diff options
550 files changed, 16276 insertions, 9655 deletions
diff --git a/Documentation/cgroups/net_prio.txt b/Documentation/cgroups/net_prio.txt new file mode 100644 index 000000000000..01b322635591 --- /dev/null +++ b/Documentation/cgroups/net_prio.txt | |||
@@ -0,0 +1,53 @@ | |||
1 | Network priority cgroup | ||
2 | ------------------------- | ||
3 | |||
4 | The Network priority cgroup provides an interface to allow an administrator to | ||
5 | dynamically set the priority of network traffic generated by various | ||
6 | applications | ||
7 | |||
8 | Nominally, an application would set the priority of its traffic via the | ||
9 | SO_PRIORITY socket option. This however, is not always possible because: | ||
10 | |||
11 | 1) The application may not have been coded to set this value | ||
12 | 2) The priority of application traffic is often a site-specific administrative | ||
13 | decision rather than an application defined one. | ||
14 | |||
15 | This cgroup allows an administrator to assign a process to a group which defines | ||
16 | the priority of egress traffic on a given interface. Network priority groups can | ||
17 | be created by first mounting the cgroup filesystem. | ||
18 | |||
19 | # mount -t cgroup -onet_prio none /sys/fs/cgroup/net_prio | ||
20 | |||
21 | With the above step, the initial group acting as the parent accounting group | ||
22 | becomes visible at '/sys/fs/cgroup/net_prio'. This group includes all tasks in | ||
23 | the system. '/sys/fs/cgroup/net_prio/tasks' lists the tasks in this cgroup. | ||
24 | |||
25 | Each net_prio cgroup contains two files that are subsystem specific | ||
26 | |||
27 | net_prio.prioidx | ||
28 | This file is read-only, and is simply informative. It contains a unique integer | ||
29 | value that the kernel uses as an internal representation of this cgroup. | ||
30 | |||
31 | net_prio.ifpriomap | ||
32 | This file contains a map of the priorities assigned to traffic originating from | ||
33 | processes in this group and egressing the system on various interfaces. It | ||
34 | contains a list of tuples in the form <ifname priority>. Contents of this file | ||
35 | can be modified by echoing a string into the file using the same tuple format. | ||
36 | for example: | ||
37 | |||
38 | echo "eth0 5" > /sys/fs/cgroups/net_prio/iscsi/net_prio.ifpriomap | ||
39 | |||
40 | This command would force any traffic originating from processes belonging to the | ||
41 | iscsi net_prio cgroup and egressing on interface eth0 to have the priority of | ||
42 | said traffic set to the value 5. The parent accounting group also has a | ||
43 | writeable 'net_prio.ifpriomap' file that can be used to set a system default | ||
44 | priority. | ||
45 | |||
46 | Priorities are set immediately prior to queueing a frame to the device | ||
47 | queueing discipline (qdisc) so priorities will be assigned prior to the hardware | ||
48 | queue selection being made. | ||
49 | |||
50 | One usage for the net_prio cgroup is with mqprio qdisc allowing application | ||
51 | traffic to be steered to hardware/driver based traffic classes. These mappings | ||
52 | can then be managed by administrators or other networking protocols such as | ||
53 | DCBX. | ||
diff --git a/Documentation/networking/ieee802154.txt b/Documentation/networking/ieee802154.txt index f41ea2405220..1dc1c24a7547 100644 --- a/Documentation/networking/ieee802154.txt +++ b/Documentation/networking/ieee802154.txt | |||
@@ -78,3 +78,30 @@ in software. This is currently WIP. | |||
78 | 78 | ||
79 | See header include/net/mac802154.h and several drivers in drivers/ieee802154/. | 79 | See header include/net/mac802154.h and several drivers in drivers/ieee802154/. |
80 | 80 | ||
81 | 6LoWPAN Linux implementation | ||
82 | ============================ | ||
83 | |||
84 | The IEEE 802.15.4 standard specifies an MTU of 128 bytes, yielding about 80 | ||
85 | octets of actual MAC payload once security is turned on, on a wireless link | ||
86 | with a link throughput of 250 kbps or less. The 6LoWPAN adaptation format | ||
87 | [RFC4944] was specified to carry IPv6 datagrams over such constrained links, | ||
88 | taking into account limited bandwidth, memory, or energy resources that are | ||
89 | expected in applications such as wireless Sensor Networks. [RFC4944] defines | ||
90 | a Mesh Addressing header to support sub-IP forwarding, a Fragmentation header | ||
91 | to support the IPv6 minimum MTU requirement [RFC2460], and stateless header | ||
92 | compression for IPv6 datagrams (LOWPAN_HC1 and LOWPAN_HC2) to reduce the | ||
93 | relatively large IPv6 and UDP headers down to (in the best case) several bytes. | ||
94 | |||
95 | In Semptember 2011 the standard update was published - [RFC6282]. | ||
96 | It deprecates HC1 and HC2 compression and defines IPHC encoding format which is | ||
97 | used in this Linux implementation. | ||
98 | |||
99 | All the code related to 6lowpan you may find in files: net/ieee802154/6lowpan.* | ||
100 | |||
101 | To setup 6lowpan interface you need (busybox release > 1.17.0): | ||
102 | 1. Add IEEE802.15.4 interface and initialize PANid; | ||
103 | 2. Add 6lowpan interface by command like: | ||
104 | # ip link add link wpan0 name lowpan0 type lowpan | ||
105 | 3. Set MAC (if needs): | ||
106 | # ip link set lowpan0 address de:ad:be:ef:ca:fe:ba:be | ||
107 | 4. Bring up 'lowpan0' interface | ||
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index f049a1ca186f..b8867061fce4 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -31,6 +31,16 @@ neigh/default/gc_thresh3 - INTEGER | |||
31 | when using large numbers of interfaces and when communicating | 31 | when using large numbers of interfaces and when communicating |
32 | with large numbers of directly-connected peers. | 32 | with large numbers of directly-connected peers. |
33 | 33 | ||
34 | neigh/default/unres_qlen_bytes - INTEGER | ||
35 | The maximum number of bytes which may be used by packets | ||
36 | queued for each unresolved address by other network layers. | ||
37 | (added in linux 3.3) | ||
38 | |||
39 | neigh/default/unres_qlen - INTEGER | ||
40 | The maximum number of packets which may be queued for each | ||
41 | unresolved address by other network layers. | ||
42 | (deprecated in linux 3.3) : use unres_qlen_bytes instead. | ||
43 | |||
34 | mtu_expires - INTEGER | 44 | mtu_expires - INTEGER |
35 | Time, in seconds, that cached PMTU information is kept. | 45 | Time, in seconds, that cached PMTU information is kept. |
36 | 46 | ||
diff --git a/Documentation/networking/team.txt b/Documentation/networking/team.txt new file mode 100644 index 000000000000..5a013686b9ea --- /dev/null +++ b/Documentation/networking/team.txt | |||
@@ -0,0 +1,2 @@ | |||
1 | Team devices are driven from userspace via libteam library which is here: | ||
2 | https://github.com/jpirko/libteam | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 29f9948b2cc0..717d9e959b15 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -6495,6 +6495,13 @@ W: http://tcp-lp-mod.sourceforge.net/ | |||
6495 | S: Maintained | 6495 | S: Maintained |
6496 | F: net/ipv4/tcp_lp.c | 6496 | F: net/ipv4/tcp_lp.c |
6497 | 6497 | ||
6498 | TEAM DRIVER | ||
6499 | M: Jiri Pirko <jpirko@redhat.com> | ||
6500 | L: netdev@vger.kernel.org | ||
6501 | S: Supported | ||
6502 | F: drivers/net/team/ | ||
6503 | F: include/linux/if_team.h | ||
6504 | |||
6498 | TEGRA SUPPORT | 6505 | TEGRA SUPPORT |
6499 | M: Colin Cross <ccross@android.com> | 6506 | M: Colin Cross <ccross@android.com> |
6500 | M: Olof Johansson <olof@lixom.net> | 6507 | M: Olof Johansson <olof@lixom.net> |
diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h index 06edfefc3373..082355f159e6 100644 --- a/arch/alpha/include/asm/socket.h +++ b/arch/alpha/include/asm/socket.h | |||
@@ -69,6 +69,9 @@ | |||
69 | 69 | ||
70 | #define SO_RXQ_OVFL 40 | 70 | #define SO_RXQ_OVFL 40 |
71 | 71 | ||
72 | #define SO_WIFI_STATUS 41 | ||
73 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
74 | |||
72 | /* O_NONBLOCK clashes with the bits used for socket types. Therefore we | 75 | /* O_NONBLOCK clashes with the bits used for socket types. Therefore we |
73 | * have to define SOCK_NONBLOCK to a different value here. | 76 | * have to define SOCK_NONBLOCK to a different value here. |
74 | */ | 77 | */ |
diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h index 90ffd04b8e74..dec6f9afb3cf 100644 --- a/arch/arm/include/asm/socket.h +++ b/arch/arm/include/asm/socket.h | |||
@@ -62,4 +62,7 @@ | |||
62 | 62 | ||
63 | #define SO_RXQ_OVFL 40 | 63 | #define SO_RXQ_OVFL 40 |
64 | 64 | ||
65 | #define SO_WIFI_STATUS 41 | ||
66 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
67 | |||
65 | #endif /* _ASM_SOCKET_H */ | 68 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/avr32/include/asm/socket.h b/arch/avr32/include/asm/socket.h index c8d1fae49476..247b88c760be 100644 --- a/arch/avr32/include/asm/socket.h +++ b/arch/avr32/include/asm/socket.h | |||
@@ -62,4 +62,7 @@ | |||
62 | 62 | ||
63 | #define SO_RXQ_OVFL 40 | 63 | #define SO_RXQ_OVFL 40 |
64 | 64 | ||
65 | #define SO_WIFI_STATUS 41 | ||
66 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
67 | |||
65 | #endif /* __ASM_AVR32_SOCKET_H */ | 68 | #endif /* __ASM_AVR32_SOCKET_H */ |
diff --git a/arch/cris/include/asm/socket.h b/arch/cris/include/asm/socket.h index 1a4a61909ca8..e269264df7c4 100644 --- a/arch/cris/include/asm/socket.h +++ b/arch/cris/include/asm/socket.h | |||
@@ -64,6 +64,9 @@ | |||
64 | 64 | ||
65 | #define SO_RXQ_OVFL 40 | 65 | #define SO_RXQ_OVFL 40 |
66 | 66 | ||
67 | #define SO_WIFI_STATUS 41 | ||
68 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
69 | |||
67 | #endif /* _ASM_SOCKET_H */ | 70 | #endif /* _ASM_SOCKET_H */ |
68 | 71 | ||
69 | 72 | ||
diff --git a/arch/frv/include/asm/socket.h b/arch/frv/include/asm/socket.h index a6b26880c1ec..ce80fdadcce5 100644 --- a/arch/frv/include/asm/socket.h +++ b/arch/frv/include/asm/socket.h | |||
@@ -62,5 +62,8 @@ | |||
62 | 62 | ||
63 | #define SO_RXQ_OVFL 40 | 63 | #define SO_RXQ_OVFL 40 |
64 | 64 | ||
65 | #define SO_WIFI_STATUS 41 | ||
66 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
67 | |||
65 | #endif /* _ASM_SOCKET_H */ | 68 | #endif /* _ASM_SOCKET_H */ |
66 | 69 | ||
diff --git a/arch/h8300/include/asm/socket.h b/arch/h8300/include/asm/socket.h index 04c0f4596eb5..cf1daab6f27e 100644 --- a/arch/h8300/include/asm/socket.h +++ b/arch/h8300/include/asm/socket.h | |||
@@ -62,4 +62,7 @@ | |||
62 | 62 | ||
63 | #define SO_RXQ_OVFL 40 | 63 | #define SO_RXQ_OVFL 40 |
64 | 64 | ||
65 | #define SO_WIFI_STATUS 41 | ||
66 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
67 | |||
65 | #endif /* _ASM_SOCKET_H */ | 68 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/ia64/include/asm/socket.h b/arch/ia64/include/asm/socket.h index 51427eaa51ba..4b03664e3fb5 100644 --- a/arch/ia64/include/asm/socket.h +++ b/arch/ia64/include/asm/socket.h | |||
@@ -71,4 +71,7 @@ | |||
71 | 71 | ||
72 | #define SO_RXQ_OVFL 40 | 72 | #define SO_RXQ_OVFL 40 |
73 | 73 | ||
74 | #define SO_WIFI_STATUS 41 | ||
75 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
76 | |||
74 | #endif /* _ASM_IA64_SOCKET_H */ | 77 | #endif /* _ASM_IA64_SOCKET_H */ |
diff --git a/arch/m32r/include/asm/socket.h b/arch/m32r/include/asm/socket.h index 469787c30098..e8b8c5bb053c 100644 --- a/arch/m32r/include/asm/socket.h +++ b/arch/m32r/include/asm/socket.h | |||
@@ -62,4 +62,7 @@ | |||
62 | 62 | ||
63 | #define SO_RXQ_OVFL 40 | 63 | #define SO_RXQ_OVFL 40 |
64 | 64 | ||
65 | #define SO_WIFI_STATUS 41 | ||
66 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
67 | |||
65 | #endif /* _ASM_M32R_SOCKET_H */ | 68 | #endif /* _ASM_M32R_SOCKET_H */ |
diff --git a/arch/m68k/include/asm/socket.h b/arch/m68k/include/asm/socket.h index 9bf49c87d954..d4708ce466e0 100644 --- a/arch/m68k/include/asm/socket.h +++ b/arch/m68k/include/asm/socket.h | |||
@@ -62,4 +62,7 @@ | |||
62 | 62 | ||
63 | #define SO_RXQ_OVFL 40 | 63 | #define SO_RXQ_OVFL 40 |
64 | 64 | ||
65 | #define SO_WIFI_STATUS 41 | ||
66 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
67 | |||
65 | #endif /* _ASM_SOCKET_H */ | 68 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/mips/include/asm/socket.h b/arch/mips/include/asm/socket.h index 9de5190f2487..ad5c0a7a02a7 100644 --- a/arch/mips/include/asm/socket.h +++ b/arch/mips/include/asm/socket.h | |||
@@ -82,6 +82,9 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */ | |||
82 | 82 | ||
83 | #define SO_RXQ_OVFL 40 | 83 | #define SO_RXQ_OVFL 40 |
84 | 84 | ||
85 | #define SO_WIFI_STATUS 41 | ||
86 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
87 | |||
85 | #ifdef __KERNEL__ | 88 | #ifdef __KERNEL__ |
86 | 89 | ||
87 | /** sock_type - Socket types | 90 | /** sock_type - Socket types |
diff --git a/arch/mn10300/include/asm/socket.h b/arch/mn10300/include/asm/socket.h index 4e60c4281288..876356d78522 100644 --- a/arch/mn10300/include/asm/socket.h +++ b/arch/mn10300/include/asm/socket.h | |||
@@ -62,4 +62,7 @@ | |||
62 | 62 | ||
63 | #define SO_RXQ_OVFL 40 | 63 | #define SO_RXQ_OVFL 40 |
64 | 64 | ||
65 | #define SO_WIFI_STATUS 41 | ||
66 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
67 | |||
65 | #endif /* _ASM_SOCKET_H */ | 68 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h index 225b7d6a1a0a..d28c51b61067 100644 --- a/arch/parisc/include/asm/socket.h +++ b/arch/parisc/include/asm/socket.h | |||
@@ -61,6 +61,9 @@ | |||
61 | 61 | ||
62 | #define SO_RXQ_OVFL 0x4021 | 62 | #define SO_RXQ_OVFL 0x4021 |
63 | 63 | ||
64 | #define SO_WIFI_STATUS 0x4022 | ||
65 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
66 | |||
64 | /* O_NONBLOCK clashes with the bits used for socket types. Therefore we | 67 | /* O_NONBLOCK clashes with the bits used for socket types. Therefore we |
65 | * have to define SOCK_NONBLOCK to a different value here. | 68 | * have to define SOCK_NONBLOCK to a different value here. |
66 | */ | 69 | */ |
diff --git a/arch/powerpc/include/asm/socket.h b/arch/powerpc/include/asm/socket.h index 866f7606da68..2fc2af8fbf59 100644 --- a/arch/powerpc/include/asm/socket.h +++ b/arch/powerpc/include/asm/socket.h | |||
@@ -69,4 +69,7 @@ | |||
69 | 69 | ||
70 | #define SO_RXQ_OVFL 40 | 70 | #define SO_RXQ_OVFL 40 |
71 | 71 | ||
72 | #define SO_WIFI_STATUS 41 | ||
73 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
74 | |||
72 | #endif /* _ASM_POWERPC_SOCKET_H */ | 75 | #endif /* _ASM_POWERPC_SOCKET_H */ |
diff --git a/arch/s390/include/asm/socket.h b/arch/s390/include/asm/socket.h index fdff1e995c73..67b5c1b14b51 100644 --- a/arch/s390/include/asm/socket.h +++ b/arch/s390/include/asm/socket.h | |||
@@ -70,4 +70,7 @@ | |||
70 | 70 | ||
71 | #define SO_RXQ_OVFL 40 | 71 | #define SO_RXQ_OVFL 40 |
72 | 72 | ||
73 | #define SO_WIFI_STATUS 41 | ||
74 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
75 | |||
73 | #endif /* _ASM_SOCKET_H */ | 76 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/sparc/include/asm/socket.h b/arch/sparc/include/asm/socket.h index 9d3fefcff2f5..8af1b64168b3 100644 --- a/arch/sparc/include/asm/socket.h +++ b/arch/sparc/include/asm/socket.h | |||
@@ -58,6 +58,9 @@ | |||
58 | 58 | ||
59 | #define SO_RXQ_OVFL 0x0024 | 59 | #define SO_RXQ_OVFL 0x0024 |
60 | 60 | ||
61 | #define SO_WIFI_STATUS 0x0025 | ||
62 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
63 | |||
61 | /* Security levels - as per NRL IPv6 - don't actually do anything */ | 64 | /* Security levels - as per NRL IPv6 - don't actually do anything */ |
62 | #define SO_SECURITY_AUTHENTICATION 0x5001 | 65 | #define SO_SECURITY_AUTHENTICATION 0x5001 |
63 | #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 | 66 | #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 |
diff --git a/arch/xtensa/include/asm/socket.h b/arch/xtensa/include/asm/socket.h index cbdf2ffaacff..bb06968be227 100644 --- a/arch/xtensa/include/asm/socket.h +++ b/arch/xtensa/include/asm/socket.h | |||
@@ -73,4 +73,7 @@ | |||
73 | 73 | ||
74 | #define SO_RXQ_OVFL 40 | 74 | #define SO_RXQ_OVFL 40 |
75 | 75 | ||
76 | #define SO_WIFI_STATUS 41 | ||
77 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
78 | |||
76 | #endif /* _XTENSA_SOCKET_H */ | 79 | #endif /* _XTENSA_SOCKET_H */ |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 106beb194f3c..1622772f802d 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <net/bluetooth/bluetooth.h> | 30 | #include <net/bluetooth/bluetooth.h> |
31 | 31 | ||
32 | #define VERSION "1.0" | 32 | #define VERSION "1.0" |
33 | #define ATH3K_FIRMWARE "ath3k-1.fw" | ||
33 | 34 | ||
34 | #define ATH3K_DNLOAD 0x01 | 35 | #define ATH3K_DNLOAD 0x01 |
35 | #define ATH3K_GETSTATE 0x05 | 36 | #define ATH3K_GETSTATE 0x05 |
@@ -400,9 +401,15 @@ static int ath3k_probe(struct usb_interface *intf, | |||
400 | return 0; | 401 | return 0; |
401 | } | 402 | } |
402 | 403 | ||
403 | if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) { | 404 | ret = request_firmware(&firmware, ATH3K_FIRMWARE, &udev->dev); |
404 | BT_ERR("Error loading firmware"); | 405 | if (ret < 0) { |
405 | return -EIO; | 406 | if (ret == -ENOENT) |
407 | BT_ERR("Firmware file \"%s\" not found", | ||
408 | ATH3K_FIRMWARE); | ||
409 | else | ||
410 | BT_ERR("Firmware file \"%s\" request failed (err=%d)", | ||
411 | ATH3K_FIRMWARE, ret); | ||
412 | return ret; | ||
406 | } | 413 | } |
407 | 414 | ||
408 | ret = ath3k_load_firmware(udev, firmware); | 415 | ret = ath3k_load_firmware(udev, firmware); |
@@ -441,4 +448,4 @@ MODULE_AUTHOR("Atheros Communications"); | |||
441 | MODULE_DESCRIPTION("Atheros AR30xx firmware driver"); | 448 | MODULE_DESCRIPTION("Atheros AR30xx firmware driver"); |
442 | MODULE_VERSION(VERSION); | 449 | MODULE_VERSION(VERSION); |
443 | MODULE_LICENSE("GPL"); | 450 | MODULE_LICENSE("GPL"); |
444 | MODULE_FIRMWARE("ath3k-1.fw"); | 451 | MODULE_FIRMWARE(ATH3K_FIRMWARE); |
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c index 61b591470a90..a936763b8c3d 100644 --- a/drivers/bluetooth/bfusb.c +++ b/drivers/bluetooth/bfusb.c | |||
@@ -751,9 +751,7 @@ static void bfusb_disconnect(struct usb_interface *intf) | |||
751 | 751 | ||
752 | bfusb_close(hdev); | 752 | bfusb_close(hdev); |
753 | 753 | ||
754 | if (hci_unregister_dev(hdev) < 0) | 754 | hci_unregister_dev(hdev); |
755 | BT_ERR("Can't unregister HCI device %s", hdev->name); | ||
756 | |||
757 | hci_free_dev(hdev); | 755 | hci_free_dev(hdev); |
758 | } | 756 | } |
759 | 757 | ||
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index aed1904ea67b..c6a0c6103743 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c | |||
@@ -844,9 +844,7 @@ static int bluecard_close(bluecard_info_t *info) | |||
844 | /* Turn FPGA off */ | 844 | /* Turn FPGA off */ |
845 | outb(0x80, iobase + 0x30); | 845 | outb(0x80, iobase + 0x30); |
846 | 846 | ||
847 | if (hci_unregister_dev(hdev) < 0) | 847 | hci_unregister_dev(hdev); |
848 | BT_ERR("Can't unregister HCI device %s", hdev->name); | ||
849 | |||
850 | hci_free_dev(hdev); | 848 | hci_free_dev(hdev); |
851 | 849 | ||
852 | return 0; | 850 | return 0; |
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 4fc01949d399..0c97e5d514b6 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c | |||
@@ -636,9 +636,7 @@ static int bt3c_close(bt3c_info_t *info) | |||
636 | 636 | ||
637 | bt3c_hci_close(hdev); | 637 | bt3c_hci_close(hdev); |
638 | 638 | ||
639 | if (hci_unregister_dev(hdev) < 0) | 639 | hci_unregister_dev(hdev); |
640 | BT_ERR("Can't unregister HCI device %s", hdev->name); | ||
641 | |||
642 | hci_free_dev(hdev); | 640 | hci_free_dev(hdev); |
643 | 641 | ||
644 | return 0; | 642 | return 0; |
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 526b61807d94..200b3a2877d6 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c | |||
@@ -565,9 +565,7 @@ static int btuart_close(btuart_info_t *info) | |||
565 | 565 | ||
566 | spin_unlock_irqrestore(&(info->lock), flags); | 566 | spin_unlock_irqrestore(&(info->lock), flags); |
567 | 567 | ||
568 | if (hci_unregister_dev(hdev) < 0) | 568 | hci_unregister_dev(hdev); |
569 | BT_ERR("Can't unregister HCI device %s", hdev->name); | ||
570 | |||
571 | hci_free_dev(hdev); | 569 | hci_free_dev(hdev); |
572 | 570 | ||
573 | return 0; | 571 | return 0; |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index fe4ebc375b3d..2bd87d45f1c2 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -315,7 +315,8 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) | |||
315 | 315 | ||
316 | err = usb_submit_urb(urb, mem_flags); | 316 | err = usb_submit_urb(urb, mem_flags); |
317 | if (err < 0) { | 317 | if (err < 0) { |
318 | BT_ERR("%s urb %p submission failed (%d)", | 318 | if (err != -EPERM && err != -ENODEV) |
319 | BT_ERR("%s urb %p submission failed (%d)", | ||
319 | hdev->name, urb, -err); | 320 | hdev->name, urb, -err); |
320 | usb_unanchor_urb(urb); | 321 | usb_unanchor_urb(urb); |
321 | } | 322 | } |
@@ -400,7 +401,8 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags) | |||
400 | 401 | ||
401 | err = usb_submit_urb(urb, mem_flags); | 402 | err = usb_submit_urb(urb, mem_flags); |
402 | if (err < 0) { | 403 | if (err < 0) { |
403 | BT_ERR("%s urb %p submission failed (%d)", | 404 | if (err != -EPERM && err != -ENODEV) |
405 | BT_ERR("%s urb %p submission failed (%d)", | ||
404 | hdev->name, urb, -err); | 406 | hdev->name, urb, -err); |
405 | usb_unanchor_urb(urb); | 407 | usb_unanchor_urb(urb); |
406 | } | 408 | } |
@@ -523,7 +525,8 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags) | |||
523 | 525 | ||
524 | err = usb_submit_urb(urb, mem_flags); | 526 | err = usb_submit_urb(urb, mem_flags); |
525 | if (err < 0) { | 527 | if (err < 0) { |
526 | BT_ERR("%s urb %p submission failed (%d)", | 528 | if (err != -EPERM && err != -ENODEV) |
529 | BT_ERR("%s urb %p submission failed (%d)", | ||
527 | hdev->name, urb, -err); | 530 | hdev->name, urb, -err); |
528 | usb_unanchor_urb(urb); | 531 | usb_unanchor_urb(urb); |
529 | } | 532 | } |
@@ -727,6 +730,9 @@ static int btusb_send_frame(struct sk_buff *skb) | |||
727 | usb_fill_bulk_urb(urb, data->udev, pipe, | 730 | usb_fill_bulk_urb(urb, data->udev, pipe, |
728 | skb->data, skb->len, btusb_tx_complete, skb); | 731 | skb->data, skb->len, btusb_tx_complete, skb); |
729 | 732 | ||
733 | if (skb->priority >= HCI_PRIO_MAX - 1) | ||
734 | urb->transfer_flags = URB_ISO_ASAP; | ||
735 | |||
730 | hdev->stat.acl_tx++; | 736 | hdev->stat.acl_tx++; |
731 | break; | 737 | break; |
732 | 738 | ||
@@ -770,7 +776,9 @@ skip_waking: | |||
770 | 776 | ||
771 | err = usb_submit_urb(urb, GFP_ATOMIC); | 777 | err = usb_submit_urb(urb, GFP_ATOMIC); |
772 | if (err < 0) { | 778 | if (err < 0) { |
773 | BT_ERR("%s urb %p submission failed", hdev->name, urb); | 779 | if (err != -EPERM && err != -ENODEV) |
780 | BT_ERR("%s urb %p submission failed (%d)", | ||
781 | hdev->name, urb, -err); | ||
774 | kfree(urb->setup_packet); | 782 | kfree(urb->setup_packet); |
775 | usb_unanchor_urb(urb); | 783 | usb_unanchor_urb(urb); |
776 | } else { | 784 | } else { |
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 5e4c2de9fc3f..969bb22e493f 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c | |||
@@ -551,9 +551,7 @@ static int dtl1_close(dtl1_info_t *info) | |||
551 | 551 | ||
552 | spin_unlock_irqrestore(&(info->lock), flags); | 552 | spin_unlock_irqrestore(&(info->lock), flags); |
553 | 553 | ||
554 | if (hci_unregister_dev(hdev) < 0) | 554 | hci_unregister_dev(hdev); |
555 | BT_ERR("Can't unregister HCI device %s", hdev->name); | ||
556 | |||
557 | hci_free_dev(hdev); | 555 | hci_free_dev(hdev); |
558 | 556 | ||
559 | return 0; | 557 | return 0; |
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 67c180c2c1e0..2e302a11ab55 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c | |||
@@ -264,10 +264,7 @@ static int vhci_release(struct inode *inode, struct file *file) | |||
264 | struct vhci_data *data = file->private_data; | 264 | struct vhci_data *data = file->private_data; |
265 | struct hci_dev *hdev = data->hdev; | 265 | struct hci_dev *hdev = data->hdev; |
266 | 266 | ||
267 | if (hci_unregister_dev(hdev) < 0) { | 267 | hci_unregister_dev(hdev); |
268 | BT_ERR("Can't unregister HCI device %s", hdev->name); | ||
269 | } | ||
270 | |||
271 | hci_free_dev(hdev); | 268 | hci_free_dev(hdev); |
272 | 269 | ||
273 | file->private_data = NULL; | 270 | file->private_data = NULL; |
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c index eb0e2ccc79ae..73d453159408 100644 --- a/drivers/ieee802154/fakehard.c +++ b/drivers/ieee802154/fakehard.c | |||
@@ -343,7 +343,7 @@ static void ieee802154_fake_setup(struct net_device *dev) | |||
343 | { | 343 | { |
344 | dev->addr_len = IEEE802154_ADDR_LEN; | 344 | dev->addr_len = IEEE802154_ADDR_LEN; |
345 | memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); | 345 | memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); |
346 | dev->features = NETIF_F_NO_CSUM; | 346 | dev->features = NETIF_F_HW_CSUM; |
347 | dev->needed_tailroom = 2; /* FCS */ | 347 | dev->needed_tailroom = 2; /* FCS */ |
348 | dev->mtu = 127; | 348 | dev->mtu = 127; |
349 | dev->tx_queue_len = 10; | 349 | dev->tx_queue_len = 10; |
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 691276bafd78..adf0757280ed 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c | |||
@@ -243,8 +243,8 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, | |||
243 | int ret; | 243 | int ret; |
244 | 244 | ||
245 | memset(&fl6, 0, sizeof fl6); | 245 | memset(&fl6, 0, sizeof fl6); |
246 | ipv6_addr_copy(&fl6.daddr, &dst_in->sin6_addr); | 246 | fl6.daddr = dst_in->sin6_addr; |
247 | ipv6_addr_copy(&fl6.saddr, &src_in->sin6_addr); | 247 | fl6.saddr = src_in->sin6_addr; |
248 | fl6.flowi6_oif = addr->bound_dev_if; | 248 | fl6.flowi6_oif = addr->bound_dev_if; |
249 | 249 | ||
250 | dst = ip6_route_output(&init_net, NULL, &fl6); | 250 | dst = ip6_route_output(&init_net, NULL, &fl6); |
@@ -258,7 +258,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, | |||
258 | goto put; | 258 | goto put; |
259 | 259 | ||
260 | src_in->sin6_family = AF_INET6; | 260 | src_in->sin6_family = AF_INET6; |
261 | ipv6_addr_copy(&src_in->sin6_addr, &fl6.saddr); | 261 | src_in->sin6_addr = fl6.saddr; |
262 | } | 262 | } |
263 | 263 | ||
264 | if (dst->dev->flags & IFF_LOOPBACK) { | 264 | if (dst->dev->flags & IFF_LOOPBACK) { |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 75ff821c0af0..09e66cce05d3 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -2005,11 +2005,11 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv) | |||
2005 | if (cma_zero_addr(src)) { | 2005 | if (cma_zero_addr(src)) { |
2006 | dst = (struct sockaddr *) &id_priv->id.route.addr.dst_addr; | 2006 | dst = (struct sockaddr *) &id_priv->id.route.addr.dst_addr; |
2007 | if ((src->sa_family = dst->sa_family) == AF_INET) { | 2007 | if ((src->sa_family = dst->sa_family) == AF_INET) { |
2008 | ((struct sockaddr_in *) src)->sin_addr.s_addr = | 2008 | ((struct sockaddr_in *)src)->sin_addr = |
2009 | ((struct sockaddr_in *) dst)->sin_addr.s_addr; | 2009 | ((struct sockaddr_in *)dst)->sin_addr; |
2010 | } else { | 2010 | } else { |
2011 | ipv6_addr_copy(&((struct sockaddr_in6 *) src)->sin6_addr, | 2011 | ((struct sockaddr_in6 *)src)->sin6_addr = |
2012 | &((struct sockaddr_in6 *) dst)->sin6_addr); | 2012 | ((struct sockaddr_in6 *)dst)->sin6_addr; |
2013 | } | 2013 | } |
2014 | } | 2014 | } |
2015 | 2015 | ||
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index c00d2f3f8966..4b3fa711a247 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c | |||
@@ -1589,7 +1589,7 @@ static const struct ethtool_ops nes_ethtool_ops = { | |||
1589 | .set_pauseparam = nes_netdev_set_pauseparam, | 1589 | .set_pauseparam = nes_netdev_set_pauseparam, |
1590 | }; | 1590 | }; |
1591 | 1591 | ||
1592 | static void nes_vlan_mode(struct net_device *netdev, struct nes_device *nesdev, u32 features) | 1592 | static void nes_vlan_mode(struct net_device *netdev, struct nes_device *nesdev, netdev_features_t features) |
1593 | { | 1593 | { |
1594 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 1594 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
1595 | u32 u32temp; | 1595 | u32 u32temp; |
@@ -1610,7 +1610,7 @@ static void nes_vlan_mode(struct net_device *netdev, struct nes_device *nesdev, | |||
1610 | spin_unlock_irqrestore(&nesadapter->phy_lock, flags); | 1610 | spin_unlock_irqrestore(&nesadapter->phy_lock, flags); |
1611 | } | 1611 | } |
1612 | 1612 | ||
1613 | static u32 nes_fix_features(struct net_device *netdev, u32 features) | 1613 | static netdev_features_t nes_fix_features(struct net_device *netdev, netdev_features_t features) |
1614 | { | 1614 | { |
1615 | /* | 1615 | /* |
1616 | * Since there is no support for separate rx/tx vlan accel | 1616 | * Since there is no support for separate rx/tx vlan accel |
@@ -1624,7 +1624,7 @@ static u32 nes_fix_features(struct net_device *netdev, u32 features) | |||
1624 | return features; | 1624 | return features; |
1625 | } | 1625 | } |
1626 | 1626 | ||
1627 | static int nes_set_features(struct net_device *netdev, u32 features) | 1627 | static int nes_set_features(struct net_device *netdev, netdev_features_t features) |
1628 | { | 1628 | { |
1629 | struct nes_vnic *nesvnic = netdev_priv(netdev); | 1629 | struct nes_vnic *nesvnic = netdev_priv(netdev); |
1630 | struct nes_device *nesdev = nesvnic->nesdev; | 1630 | struct nes_device *nesdev = nesvnic->nesdev; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 7567b6000230..efd7a9636aff 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -171,7 +171,7 @@ static int ipoib_stop(struct net_device *dev) | |||
171 | return 0; | 171 | return 0; |
172 | } | 172 | } |
173 | 173 | ||
174 | static u32 ipoib_fix_features(struct net_device *dev, u32 features) | 174 | static netdev_features_t ipoib_fix_features(struct net_device *dev, netdev_features_t features) |
175 | { | 175 | { |
176 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 176 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
177 | 177 | ||
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index 0dc30ffde5ad..595d73197016 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c | |||
@@ -381,6 +381,11 @@ error: | |||
381 | return PTR_ERR(vqs[i]); | 381 | return PTR_ERR(vqs[i]); |
382 | } | 382 | } |
383 | 383 | ||
384 | static const char *lg_bus_name(struct virtio_device *vdev) | ||
385 | { | ||
386 | return ""; | ||
387 | } | ||
388 | |||
384 | /* The ops structure which hooks everything together. */ | 389 | /* The ops structure which hooks everything together. */ |
385 | static struct virtio_config_ops lguest_config_ops = { | 390 | static struct virtio_config_ops lguest_config_ops = { |
386 | .get_features = lg_get_features, | 391 | .get_features = lg_get_features, |
@@ -392,6 +397,7 @@ static struct virtio_config_ops lguest_config_ops = { | |||
392 | .reset = lg_reset, | 397 | .reset = lg_reset, |
393 | .find_vqs = lg_find_vqs, | 398 | .find_vqs = lg_find_vqs, |
394 | .del_vqs = lg_del_vqs, | 399 | .del_vqs = lg_del_vqs, |
400 | .bus_name = lg_bus_name, | ||
395 | }; | 401 | }; |
396 | 402 | ||
397 | /* | 403 | /* |
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c index 42f067347bc7..3fac67a5204c 100644 --- a/drivers/misc/sgi-xp/xpnet.c +++ b/drivers/misc/sgi-xp/xpnet.c | |||
@@ -576,7 +576,7 @@ xpnet_init(void) | |||
576 | * report an error if the data is not retrievable and the | 576 | * report an error if the data is not retrievable and the |
577 | * packet will be dropped. | 577 | * packet will be dropped. |
578 | */ | 578 | */ |
579 | xpnet_device->features = NETIF_F_NO_CSUM; | 579 | xpnet_device->features = NETIF_F_HW_CSUM; |
580 | 580 | ||
581 | result = register_netdev(xpnet_device); | 581 | result = register_netdev(xpnet_device); |
582 | if (result != 0) { | 582 | if (result != 0) { |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 654a5e94e0e7..debdf1c07c5b 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -125,6 +125,8 @@ config IFB | |||
125 | 'ifb1' etc. | 125 | 'ifb1' etc. |
126 | Look at the iproute2 documentation directory for usage etc | 126 | Look at the iproute2 documentation directory for usage etc |
127 | 127 | ||
128 | source "drivers/net/team/Kconfig" | ||
129 | |||
128 | config MACVLAN | 130 | config MACVLAN |
129 | tristate "MAC-VLAN support (EXPERIMENTAL)" | 131 | tristate "MAC-VLAN support (EXPERIMENTAL)" |
130 | depends on EXPERIMENTAL | 132 | depends on EXPERIMENTAL |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index fa877cd2b139..4e4ebfe1aa53 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -17,6 +17,7 @@ obj-$(CONFIG_NET) += Space.o loopback.o | |||
17 | obj-$(CONFIG_NETCONSOLE) += netconsole.o | 17 | obj-$(CONFIG_NETCONSOLE) += netconsole.o |
18 | obj-$(CONFIG_PHYLIB) += phy/ | 18 | obj-$(CONFIG_PHYLIB) += phy/ |
19 | obj-$(CONFIG_RIONET) += rionet.o | 19 | obj-$(CONFIG_RIONET) += rionet.o |
20 | obj-$(CONFIG_NET_TEAM) += team/ | ||
20 | obj-$(CONFIG_TUN) += tun.o | 21 | obj-$(CONFIG_TUN) += tun.o |
21 | obj-$(CONFIG_VETH) += veth.o | 22 | obj-$(CONFIG_VETH) += veth.o |
22 | obj-$(CONFIG_VIRTIO_NET) += virtio_net.o | 23 | obj-$(CONFIG_VIRTIO_NET) += virtio_net.o |
diff --git a/drivers/net/bonding/bond_ipv6.c b/drivers/net/bonding/bond_ipv6.c index 027a0ee7d85b..7e6632221a75 100644 --- a/drivers/net/bonding/bond_ipv6.c +++ b/drivers/net/bonding/bond_ipv6.c | |||
@@ -50,7 +50,7 @@ static void bond_glean_dev_ipv6(struct net_device *dev, struct in6_addr *addr) | |||
50 | struct inet6_ifaddr *ifa | 50 | struct inet6_ifaddr *ifa |
51 | = list_first_entry(&idev->addr_list, | 51 | = list_first_entry(&idev->addr_list, |
52 | struct inet6_ifaddr, if_list); | 52 | struct inet6_ifaddr, if_list); |
53 | ipv6_addr_copy(addr, &ifa->addr); | 53 | *addr = ifa->addr; |
54 | } else | 54 | } else |
55 | ipv6_addr_set(addr, 0, 0, 0, 0); | 55 | ipv6_addr_set(addr, 0, 0, 0, 0); |
56 | 56 | ||
@@ -168,8 +168,7 @@ static int bond_inet6addr_event(struct notifier_block *this, | |||
168 | switch (event) { | 168 | switch (event) { |
169 | case NETDEV_UP: | 169 | case NETDEV_UP: |
170 | if (ipv6_addr_any(&bond->master_ipv6)) | 170 | if (ipv6_addr_any(&bond->master_ipv6)) |
171 | ipv6_addr_copy(&bond->master_ipv6, | 171 | bond->master_ipv6 = ifa->addr; |
172 | &ifa->addr); | ||
173 | return NOTIFY_OK; | 172 | return NOTIFY_OK; |
174 | case NETDEV_DOWN: | 173 | case NETDEV_DOWN: |
175 | if (ipv6_addr_equal(&bond->master_ipv6, | 174 | if (ipv6_addr_equal(&bond->master_ipv6, |
@@ -191,8 +190,7 @@ static int bond_inet6addr_event(struct notifier_block *this, | |||
191 | switch (event) { | 190 | switch (event) { |
192 | case NETDEV_UP: | 191 | case NETDEV_UP: |
193 | if (ipv6_addr_any(&vlan->vlan_ipv6)) | 192 | if (ipv6_addr_any(&vlan->vlan_ipv6)) |
194 | ipv6_addr_copy(&vlan->vlan_ipv6, | 193 | vlan->vlan_ipv6 = ifa->addr; |
195 | &ifa->addr); | ||
196 | return NOTIFY_OK; | 194 | return NOTIFY_OK; |
197 | case NETDEV_DOWN: | 195 | case NETDEV_DOWN: |
198 | if (ipv6_addr_equal(&vlan->vlan_ipv6, | 196 | if (ipv6_addr_equal(&vlan->vlan_ipv6, |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b0c577256487..25a44d94be17 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1325,11 +1325,12 @@ static int bond_sethwaddr(struct net_device *bond_dev, | |||
1325 | return 0; | 1325 | return 0; |
1326 | } | 1326 | } |
1327 | 1327 | ||
1328 | static u32 bond_fix_features(struct net_device *dev, u32 features) | 1328 | static netdev_features_t bond_fix_features(struct net_device *dev, |
1329 | netdev_features_t features) | ||
1329 | { | 1330 | { |
1330 | struct slave *slave; | 1331 | struct slave *slave; |
1331 | struct bonding *bond = netdev_priv(dev); | 1332 | struct bonding *bond = netdev_priv(dev); |
1332 | u32 mask; | 1333 | netdev_features_t mask; |
1333 | int i; | 1334 | int i; |
1334 | 1335 | ||
1335 | read_lock(&bond->lock); | 1336 | read_lock(&bond->lock); |
@@ -1363,7 +1364,7 @@ static void bond_compute_features(struct bonding *bond) | |||
1363 | { | 1364 | { |
1364 | struct slave *slave; | 1365 | struct slave *slave; |
1365 | struct net_device *bond_dev = bond->dev; | 1366 | struct net_device *bond_dev = bond->dev; |
1366 | u32 vlan_features = BOND_VLAN_FEATURES; | 1367 | netdev_features_t vlan_features = BOND_VLAN_FEATURES; |
1367 | unsigned short max_hard_header_len = ETH_HLEN; | 1368 | unsigned short max_hard_header_len = ETH_HLEN; |
1368 | int i; | 1369 | int i; |
1369 | 1370 | ||
@@ -1897,7 +1898,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1897 | struct bonding *bond = netdev_priv(bond_dev); | 1898 | struct bonding *bond = netdev_priv(bond_dev); |
1898 | struct slave *slave, *oldcurrent; | 1899 | struct slave *slave, *oldcurrent; |
1899 | struct sockaddr addr; | 1900 | struct sockaddr addr; |
1900 | u32 old_features = bond_dev->features; | 1901 | netdev_features_t old_features = bond_dev->features; |
1901 | 1902 | ||
1902 | /* slave is not a slave or master is not master of this slave */ | 1903 | /* slave is not a slave or master is not master of this slave */ |
1903 | if (!(slave_dev->flags & IFF_SLAVE) || | 1904 | if (!(slave_dev->flags & IFF_SLAVE) || |
@@ -4360,7 +4361,7 @@ static void bond_setup(struct net_device *bond_dev) | |||
4360 | NETIF_F_HW_VLAN_RX | | 4361 | NETIF_F_HW_VLAN_RX | |
4361 | NETIF_F_HW_VLAN_FILTER; | 4362 | NETIF_F_HW_VLAN_FILTER; |
4362 | 4363 | ||
4363 | bond_dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_NO_CSUM); | 4364 | bond_dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM); |
4364 | bond_dev->features |= bond_dev->hw_features; | 4365 | bond_dev->features |= bond_dev->hw_features; |
4365 | } | 4366 | } |
4366 | 4367 | ||
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 25695bde0549..120f1ab5a2ce 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -454,7 +454,7 @@ static void can_setup(struct net_device *dev) | |||
454 | 454 | ||
455 | /* New-style flags. */ | 455 | /* New-style flags. */ |
456 | dev->flags = IFF_NOARP; | 456 | dev->flags = IFF_NOARP; |
457 | dev->features = NETIF_F_NO_CSUM; | 457 | dev->features = NETIF_F_HW_CSUM; |
458 | } | 458 | } |
459 | 459 | ||
460 | struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) | 460 | struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) |
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index ec4a3119e2c9..1c82dd8b896e 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c | |||
@@ -581,7 +581,10 @@ static int mscan_open(struct net_device *dev) | |||
581 | 581 | ||
582 | priv->open_time = jiffies; | 582 | priv->open_time = jiffies; |
583 | 583 | ||
584 | clrbits8(®s->canctl1, MSCAN_LISTEN); | 584 | if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) |
585 | setbits8(®s->canctl1, MSCAN_LISTEN); | ||
586 | else | ||
587 | clrbits8(®s->canctl1, MSCAN_LISTEN); | ||
585 | 588 | ||
586 | ret = mscan_start(dev); | 589 | ret = mscan_start(dev); |
587 | if (ret) | 590 | if (ret) |
@@ -690,7 +693,8 @@ struct net_device *alloc_mscandev(void) | |||
690 | priv->can.bittiming_const = &mscan_bittiming_const; | 693 | priv->can.bittiming_const = &mscan_bittiming_const; |
691 | priv->can.do_set_bittiming = mscan_do_set_bittiming; | 694 | priv->can.do_set_bittiming = mscan_do_set_bittiming; |
692 | priv->can.do_set_mode = mscan_do_set_mode; | 695 | priv->can.do_set_mode = mscan_do_set_mode; |
693 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; | 696 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | |
697 | CAN_CTRLMODE_LISTENONLY; | ||
694 | 698 | ||
695 | for (i = 0; i < TX_QUEUE_SIZE; i++) { | 699 | for (i = 0; i < TX_QUEUE_SIZE; i++) { |
696 | priv->tx_queue[i].id = i; | 700 | priv->tx_queue[i].id = i; |
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index a979b006f459..3f1ebcc2cb83 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c | |||
@@ -387,7 +387,7 @@ static void slc_setup(struct net_device *dev) | |||
387 | 387 | ||
388 | /* New-style flags. */ | 388 | /* New-style flags. */ |
389 | dev->flags = IFF_NOARP; | 389 | dev->flags = IFF_NOARP; |
390 | dev->features = NETIF_F_NO_CSUM; | 390 | dev->features = NETIF_F_HW_CSUM; |
391 | } | 391 | } |
392 | 392 | ||
393 | /****************************************** | 393 | /****************************************** |
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index a7c5e8831e8c..087648ea1edb 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c | |||
@@ -134,7 +134,7 @@ static void dummy_setup(struct net_device *dev) | |||
134 | dev->flags |= IFF_NOARP; | 134 | dev->flags |= IFF_NOARP; |
135 | dev->flags &= ~IFF_MULTICAST; | 135 | dev->flags &= ~IFF_MULTICAST; |
136 | dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO; | 136 | dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO; |
137 | dev->features |= NETIF_F_NO_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX; | 137 | dev->features |= NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX; |
138 | random_ether_addr(dev->dev_addr); | 138 | random_ether_addr(dev->dev_addr); |
139 | } | 139 | } |
140 | 140 | ||
diff --git a/drivers/net/ethernet/3com/3c589_cs.c b/drivers/net/ethernet/3com/3c589_cs.c index 972f80ecc510..da410f036869 100644 --- a/drivers/net/ethernet/3com/3c589_cs.c +++ b/drivers/net/ethernet/3com/3c589_cs.c | |||
@@ -468,9 +468,10 @@ static void tc589_reset(struct net_device *dev) | |||
468 | static void netdev_get_drvinfo(struct net_device *dev, | 468 | static void netdev_get_drvinfo(struct net_device *dev, |
469 | struct ethtool_drvinfo *info) | 469 | struct ethtool_drvinfo *info) |
470 | { | 470 | { |
471 | strcpy(info->driver, DRV_NAME); | 471 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
472 | strcpy(info->version, DRV_VERSION); | 472 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
473 | sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); | 473 | snprintf(info->bus_info, sizeof(info->bus_info), |
474 | "PCMCIA 0x%lx", dev->base_addr); | ||
474 | } | 475 | } |
475 | 476 | ||
476 | static const struct ethtool_ops netdev_ethtool_ops = { | 477 | static const struct ethtool_ops netdev_ethtool_ops = { |
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index b42c06baba89..8153a3e0a1a4 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c | |||
@@ -2929,15 +2929,17 @@ static void vortex_get_drvinfo(struct net_device *dev, | |||
2929 | { | 2929 | { |
2930 | struct vortex_private *vp = netdev_priv(dev); | 2930 | struct vortex_private *vp = netdev_priv(dev); |
2931 | 2931 | ||
2932 | strcpy(info->driver, DRV_NAME); | 2932 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
2933 | if (VORTEX_PCI(vp)) { | 2933 | if (VORTEX_PCI(vp)) { |
2934 | strcpy(info->bus_info, pci_name(VORTEX_PCI(vp))); | 2934 | strlcpy(info->bus_info, pci_name(VORTEX_PCI(vp)), |
2935 | sizeof(info->bus_info)); | ||
2935 | } else { | 2936 | } else { |
2936 | if (VORTEX_EISA(vp)) | 2937 | if (VORTEX_EISA(vp)) |
2937 | strcpy(info->bus_info, dev_name(vp->gendev)); | 2938 | strlcpy(info->bus_info, dev_name(vp->gendev), |
2939 | sizeof(info->bus_info)); | ||
2938 | else | 2940 | else |
2939 | sprintf(info->bus_info, "EISA 0x%lx %d", | 2941 | snprintf(info->bus_info, sizeof(info->bus_info), |
2940 | dev->base_addr, dev->irq); | 2942 | "EISA 0x%lx %d", dev->base_addr, dev->irq); |
2941 | } | 2943 | } |
2942 | } | 2944 | } |
2943 | 2945 | ||
diff --git a/drivers/net/ethernet/3com/typhoon.c b/drivers/net/ethernet/3com/typhoon.c index 20ea07508ac7..6d6bc754b1a8 100644 --- a/drivers/net/ethernet/3com/typhoon.c +++ b/drivers/net/ethernet/3com/typhoon.c | |||
@@ -988,21 +988,23 @@ typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
988 | 988 | ||
989 | smp_rmb(); | 989 | smp_rmb(); |
990 | if(tp->card_state == Sleeping) { | 990 | if(tp->card_state == Sleeping) { |
991 | strcpy(info->fw_version, "Sleep image"); | 991 | strlcpy(info->fw_version, "Sleep image", |
992 | sizeof(info->fw_version)); | ||
992 | } else { | 993 | } else { |
993 | INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS); | 994 | INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS); |
994 | if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) { | 995 | if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) { |
995 | strcpy(info->fw_version, "Unknown runtime"); | 996 | strlcpy(info->fw_version, "Unknown runtime", |
997 | sizeof(info->fw_version)); | ||
996 | } else { | 998 | } else { |
997 | u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2); | 999 | u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2); |
998 | snprintf(info->fw_version, 32, "%02x.%03x.%03x", | 1000 | snprintf(info->fw_version, sizeof(info->fw_version), |
999 | sleep_ver >> 24, (sleep_ver >> 12) & 0xfff, | 1001 | "%02x.%03x.%03x", sleep_ver >> 24, |
1000 | sleep_ver & 0xfff); | 1002 | (sleep_ver >> 12) & 0xfff, sleep_ver & 0xfff); |
1001 | } | 1003 | } |
1002 | } | 1004 | } |
1003 | 1005 | ||
1004 | strcpy(info->driver, KBUILD_MODNAME); | 1006 | strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); |
1005 | strcpy(info->bus_info, pci_name(pci_dev)); | 1007 | strlcpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info)); |
1006 | } | 1008 | } |
1007 | 1009 | ||
1008 | static int | 1010 | static int |
diff --git a/drivers/net/ethernet/8390/8390.h b/drivers/net/ethernet/8390/8390.h index 58a12e4c78f9..ef325ffa1b5a 100644 --- a/drivers/net/ethernet/8390/8390.h +++ b/drivers/net/ethernet/8390/8390.h | |||
@@ -14,8 +14,6 @@ | |||
14 | 14 | ||
15 | #define TX_PAGES 12 /* Two Tx slots */ | 15 | #define TX_PAGES 12 /* Two Tx slots */ |
16 | 16 | ||
17 | #define ETHER_ADDR_LEN 6 | ||
18 | |||
19 | /* The 8390 specific per-packet-header format. */ | 17 | /* The 8390 specific per-packet-header format. */ |
20 | struct e8390_pkt_hdr { | 18 | struct e8390_pkt_hdr { |
21 | unsigned char status; /* status */ | 19 | unsigned char status; /* status */ |
diff --git a/drivers/net/ethernet/8390/apne.c b/drivers/net/ethernet/8390/apne.c index 547737340cbb..3ad5d2f9a49c 100644 --- a/drivers/net/ethernet/8390/apne.c +++ b/drivers/net/ethernet/8390/apne.c | |||
@@ -318,7 +318,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr) | |||
318 | i = request_irq(dev->irq, apne_interrupt, IRQF_SHARED, DRV_NAME, dev); | 318 | i = request_irq(dev->irq, apne_interrupt, IRQF_SHARED, DRV_NAME, dev); |
319 | if (i) return i; | 319 | if (i) return i; |
320 | 320 | ||
321 | for(i = 0; i < ETHER_ADDR_LEN; i++) | 321 | for (i = 0; i < ETH_ALEN; i++) |
322 | dev->dev_addr[i] = SA_prom[i]; | 322 | dev->dev_addr[i] = SA_prom[i]; |
323 | 323 | ||
324 | printk(" %pM\n", dev->dev_addr); | 324 | printk(" %pM\n", dev->dev_addr); |
diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c index e9f8432f55b4..2a3b8c2676bd 100644 --- a/drivers/net/ethernet/8390/ax88796.c +++ b/drivers/net/ethernet/8390/ax88796.c | |||
@@ -735,15 +735,14 @@ static int ax_init_dev(struct net_device *dev) | |||
735 | if (ax->plat->flags & AXFLG_MAC_FROMDEV) { | 735 | if (ax->plat->flags & AXFLG_MAC_FROMDEV) { |
736 | ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, | 736 | ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, |
737 | ei_local->mem + E8390_CMD); /* 0x61 */ | 737 | ei_local->mem + E8390_CMD); /* 0x61 */ |
738 | for (i = 0; i < ETHER_ADDR_LEN; i++) | 738 | for (i = 0; i < ETH_ALEN; i++) |
739 | dev->dev_addr[i] = | 739 | dev->dev_addr[i] = |
740 | ei_inb(ioaddr + EN1_PHYS_SHIFT(i)); | 740 | ei_inb(ioaddr + EN1_PHYS_SHIFT(i)); |
741 | } | 741 | } |
742 | 742 | ||
743 | if ((ax->plat->flags & AXFLG_MAC_FROMPLATFORM) && | 743 | if ((ax->plat->flags & AXFLG_MAC_FROMPLATFORM) && |
744 | ax->plat->mac_addr) | 744 | ax->plat->mac_addr) |
745 | memcpy(dev->dev_addr, ax->plat->mac_addr, | 745 | memcpy(dev->dev_addr, ax->plat->mac_addr, ETH_ALEN); |
746 | ETHER_ADDR_LEN); | ||
747 | 746 | ||
748 | ax_reset_8390(dev); | 747 | ax_reset_8390(dev); |
749 | 748 | ||
diff --git a/drivers/net/ethernet/8390/es3210.c b/drivers/net/ethernet/8390/es3210.c index 7a09575ecff0..6428f9e7a554 100644 --- a/drivers/net/ethernet/8390/es3210.c +++ b/drivers/net/ethernet/8390/es3210.c | |||
@@ -195,7 +195,7 @@ static int __init es_probe1(struct net_device *dev, int ioaddr) | |||
195 | goto out; | 195 | goto out; |
196 | } | 196 | } |
197 | 197 | ||
198 | for (i = 0; i < ETHER_ADDR_LEN ; i++) | 198 | for (i = 0; i < ETH_ALEN ; i++) |
199 | dev->dev_addr[i] = inb(ioaddr + ES_SA_PROM + i); | 199 | dev->dev_addr[i] = inb(ioaddr + ES_SA_PROM + i); |
200 | 200 | ||
201 | /* Check the Racal vendor ID as well. */ | 201 | /* Check the Racal vendor ID as well. */ |
diff --git a/drivers/net/ethernet/8390/hp-plus.c b/drivers/net/ethernet/8390/hp-plus.c index eeac843dcd2d..d42938b6b596 100644 --- a/drivers/net/ethernet/8390/hp-plus.c +++ b/drivers/net/ethernet/8390/hp-plus.c | |||
@@ -202,7 +202,7 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr) | |||
202 | /* Retrieve and checksum the station address. */ | 202 | /* Retrieve and checksum the station address. */ |
203 | outw(MAC_Page, ioaddr + HP_PAGING); | 203 | outw(MAC_Page, ioaddr + HP_PAGING); |
204 | 204 | ||
205 | for(i = 0; i < ETHER_ADDR_LEN; i++) { | 205 | for(i = 0; i < ETH_ALEN; i++) { |
206 | unsigned char inval = inb(ioaddr + 8 + i); | 206 | unsigned char inval = inb(ioaddr + 8 + i); |
207 | dev->dev_addr[i] = inval; | 207 | dev->dev_addr[i] = inval; |
208 | checksum += inval; | 208 | checksum += inval; |
diff --git a/drivers/net/ethernet/8390/hp.c b/drivers/net/ethernet/8390/hp.c index 18564d4a7c04..113f1e075a26 100644 --- a/drivers/net/ethernet/8390/hp.c +++ b/drivers/net/ethernet/8390/hp.c | |||
@@ -156,7 +156,7 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr) | |||
156 | 156 | ||
157 | printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr); | 157 | printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr); |
158 | 158 | ||
159 | for(i = 0; i < ETHER_ADDR_LEN; i++) | 159 | for(i = 0; i < ETH_ALEN; i++) |
160 | dev->dev_addr[i] = inb(ioaddr + i); | 160 | dev->dev_addr[i] = inb(ioaddr + i); |
161 | 161 | ||
162 | printk(" %pM", dev->dev_addr); | 162 | printk(" %pM", dev->dev_addr); |
diff --git a/drivers/net/ethernet/8390/hydra.c b/drivers/net/ethernet/8390/hydra.c index 3dac937a67c4..5370c884620b 100644 --- a/drivers/net/ethernet/8390/hydra.c +++ b/drivers/net/ethernet/8390/hydra.c | |||
@@ -129,7 +129,7 @@ static int __devinit hydra_init(struct zorro_dev *z) | |||
129 | if (!dev) | 129 | if (!dev) |
130 | return -ENOMEM; | 130 | return -ENOMEM; |
131 | 131 | ||
132 | for(j = 0; j < ETHER_ADDR_LEN; j++) | 132 | for (j = 0; j < ETH_ALEN; j++) |
133 | dev->dev_addr[j] = *((u8 *)(board + HYDRA_ADDRPROM + 2*j)); | 133 | dev->dev_addr[j] = *((u8 *)(board + HYDRA_ADDRPROM + 2*j)); |
134 | 134 | ||
135 | /* We must set the 8390 for word mode. */ | 135 | /* We must set the 8390 for word mode. */ |
diff --git a/drivers/net/ethernet/8390/lne390.c b/drivers/net/ethernet/8390/lne390.c index f9888d20177b..69490ae018ea 100644 --- a/drivers/net/ethernet/8390/lne390.c +++ b/drivers/net/ethernet/8390/lne390.c | |||
@@ -191,14 +191,14 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr) | |||
191 | || inb(ioaddr + LNE390_SA_PROM + 1) != LNE390_ADDR1 | 191 | || inb(ioaddr + LNE390_SA_PROM + 1) != LNE390_ADDR1 |
192 | || inb(ioaddr + LNE390_SA_PROM + 2) != LNE390_ADDR2 ) { | 192 | || inb(ioaddr + LNE390_SA_PROM + 2) != LNE390_ADDR2 ) { |
193 | printk("lne390.c: card not found"); | 193 | printk("lne390.c: card not found"); |
194 | for(i = 0; i < ETHER_ADDR_LEN; i++) | 194 | for (i = 0; i < ETH_ALEN; i++) |
195 | printk(" %02x", inb(ioaddr + LNE390_SA_PROM + i)); | 195 | printk(" %02x", inb(ioaddr + LNE390_SA_PROM + i)); |
196 | printk(" (invalid prefix).\n"); | 196 | printk(" (invalid prefix).\n"); |
197 | return -ENODEV; | 197 | return -ENODEV; |
198 | } | 198 | } |
199 | #endif | 199 | #endif |
200 | 200 | ||
201 | for(i = 0; i < ETHER_ADDR_LEN; i++) | 201 | for (i = 0; i < ETH_ALEN; i++) |
202 | dev->dev_addr[i] = inb(ioaddr + LNE390_SA_PROM + i); | 202 | dev->dev_addr[i] = inb(ioaddr + LNE390_SA_PROM + i); |
203 | printk("lne390.c: LNE390%X in EISA slot %d, address %pM.\n", | 203 | printk("lne390.c: LNE390%X in EISA slot %d, address %pM.\n", |
204 | 0xa+revision, ioaddr/0x1000, dev->dev_addr); | 204 | 0xa+revision, ioaddr/0x1000, dev->dev_addr); |
diff --git a/drivers/net/ethernet/8390/ne-h8300.c b/drivers/net/ethernet/8390/ne-h8300.c index cd36a6a5f408..9b9c77d5a65c 100644 --- a/drivers/net/ethernet/8390/ne-h8300.c +++ b/drivers/net/ethernet/8390/ne-h8300.c | |||
@@ -312,7 +312,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) | |||
312 | 312 | ||
313 | dev->base_addr = ioaddr; | 313 | dev->base_addr = ioaddr; |
314 | 314 | ||
315 | for(i = 0; i < ETHER_ADDR_LEN; i++) | 315 | for (i = 0; i < ETH_ALEN; i++) |
316 | dev->dev_addr[i] = SA_prom[i]; | 316 | dev->dev_addr[i] = SA_prom[i]; |
317 | printk(" %pM\n", dev->dev_addr); | 317 | printk(" %pM\n", dev->dev_addr); |
318 | 318 | ||
diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c index 1063093b3afc..f92ea2a65a57 100644 --- a/drivers/net/ethernet/8390/ne.c +++ b/drivers/net/ethernet/8390/ne.c | |||
@@ -503,12 +503,12 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) | |||
503 | #ifdef CONFIG_PLAT_MAPPI | 503 | #ifdef CONFIG_PLAT_MAPPI |
504 | outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, | 504 | outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, |
505 | ioaddr + E8390_CMD); /* 0x61 */ | 505 | ioaddr + E8390_CMD); /* 0x61 */ |
506 | for (i = 0 ; i < ETHER_ADDR_LEN ; i++) { | 506 | for (i = 0; i < ETH_ALEN; i++) { |
507 | dev->dev_addr[i] = SA_prom[i] | 507 | dev->dev_addr[i] = SA_prom[i] |
508 | = inb_p(ioaddr + EN1_PHYS_SHIFT(i)); | 508 | = inb_p(ioaddr + EN1_PHYS_SHIFT(i)); |
509 | } | 509 | } |
510 | #else | 510 | #else |
511 | for(i = 0; i < ETHER_ADDR_LEN; i++) { | 511 | for (i = 0; i < ETH_ALEN; i++) { |
512 | dev->dev_addr[i] = SA_prom[i]; | 512 | dev->dev_addr[i] = SA_prom[i]; |
513 | } | 513 | } |
514 | #endif | 514 | #endif |
diff --git a/drivers/net/ethernet/8390/ne2.c b/drivers/net/ethernet/8390/ne2.c index 70cdc6996342..922b32036c63 100644 --- a/drivers/net/ethernet/8390/ne2.c +++ b/drivers/net/ethernet/8390/ne2.c | |||
@@ -460,7 +460,7 @@ static int __init ne2_probe1(struct net_device *dev, int slot) | |||
460 | 460 | ||
461 | dev->base_addr = base_addr; | 461 | dev->base_addr = base_addr; |
462 | 462 | ||
463 | for(i = 0; i < ETHER_ADDR_LEN; i++) | 463 | for (i = 0; i < ETH_ALEN; i++) |
464 | dev->dev_addr[i] = SA_prom[i]; | 464 | dev->dev_addr[i] = SA_prom[i]; |
465 | 465 | ||
466 | printk(" %pM\n", dev->dev_addr); | 466 | printk(" %pM\n", dev->dev_addr); |
diff --git a/drivers/net/ethernet/8390/ne2k-pci.c b/drivers/net/ethernet/8390/ne2k-pci.c index 39923425ba25..3fab04a0034a 100644 --- a/drivers/net/ethernet/8390/ne2k-pci.c +++ b/drivers/net/ethernet/8390/ne2k-pci.c | |||
@@ -639,9 +639,9 @@ static void ne2k_pci_get_drvinfo(struct net_device *dev, | |||
639 | struct ei_device *ei = netdev_priv(dev); | 639 | struct ei_device *ei = netdev_priv(dev); |
640 | struct pci_dev *pci_dev = (struct pci_dev *) ei->priv; | 640 | struct pci_dev *pci_dev = (struct pci_dev *) ei->priv; |
641 | 641 | ||
642 | strcpy(info->driver, DRV_NAME); | 642 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
643 | strcpy(info->version, DRV_VERSION); | 643 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
644 | strcpy(info->bus_info, pci_name(pci_dev)); | 644 | strlcpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info)); |
645 | } | 645 | } |
646 | 646 | ||
647 | static const struct ethtool_ops ne2k_pci_ethtool_ops = { | 647 | static const struct ethtool_ops ne2k_pci_ethtool_ops = { |
diff --git a/drivers/net/ethernet/8390/ne3210.c b/drivers/net/ethernet/8390/ne3210.c index 243ed2aee88e..2a3e8057feae 100644 --- a/drivers/net/ethernet/8390/ne3210.c +++ b/drivers/net/ethernet/8390/ne3210.c | |||
@@ -125,7 +125,7 @@ static int __init ne3210_eisa_probe (struct device *device) | |||
125 | #endif | 125 | #endif |
126 | 126 | ||
127 | port_index = inb(ioaddr + NE3210_CFG2) >> 6; | 127 | port_index = inb(ioaddr + NE3210_CFG2) >> 6; |
128 | for(i = 0; i < ETHER_ADDR_LEN; i++) | 128 | for (i = 0; i < ETH_ALEN; i++) |
129 | dev->dev_addr[i] = inb(ioaddr + NE3210_SA_PROM + i); | 129 | dev->dev_addr[i] = inb(ioaddr + NE3210_SA_PROM + i); |
130 | printk("ne3210.c: NE3210 in EISA slot %d, media: %s, addr: %pM.\n", | 130 | printk("ne3210.c: NE3210 in EISA slot %d, media: %s, addr: %pM.\n", |
131 | edev->slot, ifmap[port_index], dev->dev_addr); | 131 | edev->slot, ifmap[port_index], dev->dev_addr); |
diff --git a/drivers/net/ethernet/8390/stnic.c b/drivers/net/ethernet/8390/stnic.c index d85f0a84bc7b..3b903759980a 100644 --- a/drivers/net/ethernet/8390/stnic.c +++ b/drivers/net/ethernet/8390/stnic.c | |||
@@ -114,7 +114,7 @@ static int __init stnic_probe(void) | |||
114 | #ifdef CONFIG_SH_STANDARD_BIOS | 114 | #ifdef CONFIG_SH_STANDARD_BIOS |
115 | sh_bios_get_node_addr (stnic_eadr); | 115 | sh_bios_get_node_addr (stnic_eadr); |
116 | #endif | 116 | #endif |
117 | for (i = 0; i < ETHER_ADDR_LEN; i++) | 117 | for (i = 0; i < ETH_ALEN; i++) |
118 | dev->dev_addr[i] = stnic_eadr[i]; | 118 | dev->dev_addr[i] = stnic_eadr[i]; |
119 | 119 | ||
120 | /* Set the base address to point to the NIC, not the "real" base! */ | 120 | /* Set the base address to point to the NIC, not the "real" base! */ |
diff --git a/drivers/net/ethernet/8390/zorro8390.c b/drivers/net/ethernet/8390/zorro8390.c index 3aa9fe9999b5..bcd27323b203 100644 --- a/drivers/net/ethernet/8390/zorro8390.c +++ b/drivers/net/ethernet/8390/zorro8390.c | |||
@@ -365,7 +365,7 @@ static int __devinit zorro8390_init(struct net_device *dev, | |||
365 | if (i) | 365 | if (i) |
366 | return i; | 366 | return i; |
367 | 367 | ||
368 | for (i = 0; i < ETHER_ADDR_LEN; i++) | 368 | for (i = 0; i < ETH_ALEN; i++) |
369 | dev->dev_addr[i] = SA_prom[i]; | 369 | dev->dev_addr[i] = SA_prom[i]; |
370 | 370 | ||
371 | pr_debug("Found ethernet address: %pM\n", dev->dev_addr); | 371 | pr_debug("Found ethernet address: %pM\n", dev->dev_addr); |
diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c index 6d9f6911000f..a446e251908b 100644 --- a/drivers/net/ethernet/adaptec/starfire.c +++ b/drivers/net/ethernet/adaptec/starfire.c | |||
@@ -1842,9 +1842,9 @@ static int check_if_running(struct net_device *dev) | |||
1842 | static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 1842 | static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
1843 | { | 1843 | { |
1844 | struct netdev_private *np = netdev_priv(dev); | 1844 | struct netdev_private *np = netdev_priv(dev); |
1845 | strcpy(info->driver, DRV_NAME); | 1845 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1846 | strcpy(info->version, DRV_VERSION); | 1846 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1847 | strcpy(info->bus_info, pci_name(np->pci_dev)); | 1847 | strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); |
1848 | } | 1848 | } |
1849 | 1849 | ||
1850 | static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | 1850 | static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) |
diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c index a9745f4ddbfe..33e0a8c20f6b 100644 --- a/drivers/net/ethernet/amd/amd8111e.c +++ b/drivers/net/ethernet/amd/amd8111e.c | |||
@@ -499,7 +499,7 @@ static int amd8111e_restart(struct net_device *dev) | |||
499 | writel( VAL0 | APAD_XMT | REX_RTRY, mmio + CMD2 ); | 499 | writel( VAL0 | APAD_XMT | REX_RTRY, mmio + CMD2 ); |
500 | 500 | ||
501 | /* Setting the MAC address to the device */ | 501 | /* Setting the MAC address to the device */ |
502 | for(i = 0; i < ETH_ADDR_LEN; i++) | 502 | for (i = 0; i < ETH_ALEN; i++) |
503 | writeb( dev->dev_addr[i], mmio + PADR + i ); | 503 | writeb( dev->dev_addr[i], mmio + PADR + i ); |
504 | 504 | ||
505 | /* Enable interrupt coalesce */ | 505 | /* Enable interrupt coalesce */ |
@@ -1412,10 +1412,11 @@ static void amd8111e_get_drvinfo(struct net_device* dev, struct ethtool_drvinfo | |||
1412 | { | 1412 | { |
1413 | struct amd8111e_priv *lp = netdev_priv(dev); | 1413 | struct amd8111e_priv *lp = netdev_priv(dev); |
1414 | struct pci_dev *pci_dev = lp->pci_dev; | 1414 | struct pci_dev *pci_dev = lp->pci_dev; |
1415 | strcpy (info->driver, MODULE_NAME); | 1415 | strlcpy(info->driver, MODULE_NAME, sizeof(info->driver)); |
1416 | strcpy (info->version, MODULE_VERS); | 1416 | strlcpy(info->version, MODULE_VERS, sizeof(info->version)); |
1417 | sprintf(info->fw_version,"%u",chip_version); | 1417 | snprintf(info->fw_version, sizeof(info->fw_version), |
1418 | strcpy (info->bus_info, pci_name(pci_dev)); | 1418 | "%u", chip_version); |
1419 | strlcpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info)); | ||
1419 | } | 1420 | } |
1420 | 1421 | ||
1421 | static int amd8111e_get_regs_len(struct net_device *dev) | 1422 | static int amd8111e_get_regs_len(struct net_device *dev) |
@@ -1549,7 +1550,7 @@ static int amd8111e_set_mac_address(struct net_device *dev, void *p) | |||
1549 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | 1550 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); |
1550 | spin_lock_irq(&lp->lock); | 1551 | spin_lock_irq(&lp->lock); |
1551 | /* Setting the MAC address to the device */ | 1552 | /* Setting the MAC address to the device */ |
1552 | for(i = 0; i < ETH_ADDR_LEN; i++) | 1553 | for (i = 0; i < ETH_ALEN; i++) |
1553 | writeb( dev->dev_addr[i], lp->mmio + PADR + i ); | 1554 | writeb( dev->dev_addr[i], lp->mmio + PADR + i ); |
1554 | 1555 | ||
1555 | spin_unlock_irq(&lp->lock); | 1556 | spin_unlock_irq(&lp->lock); |
@@ -1885,7 +1886,7 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, | |||
1885 | } | 1886 | } |
1886 | 1887 | ||
1887 | /* Initializing MAC address */ | 1888 | /* Initializing MAC address */ |
1888 | for(i = 0; i < ETH_ADDR_LEN; i++) | 1889 | for (i = 0; i < ETH_ALEN; i++) |
1889 | dev->dev_addr[i] = readb(lp->mmio + PADR + i); | 1890 | dev->dev_addr[i] = readb(lp->mmio + PADR + i); |
1890 | 1891 | ||
1891 | /* Setting user defined parametrs */ | 1892 | /* Setting user defined parametrs */ |
diff --git a/drivers/net/ethernet/amd/amd8111e.h b/drivers/net/ethernet/amd/amd8111e.h index 2ff2e7a12dd0..5bbb53a1999c 100644 --- a/drivers/net/ethernet/amd/amd8111e.h +++ b/drivers/net/ethernet/amd/amd8111e.h | |||
@@ -586,7 +586,6 @@ typedef enum { | |||
586 | 586 | ||
587 | #define PKT_BUFF_SZ 1536 | 587 | #define PKT_BUFF_SZ 1536 |
588 | #define MIN_PKT_LEN 60 | 588 | #define MIN_PKT_LEN 60 |
589 | #define ETH_ADDR_LEN 6 | ||
590 | 589 | ||
591 | #define AMD8111E_TX_TIMEOUT (3 * HZ)/* 3 sec */ | 590 | #define AMD8111E_TX_TIMEOUT (3 * HZ)/* 3 sec */ |
592 | #define SOFT_TIMER_FREQ 0xBEBC /* 0.5 sec */ | 591 | #define SOFT_TIMER_FREQ 0xBEBC /* 0.5 sec */ |
diff --git a/drivers/net/ethernet/amd/nmclan_cs.c b/drivers/net/ethernet/amd/nmclan_cs.c index 3accd5d21b08..6be0dd67631a 100644 --- a/drivers/net/ethernet/amd/nmclan_cs.c +++ b/drivers/net/ethernet/amd/nmclan_cs.c | |||
@@ -160,8 +160,6 @@ Include Files | |||
160 | Defines | 160 | Defines |
161 | ---------------------------------------------------------------------------- */ | 161 | ---------------------------------------------------------------------------- */ |
162 | 162 | ||
163 | #define ETHER_ADDR_LEN ETH_ALEN | ||
164 | /* 6 bytes in an Ethernet Address */ | ||
165 | #define MACE_LADRF_LEN 8 | 163 | #define MACE_LADRF_LEN 8 |
166 | /* 8 bytes in Logical Address Filter */ | 164 | /* 8 bytes in Logical Address Filter */ |
167 | 165 | ||
@@ -600,7 +598,7 @@ static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr) | |||
600 | } | 598 | } |
601 | } | 599 | } |
602 | /* Set PADR register */ | 600 | /* Set PADR register */ |
603 | for (i = 0; i < ETHER_ADDR_LEN; i++) | 601 | for (i = 0; i < ETH_ALEN; i++) |
604 | mace_write(lp, ioaddr, MACE_PADR, enet_addr[i]); | 602 | mace_write(lp, ioaddr, MACE_PADR, enet_addr[i]); |
605 | 603 | ||
606 | /* MAC Configuration Control Register should be written last */ | 604 | /* MAC Configuration Control Register should be written last */ |
@@ -639,11 +637,11 @@ static int nmclan_config(struct pcmcia_device *link) | |||
639 | 637 | ||
640 | /* Read the ethernet address from the CIS. */ | 638 | /* Read the ethernet address from the CIS. */ |
641 | len = pcmcia_get_tuple(link, 0x80, &buf); | 639 | len = pcmcia_get_tuple(link, 0x80, &buf); |
642 | if (!buf || len < ETHER_ADDR_LEN) { | 640 | if (!buf || len < ETH_ALEN) { |
643 | kfree(buf); | 641 | kfree(buf); |
644 | goto failed; | 642 | goto failed; |
645 | } | 643 | } |
646 | memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN); | 644 | memcpy(dev->dev_addr, buf, ETH_ALEN); |
647 | kfree(buf); | 645 | kfree(buf); |
648 | 646 | ||
649 | /* Verify configuration by reading the MACE ID. */ | 647 | /* Verify configuration by reading the MACE ID. */ |
@@ -822,9 +820,10 @@ static int mace_close(struct net_device *dev) | |||
822 | static void netdev_get_drvinfo(struct net_device *dev, | 820 | static void netdev_get_drvinfo(struct net_device *dev, |
823 | struct ethtool_drvinfo *info) | 821 | struct ethtool_drvinfo *info) |
824 | { | 822 | { |
825 | strcpy(info->driver, DRV_NAME); | 823 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
826 | strcpy(info->version, DRV_VERSION); | 824 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
827 | sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); | 825 | snprintf(info->bus_info, sizeof(info->bus_info), |
826 | "PCMCIA 0x%lx", dev->base_addr); | ||
828 | } | 827 | } |
829 | 828 | ||
830 | static const struct ethtool_ops netdev_ethtool_ops = { | 829 | static const struct ethtool_ops netdev_ethtool_ops = { |
@@ -1420,7 +1419,7 @@ Output | |||
1420 | static void set_multicast_list(struct net_device *dev) | 1419 | static void set_multicast_list(struct net_device *dev) |
1421 | { | 1420 | { |
1422 | mace_private *lp = netdev_priv(dev); | 1421 | mace_private *lp = netdev_priv(dev); |
1423 | int adr[ETHER_ADDR_LEN] = {0}; /* Ethernet address */ | 1422 | int adr[ETH_ALEN] = {0}; /* Ethernet address */ |
1424 | struct netdev_hw_addr *ha; | 1423 | struct netdev_hw_addr *ha; |
1425 | 1424 | ||
1426 | #ifdef PCMCIA_DEBUG | 1425 | #ifdef PCMCIA_DEBUG |
@@ -1442,7 +1441,7 @@ static void set_multicast_list(struct net_device *dev) | |||
1442 | /* Calculate multicast logical address filter */ | 1441 | /* Calculate multicast logical address filter */ |
1443 | memset(lp->multicast_ladrf, 0, MACE_LADRF_LEN); | 1442 | memset(lp->multicast_ladrf, 0, MACE_LADRF_LEN); |
1444 | netdev_for_each_mc_addr(ha, dev) { | 1443 | netdev_for_each_mc_addr(ha, dev) { |
1445 | memcpy(adr, ha->addr, ETHER_ADDR_LEN); | 1444 | memcpy(adr, ha->addr, ETH_ALEN); |
1446 | BuildLAF(lp->multicast_ladrf, adr); | 1445 | BuildLAF(lp->multicast_ladrf, adr); |
1447 | } | 1446 | } |
1448 | } | 1447 | } |
diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c index f92bc6e34828..20e6dab0186c 100644 --- a/drivers/net/ethernet/amd/pcnet32.c +++ b/drivers/net/ethernet/amd/pcnet32.c | |||
@@ -711,12 +711,14 @@ static void pcnet32_get_drvinfo(struct net_device *dev, | |||
711 | { | 711 | { |
712 | struct pcnet32_private *lp = netdev_priv(dev); | 712 | struct pcnet32_private *lp = netdev_priv(dev); |
713 | 713 | ||
714 | strcpy(info->driver, DRV_NAME); | 714 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
715 | strcpy(info->version, DRV_VERSION); | 715 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
716 | if (lp->pci_dev) | 716 | if (lp->pci_dev) |
717 | strcpy(info->bus_info, pci_name(lp->pci_dev)); | 717 | strlcpy(info->bus_info, pci_name(lp->pci_dev), |
718 | sizeof(info->bus_info)); | ||
718 | else | 719 | else |
719 | sprintf(info->bus_info, "VLB 0x%lx", dev->base_addr); | 720 | snprintf(info->bus_info, sizeof(info->bus_info), |
721 | "VLB 0x%lx", dev->base_addr); | ||
720 | } | 722 | } |
721 | 723 | ||
722 | static u32 pcnet32_get_link(struct net_device *dev) | 724 | static u32 pcnet32_get_link(struct net_device *dev) |
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c index 7be884d0aaf6..0a9326aa58b5 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c | |||
@@ -232,7 +232,6 @@ static void atl1c_get_drvinfo(struct net_device *netdev, | |||
232 | strlcpy(drvinfo->driver, atl1c_driver_name, sizeof(drvinfo->driver)); | 232 | strlcpy(drvinfo->driver, atl1c_driver_name, sizeof(drvinfo->driver)); |
233 | strlcpy(drvinfo->version, atl1c_driver_version, | 233 | strlcpy(drvinfo->version, atl1c_driver_version, |
234 | sizeof(drvinfo->version)); | 234 | sizeof(drvinfo->version)); |
235 | strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); | ||
236 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), | 235 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), |
237 | sizeof(drvinfo->bus_info)); | 236 | sizeof(drvinfo->bus_info)); |
238 | drvinfo->n_stats = 0; | 237 | drvinfo->n_stats = 0; |
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 02c7ed8d9eca..b8591246eb4c 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c | |||
@@ -411,7 +411,7 @@ static void atl1c_set_multi(struct net_device *netdev) | |||
411 | } | 411 | } |
412 | } | 412 | } |
413 | 413 | ||
414 | static void __atl1c_vlan_mode(u32 features, u32 *mac_ctrl_data) | 414 | static void __atl1c_vlan_mode(netdev_features_t features, u32 *mac_ctrl_data) |
415 | { | 415 | { |
416 | if (features & NETIF_F_HW_VLAN_RX) { | 416 | if (features & NETIF_F_HW_VLAN_RX) { |
417 | /* enable VLAN tag insert/strip */ | 417 | /* enable VLAN tag insert/strip */ |
@@ -422,7 +422,8 @@ static void __atl1c_vlan_mode(u32 features, u32 *mac_ctrl_data) | |||
422 | } | 422 | } |
423 | } | 423 | } |
424 | 424 | ||
425 | static void atl1c_vlan_mode(struct net_device *netdev, u32 features) | 425 | static void atl1c_vlan_mode(struct net_device *netdev, |
426 | netdev_features_t features) | ||
426 | { | 427 | { |
427 | struct atl1c_adapter *adapter = netdev_priv(netdev); | 428 | struct atl1c_adapter *adapter = netdev_priv(netdev); |
428 | struct pci_dev *pdev = adapter->pdev; | 429 | struct pci_dev *pdev = adapter->pdev; |
@@ -482,7 +483,8 @@ static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter, | |||
482 | roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE; | 483 | roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE; |
483 | } | 484 | } |
484 | 485 | ||
485 | static u32 atl1c_fix_features(struct net_device *netdev, u32 features) | 486 | static netdev_features_t atl1c_fix_features(struct net_device *netdev, |
487 | netdev_features_t features) | ||
486 | { | 488 | { |
487 | /* | 489 | /* |
488 | * Since there is no support for separate rx/tx vlan accel | 490 | * Since there is no support for separate rx/tx vlan accel |
@@ -499,9 +501,10 @@ static u32 atl1c_fix_features(struct net_device *netdev, u32 features) | |||
499 | return features; | 501 | return features; |
500 | } | 502 | } |
501 | 503 | ||
502 | static int atl1c_set_features(struct net_device *netdev, u32 features) | 504 | static int atl1c_set_features(struct net_device *netdev, |
505 | netdev_features_t features) | ||
503 | { | 506 | { |
504 | u32 changed = netdev->features ^ features; | 507 | netdev_features_t changed = netdev->features ^ features; |
505 | 508 | ||
506 | if (changed & NETIF_F_HW_VLAN_RX) | 509 | if (changed & NETIF_F_HW_VLAN_RX) |
507 | atl1c_vlan_mode(netdev, features); | 510 | atl1c_vlan_mode(netdev, features); |
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c index 6269438d365f..6e61f9f9ebb5 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c | |||
@@ -310,10 +310,12 @@ static void atl1e_get_drvinfo(struct net_device *netdev, | |||
310 | { | 310 | { |
311 | struct atl1e_adapter *adapter = netdev_priv(netdev); | 311 | struct atl1e_adapter *adapter = netdev_priv(netdev); |
312 | 312 | ||
313 | strncpy(drvinfo->driver, atl1e_driver_name, 32); | 313 | strlcpy(drvinfo->driver, atl1e_driver_name, sizeof(drvinfo->driver)); |
314 | strncpy(drvinfo->version, atl1e_driver_version, 32); | 314 | strlcpy(drvinfo->version, atl1e_driver_version, |
315 | strncpy(drvinfo->fw_version, "L1e", 32); | 315 | sizeof(drvinfo->version)); |
316 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | 316 | strlcpy(drvinfo->fw_version, "L1e", sizeof(drvinfo->fw_version)); |
317 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), | ||
318 | sizeof(drvinfo->bus_info)); | ||
317 | drvinfo->n_stats = 0; | 319 | drvinfo->n_stats = 0; |
318 | drvinfo->testinfo_len = 0; | 320 | drvinfo->testinfo_len = 0; |
319 | drvinfo->regdump_len = atl1e_get_regs_len(netdev); | 321 | drvinfo->regdump_len = atl1e_get_regs_len(netdev); |
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 95483bcac1d0..c915c0873810 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c | |||
@@ -313,7 +313,7 @@ static void atl1e_set_multi(struct net_device *netdev) | |||
313 | } | 313 | } |
314 | } | 314 | } |
315 | 315 | ||
316 | static void __atl1e_vlan_mode(u32 features, u32 *mac_ctrl_data) | 316 | static void __atl1e_vlan_mode(netdev_features_t features, u32 *mac_ctrl_data) |
317 | { | 317 | { |
318 | if (features & NETIF_F_HW_VLAN_RX) { | 318 | if (features & NETIF_F_HW_VLAN_RX) { |
319 | /* enable VLAN tag insert/strip */ | 319 | /* enable VLAN tag insert/strip */ |
@@ -324,7 +324,8 @@ static void __atl1e_vlan_mode(u32 features, u32 *mac_ctrl_data) | |||
324 | } | 324 | } |
325 | } | 325 | } |
326 | 326 | ||
327 | static void atl1e_vlan_mode(struct net_device *netdev, u32 features) | 327 | static void atl1e_vlan_mode(struct net_device *netdev, |
328 | netdev_features_t features) | ||
328 | { | 329 | { |
329 | struct atl1e_adapter *adapter = netdev_priv(netdev); | 330 | struct atl1e_adapter *adapter = netdev_priv(netdev); |
330 | u32 mac_ctrl_data = 0; | 331 | u32 mac_ctrl_data = 0; |
@@ -370,7 +371,8 @@ static int atl1e_set_mac_addr(struct net_device *netdev, void *p) | |||
370 | return 0; | 371 | return 0; |
371 | } | 372 | } |
372 | 373 | ||
373 | static u32 atl1e_fix_features(struct net_device *netdev, u32 features) | 374 | static netdev_features_t atl1e_fix_features(struct net_device *netdev, |
375 | netdev_features_t features) | ||
374 | { | 376 | { |
375 | /* | 377 | /* |
376 | * Since there is no support for separate rx/tx vlan accel | 378 | * Since there is no support for separate rx/tx vlan accel |
@@ -384,9 +386,10 @@ static u32 atl1e_fix_features(struct net_device *netdev, u32 features) | |||
384 | return features; | 386 | return features; |
385 | } | 387 | } |
386 | 388 | ||
387 | static int atl1e_set_features(struct net_device *netdev, u32 features) | 389 | static int atl1e_set_features(struct net_device *netdev, |
390 | netdev_features_t features) | ||
388 | { | 391 | { |
389 | u32 changed = netdev->features ^ features; | 392 | netdev_features_t changed = netdev->features ^ features; |
390 | 393 | ||
391 | if (changed & NETIF_F_HW_VLAN_RX) | 394 | if (changed & NETIF_F_HW_VLAN_RX) |
392 | atl1e_vlan_mode(netdev, features); | 395 | atl1e_vlan_mode(netdev, features); |
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c index 33a4e35f5ee8..9bd204976648 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/drivers/net/ethernet/atheros/atlx/atl1.c | |||
@@ -3365,7 +3365,6 @@ static void atl1_get_drvinfo(struct net_device *netdev, | |||
3365 | strlcpy(drvinfo->driver, ATLX_DRIVER_NAME, sizeof(drvinfo->driver)); | 3365 | strlcpy(drvinfo->driver, ATLX_DRIVER_NAME, sizeof(drvinfo->driver)); |
3366 | strlcpy(drvinfo->version, ATLX_DRIVER_VERSION, | 3366 | strlcpy(drvinfo->version, ATLX_DRIVER_VERSION, |
3367 | sizeof(drvinfo->version)); | 3367 | sizeof(drvinfo->version)); |
3368 | strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); | ||
3369 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), | 3368 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), |
3370 | sizeof(drvinfo->bus_info)); | 3369 | sizeof(drvinfo->bus_info)); |
3371 | drvinfo->eedump_len = ATL1_EEDUMP_LEN; | 3370 | drvinfo->eedump_len = ATL1_EEDUMP_LEN; |
diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c index 1feae5928a4b..071f4c858969 100644 --- a/drivers/net/ethernet/atheros/atlx/atl2.c +++ b/drivers/net/ethernet/atheros/atlx/atl2.c | |||
@@ -361,7 +361,7 @@ static inline void atl2_irq_disable(struct atl2_adapter *adapter) | |||
361 | synchronize_irq(adapter->pdev->irq); | 361 | synchronize_irq(adapter->pdev->irq); |
362 | } | 362 | } |
363 | 363 | ||
364 | static void __atl2_vlan_mode(u32 features, u32 *ctrl) | 364 | static void __atl2_vlan_mode(netdev_features_t features, u32 *ctrl) |
365 | { | 365 | { |
366 | if (features & NETIF_F_HW_VLAN_RX) { | 366 | if (features & NETIF_F_HW_VLAN_RX) { |
367 | /* enable VLAN tag insert/strip */ | 367 | /* enable VLAN tag insert/strip */ |
@@ -372,7 +372,8 @@ static void __atl2_vlan_mode(u32 features, u32 *ctrl) | |||
372 | } | 372 | } |
373 | } | 373 | } |
374 | 374 | ||
375 | static void atl2_vlan_mode(struct net_device *netdev, u32 features) | 375 | static void atl2_vlan_mode(struct net_device *netdev, |
376 | netdev_features_t features) | ||
376 | { | 377 | { |
377 | struct atl2_adapter *adapter = netdev_priv(netdev); | 378 | struct atl2_adapter *adapter = netdev_priv(netdev); |
378 | u32 ctrl; | 379 | u32 ctrl; |
@@ -391,7 +392,8 @@ static void atl2_restore_vlan(struct atl2_adapter *adapter) | |||
391 | atl2_vlan_mode(adapter->netdev, adapter->netdev->features); | 392 | atl2_vlan_mode(adapter->netdev, adapter->netdev->features); |
392 | } | 393 | } |
393 | 394 | ||
394 | static u32 atl2_fix_features(struct net_device *netdev, u32 features) | 395 | static netdev_features_t atl2_fix_features(struct net_device *netdev, |
396 | netdev_features_t features) | ||
395 | { | 397 | { |
396 | /* | 398 | /* |
397 | * Since there is no support for separate rx/tx vlan accel | 399 | * Since there is no support for separate rx/tx vlan accel |
@@ -405,9 +407,10 @@ static u32 atl2_fix_features(struct net_device *netdev, u32 features) | |||
405 | return features; | 407 | return features; |
406 | } | 408 | } |
407 | 409 | ||
408 | static int atl2_set_features(struct net_device *netdev, u32 features) | 410 | static int atl2_set_features(struct net_device *netdev, |
411 | netdev_features_t features) | ||
409 | { | 412 | { |
410 | u32 changed = netdev->features ^ features; | 413 | netdev_features_t changed = netdev->features ^ features; |
411 | 414 | ||
412 | if (changed & NETIF_F_HW_VLAN_RX) | 415 | if (changed & NETIF_F_HW_VLAN_RX) |
413 | atl2_vlan_mode(netdev, features); | 416 | atl2_vlan_mode(netdev, features); |
@@ -2049,10 +2052,12 @@ static void atl2_get_drvinfo(struct net_device *netdev, | |||
2049 | { | 2052 | { |
2050 | struct atl2_adapter *adapter = netdev_priv(netdev); | 2053 | struct atl2_adapter *adapter = netdev_priv(netdev); |
2051 | 2054 | ||
2052 | strncpy(drvinfo->driver, atl2_driver_name, 32); | 2055 | strlcpy(drvinfo->driver, atl2_driver_name, sizeof(drvinfo->driver)); |
2053 | strncpy(drvinfo->version, atl2_driver_version, 32); | 2056 | strlcpy(drvinfo->version, atl2_driver_version, |
2054 | strncpy(drvinfo->fw_version, "L2", 32); | 2057 | sizeof(drvinfo->version)); |
2055 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | 2058 | strlcpy(drvinfo->fw_version, "L2", sizeof(drvinfo->fw_version)); |
2059 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), | ||
2060 | sizeof(drvinfo->bus_info)); | ||
2056 | drvinfo->n_stats = 0; | 2061 | drvinfo->n_stats = 0; |
2057 | drvinfo->testinfo_len = 0; | 2062 | drvinfo->testinfo_len = 0; |
2058 | drvinfo->regdump_len = atl2_get_regs_len(netdev); | 2063 | drvinfo->regdump_len = atl2_get_regs_len(netdev); |
diff --git a/drivers/net/ethernet/atheros/atlx/atlx.c b/drivers/net/ethernet/atheros/atlx/atlx.c index aabcf4b5745a..8ff7411094d5 100644 --- a/drivers/net/ethernet/atheros/atlx/atlx.c +++ b/drivers/net/ethernet/atheros/atlx/atlx.c | |||
@@ -211,7 +211,7 @@ static void atlx_link_chg_task(struct work_struct *work) | |||
211 | spin_unlock_irqrestore(&adapter->lock, flags); | 211 | spin_unlock_irqrestore(&adapter->lock, flags); |
212 | } | 212 | } |
213 | 213 | ||
214 | static void __atlx_vlan_mode(u32 features, u32 *ctrl) | 214 | static void __atlx_vlan_mode(netdev_features_t features, u32 *ctrl) |
215 | { | 215 | { |
216 | if (features & NETIF_F_HW_VLAN_RX) { | 216 | if (features & NETIF_F_HW_VLAN_RX) { |
217 | /* enable VLAN tag insert/strip */ | 217 | /* enable VLAN tag insert/strip */ |
@@ -222,7 +222,8 @@ static void __atlx_vlan_mode(u32 features, u32 *ctrl) | |||
222 | } | 222 | } |
223 | } | 223 | } |
224 | 224 | ||
225 | static void atlx_vlan_mode(struct net_device *netdev, u32 features) | 225 | static void atlx_vlan_mode(struct net_device *netdev, |
226 | netdev_features_t features) | ||
226 | { | 227 | { |
227 | struct atlx_adapter *adapter = netdev_priv(netdev); | 228 | struct atlx_adapter *adapter = netdev_priv(netdev); |
228 | unsigned long flags; | 229 | unsigned long flags; |
@@ -242,7 +243,8 @@ static void atlx_restore_vlan(struct atlx_adapter *adapter) | |||
242 | atlx_vlan_mode(adapter->netdev, adapter->netdev->features); | 243 | atlx_vlan_mode(adapter->netdev, adapter->netdev->features); |
243 | } | 244 | } |
244 | 245 | ||
245 | static u32 atlx_fix_features(struct net_device *netdev, u32 features) | 246 | static netdev_features_t atlx_fix_features(struct net_device *netdev, |
247 | netdev_features_t features) | ||
246 | { | 248 | { |
247 | /* | 249 | /* |
248 | * Since there is no support for separate rx/tx vlan accel | 250 | * Since there is no support for separate rx/tx vlan accel |
@@ -256,9 +258,10 @@ static u32 atlx_fix_features(struct net_device *netdev, u32 features) | |||
256 | return features; | 258 | return features; |
257 | } | 259 | } |
258 | 260 | ||
259 | static int atlx_set_features(struct net_device *netdev, u32 features) | 261 | static int atlx_set_features(struct net_device *netdev, |
262 | netdev_features_t features) | ||
260 | { | 263 | { |
261 | u32 changed = netdev->features ^ features; | 264 | netdev_features_t changed = netdev->features ^ features; |
262 | 265 | ||
263 | if (changed & NETIF_F_HW_VLAN_RX) | 266 | if (changed & NETIF_F_HW_VLAN_RX) |
264 | atlx_vlan_mode(netdev, features); | 267 | atlx_vlan_mode(netdev, features); |
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 965c7235804d..d573169279b7 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c | |||
@@ -409,7 +409,7 @@ static int bnx2_unregister_cnic(struct net_device *dev) | |||
409 | mutex_lock(&bp->cnic_lock); | 409 | mutex_lock(&bp->cnic_lock); |
410 | cp->drv_state = 0; | 410 | cp->drv_state = 0; |
411 | bnapi->cnic_present = 0; | 411 | bnapi->cnic_present = 0; |
412 | rcu_assign_pointer(bp->cnic_ops, NULL); | 412 | RCU_INIT_POINTER(bp->cnic_ops, NULL); |
413 | mutex_unlock(&bp->cnic_lock); | 413 | mutex_unlock(&bp->cnic_lock); |
414 | synchronize_rcu(); | 414 | synchronize_rcu(); |
415 | return 0; | 415 | return 0; |
@@ -2054,8 +2054,8 @@ __acquires(&bp->phy_lock) | |||
2054 | 2054 | ||
2055 | if (bp->autoneg & AUTONEG_SPEED) { | 2055 | if (bp->autoneg & AUTONEG_SPEED) { |
2056 | u32 adv_reg, adv1000_reg; | 2056 | u32 adv_reg, adv1000_reg; |
2057 | u32 new_adv_reg = 0; | 2057 | u32 new_adv = 0; |
2058 | u32 new_adv1000_reg = 0; | 2058 | u32 new_adv1000 = 0; |
2059 | 2059 | ||
2060 | bnx2_read_phy(bp, bp->mii_adv, &adv_reg); | 2060 | bnx2_read_phy(bp, bp->mii_adv, &adv_reg); |
2061 | adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP | | 2061 | adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP | |
@@ -2064,27 +2064,18 @@ __acquires(&bp->phy_lock) | |||
2064 | bnx2_read_phy(bp, MII_CTRL1000, &adv1000_reg); | 2064 | bnx2_read_phy(bp, MII_CTRL1000, &adv1000_reg); |
2065 | adv1000_reg &= PHY_ALL_1000_SPEED; | 2065 | adv1000_reg &= PHY_ALL_1000_SPEED; |
2066 | 2066 | ||
2067 | if (bp->advertising & ADVERTISED_10baseT_Half) | 2067 | new_adv = ethtool_adv_to_mii_adv_t(bp->advertising); |
2068 | new_adv_reg |= ADVERTISE_10HALF; | 2068 | new_adv |= ADVERTISE_CSMA; |
2069 | if (bp->advertising & ADVERTISED_10baseT_Full) | 2069 | new_adv |= bnx2_phy_get_pause_adv(bp); |
2070 | new_adv_reg |= ADVERTISE_10FULL; | ||
2071 | if (bp->advertising & ADVERTISED_100baseT_Half) | ||
2072 | new_adv_reg |= ADVERTISE_100HALF; | ||
2073 | if (bp->advertising & ADVERTISED_100baseT_Full) | ||
2074 | new_adv_reg |= ADVERTISE_100FULL; | ||
2075 | if (bp->advertising & ADVERTISED_1000baseT_Full) | ||
2076 | new_adv1000_reg |= ADVERTISE_1000FULL; | ||
2077 | 2070 | ||
2078 | new_adv_reg |= ADVERTISE_CSMA; | 2071 | new_adv1000 |= ethtool_adv_to_mii_ctrl1000_t(bp->advertising); |
2079 | 2072 | ||
2080 | new_adv_reg |= bnx2_phy_get_pause_adv(bp); | 2073 | if ((adv1000_reg != new_adv1000) || |
2081 | 2074 | (adv_reg != new_adv) || | |
2082 | if ((adv1000_reg != new_adv1000_reg) || | ||
2083 | (adv_reg != new_adv_reg) || | ||
2084 | ((bmcr & BMCR_ANENABLE) == 0)) { | 2075 | ((bmcr & BMCR_ANENABLE) == 0)) { |
2085 | 2076 | ||
2086 | bnx2_write_phy(bp, bp->mii_adv, new_adv_reg); | 2077 | bnx2_write_phy(bp, bp->mii_adv, new_adv); |
2087 | bnx2_write_phy(bp, MII_CTRL1000, new_adv1000_reg); | 2078 | bnx2_write_phy(bp, MII_CTRL1000, new_adv1000); |
2088 | bnx2_write_phy(bp, bp->mii_bmcr, BMCR_ANRESTART | | 2079 | bnx2_write_phy(bp, bp->mii_bmcr, BMCR_ANRESTART | |
2089 | BMCR_ANENABLE); | 2080 | BMCR_ANENABLE); |
2090 | } | 2081 | } |
@@ -2734,31 +2725,27 @@ bnx2_free_rx_page(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index) | |||
2734 | } | 2725 | } |
2735 | 2726 | ||
2736 | static inline int | 2727 | static inline int |
2737 | bnx2_alloc_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index, gfp_t gfp) | 2728 | bnx2_alloc_rx_data(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index, gfp_t gfp) |
2738 | { | 2729 | { |
2739 | struct sk_buff *skb; | 2730 | u8 *data; |
2740 | struct sw_bd *rx_buf = &rxr->rx_buf_ring[index]; | 2731 | struct sw_bd *rx_buf = &rxr->rx_buf_ring[index]; |
2741 | dma_addr_t mapping; | 2732 | dma_addr_t mapping; |
2742 | struct rx_bd *rxbd = &rxr->rx_desc_ring[RX_RING(index)][RX_IDX(index)]; | 2733 | struct rx_bd *rxbd = &rxr->rx_desc_ring[RX_RING(index)][RX_IDX(index)]; |
2743 | unsigned long align; | ||
2744 | 2734 | ||
2745 | skb = __netdev_alloc_skb(bp->dev, bp->rx_buf_size, gfp); | 2735 | data = kmalloc(bp->rx_buf_size, gfp); |
2746 | if (skb == NULL) { | 2736 | if (!data) |
2747 | return -ENOMEM; | 2737 | return -ENOMEM; |
2748 | } | ||
2749 | 2738 | ||
2750 | if (unlikely((align = (unsigned long) skb->data & (BNX2_RX_ALIGN - 1)))) | 2739 | mapping = dma_map_single(&bp->pdev->dev, |
2751 | skb_reserve(skb, BNX2_RX_ALIGN - align); | 2740 | get_l2_fhdr(data), |
2752 | 2741 | bp->rx_buf_use_size, | |
2753 | mapping = dma_map_single(&bp->pdev->dev, skb->data, bp->rx_buf_use_size, | ||
2754 | PCI_DMA_FROMDEVICE); | 2742 | PCI_DMA_FROMDEVICE); |
2755 | if (dma_mapping_error(&bp->pdev->dev, mapping)) { | 2743 | if (dma_mapping_error(&bp->pdev->dev, mapping)) { |
2756 | dev_kfree_skb(skb); | 2744 | kfree(data); |
2757 | return -EIO; | 2745 | return -EIO; |
2758 | } | 2746 | } |
2759 | 2747 | ||
2760 | rx_buf->skb = skb; | 2748 | rx_buf->data = data; |
2761 | rx_buf->desc = (struct l2_fhdr *) skb->data; | ||
2762 | dma_unmap_addr_set(rx_buf, mapping, mapping); | 2749 | dma_unmap_addr_set(rx_buf, mapping, mapping); |
2763 | 2750 | ||
2764 | rxbd->rx_bd_haddr_hi = (u64) mapping >> 32; | 2751 | rxbd->rx_bd_haddr_hi = (u64) mapping >> 32; |
@@ -2965,8 +2952,8 @@ bnx2_reuse_rx_skb_pages(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, | |||
2965 | } | 2952 | } |
2966 | 2953 | ||
2967 | static inline void | 2954 | static inline void |
2968 | bnx2_reuse_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, | 2955 | bnx2_reuse_rx_data(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, |
2969 | struct sk_buff *skb, u16 cons, u16 prod) | 2956 | u8 *data, u16 cons, u16 prod) |
2970 | { | 2957 | { |
2971 | struct sw_bd *cons_rx_buf, *prod_rx_buf; | 2958 | struct sw_bd *cons_rx_buf, *prod_rx_buf; |
2972 | struct rx_bd *cons_bd, *prod_bd; | 2959 | struct rx_bd *cons_bd, *prod_bd; |
@@ -2980,8 +2967,7 @@ bnx2_reuse_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, | |||
2980 | 2967 | ||
2981 | rxr->rx_prod_bseq += bp->rx_buf_use_size; | 2968 | rxr->rx_prod_bseq += bp->rx_buf_use_size; |
2982 | 2969 | ||
2983 | prod_rx_buf->skb = skb; | 2970 | prod_rx_buf->data = data; |
2984 | prod_rx_buf->desc = (struct l2_fhdr *) skb->data; | ||
2985 | 2971 | ||
2986 | if (cons == prod) | 2972 | if (cons == prod) |
2987 | return; | 2973 | return; |
@@ -2995,33 +2981,39 @@ bnx2_reuse_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, | |||
2995 | prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo; | 2981 | prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo; |
2996 | } | 2982 | } |
2997 | 2983 | ||
2998 | static int | 2984 | static struct sk_buff * |
2999 | bnx2_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, struct sk_buff *skb, | 2985 | bnx2_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u8 *data, |
3000 | unsigned int len, unsigned int hdr_len, dma_addr_t dma_addr, | 2986 | unsigned int len, unsigned int hdr_len, dma_addr_t dma_addr, |
3001 | u32 ring_idx) | 2987 | u32 ring_idx) |
3002 | { | 2988 | { |
3003 | int err; | 2989 | int err; |
3004 | u16 prod = ring_idx & 0xffff; | 2990 | u16 prod = ring_idx & 0xffff; |
2991 | struct sk_buff *skb; | ||
3005 | 2992 | ||
3006 | err = bnx2_alloc_rx_skb(bp, rxr, prod, GFP_ATOMIC); | 2993 | err = bnx2_alloc_rx_data(bp, rxr, prod, GFP_ATOMIC); |
3007 | if (unlikely(err)) { | 2994 | if (unlikely(err)) { |
3008 | bnx2_reuse_rx_skb(bp, rxr, skb, (u16) (ring_idx >> 16), prod); | 2995 | bnx2_reuse_rx_data(bp, rxr, data, (u16) (ring_idx >> 16), prod); |
2996 | error: | ||
3009 | if (hdr_len) { | 2997 | if (hdr_len) { |
3010 | unsigned int raw_len = len + 4; | 2998 | unsigned int raw_len = len + 4; |
3011 | int pages = PAGE_ALIGN(raw_len - hdr_len) >> PAGE_SHIFT; | 2999 | int pages = PAGE_ALIGN(raw_len - hdr_len) >> PAGE_SHIFT; |
3012 | 3000 | ||
3013 | bnx2_reuse_rx_skb_pages(bp, rxr, NULL, pages); | 3001 | bnx2_reuse_rx_skb_pages(bp, rxr, NULL, pages); |
3014 | } | 3002 | } |
3015 | return err; | 3003 | return NULL; |
3016 | } | 3004 | } |
3017 | 3005 | ||
3018 | skb_reserve(skb, BNX2_RX_OFFSET); | ||
3019 | dma_unmap_single(&bp->pdev->dev, dma_addr, bp->rx_buf_use_size, | 3006 | dma_unmap_single(&bp->pdev->dev, dma_addr, bp->rx_buf_use_size, |
3020 | PCI_DMA_FROMDEVICE); | 3007 | PCI_DMA_FROMDEVICE); |
3021 | 3008 | skb = build_skb(data); | |
3009 | if (!skb) { | ||
3010 | kfree(data); | ||
3011 | goto error; | ||
3012 | } | ||
3013 | skb_reserve(skb, ((u8 *)get_l2_fhdr(data) - data) + BNX2_RX_OFFSET); | ||
3022 | if (hdr_len == 0) { | 3014 | if (hdr_len == 0) { |
3023 | skb_put(skb, len); | 3015 | skb_put(skb, len); |
3024 | return 0; | 3016 | return skb; |
3025 | } else { | 3017 | } else { |
3026 | unsigned int i, frag_len, frag_size, pages; | 3018 | unsigned int i, frag_len, frag_size, pages; |
3027 | struct sw_pg *rx_pg; | 3019 | struct sw_pg *rx_pg; |
@@ -3052,7 +3044,7 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, struct sk_buff *skb, | |||
3052 | skb_frag_size_sub(frag, tail); | 3044 | skb_frag_size_sub(frag, tail); |
3053 | skb->data_len -= tail; | 3045 | skb->data_len -= tail; |
3054 | } | 3046 | } |
3055 | return 0; | 3047 | return skb; |
3056 | } | 3048 | } |
3057 | rx_pg = &rxr->rx_pg_ring[pg_cons]; | 3049 | rx_pg = &rxr->rx_pg_ring[pg_cons]; |
3058 | 3050 | ||
@@ -3074,7 +3066,7 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, struct sk_buff *skb, | |||
3074 | rxr->rx_pg_prod = pg_prod; | 3066 | rxr->rx_pg_prod = pg_prod; |
3075 | bnx2_reuse_rx_skb_pages(bp, rxr, skb, | 3067 | bnx2_reuse_rx_skb_pages(bp, rxr, skb, |
3076 | pages - i); | 3068 | pages - i); |
3077 | return err; | 3069 | return NULL; |
3078 | } | 3070 | } |
3079 | 3071 | ||
3080 | dma_unmap_page(&bp->pdev->dev, mapping_old, | 3072 | dma_unmap_page(&bp->pdev->dev, mapping_old, |
@@ -3091,7 +3083,7 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, struct sk_buff *skb, | |||
3091 | rxr->rx_pg_prod = pg_prod; | 3083 | rxr->rx_pg_prod = pg_prod; |
3092 | rxr->rx_pg_cons = pg_cons; | 3084 | rxr->rx_pg_cons = pg_cons; |
3093 | } | 3085 | } |
3094 | return 0; | 3086 | return skb; |
3095 | } | 3087 | } |
3096 | 3088 | ||
3097 | static inline u16 | 3089 | static inline u16 |
@@ -3130,19 +3122,17 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) | |||
3130 | struct sw_bd *rx_buf, *next_rx_buf; | 3122 | struct sw_bd *rx_buf, *next_rx_buf; |
3131 | struct sk_buff *skb; | 3123 | struct sk_buff *skb; |
3132 | dma_addr_t dma_addr; | 3124 | dma_addr_t dma_addr; |
3125 | u8 *data; | ||
3133 | 3126 | ||
3134 | sw_ring_cons = RX_RING_IDX(sw_cons); | 3127 | sw_ring_cons = RX_RING_IDX(sw_cons); |
3135 | sw_ring_prod = RX_RING_IDX(sw_prod); | 3128 | sw_ring_prod = RX_RING_IDX(sw_prod); |
3136 | 3129 | ||
3137 | rx_buf = &rxr->rx_buf_ring[sw_ring_cons]; | 3130 | rx_buf = &rxr->rx_buf_ring[sw_ring_cons]; |
3138 | skb = rx_buf->skb; | 3131 | data = rx_buf->data; |
3139 | prefetchw(skb); | 3132 | rx_buf->data = NULL; |
3140 | |||
3141 | next_rx_buf = | ||
3142 | &rxr->rx_buf_ring[RX_RING_IDX(NEXT_RX_BD(sw_cons))]; | ||
3143 | prefetch(next_rx_buf->desc); | ||
3144 | 3133 | ||
3145 | rx_buf->skb = NULL; | 3134 | rx_hdr = get_l2_fhdr(data); |
3135 | prefetch(rx_hdr); | ||
3146 | 3136 | ||
3147 | dma_addr = dma_unmap_addr(rx_buf, mapping); | 3137 | dma_addr = dma_unmap_addr(rx_buf, mapping); |
3148 | 3138 | ||
@@ -3150,7 +3140,10 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) | |||
3150 | BNX2_RX_OFFSET + BNX2_RX_COPY_THRESH, | 3140 | BNX2_RX_OFFSET + BNX2_RX_COPY_THRESH, |
3151 | PCI_DMA_FROMDEVICE); | 3141 | PCI_DMA_FROMDEVICE); |
3152 | 3142 | ||
3153 | rx_hdr = rx_buf->desc; | 3143 | next_rx_buf = |
3144 | &rxr->rx_buf_ring[RX_RING_IDX(NEXT_RX_BD(sw_cons))]; | ||
3145 | prefetch(get_l2_fhdr(next_rx_buf->data)); | ||
3146 | |||
3154 | len = rx_hdr->l2_fhdr_pkt_len; | 3147 | len = rx_hdr->l2_fhdr_pkt_len; |
3155 | status = rx_hdr->l2_fhdr_status; | 3148 | status = rx_hdr->l2_fhdr_status; |
3156 | 3149 | ||
@@ -3169,7 +3162,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) | |||
3169 | L2_FHDR_ERRORS_TOO_SHORT | | 3162 | L2_FHDR_ERRORS_TOO_SHORT | |
3170 | L2_FHDR_ERRORS_GIANT_FRAME))) { | 3163 | L2_FHDR_ERRORS_GIANT_FRAME))) { |
3171 | 3164 | ||
3172 | bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons, | 3165 | bnx2_reuse_rx_data(bp, rxr, data, sw_ring_cons, |
3173 | sw_ring_prod); | 3166 | sw_ring_prod); |
3174 | if (pg_ring_used) { | 3167 | if (pg_ring_used) { |
3175 | int pages; | 3168 | int pages; |
@@ -3184,30 +3177,29 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) | |||
3184 | len -= 4; | 3177 | len -= 4; |
3185 | 3178 | ||
3186 | if (len <= bp->rx_copy_thresh) { | 3179 | if (len <= bp->rx_copy_thresh) { |
3187 | struct sk_buff *new_skb; | 3180 | skb = netdev_alloc_skb(bp->dev, len + 6); |
3188 | 3181 | if (skb == NULL) { | |
3189 | new_skb = netdev_alloc_skb(bp->dev, len + 6); | 3182 | bnx2_reuse_rx_data(bp, rxr, data, sw_ring_cons, |
3190 | if (new_skb == NULL) { | ||
3191 | bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons, | ||
3192 | sw_ring_prod); | 3183 | sw_ring_prod); |
3193 | goto next_rx; | 3184 | goto next_rx; |
3194 | } | 3185 | } |
3195 | 3186 | ||
3196 | /* aligned copy */ | 3187 | /* aligned copy */ |
3197 | skb_copy_from_linear_data_offset(skb, | 3188 | memcpy(skb->data, |
3198 | BNX2_RX_OFFSET - 6, | 3189 | (u8 *)rx_hdr + BNX2_RX_OFFSET - 6, |
3199 | new_skb->data, len + 6); | 3190 | len + 6); |
3200 | skb_reserve(new_skb, 6); | 3191 | skb_reserve(skb, 6); |
3201 | skb_put(new_skb, len); | 3192 | skb_put(skb, len); |
3202 | 3193 | ||
3203 | bnx2_reuse_rx_skb(bp, rxr, skb, | 3194 | bnx2_reuse_rx_data(bp, rxr, data, |
3204 | sw_ring_cons, sw_ring_prod); | 3195 | sw_ring_cons, sw_ring_prod); |
3205 | 3196 | ||
3206 | skb = new_skb; | 3197 | } else { |
3207 | } else if (unlikely(bnx2_rx_skb(bp, rxr, skb, len, hdr_len, | 3198 | skb = bnx2_rx_skb(bp, rxr, data, len, hdr_len, dma_addr, |
3208 | dma_addr, (sw_ring_cons << 16) | sw_ring_prod))) | 3199 | (sw_ring_cons << 16) | sw_ring_prod); |
3209 | goto next_rx; | 3200 | if (!skb) |
3210 | 3201 | goto next_rx; | |
3202 | } | ||
3211 | if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && | 3203 | if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && |
3212 | !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) | 3204 | !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) |
3213 | __vlan_hwaccel_put_tag(skb, rx_hdr->l2_fhdr_vlan_tag); | 3205 | __vlan_hwaccel_put_tag(skb, rx_hdr->l2_fhdr_vlan_tag); |
@@ -5234,7 +5226,7 @@ bnx2_init_rx_ring(struct bnx2 *bp, int ring_num) | |||
5234 | 5226 | ||
5235 | ring_prod = prod = rxr->rx_prod; | 5227 | ring_prod = prod = rxr->rx_prod; |
5236 | for (i = 0; i < bp->rx_ring_size; i++) { | 5228 | for (i = 0; i < bp->rx_ring_size; i++) { |
5237 | if (bnx2_alloc_rx_skb(bp, rxr, ring_prod, GFP_KERNEL) < 0) { | 5229 | if (bnx2_alloc_rx_data(bp, rxr, ring_prod, GFP_KERNEL) < 0) { |
5238 | netdev_warn(bp->dev, "init'ed rx ring %d with %d/%d skbs only\n", | 5230 | netdev_warn(bp->dev, "init'ed rx ring %d with %d/%d skbs only\n", |
5239 | ring_num, i, bp->rx_ring_size); | 5231 | ring_num, i, bp->rx_ring_size); |
5240 | break; | 5232 | break; |
@@ -5329,7 +5321,7 @@ bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size) | |||
5329 | rx_size = bp->dev->mtu + ETH_HLEN + BNX2_RX_OFFSET + 8; | 5321 | rx_size = bp->dev->mtu + ETH_HLEN + BNX2_RX_OFFSET + 8; |
5330 | 5322 | ||
5331 | rx_space = SKB_DATA_ALIGN(rx_size + BNX2_RX_ALIGN) + NET_SKB_PAD + | 5323 | rx_space = SKB_DATA_ALIGN(rx_size + BNX2_RX_ALIGN) + NET_SKB_PAD + |
5332 | sizeof(struct skb_shared_info); | 5324 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); |
5333 | 5325 | ||
5334 | bp->rx_copy_thresh = BNX2_RX_COPY_THRESH; | 5326 | bp->rx_copy_thresh = BNX2_RX_COPY_THRESH; |
5335 | bp->rx_pg_ring_size = 0; | 5327 | bp->rx_pg_ring_size = 0; |
@@ -5351,8 +5343,9 @@ bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size) | |||
5351 | } | 5343 | } |
5352 | 5344 | ||
5353 | bp->rx_buf_use_size = rx_size; | 5345 | bp->rx_buf_use_size = rx_size; |
5354 | /* hw alignment */ | 5346 | /* hw alignment + build_skb() overhead*/ |
5355 | bp->rx_buf_size = bp->rx_buf_use_size + BNX2_RX_ALIGN; | 5347 | bp->rx_buf_size = SKB_DATA_ALIGN(bp->rx_buf_use_size + BNX2_RX_ALIGN) + |
5348 | NET_SKB_PAD + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); | ||
5356 | bp->rx_jumbo_thresh = rx_size - BNX2_RX_OFFSET; | 5349 | bp->rx_jumbo_thresh = rx_size - BNX2_RX_OFFSET; |
5357 | bp->rx_ring_size = size; | 5350 | bp->rx_ring_size = size; |
5358 | bp->rx_max_ring = bnx2_find_max_ring(size, MAX_RX_RINGS); | 5351 | bp->rx_max_ring = bnx2_find_max_ring(size, MAX_RX_RINGS); |
@@ -5418,9 +5411,9 @@ bnx2_free_rx_skbs(struct bnx2 *bp) | |||
5418 | 5411 | ||
5419 | for (j = 0; j < bp->rx_max_ring_idx; j++) { | 5412 | for (j = 0; j < bp->rx_max_ring_idx; j++) { |
5420 | struct sw_bd *rx_buf = &rxr->rx_buf_ring[j]; | 5413 | struct sw_bd *rx_buf = &rxr->rx_buf_ring[j]; |
5421 | struct sk_buff *skb = rx_buf->skb; | 5414 | u8 *data = rx_buf->data; |
5422 | 5415 | ||
5423 | if (skb == NULL) | 5416 | if (data == NULL) |
5424 | continue; | 5417 | continue; |
5425 | 5418 | ||
5426 | dma_unmap_single(&bp->pdev->dev, | 5419 | dma_unmap_single(&bp->pdev->dev, |
@@ -5428,9 +5421,9 @@ bnx2_free_rx_skbs(struct bnx2 *bp) | |||
5428 | bp->rx_buf_use_size, | 5421 | bp->rx_buf_use_size, |
5429 | PCI_DMA_FROMDEVICE); | 5422 | PCI_DMA_FROMDEVICE); |
5430 | 5423 | ||
5431 | rx_buf->skb = NULL; | 5424 | rx_buf->data = NULL; |
5432 | 5425 | ||
5433 | dev_kfree_skb(skb); | 5426 | kfree(data); |
5434 | } | 5427 | } |
5435 | for (j = 0; j < bp->rx_max_pg_ring_idx; j++) | 5428 | for (j = 0; j < bp->rx_max_pg_ring_idx; j++) |
5436 | bnx2_free_rx_page(bp, rxr, j); | 5429 | bnx2_free_rx_page(bp, rxr, j); |
@@ -5736,7 +5729,8 @@ static int | |||
5736 | bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | 5729 | bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) |
5737 | { | 5730 | { |
5738 | unsigned int pkt_size, num_pkts, i; | 5731 | unsigned int pkt_size, num_pkts, i; |
5739 | struct sk_buff *skb, *rx_skb; | 5732 | struct sk_buff *skb; |
5733 | u8 *data; | ||
5740 | unsigned char *packet; | 5734 | unsigned char *packet; |
5741 | u16 rx_start_idx, rx_idx; | 5735 | u16 rx_start_idx, rx_idx; |
5742 | dma_addr_t map; | 5736 | dma_addr_t map; |
@@ -5828,14 +5822,14 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
5828 | } | 5822 | } |
5829 | 5823 | ||
5830 | rx_buf = &rxr->rx_buf_ring[rx_start_idx]; | 5824 | rx_buf = &rxr->rx_buf_ring[rx_start_idx]; |
5831 | rx_skb = rx_buf->skb; | 5825 | data = rx_buf->data; |
5832 | 5826 | ||
5833 | rx_hdr = rx_buf->desc; | 5827 | rx_hdr = get_l2_fhdr(data); |
5834 | skb_reserve(rx_skb, BNX2_RX_OFFSET); | 5828 | data = (u8 *)rx_hdr + BNX2_RX_OFFSET; |
5835 | 5829 | ||
5836 | dma_sync_single_for_cpu(&bp->pdev->dev, | 5830 | dma_sync_single_for_cpu(&bp->pdev->dev, |
5837 | dma_unmap_addr(rx_buf, mapping), | 5831 | dma_unmap_addr(rx_buf, mapping), |
5838 | bp->rx_buf_size, PCI_DMA_FROMDEVICE); | 5832 | bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); |
5839 | 5833 | ||
5840 | if (rx_hdr->l2_fhdr_status & | 5834 | if (rx_hdr->l2_fhdr_status & |
5841 | (L2_FHDR_ERRORS_BAD_CRC | | 5835 | (L2_FHDR_ERRORS_BAD_CRC | |
@@ -5852,7 +5846,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
5852 | } | 5846 | } |
5853 | 5847 | ||
5854 | for (i = 14; i < pkt_size; i++) { | 5848 | for (i = 14; i < pkt_size; i++) { |
5855 | if (*(rx_skb->data + i) != (unsigned char) (i & 0xff)) { | 5849 | if (*(data + i) != (unsigned char) (i & 0xff)) { |
5856 | goto loopback_test_done; | 5850 | goto loopback_test_done; |
5857 | } | 5851 | } |
5858 | } | 5852 | } |
@@ -6873,10 +6867,10 @@ bnx2_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
6873 | { | 6867 | { |
6874 | struct bnx2 *bp = netdev_priv(dev); | 6868 | struct bnx2 *bp = netdev_priv(dev); |
6875 | 6869 | ||
6876 | strcpy(info->driver, DRV_MODULE_NAME); | 6870 | strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); |
6877 | strcpy(info->version, DRV_MODULE_VERSION); | 6871 | strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); |
6878 | strcpy(info->bus_info, pci_name(bp->pdev)); | 6872 | strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info)); |
6879 | strcpy(info->fw_version, bp->fw_version); | 6873 | strlcpy(info->fw_version, bp->fw_version, sizeof(info->fw_version)); |
6880 | } | 6874 | } |
6881 | 6875 | ||
6882 | #define BNX2_REGDUMP_LEN (32 * 1024) | 6876 | #define BNX2_REGDUMP_LEN (32 * 1024) |
@@ -7571,8 +7565,8 @@ bnx2_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state) | |||
7571 | return 0; | 7565 | return 0; |
7572 | } | 7566 | } |
7573 | 7567 | ||
7574 | static u32 | 7568 | static netdev_features_t |
7575 | bnx2_fix_features(struct net_device *dev, u32 features) | 7569 | bnx2_fix_features(struct net_device *dev, netdev_features_t features) |
7576 | { | 7570 | { |
7577 | struct bnx2 *bp = netdev_priv(dev); | 7571 | struct bnx2 *bp = netdev_priv(dev); |
7578 | 7572 | ||
@@ -7583,7 +7577,7 @@ bnx2_fix_features(struct net_device *dev, u32 features) | |||
7583 | } | 7577 | } |
7584 | 7578 | ||
7585 | static int | 7579 | static int |
7586 | bnx2_set_features(struct net_device *dev, u32 features) | 7580 | bnx2_set_features(struct net_device *dev, netdev_features_t features) |
7587 | { | 7581 | { |
7588 | struct bnx2 *bp = netdev_priv(dev); | 7582 | struct bnx2 *bp = netdev_priv(dev); |
7589 | 7583 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h index 99d31a7d6aaa..1db2d51ba3f1 100644 --- a/drivers/net/ethernet/broadcom/bnx2.h +++ b/drivers/net/ethernet/broadcom/bnx2.h | |||
@@ -6563,12 +6563,25 @@ struct l2_fhdr { | |||
6563 | #define MB_TX_CID_ADDR MB_GET_CID_ADDR(TX_CID) | 6563 | #define MB_TX_CID_ADDR MB_GET_CID_ADDR(TX_CID) |
6564 | #define MB_RX_CID_ADDR MB_GET_CID_ADDR(RX_CID) | 6564 | #define MB_RX_CID_ADDR MB_GET_CID_ADDR(RX_CID) |
6565 | 6565 | ||
6566 | /* | ||
6567 | * This driver uses new build_skb() API : | ||
6568 | * RX ring buffer contains pointer to kmalloc() data only, | ||
6569 | * skb are built only after Hardware filled the frame. | ||
6570 | */ | ||
6566 | struct sw_bd { | 6571 | struct sw_bd { |
6567 | struct sk_buff *skb; | 6572 | u8 *data; |
6568 | struct l2_fhdr *desc; | ||
6569 | DEFINE_DMA_UNMAP_ADDR(mapping); | 6573 | DEFINE_DMA_UNMAP_ADDR(mapping); |
6570 | }; | 6574 | }; |
6571 | 6575 | ||
6576 | /* Its faster to compute this from data than storing it in sw_bd | ||
6577 | * (less cache misses) | ||
6578 | */ | ||
6579 | static inline struct l2_fhdr *get_l2_fhdr(u8 *data) | ||
6580 | { | ||
6581 | return (struct l2_fhdr *)(PTR_ALIGN(data, BNX2_RX_ALIGN) + NET_SKB_PAD); | ||
6582 | } | ||
6583 | |||
6584 | |||
6572 | struct sw_pg { | 6585 | struct sw_pg { |
6573 | struct page *page; | 6586 | struct page *page; |
6574 | DEFINE_DMA_UNMAP_ADDR(mapping); | 6587 | DEFINE_DMA_UNMAP_ADDR(mapping); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index aec7212ac983..0f7b7a463eba 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -23,8 +23,8 @@ | |||
23 | * (you will need to reboot afterwards) */ | 23 | * (you will need to reboot afterwards) */ |
24 | /* #define BNX2X_STOP_ON_ERROR */ | 24 | /* #define BNX2X_STOP_ON_ERROR */ |
25 | 25 | ||
26 | #define DRV_MODULE_VERSION "1.70.30-0" | 26 | #define DRV_MODULE_VERSION "1.70.35-0" |
27 | #define DRV_MODULE_RELDATE "2011/10/25" | 27 | #define DRV_MODULE_RELDATE "2011/11/10" |
28 | #define BNX2X_BC_VER 0x040200 | 28 | #define BNX2X_BC_VER 0x040200 |
29 | 29 | ||
30 | #if defined(CONFIG_DCB) | 30 | #if defined(CONFIG_DCB) |
@@ -293,8 +293,13 @@ enum { | |||
293 | #define FCOE_TXQ_IDX(bp) (MAX_ETH_TXQ_IDX(bp)) | 293 | #define FCOE_TXQ_IDX(bp) (MAX_ETH_TXQ_IDX(bp)) |
294 | 294 | ||
295 | /* fast path */ | 295 | /* fast path */ |
296 | /* | ||
297 | * This driver uses new build_skb() API : | ||
298 | * RX ring buffer contains pointer to kmalloc() data only, | ||
299 | * skb are built only after Hardware filled the frame. | ||
300 | */ | ||
296 | struct sw_rx_bd { | 301 | struct sw_rx_bd { |
297 | struct sk_buff *skb; | 302 | u8 *data; |
298 | DEFINE_DMA_UNMAP_ADDR(mapping); | 303 | DEFINE_DMA_UNMAP_ADDR(mapping); |
299 | }; | 304 | }; |
300 | 305 | ||
@@ -411,8 +416,7 @@ union db_prod { | |||
411 | 416 | ||
412 | 417 | ||
413 | /* Number of u64 elements in SGE mask array */ | 418 | /* Number of u64 elements in SGE mask array */ |
414 | #define RX_SGE_MASK_LEN ((NUM_RX_SGE_PAGES * RX_SGE_CNT) / \ | 419 | #define RX_SGE_MASK_LEN (NUM_RX_SGE / BIT_VEC64_ELEM_SZ) |
415 | BIT_VEC64_ELEM_SZ) | ||
416 | #define RX_SGE_MASK_LEN_MASK (RX_SGE_MASK_LEN - 1) | 420 | #define RX_SGE_MASK_LEN_MASK (RX_SGE_MASK_LEN - 1) |
417 | #define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK) | 421 | #define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK) |
418 | 422 | ||
@@ -425,8 +429,8 @@ union host_hc_status_block { | |||
425 | 429 | ||
426 | struct bnx2x_agg_info { | 430 | struct bnx2x_agg_info { |
427 | /* | 431 | /* |
428 | * First aggregation buffer is an skb, the following - are pages. | 432 | * First aggregation buffer is a data buffer, the following - are pages. |
429 | * We will preallocate the skbs for each aggregation when | 433 | * We will preallocate the data buffer for each aggregation when |
430 | * we open the interface and will replace the BD at the consumer | 434 | * we open the interface and will replace the BD at the consumer |
431 | * with this one when we receive the TPA_START CQE in order to | 435 | * with this one when we receive the TPA_START CQE in order to |
432 | * keep the Rx BD ring consistent. | 436 | * keep the Rx BD ring consistent. |
@@ -440,6 +444,7 @@ struct bnx2x_agg_info { | |||
440 | u16 parsing_flags; | 444 | u16 parsing_flags; |
441 | u16 vlan_tag; | 445 | u16 vlan_tag; |
442 | u16 len_on_bd; | 446 | u16 len_on_bd; |
447 | u32 rxhash; | ||
443 | }; | 448 | }; |
444 | 449 | ||
445 | #define Q_STATS_OFFSET32(stat_name) \ | 450 | #define Q_STATS_OFFSET32(stat_name) \ |
@@ -507,6 +512,7 @@ struct bnx2x_fastpath { | |||
507 | __le16 fp_hc_idx; | 512 | __le16 fp_hc_idx; |
508 | 513 | ||
509 | u8 index; /* number in fp array */ | 514 | u8 index; /* number in fp array */ |
515 | u8 rx_queue; /* index for skb_record */ | ||
510 | u8 cl_id; /* eth client id */ | 516 | u8 cl_id; /* eth client id */ |
511 | u8 cl_qzone_id; | 517 | u8 cl_qzone_id; |
512 | u8 fw_sb_id; /* status block number in FW */ | 518 | u8 fw_sb_id; /* status block number in FW */ |
@@ -1141,6 +1147,7 @@ struct bnx2x_fw_stats_data { | |||
1141 | enum { | 1147 | enum { |
1142 | BNX2X_SP_RTNL_SETUP_TC, | 1148 | BNX2X_SP_RTNL_SETUP_TC, |
1143 | BNX2X_SP_RTNL_TX_TIMEOUT, | 1149 | BNX2X_SP_RTNL_TX_TIMEOUT, |
1150 | BNX2X_SP_RTNL_FAN_FAILURE, | ||
1144 | }; | 1151 | }; |
1145 | 1152 | ||
1146 | 1153 | ||
@@ -1186,10 +1193,20 @@ struct bnx2x { | |||
1186 | #define ETH_MAX_JUMBO_PACKET_SIZE 9600 | 1193 | #define ETH_MAX_JUMBO_PACKET_SIZE 9600 |
1187 | 1194 | ||
1188 | /* Max supported alignment is 256 (8 shift) */ | 1195 | /* Max supported alignment is 256 (8 shift) */ |
1189 | #define BNX2X_RX_ALIGN_SHIFT ((L1_CACHE_SHIFT < 8) ? \ | 1196 | #define BNX2X_RX_ALIGN_SHIFT min(8, L1_CACHE_SHIFT) |
1190 | L1_CACHE_SHIFT : 8) | 1197 | |
1191 | /* FW use 2 Cache lines Alignment for start packet and size */ | 1198 | /* FW uses 2 Cache lines Alignment for start packet and size |
1192 | #define BNX2X_FW_RX_ALIGN (2 << BNX2X_RX_ALIGN_SHIFT) | 1199 | * |
1200 | * We assume skb_build() uses sizeof(struct skb_shared_info) bytes | ||
1201 | * at the end of skb->data, to avoid wasting a full cache line. | ||
1202 | * This reduces memory use (skb->truesize). | ||
1203 | */ | ||
1204 | #define BNX2X_FW_RX_ALIGN_START (1UL << BNX2X_RX_ALIGN_SHIFT) | ||
1205 | |||
1206 | #define BNX2X_FW_RX_ALIGN_END \ | ||
1207 | max(1UL << BNX2X_RX_ALIGN_SHIFT, \ | ||
1208 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) | ||
1209 | |||
1193 | #define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) | 1210 | #define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) |
1194 | 1211 | ||
1195 | struct host_sp_status_block *def_status_blk; | 1212 | struct host_sp_status_block *def_status_blk; |
@@ -1984,13 +2001,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, | |||
1984 | #define HW_PRTY_ASSERT_SET_4 (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | \ | 2001 | #define HW_PRTY_ASSERT_SET_4 (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | \ |
1985 | AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR) | 2002 | AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR) |
1986 | 2003 | ||
1987 | #define RSS_FLAGS(bp) \ | ||
1988 | (TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY | \ | ||
1989 | TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY | \ | ||
1990 | TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY | \ | ||
1991 | TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY | \ | ||
1992 | (bp->multi_mode << \ | ||
1993 | TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT)) | ||
1994 | #define MULTI_MASK 0x7f | 2004 | #define MULTI_MASK 0x7f |
1995 | 2005 | ||
1996 | 2006 | ||
@@ -2055,6 +2065,8 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, | |||
2055 | #define BNX2X_VPD_LEN 128 | 2065 | #define BNX2X_VPD_LEN 128 |
2056 | #define VENDOR_ID_LEN 4 | 2066 | #define VENDOR_ID_LEN 4 |
2057 | 2067 | ||
2068 | int bnx2x_close(struct net_device *dev); | ||
2069 | |||
2058 | /* Congestion management fairness mode */ | 2070 | /* Congestion management fairness mode */ |
2059 | #define CMNG_FNS_NONE 0 | 2071 | #define CMNG_FNS_NONE 0 |
2060 | #define CMNG_FNS_MINMAX 1 | 2072 | #define CMNG_FNS_MINMAX 1 |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 580b44edb066..8336c784db49 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -79,19 +79,21 @@ static inline void bnx2x_bz_fp(struct bnx2x *bp, int index) | |||
79 | * @to: destination FP index | 79 | * @to: destination FP index |
80 | * | 80 | * |
81 | * Makes sure the contents of the bp->fp[to].napi is kept | 81 | * Makes sure the contents of the bp->fp[to].napi is kept |
82 | * intact. | 82 | * intact. This is done by first copying the napi struct from |
83 | * the target to the source, and then mem copying the entire | ||
84 | * source onto the target | ||
83 | */ | 85 | */ |
84 | static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to) | 86 | static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to) |
85 | { | 87 | { |
86 | struct bnx2x_fastpath *from_fp = &bp->fp[from]; | 88 | struct bnx2x_fastpath *from_fp = &bp->fp[from]; |
87 | struct bnx2x_fastpath *to_fp = &bp->fp[to]; | 89 | struct bnx2x_fastpath *to_fp = &bp->fp[to]; |
88 | struct napi_struct orig_napi = to_fp->napi; | 90 | |
91 | /* Copy the NAPI object as it has been already initialized */ | ||
92 | from_fp->napi = to_fp->napi; | ||
93 | |||
89 | /* Move bnx2x_fastpath contents */ | 94 | /* Move bnx2x_fastpath contents */ |
90 | memcpy(to_fp, from_fp, sizeof(*to_fp)); | 95 | memcpy(to_fp, from_fp, sizeof(*to_fp)); |
91 | to_fp->index = to; | 96 | to_fp->index = to; |
92 | |||
93 | /* Restore the NAPI object as it has been already initialized */ | ||
94 | to_fp->napi = orig_napi; | ||
95 | } | 97 | } |
96 | 98 | ||
97 | int load_count[2][3] = { {0} }; /* per-path: 0-common, 1-port0, 2-port1 */ | 99 | int load_count[2][3] = { {0} }; /* per-path: 0-common, 1-port0, 2-port1 */ |
@@ -292,8 +294,21 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, | |||
292 | fp->last_max_sge, fp->rx_sge_prod); | 294 | fp->last_max_sge, fp->rx_sge_prod); |
293 | } | 295 | } |
294 | 296 | ||
297 | /* Set Toeplitz hash value in the skb using the value from the | ||
298 | * CQE (calculated by HW). | ||
299 | */ | ||
300 | static u32 bnx2x_get_rxhash(const struct bnx2x *bp, | ||
301 | const struct eth_fast_path_rx_cqe *cqe) | ||
302 | { | ||
303 | /* Set Toeplitz hash from CQE */ | ||
304 | if ((bp->dev->features & NETIF_F_RXHASH) && | ||
305 | (cqe->status_flags & ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG)) | ||
306 | return le32_to_cpu(cqe->rss_hash_result); | ||
307 | return 0; | ||
308 | } | ||
309 | |||
295 | static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | 310 | static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, |
296 | struct sk_buff *skb, u16 cons, u16 prod, | 311 | u16 cons, u16 prod, |
297 | struct eth_fast_path_rx_cqe *cqe) | 312 | struct eth_fast_path_rx_cqe *cqe) |
298 | { | 313 | { |
299 | struct bnx2x *bp = fp->bp; | 314 | struct bnx2x *bp = fp->bp; |
@@ -308,9 +323,9 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | |||
308 | if (tpa_info->tpa_state != BNX2X_TPA_STOP) | 323 | if (tpa_info->tpa_state != BNX2X_TPA_STOP) |
309 | BNX2X_ERR("start of bin not in stop [%d]\n", queue); | 324 | BNX2X_ERR("start of bin not in stop [%d]\n", queue); |
310 | 325 | ||
311 | /* Try to map an empty skb from the aggregation info */ | 326 | /* Try to map an empty data buffer from the aggregation info */ |
312 | mapping = dma_map_single(&bp->pdev->dev, | 327 | mapping = dma_map_single(&bp->pdev->dev, |
313 | first_buf->skb->data, | 328 | first_buf->data + NET_SKB_PAD, |
314 | fp->rx_buf_size, DMA_FROM_DEVICE); | 329 | fp->rx_buf_size, DMA_FROM_DEVICE); |
315 | /* | 330 | /* |
316 | * ...if it fails - move the skb from the consumer to the producer | 331 | * ...if it fails - move the skb from the consumer to the producer |
@@ -320,15 +335,15 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | |||
320 | 335 | ||
321 | if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { | 336 | if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { |
322 | /* Move the BD from the consumer to the producer */ | 337 | /* Move the BD from the consumer to the producer */ |
323 | bnx2x_reuse_rx_skb(fp, cons, prod); | 338 | bnx2x_reuse_rx_data(fp, cons, prod); |
324 | tpa_info->tpa_state = BNX2X_TPA_ERROR; | 339 | tpa_info->tpa_state = BNX2X_TPA_ERROR; |
325 | return; | 340 | return; |
326 | } | 341 | } |
327 | 342 | ||
328 | /* move empty skb from pool to prod */ | 343 | /* move empty data from pool to prod */ |
329 | prod_rx_buf->skb = first_buf->skb; | 344 | prod_rx_buf->data = first_buf->data; |
330 | dma_unmap_addr_set(prod_rx_buf, mapping, mapping); | 345 | dma_unmap_addr_set(prod_rx_buf, mapping, mapping); |
331 | /* point prod_bd to new skb */ | 346 | /* point prod_bd to new data */ |
332 | prod_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); | 347 | prod_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); |
333 | prod_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); | 348 | prod_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); |
334 | 349 | ||
@@ -342,6 +357,7 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | |||
342 | tpa_info->tpa_state = BNX2X_TPA_START; | 357 | tpa_info->tpa_state = BNX2X_TPA_START; |
343 | tpa_info->len_on_bd = le16_to_cpu(cqe->len_on_bd); | 358 | tpa_info->len_on_bd = le16_to_cpu(cqe->len_on_bd); |
344 | tpa_info->placement_offset = cqe->placement_offset; | 359 | tpa_info->placement_offset = cqe->placement_offset; |
360 | tpa_info->rxhash = bnx2x_get_rxhash(bp, cqe); | ||
345 | 361 | ||
346 | #ifdef BNX2X_STOP_ON_ERROR | 362 | #ifdef BNX2X_STOP_ON_ERROR |
347 | fp->tpa_queue_used |= (1 << queue); | 363 | fp->tpa_queue_used |= (1 << queue); |
@@ -469,11 +485,12 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
469 | { | 485 | { |
470 | struct bnx2x_agg_info *tpa_info = &fp->tpa_info[queue]; | 486 | struct bnx2x_agg_info *tpa_info = &fp->tpa_info[queue]; |
471 | struct sw_rx_bd *rx_buf = &tpa_info->first_buf; | 487 | struct sw_rx_bd *rx_buf = &tpa_info->first_buf; |
472 | u8 pad = tpa_info->placement_offset; | 488 | u32 pad = tpa_info->placement_offset; |
473 | u16 len = tpa_info->len_on_bd; | 489 | u16 len = tpa_info->len_on_bd; |
474 | struct sk_buff *skb = rx_buf->skb; | 490 | struct sk_buff *skb = NULL; |
491 | u8 *data = rx_buf->data; | ||
475 | /* alloc new skb */ | 492 | /* alloc new skb */ |
476 | struct sk_buff *new_skb; | 493 | u8 *new_data; |
477 | u8 old_tpa_state = tpa_info->tpa_state; | 494 | u8 old_tpa_state = tpa_info->tpa_state; |
478 | 495 | ||
479 | tpa_info->tpa_state = BNX2X_TPA_STOP; | 496 | tpa_info->tpa_state = BNX2X_TPA_STOP; |
@@ -484,18 +501,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
484 | if (old_tpa_state == BNX2X_TPA_ERROR) | 501 | if (old_tpa_state == BNX2X_TPA_ERROR) |
485 | goto drop; | 502 | goto drop; |
486 | 503 | ||
487 | /* Try to allocate the new skb */ | 504 | /* Try to allocate the new data */ |
488 | new_skb = netdev_alloc_skb(bp->dev, fp->rx_buf_size); | 505 | new_data = kmalloc(fp->rx_buf_size + NET_SKB_PAD, GFP_ATOMIC); |
489 | 506 | ||
490 | /* Unmap skb in the pool anyway, as we are going to change | 507 | /* Unmap skb in the pool anyway, as we are going to change |
491 | pool entry status to BNX2X_TPA_STOP even if new skb allocation | 508 | pool entry status to BNX2X_TPA_STOP even if new skb allocation |
492 | fails. */ | 509 | fails. */ |
493 | dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), | 510 | dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), |
494 | fp->rx_buf_size, DMA_FROM_DEVICE); | 511 | fp->rx_buf_size, DMA_FROM_DEVICE); |
512 | if (likely(new_data)) | ||
513 | skb = build_skb(data); | ||
495 | 514 | ||
496 | if (likely(new_skb)) { | 515 | if (likely(skb)) { |
497 | prefetch(skb); | ||
498 | prefetch(((char *)(skb)) + L1_CACHE_BYTES); | ||
499 | 516 | ||
500 | #ifdef BNX2X_STOP_ON_ERROR | 517 | #ifdef BNX2X_STOP_ON_ERROR |
501 | if (pad + len > fp->rx_buf_size) { | 518 | if (pad + len > fp->rx_buf_size) { |
@@ -507,8 +524,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
507 | } | 524 | } |
508 | #endif | 525 | #endif |
509 | 526 | ||
510 | skb_reserve(skb, pad); | 527 | skb_reserve(skb, pad + NET_SKB_PAD); |
511 | skb_put(skb, len); | 528 | skb_put(skb, len); |
529 | skb->rxhash = tpa_info->rxhash; | ||
512 | 530 | ||
513 | skb->protocol = eth_type_trans(skb, bp->dev); | 531 | skb->protocol = eth_type_trans(skb, bp->dev); |
514 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 532 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -524,8 +542,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
524 | } | 542 | } |
525 | 543 | ||
526 | 544 | ||
527 | /* put new skb in bin */ | 545 | /* put new data in bin */ |
528 | rx_buf->skb = new_skb; | 546 | rx_buf->data = new_data; |
529 | 547 | ||
530 | return; | 548 | return; |
531 | } | 549 | } |
@@ -537,19 +555,6 @@ drop: | |||
537 | fp->eth_q_stats.rx_skb_alloc_failed++; | 555 | fp->eth_q_stats.rx_skb_alloc_failed++; |
538 | } | 556 | } |
539 | 557 | ||
540 | /* Set Toeplitz hash value in the skb using the value from the | ||
541 | * CQE (calculated by HW). | ||
542 | */ | ||
543 | static inline void bnx2x_set_skb_rxhash(struct bnx2x *bp, union eth_rx_cqe *cqe, | ||
544 | struct sk_buff *skb) | ||
545 | { | ||
546 | /* Set Toeplitz hash from CQE */ | ||
547 | if ((bp->dev->features & NETIF_F_RXHASH) && | ||
548 | (cqe->fast_path_cqe.status_flags & | ||
549 | ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG)) | ||
550 | skb->rxhash = | ||
551 | le32_to_cpu(cqe->fast_path_cqe.rss_hash_result); | ||
552 | } | ||
553 | 558 | ||
554 | int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) | 559 | int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) |
555 | { | 560 | { |
@@ -592,6 +597,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) | |||
592 | u8 cqe_fp_flags; | 597 | u8 cqe_fp_flags; |
593 | enum eth_rx_cqe_type cqe_fp_type; | 598 | enum eth_rx_cqe_type cqe_fp_type; |
594 | u16 len, pad; | 599 | u16 len, pad; |
600 | u8 *data; | ||
595 | 601 | ||
596 | #ifdef BNX2X_STOP_ON_ERROR | 602 | #ifdef BNX2X_STOP_ON_ERROR |
597 | if (unlikely(bp->panic)) | 603 | if (unlikely(bp->panic)) |
@@ -602,13 +608,6 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) | |||
602 | bd_prod = RX_BD(bd_prod); | 608 | bd_prod = RX_BD(bd_prod); |
603 | bd_cons = RX_BD(bd_cons); | 609 | bd_cons = RX_BD(bd_cons); |
604 | 610 | ||
605 | /* Prefetch the page containing the BD descriptor | ||
606 | at producer's index. It will be needed when new skb is | ||
607 | allocated */ | ||
608 | prefetch((void *)(PAGE_ALIGN((unsigned long) | ||
609 | (&fp->rx_desc_ring[bd_prod])) - | ||
610 | PAGE_SIZE + 1)); | ||
611 | |||
612 | cqe = &fp->rx_comp_ring[comp_ring_cons]; | 611 | cqe = &fp->rx_comp_ring[comp_ring_cons]; |
613 | cqe_fp = &cqe->fast_path_cqe; | 612 | cqe_fp = &cqe->fast_path_cqe; |
614 | cqe_fp_flags = cqe_fp->type_error_flags; | 613 | cqe_fp_flags = cqe_fp->type_error_flags; |
@@ -624,125 +623,110 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) | |||
624 | if (unlikely(CQE_TYPE_SLOW(cqe_fp_type))) { | 623 | if (unlikely(CQE_TYPE_SLOW(cqe_fp_type))) { |
625 | bnx2x_sp_event(fp, cqe); | 624 | bnx2x_sp_event(fp, cqe); |
626 | goto next_cqe; | 625 | goto next_cqe; |
626 | } | ||
627 | rx_buf = &fp->rx_buf_ring[bd_cons]; | ||
628 | data = rx_buf->data; | ||
627 | 629 | ||
628 | /* this is an rx packet */ | 630 | if (!CQE_TYPE_FAST(cqe_fp_type)) { |
629 | } else { | ||
630 | rx_buf = &fp->rx_buf_ring[bd_cons]; | ||
631 | skb = rx_buf->skb; | ||
632 | prefetch(skb); | ||
633 | |||
634 | if (!CQE_TYPE_FAST(cqe_fp_type)) { | ||
635 | #ifdef BNX2X_STOP_ON_ERROR | 631 | #ifdef BNX2X_STOP_ON_ERROR |
636 | /* sanity check */ | 632 | /* sanity check */ |
637 | if (fp->disable_tpa && | 633 | if (fp->disable_tpa && |
638 | (CQE_TYPE_START(cqe_fp_type) || | 634 | (CQE_TYPE_START(cqe_fp_type) || |
639 | CQE_TYPE_STOP(cqe_fp_type))) | 635 | CQE_TYPE_STOP(cqe_fp_type))) |
640 | BNX2X_ERR("START/STOP packet while " | 636 | BNX2X_ERR("START/STOP packet while " |
641 | "disable_tpa type %x\n", | 637 | "disable_tpa type %x\n", |
642 | CQE_TYPE(cqe_fp_type)); | 638 | CQE_TYPE(cqe_fp_type)); |
643 | #endif | 639 | #endif |
644 | 640 | ||
645 | if (CQE_TYPE_START(cqe_fp_type)) { | 641 | if (CQE_TYPE_START(cqe_fp_type)) { |
646 | u16 queue = cqe_fp->queue_index; | 642 | u16 queue = cqe_fp->queue_index; |
647 | DP(NETIF_MSG_RX_STATUS, | 643 | DP(NETIF_MSG_RX_STATUS, |
648 | "calling tpa_start on queue %d\n", | 644 | "calling tpa_start on queue %d\n", |
649 | queue); | 645 | queue); |
650 | |||
651 | bnx2x_tpa_start(fp, queue, skb, | ||
652 | bd_cons, bd_prod, | ||
653 | cqe_fp); | ||
654 | |||
655 | /* Set Toeplitz hash for LRO skb */ | ||
656 | bnx2x_set_skb_rxhash(bp, cqe, skb); | ||
657 | 646 | ||
658 | goto next_rx; | 647 | bnx2x_tpa_start(fp, queue, |
659 | 648 | bd_cons, bd_prod, | |
660 | } else { | 649 | cqe_fp); |
661 | u16 queue = | 650 | goto next_rx; |
662 | cqe->end_agg_cqe.queue_index; | 651 | } else { |
663 | DP(NETIF_MSG_RX_STATUS, | 652 | u16 queue = |
664 | "calling tpa_stop on queue %d\n", | 653 | cqe->end_agg_cqe.queue_index; |
665 | queue); | 654 | DP(NETIF_MSG_RX_STATUS, |
666 | 655 | "calling tpa_stop on queue %d\n", | |
667 | bnx2x_tpa_stop(bp, fp, queue, | 656 | queue); |
668 | &cqe->end_agg_cqe, | 657 | |
669 | comp_ring_cons); | 658 | bnx2x_tpa_stop(bp, fp, queue, |
659 | &cqe->end_agg_cqe, | ||
660 | comp_ring_cons); | ||
670 | #ifdef BNX2X_STOP_ON_ERROR | 661 | #ifdef BNX2X_STOP_ON_ERROR |
671 | if (bp->panic) | 662 | if (bp->panic) |
672 | return 0; | 663 | return 0; |
673 | #endif | 664 | #endif |
674 | 665 | ||
675 | bnx2x_update_sge_prod(fp, cqe_fp); | 666 | bnx2x_update_sge_prod(fp, cqe_fp); |
676 | goto next_cqe; | 667 | goto next_cqe; |
677 | } | ||
678 | } | 668 | } |
679 | /* non TPA */ | 669 | } |
680 | len = le16_to_cpu(cqe_fp->pkt_len); | 670 | /* non TPA */ |
681 | pad = cqe_fp->placement_offset; | 671 | len = le16_to_cpu(cqe_fp->pkt_len); |
682 | dma_sync_single_for_cpu(&bp->pdev->dev, | 672 | pad = cqe_fp->placement_offset; |
673 | dma_sync_single_for_cpu(&bp->pdev->dev, | ||
683 | dma_unmap_addr(rx_buf, mapping), | 674 | dma_unmap_addr(rx_buf, mapping), |
684 | pad + RX_COPY_THRESH, | 675 | pad + RX_COPY_THRESH, |
685 | DMA_FROM_DEVICE); | 676 | DMA_FROM_DEVICE); |
686 | prefetch(((char *)(skb)) + L1_CACHE_BYTES); | 677 | pad += NET_SKB_PAD; |
678 | prefetch(data + pad); /* speedup eth_type_trans() */ | ||
679 | /* is this an error packet? */ | ||
680 | if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) { | ||
681 | DP(NETIF_MSG_RX_ERR, | ||
682 | "ERROR flags %x rx packet %u\n", | ||
683 | cqe_fp_flags, sw_comp_cons); | ||
684 | fp->eth_q_stats.rx_err_discard_pkt++; | ||
685 | goto reuse_rx; | ||
686 | } | ||
687 | 687 | ||
688 | /* is this an error packet? */ | 688 | /* Since we don't have a jumbo ring |
689 | if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) { | 689 | * copy small packets if mtu > 1500 |
690 | */ | ||
691 | if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) && | ||
692 | (len <= RX_COPY_THRESH)) { | ||
693 | skb = netdev_alloc_skb_ip_align(bp->dev, len); | ||
694 | if (skb == NULL) { | ||
690 | DP(NETIF_MSG_RX_ERR, | 695 | DP(NETIF_MSG_RX_ERR, |
691 | "ERROR flags %x rx packet %u\n", | 696 | "ERROR packet dropped because of alloc failure\n"); |
692 | cqe_fp_flags, sw_comp_cons); | 697 | fp->eth_q_stats.rx_skb_alloc_failed++; |
693 | fp->eth_q_stats.rx_err_discard_pkt++; | ||
694 | goto reuse_rx; | 698 | goto reuse_rx; |
695 | } | 699 | } |
696 | 700 | memcpy(skb->data, data + pad, len); | |
697 | /* Since we don't have a jumbo ring | 701 | bnx2x_reuse_rx_data(fp, bd_cons, bd_prod); |
698 | * copy small packets if mtu > 1500 | 702 | } else { |
699 | */ | 703 | if (likely(bnx2x_alloc_rx_data(bp, fp, bd_prod) == 0)) { |
700 | if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) && | ||
701 | (len <= RX_COPY_THRESH)) { | ||
702 | struct sk_buff *new_skb; | ||
703 | |||
704 | new_skb = netdev_alloc_skb(bp->dev, len + pad); | ||
705 | if (new_skb == NULL) { | ||
706 | DP(NETIF_MSG_RX_ERR, | ||
707 | "ERROR packet dropped " | ||
708 | "because of alloc failure\n"); | ||
709 | fp->eth_q_stats.rx_skb_alloc_failed++; | ||
710 | goto reuse_rx; | ||
711 | } | ||
712 | |||
713 | /* aligned copy */ | ||
714 | skb_copy_from_linear_data_offset(skb, pad, | ||
715 | new_skb->data + pad, len); | ||
716 | skb_reserve(new_skb, pad); | ||
717 | skb_put(new_skb, len); | ||
718 | |||
719 | bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod); | ||
720 | |||
721 | skb = new_skb; | ||
722 | |||
723 | } else | ||
724 | if (likely(bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0)) { | ||
725 | dma_unmap_single(&bp->pdev->dev, | 704 | dma_unmap_single(&bp->pdev->dev, |
726 | dma_unmap_addr(rx_buf, mapping), | 705 | dma_unmap_addr(rx_buf, mapping), |
727 | fp->rx_buf_size, | 706 | fp->rx_buf_size, |
728 | DMA_FROM_DEVICE); | 707 | DMA_FROM_DEVICE); |
708 | skb = build_skb(data); | ||
709 | if (unlikely(!skb)) { | ||
710 | kfree(data); | ||
711 | fp->eth_q_stats.rx_skb_alloc_failed++; | ||
712 | goto next_rx; | ||
713 | } | ||
729 | skb_reserve(skb, pad); | 714 | skb_reserve(skb, pad); |
730 | skb_put(skb, len); | ||
731 | |||
732 | } else { | 715 | } else { |
733 | DP(NETIF_MSG_RX_ERR, | 716 | DP(NETIF_MSG_RX_ERR, |
734 | "ERROR packet dropped because " | 717 | "ERROR packet dropped because " |
735 | "of alloc failure\n"); | 718 | "of alloc failure\n"); |
736 | fp->eth_q_stats.rx_skb_alloc_failed++; | 719 | fp->eth_q_stats.rx_skb_alloc_failed++; |
737 | reuse_rx: | 720 | reuse_rx: |
738 | bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod); | 721 | bnx2x_reuse_rx_data(fp, bd_cons, bd_prod); |
739 | goto next_rx; | 722 | goto next_rx; |
740 | } | 723 | } |
741 | 724 | ||
725 | skb_put(skb, len); | ||
742 | skb->protocol = eth_type_trans(skb, bp->dev); | 726 | skb->protocol = eth_type_trans(skb, bp->dev); |
743 | 727 | ||
744 | /* Set Toeplitz hash for a none-LRO skb */ | 728 | /* Set Toeplitz hash for a none-LRO skb */ |
745 | bnx2x_set_skb_rxhash(bp, cqe, skb); | 729 | skb->rxhash = bnx2x_get_rxhash(bp, cqe_fp); |
746 | 730 | ||
747 | skb_checksum_none_assert(skb); | 731 | skb_checksum_none_assert(skb); |
748 | 732 | ||
@@ -755,7 +739,7 @@ reuse_rx: | |||
755 | } | 739 | } |
756 | } | 740 | } |
757 | 741 | ||
758 | skb_record_rx_queue(skb, fp->index); | 742 | skb_record_rx_queue(skb, fp->rx_queue); |
759 | 743 | ||
760 | if (le16_to_cpu(cqe_fp->pars_flags.flags) & | 744 | if (le16_to_cpu(cqe_fp->pars_flags.flags) & |
761 | PARSING_FLAGS_VLAN) | 745 | PARSING_FLAGS_VLAN) |
@@ -765,7 +749,7 @@ reuse_rx: | |||
765 | 749 | ||
766 | 750 | ||
767 | next_rx: | 751 | next_rx: |
768 | rx_buf->skb = NULL; | 752 | rx_buf->data = NULL; |
769 | 753 | ||
770 | bd_cons = NEXT_RX_IDX(bd_cons); | 754 | bd_cons = NEXT_RX_IDX(bd_cons); |
771 | bd_prod = NEXT_RX_IDX(bd_prod); | 755 | bd_prod = NEXT_RX_IDX(bd_prod); |
@@ -1011,9 +995,9 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) | |||
1011 | struct sw_rx_bd *first_buf = | 995 | struct sw_rx_bd *first_buf = |
1012 | &tpa_info->first_buf; | 996 | &tpa_info->first_buf; |
1013 | 997 | ||
1014 | first_buf->skb = netdev_alloc_skb(bp->dev, | 998 | first_buf->data = kmalloc(fp->rx_buf_size + NET_SKB_PAD, |
1015 | fp->rx_buf_size); | 999 | GFP_ATOMIC); |
1016 | if (!first_buf->skb) { | 1000 | if (!first_buf->data) { |
1017 | BNX2X_ERR("Failed to allocate TPA " | 1001 | BNX2X_ERR("Failed to allocate TPA " |
1018 | "skb pool for queue[%d] - " | 1002 | "skb pool for queue[%d] - " |
1019 | "disabling TPA on this " | 1003 | "disabling TPA on this " |
@@ -1094,13 +1078,11 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp) | |||
1094 | for_each_cos_in_tx_queue(fp, cos) { | 1078 | for_each_cos_in_tx_queue(fp, cos) { |
1095 | struct bnx2x_fp_txdata *txdata = &fp->txdata[cos]; | 1079 | struct bnx2x_fp_txdata *txdata = &fp->txdata[cos]; |
1096 | 1080 | ||
1097 | u16 bd_cons = txdata->tx_bd_cons; | ||
1098 | u16 sw_prod = txdata->tx_pkt_prod; | 1081 | u16 sw_prod = txdata->tx_pkt_prod; |
1099 | u16 sw_cons = txdata->tx_pkt_cons; | 1082 | u16 sw_cons = txdata->tx_pkt_cons; |
1100 | 1083 | ||
1101 | while (sw_cons != sw_prod) { | 1084 | while (sw_cons != sw_prod) { |
1102 | bd_cons = bnx2x_free_tx_pkt(bp, txdata, | 1085 | bnx2x_free_tx_pkt(bp, txdata, TX_BD(sw_cons)); |
1103 | TX_BD(sw_cons)); | ||
1104 | sw_cons++; | 1086 | sw_cons++; |
1105 | } | 1087 | } |
1106 | } | 1088 | } |
@@ -1118,16 +1100,16 @@ static void bnx2x_free_rx_bds(struct bnx2x_fastpath *fp) | |||
1118 | 1100 | ||
1119 | for (i = 0; i < NUM_RX_BD; i++) { | 1101 | for (i = 0; i < NUM_RX_BD; i++) { |
1120 | struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i]; | 1102 | struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i]; |
1121 | struct sk_buff *skb = rx_buf->skb; | 1103 | u8 *data = rx_buf->data; |
1122 | 1104 | ||
1123 | if (skb == NULL) | 1105 | if (data == NULL) |
1124 | continue; | 1106 | continue; |
1125 | dma_unmap_single(&bp->pdev->dev, | 1107 | dma_unmap_single(&bp->pdev->dev, |
1126 | dma_unmap_addr(rx_buf, mapping), | 1108 | dma_unmap_addr(rx_buf, mapping), |
1127 | fp->rx_buf_size, DMA_FROM_DEVICE); | 1109 | fp->rx_buf_size, DMA_FROM_DEVICE); |
1128 | 1110 | ||
1129 | rx_buf->skb = NULL; | 1111 | rx_buf->data = NULL; |
1130 | dev_kfree_skb(skb); | 1112 | kfree(data); |
1131 | } | 1113 | } |
1132 | } | 1114 | } |
1133 | 1115 | ||
@@ -1509,6 +1491,7 @@ static inline void bnx2x_set_rx_buf_size(struct bnx2x *bp) | |||
1509 | 1491 | ||
1510 | for_each_queue(bp, i) { | 1492 | for_each_queue(bp, i) { |
1511 | struct bnx2x_fastpath *fp = &bp->fp[i]; | 1493 | struct bnx2x_fastpath *fp = &bp->fp[i]; |
1494 | u32 mtu; | ||
1512 | 1495 | ||
1513 | /* Always use a mini-jumbo MTU for the FCoE L2 ring */ | 1496 | /* Always use a mini-jumbo MTU for the FCoE L2 ring */ |
1514 | if (IS_FCOE_IDX(i)) | 1497 | if (IS_FCOE_IDX(i)) |
@@ -1518,13 +1501,15 @@ static inline void bnx2x_set_rx_buf_size(struct bnx2x *bp) | |||
1518 | * IP_HEADER_ALIGNMENT_PADDING to prevent a buffer | 1501 | * IP_HEADER_ALIGNMENT_PADDING to prevent a buffer |
1519 | * overrun attack. | 1502 | * overrun attack. |
1520 | */ | 1503 | */ |
1521 | fp->rx_buf_size = | 1504 | mtu = BNX2X_FCOE_MINI_JUMBO_MTU; |
1522 | BNX2X_FCOE_MINI_JUMBO_MTU + ETH_OVREHEAD + | ||
1523 | BNX2X_FW_RX_ALIGN + IP_HEADER_ALIGNMENT_PADDING; | ||
1524 | else | 1505 | else |
1525 | fp->rx_buf_size = | 1506 | mtu = bp->dev->mtu; |
1526 | bp->dev->mtu + ETH_OVREHEAD + | 1507 | fp->rx_buf_size = BNX2X_FW_RX_ALIGN_START + |
1527 | BNX2X_FW_RX_ALIGN + IP_HEADER_ALIGNMENT_PADDING; | 1508 | IP_HEADER_ALIGNMENT_PADDING + |
1509 | ETH_OVREHEAD + | ||
1510 | mtu + | ||
1511 | BNX2X_FW_RX_ALIGN_END; | ||
1512 | /* Note : rx_buf_size doesnt take into account NET_SKB_PAD */ | ||
1528 | } | 1513 | } |
1529 | } | 1514 | } |
1530 | 1515 | ||
@@ -1929,13 +1914,17 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
1929 | break; | 1914 | break; |
1930 | } | 1915 | } |
1931 | 1916 | ||
1932 | if (!bp->port.pmf) | 1917 | if (bp->port.pmf) |
1918 | bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0); | ||
1919 | else | ||
1933 | bnx2x__link_status_update(bp); | 1920 | bnx2x__link_status_update(bp); |
1934 | 1921 | ||
1935 | /* start the timer */ | 1922 | /* start the timer */ |
1936 | mod_timer(&bp->timer, jiffies + bp->current_interval); | 1923 | mod_timer(&bp->timer, jiffies + bp->current_interval); |
1937 | 1924 | ||
1938 | #ifdef BCM_CNIC | 1925 | #ifdef BCM_CNIC |
1926 | /* re-read iscsi info */ | ||
1927 | bnx2x_get_iscsi_info(bp); | ||
1939 | bnx2x_setup_cnic_irq_info(bp); | 1928 | bnx2x_setup_cnic_irq_info(bp); |
1940 | if (bp->state == BNX2X_STATE_OPEN) | 1929 | if (bp->state == BNX2X_STATE_OPEN) |
1941 | bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD); | 1930 | bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD); |
@@ -3409,7 +3398,8 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) | |||
3409 | return bnx2x_reload_if_running(dev); | 3398 | return bnx2x_reload_if_running(dev); |
3410 | } | 3399 | } |
3411 | 3400 | ||
3412 | u32 bnx2x_fix_features(struct net_device *dev, u32 features) | 3401 | netdev_features_t bnx2x_fix_features(struct net_device *dev, |
3402 | netdev_features_t features) | ||
3413 | { | 3403 | { |
3414 | struct bnx2x *bp = netdev_priv(dev); | 3404 | struct bnx2x *bp = netdev_priv(dev); |
3415 | 3405 | ||
@@ -3420,7 +3410,7 @@ u32 bnx2x_fix_features(struct net_device *dev, u32 features) | |||
3420 | return features; | 3410 | return features; |
3421 | } | 3411 | } |
3422 | 3412 | ||
3423 | int bnx2x_set_features(struct net_device *dev, u32 features) | 3413 | int bnx2x_set_features(struct net_device *dev, netdev_features_t features) |
3424 | { | 3414 | { |
3425 | struct bnx2x *bp = netdev_priv(dev); | 3415 | struct bnx2x *bp = netdev_priv(dev); |
3426 | u32 flags = bp->flags; | 3416 | u32 flags = bp->flags; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 283d663da180..80c5ed08e419 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
@@ -533,8 +533,9 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu); | |||
533 | */ | 533 | */ |
534 | int bnx2x_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type); | 534 | int bnx2x_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type); |
535 | #endif | 535 | #endif |
536 | u32 bnx2x_fix_features(struct net_device *dev, u32 features); | 536 | netdev_features_t bnx2x_fix_features(struct net_device *dev, |
537 | int bnx2x_set_features(struct net_device *dev, u32 features); | 537 | netdev_features_t features); |
538 | int bnx2x_set_features(struct net_device *dev, netdev_features_t features); | ||
538 | 539 | ||
539 | /** | 540 | /** |
540 | * bnx2x_tx_timeout - tx timeout netdev callback | 541 | * bnx2x_tx_timeout - tx timeout netdev callback |
@@ -874,8 +875,7 @@ static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) | |||
874 | static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp) | 875 | static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp) |
875 | { | 876 | { |
876 | /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */ | 877 | /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */ |
877 | memset(fp->sge_mask, 0xff, | 878 | memset(fp->sge_mask, 0xff, sizeof(fp->sge_mask)); |
878 | (NUM_RX_SGE >> BIT_VEC64_ELEM_SHIFT)*sizeof(u64)); | ||
879 | 879 | ||
880 | /* Clear the two last indices in the page to 1: | 880 | /* Clear the two last indices in the page to 1: |
881 | these are the indices that correspond to the "next" element, | 881 | these are the indices that correspond to the "next" element, |
@@ -911,26 +911,27 @@ static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, | |||
911 | return 0; | 911 | return 0; |
912 | } | 912 | } |
913 | 913 | ||
914 | static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, | 914 | static inline int bnx2x_alloc_rx_data(struct bnx2x *bp, |
915 | struct bnx2x_fastpath *fp, u16 index) | 915 | struct bnx2x_fastpath *fp, u16 index) |
916 | { | 916 | { |
917 | struct sk_buff *skb; | 917 | u8 *data; |
918 | struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[index]; | 918 | struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[index]; |
919 | struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index]; | 919 | struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index]; |
920 | dma_addr_t mapping; | 920 | dma_addr_t mapping; |
921 | 921 | ||
922 | skb = netdev_alloc_skb(bp->dev, fp->rx_buf_size); | 922 | data = kmalloc(fp->rx_buf_size + NET_SKB_PAD, GFP_ATOMIC); |
923 | if (unlikely(skb == NULL)) | 923 | if (unlikely(data == NULL)) |
924 | return -ENOMEM; | 924 | return -ENOMEM; |
925 | 925 | ||
926 | mapping = dma_map_single(&bp->pdev->dev, skb->data, fp->rx_buf_size, | 926 | mapping = dma_map_single(&bp->pdev->dev, data + NET_SKB_PAD, |
927 | fp->rx_buf_size, | ||
927 | DMA_FROM_DEVICE); | 928 | DMA_FROM_DEVICE); |
928 | if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { | 929 | if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { |
929 | dev_kfree_skb_any(skb); | 930 | kfree(data); |
930 | return -ENOMEM; | 931 | return -ENOMEM; |
931 | } | 932 | } |
932 | 933 | ||
933 | rx_buf->skb = skb; | 934 | rx_buf->data = data; |
934 | dma_unmap_addr_set(rx_buf, mapping, mapping); | 935 | dma_unmap_addr_set(rx_buf, mapping, mapping); |
935 | 936 | ||
936 | rx_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); | 937 | rx_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); |
@@ -939,12 +940,12 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, | |||
939 | return 0; | 940 | return 0; |
940 | } | 941 | } |
941 | 942 | ||
942 | /* note that we are not allocating a new skb, | 943 | /* note that we are not allocating a new buffer, |
943 | * we are just moving one from cons to prod | 944 | * we are just moving one from cons to prod |
944 | * we are not creating a new mapping, | 945 | * we are not creating a new mapping, |
945 | * so there is no need to check for dma_mapping_error(). | 946 | * so there is no need to check for dma_mapping_error(). |
946 | */ | 947 | */ |
947 | static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, | 948 | static inline void bnx2x_reuse_rx_data(struct bnx2x_fastpath *fp, |
948 | u16 cons, u16 prod) | 949 | u16 cons, u16 prod) |
949 | { | 950 | { |
950 | struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; | 951 | struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; |
@@ -954,7 +955,7 @@ static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, | |||
954 | 955 | ||
955 | dma_unmap_addr_set(prod_rx_buf, mapping, | 956 | dma_unmap_addr_set(prod_rx_buf, mapping, |
956 | dma_unmap_addr(cons_rx_buf, mapping)); | 957 | dma_unmap_addr(cons_rx_buf, mapping)); |
957 | prod_rx_buf->skb = cons_rx_buf->skb; | 958 | prod_rx_buf->data = cons_rx_buf->data; |
958 | *prod_bd = *cons_bd; | 959 | *prod_bd = *cons_bd; |
959 | } | 960 | } |
960 | 961 | ||
@@ -1030,9 +1031,9 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, | |||
1030 | for (i = 0; i < last; i++) { | 1031 | for (i = 0; i < last; i++) { |
1031 | struct bnx2x_agg_info *tpa_info = &fp->tpa_info[i]; | 1032 | struct bnx2x_agg_info *tpa_info = &fp->tpa_info[i]; |
1032 | struct sw_rx_bd *first_buf = &tpa_info->first_buf; | 1033 | struct sw_rx_bd *first_buf = &tpa_info->first_buf; |
1033 | struct sk_buff *skb = first_buf->skb; | 1034 | u8 *data = first_buf->data; |
1034 | 1035 | ||
1035 | if (skb == NULL) { | 1036 | if (data == NULL) { |
1036 | DP(NETIF_MSG_IFDOWN, "tpa bin %d empty on free\n", i); | 1037 | DP(NETIF_MSG_IFDOWN, "tpa bin %d empty on free\n", i); |
1037 | continue; | 1038 | continue; |
1038 | } | 1039 | } |
@@ -1040,8 +1041,8 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, | |||
1040 | dma_unmap_single(&bp->pdev->dev, | 1041 | dma_unmap_single(&bp->pdev->dev, |
1041 | dma_unmap_addr(first_buf, mapping), | 1042 | dma_unmap_addr(first_buf, mapping), |
1042 | fp->rx_buf_size, DMA_FROM_DEVICE); | 1043 | fp->rx_buf_size, DMA_FROM_DEVICE); |
1043 | dev_kfree_skb(skb); | 1044 | kfree(data); |
1044 | first_buf->skb = NULL; | 1045 | first_buf->data = NULL; |
1045 | } | 1046 | } |
1046 | } | 1047 | } |
1047 | 1048 | ||
@@ -1149,7 +1150,7 @@ static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp, | |||
1149 | * fp->eth_q_stats.rx_skb_alloc_failed = 0 | 1150 | * fp->eth_q_stats.rx_skb_alloc_failed = 0 |
1150 | */ | 1151 | */ |
1151 | for (i = 0; i < rx_ring_size; i++) { | 1152 | for (i = 0; i < rx_ring_size; i++) { |
1152 | if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { | 1153 | if (bnx2x_alloc_rx_data(bp, fp, ring_prod) < 0) { |
1153 | fp->eth_q_stats.rx_skb_alloc_failed++; | 1154 | fp->eth_q_stats.rx_skb_alloc_failed++; |
1154 | continue; | 1155 | continue; |
1155 | } | 1156 | } |
@@ -1318,6 +1319,7 @@ static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) | |||
1318 | struct bnx2x_fastpath *fp = bnx2x_fcoe_fp(bp); | 1319 | struct bnx2x_fastpath *fp = bnx2x_fcoe_fp(bp); |
1319 | unsigned long q_type = 0; | 1320 | unsigned long q_type = 0; |
1320 | 1321 | ||
1322 | bnx2x_fcoe(bp, rx_queue) = BNX2X_NUM_ETH_QUEUES(bp); | ||
1321 | bnx2x_fcoe(bp, cl_id) = bnx2x_cnic_eth_cl_id(bp, | 1323 | bnx2x_fcoe(bp, cl_id) = bnx2x_cnic_eth_cl_id(bp, |
1322 | BNX2X_FCOE_ETH_CL_ID_IDX); | 1324 | BNX2X_FCOE_ETH_CL_ID_IDX); |
1323 | /** Current BNX2X_FCOE_ETH_CID deffinition implies not more than | 1325 | /** Current BNX2X_FCOE_ETH_CID deffinition implies not more than |
@@ -1488,4 +1490,68 @@ static inline u16 bnx2x_extract_max_cfg(struct bnx2x *bp, u32 mf_cfg) | |||
1488 | return max_cfg; | 1490 | return max_cfg; |
1489 | } | 1491 | } |
1490 | 1492 | ||
1493 | #ifdef BCM_CNIC | ||
1494 | /** | ||
1495 | * bnx2x_get_iscsi_info - update iSCSI params according to licensing info. | ||
1496 | * | ||
1497 | * @bp: driver handle | ||
1498 | * | ||
1499 | */ | ||
1500 | void bnx2x_get_iscsi_info(struct bnx2x *bp); | ||
1501 | #endif | ||
1502 | |||
1503 | /* returns func by VN for current port */ | ||
1504 | static inline int func_by_vn(struct bnx2x *bp, int vn) | ||
1505 | { | ||
1506 | return 2 * vn + BP_PORT(bp); | ||
1507 | } | ||
1508 | |||
1509 | /** | ||
1510 | * bnx2x_link_sync_notify - send notification to other functions. | ||
1511 | * | ||
1512 | * @bp: driver handle | ||
1513 | * | ||
1514 | */ | ||
1515 | static inline void bnx2x_link_sync_notify(struct bnx2x *bp) | ||
1516 | { | ||
1517 | int func; | ||
1518 | int vn; | ||
1519 | |||
1520 | /* Set the attention towards other drivers on the same port */ | ||
1521 | for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++) { | ||
1522 | if (vn == BP_VN(bp)) | ||
1523 | continue; | ||
1524 | |||
1525 | func = func_by_vn(bp, vn); | ||
1526 | REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + | ||
1527 | (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); | ||
1528 | } | ||
1529 | } | ||
1530 | |||
1531 | /** | ||
1532 | * bnx2x_update_drv_flags - update flags in shmem | ||
1533 | * | ||
1534 | * @bp: driver handle | ||
1535 | * @flags: flags to update | ||
1536 | * @set: set or clear | ||
1537 | * | ||
1538 | */ | ||
1539 | static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set) | ||
1540 | { | ||
1541 | if (SHMEM2_HAS(bp, drv_flags)) { | ||
1542 | u32 drv_flags; | ||
1543 | bnx2x_acquire_hw_lock(bp, HW_LOCK_DRV_FLAGS); | ||
1544 | drv_flags = SHMEM2_RD(bp, drv_flags); | ||
1545 | |||
1546 | if (set) | ||
1547 | SET_FLAGS(drv_flags, flags); | ||
1548 | else | ||
1549 | RESET_FLAGS(drv_flags, flags); | ||
1550 | |||
1551 | SHMEM2_WR(bp, drv_flags, drv_flags); | ||
1552 | DP(NETIF_MSG_HW, "drv_flags 0x%08x\n", drv_flags); | ||
1553 | bnx2x_release_hw_lock(bp, HW_LOCK_DRV_FLAGS); | ||
1554 | } | ||
1555 | } | ||
1556 | |||
1491 | #endif /* BNX2X_CMN_H */ | 1557 | #endif /* BNX2X_CMN_H */ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c index 51bd7485ab18..5051cf3deb20 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c | |||
@@ -685,24 +685,6 @@ int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall) | |||
685 | } | 685 | } |
686 | #endif | 686 | #endif |
687 | 687 | ||
688 | static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set) | ||
689 | { | ||
690 | if (SHMEM2_HAS(bp, drv_flags)) { | ||
691 | u32 drv_flags; | ||
692 | bnx2x_acquire_hw_lock(bp, HW_LOCK_DRV_FLAGS); | ||
693 | drv_flags = SHMEM2_RD(bp, drv_flags); | ||
694 | |||
695 | if (set) | ||
696 | SET_FLAGS(drv_flags, flags); | ||
697 | else | ||
698 | RESET_FLAGS(drv_flags, flags); | ||
699 | |||
700 | SHMEM2_WR(bp, drv_flags, drv_flags); | ||
701 | DP(NETIF_MSG_HW, "drv_flags 0x%08x\n", drv_flags); | ||
702 | bnx2x_release_hw_lock(bp, HW_LOCK_DRV_FLAGS); | ||
703 | } | ||
704 | } | ||
705 | |||
706 | static inline void bnx2x_dcbx_update_tc_mapping(struct bnx2x *bp) | 688 | static inline void bnx2x_dcbx_update_tc_mapping(struct bnx2x *bp) |
707 | { | 689 | { |
708 | u8 prio, cos; | 690 | u8 prio, cos; |
@@ -755,18 +737,26 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) | |||
755 | /* mark DCBX result for PMF migration */ | 737 | /* mark DCBX result for PMF migration */ |
756 | bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 1); | 738 | bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 1); |
757 | #ifdef BCM_DCBNL | 739 | #ifdef BCM_DCBNL |
758 | /** | 740 | /* |
759 | * Add new app tlvs to dcbnl | 741 | * Add new app tlvs to dcbnl |
760 | */ | 742 | */ |
761 | bnx2x_dcbnl_update_applist(bp, false); | 743 | bnx2x_dcbnl_update_applist(bp, false); |
762 | #endif | 744 | #endif |
763 | bnx2x_dcbx_stop_hw_tx(bp); | 745 | /* |
764 | 746 | * reconfigure the netdevice with the results of the new | |
765 | /* reconfigure the netdevice with the results of the new | ||
766 | * dcbx negotiation. | 747 | * dcbx negotiation. |
767 | */ | 748 | */ |
768 | bnx2x_dcbx_update_tc_mapping(bp); | 749 | bnx2x_dcbx_update_tc_mapping(bp); |
769 | 750 | ||
751 | /* | ||
752 | * allow other funtions to update their netdevices | ||
753 | * accordingly | ||
754 | */ | ||
755 | if (IS_MF(bp)) | ||
756 | bnx2x_link_sync_notify(bp); | ||
757 | |||
758 | bnx2x_dcbx_stop_hw_tx(bp); | ||
759 | |||
770 | return; | 760 | return; |
771 | } | 761 | } |
772 | case BNX2X_DCBX_STATE_TX_PAUSED: | 762 | case BNX2X_DCBX_STATE_TX_PAUSED: |
@@ -775,6 +765,7 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) | |||
775 | 765 | ||
776 | bnx2x_dcbx_update_ets_params(bp); | 766 | bnx2x_dcbx_update_ets_params(bp); |
777 | bnx2x_dcbx_resume_hw_tx(bp); | 767 | bnx2x_dcbx_resume_hw_tx(bp); |
768 | |||
778 | return; | 769 | return; |
779 | case BNX2X_DCBX_STATE_TX_RELEASED: | 770 | case BNX2X_DCBX_STATE_TX_RELEASED: |
780 | DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_RELEASED\n"); | 771 | DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_RELEASED\n"); |
@@ -883,7 +874,7 @@ static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, | |||
883 | /*For IEEE admin_recommendation_bw_precentage | 874 | /*For IEEE admin_recommendation_bw_precentage |
884 | *For IEEE admin_recommendation_ets_pg */ | 875 | *For IEEE admin_recommendation_ets_pg */ |
885 | af->pfc.pri_en_bitmap = (u8)dp->admin_pfc_bitmap; | 876 | af->pfc.pri_en_bitmap = (u8)dp->admin_pfc_bitmap; |
886 | for (i = 0; i < 4; i++) { | 877 | for (i = 0; i < DCBX_CONFIG_MAX_APP_PROTOCOL; i++) { |
887 | if (dp->admin_priority_app_table[i].valid) { | 878 | if (dp->admin_priority_app_table[i].valid) { |
888 | struct bnx2x_admin_priority_app_table *table = | 879 | struct bnx2x_admin_priority_app_table *table = |
889 | dp->admin_priority_app_table; | 880 | dp->admin_priority_app_table; |
@@ -923,7 +914,7 @@ static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, | |||
923 | 914 | ||
924 | void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled) | 915 | void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled) |
925 | { | 916 | { |
926 | if (!CHIP_IS_E1x(bp) && !CHIP_IS_E3(bp)) { | 917 | if (!CHIP_IS_E1x(bp)) { |
927 | bp->dcb_state = dcb_on; | 918 | bp->dcb_state = dcb_on; |
928 | bp->dcbx_enabled = dcbx_enabled; | 919 | bp->dcbx_enabled = dcbx_enabled; |
929 | } else { | 920 | } else { |
@@ -1863,7 +1854,7 @@ static void bnx2x_dcbx_fw_struct(struct bnx2x *bp, | |||
1863 | void bnx2x_dcbx_pmf_update(struct bnx2x *bp) | 1854 | void bnx2x_dcbx_pmf_update(struct bnx2x *bp) |
1864 | { | 1855 | { |
1865 | /* if we need to syncronize DCBX result from prev PMF | 1856 | /* if we need to syncronize DCBX result from prev PMF |
1866 | * read it from shmem and update bp accordingly | 1857 | * read it from shmem and update bp and netdev accordingly |
1867 | */ | 1858 | */ |
1868 | if (SHMEM2_HAS(bp, drv_flags) && | 1859 | if (SHMEM2_HAS(bp, drv_flags) && |
1869 | GET_FLAGS(SHMEM2_RD(bp, drv_flags), DRV_FLAGS_DCB_CONFIGURED)) { | 1860 | GET_FLAGS(SHMEM2_RD(bp, drv_flags), DRV_FLAGS_DCB_CONFIGURED)) { |
@@ -1875,6 +1866,22 @@ void bnx2x_dcbx_pmf_update(struct bnx2x *bp) | |||
1875 | bp->dcbx_error); | 1866 | bp->dcbx_error); |
1876 | bnx2x_get_dcbx_drv_param(bp, &bp->dcbx_local_feat, | 1867 | bnx2x_get_dcbx_drv_param(bp, &bp->dcbx_local_feat, |
1877 | bp->dcbx_error); | 1868 | bp->dcbx_error); |
1869 | #ifdef BCM_DCBNL | ||
1870 | /* | ||
1871 | * Add new app tlvs to dcbnl | ||
1872 | */ | ||
1873 | bnx2x_dcbnl_update_applist(bp, false); | ||
1874 | /* | ||
1875 | * Send a notification for the new negotiated parameters | ||
1876 | */ | ||
1877 | dcbnl_cee_notify(bp->dev, RTM_GETDCB, DCB_CMD_CEE_GET, 0, 0); | ||
1878 | #endif | ||
1879 | /* | ||
1880 | * reconfigure the netdevice with the results of the new | ||
1881 | * dcbx negotiation. | ||
1882 | */ | ||
1883 | bnx2x_dcbx_update_tc_mapping(bp); | ||
1884 | |||
1878 | } | 1885 | } |
1879 | } | 1886 | } |
1880 | 1887 | ||
@@ -2242,7 +2249,7 @@ static int bnx2x_set_admin_app_up(struct bnx2x *bp, u8 idtype, u16 idval, u8 up) | |||
2242 | int i, ff; | 2249 | int i, ff; |
2243 | 2250 | ||
2244 | /* iterate over the app entries looking for idtype and idval */ | 2251 | /* iterate over the app entries looking for idtype and idval */ |
2245 | for (i = 0, ff = -1; i < 4; i++) { | 2252 | for (i = 0, ff = -1; i < DCBX_CONFIG_MAX_APP_PROTOCOL; i++) { |
2246 | struct bnx2x_admin_priority_app_table *app_ent = | 2253 | struct bnx2x_admin_priority_app_table *app_ent = |
2247 | &bp->dcbx_config_params.admin_priority_app_table[i]; | 2254 | &bp->dcbx_config_params.admin_priority_app_table[i]; |
2248 | if (bnx2x_admin_app_is_equal(app_ent, idtype, idval)) | 2255 | if (bnx2x_admin_app_is_equal(app_ent, idtype, idval)) |
@@ -2251,7 +2258,7 @@ static int bnx2x_set_admin_app_up(struct bnx2x *bp, u8 idtype, u16 idval, u8 up) | |||
2251 | if (ff < 0 && !app_ent->valid) | 2258 | if (ff < 0 && !app_ent->valid) |
2252 | ff = i; | 2259 | ff = i; |
2253 | } | 2260 | } |
2254 | if (i < 4) | 2261 | if (i < DCBX_CONFIG_MAX_APP_PROTOCOL) |
2255 | /* if found overwrite up */ | 2262 | /* if found overwrite up */ |
2256 | bp->dcbx_config_params. | 2263 | bp->dcbx_config_params. |
2257 | admin_priority_app_table[i].priority = up; | 2264 | admin_priority_app_table[i].priority = up; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h index 2c6a3bca6f28..2ab9254e2d5e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h | |||
@@ -90,6 +90,7 @@ struct bnx2x_admin_priority_app_table { | |||
90 | u32 app_id; | 90 | u32 app_id; |
91 | }; | 91 | }; |
92 | 92 | ||
93 | #define DCBX_CONFIG_MAX_APP_PROTOCOL 4 | ||
93 | struct bnx2x_config_dcbx_params { | 94 | struct bnx2x_config_dcbx_params { |
94 | u32 overwrite_settings; | 95 | u32 overwrite_settings; |
95 | u32 admin_dcbx_version; | 96 | u32 admin_dcbx_version; |
@@ -109,7 +110,8 @@ struct bnx2x_config_dcbx_params { | |||
109 | u32 admin_recommendation_bw_precentage[8]; | 110 | u32 admin_recommendation_bw_precentage[8]; |
110 | u32 admin_recommendation_ets_pg[8]; | 111 | u32 admin_recommendation_ets_pg[8]; |
111 | u32 admin_pfc_bitmap; | 112 | u32 admin_pfc_bitmap; |
112 | struct bnx2x_admin_priority_app_table admin_priority_app_table[4]; | 113 | struct bnx2x_admin_priority_app_table |
114 | admin_priority_app_table[DCBX_CONFIG_MAX_APP_PROTOCOL]; | ||
113 | u32 admin_default_priority; | 115 | u32 admin_default_priority; |
114 | }; | 116 | }; |
115 | 117 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index f0ca8b27a55e..ec318711f483 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | |||
@@ -761,8 +761,8 @@ static void bnx2x_get_drvinfo(struct net_device *dev, | |||
761 | struct bnx2x *bp = netdev_priv(dev); | 761 | struct bnx2x *bp = netdev_priv(dev); |
762 | u8 phy_fw_ver[PHY_FW_VER_LEN]; | 762 | u8 phy_fw_ver[PHY_FW_VER_LEN]; |
763 | 763 | ||
764 | strcpy(info->driver, DRV_MODULE_NAME); | 764 | strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); |
765 | strcpy(info->version, DRV_MODULE_VERSION); | 765 | strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); |
766 | 766 | ||
767 | phy_fw_ver[0] = '\0'; | 767 | phy_fw_ver[0] = '\0'; |
768 | if (bp->port.pmf) { | 768 | if (bp->port.pmf) { |
@@ -773,14 +773,14 @@ static void bnx2x_get_drvinfo(struct net_device *dev, | |||
773 | bnx2x_release_phy_lock(bp); | 773 | bnx2x_release_phy_lock(bp); |
774 | } | 774 | } |
775 | 775 | ||
776 | strncpy(info->fw_version, bp->fw_ver, 32); | 776 | strlcpy(info->fw_version, bp->fw_ver, sizeof(info->fw_version)); |
777 | snprintf(info->fw_version + strlen(bp->fw_ver), 32 - strlen(bp->fw_ver), | 777 | snprintf(info->fw_version + strlen(bp->fw_ver), 32 - strlen(bp->fw_ver), |
778 | "bc %d.%d.%d%s%s", | 778 | "bc %d.%d.%d%s%s", |
779 | (bp->common.bc_ver & 0xff0000) >> 16, | 779 | (bp->common.bc_ver & 0xff0000) >> 16, |
780 | (bp->common.bc_ver & 0xff00) >> 8, | 780 | (bp->common.bc_ver & 0xff00) >> 8, |
781 | (bp->common.bc_ver & 0xff), | 781 | (bp->common.bc_ver & 0xff), |
782 | ((phy_fw_ver[0] != '\0') ? " phy " : ""), phy_fw_ver); | 782 | ((phy_fw_ver[0] != '\0') ? " phy " : ""), phy_fw_ver); |
783 | strcpy(info->bus_info, pci_name(bp->pdev)); | 783 | strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info)); |
784 | info->n_stats = BNX2X_NUM_STATS; | 784 | info->n_stats = BNX2X_NUM_STATS; |
785 | info->testinfo_len = BNX2X_NUM_TESTS; | 785 | info->testinfo_len = BNX2X_NUM_TESTS; |
786 | info->eedump_len = bp->common.flash_size; | 786 | info->eedump_len = bp->common.flash_size; |
@@ -1740,6 +1740,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) | |||
1740 | struct sw_rx_bd *rx_buf; | 1740 | struct sw_rx_bd *rx_buf; |
1741 | u16 len; | 1741 | u16 len; |
1742 | int rc = -ENODEV; | 1742 | int rc = -ENODEV; |
1743 | u8 *data; | ||
1743 | 1744 | ||
1744 | /* check the loopback mode */ | 1745 | /* check the loopback mode */ |
1745 | switch (loopback_mode) { | 1746 | switch (loopback_mode) { |
@@ -1865,10 +1866,9 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode) | |||
1865 | dma_sync_single_for_cpu(&bp->pdev->dev, | 1866 | dma_sync_single_for_cpu(&bp->pdev->dev, |
1866 | dma_unmap_addr(rx_buf, mapping), | 1867 | dma_unmap_addr(rx_buf, mapping), |
1867 | fp_rx->rx_buf_size, DMA_FROM_DEVICE); | 1868 | fp_rx->rx_buf_size, DMA_FROM_DEVICE); |
1868 | skb = rx_buf->skb; | 1869 | data = rx_buf->data + NET_SKB_PAD + cqe->fast_path_cqe.placement_offset; |
1869 | skb_reserve(skb, cqe->fast_path_cqe.placement_offset); | ||
1870 | for (i = ETH_HLEN; i < pkt_size; i++) | 1870 | for (i = ETH_HLEN; i < pkt_size; i++) |
1871 | if (*(skb->data + i) != (unsigned char) (i & 0xff)) | 1871 | if (*(data + i) != (unsigned char) (i & 0xff)) |
1872 | goto test_loopback_rx_exit; | 1872 | goto test_loopback_rx_exit; |
1873 | 1873 | ||
1874 | rc = 0; | 1874 | rc = 0; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 2f6361e949f0..0cdbb70ef83e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -2318,12 +2318,6 @@ static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp) | |||
2318 | CMNG_FLAGS_PER_PORT_FAIRNESS_VN; | 2318 | CMNG_FLAGS_PER_PORT_FAIRNESS_VN; |
2319 | } | 2319 | } |
2320 | 2320 | ||
2321 | /* returns func by VN for current port */ | ||
2322 | static inline int func_by_vn(struct bnx2x *bp, int vn) | ||
2323 | { | ||
2324 | return 2 * vn + BP_PORT(bp); | ||
2325 | } | ||
2326 | |||
2327 | static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) | 2321 | static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) |
2328 | { | 2322 | { |
2329 | struct rate_shaping_vars_per_vn m_rs_vn; | 2323 | struct rate_shaping_vars_per_vn m_rs_vn; |
@@ -2475,22 +2469,6 @@ static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type) | |||
2475 | "rate shaping and fairness are disabled\n"); | 2469 | "rate shaping and fairness are disabled\n"); |
2476 | } | 2470 | } |
2477 | 2471 | ||
2478 | static inline void bnx2x_link_sync_notify(struct bnx2x *bp) | ||
2479 | { | ||
2480 | int func; | ||
2481 | int vn; | ||
2482 | |||
2483 | /* Set the attention towards other drivers on the same port */ | ||
2484 | for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++) { | ||
2485 | if (vn == BP_VN(bp)) | ||
2486 | continue; | ||
2487 | |||
2488 | func = func_by_vn(bp, vn); | ||
2489 | REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + | ||
2490 | (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); | ||
2491 | } | ||
2492 | } | ||
2493 | |||
2494 | /* This function is called upon link interrupt */ | 2472 | /* This function is called upon link interrupt */ |
2495 | static void bnx2x_link_attn(struct bnx2x *bp) | 2473 | static void bnx2x_link_attn(struct bnx2x *bp) |
2496 | { | 2474 | { |
@@ -2549,6 +2527,9 @@ void bnx2x__link_status_update(struct bnx2x *bp) | |||
2549 | if (bp->state != BNX2X_STATE_OPEN) | 2527 | if (bp->state != BNX2X_STATE_OPEN) |
2550 | return; | 2528 | return; |
2551 | 2529 | ||
2530 | /* read updated dcb configuration */ | ||
2531 | bnx2x_dcbx_pmf_update(bp); | ||
2532 | |||
2552 | bnx2x_link_status_update(&bp->link_params, &bp->link_vars); | 2533 | bnx2x_link_status_update(&bp->link_params, &bp->link_vars); |
2553 | 2534 | ||
2554 | if (bp->link_vars.link_up) | 2535 | if (bp->link_vars.link_up) |
@@ -2808,8 +2789,8 @@ static void bnx2x_pf_rx_q_prep(struct bnx2x *bp, | |||
2808 | /* This should be a maximum number of data bytes that may be | 2789 | /* This should be a maximum number of data bytes that may be |
2809 | * placed on the BD (not including paddings). | 2790 | * placed on the BD (not including paddings). |
2810 | */ | 2791 | */ |
2811 | rxq_init->buf_sz = fp->rx_buf_size - BNX2X_FW_RX_ALIGN - | 2792 | rxq_init->buf_sz = fp->rx_buf_size - BNX2X_FW_RX_ALIGN_START - |
2812 | IP_HEADER_ALIGNMENT_PADDING; | 2793 | BNX2X_FW_RX_ALIGN_END - IP_HEADER_ALIGNMENT_PADDING; |
2813 | 2794 | ||
2814 | rxq_init->cl_qzone_id = fp->cl_qzone_id; | 2795 | rxq_init->cl_qzone_id = fp->cl_qzone_id; |
2815 | rxq_init->tpa_agg_sz = tpa_agg_size; | 2796 | rxq_init->tpa_agg_sz = tpa_agg_size; |
@@ -3318,6 +3299,17 @@ static inline void bnx2x_fan_failure(struct bnx2x *bp) | |||
3318 | netdev_err(bp->dev, "Fan Failure on Network Controller has caused" | 3299 | netdev_err(bp->dev, "Fan Failure on Network Controller has caused" |
3319 | " the driver to shutdown the card to prevent permanent" | 3300 | " the driver to shutdown the card to prevent permanent" |
3320 | " damage. Please contact OEM Support for assistance\n"); | 3301 | " damage. Please contact OEM Support for assistance\n"); |
3302 | |||
3303 | /* | ||
3304 | * Scheudle device reset (unload) | ||
3305 | * This is due to some boards consuming sufficient power when driver is | ||
3306 | * up to overheat if fan fails. | ||
3307 | */ | ||
3308 | smp_mb__before_clear_bit(); | ||
3309 | set_bit(BNX2X_SP_RTNL_FAN_FAILURE, &bp->sp_rtnl_state); | ||
3310 | smp_mb__after_clear_bit(); | ||
3311 | schedule_delayed_work(&bp->sp_rtnl_task, 0); | ||
3312 | |||
3321 | } | 3313 | } |
3322 | 3314 | ||
3323 | static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) | 3315 | static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) |
@@ -5247,7 +5239,7 @@ static void bnx2x_init_eth_fp(struct bnx2x *bp, int fp_idx) | |||
5247 | u8 cos; | 5239 | u8 cos; |
5248 | unsigned long q_type = 0; | 5240 | unsigned long q_type = 0; |
5249 | u32 cids[BNX2X_MULTI_TX_COS] = { 0 }; | 5241 | u32 cids[BNX2X_MULTI_TX_COS] = { 0 }; |
5250 | 5242 | fp->rx_queue = fp_idx; | |
5251 | fp->cid = fp_idx; | 5243 | fp->cid = fp_idx; |
5252 | fp->cl_id = bnx2x_fp_cl_id(fp); | 5244 | fp->cl_id = bnx2x_fp_cl_id(fp); |
5253 | fp->fw_sb_id = bnx2x_fp_fw_sb_id(fp); | 5245 | fp->fw_sb_id = bnx2x_fp_fw_sb_id(fp); |
@@ -8522,6 +8514,17 @@ sp_rtnl_not_reset: | |||
8522 | if (test_and_clear_bit(BNX2X_SP_RTNL_SETUP_TC, &bp->sp_rtnl_state)) | 8514 | if (test_and_clear_bit(BNX2X_SP_RTNL_SETUP_TC, &bp->sp_rtnl_state)) |
8523 | bnx2x_setup_tc(bp->dev, bp->dcbx_port_params.ets.num_of_cos); | 8515 | bnx2x_setup_tc(bp->dev, bp->dcbx_port_params.ets.num_of_cos); |
8524 | 8516 | ||
8517 | /* | ||
8518 | * in case of fan failure we need to reset id if the "stop on error" | ||
8519 | * debug flag is set, since we trying to prevent permanent overheating | ||
8520 | * damage | ||
8521 | */ | ||
8522 | if (test_and_clear_bit(BNX2X_SP_RTNL_FAN_FAILURE, &bp->sp_rtnl_state)) { | ||
8523 | DP(BNX2X_MSG_SP, "fan failure detected. Unloading driver\n"); | ||
8524 | netif_device_detach(bp->dev); | ||
8525 | bnx2x_close(bp->dev); | ||
8526 | } | ||
8527 | |||
8525 | sp_rtnl_exit: | 8528 | sp_rtnl_exit: |
8526 | rtnl_unlock(); | 8529 | rtnl_unlock(); |
8527 | } | 8530 | } |
@@ -9268,21 +9271,38 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) | |||
9268 | } | 9271 | } |
9269 | 9272 | ||
9270 | #ifdef BCM_CNIC | 9273 | #ifdef BCM_CNIC |
9271 | static void __devinit bnx2x_get_cnic_info(struct bnx2x *bp) | 9274 | void bnx2x_get_iscsi_info(struct bnx2x *bp) |
9272 | { | 9275 | { |
9273 | int port = BP_PORT(bp); | 9276 | int port = BP_PORT(bp); |
9274 | int func = BP_ABS_FUNC(bp); | ||
9275 | 9277 | ||
9276 | u32 max_iscsi_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, | 9278 | u32 max_iscsi_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, |
9277 | drv_lic_key[port].max_iscsi_conn); | 9279 | drv_lic_key[port].max_iscsi_conn); |
9278 | u32 max_fcoe_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, | ||
9279 | drv_lic_key[port].max_fcoe_conn); | ||
9280 | 9280 | ||
9281 | /* Get the number of maximum allowed iSCSI and FCoE connections */ | 9281 | /* Get the number of maximum allowed iSCSI connections */ |
9282 | bp->cnic_eth_dev.max_iscsi_conn = | 9282 | bp->cnic_eth_dev.max_iscsi_conn = |
9283 | (max_iscsi_conn & BNX2X_MAX_ISCSI_INIT_CONN_MASK) >> | 9283 | (max_iscsi_conn & BNX2X_MAX_ISCSI_INIT_CONN_MASK) >> |
9284 | BNX2X_MAX_ISCSI_INIT_CONN_SHIFT; | 9284 | BNX2X_MAX_ISCSI_INIT_CONN_SHIFT; |
9285 | 9285 | ||
9286 | BNX2X_DEV_INFO("max_iscsi_conn 0x%x\n", | ||
9287 | bp->cnic_eth_dev.max_iscsi_conn); | ||
9288 | |||
9289 | /* | ||
9290 | * If maximum allowed number of connections is zero - | ||
9291 | * disable the feature. | ||
9292 | */ | ||
9293 | if (!bp->cnic_eth_dev.max_iscsi_conn) | ||
9294 | bp->flags |= NO_ISCSI_FLAG; | ||
9295 | } | ||
9296 | |||
9297 | static void __devinit bnx2x_get_fcoe_info(struct bnx2x *bp) | ||
9298 | { | ||
9299 | int port = BP_PORT(bp); | ||
9300 | int func = BP_ABS_FUNC(bp); | ||
9301 | |||
9302 | u32 max_fcoe_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, | ||
9303 | drv_lic_key[port].max_fcoe_conn); | ||
9304 | |||
9305 | /* Get the number of maximum allowed FCoE connections */ | ||
9286 | bp->cnic_eth_dev.max_fcoe_conn = | 9306 | bp->cnic_eth_dev.max_fcoe_conn = |
9287 | (max_fcoe_conn & BNX2X_MAX_FCOE_INIT_CONN_MASK) >> | 9307 | (max_fcoe_conn & BNX2X_MAX_FCOE_INIT_CONN_MASK) >> |
9288 | BNX2X_MAX_FCOE_INIT_CONN_SHIFT; | 9308 | BNX2X_MAX_FCOE_INIT_CONN_SHIFT; |
@@ -9334,20 +9354,26 @@ static void __devinit bnx2x_get_cnic_info(struct bnx2x *bp) | |||
9334 | } | 9354 | } |
9335 | } | 9355 | } |
9336 | 9356 | ||
9337 | BNX2X_DEV_INFO("max_iscsi_conn 0x%x max_fcoe_conn 0x%x\n", | 9357 | BNX2X_DEV_INFO("max_fcoe_conn 0x%x\n", bp->cnic_eth_dev.max_fcoe_conn); |
9338 | bp->cnic_eth_dev.max_iscsi_conn, | ||
9339 | bp->cnic_eth_dev.max_fcoe_conn); | ||
9340 | 9358 | ||
9341 | /* | 9359 | /* |
9342 | * If maximum allowed number of connections is zero - | 9360 | * If maximum allowed number of connections is zero - |
9343 | * disable the feature. | 9361 | * disable the feature. |
9344 | */ | 9362 | */ |
9345 | if (!bp->cnic_eth_dev.max_iscsi_conn) | ||
9346 | bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG; | ||
9347 | |||
9348 | if (!bp->cnic_eth_dev.max_fcoe_conn) | 9363 | if (!bp->cnic_eth_dev.max_fcoe_conn) |
9349 | bp->flags |= NO_FCOE_FLAG; | 9364 | bp->flags |= NO_FCOE_FLAG; |
9350 | } | 9365 | } |
9366 | |||
9367 | static void __devinit bnx2x_get_cnic_info(struct bnx2x *bp) | ||
9368 | { | ||
9369 | /* | ||
9370 | * iSCSI may be dynamically disabled but reading | ||
9371 | * info here we will decrease memory usage by driver | ||
9372 | * if the feature is disabled for good | ||
9373 | */ | ||
9374 | bnx2x_get_iscsi_info(bp); | ||
9375 | bnx2x_get_fcoe_info(bp); | ||
9376 | } | ||
9351 | #endif | 9377 | #endif |
9352 | 9378 | ||
9353 | static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) | 9379 | static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) |
@@ -9965,7 +9991,7 @@ static int bnx2x_open(struct net_device *dev) | |||
9965 | } | 9991 | } |
9966 | 9992 | ||
9967 | /* called with rtnl_lock */ | 9993 | /* called with rtnl_lock */ |
9968 | static int bnx2x_close(struct net_device *dev) | 9994 | int bnx2x_close(struct net_device *dev) |
9969 | { | 9995 | { |
9970 | struct bnx2x *bp = netdev_priv(dev); | 9996 | struct bnx2x *bp = netdev_priv(dev); |
9971 | 9997 | ||
@@ -10823,8 +10849,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, | |||
10823 | bp->qm_cid_count = bnx2x_set_qm_cid_count(bp); | 10849 | bp->qm_cid_count = bnx2x_set_qm_cid_count(bp); |
10824 | 10850 | ||
10825 | #ifdef BCM_CNIC | 10851 | #ifdef BCM_CNIC |
10826 | /* disable FCOE L2 queue for E1x and E3*/ | 10852 | /* disable FCOE L2 queue for E1x */ |
10827 | if (CHIP_IS_E1x(bp) || CHIP_IS_E3(bp)) | 10853 | if (CHIP_IS_E1x(bp)) |
10828 | bp->flags |= NO_FCOE_FLAG; | 10854 | bp->flags |= NO_FCOE_FLAG; |
10829 | 10855 | ||
10830 | #endif | 10856 | #endif |
@@ -11561,7 +11587,7 @@ static int bnx2x_unregister_cnic(struct net_device *dev) | |||
11561 | 11587 | ||
11562 | mutex_lock(&bp->cnic_mutex); | 11588 | mutex_lock(&bp->cnic_mutex); |
11563 | cp->drv_state = 0; | 11589 | cp->drv_state = 0; |
11564 | rcu_assign_pointer(bp->cnic_ops, NULL); | 11590 | RCU_INIT_POINTER(bp->cnic_ops, NULL); |
11565 | mutex_unlock(&bp->cnic_mutex); | 11591 | mutex_unlock(&bp->cnic_mutex); |
11566 | synchronize_rcu(); | 11592 | synchronize_rcu(); |
11567 | kfree(bp->cnic_kwq); | 11593 | kfree(bp->cnic_kwq); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 02ac6a771bf9..3034f0e31938 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | |||
@@ -1349,12 +1349,14 @@ void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) | |||
1349 | enum bnx2x_stats_state state; | 1349 | enum bnx2x_stats_state state; |
1350 | if (unlikely(bp->panic)) | 1350 | if (unlikely(bp->panic)) |
1351 | return; | 1351 | return; |
1352 | bnx2x_stats_stm[bp->stats_state][event].action(bp); | 1352 | |
1353 | spin_lock_bh(&bp->stats_lock); | 1353 | spin_lock_bh(&bp->stats_lock); |
1354 | state = bp->stats_state; | 1354 | state = bp->stats_state; |
1355 | bp->stats_state = bnx2x_stats_stm[state][event].next_state; | 1355 | bp->stats_state = bnx2x_stats_stm[state][event].next_state; |
1356 | spin_unlock_bh(&bp->stats_lock); | 1356 | spin_unlock_bh(&bp->stats_lock); |
1357 | 1357 | ||
1358 | bnx2x_stats_stm[state][event].action(bp); | ||
1359 | |||
1358 | if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) | 1360 | if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) |
1359 | DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", | 1361 | DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", |
1360 | state, event, bp->stats_state); | 1362 | state, event, bp->stats_state); |
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index 6f10c6939834..b336e55e0d80 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c | |||
@@ -506,7 +506,7 @@ int cnic_unregister_driver(int ulp_type) | |||
506 | } | 506 | } |
507 | read_unlock(&cnic_dev_lock); | 507 | read_unlock(&cnic_dev_lock); |
508 | 508 | ||
509 | rcu_assign_pointer(cnic_ulp_tbl[ulp_type], NULL); | 509 | RCU_INIT_POINTER(cnic_ulp_tbl[ulp_type], NULL); |
510 | 510 | ||
511 | mutex_unlock(&cnic_lock); | 511 | mutex_unlock(&cnic_lock); |
512 | synchronize_rcu(); | 512 | synchronize_rcu(); |
@@ -579,7 +579,7 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type) | |||
579 | } | 579 | } |
580 | mutex_lock(&cnic_lock); | 580 | mutex_lock(&cnic_lock); |
581 | if (rcu_dereference(cp->ulp_ops[ulp_type])) { | 581 | if (rcu_dereference(cp->ulp_ops[ulp_type])) { |
582 | rcu_assign_pointer(cp->ulp_ops[ulp_type], NULL); | 582 | RCU_INIT_POINTER(cp->ulp_ops[ulp_type], NULL); |
583 | cnic_put(dev); | 583 | cnic_put(dev); |
584 | } else { | 584 | } else { |
585 | pr_err("%s: device not registered to this ulp type %d\n", | 585 | pr_err("%s: device not registered to this ulp type %d\n", |
@@ -3475,7 +3475,7 @@ static int cnic_get_v6_route(struct sockaddr_in6 *dst_addr, | |||
3475 | struct flowi6 fl6; | 3475 | struct flowi6 fl6; |
3476 | 3476 | ||
3477 | memset(&fl6, 0, sizeof(fl6)); | 3477 | memset(&fl6, 0, sizeof(fl6)); |
3478 | ipv6_addr_copy(&fl6.daddr, &dst_addr->sin6_addr); | 3478 | fl6.daddr = dst_addr->sin6_addr; |
3479 | if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL) | 3479 | if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL) |
3480 | fl6.flowi6_oif = dst_addr->sin6_scope_id; | 3480 | fl6.flowi6_oif = dst_addr->sin6_scope_id; |
3481 | 3481 | ||
@@ -5134,7 +5134,7 @@ static void cnic_stop_hw(struct cnic_dev *dev) | |||
5134 | } | 5134 | } |
5135 | cnic_shutdown_rings(dev); | 5135 | cnic_shutdown_rings(dev); |
5136 | clear_bit(CNIC_F_CNIC_UP, &dev->flags); | 5136 | clear_bit(CNIC_F_CNIC_UP, &dev->flags); |
5137 | rcu_assign_pointer(cp->ulp_ops[CNIC_ULP_L4], NULL); | 5137 | RCU_INIT_POINTER(cp->ulp_ops[CNIC_ULP_L4], NULL); |
5138 | synchronize_rcu(); | 5138 | synchronize_rcu(); |
5139 | cnic_cm_shutdown(dev); | 5139 | cnic_cm_shutdown(dev); |
5140 | cp->stop_hw(dev); | 5140 | cp->stop_hw(dev); |
diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c index 0a1d7f279fc8..aa58f9e3f913 100644 --- a/drivers/net/ethernet/broadcom/sb1250-mac.c +++ b/drivers/net/ethernet/broadcom/sb1250-mac.c | |||
@@ -163,7 +163,6 @@ enum sbmac_state { | |||
163 | #define SBMAC_MAX_TXDESCR 256 | 163 | #define SBMAC_MAX_TXDESCR 256 |
164 | #define SBMAC_MAX_RXDESCR 256 | 164 | #define SBMAC_MAX_RXDESCR 256 |
165 | 165 | ||
166 | #define ETHER_ADDR_LEN 6 | ||
167 | #define ENET_PACKET_SIZE 1518 | 166 | #define ENET_PACKET_SIZE 1518 |
168 | /*#define ENET_PACKET_SIZE 9216 */ | 167 | /*#define ENET_PACKET_SIZE 9216 */ |
169 | 168 | ||
@@ -266,7 +265,7 @@ struct sbmac_softc { | |||
266 | int sbm_pause; /* current pause setting */ | 265 | int sbm_pause; /* current pause setting */ |
267 | int sbm_link; /* current link state */ | 266 | int sbm_link; /* current link state */ |
268 | 267 | ||
269 | unsigned char sbm_hwaddr[ETHER_ADDR_LEN]; | 268 | unsigned char sbm_hwaddr[ETH_ALEN]; |
270 | 269 | ||
271 | struct sbmacdma sbm_txdma; /* only channel 0 for now */ | 270 | struct sbmacdma sbm_txdma; /* only channel 0 for now */ |
272 | struct sbmacdma sbm_rxdma; | 271 | struct sbmacdma sbm_rxdma; |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index bf4074167d6a..0acb279dcf5c 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -194,7 +194,7 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) | |||
194 | #if (NET_IP_ALIGN != 0) | 194 | #if (NET_IP_ALIGN != 0) |
195 | #define TG3_RX_OFFSET(tp) ((tp)->rx_offset) | 195 | #define TG3_RX_OFFSET(tp) ((tp)->rx_offset) |
196 | #else | 196 | #else |
197 | #define TG3_RX_OFFSET(tp) 0 | 197 | #define TG3_RX_OFFSET(tp) (NET_SKB_PAD) |
198 | #endif | 198 | #endif |
199 | 199 | ||
200 | /* minimum number of free TX descriptors required to wake up TX process */ | 200 | /* minimum number of free TX descriptors required to wake up TX process */ |
@@ -1706,18 +1706,12 @@ static u8 tg3_resolve_flowctrl_1000X(u16 lcladv, u16 rmtadv) | |||
1706 | { | 1706 | { |
1707 | u8 cap = 0; | 1707 | u8 cap = 0; |
1708 | 1708 | ||
1709 | if (lcladv & ADVERTISE_1000XPAUSE) { | 1709 | if (lcladv & rmtadv & ADVERTISE_1000XPAUSE) { |
1710 | if (lcladv & ADVERTISE_1000XPSE_ASYM) { | 1710 | cap = FLOW_CTRL_TX | FLOW_CTRL_RX; |
1711 | if (rmtadv & LPA_1000XPAUSE) | 1711 | } else if (lcladv & rmtadv & ADVERTISE_1000XPSE_ASYM) { |
1712 | cap = FLOW_CTRL_TX | FLOW_CTRL_RX; | 1712 | if (lcladv & ADVERTISE_1000XPAUSE) |
1713 | else if (rmtadv & LPA_1000XPAUSE_ASYM) | 1713 | cap = FLOW_CTRL_RX; |
1714 | cap = FLOW_CTRL_RX; | 1714 | if (rmtadv & ADVERTISE_1000XPAUSE) |
1715 | } else { | ||
1716 | if (rmtadv & LPA_1000XPAUSE) | ||
1717 | cap = FLOW_CTRL_TX | FLOW_CTRL_RX; | ||
1718 | } | ||
1719 | } else if (lcladv & ADVERTISE_1000XPSE_ASYM) { | ||
1720 | if ((rmtadv & LPA_1000XPAUSE) && (rmtadv & LPA_1000XPAUSE_ASYM)) | ||
1721 | cap = FLOW_CTRL_TX; | 1715 | cap = FLOW_CTRL_TX; |
1722 | } | 1716 | } |
1723 | 1717 | ||
@@ -3594,15 +3588,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) | |||
3594 | u32 val, new_adv; | 3588 | u32 val, new_adv; |
3595 | 3589 | ||
3596 | new_adv = ADVERTISE_CSMA; | 3590 | new_adv = ADVERTISE_CSMA; |
3597 | if (advertise & ADVERTISED_10baseT_Half) | 3591 | new_adv |= ethtool_adv_to_mii_adv_t(advertise) & ADVERTISE_ALL; |
3598 | new_adv |= ADVERTISE_10HALF; | ||
3599 | if (advertise & ADVERTISED_10baseT_Full) | ||
3600 | new_adv |= ADVERTISE_10FULL; | ||
3601 | if (advertise & ADVERTISED_100baseT_Half) | ||
3602 | new_adv |= ADVERTISE_100HALF; | ||
3603 | if (advertise & ADVERTISED_100baseT_Full) | ||
3604 | new_adv |= ADVERTISE_100FULL; | ||
3605 | |||
3606 | new_adv |= tg3_advert_flowctrl_1000T(flowctrl); | 3592 | new_adv |= tg3_advert_flowctrl_1000T(flowctrl); |
3607 | 3593 | ||
3608 | err = tg3_writephy(tp, MII_ADVERTISE, new_adv); | 3594 | err = tg3_writephy(tp, MII_ADVERTISE, new_adv); |
@@ -3612,11 +3598,7 @@ static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl) | |||
3612 | if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) | 3598 | if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) |
3613 | goto done; | 3599 | goto done; |
3614 | 3600 | ||
3615 | new_adv = 0; | 3601 | new_adv = ethtool_adv_to_mii_ctrl1000_t(advertise); |
3616 | if (advertise & ADVERTISED_1000baseT_Half) | ||
3617 | new_adv |= ADVERTISE_1000HALF; | ||
3618 | if (advertise & ADVERTISED_1000baseT_Full) | ||
3619 | new_adv |= ADVERTISE_1000FULL; | ||
3620 | 3602 | ||
3621 | if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 || | 3603 | if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 || |
3622 | tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) | 3604 | tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) |
@@ -3790,14 +3772,7 @@ static int tg3_copper_is_advertising_all(struct tg3 *tp, u32 mask) | |||
3790 | { | 3772 | { |
3791 | u32 adv_reg, all_mask = 0; | 3773 | u32 adv_reg, all_mask = 0; |
3792 | 3774 | ||
3793 | if (mask & ADVERTISED_10baseT_Half) | 3775 | all_mask = ethtool_adv_to_mii_adv_t(mask) & ADVERTISE_ALL; |
3794 | all_mask |= ADVERTISE_10HALF; | ||
3795 | if (mask & ADVERTISED_10baseT_Full) | ||
3796 | all_mask |= ADVERTISE_10FULL; | ||
3797 | if (mask & ADVERTISED_100baseT_Half) | ||
3798 | all_mask |= ADVERTISE_100HALF; | ||
3799 | if (mask & ADVERTISED_100baseT_Full) | ||
3800 | all_mask |= ADVERTISE_100FULL; | ||
3801 | 3776 | ||
3802 | if (tg3_readphy(tp, MII_ADVERTISE, &adv_reg)) | 3777 | if (tg3_readphy(tp, MII_ADVERTISE, &adv_reg)) |
3803 | return 0; | 3778 | return 0; |
@@ -3808,11 +3783,7 @@ static int tg3_copper_is_advertising_all(struct tg3 *tp, u32 mask) | |||
3808 | if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) { | 3783 | if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) { |
3809 | u32 tg3_ctrl; | 3784 | u32 tg3_ctrl; |
3810 | 3785 | ||
3811 | all_mask = 0; | 3786 | all_mask = ethtool_adv_to_mii_ctrl1000_t(mask); |
3812 | if (mask & ADVERTISED_1000baseT_Half) | ||
3813 | all_mask |= ADVERTISE_1000HALF; | ||
3814 | if (mask & ADVERTISED_1000baseT_Full) | ||
3815 | all_mask |= ADVERTISE_1000FULL; | ||
3816 | 3787 | ||
3817 | if (tg3_readphy(tp, MII_CTRL1000, &tg3_ctrl)) | 3788 | if (tg3_readphy(tp, MII_CTRL1000, &tg3_ctrl)) |
3818 | return 0; | 3789 | return 0; |
@@ -3961,6 +3932,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) | |||
3961 | current_link_up = 0; | 3932 | current_link_up = 0; |
3962 | current_speed = SPEED_INVALID; | 3933 | current_speed = SPEED_INVALID; |
3963 | current_duplex = DUPLEX_INVALID; | 3934 | current_duplex = DUPLEX_INVALID; |
3935 | tp->phy_flags &= ~TG3_PHYFLG_MDIX_STATE; | ||
3964 | 3936 | ||
3965 | if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) { | 3937 | if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) { |
3966 | err = tg3_phy_auxctl_read(tp, | 3938 | err = tg3_phy_auxctl_read(tp, |
@@ -4033,8 +4005,22 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) | |||
4033 | } | 4005 | } |
4034 | 4006 | ||
4035 | if (current_link_up == 1 && | 4007 | if (current_link_up == 1 && |
4036 | tp->link_config.active_duplex == DUPLEX_FULL) | 4008 | tp->link_config.active_duplex == DUPLEX_FULL) { |
4009 | u32 reg, bit; | ||
4010 | |||
4011 | if (tp->phy_flags & TG3_PHYFLG_IS_FET) { | ||
4012 | reg = MII_TG3_FET_GEN_STAT; | ||
4013 | bit = MII_TG3_FET_GEN_STAT_MDIXSTAT; | ||
4014 | } else { | ||
4015 | reg = MII_TG3_EXT_STAT; | ||
4016 | bit = MII_TG3_EXT_STAT_MDIX; | ||
4017 | } | ||
4018 | |||
4019 | if (!tg3_readphy(tp, reg, &val) && (val & bit)) | ||
4020 | tp->phy_flags |= TG3_PHYFLG_MDIX_STATE; | ||
4021 | |||
4037 | tg3_setup_flow_control(tp, lcl_adv, rmt_adv); | 4022 | tg3_setup_flow_control(tp, lcl_adv, rmt_adv); |
4023 | } | ||
4038 | } | 4024 | } |
4039 | 4025 | ||
4040 | relink: | 4026 | relink: |
@@ -4903,23 +4889,19 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) | |||
4903 | (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) { | 4889 | (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) { |
4904 | /* do nothing, just check for link up at the end */ | 4890 | /* do nothing, just check for link up at the end */ |
4905 | } else if (tp->link_config.autoneg == AUTONEG_ENABLE) { | 4891 | } else if (tp->link_config.autoneg == AUTONEG_ENABLE) { |
4906 | u32 adv, new_adv; | 4892 | u32 adv, newadv; |
4907 | 4893 | ||
4908 | err |= tg3_readphy(tp, MII_ADVERTISE, &adv); | 4894 | err |= tg3_readphy(tp, MII_ADVERTISE, &adv); |
4909 | new_adv = adv & ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF | | 4895 | newadv = adv & ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF | |
4910 | ADVERTISE_1000XPAUSE | | 4896 | ADVERTISE_1000XPAUSE | |
4911 | ADVERTISE_1000XPSE_ASYM | | 4897 | ADVERTISE_1000XPSE_ASYM | |
4912 | ADVERTISE_SLCT); | 4898 | ADVERTISE_SLCT); |
4913 | |||
4914 | new_adv |= tg3_advert_flowctrl_1000X(tp->link_config.flowctrl); | ||
4915 | 4899 | ||
4916 | if (tp->link_config.advertising & ADVERTISED_1000baseT_Half) | 4900 | newadv |= tg3_advert_flowctrl_1000X(tp->link_config.flowctrl); |
4917 | new_adv |= ADVERTISE_1000XHALF; | 4901 | newadv |= ethtool_adv_to_mii_adv_x(tp->link_config.advertising); |
4918 | if (tp->link_config.advertising & ADVERTISED_1000baseT_Full) | ||
4919 | new_adv |= ADVERTISE_1000XFULL; | ||
4920 | 4902 | ||
4921 | if ((new_adv != adv) || !(bmcr & BMCR_ANENABLE)) { | 4903 | if ((newadv != adv) || !(bmcr & BMCR_ANENABLE)) { |
4922 | tg3_writephy(tp, MII_ADVERTISE, new_adv); | 4904 | tg3_writephy(tp, MII_ADVERTISE, newadv); |
4923 | bmcr |= BMCR_ANENABLE | BMCR_ANRESTART; | 4905 | bmcr |= BMCR_ANENABLE | BMCR_ANRESTART; |
4924 | tg3_writephy(tp, MII_BMCR, bmcr); | 4906 | tg3_writephy(tp, MII_BMCR, bmcr); |
4925 | 4907 | ||
@@ -5397,15 +5379,15 @@ static void tg3_tx(struct tg3_napi *tnapi) | |||
5397 | } | 5379 | } |
5398 | } | 5380 | } |
5399 | 5381 | ||
5400 | static void tg3_rx_skb_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz) | 5382 | static void tg3_rx_data_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz) |
5401 | { | 5383 | { |
5402 | if (!ri->skb) | 5384 | if (!ri->data) |
5403 | return; | 5385 | return; |
5404 | 5386 | ||
5405 | pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping), | 5387 | pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping), |
5406 | map_sz, PCI_DMA_FROMDEVICE); | 5388 | map_sz, PCI_DMA_FROMDEVICE); |
5407 | dev_kfree_skb_any(ri->skb); | 5389 | kfree(ri->data); |
5408 | ri->skb = NULL; | 5390 | ri->data = NULL; |
5409 | } | 5391 | } |
5410 | 5392 | ||
5411 | /* Returns size of skb allocated or < 0 on error. | 5393 | /* Returns size of skb allocated or < 0 on error. |
@@ -5419,28 +5401,28 @@ static void tg3_rx_skb_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz) | |||
5419 | * buffers the cpu only reads the last cacheline of the RX descriptor | 5401 | * buffers the cpu only reads the last cacheline of the RX descriptor |
5420 | * (to fetch the error flags, vlan tag, checksum, and opaque cookie). | 5402 | * (to fetch the error flags, vlan tag, checksum, and opaque cookie). |
5421 | */ | 5403 | */ |
5422 | static int tg3_alloc_rx_skb(struct tg3 *tp, struct tg3_rx_prodring_set *tpr, | 5404 | static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr, |
5423 | u32 opaque_key, u32 dest_idx_unmasked) | 5405 | u32 opaque_key, u32 dest_idx_unmasked) |
5424 | { | 5406 | { |
5425 | struct tg3_rx_buffer_desc *desc; | 5407 | struct tg3_rx_buffer_desc *desc; |
5426 | struct ring_info *map; | 5408 | struct ring_info *map; |
5427 | struct sk_buff *skb; | 5409 | u8 *data; |
5428 | dma_addr_t mapping; | 5410 | dma_addr_t mapping; |
5429 | int skb_size, dest_idx; | 5411 | int skb_size, data_size, dest_idx; |
5430 | 5412 | ||
5431 | switch (opaque_key) { | 5413 | switch (opaque_key) { |
5432 | case RXD_OPAQUE_RING_STD: | 5414 | case RXD_OPAQUE_RING_STD: |
5433 | dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask; | 5415 | dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask; |
5434 | desc = &tpr->rx_std[dest_idx]; | 5416 | desc = &tpr->rx_std[dest_idx]; |
5435 | map = &tpr->rx_std_buffers[dest_idx]; | 5417 | map = &tpr->rx_std_buffers[dest_idx]; |
5436 | skb_size = tp->rx_pkt_map_sz; | 5418 | data_size = tp->rx_pkt_map_sz; |
5437 | break; | 5419 | break; |
5438 | 5420 | ||
5439 | case RXD_OPAQUE_RING_JUMBO: | 5421 | case RXD_OPAQUE_RING_JUMBO: |
5440 | dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask; | 5422 | dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask; |
5441 | desc = &tpr->rx_jmb[dest_idx].std; | 5423 | desc = &tpr->rx_jmb[dest_idx].std; |
5442 | map = &tpr->rx_jmb_buffers[dest_idx]; | 5424 | map = &tpr->rx_jmb_buffers[dest_idx]; |
5443 | skb_size = TG3_RX_JMB_MAP_SZ; | 5425 | data_size = TG3_RX_JMB_MAP_SZ; |
5444 | break; | 5426 | break; |
5445 | 5427 | ||
5446 | default: | 5428 | default: |
@@ -5453,31 +5435,33 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, struct tg3_rx_prodring_set *tpr, | |||
5453 | * Callers depend upon this behavior and assume that | 5435 | * Callers depend upon this behavior and assume that |
5454 | * we leave everything unchanged if we fail. | 5436 | * we leave everything unchanged if we fail. |
5455 | */ | 5437 | */ |
5456 | skb = netdev_alloc_skb(tp->dev, skb_size + TG3_RX_OFFSET(tp)); | 5438 | skb_size = SKB_DATA_ALIGN(data_size + TG3_RX_OFFSET(tp)) + |
5457 | if (skb == NULL) | 5439 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); |
5440 | data = kmalloc(skb_size, GFP_ATOMIC); | ||
5441 | if (!data) | ||
5458 | return -ENOMEM; | 5442 | return -ENOMEM; |
5459 | 5443 | ||
5460 | skb_reserve(skb, TG3_RX_OFFSET(tp)); | 5444 | mapping = pci_map_single(tp->pdev, |
5461 | 5445 | data + TG3_RX_OFFSET(tp), | |
5462 | mapping = pci_map_single(tp->pdev, skb->data, skb_size, | 5446 | data_size, |
5463 | PCI_DMA_FROMDEVICE); | 5447 | PCI_DMA_FROMDEVICE); |
5464 | if (pci_dma_mapping_error(tp->pdev, mapping)) { | 5448 | if (pci_dma_mapping_error(tp->pdev, mapping)) { |
5465 | dev_kfree_skb(skb); | 5449 | kfree(data); |
5466 | return -EIO; | 5450 | return -EIO; |
5467 | } | 5451 | } |
5468 | 5452 | ||
5469 | map->skb = skb; | 5453 | map->data = data; |
5470 | dma_unmap_addr_set(map, mapping, mapping); | 5454 | dma_unmap_addr_set(map, mapping, mapping); |
5471 | 5455 | ||
5472 | desc->addr_hi = ((u64)mapping >> 32); | 5456 | desc->addr_hi = ((u64)mapping >> 32); |
5473 | desc->addr_lo = ((u64)mapping & 0xffffffff); | 5457 | desc->addr_lo = ((u64)mapping & 0xffffffff); |
5474 | 5458 | ||
5475 | return skb_size; | 5459 | return data_size; |
5476 | } | 5460 | } |
5477 | 5461 | ||
5478 | /* We only need to move over in the address because the other | 5462 | /* We only need to move over in the address because the other |
5479 | * members of the RX descriptor are invariant. See notes above | 5463 | * members of the RX descriptor are invariant. See notes above |
5480 | * tg3_alloc_rx_skb for full details. | 5464 | * tg3_alloc_rx_data for full details. |
5481 | */ | 5465 | */ |
5482 | static void tg3_recycle_rx(struct tg3_napi *tnapi, | 5466 | static void tg3_recycle_rx(struct tg3_napi *tnapi, |
5483 | struct tg3_rx_prodring_set *dpr, | 5467 | struct tg3_rx_prodring_set *dpr, |
@@ -5511,7 +5495,7 @@ static void tg3_recycle_rx(struct tg3_napi *tnapi, | |||
5511 | return; | 5495 | return; |
5512 | } | 5496 | } |
5513 | 5497 | ||
5514 | dest_map->skb = src_map->skb; | 5498 | dest_map->data = src_map->data; |
5515 | dma_unmap_addr_set(dest_map, mapping, | 5499 | dma_unmap_addr_set(dest_map, mapping, |
5516 | dma_unmap_addr(src_map, mapping)); | 5500 | dma_unmap_addr(src_map, mapping)); |
5517 | dest_desc->addr_hi = src_desc->addr_hi; | 5501 | dest_desc->addr_hi = src_desc->addr_hi; |
@@ -5522,7 +5506,7 @@ static void tg3_recycle_rx(struct tg3_napi *tnapi, | |||
5522 | */ | 5506 | */ |
5523 | smp_wmb(); | 5507 | smp_wmb(); |
5524 | 5508 | ||
5525 | src_map->skb = NULL; | 5509 | src_map->data = NULL; |
5526 | } | 5510 | } |
5527 | 5511 | ||
5528 | /* The RX ring scheme is composed of multiple rings which post fresh | 5512 | /* The RX ring scheme is composed of multiple rings which post fresh |
@@ -5576,19 +5560,20 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
5576 | struct sk_buff *skb; | 5560 | struct sk_buff *skb; |
5577 | dma_addr_t dma_addr; | 5561 | dma_addr_t dma_addr; |
5578 | u32 opaque_key, desc_idx, *post_ptr; | 5562 | u32 opaque_key, desc_idx, *post_ptr; |
5563 | u8 *data; | ||
5579 | 5564 | ||
5580 | desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; | 5565 | desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; |
5581 | opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; | 5566 | opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; |
5582 | if (opaque_key == RXD_OPAQUE_RING_STD) { | 5567 | if (opaque_key == RXD_OPAQUE_RING_STD) { |
5583 | ri = &tp->napi[0].prodring.rx_std_buffers[desc_idx]; | 5568 | ri = &tp->napi[0].prodring.rx_std_buffers[desc_idx]; |
5584 | dma_addr = dma_unmap_addr(ri, mapping); | 5569 | dma_addr = dma_unmap_addr(ri, mapping); |
5585 | skb = ri->skb; | 5570 | data = ri->data; |
5586 | post_ptr = &std_prod_idx; | 5571 | post_ptr = &std_prod_idx; |
5587 | rx_std_posted++; | 5572 | rx_std_posted++; |
5588 | } else if (opaque_key == RXD_OPAQUE_RING_JUMBO) { | 5573 | } else if (opaque_key == RXD_OPAQUE_RING_JUMBO) { |
5589 | ri = &tp->napi[0].prodring.rx_jmb_buffers[desc_idx]; | 5574 | ri = &tp->napi[0].prodring.rx_jmb_buffers[desc_idx]; |
5590 | dma_addr = dma_unmap_addr(ri, mapping); | 5575 | dma_addr = dma_unmap_addr(ri, mapping); |
5591 | skb = ri->skb; | 5576 | data = ri->data; |
5592 | post_ptr = &jmb_prod_idx; | 5577 | post_ptr = &jmb_prod_idx; |
5593 | } else | 5578 | } else |
5594 | goto next_pkt_nopost; | 5579 | goto next_pkt_nopost; |
@@ -5606,13 +5591,14 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
5606 | goto next_pkt; | 5591 | goto next_pkt; |
5607 | } | 5592 | } |
5608 | 5593 | ||
5594 | prefetch(data + TG3_RX_OFFSET(tp)); | ||
5609 | len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - | 5595 | len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - |
5610 | ETH_FCS_LEN; | 5596 | ETH_FCS_LEN; |
5611 | 5597 | ||
5612 | if (len > TG3_RX_COPY_THRESH(tp)) { | 5598 | if (len > TG3_RX_COPY_THRESH(tp)) { |
5613 | int skb_size; | 5599 | int skb_size; |
5614 | 5600 | ||
5615 | skb_size = tg3_alloc_rx_skb(tp, tpr, opaque_key, | 5601 | skb_size = tg3_alloc_rx_data(tp, tpr, opaque_key, |
5616 | *post_ptr); | 5602 | *post_ptr); |
5617 | if (skb_size < 0) | 5603 | if (skb_size < 0) |
5618 | goto drop_it; | 5604 | goto drop_it; |
@@ -5620,35 +5606,37 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
5620 | pci_unmap_single(tp->pdev, dma_addr, skb_size, | 5606 | pci_unmap_single(tp->pdev, dma_addr, skb_size, |
5621 | PCI_DMA_FROMDEVICE); | 5607 | PCI_DMA_FROMDEVICE); |
5622 | 5608 | ||
5623 | /* Ensure that the update to the skb happens | 5609 | skb = build_skb(data); |
5610 | if (!skb) { | ||
5611 | kfree(data); | ||
5612 | goto drop_it_no_recycle; | ||
5613 | } | ||
5614 | skb_reserve(skb, TG3_RX_OFFSET(tp)); | ||
5615 | /* Ensure that the update to the data happens | ||
5624 | * after the usage of the old DMA mapping. | 5616 | * after the usage of the old DMA mapping. |
5625 | */ | 5617 | */ |
5626 | smp_wmb(); | 5618 | smp_wmb(); |
5627 | 5619 | ||
5628 | ri->skb = NULL; | 5620 | ri->data = NULL; |
5629 | 5621 | ||
5630 | skb_put(skb, len); | ||
5631 | } else { | 5622 | } else { |
5632 | struct sk_buff *copy_skb; | ||
5633 | |||
5634 | tg3_recycle_rx(tnapi, tpr, opaque_key, | 5623 | tg3_recycle_rx(tnapi, tpr, opaque_key, |
5635 | desc_idx, *post_ptr); | 5624 | desc_idx, *post_ptr); |
5636 | 5625 | ||
5637 | copy_skb = netdev_alloc_skb(tp->dev, len + | 5626 | skb = netdev_alloc_skb(tp->dev, |
5638 | TG3_RAW_IP_ALIGN); | 5627 | len + TG3_RAW_IP_ALIGN); |
5639 | if (copy_skb == NULL) | 5628 | if (skb == NULL) |
5640 | goto drop_it_no_recycle; | 5629 | goto drop_it_no_recycle; |
5641 | 5630 | ||
5642 | skb_reserve(copy_skb, TG3_RAW_IP_ALIGN); | 5631 | skb_reserve(skb, TG3_RAW_IP_ALIGN); |
5643 | skb_put(copy_skb, len); | ||
5644 | pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); | 5632 | pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); |
5645 | skb_copy_from_linear_data(skb, copy_skb->data, len); | 5633 | memcpy(skb->data, |
5634 | data + TG3_RX_OFFSET(tp), | ||
5635 | len); | ||
5646 | pci_dma_sync_single_for_device(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); | 5636 | pci_dma_sync_single_for_device(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); |
5647 | |||
5648 | /* We'll reuse the original ring buffer. */ | ||
5649 | skb = copy_skb; | ||
5650 | } | 5637 | } |
5651 | 5638 | ||
5639 | skb_put(skb, len); | ||
5652 | if ((tp->dev->features & NETIF_F_RXCSUM) && | 5640 | if ((tp->dev->features & NETIF_F_RXCSUM) && |
5653 | (desc->type_flags & RXD_FLAG_TCPUDP_CSUM) && | 5641 | (desc->type_flags & RXD_FLAG_TCPUDP_CSUM) && |
5654 | (((desc->ip_tcp_csum & RXD_TCPCSUM_MASK) | 5642 | (((desc->ip_tcp_csum & RXD_TCPCSUM_MASK) |
@@ -5787,7 +5775,7 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp, | |||
5787 | di = dpr->rx_std_prod_idx; | 5775 | di = dpr->rx_std_prod_idx; |
5788 | 5776 | ||
5789 | for (i = di; i < di + cpycnt; i++) { | 5777 | for (i = di; i < di + cpycnt; i++) { |
5790 | if (dpr->rx_std_buffers[i].skb) { | 5778 | if (dpr->rx_std_buffers[i].data) { |
5791 | cpycnt = i - di; | 5779 | cpycnt = i - di; |
5792 | err = -ENOSPC; | 5780 | err = -ENOSPC; |
5793 | break; | 5781 | break; |
@@ -5845,7 +5833,7 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp, | |||
5845 | di = dpr->rx_jmb_prod_idx; | 5833 | di = dpr->rx_jmb_prod_idx; |
5846 | 5834 | ||
5847 | for (i = di; i < di + cpycnt; i++) { | 5835 | for (i = di; i < di + cpycnt; i++) { |
5848 | if (dpr->rx_jmb_buffers[i].skb) { | 5836 | if (dpr->rx_jmb_buffers[i].data) { |
5849 | cpycnt = i - di; | 5837 | cpycnt = i - di; |
5850 | err = -ENOSPC; | 5838 | err = -ENOSPC; |
5851 | break; | 5839 | break; |
@@ -6968,7 +6956,7 @@ static int tg3_phy_lpbk_set(struct tg3 *tp, u32 speed, bool extlpbk) | |||
6968 | return 0; | 6956 | return 0; |
6969 | } | 6957 | } |
6970 | 6958 | ||
6971 | static void tg3_set_loopback(struct net_device *dev, u32 features) | 6959 | static void tg3_set_loopback(struct net_device *dev, netdev_features_t features) |
6972 | { | 6960 | { |
6973 | struct tg3 *tp = netdev_priv(dev); | 6961 | struct tg3 *tp = netdev_priv(dev); |
6974 | 6962 | ||
@@ -6994,7 +6982,8 @@ static void tg3_set_loopback(struct net_device *dev, u32 features) | |||
6994 | } | 6982 | } |
6995 | } | 6983 | } |
6996 | 6984 | ||
6997 | static u32 tg3_fix_features(struct net_device *dev, u32 features) | 6985 | static netdev_features_t tg3_fix_features(struct net_device *dev, |
6986 | netdev_features_t features) | ||
6998 | { | 6987 | { |
6999 | struct tg3 *tp = netdev_priv(dev); | 6988 | struct tg3 *tp = netdev_priv(dev); |
7000 | 6989 | ||
@@ -7004,9 +6993,9 @@ static u32 tg3_fix_features(struct net_device *dev, u32 features) | |||
7004 | return features; | 6993 | return features; |
7005 | } | 6994 | } |
7006 | 6995 | ||
7007 | static int tg3_set_features(struct net_device *dev, u32 features) | 6996 | static int tg3_set_features(struct net_device *dev, netdev_features_t features) |
7008 | { | 6997 | { |
7009 | u32 changed = dev->features ^ features; | 6998 | netdev_features_t changed = dev->features ^ features; |
7010 | 6999 | ||
7011 | if ((changed & NETIF_F_LOOPBACK) && netif_running(dev)) | 7000 | if ((changed & NETIF_F_LOOPBACK) && netif_running(dev)) |
7012 | tg3_set_loopback(dev, features); | 7001 | tg3_set_loopback(dev, features); |
@@ -7082,14 +7071,14 @@ static void tg3_rx_prodring_free(struct tg3 *tp, | |||
7082 | if (tpr != &tp->napi[0].prodring) { | 7071 | if (tpr != &tp->napi[0].prodring) { |
7083 | for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx; | 7072 | for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx; |
7084 | i = (i + 1) & tp->rx_std_ring_mask) | 7073 | i = (i + 1) & tp->rx_std_ring_mask) |
7085 | tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i], | 7074 | tg3_rx_data_free(tp, &tpr->rx_std_buffers[i], |
7086 | tp->rx_pkt_map_sz); | 7075 | tp->rx_pkt_map_sz); |
7087 | 7076 | ||
7088 | if (tg3_flag(tp, JUMBO_CAPABLE)) { | 7077 | if (tg3_flag(tp, JUMBO_CAPABLE)) { |
7089 | for (i = tpr->rx_jmb_cons_idx; | 7078 | for (i = tpr->rx_jmb_cons_idx; |
7090 | i != tpr->rx_jmb_prod_idx; | 7079 | i != tpr->rx_jmb_prod_idx; |
7091 | i = (i + 1) & tp->rx_jmb_ring_mask) { | 7080 | i = (i + 1) & tp->rx_jmb_ring_mask) { |
7092 | tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i], | 7081 | tg3_rx_data_free(tp, &tpr->rx_jmb_buffers[i], |
7093 | TG3_RX_JMB_MAP_SZ); | 7082 | TG3_RX_JMB_MAP_SZ); |
7094 | } | 7083 | } |
7095 | } | 7084 | } |
@@ -7098,12 +7087,12 @@ static void tg3_rx_prodring_free(struct tg3 *tp, | |||
7098 | } | 7087 | } |
7099 | 7088 | ||
7100 | for (i = 0; i <= tp->rx_std_ring_mask; i++) | 7089 | for (i = 0; i <= tp->rx_std_ring_mask; i++) |
7101 | tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i], | 7090 | tg3_rx_data_free(tp, &tpr->rx_std_buffers[i], |
7102 | tp->rx_pkt_map_sz); | 7091 | tp->rx_pkt_map_sz); |
7103 | 7092 | ||
7104 | if (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS)) { | 7093 | if (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS)) { |
7105 | for (i = 0; i <= tp->rx_jmb_ring_mask; i++) | 7094 | for (i = 0; i <= tp->rx_jmb_ring_mask; i++) |
7106 | tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i], | 7095 | tg3_rx_data_free(tp, &tpr->rx_jmb_buffers[i], |
7107 | TG3_RX_JMB_MAP_SZ); | 7096 | TG3_RX_JMB_MAP_SZ); |
7108 | } | 7097 | } |
7109 | } | 7098 | } |
@@ -7159,7 +7148,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, | |||
7159 | 7148 | ||
7160 | /* Now allocate fresh SKBs for each rx ring. */ | 7149 | /* Now allocate fresh SKBs for each rx ring. */ |
7161 | for (i = 0; i < tp->rx_pending; i++) { | 7150 | for (i = 0; i < tp->rx_pending; i++) { |
7162 | if (tg3_alloc_rx_skb(tp, tpr, RXD_OPAQUE_RING_STD, i) < 0) { | 7151 | if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_STD, i) < 0) { |
7163 | netdev_warn(tp->dev, | 7152 | netdev_warn(tp->dev, |
7164 | "Using a smaller RX standard ring. Only " | 7153 | "Using a smaller RX standard ring. Only " |
7165 | "%d out of %d buffers were allocated " | 7154 | "%d out of %d buffers were allocated " |
@@ -7191,7 +7180,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, | |||
7191 | } | 7180 | } |
7192 | 7181 | ||
7193 | for (i = 0; i < tp->rx_jumbo_pending; i++) { | 7182 | for (i = 0; i < tp->rx_jumbo_pending; i++) { |
7194 | if (tg3_alloc_rx_skb(tp, tpr, RXD_OPAQUE_RING_JUMBO, i) < 0) { | 7183 | if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_JUMBO, i) < 0) { |
7195 | netdev_warn(tp->dev, | 7184 | netdev_warn(tp->dev, |
7196 | "Using a smaller RX jumbo ring. Only %d " | 7185 | "Using a smaller RX jumbo ring. Only %d " |
7197 | "out of %d buffers were allocated " | 7186 | "out of %d buffers were allocated " |
@@ -8197,7 +8186,8 @@ static void tg3_setup_rxbd_thresholds(struct tg3 *tp) | |||
8197 | if (!tg3_flag(tp, 5750_PLUS) || | 8186 | if (!tg3_flag(tp, 5750_PLUS) || |
8198 | tg3_flag(tp, 5780_CLASS) || | 8187 | tg3_flag(tp, 5780_CLASS) || |
8199 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 || | 8188 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 || |
8200 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) | 8189 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || |
8190 | tg3_flag(tp, 57765_PLUS)) | ||
8201 | bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5700; | 8191 | bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5700; |
8202 | else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || | 8192 | else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || |
8203 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) | 8193 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) |
@@ -8217,10 +8207,7 @@ static void tg3_setup_rxbd_thresholds(struct tg3 *tp) | |||
8217 | if (!tg3_flag(tp, JUMBO_CAPABLE) || tg3_flag(tp, 5780_CLASS)) | 8207 | if (!tg3_flag(tp, JUMBO_CAPABLE) || tg3_flag(tp, 5780_CLASS)) |
8218 | return; | 8208 | return; |
8219 | 8209 | ||
8220 | if (!tg3_flag(tp, 5705_PLUS)) | 8210 | bdcache_maxcnt = TG3_SRAM_RX_JMB_BDCACHE_SIZE_5700; |
8221 | bdcache_maxcnt = TG3_SRAM_RX_JMB_BDCACHE_SIZE_5700; | ||
8222 | else | ||
8223 | bdcache_maxcnt = TG3_SRAM_RX_JMB_BDCACHE_SIZE_5717; | ||
8224 | 8211 | ||
8225 | host_rep_thresh = max_t(u32, tp->rx_jumbo_pending / 8, 1); | 8212 | host_rep_thresh = max_t(u32, tp->rx_jumbo_pending / 8, 1); |
8226 | 8213 | ||
@@ -8581,10 +8568,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
8581 | } | 8568 | } |
8582 | 8569 | ||
8583 | if (tg3_flag(tp, 57765_PLUS)) { | 8570 | if (tg3_flag(tp, 57765_PLUS)) { |
8584 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) | 8571 | val = TG3_RX_STD_RING_SIZE(tp); |
8585 | val = TG3_RX_STD_MAX_SIZE_5700; | ||
8586 | else | ||
8587 | val = TG3_RX_STD_MAX_SIZE_5717; | ||
8588 | val <<= BDINFO_FLAGS_MAXLEN_SHIFT; | 8572 | val <<= BDINFO_FLAGS_MAXLEN_SHIFT; |
8589 | val |= (TG3_RX_STD_DMA_SZ << 2); | 8573 | val |= (TG3_RX_STD_DMA_SZ << 2); |
8590 | } else | 8574 | } else |
@@ -10321,9 +10305,16 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
10321 | if (netif_running(dev)) { | 10305 | if (netif_running(dev)) { |
10322 | ethtool_cmd_speed_set(cmd, tp->link_config.active_speed); | 10306 | ethtool_cmd_speed_set(cmd, tp->link_config.active_speed); |
10323 | cmd->duplex = tp->link_config.active_duplex; | 10307 | cmd->duplex = tp->link_config.active_duplex; |
10308 | if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) { | ||
10309 | if (tp->phy_flags & TG3_PHYFLG_MDIX_STATE) | ||
10310 | cmd->eth_tp_mdix = ETH_TP_MDI_X; | ||
10311 | else | ||
10312 | cmd->eth_tp_mdix = ETH_TP_MDI; | ||
10313 | } | ||
10324 | } else { | 10314 | } else { |
10325 | ethtool_cmd_speed_set(cmd, SPEED_INVALID); | 10315 | ethtool_cmd_speed_set(cmd, SPEED_INVALID); |
10326 | cmd->duplex = DUPLEX_INVALID; | 10316 | cmd->duplex = DUPLEX_INVALID; |
10317 | cmd->eth_tp_mdix = ETH_TP_MDI_INVALID; | ||
10327 | } | 10318 | } |
10328 | cmd->phy_address = tp->phy_addr; | 10319 | cmd->phy_address = tp->phy_addr; |
10329 | cmd->transceiver = XCVR_INTERNAL; | 10320 | cmd->transceiver = XCVR_INTERNAL; |
@@ -10428,10 +10419,10 @@ static void tg3_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info | |||
10428 | { | 10419 | { |
10429 | struct tg3 *tp = netdev_priv(dev); | 10420 | struct tg3 *tp = netdev_priv(dev); |
10430 | 10421 | ||
10431 | strcpy(info->driver, DRV_MODULE_NAME); | 10422 | strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); |
10432 | strcpy(info->version, DRV_MODULE_VERSION); | 10423 | strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); |
10433 | strcpy(info->fw_version, tp->fw_ver); | 10424 | strlcpy(info->fw_version, tp->fw_ver, sizeof(info->fw_version)); |
10434 | strcpy(info->bus_info, pci_name(tp->pdev)); | 10425 | strlcpy(info->bus_info, pci_name(tp->pdev), sizeof(info->bus_info)); |
10435 | } | 10426 | } |
10436 | 10427 | ||
10437 | static void tg3_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 10428 | static void tg3_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
@@ -11400,8 +11391,8 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, bool tso_loopback) | |||
11400 | u32 rx_start_idx, rx_idx, tx_idx, opaque_key; | 11391 | u32 rx_start_idx, rx_idx, tx_idx, opaque_key; |
11401 | u32 base_flags = 0, mss = 0, desc_idx, coal_now, data_off, val; | 11392 | u32 base_flags = 0, mss = 0, desc_idx, coal_now, data_off, val; |
11402 | u32 budget; | 11393 | u32 budget; |
11403 | struct sk_buff *skb, *rx_skb; | 11394 | struct sk_buff *skb; |
11404 | u8 *tx_data; | 11395 | u8 *tx_data, *rx_data; |
11405 | dma_addr_t map; | 11396 | dma_addr_t map; |
11406 | int num_pkts, tx_len, rx_len, i, err; | 11397 | int num_pkts, tx_len, rx_len, i, err; |
11407 | struct tg3_rx_buffer_desc *desc; | 11398 | struct tg3_rx_buffer_desc *desc; |
@@ -11569,11 +11560,11 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, bool tso_loopback) | |||
11569 | } | 11560 | } |
11570 | 11561 | ||
11571 | if (opaque_key == RXD_OPAQUE_RING_STD) { | 11562 | if (opaque_key == RXD_OPAQUE_RING_STD) { |
11572 | rx_skb = tpr->rx_std_buffers[desc_idx].skb; | 11563 | rx_data = tpr->rx_std_buffers[desc_idx].data; |
11573 | map = dma_unmap_addr(&tpr->rx_std_buffers[desc_idx], | 11564 | map = dma_unmap_addr(&tpr->rx_std_buffers[desc_idx], |
11574 | mapping); | 11565 | mapping); |
11575 | } else if (opaque_key == RXD_OPAQUE_RING_JUMBO) { | 11566 | } else if (opaque_key == RXD_OPAQUE_RING_JUMBO) { |
11576 | rx_skb = tpr->rx_jmb_buffers[desc_idx].skb; | 11567 | rx_data = tpr->rx_jmb_buffers[desc_idx].data; |
11577 | map = dma_unmap_addr(&tpr->rx_jmb_buffers[desc_idx], | 11568 | map = dma_unmap_addr(&tpr->rx_jmb_buffers[desc_idx], |
11578 | mapping); | 11569 | mapping); |
11579 | } else | 11570 | } else |
@@ -11582,15 +11573,16 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, bool tso_loopback) | |||
11582 | pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, | 11573 | pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, |
11583 | PCI_DMA_FROMDEVICE); | 11574 | PCI_DMA_FROMDEVICE); |
11584 | 11575 | ||
11576 | rx_data += TG3_RX_OFFSET(tp); | ||
11585 | for (i = data_off; i < rx_len; i++, val++) { | 11577 | for (i = data_off; i < rx_len; i++, val++) { |
11586 | if (*(rx_skb->data + i) != (u8) (val & 0xff)) | 11578 | if (*(rx_data + i) != (u8) (val & 0xff)) |
11587 | goto out; | 11579 | goto out; |
11588 | } | 11580 | } |
11589 | } | 11581 | } |
11590 | 11582 | ||
11591 | err = 0; | 11583 | err = 0; |
11592 | 11584 | ||
11593 | /* tg3_free_rings will unmap and free the rx_skb */ | 11585 | /* tg3_free_rings will unmap and free the rx_data */ |
11594 | out: | 11586 | out: |
11595 | return err; | 11587 | return err; |
11596 | } | 11588 | } |
@@ -13218,8 +13210,7 @@ static u32 __devinit tg3_read_otp_phycfg(struct tg3 *tp) | |||
13218 | 13210 | ||
13219 | static void __devinit tg3_phy_init_link_config(struct tg3 *tp) | 13211 | static void __devinit tg3_phy_init_link_config(struct tg3 *tp) |
13220 | { | 13212 | { |
13221 | u32 adv = ADVERTISED_Autoneg | | 13213 | u32 adv = ADVERTISED_Autoneg; |
13222 | ADVERTISED_Pause; | ||
13223 | 13214 | ||
13224 | if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) | 13215 | if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) |
13225 | adv |= ADVERTISED_1000baseT_Half | | 13216 | adv |= ADVERTISED_1000baseT_Half | |
@@ -14036,7 +14027,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
14036 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) | 14027 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) |
14037 | tg3_flag_set(tp, 4K_FIFO_LIMIT); | 14028 | tg3_flag_set(tp, 4K_FIFO_LIMIT); |
14038 | 14029 | ||
14039 | if (tg3_flag(tp, 5717_PLUS)) | 14030 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || |
14031 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || | ||
14032 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) | ||
14040 | tg3_flag_set(tp, LRG_PROD_RING_CAP); | 14033 | tg3_flag_set(tp, LRG_PROD_RING_CAP); |
14041 | 14034 | ||
14042 | if (tg3_flag(tp, 57765_PLUS) && | 14035 | if (tg3_flag(tp, 57765_PLUS) && |
@@ -14548,11 +14541,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
14548 | else | 14541 | else |
14549 | tg3_flag_clear(tp, POLL_SERDES); | 14542 | tg3_flag_clear(tp, POLL_SERDES); |
14550 | 14543 | ||
14551 | tp->rx_offset = NET_IP_ALIGN; | 14544 | tp->rx_offset = NET_SKB_PAD + NET_IP_ALIGN; |
14552 | tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD; | 14545 | tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD; |
14553 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && | 14546 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && |
14554 | tg3_flag(tp, PCIX_MODE)) { | 14547 | tg3_flag(tp, PCIX_MODE)) { |
14555 | tp->rx_offset = 0; | 14548 | tp->rx_offset = NET_SKB_PAD; |
14556 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | 14549 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS |
14557 | tp->rx_copy_thresh = ~(u16)0; | 14550 | tp->rx_copy_thresh = ~(u16)0; |
14558 | #endif | 14551 | #endif |
@@ -15313,7 +15306,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
15313 | u32 sndmbx, rcvmbx, intmbx; | 15306 | u32 sndmbx, rcvmbx, intmbx; |
15314 | char str[40]; | 15307 | char str[40]; |
15315 | u64 dma_mask, persist_dma_mask; | 15308 | u64 dma_mask, persist_dma_mask; |
15316 | u32 features = 0; | 15309 | netdev_features_t features = 0; |
15317 | 15310 | ||
15318 | printk_once(KERN_INFO "%s\n", version); | 15311 | printk_once(KERN_INFO "%s\n", version); |
15319 | 15312 | ||
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 94b4bd049a33..9cc10a868dcd 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
@@ -2174,6 +2174,7 @@ | |||
2174 | #define MII_TG3_EXT_CTRL_TBI 0x8000 | 2174 | #define MII_TG3_EXT_CTRL_TBI 0x8000 |
2175 | 2175 | ||
2176 | #define MII_TG3_EXT_STAT 0x11 /* Extended status register */ | 2176 | #define MII_TG3_EXT_STAT 0x11 /* Extended status register */ |
2177 | #define MII_TG3_EXT_STAT_MDIX 0x2000 | ||
2177 | #define MII_TG3_EXT_STAT_LPASS 0x0100 | 2178 | #define MII_TG3_EXT_STAT_LPASS 0x0100 |
2178 | 2179 | ||
2179 | #define MII_TG3_RXR_COUNTERS 0x14 /* Local/Remote Receiver Counts */ | 2180 | #define MII_TG3_RXR_COUNTERS 0x14 /* Local/Remote Receiver Counts */ |
@@ -2277,6 +2278,9 @@ | |||
2277 | #define MII_TG3_FET_PTEST_FRC_TX_LINK 0x1000 | 2278 | #define MII_TG3_FET_PTEST_FRC_TX_LINK 0x1000 |
2278 | #define MII_TG3_FET_PTEST_FRC_TX_LOCK 0x0800 | 2279 | #define MII_TG3_FET_PTEST_FRC_TX_LOCK 0x0800 |
2279 | 2280 | ||
2281 | #define MII_TG3_FET_GEN_STAT 0x1c | ||
2282 | #define MII_TG3_FET_GEN_STAT_MDIXSTAT 0x2000 | ||
2283 | |||
2280 | #define MII_TG3_FET_TEST 0x1f | 2284 | #define MII_TG3_FET_TEST 0x1f |
2281 | #define MII_TG3_FET_SHADOW_EN 0x0080 | 2285 | #define MII_TG3_FET_SHADOW_EN 0x0080 |
2282 | 2286 | ||
@@ -2662,9 +2666,13 @@ struct tg3_hw_stats { | |||
2662 | /* 'mapping' is superfluous as the chip does not write into | 2666 | /* 'mapping' is superfluous as the chip does not write into |
2663 | * the tx/rx post rings so we could just fetch it from there. | 2667 | * the tx/rx post rings so we could just fetch it from there. |
2664 | * But the cache behavior is better how we are doing it now. | 2668 | * But the cache behavior is better how we are doing it now. |
2669 | * | ||
2670 | * This driver uses new build_skb() API : | ||
2671 | * RX ring buffer contains pointer to kmalloc() data only, | ||
2672 | * skb are built only after Hardware filled the frame. | ||
2665 | */ | 2673 | */ |
2666 | struct ring_info { | 2674 | struct ring_info { |
2667 | struct sk_buff *skb; | 2675 | u8 *data; |
2668 | DEFINE_DMA_UNMAP_ADDR(mapping); | 2676 | DEFINE_DMA_UNMAP_ADDR(mapping); |
2669 | }; | 2677 | }; |
2670 | 2678 | ||
@@ -3131,6 +3139,7 @@ struct tg3 { | |||
3131 | #define TG3_PHYFLG_SERDES_PREEMPHASIS 0x00010000 | 3139 | #define TG3_PHYFLG_SERDES_PREEMPHASIS 0x00010000 |
3132 | #define TG3_PHYFLG_PARALLEL_DETECT 0x00020000 | 3140 | #define TG3_PHYFLG_PARALLEL_DETECT 0x00020000 |
3133 | #define TG3_PHYFLG_EEE_CAP 0x00040000 | 3141 | #define TG3_PHYFLG_EEE_CAP 0x00040000 |
3142 | #define TG3_PHYFLG_MDIX_STATE 0x00200000 | ||
3134 | 3143 | ||
3135 | u32 led_ctrl; | 3144 | u32 led_ctrl; |
3136 | u32 phy_otp; | 3145 | u32 phy_otp; |
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c index fd3dcc1e9145..38d5c66075f9 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c +++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c | |||
@@ -296,8 +296,8 @@ bnad_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) | |||
296 | struct bfa_ioc_attr *ioc_attr; | 296 | struct bfa_ioc_attr *ioc_attr; |
297 | unsigned long flags; | 297 | unsigned long flags; |
298 | 298 | ||
299 | strcpy(drvinfo->driver, BNAD_NAME); | 299 | strlcpy(drvinfo->driver, BNAD_NAME, sizeof(drvinfo->driver)); |
300 | strcpy(drvinfo->version, BNAD_VERSION); | 300 | strlcpy(drvinfo->version, BNAD_VERSION, sizeof(drvinfo->version)); |
301 | 301 | ||
302 | ioc_attr = kzalloc(sizeof(*ioc_attr), GFP_KERNEL); | 302 | ioc_attr = kzalloc(sizeof(*ioc_attr), GFP_KERNEL); |
303 | if (ioc_attr) { | 303 | if (ioc_attr) { |
@@ -305,12 +305,13 @@ bnad_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) | |||
305 | bfa_nw_ioc_get_attr(&bnad->bna.ioceth.ioc, ioc_attr); | 305 | bfa_nw_ioc_get_attr(&bnad->bna.ioceth.ioc, ioc_attr); |
306 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | 306 | spin_unlock_irqrestore(&bnad->bna_lock, flags); |
307 | 307 | ||
308 | strncpy(drvinfo->fw_version, ioc_attr->adapter_attr.fw_ver, | 308 | strlcpy(drvinfo->fw_version, ioc_attr->adapter_attr.fw_ver, |
309 | sizeof(drvinfo->fw_version) - 1); | 309 | sizeof(drvinfo->fw_version)); |
310 | kfree(ioc_attr); | 310 | kfree(ioc_attr); |
311 | } | 311 | } |
312 | 312 | ||
313 | strncpy(drvinfo->bus_info, pci_name(bnad->pcidev), ETHTOOL_BUSINFO_LEN); | 313 | strlcpy(drvinfo->bus_info, pci_name(bnad->pcidev), |
314 | sizeof(drvinfo->bus_info)); | ||
314 | } | 315 | } |
315 | 316 | ||
316 | static void | 317 | static void |
diff --git a/drivers/net/ethernet/brocade/bna/cna.h b/drivers/net/ethernet/brocade/bna/cna.h index 1b3e90dfbd9a..32e8f178ab76 100644 --- a/drivers/net/ethernet/brocade/bna/cna.h +++ b/drivers/net/ethernet/brocade/bna/cna.h | |||
@@ -43,8 +43,7 @@ extern char bfa_version[]; | |||
43 | 43 | ||
44 | #pragma pack(1) | 44 | #pragma pack(1) |
45 | 45 | ||
46 | #define MAC_ADDRLEN (6) | 46 | typedef struct mac { u8 mac[ETH_ALEN]; } mac_t; |
47 | typedef struct mac { u8 mac[MAC_ADDRLEN]; } mac_t; | ||
48 | 47 | ||
49 | #pragma pack() | 48 | #pragma pack() |
50 | 49 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c index ca26d97171bd..1d17c92f2dda 100644 --- a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c +++ b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c | |||
@@ -434,10 +434,10 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
434 | { | 434 | { |
435 | struct adapter *adapter = dev->ml_priv; | 435 | struct adapter *adapter = dev->ml_priv; |
436 | 436 | ||
437 | strcpy(info->driver, DRV_NAME); | 437 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
438 | strcpy(info->version, DRV_VERSION); | 438 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
439 | strcpy(info->fw_version, "N/A"); | 439 | strlcpy(info->bus_info, pci_name(adapter->pdev), |
440 | strcpy(info->bus_info, pci_name(adapter->pdev)); | 440 | sizeof(info->bus_info)); |
441 | } | 441 | } |
442 | 442 | ||
443 | static int get_sset_count(struct net_device *dev, int sset) | 443 | static int get_sset_count(struct net_device *dev, int sset) |
@@ -849,7 +849,8 @@ static int t1_set_mac_addr(struct net_device *dev, void *p) | |||
849 | return 0; | 849 | return 0; |
850 | } | 850 | } |
851 | 851 | ||
852 | static u32 t1_fix_features(struct net_device *dev, u32 features) | 852 | static netdev_features_t t1_fix_features(struct net_device *dev, |
853 | netdev_features_t features) | ||
853 | { | 854 | { |
854 | /* | 855 | /* |
855 | * Since there is no support for separate rx/tx vlan accel | 856 | * Since there is no support for separate rx/tx vlan accel |
@@ -863,9 +864,9 @@ static u32 t1_fix_features(struct net_device *dev, u32 features) | |||
863 | return features; | 864 | return features; |
864 | } | 865 | } |
865 | 866 | ||
866 | static int t1_set_features(struct net_device *dev, u32 features) | 867 | static int t1_set_features(struct net_device *dev, netdev_features_t features) |
867 | { | 868 | { |
868 | u32 changed = dev->features ^ features; | 869 | netdev_features_t changed = dev->features ^ features; |
869 | struct adapter *adapter = dev->ml_priv; | 870 | struct adapter *adapter = dev->ml_priv; |
870 | 871 | ||
871 | if (changed & NETIF_F_HW_VLAN_RX) | 872 | if (changed & NETIF_F_HW_VLAN_RX) |
diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/cxgb/sge.c index f9b602300040..47a84359d4e4 100644 --- a/drivers/net/ethernet/chelsio/cxgb/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb/sge.c | |||
@@ -742,7 +742,7 @@ static inline void setup_ring_params(struct adapter *adapter, u64 addr, | |||
742 | /* | 742 | /* |
743 | * Enable/disable VLAN acceleration. | 743 | * Enable/disable VLAN acceleration. |
744 | */ | 744 | */ |
745 | void t1_vlan_mode(struct adapter *adapter, u32 features) | 745 | void t1_vlan_mode(struct adapter *adapter, netdev_features_t features) |
746 | { | 746 | { |
747 | struct sge *sge = adapter->sge; | 747 | struct sge *sge = adapter->sge; |
748 | 748 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.h b/drivers/net/ethernet/chelsio/cxgb/sge.h index e03980bcdd65..b9bf16b385f7 100644 --- a/drivers/net/ethernet/chelsio/cxgb/sge.h +++ b/drivers/net/ethernet/chelsio/cxgb/sge.h | |||
@@ -79,7 +79,7 @@ irqreturn_t t1_interrupt(int irq, void *cookie); | |||
79 | int t1_poll(struct napi_struct *, int); | 79 | int t1_poll(struct napi_struct *, int); |
80 | 80 | ||
81 | netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev); | 81 | netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev); |
82 | void t1_vlan_mode(struct adapter *adapter, u32 features); | 82 | void t1_vlan_mode(struct adapter *adapter, netdev_features_t features); |
83 | void t1_sge_start(struct sge *); | 83 | void t1_sge_start(struct sge *); |
84 | void t1_sge_stop(struct sge *); | 84 | void t1_sge_stop(struct sge *); |
85 | int t1_sge_intr_error_handler(struct sge *); | 85 | int t1_sge_intr_error_handler(struct sge *); |
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index 4d15c8f99c3b..857cc254cab8 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | |||
@@ -1576,12 +1576,11 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
1576 | t3_get_tp_version(adapter, &tp_vers); | 1576 | t3_get_tp_version(adapter, &tp_vers); |
1577 | spin_unlock(&adapter->stats_lock); | 1577 | spin_unlock(&adapter->stats_lock); |
1578 | 1578 | ||
1579 | strcpy(info->driver, DRV_NAME); | 1579 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1580 | strcpy(info->version, DRV_VERSION); | 1580 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1581 | strcpy(info->bus_info, pci_name(adapter->pdev)); | 1581 | strlcpy(info->bus_info, pci_name(adapter->pdev), |
1582 | if (!fw_vers) | 1582 | sizeof(info->bus_info)); |
1583 | strcpy(info->fw_version, "N/A"); | 1583 | if (fw_vers) |
1584 | else { | ||
1585 | snprintf(info->fw_version, sizeof(info->fw_version), | 1584 | snprintf(info->fw_version, sizeof(info->fw_version), |
1586 | "%s %u.%u.%u TP %u.%u.%u", | 1585 | "%s %u.%u.%u TP %u.%u.%u", |
1587 | G_FW_VERSION_TYPE(fw_vers) ? "T" : "N", | 1586 | G_FW_VERSION_TYPE(fw_vers) ? "T" : "N", |
@@ -1591,7 +1590,6 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
1591 | G_TP_VERSION_MAJOR(tp_vers), | 1590 | G_TP_VERSION_MAJOR(tp_vers), |
1592 | G_TP_VERSION_MINOR(tp_vers), | 1591 | G_TP_VERSION_MINOR(tp_vers), |
1593 | G_TP_VERSION_MICRO(tp_vers)); | 1592 | G_TP_VERSION_MICRO(tp_vers)); |
1594 | } | ||
1595 | } | 1593 | } |
1596 | 1594 | ||
1597 | static void get_strings(struct net_device *dev, u32 stringset, u8 * data) | 1595 | static void get_strings(struct net_device *dev, u32 stringset, u8 * data) |
@@ -2531,7 +2529,7 @@ static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) | |||
2531 | } | 2529 | } |
2532 | } | 2530 | } |
2533 | 2531 | ||
2534 | static void cxgb_vlan_mode(struct net_device *dev, u32 features) | 2532 | static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features) |
2535 | { | 2533 | { |
2536 | struct port_info *pi = netdev_priv(dev); | 2534 | struct port_info *pi = netdev_priv(dev); |
2537 | struct adapter *adapter = pi->adapter; | 2535 | struct adapter *adapter = pi->adapter; |
@@ -2552,7 +2550,8 @@ static void cxgb_vlan_mode(struct net_device *dev, u32 features) | |||
2552 | t3_synchronize_rx(adapter, pi); | 2550 | t3_synchronize_rx(adapter, pi); |
2553 | } | 2551 | } |
2554 | 2552 | ||
2555 | static u32 cxgb_fix_features(struct net_device *dev, u32 features) | 2553 | static netdev_features_t cxgb_fix_features(struct net_device *dev, |
2554 | netdev_features_t features) | ||
2556 | { | 2555 | { |
2557 | /* | 2556 | /* |
2558 | * Since there is no support for separate rx/tx vlan accel | 2557 | * Since there is no support for separate rx/tx vlan accel |
@@ -2566,9 +2565,9 @@ static u32 cxgb_fix_features(struct net_device *dev, u32 features) | |||
2566 | return features; | 2565 | return features; |
2567 | } | 2566 | } |
2568 | 2567 | ||
2569 | static int cxgb_set_features(struct net_device *dev, u32 features) | 2568 | static int cxgb_set_features(struct net_device *dev, netdev_features_t features) |
2570 | { | 2569 | { |
2571 | u32 changed = dev->features ^ features; | 2570 | netdev_features_t changed = dev->features ^ features; |
2572 | 2571 | ||
2573 | if (changed & NETIF_F_HW_VLAN_RX) | 2572 | if (changed & NETIF_F_HW_VLAN_RX) |
2574 | cxgb_vlan_mode(dev, features); | 2573 | cxgb_vlan_mode(dev, features); |
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c index 90ff1318cc05..7f7882d24bc6 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | |||
@@ -1301,7 +1301,7 @@ int cxgb3_offload_activate(struct adapter *adapter) | |||
1301 | 1301 | ||
1302 | out_free_l2t: | 1302 | out_free_l2t: |
1303 | t3_free_l2t(L2DATA(dev)); | 1303 | t3_free_l2t(L2DATA(dev)); |
1304 | rcu_assign_pointer(dev->l2opt, NULL); | 1304 | RCU_INIT_POINTER(dev->l2opt, NULL); |
1305 | out_free: | 1305 | out_free: |
1306 | kfree(t); | 1306 | kfree(t); |
1307 | return err; | 1307 | return err; |
@@ -1329,7 +1329,7 @@ void cxgb3_offload_deactivate(struct adapter *adapter) | |||
1329 | rcu_read_lock(); | 1329 | rcu_read_lock(); |
1330 | d = L2DATA(tdev); | 1330 | d = L2DATA(tdev); |
1331 | rcu_read_unlock(); | 1331 | rcu_read_unlock(); |
1332 | rcu_assign_pointer(tdev->l2opt, NULL); | 1332 | RCU_INIT_POINTER(tdev->l2opt, NULL); |
1333 | call_rcu(&d->rcu_head, clean_l2_data); | 1333 | call_rcu(&d->rcu_head, clean_l2_data); |
1334 | if (t->nofail_skb) | 1334 | if (t->nofail_skb) |
1335 | kfree_skb(t->nofail_skb); | 1335 | kfree_skb(t->nofail_skb); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 4c8f42afa3c6..a34e7ce7e214 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -1002,13 +1002,12 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
1002 | { | 1002 | { |
1003 | struct adapter *adapter = netdev2adap(dev); | 1003 | struct adapter *adapter = netdev2adap(dev); |
1004 | 1004 | ||
1005 | strcpy(info->driver, KBUILD_MODNAME); | 1005 | strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); |
1006 | strcpy(info->version, DRV_VERSION); | 1006 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1007 | strcpy(info->bus_info, pci_name(adapter->pdev)); | 1007 | strlcpy(info->bus_info, pci_name(adapter->pdev), |
1008 | sizeof(info->bus_info)); | ||
1008 | 1009 | ||
1009 | if (!adapter->params.fw_vers) | 1010 | if (adapter->params.fw_vers) |
1010 | strcpy(info->fw_version, "N/A"); | ||
1011 | else | ||
1012 | snprintf(info->fw_version, sizeof(info->fw_version), | 1011 | snprintf(info->fw_version, sizeof(info->fw_version), |
1013 | "%u.%u.%u.%u, TP %u.%u.%u.%u", | 1012 | "%u.%u.%u.%u, TP %u.%u.%u.%u", |
1014 | FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers), | 1013 | FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers), |
@@ -1855,10 +1854,10 @@ static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
1855 | return err; | 1854 | return err; |
1856 | } | 1855 | } |
1857 | 1856 | ||
1858 | static int cxgb_set_features(struct net_device *dev, u32 features) | 1857 | static int cxgb_set_features(struct net_device *dev, netdev_features_t features) |
1859 | { | 1858 | { |
1860 | const struct port_info *pi = netdev_priv(dev); | 1859 | const struct port_info *pi = netdev_priv(dev); |
1861 | u32 changed = dev->features ^ features; | 1860 | netdev_features_t changed = dev->features ^ features; |
1862 | int err; | 1861 | int err; |
1863 | 1862 | ||
1864 | if (!(changed & NETIF_F_HW_VLAN_RX)) | 1863 | if (!(changed & NETIF_F_HW_VLAN_RX)) |
@@ -3537,7 +3536,7 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3537 | { | 3536 | { |
3538 | int func, i, err; | 3537 | int func, i, err; |
3539 | struct port_info *pi; | 3538 | struct port_info *pi; |
3540 | unsigned int highdma = 0; | 3539 | bool highdma = false; |
3541 | struct adapter *adapter = NULL; | 3540 | struct adapter *adapter = NULL; |
3542 | 3541 | ||
3543 | printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION); | 3542 | printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION); |
@@ -3563,7 +3562,7 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3563 | } | 3562 | } |
3564 | 3563 | ||
3565 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { | 3564 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { |
3566 | highdma = NETIF_F_HIGHDMA; | 3565 | highdma = true; |
3567 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); | 3566 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); |
3568 | if (err) { | 3567 | if (err) { |
3569 | dev_err(&pdev->dev, "unable to obtain 64-bit DMA for " | 3568 | dev_err(&pdev->dev, "unable to obtain 64-bit DMA for " |
@@ -3637,7 +3636,9 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3637 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 3636 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
3638 | NETIF_F_RXCSUM | NETIF_F_RXHASH | | 3637 | NETIF_F_RXCSUM | NETIF_F_RXHASH | |
3639 | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 3638 | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
3640 | netdev->features |= netdev->hw_features | highdma; | 3639 | if (highdma) |
3640 | netdev->hw_features |= NETIF_F_HIGHDMA; | ||
3641 | netdev->features |= netdev->hw_features; | ||
3641 | netdev->vlan_features = netdev->features & VLAN_FEAT; | 3642 | netdev->vlan_features = netdev->features & VLAN_FEAT; |
3642 | 3643 | ||
3643 | netdev->priv_flags |= IFF_UNICAST_FLT; | 3644 | netdev->priv_flags |= IFF_UNICAST_FLT; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 140254c7cba9..2dae7959f000 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c | |||
@@ -491,7 +491,7 @@ static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n, | |||
491 | __be64 *d = &q->desc[q->pidx]; | 491 | __be64 *d = &q->desc[q->pidx]; |
492 | struct rx_sw_desc *sd = &q->sdesc[q->pidx]; | 492 | struct rx_sw_desc *sd = &q->sdesc[q->pidx]; |
493 | 493 | ||
494 | gfp |= __GFP_NOWARN; /* failures are expected */ | 494 | gfp |= __GFP_NOWARN | __GFP_COLD; |
495 | 495 | ||
496 | #if FL_PG_ORDER > 0 | 496 | #if FL_PG_ORDER > 0 |
497 | /* | 497 | /* |
@@ -528,7 +528,7 @@ static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n, | |||
528 | #endif | 528 | #endif |
529 | 529 | ||
530 | while (n--) { | 530 | while (n--) { |
531 | pg = __netdev_alloc_page(adap->port[0], gfp); | 531 | pg = alloc_page(gfp); |
532 | if (unlikely(!pg)) { | 532 | if (unlikely(!pg)) { |
533 | q->alloc_failed++; | 533 | q->alloc_failed++; |
534 | break; | 534 | break; |
@@ -537,7 +537,7 @@ static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n, | |||
537 | mapping = dma_map_page(adap->pdev_dev, pg, 0, PAGE_SIZE, | 537 | mapping = dma_map_page(adap->pdev_dev, pg, 0, PAGE_SIZE, |
538 | PCI_DMA_FROMDEVICE); | 538 | PCI_DMA_FROMDEVICE); |
539 | if (unlikely(dma_mapping_error(adap->pdev_dev, mapping))) { | 539 | if (unlikely(dma_mapping_error(adap->pdev_dev, mapping))) { |
540 | netdev_free_page(adap->port[0], pg); | 540 | put_page(pg); |
541 | goto out; | 541 | goto out; |
542 | } | 542 | } |
543 | *d++ = cpu_to_be64(mapping); | 543 | *d++ = cpu_to_be64(mapping); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index da9072bfca8b..8155cfecae19 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | |||
@@ -1092,7 +1092,8 @@ static int cxgb4vf_change_mtu(struct net_device *dev, int new_mtu) | |||
1092 | return ret; | 1092 | return ret; |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | static u32 cxgb4vf_fix_features(struct net_device *dev, u32 features) | 1095 | static netdev_features_t cxgb4vf_fix_features(struct net_device *dev, |
1096 | netdev_features_t features) | ||
1096 | { | 1097 | { |
1097 | /* | 1098 | /* |
1098 | * Since there is no support for separate rx/tx vlan accel | 1099 | * Since there is no support for separate rx/tx vlan accel |
@@ -1106,10 +1107,11 @@ static u32 cxgb4vf_fix_features(struct net_device *dev, u32 features) | |||
1106 | return features; | 1107 | return features; |
1107 | } | 1108 | } |
1108 | 1109 | ||
1109 | static int cxgb4vf_set_features(struct net_device *dev, u32 features) | 1110 | static int cxgb4vf_set_features(struct net_device *dev, |
1111 | netdev_features_t features) | ||
1110 | { | 1112 | { |
1111 | struct port_info *pi = netdev_priv(dev); | 1113 | struct port_info *pi = netdev_priv(dev); |
1112 | u32 changed = dev->features ^ features; | 1114 | netdev_features_t changed = dev->features ^ features; |
1113 | 1115 | ||
1114 | if (changed & NETIF_F_HW_VLAN_RX) | 1116 | if (changed & NETIF_F_HW_VLAN_RX) |
1115 | t4vf_set_rxmode(pi->adapter, pi->viid, -1, -1, -1, -1, | 1117 | t4vf_set_rxmode(pi->adapter, pi->viid, -1, -1, -1, -1, |
@@ -1203,9 +1205,10 @@ static void cxgb4vf_get_drvinfo(struct net_device *dev, | |||
1203 | { | 1205 | { |
1204 | struct adapter *adapter = netdev2adap(dev); | 1206 | struct adapter *adapter = netdev2adap(dev); |
1205 | 1207 | ||
1206 | strcpy(drvinfo->driver, KBUILD_MODNAME); | 1208 | strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); |
1207 | strcpy(drvinfo->version, DRV_VERSION); | 1209 | strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); |
1208 | strcpy(drvinfo->bus_info, pci_name(to_pci_dev(dev->dev.parent))); | 1210 | strlcpy(drvinfo->bus_info, pci_name(to_pci_dev(dev->dev.parent)), |
1211 | sizeof(drvinfo->bus_info)); | ||
1209 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), | 1212 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), |
1210 | "%u.%u.%u.%u, TP %u.%u.%u.%u", | 1213 | "%u.%u.%u.%u, TP %u.%u.%u.%u", |
1211 | FW_HDR_FW_VER_MAJOR_GET(adapter->params.dev.fwrev), | 1214 | FW_HDR_FW_VER_MAJOR_GET(adapter->params.dev.fwrev), |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index 8d5d55ad102d..c381db23e713 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c | |||
@@ -653,8 +653,7 @@ static unsigned int refill_fl(struct adapter *adapter, struct sge_fl *fl, | |||
653 | 653 | ||
654 | alloc_small_pages: | 654 | alloc_small_pages: |
655 | while (n--) { | 655 | while (n--) { |
656 | page = __netdev_alloc_page(adapter->port[0], | 656 | page = alloc_page(gfp | __GFP_NOWARN | __GFP_COLD); |
657 | gfp | __GFP_NOWARN); | ||
658 | if (unlikely(!page)) { | 657 | if (unlikely(!page)) { |
659 | fl->alloc_failed++; | 658 | fl->alloc_failed++; |
660 | break; | 659 | break; |
@@ -664,7 +663,7 @@ alloc_small_pages: | |||
664 | dma_addr = dma_map_page(adapter->pdev_dev, page, 0, PAGE_SIZE, | 663 | dma_addr = dma_map_page(adapter->pdev_dev, page, 0, PAGE_SIZE, |
665 | PCI_DMA_FROMDEVICE); | 664 | PCI_DMA_FROMDEVICE); |
666 | if (unlikely(dma_mapping_error(adapter->pdev_dev, dma_addr))) { | 665 | if (unlikely(dma_mapping_error(adapter->pdev_dev, dma_addr))) { |
667 | netdev_free_page(adapter->port[0], page); | 666 | put_page(page); |
668 | break; | 667 | break; |
669 | } | 668 | } |
670 | *d++ = cpu_to_be64(dma_addr); | 669 | *d++ = cpu_to_be64(dma_addr); |
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index c3786fda11db..1fe5df0284a6 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c | |||
@@ -217,11 +217,11 @@ static void enic_get_drvinfo(struct net_device *netdev, | |||
217 | 217 | ||
218 | enic_dev_fw_info(enic, &fw_info); | 218 | enic_dev_fw_info(enic, &fw_info); |
219 | 219 | ||
220 | strncpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); | 220 | strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); |
221 | strncpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); | 221 | strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); |
222 | strncpy(drvinfo->fw_version, fw_info->fw_version, | 222 | strlcpy(drvinfo->fw_version, fw_info->fw_version, |
223 | sizeof(drvinfo->fw_version)); | 223 | sizeof(drvinfo->fw_version)); |
224 | strncpy(drvinfo->bus_info, pci_name(enic->pdev), | 224 | strlcpy(drvinfo->bus_info, pci_name(enic->pdev), |
225 | sizeof(drvinfo->bus_info)); | 225 | sizeof(drvinfo->bus_info)); |
226 | } | 226 | } |
227 | 227 | ||
diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c index 438f4580bf66..26be1dfc1577 100644 --- a/drivers/net/ethernet/davicom/dm9000.c +++ b/drivers/net/ethernet/davicom/dm9000.c | |||
@@ -474,10 +474,11 @@ static int dm9000_nway_reset(struct net_device *dev) | |||
474 | return mii_nway_restart(&dm->mii); | 474 | return mii_nway_restart(&dm->mii); |
475 | } | 475 | } |
476 | 476 | ||
477 | static int dm9000_set_features(struct net_device *dev, u32 features) | 477 | static int dm9000_set_features(struct net_device *dev, |
478 | netdev_features_t features) | ||
478 | { | 479 | { |
479 | board_info_t *dm = to_dm9000_board(dev); | 480 | board_info_t *dm = to_dm9000_board(dev); |
480 | u32 changed = dev->features ^ features; | 481 | netdev_features_t changed = dev->features ^ features; |
481 | unsigned long flags; | 482 | unsigned long flags; |
482 | 483 | ||
483 | if (!(changed & NETIF_F_RXCSUM)) | 484 | if (!(changed & NETIF_F_RXCSUM)) |
diff --git a/drivers/net/ethernet/dec/tulip/de2104x.c b/drivers/net/ethernet/dec/tulip/de2104x.c index 1427739d9a51..1eb46a0bb488 100644 --- a/drivers/net/ethernet/dec/tulip/de2104x.c +++ b/drivers/net/ethernet/dec/tulip/de2104x.c | |||
@@ -1598,9 +1598,9 @@ static void de_get_drvinfo (struct net_device *dev,struct ethtool_drvinfo *info) | |||
1598 | { | 1598 | { |
1599 | struct de_private *de = netdev_priv(dev); | 1599 | struct de_private *de = netdev_priv(dev); |
1600 | 1600 | ||
1601 | strcpy (info->driver, DRV_NAME); | 1601 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1602 | strcpy (info->version, DRV_VERSION); | 1602 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1603 | strcpy (info->bus_info, pci_name(de->pdev)); | 1603 | strlcpy(info->bus_info, pci_name(de->pdev), sizeof(info->bus_info)); |
1604 | info->eedump_len = DE_EEPROM_SIZE; | 1604 | info->eedump_len = DE_EEPROM_SIZE; |
1605 | } | 1605 | } |
1606 | 1606 | ||
diff --git a/drivers/net/ethernet/dec/tulip/dmfe.c b/drivers/net/ethernet/dec/tulip/dmfe.c index 17b11ee1745a..51f7542eb451 100644 --- a/drivers/net/ethernet/dec/tulip/dmfe.c +++ b/drivers/net/ethernet/dec/tulip/dmfe.c | |||
@@ -1085,10 +1085,11 @@ static void dmfe_ethtool_get_drvinfo(struct net_device *dev, | |||
1085 | { | 1085 | { |
1086 | struct dmfe_board_info *np = netdev_priv(dev); | 1086 | struct dmfe_board_info *np = netdev_priv(dev); |
1087 | 1087 | ||
1088 | strcpy(info->driver, DRV_NAME); | 1088 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1089 | strcpy(info->version, DRV_VERSION); | 1089 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1090 | if (np->pdev) | 1090 | if (np->pdev) |
1091 | strcpy(info->bus_info, pci_name(np->pdev)); | 1091 | strlcpy(info->bus_info, pci_name(np->pdev), |
1092 | sizeof(info->bus_info)); | ||
1092 | else | 1093 | else |
1093 | sprintf(info->bus_info, "EISA 0x%lx %d", | 1094 | sprintf(info->bus_info, "EISA 0x%lx %d", |
1094 | dev->base_addr, dev->irq); | 1095 | dev->base_addr, dev->irq); |
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c index 9656dd0647d9..4eb0d76145c2 100644 --- a/drivers/net/ethernet/dec/tulip/tulip_core.c +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c | |||
@@ -871,9 +871,9 @@ static struct net_device_stats *tulip_get_stats(struct net_device *dev) | |||
871 | static void tulip_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 871 | static void tulip_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
872 | { | 872 | { |
873 | struct tulip_private *np = netdev_priv(dev); | 873 | struct tulip_private *np = netdev_priv(dev); |
874 | strcpy(info->driver, DRV_NAME); | 874 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
875 | strcpy(info->version, DRV_VERSION); | 875 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
876 | strcpy(info->bus_info, pci_name(np->pdev)); | 876 | strlcpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info)); |
877 | } | 877 | } |
878 | 878 | ||
879 | 879 | ||
diff --git a/drivers/net/ethernet/dec/tulip/uli526x.c b/drivers/net/ethernet/dec/tulip/uli526x.c index 7a44a7a6adc8..48b0b6566eef 100644 --- a/drivers/net/ethernet/dec/tulip/uli526x.c +++ b/drivers/net/ethernet/dec/tulip/uli526x.c | |||
@@ -960,10 +960,11 @@ static void netdev_get_drvinfo(struct net_device *dev, | |||
960 | { | 960 | { |
961 | struct uli526x_board_info *np = netdev_priv(dev); | 961 | struct uli526x_board_info *np = netdev_priv(dev); |
962 | 962 | ||
963 | strcpy(info->driver, DRV_NAME); | 963 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
964 | strcpy(info->version, DRV_VERSION); | 964 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
965 | if (np->pdev) | 965 | if (np->pdev) |
966 | strcpy(info->bus_info, pci_name(np->pdev)); | 966 | strlcpy(info->bus_info, pci_name(np->pdev), |
967 | sizeof(info->bus_info)); | ||
967 | else | 968 | else |
968 | sprintf(info->bus_info, "EISA 0x%lx %d", | 969 | sprintf(info->bus_info, "EISA 0x%lx %d", |
969 | dev->base_addr, dev->irq); | 970 | dev->base_addr, dev->irq); |
diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c index 4d01219ba22f..52da7b2fe3b6 100644 --- a/drivers/net/ethernet/dec/tulip/winbond-840.c +++ b/drivers/net/ethernet/dec/tulip/winbond-840.c | |||
@@ -1390,9 +1390,9 @@ static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo * | |||
1390 | { | 1390 | { |
1391 | struct netdev_private *np = netdev_priv(dev); | 1391 | struct netdev_private *np = netdev_priv(dev); |
1392 | 1392 | ||
1393 | strcpy (info->driver, DRV_NAME); | 1393 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1394 | strcpy (info->version, DRV_VERSION); | 1394 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1395 | strcpy (info->bus_info, pci_name(np->pci_dev)); | 1395 | strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); |
1396 | } | 1396 | } |
1397 | 1397 | ||
1398 | static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 1398 | static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c index dcd7f7a71ad4..28a3a9b50b8b 100644 --- a/drivers/net/ethernet/dlink/sundance.c +++ b/drivers/net/ethernet/dlink/sundance.c | |||
@@ -1634,9 +1634,9 @@ static int check_if_running(struct net_device *dev) | |||
1634 | static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 1634 | static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
1635 | { | 1635 | { |
1636 | struct netdev_private *np = netdev_priv(dev); | 1636 | struct netdev_private *np = netdev_priv(dev); |
1637 | strcpy(info->driver, DRV_NAME); | 1637 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1638 | strcpy(info->version, DRV_VERSION); | 1638 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1639 | strcpy(info->bus_info, pci_name(np->pci_dev)); | 1639 | strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); |
1640 | } | 1640 | } |
1641 | 1641 | ||
1642 | static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | 1642 | static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) |
diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c index c1063d1540c2..d94b9686b80c 100644 --- a/drivers/net/ethernet/dnet.c +++ b/drivers/net/ethernet/dnet.c | |||
@@ -804,9 +804,9 @@ static int dnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
804 | static void dnet_get_drvinfo(struct net_device *dev, | 804 | static void dnet_get_drvinfo(struct net_device *dev, |
805 | struct ethtool_drvinfo *info) | 805 | struct ethtool_drvinfo *info) |
806 | { | 806 | { |
807 | strcpy(info->driver, DRV_NAME); | 807 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
808 | strcpy(info->version, DRV_VERSION); | 808 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
809 | strcpy(info->bus_info, "0"); | 809 | strlcpy(info->bus_info, "0", sizeof(info->bus_info)); |
810 | } | 810 | } |
811 | 811 | ||
812 | static const struct ethtool_ops dnet_ethtool_ops = { | 812 | static const struct ethtool_ops dnet_ethtool_ops = { |
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 644e8fed8364..34f162db9f2e 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -289,14 +289,12 @@ struct be_drv_stats { | |||
289 | 289 | ||
290 | struct be_vf_cfg { | 290 | struct be_vf_cfg { |
291 | unsigned char vf_mac_addr[ETH_ALEN]; | 291 | unsigned char vf_mac_addr[ETH_ALEN]; |
292 | u32 vf_if_handle; | 292 | int vf_if_handle; |
293 | u32 vf_pmac_id; | 293 | int vf_pmac_id; |
294 | u16 vf_vlan_tag; | 294 | u16 vf_vlan_tag; |
295 | u32 vf_tx_rate; | 295 | u32 vf_tx_rate; |
296 | }; | 296 | }; |
297 | 297 | ||
298 | #define BE_INVALID_PMAC_ID 0xffffffff | ||
299 | |||
300 | struct be_adapter { | 298 | struct be_adapter { |
301 | struct pci_dev *pdev; | 299 | struct pci_dev *pdev; |
302 | struct net_device *netdev; | 300 | struct net_device *netdev; |
@@ -347,11 +345,13 @@ struct be_adapter { | |||
347 | 345 | ||
348 | /* Ethtool knobs and info */ | 346 | /* Ethtool knobs and info */ |
349 | char fw_ver[FW_VER_LEN]; | 347 | char fw_ver[FW_VER_LEN]; |
350 | u32 if_handle; /* Used to configure filtering */ | 348 | int if_handle; /* Used to configure filtering */ |
351 | u32 pmac_id; /* MAC addr handle used by BE card */ | 349 | u32 pmac_id; /* MAC addr handle used by BE card */ |
352 | u32 beacon_state; /* for set_phys_id */ | 350 | u32 beacon_state; /* for set_phys_id */ |
353 | 351 | ||
354 | bool eeh_err; | 352 | bool eeh_err; |
353 | bool ue_detected; | ||
354 | bool fw_timeout; | ||
355 | u32 port_num; | 355 | u32 port_num; |
356 | bool promiscuous; | 356 | bool promiscuous; |
357 | bool wol; | 357 | bool wol; |
@@ -359,7 +359,6 @@ struct be_adapter { | |||
359 | u32 function_caps; | 359 | u32 function_caps; |
360 | u32 rx_fc; /* Rx flow control */ | 360 | u32 rx_fc; /* Rx flow control */ |
361 | u32 tx_fc; /* Tx flow control */ | 361 | u32 tx_fc; /* Tx flow control */ |
362 | bool ue_detected; | ||
363 | bool stats_cmd_sent; | 362 | bool stats_cmd_sent; |
364 | int link_speed; | 363 | int link_speed; |
365 | u8 port_type; | 364 | u8 port_type; |
@@ -524,6 +523,11 @@ static inline bool be_multi_rxq(const struct be_adapter *adapter) | |||
524 | return adapter->num_rx_qs > 1; | 523 | return adapter->num_rx_qs > 1; |
525 | } | 524 | } |
526 | 525 | ||
526 | static inline bool be_error(struct be_adapter *adapter) | ||
527 | { | ||
528 | return adapter->eeh_err || adapter->ue_detected || adapter->fw_timeout; | ||
529 | } | ||
530 | |||
527 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, | 531 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, |
528 | u16 num_popped); | 532 | u16 num_popped); |
529 | extern void be_link_status_update(struct be_adapter *adapter, u32 link_status); | 533 | extern void be_link_status_update(struct be_adapter *adapter, u32 link_status); |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 2c7b36673dfc..64f0c1aa1b09 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -31,11 +31,8 @@ static void be_mcc_notify(struct be_adapter *adapter) | |||
31 | struct be_queue_info *mccq = &adapter->mcc_obj.q; | 31 | struct be_queue_info *mccq = &adapter->mcc_obj.q; |
32 | u32 val = 0; | 32 | u32 val = 0; |
33 | 33 | ||
34 | if (adapter->eeh_err) { | 34 | if (be_error(adapter)) |
35 | dev_info(&adapter->pdev->dev, | ||
36 | "Error in Card Detected! Cannot issue commands\n"); | ||
37 | return; | 35 | return; |
38 | } | ||
39 | 36 | ||
40 | val |= mccq->id & DB_MCCQ_RING_ID_MASK; | 37 | val |= mccq->id & DB_MCCQ_RING_ID_MASK; |
41 | val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT; | 38 | val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT; |
@@ -266,10 +263,10 @@ static int be_mcc_wait_compl(struct be_adapter *adapter) | |||
266 | int i, num, status = 0; | 263 | int i, num, status = 0; |
267 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; | 264 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; |
268 | 265 | ||
269 | if (adapter->eeh_err) | ||
270 | return -EIO; | ||
271 | |||
272 | for (i = 0; i < mcc_timeout; i++) { | 266 | for (i = 0; i < mcc_timeout; i++) { |
267 | if (be_error(adapter)) | ||
268 | return -EIO; | ||
269 | |||
273 | num = be_process_mcc(adapter, &status); | 270 | num = be_process_mcc(adapter, &status); |
274 | if (num) | 271 | if (num) |
275 | be_cq_notify(adapter, mcc_obj->cq.id, | 272 | be_cq_notify(adapter, mcc_obj->cq.id, |
@@ -280,7 +277,8 @@ static int be_mcc_wait_compl(struct be_adapter *adapter) | |||
280 | udelay(100); | 277 | udelay(100); |
281 | } | 278 | } |
282 | if (i == mcc_timeout) { | 279 | if (i == mcc_timeout) { |
283 | dev_err(&adapter->pdev->dev, "mccq poll timed out\n"); | 280 | dev_err(&adapter->pdev->dev, "FW not responding\n"); |
281 | adapter->fw_timeout = true; | ||
284 | return -1; | 282 | return -1; |
285 | } | 283 | } |
286 | return status; | 284 | return status; |
@@ -298,26 +296,21 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db) | |||
298 | int msecs = 0; | 296 | int msecs = 0; |
299 | u32 ready; | 297 | u32 ready; |
300 | 298 | ||
301 | if (adapter->eeh_err) { | ||
302 | dev_err(&adapter->pdev->dev, | ||
303 | "Error detected in card.Cannot issue commands\n"); | ||
304 | return -EIO; | ||
305 | } | ||
306 | |||
307 | do { | 299 | do { |
300 | if (be_error(adapter)) | ||
301 | return -EIO; | ||
302 | |||
308 | ready = ioread32(db); | 303 | ready = ioread32(db); |
309 | if (ready == 0xffffffff) { | 304 | if (ready == 0xffffffff) |
310 | dev_err(&adapter->pdev->dev, | ||
311 | "pci slot disconnected\n"); | ||
312 | return -1; | 305 | return -1; |
313 | } | ||
314 | 306 | ||
315 | ready &= MPU_MAILBOX_DB_RDY_MASK; | 307 | ready &= MPU_MAILBOX_DB_RDY_MASK; |
316 | if (ready) | 308 | if (ready) |
317 | break; | 309 | break; |
318 | 310 | ||
319 | if (msecs > 4000) { | 311 | if (msecs > 4000) { |
320 | dev_err(&adapter->pdev->dev, "mbox poll timed out\n"); | 312 | dev_err(&adapter->pdev->dev, "FW not responding\n"); |
313 | adapter->fw_timeout = true; | ||
321 | be_detect_dump_ue(adapter); | 314 | be_detect_dump_ue(adapter); |
322 | return -1; | 315 | return -1; |
323 | } | 316 | } |
@@ -555,9 +548,6 @@ int be_cmd_fw_clean(struct be_adapter *adapter) | |||
555 | u8 *wrb; | 548 | u8 *wrb; |
556 | int status; | 549 | int status; |
557 | 550 | ||
558 | if (adapter->eeh_err) | ||
559 | return -EIO; | ||
560 | |||
561 | if (mutex_lock_interruptible(&adapter->mbox_lock)) | 551 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
562 | return -1; | 552 | return -1; |
563 | 553 | ||
@@ -695,12 +685,15 @@ err: | |||
695 | } | 685 | } |
696 | 686 | ||
697 | /* Uses synchronous MCCQ */ | 687 | /* Uses synchronous MCCQ */ |
698 | int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id, u32 dom) | 688 | int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, u32 dom) |
699 | { | 689 | { |
700 | struct be_mcc_wrb *wrb; | 690 | struct be_mcc_wrb *wrb; |
701 | struct be_cmd_req_pmac_del *req; | 691 | struct be_cmd_req_pmac_del *req; |
702 | int status; | 692 | int status; |
703 | 693 | ||
694 | if (pmac_id == -1) | ||
695 | return 0; | ||
696 | |||
704 | spin_lock_bh(&adapter->mcc_lock); | 697 | spin_lock_bh(&adapter->mcc_lock); |
705 | 698 | ||
706 | wrb = wrb_from_mccq(adapter); | 699 | wrb = wrb_from_mccq(adapter); |
@@ -923,10 +916,14 @@ int be_cmd_txq_create(struct be_adapter *adapter, | |||
923 | void *ctxt; | 916 | void *ctxt; |
924 | int status; | 917 | int status; |
925 | 918 | ||
926 | if (mutex_lock_interruptible(&adapter->mbox_lock)) | 919 | spin_lock_bh(&adapter->mcc_lock); |
927 | return -1; | 920 | |
921 | wrb = wrb_from_mccq(adapter); | ||
922 | if (!wrb) { | ||
923 | status = -EBUSY; | ||
924 | goto err; | ||
925 | } | ||
928 | 926 | ||
929 | wrb = wrb_from_mbox(adapter); | ||
930 | req = embedded_payload(wrb); | 927 | req = embedded_payload(wrb); |
931 | ctxt = &req->context; | 928 | ctxt = &req->context; |
932 | 929 | ||
@@ -952,14 +949,15 @@ int be_cmd_txq_create(struct be_adapter *adapter, | |||
952 | 949 | ||
953 | be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); | 950 | be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); |
954 | 951 | ||
955 | status = be_mbox_notify_wait(adapter); | 952 | status = be_mcc_notify_wait(adapter); |
956 | if (!status) { | 953 | if (!status) { |
957 | struct be_cmd_resp_eth_tx_create *resp = embedded_payload(wrb); | 954 | struct be_cmd_resp_eth_tx_create *resp = embedded_payload(wrb); |
958 | txq->id = le16_to_cpu(resp->cid); | 955 | txq->id = le16_to_cpu(resp->cid); |
959 | txq->created = true; | 956 | txq->created = true; |
960 | } | 957 | } |
961 | 958 | ||
962 | mutex_unlock(&adapter->mbox_lock); | 959 | err: |
960 | spin_unlock_bh(&adapter->mcc_lock); | ||
963 | 961 | ||
964 | return status; | 962 | return status; |
965 | } | 963 | } |
@@ -1018,9 +1016,6 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, | |||
1018 | u8 subsys = 0, opcode = 0; | 1016 | u8 subsys = 0, opcode = 0; |
1019 | int status; | 1017 | int status; |
1020 | 1018 | ||
1021 | if (adapter->eeh_err) | ||
1022 | return -EIO; | ||
1023 | |||
1024 | if (mutex_lock_interruptible(&adapter->mbox_lock)) | 1019 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
1025 | return -1; | 1020 | return -1; |
1026 | 1021 | ||
@@ -1136,16 +1131,13 @@ err: | |||
1136 | } | 1131 | } |
1137 | 1132 | ||
1138 | /* Uses MCCQ */ | 1133 | /* Uses MCCQ */ |
1139 | int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id, u32 domain) | 1134 | int be_cmd_if_destroy(struct be_adapter *adapter, int interface_id, u32 domain) |
1140 | { | 1135 | { |
1141 | struct be_mcc_wrb *wrb; | 1136 | struct be_mcc_wrb *wrb; |
1142 | struct be_cmd_req_if_destroy *req; | 1137 | struct be_cmd_req_if_destroy *req; |
1143 | int status; | 1138 | int status; |
1144 | 1139 | ||
1145 | if (adapter->eeh_err) | 1140 | if (interface_id == -1) |
1146 | return -EIO; | ||
1147 | |||
1148 | if (!interface_id) | ||
1149 | return 0; | 1141 | return 0; |
1150 | 1142 | ||
1151 | spin_lock_bh(&adapter->mcc_lock); | 1143 | spin_lock_bh(&adapter->mcc_lock); |
@@ -1254,6 +1246,9 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed, | |||
1254 | } | 1246 | } |
1255 | req = embedded_payload(wrb); | 1247 | req = embedded_payload(wrb); |
1256 | 1248 | ||
1249 | if (lancer_chip(adapter)) | ||
1250 | req->hdr.version = 1; | ||
1251 | |||
1257 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | 1252 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, |
1258 | OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req), wrb, NULL); | 1253 | OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req), wrb, NULL); |
1259 | 1254 | ||
@@ -1836,6 +1831,53 @@ err_unlock: | |||
1836 | return status; | 1831 | return status; |
1837 | } | 1832 | } |
1838 | 1833 | ||
1834 | int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd, | ||
1835 | u32 data_size, u32 data_offset, const char *obj_name, | ||
1836 | u32 *data_read, u32 *eof, u8 *addn_status) | ||
1837 | { | ||
1838 | struct be_mcc_wrb *wrb; | ||
1839 | struct lancer_cmd_req_read_object *req; | ||
1840 | struct lancer_cmd_resp_read_object *resp; | ||
1841 | int status; | ||
1842 | |||
1843 | spin_lock_bh(&adapter->mcc_lock); | ||
1844 | |||
1845 | wrb = wrb_from_mccq(adapter); | ||
1846 | if (!wrb) { | ||
1847 | status = -EBUSY; | ||
1848 | goto err_unlock; | ||
1849 | } | ||
1850 | |||
1851 | req = embedded_payload(wrb); | ||
1852 | |||
1853 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
1854 | OPCODE_COMMON_READ_OBJECT, | ||
1855 | sizeof(struct lancer_cmd_req_read_object), wrb, | ||
1856 | NULL); | ||
1857 | |||
1858 | req->desired_read_len = cpu_to_le32(data_size); | ||
1859 | req->read_offset = cpu_to_le32(data_offset); | ||
1860 | strcpy(req->object_name, obj_name); | ||
1861 | req->descriptor_count = cpu_to_le32(1); | ||
1862 | req->buf_len = cpu_to_le32(data_size); | ||
1863 | req->addr_low = cpu_to_le32((cmd->dma & 0xFFFFFFFF)); | ||
1864 | req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma)); | ||
1865 | |||
1866 | status = be_mcc_notify_wait(adapter); | ||
1867 | |||
1868 | resp = embedded_payload(wrb); | ||
1869 | if (!status) { | ||
1870 | *data_read = le32_to_cpu(resp->actual_read_len); | ||
1871 | *eof = le32_to_cpu(resp->eof); | ||
1872 | } else { | ||
1873 | *addn_status = resp->additional_status; | ||
1874 | } | ||
1875 | |||
1876 | err_unlock: | ||
1877 | spin_unlock_bh(&adapter->mcc_lock); | ||
1878 | return status; | ||
1879 | } | ||
1880 | |||
1839 | int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, | 1881 | int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, |
1840 | u32 flash_type, u32 flash_opcode, u32 buf_size) | 1882 | u32 flash_type, u32 flash_opcode, u32 buf_size) |
1841 | { | 1883 | { |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index a35cd03fac4e..ac112465e719 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h | |||
@@ -189,6 +189,7 @@ struct be_mcc_mailbox { | |||
189 | #define OPCODE_COMMON_GET_PHY_DETAILS 102 | 189 | #define OPCODE_COMMON_GET_PHY_DETAILS 102 |
190 | #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103 | 190 | #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103 |
191 | #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 | 191 | #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 |
192 | #define OPCODE_COMMON_READ_OBJECT 171 | ||
192 | #define OPCODE_COMMON_WRITE_OBJECT 172 | 193 | #define OPCODE_COMMON_WRITE_OBJECT 172 |
193 | 194 | ||
194 | #define OPCODE_ETH_RSS_CONFIG 1 | 195 | #define OPCODE_ETH_RSS_CONFIG 1 |
@@ -1161,6 +1162,38 @@ struct lancer_cmd_resp_write_object { | |||
1161 | u32 actual_write_len; | 1162 | u32 actual_write_len; |
1162 | }; | 1163 | }; |
1163 | 1164 | ||
1165 | /************************ Lancer Read FW info **************/ | ||
1166 | #define LANCER_READ_FILE_CHUNK (32*1024) | ||
1167 | #define LANCER_READ_FILE_EOF_MASK 0x80000000 | ||
1168 | |||
1169 | #define LANCER_FW_DUMP_FILE "/dbg/dump.bin" | ||
1170 | #define LANCER_VPD_PF_FILE "/vpd/ntr_pf.vpd" | ||
1171 | #define LANCER_VPD_VF_FILE "/vpd/ntr_vf.vpd" | ||
1172 | |||
1173 | struct lancer_cmd_req_read_object { | ||
1174 | struct be_cmd_req_hdr hdr; | ||
1175 | u32 desired_read_len; | ||
1176 | u32 read_offset; | ||
1177 | u8 object_name[104]; | ||
1178 | u32 descriptor_count; | ||
1179 | u32 buf_len; | ||
1180 | u32 addr_low; | ||
1181 | u32 addr_high; | ||
1182 | }; | ||
1183 | |||
1184 | struct lancer_cmd_resp_read_object { | ||
1185 | u8 opcode; | ||
1186 | u8 subsystem; | ||
1187 | u8 rsvd1[2]; | ||
1188 | u8 status; | ||
1189 | u8 additional_status; | ||
1190 | u8 rsvd2[2]; | ||
1191 | u32 resp_len; | ||
1192 | u32 actual_resp_len; | ||
1193 | u32 actual_read_len; | ||
1194 | u32 eof; | ||
1195 | }; | ||
1196 | |||
1164 | /************************ WOL *******************************/ | 1197 | /************************ WOL *******************************/ |
1165 | struct be_cmd_req_acpi_wol_magic_config{ | 1198 | struct be_cmd_req_acpi_wol_magic_config{ |
1166 | struct be_cmd_req_hdr hdr; | 1199 | struct be_cmd_req_hdr hdr; |
@@ -1417,11 +1450,11 @@ extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, | |||
1417 | extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, | 1450 | extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, |
1418 | u32 if_id, u32 *pmac_id, u32 domain); | 1451 | u32 if_id, u32 *pmac_id, u32 domain); |
1419 | extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, | 1452 | extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, |
1420 | u32 pmac_id, u32 domain); | 1453 | int pmac_id, u32 domain); |
1421 | extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, | 1454 | extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, |
1422 | u32 en_flags, u8 *mac, u32 *if_handle, u32 *pmac_id, | 1455 | u32 en_flags, u8 *mac, u32 *if_handle, u32 *pmac_id, |
1423 | u32 domain); | 1456 | u32 domain); |
1424 | extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle, | 1457 | extern int be_cmd_if_destroy(struct be_adapter *adapter, int if_handle, |
1425 | u32 domain); | 1458 | u32 domain); |
1426 | extern int be_cmd_eq_create(struct be_adapter *adapter, | 1459 | extern int be_cmd_eq_create(struct be_adapter *adapter, |
1427 | struct be_queue_info *eq, int eq_delay); | 1460 | struct be_queue_info *eq, int eq_delay); |
@@ -1480,6 +1513,9 @@ extern int lancer_cmd_write_object(struct be_adapter *adapter, | |||
1480 | u32 data_size, u32 data_offset, | 1513 | u32 data_size, u32 data_offset, |
1481 | const char *obj_name, | 1514 | const char *obj_name, |
1482 | u32 *data_written, u8 *addn_status); | 1515 | u32 *data_written, u8 *addn_status); |
1516 | int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd, | ||
1517 | u32 data_size, u32 data_offset, const char *obj_name, | ||
1518 | u32 *data_read, u32 *eof, u8 *addn_status); | ||
1483 | int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, | 1519 | int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, |
1484 | int offset); | 1520 | int offset); |
1485 | extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, | 1521 | extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, |
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index bf8153ea4ed8..575c78306313 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c | |||
@@ -127,8 +127,8 @@ static void be_get_drvinfo(struct net_device *netdev, | |||
127 | memset(fw_on_flash, 0 , sizeof(fw_on_flash)); | 127 | memset(fw_on_flash, 0 , sizeof(fw_on_flash)); |
128 | be_cmd_get_fw_ver(adapter, adapter->fw_ver, fw_on_flash); | 128 | be_cmd_get_fw_ver(adapter, adapter->fw_ver, fw_on_flash); |
129 | 129 | ||
130 | strcpy(drvinfo->driver, DRV_NAME); | 130 | strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); |
131 | strcpy(drvinfo->version, DRV_VER); | 131 | strlcpy(drvinfo->version, DRV_VER, sizeof(drvinfo->version)); |
132 | strncpy(drvinfo->fw_version, adapter->fw_ver, FW_VER_LEN); | 132 | strncpy(drvinfo->fw_version, adapter->fw_ver, FW_VER_LEN); |
133 | if (memcmp(adapter->fw_ver, fw_on_flash, FW_VER_LEN) != 0) { | 133 | if (memcmp(adapter->fw_ver, fw_on_flash, FW_VER_LEN) != 0) { |
134 | strcat(drvinfo->fw_version, " ["); | 134 | strcat(drvinfo->fw_version, " ["); |
@@ -136,21 +136,84 @@ static void be_get_drvinfo(struct net_device *netdev, | |||
136 | strcat(drvinfo->fw_version, "]"); | 136 | strcat(drvinfo->fw_version, "]"); |
137 | } | 137 | } |
138 | 138 | ||
139 | strcpy(drvinfo->bus_info, pci_name(adapter->pdev)); | 139 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), |
140 | sizeof(drvinfo->bus_info)); | ||
140 | drvinfo->testinfo_len = 0; | 141 | drvinfo->testinfo_len = 0; |
141 | drvinfo->regdump_len = 0; | 142 | drvinfo->regdump_len = 0; |
142 | drvinfo->eedump_len = 0; | 143 | drvinfo->eedump_len = 0; |
143 | } | 144 | } |
144 | 145 | ||
146 | static u32 | ||
147 | lancer_cmd_get_file_len(struct be_adapter *adapter, u8 *file_name) | ||
148 | { | ||
149 | u32 data_read = 0, eof; | ||
150 | u8 addn_status; | ||
151 | struct be_dma_mem data_len_cmd; | ||
152 | int status; | ||
153 | |||
154 | memset(&data_len_cmd, 0, sizeof(data_len_cmd)); | ||
155 | /* data_offset and data_size should be 0 to get reg len */ | ||
156 | status = lancer_cmd_read_object(adapter, &data_len_cmd, 0, 0, | ||
157 | file_name, &data_read, &eof, &addn_status); | ||
158 | |||
159 | return data_read; | ||
160 | } | ||
161 | |||
162 | static int | ||
163 | lancer_cmd_read_file(struct be_adapter *adapter, u8 *file_name, | ||
164 | u32 buf_len, void *buf) | ||
165 | { | ||
166 | struct be_dma_mem read_cmd; | ||
167 | u32 read_len = 0, total_read_len = 0, chunk_size; | ||
168 | u32 eof = 0; | ||
169 | u8 addn_status; | ||
170 | int status = 0; | ||
171 | |||
172 | read_cmd.size = LANCER_READ_FILE_CHUNK; | ||
173 | read_cmd.va = pci_alloc_consistent(adapter->pdev, read_cmd.size, | ||
174 | &read_cmd.dma); | ||
175 | |||
176 | if (!read_cmd.va) { | ||
177 | dev_err(&adapter->pdev->dev, | ||
178 | "Memory allocation failure while reading dump\n"); | ||
179 | return -ENOMEM; | ||
180 | } | ||
181 | |||
182 | while ((total_read_len < buf_len) && !eof) { | ||
183 | chunk_size = min_t(u32, (buf_len - total_read_len), | ||
184 | LANCER_READ_FILE_CHUNK); | ||
185 | chunk_size = ALIGN(chunk_size, 4); | ||
186 | status = lancer_cmd_read_object(adapter, &read_cmd, chunk_size, | ||
187 | total_read_len, file_name, &read_len, | ||
188 | &eof, &addn_status); | ||
189 | if (!status) { | ||
190 | memcpy(buf + total_read_len, read_cmd.va, read_len); | ||
191 | total_read_len += read_len; | ||
192 | eof &= LANCER_READ_FILE_EOF_MASK; | ||
193 | } else { | ||
194 | status = -EIO; | ||
195 | break; | ||
196 | } | ||
197 | } | ||
198 | pci_free_consistent(adapter->pdev, read_cmd.size, read_cmd.va, | ||
199 | read_cmd.dma); | ||
200 | |||
201 | return status; | ||
202 | } | ||
203 | |||
145 | static int | 204 | static int |
146 | be_get_reg_len(struct net_device *netdev) | 205 | be_get_reg_len(struct net_device *netdev) |
147 | { | 206 | { |
148 | struct be_adapter *adapter = netdev_priv(netdev); | 207 | struct be_adapter *adapter = netdev_priv(netdev); |
149 | u32 log_size = 0; | 208 | u32 log_size = 0; |
150 | 209 | ||
151 | if (be_physfn(adapter)) | 210 | if (be_physfn(adapter)) { |
152 | be_cmd_get_reg_len(adapter, &log_size); | 211 | if (lancer_chip(adapter)) |
153 | 212 | log_size = lancer_cmd_get_file_len(adapter, | |
213 | LANCER_FW_DUMP_FILE); | ||
214 | else | ||
215 | be_cmd_get_reg_len(adapter, &log_size); | ||
216 | } | ||
154 | return log_size; | 217 | return log_size; |
155 | } | 218 | } |
156 | 219 | ||
@@ -161,7 +224,11 @@ be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf) | |||
161 | 224 | ||
162 | if (be_physfn(adapter)) { | 225 | if (be_physfn(adapter)) { |
163 | memset(buf, 0, regs->len); | 226 | memset(buf, 0, regs->len); |
164 | be_cmd_get_regs(adapter, regs->len, buf); | 227 | if (lancer_chip(adapter)) |
228 | lancer_cmd_read_file(adapter, LANCER_FW_DUMP_FILE, | ||
229 | regs->len, buf); | ||
230 | else | ||
231 | be_cmd_get_regs(adapter, regs->len, buf); | ||
165 | } | 232 | } |
166 | } | 233 | } |
167 | 234 | ||
@@ -660,7 +727,17 @@ be_do_flash(struct net_device *netdev, struct ethtool_flash *efl) | |||
660 | static int | 727 | static int |
661 | be_get_eeprom_len(struct net_device *netdev) | 728 | be_get_eeprom_len(struct net_device *netdev) |
662 | { | 729 | { |
663 | return BE_READ_SEEPROM_LEN; | 730 | struct be_adapter *adapter = netdev_priv(netdev); |
731 | if (lancer_chip(adapter)) { | ||
732 | if (be_physfn(adapter)) | ||
733 | return lancer_cmd_get_file_len(adapter, | ||
734 | LANCER_VPD_PF_FILE); | ||
735 | else | ||
736 | return lancer_cmd_get_file_len(adapter, | ||
737 | LANCER_VPD_VF_FILE); | ||
738 | } else { | ||
739 | return BE_READ_SEEPROM_LEN; | ||
740 | } | ||
664 | } | 741 | } |
665 | 742 | ||
666 | static int | 743 | static int |
@@ -675,6 +752,15 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, | |||
675 | if (!eeprom->len) | 752 | if (!eeprom->len) |
676 | return -EINVAL; | 753 | return -EINVAL; |
677 | 754 | ||
755 | if (lancer_chip(adapter)) { | ||
756 | if (be_physfn(adapter)) | ||
757 | return lancer_cmd_read_file(adapter, LANCER_VPD_PF_FILE, | ||
758 | eeprom->len, data); | ||
759 | else | ||
760 | return lancer_cmd_read_file(adapter, LANCER_VPD_VF_FILE, | ||
761 | eeprom->len, data); | ||
762 | } | ||
763 | |||
678 | eeprom->magic = BE_VENDOR_ID | (adapter->pdev->device<<16); | 764 | eeprom->magic = BE_VENDOR_ID | (adapter->pdev->device<<16); |
679 | 765 | ||
680 | memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem)); | 766 | memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem)); |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index bf266a00c774..93869d457b14 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -848,15 +848,11 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) | |||
848 | if (!is_valid_ether_addr(mac) || (vf >= num_vfs)) | 848 | if (!is_valid_ether_addr(mac) || (vf >= num_vfs)) |
849 | return -EINVAL; | 849 | return -EINVAL; |
850 | 850 | ||
851 | if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID) | 851 | status = be_cmd_pmac_del(adapter, adapter->vf_cfg[vf].vf_if_handle, |
852 | status = be_cmd_pmac_del(adapter, | 852 | adapter->vf_cfg[vf].vf_pmac_id, vf + 1); |
853 | adapter->vf_cfg[vf].vf_if_handle, | ||
854 | adapter->vf_cfg[vf].vf_pmac_id, vf + 1); | ||
855 | 853 | ||
856 | status = be_cmd_pmac_add(adapter, mac, | 854 | status = be_cmd_pmac_add(adapter, mac, adapter->vf_cfg[vf].vf_if_handle, |
857 | adapter->vf_cfg[vf].vf_if_handle, | ||
858 | &adapter->vf_cfg[vf].vf_pmac_id, vf + 1); | 855 | &adapter->vf_cfg[vf].vf_pmac_id, vf + 1); |
859 | |||
860 | if (status) | 856 | if (status) |
861 | dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n", | 857 | dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n", |
862 | mac, vf); | 858 | mac, vf); |
@@ -1693,9 +1689,6 @@ static int be_tx_queues_create(struct be_adapter *adapter) | |||
1693 | if (be_queue_alloc(adapter, q, TX_Q_LEN, | 1689 | if (be_queue_alloc(adapter, q, TX_Q_LEN, |
1694 | sizeof(struct be_eth_wrb))) | 1690 | sizeof(struct be_eth_wrb))) |
1695 | goto err; | 1691 | goto err; |
1696 | |||
1697 | if (be_cmd_txq_create(adapter, q, cq)) | ||
1698 | goto err; | ||
1699 | } | 1692 | } |
1700 | return 0; | 1693 | return 0; |
1701 | 1694 | ||
@@ -1982,6 +1975,9 @@ void be_detect_dump_ue(struct be_adapter *adapter) | |||
1982 | u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0; | 1975 | u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0; |
1983 | u32 i; | 1976 | u32 i; |
1984 | 1977 | ||
1978 | if (adapter->eeh_err || adapter->ue_detected) | ||
1979 | return; | ||
1980 | |||
1985 | if (lancer_chip(adapter)) { | 1981 | if (lancer_chip(adapter)) { |
1986 | sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); | 1982 | sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); |
1987 | if (sliport_status & SLIPORT_STATUS_ERR_MASK) { | 1983 | if (sliport_status & SLIPORT_STATUS_ERR_MASK) { |
@@ -2008,7 +2004,8 @@ void be_detect_dump_ue(struct be_adapter *adapter) | |||
2008 | sliport_status & SLIPORT_STATUS_ERR_MASK) { | 2004 | sliport_status & SLIPORT_STATUS_ERR_MASK) { |
2009 | adapter->ue_detected = true; | 2005 | adapter->ue_detected = true; |
2010 | adapter->eeh_err = true; | 2006 | adapter->eeh_err = true; |
2011 | dev_err(&adapter->pdev->dev, "UE Detected!!\n"); | 2007 | dev_err(&adapter->pdev->dev, |
2008 | "Unrecoverable error in the card\n"); | ||
2012 | } | 2009 | } |
2013 | 2010 | ||
2014 | if (ue_lo) { | 2011 | if (ue_lo) { |
@@ -2043,8 +2040,7 @@ static void be_worker(struct work_struct *work) | |||
2043 | struct be_rx_obj *rxo; | 2040 | struct be_rx_obj *rxo; |
2044 | int i; | 2041 | int i; |
2045 | 2042 | ||
2046 | if (!adapter->ue_detected) | 2043 | be_detect_dump_ue(adapter); |
2047 | be_detect_dump_ue(adapter); | ||
2048 | 2044 | ||
2049 | /* when interrupts are not yet enabled, just reap any pending | 2045 | /* when interrupts are not yet enabled, just reap any pending |
2050 | * mcc completions */ | 2046 | * mcc completions */ |
@@ -2488,17 +2484,13 @@ static void be_vf_clear(struct be_adapter *adapter) | |||
2488 | { | 2484 | { |
2489 | u32 vf; | 2485 | u32 vf; |
2490 | 2486 | ||
2491 | for (vf = 0; vf < num_vfs; vf++) { | 2487 | for (vf = 0; vf < num_vfs; vf++) |
2492 | if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID) | 2488 | be_cmd_pmac_del(adapter, adapter->vf_cfg[vf].vf_if_handle, |
2493 | be_cmd_pmac_del(adapter, | 2489 | adapter->vf_cfg[vf].vf_pmac_id, vf + 1); |
2494 | adapter->vf_cfg[vf].vf_if_handle, | ||
2495 | adapter->vf_cfg[vf].vf_pmac_id, vf + 1); | ||
2496 | } | ||
2497 | 2490 | ||
2498 | for (vf = 0; vf < num_vfs; vf++) | 2491 | for (vf = 0; vf < num_vfs; vf++) |
2499 | if (adapter->vf_cfg[vf].vf_if_handle) | 2492 | be_cmd_if_destroy(adapter, adapter->vf_cfg[vf].vf_if_handle, |
2500 | be_cmd_if_destroy(adapter, | 2493 | vf + 1); |
2501 | adapter->vf_cfg[vf].vf_if_handle, vf + 1); | ||
2502 | } | 2494 | } |
2503 | 2495 | ||
2504 | static int be_clear(struct be_adapter *adapter) | 2496 | static int be_clear(struct be_adapter *adapter) |
@@ -2511,22 +2503,30 @@ static int be_clear(struct be_adapter *adapter) | |||
2511 | be_mcc_queues_destroy(adapter); | 2503 | be_mcc_queues_destroy(adapter); |
2512 | be_rx_queues_destroy(adapter); | 2504 | be_rx_queues_destroy(adapter); |
2513 | be_tx_queues_destroy(adapter); | 2505 | be_tx_queues_destroy(adapter); |
2514 | adapter->eq_next_idx = 0; | ||
2515 | |||
2516 | adapter->be3_native = false; | ||
2517 | adapter->promiscuous = false; | ||
2518 | 2506 | ||
2519 | /* tell fw we're done with firing cmds */ | 2507 | /* tell fw we're done with firing cmds */ |
2520 | be_cmd_fw_clean(adapter); | 2508 | be_cmd_fw_clean(adapter); |
2521 | return 0; | 2509 | return 0; |
2522 | } | 2510 | } |
2523 | 2511 | ||
2512 | static void be_vf_setup_init(struct be_adapter *adapter) | ||
2513 | { | ||
2514 | int vf; | ||
2515 | |||
2516 | for (vf = 0; vf < num_vfs; vf++) { | ||
2517 | adapter->vf_cfg[vf].vf_if_handle = -1; | ||
2518 | adapter->vf_cfg[vf].vf_pmac_id = -1; | ||
2519 | } | ||
2520 | } | ||
2521 | |||
2524 | static int be_vf_setup(struct be_adapter *adapter) | 2522 | static int be_vf_setup(struct be_adapter *adapter) |
2525 | { | 2523 | { |
2526 | u32 cap_flags, en_flags, vf; | 2524 | u32 cap_flags, en_flags, vf; |
2527 | u16 lnk_speed; | 2525 | u16 lnk_speed; |
2528 | int status; | 2526 | int status; |
2529 | 2527 | ||
2528 | be_vf_setup_init(adapter); | ||
2529 | |||
2530 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST; | 2530 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST; |
2531 | for (vf = 0; vf < num_vfs; vf++) { | 2531 | for (vf = 0; vf < num_vfs; vf++) { |
2532 | status = be_cmd_if_create(adapter, cap_flags, en_flags, NULL, | 2532 | status = be_cmd_if_create(adapter, cap_flags, en_flags, NULL, |
@@ -2534,7 +2534,6 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
2534 | NULL, vf+1); | 2534 | NULL, vf+1); |
2535 | if (status) | 2535 | if (status) |
2536 | goto err; | 2536 | goto err; |
2537 | adapter->vf_cfg[vf].vf_pmac_id = BE_INVALID_PMAC_ID; | ||
2538 | } | 2537 | } |
2539 | 2538 | ||
2540 | if (!lancer_chip(adapter)) { | 2539 | if (!lancer_chip(adapter)) { |
@@ -2555,17 +2554,26 @@ err: | |||
2555 | return status; | 2554 | return status; |
2556 | } | 2555 | } |
2557 | 2556 | ||
2557 | static void be_setup_init(struct be_adapter *adapter) | ||
2558 | { | ||
2559 | adapter->vlan_prio_bmap = 0xff; | ||
2560 | adapter->link_speed = -1; | ||
2561 | adapter->if_handle = -1; | ||
2562 | adapter->be3_native = false; | ||
2563 | adapter->promiscuous = false; | ||
2564 | adapter->eq_next_idx = 0; | ||
2565 | } | ||
2566 | |||
2558 | static int be_setup(struct be_adapter *adapter) | 2567 | static int be_setup(struct be_adapter *adapter) |
2559 | { | 2568 | { |
2560 | struct net_device *netdev = adapter->netdev; | 2569 | struct net_device *netdev = adapter->netdev; |
2561 | u32 cap_flags, en_flags; | 2570 | u32 cap_flags, en_flags; |
2562 | u32 tx_fc, rx_fc; | 2571 | u32 tx_fc, rx_fc; |
2563 | int status; | 2572 | int status, i; |
2564 | u8 mac[ETH_ALEN]; | 2573 | u8 mac[ETH_ALEN]; |
2574 | struct be_tx_obj *txo; | ||
2565 | 2575 | ||
2566 | /* Allow all priorities by default. A GRP5 evt may modify this */ | 2576 | be_setup_init(adapter); |
2567 | adapter->vlan_prio_bmap = 0xff; | ||
2568 | adapter->link_speed = -1; | ||
2569 | 2577 | ||
2570 | be_cmd_req_native_mode(adapter); | 2578 | be_cmd_req_native_mode(adapter); |
2571 | 2579 | ||
@@ -2592,7 +2600,8 @@ static int be_setup(struct be_adapter *adapter) | |||
2592 | en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | | 2600 | en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | |
2593 | BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS; | 2601 | BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS; |
2594 | cap_flags = en_flags | BE_IF_FLAGS_MCAST_PROMISCUOUS | | 2602 | cap_flags = en_flags | BE_IF_FLAGS_MCAST_PROMISCUOUS | |
2595 | BE_IF_FLAGS_PROMISCUOUS; | 2603 | BE_IF_FLAGS_VLAN_PROMISCUOUS | BE_IF_FLAGS_PROMISCUOUS; |
2604 | |||
2596 | if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) { | 2605 | if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) { |
2597 | cap_flags |= BE_IF_FLAGS_RSS; | 2606 | cap_flags |= BE_IF_FLAGS_RSS; |
2598 | en_flags |= BE_IF_FLAGS_RSS; | 2607 | en_flags |= BE_IF_FLAGS_RSS; |
@@ -2603,6 +2612,12 @@ static int be_setup(struct be_adapter *adapter) | |||
2603 | if (status != 0) | 2612 | if (status != 0) |
2604 | goto err; | 2613 | goto err; |
2605 | 2614 | ||
2615 | for_all_tx_queues(adapter, txo, i) { | ||
2616 | status = be_cmd_txq_create(adapter, &txo->q, &txo->cq); | ||
2617 | if (status) | ||
2618 | goto err; | ||
2619 | } | ||
2620 | |||
2606 | /* For BEx, the VF's permanent mac queried from card is incorrect. | 2621 | /* For BEx, the VF's permanent mac queried from card is incorrect. |
2607 | * Query the mac configued by the PF using if_handle | 2622 | * Query the mac configued by the PF using if_handle |
2608 | */ | 2623 | */ |
@@ -3559,6 +3574,8 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev) | |||
3559 | 3574 | ||
3560 | dev_info(&adapter->pdev->dev, "EEH reset\n"); | 3575 | dev_info(&adapter->pdev->dev, "EEH reset\n"); |
3561 | adapter->eeh_err = false; | 3576 | adapter->eeh_err = false; |
3577 | adapter->ue_detected = false; | ||
3578 | adapter->fw_timeout = false; | ||
3562 | 3579 | ||
3563 | status = pci_enable_device(pdev); | 3580 | status = pci_enable_device(pdev); |
3564 | if (status) | 3581 | if (status) |
diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c index 61d2bddec1fa..c82d444b582d 100644 --- a/drivers/net/ethernet/fealnx.c +++ b/drivers/net/ethernet/fealnx.c | |||
@@ -1818,9 +1818,9 @@ static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i | |||
1818 | { | 1818 | { |
1819 | struct netdev_private *np = netdev_priv(dev); | 1819 | struct netdev_private *np = netdev_priv(dev); |
1820 | 1820 | ||
1821 | strcpy(info->driver, DRV_NAME); | 1821 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1822 | strcpy(info->version, DRV_VERSION); | 1822 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1823 | strcpy(info->bus_info, pci_name(np->pci_dev)); | 1823 | strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); |
1824 | } | 1824 | } |
1825 | 1825 | ||
1826 | static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 1826 | static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c index 52f4e8ad48e7..8dee1aed47e4 100644 --- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c +++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c | |||
@@ -183,28 +183,10 @@ void fsl_pq_mdio_bus_name(char *name, struct device_node *np) | |||
183 | } | 183 | } |
184 | EXPORT_SYMBOL_GPL(fsl_pq_mdio_bus_name); | 184 | EXPORT_SYMBOL_GPL(fsl_pq_mdio_bus_name); |
185 | 185 | ||
186 | /* Scan the bus in reverse, looking for an empty spot */ | ||
187 | static int fsl_pq_mdio_find_free(struct mii_bus *new_bus) | ||
188 | { | ||
189 | int i; | ||
190 | |||
191 | for (i = PHY_MAX_ADDR; i > 0; i--) { | ||
192 | u32 phy_id; | ||
193 | |||
194 | if (get_phy_id(new_bus, i, &phy_id)) | ||
195 | return -1; | ||
196 | |||
197 | if (phy_id == 0xffffffff) | ||
198 | break; | ||
199 | } | ||
200 | |||
201 | return i; | ||
202 | } | ||
203 | 186 | ||
204 | |||
205 | #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) | ||
206 | static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np) | 187 | static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np) |
207 | { | 188 | { |
189 | #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) | ||
208 | struct gfar __iomem *enet_regs; | 190 | struct gfar __iomem *enet_regs; |
209 | 191 | ||
210 | /* | 192 | /* |
@@ -220,15 +202,15 @@ static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct devi | |||
220 | } else if (of_device_is_compatible(np, "fsl,etsec2-mdio") || | 202 | } else if (of_device_is_compatible(np, "fsl,etsec2-mdio") || |
221 | of_device_is_compatible(np, "fsl,etsec2-tbi")) { | 203 | of_device_is_compatible(np, "fsl,etsec2-tbi")) { |
222 | return of_iomap(np, 1); | 204 | return of_iomap(np, 1); |
223 | } else | 205 | } |
224 | return NULL; | ||
225 | } | ||
226 | #endif | 206 | #endif |
207 | return NULL; | ||
208 | } | ||
227 | 209 | ||
228 | 210 | ||
229 | #if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) | ||
230 | static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) | 211 | static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) |
231 | { | 212 | { |
213 | #if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) | ||
232 | struct device_node *np = NULL; | 214 | struct device_node *np = NULL; |
233 | int err = 0; | 215 | int err = 0; |
234 | 216 | ||
@@ -261,9 +243,10 @@ static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) | |||
261 | return err; | 243 | return err; |
262 | else | 244 | else |
263 | return -EINVAL; | 245 | return -EINVAL; |
264 | } | 246 | #else |
247 | return -ENODEV; | ||
265 | #endif | 248 | #endif |
266 | 249 | } | |
267 | 250 | ||
268 | static int fsl_pq_mdio_probe(struct platform_device *ofdev) | 251 | static int fsl_pq_mdio_probe(struct platform_device *ofdev) |
269 | { | 252 | { |
@@ -339,19 +322,13 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev) | |||
339 | of_device_is_compatible(np, "fsl,etsec2-mdio") || | 322 | of_device_is_compatible(np, "fsl,etsec2-mdio") || |
340 | of_device_is_compatible(np, "fsl,etsec2-tbi") || | 323 | of_device_is_compatible(np, "fsl,etsec2-tbi") || |
341 | of_device_is_compatible(np, "gianfar")) { | 324 | of_device_is_compatible(np, "gianfar")) { |
342 | #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) | ||
343 | tbipa = get_gfar_tbipa(regs, np); | 325 | tbipa = get_gfar_tbipa(regs, np); |
344 | if (!tbipa) { | 326 | if (!tbipa) { |
345 | err = -EINVAL; | 327 | err = -EINVAL; |
346 | goto err_free_irqs; | 328 | goto err_free_irqs; |
347 | } | 329 | } |
348 | #else | ||
349 | err = -ENODEV; | ||
350 | goto err_free_irqs; | ||
351 | #endif | ||
352 | } else if (of_device_is_compatible(np, "fsl,ucc-mdio") || | 330 | } else if (of_device_is_compatible(np, "fsl,ucc-mdio") || |
353 | of_device_is_compatible(np, "ucc_geth_phy")) { | 331 | of_device_is_compatible(np, "ucc_geth_phy")) { |
354 | #if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) | ||
355 | u32 id; | 332 | u32 id; |
356 | static u32 mii_mng_master; | 333 | static u32 mii_mng_master; |
357 | 334 | ||
@@ -364,10 +341,6 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev) | |||
364 | mii_mng_master = id; | 341 | mii_mng_master = id; |
365 | ucc_set_qe_mux_mii_mng(id - 1); | 342 | ucc_set_qe_mux_mii_mng(id - 1); |
366 | } | 343 | } |
367 | #else | ||
368 | err = -ENODEV; | ||
369 | goto err_free_irqs; | ||
370 | #endif | ||
371 | } else { | 344 | } else { |
372 | err = -ENODEV; | 345 | err = -ENODEV; |
373 | goto err_free_irqs; | 346 | goto err_free_irqs; |
@@ -383,26 +356,16 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev) | |||
383 | 356 | ||
384 | if (prop) | 357 | if (prop) |
385 | tbiaddr = *prop; | 358 | tbiaddr = *prop; |
386 | } | ||
387 | |||
388 | if (tbiaddr == -1) { | ||
389 | out_be32(tbipa, 0); | ||
390 | 359 | ||
391 | tbiaddr = fsl_pq_mdio_find_free(new_bus); | 360 | if (tbiaddr == -1) { |
392 | } | 361 | err = -EBUSY; |
393 | |||
394 | /* | ||
395 | * We define TBIPA at 0 to be illegal, opting to fail for boards that | ||
396 | * have PHYs at 1-31, rather than change tbipa and rescan. | ||
397 | */ | ||
398 | if (tbiaddr == 0) { | ||
399 | err = -EBUSY; | ||
400 | 362 | ||
401 | goto err_free_irqs; | 363 | goto err_free_irqs; |
364 | } else { | ||
365 | out_be32(tbipa, tbiaddr); | ||
366 | } | ||
402 | } | 367 | } |
403 | 368 | ||
404 | out_be32(tbipa, tbiaddr); | ||
405 | |||
406 | err = of_mdiobus_register(new_bus, np); | 369 | err = of_mdiobus_register(new_bus, np); |
407 | if (err) { | 370 | if (err) { |
408 | printk (KERN_ERR "%s: Cannot register as MDIO bus\n", | 371 | printk (KERN_ERR "%s: Cannot register as MDIO bus\n", |
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 83199fd0d62b..8e21ceb3b7da 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -734,7 +734,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) | |||
734 | 734 | ||
735 | mac_addr = of_get_mac_address(np); | 735 | mac_addr = of_get_mac_address(np); |
736 | if (mac_addr) | 736 | if (mac_addr) |
737 | memcpy(dev->dev_addr, mac_addr, MAC_ADDR_LEN); | 737 | memcpy(dev->dev_addr, mac_addr, ETH_ALEN); |
738 | 738 | ||
739 | if (model && !strcasecmp(model, "TSEC")) | 739 | if (model && !strcasecmp(model, "TSEC")) |
740 | priv->device_flags = | 740 | priv->device_flags = |
@@ -2306,7 +2306,7 @@ void gfar_check_rx_parser_mode(struct gfar_private *priv) | |||
2306 | } | 2306 | } |
2307 | 2307 | ||
2308 | /* Enables and disables VLAN insertion/extraction */ | 2308 | /* Enables and disables VLAN insertion/extraction */ |
2309 | void gfar_vlan_mode(struct net_device *dev, u32 features) | 2309 | void gfar_vlan_mode(struct net_device *dev, netdev_features_t features) |
2310 | { | 2310 | { |
2311 | struct gfar_private *priv = netdev_priv(dev); | 2311 | struct gfar_private *priv = netdev_priv(dev); |
2312 | struct gfar __iomem *regs = NULL; | 2312 | struct gfar __iomem *regs = NULL; |
@@ -3114,7 +3114,7 @@ static void gfar_set_multi(struct net_device *dev) | |||
3114 | static void gfar_clear_exact_match(struct net_device *dev) | 3114 | static void gfar_clear_exact_match(struct net_device *dev) |
3115 | { | 3115 | { |
3116 | int idx; | 3116 | int idx; |
3117 | static const u8 zero_arr[MAC_ADDR_LEN] = {0, 0, 0, 0, 0, 0}; | 3117 | static const u8 zero_arr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; |
3118 | 3118 | ||
3119 | for(idx = 1;idx < GFAR_EM_NUM + 1;idx++) | 3119 | for(idx = 1;idx < GFAR_EM_NUM + 1;idx++) |
3120 | gfar_set_mac_for_addr(dev, idx, zero_arr); | 3120 | gfar_set_mac_for_addr(dev, idx, zero_arr); |
@@ -3137,7 +3137,7 @@ static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr) | |||
3137 | { | 3137 | { |
3138 | u32 tempval; | 3138 | u32 tempval; |
3139 | struct gfar_private *priv = netdev_priv(dev); | 3139 | struct gfar_private *priv = netdev_priv(dev); |
3140 | u32 result = ether_crc(MAC_ADDR_LEN, addr); | 3140 | u32 result = ether_crc(ETH_ALEN, addr); |
3141 | int width = priv->hash_width; | 3141 | int width = priv->hash_width; |
3142 | u8 whichbit = (result >> (32 - width)) & 0x1f; | 3142 | u8 whichbit = (result >> (32 - width)) & 0x1f; |
3143 | u8 whichreg = result >> (32 - width + 5); | 3143 | u8 whichreg = result >> (32 - width + 5); |
@@ -3158,7 +3158,7 @@ static void gfar_set_mac_for_addr(struct net_device *dev, int num, | |||
3158 | struct gfar_private *priv = netdev_priv(dev); | 3158 | struct gfar_private *priv = netdev_priv(dev); |
3159 | struct gfar __iomem *regs = priv->gfargrp[0].regs; | 3159 | struct gfar __iomem *regs = priv->gfargrp[0].regs; |
3160 | int idx; | 3160 | int idx; |
3161 | char tmpbuf[MAC_ADDR_LEN]; | 3161 | char tmpbuf[ETH_ALEN]; |
3162 | u32 tempval; | 3162 | u32 tempval; |
3163 | u32 __iomem *macptr = ®s->macstnaddr1; | 3163 | u32 __iomem *macptr = ®s->macstnaddr1; |
3164 | 3164 | ||
@@ -3166,8 +3166,8 @@ static void gfar_set_mac_for_addr(struct net_device *dev, int num, | |||
3166 | 3166 | ||
3167 | /* Now copy it into the mac registers backwards, cuz */ | 3167 | /* Now copy it into the mac registers backwards, cuz */ |
3168 | /* little endian is silly */ | 3168 | /* little endian is silly */ |
3169 | for (idx = 0; idx < MAC_ADDR_LEN; idx++) | 3169 | for (idx = 0; idx < ETH_ALEN; idx++) |
3170 | tmpbuf[MAC_ADDR_LEN - 1 - idx] = addr[idx]; | 3170 | tmpbuf[ETH_ALEN - 1 - idx] = addr[idx]; |
3171 | 3171 | ||
3172 | gfar_write(macptr, *((u32 *) (tmpbuf))); | 3172 | gfar_write(macptr, *((u32 *) (tmpbuf))); |
3173 | 3173 | ||
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 9aa43773e8e3..fe7ac3a83194 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h | |||
@@ -74,9 +74,6 @@ struct ethtool_rx_list { | |||
74 | * will be the next highest multiple of 512 bytes. */ | 74 | * will be the next highest multiple of 512 bytes. */ |
75 | #define INCREMENTAL_BUFFER_SIZE 512 | 75 | #define INCREMENTAL_BUFFER_SIZE 512 |
76 | 76 | ||
77 | |||
78 | #define MAC_ADDR_LEN 6 | ||
79 | |||
80 | #define PHY_INIT_TIMEOUT 100000 | 77 | #define PHY_INIT_TIMEOUT 100000 |
81 | #define GFAR_PHY_CHANGE_TIME 2 | 78 | #define GFAR_PHY_CHANGE_TIME 2 |
82 | 79 | ||
@@ -1179,9 +1176,9 @@ extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, | |||
1179 | extern void gfar_configure_coalescing(struct gfar_private *priv, | 1176 | extern void gfar_configure_coalescing(struct gfar_private *priv, |
1180 | unsigned long tx_mask, unsigned long rx_mask); | 1177 | unsigned long tx_mask, unsigned long rx_mask); |
1181 | void gfar_init_sysfs(struct net_device *dev); | 1178 | void gfar_init_sysfs(struct net_device *dev); |
1182 | int gfar_set_features(struct net_device *dev, u32 features); | 1179 | int gfar_set_features(struct net_device *dev, netdev_features_t features); |
1183 | extern void gfar_check_rx_parser_mode(struct gfar_private *priv); | 1180 | extern void gfar_check_rx_parser_mode(struct gfar_private *priv); |
1184 | extern void gfar_vlan_mode(struct net_device *dev, u32 features); | 1181 | extern void gfar_vlan_mode(struct net_device *dev, netdev_features_t features); |
1185 | 1182 | ||
1186 | extern const struct ethtool_ops gfar_ethtool_ops; | 1183 | extern const struct ethtool_ops gfar_ethtool_ops; |
1187 | 1184 | ||
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c index 212736bab6bb..5890f4b0c0da 100644 --- a/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c | |||
@@ -519,12 +519,12 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva | |||
519 | return err; | 519 | return err; |
520 | } | 520 | } |
521 | 521 | ||
522 | int gfar_set_features(struct net_device *dev, u32 features) | 522 | int gfar_set_features(struct net_device *dev, netdev_features_t features) |
523 | { | 523 | { |
524 | struct gfar_private *priv = netdev_priv(dev); | 524 | struct gfar_private *priv = netdev_priv(dev); |
525 | unsigned long flags; | 525 | unsigned long flags; |
526 | int err = 0, i = 0; | 526 | int err = 0, i = 0; |
527 | u32 changed = dev->features ^ features; | 527 | netdev_features_t changed = dev->features ^ features; |
528 | 528 | ||
529 | if (changed & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)) | 529 | if (changed & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)) |
530 | gfar_vlan_mode(dev, features); | 530 | gfar_vlan_mode(dev, features); |
@@ -1410,10 +1410,9 @@ static int gfar_optimize_filer_masks(struct filer_table *tab) | |||
1410 | 1410 | ||
1411 | /* We need a copy of the filer table because | 1411 | /* We need a copy of the filer table because |
1412 | * we want to change its order */ | 1412 | * we want to change its order */ |
1413 | temp_table = kmalloc(sizeof(*temp_table), GFP_KERNEL); | 1413 | temp_table = kmemdup(tab, sizeof(*temp_table), GFP_KERNEL); |
1414 | if (temp_table == NULL) | 1414 | if (temp_table == NULL) |
1415 | return -ENOMEM; | 1415 | return -ENOMEM; |
1416 | memcpy(temp_table, tab, sizeof(*temp_table)); | ||
1417 | 1416 | ||
1418 | mask_table = kcalloc(MAX_FILER_CACHE_IDX / 2 + 1, | 1417 | mask_table = kcalloc(MAX_FILER_CACHE_IDX / 2 + 1, |
1419 | sizeof(struct gfar_mask_entry), GFP_KERNEL); | 1418 | sizeof(struct gfar_mask_entry), GFP_KERNEL); |
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index b5dc0273a1d1..ba2dc083bfc0 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c | |||
@@ -443,7 +443,7 @@ static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, | |||
443 | 443 | ||
444 | static inline int compare_addr(u8 **addr1, u8 **addr2) | 444 | static inline int compare_addr(u8 **addr1, u8 **addr2) |
445 | { | 445 | { |
446 | return memcmp(addr1, addr2, ENET_NUM_OCTETS_PER_ADDRESS); | 446 | return memcmp(addr1, addr2, ETH_ALEN); |
447 | } | 447 | } |
448 | 448 | ||
449 | #ifdef DEBUG | 449 | #ifdef DEBUG |
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h index d12fcad145e9..2e395a2566b8 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.h +++ b/drivers/net/ethernet/freescale/ucc_geth.h | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
23 | #include <linux/if_ether.h> | ||
23 | 24 | ||
24 | #include <asm/immap_qe.h> | 25 | #include <asm/immap_qe.h> |
25 | #include <asm/qe.h> | 26 | #include <asm/qe.h> |
@@ -881,7 +882,6 @@ struct ucc_geth_hardware_statistics { | |||
881 | #define TX_RING_MOD_MASK(size) (size-1) | 882 | #define TX_RING_MOD_MASK(size) (size-1) |
882 | #define RX_RING_MOD_MASK(size) (size-1) | 883 | #define RX_RING_MOD_MASK(size) (size-1) |
883 | 884 | ||
884 | #define ENET_NUM_OCTETS_PER_ADDRESS 6 | ||
885 | #define ENET_GROUP_ADDR 0x01 /* Group address mask | 885 | #define ENET_GROUP_ADDR 0x01 /* Group address mask |
886 | for ethernet | 886 | for ethernet |
887 | addresses */ | 887 | addresses */ |
@@ -1051,7 +1051,7 @@ enum ucc_geth_num_of_station_addresses { | |||
1051 | 1051 | ||
1052 | /* UCC GETH 82xx Ethernet Address Container */ | 1052 | /* UCC GETH 82xx Ethernet Address Container */ |
1053 | struct enet_addr_container { | 1053 | struct enet_addr_container { |
1054 | u8 address[ENET_NUM_OCTETS_PER_ADDRESS]; /* ethernet address */ | 1054 | u8 address[ETH_ALEN]; /* ethernet address */ |
1055 | enum ucc_geth_enet_address_recognition_location location; /* location in | 1055 | enum ucc_geth_enet_address_recognition_location location; /* location in |
1056 | 82xx address | 1056 | 82xx address |
1057 | recognition | 1057 | recognition |
@@ -1194,7 +1194,7 @@ struct ucc_geth_private { | |||
1194 | u16 cpucount[NUM_TX_QUEUES]; | 1194 | u16 cpucount[NUM_TX_QUEUES]; |
1195 | u16 __iomem *p_cpucount[NUM_TX_QUEUES]; | 1195 | u16 __iomem *p_cpucount[NUM_TX_QUEUES]; |
1196 | int indAddrRegUsed[NUM_OF_PADDRS]; | 1196 | int indAddrRegUsed[NUM_OF_PADDRS]; |
1197 | u8 paddr[NUM_OF_PADDRS][ENET_NUM_OCTETS_PER_ADDRESS]; /* ethernet address */ | 1197 | u8 paddr[NUM_OF_PADDRS][ETH_ALEN]; /* ethernet address */ |
1198 | u8 numGroupAddrInHash; | 1198 | u8 numGroupAddrInHash; |
1199 | u8 numIndAddrInHash; | 1199 | u8 numIndAddrInHash; |
1200 | u8 numIndAddrInReg; | 1200 | u8 numIndAddrInReg; |
diff --git a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c index 15416752c13e..ee84b472cee6 100644 --- a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c +++ b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c | |||
@@ -1058,9 +1058,10 @@ static void fjn_rx(struct net_device *dev) | |||
1058 | static void netdev_get_drvinfo(struct net_device *dev, | 1058 | static void netdev_get_drvinfo(struct net_device *dev, |
1059 | struct ethtool_drvinfo *info) | 1059 | struct ethtool_drvinfo *info) |
1060 | { | 1060 | { |
1061 | strcpy(info->driver, DRV_NAME); | 1061 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1062 | strcpy(info->version, DRV_VERSION); | 1062 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1063 | sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); | 1063 | snprintf(info->bus_info, sizeof(info->bus_info), |
1064 | "PCMCIA 0x%lx", dev->base_addr); | ||
1064 | } | 1065 | } |
1065 | 1066 | ||
1066 | static const struct ethtool_ops netdev_ethtool_ops = { | 1067 | static const struct ethtool_ops netdev_ethtool_ops = { |
diff --git a/drivers/net/ethernet/i825xx/eepro.c b/drivers/net/ethernet/i825xx/eepro.c index 067c46069a11..114cda7721fe 100644 --- a/drivers/net/ethernet/i825xx/eepro.c +++ b/drivers/net/ethernet/i825xx/eepro.c | |||
@@ -1726,9 +1726,10 @@ static int eepro_ethtool_get_settings(struct net_device *dev, | |||
1726 | static void eepro_ethtool_get_drvinfo(struct net_device *dev, | 1726 | static void eepro_ethtool_get_drvinfo(struct net_device *dev, |
1727 | struct ethtool_drvinfo *drvinfo) | 1727 | struct ethtool_drvinfo *drvinfo) |
1728 | { | 1728 | { |
1729 | strcpy(drvinfo->driver, DRV_NAME); | 1729 | strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); |
1730 | strcpy(drvinfo->version, DRV_VERSION); | 1730 | strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); |
1731 | sprintf(drvinfo->bus_info, "ISA 0x%lx", dev->base_addr); | 1731 | snprintf(drvinfo->bus_info, sizeof(drvinfo->bus_info), |
1732 | "ISA 0x%lx", dev->base_addr); | ||
1732 | } | 1733 | } |
1733 | 1734 | ||
1734 | static const struct ethtool_ops eepro_ethtool_ops = { | 1735 | static const struct ethtool_ops eepro_ethtool_ops = { |
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index ed79b2d3ad3e..2abce965c7bd 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c | |||
@@ -2924,6 +2924,9 @@ static int __devexit emac_remove(struct platform_device *ofdev) | |||
2924 | if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII)) | 2924 | if (emac_has_feature(dev, EMAC_FTR_HAS_ZMII)) |
2925 | zmii_detach(dev->zmii_dev, dev->zmii_port); | 2925 | zmii_detach(dev->zmii_dev, dev->zmii_port); |
2926 | 2926 | ||
2927 | busy_phy_map &= ~(1 << dev->phy.address); | ||
2928 | DBG(dev, "busy_phy_map now %#x" NL, busy_phy_map); | ||
2929 | |||
2927 | mal_unregister_commac(dev->mal, &dev->commac); | 2930 | mal_unregister_commac(dev->mal, &dev->commac); |
2928 | emac_put_deps(dev); | 2931 | emac_put_deps(dev); |
2929 | 2932 | ||
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index b1cd41b9c61c..e877371680a9 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c | |||
@@ -735,7 +735,8 @@ static void netdev_get_drvinfo(struct net_device *dev, | |||
735 | sizeof(info->version) - 1); | 735 | sizeof(info->version) - 1); |
736 | } | 736 | } |
737 | 737 | ||
738 | static u32 ibmveth_fix_features(struct net_device *dev, u32 features) | 738 | static netdev_features_t ibmveth_fix_features(struct net_device *dev, |
739 | netdev_features_t features) | ||
739 | { | 740 | { |
740 | /* | 741 | /* |
741 | * Since the ibmveth firmware interface does not have the | 742 | * Since the ibmveth firmware interface does not have the |
@@ -838,7 +839,8 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data) | |||
838 | return rc1 ? rc1 : rc2; | 839 | return rc1 ? rc1 : rc2; |
839 | } | 840 | } |
840 | 841 | ||
841 | static int ibmveth_set_features(struct net_device *dev, u32 features) | 842 | static int ibmveth_set_features(struct net_device *dev, |
843 | netdev_features_t features) | ||
842 | { | 844 | { |
843 | struct ibmveth_adapter *adapter = netdev_priv(dev); | 845 | struct ibmveth_adapter *adapter = netdev_priv(dev); |
844 | int rx_csum = !!(features & NETIF_F_RXCSUM); | 846 | int rx_csum = !!(features & NETIF_F_RXCSUM); |
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index 5a2fdf7a00c8..9436397e5725 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c | |||
@@ -2376,10 +2376,10 @@ static void e100_get_drvinfo(struct net_device *netdev, | |||
2376 | struct ethtool_drvinfo *info) | 2376 | struct ethtool_drvinfo *info) |
2377 | { | 2377 | { |
2378 | struct nic *nic = netdev_priv(netdev); | 2378 | struct nic *nic = netdev_priv(netdev); |
2379 | strcpy(info->driver, DRV_NAME); | 2379 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
2380 | strcpy(info->version, DRV_VERSION); | 2380 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
2381 | strcpy(info->fw_version, "N/A"); | 2381 | strlcpy(info->bus_info, pci_name(nic->pdev), |
2382 | strcpy(info->bus_info, pci_name(nic->pdev)); | 2382 | sizeof(info->bus_info)); |
2383 | } | 2383 | } |
2384 | 2384 | ||
2385 | #define E100_PHY_REGS 0x1C | 2385 | #define E100_PHY_REGS 0x1C |
diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c index 2b223ac99c42..3103f0b6bf5e 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c +++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c | |||
@@ -515,14 +515,14 @@ static void e1000_get_drvinfo(struct net_device *netdev, | |||
515 | struct ethtool_drvinfo *drvinfo) | 515 | struct ethtool_drvinfo *drvinfo) |
516 | { | 516 | { |
517 | struct e1000_adapter *adapter = netdev_priv(netdev); | 517 | struct e1000_adapter *adapter = netdev_priv(netdev); |
518 | char firmware_version[32]; | ||
519 | 518 | ||
520 | strncpy(drvinfo->driver, e1000_driver_name, 32); | 519 | strlcpy(drvinfo->driver, e1000_driver_name, |
521 | strncpy(drvinfo->version, e1000_driver_version, 32); | 520 | sizeof(drvinfo->driver)); |
521 | strlcpy(drvinfo->version, e1000_driver_version, | ||
522 | sizeof(drvinfo->version)); | ||
522 | 523 | ||
523 | sprintf(firmware_version, "N/A"); | 524 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), |
524 | strncpy(drvinfo->fw_version, firmware_version, 32); | 525 | sizeof(drvinfo->bus_info)); |
525 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | ||
526 | drvinfo->regdump_len = e1000_get_regs_len(netdev); | 526 | drvinfo->regdump_len = e1000_get_regs_len(netdev); |
527 | drvinfo->eedump_len = e1000_get_eeprom_len(netdev); | 527 | drvinfo->eedump_len = e1000_get_eeprom_len(netdev); |
528 | } | 528 | } |
diff --git a/drivers/net/ethernet/intel/e1000/e1000_hw.h b/drivers/net/ethernet/intel/e1000/e1000_hw.h index 5c9a8403668b..cf7e3c094477 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_hw.h +++ b/drivers/net/ethernet/intel/e1000/e1000_hw.h | |||
@@ -448,7 +448,6 @@ void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value); | |||
448 | #define E1000_DEV_ID_INTEL_CE4100_GBE 0x2E6E | 448 | #define E1000_DEV_ID_INTEL_CE4100_GBE 0x2E6E |
449 | 449 | ||
450 | #define NODE_ADDRESS_SIZE 6 | 450 | #define NODE_ADDRESS_SIZE 6 |
451 | #define ETH_LENGTH_OF_ADDRESS 6 | ||
452 | 451 | ||
453 | /* MAC decode size is 128K - This is the size of BAR0 */ | 452 | /* MAC decode size is 128K - This is the size of BAR0 */ |
454 | #define MAC_DECODE_SIZE (128 * 1024) | 453 | #define MAC_DECODE_SIZE (128 * 1024) |
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index cf480b554622..82f4ef142259 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c | |||
@@ -167,7 +167,8 @@ static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, | |||
167 | struct sk_buff *skb); | 167 | struct sk_buff *skb); |
168 | 168 | ||
169 | static bool e1000_vlan_used(struct e1000_adapter *adapter); | 169 | static bool e1000_vlan_used(struct e1000_adapter *adapter); |
170 | static void e1000_vlan_mode(struct net_device *netdev, u32 features); | 170 | static void e1000_vlan_mode(struct net_device *netdev, |
171 | netdev_features_t features); | ||
171 | static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid); | 172 | static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid); |
172 | static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); | 173 | static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); |
173 | static void e1000_restore_vlan(struct e1000_adapter *adapter); | 174 | static void e1000_restore_vlan(struct e1000_adapter *adapter); |
@@ -806,7 +807,8 @@ static int e1000_is_need_ioport(struct pci_dev *pdev) | |||
806 | } | 807 | } |
807 | } | 808 | } |
808 | 809 | ||
809 | static u32 e1000_fix_features(struct net_device *netdev, u32 features) | 810 | static netdev_features_t e1000_fix_features(struct net_device *netdev, |
811 | netdev_features_t features) | ||
810 | { | 812 | { |
811 | /* | 813 | /* |
812 | * Since there is no support for separate rx/tx vlan accel | 814 | * Since there is no support for separate rx/tx vlan accel |
@@ -820,10 +822,11 @@ static u32 e1000_fix_features(struct net_device *netdev, u32 features) | |||
820 | return features; | 822 | return features; |
821 | } | 823 | } |
822 | 824 | ||
823 | static int e1000_set_features(struct net_device *netdev, u32 features) | 825 | static int e1000_set_features(struct net_device *netdev, |
826 | netdev_features_t features) | ||
824 | { | 827 | { |
825 | struct e1000_adapter *adapter = netdev_priv(netdev); | 828 | struct e1000_adapter *adapter = netdev_priv(netdev); |
826 | u32 changed = features ^ netdev->features; | 829 | netdev_features_t changed = features ^ netdev->features; |
827 | 830 | ||
828 | if (changed & NETIF_F_HW_VLAN_RX) | 831 | if (changed & NETIF_F_HW_VLAN_RX) |
829 | e1000_vlan_mode(netdev, features); | 832 | e1000_vlan_mode(netdev, features); |
@@ -4577,7 +4580,8 @@ static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, | |||
4577 | e1000_irq_enable(adapter); | 4580 | e1000_irq_enable(adapter); |
4578 | } | 4581 | } |
4579 | 4582 | ||
4580 | static void e1000_vlan_mode(struct net_device *netdev, u32 features) | 4583 | static void e1000_vlan_mode(struct net_device *netdev, |
4584 | netdev_features_t features) | ||
4581 | { | 4585 | { |
4582 | struct e1000_adapter *adapter = netdev_priv(netdev); | 4586 | struct e1000_adapter *adapter = netdev_priv(netdev); |
4583 | struct e1000_hw *hw = &adapter->hw; | 4587 | struct e1000_hw *hw = &adapter->hw; |
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 69c9d2199140..fb2c28e799a2 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c | |||
@@ -579,26 +579,24 @@ static void e1000_get_drvinfo(struct net_device *netdev, | |||
579 | struct ethtool_drvinfo *drvinfo) | 579 | struct ethtool_drvinfo *drvinfo) |
580 | { | 580 | { |
581 | struct e1000_adapter *adapter = netdev_priv(netdev); | 581 | struct e1000_adapter *adapter = netdev_priv(netdev); |
582 | char firmware_version[32]; | ||
583 | 582 | ||
584 | strncpy(drvinfo->driver, e1000e_driver_name, | 583 | strlcpy(drvinfo->driver, e1000e_driver_name, |
585 | sizeof(drvinfo->driver) - 1); | 584 | sizeof(drvinfo->driver)); |
586 | strncpy(drvinfo->version, e1000e_driver_version, | 585 | strlcpy(drvinfo->version, e1000e_driver_version, |
587 | sizeof(drvinfo->version) - 1); | 586 | sizeof(drvinfo->version)); |
588 | 587 | ||
589 | /* | 588 | /* |
590 | * EEPROM image version # is reported as firmware version # for | 589 | * EEPROM image version # is reported as firmware version # for |
591 | * PCI-E controllers | 590 | * PCI-E controllers |
592 | */ | 591 | */ |
593 | snprintf(firmware_version, sizeof(firmware_version), "%d.%d-%d", | 592 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), |
593 | "%d.%d-%d", | ||
594 | (adapter->eeprom_vers & 0xF000) >> 12, | 594 | (adapter->eeprom_vers & 0xF000) >> 12, |
595 | (adapter->eeprom_vers & 0x0FF0) >> 4, | 595 | (adapter->eeprom_vers & 0x0FF0) >> 4, |
596 | (adapter->eeprom_vers & 0x000F)); | 596 | (adapter->eeprom_vers & 0x000F)); |
597 | 597 | ||
598 | strncpy(drvinfo->fw_version, firmware_version, | 598 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), |
599 | sizeof(drvinfo->fw_version) - 1); | 599 | sizeof(drvinfo->bus_info)); |
600 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), | ||
601 | sizeof(drvinfo->bus_info) - 1); | ||
602 | drvinfo->regdump_len = e1000_get_regs_len(netdev); | 600 | drvinfo->regdump_len = e1000_get_regs_len(netdev); |
603 | drvinfo->eedump_len = e1000_get_eeprom_len(netdev); | 601 | drvinfo->eedump_len = e1000_get_eeprom_len(netdev); |
604 | } | 602 | } |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index a855db1ad249..a5bd7a3dafc9 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -163,16 +163,13 @@ static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo) | |||
163 | regs[n] = __er32(hw, E1000_TARC(n)); | 163 | regs[n] = __er32(hw, E1000_TARC(n)); |
164 | break; | 164 | break; |
165 | default: | 165 | default: |
166 | printk(KERN_INFO "%-15s %08x\n", | 166 | pr_info("%-15s %08x\n", |
167 | reginfo->name, __er32(hw, reginfo->ofs)); | 167 | reginfo->name, __er32(hw, reginfo->ofs)); |
168 | return; | 168 | return; |
169 | } | 169 | } |
170 | 170 | ||
171 | snprintf(rname, 16, "%s%s", reginfo->name, "[0-1]"); | 171 | snprintf(rname, 16, "%s%s", reginfo->name, "[0-1]"); |
172 | printk(KERN_INFO "%-15s ", rname); | 172 | pr_info("%-15s %08x %08x\n", rname, regs[0], regs[1]); |
173 | for (n = 0; n < 2; n++) | ||
174 | printk(KERN_CONT "%08x ", regs[n]); | ||
175 | printk(KERN_CONT "\n"); | ||
176 | } | 173 | } |
177 | 174 | ||
178 | /* | 175 | /* |
@@ -208,16 +205,15 @@ static void e1000e_dump(struct e1000_adapter *adapter) | |||
208 | /* Print netdevice Info */ | 205 | /* Print netdevice Info */ |
209 | if (netdev) { | 206 | if (netdev) { |
210 | dev_info(&adapter->pdev->dev, "Net device Info\n"); | 207 | dev_info(&adapter->pdev->dev, "Net device Info\n"); |
211 | printk(KERN_INFO "Device Name state " | 208 | pr_info("Device Name state trans_start last_rx\n"); |
212 | "trans_start last_rx\n"); | 209 | pr_info("%-15s %016lX %016lX %016lX\n", |
213 | printk(KERN_INFO "%-15s %016lX %016lX %016lX\n", | 210 | netdev->name, netdev->state, netdev->trans_start, |
214 | netdev->name, netdev->state, netdev->trans_start, | 211 | netdev->last_rx); |
215 | netdev->last_rx); | ||
216 | } | 212 | } |
217 | 213 | ||
218 | /* Print Registers */ | 214 | /* Print Registers */ |
219 | dev_info(&adapter->pdev->dev, "Register Dump\n"); | 215 | dev_info(&adapter->pdev->dev, "Register Dump\n"); |
220 | printk(KERN_INFO " Register Name Value\n"); | 216 | pr_info(" Register Name Value\n"); |
221 | for (reginfo = (struct e1000_reg_info *)e1000_reg_info_tbl; | 217 | for (reginfo = (struct e1000_reg_info *)e1000_reg_info_tbl; |
222 | reginfo->name; reginfo++) { | 218 | reginfo->name; reginfo++) { |
223 | e1000_regdump(hw, reginfo); | 219 | e1000_regdump(hw, reginfo); |
@@ -228,15 +224,14 @@ static void e1000e_dump(struct e1000_adapter *adapter) | |||
228 | goto exit; | 224 | goto exit; |
229 | 225 | ||
230 | dev_info(&adapter->pdev->dev, "Tx Ring Summary\n"); | 226 | dev_info(&adapter->pdev->dev, "Tx Ring Summary\n"); |
231 | printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma ]" | 227 | pr_info("Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp\n"); |
232 | " leng ntw timestamp\n"); | ||
233 | buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean]; | 228 | buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean]; |
234 | printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n", | 229 | pr_info(" %5d %5X %5X %016llX %04X %3X %016llX\n", |
235 | 0, tx_ring->next_to_use, tx_ring->next_to_clean, | 230 | 0, tx_ring->next_to_use, tx_ring->next_to_clean, |
236 | (unsigned long long)buffer_info->dma, | 231 | (unsigned long long)buffer_info->dma, |
237 | buffer_info->length, | 232 | buffer_info->length, |
238 | buffer_info->next_to_watch, | 233 | buffer_info->next_to_watch, |
239 | (unsigned long long)buffer_info->time_stamp); | 234 | (unsigned long long)buffer_info->time_stamp); |
240 | 235 | ||
241 | /* Print Tx Ring */ | 236 | /* Print Tx Ring */ |
242 | if (!netif_msg_tx_done(adapter)) | 237 | if (!netif_msg_tx_done(adapter)) |
@@ -271,37 +266,32 @@ static void e1000e_dump(struct e1000_adapter *adapter) | |||
271 | * +----------------------------------------------------------------+ | 266 | * +----------------------------------------------------------------+ |
272 | * 63 48 47 40 39 36 35 32 31 24 23 20 19 0 | 267 | * 63 48 47 40 39 36 35 32 31 24 23 20 19 0 |
273 | */ | 268 | */ |
274 | printk(KERN_INFO "Tl[desc] [address 63:0 ] [SpeCssSCmCsLen]" | 269 | pr_info("Tl[desc] [address 63:0 ] [SpeCssSCmCsLen] [bi->dma ] leng ntw timestamp bi->skb <-- Legacy format\n"); |
275 | " [bi->dma ] leng ntw timestamp bi->skb " | 270 | pr_info("Tc[desc] [Ce CoCsIpceCoS] [MssHlRSCm0Plen] [bi->dma ] leng ntw timestamp bi->skb <-- Ext Context format\n"); |
276 | "<-- Legacy format\n"); | 271 | pr_info("Td[desc] [address 63:0 ] [VlaPoRSCm1Dlen] [bi->dma ] leng ntw timestamp bi->skb <-- Ext Data format\n"); |
277 | printk(KERN_INFO "Tc[desc] [Ce CoCsIpceCoS] [MssHlRSCm0Plen]" | ||
278 | " [bi->dma ] leng ntw timestamp bi->skb " | ||
279 | "<-- Ext Context format\n"); | ||
280 | printk(KERN_INFO "Td[desc] [address 63:0 ] [VlaPoRSCm1Dlen]" | ||
281 | " [bi->dma ] leng ntw timestamp bi->skb " | ||
282 | "<-- Ext Data format\n"); | ||
283 | for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { | 272 | for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { |
273 | const char *next_desc; | ||
284 | tx_desc = E1000_TX_DESC(*tx_ring, i); | 274 | tx_desc = E1000_TX_DESC(*tx_ring, i); |
285 | buffer_info = &tx_ring->buffer_info[i]; | 275 | buffer_info = &tx_ring->buffer_info[i]; |
286 | u0 = (struct my_u0 *)tx_desc; | 276 | u0 = (struct my_u0 *)tx_desc; |
287 | printk(KERN_INFO "T%c[0x%03X] %016llX %016llX %016llX " | ||
288 | "%04X %3X %016llX %p", | ||
289 | (!(le64_to_cpu(u0->b) & (1 << 29)) ? 'l' : | ||
290 | ((le64_to_cpu(u0->b) & (1 << 20)) ? 'd' : 'c')), i, | ||
291 | (unsigned long long)le64_to_cpu(u0->a), | ||
292 | (unsigned long long)le64_to_cpu(u0->b), | ||
293 | (unsigned long long)buffer_info->dma, | ||
294 | buffer_info->length, buffer_info->next_to_watch, | ||
295 | (unsigned long long)buffer_info->time_stamp, | ||
296 | buffer_info->skb); | ||
297 | if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean) | 277 | if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean) |
298 | printk(KERN_CONT " NTC/U\n"); | 278 | next_desc = " NTC/U"; |
299 | else if (i == tx_ring->next_to_use) | 279 | else if (i == tx_ring->next_to_use) |
300 | printk(KERN_CONT " NTU\n"); | 280 | next_desc = " NTU"; |
301 | else if (i == tx_ring->next_to_clean) | 281 | else if (i == tx_ring->next_to_clean) |
302 | printk(KERN_CONT " NTC\n"); | 282 | next_desc = " NTC"; |
303 | else | 283 | else |
304 | printk(KERN_CONT "\n"); | 284 | next_desc = ""; |
285 | pr_info("T%c[0x%03X] %016llX %016llX %016llX %04X %3X %016llX %p%s\n", | ||
286 | (!(le64_to_cpu(u0->b) & (1 << 29)) ? 'l' : | ||
287 | ((le64_to_cpu(u0->b) & (1 << 20)) ? 'd' : 'c')), | ||
288 | i, | ||
289 | (unsigned long long)le64_to_cpu(u0->a), | ||
290 | (unsigned long long)le64_to_cpu(u0->b), | ||
291 | (unsigned long long)buffer_info->dma, | ||
292 | buffer_info->length, buffer_info->next_to_watch, | ||
293 | (unsigned long long)buffer_info->time_stamp, | ||
294 | buffer_info->skb, next_desc); | ||
305 | 295 | ||
306 | if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) | 296 | if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) |
307 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, | 297 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, |
@@ -312,9 +302,9 @@ static void e1000e_dump(struct e1000_adapter *adapter) | |||
312 | /* Print Rx Ring Summary */ | 302 | /* Print Rx Ring Summary */ |
313 | rx_ring_summary: | 303 | rx_ring_summary: |
314 | dev_info(&adapter->pdev->dev, "Rx Ring Summary\n"); | 304 | dev_info(&adapter->pdev->dev, "Rx Ring Summary\n"); |
315 | printk(KERN_INFO "Queue [NTU] [NTC]\n"); | 305 | pr_info("Queue [NTU] [NTC]\n"); |
316 | printk(KERN_INFO " %5d %5X %5X\n", 0, | 306 | pr_info(" %5d %5X %5X\n", |
317 | rx_ring->next_to_use, rx_ring->next_to_clean); | 307 | 0, rx_ring->next_to_use, rx_ring->next_to_clean); |
318 | 308 | ||
319 | /* Print Rx Ring */ | 309 | /* Print Rx Ring */ |
320 | if (!netif_msg_rx_status(adapter)) | 310 | if (!netif_msg_rx_status(adapter)) |
@@ -337,10 +327,7 @@ rx_ring_summary: | |||
337 | * 24 | Buffer Address 3 [63:0] | | 327 | * 24 | Buffer Address 3 [63:0] | |
338 | * +-----------------------------------------------------+ | 328 | * +-----------------------------------------------------+ |
339 | */ | 329 | */ |
340 | printk(KERN_INFO "R [desc] [buffer 0 63:0 ] " | 330 | pr_info("R [desc] [buffer 0 63:0 ] [buffer 1 63:0 ] [buffer 2 63:0 ] [buffer 3 63:0 ] [bi->dma ] [bi->skb] <-- Ext Pkt Split format\n"); |
341 | "[buffer 1 63:0 ] " | ||
342 | "[buffer 2 63:0 ] [buffer 3 63:0 ] [bi->dma ] " | ||
343 | "[bi->skb] <-- Ext Pkt Split format\n"); | ||
344 | /* [Extended] Receive Descriptor (Write-Back) Format | 331 | /* [Extended] Receive Descriptor (Write-Back) Format |
345 | * | 332 | * |
346 | * 63 48 47 32 31 13 12 8 7 4 3 0 | 333 | * 63 48 47 32 31 13 12 8 7 4 3 0 |
@@ -352,35 +339,40 @@ rx_ring_summary: | |||
352 | * +------------------------------------------------------+ | 339 | * +------------------------------------------------------+ |
353 | * 63 48 47 32 31 20 19 0 | 340 | * 63 48 47 32 31 20 19 0 |
354 | */ | 341 | */ |
355 | printk(KERN_INFO "RWB[desc] [ck ipid mrqhsh] " | 342 | pr_info("RWB[desc] [ck ipid mrqhsh] [vl l0 ee es] [ l3 l2 l1 hs] [reserved ] ---------------- [bi->skb] <-- Ext Rx Write-Back format\n"); |
356 | "[vl l0 ee es] " | ||
357 | "[ l3 l2 l1 hs] [reserved ] ---------------- " | ||
358 | "[bi->skb] <-- Ext Rx Write-Back format\n"); | ||
359 | for (i = 0; i < rx_ring->count; i++) { | 343 | for (i = 0; i < rx_ring->count; i++) { |
344 | const char *next_desc; | ||
360 | buffer_info = &rx_ring->buffer_info[i]; | 345 | buffer_info = &rx_ring->buffer_info[i]; |
361 | rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i); | 346 | rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i); |
362 | u1 = (struct my_u1 *)rx_desc_ps; | 347 | u1 = (struct my_u1 *)rx_desc_ps; |
363 | staterr = | 348 | staterr = |
364 | le32_to_cpu(rx_desc_ps->wb.middle.status_error); | 349 | le32_to_cpu(rx_desc_ps->wb.middle.status_error); |
350 | |||
351 | if (i == rx_ring->next_to_use) | ||
352 | next_desc = " NTU"; | ||
353 | else if (i == rx_ring->next_to_clean) | ||
354 | next_desc = " NTC"; | ||
355 | else | ||
356 | next_desc = ""; | ||
357 | |||
365 | if (staterr & E1000_RXD_STAT_DD) { | 358 | if (staterr & E1000_RXD_STAT_DD) { |
366 | /* Descriptor Done */ | 359 | /* Descriptor Done */ |
367 | printk(KERN_INFO "RWB[0x%03X] %016llX " | 360 | pr_info("%s[0x%03X] %016llX %016llX %016llX %016llX ---------------- %p%s\n", |
368 | "%016llX %016llX %016llX " | 361 | "RWB", i, |
369 | "---------------- %p", i, | 362 | (unsigned long long)le64_to_cpu(u1->a), |
370 | (unsigned long long)le64_to_cpu(u1->a), | 363 | (unsigned long long)le64_to_cpu(u1->b), |
371 | (unsigned long long)le64_to_cpu(u1->b), | 364 | (unsigned long long)le64_to_cpu(u1->c), |
372 | (unsigned long long)le64_to_cpu(u1->c), | 365 | (unsigned long long)le64_to_cpu(u1->d), |
373 | (unsigned long long)le64_to_cpu(u1->d), | 366 | buffer_info->skb, next_desc); |
374 | buffer_info->skb); | ||
375 | } else { | 367 | } else { |
376 | printk(KERN_INFO "R [0x%03X] %016llX " | 368 | pr_info("%s[0x%03X] %016llX %016llX %016llX %016llX %016llX %p%s\n", |
377 | "%016llX %016llX %016llX %016llX %p", i, | 369 | "R ", i, |
378 | (unsigned long long)le64_to_cpu(u1->a), | 370 | (unsigned long long)le64_to_cpu(u1->a), |
379 | (unsigned long long)le64_to_cpu(u1->b), | 371 | (unsigned long long)le64_to_cpu(u1->b), |
380 | (unsigned long long)le64_to_cpu(u1->c), | 372 | (unsigned long long)le64_to_cpu(u1->c), |
381 | (unsigned long long)le64_to_cpu(u1->d), | 373 | (unsigned long long)le64_to_cpu(u1->d), |
382 | (unsigned long long)buffer_info->dma, | 374 | (unsigned long long)buffer_info->dma, |
383 | buffer_info->skb); | 375 | buffer_info->skb, next_desc); |
384 | 376 | ||
385 | if (netif_msg_pktdata(adapter)) | 377 | if (netif_msg_pktdata(adapter)) |
386 | print_hex_dump(KERN_INFO, "", | 378 | print_hex_dump(KERN_INFO, "", |
@@ -388,13 +380,6 @@ rx_ring_summary: | |||
388 | phys_to_virt(buffer_info->dma), | 380 | phys_to_virt(buffer_info->dma), |
389 | adapter->rx_ps_bsize0, true); | 381 | adapter->rx_ps_bsize0, true); |
390 | } | 382 | } |
391 | |||
392 | if (i == rx_ring->next_to_use) | ||
393 | printk(KERN_CONT " NTU\n"); | ||
394 | else if (i == rx_ring->next_to_clean) | ||
395 | printk(KERN_CONT " NTC\n"); | ||
396 | else | ||
397 | printk(KERN_CONT "\n"); | ||
398 | } | 383 | } |
399 | break; | 384 | break; |
400 | default: | 385 | default: |
@@ -407,9 +392,7 @@ rx_ring_summary: | |||
407 | * 8 | Reserved | | 392 | * 8 | Reserved | |
408 | * +-----------------------------------------------------+ | 393 | * +-----------------------------------------------------+ |
409 | */ | 394 | */ |
410 | printk(KERN_INFO "R [desc] [buf addr 63:0 ] " | 395 | pr_info("R [desc] [buf addr 63:0 ] [reserved 63:0 ] [bi->dma ] [bi->skb] <-- Ext (Read) format\n"); |
411 | "[reserved 63:0 ] [bi->dma ] " | ||
412 | "[bi->skb] <-- Ext (Read) format\n"); | ||
413 | /* Extended Receive Descriptor (Write-Back) Format | 396 | /* Extended Receive Descriptor (Write-Back) Format |
414 | * | 397 | * |
415 | * 63 48 47 32 31 24 23 4 3 0 | 398 | * 63 48 47 32 31 24 23 4 3 0 |
@@ -423,29 +406,37 @@ rx_ring_summary: | |||
423 | * +------------------------------------------------------+ | 406 | * +------------------------------------------------------+ |
424 | * 63 48 47 32 31 20 19 0 | 407 | * 63 48 47 32 31 20 19 0 |
425 | */ | 408 | */ |
426 | printk(KERN_INFO "RWB[desc] [cs ipid mrq] " | 409 | pr_info("RWB[desc] [cs ipid mrq] [vt ln xe xs] [bi->skb] <-- Ext (Write-Back) format\n"); |
427 | "[vt ln xe xs] " | ||
428 | "[bi->skb] <-- Ext (Write-Back) format\n"); | ||
429 | 410 | ||
430 | for (i = 0; i < rx_ring->count; i++) { | 411 | for (i = 0; i < rx_ring->count; i++) { |
412 | const char *next_desc; | ||
413 | |||
431 | buffer_info = &rx_ring->buffer_info[i]; | 414 | buffer_info = &rx_ring->buffer_info[i]; |
432 | rx_desc = E1000_RX_DESC_EXT(*rx_ring, i); | 415 | rx_desc = E1000_RX_DESC_EXT(*rx_ring, i); |
433 | u1 = (struct my_u1 *)rx_desc; | 416 | u1 = (struct my_u1 *)rx_desc; |
434 | staterr = le32_to_cpu(rx_desc->wb.upper.status_error); | 417 | staterr = le32_to_cpu(rx_desc->wb.upper.status_error); |
418 | |||
419 | if (i == rx_ring->next_to_use) | ||
420 | next_desc = " NTU"; | ||
421 | else if (i == rx_ring->next_to_clean) | ||
422 | next_desc = " NTC"; | ||
423 | else | ||
424 | next_desc = ""; | ||
425 | |||
435 | if (staterr & E1000_RXD_STAT_DD) { | 426 | if (staterr & E1000_RXD_STAT_DD) { |
436 | /* Descriptor Done */ | 427 | /* Descriptor Done */ |
437 | printk(KERN_INFO "RWB[0x%03X] %016llX " | 428 | pr_info("%s[0x%03X] %016llX %016llX ---------------- %p%s\n", |
438 | "%016llX ---------------- %p", i, | 429 | "RWB", i, |
439 | (unsigned long long)le64_to_cpu(u1->a), | 430 | (unsigned long long)le64_to_cpu(u1->a), |
440 | (unsigned long long)le64_to_cpu(u1->b), | 431 | (unsigned long long)le64_to_cpu(u1->b), |
441 | buffer_info->skb); | 432 | buffer_info->skb, next_desc); |
442 | } else { | 433 | } else { |
443 | printk(KERN_INFO "R [0x%03X] %016llX " | 434 | pr_info("%s[0x%03X] %016llX %016llX %016llX %p%s\n", |
444 | "%016llX %016llX %p", i, | 435 | "R ", i, |
445 | (unsigned long long)le64_to_cpu(u1->a), | 436 | (unsigned long long)le64_to_cpu(u1->a), |
446 | (unsigned long long)le64_to_cpu(u1->b), | 437 | (unsigned long long)le64_to_cpu(u1->b), |
447 | (unsigned long long)buffer_info->dma, | 438 | (unsigned long long)buffer_info->dma, |
448 | buffer_info->skb); | 439 | buffer_info->skb, next_desc); |
449 | 440 | ||
450 | if (netif_msg_pktdata(adapter)) | 441 | if (netif_msg_pktdata(adapter)) |
451 | print_hex_dump(KERN_INFO, "", | 442 | print_hex_dump(KERN_INFO, "", |
@@ -456,13 +447,6 @@ rx_ring_summary: | |||
456 | adapter->rx_buffer_len, | 447 | adapter->rx_buffer_len, |
457 | true); | 448 | true); |
458 | } | 449 | } |
459 | |||
460 | if (i == rx_ring->next_to_use) | ||
461 | printk(KERN_CONT " NTU\n"); | ||
462 | else if (i == rx_ring->next_to_clean) | ||
463 | printk(KERN_CONT " NTC\n"); | ||
464 | else | ||
465 | printk(KERN_CONT "\n"); | ||
466 | } | 450 | } |
467 | } | 451 | } |
468 | 452 | ||
@@ -1222,8 +1206,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
1222 | adapter->flags2 |= FLAG2_IS_DISCARDING; | 1206 | adapter->flags2 |= FLAG2_IS_DISCARDING; |
1223 | 1207 | ||
1224 | if (adapter->flags2 & FLAG2_IS_DISCARDING) { | 1208 | if (adapter->flags2 & FLAG2_IS_DISCARDING) { |
1225 | e_dbg("Packet Split buffers didn't pick up the full " | 1209 | e_dbg("Packet Split buffers didn't pick up the full packet\n"); |
1226 | "packet\n"); | ||
1227 | dev_kfree_skb_irq(skb); | 1210 | dev_kfree_skb_irq(skb); |
1228 | if (staterr & E1000_RXD_STAT_EOP) | 1211 | if (staterr & E1000_RXD_STAT_EOP) |
1229 | adapter->flags2 &= ~FLAG2_IS_DISCARDING; | 1212 | adapter->flags2 &= ~FLAG2_IS_DISCARDING; |
@@ -1238,8 +1221,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
1238 | length = le16_to_cpu(rx_desc->wb.middle.length0); | 1221 | length = le16_to_cpu(rx_desc->wb.middle.length0); |
1239 | 1222 | ||
1240 | if (!length) { | 1223 | if (!length) { |
1241 | e_dbg("Last part of the packet spanning multiple " | 1224 | e_dbg("Last part of the packet spanning multiple descriptors\n"); |
1242 | "descriptors\n"); | ||
1243 | dev_kfree_skb_irq(skb); | 1225 | dev_kfree_skb_irq(skb); |
1244 | goto next_desc; | 1226 | goto next_desc; |
1245 | } | 1227 | } |
@@ -1917,8 +1899,7 @@ void e1000e_set_interrupt_capability(struct e1000_adapter *adapter) | |||
1917 | return; | 1899 | return; |
1918 | } | 1900 | } |
1919 | /* MSI-X failed, so fall through and try MSI */ | 1901 | /* MSI-X failed, so fall through and try MSI */ |
1920 | e_err("Failed to initialize MSI-X interrupts. " | 1902 | e_err("Failed to initialize MSI-X interrupts. Falling back to MSI interrupts.\n"); |
1921 | "Falling back to MSI interrupts.\n"); | ||
1922 | e1000e_reset_interrupt_capability(adapter); | 1903 | e1000e_reset_interrupt_capability(adapter); |
1923 | } | 1904 | } |
1924 | adapter->int_mode = E1000E_INT_MODE_MSI; | 1905 | adapter->int_mode = E1000E_INT_MODE_MSI; |
@@ -1928,8 +1909,7 @@ void e1000e_set_interrupt_capability(struct e1000_adapter *adapter) | |||
1928 | adapter->flags |= FLAG_MSI_ENABLED; | 1909 | adapter->flags |= FLAG_MSI_ENABLED; |
1929 | } else { | 1910 | } else { |
1930 | adapter->int_mode = E1000E_INT_MODE_LEGACY; | 1911 | adapter->int_mode = E1000E_INT_MODE_LEGACY; |
1931 | e_err("Failed to initialize MSI interrupts. Falling " | 1912 | e_err("Failed to initialize MSI interrupts. Falling back to legacy interrupts.\n"); |
1932 | "back to legacy interrupts.\n"); | ||
1933 | } | 1913 | } |
1934 | /* Fall through */ | 1914 | /* Fall through */ |
1935 | case E1000E_INT_MODE_LEGACY: | 1915 | case E1000E_INT_MODE_LEGACY: |
@@ -3113,79 +3093,147 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) | |||
3113 | } | 3093 | } |
3114 | 3094 | ||
3115 | /** | 3095 | /** |
3116 | * e1000_update_mc_addr_list - Update Multicast addresses | 3096 | * e1000e_write_mc_addr_list - write multicast addresses to MTA |
3117 | * @hw: pointer to the HW structure | 3097 | * @netdev: network interface device structure |
3118 | * @mc_addr_list: array of multicast addresses to program | 3098 | * |
3119 | * @mc_addr_count: number of multicast addresses to program | 3099 | * Writes multicast address list to the MTA hash table. |
3100 | * Returns: -ENOMEM on failure | ||
3101 | * 0 on no addresses written | ||
3102 | * X on writing X addresses to MTA | ||
3103 | */ | ||
3104 | static int e1000e_write_mc_addr_list(struct net_device *netdev) | ||
3105 | { | ||
3106 | struct e1000_adapter *adapter = netdev_priv(netdev); | ||
3107 | struct e1000_hw *hw = &adapter->hw; | ||
3108 | struct netdev_hw_addr *ha; | ||
3109 | u8 *mta_list; | ||
3110 | int i; | ||
3111 | |||
3112 | if (netdev_mc_empty(netdev)) { | ||
3113 | /* nothing to program, so clear mc list */ | ||
3114 | hw->mac.ops.update_mc_addr_list(hw, NULL, 0); | ||
3115 | return 0; | ||
3116 | } | ||
3117 | |||
3118 | mta_list = kzalloc(netdev_mc_count(netdev) * ETH_ALEN, GFP_ATOMIC); | ||
3119 | if (!mta_list) | ||
3120 | return -ENOMEM; | ||
3121 | |||
3122 | /* update_mc_addr_list expects a packed array of only addresses. */ | ||
3123 | i = 0; | ||
3124 | netdev_for_each_mc_addr(ha, netdev) | ||
3125 | memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN); | ||
3126 | |||
3127 | hw->mac.ops.update_mc_addr_list(hw, mta_list, i); | ||
3128 | kfree(mta_list); | ||
3129 | |||
3130 | return netdev_mc_count(netdev); | ||
3131 | } | ||
3132 | |||
3133 | /** | ||
3134 | * e1000e_write_uc_addr_list - write unicast addresses to RAR table | ||
3135 | * @netdev: network interface device structure | ||
3120 | * | 3136 | * |
3121 | * Updates the Multicast Table Array. | 3137 | * Writes unicast address list to the RAR table. |
3122 | * The caller must have a packed mc_addr_list of multicast addresses. | 3138 | * Returns: -ENOMEM on failure/insufficient address space |
3139 | * 0 on no addresses written | ||
3140 | * X on writing X addresses to the RAR table | ||
3123 | **/ | 3141 | **/ |
3124 | static void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list, | 3142 | static int e1000e_write_uc_addr_list(struct net_device *netdev) |
3125 | u32 mc_addr_count) | ||
3126 | { | 3143 | { |
3127 | hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count); | 3144 | struct e1000_adapter *adapter = netdev_priv(netdev); |
3145 | struct e1000_hw *hw = &adapter->hw; | ||
3146 | unsigned int rar_entries = hw->mac.rar_entry_count; | ||
3147 | int count = 0; | ||
3148 | |||
3149 | /* save a rar entry for our hardware address */ | ||
3150 | rar_entries--; | ||
3151 | |||
3152 | /* save a rar entry for the LAA workaround */ | ||
3153 | if (adapter->flags & FLAG_RESET_OVERWRITES_LAA) | ||
3154 | rar_entries--; | ||
3155 | |||
3156 | /* return ENOMEM indicating insufficient memory for addresses */ | ||
3157 | if (netdev_uc_count(netdev) > rar_entries) | ||
3158 | return -ENOMEM; | ||
3159 | |||
3160 | if (!netdev_uc_empty(netdev) && rar_entries) { | ||
3161 | struct netdev_hw_addr *ha; | ||
3162 | |||
3163 | /* | ||
3164 | * write the addresses in reverse order to avoid write | ||
3165 | * combining | ||
3166 | */ | ||
3167 | netdev_for_each_uc_addr(ha, netdev) { | ||
3168 | if (!rar_entries) | ||
3169 | break; | ||
3170 | e1000e_rar_set(hw, ha->addr, rar_entries--); | ||
3171 | count++; | ||
3172 | } | ||
3173 | } | ||
3174 | |||
3175 | /* zero out the remaining RAR entries not used above */ | ||
3176 | for (; rar_entries > 0; rar_entries--) { | ||
3177 | ew32(RAH(rar_entries), 0); | ||
3178 | ew32(RAL(rar_entries), 0); | ||
3179 | } | ||
3180 | e1e_flush(); | ||
3181 | |||
3182 | return count; | ||
3128 | } | 3183 | } |
3129 | 3184 | ||
3130 | /** | 3185 | /** |
3131 | * e1000_set_multi - Multicast and Promiscuous mode set | 3186 | * e1000e_set_rx_mode - secondary unicast, Multicast and Promiscuous mode set |
3132 | * @netdev: network interface device structure | 3187 | * @netdev: network interface device structure |
3133 | * | 3188 | * |
3134 | * The set_multi entry point is called whenever the multicast address | 3189 | * The ndo_set_rx_mode entry point is called whenever the unicast or multicast |
3135 | * list or the network interface flags are updated. This routine is | 3190 | * address list or the network interface flags are updated. This routine is |
3136 | * responsible for configuring the hardware for proper multicast, | 3191 | * responsible for configuring the hardware for proper unicast, multicast, |
3137 | * promiscuous mode, and all-multi behavior. | 3192 | * promiscuous mode, and all-multi behavior. |
3138 | **/ | 3193 | **/ |
3139 | static void e1000_set_multi(struct net_device *netdev) | 3194 | static void e1000e_set_rx_mode(struct net_device *netdev) |
3140 | { | 3195 | { |
3141 | struct e1000_adapter *adapter = netdev_priv(netdev); | 3196 | struct e1000_adapter *adapter = netdev_priv(netdev); |
3142 | struct e1000_hw *hw = &adapter->hw; | 3197 | struct e1000_hw *hw = &adapter->hw; |
3143 | struct netdev_hw_addr *ha; | ||
3144 | u8 *mta_list; | ||
3145 | u32 rctl; | 3198 | u32 rctl; |
3146 | 3199 | ||
3147 | /* Check for Promiscuous and All Multicast modes */ | 3200 | /* Check for Promiscuous and All Multicast modes */ |
3148 | |||
3149 | rctl = er32(RCTL); | 3201 | rctl = er32(RCTL); |
3150 | 3202 | ||
3203 | /* clear the affected bits */ | ||
3204 | rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); | ||
3205 | |||
3151 | if (netdev->flags & IFF_PROMISC) { | 3206 | if (netdev->flags & IFF_PROMISC) { |
3152 | rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); | 3207 | rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); |
3153 | rctl &= ~E1000_RCTL_VFE; | ||
3154 | /* Do not hardware filter VLANs in promisc mode */ | 3208 | /* Do not hardware filter VLANs in promisc mode */ |
3155 | e1000e_vlan_filter_disable(adapter); | 3209 | e1000e_vlan_filter_disable(adapter); |
3156 | } else { | 3210 | } else { |
3211 | int count; | ||
3157 | if (netdev->flags & IFF_ALLMULTI) { | 3212 | if (netdev->flags & IFF_ALLMULTI) { |
3158 | rctl |= E1000_RCTL_MPE; | 3213 | rctl |= E1000_RCTL_MPE; |
3159 | rctl &= ~E1000_RCTL_UPE; | ||
3160 | } else { | 3214 | } else { |
3161 | rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); | 3215 | /* |
3216 | * Write addresses to the MTA, if the attempt fails | ||
3217 | * then we should just turn on promiscuous mode so | ||
3218 | * that we can at least receive multicast traffic | ||
3219 | */ | ||
3220 | count = e1000e_write_mc_addr_list(netdev); | ||
3221 | if (count < 0) | ||
3222 | rctl |= E1000_RCTL_MPE; | ||
3162 | } | 3223 | } |
3163 | e1000e_vlan_filter_enable(adapter); | 3224 | e1000e_vlan_filter_enable(adapter); |
3164 | } | ||
3165 | |||
3166 | ew32(RCTL, rctl); | ||
3167 | |||
3168 | if (!netdev_mc_empty(netdev)) { | ||
3169 | int i = 0; | ||
3170 | |||
3171 | mta_list = kmalloc(netdev_mc_count(netdev) * 6, GFP_ATOMIC); | ||
3172 | if (!mta_list) | ||
3173 | return; | ||
3174 | |||
3175 | /* prepare a packed array of only addresses. */ | ||
3176 | netdev_for_each_mc_addr(ha, netdev) | ||
3177 | memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN); | ||
3178 | |||
3179 | e1000_update_mc_addr_list(hw, mta_list, i); | ||
3180 | kfree(mta_list); | ||
3181 | } else { | ||
3182 | /* | 3225 | /* |
3183 | * if we're called from probe, we might not have | 3226 | * Write addresses to available RAR registers, if there is not |
3184 | * anything to do here, so clear out the list | 3227 | * sufficient space to store all the addresses then enable |
3228 | * unicast promiscuous mode | ||
3185 | */ | 3229 | */ |
3186 | e1000_update_mc_addr_list(hw, NULL, 0); | 3230 | count = e1000e_write_uc_addr_list(netdev); |
3231 | if (count < 0) | ||
3232 | rctl |= E1000_RCTL_UPE; | ||
3187 | } | 3233 | } |
3188 | 3234 | ||
3235 | ew32(RCTL, rctl); | ||
3236 | |||
3189 | if (netdev->features & NETIF_F_HW_VLAN_RX) | 3237 | if (netdev->features & NETIF_F_HW_VLAN_RX) |
3190 | e1000e_vlan_strip_enable(adapter); | 3238 | e1000e_vlan_strip_enable(adapter); |
3191 | else | 3239 | else |
@@ -3198,7 +3246,7 @@ static void e1000_set_multi(struct net_device *netdev) | |||
3198 | **/ | 3246 | **/ |
3199 | static void e1000_configure(struct e1000_adapter *adapter) | 3247 | static void e1000_configure(struct e1000_adapter *adapter) |
3200 | { | 3248 | { |
3201 | e1000_set_multi(adapter->netdev); | 3249 | e1000e_set_rx_mode(adapter->netdev); |
3202 | 3250 | ||
3203 | e1000_restore_vlan(adapter); | 3251 | e1000_restore_vlan(adapter); |
3204 | e1000_init_manageability_pt(adapter); | 3252 | e1000_init_manageability_pt(adapter); |
@@ -4168,16 +4216,13 @@ static void e1000_print_link_info(struct e1000_adapter *adapter) | |||
4168 | u32 ctrl = er32(CTRL); | 4216 | u32 ctrl = er32(CTRL); |
4169 | 4217 | ||
4170 | /* Link status message must follow this format for user tools */ | 4218 | /* Link status message must follow this format for user tools */ |
4171 | printk(KERN_INFO "e1000e: %s NIC Link is Up %d Mbps %s, " | 4219 | printk(KERN_INFO "e1000e: %s NIC Link is Up %d Mbps %s Duplex, Flow Control: %s\n", |
4172 | "Flow Control: %s\n", | 4220 | adapter->netdev->name, |
4173 | adapter->netdev->name, | 4221 | adapter->link_speed, |
4174 | adapter->link_speed, | 4222 | adapter->link_duplex == FULL_DUPLEX ? "Full" : "Half", |
4175 | (adapter->link_duplex == FULL_DUPLEX) ? | 4223 | (ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE) ? "Rx/Tx" : |
4176 | "Full Duplex" : "Half Duplex", | 4224 | (ctrl & E1000_CTRL_RFCE) ? "Rx" : |
4177 | ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ? | 4225 | (ctrl & E1000_CTRL_TFCE) ? "Tx" : "None"); |
4178 | "Rx/Tx" : | ||
4179 | ((ctrl & E1000_CTRL_RFCE) ? "Rx" : | ||
4180 | ((ctrl & E1000_CTRL_TFCE) ? "Tx" : "None"))); | ||
4181 | } | 4226 | } |
4182 | 4227 | ||
4183 | static bool e1000e_has_link(struct e1000_adapter *adapter) | 4228 | static bool e1000e_has_link(struct e1000_adapter *adapter) |
@@ -4323,10 +4368,7 @@ static void e1000_watchdog_task(struct work_struct *work) | |||
4323 | e1e_rphy(hw, PHY_AUTONEG_EXP, &autoneg_exp); | 4368 | e1e_rphy(hw, PHY_AUTONEG_EXP, &autoneg_exp); |
4324 | 4369 | ||
4325 | if (!(autoneg_exp & NWAY_ER_LP_NWAY_CAPS)) | 4370 | if (!(autoneg_exp & NWAY_ER_LP_NWAY_CAPS)) |
4326 | e_info("Autonegotiated half duplex but" | 4371 | e_info("Autonegotiated half duplex but link partner cannot autoneg. Try forcing full duplex if link gets many collisions.\n"); |
4327 | " link partner cannot autoneg. " | ||
4328 | " Try forcing full duplex if " | ||
4329 | "link gets many collisions.\n"); | ||
4330 | } | 4372 | } |
4331 | 4373 | ||
4332 | /* adjust timeout factor according to speed/duplex */ | 4374 | /* adjust timeout factor according to speed/duplex */ |
@@ -5110,8 +5152,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
5110 | if ((adapter->hw.mac.type == e1000_pch2lan) && | 5152 | if ((adapter->hw.mac.type == e1000_pch2lan) && |
5111 | !(adapter->flags2 & FLAG2_CRC_STRIPPING) && | 5153 | !(adapter->flags2 & FLAG2_CRC_STRIPPING) && |
5112 | (new_mtu > ETH_DATA_LEN)) { | 5154 | (new_mtu > ETH_DATA_LEN)) { |
5113 | e_err("Jumbo Frames not supported on 82579 when CRC " | 5155 | e_err("Jumbo Frames not supported on 82579 when CRC stripping is disabled.\n"); |
5114 | "stripping is disabled.\n"); | ||
5115 | return -EINVAL; | 5156 | return -EINVAL; |
5116 | } | 5157 | } |
5117 | 5158 | ||
@@ -5331,7 +5372,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, | |||
5331 | 5372 | ||
5332 | if (wufc) { | 5373 | if (wufc) { |
5333 | e1000_setup_rctl(adapter); | 5374 | e1000_setup_rctl(adapter); |
5334 | e1000_set_multi(netdev); | 5375 | e1000e_set_rx_mode(netdev); |
5335 | 5376 | ||
5336 | /* turn on all-multi mode if wake on multicast is enabled */ | 5377 | /* turn on all-multi mode if wake on multicast is enabled */ |
5337 | if (wufc & E1000_WUFC_MC) { | 5378 | if (wufc & E1000_WUFC_MC) { |
@@ -5527,8 +5568,8 @@ static int __e1000_resume(struct pci_dev *pdev) | |||
5527 | phy_data & E1000_WUS_MC ? "Multicast Packet" : | 5568 | phy_data & E1000_WUS_MC ? "Multicast Packet" : |
5528 | phy_data & E1000_WUS_BC ? "Broadcast Packet" : | 5569 | phy_data & E1000_WUS_BC ? "Broadcast Packet" : |
5529 | phy_data & E1000_WUS_MAG ? "Magic Packet" : | 5570 | phy_data & E1000_WUS_MAG ? "Magic Packet" : |
5530 | phy_data & E1000_WUS_LNKC ? "Link Status " | 5571 | phy_data & E1000_WUS_LNKC ? |
5531 | " Change" : "other"); | 5572 | "Link Status Change" : "other"); |
5532 | } | 5573 | } |
5533 | e1e_wphy(&adapter->hw, BM_WUS, ~0); | 5574 | e1e_wphy(&adapter->hw, BM_WUS, ~0); |
5534 | } else { | 5575 | } else { |
@@ -5859,10 +5900,11 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter) | |||
5859 | } | 5900 | } |
5860 | } | 5901 | } |
5861 | 5902 | ||
5862 | static int e1000_set_features(struct net_device *netdev, u32 features) | 5903 | static int e1000_set_features(struct net_device *netdev, |
5904 | netdev_features_t features) | ||
5863 | { | 5905 | { |
5864 | struct e1000_adapter *adapter = netdev_priv(netdev); | 5906 | struct e1000_adapter *adapter = netdev_priv(netdev); |
5865 | u32 changed = features ^ netdev->features; | 5907 | netdev_features_t changed = features ^ netdev->features; |
5866 | 5908 | ||
5867 | if (changed & (NETIF_F_TSO | NETIF_F_TSO6)) | 5909 | if (changed & (NETIF_F_TSO | NETIF_F_TSO6)) |
5868 | adapter->flags |= FLAG_TSO_FORCE; | 5910 | adapter->flags |= FLAG_TSO_FORCE; |
@@ -5884,7 +5926,7 @@ static const struct net_device_ops e1000e_netdev_ops = { | |||
5884 | .ndo_stop = e1000_close, | 5926 | .ndo_stop = e1000_close, |
5885 | .ndo_start_xmit = e1000_xmit_frame, | 5927 | .ndo_start_xmit = e1000_xmit_frame, |
5886 | .ndo_get_stats64 = e1000e_get_stats64, | 5928 | .ndo_get_stats64 = e1000e_get_stats64, |
5887 | .ndo_set_rx_mode = e1000_set_multi, | 5929 | .ndo_set_rx_mode = e1000e_set_rx_mode, |
5888 | .ndo_set_mac_address = e1000_set_mac, | 5930 | .ndo_set_mac_address = e1000_set_mac, |
5889 | .ndo_change_mtu = e1000_change_mtu, | 5931 | .ndo_change_mtu = e1000_change_mtu, |
5890 | .ndo_do_ioctl = e1000_ioctl, | 5932 | .ndo_do_ioctl = e1000_ioctl, |
@@ -5949,8 +5991,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
5949 | err = dma_set_coherent_mask(&pdev->dev, | 5991 | err = dma_set_coherent_mask(&pdev->dev, |
5950 | DMA_BIT_MASK(32)); | 5992 | DMA_BIT_MASK(32)); |
5951 | if (err) { | 5993 | if (err) { |
5952 | dev_err(&pdev->dev, "No usable DMA " | 5994 | dev_err(&pdev->dev, "No usable DMA configuration, aborting\n"); |
5953 | "configuration, aborting\n"); | ||
5954 | goto err_dma; | 5995 | goto err_dma; |
5955 | } | 5996 | } |
5956 | } | 5997 | } |
@@ -6076,6 +6117,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
6076 | NETIF_F_TSO6 | | 6117 | NETIF_F_TSO6 | |
6077 | NETIF_F_HW_CSUM); | 6118 | NETIF_F_HW_CSUM); |
6078 | 6119 | ||
6120 | netdev->priv_flags |= IFF_UNICAST_FLT; | ||
6121 | |||
6079 | if (pci_using_dac) { | 6122 | if (pci_using_dac) { |
6080 | netdev->features |= NETIF_F_HIGHDMA; | 6123 | netdev->features |= NETIF_F_HIGHDMA; |
6081 | netdev->vlan_features |= NETIF_F_HIGHDMA; | 6124 | netdev->vlan_features |= NETIF_F_HIGHDMA; |
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 7881fb95a25b..b8e20f037d0a 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c | |||
@@ -29,6 +29,8 @@ | |||
29 | * e1000_82576 | 29 | * e1000_82576 |
30 | */ | 30 | */ |
31 | 31 | ||
32 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
33 | |||
32 | #include <linux/types.h> | 34 | #include <linux/types.h> |
33 | #include <linux/if_ether.h> | 35 | #include <linux/if_ether.h> |
34 | 36 | ||
@@ -244,8 +246,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
244 | * Check for invalid size | 246 | * Check for invalid size |
245 | */ | 247 | */ |
246 | if ((hw->mac.type == e1000_82576) && (size > 15)) { | 248 | if ((hw->mac.type == e1000_82576) && (size > 15)) { |
247 | printk("igb: The NVM size is not valid, " | 249 | pr_notice("The NVM size is not valid, defaulting to 32K\n"); |
248 | "defaulting to 32K.\n"); | ||
249 | size = 15; | 250 | size = 15; |
250 | } | 251 | } |
251 | nvm->word_size = 1 << size; | 252 | nvm->word_size = 1 << size; |
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index 43873eba2f63..e9335efac386 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c | |||
@@ -673,25 +673,22 @@ static void igb_get_drvinfo(struct net_device *netdev, | |||
673 | struct ethtool_drvinfo *drvinfo) | 673 | struct ethtool_drvinfo *drvinfo) |
674 | { | 674 | { |
675 | struct igb_adapter *adapter = netdev_priv(netdev); | 675 | struct igb_adapter *adapter = netdev_priv(netdev); |
676 | char firmware_version[32]; | ||
677 | u16 eeprom_data; | 676 | u16 eeprom_data; |
678 | 677 | ||
679 | strncpy(drvinfo->driver, igb_driver_name, sizeof(drvinfo->driver) - 1); | 678 | strlcpy(drvinfo->driver, igb_driver_name, sizeof(drvinfo->driver)); |
680 | strncpy(drvinfo->version, igb_driver_version, | 679 | strlcpy(drvinfo->version, igb_driver_version, sizeof(drvinfo->version)); |
681 | sizeof(drvinfo->version) - 1); | ||
682 | 680 | ||
683 | /* EEPROM image version # is reported as firmware version # for | 681 | /* EEPROM image version # is reported as firmware version # for |
684 | * 82575 controllers */ | 682 | * 82575 controllers */ |
685 | adapter->hw.nvm.ops.read(&adapter->hw, 5, 1, &eeprom_data); | 683 | adapter->hw.nvm.ops.read(&adapter->hw, 5, 1, &eeprom_data); |
686 | sprintf(firmware_version, "%d.%d-%d", | 684 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), |
685 | "%d.%d-%d", | ||
687 | (eeprom_data & 0xF000) >> 12, | 686 | (eeprom_data & 0xF000) >> 12, |
688 | (eeprom_data & 0x0FF0) >> 4, | 687 | (eeprom_data & 0x0FF0) >> 4, |
689 | eeprom_data & 0x000F); | 688 | eeprom_data & 0x000F); |
690 | 689 | ||
691 | strncpy(drvinfo->fw_version, firmware_version, | 690 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), |
692 | sizeof(drvinfo->fw_version) - 1); | 691 | sizeof(drvinfo->bus_info)); |
693 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), | ||
694 | sizeof(drvinfo->bus_info) - 1); | ||
695 | drvinfo->n_stats = IGB_STATS_LEN; | 692 | drvinfo->n_stats = IGB_STATS_LEN; |
696 | drvinfo->testinfo_len = IGB_TEST_LEN; | 693 | drvinfo->testinfo_len = IGB_TEST_LEN; |
697 | drvinfo->regdump_len = igb_get_regs_len(netdev); | 694 | drvinfo->regdump_len = igb_get_regs_len(netdev); |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index ced544499f1b..b66b8aa751e7 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -25,6 +25,8 @@ | |||
25 | 25 | ||
26 | *******************************************************************************/ | 26 | *******************************************************************************/ |
27 | 27 | ||
28 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
29 | |||
28 | #include <linux/module.h> | 30 | #include <linux/module.h> |
29 | #include <linux/types.h> | 31 | #include <linux/types.h> |
30 | #include <linux/init.h> | 32 | #include <linux/init.h> |
@@ -145,7 +147,7 @@ static bool igb_clean_rx_irq(struct igb_q_vector *, int); | |||
145 | static int igb_ioctl(struct net_device *, struct ifreq *, int cmd); | 147 | static int igb_ioctl(struct net_device *, struct ifreq *, int cmd); |
146 | static void igb_tx_timeout(struct net_device *); | 148 | static void igb_tx_timeout(struct net_device *); |
147 | static void igb_reset_task(struct work_struct *); | 149 | static void igb_reset_task(struct work_struct *); |
148 | static void igb_vlan_mode(struct net_device *netdev, u32 features); | 150 | static void igb_vlan_mode(struct net_device *netdev, netdev_features_t features); |
149 | static void igb_vlan_rx_add_vid(struct net_device *, u16); | 151 | static void igb_vlan_rx_add_vid(struct net_device *, u16); |
150 | static void igb_vlan_rx_kill_vid(struct net_device *, u16); | 152 | static void igb_vlan_rx_kill_vid(struct net_device *, u16); |
151 | static void igb_restore_vlan(struct igb_adapter *); | 153 | static void igb_restore_vlan(struct igb_adapter *); |
@@ -325,16 +327,13 @@ static void igb_regdump(struct e1000_hw *hw, struct igb_reg_info *reginfo) | |||
325 | regs[n] = rd32(E1000_TXDCTL(n)); | 327 | regs[n] = rd32(E1000_TXDCTL(n)); |
326 | break; | 328 | break; |
327 | default: | 329 | default: |
328 | printk(KERN_INFO "%-15s %08x\n", | 330 | pr_info("%-15s %08x\n", reginfo->name, rd32(reginfo->ofs)); |
329 | reginfo->name, rd32(reginfo->ofs)); | ||
330 | return; | 331 | return; |
331 | } | 332 | } |
332 | 333 | ||
333 | snprintf(rname, 16, "%s%s", reginfo->name, "[0-3]"); | 334 | snprintf(rname, 16, "%s%s", reginfo->name, "[0-3]"); |
334 | printk(KERN_INFO "%-15s ", rname); | 335 | pr_info("%-15s %08x %08x %08x %08x\n", rname, regs[0], regs[1], |
335 | for (n = 0; n < 4; n++) | 336 | regs[2], regs[3]); |
336 | printk(KERN_CONT "%08x ", regs[n]); | ||
337 | printk(KERN_CONT "\n"); | ||
338 | } | 337 | } |
339 | 338 | ||
340 | /* | 339 | /* |
@@ -359,18 +358,15 @@ static void igb_dump(struct igb_adapter *adapter) | |||
359 | /* Print netdevice Info */ | 358 | /* Print netdevice Info */ |
360 | if (netdev) { | 359 | if (netdev) { |
361 | dev_info(&adapter->pdev->dev, "Net device Info\n"); | 360 | dev_info(&adapter->pdev->dev, "Net device Info\n"); |
362 | printk(KERN_INFO "Device Name state " | 361 | pr_info("Device Name state trans_start " |
363 | "trans_start last_rx\n"); | 362 | "last_rx\n"); |
364 | printk(KERN_INFO "%-15s %016lX %016lX %016lX\n", | 363 | pr_info("%-15s %016lX %016lX %016lX\n", netdev->name, |
365 | netdev->name, | 364 | netdev->state, netdev->trans_start, netdev->last_rx); |
366 | netdev->state, | ||
367 | netdev->trans_start, | ||
368 | netdev->last_rx); | ||
369 | } | 365 | } |
370 | 366 | ||
371 | /* Print Registers */ | 367 | /* Print Registers */ |
372 | dev_info(&adapter->pdev->dev, "Register Dump\n"); | 368 | dev_info(&adapter->pdev->dev, "Register Dump\n"); |
373 | printk(KERN_INFO " Register Name Value\n"); | 369 | pr_info(" Register Name Value\n"); |
374 | for (reginfo = (struct igb_reg_info *)igb_reg_info_tbl; | 370 | for (reginfo = (struct igb_reg_info *)igb_reg_info_tbl; |
375 | reginfo->name; reginfo++) { | 371 | reginfo->name; reginfo++) { |
376 | igb_regdump(hw, reginfo); | 372 | igb_regdump(hw, reginfo); |
@@ -381,18 +377,17 @@ static void igb_dump(struct igb_adapter *adapter) | |||
381 | goto exit; | 377 | goto exit; |
382 | 378 | ||
383 | dev_info(&adapter->pdev->dev, "TX Rings Summary\n"); | 379 | dev_info(&adapter->pdev->dev, "TX Rings Summary\n"); |
384 | printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma ]" | 380 | pr_info("Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp\n"); |
385 | " leng ntw timestamp\n"); | ||
386 | for (n = 0; n < adapter->num_tx_queues; n++) { | 381 | for (n = 0; n < adapter->num_tx_queues; n++) { |
387 | struct igb_tx_buffer *buffer_info; | 382 | struct igb_tx_buffer *buffer_info; |
388 | tx_ring = adapter->tx_ring[n]; | 383 | tx_ring = adapter->tx_ring[n]; |
389 | buffer_info = &tx_ring->tx_buffer_info[tx_ring->next_to_clean]; | 384 | buffer_info = &tx_ring->tx_buffer_info[tx_ring->next_to_clean]; |
390 | printk(KERN_INFO " %5d %5X %5X %016llX %04X %p %016llX\n", | 385 | pr_info(" %5d %5X %5X %016llX %04X %p %016llX\n", |
391 | n, tx_ring->next_to_use, tx_ring->next_to_clean, | 386 | n, tx_ring->next_to_use, tx_ring->next_to_clean, |
392 | (u64)buffer_info->dma, | 387 | (u64)buffer_info->dma, |
393 | buffer_info->length, | 388 | buffer_info->length, |
394 | buffer_info->next_to_watch, | 389 | buffer_info->next_to_watch, |
395 | (u64)buffer_info->time_stamp); | 390 | (u64)buffer_info->time_stamp); |
396 | } | 391 | } |
397 | 392 | ||
398 | /* Print TX Rings */ | 393 | /* Print TX Rings */ |
@@ -414,36 +409,38 @@ static void igb_dump(struct igb_adapter *adapter) | |||
414 | 409 | ||
415 | for (n = 0; n < adapter->num_tx_queues; n++) { | 410 | for (n = 0; n < adapter->num_tx_queues; n++) { |
416 | tx_ring = adapter->tx_ring[n]; | 411 | tx_ring = adapter->tx_ring[n]; |
417 | printk(KERN_INFO "------------------------------------\n"); | 412 | pr_info("------------------------------------\n"); |
418 | printk(KERN_INFO "TX QUEUE INDEX = %d\n", tx_ring->queue_index); | 413 | pr_info("TX QUEUE INDEX = %d\n", tx_ring->queue_index); |
419 | printk(KERN_INFO "------------------------------------\n"); | 414 | pr_info("------------------------------------\n"); |
420 | printk(KERN_INFO "T [desc] [address 63:0 ] " | 415 | pr_info("T [desc] [address 63:0 ] [PlPOCIStDDM Ln] " |
421 | "[PlPOCIStDDM Ln] [bi->dma ] " | 416 | "[bi->dma ] leng ntw timestamp " |
422 | "leng ntw timestamp bi->skb\n"); | 417 | "bi->skb\n"); |
423 | 418 | ||
424 | for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { | 419 | for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { |
420 | const char *next_desc; | ||
425 | struct igb_tx_buffer *buffer_info; | 421 | struct igb_tx_buffer *buffer_info; |
426 | tx_desc = IGB_TX_DESC(tx_ring, i); | 422 | tx_desc = IGB_TX_DESC(tx_ring, i); |
427 | buffer_info = &tx_ring->tx_buffer_info[i]; | 423 | buffer_info = &tx_ring->tx_buffer_info[i]; |
428 | u0 = (struct my_u0 *)tx_desc; | 424 | u0 = (struct my_u0 *)tx_desc; |
429 | printk(KERN_INFO "T [0x%03X] %016llX %016llX %016llX" | 425 | if (i == tx_ring->next_to_use && |
430 | " %04X %p %016llX %p", i, | 426 | i == tx_ring->next_to_clean) |
427 | next_desc = " NTC/U"; | ||
428 | else if (i == tx_ring->next_to_use) | ||
429 | next_desc = " NTU"; | ||
430 | else if (i == tx_ring->next_to_clean) | ||
431 | next_desc = " NTC"; | ||
432 | else | ||
433 | next_desc = ""; | ||
434 | |||
435 | pr_info("T [0x%03X] %016llX %016llX %016llX" | ||
436 | " %04X %p %016llX %p%s\n", i, | ||
431 | le64_to_cpu(u0->a), | 437 | le64_to_cpu(u0->a), |
432 | le64_to_cpu(u0->b), | 438 | le64_to_cpu(u0->b), |
433 | (u64)buffer_info->dma, | 439 | (u64)buffer_info->dma, |
434 | buffer_info->length, | 440 | buffer_info->length, |
435 | buffer_info->next_to_watch, | 441 | buffer_info->next_to_watch, |
436 | (u64)buffer_info->time_stamp, | 442 | (u64)buffer_info->time_stamp, |
437 | buffer_info->skb); | 443 | buffer_info->skb, next_desc); |
438 | if (i == tx_ring->next_to_use && | ||
439 | i == tx_ring->next_to_clean) | ||
440 | printk(KERN_CONT " NTC/U\n"); | ||
441 | else if (i == tx_ring->next_to_use) | ||
442 | printk(KERN_CONT " NTU\n"); | ||
443 | else if (i == tx_ring->next_to_clean) | ||
444 | printk(KERN_CONT " NTC\n"); | ||
445 | else | ||
446 | printk(KERN_CONT "\n"); | ||
447 | 444 | ||
448 | if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) | 445 | if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) |
449 | print_hex_dump(KERN_INFO, "", | 446 | print_hex_dump(KERN_INFO, "", |
@@ -456,11 +453,11 @@ static void igb_dump(struct igb_adapter *adapter) | |||
456 | /* Print RX Rings Summary */ | 453 | /* Print RX Rings Summary */ |
457 | rx_ring_summary: | 454 | rx_ring_summary: |
458 | dev_info(&adapter->pdev->dev, "RX Rings Summary\n"); | 455 | dev_info(&adapter->pdev->dev, "RX Rings Summary\n"); |
459 | printk(KERN_INFO "Queue [NTU] [NTC]\n"); | 456 | pr_info("Queue [NTU] [NTC]\n"); |
460 | for (n = 0; n < adapter->num_rx_queues; n++) { | 457 | for (n = 0; n < adapter->num_rx_queues; n++) { |
461 | rx_ring = adapter->rx_ring[n]; | 458 | rx_ring = adapter->rx_ring[n]; |
462 | printk(KERN_INFO " %5d %5X %5X\n", n, | 459 | pr_info(" %5d %5X %5X\n", |
463 | rx_ring->next_to_use, rx_ring->next_to_clean); | 460 | n, rx_ring->next_to_use, rx_ring->next_to_clean); |
464 | } | 461 | } |
465 | 462 | ||
466 | /* Print RX Rings */ | 463 | /* Print RX Rings */ |
@@ -492,36 +489,43 @@ rx_ring_summary: | |||
492 | 489 | ||
493 | for (n = 0; n < adapter->num_rx_queues; n++) { | 490 | for (n = 0; n < adapter->num_rx_queues; n++) { |
494 | rx_ring = adapter->rx_ring[n]; | 491 | rx_ring = adapter->rx_ring[n]; |
495 | printk(KERN_INFO "------------------------------------\n"); | 492 | pr_info("------------------------------------\n"); |
496 | printk(KERN_INFO "RX QUEUE INDEX = %d\n", rx_ring->queue_index); | 493 | pr_info("RX QUEUE INDEX = %d\n", rx_ring->queue_index); |
497 | printk(KERN_INFO "------------------------------------\n"); | 494 | pr_info("------------------------------------\n"); |
498 | printk(KERN_INFO "R [desc] [ PktBuf A0] " | 495 | pr_info("R [desc] [ PktBuf A0] [ HeadBuf DD] " |
499 | "[ HeadBuf DD] [bi->dma ] [bi->skb] " | 496 | "[bi->dma ] [bi->skb] <-- Adv Rx Read format\n"); |
500 | "<-- Adv Rx Read format\n"); | 497 | pr_info("RWB[desc] [PcsmIpSHl PtRs] [vl er S cks ln] -----" |
501 | printk(KERN_INFO "RWB[desc] [PcsmIpSHl PtRs] " | 498 | "----------- [bi->skb] <-- Adv Rx Write-Back format\n"); |
502 | "[vl er S cks ln] ---------------- [bi->skb] " | ||
503 | "<-- Adv Rx Write-Back format\n"); | ||
504 | 499 | ||
505 | for (i = 0; i < rx_ring->count; i++) { | 500 | for (i = 0; i < rx_ring->count; i++) { |
501 | const char *next_desc; | ||
506 | struct igb_rx_buffer *buffer_info; | 502 | struct igb_rx_buffer *buffer_info; |
507 | buffer_info = &rx_ring->rx_buffer_info[i]; | 503 | buffer_info = &rx_ring->rx_buffer_info[i]; |
508 | rx_desc = IGB_RX_DESC(rx_ring, i); | 504 | rx_desc = IGB_RX_DESC(rx_ring, i); |
509 | u0 = (struct my_u0 *)rx_desc; | 505 | u0 = (struct my_u0 *)rx_desc; |
510 | staterr = le32_to_cpu(rx_desc->wb.upper.status_error); | 506 | staterr = le32_to_cpu(rx_desc->wb.upper.status_error); |
507 | |||
508 | if (i == rx_ring->next_to_use) | ||
509 | next_desc = " NTU"; | ||
510 | else if (i == rx_ring->next_to_clean) | ||
511 | next_desc = " NTC"; | ||
512 | else | ||
513 | next_desc = ""; | ||
514 | |||
511 | if (staterr & E1000_RXD_STAT_DD) { | 515 | if (staterr & E1000_RXD_STAT_DD) { |
512 | /* Descriptor Done */ | 516 | /* Descriptor Done */ |
513 | printk(KERN_INFO "RWB[0x%03X] %016llX " | 517 | pr_info("%s[0x%03X] %016llX %016llX -------" |
514 | "%016llX ---------------- %p", i, | 518 | "--------- %p%s\n", "RWB", i, |
515 | le64_to_cpu(u0->a), | 519 | le64_to_cpu(u0->a), |
516 | le64_to_cpu(u0->b), | 520 | le64_to_cpu(u0->b), |
517 | buffer_info->skb); | 521 | buffer_info->skb, next_desc); |
518 | } else { | 522 | } else { |
519 | printk(KERN_INFO "R [0x%03X] %016llX " | 523 | pr_info("%s[0x%03X] %016llX %016llX %016llX" |
520 | "%016llX %016llX %p", i, | 524 | " %p%s\n", "R ", i, |
521 | le64_to_cpu(u0->a), | 525 | le64_to_cpu(u0->a), |
522 | le64_to_cpu(u0->b), | 526 | le64_to_cpu(u0->b), |
523 | (u64)buffer_info->dma, | 527 | (u64)buffer_info->dma, |
524 | buffer_info->skb); | 528 | buffer_info->skb, next_desc); |
525 | 529 | ||
526 | if (netif_msg_pktdata(adapter)) { | 530 | if (netif_msg_pktdata(adapter)) { |
527 | print_hex_dump(KERN_INFO, "", | 531 | print_hex_dump(KERN_INFO, "", |
@@ -538,14 +542,6 @@ rx_ring_summary: | |||
538 | PAGE_SIZE/2, true); | 542 | PAGE_SIZE/2, true); |
539 | } | 543 | } |
540 | } | 544 | } |
541 | |||
542 | if (i == rx_ring->next_to_use) | ||
543 | printk(KERN_CONT " NTU\n"); | ||
544 | else if (i == rx_ring->next_to_clean) | ||
545 | printk(KERN_CONT " NTC\n"); | ||
546 | else | ||
547 | printk(KERN_CONT "\n"); | ||
548 | |||
549 | } | 545 | } |
550 | } | 546 | } |
551 | 547 | ||
@@ -599,10 +595,10 @@ struct net_device *igb_get_hw_dev(struct e1000_hw *hw) | |||
599 | static int __init igb_init_module(void) | 595 | static int __init igb_init_module(void) |
600 | { | 596 | { |
601 | int ret; | 597 | int ret; |
602 | printk(KERN_INFO "%s - version %s\n", | 598 | pr_info("%s - version %s\n", |
603 | igb_driver_string, igb_driver_version); | 599 | igb_driver_string, igb_driver_version); |
604 | 600 | ||
605 | printk(KERN_INFO "%s\n", igb_copyright); | 601 | pr_info("%s\n", igb_copyright); |
606 | 602 | ||
607 | #ifdef CONFIG_IGB_DCA | 603 | #ifdef CONFIG_IGB_DCA |
608 | dca_register_notify(&dca_notifier); | 604 | dca_register_notify(&dca_notifier); |
@@ -1742,7 +1738,8 @@ void igb_reset(struct igb_adapter *adapter) | |||
1742 | igb_get_phy_info(hw); | 1738 | igb_get_phy_info(hw); |
1743 | } | 1739 | } |
1744 | 1740 | ||
1745 | static u32 igb_fix_features(struct net_device *netdev, u32 features) | 1741 | static netdev_features_t igb_fix_features(struct net_device *netdev, |
1742 | netdev_features_t features) | ||
1746 | { | 1743 | { |
1747 | /* | 1744 | /* |
1748 | * Since there is no support for separate rx/tx vlan accel | 1745 | * Since there is no support for separate rx/tx vlan accel |
@@ -1756,9 +1753,10 @@ static u32 igb_fix_features(struct net_device *netdev, u32 features) | |||
1756 | return features; | 1753 | return features; |
1757 | } | 1754 | } |
1758 | 1755 | ||
1759 | static int igb_set_features(struct net_device *netdev, u32 features) | 1756 | static int igb_set_features(struct net_device *netdev, |
1757 | netdev_features_t features) | ||
1760 | { | 1758 | { |
1761 | u32 changed = netdev->features ^ features; | 1759 | netdev_features_t changed = netdev->features ^ features; |
1762 | 1760 | ||
1763 | if (changed & NETIF_F_HW_VLAN_RX) | 1761 | if (changed & NETIF_F_HW_VLAN_RX) |
1764 | igb_vlan_mode(netdev, features); | 1762 | igb_vlan_mode(netdev, features); |
@@ -3640,23 +3638,23 @@ static void igb_watchdog_task(struct work_struct *work) | |||
3640 | 3638 | ||
3641 | ctrl = rd32(E1000_CTRL); | 3639 | ctrl = rd32(E1000_CTRL); |
3642 | /* Links status message must follow this format */ | 3640 | /* Links status message must follow this format */ |
3643 | printk(KERN_INFO "igb: %s NIC Link is Up %d Mbps %s, " | 3641 | printk(KERN_INFO "igb: %s NIC Link is Up %d Mbps %s " |
3644 | "Flow Control: %s\n", | 3642 | "Duplex, Flow Control: %s\n", |
3645 | netdev->name, | 3643 | netdev->name, |
3646 | adapter->link_speed, | 3644 | adapter->link_speed, |
3647 | adapter->link_duplex == FULL_DUPLEX ? | 3645 | adapter->link_duplex == FULL_DUPLEX ? |
3648 | "Full Duplex" : "Half Duplex", | 3646 | "Full" : "Half", |
3649 | ((ctrl & E1000_CTRL_TFCE) && | 3647 | (ctrl & E1000_CTRL_TFCE) && |
3650 | (ctrl & E1000_CTRL_RFCE)) ? "RX/TX" : | 3648 | (ctrl & E1000_CTRL_RFCE) ? "RX/TX" : |
3651 | ((ctrl & E1000_CTRL_RFCE) ? "RX" : | 3649 | (ctrl & E1000_CTRL_RFCE) ? "RX" : |
3652 | ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None"))); | 3650 | (ctrl & E1000_CTRL_TFCE) ? "TX" : "None"); |
3653 | 3651 | ||
3654 | /* check for thermal sensor event */ | 3652 | /* check for thermal sensor event */ |
3655 | if (igb_thermal_sensor_event(hw, E1000_THSTAT_LINK_THROTTLE)) { | 3653 | if (igb_thermal_sensor_event(hw, |
3656 | printk(KERN_INFO "igb: %s The network adapter " | 3654 | E1000_THSTAT_LINK_THROTTLE)) { |
3657 | "link speed was downshifted " | 3655 | netdev_info(netdev, "The network adapter link " |
3658 | "because it overheated.\n", | 3656 | "speed was downshifted because it " |
3659 | netdev->name); | 3657 | "overheated\n"); |
3660 | } | 3658 | } |
3661 | 3659 | ||
3662 | /* adjust timeout factor according to speed/duplex */ | 3660 | /* adjust timeout factor according to speed/duplex */ |
@@ -3686,11 +3684,10 @@ static void igb_watchdog_task(struct work_struct *work) | |||
3686 | adapter->link_duplex = 0; | 3684 | adapter->link_duplex = 0; |
3687 | 3685 | ||
3688 | /* check for thermal sensor event */ | 3686 | /* check for thermal sensor event */ |
3689 | if (igb_thermal_sensor_event(hw, E1000_THSTAT_PWR_DOWN)) { | 3687 | if (igb_thermal_sensor_event(hw, |
3690 | printk(KERN_ERR "igb: %s The network adapter " | 3688 | E1000_THSTAT_PWR_DOWN)) { |
3691 | "was stopped because it " | 3689 | netdev_err(netdev, "The network adapter was " |
3692 | "overheated.\n", | 3690 | "stopped because it overheated\n"); |
3693 | netdev->name); | ||
3694 | } | 3691 | } |
3695 | 3692 | ||
3696 | /* Links status message must follow this format */ | 3693 | /* Links status message must follow this format */ |
@@ -6138,7 +6135,7 @@ static bool igb_alloc_mapped_page(struct igb_ring *rx_ring, | |||
6138 | return true; | 6135 | return true; |
6139 | 6136 | ||
6140 | if (!page) { | 6137 | if (!page) { |
6141 | page = netdev_alloc_page(rx_ring->netdev); | 6138 | page = alloc_page(GFP_ATOMIC | __GFP_COLD); |
6142 | bi->page = page; | 6139 | bi->page = page; |
6143 | if (unlikely(!page)) { | 6140 | if (unlikely(!page)) { |
6144 | rx_ring->rx_stats.alloc_failed++; | 6141 | rx_ring->rx_stats.alloc_failed++; |
@@ -6467,7 +6464,7 @@ s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value) | |||
6467 | return 0; | 6464 | return 0; |
6468 | } | 6465 | } |
6469 | 6466 | ||
6470 | static void igb_vlan_mode(struct net_device *netdev, u32 features) | 6467 | static void igb_vlan_mode(struct net_device *netdev, netdev_features_t features) |
6471 | { | 6468 | { |
6472 | struct igb_adapter *adapter = netdev_priv(netdev); | 6469 | struct igb_adapter *adapter = netdev_priv(netdev); |
6473 | struct e1000_hw *hw = &adapter->hw; | 6470 | struct e1000_hw *hw = &adapter->hw; |
diff --git a/drivers/net/ethernet/intel/igbvf/ethtool.c b/drivers/net/ethernet/intel/igbvf/ethtool.c index 2c25858cc0ff..7b600a1f6366 100644 --- a/drivers/net/ethernet/intel/igbvf/ethtool.c +++ b/drivers/net/ethernet/intel/igbvf/ethtool.c | |||
@@ -191,12 +191,12 @@ static void igbvf_get_drvinfo(struct net_device *netdev, | |||
191 | struct ethtool_drvinfo *drvinfo) | 191 | struct ethtool_drvinfo *drvinfo) |
192 | { | 192 | { |
193 | struct igbvf_adapter *adapter = netdev_priv(netdev); | 193 | struct igbvf_adapter *adapter = netdev_priv(netdev); |
194 | char firmware_version[32] = "N/A"; | ||
195 | 194 | ||
196 | strncpy(drvinfo->driver, igbvf_driver_name, 32); | 195 | strlcpy(drvinfo->driver, igbvf_driver_name, sizeof(drvinfo->driver)); |
197 | strncpy(drvinfo->version, igbvf_driver_version, 32); | 196 | strlcpy(drvinfo->version, igbvf_driver_version, |
198 | strncpy(drvinfo->fw_version, firmware_version, 32); | 197 | sizeof(drvinfo->version)); |
199 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | 198 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), |
199 | sizeof(drvinfo->bus_info)); | ||
200 | drvinfo->regdump_len = igbvf_get_regs_len(netdev); | 200 | drvinfo->regdump_len = igbvf_get_regs_len(netdev); |
201 | drvinfo->eedump_len = igbvf_get_eeprom_len(netdev); | 201 | drvinfo->eedump_len = igbvf_get_eeprom_len(netdev); |
202 | } | 202 | } |
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index cca78124be31..c358973ce414 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c | |||
@@ -25,6 +25,8 @@ | |||
25 | 25 | ||
26 | *******************************************************************************/ | 26 | *******************************************************************************/ |
27 | 27 | ||
28 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
29 | |||
28 | #include <linux/module.h> | 30 | #include <linux/module.h> |
29 | #include <linux/types.h> | 31 | #include <linux/types.h> |
30 | #include <linux/init.h> | 32 | #include <linux/init.h> |
@@ -1746,10 +1748,9 @@ void igbvf_update_stats(struct igbvf_adapter *adapter) | |||
1746 | 1748 | ||
1747 | static void igbvf_print_link_info(struct igbvf_adapter *adapter) | 1749 | static void igbvf_print_link_info(struct igbvf_adapter *adapter) |
1748 | { | 1750 | { |
1749 | dev_info(&adapter->pdev->dev, "Link is Up %d Mbps %s\n", | 1751 | dev_info(&adapter->pdev->dev, "Link is Up %d Mbps %s Duplex\n", |
1750 | adapter->link_speed, | 1752 | adapter->link_speed, |
1751 | ((adapter->link_duplex == FULL_DUPLEX) ? | 1753 | adapter->link_duplex == FULL_DUPLEX ? "Full" : "Half"); |
1752 | "Full Duplex" : "Half Duplex")); | ||
1753 | } | 1754 | } |
1754 | 1755 | ||
1755 | static bool igbvf_has_link(struct igbvf_adapter *adapter) | 1756 | static bool igbvf_has_link(struct igbvf_adapter *adapter) |
@@ -2532,7 +2533,8 @@ static void igbvf_print_device_info(struct igbvf_adapter *adapter) | |||
2532 | dev_info(&pdev->dev, "Address: %pM\n", netdev->dev_addr); | 2533 | dev_info(&pdev->dev, "Address: %pM\n", netdev->dev_addr); |
2533 | } | 2534 | } |
2534 | 2535 | ||
2535 | static int igbvf_set_features(struct net_device *netdev, u32 features) | 2536 | static int igbvf_set_features(struct net_device *netdev, |
2537 | netdev_features_t features) | ||
2536 | { | 2538 | { |
2537 | struct igbvf_adapter *adapter = netdev_priv(netdev); | 2539 | struct igbvf_adapter *adapter = netdev_priv(netdev); |
2538 | 2540 | ||
@@ -2842,9 +2844,8 @@ static struct pci_driver igbvf_driver = { | |||
2842 | static int __init igbvf_init_module(void) | 2844 | static int __init igbvf_init_module(void) |
2843 | { | 2845 | { |
2844 | int ret; | 2846 | int ret; |
2845 | printk(KERN_INFO "%s - version %s\n", | 2847 | pr_info("%s - version %s\n", igbvf_driver_string, igbvf_driver_version); |
2846 | igbvf_driver_string, igbvf_driver_version); | 2848 | pr_info("%s\n", igbvf_copyright); |
2847 | printk(KERN_INFO "%s\n", igbvf_copyright); | ||
2848 | 2849 | ||
2849 | ret = pci_register_driver(&igbvf_driver); | 2850 | ret = pci_register_driver(&igbvf_driver); |
2850 | 2851 | ||
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c b/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c index 9dfce7dff79b..dbb7dd2f8e36 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c | |||
@@ -473,10 +473,12 @@ ixgb_get_drvinfo(struct net_device *netdev, | |||
473 | { | 473 | { |
474 | struct ixgb_adapter *adapter = netdev_priv(netdev); | 474 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
475 | 475 | ||
476 | strncpy(drvinfo->driver, ixgb_driver_name, 32); | 476 | strlcpy(drvinfo->driver, ixgb_driver_name, |
477 | strncpy(drvinfo->version, ixgb_driver_version, 32); | 477 | sizeof(drvinfo->driver)); |
478 | strncpy(drvinfo->fw_version, "N/A", 32); | 478 | strlcpy(drvinfo->version, ixgb_driver_version, |
479 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | 479 | sizeof(drvinfo->version)); |
480 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), | ||
481 | sizeof(drvinfo->bus_info)); | ||
480 | drvinfo->n_stats = IXGB_STATS_LEN; | 482 | drvinfo->n_stats = IXGB_STATS_LEN; |
481 | drvinfo->regdump_len = ixgb_get_regs_len(netdev); | 483 | drvinfo->regdump_len = ixgb_get_regs_len(netdev); |
482 | drvinfo->eedump_len = ixgb_get_eeprom_len(netdev); | 484 | drvinfo->eedump_len = ixgb_get_eeprom_len(netdev); |
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c index e21148f8b160..247cf9219e03 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c | |||
@@ -325,8 +325,8 @@ ixgb_reset(struct ixgb_adapter *adapter) | |||
325 | } | 325 | } |
326 | } | 326 | } |
327 | 327 | ||
328 | static u32 | 328 | static netdev_features_t |
329 | ixgb_fix_features(struct net_device *netdev, u32 features) | 329 | ixgb_fix_features(struct net_device *netdev, netdev_features_t features) |
330 | { | 330 | { |
331 | /* | 331 | /* |
332 | * Tx VLAN insertion does not work per HW design when Rx stripping is | 332 | * Tx VLAN insertion does not work per HW design when Rx stripping is |
@@ -339,10 +339,10 @@ ixgb_fix_features(struct net_device *netdev, u32 features) | |||
339 | } | 339 | } |
340 | 340 | ||
341 | static int | 341 | static int |
342 | ixgb_set_features(struct net_device *netdev, u32 features) | 342 | ixgb_set_features(struct net_device *netdev, netdev_features_t features) |
343 | { | 343 | { |
344 | struct ixgb_adapter *adapter = netdev_priv(netdev); | 344 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
345 | u32 changed = features ^ netdev->features; | 345 | netdev_features_t changed = features ^ netdev->features; |
346 | 346 | ||
347 | if (!(changed & (NETIF_F_RXCSUM|NETIF_F_HW_VLAN_RX))) | 347 | if (!(changed & (NETIF_F_RXCSUM|NETIF_F_HW_VLAN_RX))) |
348 | return 0; | 348 | return 0; |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 70d58c3849b0..91f871b6b3ba 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | |||
@@ -888,23 +888,19 @@ static void ixgbe_get_drvinfo(struct net_device *netdev, | |||
888 | struct ethtool_drvinfo *drvinfo) | 888 | struct ethtool_drvinfo *drvinfo) |
889 | { | 889 | { |
890 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 890 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
891 | char firmware_version[32]; | ||
892 | u32 nvm_track_id; | 891 | u32 nvm_track_id; |
893 | 892 | ||
894 | strncpy(drvinfo->driver, ixgbe_driver_name, | 893 | strlcpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver)); |
895 | sizeof(drvinfo->driver) - 1); | 894 | strlcpy(drvinfo->version, ixgbe_driver_version, |
896 | strncpy(drvinfo->version, ixgbe_driver_version, | 895 | sizeof(drvinfo->version)); |
897 | sizeof(drvinfo->version) - 1); | ||
898 | 896 | ||
899 | nvm_track_id = (adapter->eeprom_verh << 16) | | 897 | nvm_track_id = (adapter->eeprom_verh << 16) | |
900 | adapter->eeprom_verl; | 898 | adapter->eeprom_verl; |
901 | snprintf(firmware_version, sizeof(firmware_version), "0x%08x", | 899 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "0x%08x", |
902 | nvm_track_id); | 900 | nvm_track_id); |
903 | 901 | ||
904 | strncpy(drvinfo->fw_version, firmware_version, | 902 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), |
905 | sizeof(drvinfo->fw_version) - 1); | 903 | sizeof(drvinfo->bus_info)); |
906 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), | ||
907 | sizeof(drvinfo->bus_info) - 1); | ||
908 | drvinfo->n_stats = IXGBE_STATS_LEN; | 904 | drvinfo->n_stats = IXGBE_STATS_LEN; |
909 | drvinfo->testinfo_len = IXGBE_TEST_LEN; | 905 | drvinfo->testinfo_len = IXGBE_TEST_LEN; |
910 | drvinfo->regdump_len = ixgbe_get_regs_len(netdev); | 906 | drvinfo->regdump_len = ixgbe_get_regs_len(netdev); |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 8ef92d1a6aa1..1b28ed9d8cc1 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -1140,7 +1140,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count) | |||
1140 | 1140 | ||
1141 | if (ring_is_ps_enabled(rx_ring)) { | 1141 | if (ring_is_ps_enabled(rx_ring)) { |
1142 | if (!bi->page) { | 1142 | if (!bi->page) { |
1143 | bi->page = netdev_alloc_page(rx_ring->netdev); | 1143 | bi->page = alloc_page(GFP_ATOMIC | __GFP_COLD); |
1144 | if (!bi->page) { | 1144 | if (!bi->page) { |
1145 | rx_ring->rx_stats.alloc_rx_page_failed++; | 1145 | rx_ring->rx_stats.alloc_rx_page_failed++; |
1146 | goto no_buffers; | 1146 | goto no_buffers; |
@@ -7174,7 +7174,8 @@ void ixgbe_do_reset(struct net_device *netdev) | |||
7174 | ixgbe_reset(adapter); | 7174 | ixgbe_reset(adapter); |
7175 | } | 7175 | } |
7176 | 7176 | ||
7177 | static u32 ixgbe_fix_features(struct net_device *netdev, u32 data) | 7177 | static netdev_features_t ixgbe_fix_features(struct net_device *netdev, |
7178 | netdev_features_t data) | ||
7178 | { | 7179 | { |
7179 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 7180 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
7180 | 7181 | ||
@@ -7204,7 +7205,8 @@ static u32 ixgbe_fix_features(struct net_device *netdev, u32 data) | |||
7204 | return data; | 7205 | return data; |
7205 | } | 7206 | } |
7206 | 7207 | ||
7207 | static int ixgbe_set_features(struct net_device *netdev, u32 data) | 7208 | static int ixgbe_set_features(struct net_device *netdev, |
7209 | netdev_features_t data) | ||
7208 | { | 7210 | { |
7209 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 7211 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
7210 | bool need_reset = false; | 7212 | bool need_reset = false; |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 00fcd39ad666..cf6812dd1436 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | |||
@@ -572,7 +572,7 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) | |||
572 | 572 | ||
573 | /* reply to reset with ack and vf mac address */ | 573 | /* reply to reset with ack and vf mac address */ |
574 | msgbuf[0] = IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK; | 574 | msgbuf[0] = IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK; |
575 | memcpy(new_mac, vf_mac, IXGBE_ETH_LENGTH_OF_ADDRESS); | 575 | memcpy(new_mac, vf_mac, ETH_ALEN); |
576 | /* | 576 | /* |
577 | * Piggyback the multicast filter type so VF can compute the | 577 | * Piggyback the multicast filter type so VF can compute the |
578 | * correct vectors | 578 | * correct vectors |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 6c5cca808bd7..242643a69b3f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | |||
@@ -1710,8 +1710,6 @@ enum { | |||
1710 | #define IXGBE_NVM_POLL_WRITE 1 /* Flag for polling for write complete */ | 1710 | #define IXGBE_NVM_POLL_WRITE 1 /* Flag for polling for write complete */ |
1711 | #define IXGBE_NVM_POLL_READ 0 /* Flag for polling for read complete */ | 1711 | #define IXGBE_NVM_POLL_READ 0 /* Flag for polling for read complete */ |
1712 | 1712 | ||
1713 | #define IXGBE_ETH_LENGTH_OF_ADDRESS 6 | ||
1714 | |||
1715 | #define IXGBE_EEPROM_PAGE_SIZE_MAX 128 | 1713 | #define IXGBE_EEPROM_PAGE_SIZE_MAX 128 |
1716 | #define IXGBE_EEPROM_RD_BUFFER_MAX_COUNT 512 /* EEPROM words # read in burst */ | 1714 | #define IXGBE_EEPROM_RD_BUFFER_MAX_COUNT 512 /* EEPROM words # read in burst */ |
1717 | #define IXGBE_EEPROM_WR_BUFFER_MAX_COUNT 256 /* EEPROM words # wr in burst */ | 1715 | #define IXGBE_EEPROM_WR_BUFFER_MAX_COUNT 256 /* EEPROM words # wr in burst */ |
@@ -2802,9 +2800,9 @@ struct ixgbe_eeprom_info { | |||
2802 | struct ixgbe_mac_info { | 2800 | struct ixgbe_mac_info { |
2803 | struct ixgbe_mac_operations ops; | 2801 | struct ixgbe_mac_operations ops; |
2804 | enum ixgbe_mac_type type; | 2802 | enum ixgbe_mac_type type; |
2805 | u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; | 2803 | u8 addr[ETH_ALEN]; |
2806 | u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; | 2804 | u8 perm_addr[ETH_ALEN]; |
2807 | u8 san_addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; | 2805 | u8 san_addr[ETH_ALEN]; |
2808 | /* prefix for World Wide Node Name (WWNN) */ | 2806 | /* prefix for World Wide Node Name (WWNN) */ |
2809 | u16 wwnn_prefix; | 2807 | u16 wwnn_prefix; |
2810 | /* prefix for World Wide Port Name (WWPN) */ | 2808 | /* prefix for World Wide Port Name (WWPN) */ |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c index e5101e91b6b5..8cc5eccfd651 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c | |||
@@ -751,16 +751,20 @@ static s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index) | |||
751 | { | 751 | { |
752 | u32 macc_reg; | 752 | u32 macc_reg; |
753 | u32 ledctl_reg; | 753 | u32 ledctl_reg; |
754 | ixgbe_link_speed speed; | ||
755 | bool link_up; | ||
754 | 756 | ||
755 | /* | 757 | /* |
756 | * In order for the blink bit in the LED control register | 758 | * Link should be up in order for the blink bit in the LED control |
757 | * to work, link and speed must be forced in the MAC. We | 759 | * register to work. Force link and speed in the MAC if link is down. |
758 | * will reverse this when we stop the blinking. | 760 | * This will be reversed when we stop the blinking. |
759 | */ | 761 | */ |
760 | macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); | 762 | hw->mac.ops.check_link(hw, &speed, &link_up, false); |
761 | macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS; | 763 | if (link_up == false) { |
762 | IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); | 764 | macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC); |
763 | 765 | macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS; | |
766 | IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg); | ||
767 | } | ||
764 | /* Set the LED to LINK_UP + BLINK. */ | 768 | /* Set the LED to LINK_UP + BLINK. */ |
765 | ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | 769 | ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); |
766 | ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); | 770 | ledctl_reg &= ~IXGBE_LED_MODE_MASK(index); |
diff --git a/drivers/net/ethernet/intel/ixgbevf/defines.h b/drivers/net/ethernet/intel/ixgbevf/defines.h index 78abb6f1a866..2eb89cb94a0d 100644 --- a/drivers/net/ethernet/intel/ixgbevf/defines.h +++ b/drivers/net/ethernet/intel/ixgbevf/defines.h | |||
@@ -35,7 +35,6 @@ | |||
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 1 |
37 | #define IXGBE_VF_MAX_RX_QUEUES 1 | 37 | #define IXGBE_VF_MAX_RX_QUEUES 1 |
38 | #define IXGBE_ETH_LENGTH_OF_ADDRESS 6 | ||
39 | 38 | ||
40 | /* Link speed */ | 39 | /* Link speed */ |
41 | typedef u32 ixgbe_link_speed; | 40 | typedef u32 ixgbe_link_speed; |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c index e29ba4506b74..dc8e6511c640 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c +++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c | |||
@@ -27,6 +27,8 @@ | |||
27 | 27 | ||
28 | /* ethtool support for ixgbevf */ | 28 | /* ethtool support for ixgbevf */ |
29 | 29 | ||
30 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
31 | |||
30 | #include <linux/types.h> | 32 | #include <linux/types.h> |
31 | #include <linux/module.h> | 33 | #include <linux/module.h> |
32 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
@@ -265,11 +267,11 @@ static void ixgbevf_get_drvinfo(struct net_device *netdev, | |||
265 | { | 267 | { |
266 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); | 268 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); |
267 | 269 | ||
268 | strlcpy(drvinfo->driver, ixgbevf_driver_name, 32); | 270 | strlcpy(drvinfo->driver, ixgbevf_driver_name, sizeof(drvinfo->driver)); |
269 | strlcpy(drvinfo->version, ixgbevf_driver_version, 32); | 271 | strlcpy(drvinfo->version, ixgbevf_driver_version, |
270 | 272 | sizeof(drvinfo->version)); | |
271 | strlcpy(drvinfo->fw_version, "N/A", 4); | 273 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), |
272 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | 274 | sizeof(drvinfo->bus_info)); |
273 | } | 275 | } |
274 | 276 | ||
275 | static void ixgbevf_get_ringparam(struct net_device *netdev, | 277 | static void ixgbevf_get_ringparam(struct net_device *netdev, |
@@ -549,8 +551,8 @@ static const u32 register_test_patterns[] = { | |||
549 | writel((W & M), (adapter->hw.hw_addr + R)); \ | 551 | writel((W & M), (adapter->hw.hw_addr + R)); \ |
550 | val = readl(adapter->hw.hw_addr + R); \ | 552 | val = readl(adapter->hw.hw_addr + R); \ |
551 | if ((W & M) != (val & M)) { \ | 553 | if ((W & M) != (val & M)) { \ |
552 | printk(KERN_ERR "set/check reg %04X test failed: got 0x%08X " \ | 554 | pr_err("set/check reg %04X test failed: got 0x%08X expected " \ |
553 | "expected 0x%08X\n", R, (val & M), (W & M)); \ | 555 | "0x%08X\n", R, (val & M), (W & M)); \ |
554 | *data = R; \ | 556 | *data = R; \ |
555 | writel(before, (adapter->hw.hw_addr + R)); \ | 557 | writel(before, (adapter->hw.hw_addr + R)); \ |
556 | return 1; \ | 558 | return 1; \ |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 4c8e19951d57..5d1a64398169 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
@@ -29,6 +29,9 @@ | |||
29 | /****************************************************************************** | 29 | /****************************************************************************** |
30 | Copyright (c)2006 - 2007 Myricom, Inc. for some LRO specific code | 30 | Copyright (c)2006 - 2007 Myricom, Inc. for some LRO specific code |
31 | ******************************************************************************/ | 31 | ******************************************************************************/ |
32 | |||
33 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
34 | |||
32 | #include <linux/types.h> | 35 | #include <linux/types.h> |
33 | #include <linux/bitops.h> | 36 | #include <linux/bitops.h> |
34 | #include <linux/module.h> | 37 | #include <linux/module.h> |
@@ -363,7 +366,7 @@ static void ixgbevf_alloc_rx_buffers(struct ixgbevf_adapter *adapter, | |||
363 | if (!bi->page_dma && | 366 | if (!bi->page_dma && |
364 | (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)) { | 367 | (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)) { |
365 | if (!bi->page) { | 368 | if (!bi->page) { |
366 | bi->page = netdev_alloc_page(adapter->netdev); | 369 | bi->page = alloc_page(GFP_ATOMIC | __GFP_COLD); |
367 | if (!bi->page) { | 370 | if (!bi->page) { |
368 | adapter->alloc_rx_page_failed++; | 371 | adapter->alloc_rx_page_failed++; |
369 | goto no_buffers; | 372 | goto no_buffers; |
@@ -1437,7 +1440,7 @@ static int ixgbevf_write_uc_addr_list(struct net_device *netdev) | |||
1437 | int count = 0; | 1440 | int count = 0; |
1438 | 1441 | ||
1439 | if ((netdev_uc_count(netdev)) > 10) { | 1442 | if ((netdev_uc_count(netdev)) > 10) { |
1440 | printk(KERN_ERR "Too many unicast filters - No Space\n"); | 1443 | pr_err("Too many unicast filters - No Space\n"); |
1441 | return -ENOSPC; | 1444 | return -ENOSPC; |
1442 | } | 1445 | } |
1443 | 1446 | ||
@@ -2135,7 +2138,7 @@ static int ixgbevf_init_interrupt_scheme(struct ixgbevf_adapter *adapter) | |||
2135 | 2138 | ||
2136 | err = ixgbevf_alloc_queues(adapter); | 2139 | err = ixgbevf_alloc_queues(adapter); |
2137 | if (err) { | 2140 | if (err) { |
2138 | printk(KERN_ERR "Unable to allocate memory for queues\n"); | 2141 | pr_err("Unable to allocate memory for queues\n"); |
2139 | goto err_alloc_queues; | 2142 | goto err_alloc_queues; |
2140 | } | 2143 | } |
2141 | 2144 | ||
@@ -2189,7 +2192,7 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter) | |||
2189 | } else { | 2192 | } else { |
2190 | err = hw->mac.ops.init_hw(hw); | 2193 | err = hw->mac.ops.init_hw(hw); |
2191 | if (err) { | 2194 | if (err) { |
2192 | printk(KERN_ERR "init_shared_code failed: %d\n", err); | 2195 | pr_err("init_shared_code failed: %d\n", err); |
2193 | goto out; | 2196 | goto out; |
2194 | } | 2197 | } |
2195 | } | 2198 | } |
@@ -2630,8 +2633,8 @@ static int ixgbevf_open(struct net_device *netdev) | |||
2630 | * the vf can't start. */ | 2633 | * the vf can't start. */ |
2631 | if (hw->adapter_stopped) { | 2634 | if (hw->adapter_stopped) { |
2632 | err = IXGBE_ERR_MBX; | 2635 | err = IXGBE_ERR_MBX; |
2633 | printk(KERN_ERR "Unable to start - perhaps the PF" | 2636 | pr_err("Unable to start - perhaps the PF Driver isn't " |
2634 | " Driver isn't up yet\n"); | 2637 | "up yet\n"); |
2635 | goto err_setup_reset; | 2638 | goto err_setup_reset; |
2636 | } | 2639 | } |
2637 | } | 2640 | } |
@@ -2842,10 +2845,8 @@ static bool ixgbevf_tx_csum(struct ixgbevf_adapter *adapter, | |||
2842 | break; | 2845 | break; |
2843 | default: | 2846 | default: |
2844 | if (unlikely(net_ratelimit())) { | 2847 | if (unlikely(net_ratelimit())) { |
2845 | printk(KERN_WARNING | 2848 | pr_warn("partial checksum but " |
2846 | "partial checksum but " | 2849 | "proto=%x!\n", skb->protocol); |
2847 | "proto=%x!\n", | ||
2848 | skb->protocol); | ||
2849 | } | 2850 | } |
2850 | break; | 2851 | break; |
2851 | } | 2852 | } |
@@ -3249,7 +3250,8 @@ static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev, | |||
3249 | return stats; | 3250 | return stats; |
3250 | } | 3251 | } |
3251 | 3252 | ||
3252 | static int ixgbevf_set_features(struct net_device *netdev, u32 features) | 3253 | static int ixgbevf_set_features(struct net_device *netdev, |
3254 | netdev_features_t features) | ||
3253 | { | 3255 | { |
3254 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); | 3256 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); |
3255 | 3257 | ||
@@ -3414,7 +3416,7 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, | |||
3414 | memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len); | 3416 | memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len); |
3415 | 3417 | ||
3416 | if (!is_valid_ether_addr(netdev->dev_addr)) { | 3418 | if (!is_valid_ether_addr(netdev->dev_addr)) { |
3417 | printk(KERN_ERR "invalid MAC address\n"); | 3419 | pr_err("invalid MAC address\n"); |
3418 | err = -EIO; | 3420 | err = -EIO; |
3419 | goto err_sw_init; | 3421 | goto err_sw_init; |
3420 | } | 3422 | } |
@@ -3535,10 +3537,10 @@ static struct pci_driver ixgbevf_driver = { | |||
3535 | static int __init ixgbevf_init_module(void) | 3537 | static int __init ixgbevf_init_module(void) |
3536 | { | 3538 | { |
3537 | int ret; | 3539 | int ret; |
3538 | printk(KERN_INFO "ixgbevf: %s - version %s\n", ixgbevf_driver_string, | 3540 | pr_info("%s - version %s\n", ixgbevf_driver_string, |
3539 | ixgbevf_driver_version); | 3541 | ixgbevf_driver_version); |
3540 | 3542 | ||
3541 | printk(KERN_INFO "%s\n", ixgbevf_copyright); | 3543 | pr_info("%s\n", ixgbevf_copyright); |
3542 | 3544 | ||
3543 | ret = pci_register_driver(&ixgbevf_driver); | 3545 | ret = pci_register_driver(&ixgbevf_driver); |
3544 | return ret; | 3546 | return ret; |
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c index aa3682e8c473..21533e300367 100644 --- a/drivers/net/ethernet/intel/ixgbevf/vf.c +++ b/drivers/net/ethernet/intel/ixgbevf/vf.c | |||
@@ -108,7 +108,7 @@ static s32 ixgbevf_reset_hw_vf(struct ixgbe_hw *hw) | |||
108 | if (msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK)) | 108 | if (msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK)) |
109 | return IXGBE_ERR_INVALID_MAC_ADDR; | 109 | return IXGBE_ERR_INVALID_MAC_ADDR; |
110 | 110 | ||
111 | memcpy(hw->mac.perm_addr, addr, IXGBE_ETH_LENGTH_OF_ADDRESS); | 111 | memcpy(hw->mac.perm_addr, addr, ETH_ALEN); |
112 | hw->mac.mc_filter_type = msgbuf[IXGBE_VF_MC_TYPE_WORD]; | 112 | hw->mac.mc_filter_type = msgbuf[IXGBE_VF_MC_TYPE_WORD]; |
113 | 113 | ||
114 | return 0; | 114 | return 0; |
@@ -211,7 +211,7 @@ static s32 ixgbevf_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) | |||
211 | **/ | 211 | **/ |
212 | static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr) | 212 | static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr) |
213 | { | 213 | { |
214 | memcpy(mac_addr, hw->mac.perm_addr, IXGBE_ETH_LENGTH_OF_ADDRESS); | 214 | memcpy(mac_addr, hw->mac.perm_addr, ETH_ALEN); |
215 | 215 | ||
216 | return 0; | 216 | return 0; |
217 | } | 217 | } |
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 7becff1f387d..5c0b531949e2 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c | |||
@@ -1883,7 +1883,7 @@ jme_fill_tx_map(struct pci_dev *pdev, | |||
1883 | struct page *page, | 1883 | struct page *page, |
1884 | u32 page_offset, | 1884 | u32 page_offset, |
1885 | u32 len, | 1885 | u32 len, |
1886 | u8 hidma) | 1886 | bool hidma) |
1887 | { | 1887 | { |
1888 | dma_addr_t dmaaddr; | 1888 | dma_addr_t dmaaddr; |
1889 | 1889 | ||
@@ -1917,7 +1917,7 @@ jme_map_tx_skb(struct jme_adapter *jme, struct sk_buff *skb, int idx) | |||
1917 | struct jme_ring *txring = &(jme->txring[0]); | 1917 | struct jme_ring *txring = &(jme->txring[0]); |
1918 | struct txdesc *txdesc = txring->desc, *ctxdesc; | 1918 | struct txdesc *txdesc = txring->desc, *ctxdesc; |
1919 | struct jme_buffer_info *txbi = txring->bufinf, *ctxbi; | 1919 | struct jme_buffer_info *txbi = txring->bufinf, *ctxbi; |
1920 | u8 hidma = jme->dev->features & NETIF_F_HIGHDMA; | 1920 | bool hidma = jme->dev->features & NETIF_F_HIGHDMA; |
1921 | int i, nr_frags = skb_shinfo(skb)->nr_frags; | 1921 | int i, nr_frags = skb_shinfo(skb)->nr_frags; |
1922 | int mask = jme->tx_ring_mask; | 1922 | int mask = jme->tx_ring_mask; |
1923 | const struct skb_frag_struct *frag; | 1923 | const struct skb_frag_struct *frag; |
@@ -2292,9 +2292,9 @@ jme_get_drvinfo(struct net_device *netdev, | |||
2292 | { | 2292 | { |
2293 | struct jme_adapter *jme = netdev_priv(netdev); | 2293 | struct jme_adapter *jme = netdev_priv(netdev); |
2294 | 2294 | ||
2295 | strcpy(info->driver, DRV_NAME); | 2295 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
2296 | strcpy(info->version, DRV_VERSION); | 2296 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
2297 | strcpy(info->bus_info, pci_name(jme->pdev)); | 2297 | strlcpy(info->bus_info, pci_name(jme->pdev), sizeof(info->bus_info)); |
2298 | } | 2298 | } |
2299 | 2299 | ||
2300 | static int | 2300 | static int |
@@ -2620,8 +2620,8 @@ jme_set_msglevel(struct net_device *netdev, u32 value) | |||
2620 | jme->msg_enable = value; | 2620 | jme->msg_enable = value; |
2621 | } | 2621 | } |
2622 | 2622 | ||
2623 | static u32 | 2623 | static netdev_features_t |
2624 | jme_fix_features(struct net_device *netdev, u32 features) | 2624 | jme_fix_features(struct net_device *netdev, netdev_features_t features) |
2625 | { | 2625 | { |
2626 | if (netdev->mtu > 1900) | 2626 | if (netdev->mtu > 1900) |
2627 | features &= ~(NETIF_F_ALL_TSO | NETIF_F_ALL_CSUM); | 2627 | features &= ~(NETIF_F_ALL_TSO | NETIF_F_ALL_CSUM); |
@@ -2629,7 +2629,7 @@ jme_fix_features(struct net_device *netdev, u32 features) | |||
2629 | } | 2629 | } |
2630 | 2630 | ||
2631 | static int | 2631 | static int |
2632 | jme_set_features(struct net_device *netdev, u32 features) | 2632 | jme_set_features(struct net_device *netdev, netdev_features_t features) |
2633 | { | 2633 | { |
2634 | struct jme_adapter *jme = netdev_priv(netdev); | 2634 | struct jme_adapter *jme = netdev_priv(netdev); |
2635 | 2635 | ||
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 194a03113802..e87847e32ddb 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c | |||
@@ -1502,10 +1502,12 @@ mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
1502 | static void mv643xx_eth_get_drvinfo(struct net_device *dev, | 1502 | static void mv643xx_eth_get_drvinfo(struct net_device *dev, |
1503 | struct ethtool_drvinfo *drvinfo) | 1503 | struct ethtool_drvinfo *drvinfo) |
1504 | { | 1504 | { |
1505 | strncpy(drvinfo->driver, mv643xx_eth_driver_name, 32); | 1505 | strlcpy(drvinfo->driver, mv643xx_eth_driver_name, |
1506 | strncpy(drvinfo->version, mv643xx_eth_driver_version, 32); | 1506 | sizeof(drvinfo->driver)); |
1507 | strncpy(drvinfo->fw_version, "N/A", 32); | 1507 | strlcpy(drvinfo->version, mv643xx_eth_driver_version, |
1508 | strncpy(drvinfo->bus_info, "platform", 32); | 1508 | sizeof(drvinfo->version)); |
1509 | strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); | ||
1510 | strlcpy(drvinfo->bus_info, "platform", sizeof(drvinfo->bus_info)); | ||
1509 | drvinfo->n_stats = ARRAY_SIZE(mv643xx_eth_stats); | 1511 | drvinfo->n_stats = ARRAY_SIZE(mv643xx_eth_stats); |
1510 | } | 1512 | } |
1511 | 1513 | ||
@@ -1578,10 +1580,10 @@ mv643xx_eth_set_ringparam(struct net_device *dev, struct ethtool_ringparam *er) | |||
1578 | 1580 | ||
1579 | 1581 | ||
1580 | static int | 1582 | static int |
1581 | mv643xx_eth_set_features(struct net_device *dev, u32 features) | 1583 | mv643xx_eth_set_features(struct net_device *dev, netdev_features_t features) |
1582 | { | 1584 | { |
1583 | struct mv643xx_eth_private *mp = netdev_priv(dev); | 1585 | struct mv643xx_eth_private *mp = netdev_priv(dev); |
1584 | u32 rx_csum = features & NETIF_F_RXCSUM; | 1586 | bool rx_csum = features & NETIF_F_RXCSUM; |
1585 | 1587 | ||
1586 | wrlp(mp, PORT_CONFIG, rx_csum ? 0x02000000 : 0x00000000); | 1588 | wrlp(mp, PORT_CONFIG, rx_csum ? 0x02000000 : 0x00000000); |
1587 | 1589 | ||
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index c7b60839ac99..d957b2cf0869 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c | |||
@@ -394,10 +394,10 @@ static void skge_get_drvinfo(struct net_device *dev, | |||
394 | { | 394 | { |
395 | struct skge_port *skge = netdev_priv(dev); | 395 | struct skge_port *skge = netdev_priv(dev); |
396 | 396 | ||
397 | strcpy(info->driver, DRV_NAME); | 397 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
398 | strcpy(info->version, DRV_VERSION); | 398 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
399 | strcpy(info->fw_version, "N/A"); | 399 | strlcpy(info->bus_info, pci_name(skge->hw->pdev), |
400 | strcpy(info->bus_info, pci_name(skge->hw->pdev)); | 400 | sizeof(info->bus_info)); |
401 | } | 401 | } |
402 | 402 | ||
403 | static const struct skge_stat { | 403 | static const struct skge_stat { |
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index 7803efa46eb2..29adc7850ee4 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c | |||
@@ -1284,7 +1284,7 @@ static const uint32_t rss_init_key[10] = { | |||
1284 | }; | 1284 | }; |
1285 | 1285 | ||
1286 | /* Enable/disable receive hash calculation (RSS) */ | 1286 | /* Enable/disable receive hash calculation (RSS) */ |
1287 | static void rx_set_rss(struct net_device *dev, u32 features) | 1287 | static void rx_set_rss(struct net_device *dev, netdev_features_t features) |
1288 | { | 1288 | { |
1289 | struct sky2_port *sky2 = netdev_priv(dev); | 1289 | struct sky2_port *sky2 = netdev_priv(dev); |
1290 | struct sky2_hw *hw = sky2->hw; | 1290 | struct sky2_hw *hw = sky2->hw; |
@@ -1402,7 +1402,7 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1402 | 1402 | ||
1403 | #define SKY2_VLAN_OFFLOADS (NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO) | 1403 | #define SKY2_VLAN_OFFLOADS (NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO) |
1404 | 1404 | ||
1405 | static void sky2_vlan_mode(struct net_device *dev, u32 features) | 1405 | static void sky2_vlan_mode(struct net_device *dev, netdev_features_t features) |
1406 | { | 1406 | { |
1407 | struct sky2_port *sky2 = netdev_priv(dev); | 1407 | struct sky2_port *sky2 = netdev_priv(dev); |
1408 | struct sky2_hw *hw = sky2->hw; | 1408 | struct sky2_hw *hw = sky2->hw; |
@@ -3643,10 +3643,10 @@ static void sky2_get_drvinfo(struct net_device *dev, | |||
3643 | { | 3643 | { |
3644 | struct sky2_port *sky2 = netdev_priv(dev); | 3644 | struct sky2_port *sky2 = netdev_priv(dev); |
3645 | 3645 | ||
3646 | strcpy(info->driver, DRV_NAME); | 3646 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
3647 | strcpy(info->version, DRV_VERSION); | 3647 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
3648 | strcpy(info->fw_version, "N/A"); | 3648 | strlcpy(info->bus_info, pci_name(sky2->hw->pdev), |
3649 | strcpy(info->bus_info, pci_name(sky2->hw->pdev)); | 3649 | sizeof(info->bus_info)); |
3650 | } | 3650 | } |
3651 | 3651 | ||
3652 | static const struct sky2_stat { | 3652 | static const struct sky2_stat { |
@@ -4311,7 +4311,8 @@ static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom | |||
4311 | return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len); | 4311 | return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len); |
4312 | } | 4312 | } |
4313 | 4313 | ||
4314 | static u32 sky2_fix_features(struct net_device *dev, u32 features) | 4314 | static netdev_features_t sky2_fix_features(struct net_device *dev, |
4315 | netdev_features_t features) | ||
4315 | { | 4316 | { |
4316 | const struct sky2_port *sky2 = netdev_priv(dev); | 4317 | const struct sky2_port *sky2 = netdev_priv(dev); |
4317 | const struct sky2_hw *hw = sky2->hw; | 4318 | const struct sky2_hw *hw = sky2->hw; |
@@ -4335,13 +4336,13 @@ static u32 sky2_fix_features(struct net_device *dev, u32 features) | |||
4335 | return features; | 4336 | return features; |
4336 | } | 4337 | } |
4337 | 4338 | ||
4338 | static int sky2_set_features(struct net_device *dev, u32 features) | 4339 | static int sky2_set_features(struct net_device *dev, netdev_features_t features) |
4339 | { | 4340 | { |
4340 | struct sky2_port *sky2 = netdev_priv(dev); | 4341 | struct sky2_port *sky2 = netdev_priv(dev); |
4341 | u32 changed = dev->features ^ features; | 4342 | netdev_features_t changed = dev->features ^ features; |
4342 | 4343 | ||
4343 | if (changed & NETIF_F_RXCSUM) { | 4344 | if (changed & NETIF_F_RXCSUM) { |
4344 | u32 on = features & NETIF_F_RXCSUM; | 4345 | bool on = features & NETIF_F_RXCSUM; |
4345 | sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), | 4346 | sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), |
4346 | on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); | 4347 | on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); |
4347 | } | 4348 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 74e2a2a8a02b..ee637a200915 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | |||
@@ -45,13 +45,16 @@ mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) | |||
45 | struct mlx4_en_priv *priv = netdev_priv(dev); | 45 | struct mlx4_en_priv *priv = netdev_priv(dev); |
46 | struct mlx4_en_dev *mdev = priv->mdev; | 46 | struct mlx4_en_dev *mdev = priv->mdev; |
47 | 47 | ||
48 | strncpy(drvinfo->driver, DRV_NAME, 32); | 48 | strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); |
49 | strncpy(drvinfo->version, DRV_VERSION " (" DRV_RELDATE ")", 32); | 49 | strlcpy(drvinfo->version, DRV_VERSION " (" DRV_RELDATE ")", |
50 | sprintf(drvinfo->fw_version, "%d.%d.%d", | 50 | sizeof(drvinfo->version)); |
51 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), | ||
52 | "%d.%d.%d", | ||
51 | (u16) (mdev->dev->caps.fw_ver >> 32), | 53 | (u16) (mdev->dev->caps.fw_ver >> 32), |
52 | (u16) ((mdev->dev->caps.fw_ver >> 16) & 0xffff), | 54 | (u16) ((mdev->dev->caps.fw_ver >> 16) & 0xffff), |
53 | (u16) (mdev->dev->caps.fw_ver & 0xffff)); | 55 | (u16) (mdev->dev->caps.fw_ver & 0xffff)); |
54 | strncpy(drvinfo->bus_info, pci_name(mdev->dev->pdev), 32); | 56 | strlcpy(drvinfo->bus_info, pci_name(mdev->dev->pdev), |
57 | sizeof(drvinfo->bus_info)); | ||
55 | drvinfo->n_stats = 0; | 58 | drvinfo->n_stats = 0; |
56 | drvinfo->regdump_len = 0; | 59 | drvinfo->regdump_len = 0; |
57 | drvinfo->eedump_len = 0; | 60 | drvinfo->eedump_len = 0; |
diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index d19c849059d8..228c5c0b50de 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c | |||
@@ -1500,8 +1500,7 @@ static int ks_hw_init(struct ks_net *ks) | |||
1500 | ks->all_mcast = 0; | 1500 | ks->all_mcast = 0; |
1501 | ks->mcast_lst_size = 0; | 1501 | ks->mcast_lst_size = 0; |
1502 | 1502 | ||
1503 | ks->frame_head_info = (struct type_frame_head *) \ | 1503 | ks->frame_head_info = kmalloc(MHEADER_SIZE, GFP_KERNEL); |
1504 | kmalloc(MHEADER_SIZE, GFP_KERNEL); | ||
1505 | if (!ks->frame_head_info) { | 1504 | if (!ks->frame_head_info) { |
1506 | pr_err("Error: Fail to allocate frame memory\n"); | 1505 | pr_err("Error: Fail to allocate frame memory\n"); |
1507 | return false; | 1506 | return false; |
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index 7ece990381c8..a718865a8fed 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c | |||
@@ -743,8 +743,7 @@ | |||
743 | /* Change default LED mode. */ | 743 | /* Change default LED mode. */ |
744 | #define SET_DEFAULT_LED LED_SPEED_DUPLEX_ACT | 744 | #define SET_DEFAULT_LED LED_SPEED_DUPLEX_ACT |
745 | 745 | ||
746 | #define MAC_ADDR_LEN 6 | 746 | #define MAC_ADDR_ORDER(i) (ETH_ALEN - 1 - (i)) |
747 | #define MAC_ADDR_ORDER(i) (MAC_ADDR_LEN - 1 - (i)) | ||
748 | 747 | ||
749 | #define MAX_ETHERNET_BODY_SIZE 1500 | 748 | #define MAX_ETHERNET_BODY_SIZE 1500 |
750 | #define ETHERNET_HEADER_SIZE 14 | 749 | #define ETHERNET_HEADER_SIZE 14 |
@@ -1043,7 +1042,7 @@ enum { | |||
1043 | * @valid: Valid setting indicating the entry is being used. | 1042 | * @valid: Valid setting indicating the entry is being used. |
1044 | */ | 1043 | */ |
1045 | struct ksz_mac_table { | 1044 | struct ksz_mac_table { |
1046 | u8 mac_addr[MAC_ADDR_LEN]; | 1045 | u8 mac_addr[ETH_ALEN]; |
1047 | u16 vid; | 1046 | u16 vid; |
1048 | u8 fid; | 1047 | u8 fid; |
1049 | u8 ports; | 1048 | u8 ports; |
@@ -1187,8 +1186,8 @@ struct ksz_switch { | |||
1187 | u8 diffserv[DIFFSERV_ENTRIES]; | 1186 | u8 diffserv[DIFFSERV_ENTRIES]; |
1188 | u8 p_802_1p[PRIO_802_1P_ENTRIES]; | 1187 | u8 p_802_1p[PRIO_802_1P_ENTRIES]; |
1189 | 1188 | ||
1190 | u8 br_addr[MAC_ADDR_LEN]; | 1189 | u8 br_addr[ETH_ALEN]; |
1191 | u8 other_addr[MAC_ADDR_LEN]; | 1190 | u8 other_addr[ETH_ALEN]; |
1192 | 1191 | ||
1193 | u8 broad_per; | 1192 | u8 broad_per; |
1194 | u8 member; | 1193 | u8 member; |
@@ -1292,14 +1291,14 @@ struct ksz_hw { | |||
1292 | int tx_int_mask; | 1291 | int tx_int_mask; |
1293 | int tx_size; | 1292 | int tx_size; |
1294 | 1293 | ||
1295 | u8 perm_addr[MAC_ADDR_LEN]; | 1294 | u8 perm_addr[ETH_ALEN]; |
1296 | u8 override_addr[MAC_ADDR_LEN]; | 1295 | u8 override_addr[ETH_ALEN]; |
1297 | u8 address[ADDITIONAL_ENTRIES][MAC_ADDR_LEN]; | 1296 | u8 address[ADDITIONAL_ENTRIES][ETH_ALEN]; |
1298 | u8 addr_list_size; | 1297 | u8 addr_list_size; |
1299 | u8 mac_override; | 1298 | u8 mac_override; |
1300 | u8 promiscuous; | 1299 | u8 promiscuous; |
1301 | u8 all_multi; | 1300 | u8 all_multi; |
1302 | u8 multi_list[MAX_MULTICAST_LIST][MAC_ADDR_LEN]; | 1301 | u8 multi_list[MAX_MULTICAST_LIST][ETH_ALEN]; |
1303 | u8 multi_bits[HW_MULTICAST_SIZE]; | 1302 | u8 multi_bits[HW_MULTICAST_SIZE]; |
1304 | u8 multi_list_size; | 1303 | u8 multi_list_size; |
1305 | 1304 | ||
@@ -3654,7 +3653,7 @@ static void hw_add_wol_bcast(struct ksz_hw *hw) | |||
3654 | static const u8 mask[] = { 0x3F }; | 3653 | static const u8 mask[] = { 0x3F }; |
3655 | static const u8 pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 3654 | static const u8 pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
3656 | 3655 | ||
3657 | hw_set_wol_frame(hw, 2, 1, mask, MAC_ADDR_LEN, pattern); | 3656 | hw_set_wol_frame(hw, 2, 1, mask, ETH_ALEN, pattern); |
3658 | } | 3657 | } |
3659 | 3658 | ||
3660 | /** | 3659 | /** |
@@ -3689,7 +3688,7 @@ static void hw_add_wol_ucast(struct ksz_hw *hw) | |||
3689 | { | 3688 | { |
3690 | static const u8 mask[] = { 0x3F }; | 3689 | static const u8 mask[] = { 0x3F }; |
3691 | 3690 | ||
3692 | hw_set_wol_frame(hw, 0, 1, mask, MAC_ADDR_LEN, hw->override_addr); | 3691 | hw_set_wol_frame(hw, 0, 1, mask, ETH_ALEN, hw->override_addr); |
3693 | } | 3692 | } |
3694 | 3693 | ||
3695 | /** | 3694 | /** |
@@ -4055,7 +4054,7 @@ static void hw_set_addr(struct ksz_hw *hw) | |||
4055 | { | 4054 | { |
4056 | int i; | 4055 | int i; |
4057 | 4056 | ||
4058 | for (i = 0; i < MAC_ADDR_LEN; i++) | 4057 | for (i = 0; i < ETH_ALEN; i++) |
4059 | writeb(hw->override_addr[MAC_ADDR_ORDER(i)], | 4058 | writeb(hw->override_addr[MAC_ADDR_ORDER(i)], |
4060 | hw->io + KS884X_ADDR_0_OFFSET + i); | 4059 | hw->io + KS884X_ADDR_0_OFFSET + i); |
4061 | 4060 | ||
@@ -4072,17 +4071,16 @@ static void hw_read_addr(struct ksz_hw *hw) | |||
4072 | { | 4071 | { |
4073 | int i; | 4072 | int i; |
4074 | 4073 | ||
4075 | for (i = 0; i < MAC_ADDR_LEN; i++) | 4074 | for (i = 0; i < ETH_ALEN; i++) |
4076 | hw->perm_addr[MAC_ADDR_ORDER(i)] = readb(hw->io + | 4075 | hw->perm_addr[MAC_ADDR_ORDER(i)] = readb(hw->io + |
4077 | KS884X_ADDR_0_OFFSET + i); | 4076 | KS884X_ADDR_0_OFFSET + i); |
4078 | 4077 | ||
4079 | if (!hw->mac_override) { | 4078 | if (!hw->mac_override) { |
4080 | memcpy(hw->override_addr, hw->perm_addr, MAC_ADDR_LEN); | 4079 | memcpy(hw->override_addr, hw->perm_addr, ETH_ALEN); |
4081 | if (empty_addr(hw->override_addr)) { | 4080 | if (empty_addr(hw->override_addr)) { |
4082 | memcpy(hw->perm_addr, DEFAULT_MAC_ADDRESS, | 4081 | memcpy(hw->perm_addr, DEFAULT_MAC_ADDRESS, ETH_ALEN); |
4083 | MAC_ADDR_LEN); | ||
4084 | memcpy(hw->override_addr, DEFAULT_MAC_ADDRESS, | 4082 | memcpy(hw->override_addr, DEFAULT_MAC_ADDRESS, |
4085 | MAC_ADDR_LEN); | 4083 | ETH_ALEN); |
4086 | hw->override_addr[5] += hw->id; | 4084 | hw->override_addr[5] += hw->id; |
4087 | hw_set_addr(hw); | 4085 | hw_set_addr(hw); |
4088 | } | 4086 | } |
@@ -4130,16 +4128,16 @@ static int hw_add_addr(struct ksz_hw *hw, u8 *mac_addr) | |||
4130 | int i; | 4128 | int i; |
4131 | int j = ADDITIONAL_ENTRIES; | 4129 | int j = ADDITIONAL_ENTRIES; |
4132 | 4130 | ||
4133 | if (!memcmp(hw->override_addr, mac_addr, MAC_ADDR_LEN)) | 4131 | if (!memcmp(hw->override_addr, mac_addr, ETH_ALEN)) |
4134 | return 0; | 4132 | return 0; |
4135 | for (i = 0; i < hw->addr_list_size; i++) { | 4133 | for (i = 0; i < hw->addr_list_size; i++) { |
4136 | if (!memcmp(hw->address[i], mac_addr, MAC_ADDR_LEN)) | 4134 | if (!memcmp(hw->address[i], mac_addr, ETH_ALEN)) |
4137 | return 0; | 4135 | return 0; |
4138 | if (ADDITIONAL_ENTRIES == j && empty_addr(hw->address[i])) | 4136 | if (ADDITIONAL_ENTRIES == j && empty_addr(hw->address[i])) |
4139 | j = i; | 4137 | j = i; |
4140 | } | 4138 | } |
4141 | if (j < ADDITIONAL_ENTRIES) { | 4139 | if (j < ADDITIONAL_ENTRIES) { |
4142 | memcpy(hw->address[j], mac_addr, MAC_ADDR_LEN); | 4140 | memcpy(hw->address[j], mac_addr, ETH_ALEN); |
4143 | hw_ena_add_addr(hw, j, hw->address[j]); | 4141 | hw_ena_add_addr(hw, j, hw->address[j]); |
4144 | return 0; | 4142 | return 0; |
4145 | } | 4143 | } |
@@ -4151,8 +4149,8 @@ static int hw_del_addr(struct ksz_hw *hw, u8 *mac_addr) | |||
4151 | int i; | 4149 | int i; |
4152 | 4150 | ||
4153 | for (i = 0; i < hw->addr_list_size; i++) { | 4151 | for (i = 0; i < hw->addr_list_size; i++) { |
4154 | if (!memcmp(hw->address[i], mac_addr, MAC_ADDR_LEN)) { | 4152 | if (!memcmp(hw->address[i], mac_addr, ETH_ALEN)) { |
4155 | memset(hw->address[i], 0, MAC_ADDR_LEN); | 4153 | memset(hw->address[i], 0, ETH_ALEN); |
4156 | writel(0, hw->io + ADD_ADDR_INCR * i + | 4154 | writel(0, hw->io + ADD_ADDR_INCR * i + |
4157 | KS_ADD_ADDR_0_HI); | 4155 | KS_ADD_ADDR_0_HI); |
4158 | return 0; | 4156 | return 0; |
@@ -4382,12 +4380,10 @@ static void ksz_update_timer(struct ksz_timer_info *info) | |||
4382 | */ | 4380 | */ |
4383 | static int ksz_alloc_soft_desc(struct ksz_desc_info *desc_info, int transmit) | 4381 | static int ksz_alloc_soft_desc(struct ksz_desc_info *desc_info, int transmit) |
4384 | { | 4382 | { |
4385 | desc_info->ring = kmalloc(sizeof(struct ksz_desc) * desc_info->alloc, | 4383 | desc_info->ring = kzalloc(sizeof(struct ksz_desc) * desc_info->alloc, |
4386 | GFP_KERNEL); | 4384 | GFP_KERNEL); |
4387 | if (!desc_info->ring) | 4385 | if (!desc_info->ring) |
4388 | return 1; | 4386 | return 1; |
4389 | memset((void *) desc_info->ring, 0, | ||
4390 | sizeof(struct ksz_desc) * desc_info->alloc); | ||
4391 | hw_init_desc(desc_info, transmit); | 4387 | hw_init_desc(desc_info, transmit); |
4392 | return 0; | 4388 | return 0; |
4393 | } | 4389 | } |
@@ -5676,7 +5672,7 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr) | |||
5676 | hw_del_addr(hw, dev->dev_addr); | 5672 | hw_del_addr(hw, dev->dev_addr); |
5677 | else { | 5673 | else { |
5678 | hw->mac_override = 1; | 5674 | hw->mac_override = 1; |
5679 | memcpy(hw->override_addr, mac->sa_data, MAC_ADDR_LEN); | 5675 | memcpy(hw->override_addr, mac->sa_data, ETH_ALEN); |
5680 | } | 5676 | } |
5681 | 5677 | ||
5682 | memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN); | 5678 | memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN); |
@@ -5786,7 +5782,7 @@ static void netdev_set_rx_mode(struct net_device *dev) | |||
5786 | netdev_for_each_mc_addr(ha, dev) { | 5782 | netdev_for_each_mc_addr(ha, dev) { |
5787 | if (i >= MAX_MULTICAST_LIST) | 5783 | if (i >= MAX_MULTICAST_LIST) |
5788 | break; | 5784 | break; |
5789 | memcpy(hw->multi_list[i++], ha->addr, MAC_ADDR_LEN); | 5785 | memcpy(hw->multi_list[i++], ha->addr, ETH_ALEN); |
5790 | } | 5786 | } |
5791 | hw->multi_list_size = (u8) i; | 5787 | hw->multi_list_size = (u8) i; |
5792 | hw_set_grp_addr(hw); | 5788 | hw_set_grp_addr(hw); |
@@ -6093,9 +6089,10 @@ static void netdev_get_drvinfo(struct net_device *dev, | |||
6093 | struct dev_priv *priv = netdev_priv(dev); | 6089 | struct dev_priv *priv = netdev_priv(dev); |
6094 | struct dev_info *hw_priv = priv->adapter; | 6090 | struct dev_info *hw_priv = priv->adapter; |
6095 | 6091 | ||
6096 | strcpy(info->driver, DRV_NAME); | 6092 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
6097 | strcpy(info->version, DRV_VERSION); | 6093 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
6098 | strcpy(info->bus_info, pci_name(hw_priv->pdev)); | 6094 | strlcpy(info->bus_info, pci_name(hw_priv->pdev), |
6095 | sizeof(info->bus_info)); | ||
6099 | } | 6096 | } |
6100 | 6097 | ||
6101 | /** | 6098 | /** |
@@ -6587,7 +6584,8 @@ static void netdev_get_ethtool_stats(struct net_device *dev, | |||
6587 | * | 6584 | * |
6588 | * Return 0 if successful; otherwise an error code. | 6585 | * Return 0 if successful; otherwise an error code. |
6589 | */ | 6586 | */ |
6590 | static int netdev_set_features(struct net_device *dev, u32 features) | 6587 | static int netdev_set_features(struct net_device *dev, |
6588 | netdev_features_t features) | ||
6591 | { | 6589 | { |
6592 | struct dev_priv *priv = netdev_priv(dev); | 6590 | struct dev_priv *priv = netdev_priv(dev); |
6593 | struct dev_info *hw_priv = priv->adapter; | 6591 | struct dev_info *hw_priv = priv->adapter; |
@@ -6860,7 +6858,7 @@ static void get_mac_addr(struct dev_info *hw_priv, u8 *macaddr, int port) | |||
6860 | int num; | 6858 | int num; |
6861 | 6859 | ||
6862 | i = j = num = got_num = 0; | 6860 | i = j = num = got_num = 0; |
6863 | while (j < MAC_ADDR_LEN) { | 6861 | while (j < ETH_ALEN) { |
6864 | if (macaddr[i]) { | 6862 | if (macaddr[i]) { |
6865 | int digit; | 6863 | int digit; |
6866 | 6864 | ||
@@ -6891,7 +6889,7 @@ static void get_mac_addr(struct dev_info *hw_priv, u8 *macaddr, int port) | |||
6891 | } | 6889 | } |
6892 | i++; | 6890 | i++; |
6893 | } | 6891 | } |
6894 | if (MAC_ADDR_LEN == j) { | 6892 | if (ETH_ALEN == j) { |
6895 | if (MAIN_PORT == port) | 6893 | if (MAIN_PORT == port) |
6896 | hw_priv->hw.mac_override = 1; | 6894 | hw_priv->hw.mac_override = 1; |
6897 | } | 6895 | } |
@@ -7058,7 +7056,7 @@ static int __devinit pcidev_init(struct pci_dev *pdev, | |||
7058 | 7056 | ||
7059 | /* Multiple device interfaces mode requires a second MAC address. */ | 7057 | /* Multiple device interfaces mode requires a second MAC address. */ |
7060 | if (hw->dev_count > 1) { | 7058 | if (hw->dev_count > 1) { |
7061 | memcpy(sw->other_addr, hw->override_addr, MAC_ADDR_LEN); | 7059 | memcpy(sw->other_addr, hw->override_addr, ETH_ALEN); |
7062 | read_other_addr(hw); | 7060 | read_other_addr(hw); |
7063 | if (mac1addr[0] != ':') | 7061 | if (mac1addr[0] != ':') |
7064 | get_mac_addr(hw_priv, mac1addr, OTHER_PORT); | 7062 | get_mac_addr(hw_priv, mac1addr, OTHER_PORT); |
@@ -7108,12 +7106,11 @@ static int __devinit pcidev_init(struct pci_dev *pdev, | |||
7108 | dev->irq = pdev->irq; | 7106 | dev->irq = pdev->irq; |
7109 | if (MAIN_PORT == i) | 7107 | if (MAIN_PORT == i) |
7110 | memcpy(dev->dev_addr, hw_priv->hw.override_addr, | 7108 | memcpy(dev->dev_addr, hw_priv->hw.override_addr, |
7111 | MAC_ADDR_LEN); | 7109 | ETH_ALEN); |
7112 | else { | 7110 | else { |
7113 | memcpy(dev->dev_addr, sw->other_addr, | 7111 | memcpy(dev->dev_addr, sw->other_addr, ETH_ALEN); |
7114 | MAC_ADDR_LEN); | ||
7115 | if (!memcmp(sw->other_addr, hw->override_addr, | 7112 | if (!memcmp(sw->other_addr, hw->override_addr, |
7116 | MAC_ADDR_LEN)) | 7113 | ETH_ALEN)) |
7117 | dev->dev_addr[5] += port->first_port; | 7114 | dev->dev_addr[5] += port->first_port; |
7118 | } | 7115 | } |
7119 | 7116 | ||
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 0778edcf7b9a..20b72ecb020a 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c | |||
@@ -1491,7 +1491,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget) | |||
1491 | * access to avoid theoretical race condition with functions that | 1491 | * access to avoid theoretical race condition with functions that |
1492 | * change NETIF_F_LRO flag at runtime. | 1492 | * change NETIF_F_LRO flag at runtime. |
1493 | */ | 1493 | */ |
1494 | bool lro_enabled = ACCESS_ONCE(mgp->dev->features) & NETIF_F_LRO; | 1494 | bool lro_enabled = !!(ACCESS_ONCE(mgp->dev->features) & NETIF_F_LRO); |
1495 | 1495 | ||
1496 | while (rx_done->entry[idx].length != 0 && work_done < budget) { | 1496 | while (rx_done->entry[idx].length != 0 && work_done < budget) { |
1497 | length = ntohs(rx_done->entry[idx].length); | 1497 | length = ntohs(rx_done->entry[idx].length); |
@@ -3149,7 +3149,8 @@ static int myri10ge_set_mac_address(struct net_device *dev, void *addr) | |||
3149 | return 0; | 3149 | return 0; |
3150 | } | 3150 | } |
3151 | 3151 | ||
3152 | static u32 myri10ge_fix_features(struct net_device *dev, u32 features) | 3152 | static netdev_features_t myri10ge_fix_features(struct net_device *dev, |
3153 | netdev_features_t features) | ||
3153 | { | 3154 | { |
3154 | if (!(features & NETIF_F_RXCSUM)) | 3155 | if (!(features & NETIF_F_RXCSUM)) |
3155 | features &= ~NETIF_F_LRO; | 3156 | features &= ~NETIF_F_LRO; |
diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c index 6ca047aab793..ac7b16b6e7af 100644 --- a/drivers/net/ethernet/natsemi/natsemi.c +++ b/drivers/net/ethernet/natsemi/natsemi.c | |||
@@ -2555,9 +2555,9 @@ static void set_rx_mode(struct net_device *dev) | |||
2555 | static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 2555 | static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
2556 | { | 2556 | { |
2557 | struct netdev_private *np = netdev_priv(dev); | 2557 | struct netdev_private *np = netdev_priv(dev); |
2558 | strncpy(info->driver, DRV_NAME, ETHTOOL_BUSINFO_LEN); | 2558 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
2559 | strncpy(info->version, DRV_VERSION, ETHTOOL_BUSINFO_LEN); | 2559 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
2560 | strncpy(info->bus_info, pci_name(np->pci_dev), ETHTOOL_BUSINFO_LEN); | 2560 | strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); |
2561 | } | 2561 | } |
2562 | 2562 | ||
2563 | static int get_regs_len(struct net_device *dev) | 2563 | static int get_regs_len(struct net_device *dev) |
diff --git a/drivers/net/ethernet/natsemi/ns83820.c b/drivers/net/ethernet/natsemi/ns83820.c index 2b8f64ddfb55..c24b46cbfe27 100644 --- a/drivers/net/ethernet/natsemi/ns83820.c +++ b/drivers/net/ethernet/natsemi/ns83820.c | |||
@@ -1364,9 +1364,9 @@ static int ns83820_set_settings(struct net_device *ndev, | |||
1364 | static void ns83820_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) | 1364 | static void ns83820_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) |
1365 | { | 1365 | { |
1366 | struct ns83820 *dev = PRIV(ndev); | 1366 | struct ns83820 *dev = PRIV(ndev); |
1367 | strcpy(info->driver, "ns83820"); | 1367 | strlcpy(info->driver, "ns83820", sizeof(info->driver)); |
1368 | strcpy(info->version, VERSION); | 1368 | strlcpy(info->version, VERSION, sizeof(info->version)); |
1369 | strcpy(info->bus_info, pci_name(dev->pci_dev)); | 1369 | strlcpy(info->bus_info, pci_name(dev->pci_dev), sizeof(info->bus_info)); |
1370 | } | 1370 | } |
1371 | 1371 | ||
1372 | static u32 ns83820_get_link(struct net_device *ndev) | 1372 | static u32 ns83820_get_link(struct net_device *ndev) |
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index c27fb3dda9f4..76ae47627200 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c | |||
@@ -5391,10 +5391,10 @@ static void s2io_ethtool_gdrvinfo(struct net_device *dev, | |||
5391 | { | 5391 | { |
5392 | struct s2io_nic *sp = netdev_priv(dev); | 5392 | struct s2io_nic *sp = netdev_priv(dev); |
5393 | 5393 | ||
5394 | strncpy(info->driver, s2io_driver_name, sizeof(info->driver)); | 5394 | strlcpy(info->driver, s2io_driver_name, sizeof(info->driver)); |
5395 | strncpy(info->version, s2io_driver_version, sizeof(info->version)); | 5395 | strlcpy(info->version, s2io_driver_version, sizeof(info->version)); |
5396 | strncpy(info->fw_version, "", sizeof(info->fw_version)); | 5396 | strlcpy(info->fw_version, "", sizeof(info->fw_version)); |
5397 | strncpy(info->bus_info, pci_name(sp->pdev), sizeof(info->bus_info)); | 5397 | strlcpy(info->bus_info, pci_name(sp->pdev), sizeof(info->bus_info)); |
5398 | info->regdump_len = XENA_REG_SPACE; | 5398 | info->regdump_len = XENA_REG_SPACE; |
5399 | info->eedump_len = XENA_EEPROM_SPACE; | 5399 | info->eedump_len = XENA_EEPROM_SPACE; |
5400 | } | 5400 | } |
@@ -6616,10 +6616,10 @@ static void s2io_ethtool_get_strings(struct net_device *dev, | |||
6616 | } | 6616 | } |
6617 | } | 6617 | } |
6618 | 6618 | ||
6619 | static int s2io_set_features(struct net_device *dev, u32 features) | 6619 | static int s2io_set_features(struct net_device *dev, netdev_features_t features) |
6620 | { | 6620 | { |
6621 | struct s2io_nic *sp = netdev_priv(dev); | 6621 | struct s2io_nic *sp = netdev_priv(dev); |
6622 | u32 changed = (features ^ dev->features) & NETIF_F_LRO; | 6622 | netdev_features_t changed = (features ^ dev->features) & NETIF_F_LRO; |
6623 | 6623 | ||
6624 | if (changed && netif_running(dev)) { | 6624 | if (changed && netif_running(dev)) { |
6625 | int rc; | 6625 | int rc; |
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index a83197d757c1..16d4d8e913c3 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c | |||
@@ -2662,9 +2662,10 @@ static void vxge_poll_vp_lockup(unsigned long data) | |||
2662 | mod_timer(&vdev->vp_lockup_timer, jiffies + HZ / 1000); | 2662 | mod_timer(&vdev->vp_lockup_timer, jiffies + HZ / 1000); |
2663 | } | 2663 | } |
2664 | 2664 | ||
2665 | static u32 vxge_fix_features(struct net_device *dev, u32 features) | 2665 | static netdev_features_t vxge_fix_features(struct net_device *dev, |
2666 | netdev_features_t features) | ||
2666 | { | 2667 | { |
2667 | u32 changed = dev->features ^ features; | 2668 | netdev_features_t changed = dev->features ^ features; |
2668 | 2669 | ||
2669 | /* Enabling RTH requires some of the logic in vxge_device_register and a | 2670 | /* Enabling RTH requires some of the logic in vxge_device_register and a |
2670 | * vpath reset. Due to these restrictions, only allow modification | 2671 | * vpath reset. Due to these restrictions, only allow modification |
@@ -2676,10 +2677,10 @@ static u32 vxge_fix_features(struct net_device *dev, u32 features) | |||
2676 | return features; | 2677 | return features; |
2677 | } | 2678 | } |
2678 | 2679 | ||
2679 | static int vxge_set_features(struct net_device *dev, u32 features) | 2680 | static int vxge_set_features(struct net_device *dev, netdev_features_t features) |
2680 | { | 2681 | { |
2681 | struct vxgedev *vdev = netdev_priv(dev); | 2682 | struct vxgedev *vdev = netdev_priv(dev); |
2682 | u32 changed = dev->features ^ features; | 2683 | netdev_features_t changed = dev->features ^ features; |
2683 | 2684 | ||
2684 | if (!(changed & NETIF_F_RXHASH)) | 2685 | if (!(changed & NETIF_F_RXHASH)) |
2685 | return 0; | 2686 | return 0; |
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 1c61d36e6570..8db0b376d5b7 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c | |||
@@ -65,7 +65,8 @@ | |||
65 | #include <linux/slab.h> | 65 | #include <linux/slab.h> |
66 | #include <linux/uaccess.h> | 66 | #include <linux/uaccess.h> |
67 | #include <linux/prefetch.h> | 67 | #include <linux/prefetch.h> |
68 | #include <linux/io.h> | 68 | #include <linux/u64_stats_sync.h> |
69 | #include <linux/io.h> | ||
69 | 70 | ||
70 | #include <asm/irq.h> | 71 | #include <asm/irq.h> |
71 | #include <asm/system.h> | 72 | #include <asm/system.h> |
@@ -736,6 +737,16 @@ struct nv_skb_map { | |||
736 | * - tx setup is lockless: it relies on netif_tx_lock. Actual submission | 737 | * - tx setup is lockless: it relies on netif_tx_lock. Actual submission |
737 | * needs netdev_priv(dev)->lock :-( | 738 | * needs netdev_priv(dev)->lock :-( |
738 | * - set_multicast_list: preparation lockless, relies on netif_tx_lock. | 739 | * - set_multicast_list: preparation lockless, relies on netif_tx_lock. |
740 | * | ||
741 | * Hardware stats updates are protected by hwstats_lock: | ||
742 | * - updated by nv_do_stats_poll (timer). This is meant to avoid | ||
743 | * integer wraparound in the NIC stats registers, at low frequency | ||
744 | * (0.1 Hz) | ||
745 | * - updated by nv_get_ethtool_stats + nv_get_stats64 | ||
746 | * | ||
747 | * Software stats are accessed only through 64b synchronization points | ||
748 | * and are not subject to other synchronization techniques (single | ||
749 | * update thread on the TX or RX paths). | ||
739 | */ | 750 | */ |
740 | 751 | ||
741 | /* in dev: base, irq */ | 752 | /* in dev: base, irq */ |
@@ -745,9 +756,10 @@ struct fe_priv { | |||
745 | struct net_device *dev; | 756 | struct net_device *dev; |
746 | struct napi_struct napi; | 757 | struct napi_struct napi; |
747 | 758 | ||
748 | /* General data: | 759 | /* hardware stats are updated in syscall and timer */ |
749 | * Locking: spin_lock(&np->lock); */ | 760 | spinlock_t hwstats_lock; |
750 | struct nv_ethtool_stats estats; | 761 | struct nv_ethtool_stats estats; |
762 | |||
751 | int in_shutdown; | 763 | int in_shutdown; |
752 | u32 linkspeed; | 764 | u32 linkspeed; |
753 | int duplex; | 765 | int duplex; |
@@ -798,6 +810,13 @@ struct fe_priv { | |||
798 | u32 nic_poll_irq; | 810 | u32 nic_poll_irq; |
799 | int rx_ring_size; | 811 | int rx_ring_size; |
800 | 812 | ||
813 | /* RX software stats */ | ||
814 | struct u64_stats_sync swstats_rx_syncp; | ||
815 | u64 stat_rx_packets; | ||
816 | u64 stat_rx_bytes; /* not always available in HW */ | ||
817 | u64 stat_rx_missed_errors; | ||
818 | u64 stat_rx_dropped; | ||
819 | |||
801 | /* media detection workaround. | 820 | /* media detection workaround. |
802 | * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); | 821 | * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); |
803 | */ | 822 | */ |
@@ -820,6 +839,12 @@ struct fe_priv { | |||
820 | struct nv_skb_map *tx_end_flip; | 839 | struct nv_skb_map *tx_end_flip; |
821 | int tx_stop; | 840 | int tx_stop; |
822 | 841 | ||
842 | /* TX software stats */ | ||
843 | struct u64_stats_sync swstats_tx_syncp; | ||
844 | u64 stat_tx_packets; /* not always available in HW */ | ||
845 | u64 stat_tx_bytes; | ||
846 | u64 stat_tx_dropped; | ||
847 | |||
823 | /* msi/msi-x fields */ | 848 | /* msi/msi-x fields */ |
824 | u32 msi_flags; | 849 | u32 msi_flags; |
825 | struct msix_entry msi_x_entry[NV_MSI_X_MAX_VECTORS]; | 850 | struct msix_entry msi_x_entry[NV_MSI_X_MAX_VECTORS]; |
@@ -892,6 +917,11 @@ enum { | |||
892 | static int dma_64bit = NV_DMA_64BIT_ENABLED; | 917 | static int dma_64bit = NV_DMA_64BIT_ENABLED; |
893 | 918 | ||
894 | /* | 919 | /* |
920 | * Debug output control for tx_timeout | ||
921 | */ | ||
922 | static bool debug_tx_timeout = false; | ||
923 | |||
924 | /* | ||
895 | * Crossover Detection | 925 | * Crossover Detection |
896 | * Realtek 8201 phy + some OEM boards do not work properly. | 926 | * Realtek 8201 phy + some OEM boards do not work properly. |
897 | */ | 927 | */ |
@@ -1630,11 +1660,19 @@ static void nv_mac_reset(struct net_device *dev) | |||
1630 | pci_push(base); | 1660 | pci_push(base); |
1631 | } | 1661 | } |
1632 | 1662 | ||
1633 | static void nv_get_hw_stats(struct net_device *dev) | 1663 | /* Caller must appropriately lock netdev_priv(dev)->hwstats_lock */ |
1664 | static void nv_update_stats(struct net_device *dev) | ||
1634 | { | 1665 | { |
1635 | struct fe_priv *np = netdev_priv(dev); | 1666 | struct fe_priv *np = netdev_priv(dev); |
1636 | u8 __iomem *base = get_hwbase(dev); | 1667 | u8 __iomem *base = get_hwbase(dev); |
1637 | 1668 | ||
1669 | /* If it happens that this is run in top-half context, then | ||
1670 | * replace the spin_lock of hwstats_lock with | ||
1671 | * spin_lock_irqsave() in calling functions. */ | ||
1672 | WARN_ONCE(in_irq(), "forcedeth: estats spin_lock(_bh) from top-half"); | ||
1673 | assert_spin_locked(&np->hwstats_lock); | ||
1674 | |||
1675 | /* query hardware */ | ||
1638 | np->estats.tx_bytes += readl(base + NvRegTxCnt); | 1676 | np->estats.tx_bytes += readl(base + NvRegTxCnt); |
1639 | np->estats.tx_zero_rexmt += readl(base + NvRegTxZeroReXmt); | 1677 | np->estats.tx_zero_rexmt += readl(base + NvRegTxZeroReXmt); |
1640 | np->estats.tx_one_rexmt += readl(base + NvRegTxOneReXmt); | 1678 | np->estats.tx_one_rexmt += readl(base + NvRegTxOneReXmt); |
@@ -1693,40 +1731,73 @@ static void nv_get_hw_stats(struct net_device *dev) | |||
1693 | } | 1731 | } |
1694 | 1732 | ||
1695 | /* | 1733 | /* |
1696 | * nv_get_stats: dev->get_stats function | 1734 | * nv_get_stats64: dev->ndo_get_stats64 function |
1697 | * Get latest stats value from the nic. | 1735 | * Get latest stats value from the nic. |
1698 | * Called with read_lock(&dev_base_lock) held for read - | 1736 | * Called with read_lock(&dev_base_lock) held for read - |
1699 | * only synchronized against unregister_netdevice. | 1737 | * only synchronized against unregister_netdevice. |
1700 | */ | 1738 | */ |
1701 | static struct net_device_stats *nv_get_stats(struct net_device *dev) | 1739 | static struct rtnl_link_stats64* |
1740 | nv_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *storage) | ||
1741 | __acquires(&netdev_priv(dev)->hwstats_lock) | ||
1742 | __releases(&netdev_priv(dev)->hwstats_lock) | ||
1702 | { | 1743 | { |
1703 | struct fe_priv *np = netdev_priv(dev); | 1744 | struct fe_priv *np = netdev_priv(dev); |
1745 | unsigned int syncp_start; | ||
1746 | |||
1747 | /* | ||
1748 | * Note: because HW stats are not always available and for | ||
1749 | * consistency reasons, the following ifconfig stats are | ||
1750 | * managed by software: rx_bytes, tx_bytes, rx_packets and | ||
1751 | * tx_packets. The related hardware stats reported by ethtool | ||
1752 | * should be equivalent to these ifconfig stats, with 4 | ||
1753 | * additional bytes per packet (Ethernet FCS CRC), except for | ||
1754 | * tx_packets when TSO kicks in. | ||
1755 | */ | ||
1756 | |||
1757 | /* software stats */ | ||
1758 | do { | ||
1759 | syncp_start = u64_stats_fetch_begin_bh(&np->swstats_rx_syncp); | ||
1760 | storage->rx_packets = np->stat_rx_packets; | ||
1761 | storage->rx_bytes = np->stat_rx_bytes; | ||
1762 | storage->rx_dropped = np->stat_rx_dropped; | ||
1763 | storage->rx_missed_errors = np->stat_rx_missed_errors; | ||
1764 | } while (u64_stats_fetch_retry_bh(&np->swstats_rx_syncp, syncp_start)); | ||
1765 | |||
1766 | do { | ||
1767 | syncp_start = u64_stats_fetch_begin_bh(&np->swstats_tx_syncp); | ||
1768 | storage->tx_packets = np->stat_tx_packets; | ||
1769 | storage->tx_bytes = np->stat_tx_bytes; | ||
1770 | storage->tx_dropped = np->stat_tx_dropped; | ||
1771 | } while (u64_stats_fetch_retry_bh(&np->swstats_tx_syncp, syncp_start)); | ||
1704 | 1772 | ||
1705 | /* If the nic supports hw counters then retrieve latest values */ | 1773 | /* If the nic supports hw counters then retrieve latest values */ |
1706 | if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3)) { | 1774 | if (np->driver_data & DEV_HAS_STATISTICS_V123) { |
1707 | nv_get_hw_stats(dev); | 1775 | spin_lock_bh(&np->hwstats_lock); |
1708 | 1776 | ||
1709 | /* | 1777 | nv_update_stats(dev); |
1710 | * Note: because HW stats are not always available and | ||
1711 | * for consistency reasons, the following ifconfig | ||
1712 | * stats are managed by software: rx_bytes, tx_bytes, | ||
1713 | * rx_packets and tx_packets. The related hardware | ||
1714 | * stats reported by ethtool should be equivalent to | ||
1715 | * these ifconfig stats, with 4 additional bytes per | ||
1716 | * packet (Ethernet FCS CRC). | ||
1717 | */ | ||
1718 | 1778 | ||
1719 | /* copy to net_device stats */ | 1779 | /* generic stats */ |
1720 | dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors; | 1780 | storage->rx_errors = np->estats.rx_errors_total; |
1721 | dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors; | 1781 | storage->tx_errors = np->estats.tx_errors_total; |
1722 | dev->stats.rx_crc_errors = np->estats.rx_crc_errors; | 1782 | |
1723 | dev->stats.rx_over_errors = np->estats.rx_over_errors; | 1783 | /* meaningful only when NIC supports stats v3 */ |
1724 | dev->stats.rx_fifo_errors = np->estats.rx_drop_frame; | 1784 | storage->multicast = np->estats.rx_multicast; |
1725 | dev->stats.rx_errors = np->estats.rx_errors_total; | 1785 | |
1726 | dev->stats.tx_errors = np->estats.tx_errors_total; | 1786 | /* detailed rx_errors */ |
1787 | storage->rx_length_errors = np->estats.rx_length_error; | ||
1788 | storage->rx_over_errors = np->estats.rx_over_errors; | ||
1789 | storage->rx_crc_errors = np->estats.rx_crc_errors; | ||
1790 | storage->rx_frame_errors = np->estats.rx_frame_align_error; | ||
1791 | storage->rx_fifo_errors = np->estats.rx_drop_frame; | ||
1792 | |||
1793 | /* detailed tx_errors */ | ||
1794 | storage->tx_carrier_errors = np->estats.tx_carrier_errors; | ||
1795 | storage->tx_fifo_errors = np->estats.tx_fifo_errors; | ||
1796 | |||
1797 | spin_unlock_bh(&np->hwstats_lock); | ||
1727 | } | 1798 | } |
1728 | 1799 | ||
1729 | return &dev->stats; | 1800 | return storage; |
1730 | } | 1801 | } |
1731 | 1802 | ||
1732 | /* | 1803 | /* |
@@ -1759,8 +1830,12 @@ static int nv_alloc_rx(struct net_device *dev) | |||
1759 | np->put_rx.orig = np->first_rx.orig; | 1830 | np->put_rx.orig = np->first_rx.orig; |
1760 | if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx)) | 1831 | if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx)) |
1761 | np->put_rx_ctx = np->first_rx_ctx; | 1832 | np->put_rx_ctx = np->first_rx_ctx; |
1762 | } else | 1833 | } else { |
1834 | u64_stats_update_begin(&np->swstats_rx_syncp); | ||
1835 | np->stat_rx_dropped++; | ||
1836 | u64_stats_update_end(&np->swstats_rx_syncp); | ||
1763 | return 1; | 1837 | return 1; |
1838 | } | ||
1764 | } | 1839 | } |
1765 | return 0; | 1840 | return 0; |
1766 | } | 1841 | } |
@@ -1791,8 +1866,12 @@ static int nv_alloc_rx_optimized(struct net_device *dev) | |||
1791 | np->put_rx.ex = np->first_rx.ex; | 1866 | np->put_rx.ex = np->first_rx.ex; |
1792 | if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx)) | 1867 | if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx)) |
1793 | np->put_rx_ctx = np->first_rx_ctx; | 1868 | np->put_rx_ctx = np->first_rx_ctx; |
1794 | } else | 1869 | } else { |
1870 | u64_stats_update_begin(&np->swstats_rx_syncp); | ||
1871 | np->stat_rx_dropped++; | ||
1872 | u64_stats_update_end(&np->swstats_rx_syncp); | ||
1795 | return 1; | 1873 | return 1; |
1874 | } | ||
1796 | } | 1875 | } |
1797 | return 0; | 1876 | return 0; |
1798 | } | 1877 | } |
@@ -1927,8 +2006,11 @@ static void nv_drain_tx(struct net_device *dev) | |||
1927 | np->tx_ring.ex[i].bufhigh = 0; | 2006 | np->tx_ring.ex[i].bufhigh = 0; |
1928 | np->tx_ring.ex[i].buflow = 0; | 2007 | np->tx_ring.ex[i].buflow = 0; |
1929 | } | 2008 | } |
1930 | if (nv_release_txskb(np, &np->tx_skb[i])) | 2009 | if (nv_release_txskb(np, &np->tx_skb[i])) { |
1931 | dev->stats.tx_dropped++; | 2010 | u64_stats_update_begin(&np->swstats_tx_syncp); |
2011 | np->stat_tx_dropped++; | ||
2012 | u64_stats_update_end(&np->swstats_tx_syncp); | ||
2013 | } | ||
1932 | np->tx_skb[i].dma = 0; | 2014 | np->tx_skb[i].dma = 0; |
1933 | np->tx_skb[i].dma_len = 0; | 2015 | np->tx_skb[i].dma_len = 0; |
1934 | np->tx_skb[i].dma_single = 0; | 2016 | np->tx_skb[i].dma_single = 0; |
@@ -2385,11 +2467,14 @@ static int nv_tx_done(struct net_device *dev, int limit) | |||
2385 | if (np->desc_ver == DESC_VER_1) { | 2467 | if (np->desc_ver == DESC_VER_1) { |
2386 | if (flags & NV_TX_LASTPACKET) { | 2468 | if (flags & NV_TX_LASTPACKET) { |
2387 | if (flags & NV_TX_ERROR) { | 2469 | if (flags & NV_TX_ERROR) { |
2388 | if ((flags & NV_TX_RETRYERROR) && !(flags & NV_TX_RETRYCOUNT_MASK)) | 2470 | if ((flags & NV_TX_RETRYERROR) |
2471 | && !(flags & NV_TX_RETRYCOUNT_MASK)) | ||
2389 | nv_legacybackoff_reseed(dev); | 2472 | nv_legacybackoff_reseed(dev); |
2390 | } else { | 2473 | } else { |
2391 | dev->stats.tx_packets++; | 2474 | u64_stats_update_begin(&np->swstats_tx_syncp); |
2392 | dev->stats.tx_bytes += np->get_tx_ctx->skb->len; | 2475 | np->stat_tx_packets++; |
2476 | np->stat_tx_bytes += np->get_tx_ctx->skb->len; | ||
2477 | u64_stats_update_end(&np->swstats_tx_syncp); | ||
2393 | } | 2478 | } |
2394 | dev_kfree_skb_any(np->get_tx_ctx->skb); | 2479 | dev_kfree_skb_any(np->get_tx_ctx->skb); |
2395 | np->get_tx_ctx->skb = NULL; | 2480 | np->get_tx_ctx->skb = NULL; |
@@ -2398,11 +2483,14 @@ static int nv_tx_done(struct net_device *dev, int limit) | |||
2398 | } else { | 2483 | } else { |
2399 | if (flags & NV_TX2_LASTPACKET) { | 2484 | if (flags & NV_TX2_LASTPACKET) { |
2400 | if (flags & NV_TX2_ERROR) { | 2485 | if (flags & NV_TX2_ERROR) { |
2401 | if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK)) | 2486 | if ((flags & NV_TX2_RETRYERROR) |
2487 | && !(flags & NV_TX2_RETRYCOUNT_MASK)) | ||
2402 | nv_legacybackoff_reseed(dev); | 2488 | nv_legacybackoff_reseed(dev); |
2403 | } else { | 2489 | } else { |
2404 | dev->stats.tx_packets++; | 2490 | u64_stats_update_begin(&np->swstats_tx_syncp); |
2405 | dev->stats.tx_bytes += np->get_tx_ctx->skb->len; | 2491 | np->stat_tx_packets++; |
2492 | np->stat_tx_bytes += np->get_tx_ctx->skb->len; | ||
2493 | u64_stats_update_end(&np->swstats_tx_syncp); | ||
2406 | } | 2494 | } |
2407 | dev_kfree_skb_any(np->get_tx_ctx->skb); | 2495 | dev_kfree_skb_any(np->get_tx_ctx->skb); |
2408 | np->get_tx_ctx->skb = NULL; | 2496 | np->get_tx_ctx->skb = NULL; |
@@ -2436,15 +2524,18 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit) | |||
2436 | 2524 | ||
2437 | if (flags & NV_TX2_LASTPACKET) { | 2525 | if (flags & NV_TX2_LASTPACKET) { |
2438 | if (flags & NV_TX2_ERROR) { | 2526 | if (flags & NV_TX2_ERROR) { |
2439 | if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK)) { | 2527 | if ((flags & NV_TX2_RETRYERROR) |
2528 | && !(flags & NV_TX2_RETRYCOUNT_MASK)) { | ||
2440 | if (np->driver_data & DEV_HAS_GEAR_MODE) | 2529 | if (np->driver_data & DEV_HAS_GEAR_MODE) |
2441 | nv_gear_backoff_reseed(dev); | 2530 | nv_gear_backoff_reseed(dev); |
2442 | else | 2531 | else |
2443 | nv_legacybackoff_reseed(dev); | 2532 | nv_legacybackoff_reseed(dev); |
2444 | } | 2533 | } |
2445 | } else { | 2534 | } else { |
2446 | dev->stats.tx_packets++; | 2535 | u64_stats_update_begin(&np->swstats_tx_syncp); |
2447 | dev->stats.tx_bytes += np->get_tx_ctx->skb->len; | 2536 | np->stat_tx_packets++; |
2537 | np->stat_tx_bytes += np->get_tx_ctx->skb->len; | ||
2538 | u64_stats_update_end(&np->swstats_tx_syncp); | ||
2448 | } | 2539 | } |
2449 | 2540 | ||
2450 | dev_kfree_skb_any(np->get_tx_ctx->skb); | 2541 | dev_kfree_skb_any(np->get_tx_ctx->skb); |
@@ -2477,56 +2568,64 @@ static void nv_tx_timeout(struct net_device *dev) | |||
2477 | u32 status; | 2568 | u32 status; |
2478 | union ring_type put_tx; | 2569 | union ring_type put_tx; |
2479 | int saved_tx_limit; | 2570 | int saved_tx_limit; |
2480 | int i; | ||
2481 | 2571 | ||
2482 | if (np->msi_flags & NV_MSI_X_ENABLED) | 2572 | if (np->msi_flags & NV_MSI_X_ENABLED) |
2483 | status = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK; | 2573 | status = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK; |
2484 | else | 2574 | else |
2485 | status = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; | 2575 | status = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; |
2486 | 2576 | ||
2487 | netdev_info(dev, "Got tx_timeout. irq: %08x\n", status); | 2577 | netdev_warn(dev, "Got tx_timeout. irq status: %08x\n", status); |
2488 | 2578 | ||
2489 | netdev_info(dev, "Ring at %lx\n", (unsigned long)np->ring_addr); | 2579 | if (unlikely(debug_tx_timeout)) { |
2490 | netdev_info(dev, "Dumping tx registers\n"); | 2580 | int i; |
2491 | for (i = 0; i <= np->register_size; i += 32) { | 2581 | |
2492 | netdev_info(dev, | 2582 | netdev_info(dev, "Ring at %lx\n", (unsigned long)np->ring_addr); |
2493 | "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", | 2583 | netdev_info(dev, "Dumping tx registers\n"); |
2494 | i, | 2584 | for (i = 0; i <= np->register_size; i += 32) { |
2495 | readl(base + i + 0), readl(base + i + 4), | ||
2496 | readl(base + i + 8), readl(base + i + 12), | ||
2497 | readl(base + i + 16), readl(base + i + 20), | ||
2498 | readl(base + i + 24), readl(base + i + 28)); | ||
2499 | } | ||
2500 | netdev_info(dev, "Dumping tx ring\n"); | ||
2501 | for (i = 0; i < np->tx_ring_size; i += 4) { | ||
2502 | if (!nv_optimized(np)) { | ||
2503 | netdev_info(dev, | ||
2504 | "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n", | ||
2505 | i, | ||
2506 | le32_to_cpu(np->tx_ring.orig[i].buf), | ||
2507 | le32_to_cpu(np->tx_ring.orig[i].flaglen), | ||
2508 | le32_to_cpu(np->tx_ring.orig[i+1].buf), | ||
2509 | le32_to_cpu(np->tx_ring.orig[i+1].flaglen), | ||
2510 | le32_to_cpu(np->tx_ring.orig[i+2].buf), | ||
2511 | le32_to_cpu(np->tx_ring.orig[i+2].flaglen), | ||
2512 | le32_to_cpu(np->tx_ring.orig[i+3].buf), | ||
2513 | le32_to_cpu(np->tx_ring.orig[i+3].flaglen)); | ||
2514 | } else { | ||
2515 | netdev_info(dev, | 2585 | netdev_info(dev, |
2516 | "%03x: %08x %08x %08x // %08x %08x %08x // %08x %08x %08x // %08x %08x %08x\n", | 2586 | "%3x: %08x %08x %08x %08x " |
2587 | "%08x %08x %08x %08x\n", | ||
2517 | i, | 2588 | i, |
2518 | le32_to_cpu(np->tx_ring.ex[i].bufhigh), | 2589 | readl(base + i + 0), readl(base + i + 4), |
2519 | le32_to_cpu(np->tx_ring.ex[i].buflow), | 2590 | readl(base + i + 8), readl(base + i + 12), |
2520 | le32_to_cpu(np->tx_ring.ex[i].flaglen), | 2591 | readl(base + i + 16), readl(base + i + 20), |
2521 | le32_to_cpu(np->tx_ring.ex[i+1].bufhigh), | 2592 | readl(base + i + 24), readl(base + i + 28)); |
2522 | le32_to_cpu(np->tx_ring.ex[i+1].buflow), | 2593 | } |
2523 | le32_to_cpu(np->tx_ring.ex[i+1].flaglen), | 2594 | netdev_info(dev, "Dumping tx ring\n"); |
2524 | le32_to_cpu(np->tx_ring.ex[i+2].bufhigh), | 2595 | for (i = 0; i < np->tx_ring_size; i += 4) { |
2525 | le32_to_cpu(np->tx_ring.ex[i+2].buflow), | 2596 | if (!nv_optimized(np)) { |
2526 | le32_to_cpu(np->tx_ring.ex[i+2].flaglen), | 2597 | netdev_info(dev, |
2527 | le32_to_cpu(np->tx_ring.ex[i+3].bufhigh), | 2598 | "%03x: %08x %08x // %08x %08x " |
2528 | le32_to_cpu(np->tx_ring.ex[i+3].buflow), | 2599 | "// %08x %08x // %08x %08x\n", |
2529 | le32_to_cpu(np->tx_ring.ex[i+3].flaglen)); | 2600 | i, |
2601 | le32_to_cpu(np->tx_ring.orig[i].buf), | ||
2602 | le32_to_cpu(np->tx_ring.orig[i].flaglen), | ||
2603 | le32_to_cpu(np->tx_ring.orig[i+1].buf), | ||
2604 | le32_to_cpu(np->tx_ring.orig[i+1].flaglen), | ||
2605 | le32_to_cpu(np->tx_ring.orig[i+2].buf), | ||
2606 | le32_to_cpu(np->tx_ring.orig[i+2].flaglen), | ||
2607 | le32_to_cpu(np->tx_ring.orig[i+3].buf), | ||
2608 | le32_to_cpu(np->tx_ring.orig[i+3].flaglen)); | ||
2609 | } else { | ||
2610 | netdev_info(dev, | ||
2611 | "%03x: %08x %08x %08x " | ||
2612 | "// %08x %08x %08x " | ||
2613 | "// %08x %08x %08x " | ||
2614 | "// %08x %08x %08x\n", | ||
2615 | i, | ||
2616 | le32_to_cpu(np->tx_ring.ex[i].bufhigh), | ||
2617 | le32_to_cpu(np->tx_ring.ex[i].buflow), | ||
2618 | le32_to_cpu(np->tx_ring.ex[i].flaglen), | ||
2619 | le32_to_cpu(np->tx_ring.ex[i+1].bufhigh), | ||
2620 | le32_to_cpu(np->tx_ring.ex[i+1].buflow), | ||
2621 | le32_to_cpu(np->tx_ring.ex[i+1].flaglen), | ||
2622 | le32_to_cpu(np->tx_ring.ex[i+2].bufhigh), | ||
2623 | le32_to_cpu(np->tx_ring.ex[i+2].buflow), | ||
2624 | le32_to_cpu(np->tx_ring.ex[i+2].flaglen), | ||
2625 | le32_to_cpu(np->tx_ring.ex[i+3].bufhigh), | ||
2626 | le32_to_cpu(np->tx_ring.ex[i+3].buflow), | ||
2627 | le32_to_cpu(np->tx_ring.ex[i+3].flaglen)); | ||
2628 | } | ||
2530 | } | 2629 | } |
2531 | } | 2630 | } |
2532 | 2631 | ||
@@ -2649,8 +2748,11 @@ static int nv_rx_process(struct net_device *dev, int limit) | |||
2649 | } | 2748 | } |
2650 | /* the rest are hard errors */ | 2749 | /* the rest are hard errors */ |
2651 | else { | 2750 | else { |
2652 | if (flags & NV_RX_MISSEDFRAME) | 2751 | if (flags & NV_RX_MISSEDFRAME) { |
2653 | dev->stats.rx_missed_errors++; | 2752 | u64_stats_update_begin(&np->swstats_rx_syncp); |
2753 | np->stat_rx_missed_errors++; | ||
2754 | u64_stats_update_end(&np->swstats_rx_syncp); | ||
2755 | } | ||
2654 | dev_kfree_skb(skb); | 2756 | dev_kfree_skb(skb); |
2655 | goto next_pkt; | 2757 | goto next_pkt; |
2656 | } | 2758 | } |
@@ -2693,8 +2795,10 @@ static int nv_rx_process(struct net_device *dev, int limit) | |||
2693 | skb_put(skb, len); | 2795 | skb_put(skb, len); |
2694 | skb->protocol = eth_type_trans(skb, dev); | 2796 | skb->protocol = eth_type_trans(skb, dev); |
2695 | napi_gro_receive(&np->napi, skb); | 2797 | napi_gro_receive(&np->napi, skb); |
2696 | dev->stats.rx_packets++; | 2798 | u64_stats_update_begin(&np->swstats_rx_syncp); |
2697 | dev->stats.rx_bytes += len; | 2799 | np->stat_rx_packets++; |
2800 | np->stat_rx_bytes += len; | ||
2801 | u64_stats_update_end(&np->swstats_rx_syncp); | ||
2698 | next_pkt: | 2802 | next_pkt: |
2699 | if (unlikely(np->get_rx.orig++ == np->last_rx.orig)) | 2803 | if (unlikely(np->get_rx.orig++ == np->last_rx.orig)) |
2700 | np->get_rx.orig = np->first_rx.orig; | 2804 | np->get_rx.orig = np->first_rx.orig; |
@@ -2777,8 +2881,10 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) | |||
2777 | __vlan_hwaccel_put_tag(skb, vid); | 2881 | __vlan_hwaccel_put_tag(skb, vid); |
2778 | } | 2882 | } |
2779 | napi_gro_receive(&np->napi, skb); | 2883 | napi_gro_receive(&np->napi, skb); |
2780 | dev->stats.rx_packets++; | 2884 | u64_stats_update_begin(&np->swstats_rx_syncp); |
2781 | dev->stats.rx_bytes += len; | 2885 | np->stat_rx_packets++; |
2886 | np->stat_rx_bytes += len; | ||
2887 | u64_stats_update_end(&np->swstats_rx_syncp); | ||
2782 | } else { | 2888 | } else { |
2783 | dev_kfree_skb(skb); | 2889 | dev_kfree_skb(skb); |
2784 | } | 2890 | } |
@@ -3021,6 +3127,73 @@ static void nv_update_pause(struct net_device *dev, u32 pause_flags) | |||
3021 | } | 3127 | } |
3022 | } | 3128 | } |
3023 | 3129 | ||
3130 | static void nv_force_linkspeed(struct net_device *dev, int speed, int duplex) | ||
3131 | { | ||
3132 | struct fe_priv *np = netdev_priv(dev); | ||
3133 | u8 __iomem *base = get_hwbase(dev); | ||
3134 | u32 phyreg, txreg; | ||
3135 | int mii_status; | ||
3136 | |||
3137 | np->linkspeed = NVREG_LINKSPEED_FORCE|speed; | ||
3138 | np->duplex = duplex; | ||
3139 | |||
3140 | /* see if gigabit phy */ | ||
3141 | mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); | ||
3142 | if (mii_status & PHY_GIGABIT) { | ||
3143 | np->gigabit = PHY_GIGABIT; | ||
3144 | phyreg = readl(base + NvRegSlotTime); | ||
3145 | phyreg &= ~(0x3FF00); | ||
3146 | if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10) | ||
3147 | phyreg |= NVREG_SLOTTIME_10_100_FULL; | ||
3148 | else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) | ||
3149 | phyreg |= NVREG_SLOTTIME_10_100_FULL; | ||
3150 | else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) | ||
3151 | phyreg |= NVREG_SLOTTIME_1000_FULL; | ||
3152 | writel(phyreg, base + NvRegSlotTime); | ||
3153 | } | ||
3154 | |||
3155 | phyreg = readl(base + NvRegPhyInterface); | ||
3156 | phyreg &= ~(PHY_HALF|PHY_100|PHY_1000); | ||
3157 | if (np->duplex == 0) | ||
3158 | phyreg |= PHY_HALF; | ||
3159 | if ((np->linkspeed & NVREG_LINKSPEED_MASK) == NVREG_LINKSPEED_100) | ||
3160 | phyreg |= PHY_100; | ||
3161 | else if ((np->linkspeed & NVREG_LINKSPEED_MASK) == | ||
3162 | NVREG_LINKSPEED_1000) | ||
3163 | phyreg |= PHY_1000; | ||
3164 | writel(phyreg, base + NvRegPhyInterface); | ||
3165 | |||
3166 | if (phyreg & PHY_RGMII) { | ||
3167 | if ((np->linkspeed & NVREG_LINKSPEED_MASK) == | ||
3168 | NVREG_LINKSPEED_1000) | ||
3169 | txreg = NVREG_TX_DEFERRAL_RGMII_1000; | ||
3170 | else | ||
3171 | txreg = NVREG_TX_DEFERRAL_RGMII_10_100; | ||
3172 | } else { | ||
3173 | txreg = NVREG_TX_DEFERRAL_DEFAULT; | ||
3174 | } | ||
3175 | writel(txreg, base + NvRegTxDeferral); | ||
3176 | |||
3177 | if (np->desc_ver == DESC_VER_1) { | ||
3178 | txreg = NVREG_TX_WM_DESC1_DEFAULT; | ||
3179 | } else { | ||
3180 | if ((np->linkspeed & NVREG_LINKSPEED_MASK) == | ||
3181 | NVREG_LINKSPEED_1000) | ||
3182 | txreg = NVREG_TX_WM_DESC2_3_1000; | ||
3183 | else | ||
3184 | txreg = NVREG_TX_WM_DESC2_3_DEFAULT; | ||
3185 | } | ||
3186 | writel(txreg, base + NvRegTxWatermark); | ||
3187 | |||
3188 | writel(NVREG_MISC1_FORCE | (np->duplex ? 0 : NVREG_MISC1_HD), | ||
3189 | base + NvRegMisc1); | ||
3190 | pci_push(base); | ||
3191 | writel(np->linkspeed, base + NvRegLinkSpeed); | ||
3192 | pci_push(base); | ||
3193 | |||
3194 | return; | ||
3195 | } | ||
3196 | |||
3024 | /** | 3197 | /** |
3025 | * nv_update_linkspeed: Setup the MAC according to the link partner | 3198 | * nv_update_linkspeed: Setup the MAC according to the link partner |
3026 | * @dev: Network device to be configured | 3199 | * @dev: Network device to be configured |
@@ -3042,11 +3215,25 @@ static int nv_update_linkspeed(struct net_device *dev) | |||
3042 | int newls = np->linkspeed; | 3215 | int newls = np->linkspeed; |
3043 | int newdup = np->duplex; | 3216 | int newdup = np->duplex; |
3044 | int mii_status; | 3217 | int mii_status; |
3218 | u32 bmcr; | ||
3045 | int retval = 0; | 3219 | int retval = 0; |
3046 | u32 control_1000, status_1000, phyreg, pause_flags, txreg; | 3220 | u32 control_1000, status_1000, phyreg, pause_flags, txreg; |
3047 | u32 txrxFlags = 0; | 3221 | u32 txrxFlags = 0; |
3048 | u32 phy_exp; | 3222 | u32 phy_exp; |
3049 | 3223 | ||
3224 | /* If device loopback is enabled, set carrier on and enable max link | ||
3225 | * speed. | ||
3226 | */ | ||
3227 | bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); | ||
3228 | if (bmcr & BMCR_LOOPBACK) { | ||
3229 | if (netif_running(dev)) { | ||
3230 | nv_force_linkspeed(dev, NVREG_LINKSPEED_1000, 1); | ||
3231 | if (!netif_carrier_ok(dev)) | ||
3232 | netif_carrier_on(dev); | ||
3233 | } | ||
3234 | return 1; | ||
3235 | } | ||
3236 | |||
3050 | /* BMSR_LSTATUS is latched, read it twice: | 3237 | /* BMSR_LSTATUS is latched, read it twice: |
3051 | * we want the current value. | 3238 | * we want the current value. |
3052 | */ | 3239 | */ |
@@ -3729,6 +3916,7 @@ static int nv_request_irq(struct net_device *dev, int intr_test) | |||
3729 | writel(0, base + NvRegMSIXMap0); | 3916 | writel(0, base + NvRegMSIXMap0); |
3730 | writel(0, base + NvRegMSIXMap1); | 3917 | writel(0, base + NvRegMSIXMap1); |
3731 | } | 3918 | } |
3919 | netdev_info(dev, "MSI-X enabled\n"); | ||
3732 | } | 3920 | } |
3733 | } | 3921 | } |
3734 | if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { | 3922 | if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { |
@@ -3750,6 +3938,7 @@ static int nv_request_irq(struct net_device *dev, int intr_test) | |||
3750 | writel(0, base + NvRegMSIMap1); | 3938 | writel(0, base + NvRegMSIMap1); |
3751 | /* enable msi vector 0 */ | 3939 | /* enable msi vector 0 */ |
3752 | writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask); | 3940 | writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask); |
3941 | netdev_info(dev, "MSI enabled\n"); | ||
3753 | } | 3942 | } |
3754 | } | 3943 | } |
3755 | if (ret != 0) { | 3944 | if (ret != 0) { |
@@ -3904,11 +4093,18 @@ static void nv_poll_controller(struct net_device *dev) | |||
3904 | #endif | 4093 | #endif |
3905 | 4094 | ||
3906 | static void nv_do_stats_poll(unsigned long data) | 4095 | static void nv_do_stats_poll(unsigned long data) |
4096 | __acquires(&netdev_priv(dev)->hwstats_lock) | ||
4097 | __releases(&netdev_priv(dev)->hwstats_lock) | ||
3907 | { | 4098 | { |
3908 | struct net_device *dev = (struct net_device *) data; | 4099 | struct net_device *dev = (struct net_device *) data; |
3909 | struct fe_priv *np = netdev_priv(dev); | 4100 | struct fe_priv *np = netdev_priv(dev); |
3910 | 4101 | ||
3911 | nv_get_hw_stats(dev); | 4102 | /* If lock is currently taken, the stats are being refreshed |
4103 | * and hence fresh enough */ | ||
4104 | if (spin_trylock(&np->hwstats_lock)) { | ||
4105 | nv_update_stats(dev); | ||
4106 | spin_unlock(&np->hwstats_lock); | ||
4107 | } | ||
3912 | 4108 | ||
3913 | if (!np->in_shutdown) | 4109 | if (!np->in_shutdown) |
3914 | mod_timer(&np->stats_poll, | 4110 | mod_timer(&np->stats_poll, |
@@ -3918,9 +4114,9 @@ static void nv_do_stats_poll(unsigned long data) | |||
3918 | static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 4114 | static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
3919 | { | 4115 | { |
3920 | struct fe_priv *np = netdev_priv(dev); | 4116 | struct fe_priv *np = netdev_priv(dev); |
3921 | strcpy(info->driver, DRV_NAME); | 4117 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
3922 | strcpy(info->version, FORCEDETH_VERSION); | 4118 | strlcpy(info->version, FORCEDETH_VERSION, sizeof(info->version)); |
3923 | strcpy(info->bus_info, pci_name(np->pci_dev)); | 4119 | strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); |
3924 | } | 4120 | } |
3925 | 4121 | ||
3926 | static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo) | 4122 | static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo) |
@@ -4473,7 +4669,63 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* | |||
4473 | return 0; | 4669 | return 0; |
4474 | } | 4670 | } |
4475 | 4671 | ||
4476 | static u32 nv_fix_features(struct net_device *dev, u32 features) | 4672 | static int nv_set_loopback(struct net_device *dev, netdev_features_t features) |
4673 | { | ||
4674 | struct fe_priv *np = netdev_priv(dev); | ||
4675 | unsigned long flags; | ||
4676 | u32 miicontrol; | ||
4677 | int err, retval = 0; | ||
4678 | |||
4679 | spin_lock_irqsave(&np->lock, flags); | ||
4680 | miicontrol = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); | ||
4681 | if (features & NETIF_F_LOOPBACK) { | ||
4682 | if (miicontrol & BMCR_LOOPBACK) { | ||
4683 | spin_unlock_irqrestore(&np->lock, flags); | ||
4684 | netdev_info(dev, "Loopback already enabled\n"); | ||
4685 | return 0; | ||
4686 | } | ||
4687 | nv_disable_irq(dev); | ||
4688 | /* Turn on loopback mode */ | ||
4689 | miicontrol |= BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000; | ||
4690 | err = mii_rw(dev, np->phyaddr, MII_BMCR, miicontrol); | ||
4691 | if (err) { | ||
4692 | retval = PHY_ERROR; | ||
4693 | spin_unlock_irqrestore(&np->lock, flags); | ||
4694 | phy_init(dev); | ||
4695 | } else { | ||
4696 | if (netif_running(dev)) { | ||
4697 | /* Force 1000 Mbps full-duplex */ | ||
4698 | nv_force_linkspeed(dev, NVREG_LINKSPEED_1000, | ||
4699 | 1); | ||
4700 | /* Force link up */ | ||
4701 | netif_carrier_on(dev); | ||
4702 | } | ||
4703 | spin_unlock_irqrestore(&np->lock, flags); | ||
4704 | netdev_info(dev, | ||
4705 | "Internal PHY loopback mode enabled.\n"); | ||
4706 | } | ||
4707 | } else { | ||
4708 | if (!(miicontrol & BMCR_LOOPBACK)) { | ||
4709 | spin_unlock_irqrestore(&np->lock, flags); | ||
4710 | netdev_info(dev, "Loopback already disabled\n"); | ||
4711 | return 0; | ||
4712 | } | ||
4713 | nv_disable_irq(dev); | ||
4714 | /* Turn off loopback */ | ||
4715 | spin_unlock_irqrestore(&np->lock, flags); | ||
4716 | netdev_info(dev, "Internal PHY loopback mode disabled.\n"); | ||
4717 | phy_init(dev); | ||
4718 | } | ||
4719 | msleep(500); | ||
4720 | spin_lock_irqsave(&np->lock, flags); | ||
4721 | nv_enable_irq(dev); | ||
4722 | spin_unlock_irqrestore(&np->lock, flags); | ||
4723 | |||
4724 | return retval; | ||
4725 | } | ||
4726 | |||
4727 | static netdev_features_t nv_fix_features(struct net_device *dev, | ||
4728 | netdev_features_t features) | ||
4477 | { | 4729 | { |
4478 | /* vlan is dependent on rx checksum offload */ | 4730 | /* vlan is dependent on rx checksum offload */ |
4479 | if (features & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)) | 4731 | if (features & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)) |
@@ -4482,7 +4734,7 @@ static u32 nv_fix_features(struct net_device *dev, u32 features) | |||
4482 | return features; | 4734 | return features; |
4483 | } | 4735 | } |
4484 | 4736 | ||
4485 | static void nv_vlan_mode(struct net_device *dev, u32 features) | 4737 | static void nv_vlan_mode(struct net_device *dev, netdev_features_t features) |
4486 | { | 4738 | { |
4487 | struct fe_priv *np = get_nvpriv(dev); | 4739 | struct fe_priv *np = get_nvpriv(dev); |
4488 | 4740 | ||
@@ -4503,11 +4755,18 @@ static void nv_vlan_mode(struct net_device *dev, u32 features) | |||
4503 | spin_unlock_irq(&np->lock); | 4755 | spin_unlock_irq(&np->lock); |
4504 | } | 4756 | } |
4505 | 4757 | ||
4506 | static int nv_set_features(struct net_device *dev, u32 features) | 4758 | static int nv_set_features(struct net_device *dev, netdev_features_t features) |
4507 | { | 4759 | { |
4508 | struct fe_priv *np = netdev_priv(dev); | 4760 | struct fe_priv *np = netdev_priv(dev); |
4509 | u8 __iomem *base = get_hwbase(dev); | 4761 | u8 __iomem *base = get_hwbase(dev); |
4510 | u32 changed = dev->features ^ features; | 4762 | netdev_features_t changed = dev->features ^ features; |
4763 | int retval; | ||
4764 | |||
4765 | if ((changed & NETIF_F_LOOPBACK) && netif_running(dev)) { | ||
4766 | retval = nv_set_loopback(dev, features); | ||
4767 | if (retval != 0) | ||
4768 | return retval; | ||
4769 | } | ||
4511 | 4770 | ||
4512 | if (changed & NETIF_F_RXCSUM) { | 4771 | if (changed & NETIF_F_RXCSUM) { |
4513 | spin_lock_irq(&np->lock); | 4772 | spin_lock_irq(&np->lock); |
@@ -4553,14 +4812,18 @@ static int nv_get_sset_count(struct net_device *dev, int sset) | |||
4553 | } | 4812 | } |
4554 | } | 4813 | } |
4555 | 4814 | ||
4556 | static void nv_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *buffer) | 4815 | static void nv_get_ethtool_stats(struct net_device *dev, |
4816 | struct ethtool_stats *estats, u64 *buffer) | ||
4817 | __acquires(&netdev_priv(dev)->hwstats_lock) | ||
4818 | __releases(&netdev_priv(dev)->hwstats_lock) | ||
4557 | { | 4819 | { |
4558 | struct fe_priv *np = netdev_priv(dev); | 4820 | struct fe_priv *np = netdev_priv(dev); |
4559 | 4821 | ||
4560 | /* update stats */ | 4822 | spin_lock_bh(&np->hwstats_lock); |
4561 | nv_get_hw_stats(dev); | 4823 | nv_update_stats(dev); |
4562 | 4824 | memcpy(buffer, &np->estats, | |
4563 | memcpy(buffer, &np->estats, nv_get_sset_count(dev, ETH_SS_STATS)*sizeof(u64)); | 4825 | nv_get_sset_count(dev, ETH_SS_STATS)*sizeof(u64)); |
4826 | spin_unlock_bh(&np->hwstats_lock); | ||
4564 | } | 4827 | } |
4565 | 4828 | ||
4566 | static int nv_link_test(struct net_device *dev) | 4829 | static int nv_link_test(struct net_device *dev) |
@@ -5142,6 +5405,12 @@ static int nv_open(struct net_device *dev) | |||
5142 | 5405 | ||
5143 | spin_unlock_irq(&np->lock); | 5406 | spin_unlock_irq(&np->lock); |
5144 | 5407 | ||
5408 | /* If the loopback feature was set while the device was down, make sure | ||
5409 | * that it's set correctly now. | ||
5410 | */ | ||
5411 | if (dev->features & NETIF_F_LOOPBACK) | ||
5412 | nv_set_loopback(dev, dev->features); | ||
5413 | |||
5145 | return 0; | 5414 | return 0; |
5146 | out_drain: | 5415 | out_drain: |
5147 | nv_drain_rxtx(dev); | 5416 | nv_drain_rxtx(dev); |
@@ -5198,7 +5467,7 @@ static int nv_close(struct net_device *dev) | |||
5198 | static const struct net_device_ops nv_netdev_ops = { | 5467 | static const struct net_device_ops nv_netdev_ops = { |
5199 | .ndo_open = nv_open, | 5468 | .ndo_open = nv_open, |
5200 | .ndo_stop = nv_close, | 5469 | .ndo_stop = nv_close, |
5201 | .ndo_get_stats = nv_get_stats, | 5470 | .ndo_get_stats64 = nv_get_stats64, |
5202 | .ndo_start_xmit = nv_start_xmit, | 5471 | .ndo_start_xmit = nv_start_xmit, |
5203 | .ndo_tx_timeout = nv_tx_timeout, | 5472 | .ndo_tx_timeout = nv_tx_timeout, |
5204 | .ndo_change_mtu = nv_change_mtu, | 5473 | .ndo_change_mtu = nv_change_mtu, |
@@ -5215,7 +5484,7 @@ static const struct net_device_ops nv_netdev_ops = { | |||
5215 | static const struct net_device_ops nv_netdev_ops_optimized = { | 5484 | static const struct net_device_ops nv_netdev_ops_optimized = { |
5216 | .ndo_open = nv_open, | 5485 | .ndo_open = nv_open, |
5217 | .ndo_stop = nv_close, | 5486 | .ndo_stop = nv_close, |
5218 | .ndo_get_stats = nv_get_stats, | 5487 | .ndo_get_stats64 = nv_get_stats64, |
5219 | .ndo_start_xmit = nv_start_xmit_optimized, | 5488 | .ndo_start_xmit = nv_start_xmit_optimized, |
5220 | .ndo_tx_timeout = nv_tx_timeout, | 5489 | .ndo_tx_timeout = nv_tx_timeout, |
5221 | .ndo_change_mtu = nv_change_mtu, | 5490 | .ndo_change_mtu = nv_change_mtu, |
@@ -5254,6 +5523,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
5254 | np->dev = dev; | 5523 | np->dev = dev; |
5255 | np->pci_dev = pci_dev; | 5524 | np->pci_dev = pci_dev; |
5256 | spin_lock_init(&np->lock); | 5525 | spin_lock_init(&np->lock); |
5526 | spin_lock_init(&np->hwstats_lock); | ||
5257 | SET_NETDEV_DEV(dev, &pci_dev->dev); | 5527 | SET_NETDEV_DEV(dev, &pci_dev->dev); |
5258 | 5528 | ||
5259 | init_timer(&np->oom_kick); | 5529 | init_timer(&np->oom_kick); |
@@ -5262,7 +5532,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
5262 | init_timer(&np->nic_poll); | 5532 | init_timer(&np->nic_poll); |
5263 | np->nic_poll.data = (unsigned long) dev; | 5533 | np->nic_poll.data = (unsigned long) dev; |
5264 | np->nic_poll.function = nv_do_nic_poll; /* timer handler */ | 5534 | np->nic_poll.function = nv_do_nic_poll; /* timer handler */ |
5265 | init_timer(&np->stats_poll); | 5535 | init_timer_deferrable(&np->stats_poll); |
5266 | np->stats_poll.data = (unsigned long) dev; | 5536 | np->stats_poll.data = (unsigned long) dev; |
5267 | np->stats_poll.function = nv_do_stats_poll; /* timer handler */ | 5537 | np->stats_poll.function = nv_do_stats_poll; /* timer handler */ |
5268 | 5538 | ||
@@ -5346,6 +5616,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
5346 | 5616 | ||
5347 | dev->features |= dev->hw_features; | 5617 | dev->features |= dev->hw_features; |
5348 | 5618 | ||
5619 | /* Add loopback capability to the device. */ | ||
5620 | dev->hw_features |= NETIF_F_LOOPBACK; | ||
5621 | |||
5349 | np->pause_flags = NV_PAUSEFRAME_RX_CAPABLE | NV_PAUSEFRAME_RX_REQ | NV_PAUSEFRAME_AUTONEG; | 5622 | np->pause_flags = NV_PAUSEFRAME_RX_CAPABLE | NV_PAUSEFRAME_RX_REQ | NV_PAUSEFRAME_AUTONEG; |
5350 | if ((id->driver_data & DEV_HAS_PAUSEFRAME_TX_V1) || | 5623 | if ((id->driver_data & DEV_HAS_PAUSEFRAME_TX_V1) || |
5351 | (id->driver_data & DEV_HAS_PAUSEFRAME_TX_V2) || | 5624 | (id->driver_data & DEV_HAS_PAUSEFRAME_TX_V2) || |
@@ -5621,12 +5894,14 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
5621 | dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n", | 5894 | dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n", |
5622 | dev->name, np->phy_oui, np->phyaddr, dev->dev_addr); | 5895 | dev->name, np->phy_oui, np->phyaddr, dev->dev_addr); |
5623 | 5896 | ||
5624 | dev_info(&pci_dev->dev, "%s%s%s%s%s%s%s%s%s%sdesc-v%u\n", | 5897 | dev_info(&pci_dev->dev, "%s%s%s%s%s%s%s%s%s%s%sdesc-v%u\n", |
5625 | dev->features & NETIF_F_HIGHDMA ? "highdma " : "", | 5898 | dev->features & NETIF_F_HIGHDMA ? "highdma " : "", |
5626 | dev->features & (NETIF_F_IP_CSUM | NETIF_F_SG) ? | 5899 | dev->features & (NETIF_F_IP_CSUM | NETIF_F_SG) ? |
5627 | "csum " : "", | 5900 | "csum " : "", |
5628 | dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ? | 5901 | dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ? |
5629 | "vlan " : "", | 5902 | "vlan " : "", |
5903 | dev->features & (NETIF_F_LOOPBACK) ? | ||
5904 | "loopback " : "", | ||
5630 | id->driver_data & DEV_HAS_POWER_CNTRL ? "pwrctl " : "", | 5905 | id->driver_data & DEV_HAS_POWER_CNTRL ? "pwrctl " : "", |
5631 | id->driver_data & DEV_HAS_MGMT_UNIT ? "mgmt " : "", | 5906 | id->driver_data & DEV_HAS_MGMT_UNIT ? "mgmt " : "", |
5632 | id->driver_data & DEV_NEED_TIMERIRQ ? "timirq " : "", | 5907 | id->driver_data & DEV_NEED_TIMERIRQ ? "timirq " : "", |
@@ -6000,6 +6275,9 @@ module_param(phy_cross, int, 0); | |||
6000 | MODULE_PARM_DESC(phy_cross, "Phy crossover detection for Realtek 8201 phy is enabled by setting to 1 and disabled by setting to 0."); | 6275 | MODULE_PARM_DESC(phy_cross, "Phy crossover detection for Realtek 8201 phy is enabled by setting to 1 and disabled by setting to 0."); |
6001 | module_param(phy_power_down, int, 0); | 6276 | module_param(phy_power_down, int, 0); |
6002 | MODULE_PARM_DESC(phy_power_down, "Power down phy and disable link when interface is down (1), or leave phy powered up (0)."); | 6277 | MODULE_PARM_DESC(phy_power_down, "Power down phy and disable link when interface is down (1), or leave phy powered up (0)."); |
6278 | module_param(debug_tx_timeout, bool, 0); | ||
6279 | MODULE_PARM_DESC(debug_tx_timeout, | ||
6280 | "Dump tx related registers and ring when tx_timeout happens"); | ||
6003 | 6281 | ||
6004 | MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>"); | 6282 | MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>"); |
6005 | MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver"); | 6283 | MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver"); |
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c index 8c8027176bef..ac4e72d529e5 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c | |||
@@ -161,10 +161,10 @@ static void pch_gbe_get_drvinfo(struct net_device *netdev, | |||
161 | { | 161 | { |
162 | struct pch_gbe_adapter *adapter = netdev_priv(netdev); | 162 | struct pch_gbe_adapter *adapter = netdev_priv(netdev); |
163 | 163 | ||
164 | strcpy(drvinfo->driver, KBUILD_MODNAME); | 164 | strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); |
165 | strcpy(drvinfo->version, pch_driver_version); | 165 | strlcpy(drvinfo->version, pch_driver_version, sizeof(drvinfo->version)); |
166 | strcpy(drvinfo->fw_version, "N/A"); | 166 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), |
167 | strcpy(drvinfo->bus_info, pci_name(adapter->pdev)); | 167 | sizeof(drvinfo->bus_info)); |
168 | drvinfo->regdump_len = pch_gbe_get_regs_len(netdev); | 168 | drvinfo->regdump_len = pch_gbe_get_regs_len(netdev); |
169 | } | 169 | } |
170 | 170 | ||
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 48406ca382f1..964e9c0948bc 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 | |||
@@ -2109,10 +2109,11 @@ static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu) | |||
2109 | * Returns | 2109 | * Returns |
2110 | * 0: HW state updated successfully | 2110 | * 0: HW state updated successfully |
2111 | */ | 2111 | */ |
2112 | static int pch_gbe_set_features(struct net_device *netdev, u32 features) | 2112 | static int pch_gbe_set_features(struct net_device *netdev, |
2113 | netdev_features_t features) | ||
2113 | { | 2114 | { |
2114 | struct pch_gbe_adapter *adapter = netdev_priv(netdev); | 2115 | struct pch_gbe_adapter *adapter = netdev_priv(netdev); |
2115 | u32 changed = features ^ netdev->features; | 2116 | netdev_features_t changed = features ^ netdev->features; |
2116 | 2117 | ||
2117 | if (!(changed & NETIF_F_RXCSUM)) | 2118 | if (!(changed & NETIF_F_RXCSUM)) |
2118 | return 0; | 2119 | return 0; |
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c index e09ea83b8c47..8a371985319f 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c | |||
@@ -83,14 +83,18 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) | |||
83 | u32 fw_minor = 0; | 83 | u32 fw_minor = 0; |
84 | u32 fw_build = 0; | 84 | u32 fw_build = 0; |
85 | 85 | ||
86 | strncpy(drvinfo->driver, netxen_nic_driver_name, 32); | 86 | strlcpy(drvinfo->driver, netxen_nic_driver_name, |
87 | strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32); | 87 | sizeof(drvinfo->driver)); |
88 | strlcpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, | ||
89 | sizeof(drvinfo->version)); | ||
88 | fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); | 90 | fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); |
89 | fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR); | 91 | fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR); |
90 | fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB); | 92 | fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB); |
91 | sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build); | 93 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), |
94 | "%d.%d.%d", fw_major, fw_minor, fw_build); | ||
92 | 95 | ||
93 | strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | 96 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), |
97 | sizeof(drvinfo->bus_info)); | ||
94 | drvinfo->regdump_len = NETXEN_NIC_REGS_LEN; | 98 | drvinfo->regdump_len = NETXEN_NIC_REGS_LEN; |
95 | drvinfo->eedump_len = netxen_nic_get_eeprom_len(dev); | 99 | drvinfo->eedump_len = netxen_nic_get_eeprom_len(dev); |
96 | } | 100 | } |
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 8cf3173ba488..7dd9a4b107e6 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | |||
@@ -544,7 +544,8 @@ static void netxen_set_multicast_list(struct net_device *dev) | |||
544 | adapter->set_multi(dev); | 544 | adapter->set_multi(dev); |
545 | } | 545 | } |
546 | 546 | ||
547 | static u32 netxen_fix_features(struct net_device *dev, u32 features) | 547 | static netdev_features_t netxen_fix_features(struct net_device *dev, |
548 | netdev_features_t features) | ||
548 | { | 549 | { |
549 | if (!(features & NETIF_F_RXCSUM)) { | 550 | if (!(features & NETIF_F_RXCSUM)) { |
550 | netdev_info(dev, "disabling LRO as RXCSUM is off\n"); | 551 | netdev_info(dev, "disabling LRO as RXCSUM is off\n"); |
@@ -555,7 +556,8 @@ static u32 netxen_fix_features(struct net_device *dev, u32 features) | |||
555 | return features; | 556 | return features; |
556 | } | 557 | } |
557 | 558 | ||
558 | static int netxen_set_features(struct net_device *dev, u32 features) | 559 | static int netxen_set_features(struct net_device *dev, |
560 | netdev_features_t features) | ||
559 | { | 561 | { |
560 | struct netxen_adapter *adapter = netdev_priv(dev); | 562 | struct netxen_adapter *adapter = netdev_priv(dev); |
561 | int hw_lro; | 563 | int hw_lro; |
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index a4bdff438a5e..7931531c3a40 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c | |||
@@ -1735,10 +1735,11 @@ static void ql_get_drvinfo(struct net_device *ndev, | |||
1735 | struct ethtool_drvinfo *drvinfo) | 1735 | struct ethtool_drvinfo *drvinfo) |
1736 | { | 1736 | { |
1737 | struct ql3_adapter *qdev = netdev_priv(ndev); | 1737 | struct ql3_adapter *qdev = netdev_priv(ndev); |
1738 | strncpy(drvinfo->driver, ql3xxx_driver_name, 32); | 1738 | strlcpy(drvinfo->driver, ql3xxx_driver_name, sizeof(drvinfo->driver)); |
1739 | strncpy(drvinfo->version, ql3xxx_driver_version, 32); | 1739 | strlcpy(drvinfo->version, ql3xxx_driver_version, |
1740 | strncpy(drvinfo->fw_version, "N/A", 32); | 1740 | sizeof(drvinfo->version)); |
1741 | strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32); | 1741 | strlcpy(drvinfo->bus_info, pci_name(qdev->pdev), |
1742 | sizeof(drvinfo->bus_info)); | ||
1742 | drvinfo->regdump_len = 0; | 1743 | drvinfo->regdump_len = 0; |
1743 | drvinfo->eedump_len = 0; | 1744 | drvinfo->eedump_len = 0; |
1744 | } | 1745 | } |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 7ed53dbb8646..60976fc4ccc6 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -1466,8 +1466,9 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup); | |||
1466 | 1466 | ||
1467 | int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu); | 1467 | int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu); |
1468 | int qlcnic_change_mtu(struct net_device *netdev, int new_mtu); | 1468 | int qlcnic_change_mtu(struct net_device *netdev, int new_mtu); |
1469 | u32 qlcnic_fix_features(struct net_device *netdev, u32 features); | 1469 | netdev_features_t qlcnic_fix_features(struct net_device *netdev, |
1470 | int qlcnic_set_features(struct net_device *netdev, u32 features); | 1470 | netdev_features_t features); |
1471 | int qlcnic_set_features(struct net_device *netdev, netdev_features_t features); | ||
1471 | int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable); | 1472 | int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable); |
1472 | int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable); | 1473 | int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable); |
1473 | int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter); | 1474 | int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 8aa1c6e8667b..cc228cf3d84b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | |||
@@ -140,11 +140,14 @@ qlcnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) | |||
140 | fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR); | 140 | fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR); |
141 | fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR); | 141 | fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR); |
142 | fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB); | 142 | fw_build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB); |
143 | sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build); | 143 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), |
144 | 144 | "%d.%d.%d", fw_major, fw_minor, fw_build); | |
145 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); | 145 | |
146 | strlcpy(drvinfo->driver, qlcnic_driver_name, 32); | 146 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), |
147 | strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID, 32); | 147 | sizeof(drvinfo->bus_info)); |
148 | strlcpy(drvinfo->driver, qlcnic_driver_name, sizeof(drvinfo->driver)); | ||
149 | strlcpy(drvinfo->version, QLCNIC_LINUX_VERSIONID, | ||
150 | sizeof(drvinfo->version)); | ||
148 | } | 151 | } |
149 | 152 | ||
150 | static int | 153 | static int |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index bcb81e47543a..b528e52a8ee1 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | |||
@@ -817,12 +817,13 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu) | |||
817 | } | 817 | } |
818 | 818 | ||
819 | 819 | ||
820 | u32 qlcnic_fix_features(struct net_device *netdev, u32 features) | 820 | netdev_features_t qlcnic_fix_features(struct net_device *netdev, |
821 | netdev_features_t features) | ||
821 | { | 822 | { |
822 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 823 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
823 | 824 | ||
824 | if ((adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | 825 | if ((adapter->flags & QLCNIC_ESWITCH_ENABLED)) { |
825 | u32 changed = features ^ netdev->features; | 826 | netdev_features_t changed = features ^ netdev->features; |
826 | features ^= changed & (NETIF_F_ALL_CSUM | NETIF_F_RXCSUM); | 827 | features ^= changed & (NETIF_F_ALL_CSUM | NETIF_F_RXCSUM); |
827 | } | 828 | } |
828 | 829 | ||
@@ -833,10 +834,10 @@ u32 qlcnic_fix_features(struct net_device *netdev, u32 features) | |||
833 | } | 834 | } |
834 | 835 | ||
835 | 836 | ||
836 | int qlcnic_set_features(struct net_device *netdev, u32 features) | 837 | int qlcnic_set_features(struct net_device *netdev, netdev_features_t features) |
837 | { | 838 | { |
838 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 839 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
839 | u32 changed = netdev->features ^ features; | 840 | netdev_features_t changed = netdev->features ^ features; |
840 | int hw_lro = (features & NETIF_F_LRO) ? QLCNIC_LRO_ENABLED : 0; | 841 | int hw_lro = (features & NETIF_F_LRO) ? QLCNIC_LRO_ENABLED : 0; |
841 | 842 | ||
842 | if (!(changed & NETIF_F_LRO)) | 843 | if (!(changed & NETIF_F_LRO)) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 0bd163828e33..823f845ddc04 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -792,7 +792,7 @@ qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, | |||
792 | struct qlcnic_esw_func_cfg *esw_cfg) | 792 | struct qlcnic_esw_func_cfg *esw_cfg) |
793 | { | 793 | { |
794 | struct net_device *netdev = adapter->netdev; | 794 | struct net_device *netdev = adapter->netdev; |
795 | unsigned long features, vlan_features; | 795 | netdev_features_t features, vlan_features; |
796 | 796 | ||
797 | features = (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | | 797 | features = (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | |
798 | NETIF_F_IPV6_CSUM | NETIF_F_GRO); | 798 | NETIF_F_IPV6_CSUM | NETIF_F_GRO); |
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c b/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c index 9b67bfea035f..8e2c2a74f3a5 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c | |||
@@ -366,13 +366,16 @@ static void ql_get_drvinfo(struct net_device *ndev, | |||
366 | struct ethtool_drvinfo *drvinfo) | 366 | struct ethtool_drvinfo *drvinfo) |
367 | { | 367 | { |
368 | struct ql_adapter *qdev = netdev_priv(ndev); | 368 | struct ql_adapter *qdev = netdev_priv(ndev); |
369 | strncpy(drvinfo->driver, qlge_driver_name, 32); | 369 | strlcpy(drvinfo->driver, qlge_driver_name, sizeof(drvinfo->driver)); |
370 | strncpy(drvinfo->version, qlge_driver_version, 32); | 370 | strlcpy(drvinfo->version, qlge_driver_version, |
371 | snprintf(drvinfo->fw_version, 32, "v%d.%d.%d", | 371 | sizeof(drvinfo->version)); |
372 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), | ||
373 | "v%d.%d.%d", | ||
372 | (qdev->fw_rev_id & 0x00ff0000) >> 16, | 374 | (qdev->fw_rev_id & 0x00ff0000) >> 16, |
373 | (qdev->fw_rev_id & 0x0000ff00) >> 8, | 375 | (qdev->fw_rev_id & 0x0000ff00) >> 8, |
374 | (qdev->fw_rev_id & 0x000000ff)); | 376 | (qdev->fw_rev_id & 0x000000ff)); |
375 | strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32); | 377 | strlcpy(drvinfo->bus_info, pci_name(qdev->pdev), |
378 | sizeof(drvinfo->bus_info)); | ||
376 | drvinfo->n_stats = 0; | 379 | drvinfo->n_stats = 0; |
377 | drvinfo->testinfo_len = 0; | 380 | drvinfo->testinfo_len = 0; |
378 | if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) | 381 | if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) |
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index c92afcd912e2..1ce4e08037b8 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c | |||
@@ -2307,7 +2307,7 @@ static int ql_napi_poll_msix(struct napi_struct *napi, int budget) | |||
2307 | return work_done; | 2307 | return work_done; |
2308 | } | 2308 | } |
2309 | 2309 | ||
2310 | static void qlge_vlan_mode(struct net_device *ndev, u32 features) | 2310 | static void qlge_vlan_mode(struct net_device *ndev, netdev_features_t features) |
2311 | { | 2311 | { |
2312 | struct ql_adapter *qdev = netdev_priv(ndev); | 2312 | struct ql_adapter *qdev = netdev_priv(ndev); |
2313 | 2313 | ||
@@ -2323,7 +2323,8 @@ static void qlge_vlan_mode(struct net_device *ndev, u32 features) | |||
2323 | } | 2323 | } |
2324 | } | 2324 | } |
2325 | 2325 | ||
2326 | static u32 qlge_fix_features(struct net_device *ndev, u32 features) | 2326 | static netdev_features_t qlge_fix_features(struct net_device *ndev, |
2327 | netdev_features_t features) | ||
2327 | { | 2328 | { |
2328 | /* | 2329 | /* |
2329 | * Since there is no support for separate rx/tx vlan accel | 2330 | * Since there is no support for separate rx/tx vlan accel |
@@ -2337,9 +2338,10 @@ static u32 qlge_fix_features(struct net_device *ndev, u32 features) | |||
2337 | return features; | 2338 | return features; |
2338 | } | 2339 | } |
2339 | 2340 | ||
2340 | static int qlge_set_features(struct net_device *ndev, u32 features) | 2341 | static int qlge_set_features(struct net_device *ndev, |
2342 | netdev_features_t features) | ||
2341 | { | 2343 | { |
2342 | u32 changed = ndev->features ^ features; | 2344 | netdev_features_t changed = ndev->features ^ features; |
2343 | 2345 | ||
2344 | if (changed & NETIF_F_HW_VLAN_RX) | 2346 | if (changed & NETIF_F_HW_VLAN_RX) |
2345 | qlge_vlan_mode(ndev, features); | 2347 | qlge_vlan_mode(ndev, features); |
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c index ee5da9293ce0..87cff10f7be7 100644 --- a/drivers/net/ethernet/realtek/8139cp.c +++ b/drivers/net/ethernet/realtek/8139cp.c | |||
@@ -1319,9 +1319,9 @@ static void cp_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info | |||
1319 | { | 1319 | { |
1320 | struct cp_private *cp = netdev_priv(dev); | 1320 | struct cp_private *cp = netdev_priv(dev); |
1321 | 1321 | ||
1322 | strcpy (info->driver, DRV_NAME); | 1322 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1323 | strcpy (info->version, DRV_VERSION); | 1323 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1324 | strcpy (info->bus_info, pci_name(cp->pdev)); | 1324 | strlcpy(info->bus_info, pci_name(cp->pdev), sizeof(info->bus_info)); |
1325 | } | 1325 | } |
1326 | 1326 | ||
1327 | static void cp_get_ringparam(struct net_device *dev, | 1327 | static void cp_get_ringparam(struct net_device *dev, |
@@ -1392,7 +1392,7 @@ static void cp_set_msglevel(struct net_device *dev, u32 value) | |||
1392 | cp->msg_enable = value; | 1392 | cp->msg_enable = value; |
1393 | } | 1393 | } |
1394 | 1394 | ||
1395 | static int cp_set_features(struct net_device *dev, u32 features) | 1395 | static int cp_set_features(struct net_device *dev, netdev_features_t features) |
1396 | { | 1396 | { |
1397 | struct cp_private *cp = netdev_priv(dev); | 1397 | struct cp_private *cp = netdev_priv(dev); |
1398 | unsigned long flags; | 1398 | unsigned long flags; |
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index 4d6b254fc6c1..d9c72273e428 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c | |||
@@ -2330,9 +2330,9 @@ static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
2330 | static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 2330 | static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
2331 | { | 2331 | { |
2332 | struct rtl8139_private *tp = netdev_priv(dev); | 2332 | struct rtl8139_private *tp = netdev_priv(dev); |
2333 | strcpy(info->driver, DRV_NAME); | 2333 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
2334 | strcpy(info->version, DRV_VERSION); | 2334 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
2335 | strcpy(info->bus_info, pci_name(tp->pci_dev)); | 2335 | strlcpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info)); |
2336 | info->regdump_len = tp->regs_len; | 2336 | info->regdump_len = tp->regs_len; |
2337 | } | 2337 | } |
2338 | 2338 | ||
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 6f06aa10f0d7..f7bc310f5185 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -69,9 +69,6 @@ | |||
69 | The RTL chips use a 64 element hash table based on the Ethernet CRC. */ | 69 | The RTL chips use a 64 element hash table based on the Ethernet CRC. */ |
70 | static const int multicast_filter_limit = 32; | 70 | static const int multicast_filter_limit = 32; |
71 | 71 | ||
72 | /* MAC address length */ | ||
73 | #define MAC_ADDR_LEN 6 | ||
74 | |||
75 | #define MAX_READ_REQUEST_SHIFT 12 | 72 | #define MAX_READ_REQUEST_SHIFT 12 |
76 | #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ | 73 | #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ |
77 | #define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ | 74 | #define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ |
@@ -1404,12 +1401,12 @@ static void rtl8169_get_drvinfo(struct net_device *dev, | |||
1404 | struct rtl8169_private *tp = netdev_priv(dev); | 1401 | struct rtl8169_private *tp = netdev_priv(dev); |
1405 | struct rtl_fw *rtl_fw = tp->rtl_fw; | 1402 | struct rtl_fw *rtl_fw = tp->rtl_fw; |
1406 | 1403 | ||
1407 | strcpy(info->driver, MODULENAME); | 1404 | strlcpy(info->driver, MODULENAME, sizeof(info->driver)); |
1408 | strcpy(info->version, RTL8169_VERSION); | 1405 | strlcpy(info->version, RTL8169_VERSION, sizeof(info->version)); |
1409 | strcpy(info->bus_info, pci_name(tp->pci_dev)); | 1406 | strlcpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info)); |
1410 | BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version)); | 1407 | BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version)); |
1411 | strcpy(info->fw_version, IS_ERR_OR_NULL(rtl_fw) ? "N/A" : | 1408 | strlcpy(info->fw_version, IS_ERR_OR_NULL(rtl_fw) ? "N/A" : |
1412 | rtl_fw->version); | 1409 | rtl_fw->version, sizeof(info->fw_version)); |
1413 | } | 1410 | } |
1414 | 1411 | ||
1415 | static int rtl8169_get_regs_len(struct net_device *dev) | 1412 | static int rtl8169_get_regs_len(struct net_device *dev) |
@@ -1553,7 +1550,8 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
1553 | return ret; | 1550 | return ret; |
1554 | } | 1551 | } |
1555 | 1552 | ||
1556 | static u32 rtl8169_fix_features(struct net_device *dev, u32 features) | 1553 | static netdev_features_t rtl8169_fix_features(struct net_device *dev, |
1554 | netdev_features_t features) | ||
1557 | { | 1555 | { |
1558 | struct rtl8169_private *tp = netdev_priv(dev); | 1556 | struct rtl8169_private *tp = netdev_priv(dev); |
1559 | 1557 | ||
@@ -1567,7 +1565,8 @@ static u32 rtl8169_fix_features(struct net_device *dev, u32 features) | |||
1567 | return features; | 1565 | return features; |
1568 | } | 1566 | } |
1569 | 1567 | ||
1570 | static int rtl8169_set_features(struct net_device *dev, u32 features) | 1568 | static int rtl8169_set_features(struct net_device *dev, |
1569 | netdev_features_t features) | ||
1571 | { | 1570 | { |
1572 | struct rtl8169_private *tp = netdev_priv(dev); | 1571 | struct rtl8169_private *tp = netdev_priv(dev); |
1573 | void __iomem *ioaddr = tp->mmio_addr; | 1572 | void __iomem *ioaddr = tp->mmio_addr; |
@@ -4099,7 +4098,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4099 | spin_lock_init(&tp->lock); | 4098 | spin_lock_init(&tp->lock); |
4100 | 4099 | ||
4101 | /* Get MAC address */ | 4100 | /* Get MAC address */ |
4102 | for (i = 0; i < MAC_ADDR_LEN; i++) | 4101 | for (i = 0; i < ETH_ALEN; i++) |
4103 | dev->dev_addr[i] = RTL_R8(MAC0 + i); | 4102 | dev->dev_addr[i] = RTL_R8(MAC0 + i); |
4104 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | 4103 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); |
4105 | 4104 | ||
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index d5731f1fe6d6..14e134d3b4d7 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
@@ -1900,7 +1900,7 @@ static void efx_set_multicast_list(struct net_device *net_dev) | |||
1900 | /* Otherwise efx_start_port() will do this */ | 1900 | /* Otherwise efx_start_port() will do this */ |
1901 | } | 1901 | } |
1902 | 1902 | ||
1903 | static int efx_set_features(struct net_device *net_dev, u32 data) | 1903 | static int efx_set_features(struct net_device *net_dev, netdev_features_t data) |
1904 | { | 1904 | { |
1905 | struct efx_nic *efx = netdev_priv(net_dev); | 1905 | struct efx_nic *efx = netdev_priv(net_dev); |
1906 | 1906 | ||
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index b8e251a1ee48..c49502bab6a3 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h | |||
@@ -908,7 +908,7 @@ struct efx_nic_type { | |||
908 | unsigned int phys_addr_channels; | 908 | unsigned int phys_addr_channels; |
909 | unsigned int tx_dc_base; | 909 | unsigned int tx_dc_base; |
910 | unsigned int rx_dc_base; | 910 | unsigned int rx_dc_base; |
911 | u32 offload_features; | 911 | netdev_features_t offload_features; |
912 | }; | 912 | }; |
913 | 913 | ||
914 | /************************************************************************** | 914 | /************************************************************************** |
diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c index 1b4658c99391..5b118cd5bf94 100644 --- a/drivers/net/ethernet/sis/sis190.c +++ b/drivers/net/ethernet/sis/sis190.c | |||
@@ -47,8 +47,6 @@ | |||
47 | #define sis190_rx_skb netif_rx | 47 | #define sis190_rx_skb netif_rx |
48 | #define sis190_rx_quota(count, quota) count | 48 | #define sis190_rx_quota(count, quota) count |
49 | 49 | ||
50 | #define MAC_ADDR_LEN 6 | ||
51 | |||
52 | #define NUM_TX_DESC 64 /* [8..1024] */ | 50 | #define NUM_TX_DESC 64 /* [8..1024] */ |
53 | #define NUM_RX_DESC 64 /* [8..8192] */ | 51 | #define NUM_RX_DESC 64 /* [8..8192] */ |
54 | #define TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) | 52 | #define TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) |
@@ -1601,7 +1599,7 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev, | |||
1601 | } | 1599 | } |
1602 | 1600 | ||
1603 | /* Get MAC address from EEPROM */ | 1601 | /* Get MAC address from EEPROM */ |
1604 | for (i = 0; i < MAC_ADDR_LEN / 2; i++) { | 1602 | for (i = 0; i < ETH_ALEN / 2; i++) { |
1605 | u16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i); | 1603 | u16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i); |
1606 | 1604 | ||
1607 | ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(w); | 1605 | ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(w); |
@@ -1653,7 +1651,7 @@ static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev, | |||
1653 | udelay(50); | 1651 | udelay(50); |
1654 | pci_read_config_byte(isa_bridge, 0x48, ®); | 1652 | pci_read_config_byte(isa_bridge, 0x48, ®); |
1655 | 1653 | ||
1656 | for (i = 0; i < MAC_ADDR_LEN; i++) { | 1654 | for (i = 0; i < ETH_ALEN; i++) { |
1657 | outb(0x9 + i, 0x78); | 1655 | outb(0x9 + i, 0x78); |
1658 | dev->dev_addr[i] = inb(0x79); | 1656 | dev->dev_addr[i] = inb(0x79); |
1659 | } | 1657 | } |
@@ -1692,7 +1690,7 @@ static inline void sis190_init_rxfilter(struct net_device *dev) | |||
1692 | */ | 1690 | */ |
1693 | SIS_W16(RxMacControl, ctl & ~0x0f00); | 1691 | SIS_W16(RxMacControl, ctl & ~0x0f00); |
1694 | 1692 | ||
1695 | for (i = 0; i < MAC_ADDR_LEN; i++) | 1693 | for (i = 0; i < ETH_ALEN; i++) |
1696 | SIS_W8(RxMacAddr + i, dev->dev_addr[i]); | 1694 | SIS_W8(RxMacAddr + i, dev->dev_addr[i]); |
1697 | 1695 | ||
1698 | SIS_W16(RxMacControl, ctl); | 1696 | SIS_W16(RxMacControl, ctl); |
@@ -1760,9 +1758,10 @@ static void sis190_get_drvinfo(struct net_device *dev, | |||
1760 | { | 1758 | { |
1761 | struct sis190_private *tp = netdev_priv(dev); | 1759 | struct sis190_private *tp = netdev_priv(dev); |
1762 | 1760 | ||
1763 | strcpy(info->driver, DRV_NAME); | 1761 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1764 | strcpy(info->version, DRV_VERSION); | 1762 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1765 | strcpy(info->bus_info, pci_name(tp->pci_dev)); | 1763 | strlcpy(info->bus_info, pci_name(tp->pci_dev), |
1764 | sizeof(info->bus_info)); | ||
1766 | } | 1765 | } |
1767 | 1766 | ||
1768 | static int sis190_get_regs_len(struct net_device *dev) | 1767 | static int sis190_get_regs_len(struct net_device *dev) |
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index a184abc5ef11..c8efc708c792 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c | |||
@@ -1991,9 +1991,10 @@ static void sis900_get_drvinfo(struct net_device *net_dev, | |||
1991 | { | 1991 | { |
1992 | struct sis900_private *sis_priv = netdev_priv(net_dev); | 1992 | struct sis900_private *sis_priv = netdev_priv(net_dev); |
1993 | 1993 | ||
1994 | strcpy (info->driver, SIS900_MODULE_NAME); | 1994 | strlcpy(info->driver, SIS900_MODULE_NAME, sizeof(info->driver)); |
1995 | strcpy (info->version, SIS900_DRV_VERSION); | 1995 | strlcpy(info->version, SIS900_DRV_VERSION, sizeof(info->version)); |
1996 | strcpy (info->bus_info, pci_name(sis_priv->pci_dev)); | 1996 | strlcpy(info->bus_info, pci_name(sis_priv->pci_dev), |
1997 | sizeof(info->bus_info)); | ||
1997 | } | 1998 | } |
1998 | 1999 | ||
1999 | static u32 sis900_get_msglevel(struct net_device *net_dev) | 2000 | static u32 sis900_get_msglevel(struct net_device *net_dev) |
diff --git a/drivers/net/ethernet/smsc/epic100.c b/drivers/net/ethernet/smsc/epic100.c index 0a5dfb814157..2c077ce0b6d6 100644 --- a/drivers/net/ethernet/smsc/epic100.c +++ b/drivers/net/ethernet/smsc/epic100.c | |||
@@ -1414,9 +1414,9 @@ static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo * | |||
1414 | { | 1414 | { |
1415 | struct epic_private *np = netdev_priv(dev); | 1415 | struct epic_private *np = netdev_priv(dev); |
1416 | 1416 | ||
1417 | strcpy (info->driver, DRV_NAME); | 1417 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1418 | strcpy (info->version, DRV_VERSION); | 1418 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1419 | strcpy (info->bus_info, pci_name(np->pci_dev)); | 1419 | strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); |
1420 | } | 1420 | } |
1421 | 1421 | ||
1422 | static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 1422 | static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
diff --git a/drivers/net/ethernet/smsc/smc91c92_cs.c b/drivers/net/ethernet/smsc/smc91c92_cs.c index cbfa98187131..ada927aba7a5 100644 --- a/drivers/net/ethernet/smsc/smc91c92_cs.c +++ b/drivers/net/ethernet/smsc/smc91c92_cs.c | |||
@@ -1909,8 +1909,8 @@ static int check_if_running(struct net_device *dev) | |||
1909 | 1909 | ||
1910 | static void smc_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 1910 | static void smc_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
1911 | { | 1911 | { |
1912 | strcpy(info->driver, DRV_NAME); | 1912 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1913 | strcpy(info->version, DRV_VERSION); | 1913 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1914 | } | 1914 | } |
1915 | 1915 | ||
1916 | static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | 1916 | static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) |
diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c index edb24b0e337b..a9efbdfe5302 100644 --- a/drivers/net/ethernet/smsc/smsc9420.c +++ b/drivers/net/ethernet/smsc/smsc9420.c | |||
@@ -279,9 +279,10 @@ static void smsc9420_ethtool_get_drvinfo(struct net_device *netdev, | |||
279 | { | 279 | { |
280 | struct smsc9420_pdata *pd = netdev_priv(netdev); | 280 | struct smsc9420_pdata *pd = netdev_priv(netdev); |
281 | 281 | ||
282 | strcpy(drvinfo->driver, DRV_NAME); | 282 | strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); |
283 | strcpy(drvinfo->bus_info, pci_name(pd->pdev)); | 283 | strlcpy(drvinfo->bus_info, pci_name(pd->pdev), |
284 | strcpy(drvinfo->version, DRV_VERSION); | 284 | sizeof(drvinfo->bus_info)); |
285 | strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); | ||
285 | } | 286 | } |
286 | 287 | ||
287 | static u32 smsc9420_ethtool_get_msglevel(struct net_device *netdev) | 288 | static u32 smsc9420_ethtool_get_msglevel(struct net_device *netdev) |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index 0395f9eba801..ed83c4c47b8a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | |||
@@ -185,9 +185,10 @@ static void stmmac_ethtool_getdrvinfo(struct net_device *dev, | |||
185 | struct stmmac_priv *priv = netdev_priv(dev); | 185 | struct stmmac_priv *priv = netdev_priv(dev); |
186 | 186 | ||
187 | if (priv->plat->has_gmac) | 187 | if (priv->plat->has_gmac) |
188 | strcpy(info->driver, GMAC_ETHTOOL_NAME); | 188 | strlcpy(info->driver, GMAC_ETHTOOL_NAME, sizeof(info->driver)); |
189 | else | 189 | else |
190 | strcpy(info->driver, MAC100_ETHTOOL_NAME); | 190 | strlcpy(info->driver, MAC100_ETHTOOL_NAME, |
191 | sizeof(info->driver)); | ||
191 | 192 | ||
192 | strcpy(info->version, DRV_MODULE_VERSION); | 193 | strcpy(info->version, DRV_MODULE_VERSION); |
193 | info->fw_version[0] = '\0'; | 194 | info->fw_version[0] = '\0'; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 72cd190b9c1a..20e8267e8e40 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -1470,7 +1470,8 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu) | |||
1470 | return 0; | 1470 | return 0; |
1471 | } | 1471 | } |
1472 | 1472 | ||
1473 | static u32 stmmac_fix_features(struct net_device *dev, u32 features) | 1473 | static netdev_features_t stmmac_fix_features(struct net_device *dev, |
1474 | netdev_features_t features) | ||
1474 | { | 1475 | { |
1475 | struct stmmac_priv *priv = netdev_priv(dev); | 1476 | struct stmmac_priv *priv = netdev_priv(dev); |
1476 | 1477 | ||
diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c index fd40988c19a6..f10665f594c4 100644 --- a/drivers/net/ethernet/sun/cassini.c +++ b/drivers/net/ethernet/sun/cassini.c | |||
@@ -4532,10 +4532,9 @@ static void cas_set_multicast(struct net_device *dev) | |||
4532 | static void cas_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 4532 | static void cas_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
4533 | { | 4533 | { |
4534 | struct cas *cp = netdev_priv(dev); | 4534 | struct cas *cp = netdev_priv(dev); |
4535 | strncpy(info->driver, DRV_MODULE_NAME, ETHTOOL_BUSINFO_LEN); | 4535 | strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); |
4536 | strncpy(info->version, DRV_MODULE_VERSION, ETHTOOL_BUSINFO_LEN); | 4536 | strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); |
4537 | info->fw_version[0] = '\0'; | 4537 | strlcpy(info->bus_info, pci_name(cp->pdev), sizeof(info->bus_info)); |
4538 | strncpy(info->bus_info, pci_name(cp->pdev), ETHTOOL_BUSINFO_LEN); | ||
4539 | info->regdump_len = cp->casreg_len < CAS_MAX_REGS ? | 4538 | info->regdump_len = cp->casreg_len < CAS_MAX_REGS ? |
4540 | cp->casreg_len : CAS_MAX_REGS; | 4539 | cp->casreg_len : CAS_MAX_REGS; |
4541 | info->n_stats = CAS_NUM_STAT_KEYS; | 4540 | info->n_stats = CAS_NUM_STAT_KEYS; |
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index 73c708107a37..680b107fdabd 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c | |||
@@ -1151,19 +1151,8 @@ static int link_status_mii(struct niu *np, int *link_up_p) | |||
1151 | supported |= SUPPORTED_1000baseT_Full; | 1151 | supported |= SUPPORTED_1000baseT_Full; |
1152 | lp->supported = supported; | 1152 | lp->supported = supported; |
1153 | 1153 | ||
1154 | advertising = 0; | 1154 | advertising = mii_adv_to_ethtool_adv_t(advert); |
1155 | if (advert & ADVERTISE_10HALF) | 1155 | advertising |= mii_ctrl1000_to_ethtool_adv_t(ctrl1000); |
1156 | advertising |= ADVERTISED_10baseT_Half; | ||
1157 | if (advert & ADVERTISE_10FULL) | ||
1158 | advertising |= ADVERTISED_10baseT_Full; | ||
1159 | if (advert & ADVERTISE_100HALF) | ||
1160 | advertising |= ADVERTISED_100baseT_Half; | ||
1161 | if (advert & ADVERTISE_100FULL) | ||
1162 | advertising |= ADVERTISED_100baseT_Full; | ||
1163 | if (ctrl1000 & ADVERTISE_1000HALF) | ||
1164 | advertising |= ADVERTISED_1000baseT_Half; | ||
1165 | if (ctrl1000 & ADVERTISE_1000FULL) | ||
1166 | advertising |= ADVERTISED_1000baseT_Full; | ||
1167 | 1156 | ||
1168 | if (bmcr & BMCR_ANENABLE) { | 1157 | if (bmcr & BMCR_ANENABLE) { |
1169 | int neg, neg1000; | 1158 | int neg, neg1000; |
@@ -6823,12 +6812,13 @@ static void niu_get_drvinfo(struct net_device *dev, | |||
6823 | struct niu *np = netdev_priv(dev); | 6812 | struct niu *np = netdev_priv(dev); |
6824 | struct niu_vpd *vpd = &np->vpd; | 6813 | struct niu_vpd *vpd = &np->vpd; |
6825 | 6814 | ||
6826 | strcpy(info->driver, DRV_MODULE_NAME); | 6815 | strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); |
6827 | strcpy(info->version, DRV_MODULE_VERSION); | 6816 | strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); |
6828 | sprintf(info->fw_version, "%d.%d", | 6817 | snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d", |
6829 | vpd->fcode_major, vpd->fcode_minor); | 6818 | vpd->fcode_major, vpd->fcode_minor); |
6830 | if (np->parent->plat_type != PLAT_TYPE_NIU) | 6819 | if (np->parent->plat_type != PLAT_TYPE_NIU) |
6831 | strcpy(info->bus_info, pci_name(np->pdev)); | 6820 | strlcpy(info->bus_info, pci_name(np->pdev), |
6821 | sizeof(info->bus_info)); | ||
6832 | } | 6822 | } |
6833 | 6823 | ||
6834 | static int niu_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 6824 | static int niu_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index ceab215bb4a3..31441a870b0b 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c | |||
@@ -2517,9 +2517,9 @@ static void gem_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info | |||
2517 | { | 2517 | { |
2518 | struct gem *gp = netdev_priv(dev); | 2518 | struct gem *gp = netdev_priv(dev); |
2519 | 2519 | ||
2520 | strcpy(info->driver, DRV_NAME); | 2520 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
2521 | strcpy(info->version, DRV_VERSION); | 2521 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
2522 | strcpy(info->bus_info, pci_name(gp->pdev)); | 2522 | strlcpy(info->bus_info, pci_name(gp->pdev), sizeof(info->bus_info)); |
2523 | } | 2523 | } |
2524 | 2524 | ||
2525 | static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 2525 | static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c index cf14ab9db576..eebd52f10365 100644 --- a/drivers/net/ethernet/sun/sunhme.c +++ b/drivers/net/ethernet/sun/sunhme.c | |||
@@ -2457,11 +2457,11 @@ static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info | |||
2457 | { | 2457 | { |
2458 | struct happy_meal *hp = netdev_priv(dev); | 2458 | struct happy_meal *hp = netdev_priv(dev); |
2459 | 2459 | ||
2460 | strcpy(info->driver, "sunhme"); | 2460 | strlcpy(info->driver, "sunhme", sizeof(info->driver)); |
2461 | strcpy(info->version, "2.02"); | 2461 | strlcpy(info->version, "2.02", sizeof(info->version)); |
2462 | if (hp->happy_flags & HFLAG_PCI) { | 2462 | if (hp->happy_flags & HFLAG_PCI) { |
2463 | struct pci_dev *pdev = hp->happy_dev; | 2463 | struct pci_dev *pdev = hp->happy_dev; |
2464 | strcpy(info->bus_info, pci_name(pdev)); | 2464 | strlcpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info)); |
2465 | } | 2465 | } |
2466 | #ifdef CONFIG_SBUS | 2466 | #ifdef CONFIG_SBUS |
2467 | else { | 2467 | else { |
@@ -2469,7 +2469,8 @@ static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info | |||
2469 | struct platform_device *op = hp->happy_dev; | 2469 | struct platform_device *op = hp->happy_dev; |
2470 | regs = of_get_property(op->dev.of_node, "regs", NULL); | 2470 | regs = of_get_property(op->dev.of_node, "regs", NULL); |
2471 | if (regs) | 2471 | if (regs) |
2472 | sprintf(info->bus_info, "SBUS:%d", | 2472 | snprintf(info->bus_info, sizeof(info->bus_info), |
2473 | "SBUS:%d", | ||
2473 | regs->which_io); | 2474 | regs->which_io); |
2474 | } | 2475 | } |
2475 | #endif | 2476 | #endif |
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c index f34dd99fe579..5587ecdf32e3 100644 --- a/drivers/net/ethernet/via/via-rhine.c +++ b/drivers/net/ethernet/via/via-rhine.c | |||
@@ -2009,9 +2009,9 @@ static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i | |||
2009 | { | 2009 | { |
2010 | struct rhine_private *rp = netdev_priv(dev); | 2010 | struct rhine_private *rp = netdev_priv(dev); |
2011 | 2011 | ||
2012 | strcpy(info->driver, DRV_NAME); | 2012 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
2013 | strcpy(info->version, DRV_VERSION); | 2013 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
2014 | strcpy(info->bus_info, pci_name(rp->pdev)); | 2014 | strlcpy(info->bus_info, pci_name(rp->pdev), sizeof(info->bus_info)); |
2015 | } | 2015 | } |
2016 | 2016 | ||
2017 | static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 2017 | static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index 4535d7cc848e..59bb5fd56afe 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c | |||
@@ -3270,9 +3270,9 @@ static int velocity_set_settings(struct net_device *dev, | |||
3270 | static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 3270 | static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
3271 | { | 3271 | { |
3272 | struct velocity_info *vptr = netdev_priv(dev); | 3272 | struct velocity_info *vptr = netdev_priv(dev); |
3273 | strcpy(info->driver, VELOCITY_NAME); | 3273 | strlcpy(info->driver, VELOCITY_NAME, sizeof(info->driver)); |
3274 | strcpy(info->version, VELOCITY_VERSION); | 3274 | strlcpy(info->version, VELOCITY_VERSION, sizeof(info->version)); |
3275 | strcpy(info->bus_info, pci_name(vptr->pdev)); | 3275 | strlcpy(info->bus_info, pci_name(vptr->pdev), sizeof(info->bus_info)); |
3276 | } | 3276 | } |
3277 | 3277 | ||
3278 | static void velocity_ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 3278 | static void velocity_ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 2681b53820ee..1ade9e18d299 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c | |||
@@ -920,12 +920,26 @@ temac_poll_controller(struct net_device *ndev) | |||
920 | } | 920 | } |
921 | #endif | 921 | #endif |
922 | 922 | ||
923 | static int temac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) | ||
924 | { | ||
925 | struct temac_local *lp = netdev_priv(ndev); | ||
926 | |||
927 | if (!netif_running(ndev)) | ||
928 | return -EINVAL; | ||
929 | |||
930 | if (!lp->phy_dev) | ||
931 | return -EINVAL; | ||
932 | |||
933 | return phy_mii_ioctl(lp->phy_dev, rq, cmd); | ||
934 | } | ||
935 | |||
923 | static const struct net_device_ops temac_netdev_ops = { | 936 | static const struct net_device_ops temac_netdev_ops = { |
924 | .ndo_open = temac_open, | 937 | .ndo_open = temac_open, |
925 | .ndo_stop = temac_stop, | 938 | .ndo_stop = temac_stop, |
926 | .ndo_start_xmit = temac_start_xmit, | 939 | .ndo_start_xmit = temac_start_xmit, |
927 | .ndo_set_mac_address = netdev_set_mac_address, | 940 | .ndo_set_mac_address = netdev_set_mac_address, |
928 | .ndo_validate_addr = eth_validate_addr, | 941 | .ndo_validate_addr = eth_validate_addr, |
942 | .ndo_do_ioctl = temac_ioctl, | ||
929 | #ifdef CONFIG_NET_POLL_CONTROLLER | 943 | #ifdef CONFIG_NET_POLL_CONTROLLER |
930 | .ndo_poll_controller = temac_poll_controller, | 944 | .ndo_poll_controller = temac_poll_controller, |
931 | #endif | 945 | #endif |
diff --git a/drivers/net/ethernet/xircom/xirc2ps_cs.c b/drivers/net/ethernet/xircom/xirc2ps_cs.c index bbe8b7dbf3f3..33979c3ac943 100644 --- a/drivers/net/ethernet/xircom/xirc2ps_cs.c +++ b/drivers/net/ethernet/xircom/xirc2ps_cs.c | |||
@@ -1411,7 +1411,7 @@ do_open(struct net_device *dev) | |||
1411 | static void netdev_get_drvinfo(struct net_device *dev, | 1411 | static void netdev_get_drvinfo(struct net_device *dev, |
1412 | struct ethtool_drvinfo *info) | 1412 | struct ethtool_drvinfo *info) |
1413 | { | 1413 | { |
1414 | strcpy(info->driver, "xirc2ps_cs"); | 1414 | strlcpy(info->driver, "xirc2ps_cs", sizeof(info->driver)); |
1415 | sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); | 1415 | sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr); |
1416 | } | 1416 | } |
1417 | 1417 | ||
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 46b5f5fd686b..e05b645bbc32 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c | |||
@@ -164,7 +164,7 @@ static const struct net_device_ops ifb_netdev_ops = { | |||
164 | .ndo_validate_addr = eth_validate_addr, | 164 | .ndo_validate_addr = eth_validate_addr, |
165 | }; | 165 | }; |
166 | 166 | ||
167 | #define IFB_FEATURES (NETIF_F_NO_CSUM | NETIF_F_SG | NETIF_F_FRAGLIST | \ | 167 | #define IFB_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_FRAGLIST | \ |
168 | NETIF_F_TSO_ECN | NETIF_F_TSO | NETIF_F_TSO6 | \ | 168 | NETIF_F_TSO_ECN | NETIF_F_TSO | NETIF_F_TSO6 | \ |
169 | NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_TX) | 169 | NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_TX) |
170 | 170 | ||
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 4ce9e5f2c069..b71998d0b5b4 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c | |||
@@ -169,7 +169,7 @@ static void loopback_setup(struct net_device *dev) | |||
169 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | 169 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST |
170 | | NETIF_F_ALL_TSO | 170 | | NETIF_F_ALL_TSO |
171 | | NETIF_F_UFO | 171 | | NETIF_F_UFO |
172 | | NETIF_F_NO_CSUM | 172 | | NETIF_F_HW_CSUM |
173 | | NETIF_F_RXCSUM | 173 | | NETIF_F_RXCSUM |
174 | | NETIF_F_HIGHDMA | 174 | | NETIF_F_HIGHDMA |
175 | | NETIF_F_LLTX | 175 | | NETIF_F_LLTX |
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 1b7082d08f33..7c88d136e723 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
@@ -145,8 +145,8 @@ static void macvtap_put_queue(struct macvtap_queue *q) | |||
145 | if (vlan) { | 145 | if (vlan) { |
146 | int index = get_slot(vlan, q); | 146 | int index = get_slot(vlan, q); |
147 | 147 | ||
148 | rcu_assign_pointer(vlan->taps[index], NULL); | 148 | RCU_INIT_POINTER(vlan->taps[index], NULL); |
149 | rcu_assign_pointer(q->vlan, NULL); | 149 | RCU_INIT_POINTER(q->vlan, NULL); |
150 | sock_put(&q->sk); | 150 | sock_put(&q->sk); |
151 | --vlan->numvtaps; | 151 | --vlan->numvtaps; |
152 | } | 152 | } |
@@ -223,8 +223,8 @@ static void macvtap_del_queues(struct net_device *dev) | |||
223 | lockdep_is_held(&macvtap_lock)); | 223 | lockdep_is_held(&macvtap_lock)); |
224 | if (q) { | 224 | if (q) { |
225 | qlist[j++] = q; | 225 | qlist[j++] = q; |
226 | rcu_assign_pointer(vlan->taps[i], NULL); | 226 | RCU_INIT_POINTER(vlan->taps[i], NULL); |
227 | rcu_assign_pointer(q->vlan, NULL); | 227 | RCU_INIT_POINTER(q->vlan, NULL); |
228 | vlan->numvtaps--; | 228 | vlan->numvtaps--; |
229 | } | 229 | } |
230 | } | 230 | } |
diff --git a/drivers/net/mii.c b/drivers/net/mii.c index c62e7816d548..c70c2332d15e 100644 --- a/drivers/net/mii.c +++ b/drivers/net/mii.c | |||
@@ -35,26 +35,11 @@ | |||
35 | 35 | ||
36 | static u32 mii_get_an(struct mii_if_info *mii, u16 addr) | 36 | static u32 mii_get_an(struct mii_if_info *mii, u16 addr) |
37 | { | 37 | { |
38 | u32 result = 0; | ||
39 | int advert; | 38 | int advert; |
40 | 39 | ||
41 | advert = mii->mdio_read(mii->dev, mii->phy_id, addr); | 40 | advert = mii->mdio_read(mii->dev, mii->phy_id, addr); |
42 | if (advert & LPA_LPACK) | 41 | |
43 | result |= ADVERTISED_Autoneg; | 42 | return mii_lpa_to_ethtool_lpa_t(advert); |
44 | if (advert & ADVERTISE_10HALF) | ||
45 | result |= ADVERTISED_10baseT_Half; | ||
46 | if (advert & ADVERTISE_10FULL) | ||
47 | result |= ADVERTISED_10baseT_Full; | ||
48 | if (advert & ADVERTISE_100HALF) | ||
49 | result |= ADVERTISED_100baseT_Half; | ||
50 | if (advert & ADVERTISE_100FULL) | ||
51 | result |= ADVERTISED_100baseT_Full; | ||
52 | if (advert & ADVERTISE_PAUSE_CAP) | ||
53 | result |= ADVERTISED_Pause; | ||
54 | if (advert & ADVERTISE_PAUSE_ASYM) | ||
55 | result |= ADVERTISED_Asym_Pause; | ||
56 | |||
57 | return result; | ||
58 | } | 43 | } |
59 | 44 | ||
60 | /** | 45 | /** |
@@ -104,19 +89,14 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) | |||
104 | ecmd->autoneg = AUTONEG_ENABLE; | 89 | ecmd->autoneg = AUTONEG_ENABLE; |
105 | 90 | ||
106 | ecmd->advertising |= mii_get_an(mii, MII_ADVERTISE); | 91 | ecmd->advertising |= mii_get_an(mii, MII_ADVERTISE); |
107 | if (ctrl1000 & ADVERTISE_1000HALF) | 92 | if (mii->supports_gmii) |
108 | ecmd->advertising |= ADVERTISED_1000baseT_Half; | 93 | ecmd->advertising |= |
109 | if (ctrl1000 & ADVERTISE_1000FULL) | 94 | mii_ctrl1000_to_ethtool_adv_t(ctrl1000); |
110 | ecmd->advertising |= ADVERTISED_1000baseT_Full; | ||
111 | 95 | ||
112 | if (bmsr & BMSR_ANEGCOMPLETE) { | 96 | if (bmsr & BMSR_ANEGCOMPLETE) { |
113 | ecmd->lp_advertising = mii_get_an(mii, MII_LPA); | 97 | ecmd->lp_advertising = mii_get_an(mii, MII_LPA); |
114 | if (stat1000 & LPA_1000HALF) | 98 | ecmd->lp_advertising |= |
115 | ecmd->lp_advertising |= | 99 | mii_stat1000_to_ethtool_lpa_t(stat1000); |
116 | ADVERTISED_1000baseT_Half; | ||
117 | if (stat1000 & LPA_1000FULL) | ||
118 | ecmd->lp_advertising |= | ||
119 | ADVERTISED_1000baseT_Full; | ||
120 | } else { | 100 | } else { |
121 | ecmd->lp_advertising = 0; | 101 | ecmd->lp_advertising = 0; |
122 | } | 102 | } |
@@ -204,20 +184,11 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) | |||
204 | advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000); | 184 | advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000); |
205 | tmp2 = advert2 & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL); | 185 | tmp2 = advert2 & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL); |
206 | } | 186 | } |
207 | if (ecmd->advertising & ADVERTISED_10baseT_Half) | 187 | tmp |= ethtool_adv_to_mii_adv_t(ecmd->advertising); |
208 | tmp |= ADVERTISE_10HALF; | 188 | |
209 | if (ecmd->advertising & ADVERTISED_10baseT_Full) | 189 | if (mii->supports_gmii) |
210 | tmp |= ADVERTISE_10FULL; | 190 | tmp2 |= |
211 | if (ecmd->advertising & ADVERTISED_100baseT_Half) | 191 | ethtool_adv_to_mii_ctrl1000_t(ecmd->advertising); |
212 | tmp |= ADVERTISE_100HALF; | ||
213 | if (ecmd->advertising & ADVERTISED_100baseT_Full) | ||
214 | tmp |= ADVERTISE_100FULL; | ||
215 | if (mii->supports_gmii) { | ||
216 | if (ecmd->advertising & ADVERTISED_1000baseT_Half) | ||
217 | tmp2 |= ADVERTISE_1000HALF; | ||
218 | if (ecmd->advertising & ADVERTISED_1000baseT_Full) | ||
219 | tmp2 |= ADVERTISE_1000FULL; | ||
220 | } | ||
221 | if (advert != tmp) { | 192 | if (advert != tmp) { |
222 | mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp); | 193 | mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp); |
223 | mii->advertising = tmp; | 194 | mii->advertising = tmp; |
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c index 65391891d8c4..daec9b05d168 100644 --- a/drivers/net/phy/mdio-bitbang.c +++ b/drivers/net/phy/mdio-bitbang.c | |||
@@ -202,6 +202,14 @@ static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val) | |||
202 | return 0; | 202 | return 0; |
203 | } | 203 | } |
204 | 204 | ||
205 | static int mdiobb_reset(struct mii_bus *bus) | ||
206 | { | ||
207 | struct mdiobb_ctrl *ctrl = bus->priv; | ||
208 | if (ctrl->reset) | ||
209 | ctrl->reset(bus); | ||
210 | return 0; | ||
211 | } | ||
212 | |||
205 | struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl) | 213 | struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl) |
206 | { | 214 | { |
207 | struct mii_bus *bus; | 215 | struct mii_bus *bus; |
@@ -214,6 +222,7 @@ struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl) | |||
214 | 222 | ||
215 | bus->read = mdiobb_read; | 223 | bus->read = mdiobb_read; |
216 | bus->write = mdiobb_write; | 224 | bus->write = mdiobb_write; |
225 | bus->reset = mdiobb_reset; | ||
217 | bus->priv = ctrl; | 226 | bus->priv = ctrl; |
218 | 227 | ||
219 | return bus; | 228 | return bus; |
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 2843c90f712f..89c5a3eccc12 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c | |||
@@ -95,6 +95,7 @@ static struct mii_bus * __devinit mdio_gpio_bus_init(struct device *dev, | |||
95 | goto out; | 95 | goto out; |
96 | 96 | ||
97 | bitbang->ctrl.ops = &mdio_gpio_ops; | 97 | bitbang->ctrl.ops = &mdio_gpio_ops; |
98 | bitbang->ctrl.reset = pdata->reset; | ||
98 | bitbang->mdc = pdata->mdc; | 99 | bitbang->mdc = pdata->mdc; |
99 | bitbang->mdio = pdata->mdio; | 100 | bitbang->mdio = pdata->mdio; |
100 | 101 | ||
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 83a5a5afec67..f320f466f03b 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -563,20 +563,9 @@ static int genphy_config_advert(struct phy_device *phydev) | |||
563 | if (adv < 0) | 563 | if (adv < 0) |
564 | return adv; | 564 | return adv; |
565 | 565 | ||
566 | adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | | 566 | adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | |
567 | ADVERTISE_PAUSE_ASYM); | 567 | ADVERTISE_PAUSE_ASYM); |
568 | if (advertise & ADVERTISED_10baseT_Half) | 568 | adv |= ethtool_adv_to_mii_adv_t(advertise); |
569 | adv |= ADVERTISE_10HALF; | ||
570 | if (advertise & ADVERTISED_10baseT_Full) | ||
571 | adv |= ADVERTISE_10FULL; | ||
572 | if (advertise & ADVERTISED_100baseT_Half) | ||
573 | adv |= ADVERTISE_100HALF; | ||
574 | if (advertise & ADVERTISED_100baseT_Full) | ||
575 | adv |= ADVERTISE_100FULL; | ||
576 | if (advertise & ADVERTISED_Pause) | ||
577 | adv |= ADVERTISE_PAUSE_CAP; | ||
578 | if (advertise & ADVERTISED_Asym_Pause) | ||
579 | adv |= ADVERTISE_PAUSE_ASYM; | ||
580 | 569 | ||
581 | if (adv != oldadv) { | 570 | if (adv != oldadv) { |
582 | err = phy_write(phydev, MII_ADVERTISE, adv); | 571 | err = phy_write(phydev, MII_ADVERTISE, adv); |
@@ -595,10 +584,7 @@ static int genphy_config_advert(struct phy_device *phydev) | |||
595 | return adv; | 584 | return adv; |
596 | 585 | ||
597 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | 586 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); |
598 | if (advertise & SUPPORTED_1000baseT_Half) | 587 | adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); |
599 | adv |= ADVERTISE_1000HALF; | ||
600 | if (advertise & SUPPORTED_1000baseT_Full) | ||
601 | adv |= ADVERTISE_1000FULL; | ||
602 | 588 | ||
603 | if (adv != oldadv) { | 589 | if (adv != oldadv) { |
604 | err = phy_write(phydev, MII_CTRL1000, adv); | 590 | err = phy_write(phydev, MII_CTRL1000, adv); |
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index 89f829f5f725..ede899ca0ee6 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c | |||
@@ -162,7 +162,7 @@ static void del_chan(struct pppox_sock *sock) | |||
162 | { | 162 | { |
163 | spin_lock(&chan_lock); | 163 | spin_lock(&chan_lock); |
164 | clear_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap); | 164 | clear_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap); |
165 | rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], NULL); | 165 | RCU_INIT_POINTER(callid_sock[sock->proto.pptp.src_addr.call_id], NULL); |
166 | spin_unlock(&chan_lock); | 166 | spin_unlock(&chan_lock); |
167 | synchronize_rcu(); | 167 | synchronize_rcu(); |
168 | } | 168 | } |
diff --git a/drivers/net/team/Kconfig b/drivers/net/team/Kconfig new file mode 100644 index 000000000000..248a144033ca --- /dev/null +++ b/drivers/net/team/Kconfig | |||
@@ -0,0 +1,43 @@ | |||
1 | menuconfig NET_TEAM | ||
2 | tristate "Ethernet team driver support (EXPERIMENTAL)" | ||
3 | depends on EXPERIMENTAL | ||
4 | ---help--- | ||
5 | This allows one to create virtual interfaces that teams together | ||
6 | multiple ethernet devices. | ||
7 | |||
8 | Team devices can be added using the "ip" command from the | ||
9 | iproute2 package: | ||
10 | |||
11 | "ip link add link [ address MAC ] [ NAME ] type team" | ||
12 | |||
13 | To compile this driver as a module, choose M here: the module | ||
14 | will be called team. | ||
15 | |||
16 | if NET_TEAM | ||
17 | |||
18 | config NET_TEAM_MODE_ROUNDROBIN | ||
19 | tristate "Round-robin mode support" | ||
20 | depends on NET_TEAM | ||
21 | ---help--- | ||
22 | Basic mode where port used for transmitting packets is selected in | ||
23 | round-robin fashion using packet counter. | ||
24 | |||
25 | All added ports are setup to have bond's mac address. | ||
26 | |||
27 | To compile this team mode as a module, choose M here: the module | ||
28 | will be called team_mode_roundrobin. | ||
29 | |||
30 | config NET_TEAM_MODE_ACTIVEBACKUP | ||
31 | tristate "Active-backup mode support" | ||
32 | depends on NET_TEAM | ||
33 | ---help--- | ||
34 | Only one port is active at a time and the rest of ports are used | ||
35 | for backup. | ||
36 | |||
37 | Mac addresses of ports are not modified. Userspace is responsible | ||
38 | to do so. | ||
39 | |||
40 | To compile this team mode as a module, choose M here: the module | ||
41 | will be called team_mode_activebackup. | ||
42 | |||
43 | endif # NET_TEAM | ||
diff --git a/drivers/net/team/Makefile b/drivers/net/team/Makefile new file mode 100644 index 000000000000..85f2028a87af --- /dev/null +++ b/drivers/net/team/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Makefile for the network team driver | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_NET_TEAM) += team.o | ||
6 | obj-$(CONFIG_NET_TEAM_MODE_ROUNDROBIN) += team_mode_roundrobin.o | ||
7 | obj-$(CONFIG_NET_TEAM_MODE_ACTIVEBACKUP) += team_mode_activebackup.o | ||
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c new file mode 100644 index 000000000000..064155d56bce --- /dev/null +++ b/drivers/net/team/team.c | |||
@@ -0,0 +1,1661 @@ | |||
1 | /* | ||
2 | * net/drivers/team/team.c - Network team device driver | ||
3 | * Copyright (c) 2011 Jiri Pirko <jpirko@redhat.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 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/rcupdate.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/ctype.h> | ||
19 | #include <linux/notifier.h> | ||
20 | #include <linux/netdevice.h> | ||
21 | #include <linux/if_arp.h> | ||
22 | #include <linux/socket.h> | ||
23 | #include <linux/etherdevice.h> | ||
24 | #include <linux/rtnetlink.h> | ||
25 | #include <net/rtnetlink.h> | ||
26 | #include <net/genetlink.h> | ||
27 | #include <net/netlink.h> | ||
28 | #include <linux/if_team.h> | ||
29 | |||
30 | #define DRV_NAME "team" | ||
31 | |||
32 | |||
33 | /********** | ||
34 | * Helpers | ||
35 | **********/ | ||
36 | |||
37 | #define team_port_exists(dev) (dev->priv_flags & IFF_TEAM_PORT) | ||
38 | |||
39 | static struct team_port *team_port_get_rcu(const struct net_device *dev) | ||
40 | { | ||
41 | struct team_port *port = rcu_dereference(dev->rx_handler_data); | ||
42 | |||
43 | return team_port_exists(dev) ? port : NULL; | ||
44 | } | ||
45 | |||
46 | static struct team_port *team_port_get_rtnl(const struct net_device *dev) | ||
47 | { | ||
48 | struct team_port *port = rtnl_dereference(dev->rx_handler_data); | ||
49 | |||
50 | return team_port_exists(dev) ? port : NULL; | ||
51 | } | ||
52 | |||
53 | /* | ||
54 | * Since the ability to change mac address for open port device is tested in | ||
55 | * team_port_add, this function can be called without control of return value | ||
56 | */ | ||
57 | static int __set_port_mac(struct net_device *port_dev, | ||
58 | const unsigned char *dev_addr) | ||
59 | { | ||
60 | struct sockaddr addr; | ||
61 | |||
62 | memcpy(addr.sa_data, dev_addr, ETH_ALEN); | ||
63 | addr.sa_family = ARPHRD_ETHER; | ||
64 | return dev_set_mac_address(port_dev, &addr); | ||
65 | } | ||
66 | |||
67 | int team_port_set_orig_mac(struct team_port *port) | ||
68 | { | ||
69 | return __set_port_mac(port->dev, port->orig.dev_addr); | ||
70 | } | ||
71 | |||
72 | int team_port_set_team_mac(struct team_port *port) | ||
73 | { | ||
74 | return __set_port_mac(port->dev, port->team->dev->dev_addr); | ||
75 | } | ||
76 | EXPORT_SYMBOL(team_port_set_team_mac); | ||
77 | |||
78 | |||
79 | /******************* | ||
80 | * Options handling | ||
81 | *******************/ | ||
82 | |||
83 | struct team_option *__team_find_option(struct team *team, const char *opt_name) | ||
84 | { | ||
85 | struct team_option *option; | ||
86 | |||
87 | list_for_each_entry(option, &team->option_list, list) { | ||
88 | if (strcmp(option->name, opt_name) == 0) | ||
89 | return option; | ||
90 | } | ||
91 | return NULL; | ||
92 | } | ||
93 | |||
94 | int team_options_register(struct team *team, | ||
95 | const struct team_option *option, | ||
96 | size_t option_count) | ||
97 | { | ||
98 | int i; | ||
99 | struct team_option **dst_opts; | ||
100 | int err; | ||
101 | |||
102 | dst_opts = kzalloc(sizeof(struct team_option *) * option_count, | ||
103 | GFP_KERNEL); | ||
104 | if (!dst_opts) | ||
105 | return -ENOMEM; | ||
106 | for (i = 0; i < option_count; i++, option++) { | ||
107 | if (__team_find_option(team, option->name)) { | ||
108 | err = -EEXIST; | ||
109 | goto rollback; | ||
110 | } | ||
111 | dst_opts[i] = kmemdup(option, sizeof(*option), GFP_KERNEL); | ||
112 | if (!dst_opts[i]) { | ||
113 | err = -ENOMEM; | ||
114 | goto rollback; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | for (i = 0; i < option_count; i++) | ||
119 | list_add_tail(&dst_opts[i]->list, &team->option_list); | ||
120 | |||
121 | kfree(dst_opts); | ||
122 | return 0; | ||
123 | |||
124 | rollback: | ||
125 | for (i = 0; i < option_count; i++) | ||
126 | kfree(dst_opts[i]); | ||
127 | |||
128 | kfree(dst_opts); | ||
129 | return err; | ||
130 | } | ||
131 | |||
132 | EXPORT_SYMBOL(team_options_register); | ||
133 | |||
134 | static void __team_options_change_check(struct team *team, | ||
135 | struct team_option *changed_option); | ||
136 | |||
137 | static void __team_options_unregister(struct team *team, | ||
138 | const struct team_option *option, | ||
139 | size_t option_count) | ||
140 | { | ||
141 | int i; | ||
142 | |||
143 | for (i = 0; i < option_count; i++, option++) { | ||
144 | struct team_option *del_opt; | ||
145 | |||
146 | del_opt = __team_find_option(team, option->name); | ||
147 | if (del_opt) { | ||
148 | list_del(&del_opt->list); | ||
149 | kfree(del_opt); | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
154 | void team_options_unregister(struct team *team, | ||
155 | const struct team_option *option, | ||
156 | size_t option_count) | ||
157 | { | ||
158 | __team_options_unregister(team, option, option_count); | ||
159 | __team_options_change_check(team, NULL); | ||
160 | } | ||
161 | EXPORT_SYMBOL(team_options_unregister); | ||
162 | |||
163 | static int team_option_get(struct team *team, struct team_option *option, | ||
164 | void *arg) | ||
165 | { | ||
166 | return option->getter(team, arg); | ||
167 | } | ||
168 | |||
169 | static int team_option_set(struct team *team, struct team_option *option, | ||
170 | void *arg) | ||
171 | { | ||
172 | int err; | ||
173 | |||
174 | err = option->setter(team, arg); | ||
175 | if (err) | ||
176 | return err; | ||
177 | |||
178 | __team_options_change_check(team, option); | ||
179 | return err; | ||
180 | } | ||
181 | |||
182 | /**************** | ||
183 | * Mode handling | ||
184 | ****************/ | ||
185 | |||
186 | static LIST_HEAD(mode_list); | ||
187 | static DEFINE_SPINLOCK(mode_list_lock); | ||
188 | |||
189 | static struct team_mode *__find_mode(const char *kind) | ||
190 | { | ||
191 | struct team_mode *mode; | ||
192 | |||
193 | list_for_each_entry(mode, &mode_list, list) { | ||
194 | if (strcmp(mode->kind, kind) == 0) | ||
195 | return mode; | ||
196 | } | ||
197 | return NULL; | ||
198 | } | ||
199 | |||
200 | static bool is_good_mode_name(const char *name) | ||
201 | { | ||
202 | while (*name != '\0') { | ||
203 | if (!isalpha(*name) && !isdigit(*name) && *name != '_') | ||
204 | return false; | ||
205 | name++; | ||
206 | } | ||
207 | return true; | ||
208 | } | ||
209 | |||
210 | int team_mode_register(struct team_mode *mode) | ||
211 | { | ||
212 | int err = 0; | ||
213 | |||
214 | if (!is_good_mode_name(mode->kind) || | ||
215 | mode->priv_size > TEAM_MODE_PRIV_SIZE) | ||
216 | return -EINVAL; | ||
217 | spin_lock(&mode_list_lock); | ||
218 | if (__find_mode(mode->kind)) { | ||
219 | err = -EEXIST; | ||
220 | goto unlock; | ||
221 | } | ||
222 | list_add_tail(&mode->list, &mode_list); | ||
223 | unlock: | ||
224 | spin_unlock(&mode_list_lock); | ||
225 | return err; | ||
226 | } | ||
227 | EXPORT_SYMBOL(team_mode_register); | ||
228 | |||
229 | int team_mode_unregister(struct team_mode *mode) | ||
230 | { | ||
231 | spin_lock(&mode_list_lock); | ||
232 | list_del_init(&mode->list); | ||
233 | spin_unlock(&mode_list_lock); | ||
234 | return 0; | ||
235 | } | ||
236 | EXPORT_SYMBOL(team_mode_unregister); | ||
237 | |||
238 | static struct team_mode *team_mode_get(const char *kind) | ||
239 | { | ||
240 | struct team_mode *mode; | ||
241 | |||
242 | spin_lock(&mode_list_lock); | ||
243 | mode = __find_mode(kind); | ||
244 | if (!mode) { | ||
245 | spin_unlock(&mode_list_lock); | ||
246 | request_module("team-mode-%s", kind); | ||
247 | spin_lock(&mode_list_lock); | ||
248 | mode = __find_mode(kind); | ||
249 | } | ||
250 | if (mode) | ||
251 | if (!try_module_get(mode->owner)) | ||
252 | mode = NULL; | ||
253 | |||
254 | spin_unlock(&mode_list_lock); | ||
255 | return mode; | ||
256 | } | ||
257 | |||
258 | static void team_mode_put(const struct team_mode *mode) | ||
259 | { | ||
260 | module_put(mode->owner); | ||
261 | } | ||
262 | |||
263 | static bool team_dummy_transmit(struct team *team, struct sk_buff *skb) | ||
264 | { | ||
265 | dev_kfree_skb_any(skb); | ||
266 | return false; | ||
267 | } | ||
268 | |||
269 | rx_handler_result_t team_dummy_receive(struct team *team, | ||
270 | struct team_port *port, | ||
271 | struct sk_buff *skb) | ||
272 | { | ||
273 | return RX_HANDLER_ANOTHER; | ||
274 | } | ||
275 | |||
276 | static void team_adjust_ops(struct team *team) | ||
277 | { | ||
278 | /* | ||
279 | * To avoid checks in rx/tx skb paths, ensure here that non-null and | ||
280 | * correct ops are always set. | ||
281 | */ | ||
282 | |||
283 | if (list_empty(&team->port_list) || | ||
284 | !team->mode || !team->mode->ops->transmit) | ||
285 | team->ops.transmit = team_dummy_transmit; | ||
286 | else | ||
287 | team->ops.transmit = team->mode->ops->transmit; | ||
288 | |||
289 | if (list_empty(&team->port_list) || | ||
290 | !team->mode || !team->mode->ops->receive) | ||
291 | team->ops.receive = team_dummy_receive; | ||
292 | else | ||
293 | team->ops.receive = team->mode->ops->receive; | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * We can benefit from the fact that it's ensured no port is present | ||
298 | * at the time of mode change. Therefore no packets are in fly so there's no | ||
299 | * need to set mode operations in any special way. | ||
300 | */ | ||
301 | static int __team_change_mode(struct team *team, | ||
302 | const struct team_mode *new_mode) | ||
303 | { | ||
304 | /* Check if mode was previously set and do cleanup if so */ | ||
305 | if (team->mode) { | ||
306 | void (*exit_op)(struct team *team) = team->ops.exit; | ||
307 | |||
308 | /* Clear ops area so no callback is called any longer */ | ||
309 | memset(&team->ops, 0, sizeof(struct team_mode_ops)); | ||
310 | team_adjust_ops(team); | ||
311 | |||
312 | if (exit_op) | ||
313 | exit_op(team); | ||
314 | team_mode_put(team->mode); | ||
315 | team->mode = NULL; | ||
316 | /* zero private data area */ | ||
317 | memset(&team->mode_priv, 0, | ||
318 | sizeof(struct team) - offsetof(struct team, mode_priv)); | ||
319 | } | ||
320 | |||
321 | if (!new_mode) | ||
322 | return 0; | ||
323 | |||
324 | if (new_mode->ops->init) { | ||
325 | int err; | ||
326 | |||
327 | err = new_mode->ops->init(team); | ||
328 | if (err) | ||
329 | return err; | ||
330 | } | ||
331 | |||
332 | team->mode = new_mode; | ||
333 | memcpy(&team->ops, new_mode->ops, sizeof(struct team_mode_ops)); | ||
334 | team_adjust_ops(team); | ||
335 | |||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static int team_change_mode(struct team *team, const char *kind) | ||
340 | { | ||
341 | struct team_mode *new_mode; | ||
342 | struct net_device *dev = team->dev; | ||
343 | int err; | ||
344 | |||
345 | if (!list_empty(&team->port_list)) { | ||
346 | netdev_err(dev, "No ports can be present during mode change\n"); | ||
347 | return -EBUSY; | ||
348 | } | ||
349 | |||
350 | if (team->mode && strcmp(team->mode->kind, kind) == 0) { | ||
351 | netdev_err(dev, "Unable to change to the same mode the team is in\n"); | ||
352 | return -EINVAL; | ||
353 | } | ||
354 | |||
355 | new_mode = team_mode_get(kind); | ||
356 | if (!new_mode) { | ||
357 | netdev_err(dev, "Mode \"%s\" not found\n", kind); | ||
358 | return -EINVAL; | ||
359 | } | ||
360 | |||
361 | err = __team_change_mode(team, new_mode); | ||
362 | if (err) { | ||
363 | netdev_err(dev, "Failed to change to mode \"%s\"\n", kind); | ||
364 | team_mode_put(new_mode); | ||
365 | return err; | ||
366 | } | ||
367 | |||
368 | netdev_info(dev, "Mode changed to \"%s\"\n", kind); | ||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | |||
373 | /************************ | ||
374 | * Rx path frame handler | ||
375 | ************************/ | ||
376 | |||
377 | /* note: already called with rcu_read_lock */ | ||
378 | static rx_handler_result_t team_handle_frame(struct sk_buff **pskb) | ||
379 | { | ||
380 | struct sk_buff *skb = *pskb; | ||
381 | struct team_port *port; | ||
382 | struct team *team; | ||
383 | rx_handler_result_t res; | ||
384 | |||
385 | skb = skb_share_check(skb, GFP_ATOMIC); | ||
386 | if (!skb) | ||
387 | return RX_HANDLER_CONSUMED; | ||
388 | |||
389 | *pskb = skb; | ||
390 | |||
391 | port = team_port_get_rcu(skb->dev); | ||
392 | team = port->team; | ||
393 | |||
394 | res = team->ops.receive(team, port, skb); | ||
395 | if (res == RX_HANDLER_ANOTHER) { | ||
396 | struct team_pcpu_stats *pcpu_stats; | ||
397 | |||
398 | pcpu_stats = this_cpu_ptr(team->pcpu_stats); | ||
399 | u64_stats_update_begin(&pcpu_stats->syncp); | ||
400 | pcpu_stats->rx_packets++; | ||
401 | pcpu_stats->rx_bytes += skb->len; | ||
402 | if (skb->pkt_type == PACKET_MULTICAST) | ||
403 | pcpu_stats->rx_multicast++; | ||
404 | u64_stats_update_end(&pcpu_stats->syncp); | ||
405 | |||
406 | skb->dev = team->dev; | ||
407 | } else { | ||
408 | this_cpu_inc(team->pcpu_stats->rx_dropped); | ||
409 | } | ||
410 | |||
411 | return res; | ||
412 | } | ||
413 | |||
414 | |||
415 | /**************** | ||
416 | * Port handling | ||
417 | ****************/ | ||
418 | |||
419 | static bool team_port_find(const struct team *team, | ||
420 | const struct team_port *port) | ||
421 | { | ||
422 | struct team_port *cur; | ||
423 | |||
424 | list_for_each_entry(cur, &team->port_list, list) | ||
425 | if (cur == port) | ||
426 | return true; | ||
427 | return false; | ||
428 | } | ||
429 | |||
430 | /* | ||
431 | * Add/delete port to the team port list. Write guarded by rtnl_lock. | ||
432 | * Takes care of correct port->index setup (might be racy). | ||
433 | */ | ||
434 | static void team_port_list_add_port(struct team *team, | ||
435 | struct team_port *port) | ||
436 | { | ||
437 | port->index = team->port_count++; | ||
438 | hlist_add_head_rcu(&port->hlist, | ||
439 | team_port_index_hash(team, port->index)); | ||
440 | list_add_tail_rcu(&port->list, &team->port_list); | ||
441 | } | ||
442 | |||
443 | static void __reconstruct_port_hlist(struct team *team, int rm_index) | ||
444 | { | ||
445 | int i; | ||
446 | struct team_port *port; | ||
447 | |||
448 | for (i = rm_index + 1; i < team->port_count; i++) { | ||
449 | port = team_get_port_by_index(team, i); | ||
450 | hlist_del_rcu(&port->hlist); | ||
451 | port->index--; | ||
452 | hlist_add_head_rcu(&port->hlist, | ||
453 | team_port_index_hash(team, port->index)); | ||
454 | } | ||
455 | } | ||
456 | |||
457 | static void team_port_list_del_port(struct team *team, | ||
458 | struct team_port *port) | ||
459 | { | ||
460 | int rm_index = port->index; | ||
461 | |||
462 | hlist_del_rcu(&port->hlist); | ||
463 | list_del_rcu(&port->list); | ||
464 | __reconstruct_port_hlist(team, rm_index); | ||
465 | team->port_count--; | ||
466 | } | ||
467 | |||
468 | #define TEAM_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \ | ||
469 | NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \ | ||
470 | NETIF_F_HIGHDMA | NETIF_F_LRO) | ||
471 | |||
472 | static void __team_compute_features(struct team *team) | ||
473 | { | ||
474 | struct team_port *port; | ||
475 | u32 vlan_features = TEAM_VLAN_FEATURES; | ||
476 | unsigned short max_hard_header_len = ETH_HLEN; | ||
477 | |||
478 | list_for_each_entry(port, &team->port_list, list) { | ||
479 | vlan_features = netdev_increment_features(vlan_features, | ||
480 | port->dev->vlan_features, | ||
481 | TEAM_VLAN_FEATURES); | ||
482 | |||
483 | if (port->dev->hard_header_len > max_hard_header_len) | ||
484 | max_hard_header_len = port->dev->hard_header_len; | ||
485 | } | ||
486 | |||
487 | team->dev->vlan_features = vlan_features; | ||
488 | team->dev->hard_header_len = max_hard_header_len; | ||
489 | |||
490 | netdev_change_features(team->dev); | ||
491 | } | ||
492 | |||
493 | static void team_compute_features(struct team *team) | ||
494 | { | ||
495 | mutex_lock(&team->lock); | ||
496 | __team_compute_features(team); | ||
497 | mutex_unlock(&team->lock); | ||
498 | } | ||
499 | |||
500 | static int team_port_enter(struct team *team, struct team_port *port) | ||
501 | { | ||
502 | int err = 0; | ||
503 | |||
504 | dev_hold(team->dev); | ||
505 | port->dev->priv_flags |= IFF_TEAM_PORT; | ||
506 | if (team->ops.port_enter) { | ||
507 | err = team->ops.port_enter(team, port); | ||
508 | if (err) { | ||
509 | netdev_err(team->dev, "Device %s failed to enter team mode\n", | ||
510 | port->dev->name); | ||
511 | goto err_port_enter; | ||
512 | } | ||
513 | } | ||
514 | |||
515 | return 0; | ||
516 | |||
517 | err_port_enter: | ||
518 | port->dev->priv_flags &= ~IFF_TEAM_PORT; | ||
519 | dev_put(team->dev); | ||
520 | |||
521 | return err; | ||
522 | } | ||
523 | |||
524 | static void team_port_leave(struct team *team, struct team_port *port) | ||
525 | { | ||
526 | if (team->ops.port_leave) | ||
527 | team->ops.port_leave(team, port); | ||
528 | port->dev->priv_flags &= ~IFF_TEAM_PORT; | ||
529 | dev_put(team->dev); | ||
530 | } | ||
531 | |||
532 | static void __team_port_change_check(struct team_port *port, bool linkup); | ||
533 | |||
534 | static int team_port_add(struct team *team, struct net_device *port_dev) | ||
535 | { | ||
536 | struct net_device *dev = team->dev; | ||
537 | struct team_port *port; | ||
538 | char *portname = port_dev->name; | ||
539 | int err; | ||
540 | |||
541 | if (port_dev->flags & IFF_LOOPBACK || | ||
542 | port_dev->type != ARPHRD_ETHER) { | ||
543 | netdev_err(dev, "Device %s is of an unsupported type\n", | ||
544 | portname); | ||
545 | return -EINVAL; | ||
546 | } | ||
547 | |||
548 | if (team_port_exists(port_dev)) { | ||
549 | netdev_err(dev, "Device %s is already a port " | ||
550 | "of a team device\n", portname); | ||
551 | return -EBUSY; | ||
552 | } | ||
553 | |||
554 | if (port_dev->flags & IFF_UP) { | ||
555 | netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n", | ||
556 | portname); | ||
557 | return -EBUSY; | ||
558 | } | ||
559 | |||
560 | port = kzalloc(sizeof(struct team_port), GFP_KERNEL); | ||
561 | if (!port) | ||
562 | return -ENOMEM; | ||
563 | |||
564 | port->dev = port_dev; | ||
565 | port->team = team; | ||
566 | |||
567 | port->orig.mtu = port_dev->mtu; | ||
568 | err = dev_set_mtu(port_dev, dev->mtu); | ||
569 | if (err) { | ||
570 | netdev_dbg(dev, "Error %d calling dev_set_mtu\n", err); | ||
571 | goto err_set_mtu; | ||
572 | } | ||
573 | |||
574 | memcpy(port->orig.dev_addr, port_dev->dev_addr, ETH_ALEN); | ||
575 | |||
576 | err = team_port_enter(team, port); | ||
577 | if (err) { | ||
578 | netdev_err(dev, "Device %s failed to enter team mode\n", | ||
579 | portname); | ||
580 | goto err_port_enter; | ||
581 | } | ||
582 | |||
583 | err = dev_open(port_dev); | ||
584 | if (err) { | ||
585 | netdev_dbg(dev, "Device %s opening failed\n", | ||
586 | portname); | ||
587 | goto err_dev_open; | ||
588 | } | ||
589 | |||
590 | err = netdev_set_master(port_dev, dev); | ||
591 | if (err) { | ||
592 | netdev_err(dev, "Device %s failed to set master\n", portname); | ||
593 | goto err_set_master; | ||
594 | } | ||
595 | |||
596 | err = netdev_rx_handler_register(port_dev, team_handle_frame, | ||
597 | port); | ||
598 | if (err) { | ||
599 | netdev_err(dev, "Device %s failed to register rx_handler\n", | ||
600 | portname); | ||
601 | goto err_handler_register; | ||
602 | } | ||
603 | |||
604 | team_port_list_add_port(team, port); | ||
605 | team_adjust_ops(team); | ||
606 | __team_compute_features(team); | ||
607 | __team_port_change_check(port, !!netif_carrier_ok(port_dev)); | ||
608 | |||
609 | netdev_info(dev, "Port device %s added\n", portname); | ||
610 | |||
611 | return 0; | ||
612 | |||
613 | err_handler_register: | ||
614 | netdev_set_master(port_dev, NULL); | ||
615 | |||
616 | err_set_master: | ||
617 | dev_close(port_dev); | ||
618 | |||
619 | err_dev_open: | ||
620 | team_port_leave(team, port); | ||
621 | team_port_set_orig_mac(port); | ||
622 | |||
623 | err_port_enter: | ||
624 | dev_set_mtu(port_dev, port->orig.mtu); | ||
625 | |||
626 | err_set_mtu: | ||
627 | kfree(port); | ||
628 | |||
629 | return err; | ||
630 | } | ||
631 | |||
632 | static int team_port_del(struct team *team, struct net_device *port_dev) | ||
633 | { | ||
634 | struct net_device *dev = team->dev; | ||
635 | struct team_port *port; | ||
636 | char *portname = port_dev->name; | ||
637 | |||
638 | port = team_port_get_rtnl(port_dev); | ||
639 | if (!port || !team_port_find(team, port)) { | ||
640 | netdev_err(dev, "Device %s does not act as a port of this team\n", | ||
641 | portname); | ||
642 | return -ENOENT; | ||
643 | } | ||
644 | |||
645 | __team_port_change_check(port, false); | ||
646 | team_port_list_del_port(team, port); | ||
647 | team_adjust_ops(team); | ||
648 | netdev_rx_handler_unregister(port_dev); | ||
649 | netdev_set_master(port_dev, NULL); | ||
650 | dev_close(port_dev); | ||
651 | team_port_leave(team, port); | ||
652 | team_port_set_orig_mac(port); | ||
653 | dev_set_mtu(port_dev, port->orig.mtu); | ||
654 | synchronize_rcu(); | ||
655 | kfree(port); | ||
656 | netdev_info(dev, "Port device %s removed\n", portname); | ||
657 | __team_compute_features(team); | ||
658 | |||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | |||
663 | /***************** | ||
664 | * Net device ops | ||
665 | *****************/ | ||
666 | |||
667 | static const char team_no_mode_kind[] = "*NOMODE*"; | ||
668 | |||
669 | static int team_mode_option_get(struct team *team, void *arg) | ||
670 | { | ||
671 | const char **str = arg; | ||
672 | |||
673 | *str = team->mode ? team->mode->kind : team_no_mode_kind; | ||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | static int team_mode_option_set(struct team *team, void *arg) | ||
678 | { | ||
679 | const char **str = arg; | ||
680 | |||
681 | return team_change_mode(team, *str); | ||
682 | } | ||
683 | |||
684 | static const struct team_option team_options[] = { | ||
685 | { | ||
686 | .name = "mode", | ||
687 | .type = TEAM_OPTION_TYPE_STRING, | ||
688 | .getter = team_mode_option_get, | ||
689 | .setter = team_mode_option_set, | ||
690 | }, | ||
691 | }; | ||
692 | |||
693 | static int team_init(struct net_device *dev) | ||
694 | { | ||
695 | struct team *team = netdev_priv(dev); | ||
696 | int i; | ||
697 | int err; | ||
698 | |||
699 | team->dev = dev; | ||
700 | mutex_init(&team->lock); | ||
701 | |||
702 | team->pcpu_stats = alloc_percpu(struct team_pcpu_stats); | ||
703 | if (!team->pcpu_stats) | ||
704 | return -ENOMEM; | ||
705 | |||
706 | for (i = 0; i < TEAM_PORT_HASHENTRIES; i++) | ||
707 | INIT_HLIST_HEAD(&team->port_hlist[i]); | ||
708 | INIT_LIST_HEAD(&team->port_list); | ||
709 | |||
710 | team_adjust_ops(team); | ||
711 | |||
712 | INIT_LIST_HEAD(&team->option_list); | ||
713 | err = team_options_register(team, team_options, ARRAY_SIZE(team_options)); | ||
714 | if (err) | ||
715 | goto err_options_register; | ||
716 | netif_carrier_off(dev); | ||
717 | |||
718 | return 0; | ||
719 | |||
720 | err_options_register: | ||
721 | free_percpu(team->pcpu_stats); | ||
722 | |||
723 | return err; | ||
724 | } | ||
725 | |||
726 | static void team_uninit(struct net_device *dev) | ||
727 | { | ||
728 | struct team *team = netdev_priv(dev); | ||
729 | struct team_port *port; | ||
730 | struct team_port *tmp; | ||
731 | |||
732 | mutex_lock(&team->lock); | ||
733 | list_for_each_entry_safe(port, tmp, &team->port_list, list) | ||
734 | team_port_del(team, port->dev); | ||
735 | |||
736 | __team_change_mode(team, NULL); /* cleanup */ | ||
737 | __team_options_unregister(team, team_options, ARRAY_SIZE(team_options)); | ||
738 | mutex_unlock(&team->lock); | ||
739 | } | ||
740 | |||
741 | static void team_destructor(struct net_device *dev) | ||
742 | { | ||
743 | struct team *team = netdev_priv(dev); | ||
744 | |||
745 | free_percpu(team->pcpu_stats); | ||
746 | free_netdev(dev); | ||
747 | } | ||
748 | |||
749 | static int team_open(struct net_device *dev) | ||
750 | { | ||
751 | netif_carrier_on(dev); | ||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | static int team_close(struct net_device *dev) | ||
756 | { | ||
757 | netif_carrier_off(dev); | ||
758 | return 0; | ||
759 | } | ||
760 | |||
761 | /* | ||
762 | * note: already called with rcu_read_lock | ||
763 | */ | ||
764 | static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev) | ||
765 | { | ||
766 | struct team *team = netdev_priv(dev); | ||
767 | bool tx_success = false; | ||
768 | unsigned int len = skb->len; | ||
769 | |||
770 | tx_success = team->ops.transmit(team, skb); | ||
771 | if (tx_success) { | ||
772 | struct team_pcpu_stats *pcpu_stats; | ||
773 | |||
774 | pcpu_stats = this_cpu_ptr(team->pcpu_stats); | ||
775 | u64_stats_update_begin(&pcpu_stats->syncp); | ||
776 | pcpu_stats->tx_packets++; | ||
777 | pcpu_stats->tx_bytes += len; | ||
778 | u64_stats_update_end(&pcpu_stats->syncp); | ||
779 | } else { | ||
780 | this_cpu_inc(team->pcpu_stats->tx_dropped); | ||
781 | } | ||
782 | |||
783 | return NETDEV_TX_OK; | ||
784 | } | ||
785 | |||
786 | static void team_change_rx_flags(struct net_device *dev, int change) | ||
787 | { | ||
788 | struct team *team = netdev_priv(dev); | ||
789 | struct team_port *port; | ||
790 | int inc; | ||
791 | |||
792 | rcu_read_lock(); | ||
793 | list_for_each_entry_rcu(port, &team->port_list, list) { | ||
794 | if (change & IFF_PROMISC) { | ||
795 | inc = dev->flags & IFF_PROMISC ? 1 : -1; | ||
796 | dev_set_promiscuity(port->dev, inc); | ||
797 | } | ||
798 | if (change & IFF_ALLMULTI) { | ||
799 | inc = dev->flags & IFF_ALLMULTI ? 1 : -1; | ||
800 | dev_set_allmulti(port->dev, inc); | ||
801 | } | ||
802 | } | ||
803 | rcu_read_unlock(); | ||
804 | } | ||
805 | |||
806 | static void team_set_rx_mode(struct net_device *dev) | ||
807 | { | ||
808 | struct team *team = netdev_priv(dev); | ||
809 | struct team_port *port; | ||
810 | |||
811 | rcu_read_lock(); | ||
812 | list_for_each_entry_rcu(port, &team->port_list, list) { | ||
813 | dev_uc_sync(port->dev, dev); | ||
814 | dev_mc_sync(port->dev, dev); | ||
815 | } | ||
816 | rcu_read_unlock(); | ||
817 | } | ||
818 | |||
819 | static int team_set_mac_address(struct net_device *dev, void *p) | ||
820 | { | ||
821 | struct team *team = netdev_priv(dev); | ||
822 | struct team_port *port; | ||
823 | struct sockaddr *addr = p; | ||
824 | |||
825 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | ||
826 | rcu_read_lock(); | ||
827 | list_for_each_entry_rcu(port, &team->port_list, list) | ||
828 | if (team->ops.port_change_mac) | ||
829 | team->ops.port_change_mac(team, port); | ||
830 | rcu_read_unlock(); | ||
831 | return 0; | ||
832 | } | ||
833 | |||
834 | static int team_change_mtu(struct net_device *dev, int new_mtu) | ||
835 | { | ||
836 | struct team *team = netdev_priv(dev); | ||
837 | struct team_port *port; | ||
838 | int err; | ||
839 | |||
840 | /* | ||
841 | * Alhough this is reader, it's guarded by team lock. It's not possible | ||
842 | * to traverse list in reverse under rcu_read_lock | ||
843 | */ | ||
844 | mutex_lock(&team->lock); | ||
845 | list_for_each_entry(port, &team->port_list, list) { | ||
846 | err = dev_set_mtu(port->dev, new_mtu); | ||
847 | if (err) { | ||
848 | netdev_err(dev, "Device %s failed to change mtu", | ||
849 | port->dev->name); | ||
850 | goto unwind; | ||
851 | } | ||
852 | } | ||
853 | mutex_unlock(&team->lock); | ||
854 | |||
855 | dev->mtu = new_mtu; | ||
856 | |||
857 | return 0; | ||
858 | |||
859 | unwind: | ||
860 | list_for_each_entry_continue_reverse(port, &team->port_list, list) | ||
861 | dev_set_mtu(port->dev, dev->mtu); | ||
862 | mutex_unlock(&team->lock); | ||
863 | |||
864 | return err; | ||
865 | } | ||
866 | |||
867 | static struct rtnl_link_stats64 * | ||
868 | team_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) | ||
869 | { | ||
870 | struct team *team = netdev_priv(dev); | ||
871 | struct team_pcpu_stats *p; | ||
872 | u64 rx_packets, rx_bytes, rx_multicast, tx_packets, tx_bytes; | ||
873 | u32 rx_dropped = 0, tx_dropped = 0; | ||
874 | unsigned int start; | ||
875 | int i; | ||
876 | |||
877 | for_each_possible_cpu(i) { | ||
878 | p = per_cpu_ptr(team->pcpu_stats, i); | ||
879 | do { | ||
880 | start = u64_stats_fetch_begin_bh(&p->syncp); | ||
881 | rx_packets = p->rx_packets; | ||
882 | rx_bytes = p->rx_bytes; | ||
883 | rx_multicast = p->rx_multicast; | ||
884 | tx_packets = p->tx_packets; | ||
885 | tx_bytes = p->tx_bytes; | ||
886 | } while (u64_stats_fetch_retry_bh(&p->syncp, start)); | ||
887 | |||
888 | stats->rx_packets += rx_packets; | ||
889 | stats->rx_bytes += rx_bytes; | ||
890 | stats->multicast += rx_multicast; | ||
891 | stats->tx_packets += tx_packets; | ||
892 | stats->tx_bytes += tx_bytes; | ||
893 | /* | ||
894 | * rx_dropped & tx_dropped are u32, updated | ||
895 | * without syncp protection. | ||
896 | */ | ||
897 | rx_dropped += p->rx_dropped; | ||
898 | tx_dropped += p->tx_dropped; | ||
899 | } | ||
900 | stats->rx_dropped = rx_dropped; | ||
901 | stats->tx_dropped = tx_dropped; | ||
902 | return stats; | ||
903 | } | ||
904 | |||
905 | static void team_vlan_rx_add_vid(struct net_device *dev, uint16_t vid) | ||
906 | { | ||
907 | struct team *team = netdev_priv(dev); | ||
908 | struct team_port *port; | ||
909 | |||
910 | rcu_read_lock(); | ||
911 | list_for_each_entry_rcu(port, &team->port_list, list) { | ||
912 | const struct net_device_ops *ops = port->dev->netdev_ops; | ||
913 | |||
914 | if (ops->ndo_vlan_rx_add_vid) | ||
915 | ops->ndo_vlan_rx_add_vid(port->dev, vid); | ||
916 | } | ||
917 | rcu_read_unlock(); | ||
918 | } | ||
919 | |||
920 | static void team_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) | ||
921 | { | ||
922 | struct team *team = netdev_priv(dev); | ||
923 | struct team_port *port; | ||
924 | |||
925 | rcu_read_lock(); | ||
926 | list_for_each_entry_rcu(port, &team->port_list, list) { | ||
927 | const struct net_device_ops *ops = port->dev->netdev_ops; | ||
928 | |||
929 | if (ops->ndo_vlan_rx_kill_vid) | ||
930 | ops->ndo_vlan_rx_kill_vid(port->dev, vid); | ||
931 | } | ||
932 | rcu_read_unlock(); | ||
933 | } | ||
934 | |||
935 | static int team_add_slave(struct net_device *dev, struct net_device *port_dev) | ||
936 | { | ||
937 | struct team *team = netdev_priv(dev); | ||
938 | int err; | ||
939 | |||
940 | mutex_lock(&team->lock); | ||
941 | err = team_port_add(team, port_dev); | ||
942 | mutex_unlock(&team->lock); | ||
943 | return err; | ||
944 | } | ||
945 | |||
946 | static int team_del_slave(struct net_device *dev, struct net_device *port_dev) | ||
947 | { | ||
948 | struct team *team = netdev_priv(dev); | ||
949 | int err; | ||
950 | |||
951 | mutex_lock(&team->lock); | ||
952 | err = team_port_del(team, port_dev); | ||
953 | mutex_unlock(&team->lock); | ||
954 | return err; | ||
955 | } | ||
956 | |||
957 | static netdev_features_t team_fix_features(struct net_device *dev, | ||
958 | netdev_features_t features) | ||
959 | { | ||
960 | struct team_port *port; | ||
961 | struct team *team = netdev_priv(dev); | ||
962 | netdev_features_t mask; | ||
963 | |||
964 | mask = features; | ||
965 | features &= ~NETIF_F_ONE_FOR_ALL; | ||
966 | features |= NETIF_F_ALL_FOR_ALL; | ||
967 | |||
968 | rcu_read_lock(); | ||
969 | list_for_each_entry_rcu(port, &team->port_list, list) { | ||
970 | features = netdev_increment_features(features, | ||
971 | port->dev->features, | ||
972 | mask); | ||
973 | } | ||
974 | rcu_read_unlock(); | ||
975 | return features; | ||
976 | } | ||
977 | |||
978 | static const struct net_device_ops team_netdev_ops = { | ||
979 | .ndo_init = team_init, | ||
980 | .ndo_uninit = team_uninit, | ||
981 | .ndo_open = team_open, | ||
982 | .ndo_stop = team_close, | ||
983 | .ndo_start_xmit = team_xmit, | ||
984 | .ndo_change_rx_flags = team_change_rx_flags, | ||
985 | .ndo_set_rx_mode = team_set_rx_mode, | ||
986 | .ndo_set_mac_address = team_set_mac_address, | ||
987 | .ndo_change_mtu = team_change_mtu, | ||
988 | .ndo_get_stats64 = team_get_stats64, | ||
989 | .ndo_vlan_rx_add_vid = team_vlan_rx_add_vid, | ||
990 | .ndo_vlan_rx_kill_vid = team_vlan_rx_kill_vid, | ||
991 | .ndo_add_slave = team_add_slave, | ||
992 | .ndo_del_slave = team_del_slave, | ||
993 | .ndo_fix_features = team_fix_features, | ||
994 | }; | ||
995 | |||
996 | |||
997 | /*********************** | ||
998 | * rt netlink interface | ||
999 | ***********************/ | ||
1000 | |||
1001 | static void team_setup(struct net_device *dev) | ||
1002 | { | ||
1003 | ether_setup(dev); | ||
1004 | |||
1005 | dev->netdev_ops = &team_netdev_ops; | ||
1006 | dev->destructor = team_destructor; | ||
1007 | dev->tx_queue_len = 0; | ||
1008 | dev->flags |= IFF_MULTICAST; | ||
1009 | dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); | ||
1010 | |||
1011 | /* | ||
1012 | * Indicate we support unicast address filtering. That way core won't | ||
1013 | * bring us to promisc mode in case a unicast addr is added. | ||
1014 | * Let this up to underlay drivers. | ||
1015 | */ | ||
1016 | dev->priv_flags |= IFF_UNICAST_FLT; | ||
1017 | |||
1018 | dev->features |= NETIF_F_LLTX; | ||
1019 | dev->features |= NETIF_F_GRO; | ||
1020 | dev->hw_features = NETIF_F_HW_VLAN_TX | | ||
1021 | NETIF_F_HW_VLAN_RX | | ||
1022 | NETIF_F_HW_VLAN_FILTER; | ||
1023 | |||
1024 | dev->features |= dev->hw_features; | ||
1025 | } | ||
1026 | |||
1027 | static int team_newlink(struct net *src_net, struct net_device *dev, | ||
1028 | struct nlattr *tb[], struct nlattr *data[]) | ||
1029 | { | ||
1030 | int err; | ||
1031 | |||
1032 | if (tb[IFLA_ADDRESS] == NULL) | ||
1033 | random_ether_addr(dev->dev_addr); | ||
1034 | |||
1035 | err = register_netdevice(dev); | ||
1036 | if (err) | ||
1037 | return err; | ||
1038 | |||
1039 | return 0; | ||
1040 | } | ||
1041 | |||
1042 | static int team_validate(struct nlattr *tb[], struct nlattr *data[]) | ||
1043 | { | ||
1044 | if (tb[IFLA_ADDRESS]) { | ||
1045 | if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) | ||
1046 | return -EINVAL; | ||
1047 | if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) | ||
1048 | return -EADDRNOTAVAIL; | ||
1049 | } | ||
1050 | return 0; | ||
1051 | } | ||
1052 | |||
1053 | static struct rtnl_link_ops team_link_ops __read_mostly = { | ||
1054 | .kind = DRV_NAME, | ||
1055 | .priv_size = sizeof(struct team), | ||
1056 | .setup = team_setup, | ||
1057 | .newlink = team_newlink, | ||
1058 | .validate = team_validate, | ||
1059 | }; | ||
1060 | |||
1061 | |||
1062 | /*********************************** | ||
1063 | * Generic netlink custom interface | ||
1064 | ***********************************/ | ||
1065 | |||
1066 | static struct genl_family team_nl_family = { | ||
1067 | .id = GENL_ID_GENERATE, | ||
1068 | .name = TEAM_GENL_NAME, | ||
1069 | .version = TEAM_GENL_VERSION, | ||
1070 | .maxattr = TEAM_ATTR_MAX, | ||
1071 | .netnsok = true, | ||
1072 | }; | ||
1073 | |||
1074 | static const struct nla_policy team_nl_policy[TEAM_ATTR_MAX + 1] = { | ||
1075 | [TEAM_ATTR_UNSPEC] = { .type = NLA_UNSPEC, }, | ||
1076 | [TEAM_ATTR_TEAM_IFINDEX] = { .type = NLA_U32 }, | ||
1077 | [TEAM_ATTR_LIST_OPTION] = { .type = NLA_NESTED }, | ||
1078 | [TEAM_ATTR_LIST_PORT] = { .type = NLA_NESTED }, | ||
1079 | }; | ||
1080 | |||
1081 | static const struct nla_policy | ||
1082 | team_nl_option_policy[TEAM_ATTR_OPTION_MAX + 1] = { | ||
1083 | [TEAM_ATTR_OPTION_UNSPEC] = { .type = NLA_UNSPEC, }, | ||
1084 | [TEAM_ATTR_OPTION_NAME] = { | ||
1085 | .type = NLA_STRING, | ||
1086 | .len = TEAM_STRING_MAX_LEN, | ||
1087 | }, | ||
1088 | [TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG }, | ||
1089 | [TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8 }, | ||
1090 | [TEAM_ATTR_OPTION_DATA] = { | ||
1091 | .type = NLA_BINARY, | ||
1092 | .len = TEAM_STRING_MAX_LEN, | ||
1093 | }, | ||
1094 | }; | ||
1095 | |||
1096 | static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) | ||
1097 | { | ||
1098 | struct sk_buff *msg; | ||
1099 | void *hdr; | ||
1100 | int err; | ||
1101 | |||
1102 | msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | ||
1103 | if (!msg) | ||
1104 | return -ENOMEM; | ||
1105 | |||
1106 | hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq, | ||
1107 | &team_nl_family, 0, TEAM_CMD_NOOP); | ||
1108 | if (IS_ERR(hdr)) { | ||
1109 | err = PTR_ERR(hdr); | ||
1110 | goto err_msg_put; | ||
1111 | } | ||
1112 | |||
1113 | genlmsg_end(msg, hdr); | ||
1114 | |||
1115 | return genlmsg_unicast(genl_info_net(info), msg, info->snd_pid); | ||
1116 | |||
1117 | err_msg_put: | ||
1118 | nlmsg_free(msg); | ||
1119 | |||
1120 | return err; | ||
1121 | } | ||
1122 | |||
1123 | /* | ||
1124 | * Netlink cmd functions should be locked by following two functions. | ||
1125 | * Since dev gets held here, that ensures dev won't disappear in between. | ||
1126 | */ | ||
1127 | static struct team *team_nl_team_get(struct genl_info *info) | ||
1128 | { | ||
1129 | struct net *net = genl_info_net(info); | ||
1130 | int ifindex; | ||
1131 | struct net_device *dev; | ||
1132 | struct team *team; | ||
1133 | |||
1134 | if (!info->attrs[TEAM_ATTR_TEAM_IFINDEX]) | ||
1135 | return NULL; | ||
1136 | |||
1137 | ifindex = nla_get_u32(info->attrs[TEAM_ATTR_TEAM_IFINDEX]); | ||
1138 | dev = dev_get_by_index(net, ifindex); | ||
1139 | if (!dev || dev->netdev_ops != &team_netdev_ops) { | ||
1140 | if (dev) | ||
1141 | dev_put(dev); | ||
1142 | return NULL; | ||
1143 | } | ||
1144 | |||
1145 | team = netdev_priv(dev); | ||
1146 | mutex_lock(&team->lock); | ||
1147 | return team; | ||
1148 | } | ||
1149 | |||
1150 | static void team_nl_team_put(struct team *team) | ||
1151 | { | ||
1152 | mutex_unlock(&team->lock); | ||
1153 | dev_put(team->dev); | ||
1154 | } | ||
1155 | |||
1156 | static int team_nl_send_generic(struct genl_info *info, struct team *team, | ||
1157 | int (*fill_func)(struct sk_buff *skb, | ||
1158 | struct genl_info *info, | ||
1159 | int flags, struct team *team)) | ||
1160 | { | ||
1161 | struct sk_buff *skb; | ||
1162 | int err; | ||
1163 | |||
1164 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | ||
1165 | if (!skb) | ||
1166 | return -ENOMEM; | ||
1167 | |||
1168 | err = fill_func(skb, info, NLM_F_ACK, team); | ||
1169 | if (err < 0) | ||
1170 | goto err_fill; | ||
1171 | |||
1172 | err = genlmsg_unicast(genl_info_net(info), skb, info->snd_pid); | ||
1173 | return err; | ||
1174 | |||
1175 | err_fill: | ||
1176 | nlmsg_free(skb); | ||
1177 | return err; | ||
1178 | } | ||
1179 | |||
1180 | static int team_nl_fill_options_get_changed(struct sk_buff *skb, | ||
1181 | u32 pid, u32 seq, int flags, | ||
1182 | struct team *team, | ||
1183 | struct team_option *changed_option) | ||
1184 | { | ||
1185 | struct nlattr *option_list; | ||
1186 | void *hdr; | ||
1187 | struct team_option *option; | ||
1188 | |||
1189 | hdr = genlmsg_put(skb, pid, seq, &team_nl_family, flags, | ||
1190 | TEAM_CMD_OPTIONS_GET); | ||
1191 | if (IS_ERR(hdr)) | ||
1192 | return PTR_ERR(hdr); | ||
1193 | |||
1194 | NLA_PUT_U32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex); | ||
1195 | option_list = nla_nest_start(skb, TEAM_ATTR_LIST_OPTION); | ||
1196 | if (!option_list) | ||
1197 | return -EMSGSIZE; | ||
1198 | |||
1199 | list_for_each_entry(option, &team->option_list, list) { | ||
1200 | struct nlattr *option_item; | ||
1201 | long arg; | ||
1202 | |||
1203 | option_item = nla_nest_start(skb, TEAM_ATTR_ITEM_OPTION); | ||
1204 | if (!option_item) | ||
1205 | goto nla_put_failure; | ||
1206 | NLA_PUT_STRING(skb, TEAM_ATTR_OPTION_NAME, option->name); | ||
1207 | if (option == changed_option) | ||
1208 | NLA_PUT_FLAG(skb, TEAM_ATTR_OPTION_CHANGED); | ||
1209 | switch (option->type) { | ||
1210 | case TEAM_OPTION_TYPE_U32: | ||
1211 | NLA_PUT_U8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32); | ||
1212 | team_option_get(team, option, &arg); | ||
1213 | NLA_PUT_U32(skb, TEAM_ATTR_OPTION_DATA, arg); | ||
1214 | break; | ||
1215 | case TEAM_OPTION_TYPE_STRING: | ||
1216 | NLA_PUT_U8(skb, TEAM_ATTR_OPTION_TYPE, NLA_STRING); | ||
1217 | team_option_get(team, option, &arg); | ||
1218 | NLA_PUT_STRING(skb, TEAM_ATTR_OPTION_DATA, | ||
1219 | (char *) arg); | ||
1220 | break; | ||
1221 | default: | ||
1222 | BUG(); | ||
1223 | } | ||
1224 | nla_nest_end(skb, option_item); | ||
1225 | } | ||
1226 | |||
1227 | nla_nest_end(skb, option_list); | ||
1228 | return genlmsg_end(skb, hdr); | ||
1229 | |||
1230 | nla_put_failure: | ||
1231 | genlmsg_cancel(skb, hdr); | ||
1232 | return -EMSGSIZE; | ||
1233 | } | ||
1234 | |||
1235 | static int team_nl_fill_options_get(struct sk_buff *skb, | ||
1236 | struct genl_info *info, int flags, | ||
1237 | struct team *team) | ||
1238 | { | ||
1239 | return team_nl_fill_options_get_changed(skb, info->snd_pid, | ||
1240 | info->snd_seq, NLM_F_ACK, | ||
1241 | team, NULL); | ||
1242 | } | ||
1243 | |||
1244 | static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info) | ||
1245 | { | ||
1246 | struct team *team; | ||
1247 | int err; | ||
1248 | |||
1249 | team = team_nl_team_get(info); | ||
1250 | if (!team) | ||
1251 | return -EINVAL; | ||
1252 | |||
1253 | err = team_nl_send_generic(info, team, team_nl_fill_options_get); | ||
1254 | |||
1255 | team_nl_team_put(team); | ||
1256 | |||
1257 | return err; | ||
1258 | } | ||
1259 | |||
1260 | static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) | ||
1261 | { | ||
1262 | struct team *team; | ||
1263 | int err = 0; | ||
1264 | int i; | ||
1265 | struct nlattr *nl_option; | ||
1266 | |||
1267 | team = team_nl_team_get(info); | ||
1268 | if (!team) | ||
1269 | return -EINVAL; | ||
1270 | |||
1271 | err = -EINVAL; | ||
1272 | if (!info->attrs[TEAM_ATTR_LIST_OPTION]) { | ||
1273 | err = -EINVAL; | ||
1274 | goto team_put; | ||
1275 | } | ||
1276 | |||
1277 | nla_for_each_nested(nl_option, info->attrs[TEAM_ATTR_LIST_OPTION], i) { | ||
1278 | struct nlattr *mode_attrs[TEAM_ATTR_OPTION_MAX + 1]; | ||
1279 | enum team_option_type opt_type; | ||
1280 | struct team_option *option; | ||
1281 | char *opt_name; | ||
1282 | bool opt_found = false; | ||
1283 | |||
1284 | if (nla_type(nl_option) != TEAM_ATTR_ITEM_OPTION) { | ||
1285 | err = -EINVAL; | ||
1286 | goto team_put; | ||
1287 | } | ||
1288 | err = nla_parse_nested(mode_attrs, TEAM_ATTR_OPTION_MAX, | ||
1289 | nl_option, team_nl_option_policy); | ||
1290 | if (err) | ||
1291 | goto team_put; | ||
1292 | if (!mode_attrs[TEAM_ATTR_OPTION_NAME] || | ||
1293 | !mode_attrs[TEAM_ATTR_OPTION_TYPE] || | ||
1294 | !mode_attrs[TEAM_ATTR_OPTION_DATA]) { | ||
1295 | err = -EINVAL; | ||
1296 | goto team_put; | ||
1297 | } | ||
1298 | switch (nla_get_u8(mode_attrs[TEAM_ATTR_OPTION_TYPE])) { | ||
1299 | case NLA_U32: | ||
1300 | opt_type = TEAM_OPTION_TYPE_U32; | ||
1301 | break; | ||
1302 | case NLA_STRING: | ||
1303 | opt_type = TEAM_OPTION_TYPE_STRING; | ||
1304 | break; | ||
1305 | default: | ||
1306 | goto team_put; | ||
1307 | } | ||
1308 | |||
1309 | opt_name = nla_data(mode_attrs[TEAM_ATTR_OPTION_NAME]); | ||
1310 | list_for_each_entry(option, &team->option_list, list) { | ||
1311 | long arg; | ||
1312 | struct nlattr *opt_data_attr; | ||
1313 | |||
1314 | if (option->type != opt_type || | ||
1315 | strcmp(option->name, opt_name)) | ||
1316 | continue; | ||
1317 | opt_found = true; | ||
1318 | opt_data_attr = mode_attrs[TEAM_ATTR_OPTION_DATA]; | ||
1319 | switch (opt_type) { | ||
1320 | case TEAM_OPTION_TYPE_U32: | ||
1321 | arg = nla_get_u32(opt_data_attr); | ||
1322 | break; | ||
1323 | case TEAM_OPTION_TYPE_STRING: | ||
1324 | arg = (long) nla_data(opt_data_attr); | ||
1325 | break; | ||
1326 | default: | ||
1327 | BUG(); | ||
1328 | } | ||
1329 | err = team_option_set(team, option, &arg); | ||
1330 | if (err) | ||
1331 | goto team_put; | ||
1332 | } | ||
1333 | if (!opt_found) { | ||
1334 | err = -ENOENT; | ||
1335 | goto team_put; | ||
1336 | } | ||
1337 | } | ||
1338 | |||
1339 | team_put: | ||
1340 | team_nl_team_put(team); | ||
1341 | |||
1342 | return err; | ||
1343 | } | ||
1344 | |||
1345 | static int team_nl_fill_port_list_get_changed(struct sk_buff *skb, | ||
1346 | u32 pid, u32 seq, int flags, | ||
1347 | struct team *team, | ||
1348 | struct team_port *changed_port) | ||
1349 | { | ||
1350 | struct nlattr *port_list; | ||
1351 | void *hdr; | ||
1352 | struct team_port *port; | ||
1353 | |||
1354 | hdr = genlmsg_put(skb, pid, seq, &team_nl_family, flags, | ||
1355 | TEAM_CMD_PORT_LIST_GET); | ||
1356 | if (IS_ERR(hdr)) | ||
1357 | return PTR_ERR(hdr); | ||
1358 | |||
1359 | NLA_PUT_U32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex); | ||
1360 | port_list = nla_nest_start(skb, TEAM_ATTR_LIST_PORT); | ||
1361 | if (!port_list) | ||
1362 | return -EMSGSIZE; | ||
1363 | |||
1364 | list_for_each_entry(port, &team->port_list, list) { | ||
1365 | struct nlattr *port_item; | ||
1366 | |||
1367 | port_item = nla_nest_start(skb, TEAM_ATTR_ITEM_PORT); | ||
1368 | if (!port_item) | ||
1369 | goto nla_put_failure; | ||
1370 | NLA_PUT_U32(skb, TEAM_ATTR_PORT_IFINDEX, port->dev->ifindex); | ||
1371 | if (port == changed_port) | ||
1372 | NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_CHANGED); | ||
1373 | if (port->linkup) | ||
1374 | NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_LINKUP); | ||
1375 | NLA_PUT_U32(skb, TEAM_ATTR_PORT_SPEED, port->speed); | ||
1376 | NLA_PUT_U8(skb, TEAM_ATTR_PORT_DUPLEX, port->duplex); | ||
1377 | nla_nest_end(skb, port_item); | ||
1378 | } | ||
1379 | |||
1380 | nla_nest_end(skb, port_list); | ||
1381 | return genlmsg_end(skb, hdr); | ||
1382 | |||
1383 | nla_put_failure: | ||
1384 | genlmsg_cancel(skb, hdr); | ||
1385 | return -EMSGSIZE; | ||
1386 | } | ||
1387 | |||
1388 | static int team_nl_fill_port_list_get(struct sk_buff *skb, | ||
1389 | struct genl_info *info, int flags, | ||
1390 | struct team *team) | ||
1391 | { | ||
1392 | return team_nl_fill_port_list_get_changed(skb, info->snd_pid, | ||
1393 | info->snd_seq, NLM_F_ACK, | ||
1394 | team, NULL); | ||
1395 | } | ||
1396 | |||
1397 | static int team_nl_cmd_port_list_get(struct sk_buff *skb, | ||
1398 | struct genl_info *info) | ||
1399 | { | ||
1400 | struct team *team; | ||
1401 | int err; | ||
1402 | |||
1403 | team = team_nl_team_get(info); | ||
1404 | if (!team) | ||
1405 | return -EINVAL; | ||
1406 | |||
1407 | err = team_nl_send_generic(info, team, team_nl_fill_port_list_get); | ||
1408 | |||
1409 | team_nl_team_put(team); | ||
1410 | |||
1411 | return err; | ||
1412 | } | ||
1413 | |||
1414 | static struct genl_ops team_nl_ops[] = { | ||
1415 | { | ||
1416 | .cmd = TEAM_CMD_NOOP, | ||
1417 | .doit = team_nl_cmd_noop, | ||
1418 | .policy = team_nl_policy, | ||
1419 | }, | ||
1420 | { | ||
1421 | .cmd = TEAM_CMD_OPTIONS_SET, | ||
1422 | .doit = team_nl_cmd_options_set, | ||
1423 | .policy = team_nl_policy, | ||
1424 | .flags = GENL_ADMIN_PERM, | ||
1425 | }, | ||
1426 | { | ||
1427 | .cmd = TEAM_CMD_OPTIONS_GET, | ||
1428 | .doit = team_nl_cmd_options_get, | ||
1429 | .policy = team_nl_policy, | ||
1430 | .flags = GENL_ADMIN_PERM, | ||
1431 | }, | ||
1432 | { | ||
1433 | .cmd = TEAM_CMD_PORT_LIST_GET, | ||
1434 | .doit = team_nl_cmd_port_list_get, | ||
1435 | .policy = team_nl_policy, | ||
1436 | .flags = GENL_ADMIN_PERM, | ||
1437 | }, | ||
1438 | }; | ||
1439 | |||
1440 | static struct genl_multicast_group team_change_event_mcgrp = { | ||
1441 | .name = TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME, | ||
1442 | }; | ||
1443 | |||
1444 | static int team_nl_send_event_options_get(struct team *team, | ||
1445 | struct team_option *changed_option) | ||
1446 | { | ||
1447 | struct sk_buff *skb; | ||
1448 | int err; | ||
1449 | struct net *net = dev_net(team->dev); | ||
1450 | |||
1451 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | ||
1452 | if (!skb) | ||
1453 | return -ENOMEM; | ||
1454 | |||
1455 | err = team_nl_fill_options_get_changed(skb, 0, 0, 0, team, | ||
1456 | changed_option); | ||
1457 | if (err < 0) | ||
1458 | goto err_fill; | ||
1459 | |||
1460 | err = genlmsg_multicast_netns(net, skb, 0, team_change_event_mcgrp.id, | ||
1461 | GFP_KERNEL); | ||
1462 | return err; | ||
1463 | |||
1464 | err_fill: | ||
1465 | nlmsg_free(skb); | ||
1466 | return err; | ||
1467 | } | ||
1468 | |||
1469 | static int team_nl_send_event_port_list_get(struct team_port *port) | ||
1470 | { | ||
1471 | struct sk_buff *skb; | ||
1472 | int err; | ||
1473 | struct net *net = dev_net(port->team->dev); | ||
1474 | |||
1475 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | ||
1476 | if (!skb) | ||
1477 | return -ENOMEM; | ||
1478 | |||
1479 | err = team_nl_fill_port_list_get_changed(skb, 0, 0, 0, | ||
1480 | port->team, port); | ||
1481 | if (err < 0) | ||
1482 | goto err_fill; | ||
1483 | |||
1484 | err = genlmsg_multicast_netns(net, skb, 0, team_change_event_mcgrp.id, | ||
1485 | GFP_KERNEL); | ||
1486 | return err; | ||
1487 | |||
1488 | err_fill: | ||
1489 | nlmsg_free(skb); | ||
1490 | return err; | ||
1491 | } | ||
1492 | |||
1493 | static int team_nl_init(void) | ||
1494 | { | ||
1495 | int err; | ||
1496 | |||
1497 | err = genl_register_family_with_ops(&team_nl_family, team_nl_ops, | ||
1498 | ARRAY_SIZE(team_nl_ops)); | ||
1499 | if (err) | ||
1500 | return err; | ||
1501 | |||
1502 | err = genl_register_mc_group(&team_nl_family, &team_change_event_mcgrp); | ||
1503 | if (err) | ||
1504 | goto err_change_event_grp_reg; | ||
1505 | |||
1506 | return 0; | ||
1507 | |||
1508 | err_change_event_grp_reg: | ||
1509 | genl_unregister_family(&team_nl_family); | ||
1510 | |||
1511 | return err; | ||
1512 | } | ||
1513 | |||
1514 | static void team_nl_fini(void) | ||
1515 | { | ||
1516 | genl_unregister_family(&team_nl_family); | ||
1517 | } | ||
1518 | |||
1519 | |||
1520 | /****************** | ||
1521 | * Change checkers | ||
1522 | ******************/ | ||
1523 | |||
1524 | static void __team_options_change_check(struct team *team, | ||
1525 | struct team_option *changed_option) | ||
1526 | { | ||
1527 | int err; | ||
1528 | |||
1529 | err = team_nl_send_event_options_get(team, changed_option); | ||
1530 | if (err) | ||
1531 | netdev_warn(team->dev, "Failed to send options change via netlink\n"); | ||
1532 | } | ||
1533 | |||
1534 | /* rtnl lock is held */ | ||
1535 | static void __team_port_change_check(struct team_port *port, bool linkup) | ||
1536 | { | ||
1537 | int err; | ||
1538 | |||
1539 | if (port->linkup == linkup) | ||
1540 | return; | ||
1541 | |||
1542 | port->linkup = linkup; | ||
1543 | if (linkup) { | ||
1544 | struct ethtool_cmd ecmd; | ||
1545 | |||
1546 | err = __ethtool_get_settings(port->dev, &ecmd); | ||
1547 | if (!err) { | ||
1548 | port->speed = ethtool_cmd_speed(&ecmd); | ||
1549 | port->duplex = ecmd.duplex; | ||
1550 | goto send_event; | ||
1551 | } | ||
1552 | } | ||
1553 | port->speed = 0; | ||
1554 | port->duplex = 0; | ||
1555 | |||
1556 | send_event: | ||
1557 | err = team_nl_send_event_port_list_get(port); | ||
1558 | if (err) | ||
1559 | netdev_warn(port->team->dev, "Failed to send port change of device %s via netlink\n", | ||
1560 | port->dev->name); | ||
1561 | |||
1562 | } | ||
1563 | |||
1564 | static void team_port_change_check(struct team_port *port, bool linkup) | ||
1565 | { | ||
1566 | struct team *team = port->team; | ||
1567 | |||
1568 | mutex_lock(&team->lock); | ||
1569 | __team_port_change_check(port, linkup); | ||
1570 | mutex_unlock(&team->lock); | ||
1571 | } | ||
1572 | |||
1573 | /************************************ | ||
1574 | * Net device notifier event handler | ||
1575 | ************************************/ | ||
1576 | |||
1577 | static int team_device_event(struct notifier_block *unused, | ||
1578 | unsigned long event, void *ptr) | ||
1579 | { | ||
1580 | struct net_device *dev = (struct net_device *) ptr; | ||
1581 | struct team_port *port; | ||
1582 | |||
1583 | port = team_port_get_rtnl(dev); | ||
1584 | if (!port) | ||
1585 | return NOTIFY_DONE; | ||
1586 | |||
1587 | switch (event) { | ||
1588 | case NETDEV_UP: | ||
1589 | if (netif_carrier_ok(dev)) | ||
1590 | team_port_change_check(port, true); | ||
1591 | case NETDEV_DOWN: | ||
1592 | team_port_change_check(port, false); | ||
1593 | case NETDEV_CHANGE: | ||
1594 | if (netif_running(port->dev)) | ||
1595 | team_port_change_check(port, | ||
1596 | !!netif_carrier_ok(port->dev)); | ||
1597 | break; | ||
1598 | case NETDEV_UNREGISTER: | ||
1599 | team_del_slave(port->team->dev, dev); | ||
1600 | break; | ||
1601 | case NETDEV_FEAT_CHANGE: | ||
1602 | team_compute_features(port->team); | ||
1603 | break; | ||
1604 | case NETDEV_CHANGEMTU: | ||
1605 | /* Forbid to change mtu of underlaying device */ | ||
1606 | return NOTIFY_BAD; | ||
1607 | case NETDEV_PRE_TYPE_CHANGE: | ||
1608 | /* Forbid to change type of underlaying device */ | ||
1609 | return NOTIFY_BAD; | ||
1610 | } | ||
1611 | return NOTIFY_DONE; | ||
1612 | } | ||
1613 | |||
1614 | static struct notifier_block team_notifier_block __read_mostly = { | ||
1615 | .notifier_call = team_device_event, | ||
1616 | }; | ||
1617 | |||
1618 | |||
1619 | /*********************** | ||
1620 | * Module init and exit | ||
1621 | ***********************/ | ||
1622 | |||
1623 | static int __init team_module_init(void) | ||
1624 | { | ||
1625 | int err; | ||
1626 | |||
1627 | register_netdevice_notifier(&team_notifier_block); | ||
1628 | |||
1629 | err = rtnl_link_register(&team_link_ops); | ||
1630 | if (err) | ||
1631 | goto err_rtnl_reg; | ||
1632 | |||
1633 | err = team_nl_init(); | ||
1634 | if (err) | ||
1635 | goto err_nl_init; | ||
1636 | |||
1637 | return 0; | ||
1638 | |||
1639 | err_nl_init: | ||
1640 | rtnl_link_unregister(&team_link_ops); | ||
1641 | |||
1642 | err_rtnl_reg: | ||
1643 | unregister_netdevice_notifier(&team_notifier_block); | ||
1644 | |||
1645 | return err; | ||
1646 | } | ||
1647 | |||
1648 | static void __exit team_module_exit(void) | ||
1649 | { | ||
1650 | team_nl_fini(); | ||
1651 | rtnl_link_unregister(&team_link_ops); | ||
1652 | unregister_netdevice_notifier(&team_notifier_block); | ||
1653 | } | ||
1654 | |||
1655 | module_init(team_module_init); | ||
1656 | module_exit(team_module_exit); | ||
1657 | |||
1658 | MODULE_LICENSE("GPL v2"); | ||
1659 | MODULE_AUTHOR("Jiri Pirko <jpirko@redhat.com>"); | ||
1660 | MODULE_DESCRIPTION("Ethernet team device driver"); | ||
1661 | MODULE_ALIAS_RTNL_LINK(DRV_NAME); | ||
diff --git a/drivers/net/team/team_mode_activebackup.c b/drivers/net/team/team_mode_activebackup.c new file mode 100644 index 000000000000..f4d960e82e29 --- /dev/null +++ b/drivers/net/team/team_mode_activebackup.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * net/drivers/team/team_mode_activebackup.c - Active-backup mode for team | ||
3 | * Copyright (c) 2011 Jiri Pirko <jpirko@redhat.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 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/netdevice.h> | ||
17 | #include <net/rtnetlink.h> | ||
18 | #include <linux/if_team.h> | ||
19 | |||
20 | struct ab_priv { | ||
21 | struct team_port __rcu *active_port; | ||
22 | }; | ||
23 | |||
24 | static struct ab_priv *ab_priv(struct team *team) | ||
25 | { | ||
26 | return (struct ab_priv *) &team->mode_priv; | ||
27 | } | ||
28 | |||
29 | static rx_handler_result_t ab_receive(struct team *team, struct team_port *port, | ||
30 | struct sk_buff *skb) { | ||
31 | struct team_port *active_port; | ||
32 | |||
33 | active_port = rcu_dereference(ab_priv(team)->active_port); | ||
34 | if (active_port != port) | ||
35 | return RX_HANDLER_EXACT; | ||
36 | return RX_HANDLER_ANOTHER; | ||
37 | } | ||
38 | |||
39 | static bool ab_transmit(struct team *team, struct sk_buff *skb) | ||
40 | { | ||
41 | struct team_port *active_port; | ||
42 | |||
43 | active_port = rcu_dereference(ab_priv(team)->active_port); | ||
44 | if (unlikely(!active_port)) | ||
45 | goto drop; | ||
46 | skb->dev = active_port->dev; | ||
47 | if (dev_queue_xmit(skb)) | ||
48 | return false; | ||
49 | return true; | ||
50 | |||
51 | drop: | ||
52 | dev_kfree_skb_any(skb); | ||
53 | return false; | ||
54 | } | ||
55 | |||
56 | static void ab_port_leave(struct team *team, struct team_port *port) | ||
57 | { | ||
58 | if (ab_priv(team)->active_port == port) | ||
59 | RCU_INIT_POINTER(ab_priv(team)->active_port, NULL); | ||
60 | } | ||
61 | |||
62 | static int ab_active_port_get(struct team *team, void *arg) | ||
63 | { | ||
64 | u32 *ifindex = arg; | ||
65 | |||
66 | *ifindex = 0; | ||
67 | if (ab_priv(team)->active_port) | ||
68 | *ifindex = ab_priv(team)->active_port->dev->ifindex; | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static int ab_active_port_set(struct team *team, void *arg) | ||
73 | { | ||
74 | u32 *ifindex = arg; | ||
75 | struct team_port *port; | ||
76 | |||
77 | list_for_each_entry_rcu(port, &team->port_list, list) { | ||
78 | if (port->dev->ifindex == *ifindex) { | ||
79 | rcu_assign_pointer(ab_priv(team)->active_port, port); | ||
80 | return 0; | ||
81 | } | ||
82 | } | ||
83 | return -ENOENT; | ||
84 | } | ||
85 | |||
86 | static const struct team_option ab_options[] = { | ||
87 | { | ||
88 | .name = "activeport", | ||
89 | .type = TEAM_OPTION_TYPE_U32, | ||
90 | .getter = ab_active_port_get, | ||
91 | .setter = ab_active_port_set, | ||
92 | }, | ||
93 | }; | ||
94 | |||
95 | int ab_init(struct team *team) | ||
96 | { | ||
97 | return team_options_register(team, ab_options, ARRAY_SIZE(ab_options)); | ||
98 | } | ||
99 | |||
100 | void ab_exit(struct team *team) | ||
101 | { | ||
102 | team_options_unregister(team, ab_options, ARRAY_SIZE(ab_options)); | ||
103 | } | ||
104 | |||
105 | static const struct team_mode_ops ab_mode_ops = { | ||
106 | .init = ab_init, | ||
107 | .exit = ab_exit, | ||
108 | .receive = ab_receive, | ||
109 | .transmit = ab_transmit, | ||
110 | .port_leave = ab_port_leave, | ||
111 | }; | ||
112 | |||
113 | static struct team_mode ab_mode = { | ||
114 | .kind = "activebackup", | ||
115 | .owner = THIS_MODULE, | ||
116 | .priv_size = sizeof(struct ab_priv), | ||
117 | .ops = &ab_mode_ops, | ||
118 | }; | ||
119 | |||
120 | static int __init ab_init_module(void) | ||
121 | { | ||
122 | return team_mode_register(&ab_mode); | ||
123 | } | ||
124 | |||
125 | static void __exit ab_cleanup_module(void) | ||
126 | { | ||
127 | team_mode_unregister(&ab_mode); | ||
128 | } | ||
129 | |||
130 | module_init(ab_init_module); | ||
131 | module_exit(ab_cleanup_module); | ||
132 | |||
133 | MODULE_LICENSE("GPL v2"); | ||
134 | MODULE_AUTHOR("Jiri Pirko <jpirko@redhat.com>"); | ||
135 | MODULE_DESCRIPTION("Active-backup mode for team"); | ||
136 | MODULE_ALIAS("team-mode-activebackup"); | ||
diff --git a/drivers/net/team/team_mode_roundrobin.c b/drivers/net/team/team_mode_roundrobin.c new file mode 100644 index 000000000000..a0e8f806331a --- /dev/null +++ b/drivers/net/team/team_mode_roundrobin.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * net/drivers/team/team_mode_roundrobin.c - Round-robin mode for team | ||
3 | * Copyright (c) 2011 Jiri Pirko <jpirko@redhat.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 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/netdevice.h> | ||
17 | #include <linux/if_team.h> | ||
18 | |||
19 | struct rr_priv { | ||
20 | unsigned int sent_packets; | ||
21 | }; | ||
22 | |||
23 | static struct rr_priv *rr_priv(struct team *team) | ||
24 | { | ||
25 | return (struct rr_priv *) &team->mode_priv; | ||
26 | } | ||
27 | |||
28 | static struct team_port *__get_first_port_up(struct team *team, | ||
29 | struct team_port *port) | ||
30 | { | ||
31 | struct team_port *cur; | ||
32 | |||
33 | if (port->linkup) | ||
34 | return port; | ||
35 | cur = port; | ||
36 | list_for_each_entry_continue_rcu(cur, &team->port_list, list) | ||
37 | if (cur->linkup) | ||
38 | return cur; | ||
39 | list_for_each_entry_rcu(cur, &team->port_list, list) { | ||
40 | if (cur == port) | ||
41 | break; | ||
42 | if (cur->linkup) | ||
43 | return cur; | ||
44 | } | ||
45 | return NULL; | ||
46 | } | ||
47 | |||
48 | static bool rr_transmit(struct team *team, struct sk_buff *skb) | ||
49 | { | ||
50 | struct team_port *port; | ||
51 | int port_index; | ||
52 | |||
53 | port_index = rr_priv(team)->sent_packets++ % team->port_count; | ||
54 | port = team_get_port_by_index_rcu(team, port_index); | ||
55 | port = __get_first_port_up(team, port); | ||
56 | if (unlikely(!port)) | ||
57 | goto drop; | ||
58 | skb->dev = port->dev; | ||
59 | if (dev_queue_xmit(skb)) | ||
60 | return false; | ||
61 | return true; | ||
62 | |||
63 | drop: | ||
64 | dev_kfree_skb_any(skb); | ||
65 | return false; | ||
66 | } | ||
67 | |||
68 | static int rr_port_enter(struct team *team, struct team_port *port) | ||
69 | { | ||
70 | return team_port_set_team_mac(port); | ||
71 | } | ||
72 | |||
73 | static void rr_port_change_mac(struct team *team, struct team_port *port) | ||
74 | { | ||
75 | team_port_set_team_mac(port); | ||
76 | } | ||
77 | |||
78 | static const struct team_mode_ops rr_mode_ops = { | ||
79 | .transmit = rr_transmit, | ||
80 | .port_enter = rr_port_enter, | ||
81 | .port_change_mac = rr_port_change_mac, | ||
82 | }; | ||
83 | |||
84 | static struct team_mode rr_mode = { | ||
85 | .kind = "roundrobin", | ||
86 | .owner = THIS_MODULE, | ||
87 | .priv_size = sizeof(struct rr_priv), | ||
88 | .ops = &rr_mode_ops, | ||
89 | }; | ||
90 | |||
91 | static int __init rr_init_module(void) | ||
92 | { | ||
93 | return team_mode_register(&rr_mode); | ||
94 | } | ||
95 | |||
96 | static void __exit rr_cleanup_module(void) | ||
97 | { | ||
98 | team_mode_unregister(&rr_mode); | ||
99 | } | ||
100 | |||
101 | module_init(rr_init_module); | ||
102 | module_exit(rr_cleanup_module); | ||
103 | |||
104 | MODULE_LICENSE("GPL v2"); | ||
105 | MODULE_AUTHOR("Jiri Pirko <jpirko@redhat.com>"); | ||
106 | MODULE_DESCRIPTION("Round-robin mode for team"); | ||
107 | MODULE_ALIAS("team-mode-roundrobin"); | ||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 7bea9c65119e..93c5d72711b0 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -123,7 +123,7 @@ struct tun_struct { | |||
123 | gid_t group; | 123 | gid_t group; |
124 | 124 | ||
125 | struct net_device *dev; | 125 | struct net_device *dev; |
126 | u32 set_features; | 126 | netdev_features_t set_features; |
127 | #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ | 127 | #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ |
128 | NETIF_F_TSO6|NETIF_F_UFO) | 128 | NETIF_F_TSO6|NETIF_F_UFO) |
129 | struct fasync_struct *fasync; | 129 | struct fasync_struct *fasync; |
@@ -454,7 +454,8 @@ tun_net_change_mtu(struct net_device *dev, int new_mtu) | |||
454 | return 0; | 454 | return 0; |
455 | } | 455 | } |
456 | 456 | ||
457 | static u32 tun_net_fix_features(struct net_device *dev, u32 features) | 457 | static netdev_features_t tun_net_fix_features(struct net_device *dev, |
458 | netdev_features_t features) | ||
458 | { | 459 | { |
459 | struct tun_struct *tun = netdev_priv(dev); | 460 | struct tun_struct *tun = netdev_priv(dev); |
460 | 461 | ||
@@ -1196,7 +1197,7 @@ static int tun_get_iff(struct net *net, struct tun_struct *tun, | |||
1196 | * privs required. */ | 1197 | * privs required. */ |
1197 | static int set_offload(struct tun_struct *tun, unsigned long arg) | 1198 | static int set_offload(struct tun_struct *tun, unsigned long arg) |
1198 | { | 1199 | { |
1199 | u32 features = 0; | 1200 | netdev_features_t features = 0; |
1200 | 1201 | ||
1201 | if (arg & TUN_F_CSUM) { | 1202 | if (arg & TUN_F_CSUM) { |
1202 | features |= NETIF_F_HW_CSUM; | 1203 | features |= NETIF_F_HW_CSUM; |
@@ -1589,16 +1590,15 @@ static void tun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info | |||
1589 | { | 1590 | { |
1590 | struct tun_struct *tun = netdev_priv(dev); | 1591 | struct tun_struct *tun = netdev_priv(dev); |
1591 | 1592 | ||
1592 | strcpy(info->driver, DRV_NAME); | 1593 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1593 | strcpy(info->version, DRV_VERSION); | 1594 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
1594 | strcpy(info->fw_version, "N/A"); | ||
1595 | 1595 | ||
1596 | switch (tun->flags & TUN_TYPE_MASK) { | 1596 | switch (tun->flags & TUN_TYPE_MASK) { |
1597 | case TUN_TUN_DEV: | 1597 | case TUN_TUN_DEV: |
1598 | strcpy(info->bus_info, "tun"); | 1598 | strlcpy(info->bus_info, "tun", sizeof(info->bus_info)); |
1599 | break; | 1599 | break; |
1600 | case TUN_TAP_DEV: | 1600 | case TUN_TAP_DEV: |
1601 | strcpy(info->bus_info, "tap"); | 1601 | strlcpy(info->bus_info, "tap", sizeof(info->bus_info)); |
1602 | break; | 1602 | break; |
1603 | } | 1603 | } |
1604 | } | 1604 | } |
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index a60d0069cc45..331e44056f5a 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c | |||
@@ -130,7 +130,7 @@ static int rx_submit(struct usbpn_dev *pnd, struct urb *req, gfp_t gfp_flags) | |||
130 | struct page *page; | 130 | struct page *page; |
131 | int err; | 131 | int err; |
132 | 132 | ||
133 | page = __netdev_alloc_page(dev, gfp_flags); | 133 | page = alloc_page(gfp_flags); |
134 | if (!page) | 134 | if (!page) |
135 | return -ENOMEM; | 135 | return -ENOMEM; |
136 | 136 | ||
@@ -140,7 +140,7 @@ static int rx_submit(struct usbpn_dev *pnd, struct urb *req, gfp_t gfp_flags) | |||
140 | err = usb_submit_urb(req, gfp_flags); | 140 | err = usb_submit_urb(req, gfp_flags); |
141 | if (unlikely(err)) { | 141 | if (unlikely(err)) { |
142 | dev_dbg(&dev->dev, "RX submit error (%d)\n", err); | 142 | dev_dbg(&dev->dev, "RX submit error (%d)\n", err); |
143 | netdev_free_page(dev, page); | 143 | put_page(page); |
144 | } | 144 | } |
145 | return err; | 145 | return err; |
146 | } | 146 | } |
@@ -208,9 +208,9 @@ static void rx_complete(struct urb *req) | |||
208 | dev->stats.rx_errors++; | 208 | dev->stats.rx_errors++; |
209 | resubmit: | 209 | resubmit: |
210 | if (page) | 210 | if (page) |
211 | netdev_free_page(dev, page); | 211 | put_page(page); |
212 | if (req) | 212 | if (req) |
213 | rx_submit(pnd, req, GFP_ATOMIC); | 213 | rx_submit(pnd, req, GFP_ATOMIC | __GFP_COLD); |
214 | } | 214 | } |
215 | 215 | ||
216 | static int usbpn_close(struct net_device *dev); | 216 | static int usbpn_close(struct net_device *dev); |
@@ -229,7 +229,7 @@ static int usbpn_open(struct net_device *dev) | |||
229 | for (i = 0; i < rxq_size; i++) { | 229 | for (i = 0; i < rxq_size; i++) { |
230 | struct urb *req = usb_alloc_urb(0, GFP_KERNEL); | 230 | struct urb *req = usb_alloc_urb(0, GFP_KERNEL); |
231 | 231 | ||
232 | if (!req || rx_submit(pnd, req, GFP_KERNEL)) { | 232 | if (!req || rx_submit(pnd, req, GFP_KERNEL | __GFP_COLD)) { |
233 | usbpn_close(dev); | 233 | usbpn_close(dev); |
234 | return -ENOMEM; | 234 | return -ENOMEM; |
235 | } | 235 | } |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index f06fb78383a1..009dd0f18535 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -465,12 +465,10 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) | |||
465 | int temp; | 465 | int temp; |
466 | u8 iface_no; | 466 | u8 iface_no; |
467 | 467 | ||
468 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); | 468 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); |
469 | if (ctx == NULL) | 469 | if (ctx == NULL) |
470 | return -ENODEV; | 470 | return -ENODEV; |
471 | 471 | ||
472 | memset(ctx, 0, sizeof(*ctx)); | ||
473 | |||
474 | init_timer(&ctx->tx_timer); | 472 | init_timer(&ctx->tx_timer); |
475 | spin_lock_init(&ctx->mtx); | 473 | spin_lock_init(&ctx->mtx); |
476 | ctx->netdev = dev->net; | 474 | ctx->netdev = dev->net; |
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index a5b9b12ef268..7d62c39f65cf 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c | |||
@@ -728,7 +728,8 @@ static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu) | |||
728 | } | 728 | } |
729 | 729 | ||
730 | /* Enable or disable Rx checksum offload engine */ | 730 | /* Enable or disable Rx checksum offload engine */ |
731 | static int smsc75xx_set_features(struct net_device *netdev, u32 features) | 731 | static int smsc75xx_set_features(struct net_device *netdev, |
732 | netdev_features_t features) | ||
732 | { | 733 | { |
733 | struct usbnet *dev = netdev_priv(netdev); | 734 | struct usbnet *dev = netdev_priv(netdev); |
734 | struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); | 735 | struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); |
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index eff67678c5a6..56f3894d701a 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c | |||
@@ -516,7 +516,8 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb) | |||
516 | } | 516 | } |
517 | 517 | ||
518 | /* Enable or disable Tx & Rx checksum offload engines */ | 518 | /* Enable or disable Tx & Rx checksum offload engines */ |
519 | static int smsc95xx_set_features(struct net_device *netdev, u32 features) | 519 | static int smsc95xx_set_features(struct net_device *netdev, |
520 | netdev_features_t features) | ||
520 | { | 521 | { |
521 | struct usbnet *dev = netdev_priv(netdev); | 522 | struct usbnet *dev = netdev_priv(netdev); |
522 | u32 read_buf; | 523 | u32 read_buf; |
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index ef883e97cee0..49f4667e1fa3 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c | |||
@@ -27,8 +27,8 @@ | |||
27 | 27 | ||
28 | struct veth_net_stats { | 28 | struct veth_net_stats { |
29 | u64 rx_packets; | 29 | u64 rx_packets; |
30 | u64 tx_packets; | ||
31 | u64 rx_bytes; | 30 | u64 rx_bytes; |
31 | u64 tx_packets; | ||
32 | u64 tx_bytes; | 32 | u64 tx_bytes; |
33 | u64 rx_dropped; | 33 | u64 rx_dropped; |
34 | struct u64_stats_sync syncp; | 34 | struct u64_stats_sync syncp; |
@@ -66,9 +66,8 @@ static int veth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
66 | 66 | ||
67 | static void veth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 67 | static void veth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
68 | { | 68 | { |
69 | strcpy(info->driver, DRV_NAME); | 69 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); |
70 | strcpy(info->version, DRV_VERSION); | 70 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); |
71 | strcpy(info->fw_version, "N/A"); | ||
72 | } | 71 | } |
73 | 72 | ||
74 | static void veth_get_strings(struct net_device *dev, u32 stringset, u8 *buf) | 73 | static void veth_get_strings(struct net_device *dev, u32 stringset, u8 *buf) |
@@ -271,7 +270,7 @@ static void veth_setup(struct net_device *dev) | |||
271 | dev->features |= NETIF_F_LLTX; | 270 | dev->features |= NETIF_F_LLTX; |
272 | dev->destructor = veth_dev_free; | 271 | dev->destructor = veth_dev_free; |
273 | 272 | ||
274 | dev->hw_features = NETIF_F_NO_CSUM | NETIF_F_SG | NETIF_F_RXCSUM; | 273 | dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_RXCSUM; |
275 | } | 274 | } |
276 | 275 | ||
277 | /* | 276 | /* |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 6ee8410443c4..4dc9d842a7a3 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -39,6 +39,7 @@ module_param(gso, bool, 0444); | |||
39 | #define GOOD_COPY_LEN 128 | 39 | #define GOOD_COPY_LEN 128 |
40 | 40 | ||
41 | #define VIRTNET_SEND_COMMAND_SG_MAX 2 | 41 | #define VIRTNET_SEND_COMMAND_SG_MAX 2 |
42 | #define VIRTNET_DRIVER_VERSION "1.0.0" | ||
42 | 43 | ||
43 | struct virtnet_stats { | 44 | struct virtnet_stats { |
44 | struct u64_stats_sync syncp; | 45 | struct u64_stats_sync syncp; |
@@ -889,7 +890,21 @@ static void virtnet_get_ringparam(struct net_device *dev, | |||
889 | 890 | ||
890 | } | 891 | } |
891 | 892 | ||
893 | |||
894 | static void virtnet_get_drvinfo(struct net_device *dev, | ||
895 | struct ethtool_drvinfo *info) | ||
896 | { | ||
897 | struct virtnet_info *vi = netdev_priv(dev); | ||
898 | struct virtio_device *vdev = vi->vdev; | ||
899 | |||
900 | strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); | ||
901 | strlcpy(info->version, VIRTNET_DRIVER_VERSION, sizeof(info->version)); | ||
902 | strlcpy(info->bus_info, virtio_bus_name(vdev), sizeof(info->bus_info)); | ||
903 | |||
904 | } | ||
905 | |||
892 | static const struct ethtool_ops virtnet_ethtool_ops = { | 906 | static const struct ethtool_ops virtnet_ethtool_ops = { |
907 | .get_drvinfo = virtnet_get_drvinfo, | ||
893 | .get_link = ethtool_op_get_link, | 908 | .get_link = ethtool_op_get_link, |
894 | .get_ringparam = virtnet_get_ringparam, | 909 | .get_ringparam = virtnet_get_ringparam, |
895 | }; | 910 | }; |
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index e662cbc8bfbd..b492ee1e5f17 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c | |||
@@ -202,14 +202,9 @@ vmxnet3_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) | |||
202 | struct vmxnet3_adapter *adapter = netdev_priv(netdev); | 202 | struct vmxnet3_adapter *adapter = netdev_priv(netdev); |
203 | 203 | ||
204 | strlcpy(drvinfo->driver, vmxnet3_driver_name, sizeof(drvinfo->driver)); | 204 | strlcpy(drvinfo->driver, vmxnet3_driver_name, sizeof(drvinfo->driver)); |
205 | drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0'; | ||
206 | 205 | ||
207 | strlcpy(drvinfo->version, VMXNET3_DRIVER_VERSION_REPORT, | 206 | strlcpy(drvinfo->version, VMXNET3_DRIVER_VERSION_REPORT, |
208 | sizeof(drvinfo->version)); | 207 | sizeof(drvinfo->version)); |
209 | drvinfo->driver[sizeof(drvinfo->version) - 1] = '\0'; | ||
210 | |||
211 | strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); | ||
212 | drvinfo->fw_version[sizeof(drvinfo->fw_version) - 1] = '\0'; | ||
213 | 208 | ||
214 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), | 209 | strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), |
215 | ETHTOOL_BUSINFO_LEN); | 210 | ETHTOOL_BUSINFO_LEN); |
@@ -262,11 +257,11 @@ vmxnet3_get_strings(struct net_device *netdev, u32 stringset, u8 *buf) | |||
262 | } | 257 | } |
263 | } | 258 | } |
264 | 259 | ||
265 | int vmxnet3_set_features(struct net_device *netdev, u32 features) | 260 | int vmxnet3_set_features(struct net_device *netdev, netdev_features_t features) |
266 | { | 261 | { |
267 | struct vmxnet3_adapter *adapter = netdev_priv(netdev); | 262 | struct vmxnet3_adapter *adapter = netdev_priv(netdev); |
268 | unsigned long flags; | 263 | unsigned long flags; |
269 | u32 changed = features ^ netdev->features; | 264 | netdev_features_t changed = features ^ netdev->features; |
270 | 265 | ||
271 | if (changed & (NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_HW_VLAN_RX)) { | 266 | if (changed & (NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_HW_VLAN_RX)) { |
272 | if (features & NETIF_F_RXCSUM) | 267 | if (features & NETIF_F_RXCSUM) |
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index b18eac1dccaa..ed54797db191 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h | |||
@@ -401,7 +401,7 @@ void | |||
401 | vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter); | 401 | vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter); |
402 | 402 | ||
403 | int | 403 | int |
404 | vmxnet3_set_features(struct net_device *netdev, u32 features); | 404 | vmxnet3_set_features(struct net_device *netdev, netdev_features_t features); |
405 | 405 | ||
406 | int | 406 | int |
407 | vmxnet3_create_queues(struct vmxnet3_adapter *adapter, | 407 | vmxnet3_create_queues(struct vmxnet3_adapter *adapter, |
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 0a304b060b6c..c1c0678b1fb6 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile | |||
@@ -58,6 +58,6 @@ obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/ | |||
58 | obj-$(CONFIG_IWM) += iwmc3200wifi/ | 58 | obj-$(CONFIG_IWM) += iwmc3200wifi/ |
59 | 59 | ||
60 | obj-$(CONFIG_MWIFIEX) += mwifiex/ | 60 | obj-$(CONFIG_MWIFIEX) += mwifiex/ |
61 | obj-$(CONFIG_BRCMFMAC) += brcm80211/ | 61 | |
62 | obj-$(CONFIG_BRCMUMAC) += brcm80211/ | 62 | obj-$(CONFIG_BRCMFMAC) += brcm80211/ |
63 | obj-$(CONFIG_BRCMSMAC) += brcm80211/ | 63 | obj-$(CONFIG_BRCMSMAC) += brcm80211/ |
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 0f9ee46cfc97..4596c33a7a69 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -239,6 +239,7 @@ enum ATH_DEBUG { | |||
239 | ATH_DBG_BTCOEX = 0x00002000, | 239 | ATH_DBG_BTCOEX = 0x00002000, |
240 | ATH_DBG_WMI = 0x00004000, | 240 | ATH_DBG_WMI = 0x00004000, |
241 | ATH_DBG_BSTUCK = 0x00008000, | 241 | ATH_DBG_BSTUCK = 0x00008000, |
242 | ATH_DBG_MCI = 0x00010000, | ||
242 | ATH_DBG_ANY = 0xffffffff | 243 | ATH_DBG_ANY = 0xffffffff |
243 | }; | 244 | }; |
244 | 245 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index f517eb8f7b44..5ac2bc2ebee6 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -1734,7 +1734,8 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
1734 | struct ieee80211_channel *chan, bool offchan, | 1734 | struct ieee80211_channel *chan, bool offchan, |
1735 | enum nl80211_channel_type channel_type, | 1735 | enum nl80211_channel_type channel_type, |
1736 | bool channel_type_valid, unsigned int wait, | 1736 | bool channel_type_valid, unsigned int wait, |
1737 | const u8 *buf, size_t len, bool no_cck, u64 *cookie) | 1737 | const u8 *buf, size_t len, bool no_cck, |
1738 | bool dont_wait_for_ack, u64 *cookie) | ||
1738 | { | 1739 | { |
1739 | struct ath6kl *ar = ath6kl_priv(dev); | 1740 | struct ath6kl *ar = ath6kl_priv(dev); |
1740 | u32 id; | 1741 | u32 id; |
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index c1d2366704b5..81e0031012ca 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c | |||
@@ -1548,7 +1548,8 @@ static int ath6kl_init(struct net_device *dev) | |||
1548 | ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | | 1548 | ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | |
1549 | ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; | 1549 | ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; |
1550 | 1550 | ||
1551 | ar->wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; | 1551 | ar->wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | |
1552 | WIPHY_FLAG_HAVE_AP_SME; | ||
1552 | 1553 | ||
1553 | status = ath6kl_target_config_wlan_params(ar); | 1554 | status = ath6kl_target_config_wlan_params(ar); |
1554 | if (!status) | 1555 | if (!status) |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index d9c08c619a3a..7b4c074e12fa 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -25,6 +25,7 @@ config ATH9K | |||
25 | 25 | ||
26 | config ATH9K_PCI | 26 | config ATH9K_PCI |
27 | bool "Atheros ath9k PCI/PCIe bus support" | 27 | bool "Atheros ath9k PCI/PCIe bus support" |
28 | default y | ||
28 | depends on ATH9K && PCI | 29 | depends on ATH9K && PCI |
29 | ---help--- | 30 | ---help--- |
30 | This option enables the PCI bus support in ath9k. | 31 | This option enables the PCI bus support in ath9k. |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 36ed3c46fec6..49d3f25f509d 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -4,6 +4,7 @@ ath9k-y += beacon.o \ | |||
4 | main.o \ | 4 | main.o \ |
5 | recv.o \ | 5 | recv.o \ |
6 | xmit.o \ | 6 | xmit.o \ |
7 | mci.o \ | ||
7 | 8 | ||
8 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o | 9 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o |
9 | ath9k-$(CONFIG_ATH9K_PCI) += pci.o | 10 | ath9k-$(CONFIG_ATH9K_PCI) += pci.o |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 3b262ba6b172..a93bd63ad23b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -121,10 +121,8 @@ static const struct ar9300_eeprom ar9300_default = { | |||
121 | * if the register is per chain | 121 | * if the register is per chain |
122 | */ | 122 | */ |
123 | .noiseFloorThreshCh = {-1, 0, 0}, | 123 | .noiseFloorThreshCh = {-1, 0, 0}, |
124 | .ob = {1, 1, 1},/* 3 chain */ | 124 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
125 | .db_stage2 = {1, 1, 1}, /* 3 chain */ | 125 | .quick_drop = 0, |
126 | .db_stage3 = {0, 0, 0}, | ||
127 | .db_stage4 = {0, 0, 0}, | ||
128 | .xpaBiasLvl = 0, | 126 | .xpaBiasLvl = 0, |
129 | .txFrameToDataStart = 0x0e, | 127 | .txFrameToDataStart = 0x0e, |
130 | .txFrameToPaOn = 0x0e, | 128 | .txFrameToPaOn = 0x0e, |
@@ -144,7 +142,7 @@ static const struct ar9300_eeprom ar9300_default = { | |||
144 | }, | 142 | }, |
145 | .base_ext1 = { | 143 | .base_ext1 = { |
146 | .ant_div_control = 0, | 144 | .ant_div_control = 0, |
147 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} | 145 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
148 | }, | 146 | }, |
149 | .calFreqPier2G = { | 147 | .calFreqPier2G = { |
150 | FREQ2FBIN(2412, 1), | 148 | FREQ2FBIN(2412, 1), |
@@ -323,10 +321,8 @@ static const struct ar9300_eeprom ar9300_default = { | |||
323 | .spurChans = {0, 0, 0, 0, 0}, | 321 | .spurChans = {0, 0, 0, 0, 0}, |
324 | /* noiseFloorThreshCh Check if the register is per chain */ | 322 | /* noiseFloorThreshCh Check if the register is per chain */ |
325 | .noiseFloorThreshCh = {-1, 0, 0}, | 323 | .noiseFloorThreshCh = {-1, 0, 0}, |
326 | .ob = {3, 3, 3}, /* 3 chain */ | 324 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
327 | .db_stage2 = {3, 3, 3}, /* 3 chain */ | 325 | .quick_drop = 0, |
328 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ | ||
329 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ | ||
330 | .xpaBiasLvl = 0, | 326 | .xpaBiasLvl = 0, |
331 | .txFrameToDataStart = 0x0e, | 327 | .txFrameToDataStart = 0x0e, |
332 | .txFrameToPaOn = 0x0e, | 328 | .txFrameToPaOn = 0x0e, |
@@ -698,10 +694,8 @@ static const struct ar9300_eeprom ar9300_x113 = { | |||
698 | * if the register is per chain | 694 | * if the register is per chain |
699 | */ | 695 | */ |
700 | .noiseFloorThreshCh = {-1, 0, 0}, | 696 | .noiseFloorThreshCh = {-1, 0, 0}, |
701 | .ob = {1, 1, 1},/* 3 chain */ | 697 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
702 | .db_stage2 = {1, 1, 1}, /* 3 chain */ | 698 | .quick_drop = 0, |
703 | .db_stage3 = {0, 0, 0}, | ||
704 | .db_stage4 = {0, 0, 0}, | ||
705 | .xpaBiasLvl = 0, | 699 | .xpaBiasLvl = 0, |
706 | .txFrameToDataStart = 0x0e, | 700 | .txFrameToDataStart = 0x0e, |
707 | .txFrameToPaOn = 0x0e, | 701 | .txFrameToPaOn = 0x0e, |
@@ -721,7 +715,7 @@ static const struct ar9300_eeprom ar9300_x113 = { | |||
721 | }, | 715 | }, |
722 | .base_ext1 = { | 716 | .base_ext1 = { |
723 | .ant_div_control = 0, | 717 | .ant_div_control = 0, |
724 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} | 718 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
725 | }, | 719 | }, |
726 | .calFreqPier2G = { | 720 | .calFreqPier2G = { |
727 | FREQ2FBIN(2412, 1), | 721 | FREQ2FBIN(2412, 1), |
@@ -900,10 +894,8 @@ static const struct ar9300_eeprom ar9300_x113 = { | |||
900 | .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0}, | 894 | .spurChans = {FREQ2FBIN(5500, 0), 0, 0, 0, 0}, |
901 | /* noiseFloorThreshCh Check if the register is per chain */ | 895 | /* noiseFloorThreshCh Check if the register is per chain */ |
902 | .noiseFloorThreshCh = {-1, 0, 0}, | 896 | .noiseFloorThreshCh = {-1, 0, 0}, |
903 | .ob = {3, 3, 3}, /* 3 chain */ | 897 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
904 | .db_stage2 = {3, 3, 3}, /* 3 chain */ | 898 | .quick_drop = 0, |
905 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ | ||
906 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ | ||
907 | .xpaBiasLvl = 0xf, | 899 | .xpaBiasLvl = 0xf, |
908 | .txFrameToDataStart = 0x0e, | 900 | .txFrameToDataStart = 0x0e, |
909 | .txFrameToPaOn = 0x0e, | 901 | .txFrameToPaOn = 0x0e, |
@@ -1276,10 +1268,8 @@ static const struct ar9300_eeprom ar9300_h112 = { | |||
1276 | * if the register is per chain | 1268 | * if the register is per chain |
1277 | */ | 1269 | */ |
1278 | .noiseFloorThreshCh = {-1, 0, 0}, | 1270 | .noiseFloorThreshCh = {-1, 0, 0}, |
1279 | .ob = {1, 1, 1},/* 3 chain */ | 1271 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
1280 | .db_stage2 = {1, 1, 1}, /* 3 chain */ | 1272 | .quick_drop = 0, |
1281 | .db_stage3 = {0, 0, 0}, | ||
1282 | .db_stage4 = {0, 0, 0}, | ||
1283 | .xpaBiasLvl = 0, | 1273 | .xpaBiasLvl = 0, |
1284 | .txFrameToDataStart = 0x0e, | 1274 | .txFrameToDataStart = 0x0e, |
1285 | .txFrameToPaOn = 0x0e, | 1275 | .txFrameToPaOn = 0x0e, |
@@ -1291,20 +1281,20 @@ static const struct ar9300_eeprom ar9300_h112 = { | |||
1291 | .txEndToRxOn = 0x2, | 1281 | .txEndToRxOn = 0x2, |
1292 | .txFrameToXpaOn = 0xe, | 1282 | .txFrameToXpaOn = 0xe, |
1293 | .thresh62 = 28, | 1283 | .thresh62 = 28, |
1294 | .papdRateMaskHt20 = LE32(0x80c080), | 1284 | .papdRateMaskHt20 = LE32(0x0c80c080), |
1295 | .papdRateMaskHt40 = LE32(0x80c080), | 1285 | .papdRateMaskHt40 = LE32(0x0080c080), |
1296 | .futureModal = { | 1286 | .futureModal = { |
1297 | 0, 0, 0, 0, 0, 0, 0, 0, | 1287 | 0, 0, 0, 0, 0, 0, 0, 0, |
1298 | }, | 1288 | }, |
1299 | }, | 1289 | }, |
1300 | .base_ext1 = { | 1290 | .base_ext1 = { |
1301 | .ant_div_control = 0, | 1291 | .ant_div_control = 0, |
1302 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} | 1292 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
1303 | }, | 1293 | }, |
1304 | .calFreqPier2G = { | 1294 | .calFreqPier2G = { |
1305 | FREQ2FBIN(2412, 1), | 1295 | FREQ2FBIN(2412, 1), |
1306 | FREQ2FBIN(2437, 1), | 1296 | FREQ2FBIN(2437, 1), |
1307 | FREQ2FBIN(2472, 1), | 1297 | FREQ2FBIN(2462, 1), |
1308 | }, | 1298 | }, |
1309 | /* ar9300_cal_data_per_freq_op_loop 2g */ | 1299 | /* ar9300_cal_data_per_freq_op_loop 2g */ |
1310 | .calPierData2G = { | 1300 | .calPierData2G = { |
@@ -1314,7 +1304,7 @@ static const struct ar9300_eeprom ar9300_h112 = { | |||
1314 | }, | 1304 | }, |
1315 | .calTarget_freqbin_Cck = { | 1305 | .calTarget_freqbin_Cck = { |
1316 | FREQ2FBIN(2412, 1), | 1306 | FREQ2FBIN(2412, 1), |
1317 | FREQ2FBIN(2484, 1), | 1307 | FREQ2FBIN(2472, 1), |
1318 | }, | 1308 | }, |
1319 | .calTarget_freqbin_2G = { | 1309 | .calTarget_freqbin_2G = { |
1320 | FREQ2FBIN(2412, 1), | 1310 | FREQ2FBIN(2412, 1), |
@@ -1478,10 +1468,8 @@ static const struct ar9300_eeprom ar9300_h112 = { | |||
1478 | .spurChans = {0, 0, 0, 0, 0}, | 1468 | .spurChans = {0, 0, 0, 0, 0}, |
1479 | /* noiseFloorThreshCh Check if the register is per chain */ | 1469 | /* noiseFloorThreshCh Check if the register is per chain */ |
1480 | .noiseFloorThreshCh = {-1, 0, 0}, | 1470 | .noiseFloorThreshCh = {-1, 0, 0}, |
1481 | .ob = {3, 3, 3}, /* 3 chain */ | 1471 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
1482 | .db_stage2 = {3, 3, 3}, /* 3 chain */ | 1472 | .quick_drop = 0, |
1483 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ | ||
1484 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ | ||
1485 | .xpaBiasLvl = 0, | 1473 | .xpaBiasLvl = 0, |
1486 | .txFrameToDataStart = 0x0e, | 1474 | .txFrameToDataStart = 0x0e, |
1487 | .txFrameToPaOn = 0x0e, | 1475 | .txFrameToPaOn = 0x0e, |
@@ -1515,7 +1503,7 @@ static const struct ar9300_eeprom ar9300_h112 = { | |||
1515 | FREQ2FBIN(5500, 0), | 1503 | FREQ2FBIN(5500, 0), |
1516 | FREQ2FBIN(5600, 0), | 1504 | FREQ2FBIN(5600, 0), |
1517 | FREQ2FBIN(5700, 0), | 1505 | FREQ2FBIN(5700, 0), |
1518 | FREQ2FBIN(5825, 0) | 1506 | FREQ2FBIN(5785, 0) |
1519 | }, | 1507 | }, |
1520 | .calPierData5G = { | 1508 | .calPierData5G = { |
1521 | { | 1509 | { |
@@ -1854,10 +1842,8 @@ static const struct ar9300_eeprom ar9300_x112 = { | |||
1854 | * if the register is per chain | 1842 | * if the register is per chain |
1855 | */ | 1843 | */ |
1856 | .noiseFloorThreshCh = {-1, 0, 0}, | 1844 | .noiseFloorThreshCh = {-1, 0, 0}, |
1857 | .ob = {1, 1, 1},/* 3 chain */ | 1845 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
1858 | .db_stage2 = {1, 1, 1}, /* 3 chain */ | 1846 | .quick_drop = 0, |
1859 | .db_stage3 = {0, 0, 0}, | ||
1860 | .db_stage4 = {0, 0, 0}, | ||
1861 | .xpaBiasLvl = 0, | 1847 | .xpaBiasLvl = 0, |
1862 | .txFrameToDataStart = 0x0e, | 1848 | .txFrameToDataStart = 0x0e, |
1863 | .txFrameToPaOn = 0x0e, | 1849 | .txFrameToPaOn = 0x0e, |
@@ -1877,7 +1863,7 @@ static const struct ar9300_eeprom ar9300_x112 = { | |||
1877 | }, | 1863 | }, |
1878 | .base_ext1 = { | 1864 | .base_ext1 = { |
1879 | .ant_div_control = 0, | 1865 | .ant_div_control = 0, |
1880 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} | 1866 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
1881 | }, | 1867 | }, |
1882 | .calFreqPier2G = { | 1868 | .calFreqPier2G = { |
1883 | FREQ2FBIN(2412, 1), | 1869 | FREQ2FBIN(2412, 1), |
@@ -2056,10 +2042,8 @@ static const struct ar9300_eeprom ar9300_x112 = { | |||
2056 | .spurChans = {0, 0, 0, 0, 0}, | 2042 | .spurChans = {0, 0, 0, 0, 0}, |
2057 | /* noiseFloorThreshch check if the register is per chain */ | 2043 | /* noiseFloorThreshch check if the register is per chain */ |
2058 | .noiseFloorThreshCh = {-1, 0, 0}, | 2044 | .noiseFloorThreshCh = {-1, 0, 0}, |
2059 | .ob = {3, 3, 3}, /* 3 chain */ | 2045 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
2060 | .db_stage2 = {3, 3, 3}, /* 3 chain */ | 2046 | .quick_drop = 0, |
2061 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ | ||
2062 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ | ||
2063 | .xpaBiasLvl = 0, | 2047 | .xpaBiasLvl = 0, |
2064 | .txFrameToDataStart = 0x0e, | 2048 | .txFrameToDataStart = 0x0e, |
2065 | .txFrameToPaOn = 0x0e, | 2049 | .txFrameToPaOn = 0x0e, |
@@ -2431,10 +2415,8 @@ static const struct ar9300_eeprom ar9300_h116 = { | |||
2431 | * if the register is per chain | 2415 | * if the register is per chain |
2432 | */ | 2416 | */ |
2433 | .noiseFloorThreshCh = {-1, 0, 0}, | 2417 | .noiseFloorThreshCh = {-1, 0, 0}, |
2434 | .ob = {1, 1, 1},/* 3 chain */ | 2418 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
2435 | .db_stage2 = {1, 1, 1}, /* 3 chain */ | 2419 | .quick_drop = 0, |
2436 | .db_stage3 = {0, 0, 0}, | ||
2437 | .db_stage4 = {0, 0, 0}, | ||
2438 | .xpaBiasLvl = 0, | 2420 | .xpaBiasLvl = 0, |
2439 | .txFrameToDataStart = 0x0e, | 2421 | .txFrameToDataStart = 0x0e, |
2440 | .txFrameToPaOn = 0x0e, | 2422 | .txFrameToPaOn = 0x0e, |
@@ -2454,12 +2436,12 @@ static const struct ar9300_eeprom ar9300_h116 = { | |||
2454 | }, | 2436 | }, |
2455 | .base_ext1 = { | 2437 | .base_ext1 = { |
2456 | .ant_div_control = 0, | 2438 | .ant_div_control = 0, |
2457 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} | 2439 | .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
2458 | }, | 2440 | }, |
2459 | .calFreqPier2G = { | 2441 | .calFreqPier2G = { |
2460 | FREQ2FBIN(2412, 1), | 2442 | FREQ2FBIN(2412, 1), |
2461 | FREQ2FBIN(2437, 1), | 2443 | FREQ2FBIN(2437, 1), |
2462 | FREQ2FBIN(2472, 1), | 2444 | FREQ2FBIN(2462, 1), |
2463 | }, | 2445 | }, |
2464 | /* ar9300_cal_data_per_freq_op_loop 2g */ | 2446 | /* ar9300_cal_data_per_freq_op_loop 2g */ |
2465 | .calPierData2G = { | 2447 | .calPierData2G = { |
@@ -2633,10 +2615,8 @@ static const struct ar9300_eeprom ar9300_h116 = { | |||
2633 | .spurChans = {0, 0, 0, 0, 0}, | 2615 | .spurChans = {0, 0, 0, 0, 0}, |
2634 | /* noiseFloorThreshCh Check if the register is per chain */ | 2616 | /* noiseFloorThreshCh Check if the register is per chain */ |
2635 | .noiseFloorThreshCh = {-1, 0, 0}, | 2617 | .noiseFloorThreshCh = {-1, 0, 0}, |
2636 | .ob = {3, 3, 3}, /* 3 chain */ | 2618 | .reserved = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
2637 | .db_stage2 = {3, 3, 3}, /* 3 chain */ | 2619 | .quick_drop = 0, |
2638 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ | ||
2639 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ | ||
2640 | .xpaBiasLvl = 0, | 2620 | .xpaBiasLvl = 0, |
2641 | .txFrameToDataStart = 0x0e, | 2621 | .txFrameToDataStart = 0x0e, |
2642 | .txFrameToPaOn = 0x0e, | 2622 | .txFrameToPaOn = 0x0e, |
@@ -2663,7 +2643,7 @@ static const struct ar9300_eeprom ar9300_h116 = { | |||
2663 | .xatten1MarginHigh = {0, 0, 0} | 2643 | .xatten1MarginHigh = {0, 0, 0} |
2664 | }, | 2644 | }, |
2665 | .calFreqPier5G = { | 2645 | .calFreqPier5G = { |
2666 | FREQ2FBIN(5180, 0), | 2646 | FREQ2FBIN(5160, 0), |
2667 | FREQ2FBIN(5220, 0), | 2647 | FREQ2FBIN(5220, 0), |
2668 | FREQ2FBIN(5320, 0), | 2648 | FREQ2FBIN(5320, 0), |
2669 | FREQ2FBIN(5400, 0), | 2649 | FREQ2FBIN(5400, 0), |
@@ -3023,6 +3003,8 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, | |||
3023 | return eep->modalHeader5G.antennaGain; | 3003 | return eep->modalHeader5G.antennaGain; |
3024 | case EEP_ANTENNA_GAIN_2G: | 3004 | case EEP_ANTENNA_GAIN_2G: |
3025 | return eep->modalHeader2G.antennaGain; | 3005 | return eep->modalHeader2G.antennaGain; |
3006 | case EEP_QUICK_DROP: | ||
3007 | return pBase->miscConfiguration & BIT(1); | ||
3026 | default: | 3008 | default: |
3027 | return 0; | 3009 | return 0; |
3028 | } | 3010 | } |
@@ -3428,25 +3410,14 @@ static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size, | |||
3428 | PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]); | 3410 | PR_EEP("Chain0 NF Threshold", modal_hdr->noiseFloorThreshCh[0]); |
3429 | PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]); | 3411 | PR_EEP("Chain1 NF Threshold", modal_hdr->noiseFloorThreshCh[1]); |
3430 | PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]); | 3412 | PR_EEP("Chain2 NF Threshold", modal_hdr->noiseFloorThreshCh[2]); |
3413 | PR_EEP("Quick Drop", modal_hdr->quick_drop); | ||
3414 | PR_EEP("txEndToXpaOff", modal_hdr->txEndToXpaOff); | ||
3431 | PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl); | 3415 | PR_EEP("xPA Bias Level", modal_hdr->xpaBiasLvl); |
3432 | PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart); | 3416 | PR_EEP("txFrameToDataStart", modal_hdr->txFrameToDataStart); |
3433 | PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn); | 3417 | PR_EEP("txFrameToPaOn", modal_hdr->txFrameToPaOn); |
3434 | PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn); | 3418 | PR_EEP("txFrameToXpaOn", modal_hdr->txFrameToXpaOn); |
3435 | PR_EEP("txClip", modal_hdr->txClip); | 3419 | PR_EEP("txClip", modal_hdr->txClip); |
3436 | PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize); | 3420 | PR_EEP("ADC Desired size", modal_hdr->adcDesiredSize); |
3437 | PR_EEP("Chain0 ob", modal_hdr->ob[0]); | ||
3438 | PR_EEP("Chain1 ob", modal_hdr->ob[1]); | ||
3439 | PR_EEP("Chain2 ob", modal_hdr->ob[2]); | ||
3440 | |||
3441 | PR_EEP("Chain0 db_stage2", modal_hdr->db_stage2[0]); | ||
3442 | PR_EEP("Chain1 db_stage2", modal_hdr->db_stage2[1]); | ||
3443 | PR_EEP("Chain2 db_stage2", modal_hdr->db_stage2[2]); | ||
3444 | PR_EEP("Chain0 db_stage3", modal_hdr->db_stage3[0]); | ||
3445 | PR_EEP("Chain1 db_stage3", modal_hdr->db_stage3[1]); | ||
3446 | PR_EEP("Chain2 db_stage3", modal_hdr->db_stage3[2]); | ||
3447 | PR_EEP("Chain0 db_stage4", modal_hdr->db_stage4[0]); | ||
3448 | PR_EEP("Chain1 db_stage4", modal_hdr->db_stage4[1]); | ||
3449 | PR_EEP("Chain2 db_stage4", modal_hdr->db_stage4[2]); | ||
3450 | 3421 | ||
3451 | return len; | 3422 | return len; |
3452 | } | 3423 | } |
@@ -3503,6 +3474,7 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
3503 | PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4))); | 3474 | PR_EEP("Internal regulator", !!(pBase->featureEnable & BIT(4))); |
3504 | PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5))); | 3475 | PR_EEP("Enable Paprd", !!(pBase->featureEnable & BIT(5))); |
3505 | PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0))); | 3476 | PR_EEP("Driver Strength", !!(pBase->miscConfiguration & BIT(0))); |
3477 | PR_EEP("Quick Drop", !!(pBase->miscConfiguration & BIT(1))); | ||
3506 | PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1); | 3478 | PR_EEP("Chain mask Reduce", (pBase->miscConfiguration >> 0x3) & 0x1); |
3507 | PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio); | 3479 | PR_EEP("Write enable Gpio", pBase->eepromWriteEnableGpio); |
3508 | PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio); | 3480 | PR_EEP("WLAN Disable Gpio", pBase->wlanDisableGpio); |
@@ -3965,6 +3937,40 @@ static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah) | |||
3965 | } | 3937 | } |
3966 | } | 3938 | } |
3967 | 3939 | ||
3940 | static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq) | ||
3941 | { | ||
3942 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
3943 | int quick_drop = ath9k_hw_ar9300_get_eeprom(ah, EEP_QUICK_DROP); | ||
3944 | s32 t[3], f[3] = {5180, 5500, 5785}; | ||
3945 | |||
3946 | if (!quick_drop) | ||
3947 | return; | ||
3948 | |||
3949 | if (freq < 4000) | ||
3950 | quick_drop = eep->modalHeader2G.quick_drop; | ||
3951 | else { | ||
3952 | t[0] = eep->base_ext1.quick_drop_low; | ||
3953 | t[1] = eep->modalHeader5G.quick_drop; | ||
3954 | t[2] = eep->base_ext1.quick_drop_high; | ||
3955 | quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3); | ||
3956 | } | ||
3957 | REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop); | ||
3958 | } | ||
3959 | |||
3960 | static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, u16 freq) | ||
3961 | { | ||
3962 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
3963 | u32 value; | ||
3964 | |||
3965 | value = (freq < 4000) ? eep->modalHeader2G.txEndToXpaOff : | ||
3966 | eep->modalHeader5G.txEndToXpaOff; | ||
3967 | |||
3968 | REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, | ||
3969 | AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value); | ||
3970 | REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, | ||
3971 | AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value); | ||
3972 | } | ||
3973 | |||
3968 | static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, | 3974 | static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, |
3969 | struct ath9k_channel *chan) | 3975 | struct ath9k_channel *chan) |
3970 | { | 3976 | { |
@@ -3972,10 +3978,12 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, | |||
3972 | ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); | 3978 | ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); |
3973 | ar9003_hw_drive_strength_apply(ah); | 3979 | ar9003_hw_drive_strength_apply(ah); |
3974 | ar9003_hw_atten_apply(ah, chan); | 3980 | ar9003_hw_atten_apply(ah, chan); |
3981 | ar9003_hw_quick_drop_apply(ah, chan->channel); | ||
3975 | if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah)) | 3982 | if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah)) |
3976 | ar9003_hw_internal_regulator_apply(ah); | 3983 | ar9003_hw_internal_regulator_apply(ah); |
3977 | if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) | 3984 | if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) |
3978 | ar9003_hw_apply_tuning_caps(ah); | 3985 | ar9003_hw_apply_tuning_caps(ah); |
3986 | ar9003_hw_txend_to_xpa_off_apply(ah, chan->channel); | ||
3979 | } | 3987 | } |
3980 | 3988 | ||
3981 | static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah, | 3989 | static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah, |
@@ -5051,6 +5059,8 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, | |||
5051 | regulatory->max_power_level = targetPowerValT2[i]; | 5059 | regulatory->max_power_level = targetPowerValT2[i]; |
5052 | } | 5060 | } |
5053 | 5061 | ||
5062 | ath9k_hw_update_regulatory_maxpower(ah); | ||
5063 | |||
5054 | if (test) | 5064 | if (test) |
5055 | return; | 5065 | return; |
5056 | 5066 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 6335a867527e..bb223fe82816 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | |||
@@ -216,10 +216,8 @@ struct ar9300_modal_eep_header { | |||
216 | u8 spurChans[AR_EEPROM_MODAL_SPURS]; | 216 | u8 spurChans[AR_EEPROM_MODAL_SPURS]; |
217 | /* 3 Check if the register is per chain */ | 217 | /* 3 Check if the register is per chain */ |
218 | int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS]; | 218 | int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS]; |
219 | u8 ob[AR9300_MAX_CHAINS]; | 219 | u8 reserved[11]; |
220 | u8 db_stage2[AR9300_MAX_CHAINS]; | 220 | int8_t quick_drop; |
221 | u8 db_stage3[AR9300_MAX_CHAINS]; | ||
222 | u8 db_stage4[AR9300_MAX_CHAINS]; | ||
223 | u8 xpaBiasLvl; | 221 | u8 xpaBiasLvl; |
224 | u8 txFrameToDataStart; | 222 | u8 txFrameToDataStart; |
225 | u8 txFrameToPaOn; | 223 | u8 txFrameToPaOn; |
@@ -269,7 +267,9 @@ struct cal_ctl_data_5g { | |||
269 | 267 | ||
270 | struct ar9300_BaseExtension_1 { | 268 | struct ar9300_BaseExtension_1 { |
271 | u8 ant_div_control; | 269 | u8 ant_div_control; |
272 | u8 future[13]; | 270 | u8 future[11]; |
271 | int8_t quick_drop_low; | ||
272 | int8_t quick_drop_high; | ||
273 | } __packed; | 273 | } __packed; |
274 | 274 | ||
275 | struct ar9300_BaseExtension_2 { | 275 | struct ar9300_BaseExtension_2 { |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 2330e7ede199..e41d26939ab8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -199,12 +199,14 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, | |||
199 | synth_freq = chan->channel; | 199 | synth_freq = chan->channel; |
200 | } | 200 | } |
201 | } else { | 201 | } else { |
202 | range = 10; | 202 | range = AR_SREV_9462(ah) ? 5 : 10; |
203 | max_spur_cnts = 4; | 203 | max_spur_cnts = 4; |
204 | synth_freq = chan->channel; | 204 | synth_freq = chan->channel; |
205 | } | 205 | } |
206 | 206 | ||
207 | for (i = 0; i < max_spur_cnts; i++) { | 207 | for (i = 0; i < max_spur_cnts; i++) { |
208 | if (AR_SREV_9462(ah) && (i == 0 || i == 3)) | ||
209 | continue; | ||
208 | negative = 0; | 210 | negative = 0; |
209 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) | 211 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) |
210 | cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], | 212 | cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 4114fe752c6b..497d7461838a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -389,6 +389,8 @@ | |||
389 | #define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10 | 389 | #define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10 |
390 | 390 | ||
391 | #define AR_PHY_RIFS_INIT_DELAY 0x3ff0000 | 391 | #define AR_PHY_RIFS_INIT_DELAY 0x3ff0000 |
392 | #define AR_PHY_AGC_QUICK_DROP 0x03c00000 | ||
393 | #define AR_PHY_AGC_QUICK_DROP_S 22 | ||
392 | #define AR_PHY_AGC_COARSE_LOW 0x00007F80 | 394 | #define AR_PHY_AGC_COARSE_LOW 0x00007F80 |
393 | #define AR_PHY_AGC_COARSE_LOW_S 7 | 395 | #define AR_PHY_AGC_COARSE_LOW_S 7 |
394 | #define AR_PHY_AGC_COARSE_HIGH 0x003F8000 | 396 | #define AR_PHY_AGC_COARSE_HIGH 0x003F8000 |
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 9c51b395b4ff..259a6f312afb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | |||
@@ -43,16 +43,16 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { | |||
43 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 43 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
44 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, | 44 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, |
45 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, | 45 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, |
46 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, | 46 | {0x00009824, 0x5ac640de, 0x5ac640d0, 0x5ac640d0, 0x5ac640de}, |
47 | {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, | 47 | {0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x0796be89}, |
48 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | 48 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, |
49 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, | 49 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, |
50 | {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, | 50 | {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, |
51 | {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, | 51 | {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, |
52 | {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, | 52 | {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, |
53 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, | 53 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, |
54 | {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, | 54 | {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x92c84d2e}, |
55 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3039605e, 0x33795d5e}, | 55 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, |
56 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 56 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
57 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | 57 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, |
58 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | 58 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, |
@@ -688,8 +688,8 @@ static const u32 ar9462_2p0_mac_postamble_emulation[][5] = { | |||
688 | static const u32 ar9462_2p0_radio_postamble_sys3ant[][5] = { | 688 | static const u32 ar9462_2p0_radio_postamble_sys3ant[][5] = { |
689 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 689 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
690 | {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, | 690 | {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, |
691 | {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, | 691 | {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, |
692 | {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, | 692 | {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, |
693 | }; | 693 | }; |
694 | 694 | ||
695 | static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = { | 695 | static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = { |
@@ -717,8 +717,8 @@ static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = { | |||
717 | static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = { | 717 | static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = { |
718 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 718 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
719 | {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, | 719 | {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, |
720 | {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, | 720 | {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, |
721 | {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, | 721 | {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, |
722 | }; | 722 | }; |
723 | 723 | ||
724 | static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = { | 724 | static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = { |
@@ -1059,7 +1059,7 @@ static const u32 ar9462_modes_low_ob_db_tx_gain_table_2p0[][5] = { | |||
1059 | 1059 | ||
1060 | static const u32 ar9462_2p0_soc_postamble[][5] = { | 1060 | static const u32 ar9462_2p0_soc_postamble[][5] = { |
1061 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 1061 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
1062 | {0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233}, | 1062 | {0x00007010, 0x00000033, 0x00000033, 0x00000033, 0x00000033}, |
1063 | }; | 1063 | }; |
1064 | 1064 | ||
1065 | static const u32 ar9462_2p0_baseband_core[][2] = { | 1065 | static const u32 ar9462_2p0_baseband_core[][2] = { |
@@ -1257,8 +1257,8 @@ static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = { | |||
1257 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, | 1257 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, |
1258 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, | 1258 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, |
1259 | {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, | 1259 | {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, |
1260 | {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, | 1260 | {0x0000a54c, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83}, |
1261 | {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, | 1261 | {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001c84, 0x44001c84}, |
1262 | {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, | 1262 | {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, |
1263 | {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, | 1263 | {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, |
1264 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, | 1264 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, |
@@ -1850,8 +1850,8 @@ static const u32 ar9462_modes_green_ob_db_tx_gain_table_2p0[][5] = { | |||
1850 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, | 1850 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, |
1851 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, | 1851 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, |
1852 | {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, | 1852 | {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, |
1853 | {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, | 1853 | {0x0000a54c, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83}, |
1854 | {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, | 1854 | {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001c84, 0x44001c84}, |
1855 | {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, | 1855 | {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, |
1856 | {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, | 1856 | {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, |
1857 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, | 1857 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 1c269f50822b..93b45b4b3033 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include "debug.h" | 26 | #include "debug.h" |
27 | #include "common.h" | 27 | #include "common.h" |
28 | #include "mci.h" | ||
28 | 29 | ||
29 | /* | 30 | /* |
30 | * Header for the ath9k.ko driver core *only* -- hw code nor any other driver | 31 | * Header for the ath9k.ko driver core *only* -- hw code nor any other driver |
@@ -252,6 +253,7 @@ struct ath_node { | |||
252 | #ifdef CONFIG_ATH9K_DEBUGFS | 253 | #ifdef CONFIG_ATH9K_DEBUGFS |
253 | struct list_head list; /* for sc->nodes */ | 254 | struct list_head list; /* for sc->nodes */ |
254 | struct ieee80211_sta *sta; /* station struct we're part of */ | 255 | struct ieee80211_sta *sta; /* station struct we're part of */ |
256 | struct ieee80211_vif *vif; /* interface with which we're associated */ | ||
255 | #endif | 257 | #endif |
256 | struct ath_atx_tid tid[WME_NUM_TID]; | 258 | struct ath_atx_tid tid[WME_NUM_TID]; |
257 | struct ath_atx_ac ac[WME_NUM_AC]; | 259 | struct ath_atx_ac ac[WME_NUM_AC]; |
@@ -443,7 +445,9 @@ struct ath_btcoex { | |||
443 | u32 btcoex_no_stomp; /* in usec */ | 445 | u32 btcoex_no_stomp; /* in usec */ |
444 | u32 btcoex_period; /* in usec */ | 446 | u32 btcoex_period; /* in usec */ |
445 | u32 btscan_no_stomp; /* in usec */ | 447 | u32 btscan_no_stomp; /* in usec */ |
448 | u32 duty_cycle; | ||
446 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ | 449 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ |
450 | struct ath_mci_profile mci; | ||
447 | }; | 451 | }; |
448 | 452 | ||
449 | int ath_init_btcoex_timer(struct ath_softc *sc); | 453 | int ath_init_btcoex_timer(struct ath_softc *sc); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 2741203e803f..6fb719d85b37 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -709,24 +709,29 @@ static ssize_t read_file_stations(struct file *file, char __user *user_buf, | |||
709 | 709 | ||
710 | len += snprintf(buf + len, size - len, | 710 | len += snprintf(buf + len, size - len, |
711 | "Stations:\n" | 711 | "Stations:\n" |
712 | " tid: addr sched paused buf_q-empty an ac\n" | 712 | " tid: addr sched paused buf_q-empty an ac baw\n" |
713 | " ac: addr sched tid_q-empty txq\n"); | 713 | " ac: addr sched tid_q-empty txq\n"); |
714 | 714 | ||
715 | spin_lock(&sc->nodes_lock); | 715 | spin_lock(&sc->nodes_lock); |
716 | list_for_each_entry(an, &sc->nodes, list) { | 716 | list_for_each_entry(an, &sc->nodes, list) { |
717 | unsigned short ma = an->maxampdu; | ||
718 | if (ma == 0) | ||
719 | ma = 65535; /* see ath_lookup_rate */ | ||
717 | len += snprintf(buf + len, size - len, | 720 | len += snprintf(buf + len, size - len, |
718 | "%pM\n", an->sta->addr); | 721 | "iface: %pM sta: %pM max-ampdu: %hu mpdu-density: %uus\n", |
722 | an->vif->addr, an->sta->addr, ma, | ||
723 | (unsigned int)(an->mpdudensity)); | ||
719 | if (len >= size) | 724 | if (len >= size) |
720 | goto done; | 725 | goto done; |
721 | 726 | ||
722 | for (q = 0; q < WME_NUM_TID; q++) { | 727 | for (q = 0; q < WME_NUM_TID; q++) { |
723 | struct ath_atx_tid *tid = &(an->tid[q]); | 728 | struct ath_atx_tid *tid = &(an->tid[q]); |
724 | len += snprintf(buf + len, size - len, | 729 | len += snprintf(buf + len, size - len, |
725 | " tid: %p %s %s %i %p %p\n", | 730 | " tid: %p %s %s %i %p %p %hu\n", |
726 | tid, tid->sched ? "sched" : "idle", | 731 | tid, tid->sched ? "sched" : "idle", |
727 | tid->paused ? "paused" : "running", | 732 | tid->paused ? "paused" : "running", |
728 | skb_queue_empty(&tid->buf_q), | 733 | skb_queue_empty(&tid->buf_q), |
729 | tid->an, tid->ac); | 734 | tid->an, tid->ac, tid->baw_size); |
730 | if (len >= size) | 735 | if (len >= size) |
731 | goto done; | 736 | goto done; |
732 | } | 737 | } |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 49abd34be741..5ff7ab965120 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -249,7 +249,8 @@ enum eeprom_param { | |||
249 | EEP_ANT_DIV_CTL1, | 249 | EEP_ANT_DIV_CTL1, |
250 | EEP_CHAIN_MASK_REDUCE, | 250 | EEP_CHAIN_MASK_REDUCE, |
251 | EEP_ANTENNA_GAIN_2G, | 251 | EEP_ANTENNA_GAIN_2G, |
252 | EEP_ANTENNA_GAIN_5G | 252 | EEP_ANTENNA_GAIN_5G, |
253 | EEP_QUICK_DROP | ||
253 | }; | 254 | }; |
254 | 255 | ||
255 | enum ar5416_rates { | 256 | enum ar5416_rates { |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 655576c8fdab..2c279dcaf4ba 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -189,8 +189,8 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
189 | bool is_btscan; | 189 | bool is_btscan; |
190 | 190 | ||
191 | ath9k_ps_wakeup(sc); | 191 | ath9k_ps_wakeup(sc); |
192 | ath_detect_bt_priority(sc); | 192 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) |
193 | 193 | ath_detect_bt_priority(sc); | |
194 | is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | 194 | is_btscan = sc->sc_flags & SC_OP_BT_SCAN; |
195 | 195 | ||
196 | spin_lock_bh(&btcoex->btcoex_lock); | 196 | spin_lock_bh(&btcoex->btcoex_lock); |
@@ -212,8 +212,9 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
212 | } | 212 | } |
213 | 213 | ||
214 | ath9k_ps_restore(sc); | 214 | ath9k_ps_restore(sc); |
215 | timer_period = btcoex->btcoex_period / 1000; | ||
215 | mod_timer(&btcoex->period_timer, jiffies + | 216 | mod_timer(&btcoex->period_timer, jiffies + |
216 | msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); | 217 | msecs_to_jiffies(timer_period)); |
217 | } | 218 | } |
218 | 219 | ||
219 | /* | 220 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 2f91acccb7db..662ab7e9a0f0 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -2335,7 +2335,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2335 | ah->enabled_cals |= TX_IQ_ON_AGC_CAL; | 2335 | ah->enabled_cals |= TX_IQ_ON_AGC_CAL; |
2336 | } | 2336 | } |
2337 | if (AR_SREV_9462(ah)) | 2337 | if (AR_SREV_9462(ah)) |
2338 | pCap->hw_caps |= ATH9K_HW_CAP_RTT; | 2338 | pCap->hw_caps |= ATH9K_HW_CAP_RTT | ATH9K_HW_CAP_MCI; |
2339 | 2339 | ||
2340 | return 0; | 2340 | return 0; |
2341 | } | 2341 | } |
@@ -2583,7 +2583,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) | |||
2583 | struct ath9k_channel *chan = ah->curchan; | 2583 | struct ath9k_channel *chan = ah->curchan; |
2584 | struct ieee80211_channel *channel = chan->chan; | 2584 | struct ieee80211_channel *channel = chan->chan; |
2585 | 2585 | ||
2586 | reg->power_limit = min_t(int, limit, MAX_RATE_POWER); | 2586 | reg->power_limit = min_t(u32, limit, MAX_RATE_POWER); |
2587 | if (test) | 2587 | if (test) |
2588 | channel->max_power = MAX_RATE_POWER / 2; | 2588 | channel->max_power = MAX_RATE_POWER / 2; |
2589 | 2589 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index f389b3c93cf3..33e8f2f9d425 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -203,6 +203,7 @@ enum ath9k_hw_caps { | |||
203 | ATH9K_HW_CAP_5GHZ = BIT(14), | 203 | ATH9K_HW_CAP_5GHZ = BIT(14), |
204 | ATH9K_HW_CAP_APM = BIT(15), | 204 | ATH9K_HW_CAP_APM = BIT(15), |
205 | ATH9K_HW_CAP_RTT = BIT(16), | 205 | ATH9K_HW_CAP_RTT = BIT(16), |
206 | ATH9K_HW_CAP_MCI = BIT(17), | ||
206 | }; | 207 | }; |
207 | 208 | ||
208 | struct ath9k_hw_capabilities { | 209 | struct ath9k_hw_capabilities { |
@@ -419,6 +420,16 @@ enum ath9k_rx_qtype { | |||
419 | ATH9K_RX_QUEUE_MAX, | 420 | ATH9K_RX_QUEUE_MAX, |
420 | }; | 421 | }; |
421 | 422 | ||
423 | enum ath_mci_gpm_coex_profile_type { | ||
424 | MCI_GPM_COEX_PROFILE_UNKNOWN, | ||
425 | MCI_GPM_COEX_PROFILE_RFCOMM, | ||
426 | MCI_GPM_COEX_PROFILE_A2DP, | ||
427 | MCI_GPM_COEX_PROFILE_HID, | ||
428 | MCI_GPM_COEX_PROFILE_BNEP, | ||
429 | MCI_GPM_COEX_PROFILE_VOICE, | ||
430 | MCI_GPM_COEX_PROFILE_MAX | ||
431 | }; | ||
432 | |||
422 | struct ath9k_beacon_state { | 433 | struct ath9k_beacon_state { |
423 | u32 bs_nexttbtt; | 434 | u32 bs_nexttbtt; |
424 | u32 bs_nextdtim; | 435 | u32 bs_nextdtim; |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d4c909f8e474..e046de94836a 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -424,6 +424,8 @@ static int ath9k_init_btcoex(struct ath_softc *sc) | |||
424 | txq = sc->tx.txq_map[WME_AC_BE]; | 424 | txq = sc->tx.txq_map[WME_AC_BE]; |
425 | ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); | 425 | ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); |
426 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | 426 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; |
427 | sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; | ||
428 | INIT_LIST_HEAD(&sc->btcoex.mci.info); | ||
427 | break; | 429 | break; |
428 | default: | 430 | default: |
429 | WARN_ON(1); | 431 | WARN_ON(1); |
@@ -695,6 +697,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
695 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 697 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
696 | 698 | ||
697 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | 699 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
700 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; | ||
698 | 701 | ||
699 | hw->queues = 4; | 702 | hw->queues = 4; |
700 | hw->max_rates = 4; | 703 | hw->max_rates = 4; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 93fbe6f40898..e43c41cff25b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -630,7 +630,8 @@ set_timer: | |||
630 | } | 630 | } |
631 | } | 631 | } |
632 | 632 | ||
633 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) | 633 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, |
634 | struct ieee80211_vif *vif) | ||
634 | { | 635 | { |
635 | struct ath_node *an; | 636 | struct ath_node *an; |
636 | an = (struct ath_node *)sta->drv_priv; | 637 | an = (struct ath_node *)sta->drv_priv; |
@@ -640,6 +641,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) | |||
640 | list_add(&an->list, &sc->nodes); | 641 | list_add(&an->list, &sc->nodes); |
641 | spin_unlock(&sc->nodes_lock); | 642 | spin_unlock(&sc->nodes_lock); |
642 | an->sta = sta; | 643 | an->sta = sta; |
644 | an->vif = vif; | ||
643 | #endif | 645 | #endif |
644 | if (sc->sc_flags & SC_OP_TXAGGR) { | 646 | if (sc->sc_flags & SC_OP_TXAGGR) { |
645 | ath_tx_node_init(sc, an); | 647 | ath_tx_node_init(sc, an); |
@@ -1133,8 +1135,9 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1133 | 1135 | ||
1134 | if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && | 1136 | if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && |
1135 | !ah->btcoex_hw.enabled) { | 1137 | !ah->btcoex_hw.enabled) { |
1136 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | 1138 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) |
1137 | AR_STOMP_LOW_WLAN_WGHT); | 1139 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, |
1140 | AR_STOMP_LOW_WLAN_WGHT); | ||
1138 | ath9k_hw_btcoex_enable(ah); | 1141 | ath9k_hw_btcoex_enable(ah); |
1139 | 1142 | ||
1140 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 1143 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
@@ -1237,6 +1240,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1237 | ath9k_hw_btcoex_disable(ah); | 1240 | ath9k_hw_btcoex_disable(ah); |
1238 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 1241 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
1239 | ath9k_btcoex_timer_pause(sc); | 1242 | ath9k_btcoex_timer_pause(sc); |
1243 | ath_mci_flush_profile(&sc->btcoex.mci); | ||
1240 | } | 1244 | } |
1241 | 1245 | ||
1242 | spin_lock_bh(&sc->sc_pcu_lock); | 1246 | spin_lock_bh(&sc->sc_pcu_lock); |
@@ -1798,7 +1802,7 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, | |||
1798 | struct ath_node *an = (struct ath_node *) sta->drv_priv; | 1802 | struct ath_node *an = (struct ath_node *) sta->drv_priv; |
1799 | struct ieee80211_key_conf ps_key = { }; | 1803 | struct ieee80211_key_conf ps_key = { }; |
1800 | 1804 | ||
1801 | ath_node_attach(sc, sta); | 1805 | ath_node_attach(sc, sta, vif); |
1802 | 1806 | ||
1803 | if (vif->type != NL80211_IFTYPE_AP && | 1807 | if (vif->type != NL80211_IFTYPE_AP && |
1804 | vif->type != NL80211_IFTYPE_AP_VLAN) | 1808 | vif->type != NL80211_IFTYPE_AP_VLAN) |
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c new file mode 100644 index 000000000000..0fbb141bc302 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/mci.c | |||
@@ -0,0 +1,254 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "ath9k.h" | ||
18 | #include "mci.h" | ||
19 | |||
20 | u8 ath_mci_duty_cycle[] = { 0, 50, 60, 70, 80, 85, 90, 95, 98 }; | ||
21 | |||
22 | static struct ath_mci_profile_info* | ||
23 | ath_mci_find_profile(struct ath_mci_profile *mci, | ||
24 | struct ath_mci_profile_info *info) | ||
25 | { | ||
26 | struct ath_mci_profile_info *entry; | ||
27 | |||
28 | list_for_each_entry(entry, &mci->info, list) { | ||
29 | if (entry->conn_handle == info->conn_handle) | ||
30 | break; | ||
31 | } | ||
32 | return entry; | ||
33 | } | ||
34 | |||
35 | static bool ath_mci_add_profile(struct ath_common *common, | ||
36 | struct ath_mci_profile *mci, | ||
37 | struct ath_mci_profile_info *info) | ||
38 | { | ||
39 | struct ath_mci_profile_info *entry; | ||
40 | |||
41 | if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) && | ||
42 | (info->type == MCI_GPM_COEX_PROFILE_VOICE)) { | ||
43 | ath_dbg(common, ATH_DBG_MCI, | ||
44 | "Too many SCO profile, failed to add new profile\n"); | ||
45 | return false; | ||
46 | } | ||
47 | |||
48 | if (((NUM_PROF(mci) - mci->num_sco) == ATH_MCI_MAX_ACL_PROFILE) && | ||
49 | (info->type != MCI_GPM_COEX_PROFILE_VOICE)) { | ||
50 | ath_dbg(common, ATH_DBG_MCI, | ||
51 | "Too many ACL profile, failed to add new profile\n"); | ||
52 | return false; | ||
53 | } | ||
54 | |||
55 | entry = ath_mci_find_profile(mci, info); | ||
56 | |||
57 | if (entry) | ||
58 | memcpy(entry, info, 10); | ||
59 | else { | ||
60 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | ||
61 | if (!entry) | ||
62 | return false; | ||
63 | |||
64 | memcpy(entry, info, 10); | ||
65 | INC_PROF(mci, info); | ||
66 | list_add_tail(&info->list, &mci->info); | ||
67 | } | ||
68 | return true; | ||
69 | } | ||
70 | |||
71 | static void ath_mci_del_profile(struct ath_common *common, | ||
72 | struct ath_mci_profile *mci, | ||
73 | struct ath_mci_profile_info *info) | ||
74 | { | ||
75 | struct ath_mci_profile_info *entry; | ||
76 | |||
77 | entry = ath_mci_find_profile(mci, info); | ||
78 | |||
79 | if (!entry) { | ||
80 | ath_dbg(common, ATH_DBG_MCI, | ||
81 | "Profile to be deleted not found\n"); | ||
82 | return; | ||
83 | } | ||
84 | DEC_PROF(mci, entry); | ||
85 | list_del(&entry->list); | ||
86 | kfree(entry); | ||
87 | } | ||
88 | |||
89 | void ath_mci_flush_profile(struct ath_mci_profile *mci) | ||
90 | { | ||
91 | struct ath_mci_profile_info *info, *tinfo; | ||
92 | |||
93 | list_for_each_entry_safe(info, tinfo, &mci->info, list) { | ||
94 | list_del(&info->list); | ||
95 | DEC_PROF(mci, info); | ||
96 | kfree(info); | ||
97 | } | ||
98 | mci->aggr_limit = 0; | ||
99 | } | ||
100 | |||
101 | static void ath_mci_adjust_aggr_limit(struct ath_btcoex *btcoex) | ||
102 | { | ||
103 | struct ath_mci_profile *mci = &btcoex->mci; | ||
104 | u32 wlan_airtime = btcoex->btcoex_period * | ||
105 | (100 - btcoex->duty_cycle) / 100; | ||
106 | |||
107 | /* | ||
108 | * Scale: wlan_airtime is in ms, aggr_limit is in 0.25 ms. | ||
109 | * When wlan_airtime is less than 4ms, aggregation limit has to be | ||
110 | * adjusted half of wlan_airtime to ensure that the aggregation can fit | ||
111 | * without collision with BT traffic. | ||
112 | */ | ||
113 | if ((wlan_airtime <= 4) && | ||
114 | (!mci->aggr_limit || (mci->aggr_limit > (2 * wlan_airtime)))) | ||
115 | mci->aggr_limit = 2 * wlan_airtime; | ||
116 | } | ||
117 | |||
118 | static void ath_mci_update_scheme(struct ath_softc *sc) | ||
119 | { | ||
120 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
121 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
122 | struct ath_mci_profile *mci = &btcoex->mci; | ||
123 | struct ath_mci_profile_info *info; | ||
124 | u32 num_profile = NUM_PROF(mci); | ||
125 | |||
126 | if (num_profile == 1) { | ||
127 | info = list_first_entry(&mci->info, | ||
128 | struct ath_mci_profile_info, | ||
129 | list); | ||
130 | if (mci->num_sco && info->T == 12) { | ||
131 | mci->aggr_limit = 8; | ||
132 | ath_dbg(common, ATH_DBG_MCI, | ||
133 | "Single SCO, aggregation limit 2 ms\n"); | ||
134 | } else if ((info->type == MCI_GPM_COEX_PROFILE_BNEP) && | ||
135 | !info->master) { | ||
136 | btcoex->btcoex_period = 60; | ||
137 | ath_dbg(common, ATH_DBG_MCI, | ||
138 | "Single slave PAN/FTP, bt period 60 ms\n"); | ||
139 | } else if ((info->type == MCI_GPM_COEX_PROFILE_HID) && | ||
140 | (info->T > 0 && info->T < 50) && | ||
141 | (info->A > 1 || info->W > 1)) { | ||
142 | btcoex->duty_cycle = 30; | ||
143 | mci->aggr_limit = 8; | ||
144 | ath_dbg(common, ATH_DBG_MCI, | ||
145 | "Multiple attempt/timeout single HID " | ||
146 | "aggregation limit 2 ms dutycycle 30%%\n"); | ||
147 | } | ||
148 | } else if ((num_profile == 2) && (mci->num_hid == 2)) { | ||
149 | btcoex->duty_cycle = 30; | ||
150 | mci->aggr_limit = 8; | ||
151 | ath_dbg(common, ATH_DBG_MCI, | ||
152 | "Two HIDs aggregation limit 2 ms dutycycle 30%%\n"); | ||
153 | } else if (num_profile > 3) { | ||
154 | mci->aggr_limit = 6; | ||
155 | ath_dbg(common, ATH_DBG_MCI, | ||
156 | "Three or more profiles aggregation limit 1.5 ms\n"); | ||
157 | } | ||
158 | |||
159 | if (IS_CHAN_2GHZ(sc->sc_ah->curchan)) { | ||
160 | if (IS_CHAN_HT(sc->sc_ah->curchan)) | ||
161 | ath_mci_adjust_aggr_limit(btcoex); | ||
162 | else | ||
163 | btcoex->btcoex_period >>= 1; | ||
164 | } | ||
165 | |||
166 | ath9k_hw_btcoex_disable(sc->sc_ah); | ||
167 | ath9k_btcoex_timer_pause(sc); | ||
168 | |||
169 | if (IS_CHAN_5GHZ(sc->sc_ah->curchan)) | ||
170 | return; | ||
171 | |||
172 | btcoex->duty_cycle += (mci->num_bdr ? ATH_MCI_MAX_DUTY_CYCLE : 0); | ||
173 | if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE) | ||
174 | btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE; | ||
175 | |||
176 | btcoex->btcoex_period *= 1000; | ||
177 | btcoex->btcoex_no_stomp = btcoex->btcoex_period * | ||
178 | (100 - btcoex->duty_cycle) / 100; | ||
179 | |||
180 | ath9k_hw_btcoex_enable(sc->sc_ah); | ||
181 | ath9k_btcoex_timer_resume(sc); | ||
182 | } | ||
183 | |||
184 | void ath_mci_process_profile(struct ath_softc *sc, | ||
185 | struct ath_mci_profile_info *info) | ||
186 | { | ||
187 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
188 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
189 | struct ath_mci_profile *mci = &btcoex->mci; | ||
190 | |||
191 | if (info->start) { | ||
192 | if (!ath_mci_add_profile(common, mci, info)) | ||
193 | return; | ||
194 | } else | ||
195 | ath_mci_del_profile(common, mci, info); | ||
196 | |||
197 | btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD; | ||
198 | mci->aggr_limit = mci->num_sco ? 6 : 0; | ||
199 | if (NUM_PROF(mci)) { | ||
200 | btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | ||
201 | btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)]; | ||
202 | } else { | ||
203 | btcoex->bt_stomp_type = mci->num_mgmt ? ATH_BTCOEX_STOMP_ALL : | ||
204 | ATH_BTCOEX_STOMP_LOW; | ||
205 | btcoex->duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; | ||
206 | } | ||
207 | |||
208 | ath_mci_update_scheme(sc); | ||
209 | } | ||
210 | |||
211 | void ath_mci_process_status(struct ath_softc *sc, | ||
212 | struct ath_mci_profile_status *status) | ||
213 | { | ||
214 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
215 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
216 | struct ath_mci_profile *mci = &btcoex->mci; | ||
217 | struct ath_mci_profile_info info; | ||
218 | int i = 0, old_num_mgmt = mci->num_mgmt; | ||
219 | |||
220 | /* Link status type are not handled */ | ||
221 | if (status->is_link) { | ||
222 | ath_dbg(common, ATH_DBG_MCI, | ||
223 | "Skip link type status update\n"); | ||
224 | return; | ||
225 | } | ||
226 | |||
227 | memset(&info, 0, sizeof(struct ath_mci_profile_info)); | ||
228 | |||
229 | info.conn_handle = status->conn_handle; | ||
230 | if (ath_mci_find_profile(mci, &info)) { | ||
231 | ath_dbg(common, ATH_DBG_MCI, | ||
232 | "Skip non link state update for existing profile %d\n", | ||
233 | status->conn_handle); | ||
234 | return; | ||
235 | } | ||
236 | if (status->conn_handle >= ATH_MCI_MAX_PROFILE) { | ||
237 | ath_dbg(common, ATH_DBG_MCI, | ||
238 | "Ignore too many non-link update\n"); | ||
239 | return; | ||
240 | } | ||
241 | if (status->is_critical) | ||
242 | __set_bit(status->conn_handle, mci->status); | ||
243 | else | ||
244 | __clear_bit(status->conn_handle, mci->status); | ||
245 | |||
246 | mci->num_mgmt = 0; | ||
247 | do { | ||
248 | if (test_bit(i, mci->status)) | ||
249 | mci->num_mgmt++; | ||
250 | } while (++i < ATH_MCI_MAX_PROFILE); | ||
251 | |||
252 | if (old_num_mgmt != mci->num_mgmt) | ||
253 | ath_mci_update_scheme(sc); | ||
254 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/mci.h b/drivers/net/wireless/ath/ath9k/mci.h new file mode 100644 index 000000000000..9590c61822d1 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/mci.h | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef MCI_H | ||
18 | #define MCI_H | ||
19 | |||
20 | #define ATH_MCI_DEF_BT_PERIOD 40 | ||
21 | #define ATH_MCI_BDR_DUTY_CYCLE 20 | ||
22 | #define ATH_MCI_MAX_DUTY_CYCLE 90 | ||
23 | |||
24 | #define ATH_MCI_DEF_AGGR_LIMIT 6 /* in 0.24 ms */ | ||
25 | #define ATH_MCI_MAX_ACL_PROFILE 7 | ||
26 | #define ATH_MCI_MAX_SCO_PROFILE 1 | ||
27 | #define ATH_MCI_MAX_PROFILE (ATH_MCI_MAX_ACL_PROFILE +\ | ||
28 | ATH_MCI_MAX_SCO_PROFILE) | ||
29 | |||
30 | #define INC_PROF(_mci, _info) do { \ | ||
31 | switch (_info->type) { \ | ||
32 | case MCI_GPM_COEX_PROFILE_RFCOMM:\ | ||
33 | _mci->num_other_acl++; \ | ||
34 | break; \ | ||
35 | case MCI_GPM_COEX_PROFILE_A2DP: \ | ||
36 | _mci->num_a2dp++; \ | ||
37 | if (!_info->edr) \ | ||
38 | _mci->num_bdr++; \ | ||
39 | break; \ | ||
40 | case MCI_GPM_COEX_PROFILE_HID: \ | ||
41 | _mci->num_hid++; \ | ||
42 | break; \ | ||
43 | case MCI_GPM_COEX_PROFILE_BNEP: \ | ||
44 | _mci->num_pan++; \ | ||
45 | break; \ | ||
46 | case MCI_GPM_COEX_PROFILE_VOICE: \ | ||
47 | _mci->num_sco++; \ | ||
48 | break; \ | ||
49 | default: \ | ||
50 | break; \ | ||
51 | } \ | ||
52 | } while (0) | ||
53 | |||
54 | #define DEC_PROF(_mci, _info) do { \ | ||
55 | switch (_info->type) { \ | ||
56 | case MCI_GPM_COEX_PROFILE_RFCOMM:\ | ||
57 | _mci->num_other_acl--; \ | ||
58 | break; \ | ||
59 | case MCI_GPM_COEX_PROFILE_A2DP: \ | ||
60 | _mci->num_a2dp--; \ | ||
61 | if (!_info->edr) \ | ||
62 | _mci->num_bdr--; \ | ||
63 | break; \ | ||
64 | case MCI_GPM_COEX_PROFILE_HID: \ | ||
65 | _mci->num_hid--; \ | ||
66 | break; \ | ||
67 | case MCI_GPM_COEX_PROFILE_BNEP: \ | ||
68 | _mci->num_pan--; \ | ||
69 | break; \ | ||
70 | case MCI_GPM_COEX_PROFILE_VOICE: \ | ||
71 | _mci->num_sco--; \ | ||
72 | break; \ | ||
73 | default: \ | ||
74 | break; \ | ||
75 | } \ | ||
76 | } while (0) | ||
77 | |||
78 | #define NUM_PROF(_mci) (_mci->num_other_acl + _mci->num_a2dp + \ | ||
79 | _mci->num_hid + _mci->num_pan + _mci->num_sco) | ||
80 | |||
81 | struct ath_mci_profile_info { | ||
82 | u8 type; | ||
83 | u8 conn_handle; | ||
84 | bool start; | ||
85 | bool master; | ||
86 | bool edr; | ||
87 | u8 voice_type; | ||
88 | u16 T; /* Voice: Tvoice, HID: Tsniff, in slots */ | ||
89 | u8 W; /* Voice: Wvoice, HID: Sniff timeout, in slots */ | ||
90 | u8 A; /* HID: Sniff attempt, in slots */ | ||
91 | struct list_head list; | ||
92 | }; | ||
93 | |||
94 | struct ath_mci_profile_status { | ||
95 | bool is_critical; | ||
96 | bool is_link; | ||
97 | u8 conn_handle; | ||
98 | }; | ||
99 | |||
100 | struct ath_mci_profile { | ||
101 | struct list_head info; | ||
102 | DECLARE_BITMAP(status, ATH_MCI_MAX_PROFILE); | ||
103 | u16 aggr_limit; | ||
104 | u8 num_mgmt; | ||
105 | u8 num_sco; | ||
106 | u8 num_a2dp; | ||
107 | u8 num_hid; | ||
108 | u8 num_pan; | ||
109 | u8 num_other_acl; | ||
110 | u8 num_bdr; | ||
111 | }; | ||
112 | |||
113 | void ath_mci_flush_profile(struct ath_mci_profile *mci); | ||
114 | void ath_mci_process_profile(struct ath_softc *sc, | ||
115 | struct ath_mci_profile_info *info); | ||
116 | void ath_mci_process_status(struct ath_softc *sc, | ||
117 | struct ath_mci_profile_status *status); | ||
118 | #endif | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 03b0a651a591..55d077e7135d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -601,6 +601,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
601 | struct sk_buff *skb; | 601 | struct sk_buff *skb; |
602 | struct ieee80211_tx_info *tx_info; | 602 | struct ieee80211_tx_info *tx_info; |
603 | struct ieee80211_tx_rate *rates; | 603 | struct ieee80211_tx_rate *rates; |
604 | struct ath_mci_profile *mci = &sc->btcoex.mci; | ||
604 | u32 max_4ms_framelen, frmlen; | 605 | u32 max_4ms_framelen, frmlen; |
605 | u16 aggr_limit, legacy = 0; | 606 | u16 aggr_limit, legacy = 0; |
606 | int i; | 607 | int i; |
@@ -645,7 +646,9 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
645 | if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy) | 646 | if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy) |
646 | return 0; | 647 | return 0; |
647 | 648 | ||
648 | if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) | 649 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit) |
650 | aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4; | ||
651 | else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) | ||
649 | aggr_limit = min((max_4ms_framelen * 3) / 8, | 652 | aggr_limit = min((max_4ms_framelen * 3) / 8, |
650 | (u32)ATH_AMPDU_LIMIT_MAX); | 653 | (u32)ATH_AMPDU_LIMIT_MAX); |
651 | else | 654 | else |
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index f06e0695d412..551859214ee9 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -446,7 +446,7 @@ static void carl9170_op_stop(struct ieee80211_hw *hw) | |||
446 | 446 | ||
447 | mutex_lock(&ar->mutex); | 447 | mutex_lock(&ar->mutex); |
448 | if (IS_ACCEPTING_CMD(ar)) { | 448 | if (IS_ACCEPTING_CMD(ar)) { |
449 | rcu_assign_pointer(ar->beacon_iter, NULL); | 449 | RCU_INIT_POINTER(ar->beacon_iter, NULL); |
450 | 450 | ||
451 | carl9170_led_set_state(ar, 0); | 451 | carl9170_led_set_state(ar, 0); |
452 | 452 | ||
@@ -678,7 +678,7 @@ unlock: | |||
678 | vif_priv->active = false; | 678 | vif_priv->active = false; |
679 | bitmap_release_region(&ar->vif_bitmap, vif_id, 0); | 679 | bitmap_release_region(&ar->vif_bitmap, vif_id, 0); |
680 | ar->vifs--; | 680 | ar->vifs--; |
681 | rcu_assign_pointer(ar->vif_priv[vif_id].vif, NULL); | 681 | RCU_INIT_POINTER(ar->vif_priv[vif_id].vif, NULL); |
682 | list_del_rcu(&vif_priv->list); | 682 | list_del_rcu(&vif_priv->list); |
683 | mutex_unlock(&ar->mutex); | 683 | mutex_unlock(&ar->mutex); |
684 | synchronize_rcu(); | 684 | synchronize_rcu(); |
@@ -716,7 +716,7 @@ static void carl9170_op_remove_interface(struct ieee80211_hw *hw, | |||
716 | WARN_ON(vif_priv->enable_beacon); | 716 | WARN_ON(vif_priv->enable_beacon); |
717 | vif_priv->enable_beacon = false; | 717 | vif_priv->enable_beacon = false; |
718 | list_del_rcu(&vif_priv->list); | 718 | list_del_rcu(&vif_priv->list); |
719 | rcu_assign_pointer(ar->vif_priv[id].vif, NULL); | 719 | RCU_INIT_POINTER(ar->vif_priv[id].vif, NULL); |
720 | 720 | ||
721 | if (vif == main_vif) { | 721 | if (vif == main_vif) { |
722 | rcu_read_unlock(); | 722 | rcu_read_unlock(); |
@@ -1258,7 +1258,7 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw, | |||
1258 | } | 1258 | } |
1259 | 1259 | ||
1260 | for (i = 0; i < CARL9170_NUM_TID; i++) | 1260 | for (i = 0; i < CARL9170_NUM_TID; i++) |
1261 | rcu_assign_pointer(sta_info->agg[i], NULL); | 1261 | RCU_INIT_POINTER(sta_info->agg[i], NULL); |
1262 | 1262 | ||
1263 | sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); | 1263 | sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); |
1264 | sta_info->ht_sta = true; | 1264 | sta_info->ht_sta = true; |
@@ -1285,7 +1285,7 @@ static int carl9170_op_sta_remove(struct ieee80211_hw *hw, | |||
1285 | struct carl9170_sta_tid *tid_info; | 1285 | struct carl9170_sta_tid *tid_info; |
1286 | 1286 | ||
1287 | tid_info = rcu_dereference(sta_info->agg[i]); | 1287 | tid_info = rcu_dereference(sta_info->agg[i]); |
1288 | rcu_assign_pointer(sta_info->agg[i], NULL); | 1288 | RCU_INIT_POINTER(sta_info->agg[i], NULL); |
1289 | 1289 | ||
1290 | if (!tid_info) | 1290 | if (!tid_info) |
1291 | continue; | 1291 | continue; |
@@ -1398,7 +1398,7 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, | |||
1398 | spin_unlock_bh(&ar->tx_ampdu_list_lock); | 1398 | spin_unlock_bh(&ar->tx_ampdu_list_lock); |
1399 | } | 1399 | } |
1400 | 1400 | ||
1401 | rcu_assign_pointer(sta_info->agg[tid], NULL); | 1401 | RCU_INIT_POINTER(sta_info->agg[tid], NULL); |
1402 | rcu_read_unlock(); | 1402 | rcu_read_unlock(); |
1403 | 1403 | ||
1404 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 1404 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index b44e3094588a..d58aa1b0a932 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile | |||
@@ -26,7 +26,8 @@ DHDOFILES = \ | |||
26 | dhd_sdio.o \ | 26 | dhd_sdio.o \ |
27 | dhd_linux.o \ | 27 | dhd_linux.o \ |
28 | bcmsdh.o \ | 28 | bcmsdh.o \ |
29 | bcmsdh_sdmmc.o | 29 | bcmsdh_sdmmc.o \ |
30 | sdio_chip.o | ||
30 | 31 | ||
31 | obj-$(CONFIG_BRCMFMAC) += brcmfmac.o | 32 | obj-$(CONFIG_BRCMFMAC) += brcmfmac.o |
32 | brcmfmac-objs += $(DHDOFILES) | 33 | brcmfmac-objs += $(DHDOFILES) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h b/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h index d7d3afd5a10f..cecb5e5f412b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h | |||
@@ -18,13 +18,6 @@ | |||
18 | #define _bcmchip_h_ | 18 | #define _bcmchip_h_ |
19 | 19 | ||
20 | /* bcm4329 */ | 20 | /* bcm4329 */ |
21 | /* SDIO device core, ID 0x829 */ | ||
22 | #define BCM4329_CORE_BUS_BASE 0x18011000 | ||
23 | /* internal memory core, ID 0x80e */ | ||
24 | #define BCM4329_CORE_SOCRAM_BASE 0x18003000 | ||
25 | /* ARM Cortex M3 core, ID 0x82a */ | ||
26 | #define BCM4329_CORE_ARM_BASE 0x18002000 | ||
27 | #define BCM4329_RAMSIZE 0x48000 | ||
28 | /* firmware name */ | 21 | /* firmware name */ |
29 | #define BCM4329_FW_NAME "brcm/bcm4329-fullmac-4.bin" | 22 | #define BCM4329_FW_NAME "brcm/bcm4329-fullmac-4.bin" |
30 | #define BCM4329_NV_NAME "brcm/bcm4329-fullmac-4.txt" | 23 | #define BCM4329_NV_NAME "brcm/bcm4329-fullmac-4.txt" |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 4645766b4070..6da519e7578f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h | |||
@@ -87,7 +87,7 @@ | |||
87 | #define TOE_TX_CSUM_OL 0x00000001 | 87 | #define TOE_TX_CSUM_OL 0x00000001 |
88 | #define TOE_RX_CSUM_OL 0x00000002 | 88 | #define TOE_RX_CSUM_OL 0x00000002 |
89 | 89 | ||
90 | #define BRCMF_BSS_INFO_VERSION 108 /* current ver of brcmf_bss_info struct */ | 90 | #define BRCMF_BSS_INFO_VERSION 108 /* curr ver of brcmf_bss_info_le struct */ |
91 | 91 | ||
92 | /* size of brcmf_scan_params not including variable length array */ | 92 | /* size of brcmf_scan_params not including variable length array */ |
93 | #define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 | 93 | #define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 |
@@ -122,8 +122,6 @@ | |||
122 | 122 | ||
123 | /* For supporting multiple interfaces */ | 123 | /* For supporting multiple interfaces */ |
124 | #define BRCMF_MAX_IFS 16 | 124 | #define BRCMF_MAX_IFS 16 |
125 | #define BRCMF_DEL_IF -0xe | ||
126 | #define BRCMF_BAD_IF -0xf | ||
127 | 125 | ||
128 | #define DOT11_BSSTYPE_ANY 2 | 126 | #define DOT11_BSSTYPE_ANY 2 |
129 | #define DOT11_MAX_DEFAULT_KEYS 4 | 127 | #define DOT11_MAX_DEFAULT_KEYS 4 |
@@ -365,7 +363,7 @@ struct brcmf_pkt_filter_enable_le { | |||
365 | * Applications MUST CHECK ie_offset field and length field to access IEs and | 363 | * Applications MUST CHECK ie_offset field and length field to access IEs and |
366 | * next bss_info structure in a vector (in struct brcmf_scan_results) | 364 | * next bss_info structure in a vector (in struct brcmf_scan_results) |
367 | */ | 365 | */ |
368 | struct brcmf_bss_info { | 366 | struct brcmf_bss_info_le { |
369 | __le32 version; /* version field */ | 367 | __le32 version; /* version field */ |
370 | __le32 length; /* byte length of data in this record, | 368 | __le32 length; /* byte length of data in this record, |
371 | * starting at version and including IEs | 369 | * starting at version and including IEs |
@@ -466,14 +464,13 @@ struct brcmf_scan_results { | |||
466 | u32 buflen; | 464 | u32 buflen; |
467 | u32 version; | 465 | u32 version; |
468 | u32 count; | 466 | u32 count; |
469 | struct brcmf_bss_info bss_info[1]; | 467 | struct brcmf_bss_info_le bss_info_le[]; |
470 | }; | 468 | }; |
471 | 469 | ||
472 | struct brcmf_scan_results_le { | 470 | struct brcmf_scan_results_le { |
473 | __le32 buflen; | 471 | __le32 buflen; |
474 | __le32 version; | 472 | __le32 version; |
475 | __le32 count; | 473 | __le32 count; |
476 | struct brcmf_bss_info bss_info[1]; | ||
477 | }; | 474 | }; |
478 | 475 | ||
479 | /* used for association with a specific BSSID and chanspec list */ | 476 | /* used for association with a specific BSSID and chanspec list */ |
@@ -493,10 +490,6 @@ struct brcmf_join_params { | |||
493 | struct brcmf_assoc_params_le params_le; | 490 | struct brcmf_assoc_params_le params_le; |
494 | }; | 491 | }; |
495 | 492 | ||
496 | /* size of brcmf_scan_results not including variable length array */ | ||
497 | #define BRCMF_SCAN_RESULTS_FIXED_SIZE \ | ||
498 | (sizeof(struct brcmf_scan_results) - sizeof(struct brcmf_bss_info)) | ||
499 | |||
500 | /* incremental scan results struct */ | 493 | /* incremental scan results struct */ |
501 | struct brcmf_iscan_results { | 494 | struct brcmf_iscan_results { |
502 | union { | 495 | union { |
@@ -511,7 +504,7 @@ struct brcmf_iscan_results { | |||
511 | 504 | ||
512 | /* size of brcmf_iscan_results not including variable length array */ | 505 | /* size of brcmf_iscan_results not including variable length array */ |
513 | #define BRCMF_ISCAN_RESULTS_FIXED_SIZE \ | 506 | #define BRCMF_ISCAN_RESULTS_FIXED_SIZE \ |
514 | (BRCMF_SCAN_RESULTS_FIXED_SIZE + \ | 507 | (sizeof(struct brcmf_scan_results) + \ |
515 | offsetof(struct brcmf_iscan_results, results)) | 508 | offsetof(struct brcmf_iscan_results, results)) |
516 | 509 | ||
517 | struct brcmf_wsec_key { | 510 | struct brcmf_wsec_key { |
@@ -734,8 +727,7 @@ extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx, | |||
734 | extern void brcmf_c_init(void); | 727 | extern void brcmf_c_init(void); |
735 | 728 | ||
736 | extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, | 729 | extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, |
737 | struct net_device *ndev, char *name, u8 *mac_addr, | 730 | char *name, u8 *mac_addr); |
738 | u32 flags, u8 bssidx); | ||
739 | extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx); | 731 | extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx); |
740 | 732 | ||
741 | /* Send packet to dongle via data channel */ | 733 | /* Send packet to dongle via data channel */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 891826197f96..40928e58b6a6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | |||
@@ -488,10 +488,9 @@ brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, | |||
488 | 488 | ||
489 | if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { | 489 | if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { |
490 | if (ifevent->action == BRCMF_E_IF_ADD) | 490 | if (ifevent->action == BRCMF_E_IF_ADD) |
491 | brcmf_add_if(drvr_priv, ifevent->ifidx, NULL, | 491 | brcmf_add_if(drvr_priv, ifevent->ifidx, |
492 | event->ifname, | 492 | event->ifname, |
493 | pvt_data->eth.h_dest, | 493 | pvt_data->eth.h_dest); |
494 | ifevent->flags, ifevent->bssidx); | ||
495 | else | 494 | else |
496 | brcmf_del_if(drvr_priv, ifevent->ifidx); | 495 | brcmf_del_if(drvr_priv, ifevent->ifidx); |
497 | } else { | 496 | } else { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 4acbac5a74c6..719fd9397eb6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -58,7 +58,6 @@ struct brcmf_if { | |||
58 | struct net_device *ndev; | 58 | struct net_device *ndev; |
59 | struct net_device_stats stats; | 59 | struct net_device_stats stats; |
60 | int idx; /* iface idx in dongle */ | 60 | int idx; /* iface idx in dongle */ |
61 | int state; /* interface state */ | ||
62 | u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ | 61 | u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ |
63 | }; | 62 | }; |
64 | 63 | ||
@@ -80,20 +79,6 @@ struct brcmf_info { | |||
80 | /* Error bits */ | 79 | /* Error bits */ |
81 | module_param(brcmf_msg_level, int, 0); | 80 | module_param(brcmf_msg_level, int, 0); |
82 | 81 | ||
83 | |||
84 | static int brcmf_net2idx(struct brcmf_info *drvr_priv, struct net_device *ndev) | ||
85 | { | ||
86 | int i = 0; | ||
87 | |||
88 | while (i < BRCMF_MAX_IFS) { | ||
89 | if (drvr_priv->iflist[i] && drvr_priv->iflist[i]->ndev == ndev) | ||
90 | return i; | ||
91 | i++; | ||
92 | } | ||
93 | |||
94 | return BRCMF_BAD_IF; | ||
95 | } | ||
96 | |||
97 | int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name) | 82 | int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name) |
98 | { | 83 | { |
99 | int i = BRCMF_MAX_IFS; | 84 | int i = BRCMF_MAX_IFS; |
@@ -285,14 +270,9 @@ _brcmf_set_mac_address(struct work_struct *work) | |||
285 | 270 | ||
286 | static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) | 271 | static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) |
287 | { | 272 | { |
288 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 273 | struct brcmf_if *ifp = netdev_priv(ndev); |
289 | netdev_priv(ndev); | 274 | struct brcmf_info *drvr_priv = ifp->info; |
290 | struct sockaddr *sa = (struct sockaddr *)addr; | 275 | struct sockaddr *sa = (struct sockaddr *)addr; |
291 | int ifidx; | ||
292 | |||
293 | ifidx = brcmf_net2idx(drvr_priv, ndev); | ||
294 | if (ifidx == BRCMF_BAD_IF) | ||
295 | return -1; | ||
296 | 276 | ||
297 | memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN); | 277 | memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN); |
298 | schedule_work(&drvr_priv->setmacaddr_work); | 278 | schedule_work(&drvr_priv->setmacaddr_work); |
@@ -301,13 +281,8 @@ static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) | |||
301 | 281 | ||
302 | static void brcmf_netdev_set_multicast_list(struct net_device *ndev) | 282 | static void brcmf_netdev_set_multicast_list(struct net_device *ndev) |
303 | { | 283 | { |
304 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 284 | struct brcmf_if *ifp = netdev_priv(ndev); |
305 | netdev_priv(ndev); | 285 | struct brcmf_info *drvr_priv = ifp->info; |
306 | int ifidx; | ||
307 | |||
308 | ifidx = brcmf_net2idx(drvr_priv, ndev); | ||
309 | if (ifidx == BRCMF_BAD_IF) | ||
310 | return; | ||
311 | 286 | ||
312 | schedule_work(&drvr_priv->multicast_work); | 287 | schedule_work(&drvr_priv->multicast_work); |
313 | } | 288 | } |
@@ -341,9 +316,8 @@ int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf) | |||
341 | static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | 316 | static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
342 | { | 317 | { |
343 | int ret; | 318 | int ret; |
344 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 319 | struct brcmf_if *ifp = netdev_priv(ndev); |
345 | netdev_priv(ndev); | 320 | struct brcmf_info *drvr_priv = ifp->info; |
346 | int ifidx; | ||
347 | 321 | ||
348 | brcmf_dbg(TRACE, "Enter\n"); | 322 | brcmf_dbg(TRACE, "Enter\n"); |
349 | 323 | ||
@@ -355,9 +329,8 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
355 | return -ENODEV; | 329 | return -ENODEV; |
356 | } | 330 | } |
357 | 331 | ||
358 | ifidx = brcmf_net2idx(drvr_priv, ndev); | 332 | if (!drvr_priv->iflist[ifp->idx]) { |
359 | if (ifidx == BRCMF_BAD_IF) { | 333 | brcmf_dbg(ERROR, "bad ifidx %d\n", ifp->idx); |
360 | brcmf_dbg(ERROR, "bad ifidx %d\n", ifidx); | ||
361 | netif_stop_queue(ndev); | 334 | netif_stop_queue(ndev); |
362 | return -ENODEV; | 335 | return -ENODEV; |
363 | } | 336 | } |
@@ -367,20 +340,20 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
367 | struct sk_buff *skb2; | 340 | struct sk_buff *skb2; |
368 | 341 | ||
369 | brcmf_dbg(INFO, "%s: insufficient headroom\n", | 342 | brcmf_dbg(INFO, "%s: insufficient headroom\n", |
370 | brcmf_ifname(&drvr_priv->pub, ifidx)); | 343 | brcmf_ifname(&drvr_priv->pub, ifp->idx)); |
371 | drvr_priv->pub.tx_realloc++; | 344 | drvr_priv->pub.tx_realloc++; |
372 | skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen); | 345 | skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen); |
373 | dev_kfree_skb(skb); | 346 | dev_kfree_skb(skb); |
374 | skb = skb2; | 347 | skb = skb2; |
375 | if (skb == NULL) { | 348 | if (skb == NULL) { |
376 | brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n", | 349 | brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n", |
377 | brcmf_ifname(&drvr_priv->pub, ifidx)); | 350 | brcmf_ifname(&drvr_priv->pub, ifp->idx)); |
378 | ret = -ENOMEM; | 351 | ret = -ENOMEM; |
379 | goto done; | 352 | goto done; |
380 | } | 353 | } |
381 | } | 354 | } |
382 | 355 | ||
383 | ret = brcmf_sendpkt(&drvr_priv->pub, ifidx, skb); | 356 | ret = brcmf_sendpkt(&drvr_priv->pub, ifp->idx, skb); |
384 | 357 | ||
385 | done: | 358 | done: |
386 | if (ret) | 359 | if (ret) |
@@ -482,12 +455,10 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb, | |||
482 | skb_mac_header(skb), | 455 | skb_mac_header(skb), |
483 | &event, &data); | 456 | &event, &data); |
484 | 457 | ||
485 | if (drvr_priv->iflist[ifidx] && | 458 | if (drvr_priv->iflist[ifidx]) { |
486 | !drvr_priv->iflist[ifidx]->state) | ||
487 | ifp = drvr_priv->iflist[ifidx]; | 459 | ifp = drvr_priv->iflist[ifidx]; |
488 | |||
489 | if (ifp->ndev) | ||
490 | ifp->ndev->last_rx = jiffies; | 460 | ifp->ndev->last_rx = jiffies; |
461 | } | ||
491 | 462 | ||
492 | drvr->dstats.rx_bytes += skb->len; | 463 | drvr->dstats.rx_bytes += skb->len; |
493 | drvr->rx_packets++; /* Local count */ | 464 | drvr->rx_packets++; /* Local count */ |
@@ -524,19 +495,11 @@ void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, bool success) | |||
524 | 495 | ||
525 | static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) | 496 | static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) |
526 | { | 497 | { |
527 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 498 | struct brcmf_if *ifp = netdev_priv(ndev); |
528 | netdev_priv(ndev); | 499 | struct brcmf_info *drvr_priv = ifp->info; |
529 | struct brcmf_if *ifp; | ||
530 | int ifidx; | ||
531 | 500 | ||
532 | brcmf_dbg(TRACE, "Enter\n"); | 501 | brcmf_dbg(TRACE, "Enter\n"); |
533 | 502 | ||
534 | ifidx = brcmf_net2idx(drvr_priv, ndev); | ||
535 | if (ifidx == BRCMF_BAD_IF) | ||
536 | return NULL; | ||
537 | |||
538 | ifp = drvr_priv->iflist[ifidx]; | ||
539 | |||
540 | if (drvr_priv->pub.up) | 503 | if (drvr_priv->pub.up) |
541 | /* Use the protocol to get dongle stats */ | 504 | /* Use the protocol to get dongle stats */ |
542 | brcmf_proto_dstats(&drvr_priv->pub); | 505 | brcmf_proto_dstats(&drvr_priv->pub); |
@@ -637,8 +600,8 @@ static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol) | |||
637 | static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, | 600 | static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, |
638 | struct ethtool_drvinfo *info) | 601 | struct ethtool_drvinfo *info) |
639 | { | 602 | { |
640 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 603 | struct brcmf_if *ifp = netdev_priv(ndev); |
641 | netdev_priv(ndev); | 604 | struct brcmf_info *drvr_priv = ifp->info; |
642 | 605 | ||
643 | sprintf(info->driver, KBUILD_MODNAME); | 606 | sprintf(info->driver, KBUILD_MODNAME); |
644 | sprintf(info->version, "%lu", drvr_priv->pub.drv_version); | 607 | sprintf(info->version, "%lu", drvr_priv->pub.drv_version); |
@@ -765,14 +728,12 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr) | |||
765 | static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, | 728 | static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, |
766 | int cmd) | 729 | int cmd) |
767 | { | 730 | { |
768 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 731 | struct brcmf_if *ifp = netdev_priv(ndev); |
769 | netdev_priv(ndev); | 732 | struct brcmf_info *drvr_priv = ifp->info; |
770 | int ifidx; | ||
771 | 733 | ||
772 | ifidx = brcmf_net2idx(drvr_priv, ndev); | 734 | brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd); |
773 | brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifidx, cmd); | ||
774 | 735 | ||
775 | if (ifidx == BRCMF_BAD_IF) | 736 | if (!drvr_priv->iflist[ifp->idx]) |
776 | return -1; | 737 | return -1; |
777 | 738 | ||
778 | if (cmd == SIOCETHTOOL) | 739 | if (cmd == SIOCETHTOOL) |
@@ -788,17 +749,14 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len) | |||
788 | s32 err = 0; | 749 | s32 err = 0; |
789 | int buflen = 0; | 750 | int buflen = 0; |
790 | bool is_set_key_cmd; | 751 | bool is_set_key_cmd; |
791 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 752 | struct brcmf_if *ifp = netdev_priv(ndev); |
792 | netdev_priv(ndev); | 753 | struct brcmf_info *drvr_priv = ifp->info; |
793 | int ifidx; | ||
794 | 754 | ||
795 | memset(&dcmd, 0, sizeof(dcmd)); | 755 | memset(&dcmd, 0, sizeof(dcmd)); |
796 | dcmd.cmd = cmd; | 756 | dcmd.cmd = cmd; |
797 | dcmd.buf = arg; | 757 | dcmd.buf = arg; |
798 | dcmd.len = len; | 758 | dcmd.len = len; |
799 | 759 | ||
800 | ifidx = brcmf_net2idx(drvr_priv, ndev); | ||
801 | |||
802 | if (dcmd.buf != NULL) | 760 | if (dcmd.buf != NULL) |
803 | buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN); | 761 | buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN); |
804 | 762 | ||
@@ -826,7 +784,7 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len) | |||
826 | if (is_set_key_cmd) | 784 | if (is_set_key_cmd) |
827 | brcmf_netdev_wait_pend8021x(ndev); | 785 | brcmf_netdev_wait_pend8021x(ndev); |
828 | 786 | ||
829 | err = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, buflen); | 787 | err = brcmf_proto_dcmd(&drvr_priv->pub, ifp->idx, &dcmd, buflen); |
830 | 788 | ||
831 | done: | 789 | done: |
832 | if (err > 0) | 790 | if (err > 0) |
@@ -837,7 +795,8 @@ done: | |||
837 | 795 | ||
838 | static int brcmf_netdev_stop(struct net_device *ndev) | 796 | static int brcmf_netdev_stop(struct net_device *ndev) |
839 | { | 797 | { |
840 | struct brcmf_pub *drvr = *(struct brcmf_pub **) netdev_priv(ndev); | 798 | struct brcmf_if *ifp = netdev_priv(ndev); |
799 | struct brcmf_pub *drvr = &ifp->info->pub; | ||
841 | 800 | ||
842 | brcmf_dbg(TRACE, "Enter\n"); | 801 | brcmf_dbg(TRACE, "Enter\n"); |
843 | brcmf_cfg80211_down(drvr->config); | 802 | brcmf_cfg80211_down(drvr->config); |
@@ -853,16 +812,14 @@ static int brcmf_netdev_stop(struct net_device *ndev) | |||
853 | 812 | ||
854 | static int brcmf_netdev_open(struct net_device *ndev) | 813 | static int brcmf_netdev_open(struct net_device *ndev) |
855 | { | 814 | { |
856 | struct brcmf_info *drvr_priv = *(struct brcmf_info **) | 815 | struct brcmf_if *ifp = netdev_priv(ndev); |
857 | netdev_priv(ndev); | 816 | struct brcmf_info *drvr_priv = ifp->info; |
858 | u32 toe_ol; | 817 | u32 toe_ol; |
859 | int ifidx = brcmf_net2idx(drvr_priv, ndev); | ||
860 | s32 ret = 0; | 818 | s32 ret = 0; |
861 | 819 | ||
862 | brcmf_dbg(TRACE, "ifidx %d\n", ifidx); | 820 | brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); |
863 | |||
864 | if (ifidx == 0) { /* do it only for primary eth0 */ | ||
865 | 821 | ||
822 | if (ifp->idx == 0) { /* do it only for primary eth0 */ | ||
866 | /* try to bring up bus */ | 823 | /* try to bring up bus */ |
867 | ret = brcmf_bus_start(&drvr_priv->pub); | 824 | ret = brcmf_bus_start(&drvr_priv->pub); |
868 | if (ret != 0) { | 825 | if (ret != 0) { |
@@ -874,12 +831,12 @@ static int brcmf_netdev_open(struct net_device *ndev) | |||
874 | memcpy(ndev->dev_addr, drvr_priv->pub.mac, ETH_ALEN); | 831 | memcpy(ndev->dev_addr, drvr_priv->pub.mac, ETH_ALEN); |
875 | 832 | ||
876 | /* Get current TOE mode from dongle */ | 833 | /* Get current TOE mode from dongle */ |
877 | if (brcmf_toe_get(drvr_priv, ifidx, &toe_ol) >= 0 | 834 | if (brcmf_toe_get(drvr_priv, ifp->idx, &toe_ol) >= 0 |
878 | && (toe_ol & TOE_TX_CSUM_OL) != 0) | 835 | && (toe_ol & TOE_TX_CSUM_OL) != 0) |
879 | drvr_priv->iflist[ifidx]->ndev->features |= | 836 | drvr_priv->iflist[ifp->idx]->ndev->features |= |
880 | NETIF_F_IP_CSUM; | 837 | NETIF_F_IP_CSUM; |
881 | else | 838 | else |
882 | drvr_priv->iflist[ifidx]->ndev->features &= | 839 | drvr_priv->iflist[ifp->idx]->ndev->features &= |
883 | ~NETIF_F_IP_CSUM; | 840 | ~NETIF_F_IP_CSUM; |
884 | } | 841 | } |
885 | /* Allow transmit calls */ | 842 | /* Allow transmit calls */ |
@@ -893,75 +850,62 @@ static int brcmf_netdev_open(struct net_device *ndev) | |||
893 | return ret; | 850 | return ret; |
894 | } | 851 | } |
895 | 852 | ||
853 | static const struct net_device_ops brcmf_netdev_ops_pri = { | ||
854 | .ndo_open = brcmf_netdev_open, | ||
855 | .ndo_stop = brcmf_netdev_stop, | ||
856 | .ndo_get_stats = brcmf_netdev_get_stats, | ||
857 | .ndo_do_ioctl = brcmf_netdev_ioctl_entry, | ||
858 | .ndo_start_xmit = brcmf_netdev_start_xmit, | ||
859 | .ndo_set_mac_address = brcmf_netdev_set_mac_address, | ||
860 | .ndo_set_rx_mode = brcmf_netdev_set_multicast_list | ||
861 | }; | ||
862 | |||
896 | int | 863 | int |
897 | brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, struct net_device *ndev, | 864 | brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, char *name, u8 *mac_addr) |
898 | char *name, u8 *mac_addr, u32 flags, u8 bssidx) | ||
899 | { | 865 | { |
900 | struct brcmf_if *ifp; | 866 | struct brcmf_if *ifp; |
901 | int ret = 0, err = 0; | 867 | struct net_device *ndev; |
902 | 868 | ||
903 | brcmf_dbg(TRACE, "idx %d, handle->%p\n", ifidx, ndev); | 869 | brcmf_dbg(TRACE, "idx %d\n", ifidx); |
904 | 870 | ||
905 | ifp = drvr_priv->iflist[ifidx]; | 871 | ifp = drvr_priv->iflist[ifidx]; |
906 | if (!ifp) { | 872 | /* |
907 | ifp = kmalloc(sizeof(struct brcmf_if), GFP_ATOMIC); | 873 | * Delete the existing interface before overwriting it |
908 | if (!ifp) | 874 | * in case we missed the BRCMF_E_IF_DEL event. |
909 | return -ENOMEM; | 875 | */ |
876 | if (ifp) { | ||
877 | brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n", | ||
878 | ifp->ndev->name); | ||
879 | netif_stop_queue(ifp->ndev); | ||
880 | unregister_netdev(ifp->ndev); | ||
881 | free_netdev(ifp->ndev); | ||
882 | drvr_priv->iflist[ifidx] = NULL; | ||
883 | } | ||
884 | |||
885 | /* Allocate netdev, including space for private structure */ | ||
886 | ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup); | ||
887 | if (!ndev) { | ||
888 | brcmf_dbg(ERROR, "OOM - alloc_netdev\n"); | ||
889 | return -ENOMEM; | ||
910 | } | 890 | } |
911 | 891 | ||
912 | memset(ifp, 0, sizeof(struct brcmf_if)); | 892 | ifp = netdev_priv(ndev); |
893 | ifp->ndev = ndev; | ||
913 | ifp->info = drvr_priv; | 894 | ifp->info = drvr_priv; |
914 | drvr_priv->iflist[ifidx] = ifp; | 895 | drvr_priv->iflist[ifidx] = ifp; |
896 | ifp->idx = ifidx; | ||
915 | if (mac_addr != NULL) | 897 | if (mac_addr != NULL) |
916 | memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); | 898 | memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); |
917 | 899 | ||
918 | if (ndev == NULL) { | 900 | if (brcmf_net_attach(&drvr_priv->pub, ifp->idx)) { |
919 | ifp->state = BRCMF_E_IF_ADD; | 901 | brcmf_dbg(ERROR, "brcmf_net_attach failed"); |
920 | ifp->idx = ifidx; | 902 | free_netdev(ifp->ndev); |
921 | /* | 903 | drvr_priv->iflist[ifidx] = NULL; |
922 | * Delete the existing interface before overwriting it | 904 | return -EOPNOTSUPP; |
923 | * in case we missed the BRCMF_E_IF_DEL event. | 905 | } |
924 | */ | ||
925 | if (ifp->ndev != NULL) { | ||
926 | brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n", | ||
927 | ifp->ndev->name); | ||
928 | netif_stop_queue(ifp->ndev); | ||
929 | unregister_netdev(ifp->ndev); | ||
930 | free_netdev(ifp->ndev); | ||
931 | } | ||
932 | |||
933 | /* Allocate netdev, including space for private structure */ | ||
934 | ifp->ndev = alloc_netdev(sizeof(drvr_priv), "wlan%d", | ||
935 | ether_setup); | ||
936 | if (!ifp->ndev) { | ||
937 | brcmf_dbg(ERROR, "OOM - alloc_netdev\n"); | ||
938 | ret = -ENOMEM; | ||
939 | } | ||
940 | |||
941 | if (ret == 0) { | ||
942 | memcpy(netdev_priv(ifp->ndev), &drvr_priv, | ||
943 | sizeof(drvr_priv)); | ||
944 | err = brcmf_net_attach(&drvr_priv->pub, ifp->idx); | ||
945 | if (err != 0) { | ||
946 | brcmf_dbg(ERROR, "brcmf_net_attach failed, err %d\n", | ||
947 | err); | ||
948 | ret = -EOPNOTSUPP; | ||
949 | } else { | ||
950 | brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", | ||
951 | current->pid, ifp->ndev->name); | ||
952 | ifp->state = 0; | ||
953 | } | ||
954 | } | ||
955 | |||
956 | if (ret < 0) { | ||
957 | if (ifp->ndev) | ||
958 | free_netdev(ifp->ndev); | ||
959 | 906 | ||
960 | drvr_priv->iflist[ifp->idx] = NULL; | 907 | brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", |
961 | kfree(ifp); | 908 | current->pid, ifp->ndev->name); |
962 | } | ||
963 | } else | ||
964 | ifp->ndev = ndev; | ||
965 | 909 | ||
966 | return 0; | 910 | return 0; |
967 | } | 911 | } |
@@ -977,47 +921,36 @@ void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx) | |||
977 | brcmf_dbg(ERROR, "Null interface\n"); | 921 | brcmf_dbg(ERROR, "Null interface\n"); |
978 | return; | 922 | return; |
979 | } | 923 | } |
924 | if (ifp->ndev) { | ||
925 | if (ifidx == 0) { | ||
926 | if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { | ||
927 | rtnl_lock(); | ||
928 | brcmf_netdev_stop(ifp->ndev); | ||
929 | rtnl_unlock(); | ||
930 | } | ||
931 | } else { | ||
932 | netif_stop_queue(ifp->ndev); | ||
933 | } | ||
980 | 934 | ||
981 | ifp->state = BRCMF_E_IF_DEL; | ||
982 | ifp->idx = ifidx; | ||
983 | if (ifp->ndev != NULL) { | ||
984 | netif_stop_queue(ifp->ndev); | ||
985 | unregister_netdev(ifp->ndev); | 935 | unregister_netdev(ifp->ndev); |
986 | free_netdev(ifp->ndev); | ||
987 | drvr_priv->iflist[ifidx] = NULL; | 936 | drvr_priv->iflist[ifidx] = NULL; |
988 | kfree(ifp); | 937 | if (ifidx == 0) |
938 | brcmf_cfg80211_detach(drvr_priv->pub.config); | ||
939 | free_netdev(ifp->ndev); | ||
989 | } | 940 | } |
990 | } | 941 | } |
991 | 942 | ||
992 | struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) | 943 | struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) |
993 | { | 944 | { |
994 | struct brcmf_info *drvr_priv = NULL; | 945 | struct brcmf_info *drvr_priv = NULL; |
995 | struct net_device *ndev; | ||
996 | 946 | ||
997 | brcmf_dbg(TRACE, "Enter\n"); | 947 | brcmf_dbg(TRACE, "Enter\n"); |
998 | 948 | ||
999 | /* Allocate netdev, including space for private structure */ | ||
1000 | ndev = alloc_netdev(sizeof(drvr_priv), "wlan%d", ether_setup); | ||
1001 | if (!ndev) { | ||
1002 | brcmf_dbg(ERROR, "OOM - alloc_netdev\n"); | ||
1003 | goto fail; | ||
1004 | } | ||
1005 | |||
1006 | /* Allocate primary brcmf_info */ | 949 | /* Allocate primary brcmf_info */ |
1007 | drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC); | 950 | drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC); |
1008 | if (!drvr_priv) | 951 | if (!drvr_priv) |
1009 | goto fail; | 952 | goto fail; |
1010 | 953 | ||
1011 | /* | ||
1012 | * Save the brcmf_info into the priv | ||
1013 | */ | ||
1014 | memcpy(netdev_priv(ndev), &drvr_priv, sizeof(drvr_priv)); | ||
1015 | |||
1016 | if (brcmf_add_if(drvr_priv, 0, ndev, ndev->name, NULL, 0, 0) == | ||
1017 | BRCMF_BAD_IF) | ||
1018 | goto fail; | ||
1019 | |||
1020 | ndev->netdev_ops = NULL; | ||
1021 | mutex_init(&drvr_priv->proto_block); | 954 | mutex_init(&drvr_priv->proto_block); |
1022 | 955 | ||
1023 | /* Link to info module */ | 956 | /* Link to info module */ |
@@ -1033,29 +966,12 @@ struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) | |||
1033 | goto fail; | 966 | goto fail; |
1034 | } | 967 | } |
1035 | 968 | ||
1036 | /* Attach and link in the cfg80211 */ | ||
1037 | drvr_priv->pub.config = | ||
1038 | brcmf_cfg80211_attach(ndev, | ||
1039 | brcmf_bus_get_device(bus), | ||
1040 | &drvr_priv->pub); | ||
1041 | if (drvr_priv->pub.config == NULL) { | ||
1042 | brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n"); | ||
1043 | goto fail; | ||
1044 | } | ||
1045 | |||
1046 | INIT_WORK(&drvr_priv->setmacaddr_work, _brcmf_set_mac_address); | 969 | INIT_WORK(&drvr_priv->setmacaddr_work, _brcmf_set_mac_address); |
1047 | INIT_WORK(&drvr_priv->multicast_work, _brcmf_set_multicast_list); | 970 | INIT_WORK(&drvr_priv->multicast_work, _brcmf_set_multicast_list); |
1048 | 971 | ||
1049 | /* | ||
1050 | * Save the brcmf_info into the priv | ||
1051 | */ | ||
1052 | memcpy(netdev_priv(ndev), &drvr_priv, sizeof(drvr_priv)); | ||
1053 | |||
1054 | return &drvr_priv->pub; | 972 | return &drvr_priv->pub; |
1055 | 973 | ||
1056 | fail: | 974 | fail: |
1057 | if (ndev) | ||
1058 | free_netdev(ndev); | ||
1059 | if (drvr_priv) | 975 | if (drvr_priv) |
1060 | brcmf_detach(&drvr_priv->pub); | 976 | brcmf_detach(&drvr_priv->pub); |
1061 | 977 | ||
@@ -1123,16 +1039,6 @@ int brcmf_bus_start(struct brcmf_pub *drvr) | |||
1123 | return 0; | 1039 | return 0; |
1124 | } | 1040 | } |
1125 | 1041 | ||
1126 | static struct net_device_ops brcmf_netdev_ops_pri = { | ||
1127 | .ndo_open = brcmf_netdev_open, | ||
1128 | .ndo_stop = brcmf_netdev_stop, | ||
1129 | .ndo_get_stats = brcmf_netdev_get_stats, | ||
1130 | .ndo_do_ioctl = brcmf_netdev_ioctl_entry, | ||
1131 | .ndo_start_xmit = brcmf_netdev_start_xmit, | ||
1132 | .ndo_set_mac_address = brcmf_netdev_set_mac_address, | ||
1133 | .ndo_set_rx_mode = brcmf_netdev_set_multicast_list | ||
1134 | }; | ||
1135 | |||
1136 | int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) | 1042 | int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) |
1137 | { | 1043 | { |
1138 | struct brcmf_info *drvr_priv = drvr->info; | 1044 | struct brcmf_info *drvr_priv = drvr->info; |
@@ -1169,6 +1075,18 @@ int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) | |||
1169 | 1075 | ||
1170 | memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); | 1076 | memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); |
1171 | 1077 | ||
1078 | /* attach to cfg80211 for primary interface */ | ||
1079 | if (!ifidx) { | ||
1080 | drvr->config = | ||
1081 | brcmf_cfg80211_attach(ndev, | ||
1082 | brcmf_bus_get_device(drvr->bus), | ||
1083 | drvr); | ||
1084 | if (drvr->config == NULL) { | ||
1085 | brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n"); | ||
1086 | goto fail; | ||
1087 | } | ||
1088 | } | ||
1089 | |||
1172 | if (register_netdev(ndev) != 0) { | 1090 | if (register_netdev(ndev) != 0) { |
1173 | brcmf_dbg(ERROR, "couldn't register the net device\n"); | 1091 | brcmf_dbg(ERROR, "couldn't register the net device\n"); |
1174 | goto fail; | 1092 | goto fail; |
@@ -1210,21 +1128,13 @@ void brcmf_detach(struct brcmf_pub *drvr) | |||
1210 | if (drvr) { | 1128 | if (drvr) { |
1211 | drvr_priv = drvr->info; | 1129 | drvr_priv = drvr->info; |
1212 | if (drvr_priv) { | 1130 | if (drvr_priv) { |
1213 | struct brcmf_if *ifp; | ||
1214 | int i; | 1131 | int i; |
1215 | 1132 | ||
1216 | for (i = 1; i < BRCMF_MAX_IFS; i++) | 1133 | /* make sure primary interface removed last */ |
1134 | for (i = BRCMF_MAX_IFS-1; i > -1; i--) | ||
1217 | if (drvr_priv->iflist[i]) | 1135 | if (drvr_priv->iflist[i]) |
1218 | brcmf_del_if(drvr_priv, i); | 1136 | brcmf_del_if(drvr_priv, i); |
1219 | 1137 | ||
1220 | ifp = drvr_priv->iflist[0]; | ||
1221 | if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { | ||
1222 | rtnl_lock(); | ||
1223 | brcmf_netdev_stop(ifp->ndev); | ||
1224 | rtnl_unlock(); | ||
1225 | unregister_netdev(ifp->ndev); | ||
1226 | } | ||
1227 | |||
1228 | cancel_work_sync(&drvr_priv->setmacaddr_work); | 1138 | cancel_work_sync(&drvr_priv->setmacaddr_work); |
1229 | cancel_work_sync(&drvr_priv->multicast_work); | 1139 | cancel_work_sync(&drvr_priv->multicast_work); |
1230 | 1140 | ||
@@ -1233,10 +1143,6 @@ void brcmf_detach(struct brcmf_pub *drvr) | |||
1233 | if (drvr->prot) | 1143 | if (drvr->prot) |
1234 | brcmf_proto_detach(drvr); | 1144 | brcmf_proto_detach(drvr); |
1235 | 1145 | ||
1236 | brcmf_cfg80211_detach(drvr->config); | ||
1237 | |||
1238 | free_netdev(ifp->ndev); | ||
1239 | kfree(ifp); | ||
1240 | kfree(drvr_priv); | 1146 | kfree(drvr_priv); |
1241 | } | 1147 | } |
1242 | } | 1148 | } |
@@ -1302,7 +1208,8 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv) | |||
1302 | 1208 | ||
1303 | int brcmf_netdev_wait_pend8021x(struct net_device *ndev) | 1209 | int brcmf_netdev_wait_pend8021x(struct net_device *ndev) |
1304 | { | 1210 | { |
1305 | struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(ndev); | 1211 | struct brcmf_if *ifp = netdev_priv(ndev); |
1212 | struct brcmf_info *drvr_priv = ifp->info; | ||
1306 | int timeout = 10 * HZ / 1000; | 1213 | int timeout = 10 * HZ / 1000; |
1307 | int ntimes = MAX_WAIT_FOR_8021X_TX; | 1214 | int ntimes = MAX_WAIT_FOR_8021X_TX; |
1308 | int pend = brcmf_get_pend_8021x_cnt(drvr_priv); | 1215 | int pend = brcmf_get_pend_8021x_cnt(drvr_priv); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 313b8bf592d1..22913af26db8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/semaphore.h> | 28 | #include <linux/semaphore.h> |
29 | #include <linux/firmware.h> | 29 | #include <linux/firmware.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/bcma/bcma.h> | ||
31 | #include <asm/unaligned.h> | 32 | #include <asm/unaligned.h> |
32 | #include <defs.h> | 33 | #include <defs.h> |
33 | #include <brcmu_wifi.h> | 34 | #include <brcmu_wifi.h> |
@@ -35,6 +36,7 @@ | |||
35 | #include <brcm_hw_ids.h> | 36 | #include <brcm_hw_ids.h> |
36 | #include <soc.h> | 37 | #include <soc.h> |
37 | #include "sdio_host.h" | 38 | #include "sdio_host.h" |
39 | #include "sdio_chip.h" | ||
38 | 40 | ||
39 | #define DCMD_RESP_TIMEOUT 2000 /* In milli second */ | 41 | #define DCMD_RESP_TIMEOUT 2000 /* In milli second */ |
40 | 42 | ||
@@ -134,33 +136,6 @@ struct rte_console { | |||
134 | /* Force no backplane reset */ | 136 | /* Force no backplane reset */ |
135 | #define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 | 137 | #define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 |
136 | 138 | ||
137 | /* SBSDIO_FUNC1_CHIPCLKCSR */ | ||
138 | |||
139 | /* Force ALP request to backplane */ | ||
140 | #define SBSDIO_FORCE_ALP 0x01 | ||
141 | /* Force HT request to backplane */ | ||
142 | #define SBSDIO_FORCE_HT 0x02 | ||
143 | /* Force ILP request to backplane */ | ||
144 | #define SBSDIO_FORCE_ILP 0x04 | ||
145 | /* Make ALP ready (power up xtal) */ | ||
146 | #define SBSDIO_ALP_AVAIL_REQ 0x08 | ||
147 | /* Make HT ready (power up PLL) */ | ||
148 | #define SBSDIO_HT_AVAIL_REQ 0x10 | ||
149 | /* Squelch clock requests from HW */ | ||
150 | #define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 | ||
151 | /* Status: ALP is ready */ | ||
152 | #define SBSDIO_ALP_AVAIL 0x40 | ||
153 | /* Status: HT is ready */ | ||
154 | #define SBSDIO_HT_AVAIL 0x80 | ||
155 | |||
156 | #define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) | ||
157 | #define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) | ||
158 | #define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS) | ||
159 | #define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval)) | ||
160 | |||
161 | #define SBSDIO_CLKAV(regval, alponly) \ | ||
162 | (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval))) | ||
163 | |||
164 | /* direct(mapped) cis space */ | 139 | /* direct(mapped) cis space */ |
165 | 140 | ||
166 | /* MAPPED common CIS address */ | 141 | /* MAPPED common CIS address */ |
@@ -335,50 +310,6 @@ struct rte_console { | |||
335 | /* Flags for SDH calls */ | 310 | /* Flags for SDH calls */ |
336 | #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) | 311 | #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) |
337 | 312 | ||
338 | /* sbimstate */ | ||
339 | #define SBIM_IBE 0x20000 /* inbanderror */ | ||
340 | #define SBIM_TO 0x40000 /* timeout */ | ||
341 | #define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */ | ||
342 | #define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ | ||
343 | |||
344 | /* sbtmstatelow */ | ||
345 | |||
346 | /* reset */ | ||
347 | #define SBTML_RESET 0x0001 | ||
348 | /* reject field */ | ||
349 | #define SBTML_REJ_MASK 0x0006 | ||
350 | /* reject */ | ||
351 | #define SBTML_REJ 0x0002 | ||
352 | /* temporary reject, for error recovery */ | ||
353 | #define SBTML_TMPREJ 0x0004 | ||
354 | |||
355 | /* Shift to locate the SI control flags in sbtml */ | ||
356 | #define SBTML_SICF_SHIFT 16 | ||
357 | |||
358 | /* sbtmstatehigh */ | ||
359 | #define SBTMH_SERR 0x0001 /* serror */ | ||
360 | #define SBTMH_INT 0x0002 /* interrupt */ | ||
361 | #define SBTMH_BUSY 0x0004 /* busy */ | ||
362 | #define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */ | ||
363 | |||
364 | /* Shift to locate the SI status flags in sbtmh */ | ||
365 | #define SBTMH_SISF_SHIFT 16 | ||
366 | |||
367 | /* sbidlow */ | ||
368 | #define SBIDL_INIT 0x80 /* initiator */ | ||
369 | |||
370 | /* sbidhigh */ | ||
371 | #define SBIDH_RC_MASK 0x000f /* revision code */ | ||
372 | #define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ | ||
373 | #define SBIDH_RCE_SHIFT 8 | ||
374 | #define SBCOREREV(sbidh) \ | ||
375 | ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | \ | ||
376 | ((sbidh) & SBIDH_RC_MASK)) | ||
377 | #define SBIDH_CC_MASK 0x8ff0 /* core code */ | ||
378 | #define SBIDH_CC_SHIFT 4 | ||
379 | #define SBIDH_VC_MASK 0xffff0000 /* vendor code */ | ||
380 | #define SBIDH_VC_SHIFT 16 | ||
381 | |||
382 | /* | 313 | /* |
383 | * Conversion of 802.1D priority to precedence level | 314 | * Conversion of 802.1D priority to precedence level |
384 | */ | 315 | */ |
@@ -388,17 +319,6 @@ static uint prio2prec(u32 prio) | |||
388 | (prio^2) : prio; | 319 | (prio^2) : prio; |
389 | } | 320 | } |
390 | 321 | ||
391 | /* | ||
392 | * Core reg address translation. | ||
393 | * Both macro's returns a 32 bits byte address on the backplane bus. | ||
394 | */ | ||
395 | #define CORE_CC_REG(base, field) \ | ||
396 | (base + offsetof(struct chipcregs, field)) | ||
397 | #define CORE_BUS_REG(base, field) \ | ||
398 | (base + offsetof(struct sdpcmd_regs, field)) | ||
399 | #define CORE_SB(base, field) \ | ||
400 | (base + SBCONFIGOFF + offsetof(struct sbconfig, field)) | ||
401 | |||
402 | /* core registers */ | 322 | /* core registers */ |
403 | struct sdpcmd_regs { | 323 | struct sdpcmd_regs { |
404 | u32 corecontrol; /* 0x00, rev8 */ | 324 | u32 corecontrol; /* 0x00, rev8 */ |
@@ -524,21 +444,6 @@ struct sdpcm_shared_le { | |||
524 | 444 | ||
525 | 445 | ||
526 | /* misc chip info needed by some of the routines */ | 446 | /* misc chip info needed by some of the routines */ |
527 | struct chip_info { | ||
528 | u32 chip; | ||
529 | u32 chiprev; | ||
530 | u32 cccorebase; | ||
531 | u32 ccrev; | ||
532 | u32 cccaps; | ||
533 | u32 buscorebase; /* 32 bits backplane bus address */ | ||
534 | u32 buscorerev; | ||
535 | u32 buscoretype; | ||
536 | u32 ramcorebase; | ||
537 | u32 armcorebase; | ||
538 | u32 pmurev; | ||
539 | u32 ramsize; | ||
540 | }; | ||
541 | |||
542 | /* Private data for SDIO bus interaction */ | 447 | /* Private data for SDIO bus interaction */ |
543 | struct brcmf_bus { | 448 | struct brcmf_bus { |
544 | struct brcmf_pub *drvr; | 449 | struct brcmf_pub *drvr; |
@@ -574,7 +479,7 @@ struct brcmf_bus { | |||
574 | uint txminmax; | 479 | uint txminmax; |
575 | 480 | ||
576 | struct sk_buff *glomd; /* Packet containing glomming descriptor */ | 481 | struct sk_buff *glomd; /* Packet containing glomming descriptor */ |
577 | struct sk_buff *glom; /* Packet chain for glommed superframe */ | 482 | struct sk_buff_head glom; /* Packet list for glommed superframe */ |
578 | uint glomerr; /* Glom packet read errors */ | 483 | uint glomerr; /* Glom packet read errors */ |
579 | 484 | ||
580 | u8 *rxbuf; /* Buffer for receiving control packets */ | 485 | u8 *rxbuf; /* Buffer for receiving control packets */ |
@@ -663,46 +568,6 @@ struct brcmf_bus { | |||
663 | u32 fw_ptr; | 568 | u32 fw_ptr; |
664 | }; | 569 | }; |
665 | 570 | ||
666 | struct sbconfig { | ||
667 | u32 PAD[2]; | ||
668 | u32 sbipsflag; /* initiator port ocp slave flag */ | ||
669 | u32 PAD[3]; | ||
670 | u32 sbtpsflag; /* target port ocp slave flag */ | ||
671 | u32 PAD[11]; | ||
672 | u32 sbtmerrloga; /* (sonics >= 2.3) */ | ||
673 | u32 PAD; | ||
674 | u32 sbtmerrlog; /* (sonics >= 2.3) */ | ||
675 | u32 PAD[3]; | ||
676 | u32 sbadmatch3; /* address match3 */ | ||
677 | u32 PAD; | ||
678 | u32 sbadmatch2; /* address match2 */ | ||
679 | u32 PAD; | ||
680 | u32 sbadmatch1; /* address match1 */ | ||
681 | u32 PAD[7]; | ||
682 | u32 sbimstate; /* initiator agent state */ | ||
683 | u32 sbintvec; /* interrupt mask */ | ||
684 | u32 sbtmstatelow; /* target state */ | ||
685 | u32 sbtmstatehigh; /* target state */ | ||
686 | u32 sbbwa0; /* bandwidth allocation table0 */ | ||
687 | u32 PAD; | ||
688 | u32 sbimconfiglow; /* initiator configuration */ | ||
689 | u32 sbimconfighigh; /* initiator configuration */ | ||
690 | u32 sbadmatch0; /* address match0 */ | ||
691 | u32 PAD; | ||
692 | u32 sbtmconfiglow; /* target configuration */ | ||
693 | u32 sbtmconfighigh; /* target configuration */ | ||
694 | u32 sbbconfig; /* broadcast configuration */ | ||
695 | u32 PAD; | ||
696 | u32 sbbstate; /* broadcast state */ | ||
697 | u32 PAD[3]; | ||
698 | u32 sbactcnfg; /* activate configuration */ | ||
699 | u32 PAD[3]; | ||
700 | u32 sbflagst; /* current sbflags */ | ||
701 | u32 PAD[3]; | ||
702 | u32 sbidlow; /* identification */ | ||
703 | u32 sbidhigh; /* identification */ | ||
704 | }; | ||
705 | |||
706 | /* clkstate */ | 571 | /* clkstate */ |
707 | #define CLK_NONE 0 | 572 | #define CLK_NONE 0 |
708 | #define CLK_SDONLY 1 | 573 | #define CLK_SDONLY 1 |
@@ -750,10 +615,12 @@ static bool data_ok(struct brcmf_bus *bus) | |||
750 | static void | 615 | static void |
751 | r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar) | 616 | r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar) |
752 | { | 617 | { |
618 | u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); | ||
753 | *retryvar = 0; | 619 | *retryvar = 0; |
754 | do { | 620 | do { |
755 | *regvar = brcmf_sdcard_reg_read(bus->sdiodev, | 621 | *regvar = brcmf_sdcard_reg_read(bus->sdiodev, |
756 | bus->ci->buscorebase + reg_offset, sizeof(u32)); | 622 | bus->ci->c_inf[idx].base + reg_offset, |
623 | sizeof(u32)); | ||
757 | } while (brcmf_sdcard_regfail(bus->sdiodev) && | 624 | } while (brcmf_sdcard_regfail(bus->sdiodev) && |
758 | (++(*retryvar) <= retry_limit)); | 625 | (++(*retryvar) <= retry_limit)); |
759 | if (*retryvar) { | 626 | if (*retryvar) { |
@@ -768,10 +635,11 @@ r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar) | |||
768 | static void | 635 | static void |
769 | w_sdreg32(struct brcmf_bus *bus, u32 regval, u32 reg_offset, u32 *retryvar) | 636 | w_sdreg32(struct brcmf_bus *bus, u32 regval, u32 reg_offset, u32 *retryvar) |
770 | { | 637 | { |
638 | u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); | ||
771 | *retryvar = 0; | 639 | *retryvar = 0; |
772 | do { | 640 | do { |
773 | brcmf_sdcard_reg_write(bus->sdiodev, | 641 | brcmf_sdcard_reg_write(bus->sdiodev, |
774 | bus->ci->buscorebase + reg_offset, | 642 | bus->ci->c_inf[idx].base + reg_offset, |
775 | sizeof(u32), regval); | 643 | sizeof(u32), regval); |
776 | } while (brcmf_sdcard_regfail(bus->sdiodev) && | 644 | } while (brcmf_sdcard_regfail(bus->sdiodev) && |
777 | (++(*retryvar) <= retry_limit)); | 645 | (++(*retryvar) <= retry_limit)); |
@@ -812,10 +680,6 @@ static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok) | |||
812 | clkreq = | 680 | clkreq = |
813 | bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; | 681 | bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; |
814 | 682 | ||
815 | if ((bus->ci->chip == BCM4329_CHIP_ID) | ||
816 | && (bus->ci->chiprev == 0)) | ||
817 | clkreq |= SBSDIO_FORCE_ALP; | ||
818 | |||
819 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | 683 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, |
820 | SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); | 684 | SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); |
821 | if (err) { | 685 | if (err) { |
@@ -823,14 +687,6 @@ static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok) | |||
823 | return -EBADE; | 687 | return -EBADE; |
824 | } | 688 | } |
825 | 689 | ||
826 | if (pendok && ((bus->ci->buscoretype == PCMCIA_CORE_ID) | ||
827 | && (bus->ci->buscorerev == 9))) { | ||
828 | u32 dummy, retries; | ||
829 | r_sdreg32(bus, &dummy, | ||
830 | offsetof(struct sdpcmd_regs, clockctlstatus), | ||
831 | &retries); | ||
832 | } | ||
833 | |||
834 | /* Check current status */ | 690 | /* Check current status */ |
835 | clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, | 691 | clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, |
836 | SBSDIO_FUNC1_CHIPCLKCSR, &err); | 692 | SBSDIO_FUNC1_CHIPCLKCSR, &err); |
@@ -1034,11 +890,9 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep) | |||
1034 | SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); | 890 | SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); |
1035 | 891 | ||
1036 | /* Isolate the bus */ | 892 | /* Isolate the bus */ |
1037 | if (bus->ci->chip != BCM4329_CHIP_ID) { | 893 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, |
1038 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | 894 | SBSDIO_DEVICE_CTL, |
1039 | SBSDIO_DEVICE_CTL, | 895 | SBSDIO_DEVCTL_PADS_ISO, NULL); |
1040 | SBSDIO_DEVCTL_PADS_ISO, NULL); | ||
1041 | } | ||
1042 | 896 | ||
1043 | /* Change state */ | 897 | /* Change state */ |
1044 | bus->sleeping = true; | 898 | bus->sleeping = true; |
@@ -1049,13 +903,6 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep) | |||
1049 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | 903 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, |
1050 | SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); | 904 | SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); |
1051 | 905 | ||
1052 | /* Force pad isolation off if possible | ||
1053 | (in case power never toggled) */ | ||
1054 | if ((bus->ci->buscoretype == PCMCIA_CORE_ID) | ||
1055 | && (bus->ci->buscorerev >= 10)) | ||
1056 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | ||
1057 | SBSDIO_DEVICE_CTL, 0, NULL); | ||
1058 | |||
1059 | /* Make sure the controller has the bus up */ | 906 | /* Make sure the controller has the bus up */ |
1060 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 907 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
1061 | 908 | ||
@@ -1222,6 +1069,51 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_bus *bus, bool abort, bool rtx) | |||
1222 | bus->drvr->busstate = BRCMF_BUS_DOWN; | 1069 | bus->drvr->busstate = BRCMF_BUS_DOWN; |
1223 | } | 1070 | } |
1224 | 1071 | ||
1072 | /* copy a buffer into a pkt buffer chain */ | ||
1073 | static uint brcmf_sdbrcm_glom_from_buf(struct brcmf_bus *bus, uint len) | ||
1074 | { | ||
1075 | uint n, ret = 0; | ||
1076 | struct sk_buff *p; | ||
1077 | u8 *buf; | ||
1078 | |||
1079 | buf = bus->dataptr; | ||
1080 | |||
1081 | /* copy the data */ | ||
1082 | skb_queue_walk(&bus->glom, p) { | ||
1083 | n = min_t(uint, p->len, len); | ||
1084 | memcpy(p->data, buf, n); | ||
1085 | buf += n; | ||
1086 | len -= n; | ||
1087 | ret += n; | ||
1088 | if (!len) | ||
1089 | break; | ||
1090 | } | ||
1091 | |||
1092 | return ret; | ||
1093 | } | ||
1094 | |||
1095 | /* return total length of buffer chain */ | ||
1096 | static uint brcmf_sdbrcm_glom_len(struct brcmf_bus *bus) | ||
1097 | { | ||
1098 | struct sk_buff *p; | ||
1099 | uint total; | ||
1100 | |||
1101 | total = 0; | ||
1102 | skb_queue_walk(&bus->glom, p) | ||
1103 | total += p->len; | ||
1104 | return total; | ||
1105 | } | ||
1106 | |||
1107 | static void brcmf_sdbrcm_free_glom(struct brcmf_bus *bus) | ||
1108 | { | ||
1109 | struct sk_buff *cur, *next; | ||
1110 | |||
1111 | skb_queue_walk_safe(&bus->glom, cur, next) { | ||
1112 | skb_unlink(cur, &bus->glom); | ||
1113 | brcmu_pkt_buf_free_skb(cur); | ||
1114 | } | ||
1115 | } | ||
1116 | |||
1225 | static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | 1117 | static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) |
1226 | { | 1118 | { |
1227 | u16 dlen, totlen; | 1119 | u16 dlen, totlen; |
@@ -1240,7 +1132,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1240 | /* If packets, issue read(s) and send up packet chain */ | 1132 | /* If packets, issue read(s) and send up packet chain */ |
1241 | /* Return sequence numbers consumed? */ | 1133 | /* Return sequence numbers consumed? */ |
1242 | 1134 | ||
1243 | brcmf_dbg(TRACE, "start: glomd %p glom %p\n", bus->glomd, bus->glom); | 1135 | brcmf_dbg(TRACE, "start: glomd %p glom %p\n", |
1136 | bus->glomd, skb_peek(&bus->glom)); | ||
1244 | 1137 | ||
1245 | /* If there's a descriptor, generate the packet chain */ | 1138 | /* If there's a descriptor, generate the packet chain */ |
1246 | if (bus->glomd) { | 1139 | if (bus->glomd) { |
@@ -1287,12 +1180,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1287 | num, sublen); | 1180 | num, sublen); |
1288 | break; | 1181 | break; |
1289 | } | 1182 | } |
1290 | if (!pfirst) { | 1183 | skb_queue_tail(&bus->glom, pnext); |
1291 | pfirst = plast = pnext; | ||
1292 | } else { | ||
1293 | plast->next = pnext; | ||
1294 | plast = pnext; | ||
1295 | } | ||
1296 | 1184 | ||
1297 | /* Adhere to start alignment requirements */ | 1185 | /* Adhere to start alignment requirements */ |
1298 | pkt_align(pnext, sublen, BRCMF_SDALIGN); | 1186 | pkt_align(pnext, sublen, BRCMF_SDALIGN); |
@@ -1308,12 +1196,9 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1308 | brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n", | 1196 | brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n", |
1309 | bus->nextlen, totlen, rxseq); | 1197 | bus->nextlen, totlen, rxseq); |
1310 | } | 1198 | } |
1311 | bus->glom = pfirst; | ||
1312 | pfirst = pnext = NULL; | 1199 | pfirst = pnext = NULL; |
1313 | } else { | 1200 | } else { |
1314 | if (pfirst) | 1201 | brcmf_sdbrcm_free_glom(bus); |
1315 | brcmu_pkt_buf_free_skb(pfirst); | ||
1316 | bus->glom = NULL; | ||
1317 | num = 0; | 1202 | num = 0; |
1318 | } | 1203 | } |
1319 | 1204 | ||
@@ -1325,18 +1210,18 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1325 | 1210 | ||
1326 | /* Ok -- either we just generated a packet chain, | 1211 | /* Ok -- either we just generated a packet chain, |
1327 | or had one from before */ | 1212 | or had one from before */ |
1328 | if (bus->glom) { | 1213 | if (!skb_queue_empty(&bus->glom)) { |
1329 | if (BRCMF_GLOM_ON()) { | 1214 | if (BRCMF_GLOM_ON()) { |
1330 | brcmf_dbg(GLOM, "try superframe read, packet chain:\n"); | 1215 | brcmf_dbg(GLOM, "try superframe read, packet chain:\n"); |
1331 | for (pnext = bus->glom; pnext; pnext = pnext->next) { | 1216 | skb_queue_walk(&bus->glom, pnext) { |
1332 | brcmf_dbg(GLOM, " %p: %p len 0x%04x (%d)\n", | 1217 | brcmf_dbg(GLOM, " %p: %p len 0x%04x (%d)\n", |
1333 | pnext, (u8 *) (pnext->data), | 1218 | pnext, (u8 *) (pnext->data), |
1334 | pnext->len, pnext->len); | 1219 | pnext->len, pnext->len); |
1335 | } | 1220 | } |
1336 | } | 1221 | } |
1337 | 1222 | ||
1338 | pfirst = bus->glom; | 1223 | pfirst = skb_peek(&bus->glom); |
1339 | dlen = (u16) brcmu_pkttotlen(pfirst); | 1224 | dlen = (u16) brcmf_sdbrcm_glom_len(bus); |
1340 | 1225 | ||
1341 | /* Do an SDIO read for the superframe. Configurable iovar to | 1226 | /* Do an SDIO read for the superframe. Configurable iovar to |
1342 | * read directly into the chained packet, or allocate a large | 1227 | * read directly into the chained packet, or allocate a large |
@@ -1354,8 +1239,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1354 | SDIO_FUNC_2, | 1239 | SDIO_FUNC_2, |
1355 | F2SYNC, bus->dataptr, dlen, | 1240 | F2SYNC, bus->dataptr, dlen, |
1356 | NULL); | 1241 | NULL); |
1357 | sublen = (u16) brcmu_pktfrombuf(pfirst, 0, dlen, | 1242 | sublen = (u16) brcmf_sdbrcm_glom_from_buf(bus, dlen); |
1358 | bus->dataptr); | ||
1359 | if (sublen != dlen) { | 1243 | if (sublen != dlen) { |
1360 | brcmf_dbg(ERROR, "FAILED TO COPY, dlen %d sublen %d\n", | 1244 | brcmf_dbg(ERROR, "FAILED TO COPY, dlen %d sublen %d\n", |
1361 | dlen, sublen); | 1245 | dlen, sublen); |
@@ -1380,9 +1264,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1380 | } else { | 1264 | } else { |
1381 | bus->glomerr = 0; | 1265 | bus->glomerr = 0; |
1382 | brcmf_sdbrcm_rxfail(bus, true, false); | 1266 | brcmf_sdbrcm_rxfail(bus, true, false); |
1383 | brcmu_pkt_buf_free_skb(bus->glom); | ||
1384 | bus->rxglomfail++; | 1267 | bus->rxglomfail++; |
1385 | bus->glom = NULL; | 1268 | brcmf_sdbrcm_free_glom(bus); |
1386 | } | 1269 | } |
1387 | return 0; | 1270 | return 0; |
1388 | } | 1271 | } |
@@ -1503,9 +1386,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1503 | } else { | 1386 | } else { |
1504 | bus->glomerr = 0; | 1387 | bus->glomerr = 0; |
1505 | brcmf_sdbrcm_rxfail(bus, true, false); | 1388 | brcmf_sdbrcm_rxfail(bus, true, false); |
1506 | brcmu_pkt_buf_free_skb(bus->glom); | ||
1507 | bus->rxglomfail++; | 1389 | bus->rxglomfail++; |
1508 | bus->glom = NULL; | 1390 | brcmf_sdbrcm_free_glom(bus); |
1509 | } | 1391 | } |
1510 | bus->nextlen = 0; | 1392 | bus->nextlen = 0; |
1511 | return 0; | 1393 | return 0; |
@@ -1513,7 +1395,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) | |||
1513 | 1395 | ||
1514 | /* Basic SD framing looks ok - process each packet (header) */ | 1396 | /* Basic SD framing looks ok - process each packet (header) */ |
1515 | save_pfirst = pfirst; | 1397 | save_pfirst = pfirst; |
1516 | bus->glom = NULL; | ||
1517 | plast = NULL; | 1398 | plast = NULL; |
1518 | 1399 | ||
1519 | for (num = 0; pfirst; rxseq++, pfirst = pnext) { | 1400 | for (num = 0; pfirst; rxseq++, pfirst = pnext) { |
@@ -1850,10 +1731,10 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) | |||
1850 | rxseq++, rxleft--) { | 1731 | rxseq++, rxleft--) { |
1851 | 1732 | ||
1852 | /* Handle glomming separately */ | 1733 | /* Handle glomming separately */ |
1853 | if (bus->glom || bus->glomd) { | 1734 | if (bus->glomd || !skb_queue_empty(&bus->glom)) { |
1854 | u8 cnt; | 1735 | u8 cnt; |
1855 | brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n", | 1736 | brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n", |
1856 | bus->glomd, bus->glom); | 1737 | bus->glomd, skb_peek(&bus->glom)); |
1857 | cnt = brcmf_sdbrcm_rxglom(bus, rxseq); | 1738 | cnt = brcmf_sdbrcm_rxglom(bus, rxseq); |
1858 | brcmf_dbg(GLOM, "rxglom returned %d\n", cnt); | 1739 | brcmf_dbg(GLOM, "rxglom returned %d\n", cnt); |
1859 | rxseq += cnt - 1; | 1740 | rxseq += cnt - 1; |
@@ -3210,135 +3091,11 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_bus *bus) | |||
3210 | return bcmerror; | 3091 | return bcmerror; |
3211 | } | 3092 | } |
3212 | 3093 | ||
3213 | static void | ||
3214 | brcmf_sdbrcm_chip_disablecore(struct brcmf_sdio_dev *sdiodev, u32 corebase) | ||
3215 | { | ||
3216 | u32 regdata; | ||
3217 | |||
3218 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3219 | CORE_SB(corebase, sbtmstatelow), 4); | ||
3220 | if (regdata & SBTML_RESET) | ||
3221 | return; | ||
3222 | |||
3223 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3224 | CORE_SB(corebase, sbtmstatelow), 4); | ||
3225 | if ((regdata & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) != 0) { | ||
3226 | /* | ||
3227 | * set target reject and spin until busy is clear | ||
3228 | * (preserve core-specific bits) | ||
3229 | */ | ||
3230 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3231 | CORE_SB(corebase, sbtmstatelow), 4); | ||
3232 | brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), | ||
3233 | 4, regdata | SBTML_REJ); | ||
3234 | |||
3235 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3236 | CORE_SB(corebase, sbtmstatelow), 4); | ||
3237 | udelay(1); | ||
3238 | SPINWAIT((brcmf_sdcard_reg_read(sdiodev, | ||
3239 | CORE_SB(corebase, sbtmstatehigh), 4) & | ||
3240 | SBTMH_BUSY), 100000); | ||
3241 | |||
3242 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3243 | CORE_SB(corebase, sbtmstatehigh), 4); | ||
3244 | if (regdata & SBTMH_BUSY) | ||
3245 | brcmf_dbg(ERROR, "ARM core still busy\n"); | ||
3246 | |||
3247 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3248 | CORE_SB(corebase, sbidlow), 4); | ||
3249 | if (regdata & SBIDL_INIT) { | ||
3250 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3251 | CORE_SB(corebase, sbimstate), 4) | | ||
3252 | SBIM_RJ; | ||
3253 | brcmf_sdcard_reg_write(sdiodev, | ||
3254 | CORE_SB(corebase, sbimstate), 4, | ||
3255 | regdata); | ||
3256 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3257 | CORE_SB(corebase, sbimstate), 4); | ||
3258 | udelay(1); | ||
3259 | SPINWAIT((brcmf_sdcard_reg_read(sdiodev, | ||
3260 | CORE_SB(corebase, sbimstate), 4) & | ||
3261 | SBIM_BY), 100000); | ||
3262 | } | ||
3263 | |||
3264 | /* set reset and reject while enabling the clocks */ | ||
3265 | brcmf_sdcard_reg_write(sdiodev, | ||
3266 | CORE_SB(corebase, sbtmstatelow), 4, | ||
3267 | (((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | | ||
3268 | SBTML_REJ | SBTML_RESET)); | ||
3269 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3270 | CORE_SB(corebase, sbtmstatelow), 4); | ||
3271 | udelay(10); | ||
3272 | |||
3273 | /* clear the initiator reject bit */ | ||
3274 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3275 | CORE_SB(corebase, sbidlow), 4); | ||
3276 | if (regdata & SBIDL_INIT) { | ||
3277 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3278 | CORE_SB(corebase, sbimstate), 4) & | ||
3279 | ~SBIM_RJ; | ||
3280 | brcmf_sdcard_reg_write(sdiodev, | ||
3281 | CORE_SB(corebase, sbimstate), 4, | ||
3282 | regdata); | ||
3283 | } | ||
3284 | } | ||
3285 | |||
3286 | /* leave reset and reject asserted */ | ||
3287 | brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4, | ||
3288 | (SBTML_REJ | SBTML_RESET)); | ||
3289 | udelay(1); | ||
3290 | } | ||
3291 | |||
3292 | static void | ||
3293 | brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_dev *sdiodev, u32 corebase) | ||
3294 | { | ||
3295 | u32 regdata; | ||
3296 | |||
3297 | /* | ||
3298 | * Must do the disable sequence first to work for | ||
3299 | * arbitrary current core state. | ||
3300 | */ | ||
3301 | brcmf_sdbrcm_chip_disablecore(sdiodev, corebase); | ||
3302 | |||
3303 | /* | ||
3304 | * Now do the initialization sequence. | ||
3305 | * set reset while enabling the clock and | ||
3306 | * forcing them on throughout the core | ||
3307 | */ | ||
3308 | brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4, | ||
3309 | ((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | | ||
3310 | SBTML_RESET); | ||
3311 | udelay(1); | ||
3312 | |||
3313 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3314 | CORE_SB(corebase, sbtmstatehigh), 4); | ||
3315 | if (regdata & SBTMH_SERR) | ||
3316 | brcmf_sdcard_reg_write(sdiodev, | ||
3317 | CORE_SB(corebase, sbtmstatehigh), 4, 0); | ||
3318 | |||
3319 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
3320 | CORE_SB(corebase, sbimstate), 4); | ||
3321 | if (regdata & (SBIM_IBE | SBIM_TO)) | ||
3322 | brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbimstate), 4, | ||
3323 | regdata & ~(SBIM_IBE | SBIM_TO)); | ||
3324 | |||
3325 | /* clear reset and allow it to propagate throughout the core */ | ||
3326 | brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4, | ||
3327 | (SICF_FGC << SBTML_SICF_SHIFT) | | ||
3328 | (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); | ||
3329 | udelay(1); | ||
3330 | |||
3331 | /* leave clock enabled */ | ||
3332 | brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4, | ||
3333 | (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); | ||
3334 | udelay(1); | ||
3335 | } | ||
3336 | |||
3337 | static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) | 3094 | static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) |
3338 | { | 3095 | { |
3339 | uint retries; | 3096 | uint retries; |
3340 | u32 regdata; | ||
3341 | int bcmerror = 0; | 3097 | int bcmerror = 0; |
3098 | struct chip_info *ci = bus->ci; | ||
3342 | 3099 | ||
3343 | /* To enter download state, disable ARM and reset SOCRAM. | 3100 | /* To enter download state, disable ARM and reset SOCRAM. |
3344 | * To exit download state, simply reset ARM (default is RAM boot). | 3101 | * To exit download state, simply reset ARM (default is RAM boot). |
@@ -3346,10 +3103,9 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) | |||
3346 | if (enter) { | 3103 | if (enter) { |
3347 | bus->alp_only = true; | 3104 | bus->alp_only = true; |
3348 | 3105 | ||
3349 | brcmf_sdbrcm_chip_disablecore(bus->sdiodev, | 3106 | ci->coredisable(bus->sdiodev, ci, BCMA_CORE_ARM_CM3); |
3350 | bus->ci->armcorebase); | ||
3351 | 3107 | ||
3352 | brcmf_sdbrcm_chip_resetcore(bus->sdiodev, bus->ci->ramcorebase); | 3108 | ci->resetcore(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM); |
3353 | 3109 | ||
3354 | /* Clear the top bit of memory */ | 3110 | /* Clear the top bit of memory */ |
3355 | if (bus->ramsize) { | 3111 | if (bus->ramsize) { |
@@ -3358,11 +3114,7 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) | |||
3358 | (u8 *)&zeros, 4); | 3114 | (u8 *)&zeros, 4); |
3359 | } | 3115 | } |
3360 | } else { | 3116 | } else { |
3361 | regdata = brcmf_sdcard_reg_read(bus->sdiodev, | 3117 | if (!ci->iscoreup(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) { |
3362 | CORE_SB(bus->ci->ramcorebase, sbtmstatelow), 4); | ||
3363 | regdata &= (SBTML_RESET | SBTML_REJ_MASK | | ||
3364 | (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); | ||
3365 | if ((SICF_CLOCK_EN << SBTML_SICF_SHIFT) != regdata) { | ||
3366 | brcmf_dbg(ERROR, "SOCRAM core is down after reset?\n"); | 3118 | brcmf_dbg(ERROR, "SOCRAM core is down after reset?\n"); |
3367 | bcmerror = -EBADE; | 3119 | bcmerror = -EBADE; |
3368 | goto fail; | 3120 | goto fail; |
@@ -3377,7 +3129,7 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) | |||
3377 | w_sdreg32(bus, 0xFFFFFFFF, | 3129 | w_sdreg32(bus, 0xFFFFFFFF, |
3378 | offsetof(struct sdpcmd_regs, intstatus), &retries); | 3130 | offsetof(struct sdpcmd_regs, intstatus), &retries); |
3379 | 3131 | ||
3380 | brcmf_sdbrcm_chip_resetcore(bus->sdiodev, bus->ci->armcorebase); | 3132 | ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3); |
3381 | 3133 | ||
3382 | /* Allow HT Clock now that the ARM is running. */ | 3134 | /* Allow HT Clock now that the ARM is running. */ |
3383 | bus->alp_only = false; | 3135 | bus->alp_only = false; |
@@ -3661,11 +3413,7 @@ void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus) | |||
3661 | /* Clear any held glomming stuff */ | 3413 | /* Clear any held glomming stuff */ |
3662 | if (bus->glomd) | 3414 | if (bus->glomd) |
3663 | brcmu_pkt_buf_free_skb(bus->glomd); | 3415 | brcmu_pkt_buf_free_skb(bus->glomd); |
3664 | 3416 | brcmf_sdbrcm_free_glom(bus); | |
3665 | if (bus->glom) | ||
3666 | brcmu_pkt_buf_free_skb(bus->glom); | ||
3667 | |||
3668 | bus->glom = bus->glomd = NULL; | ||
3669 | 3417 | ||
3670 | /* Clear rx control and wake any waiters */ | 3418 | /* Clear rx control and wake any waiters */ |
3671 | bus->rxlen = 0; | 3419 | bus->rxlen = 0; |
@@ -3950,269 +3698,6 @@ fail: | |||
3950 | return false; | 3698 | return false; |
3951 | } | 3699 | } |
3952 | 3700 | ||
3953 | /* SDIO Pad drive strength to select value mappings */ | ||
3954 | struct sdiod_drive_str { | ||
3955 | u8 strength; /* Pad Drive Strength in mA */ | ||
3956 | u8 sel; /* Chip-specific select value */ | ||
3957 | }; | ||
3958 | |||
3959 | /* SDIO Drive Strength to sel value table for PMU Rev 1 */ | ||
3960 | static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = { | ||
3961 | { | ||
3962 | 4, 0x2}, { | ||
3963 | 2, 0x3}, { | ||
3964 | 1, 0x0}, { | ||
3965 | 0, 0x0} | ||
3966 | }; | ||
3967 | |||
3968 | /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ | ||
3969 | static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = { | ||
3970 | { | ||
3971 | 12, 0x7}, { | ||
3972 | 10, 0x6}, { | ||
3973 | 8, 0x5}, { | ||
3974 | 6, 0x4}, { | ||
3975 | 4, 0x2}, { | ||
3976 | 2, 0x1}, { | ||
3977 | 0, 0x0} | ||
3978 | }; | ||
3979 | |||
3980 | /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */ | ||
3981 | static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = { | ||
3982 | { | ||
3983 | 32, 0x7}, { | ||
3984 | 26, 0x6}, { | ||
3985 | 22, 0x5}, { | ||
3986 | 16, 0x4}, { | ||
3987 | 12, 0x3}, { | ||
3988 | 8, 0x2}, { | ||
3989 | 4, 0x1}, { | ||
3990 | 0, 0x0} | ||
3991 | }; | ||
3992 | |||
3993 | #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) | ||
3994 | |||
3995 | static char *brcmf_chipname(uint chipid, char *buf, uint len) | ||
3996 | { | ||
3997 | const char *fmt; | ||
3998 | |||
3999 | fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x"; | ||
4000 | snprintf(buf, len, fmt, chipid); | ||
4001 | return buf; | ||
4002 | } | ||
4003 | |||
4004 | static void brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus, | ||
4005 | u32 drivestrength) { | ||
4006 | struct sdiod_drive_str *str_tab = NULL; | ||
4007 | u32 str_mask = 0; | ||
4008 | u32 str_shift = 0; | ||
4009 | char chn[8]; | ||
4010 | |||
4011 | if (!(bus->ci->cccaps & CC_CAP_PMU)) | ||
4012 | return; | ||
4013 | |||
4014 | switch (SDIOD_DRVSTR_KEY(bus->ci->chip, bus->ci->pmurev)) { | ||
4015 | case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1): | ||
4016 | str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1; | ||
4017 | str_mask = 0x30000000; | ||
4018 | str_shift = 28; | ||
4019 | break; | ||
4020 | case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2): | ||
4021 | case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3): | ||
4022 | str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2; | ||
4023 | str_mask = 0x00003800; | ||
4024 | str_shift = 11; | ||
4025 | break; | ||
4026 | case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8): | ||
4027 | str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3; | ||
4028 | str_mask = 0x00003800; | ||
4029 | str_shift = 11; | ||
4030 | break; | ||
4031 | default: | ||
4032 | brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", | ||
4033 | brcmf_chipname(bus->ci->chip, chn, 8), | ||
4034 | bus->ci->chiprev, bus->ci->pmurev); | ||
4035 | break; | ||
4036 | } | ||
4037 | |||
4038 | if (str_tab != NULL) { | ||
4039 | u32 drivestrength_sel = 0; | ||
4040 | u32 cc_data_temp; | ||
4041 | int i; | ||
4042 | |||
4043 | for (i = 0; str_tab[i].strength != 0; i++) { | ||
4044 | if (drivestrength >= str_tab[i].strength) { | ||
4045 | drivestrength_sel = str_tab[i].sel; | ||
4046 | break; | ||
4047 | } | ||
4048 | } | ||
4049 | |||
4050 | brcmf_sdcard_reg_write(bus->sdiodev, | ||
4051 | CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), | ||
4052 | 4, 1); | ||
4053 | cc_data_temp = brcmf_sdcard_reg_read(bus->sdiodev, | ||
4054 | CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4); | ||
4055 | cc_data_temp &= ~str_mask; | ||
4056 | drivestrength_sel <<= str_shift; | ||
4057 | cc_data_temp |= drivestrength_sel; | ||
4058 | brcmf_sdcard_reg_write(bus->sdiodev, | ||
4059 | CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), | ||
4060 | 4, cc_data_temp); | ||
4061 | |||
4062 | brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n", | ||
4063 | drivestrength, cc_data_temp); | ||
4064 | } | ||
4065 | } | ||
4066 | |||
4067 | static int | ||
4068 | brcmf_sdbrcm_chip_recognition(struct brcmf_sdio_dev *sdiodev, | ||
4069 | struct chip_info *ci, u32 regs) | ||
4070 | { | ||
4071 | u32 regdata; | ||
4072 | |||
4073 | /* | ||
4074 | * Get CC core rev | ||
4075 | * Chipid is assume to be at offset 0 from regs arg | ||
4076 | * For different chiptypes or old sdio hosts w/o chipcommon, | ||
4077 | * other ways of recognition should be added here. | ||
4078 | */ | ||
4079 | ci->cccorebase = regs; | ||
4080 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
4081 | CORE_CC_REG(ci->cccorebase, chipid), 4); | ||
4082 | ci->chip = regdata & CID_ID_MASK; | ||
4083 | ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; | ||
4084 | |||
4085 | brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev); | ||
4086 | |||
4087 | /* Address of cores for new chips should be added here */ | ||
4088 | switch (ci->chip) { | ||
4089 | case BCM4329_CHIP_ID: | ||
4090 | ci->buscorebase = BCM4329_CORE_BUS_BASE; | ||
4091 | ci->ramcorebase = BCM4329_CORE_SOCRAM_BASE; | ||
4092 | ci->armcorebase = BCM4329_CORE_ARM_BASE; | ||
4093 | ci->ramsize = BCM4329_RAMSIZE; | ||
4094 | break; | ||
4095 | default: | ||
4096 | brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip); | ||
4097 | return -ENODEV; | ||
4098 | } | ||
4099 | |||
4100 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
4101 | CORE_SB(ci->cccorebase, sbidhigh), 4); | ||
4102 | ci->ccrev = SBCOREREV(regdata); | ||
4103 | |||
4104 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
4105 | CORE_CC_REG(ci->cccorebase, pmucapabilities), 4); | ||
4106 | ci->pmurev = regdata & PCAP_REV_MASK; | ||
4107 | |||
4108 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
4109 | CORE_SB(ci->buscorebase, sbidhigh), 4); | ||
4110 | ci->buscorerev = SBCOREREV(regdata); | ||
4111 | ci->buscoretype = (regdata & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT; | ||
4112 | |||
4113 | brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n", | ||
4114 | ci->ccrev, ci->pmurev, ci->buscorerev, ci->buscoretype); | ||
4115 | |||
4116 | /* get chipcommon capabilites */ | ||
4117 | ci->cccaps = brcmf_sdcard_reg_read(sdiodev, | ||
4118 | CORE_CC_REG(ci->cccorebase, capabilities), 4); | ||
4119 | |||
4120 | return 0; | ||
4121 | } | ||
4122 | |||
4123 | static int | ||
4124 | brcmf_sdbrcm_chip_attach(struct brcmf_bus *bus, u32 regs) | ||
4125 | { | ||
4126 | struct chip_info *ci; | ||
4127 | int err; | ||
4128 | u8 clkval, clkset; | ||
4129 | |||
4130 | brcmf_dbg(TRACE, "Enter\n"); | ||
4131 | |||
4132 | /* alloc chip_info_t */ | ||
4133 | ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC); | ||
4134 | if (NULL == ci) | ||
4135 | return -ENOMEM; | ||
4136 | |||
4137 | /* bus/core/clk setup for register access */ | ||
4138 | /* Try forcing SDIO core to do ALPAvail request only */ | ||
4139 | clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; | ||
4140 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | ||
4141 | SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); | ||
4142 | if (err) { | ||
4143 | brcmf_dbg(ERROR, "error writing for HT off\n"); | ||
4144 | goto fail; | ||
4145 | } | ||
4146 | |||
4147 | /* If register supported, wait for ALPAvail and then force ALP */ | ||
4148 | /* This may take up to 15 milliseconds */ | ||
4149 | clkval = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, | ||
4150 | SBSDIO_FUNC1_CHIPCLKCSR, NULL); | ||
4151 | if ((clkval & ~SBSDIO_AVBITS) == clkset) { | ||
4152 | SPINWAIT(((clkval = | ||
4153 | brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, | ||
4154 | SBSDIO_FUNC1_CHIPCLKCSR, | ||
4155 | NULL)), | ||
4156 | !SBSDIO_ALPAV(clkval)), | ||
4157 | PMU_MAX_TRANSITION_DLY); | ||
4158 | if (!SBSDIO_ALPAV(clkval)) { | ||
4159 | brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n", | ||
4160 | clkval); | ||
4161 | err = -EBUSY; | ||
4162 | goto fail; | ||
4163 | } | ||
4164 | clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | | ||
4165 | SBSDIO_FORCE_ALP; | ||
4166 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | ||
4167 | SBSDIO_FUNC1_CHIPCLKCSR, | ||
4168 | clkset, &err); | ||
4169 | udelay(65); | ||
4170 | } else { | ||
4171 | brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n", | ||
4172 | clkset, clkval); | ||
4173 | err = -EACCES; | ||
4174 | goto fail; | ||
4175 | } | ||
4176 | |||
4177 | /* Also, disable the extra SDIO pull-ups */ | ||
4178 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | ||
4179 | SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); | ||
4180 | |||
4181 | err = brcmf_sdbrcm_chip_recognition(bus->sdiodev, ci, regs); | ||
4182 | if (err) | ||
4183 | goto fail; | ||
4184 | |||
4185 | /* | ||
4186 | * Make sure any on-chip ARM is off (in case strapping is wrong), | ||
4187 | * or downloaded code was already running. | ||
4188 | */ | ||
4189 | brcmf_sdbrcm_chip_disablecore(bus->sdiodev, ci->armcorebase); | ||
4190 | |||
4191 | brcmf_sdcard_reg_write(bus->sdiodev, | ||
4192 | CORE_CC_REG(ci->cccorebase, gpiopullup), 4, 0); | ||
4193 | brcmf_sdcard_reg_write(bus->sdiodev, | ||
4194 | CORE_CC_REG(ci->cccorebase, gpiopulldown), 4, 0); | ||
4195 | |||
4196 | /* Disable F2 to clear any intermediate frame state on the dongle */ | ||
4197 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, | ||
4198 | SDIO_FUNC_ENABLE_1, NULL); | ||
4199 | |||
4200 | /* WAR: cmd52 backplane read so core HW will drop ALPReq */ | ||
4201 | clkval = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, | ||
4202 | 0, NULL); | ||
4203 | |||
4204 | /* Done with backplane-dependent accesses, can drop clock... */ | ||
4205 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | ||
4206 | SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); | ||
4207 | |||
4208 | bus->ci = ci; | ||
4209 | return 0; | ||
4210 | fail: | ||
4211 | bus->ci = NULL; | ||
4212 | kfree(ci); | ||
4213 | return err; | ||
4214 | } | ||
4215 | |||
4216 | static bool | 3701 | static bool |
4217 | brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) | 3702 | brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) |
4218 | { | 3703 | { |
@@ -4220,6 +3705,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) | |||
4220 | int err = 0; | 3705 | int err = 0; |
4221 | int reg_addr; | 3706 | int reg_addr; |
4222 | u32 reg_val; | 3707 | u32 reg_val; |
3708 | u8 idx; | ||
4223 | 3709 | ||
4224 | bus->alp_only = true; | 3710 | bus->alp_only = true; |
4225 | 3711 | ||
@@ -4234,7 +3720,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) | |||
4234 | #endif /* BCMDBG */ | 3720 | #endif /* BCMDBG */ |
4235 | 3721 | ||
4236 | /* | 3722 | /* |
4237 | * Force PLL off until brcmf_sdbrcm_chip_attach() | 3723 | * Force PLL off until brcmf_sdio_chip_attach() |
4238 | * programs PLL control regs | 3724 | * programs PLL control regs |
4239 | */ | 3725 | */ |
4240 | 3726 | ||
@@ -4252,8 +3738,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) | |||
4252 | goto fail; | 3738 | goto fail; |
4253 | } | 3739 | } |
4254 | 3740 | ||
4255 | if (brcmf_sdbrcm_chip_attach(bus, regsva)) { | 3741 | if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci, regsva)) { |
4256 | brcmf_dbg(ERROR, "brcmf_sdbrcm_chip_attach failed!\n"); | 3742 | brcmf_dbg(ERROR, "brcmf_sdio_chip_attach failed!\n"); |
4257 | goto fail; | 3743 | goto fail; |
4258 | } | 3744 | } |
4259 | 3745 | ||
@@ -4262,11 +3748,10 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) | |||
4262 | goto fail; | 3748 | goto fail; |
4263 | } | 3749 | } |
4264 | 3750 | ||
4265 | brcmf_sdbrcm_sdiod_drive_strength_init(bus, SDIO_DRIVE_STRENGTH); | 3751 | brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci, |
3752 | SDIO_DRIVE_STRENGTH); | ||
4266 | 3753 | ||
4267 | /* Get info on the ARM and SOCRAM cores... */ | 3754 | /* Get info on the SOCRAM cores... */ |
4268 | brcmf_sdcard_reg_read(bus->sdiodev, | ||
4269 | CORE_SB(bus->ci->armcorebase, sbidhigh), 4); | ||
4270 | bus->ramsize = bus->ci->ramsize; | 3755 | bus->ramsize = bus->ci->ramsize; |
4271 | if (!(bus->ramsize)) { | 3756 | if (!(bus->ramsize)) { |
4272 | brcmf_dbg(ERROR, "failed to find SOCRAM memory!\n"); | 3757 | brcmf_dbg(ERROR, "failed to find SOCRAM memory!\n"); |
@@ -4274,7 +3759,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) | |||
4274 | } | 3759 | } |
4275 | 3760 | ||
4276 | /* Set core control so an SDIO reset does a backplane reset */ | 3761 | /* Set core control so an SDIO reset does a backplane reset */ |
4277 | reg_addr = bus->ci->buscorebase + | 3762 | idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); |
3763 | reg_addr = bus->ci->c_inf[idx].base + | ||
4278 | offsetof(struct sdpcmd_regs, corecontrol); | 3764 | offsetof(struct sdpcmd_regs, corecontrol); |
4279 | reg_val = brcmf_sdcard_reg_read(bus->sdiodev, reg_addr, sizeof(u32)); | 3765 | reg_val = brcmf_sdcard_reg_read(bus->sdiodev, reg_addr, sizeof(u32)); |
4280 | brcmf_sdcard_reg_write(bus->sdiodev, reg_addr, sizeof(u32), | 3766 | brcmf_sdcard_reg_write(bus->sdiodev, reg_addr, sizeof(u32), |
@@ -4364,15 +3850,6 @@ brcmf_sdbrcm_watchdog(unsigned long data) | |||
4364 | } | 3850 | } |
4365 | } | 3851 | } |
4366 | 3852 | ||
4367 | static void | ||
4368 | brcmf_sdbrcm_chip_detach(struct brcmf_bus *bus) | ||
4369 | { | ||
4370 | brcmf_dbg(TRACE, "Enter\n"); | ||
4371 | |||
4372 | kfree(bus->ci); | ||
4373 | bus->ci = NULL; | ||
4374 | } | ||
4375 | |||
4376 | static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus) | 3853 | static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus) |
4377 | { | 3854 | { |
4378 | brcmf_dbg(TRACE, "Enter\n"); | 3855 | brcmf_dbg(TRACE, "Enter\n"); |
@@ -4380,7 +3857,7 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus) | |||
4380 | if (bus->ci) { | 3857 | if (bus->ci) { |
4381 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 3858 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
4382 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); | 3859 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); |
4383 | brcmf_sdbrcm_chip_detach(bus); | 3860 | brcmf_sdio_chip_detach(&bus->ci); |
4384 | if (bus->vars && bus->varsz) | 3861 | if (bus->vars && bus->varsz) |
4385 | kfree(bus->vars); | 3862 | kfree(bus->vars); |
4386 | bus->vars = NULL; | 3863 | bus->vars = NULL; |
@@ -4440,6 +3917,7 @@ void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype, | |||
4440 | 3917 | ||
4441 | bus->sdiodev = sdiodev; | 3918 | bus->sdiodev = sdiodev; |
4442 | sdiodev->bus = bus; | 3919 | sdiodev->bus = bus; |
3920 | skb_queue_head_init(&bus->glom); | ||
4443 | bus->txbound = BRCMF_TXBOUND; | 3921 | bus->txbound = BRCMF_TXBOUND; |
4444 | bus->rxbound = BRCMF_RXBOUND; | 3922 | bus->rxbound = BRCMF_RXBOUND; |
4445 | bus->txminmax = BRCMF_TXMINMAX; | 3923 | bus->txminmax = BRCMF_TXMINMAX; |
@@ -4521,9 +3999,10 @@ void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype, | |||
4521 | goto fail; | 3999 | goto fail; |
4522 | } | 4000 | } |
4523 | } | 4001 | } |
4524 | /* Ok, have the per-port tell the stack we're open for business */ | 4002 | |
4525 | if (brcmf_net_attach(bus->drvr, 0) != 0) { | 4003 | /* add interface and open for business */ |
4526 | brcmf_dbg(ERROR, "Net attach failed!!\n"); | 4004 | if (brcmf_add_if((struct brcmf_info *)bus->drvr, 0, "wlan%d", NULL)) { |
4005 | brcmf_dbg(ERROR, "Add primary net device interface failed!!\n"); | ||
4527 | goto fail; | 4006 | goto fail; |
4528 | } | 4007 | } |
4529 | 4008 | ||
@@ -4554,10 +4033,6 @@ struct device *brcmf_bus_get_device(struct brcmf_bus *bus) | |||
4554 | void | 4033 | void |
4555 | brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick) | 4034 | brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick) |
4556 | { | 4035 | { |
4557 | /* don't start the wd until fw is loaded */ | ||
4558 | if (bus->drvr->busstate == BRCMF_BUS_DOWN) | ||
4559 | return; | ||
4560 | |||
4561 | /* Totally stop the timer */ | 4036 | /* Totally stop the timer */ |
4562 | if (!wdtick && bus->wd_timer_valid == true) { | 4037 | if (!wdtick && bus->wd_timer_valid == true) { |
4563 | del_timer_sync(&bus->timer); | 4038 | del_timer_sync(&bus->timer); |
@@ -4566,6 +4041,10 @@ brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick) | |||
4566 | return; | 4041 | return; |
4567 | } | 4042 | } |
4568 | 4043 | ||
4044 | /* don't start the wd until fw is loaded */ | ||
4045 | if (bus->drvr->busstate == BRCMF_BUS_DOWN) | ||
4046 | return; | ||
4047 | |||
4569 | if (wdtick) { | 4048 | if (wdtick) { |
4570 | if (bus->save_ms != BRCMF_WD_POLL_MS) { | 4049 | if (bus->save_ms != BRCMF_WD_POLL_MS) { |
4571 | if (bus->wd_timer_valid == true) | 4050 | if (bus->wd_timer_valid == true) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c new file mode 100644 index 000000000000..f6b1822031fe --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | |||
@@ -0,0 +1,622 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Broadcom Corporation | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | /* ***** SDIO interface chip backplane handle functions ***** */ | ||
17 | |||
18 | #include <linux/types.h> | ||
19 | #include <linux/netdevice.h> | ||
20 | #include <linux/mmc/card.h> | ||
21 | #include <linux/ssb/ssb_regs.h> | ||
22 | #include <linux/bcma/bcma.h> | ||
23 | |||
24 | #include <chipcommon.h> | ||
25 | #include <brcm_hw_ids.h> | ||
26 | #include <brcmu_wifi.h> | ||
27 | #include <brcmu_utils.h> | ||
28 | #include <soc.h> | ||
29 | #include "dhd.h" | ||
30 | #include "dhd_dbg.h" | ||
31 | #include "sdio_host.h" | ||
32 | #include "sdio_chip.h" | ||
33 | |||
34 | /* chip core base & ramsize */ | ||
35 | /* bcm4329 */ | ||
36 | /* SDIO device core, ID 0x829 */ | ||
37 | #define BCM4329_CORE_BUS_BASE 0x18011000 | ||
38 | /* internal memory core, ID 0x80e */ | ||
39 | #define BCM4329_CORE_SOCRAM_BASE 0x18003000 | ||
40 | /* ARM Cortex M3 core, ID 0x82a */ | ||
41 | #define BCM4329_CORE_ARM_BASE 0x18002000 | ||
42 | #define BCM4329_RAMSIZE 0x48000 | ||
43 | |||
44 | #define SBCOREREV(sbidh) \ | ||
45 | ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \ | ||
46 | ((sbidh) & SSB_IDHIGH_RCLO)) | ||
47 | |||
48 | /* SOC Interconnect types (aka chip types) */ | ||
49 | #define SOCI_SB 0 | ||
50 | #define SOCI_AI 1 | ||
51 | |||
52 | /* EROM CompIdentB */ | ||
53 | #define CIB_REV_MASK 0xff000000 | ||
54 | #define CIB_REV_SHIFT 24 | ||
55 | |||
56 | #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) | ||
57 | /* SDIO Pad drive strength to select value mappings */ | ||
58 | struct sdiod_drive_str { | ||
59 | u8 strength; /* Pad Drive Strength in mA */ | ||
60 | u8 sel; /* Chip-specific select value */ | ||
61 | }; | ||
62 | /* SDIO Drive Strength to sel value table for PMU Rev 1 */ | ||
63 | static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = { | ||
64 | { | ||
65 | 4, 0x2}, { | ||
66 | 2, 0x3}, { | ||
67 | 1, 0x0}, { | ||
68 | 0, 0x0} | ||
69 | }; | ||
70 | /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */ | ||
71 | static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = { | ||
72 | { | ||
73 | 12, 0x7}, { | ||
74 | 10, 0x6}, { | ||
75 | 8, 0x5}, { | ||
76 | 6, 0x4}, { | ||
77 | 4, 0x2}, { | ||
78 | 2, 0x1}, { | ||
79 | 0, 0x0} | ||
80 | }; | ||
81 | /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */ | ||
82 | static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = { | ||
83 | { | ||
84 | 32, 0x7}, { | ||
85 | 26, 0x6}, { | ||
86 | 22, 0x5}, { | ||
87 | 16, 0x4}, { | ||
88 | 12, 0x3}, { | ||
89 | 8, 0x2}, { | ||
90 | 4, 0x1}, { | ||
91 | 0, 0x0} | ||
92 | }; | ||
93 | |||
94 | u8 | ||
95 | brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid) | ||
96 | { | ||
97 | u8 idx; | ||
98 | |||
99 | for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++) | ||
100 | if (coreid == ci->c_inf[idx].id) | ||
101 | return idx; | ||
102 | |||
103 | return BRCMF_MAX_CORENUM; | ||
104 | } | ||
105 | |||
106 | static u32 | ||
107 | brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev, | ||
108 | struct chip_info *ci, u16 coreid) | ||
109 | { | ||
110 | u32 regdata; | ||
111 | u8 idx; | ||
112 | |||
113 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
114 | |||
115 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
116 | CORE_SB(ci->c_inf[idx].base, sbidhigh), 4); | ||
117 | return SBCOREREV(regdata); | ||
118 | } | ||
119 | |||
120 | static u32 | ||
121 | brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev, | ||
122 | struct chip_info *ci, u16 coreid) | ||
123 | { | ||
124 | u8 idx; | ||
125 | |||
126 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
127 | |||
128 | return (ci->c_inf[idx].cib & CIB_REV_MASK) >> CIB_REV_SHIFT; | ||
129 | } | ||
130 | |||
131 | static bool | ||
132 | brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev, | ||
133 | struct chip_info *ci, u16 coreid) | ||
134 | { | ||
135 | u32 regdata; | ||
136 | u8 idx; | ||
137 | |||
138 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
139 | |||
140 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
141 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
142 | regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT | | ||
143 | SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK); | ||
144 | return (SSB_TMSLOW_CLOCK == regdata); | ||
145 | } | ||
146 | |||
147 | static bool | ||
148 | brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, | ||
149 | struct chip_info *ci, u16 coreid) | ||
150 | { | ||
151 | u32 regdata; | ||
152 | u8 idx; | ||
153 | bool ret; | ||
154 | |||
155 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
156 | |||
157 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
158 | ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); | ||
159 | ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK; | ||
160 | |||
161 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
162 | ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | ||
163 | 4); | ||
164 | ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0); | ||
165 | |||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | static void | ||
170 | brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, | ||
171 | struct chip_info *ci, u16 coreid) | ||
172 | { | ||
173 | u32 regdata; | ||
174 | u8 idx; | ||
175 | |||
176 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
177 | |||
178 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
179 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
180 | if (regdata & SSB_TMSLOW_RESET) | ||
181 | return; | ||
182 | |||
183 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
184 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
185 | if ((regdata & SSB_TMSLOW_CLOCK) != 0) { | ||
186 | /* | ||
187 | * set target reject and spin until busy is clear | ||
188 | * (preserve core-specific bits) | ||
189 | */ | ||
190 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
191 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
192 | brcmf_sdcard_reg_write(sdiodev, | ||
193 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), | ||
194 | 4, regdata | SSB_TMSLOW_REJECT); | ||
195 | |||
196 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
197 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
198 | udelay(1); | ||
199 | SPINWAIT((brcmf_sdcard_reg_read(sdiodev, | ||
200 | CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4) & | ||
201 | SSB_TMSHIGH_BUSY), 100000); | ||
202 | |||
203 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
204 | CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4); | ||
205 | if (regdata & SSB_TMSHIGH_BUSY) | ||
206 | brcmf_dbg(ERROR, "core state still busy\n"); | ||
207 | |||
208 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
209 | CORE_SB(ci->c_inf[idx].base, sbidlow), 4); | ||
210 | if (regdata & SSB_IDLOW_INITIATOR) { | ||
211 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
212 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4) | | ||
213 | SSB_IMSTATE_REJECT; | ||
214 | brcmf_sdcard_reg_write(sdiodev, | ||
215 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4, | ||
216 | regdata); | ||
217 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
218 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4); | ||
219 | udelay(1); | ||
220 | SPINWAIT((brcmf_sdcard_reg_read(sdiodev, | ||
221 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4) & | ||
222 | SSB_IMSTATE_BUSY), 100000); | ||
223 | } | ||
224 | |||
225 | /* set reset and reject while enabling the clocks */ | ||
226 | brcmf_sdcard_reg_write(sdiodev, | ||
227 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, | ||
228 | (SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | | ||
229 | SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET)); | ||
230 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
231 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
232 | udelay(10); | ||
233 | |||
234 | /* clear the initiator reject bit */ | ||
235 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
236 | CORE_SB(ci->c_inf[idx].base, sbidlow), 4); | ||
237 | if (regdata & SSB_IDLOW_INITIATOR) { | ||
238 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
239 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4) & | ||
240 | ~SSB_IMSTATE_REJECT; | ||
241 | brcmf_sdcard_reg_write(sdiodev, | ||
242 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4, | ||
243 | regdata); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | /* leave reset and reject asserted */ | ||
248 | brcmf_sdcard_reg_write(sdiodev, | ||
249 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, | ||
250 | (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET)); | ||
251 | udelay(1); | ||
252 | } | ||
253 | |||
254 | static void | ||
255 | brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, | ||
256 | struct chip_info *ci, u16 coreid) | ||
257 | { | ||
258 | u8 idx; | ||
259 | u32 regdata; | ||
260 | |||
261 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
262 | |||
263 | /* if core is already in reset, just return */ | ||
264 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
265 | ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | ||
266 | 4); | ||
267 | if ((regdata & BCMA_RESET_CTL_RESET) != 0) | ||
268 | return; | ||
269 | |||
270 | brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | ||
271 | 4, 0); | ||
272 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
273 | ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); | ||
274 | udelay(10); | ||
275 | |||
276 | brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | ||
277 | 4, BCMA_RESET_CTL_RESET); | ||
278 | udelay(1); | ||
279 | } | ||
280 | |||
281 | static void | ||
282 | brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, | ||
283 | struct chip_info *ci, u16 coreid) | ||
284 | { | ||
285 | u32 regdata; | ||
286 | u8 idx; | ||
287 | |||
288 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
289 | |||
290 | /* | ||
291 | * Must do the disable sequence first to work for | ||
292 | * arbitrary current core state. | ||
293 | */ | ||
294 | brcmf_sdio_sb_coredisable(sdiodev, ci, coreid); | ||
295 | |||
296 | /* | ||
297 | * Now do the initialization sequence. | ||
298 | * set reset while enabling the clock and | ||
299 | * forcing them on throughout the core | ||
300 | */ | ||
301 | brcmf_sdcard_reg_write(sdiodev, | ||
302 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, | ||
303 | SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET); | ||
304 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
305 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
306 | udelay(1); | ||
307 | |||
308 | /* clear any serror */ | ||
309 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
310 | CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4); | ||
311 | if (regdata & SSB_TMSHIGH_SERR) | ||
312 | brcmf_sdcard_reg_write(sdiodev, | ||
313 | CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4, 0); | ||
314 | |||
315 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
316 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4); | ||
317 | if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) | ||
318 | brcmf_sdcard_reg_write(sdiodev, | ||
319 | CORE_SB(ci->c_inf[idx].base, sbimstate), 4, | ||
320 | regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO)); | ||
321 | |||
322 | /* clear reset and allow it to propagate throughout the core */ | ||
323 | brcmf_sdcard_reg_write(sdiodev, | ||
324 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4, | ||
325 | SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK); | ||
326 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
327 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
328 | udelay(1); | ||
329 | |||
330 | /* leave clock enabled */ | ||
331 | brcmf_sdcard_reg_write(sdiodev, | ||
332 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), | ||
333 | 4, SSB_TMSLOW_CLOCK); | ||
334 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
335 | CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4); | ||
336 | udelay(1); | ||
337 | } | ||
338 | |||
339 | static void | ||
340 | brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, | ||
341 | struct chip_info *ci, u16 coreid) | ||
342 | { | ||
343 | u8 idx; | ||
344 | u32 regdata; | ||
345 | |||
346 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | ||
347 | |||
348 | /* must disable first to work for arbitrary current core state */ | ||
349 | brcmf_sdio_ai_coredisable(sdiodev, ci, coreid); | ||
350 | |||
351 | /* now do initialization sequence */ | ||
352 | brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | ||
353 | 4, BCMA_IOCTL_FGC | BCMA_IOCTL_CLK); | ||
354 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
355 | ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); | ||
356 | brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | ||
357 | 4, 0); | ||
358 | udelay(1); | ||
359 | |||
360 | brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | ||
361 | 4, BCMA_IOCTL_CLK); | ||
362 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
363 | ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4); | ||
364 | udelay(1); | ||
365 | } | ||
366 | |||
367 | static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | ||
368 | struct chip_info *ci, u32 regs) | ||
369 | { | ||
370 | u32 regdata; | ||
371 | |||
372 | /* | ||
373 | * Get CC core rev | ||
374 | * Chipid is assume to be at offset 0 from regs arg | ||
375 | * For different chiptypes or old sdio hosts w/o chipcommon, | ||
376 | * other ways of recognition should be added here. | ||
377 | */ | ||
378 | ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON; | ||
379 | ci->c_inf[0].base = regs; | ||
380 | regdata = brcmf_sdcard_reg_read(sdiodev, | ||
381 | CORE_CC_REG(ci->c_inf[0].base, chipid), 4); | ||
382 | ci->chip = regdata & CID_ID_MASK; | ||
383 | ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; | ||
384 | ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT; | ||
385 | |||
386 | brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev); | ||
387 | |||
388 | /* Address of cores for new chips should be added here */ | ||
389 | switch (ci->chip) { | ||
390 | case BCM4329_CHIP_ID: | ||
391 | ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; | ||
392 | ci->c_inf[1].base = BCM4329_CORE_BUS_BASE; | ||
393 | ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; | ||
394 | ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE; | ||
395 | ci->c_inf[3].id = BCMA_CORE_ARM_CM3; | ||
396 | ci->c_inf[3].base = BCM4329_CORE_ARM_BASE; | ||
397 | ci->ramsize = BCM4329_RAMSIZE; | ||
398 | break; | ||
399 | default: | ||
400 | brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip); | ||
401 | return -ENODEV; | ||
402 | } | ||
403 | |||
404 | switch (ci->socitype) { | ||
405 | case SOCI_SB: | ||
406 | ci->iscoreup = brcmf_sdio_sb_iscoreup; | ||
407 | ci->corerev = brcmf_sdio_sb_corerev; | ||
408 | ci->coredisable = brcmf_sdio_sb_coredisable; | ||
409 | ci->resetcore = brcmf_sdio_sb_resetcore; | ||
410 | break; | ||
411 | case SOCI_AI: | ||
412 | ci->iscoreup = brcmf_sdio_ai_iscoreup; | ||
413 | ci->corerev = brcmf_sdio_ai_corerev; | ||
414 | ci->coredisable = brcmf_sdio_ai_coredisable; | ||
415 | ci->resetcore = brcmf_sdio_ai_resetcore; | ||
416 | break; | ||
417 | default: | ||
418 | brcmf_dbg(ERROR, "socitype %u not supported\n", ci->socitype); | ||
419 | return -ENODEV; | ||
420 | } | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | static int | ||
426 | brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev) | ||
427 | { | ||
428 | int err = 0; | ||
429 | u8 clkval, clkset; | ||
430 | |||
431 | /* Try forcing SDIO core to do ALPAvail request only */ | ||
432 | clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; | ||
433 | brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, | ||
434 | SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); | ||
435 | if (err) { | ||
436 | brcmf_dbg(ERROR, "error writing for HT off\n"); | ||
437 | return err; | ||
438 | } | ||
439 | |||
440 | /* If register supported, wait for ALPAvail and then force ALP */ | ||
441 | /* This may take up to 15 milliseconds */ | ||
442 | clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1, | ||
443 | SBSDIO_FUNC1_CHIPCLKCSR, NULL); | ||
444 | |||
445 | if ((clkval & ~SBSDIO_AVBITS) != clkset) { | ||
446 | brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n", | ||
447 | clkset, clkval); | ||
448 | return -EACCES; | ||
449 | } | ||
450 | |||
451 | SPINWAIT(((clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1, | ||
452 | SBSDIO_FUNC1_CHIPCLKCSR, NULL)), | ||
453 | !SBSDIO_ALPAV(clkval)), | ||
454 | PMU_MAX_TRANSITION_DLY); | ||
455 | if (!SBSDIO_ALPAV(clkval)) { | ||
456 | brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n", | ||
457 | clkval); | ||
458 | return -EBUSY; | ||
459 | } | ||
460 | |||
461 | clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; | ||
462 | brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, | ||
463 | SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); | ||
464 | udelay(65); | ||
465 | |||
466 | /* Also, disable the extra SDIO pull-ups */ | ||
467 | brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, | ||
468 | SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | static void | ||
474 | brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, | ||
475 | struct chip_info *ci) | ||
476 | { | ||
477 | /* get chipcommon rev */ | ||
478 | ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id); | ||
479 | |||
480 | /* get chipcommon capabilites */ | ||
481 | ci->c_inf[0].caps = | ||
482 | brcmf_sdcard_reg_read(sdiodev, | ||
483 | CORE_CC_REG(ci->c_inf[0].base, capabilities), 4); | ||
484 | |||
485 | /* get pmu caps & rev */ | ||
486 | if (ci->c_inf[0].caps & CC_CAP_PMU) { | ||
487 | ci->pmucaps = brcmf_sdcard_reg_read(sdiodev, | ||
488 | CORE_CC_REG(ci->c_inf[0].base, pmucapabilities), 4); | ||
489 | ci->pmurev = ci->pmucaps & PCAP_REV_MASK; | ||
490 | } | ||
491 | |||
492 | ci->c_inf[1].rev = ci->corerev(sdiodev, ci, ci->c_inf[1].id); | ||
493 | |||
494 | brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n", | ||
495 | ci->c_inf[0].rev, ci->pmurev, | ||
496 | ci->c_inf[1].rev, ci->c_inf[1].id); | ||
497 | |||
498 | /* | ||
499 | * Make sure any on-chip ARM is off (in case strapping is wrong), | ||
500 | * or downloaded code was already running. | ||
501 | */ | ||
502 | ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3); | ||
503 | } | ||
504 | |||
505 | int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, | ||
506 | struct chip_info **ci_ptr, u32 regs) | ||
507 | { | ||
508 | int ret; | ||
509 | struct chip_info *ci; | ||
510 | |||
511 | brcmf_dbg(TRACE, "Enter\n"); | ||
512 | |||
513 | /* alloc chip_info_t */ | ||
514 | ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC); | ||
515 | if (!ci) | ||
516 | return -ENOMEM; | ||
517 | |||
518 | ret = brcmf_sdio_chip_buscoreprep(sdiodev); | ||
519 | if (ret != 0) | ||
520 | goto err; | ||
521 | |||
522 | ret = brcmf_sdio_chip_recognition(sdiodev, ci, regs); | ||
523 | if (ret != 0) | ||
524 | goto err; | ||
525 | |||
526 | brcmf_sdio_chip_buscoresetup(sdiodev, ci); | ||
527 | |||
528 | brcmf_sdcard_reg_write(sdiodev, | ||
529 | CORE_CC_REG(ci->c_inf[0].base, gpiopullup), 4, 0); | ||
530 | brcmf_sdcard_reg_write(sdiodev, | ||
531 | CORE_CC_REG(ci->c_inf[0].base, gpiopulldown), 4, 0); | ||
532 | |||
533 | *ci_ptr = ci; | ||
534 | return 0; | ||
535 | |||
536 | err: | ||
537 | kfree(ci); | ||
538 | return ret; | ||
539 | } | ||
540 | |||
541 | void | ||
542 | brcmf_sdio_chip_detach(struct chip_info **ci_ptr) | ||
543 | { | ||
544 | brcmf_dbg(TRACE, "Enter\n"); | ||
545 | |||
546 | kfree(*ci_ptr); | ||
547 | *ci_ptr = NULL; | ||
548 | } | ||
549 | |||
550 | static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len) | ||
551 | { | ||
552 | const char *fmt; | ||
553 | |||
554 | fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x"; | ||
555 | snprintf(buf, len, fmt, chipid); | ||
556 | return buf; | ||
557 | } | ||
558 | |||
559 | void | ||
560 | brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, | ||
561 | struct chip_info *ci, u32 drivestrength) | ||
562 | { | ||
563 | struct sdiod_drive_str *str_tab = NULL; | ||
564 | u32 str_mask = 0; | ||
565 | u32 str_shift = 0; | ||
566 | char chn[8]; | ||
567 | |||
568 | if (!(ci->c_inf[0].caps & CC_CAP_PMU)) | ||
569 | return; | ||
570 | |||
571 | switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) { | ||
572 | case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1): | ||
573 | str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1; | ||
574 | str_mask = 0x30000000; | ||
575 | str_shift = 28; | ||
576 | break; | ||
577 | case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2): | ||
578 | case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3): | ||
579 | str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2; | ||
580 | str_mask = 0x00003800; | ||
581 | str_shift = 11; | ||
582 | break; | ||
583 | case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8): | ||
584 | str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3; | ||
585 | str_mask = 0x00003800; | ||
586 | str_shift = 11; | ||
587 | break; | ||
588 | default: | ||
589 | brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", | ||
590 | brcmf_sdio_chip_name(ci->chip, chn, 8), | ||
591 | ci->chiprev, ci->pmurev); | ||
592 | break; | ||
593 | } | ||
594 | |||
595 | if (str_tab != NULL) { | ||
596 | u32 drivestrength_sel = 0; | ||
597 | u32 cc_data_temp; | ||
598 | int i; | ||
599 | |||
600 | for (i = 0; str_tab[i].strength != 0; i++) { | ||
601 | if (drivestrength >= str_tab[i].strength) { | ||
602 | drivestrength_sel = str_tab[i].sel; | ||
603 | break; | ||
604 | } | ||
605 | } | ||
606 | |||
607 | brcmf_sdcard_reg_write(sdiodev, | ||
608 | CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), | ||
609 | 4, 1); | ||
610 | cc_data_temp = brcmf_sdcard_reg_read(sdiodev, | ||
611 | CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), 4); | ||
612 | cc_data_temp &= ~str_mask; | ||
613 | drivestrength_sel <<= str_shift; | ||
614 | cc_data_temp |= drivestrength_sel; | ||
615 | brcmf_sdcard_reg_write(sdiodev, | ||
616 | CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), | ||
617 | 4, cc_data_temp); | ||
618 | |||
619 | brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n", | ||
620 | drivestrength, cc_data_temp); | ||
621 | } | ||
622 | } | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h new file mode 100644 index 000000000000..ce974d76bd92 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Broadcom Corporation | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef _BRCMFMAC_SDIO_CHIP_H_ | ||
18 | #define _BRCMFMAC_SDIO_CHIP_H_ | ||
19 | |||
20 | /* | ||
21 | * Core reg address translation. | ||
22 | * Both macro's returns a 32 bits byte address on the backplane bus. | ||
23 | */ | ||
24 | #define CORE_CC_REG(base, field) \ | ||
25 | (base + offsetof(struct chipcregs, field)) | ||
26 | #define CORE_BUS_REG(base, field) \ | ||
27 | (base + offsetof(struct sdpcmd_regs, field)) | ||
28 | #define CORE_SB(base, field) \ | ||
29 | (base + SBCONFIGOFF + offsetof(struct sbconfig, field)) | ||
30 | |||
31 | /* SDIO function 1 register CHIPCLKCSR */ | ||
32 | /* Force ALP request to backplane */ | ||
33 | #define SBSDIO_FORCE_ALP 0x01 | ||
34 | /* Force HT request to backplane */ | ||
35 | #define SBSDIO_FORCE_HT 0x02 | ||
36 | /* Force ILP request to backplane */ | ||
37 | #define SBSDIO_FORCE_ILP 0x04 | ||
38 | /* Make ALP ready (power up xtal) */ | ||
39 | #define SBSDIO_ALP_AVAIL_REQ 0x08 | ||
40 | /* Make HT ready (power up PLL) */ | ||
41 | #define SBSDIO_HT_AVAIL_REQ 0x10 | ||
42 | /* Squelch clock requests from HW */ | ||
43 | #define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 | ||
44 | /* Status: ALP is ready */ | ||
45 | #define SBSDIO_ALP_AVAIL 0x40 | ||
46 | /* Status: HT is ready */ | ||
47 | #define SBSDIO_HT_AVAIL 0x80 | ||
48 | #define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) | ||
49 | #define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) | ||
50 | #define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS) | ||
51 | #define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval)) | ||
52 | #define SBSDIO_CLKAV(regval, alponly) \ | ||
53 | (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval))) | ||
54 | |||
55 | #define BRCMF_MAX_CORENUM 6 | ||
56 | |||
57 | struct chip_core_info { | ||
58 | u16 id; | ||
59 | u16 rev; | ||
60 | u32 base; | ||
61 | u32 wrapbase; | ||
62 | u32 caps; | ||
63 | u32 cib; | ||
64 | }; | ||
65 | |||
66 | struct chip_info { | ||
67 | u32 chip; | ||
68 | u32 chiprev; | ||
69 | u32 socitype; | ||
70 | /* core info */ | ||
71 | /* always put chipcommon core at 0, bus core at 1 */ | ||
72 | struct chip_core_info c_inf[BRCMF_MAX_CORENUM]; | ||
73 | u32 pmurev; | ||
74 | u32 pmucaps; | ||
75 | u32 ramsize; | ||
76 | |||
77 | bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | ||
78 | u16 coreid); | ||
79 | u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | ||
80 | u16 coreid); | ||
81 | void (*coredisable)(struct brcmf_sdio_dev *sdiodev, | ||
82 | struct chip_info *ci, u16 coreid); | ||
83 | void (*resetcore)(struct brcmf_sdio_dev *sdiodev, | ||
84 | struct chip_info *ci, u16 coreid); | ||
85 | }; | ||
86 | |||
87 | struct sbconfig { | ||
88 | u32 PAD[2]; | ||
89 | u32 sbipsflag; /* initiator port ocp slave flag */ | ||
90 | u32 PAD[3]; | ||
91 | u32 sbtpsflag; /* target port ocp slave flag */ | ||
92 | u32 PAD[11]; | ||
93 | u32 sbtmerrloga; /* (sonics >= 2.3) */ | ||
94 | u32 PAD; | ||
95 | u32 sbtmerrlog; /* (sonics >= 2.3) */ | ||
96 | u32 PAD[3]; | ||
97 | u32 sbadmatch3; /* address match3 */ | ||
98 | u32 PAD; | ||
99 | u32 sbadmatch2; /* address match2 */ | ||
100 | u32 PAD; | ||
101 | u32 sbadmatch1; /* address match1 */ | ||
102 | u32 PAD[7]; | ||
103 | u32 sbimstate; /* initiator agent state */ | ||
104 | u32 sbintvec; /* interrupt mask */ | ||
105 | u32 sbtmstatelow; /* target state */ | ||
106 | u32 sbtmstatehigh; /* target state */ | ||
107 | u32 sbbwa0; /* bandwidth allocation table0 */ | ||
108 | u32 PAD; | ||
109 | u32 sbimconfiglow; /* initiator configuration */ | ||
110 | u32 sbimconfighigh; /* initiator configuration */ | ||
111 | u32 sbadmatch0; /* address match0 */ | ||
112 | u32 PAD; | ||
113 | u32 sbtmconfiglow; /* target configuration */ | ||
114 | u32 sbtmconfighigh; /* target configuration */ | ||
115 | u32 sbbconfig; /* broadcast configuration */ | ||
116 | u32 PAD; | ||
117 | u32 sbbstate; /* broadcast state */ | ||
118 | u32 PAD[3]; | ||
119 | u32 sbactcnfg; /* activate configuration */ | ||
120 | u32 PAD[3]; | ||
121 | u32 sbflagst; /* current sbflags */ | ||
122 | u32 PAD[3]; | ||
123 | u32 sbidlow; /* identification */ | ||
124 | u32 sbidhigh; /* identification */ | ||
125 | }; | ||
126 | |||
127 | extern int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, | ||
128 | struct chip_info **ci_ptr, u32 regs); | ||
129 | extern void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); | ||
130 | extern void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, | ||
131 | struct chip_info *ci, | ||
132 | u32 drivestrength); | ||
133 | extern u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); | ||
134 | |||
135 | |||
136 | #endif /* _BRCMFMAC_SDIO_CHIP_H_ */ | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 5eddabe5228a..cc19a733ac65 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -1997,7 +1997,7 @@ done: | |||
1997 | } | 1997 | } |
1998 | 1998 | ||
1999 | static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, | 1999 | static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, |
2000 | struct brcmf_bss_info *bi) | 2000 | struct brcmf_bss_info_le *bi) |
2001 | { | 2001 | { |
2002 | struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); | 2002 | struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); |
2003 | struct ieee80211_channel *notify_channel; | 2003 | struct ieee80211_channel *notify_channel; |
@@ -2049,18 +2049,27 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2049 | notify_timestamp, notify_capability, notify_interval, notify_ie, | 2049 | notify_timestamp, notify_capability, notify_interval, notify_ie, |
2050 | notify_ielen, notify_signal, GFP_KERNEL); | 2050 | notify_ielen, notify_signal, GFP_KERNEL); |
2051 | 2051 | ||
2052 | if (!bss) { | 2052 | if (!bss) |
2053 | WL_ERR("cfg80211_inform_bss_frame error\n"); | 2053 | return -ENOMEM; |
2054 | return -EINVAL; | 2054 | |
2055 | } | 2055 | cfg80211_put_bss(bss); |
2056 | 2056 | ||
2057 | return err; | 2057 | return err; |
2058 | } | 2058 | } |
2059 | 2059 | ||
2060 | static struct brcmf_bss_info_le * | ||
2061 | next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss) | ||
2062 | { | ||
2063 | if (bss == NULL) | ||
2064 | return list->bss_info_le; | ||
2065 | return (struct brcmf_bss_info_le *)((unsigned long)bss + | ||
2066 | le32_to_cpu(bss->length)); | ||
2067 | } | ||
2068 | |||
2060 | static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv) | 2069 | static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv) |
2061 | { | 2070 | { |
2062 | struct brcmf_scan_results *bss_list; | 2071 | struct brcmf_scan_results *bss_list; |
2063 | struct brcmf_bss_info *bi = NULL; /* must be initialized */ | 2072 | struct brcmf_bss_info_le *bi = NULL; /* must be initialized */ |
2064 | s32 err = 0; | 2073 | s32 err = 0; |
2065 | int i; | 2074 | int i; |
2066 | 2075 | ||
@@ -2072,7 +2081,7 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv) | |||
2072 | } | 2081 | } |
2073 | WL_SCAN("scanned AP count (%d)\n", bss_list->count); | 2082 | WL_SCAN("scanned AP count (%d)\n", bss_list->count); |
2074 | for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) { | 2083 | for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) { |
2075 | bi = next_bss(bss_list, bi); | 2084 | bi = next_bss_le(bss_list, bi); |
2076 | err = brcmf_inform_single_bss(cfg_priv, bi); | 2085 | err = brcmf_inform_single_bss(cfg_priv, bi); |
2077 | if (err) | 2086 | if (err) |
2078 | break; | 2087 | break; |
@@ -2085,8 +2094,9 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2085 | { | 2094 | { |
2086 | struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); | 2095 | struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); |
2087 | struct ieee80211_channel *notify_channel; | 2096 | struct ieee80211_channel *notify_channel; |
2088 | struct brcmf_bss_info *bi = NULL; | 2097 | struct brcmf_bss_info_le *bi = NULL; |
2089 | struct ieee80211_supported_band *band; | 2098 | struct ieee80211_supported_band *band; |
2099 | struct cfg80211_bss *bss; | ||
2090 | u8 *buf = NULL; | 2100 | u8 *buf = NULL; |
2091 | s32 err = 0; | 2101 | s32 err = 0; |
2092 | u16 channel; | 2102 | u16 channel; |
@@ -2114,7 +2124,7 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2114 | goto CleanUp; | 2124 | goto CleanUp; |
2115 | } | 2125 | } |
2116 | 2126 | ||
2117 | bi = (struct brcmf_bss_info *)(buf + 4); | 2127 | bi = (struct brcmf_bss_info_le *)(buf + 4); |
2118 | 2128 | ||
2119 | channel = bi->ctl_ch ? bi->ctl_ch : | 2129 | channel = bi->ctl_ch ? bi->ctl_ch : |
2120 | CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); | 2130 | CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); |
@@ -2140,10 +2150,17 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2140 | WL_CONN("signal: %d\n", notify_signal); | 2150 | WL_CONN("signal: %d\n", notify_signal); |
2141 | WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); | 2151 | WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); |
2142 | 2152 | ||
2143 | cfg80211_inform_bss(wiphy, notify_channel, bssid, | 2153 | bss = cfg80211_inform_bss(wiphy, notify_channel, bssid, |
2144 | notify_timestamp, notify_capability, notify_interval, | 2154 | notify_timestamp, notify_capability, notify_interval, |
2145 | notify_ie, notify_ielen, notify_signal, GFP_KERNEL); | 2155 | notify_ie, notify_ielen, notify_signal, GFP_KERNEL); |
2146 | 2156 | ||
2157 | if (!bss) { | ||
2158 | err = -ENOMEM; | ||
2159 | goto CleanUp; | ||
2160 | } | ||
2161 | |||
2162 | cfg80211_put_bss(bss); | ||
2163 | |||
2147 | CleanUp: | 2164 | CleanUp: |
2148 | 2165 | ||
2149 | kfree(buf); | 2166 | kfree(buf); |
@@ -2188,7 +2205,7 @@ static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key) | |||
2188 | 2205 | ||
2189 | static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv) | 2206 | static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv) |
2190 | { | 2207 | { |
2191 | struct brcmf_bss_info *bi; | 2208 | struct brcmf_bss_info_le *bi; |
2192 | struct brcmf_ssid *ssid; | 2209 | struct brcmf_ssid *ssid; |
2193 | struct brcmf_tlv *tim; | 2210 | struct brcmf_tlv *tim; |
2194 | u16 beacon_interval; | 2211 | u16 beacon_interval; |
@@ -2211,7 +2228,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv) | |||
2211 | goto update_bss_info_out; | 2228 | goto update_bss_info_out; |
2212 | } | 2229 | } |
2213 | 2230 | ||
2214 | bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4); | 2231 | bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4); |
2215 | err = brcmf_inform_single_bss(cfg_priv, bi); | 2232 | err = brcmf_inform_single_bss(cfg_priv, bi); |
2216 | if (err) | 2233 | if (err) |
2217 | goto update_bss_info_out; | 2234 | goto update_bss_info_out; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index 62dc46144ede..a613b49cb13f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | |||
@@ -352,15 +352,6 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_priv *cfg) | |||
352 | return &cfg->conn_info; | 352 | return &cfg->conn_info; |
353 | } | 353 | } |
354 | 354 | ||
355 | static inline struct brcmf_bss_info *next_bss(struct brcmf_scan_results *list, | ||
356 | struct brcmf_bss_info *bss) | ||
357 | { | ||
358 | return bss = bss ? | ||
359 | (struct brcmf_bss_info *)((unsigned long)bss + | ||
360 | le32_to_cpu(bss->length)) : | ||
361 | list->bss_info; | ||
362 | } | ||
363 | |||
364 | extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev, | 355 | extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev, |
365 | struct device *busdev, | 356 | struct device *busdev, |
366 | void *data); | 357 | void *data); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h index 106a7424a7cd..b51d1e421e24 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h | |||
@@ -38,88 +38,12 @@ | |||
38 | /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */ | 38 | /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */ |
39 | #define SI_PCIE_DMA_H32 0x80000000 | 39 | #define SI_PCIE_DMA_H32 0x80000000 |
40 | 40 | ||
41 | /* core codes */ | ||
42 | #define NODEV_CORE_ID 0x700 /* Invalid coreid */ | ||
43 | #define CC_CORE_ID 0x800 /* chipcommon core */ | ||
44 | #define ILINE20_CORE_ID 0x801 /* iline20 core */ | ||
45 | #define SRAM_CORE_ID 0x802 /* sram core */ | ||
46 | #define SDRAM_CORE_ID 0x803 /* sdram core */ | ||
47 | #define PCI_CORE_ID 0x804 /* pci core */ | ||
48 | #define MIPS_CORE_ID 0x805 /* mips core */ | ||
49 | #define ENET_CORE_ID 0x806 /* enet mac core */ | ||
50 | #define CODEC_CORE_ID 0x807 /* v90 codec core */ | ||
51 | #define USB_CORE_ID 0x808 /* usb 1.1 host/device core */ | ||
52 | #define ADSL_CORE_ID 0x809 /* ADSL core */ | ||
53 | #define ILINE100_CORE_ID 0x80a /* iline100 core */ | ||
54 | #define IPSEC_CORE_ID 0x80b /* ipsec core */ | ||
55 | #define UTOPIA_CORE_ID 0x80c /* utopia core */ | ||
56 | #define PCMCIA_CORE_ID 0x80d /* pcmcia core */ | ||
57 | #define SOCRAM_CORE_ID 0x80e /* internal memory core */ | ||
58 | #define MEMC_CORE_ID 0x80f /* memc sdram core */ | ||
59 | #define OFDM_CORE_ID 0x810 /* OFDM phy core */ | ||
60 | #define EXTIF_CORE_ID 0x811 /* external interface core */ | ||
61 | #define D11_CORE_ID 0x812 /* 802.11 MAC core */ | ||
62 | #define APHY_CORE_ID 0x813 /* 802.11a phy core */ | ||
63 | #define BPHY_CORE_ID 0x814 /* 802.11b phy core */ | ||
64 | #define GPHY_CORE_ID 0x815 /* 802.11g phy core */ | ||
65 | #define MIPS33_CORE_ID 0x816 /* mips3302 core */ | ||
66 | #define USB11H_CORE_ID 0x817 /* usb 1.1 host core */ | ||
67 | #define USB11D_CORE_ID 0x818 /* usb 1.1 device core */ | ||
68 | #define USB20H_CORE_ID 0x819 /* usb 2.0 host core */ | ||
69 | #define USB20D_CORE_ID 0x81a /* usb 2.0 device core */ | ||
70 | #define SDIOH_CORE_ID 0x81b /* sdio host core */ | ||
71 | #define ROBO_CORE_ID 0x81c /* roboswitch core */ | ||
72 | #define ATA100_CORE_ID 0x81d /* parallel ATA core */ | ||
73 | #define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */ | ||
74 | #define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */ | ||
75 | #define PCIE_CORE_ID 0x820 /* pci express core */ | ||
76 | #define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */ | ||
77 | #define SRAMC_CORE_ID 0x822 /* SRAM controller core */ | ||
78 | #define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */ | ||
79 | #define ARM11_CORE_ID 0x824 /* ARM 1176 core */ | ||
80 | #define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */ | ||
81 | #define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */ | ||
82 | #define PMU_CORE_ID 0x827 /* PMU core */ | ||
83 | #define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */ | ||
84 | #define SDIOD_CORE_ID 0x829 /* SDIO device core */ | ||
85 | #define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */ | ||
86 | #define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */ | ||
87 | #define MIPS74K_CORE_ID 0x82c /* mips 74k core */ | ||
88 | #define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ | ||
89 | #define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */ | ||
90 | #define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */ | ||
91 | #define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */ | ||
92 | #define SC_CORE_ID 0x831 /* shared common core */ | ||
93 | #define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */ | ||
94 | #define SPIH_CORE_ID 0x833 /* SPI host core */ | ||
95 | #define I2S_CORE_ID 0x834 /* I2S core */ | ||
96 | #define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ | ||
97 | #define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ | ||
98 | #define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ | ||
99 | #define DEF_AI_COMP 0xfff /* Default component, in ai chips it | ||
100 | * maps all unused address ranges | ||
101 | */ | ||
102 | |||
103 | /* chipcommon being the first core: */ | 41 | /* chipcommon being the first core: */ |
104 | #define SI_CC_IDX 0 | 42 | #define SI_CC_IDX 0 |
105 | 43 | ||
106 | /* SOC Interconnect types (aka chip types) */ | 44 | /* SOC Interconnect types (aka chip types) */ |
107 | #define SOCI_AI 1 | 45 | #define SOCI_AI 1 |
108 | 46 | ||
109 | /* Common core control flags */ | ||
110 | #define SICF_BIST_EN 0x8000 | ||
111 | #define SICF_PME_EN 0x4000 | ||
112 | #define SICF_CORE_BITS 0x3ffc | ||
113 | #define SICF_FGC 0x0002 | ||
114 | #define SICF_CLOCK_EN 0x0001 | ||
115 | |||
116 | /* Common core status flags */ | ||
117 | #define SISF_BIST_DONE 0x8000 | ||
118 | #define SISF_BIST_ERROR 0x4000 | ||
119 | #define SISF_GATED_CLK 0x2000 | ||
120 | #define SISF_DMA64 0x1000 | ||
121 | #define SISF_CORE_BITS 0x0fff | ||
122 | |||
123 | /* A register that is common to all cores to | 47 | /* A register that is common to all cores to |
124 | * communicate w/PMU regarding clock control. | 48 | * communicate w/PMU regarding clock control. |
125 | */ | 49 | */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index 7f27dbdb6b60..43f7a724dda8 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | |||
@@ -649,7 +649,7 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, | |||
649 | len = roundup(len, 4); | 649 | len = roundup(len, 4); |
650 | ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); | 650 | ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); |
651 | 651 | ||
652 | dma_len += (u16) brcmu_pkttotlen(p); | 652 | dma_len += (u16) p->len; |
653 | 653 | ||
654 | BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d" | 654 | BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d" |
655 | " seg_cnt %d null delim %d\n", | 655 | " seg_cnt %d null delim %d\n", |
@@ -741,9 +741,7 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, | |||
741 | if (p) { | 741 | if (p) { |
742 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && | 742 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && |
743 | ((u8) (p->priority) == tid)) { | 743 | ((u8) (p->priority) == tid)) { |
744 | 744 | plen = p->len + AMPDU_MAX_MPDU_OVERHEAD; | |
745 | plen = brcmu_pkttotlen(p) + | ||
746 | AMPDU_MAX_MPDU_OVERHEAD; | ||
747 | plen = max(scb_ampdu->min_len, plen); | 745 | plen = max(scb_ampdu->min_len, plen); |
748 | 746 | ||
749 | if ((plen + ampdu_len) > max_ampdu_bytes) { | 747 | if ((plen + ampdu_len) > max_ampdu_bytes) { |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 89ad1b7dab8f..55e9f45fce22 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c | |||
@@ -1153,121 +1153,6 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, | |||
1153 | &txpwr); | 1153 | &txpwr); |
1154 | } | 1154 | } |
1155 | 1155 | ||
1156 | #ifdef POWER_DBG | ||
1157 | static void wlc_phy_txpower_limits_dump(struct txpwr_limits *txpwr) | ||
1158 | { | ||
1159 | int i; | ||
1160 | char buf[80]; | ||
1161 | char fraction[4][4] = { " ", ".25", ".5 ", ".75" }; | ||
1162 | |||
1163 | sprintf(buf, "CCK "); | ||
1164 | for (i = 0; i < BRCMS_NUM_RATES_CCK; i++) | ||
1165 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1166 | txpwr->cck[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1167 | fraction[txpwr->cck[i] % BRCMS_TXPWR_DB_FACTOR]); | ||
1168 | printk(KERN_DEBUG "%s\n", buf); | ||
1169 | |||
1170 | sprintf(buf, "20 MHz OFDM SISO "); | ||
1171 | for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) | ||
1172 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1173 | txpwr->ofdm[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1174 | fraction[txpwr->ofdm[i] % BRCMS_TXPWR_DB_FACTOR]); | ||
1175 | printk(KERN_DEBUG "%s\n", buf); | ||
1176 | |||
1177 | sprintf(buf, "20 MHz OFDM CDD "); | ||
1178 | for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) | ||
1179 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1180 | txpwr->ofdm_cdd[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1181 | fraction[txpwr->ofdm_cdd[i] % BRCMS_TXPWR_DB_FACTOR]); | ||
1182 | printk(KERN_DEBUG "%s\n", buf); | ||
1183 | |||
1184 | sprintf(buf, "40 MHz OFDM SISO "); | ||
1185 | for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) | ||
1186 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1187 | txpwr->ofdm_40_siso[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1188 | fraction[txpwr->ofdm_40_siso[i] % | ||
1189 | BRCMS_TXPWR_DB_FACTOR]); | ||
1190 | printk(KERN_DEBUG "%s\n", buf); | ||
1191 | |||
1192 | sprintf(buf, "40 MHz OFDM CDD "); | ||
1193 | for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) | ||
1194 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1195 | txpwr->ofdm_40_cdd[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1196 | fraction[txpwr->ofdm_40_cdd[i] % | ||
1197 | BRCMS_TXPWR_DB_FACTOR]); | ||
1198 | printk(KERN_DEBUG "%s\n", buf); | ||
1199 | |||
1200 | sprintf(buf, "20 MHz MCS0-7 SISO "); | ||
1201 | for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) | ||
1202 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1203 | txpwr->mcs_20_siso[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1204 | fraction[txpwr->mcs_20_siso[i] % | ||
1205 | BRCMS_TXPWR_DB_FACTOR]); | ||
1206 | printk(KERN_DEBUG "%s\n", buf); | ||
1207 | |||
1208 | sprintf(buf, "20 MHz MCS0-7 CDD "); | ||
1209 | for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) | ||
1210 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1211 | txpwr->mcs_20_cdd[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1212 | fraction[txpwr->mcs_20_cdd[i] % | ||
1213 | BRCMS_TXPWR_DB_FACTOR]); | ||
1214 | printk(KERN_DEBUG "%s\n", buf); | ||
1215 | |||
1216 | sprintf(buf, "20 MHz MCS0-7 STBC "); | ||
1217 | for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) | ||
1218 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1219 | txpwr->mcs_20_stbc[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1220 | fraction[txpwr->mcs_20_stbc[i] % | ||
1221 | BRCMS_TXPWR_DB_FACTOR]); | ||
1222 | printk(KERN_DEBUG "%s\n", buf); | ||
1223 | |||
1224 | sprintf(buf, "20 MHz MCS8-15 SDM "); | ||
1225 | for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) | ||
1226 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1227 | txpwr->mcs_20_mimo[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1228 | fraction[txpwr->mcs_20_mimo[i] % | ||
1229 | BRCMS_TXPWR_DB_FACTOR]); | ||
1230 | printk(KERN_DEBUG "%s\n", buf); | ||
1231 | |||
1232 | sprintf(buf, "40 MHz MCS0-7 SISO "); | ||
1233 | for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) | ||
1234 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1235 | txpwr->mcs_40_siso[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1236 | fraction[txpwr->mcs_40_siso[i] % | ||
1237 | BRCMS_TXPWR_DB_FACTOR]); | ||
1238 | printk(KERN_DEBUG "%s\n", buf); | ||
1239 | |||
1240 | sprintf(buf, "40 MHz MCS0-7 CDD "); | ||
1241 | for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) | ||
1242 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1243 | txpwr->mcs_40_cdd[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1244 | fraction[txpwr->mcs_40_cdd[i] % | ||
1245 | BRCMS_TXPWR_DB_FACTOR]); | ||
1246 | printk(KERN_DEBUG "%s\n", buf); | ||
1247 | |||
1248 | sprintf(buf, "40 MHz MCS0-7 STBC "); | ||
1249 | for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) | ||
1250 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1251 | txpwr->mcs_40_stbc[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1252 | fraction[txpwr->mcs_40_stbc[i] % | ||
1253 | BRCMS_TXPWR_DB_FACTOR]); | ||
1254 | printk(KERN_DEBUG "%s\n", buf); | ||
1255 | |||
1256 | sprintf(buf, "40 MHz MCS8-15 SDM "); | ||
1257 | for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) | ||
1258 | sprintf(buf[strlen(buf)], " %2d%s", | ||
1259 | txpwr->mcs_40_mimo[i] / BRCMS_TXPWR_DB_FACTOR, | ||
1260 | fraction[txpwr->mcs_40_mimo[i] % | ||
1261 | BRCMS_TXPWR_DB_FACTOR]); | ||
1262 | } | ||
1263 | printk(KERN_DEBUG "%s\n", buf); | ||
1264 | |||
1265 | printk(KERN_DEBUG "MCS32 %2d%s\n", | ||
1266 | txpwr->mcs32 / BRCMS_TXPWR_DB_FACTOR, | ||
1267 | fraction[txpwr->mcs32 % BRCMS_TXPWR_DB_FACTOR]); | ||
1268 | } | ||
1269 | #endif /* POWER_DBG */ | ||
1270 | |||
1271 | void | 1156 | void |
1272 | brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, | 1157 | brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, |
1273 | struct txpwr_limits *txpwr) | 1158 | struct txpwr_limits *txpwr) |
@@ -1478,9 +1363,6 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, | |||
1478 | txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i]; | 1363 | txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i]; |
1479 | } | 1364 | } |
1480 | 1365 | ||
1481 | #ifdef POWER_DBG | ||
1482 | wlc_phy_txpower_limits_dump(txpwr); | ||
1483 | #endif | ||
1484 | return; | 1366 | return; |
1485 | } | 1367 | } |
1486 | 1368 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index 6ebec8f42846..e286fb4d4813 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c | |||
@@ -14,7 +14,6 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/skbuff.h> | ||
18 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
19 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
20 | 19 | ||
@@ -22,6 +21,7 @@ | |||
22 | #include <aiutils.h> | 21 | #include <aiutils.h> |
23 | #include "types.h" | 22 | #include "types.h" |
24 | #include "dma.h" | 23 | #include "dma.h" |
24 | #include "soc.h" | ||
25 | 25 | ||
26 | /* | 26 | /* |
27 | * DMA hardware requires each descriptor ring to be 8kB aligned, and fit within | 27 | * DMA hardware requires each descriptor ring to be 8kB aligned, and fit within |
@@ -901,7 +901,7 @@ static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall) | |||
901 | 901 | ||
902 | /* | 902 | /* |
903 | * !! rx entry routine | 903 | * !! rx entry routine |
904 | * returns a pointer to the next frame received, or NULL if there are no more | 904 | * returns the number packages in the next frame, or 0 if there are no more |
905 | * if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is | 905 | * if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is |
906 | * supported with pkts chain | 906 | * supported with pkts chain |
907 | * otherwise, it's treated as giant pkt and will be tossed. | 907 | * otherwise, it's treated as giant pkt and will be tossed. |
@@ -909,38 +909,40 @@ static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall) | |||
909 | * buffer data. After it reaches the max size of buffer, the data continues | 909 | * buffer data. After it reaches the max size of buffer, the data continues |
910 | * in next DMA descriptor buffer WITHOUT DMA header | 910 | * in next DMA descriptor buffer WITHOUT DMA header |
911 | */ | 911 | */ |
912 | struct sk_buff *dma_rx(struct dma_pub *pub) | 912 | int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) |
913 | { | 913 | { |
914 | struct dma_info *di = (struct dma_info *)pub; | 914 | struct dma_info *di = (struct dma_info *)pub; |
915 | struct sk_buff *p, *head, *tail; | 915 | struct sk_buff_head dma_frames; |
916 | struct sk_buff *p, *next; | ||
916 | uint len; | 917 | uint len; |
917 | uint pkt_len; | 918 | uint pkt_len; |
918 | int resid = 0; | 919 | int resid = 0; |
920 | int pktcnt = 1; | ||
919 | 921 | ||
922 | skb_queue_head_init(&dma_frames); | ||
920 | next_frame: | 923 | next_frame: |
921 | head = _dma_getnextrxp(di, false); | 924 | p = _dma_getnextrxp(di, false); |
922 | if (head == NULL) | 925 | if (p == NULL) |
923 | return NULL; | 926 | return 0; |
924 | 927 | ||
925 | len = le16_to_cpu(*(__le16 *) (head->data)); | 928 | len = le16_to_cpu(*(__le16 *) (p->data)); |
926 | DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); | 929 | DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); |
927 | dma_spin_for_len(len, head); | 930 | dma_spin_for_len(len, p); |
928 | 931 | ||
929 | /* set actual length */ | 932 | /* set actual length */ |
930 | pkt_len = min((di->rxoffset + len), di->rxbufsize); | 933 | pkt_len = min((di->rxoffset + len), di->rxbufsize); |
931 | __skb_trim(head, pkt_len); | 934 | __skb_trim(p, pkt_len); |
935 | skb_queue_tail(&dma_frames, p); | ||
932 | resid = len - (di->rxbufsize - di->rxoffset); | 936 | resid = len - (di->rxbufsize - di->rxoffset); |
933 | 937 | ||
934 | /* check for single or multi-buffer rx */ | 938 | /* check for single or multi-buffer rx */ |
935 | if (resid > 0) { | 939 | if (resid > 0) { |
936 | tail = head; | ||
937 | while ((resid > 0) && (p = _dma_getnextrxp(di, false))) { | 940 | while ((resid > 0) && (p = _dma_getnextrxp(di, false))) { |
938 | tail->next = p; | ||
939 | pkt_len = min_t(uint, resid, di->rxbufsize); | 941 | pkt_len = min_t(uint, resid, di->rxbufsize); |
940 | __skb_trim(p, pkt_len); | 942 | __skb_trim(p, pkt_len); |
941 | 943 | skb_queue_tail(&dma_frames, p); | |
942 | tail = p; | ||
943 | resid -= di->rxbufsize; | 944 | resid -= di->rxbufsize; |
945 | pktcnt++; | ||
944 | } | 946 | } |
945 | 947 | ||
946 | #ifdef BCMDBG | 948 | #ifdef BCMDBG |
@@ -959,13 +961,18 @@ struct sk_buff *dma_rx(struct dma_pub *pub) | |||
959 | if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { | 961 | if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { |
960 | DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", | 962 | DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", |
961 | di->name, len)); | 963 | di->name, len)); |
962 | brcmu_pkt_buf_free_skb(head); | 964 | skb_queue_walk_safe(&dma_frames, p, next) { |
965 | skb_unlink(p, &dma_frames); | ||
966 | brcmu_pkt_buf_free_skb(p); | ||
967 | } | ||
963 | di->dma.rxgiants++; | 968 | di->dma.rxgiants++; |
969 | pktcnt = 1; | ||
964 | goto next_frame; | 970 | goto next_frame; |
965 | } | 971 | } |
966 | } | 972 | } |
967 | 973 | ||
968 | return head; | 974 | skb_queue_splice_tail(&dma_frames, skb_list); |
975 | return pktcnt; | ||
969 | } | 976 | } |
970 | 977 | ||
971 | static bool dma64_rxidle(struct dma_info *di) | 978 | static bool dma64_rxidle(struct dma_info *di) |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/brcm80211/brcmsmac/dma.h index ebc5bc546f3b..d317c7c12f91 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #define _BRCM_DMA_H_ | 18 | #define _BRCM_DMA_H_ |
19 | 19 | ||
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/skbuff.h> | ||
21 | #include "types.h" /* forward structure declarations */ | 22 | #include "types.h" /* forward structure declarations */ |
22 | 23 | ||
23 | /* map/unmap direction */ | 24 | /* map/unmap direction */ |
@@ -80,7 +81,7 @@ extern struct dma_pub *dma_attach(char *name, struct si_pub *sih, | |||
80 | uint nrxpost, uint rxoffset, uint *msg_level); | 81 | uint nrxpost, uint rxoffset, uint *msg_level); |
81 | 82 | ||
82 | void dma_rxinit(struct dma_pub *pub); | 83 | void dma_rxinit(struct dma_pub *pub); |
83 | struct sk_buff *dma_rx(struct dma_pub *pub); | 84 | int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list); |
84 | bool dma_rxfill(struct dma_pub *pub); | 85 | bool dma_rxfill(struct dma_pub *pub); |
85 | bool dma_rxreset(struct dma_pub *pub); | 86 | bool dma_rxreset(struct dma_pub *pub); |
86 | bool dma_txreset(struct dma_pub *pub); | 87 | bool dma_txreset(struct dma_pub *pub); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 0d8a9cdf897a..8457e969eb4f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -216,8 +216,7 @@ static const struct ieee80211_supported_band brcms_band_2GHz_nphy_template = { | |||
216 | .ht_cap = { | 216 | .ht_cap = { |
217 | /* from include/linux/ieee80211.h */ | 217 | /* from include/linux/ieee80211.h */ |
218 | .cap = IEEE80211_HT_CAP_GRN_FLD | | 218 | .cap = IEEE80211_HT_CAP_GRN_FLD | |
219 | IEEE80211_HT_CAP_SGI_20 | | 219 | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40, |
220 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, | ||
221 | .ht_supported = true, | 220 | .ht_supported = true, |
222 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, | 221 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, |
223 | .ampdu_density = AMPDU_DEF_MPDU_DENSITY, | 222 | .ampdu_density = AMPDU_DEF_MPDU_DENSITY, |
@@ -238,8 +237,7 @@ static const struct ieee80211_supported_band brcms_band_5GHz_nphy_template = { | |||
238 | BRCMS_LEGACY_5G_RATE_OFFSET, | 237 | BRCMS_LEGACY_5G_RATE_OFFSET, |
239 | .ht_cap = { | 238 | .ht_cap = { |
240 | .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | | 239 | .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | |
241 | IEEE80211_HT_CAP_SGI_40 | | 240 | IEEE80211_HT_CAP_SGI_40, |
242 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */ | ||
243 | .ht_supported = true, | 241 | .ht_supported = true, |
244 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, | 242 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, |
245 | .ampdu_density = AMPDU_DEF_MPDU_DENSITY, | 243 | .ampdu_density = AMPDU_DEF_MPDU_DENSITY, |
@@ -287,6 +285,7 @@ static int brcms_ops_start(struct ieee80211_hw *hw) | |||
287 | { | 285 | { |
288 | struct brcms_info *wl = hw->priv; | 286 | struct brcms_info *wl = hw->priv; |
289 | bool blocked; | 287 | bool blocked; |
288 | int err; | ||
290 | 289 | ||
291 | ieee80211_wake_queues(hw); | 290 | ieee80211_wake_queues(hw); |
292 | spin_lock_bh(&wl->lock); | 291 | spin_lock_bh(&wl->lock); |
@@ -295,57 +294,69 @@ static int brcms_ops_start(struct ieee80211_hw *hw) | |||
295 | if (!blocked) | 294 | if (!blocked) |
296 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | 295 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); |
297 | 296 | ||
298 | return 0; | 297 | spin_lock_bh(&wl->lock); |
298 | /* avoid acknowledging frames before a non-monitor device is added */ | ||
299 | wl->mute_tx = true; | ||
300 | |||
301 | if (!wl->pub->up) | ||
302 | err = brcms_up(wl); | ||
303 | else | ||
304 | err = -ENODEV; | ||
305 | spin_unlock_bh(&wl->lock); | ||
306 | |||
307 | if (err != 0) | ||
308 | wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, | ||
309 | err); | ||
310 | return err; | ||
299 | } | 311 | } |
300 | 312 | ||
301 | static void brcms_ops_stop(struct ieee80211_hw *hw) | 313 | static void brcms_ops_stop(struct ieee80211_hw *hw) |
302 | { | 314 | { |
315 | struct brcms_info *wl = hw->priv; | ||
316 | int status; | ||
317 | |||
303 | ieee80211_stop_queues(hw); | 318 | ieee80211_stop_queues(hw); |
319 | |||
320 | if (wl->wlc == NULL) | ||
321 | return; | ||
322 | |||
323 | spin_lock_bh(&wl->lock); | ||
324 | status = brcms_c_chipmatch(wl->wlc->hw->vendorid, | ||
325 | wl->wlc->hw->deviceid); | ||
326 | spin_unlock_bh(&wl->lock); | ||
327 | if (!status) { | ||
328 | wiphy_err(wl->wiphy, | ||
329 | "wl: brcms_ops_stop: chipmatch failed\n"); | ||
330 | return; | ||
331 | } | ||
332 | |||
333 | /* put driver in down state */ | ||
334 | spin_lock_bh(&wl->lock); | ||
335 | brcms_down(wl); | ||
336 | spin_unlock_bh(&wl->lock); | ||
304 | } | 337 | } |
305 | 338 | ||
306 | static int | 339 | static int |
307 | brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 340 | brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
308 | { | 341 | { |
309 | struct brcms_info *wl; | 342 | struct brcms_info *wl = hw->priv; |
310 | int err; | ||
311 | 343 | ||
312 | /* Just STA for now */ | 344 | /* Just STA for now */ |
313 | if (vif->type != NL80211_IFTYPE_AP && | 345 | if (vif->type != NL80211_IFTYPE_STATION) { |
314 | vif->type != NL80211_IFTYPE_MESH_POINT && | ||
315 | vif->type != NL80211_IFTYPE_STATION && | ||
316 | vif->type != NL80211_IFTYPE_WDS && | ||
317 | vif->type != NL80211_IFTYPE_ADHOC) { | ||
318 | wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only" | 346 | wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only" |
319 | " STA for now\n", __func__, vif->type); | 347 | " STA for now\n", __func__, vif->type); |
320 | return -EOPNOTSUPP; | 348 | return -EOPNOTSUPP; |
321 | } | 349 | } |
322 | 350 | ||
323 | wl = hw->priv; | 351 | wl->mute_tx = false; |
324 | spin_lock_bh(&wl->lock); | 352 | brcms_c_mute(wl->wlc, false); |
325 | if (!wl->pub->up) | ||
326 | err = brcms_up(wl); | ||
327 | else | ||
328 | err = -ENODEV; | ||
329 | spin_unlock_bh(&wl->lock); | ||
330 | |||
331 | if (err != 0) | ||
332 | wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, | ||
333 | err); | ||
334 | 353 | ||
335 | return err; | 354 | return 0; |
336 | } | 355 | } |
337 | 356 | ||
338 | static void | 357 | static void |
339 | brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 358 | brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
340 | { | 359 | { |
341 | struct brcms_info *wl; | ||
342 | |||
343 | wl = hw->priv; | ||
344 | |||
345 | /* put driver in down state */ | ||
346 | spin_lock_bh(&wl->lock); | ||
347 | brcms_down(wl); | ||
348 | spin_unlock_bh(&wl->lock); | ||
349 | } | 360 | } |
350 | 361 | ||
351 | static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) | 362 | static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) |
@@ -609,13 +620,6 @@ brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
609 | wl->pub->global_ampdu->scb = scb; | 620 | wl->pub->global_ampdu->scb = scb; |
610 | wl->pub->global_ampdu->max_pdu = 16; | 621 | wl->pub->global_ampdu->max_pdu = 16; |
611 | 622 | ||
612 | sta->ht_cap.ht_supported = true; | ||
613 | sta->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
614 | sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY; | ||
615 | sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD | | ||
616 | IEEE80211_HT_CAP_SGI_20 | | ||
617 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT; | ||
618 | |||
619 | /* | 623 | /* |
620 | * minstrel_ht initiates addBA on our behalf by calling | 624 | * minstrel_ht initiates addBA on our behalf by calling |
621 | * ieee80211_start_tx_ba_session() | 625 | * ieee80211_start_tx_ba_session() |
@@ -877,37 +881,18 @@ static void brcms_free(struct brcms_info *wl) | |||
877 | } | 881 | } |
878 | 882 | ||
879 | /* | 883 | /* |
880 | * called from both kernel as from this kernel module. | 884 | * called from both kernel as from this kernel module (error flow on attach) |
881 | * precondition: perimeter lock is not acquired. | 885 | * precondition: perimeter lock is not acquired. |
882 | */ | 886 | */ |
883 | static void brcms_remove(struct pci_dev *pdev) | 887 | static void brcms_remove(struct pci_dev *pdev) |
884 | { | 888 | { |
885 | struct brcms_info *wl; | 889 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
886 | struct ieee80211_hw *hw; | 890 | struct brcms_info *wl = hw->priv; |
887 | int status; | ||
888 | |||
889 | hw = pci_get_drvdata(pdev); | ||
890 | wl = hw->priv; | ||
891 | if (!wl) { | ||
892 | pr_err("wl: brcms_remove: pci_get_drvdata failed\n"); | ||
893 | return; | ||
894 | } | ||
895 | 891 | ||
896 | spin_lock_bh(&wl->lock); | ||
897 | status = brcms_c_chipmatch(pdev->vendor, pdev->device); | ||
898 | spin_unlock_bh(&wl->lock); | ||
899 | if (!status) { | ||
900 | wiphy_err(wl->wiphy, "wl: brcms_remove: chipmatch " | ||
901 | "failed\n"); | ||
902 | return; | ||
903 | } | ||
904 | if (wl->wlc) { | 892 | if (wl->wlc) { |
905 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); | 893 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); |
906 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | 894 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); |
907 | ieee80211_unregister_hw(hw); | 895 | ieee80211_unregister_hw(hw); |
908 | spin_lock_bh(&wl->lock); | ||
909 | brcms_down(wl); | ||
910 | spin_unlock_bh(&wl->lock); | ||
911 | } | 896 | } |
912 | pci_disable_device(pdev); | 897 | pci_disable_device(pdev); |
913 | 898 | ||
@@ -1081,9 +1066,6 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device, | |||
1081 | 1066 | ||
1082 | wl->pub->ieee_hw = hw; | 1067 | wl->pub->ieee_hw = hw; |
1083 | 1068 | ||
1084 | /* disable mpc */ | ||
1085 | brcms_c_set_radio_mpc(wl->wlc, false); | ||
1086 | |||
1087 | /* register our interrupt handler */ | 1069 | /* register our interrupt handler */ |
1088 | if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { | 1070 | if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { |
1089 | wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); | 1071 | wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); |
@@ -1319,8 +1301,7 @@ void brcms_init(struct brcms_info *wl) | |||
1319 | { | 1301 | { |
1320 | BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); | 1302 | BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); |
1321 | brcms_reset(wl); | 1303 | brcms_reset(wl); |
1322 | 1304 | brcms_c_init(wl->wlc, wl->mute_tx); | |
1323 | brcms_c_init(wl->wlc); | ||
1324 | } | 1305 | } |
1325 | 1306 | ||
1326 | /* | 1307 | /* |
@@ -1337,6 +1318,14 @@ uint brcms_reset(struct brcms_info *wl) | |||
1337 | return 0; | 1318 | return 0; |
1338 | } | 1319 | } |
1339 | 1320 | ||
1321 | void brcms_fatal_error(struct brcms_info *wl) | ||
1322 | { | ||
1323 | wiphy_err(wl->wlc->wiphy, "wl%d: fatal error, reinitializing\n", | ||
1324 | wl->wlc->pub->unit); | ||
1325 | brcms_reset(wl); | ||
1326 | ieee80211_restart_hw(wl->pub->ieee_hw); | ||
1327 | } | ||
1328 | |||
1340 | /* | 1329 | /* |
1341 | * These are interrupt on/off entry points. Disable interrupts | 1330 | * These are interrupt on/off entry points. Disable interrupts |
1342 | * during interrupt state transition. | 1331 | * during interrupt state transition. |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h index 177f0e44e4b6..6242f188b717 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h | |||
@@ -80,6 +80,7 @@ struct brcms_info { | |||
80 | struct brcms_firmware fw; | 80 | struct brcms_firmware fw; |
81 | struct wiphy *wiphy; | 81 | struct wiphy *wiphy; |
82 | struct brcms_ucode ucode; | 82 | struct brcms_ucode ucode; |
83 | bool mute_tx; | ||
83 | }; | 84 | }; |
84 | 85 | ||
85 | /* misc callbacks */ | 86 | /* misc callbacks */ |
@@ -104,5 +105,6 @@ extern bool brcms_del_timer(struct brcms_timer *timer); | |||
104 | extern void brcms_msleep(struct brcms_info *wl, uint ms); | 105 | extern void brcms_msleep(struct brcms_info *wl, uint ms); |
105 | extern void brcms_dpc(unsigned long data); | 106 | extern void brcms_dpc(unsigned long data); |
106 | extern void brcms_timer(struct brcms_timer *t); | 107 | extern void brcms_timer(struct brcms_timer *t); |
108 | extern void brcms_fatal_error(struct brcms_info *wl); | ||
107 | 109 | ||
108 | #endif /* _BRCM_MAC80211_IF_H_ */ | 110 | #endif /* _BRCM_MAC80211_IF_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 510e9bb52287..36e3e0638300 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c | |||
@@ -30,44 +30,21 @@ | |||
30 | #include "mac80211_if.h" | 30 | #include "mac80211_if.h" |
31 | #include "ucode_loader.h" | 31 | #include "ucode_loader.h" |
32 | #include "main.h" | 32 | #include "main.h" |
33 | #include "soc.h" | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * Indication for txflowcontrol that all priority bits in | 36 | * Indication for txflowcontrol that all priority bits in |
36 | * TXQ_STOP_FOR_PRIOFC_MASK are to be considered. | 37 | * TXQ_STOP_FOR_PRIOFC_MASK are to be considered. |
37 | */ | 38 | */ |
38 | #define ALLPRIO -1 | 39 | #define ALLPRIO -1 |
39 | |||
40 | /* | ||
41 | * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. | ||
42 | */ | ||
43 | #define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) | ||
44 | 40 | ||
45 | /* watchdog timer, in unit of ms */ | 41 | /* watchdog timer, in unit of ms */ |
46 | #define TIMER_INTERVAL_WATCHDOG 1000 | 42 | #define TIMER_INTERVAL_WATCHDOG 1000 |
47 | /* radio monitor timer, in unit of ms */ | 43 | /* radio monitor timer, in unit of ms */ |
48 | #define TIMER_INTERVAL_RADIOCHK 800 | 44 | #define TIMER_INTERVAL_RADIOCHK 800 |
49 | |||
50 | /* Max MPC timeout, in unit of watchdog */ | ||
51 | #ifndef BRCMS_MPC_MAX_DELAYCNT | ||
52 | #define BRCMS_MPC_MAX_DELAYCNT 10 | ||
53 | #endif | ||
54 | |||
55 | /* Min MPC timeout, in unit of watchdog */ | ||
56 | #define BRCMS_MPC_MIN_DELAYCNT 1 | ||
57 | #define BRCMS_MPC_THRESHOLD 3 /* MPC count threshold level */ | ||
58 | 45 | ||
59 | /* beacon interval, in unit of 1024TU */ | 46 | /* beacon interval, in unit of 1024TU */ |
60 | #define BEACON_INTERVAL_DEFAULT 100 | 47 | #define BEACON_INTERVAL_DEFAULT 100 |
61 | /* DTIM interval, in unit of beacon interval */ | ||
62 | #define DTIM_INTERVAL_DEFAULT 3 | ||
63 | |||
64 | /* Scale down delays to accommodate QT slow speed */ | ||
65 | /* beacon interval, in unit of 1024TU */ | ||
66 | #define BEACON_INTERVAL_DEF_QT 20 | ||
67 | /* DTIM interval, in unit of beacon interval */ | ||
68 | #define DTIM_INTERVAL_DEF_QT 1 | ||
69 | |||
70 | #define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */ | ||
71 | 48 | ||
72 | /* n-mode support capability */ | 49 | /* n-mode support capability */ |
73 | /* 2x2 includes both 1x1 & 2x2 devices | 50 | /* 2x2 includes both 1x1 & 2x2 devices |
@@ -78,113 +55,71 @@ | |||
78 | #define WL_11N_3x3 3 | 55 | #define WL_11N_3x3 3 |
79 | #define WL_11N_4x4 4 | 56 | #define WL_11N_4x4 4 |
80 | 57 | ||
81 | /* define 11n feature disable flags */ | 58 | #define EDCF_ACI_MASK 0x60 |
82 | #define WLFEATURE_DISABLE_11N 0x00000001 | 59 | #define EDCF_ACI_SHIFT 5 |
83 | #define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 | 60 | #define EDCF_ECWMIN_MASK 0x0f |
84 | #define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 | 61 | #define EDCF_ECWMAX_SHIFT 4 |
85 | #define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 | 62 | #define EDCF_AIFSN_MASK 0x0f |
86 | #define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 | 63 | #define EDCF_AIFSN_MAX 15 |
87 | #define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 | 64 | #define EDCF_ECWMAX_MASK 0xf0 |
88 | #define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 | 65 | |
89 | #define WLFEATURE_DISABLE_11N_GF 0x00000080 | 66 | #define EDCF_AC_BE_TXOP_STA 0x0000 |
90 | 67 | #define EDCF_AC_BK_TXOP_STA 0x0000 | |
91 | #define EDCF_ACI_MASK 0x60 | 68 | #define EDCF_AC_VO_ACI_STA 0x62 |
92 | #define EDCF_ACI_SHIFT 5 | 69 | #define EDCF_AC_VO_ECW_STA 0x32 |
93 | #define EDCF_ECWMIN_MASK 0x0f | 70 | #define EDCF_AC_VI_ACI_STA 0x42 |
94 | #define EDCF_ECWMAX_SHIFT 4 | 71 | #define EDCF_AC_VI_ECW_STA 0x43 |
95 | #define EDCF_AIFSN_MASK 0x0f | 72 | #define EDCF_AC_BK_ECW_STA 0xA4 |
96 | #define EDCF_AIFSN_MAX 15 | 73 | #define EDCF_AC_VI_TXOP_STA 0x005e |
97 | #define EDCF_ECWMAX_MASK 0xf0 | 74 | #define EDCF_AC_VO_TXOP_STA 0x002f |
98 | 75 | #define EDCF_AC_BE_ACI_STA 0x03 | |
99 | #define EDCF_AC_BE_TXOP_STA 0x0000 | 76 | #define EDCF_AC_BE_ECW_STA 0xA4 |
100 | #define EDCF_AC_BK_TXOP_STA 0x0000 | 77 | #define EDCF_AC_BK_ACI_STA 0x27 |
101 | #define EDCF_AC_VO_ACI_STA 0x62 | 78 | #define EDCF_AC_VO_TXOP_AP 0x002f |
102 | #define EDCF_AC_VO_ECW_STA 0x32 | 79 | |
103 | #define EDCF_AC_VI_ACI_STA 0x42 | 80 | #define EDCF_TXOP2USEC(txop) ((txop) << 5) |
104 | #define EDCF_AC_VI_ECW_STA 0x43 | 81 | #define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) |
105 | #define EDCF_AC_BK_ECW_STA 0xA4 | 82 | |
106 | #define EDCF_AC_VI_TXOP_STA 0x005e | 83 | #define APHY_SYMBOL_TIME 4 |
107 | #define EDCF_AC_VO_TXOP_STA 0x002f | 84 | #define APHY_PREAMBLE_TIME 16 |
108 | #define EDCF_AC_BE_ACI_STA 0x03 | 85 | #define APHY_SIGNAL_TIME 4 |
109 | #define EDCF_AC_BE_ECW_STA 0xA4 | 86 | #define APHY_SIFS_TIME 16 |
110 | #define EDCF_AC_BK_ACI_STA 0x27 | 87 | #define APHY_SERVICE_NBITS 16 |
111 | #define EDCF_AC_VO_TXOP_AP 0x002f | 88 | #define APHY_TAIL_NBITS 6 |
112 | 89 | #define BPHY_SIFS_TIME 10 | |
113 | #define EDCF_TXOP2USEC(txop) ((txop) << 5) | 90 | #define BPHY_PLCP_SHORT_TIME 96 |
114 | #define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) | 91 | |
115 | 92 | #define PREN_PREAMBLE 24 | |
116 | #define APHY_SYMBOL_TIME 4 | 93 | #define PREN_MM_EXT 12 |
117 | #define APHY_PREAMBLE_TIME 16 | 94 | #define PREN_PREAMBLE_EXT 4 |
118 | #define APHY_SIGNAL_TIME 4 | ||
119 | #define APHY_SIFS_TIME 16 | ||
120 | #define APHY_SERVICE_NBITS 16 | ||
121 | #define APHY_TAIL_NBITS 6 | ||
122 | #define BPHY_SIFS_TIME 10 | ||
123 | #define BPHY_PLCP_SHORT_TIME 96 | ||
124 | |||
125 | #define PREN_PREAMBLE 24 | ||
126 | #define PREN_MM_EXT 12 | ||
127 | #define PREN_PREAMBLE_EXT 4 | ||
128 | 95 | ||
129 | #define DOT11_MAC_HDR_LEN 24 | 96 | #define DOT11_MAC_HDR_LEN 24 |
130 | #define DOT11_ACK_LEN 10 | 97 | #define DOT11_ACK_LEN 10 |
131 | #define DOT11_BA_LEN 4 | 98 | #define DOT11_BA_LEN 4 |
132 | #define DOT11_OFDM_SIGNAL_EXTENSION 6 | 99 | #define DOT11_OFDM_SIGNAL_EXTENSION 6 |
133 | #define DOT11_MIN_FRAG_LEN 256 | 100 | #define DOT11_MIN_FRAG_LEN 256 |
134 | #define DOT11_RTS_LEN 16 | 101 | #define DOT11_RTS_LEN 16 |
135 | #define DOT11_CTS_LEN 10 | 102 | #define DOT11_CTS_LEN 10 |
136 | #define DOT11_BA_BITMAP_LEN 128 | 103 | #define DOT11_BA_BITMAP_LEN 128 |
137 | #define DOT11_MIN_BEACON_PERIOD 1 | 104 | #define DOT11_MIN_BEACON_PERIOD 1 |
138 | #define DOT11_MAX_BEACON_PERIOD 0xFFFF | 105 | #define DOT11_MAX_BEACON_PERIOD 0xFFFF |
139 | #define DOT11_MAXNUMFRAGS 16 | 106 | #define DOT11_MAXNUMFRAGS 16 |
140 | #define DOT11_MAX_FRAG_LEN 2346 | 107 | #define DOT11_MAX_FRAG_LEN 2346 |
141 | 108 | ||
142 | #define BPHY_PLCP_TIME 192 | 109 | #define BPHY_PLCP_TIME 192 |
143 | #define RIFS_11N_TIME 2 | 110 | #define RIFS_11N_TIME 2 |
144 | |||
145 | #define WME_VER 1 | ||
146 | #define WME_SUBTYPE_PARAM_IE 1 | ||
147 | #define WME_TYPE 2 | ||
148 | #define WME_OUI "\x00\x50\xf2" | ||
149 | |||
150 | #define AC_BE 0 | ||
151 | #define AC_BK 1 | ||
152 | #define AC_VI 2 | ||
153 | #define AC_VO 3 | ||
154 | 111 | ||
155 | #define BCN_TMPL_LEN 512 /* length of the BCN template area */ | 112 | /* length of the BCN template area */ |
113 | #define BCN_TMPL_LEN 512 | ||
156 | 114 | ||
157 | /* brcms_bss_info flag bit values */ | 115 | /* brcms_bss_info flag bit values */ |
158 | #define BRCMS_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ | 116 | #define BRCMS_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ |
159 | 117 | ||
160 | /* Flags used in brcms_c_txq_info.stopped */ | 118 | /* chip rx buffer offset */ |
161 | /* per prio flow control bits */ | 119 | #define BRCMS_HWRXOFF 38 |
162 | #define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF | ||
163 | /* stop txq enqueue for packet drain */ | ||
164 | #define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 | ||
165 | /* stop txq enqueue for ampdu flow control */ | ||
166 | #define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 | ||
167 | |||
168 | #define BRCMS_HWRXOFF 38 /* chip rx buffer offset */ | ||
169 | |||
170 | /* Find basic rate for a given rate */ | ||
171 | static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) | ||
172 | { | ||
173 | if (is_mcs_rate(rspec)) | ||
174 | return wlc->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK] | ||
175 | .leg_ofdm]; | ||
176 | return wlc->band->basic_rate[rspec & RSPEC_RATE_MASK]; | ||
177 | } | ||
178 | |||
179 | static u16 frametype(u32 rspec, u8 mimoframe) | ||
180 | { | ||
181 | if (is_mcs_rate(rspec)) | ||
182 | return mimoframe; | ||
183 | return is_cck_rate(rspec) ? FT_CCK : FT_OFDM; | ||
184 | } | ||
185 | 120 | ||
186 | /* rfdisable delay timer 500 ms, runs of ALP clock */ | 121 | /* rfdisable delay timer 500 ms, runs of ALP clock */ |
187 | #define RFDISABLE_DEFAULT 10000000 | 122 | #define RFDISABLE_DEFAULT 10000000 |
188 | 123 | ||
189 | #define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ | 124 | #define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ |
190 | 125 | ||
@@ -194,87 +129,83 @@ static u16 frametype(u32 rspec, u8 mimoframe) | |||
194 | * These constants are used ONLY by wlc_prio2prec_map. Do not use them | 129 | * These constants are used ONLY by wlc_prio2prec_map. Do not use them |
195 | * elsewhere. | 130 | * elsewhere. |
196 | */ | 131 | */ |
197 | #define _BRCMS_PREC_NONE 0 /* None = - */ | 132 | #define _BRCMS_PREC_NONE 0 /* None = - */ |
198 | #define _BRCMS_PREC_BK 2 /* BK - Background */ | 133 | #define _BRCMS_PREC_BK 2 /* BK - Background */ |
199 | #define _BRCMS_PREC_BE 4 /* BE - Best-effort */ | 134 | #define _BRCMS_PREC_BE 4 /* BE - Best-effort */ |
200 | #define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */ | 135 | #define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */ |
201 | #define _BRCMS_PREC_CL 8 /* CL - Controlled Load */ | 136 | #define _BRCMS_PREC_CL 8 /* CL - Controlled Load */ |
202 | #define _BRCMS_PREC_VI 10 /* Vi - Video */ | 137 | #define _BRCMS_PREC_VI 10 /* Vi - Video */ |
203 | #define _BRCMS_PREC_VO 12 /* Vo - Voice */ | 138 | #define _BRCMS_PREC_VO 12 /* Vo - Voice */ |
204 | #define _BRCMS_PREC_NC 14 /* NC - Network Control */ | 139 | #define _BRCMS_PREC_NC 14 /* NC - Network Control */ |
205 | 140 | ||
206 | /* The BSS is generating beacons in HW */ | 141 | /* synthpu_dly times in us */ |
207 | #define BRCMS_BSSCFG_HW_BCN 0x20 | 142 | #define SYNTHPU_DLY_APHY_US 3700 |
208 | 143 | #define SYNTHPU_DLY_BPHY_US 1050 | |
209 | #define SYNTHPU_DLY_APHY_US 3700 /* a phy synthpu_dly time in us */ | 144 | #define SYNTHPU_DLY_NPHY_US 2048 |
210 | #define SYNTHPU_DLY_BPHY_US 1050 /* b/g phy synthpu_dly time in us */ | 145 | #define SYNTHPU_DLY_LPPHY_US 300 |
211 | #define SYNTHPU_DLY_NPHY_US 2048 /* n phy REV3 synthpu_dly time in us */ | 146 | |
212 | #define SYNTHPU_DLY_LPPHY_US 300 /* lpphy synthpu_dly time in us */ | 147 | #define ANTCNT 10 /* vanilla M_MAX_ANTCNT val */ |
213 | |||
214 | #define SYNTHPU_DLY_PHY_US_QT 100 /* QT synthpu_dly time in us */ | ||
215 | |||
216 | #define ANTCNT 10 /* vanilla M_MAX_ANTCNT value */ | ||
217 | 148 | ||
218 | /* Per-AC retry limit register definitions; uses defs.h bitfield macros */ | 149 | /* Per-AC retry limit register definitions; uses defs.h bitfield macros */ |
219 | #define EDCF_SHORT_S 0 | 150 | #define EDCF_SHORT_S 0 |
220 | #define EDCF_SFB_S 4 | 151 | #define EDCF_SFB_S 4 |
221 | #define EDCF_LONG_S 8 | 152 | #define EDCF_LONG_S 8 |
222 | #define EDCF_LFB_S 12 | 153 | #define EDCF_LFB_S 12 |
223 | #define EDCF_SHORT_M BITFIELD_MASK(4) | 154 | #define EDCF_SHORT_M BITFIELD_MASK(4) |
224 | #define EDCF_SFB_M BITFIELD_MASK(4) | 155 | #define EDCF_SFB_M BITFIELD_MASK(4) |
225 | #define EDCF_LONG_M BITFIELD_MASK(4) | 156 | #define EDCF_LONG_M BITFIELD_MASK(4) |
226 | #define EDCF_LFB_M BITFIELD_MASK(4) | 157 | #define EDCF_LFB_M BITFIELD_MASK(4) |
227 | 158 | ||
228 | #define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ | 159 | #define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ |
229 | #define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ | 160 | #define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ |
230 | #define RETRY_LONG_DEF 4 /* Default Long retry count */ | 161 | #define RETRY_LONG_DEF 4 /* Default Long retry count */ |
231 | #define RETRY_SHORT_FB 3 /* Short count for fallback rate */ | 162 | #define RETRY_SHORT_FB 3 /* Short count for fb rate */ |
232 | #define RETRY_LONG_FB 2 /* Long count for fallback rate */ | 163 | #define RETRY_LONG_FB 2 /* Long count for fb rate */ |
233 | 164 | ||
234 | #define APHY_CWMIN 15 | 165 | #define APHY_CWMIN 15 |
235 | #define PHY_CWMAX 1023 | 166 | #define PHY_CWMAX 1023 |
236 | 167 | ||
237 | #define EDCF_AIFSN_MIN 1 | 168 | #define EDCF_AIFSN_MIN 1 |
238 | 169 | ||
239 | #define FRAGNUM_MASK 0xF | 170 | #define FRAGNUM_MASK 0xF |
240 | 171 | ||
241 | #define APHY_SLOT_TIME 9 | 172 | #define APHY_SLOT_TIME 9 |
242 | #define BPHY_SLOT_TIME 20 | 173 | #define BPHY_SLOT_TIME 20 |
243 | 174 | ||
244 | #define WL_SPURAVOID_OFF 0 | 175 | #define WL_SPURAVOID_OFF 0 |
245 | #define WL_SPURAVOID_ON1 1 | 176 | #define WL_SPURAVOID_ON1 1 |
246 | #define WL_SPURAVOID_ON2 2 | 177 | #define WL_SPURAVOID_ON2 2 |
247 | 178 | ||
248 | /* invalid core flags, use the saved coreflags */ | 179 | /* invalid core flags, use the saved coreflags */ |
249 | #define BRCMS_USE_COREFLAGS 0xffffffff | 180 | #define BRCMS_USE_COREFLAGS 0xffffffff |
250 | 181 | ||
251 | /* values for PLCPHdr_override */ | 182 | /* values for PLCPHdr_override */ |
252 | #define BRCMS_PLCP_AUTO -1 | 183 | #define BRCMS_PLCP_AUTO -1 |
253 | #define BRCMS_PLCP_SHORT 0 | 184 | #define BRCMS_PLCP_SHORT 0 |
254 | #define BRCMS_PLCP_LONG 1 | 185 | #define BRCMS_PLCP_LONG 1 |
255 | 186 | ||
256 | /* values for g_protection_override and n_protection_override */ | 187 | /* values for g_protection_override and n_protection_override */ |
257 | #define BRCMS_PROTECTION_AUTO -1 | 188 | #define BRCMS_PROTECTION_AUTO -1 |
258 | #define BRCMS_PROTECTION_OFF 0 | 189 | #define BRCMS_PROTECTION_OFF 0 |
259 | #define BRCMS_PROTECTION_ON 1 | 190 | #define BRCMS_PROTECTION_ON 1 |
260 | #define BRCMS_PROTECTION_MMHDR_ONLY 2 | 191 | #define BRCMS_PROTECTION_MMHDR_ONLY 2 |
261 | #define BRCMS_PROTECTION_CTS_ONLY 3 | 192 | #define BRCMS_PROTECTION_CTS_ONLY 3 |
262 | 193 | ||
263 | /* values for g_protection_control and n_protection_control */ | 194 | /* values for g_protection_control and n_protection_control */ |
264 | #define BRCMS_PROTECTION_CTL_OFF 0 | 195 | #define BRCMS_PROTECTION_CTL_OFF 0 |
265 | #define BRCMS_PROTECTION_CTL_LOCAL 1 | 196 | #define BRCMS_PROTECTION_CTL_LOCAL 1 |
266 | #define BRCMS_PROTECTION_CTL_OVERLAP 2 | 197 | #define BRCMS_PROTECTION_CTL_OVERLAP 2 |
267 | 198 | ||
268 | /* values for n_protection */ | 199 | /* values for n_protection */ |
269 | #define BRCMS_N_PROTECTION_OFF 0 | 200 | #define BRCMS_N_PROTECTION_OFF 0 |
270 | #define BRCMS_N_PROTECTION_OPTIONAL 1 | 201 | #define BRCMS_N_PROTECTION_OPTIONAL 1 |
271 | #define BRCMS_N_PROTECTION_20IN40 2 | 202 | #define BRCMS_N_PROTECTION_20IN40 2 |
272 | #define BRCMS_N_PROTECTION_MIXEDMODE 3 | 203 | #define BRCMS_N_PROTECTION_MIXEDMODE 3 |
273 | 204 | ||
274 | /* values for band specific 40MHz capabilities */ | 205 | /* values for band specific 40MHz capabilities */ |
275 | #define BRCMS_N_BW_20ALL 0 | 206 | #define BRCMS_N_BW_20ALL 0 |
276 | #define BRCMS_N_BW_40ALL 1 | 207 | #define BRCMS_N_BW_40ALL 1 |
277 | #define BRCMS_N_BW_20IN2G_40IN5G 2 | 208 | #define BRCMS_N_BW_20IN2G_40IN5G 2 |
278 | 209 | ||
279 | /* bitflags for SGI support (sgi_rx iovar) */ | 210 | /* bitflags for SGI support (sgi_rx iovar) */ |
280 | #define BRCMS_N_SGI_20 0x01 | 211 | #define BRCMS_N_SGI_20 0x01 |
@@ -282,48 +213,42 @@ static u16 frametype(u32 rspec, u8 mimoframe) | |||
282 | 213 | ||
283 | /* defines used by the nrate iovar */ | 214 | /* defines used by the nrate iovar */ |
284 | /* MSC in use,indicates b0-6 holds an mcs */ | 215 | /* MSC in use,indicates b0-6 holds an mcs */ |
285 | #define NRATE_MCS_INUSE 0x00000080 | 216 | #define NRATE_MCS_INUSE 0x00000080 |
286 | /* rate/mcs value */ | 217 | /* rate/mcs value */ |
287 | #define NRATE_RATE_MASK 0x0000007f | 218 | #define NRATE_RATE_MASK 0x0000007f |
288 | /* stf mode mask: siso, cdd, stbc, sdm */ | 219 | /* stf mode mask: siso, cdd, stbc, sdm */ |
289 | #define NRATE_STF_MASK 0x0000ff00 | 220 | #define NRATE_STF_MASK 0x0000ff00 |
290 | /* stf mode shift */ | 221 | /* stf mode shift */ |
291 | #define NRATE_STF_SHIFT 8 | 222 | #define NRATE_STF_SHIFT 8 |
292 | /* bit indicates override both rate & mode */ | ||
293 | #define NRATE_OVERRIDE 0x80000000 | ||
294 | /* bit indicate to override mcs only */ | 223 | /* bit indicate to override mcs only */ |
295 | #define NRATE_OVERRIDE_MCS_ONLY 0x40000000 | 224 | #define NRATE_OVERRIDE_MCS_ONLY 0x40000000 |
296 | #define NRATE_SGI_MASK 0x00800000 /* sgi mode */ | 225 | #define NRATE_SGI_MASK 0x00800000 /* sgi mode */ |
297 | #define NRATE_SGI_SHIFT 23 /* sgi mode */ | 226 | #define NRATE_SGI_SHIFT 23 /* sgi mode */ |
298 | #define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ | 227 | #define NRATE_LDPC_CODING 0x00400000 /* adv coding in use */ |
299 | #define NRATE_LDPC_SHIFT 22 /* ldpc shift */ | 228 | #define NRATE_LDPC_SHIFT 22 /* ldpc shift */ |
300 | 229 | ||
301 | #define NRATE_STF_SISO 0 /* stf mode SISO */ | 230 | #define NRATE_STF_SISO 0 /* stf mode SISO */ |
302 | #define NRATE_STF_CDD 1 /* stf mode CDD */ | 231 | #define NRATE_STF_CDD 1 /* stf mode CDD */ |
303 | #define NRATE_STF_STBC 2 /* stf mode STBC */ | 232 | #define NRATE_STF_STBC 2 /* stf mode STBC */ |
304 | #define NRATE_STF_SDM 3 /* stf mode SDM */ | 233 | #define NRATE_STF_SDM 3 /* stf mode SDM */ |
305 | 234 | ||
306 | #define MAX_DMA_SEGS 4 | 235 | #define MAX_DMA_SEGS 4 |
307 | 236 | ||
308 | /* Max # of entries in Tx FIFO based on 4kb page size */ | 237 | /* Max # of entries in Tx FIFO based on 4kb page size */ |
309 | #define NTXD 256 | 238 | #define NTXD 256 |
310 | /* Max # of entries in Rx FIFO based on 4kb page size */ | 239 | /* Max # of entries in Rx FIFO based on 4kb page size */ |
311 | #define NRXD 256 | 240 | #define NRXD 256 |
312 | 241 | ||
313 | /* try to keep this # rbufs posted to the chip */ | 242 | /* try to keep this # rbufs posted to the chip */ |
314 | #define NRXBUFPOST 32 | 243 | #define NRXBUFPOST 32 |
315 | 244 | ||
316 | /* data msg txq hiwat mark */ | 245 | /* data msg txq hiwat mark */ |
317 | #define BRCMS_DATAHIWAT 50 | 246 | #define BRCMS_DATAHIWAT 50 |
318 | 247 | ||
319 | /* bounded rx loops */ | 248 | /* max # frames to process in brcms_c_recv() */ |
320 | #define RXBND 8 /* max # frames to process in brcms_c_recv() */ | 249 | #define RXBND 8 |
321 | #define TXSBND 8 /* max # tx status to process in wlc_txstatus() */ | 250 | /* max # tx status to process in wlc_txstatus() */ |
322 | 251 | #define TXSBND 8 | |
323 | /* | ||
324 | * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. | ||
325 | */ | ||
326 | #define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) | ||
327 | 252 | ||
328 | /* brcmu_format_flags() bit description structure */ | 253 | /* brcmu_format_flags() bit description structure */ |
329 | struct brcms_c_bit_desc { | 254 | struct brcms_c_bit_desc { |
@@ -375,10 +300,22 @@ uint brcm_msg_level = | |||
375 | #endif /* BCMDBG */ | 300 | #endif /* BCMDBG */ |
376 | 301 | ||
377 | /* TX FIFO number to WME/802.1E Access Category */ | 302 | /* TX FIFO number to WME/802.1E Access Category */ |
378 | static const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE }; | 303 | static const u8 wme_fifo2ac[] = { |
304 | IEEE80211_AC_BK, | ||
305 | IEEE80211_AC_BE, | ||
306 | IEEE80211_AC_VI, | ||
307 | IEEE80211_AC_VO, | ||
308 | IEEE80211_AC_BE, | ||
309 | IEEE80211_AC_BE | ||
310 | }; | ||
379 | 311 | ||
380 | /* WME/802.1E Access Category to TX FIFO number */ | 312 | /* ieee80211 Access Category to TX FIFO number */ |
381 | static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 }; | 313 | static const u8 wme_ac2fifo[] = { |
314 | TX_AC_VO_FIFO, | ||
315 | TX_AC_VI_FIFO, | ||
316 | TX_AC_BE_FIFO, | ||
317 | TX_AC_BK_FIFO | ||
318 | }; | ||
382 | 319 | ||
383 | /* 802.1D Priority to precedence queue mapping */ | 320 | /* 802.1D Priority to precedence queue mapping */ |
384 | const u8 wlc_prio2prec_map[] = { | 321 | const u8 wlc_prio2prec_map[] = { |
@@ -405,13 +342,6 @@ static const u16 xmtfifo_sz[][NFIFO] = { | |||
405 | {9, 58, 22, 14, 14, 5}, | 342 | {9, 58, 22, 14, 14, 5}, |
406 | }; | 343 | }; |
407 | 344 | ||
408 | static const u8 acbitmap2maxprio[] = { | ||
409 | PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK, | ||
410 | PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, | ||
411 | PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, | ||
412 | PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO | ||
413 | }; | ||
414 | |||
415 | #ifdef BCMDBG | 345 | #ifdef BCMDBG |
416 | static const char * const fifo_names[] = { | 346 | static const char * const fifo_names[] = { |
417 | "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; | 347 | "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; |
@@ -424,6 +354,22 @@ static const char fifo_names[6][0]; | |||
424 | static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); | 354 | static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); |
425 | #endif | 355 | #endif |
426 | 356 | ||
357 | /* Find basic rate for a given rate */ | ||
358 | static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) | ||
359 | { | ||
360 | if (is_mcs_rate(rspec)) | ||
361 | return wlc->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK] | ||
362 | .leg_ofdm]; | ||
363 | return wlc->band->basic_rate[rspec & RSPEC_RATE_MASK]; | ||
364 | } | ||
365 | |||
366 | static u16 frametype(u32 rspec, u8 mimoframe) | ||
367 | { | ||
368 | if (is_mcs_rate(rspec)) | ||
369 | return mimoframe; | ||
370 | return is_cck_rate(rspec) ? FT_CCK : FT_OFDM; | ||
371 | } | ||
372 | |||
427 | /* currently the best mechanism for determining SIFS is the band in use */ | 373 | /* currently the best mechanism for determining SIFS is the band in use */ |
428 | static u16 get_sifs(struct brcms_band *band) | 374 | static u16 get_sifs(struct brcms_band *band) |
429 | { | 375 | { |
@@ -470,20 +416,6 @@ static int brcms_chspec_bw(u16 chanspec) | |||
470 | return BRCMS_10_MHZ; | 416 | return BRCMS_10_MHZ; |
471 | } | 417 | } |
472 | 418 | ||
473 | /* | ||
474 | * return true if Minimum Power Consumption should | ||
475 | * be entered, false otherwise | ||
476 | */ | ||
477 | static bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc) | ||
478 | { | ||
479 | return false; | ||
480 | } | ||
481 | |||
482 | static bool brcms_c_ismpc(struct brcms_c_info *wlc) | ||
483 | { | ||
484 | return (wlc->mpc_delay_off == 0) && (brcms_c_is_non_delay_mpc(wlc)); | ||
485 | } | ||
486 | |||
487 | static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg) | 419 | static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg) |
488 | { | 420 | { |
489 | if (cfg == NULL) | 421 | if (cfg == NULL) |
@@ -669,9 +601,8 @@ static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw, | |||
669 | * calculate frame duration of a given rate and length, return | 601 | * calculate frame duration of a given rate and length, return |
670 | * time in usec unit | 602 | * time in usec unit |
671 | */ | 603 | */ |
672 | uint | 604 | static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec, |
673 | brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec, | 605 | u8 preamble_type, uint mac_len) |
674 | u8 preamble_type, uint mac_len) | ||
675 | { | 606 | { |
676 | uint nsyms, dur = 0, Ndps, kNdps; | 607 | uint nsyms, dur = 0, Ndps, kNdps; |
677 | uint rate = rspec2rate(ratespec); | 608 | uint rate = rspec2rate(ratespec); |
@@ -969,7 +900,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
969 | lfbl, /* Long Frame Rate Fallback Limit */ | 900 | lfbl, /* Long Frame Rate Fallback Limit */ |
970 | fbl; | 901 | fbl; |
971 | 902 | ||
972 | if (queue < AC_COUNT) { | 903 | if (queue < IEEE80211_NUM_ACS) { |
973 | sfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]], | 904 | sfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]], |
974 | EDCF_SFB); | 905 | EDCF_SFB); |
975 | lfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]], | 906 | lfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]], |
@@ -1018,7 +949,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
1018 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 949 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
1019 | } | 950 | } |
1020 | 951 | ||
1021 | totlen = brcmu_pkttotlen(p); | 952 | totlen = p->len; |
1022 | free_pdu = true; | 953 | free_pdu = true; |
1023 | 954 | ||
1024 | brcms_c_txfifo_complete(wlc, queue, 1); | 955 | brcms_c_txfifo_complete(wlc, queue, 1); |
@@ -2352,13 +2283,6 @@ void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type) | |||
2352 | wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); | 2283 | wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); |
2353 | } | 2284 | } |
2354 | 2285 | ||
2355 | static void brcms_c_fatal_error(struct brcms_c_info *wlc) | ||
2356 | { | ||
2357 | wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n", | ||
2358 | wlc->pub->unit); | ||
2359 | brcms_init(wlc->wl); | ||
2360 | } | ||
2361 | |||
2362 | static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) | 2286 | static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) |
2363 | { | 2287 | { |
2364 | bool fatal = false; | 2288 | bool fatal = false; |
@@ -2414,7 +2338,7 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) | |||
2414 | } | 2338 | } |
2415 | 2339 | ||
2416 | if (fatal) { | 2340 | if (fatal) { |
2417 | brcms_c_fatal_error(wlc_hw->wlc); /* big hammer */ | 2341 | brcms_fatal_error(wlc_hw->wlc->wl); /* big hammer */ |
2418 | break; | 2342 | break; |
2419 | } else | 2343 | } else |
2420 | W_REG(®s->intctrlregs[idx].intstatus, | 2344 | W_REG(®s->intctrlregs[idx].intstatus, |
@@ -2479,6 +2403,7 @@ void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask) | |||
2479 | W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); | 2403 | W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); |
2480 | } | 2404 | } |
2481 | 2405 | ||
2406 | /* assumes that the d11 MAC is enabled */ | ||
2482 | static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw, | 2407 | static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw, |
2483 | uint tx_fifo) | 2408 | uint tx_fifo) |
2484 | { | 2409 | { |
@@ -2535,11 +2460,12 @@ static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw, | |||
2535 | } | 2460 | } |
2536 | } | 2461 | } |
2537 | 2462 | ||
2538 | static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, u32 flags) | 2463 | /* precondition: requires the mac core to be enabled */ |
2464 | static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx) | ||
2539 | { | 2465 | { |
2540 | static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; | 2466 | static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; |
2541 | 2467 | ||
2542 | if (on) { | 2468 | if (mute_tx) { |
2543 | /* suspend tx fifos */ | 2469 | /* suspend tx fifos */ |
2544 | brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); | 2470 | brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); |
2545 | brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); | 2471 | brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); |
@@ -2561,14 +2487,20 @@ static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, u32 flags) | |||
2561 | wlc_hw->etheraddr); | 2487 | wlc_hw->etheraddr); |
2562 | } | 2488 | } |
2563 | 2489 | ||
2564 | wlc_phy_mute_upd(wlc_hw->band->pi, on, flags); | 2490 | wlc_phy_mute_upd(wlc_hw->band->pi, mute_tx, 0); |
2565 | 2491 | ||
2566 | if (on) | 2492 | if (mute_tx) |
2567 | brcms_c_ucode_mute_override_set(wlc_hw); | 2493 | brcms_c_ucode_mute_override_set(wlc_hw); |
2568 | else | 2494 | else |
2569 | brcms_c_ucode_mute_override_clear(wlc_hw); | 2495 | brcms_c_ucode_mute_override_clear(wlc_hw); |
2570 | } | 2496 | } |
2571 | 2497 | ||
2498 | void | ||
2499 | brcms_c_mute(struct brcms_c_info *wlc, bool mute_tx) | ||
2500 | { | ||
2501 | brcms_b_mute(wlc->hw, mute_tx); | ||
2502 | } | ||
2503 | |||
2572 | /* | 2504 | /* |
2573 | * Read and clear macintmask and macintstatus and intstatus registers. | 2505 | * Read and clear macintmask and macintstatus and intstatus registers. |
2574 | * This routine should be called with interrupts off | 2506 | * This routine should be called with interrupts off |
@@ -3437,8 +3369,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) | |||
3437 | } | 3369 | } |
3438 | 3370 | ||
3439 | void | 3371 | void |
3440 | static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec, | 3372 | static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) { |
3441 | bool mute) { | ||
3442 | u32 macintmask; | 3373 | u32 macintmask; |
3443 | bool fastclk; | 3374 | bool fastclk; |
3444 | struct brcms_c_info *wlc = wlc_hw->wlc; | 3375 | struct brcms_c_info *wlc = wlc_hw->wlc; |
@@ -3463,10 +3394,6 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec, | |||
3463 | /* core-specific initialization */ | 3394 | /* core-specific initialization */ |
3464 | brcms_b_coreinit(wlc); | 3395 | brcms_b_coreinit(wlc); |
3465 | 3396 | ||
3466 | /* suspend the tx fifos and mute the phy for preism cac time */ | ||
3467 | if (mute) | ||
3468 | brcms_b_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM); | ||
3469 | |||
3470 | /* band-specific inits */ | 3397 | /* band-specific inits */ |
3471 | brcms_b_bsinit(wlc, chanspec); | 3398 | brcms_b_bsinit(wlc, chanspec); |
3472 | 3399 | ||
@@ -3656,42 +3583,30 @@ static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc, | |||
3656 | brcms_c_set_phy_chanspec(wlc, chanspec); | 3583 | brcms_c_set_phy_chanspec(wlc, chanspec); |
3657 | } | 3584 | } |
3658 | 3585 | ||
3659 | static void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc) | 3586 | /* |
3660 | { | 3587 | * Set or clear maccontrol bits MCTL_PROMISC, MCTL_BCNS_PROMISC and |
3661 | if (wlc->bcnmisc_monitor) | 3588 | * MCTL_KEEPCONTROL |
3662 | brcms_b_mctrl(wlc->hw, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC); | 3589 | */ |
3663 | else | ||
3664 | brcms_b_mctrl(wlc->hw, MCTL_BCNS_PROMISC, 0); | ||
3665 | } | ||
3666 | |||
3667 | void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, bool promisc) | ||
3668 | { | ||
3669 | wlc->bcnmisc_monitor = promisc; | ||
3670 | brcms_c_mac_bcn_promisc(wlc); | ||
3671 | } | ||
3672 | |||
3673 | /* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */ | ||
3674 | static void brcms_c_mac_promisc(struct brcms_c_info *wlc) | 3590 | static void brcms_c_mac_promisc(struct brcms_c_info *wlc) |
3675 | { | 3591 | { |
3676 | u32 promisc_bits = 0; | 3592 | u32 promisc_bits = 0; |
3677 | 3593 | ||
3678 | /* | 3594 | if (wlc->bcnmisc_monitor) |
3679 | * promiscuous mode just sets MCTL_PROMISC | 3595 | promisc_bits |= MCTL_BCNS_PROMISC; |
3680 | * Note: APs get all BSS traffic without the need to set | ||
3681 | * the MCTL_PROMISC bit since all BSS data traffic is | ||
3682 | * directed at the AP | ||
3683 | */ | ||
3684 | if (wlc->pub->promisc) | ||
3685 | promisc_bits |= MCTL_PROMISC; | ||
3686 | 3596 | ||
3687 | /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL | ||
3688 | * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is | ||
3689 | * handled in brcms_c_mac_bcn_promisc() | ||
3690 | */ | ||
3691 | if (wlc->monitor) | 3597 | if (wlc->monitor) |
3692 | promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL; | 3598 | promisc_bits |= |
3599 | MCTL_PROMISC | MCTL_BCNS_PROMISC | MCTL_KEEPCONTROL; | ||
3693 | 3600 | ||
3694 | brcms_b_mctrl(wlc->hw, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits); | 3601 | brcms_b_mctrl(wlc->hw, |
3602 | MCTL_PROMISC | MCTL_BCNS_PROMISC | MCTL_KEEPCONTROL, | ||
3603 | promisc_bits); | ||
3604 | } | ||
3605 | |||
3606 | void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, bool promisc) | ||
3607 | { | ||
3608 | wlc->bcnmisc_monitor = promisc; | ||
3609 | brcms_c_mac_promisc(wlc); | ||
3695 | } | 3610 | } |
3696 | 3611 | ||
3697 | /* | 3612 | /* |
@@ -3723,7 +3638,6 @@ static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc) | |||
3723 | } | 3638 | } |
3724 | 3639 | ||
3725 | /* update the various promisc bits */ | 3640 | /* update the various promisc bits */ |
3726 | brcms_c_mac_bcn_promisc(wlc); | ||
3727 | brcms_c_mac_promisc(wlc); | 3641 | brcms_c_mac_promisc(wlc); |
3728 | } | 3642 | } |
3729 | 3643 | ||
@@ -3979,7 +3893,7 @@ static void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec) | |||
3979 | 3893 | ||
3980 | void | 3894 | void |
3981 | brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, | 3895 | brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, |
3982 | bool mute, struct txpwr_limits *txpwr) | 3896 | bool mute_tx, struct txpwr_limits *txpwr) |
3983 | { | 3897 | { |
3984 | uint bandunit; | 3898 | uint bandunit; |
3985 | 3899 | ||
@@ -4005,7 +3919,7 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, | |||
4005 | } | 3919 | } |
4006 | } | 3920 | } |
4007 | 3921 | ||
4008 | wlc_phy_initcal_enable(wlc_hw->band->pi, !mute); | 3922 | wlc_phy_initcal_enable(wlc_hw->band->pi, !mute_tx); |
4009 | 3923 | ||
4010 | if (!wlc_hw->up) { | 3924 | if (!wlc_hw->up) { |
4011 | if (wlc_hw->clk) | 3925 | if (wlc_hw->clk) |
@@ -4017,7 +3931,7 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, | |||
4017 | wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec); | 3931 | wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec); |
4018 | 3932 | ||
4019 | /* Update muting of the channel */ | 3933 | /* Update muting of the channel */ |
4020 | brcms_b_mute(wlc_hw, mute, 0); | 3934 | brcms_b_mute(wlc_hw, mute_tx); |
4021 | } | 3935 | } |
4022 | } | 3936 | } |
4023 | 3937 | ||
@@ -4205,7 +4119,7 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, | |||
4205 | EDCF_TXOP2USEC(acp_shm.txop); | 4119 | EDCF_TXOP2USEC(acp_shm.txop); |
4206 | acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK); | 4120 | acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK); |
4207 | 4121 | ||
4208 | if (aci == AC_VI && acp_shm.txop == 0 | 4122 | if (aci == IEEE80211_AC_VI && acp_shm.txop == 0 |
4209 | && acp_shm.aifs < EDCF_AIFSN_MAX) | 4123 | && acp_shm.aifs < EDCF_AIFSN_MAX) |
4210 | acp_shm.aifs++; | 4124 | acp_shm.aifs++; |
4211 | 4125 | ||
@@ -4242,7 +4156,7 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, | |||
4242 | } | 4156 | } |
4243 | } | 4157 | } |
4244 | 4158 | ||
4245 | void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) | 4159 | static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) |
4246 | { | 4160 | { |
4247 | u16 aci; | 4161 | u16 aci; |
4248 | int i_ac; | 4162 | int i_ac; |
@@ -4255,7 +4169,7 @@ void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) | |||
4255 | }; /* ucode needs these parameters during its initialization */ | 4169 | }; /* ucode needs these parameters during its initialization */ |
4256 | const struct edcf_acparam *edcf_acp = &default_edcf_acparams[0]; | 4170 | const struct edcf_acparam *edcf_acp = &default_edcf_acparams[0]; |
4257 | 4171 | ||
4258 | for (i_ac = 0; i_ac < AC_COUNT; i_ac++, edcf_acp++) { | 4172 | for (i_ac = 0; i_ac < IEEE80211_NUM_ACS; i_ac++, edcf_acp++) { |
4259 | /* find out which ac this set of params applies to */ | 4173 | /* find out which ac this set of params applies to */ |
4260 | aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; | 4174 | aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; |
4261 | 4175 | ||
@@ -4277,17 +4191,6 @@ void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) | |||
4277 | } | 4191 | } |
4278 | } | 4192 | } |
4279 | 4193 | ||
4280 | /* maintain LED behavior in down state */ | ||
4281 | static void brcms_c_down_led_upd(struct brcms_c_info *wlc) | ||
4282 | { | ||
4283 | /* | ||
4284 | * maintain LEDs while in down state, turn on sbclk if | ||
4285 | * not available yet. Turn on sbclk if necessary | ||
4286 | */ | ||
4287 | brcms_b_pllreq(wlc->hw, true, BRCMS_PLLREQ_FLIP); | ||
4288 | brcms_b_pllreq(wlc->hw, false, BRCMS_PLLREQ_FLIP); | ||
4289 | } | ||
4290 | |||
4291 | static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc) | 4194 | static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc) |
4292 | { | 4195 | { |
4293 | /* Don't start the timer if HWRADIO feature is disabled */ | 4196 | /* Don't start the timer if HWRADIO feature is disabled */ |
@@ -4299,28 +4202,6 @@ static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc) | |||
4299 | brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); | 4202 | brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); |
4300 | } | 4203 | } |
4301 | 4204 | ||
4302 | static void brcms_c_radio_disable(struct brcms_c_info *wlc) | ||
4303 | { | ||
4304 | if (!wlc->pub->up) { | ||
4305 | brcms_c_down_led_upd(wlc); | ||
4306 | return; | ||
4307 | } | ||
4308 | |||
4309 | brcms_c_radio_monitor_start(wlc); | ||
4310 | brcms_down(wlc->wl); | ||
4311 | } | ||
4312 | |||
4313 | static void brcms_c_radio_enable(struct brcms_c_info *wlc) | ||
4314 | { | ||
4315 | if (wlc->pub->up) | ||
4316 | return; | ||
4317 | |||
4318 | if (brcms_deviceremoved(wlc)) | ||
4319 | return; | ||
4320 | |||
4321 | brcms_up(wlc->wl); | ||
4322 | } | ||
4323 | |||
4324 | static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc) | 4205 | static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc) |
4325 | { | 4206 | { |
4326 | if (!wlc->radio_monitor) | 4207 | if (!wlc->radio_monitor) |
@@ -4343,18 +4224,6 @@ static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc) | |||
4343 | mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); | 4224 | mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); |
4344 | } | 4225 | } |
4345 | 4226 | ||
4346 | /* | ||
4347 | * centralized radio disable/enable function, | ||
4348 | * invoke radio enable/disable after updating hwradio status | ||
4349 | */ | ||
4350 | static void brcms_c_radio_upd(struct brcms_c_info *wlc) | ||
4351 | { | ||
4352 | if (wlc->pub->radio_disabled) | ||
4353 | brcms_c_radio_disable(wlc); | ||
4354 | else | ||
4355 | brcms_c_radio_enable(wlc); | ||
4356 | } | ||
4357 | |||
4358 | /* update hwradio status and return it */ | 4227 | /* update hwradio status and return it */ |
4359 | bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc) | 4228 | bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc) |
4360 | { | 4229 | { |
@@ -4376,12 +4245,7 @@ static void brcms_c_radio_timer(void *arg) | |||
4376 | return; | 4245 | return; |
4377 | } | 4246 | } |
4378 | 4247 | ||
4379 | /* cap mpc off count */ | ||
4380 | if (wlc->mpc_offcnt < BRCMS_MPC_MAX_DELAYCNT) | ||
4381 | wlc->mpc_offcnt++; | ||
4382 | |||
4383 | brcms_c_radio_hwdisable_upd(wlc); | 4248 | brcms_c_radio_hwdisable_upd(wlc); |
4384 | brcms_c_radio_upd(wlc); | ||
4385 | } | 4249 | } |
4386 | 4250 | ||
4387 | /* common low-level watchdog code */ | 4251 | /* common low-level watchdog code */ |
@@ -4407,60 +4271,6 @@ static void brcms_b_watchdog(void *arg) | |||
4407 | wlc_phy_watchdog(wlc_hw->band->pi); | 4271 | wlc_phy_watchdog(wlc_hw->band->pi); |
4408 | } | 4272 | } |
4409 | 4273 | ||
4410 | static void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc) | ||
4411 | { | ||
4412 | bool mpc_radio, radio_state; | ||
4413 | |||
4414 | /* | ||
4415 | * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled | ||
4416 | * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio | ||
4417 | * monitor also when WL_RADIO_MPC_DISABLE is the only reason that | ||
4418 | * the radio is going down. | ||
4419 | */ | ||
4420 | if (!wlc->mpc) { | ||
4421 | if (!wlc->pub->radio_disabled) | ||
4422 | return; | ||
4423 | mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); | ||
4424 | brcms_c_radio_upd(wlc); | ||
4425 | if (!wlc->pub->radio_disabled) | ||
4426 | brcms_c_radio_monitor_stop(wlc); | ||
4427 | return; | ||
4428 | } | ||
4429 | |||
4430 | /* | ||
4431 | * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in | ||
4432 | * wlc->pub->radio_disabled to go ON, always call radio_upd | ||
4433 | * synchronously to go OFF, postpone radio_upd to later when | ||
4434 | * context is safe(e.g. watchdog) | ||
4435 | */ | ||
4436 | radio_state = | ||
4437 | (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF : | ||
4438 | ON); | ||
4439 | mpc_radio = (brcms_c_ismpc(wlc) == true) ? OFF : ON; | ||
4440 | |||
4441 | if (radio_state == ON && mpc_radio == OFF) | ||
4442 | wlc->mpc_delay_off = wlc->mpc_dlycnt; | ||
4443 | else if (radio_state == OFF && mpc_radio == ON) { | ||
4444 | mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); | ||
4445 | brcms_c_radio_upd(wlc); | ||
4446 | if (wlc->mpc_offcnt < BRCMS_MPC_THRESHOLD) | ||
4447 | wlc->mpc_dlycnt = BRCMS_MPC_MAX_DELAYCNT; | ||
4448 | else | ||
4449 | wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT; | ||
4450 | } | ||
4451 | /* | ||
4452 | * Below logic is meant to capture the transition from mpc off | ||
4453 | * to mpc on for reasons other than wlc->mpc_delay_off keeping | ||
4454 | * the mpc off. In that case reset wlc->mpc_delay_off to | ||
4455 | * wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off | ||
4456 | */ | ||
4457 | if ((wlc->prev_non_delay_mpc == false) && | ||
4458 | (brcms_c_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) | ||
4459 | wlc->mpc_delay_off = wlc->mpc_dlycnt; | ||
4460 | |||
4461 | wlc->prev_non_delay_mpc = brcms_c_is_non_delay_mpc(wlc); | ||
4462 | } | ||
4463 | |||
4464 | /* common watchdog code */ | 4274 | /* common watchdog code */ |
4465 | static void brcms_c_watchdog(void *arg) | 4275 | static void brcms_c_watchdog(void *arg) |
4466 | { | 4276 | { |
@@ -4481,21 +4291,7 @@ static void brcms_c_watchdog(void *arg) | |||
4481 | /* increment second count */ | 4291 | /* increment second count */ |
4482 | wlc->pub->now++; | 4292 | wlc->pub->now++; |
4483 | 4293 | ||
4484 | /* delay radio disable */ | ||
4485 | if (wlc->mpc_delay_off) { | ||
4486 | if (--wlc->mpc_delay_off == 0) { | ||
4487 | mboolset(wlc->pub->radio_disabled, | ||
4488 | WL_RADIO_MPC_DISABLE); | ||
4489 | if (wlc->mpc && brcms_c_ismpc(wlc)) | ||
4490 | wlc->mpc_offcnt = 0; | ||
4491 | } | ||
4492 | } | ||
4493 | |||
4494 | /* mpc sync */ | ||
4495 | brcms_c_radio_mpc_upd(wlc); | ||
4496 | /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */ | ||
4497 | brcms_c_radio_hwdisable_upd(wlc); | 4294 | brcms_c_radio_hwdisable_upd(wlc); |
4498 | brcms_c_radio_upd(wlc); | ||
4499 | /* if radio is disable, driver may be down, quit here */ | 4295 | /* if radio is disable, driver may be down, quit here */ |
4500 | if (wlc->pub->radio_disabled) | 4296 | if (wlc->pub->radio_disabled) |
4501 | return; | 4297 | return; |
@@ -4599,9 +4395,6 @@ static void brcms_c_info_init(struct brcms_c_info *wlc, int unit) | |||
4599 | /* WME QoS mode is Auto by default */ | 4395 | /* WME QoS mode is Auto by default */ |
4600 | wlc->pub->_ampdu = AMPDU_AGG_HOST; | 4396 | wlc->pub->_ampdu = AMPDU_AGG_HOST; |
4601 | wlc->pub->bcmerror = 0; | 4397 | wlc->pub->bcmerror = 0; |
4602 | |||
4603 | /* initialize mpc delay */ | ||
4604 | wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT; | ||
4605 | } | 4398 | } |
4606 | 4399 | ||
4607 | static uint brcms_c_attach_module(struct brcms_c_info *wlc) | 4400 | static uint brcms_c_attach_module(struct brcms_c_info *wlc) |
@@ -5259,9 +5052,6 @@ static void brcms_c_ap_upd(struct brcms_c_info *wlc) | |||
5259 | { | 5052 | { |
5260 | /* STA-BSS; short capable */ | 5053 | /* STA-BSS; short capable */ |
5261 | wlc->PLCPHdr_override = BRCMS_PLCP_SHORT; | 5054 | wlc->PLCPHdr_override = BRCMS_PLCP_SHORT; |
5262 | |||
5263 | /* fixup mpc */ | ||
5264 | wlc->mpc = true; | ||
5265 | } | 5055 | } |
5266 | 5056 | ||
5267 | /* Initialize just the hardware when coming out of POR or S3/S5 system states */ | 5057 | /* Initialize just the hardware when coming out of POR or S3/S5 system states */ |
@@ -5376,7 +5166,7 @@ static void brcms_c_wme_retries_write(struct brcms_c_info *wlc) | |||
5376 | if (!wlc->clk) | 5166 | if (!wlc->clk) |
5377 | return; | 5167 | return; |
5378 | 5168 | ||
5379 | for (ac = 0; ac < AC_COUNT; ac++) | 5169 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |
5380 | brcms_b_write_shm(wlc->hw, M_AC_TXLMT_ADDR(ac), | 5170 | brcms_b_write_shm(wlc->hw, M_AC_TXLMT_ADDR(ac), |
5381 | wlc->wme_retries[ac]); | 5171 | wlc->wme_retries[ac]); |
5382 | } | 5172 | } |
@@ -5575,7 +5365,6 @@ uint brcms_c_down(struct brcms_c_info *wlc) | |||
5575 | if (!wlc->pub->up) | 5365 | if (!wlc->pub->up) |
5576 | return callbacks; | 5366 | return callbacks; |
5577 | 5367 | ||
5578 | /* in between, mpc could try to bring down again.. */ | ||
5579 | wlc->going_down = true; | 5368 | wlc->going_down = true; |
5580 | 5369 | ||
5581 | callbacks += brcms_b_bmac_down_prep(wlc->hw); | 5370 | callbacks += brcms_b_bmac_down_prep(wlc->hw); |
@@ -5852,7 +5641,7 @@ int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl) | |||
5852 | 5641 | ||
5853 | brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); | 5642 | brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); |
5854 | 5643 | ||
5855 | for (ac = 0; ac < AC_COUNT; ac++) { | 5644 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
5856 | wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], | 5645 | wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], |
5857 | EDCF_SHORT, wlc->SRL); | 5646 | EDCF_SHORT, wlc->SRL); |
5858 | wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], | 5647 | wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], |
@@ -6103,7 +5892,6 @@ void brcms_c_print_txdesc(struct d11txh *txh) | |||
6103 | 5892 | ||
6104 | u8 *rtsph = txh->RTSPhyHeader; | 5893 | u8 *rtsph = txh->RTSPhyHeader; |
6105 | struct ieee80211_rts rts = txh->rts_frame; | 5894 | struct ieee80211_rts rts = txh->rts_frame; |
6106 | char hexbuf[256]; | ||
6107 | 5895 | ||
6108 | /* add plcp header along with txh descriptor */ | 5896 | /* add plcp header along with txh descriptor */ |
6109 | printk(KERN_DEBUG "Raw TxDesc + plcp header:\n"); | 5897 | printk(KERN_DEBUG "Raw TxDesc + plcp header:\n"); |
@@ -6124,17 +5912,16 @@ void brcms_c_print_txdesc(struct d11txh *txh) | |||
6124 | printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft); | 5912 | printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft); |
6125 | printk(KERN_DEBUG "\n"); | 5913 | printk(KERN_DEBUG "\n"); |
6126 | 5914 | ||
6127 | brcmu_format_hex(hexbuf, iv, sizeof(txh->IV)); | 5915 | print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV)); |
6128 | printk(KERN_DEBUG "SecIV: %s\n", hexbuf); | 5916 | print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET, |
6129 | brcmu_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); | 5917 | ra, sizeof(txh->TxFrameRA)); |
6130 | printk(KERN_DEBUG "RA: %s\n", hexbuf); | ||
6131 | 5918 | ||
6132 | printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb); | 5919 | printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb); |
6133 | brcmu_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); | 5920 | print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET, |
6134 | printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); | 5921 | rtspfb, sizeof(txh->RTSPLCPFallback)); |
6135 | printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb); | 5922 | printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb); |
6136 | brcmu_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); | 5923 | print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET, |
6137 | printk(KERN_DEBUG "PLCP: %s ", hexbuf); | 5924 | fragpfb, sizeof(txh->FragPLCPFallback)); |
6138 | printk(KERN_DEBUG "DUR: %04x", fragdfb); | 5925 | printk(KERN_DEBUG "DUR: %04x", fragdfb); |
6139 | printk(KERN_DEBUG "\n"); | 5926 | printk(KERN_DEBUG "\n"); |
6140 | 5927 | ||
@@ -6149,18 +5936,18 @@ void brcms_c_print_txdesc(struct d11txh *txh) | |||
6149 | printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f); | 5936 | printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f); |
6150 | printk(KERN_DEBUG "MinByte: %04x\n", mmbyte); | 5937 | printk(KERN_DEBUG "MinByte: %04x\n", mmbyte); |
6151 | 5938 | ||
6152 | brcmu_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); | 5939 | print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET, |
6153 | printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); | 5940 | rtsph, sizeof(txh->RTSPhyHeader)); |
6154 | brcmu_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); | 5941 | print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET, |
6155 | printk(KERN_DEBUG "RTS Frame: %s", hexbuf); | 5942 | (u8 *)&rts, sizeof(txh->rts_frame)); |
6156 | printk(KERN_DEBUG "\n"); | 5943 | printk(KERN_DEBUG "\n"); |
6157 | } | 5944 | } |
6158 | #endif /* defined(BCMDBG) */ | 5945 | #endif /* defined(BCMDBG) */ |
6159 | 5946 | ||
6160 | #if defined(BCMDBG) | 5947 | #if defined(BCMDBG) |
6161 | int | 5948 | static int |
6162 | brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, | 5949 | brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, |
6163 | int len) | 5950 | int len) |
6164 | { | 5951 | { |
6165 | int i; | 5952 | int i; |
6166 | char *p = buf; | 5953 | char *p = buf; |
@@ -6916,7 +6703,7 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, | |||
6916 | qos = ieee80211_is_data_qos(h->frame_control); | 6703 | qos = ieee80211_is_data_qos(h->frame_control); |
6917 | 6704 | ||
6918 | /* compute length of frame in bytes for use in PLCP computations */ | 6705 | /* compute length of frame in bytes for use in PLCP computations */ |
6919 | len = brcmu_pkttotlen(p); | 6706 | len = p->len; |
6920 | phylen = len + FCS_LEN; | 6707 | phylen = len + FCS_LEN; |
6921 | 6708 | ||
6922 | /* Get tx_info */ | 6709 | /* Get tx_info */ |
@@ -8253,12 +8040,6 @@ int brcms_c_get_tx_power(struct brcms_c_info *wlc) | |||
8253 | return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR); | 8040 | return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR); |
8254 | } | 8041 | } |
8255 | 8042 | ||
8256 | void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc) | ||
8257 | { | ||
8258 | wlc->mpc = mpc; | ||
8259 | brcms_c_radio_mpc_upd(wlc); | ||
8260 | } | ||
8261 | |||
8262 | /* Process received frames */ | 8043 | /* Process received frames */ |
8263 | /* | 8044 | /* |
8264 | * Return true if more frames need to be processed. false otherwise. | 8045 | * Return true if more frames need to be processed. false otherwise. |
@@ -8328,21 +8109,17 @@ static bool | |||
8328 | brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) | 8109 | brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) |
8329 | { | 8110 | { |
8330 | struct sk_buff *p; | 8111 | struct sk_buff *p; |
8331 | struct sk_buff *head = NULL; | 8112 | struct sk_buff *next = NULL; |
8332 | struct sk_buff *tail = NULL; | 8113 | struct sk_buff_head recv_frames; |
8114 | |||
8333 | uint n = 0; | 8115 | uint n = 0; |
8334 | uint bound_limit = bound ? RXBND : -1; | 8116 | uint bound_limit = bound ? RXBND : -1; |
8335 | 8117 | ||
8336 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 8118 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); |
8337 | /* gather received frames */ | 8119 | skb_queue_head_init(&recv_frames); |
8338 | while ((p = dma_rx(wlc_hw->di[fifo]))) { | ||
8339 | 8120 | ||
8340 | if (!tail) | 8121 | /* gather received frames */ |
8341 | head = tail = p; | 8122 | while (dma_rx(wlc_hw->di[fifo], &recv_frames)) { |
8342 | else { | ||
8343 | tail->prev = p; | ||
8344 | tail = p; | ||
8345 | } | ||
8346 | 8123 | ||
8347 | /* !give others some time to run! */ | 8124 | /* !give others some time to run! */ |
8348 | if (++n >= bound_limit) | 8125 | if (++n >= bound_limit) |
@@ -8353,12 +8130,11 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) | |||
8353 | dma_rxfill(wlc_hw->di[fifo]); | 8130 | dma_rxfill(wlc_hw->di[fifo]); |
8354 | 8131 | ||
8355 | /* process each frame */ | 8132 | /* process each frame */ |
8356 | while ((p = head) != NULL) { | 8133 | skb_queue_walk_safe(&recv_frames, p, next) { |
8357 | struct d11rxhdr_le *rxh_le; | 8134 | struct d11rxhdr_le *rxh_le; |
8358 | struct d11rxhdr *rxh; | 8135 | struct d11rxhdr *rxh; |
8359 | head = head->prev; | ||
8360 | p->prev = NULL; | ||
8361 | 8136 | ||
8137 | skb_unlink(p, &recv_frames); | ||
8362 | rxh_le = (struct d11rxhdr_le *)p->data; | 8138 | rxh_le = (struct d11rxhdr_le *)p->data; |
8363 | rxh = (struct d11rxhdr *)p->data; | 8139 | rxh = (struct d11rxhdr *)p->data; |
8364 | 8140 | ||
@@ -8448,8 +8224,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8448 | printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", | 8224 | printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", |
8449 | __func__, wlc_hw->sih->chip, | 8225 | __func__, wlc_hw->sih->chip, |
8450 | wlc_hw->sih->chiprev); | 8226 | wlc_hw->sih->chiprev); |
8451 | /* big hammer */ | 8227 | brcms_fatal_error(wlc_hw->wlc->wl); |
8452 | brcms_init(wlc->wl); | ||
8453 | } | 8228 | } |
8454 | 8229 | ||
8455 | /* gptimer timeout */ | 8230 | /* gptimer timeout */ |
@@ -8470,15 +8245,14 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8470 | return wlc->macintstatus != 0; | 8245 | return wlc->macintstatus != 0; |
8471 | 8246 | ||
8472 | fatal: | 8247 | fatal: |
8473 | brcms_init(wlc->wl); | 8248 | brcms_fatal_error(wlc_hw->wlc->wl); |
8474 | return wlc->macintstatus != 0; | 8249 | return wlc->macintstatus != 0; |
8475 | } | 8250 | } |
8476 | 8251 | ||
8477 | void brcms_c_init(struct brcms_c_info *wlc) | 8252 | void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) |
8478 | { | 8253 | { |
8479 | struct d11regs __iomem *regs; | 8254 | struct d11regs __iomem *regs; |
8480 | u16 chanspec; | 8255 | u16 chanspec; |
8481 | bool mute = false; | ||
8482 | 8256 | ||
8483 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | 8257 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); |
8484 | 8258 | ||
@@ -8494,7 +8268,7 @@ void brcms_c_init(struct brcms_c_info *wlc) | |||
8494 | else | 8268 | else |
8495 | chanspec = brcms_c_init_chanspec(wlc); | 8269 | chanspec = brcms_c_init_chanspec(wlc); |
8496 | 8270 | ||
8497 | brcms_b_init(wlc->hw, chanspec, mute); | 8271 | brcms_b_init(wlc->hw, chanspec); |
8498 | 8272 | ||
8499 | /* update beacon listen interval */ | 8273 | /* update beacon listen interval */ |
8500 | brcms_c_bcn_li_upd(wlc); | 8274 | brcms_c_bcn_li_upd(wlc); |
@@ -8560,15 +8334,16 @@ void brcms_c_init(struct brcms_c_info *wlc) | |||
8560 | /* ..now really unleash hell (allow the MAC out of suspend) */ | 8334 | /* ..now really unleash hell (allow the MAC out of suspend) */ |
8561 | brcms_c_enable_mac(wlc); | 8335 | brcms_c_enable_mac(wlc); |
8562 | 8336 | ||
8337 | /* suspend the tx fifos and mute the phy for preism cac time */ | ||
8338 | if (mute_tx) | ||
8339 | brcms_b_mute(wlc->hw, true); | ||
8340 | |||
8563 | /* clear tx flow control */ | 8341 | /* clear tx flow control */ |
8564 | brcms_c_txflowcontrol_reset(wlc); | 8342 | brcms_c_txflowcontrol_reset(wlc); |
8565 | 8343 | ||
8566 | /* enable the RF Disable Delay timer */ | 8344 | /* enable the RF Disable Delay timer */ |
8567 | W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); | 8345 | W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); |
8568 | 8346 | ||
8569 | /* initialize mpc delay */ | ||
8570 | wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT; | ||
8571 | |||
8572 | /* | 8347 | /* |
8573 | * Initialize WME parameters; if they haven't been set by some other | 8348 | * Initialize WME parameters; if they haven't been set by some other |
8574 | * mechanism (IOVar, etc) then read them from the hardware. | 8349 | * mechanism (IOVar, etc) then read them from the hardware. |
@@ -8577,7 +8352,7 @@ void brcms_c_init(struct brcms_c_info *wlc) | |||
8577 | /* Uninitialized; read from HW */ | 8352 | /* Uninitialized; read from HW */ |
8578 | int ac; | 8353 | int ac; |
8579 | 8354 | ||
8580 | for (ac = 0; ac < AC_COUNT; ac++) | 8355 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |
8581 | wlc->wme_retries[ac] = | 8356 | wlc->wme_retries[ac] = |
8582 | brcms_b_read_shm(wlc->hw, M_AC_TXLMT_ADDR(ac)); | 8357 | brcms_b_read_shm(wlc->hw, M_AC_TXLMT_ADDR(ac)); |
8583 | } | 8358 | } |
@@ -8754,8 +8529,6 @@ brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit, | |||
8754 | brcms_c_ht_update_sgi_rx(wlc, 0); | 8529 | brcms_c_ht_update_sgi_rx(wlc, 0); |
8755 | } | 8530 | } |
8756 | 8531 | ||
8757 | /* initialize radio_mpc_disable according to wlc->mpc */ | ||
8758 | brcms_c_radio_mpc_upd(wlc); | ||
8759 | brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail); | 8532 | brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail); |
8760 | 8533 | ||
8761 | if (perr) | 8534 | if (perr) |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h index c0e0fcfdfaf8..251c350b3164 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h | |||
@@ -44,8 +44,6 @@ | |||
44 | /* transmit buffer max headroom for protocol headers */ | 44 | /* transmit buffer max headroom for protocol headers */ |
45 | #define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN) | 45 | #define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN) |
46 | 46 | ||
47 | #define AC_COUNT 4 | ||
48 | |||
49 | /* Macros for doing definition and get/set of bitfields | 47 | /* Macros for doing definition and get/set of bitfields |
50 | * Usage example, e.g. a three-bit field (bits 4-6): | 48 | * Usage example, e.g. a three-bit field (bits 4-6): |
51 | * #define <NAME>_M BITFIELD_MASK(3) | 49 | * #define <NAME>_M BITFIELD_MASK(3) |
@@ -427,11 +425,6 @@ struct brcms_txq_info { | |||
427 | * bandinit_pending: track band init in auto band. | 425 | * bandinit_pending: track band init in auto band. |
428 | * radio_monitor: radio timer is running. | 426 | * radio_monitor: radio timer is running. |
429 | * going_down: down path intermediate variable. | 427 | * going_down: down path intermediate variable. |
430 | * mpc: enable minimum power consumption. | ||
431 | * mpc_dlycnt: # of watchdog cnt before turn disable radio. | ||
432 | * mpc_offcnt: # of watchdog cnt that radio is disabled. | ||
433 | * mpc_delay_off: delay radio disable by # of watchdog cnt. | ||
434 | * prev_non_delay_mpc: prev state brcms_c_is_non_delay_mpc. | ||
435 | * wdtimer: timer for watchdog routine. | 428 | * wdtimer: timer for watchdog routine. |
436 | * radio_timer: timer for hw radio button monitor routine. | 429 | * radio_timer: timer for hw radio button monitor routine. |
437 | * monitor: monitor (MPDU sniffing) mode. | 430 | * monitor: monitor (MPDU sniffing) mode. |
@@ -441,7 +434,7 @@ struct brcms_txq_info { | |||
441 | * bcn_li_dtim: beacon listen interval in # dtims. | 434 | * bcn_li_dtim: beacon listen interval in # dtims. |
442 | * WDarmed: watchdog timer is armed. | 435 | * WDarmed: watchdog timer is armed. |
443 | * WDlast: last time wlc_watchdog() was called. | 436 | * WDlast: last time wlc_watchdog() was called. |
444 | * edcf_txop[AC_COUNT]: current txop for each ac. | 437 | * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac. |
445 | * wme_retries: per-AC retry limits. | 438 | * wme_retries: per-AC retry limits. |
446 | * tx_prec_map: Precedence map based on HW FIFO space. | 439 | * tx_prec_map: Precedence map based on HW FIFO space. |
447 | * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME. | 440 | * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME. |
@@ -522,12 +515,6 @@ struct brcms_c_info { | |||
522 | bool radio_monitor; | 515 | bool radio_monitor; |
523 | bool going_down; | 516 | bool going_down; |
524 | 517 | ||
525 | bool mpc; | ||
526 | u8 mpc_dlycnt; | ||
527 | u8 mpc_offcnt; | ||
528 | u8 mpc_delay_off; | ||
529 | u8 prev_non_delay_mpc; | ||
530 | |||
531 | struct brcms_timer *wdtimer; | 518 | struct brcms_timer *wdtimer; |
532 | struct brcms_timer *radio_timer; | 519 | struct brcms_timer *radio_timer; |
533 | 520 | ||
@@ -546,9 +533,9 @@ struct brcms_c_info { | |||
546 | u32 WDlast; | 533 | u32 WDlast; |
547 | 534 | ||
548 | /* WME */ | 535 | /* WME */ |
549 | u16 edcf_txop[AC_COUNT]; | 536 | u16 edcf_txop[IEEE80211_NUM_ACS]; |
550 | 537 | ||
551 | u16 wme_retries[AC_COUNT]; | 538 | u16 wme_retries[IEEE80211_NUM_ACS]; |
552 | u16 tx_prec_map; | 539 | u16 tx_prec_map; |
553 | u16 fifo2prec_map[NFIFO]; | 540 | u16 fifo2prec_map[NFIFO]; |
554 | 541 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c index a3149254cbcd..e17edf7e6833 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c | |||
@@ -112,7 +112,7 @@ static const struct chan_info_basic chan_info_all[] = { | |||
112 | {216, 50800} | 112 | {216, 50800} |
113 | }; | 113 | }; |
114 | 114 | ||
115 | const u8 ofdm_rate_lookup[] = { | 115 | static const u8 ofdm_rate_lookup[] = { |
116 | 116 | ||
117 | BRCM_RATE_48M, | 117 | BRCM_RATE_48M, |
118 | BRCM_RATE_24M, | 118 | BRCM_RATE_24M, |
@@ -190,15 +190,7 @@ u16 read_radio_reg(struct brcms_phy *pi, u16 addr) | |||
190 | data = R_REG(&pi->regs->radioregdata); | 190 | data = R_REG(&pi->regs->radioregdata); |
191 | } else { | 191 | } else { |
192 | W_REG_FLUSH(&pi->regs->phy4waddr, addr); | 192 | W_REG_FLUSH(&pi->regs->phy4waddr, addr); |
193 | |||
194 | #ifdef __ARM_ARCH_4T__ | ||
195 | __asm__(" .align 4 "); | ||
196 | __asm__(" nop "); | ||
197 | data = R_REG(&pi->regs->phy4wdatalo); | ||
198 | #else | ||
199 | data = R_REG(&pi->regs->phy4wdatalo); | 193 | data = R_REG(&pi->regs->phy4wdatalo); |
200 | #endif | ||
201 | |||
202 | } | 194 | } |
203 | pi->phy_wreg = 0; | 195 | pi->phy_wreg = 0; |
204 | 196 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h index bea85241a244..5f9478b1c993 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h | |||
@@ -774,11 +774,6 @@ struct brcms_phy { | |||
774 | s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ]; | 774 | s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ]; |
775 | u8 nphy_noise_index; | 775 | u8 nphy_noise_index; |
776 | 776 | ||
777 | u8 nphy_txpid2g[PHY_CORE_NUM_2]; | ||
778 | u8 nphy_txpid5g[PHY_CORE_NUM_2]; | ||
779 | u8 nphy_txpid5gl[PHY_CORE_NUM_2]; | ||
780 | u8 nphy_txpid5gh[PHY_CORE_NUM_2]; | ||
781 | |||
782 | bool nphy_gain_boost; | 777 | bool nphy_gain_boost; |
783 | bool nphy_elna_gain_config; | 778 | bool nphy_elna_gain_config; |
784 | u16 old_bphy_test; | 779 | u16 old_bphy_test; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c index cd19c2f7a347..ec9b56639d54 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "phy_radio.h" | 29 | #include "phy_radio.h" |
30 | #include "phyreg_n.h" | 30 | #include "phyreg_n.h" |
31 | #include "phytbl_n.h" | 31 | #include "phytbl_n.h" |
32 | #include "soc.h" | ||
32 | 33 | ||
33 | #define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \ | 34 | #define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \ |
34 | read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ | 35 | read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ |
@@ -14417,12 +14418,6 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) | |||
14417 | switch (band_num) { | 14418 | switch (band_num) { |
14418 | case 0: | 14419 | case 0: |
14419 | 14420 | ||
14420 | pi->nphy_txpid2g[PHY_CORE_0] = | ||
14421 | (u8) wlapi_getintvar(shim, | ||
14422 | BRCMS_SROM_TXPID2GA0); | ||
14423 | pi->nphy_txpid2g[PHY_CORE_1] = | ||
14424 | (u8) wlapi_getintvar(shim, | ||
14425 | BRCMS_SROM_TXPID2GA1); | ||
14426 | pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g = | 14421 | pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g = |
14427 | (s8) wlapi_getintvar(shim, | 14422 | (s8) wlapi_getintvar(shim, |
14428 | BRCMS_SROM_MAXP2GA0); | 14423 | BRCMS_SROM_MAXP2GA0); |
@@ -14486,12 +14481,6 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) | |||
14486 | break; | 14481 | break; |
14487 | case 1: | 14482 | case 1: |
14488 | 14483 | ||
14489 | pi->nphy_txpid5g[PHY_CORE_0] = | ||
14490 | (u8) wlapi_getintvar(shim, | ||
14491 | BRCMS_SROM_TXPID5GA0); | ||
14492 | pi->nphy_txpid5g[PHY_CORE_1] = | ||
14493 | (u8) wlapi_getintvar(shim, | ||
14494 | BRCMS_SROM_TXPID5GA1); | ||
14495 | pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm = | 14484 | pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm = |
14496 | (s8) wlapi_getintvar(shim, BRCMS_SROM_MAXP5GA0); | 14485 | (s8) wlapi_getintvar(shim, BRCMS_SROM_MAXP5GA0); |
14497 | pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm = | 14486 | pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm = |
@@ -14551,12 +14540,6 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) | |||
14551 | break; | 14540 | break; |
14552 | case 2: | 14541 | case 2: |
14553 | 14542 | ||
14554 | pi->nphy_txpid5gl[0] = | ||
14555 | (u8) wlapi_getintvar(shim, | ||
14556 | BRCMS_SROM_TXPID5GLA0); | ||
14557 | pi->nphy_txpid5gl[1] = | ||
14558 | (u8) wlapi_getintvar(shim, | ||
14559 | BRCMS_SROM_TXPID5GLA1); | ||
14560 | pi->nphy_pwrctrl_info[0].max_pwr_5gl = | 14543 | pi->nphy_pwrctrl_info[0].max_pwr_5gl = |
14561 | (s8) wlapi_getintvar(shim, | 14544 | (s8) wlapi_getintvar(shim, |
14562 | BRCMS_SROM_MAXP5GLA0); | 14545 | BRCMS_SROM_MAXP5GLA0); |
@@ -14615,12 +14598,6 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) | |||
14615 | break; | 14598 | break; |
14616 | case 3: | 14599 | case 3: |
14617 | 14600 | ||
14618 | pi->nphy_txpid5gh[0] = | ||
14619 | (u8) wlapi_getintvar(shim, | ||
14620 | BRCMS_SROM_TXPID5GHA0); | ||
14621 | pi->nphy_txpid5gh[1] = | ||
14622 | (u8) wlapi_getintvar(shim, | ||
14623 | BRCMS_SROM_TXPID5GHA1); | ||
14624 | pi->nphy_pwrctrl_info[0].max_pwr_5gh = | 14601 | pi->nphy_pwrctrl_info[0].max_pwr_5gh = |
14625 | (s8) wlapi_getintvar(shim, | 14602 | (s8) wlapi_getintvar(shim, |
14626 | BRCMS_SROM_MAXP5GHA0); | 14603 | BRCMS_SROM_MAXP5GHA0); |
@@ -27994,20 +27971,11 @@ void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi) | |||
27994 | chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0); | 27971 | chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0); |
27995 | switch (chan_freq_range) { | 27972 | switch (chan_freq_range) { |
27996 | case WL_CHAN_FREQ_RANGE_2G: | 27973 | case WL_CHAN_FREQ_RANGE_2G: |
27997 | txpi[0] = pi->nphy_txpid2g[0]; | ||
27998 | txpi[1] = pi->nphy_txpid2g[1]; | ||
27999 | break; | ||
28000 | case WL_CHAN_FREQ_RANGE_5GL: | 27974 | case WL_CHAN_FREQ_RANGE_5GL: |
28001 | txpi[0] = pi->nphy_txpid5gl[0]; | ||
28002 | txpi[1] = pi->nphy_txpid5gl[1]; | ||
28003 | break; | ||
28004 | case WL_CHAN_FREQ_RANGE_5GM: | 27975 | case WL_CHAN_FREQ_RANGE_5GM: |
28005 | txpi[0] = pi->nphy_txpid5g[0]; | ||
28006 | txpi[1] = pi->nphy_txpid5g[1]; | ||
28007 | break; | ||
28008 | case WL_CHAN_FREQ_RANGE_5GH: | 27976 | case WL_CHAN_FREQ_RANGE_5GH: |
28009 | txpi[0] = pi->nphy_txpid5gh[0]; | 27977 | txpi[0] = 0; |
28010 | txpi[1] = pi->nphy_txpid5gh[1]; | 27978 | txpi[1] = 0; |
28011 | break; | 27979 | break; |
28012 | default: | 27980 | default: |
28013 | txpi[0] = txpi[1] = 91; | 27981 | txpi[0] = txpi[1] = 91; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.c b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c index 3b36e3acfd74..12ba575f5785 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pmu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "pub.h" | 23 | #include "pub.h" |
24 | #include "aiutils.h" | 24 | #include "aiutils.h" |
25 | #include "pmu.h" | 25 | #include "pmu.h" |
26 | #include "soc.h" | ||
26 | 27 | ||
27 | /* | 28 | /* |
28 | * external LPO crystal frequency | 29 | * external LPO crystal frequency |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h index 37bb2dcc113f..21ccf3a03987 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h | |||
@@ -170,22 +170,6 @@ enum brcms_srom_id { | |||
170 | BRCMS_SROM_TSSIPOS2G, | 170 | BRCMS_SROM_TSSIPOS2G, |
171 | BRCMS_SROM_TSSIPOS5G, | 171 | BRCMS_SROM_TSSIPOS5G, |
172 | BRCMS_SROM_TXCHAIN, | 172 | BRCMS_SROM_TXCHAIN, |
173 | BRCMS_SROM_TXPID2GA0, | ||
174 | BRCMS_SROM_TXPID2GA1, | ||
175 | BRCMS_SROM_TXPID2GA2, | ||
176 | BRCMS_SROM_TXPID2GA3, | ||
177 | BRCMS_SROM_TXPID5GA0, | ||
178 | BRCMS_SROM_TXPID5GA1, | ||
179 | BRCMS_SROM_TXPID5GA2, | ||
180 | BRCMS_SROM_TXPID5GA3, | ||
181 | BRCMS_SROM_TXPID5GHA0, | ||
182 | BRCMS_SROM_TXPID5GHA1, | ||
183 | BRCMS_SROM_TXPID5GHA2, | ||
184 | BRCMS_SROM_TXPID5GHA3, | ||
185 | BRCMS_SROM_TXPID5GLA0, | ||
186 | BRCMS_SROM_TXPID5GLA1, | ||
187 | BRCMS_SROM_TXPID5GLA2, | ||
188 | BRCMS_SROM_TXPID5GLA3, | ||
189 | /* | 173 | /* |
190 | * per-path identifiers (see srom.c) | 174 | * per-path identifiers (see srom.c) |
191 | */ | 175 | */ |
@@ -225,10 +209,6 @@ enum brcms_srom_id { | |||
225 | BRCMS_SROM_PA2GW2A1, | 209 | BRCMS_SROM_PA2GW2A1, |
226 | BRCMS_SROM_PA2GW2A2, | 210 | BRCMS_SROM_PA2GW2A2, |
227 | BRCMS_SROM_PA2GW2A3, | 211 | BRCMS_SROM_PA2GW2A3, |
228 | BRCMS_SROM_PA2GW3A0, | ||
229 | BRCMS_SROM_PA2GW3A1, | ||
230 | BRCMS_SROM_PA2GW3A2, | ||
231 | BRCMS_SROM_PA2GW3A3, | ||
232 | BRCMS_SROM_PA5GHW0A0, | 212 | BRCMS_SROM_PA5GHW0A0, |
233 | BRCMS_SROM_PA5GHW0A1, | 213 | BRCMS_SROM_PA5GHW0A1, |
234 | BRCMS_SROM_PA5GHW0A2, | 214 | BRCMS_SROM_PA5GHW0A2, |
@@ -241,10 +221,6 @@ enum brcms_srom_id { | |||
241 | BRCMS_SROM_PA5GHW2A1, | 221 | BRCMS_SROM_PA5GHW2A1, |
242 | BRCMS_SROM_PA5GHW2A2, | 222 | BRCMS_SROM_PA5GHW2A2, |
243 | BRCMS_SROM_PA5GHW2A3, | 223 | BRCMS_SROM_PA5GHW2A3, |
244 | BRCMS_SROM_PA5GHW3A0, | ||
245 | BRCMS_SROM_PA5GHW3A1, | ||
246 | BRCMS_SROM_PA5GHW3A2, | ||
247 | BRCMS_SROM_PA5GHW3A3, | ||
248 | BRCMS_SROM_PA5GLW0A0, | 224 | BRCMS_SROM_PA5GLW0A0, |
249 | BRCMS_SROM_PA5GLW0A1, | 225 | BRCMS_SROM_PA5GLW0A1, |
250 | BRCMS_SROM_PA5GLW0A2, | 226 | BRCMS_SROM_PA5GLW0A2, |
@@ -257,10 +233,6 @@ enum brcms_srom_id { | |||
257 | BRCMS_SROM_PA5GLW2A1, | 233 | BRCMS_SROM_PA5GLW2A1, |
258 | BRCMS_SROM_PA5GLW2A2, | 234 | BRCMS_SROM_PA5GLW2A2, |
259 | BRCMS_SROM_PA5GLW2A3, | 235 | BRCMS_SROM_PA5GLW2A3, |
260 | BRCMS_SROM_PA5GLW3A0, | ||
261 | BRCMS_SROM_PA5GLW3A1, | ||
262 | BRCMS_SROM_PA5GLW3A2, | ||
263 | BRCMS_SROM_PA5GLW3A3, | ||
264 | BRCMS_SROM_PA5GW0A0, | 236 | BRCMS_SROM_PA5GW0A0, |
265 | BRCMS_SROM_PA5GW0A1, | 237 | BRCMS_SROM_PA5GW0A1, |
266 | BRCMS_SROM_PA5GW0A2, | 238 | BRCMS_SROM_PA5GW0A2, |
@@ -273,14 +245,9 @@ enum brcms_srom_id { | |||
273 | BRCMS_SROM_PA5GW2A1, | 245 | BRCMS_SROM_PA5GW2A1, |
274 | BRCMS_SROM_PA5GW2A2, | 246 | BRCMS_SROM_PA5GW2A2, |
275 | BRCMS_SROM_PA5GW2A3, | 247 | BRCMS_SROM_PA5GW2A3, |
276 | BRCMS_SROM_PA5GW3A0, | ||
277 | BRCMS_SROM_PA5GW3A1, | ||
278 | BRCMS_SROM_PA5GW3A2, | ||
279 | BRCMS_SROM_PA5GW3A3, | ||
280 | }; | 248 | }; |
281 | 249 | ||
282 | #define BRCMS_NUMRATES 16 /* max # of rates in a rateset */ | 250 | #define BRCMS_NUMRATES 16 /* max # of rates in a rateset */ |
283 | #define D11_PHY_HDR_LEN 6 /* Phy header length - 6 bytes */ | ||
284 | 251 | ||
285 | /* phy types */ | 252 | /* phy types */ |
286 | #define PHY_TYPE_A 0 /* Phy type A */ | 253 | #define PHY_TYPE_A 0 /* Phy type A */ |
@@ -414,7 +381,6 @@ struct brcms_pub { | |||
414 | uint _nbands; /* # bands supported */ | 381 | uint _nbands; /* # bands supported */ |
415 | uint now; /* # elapsed seconds */ | 382 | uint now; /* # elapsed seconds */ |
416 | 383 | ||
417 | bool promisc; /* promiscuous destination address */ | ||
418 | bool delayed_down; /* down delayed */ | 384 | bool delayed_down; /* down delayed */ |
419 | bool associated; /* true:part of [I]BSS, false: not */ | 385 | bool associated; /* true:part of [I]BSS, false: not */ |
420 | /* (union of stas_associated, aps_associated) */ | 386 | /* (union of stas_associated, aps_associated) */ |
@@ -572,7 +538,7 @@ extern int brcms_c_up(struct brcms_c_info *wlc); | |||
572 | extern uint brcms_c_down(struct brcms_c_info *wlc); | 538 | extern uint brcms_c_down(struct brcms_c_info *wlc); |
573 | 539 | ||
574 | extern bool brcms_c_chipmatch(u16 vendor, u16 device); | 540 | extern bool brcms_c_chipmatch(u16 vendor, u16 device); |
575 | extern void brcms_c_init(struct brcms_c_info *wlc); | 541 | extern void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx); |
576 | extern void brcms_c_reset(struct brcms_c_info *wlc); | 542 | extern void brcms_c_reset(struct brcms_c_info *wlc); |
577 | 543 | ||
578 | extern void brcms_c_intrson(struct brcms_c_info *wlc); | 544 | extern void brcms_c_intrson(struct brcms_c_info *wlc); |
@@ -628,7 +594,7 @@ extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, | |||
628 | u8 interval); | 594 | u8 interval); |
629 | extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); | 595 | extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); |
630 | extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); | 596 | extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); |
631 | extern void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc); | ||
632 | extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); | 597 | extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); |
598 | extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); | ||
633 | 599 | ||
634 | #endif /* _BRCM_PUB_H_ */ | 600 | #endif /* _BRCM_PUB_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/rate.h b/drivers/net/wireless/brcm80211/brcmsmac/rate.h index e7b9dc2f2731..980d578825cc 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/rate.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/rate.h | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include "types.h" | 20 | #include "types.h" |
21 | #include "d11.h" | 21 | #include "d11.h" |
22 | #include "phy_hal.h" | ||
22 | 23 | ||
23 | extern const u8 rate_info[]; | 24 | extern const u8 rate_info[]; |
24 | extern const struct brcms_c_rateset cck_ofdm_mimo_rates; | 25 | extern const struct brcms_c_rateset cck_ofdm_mimo_rates; |
@@ -198,11 +199,9 @@ static inline u8 cck_rspec(u8 cck) | |||
198 | 199 | ||
199 | /* Convert encoded rate value in plcp header to numerical rates in 500 KHz | 200 | /* Convert encoded rate value in plcp header to numerical rates in 500 KHz |
200 | * increments */ | 201 | * increments */ |
201 | extern const u8 ofdm_rate_lookup[]; | ||
202 | |||
203 | static inline u8 ofdm_phy2mac_rate(u8 rlpt) | 202 | static inline u8 ofdm_phy2mac_rate(u8 rlpt) |
204 | { | 203 | { |
205 | return ofdm_rate_lookup[rlpt & 0x7]; | 204 | return wlc_phy_get_ofdm_rate_lookup()[rlpt & 0x7]; |
206 | } | 205 | } |
207 | 206 | ||
208 | static inline u8 cck_phy2mac_rate(u8 signal) | 207 | static inline u8 cck_phy2mac_rate(u8 signal) |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.c b/drivers/net/wireless/brcm80211/brcmsmac/srom.c index 99f791048e84..b6987ea9fc68 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/srom.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/srom.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "aiutils.h" | 28 | #include "aiutils.h" |
29 | #include "otp.h" | 29 | #include "otp.h" |
30 | #include "srom.h" | 30 | #include "srom.h" |
31 | #include "soc.h" | ||
31 | 32 | ||
32 | /* | 33 | /* |
33 | * SROM CRC8 polynomial value: | 34 | * SROM CRC8 polynomial value: |
@@ -62,9 +63,6 @@ | |||
62 | #define SROM_MACHI_ET1 42 | 63 | #define SROM_MACHI_ET1 42 |
63 | #define SROM_MACMID_ET1 43 | 64 | #define SROM_MACMID_ET1 43 |
64 | #define SROM_MACLO_ET1 44 | 65 | #define SROM_MACLO_ET1 44 |
65 | #define SROM3_MACHI 37 | ||
66 | #define SROM3_MACMID 38 | ||
67 | #define SROM3_MACLO 39 | ||
68 | 66 | ||
69 | #define SROM_BXARSSI2G 40 | 67 | #define SROM_BXARSSI2G 40 |
70 | #define SROM_BXARSSI5G 41 | 68 | #define SROM_BXARSSI5G 41 |
@@ -101,7 +99,6 @@ | |||
101 | 99 | ||
102 | #define SROM_BFL 57 | 100 | #define SROM_BFL 57 |
103 | #define SROM_BFL2 28 | 101 | #define SROM_BFL2 28 |
104 | #define SROM3_BFL2 61 | ||
105 | 102 | ||
106 | #define SROM_AG10 58 | 103 | #define SROM_AG10 58 |
107 | 104 | ||
@@ -109,99 +106,16 @@ | |||
109 | 106 | ||
110 | #define SROM_OPO 60 | 107 | #define SROM_OPO 60 |
111 | 108 | ||
112 | #define SROM3_LEDDC 62 | ||
113 | |||
114 | #define SROM_CRCREV 63 | 109 | #define SROM_CRCREV 63 |
115 | 110 | ||
116 | /* SROM Rev 4: Reallocate the software part of the srom to accommodate | ||
117 | * MIMO features. It assumes up to two PCIE functions and 440 bytes | ||
118 | * of usable srom i.e. the usable storage in chips with OTP that | ||
119 | * implements hardware redundancy. | ||
120 | */ | ||
121 | |||
122 | #define SROM4_WORDS 220 | 111 | #define SROM4_WORDS 220 |
123 | 112 | ||
124 | #define SROM4_SIGN 32 | ||
125 | #define SROM4_SIGNATURE 0x5372 | ||
126 | |||
127 | #define SROM4_BREV 33 | ||
128 | |||
129 | #define SROM4_BFL0 34 | ||
130 | #define SROM4_BFL1 35 | ||
131 | #define SROM4_BFL2 36 | ||
132 | #define SROM4_BFL3 37 | ||
133 | #define SROM5_BFL0 37 | ||
134 | #define SROM5_BFL1 38 | ||
135 | #define SROM5_BFL2 39 | ||
136 | #define SROM5_BFL3 40 | ||
137 | |||
138 | #define SROM4_MACHI 38 | ||
139 | #define SROM4_MACMID 39 | ||
140 | #define SROM4_MACLO 40 | ||
141 | #define SROM5_MACHI 41 | ||
142 | #define SROM5_MACMID 42 | ||
143 | #define SROM5_MACLO 43 | ||
144 | |||
145 | #define SROM4_CCODE 41 | ||
146 | #define SROM4_REGREV 42 | ||
147 | #define SROM5_CCODE 34 | ||
148 | #define SROM5_REGREV 35 | ||
149 | |||
150 | #define SROM4_LEDBH10 43 | ||
151 | #define SROM4_LEDBH32 44 | ||
152 | #define SROM5_LEDBH10 59 | ||
153 | #define SROM5_LEDBH32 60 | ||
154 | |||
155 | #define SROM4_LEDDC 45 | ||
156 | #define SROM5_LEDDC 45 | ||
157 | |||
158 | #define SROM4_AA 46 | ||
159 | |||
160 | #define SROM4_AG10 47 | ||
161 | #define SROM4_AG32 48 | ||
162 | |||
163 | #define SROM4_TXPID2G 49 | ||
164 | #define SROM4_TXPID5G 51 | ||
165 | #define SROM4_TXPID5GL 53 | ||
166 | #define SROM4_TXPID5GH 55 | ||
167 | |||
168 | #define SROM4_TXRXC 61 | ||
169 | #define SROM4_TXCHAIN_MASK 0x000f | 113 | #define SROM4_TXCHAIN_MASK 0x000f |
170 | #define SROM4_TXCHAIN_SHIFT 0 | ||
171 | #define SROM4_RXCHAIN_MASK 0x00f0 | 114 | #define SROM4_RXCHAIN_MASK 0x00f0 |
172 | #define SROM4_RXCHAIN_SHIFT 4 | ||
173 | #define SROM4_SWITCH_MASK 0xff00 | 115 | #define SROM4_SWITCH_MASK 0xff00 |
174 | #define SROM4_SWITCH_SHIFT 8 | ||
175 | 116 | ||
176 | /* Per-path fields */ | 117 | /* Per-path fields */ |
177 | #define MAX_PATH_SROM 4 | 118 | #define MAX_PATH_SROM 4 |
178 | #define SROM4_PATH0 64 | ||
179 | #define SROM4_PATH1 87 | ||
180 | #define SROM4_PATH2 110 | ||
181 | #define SROM4_PATH3 133 | ||
182 | |||
183 | #define SROM4_2G_ITT_MAXP 0 | ||
184 | #define SROM4_2G_PA 1 | ||
185 | #define SROM4_5G_ITT_MAXP 5 | ||
186 | #define SROM4_5GLH_MAXP 6 | ||
187 | #define SROM4_5G_PA 7 | ||
188 | #define SROM4_5GL_PA 11 | ||
189 | #define SROM4_5GH_PA 15 | ||
190 | |||
191 | /* All the miriad power offsets */ | ||
192 | #define SROM4_2G_CCKPO 156 | ||
193 | #define SROM4_2G_OFDMPO 157 | ||
194 | #define SROM4_5G_OFDMPO 159 | ||
195 | #define SROM4_5GL_OFDMPO 161 | ||
196 | #define SROM4_5GH_OFDMPO 163 | ||
197 | #define SROM4_2G_MCSPO 165 | ||
198 | #define SROM4_5G_MCSPO 173 | ||
199 | #define SROM4_5GL_MCSPO 181 | ||
200 | #define SROM4_5GH_MCSPO 189 | ||
201 | #define SROM4_CDDPO 197 | ||
202 | #define SROM4_STBCPO 198 | ||
203 | #define SROM4_BW40PO 199 | ||
204 | #define SROM4_BWDUPPO 200 | ||
205 | 119 | ||
206 | #define SROM4_CRCREV 219 | 120 | #define SROM4_CRCREV 219 |
207 | 121 | ||
@@ -424,103 +338,32 @@ struct brcms_varbuf { | |||
424 | static const struct brcms_sromvar pci_sromvars[] = { | 338 | static const struct brcms_sromvar pci_sromvars[] = { |
425 | {BRCMS_SROM_DEVID, 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, | 339 | {BRCMS_SROM_DEVID, 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, |
426 | 0xffff}, | 340 | 0xffff}, |
427 | {BRCMS_SROM_BOARDREV, 0x0000000e, SRFL_PRHEX, SROM_AABREV, | ||
428 | SROM_BR_MASK}, | ||
429 | {BRCMS_SROM_BOARDREV, 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff}, | ||
430 | {BRCMS_SROM_BOARDREV, 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff}, | 341 | {BRCMS_SROM_BOARDREV, 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff}, |
431 | {BRCMS_SROM_BOARDFLAGS, 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff}, | ||
432 | {BRCMS_SROM_BOARDFLAGS, 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, | ||
433 | 0xffff}, | ||
434 | {BRCMS_SROM_CONT, 0, 0, SROM_BFL2, 0xffff}, | ||
435 | {BRCMS_SROM_BOARDFLAGS, 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, | ||
436 | 0xffff}, | ||
437 | {BRCMS_SROM_CONT, 0, 0, SROM3_BFL2, 0xffff}, | ||
438 | {BRCMS_SROM_BOARDFLAGS, 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, | ||
439 | 0xffff}, | ||
440 | {BRCMS_SROM_CONT, 0, 0, SROM4_BFL1, 0xffff}, | ||
441 | {BRCMS_SROM_BOARDFLAGS, 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, | ||
442 | 0xffff}, | ||
443 | {BRCMS_SROM_CONT, 0, 0, SROM5_BFL1, 0xffff}, | ||
444 | {BRCMS_SROM_BOARDFLAGS, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, | 342 | {BRCMS_SROM_BOARDFLAGS, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, |
445 | 0xffff}, | 343 | 0xffff}, |
446 | {BRCMS_SROM_CONT, 0, 0, SROM8_BFL1, 0xffff}, | 344 | {BRCMS_SROM_CONT, 0, 0, SROM8_BFL1, 0xffff}, |
447 | {BRCMS_SROM_BOARDFLAGS2, 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, | ||
448 | 0xffff}, | ||
449 | {BRCMS_SROM_CONT, 0, 0, SROM4_BFL3, 0xffff}, | ||
450 | {BRCMS_SROM_BOARDFLAGS2, 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, | ||
451 | 0xffff}, | ||
452 | {BRCMS_SROM_CONT, 0, 0, SROM5_BFL3, 0xffff}, | ||
453 | {BRCMS_SROM_BOARDFLAGS2, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, | 345 | {BRCMS_SROM_BOARDFLAGS2, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, |
454 | 0xffff}, | 346 | 0xffff}, |
455 | {BRCMS_SROM_CONT, 0, 0, SROM8_BFL3, 0xffff}, | 347 | {BRCMS_SROM_CONT, 0, 0, SROM8_BFL3, 0xffff}, |
456 | {BRCMS_SROM_BOARDTYPE, 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff}, | 348 | {BRCMS_SROM_BOARDTYPE, 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff}, |
457 | {BRCMS_SROM_BOARDNUM, 0x00000006, 0, SROM_MACLO_IL0, 0xffff}, | ||
458 | {BRCMS_SROM_BOARDNUM, 0x00000008, 0, SROM3_MACLO, 0xffff}, | ||
459 | {BRCMS_SROM_BOARDNUM, 0x00000010, 0, SROM4_MACLO, 0xffff}, | ||
460 | {BRCMS_SROM_BOARDNUM, 0x000000e0, 0, SROM5_MACLO, 0xffff}, | ||
461 | {BRCMS_SROM_BOARDNUM, 0xffffff00, 0, SROM8_MACLO, 0xffff}, | 349 | {BRCMS_SROM_BOARDNUM, 0xffffff00, 0, SROM8_MACLO, 0xffff}, |
462 | {BRCMS_SROM_CC, 0x00000002, 0, SROM_AABREV, SROM_CC_MASK}, | ||
463 | {BRCMS_SROM_REGREV, 0x00000008, 0, SROM_OPO, 0xff00}, | ||
464 | {BRCMS_SROM_REGREV, 0x00000010, 0, SROM4_REGREV, 0x00ff}, | ||
465 | {BRCMS_SROM_REGREV, 0x000000e0, 0, SROM5_REGREV, 0x00ff}, | ||
466 | {BRCMS_SROM_REGREV, 0xffffff00, 0, SROM8_REGREV, 0x00ff}, | 350 | {BRCMS_SROM_REGREV, 0xffffff00, 0, SROM8_REGREV, 0x00ff}, |
467 | {BRCMS_SROM_LEDBH0, 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff}, | ||
468 | {BRCMS_SROM_LEDBH1, 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00}, | ||
469 | {BRCMS_SROM_LEDBH2, 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff}, | ||
470 | {BRCMS_SROM_LEDBH3, 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00}, | ||
471 | {BRCMS_SROM_LEDBH0, 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff}, | ||
472 | {BRCMS_SROM_LEDBH1, 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00}, | ||
473 | {BRCMS_SROM_LEDBH2, 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff}, | ||
474 | {BRCMS_SROM_LEDBH3, 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00}, | ||
475 | {BRCMS_SROM_LEDBH0, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff}, | ||
476 | {BRCMS_SROM_LEDBH1, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00}, | ||
477 | {BRCMS_SROM_LEDBH2, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff}, | ||
478 | {BRCMS_SROM_LEDBH3, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00}, | ||
479 | {BRCMS_SROM_LEDBH0, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff}, | 351 | {BRCMS_SROM_LEDBH0, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff}, |
480 | {BRCMS_SROM_LEDBH1, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00}, | 352 | {BRCMS_SROM_LEDBH1, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00}, |
481 | {BRCMS_SROM_LEDBH2, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff}, | 353 | {BRCMS_SROM_LEDBH2, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff}, |
482 | {BRCMS_SROM_LEDBH3, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00}, | 354 | {BRCMS_SROM_LEDBH3, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00}, |
483 | {BRCMS_SROM_PA0B0, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff}, | ||
484 | {BRCMS_SROM_PA0B1, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff}, | ||
485 | {BRCMS_SROM_PA0B2, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff}, | ||
486 | {BRCMS_SROM_PA0ITSSIT, 0x0000000e, 0, SROM_ITT, 0x00ff}, | ||
487 | {BRCMS_SROM_PA0MAXPWR, 0x0000000e, 0, SROM_WL10MAXP, 0x00ff}, | ||
488 | {BRCMS_SROM_PA0B0, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff}, | 355 | {BRCMS_SROM_PA0B0, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff}, |
489 | {BRCMS_SROM_PA0B1, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff}, | 356 | {BRCMS_SROM_PA0B1, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff}, |
490 | {BRCMS_SROM_PA0B2, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff}, | 357 | {BRCMS_SROM_PA0B2, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff}, |
491 | {BRCMS_SROM_PA0ITSSIT, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00}, | 358 | {BRCMS_SROM_PA0ITSSIT, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00}, |
492 | {BRCMS_SROM_PA0MAXPWR, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff}, | 359 | {BRCMS_SROM_PA0MAXPWR, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff}, |
493 | {BRCMS_SROM_OPO, 0x0000000c, 0, SROM_OPO, 0x00ff}, | ||
494 | {BRCMS_SROM_OPO, 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff}, | 360 | {BRCMS_SROM_OPO, 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff}, |
495 | {BRCMS_SROM_AA2G, 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK}, | ||
496 | {BRCMS_SROM_AA2G, 0x000000f0, 0, SROM4_AA, 0x00ff}, | ||
497 | {BRCMS_SROM_AA2G, 0xffffff00, 0, SROM8_AA, 0x00ff}, | 361 | {BRCMS_SROM_AA2G, 0xffffff00, 0, SROM8_AA, 0x00ff}, |
498 | {BRCMS_SROM_AA5G, 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK}, | ||
499 | {BRCMS_SROM_AA5G, 0x000000f0, 0, SROM4_AA, 0xff00}, | ||
500 | {BRCMS_SROM_AA5G, 0xffffff00, 0, SROM8_AA, 0xff00}, | 362 | {BRCMS_SROM_AA5G, 0xffffff00, 0, SROM8_AA, 0xff00}, |
501 | {BRCMS_SROM_AG0, 0x0000000e, 0, SROM_AG10, 0x00ff}, | ||
502 | {BRCMS_SROM_AG1, 0x0000000e, 0, SROM_AG10, 0xff00}, | ||
503 | {BRCMS_SROM_AG0, 0x000000f0, 0, SROM4_AG10, 0x00ff}, | ||
504 | {BRCMS_SROM_AG1, 0x000000f0, 0, SROM4_AG10, 0xff00}, | ||
505 | {BRCMS_SROM_AG2, 0x000000f0, 0, SROM4_AG32, 0x00ff}, | ||
506 | {BRCMS_SROM_AG3, 0x000000f0, 0, SROM4_AG32, 0xff00}, | ||
507 | {BRCMS_SROM_AG0, 0xffffff00, 0, SROM8_AG10, 0x00ff}, | 363 | {BRCMS_SROM_AG0, 0xffffff00, 0, SROM8_AG10, 0x00ff}, |
508 | {BRCMS_SROM_AG1, 0xffffff00, 0, SROM8_AG10, 0xff00}, | 364 | {BRCMS_SROM_AG1, 0xffffff00, 0, SROM8_AG10, 0xff00}, |
509 | {BRCMS_SROM_AG2, 0xffffff00, 0, SROM8_AG32, 0x00ff}, | 365 | {BRCMS_SROM_AG2, 0xffffff00, 0, SROM8_AG32, 0x00ff}, |
510 | {BRCMS_SROM_AG3, 0xffffff00, 0, SROM8_AG32, 0xff00}, | 366 | {BRCMS_SROM_AG3, 0xffffff00, 0, SROM8_AG32, 0xff00}, |
511 | {BRCMS_SROM_PA1B0, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff}, | ||
512 | {BRCMS_SROM_PA1B1, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff}, | ||
513 | {BRCMS_SROM_PA1B2, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff}, | ||
514 | {BRCMS_SROM_PA1LOB0, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff}, | ||
515 | {BRCMS_SROM_PA1LOB1, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff}, | ||
516 | {BRCMS_SROM_PA1LOB2, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff}, | ||
517 | {BRCMS_SROM_PA1HIB0, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff}, | ||
518 | {BRCMS_SROM_PA1HIB1, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff}, | ||
519 | {BRCMS_SROM_PA1HIB2, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff}, | ||
520 | {BRCMS_SROM_PA1ITSSIT, 0x0000000e, 0, SROM_ITT, 0xff00}, | ||
521 | {BRCMS_SROM_PA1MAXPWR, 0x0000000e, 0, SROM_WL10MAXP, 0xff00}, | ||
522 | {BRCMS_SROM_PA1LOMAXPWR, 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00}, | ||
523 | {BRCMS_SROM_PA1HIMAXPWR, 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff}, | ||
524 | {BRCMS_SROM_PA1B0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff}, | 367 | {BRCMS_SROM_PA1B0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff}, |
525 | {BRCMS_SROM_PA1B1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff}, | 368 | {BRCMS_SROM_PA1B1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff}, |
526 | {BRCMS_SROM_PA1B2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff}, | 369 | {BRCMS_SROM_PA1B2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff}, |
@@ -534,40 +377,20 @@ static const struct brcms_sromvar pci_sromvars[] = { | |||
534 | {BRCMS_SROM_PA1MAXPWR, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff}, | 377 | {BRCMS_SROM_PA1MAXPWR, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff}, |
535 | {BRCMS_SROM_PA1LOMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00}, | 378 | {BRCMS_SROM_PA1LOMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00}, |
536 | {BRCMS_SROM_PA1HIMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff}, | 379 | {BRCMS_SROM_PA1HIMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff}, |
537 | {BRCMS_SROM_BXA2G, 0x00000008, 0, SROM_BXARSSI2G, 0x1800}, | ||
538 | {BRCMS_SROM_RSSISAV2G, 0x00000008, 0, SROM_BXARSSI2G, 0x0700}, | ||
539 | {BRCMS_SROM_RSSISMC2G, 0x00000008, 0, SROM_BXARSSI2G, 0x00f0}, | ||
540 | {BRCMS_SROM_RSSISMF2G, 0x00000008, 0, SROM_BXARSSI2G, 0x000f}, | ||
541 | {BRCMS_SROM_BXA2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800}, | 380 | {BRCMS_SROM_BXA2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800}, |
542 | {BRCMS_SROM_RSSISAV2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700}, | 381 | {BRCMS_SROM_RSSISAV2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700}, |
543 | {BRCMS_SROM_RSSISMC2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0}, | 382 | {BRCMS_SROM_RSSISMC2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0}, |
544 | {BRCMS_SROM_RSSISMF2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f}, | 383 | {BRCMS_SROM_RSSISMF2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f}, |
545 | {BRCMS_SROM_BXA5G, 0x00000008, 0, SROM_BXARSSI5G, 0x1800}, | ||
546 | {BRCMS_SROM_RSSISAV5G, 0x00000008, 0, SROM_BXARSSI5G, 0x0700}, | ||
547 | {BRCMS_SROM_RSSISMC5G, 0x00000008, 0, SROM_BXARSSI5G, 0x00f0}, | ||
548 | {BRCMS_SROM_RSSISMF5G, 0x00000008, 0, SROM_BXARSSI5G, 0x000f}, | ||
549 | {BRCMS_SROM_BXA5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800}, | 384 | {BRCMS_SROM_BXA5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800}, |
550 | {BRCMS_SROM_RSSISAV5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700}, | 385 | {BRCMS_SROM_RSSISAV5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700}, |
551 | {BRCMS_SROM_RSSISMC5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0}, | 386 | {BRCMS_SROM_RSSISMC5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0}, |
552 | {BRCMS_SROM_RSSISMF5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f}, | 387 | {BRCMS_SROM_RSSISMF5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f}, |
553 | {BRCMS_SROM_TRI2G, 0x00000008, 0, SROM_TRI52G, 0x00ff}, | ||
554 | {BRCMS_SROM_TRI5G, 0x00000008, 0, SROM_TRI52G, 0xff00}, | ||
555 | {BRCMS_SROM_TRI5GL, 0x00000008, 0, SROM_TRI5GHL, 0x00ff}, | ||
556 | {BRCMS_SROM_TRI5GH, 0x00000008, 0, SROM_TRI5GHL, 0xff00}, | ||
557 | {BRCMS_SROM_TRI2G, 0xffffff00, 0, SROM8_TRI52G, 0x00ff}, | 388 | {BRCMS_SROM_TRI2G, 0xffffff00, 0, SROM8_TRI52G, 0x00ff}, |
558 | {BRCMS_SROM_TRI5G, 0xffffff00, 0, SROM8_TRI52G, 0xff00}, | 389 | {BRCMS_SROM_TRI5G, 0xffffff00, 0, SROM8_TRI52G, 0xff00}, |
559 | {BRCMS_SROM_TRI5GL, 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff}, | 390 | {BRCMS_SROM_TRI5GL, 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff}, |
560 | {BRCMS_SROM_TRI5GH, 0xffffff00, 0, SROM8_TRI5GHL, 0xff00}, | 391 | {BRCMS_SROM_TRI5GH, 0xffffff00, 0, SROM8_TRI5GHL, 0xff00}, |
561 | {BRCMS_SROM_RXPO2G, 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff}, | ||
562 | {BRCMS_SROM_RXPO5G, 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00}, | ||
563 | {BRCMS_SROM_RXPO2G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff}, | 392 | {BRCMS_SROM_RXPO2G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff}, |
564 | {BRCMS_SROM_RXPO5G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00}, | 393 | {BRCMS_SROM_RXPO5G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00}, |
565 | {BRCMS_SROM_TXCHAIN, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, | ||
566 | SROM4_TXCHAIN_MASK}, | ||
567 | {BRCMS_SROM_RXCHAIN, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, | ||
568 | SROM4_RXCHAIN_MASK}, | ||
569 | {BRCMS_SROM_ANTSWITCH, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, | ||
570 | SROM4_SWITCH_MASK}, | ||
571 | {BRCMS_SROM_TXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, | 394 | {BRCMS_SROM_TXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, |
572 | SROM4_TXCHAIN_MASK}, | 395 | SROM4_TXCHAIN_MASK}, |
573 | {BRCMS_SROM_RXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, | 396 | {BRCMS_SROM_RXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, |
@@ -594,43 +417,11 @@ static const struct brcms_sromvar pci_sromvars[] = { | |||
594 | SROM8_FEM_ANTSWLUT_MASK}, | 417 | SROM8_FEM_ANTSWLUT_MASK}, |
595 | {BRCMS_SROM_TEMPTHRESH, 0xffffff00, 0, SROM8_THERMAL, 0xff00}, | 418 | {BRCMS_SROM_TEMPTHRESH, 0xffffff00, 0, SROM8_THERMAL, 0xff00}, |
596 | {BRCMS_SROM_TEMPOFFSET, 0xffffff00, 0, SROM8_THERMAL, 0x00ff}, | 419 | {BRCMS_SROM_TEMPOFFSET, 0xffffff00, 0, SROM8_THERMAL, 0x00ff}, |
597 | {BRCMS_SROM_TXPID2GA0, 0x000000f0, 0, SROM4_TXPID2G, 0x00ff}, | 420 | |
598 | {BRCMS_SROM_TXPID2GA1, 0x000000f0, 0, SROM4_TXPID2G, 0xff00}, | ||
599 | {BRCMS_SROM_TXPID2GA2, 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff}, | ||
600 | {BRCMS_SROM_TXPID2GA3, 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00}, | ||
601 | {BRCMS_SROM_TXPID5GA0, 0x000000f0, 0, SROM4_TXPID5G, 0x00ff}, | ||
602 | {BRCMS_SROM_TXPID5GA1, 0x000000f0, 0, SROM4_TXPID5G, 0xff00}, | ||
603 | {BRCMS_SROM_TXPID5GA2, 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff}, | ||
604 | {BRCMS_SROM_TXPID5GA3, 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00}, | ||
605 | {BRCMS_SROM_TXPID5GLA0, 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff}, | ||
606 | {BRCMS_SROM_TXPID5GLA1, 0x000000f0, 0, SROM4_TXPID5GL, 0xff00}, | ||
607 | {BRCMS_SROM_TXPID5GLA2, 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff}, | ||
608 | {BRCMS_SROM_TXPID5GLA3, 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00}, | ||
609 | {BRCMS_SROM_TXPID5GHA0, 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff}, | ||
610 | {BRCMS_SROM_TXPID5GHA1, 0x000000f0, 0, SROM4_TXPID5GH, 0xff00}, | ||
611 | {BRCMS_SROM_TXPID5GHA2, 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff}, | ||
612 | {BRCMS_SROM_TXPID5GHA3, 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00}, | ||
613 | |||
614 | {BRCMS_SROM_CCODE, 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff}, | ||
615 | {BRCMS_SROM_CCODE, 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff}, | ||
616 | {BRCMS_SROM_CCODE, 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff}, | ||
617 | {BRCMS_SROM_CCODE, 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff}, | 421 | {BRCMS_SROM_CCODE, 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff}, |
618 | {BRCMS_SROM_MACADDR, 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff}, | 422 | {BRCMS_SROM_MACADDR, 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff}, |
619 | {BRCMS_SROM_MACADDR, 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff}, | ||
620 | {BRCMS_SROM_MACADDR, 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff}, | ||
621 | {BRCMS_SROM_MACADDR, 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff}, | ||
622 | {BRCMS_SROM_IL0MACADDR, 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, | ||
623 | 0xffff}, | ||
624 | {BRCMS_SROM_ET1MACADDR, 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, | ||
625 | 0xffff}, | ||
626 | {BRCMS_SROM_LEDDC, 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, | 423 | {BRCMS_SROM_LEDDC, 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, |
627 | 0xffff}, | 424 | 0xffff}, |
628 | {BRCMS_SROM_LEDDC, 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, | ||
629 | 0xffff}, | ||
630 | {BRCMS_SROM_LEDDC, 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, | ||
631 | 0xffff}, | ||
632 | {BRCMS_SROM_LEDDC, 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, | ||
633 | 0xffff}, | ||
634 | {BRCMS_SROM_RAWTEMPSENSE, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, | 425 | {BRCMS_SROM_RAWTEMPSENSE, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, |
635 | 0x01ff}, | 426 | 0x01ff}, |
636 | {BRCMS_SROM_MEASPOWER, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, | 427 | {BRCMS_SROM_MEASPOWER, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, |
@@ -650,16 +441,7 @@ static const struct brcms_sromvar pci_sromvars[] = { | |||
650 | {BRCMS_SROM_PHYCAL_TEMPDELTA, 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, | 441 | {BRCMS_SROM_PHYCAL_TEMPDELTA, 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, |
651 | 0x00ff}, | 442 | 0x00ff}, |
652 | 443 | ||
653 | {BRCMS_SROM_CCK2GPO, 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff}, | ||
654 | {BRCMS_SROM_CCK2GPO, 0x00000100, 0, SROM8_2G_CCKPO, 0xffff}, | 444 | {BRCMS_SROM_CCK2GPO, 0x00000100, 0, SROM8_2G_CCKPO, 0xffff}, |
655 | {BRCMS_SROM_OFDM2GPO, 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff}, | ||
656 | {BRCMS_SROM_CONT, 0, 0, SROM4_2G_OFDMPO + 1, 0xffff}, | ||
657 | {BRCMS_SROM_OFDM5GPO, 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff}, | ||
658 | {BRCMS_SROM_CONT, 0, 0, SROM4_5G_OFDMPO + 1, 0xffff}, | ||
659 | {BRCMS_SROM_OFDM5GLPO, 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff}, | ||
660 | {BRCMS_SROM_CONT, 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff}, | ||
661 | {BRCMS_SROM_OFDM5GHPO, 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff}, | ||
662 | {BRCMS_SROM_CONT, 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff}, | ||
663 | {BRCMS_SROM_OFDM2GPO, 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff}, | 445 | {BRCMS_SROM_OFDM2GPO, 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff}, |
664 | {BRCMS_SROM_CONT, 0, 0, SROM8_2G_OFDMPO + 1, 0xffff}, | 446 | {BRCMS_SROM_CONT, 0, 0, SROM8_2G_OFDMPO + 1, 0xffff}, |
665 | {BRCMS_SROM_OFDM5GPO, 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff}, | 447 | {BRCMS_SROM_OFDM5GPO, 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff}, |
@@ -668,38 +450,6 @@ static const struct brcms_sromvar pci_sromvars[] = { | |||
668 | {BRCMS_SROM_CONT, 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff}, | 450 | {BRCMS_SROM_CONT, 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff}, |
669 | {BRCMS_SROM_OFDM5GHPO, 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff}, | 451 | {BRCMS_SROM_OFDM5GHPO, 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff}, |
670 | {BRCMS_SROM_CONT, 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff}, | 452 | {BRCMS_SROM_CONT, 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff}, |
671 | {BRCMS_SROM_MCS2GPO0, 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff}, | ||
672 | {BRCMS_SROM_MCS2GPO1, 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff}, | ||
673 | {BRCMS_SROM_MCS2GPO2, 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff}, | ||
674 | {BRCMS_SROM_MCS2GPO3, 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff}, | ||
675 | {BRCMS_SROM_MCS2GPO4, 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff}, | ||
676 | {BRCMS_SROM_MCS2GPO5, 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff}, | ||
677 | {BRCMS_SROM_MCS2GPO6, 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff}, | ||
678 | {BRCMS_SROM_MCS2GPO7, 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff}, | ||
679 | {BRCMS_SROM_MCS5GPO0, 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff}, | ||
680 | {BRCMS_SROM_MCS5GPO1, 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff}, | ||
681 | {BRCMS_SROM_MCS5GPO2, 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff}, | ||
682 | {BRCMS_SROM_MCS5GPO3, 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff}, | ||
683 | {BRCMS_SROM_MCS5GPO4, 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff}, | ||
684 | {BRCMS_SROM_MCS5GPO5, 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff}, | ||
685 | {BRCMS_SROM_MCS5GPO6, 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff}, | ||
686 | {BRCMS_SROM_MCS5GPO7, 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff}, | ||
687 | {BRCMS_SROM_MCS5GLPO0, 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff}, | ||
688 | {BRCMS_SROM_MCS5GLPO1, 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff}, | ||
689 | {BRCMS_SROM_MCS5GLPO2, 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff}, | ||
690 | {BRCMS_SROM_MCS5GLPO3, 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff}, | ||
691 | {BRCMS_SROM_MCS5GLPO4, 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff}, | ||
692 | {BRCMS_SROM_MCS5GLPO5, 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff}, | ||
693 | {BRCMS_SROM_MCS5GLPO6, 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff}, | ||
694 | {BRCMS_SROM_MCS5GLPO7, 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff}, | ||
695 | {BRCMS_SROM_MCS5GHPO0, 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff}, | ||
696 | {BRCMS_SROM_MCS5GHPO1, 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff}, | ||
697 | {BRCMS_SROM_MCS5GHPO2, 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff}, | ||
698 | {BRCMS_SROM_MCS5GHPO3, 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff}, | ||
699 | {BRCMS_SROM_MCS5GHPO4, 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff}, | ||
700 | {BRCMS_SROM_MCS5GHPO5, 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff}, | ||
701 | {BRCMS_SROM_MCS5GHPO6, 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff}, | ||
702 | {BRCMS_SROM_MCS5GHPO7, 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff}, | ||
703 | {BRCMS_SROM_MCS2GPO0, 0x00000100, 0, SROM8_2G_MCSPO, 0xffff}, | 453 | {BRCMS_SROM_MCS2GPO0, 0x00000100, 0, SROM8_2G_MCSPO, 0xffff}, |
704 | {BRCMS_SROM_MCS2GPO1, 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff}, | 454 | {BRCMS_SROM_MCS2GPO1, 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff}, |
705 | {BRCMS_SROM_MCS2GPO2, 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff}, | 455 | {BRCMS_SROM_MCS2GPO2, 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff}, |
@@ -732,10 +482,6 @@ static const struct brcms_sromvar pci_sromvars[] = { | |||
732 | {BRCMS_SROM_MCS5GHPO5, 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff}, | 482 | {BRCMS_SROM_MCS5GHPO5, 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff}, |
733 | {BRCMS_SROM_MCS5GHPO6, 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff}, | 483 | {BRCMS_SROM_MCS5GHPO6, 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff}, |
734 | {BRCMS_SROM_MCS5GHPO7, 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff}, | 484 | {BRCMS_SROM_MCS5GHPO7, 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff}, |
735 | {BRCMS_SROM_CDDPO, 0x000000f0, 0, SROM4_CDDPO, 0xffff}, | ||
736 | {BRCMS_SROM_STBCPO, 0x000000f0, 0, SROM4_STBCPO, 0xffff}, | ||
737 | {BRCMS_SROM_BW40PO, 0x000000f0, 0, SROM4_BW40PO, 0xffff}, | ||
738 | {BRCMS_SROM_BWDUPPO, 0x000000f0, 0, SROM4_BWDUPPO, 0xffff}, | ||
739 | {BRCMS_SROM_CDDPO, 0x00000100, 0, SROM8_CDDPO, 0xffff}, | 485 | {BRCMS_SROM_CDDPO, 0x00000100, 0, SROM8_CDDPO, 0xffff}, |
740 | {BRCMS_SROM_STBCPO, 0x00000100, 0, SROM8_STBCPO, 0xffff}, | 486 | {BRCMS_SROM_STBCPO, 0x00000100, 0, SROM8_STBCPO, 0xffff}, |
741 | {BRCMS_SROM_BW40PO, 0x00000100, 0, SROM8_BW40PO, 0xffff}, | 487 | {BRCMS_SROM_BW40PO, 0x00000100, 0, SROM8_BW40PO, 0xffff}, |
@@ -811,34 +557,6 @@ static const struct brcms_sromvar pci_sromvars[] = { | |||
811 | }; | 557 | }; |
812 | 558 | ||
813 | static const struct brcms_sromvar perpath_pci_sromvars[] = { | 559 | static const struct brcms_sromvar perpath_pci_sromvars[] = { |
814 | {BRCMS_SROM_MAXP2GA0, 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff}, | ||
815 | {BRCMS_SROM_ITT2GA0, 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00}, | ||
816 | {BRCMS_SROM_ITT5GA0, 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00}, | ||
817 | {BRCMS_SROM_PA2GW0A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff}, | ||
818 | {BRCMS_SROM_PA2GW1A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff}, | ||
819 | {BRCMS_SROM_PA2GW2A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff}, | ||
820 | {BRCMS_SROM_PA2GW3A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff}, | ||
821 | {BRCMS_SROM_MAXP5GA0, 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff}, | ||
822 | {BRCMS_SROM_MAXP5GHA0, 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff}, | ||
823 | {BRCMS_SROM_MAXP5GLA0, 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00}, | ||
824 | {BRCMS_SROM_PA5GW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff}, | ||
825 | {BRCMS_SROM_PA5GW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff}, | ||
826 | {BRCMS_SROM_PA5GW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff}, | ||
827 | {BRCMS_SROM_PA5GW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff}, | ||
828 | {BRCMS_SROM_PA5GLW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff}, | ||
829 | {BRCMS_SROM_PA5GLW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, | ||
830 | 0xffff}, | ||
831 | {BRCMS_SROM_PA5GLW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, | ||
832 | 0xffff}, | ||
833 | {BRCMS_SROM_PA5GLW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, | ||
834 | 0xffff}, | ||
835 | {BRCMS_SROM_PA5GHW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff}, | ||
836 | {BRCMS_SROM_PA5GHW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, | ||
837 | 0xffff}, | ||
838 | {BRCMS_SROM_PA5GHW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, | ||
839 | 0xffff}, | ||
840 | {BRCMS_SROM_PA5GHW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, | ||
841 | 0xffff}, | ||
842 | {BRCMS_SROM_MAXP2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff}, | 560 | {BRCMS_SROM_MAXP2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff}, |
843 | {BRCMS_SROM_ITT2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00}, | 561 | {BRCMS_SROM_ITT2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00}, |
844 | {BRCMS_SROM_ITT5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00}, | 562 | {BRCMS_SROM_ITT5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00}, |
@@ -868,24 +586,17 @@ static const struct brcms_sromvar perpath_pci_sromvars[] = { | |||
868 | * shared between devices. */ | 586 | * shared between devices. */ |
869 | static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE]; | 587 | static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE]; |
870 | 588 | ||
871 | static u16 __iomem * | 589 | static u8 __iomem * |
872 | srom_window_address(struct si_pub *sih, u8 __iomem *curmap) | 590 | srom_window_address(struct si_pub *sih, u8 __iomem *curmap) |
873 | { | 591 | { |
874 | if (sih->ccrev < 32) | 592 | if (sih->ccrev < 32) |
875 | return (u16 __iomem *)(curmap + PCI_BAR0_SPROM_OFFSET); | 593 | return curmap + PCI_BAR0_SPROM_OFFSET; |
876 | if (sih->cccaps & CC_CAP_SROM) | 594 | if (sih->cccaps & CC_CAP_SROM) |
877 | return (u16 __iomem *) | 595 | return curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP; |
878 | (curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP); | ||
879 | 596 | ||
880 | return NULL; | 597 | return NULL; |
881 | } | 598 | } |
882 | 599 | ||
883 | /* Parse SROM and create name=value pairs. 'srom' points to | ||
884 | * the SROM word array. 'off' specifies the offset of the | ||
885 | * first word 'srom' points to, which should be either 0 or | ||
886 | * SROM3_SWRG_OFF (full SROM or software region). | ||
887 | */ | ||
888 | |||
889 | static uint mask_shift(u16 mask) | 600 | static uint mask_shift(u16 mask) |
890 | { | 601 | { |
891 | uint i; | 602 | uint i; |
@@ -906,18 +617,16 @@ static uint mask_width(u16 mask) | |||
906 | return 0; | 617 | return 0; |
907 | } | 618 | } |
908 | 619 | ||
909 | static inline void ltoh16_buf(u16 *buf, unsigned int size) | 620 | static inline void le16_to_cpu_buf(u16 *buf, uint nwords) |
910 | { | 621 | { |
911 | size /= 2; | 622 | while (nwords--) |
912 | while (size--) | 623 | *(buf + nwords) = le16_to_cpu(*(__le16 *)(buf + nwords)); |
913 | *(buf + size) = le16_to_cpu(*(__le16 *)(buf + size)); | ||
914 | } | 624 | } |
915 | 625 | ||
916 | static inline void htol16_buf(u16 *buf, unsigned int size) | 626 | static inline void cpu_to_le16_buf(u16 *buf, uint nwords) |
917 | { | 627 | { |
918 | size /= 2; | 628 | while (nwords--) |
919 | while (size--) | 629 | *(__le16 *)(buf + nwords) = cpu_to_le16(*(buf + nwords)); |
920 | *(__le16 *)(buf + size) = cpu_to_le16(*(buf + size)); | ||
921 | } | 630 | } |
922 | 631 | ||
923 | /* | 632 | /* |
@@ -929,11 +638,14 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) | |||
929 | struct brcms_srom_list_head *entry; | 638 | struct brcms_srom_list_head *entry; |
930 | enum brcms_srom_id id; | 639 | enum brcms_srom_id id; |
931 | u16 w; | 640 | u16 w; |
932 | u32 val; | 641 | u32 val = 0; |
933 | const struct brcms_sromvar *srv; | 642 | const struct brcms_sromvar *srv; |
934 | uint width; | 643 | uint width; |
935 | uint flags; | 644 | uint flags; |
936 | u32 sr = (1 << sromrev); | 645 | u32 sr = (1 << sromrev); |
646 | uint p; | ||
647 | uint pb = SROM8_PATH0; | ||
648 | const uint psz = SROM8_PATH1 - SROM8_PATH0; | ||
937 | 649 | ||
938 | /* first store the srom revision */ | 650 | /* first store the srom revision */ |
939 | entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL); | 651 | entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL); |
@@ -1031,47 +743,34 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) | |||
1031 | list_add(&entry->var_list, var_list); | 743 | list_add(&entry->var_list, var_list); |
1032 | } | 744 | } |
1033 | 745 | ||
1034 | if (sromrev >= 4) { | 746 | for (p = 0; p < MAX_PATH_SROM; p++) { |
1035 | /* Do per-path variables */ | 747 | for (srv = perpath_pci_sromvars; |
1036 | uint p, pb, psz; | 748 | srv->varid != BRCMS_SROM_NULL; srv++) { |
1037 | 749 | if ((srv->revmask & sr) == 0) | |
1038 | if (sromrev >= 8) { | 750 | continue; |
1039 | pb = SROM8_PATH0; | ||
1040 | psz = SROM8_PATH1 - SROM8_PATH0; | ||
1041 | } else { | ||
1042 | pb = SROM4_PATH0; | ||
1043 | psz = SROM4_PATH1 - SROM4_PATH0; | ||
1044 | } | ||
1045 | |||
1046 | for (p = 0; p < MAX_PATH_SROM; p++) { | ||
1047 | for (srv = perpath_pci_sromvars; | ||
1048 | srv->varid != BRCMS_SROM_NULL; srv++) { | ||
1049 | if ((srv->revmask & sr) == 0) | ||
1050 | continue; | ||
1051 | 751 | ||
1052 | if (srv->flags & SRFL_NOVAR) | 752 | if (srv->flags & SRFL_NOVAR) |
1053 | continue; | 753 | continue; |
1054 | 754 | ||
1055 | w = srom[pb + srv->off]; | 755 | w = srom[pb + srv->off]; |
1056 | val = (w & srv->mask) >> mask_shift(srv->mask); | 756 | val = (w & srv->mask) >> mask_shift(srv->mask); |
1057 | width = mask_width(srv->mask); | 757 | width = mask_width(srv->mask); |
1058 | 758 | ||
1059 | /* Cheating: no per-path var is more than | 759 | /* Cheating: no per-path var is more than |
1060 | * 1 word */ | 760 | * 1 word */ |
1061 | if ((srv->flags & SRFL_NOFFS) | 761 | if ((srv->flags & SRFL_NOFFS) |
1062 | && ((int)val == (1 << width) - 1)) | 762 | && ((int)val == (1 << width) - 1)) |
1063 | continue; | 763 | continue; |
1064 | 764 | ||
1065 | entry = | 765 | entry = |
1066 | kzalloc(sizeof(struct brcms_srom_list_head), | 766 | kzalloc(sizeof(struct brcms_srom_list_head), |
1067 | GFP_KERNEL); | 767 | GFP_KERNEL); |
1068 | entry->varid = srv->varid+p; | 768 | entry->varid = srv->varid+p; |
1069 | entry->var_type = BRCMS_SROM_UNUMBER; | 769 | entry->var_type = BRCMS_SROM_UNUMBER; |
1070 | entry->uval = val; | 770 | entry->uval = val; |
1071 | list_add(&entry->var_list, var_list); | 771 | list_add(&entry->var_list, var_list); |
1072 | } | ||
1073 | pb += psz; | ||
1074 | } | 772 | } |
773 | pb += psz; | ||
1075 | } | 774 | } |
1076 | } | 775 | } |
1077 | 776 | ||
@@ -1080,41 +779,38 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) | |||
1080 | * Return 0 on success, nonzero on error. | 779 | * Return 0 on success, nonzero on error. |
1081 | */ | 780 | */ |
1082 | static int | 781 | static int |
1083 | sprom_read_pci(struct si_pub *sih, u16 __iomem *sprom, uint wordoff, | 782 | sprom_read_pci(struct si_pub *sih, u8 __iomem *sprom, uint wordoff, |
1084 | u16 *buf, uint nwords, bool check_crc) | 783 | u16 *buf, uint nwords, bool check_crc) |
1085 | { | 784 | { |
1086 | int err = 0; | 785 | int err = 0; |
1087 | uint i; | 786 | uint i; |
787 | u8 *bbuf = (u8 *)buf; /* byte buffer */ | ||
788 | uint nbytes = nwords << 1; | ||
1088 | 789 | ||
1089 | /* read the sprom */ | 790 | /* read the sprom in bytes */ |
1090 | for (i = 0; i < nwords; i++) | 791 | for (i = 0; i < nbytes; i++) |
1091 | buf[i] = R_REG(&sprom[wordoff + i]); | 792 | bbuf[i] = readb(sprom+i); |
1092 | |||
1093 | if (check_crc) { | ||
1094 | 793 | ||
1095 | if (buf[0] == 0xffff) | 794 | if (buf[0] == 0xffff) |
1096 | /* | 795 | /* |
1097 | * The hardware thinks that an srom that starts with | 796 | * The hardware thinks that an srom that starts with |
1098 | * 0xffff is blank, regardless of the rest of the | 797 | * 0xffff is blank, regardless of the rest of the |
1099 | * content, so declare it bad. | 798 | * content, so declare it bad. |
1100 | */ | 799 | */ |
1101 | return -ENODATA; | 800 | return -ENODATA; |
1102 | |||
1103 | /* fixup the endianness so crc8 will pass */ | ||
1104 | htol16_buf(buf, nwords * 2); | ||
1105 | if (crc8(brcms_srom_crc8_table, (u8 *) buf, nwords * 2, | ||
1106 | CRC8_INIT_VALUE) != | ||
1107 | CRC8_GOOD_VALUE(brcms_srom_crc8_table)) | ||
1108 | /* DBG only pci always read srom4 first, then srom8/9 */ | ||
1109 | err = -EIO; | ||
1110 | 801 | ||
802 | if (check_crc && | ||
803 | crc8(brcms_srom_crc8_table, bbuf, nbytes, CRC8_INIT_VALUE) != | ||
804 | CRC8_GOOD_VALUE(brcms_srom_crc8_table)) | ||
805 | err = -EIO; | ||
806 | else | ||
1111 | /* now correct the endianness of the byte array */ | 807 | /* now correct the endianness of the byte array */ |
1112 | ltoh16_buf(buf, nwords * 2); | 808 | le16_to_cpu_buf(buf, nwords); |
1113 | } | 809 | |
1114 | return err; | 810 | return err; |
1115 | } | 811 | } |
1116 | 812 | ||
1117 | static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) | 813 | static int otp_read_pci(struct si_pub *sih, u16 *buf, uint nwords) |
1118 | { | 814 | { |
1119 | u8 *otp; | 815 | u8 *otp; |
1120 | uint sz = OTP_SZ_MAX / 2; /* size in words */ | 816 | uint sz = OTP_SZ_MAX / 2; /* size in words */ |
@@ -1126,7 +822,8 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) | |||
1126 | 822 | ||
1127 | err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz); | 823 | err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz); |
1128 | 824 | ||
1129 | memcpy(buf, otp, bufsz); | 825 | sz = min_t(uint, sz, nwords); |
826 | memcpy(buf, otp, sz * 2); | ||
1130 | 827 | ||
1131 | kfree(otp); | 828 | kfree(otp); |
1132 | 829 | ||
@@ -1139,13 +836,13 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) | |||
1139 | return -ENODATA; | 836 | return -ENODATA; |
1140 | 837 | ||
1141 | /* fixup the endianness so crc8 will pass */ | 838 | /* fixup the endianness so crc8 will pass */ |
1142 | htol16_buf(buf, bufsz); | 839 | cpu_to_le16_buf(buf, sz); |
1143 | if (crc8(brcms_srom_crc8_table, (u8 *) buf, SROM4_WORDS * 2, | 840 | if (crc8(brcms_srom_crc8_table, (u8 *) buf, sz * 2, |
1144 | CRC8_INIT_VALUE) != CRC8_GOOD_VALUE(brcms_srom_crc8_table)) | 841 | CRC8_INIT_VALUE) != CRC8_GOOD_VALUE(brcms_srom_crc8_table)) |
1145 | err = -EIO; | 842 | err = -EIO; |
1146 | 843 | else | |
1147 | /* now correct the endianness of the byte array */ | 844 | /* now correct the endianness of the byte array */ |
1148 | ltoh16_buf(buf, bufsz); | 845 | le16_to_cpu_buf(buf, sz); |
1149 | 846 | ||
1150 | return err; | 847 | return err; |
1151 | } | 848 | } |
@@ -1157,7 +854,7 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) | |||
1157 | static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) | 854 | static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) |
1158 | { | 855 | { |
1159 | u16 *srom; | 856 | u16 *srom; |
1160 | u16 __iomem *sromwindow; | 857 | u8 __iomem *sromwindow; |
1161 | u8 sromrev = 0; | 858 | u8 sromrev = 0; |
1162 | u32 sr; | 859 | u32 sr; |
1163 | int err = 0; | 860 | int err = 0; |
@@ -1173,29 +870,16 @@ static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) | |||
1173 | 870 | ||
1174 | crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY); | 871 | crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY); |
1175 | if (ai_is_sprom_available(sih)) { | 872 | if (ai_is_sprom_available(sih)) { |
1176 | err = sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS, | 873 | err = sprom_read_pci(sih, sromwindow, 0, srom, |
1177 | true); | 874 | SROM4_WORDS, true); |
1178 | 875 | ||
1179 | if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) || | 876 | if (err == 0) |
1180 | (((sih->buscoretype == PCIE_CORE_ID) | 877 | /* srom read and passed crc */ |
1181 | && (sih->buscorerev >= 6)) | ||
1182 | || ((sih->buscoretype == PCI_CORE_ID) | ||
1183 | && (sih->buscorerev >= 0xe)))) { | ||
1184 | /* sromrev >= 4, read more */ | ||
1185 | err = sprom_read_pci(sih, sromwindow, 0, srom, | ||
1186 | SROM4_WORDS, true); | ||
1187 | sromrev = srom[SROM4_CRCREV] & 0xff; | ||
1188 | } else if (err == 0) { | ||
1189 | /* srom is good and is rev < 4 */ | ||
1190 | /* top word of sprom contains version and crc8 */ | 878 | /* top word of sprom contains version and crc8 */ |
1191 | sromrev = srom[SROM_CRCREV] & 0xff; | 879 | sromrev = srom[SROM4_CRCREV] & 0xff; |
1192 | /* bcm4401 sroms misprogrammed */ | ||
1193 | if (sromrev == 0x10) | ||
1194 | sromrev = 1; | ||
1195 | } | ||
1196 | } else { | 880 | } else { |
1197 | /* Use OTP if SPROM not available */ | 881 | /* Use OTP if SPROM not available */ |
1198 | err = otp_read_pci(sih, srom, SROM_MAX); | 882 | err = otp_read_pci(sih, srom, SROM4_WORDS); |
1199 | if (err == 0) | 883 | if (err == 0) |
1200 | /* OTP only contain SROM rev8/rev9 for now */ | 884 | /* OTP only contain SROM rev8/rev9 for now */ |
1201 | sromrev = srom[SROM4_CRCREV] & 0xff; | 885 | sromrev = srom[SROM4_CRCREV] & 0xff; |
@@ -1208,10 +892,9 @@ static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) | |||
1208 | sr = 1 << sromrev; | 892 | sr = 1 << sromrev; |
1209 | 893 | ||
1210 | /* | 894 | /* |
1211 | * srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, | 895 | * srom version check: Current valid versions: 8, 9 |
1212 | * 9 | ||
1213 | */ | 896 | */ |
1214 | if ((sr & 0x33e) == 0) { | 897 | if ((sr & 0x300) == 0) { |
1215 | err = -EINVAL; | 898 | err = -EINVAL; |
1216 | goto errout; | 899 | goto errout; |
1217 | } | 900 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.h b/drivers/net/wireless/brcm80211/brcmsmac/srom.h index 708c43ff51cc..c81df9798e50 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/srom.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/srom.h | |||
@@ -26,9 +26,4 @@ extern void srom_free_vars(struct si_pub *sih); | |||
26 | extern int srom_read(struct si_pub *sih, uint bus, void *curmap, | 26 | extern int srom_read(struct si_pub *sih, uint bus, void *curmap, |
27 | uint byteoff, uint nbytes, u16 *buf, bool check_crc); | 27 | uint byteoff, uint nbytes, u16 *buf, bool check_crc); |
28 | 28 | ||
29 | /* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP | ||
30 | * and extract from it into name=value pairs | ||
31 | */ | ||
32 | extern int srom_parsecis(u8 **pcis, uint ciscnt, | ||
33 | char **vars, uint *count); | ||
34 | #endif /* _BRCM_SROM_H_ */ | 29 | #endif /* _BRCM_SROM_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index f27c48910827..b7537f70a795 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/netdevice.h> | 17 | #include <linux/netdevice.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | |||
19 | #include <brcmu_utils.h> | 20 | #include <brcmu_utils.h> |
20 | 21 | ||
21 | MODULE_AUTHOR("Broadcom Corporation"); | 22 | MODULE_AUTHOR("Broadcom Corporation"); |
@@ -40,74 +41,20 @@ EXPORT_SYMBOL(brcmu_pkt_buf_get_skb); | |||
40 | /* Free the driver packet. Free the tag if present */ | 41 | /* Free the driver packet. Free the tag if present */ |
41 | void brcmu_pkt_buf_free_skb(struct sk_buff *skb) | 42 | void brcmu_pkt_buf_free_skb(struct sk_buff *skb) |
42 | { | 43 | { |
43 | struct sk_buff *nskb; | 44 | WARN_ON(skb->next); |
44 | int nest = 0; | 45 | if (skb->destructor) |
45 | 46 | /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if | |
46 | /* perversion: we use skb->next to chain multi-skb packets */ | 47 | * destructor exists |
47 | while (skb) { | 48 | */ |
48 | nskb = skb->next; | 49 | dev_kfree_skb_any(skb); |
49 | skb->next = NULL; | 50 | else |
50 | 51 | /* can free immediately (even in_irq()) if destructor | |
51 | if (skb->destructor) | 52 | * does not exist |
52 | /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if | 53 | */ |
53 | * destructor exists | 54 | dev_kfree_skb(skb); |
54 | */ | ||
55 | dev_kfree_skb_any(skb); | ||
56 | else | ||
57 | /* can free immediately (even in_irq()) if destructor | ||
58 | * does not exist | ||
59 | */ | ||
60 | dev_kfree_skb(skb); | ||
61 | |||
62 | nest++; | ||
63 | skb = nskb; | ||
64 | } | ||
65 | } | 55 | } |
66 | EXPORT_SYMBOL(brcmu_pkt_buf_free_skb); | 56 | EXPORT_SYMBOL(brcmu_pkt_buf_free_skb); |
67 | 57 | ||
68 | |||
69 | /* copy a buffer into a pkt buffer chain */ | ||
70 | uint brcmu_pktfrombuf(struct sk_buff *p, uint offset, int len, | ||
71 | unsigned char *buf) | ||
72 | { | ||
73 | uint n, ret = 0; | ||
74 | |||
75 | /* skip 'offset' bytes */ | ||
76 | for (; p && offset; p = p->next) { | ||
77 | if (offset < (uint) (p->len)) | ||
78 | break; | ||
79 | offset -= p->len; | ||
80 | } | ||
81 | |||
82 | if (!p) | ||
83 | return 0; | ||
84 | |||
85 | /* copy the data */ | ||
86 | for (; p && len; p = p->next) { | ||
87 | n = min((uint) (p->len) - offset, (uint) len); | ||
88 | memcpy(p->data + offset, buf, n); | ||
89 | buf += n; | ||
90 | len -= n; | ||
91 | ret += n; | ||
92 | offset = 0; | ||
93 | } | ||
94 | |||
95 | return ret; | ||
96 | } | ||
97 | EXPORT_SYMBOL(brcmu_pktfrombuf); | ||
98 | |||
99 | /* return total length of buffer chain */ | ||
100 | uint brcmu_pkttotlen(struct sk_buff *p) | ||
101 | { | ||
102 | uint total; | ||
103 | |||
104 | total = 0; | ||
105 | for (; p; p = p->next) | ||
106 | total += p->len; | ||
107 | return total; | ||
108 | } | ||
109 | EXPORT_SYMBOL(brcmu_pkttotlen); | ||
110 | |||
111 | /* | 58 | /* |
112 | * osl multiple-precedence packet queue | 59 | * osl multiple-precedence packet queue |
113 | * hi_prec is always >= the number of the highest non-empty precedence | 60 | * hi_prec is always >= the number of the highest non-empty precedence |
@@ -115,21 +62,13 @@ EXPORT_SYMBOL(brcmu_pkttotlen); | |||
115 | struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, | 62 | struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, |
116 | struct sk_buff *p) | 63 | struct sk_buff *p) |
117 | { | 64 | { |
118 | struct pktq_prec *q; | 65 | struct sk_buff_head *q; |
119 | 66 | ||
120 | if (pktq_full(pq) || pktq_pfull(pq, prec)) | 67 | if (pktq_full(pq) || pktq_pfull(pq, prec)) |
121 | return NULL; | 68 | return NULL; |
122 | 69 | ||
123 | q = &pq->q[prec]; | 70 | q = &pq->q[prec].skblist; |
124 | 71 | skb_queue_tail(q, p); | |
125 | if (q->head) | ||
126 | q->tail->prev = p; | ||
127 | else | ||
128 | q->head = p; | ||
129 | |||
130 | q->tail = p; | ||
131 | q->len++; | ||
132 | |||
133 | pq->len++; | 72 | pq->len++; |
134 | 73 | ||
135 | if (pq->hi_prec < prec) | 74 | if (pq->hi_prec < prec) |
@@ -142,20 +81,13 @@ EXPORT_SYMBOL(brcmu_pktq_penq); | |||
142 | struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, | 81 | struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, |
143 | struct sk_buff *p) | 82 | struct sk_buff *p) |
144 | { | 83 | { |
145 | struct pktq_prec *q; | 84 | struct sk_buff_head *q; |
146 | 85 | ||
147 | if (pktq_full(pq) || pktq_pfull(pq, prec)) | 86 | if (pktq_full(pq) || pktq_pfull(pq, prec)) |
148 | return NULL; | 87 | return NULL; |
149 | 88 | ||
150 | q = &pq->q[prec]; | 89 | q = &pq->q[prec].skblist; |
151 | 90 | skb_queue_head(q, p); | |
152 | if (q->head == NULL) | ||
153 | q->tail = p; | ||
154 | |||
155 | p->prev = q->head; | ||
156 | q->head = p; | ||
157 | q->len++; | ||
158 | |||
159 | pq->len++; | 91 | pq->len++; |
160 | 92 | ||
161 | if (pq->hi_prec < prec) | 93 | if (pq->hi_prec < prec) |
@@ -167,53 +99,30 @@ EXPORT_SYMBOL(brcmu_pktq_penq_head); | |||
167 | 99 | ||
168 | struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec) | 100 | struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec) |
169 | { | 101 | { |
170 | struct pktq_prec *q; | 102 | struct sk_buff_head *q; |
171 | struct sk_buff *p; | 103 | struct sk_buff *p; |
172 | 104 | ||
173 | q = &pq->q[prec]; | 105 | q = &pq->q[prec].skblist; |
174 | 106 | p = skb_dequeue(q); | |
175 | p = q->head; | ||
176 | if (p == NULL) | 107 | if (p == NULL) |
177 | return NULL; | 108 | return NULL; |
178 | 109 | ||
179 | q->head = p->prev; | ||
180 | if (q->head == NULL) | ||
181 | q->tail = NULL; | ||
182 | |||
183 | q->len--; | ||
184 | |||
185 | pq->len--; | 110 | pq->len--; |
186 | |||
187 | p->prev = NULL; | ||
188 | |||
189 | return p; | 111 | return p; |
190 | } | 112 | } |
191 | EXPORT_SYMBOL(brcmu_pktq_pdeq); | 113 | EXPORT_SYMBOL(brcmu_pktq_pdeq); |
192 | 114 | ||
193 | struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec) | 115 | struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec) |
194 | { | 116 | { |
195 | struct pktq_prec *q; | 117 | struct sk_buff_head *q; |
196 | struct sk_buff *p, *prev; | 118 | struct sk_buff *p; |
197 | |||
198 | q = &pq->q[prec]; | ||
199 | 119 | ||
200 | p = q->head; | 120 | q = &pq->q[prec].skblist; |
121 | p = skb_dequeue_tail(q); | ||
201 | if (p == NULL) | 122 | if (p == NULL) |
202 | return NULL; | 123 | return NULL; |
203 | 124 | ||
204 | for (prev = NULL; p != q->tail; p = p->prev) | ||
205 | prev = p; | ||
206 | |||
207 | if (prev) | ||
208 | prev->prev = NULL; | ||
209 | else | ||
210 | q->head = NULL; | ||
211 | |||
212 | q->tail = prev; | ||
213 | q->len--; | ||
214 | |||
215 | pq->len--; | 125 | pq->len--; |
216 | |||
217 | return p; | 126 | return p; |
218 | } | 127 | } |
219 | EXPORT_SYMBOL(brcmu_pktq_pdeq_tail); | 128 | EXPORT_SYMBOL(brcmu_pktq_pdeq_tail); |
@@ -222,31 +131,17 @@ void | |||
222 | brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir, | 131 | brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir, |
223 | bool (*fn)(struct sk_buff *, void *), void *arg) | 132 | bool (*fn)(struct sk_buff *, void *), void *arg) |
224 | { | 133 | { |
225 | struct pktq_prec *q; | 134 | struct sk_buff_head *q; |
226 | struct sk_buff *p, *prev = NULL; | 135 | struct sk_buff *p, *next; |
227 | 136 | ||
228 | q = &pq->q[prec]; | 137 | q = &pq->q[prec].skblist; |
229 | p = q->head; | 138 | skb_queue_walk_safe(q, p, next) { |
230 | while (p) { | ||
231 | if (fn == NULL || (*fn) (p, arg)) { | 139 | if (fn == NULL || (*fn) (p, arg)) { |
232 | bool head = (p == q->head); | 140 | skb_unlink(p, q); |
233 | if (head) | ||
234 | q->head = p->prev; | ||
235 | else | ||
236 | prev->prev = p->prev; | ||
237 | p->prev = NULL; | ||
238 | brcmu_pkt_buf_free_skb(p); | 141 | brcmu_pkt_buf_free_skb(p); |
239 | q->len--; | ||
240 | pq->len--; | 142 | pq->len--; |
241 | p = (head ? q->head : prev->prev); | ||
242 | } else { | ||
243 | prev = p; | ||
244 | p = p->prev; | ||
245 | } | 143 | } |
246 | } | 144 | } |
247 | |||
248 | if (q->head == NULL) | ||
249 | q->tail = NULL; | ||
250 | } | 145 | } |
251 | EXPORT_SYMBOL(brcmu_pktq_pflush); | 146 | EXPORT_SYMBOL(brcmu_pktq_pflush); |
252 | 147 | ||
@@ -271,8 +166,10 @@ void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len) | |||
271 | 166 | ||
272 | pq->max = (u16) max_len; | 167 | pq->max = (u16) max_len; |
273 | 168 | ||
274 | for (prec = 0; prec < num_prec; prec++) | 169 | for (prec = 0; prec < num_prec; prec++) { |
275 | pq->q[prec].max = pq->max; | 170 | pq->q[prec].max = pq->max; |
171 | skb_queue_head_init(&pq->q[prec].skblist); | ||
172 | } | ||
276 | } | 173 | } |
277 | EXPORT_SYMBOL(brcmu_pktq_init); | 174 | EXPORT_SYMBOL(brcmu_pktq_init); |
278 | 175 | ||
@@ -284,13 +181,13 @@ struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out) | |||
284 | return NULL; | 181 | return NULL; |
285 | 182 | ||
286 | for (prec = 0; prec < pq->hi_prec; prec++) | 183 | for (prec = 0; prec < pq->hi_prec; prec++) |
287 | if (pq->q[prec].head) | 184 | if (!skb_queue_empty(&pq->q[prec].skblist)) |
288 | break; | 185 | break; |
289 | 186 | ||
290 | if (prec_out) | 187 | if (prec_out) |
291 | *prec_out = prec; | 188 | *prec_out = prec; |
292 | 189 | ||
293 | return pq->q[prec].tail; | 190 | return skb_peek_tail(&pq->q[prec].skblist); |
294 | } | 191 | } |
295 | EXPORT_SYMBOL(brcmu_pktq_peek_tail); | 192 | EXPORT_SYMBOL(brcmu_pktq_peek_tail); |
296 | 193 | ||
@@ -303,7 +200,7 @@ int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp) | |||
303 | 200 | ||
304 | for (prec = 0; prec <= pq->hi_prec; prec++) | 201 | for (prec = 0; prec <= pq->hi_prec; prec++) |
305 | if (prec_bmp & (1 << prec)) | 202 | if (prec_bmp & (1 << prec)) |
306 | len += pq->q[prec].len; | 203 | len += pq->q[prec].skblist.qlen; |
307 | 204 | ||
308 | return len; | 205 | return len; |
309 | } | 206 | } |
@@ -313,39 +210,32 @@ EXPORT_SYMBOL(brcmu_pktq_mlen); | |||
313 | struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, | 210 | struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, |
314 | int *prec_out) | 211 | int *prec_out) |
315 | { | 212 | { |
316 | struct pktq_prec *q; | 213 | struct sk_buff_head *q; |
317 | struct sk_buff *p; | 214 | struct sk_buff *p; |
318 | int prec; | 215 | int prec; |
319 | 216 | ||
320 | if (pq->len == 0) | 217 | if (pq->len == 0) |
321 | return NULL; | 218 | return NULL; |
322 | 219 | ||
323 | while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) | 220 | while ((prec = pq->hi_prec) > 0 && |
221 | skb_queue_empty(&pq->q[prec].skblist)) | ||
324 | pq->hi_prec--; | 222 | pq->hi_prec--; |
325 | 223 | ||
326 | while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) | 224 | while ((prec_bmp & (1 << prec)) == 0 || |
225 | skb_queue_empty(&pq->q[prec].skblist)) | ||
327 | if (prec-- == 0) | 226 | if (prec-- == 0) |
328 | return NULL; | 227 | return NULL; |
329 | 228 | ||
330 | q = &pq->q[prec]; | 229 | q = &pq->q[prec].skblist; |
331 | 230 | p = skb_dequeue(q); | |
332 | p = q->head; | ||
333 | if (p == NULL) | 231 | if (p == NULL) |
334 | return NULL; | 232 | return NULL; |
335 | 233 | ||
336 | q->head = p->prev; | 234 | pq->len--; |
337 | if (q->head == NULL) | ||
338 | q->tail = NULL; | ||
339 | |||
340 | q->len--; | ||
341 | 235 | ||
342 | if (prec_out) | 236 | if (prec_out) |
343 | *prec_out = prec; | 237 | *prec_out = prec; |
344 | 238 | ||
345 | pq->len--; | ||
346 | |||
347 | p->prev = NULL; | ||
348 | |||
349 | return p; | 239 | return p; |
350 | } | 240 | } |
351 | EXPORT_SYMBOL(brcmu_pktq_mdeq); | 241 | EXPORT_SYMBOL(brcmu_pktq_mdeq); |
@@ -364,23 +254,3 @@ void brcmu_prpkt(const char *msg, struct sk_buff *p0) | |||
364 | } | 254 | } |
365 | EXPORT_SYMBOL(brcmu_prpkt); | 255 | EXPORT_SYMBOL(brcmu_prpkt); |
366 | #endif /* defined(BCMDBG) */ | 256 | #endif /* defined(BCMDBG) */ |
367 | |||
368 | #if defined(BCMDBG) | ||
369 | /* | ||
370 | * print bytes formatted as hex to a string. return the resulting | ||
371 | * string length | ||
372 | */ | ||
373 | int brcmu_format_hex(char *str, const void *bytes, int len) | ||
374 | { | ||
375 | int i; | ||
376 | char *p = str; | ||
377 | const u8 *src = (const u8 *)bytes; | ||
378 | |||
379 | for (i = 0; i < len; i++) { | ||
380 | p += snprintf(p, 3, "%02X", *src); | ||
381 | src++; | ||
382 | } | ||
383 | return (int)(p - str); | ||
384 | } | ||
385 | EXPORT_SYMBOL(brcmu_format_hex); | ||
386 | #endif /* defined(BCMDBG) */ | ||
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h index 7d0f46e0eb95..ad249a0b4730 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h | |||
@@ -65,9 +65,7 @@ | |||
65 | #define ETHER_ADDR_STR_LEN 18 | 65 | #define ETHER_ADDR_STR_LEN 18 |
66 | 66 | ||
67 | struct pktq_prec { | 67 | struct pktq_prec { |
68 | struct sk_buff *head; /* first packet to dequeue */ | 68 | struct sk_buff_head skblist; |
69 | struct sk_buff *tail; /* last packet to dequeue */ | ||
70 | u16 len; /* number of queued packets */ | ||
71 | u16 max; /* maximum number of queued packets */ | 69 | u16 max; /* maximum number of queued packets */ |
72 | }; | 70 | }; |
73 | 71 | ||
@@ -88,32 +86,32 @@ struct pktq { | |||
88 | 86 | ||
89 | static inline int pktq_plen(struct pktq *pq, int prec) | 87 | static inline int pktq_plen(struct pktq *pq, int prec) |
90 | { | 88 | { |
91 | return pq->q[prec].len; | 89 | return pq->q[prec].skblist.qlen; |
92 | } | 90 | } |
93 | 91 | ||
94 | static inline int pktq_pavail(struct pktq *pq, int prec) | 92 | static inline int pktq_pavail(struct pktq *pq, int prec) |
95 | { | 93 | { |
96 | return pq->q[prec].max - pq->q[prec].len; | 94 | return pq->q[prec].max - pq->q[prec].skblist.qlen; |
97 | } | 95 | } |
98 | 96 | ||
99 | static inline bool pktq_pfull(struct pktq *pq, int prec) | 97 | static inline bool pktq_pfull(struct pktq *pq, int prec) |
100 | { | 98 | { |
101 | return pq->q[prec].len >= pq->q[prec].max; | 99 | return pq->q[prec].skblist.qlen >= pq->q[prec].max; |
102 | } | 100 | } |
103 | 101 | ||
104 | static inline bool pktq_pempty(struct pktq *pq, int prec) | 102 | static inline bool pktq_pempty(struct pktq *pq, int prec) |
105 | { | 103 | { |
106 | return pq->q[prec].len == 0; | 104 | return skb_queue_empty(&pq->q[prec].skblist); |
107 | } | 105 | } |
108 | 106 | ||
109 | static inline struct sk_buff *pktq_ppeek(struct pktq *pq, int prec) | 107 | static inline struct sk_buff *pktq_ppeek(struct pktq *pq, int prec) |
110 | { | 108 | { |
111 | return pq->q[prec].head; | 109 | return skb_peek(&pq->q[prec].skblist); |
112 | } | 110 | } |
113 | 111 | ||
114 | static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec) | 112 | static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec) |
115 | { | 113 | { |
116 | return pq->q[prec].tail; | 114 | return skb_peek_tail(&pq->q[prec].skblist); |
117 | } | 115 | } |
118 | 116 | ||
119 | extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, | 117 | extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, |
@@ -172,24 +170,16 @@ extern void brcmu_pktq_flush(struct pktq *pq, bool dir, | |||
172 | bool (*fn)(struct sk_buff *, void *), void *arg); | 170 | bool (*fn)(struct sk_buff *, void *), void *arg); |
173 | 171 | ||
174 | /* externs */ | 172 | /* externs */ |
175 | /* packet */ | ||
176 | extern uint brcmu_pktfrombuf(struct sk_buff *p, | ||
177 | uint offset, int len, unsigned char *buf); | ||
178 | extern uint brcmu_pkttotlen(struct sk_buff *p); | ||
179 | |||
180 | /* ip address */ | 173 | /* ip address */ |
181 | struct ipv4_addr; | 174 | struct ipv4_addr; |
182 | 175 | ||
176 | |||
177 | /* externs */ | ||
178 | /* format/print */ | ||
183 | #ifdef BCMDBG | 179 | #ifdef BCMDBG |
184 | extern void brcmu_prpkt(const char *msg, struct sk_buff *p0); | 180 | extern void brcmu_prpkt(const char *msg, struct sk_buff *p0); |
185 | #else | 181 | #else |
186 | #define brcmu_prpkt(a, b) | 182 | #define brcmu_prpkt(a, b) |
187 | #endif /* BCMDBG */ | 183 | #endif /* BCMDBG */ |
188 | 184 | ||
189 | /* externs */ | ||
190 | /* format/print */ | ||
191 | #if defined(BCMDBG) | ||
192 | extern int brcmu_format_hex(char *str, const void *bytes, int len); | ||
193 | #endif | ||
194 | |||
195 | #endif /* _BRCMU_UTILS_H_ */ | 185 | #endif /* _BRCMU_UTILS_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h index 1e5f310af1e7..f0d8c04a9c8c 100644 --- a/drivers/net/wireless/brcm80211/include/defs.h +++ b/drivers/net/wireless/brcm80211/include/defs.h | |||
@@ -62,7 +62,6 @@ | |||
62 | 62 | ||
63 | #define WL_RADIO_SW_DISABLE (1<<0) | 63 | #define WL_RADIO_SW_DISABLE (1<<0) |
64 | #define WL_RADIO_HW_DISABLE (1<<1) | 64 | #define WL_RADIO_HW_DISABLE (1<<1) |
65 | #define WL_RADIO_MPC_DISABLE (1<<2) | ||
66 | /* some countries don't support any channel */ | 65 | /* some countries don't support any channel */ |
67 | #define WL_RADIO_COUNTRY_DISABLE (1<<3) | 66 | #define WL_RADIO_COUNTRY_DISABLE (1<<3) |
68 | 67 | ||
diff --git a/drivers/net/wireless/brcm80211/include/soc.h b/drivers/net/wireless/brcm80211/include/soc.h index 4fcb956ad9e0..4e9b7e4827ea 100644 --- a/drivers/net/wireless/brcm80211/include/soc.h +++ b/drivers/net/wireless/brcm80211/include/soc.h | |||
@@ -77,8 +77,9 @@ | |||
77 | #define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ | 77 | #define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ |
78 | #define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ | 78 | #define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ |
79 | #define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ | 79 | #define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ |
80 | /* Default component, in ai chips it maps all unused address ranges */ | 80 | #define DEF_AI_COMP 0xfff /* Default component, in ai chips it |
81 | #define DEF_AI_COMP 0xfff | 81 | * maps all unused address ranges |
82 | */ | ||
82 | 83 | ||
83 | /* Common core control flags */ | 84 | /* Common core control flags */ |
84 | #define SICF_BIST_EN 0x8000 | 85 | #define SICF_BIST_EN 0x8000 |
@@ -87,4 +88,11 @@ | |||
87 | #define SICF_FGC 0x0002 | 88 | #define SICF_FGC 0x0002 |
88 | #define SICF_CLOCK_EN 0x0001 | 89 | #define SICF_CLOCK_EN 0x0001 |
89 | 90 | ||
91 | /* Common core status flags */ | ||
92 | #define SISF_BIST_DONE 0x8000 | ||
93 | #define SISF_BIST_ERROR 0x4000 | ||
94 | #define SISF_GATED_CLK 0x2000 | ||
95 | #define SISF_DMA64 0x1000 | ||
96 | #define SISF_CORE_BITS 0x0fff | ||
97 | |||
90 | #endif /* _BRCM_SOC_H */ | 98 | #endif /* _BRCM_SOC_H */ |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 99a710dfe771..99575884ff52 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -131,6 +131,14 @@ static struct ieee80211_rate ipw2200_rates[] = { | |||
131 | #define ipw2200_bg_rates (ipw2200_rates + 0) | 131 | #define ipw2200_bg_rates (ipw2200_rates + 0) |
132 | #define ipw2200_num_bg_rates 12 | 132 | #define ipw2200_num_bg_rates 12 |
133 | 133 | ||
134 | /* Ugly macro to convert literal channel numbers into their mhz equivalents | ||
135 | * There are certianly some conditions that will break this (like feeding it '30') | ||
136 | * but they shouldn't arise since nothing talks on channel 30. */ | ||
137 | #define ieee80211chan2mhz(x) \ | ||
138 | (((x) <= 14) ? \ | ||
139 | (((x) == 14) ? 2484 : ((x) * 5) + 2407) : \ | ||
140 | ((x) + 1000) * 5) | ||
141 | |||
134 | #ifdef CONFIG_IPW2200_QOS | 142 | #ifdef CONFIG_IPW2200_QOS |
135 | static int qos_enable = 0; | 143 | static int qos_enable = 0; |
136 | static int qos_burst_enable = 0; | 144 | static int qos_burst_enable = 0; |
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index 70f5586d96bd..3d5821eeb054 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h | |||
@@ -66,16 +66,8 @@ extern u32 libipw_debug_level; | |||
66 | do { if (libipw_debug_level & (level)) \ | 66 | do { if (libipw_debug_level & (level)) \ |
67 | printk(KERN_DEBUG "libipw: %c %s " fmt, \ | 67 | printk(KERN_DEBUG "libipw: %c %s " fmt, \ |
68 | in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) | 68 | in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) |
69 | static inline bool libipw_ratelimit_debug(u32 level) | ||
70 | { | ||
71 | return (libipw_debug_level & level) && net_ratelimit(); | ||
72 | } | ||
73 | #else | 69 | #else |
74 | #define LIBIPW_DEBUG(level, fmt, args...) do {} while (0) | 70 | #define LIBIPW_DEBUG(level, fmt, args...) do {} while (0) |
75 | static inline bool libipw_ratelimit_debug(u32 level) | ||
76 | { | ||
77 | return false; | ||
78 | } | ||
79 | #endif /* CONFIG_LIBIPW_DEBUG */ | 71 | #endif /* CONFIG_LIBIPW_DEBUG */ |
80 | 72 | ||
81 | /* | 73 | /* |
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index c73e5ed8db5e..a7ab280994c8 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | # WIFI | 1 | # WIFI |
2 | obj-$(CONFIG_IWLWIFI) += iwlwifi.o | 2 | obj-$(CONFIG_IWLWIFI) += iwlwifi.o |
3 | iwlwifi-objs := iwl-agn.o iwl-agn-rs.o | 3 | iwlwifi-objs := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o |
4 | iwlwifi-objs += iwl-agn-ucode.o iwl-agn-tx.o | 4 | iwlwifi-objs += iwl-agn-ucode.o iwl-agn-tx.o |
5 | iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o | 5 | iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o |
6 | iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o | 6 | iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 79431977a968..b3193571ed07 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -270,11 +270,6 @@ struct iwl_cfg iwl2000_2bgn_cfg = { | |||
270 | .ht_params = &iwl2000_ht_params, | 270 | .ht_params = &iwl2000_ht_params, |
271 | }; | 271 | }; |
272 | 272 | ||
273 | struct iwl_cfg iwl2000_2bg_cfg = { | ||
274 | .name = "2000 Series 2x2 BG", | ||
275 | IWL_DEVICE_2000, | ||
276 | }; | ||
277 | |||
278 | struct iwl_cfg iwl2000_2bgn_d_cfg = { | 273 | struct iwl_cfg iwl2000_2bgn_d_cfg = { |
279 | .name = "2000D Series 2x2 BGN", | 274 | .name = "2000D Series 2x2 BGN", |
280 | IWL_DEVICE_2000, | 275 | IWL_DEVICE_2000, |
@@ -304,11 +299,6 @@ struct iwl_cfg iwl2030_2bgn_cfg = { | |||
304 | .ht_params = &iwl2000_ht_params, | 299 | .ht_params = &iwl2000_ht_params, |
305 | }; | 300 | }; |
306 | 301 | ||
307 | struct iwl_cfg iwl2030_2bg_cfg = { | ||
308 | .name = "2000 Series 2x2 BG/BT", | ||
309 | IWL_DEVICE_2030, | ||
310 | }; | ||
311 | |||
312 | #define IWL_DEVICE_105 \ | 302 | #define IWL_DEVICE_105 \ |
313 | .fw_name_pre = IWL105_FW_PRE, \ | 303 | .fw_name_pre = IWL105_FW_PRE, \ |
314 | .ucode_api_max = IWL105_UCODE_API_MAX, \ | 304 | .ucode_api_max = IWL105_UCODE_API_MAX, \ |
@@ -326,11 +316,6 @@ struct iwl_cfg iwl2030_2bg_cfg = { | |||
326 | .rx_with_siso_diversity = true, \ | 316 | .rx_with_siso_diversity = true, \ |
327 | .iq_invert = true \ | 317 | .iq_invert = true \ |
328 | 318 | ||
329 | struct iwl_cfg iwl105_bg_cfg = { | ||
330 | .name = "105 Series 1x1 BG", | ||
331 | IWL_DEVICE_105, | ||
332 | }; | ||
333 | |||
334 | struct iwl_cfg iwl105_bgn_cfg = { | 319 | struct iwl_cfg iwl105_bgn_cfg = { |
335 | .name = "105 Series 1x1 BGN", | 320 | .name = "105 Series 1x1 BGN", |
336 | IWL_DEVICE_105, | 321 | IWL_DEVICE_105, |
@@ -361,11 +346,6 @@ struct iwl_cfg iwl105_bgn_d_cfg = { | |||
361 | .rx_with_siso_diversity = true, \ | 346 | .rx_with_siso_diversity = true, \ |
362 | .iq_invert = true \ | 347 | .iq_invert = true \ |
363 | 348 | ||
364 | struct iwl_cfg iwl135_bg_cfg = { | ||
365 | .name = "135 Series 1x1 BG/BT", | ||
366 | IWL_DEVICE_135, | ||
367 | }; | ||
368 | |||
369 | struct iwl_cfg iwl135_bgn_cfg = { | 349 | struct iwl_cfg iwl135_bgn_cfg = { |
370 | .name = "135 Series 1x1 BGN/BT", | 350 | .name = "135 Series 1x1 BGN/BT", |
371 | IWL_DEVICE_135, | 351 | IWL_DEVICE_135, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index c840c78278db..ee3363fdf309 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -439,16 +439,6 @@ struct iwl_cfg iwl6035_2agn_cfg = { | |||
439 | .ht_params = &iwl6000_ht_params, | 439 | .ht_params = &iwl6000_ht_params, |
440 | }; | 440 | }; |
441 | 441 | ||
442 | struct iwl_cfg iwl6035_2abg_cfg = { | ||
443 | .name = "6035 Series 2x2 ABG/BT", | ||
444 | IWL_DEVICE_6030, | ||
445 | }; | ||
446 | |||
447 | struct iwl_cfg iwl6035_2bg_cfg = { | ||
448 | .name = "6035 Series 2x2 BG/BT", | ||
449 | IWL_DEVICE_6030, | ||
450 | }; | ||
451 | |||
452 | struct iwl_cfg iwl1030_bgn_cfg = { | 442 | struct iwl_cfg iwl1030_bgn_cfg = { |
453 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", | 443 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", |
454 | IWL_DEVICE_6030, | 444 | IWL_DEVICE_6030, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 1a52ed29f2d6..0bc962217351 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -827,6 +827,7 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) | |||
827 | case IEEE80211_SMPS_STATIC: | 827 | case IEEE80211_SMPS_STATIC: |
828 | case IEEE80211_SMPS_DYNAMIC: | 828 | case IEEE80211_SMPS_DYNAMIC: |
829 | return IWL_NUM_IDLE_CHAINS_SINGLE; | 829 | return IWL_NUM_IDLE_CHAINS_SINGLE; |
830 | case IEEE80211_SMPS_AUTOMATIC: | ||
830 | case IEEE80211_SMPS_OFF: | 831 | case IEEE80211_SMPS_OFF: |
831 | return active_cnt; | 832 | return active_cnt; |
832 | default: | 833 | default: |
@@ -983,3 +984,360 @@ void iwlagn_remove_notification(struct iwl_priv *priv, | |||
983 | list_del(&wait_entry->list); | 984 | list_del(&wait_entry->list); |
984 | spin_unlock_bh(&priv->notif_wait_lock); | 985 | spin_unlock_bh(&priv->notif_wait_lock); |
985 | } | 986 | } |
987 | |||
988 | #ifdef CONFIG_PM_SLEEP | ||
989 | static void iwlagn_convert_p1k(u16 *p1k, __le16 *out) | ||
990 | { | ||
991 | int i; | ||
992 | |||
993 | for (i = 0; i < IWLAGN_P1K_SIZE; i++) | ||
994 | out[i] = cpu_to_le16(p1k[i]); | ||
995 | } | ||
996 | |||
997 | struct wowlan_key_data { | ||
998 | struct iwl_rxon_context *ctx; | ||
999 | struct iwlagn_wowlan_rsc_tsc_params_cmd *rsc_tsc; | ||
1000 | struct iwlagn_wowlan_tkip_params_cmd *tkip; | ||
1001 | const u8 *bssid; | ||
1002 | bool error, use_rsc_tsc, use_tkip; | ||
1003 | }; | ||
1004 | |||
1005 | |||
1006 | static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw, | ||
1007 | struct ieee80211_vif *vif, | ||
1008 | struct ieee80211_sta *sta, | ||
1009 | struct ieee80211_key_conf *key, | ||
1010 | void *_data) | ||
1011 | { | ||
1012 | struct iwl_priv *priv = hw->priv; | ||
1013 | struct wowlan_key_data *data = _data; | ||
1014 | struct iwl_rxon_context *ctx = data->ctx; | ||
1015 | struct aes_sc *aes_sc, *aes_tx_sc = NULL; | ||
1016 | struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL; | ||
1017 | struct iwlagn_p1k_cache *rx_p1ks; | ||
1018 | u8 *rx_mic_key; | ||
1019 | struct ieee80211_key_seq seq; | ||
1020 | u32 cur_rx_iv32 = 0; | ||
1021 | u16 p1k[IWLAGN_P1K_SIZE]; | ||
1022 | int ret, i; | ||
1023 | |||
1024 | mutex_lock(&priv->shrd->mutex); | ||
1025 | |||
1026 | if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || | ||
1027 | key->cipher == WLAN_CIPHER_SUITE_WEP104) && | ||
1028 | !sta && !ctx->key_mapping_keys) | ||
1029 | ret = iwl_set_default_wep_key(priv, ctx, key); | ||
1030 | else | ||
1031 | ret = iwl_set_dynamic_key(priv, ctx, key, sta); | ||
1032 | |||
1033 | if (ret) { | ||
1034 | IWL_ERR(priv, "Error setting key during suspend!\n"); | ||
1035 | data->error = true; | ||
1036 | } | ||
1037 | |||
1038 | switch (key->cipher) { | ||
1039 | case WLAN_CIPHER_SUITE_TKIP: | ||
1040 | if (sta) { | ||
1041 | tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc; | ||
1042 | tkip_tx_sc = &data->rsc_tsc->all_tsc_rsc.tkip.tsc; | ||
1043 | |||
1044 | rx_p1ks = data->tkip->rx_uni; | ||
1045 | |||
1046 | ieee80211_get_key_tx_seq(key, &seq); | ||
1047 | tkip_tx_sc->iv16 = cpu_to_le16(seq.tkip.iv16); | ||
1048 | tkip_tx_sc->iv32 = cpu_to_le32(seq.tkip.iv32); | ||
1049 | |||
1050 | ieee80211_get_tkip_p1k_iv(key, seq.tkip.iv32, p1k); | ||
1051 | iwlagn_convert_p1k(p1k, data->tkip->tx.p1k); | ||
1052 | |||
1053 | memcpy(data->tkip->mic_keys.tx, | ||
1054 | &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], | ||
1055 | IWLAGN_MIC_KEY_SIZE); | ||
1056 | |||
1057 | rx_mic_key = data->tkip->mic_keys.rx_unicast; | ||
1058 | } else { | ||
1059 | tkip_sc = | ||
1060 | data->rsc_tsc->all_tsc_rsc.tkip.multicast_rsc; | ||
1061 | rx_p1ks = data->tkip->rx_multi; | ||
1062 | rx_mic_key = data->tkip->mic_keys.rx_mcast; | ||
1063 | } | ||
1064 | |||
1065 | /* | ||
1066 | * For non-QoS this relies on the fact that both the uCode and | ||
1067 | * mac80211 use TID 0 (as they need to to avoid replay attacks) | ||
1068 | * for checking the IV in the frames. | ||
1069 | */ | ||
1070 | for (i = 0; i < IWLAGN_NUM_RSC; i++) { | ||
1071 | ieee80211_get_key_rx_seq(key, i, &seq); | ||
1072 | tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16); | ||
1073 | tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32); | ||
1074 | /* wrapping isn't allowed, AP must rekey */ | ||
1075 | if (seq.tkip.iv32 > cur_rx_iv32) | ||
1076 | cur_rx_iv32 = seq.tkip.iv32; | ||
1077 | } | ||
1078 | |||
1079 | ieee80211_get_tkip_rx_p1k(key, data->bssid, cur_rx_iv32, p1k); | ||
1080 | iwlagn_convert_p1k(p1k, rx_p1ks[0].p1k); | ||
1081 | ieee80211_get_tkip_rx_p1k(key, data->bssid, | ||
1082 | cur_rx_iv32 + 1, p1k); | ||
1083 | iwlagn_convert_p1k(p1k, rx_p1ks[1].p1k); | ||
1084 | |||
1085 | memcpy(rx_mic_key, | ||
1086 | &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], | ||
1087 | IWLAGN_MIC_KEY_SIZE); | ||
1088 | |||
1089 | data->use_tkip = true; | ||
1090 | data->use_rsc_tsc = true; | ||
1091 | break; | ||
1092 | case WLAN_CIPHER_SUITE_CCMP: | ||
1093 | if (sta) { | ||
1094 | u8 *pn = seq.ccmp.pn; | ||
1095 | |||
1096 | aes_sc = data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc; | ||
1097 | aes_tx_sc = &data->rsc_tsc->all_tsc_rsc.aes.tsc; | ||
1098 | |||
1099 | ieee80211_get_key_tx_seq(key, &seq); | ||
1100 | aes_tx_sc->pn = cpu_to_le64( | ||
1101 | (u64)pn[5] | | ||
1102 | ((u64)pn[4] << 8) | | ||
1103 | ((u64)pn[3] << 16) | | ||
1104 | ((u64)pn[2] << 24) | | ||
1105 | ((u64)pn[1] << 32) | | ||
1106 | ((u64)pn[0] << 40)); | ||
1107 | } else | ||
1108 | aes_sc = data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc; | ||
1109 | |||
1110 | /* | ||
1111 | * For non-QoS this relies on the fact that both the uCode and | ||
1112 | * mac80211 use TID 0 for checking the IV in the frames. | ||
1113 | */ | ||
1114 | for (i = 0; i < IWLAGN_NUM_RSC; i++) { | ||
1115 | u8 *pn = seq.ccmp.pn; | ||
1116 | |||
1117 | ieee80211_get_key_rx_seq(key, i, &seq); | ||
1118 | aes_sc->pn = cpu_to_le64( | ||
1119 | (u64)pn[5] | | ||
1120 | ((u64)pn[4] << 8) | | ||
1121 | ((u64)pn[3] << 16) | | ||
1122 | ((u64)pn[2] << 24) | | ||
1123 | ((u64)pn[1] << 32) | | ||
1124 | ((u64)pn[0] << 40)); | ||
1125 | } | ||
1126 | data->use_rsc_tsc = true; | ||
1127 | break; | ||
1128 | } | ||
1129 | |||
1130 | mutex_unlock(&priv->shrd->mutex); | ||
1131 | } | ||
1132 | |||
1133 | int iwlagn_send_patterns(struct iwl_priv *priv, | ||
1134 | struct cfg80211_wowlan *wowlan) | ||
1135 | { | ||
1136 | struct iwlagn_wowlan_patterns_cmd *pattern_cmd; | ||
1137 | struct iwl_host_cmd cmd = { | ||
1138 | .id = REPLY_WOWLAN_PATTERNS, | ||
1139 | .dataflags[0] = IWL_HCMD_DFL_NOCOPY, | ||
1140 | .flags = CMD_SYNC, | ||
1141 | }; | ||
1142 | int i, err; | ||
1143 | |||
1144 | if (!wowlan->n_patterns) | ||
1145 | return 0; | ||
1146 | |||
1147 | cmd.len[0] = sizeof(*pattern_cmd) + | ||
1148 | wowlan->n_patterns * sizeof(struct iwlagn_wowlan_pattern); | ||
1149 | |||
1150 | pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL); | ||
1151 | if (!pattern_cmd) | ||
1152 | return -ENOMEM; | ||
1153 | |||
1154 | pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns); | ||
1155 | |||
1156 | for (i = 0; i < wowlan->n_patterns; i++) { | ||
1157 | int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8); | ||
1158 | |||
1159 | memcpy(&pattern_cmd->patterns[i].mask, | ||
1160 | wowlan->patterns[i].mask, mask_len); | ||
1161 | memcpy(&pattern_cmd->patterns[i].pattern, | ||
1162 | wowlan->patterns[i].pattern, | ||
1163 | wowlan->patterns[i].pattern_len); | ||
1164 | pattern_cmd->patterns[i].mask_size = mask_len; | ||
1165 | pattern_cmd->patterns[i].pattern_size = | ||
1166 | wowlan->patterns[i].pattern_len; | ||
1167 | } | ||
1168 | |||
1169 | cmd.data[0] = pattern_cmd; | ||
1170 | err = iwl_trans_send_cmd(trans(priv), &cmd); | ||
1171 | kfree(pattern_cmd); | ||
1172 | return err; | ||
1173 | } | ||
1174 | |||
1175 | int iwlagn_suspend(struct iwl_priv *priv, | ||
1176 | struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | ||
1177 | { | ||
1178 | struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd; | ||
1179 | struct iwl_rxon_cmd rxon; | ||
1180 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
1181 | struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd; | ||
1182 | struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {}; | ||
1183 | struct iwlagn_d3_config_cmd d3_cfg_cmd = {}; | ||
1184 | struct wowlan_key_data key_data = { | ||
1185 | .ctx = ctx, | ||
1186 | .bssid = ctx->active.bssid_addr, | ||
1187 | .use_rsc_tsc = false, | ||
1188 | .tkip = &tkip_cmd, | ||
1189 | .use_tkip = false, | ||
1190 | }; | ||
1191 | int ret, i; | ||
1192 | u16 seq; | ||
1193 | |||
1194 | key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL); | ||
1195 | if (!key_data.rsc_tsc) | ||
1196 | return -ENOMEM; | ||
1197 | |||
1198 | memset(&wakeup_filter_cmd, 0, sizeof(wakeup_filter_cmd)); | ||
1199 | |||
1200 | /* | ||
1201 | * We know the last used seqno, and the uCode expects to know that | ||
1202 | * one, it will increment before TX. | ||
1203 | */ | ||
1204 | seq = le16_to_cpu(priv->last_seq_ctl) & IEEE80211_SCTL_SEQ; | ||
1205 | wakeup_filter_cmd.non_qos_seq = cpu_to_le16(seq); | ||
1206 | |||
1207 | /* | ||
1208 | * For QoS counters, we store the one to use next, so subtract 0x10 | ||
1209 | * since the uCode will add 0x10 before using the value. | ||
1210 | */ | ||
1211 | for (i = 0; i < 8; i++) { | ||
1212 | seq = priv->shrd->tid_data[IWL_AP_ID][i].seq_number; | ||
1213 | seq -= 0x10; | ||
1214 | wakeup_filter_cmd.qos_seq[i] = cpu_to_le16(seq); | ||
1215 | } | ||
1216 | |||
1217 | if (wowlan->disconnect) | ||
1218 | wakeup_filter_cmd.enabled |= | ||
1219 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_BEACON_MISS | | ||
1220 | IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE); | ||
1221 | if (wowlan->magic_pkt) | ||
1222 | wakeup_filter_cmd.enabled |= | ||
1223 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_MAGIC_PACKET); | ||
1224 | if (wowlan->gtk_rekey_failure) | ||
1225 | wakeup_filter_cmd.enabled |= | ||
1226 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL); | ||
1227 | if (wowlan->eap_identity_req) | ||
1228 | wakeup_filter_cmd.enabled |= | ||
1229 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ); | ||
1230 | if (wowlan->four_way_handshake) | ||
1231 | wakeup_filter_cmd.enabled |= | ||
1232 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE); | ||
1233 | if (wowlan->n_patterns) | ||
1234 | wakeup_filter_cmd.enabled |= | ||
1235 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH); | ||
1236 | |||
1237 | if (wowlan->rfkill_release) | ||
1238 | d3_cfg_cmd.wakeup_flags |= | ||
1239 | cpu_to_le32(IWLAGN_D3_WAKEUP_RFKILL); | ||
1240 | |||
1241 | iwl_scan_cancel_timeout(priv, 200); | ||
1242 | |||
1243 | memcpy(&rxon, &ctx->active, sizeof(rxon)); | ||
1244 | |||
1245 | iwl_trans_stop_device(trans(priv)); | ||
1246 | |||
1247 | priv->shrd->wowlan = true; | ||
1248 | |||
1249 | ret = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); | ||
1250 | if (ret) | ||
1251 | goto out; | ||
1252 | |||
1253 | /* now configure WoWLAN ucode */ | ||
1254 | ret = iwl_alive_start(priv); | ||
1255 | if (ret) | ||
1256 | goto out; | ||
1257 | |||
1258 | memcpy(&ctx->staging, &rxon, sizeof(rxon)); | ||
1259 | ret = iwlagn_commit_rxon(priv, ctx); | ||
1260 | if (ret) | ||
1261 | goto out; | ||
1262 | |||
1263 | ret = iwl_power_update_mode(priv, true); | ||
1264 | if (ret) | ||
1265 | goto out; | ||
1266 | |||
1267 | if (!iwlagn_mod_params.sw_crypto) { | ||
1268 | /* mark all keys clear */ | ||
1269 | priv->ucode_key_table = 0; | ||
1270 | ctx->key_mapping_keys = 0; | ||
1271 | |||
1272 | /* | ||
1273 | * This needs to be unlocked due to lock ordering | ||
1274 | * constraints. Since we're in the suspend path | ||
1275 | * that isn't really a problem though. | ||
1276 | */ | ||
1277 | mutex_unlock(&priv->shrd->mutex); | ||
1278 | ieee80211_iter_keys(priv->hw, ctx->vif, | ||
1279 | iwlagn_wowlan_program_keys, | ||
1280 | &key_data); | ||
1281 | mutex_lock(&priv->shrd->mutex); | ||
1282 | if (key_data.error) { | ||
1283 | ret = -EIO; | ||
1284 | goto out; | ||
1285 | } | ||
1286 | |||
1287 | if (key_data.use_rsc_tsc) { | ||
1288 | struct iwl_host_cmd rsc_tsc_cmd = { | ||
1289 | .id = REPLY_WOWLAN_TSC_RSC_PARAMS, | ||
1290 | .flags = CMD_SYNC, | ||
1291 | .data[0] = key_data.rsc_tsc, | ||
1292 | .dataflags[0] = IWL_HCMD_DFL_NOCOPY, | ||
1293 | .len[0] = sizeof(key_data.rsc_tsc), | ||
1294 | }; | ||
1295 | |||
1296 | ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd); | ||
1297 | if (ret) | ||
1298 | goto out; | ||
1299 | } | ||
1300 | |||
1301 | if (key_data.use_tkip) { | ||
1302 | ret = iwl_trans_send_cmd_pdu(trans(priv), | ||
1303 | REPLY_WOWLAN_TKIP_PARAMS, | ||
1304 | CMD_SYNC, sizeof(tkip_cmd), | ||
1305 | &tkip_cmd); | ||
1306 | if (ret) | ||
1307 | goto out; | ||
1308 | } | ||
1309 | |||
1310 | if (priv->have_rekey_data) { | ||
1311 | memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd)); | ||
1312 | memcpy(kek_kck_cmd.kck, priv->kck, NL80211_KCK_LEN); | ||
1313 | kek_kck_cmd.kck_len = cpu_to_le16(NL80211_KCK_LEN); | ||
1314 | memcpy(kek_kck_cmd.kek, priv->kek, NL80211_KEK_LEN); | ||
1315 | kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN); | ||
1316 | kek_kck_cmd.replay_ctr = priv->replay_ctr; | ||
1317 | |||
1318 | ret = iwl_trans_send_cmd_pdu(trans(priv), | ||
1319 | REPLY_WOWLAN_KEK_KCK_MATERIAL, | ||
1320 | CMD_SYNC, sizeof(kek_kck_cmd), | ||
1321 | &kek_kck_cmd); | ||
1322 | if (ret) | ||
1323 | goto out; | ||
1324 | } | ||
1325 | } | ||
1326 | |||
1327 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_D3_CONFIG, CMD_SYNC, | ||
1328 | sizeof(d3_cfg_cmd), &d3_cfg_cmd); | ||
1329 | if (ret) | ||
1330 | goto out; | ||
1331 | |||
1332 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER, | ||
1333 | CMD_SYNC, sizeof(wakeup_filter_cmd), | ||
1334 | &wakeup_filter_cmd); | ||
1335 | if (ret) | ||
1336 | goto out; | ||
1337 | |||
1338 | ret = iwlagn_send_patterns(priv, wowlan); | ||
1339 | out: | ||
1340 | kfree(key_data.rsc_tsc); | ||
1341 | return ret; | ||
1342 | } | ||
1343 | #endif | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 66118cea2af3..359c47a4fcea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -1458,10 +1458,8 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1458 | break; | 1458 | break; |
1459 | case IWL_BT_COEX_TRAFFIC_LOAD_LOW: | 1459 | case IWL_BT_COEX_TRAFFIC_LOAD_LOW: |
1460 | /* avoid antenna B unless MIMO */ | 1460 | /* avoid antenna B unless MIMO */ |
1461 | valid_tx_ant = | ||
1462 | first_antenna(hw_params(priv).valid_tx_ant); | ||
1463 | if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2) | 1461 | if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2) |
1464 | tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; | 1462 | tbl->action = IWL_LEGACY_SWITCH_SISO; |
1465 | break; | 1463 | break; |
1466 | case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: | 1464 | case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: |
1467 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: | 1465 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: |
@@ -1636,10 +1634,8 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1636 | break; | 1634 | break; |
1637 | case IWL_BT_COEX_TRAFFIC_LOAD_LOW: | 1635 | case IWL_BT_COEX_TRAFFIC_LOAD_LOW: |
1638 | /* avoid antenna B unless MIMO */ | 1636 | /* avoid antenna B unless MIMO */ |
1639 | valid_tx_ant = | ||
1640 | first_antenna(hw_params(priv).valid_tx_ant); | ||
1641 | if (tbl->action == IWL_SISO_SWITCH_ANTENNA2) | 1637 | if (tbl->action == IWL_SISO_SWITCH_ANTENNA2) |
1642 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; | 1638 | tbl->action = IWL_SISO_SWITCH_MIMO2_AB; |
1643 | break; | 1639 | break; |
1644 | case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: | 1640 | case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: |
1645 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: | 1641 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 5af9e6258a16..fdb4c3786114 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c | |||
@@ -800,7 +800,8 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
800 | ctx->active.bssid_addr)) | 800 | ctx->active.bssid_addr)) |
801 | continue; | 801 | continue; |
802 | ctx->last_tx_rejected = false; | 802 | ctx->last_tx_rejected = false; |
803 | iwl_trans_wake_any_queue(trans(priv), ctx->ctxid); | 803 | iwl_trans_wake_any_queue(trans(priv), ctx->ctxid, |
804 | "channel got active"); | ||
804 | } | 805 | } |
805 | } | 806 | } |
806 | 807 | ||
@@ -1032,6 +1033,50 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
1032 | return 0; | 1033 | return 0; |
1033 | } | 1034 | } |
1034 | 1035 | ||
1036 | static int iwlagn_rx_noa_notification(struct iwl_priv *priv, | ||
1037 | struct iwl_rx_mem_buffer *rxb, | ||
1038 | struct iwl_device_cmd *cmd) | ||
1039 | { | ||
1040 | struct iwl_wipan_noa_data *new_data, *old_data; | ||
1041 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
1042 | struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->u.raw; | ||
1043 | |||
1044 | /* no condition -- we're in softirq */ | ||
1045 | old_data = rcu_dereference_protected(priv->noa_data, true); | ||
1046 | |||
1047 | if (noa_notif->noa_active) { | ||
1048 | u32 len = le16_to_cpu(noa_notif->noa_attribute.length); | ||
1049 | u32 copylen = len; | ||
1050 | |||
1051 | /* EID, len, OUI, subtype */ | ||
1052 | len += 1 + 1 + 3 + 1; | ||
1053 | /* P2P id, P2P length */ | ||
1054 | len += 1 + 2; | ||
1055 | copylen += 1 + 2; | ||
1056 | |||
1057 | new_data = kmalloc(sizeof(*new_data) + len, GFP_ATOMIC); | ||
1058 | if (new_data) { | ||
1059 | new_data->length = len; | ||
1060 | new_data->data[0] = WLAN_EID_VENDOR_SPECIFIC; | ||
1061 | new_data->data[1] = len - 2; /* not counting EID, len */ | ||
1062 | new_data->data[2] = (WLAN_OUI_WFA >> 16) & 0xff; | ||
1063 | new_data->data[3] = (WLAN_OUI_WFA >> 8) & 0xff; | ||
1064 | new_data->data[4] = (WLAN_OUI_WFA >> 0) & 0xff; | ||
1065 | new_data->data[5] = WLAN_OUI_TYPE_WFA_P2P; | ||
1066 | memcpy(&new_data->data[6], &noa_notif->noa_attribute, | ||
1067 | copylen); | ||
1068 | } | ||
1069 | } else | ||
1070 | new_data = NULL; | ||
1071 | |||
1072 | rcu_assign_pointer(priv->noa_data, new_data); | ||
1073 | |||
1074 | if (old_data) | ||
1075 | kfree_rcu(old_data, rcu_head); | ||
1076 | |||
1077 | return 0; | ||
1078 | } | ||
1079 | |||
1035 | /** | 1080 | /** |
1036 | * iwl_setup_rx_handlers - Initialize Rx handler callbacks | 1081 | * iwl_setup_rx_handlers - Initialize Rx handler callbacks |
1037 | * | 1082 | * |
@@ -1055,6 +1100,8 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
1055 | handlers[BEACON_NOTIFICATION] = iwlagn_rx_beacon_notif; | 1100 | handlers[BEACON_NOTIFICATION] = iwlagn_rx_beacon_notif; |
1056 | handlers[REPLY_ADD_STA] = iwl_add_sta_callback; | 1101 | handlers[REPLY_ADD_STA] = iwl_add_sta_callback; |
1057 | 1102 | ||
1103 | handlers[REPLY_WIPAN_NOA_NOTIFICATION] = iwlagn_rx_noa_notification; | ||
1104 | |||
1058 | /* | 1105 | /* |
1059 | * The same handler is used for both the REPLY to a discrete | 1106 | * The same handler is used for both the REPLY to a discrete |
1060 | * statistics request from the host as well as for the periodic | 1107 | * statistics request from the host as well as for the periodic |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 58a381c01c89..8de97f5a1825 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -45,7 +45,8 @@ static int iwlagn_disable_bss(struct iwl_priv *priv, | |||
45 | send->filter_flags = old_filter; | 45 | send->filter_flags = old_filter; |
46 | 46 | ||
47 | if (ret) | 47 | if (ret) |
48 | IWL_ERR(priv, "Error clearing ASSOC_MSK on BSS (%d)\n", ret); | 48 | IWL_DEBUG_QUIET_RFKILL(priv, |
49 | "Error clearing ASSOC_MSK on BSS (%d)\n", ret); | ||
49 | 50 | ||
50 | return ret; | 51 | return ret; |
51 | } | 52 | } |
@@ -116,7 +117,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, | |||
116 | if (ctx->ht.enabled) | 117 | if (ctx->ht.enabled) |
117 | ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; | 118 | ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; |
118 | 119 | ||
119 | IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", | 120 | IWL_DEBUG_INFO(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", |
120 | ctx->qos_data.qos_active, | 121 | ctx->qos_data.qos_active, |
121 | ctx->qos_data.def_qos_parm.qos_flags); | 122 | ctx->qos_data.def_qos_parm.qos_flags); |
122 | 123 | ||
@@ -124,7 +125,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, | |||
124 | sizeof(struct iwl_qosparam_cmd), | 125 | sizeof(struct iwl_qosparam_cmd), |
125 | &ctx->qos_data.def_qos_parm); | 126 | &ctx->qos_data.def_qos_parm); |
126 | if (ret) | 127 | if (ret) |
127 | IWL_ERR(priv, "Failed to update QoS\n"); | 128 | IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n"); |
128 | } | 129 | } |
129 | 130 | ||
130 | static int iwlagn_update_beacon(struct iwl_priv *priv, | 131 | static int iwlagn_update_beacon(struct iwl_priv *priv, |
@@ -541,6 +542,9 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
541 | 542 | ||
542 | mutex_lock(&priv->shrd->mutex); | 543 | mutex_lock(&priv->shrd->mutex); |
543 | 544 | ||
545 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
546 | goto out; | ||
547 | |||
544 | if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) { | 548 | if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) { |
545 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); | 549 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); |
546 | goto out; | 550 | goto out; |
@@ -840,7 +844,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
840 | if (ctx->last_tx_rejected) { | 844 | if (ctx->last_tx_rejected) { |
841 | ctx->last_tx_rejected = false; | 845 | ctx->last_tx_rejected = false; |
842 | iwl_trans_wake_any_queue(trans(priv), | 846 | iwl_trans_wake_any_queue(trans(priv), |
843 | ctx->ctxid); | 847 | ctx->ctxid, |
848 | "Disassoc: flush queue"); | ||
844 | } | 849 | } |
845 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 850 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
846 | 851 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index ed6283623932..901fd9485d75 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c | |||
@@ -647,7 +647,7 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
647 | int ret; | 647 | int ret; |
648 | struct iwl_addsta_cmd sta_cmd; | 648 | struct iwl_addsta_cmd sta_cmd; |
649 | struct iwl_link_quality_cmd lq; | 649 | struct iwl_link_quality_cmd lq; |
650 | bool active; | 650 | bool active, have_lq = false; |
651 | 651 | ||
652 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 652 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); |
653 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { | 653 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { |
@@ -657,7 +657,10 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
657 | 657 | ||
658 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); | 658 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); |
659 | sta_cmd.mode = 0; | 659 | sta_cmd.mode = 0; |
660 | memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); | 660 | if (priv->stations[sta_id].lq) { |
661 | memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); | ||
662 | have_lq = true; | ||
663 | } | ||
661 | 664 | ||
662 | active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; | 665 | active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; |
663 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | 666 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; |
@@ -679,7 +682,8 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
679 | if (ret) | 682 | if (ret) |
680 | IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", | 683 | IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", |
681 | priv->stations[sta_id].sta.sta.addr, ret); | 684 | priv->stations[sta_id].sta.sta.addr, ret); |
682 | iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); | 685 | if (have_lq) |
686 | iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); | ||
683 | } | 687 | } |
684 | 688 | ||
685 | int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) | 689 | int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) |
@@ -825,28 +829,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
825 | return ret; | 829 | return ret; |
826 | } | 830 | } |
827 | 831 | ||
828 | int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, | ||
829 | struct ieee80211_vif *vif, | ||
830 | struct ieee80211_sta *sta) | ||
831 | { | ||
832 | struct iwl_priv *priv = hw->priv; | ||
833 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
834 | int ret; | ||
835 | |||
836 | IWL_DEBUG_MAC80211(priv, "enter: received request to remove " | ||
837 | "station %pM\n", sta->addr); | ||
838 | mutex_lock(&priv->shrd->mutex); | ||
839 | IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", | ||
840 | sta->addr); | ||
841 | ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); | ||
842 | if (ret) | ||
843 | IWL_ERR(priv, "Error removing station %pM\n", | ||
844 | sta->addr); | ||
845 | mutex_unlock(&priv->shrd->mutex); | ||
846 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
847 | |||
848 | return ret; | ||
849 | } | ||
850 | 832 | ||
851 | void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 833 | void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
852 | u8 sta_id, struct iwl_link_quality_cmd *link_cmd) | 834 | u8 sta_id, struct iwl_link_quality_cmd *link_cmd) |
@@ -1464,20 +1446,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, | |||
1464 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 1446 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
1465 | } | 1447 | } |
1466 | 1448 | ||
1467 | static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | ||
1468 | { | ||
1469 | unsigned long flags; | ||
1470 | 1449 | ||
1471 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | ||
1472 | priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; | ||
1473 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; | ||
1474 | priv->stations[sta_id].sta.sta.modify_mask = 0; | ||
1475 | priv->stations[sta_id].sta.sleep_tx_count = 0; | ||
1476 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
1477 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | ||
1478 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
1479 | |||
1480 | } | ||
1481 | 1450 | ||
1482 | void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) | 1451 | void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) |
1483 | { | 1452 | { |
@@ -1494,36 +1463,3 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) | |||
1494 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1463 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); |
1495 | 1464 | ||
1496 | } | 1465 | } |
1497 | |||
1498 | void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | ||
1499 | struct ieee80211_vif *vif, | ||
1500 | enum sta_notify_cmd cmd, | ||
1501 | struct ieee80211_sta *sta) | ||
1502 | { | ||
1503 | struct iwl_priv *priv = hw->priv; | ||
1504 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
1505 | int sta_id; | ||
1506 | |||
1507 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1508 | |||
1509 | switch (cmd) { | ||
1510 | case STA_NOTIFY_SLEEP: | ||
1511 | WARN_ON(!sta_priv->client); | ||
1512 | sta_priv->asleep = true; | ||
1513 | if (atomic_read(&sta_priv->pending_frames) > 0) | ||
1514 | ieee80211_sta_block_awake(hw, sta, true); | ||
1515 | break; | ||
1516 | case STA_NOTIFY_AWAKE: | ||
1517 | WARN_ON(!sta_priv->client); | ||
1518 | if (!sta_priv->asleep) | ||
1519 | break; | ||
1520 | sta_priv->asleep = false; | ||
1521 | sta_id = iwl_sta_id(sta); | ||
1522 | if (sta_id != IWL_INVALID_STATION) | ||
1523 | iwl_sta_modify_ps_wake(priv, sta_id); | ||
1524 | break; | ||
1525 | default: | ||
1526 | break; | ||
1527 | } | ||
1528 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1529 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 35a6b71f358c..e6a02e09ee18 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -283,6 +283,19 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
283 | IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); | 283 | IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); |
284 | #endif | 284 | #endif |
285 | 285 | ||
286 | if (unlikely(ieee80211_is_probe_resp(fc))) { | ||
287 | struct iwl_wipan_noa_data *noa_data = | ||
288 | rcu_dereference(priv->noa_data); | ||
289 | |||
290 | if (noa_data && | ||
291 | pskb_expand_head(skb, 0, noa_data->length, | ||
292 | GFP_ATOMIC) == 0) { | ||
293 | memcpy(skb_put(skb, noa_data->length), | ||
294 | noa_data->data, noa_data->length); | ||
295 | hdr = (struct ieee80211_hdr *)skb->data; | ||
296 | } | ||
297 | } | ||
298 | |||
286 | hdr_len = ieee80211_hdrlen(fc); | 299 | hdr_len = ieee80211_hdrlen(fc); |
287 | 300 | ||
288 | /* For management frames use broadcast id to do not break aggregation */ | 301 | /* For management frames use broadcast id to do not break aggregation */ |
@@ -800,7 +813,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
800 | iwl_is_associated_ctx(ctx) && ctx->vif && | 813 | iwl_is_associated_ctx(ctx) && ctx->vif && |
801 | ctx->vif->type == NL80211_IFTYPE_STATION) { | 814 | ctx->vif->type == NL80211_IFTYPE_STATION) { |
802 | ctx->last_tx_rejected = true; | 815 | ctx->last_tx_rejected = true; |
803 | iwl_trans_stop_queue(trans(priv), txq_id); | 816 | iwl_trans_stop_queue(trans(priv), txq_id, |
817 | "Tx on passive channel"); | ||
804 | 818 | ||
805 | IWL_DEBUG_TX_REPLY(priv, | 819 | IWL_DEBUG_TX_REPLY(priv, |
806 | "TXQ %d status %s (0x%08x) " | 820 | "TXQ %d status %s (0x%08x) " |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 8ba0dd54e37d..9ec315b31d45 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/dma-mapping.h> | ||
34 | 35 | ||
35 | #include "iwl-dev.h" | 36 | #include "iwl-dev.h" |
36 | #include "iwl-core.h" | 37 | #include "iwl-core.h" |
@@ -72,51 +73,98 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { | |||
72 | {COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS} | 73 | {COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS} |
73 | }; | 74 | }; |
74 | 75 | ||
76 | /****************************************************************************** | ||
77 | * | ||
78 | * uCode download functions | ||
79 | * | ||
80 | ******************************************************************************/ | ||
81 | |||
82 | static void iwl_free_fw_desc(struct iwl_bus *bus, struct fw_desc *desc) | ||
83 | { | ||
84 | if (desc->v_addr) | ||
85 | dma_free_coherent(bus->dev, desc->len, | ||
86 | desc->v_addr, desc->p_addr); | ||
87 | desc->v_addr = NULL; | ||
88 | desc->len = 0; | ||
89 | } | ||
90 | |||
91 | static void iwl_free_fw_img(struct iwl_bus *bus, struct fw_img *img) | ||
92 | { | ||
93 | iwl_free_fw_desc(bus, &img->code); | ||
94 | iwl_free_fw_desc(bus, &img->data); | ||
95 | } | ||
96 | |||
97 | void iwl_dealloc_ucode(struct iwl_trans *trans) | ||
98 | { | ||
99 | iwl_free_fw_img(bus(trans), &trans->ucode_rt); | ||
100 | iwl_free_fw_img(bus(trans), &trans->ucode_init); | ||
101 | iwl_free_fw_img(bus(trans), &trans->ucode_wowlan); | ||
102 | } | ||
103 | |||
104 | int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, | ||
105 | const void *data, size_t len) | ||
106 | { | ||
107 | if (!len) { | ||
108 | desc->v_addr = NULL; | ||
109 | return -EINVAL; | ||
110 | } | ||
111 | |||
112 | desc->v_addr = dma_alloc_coherent(bus->dev, len, | ||
113 | &desc->p_addr, GFP_KERNEL); | ||
114 | if (!desc->v_addr) | ||
115 | return -ENOMEM; | ||
116 | |||
117 | desc->len = len; | ||
118 | memcpy(desc->v_addr, data, len); | ||
119 | return 0; | ||
120 | } | ||
121 | |||
75 | /* | 122 | /* |
76 | * ucode | 123 | * ucode |
77 | */ | 124 | */ |
78 | static int iwlagn_load_section(struct iwl_priv *priv, const char *name, | 125 | static int iwlagn_load_section(struct iwl_trans *trans, const char *name, |
79 | struct fw_desc *image, u32 dst_addr) | 126 | struct fw_desc *image, u32 dst_addr) |
80 | { | 127 | { |
128 | struct iwl_bus *bus = bus(trans); | ||
81 | dma_addr_t phy_addr = image->p_addr; | 129 | dma_addr_t phy_addr = image->p_addr; |
82 | u32 byte_cnt = image->len; | 130 | u32 byte_cnt = image->len; |
83 | int ret; | 131 | int ret; |
84 | 132 | ||
85 | priv->ucode_write_complete = 0; | 133 | trans->ucode_write_complete = 0; |
86 | 134 | ||
87 | iwl_write_direct32(bus(priv), | 135 | iwl_write_direct32(bus, |
88 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | 136 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), |
89 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); | 137 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); |
90 | 138 | ||
91 | iwl_write_direct32(bus(priv), | 139 | iwl_write_direct32(bus, |
92 | FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); | 140 | FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); |
93 | 141 | ||
94 | iwl_write_direct32(bus(priv), | 142 | iwl_write_direct32(bus, |
95 | FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), | 143 | FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), |
96 | phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); | 144 | phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); |
97 | 145 | ||
98 | iwl_write_direct32(bus(priv), | 146 | iwl_write_direct32(bus, |
99 | FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), | 147 | FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), |
100 | (iwl_get_dma_hi_addr(phy_addr) | 148 | (iwl_get_dma_hi_addr(phy_addr) |
101 | << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); | 149 | << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); |
102 | 150 | ||
103 | iwl_write_direct32(bus(priv), | 151 | iwl_write_direct32(bus, |
104 | FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), | 152 | FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), |
105 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | | 153 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | |
106 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | | 154 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | |
107 | FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); | 155 | FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); |
108 | 156 | ||
109 | iwl_write_direct32(bus(priv), | 157 | iwl_write_direct32(bus, |
110 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | 158 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), |
111 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | 159 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | |
112 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | | 160 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | |
113 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); | 161 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); |
114 | 162 | ||
115 | IWL_DEBUG_FW(priv, "%s uCode section being loaded...\n", name); | 163 | IWL_DEBUG_FW(bus, "%s uCode section being loaded...\n", name); |
116 | ret = wait_event_timeout(priv->shrd->wait_command_queue, | 164 | ret = wait_event_timeout(trans->shrd->wait_command_queue, |
117 | priv->ucode_write_complete, 5 * HZ); | 165 | trans->ucode_write_complete, 5 * HZ); |
118 | if (!ret) { | 166 | if (!ret) { |
119 | IWL_ERR(priv, "Could not load the %s uCode section\n", | 167 | IWL_ERR(trans, "Could not load the %s uCode section\n", |
120 | name); | 168 | name); |
121 | return -ETIMEDOUT; | 169 | return -ETIMEDOUT; |
122 | } | 170 | } |
@@ -124,17 +172,41 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name, | |||
124 | return 0; | 172 | return 0; |
125 | } | 173 | } |
126 | 174 | ||
127 | static int iwlagn_load_given_ucode(struct iwl_priv *priv, | 175 | static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans, |
128 | struct fw_img *image) | 176 | enum iwl_ucode_type ucode_type) |
177 | { | ||
178 | switch (ucode_type) { | ||
179 | case IWL_UCODE_INIT: | ||
180 | return &trans->ucode_init; | ||
181 | case IWL_UCODE_WOWLAN: | ||
182 | return &trans->ucode_wowlan; | ||
183 | case IWL_UCODE_REGULAR: | ||
184 | return &trans->ucode_rt; | ||
185 | case IWL_UCODE_NONE: | ||
186 | break; | ||
187 | } | ||
188 | return NULL; | ||
189 | } | ||
190 | |||
191 | static int iwlagn_load_given_ucode(struct iwl_trans *trans, | ||
192 | enum iwl_ucode_type ucode_type) | ||
129 | { | 193 | { |
130 | int ret = 0; | 194 | int ret = 0; |
195 | struct fw_img *image = iwl_get_ucode_image(trans, ucode_type); | ||
196 | |||
197 | |||
198 | if (!image) { | ||
199 | IWL_ERR(trans, "Invalid ucode requested (%d)\n", | ||
200 | ucode_type); | ||
201 | return -EINVAL; | ||
202 | } | ||
131 | 203 | ||
132 | ret = iwlagn_load_section(priv, "INST", &image->code, | 204 | ret = iwlagn_load_section(trans, "INST", &image->code, |
133 | IWLAGN_RTC_INST_LOWER_BOUND); | 205 | IWLAGN_RTC_INST_LOWER_BOUND); |
134 | if (ret) | 206 | if (ret) |
135 | return ret; | 207 | return ret; |
136 | 208 | ||
137 | return iwlagn_load_section(priv, "DATA", &image->data, | 209 | return iwlagn_load_section(trans, "DATA", &image->data, |
138 | IWLAGN_RTC_DATA_LOWER_BOUND); | 210 | IWLAGN_RTC_DATA_LOWER_BOUND); |
139 | } | 211 | } |
140 | 212 | ||
@@ -418,7 +490,7 @@ static int iwlagn_alive_notify(struct iwl_priv *priv) | |||
418 | * using sample data 100 bytes apart. If these sample points are good, | 490 | * using sample data 100 bytes apart. If these sample points are good, |
419 | * it's a pretty good bet that everything between them is good, too. | 491 | * it's a pretty good bet that everything between them is good, too. |
420 | */ | 492 | */ |
421 | static int iwl_verify_inst_sparse(struct iwl_priv *priv, | 493 | static int iwl_verify_inst_sparse(struct iwl_bus *bus, |
422 | struct fw_desc *fw_desc) | 494 | struct fw_desc *fw_desc) |
423 | { | 495 | { |
424 | __le32 *image = (__le32 *)fw_desc->v_addr; | 496 | __le32 *image = (__le32 *)fw_desc->v_addr; |
@@ -426,15 +498,15 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, | |||
426 | u32 val; | 498 | u32 val; |
427 | u32 i; | 499 | u32 i; |
428 | 500 | ||
429 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); | 501 | IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len); |
430 | 502 | ||
431 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { | 503 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { |
432 | /* read data comes through single port, auto-incr addr */ | 504 | /* read data comes through single port, auto-incr addr */ |
433 | /* NOTE: Use the debugless read so we don't flood kernel log | 505 | /* NOTE: Use the debugless read so we don't flood kernel log |
434 | * if IWL_DL_IO is set */ | 506 | * if IWL_DL_IO is set */ |
435 | iwl_write_direct32(bus(priv), HBUS_TARG_MEM_RADDR, | 507 | iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR, |
436 | i + IWLAGN_RTC_INST_LOWER_BOUND); | 508 | i + IWLAGN_RTC_INST_LOWER_BOUND); |
437 | val = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | 509 | val = iwl_read32(bus, HBUS_TARG_MEM_RDAT); |
438 | if (val != le32_to_cpu(*image)) | 510 | if (val != le32_to_cpu(*image)) |
439 | return -EIO; | 511 | return -EIO; |
440 | } | 512 | } |
@@ -442,7 +514,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, | |||
442 | return 0; | 514 | return 0; |
443 | } | 515 | } |
444 | 516 | ||
445 | static void iwl_print_mismatch_inst(struct iwl_priv *priv, | 517 | static void iwl_print_mismatch_inst(struct iwl_bus *bus, |
446 | struct fw_desc *fw_desc) | 518 | struct fw_desc *fw_desc) |
447 | { | 519 | { |
448 | __le32 *image = (__le32 *)fw_desc->v_addr; | 520 | __le32 *image = (__le32 *)fw_desc->v_addr; |
@@ -451,18 +523,18 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, | |||
451 | u32 offs; | 523 | u32 offs; |
452 | int errors = 0; | 524 | int errors = 0; |
453 | 525 | ||
454 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); | 526 | IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len); |
455 | 527 | ||
456 | iwl_write_direct32(bus(priv), HBUS_TARG_MEM_RADDR, | 528 | iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR, |
457 | IWLAGN_RTC_INST_LOWER_BOUND); | 529 | IWLAGN_RTC_INST_LOWER_BOUND); |
458 | 530 | ||
459 | for (offs = 0; | 531 | for (offs = 0; |
460 | offs < len && errors < 20; | 532 | offs < len && errors < 20; |
461 | offs += sizeof(u32), image++) { | 533 | offs += sizeof(u32), image++) { |
462 | /* read data comes through single port, auto-incr addr */ | 534 | /* read data comes through single port, auto-incr addr */ |
463 | val = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | 535 | val = iwl_read32(bus, HBUS_TARG_MEM_RDAT); |
464 | if (val != le32_to_cpu(*image)) { | 536 | if (val != le32_to_cpu(*image)) { |
465 | IWL_ERR(priv, "uCode INST section at " | 537 | IWL_ERR(bus, "uCode INST section at " |
466 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | 538 | "offset 0x%x, is 0x%x, s/b 0x%x\n", |
467 | offs, val, le32_to_cpu(*image)); | 539 | offs, val, le32_to_cpu(*image)); |
468 | errors++; | 540 | errors++; |
@@ -474,16 +546,24 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, | |||
474 | * iwl_verify_ucode - determine which instruction image is in SRAM, | 546 | * iwl_verify_ucode - determine which instruction image is in SRAM, |
475 | * and verify its contents | 547 | * and verify its contents |
476 | */ | 548 | */ |
477 | static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_img *img) | 549 | static int iwl_verify_ucode(struct iwl_trans *trans, |
550 | enum iwl_ucode_type ucode_type) | ||
478 | { | 551 | { |
479 | if (!iwl_verify_inst_sparse(priv, &img->code)) { | 552 | struct fw_img *img = iwl_get_ucode_image(trans, ucode_type); |
480 | IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); | 553 | |
554 | if (!img) { | ||
555 | IWL_ERR(trans, "Invalid ucode requested (%d)\n", ucode_type); | ||
556 | return -EINVAL; | ||
557 | } | ||
558 | |||
559 | if (!iwl_verify_inst_sparse(bus(trans), &img->code)) { | ||
560 | IWL_DEBUG_FW(trans, "uCode is good in inst SRAM\n"); | ||
481 | return 0; | 561 | return 0; |
482 | } | 562 | } |
483 | 563 | ||
484 | IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); | 564 | IWL_ERR(trans, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); |
485 | 565 | ||
486 | iwl_print_mismatch_inst(priv, &img->code); | 566 | iwl_print_mismatch_inst(bus(trans), &img->code); |
487 | return -EIO; | 567 | return -EIO; |
488 | } | 568 | } |
489 | 569 | ||
@@ -519,13 +599,12 @@ static void iwlagn_alive_fn(struct iwl_priv *priv, | |||
519 | #define UCODE_CALIB_TIMEOUT (2*HZ) | 599 | #define UCODE_CALIB_TIMEOUT (2*HZ) |
520 | 600 | ||
521 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | 601 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, |
522 | struct fw_img *image, | 602 | enum iwl_ucode_type ucode_type) |
523 | enum iwlagn_ucode_type ucode_type) | ||
524 | { | 603 | { |
525 | struct iwl_notification_wait alive_wait; | 604 | struct iwl_notification_wait alive_wait; |
526 | struct iwlagn_alive_data alive_data; | 605 | struct iwlagn_alive_data alive_data; |
527 | int ret; | 606 | int ret; |
528 | enum iwlagn_ucode_type old_type; | 607 | enum iwl_ucode_type old_type; |
529 | 608 | ||
530 | ret = iwl_trans_start_device(trans(priv)); | 609 | ret = iwl_trans_start_device(trans(priv)); |
531 | if (ret) | 610 | if (ret) |
@@ -537,7 +616,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | |||
537 | old_type = priv->ucode_type; | 616 | old_type = priv->ucode_type; |
538 | priv->ucode_type = ucode_type; | 617 | priv->ucode_type = ucode_type; |
539 | 618 | ||
540 | ret = iwlagn_load_given_ucode(priv, image); | 619 | ret = iwlagn_load_given_ucode(trans(priv), ucode_type); |
541 | if (ret) { | 620 | if (ret) { |
542 | priv->ucode_type = old_type; | 621 | priv->ucode_type = old_type; |
543 | iwlagn_remove_notification(priv, &alive_wait); | 622 | iwlagn_remove_notification(priv, &alive_wait); |
@@ -568,7 +647,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | |||
568 | * skip it for WoWLAN. | 647 | * skip it for WoWLAN. |
569 | */ | 648 | */ |
570 | if (ucode_type != IWL_UCODE_WOWLAN) { | 649 | if (ucode_type != IWL_UCODE_WOWLAN) { |
571 | ret = iwl_verify_ucode(priv, image); | 650 | ret = iwl_verify_ucode(trans(priv), ucode_type); |
572 | if (ret) { | 651 | if (ret) { |
573 | priv->ucode_type = old_type; | 652 | priv->ucode_type = old_type; |
574 | return ret; | 653 | return ret; |
@@ -597,7 +676,7 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv) | |||
597 | lockdep_assert_held(&priv->shrd->mutex); | 676 | lockdep_assert_held(&priv->shrd->mutex); |
598 | 677 | ||
599 | /* No init ucode required? Curious, but maybe ok */ | 678 | /* No init ucode required? Curious, but maybe ok */ |
600 | if (!priv->ucode_init.code.len) | 679 | if (!trans(priv)->ucode_init.code.len) |
601 | return 0; | 680 | return 0; |
602 | 681 | ||
603 | if (priv->ucode_type != IWL_UCODE_NONE) | 682 | if (priv->ucode_type != IWL_UCODE_NONE) |
@@ -608,8 +687,7 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv) | |||
608 | NULL, NULL); | 687 | NULL, NULL); |
609 | 688 | ||
610 | /* Will also start the device */ | 689 | /* Will also start the device */ |
611 | ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, | 690 | ret = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_INIT); |
612 | IWL_UCODE_INIT); | ||
613 | if (ret) | 691 | if (ret) |
614 | goto error; | 692 | goto error; |
615 | 693 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ccba69b7f8a7..e235e84de8b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/dma-mapping.h> | ||
34 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
35 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
36 | #include <linux/skbuff.h> | 35 | #include <linux/skbuff.h> |
@@ -452,52 +451,6 @@ static void iwl_bg_tx_flush(struct work_struct *work) | |||
452 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); | 451 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); |
453 | } | 452 | } |
454 | 453 | ||
455 | /****************************************************************************** | ||
456 | * | ||
457 | * uCode download functions | ||
458 | * | ||
459 | ******************************************************************************/ | ||
460 | |||
461 | static void iwl_free_fw_desc(struct iwl_priv *priv, struct fw_desc *desc) | ||
462 | { | ||
463 | if (desc->v_addr) | ||
464 | dma_free_coherent(bus(priv)->dev, desc->len, | ||
465 | desc->v_addr, desc->p_addr); | ||
466 | desc->v_addr = NULL; | ||
467 | desc->len = 0; | ||
468 | } | ||
469 | |||
470 | static void iwl_free_fw_img(struct iwl_priv *priv, struct fw_img *img) | ||
471 | { | ||
472 | iwl_free_fw_desc(priv, &img->code); | ||
473 | iwl_free_fw_desc(priv, &img->data); | ||
474 | } | ||
475 | |||
476 | static void iwl_dealloc_ucode(struct iwl_priv *priv) | ||
477 | { | ||
478 | iwl_free_fw_img(priv, &priv->ucode_rt); | ||
479 | iwl_free_fw_img(priv, &priv->ucode_init); | ||
480 | iwl_free_fw_img(priv, &priv->ucode_wowlan); | ||
481 | } | ||
482 | |||
483 | static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc, | ||
484 | const void *data, size_t len) | ||
485 | { | ||
486 | if (!len) { | ||
487 | desc->v_addr = NULL; | ||
488 | return -EINVAL; | ||
489 | } | ||
490 | |||
491 | desc->v_addr = dma_alloc_coherent(bus(priv)->dev, len, | ||
492 | &desc->p_addr, GFP_KERNEL); | ||
493 | if (!desc->v_addr) | ||
494 | return -ENOMEM; | ||
495 | |||
496 | desc->len = len; | ||
497 | memcpy(desc->v_addr, data, len); | ||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | 454 | static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) |
502 | { | 455 | { |
503 | int i; | 456 | int i; |
@@ -555,16 +508,7 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | |||
555 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | 508 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); |
556 | } | 509 | } |
557 | 510 | ||
558 | |||
559 | struct iwlagn_ucode_capabilities { | ||
560 | u32 max_probe_length; | ||
561 | u32 standard_phy_calibration_size; | ||
562 | u32 flags; | ||
563 | }; | ||
564 | |||
565 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | 511 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); |
566 | static int iwlagn_mac_setup_register(struct iwl_priv *priv, | ||
567 | struct iwlagn_ucode_capabilities *capa); | ||
568 | 512 | ||
569 | #define UCODE_EXPERIMENTAL_INDEX 100 | 513 | #define UCODE_EXPERIMENTAL_INDEX 100 |
570 | #define UCODE_EXPERIMENTAL_TAG "exp" | 514 | #define UCODE_EXPERIMENTAL_TAG "exp" |
@@ -1040,30 +984,32 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1040 | /* Runtime instructions and 2 copies of data: | 984 | /* Runtime instructions and 2 copies of data: |
1041 | * 1) unmodified from disk | 985 | * 1) unmodified from disk |
1042 | * 2) backup cache for save/restore during power-downs */ | 986 | * 2) backup cache for save/restore during power-downs */ |
1043 | if (iwl_alloc_fw_desc(priv, &priv->ucode_rt.code, | 987 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.code, |
1044 | pieces.inst, pieces.inst_size)) | 988 | pieces.inst, pieces.inst_size)) |
1045 | goto err_pci_alloc; | 989 | goto err_pci_alloc; |
1046 | if (iwl_alloc_fw_desc(priv, &priv->ucode_rt.data, | 990 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.data, |
1047 | pieces.data, pieces.data_size)) | 991 | pieces.data, pieces.data_size)) |
1048 | goto err_pci_alloc; | 992 | goto err_pci_alloc; |
1049 | 993 | ||
1050 | /* Initialization instructions and data */ | 994 | /* Initialization instructions and data */ |
1051 | if (pieces.init_size && pieces.init_data_size) { | 995 | if (pieces.init_size && pieces.init_data_size) { |
1052 | if (iwl_alloc_fw_desc(priv, &priv->ucode_init.code, | 996 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.code, |
1053 | pieces.init, pieces.init_size)) | 997 | pieces.init, pieces.init_size)) |
1054 | goto err_pci_alloc; | 998 | goto err_pci_alloc; |
1055 | if (iwl_alloc_fw_desc(priv, &priv->ucode_init.data, | 999 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.data, |
1056 | pieces.init_data, pieces.init_data_size)) | 1000 | pieces.init_data, pieces.init_data_size)) |
1057 | goto err_pci_alloc; | 1001 | goto err_pci_alloc; |
1058 | } | 1002 | } |
1059 | 1003 | ||
1060 | /* WoWLAN instructions and data */ | 1004 | /* WoWLAN instructions and data */ |
1061 | if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { | 1005 | if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { |
1062 | if (iwl_alloc_fw_desc(priv, &priv->ucode_wowlan.code, | 1006 | if (iwl_alloc_fw_desc(bus(priv), |
1007 | &trans(priv)->ucode_wowlan.code, | ||
1063 | pieces.wowlan_inst, | 1008 | pieces.wowlan_inst, |
1064 | pieces.wowlan_inst_size)) | 1009 | pieces.wowlan_inst_size)) |
1065 | goto err_pci_alloc; | 1010 | goto err_pci_alloc; |
1066 | if (iwl_alloc_fw_desc(priv, &priv->ucode_wowlan.data, | 1011 | if (iwl_alloc_fw_desc(bus(priv), |
1012 | &trans(priv)->ucode_wowlan.data, | ||
1067 | pieces.wowlan_data, | 1013 | pieces.wowlan_data, |
1068 | pieces.wowlan_data_size)) | 1014 | pieces.wowlan_data_size)) |
1069 | goto err_pci_alloc; | 1015 | goto err_pci_alloc; |
@@ -1156,7 +1102,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1156 | 1102 | ||
1157 | err_pci_alloc: | 1103 | err_pci_alloc: |
1158 | IWL_ERR(priv, "failed to allocate pci memory\n"); | 1104 | IWL_ERR(priv, "failed to allocate pci memory\n"); |
1159 | iwl_dealloc_ucode(priv); | 1105 | iwl_dealloc_ucode(trans(priv)); |
1160 | out_unbind: | 1106 | out_unbind: |
1161 | complete(&priv->firmware_loading_complete); | 1107 | complete(&priv->firmware_loading_complete); |
1162 | device_release_driver(bus(priv)->dev); | 1108 | device_release_driver(bus(priv)->dev); |
@@ -1352,7 +1298,7 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
1352 | 1298 | ||
1353 | static void iwl_cancel_deferred_work(struct iwl_priv *priv); | 1299 | static void iwl_cancel_deferred_work(struct iwl_priv *priv); |
1354 | 1300 | ||
1355 | static void __iwl_down(struct iwl_priv *priv) | 1301 | void __iwl_down(struct iwl_priv *priv) |
1356 | { | 1302 | { |
1357 | int exit_pending; | 1303 | int exit_pending; |
1358 | 1304 | ||
@@ -1415,7 +1361,7 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1415 | priv->beacon_skb = NULL; | 1361 | priv->beacon_skb = NULL; |
1416 | } | 1362 | } |
1417 | 1363 | ||
1418 | static void iwl_down(struct iwl_priv *priv) | 1364 | void iwl_down(struct iwl_priv *priv) |
1419 | { | 1365 | { |
1420 | mutex_lock(&priv->shrd->mutex); | 1366 | mutex_lock(&priv->shrd->mutex); |
1421 | __iwl_down(priv); | 1367 | __iwl_down(priv); |
@@ -1424,57 +1370,6 @@ static void iwl_down(struct iwl_priv *priv) | |||
1424 | iwl_cancel_deferred_work(priv); | 1370 | iwl_cancel_deferred_work(priv); |
1425 | } | 1371 | } |
1426 | 1372 | ||
1427 | #define MAX_HW_RESTARTS 5 | ||
1428 | |||
1429 | static int __iwl_up(struct iwl_priv *priv) | ||
1430 | { | ||
1431 | struct iwl_rxon_context *ctx; | ||
1432 | int ret; | ||
1433 | |||
1434 | lockdep_assert_held(&priv->shrd->mutex); | ||
1435 | |||
1436 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | ||
1437 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); | ||
1438 | return -EIO; | ||
1439 | } | ||
1440 | |||
1441 | for_each_context(priv, ctx) { | ||
1442 | ret = iwlagn_alloc_bcast_station(priv, ctx); | ||
1443 | if (ret) { | ||
1444 | iwl_dealloc_bcast_stations(priv); | ||
1445 | return ret; | ||
1446 | } | ||
1447 | } | ||
1448 | |||
1449 | ret = iwlagn_run_init_ucode(priv); | ||
1450 | if (ret) { | ||
1451 | IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); | ||
1452 | goto error; | ||
1453 | } | ||
1454 | |||
1455 | ret = iwlagn_load_ucode_wait_alive(priv, | ||
1456 | &priv->ucode_rt, | ||
1457 | IWL_UCODE_REGULAR); | ||
1458 | if (ret) { | ||
1459 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); | ||
1460 | goto error; | ||
1461 | } | ||
1462 | |||
1463 | ret = iwl_alive_start(priv); | ||
1464 | if (ret) | ||
1465 | goto error; | ||
1466 | return 0; | ||
1467 | |||
1468 | error: | ||
1469 | set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | ||
1470 | __iwl_down(priv); | ||
1471 | clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | ||
1472 | |||
1473 | IWL_ERR(priv, "Unable to initialize device.\n"); | ||
1474 | return ret; | ||
1475 | } | ||
1476 | |||
1477 | |||
1478 | /***************************************************************************** | 1373 | /***************************************************************************** |
1479 | * | 1374 | * |
1480 | * Workqueue callbacks | 1375 | * Workqueue callbacks |
@@ -1502,7 +1397,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
1502 | mutex_unlock(&priv->shrd->mutex); | 1397 | mutex_unlock(&priv->shrd->mutex); |
1503 | } | 1398 | } |
1504 | 1399 | ||
1505 | static void iwlagn_prepare_restart(struct iwl_priv *priv) | 1400 | void iwlagn_prepare_restart(struct iwl_priv *priv) |
1506 | { | 1401 | { |
1507 | struct iwl_rxon_context *ctx; | 1402 | struct iwl_rxon_context *ctx; |
1508 | bool bt_full_concurrent; | 1403 | bool bt_full_concurrent; |
@@ -1559,1173 +1454,8 @@ static void iwl_bg_restart(struct work_struct *data) | |||
1559 | } | 1454 | } |
1560 | } | 1455 | } |
1561 | 1456 | ||
1562 | /***************************************************************************** | ||
1563 | * | ||
1564 | * mac80211 entry point functions | ||
1565 | * | ||
1566 | *****************************************************************************/ | ||
1567 | |||
1568 | static const struct ieee80211_iface_limit iwlagn_sta_ap_limits[] = { | ||
1569 | { | ||
1570 | .max = 1, | ||
1571 | .types = BIT(NL80211_IFTYPE_STATION), | ||
1572 | }, | ||
1573 | { | ||
1574 | .max = 1, | ||
1575 | .types = BIT(NL80211_IFTYPE_AP), | ||
1576 | }, | ||
1577 | }; | ||
1578 | |||
1579 | static const struct ieee80211_iface_limit iwlagn_2sta_limits[] = { | ||
1580 | { | ||
1581 | .max = 2, | ||
1582 | .types = BIT(NL80211_IFTYPE_STATION), | ||
1583 | }, | ||
1584 | }; | ||
1585 | |||
1586 | static const struct ieee80211_iface_limit iwlagn_p2p_sta_go_limits[] = { | ||
1587 | { | ||
1588 | .max = 1, | ||
1589 | .types = BIT(NL80211_IFTYPE_STATION), | ||
1590 | }, | ||
1591 | { | ||
1592 | .max = 1, | ||
1593 | .types = BIT(NL80211_IFTYPE_P2P_GO) | | ||
1594 | BIT(NL80211_IFTYPE_AP), | ||
1595 | }, | ||
1596 | }; | ||
1597 | |||
1598 | static const struct ieee80211_iface_limit iwlagn_p2p_2sta_limits[] = { | ||
1599 | { | ||
1600 | .max = 2, | ||
1601 | .types = BIT(NL80211_IFTYPE_STATION), | ||
1602 | }, | ||
1603 | { | ||
1604 | .max = 1, | ||
1605 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT), | ||
1606 | }, | ||
1607 | }; | ||
1608 | |||
1609 | static const struct ieee80211_iface_combination | ||
1610 | iwlagn_iface_combinations_dualmode[] = { | ||
1611 | { .num_different_channels = 1, | ||
1612 | .max_interfaces = 2, | ||
1613 | .beacon_int_infra_match = true, | ||
1614 | .limits = iwlagn_sta_ap_limits, | ||
1615 | .n_limits = ARRAY_SIZE(iwlagn_sta_ap_limits), | ||
1616 | }, | ||
1617 | { .num_different_channels = 1, | ||
1618 | .max_interfaces = 2, | ||
1619 | .limits = iwlagn_2sta_limits, | ||
1620 | .n_limits = ARRAY_SIZE(iwlagn_2sta_limits), | ||
1621 | }, | ||
1622 | }; | ||
1623 | |||
1624 | static const struct ieee80211_iface_combination | ||
1625 | iwlagn_iface_combinations_p2p[] = { | ||
1626 | { .num_different_channels = 1, | ||
1627 | .max_interfaces = 2, | ||
1628 | .beacon_int_infra_match = true, | ||
1629 | .limits = iwlagn_p2p_sta_go_limits, | ||
1630 | .n_limits = ARRAY_SIZE(iwlagn_p2p_sta_go_limits), | ||
1631 | }, | ||
1632 | { .num_different_channels = 1, | ||
1633 | .max_interfaces = 2, | ||
1634 | .limits = iwlagn_p2p_2sta_limits, | ||
1635 | .n_limits = ARRAY_SIZE(iwlagn_p2p_2sta_limits), | ||
1636 | }, | ||
1637 | }; | ||
1638 | |||
1639 | /* | ||
1640 | * Not a mac80211 entry point function, but it fits in with all the | ||
1641 | * other mac80211 functions grouped here. | ||
1642 | */ | ||
1643 | static int iwlagn_mac_setup_register(struct iwl_priv *priv, | ||
1644 | struct iwlagn_ucode_capabilities *capa) | ||
1645 | { | ||
1646 | int ret; | ||
1647 | struct ieee80211_hw *hw = priv->hw; | ||
1648 | struct iwl_rxon_context *ctx; | ||
1649 | |||
1650 | hw->rate_control_algorithm = "iwl-agn-rs"; | ||
1651 | |||
1652 | /* Tell mac80211 our characteristics */ | ||
1653 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | ||
1654 | IEEE80211_HW_AMPDU_AGGREGATION | | ||
1655 | IEEE80211_HW_NEED_DTIM_PERIOD | | ||
1656 | IEEE80211_HW_SPECTRUM_MGMT | | ||
1657 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; | ||
1658 | |||
1659 | /* | ||
1660 | * Including the following line will crash some AP's. This | ||
1661 | * workaround removes the stimulus which causes the crash until | ||
1662 | * the AP software can be fixed. | ||
1663 | hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
1664 | */ | ||
1665 | |||
1666 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | ||
1667 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | ||
1668 | |||
1669 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) | ||
1670 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | ||
1671 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | ||
1672 | |||
1673 | if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) | ||
1674 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | ||
1675 | |||
1676 | hw->sta_data_size = sizeof(struct iwl_station_priv); | ||
1677 | hw->vif_data_size = sizeof(struct iwl_vif_priv); | ||
1678 | |||
1679 | for_each_context(priv, ctx) { | ||
1680 | hw->wiphy->interface_modes |= ctx->interface_modes; | ||
1681 | hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; | ||
1682 | } | ||
1683 | |||
1684 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | ||
1685 | |||
1686 | if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) { | ||
1687 | hw->wiphy->iface_combinations = iwlagn_iface_combinations_p2p; | ||
1688 | hw->wiphy->n_iface_combinations = | ||
1689 | ARRAY_SIZE(iwlagn_iface_combinations_p2p); | ||
1690 | } else if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { | ||
1691 | hw->wiphy->iface_combinations = iwlagn_iface_combinations_dualmode; | ||
1692 | hw->wiphy->n_iface_combinations = | ||
1693 | ARRAY_SIZE(iwlagn_iface_combinations_dualmode); | ||
1694 | } | ||
1695 | |||
1696 | hw->wiphy->max_remain_on_channel_duration = 1000; | ||
1697 | |||
1698 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | | ||
1699 | WIPHY_FLAG_DISABLE_BEACON_HINTS | | ||
1700 | WIPHY_FLAG_IBSS_RSN; | ||
1701 | |||
1702 | if (priv->ucode_wowlan.code.len && device_can_wakeup(bus(priv)->dev)) { | ||
1703 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | | ||
1704 | WIPHY_WOWLAN_DISCONNECT | | ||
1705 | WIPHY_WOWLAN_EAP_IDENTITY_REQ | | ||
1706 | WIPHY_WOWLAN_RFKILL_RELEASE; | ||
1707 | if (!iwlagn_mod_params.sw_crypto) | ||
1708 | hw->wiphy->wowlan.flags |= | ||
1709 | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | | ||
1710 | WIPHY_WOWLAN_GTK_REKEY_FAILURE; | ||
1711 | |||
1712 | hw->wiphy->wowlan.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS; | ||
1713 | hw->wiphy->wowlan.pattern_min_len = | ||
1714 | IWLAGN_WOWLAN_MIN_PATTERN_LEN; | ||
1715 | hw->wiphy->wowlan.pattern_max_len = | ||
1716 | IWLAGN_WOWLAN_MAX_PATTERN_LEN; | ||
1717 | } | ||
1718 | |||
1719 | if (iwlagn_mod_params.power_save) | ||
1720 | hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1721 | else | ||
1722 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1723 | |||
1724 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; | ||
1725 | /* we create the 802.11 header and a zero-length SSID element */ | ||
1726 | hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 2; | ||
1727 | |||
1728 | /* Default value; 4 EDCA QOS priorities */ | ||
1729 | hw->queues = 4; | ||
1730 | |||
1731 | hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; | ||
1732 | |||
1733 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
1734 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
1735 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
1736 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
1737 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
1738 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
1739 | |||
1740 | iwl_leds_init(priv); | ||
1741 | |||
1742 | ret = ieee80211_register_hw(priv->hw); | ||
1743 | if (ret) { | ||
1744 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); | ||
1745 | return ret; | ||
1746 | } | ||
1747 | priv->mac80211_registered = 1; | ||
1748 | |||
1749 | return 0; | ||
1750 | } | ||
1751 | |||
1752 | |||
1753 | static int iwlagn_mac_start(struct ieee80211_hw *hw) | ||
1754 | { | ||
1755 | struct iwl_priv *priv = hw->priv; | ||
1756 | int ret; | ||
1757 | |||
1758 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1759 | |||
1760 | /* we should be verifying the device is ready to be opened */ | ||
1761 | mutex_lock(&priv->shrd->mutex); | ||
1762 | ret = __iwl_up(priv); | ||
1763 | mutex_unlock(&priv->shrd->mutex); | ||
1764 | if (ret) | ||
1765 | return ret; | ||
1766 | |||
1767 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); | ||
1768 | |||
1769 | /* Now we should be done, and the READY bit should be set. */ | ||
1770 | if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status))) | ||
1771 | ret = -EIO; | ||
1772 | |||
1773 | iwlagn_led_enable(priv); | ||
1774 | |||
1775 | priv->is_open = 1; | ||
1776 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1777 | return 0; | ||
1778 | } | ||
1779 | |||
1780 | static void iwlagn_mac_stop(struct ieee80211_hw *hw) | ||
1781 | { | ||
1782 | struct iwl_priv *priv = hw->priv; | ||
1783 | |||
1784 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1785 | |||
1786 | if (!priv->is_open) | ||
1787 | return; | ||
1788 | |||
1789 | priv->is_open = 0; | ||
1790 | |||
1791 | iwl_down(priv); | ||
1792 | |||
1793 | flush_workqueue(priv->shrd->workqueue); | ||
1794 | |||
1795 | /* User space software may expect getting rfkill changes | ||
1796 | * even if interface is down */ | ||
1797 | iwl_write32(bus(priv), CSR_INT, 0xFFFFFFFF); | ||
1798 | iwl_enable_rfkill_int(priv); | ||
1799 | |||
1800 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1801 | } | ||
1802 | |||
1803 | #ifdef CONFIG_PM_SLEEP | ||
1804 | static int iwlagn_send_patterns(struct iwl_priv *priv, | ||
1805 | struct cfg80211_wowlan *wowlan) | ||
1806 | { | ||
1807 | struct iwlagn_wowlan_patterns_cmd *pattern_cmd; | ||
1808 | struct iwl_host_cmd cmd = { | ||
1809 | .id = REPLY_WOWLAN_PATTERNS, | ||
1810 | .dataflags[0] = IWL_HCMD_DFL_NOCOPY, | ||
1811 | .flags = CMD_SYNC, | ||
1812 | }; | ||
1813 | int i, err; | ||
1814 | |||
1815 | if (!wowlan->n_patterns) | ||
1816 | return 0; | ||
1817 | |||
1818 | cmd.len[0] = sizeof(*pattern_cmd) + | ||
1819 | wowlan->n_patterns * sizeof(struct iwlagn_wowlan_pattern); | ||
1820 | |||
1821 | pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL); | ||
1822 | if (!pattern_cmd) | ||
1823 | return -ENOMEM; | ||
1824 | |||
1825 | pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns); | ||
1826 | |||
1827 | for (i = 0; i < wowlan->n_patterns; i++) { | ||
1828 | int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8); | ||
1829 | |||
1830 | memcpy(&pattern_cmd->patterns[i].mask, | ||
1831 | wowlan->patterns[i].mask, mask_len); | ||
1832 | memcpy(&pattern_cmd->patterns[i].pattern, | ||
1833 | wowlan->patterns[i].pattern, | ||
1834 | wowlan->patterns[i].pattern_len); | ||
1835 | pattern_cmd->patterns[i].mask_size = mask_len; | ||
1836 | pattern_cmd->patterns[i].pattern_size = | ||
1837 | wowlan->patterns[i].pattern_len; | ||
1838 | } | ||
1839 | |||
1840 | cmd.data[0] = pattern_cmd; | ||
1841 | err = iwl_trans_send_cmd(trans(priv), &cmd); | ||
1842 | kfree(pattern_cmd); | ||
1843 | return err; | ||
1844 | } | ||
1845 | #endif | ||
1846 | |||
1847 | static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | ||
1848 | struct ieee80211_vif *vif, | ||
1849 | struct cfg80211_gtk_rekey_data *data) | ||
1850 | { | ||
1851 | struct iwl_priv *priv = hw->priv; | ||
1852 | |||
1853 | if (iwlagn_mod_params.sw_crypto) | ||
1854 | return; | ||
1855 | |||
1856 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1857 | mutex_lock(&priv->shrd->mutex); | ||
1858 | |||
1859 | if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif) | ||
1860 | goto out; | ||
1861 | |||
1862 | memcpy(priv->kek, data->kek, NL80211_KEK_LEN); | ||
1863 | memcpy(priv->kck, data->kck, NL80211_KCK_LEN); | ||
1864 | priv->replay_ctr = cpu_to_le64(be64_to_cpup((__be64 *)&data->replay_ctr)); | ||
1865 | priv->have_rekey_data = true; | ||
1866 | |||
1867 | out: | ||
1868 | mutex_unlock(&priv->shrd->mutex); | ||
1869 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1870 | } | ||
1871 | |||
1872 | struct wowlan_key_data { | ||
1873 | struct iwl_rxon_context *ctx; | ||
1874 | struct iwlagn_wowlan_rsc_tsc_params_cmd *rsc_tsc; | ||
1875 | struct iwlagn_wowlan_tkip_params_cmd *tkip; | ||
1876 | const u8 *bssid; | ||
1877 | bool error, use_rsc_tsc, use_tkip; | ||
1878 | }; | ||
1879 | |||
1880 | #ifdef CONFIG_PM_SLEEP | ||
1881 | static void iwlagn_convert_p1k(u16 *p1k, __le16 *out) | ||
1882 | { | ||
1883 | int i; | ||
1884 | |||
1885 | for (i = 0; i < IWLAGN_P1K_SIZE; i++) | ||
1886 | out[i] = cpu_to_le16(p1k[i]); | ||
1887 | } | ||
1888 | |||
1889 | static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw, | ||
1890 | struct ieee80211_vif *vif, | ||
1891 | struct ieee80211_sta *sta, | ||
1892 | struct ieee80211_key_conf *key, | ||
1893 | void *_data) | ||
1894 | { | ||
1895 | struct iwl_priv *priv = hw->priv; | ||
1896 | struct wowlan_key_data *data = _data; | ||
1897 | struct iwl_rxon_context *ctx = data->ctx; | ||
1898 | struct aes_sc *aes_sc, *aes_tx_sc = NULL; | ||
1899 | struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL; | ||
1900 | struct iwlagn_p1k_cache *rx_p1ks; | ||
1901 | u8 *rx_mic_key; | ||
1902 | struct ieee80211_key_seq seq; | ||
1903 | u32 cur_rx_iv32 = 0; | ||
1904 | u16 p1k[IWLAGN_P1K_SIZE]; | ||
1905 | int ret, i; | ||
1906 | |||
1907 | mutex_lock(&priv->shrd->mutex); | ||
1908 | |||
1909 | if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || | ||
1910 | key->cipher == WLAN_CIPHER_SUITE_WEP104) && | ||
1911 | !sta && !ctx->key_mapping_keys) | ||
1912 | ret = iwl_set_default_wep_key(priv, ctx, key); | ||
1913 | else | ||
1914 | ret = iwl_set_dynamic_key(priv, ctx, key, sta); | ||
1915 | |||
1916 | if (ret) { | ||
1917 | IWL_ERR(priv, "Error setting key during suspend!\n"); | ||
1918 | data->error = true; | ||
1919 | } | ||
1920 | |||
1921 | switch (key->cipher) { | ||
1922 | case WLAN_CIPHER_SUITE_TKIP: | ||
1923 | if (sta) { | ||
1924 | tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc; | ||
1925 | tkip_tx_sc = &data->rsc_tsc->all_tsc_rsc.tkip.tsc; | ||
1926 | |||
1927 | rx_p1ks = data->tkip->rx_uni; | ||
1928 | |||
1929 | ieee80211_get_key_tx_seq(key, &seq); | ||
1930 | tkip_tx_sc->iv16 = cpu_to_le16(seq.tkip.iv16); | ||
1931 | tkip_tx_sc->iv32 = cpu_to_le32(seq.tkip.iv32); | ||
1932 | |||
1933 | ieee80211_get_tkip_p1k_iv(key, seq.tkip.iv32, p1k); | ||
1934 | iwlagn_convert_p1k(p1k, data->tkip->tx.p1k); | ||
1935 | |||
1936 | memcpy(data->tkip->mic_keys.tx, | ||
1937 | &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], | ||
1938 | IWLAGN_MIC_KEY_SIZE); | ||
1939 | |||
1940 | rx_mic_key = data->tkip->mic_keys.rx_unicast; | ||
1941 | } else { | ||
1942 | tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.multicast_rsc; | ||
1943 | rx_p1ks = data->tkip->rx_multi; | ||
1944 | rx_mic_key = data->tkip->mic_keys.rx_mcast; | ||
1945 | } | ||
1946 | |||
1947 | /* | ||
1948 | * For non-QoS this relies on the fact that both the uCode and | ||
1949 | * mac80211 use TID 0 (as they need to to avoid replay attacks) | ||
1950 | * for checking the IV in the frames. | ||
1951 | */ | ||
1952 | for (i = 0; i < IWLAGN_NUM_RSC; i++) { | ||
1953 | ieee80211_get_key_rx_seq(key, i, &seq); | ||
1954 | tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16); | ||
1955 | tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32); | ||
1956 | /* wrapping isn't allowed, AP must rekey */ | ||
1957 | if (seq.tkip.iv32 > cur_rx_iv32) | ||
1958 | cur_rx_iv32 = seq.tkip.iv32; | ||
1959 | } | ||
1960 | |||
1961 | ieee80211_get_tkip_rx_p1k(key, data->bssid, cur_rx_iv32, p1k); | ||
1962 | iwlagn_convert_p1k(p1k, rx_p1ks[0].p1k); | ||
1963 | ieee80211_get_tkip_rx_p1k(key, data->bssid, | ||
1964 | cur_rx_iv32 + 1, p1k); | ||
1965 | iwlagn_convert_p1k(p1k, rx_p1ks[1].p1k); | ||
1966 | |||
1967 | memcpy(rx_mic_key, | ||
1968 | &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], | ||
1969 | IWLAGN_MIC_KEY_SIZE); | ||
1970 | |||
1971 | data->use_tkip = true; | ||
1972 | data->use_rsc_tsc = true; | ||
1973 | break; | ||
1974 | case WLAN_CIPHER_SUITE_CCMP: | ||
1975 | if (sta) { | ||
1976 | u8 *pn = seq.ccmp.pn; | ||
1977 | |||
1978 | aes_sc = data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc; | ||
1979 | aes_tx_sc = &data->rsc_tsc->all_tsc_rsc.aes.tsc; | ||
1980 | |||
1981 | ieee80211_get_key_tx_seq(key, &seq); | ||
1982 | aes_tx_sc->pn = cpu_to_le64( | ||
1983 | (u64)pn[5] | | ||
1984 | ((u64)pn[4] << 8) | | ||
1985 | ((u64)pn[3] << 16) | | ||
1986 | ((u64)pn[2] << 24) | | ||
1987 | ((u64)pn[1] << 32) | | ||
1988 | ((u64)pn[0] << 40)); | ||
1989 | } else | ||
1990 | aes_sc = data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc; | ||
1991 | |||
1992 | /* | ||
1993 | * For non-QoS this relies on the fact that both the uCode and | ||
1994 | * mac80211 use TID 0 for checking the IV in the frames. | ||
1995 | */ | ||
1996 | for (i = 0; i < IWLAGN_NUM_RSC; i++) { | ||
1997 | u8 *pn = seq.ccmp.pn; | ||
1998 | |||
1999 | ieee80211_get_key_rx_seq(key, i, &seq); | ||
2000 | aes_sc->pn = cpu_to_le64( | ||
2001 | (u64)pn[5] | | ||
2002 | ((u64)pn[4] << 8) | | ||
2003 | ((u64)pn[3] << 16) | | ||
2004 | ((u64)pn[2] << 24) | | ||
2005 | ((u64)pn[1] << 32) | | ||
2006 | ((u64)pn[0] << 40)); | ||
2007 | } | ||
2008 | data->use_rsc_tsc = true; | ||
2009 | break; | ||
2010 | } | ||
2011 | |||
2012 | mutex_unlock(&priv->shrd->mutex); | ||
2013 | } | ||
2014 | |||
2015 | static int iwlagn_mac_suspend(struct ieee80211_hw *hw, | ||
2016 | struct cfg80211_wowlan *wowlan) | ||
2017 | { | ||
2018 | struct iwl_priv *priv = hw->priv; | ||
2019 | struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd; | ||
2020 | struct iwl_rxon_cmd rxon; | ||
2021 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
2022 | struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd; | ||
2023 | struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {}; | ||
2024 | struct wowlan_key_data key_data = { | ||
2025 | .ctx = ctx, | ||
2026 | .bssid = ctx->active.bssid_addr, | ||
2027 | .use_rsc_tsc = false, | ||
2028 | .tkip = &tkip_cmd, | ||
2029 | .use_tkip = false, | ||
2030 | }; | ||
2031 | int ret, i; | ||
2032 | u16 seq; | ||
2033 | |||
2034 | if (WARN_ON(!wowlan)) | ||
2035 | return -EINVAL; | ||
2036 | |||
2037 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2038 | mutex_lock(&priv->shrd->mutex); | ||
2039 | |||
2040 | /* Don't attempt WoWLAN when not associated, tear down instead. */ | ||
2041 | if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION || | ||
2042 | !iwl_is_associated_ctx(ctx)) { | ||
2043 | ret = 1; | ||
2044 | goto out; | ||
2045 | } | ||
2046 | |||
2047 | key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL); | ||
2048 | if (!key_data.rsc_tsc) { | ||
2049 | ret = -ENOMEM; | ||
2050 | goto out; | ||
2051 | } | ||
2052 | |||
2053 | memset(&wakeup_filter_cmd, 0, sizeof(wakeup_filter_cmd)); | ||
2054 | |||
2055 | /* | ||
2056 | * We know the last used seqno, and the uCode expects to know that | ||
2057 | * one, it will increment before TX. | ||
2058 | */ | ||
2059 | seq = le16_to_cpu(priv->last_seq_ctl) & IEEE80211_SCTL_SEQ; | ||
2060 | wakeup_filter_cmd.non_qos_seq = cpu_to_le16(seq); | ||
2061 | |||
2062 | /* | ||
2063 | * For QoS counters, we store the one to use next, so subtract 0x10 | ||
2064 | * since the uCode will add 0x10 before using the value. | ||
2065 | */ | ||
2066 | for (i = 0; i < 8; i++) { | ||
2067 | seq = priv->shrd->tid_data[IWL_AP_ID][i].seq_number; | ||
2068 | seq -= 0x10; | ||
2069 | wakeup_filter_cmd.qos_seq[i] = cpu_to_le16(seq); | ||
2070 | } | ||
2071 | |||
2072 | if (wowlan->disconnect) | ||
2073 | wakeup_filter_cmd.enabled |= | ||
2074 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_BEACON_MISS | | ||
2075 | IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE); | ||
2076 | if (wowlan->magic_pkt) | ||
2077 | wakeup_filter_cmd.enabled |= | ||
2078 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_MAGIC_PACKET); | ||
2079 | if (wowlan->gtk_rekey_failure) | ||
2080 | wakeup_filter_cmd.enabled |= | ||
2081 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL); | ||
2082 | if (wowlan->eap_identity_req) | ||
2083 | wakeup_filter_cmd.enabled |= | ||
2084 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ); | ||
2085 | if (wowlan->four_way_handshake) | ||
2086 | wakeup_filter_cmd.enabled |= | ||
2087 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE); | ||
2088 | if (wowlan->rfkill_release) | ||
2089 | wakeup_filter_cmd.enabled |= | ||
2090 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_RFKILL); | ||
2091 | if (wowlan->n_patterns) | ||
2092 | wakeup_filter_cmd.enabled |= | ||
2093 | cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH); | ||
2094 | |||
2095 | iwl_scan_cancel_timeout(priv, 200); | ||
2096 | |||
2097 | memcpy(&rxon, &ctx->active, sizeof(rxon)); | ||
2098 | |||
2099 | iwl_trans_stop_device(trans(priv)); | ||
2100 | |||
2101 | priv->shrd->wowlan = true; | ||
2102 | |||
2103 | ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_wowlan, | ||
2104 | IWL_UCODE_WOWLAN); | ||
2105 | if (ret) | ||
2106 | goto error; | ||
2107 | |||
2108 | /* now configure WoWLAN ucode */ | ||
2109 | ret = iwl_alive_start(priv); | ||
2110 | if (ret) | ||
2111 | goto error; | ||
2112 | |||
2113 | memcpy(&ctx->staging, &rxon, sizeof(rxon)); | ||
2114 | ret = iwlagn_commit_rxon(priv, ctx); | ||
2115 | if (ret) | ||
2116 | goto error; | ||
2117 | |||
2118 | ret = iwl_power_update_mode(priv, true); | ||
2119 | if (ret) | ||
2120 | goto error; | ||
2121 | |||
2122 | if (!iwlagn_mod_params.sw_crypto) { | ||
2123 | /* mark all keys clear */ | ||
2124 | priv->ucode_key_table = 0; | ||
2125 | ctx->key_mapping_keys = 0; | ||
2126 | |||
2127 | /* | ||
2128 | * This needs to be unlocked due to lock ordering | ||
2129 | * constraints. Since we're in the suspend path | ||
2130 | * that isn't really a problem though. | ||
2131 | */ | ||
2132 | mutex_unlock(&priv->shrd->mutex); | ||
2133 | ieee80211_iter_keys(priv->hw, ctx->vif, | ||
2134 | iwlagn_wowlan_program_keys, | ||
2135 | &key_data); | ||
2136 | mutex_lock(&priv->shrd->mutex); | ||
2137 | if (key_data.error) { | ||
2138 | ret = -EIO; | ||
2139 | goto error; | ||
2140 | } | ||
2141 | |||
2142 | if (key_data.use_rsc_tsc) { | ||
2143 | struct iwl_host_cmd rsc_tsc_cmd = { | ||
2144 | .id = REPLY_WOWLAN_TSC_RSC_PARAMS, | ||
2145 | .flags = CMD_SYNC, | ||
2146 | .data[0] = key_data.rsc_tsc, | ||
2147 | .dataflags[0] = IWL_HCMD_DFL_NOCOPY, | ||
2148 | .len[0] = sizeof(*key_data.rsc_tsc), | ||
2149 | }; | ||
2150 | |||
2151 | ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd); | ||
2152 | if (ret) | ||
2153 | goto error; | ||
2154 | } | ||
2155 | |||
2156 | if (key_data.use_tkip) { | ||
2157 | ret = iwl_trans_send_cmd_pdu(trans(priv), | ||
2158 | REPLY_WOWLAN_TKIP_PARAMS, | ||
2159 | CMD_SYNC, sizeof(tkip_cmd), | ||
2160 | &tkip_cmd); | ||
2161 | if (ret) | ||
2162 | goto error; | ||
2163 | } | ||
2164 | |||
2165 | if (priv->have_rekey_data) { | ||
2166 | memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd)); | ||
2167 | memcpy(kek_kck_cmd.kck, priv->kck, NL80211_KCK_LEN); | ||
2168 | kek_kck_cmd.kck_len = cpu_to_le16(NL80211_KCK_LEN); | ||
2169 | memcpy(kek_kck_cmd.kek, priv->kek, NL80211_KEK_LEN); | ||
2170 | kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN); | ||
2171 | kek_kck_cmd.replay_ctr = priv->replay_ctr; | ||
2172 | |||
2173 | ret = iwl_trans_send_cmd_pdu(trans(priv), | ||
2174 | REPLY_WOWLAN_KEK_KCK_MATERIAL, | ||
2175 | CMD_SYNC, sizeof(kek_kck_cmd), | ||
2176 | &kek_kck_cmd); | ||
2177 | if (ret) | ||
2178 | goto error; | ||
2179 | } | ||
2180 | } | ||
2181 | |||
2182 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER, | ||
2183 | CMD_SYNC, sizeof(wakeup_filter_cmd), | ||
2184 | &wakeup_filter_cmd); | ||
2185 | if (ret) | ||
2186 | goto error; | ||
2187 | |||
2188 | ret = iwlagn_send_patterns(priv, wowlan); | ||
2189 | if (ret) | ||
2190 | goto error; | ||
2191 | |||
2192 | device_set_wakeup_enable(bus(priv)->dev, true); | ||
2193 | |||
2194 | /* Now let the ucode operate on its own */ | ||
2195 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, | ||
2196 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
2197 | |||
2198 | goto out; | ||
2199 | |||
2200 | error: | ||
2201 | priv->shrd->wowlan = false; | ||
2202 | iwlagn_prepare_restart(priv); | ||
2203 | ieee80211_restart_hw(priv->hw); | ||
2204 | out: | ||
2205 | mutex_unlock(&priv->shrd->mutex); | ||
2206 | kfree(key_data.rsc_tsc); | ||
2207 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2208 | |||
2209 | return ret; | ||
2210 | } | ||
2211 | |||
2212 | static int iwlagn_mac_resume(struct ieee80211_hw *hw) | ||
2213 | { | ||
2214 | struct iwl_priv *priv = hw->priv; | ||
2215 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
2216 | struct ieee80211_vif *vif; | ||
2217 | unsigned long flags; | ||
2218 | u32 base, status = 0xffffffff; | ||
2219 | int ret = -EIO; | ||
2220 | |||
2221 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2222 | mutex_lock(&priv->shrd->mutex); | ||
2223 | |||
2224 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, | ||
2225 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
2226 | |||
2227 | base = priv->device_pointers.error_event_table; | ||
2228 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | ||
2229 | spin_lock_irqsave(&bus(priv)->reg_lock, flags); | ||
2230 | ret = iwl_grab_nic_access_silent(bus(priv)); | ||
2231 | if (ret == 0) { | ||
2232 | iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, base); | ||
2233 | status = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | ||
2234 | iwl_release_nic_access(bus(priv)); | ||
2235 | } | ||
2236 | spin_unlock_irqrestore(&bus(priv)->reg_lock, flags); | ||
2237 | |||
2238 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
2239 | if (ret == 0) { | ||
2240 | if (!priv->wowlan_sram) | ||
2241 | priv->wowlan_sram = | ||
2242 | kzalloc(priv->ucode_wowlan.data.len, | ||
2243 | GFP_KERNEL); | ||
2244 | |||
2245 | if (priv->wowlan_sram) | ||
2246 | _iwl_read_targ_mem_words( | ||
2247 | bus(priv), 0x800000, priv->wowlan_sram, | ||
2248 | priv->ucode_wowlan.data.len / 4); | ||
2249 | } | ||
2250 | #endif | ||
2251 | } | ||
2252 | |||
2253 | /* we'll clear ctx->vif during iwlagn_prepare_restart() */ | ||
2254 | vif = ctx->vif; | ||
2255 | |||
2256 | priv->shrd->wowlan = false; | ||
2257 | |||
2258 | device_set_wakeup_enable(bus(priv)->dev, false); | ||
2259 | |||
2260 | iwlagn_prepare_restart(priv); | ||
2261 | |||
2262 | memset((void *)&ctx->active, 0, sizeof(ctx->active)); | ||
2263 | iwl_connection_init_rx_config(priv, ctx); | ||
2264 | iwlagn_set_rxon_chain(priv, ctx); | ||
2265 | |||
2266 | mutex_unlock(&priv->shrd->mutex); | ||
2267 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2268 | |||
2269 | ieee80211_resume_disconnect(vif); | ||
2270 | |||
2271 | return 1; | ||
2272 | } | ||
2273 | #endif | ||
2274 | |||
2275 | static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
2276 | { | ||
2277 | struct iwl_priv *priv = hw->priv; | ||
2278 | |||
2279 | IWL_DEBUG_MACDUMP(priv, "enter\n"); | ||
2280 | |||
2281 | IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | ||
2282 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); | ||
2283 | |||
2284 | if (iwlagn_tx_skb(priv, skb)) | ||
2285 | dev_kfree_skb_any(skb); | ||
2286 | |||
2287 | IWL_DEBUG_MACDUMP(priv, "leave\n"); | ||
2288 | } | ||
2289 | |||
2290 | static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | ||
2291 | struct ieee80211_vif *vif, | ||
2292 | struct ieee80211_key_conf *keyconf, | ||
2293 | struct ieee80211_sta *sta, | ||
2294 | u32 iv32, u16 *phase1key) | ||
2295 | { | ||
2296 | struct iwl_priv *priv = hw->priv; | ||
2297 | |||
2298 | iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); | ||
2299 | } | ||
2300 | |||
2301 | static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | ||
2302 | struct ieee80211_vif *vif, | ||
2303 | struct ieee80211_sta *sta, | ||
2304 | struct ieee80211_key_conf *key) | ||
2305 | { | ||
2306 | struct iwl_priv *priv = hw->priv; | ||
2307 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
2308 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
2309 | int ret; | ||
2310 | bool is_default_wep_key = false; | ||
2311 | |||
2312 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2313 | |||
2314 | if (iwlagn_mod_params.sw_crypto) { | ||
2315 | IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); | ||
2316 | return -EOPNOTSUPP; | ||
2317 | } | ||
2318 | |||
2319 | /* | ||
2320 | * We could program these keys into the hardware as well, but we | ||
2321 | * don't expect much multicast traffic in IBSS and having keys | ||
2322 | * for more stations is probably more useful. | ||
2323 | * | ||
2324 | * Mark key TX-only and return 0. | ||
2325 | */ | ||
2326 | if (vif->type == NL80211_IFTYPE_ADHOC && | ||
2327 | !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | ||
2328 | key->hw_key_idx = WEP_INVALID_OFFSET; | ||
2329 | return 0; | ||
2330 | } | ||
2331 | |||
2332 | /* If they key was TX-only, accept deletion */ | ||
2333 | if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET) | ||
2334 | return 0; | ||
2335 | |||
2336 | mutex_lock(&priv->shrd->mutex); | ||
2337 | iwl_scan_cancel_timeout(priv, 100); | ||
2338 | |||
2339 | BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT); | ||
2340 | |||
2341 | /* | ||
2342 | * If we are getting WEP group key and we didn't receive any key mapping | ||
2343 | * so far, we are in legacy wep mode (group key only), otherwise we are | ||
2344 | * in 1X mode. | ||
2345 | * In legacy wep mode, we use another host command to the uCode. | ||
2346 | */ | ||
2347 | if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || | ||
2348 | key->cipher == WLAN_CIPHER_SUITE_WEP104) && !sta) { | ||
2349 | if (cmd == SET_KEY) | ||
2350 | is_default_wep_key = !ctx->key_mapping_keys; | ||
2351 | else | ||
2352 | is_default_wep_key = | ||
2353 | key->hw_key_idx == IWLAGN_HW_KEY_DEFAULT; | ||
2354 | } | ||
2355 | |||
2356 | |||
2357 | switch (cmd) { | ||
2358 | case SET_KEY: | ||
2359 | if (is_default_wep_key) { | ||
2360 | ret = iwl_set_default_wep_key(priv, vif_priv->ctx, key); | ||
2361 | break; | ||
2362 | } | ||
2363 | ret = iwl_set_dynamic_key(priv, vif_priv->ctx, key, sta); | ||
2364 | if (ret) { | ||
2365 | /* | ||
2366 | * can't add key for RX, but we don't need it | ||
2367 | * in the device for TX so still return 0 | ||
2368 | */ | ||
2369 | ret = 0; | ||
2370 | key->hw_key_idx = WEP_INVALID_OFFSET; | ||
2371 | } | ||
2372 | |||
2373 | IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n"); | ||
2374 | break; | ||
2375 | case DISABLE_KEY: | ||
2376 | if (is_default_wep_key) | ||
2377 | ret = iwl_remove_default_wep_key(priv, ctx, key); | ||
2378 | else | ||
2379 | ret = iwl_remove_dynamic_key(priv, ctx, key, sta); | ||
2380 | |||
2381 | IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n"); | ||
2382 | break; | ||
2383 | default: | ||
2384 | ret = -EINVAL; | ||
2385 | } | ||
2386 | |||
2387 | mutex_unlock(&priv->shrd->mutex); | ||
2388 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2389 | |||
2390 | return ret; | ||
2391 | } | ||
2392 | |||
2393 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | ||
2394 | struct ieee80211_vif *vif, | ||
2395 | enum ieee80211_ampdu_mlme_action action, | ||
2396 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, | ||
2397 | u8 buf_size) | ||
2398 | { | ||
2399 | struct iwl_priv *priv = hw->priv; | ||
2400 | int ret = -EINVAL; | ||
2401 | struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; | ||
2402 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
2403 | |||
2404 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", | ||
2405 | sta->addr, tid); | ||
2406 | |||
2407 | if (!(priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)) | ||
2408 | return -EACCES; | ||
2409 | |||
2410 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2411 | mutex_lock(&priv->shrd->mutex); | ||
2412 | |||
2413 | switch (action) { | ||
2414 | case IEEE80211_AMPDU_RX_START: | ||
2415 | IWL_DEBUG_HT(priv, "start Rx\n"); | ||
2416 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); | ||
2417 | break; | ||
2418 | case IEEE80211_AMPDU_RX_STOP: | ||
2419 | IWL_DEBUG_HT(priv, "stop Rx\n"); | ||
2420 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); | ||
2421 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
2422 | ret = 0; | ||
2423 | break; | ||
2424 | case IEEE80211_AMPDU_TX_START: | ||
2425 | IWL_DEBUG_HT(priv, "start Tx\n"); | ||
2426 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); | ||
2427 | break; | ||
2428 | case IEEE80211_AMPDU_TX_STOP: | ||
2429 | IWL_DEBUG_HT(priv, "stop Tx\n"); | ||
2430 | ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); | ||
2431 | if ((ret == 0) && (priv->agg_tids_count > 0)) { | ||
2432 | priv->agg_tids_count--; | ||
2433 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | ||
2434 | priv->agg_tids_count); | ||
2435 | } | ||
2436 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
2437 | ret = 0; | ||
2438 | if (!priv->agg_tids_count && priv->cfg->ht_params && | ||
2439 | priv->cfg->ht_params->use_rts_for_aggregation) { | ||
2440 | /* | ||
2441 | * switch off RTS/CTS if it was previously enabled | ||
2442 | */ | ||
2443 | sta_priv->lq_sta.lq.general_params.flags &= | ||
2444 | ~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; | ||
2445 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | ||
2446 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
2447 | } | ||
2448 | break; | ||
2449 | case IEEE80211_AMPDU_TX_OPERATIONAL: | ||
2450 | buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); | ||
2451 | |||
2452 | iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, iwl_sta_id(sta), | ||
2453 | tid, buf_size); | ||
2454 | |||
2455 | /* | ||
2456 | * If the limit is 0, then it wasn't initialised yet, | ||
2457 | * use the default. We can do that since we take the | ||
2458 | * minimum below, and we don't want to go above our | ||
2459 | * default due to hardware restrictions. | ||
2460 | */ | ||
2461 | if (sta_priv->max_agg_bufsize == 0) | ||
2462 | sta_priv->max_agg_bufsize = | ||
2463 | LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
2464 | |||
2465 | /* | ||
2466 | * Even though in theory the peer could have different | ||
2467 | * aggregation reorder buffer sizes for different sessions, | ||
2468 | * our ucode doesn't allow for that and has a global limit | ||
2469 | * for each station. Therefore, use the minimum of all the | ||
2470 | * aggregation sessions and our default value. | ||
2471 | */ | ||
2472 | sta_priv->max_agg_bufsize = | ||
2473 | min(sta_priv->max_agg_bufsize, buf_size); | ||
2474 | |||
2475 | if (priv->cfg->ht_params && | ||
2476 | priv->cfg->ht_params->use_rts_for_aggregation) { | ||
2477 | /* | ||
2478 | * switch to RTS/CTS if it is the prefer protection | ||
2479 | * method for HT traffic | ||
2480 | */ | ||
2481 | |||
2482 | sta_priv->lq_sta.lq.general_params.flags |= | ||
2483 | LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; | ||
2484 | } | ||
2485 | priv->agg_tids_count++; | ||
2486 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | ||
2487 | priv->agg_tids_count); | ||
2488 | |||
2489 | sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit = | ||
2490 | sta_priv->max_agg_bufsize; | ||
2491 | |||
2492 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | ||
2493 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
2494 | |||
2495 | IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n", | ||
2496 | sta->addr, tid); | ||
2497 | ret = 0; | ||
2498 | break; | ||
2499 | } | ||
2500 | mutex_unlock(&priv->shrd->mutex); | ||
2501 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2502 | return ret; | ||
2503 | } | ||
2504 | |||
2505 | static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | ||
2506 | struct ieee80211_vif *vif, | ||
2507 | struct ieee80211_sta *sta) | ||
2508 | { | ||
2509 | struct iwl_priv *priv = hw->priv; | ||
2510 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
2511 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
2512 | bool is_ap = vif->type == NL80211_IFTYPE_STATION; | ||
2513 | int ret = 0; | ||
2514 | u8 sta_id; | ||
2515 | |||
2516 | IWL_DEBUG_MAC80211(priv, "received request to add station %pM\n", | ||
2517 | sta->addr); | ||
2518 | mutex_lock(&priv->shrd->mutex); | ||
2519 | IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", | ||
2520 | sta->addr); | ||
2521 | sta_priv->sta_id = IWL_INVALID_STATION; | ||
2522 | |||
2523 | atomic_set(&sta_priv->pending_frames, 0); | ||
2524 | if (vif->type == NL80211_IFTYPE_AP) | ||
2525 | sta_priv->client = true; | ||
2526 | |||
2527 | ret = iwl_add_station_common(priv, vif_priv->ctx, sta->addr, | ||
2528 | is_ap, sta, &sta_id); | ||
2529 | if (ret) { | ||
2530 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", | ||
2531 | sta->addr, ret); | ||
2532 | /* Should we return success if return code is EEXIST ? */ | ||
2533 | goto out; | ||
2534 | } | ||
2535 | |||
2536 | sta_priv->sta_id = sta_id; | ||
2537 | |||
2538 | /* Initialize rate scaling */ | ||
2539 | IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", | ||
2540 | sta->addr); | ||
2541 | iwl_rs_rate_init(priv, sta, sta_id); | ||
2542 | out: | ||
2543 | mutex_unlock(&priv->shrd->mutex); | ||
2544 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2545 | |||
2546 | return ret; | ||
2547 | } | ||
2548 | |||
2549 | static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | ||
2550 | struct ieee80211_channel_switch *ch_switch) | ||
2551 | { | ||
2552 | struct iwl_priv *priv = hw->priv; | ||
2553 | const struct iwl_channel_info *ch_info; | ||
2554 | struct ieee80211_conf *conf = &hw->conf; | ||
2555 | struct ieee80211_channel *channel = ch_switch->channel; | ||
2556 | struct iwl_ht_config *ht_conf = &priv->current_ht_config; | ||
2557 | /* | ||
2558 | * MULTI-FIXME | ||
2559 | * When we add support for multiple interfaces, we need to | ||
2560 | * revisit this. The channel switch command in the device | ||
2561 | * only affects the BSS context, but what does that really | ||
2562 | * mean? And what if we get a CSA on the second interface? | ||
2563 | * This needs a lot of work. | ||
2564 | */ | ||
2565 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
2566 | u16 ch; | ||
2567 | |||
2568 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2569 | |||
2570 | mutex_lock(&priv->shrd->mutex); | ||
2571 | |||
2572 | if (iwl_is_rfkill(priv->shrd)) | ||
2573 | goto out; | ||
2574 | |||
2575 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || | ||
2576 | test_bit(STATUS_SCANNING, &priv->shrd->status) || | ||
2577 | test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) | ||
2578 | goto out; | ||
2579 | |||
2580 | if (!iwl_is_associated_ctx(ctx)) | ||
2581 | goto out; | ||
2582 | |||
2583 | if (!priv->cfg->lib->set_channel_switch) | ||
2584 | goto out; | ||
2585 | |||
2586 | ch = channel->hw_value; | ||
2587 | if (le16_to_cpu(ctx->active.channel) == ch) | ||
2588 | goto out; | ||
2589 | |||
2590 | ch_info = iwl_get_channel_info(priv, channel->band, ch); | ||
2591 | if (!is_channel_valid(ch_info)) { | ||
2592 | IWL_DEBUG_MAC80211(priv, "invalid channel\n"); | ||
2593 | goto out; | ||
2594 | } | ||
2595 | |||
2596 | spin_lock_irq(&priv->shrd->lock); | ||
2597 | |||
2598 | priv->current_ht_config.smps = conf->smps_mode; | ||
2599 | |||
2600 | /* Configure HT40 channels */ | ||
2601 | ctx->ht.enabled = conf_is_ht(conf); | ||
2602 | if (ctx->ht.enabled) { | ||
2603 | if (conf_is_ht40_minus(conf)) { | ||
2604 | ctx->ht.extension_chan_offset = | ||
2605 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
2606 | ctx->ht.is_40mhz = true; | ||
2607 | } else if (conf_is_ht40_plus(conf)) { | ||
2608 | ctx->ht.extension_chan_offset = | ||
2609 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
2610 | ctx->ht.is_40mhz = true; | ||
2611 | } else { | ||
2612 | ctx->ht.extension_chan_offset = | ||
2613 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
2614 | ctx->ht.is_40mhz = false; | ||
2615 | } | ||
2616 | } else | ||
2617 | ctx->ht.is_40mhz = false; | ||
2618 | |||
2619 | if ((le16_to_cpu(ctx->staging.channel) != ch)) | ||
2620 | ctx->staging.flags = 0; | ||
2621 | |||
2622 | iwl_set_rxon_channel(priv, channel, ctx); | ||
2623 | iwl_set_rxon_ht(priv, ht_conf); | ||
2624 | iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); | ||
2625 | |||
2626 | spin_unlock_irq(&priv->shrd->lock); | ||
2627 | |||
2628 | iwl_set_rate(priv); | ||
2629 | /* | ||
2630 | * at this point, staging_rxon has the | ||
2631 | * configuration for channel switch | ||
2632 | */ | ||
2633 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | ||
2634 | priv->switch_channel = cpu_to_le16(ch); | ||
2635 | if (priv->cfg->lib->set_channel_switch(priv, ch_switch)) { | ||
2636 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | ||
2637 | priv->switch_channel = 0; | ||
2638 | ieee80211_chswitch_done(ctx->vif, false); | ||
2639 | } | ||
2640 | |||
2641 | out: | ||
2642 | mutex_unlock(&priv->shrd->mutex); | ||
2643 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2644 | } | ||
2645 | |||
2646 | static void iwlagn_configure_filter(struct ieee80211_hw *hw, | ||
2647 | unsigned int changed_flags, | ||
2648 | unsigned int *total_flags, | ||
2649 | u64 multicast) | ||
2650 | { | ||
2651 | struct iwl_priv *priv = hw->priv; | ||
2652 | __le32 filter_or = 0, filter_nand = 0; | ||
2653 | struct iwl_rxon_context *ctx; | ||
2654 | |||
2655 | #define CHK(test, flag) do { \ | ||
2656 | if (*total_flags & (test)) \ | ||
2657 | filter_or |= (flag); \ | ||
2658 | else \ | ||
2659 | filter_nand |= (flag); \ | ||
2660 | } while (0) | ||
2661 | |||
2662 | IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", | ||
2663 | changed_flags, *total_flags); | ||
2664 | 1457 | ||
2665 | CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); | ||
2666 | /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */ | ||
2667 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK); | ||
2668 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); | ||
2669 | 1458 | ||
2670 | #undef CHK | ||
2671 | |||
2672 | mutex_lock(&priv->shrd->mutex); | ||
2673 | |||
2674 | for_each_context(priv, ctx) { | ||
2675 | ctx->staging.filter_flags &= ~filter_nand; | ||
2676 | ctx->staging.filter_flags |= filter_or; | ||
2677 | |||
2678 | /* | ||
2679 | * Not committing directly because hardware can perform a scan, | ||
2680 | * but we'll eventually commit the filter flags change anyway. | ||
2681 | */ | ||
2682 | } | ||
2683 | |||
2684 | mutex_unlock(&priv->shrd->mutex); | ||
2685 | |||
2686 | /* | ||
2687 | * Receiving all multicast frames is always enabled by the | ||
2688 | * default flags setup in iwl_connection_init_rx_config() | ||
2689 | * since we currently do not support programming multicast | ||
2690 | * filters into the device. | ||
2691 | */ | ||
2692 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | ||
2693 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
2694 | } | ||
2695 | |||
2696 | static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | ||
2697 | { | ||
2698 | struct iwl_priv *priv = hw->priv; | ||
2699 | |||
2700 | mutex_lock(&priv->shrd->mutex); | ||
2701 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2702 | |||
2703 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | ||
2704 | IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); | ||
2705 | goto done; | ||
2706 | } | ||
2707 | if (iwl_is_rfkill(priv->shrd)) { | ||
2708 | IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n"); | ||
2709 | goto done; | ||
2710 | } | ||
2711 | |||
2712 | /* | ||
2713 | * mac80211 will not push any more frames for transmit | ||
2714 | * until the flush is completed | ||
2715 | */ | ||
2716 | if (drop) { | ||
2717 | IWL_DEBUG_MAC80211(priv, "send flush command\n"); | ||
2718 | if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { | ||
2719 | IWL_ERR(priv, "flush request fail\n"); | ||
2720 | goto done; | ||
2721 | } | ||
2722 | } | ||
2723 | IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); | ||
2724 | iwl_trans_wait_tx_queue_empty(trans(priv)); | ||
2725 | done: | ||
2726 | mutex_unlock(&priv->shrd->mutex); | ||
2727 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2728 | } | ||
2729 | 1459 | ||
2730 | void iwlagn_disable_roc(struct iwl_priv *priv) | 1460 | void iwlagn_disable_roc(struct iwl_priv *priv) |
2731 | { | 1461 | { |
@@ -2759,160 +1489,6 @@ static void iwlagn_disable_roc_work(struct work_struct *work) | |||
2759 | mutex_unlock(&priv->shrd->mutex); | 1489 | mutex_unlock(&priv->shrd->mutex); |
2760 | } | 1490 | } |
2761 | 1491 | ||
2762 | static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | ||
2763 | struct ieee80211_channel *channel, | ||
2764 | enum nl80211_channel_type channel_type, | ||
2765 | int duration) | ||
2766 | { | ||
2767 | struct iwl_priv *priv = hw->priv; | ||
2768 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; | ||
2769 | int err = 0; | ||
2770 | |||
2771 | if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | ||
2772 | return -EOPNOTSUPP; | ||
2773 | |||
2774 | if (!(ctx->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT))) | ||
2775 | return -EOPNOTSUPP; | ||
2776 | |||
2777 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2778 | mutex_lock(&priv->shrd->mutex); | ||
2779 | |||
2780 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | ||
2781 | err = -EBUSY; | ||
2782 | goto out; | ||
2783 | } | ||
2784 | |||
2785 | priv->hw_roc_channel = channel; | ||
2786 | priv->hw_roc_chantype = channel_type; | ||
2787 | priv->hw_roc_duration = duration; | ||
2788 | priv->hw_roc_start_notified = false; | ||
2789 | cancel_delayed_work(&priv->hw_roc_disable_work); | ||
2790 | |||
2791 | if (!ctx->is_active) { | ||
2792 | ctx->is_active = true; | ||
2793 | ctx->staging.dev_type = RXON_DEV_TYPE_P2P; | ||
2794 | memcpy(ctx->staging.node_addr, | ||
2795 | priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr, | ||
2796 | ETH_ALEN); | ||
2797 | memcpy(ctx->staging.bssid_addr, | ||
2798 | priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr, | ||
2799 | ETH_ALEN); | ||
2800 | err = iwlagn_commit_rxon(priv, ctx); | ||
2801 | if (err) | ||
2802 | goto out; | ||
2803 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK | | ||
2804 | RXON_FILTER_PROMISC_MSK | | ||
2805 | RXON_FILTER_CTL2HOST_MSK; | ||
2806 | |||
2807 | err = iwlagn_commit_rxon(priv, ctx); | ||
2808 | if (err) { | ||
2809 | iwlagn_disable_roc(priv); | ||
2810 | goto out; | ||
2811 | } | ||
2812 | priv->hw_roc_setup = true; | ||
2813 | } | ||
2814 | |||
2815 | err = iwl_scan_initiate(priv, ctx->vif, IWL_SCAN_ROC, channel->band); | ||
2816 | if (err) | ||
2817 | iwlagn_disable_roc(priv); | ||
2818 | |||
2819 | out: | ||
2820 | mutex_unlock(&priv->shrd->mutex); | ||
2821 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2822 | |||
2823 | return err; | ||
2824 | } | ||
2825 | |||
2826 | static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | ||
2827 | { | ||
2828 | struct iwl_priv *priv = hw->priv; | ||
2829 | |||
2830 | if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | ||
2831 | return -EOPNOTSUPP; | ||
2832 | |||
2833 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2834 | mutex_lock(&priv->shrd->mutex); | ||
2835 | iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); | ||
2836 | iwlagn_disable_roc(priv); | ||
2837 | mutex_unlock(&priv->shrd->mutex); | ||
2838 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2839 | |||
2840 | return 0; | ||
2841 | } | ||
2842 | |||
2843 | static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw, | ||
2844 | struct ieee80211_vif *vif, | ||
2845 | const u8 *bssid, | ||
2846 | enum ieee80211_tx_sync_type type) | ||
2847 | { | ||
2848 | struct iwl_priv *priv = hw->priv; | ||
2849 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
2850 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
2851 | int ret; | ||
2852 | u8 sta_id; | ||
2853 | |||
2854 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2855 | mutex_lock(&priv->shrd->mutex); | ||
2856 | |||
2857 | if (iwl_is_associated_ctx(ctx)) { | ||
2858 | ret = 0; | ||
2859 | goto out; | ||
2860 | } | ||
2861 | |||
2862 | if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | ||
2863 | ret = -EBUSY; | ||
2864 | goto out; | ||
2865 | } | ||
2866 | |||
2867 | ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id); | ||
2868 | if (ret) | ||
2869 | goto out; | ||
2870 | |||
2871 | if (WARN_ON(sta_id != ctx->ap_sta_id)) { | ||
2872 | ret = -EIO; | ||
2873 | goto out_remove_sta; | ||
2874 | } | ||
2875 | |||
2876 | memcpy(ctx->bssid, bssid, ETH_ALEN); | ||
2877 | ctx->preauth_bssid = true; | ||
2878 | |||
2879 | ret = iwlagn_commit_rxon(priv, ctx); | ||
2880 | |||
2881 | if (ret == 0) | ||
2882 | goto out; | ||
2883 | |||
2884 | out_remove_sta: | ||
2885 | iwl_remove_station(priv, sta_id, bssid); | ||
2886 | out: | ||
2887 | mutex_unlock(&priv->shrd->mutex); | ||
2888 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2889 | |||
2890 | return ret; | ||
2891 | } | ||
2892 | |||
2893 | static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw, | ||
2894 | struct ieee80211_vif *vif, | ||
2895 | const u8 *bssid, | ||
2896 | enum ieee80211_tx_sync_type type) | ||
2897 | { | ||
2898 | struct iwl_priv *priv = hw->priv; | ||
2899 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
2900 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
2901 | |||
2902 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
2903 | mutex_lock(&priv->shrd->mutex); | ||
2904 | |||
2905 | if (iwl_is_associated_ctx(ctx)) | ||
2906 | goto out; | ||
2907 | |||
2908 | iwl_remove_station(priv, ctx->ap_sta_id, bssid); | ||
2909 | ctx->preauth_bssid = false; | ||
2910 | /* no need to commit */ | ||
2911 | out: | ||
2912 | mutex_unlock(&priv->shrd->mutex); | ||
2913 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
2914 | } | ||
2915 | |||
2916 | /***************************************************************************** | 1492 | /***************************************************************************** |
2917 | * | 1493 | * |
2918 | * driver setup and teardown | 1494 | * driver setup and teardown |
@@ -3062,81 +1638,13 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
3062 | kmem_cache_destroy(priv->tx_cmd_pool); | 1638 | kmem_cache_destroy(priv->tx_cmd_pool); |
3063 | kfree(priv->scan_cmd); | 1639 | kfree(priv->scan_cmd); |
3064 | kfree(priv->beacon_cmd); | 1640 | kfree(priv->beacon_cmd); |
1641 | kfree(rcu_dereference_raw(priv->noa_data)); | ||
3065 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1642 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
3066 | kfree(priv->wowlan_sram); | 1643 | kfree(priv->wowlan_sram); |
3067 | #endif | 1644 | #endif |
3068 | } | 1645 | } |
3069 | 1646 | ||
3070 | static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | ||
3071 | enum ieee80211_rssi_event rssi_event) | ||
3072 | { | ||
3073 | struct iwl_priv *priv = hw->priv; | ||
3074 | |||
3075 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
3076 | mutex_lock(&priv->shrd->mutex); | ||
3077 | |||
3078 | if (priv->cfg->bt_params && | ||
3079 | priv->cfg->bt_params->advanced_bt_coexist) { | ||
3080 | if (rssi_event == RSSI_EVENT_LOW) | ||
3081 | priv->bt_enable_pspoll = true; | ||
3082 | else if (rssi_event == RSSI_EVENT_HIGH) | ||
3083 | priv->bt_enable_pspoll = false; | ||
3084 | |||
3085 | iwlagn_send_advance_bt_config(priv); | ||
3086 | } else { | ||
3087 | IWL_DEBUG_MAC80211(priv, "Advanced BT coex disabled," | ||
3088 | "ignoring RSSI callback\n"); | ||
3089 | } | ||
3090 | |||
3091 | mutex_unlock(&priv->shrd->mutex); | ||
3092 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
3093 | } | ||
3094 | |||
3095 | static int iwlagn_mac_set_tim(struct ieee80211_hw *hw, | ||
3096 | struct ieee80211_sta *sta, bool set) | ||
3097 | { | ||
3098 | struct iwl_priv *priv = hw->priv; | ||
3099 | |||
3100 | queue_work(priv->shrd->workqueue, &priv->beacon_update); | ||
3101 | 1647 | ||
3102 | return 0; | ||
3103 | } | ||
3104 | |||
3105 | struct ieee80211_ops iwlagn_hw_ops = { | ||
3106 | .tx = iwlagn_mac_tx, | ||
3107 | .start = iwlagn_mac_start, | ||
3108 | .stop = iwlagn_mac_stop, | ||
3109 | #ifdef CONFIG_PM_SLEEP | ||
3110 | .suspend = iwlagn_mac_suspend, | ||
3111 | .resume = iwlagn_mac_resume, | ||
3112 | #endif | ||
3113 | .add_interface = iwlagn_mac_add_interface, | ||
3114 | .remove_interface = iwlagn_mac_remove_interface, | ||
3115 | .change_interface = iwlagn_mac_change_interface, | ||
3116 | .config = iwlagn_mac_config, | ||
3117 | .configure_filter = iwlagn_configure_filter, | ||
3118 | .set_key = iwlagn_mac_set_key, | ||
3119 | .update_tkip_key = iwlagn_mac_update_tkip_key, | ||
3120 | .set_rekey_data = iwlagn_mac_set_rekey_data, | ||
3121 | .conf_tx = iwlagn_mac_conf_tx, | ||
3122 | .bss_info_changed = iwlagn_bss_info_changed, | ||
3123 | .ampdu_action = iwlagn_mac_ampdu_action, | ||
3124 | .hw_scan = iwlagn_mac_hw_scan, | ||
3125 | .sta_notify = iwlagn_mac_sta_notify, | ||
3126 | .sta_add = iwlagn_mac_sta_add, | ||
3127 | .sta_remove = iwlagn_mac_sta_remove, | ||
3128 | .channel_switch = iwlagn_mac_channel_switch, | ||
3129 | .flush = iwlagn_mac_flush, | ||
3130 | .tx_last_beacon = iwlagn_mac_tx_last_beacon, | ||
3131 | .remain_on_channel = iwlagn_mac_remain_on_channel, | ||
3132 | .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel, | ||
3133 | .rssi_callback = iwlagn_mac_rssi_callback, | ||
3134 | CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) | ||
3135 | CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump) | ||
3136 | .tx_sync = iwlagn_mac_tx_sync, | ||
3137 | .finish_tx_sync = iwlagn_mac_finish_tx_sync, | ||
3138 | .set_tim = iwlagn_mac_set_tim, | ||
3139 | }; | ||
3140 | 1648 | ||
3141 | static u32 iwl_hw_detect(struct iwl_priv *priv) | 1649 | static u32 iwl_hw_detect(struct iwl_priv *priv) |
3142 | { | 1650 | { |
@@ -3170,27 +1678,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv) | |||
3170 | return priv->cfg->lib->set_hw_params(priv); | 1678 | return priv->cfg->lib->set_hw_params(priv); |
3171 | } | 1679 | } |
3172 | 1680 | ||
3173 | /* This function both allocates and initializes hw and priv. */ | ||
3174 | static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) | ||
3175 | { | ||
3176 | struct iwl_priv *priv; | ||
3177 | /* mac80211 allocates memory for this device instance, including | ||
3178 | * space for this driver's private structure */ | ||
3179 | struct ieee80211_hw *hw; | ||
3180 | |||
3181 | hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops); | ||
3182 | if (hw == NULL) { | ||
3183 | pr_err("%s: Can not allocate network device\n", | ||
3184 | cfg->name); | ||
3185 | goto out; | ||
3186 | } | ||
3187 | 1681 | ||
3188 | priv = hw->priv; | ||
3189 | priv->hw = hw; | ||
3190 | |||
3191 | out: | ||
3192 | return hw; | ||
3193 | } | ||
3194 | 1682 | ||
3195 | int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | 1683 | int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, |
3196 | struct iwl_cfg *cfg) | 1684 | struct iwl_cfg *cfg) |
@@ -3204,8 +1692,9 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | |||
3204 | /************************ | 1692 | /************************ |
3205 | * 1. Allocating HW data | 1693 | * 1. Allocating HW data |
3206 | ************************/ | 1694 | ************************/ |
3207 | hw = iwl_alloc_all(cfg); | 1695 | hw = iwl_alloc_all(); |
3208 | if (!hw) { | 1696 | if (!hw) { |
1697 | pr_err("%s: Cannot allocate network device\n", cfg->name); | ||
3209 | err = -ENOMEM; | 1698 | err = -ENOMEM; |
3210 | goto out; | 1699 | goto out; |
3211 | } | 1700 | } |
@@ -3397,7 +1886,7 @@ void __devexit iwl_remove(struct iwl_priv * priv) | |||
3397 | /*This will stop the queues, move the device to low power state */ | 1886 | /*This will stop the queues, move the device to low power state */ |
3398 | iwl_trans_stop_device(trans(priv)); | 1887 | iwl_trans_stop_device(trans(priv)); |
3399 | 1888 | ||
3400 | iwl_dealloc_ucode(priv); | 1889 | iwl_dealloc_ucode(trans(priv)); |
3401 | 1890 | ||
3402 | iwl_eeprom_free(priv); | 1891 | iwl_eeprom_free(priv); |
3403 | 1892 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5b936ec1a541..5d8d2f445923 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -65,6 +65,12 @@ | |||
65 | 65 | ||
66 | #include "iwl-dev.h" | 66 | #include "iwl-dev.h" |
67 | 67 | ||
68 | struct iwlagn_ucode_capabilities { | ||
69 | u32 max_probe_length; | ||
70 | u32 standard_phy_calibration_size; | ||
71 | u32 flags; | ||
72 | }; | ||
73 | |||
68 | extern struct ieee80211_ops iwlagn_hw_ops; | 74 | extern struct ieee80211_ops iwlagn_hw_ops; |
69 | 75 | ||
70 | int iwl_reset_ict(struct iwl_trans *trans); | 76 | int iwl_reset_ict(struct iwl_trans *trans); |
@@ -77,6 +83,15 @@ static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) | |||
77 | hdr->data_valid = 1; | 83 | hdr->data_valid = 1; |
78 | } | 84 | } |
79 | 85 | ||
86 | void __iwl_down(struct iwl_priv *priv); | ||
87 | void iwl_down(struct iwl_priv *priv); | ||
88 | void iwlagn_prepare_restart(struct iwl_priv *priv); | ||
89 | |||
90 | /* MAC80211 */ | ||
91 | struct ieee80211_hw *iwl_alloc_all(void); | ||
92 | int iwlagn_mac_setup_register(struct iwl_priv *priv, | ||
93 | struct iwlagn_ucode_capabilities *capa); | ||
94 | |||
80 | /* RXON */ | 95 | /* RXON */ |
81 | int iwlagn_set_pan_params(struct iwl_priv *priv); | 96 | int iwlagn_set_pan_params(struct iwl_priv *priv); |
82 | int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | 97 | int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
@@ -95,8 +110,7 @@ int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); | |||
95 | void iwlagn_send_prio_tbl(struct iwl_priv *priv); | 110 | void iwlagn_send_prio_tbl(struct iwl_priv *priv); |
96 | int iwlagn_run_init_ucode(struct iwl_priv *priv); | 111 | int iwlagn_run_init_ucode(struct iwl_priv *priv); |
97 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | 112 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, |
98 | struct fw_img *image, | 113 | enum iwl_ucode_type ucode_type); |
99 | enum iwlagn_ucode_type ucode_type); | ||
100 | 114 | ||
101 | /* lib */ | 115 | /* lib */ |
102 | int iwlagn_send_tx_power(struct iwl_priv *priv); | 116 | int iwlagn_send_tx_power(struct iwl_priv *priv); |
@@ -105,6 +119,12 @@ u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv); | |||
105 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | 119 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); |
106 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | 120 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); |
107 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); | 121 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); |
122 | #ifdef CONFIG_PM_SLEEP | ||
123 | int iwlagn_send_patterns(struct iwl_priv *priv, | ||
124 | struct cfg80211_wowlan *wowlan); | ||
125 | int iwlagn_suspend(struct iwl_priv *priv, | ||
126 | struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); | ||
127 | #endif | ||
108 | 128 | ||
109 | /* rx */ | 129 | /* rx */ |
110 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); | 130 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); |
@@ -196,9 +216,6 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
196 | struct ieee80211_sta *sta, u8 *sta_id_r); | 216 | struct ieee80211_sta *sta, u8 *sta_id_r); |
197 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | 217 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, |
198 | const u8 *addr); | 218 | const u8 *addr); |
199 | int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||
200 | struct ieee80211_sta *sta); | ||
201 | |||
202 | u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 219 | u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
203 | const u8 *addr, bool is_ap, struct ieee80211_sta *sta); | 220 | const u8 *addr, bool is_ap, struct ieee80211_sta *sta); |
204 | 221 | ||
@@ -316,10 +333,6 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); | |||
316 | int iwl_update_bcast_station(struct iwl_priv *priv, | 333 | int iwl_update_bcast_station(struct iwl_priv *priv, |
317 | struct iwl_rxon_context *ctx); | 334 | struct iwl_rxon_context *ctx); |
318 | int iwl_update_bcast_stations(struct iwl_priv *priv); | 335 | int iwl_update_bcast_stations(struct iwl_priv *priv); |
319 | void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | ||
320 | struct ieee80211_vif *vif, | ||
321 | enum sta_notify_cmd cmd, | ||
322 | struct ieee80211_sta *sta); | ||
323 | 336 | ||
324 | /* rate */ | 337 | /* rate */ |
325 | static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) | 338 | static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/iwl-cfg.h index 2a2dc4597ba1..e1d78257e4a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-cfg.h +++ b/drivers/net/wireless/iwlwifi/iwl-cfg.h | |||
@@ -101,17 +101,11 @@ extern struct iwl_cfg iwl100_bg_cfg; | |||
101 | extern struct iwl_cfg iwl130_bgn_cfg; | 101 | extern struct iwl_cfg iwl130_bgn_cfg; |
102 | extern struct iwl_cfg iwl130_bg_cfg; | 102 | extern struct iwl_cfg iwl130_bg_cfg; |
103 | extern struct iwl_cfg iwl2000_2bgn_cfg; | 103 | extern struct iwl_cfg iwl2000_2bgn_cfg; |
104 | extern struct iwl_cfg iwl2000_2bg_cfg; | ||
105 | extern struct iwl_cfg iwl2000_2bgn_d_cfg; | 104 | extern struct iwl_cfg iwl2000_2bgn_d_cfg; |
106 | extern struct iwl_cfg iwl2030_2bgn_cfg; | 105 | extern struct iwl_cfg iwl2030_2bgn_cfg; |
107 | extern struct iwl_cfg iwl2030_2bg_cfg; | ||
108 | extern struct iwl_cfg iwl6035_2agn_cfg; | 106 | extern struct iwl_cfg iwl6035_2agn_cfg; |
109 | extern struct iwl_cfg iwl6035_2abg_cfg; | ||
110 | extern struct iwl_cfg iwl6035_2bg_cfg; | ||
111 | extern struct iwl_cfg iwl105_bg_cfg; | ||
112 | extern struct iwl_cfg iwl105_bgn_cfg; | 107 | extern struct iwl_cfg iwl105_bgn_cfg; |
113 | extern struct iwl_cfg iwl105_bgn_d_cfg; | 108 | extern struct iwl_cfg iwl105_bgn_d_cfg; |
114 | extern struct iwl_cfg iwl135_bg_cfg; | ||
115 | extern struct iwl_cfg iwl135_bgn_cfg; | 109 | extern struct iwl_cfg iwl135_bgn_cfg; |
116 | 110 | ||
117 | #endif /* __iwl_pci_h__ */ | 111 | #endif /* __iwl_pci_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 69d5f85d11e2..f4eccf583775 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -198,6 +198,7 @@ enum { | |||
198 | REPLY_WOWLAN_TKIP_PARAMS = 0xe3, | 198 | REPLY_WOWLAN_TKIP_PARAMS = 0xe3, |
199 | REPLY_WOWLAN_KEK_KCK_MATERIAL = 0xe4, | 199 | REPLY_WOWLAN_KEK_KCK_MATERIAL = 0xe4, |
200 | REPLY_WOWLAN_GET_STATUS = 0xe5, | 200 | REPLY_WOWLAN_GET_STATUS = 0xe5, |
201 | REPLY_D3_CONFIG = 0xd3, | ||
201 | 202 | ||
202 | REPLY_MAX = 0xff | 203 | REPLY_MAX = 0xff |
203 | }; | 204 | }; |
@@ -3801,6 +3802,19 @@ struct iwl_bt_coex_prot_env_cmd { | |||
3801 | } __attribute__((packed)); | 3802 | } __attribute__((packed)); |
3802 | 3803 | ||
3803 | /* | 3804 | /* |
3805 | * REPLY_D3_CONFIG | ||
3806 | */ | ||
3807 | enum iwlagn_d3_wakeup_filters { | ||
3808 | IWLAGN_D3_WAKEUP_RFKILL = BIT(0), | ||
3809 | IWLAGN_D3_WAKEUP_SYSASSERT = BIT(1), | ||
3810 | }; | ||
3811 | |||
3812 | struct iwlagn_d3_config_cmd { | ||
3813 | __le32 min_sleep_time; | ||
3814 | __le32 wakeup_flags; | ||
3815 | } __packed; | ||
3816 | |||
3817 | /* | ||
3804 | * REPLY_WOWLAN_PATTERNS | 3818 | * REPLY_WOWLAN_PATTERNS |
3805 | */ | 3819 | */ |
3806 | #define IWLAGN_WOWLAN_MIN_PATTERN_LEN 16 | 3820 | #define IWLAGN_WOWLAN_MIN_PATTERN_LEN 16 |
@@ -3830,19 +3844,16 @@ enum iwlagn_wowlan_wakeup_filters { | |||
3830 | IWLAGN_WOWLAN_WAKEUP_BEACON_MISS = BIT(2), | 3844 | IWLAGN_WOWLAN_WAKEUP_BEACON_MISS = BIT(2), |
3831 | IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE = BIT(3), | 3845 | IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE = BIT(3), |
3832 | IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL = BIT(4), | 3846 | IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL = BIT(4), |
3833 | IWLAGN_WOWLAN_WAKEUP_RFKILL = BIT(5), | 3847 | IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ = BIT(5), |
3834 | IWLAGN_WOWLAN_WAKEUP_UCODE_ERROR = BIT(6), | 3848 | IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE = BIT(6), |
3835 | IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ = BIT(7), | 3849 | IWLAGN_WOWLAN_WAKEUP_ALWAYS = BIT(7), |
3836 | IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE = BIT(8), | 3850 | IWLAGN_WOWLAN_WAKEUP_ENABLE_NET_DETECT = BIT(8), |
3837 | IWLAGN_WOWLAN_WAKEUP_ALWAYS = BIT(9), | ||
3838 | IWLAGN_WOWLAN_WAKEUP_ENABLE_NET_DETECT = BIT(10), | ||
3839 | }; | 3851 | }; |
3840 | 3852 | ||
3841 | struct iwlagn_wowlan_wakeup_filter_cmd { | 3853 | struct iwlagn_wowlan_wakeup_filter_cmd { |
3842 | __le32 enabled; | 3854 | __le32 enabled; |
3843 | __le16 non_qos_seq; | 3855 | __le16 non_qos_seq; |
3844 | u8 min_sleep_seconds; | 3856 | __le16 reserved; |
3845 | u8 reserved; | ||
3846 | __le16 qos_seq[8]; | 3857 | __le16 qos_seq[8]; |
3847 | }; | 3858 | }; |
3848 | 3859 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 001fdf140abb..f9e9170e977a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1120,229 +1120,8 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) | |||
1120 | &statistics_cmd); | 1120 | &statistics_cmd); |
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | ||
1124 | struct ieee80211_vif *vif, u16 queue, | ||
1125 | const struct ieee80211_tx_queue_params *params) | ||
1126 | { | ||
1127 | struct iwl_priv *priv = hw->priv; | ||
1128 | struct iwl_rxon_context *ctx; | ||
1129 | unsigned long flags; | ||
1130 | int q; | ||
1131 | |||
1132 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1133 | |||
1134 | if (!iwl_is_ready_rf(priv->shrd)) { | ||
1135 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||
1136 | return -EIO; | ||
1137 | } | ||
1138 | |||
1139 | if (queue >= AC_NUM) { | ||
1140 | IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue); | ||
1141 | return 0; | ||
1142 | } | ||
1143 | |||
1144 | q = AC_NUM - 1 - queue; | ||
1145 | |||
1146 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
1147 | |||
1148 | /* | ||
1149 | * MULTI-FIXME | ||
1150 | * This may need to be done per interface in nl80211/cfg80211/mac80211. | ||
1151 | */ | ||
1152 | for_each_context(priv, ctx) { | ||
1153 | ctx->qos_data.def_qos_parm.ac[q].cw_min = | ||
1154 | cpu_to_le16(params->cw_min); | ||
1155 | ctx->qos_data.def_qos_parm.ac[q].cw_max = | ||
1156 | cpu_to_le16(params->cw_max); | ||
1157 | ctx->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; | ||
1158 | ctx->qos_data.def_qos_parm.ac[q].edca_txop = | ||
1159 | cpu_to_le16((params->txop * 32)); | ||
1160 | |||
1161 | ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; | ||
1162 | } | ||
1163 | |||
1164 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
1165 | |||
1166 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1167 | return 0; | ||
1168 | } | ||
1169 | |||
1170 | int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) | ||
1171 | { | ||
1172 | struct iwl_priv *priv = hw->priv; | ||
1173 | |||
1174 | return priv->ibss_manager == IWL_IBSS_MANAGER; | ||
1175 | } | ||
1176 | |||
1177 | static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | ||
1178 | { | ||
1179 | iwl_connection_init_rx_config(priv, ctx); | ||
1180 | |||
1181 | iwlagn_set_rxon_chain(priv, ctx); | ||
1182 | |||
1183 | return iwlagn_commit_rxon(priv, ctx); | ||
1184 | } | ||
1185 | |||
1186 | static int iwl_setup_interface(struct iwl_priv *priv, | ||
1187 | struct iwl_rxon_context *ctx) | ||
1188 | { | ||
1189 | struct ieee80211_vif *vif = ctx->vif; | ||
1190 | int err; | ||
1191 | |||
1192 | lockdep_assert_held(&priv->shrd->mutex); | ||
1193 | |||
1194 | /* | ||
1195 | * This variable will be correct only when there's just | ||
1196 | * a single context, but all code using it is for hardware | ||
1197 | * that supports only one context. | ||
1198 | */ | ||
1199 | priv->iw_mode = vif->type; | ||
1200 | |||
1201 | ctx->is_active = true; | ||
1202 | |||
1203 | err = iwl_set_mode(priv, ctx); | ||
1204 | if (err) { | ||
1205 | if (!ctx->always_active) | ||
1206 | ctx->is_active = false; | ||
1207 | return err; | ||
1208 | } | ||
1209 | |||
1210 | if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist && | ||
1211 | vif->type == NL80211_IFTYPE_ADHOC) { | ||
1212 | /* | ||
1213 | * pretend to have high BT traffic as long as we | ||
1214 | * are operating in IBSS mode, as this will cause | ||
1215 | * the rate scaling etc. to behave as intended. | ||
1216 | */ | ||
1217 | priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH; | ||
1218 | } | ||
1219 | |||
1220 | return 0; | ||
1221 | } | ||
1222 | |||
1223 | int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | ||
1224 | struct ieee80211_vif *vif) | ||
1225 | { | ||
1226 | struct iwl_priv *priv = hw->priv; | ||
1227 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
1228 | struct iwl_rxon_context *tmp, *ctx = NULL; | ||
1229 | int err; | ||
1230 | enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif); | ||
1231 | |||
1232 | IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", | ||
1233 | viftype, vif->addr); | ||
1234 | |||
1235 | cancel_delayed_work_sync(&priv->hw_roc_disable_work); | ||
1236 | |||
1237 | mutex_lock(&priv->shrd->mutex); | ||
1238 | |||
1239 | iwlagn_disable_roc(priv); | ||
1240 | |||
1241 | if (!iwl_is_ready_rf(priv->shrd)) { | ||
1242 | IWL_WARN(priv, "Try to add interface when device not ready\n"); | ||
1243 | err = -EINVAL; | ||
1244 | goto out; | ||
1245 | } | ||
1246 | |||
1247 | for_each_context(priv, tmp) { | ||
1248 | u32 possible_modes = | ||
1249 | tmp->interface_modes | tmp->exclusive_interface_modes; | ||
1250 | |||
1251 | if (tmp->vif) { | ||
1252 | /* check if this busy context is exclusive */ | ||
1253 | if (tmp->exclusive_interface_modes & | ||
1254 | BIT(tmp->vif->type)) { | ||
1255 | err = -EINVAL; | ||
1256 | goto out; | ||
1257 | } | ||
1258 | continue; | ||
1259 | } | ||
1260 | |||
1261 | if (!(possible_modes & BIT(viftype))) | ||
1262 | continue; | ||
1263 | 1123 | ||
1264 | /* have maybe usable context w/o interface */ | ||
1265 | ctx = tmp; | ||
1266 | break; | ||
1267 | } | ||
1268 | |||
1269 | if (!ctx) { | ||
1270 | err = -EOPNOTSUPP; | ||
1271 | goto out; | ||
1272 | } | ||
1273 | |||
1274 | vif_priv->ctx = ctx; | ||
1275 | ctx->vif = vif; | ||
1276 | |||
1277 | err = iwl_setup_interface(priv, ctx); | ||
1278 | if (!err) | ||
1279 | goto out; | ||
1280 | 1124 | ||
1281 | ctx->vif = NULL; | ||
1282 | priv->iw_mode = NL80211_IFTYPE_STATION; | ||
1283 | out: | ||
1284 | mutex_unlock(&priv->shrd->mutex); | ||
1285 | |||
1286 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1287 | return err; | ||
1288 | } | ||
1289 | |||
1290 | static void iwl_teardown_interface(struct iwl_priv *priv, | ||
1291 | struct ieee80211_vif *vif, | ||
1292 | bool mode_change) | ||
1293 | { | ||
1294 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
1295 | |||
1296 | lockdep_assert_held(&priv->shrd->mutex); | ||
1297 | |||
1298 | if (priv->scan_vif == vif) { | ||
1299 | iwl_scan_cancel_timeout(priv, 200); | ||
1300 | iwl_force_scan_end(priv); | ||
1301 | } | ||
1302 | |||
1303 | if (!mode_change) { | ||
1304 | iwl_set_mode(priv, ctx); | ||
1305 | if (!ctx->always_active) | ||
1306 | ctx->is_active = false; | ||
1307 | } | ||
1308 | |||
1309 | /* | ||
1310 | * When removing the IBSS interface, overwrite the | ||
1311 | * BT traffic load with the stored one from the last | ||
1312 | * notification, if any. If this is a device that | ||
1313 | * doesn't implement this, this has no effect since | ||
1314 | * both values are the same and zero. | ||
1315 | */ | ||
1316 | if (vif->type == NL80211_IFTYPE_ADHOC) | ||
1317 | priv->bt_traffic_load = priv->last_bt_traffic_load; | ||
1318 | } | ||
1319 | |||
1320 | void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, | ||
1321 | struct ieee80211_vif *vif) | ||
1322 | { | ||
1323 | struct iwl_priv *priv = hw->priv; | ||
1324 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
1325 | |||
1326 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1327 | |||
1328 | mutex_lock(&priv->shrd->mutex); | ||
1329 | |||
1330 | if (WARN_ON(ctx->vif != vif)) { | ||
1331 | struct iwl_rxon_context *tmp; | ||
1332 | IWL_ERR(priv, "ctx->vif = %p, vif = %p\n", ctx->vif, vif); | ||
1333 | for_each_context(priv, tmp) | ||
1334 | IWL_ERR(priv, "\tID = %d:\tctx = %p\tctx->vif = %p\n", | ||
1335 | tmp->ctxid, tmp, tmp->vif); | ||
1336 | } | ||
1337 | ctx->vif = NULL; | ||
1338 | |||
1339 | iwl_teardown_interface(priv, vif, false); | ||
1340 | |||
1341 | mutex_unlock(&priv->shrd->mutex); | ||
1342 | |||
1343 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1344 | |||
1345 | } | ||
1346 | 1125 | ||
1347 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1126 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
1348 | 1127 | ||
@@ -1649,97 +1428,13 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) | |||
1649 | return 0; | 1428 | return 0; |
1650 | } | 1429 | } |
1651 | 1430 | ||
1652 | int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | ||
1653 | struct ieee80211_vif *vif, | ||
1654 | enum nl80211_iftype newtype, bool newp2p) | ||
1655 | { | ||
1656 | struct iwl_priv *priv = hw->priv; | ||
1657 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
1658 | struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
1659 | struct iwl_rxon_context *tmp; | ||
1660 | enum nl80211_iftype newviftype = newtype; | ||
1661 | u32 interface_modes; | ||
1662 | int err; | ||
1663 | |||
1664 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1665 | |||
1666 | newtype = ieee80211_iftype_p2p(newtype, newp2p); | ||
1667 | |||
1668 | mutex_lock(&priv->shrd->mutex); | ||
1669 | |||
1670 | if (!ctx->vif || !iwl_is_ready_rf(priv->shrd)) { | ||
1671 | /* | ||
1672 | * Huh? But wait ... this can maybe happen when | ||
1673 | * we're in the middle of a firmware restart! | ||
1674 | */ | ||
1675 | err = -EBUSY; | ||
1676 | goto out; | ||
1677 | } | ||
1678 | |||
1679 | interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; | ||
1680 | |||
1681 | if (!(interface_modes & BIT(newtype))) { | ||
1682 | err = -EBUSY; | ||
1683 | goto out; | ||
1684 | } | ||
1685 | |||
1686 | /* | ||
1687 | * Refuse a change that should be done by moving from the PAN | ||
1688 | * context to the BSS context instead, if the BSS context is | ||
1689 | * available and can support the new interface type. | ||
1690 | */ | ||
1691 | if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif && | ||
1692 | (bss_ctx->interface_modes & BIT(newtype) || | ||
1693 | bss_ctx->exclusive_interface_modes & BIT(newtype))) { | ||
1694 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | ||
1695 | err = -EBUSY; | ||
1696 | goto out; | ||
1697 | } | ||
1698 | |||
1699 | if (ctx->exclusive_interface_modes & BIT(newtype)) { | ||
1700 | for_each_context(priv, tmp) { | ||
1701 | if (ctx == tmp) | ||
1702 | continue; | ||
1703 | |||
1704 | if (!tmp->vif) | ||
1705 | continue; | ||
1706 | |||
1707 | /* | ||
1708 | * The current mode switch would be exclusive, but | ||
1709 | * another context is active ... refuse the switch. | ||
1710 | */ | ||
1711 | err = -EBUSY; | ||
1712 | goto out; | ||
1713 | } | ||
1714 | } | ||
1715 | |||
1716 | /* success */ | ||
1717 | iwl_teardown_interface(priv, vif, true); | ||
1718 | vif->type = newviftype; | ||
1719 | vif->p2p = newp2p; | ||
1720 | err = iwl_setup_interface(priv, ctx); | ||
1721 | WARN_ON(err); | ||
1722 | /* | ||
1723 | * We've switched internally, but submitting to the | ||
1724 | * device may have failed for some reason. Mask this | ||
1725 | * error, because otherwise mac80211 will not switch | ||
1726 | * (and set the interface type back) and we'll be | ||
1727 | * out of sync with it. | ||
1728 | */ | ||
1729 | err = 0; | ||
1730 | |||
1731 | out: | ||
1732 | mutex_unlock(&priv->shrd->mutex); | ||
1733 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1734 | |||
1735 | return err; | ||
1736 | } | ||
1737 | 1431 | ||
1738 | int iwl_cmd_echo_test(struct iwl_priv *priv) | 1432 | int iwl_cmd_echo_test(struct iwl_priv *priv) |
1739 | { | 1433 | { |
1740 | int ret; | 1434 | int ret; |
1741 | struct iwl_host_cmd cmd = { | 1435 | struct iwl_host_cmd cmd = { |
1742 | .id = REPLY_ECHO, | 1436 | .id = REPLY_ECHO, |
1437 | .len = { 0 }, | ||
1743 | .flags = CMD_SYNC, | 1438 | .flags = CMD_SYNC, |
1744 | }; | 1439 | }; |
1745 | 1440 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 137da3380704..fa47f75185df 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -237,10 +237,6 @@ struct iwl_cfg { | |||
237 | * L i b * | 237 | * L i b * |
238 | ***************************/ | 238 | ***************************/ |
239 | 239 | ||
240 | int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | ||
241 | struct ieee80211_vif *vif, u16 queue, | ||
242 | const struct ieee80211_tx_queue_params *params); | ||
243 | int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw); | ||
244 | void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 240 | void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
245 | int hw_decrypt); | 241 | int hw_decrypt); |
246 | int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | 242 | int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
@@ -260,13 +256,6 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, | |||
260 | void iwl_connection_init_rx_config(struct iwl_priv *priv, | 256 | void iwl_connection_init_rx_config(struct iwl_priv *priv, |
261 | struct iwl_rxon_context *ctx); | 257 | struct iwl_rxon_context *ctx); |
262 | void iwl_set_rate(struct iwl_priv *priv); | 258 | void iwl_set_rate(struct iwl_priv *priv); |
263 | int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | ||
264 | struct ieee80211_vif *vif); | ||
265 | void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, | ||
266 | struct ieee80211_vif *vif); | ||
267 | int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | ||
268 | struct ieee80211_vif *vif, | ||
269 | enum nl80211_iftype newtype, bool newp2p); | ||
270 | int iwl_cmd_echo_test(struct iwl_priv *priv); | 259 | int iwl_cmd_echo_test(struct iwl_priv *priv); |
271 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 260 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
272 | int iwl_alloc_traffic_mem(struct iwl_priv *priv); | 261 | int iwl_alloc_traffic_mem(struct iwl_priv *priv); |
@@ -323,9 +312,6 @@ void iwl_init_scan_params(struct iwl_priv *priv); | |||
323 | int iwl_scan_cancel(struct iwl_priv *priv); | 312 | int iwl_scan_cancel(struct iwl_priv *priv); |
324 | void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); | 313 | void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); |
325 | void iwl_force_scan_end(struct iwl_priv *priv); | 314 | void iwl_force_scan_end(struct iwl_priv *priv); |
326 | int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | ||
327 | struct ieee80211_vif *vif, | ||
328 | struct cfg80211_scan_request *req); | ||
329 | void iwl_internal_short_hw_scan(struct iwl_priv *priv); | 315 | void iwl_internal_short_hw_scan(struct iwl_priv *priv); |
330 | int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); | 316 | int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); |
331 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, | 317 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index b9f3267e720c..fbc3095c7b44 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -284,8 +284,8 @@ | |||
284 | #define CSR_HW_REV_TYPE_6x35 CSR_HW_REV_TYPE_6x05 | 284 | #define CSR_HW_REV_TYPE_6x35 CSR_HW_REV_TYPE_6x05 |
285 | #define CSR_HW_REV_TYPE_2x30 (0x00000C0) | 285 | #define CSR_HW_REV_TYPE_2x30 (0x00000C0) |
286 | #define CSR_HW_REV_TYPE_2x00 (0x0000100) | 286 | #define CSR_HW_REV_TYPE_2x00 (0x0000100) |
287 | #define CSR_HW_REV_TYPE_200 (0x0000110) | 287 | #define CSR_HW_REV_TYPE_105 (0x0000110) |
288 | #define CSR_HW_REV_TYPE_230 (0x0000120) | 288 | #define CSR_HW_REV_TYPE_135 (0x0000120) |
289 | #define CSR_HW_REV_TYPE_NONE (0x00001F0) | 289 | #define CSR_HW_REV_TYPE_NONE (0x00001F0) |
290 | 290 | ||
291 | /* EEPROM REG */ | 291 | /* EEPROM REG */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 69a77e24d229..40ef97bac1aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -70,10 +70,25 @@ do { \ | |||
70 | DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ | 70 | DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ |
71 | } while (0) | 71 | } while (0) |
72 | 72 | ||
73 | #define IWL_DEBUG_QUIET_RFKILL(p, fmt, args...) \ | ||
74 | do { \ | ||
75 | if (!iwl_is_rfkill(p->shrd)) \ | ||
76 | dev_printk(KERN_ERR, bus(p)->dev, "%c %s " fmt, \ | ||
77 | (in_interrupt() ? 'I' : 'U'), __func__ , ##args); \ | ||
78 | else if (iwl_get_debug_level(p->shrd) & IWL_DL_RADIO) \ | ||
79 | dev_printk(KERN_ERR, bus(p)->dev, "(RFKILL) %c %s " fmt, \ | ||
80 | (in_interrupt() ? 'I' : 'U'), __func__ , ##args); \ | ||
81 | } while (0) | ||
82 | |||
73 | #else | 83 | #else |
74 | #define IWL_DEBUG(m, level, fmt, args...) | 84 | #define IWL_DEBUG(m, level, fmt, args...) |
75 | #define IWL_DEBUG_LIMIT(m, level, fmt, args...) | 85 | #define IWL_DEBUG_LIMIT(m, level, fmt, args...) |
76 | #define iwl_print_hex_dump(m, level, p, len) | 86 | #define iwl_print_hex_dump(m, level, p, len) |
87 | #define IWL_DEBUG_QUIET_RFKILL(p, fmt, args...) \ | ||
88 | do { \ | ||
89 | if (!iwl_is_rfkill(p->shrd)) \ | ||
90 | IWL_ERR(p, fmt, ##args); \ | ||
91 | } while (0) | ||
77 | #endif /* CONFIG_IWLWIFI_DEBUG */ | 92 | #endif /* CONFIG_IWLWIFI_DEBUG */ |
78 | 93 | ||
79 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 94 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
@@ -151,7 +166,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
151 | #define IWL_DL_11H (1 << 28) | 166 | #define IWL_DL_11H (1 << 28) |
152 | #define IWL_DL_STATS (1 << 29) | 167 | #define IWL_DL_STATS (1 << 29) |
153 | #define IWL_DL_TX_REPLY (1 << 30) | 168 | #define IWL_DL_TX_REPLY (1 << 30) |
154 | #define IWL_DL_QOS (1 << 31) | 169 | #define IWL_DL_TX_QUEUES (1 << 31) |
155 | 170 | ||
156 | #define IWL_DEBUG_INFO(p, f, a...) IWL_DEBUG(p, IWL_DL_INFO, f, ## a) | 171 | #define IWL_DEBUG_INFO(p, f, a...) IWL_DEBUG(p, IWL_DL_INFO, f, ## a) |
157 | #define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a) | 172 | #define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a) |
@@ -188,7 +203,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
188 | #define IWL_DEBUG_TX_REPLY(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_REPLY, f, ## a) | 203 | #define IWL_DEBUG_TX_REPLY(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_REPLY, f, ## a) |
189 | #define IWL_DEBUG_TX_REPLY_LIMIT(p, f, a...) \ | 204 | #define IWL_DEBUG_TX_REPLY_LIMIT(p, f, a...) \ |
190 | IWL_DEBUG_LIMIT(p, IWL_DL_TX_REPLY, f, ## a) | 205 | IWL_DEBUG_LIMIT(p, IWL_DL_TX_REPLY, f, ## a) |
191 | #define IWL_DEBUG_QOS(p, f, a...) IWL_DEBUG(p, IWL_DL_QOS, f, ## a) | 206 | #define IWL_DEBUG_TX_QUEUES(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_QUEUES, f, ## a) |
192 | #define IWL_DEBUG_RADIO(p, f, a...) IWL_DEBUG(p, IWL_DL_RADIO, f, ## a) | 207 | #define IWL_DEBUG_RADIO(p, f, a...) IWL_DEBUG(p, IWL_DL_RADIO, f, ## a) |
193 | #define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a) | 208 | #define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a) |
194 | #define IWL_DEBUG_11H(p, f, a...) IWL_DEBUG(p, IWL_DL_11H, f, ## a) | 209 | #define IWL_DEBUG_11H(p, f, a...) IWL_DEBUG(p, IWL_DL_11H, f, ## a) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index a1670e3f8bfa..68b04f5b10ce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -236,9 +236,9 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
236 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { | 236 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { |
237 | priv->dbgfs_sram_offset = 0x800000; | 237 | priv->dbgfs_sram_offset = 0x800000; |
238 | if (priv->ucode_type == IWL_UCODE_INIT) | 238 | if (priv->ucode_type == IWL_UCODE_INIT) |
239 | priv->dbgfs_sram_len = priv->ucode_init.data.len; | 239 | priv->dbgfs_sram_len = trans(priv)->ucode_init.data.len; |
240 | else | 240 | else |
241 | priv->dbgfs_sram_len = priv->ucode_rt.data.len; | 241 | priv->dbgfs_sram_len = trans(priv)->ucode_rt.data.len; |
242 | } | 242 | } |
243 | len = priv->dbgfs_sram_len; | 243 | len = priv->dbgfs_sram_len; |
244 | 244 | ||
@@ -341,7 +341,7 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file, | |||
341 | 341 | ||
342 | return simple_read_from_buffer(user_buf, count, ppos, | 342 | return simple_read_from_buffer(user_buf, count, ppos, |
343 | priv->wowlan_sram, | 343 | priv->wowlan_sram, |
344 | priv->ucode_wowlan.data.len); | 344 | trans(priv)->ucode_wowlan.data.len); |
345 | } | 345 | } |
346 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | 346 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, |
347 | size_t count, loff_t *ppos) | 347 | size_t count, loff_t *ppos) |
@@ -430,7 +430,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, | |||
430 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); | 430 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); |
431 | pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " | 431 | pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " |
432 | "version: 0x%x\n", | 432 | "version: 0x%x\n", |
433 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) | 433 | (trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP) |
434 | ? "OTP" : "EEPROM", eeprom_ver); | 434 | ? "OTP" : "EEPROM", eeprom_ver); |
435 | for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { | 435 | for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { |
436 | pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); | 436 | pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 6c00a447963d..556e4a2c19bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -230,17 +230,6 @@ struct iwl_vif_priv { | |||
230 | u8 ibss_bssid_sta_id; | 230 | u8 ibss_bssid_sta_id; |
231 | }; | 231 | }; |
232 | 232 | ||
233 | /* one for each uCode image (inst/data, boot/init/runtime) */ | ||
234 | struct fw_desc { | ||
235 | void *v_addr; /* access by driver */ | ||
236 | dma_addr_t p_addr; /* access by card's busmaster DMA */ | ||
237 | u32 len; /* bytes */ | ||
238 | }; | ||
239 | |||
240 | struct fw_img { | ||
241 | struct fw_desc code, data; | ||
242 | }; | ||
243 | |||
244 | /* v1/v2 uCode file layout */ | 233 | /* v1/v2 uCode file layout */ |
245 | struct iwl_ucode_header { | 234 | struct iwl_ucode_header { |
246 | __le32 ver; /* major/minor/API/serial */ | 235 | __le32 ver; /* major/minor/API/serial */ |
@@ -805,13 +794,6 @@ enum iwl_scan_type { | |||
805 | IWL_SCAN_ROC, | 794 | IWL_SCAN_ROC, |
806 | }; | 795 | }; |
807 | 796 | ||
808 | enum iwlagn_ucode_type { | ||
809 | IWL_UCODE_NONE, | ||
810 | IWL_UCODE_REGULAR, | ||
811 | IWL_UCODE_INIT, | ||
812 | IWL_UCODE_WOWLAN, | ||
813 | }; | ||
814 | |||
815 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL | 797 | #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL |
816 | struct iwl_testmode_trace { | 798 | struct iwl_testmode_trace { |
817 | u32 buff_size; | 799 | u32 buff_size; |
@@ -824,6 +806,12 @@ struct iwl_testmode_trace { | |||
824 | }; | 806 | }; |
825 | #endif | 807 | #endif |
826 | 808 | ||
809 | struct iwl_wipan_noa_data { | ||
810 | struct rcu_head rcu_head; | ||
811 | u32 length; | ||
812 | u8 data[]; | ||
813 | }; | ||
814 | |||
827 | struct iwl_priv { | 815 | struct iwl_priv { |
828 | 816 | ||
829 | /*data shared among all the driver's layers */ | 817 | /*data shared among all the driver's layers */ |
@@ -883,6 +871,8 @@ struct iwl_priv { | |||
883 | /* init calibration results */ | 871 | /* init calibration results */ |
884 | struct iwl_calib_result calib_results[IWL_CALIB_MAX]; | 872 | struct iwl_calib_result calib_results[IWL_CALIB_MAX]; |
885 | 873 | ||
874 | struct iwl_wipan_noa_data __rcu *noa_data; | ||
875 | |||
886 | /* Scan related variables */ | 876 | /* Scan related variables */ |
887 | unsigned long scan_start; | 877 | unsigned long scan_start; |
888 | unsigned long scan_start_tsf; | 878 | unsigned long scan_start_tsf; |
@@ -907,12 +897,7 @@ struct iwl_priv { | |||
907 | u32 ucode_ver; /* version of ucode, copy of | 897 | u32 ucode_ver; /* version of ucode, copy of |
908 | iwl_ucode.ver */ | 898 | iwl_ucode.ver */ |
909 | 899 | ||
910 | struct fw_img ucode_rt; | 900 | enum iwl_ucode_type ucode_type; |
911 | struct fw_img ucode_init; | ||
912 | struct fw_img ucode_wowlan; | ||
913 | |||
914 | enum iwlagn_ucode_type ucode_type; | ||
915 | u8 ucode_write_complete; /* the image write is complete */ | ||
916 | char firmware_name[25]; | 901 | char firmware_name[25]; |
917 | 902 | ||
918 | struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; | 903 | struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; |
@@ -959,7 +944,6 @@ struct iwl_priv { | |||
959 | 944 | ||
960 | /* eeprom -- this is in the card's little endian byte order */ | 945 | /* eeprom -- this is in the card's little endian byte order */ |
961 | u8 *eeprom; | 946 | u8 *eeprom; |
962 | int nvm_device_type; | ||
963 | struct iwl_eeprom_calib_info *calib_info; | 947 | struct iwl_eeprom_calib_info *calib_info; |
964 | 948 | ||
965 | enum nl80211_iftype iw_mode; | 949 | enum nl80211_iftype iw_mode; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index a635a7e75447..2a2c8de64a04 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | /* sparse doesn't like tracepoint macros */ | 29 | /* sparse doesn't like tracepoint macros */ |
30 | #ifndef __CHECKER__ | 30 | #ifndef __CHECKER__ |
31 | #include "iwl-dev.h" | 31 | #include "iwl-trans.h" |
32 | 32 | ||
33 | #define CREATE_TRACE_POINTS | 33 | #define CREATE_TRACE_POINTS |
34 | #include "iwl-devtrace.h" | 34 | #include "iwl-devtrace.h" |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 8a51c5ccda1e..f9d3319ecad5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
@@ -29,7 +29,6 @@ | |||
29 | 29 | ||
30 | #include <linux/tracepoint.h> | 30 | #include <linux/tracepoint.h> |
31 | 31 | ||
32 | struct iwl_priv; | ||
33 | 32 | ||
34 | #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) | 33 | #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) |
35 | #undef TRACE_EVENT | 34 | #undef TRACE_EVENT |
@@ -37,14 +36,14 @@ struct iwl_priv; | |||
37 | static inline void trace_ ## name(proto) {} | 36 | static inline void trace_ ## name(proto) {} |
38 | #endif | 37 | #endif |
39 | 38 | ||
40 | #define PRIV_ENTRY __field(struct iwl_priv *, priv) | 39 | #define PRIV_ENTRY __field(void *, priv) |
41 | #define PRIV_ASSIGN __entry->priv = priv | 40 | #define PRIV_ASSIGN __entry->priv = priv |
42 | 41 | ||
43 | #undef TRACE_SYSTEM | 42 | #undef TRACE_SYSTEM |
44 | #define TRACE_SYSTEM iwlwifi_io | 43 | #define TRACE_SYSTEM iwlwifi_io |
45 | 44 | ||
46 | TRACE_EVENT(iwlwifi_dev_ioread32, | 45 | TRACE_EVENT(iwlwifi_dev_ioread32, |
47 | TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), | 46 | TP_PROTO(void *priv, u32 offs, u32 val), |
48 | TP_ARGS(priv, offs, val), | 47 | TP_ARGS(priv, offs, val), |
49 | TP_STRUCT__entry( | 48 | TP_STRUCT__entry( |
50 | PRIV_ENTRY | 49 | PRIV_ENTRY |
@@ -60,7 +59,7 @@ TRACE_EVENT(iwlwifi_dev_ioread32, | |||
60 | ); | 59 | ); |
61 | 60 | ||
62 | TRACE_EVENT(iwlwifi_dev_iowrite8, | 61 | TRACE_EVENT(iwlwifi_dev_iowrite8, |
63 | TP_PROTO(struct iwl_priv *priv, u32 offs, u8 val), | 62 | TP_PROTO(void *priv, u32 offs, u8 val), |
64 | TP_ARGS(priv, offs, val), | 63 | TP_ARGS(priv, offs, val), |
65 | TP_STRUCT__entry( | 64 | TP_STRUCT__entry( |
66 | PRIV_ENTRY | 65 | PRIV_ENTRY |
@@ -76,7 +75,7 @@ TRACE_EVENT(iwlwifi_dev_iowrite8, | |||
76 | ); | 75 | ); |
77 | 76 | ||
78 | TRACE_EVENT(iwlwifi_dev_iowrite32, | 77 | TRACE_EVENT(iwlwifi_dev_iowrite32, |
79 | TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), | 78 | TP_PROTO(void *priv, u32 offs, u32 val), |
80 | TP_ARGS(priv, offs, val), | 79 | TP_ARGS(priv, offs, val), |
81 | TP_STRUCT__entry( | 80 | TP_STRUCT__entry( |
82 | PRIV_ENTRY | 81 | PRIV_ENTRY |
@@ -95,7 +94,7 @@ TRACE_EVENT(iwlwifi_dev_iowrite32, | |||
95 | #define TRACE_SYSTEM iwlwifi_ucode | 94 | #define TRACE_SYSTEM iwlwifi_ucode |
96 | 95 | ||
97 | TRACE_EVENT(iwlwifi_dev_ucode_cont_event, | 96 | TRACE_EVENT(iwlwifi_dev_ucode_cont_event, |
98 | TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), | 97 | TP_PROTO(void *priv, u32 time, u32 data, u32 ev), |
99 | TP_ARGS(priv, time, data, ev), | 98 | TP_ARGS(priv, time, data, ev), |
100 | TP_STRUCT__entry( | 99 | TP_STRUCT__entry( |
101 | PRIV_ENTRY | 100 | PRIV_ENTRY |
@@ -115,7 +114,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_cont_event, | |||
115 | ); | 114 | ); |
116 | 115 | ||
117 | TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, | 116 | TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, |
118 | TP_PROTO(struct iwl_priv *priv, u32 wraps, u32 n_entry, u32 p_entry), | 117 | TP_PROTO(void *priv, u32 wraps, u32 n_entry, u32 p_entry), |
119 | TP_ARGS(priv, wraps, n_entry, p_entry), | 118 | TP_ARGS(priv, wraps, n_entry, p_entry), |
120 | TP_STRUCT__entry( | 119 | TP_STRUCT__entry( |
121 | PRIV_ENTRY | 120 | PRIV_ENTRY |
@@ -139,7 +138,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, | |||
139 | #define TRACE_SYSTEM iwlwifi | 138 | #define TRACE_SYSTEM iwlwifi |
140 | 139 | ||
141 | TRACE_EVENT(iwlwifi_dev_hcmd, | 140 | TRACE_EVENT(iwlwifi_dev_hcmd, |
142 | TP_PROTO(struct iwl_priv *priv, u32 flags, | 141 | TP_PROTO(void *priv, u32 flags, |
143 | const void *hcmd0, size_t len0, | 142 | const void *hcmd0, size_t len0, |
144 | const void *hcmd1, size_t len1, | 143 | const void *hcmd1, size_t len1, |
145 | const void *hcmd2, size_t len2), | 144 | const void *hcmd2, size_t len2), |
@@ -164,7 +163,7 @@ TRACE_EVENT(iwlwifi_dev_hcmd, | |||
164 | ); | 163 | ); |
165 | 164 | ||
166 | TRACE_EVENT(iwlwifi_dev_rx, | 165 | TRACE_EVENT(iwlwifi_dev_rx, |
167 | TP_PROTO(struct iwl_priv *priv, void *rxbuf, size_t len), | 166 | TP_PROTO(void *priv, void *rxbuf, size_t len), |
168 | TP_ARGS(priv, rxbuf, len), | 167 | TP_ARGS(priv, rxbuf, len), |
169 | TP_STRUCT__entry( | 168 | TP_STRUCT__entry( |
170 | PRIV_ENTRY | 169 | PRIV_ENTRY |
@@ -179,7 +178,7 @@ TRACE_EVENT(iwlwifi_dev_rx, | |||
179 | ); | 178 | ); |
180 | 179 | ||
181 | TRACE_EVENT(iwlwifi_dev_tx, | 180 | TRACE_EVENT(iwlwifi_dev_tx, |
182 | TP_PROTO(struct iwl_priv *priv, void *tfd, size_t tfdlen, | 181 | TP_PROTO(void *priv, void *tfd, size_t tfdlen, |
183 | void *buf0, size_t buf0_len, | 182 | void *buf0, size_t buf0_len, |
184 | void *buf1, size_t buf1_len), | 183 | void *buf1, size_t buf1_len), |
185 | TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), | 184 | TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), |
@@ -211,7 +210,7 @@ TRACE_EVENT(iwlwifi_dev_tx, | |||
211 | ); | 210 | ); |
212 | 211 | ||
213 | TRACE_EVENT(iwlwifi_dev_ucode_error, | 212 | TRACE_EVENT(iwlwifi_dev_ucode_error, |
214 | TP_PROTO(struct iwl_priv *priv, u32 desc, u32 tsf_low, | 213 | TP_PROTO(void *priv, u32 desc, u32 tsf_low, |
215 | u32 data1, u32 data2, u32 line, u32 blink1, | 214 | u32 data1, u32 data2, u32 line, u32 blink1, |
216 | u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, | 215 | u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, |
217 | u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, | 216 | u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, |
@@ -271,7 +270,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, | |||
271 | ); | 270 | ); |
272 | 271 | ||
273 | TRACE_EVENT(iwlwifi_dev_ucode_event, | 272 | TRACE_EVENT(iwlwifi_dev_ucode_event, |
274 | TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), | 273 | TP_PROTO(void *priv, u32 time, u32 data, u32 ev), |
275 | TP_ARGS(priv, time, data, ev), | 274 | TP_ARGS(priv, time, data, ev), |
276 | TP_STRUCT__entry( | 275 | TP_STRUCT__entry( |
277 | PRIV_ENTRY | 276 | PRIV_ENTRY |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index a4e43bd4a547..dcada0827ea4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -149,23 +149,23 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ | |||
149 | * EEPROM chip, not a single event, so even reads could conflict if they | 149 | * EEPROM chip, not a single event, so even reads could conflict if they |
150 | * weren't arbitrated by the semaphore. | 150 | * weren't arbitrated by the semaphore. |
151 | */ | 151 | */ |
152 | static int iwl_eeprom_acquire_semaphore(struct iwl_priv *priv) | 152 | static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus) |
153 | { | 153 | { |
154 | u16 count; | 154 | u16 count; |
155 | int ret; | 155 | int ret; |
156 | 156 | ||
157 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { | 157 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { |
158 | /* Request semaphore */ | 158 | /* Request semaphore */ |
159 | iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, | 159 | iwl_set_bit(bus, CSR_HW_IF_CONFIG_REG, |
160 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | 160 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); |
161 | 161 | ||
162 | /* See if we got it */ | 162 | /* See if we got it */ |
163 | ret = iwl_poll_bit(bus(priv), CSR_HW_IF_CONFIG_REG, | 163 | ret = iwl_poll_bit(bus, CSR_HW_IF_CONFIG_REG, |
164 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | 164 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, |
165 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | 165 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, |
166 | EEPROM_SEM_TIMEOUT); | 166 | EEPROM_SEM_TIMEOUT); |
167 | if (ret >= 0) { | 167 | if (ret >= 0) { |
168 | IWL_DEBUG_EEPROM(priv, | 168 | IWL_DEBUG_EEPROM(bus, |
169 | "Acquired semaphore after %d tries.\n", | 169 | "Acquired semaphore after %d tries.\n", |
170 | count+1); | 170 | count+1); |
171 | return ret; | 171 | return ret; |
@@ -175,39 +175,39 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_priv *priv) | |||
175 | return ret; | 175 | return ret; |
176 | } | 176 | } |
177 | 177 | ||
178 | static void iwl_eeprom_release_semaphore(struct iwl_priv *priv) | 178 | static void iwl_eeprom_release_semaphore(struct iwl_bus *bus) |
179 | { | 179 | { |
180 | iwl_clear_bit(bus(priv), CSR_HW_IF_CONFIG_REG, | 180 | iwl_clear_bit(bus, CSR_HW_IF_CONFIG_REG, |
181 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | 181 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); |
182 | 182 | ||
183 | } | 183 | } |
184 | 184 | ||
185 | static int iwl_eeprom_verify_signature(struct iwl_priv *priv) | 185 | static int iwl_eeprom_verify_signature(struct iwl_trans *trans) |
186 | { | 186 | { |
187 | u32 gp = iwl_read32(bus(priv), CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; | 187 | u32 gp = iwl_read32(bus(trans), CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; |
188 | int ret = 0; | 188 | int ret = 0; |
189 | 189 | ||
190 | IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp); | 190 | IWL_DEBUG_EEPROM(trans, "EEPROM signature=0x%08x\n", gp); |
191 | switch (gp) { | 191 | switch (gp) { |
192 | case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: | 192 | case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: |
193 | if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) { | 193 | if (trans->nvm_device_type != NVM_DEVICE_TYPE_OTP) { |
194 | IWL_ERR(priv, "EEPROM with bad signature: 0x%08x\n", | 194 | IWL_ERR(trans, "EEPROM with bad signature: 0x%08x\n", |
195 | gp); | 195 | gp); |
196 | ret = -ENOENT; | 196 | ret = -ENOENT; |
197 | } | 197 | } |
198 | break; | 198 | break; |
199 | case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: | 199 | case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: |
200 | case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: | 200 | case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: |
201 | if (priv->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) { | 201 | if (trans->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) { |
202 | IWL_ERR(priv, "OTP with bad signature: 0x%08x\n", gp); | 202 | IWL_ERR(trans, "OTP with bad signature: 0x%08x\n", gp); |
203 | ret = -ENOENT; | 203 | ret = -ENOENT; |
204 | } | 204 | } |
205 | break; | 205 | break; |
206 | case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: | 206 | case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: |
207 | default: | 207 | default: |
208 | IWL_ERR(priv, "bad EEPROM/OTP signature, type=%s, " | 208 | IWL_ERR(trans, "bad EEPROM/OTP signature, type=%s, " |
209 | "EEPROM_GP=0x%08x\n", | 209 | "EEPROM_GP=0x%08x\n", |
210 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) | 210 | (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP) |
211 | ? "OTP" : "EEPROM", gp); | 211 | ? "OTP" : "EEPROM", gp); |
212 | ret = -ENOENT; | 212 | ret = -ENOENT; |
213 | break; | 213 | break; |
@@ -302,19 +302,19 @@ void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) | |||
302 | * | 302 | * |
303 | ******************************************************************************/ | 303 | ******************************************************************************/ |
304 | 304 | ||
305 | static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode) | 305 | static void iwl_set_otp_access(struct iwl_bus *bus, enum iwl_access_mode mode) |
306 | { | 306 | { |
307 | iwl_read32(bus(priv), CSR_OTP_GP_REG); | 307 | iwl_read32(bus, CSR_OTP_GP_REG); |
308 | 308 | ||
309 | if (mode == IWL_OTP_ACCESS_ABSOLUTE) | 309 | if (mode == IWL_OTP_ACCESS_ABSOLUTE) |
310 | iwl_clear_bit(bus(priv), CSR_OTP_GP_REG, | 310 | iwl_clear_bit(bus, CSR_OTP_GP_REG, |
311 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | 311 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); |
312 | else | 312 | else |
313 | iwl_set_bit(bus(priv), CSR_OTP_GP_REG, | 313 | iwl_set_bit(bus, CSR_OTP_GP_REG, |
314 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | 314 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); |
315 | } | 315 | } |
316 | 316 | ||
317 | static int iwl_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) | 317 | static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev) |
318 | { | 318 | { |
319 | u32 otpgp; | 319 | u32 otpgp; |
320 | int nvm_type; | 320 | int nvm_type; |
@@ -322,7 +322,7 @@ static int iwl_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) | |||
322 | /* OTP only valid for CP/PP and after */ | 322 | /* OTP only valid for CP/PP and after */ |
323 | switch (hw_rev & CSR_HW_REV_TYPE_MSK) { | 323 | switch (hw_rev & CSR_HW_REV_TYPE_MSK) { |
324 | case CSR_HW_REV_TYPE_NONE: | 324 | case CSR_HW_REV_TYPE_NONE: |
325 | IWL_ERR(priv, "Unknown hardware type\n"); | 325 | IWL_ERR(bus, "Unknown hardware type\n"); |
326 | return -ENOENT; | 326 | return -ENOENT; |
327 | case CSR_HW_REV_TYPE_5300: | 327 | case CSR_HW_REV_TYPE_5300: |
328 | case CSR_HW_REV_TYPE_5350: | 328 | case CSR_HW_REV_TYPE_5350: |
@@ -331,7 +331,7 @@ static int iwl_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) | |||
331 | nvm_type = NVM_DEVICE_TYPE_EEPROM; | 331 | nvm_type = NVM_DEVICE_TYPE_EEPROM; |
332 | break; | 332 | break; |
333 | default: | 333 | default: |
334 | otpgp = iwl_read32(bus(priv), CSR_OTP_GP_REG); | 334 | otpgp = iwl_read32(bus, CSR_OTP_GP_REG); |
335 | if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) | 335 | if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) |
336 | nvm_type = NVM_DEVICE_TYPE_OTP; | 336 | nvm_type = NVM_DEVICE_TYPE_OTP; |
337 | else | 337 | else |
@@ -341,73 +341,73 @@ static int iwl_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) | |||
341 | return nvm_type; | 341 | return nvm_type; |
342 | } | 342 | } |
343 | 343 | ||
344 | static int iwl_init_otp_access(struct iwl_priv *priv) | 344 | static int iwl_init_otp_access(struct iwl_bus *bus) |
345 | { | 345 | { |
346 | int ret; | 346 | int ret; |
347 | 347 | ||
348 | /* Enable 40MHz radio clock */ | 348 | /* Enable 40MHz radio clock */ |
349 | iwl_write32(bus(priv), CSR_GP_CNTRL, | 349 | iwl_write32(bus, CSR_GP_CNTRL, |
350 | iwl_read32(bus(priv), CSR_GP_CNTRL) | | 350 | iwl_read32(bus, CSR_GP_CNTRL) | |
351 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | 351 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); |
352 | 352 | ||
353 | /* wait for clock to be ready */ | 353 | /* wait for clock to be ready */ |
354 | ret = iwl_poll_bit(bus(priv), CSR_GP_CNTRL, | 354 | ret = iwl_poll_bit(bus, CSR_GP_CNTRL, |
355 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | 355 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, |
356 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | 356 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, |
357 | 25000); | 357 | 25000); |
358 | if (ret < 0) | 358 | if (ret < 0) |
359 | IWL_ERR(priv, "Time out access OTP\n"); | 359 | IWL_ERR(bus, "Time out access OTP\n"); |
360 | else { | 360 | else { |
361 | iwl_set_bits_prph(bus(priv), APMG_PS_CTRL_REG, | 361 | iwl_set_bits_prph(bus, APMG_PS_CTRL_REG, |
362 | APMG_PS_CTRL_VAL_RESET_REQ); | 362 | APMG_PS_CTRL_VAL_RESET_REQ); |
363 | udelay(5); | 363 | udelay(5); |
364 | iwl_clear_bits_prph(bus(priv), APMG_PS_CTRL_REG, | 364 | iwl_clear_bits_prph(bus, APMG_PS_CTRL_REG, |
365 | APMG_PS_CTRL_VAL_RESET_REQ); | 365 | APMG_PS_CTRL_VAL_RESET_REQ); |
366 | 366 | ||
367 | /* | 367 | /* |
368 | * CSR auto clock gate disable bit - | 368 | * CSR auto clock gate disable bit - |
369 | * this is only applicable for HW with OTP shadow RAM | 369 | * this is only applicable for HW with OTP shadow RAM |
370 | */ | 370 | */ |
371 | if (priv->cfg->base_params->shadow_ram_support) | 371 | if (priv(bus)->cfg->base_params->shadow_ram_support) |
372 | iwl_set_bit(bus(priv), CSR_DBG_LINK_PWR_MGMT_REG, | 372 | iwl_set_bit(bus, CSR_DBG_LINK_PWR_MGMT_REG, |
373 | CSR_RESET_LINK_PWR_MGMT_DISABLED); | 373 | CSR_RESET_LINK_PWR_MGMT_DISABLED); |
374 | } | 374 | } |
375 | return ret; | 375 | return ret; |
376 | } | 376 | } |
377 | 377 | ||
378 | static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_data) | 378 | static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) |
379 | { | 379 | { |
380 | int ret = 0; | 380 | int ret = 0; |
381 | u32 r; | 381 | u32 r; |
382 | u32 otpgp; | 382 | u32 otpgp; |
383 | 383 | ||
384 | iwl_write32(bus(priv), CSR_EEPROM_REG, | 384 | iwl_write32(bus, CSR_EEPROM_REG, |
385 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | 385 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); |
386 | ret = iwl_poll_bit(bus(priv), CSR_EEPROM_REG, | 386 | ret = iwl_poll_bit(bus, CSR_EEPROM_REG, |
387 | CSR_EEPROM_REG_READ_VALID_MSK, | 387 | CSR_EEPROM_REG_READ_VALID_MSK, |
388 | CSR_EEPROM_REG_READ_VALID_MSK, | 388 | CSR_EEPROM_REG_READ_VALID_MSK, |
389 | IWL_EEPROM_ACCESS_TIMEOUT); | 389 | IWL_EEPROM_ACCESS_TIMEOUT); |
390 | if (ret < 0) { | 390 | if (ret < 0) { |
391 | IWL_ERR(priv, "Time out reading OTP[%d]\n", addr); | 391 | IWL_ERR(bus, "Time out reading OTP[%d]\n", addr); |
392 | return ret; | 392 | return ret; |
393 | } | 393 | } |
394 | r = iwl_read32(bus(priv), CSR_EEPROM_REG); | 394 | r = iwl_read32(bus, CSR_EEPROM_REG); |
395 | /* check for ECC errors: */ | 395 | /* check for ECC errors: */ |
396 | otpgp = iwl_read32(bus(priv), CSR_OTP_GP_REG); | 396 | otpgp = iwl_read32(bus, CSR_OTP_GP_REG); |
397 | if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { | 397 | if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { |
398 | /* stop in this case */ | 398 | /* stop in this case */ |
399 | /* set the uncorrectable OTP ECC bit for acknowledgement */ | 399 | /* set the uncorrectable OTP ECC bit for acknowledgement */ |
400 | iwl_set_bit(bus(priv), CSR_OTP_GP_REG, | 400 | iwl_set_bit(bus, CSR_OTP_GP_REG, |
401 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | 401 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); |
402 | IWL_ERR(priv, "Uncorrectable OTP ECC error, abort OTP read\n"); | 402 | IWL_ERR(bus, "Uncorrectable OTP ECC error, abort OTP read\n"); |
403 | return -EINVAL; | 403 | return -EINVAL; |
404 | } | 404 | } |
405 | if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { | 405 | if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { |
406 | /* continue in this case */ | 406 | /* continue in this case */ |
407 | /* set the correctable OTP ECC bit for acknowledgement */ | 407 | /* set the correctable OTP ECC bit for acknowledgement */ |
408 | iwl_set_bit(bus(priv), CSR_OTP_GP_REG, | 408 | iwl_set_bit(bus, CSR_OTP_GP_REG, |
409 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); | 409 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); |
410 | IWL_ERR(priv, "Correctable OTP ECC error, continue read\n"); | 410 | IWL_ERR(bus, "Correctable OTP ECC error, continue read\n"); |
411 | } | 411 | } |
412 | *eeprom_data = cpu_to_le16(r >> 16); | 412 | *eeprom_data = cpu_to_le16(r >> 16); |
413 | return 0; | 413 | return 0; |
@@ -416,20 +416,20 @@ static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, __le16 *eeprom_dat | |||
416 | /* | 416 | /* |
417 | * iwl_is_otp_empty: check for empty OTP | 417 | * iwl_is_otp_empty: check for empty OTP |
418 | */ | 418 | */ |
419 | static bool iwl_is_otp_empty(struct iwl_priv *priv) | 419 | static bool iwl_is_otp_empty(struct iwl_bus *bus) |
420 | { | 420 | { |
421 | u16 next_link_addr = 0; | 421 | u16 next_link_addr = 0; |
422 | __le16 link_value; | 422 | __le16 link_value; |
423 | bool is_empty = false; | 423 | bool is_empty = false; |
424 | 424 | ||
425 | /* locate the beginning of OTP link list */ | 425 | /* locate the beginning of OTP link list */ |
426 | if (!iwl_read_otp_word(priv, next_link_addr, &link_value)) { | 426 | if (!iwl_read_otp_word(bus, next_link_addr, &link_value)) { |
427 | if (!link_value) { | 427 | if (!link_value) { |
428 | IWL_ERR(priv, "OTP is empty\n"); | 428 | IWL_ERR(bus, "OTP is empty\n"); |
429 | is_empty = true; | 429 | is_empty = true; |
430 | } | 430 | } |
431 | } else { | 431 | } else { |
432 | IWL_ERR(priv, "Unable to read first block of OTP list.\n"); | 432 | IWL_ERR(bus, "Unable to read first block of OTP list.\n"); |
433 | is_empty = true; | 433 | is_empty = true; |
434 | } | 434 | } |
435 | 435 | ||
@@ -446,7 +446,7 @@ static bool iwl_is_otp_empty(struct iwl_priv *priv) | |||
446 | * we should read and used to configure the device. | 446 | * we should read and used to configure the device. |
447 | * only perform this operation if shadow RAM is disabled | 447 | * only perform this operation if shadow RAM is disabled |
448 | */ | 448 | */ |
449 | static int iwl_find_otp_image(struct iwl_priv *priv, | 449 | static int iwl_find_otp_image(struct iwl_bus *bus, |
450 | u16 *validblockaddr) | 450 | u16 *validblockaddr) |
451 | { | 451 | { |
452 | u16 next_link_addr = 0, valid_addr; | 452 | u16 next_link_addr = 0, valid_addr; |
@@ -454,10 +454,10 @@ static int iwl_find_otp_image(struct iwl_priv *priv, | |||
454 | int usedblocks = 0; | 454 | int usedblocks = 0; |
455 | 455 | ||
456 | /* set addressing mode to absolute to traverse the link list */ | 456 | /* set addressing mode to absolute to traverse the link list */ |
457 | iwl_set_otp_access(priv, IWL_OTP_ACCESS_ABSOLUTE); | 457 | iwl_set_otp_access(bus, IWL_OTP_ACCESS_ABSOLUTE); |
458 | 458 | ||
459 | /* checking for empty OTP or error */ | 459 | /* checking for empty OTP or error */ |
460 | if (iwl_is_otp_empty(priv)) | 460 | if (iwl_is_otp_empty(bus)) |
461 | return -EINVAL; | 461 | return -EINVAL; |
462 | 462 | ||
463 | /* | 463 | /* |
@@ -471,9 +471,9 @@ static int iwl_find_otp_image(struct iwl_priv *priv, | |||
471 | */ | 471 | */ |
472 | valid_addr = next_link_addr; | 472 | valid_addr = next_link_addr; |
473 | next_link_addr = le16_to_cpu(link_value) * sizeof(u16); | 473 | next_link_addr = le16_to_cpu(link_value) * sizeof(u16); |
474 | IWL_DEBUG_EEPROM(priv, "OTP blocks %d addr 0x%x\n", | 474 | IWL_DEBUG_EEPROM(bus, "OTP blocks %d addr 0x%x\n", |
475 | usedblocks, next_link_addr); | 475 | usedblocks, next_link_addr); |
476 | if (iwl_read_otp_word(priv, next_link_addr, &link_value)) | 476 | if (iwl_read_otp_word(bus, next_link_addr, &link_value)) |
477 | return -EINVAL; | 477 | return -EINVAL; |
478 | if (!link_value) { | 478 | if (!link_value) { |
479 | /* | 479 | /* |
@@ -488,10 +488,10 @@ static int iwl_find_otp_image(struct iwl_priv *priv, | |||
488 | } | 488 | } |
489 | /* more in the link list, continue */ | 489 | /* more in the link list, continue */ |
490 | usedblocks++; | 490 | usedblocks++; |
491 | } while (usedblocks <= priv->cfg->base_params->max_ll_items); | 491 | } while (usedblocks <= priv(bus)->cfg->base_params->max_ll_items); |
492 | 492 | ||
493 | /* OTP has no valid blocks */ | 493 | /* OTP has no valid blocks */ |
494 | IWL_DEBUG_EEPROM(priv, "OTP has no valid blocks\n"); | 494 | IWL_DEBUG_EEPROM(bus, "OTP has no valid blocks\n"); |
495 | return -EINVAL; | 495 | return -EINVAL; |
496 | } | 496 | } |
497 | 497 | ||
@@ -504,28 +504,28 @@ static int iwl_find_otp_image(struct iwl_priv *priv, | |||
504 | * iwl_get_max_txpower_avg - get the highest tx power from all chains. | 504 | * iwl_get_max_txpower_avg - get the highest tx power from all chains. |
505 | * find the highest tx power from all chains for the channel | 505 | * find the highest tx power from all chains for the channel |
506 | */ | 506 | */ |
507 | static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, | 507 | static s8 iwl_get_max_txpower_avg(struct iwl_cfg *cfg, |
508 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, | 508 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, |
509 | int element, s8 *max_txpower_in_half_dbm) | 509 | int element, s8 *max_txpower_in_half_dbm) |
510 | { | 510 | { |
511 | s8 max_txpower_avg = 0; /* (dBm) */ | 511 | s8 max_txpower_avg = 0; /* (dBm) */ |
512 | 512 | ||
513 | /* Take the highest tx power from any valid chains */ | 513 | /* Take the highest tx power from any valid chains */ |
514 | if ((priv->cfg->valid_tx_ant & ANT_A) && | 514 | if ((cfg->valid_tx_ant & ANT_A) && |
515 | (enhanced_txpower[element].chain_a_max > max_txpower_avg)) | 515 | (enhanced_txpower[element].chain_a_max > max_txpower_avg)) |
516 | max_txpower_avg = enhanced_txpower[element].chain_a_max; | 516 | max_txpower_avg = enhanced_txpower[element].chain_a_max; |
517 | if ((priv->cfg->valid_tx_ant & ANT_B) && | 517 | if ((cfg->valid_tx_ant & ANT_B) && |
518 | (enhanced_txpower[element].chain_b_max > max_txpower_avg)) | 518 | (enhanced_txpower[element].chain_b_max > max_txpower_avg)) |
519 | max_txpower_avg = enhanced_txpower[element].chain_b_max; | 519 | max_txpower_avg = enhanced_txpower[element].chain_b_max; |
520 | if ((priv->cfg->valid_tx_ant & ANT_C) && | 520 | if ((cfg->valid_tx_ant & ANT_C) && |
521 | (enhanced_txpower[element].chain_c_max > max_txpower_avg)) | 521 | (enhanced_txpower[element].chain_c_max > max_txpower_avg)) |
522 | max_txpower_avg = enhanced_txpower[element].chain_c_max; | 522 | max_txpower_avg = enhanced_txpower[element].chain_c_max; |
523 | if (((priv->cfg->valid_tx_ant == ANT_AB) | | 523 | if (((cfg->valid_tx_ant == ANT_AB) | |
524 | (priv->cfg->valid_tx_ant == ANT_BC) | | 524 | (cfg->valid_tx_ant == ANT_BC) | |
525 | (priv->cfg->valid_tx_ant == ANT_AC)) && | 525 | (cfg->valid_tx_ant == ANT_AC)) && |
526 | (enhanced_txpower[element].mimo2_max > max_txpower_avg)) | 526 | (enhanced_txpower[element].mimo2_max > max_txpower_avg)) |
527 | max_txpower_avg = enhanced_txpower[element].mimo2_max; | 527 | max_txpower_avg = enhanced_txpower[element].mimo2_max; |
528 | if ((priv->cfg->valid_tx_ant == ANT_ABC) && | 528 | if ((cfg->valid_tx_ant == ANT_ABC) && |
529 | (enhanced_txpower[element].mimo3_max > max_txpower_avg)) | 529 | (enhanced_txpower[element].mimo3_max > max_txpower_avg)) |
530 | max_txpower_avg = enhanced_txpower[element].mimo3_max; | 530 | max_txpower_avg = enhanced_txpower[element].mimo3_max; |
531 | 531 | ||
@@ -627,7 +627,7 @@ void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) | |||
627 | ((txp->delta_20_in_40 & 0xf0) >> 4), | 627 | ((txp->delta_20_in_40 & 0xf0) >> 4), |
628 | (txp->delta_20_in_40 & 0x0f)); | 628 | (txp->delta_20_in_40 & 0x0f)); |
629 | 629 | ||
630 | max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, | 630 | max_txp_avg = iwl_get_max_txpower_avg(priv->cfg, txp_array, idx, |
631 | &max_txp_avg_halfdbm); | 631 | &max_txp_avg_halfdbm); |
632 | 632 | ||
633 | /* | 633 | /* |
@@ -660,8 +660,8 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
660 | u16 validblockaddr = 0; | 660 | u16 validblockaddr = 0; |
661 | u16 cache_addr = 0; | 661 | u16 cache_addr = 0; |
662 | 662 | ||
663 | priv->nvm_device_type = iwl_get_nvm_type(priv, hw_rev); | 663 | trans(priv)->nvm_device_type = iwl_get_nvm_type(bus(priv), hw_rev); |
664 | if (priv->nvm_device_type == -ENOENT) | 664 | if (trans(priv)->nvm_device_type == -ENOENT) |
665 | return -ENOENT; | 665 | return -ENOENT; |
666 | /* allocate eeprom */ | 666 | /* allocate eeprom */ |
667 | sz = priv->cfg->base_params->eeprom_size; | 667 | sz = priv->cfg->base_params->eeprom_size; |
@@ -675,7 +675,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
675 | 675 | ||
676 | iwl_apm_init(priv); | 676 | iwl_apm_init(priv); |
677 | 677 | ||
678 | ret = iwl_eeprom_verify_signature(priv); | 678 | ret = iwl_eeprom_verify_signature(trans(priv)); |
679 | if (ret < 0) { | 679 | if (ret < 0) { |
680 | IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); | 680 | IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); |
681 | ret = -ENOENT; | 681 | ret = -ENOENT; |
@@ -683,16 +683,16 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
683 | } | 683 | } |
684 | 684 | ||
685 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | 685 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ |
686 | ret = iwl_eeprom_acquire_semaphore(priv); | 686 | ret = iwl_eeprom_acquire_semaphore(bus(priv)); |
687 | if (ret < 0) { | 687 | if (ret < 0) { |
688 | IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); | 688 | IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); |
689 | ret = -ENOENT; | 689 | ret = -ENOENT; |
690 | goto err; | 690 | goto err; |
691 | } | 691 | } |
692 | 692 | ||
693 | if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { | 693 | if (trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP) { |
694 | 694 | ||
695 | ret = iwl_init_otp_access(priv); | 695 | ret = iwl_init_otp_access(bus(priv)); |
696 | if (ret) { | 696 | if (ret) { |
697 | IWL_ERR(priv, "Failed to initialize OTP access.\n"); | 697 | IWL_ERR(priv, "Failed to initialize OTP access.\n"); |
698 | ret = -ENOENT; | 698 | ret = -ENOENT; |
@@ -707,7 +707,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
707 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | 707 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); |
708 | /* traversing the linked list if no shadow ram supported */ | 708 | /* traversing the linked list if no shadow ram supported */ |
709 | if (!priv->cfg->base_params->shadow_ram_support) { | 709 | if (!priv->cfg->base_params->shadow_ram_support) { |
710 | if (iwl_find_otp_image(priv, &validblockaddr)) { | 710 | if (iwl_find_otp_image(bus(priv), &validblockaddr)) { |
711 | ret = -ENOENT; | 711 | ret = -ENOENT; |
712 | goto done; | 712 | goto done; |
713 | } | 713 | } |
@@ -716,7 +716,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
716 | addr += sizeof(u16)) { | 716 | addr += sizeof(u16)) { |
717 | __le16 eeprom_data; | 717 | __le16 eeprom_data; |
718 | 718 | ||
719 | ret = iwl_read_otp_word(priv, addr, &eeprom_data); | 719 | ret = iwl_read_otp_word(bus(priv), addr, &eeprom_data); |
720 | if (ret) | 720 | if (ret) |
721 | goto done; | 721 | goto done; |
722 | e[cache_addr / 2] = eeprom_data; | 722 | e[cache_addr / 2] = eeprom_data; |
@@ -744,13 +744,13 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
744 | } | 744 | } |
745 | 745 | ||
746 | IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n", | 746 | IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n", |
747 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) | 747 | (trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP) |
748 | ? "OTP" : "EEPROM", | 748 | ? "OTP" : "EEPROM", |
749 | iwl_eeprom_query16(priv, EEPROM_VERSION)); | 749 | iwl_eeprom_query16(priv, EEPROM_VERSION)); |
750 | 750 | ||
751 | ret = 0; | 751 | ret = 0; |
752 | done: | 752 | done: |
753 | iwl_eeprom_release_semaphore(priv); | 753 | iwl_eeprom_release_semaphore(bus(priv)); |
754 | 754 | ||
755 | err: | 755 | err: |
756 | if (ret) | 756 | if (ret) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c new file mode 100644 index 000000000000..05b1f0d2f387 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c | |||
@@ -0,0 +1,1632 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ipw3945 project, as well | ||
6 | * as portions of the ieee80211 subsystem header files. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of version 2 of the GNU General Public License as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution in the | ||
22 | * file called LICENSE. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <linux/dma-mapping.h> | ||
34 | #include <linux/delay.h> | ||
35 | #include <linux/sched.h> | ||
36 | #include <linux/skbuff.h> | ||
37 | #include <linux/netdevice.h> | ||
38 | #include <linux/firmware.h> | ||
39 | #include <linux/etherdevice.h> | ||
40 | #include <linux/if_arp.h> | ||
41 | |||
42 | #include <net/mac80211.h> | ||
43 | |||
44 | #include <asm/div64.h> | ||
45 | |||
46 | #include "iwl-eeprom.h" | ||
47 | #include "iwl-dev.h" | ||
48 | #include "iwl-core.h" | ||
49 | #include "iwl-io.h" | ||
50 | #include "iwl-agn-calib.h" | ||
51 | #include "iwl-agn.h" | ||
52 | #include "iwl-shared.h" | ||
53 | #include "iwl-bus.h" | ||
54 | #include "iwl-trans.h" | ||
55 | |||
56 | /***************************************************************************** | ||
57 | * | ||
58 | * mac80211 entry point functions | ||
59 | * | ||
60 | *****************************************************************************/ | ||
61 | |||
62 | static const struct ieee80211_iface_limit iwlagn_sta_ap_limits[] = { | ||
63 | { | ||
64 | .max = 1, | ||
65 | .types = BIT(NL80211_IFTYPE_STATION), | ||
66 | }, | ||
67 | { | ||
68 | .max = 1, | ||
69 | .types = BIT(NL80211_IFTYPE_AP), | ||
70 | }, | ||
71 | }; | ||
72 | |||
73 | static const struct ieee80211_iface_limit iwlagn_2sta_limits[] = { | ||
74 | { | ||
75 | .max = 2, | ||
76 | .types = BIT(NL80211_IFTYPE_STATION), | ||
77 | }, | ||
78 | }; | ||
79 | |||
80 | static const struct ieee80211_iface_limit iwlagn_p2p_sta_go_limits[] = { | ||
81 | { | ||
82 | .max = 1, | ||
83 | .types = BIT(NL80211_IFTYPE_STATION), | ||
84 | }, | ||
85 | { | ||
86 | .max = 1, | ||
87 | .types = BIT(NL80211_IFTYPE_P2P_GO) | | ||
88 | BIT(NL80211_IFTYPE_AP), | ||
89 | }, | ||
90 | }; | ||
91 | |||
92 | static const struct ieee80211_iface_limit iwlagn_p2p_2sta_limits[] = { | ||
93 | { | ||
94 | .max = 2, | ||
95 | .types = BIT(NL80211_IFTYPE_STATION), | ||
96 | }, | ||
97 | { | ||
98 | .max = 1, | ||
99 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT), | ||
100 | }, | ||
101 | }; | ||
102 | |||
103 | static const struct ieee80211_iface_combination | ||
104 | iwlagn_iface_combinations_dualmode[] = { | ||
105 | { .num_different_channels = 1, | ||
106 | .max_interfaces = 2, | ||
107 | .beacon_int_infra_match = true, | ||
108 | .limits = iwlagn_sta_ap_limits, | ||
109 | .n_limits = ARRAY_SIZE(iwlagn_sta_ap_limits), | ||
110 | }, | ||
111 | { .num_different_channels = 1, | ||
112 | .max_interfaces = 2, | ||
113 | .limits = iwlagn_2sta_limits, | ||
114 | .n_limits = ARRAY_SIZE(iwlagn_2sta_limits), | ||
115 | }, | ||
116 | }; | ||
117 | |||
118 | static const struct ieee80211_iface_combination | ||
119 | iwlagn_iface_combinations_p2p[] = { | ||
120 | { .num_different_channels = 1, | ||
121 | .max_interfaces = 2, | ||
122 | .beacon_int_infra_match = true, | ||
123 | .limits = iwlagn_p2p_sta_go_limits, | ||
124 | .n_limits = ARRAY_SIZE(iwlagn_p2p_sta_go_limits), | ||
125 | }, | ||
126 | { .num_different_channels = 1, | ||
127 | .max_interfaces = 2, | ||
128 | .limits = iwlagn_p2p_2sta_limits, | ||
129 | .n_limits = ARRAY_SIZE(iwlagn_p2p_2sta_limits), | ||
130 | }, | ||
131 | }; | ||
132 | |||
133 | /* | ||
134 | * Not a mac80211 entry point function, but it fits in with all the | ||
135 | * other mac80211 functions grouped here. | ||
136 | */ | ||
137 | int iwlagn_mac_setup_register(struct iwl_priv *priv, | ||
138 | struct iwlagn_ucode_capabilities *capa) | ||
139 | { | ||
140 | int ret; | ||
141 | struct ieee80211_hw *hw = priv->hw; | ||
142 | struct iwl_rxon_context *ctx; | ||
143 | |||
144 | hw->rate_control_algorithm = "iwl-agn-rs"; | ||
145 | |||
146 | /* Tell mac80211 our characteristics */ | ||
147 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | ||
148 | IEEE80211_HW_AMPDU_AGGREGATION | | ||
149 | IEEE80211_HW_NEED_DTIM_PERIOD | | ||
150 | IEEE80211_HW_SPECTRUM_MGMT | | ||
151 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; | ||
152 | |||
153 | /* | ||
154 | * Including the following line will crash some AP's. This | ||
155 | * workaround removes the stimulus which causes the crash until | ||
156 | * the AP software can be fixed. | ||
157 | hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
158 | */ | ||
159 | |||
160 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | ||
161 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | ||
162 | |||
163 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) | ||
164 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | ||
165 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | ||
166 | |||
167 | if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) | ||
168 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | ||
169 | |||
170 | hw->sta_data_size = sizeof(struct iwl_station_priv); | ||
171 | hw->vif_data_size = sizeof(struct iwl_vif_priv); | ||
172 | |||
173 | for_each_context(priv, ctx) { | ||
174 | hw->wiphy->interface_modes |= ctx->interface_modes; | ||
175 | hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; | ||
176 | } | ||
177 | |||
178 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | ||
179 | |||
180 | if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) { | ||
181 | hw->wiphy->iface_combinations = iwlagn_iface_combinations_p2p; | ||
182 | hw->wiphy->n_iface_combinations = | ||
183 | ARRAY_SIZE(iwlagn_iface_combinations_p2p); | ||
184 | } else if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { | ||
185 | hw->wiphy->iface_combinations = | ||
186 | iwlagn_iface_combinations_dualmode; | ||
187 | hw->wiphy->n_iface_combinations = | ||
188 | ARRAY_SIZE(iwlagn_iface_combinations_dualmode); | ||
189 | } | ||
190 | |||
191 | hw->wiphy->max_remain_on_channel_duration = 1000; | ||
192 | |||
193 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | | ||
194 | WIPHY_FLAG_DISABLE_BEACON_HINTS | | ||
195 | WIPHY_FLAG_IBSS_RSN; | ||
196 | |||
197 | if (trans(priv)->ucode_wowlan.code.len && | ||
198 | device_can_wakeup(bus(priv)->dev)) { | ||
199 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | | ||
200 | WIPHY_WOWLAN_DISCONNECT | | ||
201 | WIPHY_WOWLAN_EAP_IDENTITY_REQ | | ||
202 | WIPHY_WOWLAN_RFKILL_RELEASE; | ||
203 | if (!iwlagn_mod_params.sw_crypto) | ||
204 | hw->wiphy->wowlan.flags |= | ||
205 | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | | ||
206 | WIPHY_WOWLAN_GTK_REKEY_FAILURE; | ||
207 | |||
208 | hw->wiphy->wowlan.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS; | ||
209 | hw->wiphy->wowlan.pattern_min_len = | ||
210 | IWLAGN_WOWLAN_MIN_PATTERN_LEN; | ||
211 | hw->wiphy->wowlan.pattern_max_len = | ||
212 | IWLAGN_WOWLAN_MAX_PATTERN_LEN; | ||
213 | } | ||
214 | |||
215 | if (iwlagn_mod_params.power_save) | ||
216 | hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
217 | else | ||
218 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
219 | |||
220 | hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; | ||
221 | /* we create the 802.11 header and a zero-length SSID element */ | ||
222 | hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 2; | ||
223 | |||
224 | /* Default value; 4 EDCA QOS priorities */ | ||
225 | hw->queues = 4; | ||
226 | |||
227 | hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; | ||
228 | |||
229 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
230 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
231 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
232 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
233 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
234 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
235 | |||
236 | iwl_leds_init(priv); | ||
237 | |||
238 | ret = ieee80211_register_hw(priv->hw); | ||
239 | if (ret) { | ||
240 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); | ||
241 | return ret; | ||
242 | } | ||
243 | priv->mac80211_registered = 1; | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static int __iwl_up(struct iwl_priv *priv) | ||
249 | { | ||
250 | struct iwl_rxon_context *ctx; | ||
251 | int ret; | ||
252 | |||
253 | lockdep_assert_held(&priv->shrd->mutex); | ||
254 | |||
255 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | ||
256 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); | ||
257 | return -EIO; | ||
258 | } | ||
259 | |||
260 | for_each_context(priv, ctx) { | ||
261 | ret = iwlagn_alloc_bcast_station(priv, ctx); | ||
262 | if (ret) { | ||
263 | iwl_dealloc_bcast_stations(priv); | ||
264 | return ret; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | ret = iwlagn_run_init_ucode(priv); | ||
269 | if (ret) { | ||
270 | IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); | ||
271 | goto error; | ||
272 | } | ||
273 | |||
274 | ret = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); | ||
275 | if (ret) { | ||
276 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); | ||
277 | goto error; | ||
278 | } | ||
279 | |||
280 | ret = iwl_alive_start(priv); | ||
281 | if (ret) | ||
282 | goto error; | ||
283 | return 0; | ||
284 | |||
285 | error: | ||
286 | set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | ||
287 | __iwl_down(priv); | ||
288 | clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | ||
289 | |||
290 | IWL_ERR(priv, "Unable to initialize device.\n"); | ||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | static int iwlagn_mac_start(struct ieee80211_hw *hw) | ||
295 | { | ||
296 | struct iwl_priv *priv = hw->priv; | ||
297 | int ret; | ||
298 | |||
299 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
300 | |||
301 | /* we should be verifying the device is ready to be opened */ | ||
302 | mutex_lock(&priv->shrd->mutex); | ||
303 | ret = __iwl_up(priv); | ||
304 | mutex_unlock(&priv->shrd->mutex); | ||
305 | if (ret) | ||
306 | return ret; | ||
307 | |||
308 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); | ||
309 | |||
310 | /* Now we should be done, and the READY bit should be set. */ | ||
311 | if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status))) | ||
312 | ret = -EIO; | ||
313 | |||
314 | iwlagn_led_enable(priv); | ||
315 | |||
316 | priv->is_open = 1; | ||
317 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static void iwlagn_mac_stop(struct ieee80211_hw *hw) | ||
322 | { | ||
323 | struct iwl_priv *priv = hw->priv; | ||
324 | |||
325 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
326 | |||
327 | if (!priv->is_open) | ||
328 | return; | ||
329 | |||
330 | priv->is_open = 0; | ||
331 | |||
332 | iwl_down(priv); | ||
333 | |||
334 | flush_workqueue(priv->shrd->workqueue); | ||
335 | |||
336 | /* User space software may expect getting rfkill changes | ||
337 | * even if interface is down */ | ||
338 | iwl_write32(bus(priv), CSR_INT, 0xFFFFFFFF); | ||
339 | iwl_enable_rfkill_int(priv); | ||
340 | |||
341 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
342 | } | ||
343 | |||
344 | static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | ||
345 | struct ieee80211_vif *vif, | ||
346 | struct cfg80211_gtk_rekey_data *data) | ||
347 | { | ||
348 | struct iwl_priv *priv = hw->priv; | ||
349 | |||
350 | if (iwlagn_mod_params.sw_crypto) | ||
351 | return; | ||
352 | |||
353 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
354 | mutex_lock(&priv->shrd->mutex); | ||
355 | |||
356 | if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif) | ||
357 | goto out; | ||
358 | |||
359 | memcpy(priv->kek, data->kek, NL80211_KEK_LEN); | ||
360 | memcpy(priv->kck, data->kck, NL80211_KCK_LEN); | ||
361 | priv->replay_ctr = | ||
362 | cpu_to_le64(be64_to_cpup((__be64 *)&data->replay_ctr)); | ||
363 | priv->have_rekey_data = true; | ||
364 | |||
365 | out: | ||
366 | mutex_unlock(&priv->shrd->mutex); | ||
367 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
368 | } | ||
369 | |||
370 | #ifdef CONFIG_PM_SLEEP | ||
371 | |||
372 | static int iwlagn_mac_suspend(struct ieee80211_hw *hw, | ||
373 | struct cfg80211_wowlan *wowlan) | ||
374 | { | ||
375 | struct iwl_priv *priv = hw->priv; | ||
376 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
377 | int ret; | ||
378 | |||
379 | if (WARN_ON(!wowlan)) | ||
380 | return -EINVAL; | ||
381 | |||
382 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
383 | mutex_lock(&priv->shrd->mutex); | ||
384 | |||
385 | /* Don't attempt WoWLAN when not associated, tear down instead. */ | ||
386 | if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION || | ||
387 | !iwl_is_associated_ctx(ctx)) { | ||
388 | ret = 1; | ||
389 | goto out; | ||
390 | } | ||
391 | |||
392 | ret = iwlagn_suspend(priv, hw, wowlan); | ||
393 | if (ret) | ||
394 | goto error; | ||
395 | |||
396 | device_set_wakeup_enable(bus(priv)->dev, true); | ||
397 | |||
398 | /* Now let the ucode operate on its own */ | ||
399 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, | ||
400 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
401 | |||
402 | goto out; | ||
403 | |||
404 | error: | ||
405 | priv->shrd->wowlan = false; | ||
406 | iwlagn_prepare_restart(priv); | ||
407 | ieee80211_restart_hw(priv->hw); | ||
408 | out: | ||
409 | mutex_unlock(&priv->shrd->mutex); | ||
410 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
411 | |||
412 | return ret; | ||
413 | } | ||
414 | |||
415 | static int iwlagn_mac_resume(struct ieee80211_hw *hw) | ||
416 | { | ||
417 | struct iwl_priv *priv = hw->priv; | ||
418 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
419 | struct ieee80211_vif *vif; | ||
420 | unsigned long flags; | ||
421 | u32 base, status = 0xffffffff; | ||
422 | int ret = -EIO; | ||
423 | |||
424 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
425 | mutex_lock(&priv->shrd->mutex); | ||
426 | |||
427 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, | ||
428 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
429 | |||
430 | base = priv->device_pointers.error_event_table; | ||
431 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | ||
432 | spin_lock_irqsave(&bus(priv)->reg_lock, flags); | ||
433 | ret = iwl_grab_nic_access_silent(bus(priv)); | ||
434 | if (ret == 0) { | ||
435 | iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, base); | ||
436 | status = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | ||
437 | iwl_release_nic_access(bus(priv)); | ||
438 | } | ||
439 | spin_unlock_irqrestore(&bus(priv)->reg_lock, flags); | ||
440 | |||
441 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
442 | if (ret == 0) { | ||
443 | struct iwl_trans *trans = trans(priv); | ||
444 | if (!priv->wowlan_sram) | ||
445 | priv->wowlan_sram = | ||
446 | kzalloc(trans->ucode_wowlan.data.len, | ||
447 | GFP_KERNEL); | ||
448 | |||
449 | if (priv->wowlan_sram) | ||
450 | _iwl_read_targ_mem_words( | ||
451 | bus(priv), 0x800000, priv->wowlan_sram, | ||
452 | trans->ucode_wowlan.data.len / 4); | ||
453 | } | ||
454 | #endif | ||
455 | } | ||
456 | |||
457 | /* we'll clear ctx->vif during iwlagn_prepare_restart() */ | ||
458 | vif = ctx->vif; | ||
459 | |||
460 | priv->shrd->wowlan = false; | ||
461 | |||
462 | device_set_wakeup_enable(bus(priv)->dev, false); | ||
463 | |||
464 | iwlagn_prepare_restart(priv); | ||
465 | |||
466 | memset((void *)&ctx->active, 0, sizeof(ctx->active)); | ||
467 | iwl_connection_init_rx_config(priv, ctx); | ||
468 | iwlagn_set_rxon_chain(priv, ctx); | ||
469 | |||
470 | mutex_unlock(&priv->shrd->mutex); | ||
471 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
472 | |||
473 | ieee80211_resume_disconnect(vif); | ||
474 | |||
475 | return 1; | ||
476 | } | ||
477 | |||
478 | #endif | ||
479 | |||
480 | static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
481 | { | ||
482 | struct iwl_priv *priv = hw->priv; | ||
483 | |||
484 | IWL_DEBUG_MACDUMP(priv, "enter\n"); | ||
485 | |||
486 | IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | ||
487 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); | ||
488 | |||
489 | if (iwlagn_tx_skb(priv, skb)) | ||
490 | dev_kfree_skb_any(skb); | ||
491 | |||
492 | IWL_DEBUG_MACDUMP(priv, "leave\n"); | ||
493 | } | ||
494 | |||
495 | static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | ||
496 | struct ieee80211_vif *vif, | ||
497 | struct ieee80211_key_conf *keyconf, | ||
498 | struct ieee80211_sta *sta, | ||
499 | u32 iv32, u16 *phase1key) | ||
500 | { | ||
501 | struct iwl_priv *priv = hw->priv; | ||
502 | |||
503 | iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); | ||
504 | } | ||
505 | |||
506 | static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | ||
507 | struct ieee80211_vif *vif, | ||
508 | struct ieee80211_sta *sta, | ||
509 | struct ieee80211_key_conf *key) | ||
510 | { | ||
511 | struct iwl_priv *priv = hw->priv; | ||
512 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
513 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
514 | int ret; | ||
515 | bool is_default_wep_key = false; | ||
516 | |||
517 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
518 | |||
519 | if (iwlagn_mod_params.sw_crypto) { | ||
520 | IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); | ||
521 | return -EOPNOTSUPP; | ||
522 | } | ||
523 | |||
524 | /* | ||
525 | * We could program these keys into the hardware as well, but we | ||
526 | * don't expect much multicast traffic in IBSS and having keys | ||
527 | * for more stations is probably more useful. | ||
528 | * | ||
529 | * Mark key TX-only and return 0. | ||
530 | */ | ||
531 | if (vif->type == NL80211_IFTYPE_ADHOC && | ||
532 | !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | ||
533 | key->hw_key_idx = WEP_INVALID_OFFSET; | ||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | /* If they key was TX-only, accept deletion */ | ||
538 | if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET) | ||
539 | return 0; | ||
540 | |||
541 | mutex_lock(&priv->shrd->mutex); | ||
542 | iwl_scan_cancel_timeout(priv, 100); | ||
543 | |||
544 | BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT); | ||
545 | |||
546 | /* | ||
547 | * If we are getting WEP group key and we didn't receive any key mapping | ||
548 | * so far, we are in legacy wep mode (group key only), otherwise we are | ||
549 | * in 1X mode. | ||
550 | * In legacy wep mode, we use another host command to the uCode. | ||
551 | */ | ||
552 | if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || | ||
553 | key->cipher == WLAN_CIPHER_SUITE_WEP104) && !sta) { | ||
554 | if (cmd == SET_KEY) | ||
555 | is_default_wep_key = !ctx->key_mapping_keys; | ||
556 | else | ||
557 | is_default_wep_key = | ||
558 | key->hw_key_idx == IWLAGN_HW_KEY_DEFAULT; | ||
559 | } | ||
560 | |||
561 | |||
562 | switch (cmd) { | ||
563 | case SET_KEY: | ||
564 | if (is_default_wep_key) { | ||
565 | ret = iwl_set_default_wep_key(priv, vif_priv->ctx, key); | ||
566 | break; | ||
567 | } | ||
568 | ret = iwl_set_dynamic_key(priv, vif_priv->ctx, key, sta); | ||
569 | if (ret) { | ||
570 | /* | ||
571 | * can't add key for RX, but we don't need it | ||
572 | * in the device for TX so still return 0 | ||
573 | */ | ||
574 | ret = 0; | ||
575 | key->hw_key_idx = WEP_INVALID_OFFSET; | ||
576 | } | ||
577 | |||
578 | IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n"); | ||
579 | break; | ||
580 | case DISABLE_KEY: | ||
581 | if (is_default_wep_key) | ||
582 | ret = iwl_remove_default_wep_key(priv, ctx, key); | ||
583 | else | ||
584 | ret = iwl_remove_dynamic_key(priv, ctx, key, sta); | ||
585 | |||
586 | IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n"); | ||
587 | break; | ||
588 | default: | ||
589 | ret = -EINVAL; | ||
590 | } | ||
591 | |||
592 | mutex_unlock(&priv->shrd->mutex); | ||
593 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
594 | |||
595 | return ret; | ||
596 | } | ||
597 | |||
598 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | ||
599 | struct ieee80211_vif *vif, | ||
600 | enum ieee80211_ampdu_mlme_action action, | ||
601 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, | ||
602 | u8 buf_size) | ||
603 | { | ||
604 | struct iwl_priv *priv = hw->priv; | ||
605 | int ret = -EINVAL; | ||
606 | struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; | ||
607 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
608 | |||
609 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", | ||
610 | sta->addr, tid); | ||
611 | |||
612 | if (!(priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)) | ||
613 | return -EACCES; | ||
614 | |||
615 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
616 | mutex_lock(&priv->shrd->mutex); | ||
617 | |||
618 | switch (action) { | ||
619 | case IEEE80211_AMPDU_RX_START: | ||
620 | IWL_DEBUG_HT(priv, "start Rx\n"); | ||
621 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); | ||
622 | break; | ||
623 | case IEEE80211_AMPDU_RX_STOP: | ||
624 | IWL_DEBUG_HT(priv, "stop Rx\n"); | ||
625 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); | ||
626 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
627 | ret = 0; | ||
628 | break; | ||
629 | case IEEE80211_AMPDU_TX_START: | ||
630 | IWL_DEBUG_HT(priv, "start Tx\n"); | ||
631 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); | ||
632 | break; | ||
633 | case IEEE80211_AMPDU_TX_STOP: | ||
634 | IWL_DEBUG_HT(priv, "stop Tx\n"); | ||
635 | ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); | ||
636 | if ((ret == 0) && (priv->agg_tids_count > 0)) { | ||
637 | priv->agg_tids_count--; | ||
638 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | ||
639 | priv->agg_tids_count); | ||
640 | } | ||
641 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
642 | ret = 0; | ||
643 | if (!priv->agg_tids_count && priv->cfg->ht_params && | ||
644 | priv->cfg->ht_params->use_rts_for_aggregation) { | ||
645 | /* | ||
646 | * switch off RTS/CTS if it was previously enabled | ||
647 | */ | ||
648 | sta_priv->lq_sta.lq.general_params.flags &= | ||
649 | ~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; | ||
650 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | ||
651 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
652 | } | ||
653 | break; | ||
654 | case IEEE80211_AMPDU_TX_OPERATIONAL: | ||
655 | buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); | ||
656 | |||
657 | iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, iwl_sta_id(sta), | ||
658 | tid, buf_size); | ||
659 | |||
660 | /* | ||
661 | * If the limit is 0, then it wasn't initialised yet, | ||
662 | * use the default. We can do that since we take the | ||
663 | * minimum below, and we don't want to go above our | ||
664 | * default due to hardware restrictions. | ||
665 | */ | ||
666 | if (sta_priv->max_agg_bufsize == 0) | ||
667 | sta_priv->max_agg_bufsize = | ||
668 | LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
669 | |||
670 | /* | ||
671 | * Even though in theory the peer could have different | ||
672 | * aggregation reorder buffer sizes for different sessions, | ||
673 | * our ucode doesn't allow for that and has a global limit | ||
674 | * for each station. Therefore, use the minimum of all the | ||
675 | * aggregation sessions and our default value. | ||
676 | */ | ||
677 | sta_priv->max_agg_bufsize = | ||
678 | min(sta_priv->max_agg_bufsize, buf_size); | ||
679 | |||
680 | if (priv->cfg->ht_params && | ||
681 | priv->cfg->ht_params->use_rts_for_aggregation) { | ||
682 | /* | ||
683 | * switch to RTS/CTS if it is the prefer protection | ||
684 | * method for HT traffic | ||
685 | */ | ||
686 | |||
687 | sta_priv->lq_sta.lq.general_params.flags |= | ||
688 | LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; | ||
689 | } | ||
690 | priv->agg_tids_count++; | ||
691 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | ||
692 | priv->agg_tids_count); | ||
693 | |||
694 | sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit = | ||
695 | sta_priv->max_agg_bufsize; | ||
696 | |||
697 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | ||
698 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
699 | |||
700 | IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n", | ||
701 | sta->addr, tid); | ||
702 | ret = 0; | ||
703 | break; | ||
704 | } | ||
705 | mutex_unlock(&priv->shrd->mutex); | ||
706 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
707 | return ret; | ||
708 | } | ||
709 | |||
710 | static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | ||
711 | struct ieee80211_vif *vif, | ||
712 | struct ieee80211_sta *sta) | ||
713 | { | ||
714 | struct iwl_priv *priv = hw->priv; | ||
715 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
716 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
717 | bool is_ap = vif->type == NL80211_IFTYPE_STATION; | ||
718 | int ret = 0; | ||
719 | u8 sta_id; | ||
720 | |||
721 | IWL_DEBUG_MAC80211(priv, "received request to add station %pM\n", | ||
722 | sta->addr); | ||
723 | mutex_lock(&priv->shrd->mutex); | ||
724 | IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", | ||
725 | sta->addr); | ||
726 | sta_priv->sta_id = IWL_INVALID_STATION; | ||
727 | |||
728 | atomic_set(&sta_priv->pending_frames, 0); | ||
729 | if (vif->type == NL80211_IFTYPE_AP) | ||
730 | sta_priv->client = true; | ||
731 | |||
732 | ret = iwl_add_station_common(priv, vif_priv->ctx, sta->addr, | ||
733 | is_ap, sta, &sta_id); | ||
734 | if (ret) { | ||
735 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", | ||
736 | sta->addr, ret); | ||
737 | /* Should we return success if return code is EEXIST ? */ | ||
738 | goto out; | ||
739 | } | ||
740 | |||
741 | sta_priv->sta_id = sta_id; | ||
742 | |||
743 | /* Initialize rate scaling */ | ||
744 | IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", | ||
745 | sta->addr); | ||
746 | iwl_rs_rate_init(priv, sta, sta_id); | ||
747 | out: | ||
748 | mutex_unlock(&priv->shrd->mutex); | ||
749 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
750 | |||
751 | return ret; | ||
752 | } | ||
753 | |||
754 | static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | ||
755 | struct ieee80211_channel_switch *ch_switch) | ||
756 | { | ||
757 | struct iwl_priv *priv = hw->priv; | ||
758 | const struct iwl_channel_info *ch_info; | ||
759 | struct ieee80211_conf *conf = &hw->conf; | ||
760 | struct ieee80211_channel *channel = ch_switch->channel; | ||
761 | struct iwl_ht_config *ht_conf = &priv->current_ht_config; | ||
762 | /* | ||
763 | * MULTI-FIXME | ||
764 | * When we add support for multiple interfaces, we need to | ||
765 | * revisit this. The channel switch command in the device | ||
766 | * only affects the BSS context, but what does that really | ||
767 | * mean? And what if we get a CSA on the second interface? | ||
768 | * This needs a lot of work. | ||
769 | */ | ||
770 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
771 | u16 ch; | ||
772 | |||
773 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
774 | |||
775 | mutex_lock(&priv->shrd->mutex); | ||
776 | |||
777 | if (iwl_is_rfkill(priv->shrd)) | ||
778 | goto out; | ||
779 | |||
780 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || | ||
781 | test_bit(STATUS_SCANNING, &priv->shrd->status) || | ||
782 | test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) | ||
783 | goto out; | ||
784 | |||
785 | if (!iwl_is_associated_ctx(ctx)) | ||
786 | goto out; | ||
787 | |||
788 | if (!priv->cfg->lib->set_channel_switch) | ||
789 | goto out; | ||
790 | |||
791 | ch = channel->hw_value; | ||
792 | if (le16_to_cpu(ctx->active.channel) == ch) | ||
793 | goto out; | ||
794 | |||
795 | ch_info = iwl_get_channel_info(priv, channel->band, ch); | ||
796 | if (!is_channel_valid(ch_info)) { | ||
797 | IWL_DEBUG_MAC80211(priv, "invalid channel\n"); | ||
798 | goto out; | ||
799 | } | ||
800 | |||
801 | spin_lock_irq(&priv->shrd->lock); | ||
802 | |||
803 | priv->current_ht_config.smps = conf->smps_mode; | ||
804 | |||
805 | /* Configure HT40 channels */ | ||
806 | ctx->ht.enabled = conf_is_ht(conf); | ||
807 | if (ctx->ht.enabled) { | ||
808 | if (conf_is_ht40_minus(conf)) { | ||
809 | ctx->ht.extension_chan_offset = | ||
810 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
811 | ctx->ht.is_40mhz = true; | ||
812 | } else if (conf_is_ht40_plus(conf)) { | ||
813 | ctx->ht.extension_chan_offset = | ||
814 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
815 | ctx->ht.is_40mhz = true; | ||
816 | } else { | ||
817 | ctx->ht.extension_chan_offset = | ||
818 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
819 | ctx->ht.is_40mhz = false; | ||
820 | } | ||
821 | } else | ||
822 | ctx->ht.is_40mhz = false; | ||
823 | |||
824 | if ((le16_to_cpu(ctx->staging.channel) != ch)) | ||
825 | ctx->staging.flags = 0; | ||
826 | |||
827 | iwl_set_rxon_channel(priv, channel, ctx); | ||
828 | iwl_set_rxon_ht(priv, ht_conf); | ||
829 | iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); | ||
830 | |||
831 | spin_unlock_irq(&priv->shrd->lock); | ||
832 | |||
833 | iwl_set_rate(priv); | ||
834 | /* | ||
835 | * at this point, staging_rxon has the | ||
836 | * configuration for channel switch | ||
837 | */ | ||
838 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | ||
839 | priv->switch_channel = cpu_to_le16(ch); | ||
840 | if (priv->cfg->lib->set_channel_switch(priv, ch_switch)) { | ||
841 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | ||
842 | priv->switch_channel = 0; | ||
843 | ieee80211_chswitch_done(ctx->vif, false); | ||
844 | } | ||
845 | |||
846 | out: | ||
847 | mutex_unlock(&priv->shrd->mutex); | ||
848 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
849 | } | ||
850 | |||
851 | static void iwlagn_configure_filter(struct ieee80211_hw *hw, | ||
852 | unsigned int changed_flags, | ||
853 | unsigned int *total_flags, | ||
854 | u64 multicast) | ||
855 | { | ||
856 | struct iwl_priv *priv = hw->priv; | ||
857 | __le32 filter_or = 0, filter_nand = 0; | ||
858 | struct iwl_rxon_context *ctx; | ||
859 | |||
860 | #define CHK(test, flag) do { \ | ||
861 | if (*total_flags & (test)) \ | ||
862 | filter_or |= (flag); \ | ||
863 | else \ | ||
864 | filter_nand |= (flag); \ | ||
865 | } while (0) | ||
866 | |||
867 | IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", | ||
868 | changed_flags, *total_flags); | ||
869 | |||
870 | CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); | ||
871 | /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */ | ||
872 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK); | ||
873 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); | ||
874 | |||
875 | #undef CHK | ||
876 | |||
877 | mutex_lock(&priv->shrd->mutex); | ||
878 | |||
879 | for_each_context(priv, ctx) { | ||
880 | ctx->staging.filter_flags &= ~filter_nand; | ||
881 | ctx->staging.filter_flags |= filter_or; | ||
882 | |||
883 | /* | ||
884 | * Not committing directly because hardware can perform a scan, | ||
885 | * but we'll eventually commit the filter flags change anyway. | ||
886 | */ | ||
887 | } | ||
888 | |||
889 | mutex_unlock(&priv->shrd->mutex); | ||
890 | |||
891 | /* | ||
892 | * Receiving all multicast frames is always enabled by the | ||
893 | * default flags setup in iwl_connection_init_rx_config() | ||
894 | * since we currently do not support programming multicast | ||
895 | * filters into the device. | ||
896 | */ | ||
897 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | ||
898 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
899 | } | ||
900 | |||
901 | static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | ||
902 | { | ||
903 | struct iwl_priv *priv = hw->priv; | ||
904 | |||
905 | mutex_lock(&priv->shrd->mutex); | ||
906 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
907 | |||
908 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | ||
909 | IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); | ||
910 | goto done; | ||
911 | } | ||
912 | if (iwl_is_rfkill(priv->shrd)) { | ||
913 | IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n"); | ||
914 | goto done; | ||
915 | } | ||
916 | |||
917 | /* | ||
918 | * mac80211 will not push any more frames for transmit | ||
919 | * until the flush is completed | ||
920 | */ | ||
921 | if (drop) { | ||
922 | IWL_DEBUG_MAC80211(priv, "send flush command\n"); | ||
923 | if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { | ||
924 | IWL_ERR(priv, "flush request fail\n"); | ||
925 | goto done; | ||
926 | } | ||
927 | } | ||
928 | IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); | ||
929 | iwl_trans_wait_tx_queue_empty(trans(priv)); | ||
930 | done: | ||
931 | mutex_unlock(&priv->shrd->mutex); | ||
932 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
933 | } | ||
934 | |||
935 | static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | ||
936 | struct ieee80211_channel *channel, | ||
937 | enum nl80211_channel_type channel_type, | ||
938 | int duration) | ||
939 | { | ||
940 | struct iwl_priv *priv = hw->priv; | ||
941 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; | ||
942 | int err = 0; | ||
943 | |||
944 | if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | ||
945 | return -EOPNOTSUPP; | ||
946 | |||
947 | if (!(ctx->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT))) | ||
948 | return -EOPNOTSUPP; | ||
949 | |||
950 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
951 | mutex_lock(&priv->shrd->mutex); | ||
952 | |||
953 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | ||
954 | err = -EBUSY; | ||
955 | goto out; | ||
956 | } | ||
957 | |||
958 | priv->hw_roc_channel = channel; | ||
959 | priv->hw_roc_chantype = channel_type; | ||
960 | /* convert from ms to TU */ | ||
961 | priv->hw_roc_duration = DIV_ROUND_UP(1000 * duration, 1024); | ||
962 | priv->hw_roc_start_notified = false; | ||
963 | cancel_delayed_work(&priv->hw_roc_disable_work); | ||
964 | |||
965 | if (!ctx->is_active) { | ||
966 | static const struct iwl_qos_info default_qos_data = { | ||
967 | .def_qos_parm = { | ||
968 | .ac[0] = { | ||
969 | .cw_min = cpu_to_le16(3), | ||
970 | .cw_max = cpu_to_le16(7), | ||
971 | .aifsn = 2, | ||
972 | .edca_txop = cpu_to_le16(1504), | ||
973 | }, | ||
974 | .ac[1] = { | ||
975 | .cw_min = cpu_to_le16(7), | ||
976 | .cw_max = cpu_to_le16(15), | ||
977 | .aifsn = 2, | ||
978 | .edca_txop = cpu_to_le16(3008), | ||
979 | }, | ||
980 | .ac[2] = { | ||
981 | .cw_min = cpu_to_le16(15), | ||
982 | .cw_max = cpu_to_le16(1023), | ||
983 | .aifsn = 3, | ||
984 | }, | ||
985 | .ac[3] = { | ||
986 | .cw_min = cpu_to_le16(15), | ||
987 | .cw_max = cpu_to_le16(1023), | ||
988 | .aifsn = 7, | ||
989 | }, | ||
990 | }, | ||
991 | }; | ||
992 | |||
993 | ctx->is_active = true; | ||
994 | ctx->qos_data = default_qos_data; | ||
995 | ctx->staging.dev_type = RXON_DEV_TYPE_P2P; | ||
996 | memcpy(ctx->staging.node_addr, | ||
997 | priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr, | ||
998 | ETH_ALEN); | ||
999 | memcpy(ctx->staging.bssid_addr, | ||
1000 | priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr, | ||
1001 | ETH_ALEN); | ||
1002 | err = iwlagn_commit_rxon(priv, ctx); | ||
1003 | if (err) | ||
1004 | goto out; | ||
1005 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK | | ||
1006 | RXON_FILTER_PROMISC_MSK | | ||
1007 | RXON_FILTER_CTL2HOST_MSK; | ||
1008 | |||
1009 | err = iwlagn_commit_rxon(priv, ctx); | ||
1010 | if (err) { | ||
1011 | iwlagn_disable_roc(priv); | ||
1012 | goto out; | ||
1013 | } | ||
1014 | priv->hw_roc_setup = true; | ||
1015 | } | ||
1016 | |||
1017 | err = iwl_scan_initiate(priv, ctx->vif, IWL_SCAN_ROC, channel->band); | ||
1018 | if (err) | ||
1019 | iwlagn_disable_roc(priv); | ||
1020 | |||
1021 | out: | ||
1022 | mutex_unlock(&priv->shrd->mutex); | ||
1023 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1024 | |||
1025 | return err; | ||
1026 | } | ||
1027 | |||
1028 | static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | ||
1029 | { | ||
1030 | struct iwl_priv *priv = hw->priv; | ||
1031 | |||
1032 | if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | ||
1033 | return -EOPNOTSUPP; | ||
1034 | |||
1035 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1036 | mutex_lock(&priv->shrd->mutex); | ||
1037 | iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); | ||
1038 | iwlagn_disable_roc(priv); | ||
1039 | mutex_unlock(&priv->shrd->mutex); | ||
1040 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1041 | |||
1042 | return 0; | ||
1043 | } | ||
1044 | |||
1045 | static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw, | ||
1046 | struct ieee80211_vif *vif, | ||
1047 | const u8 *bssid, | ||
1048 | enum ieee80211_tx_sync_type type) | ||
1049 | { | ||
1050 | struct iwl_priv *priv = hw->priv; | ||
1051 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
1052 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
1053 | int ret; | ||
1054 | u8 sta_id; | ||
1055 | |||
1056 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1057 | mutex_lock(&priv->shrd->mutex); | ||
1058 | |||
1059 | if (iwl_is_associated_ctx(ctx)) { | ||
1060 | ret = 0; | ||
1061 | goto out; | ||
1062 | } | ||
1063 | |||
1064 | if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW, | ||
1065 | &priv->shrd->status)) { | ||
1066 | ret = -EBUSY; | ||
1067 | goto out; | ||
1068 | } | ||
1069 | |||
1070 | ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id); | ||
1071 | if (ret) | ||
1072 | goto out; | ||
1073 | |||
1074 | if (WARN_ON(sta_id != ctx->ap_sta_id)) { | ||
1075 | ret = -EIO; | ||
1076 | goto out_remove_sta; | ||
1077 | } | ||
1078 | |||
1079 | memcpy(ctx->bssid, bssid, ETH_ALEN); | ||
1080 | ctx->preauth_bssid = true; | ||
1081 | |||
1082 | ret = iwlagn_commit_rxon(priv, ctx); | ||
1083 | |||
1084 | if (ret == 0) | ||
1085 | goto out; | ||
1086 | |||
1087 | out_remove_sta: | ||
1088 | iwl_remove_station(priv, sta_id, bssid); | ||
1089 | out: | ||
1090 | mutex_unlock(&priv->shrd->mutex); | ||
1091 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1092 | |||
1093 | return ret; | ||
1094 | } | ||
1095 | |||
1096 | static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw, | ||
1097 | struct ieee80211_vif *vif, | ||
1098 | const u8 *bssid, | ||
1099 | enum ieee80211_tx_sync_type type) | ||
1100 | { | ||
1101 | struct iwl_priv *priv = hw->priv; | ||
1102 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
1103 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
1104 | |||
1105 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1106 | mutex_lock(&priv->shrd->mutex); | ||
1107 | |||
1108 | if (iwl_is_associated_ctx(ctx)) | ||
1109 | goto out; | ||
1110 | |||
1111 | iwl_remove_station(priv, ctx->ap_sta_id, bssid); | ||
1112 | ctx->preauth_bssid = false; | ||
1113 | /* no need to commit */ | ||
1114 | out: | ||
1115 | mutex_unlock(&priv->shrd->mutex); | ||
1116 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1117 | } | ||
1118 | |||
1119 | static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | ||
1120 | enum ieee80211_rssi_event rssi_event) | ||
1121 | { | ||
1122 | struct iwl_priv *priv = hw->priv; | ||
1123 | |||
1124 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1125 | mutex_lock(&priv->shrd->mutex); | ||
1126 | |||
1127 | if (priv->cfg->bt_params && | ||
1128 | priv->cfg->bt_params->advanced_bt_coexist) { | ||
1129 | if (rssi_event == RSSI_EVENT_LOW) | ||
1130 | priv->bt_enable_pspoll = true; | ||
1131 | else if (rssi_event == RSSI_EVENT_HIGH) | ||
1132 | priv->bt_enable_pspoll = false; | ||
1133 | |||
1134 | iwlagn_send_advance_bt_config(priv); | ||
1135 | } else { | ||
1136 | IWL_DEBUG_MAC80211(priv, "Advanced BT coex disabled," | ||
1137 | "ignoring RSSI callback\n"); | ||
1138 | } | ||
1139 | |||
1140 | mutex_unlock(&priv->shrd->mutex); | ||
1141 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1142 | } | ||
1143 | |||
1144 | static int iwlagn_mac_set_tim(struct ieee80211_hw *hw, | ||
1145 | struct ieee80211_sta *sta, bool set) | ||
1146 | { | ||
1147 | struct iwl_priv *priv = hw->priv; | ||
1148 | |||
1149 | queue_work(priv->shrd->workqueue, &priv->beacon_update); | ||
1150 | |||
1151 | return 0; | ||
1152 | } | ||
1153 | |||
1154 | static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | ||
1155 | struct ieee80211_vif *vif, u16 queue, | ||
1156 | const struct ieee80211_tx_queue_params *params) | ||
1157 | { | ||
1158 | struct iwl_priv *priv = hw->priv; | ||
1159 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
1160 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
1161 | unsigned long flags; | ||
1162 | int q; | ||
1163 | |||
1164 | if (WARN_ON(!ctx)) | ||
1165 | return -EINVAL; | ||
1166 | |||
1167 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1168 | |||
1169 | if (!iwl_is_ready_rf(priv->shrd)) { | ||
1170 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | ||
1171 | return -EIO; | ||
1172 | } | ||
1173 | |||
1174 | if (queue >= AC_NUM) { | ||
1175 | IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue); | ||
1176 | return 0; | ||
1177 | } | ||
1178 | |||
1179 | q = AC_NUM - 1 - queue; | ||
1180 | |||
1181 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
1182 | |||
1183 | ctx->qos_data.def_qos_parm.ac[q].cw_min = | ||
1184 | cpu_to_le16(params->cw_min); | ||
1185 | ctx->qos_data.def_qos_parm.ac[q].cw_max = | ||
1186 | cpu_to_le16(params->cw_max); | ||
1187 | ctx->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; | ||
1188 | ctx->qos_data.def_qos_parm.ac[q].edca_txop = | ||
1189 | cpu_to_le16((params->txop * 32)); | ||
1190 | |||
1191 | ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; | ||
1192 | |||
1193 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
1194 | |||
1195 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1196 | return 0; | ||
1197 | } | ||
1198 | |||
1199 | static int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) | ||
1200 | { | ||
1201 | struct iwl_priv *priv = hw->priv; | ||
1202 | |||
1203 | return priv->ibss_manager == IWL_IBSS_MANAGER; | ||
1204 | } | ||
1205 | |||
1206 | static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | ||
1207 | { | ||
1208 | iwl_connection_init_rx_config(priv, ctx); | ||
1209 | |||
1210 | iwlagn_set_rxon_chain(priv, ctx); | ||
1211 | |||
1212 | return iwlagn_commit_rxon(priv, ctx); | ||
1213 | } | ||
1214 | |||
1215 | static int iwl_setup_interface(struct iwl_priv *priv, | ||
1216 | struct iwl_rxon_context *ctx) | ||
1217 | { | ||
1218 | struct ieee80211_vif *vif = ctx->vif; | ||
1219 | int err; | ||
1220 | |||
1221 | lockdep_assert_held(&priv->shrd->mutex); | ||
1222 | |||
1223 | /* | ||
1224 | * This variable will be correct only when there's just | ||
1225 | * a single context, but all code using it is for hardware | ||
1226 | * that supports only one context. | ||
1227 | */ | ||
1228 | priv->iw_mode = vif->type; | ||
1229 | |||
1230 | ctx->is_active = true; | ||
1231 | |||
1232 | err = iwl_set_mode(priv, ctx); | ||
1233 | if (err) { | ||
1234 | if (!ctx->always_active) | ||
1235 | ctx->is_active = false; | ||
1236 | return err; | ||
1237 | } | ||
1238 | |||
1239 | if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist && | ||
1240 | vif->type == NL80211_IFTYPE_ADHOC) { | ||
1241 | /* | ||
1242 | * pretend to have high BT traffic as long as we | ||
1243 | * are operating in IBSS mode, as this will cause | ||
1244 | * the rate scaling etc. to behave as intended. | ||
1245 | */ | ||
1246 | priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH; | ||
1247 | } | ||
1248 | |||
1249 | return 0; | ||
1250 | } | ||
1251 | |||
1252 | static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | ||
1253 | struct ieee80211_vif *vif) | ||
1254 | { | ||
1255 | struct iwl_priv *priv = hw->priv; | ||
1256 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
1257 | struct iwl_rxon_context *tmp, *ctx = NULL; | ||
1258 | int err; | ||
1259 | enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif); | ||
1260 | |||
1261 | IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", | ||
1262 | viftype, vif->addr); | ||
1263 | |||
1264 | cancel_delayed_work_sync(&priv->hw_roc_disable_work); | ||
1265 | |||
1266 | mutex_lock(&priv->shrd->mutex); | ||
1267 | |||
1268 | iwlagn_disable_roc(priv); | ||
1269 | |||
1270 | if (!iwl_is_ready_rf(priv->shrd)) { | ||
1271 | IWL_WARN(priv, "Try to add interface when device not ready\n"); | ||
1272 | err = -EINVAL; | ||
1273 | goto out; | ||
1274 | } | ||
1275 | |||
1276 | for_each_context(priv, tmp) { | ||
1277 | u32 possible_modes = | ||
1278 | tmp->interface_modes | tmp->exclusive_interface_modes; | ||
1279 | |||
1280 | if (tmp->vif) { | ||
1281 | /* check if this busy context is exclusive */ | ||
1282 | if (tmp->exclusive_interface_modes & | ||
1283 | BIT(tmp->vif->type)) { | ||
1284 | err = -EINVAL; | ||
1285 | goto out; | ||
1286 | } | ||
1287 | continue; | ||
1288 | } | ||
1289 | |||
1290 | if (!(possible_modes & BIT(viftype))) | ||
1291 | continue; | ||
1292 | |||
1293 | /* have maybe usable context w/o interface */ | ||
1294 | ctx = tmp; | ||
1295 | break; | ||
1296 | } | ||
1297 | |||
1298 | if (!ctx) { | ||
1299 | err = -EOPNOTSUPP; | ||
1300 | goto out; | ||
1301 | } | ||
1302 | |||
1303 | vif_priv->ctx = ctx; | ||
1304 | ctx->vif = vif; | ||
1305 | |||
1306 | err = iwl_setup_interface(priv, ctx); | ||
1307 | if (!err) | ||
1308 | goto out; | ||
1309 | |||
1310 | ctx->vif = NULL; | ||
1311 | priv->iw_mode = NL80211_IFTYPE_STATION; | ||
1312 | out: | ||
1313 | mutex_unlock(&priv->shrd->mutex); | ||
1314 | |||
1315 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1316 | return err; | ||
1317 | } | ||
1318 | |||
1319 | static void iwl_teardown_interface(struct iwl_priv *priv, | ||
1320 | struct ieee80211_vif *vif, | ||
1321 | bool mode_change) | ||
1322 | { | ||
1323 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
1324 | |||
1325 | lockdep_assert_held(&priv->shrd->mutex); | ||
1326 | |||
1327 | if (priv->scan_vif == vif) { | ||
1328 | iwl_scan_cancel_timeout(priv, 200); | ||
1329 | iwl_force_scan_end(priv); | ||
1330 | } | ||
1331 | |||
1332 | if (!mode_change) { | ||
1333 | iwl_set_mode(priv, ctx); | ||
1334 | if (!ctx->always_active) | ||
1335 | ctx->is_active = false; | ||
1336 | } | ||
1337 | |||
1338 | /* | ||
1339 | * When removing the IBSS interface, overwrite the | ||
1340 | * BT traffic load with the stored one from the last | ||
1341 | * notification, if any. If this is a device that | ||
1342 | * doesn't implement this, this has no effect since | ||
1343 | * both values are the same and zero. | ||
1344 | */ | ||
1345 | if (vif->type == NL80211_IFTYPE_ADHOC) | ||
1346 | priv->bt_traffic_load = priv->last_bt_traffic_load; | ||
1347 | } | ||
1348 | |||
1349 | static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, | ||
1350 | struct ieee80211_vif *vif) | ||
1351 | { | ||
1352 | struct iwl_priv *priv = hw->priv; | ||
1353 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
1354 | |||
1355 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1356 | |||
1357 | mutex_lock(&priv->shrd->mutex); | ||
1358 | |||
1359 | if (WARN_ON(ctx->vif != vif)) { | ||
1360 | struct iwl_rxon_context *tmp; | ||
1361 | IWL_ERR(priv, "ctx->vif = %p, vif = %p\n", ctx->vif, vif); | ||
1362 | for_each_context(priv, tmp) | ||
1363 | IWL_ERR(priv, "\tID = %d:\tctx = %p\tctx->vif = %p\n", | ||
1364 | tmp->ctxid, tmp, tmp->vif); | ||
1365 | } | ||
1366 | ctx->vif = NULL; | ||
1367 | |||
1368 | iwl_teardown_interface(priv, vif, false); | ||
1369 | |||
1370 | mutex_unlock(&priv->shrd->mutex); | ||
1371 | |||
1372 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1373 | |||
1374 | } | ||
1375 | |||
1376 | static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | ||
1377 | struct ieee80211_vif *vif, | ||
1378 | enum nl80211_iftype newtype, bool newp2p) | ||
1379 | { | ||
1380 | struct iwl_priv *priv = hw->priv; | ||
1381 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
1382 | struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
1383 | struct iwl_rxon_context *tmp; | ||
1384 | enum nl80211_iftype newviftype = newtype; | ||
1385 | u32 interface_modes; | ||
1386 | int err; | ||
1387 | |||
1388 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1389 | |||
1390 | newtype = ieee80211_iftype_p2p(newtype, newp2p); | ||
1391 | |||
1392 | mutex_lock(&priv->shrd->mutex); | ||
1393 | |||
1394 | if (!ctx->vif || !iwl_is_ready_rf(priv->shrd)) { | ||
1395 | /* | ||
1396 | * Huh? But wait ... this can maybe happen when | ||
1397 | * we're in the middle of a firmware restart! | ||
1398 | */ | ||
1399 | err = -EBUSY; | ||
1400 | goto out; | ||
1401 | } | ||
1402 | |||
1403 | interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; | ||
1404 | |||
1405 | if (!(interface_modes & BIT(newtype))) { | ||
1406 | err = -EBUSY; | ||
1407 | goto out; | ||
1408 | } | ||
1409 | |||
1410 | /* | ||
1411 | * Refuse a change that should be done by moving from the PAN | ||
1412 | * context to the BSS context instead, if the BSS context is | ||
1413 | * available and can support the new interface type. | ||
1414 | */ | ||
1415 | if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif && | ||
1416 | (bss_ctx->interface_modes & BIT(newtype) || | ||
1417 | bss_ctx->exclusive_interface_modes & BIT(newtype))) { | ||
1418 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | ||
1419 | err = -EBUSY; | ||
1420 | goto out; | ||
1421 | } | ||
1422 | |||
1423 | if (ctx->exclusive_interface_modes & BIT(newtype)) { | ||
1424 | for_each_context(priv, tmp) { | ||
1425 | if (ctx == tmp) | ||
1426 | continue; | ||
1427 | |||
1428 | if (!tmp->vif) | ||
1429 | continue; | ||
1430 | |||
1431 | /* | ||
1432 | * The current mode switch would be exclusive, but | ||
1433 | * another context is active ... refuse the switch. | ||
1434 | */ | ||
1435 | err = -EBUSY; | ||
1436 | goto out; | ||
1437 | } | ||
1438 | } | ||
1439 | |||
1440 | /* success */ | ||
1441 | iwl_teardown_interface(priv, vif, true); | ||
1442 | vif->type = newviftype; | ||
1443 | vif->p2p = newp2p; | ||
1444 | err = iwl_setup_interface(priv, ctx); | ||
1445 | WARN_ON(err); | ||
1446 | /* | ||
1447 | * We've switched internally, but submitting to the | ||
1448 | * device may have failed for some reason. Mask this | ||
1449 | * error, because otherwise mac80211 will not switch | ||
1450 | * (and set the interface type back) and we'll be | ||
1451 | * out of sync with it. | ||
1452 | */ | ||
1453 | err = 0; | ||
1454 | |||
1455 | out: | ||
1456 | mutex_unlock(&priv->shrd->mutex); | ||
1457 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1458 | |||
1459 | return err; | ||
1460 | } | ||
1461 | |||
1462 | static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | ||
1463 | struct ieee80211_vif *vif, | ||
1464 | struct cfg80211_scan_request *req) | ||
1465 | { | ||
1466 | struct iwl_priv *priv = hw->priv; | ||
1467 | int ret; | ||
1468 | |||
1469 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1470 | |||
1471 | if (req->n_channels == 0) | ||
1472 | return -EINVAL; | ||
1473 | |||
1474 | mutex_lock(&priv->shrd->mutex); | ||
1475 | |||
1476 | /* | ||
1477 | * If an internal scan is in progress, just set | ||
1478 | * up the scan_request as per above. | ||
1479 | */ | ||
1480 | if (priv->scan_type != IWL_SCAN_NORMAL) { | ||
1481 | IWL_DEBUG_SCAN(priv, | ||
1482 | "SCAN request during internal scan - defer\n"); | ||
1483 | priv->scan_request = req; | ||
1484 | priv->scan_vif = vif; | ||
1485 | ret = 0; | ||
1486 | } else { | ||
1487 | priv->scan_request = req; | ||
1488 | priv->scan_vif = vif; | ||
1489 | /* | ||
1490 | * mac80211 will only ask for one band at a time | ||
1491 | * so using channels[0] here is ok | ||
1492 | */ | ||
1493 | ret = iwl_scan_initiate(priv, vif, IWL_SCAN_NORMAL, | ||
1494 | req->channels[0]->band); | ||
1495 | if (ret) { | ||
1496 | priv->scan_request = NULL; | ||
1497 | priv->scan_vif = NULL; | ||
1498 | } | ||
1499 | } | ||
1500 | |||
1501 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1502 | |||
1503 | mutex_unlock(&priv->shrd->mutex); | ||
1504 | |||
1505 | return ret; | ||
1506 | } | ||
1507 | |||
1508 | static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, | ||
1509 | struct ieee80211_vif *vif, | ||
1510 | struct ieee80211_sta *sta) | ||
1511 | { | ||
1512 | struct iwl_priv *priv = hw->priv; | ||
1513 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
1514 | int ret; | ||
1515 | |||
1516 | IWL_DEBUG_MAC80211(priv, "enter: received request to remove " | ||
1517 | "station %pM\n", sta->addr); | ||
1518 | mutex_lock(&priv->shrd->mutex); | ||
1519 | IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", | ||
1520 | sta->addr); | ||
1521 | ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); | ||
1522 | if (ret) | ||
1523 | IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n", | ||
1524 | sta->addr); | ||
1525 | mutex_unlock(&priv->shrd->mutex); | ||
1526 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1527 | |||
1528 | return ret; | ||
1529 | } | ||
1530 | |||
1531 | static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | ||
1532 | { | ||
1533 | unsigned long flags; | ||
1534 | |||
1535 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | ||
1536 | priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; | ||
1537 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; | ||
1538 | priv->stations[sta_id].sta.sta.modify_mask = 0; | ||
1539 | priv->stations[sta_id].sta.sleep_tx_count = 0; | ||
1540 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
1541 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | ||
1542 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
1543 | |||
1544 | } | ||
1545 | |||
1546 | static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | ||
1547 | struct ieee80211_vif *vif, | ||
1548 | enum sta_notify_cmd cmd, | ||
1549 | struct ieee80211_sta *sta) | ||
1550 | { | ||
1551 | struct iwl_priv *priv = hw->priv; | ||
1552 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
1553 | int sta_id; | ||
1554 | |||
1555 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1556 | |||
1557 | switch (cmd) { | ||
1558 | case STA_NOTIFY_SLEEP: | ||
1559 | WARN_ON(!sta_priv->client); | ||
1560 | sta_priv->asleep = true; | ||
1561 | if (atomic_read(&sta_priv->pending_frames) > 0) | ||
1562 | ieee80211_sta_block_awake(hw, sta, true); | ||
1563 | break; | ||
1564 | case STA_NOTIFY_AWAKE: | ||
1565 | WARN_ON(!sta_priv->client); | ||
1566 | if (!sta_priv->asleep) | ||
1567 | break; | ||
1568 | sta_priv->asleep = false; | ||
1569 | sta_id = iwl_sta_id(sta); | ||
1570 | if (sta_id != IWL_INVALID_STATION) | ||
1571 | iwl_sta_modify_ps_wake(priv, sta_id); | ||
1572 | break; | ||
1573 | default: | ||
1574 | break; | ||
1575 | } | ||
1576 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1577 | } | ||
1578 | |||
1579 | struct ieee80211_ops iwlagn_hw_ops = { | ||
1580 | .tx = iwlagn_mac_tx, | ||
1581 | .start = iwlagn_mac_start, | ||
1582 | .stop = iwlagn_mac_stop, | ||
1583 | #ifdef CONFIG_PM_SLEEP | ||
1584 | .suspend = iwlagn_mac_suspend, | ||
1585 | .resume = iwlagn_mac_resume, | ||
1586 | #endif | ||
1587 | .add_interface = iwlagn_mac_add_interface, | ||
1588 | .remove_interface = iwlagn_mac_remove_interface, | ||
1589 | .change_interface = iwlagn_mac_change_interface, | ||
1590 | .config = iwlagn_mac_config, | ||
1591 | .configure_filter = iwlagn_configure_filter, | ||
1592 | .set_key = iwlagn_mac_set_key, | ||
1593 | .update_tkip_key = iwlagn_mac_update_tkip_key, | ||
1594 | .set_rekey_data = iwlagn_mac_set_rekey_data, | ||
1595 | .conf_tx = iwlagn_mac_conf_tx, | ||
1596 | .bss_info_changed = iwlagn_bss_info_changed, | ||
1597 | .ampdu_action = iwlagn_mac_ampdu_action, | ||
1598 | .hw_scan = iwlagn_mac_hw_scan, | ||
1599 | .sta_notify = iwlagn_mac_sta_notify, | ||
1600 | .sta_add = iwlagn_mac_sta_add, | ||
1601 | .sta_remove = iwlagn_mac_sta_remove, | ||
1602 | .channel_switch = iwlagn_mac_channel_switch, | ||
1603 | .flush = iwlagn_mac_flush, | ||
1604 | .tx_last_beacon = iwlagn_mac_tx_last_beacon, | ||
1605 | .remain_on_channel = iwlagn_mac_remain_on_channel, | ||
1606 | .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel, | ||
1607 | .rssi_callback = iwlagn_mac_rssi_callback, | ||
1608 | CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) | ||
1609 | CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump) | ||
1610 | .tx_sync = iwlagn_mac_tx_sync, | ||
1611 | .finish_tx_sync = iwlagn_mac_finish_tx_sync, | ||
1612 | .set_tim = iwlagn_mac_set_tim, | ||
1613 | }; | ||
1614 | |||
1615 | /* This function both allocates and initializes hw and priv. */ | ||
1616 | struct ieee80211_hw *iwl_alloc_all(void) | ||
1617 | { | ||
1618 | struct iwl_priv *priv; | ||
1619 | /* mac80211 allocates memory for this device instance, including | ||
1620 | * space for this driver's private structure */ | ||
1621 | struct ieee80211_hw *hw; | ||
1622 | |||
1623 | hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops); | ||
1624 | if (!hw) | ||
1625 | goto out; | ||
1626 | |||
1627 | priv = hw->priv; | ||
1628 | priv->hw = hw; | ||
1629 | |||
1630 | out: | ||
1631 | return hw; | ||
1632 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 1800029911ad..850ec8e51b17 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c | |||
@@ -256,6 +256,8 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
256 | {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, | 256 | {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, |
257 | {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, | 257 | {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, |
258 | {IWL_PCI_DEVICE(0x0082, 0x1341, iwl6005_2agn_d_cfg)}, | 258 | {IWL_PCI_DEVICE(0x0082, 0x1341, iwl6005_2agn_d_cfg)}, |
259 | {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_cfg)},/* low 5GHz active */ | ||
260 | {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_cfg)},/* high 5GHz active */ | ||
259 | 261 | ||
260 | /* 6x30 Series */ | 262 | /* 6x30 Series */ |
261 | {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, | 263 | {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, |
@@ -325,46 +327,28 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
325 | {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, | 327 | {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, |
326 | {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, | 328 | {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, |
327 | {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, | 329 | {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, |
328 | {IWL_PCI_DEVICE(0x0890, 0x4026, iwl2000_2bg_cfg)}, | ||
329 | {IWL_PCI_DEVICE(0x0891, 0x4226, iwl2000_2bg_cfg)}, | ||
330 | {IWL_PCI_DEVICE(0x0890, 0x4426, iwl2000_2bg_cfg)}, | ||
331 | {IWL_PCI_DEVICE(0x0890, 0x4822, iwl2000_2bgn_d_cfg)}, | 330 | {IWL_PCI_DEVICE(0x0890, 0x4822, iwl2000_2bgn_d_cfg)}, |
332 | 331 | ||
333 | /* 2x30 Series */ | 332 | /* 2x30 Series */ |
334 | {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, | 333 | {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, |
335 | {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, | 334 | {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, |
336 | {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, | 335 | {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, |
337 | {IWL_PCI_DEVICE(0x0887, 0x4066, iwl2030_2bg_cfg)}, | ||
338 | {IWL_PCI_DEVICE(0x0888, 0x4266, iwl2030_2bg_cfg)}, | ||
339 | {IWL_PCI_DEVICE(0x0887, 0x4466, iwl2030_2bg_cfg)}, | ||
340 | 336 | ||
341 | /* 6x35 Series */ | 337 | /* 6x35 Series */ |
342 | {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, | 338 | {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, |
343 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, | 339 | {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, |
344 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, | 340 | {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, |
345 | {IWL_PCI_DEVICE(0x088E, 0x4064, iwl6035_2abg_cfg)}, | ||
346 | {IWL_PCI_DEVICE(0x088F, 0x4264, iwl6035_2abg_cfg)}, | ||
347 | {IWL_PCI_DEVICE(0x088E, 0x4464, iwl6035_2abg_cfg)}, | ||
348 | {IWL_PCI_DEVICE(0x088E, 0x4066, iwl6035_2bg_cfg)}, | ||
349 | {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, | ||
350 | {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, | ||
351 | 341 | ||
352 | /* 105 Series */ | 342 | /* 105 Series */ |
353 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, | 343 | {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, |
354 | {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)}, | 344 | {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)}, |
355 | {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)}, | 345 | {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)}, |
356 | {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)}, | ||
357 | {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)}, | ||
358 | {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)}, | ||
359 | {IWL_PCI_DEVICE(0x0894, 0x0822, iwl105_bgn_d_cfg)}, | 346 | {IWL_PCI_DEVICE(0x0894, 0x0822, iwl105_bgn_d_cfg)}, |
360 | 347 | ||
361 | /* 135 Series */ | 348 | /* 135 Series */ |
362 | {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, | 349 | {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, |
363 | {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, | 350 | {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, |
364 | {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, | 351 | {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, |
365 | {IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)}, | ||
366 | {IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)}, | ||
367 | {IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)}, | ||
368 | 352 | ||
369 | {0} | 353 | {0} |
370 | }; | 354 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index e5d727f537d0..359d2182757b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -416,6 +416,8 @@ static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time) | |||
416 | 416 | ||
417 | if (!iwl_is_associated_ctx(ctx)) | 417 | if (!iwl_is_associated_ctx(ctx)) |
418 | continue; | 418 | continue; |
419 | if (ctx->staging.dev_type == RXON_DEV_TYPE_P2P) | ||
420 | continue; | ||
419 | value = ctx->beacon_int; | 421 | value = ctx->beacon_int; |
420 | if (!value) | 422 | if (!value) |
421 | value = IWL_PASSIVE_DWELL_BASE; | 423 | value = IWL_PASSIVE_DWELL_BASE; |
@@ -678,7 +680,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
678 | priv->contexts[IWL_RXON_CTX_BSS].active.flags & | 680 | priv->contexts[IWL_RXON_CTX_BSS].active.flags & |
679 | RXON_FLG_CHANNEL_MODE_MSK) | 681 | RXON_FLG_CHANNEL_MODE_MSK) |
680 | >> RXON_FLG_CHANNEL_MODE_POS; | 682 | >> RXON_FLG_CHANNEL_MODE_POS; |
681 | if (chan_mod == CHANNEL_MODE_PURE_40) { | 683 | if ((priv->scan_request && priv->scan_request->no_cck) || |
684 | chan_mod == CHANNEL_MODE_PURE_40) { | ||
682 | rate = IWL_RATE_6M_PLCP; | 685 | rate = IWL_RATE_6M_PLCP; |
683 | } else { | 686 | } else { |
684 | rate = IWL_RATE_1M_PLCP; | 687 | rate = IWL_RATE_1M_PLCP; |
@@ -938,51 +941,6 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, | |||
938 | return 0; | 941 | return 0; |
939 | } | 942 | } |
940 | 943 | ||
941 | int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | ||
942 | struct ieee80211_vif *vif, | ||
943 | struct cfg80211_scan_request *req) | ||
944 | { | ||
945 | struct iwl_priv *priv = hw->priv; | ||
946 | int ret; | ||
947 | |||
948 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
949 | |||
950 | if (req->n_channels == 0) | ||
951 | return -EINVAL; | ||
952 | |||
953 | mutex_lock(&priv->shrd->mutex); | ||
954 | |||
955 | /* | ||
956 | * If an internal scan is in progress, just set | ||
957 | * up the scan_request as per above. | ||
958 | */ | ||
959 | if (priv->scan_type != IWL_SCAN_NORMAL) { | ||
960 | IWL_DEBUG_SCAN(priv, | ||
961 | "SCAN request during internal scan - defer\n"); | ||
962 | priv->scan_request = req; | ||
963 | priv->scan_vif = vif; | ||
964 | ret = 0; | ||
965 | } else { | ||
966 | priv->scan_request = req; | ||
967 | priv->scan_vif = vif; | ||
968 | /* | ||
969 | * mac80211 will only ask for one band at a time | ||
970 | * so using channels[0] here is ok | ||
971 | */ | ||
972 | ret = iwl_scan_initiate(priv, vif, IWL_SCAN_NORMAL, | ||
973 | req->channels[0]->band); | ||
974 | if (ret) { | ||
975 | priv->scan_request = NULL; | ||
976 | priv->scan_vif = NULL; | ||
977 | } | ||
978 | } | ||
979 | |||
980 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
981 | |||
982 | mutex_unlock(&priv->shrd->mutex); | ||
983 | |||
984 | return ret; | ||
985 | } | ||
986 | 944 | ||
987 | /* | 945 | /* |
988 | * internal short scan, this function should only been called while associated. | 946 | * internal short scan, this function should only been called while associated. |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 5e50d88f302b..e3882d0cfc85 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c | |||
@@ -396,8 +396,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
396 | break; | 396 | break; |
397 | 397 | ||
398 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: | 398 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: |
399 | status = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, | 399 | status = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_INIT); |
400 | IWL_UCODE_INIT); | ||
401 | if (status) | 400 | if (status) |
402 | IWL_DEBUG_INFO(priv, | 401 | IWL_DEBUG_INFO(priv, |
403 | "Error loading init ucode: %d\n", status); | 402 | "Error loading init ucode: %d\n", status); |
@@ -409,9 +408,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
409 | break; | 408 | break; |
410 | 409 | ||
411 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: | 410 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: |
412 | status = iwlagn_load_ucode_wait_alive(priv, | 411 | status = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); |
413 | &priv->ucode_rt, | ||
414 | IWL_UCODE_REGULAR); | ||
415 | if (status) { | 412 | if (status) { |
416 | IWL_DEBUG_INFO(priv, | 413 | IWL_DEBUG_INFO(priv, |
417 | "Error loading runtime ucode: %d\n", status); | 414 | "Error loading runtime ucode: %d\n", status); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 2b6756e8b8f9..afaaa2a51b96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | |||
@@ -355,7 +355,7 @@ static inline void iwl_set_swq_id(struct iwl_tx_queue *txq, u8 ac, u8 hwq) | |||
355 | } | 355 | } |
356 | 356 | ||
357 | static inline void iwl_wake_queue(struct iwl_trans *trans, | 357 | static inline void iwl_wake_queue(struct iwl_trans *trans, |
358 | struct iwl_tx_queue *txq) | 358 | struct iwl_tx_queue *txq, const char *msg) |
359 | { | 359 | { |
360 | u8 queue = txq->swq_id; | 360 | u8 queue = txq->swq_id; |
361 | u8 ac = queue & 3; | 361 | u8 ac = queue & 3; |
@@ -363,13 +363,22 @@ static inline void iwl_wake_queue(struct iwl_trans *trans, | |||
363 | struct iwl_trans_pcie *trans_pcie = | 363 | struct iwl_trans_pcie *trans_pcie = |
364 | IWL_TRANS_GET_PCIE_TRANS(trans); | 364 | IWL_TRANS_GET_PCIE_TRANS(trans); |
365 | 365 | ||
366 | if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) | 366 | if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) { |
367 | if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) | 367 | if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) { |
368 | iwl_wake_sw_queue(priv(trans), ac); | 368 | iwl_wake_sw_queue(priv(trans), ac); |
369 | IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d. %s", | ||
370 | hwq, ac, msg); | ||
371 | } else { | ||
372 | IWL_DEBUG_TX_QUEUES(trans, "Don't wake hwq %d ac %d" | ||
373 | " stop count %d. %s", | ||
374 | hwq, ac, atomic_read(&trans_pcie-> | ||
375 | queue_stop_count[ac]), msg); | ||
376 | } | ||
377 | } | ||
369 | } | 378 | } |
370 | 379 | ||
371 | static inline void iwl_stop_queue(struct iwl_trans *trans, | 380 | static inline void iwl_stop_queue(struct iwl_trans *trans, |
372 | struct iwl_tx_queue *txq) | 381 | struct iwl_tx_queue *txq, const char *msg) |
373 | { | 382 | { |
374 | u8 queue = txq->swq_id; | 383 | u8 queue = txq->swq_id; |
375 | u8 ac = queue & 3; | 384 | u8 ac = queue & 3; |
@@ -377,9 +386,23 @@ static inline void iwl_stop_queue(struct iwl_trans *trans, | |||
377 | struct iwl_trans_pcie *trans_pcie = | 386 | struct iwl_trans_pcie *trans_pcie = |
378 | IWL_TRANS_GET_PCIE_TRANS(trans); | 387 | IWL_TRANS_GET_PCIE_TRANS(trans); |
379 | 388 | ||
380 | if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) | 389 | if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) { |
381 | if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) | 390 | if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) { |
382 | iwl_stop_sw_queue(priv(trans), ac); | 391 | iwl_stop_sw_queue(priv(trans), ac); |
392 | IWL_DEBUG_TX_QUEUES(trans, "Stop hwq %d ac %d" | ||
393 | " stop count %d. %s", | ||
394 | hwq, ac, atomic_read(&trans_pcie-> | ||
395 | queue_stop_count[ac]), msg); | ||
396 | } else { | ||
397 | IWL_DEBUG_TX_QUEUES(trans, "Don't stop hwq %d ac %d" | ||
398 | " stop count %d. %s", | ||
399 | hwq, ac, atomic_read(&trans_pcie-> | ||
400 | queue_stop_count[ac]), msg); | ||
401 | } | ||
402 | } else { | ||
403 | IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped/ %s", | ||
404 | hwq, msg); | ||
405 | } | ||
383 | } | 406 | } |
384 | 407 | ||
385 | #ifdef ieee80211_stop_queue | 408 | #ifdef ieee80211_stop_queue |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 374c68cc1d70..ee126f844a5c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | |||
@@ -1108,7 +1108,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1108 | isr_stats->tx++; | 1108 | isr_stats->tx++; |
1109 | handled |= CSR_INT_BIT_FH_TX; | 1109 | handled |= CSR_INT_BIT_FH_TX; |
1110 | /* Wake up uCode load routine, now that load is complete */ | 1110 | /* Wake up uCode load routine, now that load is complete */ |
1111 | priv(trans)->ucode_write_complete = 1; | 1111 | trans->ucode_write_complete = 1; |
1112 | wake_up(&trans->shrd->wait_command_queue); | 1112 | wake_up(&trans->shrd->wait_command_queue); |
1113 | } | 1113 | } |
1114 | 1114 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 4a0c95302a7e..6dba1515023c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | |||
@@ -430,7 +430,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, | |||
430 | 430 | ||
431 | txq->sched_retry = scd_retry; | 431 | txq->sched_retry = scd_retry; |
432 | 432 | ||
433 | IWL_DEBUG_INFO(trans, "%s %s Queue %d on FIFO %d\n", | 433 | IWL_DEBUG_TX_QUEUES(trans, "%s %s Queue %d on FIFO %d\n", |
434 | active ? "Activate" : "Deactivate", | 434 | active ? "Activate" : "Deactivate", |
435 | scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); | 435 | scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); |
436 | } | 436 | } |
@@ -561,12 +561,13 @@ int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans, | |||
561 | 561 | ||
562 | tid_data = &trans->shrd->tid_data[sta_id][tid]; | 562 | tid_data = &trans->shrd->tid_data[sta_id][tid]; |
563 | if (tid_data->tfds_in_queue == 0) { | 563 | if (tid_data->tfds_in_queue == 0) { |
564 | IWL_DEBUG_HT(trans, "HW queue is empty\n"); | 564 | IWL_DEBUG_TX_QUEUES(trans, "HW queue is empty\n"); |
565 | tid_data->agg.state = IWL_AGG_ON; | 565 | tid_data->agg.state = IWL_AGG_ON; |
566 | iwl_start_tx_ba_trans_ready(priv(trans), ctx, sta_id, tid); | 566 | iwl_start_tx_ba_trans_ready(priv(trans), ctx, sta_id, tid); |
567 | } else { | 567 | } else { |
568 | IWL_DEBUG_HT(trans, "HW queue is NOT empty: %d packets in HW" | 568 | IWL_DEBUG_TX_QUEUES(trans, |
569 | "queue\n", tid_data->tfds_in_queue); | 569 | "HW queue is NOT empty: %d packets in HW" |
570 | " queue\n", tid_data->tfds_in_queue); | ||
570 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; | 571 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; |
571 | } | 572 | } |
572 | spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); | 573 | spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); |
@@ -643,14 +644,15 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, | |||
643 | 644 | ||
644 | /* The queue is not empty */ | 645 | /* The queue is not empty */ |
645 | if (write_ptr != read_ptr) { | 646 | if (write_ptr != read_ptr) { |
646 | IWL_DEBUG_HT(trans, "Stopping a non empty AGG HW QUEUE\n"); | 647 | IWL_DEBUG_TX_QUEUES(trans, |
648 | "Stopping a non empty AGG HW QUEUE\n"); | ||
647 | trans->shrd->tid_data[sta_id][tid].agg.state = | 649 | trans->shrd->tid_data[sta_id][tid].agg.state = |
648 | IWL_EMPTYING_HW_QUEUE_DELBA; | 650 | IWL_EMPTYING_HW_QUEUE_DELBA; |
649 | spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); | 651 | spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); |
650 | return 0; | 652 | return 0; |
651 | } | 653 | } |
652 | 654 | ||
653 | IWL_DEBUG_HT(trans, "HW queue is empty\n"); | 655 | IWL_DEBUG_TX_QUEUES(trans, "HW queue is empty\n"); |
654 | turn_off: | 656 | turn_off: |
655 | trans->shrd->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; | 657 | trans->shrd->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; |
656 | 658 | ||
@@ -982,7 +984,8 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
982 | 984 | ||
983 | ret = iwl_enqueue_hcmd(trans, cmd); | 985 | ret = iwl_enqueue_hcmd(trans, cmd); |
984 | if (ret < 0) { | 986 | if (ret < 0) { |
985 | IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n", | 987 | IWL_DEBUG_QUIET_RFKILL(trans, |
988 | "Error sending %s: enqueue_hcmd failed: %d\n", | ||
986 | get_cmd_string(cmd->id), ret); | 989 | get_cmd_string(cmd->id), ret); |
987 | return ret; | 990 | return ret; |
988 | } | 991 | } |
@@ -1000,6 +1003,20 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
1000 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", | 1003 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", |
1001 | get_cmd_string(cmd->id)); | 1004 | get_cmd_string(cmd->id)); |
1002 | 1005 | ||
1006 | if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status)) | ||
1007 | return -EBUSY; | ||
1008 | |||
1009 | |||
1010 | if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) { | ||
1011 | IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n", | ||
1012 | get_cmd_string(cmd->id)); | ||
1013 | return -ECANCELED; | ||
1014 | } | ||
1015 | if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) { | ||
1016 | IWL_ERR(trans, "Command %s failed: FW Error\n", | ||
1017 | get_cmd_string(cmd->id)); | ||
1018 | return -EIO; | ||
1019 | } | ||
1003 | set_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 1020 | set_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); |
1004 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", | 1021 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", |
1005 | get_cmd_string(cmd->id)); | 1022 | get_cmd_string(cmd->id)); |
@@ -1008,7 +1025,8 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
1008 | if (cmd_idx < 0) { | 1025 | if (cmd_idx < 0) { |
1009 | ret = cmd_idx; | 1026 | ret = cmd_idx; |
1010 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 1027 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); |
1011 | IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n", | 1028 | IWL_DEBUG_QUIET_RFKILL(trans, |
1029 | "Error sending %s: enqueue_hcmd failed: %d\n", | ||
1012 | get_cmd_string(cmd->id), ret); | 1030 | get_cmd_string(cmd->id), ret); |
1013 | return ret; | 1031 | return ret; |
1014 | } | 1032 | } |
@@ -1022,12 +1040,12 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
1022 | &trans_pcie->txq[trans->shrd->cmd_queue]; | 1040 | &trans_pcie->txq[trans->shrd->cmd_queue]; |
1023 | struct iwl_queue *q = &txq->q; | 1041 | struct iwl_queue *q = &txq->q; |
1024 | 1042 | ||
1025 | IWL_ERR(trans, | 1043 | IWL_DEBUG_QUIET_RFKILL(trans, |
1026 | "Error sending %s: time out after %dms.\n", | 1044 | "Error sending %s: time out after %dms.\n", |
1027 | get_cmd_string(cmd->id), | 1045 | get_cmd_string(cmd->id), |
1028 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); | 1046 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); |
1029 | 1047 | ||
1030 | IWL_ERR(trans, | 1048 | IWL_DEBUG_QUIET_RFKILL(trans, |
1031 | "Current CMD queue read_ptr %d write_ptr %d\n", | 1049 | "Current CMD queue read_ptr %d write_ptr %d\n", |
1032 | q->read_ptr, q->write_ptr); | 1050 | q->read_ptr, q->write_ptr); |
1033 | 1051 | ||
@@ -1039,18 +1057,6 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
1039 | } | 1057 | } |
1040 | } | 1058 | } |
1041 | 1059 | ||
1042 | if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) { | ||
1043 | IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n", | ||
1044 | get_cmd_string(cmd->id)); | ||
1045 | ret = -ECANCELED; | ||
1046 | goto fail; | ||
1047 | } | ||
1048 | if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) { | ||
1049 | IWL_ERR(trans, "Command %s failed: FW Error\n", | ||
1050 | get_cmd_string(cmd->id)); | ||
1051 | ret = -EIO; | ||
1052 | goto fail; | ||
1053 | } | ||
1054 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) { | 1060 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) { |
1055 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", | 1061 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", |
1056 | get_cmd_string(cmd->id)); | 1062 | get_cmd_string(cmd->id)); |
@@ -1071,7 +1077,7 @@ cancel: | |||
1071 | trans_pcie->txq[trans->shrd->cmd_queue].meta[cmd_idx].flags &= | 1077 | trans_pcie->txq[trans->shrd->cmd_queue].meta[cmd_idx].flags &= |
1072 | ~CMD_WANT_SKB; | 1078 | ~CMD_WANT_SKB; |
1073 | } | 1079 | } |
1074 | fail: | 1080 | |
1075 | if (cmd->reply_page) { | 1081 | if (cmd->reply_page) { |
1076 | iwl_free_pages(trans->shrd, cmd->reply_page); | 1082 | iwl_free_pages(trans->shrd, cmd->reply_page); |
1077 | cmd->reply_page = 0; | 1083 | cmd->reply_page = 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ce918980e977..93c4f56ac408 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
@@ -1232,7 +1232,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1232 | txq->need_update = 1; | 1232 | txq->need_update = 1; |
1233 | iwl_txq_update_write_ptr(trans, txq); | 1233 | iwl_txq_update_write_ptr(trans, txq); |
1234 | } else { | 1234 | } else { |
1235 | iwl_stop_queue(trans, txq); | 1235 | iwl_stop_queue(trans, txq, "Queue is full"); |
1236 | } | 1236 | } |
1237 | } | 1237 | } |
1238 | return 0; | 1238 | return 0; |
@@ -1284,20 +1284,21 @@ static int iwlagn_txq_check_empty(struct iwl_trans *trans, | |||
1284 | /* aggregated HW queue */ | 1284 | /* aggregated HW queue */ |
1285 | if ((txq_id == tid_data->agg.txq_id) && | 1285 | if ((txq_id == tid_data->agg.txq_id) && |
1286 | (q->read_ptr == q->write_ptr)) { | 1286 | (q->read_ptr == q->write_ptr)) { |
1287 | IWL_DEBUG_HT(trans, | 1287 | IWL_DEBUG_TX_QUEUES(trans, |
1288 | "HW queue empty: continue DELBA flow\n"); | 1288 | "HW queue empty: continue DELBA flow\n"); |
1289 | iwl_trans_pcie_txq_agg_disable(trans, txq_id); | 1289 | iwl_trans_pcie_txq_agg_disable(trans, txq_id); |
1290 | tid_data->agg.state = IWL_AGG_OFF; | 1290 | tid_data->agg.state = IWL_AGG_OFF; |
1291 | iwl_stop_tx_ba_trans_ready(priv(trans), | 1291 | iwl_stop_tx_ba_trans_ready(priv(trans), |
1292 | NUM_IWL_RXON_CTX, | 1292 | NUM_IWL_RXON_CTX, |
1293 | sta_id, tid); | 1293 | sta_id, tid); |
1294 | iwl_wake_queue(trans, &trans_pcie->txq[txq_id]); | 1294 | iwl_wake_queue(trans, &trans_pcie->txq[txq_id], |
1295 | "DELBA flow complete"); | ||
1295 | } | 1296 | } |
1296 | break; | 1297 | break; |
1297 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | 1298 | case IWL_EMPTYING_HW_QUEUE_ADDBA: |
1298 | /* We are reclaiming the last packet of the queue */ | 1299 | /* We are reclaiming the last packet of the queue */ |
1299 | if (tid_data->tfds_in_queue == 0) { | 1300 | if (tid_data->tfds_in_queue == 0) { |
1300 | IWL_DEBUG_HT(trans, | 1301 | IWL_DEBUG_TX_QUEUES(trans, |
1301 | "HW queue empty: continue ADDBA flow\n"); | 1302 | "HW queue empty: continue ADDBA flow\n"); |
1302 | tid_data->agg.state = IWL_AGG_ON; | 1303 | tid_data->agg.state = IWL_AGG_ON; |
1303 | iwl_start_tx_ba_trans_ready(priv(trans), | 1304 | iwl_start_tx_ba_trans_ready(priv(trans), |
@@ -1355,7 +1356,7 @@ static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | |||
1355 | ssn , tfd_num, txq_id, txq->swq_id); | 1356 | ssn , tfd_num, txq_id, txq->swq_id); |
1356 | freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); | 1357 | freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); |
1357 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && cond) | 1358 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && cond) |
1358 | iwl_wake_queue(trans, txq); | 1359 | iwl_wake_queue(trans, txq, "Packets reclaimed"); |
1359 | } | 1360 | } |
1360 | 1361 | ||
1361 | iwl_free_tfds_in_queue(trans, sta_id, tid, freed); | 1362 | iwl_free_tfds_in_queue(trans, sta_id, tid, freed); |
@@ -1419,7 +1420,8 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) | |||
1419 | #endif /* CONFIG_PM_SLEEP */ | 1420 | #endif /* CONFIG_PM_SLEEP */ |
1420 | 1421 | ||
1421 | static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, | 1422 | static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, |
1422 | enum iwl_rxon_context_id ctx) | 1423 | enum iwl_rxon_context_id ctx, |
1424 | const char *msg) | ||
1423 | { | 1425 | { |
1424 | u8 ac, txq_id; | 1426 | u8 ac, txq_id; |
1425 | struct iwl_trans_pcie *trans_pcie = | 1427 | struct iwl_trans_pcie *trans_pcie = |
@@ -1427,11 +1429,11 @@ static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, | |||
1427 | 1429 | ||
1428 | for (ac = 0; ac < AC_NUM; ac++) { | 1430 | for (ac = 0; ac < AC_NUM; ac++) { |
1429 | txq_id = trans_pcie->ac_to_queue[ctx][ac]; | 1431 | txq_id = trans_pcie->ac_to_queue[ctx][ac]; |
1430 | IWL_DEBUG_INFO(trans, "Queue Status: Q[%d] %s\n", | 1432 | IWL_DEBUG_TX_QUEUES(trans, "Queue Status: Q[%d] %s\n", |
1431 | ac, | 1433 | ac, |
1432 | (atomic_read(&trans_pcie->queue_stop_count[ac]) > 0) | 1434 | (atomic_read(&trans_pcie->queue_stop_count[ac]) > 0) |
1433 | ? "stopped" : "awake"); | 1435 | ? "stopped" : "awake"); |
1434 | iwl_wake_queue(trans, &trans_pcie->txq[txq_id]); | 1436 | iwl_wake_queue(trans, &trans_pcie->txq[txq_id], msg); |
1435 | } | 1437 | } |
1436 | } | 1438 | } |
1437 | 1439 | ||
@@ -1454,11 +1456,12 @@ static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd) | |||
1454 | return iwl_trans; | 1456 | return iwl_trans; |
1455 | } | 1457 | } |
1456 | 1458 | ||
1457 | static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id) | 1459 | static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id, |
1460 | const char *msg) | ||
1458 | { | 1461 | { |
1459 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1462 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1460 | 1463 | ||
1461 | iwl_stop_queue(trans, &trans_pcie->txq[txq_id]); | 1464 | iwl_stop_queue(trans, &trans_pcie->txq[txq_id], msg); |
1462 | } | 1465 | } |
1463 | 1466 | ||
1464 | #define IWL_FLUSH_WAIT_MS 2000 | 1467 | #define IWL_FLUSH_WAIT_MS 2000 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index c5923125c3f9..50227ebc0ee2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -171,7 +171,8 @@ struct iwl_trans_ops { | |||
171 | void (*tx_start)(struct iwl_trans *trans); | 171 | void (*tx_start)(struct iwl_trans *trans); |
172 | 172 | ||
173 | void (*wake_any_queue)(struct iwl_trans *trans, | 173 | void (*wake_any_queue)(struct iwl_trans *trans, |
174 | enum iwl_rxon_context_id ctx); | 174 | enum iwl_rxon_context_id ctx, |
175 | const char *msg); | ||
175 | 176 | ||
176 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); | 177 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); |
177 | 178 | ||
@@ -196,7 +197,7 @@ struct iwl_trans_ops { | |||
196 | 197 | ||
197 | void (*free)(struct iwl_trans *trans); | 198 | void (*free)(struct iwl_trans *trans); |
198 | 199 | ||
199 | void (*stop_queue)(struct iwl_trans *trans, int q); | 200 | void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg); |
200 | 201 | ||
201 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); | 202 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); |
202 | int (*check_stuck_queue)(struct iwl_trans *trans, int q); | 203 | int (*check_stuck_queue)(struct iwl_trans *trans, int q); |
@@ -207,17 +208,48 @@ struct iwl_trans_ops { | |||
207 | #endif | 208 | #endif |
208 | }; | 209 | }; |
209 | 210 | ||
211 | /* one for each uCode image (inst/data, boot/init/runtime) */ | ||
212 | struct fw_desc { | ||
213 | dma_addr_t p_addr; /* hardware address */ | ||
214 | void *v_addr; /* software address */ | ||
215 | u32 len; /* size in bytes */ | ||
216 | }; | ||
217 | |||
218 | struct fw_img { | ||
219 | struct fw_desc code; /* firmware code image */ | ||
220 | struct fw_desc data; /* firmware data image */ | ||
221 | }; | ||
222 | |||
223 | enum iwl_ucode_type { | ||
224 | IWL_UCODE_NONE, | ||
225 | IWL_UCODE_REGULAR, | ||
226 | IWL_UCODE_INIT, | ||
227 | IWL_UCODE_WOWLAN, | ||
228 | }; | ||
229 | |||
210 | /** | 230 | /** |
211 | * struct iwl_trans - transport common data | 231 | * struct iwl_trans - transport common data |
212 | * @ops - pointer to iwl_trans_ops | 232 | * @ops - pointer to iwl_trans_ops |
213 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer | 233 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer |
214 | * @hcmd_lock: protects HCMD | 234 | * @hcmd_lock: protects HCMD |
235 | * @ucode_write_complete: indicates that the ucode has been copied. | ||
236 | * @ucode_rt: run time ucode image | ||
237 | * @ucode_init: init ucode image | ||
238 | * @ucode_wowlan: wake on wireless ucode image (optional) | ||
215 | */ | 239 | */ |
216 | struct iwl_trans { | 240 | struct iwl_trans { |
217 | const struct iwl_trans_ops *ops; | 241 | const struct iwl_trans_ops *ops; |
218 | struct iwl_shared *shrd; | 242 | struct iwl_shared *shrd; |
219 | spinlock_t hcmd_lock; | 243 | spinlock_t hcmd_lock; |
220 | 244 | ||
245 | u8 ucode_write_complete; /* the image write is complete */ | ||
246 | struct fw_img ucode_rt; | ||
247 | struct fw_img ucode_init; | ||
248 | struct fw_img ucode_wowlan; | ||
249 | |||
250 | /* eeprom related variables */ | ||
251 | int nvm_device_type; | ||
252 | |||
221 | /* pointer to trans specific struct */ | 253 | /* pointer to trans specific struct */ |
222 | /*Ensure that this pointer will always be aligned to sizeof pointer */ | 254 | /*Ensure that this pointer will always be aligned to sizeof pointer */ |
223 | char trans_specific[0] __attribute__((__aligned__(sizeof(void *)))); | 255 | char trans_specific[0] __attribute__((__aligned__(sizeof(void *)))); |
@@ -249,9 +281,10 @@ static inline void iwl_trans_tx_start(struct iwl_trans *trans) | |||
249 | } | 281 | } |
250 | 282 | ||
251 | static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, | 283 | static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, |
252 | enum iwl_rxon_context_id ctx) | 284 | enum iwl_rxon_context_id ctx, |
285 | const char *msg) | ||
253 | { | 286 | { |
254 | trans->ops->wake_any_queue(trans, ctx); | 287 | trans->ops->wake_any_queue(trans, ctx, msg); |
255 | } | 288 | } |
256 | 289 | ||
257 | 290 | ||
@@ -311,9 +344,10 @@ static inline void iwl_trans_free(struct iwl_trans *trans) | |||
311 | trans->ops->free(trans); | 344 | trans->ops->free(trans); |
312 | } | 345 | } |
313 | 346 | ||
314 | static inline void iwl_trans_stop_queue(struct iwl_trans *trans, int q) | 347 | static inline void iwl_trans_stop_queue(struct iwl_trans *trans, int q, |
348 | const char *msg) | ||
315 | { | 349 | { |
316 | trans->ops->stop_queue(trans, q); | 350 | trans->ops->stop_queue(trans, q, msg); |
317 | } | 351 | } |
318 | 352 | ||
319 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) | 353 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) |
@@ -348,4 +382,8 @@ static inline int iwl_trans_resume(struct iwl_trans *trans) | |||
348 | ******************************************************/ | 382 | ******************************************************/ |
349 | extern const struct iwl_trans_ops trans_ops_pcie; | 383 | extern const struct iwl_trans_ops trans_ops_pcie; |
350 | 384 | ||
385 | int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, | ||
386 | const void *data, size_t len); | ||
387 | void iwl_dealloc_ucode(struct iwl_trans *trans); | ||
388 | |||
351 | #endif /* __iwl_trans_h__ */ | 389 | #endif /* __iwl_trans_h__ */ |
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index c42be81e979e..48e8218fd23b 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c | |||
@@ -165,11 +165,15 @@ static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
165 | struct key_params *params) | 165 | struct key_params *params) |
166 | { | 166 | { |
167 | struct iwm_priv *iwm = ndev_to_iwm(ndev); | 167 | struct iwm_priv *iwm = ndev_to_iwm(ndev); |
168 | struct iwm_key *key = &iwm->keys[key_index]; | 168 | struct iwm_key *key; |
169 | int ret; | 169 | int ret; |
170 | 170 | ||
171 | IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr); | 171 | IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr); |
172 | 172 | ||
173 | if (key_index >= IWM_NUM_KEYS) | ||
174 | return -ENOENT; | ||
175 | |||
176 | key = &iwm->keys[key_index]; | ||
173 | memset(key, 0, sizeof(struct iwm_key)); | 177 | memset(key, 0, sizeof(struct iwm_key)); |
174 | ret = iwm_key_init(key, key_index, mac_addr, params); | 178 | ret = iwm_key_init(key, key_index, mac_addr, params); |
175 | if (ret < 0) { | 179 | if (ret < 0) { |
@@ -214,8 +218,12 @@ static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, | |||
214 | u8 key_index, bool pairwise, const u8 *mac_addr) | 218 | u8 key_index, bool pairwise, const u8 *mac_addr) |
215 | { | 219 | { |
216 | struct iwm_priv *iwm = ndev_to_iwm(ndev); | 220 | struct iwm_priv *iwm = ndev_to_iwm(ndev); |
217 | struct iwm_key *key = &iwm->keys[key_index]; | 221 | struct iwm_key *key; |
218 | 222 | ||
223 | if (key_index >= IWM_NUM_KEYS) | ||
224 | return -ENOENT; | ||
225 | |||
226 | key = &iwm->keys[key_index]; | ||
219 | if (!iwm->keys[key_index].key_len) { | 227 | if (!iwm->keys[key_index].key_len) { |
220 | IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index); | 228 | IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index); |
221 | return 0; | 229 | return 0; |
@@ -236,6 +244,9 @@ static int iwm_cfg80211_set_default_key(struct wiphy *wiphy, | |||
236 | 244 | ||
237 | IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index); | 245 | IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index); |
238 | 246 | ||
247 | if (key_index >= IWM_NUM_KEYS) | ||
248 | return -ENOENT; | ||
249 | |||
239 | if (!iwm->keys[key_index].key_len) { | 250 | if (!iwm->keys[key_index].key_len) { |
240 | IWM_ERR(iwm, "Key %d not used\n", key_index); | 251 | IWM_ERR(iwm, "Key %d not used\n", key_index); |
241 | return -EINVAL; | 252 | return -EINVAL; |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index a7f1ab28940d..d1d84e0e30fc 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -485,6 +485,7 @@ static int lbs_cfg_set_channel(struct wiphy *wiphy, | |||
485 | static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | 485 | static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, |
486 | struct cmd_header *resp) | 486 | struct cmd_header *resp) |
487 | { | 487 | { |
488 | struct cfg80211_bss *bss; | ||
488 | struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp; | 489 | struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp; |
489 | int bsssize; | 490 | int bsssize; |
490 | const u8 *pos; | 491 | const u8 *pos; |
@@ -632,12 +633,14 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
632 | LBS_SCAN_RSSI_TO_MBM(rssi)/100); | 633 | LBS_SCAN_RSSI_TO_MBM(rssi)/100); |
633 | 634 | ||
634 | if (channel && | 635 | if (channel && |
635 | !(channel->flags & IEEE80211_CHAN_DISABLED)) | 636 | !(channel->flags & IEEE80211_CHAN_DISABLED)) { |
636 | cfg80211_inform_bss(wiphy, channel, | 637 | bss = cfg80211_inform_bss(wiphy, channel, |
637 | bssid, get_unaligned_le64(tsfdesc), | 638 | bssid, get_unaligned_le64(tsfdesc), |
638 | capa, intvl, ie, ielen, | 639 | capa, intvl, ie, ielen, |
639 | LBS_SCAN_RSSI_TO_MBM(rssi), | 640 | LBS_SCAN_RSSI_TO_MBM(rssi), |
640 | GFP_KERNEL); | 641 | GFP_KERNEL); |
642 | cfg80211_put_bss(bss); | ||
643 | } | ||
641 | } else | 644 | } else |
642 | lbs_deb_scan("scan response: missing BSS channel IE\n"); | 645 | lbs_deb_scan("scan response: missing BSS channel IE\n"); |
643 | 646 | ||
@@ -1720,6 +1723,7 @@ static void lbs_join_post(struct lbs_private *priv, | |||
1720 | 2 + 2 + /* atim */ | 1723 | 2 + 2 + /* atim */ |
1721 | 2 + 8]; /* extended rates */ | 1724 | 2 + 8]; /* extended rates */ |
1722 | u8 *fake = fake_ie; | 1725 | u8 *fake = fake_ie; |
1726 | struct cfg80211_bss *bss; | ||
1723 | 1727 | ||
1724 | lbs_deb_enter(LBS_DEB_CFG80211); | 1728 | lbs_deb_enter(LBS_DEB_CFG80211); |
1725 | 1729 | ||
@@ -1763,14 +1767,15 @@ static void lbs_join_post(struct lbs_private *priv, | |||
1763 | *fake++ = 0x6c; | 1767 | *fake++ = 0x6c; |
1764 | lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie); | 1768 | lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie); |
1765 | 1769 | ||
1766 | cfg80211_inform_bss(priv->wdev->wiphy, | 1770 | bss = cfg80211_inform_bss(priv->wdev->wiphy, |
1767 | params->channel, | 1771 | params->channel, |
1768 | bssid, | 1772 | bssid, |
1769 | 0, | 1773 | 0, |
1770 | capability, | 1774 | capability, |
1771 | params->beacon_interval, | 1775 | params->beacon_interval, |
1772 | fake_ie, fake - fake_ie, | 1776 | fake_ie, fake - fake_ie, |
1773 | 0, GFP_KERNEL); | 1777 | 0, GFP_KERNEL); |
1778 | cfg80211_put_bss(bss); | ||
1774 | 1779 | ||
1775 | memcpy(priv->wdev->ssid, params->ssid, params->ssid_len); | 1780 | memcpy(priv->wdev->ssid, params->ssid, params->ssid_len); |
1776 | priv->wdev->ssid_len = params->ssid_len; | 1781 | priv->wdev->ssid_len = params->ssid_len; |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 523ad55a2885..6cf6d6d25e21 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -1748,6 +1748,8 @@ static int __init init_mac80211_hwsim(void) | |||
1748 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 1748 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | |
1749 | IEEE80211_HW_AMPDU_AGGREGATION; | 1749 | IEEE80211_HW_AMPDU_AGGREGATION; |
1750 | 1750 | ||
1751 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; | ||
1752 | |||
1751 | /* ask mac80211 to reserve space for magic */ | 1753 | /* ask mac80211 to reserve space for magic */ |
1752 | hw->vif_data_size = sizeof(struct hwsim_vif_priv); | 1754 | hw->vif_data_size = sizeof(struct hwsim_vif_priv); |
1753 | hw->sta_data_size = sizeof(struct hwsim_sta_priv); | 1755 | hw->sta_data_size = sizeof(struct hwsim_sta_priv); |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 7aa9aa0ac958..681d3f2a4c28 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c | |||
@@ -33,7 +33,7 @@ | |||
33 | * Since the buffer is linear, the function uses rotation to simulate | 33 | * Since the buffer is linear, the function uses rotation to simulate |
34 | * circular buffer. | 34 | * circular buffer. |
35 | */ | 35 | */ |
36 | static int | 36 | static void |
37 | mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, | 37 | mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, |
38 | struct mwifiex_rx_reorder_tbl | 38 | struct mwifiex_rx_reorder_tbl |
39 | *rx_reor_tbl_ptr, int start_win) | 39 | *rx_reor_tbl_ptr, int start_win) |
@@ -71,8 +71,6 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, | |||
71 | 71 | ||
72 | rx_reor_tbl_ptr->start_win = start_win; | 72 | rx_reor_tbl_ptr->start_win = start_win; |
73 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); | 73 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); |
74 | |||
75 | return 0; | ||
76 | } | 74 | } |
77 | 75 | ||
78 | /* | 76 | /* |
@@ -83,7 +81,7 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, | |||
83 | * Since the buffer is linear, the function uses rotation to simulate | 81 | * Since the buffer is linear, the function uses rotation to simulate |
84 | * circular buffer. | 82 | * circular buffer. |
85 | */ | 83 | */ |
86 | static int | 84 | static void |
87 | mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, | 85 | mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, |
88 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr) | 86 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr) |
89 | { | 87 | { |
@@ -119,7 +117,6 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, | |||
119 | rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i) | 117 | rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i) |
120 | &(MAX_TID_VALUE - 1); | 118 | &(MAX_TID_VALUE - 1); |
121 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); | 119 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); |
122 | return 0; | ||
123 | } | 120 | } |
124 | 121 | ||
125 | /* | 122 | /* |
@@ -405,7 +402,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, | |||
405 | u8 *ta, u8 pkt_type, void *payload) | 402 | u8 *ta, u8 pkt_type, void *payload) |
406 | { | 403 | { |
407 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; | 404 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; |
408 | int start_win, end_win, win_size, ret; | 405 | int start_win, end_win, win_size; |
409 | u16 pkt_index; | 406 | u16 pkt_index; |
410 | 407 | ||
411 | rx_reor_tbl_ptr = | 408 | rx_reor_tbl_ptr = |
@@ -452,11 +449,8 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, | |||
452 | start_win = (end_win - win_size) + 1; | 449 | start_win = (end_win - win_size) + 1; |
453 | else | 450 | else |
454 | start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1; | 451 | start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1; |
455 | ret = mwifiex_11n_dispatch_pkt_until_start_win(priv, | 452 | mwifiex_11n_dispatch_pkt_until_start_win(priv, |
456 | rx_reor_tbl_ptr, start_win); | 453 | rx_reor_tbl_ptr, start_win); |
457 | |||
458 | if (ret) | ||
459 | return ret; | ||
460 | } | 454 | } |
461 | 455 | ||
462 | if (pkt_type != PKT_TYPE_BAR) { | 456 | if (pkt_type != PKT_TYPE_BAR) { |
@@ -475,9 +469,9 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, | |||
475 | * Dispatch all packets sequentially from start_win until a | 469 | * Dispatch all packets sequentially from start_win until a |
476 | * hole is found and adjust the start_win appropriately | 470 | * hole is found and adjust the start_win appropriately |
477 | */ | 471 | */ |
478 | ret = mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr); | 472 | mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr); |
479 | 473 | ||
480 | return ret; | 474 | return 0; |
481 | } | 475 | } |
482 | 476 | ||
483 | /* | 477 | /* |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 462c71067bfb..e9ab9a3fbe9c 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -780,6 +780,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) | |||
780 | { | 780 | { |
781 | struct ieee80211_channel *chan; | 781 | struct ieee80211_channel *chan; |
782 | struct mwifiex_bss_info bss_info; | 782 | struct mwifiex_bss_info bss_info; |
783 | struct cfg80211_bss *bss; | ||
783 | int ie_len; | 784 | int ie_len; |
784 | u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)]; | 785 | u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)]; |
785 | enum ieee80211_band band; | 786 | enum ieee80211_band band; |
@@ -800,9 +801,10 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) | |||
800 | ieee80211_channel_to_frequency(bss_info.bss_chan, | 801 | ieee80211_channel_to_frequency(bss_info.bss_chan, |
801 | band)); | 802 | band)); |
802 | 803 | ||
803 | cfg80211_inform_bss(priv->wdev->wiphy, chan, | 804 | bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, |
804 | bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, | 805 | bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, |
805 | 0, ie_buf, ie_len, 0, GFP_KERNEL); | 806 | 0, ie_buf, ie_len, 0, GFP_KERNEL); |
807 | cfg80211_put_bss(bss); | ||
806 | memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); | 808 | memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); |
807 | 809 | ||
808 | return 0; | 810 | return 0; |
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 0cc5d73cb0c1..35cb29cbd96e 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
@@ -673,7 +673,7 @@ struct host_cmd_ds_802_11_ad_hoc_start { | |||
673 | union ieee_types_phy_param_set phy_param_set; | 673 | union ieee_types_phy_param_set phy_param_set; |
674 | u16 reserved1; | 674 | u16 reserved1; |
675 | __le16 cap_info_bitmap; | 675 | __le16 cap_info_bitmap; |
676 | u8 DataRate[HOSTCMD_SUPPORTED_RATES]; | 676 | u8 data_rate[HOSTCMD_SUPPORTED_RATES]; |
677 | } __packed; | 677 | } __packed; |
678 | 678 | ||
679 | struct host_cmd_ds_802_11_ad_hoc_result { | 679 | struct host_cmd_ds_802_11_ad_hoc_result { |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index d792b3fb7c16..26940455255b 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -187,8 +187,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) | |||
187 | struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = NULL; | 187 | struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = NULL; |
188 | 188 | ||
189 | skb_put(adapter->sleep_cfm, sizeof(struct mwifiex_opt_sleep_confirm)); | 189 | skb_put(adapter->sleep_cfm, sizeof(struct mwifiex_opt_sleep_confirm)); |
190 | sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *) | ||
191 | (adapter->sleep_cfm->data); | ||
192 | 190 | ||
193 | adapter->cmd_sent = false; | 191 | adapter->cmd_sent = false; |
194 | 192 | ||
@@ -254,6 +252,8 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) | |||
254 | mwifiex_wmm_init(adapter); | 252 | mwifiex_wmm_init(adapter); |
255 | 253 | ||
256 | if (adapter->sleep_cfm) { | 254 | if (adapter->sleep_cfm) { |
255 | sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *) | ||
256 | adapter->sleep_cfm->data; | ||
257 | memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len); | 257 | memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len); |
258 | sleep_cfm_buf->command = | 258 | sleep_cfm_buf->command = |
259 | cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH); | 259 | cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH); |
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 62b4c2938608..1c4981367e50 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
@@ -724,8 +724,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
724 | u32 cmd_append_size = 0; | 724 | u32 cmd_append_size = 0; |
725 | u32 i; | 725 | u32 i; |
726 | u16 tmp_cap; | 726 | u16 tmp_cap; |
727 | uint16_t ht_cap_info; | ||
728 | struct mwifiex_ie_types_chan_list_param_set *chan_tlv; | 727 | struct mwifiex_ie_types_chan_list_param_set *chan_tlv; |
728 | u8 radio_type; | ||
729 | 729 | ||
730 | struct mwifiex_ie_types_htcap *ht_cap; | 730 | struct mwifiex_ie_types_htcap *ht_cap; |
731 | struct mwifiex_ie_types_htinfo *ht_info; | 731 | struct mwifiex_ie_types_htinfo *ht_info; |
@@ -837,8 +837,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
837 | bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL; | 837 | bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL; |
838 | } | 838 | } |
839 | 839 | ||
840 | memset(adhoc_start->DataRate, 0, sizeof(adhoc_start->DataRate)); | 840 | memset(adhoc_start->data_rate, 0, sizeof(adhoc_start->data_rate)); |
841 | mwifiex_get_active_data_rates(priv, adhoc_start->DataRate); | 841 | mwifiex_get_active_data_rates(priv, adhoc_start->data_rate); |
842 | if ((adapter->adhoc_start_band & BAND_G) && | 842 | if ((adapter->adhoc_start_band & BAND_G) && |
843 | (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { | 843 | (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { |
844 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, | 844 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, |
@@ -850,20 +850,19 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
850 | } | 850 | } |
851 | } | 851 | } |
852 | /* Find the last non zero */ | 852 | /* Find the last non zero */ |
853 | for (i = 0; i < sizeof(adhoc_start->DataRate) && | 853 | for (i = 0; i < sizeof(adhoc_start->data_rate); i++) |
854 | adhoc_start->DataRate[i]; | 854 | if (!adhoc_start->data_rate[i]) |
855 | i++) | 855 | break; |
856 | ; | ||
857 | 856 | ||
858 | priv->curr_bss_params.num_of_rates = i; | 857 | priv->curr_bss_params.num_of_rates = i; |
859 | 858 | ||
860 | /* Copy the ad-hoc creating rates into Current BSS rate structure */ | 859 | /* Copy the ad-hoc creating rates into Current BSS rate structure */ |
861 | memcpy(&priv->curr_bss_params.data_rates, | 860 | memcpy(&priv->curr_bss_params.data_rates, |
862 | &adhoc_start->DataRate, priv->curr_bss_params.num_of_rates); | 861 | &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates); |
863 | 862 | ||
864 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n", | 863 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n", |
865 | adhoc_start->DataRate[0], adhoc_start->DataRate[1], | 864 | adhoc_start->data_rate[0], adhoc_start->data_rate[1], |
866 | adhoc_start->DataRate[2], adhoc_start->DataRate[3]); | 865 | adhoc_start->data_rate[2], adhoc_start->data_rate[3]); |
867 | 866 | ||
868 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n"); | 867 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n"); |
869 | 868 | ||
@@ -914,55 +913,40 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
914 | } | 913 | } |
915 | 914 | ||
916 | if (adapter->adhoc_11n_enabled) { | 915 | if (adapter->adhoc_11n_enabled) { |
917 | { | 916 | /* Fill HT CAPABILITY */ |
918 | ht_cap = (struct mwifiex_ie_types_htcap *) pos; | 917 | ht_cap = (struct mwifiex_ie_types_htcap *) pos; |
919 | memset(ht_cap, 0, | 918 | memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); |
920 | sizeof(struct mwifiex_ie_types_htcap)); | 919 | ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); |
921 | ht_cap->header.type = | 920 | ht_cap->header.len = |
922 | cpu_to_le16(WLAN_EID_HT_CAPABILITY); | 921 | cpu_to_le16(sizeof(struct ieee80211_ht_cap)); |
923 | ht_cap->header.len = | 922 | radio_type = mwifiex_band_to_radio_type( |
924 | cpu_to_le16(sizeof(struct ieee80211_ht_cap)); | 923 | priv->adapter->config_bands); |
925 | ht_cap_info = le16_to_cpu(ht_cap->ht_cap.cap_info); | 924 | mwifiex_fill_cap_info(priv, radio_type, ht_cap); |
926 | 925 | ||
927 | ht_cap_info |= IEEE80211_HT_CAP_SGI_20; | 926 | pos += sizeof(struct mwifiex_ie_types_htcap); |
928 | if (adapter->chan_offset) { | 927 | cmd_append_size += |
929 | ht_cap_info |= IEEE80211_HT_CAP_SGI_40; | 928 | sizeof(struct mwifiex_ie_types_htcap); |
930 | ht_cap_info |= IEEE80211_HT_CAP_DSSSCCK40; | ||
931 | ht_cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
932 | SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); | ||
933 | } | ||
934 | 929 | ||
935 | ht_cap->ht_cap.ampdu_params_info | 930 | /* Fill HT INFORMATION */ |
936 | = IEEE80211_HT_MAX_AMPDU_64K; | 931 | ht_info = (struct mwifiex_ie_types_htinfo *) pos; |
937 | ht_cap->ht_cap.mcs.rx_mask[0] = 0xff; | 932 | memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo)); |
938 | pos += sizeof(struct mwifiex_ie_types_htcap); | 933 | ht_info->header.type = cpu_to_le16(WLAN_EID_HT_INFORMATION); |
939 | cmd_append_size += | 934 | ht_info->header.len = |
940 | sizeof(struct mwifiex_ie_types_htcap); | 935 | cpu_to_le16(sizeof(struct ieee80211_ht_info)); |
941 | } | 936 | |
942 | { | 937 | ht_info->ht_info.control_chan = |
943 | ht_info = (struct mwifiex_ie_types_htinfo *) pos; | 938 | (u8) priv->curr_bss_params.bss_descriptor.channel; |
944 | memset(ht_info, 0, | 939 | if (adapter->chan_offset) { |
945 | sizeof(struct mwifiex_ie_types_htinfo)); | 940 | ht_info->ht_info.ht_param = adapter->chan_offset; |
946 | ht_info->header.type = | 941 | ht_info->ht_info.ht_param |= |
947 | cpu_to_le16(WLAN_EID_HT_INFORMATION); | ||
948 | ht_info->header.len = | ||
949 | cpu_to_le16(sizeof(struct ieee80211_ht_info)); | ||
950 | ht_info->ht_info.control_chan = | ||
951 | (u8) priv->curr_bss_params.bss_descriptor. | ||
952 | channel; | ||
953 | if (adapter->chan_offset) { | ||
954 | ht_info->ht_info.ht_param = | ||
955 | adapter->chan_offset; | ||
956 | ht_info->ht_info.ht_param |= | ||
957 | IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; | 942 | IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; |
958 | } | ||
959 | ht_info->ht_info.operation_mode = | ||
960 | cpu_to_le16(IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | ||
961 | ht_info->ht_info.basic_set[0] = 0xff; | ||
962 | pos += sizeof(struct mwifiex_ie_types_htinfo); | ||
963 | cmd_append_size += | ||
964 | sizeof(struct mwifiex_ie_types_htinfo); | ||
965 | } | 943 | } |
944 | ht_info->ht_info.operation_mode = | ||
945 | cpu_to_le16(IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | ||
946 | ht_info->ht_info.basic_set[0] = 0xff; | ||
947 | pos += sizeof(struct mwifiex_ie_types_htinfo); | ||
948 | cmd_append_size += | ||
949 | sizeof(struct mwifiex_ie_types_htinfo); | ||
966 | } | 950 | } |
967 | 951 | ||
968 | cmd->size = cpu_to_le16((u16) | 952 | cmd->size = cpu_to_le16((u16) |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index d34acf082d3a..a2f32008f9a8 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c | |||
@@ -386,7 +386,6 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) | |||
386 | card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL); | 386 | card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL); |
387 | if (!card->txbd_ring_vbase) { | 387 | if (!card->txbd_ring_vbase) { |
388 | dev_err(adapter->dev, "Unable to allocate buffer for txbd ring.\n"); | 388 | dev_err(adapter->dev, "Unable to allocate buffer for txbd ring.\n"); |
389 | kfree(card->txbd_ring_vbase); | ||
390 | return -1; | 389 | return -1; |
391 | } | 390 | } |
392 | card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase); | 391 | card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase); |
@@ -1229,9 +1228,12 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, | |||
1229 | if (!skb) | 1228 | if (!skb) |
1230 | return 0; | 1229 | return 0; |
1231 | 1230 | ||
1232 | if (rdptr >= MWIFIEX_MAX_EVT_BD) | 1231 | if (rdptr >= MWIFIEX_MAX_EVT_BD) { |
1233 | dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n", | 1232 | dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n", |
1234 | rdptr); | 1233 | rdptr); |
1234 | ret = -EINVAL; | ||
1235 | goto done; | ||
1236 | } | ||
1235 | 1237 | ||
1236 | /* Read the event ring write pointer set by firmware */ | 1238 | /* Read the event ring write pointer set by firmware */ |
1237 | if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { | 1239 | if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { |
@@ -1672,9 +1674,8 @@ static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type, | |||
1672 | struct sk_buff *skb, | 1674 | struct sk_buff *skb, |
1673 | struct mwifiex_tx_param *tx_param) | 1675 | struct mwifiex_tx_param *tx_param) |
1674 | { | 1676 | { |
1675 | if (!adapter || !skb) { | 1677 | if (!skb) { |
1676 | dev_err(adapter->dev, "Invalid parameter in %s <%p, %p>\n", | 1678 | dev_err(adapter->dev, "Passed NULL skb to %s\n", __func__); |
1677 | __func__, adapter, skb); | ||
1678 | return -1; | 1679 | return -1; |
1679 | } | 1680 | } |
1680 | 1681 | ||
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 8d3ab378662b..b8b9d37b01a9 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -1537,11 +1537,6 @@ done: | |||
1537 | return 0; | 1537 | return 0; |
1538 | } | 1538 | } |
1539 | 1539 | ||
1540 | static void mwifiex_free_bss_priv(struct cfg80211_bss *bss) | ||
1541 | { | ||
1542 | kfree(bss->priv); | ||
1543 | } | ||
1544 | |||
1545 | /* | 1540 | /* |
1546 | * This function handles the command response of scan. | 1541 | * This function handles the command response of scan. |
1547 | * | 1542 | * |
@@ -1767,7 +1762,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1767 | cap_info_bitmap, beacon_period, | 1762 | cap_info_bitmap, beacon_period, |
1768 | ie_buf, ie_len, rssi, GFP_KERNEL); | 1763 | ie_buf, ie_len, rssi, GFP_KERNEL); |
1769 | *(u8 *)bss->priv = band; | 1764 | *(u8 *)bss->priv = band; |
1770 | bss->free_priv = mwifiex_free_bss_priv; | 1765 | cfg80211_put_bss(bss); |
1771 | 1766 | ||
1772 | if (priv->media_connected && !memcmp(bssid, | 1767 | if (priv->media_connected && !memcmp(bssid, |
1773 | priv->curr_bss_params.bss_descriptor | 1768 | priv->curr_bss_params.bss_descriptor |
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 283171bbcedf..ffaf3f3a57df 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
@@ -1630,14 +1630,14 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter) | |||
1630 | card->mpa_tx.pkt_cnt = 0; | 1630 | card->mpa_tx.pkt_cnt = 0; |
1631 | card->mpa_tx.start_port = 0; | 1631 | card->mpa_tx.start_port = 0; |
1632 | 1632 | ||
1633 | card->mpa_tx.enabled = 0; | 1633 | card->mpa_tx.enabled = 1; |
1634 | card->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; | 1634 | card->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; |
1635 | 1635 | ||
1636 | card->mpa_rx.buf_len = 0; | 1636 | card->mpa_rx.buf_len = 0; |
1637 | card->mpa_rx.pkt_cnt = 0; | 1637 | card->mpa_rx.pkt_cnt = 0; |
1638 | card->mpa_rx.start_port = 0; | 1638 | card->mpa_rx.start_port = 0; |
1639 | 1639 | ||
1640 | card->mpa_rx.enabled = 0; | 1640 | card->mpa_rx.enabled = 1; |
1641 | card->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; | 1641 | card->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; |
1642 | 1642 | ||
1643 | /* Allocate buffers for SDIO MP-A */ | 1643 | /* Allocate buffers for SDIO MP-A */ |
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c index 27430512f7cd..5e1ef7e5da4f 100644 --- a/drivers/net/wireless/mwifiex/sta_rx.c +++ b/drivers/net/wireless/mwifiex/sta_rx.c | |||
@@ -126,6 +126,9 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, | |||
126 | u16 rx_pkt_type; | 126 | u16 rx_pkt_type; |
127 | struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; | 127 | struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; |
128 | 128 | ||
129 | if (!priv) | ||
130 | return -1; | ||
131 | |||
129 | local_rx_pd = (struct rxpd *) (skb->data); | 132 | local_rx_pd = (struct rxpd *) (skb->data); |
130 | rx_pkt_type = local_rx_pd->rx_pkt_type; | 133 | rx_pkt_type = local_rx_pd->rx_pkt_type; |
131 | 134 | ||
@@ -189,12 +192,11 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, | |||
189 | (u8) local_rx_pd->rx_pkt_type, | 192 | (u8) local_rx_pd->rx_pkt_type, |
190 | skb); | 193 | skb); |
191 | 194 | ||
192 | if (ret || (rx_pkt_type == PKT_TYPE_BAR)) { | 195 | if (ret || (rx_pkt_type == PKT_TYPE_BAR)) |
193 | if (priv && (ret == -1)) | ||
194 | priv->stats.rx_dropped++; | ||
195 | |||
196 | dev_kfree_skb_any(skb); | 196 | dev_kfree_skb_any(skb); |
197 | } | 197 | |
198 | if (ret) | ||
199 | priv->stats.rx_dropped++; | ||
198 | 200 | ||
199 | return ret; | 201 | return ret; |
200 | } | 202 | } |
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c index e99ca1c1e0d8..96e39edfec77 100644 --- a/drivers/net/wireless/orinoco/scan.c +++ b/drivers/net/wireless/orinoco/scan.c | |||
@@ -76,6 +76,7 @@ static void orinoco_add_hostscan_result(struct orinoco_private *priv, | |||
76 | { | 76 | { |
77 | struct wiphy *wiphy = priv_to_wiphy(priv); | 77 | struct wiphy *wiphy = priv_to_wiphy(priv); |
78 | struct ieee80211_channel *channel; | 78 | struct ieee80211_channel *channel; |
79 | struct cfg80211_bss *cbss; | ||
79 | u8 *ie; | 80 | u8 *ie; |
80 | u8 ie_buf[46]; | 81 | u8 ie_buf[46]; |
81 | u64 timestamp; | 82 | u64 timestamp; |
@@ -121,9 +122,10 @@ static void orinoco_add_hostscan_result(struct orinoco_private *priv, | |||
121 | beacon_interval = le16_to_cpu(bss->a.beacon_interv); | 122 | beacon_interval = le16_to_cpu(bss->a.beacon_interv); |
122 | signal = SIGNAL_TO_MBM(le16_to_cpu(bss->a.level)); | 123 | signal = SIGNAL_TO_MBM(le16_to_cpu(bss->a.level)); |
123 | 124 | ||
124 | cfg80211_inform_bss(wiphy, channel, bss->a.bssid, timestamp, | 125 | cbss = cfg80211_inform_bss(wiphy, channel, bss->a.bssid, timestamp, |
125 | capability, beacon_interval, ie_buf, ie_len, | 126 | capability, beacon_interval, ie_buf, ie_len, |
126 | signal, GFP_KERNEL); | 127 | signal, GFP_KERNEL); |
128 | cfg80211_put_bss(cbss); | ||
127 | } | 129 | } |
128 | 130 | ||
129 | void orinoco_add_extscan_result(struct orinoco_private *priv, | 131 | void orinoco_add_extscan_result(struct orinoco_private *priv, |
@@ -132,6 +134,7 @@ void orinoco_add_extscan_result(struct orinoco_private *priv, | |||
132 | { | 134 | { |
133 | struct wiphy *wiphy = priv_to_wiphy(priv); | 135 | struct wiphy *wiphy = priv_to_wiphy(priv); |
134 | struct ieee80211_channel *channel; | 136 | struct ieee80211_channel *channel; |
137 | struct cfg80211_bss *cbss; | ||
135 | const u8 *ie; | 138 | const u8 *ie; |
136 | u64 timestamp; | 139 | u64 timestamp; |
137 | s32 signal; | 140 | s32 signal; |
@@ -152,9 +155,10 @@ void orinoco_add_extscan_result(struct orinoco_private *priv, | |||
152 | ie = bss->data; | 155 | ie = bss->data; |
153 | signal = SIGNAL_TO_MBM(bss->level); | 156 | signal = SIGNAL_TO_MBM(bss->level); |
154 | 157 | ||
155 | cfg80211_inform_bss(wiphy, channel, bss->bssid, timestamp, | 158 | cbss = cfg80211_inform_bss(wiphy, channel, bss->bssid, timestamp, |
156 | capability, beacon_interval, ie, ie_len, | 159 | capability, beacon_interval, ie, ie_len, |
157 | signal, GFP_KERNEL); | 160 | signal, GFP_KERNEL); |
161 | cfg80211_put_bss(cbss); | ||
158 | } | 162 | } |
159 | 163 | ||
160 | void orinoco_add_hostscan_results(struct orinoco_private *priv, | 164 | void orinoco_add_hostscan_results(struct orinoco_private *priv, |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 0c13840a7de5..620e3c0e88e0 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -414,6 +414,7 @@ struct ndis_80211_pmkid { | |||
414 | #define RNDIS_WLAN_ALG_TKIP (1<<1) | 414 | #define RNDIS_WLAN_ALG_TKIP (1<<1) |
415 | #define RNDIS_WLAN_ALG_CCMP (1<<2) | 415 | #define RNDIS_WLAN_ALG_CCMP (1<<2) |
416 | 416 | ||
417 | #define RNDIS_WLAN_NUM_KEYS 4 | ||
417 | #define RNDIS_WLAN_KEY_MGMT_NONE 0 | 418 | #define RNDIS_WLAN_KEY_MGMT_NONE 0 |
418 | #define RNDIS_WLAN_KEY_MGMT_802_1X (1<<0) | 419 | #define RNDIS_WLAN_KEY_MGMT_802_1X (1<<0) |
419 | #define RNDIS_WLAN_KEY_MGMT_PSK (1<<1) | 420 | #define RNDIS_WLAN_KEY_MGMT_PSK (1<<1) |
@@ -516,7 +517,7 @@ struct rndis_wlan_private { | |||
516 | 517 | ||
517 | /* encryption stuff */ | 518 | /* encryption stuff */ |
518 | int encr_tx_key_index; | 519 | int encr_tx_key_index; |
519 | struct rndis_wlan_encr_key encr_keys[4]; | 520 | struct rndis_wlan_encr_key encr_keys[RNDIS_WLAN_NUM_KEYS]; |
520 | int wpa_version; | 521 | int wpa_version; |
521 | 522 | ||
522 | u8 command_buffer[COMMAND_BUFFER_SIZE]; | 523 | u8 command_buffer[COMMAND_BUFFER_SIZE]; |
@@ -1535,6 +1536,9 @@ static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid) | |||
1535 | bool is_wpa; | 1536 | bool is_wpa; |
1536 | int ret; | 1537 | int ret; |
1537 | 1538 | ||
1539 | if (index >= RNDIS_WLAN_NUM_KEYS) | ||
1540 | return -ENOENT; | ||
1541 | |||
1538 | if (priv->encr_keys[index].len == 0) | 1542 | if (priv->encr_keys[index].len == 0) |
1539 | return 0; | 1543 | return 0; |
1540 | 1544 | ||
@@ -1972,11 +1976,12 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, | |||
1972 | return ret; | 1976 | return ret; |
1973 | } | 1977 | } |
1974 | 1978 | ||
1975 | static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, | 1979 | static bool rndis_bss_info_update(struct usbnet *usbdev, |
1976 | struct ndis_80211_bssid_ex *bssid) | 1980 | struct ndis_80211_bssid_ex *bssid) |
1977 | { | 1981 | { |
1978 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1982 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1979 | struct ieee80211_channel *channel; | 1983 | struct ieee80211_channel *channel; |
1984 | struct cfg80211_bss *bss; | ||
1980 | s32 signal; | 1985 | s32 signal; |
1981 | u64 timestamp; | 1986 | u64 timestamp; |
1982 | u16 capability; | 1987 | u16 capability; |
@@ -2015,9 +2020,12 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, | |||
2015 | capability = le16_to_cpu(fixed->capabilities); | 2020 | capability = le16_to_cpu(fixed->capabilities); |
2016 | beacon_interval = le16_to_cpu(fixed->beacon_interval); | 2021 | beacon_interval = le16_to_cpu(fixed->beacon_interval); |
2017 | 2022 | ||
2018 | return cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac, | 2023 | bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac, |
2019 | timestamp, capability, beacon_interval, ie, ie_len, signal, | 2024 | timestamp, capability, beacon_interval, ie, ie_len, signal, |
2020 | GFP_KERNEL); | 2025 | GFP_KERNEL); |
2026 | cfg80211_put_bss(bss); | ||
2027 | |||
2028 | return (bss != NULL); | ||
2021 | } | 2029 | } |
2022 | 2030 | ||
2023 | static struct ndis_80211_bssid_ex *next_bssid_list_item( | 2031 | static struct ndis_80211_bssid_ex *next_bssid_list_item( |
@@ -2451,6 +2459,9 @@ static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, | |||
2451 | 2459 | ||
2452 | netdev_dbg(usbdev->net, "%s(%i)\n", __func__, key_index); | 2460 | netdev_dbg(usbdev->net, "%s(%i)\n", __func__, key_index); |
2453 | 2461 | ||
2462 | if (key_index >= RNDIS_WLAN_NUM_KEYS) | ||
2463 | return -ENOENT; | ||
2464 | |||
2454 | priv->encr_tx_key_index = key_index; | 2465 | priv->encr_tx_key_index = key_index; |
2455 | 2466 | ||
2456 | if (is_wpa_key(priv, key_index)) | 2467 | if (is_wpa_key(priv, key_index)) |
@@ -2641,6 +2652,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, | |||
2641 | struct ieee80211_channel *channel; | 2652 | struct ieee80211_channel *channel; |
2642 | struct ndis_80211_conf config; | 2653 | struct ndis_80211_conf config; |
2643 | struct ndis_80211_ssid ssid; | 2654 | struct ndis_80211_ssid ssid; |
2655 | struct cfg80211_bss *bss; | ||
2644 | s32 signal; | 2656 | s32 signal; |
2645 | u64 timestamp; | 2657 | u64 timestamp; |
2646 | u16 capability; | 2658 | u16 capability; |
@@ -2714,9 +2726,10 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, | |||
2714 | bssid, (u32)timestamp, capability, beacon_interval, ie_len, | 2726 | bssid, (u32)timestamp, capability, beacon_interval, ie_len, |
2715 | ssid.essid, signal); | 2727 | ssid.essid, signal); |
2716 | 2728 | ||
2717 | cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, | 2729 | bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, |
2718 | timestamp, capability, beacon_interval, ie_buf, ie_len, | 2730 | timestamp, capability, beacon_interval, ie_buf, ie_len, |
2719 | signal, GFP_KERNEL); | 2731 | signal, GFP_KERNEL); |
2732 | cfg80211_put_bss(bss); | ||
2720 | } | 2733 | } |
2721 | 2734 | ||
2722 | /* | 2735 | /* |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index c244f2f1b83f..94a3e1706158 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | |||
@@ -275,6 +275,8 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
275 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8191, rtl92cu_hal_cfg)}, | 275 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8191, rtl92cu_hal_cfg)}, |
276 | 276 | ||
277 | /****** 8188CU ********/ | 277 | /****** 8188CU ********/ |
278 | /* RTL8188CTV */ | ||
279 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x018a, rtl92cu_hal_cfg)}, | ||
278 | /* 8188CE-VAU USB minCard */ | 280 | /* 8188CE-VAU USB minCard */ |
279 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8170, rtl92cu_hal_cfg)}, | 281 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8170, rtl92cu_hal_cfg)}, |
280 | /* 8188cu 1*1 dongle */ | 282 | /* 8188cu 1*1 dongle */ |
@@ -291,14 +293,14 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
291 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817e, rtl92cu_hal_cfg)}, | 293 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817e, rtl92cu_hal_cfg)}, |
292 | /* 8188RU in Alfa AWUS036NHR */ | 294 | /* 8188RU in Alfa AWUS036NHR */ |
293 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)}, | 295 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)}, |
296 | /* RTL8188CUS-VL */ | ||
297 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x818a, rtl92cu_hal_cfg)}, | ||
294 | /* 8188 Combo for BC4 */ | 298 | /* 8188 Combo for BC4 */ |
295 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)}, | 299 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)}, |
296 | 300 | ||
297 | /****** 8192CU ********/ | 301 | /****** 8192CU ********/ |
298 | /* 8191cu 1*2 */ | ||
299 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8177, rtl92cu_hal_cfg)}, | ||
300 | /* 8192cu 2*2 */ | 302 | /* 8192cu 2*2 */ |
301 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817b, rtl92cu_hal_cfg)}, | 303 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8178, rtl92cu_hal_cfg)}, |
302 | /* 8192CE-VAU USB minCard */ | 304 | /* 8192CE-VAU USB minCard */ |
303 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817c, rtl92cu_hal_cfg)}, | 305 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817c, rtl92cu_hal_cfg)}, |
304 | 306 | ||
@@ -309,13 +311,17 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
309 | {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ | 311 | {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ |
310 | {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ | 312 | {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ |
311 | {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ | 313 | {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ |
312 | {RTL_USB_DEVICE(0x0Df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ | 314 | {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ |
315 | {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ | ||
313 | {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ | 316 | {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ |
314 | /* HP - Lite-On ,8188CUS Slim Combo */ | 317 | /* HP - Lite-On ,8188CUS Slim Combo */ |
315 | {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, | 318 | {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, |
316 | {RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */ | 319 | {RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */ |
317 | {RTL_USB_DEVICE(0x2001, 0x3308, rtl92cu_hal_cfg)}, /*D-Link - Alpha*/ | 320 | {RTL_USB_DEVICE(0x2001, 0x3308, rtl92cu_hal_cfg)}, /*D-Link - Alpha*/ |
321 | {RTL_USB_DEVICE(0x2019, 0x4902, rtl92cu_hal_cfg)}, /*Planex - Etop*/ | ||
318 | {RTL_USB_DEVICE(0x2019, 0xab2a, rtl92cu_hal_cfg)}, /*Planex - Abocom*/ | 322 | {RTL_USB_DEVICE(0x2019, 0xab2a, rtl92cu_hal_cfg)}, /*Planex - Abocom*/ |
323 | /*SW-WF02-AD15 -Abocom*/ | ||
324 | {RTL_USB_DEVICE(0x2019, 0xab2e, rtl92cu_hal_cfg)}, | ||
319 | {RTL_USB_DEVICE(0x2019, 0xed17, rtl92cu_hal_cfg)}, /*PCI - Edimax*/ | 325 | {RTL_USB_DEVICE(0x2019, 0xed17, rtl92cu_hal_cfg)}, /*PCI - Edimax*/ |
320 | {RTL_USB_DEVICE(0x20f4, 0x648b, rtl92cu_hal_cfg)}, /*TRENDnet - Cameo*/ | 326 | {RTL_USB_DEVICE(0x20f4, 0x648b, rtl92cu_hal_cfg)}, /*TRENDnet - Cameo*/ |
321 | {RTL_USB_DEVICE(0x7392, 0x7811, rtl92cu_hal_cfg)}, /*Edimax - Edimax*/ | 327 | {RTL_USB_DEVICE(0x7392, 0x7811, rtl92cu_hal_cfg)}, /*Edimax - Edimax*/ |
@@ -326,14 +332,36 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
326 | {RTL_USB_DEVICE(0x4855, 0x0091, rtl92cu_hal_cfg)}, /* NetweeN-Feixun */ | 332 | {RTL_USB_DEVICE(0x4855, 0x0091, rtl92cu_hal_cfg)}, /* NetweeN-Feixun */ |
327 | {RTL_USB_DEVICE(0x9846, 0x9041, rtl92cu_hal_cfg)}, /* Netgear Cameo */ | 333 | {RTL_USB_DEVICE(0x9846, 0x9041, rtl92cu_hal_cfg)}, /* Netgear Cameo */ |
328 | 334 | ||
335 | /****** 8188 RU ********/ | ||
336 | /* Netcore */ | ||
337 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x317f, rtl92cu_hal_cfg)}, | ||
338 | |||
339 | /****** 8188CUS Slim Solo********/ | ||
340 | {RTL_USB_DEVICE(0x04f2, 0xaff7, rtl92cu_hal_cfg)}, /*Xavi*/ | ||
341 | {RTL_USB_DEVICE(0x04f2, 0xaff9, rtl92cu_hal_cfg)}, /*Xavi*/ | ||
342 | {RTL_USB_DEVICE(0x04f2, 0xaffa, rtl92cu_hal_cfg)}, /*Xavi*/ | ||
343 | |||
344 | /****** 8188CUS Slim Combo ********/ | ||
345 | {RTL_USB_DEVICE(0x04f2, 0xaff8, rtl92cu_hal_cfg)}, /*Xavi*/ | ||
346 | {RTL_USB_DEVICE(0x04f2, 0xaffb, rtl92cu_hal_cfg)}, /*Xavi*/ | ||
347 | {RTL_USB_DEVICE(0x04f2, 0xaffc, rtl92cu_hal_cfg)}, /*Xavi*/ | ||
348 | {RTL_USB_DEVICE(0x2019, 0x1201, rtl92cu_hal_cfg)}, /*Planex-Vencer*/ | ||
349 | |||
329 | /****** 8192CU ********/ | 350 | /****** 8192CU ********/ |
351 | {RTL_USB_DEVICE(0x050d, 0x2102, rtl92cu_hal_cfg)}, /*Belcom-Sercomm*/ | ||
352 | {RTL_USB_DEVICE(0x050d, 0x2103, rtl92cu_hal_cfg)}, /*Belcom-Edimax*/ | ||
330 | {RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/ | 353 | {RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/ |
331 | {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/ | 354 | {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/ |
332 | {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ | 355 | {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ |
356 | {RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/ | ||
357 | {RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ | ||
358 | {RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/ | ||
359 | {RTL_USB_DEVICE(0x0e66, 0x0019, rtl92cu_hal_cfg)}, /*Hawking-Edimax*/ | ||
333 | {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ | 360 | {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ |
334 | {RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ | 361 | {RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ |
335 | {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ | 362 | {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ |
336 | {RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/ | 363 | {RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/ |
364 | {RTL_USB_DEVICE(0x20f4, 0x624d, rtl92cu_hal_cfg)}, /*TRENDNet*/ | ||
337 | {RTL_USB_DEVICE(0x7392, 0x7822, rtl92cu_hal_cfg)}, /*Edimax -Edimax*/ | 365 | {RTL_USB_DEVICE(0x7392, 0x7822, rtl92cu_hal_cfg)}, /*Edimax -Edimax*/ |
338 | {} | 366 | {} |
339 | }; | 367 | }; |
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 182562952c79..0b5c18feb303 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
@@ -165,7 +165,8 @@ static int xenvif_change_mtu(struct net_device *dev, int mtu) | |||
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | 167 | ||
168 | static u32 xenvif_fix_features(struct net_device *dev, u32 features) | 168 | static netdev_features_t xenvif_fix_features(struct net_device *dev, |
169 | netdev_features_t features) | ||
169 | { | 170 | { |
170 | struct xenvif *vif = netdev_priv(dev); | 171 | struct xenvif *vif = netdev_priv(dev); |
171 | 172 | ||
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 226faab23603..4312db8cdeab 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -201,7 +201,7 @@ static void xennet_sysfs_delif(struct net_device *netdev); | |||
201 | #define xennet_sysfs_delif(dev) do { } while (0) | 201 | #define xennet_sysfs_delif(dev) do { } while (0) |
202 | #endif | 202 | #endif |
203 | 203 | ||
204 | static int xennet_can_sg(struct net_device *dev) | 204 | static bool xennet_can_sg(struct net_device *dev) |
205 | { | 205 | { |
206 | return dev->features & NETIF_F_SG; | 206 | return dev->features & NETIF_F_SG; |
207 | } | 207 | } |
@@ -1190,7 +1190,8 @@ static void xennet_uninit(struct net_device *dev) | |||
1190 | gnttab_free_grant_references(np->gref_rx_head); | 1190 | gnttab_free_grant_references(np->gref_rx_head); |
1191 | } | 1191 | } |
1192 | 1192 | ||
1193 | static u32 xennet_fix_features(struct net_device *dev, u32 features) | 1193 | static netdev_features_t xennet_fix_features(struct net_device *dev, |
1194 | netdev_features_t features) | ||
1194 | { | 1195 | { |
1195 | struct netfront_info *np = netdev_priv(dev); | 1196 | struct netfront_info *np = netdev_priv(dev); |
1196 | int val; | 1197 | int val; |
@@ -1216,7 +1217,8 @@ static u32 xennet_fix_features(struct net_device *dev, u32 features) | |||
1216 | return features; | 1217 | return features; |
1217 | } | 1218 | } |
1218 | 1219 | ||
1219 | static int xennet_set_features(struct net_device *dev, u32 features) | 1220 | static int xennet_set_features(struct net_device *dev, |
1221 | netdev_features_t features) | ||
1220 | { | 1222 | { |
1221 | if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) { | 1223 | if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) { |
1222 | netdev_info(dev, "Reducing MTU because no SG offload"); | 1224 | netdev_info(dev, "Reducing MTU because no SG offload"); |
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index 94f49ffa70ba..8af868bab20b 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c | |||
@@ -263,6 +263,11 @@ error: | |||
263 | return PTR_ERR(vqs[i]); | 263 | return PTR_ERR(vqs[i]); |
264 | } | 264 | } |
265 | 265 | ||
266 | static const char *kvm_bus_name(struct virtio_device *vdev) | ||
267 | { | ||
268 | return ""; | ||
269 | } | ||
270 | |||
266 | /* | 271 | /* |
267 | * The config ops structure as defined by virtio config | 272 | * The config ops structure as defined by virtio config |
268 | */ | 273 | */ |
@@ -276,6 +281,7 @@ static struct virtio_config_ops kvm_vq_configspace_ops = { | |||
276 | .reset = kvm_reset, | 281 | .reset = kvm_reset, |
277 | .find_vqs = kvm_find_vqs, | 282 | .find_vqs = kvm_find_vqs, |
278 | .del_vqs = kvm_del_vqs, | 283 | .del_vqs = kvm_del_vqs, |
284 | .bus_name = kvm_bus_name, | ||
279 | }; | 285 | }; |
280 | 286 | ||
281 | /* | 287 | /* |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 4d5307ddbe55..63578925bc59 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -3209,7 +3209,8 @@ static int qeth_l3_stop(struct net_device *dev) | |||
3209 | return 0; | 3209 | return 0; |
3210 | } | 3210 | } |
3211 | 3211 | ||
3212 | static u32 qeth_l3_fix_features(struct net_device *dev, u32 features) | 3212 | static netdev_features_t qeth_l3_fix_features(struct net_device *dev, |
3213 | netdev_features_t features) | ||
3213 | { | 3214 | { |
3214 | struct qeth_card *card = dev->ml_priv; | 3215 | struct qeth_card *card = dev->ml_priv; |
3215 | 3216 | ||
@@ -3223,7 +3224,8 @@ static u32 qeth_l3_fix_features(struct net_device *dev, u32 features) | |||
3223 | return features; | 3224 | return features; |
3224 | } | 3225 | } |
3225 | 3226 | ||
3226 | static int qeth_l3_set_features(struct net_device *dev, u32 features) | 3227 | static int qeth_l3_set_features(struct net_device *dev, |
3228 | netdev_features_t features) | ||
3227 | { | 3229 | { |
3228 | struct qeth_card *card = dev->ml_priv; | 3230 | struct qeth_card *card = dev->ml_priv; |
3229 | u32 changed = dev->features ^ features; | 3231 | u32 changed = dev->features ^ features; |
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index 16a509ae517b..7cdcb63b21ff 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c | |||
@@ -298,11 +298,10 @@ static void pn_net_setup(struct net_device *dev) | |||
298 | static int | 298 | static int |
299 | pn_rx_submit(struct f_phonet *fp, struct usb_request *req, gfp_t gfp_flags) | 299 | pn_rx_submit(struct f_phonet *fp, struct usb_request *req, gfp_t gfp_flags) |
300 | { | 300 | { |
301 | struct net_device *dev = fp->dev; | ||
302 | struct page *page; | 301 | struct page *page; |
303 | int err; | 302 | int err; |
304 | 303 | ||
305 | page = __netdev_alloc_page(dev, gfp_flags); | 304 | page = alloc_page(gfp_flags); |
306 | if (!page) | 305 | if (!page) |
307 | return -ENOMEM; | 306 | return -ENOMEM; |
308 | 307 | ||
@@ -312,7 +311,7 @@ pn_rx_submit(struct f_phonet *fp, struct usb_request *req, gfp_t gfp_flags) | |||
312 | 311 | ||
313 | err = usb_ep_queue(fp->out_ep, req, gfp_flags); | 312 | err = usb_ep_queue(fp->out_ep, req, gfp_flags); |
314 | if (unlikely(err)) | 313 | if (unlikely(err)) |
315 | netdev_free_page(dev, page); | 314 | put_page(page); |
316 | return err; | 315 | return err; |
317 | } | 316 | } |
318 | 317 | ||
@@ -374,9 +373,9 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req) | |||
374 | } | 373 | } |
375 | 374 | ||
376 | if (page) | 375 | if (page) |
377 | netdev_free_page(dev, page); | 376 | put_page(page); |
378 | if (req) | 377 | if (req) |
379 | pn_rx_submit(fp, req, GFP_ATOMIC); | 378 | pn_rx_submit(fp, req, GFP_ATOMIC | __GFP_COLD); |
380 | } | 379 | } |
381 | 380 | ||
382 | /*-------------------------------------------------------------------------*/ | 381 | /*-------------------------------------------------------------------------*/ |
@@ -436,7 +435,7 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
436 | 435 | ||
437 | netif_carrier_on(dev); | 436 | netif_carrier_on(dev); |
438 | for (i = 0; i < phonet_rxq_size; i++) | 437 | for (i = 0; i < phonet_rxq_size; i++) |
439 | pn_rx_submit(fp, fp->out_reqv[i], GFP_ATOMIC); | 438 | pn_rx_submit(fp, fp->out_reqv[i], GFP_ATOMIC | __GFP_COLD); |
440 | } | 439 | } |
441 | spin_unlock(&port->lock); | 440 | spin_unlock(&port->lock); |
442 | return 0; | 441 | return 0; |
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index acc5e43c373e..2f57380d7ed4 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c | |||
@@ -361,7 +361,12 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs, | |||
361 | return 0; | 361 | return 0; |
362 | } | 362 | } |
363 | 363 | ||
364 | static const char *vm_bus_name(struct virtio_device *vdev) | ||
365 | { | ||
366 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); | ||
364 | 367 | ||
368 | return vm_dev->pdev->name; | ||
369 | } | ||
365 | 370 | ||
366 | static struct virtio_config_ops virtio_mmio_config_ops = { | 371 | static struct virtio_config_ops virtio_mmio_config_ops = { |
367 | .get = vm_get, | 372 | .get = vm_get, |
@@ -373,6 +378,7 @@ static struct virtio_config_ops virtio_mmio_config_ops = { | |||
373 | .del_vqs = vm_del_vqs, | 378 | .del_vqs = vm_del_vqs, |
374 | .get_features = vm_get_features, | 379 | .get_features = vm_get_features, |
375 | .finalize_features = vm_finalize_features, | 380 | .finalize_features = vm_finalize_features, |
381 | .bus_name = vm_bus_name, | ||
376 | }; | 382 | }; |
377 | 383 | ||
378 | 384 | ||
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 3d1bf41e8892..91683e6e7af5 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -580,6 +580,13 @@ static int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs, | |||
580 | false, false); | 580 | false, false); |
581 | } | 581 | } |
582 | 582 | ||
583 | static const char *vp_bus_name(struct virtio_device *vdev) | ||
584 | { | ||
585 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | ||
586 | |||
587 | return pci_name(vp_dev->pci_dev); | ||
588 | } | ||
589 | |||
583 | static struct virtio_config_ops virtio_pci_config_ops = { | 590 | static struct virtio_config_ops virtio_pci_config_ops = { |
584 | .get = vp_get, | 591 | .get = vp_get, |
585 | .set = vp_set, | 592 | .set = vp_set, |
@@ -590,6 +597,7 @@ static struct virtio_config_ops virtio_pci_config_ops = { | |||
590 | .del_vqs = vp_del_vqs, | 597 | .del_vqs = vp_del_vqs, |
591 | .get_features = vp_get_features, | 598 | .get_features = vp_get_features, |
592 | .finalize_features = vp_finalize_features, | 599 | .finalize_features = vp_finalize_features, |
600 | .bus_name = vp_bus_name, | ||
593 | }; | 601 | }; |
594 | 602 | ||
595 | static void virtio_pci_release_dev(struct device *_d) | 603 | static void virtio_pci_release_dev(struct device *_d) |
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 990626e7da80..0b3109ee4257 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c | |||
@@ -281,7 +281,7 @@ static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr) | |||
281 | } else { | 281 | } else { |
282 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &addr; | 282 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &addr; |
283 | struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *) retaddr; | 283 | struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *) retaddr; |
284 | ipv6_addr_copy(&ret6->sin6_addr, &in6->sin6_addr); | 284 | ret6->sin6_addr = in6->sin6_addr; |
285 | } | 285 | } |
286 | 286 | ||
287 | return 0; | 287 | return 0; |
diff --git a/include/asm-generic/socket.h b/include/asm-generic/socket.h index 9a6115e7cf63..49c1704173e7 100644 --- a/include/asm-generic/socket.h +++ b/include/asm-generic/socket.h | |||
@@ -64,4 +64,7 @@ | |||
64 | #define SO_DOMAIN 39 | 64 | #define SO_DOMAIN 39 |
65 | 65 | ||
66 | #define SO_RXQ_OVFL 40 | 66 | #define SO_RXQ_OVFL 40 |
67 | |||
68 | #define SO_WIFI_STATUS 41 | ||
69 | #define SCM_WIFI_STATUS SO_WIFI_STATUS | ||
67 | #endif /* __ASM_GENERIC_SOCKET_H */ | 70 | #endif /* __ASM_GENERIC_SOCKET_H */ |
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 619b5657af77..0b091b32267d 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild | |||
@@ -185,6 +185,7 @@ header-y += if_pppol2tp.h | |||
185 | header-y += if_pppox.h | 185 | header-y += if_pppox.h |
186 | header-y += if_slip.h | 186 | header-y += if_slip.h |
187 | header-y += if_strip.h | 187 | header-y += if_strip.h |
188 | header-y += if_team.h | ||
188 | header-y += if_tr.h | 189 | header-y += if_tr.h |
189 | header-y += if_tun.h | 190 | header-y += if_tun.h |
190 | header-y += if_tunnel.h | 191 | header-y += if_tunnel.h |
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index 49a83ca900ba..43ea1b2de3ee 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h | |||
@@ -452,7 +452,7 @@ void atm_dev_release_vccs(struct atm_dev *dev); | |||
452 | 452 | ||
453 | static inline int atm_guess_pdu2truesize(int size) | 453 | static inline int atm_guess_pdu2truesize(int size) |
454 | { | 454 | { |
455 | return SKB_DATA_ALIGN(size) + sizeof(struct skb_shared_info); | 455 | return SKB_TRUESIZE(size); |
456 | } | 456 | } |
457 | 457 | ||
458 | 458 | ||
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h index ac663c18776c..0bd390ce98b2 100644 --- a/include/linux/cgroup_subsys.h +++ b/include/linux/cgroup_subsys.h | |||
@@ -59,8 +59,16 @@ SUBSYS(net_cls) | |||
59 | SUBSYS(blkio) | 59 | SUBSYS(blkio) |
60 | #endif | 60 | #endif |
61 | 61 | ||
62 | /* */ | ||
63 | |||
62 | #ifdef CONFIG_CGROUP_PERF | 64 | #ifdef CONFIG_CGROUP_PERF |
63 | SUBSYS(perf) | 65 | SUBSYS(perf) |
64 | #endif | 66 | #endif |
65 | 67 | ||
66 | /* */ | 68 | /* */ |
69 | |||
70 | #ifdef CONFIG_NETPRIO_CGROUP | ||
71 | SUBSYS(net_prio) | ||
72 | #endif | ||
73 | |||
74 | /* */ | ||
diff --git a/include/linux/errqueue.h b/include/linux/errqueue.h index 034072cea853..c9f522bd17e4 100644 --- a/include/linux/errqueue.h +++ b/include/linux/errqueue.h | |||
@@ -17,7 +17,8 @@ struct sock_extended_err { | |||
17 | #define SO_EE_ORIGIN_LOCAL 1 | 17 | #define SO_EE_ORIGIN_LOCAL 1 |
18 | #define SO_EE_ORIGIN_ICMP 2 | 18 | #define SO_EE_ORIGIN_ICMP 2 |
19 | #define SO_EE_ORIGIN_ICMP6 3 | 19 | #define SO_EE_ORIGIN_ICMP6 3 |
20 | #define SO_EE_ORIGIN_TIMESTAMPING 4 | 20 | #define SO_EE_ORIGIN_TXSTATUS 4 |
21 | #define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS | ||
21 | 22 | ||
22 | #define SO_EE_OFFENDER(ee) ((struct sockaddr*)((ee)+1)) | 23 | #define SO_EE_OFFENDER(ee) ((struct sockaddr*)((ee)+1)) |
23 | 24 | ||
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index de33de1e2052..20db5b275c3f 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h | |||
@@ -724,9 +724,6 @@ enum ethtool_sfeatures_retval_bits { | |||
724 | 724 | ||
725 | #include <linux/rculist.h> | 725 | #include <linux/rculist.h> |
726 | 726 | ||
727 | /* needed by dev_disable_lro() */ | ||
728 | extern int __ethtool_set_flags(struct net_device *dev, u32 flags); | ||
729 | |||
730 | extern int __ethtool_get_settings(struct net_device *dev, | 727 | extern int __ethtool_get_settings(struct net_device *dev, |
731 | struct ethtool_cmd *cmd); | 728 | struct ethtool_cmd *cmd); |
732 | 729 | ||
@@ -750,19 +747,6 @@ struct net_device; | |||
750 | 747 | ||
751 | /* Some generic methods drivers may use in their ethtool_ops */ | 748 | /* Some generic methods drivers may use in their ethtool_ops */ |
752 | u32 ethtool_op_get_link(struct net_device *dev); | 749 | u32 ethtool_op_get_link(struct net_device *dev); |
753 | u32 ethtool_op_get_tx_csum(struct net_device *dev); | ||
754 | int ethtool_op_set_tx_csum(struct net_device *dev, u32 data); | ||
755 | int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data); | ||
756 | int ethtool_op_set_tx_ipv6_csum(struct net_device *dev, u32 data); | ||
757 | u32 ethtool_op_get_sg(struct net_device *dev); | ||
758 | int ethtool_op_set_sg(struct net_device *dev, u32 data); | ||
759 | u32 ethtool_op_get_tso(struct net_device *dev); | ||
760 | int ethtool_op_set_tso(struct net_device *dev, u32 data); | ||
761 | u32 ethtool_op_get_ufo(struct net_device *dev); | ||
762 | int ethtool_op_set_ufo(struct net_device *dev, u32 data); | ||
763 | u32 ethtool_op_get_flags(struct net_device *dev); | ||
764 | int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported); | ||
765 | bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); | ||
766 | 750 | ||
767 | /** | 751 | /** |
768 | * struct ethtool_ops - optional netdev operations | 752 | * struct ethtool_ops - optional netdev operations |
@@ -807,22 +791,6 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); | |||
807 | * @get_pauseparam: Report pause parameters | 791 | * @get_pauseparam: Report pause parameters |
808 | * @set_pauseparam: Set pause parameters. Returns a negative error code | 792 | * @set_pauseparam: Set pause parameters. Returns a negative error code |
809 | * or zero. | 793 | * or zero. |
810 | * @get_rx_csum: Deprecated in favour of the netdev feature %NETIF_F_RXCSUM. | ||
811 | * Report whether receive checksums are turned on or off. | ||
812 | * @set_rx_csum: Deprecated in favour of generic netdev features. Turn | ||
813 | * receive checksum on or off. Returns a negative error code or zero. | ||
814 | * @get_tx_csum: Deprecated as redundant. Report whether transmit checksums | ||
815 | * are turned on or off. | ||
816 | * @set_tx_csum: Deprecated in favour of generic netdev features. Turn | ||
817 | * transmit checksums on or off. Returns a negative error code or zero. | ||
818 | * @get_sg: Deprecated as redundant. Report whether scatter-gather is | ||
819 | * enabled. | ||
820 | * @set_sg: Deprecated in favour of generic netdev features. Turn | ||
821 | * scatter-gather on or off. Returns a negative error code or zero. | ||
822 | * @get_tso: Deprecated as redundant. Report whether TCP segmentation | ||
823 | * offload is enabled. | ||
824 | * @set_tso: Deprecated in favour of generic netdev features. Turn TCP | ||
825 | * segmentation offload on or off. Returns a negative error code or zero. | ||
826 | * @self_test: Run specified self-tests | 794 | * @self_test: Run specified self-tests |
827 | * @get_strings: Return a set of strings that describe the requested objects | 795 | * @get_strings: Return a set of strings that describe the requested objects |
828 | * @set_phys_id: Identify the physical devices, e.g. by flashing an LED | 796 | * @set_phys_id: Identify the physical devices, e.g. by flashing an LED |
@@ -844,15 +812,6 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); | |||
844 | * negative error code or zero. | 812 | * negative error code or zero. |
845 | * @complete: Function to be called after any other operation except | 813 | * @complete: Function to be called after any other operation except |
846 | * @begin. Will be called even if the other operation failed. | 814 | * @begin. Will be called even if the other operation failed. |
847 | * @get_ufo: Deprecated as redundant. Report whether UDP fragmentation | ||
848 | * offload is enabled. | ||
849 | * @set_ufo: Deprecated in favour of generic netdev features. Turn UDP | ||
850 | * fragmentation offload on or off. Returns a negative error code or zero. | ||
851 | * @get_flags: Deprecated as redundant. Report features included in | ||
852 | * &enum ethtool_flags that are enabled. | ||
853 | * @set_flags: Deprecated in favour of generic netdev features. Turn | ||
854 | * features included in &enum ethtool_flags on or off. Returns a | ||
855 | * negative error code or zero. | ||
856 | * @get_priv_flags: Report driver-specific feature flags. | 815 | * @get_priv_flags: Report driver-specific feature flags. |
857 | * @set_priv_flags: Set driver-specific feature flags. Returns a negative | 816 | * @set_priv_flags: Set driver-specific feature flags. Returns a negative |
858 | * error code or zero. | 817 | * error code or zero. |
@@ -917,14 +876,6 @@ struct ethtool_ops { | |||
917 | struct ethtool_pauseparam*); | 876 | struct ethtool_pauseparam*); |
918 | int (*set_pauseparam)(struct net_device *, | 877 | int (*set_pauseparam)(struct net_device *, |
919 | struct ethtool_pauseparam*); | 878 | struct ethtool_pauseparam*); |
920 | u32 (*get_rx_csum)(struct net_device *); | ||
921 | int (*set_rx_csum)(struct net_device *, u32); | ||
922 | u32 (*get_tx_csum)(struct net_device *); | ||
923 | int (*set_tx_csum)(struct net_device *, u32); | ||
924 | u32 (*get_sg)(struct net_device *); | ||
925 | int (*set_sg)(struct net_device *, u32); | ||
926 | u32 (*get_tso)(struct net_device *); | ||
927 | int (*set_tso)(struct net_device *, u32); | ||
928 | void (*self_test)(struct net_device *, struct ethtool_test *, u64 *); | 879 | void (*self_test)(struct net_device *, struct ethtool_test *, u64 *); |
929 | void (*get_strings)(struct net_device *, u32 stringset, u8 *); | 880 | void (*get_strings)(struct net_device *, u32 stringset, u8 *); |
930 | int (*set_phys_id)(struct net_device *, enum ethtool_phys_id_state); | 881 | int (*set_phys_id)(struct net_device *, enum ethtool_phys_id_state); |
@@ -932,10 +883,6 @@ struct ethtool_ops { | |||
932 | struct ethtool_stats *, u64 *); | 883 | struct ethtool_stats *, u64 *); |
933 | int (*begin)(struct net_device *); | 884 | int (*begin)(struct net_device *); |
934 | void (*complete)(struct net_device *); | 885 | void (*complete)(struct net_device *); |
935 | u32 (*get_ufo)(struct net_device *); | ||
936 | int (*set_ufo)(struct net_device *, u32); | ||
937 | u32 (*get_flags)(struct net_device *); | ||
938 | int (*set_flags)(struct net_device *, u32); | ||
939 | u32 (*get_priv_flags)(struct net_device *); | 886 | u32 (*get_priv_flags)(struct net_device *); |
940 | int (*set_priv_flags)(struct net_device *, u32); | 887 | int (*set_priv_flags)(struct net_device *, u32); |
941 | int (*get_sset_count)(struct net_device *, int); | 888 | int (*get_sset_count)(struct net_device *, int); |
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 48363c3c40f8..66cedf6eb5c2 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
@@ -128,6 +128,7 @@ | |||
128 | #define IEEE80211_QOS_CTL_ACK_POLICY_NOACK 0x0020 | 128 | #define IEEE80211_QOS_CTL_ACK_POLICY_NOACK 0x0020 |
129 | #define IEEE80211_QOS_CTL_ACK_POLICY_NO_EXPL 0x0040 | 129 | #define IEEE80211_QOS_CTL_ACK_POLICY_NO_EXPL 0x0040 |
130 | #define IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK 0x0060 | 130 | #define IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK 0x0060 |
131 | #define IEEE80211_QOS_CTL_ACK_POLICY_MASK 0x0060 | ||
131 | /* A-MSDU 802.11n */ | 132 | /* A-MSDU 802.11n */ |
132 | #define IEEE80211_QOS_CTL_A_MSDU_PRESENT 0x0080 | 133 | #define IEEE80211_QOS_CTL_A_MSDU_PRESENT 0x0080 |
133 | /* Mesh Control 802.11s */ | 134 | /* Mesh Control 802.11s */ |
@@ -770,6 +771,9 @@ struct ieee80211_mgmt { | |||
770 | } u; | 771 | } u; |
771 | } __attribute__ ((packed)); | 772 | } __attribute__ ((packed)); |
772 | 773 | ||
774 | /* Supported Rates value encodings in 802.11n-2009 7.3.2.2 */ | ||
775 | #define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 | ||
776 | |||
773 | /* mgmt header + 1 byte category code */ | 777 | /* mgmt header + 1 byte category code */ |
774 | #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u) | 778 | #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u) |
775 | 779 | ||
@@ -1552,6 +1556,8 @@ enum ieee80211_sa_query_action { | |||
1552 | #define WLAN_CIPHER_SUITE_WEP104 0x000FAC05 | 1556 | #define WLAN_CIPHER_SUITE_WEP104 0x000FAC05 |
1553 | #define WLAN_CIPHER_SUITE_AES_CMAC 0x000FAC06 | 1557 | #define WLAN_CIPHER_SUITE_AES_CMAC 0x000FAC06 |
1554 | 1558 | ||
1559 | #define WLAN_CIPHER_SUITE_SMS4 0x00147201 | ||
1560 | |||
1555 | /* AKM suite selectors */ | 1561 | /* AKM suite selectors */ |
1556 | #define WLAN_AKM_SUITE_8021X 0x000FAC01 | 1562 | #define WLAN_AKM_SUITE_8021X 0x000FAC01 |
1557 | #define WLAN_AKM_SUITE_PSK 0x000FAC02 | 1563 | #define WLAN_AKM_SUITE_PSK 0x000FAC02 |
diff --git a/include/linux/if.h b/include/linux/if.h index db20bd4fd16b..06b6ef60c821 100644 --- a/include/linux/if.h +++ b/include/linux/if.h | |||
@@ -79,6 +79,7 @@ | |||
79 | #define IFF_TX_SKB_SHARING 0x10000 /* The interface supports sharing | 79 | #define IFF_TX_SKB_SHARING 0x10000 /* The interface supports sharing |
80 | * skbs on transmit */ | 80 | * skbs on transmit */ |
81 | #define IFF_UNICAST_FLT 0x20000 /* Supports unicast filtering */ | 81 | #define IFF_UNICAST_FLT 0x20000 /* Supports unicast filtering */ |
82 | #define IFF_TEAM_PORT 0x40000 /* device used as team port */ | ||
82 | 83 | ||
83 | #define IF_GET_IFACE 0x0001 /* for querying only */ | 84 | #define IF_GET_IFACE 0x0001 /* for querying only */ |
84 | #define IF_GET_PROTO 0x0002 | 85 | #define IF_GET_PROTO 0x0002 |
diff --git a/include/linux/if_team.h b/include/linux/if_team.h new file mode 100644 index 000000000000..828181fbad5d --- /dev/null +++ b/include/linux/if_team.h | |||
@@ -0,0 +1,242 @@ | |||
1 | /* | ||
2 | * include/linux/if_team.h - Network team device driver header | ||
3 | * Copyright (c) 2011 Jiri Pirko <jpirko@redhat.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 | |||
11 | #ifndef _LINUX_IF_TEAM_H_ | ||
12 | #define _LINUX_IF_TEAM_H_ | ||
13 | |||
14 | #ifdef __KERNEL__ | ||
15 | |||
16 | struct team_pcpu_stats { | ||
17 | u64 rx_packets; | ||
18 | u64 rx_bytes; | ||
19 | u64 rx_multicast; | ||
20 | u64 tx_packets; | ||
21 | u64 tx_bytes; | ||
22 | struct u64_stats_sync syncp; | ||
23 | u32 rx_dropped; | ||
24 | u32 tx_dropped; | ||
25 | }; | ||
26 | |||
27 | struct team; | ||
28 | |||
29 | struct team_port { | ||
30 | struct net_device *dev; | ||
31 | struct hlist_node hlist; /* node in hash list */ | ||
32 | struct list_head list; /* node in ordinary list */ | ||
33 | struct team *team; | ||
34 | int index; | ||
35 | |||
36 | /* | ||
37 | * A place for storing original values of the device before it | ||
38 | * become a port. | ||
39 | */ | ||
40 | struct { | ||
41 | unsigned char dev_addr[MAX_ADDR_LEN]; | ||
42 | unsigned int mtu; | ||
43 | } orig; | ||
44 | |||
45 | bool linkup; | ||
46 | u32 speed; | ||
47 | u8 duplex; | ||
48 | |||
49 | struct rcu_head rcu; | ||
50 | }; | ||
51 | |||
52 | struct team_mode_ops { | ||
53 | int (*init)(struct team *team); | ||
54 | void (*exit)(struct team *team); | ||
55 | rx_handler_result_t (*receive)(struct team *team, | ||
56 | struct team_port *port, | ||
57 | struct sk_buff *skb); | ||
58 | bool (*transmit)(struct team *team, struct sk_buff *skb); | ||
59 | int (*port_enter)(struct team *team, struct team_port *port); | ||
60 | void (*port_leave)(struct team *team, struct team_port *port); | ||
61 | void (*port_change_mac)(struct team *team, struct team_port *port); | ||
62 | }; | ||
63 | |||
64 | enum team_option_type { | ||
65 | TEAM_OPTION_TYPE_U32, | ||
66 | TEAM_OPTION_TYPE_STRING, | ||
67 | }; | ||
68 | |||
69 | struct team_option { | ||
70 | struct list_head list; | ||
71 | const char *name; | ||
72 | enum team_option_type type; | ||
73 | int (*getter)(struct team *team, void *arg); | ||
74 | int (*setter)(struct team *team, void *arg); | ||
75 | }; | ||
76 | |||
77 | struct team_mode { | ||
78 | struct list_head list; | ||
79 | const char *kind; | ||
80 | struct module *owner; | ||
81 | size_t priv_size; | ||
82 | const struct team_mode_ops *ops; | ||
83 | }; | ||
84 | |||
85 | #define TEAM_PORT_HASHBITS 4 | ||
86 | #define TEAM_PORT_HASHENTRIES (1 << TEAM_PORT_HASHBITS) | ||
87 | |||
88 | #define TEAM_MODE_PRIV_LONGS 4 | ||
89 | #define TEAM_MODE_PRIV_SIZE (sizeof(long) * TEAM_MODE_PRIV_LONGS) | ||
90 | |||
91 | struct team { | ||
92 | struct net_device *dev; /* associated netdevice */ | ||
93 | struct team_pcpu_stats __percpu *pcpu_stats; | ||
94 | |||
95 | struct mutex lock; /* used for overall locking, e.g. port lists write */ | ||
96 | |||
97 | /* | ||
98 | * port lists with port count | ||
99 | */ | ||
100 | int port_count; | ||
101 | struct hlist_head port_hlist[TEAM_PORT_HASHENTRIES]; | ||
102 | struct list_head port_list; | ||
103 | |||
104 | struct list_head option_list; | ||
105 | |||
106 | const struct team_mode *mode; | ||
107 | struct team_mode_ops ops; | ||
108 | long mode_priv[TEAM_MODE_PRIV_LONGS]; | ||
109 | }; | ||
110 | |||
111 | static inline struct hlist_head *team_port_index_hash(struct team *team, | ||
112 | int port_index) | ||
113 | { | ||
114 | return &team->port_hlist[port_index & (TEAM_PORT_HASHENTRIES - 1)]; | ||
115 | } | ||
116 | |||
117 | static inline struct team_port *team_get_port_by_index(struct team *team, | ||
118 | int port_index) | ||
119 | { | ||
120 | struct hlist_node *p; | ||
121 | struct team_port *port; | ||
122 | struct hlist_head *head = team_port_index_hash(team, port_index); | ||
123 | |||
124 | hlist_for_each_entry(port, p, head, hlist) | ||
125 | if (port->index == port_index) | ||
126 | return port; | ||
127 | return NULL; | ||
128 | } | ||
129 | static inline struct team_port *team_get_port_by_index_rcu(struct team *team, | ||
130 | int port_index) | ||
131 | { | ||
132 | struct hlist_node *p; | ||
133 | struct team_port *port; | ||
134 | struct hlist_head *head = team_port_index_hash(team, port_index); | ||
135 | |||
136 | hlist_for_each_entry_rcu(port, p, head, hlist) | ||
137 | if (port->index == port_index) | ||
138 | return port; | ||
139 | return NULL; | ||
140 | } | ||
141 | |||
142 | extern int team_port_set_team_mac(struct team_port *port); | ||
143 | extern int team_options_register(struct team *team, | ||
144 | const struct team_option *option, | ||
145 | size_t option_count); | ||
146 | extern void team_options_unregister(struct team *team, | ||
147 | const struct team_option *option, | ||
148 | size_t option_count); | ||
149 | extern int team_mode_register(struct team_mode *mode); | ||
150 | extern int team_mode_unregister(struct team_mode *mode); | ||
151 | |||
152 | #endif /* __KERNEL__ */ | ||
153 | |||
154 | #define TEAM_STRING_MAX_LEN 32 | ||
155 | |||
156 | /********************************** | ||
157 | * NETLINK_GENERIC netlink family. | ||
158 | **********************************/ | ||
159 | |||
160 | enum { | ||
161 | TEAM_CMD_NOOP, | ||
162 | TEAM_CMD_OPTIONS_SET, | ||
163 | TEAM_CMD_OPTIONS_GET, | ||
164 | TEAM_CMD_PORT_LIST_GET, | ||
165 | |||
166 | __TEAM_CMD_MAX, | ||
167 | TEAM_CMD_MAX = (__TEAM_CMD_MAX - 1), | ||
168 | }; | ||
169 | |||
170 | enum { | ||
171 | TEAM_ATTR_UNSPEC, | ||
172 | TEAM_ATTR_TEAM_IFINDEX, /* u32 */ | ||
173 | TEAM_ATTR_LIST_OPTION, /* nest */ | ||
174 | TEAM_ATTR_LIST_PORT, /* nest */ | ||
175 | |||
176 | __TEAM_ATTR_MAX, | ||
177 | TEAM_ATTR_MAX = __TEAM_ATTR_MAX - 1, | ||
178 | }; | ||
179 | |||
180 | /* Nested layout of get/set msg: | ||
181 | * | ||
182 | * [TEAM_ATTR_LIST_OPTION] | ||
183 | * [TEAM_ATTR_ITEM_OPTION] | ||
184 | * [TEAM_ATTR_OPTION_*], ... | ||
185 | * [TEAM_ATTR_ITEM_OPTION] | ||
186 | * [TEAM_ATTR_OPTION_*], ... | ||
187 | * ... | ||
188 | * [TEAM_ATTR_LIST_PORT] | ||
189 | * [TEAM_ATTR_ITEM_PORT] | ||
190 | * [TEAM_ATTR_PORT_*], ... | ||
191 | * [TEAM_ATTR_ITEM_PORT] | ||
192 | * [TEAM_ATTR_PORT_*], ... | ||
193 | * ... | ||
194 | */ | ||
195 | |||
196 | enum { | ||
197 | TEAM_ATTR_ITEM_OPTION_UNSPEC, | ||
198 | TEAM_ATTR_ITEM_OPTION, /* nest */ | ||
199 | |||
200 | __TEAM_ATTR_ITEM_OPTION_MAX, | ||
201 | TEAM_ATTR_ITEM_OPTION_MAX = __TEAM_ATTR_ITEM_OPTION_MAX - 1, | ||
202 | }; | ||
203 | |||
204 | enum { | ||
205 | TEAM_ATTR_OPTION_UNSPEC, | ||
206 | TEAM_ATTR_OPTION_NAME, /* string */ | ||
207 | TEAM_ATTR_OPTION_CHANGED, /* flag */ | ||
208 | TEAM_ATTR_OPTION_TYPE, /* u8 */ | ||
209 | TEAM_ATTR_OPTION_DATA, /* dynamic */ | ||
210 | |||
211 | __TEAM_ATTR_OPTION_MAX, | ||
212 | TEAM_ATTR_OPTION_MAX = __TEAM_ATTR_OPTION_MAX - 1, | ||
213 | }; | ||
214 | |||
215 | enum { | ||
216 | TEAM_ATTR_ITEM_PORT_UNSPEC, | ||
217 | TEAM_ATTR_ITEM_PORT, /* nest */ | ||
218 | |||
219 | __TEAM_ATTR_ITEM_PORT_MAX, | ||
220 | TEAM_ATTR_ITEM_PORT_MAX = __TEAM_ATTR_ITEM_PORT_MAX - 1, | ||
221 | }; | ||
222 | |||
223 | enum { | ||
224 | TEAM_ATTR_PORT_UNSPEC, | ||
225 | TEAM_ATTR_PORT_IFINDEX, /* u32 */ | ||
226 | TEAM_ATTR_PORT_CHANGED, /* flag */ | ||
227 | TEAM_ATTR_PORT_LINKUP, /* flag */ | ||
228 | TEAM_ATTR_PORT_SPEED, /* u32 */ | ||
229 | TEAM_ATTR_PORT_DUPLEX, /* u8 */ | ||
230 | |||
231 | __TEAM_ATTR_PORT_MAX, | ||
232 | TEAM_ATTR_PORT_MAX = __TEAM_ATTR_PORT_MAX - 1, | ||
233 | }; | ||
234 | |||
235 | /* | ||
236 | * NETLINK_GENERIC related info | ||
237 | */ | ||
238 | #define TEAM_GENL_NAME "team" | ||
239 | #define TEAM_GENL_VERSION 0x1 | ||
240 | #define TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME "change_event" | ||
241 | |||
242 | #endif /* _LINUX_IF_TEAM_H_ */ | ||
diff --git a/include/linux/mdio-bitbang.h b/include/linux/mdio-bitbang.h index 0fe00cd4c93c..76f52bbbb2f4 100644 --- a/include/linux/mdio-bitbang.h +++ b/include/linux/mdio-bitbang.h | |||
@@ -32,6 +32,8 @@ struct mdiobb_ops { | |||
32 | 32 | ||
33 | struct mdiobb_ctrl { | 33 | struct mdiobb_ctrl { |
34 | const struct mdiobb_ops *ops; | 34 | const struct mdiobb_ops *ops; |
35 | /* reset callback */ | ||
36 | int (*reset)(struct mii_bus *bus); | ||
35 | }; | 37 | }; |
36 | 38 | ||
37 | /* The returned bus is not yet registered with the phy layer. */ | 39 | /* The returned bus is not yet registered with the phy layer. */ |
diff --git a/include/linux/mdio-gpio.h b/include/linux/mdio-gpio.h index e9d3fdfe41d7..7c9fe3c2be73 100644 --- a/include/linux/mdio-gpio.h +++ b/include/linux/mdio-gpio.h | |||
@@ -20,6 +20,8 @@ struct mdio_gpio_platform_data { | |||
20 | 20 | ||
21 | unsigned int phy_mask; | 21 | unsigned int phy_mask; |
22 | int irqs[PHY_MAX_ADDR]; | 22 | int irqs[PHY_MAX_ADDR]; |
23 | /* reset callback */ | ||
24 | int (*reset)(struct mii_bus *bus); | ||
23 | }; | 25 | }; |
24 | 26 | ||
25 | #endif /* __LINUX_MDIO_GPIO_H */ | 27 | #endif /* __LINUX_MDIO_GPIO_H */ |
diff --git a/include/linux/mii.h b/include/linux/mii.h index 27748230aa69..2783eca629a0 100644 --- a/include/linux/mii.h +++ b/include/linux/mii.h | |||
@@ -9,6 +9,7 @@ | |||
9 | #define __LINUX_MII_H__ | 9 | #define __LINUX_MII_H__ |
10 | 10 | ||
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <linux/ethtool.h> | ||
12 | 13 | ||
13 | /* Generic MII registers. */ | 14 | /* Generic MII registers. */ |
14 | #define MII_BMCR 0x00 /* Basic mode control register */ | 15 | #define MII_BMCR 0x00 /* Basic mode control register */ |
@@ -240,6 +241,205 @@ static inline unsigned int mii_duplex (unsigned int duplex_lock, | |||
240 | } | 241 | } |
241 | 242 | ||
242 | /** | 243 | /** |
244 | * ethtool_adv_to_mii_adv_t | ||
245 | * @ethadv: the ethtool advertisement settings | ||
246 | * | ||
247 | * A small helper function that translates ethtool advertisement | ||
248 | * settings to phy autonegotiation advertisements for the | ||
249 | * MII_ADVERTISE register. | ||
250 | */ | ||
251 | static inline u32 ethtool_adv_to_mii_adv_t(u32 ethadv) | ||
252 | { | ||
253 | u32 result = 0; | ||
254 | |||
255 | if (ethadv & ADVERTISED_10baseT_Half) | ||
256 | result |= ADVERTISE_10HALF; | ||
257 | if (ethadv & ADVERTISED_10baseT_Full) | ||
258 | result |= ADVERTISE_10FULL; | ||
259 | if (ethadv & ADVERTISED_100baseT_Half) | ||
260 | result |= ADVERTISE_100HALF; | ||
261 | if (ethadv & ADVERTISED_100baseT_Full) | ||
262 | result |= ADVERTISE_100FULL; | ||
263 | if (ethadv & ADVERTISED_Pause) | ||
264 | result |= ADVERTISE_PAUSE_CAP; | ||
265 | if (ethadv & ADVERTISED_Asym_Pause) | ||
266 | result |= ADVERTISE_PAUSE_ASYM; | ||
267 | |||
268 | return result; | ||
269 | } | ||
270 | |||
271 | /** | ||
272 | * mii_adv_to_ethtool_adv_t | ||
273 | * @adv: value of the MII_ADVERTISE register | ||
274 | * | ||
275 | * A small helper function that translates MII_ADVERTISE bits | ||
276 | * to ethtool advertisement settings. | ||
277 | */ | ||
278 | static inline u32 mii_adv_to_ethtool_adv_t(u32 adv) | ||
279 | { | ||
280 | u32 result = 0; | ||
281 | |||
282 | if (adv & ADVERTISE_10HALF) | ||
283 | result |= ADVERTISED_10baseT_Half; | ||
284 | if (adv & ADVERTISE_10FULL) | ||
285 | result |= ADVERTISED_10baseT_Full; | ||
286 | if (adv & ADVERTISE_100HALF) | ||
287 | result |= ADVERTISED_100baseT_Half; | ||
288 | if (adv & ADVERTISE_100FULL) | ||
289 | result |= ADVERTISED_100baseT_Full; | ||
290 | if (adv & ADVERTISE_PAUSE_CAP) | ||
291 | result |= ADVERTISED_Pause; | ||
292 | if (adv & ADVERTISE_PAUSE_ASYM) | ||
293 | result |= ADVERTISED_Asym_Pause; | ||
294 | |||
295 | return result; | ||
296 | } | ||
297 | |||
298 | /** | ||
299 | * ethtool_adv_to_mii_ctrl1000_t | ||
300 | * @ethadv: the ethtool advertisement settings | ||
301 | * | ||
302 | * A small helper function that translates ethtool advertisement | ||
303 | * settings to phy autonegotiation advertisements for the | ||
304 | * MII_CTRL1000 register when in 1000T mode. | ||
305 | */ | ||
306 | static inline u32 ethtool_adv_to_mii_ctrl1000_t(u32 ethadv) | ||
307 | { | ||
308 | u32 result = 0; | ||
309 | |||
310 | if (ethadv & ADVERTISED_1000baseT_Half) | ||
311 | result |= ADVERTISE_1000HALF; | ||
312 | if (ethadv & ADVERTISED_1000baseT_Full) | ||
313 | result |= ADVERTISE_1000FULL; | ||
314 | |||
315 | return result; | ||
316 | } | ||
317 | |||
318 | /** | ||
319 | * mii_ctrl1000_to_ethtool_adv_t | ||
320 | * @adv: value of the MII_CTRL1000 register | ||
321 | * | ||
322 | * A small helper function that translates MII_CTRL1000 | ||
323 | * bits, when in 1000Base-T mode, to ethtool | ||
324 | * advertisement settings. | ||
325 | */ | ||
326 | static inline u32 mii_ctrl1000_to_ethtool_adv_t(u32 adv) | ||
327 | { | ||
328 | u32 result = 0; | ||
329 | |||
330 | if (adv & ADVERTISE_1000HALF) | ||
331 | result |= ADVERTISED_1000baseT_Half; | ||
332 | if (adv & ADVERTISE_1000FULL) | ||
333 | result |= ADVERTISED_1000baseT_Full; | ||
334 | |||
335 | return result; | ||
336 | } | ||
337 | |||
338 | /** | ||
339 | * mii_lpa_to_ethtool_lpa_t | ||
340 | * @adv: value of the MII_LPA register | ||
341 | * | ||
342 | * A small helper function that translates MII_LPA | ||
343 | * bits, when in 1000Base-T mode, to ethtool | ||
344 | * LP advertisement settings. | ||
345 | */ | ||
346 | static inline u32 mii_lpa_to_ethtool_lpa_t(u32 lpa) | ||
347 | { | ||
348 | u32 result = 0; | ||
349 | |||
350 | if (lpa & LPA_LPACK) | ||
351 | result |= ADVERTISED_Autoneg; | ||
352 | |||
353 | return result | mii_adv_to_ethtool_adv_t(lpa); | ||
354 | } | ||
355 | |||
356 | /** | ||
357 | * mii_stat1000_to_ethtool_lpa_t | ||
358 | * @adv: value of the MII_STAT1000 register | ||
359 | * | ||
360 | * A small helper function that translates MII_STAT1000 | ||
361 | * bits, when in 1000Base-T mode, to ethtool | ||
362 | * advertisement settings. | ||
363 | */ | ||
364 | static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa) | ||
365 | { | ||
366 | u32 result = 0; | ||
367 | |||
368 | if (lpa & LPA_1000HALF) | ||
369 | result |= ADVERTISED_1000baseT_Half; | ||
370 | if (lpa & LPA_1000FULL) | ||
371 | result |= ADVERTISED_1000baseT_Full; | ||
372 | |||
373 | return result; | ||
374 | } | ||
375 | |||
376 | /** | ||
377 | * ethtool_adv_to_mii_adv_x | ||
378 | * @ethadv: the ethtool advertisement settings | ||
379 | * | ||
380 | * A small helper function that translates ethtool advertisement | ||
381 | * settings to phy autonegotiation advertisements for the | ||
382 | * MII_CTRL1000 register when in 1000Base-X mode. | ||
383 | */ | ||
384 | static inline u32 ethtool_adv_to_mii_adv_x(u32 ethadv) | ||
385 | { | ||
386 | u32 result = 0; | ||
387 | |||
388 | if (ethadv & ADVERTISED_1000baseT_Half) | ||
389 | result |= ADVERTISE_1000XHALF; | ||
390 | if (ethadv & ADVERTISED_1000baseT_Full) | ||
391 | result |= ADVERTISE_1000XFULL; | ||
392 | if (ethadv & ADVERTISED_Pause) | ||
393 | result |= ADVERTISE_1000XPAUSE; | ||
394 | if (ethadv & ADVERTISED_Asym_Pause) | ||
395 | result |= ADVERTISE_1000XPSE_ASYM; | ||
396 | |||
397 | return result; | ||
398 | } | ||
399 | |||
400 | /** | ||
401 | * mii_adv_to_ethtool_adv_x | ||
402 | * @adv: value of the MII_CTRL1000 register | ||
403 | * | ||
404 | * A small helper function that translates MII_CTRL1000 | ||
405 | * bits, when in 1000Base-X mode, to ethtool | ||
406 | * advertisement settings. | ||
407 | */ | ||
408 | static inline u32 mii_adv_to_ethtool_adv_x(u32 adv) | ||
409 | { | ||
410 | u32 result = 0; | ||
411 | |||
412 | if (adv & ADVERTISE_1000XHALF) | ||
413 | result |= ADVERTISED_1000baseT_Half; | ||
414 | if (adv & ADVERTISE_1000XFULL) | ||
415 | result |= ADVERTISED_1000baseT_Full; | ||
416 | if (adv & ADVERTISE_1000XPAUSE) | ||
417 | result |= ADVERTISED_Pause; | ||
418 | if (adv & ADVERTISE_1000XPSE_ASYM) | ||
419 | result |= ADVERTISED_Asym_Pause; | ||
420 | |||
421 | return result; | ||
422 | } | ||
423 | |||
424 | /** | ||
425 | * mii_lpa_to_ethtool_lpa_x | ||
426 | * @adv: value of the MII_LPA register | ||
427 | * | ||
428 | * A small helper function that translates MII_LPA | ||
429 | * bits, when in 1000Base-X mode, to ethtool | ||
430 | * LP advertisement settings. | ||
431 | */ | ||
432 | static inline u32 mii_lpa_to_ethtool_lpa_x(u32 lpa) | ||
433 | { | ||
434 | u32 result = 0; | ||
435 | |||
436 | if (lpa & LPA_LPACK) | ||
437 | result |= ADVERTISED_Autoneg; | ||
438 | |||
439 | return result | mii_adv_to_ethtool_adv_x(lpa); | ||
440 | } | ||
441 | |||
442 | /** | ||
243 | * mii_advertise_flowctrl - get flow control advertisement flags | 443 | * mii_advertise_flowctrl - get flow control advertisement flags |
244 | * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both) | 444 | * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both) |
245 | */ | 445 | */ |
diff --git a/include/linux/neighbour.h b/include/linux/neighbour.h index a7003b7a695d..b188f68a08c9 100644 --- a/include/linux/neighbour.h +++ b/include/linux/neighbour.h | |||
@@ -116,6 +116,7 @@ enum { | |||
116 | NDTPA_PROXY_DELAY, /* u64, msecs */ | 116 | NDTPA_PROXY_DELAY, /* u64, msecs */ |
117 | NDTPA_PROXY_QLEN, /* u32 */ | 117 | NDTPA_PROXY_QLEN, /* u32 */ |
118 | NDTPA_LOCKTIME, /* u64, msecs */ | 118 | NDTPA_LOCKTIME, /* u64, msecs */ |
119 | NDTPA_QUEUE_LENBYTES, /* u32 */ | ||
119 | __NDTPA_MAX | 120 | __NDTPA_MAX |
120 | }; | 121 | }; |
121 | #define NDTPA_MAX (__NDTPA_MAX - 1) | 122 | #define NDTPA_MAX (__NDTPA_MAX - 1) |
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h new file mode 100644 index 000000000000..77f5202977ce --- /dev/null +++ b/include/linux/netdev_features.h | |||
@@ -0,0 +1,146 @@ | |||
1 | /* | ||
2 | * Network device features. | ||
3 | * | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | #ifndef _LINUX_NETDEV_FEATURES_H | ||
11 | #define _LINUX_NETDEV_FEATURES_H | ||
12 | |||
13 | #include <linux/types.h> | ||
14 | |||
15 | typedef u64 netdev_features_t; | ||
16 | |||
17 | enum { | ||
18 | NETIF_F_SG_BIT, /* Scatter/gather IO. */ | ||
19 | NETIF_F_IP_CSUM_BIT, /* Can checksum TCP/UDP over IPv4. */ | ||
20 | __UNUSED_NETIF_F_1, | ||
21 | NETIF_F_HW_CSUM_BIT, /* Can checksum all the packets. */ | ||
22 | NETIF_F_IPV6_CSUM_BIT, /* Can checksum TCP/UDP over IPV6 */ | ||
23 | NETIF_F_HIGHDMA_BIT, /* Can DMA to high memory. */ | ||
24 | NETIF_F_FRAGLIST_BIT, /* Scatter/gather IO. */ | ||
25 | NETIF_F_HW_VLAN_TX_BIT, /* Transmit VLAN hw acceleration */ | ||
26 | NETIF_F_HW_VLAN_RX_BIT, /* Receive VLAN hw acceleration */ | ||
27 | NETIF_F_HW_VLAN_FILTER_BIT, /* Receive filtering on VLAN */ | ||
28 | NETIF_F_VLAN_CHALLENGED_BIT, /* Device cannot handle VLAN packets */ | ||
29 | NETIF_F_GSO_BIT, /* Enable software GSO. */ | ||
30 | NETIF_F_LLTX_BIT, /* LockLess TX - deprecated. Please */ | ||
31 | /* do not use LLTX in new drivers */ | ||
32 | NETIF_F_NETNS_LOCAL_BIT, /* Does not change network namespaces */ | ||
33 | NETIF_F_GRO_BIT, /* Generic receive offload */ | ||
34 | NETIF_F_LRO_BIT, /* large receive offload */ | ||
35 | |||
36 | /**/NETIF_F_GSO_SHIFT, /* keep the order of SKB_GSO_* bits */ | ||
37 | NETIF_F_TSO_BIT /* ... TCPv4 segmentation */ | ||
38 | = NETIF_F_GSO_SHIFT, | ||
39 | NETIF_F_UFO_BIT, /* ... UDPv4 fragmentation */ | ||
40 | NETIF_F_GSO_ROBUST_BIT, /* ... ->SKB_GSO_DODGY */ | ||
41 | NETIF_F_TSO_ECN_BIT, /* ... TCP ECN support */ | ||
42 | NETIF_F_TSO6_BIT, /* ... TCPv6 segmentation */ | ||
43 | NETIF_F_FSO_BIT, /* ... FCoE segmentation */ | ||
44 | NETIF_F_GSO_RESERVED1, /* ... free (fill GSO_MASK to 8 bits) */ | ||
45 | /**/NETIF_F_GSO_LAST, /* [can't be last bit, see GSO_MASK] */ | ||
46 | NETIF_F_GSO_RESERVED2 /* ... free (fill GSO_MASK to 8 bits) */ | ||
47 | = NETIF_F_GSO_LAST, | ||
48 | |||
49 | NETIF_F_FCOE_CRC_BIT, /* FCoE CRC32 */ | ||
50 | NETIF_F_SCTP_CSUM_BIT, /* SCTP checksum offload */ | ||
51 | NETIF_F_FCOE_MTU_BIT, /* Supports max FCoE MTU, 2158 bytes*/ | ||
52 | NETIF_F_NTUPLE_BIT, /* N-tuple filters supported */ | ||
53 | NETIF_F_RXHASH_BIT, /* Receive hashing offload */ | ||
54 | NETIF_F_RXCSUM_BIT, /* Receive checksumming offload */ | ||
55 | NETIF_F_NOCACHE_COPY_BIT, /* Use no-cache copyfromuser */ | ||
56 | NETIF_F_LOOPBACK_BIT, /* Enable loopback */ | ||
57 | |||
58 | /* | ||
59 | * Add your fresh new feature above and remember to update | ||
60 | * netdev_features_strings[] in net/core/ethtool.c and maybe | ||
61 | * some feature mask #defines below. Please also describe it | ||
62 | * in Documentation/networking/netdev-features.txt. | ||
63 | */ | ||
64 | |||
65 | /**/NETDEV_FEATURE_COUNT | ||
66 | }; | ||
67 | |||
68 | /* copy'n'paste compression ;) */ | ||
69 | #define __NETIF_F_BIT(bit) ((netdev_features_t)1 << (bit)) | ||
70 | #define __NETIF_F(name) __NETIF_F_BIT(NETIF_F_##name##_BIT) | ||
71 | |||
72 | #define NETIF_F_FCOE_CRC __NETIF_F(FCOE_CRC) | ||
73 | #define NETIF_F_FCOE_MTU __NETIF_F(FCOE_MTU) | ||
74 | #define NETIF_F_FRAGLIST __NETIF_F(FRAGLIST) | ||
75 | #define NETIF_F_FSO __NETIF_F(FSO) | ||
76 | #define NETIF_F_GRO __NETIF_F(GRO) | ||
77 | #define NETIF_F_GSO __NETIF_F(GSO) | ||
78 | #define NETIF_F_GSO_ROBUST __NETIF_F(GSO_ROBUST) | ||
79 | #define NETIF_F_HIGHDMA __NETIF_F(HIGHDMA) | ||
80 | #define NETIF_F_HW_CSUM __NETIF_F(HW_CSUM) | ||
81 | #define NETIF_F_HW_VLAN_FILTER __NETIF_F(HW_VLAN_FILTER) | ||
82 | #define NETIF_F_HW_VLAN_RX __NETIF_F(HW_VLAN_RX) | ||
83 | #define NETIF_F_HW_VLAN_TX __NETIF_F(HW_VLAN_TX) | ||
84 | #define NETIF_F_IP_CSUM __NETIF_F(IP_CSUM) | ||
85 | #define NETIF_F_IPV6_CSUM __NETIF_F(IPV6_CSUM) | ||
86 | #define NETIF_F_LLTX __NETIF_F(LLTX) | ||
87 | #define NETIF_F_LOOPBACK __NETIF_F(LOOPBACK) | ||
88 | #define NETIF_F_LRO __NETIF_F(LRO) | ||
89 | #define NETIF_F_NETNS_LOCAL __NETIF_F(NETNS_LOCAL) | ||
90 | #define NETIF_F_NOCACHE_COPY __NETIF_F(NOCACHE_COPY) | ||
91 | #define NETIF_F_NTUPLE __NETIF_F(NTUPLE) | ||
92 | #define NETIF_F_RXCSUM __NETIF_F(RXCSUM) | ||
93 | #define NETIF_F_RXHASH __NETIF_F(RXHASH) | ||
94 | #define NETIF_F_SCTP_CSUM __NETIF_F(SCTP_CSUM) | ||
95 | #define NETIF_F_SG __NETIF_F(SG) | ||
96 | #define NETIF_F_TSO6 __NETIF_F(TSO6) | ||
97 | #define NETIF_F_TSO_ECN __NETIF_F(TSO_ECN) | ||
98 | #define NETIF_F_TSO __NETIF_F(TSO) | ||
99 | #define NETIF_F_UFO __NETIF_F(UFO) | ||
100 | #define NETIF_F_VLAN_CHALLENGED __NETIF_F(VLAN_CHALLENGED) | ||
101 | |||
102 | /* Features valid for ethtool to change */ | ||
103 | /* = all defined minus driver/device-class-related */ | ||
104 | #define NETIF_F_NEVER_CHANGE (NETIF_F_VLAN_CHALLENGED | \ | ||
105 | NETIF_F_LLTX | NETIF_F_NETNS_LOCAL) | ||
106 | |||
107 | /* remember that ((t)1 << t_BITS) is undefined in C99 */ | ||
108 | #define NETIF_F_ETHTOOL_BITS ((__NETIF_F_BIT(NETDEV_FEATURE_COUNT - 1) | \ | ||
109 | (__NETIF_F_BIT(NETDEV_FEATURE_COUNT - 1) - 1)) & \ | ||
110 | ~NETIF_F_NEVER_CHANGE) | ||
111 | |||
112 | /* Segmentation offload feature mask */ | ||
113 | #define NETIF_F_GSO_MASK (__NETIF_F_BIT(NETIF_F_GSO_LAST + 1) - \ | ||
114 | __NETIF_F_BIT(NETIF_F_GSO_SHIFT)) | ||
115 | |||
116 | /* List of features with software fallbacks. */ | ||
117 | #define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | \ | ||
118 | NETIF_F_TSO6 | NETIF_F_UFO) | ||
119 | |||
120 | #define NETIF_F_GEN_CSUM NETIF_F_HW_CSUM | ||
121 | #define NETIF_F_V4_CSUM (NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM) | ||
122 | #define NETIF_F_V6_CSUM (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM) | ||
123 | #define NETIF_F_ALL_CSUM (NETIF_F_V4_CSUM | NETIF_F_V6_CSUM) | ||
124 | |||
125 | #define NETIF_F_ALL_TSO (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) | ||
126 | |||
127 | #define NETIF_F_ALL_FCOE (NETIF_F_FCOE_CRC | NETIF_F_FCOE_MTU | \ | ||
128 | NETIF_F_FSO) | ||
129 | |||
130 | /* | ||
131 | * If one device supports one of these features, then enable them | ||
132 | * for all in netdev_increment_features. | ||
133 | */ | ||
134 | #define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \ | ||
135 | NETIF_F_SG | NETIF_F_HIGHDMA | \ | ||
136 | NETIF_F_FRAGLIST | NETIF_F_VLAN_CHALLENGED) | ||
137 | /* | ||
138 | * If one device doesn't support one of these features, then disable it | ||
139 | * for all in netdev_increment_features. | ||
140 | */ | ||
141 | #define NETIF_F_ALL_FOR_ALL (NETIF_F_NOCACHE_COPY | NETIF_F_FSO) | ||
142 | |||
143 | /* changeable features with no special hardware requirements */ | ||
144 | #define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO) | ||
145 | |||
146 | #endif /* _LINUX_NETDEV_FEATURES_H */ | ||
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index cbeb5867cff7..999bb264fe27 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -50,6 +50,9 @@ | |||
50 | #ifdef CONFIG_DCB | 50 | #ifdef CONFIG_DCB |
51 | #include <net/dcbnl.h> | 51 | #include <net/dcbnl.h> |
52 | #endif | 52 | #endif |
53 | #include <net/netprio_cgroup.h> | ||
54 | |||
55 | #include <linux/netdev_features.h> | ||
53 | 56 | ||
54 | struct vlan_group; | 57 | struct vlan_group; |
55 | struct netpoll_info; | 58 | struct netpoll_info; |
@@ -212,6 +215,11 @@ enum { | |||
212 | #include <linux/cache.h> | 215 | #include <linux/cache.h> |
213 | #include <linux/skbuff.h> | 216 | #include <linux/skbuff.h> |
214 | 217 | ||
218 | #ifdef CONFIG_RPS | ||
219 | #include <linux/jump_label.h> | ||
220 | extern struct jump_label_key rps_needed; | ||
221 | #endif | ||
222 | |||
215 | struct neighbour; | 223 | struct neighbour; |
216 | struct neigh_parms; | 224 | struct neigh_parms; |
217 | struct sk_buff; | 225 | struct sk_buff; |
@@ -272,16 +280,11 @@ struct hh_cache { | |||
272 | * | 280 | * |
273 | * We could use other alignment values, but we must maintain the | 281 | * We could use other alignment values, but we must maintain the |
274 | * relationship HH alignment <= LL alignment. | 282 | * relationship HH alignment <= LL alignment. |
275 | * | ||
276 | * LL_ALLOCATED_SPACE also takes into account the tailroom the device | ||
277 | * may need. | ||
278 | */ | 283 | */ |
279 | #define LL_RESERVED_SPACE(dev) \ | 284 | #define LL_RESERVED_SPACE(dev) \ |
280 | ((((dev)->hard_header_len+(dev)->needed_headroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) | 285 | ((((dev)->hard_header_len+(dev)->needed_headroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) |
281 | #define LL_RESERVED_SPACE_EXTRA(dev,extra) \ | 286 | #define LL_RESERVED_SPACE_EXTRA(dev,extra) \ |
282 | ((((dev)->hard_header_len+(dev)->needed_headroom+(extra))&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) | 287 | ((((dev)->hard_header_len+(dev)->needed_headroom+(extra))&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) |
283 | #define LL_ALLOCATED_SPACE(dev) \ | ||
284 | ((((dev)->hard_header_len+(dev)->needed_headroom+(dev)->needed_tailroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) | ||
285 | 288 | ||
286 | struct header_ops { | 289 | struct header_ops { |
287 | int (*create) (struct sk_buff *skb, struct net_device *dev, | 290 | int (*create) (struct sk_buff *skb, struct net_device *dev, |
@@ -530,7 +533,7 @@ struct netdev_queue { | |||
530 | struct Qdisc *qdisc; | 533 | struct Qdisc *qdisc; |
531 | unsigned long state; | 534 | unsigned long state; |
532 | struct Qdisc *qdisc_sleeping; | 535 | struct Qdisc *qdisc_sleeping; |
533 | #if defined(CONFIG_RPS) || defined(CONFIG_XPS) | 536 | #ifdef CONFIG_SYSFS |
534 | struct kobject kobj; | 537 | struct kobject kobj; |
535 | #endif | 538 | #endif |
536 | #if defined(CONFIG_XPS) && defined(CONFIG_NUMA) | 539 | #if defined(CONFIG_XPS) && defined(CONFIG_NUMA) |
@@ -545,6 +548,12 @@ struct netdev_queue { | |||
545 | * please use this field instead of dev->trans_start | 548 | * please use this field instead of dev->trans_start |
546 | */ | 549 | */ |
547 | unsigned long trans_start; | 550 | unsigned long trans_start; |
551 | |||
552 | /* | ||
553 | * Number of TX timeouts for this queue | ||
554 | * (/sys/class/net/DEV/Q/trans_timeout) | ||
555 | */ | ||
556 | unsigned long trans_timeout; | ||
548 | } ____cacheline_aligned_in_smp; | 557 | } ____cacheline_aligned_in_smp; |
549 | 558 | ||
550 | static inline int netdev_queue_numa_node_read(const struct netdev_queue *q) | 559 | static inline int netdev_queue_numa_node_read(const struct netdev_queue *q) |
@@ -845,12 +854,13 @@ struct netdev_tc_txq { | |||
845 | * Called to release previously enslaved netdev. | 854 | * Called to release previously enslaved netdev. |
846 | * | 855 | * |
847 | * Feature/offload setting functions. | 856 | * Feature/offload setting functions. |
848 | * u32 (*ndo_fix_features)(struct net_device *dev, u32 features); | 857 | * netdev_features_t (*ndo_fix_features)(struct net_device *dev, |
858 | * netdev_features_t features); | ||
849 | * Adjusts the requested feature flags according to device-specific | 859 | * Adjusts the requested feature flags according to device-specific |
850 | * constraints, and returns the resulting flags. Must not modify | 860 | * constraints, and returns the resulting flags. Must not modify |
851 | * the device state. | 861 | * the device state. |
852 | * | 862 | * |
853 | * int (*ndo_set_features)(struct net_device *dev, u32 features); | 863 | * int (*ndo_set_features)(struct net_device *dev, netdev_features_t features); |
854 | * Called to update device configuration to new features. Passed | 864 | * Called to update device configuration to new features. Passed |
855 | * feature set might be less than what was returned by ndo_fix_features()). | 865 | * feature set might be less than what was returned by ndo_fix_features()). |
856 | * Must return >0 or -errno if it changed dev->features itself. | 866 | * Must return >0 or -errno if it changed dev->features itself. |
@@ -944,10 +954,10 @@ struct net_device_ops { | |||
944 | struct net_device *slave_dev); | 954 | struct net_device *slave_dev); |
945 | int (*ndo_del_slave)(struct net_device *dev, | 955 | int (*ndo_del_slave)(struct net_device *dev, |
946 | struct net_device *slave_dev); | 956 | struct net_device *slave_dev); |
947 | u32 (*ndo_fix_features)(struct net_device *dev, | 957 | netdev_features_t (*ndo_fix_features)(struct net_device *dev, |
948 | u32 features); | 958 | netdev_features_t features); |
949 | int (*ndo_set_features)(struct net_device *dev, | 959 | int (*ndo_set_features)(struct net_device *dev, |
950 | u32 features); | 960 | netdev_features_t features); |
951 | }; | 961 | }; |
952 | 962 | ||
953 | /* | 963 | /* |
@@ -997,91 +1007,13 @@ struct net_device { | |||
997 | struct list_head unreg_list; | 1007 | struct list_head unreg_list; |
998 | 1008 | ||
999 | /* currently active device features */ | 1009 | /* currently active device features */ |
1000 | u32 features; | 1010 | netdev_features_t features; |
1001 | /* user-changeable features */ | 1011 | /* user-changeable features */ |
1002 | u32 hw_features; | 1012 | netdev_features_t hw_features; |
1003 | /* user-requested features */ | 1013 | /* user-requested features */ |
1004 | u32 wanted_features; | 1014 | netdev_features_t wanted_features; |
1005 | /* mask of features inheritable by VLAN devices */ | 1015 | /* mask of features inheritable by VLAN devices */ |
1006 | u32 vlan_features; | 1016 | netdev_features_t vlan_features; |
1007 | |||
1008 | /* Net device feature bits; if you change something, | ||
1009 | * also update netdev_features_strings[] in ethtool.c */ | ||
1010 | |||
1011 | #define NETIF_F_SG 1 /* Scatter/gather IO. */ | ||
1012 | #define NETIF_F_IP_CSUM 2 /* Can checksum TCP/UDP over IPv4. */ | ||
1013 | #define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */ | ||
1014 | #define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */ | ||
1015 | #define NETIF_F_IPV6_CSUM 16 /* Can checksum TCP/UDP over IPV6 */ | ||
1016 | #define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */ | ||
1017 | #define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */ | ||
1018 | #define NETIF_F_HW_VLAN_TX 128 /* Transmit VLAN hw acceleration */ | ||
1019 | #define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */ | ||
1020 | #define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */ | ||
1021 | #define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */ | ||
1022 | #define NETIF_F_GSO 2048 /* Enable software GSO. */ | ||
1023 | #define NETIF_F_LLTX 4096 /* LockLess TX - deprecated. Please */ | ||
1024 | /* do not use LLTX in new drivers */ | ||
1025 | #define NETIF_F_NETNS_LOCAL 8192 /* Does not change network namespaces */ | ||
1026 | #define NETIF_F_GRO 16384 /* Generic receive offload */ | ||
1027 | #define NETIF_F_LRO 32768 /* large receive offload */ | ||
1028 | |||
1029 | /* the GSO_MASK reserves bits 16 through 23 */ | ||
1030 | #define NETIF_F_FCOE_CRC (1 << 24) /* FCoE CRC32 */ | ||
1031 | #define NETIF_F_SCTP_CSUM (1 << 25) /* SCTP checksum offload */ | ||
1032 | #define NETIF_F_FCOE_MTU (1 << 26) /* Supports max FCoE MTU, 2158 bytes*/ | ||
1033 | #define NETIF_F_NTUPLE (1 << 27) /* N-tuple filters supported */ | ||
1034 | #define NETIF_F_RXHASH (1 << 28) /* Receive hashing offload */ | ||
1035 | #define NETIF_F_RXCSUM (1 << 29) /* Receive checksumming offload */ | ||
1036 | #define NETIF_F_NOCACHE_COPY (1 << 30) /* Use no-cache copyfromuser */ | ||
1037 | #define NETIF_F_LOOPBACK (1 << 31) /* Enable loopback */ | ||
1038 | |||
1039 | /* Segmentation offload features */ | ||
1040 | #define NETIF_F_GSO_SHIFT 16 | ||
1041 | #define NETIF_F_GSO_MASK 0x00ff0000 | ||
1042 | #define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT) | ||
1043 | #define NETIF_F_UFO (SKB_GSO_UDP << NETIF_F_GSO_SHIFT) | ||
1044 | #define NETIF_F_GSO_ROBUST (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT) | ||
1045 | #define NETIF_F_TSO_ECN (SKB_GSO_TCP_ECN << NETIF_F_GSO_SHIFT) | ||
1046 | #define NETIF_F_TSO6 (SKB_GSO_TCPV6 << NETIF_F_GSO_SHIFT) | ||
1047 | #define NETIF_F_FSO (SKB_GSO_FCOE << NETIF_F_GSO_SHIFT) | ||
1048 | |||
1049 | /* Features valid for ethtool to change */ | ||
1050 | /* = all defined minus driver/device-class-related */ | ||
1051 | #define NETIF_F_NEVER_CHANGE (NETIF_F_VLAN_CHALLENGED | \ | ||
1052 | NETIF_F_LLTX | NETIF_F_NETNS_LOCAL) | ||
1053 | #define NETIF_F_ETHTOOL_BITS (0xff3fffff & ~NETIF_F_NEVER_CHANGE) | ||
1054 | |||
1055 | /* List of features with software fallbacks. */ | ||
1056 | #define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | \ | ||
1057 | NETIF_F_TSO6 | NETIF_F_UFO) | ||
1058 | |||
1059 | |||
1060 | #define NETIF_F_GEN_CSUM (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM) | ||
1061 | #define NETIF_F_V4_CSUM (NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM) | ||
1062 | #define NETIF_F_V6_CSUM (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM) | ||
1063 | #define NETIF_F_ALL_CSUM (NETIF_F_V4_CSUM | NETIF_F_V6_CSUM) | ||
1064 | |||
1065 | #define NETIF_F_ALL_TSO (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) | ||
1066 | |||
1067 | #define NETIF_F_ALL_FCOE (NETIF_F_FCOE_CRC | NETIF_F_FCOE_MTU | \ | ||
1068 | NETIF_F_FSO) | ||
1069 | |||
1070 | /* | ||
1071 | * If one device supports one of these features, then enable them | ||
1072 | * for all in netdev_increment_features. | ||
1073 | */ | ||
1074 | #define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \ | ||
1075 | NETIF_F_SG | NETIF_F_HIGHDMA | \ | ||
1076 | NETIF_F_FRAGLIST | NETIF_F_VLAN_CHALLENGED) | ||
1077 | /* | ||
1078 | * If one device doesn't support one of these features, then disable it | ||
1079 | * for all in netdev_increment_features. | ||
1080 | */ | ||
1081 | #define NETIF_F_ALL_FOR_ALL (NETIF_F_NOCACHE_COPY | NETIF_F_FSO) | ||
1082 | |||
1083 | /* changeable features with no special hardware requirements */ | ||
1084 | #define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO) | ||
1085 | 1017 | ||
1086 | /* Interface index. Unique device identifier */ | 1018 | /* Interface index. Unique device identifier */ |
1087 | int ifindex; | 1019 | int ifindex; |
@@ -1184,9 +1116,11 @@ struct net_device { | |||
1184 | 1116 | ||
1185 | unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ | 1117 | unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ |
1186 | 1118 | ||
1187 | #if defined(CONFIG_RPS) || defined(CONFIG_XPS) | 1119 | #ifdef CONFIG_SYSFS |
1188 | struct kset *queues_kset; | 1120 | struct kset *queues_kset; |
1121 | #endif | ||
1189 | 1122 | ||
1123 | #ifdef CONFIG_RPS | ||
1190 | struct netdev_rx_queue *_rx; | 1124 | struct netdev_rx_queue *_rx; |
1191 | 1125 | ||
1192 | /* Number of RX queues allocated at register_netdev() time */ | 1126 | /* Number of RX queues allocated at register_netdev() time */ |
@@ -1312,6 +1246,9 @@ struct net_device { | |||
1312 | /* max exchange id for FCoE LRO by ddp */ | 1246 | /* max exchange id for FCoE LRO by ddp */ |
1313 | unsigned int fcoe_ddp_xid; | 1247 | unsigned int fcoe_ddp_xid; |
1314 | #endif | 1248 | #endif |
1249 | #if IS_ENABLED(CONFIG_NETPRIO_CGROUP) | ||
1250 | struct netprio_map __rcu *priomap; | ||
1251 | #endif | ||
1315 | /* phy device may attach itself for hardware timestamping */ | 1252 | /* phy device may attach itself for hardware timestamping */ |
1316 | struct phy_device *phydev; | 1253 | struct phy_device *phydev; |
1317 | 1254 | ||
@@ -1515,7 +1452,7 @@ struct packet_type { | |||
1515 | struct packet_type *, | 1452 | struct packet_type *, |
1516 | struct net_device *); | 1453 | struct net_device *); |
1517 | struct sk_buff *(*gso_segment)(struct sk_buff *skb, | 1454 | struct sk_buff *(*gso_segment)(struct sk_buff *skb, |
1518 | u32 features); | 1455 | netdev_features_t features); |
1519 | int (*gso_send_check)(struct sk_buff *skb); | 1456 | int (*gso_send_check)(struct sk_buff *skb); |
1520 | struct sk_buff **(*gro_receive)(struct sk_buff **head, | 1457 | struct sk_buff **(*gro_receive)(struct sk_buff **head, |
1521 | struct sk_buff *skb); | 1458 | struct sk_buff *skb); |
@@ -2520,7 +2457,8 @@ extern int netdev_set_master(struct net_device *dev, struct net_device *master) | |||
2520 | extern int netdev_set_bond_master(struct net_device *dev, | 2457 | extern int netdev_set_bond_master(struct net_device *dev, |
2521 | struct net_device *master); | 2458 | struct net_device *master); |
2522 | extern int skb_checksum_help(struct sk_buff *skb); | 2459 | extern int skb_checksum_help(struct sk_buff *skb); |
2523 | extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, u32 features); | 2460 | extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, |
2461 | netdev_features_t features); | ||
2524 | #ifdef CONFIG_BUG | 2462 | #ifdef CONFIG_BUG |
2525 | extern void netdev_rx_csum_fault(struct net_device *dev); | 2463 | extern void netdev_rx_csum_fault(struct net_device *dev); |
2526 | #else | 2464 | #else |
@@ -2547,11 +2485,13 @@ extern const char *netdev_drivername(const struct net_device *dev); | |||
2547 | 2485 | ||
2548 | extern void linkwatch_run_queue(void); | 2486 | extern void linkwatch_run_queue(void); |
2549 | 2487 | ||
2550 | static inline u32 netdev_get_wanted_features(struct net_device *dev) | 2488 | static inline netdev_features_t netdev_get_wanted_features( |
2489 | struct net_device *dev) | ||
2551 | { | 2490 | { |
2552 | return (dev->features & ~dev->hw_features) | dev->wanted_features; | 2491 | return (dev->features & ~dev->hw_features) | dev->wanted_features; |
2553 | } | 2492 | } |
2554 | u32 netdev_increment_features(u32 all, u32 one, u32 mask); | 2493 | netdev_features_t netdev_increment_features(netdev_features_t all, |
2494 | netdev_features_t one, netdev_features_t mask); | ||
2555 | int __netdev_update_features(struct net_device *dev); | 2495 | int __netdev_update_features(struct net_device *dev); |
2556 | void netdev_update_features(struct net_device *dev); | 2496 | void netdev_update_features(struct net_device *dev); |
2557 | void netdev_change_features(struct net_device *dev); | 2497 | void netdev_change_features(struct net_device *dev); |
@@ -2559,21 +2499,31 @@ void netdev_change_features(struct net_device *dev); | |||
2559 | void netif_stacked_transfer_operstate(const struct net_device *rootdev, | 2499 | void netif_stacked_transfer_operstate(const struct net_device *rootdev, |
2560 | struct net_device *dev); | 2500 | struct net_device *dev); |
2561 | 2501 | ||
2562 | u32 netif_skb_features(struct sk_buff *skb); | 2502 | netdev_features_t netif_skb_features(struct sk_buff *skb); |
2563 | 2503 | ||
2564 | static inline int net_gso_ok(u32 features, int gso_type) | 2504 | static inline int net_gso_ok(netdev_features_t features, int gso_type) |
2565 | { | 2505 | { |
2566 | int feature = gso_type << NETIF_F_GSO_SHIFT; | 2506 | netdev_features_t feature = gso_type << NETIF_F_GSO_SHIFT; |
2507 | |||
2508 | /* check flags correspondence */ | ||
2509 | BUILD_BUG_ON(SKB_GSO_TCPV4 != (NETIF_F_TSO >> NETIF_F_GSO_SHIFT)); | ||
2510 | BUILD_BUG_ON(SKB_GSO_UDP != (NETIF_F_UFO >> NETIF_F_GSO_SHIFT)); | ||
2511 | BUILD_BUG_ON(SKB_GSO_DODGY != (NETIF_F_GSO_ROBUST >> NETIF_F_GSO_SHIFT)); | ||
2512 | BUILD_BUG_ON(SKB_GSO_TCP_ECN != (NETIF_F_TSO_ECN >> NETIF_F_GSO_SHIFT)); | ||
2513 | BUILD_BUG_ON(SKB_GSO_TCPV6 != (NETIF_F_TSO6 >> NETIF_F_GSO_SHIFT)); | ||
2514 | BUILD_BUG_ON(SKB_GSO_FCOE != (NETIF_F_FSO >> NETIF_F_GSO_SHIFT)); | ||
2515 | |||
2567 | return (features & feature) == feature; | 2516 | return (features & feature) == feature; |
2568 | } | 2517 | } |
2569 | 2518 | ||
2570 | static inline int skb_gso_ok(struct sk_buff *skb, u32 features) | 2519 | static inline int skb_gso_ok(struct sk_buff *skb, netdev_features_t features) |
2571 | { | 2520 | { |
2572 | return net_gso_ok(features, skb_shinfo(skb)->gso_type) && | 2521 | return net_gso_ok(features, skb_shinfo(skb)->gso_type) && |
2573 | (!skb_has_frag_list(skb) || (features & NETIF_F_FRAGLIST)); | 2522 | (!skb_has_frag_list(skb) || (features & NETIF_F_FRAGLIST)); |
2574 | } | 2523 | } |
2575 | 2524 | ||
2576 | static inline int netif_needs_gso(struct sk_buff *skb, int features) | 2525 | static inline int netif_needs_gso(struct sk_buff *skb, |
2526 | netdev_features_t features) | ||
2577 | { | 2527 | { |
2578 | return skb_is_gso(skb) && (!skb_gso_ok(skb, features) || | 2528 | return skb_is_gso(skb) && (!skb_gso_ok(skb, features) || |
2579 | unlikely(skb->ip_summed != CHECKSUM_PARTIAL)); | 2529 | unlikely(skb->ip_summed != CHECKSUM_PARTIAL)); |
@@ -2592,22 +2542,6 @@ static inline int netif_is_bond_slave(struct net_device *dev) | |||
2592 | 2542 | ||
2593 | extern struct pernet_operations __net_initdata loopback_net_ops; | 2543 | extern struct pernet_operations __net_initdata loopback_net_ops; |
2594 | 2544 | ||
2595 | static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev) | ||
2596 | { | ||
2597 | if (dev->features & NETIF_F_RXCSUM) | ||
2598 | return 1; | ||
2599 | if (!dev->ethtool_ops || !dev->ethtool_ops->get_rx_csum) | ||
2600 | return 0; | ||
2601 | return dev->ethtool_ops->get_rx_csum(dev); | ||
2602 | } | ||
2603 | |||
2604 | static inline u32 dev_ethtool_get_flags(struct net_device *dev) | ||
2605 | { | ||
2606 | if (!dev->ethtool_ops || !dev->ethtool_ops->get_flags) | ||
2607 | return 0; | ||
2608 | return dev->ethtool_ops->get_flags(dev); | ||
2609 | } | ||
2610 | |||
2611 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ | 2545 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ |
2612 | 2546 | ||
2613 | /* netdev_printk helpers, similar to dev_printk */ | 2547 | /* netdev_printk helpers, similar to dev_printk */ |
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 857f5026ced6..b809265607d0 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h | |||
@@ -162,6 +162,24 @@ extern struct ctl_path nf_net_ipv4_netfilter_sysctl_path[]; | |||
162 | 162 | ||
163 | extern struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; | 163 | extern struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; |
164 | 164 | ||
165 | #if defined(CONFIG_JUMP_LABEL) | ||
166 | #include <linux/jump_label.h> | ||
167 | extern struct jump_label_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; | ||
168 | static inline bool nf_hooks_active(u_int8_t pf, unsigned int hook) | ||
169 | { | ||
170 | if (__builtin_constant_p(pf) && | ||
171 | __builtin_constant_p(hook)) | ||
172 | return static_branch(&nf_hooks_needed[pf][hook]); | ||
173 | |||
174 | return !list_empty(&nf_hooks[pf][hook]); | ||
175 | } | ||
176 | #else | ||
177 | static inline bool nf_hooks_active(u_int8_t pf, unsigned int hook) | ||
178 | { | ||
179 | return !list_empty(&nf_hooks[pf][hook]); | ||
180 | } | ||
181 | #endif | ||
182 | |||
165 | int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb, | 183 | int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb, |
166 | struct net_device *indev, struct net_device *outdev, | 184 | struct net_device *indev, struct net_device *outdev, |
167 | int (*okfn)(struct sk_buff *), int thresh); | 185 | int (*okfn)(struct sk_buff *), int thresh); |
@@ -179,11 +197,9 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook, | |||
179 | struct net_device *outdev, | 197 | struct net_device *outdev, |
180 | int (*okfn)(struct sk_buff *), int thresh) | 198 | int (*okfn)(struct sk_buff *), int thresh) |
181 | { | 199 | { |
182 | #ifndef CONFIG_NETFILTER_DEBUG | 200 | if (nf_hooks_active(pf, hook)) |
183 | if (list_empty(&nf_hooks[pf][hook])) | 201 | return nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh); |
184 | return 1; | 202 | return 1; |
185 | #endif | ||
186 | return nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh); | ||
187 | } | 203 | } |
188 | 204 | ||
189 | static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb, | 205 | static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb, |
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 8049bf77d799..f9261c253735 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -509,6 +509,35 @@ | |||
509 | * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup). | 509 | * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup). |
510 | * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. | 510 | * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. |
511 | * | 511 | * |
512 | * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP | ||
513 | * (or GO) interface (i.e. hostapd) to ask for unexpected frames to | ||
514 | * implement sending deauth to stations that send unexpected class 3 | ||
515 | * frames. Also used as the event sent by the kernel when such a frame | ||
516 | * is received. | ||
517 | * For the event, the %NL80211_ATTR_MAC attribute carries the TA and | ||
518 | * other attributes like the interface index are present. | ||
519 | * If used as the command it must have an interface index and you can | ||
520 | * only unsubscribe from the event by closing the socket. Subscription | ||
521 | * is also for %NL80211_CMD_UNEXPECTED_4ADDR_FRAME events. | ||
522 | * | ||
523 | * @NL80211_CMD_UNEXPECTED_4ADDR_FRAME: Sent as an event indicating that the | ||
524 | * associated station identified by %NL80211_ATTR_MAC sent a 4addr frame | ||
525 | * and wasn't already in a 4-addr VLAN. The event will be sent similarly | ||
526 | * to the %NL80211_CMD_UNEXPECTED_FRAME event, to the same listener. | ||
527 | * | ||
528 | * @NL80211_CMD_PROBE_CLIENT: Probe an associated station on an AP interface | ||
529 | * by sending a null data frame to it and reporting when the frame is | ||
530 | * acknowleged. This is used to allow timing out inactive clients. Uses | ||
531 | * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_MAC. The command returns a | ||
532 | * direct reply with an %NL80211_ATTR_COOKIE that is later used to match | ||
533 | * up the event with the request. The event includes the same data and | ||
534 | * has %NL80211_ATTR_ACK set if the frame was ACKed. | ||
535 | * | ||
536 | * @NL80211_CMD_REGISTER_BEACONS: Register this socket to receive beacons from | ||
537 | * other BSSes when any interfaces are in AP mode. This helps implement | ||
538 | * OLBC handling in hostapd. Beacons are reported in %NL80211_CMD_FRAME | ||
539 | * messages. Note that per PHY only one application may register. | ||
540 | * | ||
512 | * @NL80211_CMD_MAX: highest used command number | 541 | * @NL80211_CMD_MAX: highest used command number |
513 | * @__NL80211_CMD_AFTER_LAST: internal use | 542 | * @__NL80211_CMD_AFTER_LAST: internal use |
514 | */ | 543 | */ |
@@ -638,6 +667,14 @@ enum nl80211_commands { | |||
638 | NL80211_CMD_TDLS_OPER, | 667 | NL80211_CMD_TDLS_OPER, |
639 | NL80211_CMD_TDLS_MGMT, | 668 | NL80211_CMD_TDLS_MGMT, |
640 | 669 | ||
670 | NL80211_CMD_UNEXPECTED_FRAME, | ||
671 | |||
672 | NL80211_CMD_PROBE_CLIENT, | ||
673 | |||
674 | NL80211_CMD_REGISTER_BEACONS, | ||
675 | |||
676 | NL80211_CMD_UNEXPECTED_4ADDR_FRAME, | ||
677 | |||
641 | /* add new commands above here */ | 678 | /* add new commands above here */ |
642 | 679 | ||
643 | /* used to define NL80211_CMD_MAX below */ | 680 | /* used to define NL80211_CMD_MAX below */ |
@@ -658,6 +695,8 @@ enum nl80211_commands { | |||
658 | #define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE | 695 | #define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE |
659 | #define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT | 696 | #define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT |
660 | 697 | ||
698 | #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS | ||
699 | |||
661 | /* source-level API compatibility */ | 700 | /* source-level API compatibility */ |
662 | #define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG | 701 | #define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG |
663 | #define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG | 702 | #define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG |
@@ -1109,6 +1148,28 @@ enum nl80211_commands { | |||
1109 | * %NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be | 1148 | * %NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be |
1110 | * used for asking the driver to perform a TDLS operation. | 1149 | * used for asking the driver to perform a TDLS operation. |
1111 | * | 1150 | * |
1151 | * @NL80211_ATTR_DEVICE_AP_SME: This u32 attribute may be listed for devices | ||
1152 | * that have AP support to indicate that they have the AP SME integrated | ||
1153 | * with support for the features listed in this attribute, see | ||
1154 | * &enum nl80211_ap_sme_features. | ||
1155 | * | ||
1156 | * @NL80211_ATTR_DONT_WAIT_FOR_ACK: Used with %NL80211_CMD_FRAME, this tells | ||
1157 | * the driver to not wait for an acknowledgement. Note that due to this, | ||
1158 | * it will also not give a status callback nor return a cookie. This is | ||
1159 | * mostly useful for probe responses to save airtime. | ||
1160 | * | ||
1161 | * @NL80211_ATTR_FEATURE_FLAGS: This u32 attribute contains flags from | ||
1162 | * &enum nl80211_feature_flags and is advertised in wiphy information. | ||
1163 | * @NL80211_ATTR_PROBE_RESP_OFFLOAD: Indicates that the HW responds to probe | ||
1164 | * | ||
1165 | * requests while operating in AP-mode. | ||
1166 | * This attribute holds a bitmap of the supported protocols for | ||
1167 | * offloading (see &enum nl80211_probe_resp_offload_support_attr). | ||
1168 | * | ||
1169 | * @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire | ||
1170 | * probe-response frame. The DA field in the 802.11 header is zero-ed out, | ||
1171 | * to be filled by the FW. | ||
1172 | * | ||
1112 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1173 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1113 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1174 | * @__NL80211_ATTR_AFTER_LAST: internal use |
1114 | */ | 1175 | */ |
@@ -1337,6 +1398,16 @@ enum nl80211_attrs { | |||
1337 | NL80211_ATTR_TDLS_SUPPORT, | 1398 | NL80211_ATTR_TDLS_SUPPORT, |
1338 | NL80211_ATTR_TDLS_EXTERNAL_SETUP, | 1399 | NL80211_ATTR_TDLS_EXTERNAL_SETUP, |
1339 | 1400 | ||
1401 | NL80211_ATTR_DEVICE_AP_SME, | ||
1402 | |||
1403 | NL80211_ATTR_DONT_WAIT_FOR_ACK, | ||
1404 | |||
1405 | NL80211_ATTR_FEATURE_FLAGS, | ||
1406 | |||
1407 | NL80211_ATTR_PROBE_RESP_OFFLOAD, | ||
1408 | |||
1409 | NL80211_ATTR_PROBE_RESP, | ||
1410 | |||
1340 | /* add attributes here, update the policy in nl80211.c */ | 1411 | /* add attributes here, update the policy in nl80211.c */ |
1341 | 1412 | ||
1342 | __NL80211_ATTR_AFTER_LAST, | 1413 | __NL80211_ATTR_AFTER_LAST, |
@@ -1371,6 +1442,7 @@ enum nl80211_attrs { | |||
1371 | #define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES | 1442 | #define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES |
1372 | #define NL80211_ATTR_KEY NL80211_ATTR_KEY | 1443 | #define NL80211_ATTR_KEY NL80211_ATTR_KEY |
1373 | #define NL80211_ATTR_KEYS NL80211_ATTR_KEYS | 1444 | #define NL80211_ATTR_KEYS NL80211_ATTR_KEYS |
1445 | #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS | ||
1374 | 1446 | ||
1375 | #define NL80211_MAX_SUPP_RATES 32 | 1447 | #define NL80211_MAX_SUPP_RATES 32 |
1376 | #define NL80211_MAX_SUPP_REG_RULES 32 | 1448 | #define NL80211_MAX_SUPP_REG_RULES 32 |
@@ -2650,4 +2722,43 @@ enum nl80211_tdls_operation { | |||
2650 | NL80211_TDLS_DISABLE_LINK, | 2722 | NL80211_TDLS_DISABLE_LINK, |
2651 | }; | 2723 | }; |
2652 | 2724 | ||
2725 | /* | ||
2726 | * enum nl80211_ap_sme_features - device-integrated AP features | ||
2727 | * Reserved for future use, no bits are defined in | ||
2728 | * NL80211_ATTR_DEVICE_AP_SME yet. | ||
2729 | enum nl80211_ap_sme_features { | ||
2730 | }; | ||
2731 | */ | ||
2732 | |||
2733 | /** | ||
2734 | * enum nl80211_feature_flags - device/driver features | ||
2735 | * @NL80211_FEATURE_SK_TX_STATUS: This driver supports reflecting back | ||
2736 | * TX status to the socket error queue when requested with the | ||
2737 | * socket option. | ||
2738 | */ | ||
2739 | enum nl80211_feature_flags { | ||
2740 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, | ||
2741 | }; | ||
2742 | |||
2743 | /** | ||
2744 | * enum nl80211_probe_resp_offload_support_attr - optional supported | ||
2745 | * protocols for probe-response offloading by the driver/FW. | ||
2746 | * To be used with the %NL80211_ATTR_PROBE_RESP_OFFLOAD attribute. | ||
2747 | * Each enum value represents a bit in the bitmap of supported | ||
2748 | * protocols. Typically a subset of probe-requests belonging to a | ||
2749 | * supported protocol will be excluded from offload and uploaded | ||
2750 | * to the host. | ||
2751 | * | ||
2752 | * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS: Support for WPS ver. 1 | ||
2753 | * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2: Support for WPS ver. 2 | ||
2754 | * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P: Support for P2P | ||
2755 | * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U: Support for 802.11u | ||
2756 | */ | ||
2757 | enum nl80211_probe_resp_offload_support_attr { | ||
2758 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS = 1<<0, | ||
2759 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 = 1<<1, | ||
2760 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P = 1<<2, | ||
2761 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U = 1<<3, | ||
2762 | }; | ||
2763 | |||
2653 | #endif /* __LINUX_NL80211_H */ | 2764 | #endif /* __LINUX_NL80211_H */ |
diff --git a/include/linux/phonet.h b/include/linux/phonet.h index f53a4167c5f4..f48bfc80cb4b 100644 --- a/include/linux/phonet.h +++ b/include/linux/phonet.h | |||
@@ -38,6 +38,7 @@ | |||
38 | #define PNPIPE_ENCAP 1 | 38 | #define PNPIPE_ENCAP 1 |
39 | #define PNPIPE_IFINDEX 2 | 39 | #define PNPIPE_IFINDEX 2 |
40 | #define PNPIPE_HANDLE 3 | 40 | #define PNPIPE_HANDLE 3 |
41 | #define PNPIPE_INITSTATE 4 | ||
41 | 42 | ||
42 | #define PNADDR_ANY 0 | 43 | #define PNADDR_ANY 0 |
43 | #define PNADDR_BROADCAST 0xFC | 44 | #define PNADDR_BROADCAST 0xFC |
@@ -49,6 +50,7 @@ | |||
49 | 50 | ||
50 | /* ioctls */ | 51 | /* ioctls */ |
51 | #define SIOCPNGETOBJECT (SIOCPROTOPRIVATE + 0) | 52 | #define SIOCPNGETOBJECT (SIOCPROTOPRIVATE + 0) |
53 | #define SIOCPNENABLEPIPE (SIOCPROTOPRIVATE + 13) | ||
52 | #define SIOCPNADDRESOURCE (SIOCPROTOPRIVATE + 14) | 54 | #define SIOCPNADDRESOURCE (SIOCPROTOPRIVATE + 14) |
53 | #define SIOCPNDELRESOURCE (SIOCPROTOPRIVATE + 15) | 55 | #define SIOCPNDELRESOURCE (SIOCPROTOPRIVATE + 15) |
54 | 56 | ||
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index fe864885c1ed..cec0657d0d32 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/dmaengine.h> | 30 | #include <linux/dmaengine.h> |
31 | #include <linux/hrtimer.h> | 31 | #include <linux/hrtimer.h> |
32 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
33 | #include <linux/netdev_features.h> | ||
33 | 34 | ||
34 | /* Don't change this without changing skb_csum_unnecessary! */ | 35 | /* Don't change this without changing skb_csum_unnecessary! */ |
35 | #define CHECKSUM_NONE 0 | 36 | #define CHECKSUM_NONE 0 |
@@ -87,7 +88,6 @@ | |||
87 | * at device setup time. | 88 | * at device setup time. |
88 | * NETIF_F_HW_CSUM - it is clever device, it is able to checksum | 89 | * NETIF_F_HW_CSUM - it is clever device, it is able to checksum |
89 | * everything. | 90 | * everything. |
90 | * NETIF_F_NO_CSUM - loopback or reliable single hop media. | ||
91 | * NETIF_F_IP_CSUM - device is dumb. It is able to csum only | 91 | * NETIF_F_IP_CSUM - device is dumb. It is able to csum only |
92 | * TCP/UDP over IPv4. Sigh. Vendors like this | 92 | * TCP/UDP over IPv4. Sigh. Vendors like this |
93 | * way by an unknown reason. Though, see comment above | 93 | * way by an unknown reason. Though, see comment above |
@@ -218,6 +218,9 @@ enum { | |||
218 | 218 | ||
219 | /* device driver supports TX zero-copy buffers */ | 219 | /* device driver supports TX zero-copy buffers */ |
220 | SKBTX_DEV_ZEROCOPY = 1 << 4, | 220 | SKBTX_DEV_ZEROCOPY = 1 << 4, |
221 | |||
222 | /* generate wifi status information (where possible) */ | ||
223 | SKBTX_WIFI_STATUS = 1 << 5, | ||
221 | }; | 224 | }; |
222 | 225 | ||
223 | /* | 226 | /* |
@@ -352,6 +355,8 @@ typedef unsigned char *sk_buff_data_t; | |||
352 | * @ooo_okay: allow the mapping of a socket to a queue to be changed | 355 | * @ooo_okay: allow the mapping of a socket to a queue to be changed |
353 | * @l4_rxhash: indicate rxhash is a canonical 4-tuple hash over transport | 356 | * @l4_rxhash: indicate rxhash is a canonical 4-tuple hash over transport |
354 | * ports. | 357 | * ports. |
358 | * @wifi_acked_valid: wifi_acked was set | ||
359 | * @wifi_acked: whether frame was acked on wifi or not | ||
355 | * @dma_cookie: a cookie to one of several possible DMA operations | 360 | * @dma_cookie: a cookie to one of several possible DMA operations |
356 | * done by skb DMA functions | 361 | * done by skb DMA functions |
357 | * @secmark: security marking | 362 | * @secmark: security marking |
@@ -445,10 +450,11 @@ struct sk_buff { | |||
445 | #endif | 450 | #endif |
446 | __u8 ooo_okay:1; | 451 | __u8 ooo_okay:1; |
447 | __u8 l4_rxhash:1; | 452 | __u8 l4_rxhash:1; |
453 | __u8 wifi_acked_valid:1; | ||
454 | __u8 wifi_acked:1; | ||
455 | /* 10/12 bit hole (depending on ndisc_nodetype presence) */ | ||
448 | kmemcheck_bitfield_end(flags2); | 456 | kmemcheck_bitfield_end(flags2); |
449 | 457 | ||
450 | /* 0/13 bit hole */ | ||
451 | |||
452 | #ifdef CONFIG_NET_DMA | 458 | #ifdef CONFIG_NET_DMA |
453 | dma_cookie_t dma_cookie; | 459 | dma_cookie_t dma_cookie; |
454 | #endif | 460 | #endif |
@@ -540,6 +546,7 @@ extern void consume_skb(struct sk_buff *skb); | |||
540 | extern void __kfree_skb(struct sk_buff *skb); | 546 | extern void __kfree_skb(struct sk_buff *skb); |
541 | extern struct sk_buff *__alloc_skb(unsigned int size, | 547 | extern struct sk_buff *__alloc_skb(unsigned int size, |
542 | gfp_t priority, int fclone, int node); | 548 | gfp_t priority, int fclone, int node); |
549 | extern struct sk_buff *build_skb(void *data); | ||
543 | static inline struct sk_buff *alloc_skb(unsigned int size, | 550 | static inline struct sk_buff *alloc_skb(unsigned int size, |
544 | gfp_t priority) | 551 | gfp_t priority) |
545 | { | 552 | { |
@@ -1662,38 +1669,6 @@ static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, | |||
1662 | } | 1669 | } |
1663 | 1670 | ||
1664 | /** | 1671 | /** |
1665 | * __netdev_alloc_page - allocate a page for ps-rx on a specific device | ||
1666 | * @dev: network device to receive on | ||
1667 | * @gfp_mask: alloc_pages_node mask | ||
1668 | * | ||
1669 | * Allocate a new page. dev currently unused. | ||
1670 | * | ||
1671 | * %NULL is returned if there is no free memory. | ||
1672 | */ | ||
1673 | static inline struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask) | ||
1674 | { | ||
1675 | return alloc_pages_node(NUMA_NO_NODE, gfp_mask, 0); | ||
1676 | } | ||
1677 | |||
1678 | /** | ||
1679 | * netdev_alloc_page - allocate a page for ps-rx on a specific device | ||
1680 | * @dev: network device to receive on | ||
1681 | * | ||
1682 | * Allocate a new page. dev currently unused. | ||
1683 | * | ||
1684 | * %NULL is returned if there is no free memory. | ||
1685 | */ | ||
1686 | static inline struct page *netdev_alloc_page(struct net_device *dev) | ||
1687 | { | ||
1688 | return __netdev_alloc_page(dev, GFP_ATOMIC); | ||
1689 | } | ||
1690 | |||
1691 | static inline void netdev_free_page(struct net_device *dev, struct page *page) | ||
1692 | { | ||
1693 | __free_page(page); | ||
1694 | } | ||
1695 | |||
1696 | /** | ||
1697 | * skb_frag_page - retrieve the page refered to by a paged fragment | 1672 | * skb_frag_page - retrieve the page refered to by a paged fragment |
1698 | * @frag: the paged fragment | 1673 | * @frag: the paged fragment |
1699 | * | 1674 | * |
@@ -2105,7 +2080,8 @@ extern void skb_split(struct sk_buff *skb, | |||
2105 | extern int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, | 2080 | extern int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, |
2106 | int shiftlen); | 2081 | int shiftlen); |
2107 | 2082 | ||
2108 | extern struct sk_buff *skb_segment(struct sk_buff *skb, u32 features); | 2083 | extern struct sk_buff *skb_segment(struct sk_buff *skb, |
2084 | netdev_features_t features); | ||
2109 | 2085 | ||
2110 | static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, | 2086 | static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, |
2111 | int len, void *buffer) | 2087 | int len, void *buffer) |
@@ -2263,6 +2239,15 @@ static inline void skb_tx_timestamp(struct sk_buff *skb) | |||
2263 | sw_tx_timestamp(skb); | 2239 | sw_tx_timestamp(skb); |
2264 | } | 2240 | } |
2265 | 2241 | ||
2242 | /** | ||
2243 | * skb_complete_wifi_ack - deliver skb with wifi status | ||
2244 | * | ||
2245 | * @skb: the original outgoing packet | ||
2246 | * @acked: ack status | ||
2247 | * | ||
2248 | */ | ||
2249 | void skb_complete_wifi_ack(struct sk_buff *skb, bool acked); | ||
2250 | |||
2266 | extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len); | 2251 | extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len); |
2267 | extern __sum16 __skb_checksum_complete(struct sk_buff *skb); | 2252 | extern __sum16 __skb_checksum_complete(struct sk_buff *skb); |
2268 | 2253 | ||
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 3d8f9c44e27d..f15fd985b08a 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h | |||
@@ -237,7 +237,7 @@ static inline bool __rpc_copy_addr6(struct sockaddr *dst, | |||
237 | struct sockaddr_in6 *dsin6 = (struct sockaddr_in6 *) dst; | 237 | struct sockaddr_in6 *dsin6 = (struct sockaddr_in6 *) dst; |
238 | 238 | ||
239 | dsin6->sin6_family = ssin6->sin6_family; | 239 | dsin6->sin6_family = ssin6->sin6_family; |
240 | ipv6_addr_copy(&dsin6->sin6_addr, &ssin6->sin6_addr); | 240 | dsin6->sin6_addr = ssin6->sin6_addr; |
241 | return true; | 241 | return true; |
242 | } | 242 | } |
243 | #else /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ | 243 | #else /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ |
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index add4790b21fe..63f98d0a8efa 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h | |||
@@ -100,6 +100,10 @@ | |||
100 | * vdev: the virtio_device | 100 | * vdev: the virtio_device |
101 | * This gives the final feature bits for the device: it can change | 101 | * This gives the final feature bits for the device: it can change |
102 | * the dev->feature bits if it wants. | 102 | * the dev->feature bits if it wants. |
103 | * @bus_name: return the bus name associated with the device | ||
104 | * vdev: the virtio_device | ||
105 | * This returns a pointer to the bus name a la pci_name from which | ||
106 | * the caller can then copy. | ||
103 | */ | 107 | */ |
104 | typedef void vq_callback_t(struct virtqueue *); | 108 | typedef void vq_callback_t(struct virtqueue *); |
105 | struct virtio_config_ops { | 109 | struct virtio_config_ops { |
@@ -117,6 +121,7 @@ struct virtio_config_ops { | |||
117 | void (*del_vqs)(struct virtio_device *); | 121 | void (*del_vqs)(struct virtio_device *); |
118 | u32 (*get_features)(struct virtio_device *vdev); | 122 | u32 (*get_features)(struct virtio_device *vdev); |
119 | void (*finalize_features)(struct virtio_device *vdev); | 123 | void (*finalize_features)(struct virtio_device *vdev); |
124 | const char *(*bus_name)(struct virtio_device *vdev); | ||
120 | }; | 125 | }; |
121 | 126 | ||
122 | /* If driver didn't advertise the feature, it will never appear. */ | 127 | /* If driver didn't advertise the feature, it will never appear. */ |
@@ -182,5 +187,14 @@ struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev, | |||
182 | return ERR_PTR(err); | 187 | return ERR_PTR(err); |
183 | return vq; | 188 | return vq; |
184 | } | 189 | } |
190 | |||
191 | static inline | ||
192 | const char *virtio_bus_name(struct virtio_device *vdev) | ||
193 | { | ||
194 | if (!vdev->config->bus_name) | ||
195 | return "virtio"; | ||
196 | return vdev->config->bus_name(vdev); | ||
197 | } | ||
198 | |||
185 | #endif /* __KERNEL__ */ | 199 | #endif /* __KERNEL__ */ |
186 | #endif /* _LINUX_VIRTIO_CONFIG_H */ | 200 | #endif /* _LINUX_VIRTIO_CONFIG_H */ |
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index e86af08293a8..835f3b229b84 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -77,6 +77,33 @@ struct bt_power { | |||
77 | #define BT_POWER_FORCE_ACTIVE_OFF 0 | 77 | #define BT_POWER_FORCE_ACTIVE_OFF 0 |
78 | #define BT_POWER_FORCE_ACTIVE_ON 1 | 78 | #define BT_POWER_FORCE_ACTIVE_ON 1 |
79 | 79 | ||
80 | #define BT_CHANNEL_POLICY 10 | ||
81 | |||
82 | /* BR/EDR only (default policy) | ||
83 | * AMP controllers cannot be used. | ||
84 | * Channel move requests from the remote device are denied. | ||
85 | * If the L2CAP channel is currently using AMP, move the channel to BR/EDR. | ||
86 | */ | ||
87 | #define BT_CHANNEL_POLICY_BREDR_ONLY 0 | ||
88 | |||
89 | /* BR/EDR Preferred | ||
90 | * Allow use of AMP controllers. | ||
91 | * If the L2CAP channel is currently on AMP, move it to BR/EDR. | ||
92 | * Channel move requests from the remote device are allowed. | ||
93 | */ | ||
94 | #define BT_CHANNEL_POLICY_BREDR_PREFERRED 1 | ||
95 | |||
96 | /* AMP Preferred | ||
97 | * Allow use of AMP controllers | ||
98 | * If the L2CAP channel is currently on BR/EDR and AMP controller | ||
99 | * resources are available, initiate a channel move to AMP. | ||
100 | * Channel move requests from the remote device are allowed. | ||
101 | * If the L2CAP socket has not been connected yet, try to create | ||
102 | * and configure the channel directly on an AMP controller rather | ||
103 | * than BR/EDR. | ||
104 | */ | ||
105 | #define BT_CHANNEL_POLICY_AMP_PREFERRED 2 | ||
106 | |||
80 | __printf(2, 3) | 107 | __printf(2, 3) |
81 | int bt_printk(const char *level, const char *fmt, ...); | 108 | int bt_printk(const char *level, const char *fmt, ...); |
82 | 109 | ||
@@ -158,7 +185,7 @@ struct bt_skb_cb { | |||
158 | __u8 pkt_type; | 185 | __u8 pkt_type; |
159 | __u8 incoming; | 186 | __u8 incoming; |
160 | __u16 expect; | 187 | __u16 expect; |
161 | __u8 tx_seq; | 188 | __u16 tx_seq; |
162 | __u8 retries; | 189 | __u8 retries; |
163 | __u8 sar; | 190 | __u8 sar; |
164 | unsigned short channel; | 191 | unsigned short channel; |
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index aaf79af72432..139ce2aa6eee 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -264,6 +264,13 @@ enum { | |||
264 | #define HCI_LK_SMP_IRK 0x82 | 264 | #define HCI_LK_SMP_IRK 0x82 |
265 | #define HCI_LK_SMP_CSRK 0x83 | 265 | #define HCI_LK_SMP_CSRK 0x83 |
266 | 266 | ||
267 | /* ---- HCI Error Codes ---- */ | ||
268 | #define HCI_ERROR_AUTH_FAILURE 0x05 | ||
269 | #define HCI_ERROR_REJ_BAD_ADDR 0x0f | ||
270 | #define HCI_ERROR_REMOTE_USER_TERM 0x13 | ||
271 | #define HCI_ERROR_LOCAL_HOST_TERM 0x16 | ||
272 | #define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18 | ||
273 | |||
267 | /* ----- HCI Commands ---- */ | 274 | /* ----- HCI Commands ---- */ |
268 | #define HCI_OP_NOP 0x0000 | 275 | #define HCI_OP_NOP 0x0000 |
269 | 276 | ||
@@ -726,6 +733,21 @@ struct hci_cp_write_page_scan_activity { | |||
726 | #define PAGE_SCAN_TYPE_STANDARD 0x00 | 733 | #define PAGE_SCAN_TYPE_STANDARD 0x00 |
727 | #define PAGE_SCAN_TYPE_INTERLACED 0x01 | 734 | #define PAGE_SCAN_TYPE_INTERLACED 0x01 |
728 | 735 | ||
736 | #define HCI_OP_READ_LOCAL_AMP_INFO 0x1409 | ||
737 | struct hci_rp_read_local_amp_info { | ||
738 | __u8 status; | ||
739 | __u8 amp_status; | ||
740 | __le32 total_bw; | ||
741 | __le32 max_bw; | ||
742 | __le32 min_latency; | ||
743 | __le32 max_pdu; | ||
744 | __u8 amp_type; | ||
745 | __le16 pal_cap; | ||
746 | __le16 max_assoc_size; | ||
747 | __le32 max_flush_to; | ||
748 | __le32 be_flush_to; | ||
749 | } __packed; | ||
750 | |||
729 | #define HCI_OP_LE_SET_EVENT_MASK 0x2001 | 751 | #define HCI_OP_LE_SET_EVENT_MASK 0x2001 |
730 | struct hci_cp_le_set_event_mask { | 752 | struct hci_cp_le_set_event_mask { |
731 | __u8 mask[8]; | 753 | __u8 mask[8]; |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 3779ea362257..f333e7682607 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -32,6 +32,9 @@ | |||
32 | #define HCI_PROTO_L2CAP 0 | 32 | #define HCI_PROTO_L2CAP 0 |
33 | #define HCI_PROTO_SCO 1 | 33 | #define HCI_PROTO_SCO 1 |
34 | 34 | ||
35 | /* HCI priority */ | ||
36 | #define HCI_PRIO_MAX 7 | ||
37 | |||
35 | /* HCI Core structures */ | 38 | /* HCI Core structures */ |
36 | struct inquiry_data { | 39 | struct inquiry_data { |
37 | bdaddr_t bdaddr; | 40 | bdaddr_t bdaddr; |
@@ -64,6 +67,12 @@ struct hci_conn_hash { | |||
64 | unsigned int le_num; | 67 | unsigned int le_num; |
65 | }; | 68 | }; |
66 | 69 | ||
70 | struct hci_chan_hash { | ||
71 | struct list_head list; | ||
72 | spinlock_t lock; | ||
73 | unsigned int num; | ||
74 | }; | ||
75 | |||
67 | struct bdaddr_list { | 76 | struct bdaddr_list { |
68 | struct list_head list; | 77 | struct list_head list; |
69 | bdaddr_t bdaddr; | 78 | bdaddr_t bdaddr; |
@@ -150,6 +159,17 @@ struct hci_dev { | |||
150 | __u16 sniff_min_interval; | 159 | __u16 sniff_min_interval; |
151 | __u16 sniff_max_interval; | 160 | __u16 sniff_max_interval; |
152 | 161 | ||
162 | __u8 amp_status; | ||
163 | __u32 amp_total_bw; | ||
164 | __u32 amp_max_bw; | ||
165 | __u32 amp_min_latency; | ||
166 | __u32 amp_max_pdu; | ||
167 | __u8 amp_type; | ||
168 | __u16 amp_pal_cap; | ||
169 | __u16 amp_assoc_size; | ||
170 | __u32 amp_max_flush_to; | ||
171 | __u32 amp_be_flush_to; | ||
172 | |||
153 | unsigned int auto_accept_delay; | 173 | unsigned int auto_accept_delay; |
154 | 174 | ||
155 | unsigned long quirks; | 175 | unsigned long quirks; |
@@ -173,8 +193,10 @@ struct hci_dev { | |||
173 | struct workqueue_struct *workqueue; | 193 | struct workqueue_struct *workqueue; |
174 | 194 | ||
175 | struct work_struct power_on; | 195 | struct work_struct power_on; |
176 | struct work_struct power_off; | 196 | struct delayed_work power_off; |
177 | struct timer_list off_timer; | 197 | |
198 | __u16 discov_timeout; | ||
199 | struct delayed_work discov_off; | ||
178 | 200 | ||
179 | struct timer_list cmd_timer; | 201 | struct timer_list cmd_timer; |
180 | struct tasklet_struct cmd_task; | 202 | struct tasklet_struct cmd_task; |
@@ -195,6 +217,8 @@ struct hci_dev { | |||
195 | 217 | ||
196 | __u16 init_last_cmd; | 218 | __u16 init_last_cmd; |
197 | 219 | ||
220 | struct list_head mgmt_pending; | ||
221 | |||
198 | struct inquiry_cache inq_cache; | 222 | struct inquiry_cache inq_cache; |
199 | struct hci_conn_hash conn_hash; | 223 | struct hci_conn_hash conn_hash; |
200 | struct list_head blacklist; | 224 | struct list_head blacklist; |
@@ -273,6 +297,7 @@ struct hci_conn { | |||
273 | unsigned int sent; | 297 | unsigned int sent; |
274 | 298 | ||
275 | struct sk_buff_head data_q; | 299 | struct sk_buff_head data_q; |
300 | struct hci_chan_hash chan_hash; | ||
276 | 301 | ||
277 | struct timer_list disc_timer; | 302 | struct timer_list disc_timer; |
278 | struct timer_list idle_timer; | 303 | struct timer_list idle_timer; |
@@ -295,6 +320,14 @@ struct hci_conn { | |||
295 | void (*disconn_cfm_cb) (struct hci_conn *conn, u8 reason); | 320 | void (*disconn_cfm_cb) (struct hci_conn *conn, u8 reason); |
296 | }; | 321 | }; |
297 | 322 | ||
323 | struct hci_chan { | ||
324 | struct list_head list; | ||
325 | |||
326 | struct hci_conn *conn; | ||
327 | struct sk_buff_head data_q; | ||
328 | unsigned int sent; | ||
329 | }; | ||
330 | |||
298 | extern struct hci_proto *hci_proto[]; | 331 | extern struct hci_proto *hci_proto[]; |
299 | extern struct list_head hci_dev_list; | 332 | extern struct list_head hci_dev_list; |
300 | extern struct list_head hci_cb_list; | 333 | extern struct list_head hci_cb_list; |
@@ -455,6 +488,28 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, | |||
455 | return NULL; | 488 | return NULL; |
456 | } | 489 | } |
457 | 490 | ||
491 | static inline void hci_chan_hash_init(struct hci_conn *c) | ||
492 | { | ||
493 | struct hci_chan_hash *h = &c->chan_hash; | ||
494 | INIT_LIST_HEAD(&h->list); | ||
495 | spin_lock_init(&h->lock); | ||
496 | h->num = 0; | ||
497 | } | ||
498 | |||
499 | static inline void hci_chan_hash_add(struct hci_conn *c, struct hci_chan *chan) | ||
500 | { | ||
501 | struct hci_chan_hash *h = &c->chan_hash; | ||
502 | list_add(&chan->list, &h->list); | ||
503 | h->num++; | ||
504 | } | ||
505 | |||
506 | static inline void hci_chan_hash_del(struct hci_conn *c, struct hci_chan *chan) | ||
507 | { | ||
508 | struct hci_chan_hash *h = &c->chan_hash; | ||
509 | list_del(&chan->list); | ||
510 | h->num--; | ||
511 | } | ||
512 | |||
458 | void hci_acl_connect(struct hci_conn *conn); | 513 | void hci_acl_connect(struct hci_conn *conn); |
459 | void hci_acl_disconn(struct hci_conn *conn, __u8 reason); | 514 | void hci_acl_disconn(struct hci_conn *conn, __u8 reason); |
460 | void hci_add_sco(struct hci_conn *conn, __u16 handle); | 515 | void hci_add_sco(struct hci_conn *conn, __u16 handle); |
@@ -466,6 +521,10 @@ int hci_conn_del(struct hci_conn *conn); | |||
466 | void hci_conn_hash_flush(struct hci_dev *hdev); | 521 | void hci_conn_hash_flush(struct hci_dev *hdev); |
467 | void hci_conn_check_pending(struct hci_dev *hdev); | 522 | void hci_conn_check_pending(struct hci_dev *hdev); |
468 | 523 | ||
524 | struct hci_chan *hci_chan_create(struct hci_conn *conn); | ||
525 | int hci_chan_del(struct hci_chan *chan); | ||
526 | void hci_chan_hash_flush(struct hci_conn *conn); | ||
527 | |||
469 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, | 528 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, |
470 | __u8 sec_level, __u8 auth_type); | 529 | __u8 sec_level, __u8 auth_type); |
471 | int hci_conn_check_link_mode(struct hci_conn *conn); | 530 | int hci_conn_check_link_mode(struct hci_conn *conn); |
@@ -545,7 +604,7 @@ struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst); | |||
545 | struct hci_dev *hci_alloc_dev(void); | 604 | struct hci_dev *hci_alloc_dev(void); |
546 | void hci_free_dev(struct hci_dev *hdev); | 605 | void hci_free_dev(struct hci_dev *hdev); |
547 | int hci_register_dev(struct hci_dev *hdev); | 606 | int hci_register_dev(struct hci_dev *hdev); |
548 | int hci_unregister_dev(struct hci_dev *hdev); | 607 | void hci_unregister_dev(struct hci_dev *hdev); |
549 | int hci_suspend_dev(struct hci_dev *hdev); | 608 | int hci_suspend_dev(struct hci_dev *hdev); |
550 | int hci_resume_dev(struct hci_dev *hdev); | 609 | int hci_resume_dev(struct hci_dev *hdev); |
551 | int hci_dev_open(__u16 dev); | 610 | int hci_dev_open(__u16 dev); |
@@ -599,8 +658,9 @@ int hci_recv_frame(struct sk_buff *skb); | |||
599 | int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); | 658 | int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); |
600 | int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count); | 659 | int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count); |
601 | 660 | ||
602 | int hci_register_sysfs(struct hci_dev *hdev); | 661 | void hci_init_sysfs(struct hci_dev *hdev); |
603 | void hci_unregister_sysfs(struct hci_dev *hdev); | 662 | int hci_add_sysfs(struct hci_dev *hdev); |
663 | void hci_del_sysfs(struct hci_dev *hdev); | ||
604 | void hci_conn_init_sysfs(struct hci_conn *conn); | 664 | void hci_conn_init_sysfs(struct hci_conn *conn); |
605 | void hci_conn_add_sysfs(struct hci_conn *conn); | 665 | void hci_conn_add_sysfs(struct hci_conn *conn); |
606 | void hci_conn_del_sysfs(struct hci_conn *conn); | 666 | void hci_conn_del_sysfs(struct hci_conn *conn); |
@@ -676,7 +736,7 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) | |||
676 | static inline int hci_proto_disconn_ind(struct hci_conn *conn) | 736 | static inline int hci_proto_disconn_ind(struct hci_conn *conn) |
677 | { | 737 | { |
678 | register struct hci_proto *hp; | 738 | register struct hci_proto *hp; |
679 | int reason = 0x13; | 739 | int reason = HCI_ERROR_REMOTE_USER_TERM; |
680 | 740 | ||
681 | hp = hci_proto[HCI_PROTO_L2CAP]; | 741 | hp = hci_proto[HCI_PROTO_L2CAP]; |
682 | if (hp && hp->disconn_ind) | 742 | if (hp && hp->disconn_ind) |
@@ -836,7 +896,7 @@ int hci_register_notifier(struct notifier_block *nb); | |||
836 | int hci_unregister_notifier(struct notifier_block *nb); | 896 | int hci_unregister_notifier(struct notifier_block *nb); |
837 | 897 | ||
838 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); | 898 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); |
839 | void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags); | 899 | void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); |
840 | void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); | 900 | void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); |
841 | 901 | ||
842 | void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); | 902 | void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); |
@@ -849,34 +909,41 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb, | |||
849 | 909 | ||
850 | /* Management interface */ | 910 | /* Management interface */ |
851 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); | 911 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); |
852 | int mgmt_index_added(u16 index); | 912 | int mgmt_index_added(struct hci_dev *hdev); |
853 | int mgmt_index_removed(u16 index); | 913 | int mgmt_index_removed(struct hci_dev *hdev); |
854 | int mgmt_powered(u16 index, u8 powered); | 914 | int mgmt_powered(struct hci_dev *hdev, u8 powered); |
855 | int mgmt_discoverable(u16 index, u8 discoverable); | 915 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); |
856 | int mgmt_connectable(u16 index, u8 connectable); | 916 | int mgmt_connectable(struct hci_dev *hdev, u8 connectable); |
857 | int mgmt_new_key(u16 index, struct link_key *key, u8 persistent); | 917 | int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status); |
858 | int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type); | 918 | int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, |
859 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr); | 919 | u8 persistent); |
860 | int mgmt_disconnect_failed(u16 index); | 920 | int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); |
861 | int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status); | 921 | int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); |
862 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure); | 922 | int mgmt_disconnect_failed(struct hci_dev *hdev); |
863 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | 923 | int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, |
864 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | ||
865 | int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value, | ||
866 | u8 confirm_hint); | ||
867 | int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | ||
868 | int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, | ||
869 | u8 status); | 924 | u8 status); |
870 | int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status); | 925 | int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure); |
871 | int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status); | 926 | int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
872 | int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, | ||
873 | u8 status); | 927 | u8 status); |
874 | int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, | 928 | int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
875 | u8 *eir); | 929 | u8 status); |
876 | int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name); | 930 | int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, |
877 | int mgmt_discovering(u16 index, u8 discovering); | 931 | __le32 value, u8 confirm_hint); |
878 | int mgmt_device_blocked(u16 index, bdaddr_t *bdaddr); | 932 | int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
879 | int mgmt_device_unblocked(u16 index, bdaddr_t *bdaddr); | 933 | u8 status); |
934 | int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, | ||
935 | bdaddr_t *bdaddr, u8 status); | ||
936 | int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status); | ||
937 | int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); | ||
938 | int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, | ||
939 | u8 *randomizer, u8 status); | ||
940 | int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, | ||
941 | u8 *dev_class, s8 rssi, u8 *eir); | ||
942 | int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name); | ||
943 | int mgmt_inquiry_failed(struct hci_dev *hdev, u8 status); | ||
944 | int mgmt_discovering(struct hci_dev *hdev, u8 discovering); | ||
945 | int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr); | ||
946 | int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr); | ||
880 | 947 | ||
881 | /* HCI info for socket */ | 948 | /* HCI info for socket */ |
882 | #define hci_pi(sk) ((struct hci_pinfo *) sk) | 949 | #define hci_pi(sk) ((struct hci_pinfo *) sk) |
@@ -915,4 +982,7 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], | |||
915 | void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]); | 982 | void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]); |
916 | void hci_le_ltk_neg_reply(struct hci_conn *conn); | 983 | void hci_le_ltk_neg_reply(struct hci_conn *conn); |
917 | 984 | ||
985 | int hci_do_inquiry(struct hci_dev *hdev, u8 length); | ||
986 | int hci_cancel_inquiry(struct hci_dev *hdev); | ||
987 | |||
918 | #endif /* __HCI_CORE_H */ | 988 | #endif /* __HCI_CORE_H */ |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 6cc18f371675..875021ad0675 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -27,17 +27,23 @@ | |||
27 | #ifndef __L2CAP_H | 27 | #ifndef __L2CAP_H |
28 | #define __L2CAP_H | 28 | #define __L2CAP_H |
29 | 29 | ||
30 | #include <asm/unaligned.h> | ||
31 | |||
30 | /* L2CAP defaults */ | 32 | /* L2CAP defaults */ |
31 | #define L2CAP_DEFAULT_MTU 672 | 33 | #define L2CAP_DEFAULT_MTU 672 |
32 | #define L2CAP_DEFAULT_MIN_MTU 48 | 34 | #define L2CAP_DEFAULT_MIN_MTU 48 |
33 | #define L2CAP_DEFAULT_FLUSH_TO 0xffff | 35 | #define L2CAP_DEFAULT_FLUSH_TO 0xffff |
34 | #define L2CAP_DEFAULT_TX_WINDOW 63 | 36 | #define L2CAP_DEFAULT_TX_WINDOW 63 |
37 | #define L2CAP_DEFAULT_EXT_WINDOW 0x3FFF | ||
35 | #define L2CAP_DEFAULT_MAX_TX 3 | 38 | #define L2CAP_DEFAULT_MAX_TX 3 |
36 | #define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */ | 39 | #define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */ |
37 | #define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */ | 40 | #define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */ |
38 | #define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */ | 41 | #define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */ |
39 | #define L2CAP_DEFAULT_ACK_TO 200 | 42 | #define L2CAP_DEFAULT_ACK_TO 200 |
40 | #define L2CAP_LE_DEFAULT_MTU 23 | 43 | #define L2CAP_LE_DEFAULT_MTU 23 |
44 | #define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF | ||
45 | #define L2CAP_DEFAULT_SDU_ITIME 0xFFFFFFFF | ||
46 | #define L2CAP_DEFAULT_ACC_LAT 0xFFFFFFFF | ||
41 | 47 | ||
42 | #define L2CAP_DISC_TIMEOUT (100) | 48 | #define L2CAP_DISC_TIMEOUT (100) |
43 | #define L2CAP_DISC_REJ_TIMEOUT (5000) /* 5 seconds */ | 49 | #define L2CAP_DISC_REJ_TIMEOUT (5000) /* 5 seconds */ |
@@ -91,52 +97,82 @@ struct l2cap_conninfo { | |||
91 | #define L2CAP_ECHO_RSP 0x09 | 97 | #define L2CAP_ECHO_RSP 0x09 |
92 | #define L2CAP_INFO_REQ 0x0a | 98 | #define L2CAP_INFO_REQ 0x0a |
93 | #define L2CAP_INFO_RSP 0x0b | 99 | #define L2CAP_INFO_RSP 0x0b |
100 | #define L2CAP_CREATE_CHAN_REQ 0x0c | ||
101 | #define L2CAP_CREATE_CHAN_RSP 0x0d | ||
102 | #define L2CAP_MOVE_CHAN_REQ 0x0e | ||
103 | #define L2CAP_MOVE_CHAN_RSP 0x0f | ||
104 | #define L2CAP_MOVE_CHAN_CFM 0x10 | ||
105 | #define L2CAP_MOVE_CHAN_CFM_RSP 0x11 | ||
94 | #define L2CAP_CONN_PARAM_UPDATE_REQ 0x12 | 106 | #define L2CAP_CONN_PARAM_UPDATE_REQ 0x12 |
95 | #define L2CAP_CONN_PARAM_UPDATE_RSP 0x13 | 107 | #define L2CAP_CONN_PARAM_UPDATE_RSP 0x13 |
96 | 108 | ||
97 | /* L2CAP feature mask */ | 109 | /* L2CAP extended feature mask */ |
98 | #define L2CAP_FEAT_FLOWCTL 0x00000001 | 110 | #define L2CAP_FEAT_FLOWCTL 0x00000001 |
99 | #define L2CAP_FEAT_RETRANS 0x00000002 | 111 | #define L2CAP_FEAT_RETRANS 0x00000002 |
112 | #define L2CAP_FEAT_BIDIR_QOS 0x00000004 | ||
100 | #define L2CAP_FEAT_ERTM 0x00000008 | 113 | #define L2CAP_FEAT_ERTM 0x00000008 |
101 | #define L2CAP_FEAT_STREAMING 0x00000010 | 114 | #define L2CAP_FEAT_STREAMING 0x00000010 |
102 | #define L2CAP_FEAT_FCS 0x00000020 | 115 | #define L2CAP_FEAT_FCS 0x00000020 |
116 | #define L2CAP_FEAT_EXT_FLOW 0x00000040 | ||
103 | #define L2CAP_FEAT_FIXED_CHAN 0x00000080 | 117 | #define L2CAP_FEAT_FIXED_CHAN 0x00000080 |
118 | #define L2CAP_FEAT_EXT_WINDOW 0x00000100 | ||
119 | #define L2CAP_FEAT_UCD 0x00000200 | ||
104 | 120 | ||
105 | /* L2CAP checksum option */ | 121 | /* L2CAP checksum option */ |
106 | #define L2CAP_FCS_NONE 0x00 | 122 | #define L2CAP_FCS_NONE 0x00 |
107 | #define L2CAP_FCS_CRC16 0x01 | 123 | #define L2CAP_FCS_CRC16 0x01 |
108 | 124 | ||
125 | /* L2CAP fixed channels */ | ||
126 | #define L2CAP_FC_L2CAP 0x02 | ||
127 | #define L2CAP_FC_A2MP 0x08 | ||
128 | |||
109 | /* L2CAP Control Field bit masks */ | 129 | /* L2CAP Control Field bit masks */ |
110 | #define L2CAP_CTRL_SAR 0xC000 | 130 | #define L2CAP_CTRL_SAR 0xC000 |
111 | #define L2CAP_CTRL_REQSEQ 0x3F00 | 131 | #define L2CAP_CTRL_REQSEQ 0x3F00 |
112 | #define L2CAP_CTRL_TXSEQ 0x007E | 132 | #define L2CAP_CTRL_TXSEQ 0x007E |
113 | #define L2CAP_CTRL_RETRANS 0x0080 | 133 | #define L2CAP_CTRL_SUPERVISE 0x000C |
114 | #define L2CAP_CTRL_FINAL 0x0080 | 134 | |
115 | #define L2CAP_CTRL_POLL 0x0010 | 135 | #define L2CAP_CTRL_RETRANS 0x0080 |
116 | #define L2CAP_CTRL_SUPERVISE 0x000C | 136 | #define L2CAP_CTRL_FINAL 0x0080 |
117 | #define L2CAP_CTRL_FRAME_TYPE 0x0001 /* I- or S-Frame */ | 137 | #define L2CAP_CTRL_POLL 0x0010 |
118 | 138 | #define L2CAP_CTRL_FRAME_TYPE 0x0001 /* I- or S-Frame */ | |
119 | #define L2CAP_CTRL_TXSEQ_SHIFT 1 | 139 | |
120 | #define L2CAP_CTRL_REQSEQ_SHIFT 8 | 140 | #define L2CAP_CTRL_TXSEQ_SHIFT 1 |
121 | #define L2CAP_CTRL_SAR_SHIFT 14 | 141 | #define L2CAP_CTRL_SUPER_SHIFT 2 |
142 | #define L2CAP_CTRL_REQSEQ_SHIFT 8 | ||
143 | #define L2CAP_CTRL_SAR_SHIFT 14 | ||
144 | |||
145 | /* L2CAP Extended Control Field bit mask */ | ||
146 | #define L2CAP_EXT_CTRL_TXSEQ 0xFFFC0000 | ||
147 | #define L2CAP_EXT_CTRL_SAR 0x00030000 | ||
148 | #define L2CAP_EXT_CTRL_SUPERVISE 0x00030000 | ||
149 | #define L2CAP_EXT_CTRL_REQSEQ 0x0000FFFC | ||
150 | |||
151 | #define L2CAP_EXT_CTRL_POLL 0x00040000 | ||
152 | #define L2CAP_EXT_CTRL_FINAL 0x00000002 | ||
153 | #define L2CAP_EXT_CTRL_FRAME_TYPE 0x00000001 /* I- or S-Frame */ | ||
154 | |||
155 | #define L2CAP_EXT_CTRL_REQSEQ_SHIFT 2 | ||
156 | #define L2CAP_EXT_CTRL_SAR_SHIFT 16 | ||
157 | #define L2CAP_EXT_CTRL_SUPER_SHIFT 16 | ||
158 | #define L2CAP_EXT_CTRL_TXSEQ_SHIFT 18 | ||
122 | 159 | ||
123 | /* L2CAP Supervisory Function */ | 160 | /* L2CAP Supervisory Function */ |
124 | #define L2CAP_SUPER_RCV_READY 0x0000 | 161 | #define L2CAP_SUPER_RR 0x00 |
125 | #define L2CAP_SUPER_REJECT 0x0004 | 162 | #define L2CAP_SUPER_REJ 0x01 |
126 | #define L2CAP_SUPER_RCV_NOT_READY 0x0008 | 163 | #define L2CAP_SUPER_RNR 0x02 |
127 | #define L2CAP_SUPER_SELECT_REJECT 0x000C | 164 | #define L2CAP_SUPER_SREJ 0x03 |
128 | 165 | ||
129 | /* L2CAP Segmentation and Reassembly */ | 166 | /* L2CAP Segmentation and Reassembly */ |
130 | #define L2CAP_SDU_UNSEGMENTED 0x0000 | 167 | #define L2CAP_SAR_UNSEGMENTED 0x00 |
131 | #define L2CAP_SDU_START 0x4000 | 168 | #define L2CAP_SAR_START 0x01 |
132 | #define L2CAP_SDU_END 0x8000 | 169 | #define L2CAP_SAR_END 0x02 |
133 | #define L2CAP_SDU_CONTINUE 0xC000 | 170 | #define L2CAP_SAR_CONTINUE 0x03 |
134 | 171 | ||
135 | /* L2CAP Command rej. reasons */ | 172 | /* L2CAP Command rej. reasons */ |
136 | #define L2CAP_REJ_NOT_UNDERSTOOD 0x0000 | 173 | #define L2CAP_REJ_NOT_UNDERSTOOD 0x0000 |
137 | #define L2CAP_REJ_MTU_EXCEEDED 0x0001 | 174 | #define L2CAP_REJ_MTU_EXCEEDED 0x0001 |
138 | #define L2CAP_REJ_INVALID_CID 0x0002 | 175 | #define L2CAP_REJ_INVALID_CID 0x0002 |
139 | |||
140 | 176 | ||
141 | /* L2CAP structures */ | 177 | /* L2CAP structures */ |
142 | struct l2cap_hdr { | 178 | struct l2cap_hdr { |
@@ -144,6 +180,12 @@ struct l2cap_hdr { | |||
144 | __le16 cid; | 180 | __le16 cid; |
145 | } __packed; | 181 | } __packed; |
146 | #define L2CAP_HDR_SIZE 4 | 182 | #define L2CAP_HDR_SIZE 4 |
183 | #define L2CAP_ENH_HDR_SIZE 6 | ||
184 | #define L2CAP_EXT_HDR_SIZE 8 | ||
185 | |||
186 | #define L2CAP_FCS_SIZE 2 | ||
187 | #define L2CAP_SDULEN_SIZE 2 | ||
188 | #define L2CAP_PSMLEN_SIZE 2 | ||
147 | 189 | ||
148 | struct l2cap_cmd_hdr { | 190 | struct l2cap_cmd_hdr { |
149 | __u8 code; | 191 | __u8 code; |
@@ -188,14 +230,15 @@ struct l2cap_conn_rsp { | |||
188 | #define L2CAP_CID_DYN_START 0x0040 | 230 | #define L2CAP_CID_DYN_START 0x0040 |
189 | #define L2CAP_CID_DYN_END 0xffff | 231 | #define L2CAP_CID_DYN_END 0xffff |
190 | 232 | ||
191 | /* connect result */ | 233 | /* connect/create channel results */ |
192 | #define L2CAP_CR_SUCCESS 0x0000 | 234 | #define L2CAP_CR_SUCCESS 0x0000 |
193 | #define L2CAP_CR_PEND 0x0001 | 235 | #define L2CAP_CR_PEND 0x0001 |
194 | #define L2CAP_CR_BAD_PSM 0x0002 | 236 | #define L2CAP_CR_BAD_PSM 0x0002 |
195 | #define L2CAP_CR_SEC_BLOCK 0x0003 | 237 | #define L2CAP_CR_SEC_BLOCK 0x0003 |
196 | #define L2CAP_CR_NO_MEM 0x0004 | 238 | #define L2CAP_CR_NO_MEM 0x0004 |
239 | #define L2CAP_CR_BAD_AMP 0x0005 | ||
197 | 240 | ||
198 | /* connect status */ | 241 | /* connect/create channel status */ |
199 | #define L2CAP_CS_NO_INFO 0x0000 | 242 | #define L2CAP_CS_NO_INFO 0x0000 |
200 | #define L2CAP_CS_AUTHEN_PEND 0x0001 | 243 | #define L2CAP_CS_AUTHEN_PEND 0x0001 |
201 | #define L2CAP_CS_AUTHOR_PEND 0x0002 | 244 | #define L2CAP_CS_AUTHOR_PEND 0x0002 |
@@ -217,6 +260,8 @@ struct l2cap_conf_rsp { | |||
217 | #define L2CAP_CONF_UNACCEPT 0x0001 | 260 | #define L2CAP_CONF_UNACCEPT 0x0001 |
218 | #define L2CAP_CONF_REJECT 0x0002 | 261 | #define L2CAP_CONF_REJECT 0x0002 |
219 | #define L2CAP_CONF_UNKNOWN 0x0003 | 262 | #define L2CAP_CONF_UNKNOWN 0x0003 |
263 | #define L2CAP_CONF_PENDING 0x0004 | ||
264 | #define L2CAP_CONF_EFS_REJECT 0x0005 | ||
220 | 265 | ||
221 | struct l2cap_conf_opt { | 266 | struct l2cap_conf_opt { |
222 | __u8 type; | 267 | __u8 type; |
@@ -233,6 +278,8 @@ struct l2cap_conf_opt { | |||
233 | #define L2CAP_CONF_QOS 0x03 | 278 | #define L2CAP_CONF_QOS 0x03 |
234 | #define L2CAP_CONF_RFC 0x04 | 279 | #define L2CAP_CONF_RFC 0x04 |
235 | #define L2CAP_CONF_FCS 0x05 | 280 | #define L2CAP_CONF_FCS 0x05 |
281 | #define L2CAP_CONF_EFS 0x06 | ||
282 | #define L2CAP_CONF_EWS 0x07 | ||
236 | 283 | ||
237 | #define L2CAP_CONF_MAX_SIZE 22 | 284 | #define L2CAP_CONF_MAX_SIZE 22 |
238 | 285 | ||
@@ -251,6 +298,21 @@ struct l2cap_conf_rfc { | |||
251 | #define L2CAP_MODE_ERTM 0x03 | 298 | #define L2CAP_MODE_ERTM 0x03 |
252 | #define L2CAP_MODE_STREAMING 0x04 | 299 | #define L2CAP_MODE_STREAMING 0x04 |
253 | 300 | ||
301 | struct l2cap_conf_efs { | ||
302 | __u8 id; | ||
303 | __u8 stype; | ||
304 | __le16 msdu; | ||
305 | __le32 sdu_itime; | ||
306 | __le32 acc_lat; | ||
307 | __le32 flush_to; | ||
308 | } __packed; | ||
309 | |||
310 | #define L2CAP_SERV_NOTRAFIC 0x00 | ||
311 | #define L2CAP_SERV_BESTEFFORT 0x01 | ||
312 | #define L2CAP_SERV_GUARANTEED 0x02 | ||
313 | |||
314 | #define L2CAP_BESTEFFORT_ID 0x01 | ||
315 | |||
254 | struct l2cap_disconn_req { | 316 | struct l2cap_disconn_req { |
255 | __le16 dcid; | 317 | __le16 dcid; |
256 | __le16 scid; | 318 | __le16 scid; |
@@ -271,14 +333,57 @@ struct l2cap_info_rsp { | |||
271 | __u8 data[0]; | 333 | __u8 data[0]; |
272 | } __packed; | 334 | } __packed; |
273 | 335 | ||
336 | struct l2cap_create_chan_req { | ||
337 | __le16 psm; | ||
338 | __le16 scid; | ||
339 | __u8 amp_id; | ||
340 | } __packed; | ||
341 | |||
342 | struct l2cap_create_chan_rsp { | ||
343 | __le16 dcid; | ||
344 | __le16 scid; | ||
345 | __le16 result; | ||
346 | __le16 status; | ||
347 | } __packed; | ||
348 | |||
349 | struct l2cap_move_chan_req { | ||
350 | __le16 icid; | ||
351 | __u8 dest_amp_id; | ||
352 | } __packed; | ||
353 | |||
354 | struct l2cap_move_chan_rsp { | ||
355 | __le16 icid; | ||
356 | __le16 result; | ||
357 | } __packed; | ||
358 | |||
359 | #define L2CAP_MR_SUCCESS 0x0000 | ||
360 | #define L2CAP_MR_PEND 0x0001 | ||
361 | #define L2CAP_MR_BAD_ID 0x0002 | ||
362 | #define L2CAP_MR_SAME_ID 0x0003 | ||
363 | #define L2CAP_MR_NOT_SUPP 0x0004 | ||
364 | #define L2CAP_MR_COLLISION 0x0005 | ||
365 | #define L2CAP_MR_NOT_ALLOWED 0x0006 | ||
366 | |||
367 | struct l2cap_move_chan_cfm { | ||
368 | __le16 icid; | ||
369 | __le16 result; | ||
370 | } __packed; | ||
371 | |||
372 | #define L2CAP_MC_CONFIRMED 0x0000 | ||
373 | #define L2CAP_MC_UNCONFIRMED 0x0001 | ||
374 | |||
375 | struct l2cap_move_chan_cfm_rsp { | ||
376 | __le16 icid; | ||
377 | } __packed; | ||
378 | |||
274 | /* info type */ | 379 | /* info type */ |
275 | #define L2CAP_IT_CL_MTU 0x0001 | 380 | #define L2CAP_IT_CL_MTU 0x0001 |
276 | #define L2CAP_IT_FEAT_MASK 0x0002 | 381 | #define L2CAP_IT_FEAT_MASK 0x0002 |
277 | #define L2CAP_IT_FIXED_CHAN 0x0003 | 382 | #define L2CAP_IT_FIXED_CHAN 0x0003 |
278 | 383 | ||
279 | /* info result */ | 384 | /* info result */ |
280 | #define L2CAP_IR_SUCCESS 0x0000 | 385 | #define L2CAP_IR_SUCCESS 0x0000 |
281 | #define L2CAP_IR_NOTSUPP 0x0001 | 386 | #define L2CAP_IR_NOTSUPP 0x0001 |
282 | 387 | ||
283 | struct l2cap_conn_param_update_req { | 388 | struct l2cap_conn_param_update_req { |
284 | __le16 min; | 389 | __le16 min; |
@@ -297,7 +402,7 @@ struct l2cap_conn_param_update_rsp { | |||
297 | 402 | ||
298 | /* ----- L2CAP channels and connections ----- */ | 403 | /* ----- L2CAP channels and connections ----- */ |
299 | struct srej_list { | 404 | struct srej_list { |
300 | __u8 tx_seq; | 405 | __u16 tx_seq; |
301 | struct list_head list; | 406 | struct list_head list; |
302 | }; | 407 | }; |
303 | 408 | ||
@@ -319,14 +424,11 @@ struct l2cap_chan { | |||
319 | __u16 flush_to; | 424 | __u16 flush_to; |
320 | __u8 mode; | 425 | __u8 mode; |
321 | __u8 chan_type; | 426 | __u8 chan_type; |
427 | __u8 chan_policy; | ||
322 | 428 | ||
323 | __le16 sport; | 429 | __le16 sport; |
324 | 430 | ||
325 | __u8 sec_level; | 431 | __u8 sec_level; |
326 | __u8 role_switch; | ||
327 | __u8 force_reliable; | ||
328 | __u8 flushable; | ||
329 | __u8 force_active; | ||
330 | 432 | ||
331 | __u8 ident; | 433 | __u8 ident; |
332 | 434 | ||
@@ -337,7 +439,8 @@ struct l2cap_chan { | |||
337 | 439 | ||
338 | __u8 fcs; | 440 | __u8 fcs; |
339 | 441 | ||
340 | __u8 tx_win; | 442 | __u16 tx_win; |
443 | __u16 tx_win_max; | ||
341 | __u8 max_tx; | 444 | __u8 max_tx; |
342 | __u16 retrans_timeout; | 445 | __u16 retrans_timeout; |
343 | __u16 monitor_timeout; | 446 | __u16 monitor_timeout; |
@@ -345,25 +448,40 @@ struct l2cap_chan { | |||
345 | 448 | ||
346 | unsigned long conf_state; | 449 | unsigned long conf_state; |
347 | unsigned long conn_state; | 450 | unsigned long conn_state; |
348 | 451 | unsigned long flags; | |
349 | __u8 next_tx_seq; | 452 | |
350 | __u8 expected_ack_seq; | 453 | __u16 next_tx_seq; |
351 | __u8 expected_tx_seq; | 454 | __u16 expected_ack_seq; |
352 | __u8 buffer_seq; | 455 | __u16 expected_tx_seq; |
353 | __u8 buffer_seq_srej; | 456 | __u16 buffer_seq; |
354 | __u8 srej_save_reqseq; | 457 | __u16 buffer_seq_srej; |
355 | __u8 frames_sent; | 458 | __u16 srej_save_reqseq; |
356 | __u8 unacked_frames; | 459 | __u16 frames_sent; |
460 | __u16 unacked_frames; | ||
357 | __u8 retry_count; | 461 | __u8 retry_count; |
358 | __u8 num_acked; | 462 | __u8 num_acked; |
359 | __u16 sdu_len; | 463 | __u16 sdu_len; |
360 | struct sk_buff *sdu; | 464 | struct sk_buff *sdu; |
361 | struct sk_buff *sdu_last_frag; | 465 | struct sk_buff *sdu_last_frag; |
362 | 466 | ||
363 | __u8 remote_tx_win; | 467 | __u16 remote_tx_win; |
364 | __u8 remote_max_tx; | 468 | __u8 remote_max_tx; |
365 | __u16 remote_mps; | 469 | __u16 remote_mps; |
366 | 470 | ||
471 | __u8 local_id; | ||
472 | __u8 local_stype; | ||
473 | __u16 local_msdu; | ||
474 | __u32 local_sdu_itime; | ||
475 | __u32 local_acc_lat; | ||
476 | __u32 local_flush_to; | ||
477 | |||
478 | __u8 remote_id; | ||
479 | __u8 remote_stype; | ||
480 | __u16 remote_msdu; | ||
481 | __u32 remote_sdu_itime; | ||
482 | __u32 remote_acc_lat; | ||
483 | __u32 remote_flush_to; | ||
484 | |||
367 | struct timer_list chan_timer; | 485 | struct timer_list chan_timer; |
368 | struct timer_list retrans_timer; | 486 | struct timer_list retrans_timer; |
369 | struct timer_list monitor_timer; | 487 | struct timer_list monitor_timer; |
@@ -391,6 +509,7 @@ struct l2cap_ops { | |||
391 | 509 | ||
392 | struct l2cap_conn { | 510 | struct l2cap_conn { |
393 | struct hci_conn *hcon; | 511 | struct hci_conn *hcon; |
512 | struct hci_chan *hchan; | ||
394 | 513 | ||
395 | bdaddr_t *dst; | 514 | bdaddr_t *dst; |
396 | bdaddr_t *src; | 515 | bdaddr_t *src; |
@@ -445,6 +564,9 @@ enum { | |||
445 | CONF_CONNECT_PEND, | 564 | CONF_CONNECT_PEND, |
446 | CONF_NO_FCS_RECV, | 565 | CONF_NO_FCS_RECV, |
447 | CONF_STATE2_DEVICE, | 566 | CONF_STATE2_DEVICE, |
567 | CONF_EWS_RECV, | ||
568 | CONF_LOC_CONF_PEND, | ||
569 | CONF_REM_CONF_PEND, | ||
448 | }; | 570 | }; |
449 | 571 | ||
450 | #define L2CAP_CONF_MAX_CONF_REQ 2 | 572 | #define L2CAP_CONF_MAX_CONF_REQ 2 |
@@ -462,6 +584,16 @@ enum { | |||
462 | CONN_RNR_SENT, | 584 | CONN_RNR_SENT, |
463 | }; | 585 | }; |
464 | 586 | ||
587 | /* Definitions for flags in l2cap_chan */ | ||
588 | enum { | ||
589 | FLAG_ROLE_SWITCH, | ||
590 | FLAG_FORCE_ACTIVE, | ||
591 | FLAG_FORCE_RELIABLE, | ||
592 | FLAG_FLUSHABLE, | ||
593 | FLAG_EXT_CTRL, | ||
594 | FLAG_EFS_ENABLE, | ||
595 | }; | ||
596 | |||
465 | #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) | 597 | #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) |
466 | #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) | 598 | #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) |
467 | #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ | 599 | #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ |
@@ -474,6 +606,22 @@ enum { | |||
474 | L2CAP_DEFAULT_ACK_TO); | 606 | L2CAP_DEFAULT_ACK_TO); |
475 | #define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer) | 607 | #define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer) |
476 | 608 | ||
609 | static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2) | ||
610 | { | ||
611 | int offset; | ||
612 | |||
613 | offset = (seq1 - seq2) % (chan->tx_win_max + 1); | ||
614 | if (offset < 0) | ||
615 | offset += (chan->tx_win_max + 1); | ||
616 | |||
617 | return offset; | ||
618 | } | ||
619 | |||
620 | static inline __u16 __next_seq(struct l2cap_chan *chan, __u16 seq) | ||
621 | { | ||
622 | return (seq + 1) % (chan->tx_win_max + 1); | ||
623 | } | ||
624 | |||
477 | static inline int l2cap_tx_window_full(struct l2cap_chan *ch) | 625 | static inline int l2cap_tx_window_full(struct l2cap_chan *ch) |
478 | { | 626 | { |
479 | int sub; | 627 | int sub; |
@@ -486,13 +634,165 @@ static inline int l2cap_tx_window_full(struct l2cap_chan *ch) | |||
486 | return sub == ch->remote_tx_win; | 634 | return sub == ch->remote_tx_win; |
487 | } | 635 | } |
488 | 636 | ||
489 | #define __get_txseq(ctrl) (((ctrl) & L2CAP_CTRL_TXSEQ) >> 1) | 637 | static inline __u16 __get_reqseq(struct l2cap_chan *chan, __u32 ctrl) |
490 | #define __get_reqseq(ctrl) (((ctrl) & L2CAP_CTRL_REQSEQ) >> 8) | 638 | { |
491 | #define __is_iframe(ctrl) (!((ctrl) & L2CAP_CTRL_FRAME_TYPE)) | 639 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) |
492 | #define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE) | 640 | return (ctrl & L2CAP_EXT_CTRL_REQSEQ) >> |
493 | #define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) | 641 | L2CAP_EXT_CTRL_REQSEQ_SHIFT; |
642 | else | ||
643 | return (ctrl & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT; | ||
644 | } | ||
645 | |||
646 | static inline __u32 __set_reqseq(struct l2cap_chan *chan, __u32 reqseq) | ||
647 | { | ||
648 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
649 | return (reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT) & | ||
650 | L2CAP_EXT_CTRL_REQSEQ; | ||
651 | else | ||
652 | return (reqseq << L2CAP_CTRL_REQSEQ_SHIFT) & L2CAP_CTRL_REQSEQ; | ||
653 | } | ||
654 | |||
655 | static inline __u16 __get_txseq(struct l2cap_chan *chan, __u32 ctrl) | ||
656 | { | ||
657 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
658 | return (ctrl & L2CAP_EXT_CTRL_TXSEQ) >> | ||
659 | L2CAP_EXT_CTRL_TXSEQ_SHIFT; | ||
660 | else | ||
661 | return (ctrl & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT; | ||
662 | } | ||
663 | |||
664 | static inline __u32 __set_txseq(struct l2cap_chan *chan, __u32 txseq) | ||
665 | { | ||
666 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
667 | return (txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT) & | ||
668 | L2CAP_EXT_CTRL_TXSEQ; | ||
669 | else | ||
670 | return (txseq << L2CAP_CTRL_TXSEQ_SHIFT) & L2CAP_CTRL_TXSEQ; | ||
671 | } | ||
672 | |||
673 | static inline bool __is_sframe(struct l2cap_chan *chan, __u32 ctrl) | ||
674 | { | ||
675 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
676 | return ctrl & L2CAP_EXT_CTRL_FRAME_TYPE; | ||
677 | else | ||
678 | return ctrl & L2CAP_CTRL_FRAME_TYPE; | ||
679 | } | ||
680 | |||
681 | static inline __u32 __set_sframe(struct l2cap_chan *chan) | ||
682 | { | ||
683 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
684 | return L2CAP_EXT_CTRL_FRAME_TYPE; | ||
685 | else | ||
686 | return L2CAP_CTRL_FRAME_TYPE; | ||
687 | } | ||
688 | |||
689 | static inline __u8 __get_ctrl_sar(struct l2cap_chan *chan, __u32 ctrl) | ||
690 | { | ||
691 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
692 | return (ctrl & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT; | ||
693 | else | ||
694 | return (ctrl & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT; | ||
695 | } | ||
696 | |||
697 | static inline __u32 __set_ctrl_sar(struct l2cap_chan *chan, __u32 sar) | ||
698 | { | ||
699 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
700 | return (sar << L2CAP_EXT_CTRL_SAR_SHIFT) & L2CAP_EXT_CTRL_SAR; | ||
701 | else | ||
702 | return (sar << L2CAP_CTRL_SAR_SHIFT) & L2CAP_CTRL_SAR; | ||
703 | } | ||
704 | |||
705 | static inline bool __is_sar_start(struct l2cap_chan *chan, __u32 ctrl) | ||
706 | { | ||
707 | return __get_ctrl_sar(chan, ctrl) == L2CAP_SAR_START; | ||
708 | } | ||
709 | |||
710 | static inline __u32 __get_sar_mask(struct l2cap_chan *chan) | ||
711 | { | ||
712 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
713 | return L2CAP_EXT_CTRL_SAR; | ||
714 | else | ||
715 | return L2CAP_CTRL_SAR; | ||
716 | } | ||
717 | |||
718 | static inline __u8 __get_ctrl_super(struct l2cap_chan *chan, __u32 ctrl) | ||
719 | { | ||
720 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
721 | return (ctrl & L2CAP_EXT_CTRL_SUPERVISE) >> | ||
722 | L2CAP_EXT_CTRL_SUPER_SHIFT; | ||
723 | else | ||
724 | return (ctrl & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT; | ||
725 | } | ||
726 | |||
727 | static inline __u32 __set_ctrl_super(struct l2cap_chan *chan, __u32 super) | ||
728 | { | ||
729 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
730 | return (super << L2CAP_EXT_CTRL_SUPER_SHIFT) & | ||
731 | L2CAP_EXT_CTRL_SUPERVISE; | ||
732 | else | ||
733 | return (super << L2CAP_CTRL_SUPER_SHIFT) & | ||
734 | L2CAP_CTRL_SUPERVISE; | ||
735 | } | ||
736 | |||
737 | static inline __u32 __set_ctrl_final(struct l2cap_chan *chan) | ||
738 | { | ||
739 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
740 | return L2CAP_EXT_CTRL_FINAL; | ||
741 | else | ||
742 | return L2CAP_CTRL_FINAL; | ||
743 | } | ||
744 | |||
745 | static inline bool __is_ctrl_final(struct l2cap_chan *chan, __u32 ctrl) | ||
746 | { | ||
747 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
748 | return ctrl & L2CAP_EXT_CTRL_FINAL; | ||
749 | else | ||
750 | return ctrl & L2CAP_CTRL_FINAL; | ||
751 | } | ||
752 | |||
753 | static inline __u32 __set_ctrl_poll(struct l2cap_chan *chan) | ||
754 | { | ||
755 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
756 | return L2CAP_EXT_CTRL_POLL; | ||
757 | else | ||
758 | return L2CAP_CTRL_POLL; | ||
759 | } | ||
760 | |||
761 | static inline bool __is_ctrl_poll(struct l2cap_chan *chan, __u32 ctrl) | ||
762 | { | ||
763 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
764 | return ctrl & L2CAP_EXT_CTRL_POLL; | ||
765 | else | ||
766 | return ctrl & L2CAP_CTRL_POLL; | ||
767 | } | ||
768 | |||
769 | static inline __u32 __get_control(struct l2cap_chan *chan, void *p) | ||
770 | { | ||
771 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
772 | return get_unaligned_le32(p); | ||
773 | else | ||
774 | return get_unaligned_le16(p); | ||
775 | } | ||
776 | |||
777 | static inline void __put_control(struct l2cap_chan *chan, __u32 control, | ||
778 | void *p) | ||
779 | { | ||
780 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
781 | return put_unaligned_le32(control, p); | ||
782 | else | ||
783 | return put_unaligned_le16(control, p); | ||
784 | } | ||
785 | |||
786 | static inline __u8 __ctrl_size(struct l2cap_chan *chan) | ||
787 | { | ||
788 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
789 | return L2CAP_EXT_HDR_SIZE - L2CAP_HDR_SIZE; | ||
790 | else | ||
791 | return L2CAP_ENH_HDR_SIZE - L2CAP_HDR_SIZE; | ||
792 | } | ||
494 | 793 | ||
495 | extern int disable_ertm; | 794 | extern int disable_ertm; |
795 | extern int enable_hs; | ||
496 | 796 | ||
497 | int l2cap_init_sockets(void); | 797 | int l2cap_init_sockets(void); |
498 | void l2cap_cleanup_sockets(void); | 798 | void l2cap_cleanup_sockets(void); |
@@ -507,7 +807,8 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk); | |||
507 | void l2cap_chan_close(struct l2cap_chan *chan, int reason); | 807 | void l2cap_chan_close(struct l2cap_chan *chan, int reason); |
508 | void l2cap_chan_destroy(struct l2cap_chan *chan); | 808 | void l2cap_chan_destroy(struct l2cap_chan *chan); |
509 | int l2cap_chan_connect(struct l2cap_chan *chan); | 809 | int l2cap_chan_connect(struct l2cap_chan *chan); |
510 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len); | 810 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, |
811 | u32 priority); | ||
511 | void l2cap_chan_busy(struct l2cap_chan *chan, int busy); | 812 | void l2cap_chan_busy(struct l2cap_chan *chan, int busy); |
512 | 813 | ||
513 | #endif /* __L2CAP_H */ | 814 | #endif /* __L2CAP_H */ |
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index d66da0f94f95..3e320c9cae8f 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -69,6 +69,10 @@ struct mgmt_mode { | |||
69 | #define MGMT_OP_SET_POWERED 0x0005 | 69 | #define MGMT_OP_SET_POWERED 0x0005 |
70 | 70 | ||
71 | #define MGMT_OP_SET_DISCOVERABLE 0x0006 | 71 | #define MGMT_OP_SET_DISCOVERABLE 0x0006 |
72 | struct mgmt_cp_set_discoverable { | ||
73 | __u8 val; | ||
74 | __u16 timeout; | ||
75 | } __packed; | ||
72 | 76 | ||
73 | #define MGMT_OP_SET_CONNECTABLE 0x0007 | 77 | #define MGMT_OP_SET_CONNECTABLE 0x0007 |
74 | 78 | ||
@@ -96,24 +100,22 @@ struct mgmt_cp_set_service_cache { | |||
96 | __u8 enable; | 100 | __u8 enable; |
97 | } __packed; | 101 | } __packed; |
98 | 102 | ||
99 | struct mgmt_key_info { | 103 | struct mgmt_link_key_info { |
100 | bdaddr_t bdaddr; | 104 | bdaddr_t bdaddr; |
101 | u8 type; | 105 | u8 type; |
102 | u8 val[16]; | 106 | u8 val[16]; |
103 | u8 pin_len; | 107 | u8 pin_len; |
104 | u8 dlen; | ||
105 | u8 data[0]; | ||
106 | } __packed; | 108 | } __packed; |
107 | 109 | ||
108 | #define MGMT_OP_LOAD_KEYS 0x000D | 110 | #define MGMT_OP_LOAD_LINK_KEYS 0x000D |
109 | struct mgmt_cp_load_keys { | 111 | struct mgmt_cp_load_link_keys { |
110 | __u8 debug_keys; | 112 | __u8 debug_keys; |
111 | __le16 key_count; | 113 | __le16 key_count; |
112 | struct mgmt_key_info keys[0]; | 114 | struct mgmt_link_key_info keys[0]; |
113 | } __packed; | 115 | } __packed; |
114 | 116 | ||
115 | #define MGMT_OP_REMOVE_KEY 0x000E | 117 | #define MGMT_OP_REMOVE_KEYS 0x000E |
116 | struct mgmt_cp_remove_key { | 118 | struct mgmt_cp_remove_keys { |
117 | bdaddr_t bdaddr; | 119 | bdaddr_t bdaddr; |
118 | __u8 disconnect; | 120 | __u8 disconnect; |
119 | } __packed; | 121 | } __packed; |
@@ -126,10 +128,20 @@ struct mgmt_rp_disconnect { | |||
126 | bdaddr_t bdaddr; | 128 | bdaddr_t bdaddr; |
127 | } __packed; | 129 | } __packed; |
128 | 130 | ||
131 | #define MGMT_ADDR_BREDR 0x00 | ||
132 | #define MGMT_ADDR_LE 0x01 | ||
133 | #define MGMT_ADDR_BREDR_LE 0x02 | ||
134 | #define MGMT_ADDR_INVALID 0xff | ||
135 | |||
136 | struct mgmt_addr_info { | ||
137 | bdaddr_t bdaddr; | ||
138 | __u8 type; | ||
139 | } __packed; | ||
140 | |||
129 | #define MGMT_OP_GET_CONNECTIONS 0x0010 | 141 | #define MGMT_OP_GET_CONNECTIONS 0x0010 |
130 | struct mgmt_rp_get_connections { | 142 | struct mgmt_rp_get_connections { |
131 | __le16 conn_count; | 143 | __le16 conn_count; |
132 | bdaddr_t conn[0]; | 144 | struct mgmt_addr_info addr[0]; |
133 | } __packed; | 145 | } __packed; |
134 | 146 | ||
135 | #define MGMT_OP_PIN_CODE_REPLY 0x0011 | 147 | #define MGMT_OP_PIN_CODE_REPLY 0x0011 |
@@ -245,26 +257,19 @@ struct mgmt_ev_controller_error { | |||
245 | 257 | ||
246 | #define MGMT_EV_PAIRABLE 0x0009 | 258 | #define MGMT_EV_PAIRABLE 0x0009 |
247 | 259 | ||
248 | #define MGMT_EV_NEW_KEY 0x000A | 260 | #define MGMT_EV_NEW_LINK_KEY 0x000A |
249 | struct mgmt_ev_new_key { | 261 | struct mgmt_ev_new_link_key { |
250 | __u8 store_hint; | 262 | __u8 store_hint; |
251 | struct mgmt_key_info key; | 263 | struct mgmt_link_key_info key; |
252 | } __packed; | 264 | } __packed; |
253 | 265 | ||
254 | #define MGMT_EV_CONNECTED 0x000B | 266 | #define MGMT_EV_CONNECTED 0x000B |
255 | struct mgmt_ev_connected { | ||
256 | bdaddr_t bdaddr; | ||
257 | __u8 link_type; | ||
258 | } __packed; | ||
259 | 267 | ||
260 | #define MGMT_EV_DISCONNECTED 0x000C | 268 | #define MGMT_EV_DISCONNECTED 0x000C |
261 | struct mgmt_ev_disconnected { | ||
262 | bdaddr_t bdaddr; | ||
263 | } __packed; | ||
264 | 269 | ||
265 | #define MGMT_EV_CONNECT_FAILED 0x000D | 270 | #define MGMT_EV_CONNECT_FAILED 0x000D |
266 | struct mgmt_ev_connect_failed { | 271 | struct mgmt_ev_connect_failed { |
267 | bdaddr_t bdaddr; | 272 | struct mgmt_addr_info addr; |
268 | __u8 status; | 273 | __u8 status; |
269 | } __packed; | 274 | } __packed; |
270 | 275 | ||
@@ -294,7 +299,7 @@ struct mgmt_ev_local_name_changed { | |||
294 | 299 | ||
295 | #define MGMT_EV_DEVICE_FOUND 0x0012 | 300 | #define MGMT_EV_DEVICE_FOUND 0x0012 |
296 | struct mgmt_ev_device_found { | 301 | struct mgmt_ev_device_found { |
297 | bdaddr_t bdaddr; | 302 | struct mgmt_addr_info addr; |
298 | __u8 dev_class[3]; | 303 | __u8 dev_class[3]; |
299 | __s8 rssi; | 304 | __s8 rssi; |
300 | __u8 eir[HCI_MAX_EIR_LENGTH]; | 305 | __u8 eir[HCI_MAX_EIR_LENGTH]; |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 95852e36713b..8d7ba0961d3e 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -391,6 +391,8 @@ struct cfg80211_crypto_settings { | |||
391 | * @assocresp_ies: extra information element(s) to add into (Re)Association | 391 | * @assocresp_ies: extra information element(s) to add into (Re)Association |
392 | * Response frames or %NULL | 392 | * Response frames or %NULL |
393 | * @assocresp_ies_len: length of assocresp_ies in octets | 393 | * @assocresp_ies_len: length of assocresp_ies in octets |
394 | * @probe_resp_len: length of probe response template (@probe_resp) | ||
395 | * @probe_resp: probe response template (AP mode only) | ||
394 | */ | 396 | */ |
395 | struct beacon_parameters { | 397 | struct beacon_parameters { |
396 | u8 *head, *tail; | 398 | u8 *head, *tail; |
@@ -408,6 +410,8 @@ struct beacon_parameters { | |||
408 | size_t proberesp_ies_len; | 410 | size_t proberesp_ies_len; |
409 | const u8 *assocresp_ies; | 411 | const u8 *assocresp_ies; |
410 | size_t assocresp_ies_len; | 412 | size_t assocresp_ies_len; |
413 | int probe_resp_len; | ||
414 | u8 *probe_resp; | ||
411 | }; | 415 | }; |
412 | 416 | ||
413 | /** | 417 | /** |
@@ -1342,6 +1346,9 @@ struct cfg80211_gtk_rekey_data { | |||
1342 | * doesn't verify much. Note, however, that the passed netdev may be | 1346 | * doesn't verify much. Note, however, that the passed netdev may be |
1343 | * %NULL as well if the user requested changing the channel for the | 1347 | * %NULL as well if the user requested changing the channel for the |
1344 | * device itself, or for a monitor interface. | 1348 | * device itself, or for a monitor interface. |
1349 | * @get_channel: Get the current operating channel, should return %NULL if | ||
1350 | * there's no single defined operating channel if for example the | ||
1351 | * device implements channel hopping for multi-channel virtual interfaces. | ||
1345 | * | 1352 | * |
1346 | * @scan: Request to do a scan. If returning zero, the scan request is given | 1353 | * @scan: Request to do a scan. If returning zero, the scan request is given |
1347 | * the driver, and will be valid until passed to cfg80211_scan_done(). | 1354 | * the driver, and will be valid until passed to cfg80211_scan_done(). |
@@ -1432,6 +1439,9 @@ struct cfg80211_gtk_rekey_data { | |||
1432 | * | 1439 | * |
1433 | * @tdls_mgmt: Transmit a TDLS management frame. | 1440 | * @tdls_mgmt: Transmit a TDLS management frame. |
1434 | * @tdls_oper: Perform a high-level TDLS operation (e.g. TDLS link setup). | 1441 | * @tdls_oper: Perform a high-level TDLS operation (e.g. TDLS link setup). |
1442 | * | ||
1443 | * @probe_client: probe an associated client, must return a cookie that it | ||
1444 | * later passes to cfg80211_probe_status(). | ||
1435 | */ | 1445 | */ |
1436 | struct cfg80211_ops { | 1446 | struct cfg80211_ops { |
1437 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); | 1447 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); |
@@ -1585,7 +1595,7 @@ struct cfg80211_ops { | |||
1585 | enum nl80211_channel_type channel_type, | 1595 | enum nl80211_channel_type channel_type, |
1586 | bool channel_type_valid, unsigned int wait, | 1596 | bool channel_type_valid, unsigned int wait, |
1587 | const u8 *buf, size_t len, bool no_cck, | 1597 | const u8 *buf, size_t len, bool no_cck, |
1588 | u64 *cookie); | 1598 | bool dont_wait_for_ack, u64 *cookie); |
1589 | int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy, | 1599 | int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy, |
1590 | struct net_device *dev, | 1600 | struct net_device *dev, |
1591 | u64 cookie); | 1601 | u64 cookie); |
@@ -1621,6 +1631,11 @@ struct cfg80211_ops { | |||
1621 | u16 status_code, const u8 *buf, size_t len); | 1631 | u16 status_code, const u8 *buf, size_t len); |
1622 | int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev, | 1632 | int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev, |
1623 | u8 *peer, enum nl80211_tdls_operation oper); | 1633 | u8 *peer, enum nl80211_tdls_operation oper); |
1634 | |||
1635 | int (*probe_client)(struct wiphy *wiphy, struct net_device *dev, | ||
1636 | const u8 *peer, u64 *cookie); | ||
1637 | |||
1638 | struct ieee80211_channel *(*get_channel)(struct wiphy *wiphy); | ||
1624 | }; | 1639 | }; |
1625 | 1640 | ||
1626 | /* | 1641 | /* |
@@ -1679,6 +1694,12 @@ struct cfg80211_ops { | |||
1679 | * teardown packets should be sent through the @NL80211_CMD_TDLS_MGMT | 1694 | * teardown packets should be sent through the @NL80211_CMD_TDLS_MGMT |
1680 | * command. When this flag is not set, @NL80211_CMD_TDLS_OPER should be | 1695 | * command. When this flag is not set, @NL80211_CMD_TDLS_OPER should be |
1681 | * used for asking the driver/firmware to perform a TDLS operation. | 1696 | * used for asking the driver/firmware to perform a TDLS operation. |
1697 | * @WIPHY_FLAG_HAVE_AP_SME: device integrates AP SME | ||
1698 | * @WIPHY_FLAG_REPORTS_OBSS: the device will report beacons from other BSSes | ||
1699 | * when there are virtual interfaces in AP mode by calling | ||
1700 | * cfg80211_report_obss_beacon(). | ||
1701 | * @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD: When operating as an AP, the device | ||
1702 | * responds to probe-requests in hardware. | ||
1682 | */ | 1703 | */ |
1683 | enum wiphy_flags { | 1704 | enum wiphy_flags { |
1684 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), | 1705 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), |
@@ -1697,6 +1718,9 @@ enum wiphy_flags { | |||
1697 | WIPHY_FLAG_AP_UAPSD = BIT(14), | 1718 | WIPHY_FLAG_AP_UAPSD = BIT(14), |
1698 | WIPHY_FLAG_SUPPORTS_TDLS = BIT(15), | 1719 | WIPHY_FLAG_SUPPORTS_TDLS = BIT(15), |
1699 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP = BIT(16), | 1720 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP = BIT(16), |
1721 | WIPHY_FLAG_HAVE_AP_SME = BIT(17), | ||
1722 | WIPHY_FLAG_REPORTS_OBSS = BIT(18), | ||
1723 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19), | ||
1700 | }; | 1724 | }; |
1701 | 1725 | ||
1702 | /** | 1726 | /** |
@@ -1869,6 +1893,7 @@ struct wiphy_wowlan_support { | |||
1869 | * @software_iftypes: bitmask of software interface types, these are not | 1893 | * @software_iftypes: bitmask of software interface types, these are not |
1870 | * subject to any restrictions since they are purely managed in SW. | 1894 | * subject to any restrictions since they are purely managed in SW. |
1871 | * @flags: wiphy flags, see &enum wiphy_flags | 1895 | * @flags: wiphy flags, see &enum wiphy_flags |
1896 | * @features: features advertised to nl80211, see &enum nl80211_feature_flags. | ||
1872 | * @bss_priv_size: each BSS struct has private data allocated with it, | 1897 | * @bss_priv_size: each BSS struct has private data allocated with it, |
1873 | * this variable determines its size | 1898 | * this variable determines its size |
1874 | * @max_scan_ssids: maximum number of SSIDs the device can scan for in | 1899 | * @max_scan_ssids: maximum number of SSIDs the device can scan for in |
@@ -1907,6 +1932,8 @@ struct wiphy_wowlan_support { | |||
1907 | * may request, if implemented. | 1932 | * may request, if implemented. |
1908 | * | 1933 | * |
1909 | * @wowlan: WoWLAN support information | 1934 | * @wowlan: WoWLAN support information |
1935 | * | ||
1936 | * @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features. | ||
1910 | */ | 1937 | */ |
1911 | struct wiphy { | 1938 | struct wiphy { |
1912 | /* assign these fields before you register the wiphy */ | 1939 | /* assign these fields before you register the wiphy */ |
@@ -1928,7 +1955,9 @@ struct wiphy { | |||
1928 | /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ | 1955 | /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ |
1929 | u16 interface_modes; | 1956 | u16 interface_modes; |
1930 | 1957 | ||
1931 | u32 flags; | 1958 | u32 flags, features; |
1959 | |||
1960 | u32 ap_sme_capa; | ||
1932 | 1961 | ||
1933 | enum cfg80211_signal_type signal_type; | 1962 | enum cfg80211_signal_type signal_type; |
1934 | 1963 | ||
@@ -1960,6 +1989,13 @@ struct wiphy { | |||
1960 | u32 available_antennas_tx; | 1989 | u32 available_antennas_tx; |
1961 | u32 available_antennas_rx; | 1990 | u32 available_antennas_rx; |
1962 | 1991 | ||
1992 | /* | ||
1993 | * Bitmap of supported protocols for probe response offloading | ||
1994 | * see &enum nl80211_probe_resp_offload_support_attr. Only valid | ||
1995 | * when the wiphy flag @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD is set. | ||
1996 | */ | ||
1997 | u32 probe_resp_offload; | ||
1998 | |||
1963 | /* If multiple wiphys are registered and you're handed e.g. | 1999 | /* If multiple wiphys are registered and you're handed e.g. |
1964 | * a regular netdev with assigned ieee80211_ptr, you won't | 2000 | * a regular netdev with assigned ieee80211_ptr, you won't |
1965 | * know whether it points to a wiphy your driver has registered | 2001 | * know whether it points to a wiphy your driver has registered |
@@ -2183,6 +2219,8 @@ struct wireless_dev { | |||
2183 | 2219 | ||
2184 | int beacon_interval; | 2220 | int beacon_interval; |
2185 | 2221 | ||
2222 | u32 ap_unexpected_nlpid; | ||
2223 | |||
2186 | #ifdef CONFIG_CFG80211_WEXT | 2224 | #ifdef CONFIG_CFG80211_WEXT |
2187 | /* wext data */ | 2225 | /* wext data */ |
2188 | struct { | 2226 | struct { |
@@ -2636,8 +2674,10 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy); | |||
2636 | * | 2674 | * |
2637 | * This informs cfg80211 that BSS information was found and | 2675 | * This informs cfg80211 that BSS information was found and |
2638 | * the BSS should be updated/added. | 2676 | * the BSS should be updated/added. |
2677 | * | ||
2678 | * NOTE: Returns a referenced struct, must be released with cfg80211_put_bss()! | ||
2639 | */ | 2679 | */ |
2640 | struct cfg80211_bss* | 2680 | struct cfg80211_bss * __must_check |
2641 | cfg80211_inform_bss_frame(struct wiphy *wiphy, | 2681 | cfg80211_inform_bss_frame(struct wiphy *wiphy, |
2642 | struct ieee80211_channel *channel, | 2682 | struct ieee80211_channel *channel, |
2643 | struct ieee80211_mgmt *mgmt, size_t len, | 2683 | struct ieee80211_mgmt *mgmt, size_t len, |
@@ -2659,8 +2699,10 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, | |||
2659 | * | 2699 | * |
2660 | * This informs cfg80211 that BSS information was found and | 2700 | * This informs cfg80211 that BSS information was found and |
2661 | * the BSS should be updated/added. | 2701 | * the BSS should be updated/added. |
2702 | * | ||
2703 | * NOTE: Returns a referenced struct, must be released with cfg80211_put_bss()! | ||
2662 | */ | 2704 | */ |
2663 | struct cfg80211_bss* | 2705 | struct cfg80211_bss * __must_check |
2664 | cfg80211_inform_bss(struct wiphy *wiphy, | 2706 | cfg80211_inform_bss(struct wiphy *wiphy, |
2665 | struct ieee80211_channel *channel, | 2707 | struct ieee80211_channel *channel, |
2666 | const u8 *bssid, | 2708 | const u8 *bssid, |
@@ -3189,6 +3231,64 @@ void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid, | |||
3189 | void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, | 3231 | void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, |
3190 | const u8 *bssid, bool preauth, gfp_t gfp); | 3232 | const u8 *bssid, bool preauth, gfp_t gfp); |
3191 | 3233 | ||
3234 | /** | ||
3235 | * cfg80211_rx_spurious_frame - inform userspace about a spurious frame | ||
3236 | * @dev: The device the frame matched to | ||
3237 | * @addr: the transmitter address | ||
3238 | * @gfp: context flags | ||
3239 | * | ||
3240 | * This function is used in AP mode (only!) to inform userspace that | ||
3241 | * a spurious class 3 frame was received, to be able to deauth the | ||
3242 | * sender. | ||
3243 | * Returns %true if the frame was passed to userspace (or this failed | ||
3244 | * for a reason other than not having a subscription.) | ||
3245 | */ | ||
3246 | bool cfg80211_rx_spurious_frame(struct net_device *dev, | ||
3247 | const u8 *addr, gfp_t gfp); | ||
3248 | |||
3249 | /** | ||
3250 | * cfg80211_rx_unexpected_4addr_frame - inform about unexpected WDS frame | ||
3251 | * @dev: The device the frame matched to | ||
3252 | * @addr: the transmitter address | ||
3253 | * @gfp: context flags | ||
3254 | * | ||
3255 | * This function is used in AP mode (only!) to inform userspace that | ||
3256 | * an associated station sent a 4addr frame but that wasn't expected. | ||
3257 | * It is allowed and desirable to send this event only once for each | ||
3258 | * station to avoid event flooding. | ||
3259 | * Returns %true if the frame was passed to userspace (or this failed | ||
3260 | * for a reason other than not having a subscription.) | ||
3261 | */ | ||
3262 | bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, | ||
3263 | const u8 *addr, gfp_t gfp); | ||
3264 | |||
3265 | /** | ||
3266 | * cfg80211_probe_status - notify userspace about probe status | ||
3267 | * @dev: the device the probe was sent on | ||
3268 | * @addr: the address of the peer | ||
3269 | * @cookie: the cookie filled in @probe_client previously | ||
3270 | * @acked: indicates whether probe was acked or not | ||
3271 | * @gfp: allocation flags | ||
3272 | */ | ||
3273 | void cfg80211_probe_status(struct net_device *dev, const u8 *addr, | ||
3274 | u64 cookie, bool acked, gfp_t gfp); | ||
3275 | |||
3276 | /** | ||
3277 | * cfg80211_report_obss_beacon - report beacon from other APs | ||
3278 | * @wiphy: The wiphy that received the beacon | ||
3279 | * @frame: the frame | ||
3280 | * @len: length of the frame | ||
3281 | * @freq: frequency the frame was received on | ||
3282 | * @gfp: allocation flags | ||
3283 | * | ||
3284 | * Use this function to report to userspace when a beacon was | ||
3285 | * received. It is not useful to call this when there is no | ||
3286 | * netdev that is in AP/GO mode. | ||
3287 | */ | ||
3288 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, | ||
3289 | const u8 *frame, size_t len, | ||
3290 | int freq, gfp_t gfp); | ||
3291 | |||
3192 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ | 3292 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ |
3193 | 3293 | ||
3194 | /* wiphy_printk helpers, similar to dev_printk */ | 3294 | /* wiphy_printk helpers, similar to dev_printk */ |
diff --git a/include/net/icmp.h b/include/net/icmp.h index f0698b955b73..75d615649071 100644 --- a/include/net/icmp.h +++ b/include/net/icmp.h | |||
@@ -31,8 +31,8 @@ struct icmp_err { | |||
31 | extern const struct icmp_err icmp_err_convert[]; | 31 | extern const struct icmp_err icmp_err_convert[]; |
32 | #define ICMP_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.icmp_statistics, field) | 32 | #define ICMP_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.icmp_statistics, field) |
33 | #define ICMP_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.icmp_statistics, field) | 33 | #define ICMP_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.icmp_statistics, field) |
34 | #define ICMPMSGOUT_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.icmpmsg_statistics, field+256) | 34 | #define ICMPMSGOUT_INC_STATS(net, field) SNMP_INC_STATS_ATOMIC_LONG((net)->mib.icmpmsg_statistics, field+256) |
35 | #define ICMPMSGIN_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.icmpmsg_statistics, field) | 35 | #define ICMPMSGIN_INC_STATS_BH(net, field) SNMP_INC_STATS_ATOMIC_LONG((net)->mib.icmpmsg_statistics, field) |
36 | 36 | ||
37 | struct dst_entry; | 37 | struct dst_entry; |
38 | struct net_proto_family; | 38 | struct net_proto_family; |
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h index 7e2c4d483ad0..71392545d0a1 100644 --- a/include/net/ieee80211_radiotap.h +++ b/include/net/ieee80211_radiotap.h | |||
@@ -271,14 +271,6 @@ enum ieee80211_radiotap_type { | |||
271 | #define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 | 271 | #define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 |
272 | 272 | ||
273 | 273 | ||
274 | /* Ugly macro to convert literal channel numbers into their mhz equivalents | ||
275 | * There are certianly some conditions that will break this (like feeding it '30') | ||
276 | * but they shouldn't arise since nothing talks on channel 30. */ | ||
277 | #define ieee80211chan2mhz(x) \ | ||
278 | (((x) <= 14) ? \ | ||
279 | (((x) == 14) ? 2484 : ((x) * 5) + 2407) : \ | ||
280 | ((x) + 1000) * 5) | ||
281 | |||
282 | /* helpers */ | 274 | /* helpers */ |
283 | static inline int ieee80211_get_radiotap_len(unsigned char *data) | 275 | static inline int ieee80211_get_radiotap_len(unsigned char *data) |
284 | { | 276 | { |
diff --git a/include/net/ieee802154.h b/include/net/ieee802154.h index d52685defb11..ee59f8b188dd 100644 --- a/include/net/ieee802154.h +++ b/include/net/ieee802154.h | |||
@@ -21,11 +21,14 @@ | |||
21 | * Maxim Gorbachyov <maxim.gorbachev@siemens.com> | 21 | * Maxim Gorbachyov <maxim.gorbachev@siemens.com> |
22 | * Maxim Osipov <maxim.osipov@siemens.com> | 22 | * Maxim Osipov <maxim.osipov@siemens.com> |
23 | * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 23 | * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
24 | * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> | ||
24 | */ | 25 | */ |
25 | 26 | ||
26 | #ifndef NET_IEEE802154_H | 27 | #ifndef NET_IEEE802154_H |
27 | #define NET_IEEE802154_H | 28 | #define NET_IEEE802154_H |
28 | 29 | ||
30 | #define IEEE802154_MTU 127 | ||
31 | |||
29 | #define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */ | 32 | #define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */ |
30 | #define IEEE802154_FC_TYPE_DATA 0x1 /* Frame is data */ | 33 | #define IEEE802154_FC_TYPE_DATA 0x1 /* Frame is data */ |
31 | #define IEEE802154_FC_TYPE_ACK 0x2 /* Frame is acknowledgment */ | 34 | #define IEEE802154_FC_TYPE_ACK 0x2 /* Frame is acknowledgment */ |
@@ -56,6 +59,9 @@ | |||
56 | (((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT) | 59 | (((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT) |
57 | 60 | ||
58 | 61 | ||
62 | /* MAC footer size */ | ||
63 | #define IEEE802154_MFR_SIZE 2 /* 2 octets */ | ||
64 | |||
59 | /* MAC's Command Frames Identifiers */ | 65 | /* MAC's Command Frames Identifiers */ |
60 | #define IEEE802154_CMD_ASSOCIATION_REQ 0x01 | 66 | #define IEEE802154_CMD_ASSOCIATION_REQ 0x01 |
61 | #define IEEE802154_CMD_ASSOCIATION_RESP 0x02 | 67 | #define IEEE802154_CMD_ASSOCIATION_RESP 0x02 |
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index e6db62e756dc..dbf9aab34c82 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h | |||
@@ -143,9 +143,9 @@ static inline void *inet_csk_ca(const struct sock *sk) | |||
143 | return (void *)inet_csk(sk)->icsk_ca_priv; | 143 | return (void *)inet_csk(sk)->icsk_ca_priv; |
144 | } | 144 | } |
145 | 145 | ||
146 | extern struct sock *inet_csk_clone(struct sock *sk, | 146 | extern struct sock *inet_csk_clone_lock(const struct sock *sk, |
147 | const struct request_sock *req, | 147 | const struct request_sock *req, |
148 | const gfp_t priority); | 148 | const gfp_t priority); |
149 | 149 | ||
150 | enum inet_csk_ack_state_t { | 150 | enum inet_csk_ack_state_t { |
151 | ICSK_ACK_SCHED = 1, | 151 | ICSK_ACK_SCHED = 1, |
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 78c83e62218f..73a5c26c01ea 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h | |||
@@ -86,7 +86,7 @@ static inline struct inet_peer *inet_getpeer_v6(const struct in6_addr *v6daddr, | |||
86 | { | 86 | { |
87 | struct inetpeer_addr daddr; | 87 | struct inetpeer_addr daddr; |
88 | 88 | ||
89 | ipv6_addr_copy((struct in6_addr *)daddr.addr.a6, v6daddr); | 89 | *(struct in6_addr *)daddr.addr.a6 = *v6daddr; |
90 | daddr.family = AF_INET6; | 90 | daddr.family = AF_INET6; |
91 | return inet_getpeer(&daddr, create); | 91 | return inet_getpeer(&daddr, create); |
92 | } | 92 | } |
diff --git a/include/net/ip.h b/include/net/ip.h index eca0ef7a495e..fd1561e88a1a 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
@@ -450,7 +450,7 @@ extern int ip_options_rcv_srr(struct sk_buff *skb); | |||
450 | * Functions provided by ip_sockglue.c | 450 | * Functions provided by ip_sockglue.c |
451 | */ | 451 | */ |
452 | 452 | ||
453 | extern int ip_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); | 453 | extern void ipv4_pktinfo_prepare(struct sk_buff *skb); |
454 | extern void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb); | 454 | extern void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb); |
455 | extern int ip_cmsg_send(struct net *net, | 455 | extern int ip_cmsg_send(struct net *net, |
456 | struct msghdr *msg, struct ipcm_cookie *ipc); | 456 | struct msghdr *msg, struct ipcm_cookie *ipc); |
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 873d5be7926c..48fd12e9d3af 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/netfilter.h> /* for union nf_inet_addr */ | 21 | #include <linux/netfilter.h> /* for union nf_inet_addr */ |
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> /* for ipv6_addr_copy */ | 24 | #include <net/ipv6.h> |
25 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 25 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
26 | #include <net/netfilter/nf_conntrack.h> | 26 | #include <net/netfilter/nf_conntrack.h> |
27 | #endif | 27 | #endif |
@@ -119,8 +119,8 @@ ip_vs_fill_iphdr(int af, const void *nh, struct ip_vs_iphdr *iphdr) | |||
119 | const struct ipv6hdr *iph = nh; | 119 | const struct ipv6hdr *iph = nh; |
120 | iphdr->len = sizeof(struct ipv6hdr); | 120 | iphdr->len = sizeof(struct ipv6hdr); |
121 | iphdr->protocol = iph->nexthdr; | 121 | iphdr->protocol = iph->nexthdr; |
122 | ipv6_addr_copy(&iphdr->saddr.in6, &iph->saddr); | 122 | iphdr->saddr.in6 = iph->saddr; |
123 | ipv6_addr_copy(&iphdr->daddr.in6, &iph->daddr); | 123 | iphdr->daddr.in6 = iph->daddr; |
124 | } else | 124 | } else |
125 | #endif | 125 | #endif |
126 | { | 126 | { |
@@ -137,7 +137,7 @@ static inline void ip_vs_addr_copy(int af, union nf_inet_addr *dst, | |||
137 | { | 137 | { |
138 | #ifdef CONFIG_IP_VS_IPV6 | 138 | #ifdef CONFIG_IP_VS_IPV6 |
139 | if (af == AF_INET6) | 139 | if (af == AF_INET6) |
140 | ipv6_addr_copy(&dst->in6, &src->in6); | 140 | dst->in6 = src->in6; |
141 | else | 141 | else |
142 | #endif | 142 | #endif |
143 | dst->ip = src->ip; | 143 | dst->ip = src->ip; |
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index a366a8a1fe23..f35188e002d9 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -132,6 +132,15 @@ extern struct ctl_path net_ipv6_ctl_path[]; | |||
132 | SNMP_INC_STATS##modifier((net)->mib.statname##_statistics, (field));\ | 132 | SNMP_INC_STATS##modifier((net)->mib.statname##_statistics, (field));\ |
133 | }) | 133 | }) |
134 | 134 | ||
135 | /* per device and per net counters are atomic_long_t */ | ||
136 | #define _DEVINC_ATOMIC_ATOMIC(net, statname, idev, field) \ | ||
137 | ({ \ | ||
138 | struct inet6_dev *_idev = (idev); \ | ||
139 | if (likely(_idev != NULL)) \ | ||
140 | SNMP_INC_STATS_ATOMIC_LONG((_idev)->stats.statname##dev, (field)); \ | ||
141 | SNMP_INC_STATS_ATOMIC_LONG((net)->mib.statname##_statistics, (field));\ | ||
142 | }) | ||
143 | |||
135 | #define _DEVADD(net, statname, modifier, idev, field, val) \ | 144 | #define _DEVADD(net, statname, modifier, idev, field, val) \ |
136 | ({ \ | 145 | ({ \ |
137 | struct inet6_dev *_idev = (idev); \ | 146 | struct inet6_dev *_idev = (idev); \ |
@@ -168,11 +177,11 @@ extern struct ctl_path net_ipv6_ctl_path[]; | |||
168 | _DEVINCATOMIC(net, icmpv6, _BH, idev, field) | 177 | _DEVINCATOMIC(net, icmpv6, _BH, idev, field) |
169 | 178 | ||
170 | #define ICMP6MSGOUT_INC_STATS(net, idev, field) \ | 179 | #define ICMP6MSGOUT_INC_STATS(net, idev, field) \ |
171 | _DEVINCATOMIC(net, icmpv6msg, , idev, field +256) | 180 | _DEVINC_ATOMIC_ATOMIC(net, icmpv6msg, idev, field +256) |
172 | #define ICMP6MSGOUT_INC_STATS_BH(net, idev, field) \ | 181 | #define ICMP6MSGOUT_INC_STATS_BH(net, idev, field) \ |
173 | _DEVINCATOMIC(net, icmpv6msg, _BH, idev, field +256) | 182 | _DEVINC_ATOMIC_ATOMIC(net, icmpv6msg, idev, field +256) |
174 | #define ICMP6MSGIN_INC_STATS_BH(net, idev, field) \ | 183 | #define ICMP6MSGIN_INC_STATS_BH(net, idev, field) \ |
175 | _DEVINCATOMIC(net, icmpv6msg, _BH, idev, field) | 184 | _DEVINC_ATOMIC_ATOMIC(net, icmpv6msg, idev, field) |
176 | 185 | ||
177 | struct ip6_ra_chain { | 186 | struct ip6_ra_chain { |
178 | struct ip6_ra_chain *next; | 187 | struct ip6_ra_chain *next; |
@@ -300,11 +309,6 @@ ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m, | |||
300 | ((a1->s6_addr32[3] ^ a2->s6_addr32[3]) & m->s6_addr32[3])); | 309 | ((a1->s6_addr32[3] ^ a2->s6_addr32[3]) & m->s6_addr32[3])); |
301 | } | 310 | } |
302 | 311 | ||
303 | static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2) | ||
304 | { | ||
305 | memcpy(a1, a2, sizeof(struct in6_addr)); | ||
306 | } | ||
307 | |||
308 | static inline void ipv6_addr_prefix(struct in6_addr *pfx, | 312 | static inline void ipv6_addr_prefix(struct in6_addr *pfx, |
309 | const struct in6_addr *addr, | 313 | const struct in6_addr *addr, |
310 | int plen) | 314 | int plen) |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 72eddd1b410b..0756049ae76d 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -166,6 +166,7 @@ struct ieee80211_low_level_stats { | |||
166 | * that it is only ever disabled for station mode. | 166 | * that it is only ever disabled for station mode. |
167 | * @BSS_CHANGED_IDLE: Idle changed for this BSS/interface. | 167 | * @BSS_CHANGED_IDLE: Idle changed for this BSS/interface. |
168 | * @BSS_CHANGED_SSID: SSID changed for this BSS (AP mode) | 168 | * @BSS_CHANGED_SSID: SSID changed for this BSS (AP mode) |
169 | * @BSS_CHANGED_AP_PROBE_RESP: Probe Response changed for this BSS (AP mode) | ||
169 | */ | 170 | */ |
170 | enum ieee80211_bss_change { | 171 | enum ieee80211_bss_change { |
171 | BSS_CHANGED_ASSOC = 1<<0, | 172 | BSS_CHANGED_ASSOC = 1<<0, |
@@ -184,6 +185,7 @@ enum ieee80211_bss_change { | |||
184 | BSS_CHANGED_QOS = 1<<13, | 185 | BSS_CHANGED_QOS = 1<<13, |
185 | BSS_CHANGED_IDLE = 1<<14, | 186 | BSS_CHANGED_IDLE = 1<<14, |
186 | BSS_CHANGED_SSID = 1<<15, | 187 | BSS_CHANGED_SSID = 1<<15, |
188 | BSS_CHANGED_AP_PROBE_RESP = 1<<16, | ||
187 | 189 | ||
188 | /* when adding here, make sure to change ieee80211_reconfig */ | 190 | /* when adding here, make sure to change ieee80211_reconfig */ |
189 | }; | 191 | }; |
@@ -518,7 +520,7 @@ struct ieee80211_tx_rate { | |||
518 | * @flags: transmit info flags, defined above | 520 | * @flags: transmit info flags, defined above |
519 | * @band: the band to transmit on (use for checking for races) | 521 | * @band: the band to transmit on (use for checking for races) |
520 | * @antenna_sel_tx: antenna to use, 0 for automatic diversity | 522 | * @antenna_sel_tx: antenna to use, 0 for automatic diversity |
521 | * @pad: padding, ignore | 523 | * @ack_frame_id: internal frame ID for TX status, used internally |
522 | * @control: union for control data | 524 | * @control: union for control data |
523 | * @status: union for status data | 525 | * @status: union for status data |
524 | * @driver_data: array of driver_data pointers | 526 | * @driver_data: array of driver_data pointers |
@@ -535,8 +537,7 @@ struct ieee80211_tx_info { | |||
535 | 537 | ||
536 | u8 antenna_sel_tx; | 538 | u8 antenna_sel_tx; |
537 | 539 | ||
538 | /* 2 byte hole */ | 540 | u16 ack_frame_id; |
539 | u8 pad[2]; | ||
540 | 541 | ||
541 | union { | 542 | union { |
542 | struct { | 543 | struct { |
@@ -901,6 +902,10 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif) | |||
901 | * @IEEE80211_KEY_FLAG_SW_MGMT: This flag should be set by the driver for a | 902 | * @IEEE80211_KEY_FLAG_SW_MGMT: This flag should be set by the driver for a |
902 | * CCMP key if it requires CCMP encryption of management frames (MFP) to | 903 | * CCMP key if it requires CCMP encryption of management frames (MFP) to |
903 | * be done in software. | 904 | * be done in software. |
905 | * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver | ||
906 | * for a CCMP key if space should be prepared for the IV, but the IV | ||
907 | * itself should not be generated. Do not set together with | ||
908 | * @IEEE80211_KEY_FLAG_GENERATE_IV on the same key. | ||
904 | */ | 909 | */ |
905 | enum ieee80211_key_flags { | 910 | enum ieee80211_key_flags { |
906 | IEEE80211_KEY_FLAG_WMM_STA = 1<<0, | 911 | IEEE80211_KEY_FLAG_WMM_STA = 1<<0, |
@@ -908,6 +913,7 @@ enum ieee80211_key_flags { | |||
908 | IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2, | 913 | IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2, |
909 | IEEE80211_KEY_FLAG_PAIRWISE = 1<<3, | 914 | IEEE80211_KEY_FLAG_PAIRWISE = 1<<3, |
910 | IEEE80211_KEY_FLAG_SW_MGMT = 1<<4, | 915 | IEEE80211_KEY_FLAG_SW_MGMT = 1<<4, |
916 | IEEE80211_KEY_FLAG_PUT_IV_SPACE = 1<<5, | ||
911 | }; | 917 | }; |
912 | 918 | ||
913 | /** | 919 | /** |
@@ -1304,6 +1310,16 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, | |||
1304 | } | 1310 | } |
1305 | 1311 | ||
1306 | /** | 1312 | /** |
1313 | * ieee80211_free_txskb - free TX skb | ||
1314 | * @hw: the hardware | ||
1315 | * @skb: the skb | ||
1316 | * | ||
1317 | * Free a transmit skb. Use this funtion when some failure | ||
1318 | * to transmit happened and thus status cannot be reported. | ||
1319 | */ | ||
1320 | void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
1321 | |||
1322 | /** | ||
1307 | * DOC: Hardware crypto acceleration | 1323 | * DOC: Hardware crypto acceleration |
1308 | * | 1324 | * |
1309 | * mac80211 is capable of taking advantage of many hardware | 1325 | * mac80211 is capable of taking advantage of many hardware |
@@ -2661,6 +2677,19 @@ static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
2661 | } | 2677 | } |
2662 | 2678 | ||
2663 | /** | 2679 | /** |
2680 | * ieee80211_proberesp_get - retrieve a Probe Response template | ||
2681 | * @hw: pointer obtained from ieee80211_alloc_hw(). | ||
2682 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. | ||
2683 | * | ||
2684 | * Creates a Probe Response template which can, for example, be uploaded to | ||
2685 | * hardware. The destination address should be set by the caller. | ||
2686 | * | ||
2687 | * Can only be called in AP mode. | ||
2688 | */ | ||
2689 | struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw, | ||
2690 | struct ieee80211_vif *vif); | ||
2691 | |||
2692 | /** | ||
2664 | * ieee80211_pspoll_get - retrieve a PS Poll template | 2693 | * ieee80211_pspoll_get - retrieve a PS Poll template |
2665 | * @hw: pointer obtained from ieee80211_alloc_hw(). | 2694 | * @hw: pointer obtained from ieee80211_alloc_hw(). |
2666 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. | 2695 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. |
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 2720884287c3..7ae5acff96e9 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h | |||
@@ -59,7 +59,7 @@ struct neigh_parms { | |||
59 | int reachable_time; | 59 | int reachable_time; |
60 | int delay_probe_time; | 60 | int delay_probe_time; |
61 | 61 | ||
62 | int queue_len; | 62 | int queue_len_bytes; |
63 | int ucast_probes; | 63 | int ucast_probes; |
64 | int app_probes; | 64 | int app_probes; |
65 | int mcast_probes; | 65 | int mcast_probes; |
@@ -99,6 +99,7 @@ struct neighbour { | |||
99 | rwlock_t lock; | 99 | rwlock_t lock; |
100 | atomic_t refcnt; | 100 | atomic_t refcnt; |
101 | struct sk_buff_head arp_queue; | 101 | struct sk_buff_head arp_queue; |
102 | unsigned int arp_queue_len_bytes; | ||
102 | struct timer_list timer; | 103 | struct timer_list timer; |
103 | unsigned long used; | 104 | unsigned long used; |
104 | atomic_t probes; | 105 | atomic_t probes; |
diff --git a/include/net/netns/mib.h b/include/net/netns/mib.h index 0b44112e2366..30f6728ee98c 100644 --- a/include/net/netns/mib.h +++ b/include/net/netns/mib.h | |||
@@ -10,7 +10,7 @@ struct netns_mib { | |||
10 | DEFINE_SNMP_STAT(struct udp_mib, udp_statistics); | 10 | DEFINE_SNMP_STAT(struct udp_mib, udp_statistics); |
11 | DEFINE_SNMP_STAT(struct udp_mib, udplite_statistics); | 11 | DEFINE_SNMP_STAT(struct udp_mib, udplite_statistics); |
12 | DEFINE_SNMP_STAT(struct icmp_mib, icmp_statistics); | 12 | DEFINE_SNMP_STAT(struct icmp_mib, icmp_statistics); |
13 | DEFINE_SNMP_STAT(struct icmpmsg_mib, icmpmsg_statistics); | 13 | DEFINE_SNMP_STAT_ATOMIC(struct icmpmsg_mib, icmpmsg_statistics); |
14 | 14 | ||
15 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 15 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
16 | struct proc_dir_entry *proc_net_devsnmp6; | 16 | struct proc_dir_entry *proc_net_devsnmp6; |
@@ -18,7 +18,7 @@ struct netns_mib { | |||
18 | DEFINE_SNMP_STAT(struct udp_mib, udplite_stats_in6); | 18 | DEFINE_SNMP_STAT(struct udp_mib, udplite_stats_in6); |
19 | DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); | 19 | DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); |
20 | DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); | 20 | DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); |
21 | DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics); | 21 | DEFINE_SNMP_STAT_ATOMIC(struct icmpv6msg_mib, icmpv6msg_statistics); |
22 | #endif | 22 | #endif |
23 | #ifdef CONFIG_XFRM_STATISTICS | 23 | #ifdef CONFIG_XFRM_STATISTICS |
24 | DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics); | 24 | DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics); |
diff --git a/include/net/netprio_cgroup.h b/include/net/netprio_cgroup.h new file mode 100644 index 000000000000..e503b87c4c1b --- /dev/null +++ b/include/net/netprio_cgroup.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * netprio_cgroup.h Control Group Priority set | ||
3 | * | ||
4 | * | ||
5 | * Authors: Neil Horman <nhorman@tuxdriver.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the Free | ||
9 | * Software Foundation; either version 2 of the License, or (at your option) | ||
10 | * any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #ifndef _NETPRIO_CGROUP_H | ||
15 | #define _NETPRIO_CGROUP_H | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/cgroup.h> | ||
18 | #include <linux/hardirq.h> | ||
19 | #include <linux/rcupdate.h> | ||
20 | |||
21 | |||
22 | struct netprio_map { | ||
23 | struct rcu_head rcu; | ||
24 | u32 priomap_len; | ||
25 | u32 priomap[]; | ||
26 | }; | ||
27 | |||
28 | #ifdef CONFIG_CGROUPS | ||
29 | |||
30 | struct cgroup_netprio_state { | ||
31 | struct cgroup_subsys_state css; | ||
32 | u32 prioidx; | ||
33 | }; | ||
34 | |||
35 | #ifndef CONFIG_NETPRIO_CGROUP | ||
36 | extern int net_prio_subsys_id; | ||
37 | #endif | ||
38 | |||
39 | extern void sock_update_netprioidx(struct sock *sk); | ||
40 | |||
41 | static inline struct cgroup_netprio_state | ||
42 | *task_netprio_state(struct task_struct *p) | ||
43 | { | ||
44 | #if IS_ENABLED(CONFIG_NETPRIO_CGROUP) | ||
45 | return container_of(task_subsys_state(p, net_prio_subsys_id), | ||
46 | struct cgroup_netprio_state, css); | ||
47 | #else | ||
48 | return NULL; | ||
49 | #endif | ||
50 | } | ||
51 | |||
52 | #else | ||
53 | |||
54 | #define sock_update_netprioidx(sk) | ||
55 | #endif | ||
56 | |||
57 | #endif /* _NET_CLS_CGROUP_H */ | ||
diff --git a/include/net/nfc/nci.h b/include/net/nfc/nci.h index 39b85bc0804f..cdbe67139343 100644 --- a/include/net/nfc/nci.h +++ b/include/net/nfc/nci.h | |||
@@ -36,24 +36,23 @@ | |||
36 | /* NCI Status Codes */ | 36 | /* NCI Status Codes */ |
37 | #define NCI_STATUS_OK 0x00 | 37 | #define NCI_STATUS_OK 0x00 |
38 | #define NCI_STATUS_REJECTED 0x01 | 38 | #define NCI_STATUS_REJECTED 0x01 |
39 | #define NCI_STATUS_MESSAGE_CORRUPTED 0x02 | 39 | #define NCI_STATUS_RF_FRAME_CORRUPTED 0x02 |
40 | #define NCI_STATUS_BUFFER_FULL 0x03 | 40 | #define NCI_STATUS_FAILED 0x03 |
41 | #define NCI_STATUS_FAILED 0x04 | 41 | #define NCI_STATUS_NOT_INITIALIZED 0x04 |
42 | #define NCI_STATUS_NOT_INITIALIZED 0x05 | 42 | #define NCI_STATUS_SYNTAX_ERROR 0x05 |
43 | #define NCI_STATUS_SYNTAX_ERROR 0x06 | 43 | #define NCI_STATUS_SEMANTIC_ERROR 0x06 |
44 | #define NCI_STATUS_SEMANTIC_ERROR 0x07 | 44 | #define NCI_STATUS_UNKNOWN_GID 0x07 |
45 | #define NCI_STATUS_UNKNOWN_GID 0x08 | 45 | #define NCI_STATUS_UNKNOWN_OID 0x08 |
46 | #define NCI_STATUS_UNKNOWN_OID 0x09 | 46 | #define NCI_STATUS_INVALID_PARAM 0x09 |
47 | #define NCI_STATUS_INVALID_PARAM 0x0a | 47 | #define NCI_STATUS_MESSAGE_SIZE_EXCEEDED 0x0a |
48 | #define NCI_STATUS_MESSAGE_SIZE_EXCEEDED 0x0b | ||
49 | /* Discovery Specific Status Codes */ | 48 | /* Discovery Specific Status Codes */ |
50 | #define NCI_STATUS_DISCOVERY_ALREADY_STARTED 0xa0 | 49 | #define NCI_STATUS_DISCOVERY_ALREADY_STARTED 0xa0 |
51 | #define NCI_STATUS_DISCOVERY_TARGET_ACTIVATION_FAILED 0xa1 | 50 | #define NCI_STATUS_DISCOVERY_TARGET_ACTIVATION_FAILED 0xa1 |
51 | #define NCI_STATUS_DISCOVERY_TEAR_DOWN 0xa2 | ||
52 | /* RF Interface Specific Status Codes */ | 52 | /* RF Interface Specific Status Codes */ |
53 | #define NCI_STATUS_RF_TRANSMISSION_ERROR 0xb0 | 53 | #define NCI_STATUS_RF_TRANSMISSION_ERROR 0xb0 |
54 | #define NCI_STATUS_RF_PROTOCOL_ERROR 0xb1 | 54 | #define NCI_STATUS_RF_PROTOCOL_ERROR 0xb1 |
55 | #define NCI_STATUS_RF_TIMEOUT_ERROR 0xb2 | 55 | #define NCI_STATUS_RF_TIMEOUT_ERROR 0xb2 |
56 | #define NCI_STATUS_RF_LINK_LOSS_ERROR 0xb3 | ||
57 | /* NFCEE Interface Specific Status Codes */ | 56 | /* NFCEE Interface Specific Status Codes */ |
58 | #define NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED 0xc0 | 57 | #define NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED 0xc0 |
59 | #define NCI_STATUS_NFCEE_INTERFACE_ACTIVATION_FAILED 0xc1 | 58 | #define NCI_STATUS_NFCEE_INTERFACE_ACTIVATION_FAILED 0xc1 |
@@ -73,6 +72,21 @@ | |||
73 | #define NCI_NFC_A_ACTIVE_LISTEN_MODE 0x83 | 72 | #define NCI_NFC_A_ACTIVE_LISTEN_MODE 0x83 |
74 | #define NCI_NFC_F_ACTIVE_LISTEN_MODE 0x85 | 73 | #define NCI_NFC_F_ACTIVE_LISTEN_MODE 0x85 |
75 | 74 | ||
75 | /* NCI RF Technologies */ | ||
76 | #define NCI_NFC_RF_TECHNOLOGY_A 0x00 | ||
77 | #define NCI_NFC_RF_TECHNOLOGY_B 0x01 | ||
78 | #define NCI_NFC_RF_TECHNOLOGY_F 0x02 | ||
79 | #define NCI_NFC_RF_TECHNOLOGY_15693 0x03 | ||
80 | |||
81 | /* NCI Bit Rates */ | ||
82 | #define NCI_NFC_BIT_RATE_106 0x00 | ||
83 | #define NCI_NFC_BIT_RATE_212 0x01 | ||
84 | #define NCI_NFC_BIT_RATE_424 0x02 | ||
85 | #define NCI_NFC_BIT_RATE_848 0x03 | ||
86 | #define NCI_NFC_BIT_RATE_1696 0x04 | ||
87 | #define NCI_NFC_BIT_RATE_3392 0x05 | ||
88 | #define NCI_NFC_BIT_RATE_6784 0x06 | ||
89 | |||
76 | /* NCI RF Protocols */ | 90 | /* NCI RF Protocols */ |
77 | #define NCI_RF_PROTOCOL_UNKNOWN 0x00 | 91 | #define NCI_RF_PROTOCOL_UNKNOWN 0x00 |
78 | #define NCI_RF_PROTOCOL_T1T 0x01 | 92 | #define NCI_RF_PROTOCOL_T1T 0x01 |
@@ -82,11 +96,21 @@ | |||
82 | #define NCI_RF_PROTOCOL_NFC_DEP 0x05 | 96 | #define NCI_RF_PROTOCOL_NFC_DEP 0x05 |
83 | 97 | ||
84 | /* NCI RF Interfaces */ | 98 | /* NCI RF Interfaces */ |
85 | #define NCI_RF_INTERFACE_RFU 0x00 | 99 | #define NCI_RF_INTERFACE_NFCEE_DIRECT 0x00 |
86 | #define NCI_RF_INTERFACE_FRAME 0x01 | 100 | #define NCI_RF_INTERFACE_FRAME 0x01 |
87 | #define NCI_RF_INTERFACE_ISO_DEP 0x02 | 101 | #define NCI_RF_INTERFACE_ISO_DEP 0x02 |
88 | #define NCI_RF_INTERFACE_NFC_DEP 0x03 | 102 | #define NCI_RF_INTERFACE_NFC_DEP 0x03 |
89 | 103 | ||
104 | /* NCI Reset types */ | ||
105 | #define NCI_RESET_TYPE_KEEP_CONFIG 0x00 | ||
106 | #define NCI_RESET_TYPE_RESET_CONFIG 0x01 | ||
107 | |||
108 | /* NCI Static RF connection ID */ | ||
109 | #define NCI_STATIC_RF_CONN_ID 0x00 | ||
110 | |||
111 | /* NCI Data Flow Control */ | ||
112 | #define NCI_DATA_FLOW_CONTROL_NOT_USED 0xff | ||
113 | |||
90 | /* NCI RF_DISCOVER_MAP_CMD modes */ | 114 | /* NCI RF_DISCOVER_MAP_CMD modes */ |
91 | #define NCI_DISC_MAP_MODE_POLL 0x01 | 115 | #define NCI_DISC_MAP_MODE_POLL 0x01 |
92 | #define NCI_DISC_MAP_MODE_LISTEN 0x02 | 116 | #define NCI_DISC_MAP_MODE_LISTEN 0x02 |
@@ -98,8 +122,6 @@ | |||
98 | #define NCI_DISCOVERY_TYPE_POLL_F_PASSIVE 0x02 | 122 | #define NCI_DISCOVERY_TYPE_POLL_F_PASSIVE 0x02 |
99 | #define NCI_DISCOVERY_TYPE_POLL_A_ACTIVE 0x03 | 123 | #define NCI_DISCOVERY_TYPE_POLL_A_ACTIVE 0x03 |
100 | #define NCI_DISCOVERY_TYPE_POLL_F_ACTIVE 0x05 | 124 | #define NCI_DISCOVERY_TYPE_POLL_F_ACTIVE 0x05 |
101 | #define NCI_DISCOVERY_TYPE_WAKEUP_A_PASSIVE 0x06 | ||
102 | #define NCI_DISCOVERY_TYPE_WAKEUP_B_PASSIVE 0x07 | ||
103 | #define NCI_DISCOVERY_TYPE_WAKEUP_A_ACTIVE 0x09 | 125 | #define NCI_DISCOVERY_TYPE_WAKEUP_A_ACTIVE 0x09 |
104 | #define NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE 0x80 | 126 | #define NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE 0x80 |
105 | #define NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE 0x81 | 127 | #define NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE 0x81 |
@@ -111,8 +133,7 @@ | |||
111 | #define NCI_DEACTIVATE_TYPE_IDLE_MODE 0x00 | 133 | #define NCI_DEACTIVATE_TYPE_IDLE_MODE 0x00 |
112 | #define NCI_DEACTIVATE_TYPE_SLEEP_MODE 0x01 | 134 | #define NCI_DEACTIVATE_TYPE_SLEEP_MODE 0x01 |
113 | #define NCI_DEACTIVATE_TYPE_SLEEP_AF_MODE 0x02 | 135 | #define NCI_DEACTIVATE_TYPE_SLEEP_AF_MODE 0x02 |
114 | #define NCI_DEACTIVATE_TYPE_RF_LINK_LOSS 0x03 | 136 | #define NCI_DEACTIVATE_TYPE_DISCOVERY 0x03 |
115 | #define NCI_DEACTIVATE_TYPE_DISCOVERY_ERROR 0x04 | ||
116 | 137 | ||
117 | /* Message Type (MT) */ | 138 | /* Message Type (MT) */ |
118 | #define NCI_MT_DATA_PKT 0x00 | 139 | #define NCI_MT_DATA_PKT 0x00 |
@@ -169,18 +190,11 @@ struct nci_data_hdr { | |||
169 | /* ----- NCI Commands ---- */ | 190 | /* ----- NCI Commands ---- */ |
170 | /* ------------------------ */ | 191 | /* ------------------------ */ |
171 | #define NCI_OP_CORE_RESET_CMD nci_opcode_pack(NCI_GID_CORE, 0x00) | 192 | #define NCI_OP_CORE_RESET_CMD nci_opcode_pack(NCI_GID_CORE, 0x00) |
172 | 193 | struct nci_core_reset_cmd { | |
173 | #define NCI_OP_CORE_INIT_CMD nci_opcode_pack(NCI_GID_CORE, 0x01) | 194 | __u8 reset_type; |
174 | |||
175 | #define NCI_OP_CORE_SET_CONFIG_CMD nci_opcode_pack(NCI_GID_CORE, 0x02) | ||
176 | |||
177 | #define NCI_OP_CORE_CONN_CREATE_CMD nci_opcode_pack(NCI_GID_CORE, 0x04) | ||
178 | struct nci_core_conn_create_cmd { | ||
179 | __u8 target_handle; | ||
180 | __u8 num_target_specific_params; | ||
181 | } __packed; | 195 | } __packed; |
182 | 196 | ||
183 | #define NCI_OP_CORE_CONN_CLOSE_CMD nci_opcode_pack(NCI_GID_CORE, 0x06) | 197 | #define NCI_OP_CORE_INIT_CMD nci_opcode_pack(NCI_GID_CORE, 0x01) |
184 | 198 | ||
185 | #define NCI_OP_RF_DISCOVER_MAP_CMD nci_opcode_pack(NCI_GID_RF_MGMT, 0x00) | 199 | #define NCI_OP_RF_DISCOVER_MAP_CMD nci_opcode_pack(NCI_GID_RF_MGMT, 0x00) |
186 | struct disc_map_config { | 200 | struct disc_map_config { |
@@ -218,6 +232,7 @@ struct nci_rf_deactivate_cmd { | |||
218 | struct nci_core_reset_rsp { | 232 | struct nci_core_reset_rsp { |
219 | __u8 status; | 233 | __u8 status; |
220 | __u8 nci_ver; | 234 | __u8 nci_ver; |
235 | __u8 config_status; | ||
221 | } __packed; | 236 | } __packed; |
222 | 237 | ||
223 | #define NCI_OP_CORE_INIT_RSP nci_opcode_pack(NCI_GID_CORE, 0x01) | 238 | #define NCI_OP_CORE_INIT_RSP nci_opcode_pack(NCI_GID_CORE, 0x01) |
@@ -232,24 +247,14 @@ struct nci_core_init_rsp_1 { | |||
232 | struct nci_core_init_rsp_2 { | 247 | struct nci_core_init_rsp_2 { |
233 | __u8 max_logical_connections; | 248 | __u8 max_logical_connections; |
234 | __le16 max_routing_table_size; | 249 | __le16 max_routing_table_size; |
235 | __u8 max_control_packet_payload_length; | 250 | __u8 max_ctrl_pkt_payload_len; |
236 | __le16 rf_sending_buffer_size; | 251 | __le16 max_size_for_large_params; |
237 | __le16 rf_receiving_buffer_size; | 252 | __u8 max_data_pkt_payload_size; |
238 | __le16 manufacturer_id; | ||
239 | } __packed; | ||
240 | |||
241 | #define NCI_OP_CORE_SET_CONFIG_RSP nci_opcode_pack(NCI_GID_CORE, 0x02) | ||
242 | |||
243 | #define NCI_OP_CORE_CONN_CREATE_RSP nci_opcode_pack(NCI_GID_CORE, 0x04) | ||
244 | struct nci_core_conn_create_rsp { | ||
245 | __u8 status; | ||
246 | __u8 max_pkt_payload_size; | ||
247 | __u8 initial_num_credits; | 253 | __u8 initial_num_credits; |
248 | __u8 conn_id; | 254 | __u8 manufact_id; |
255 | __le32 manufact_specific_info; | ||
249 | } __packed; | 256 | } __packed; |
250 | 257 | ||
251 | #define NCI_OP_CORE_CONN_CLOSE_RSP nci_opcode_pack(NCI_GID_CORE, 0x06) | ||
252 | |||
253 | #define NCI_OP_RF_DISCOVER_MAP_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x00) | 258 | #define NCI_OP_RF_DISCOVER_MAP_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x00) |
254 | 259 | ||
255 | #define NCI_OP_RF_DISCOVER_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x03) | 260 | #define NCI_OP_RF_DISCOVER_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x03) |
@@ -270,12 +275,7 @@ struct nci_core_conn_credit_ntf { | |||
270 | struct conn_credit_entry conn_entries[NCI_MAX_NUM_CONN]; | 275 | struct conn_credit_entry conn_entries[NCI_MAX_NUM_CONN]; |
271 | } __packed; | 276 | } __packed; |
272 | 277 | ||
273 | #define NCI_OP_RF_FIELD_INFO_NTF nci_opcode_pack(NCI_GID_CORE, 0x08) | 278 | #define NCI_OP_RF_INTF_ACTIVATED_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x05) |
274 | struct nci_rf_field_info_ntf { | ||
275 | __u8 rf_field_status; | ||
276 | } __packed; | ||
277 | |||
278 | #define NCI_OP_RF_ACTIVATE_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x05) | ||
279 | struct rf_tech_specific_params_nfca_poll { | 279 | struct rf_tech_specific_params_nfca_poll { |
280 | __u16 sens_res; | 280 | __u16 sens_res; |
281 | __u8 nfcid1_len; /* 0, 4, 7, or 10 Bytes */ | 281 | __u8 nfcid1_len; /* 0, 4, 7, or 10 Bytes */ |
@@ -289,17 +289,20 @@ struct activation_params_nfca_poll_iso_dep { | |||
289 | __u8 rats_res[20]; | 289 | __u8 rats_res[20]; |
290 | }; | 290 | }; |
291 | 291 | ||
292 | struct nci_rf_activate_ntf { | 292 | struct nci_rf_intf_activated_ntf { |
293 | __u8 target_handle; | 293 | __u8 rf_discovery_id; |
294 | __u8 rf_interface_type; | ||
294 | __u8 rf_protocol; | 295 | __u8 rf_protocol; |
295 | __u8 rf_tech_and_mode; | 296 | __u8 activation_rf_tech_and_mode; |
296 | __u8 rf_tech_specific_params_len; | 297 | __u8 rf_tech_specific_params_len; |
297 | 298 | ||
298 | union { | 299 | union { |
299 | struct rf_tech_specific_params_nfca_poll nfca_poll; | 300 | struct rf_tech_specific_params_nfca_poll nfca_poll; |
300 | } rf_tech_specific_params; | 301 | } rf_tech_specific_params; |
301 | 302 | ||
302 | __u8 rf_interface_type; | 303 | __u8 data_exch_rf_tech_and_mode; |
304 | __u8 data_exch_tx_bit_rate; | ||
305 | __u8 data_exch_rx_bit_rate; | ||
303 | __u8 activation_params_len; | 306 | __u8 activation_params_len; |
304 | 307 | ||
305 | union { | 308 | union { |
@@ -309,5 +312,9 @@ struct nci_rf_activate_ntf { | |||
309 | } __packed; | 312 | } __packed; |
310 | 313 | ||
311 | #define NCI_OP_RF_DEACTIVATE_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x06) | 314 | #define NCI_OP_RF_DEACTIVATE_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x06) |
315 | struct nci_rf_deactivate_ntf { | ||
316 | __u8 type; | ||
317 | __u8 reason; | ||
318 | } __packed; | ||
312 | 319 | ||
313 | #endif /* __NCI_H */ | 320 | #endif /* __NCI_H */ |
diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index b8b4bbd7e0fc..c92b69d7e0c2 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h | |||
@@ -109,15 +109,12 @@ struct nci_dev { | |||
109 | [NCI_MAX_SUPPORTED_RF_INTERFACES]; | 109 | [NCI_MAX_SUPPORTED_RF_INTERFACES]; |
110 | __u8 max_logical_connections; | 110 | __u8 max_logical_connections; |
111 | __u16 max_routing_table_size; | 111 | __u16 max_routing_table_size; |
112 | __u8 max_control_packet_payload_length; | 112 | __u8 max_ctrl_pkt_payload_len; |
113 | __u16 rf_sending_buffer_size; | 113 | __u16 max_size_for_large_params; |
114 | __u16 rf_receiving_buffer_size; | 114 | __u8 max_data_pkt_payload_size; |
115 | __u16 manufacturer_id; | ||
116 | |||
117 | /* received during NCI_OP_CORE_CONN_CREATE_RSP for static conn 0 */ | ||
118 | __u8 max_pkt_payload_size; | ||
119 | __u8 initial_num_credits; | 115 | __u8 initial_num_credits; |
120 | __u8 conn_id; | 116 | __u8 manufact_id; |
117 | __u32 manufact_specific_info; | ||
121 | 118 | ||
122 | /* stored during nci_data_exchange */ | 119 | /* stored during nci_data_exchange */ |
123 | data_exchange_cb_t data_exchange_cb; | 120 | data_exchange_cb_t data_exchange_cb; |
diff --git a/include/net/protocol.h b/include/net/protocol.h index 6f7eb800974a..e182e13d6391 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h | |||
@@ -38,7 +38,7 @@ struct net_protocol { | |||
38 | void (*err_handler)(struct sk_buff *skb, u32 info); | 38 | void (*err_handler)(struct sk_buff *skb, u32 info); |
39 | int (*gso_send_check)(struct sk_buff *skb); | 39 | int (*gso_send_check)(struct sk_buff *skb); |
40 | struct sk_buff *(*gso_segment)(struct sk_buff *skb, | 40 | struct sk_buff *(*gso_segment)(struct sk_buff *skb, |
41 | u32 features); | 41 | netdev_features_t features); |
42 | struct sk_buff **(*gro_receive)(struct sk_buff **head, | 42 | struct sk_buff **(*gro_receive)(struct sk_buff **head, |
43 | struct sk_buff *skb); | 43 | struct sk_buff *skb); |
44 | int (*gro_complete)(struct sk_buff *skb); | 44 | int (*gro_complete)(struct sk_buff *skb); |
@@ -57,7 +57,7 @@ struct inet6_protocol { | |||
57 | 57 | ||
58 | int (*gso_send_check)(struct sk_buff *skb); | 58 | int (*gso_send_check)(struct sk_buff *skb); |
59 | struct sk_buff *(*gso_segment)(struct sk_buff *skb, | 59 | struct sk_buff *(*gso_segment)(struct sk_buff *skb, |
60 | u32 features); | 60 | netdev_features_t features); |
61 | struct sk_buff **(*gro_receive)(struct sk_buff **head, | 61 | struct sk_buff **(*gro_receive)(struct sk_buff **head, |
62 | struct sk_buff *skb); | 62 | struct sk_buff *skb); |
63 | int (*gro_complete)(struct sk_buff *skb); | 63 | int (*gro_complete)(struct sk_buff *skb); |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index e90e7a9935dd..3382615bd710 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -1085,6 +1085,7 @@ void sctp_transport_burst_reset(struct sctp_transport *); | |||
1085 | unsigned long sctp_transport_timeout(struct sctp_transport *); | 1085 | unsigned long sctp_transport_timeout(struct sctp_transport *); |
1086 | void sctp_transport_reset(struct sctp_transport *); | 1086 | void sctp_transport_reset(struct sctp_transport *); |
1087 | void sctp_transport_update_pmtu(struct sctp_transport *, u32); | 1087 | void sctp_transport_update_pmtu(struct sctp_transport *, u32); |
1088 | void sctp_transport_immediate_rtx(struct sctp_transport *); | ||
1088 | 1089 | ||
1089 | 1090 | ||
1090 | /* This is the structure we use to queue packets as they come into | 1091 | /* This is the structure we use to queue packets as they come into |
diff --git a/include/net/snmp.h b/include/net/snmp.h index 8f0f9ac0307f..2f65e1686fc8 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h | |||
@@ -67,7 +67,7 @@ struct icmp_mib { | |||
67 | 67 | ||
68 | #define ICMPMSG_MIB_MAX __ICMPMSG_MIB_MAX | 68 | #define ICMPMSG_MIB_MAX __ICMPMSG_MIB_MAX |
69 | struct icmpmsg_mib { | 69 | struct icmpmsg_mib { |
70 | unsigned long mibs[ICMPMSG_MIB_MAX]; | 70 | atomic_long_t mibs[ICMPMSG_MIB_MAX]; |
71 | }; | 71 | }; |
72 | 72 | ||
73 | /* ICMP6 (IPv6-ICMP) */ | 73 | /* ICMP6 (IPv6-ICMP) */ |
@@ -84,7 +84,7 @@ struct icmpv6_mib_device { | |||
84 | #define ICMP6MSG_MIB_MAX __ICMP6MSG_MIB_MAX | 84 | #define ICMP6MSG_MIB_MAX __ICMP6MSG_MIB_MAX |
85 | /* per network ns counters */ | 85 | /* per network ns counters */ |
86 | struct icmpv6msg_mib { | 86 | struct icmpv6msg_mib { |
87 | unsigned long mibs[ICMP6MSG_MIB_MAX]; | 87 | atomic_long_t mibs[ICMP6MSG_MIB_MAX]; |
88 | }; | 88 | }; |
89 | /* per device counters, (shared on all cpus) */ | 89 | /* per device counters, (shared on all cpus) */ |
90 | struct icmpv6msg_mib_device { | 90 | struct icmpv6msg_mib_device { |
diff --git a/include/net/sock.h b/include/net/sock.h index abb6e0f0c3c3..8ac338cb39ce 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -306,8 +306,8 @@ struct sock { | |||
306 | kmemcheck_bitfield_end(flags); | 306 | kmemcheck_bitfield_end(flags); |
307 | int sk_wmem_queued; | 307 | int sk_wmem_queued; |
308 | gfp_t sk_allocation; | 308 | gfp_t sk_allocation; |
309 | int sk_route_caps; | 309 | netdev_features_t sk_route_caps; |
310 | int sk_route_nocaps; | 310 | netdev_features_t sk_route_nocaps; |
311 | int sk_gso_type; | 311 | int sk_gso_type; |
312 | unsigned int sk_gso_max_size; | 312 | unsigned int sk_gso_max_size; |
313 | int sk_rcvlowat; | 313 | int sk_rcvlowat; |
@@ -320,6 +320,9 @@ struct sock { | |||
320 | unsigned short sk_ack_backlog; | 320 | unsigned short sk_ack_backlog; |
321 | unsigned short sk_max_ack_backlog; | 321 | unsigned short sk_max_ack_backlog; |
322 | __u32 sk_priority; | 322 | __u32 sk_priority; |
323 | #ifdef CONFIG_CGROUPS | ||
324 | __u32 sk_cgrp_prioidx; | ||
325 | #endif | ||
323 | struct pid *sk_peer_pid; | 326 | struct pid *sk_peer_pid; |
324 | const struct cred *sk_peer_cred; | 327 | const struct cred *sk_peer_cred; |
325 | long sk_rcvtimeo; | 328 | long sk_rcvtimeo; |
@@ -563,6 +566,7 @@ enum sock_flags { | |||
563 | SOCK_FASYNC, /* fasync() active */ | 566 | SOCK_FASYNC, /* fasync() active */ |
564 | SOCK_RXQ_OVFL, | 567 | SOCK_RXQ_OVFL, |
565 | SOCK_ZEROCOPY, /* buffers from userspace */ | 568 | SOCK_ZEROCOPY, /* buffers from userspace */ |
569 | SOCK_WIFI_STATUS, /* push wifi status to userspace */ | ||
566 | }; | 570 | }; |
567 | 571 | ||
568 | static inline void sock_copy_flags(struct sock *nsk, struct sock *osk) | 572 | static inline void sock_copy_flags(struct sock *nsk, struct sock *osk) |
@@ -1089,8 +1093,8 @@ extern struct sock *sk_alloc(struct net *net, int family, | |||
1089 | struct proto *prot); | 1093 | struct proto *prot); |
1090 | extern void sk_free(struct sock *sk); | 1094 | extern void sk_free(struct sock *sk); |
1091 | extern void sk_release_kernel(struct sock *sk); | 1095 | extern void sk_release_kernel(struct sock *sk); |
1092 | extern struct sock *sk_clone(const struct sock *sk, | 1096 | extern struct sock *sk_clone_lock(const struct sock *sk, |
1093 | const gfp_t priority); | 1097 | const gfp_t priority); |
1094 | 1098 | ||
1095 | extern struct sk_buff *sock_wmalloc(struct sock *sk, | 1099 | extern struct sk_buff *sock_wmalloc(struct sock *sk, |
1096 | unsigned long size, int force, | 1100 | unsigned long size, int force, |
@@ -1393,7 +1397,7 @@ static inline int sk_can_gso(const struct sock *sk) | |||
1393 | 1397 | ||
1394 | extern void sk_setup_caps(struct sock *sk, struct dst_entry *dst); | 1398 | extern void sk_setup_caps(struct sock *sk, struct dst_entry *dst); |
1395 | 1399 | ||
1396 | static inline void sk_nocaps_add(struct sock *sk, int flags) | 1400 | static inline void sk_nocaps_add(struct sock *sk, netdev_features_t flags) |
1397 | { | 1401 | { |
1398 | sk->sk_route_nocaps |= flags; | 1402 | sk->sk_route_nocaps |= flags; |
1399 | sk->sk_route_caps &= ~flags; | 1403 | sk->sk_route_caps &= ~flags; |
@@ -1714,6 +1718,8 @@ static inline int sock_intr_errno(long timeo) | |||
1714 | 1718 | ||
1715 | extern void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, | 1719 | extern void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, |
1716 | struct sk_buff *skb); | 1720 | struct sk_buff *skb); |
1721 | extern void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, | ||
1722 | struct sk_buff *skb); | ||
1717 | 1723 | ||
1718 | static __inline__ void | 1724 | static __inline__ void |
1719 | sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) | 1725 | sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) |
@@ -1741,6 +1747,9 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) | |||
1741 | __sock_recv_timestamp(msg, sk, skb); | 1747 | __sock_recv_timestamp(msg, sk, skb); |
1742 | else | 1748 | else |
1743 | sk->sk_stamp = kt; | 1749 | sk->sk_stamp = kt; |
1750 | |||
1751 | if (sock_flag(sk, SOCK_WIFI_STATUS) && skb->wifi_acked_valid) | ||
1752 | __sock_recv_wifi_status(msg, sk, skb); | ||
1744 | } | 1753 | } |
1745 | 1754 | ||
1746 | extern void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, | 1755 | extern void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, |
diff --git a/include/net/tcp.h b/include/net/tcp.h index bb18c4d69aba..113160b84588 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -1430,7 +1430,8 @@ extern struct request_sock_ops tcp6_request_sock_ops; | |||
1430 | extern void tcp_v4_destroy_sock(struct sock *sk); | 1430 | extern void tcp_v4_destroy_sock(struct sock *sk); |
1431 | 1431 | ||
1432 | extern int tcp_v4_gso_send_check(struct sk_buff *skb); | 1432 | extern int tcp_v4_gso_send_check(struct sk_buff *skb); |
1433 | extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, u32 features); | 1433 | extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, |
1434 | netdev_features_t features); | ||
1434 | extern struct sk_buff **tcp_gro_receive(struct sk_buff **head, | 1435 | extern struct sk_buff **tcp_gro_receive(struct sk_buff **head, |
1435 | struct sk_buff *skb); | 1436 | struct sk_buff *skb); |
1436 | extern struct sk_buff **tcp4_gro_receive(struct sk_buff **head, | 1437 | extern struct sk_buff **tcp4_gro_receive(struct sk_buff **head, |
diff --git a/include/net/udp.h b/include/net/udp.h index 3b285f402f48..f54a5156b248 100644 --- a/include/net/udp.h +++ b/include/net/udp.h | |||
@@ -258,5 +258,6 @@ extern void udp4_proc_exit(void); | |||
258 | extern void udp_init(void); | 258 | extern void udp_init(void); |
259 | 259 | ||
260 | extern int udp4_ufo_send_check(struct sk_buff *skb); | 260 | extern int udp4_ufo_send_check(struct sk_buff *skb); |
261 | extern struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, u32 features); | 261 | extern struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, |
262 | netdev_features_t features); | ||
262 | #endif /* _UDP_H */ | 263 | #endif /* _UDP_H */ |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index b203e14d26b7..89174e29dca9 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -827,6 +827,14 @@ static inline bool addr_match(const void *token1, const void *token2, | |||
827 | return true; | 827 | return true; |
828 | } | 828 | } |
829 | 829 | ||
830 | static inline bool addr4_match(__be32 a1, __be32 a2, u8 prefixlen) | ||
831 | { | ||
832 | /* C99 6.5.7 (3): u32 << 32 is undefined behaviour */ | ||
833 | if (prefixlen == 0) | ||
834 | return true; | ||
835 | return !((a1 ^ a2) & htonl(0xFFFFFFFFu << (32 - prefixlen))); | ||
836 | } | ||
837 | |||
830 | static __inline__ | 838 | static __inline__ |
831 | __be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli) | 839 | __be16 xfrm_flowi_sport(const struct flowi *fl, const union flowi_uli *uli) |
832 | { | 840 | { |
@@ -1209,8 +1217,8 @@ void xfrm_flowi_addr_get(const struct flowi *fl, | |||
1209 | memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4)); | 1217 | memcpy(&daddr->a4, &fl->u.ip4.daddr, sizeof(daddr->a4)); |
1210 | break; | 1218 | break; |
1211 | case AF_INET6: | 1219 | case AF_INET6: |
1212 | ipv6_addr_copy((struct in6_addr *)&saddr->a6, &fl->u.ip6.saddr); | 1220 | *(struct in6_addr *)saddr->a6 = fl->u.ip6.saddr; |
1213 | ipv6_addr_copy((struct in6_addr *)&daddr->a6, &fl->u.ip6.daddr); | 1221 | *(struct in6_addr *)daddr->a6 = fl->u.ip6.daddr; |
1214 | break; | 1222 | break; |
1215 | } | 1223 | } |
1216 | } | 1224 | } |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 993599e66e5a..8e75003d62f6 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -777,6 +777,18 @@ char *uuid_string(char *buf, char *end, const u8 *addr, | |||
777 | return string(buf, end, uuid, spec); | 777 | return string(buf, end, uuid, spec); |
778 | } | 778 | } |
779 | 779 | ||
780 | static | ||
781 | char *netdev_feature_string(char *buf, char *end, const u8 *addr, | ||
782 | struct printf_spec spec) | ||
783 | { | ||
784 | spec.flags |= SPECIAL | SMALL | ZEROPAD; | ||
785 | if (spec.field_width == -1) | ||
786 | spec.field_width = 2 + 2 * sizeof(netdev_features_t); | ||
787 | spec.base = 16; | ||
788 | |||
789 | return number(buf, end, *(const netdev_features_t *)addr, spec); | ||
790 | } | ||
791 | |||
780 | int kptr_restrict __read_mostly; | 792 | int kptr_restrict __read_mostly; |
781 | 793 | ||
782 | /* | 794 | /* |
@@ -824,6 +836,7 @@ int kptr_restrict __read_mostly; | |||
824 | * Do not use this feature without some mechanism to verify the | 836 | * Do not use this feature without some mechanism to verify the |
825 | * correctness of the format string and va_list arguments. | 837 | * correctness of the format string and va_list arguments. |
826 | * - 'K' For a kernel pointer that should be hidden from unprivileged users | 838 | * - 'K' For a kernel pointer that should be hidden from unprivileged users |
839 | * - 'NF' For a netdev_features_t | ||
827 | * | 840 | * |
828 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 | 841 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 |
829 | * function pointers are really function descriptors, which contain a | 842 | * function pointers are really function descriptors, which contain a |
@@ -896,6 +909,12 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
896 | has_capability_noaudit(current, CAP_SYSLOG)))) | 909 | has_capability_noaudit(current, CAP_SYSLOG)))) |
897 | ptr = NULL; | 910 | ptr = NULL; |
898 | break; | 911 | break; |
912 | case 'N': | ||
913 | switch (fmt[1]) { | ||
914 | case 'F': | ||
915 | return netdev_feature_string(buf, end, ptr, spec); | ||
916 | } | ||
917 | break; | ||
899 | } | 918 | } |
900 | spec.flags |= SMALL; | 919 | spec.flags |= SMALL; |
901 | if (spec.field_width == -1) { | 920 | if (spec.field_width == -1) { |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index bc2528624583..2b5fcde1f629 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -591,18 +591,17 @@ static void vlan_dev_uninit(struct net_device *dev) | |||
591 | } | 591 | } |
592 | } | 592 | } |
593 | 593 | ||
594 | static u32 vlan_dev_fix_features(struct net_device *dev, u32 features) | 594 | static netdev_features_t vlan_dev_fix_features(struct net_device *dev, |
595 | netdev_features_t features) | ||
595 | { | 596 | { |
596 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; | 597 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
597 | u32 old_features = features; | 598 | u32 old_features = features; |
598 | 599 | ||
599 | features &= real_dev->features; | ||
600 | features &= real_dev->vlan_features; | 600 | features &= real_dev->vlan_features; |
601 | features |= NETIF_F_RXCSUM; | ||
602 | features &= real_dev->features; | ||
601 | 603 | ||
602 | features |= old_features & NETIF_F_SOFT_FEATURES; | 604 | features |= old_features & NETIF_F_SOFT_FEATURES; |
603 | |||
604 | if (dev_ethtool_get_rx_csum(real_dev)) | ||
605 | features |= NETIF_F_RXCSUM; | ||
606 | features |= NETIF_F_LLTX; | 605 | features |= NETIF_F_LLTX; |
607 | 606 | ||
608 | return features; | 607 | return features; |
diff --git a/net/Kconfig b/net/Kconfig index a07314844238..63d2c5dc36ff 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
@@ -232,6 +232,13 @@ config XPS | |||
232 | depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS | 232 | depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS |
233 | default y | 233 | default y |
234 | 234 | ||
235 | config NETPRIO_CGROUP | ||
236 | tristate "Network priority cgroup" | ||
237 | depends on CGROUPS | ||
238 | ---help--- | ||
239 | Cgroup subsystem for use in assigning processes to network priorities on | ||
240 | a per-interface basis | ||
241 | |||
235 | config HAVE_BPF_JIT | 242 | config HAVE_BPF_JIT |
236 | bool | 243 | bool |
237 | 244 | ||
diff --git a/net/atm/br2684.c b/net/atm/br2684.c index d07223c834af..53b0aa14a1e6 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c | |||
@@ -489,15 +489,11 @@ free_skb: | |||
489 | */ | 489 | */ |
490 | static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) | 490 | static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) |
491 | { | 491 | { |
492 | struct sk_buff_head queue; | ||
493 | int err; | ||
494 | struct br2684_vcc *brvcc; | 492 | struct br2684_vcc *brvcc; |
495 | struct sk_buff *skb, *tmp; | ||
496 | struct sk_buff_head *rq; | ||
497 | struct br2684_dev *brdev; | 493 | struct br2684_dev *brdev; |
498 | struct net_device *net_dev; | 494 | struct net_device *net_dev; |
499 | struct atm_backend_br2684 be; | 495 | struct atm_backend_br2684 be; |
500 | unsigned long flags; | 496 | int err; |
501 | 497 | ||
502 | if (copy_from_user(&be, arg, sizeof be)) | 498 | if (copy_from_user(&be, arg, sizeof be)) |
503 | return -EFAULT; | 499 | return -EFAULT; |
@@ -550,23 +546,6 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) | |||
550 | atmvcc->push = br2684_push; | 546 | atmvcc->push = br2684_push; |
551 | atmvcc->pop = br2684_pop; | 547 | atmvcc->pop = br2684_pop; |
552 | 548 | ||
553 | __skb_queue_head_init(&queue); | ||
554 | rq = &sk_atm(atmvcc)->sk_receive_queue; | ||
555 | |||
556 | spin_lock_irqsave(&rq->lock, flags); | ||
557 | skb_queue_splice_init(rq, &queue); | ||
558 | spin_unlock_irqrestore(&rq->lock, flags); | ||
559 | |||
560 | skb_queue_walk_safe(&queue, skb, tmp) { | ||
561 | struct net_device *dev; | ||
562 | |||
563 | br2684_push(atmvcc, skb); | ||
564 | dev = skb->dev; | ||
565 | |||
566 | dev->stats.rx_bytes -= skb->len; | ||
567 | dev->stats.rx_packets--; | ||
568 | } | ||
569 | |||
570 | /* initialize netdev carrier state */ | 549 | /* initialize netdev carrier state */ |
571 | if (atmvcc->dev->signal == ATM_PHY_SIG_LOST) | 550 | if (atmvcc->dev->signal == ATM_PHY_SIG_LOST) |
572 | netif_carrier_off(net_dev); | 551 | netif_carrier_off(net_dev); |
@@ -574,6 +553,10 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) | |||
574 | netif_carrier_on(net_dev); | 553 | netif_carrier_on(net_dev); |
575 | 554 | ||
576 | __module_get(THIS_MODULE); | 555 | __module_get(THIS_MODULE); |
556 | |||
557 | /* re-process everything received between connection setup and | ||
558 | backend setup */ | ||
559 | vcc_process_recv_queue(atmvcc); | ||
577 | return 0; | 560 | return 0; |
578 | 561 | ||
579 | error: | 562 | error: |
diff --git a/net/atm/clip.c b/net/atm/clip.c index 852394072fa1..11439a7f6782 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c | |||
@@ -189,6 +189,13 @@ static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb) | |||
189 | struct clip_vcc *clip_vcc = CLIP_VCC(vcc); | 189 | struct clip_vcc *clip_vcc = CLIP_VCC(vcc); |
190 | 190 | ||
191 | pr_debug("\n"); | 191 | pr_debug("\n"); |
192 | |||
193 | if (!clip_devs) { | ||
194 | atm_return(vcc, skb->truesize); | ||
195 | kfree_skb(skb); | ||
196 | return; | ||
197 | } | ||
198 | |||
192 | if (!skb) { | 199 | if (!skb) { |
193 | pr_debug("removing VCC %p\n", clip_vcc); | 200 | pr_debug("removing VCC %p\n", clip_vcc); |
194 | if (clip_vcc->entry) | 201 | if (clip_vcc->entry) |
@@ -329,7 +336,7 @@ static struct neigh_table clip_tbl = { | |||
329 | .gc_staletime = 60 * HZ, | 336 | .gc_staletime = 60 * HZ, |
330 | .reachable_time = 30 * HZ, | 337 | .reachable_time = 30 * HZ, |
331 | .delay_probe_time = 5 * HZ, | 338 | .delay_probe_time = 5 * HZ, |
332 | .queue_len = 3, | 339 | .queue_len_bytes = 64 * 1024, |
333 | .ucast_probes = 3, | 340 | .ucast_probes = 3, |
334 | .mcast_probes = 3, | 341 | .mcast_probes = 3, |
335 | .anycast_delay = 1 * HZ, | 342 | .anycast_delay = 1 * HZ, |
@@ -448,10 +455,7 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb, | |||
448 | 455 | ||
449 | static int clip_mkip(struct atm_vcc *vcc, int timeout) | 456 | static int clip_mkip(struct atm_vcc *vcc, int timeout) |
450 | { | 457 | { |
451 | struct sk_buff_head *rq, queue; | ||
452 | struct clip_vcc *clip_vcc; | 458 | struct clip_vcc *clip_vcc; |
453 | struct sk_buff *skb, *tmp; | ||
454 | unsigned long flags; | ||
455 | 459 | ||
456 | if (!vcc->push) | 460 | if (!vcc->push) |
457 | return -EBADFD; | 461 | return -EBADFD; |
@@ -472,29 +476,9 @@ static int clip_mkip(struct atm_vcc *vcc, int timeout) | |||
472 | vcc->push = clip_push; | 476 | vcc->push = clip_push; |
473 | vcc->pop = clip_pop; | 477 | vcc->pop = clip_pop; |
474 | 478 | ||
475 | __skb_queue_head_init(&queue); | ||
476 | rq = &sk_atm(vcc)->sk_receive_queue; | ||
477 | |||
478 | spin_lock_irqsave(&rq->lock, flags); | ||
479 | skb_queue_splice_init(rq, &queue); | ||
480 | spin_unlock_irqrestore(&rq->lock, flags); | ||
481 | |||
482 | /* re-process everything received between connection setup and MKIP */ | 479 | /* re-process everything received between connection setup and MKIP */ |
483 | skb_queue_walk_safe(&queue, skb, tmp) { | 480 | vcc_process_recv_queue(vcc); |
484 | if (!clip_devs) { | 481 | |
485 | atm_return(vcc, skb->truesize); | ||
486 | kfree_skb(skb); | ||
487 | } else { | ||
488 | struct net_device *dev = skb->dev; | ||
489 | unsigned int len = skb->len; | ||
490 | |||
491 | skb_get(skb); | ||
492 | clip_push(vcc, skb); | ||
493 | dev->stats.rx_packets--; | ||
494 | dev->stats.rx_bytes -= len; | ||
495 | kfree_skb(skb); | ||
496 | } | ||
497 | } | ||
498 | return 0; | 482 | return 0; |
499 | } | 483 | } |
500 | 484 | ||
diff --git a/net/atm/common.c b/net/atm/common.c index 14ff9fe39989..b4b44dbed645 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -214,6 +214,26 @@ void vcc_release_async(struct atm_vcc *vcc, int reply) | |||
214 | } | 214 | } |
215 | EXPORT_SYMBOL(vcc_release_async); | 215 | EXPORT_SYMBOL(vcc_release_async); |
216 | 216 | ||
217 | void vcc_process_recv_queue(struct atm_vcc *vcc) | ||
218 | { | ||
219 | struct sk_buff_head queue, *rq; | ||
220 | struct sk_buff *skb, *tmp; | ||
221 | unsigned long flags; | ||
222 | |||
223 | __skb_queue_head_init(&queue); | ||
224 | rq = &sk_atm(vcc)->sk_receive_queue; | ||
225 | |||
226 | spin_lock_irqsave(&rq->lock, flags); | ||
227 | skb_queue_splice_init(rq, &queue); | ||
228 | spin_unlock_irqrestore(&rq->lock, flags); | ||
229 | |||
230 | skb_queue_walk_safe(&queue, skb, tmp) { | ||
231 | __skb_unlink(skb, &queue); | ||
232 | vcc->push(vcc, skb); | ||
233 | } | ||
234 | } | ||
235 | EXPORT_SYMBOL(vcc_process_recv_queue); | ||
236 | |||
217 | void atm_dev_signal_change(struct atm_dev *dev, char signal) | 237 | void atm_dev_signal_change(struct atm_dev *dev, char signal) |
218 | { | 238 | { |
219 | pr_debug("%s signal=%d dev=%p number=%d dev->signal=%d\n", | 239 | pr_debug("%s signal=%d dev=%p number=%d dev->signal=%d\n", |
@@ -502,8 +522,11 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
502 | 522 | ||
503 | if (sock->state != SS_CONNECTED) | 523 | if (sock->state != SS_CONNECTED) |
504 | return -ENOTCONN; | 524 | return -ENOTCONN; |
505 | if (flags & ~MSG_DONTWAIT) /* only handle MSG_DONTWAIT */ | 525 | |
526 | /* only handle MSG_DONTWAIT and MSG_PEEK */ | ||
527 | if (flags & ~(MSG_DONTWAIT | MSG_PEEK)) | ||
506 | return -EOPNOTSUPP; | 528 | return -EOPNOTSUPP; |
529 | |||
507 | vcc = ATM_SD(sock); | 530 | vcc = ATM_SD(sock); |
508 | if (test_bit(ATM_VF_RELEASED, &vcc->flags) || | 531 | if (test_bit(ATM_VF_RELEASED, &vcc->flags) || |
509 | test_bit(ATM_VF_CLOSE, &vcc->flags) || | 532 | test_bit(ATM_VF_CLOSE, &vcc->flags) || |
@@ -524,8 +547,13 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
524 | if (error) | 547 | if (error) |
525 | return error; | 548 | return error; |
526 | sock_recv_ts_and_drops(msg, sk, skb); | 549 | sock_recv_ts_and_drops(msg, sk, skb); |
527 | pr_debug("%d -= %d\n", atomic_read(&sk->sk_rmem_alloc), skb->truesize); | 550 | |
528 | atm_return(vcc, skb->truesize); | 551 | if (!(flags & MSG_PEEK)) { |
552 | pr_debug("%d -= %d\n", atomic_read(&sk->sk_rmem_alloc), | ||
553 | skb->truesize); | ||
554 | atm_return(vcc, skb->truesize); | ||
555 | } | ||
556 | |||
529 | skb_free_datagram(sk, skb); | 557 | skb_free_datagram(sk, skb); |
530 | return copied; | 558 | return copied; |
531 | } | 559 | } |
diff --git a/net/atm/common.h b/net/atm/common.h index f48a76b6cdf4..cc3c2dae4d79 100644 --- a/net/atm/common.h +++ b/net/atm/common.h | |||
@@ -24,6 +24,7 @@ int vcc_setsockopt(struct socket *sock, int level, int optname, | |||
24 | char __user *optval, unsigned int optlen); | 24 | char __user *optval, unsigned int optlen); |
25 | int vcc_getsockopt(struct socket *sock, int level, int optname, | 25 | int vcc_getsockopt(struct socket *sock, int level, int optname, |
26 | char __user *optval, int __user *optlen); | 26 | char __user *optval, int __user *optlen); |
27 | void vcc_process_recv_queue(struct atm_vcc *vcc); | ||
27 | 28 | ||
28 | int atmpvc_init(void); | 29 | int atmpvc_init(void); |
29 | void atmpvc_exit(void); | 30 | void atmpvc_exit(void); |
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c index db4a11c61d15..df35d9a3b5fe 100644 --- a/net/atm/pppoatm.c +++ b/net/atm/pppoatm.c | |||
@@ -303,6 +303,10 @@ static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, void __user *arg) | |||
303 | atmvcc->push = pppoatm_push; | 303 | atmvcc->push = pppoatm_push; |
304 | atmvcc->pop = pppoatm_pop; | 304 | atmvcc->pop = pppoatm_pop; |
305 | __module_get(THIS_MODULE); | 305 | __module_get(THIS_MODULE); |
306 | |||
307 | /* re-process everything received between connection setup and | ||
308 | backend setup */ | ||
309 | vcc_process_recv_queue(atmvcc); | ||
306 | return 0; | 310 | return 0; |
307 | } | 311 | } |
308 | 312 | ||
diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index b8a7414c3571..c25492f7d665 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c | |||
@@ -174,7 +174,7 @@ static int store_uint_attr(const char *buff, size_t count, | |||
174 | unsigned long uint_val; | 174 | unsigned long uint_val; |
175 | int ret; | 175 | int ret; |
176 | 176 | ||
177 | ret = strict_strtoul(buff, 10, &uint_val); | 177 | ret = kstrtoul(buff, 10, &uint_val); |
178 | if (ret) { | 178 | if (ret) { |
179 | bat_info(net_dev, | 179 | bat_info(net_dev, |
180 | "%s: Invalid parameter received: %s\n", | 180 | "%s: Invalid parameter received: %s\n", |
@@ -239,7 +239,7 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, | |||
239 | unsigned long val; | 239 | unsigned long val; |
240 | int ret, vis_mode_tmp = -1; | 240 | int ret, vis_mode_tmp = -1; |
241 | 241 | ||
242 | ret = strict_strtoul(buff, 10, &val); | 242 | ret = kstrtoul(buff, 10, &val); |
243 | 243 | ||
244 | if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) || | 244 | if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) || |
245 | (strncmp(buff, "client", 6) == 0) || | 245 | (strncmp(buff, "client", 6) == 0) || |
diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c index 0be9ff346fa0..9bc63b209b3f 100644 --- a/net/batman-adv/bitarray.c +++ b/net/batman-adv/bitarray.c | |||
@@ -155,7 +155,7 @@ int bit_get_packet(void *priv, unsigned long *seq_bits, | |||
155 | /* sequence number is much newer, probably missed a lot of packets */ | 155 | /* sequence number is much newer, probably missed a lot of packets */ |
156 | 156 | ||
157 | if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE) | 157 | if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE) |
158 | || (seq_num_diff < EXPECTED_SEQNO_RANGE)) { | 158 | && (seq_num_diff < EXPECTED_SEQNO_RANGE)) { |
159 | bat_dbg(DBG_BATMAN, bat_priv, | 159 | bat_dbg(DBG_BATMAN, bat_priv, |
160 | "We missed a lot of packets (%i) !\n", | 160 | "We missed a lot of packets (%i) !\n", |
161 | seq_num_diff - 1); | 161 | seq_num_diff - 1); |
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 619fb73b3b76..9373a143c6d4 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "gateway_common.h" | 25 | #include "gateway_common.h" |
26 | #include "hard-interface.h" | 26 | #include "hard-interface.h" |
27 | #include "originator.h" | 27 | #include "originator.h" |
28 | #include "translation-table.h" | ||
28 | #include "routing.h" | 29 | #include "routing.h" |
29 | #include <linux/ip.h> | 30 | #include <linux/ip.h> |
30 | #include <linux/ipv6.h> | 31 | #include <linux/ipv6.h> |
@@ -572,108 +573,142 @@ out: | |||
572 | return ret; | 573 | return ret; |
573 | } | 574 | } |
574 | 575 | ||
575 | int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb, | 576 | bool gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len) |
576 | struct orig_node *old_gw) | ||
577 | { | 577 | { |
578 | struct ethhdr *ethhdr; | 578 | struct ethhdr *ethhdr; |
579 | struct iphdr *iphdr; | 579 | struct iphdr *iphdr; |
580 | struct ipv6hdr *ipv6hdr; | 580 | struct ipv6hdr *ipv6hdr; |
581 | struct udphdr *udphdr; | 581 | struct udphdr *udphdr; |
582 | struct gw_node *curr_gw; | ||
583 | struct neigh_node *neigh_curr = NULL, *neigh_old = NULL; | ||
584 | unsigned int header_len = 0; | ||
585 | int ret = 1; | ||
586 | |||
587 | if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF) | ||
588 | return 0; | ||
589 | 582 | ||
590 | /* check for ethernet header */ | 583 | /* check for ethernet header */ |
591 | if (!pskb_may_pull(skb, header_len + ETH_HLEN)) | 584 | if (!pskb_may_pull(skb, *header_len + ETH_HLEN)) |
592 | return 0; | 585 | return false; |
593 | ethhdr = (struct ethhdr *)skb->data; | 586 | ethhdr = (struct ethhdr *)skb->data; |
594 | header_len += ETH_HLEN; | 587 | *header_len += ETH_HLEN; |
595 | 588 | ||
596 | /* check for initial vlan header */ | 589 | /* check for initial vlan header */ |
597 | if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) { | 590 | if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) { |
598 | if (!pskb_may_pull(skb, header_len + VLAN_HLEN)) | 591 | if (!pskb_may_pull(skb, *header_len + VLAN_HLEN)) |
599 | return 0; | 592 | return false; |
600 | ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN); | 593 | ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN); |
601 | header_len += VLAN_HLEN; | 594 | *header_len += VLAN_HLEN; |
602 | } | 595 | } |
603 | 596 | ||
604 | /* check for ip header */ | 597 | /* check for ip header */ |
605 | switch (ntohs(ethhdr->h_proto)) { | 598 | switch (ntohs(ethhdr->h_proto)) { |
606 | case ETH_P_IP: | 599 | case ETH_P_IP: |
607 | if (!pskb_may_pull(skb, header_len + sizeof(*iphdr))) | 600 | if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr))) |
608 | return 0; | 601 | return false; |
609 | iphdr = (struct iphdr *)(skb->data + header_len); | 602 | iphdr = (struct iphdr *)(skb->data + *header_len); |
610 | header_len += iphdr->ihl * 4; | 603 | *header_len += iphdr->ihl * 4; |
611 | 604 | ||
612 | /* check for udp header */ | 605 | /* check for udp header */ |
613 | if (iphdr->protocol != IPPROTO_UDP) | 606 | if (iphdr->protocol != IPPROTO_UDP) |
614 | return 0; | 607 | return false; |
615 | 608 | ||
616 | break; | 609 | break; |
617 | case ETH_P_IPV6: | 610 | case ETH_P_IPV6: |
618 | if (!pskb_may_pull(skb, header_len + sizeof(*ipv6hdr))) | 611 | if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr))) |
619 | return 0; | 612 | return false; |
620 | ipv6hdr = (struct ipv6hdr *)(skb->data + header_len); | 613 | ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len); |
621 | header_len += sizeof(*ipv6hdr); | 614 | *header_len += sizeof(*ipv6hdr); |
622 | 615 | ||
623 | /* check for udp header */ | 616 | /* check for udp header */ |
624 | if (ipv6hdr->nexthdr != IPPROTO_UDP) | 617 | if (ipv6hdr->nexthdr != IPPROTO_UDP) |
625 | return 0; | 618 | return false; |
626 | 619 | ||
627 | break; | 620 | break; |
628 | default: | 621 | default: |
629 | return 0; | 622 | return false; |
630 | } | 623 | } |
631 | 624 | ||
632 | if (!pskb_may_pull(skb, header_len + sizeof(*udphdr))) | 625 | if (!pskb_may_pull(skb, *header_len + sizeof(*udphdr))) |
633 | return 0; | 626 | return false; |
634 | udphdr = (struct udphdr *)(skb->data + header_len); | 627 | udphdr = (struct udphdr *)(skb->data + *header_len); |
635 | header_len += sizeof(*udphdr); | 628 | *header_len += sizeof(*udphdr); |
636 | 629 | ||
637 | /* check for bootp port */ | 630 | /* check for bootp port */ |
638 | if ((ntohs(ethhdr->h_proto) == ETH_P_IP) && | 631 | if ((ntohs(ethhdr->h_proto) == ETH_P_IP) && |
639 | (ntohs(udphdr->dest) != 67)) | 632 | (ntohs(udphdr->dest) != 67)) |
640 | return 0; | 633 | return false; |
641 | 634 | ||
642 | if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) && | 635 | if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) && |
643 | (ntohs(udphdr->dest) != 547)) | 636 | (ntohs(udphdr->dest) != 547)) |
644 | return 0; | 637 | return false; |
645 | 638 | ||
646 | if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER) | 639 | return true; |
647 | return -1; | 640 | } |
648 | 641 | ||
649 | curr_gw = gw_get_selected_gw_node(bat_priv); | 642 | bool gw_out_of_range(struct bat_priv *bat_priv, |
650 | if (!curr_gw) | 643 | struct sk_buff *skb, struct ethhdr *ethhdr) |
651 | return 0; | 644 | { |
652 | 645 | struct neigh_node *neigh_curr = NULL, *neigh_old = NULL; | |
653 | /* If old_gw != NULL then this packet is unicast. | 646 | struct orig_node *orig_dst_node = NULL; |
654 | * So, at this point we have to check the message type: if it is a | 647 | struct gw_node *curr_gw = NULL; |
655 | * DHCPREQUEST we have to decide whether to drop it or not */ | 648 | bool ret, out_of_range = false; |
656 | if (old_gw && curr_gw->orig_node != old_gw) { | 649 | unsigned int header_len = 0; |
657 | if (is_type_dhcprequest(skb, header_len)) { | 650 | uint8_t curr_tq_avg; |
658 | /* If the dhcp packet has been sent to a different gw, | 651 | |
659 | * we have to evaluate whether the old gw is still | 652 | ret = gw_is_dhcp_target(skb, &header_len); |
660 | * reliable enough */ | 653 | if (!ret) |
661 | neigh_curr = find_router(bat_priv, curr_gw->orig_node, | 654 | goto out; |
662 | NULL); | 655 | |
663 | neigh_old = find_router(bat_priv, old_gw, NULL); | 656 | orig_dst_node = transtable_search(bat_priv, ethhdr->h_source, |
664 | if (!neigh_curr || !neigh_old) | 657 | ethhdr->h_dest); |
665 | goto free_neigh; | 658 | if (!orig_dst_node) |
666 | if (neigh_curr->tq_avg - neigh_old->tq_avg < | 659 | goto out; |
667 | GW_THRESHOLD) | 660 | |
668 | ret = -1; | 661 | if (!orig_dst_node->gw_flags) |
669 | } | 662 | goto out; |
663 | |||
664 | ret = is_type_dhcprequest(skb, header_len); | ||
665 | if (!ret) | ||
666 | goto out; | ||
667 | |||
668 | switch (atomic_read(&bat_priv->gw_mode)) { | ||
669 | case GW_MODE_SERVER: | ||
670 | /* If we are a GW then we are our best GW. We can artificially | ||
671 | * set the tq towards ourself as the maximum value */ | ||
672 | curr_tq_avg = TQ_MAX_VALUE; | ||
673 | break; | ||
674 | case GW_MODE_CLIENT: | ||
675 | curr_gw = gw_get_selected_gw_node(bat_priv); | ||
676 | if (!curr_gw) | ||
677 | goto out; | ||
678 | |||
679 | /* packet is going to our gateway */ | ||
680 | if (curr_gw->orig_node == orig_dst_node) | ||
681 | goto out; | ||
682 | |||
683 | /* If the dhcp packet has been sent to a different gw, | ||
684 | * we have to evaluate whether the old gw is still | ||
685 | * reliable enough */ | ||
686 | neigh_curr = find_router(bat_priv, curr_gw->orig_node, NULL); | ||
687 | if (!neigh_curr) | ||
688 | goto out; | ||
689 | |||
690 | curr_tq_avg = neigh_curr->tq_avg; | ||
691 | break; | ||
692 | case GW_MODE_OFF: | ||
693 | default: | ||
694 | goto out; | ||
670 | } | 695 | } |
671 | free_neigh: | 696 | |
697 | neigh_old = find_router(bat_priv, orig_dst_node, NULL); | ||
698 | if (!!neigh_old) | ||
699 | goto out; | ||
700 | |||
701 | if (curr_tq_avg - neigh_old->tq_avg > GW_THRESHOLD) | ||
702 | out_of_range = true; | ||
703 | |||
704 | out: | ||
705 | if (orig_dst_node) | ||
706 | orig_node_free_ref(orig_dst_node); | ||
707 | if (curr_gw) | ||
708 | gw_node_free_ref(curr_gw); | ||
672 | if (neigh_old) | 709 | if (neigh_old) |
673 | neigh_node_free_ref(neigh_old); | 710 | neigh_node_free_ref(neigh_old); |
674 | if (neigh_curr) | 711 | if (neigh_curr) |
675 | neigh_node_free_ref(neigh_curr); | 712 | neigh_node_free_ref(neigh_curr); |
676 | if (curr_gw) | 713 | return out_of_range; |
677 | gw_node_free_ref(curr_gw); | ||
678 | return ret; | ||
679 | } | 714 | } |
diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h index b9b983c07feb..e1edba08eb1d 100644 --- a/net/batman-adv/gateway_client.h +++ b/net/batman-adv/gateway_client.h | |||
@@ -31,7 +31,8 @@ void gw_node_update(struct bat_priv *bat_priv, | |||
31 | void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node); | 31 | void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node); |
32 | void gw_node_purge(struct bat_priv *bat_priv); | 32 | void gw_node_purge(struct bat_priv *bat_priv); |
33 | int gw_client_seq_print_text(struct seq_file *seq, void *offset); | 33 | int gw_client_seq_print_text(struct seq_file *seq, void *offset); |
34 | int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb, | 34 | bool gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len); |
35 | struct orig_node *old_gw); | 35 | bool gw_out_of_range(struct bat_priv *bat_priv, |
36 | struct sk_buff *skb, struct ethhdr *ethhdr); | ||
36 | 37 | ||
37 | #endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */ | 38 | #endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */ |
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c index 18661af0bc3b..c4ac7b0a2a63 100644 --- a/net/batman-adv/gateway_common.c +++ b/net/batman-adv/gateway_common.c | |||
@@ -97,7 +97,7 @@ static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff, | |||
97 | *tmp_ptr = '\0'; | 97 | *tmp_ptr = '\0'; |
98 | } | 98 | } |
99 | 99 | ||
100 | ret = strict_strtol(buff, 10, &ldown); | 100 | ret = kstrtol(buff, 10, &ldown); |
101 | if (ret) { | 101 | if (ret) { |
102 | bat_err(net_dev, | 102 | bat_err(net_dev, |
103 | "Download speed of gateway mode invalid: %s\n", | 103 | "Download speed of gateway mode invalid: %s\n", |
@@ -122,7 +122,7 @@ static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff, | |||
122 | *tmp_ptr = '\0'; | 122 | *tmp_ptr = '\0'; |
123 | } | 123 | } |
124 | 124 | ||
125 | ret = strict_strtol(slash_ptr + 1, 10, &lup); | 125 | ret = kstrtol(slash_ptr + 1, 10, &lup); |
126 | if (ret) { | 126 | if (ret) { |
127 | bat_err(net_dev, | 127 | bat_err(net_dev, |
128 | "Upload speed of gateway mode invalid: " | 128 | "Upload speed of gateway mode invalid: " |
diff --git a/net/batman-adv/hash.c b/net/batman-adv/hash.c index 2a172505f513..d1da29da333b 100644 --- a/net/batman-adv/hash.c +++ b/net/batman-adv/hash.c | |||
@@ -25,7 +25,7 @@ | |||
25 | /* clears the hash */ | 25 | /* clears the hash */ |
26 | static void hash_init(struct hashtable_t *hash) | 26 | static void hash_init(struct hashtable_t *hash) |
27 | { | 27 | { |
28 | int i; | 28 | uint32_t i; |
29 | 29 | ||
30 | for (i = 0 ; i < hash->size; i++) { | 30 | for (i = 0 ; i < hash->size; i++) { |
31 | INIT_HLIST_HEAD(&hash->table[i]); | 31 | INIT_HLIST_HEAD(&hash->table[i]); |
@@ -42,7 +42,7 @@ void hash_destroy(struct hashtable_t *hash) | |||
42 | } | 42 | } |
43 | 43 | ||
44 | /* allocates and clears the hash */ | 44 | /* allocates and clears the hash */ |
45 | struct hashtable_t *hash_new(int size) | 45 | struct hashtable_t *hash_new(uint32_t size) |
46 | { | 46 | { |
47 | struct hashtable_t *hash; | 47 | struct hashtable_t *hash; |
48 | 48 | ||
diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h index d20aa71ba1e8..4768717f07f9 100644 --- a/net/batman-adv/hash.h +++ b/net/batman-adv/hash.h | |||
@@ -33,17 +33,17 @@ typedef int (*hashdata_compare_cb)(const struct hlist_node *, const void *); | |||
33 | /* the hashfunction, should return an index | 33 | /* the hashfunction, should return an index |
34 | * based on the key in the data of the first | 34 | * based on the key in the data of the first |
35 | * argument and the size the second */ | 35 | * argument and the size the second */ |
36 | typedef int (*hashdata_choose_cb)(const void *, int); | 36 | typedef uint32_t (*hashdata_choose_cb)(const void *, uint32_t); |
37 | typedef void (*hashdata_free_cb)(struct hlist_node *, void *); | 37 | typedef void (*hashdata_free_cb)(struct hlist_node *, void *); |
38 | 38 | ||
39 | struct hashtable_t { | 39 | struct hashtable_t { |
40 | struct hlist_head *table; /* the hashtable itself with the buckets */ | 40 | struct hlist_head *table; /* the hashtable itself with the buckets */ |
41 | spinlock_t *list_locks; /* spinlock for each hash list entry */ | 41 | spinlock_t *list_locks; /* spinlock for each hash list entry */ |
42 | int size; /* size of hashtable */ | 42 | uint32_t size; /* size of hashtable */ |
43 | }; | 43 | }; |
44 | 44 | ||
45 | /* allocates and clears the hash */ | 45 | /* allocates and clears the hash */ |
46 | struct hashtable_t *hash_new(int size); | 46 | struct hashtable_t *hash_new(uint32_t size); |
47 | 47 | ||
48 | /* free only the hashtable and the hash itself. */ | 48 | /* free only the hashtable and the hash itself. */ |
49 | void hash_destroy(struct hashtable_t *hash); | 49 | void hash_destroy(struct hashtable_t *hash); |
@@ -57,7 +57,7 @@ static inline void hash_delete(struct hashtable_t *hash, | |||
57 | struct hlist_head *head; | 57 | struct hlist_head *head; |
58 | struct hlist_node *node, *node_tmp; | 58 | struct hlist_node *node, *node_tmp; |
59 | spinlock_t *list_lock; /* spinlock to protect write access */ | 59 | spinlock_t *list_lock; /* spinlock to protect write access */ |
60 | int i; | 60 | uint32_t i; |
61 | 61 | ||
62 | for (i = 0; i < hash->size; i++) { | 62 | for (i = 0; i < hash->size; i++) { |
63 | head = &hash->table[i]; | 63 | head = &hash->table[i]; |
@@ -93,7 +93,8 @@ static inline int hash_add(struct hashtable_t *hash, | |||
93 | hashdata_choose_cb choose, | 93 | hashdata_choose_cb choose, |
94 | const void *data, struct hlist_node *data_node) | 94 | const void *data, struct hlist_node *data_node) |
95 | { | 95 | { |
96 | int index, ret = -1; | 96 | uint32_t index; |
97 | int ret = -1; | ||
97 | struct hlist_head *head; | 98 | struct hlist_head *head; |
98 | struct hlist_node *node; | 99 | struct hlist_node *node; |
99 | spinlock_t *list_lock; /* spinlock to protect write access */ | 100 | spinlock_t *list_lock; /* spinlock to protect write access */ |
@@ -137,7 +138,7 @@ static inline void *hash_remove(struct hashtable_t *hash, | |||
137 | hashdata_compare_cb compare, | 138 | hashdata_compare_cb compare, |
138 | hashdata_choose_cb choose, void *data) | 139 | hashdata_choose_cb choose, void *data) |
139 | { | 140 | { |
140 | size_t index; | 141 | uint32_t index; |
141 | struct hlist_node *node; | 142 | struct hlist_node *node; |
142 | struct hlist_head *head; | 143 | struct hlist_head *head; |
143 | void *data_save = NULL; | 144 | void *data_save = NULL; |
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index 964ad4d8ba33..86354e06eb48 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h | |||
@@ -28,7 +28,7 @@ | |||
28 | #define DRIVER_DEVICE "batman-adv" | 28 | #define DRIVER_DEVICE "batman-adv" |
29 | 29 | ||
30 | #ifndef SOURCE_VERSION | 30 | #ifndef SOURCE_VERSION |
31 | #define SOURCE_VERSION "2011.4.0" | 31 | #define SOURCE_VERSION "2012.0.0" |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | /* B.A.T.M.A.N. parameters */ | 34 | /* B.A.T.M.A.N. parameters */ |
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 0e5b77255d99..0bc2045a2f2e 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -164,7 +164,7 @@ void originator_free(struct bat_priv *bat_priv) | |||
164 | struct hlist_head *head; | 164 | struct hlist_head *head; |
165 | spinlock_t *list_lock; /* spinlock to protect write access */ | 165 | spinlock_t *list_lock; /* spinlock to protect write access */ |
166 | struct orig_node *orig_node; | 166 | struct orig_node *orig_node; |
167 | int i; | 167 | uint32_t i; |
168 | 168 | ||
169 | if (!hash) | 169 | if (!hash) |
170 | return; | 170 | return; |
@@ -350,7 +350,7 @@ static void _purge_orig(struct bat_priv *bat_priv) | |||
350 | struct hlist_head *head; | 350 | struct hlist_head *head; |
351 | spinlock_t *list_lock; /* spinlock to protect write access */ | 351 | spinlock_t *list_lock; /* spinlock to protect write access */ |
352 | struct orig_node *orig_node; | 352 | struct orig_node *orig_node; |
353 | int i; | 353 | uint32_t i; |
354 | 354 | ||
355 | if (!hash) | 355 | if (!hash) |
356 | return; | 356 | return; |
@@ -413,7 +413,8 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) | |||
413 | int batman_count = 0; | 413 | int batman_count = 0; |
414 | int last_seen_secs; | 414 | int last_seen_secs; |
415 | int last_seen_msecs; | 415 | int last_seen_msecs; |
416 | int i, ret = 0; | 416 | uint32_t i; |
417 | int ret = 0; | ||
417 | 418 | ||
418 | primary_if = primary_if_get_selected(bat_priv); | 419 | primary_if = primary_if_get_selected(bat_priv); |
419 | 420 | ||
@@ -519,7 +520,8 @@ int orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num) | |||
519 | struct hlist_node *node; | 520 | struct hlist_node *node; |
520 | struct hlist_head *head; | 521 | struct hlist_head *head; |
521 | struct orig_node *orig_node; | 522 | struct orig_node *orig_node; |
522 | int i, ret; | 523 | uint32_t i; |
524 | int ret; | ||
523 | 525 | ||
524 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on | 526 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on |
525 | * if_num */ | 527 | * if_num */ |
@@ -601,7 +603,8 @@ int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num) | |||
601 | struct hlist_head *head; | 603 | struct hlist_head *head; |
602 | struct hard_iface *hard_iface_tmp; | 604 | struct hard_iface *hard_iface_tmp; |
603 | struct orig_node *orig_node; | 605 | struct orig_node *orig_node; |
604 | int i, ret; | 606 | uint32_t i; |
607 | int ret; | ||
605 | 608 | ||
606 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on | 609 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on |
607 | * if_num */ | 610 | * if_num */ |
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h index cfc1f60a96a1..67765ffef731 100644 --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h | |||
@@ -42,7 +42,7 @@ int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num); | |||
42 | 42 | ||
43 | /* hashfunction to choose an entry in a hash table of given size */ | 43 | /* hashfunction to choose an entry in a hash table of given size */ |
44 | /* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ | 44 | /* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ |
45 | static inline int choose_orig(const void *data, int32_t size) | 45 | static inline uint32_t choose_orig(const void *data, uint32_t size) |
46 | { | 46 | { |
47 | const unsigned char *key = data; | 47 | const unsigned char *key = data; |
48 | uint32_t hash = 0; | 48 | uint32_t hash = 0; |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index f961cc5eade5..ef24a7205f65 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -39,7 +39,7 @@ void slide_own_bcast_window(struct hard_iface *hard_iface) | |||
39 | struct hlist_head *head; | 39 | struct hlist_head *head; |
40 | struct orig_node *orig_node; | 40 | struct orig_node *orig_node; |
41 | unsigned long *word; | 41 | unsigned long *word; |
42 | int i; | 42 | uint32_t i; |
43 | size_t word_index; | 43 | size_t word_index; |
44 | 44 | ||
45 | for (i = 0; i < hash->size; i++) { | 45 | for (i = 0; i < hash->size; i++) { |
@@ -578,6 +578,7 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) | |||
578 | { | 578 | { |
579 | struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); | 579 | struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); |
580 | struct tt_query_packet *tt_query; | 580 | struct tt_query_packet *tt_query; |
581 | uint16_t tt_len; | ||
581 | struct ethhdr *ethhdr; | 582 | struct ethhdr *ethhdr; |
582 | 583 | ||
583 | /* drop packet if it has not necessary minimum size */ | 584 | /* drop packet if it has not necessary minimum size */ |
@@ -616,13 +617,22 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if) | |||
616 | } | 617 | } |
617 | break; | 618 | break; |
618 | case TT_RESPONSE: | 619 | case TT_RESPONSE: |
619 | /* packet needs to be linearized to access the TT changes */ | 620 | if (is_my_mac(tt_query->dst)) { |
620 | if (skb_linearize(skb) < 0) | 621 | /* packet needs to be linearized to access the TT |
621 | goto out; | 622 | * changes */ |
623 | if (skb_linearize(skb) < 0) | ||
624 | goto out; | ||
625 | |||
626 | tt_len = tt_query->tt_data * sizeof(struct tt_change); | ||
627 | |||
628 | /* Ensure we have all the claimed data */ | ||
629 | if (unlikely(skb_headlen(skb) < | ||
630 | sizeof(struct tt_query_packet) + | ||
631 | tt_len)) | ||
632 | goto out; | ||
622 | 633 | ||
623 | if (is_my_mac(tt_query->dst)) | ||
624 | handle_tt_response(bat_priv, tt_query); | 634 | handle_tt_response(bat_priv, tt_query); |
625 | else { | 635 | } else { |
626 | bat_dbg(DBG_TT, bat_priv, | 636 | bat_dbg(DBG_TT, bat_priv, |
627 | "Routing TT_RESPONSE to %pM [%c]\n", | 637 | "Routing TT_RESPONSE to %pM [%c]\n", |
628 | tt_query->dst, | 638 | tt_query->dst, |
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index f9cc95728989..45297c843092 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -563,10 +563,10 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) | |||
563 | struct bcast_packet *bcast_packet; | 563 | struct bcast_packet *bcast_packet; |
564 | struct vlan_ethhdr *vhdr; | 564 | struct vlan_ethhdr *vhdr; |
565 | struct softif_neigh *curr_softif_neigh = NULL; | 565 | struct softif_neigh *curr_softif_neigh = NULL; |
566 | struct orig_node *orig_node = NULL; | 566 | unsigned int header_len = 0; |
567 | int data_len = skb->len, ret; | 567 | int data_len = skb->len, ret; |
568 | short vid = -1; | 568 | short vid = -1; |
569 | bool do_bcast; | 569 | bool do_bcast = false; |
570 | 570 | ||
571 | if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) | 571 | if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) |
572 | goto dropped; | 572 | goto dropped; |
@@ -598,17 +598,28 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) | |||
598 | /* Register the client MAC in the transtable */ | 598 | /* Register the client MAC in the transtable */ |
599 | tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif); | 599 | tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif); |
600 | 600 | ||
601 | orig_node = transtable_search(bat_priv, ethhdr->h_source, | 601 | if (is_multicast_ether_addr(ethhdr->h_dest)) { |
602 | ethhdr->h_dest); | 602 | do_bcast = true; |
603 | do_bcast = is_multicast_ether_addr(ethhdr->h_dest); | ||
604 | if (do_bcast || (orig_node && orig_node->gw_flags)) { | ||
605 | ret = gw_is_target(bat_priv, skb, orig_node); | ||
606 | 603 | ||
607 | if (ret < 0) | 604 | switch (atomic_read(&bat_priv->gw_mode)) { |
608 | goto dropped; | 605 | case GW_MODE_SERVER: |
609 | 606 | /* gateway servers should not send dhcp | |
610 | if (ret) | 607 | * requests into the mesh */ |
611 | do_bcast = false; | 608 | ret = gw_is_dhcp_target(skb, &header_len); |
609 | if (ret) | ||
610 | goto dropped; | ||
611 | break; | ||
612 | case GW_MODE_CLIENT: | ||
613 | /* gateway clients should send dhcp requests | ||
614 | * via unicast to their gateway */ | ||
615 | ret = gw_is_dhcp_target(skb, &header_len); | ||
616 | if (ret) | ||
617 | do_bcast = false; | ||
618 | break; | ||
619 | case GW_MODE_OFF: | ||
620 | default: | ||
621 | break; | ||
622 | } | ||
612 | } | 623 | } |
613 | 624 | ||
614 | /* ethernet packet should be broadcasted */ | 625 | /* ethernet packet should be broadcasted */ |
@@ -644,6 +655,12 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) | |||
644 | 655 | ||
645 | /* unicast packet */ | 656 | /* unicast packet */ |
646 | } else { | 657 | } else { |
658 | if (atomic_read(&bat_priv->gw_mode) != GW_MODE_OFF) { | ||
659 | ret = gw_out_of_range(bat_priv, skb, ethhdr); | ||
660 | if (ret) | ||
661 | goto dropped; | ||
662 | } | ||
663 | |||
647 | ret = unicast_send_skb(skb, bat_priv); | 664 | ret = unicast_send_skb(skb, bat_priv); |
648 | if (ret != 0) | 665 | if (ret != 0) |
649 | goto dropped_freed; | 666 | goto dropped_freed; |
@@ -662,8 +679,6 @@ end: | |||
662 | softif_neigh_free_ref(curr_softif_neigh); | 679 | softif_neigh_free_ref(curr_softif_neigh); |
663 | if (primary_if) | 680 | if (primary_if) |
664 | hardif_free_ref(primary_if); | 681 | hardif_free_ref(primary_if); |
665 | if (orig_node) | ||
666 | orig_node_free_ref(orig_node); | ||
667 | return NETDEV_TX_OK; | 682 | return NETDEV_TX_OK; |
668 | } | 683 | } |
669 | 684 | ||
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index c7aafc7c5ed4..78b9528bfc2a 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -67,7 +67,7 @@ static struct tt_local_entry *tt_local_hash_find(struct bat_priv *bat_priv, | |||
67 | struct hlist_head *head; | 67 | struct hlist_head *head; |
68 | struct hlist_node *node; | 68 | struct hlist_node *node; |
69 | struct tt_local_entry *tt_local_entry, *tt_local_entry_tmp = NULL; | 69 | struct tt_local_entry *tt_local_entry, *tt_local_entry_tmp = NULL; |
70 | int index; | 70 | uint32_t index; |
71 | 71 | ||
72 | if (!hash) | 72 | if (!hash) |
73 | return NULL; | 73 | return NULL; |
@@ -99,7 +99,7 @@ static struct tt_global_entry *tt_global_hash_find(struct bat_priv *bat_priv, | |||
99 | struct hlist_node *node; | 99 | struct hlist_node *node; |
100 | struct tt_global_entry *tt_global_entry; | 100 | struct tt_global_entry *tt_global_entry; |
101 | struct tt_global_entry *tt_global_entry_tmp = NULL; | 101 | struct tt_global_entry *tt_global_entry_tmp = NULL; |
102 | int index; | 102 | uint32_t index; |
103 | 103 | ||
104 | if (!hash) | 104 | if (!hash) |
105 | return NULL; | 105 | return NULL; |
@@ -314,9 +314,8 @@ int tt_local_seq_print_text(struct seq_file *seq, void *offset) | |||
314 | struct hard_iface *primary_if; | 314 | struct hard_iface *primary_if; |
315 | struct hlist_node *node; | 315 | struct hlist_node *node; |
316 | struct hlist_head *head; | 316 | struct hlist_head *head; |
317 | size_t buf_size, pos; | 317 | uint32_t i; |
318 | char *buff; | 318 | int ret = 0; |
319 | int i, ret = 0; | ||
320 | 319 | ||
321 | primary_if = primary_if_get_selected(bat_priv); | 320 | primary_if = primary_if_get_selected(bat_priv); |
322 | if (!primary_if) { | 321 | if (!primary_if) { |
@@ -337,34 +336,13 @@ int tt_local_seq_print_text(struct seq_file *seq, void *offset) | |||
337 | "announced via TT (TTVN: %u):\n", | 336 | "announced via TT (TTVN: %u):\n", |
338 | net_dev->name, (uint8_t)atomic_read(&bat_priv->ttvn)); | 337 | net_dev->name, (uint8_t)atomic_read(&bat_priv->ttvn)); |
339 | 338 | ||
340 | buf_size = 1; | ||
341 | /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */ | ||
342 | for (i = 0; i < hash->size; i++) { | ||
343 | head = &hash->table[i]; | ||
344 | |||
345 | rcu_read_lock(); | ||
346 | __hlist_for_each_rcu(node, head) | ||
347 | buf_size += 29; | ||
348 | rcu_read_unlock(); | ||
349 | } | ||
350 | |||
351 | buff = kmalloc(buf_size, GFP_ATOMIC); | ||
352 | if (!buff) { | ||
353 | ret = -ENOMEM; | ||
354 | goto out; | ||
355 | } | ||
356 | |||
357 | buff[0] = '\0'; | ||
358 | pos = 0; | ||
359 | |||
360 | for (i = 0; i < hash->size; i++) { | 339 | for (i = 0; i < hash->size; i++) { |
361 | head = &hash->table[i]; | 340 | head = &hash->table[i]; |
362 | 341 | ||
363 | rcu_read_lock(); | 342 | rcu_read_lock(); |
364 | hlist_for_each_entry_rcu(tt_local_entry, node, | 343 | hlist_for_each_entry_rcu(tt_local_entry, node, |
365 | head, hash_entry) { | 344 | head, hash_entry) { |
366 | pos += snprintf(buff + pos, 30, " * %pM " | 345 | seq_printf(seq, " * %pM [%c%c%c%c%c]\n", |
367 | "[%c%c%c%c%c]\n", | ||
368 | tt_local_entry->addr, | 346 | tt_local_entry->addr, |
369 | (tt_local_entry->flags & | 347 | (tt_local_entry->flags & |
370 | TT_CLIENT_ROAM ? 'R' : '.'), | 348 | TT_CLIENT_ROAM ? 'R' : '.'), |
@@ -379,9 +357,6 @@ int tt_local_seq_print_text(struct seq_file *seq, void *offset) | |||
379 | } | 357 | } |
380 | rcu_read_unlock(); | 358 | rcu_read_unlock(); |
381 | } | 359 | } |
382 | |||
383 | seq_printf(seq, "%s", buff); | ||
384 | kfree(buff); | ||
385 | out: | 360 | out: |
386 | if (primary_if) | 361 | if (primary_if) |
387 | hardif_free_ref(primary_if); | 362 | hardif_free_ref(primary_if); |
@@ -427,7 +402,7 @@ static void tt_local_purge(struct bat_priv *bat_priv) | |||
427 | struct hlist_node *node, *node_tmp; | 402 | struct hlist_node *node, *node_tmp; |
428 | struct hlist_head *head; | 403 | struct hlist_head *head; |
429 | spinlock_t *list_lock; /* protects write access to the hash lists */ | 404 | spinlock_t *list_lock; /* protects write access to the hash lists */ |
430 | int i; | 405 | uint32_t i; |
431 | 406 | ||
432 | for (i = 0; i < hash->size; i++) { | 407 | for (i = 0; i < hash->size; i++) { |
433 | head = &hash->table[i]; | 408 | head = &hash->table[i]; |
@@ -465,7 +440,7 @@ static void tt_local_table_free(struct bat_priv *bat_priv) | |||
465 | struct tt_local_entry *tt_local_entry; | 440 | struct tt_local_entry *tt_local_entry; |
466 | struct hlist_node *node, *node_tmp; | 441 | struct hlist_node *node, *node_tmp; |
467 | struct hlist_head *head; | 442 | struct hlist_head *head; |
468 | int i; | 443 | uint32_t i; |
469 | 444 | ||
470 | if (!bat_priv->tt_local_hash) | 445 | if (!bat_priv->tt_local_hash) |
471 | return; | 446 | return; |
@@ -590,9 +565,8 @@ int tt_global_seq_print_text(struct seq_file *seq, void *offset) | |||
590 | struct hard_iface *primary_if; | 565 | struct hard_iface *primary_if; |
591 | struct hlist_node *node; | 566 | struct hlist_node *node; |
592 | struct hlist_head *head; | 567 | struct hlist_head *head; |
593 | size_t buf_size, pos; | 568 | uint32_t i; |
594 | char *buff; | 569 | int ret = 0; |
595 | int i, ret = 0; | ||
596 | 570 | ||
597 | primary_if = primary_if_get_selected(bat_priv); | 571 | primary_if = primary_if_get_selected(bat_priv); |
598 | if (!primary_if) { | 572 | if (!primary_if) { |
@@ -615,35 +589,13 @@ int tt_global_seq_print_text(struct seq_file *seq, void *offset) | |||
615 | seq_printf(seq, " %-13s %s %-15s %s %s\n", | 589 | seq_printf(seq, " %-13s %s %-15s %s %s\n", |
616 | "Client", "(TTVN)", "Originator", "(Curr TTVN)", "Flags"); | 590 | "Client", "(TTVN)", "Originator", "(Curr TTVN)", "Flags"); |
617 | 591 | ||
618 | buf_size = 1; | ||
619 | /* Estimate length for: " * xx:xx:xx:xx:xx:xx (ttvn) via | ||
620 | * xx:xx:xx:xx:xx:xx (cur_ttvn)\n"*/ | ||
621 | for (i = 0; i < hash->size; i++) { | ||
622 | head = &hash->table[i]; | ||
623 | |||
624 | rcu_read_lock(); | ||
625 | __hlist_for_each_rcu(node, head) | ||
626 | buf_size += 67; | ||
627 | rcu_read_unlock(); | ||
628 | } | ||
629 | |||
630 | buff = kmalloc(buf_size, GFP_ATOMIC); | ||
631 | if (!buff) { | ||
632 | ret = -ENOMEM; | ||
633 | goto out; | ||
634 | } | ||
635 | |||
636 | buff[0] = '\0'; | ||
637 | pos = 0; | ||
638 | |||
639 | for (i = 0; i < hash->size; i++) { | 592 | for (i = 0; i < hash->size; i++) { |
640 | head = &hash->table[i]; | 593 | head = &hash->table[i]; |
641 | 594 | ||
642 | rcu_read_lock(); | 595 | rcu_read_lock(); |
643 | hlist_for_each_entry_rcu(tt_global_entry, node, | 596 | hlist_for_each_entry_rcu(tt_global_entry, node, |
644 | head, hash_entry) { | 597 | head, hash_entry) { |
645 | pos += snprintf(buff + pos, 69, | 598 | seq_printf(seq, " * %pM (%3u) via %pM (%3u) " |
646 | " * %pM (%3u) via %pM (%3u) " | ||
647 | "[%c%c%c]\n", tt_global_entry->addr, | 599 | "[%c%c%c]\n", tt_global_entry->addr, |
648 | tt_global_entry->ttvn, | 600 | tt_global_entry->ttvn, |
649 | tt_global_entry->orig_node->orig, | 601 | tt_global_entry->orig_node->orig, |
@@ -659,9 +611,6 @@ int tt_global_seq_print_text(struct seq_file *seq, void *offset) | |||
659 | } | 611 | } |
660 | rcu_read_unlock(); | 612 | rcu_read_unlock(); |
661 | } | 613 | } |
662 | |||
663 | seq_printf(seq, "%s", buff); | ||
664 | kfree(buff); | ||
665 | out: | 614 | out: |
666 | if (primary_if) | 615 | if (primary_if) |
667 | hardif_free_ref(primary_if); | 616 | hardif_free_ref(primary_if); |
@@ -716,7 +665,7 @@ void tt_global_del_orig(struct bat_priv *bat_priv, | |||
716 | struct orig_node *orig_node, const char *message) | 665 | struct orig_node *orig_node, const char *message) |
717 | { | 666 | { |
718 | struct tt_global_entry *tt_global_entry; | 667 | struct tt_global_entry *tt_global_entry; |
719 | int i; | 668 | uint32_t i; |
720 | struct hashtable_t *hash = bat_priv->tt_global_hash; | 669 | struct hashtable_t *hash = bat_priv->tt_global_hash; |
721 | struct hlist_node *node, *safe; | 670 | struct hlist_node *node, *safe; |
722 | struct hlist_head *head; | 671 | struct hlist_head *head; |
@@ -735,9 +684,10 @@ void tt_global_del_orig(struct bat_priv *bat_priv, | |||
735 | if (tt_global_entry->orig_node == orig_node) { | 684 | if (tt_global_entry->orig_node == orig_node) { |
736 | bat_dbg(DBG_TT, bat_priv, | 685 | bat_dbg(DBG_TT, bat_priv, |
737 | "Deleting global tt entry %pM " | 686 | "Deleting global tt entry %pM " |
738 | "(via %pM): originator time out\n", | 687 | "(via %pM): %s\n", |
739 | tt_global_entry->addr, | 688 | tt_global_entry->addr, |
740 | tt_global_entry->orig_node->orig); | 689 | tt_global_entry->orig_node->orig, |
690 | message); | ||
741 | hlist_del_rcu(node); | 691 | hlist_del_rcu(node); |
742 | tt_global_entry_free_ref(tt_global_entry); | 692 | tt_global_entry_free_ref(tt_global_entry); |
743 | } | 693 | } |
@@ -754,7 +704,7 @@ static void tt_global_roam_purge(struct bat_priv *bat_priv) | |||
754 | struct hlist_node *node, *node_tmp; | 704 | struct hlist_node *node, *node_tmp; |
755 | struct hlist_head *head; | 705 | struct hlist_head *head; |
756 | spinlock_t *list_lock; /* protects write access to the hash lists */ | 706 | spinlock_t *list_lock; /* protects write access to the hash lists */ |
757 | int i; | 707 | uint32_t i; |
758 | 708 | ||
759 | for (i = 0; i < hash->size; i++) { | 709 | for (i = 0; i < hash->size; i++) { |
760 | head = &hash->table[i]; | 710 | head = &hash->table[i]; |
@@ -788,7 +738,7 @@ static void tt_global_table_free(struct bat_priv *bat_priv) | |||
788 | struct tt_global_entry *tt_global_entry; | 738 | struct tt_global_entry *tt_global_entry; |
789 | struct hlist_node *node, *node_tmp; | 739 | struct hlist_node *node, *node_tmp; |
790 | struct hlist_head *head; | 740 | struct hlist_head *head; |
791 | int i; | 741 | uint32_t i; |
792 | 742 | ||
793 | if (!bat_priv->tt_global_hash) | 743 | if (!bat_priv->tt_global_hash) |
794 | return; | 744 | return; |
@@ -874,7 +824,8 @@ uint16_t tt_global_crc(struct bat_priv *bat_priv, struct orig_node *orig_node) | |||
874 | struct tt_global_entry *tt_global_entry; | 824 | struct tt_global_entry *tt_global_entry; |
875 | struct hlist_node *node; | 825 | struct hlist_node *node; |
876 | struct hlist_head *head; | 826 | struct hlist_head *head; |
877 | int i, j; | 827 | uint32_t i; |
828 | int j; | ||
878 | 829 | ||
879 | for (i = 0; i < hash->size; i++) { | 830 | for (i = 0; i < hash->size; i++) { |
880 | head = &hash->table[i]; | 831 | head = &hash->table[i]; |
@@ -911,7 +862,8 @@ uint16_t tt_local_crc(struct bat_priv *bat_priv) | |||
911 | struct tt_local_entry *tt_local_entry; | 862 | struct tt_local_entry *tt_local_entry; |
912 | struct hlist_node *node; | 863 | struct hlist_node *node; |
913 | struct hlist_head *head; | 864 | struct hlist_head *head; |
914 | int i, j; | 865 | uint32_t i; |
866 | int j; | ||
915 | 867 | ||
916 | for (i = 0; i < hash->size; i++) { | 868 | for (i = 0; i < hash->size; i++) { |
917 | head = &hash->table[i]; | 869 | head = &hash->table[i]; |
@@ -1048,7 +1000,7 @@ static struct sk_buff *tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, | |||
1048 | struct sk_buff *skb = NULL; | 1000 | struct sk_buff *skb = NULL; |
1049 | uint16_t tt_tot, tt_count; | 1001 | uint16_t tt_tot, tt_count; |
1050 | ssize_t tt_query_size = sizeof(struct tt_query_packet); | 1002 | ssize_t tt_query_size = sizeof(struct tt_query_packet); |
1051 | int i; | 1003 | uint32_t i; |
1052 | 1004 | ||
1053 | if (tt_query_size + tt_len > primary_if->soft_iface->mtu) { | 1005 | if (tt_query_size + tt_len > primary_if->soft_iface->mtu) { |
1054 | tt_len = primary_if->soft_iface->mtu - tt_query_size; | 1006 | tt_len = primary_if->soft_iface->mtu - tt_query_size; |
@@ -1187,11 +1139,11 @@ static bool send_other_tt_response(struct bat_priv *bat_priv, | |||
1187 | (tt_request->flags & TT_FULL_TABLE ? 'F' : '.')); | 1139 | (tt_request->flags & TT_FULL_TABLE ? 'F' : '.')); |
1188 | 1140 | ||
1189 | /* Let's get the orig node of the REAL destination */ | 1141 | /* Let's get the orig node of the REAL destination */ |
1190 | req_dst_orig_node = get_orig_node(bat_priv, tt_request->dst); | 1142 | req_dst_orig_node = orig_hash_find(bat_priv, tt_request->dst); |
1191 | if (!req_dst_orig_node) | 1143 | if (!req_dst_orig_node) |
1192 | goto out; | 1144 | goto out; |
1193 | 1145 | ||
1194 | res_dst_orig_node = get_orig_node(bat_priv, tt_request->src); | 1146 | res_dst_orig_node = orig_hash_find(bat_priv, tt_request->src); |
1195 | if (!res_dst_orig_node) | 1147 | if (!res_dst_orig_node) |
1196 | goto out; | 1148 | goto out; |
1197 | 1149 | ||
@@ -1317,7 +1269,7 @@ static bool send_my_tt_response(struct bat_priv *bat_priv, | |||
1317 | my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); | 1269 | my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); |
1318 | req_ttvn = tt_request->ttvn; | 1270 | req_ttvn = tt_request->ttvn; |
1319 | 1271 | ||
1320 | orig_node = get_orig_node(bat_priv, tt_request->src); | 1272 | orig_node = orig_hash_find(bat_priv, tt_request->src); |
1321 | if (!orig_node) | 1273 | if (!orig_node) |
1322 | goto out; | 1274 | goto out; |
1323 | 1275 | ||
@@ -1725,7 +1677,7 @@ void tt_free(struct bat_priv *bat_priv) | |||
1725 | * entry */ | 1677 | * entry */ |
1726 | static void tt_local_reset_flags(struct bat_priv *bat_priv, uint16_t flags) | 1678 | static void tt_local_reset_flags(struct bat_priv *bat_priv, uint16_t flags) |
1727 | { | 1679 | { |
1728 | int i; | 1680 | uint32_t i; |
1729 | struct hashtable_t *hash = bat_priv->tt_local_hash; | 1681 | struct hashtable_t *hash = bat_priv->tt_local_hash; |
1730 | struct hlist_head *head; | 1682 | struct hlist_head *head; |
1731 | struct hlist_node *node; | 1683 | struct hlist_node *node; |
@@ -1758,7 +1710,7 @@ static void tt_local_purge_pending_clients(struct bat_priv *bat_priv) | |||
1758 | struct hlist_node *node, *node_tmp; | 1710 | struct hlist_node *node, *node_tmp; |
1759 | struct hlist_head *head; | 1711 | struct hlist_head *head; |
1760 | spinlock_t *list_lock; /* protects write access to the hash lists */ | 1712 | spinlock_t *list_lock; /* protects write access to the hash lists */ |
1761 | int i; | 1713 | uint32_t i; |
1762 | 1714 | ||
1763 | if (!hash) | 1715 | if (!hash) |
1764 | return; | 1716 | return; |
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index f81a6b668b0c..7445413253ca 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c | |||
@@ -66,7 +66,7 @@ static int vis_info_cmp(const struct hlist_node *node, const void *data2) | |||
66 | 66 | ||
67 | /* hash function to choose an entry in a hash table of given size */ | 67 | /* hash function to choose an entry in a hash table of given size */ |
68 | /* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ | 68 | /* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ |
69 | static int vis_info_choose(const void *data, int size) | 69 | static uint32_t vis_info_choose(const void *data, uint32_t size) |
70 | { | 70 | { |
71 | const struct vis_info *vis_info = data; | 71 | const struct vis_info *vis_info = data; |
72 | const struct vis_packet *packet; | 72 | const struct vis_packet *packet; |
@@ -96,7 +96,7 @@ static struct vis_info *vis_hash_find(struct bat_priv *bat_priv, | |||
96 | struct hlist_head *head; | 96 | struct hlist_head *head; |
97 | struct hlist_node *node; | 97 | struct hlist_node *node; |
98 | struct vis_info *vis_info, *vis_info_tmp = NULL; | 98 | struct vis_info *vis_info, *vis_info_tmp = NULL; |
99 | int index; | 99 | uint32_t index; |
100 | 100 | ||
101 | if (!hash) | 101 | if (!hash) |
102 | return NULL; | 102 | return NULL; |
@@ -202,7 +202,8 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) | |||
202 | HLIST_HEAD(vis_if_list); | 202 | HLIST_HEAD(vis_if_list); |
203 | struct if_list_entry *entry; | 203 | struct if_list_entry *entry; |
204 | struct hlist_node *pos, *n; | 204 | struct hlist_node *pos, *n; |
205 | int i, j, ret = 0; | 205 | uint32_t i; |
206 | int j, ret = 0; | ||
206 | int vis_server = atomic_read(&bat_priv->vis_mode); | 207 | int vis_server = atomic_read(&bat_priv->vis_mode); |
207 | size_t buff_pos, buf_size; | 208 | size_t buff_pos, buf_size; |
208 | char *buff; | 209 | char *buff; |
@@ -556,7 +557,8 @@ static int find_best_vis_server(struct bat_priv *bat_priv, | |||
556 | struct hlist_head *head; | 557 | struct hlist_head *head; |
557 | struct orig_node *orig_node; | 558 | struct orig_node *orig_node; |
558 | struct vis_packet *packet; | 559 | struct vis_packet *packet; |
559 | int best_tq = -1, i; | 560 | int best_tq = -1; |
561 | uint32_t i; | ||
560 | 562 | ||
561 | packet = (struct vis_packet *)info->skb_packet->data; | 563 | packet = (struct vis_packet *)info->skb_packet->data; |
562 | 564 | ||
@@ -608,7 +610,8 @@ static int generate_vis_packet(struct bat_priv *bat_priv) | |||
608 | struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data; | 610 | struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data; |
609 | struct vis_info_entry *entry; | 611 | struct vis_info_entry *entry; |
610 | struct tt_local_entry *tt_local_entry; | 612 | struct tt_local_entry *tt_local_entry; |
611 | int best_tq = -1, i; | 613 | int best_tq = -1; |
614 | uint32_t i; | ||
612 | 615 | ||
613 | info->first_seen = jiffies; | 616 | info->first_seen = jiffies; |
614 | packet->vis_type = atomic_read(&bat_priv->vis_mode); | 617 | packet->vis_type = atomic_read(&bat_priv->vis_mode); |
@@ -696,7 +699,7 @@ unlock: | |||
696 | * held */ | 699 | * held */ |
697 | static void purge_vis_packets(struct bat_priv *bat_priv) | 700 | static void purge_vis_packets(struct bat_priv *bat_priv) |
698 | { | 701 | { |
699 | int i; | 702 | uint32_t i; |
700 | struct hashtable_t *hash = bat_priv->vis_hash; | 703 | struct hashtable_t *hash = bat_priv->vis_hash; |
701 | struct hlist_node *node, *node_tmp; | 704 | struct hlist_node *node, *node_tmp; |
702 | struct hlist_head *head; | 705 | struct hlist_head *head; |
@@ -733,7 +736,7 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, | |||
733 | struct sk_buff *skb; | 736 | struct sk_buff *skb; |
734 | struct hard_iface *hard_iface; | 737 | struct hard_iface *hard_iface; |
735 | uint8_t dstaddr[ETH_ALEN]; | 738 | uint8_t dstaddr[ETH_ALEN]; |
736 | int i; | 739 | uint32_t i; |
737 | 740 | ||
738 | 741 | ||
739 | packet = (struct vis_packet *)info->skb_packet->data; | 742 | packet = (struct vis_packet *)info->skb_packet->data; |
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 91bcd3a961ec..a6cd856046ab 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -65,15 +65,13 @@ static DECLARE_RWSEM(bnep_session_sem); | |||
65 | static struct bnep_session *__bnep_get_session(u8 *dst) | 65 | static struct bnep_session *__bnep_get_session(u8 *dst) |
66 | { | 66 | { |
67 | struct bnep_session *s; | 67 | struct bnep_session *s; |
68 | struct list_head *p; | ||
69 | 68 | ||
70 | BT_DBG(""); | 69 | BT_DBG(""); |
71 | 70 | ||
72 | list_for_each(p, &bnep_session_list) { | 71 | list_for_each_entry(s, &bnep_session_list, list) |
73 | s = list_entry(p, struct bnep_session, list); | ||
74 | if (!compare_ether_addr(dst, s->eh.h_source)) | 72 | if (!compare_ether_addr(dst, s->eh.h_source)) |
75 | return s; | 73 | return s; |
76 | } | 74 | |
77 | return NULL; | 75 | return NULL; |
78 | } | 76 | } |
79 | 77 | ||
@@ -667,17 +665,14 @@ static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s) | |||
667 | 665 | ||
668 | int bnep_get_connlist(struct bnep_connlist_req *req) | 666 | int bnep_get_connlist(struct bnep_connlist_req *req) |
669 | { | 667 | { |
670 | struct list_head *p; | 668 | struct bnep_session *s; |
671 | int err = 0, n = 0; | 669 | int err = 0, n = 0; |
672 | 670 | ||
673 | down_read(&bnep_session_sem); | 671 | down_read(&bnep_session_sem); |
674 | 672 | ||
675 | list_for_each(p, &bnep_session_list) { | 673 | list_for_each_entry(s, &bnep_session_list, list) { |
676 | struct bnep_session *s; | ||
677 | struct bnep_conninfo ci; | 674 | struct bnep_conninfo ci; |
678 | 675 | ||
679 | s = list_entry(p, struct bnep_session, list); | ||
680 | |||
681 | __bnep_copy_ci(&ci, s); | 676 | __bnep_copy_ci(&ci, s); |
682 | 677 | ||
683 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { | 678 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { |
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 7d00ddf9e9dc..9e8940b24bba 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c | |||
@@ -53,15 +53,13 @@ static LIST_HEAD(cmtp_session_list); | |||
53 | static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr) | 53 | static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr) |
54 | { | 54 | { |
55 | struct cmtp_session *session; | 55 | struct cmtp_session *session; |
56 | struct list_head *p; | ||
57 | 56 | ||
58 | BT_DBG(""); | 57 | BT_DBG(""); |
59 | 58 | ||
60 | list_for_each(p, &cmtp_session_list) { | 59 | list_for_each_entry(session, &cmtp_session_list, list) |
61 | session = list_entry(p, struct cmtp_session, list); | ||
62 | if (!bacmp(bdaddr, &session->bdaddr)) | 60 | if (!bacmp(bdaddr, &session->bdaddr)) |
63 | return session; | 61 | return session; |
64 | } | 62 | |
65 | return NULL; | 63 | return NULL; |
66 | } | 64 | } |
67 | 65 | ||
@@ -431,19 +429,16 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) | |||
431 | 429 | ||
432 | int cmtp_get_connlist(struct cmtp_connlist_req *req) | 430 | int cmtp_get_connlist(struct cmtp_connlist_req *req) |
433 | { | 431 | { |
434 | struct list_head *p; | 432 | struct cmtp_session *session; |
435 | int err = 0, n = 0; | 433 | int err = 0, n = 0; |
436 | 434 | ||
437 | BT_DBG(""); | 435 | BT_DBG(""); |
438 | 436 | ||
439 | down_read(&cmtp_session_sem); | 437 | down_read(&cmtp_session_sem); |
440 | 438 | ||
441 | list_for_each(p, &cmtp_session_list) { | 439 | list_for_each_entry(session, &cmtp_session_list, list) { |
442 | struct cmtp_session *session; | ||
443 | struct cmtp_conninfo ci; | 440 | struct cmtp_conninfo ci; |
444 | 441 | ||
445 | session = list_entry(p, struct cmtp_session, list); | ||
446 | |||
447 | __cmtp_copy_session(session, &ci); | 442 | __cmtp_copy_session(session, &ci); |
448 | 443 | ||
449 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { | 444 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index e0af7237cd92..de0b93e45980 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -374,6 +374,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
374 | 374 | ||
375 | skb_queue_head_init(&conn->data_q); | 375 | skb_queue_head_init(&conn->data_q); |
376 | 376 | ||
377 | hci_chan_hash_init(conn); | ||
378 | |||
377 | setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); | 379 | setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); |
378 | setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); | 380 | setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); |
379 | setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept, | 381 | setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept, |
@@ -432,6 +434,8 @@ int hci_conn_del(struct hci_conn *conn) | |||
432 | 434 | ||
433 | tasklet_disable(&hdev->tx_task); | 435 | tasklet_disable(&hdev->tx_task); |
434 | 436 | ||
437 | hci_chan_hash_flush(conn); | ||
438 | |||
435 | hci_conn_hash_del(hdev, conn); | 439 | hci_conn_hash_del(hdev, conn); |
436 | if (hdev->notify) | 440 | if (hdev->notify) |
437 | hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); | 441 | hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); |
@@ -453,16 +457,13 @@ int hci_conn_del(struct hci_conn *conn) | |||
453 | struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) | 457 | struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) |
454 | { | 458 | { |
455 | int use_src = bacmp(src, BDADDR_ANY); | 459 | int use_src = bacmp(src, BDADDR_ANY); |
456 | struct hci_dev *hdev = NULL; | 460 | struct hci_dev *hdev = NULL, *d; |
457 | struct list_head *p; | ||
458 | 461 | ||
459 | BT_DBG("%s -> %s", batostr(src), batostr(dst)); | 462 | BT_DBG("%s -> %s", batostr(src), batostr(dst)); |
460 | 463 | ||
461 | read_lock_bh(&hci_dev_list_lock); | 464 | read_lock_bh(&hci_dev_list_lock); |
462 | 465 | ||
463 | list_for_each(p, &hci_dev_list) { | 466 | list_for_each_entry(d, &hci_dev_list, list) { |
464 | struct hci_dev *d = list_entry(p, struct hci_dev, list); | ||
465 | |||
466 | if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags)) | 467 | if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags)) |
467 | continue; | 468 | continue; |
468 | 469 | ||
@@ -819,7 +820,7 @@ void hci_conn_hash_flush(struct hci_dev *hdev) | |||
819 | 820 | ||
820 | c->state = BT_CLOSED; | 821 | c->state = BT_CLOSED; |
821 | 822 | ||
822 | hci_proto_disconn_cfm(c, 0x16); | 823 | hci_proto_disconn_cfm(c, HCI_ERROR_LOCAL_HOST_TERM); |
823 | hci_conn_del(c); | 824 | hci_conn_del(c); |
824 | } | 825 | } |
825 | } | 826 | } |
@@ -855,10 +856,10 @@ EXPORT_SYMBOL(hci_conn_put_device); | |||
855 | 856 | ||
856 | int hci_get_conn_list(void __user *arg) | 857 | int hci_get_conn_list(void __user *arg) |
857 | { | 858 | { |
859 | register struct hci_conn *c; | ||
858 | struct hci_conn_list_req req, *cl; | 860 | struct hci_conn_list_req req, *cl; |
859 | struct hci_conn_info *ci; | 861 | struct hci_conn_info *ci; |
860 | struct hci_dev *hdev; | 862 | struct hci_dev *hdev; |
861 | struct list_head *p; | ||
862 | int n = 0, size, err; | 863 | int n = 0, size, err; |
863 | 864 | ||
864 | if (copy_from_user(&req, arg, sizeof(req))) | 865 | if (copy_from_user(&req, arg, sizeof(req))) |
@@ -882,10 +883,7 @@ int hci_get_conn_list(void __user *arg) | |||
882 | ci = cl->conn_info; | 883 | ci = cl->conn_info; |
883 | 884 | ||
884 | hci_dev_lock_bh(hdev); | 885 | hci_dev_lock_bh(hdev); |
885 | list_for_each(p, &hdev->conn_hash.list) { | 886 | list_for_each_entry(c, &hdev->conn_hash.list, list) { |
886 | register struct hci_conn *c; | ||
887 | c = list_entry(p, struct hci_conn, list); | ||
888 | |||
889 | bacpy(&(ci + n)->bdaddr, &c->dst); | 887 | bacpy(&(ci + n)->bdaddr, &c->dst); |
890 | (ci + n)->handle = c->handle; | 888 | (ci + n)->handle = c->handle; |
891 | (ci + n)->type = c->type; | 889 | (ci + n)->type = c->type; |
@@ -956,3 +954,52 @@ int hci_get_auth_info(struct hci_dev *hdev, void __user *arg) | |||
956 | 954 | ||
957 | return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0; | 955 | return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0; |
958 | } | 956 | } |
957 | |||
958 | struct hci_chan *hci_chan_create(struct hci_conn *conn) | ||
959 | { | ||
960 | struct hci_dev *hdev = conn->hdev; | ||
961 | struct hci_chan *chan; | ||
962 | |||
963 | BT_DBG("%s conn %p", hdev->name, conn); | ||
964 | |||
965 | chan = kzalloc(sizeof(struct hci_chan), GFP_ATOMIC); | ||
966 | if (!chan) | ||
967 | return NULL; | ||
968 | |||
969 | chan->conn = conn; | ||
970 | skb_queue_head_init(&chan->data_q); | ||
971 | |||
972 | tasklet_disable(&hdev->tx_task); | ||
973 | hci_chan_hash_add(conn, chan); | ||
974 | tasklet_enable(&hdev->tx_task); | ||
975 | |||
976 | return chan; | ||
977 | } | ||
978 | |||
979 | int hci_chan_del(struct hci_chan *chan) | ||
980 | { | ||
981 | struct hci_conn *conn = chan->conn; | ||
982 | struct hci_dev *hdev = conn->hdev; | ||
983 | |||
984 | BT_DBG("%s conn %p chan %p", hdev->name, conn, chan); | ||
985 | |||
986 | tasklet_disable(&hdev->tx_task); | ||
987 | hci_chan_hash_del(conn, chan); | ||
988 | tasklet_enable(&hdev->tx_task); | ||
989 | |||
990 | skb_queue_purge(&chan->data_q); | ||
991 | kfree(chan); | ||
992 | |||
993 | return 0; | ||
994 | } | ||
995 | |||
996 | void hci_chan_hash_flush(struct hci_conn *conn) | ||
997 | { | ||
998 | struct hci_chan_hash *h = &conn->chan_hash; | ||
999 | struct hci_chan *chan, *tmp; | ||
1000 | |||
1001 | BT_DBG("conn %p", conn); | ||
1002 | |||
1003 | list_for_each_entry_safe(chan, tmp, &h->list, list) | ||
1004 | hci_chan_del(chan); | ||
1005 | } | ||
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index be84ae33ae36..fb3feeb185d7 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -319,8 +319,7 @@ static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt) | |||
319 | * Device is held on return. */ | 319 | * Device is held on return. */ |
320 | struct hci_dev *hci_dev_get(int index) | 320 | struct hci_dev *hci_dev_get(int index) |
321 | { | 321 | { |
322 | struct hci_dev *hdev = NULL; | 322 | struct hci_dev *hdev = NULL, *d; |
323 | struct list_head *p; | ||
324 | 323 | ||
325 | BT_DBG("%d", index); | 324 | BT_DBG("%d", index); |
326 | 325 | ||
@@ -328,8 +327,7 @@ struct hci_dev *hci_dev_get(int index) | |||
328 | return NULL; | 327 | return NULL; |
329 | 328 | ||
330 | read_lock(&hci_dev_list_lock); | 329 | read_lock(&hci_dev_list_lock); |
331 | list_for_each(p, &hci_dev_list) { | 330 | list_for_each_entry(d, &hci_dev_list, list) { |
332 | struct hci_dev *d = list_entry(p, struct hci_dev, list); | ||
333 | if (d->id == index) { | 331 | if (d->id == index) { |
334 | hdev = hci_dev_hold(d); | 332 | hdev = hci_dev_hold(d); |
335 | break; | 333 | break; |
@@ -551,8 +549,11 @@ int hci_dev_open(__u16 dev) | |||
551 | hci_dev_hold(hdev); | 549 | hci_dev_hold(hdev); |
552 | set_bit(HCI_UP, &hdev->flags); | 550 | set_bit(HCI_UP, &hdev->flags); |
553 | hci_notify(hdev, HCI_DEV_UP); | 551 | hci_notify(hdev, HCI_DEV_UP); |
554 | if (!test_bit(HCI_SETUP, &hdev->flags)) | 552 | if (!test_bit(HCI_SETUP, &hdev->flags)) { |
555 | mgmt_powered(hdev->id, 1); | 553 | hci_dev_lock_bh(hdev); |
554 | mgmt_powered(hdev, 1); | ||
555 | hci_dev_unlock_bh(hdev); | ||
556 | } | ||
556 | } else { | 557 | } else { |
557 | /* Init failed, cleanup */ | 558 | /* Init failed, cleanup */ |
558 | tasklet_kill(&hdev->rx_task); | 559 | tasklet_kill(&hdev->rx_task); |
@@ -597,6 +598,14 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
597 | tasklet_kill(&hdev->rx_task); | 598 | tasklet_kill(&hdev->rx_task); |
598 | tasklet_kill(&hdev->tx_task); | 599 | tasklet_kill(&hdev->tx_task); |
599 | 600 | ||
601 | if (hdev->discov_timeout > 0) { | ||
602 | cancel_delayed_work(&hdev->discov_off); | ||
603 | hdev->discov_timeout = 0; | ||
604 | } | ||
605 | |||
606 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) | ||
607 | cancel_delayed_work(&hdev->power_off); | ||
608 | |||
600 | hci_dev_lock_bh(hdev); | 609 | hci_dev_lock_bh(hdev); |
601 | inquiry_cache_flush(hdev); | 610 | inquiry_cache_flush(hdev); |
602 | hci_conn_hash_flush(hdev); | 611 | hci_conn_hash_flush(hdev); |
@@ -636,7 +645,9 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
636 | * and no tasks are scheduled. */ | 645 | * and no tasks are scheduled. */ |
637 | hdev->close(hdev); | 646 | hdev->close(hdev); |
638 | 647 | ||
639 | mgmt_powered(hdev->id, 0); | 648 | hci_dev_lock_bh(hdev); |
649 | mgmt_powered(hdev, 0); | ||
650 | hci_dev_unlock_bh(hdev); | ||
640 | 651 | ||
641 | /* Clear flags */ | 652 | /* Clear flags */ |
642 | hdev->flags = 0; | 653 | hdev->flags = 0; |
@@ -794,9 +805,9 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) | |||
794 | 805 | ||
795 | int hci_get_dev_list(void __user *arg) | 806 | int hci_get_dev_list(void __user *arg) |
796 | { | 807 | { |
808 | struct hci_dev *hdev; | ||
797 | struct hci_dev_list_req *dl; | 809 | struct hci_dev_list_req *dl; |
798 | struct hci_dev_req *dr; | 810 | struct hci_dev_req *dr; |
799 | struct list_head *p; | ||
800 | int n = 0, size, err; | 811 | int n = 0, size, err; |
801 | __u16 dev_num; | 812 | __u16 dev_num; |
802 | 813 | ||
@@ -815,12 +826,9 @@ int hci_get_dev_list(void __user *arg) | |||
815 | dr = dl->dev_req; | 826 | dr = dl->dev_req; |
816 | 827 | ||
817 | read_lock_bh(&hci_dev_list_lock); | 828 | read_lock_bh(&hci_dev_list_lock); |
818 | list_for_each(p, &hci_dev_list) { | 829 | list_for_each_entry(hdev, &hci_dev_list, list) { |
819 | struct hci_dev *hdev; | 830 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) |
820 | 831 | cancel_delayed_work(&hdev->power_off); | |
821 | hdev = list_entry(p, struct hci_dev, list); | ||
822 | |||
823 | hci_del_off_timer(hdev); | ||
824 | 832 | ||
825 | if (!test_bit(HCI_MGMT, &hdev->flags)) | 833 | if (!test_bit(HCI_MGMT, &hdev->flags)) |
826 | set_bit(HCI_PAIRABLE, &hdev->flags); | 834 | set_bit(HCI_PAIRABLE, &hdev->flags); |
@@ -855,7 +863,8 @@ int hci_get_dev_info(void __user *arg) | |||
855 | if (!hdev) | 863 | if (!hdev) |
856 | return -ENODEV; | 864 | return -ENODEV; |
857 | 865 | ||
858 | hci_del_off_timer(hdev); | 866 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) |
867 | cancel_delayed_work_sync(&hdev->power_off); | ||
859 | 868 | ||
860 | if (!test_bit(HCI_MGMT, &hdev->flags)) | 869 | if (!test_bit(HCI_MGMT, &hdev->flags)) |
861 | set_bit(HCI_PAIRABLE, &hdev->flags); | 870 | set_bit(HCI_PAIRABLE, &hdev->flags); |
@@ -912,6 +921,7 @@ struct hci_dev *hci_alloc_dev(void) | |||
912 | if (!hdev) | 921 | if (!hdev) |
913 | return NULL; | 922 | return NULL; |
914 | 923 | ||
924 | hci_init_sysfs(hdev); | ||
915 | skb_queue_head_init(&hdev->driver_init); | 925 | skb_queue_head_init(&hdev->driver_init); |
916 | 926 | ||
917 | return hdev; | 927 | return hdev; |
@@ -938,39 +948,41 @@ static void hci_power_on(struct work_struct *work) | |||
938 | return; | 948 | return; |
939 | 949 | ||
940 | if (test_bit(HCI_AUTO_OFF, &hdev->flags)) | 950 | if (test_bit(HCI_AUTO_OFF, &hdev->flags)) |
941 | mod_timer(&hdev->off_timer, | 951 | queue_delayed_work(hdev->workqueue, &hdev->power_off, |
942 | jiffies + msecs_to_jiffies(AUTO_OFF_TIMEOUT)); | 952 | msecs_to_jiffies(AUTO_OFF_TIMEOUT)); |
943 | 953 | ||
944 | if (test_and_clear_bit(HCI_SETUP, &hdev->flags)) | 954 | if (test_and_clear_bit(HCI_SETUP, &hdev->flags)) |
945 | mgmt_index_added(hdev->id); | 955 | mgmt_index_added(hdev); |
946 | } | 956 | } |
947 | 957 | ||
948 | static void hci_power_off(struct work_struct *work) | 958 | static void hci_power_off(struct work_struct *work) |
949 | { | 959 | { |
950 | struct hci_dev *hdev = container_of(work, struct hci_dev, power_off); | 960 | struct hci_dev *hdev = container_of(work, struct hci_dev, |
961 | power_off.work); | ||
951 | 962 | ||
952 | BT_DBG("%s", hdev->name); | 963 | BT_DBG("%s", hdev->name); |
953 | 964 | ||
965 | clear_bit(HCI_AUTO_OFF, &hdev->flags); | ||
966 | |||
954 | hci_dev_close(hdev->id); | 967 | hci_dev_close(hdev->id); |
955 | } | 968 | } |
956 | 969 | ||
957 | static void hci_auto_off(unsigned long data) | 970 | static void hci_discov_off(struct work_struct *work) |
958 | { | 971 | { |
959 | struct hci_dev *hdev = (struct hci_dev *) data; | 972 | struct hci_dev *hdev; |
973 | u8 scan = SCAN_PAGE; | ||
974 | |||
975 | hdev = container_of(work, struct hci_dev, discov_off.work); | ||
960 | 976 | ||
961 | BT_DBG("%s", hdev->name); | 977 | BT_DBG("%s", hdev->name); |
962 | 978 | ||
963 | clear_bit(HCI_AUTO_OFF, &hdev->flags); | 979 | hci_dev_lock_bh(hdev); |
964 | 980 | ||
965 | queue_work(hdev->workqueue, &hdev->power_off); | 981 | hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); |
966 | } | ||
967 | 982 | ||
968 | void hci_del_off_timer(struct hci_dev *hdev) | 983 | hdev->discov_timeout = 0; |
969 | { | ||
970 | BT_DBG("%s", hdev->name); | ||
971 | 984 | ||
972 | clear_bit(HCI_AUTO_OFF, &hdev->flags); | 985 | hci_dev_unlock_bh(hdev); |
973 | del_timer(&hdev->off_timer); | ||
974 | } | 986 | } |
975 | 987 | ||
976 | int hci_uuids_clear(struct hci_dev *hdev) | 988 | int hci_uuids_clear(struct hci_dev *hdev) |
@@ -1007,16 +1019,11 @@ int hci_link_keys_clear(struct hci_dev *hdev) | |||
1007 | 1019 | ||
1008 | struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) | 1020 | struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) |
1009 | { | 1021 | { |
1010 | struct list_head *p; | 1022 | struct link_key *k; |
1011 | |||
1012 | list_for_each(p, &hdev->link_keys) { | ||
1013 | struct link_key *k; | ||
1014 | |||
1015 | k = list_entry(p, struct link_key, list); | ||
1016 | 1023 | ||
1024 | list_for_each_entry(k, &hdev->link_keys, list) | ||
1017 | if (bacmp(bdaddr, &k->bdaddr) == 0) | 1025 | if (bacmp(bdaddr, &k->bdaddr) == 0) |
1018 | return k; | 1026 | return k; |
1019 | } | ||
1020 | 1027 | ||
1021 | return NULL; | 1028 | return NULL; |
1022 | } | 1029 | } |
@@ -1138,7 +1145,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, | |||
1138 | 1145 | ||
1139 | persistent = hci_persistent_key(hdev, conn, type, old_key_type); | 1146 | persistent = hci_persistent_key(hdev, conn, type, old_key_type); |
1140 | 1147 | ||
1141 | mgmt_new_key(hdev->id, key, persistent); | 1148 | mgmt_new_link_key(hdev, key, persistent); |
1142 | 1149 | ||
1143 | if (!persistent) { | 1150 | if (!persistent) { |
1144 | list_del(&key->list); | 1151 | list_del(&key->list); |
@@ -1181,7 +1188,7 @@ int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, | |||
1181 | memcpy(id->rand, rand, sizeof(id->rand)); | 1188 | memcpy(id->rand, rand, sizeof(id->rand)); |
1182 | 1189 | ||
1183 | if (new_key) | 1190 | if (new_key) |
1184 | mgmt_new_key(hdev->id, key, old_key_type); | 1191 | mgmt_new_link_key(hdev, key, old_key_type); |
1185 | 1192 | ||
1186 | return 0; | 1193 | return 0; |
1187 | } | 1194 | } |
@@ -1279,16 +1286,11 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, | |||
1279 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, | 1286 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, |
1280 | bdaddr_t *bdaddr) | 1287 | bdaddr_t *bdaddr) |
1281 | { | 1288 | { |
1282 | struct list_head *p; | 1289 | struct bdaddr_list *b; |
1283 | |||
1284 | list_for_each(p, &hdev->blacklist) { | ||
1285 | struct bdaddr_list *b; | ||
1286 | |||
1287 | b = list_entry(p, struct bdaddr_list, list); | ||
1288 | 1290 | ||
1291 | list_for_each_entry(b, &hdev->blacklist, list) | ||
1289 | if (bacmp(bdaddr, &b->bdaddr) == 0) | 1292 | if (bacmp(bdaddr, &b->bdaddr) == 0) |
1290 | return b; | 1293 | return b; |
1291 | } | ||
1292 | 1294 | ||
1293 | return NULL; | 1295 | return NULL; |
1294 | } | 1296 | } |
@@ -1327,7 +1329,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1327 | 1329 | ||
1328 | list_add(&entry->list, &hdev->blacklist); | 1330 | list_add(&entry->list, &hdev->blacklist); |
1329 | 1331 | ||
1330 | return mgmt_device_blocked(hdev->id, bdaddr); | 1332 | return mgmt_device_blocked(hdev, bdaddr); |
1331 | } | 1333 | } |
1332 | 1334 | ||
1333 | int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) | 1335 | int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) |
@@ -1346,7 +1348,7 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1346 | list_del(&entry->list); | 1348 | list_del(&entry->list); |
1347 | kfree(entry); | 1349 | kfree(entry); |
1348 | 1350 | ||
1349 | return mgmt_device_unblocked(hdev->id, bdaddr); | 1351 | return mgmt_device_unblocked(hdev, bdaddr); |
1350 | } | 1352 | } |
1351 | 1353 | ||
1352 | static void hci_clear_adv_cache(unsigned long arg) | 1354 | static void hci_clear_adv_cache(unsigned long arg) |
@@ -1425,7 +1427,7 @@ int hci_add_adv_entry(struct hci_dev *hdev, | |||
1425 | int hci_register_dev(struct hci_dev *hdev) | 1427 | int hci_register_dev(struct hci_dev *hdev) |
1426 | { | 1428 | { |
1427 | struct list_head *head = &hci_dev_list, *p; | 1429 | struct list_head *head = &hci_dev_list, *p; |
1428 | int i, id = 0; | 1430 | int i, id, error; |
1429 | 1431 | ||
1430 | BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name, | 1432 | BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name, |
1431 | hdev->bus, hdev->owner); | 1433 | hdev->bus, hdev->owner); |
@@ -1433,6 +1435,11 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1433 | if (!hdev->open || !hdev->close || !hdev->destruct) | 1435 | if (!hdev->open || !hdev->close || !hdev->destruct) |
1434 | return -EINVAL; | 1436 | return -EINVAL; |
1435 | 1437 | ||
1438 | /* Do not allow HCI_AMP devices to register at index 0, | ||
1439 | * so the index can be used as the AMP controller ID. | ||
1440 | */ | ||
1441 | id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; | ||
1442 | |||
1436 | write_lock_bh(&hci_dev_list_lock); | 1443 | write_lock_bh(&hci_dev_list_lock); |
1437 | 1444 | ||
1438 | /* Find first available device id */ | 1445 | /* Find first available device id */ |
@@ -1479,6 +1486,8 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1479 | 1486 | ||
1480 | hci_conn_hash_init(hdev); | 1487 | hci_conn_hash_init(hdev); |
1481 | 1488 | ||
1489 | INIT_LIST_HEAD(&hdev->mgmt_pending); | ||
1490 | |||
1482 | INIT_LIST_HEAD(&hdev->blacklist); | 1491 | INIT_LIST_HEAD(&hdev->blacklist); |
1483 | 1492 | ||
1484 | INIT_LIST_HEAD(&hdev->uuids); | 1493 | INIT_LIST_HEAD(&hdev->uuids); |
@@ -1492,8 +1501,9 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1492 | (unsigned long) hdev); | 1501 | (unsigned long) hdev); |
1493 | 1502 | ||
1494 | INIT_WORK(&hdev->power_on, hci_power_on); | 1503 | INIT_WORK(&hdev->power_on, hci_power_on); |
1495 | INIT_WORK(&hdev->power_off, hci_power_off); | 1504 | INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); |
1496 | setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev); | 1505 | |
1506 | INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); | ||
1497 | 1507 | ||
1498 | memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); | 1508 | memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); |
1499 | 1509 | ||
@@ -1502,10 +1512,14 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1502 | write_unlock_bh(&hci_dev_list_lock); | 1512 | write_unlock_bh(&hci_dev_list_lock); |
1503 | 1513 | ||
1504 | hdev->workqueue = create_singlethread_workqueue(hdev->name); | 1514 | hdev->workqueue = create_singlethread_workqueue(hdev->name); |
1505 | if (!hdev->workqueue) | 1515 | if (!hdev->workqueue) { |
1506 | goto nomem; | 1516 | error = -ENOMEM; |
1517 | goto err; | ||
1518 | } | ||
1507 | 1519 | ||
1508 | hci_register_sysfs(hdev); | 1520 | error = hci_add_sysfs(hdev); |
1521 | if (error < 0) | ||
1522 | goto err_wqueue; | ||
1509 | 1523 | ||
1510 | hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, | 1524 | hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, |
1511 | RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); | 1525 | RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); |
@@ -1524,17 +1538,19 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1524 | 1538 | ||
1525 | return id; | 1539 | return id; |
1526 | 1540 | ||
1527 | nomem: | 1541 | err_wqueue: |
1542 | destroy_workqueue(hdev->workqueue); | ||
1543 | err: | ||
1528 | write_lock_bh(&hci_dev_list_lock); | 1544 | write_lock_bh(&hci_dev_list_lock); |
1529 | list_del(&hdev->list); | 1545 | list_del(&hdev->list); |
1530 | write_unlock_bh(&hci_dev_list_lock); | 1546 | write_unlock_bh(&hci_dev_list_lock); |
1531 | 1547 | ||
1532 | return -ENOMEM; | 1548 | return error; |
1533 | } | 1549 | } |
1534 | EXPORT_SYMBOL(hci_register_dev); | 1550 | EXPORT_SYMBOL(hci_register_dev); |
1535 | 1551 | ||
1536 | /* Unregister HCI device */ | 1552 | /* Unregister HCI device */ |
1537 | int hci_unregister_dev(struct hci_dev *hdev) | 1553 | void hci_unregister_dev(struct hci_dev *hdev) |
1538 | { | 1554 | { |
1539 | int i; | 1555 | int i; |
1540 | 1556 | ||
@@ -1550,8 +1566,15 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
1550 | kfree_skb(hdev->reassembly[i]); | 1566 | kfree_skb(hdev->reassembly[i]); |
1551 | 1567 | ||
1552 | if (!test_bit(HCI_INIT, &hdev->flags) && | 1568 | if (!test_bit(HCI_INIT, &hdev->flags) && |
1553 | !test_bit(HCI_SETUP, &hdev->flags)) | 1569 | !test_bit(HCI_SETUP, &hdev->flags)) { |
1554 | mgmt_index_removed(hdev->id); | 1570 | hci_dev_lock_bh(hdev); |
1571 | mgmt_index_removed(hdev); | ||
1572 | hci_dev_unlock_bh(hdev); | ||
1573 | } | ||
1574 | |||
1575 | /* mgmt_index_removed should take care of emptying the | ||
1576 | * pending list */ | ||
1577 | BUG_ON(!list_empty(&hdev->mgmt_pending)); | ||
1555 | 1578 | ||
1556 | hci_notify(hdev, HCI_DEV_UNREG); | 1579 | hci_notify(hdev, HCI_DEV_UNREG); |
1557 | 1580 | ||
@@ -1560,9 +1583,8 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
1560 | rfkill_destroy(hdev->rfkill); | 1583 | rfkill_destroy(hdev->rfkill); |
1561 | } | 1584 | } |
1562 | 1585 | ||
1563 | hci_unregister_sysfs(hdev); | 1586 | hci_del_sysfs(hdev); |
1564 | 1587 | ||
1565 | hci_del_off_timer(hdev); | ||
1566 | del_timer(&hdev->adv_timer); | 1588 | del_timer(&hdev->adv_timer); |
1567 | 1589 | ||
1568 | destroy_workqueue(hdev->workqueue); | 1590 | destroy_workqueue(hdev->workqueue); |
@@ -1576,8 +1598,6 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
1576 | hci_dev_unlock_bh(hdev); | 1598 | hci_dev_unlock_bh(hdev); |
1577 | 1599 | ||
1578 | __hci_dev_put(hdev); | 1600 | __hci_dev_put(hdev); |
1579 | |||
1580 | return 0; | ||
1581 | } | 1601 | } |
1582 | EXPORT_SYMBOL(hci_unregister_dev); | 1602 | EXPORT_SYMBOL(hci_unregister_dev); |
1583 | 1603 | ||
@@ -1948,23 +1968,18 @@ static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) | |||
1948 | hdr->dlen = cpu_to_le16(len); | 1968 | hdr->dlen = cpu_to_le16(len); |
1949 | } | 1969 | } |
1950 | 1970 | ||
1951 | void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags) | 1971 | static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, |
1972 | struct sk_buff *skb, __u16 flags) | ||
1952 | { | 1973 | { |
1953 | struct hci_dev *hdev = conn->hdev; | 1974 | struct hci_dev *hdev = conn->hdev; |
1954 | struct sk_buff *list; | 1975 | struct sk_buff *list; |
1955 | 1976 | ||
1956 | BT_DBG("%s conn %p flags 0x%x", hdev->name, conn, flags); | ||
1957 | |||
1958 | skb->dev = (void *) hdev; | ||
1959 | bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; | ||
1960 | hci_add_acl_hdr(skb, conn->handle, flags); | ||
1961 | |||
1962 | list = skb_shinfo(skb)->frag_list; | 1977 | list = skb_shinfo(skb)->frag_list; |
1963 | if (!list) { | 1978 | if (!list) { |
1964 | /* Non fragmented */ | 1979 | /* Non fragmented */ |
1965 | BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); | 1980 | BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); |
1966 | 1981 | ||
1967 | skb_queue_tail(&conn->data_q, skb); | 1982 | skb_queue_tail(queue, skb); |
1968 | } else { | 1983 | } else { |
1969 | /* Fragmented */ | 1984 | /* Fragmented */ |
1970 | BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); | 1985 | BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); |
@@ -1972,9 +1987,9 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags) | |||
1972 | skb_shinfo(skb)->frag_list = NULL; | 1987 | skb_shinfo(skb)->frag_list = NULL; |
1973 | 1988 | ||
1974 | /* Queue all fragments atomically */ | 1989 | /* Queue all fragments atomically */ |
1975 | spin_lock_bh(&conn->data_q.lock); | 1990 | spin_lock_bh(&queue->lock); |
1976 | 1991 | ||
1977 | __skb_queue_tail(&conn->data_q, skb); | 1992 | __skb_queue_tail(queue, skb); |
1978 | 1993 | ||
1979 | flags &= ~ACL_START; | 1994 | flags &= ~ACL_START; |
1980 | flags |= ACL_CONT; | 1995 | flags |= ACL_CONT; |
@@ -1987,11 +2002,25 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags) | |||
1987 | 2002 | ||
1988 | BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); | 2003 | BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); |
1989 | 2004 | ||
1990 | __skb_queue_tail(&conn->data_q, skb); | 2005 | __skb_queue_tail(queue, skb); |
1991 | } while (list); | 2006 | } while (list); |
1992 | 2007 | ||
1993 | spin_unlock_bh(&conn->data_q.lock); | 2008 | spin_unlock_bh(&queue->lock); |
1994 | } | 2009 | } |
2010 | } | ||
2011 | |||
2012 | void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) | ||
2013 | { | ||
2014 | struct hci_conn *conn = chan->conn; | ||
2015 | struct hci_dev *hdev = conn->hdev; | ||
2016 | |||
2017 | BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags); | ||
2018 | |||
2019 | skb->dev = (void *) hdev; | ||
2020 | bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; | ||
2021 | hci_add_acl_hdr(skb, conn->handle, flags); | ||
2022 | |||
2023 | hci_queue_acl(conn, &chan->data_q, skb, flags); | ||
1995 | 2024 | ||
1996 | tasklet_schedule(&hdev->tx_task); | 2025 | tasklet_schedule(&hdev->tx_task); |
1997 | } | 2026 | } |
@@ -2026,16 +2055,12 @@ EXPORT_SYMBOL(hci_send_sco); | |||
2026 | static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) | 2055 | static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) |
2027 | { | 2056 | { |
2028 | struct hci_conn_hash *h = &hdev->conn_hash; | 2057 | struct hci_conn_hash *h = &hdev->conn_hash; |
2029 | struct hci_conn *conn = NULL; | 2058 | struct hci_conn *conn = NULL, *c; |
2030 | int num = 0, min = ~0; | 2059 | int num = 0, min = ~0; |
2031 | struct list_head *p; | ||
2032 | 2060 | ||
2033 | /* We don't have to lock device here. Connections are always | 2061 | /* We don't have to lock device here. Connections are always |
2034 | * added and removed with TX task disabled. */ | 2062 | * added and removed with TX task disabled. */ |
2035 | list_for_each(p, &h->list) { | 2063 | list_for_each_entry(c, &h->list, list) { |
2036 | struct hci_conn *c; | ||
2037 | c = list_entry(p, struct hci_conn, list); | ||
2038 | |||
2039 | if (c->type != type || skb_queue_empty(&c->data_q)) | 2064 | if (c->type != type || skb_queue_empty(&c->data_q)) |
2040 | continue; | 2065 | continue; |
2041 | 2066 | ||
@@ -2084,14 +2109,12 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int | |||
2084 | static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) | 2109 | static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) |
2085 | { | 2110 | { |
2086 | struct hci_conn_hash *h = &hdev->conn_hash; | 2111 | struct hci_conn_hash *h = &hdev->conn_hash; |
2087 | struct list_head *p; | 2112 | struct hci_conn *c; |
2088 | struct hci_conn *c; | ||
2089 | 2113 | ||
2090 | BT_ERR("%s link tx timeout", hdev->name); | 2114 | BT_ERR("%s link tx timeout", hdev->name); |
2091 | 2115 | ||
2092 | /* Kill stalled connections */ | 2116 | /* Kill stalled connections */ |
2093 | list_for_each(p, &h->list) { | 2117 | list_for_each_entry(c, &h->list, list) { |
2094 | c = list_entry(p, struct hci_conn, list); | ||
2095 | if (c->type == type && c->sent) { | 2118 | if (c->type == type && c->sent) { |
2096 | BT_ERR("%s killing stalled connection %s", | 2119 | BT_ERR("%s killing stalled connection %s", |
2097 | hdev->name, batostr(&c->dst)); | 2120 | hdev->name, batostr(&c->dst)); |
@@ -2100,11 +2123,137 @@ static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) | |||
2100 | } | 2123 | } |
2101 | } | 2124 | } |
2102 | 2125 | ||
2103 | static inline void hci_sched_acl(struct hci_dev *hdev) | 2126 | static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, |
2127 | int *quote) | ||
2104 | { | 2128 | { |
2129 | struct hci_conn_hash *h = &hdev->conn_hash; | ||
2130 | struct hci_chan *chan = NULL; | ||
2131 | int num = 0, min = ~0, cur_prio = 0; | ||
2105 | struct hci_conn *conn; | 2132 | struct hci_conn *conn; |
2133 | int cnt, q, conn_num = 0; | ||
2134 | |||
2135 | BT_DBG("%s", hdev->name); | ||
2136 | |||
2137 | list_for_each_entry(conn, &h->list, list) { | ||
2138 | struct hci_chan_hash *ch; | ||
2139 | struct hci_chan *tmp; | ||
2140 | |||
2141 | if (conn->type != type) | ||
2142 | continue; | ||
2143 | |||
2144 | if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) | ||
2145 | continue; | ||
2146 | |||
2147 | conn_num++; | ||
2148 | |||
2149 | ch = &conn->chan_hash; | ||
2150 | |||
2151 | list_for_each_entry(tmp, &ch->list, list) { | ||
2152 | struct sk_buff *skb; | ||
2153 | |||
2154 | if (skb_queue_empty(&tmp->data_q)) | ||
2155 | continue; | ||
2156 | |||
2157 | skb = skb_peek(&tmp->data_q); | ||
2158 | if (skb->priority < cur_prio) | ||
2159 | continue; | ||
2160 | |||
2161 | if (skb->priority > cur_prio) { | ||
2162 | num = 0; | ||
2163 | min = ~0; | ||
2164 | cur_prio = skb->priority; | ||
2165 | } | ||
2166 | |||
2167 | num++; | ||
2168 | |||
2169 | if (conn->sent < min) { | ||
2170 | min = conn->sent; | ||
2171 | chan = tmp; | ||
2172 | } | ||
2173 | } | ||
2174 | |||
2175 | if (hci_conn_num(hdev, type) == conn_num) | ||
2176 | break; | ||
2177 | } | ||
2178 | |||
2179 | if (!chan) | ||
2180 | return NULL; | ||
2181 | |||
2182 | switch (chan->conn->type) { | ||
2183 | case ACL_LINK: | ||
2184 | cnt = hdev->acl_cnt; | ||
2185 | break; | ||
2186 | case SCO_LINK: | ||
2187 | case ESCO_LINK: | ||
2188 | cnt = hdev->sco_cnt; | ||
2189 | break; | ||
2190 | case LE_LINK: | ||
2191 | cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; | ||
2192 | break; | ||
2193 | default: | ||
2194 | cnt = 0; | ||
2195 | BT_ERR("Unknown link type"); | ||
2196 | } | ||
2197 | |||
2198 | q = cnt / num; | ||
2199 | *quote = q ? q : 1; | ||
2200 | BT_DBG("chan %p quote %d", chan, *quote); | ||
2201 | return chan; | ||
2202 | } | ||
2203 | |||
2204 | static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) | ||
2205 | { | ||
2206 | struct hci_conn_hash *h = &hdev->conn_hash; | ||
2207 | struct hci_conn *conn; | ||
2208 | int num = 0; | ||
2209 | |||
2210 | BT_DBG("%s", hdev->name); | ||
2211 | |||
2212 | list_for_each_entry(conn, &h->list, list) { | ||
2213 | struct hci_chan_hash *ch; | ||
2214 | struct hci_chan *chan; | ||
2215 | |||
2216 | if (conn->type != type) | ||
2217 | continue; | ||
2218 | |||
2219 | if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) | ||
2220 | continue; | ||
2221 | |||
2222 | num++; | ||
2223 | |||
2224 | ch = &conn->chan_hash; | ||
2225 | list_for_each_entry(chan, &ch->list, list) { | ||
2226 | struct sk_buff *skb; | ||
2227 | |||
2228 | if (chan->sent) { | ||
2229 | chan->sent = 0; | ||
2230 | continue; | ||
2231 | } | ||
2232 | |||
2233 | if (skb_queue_empty(&chan->data_q)) | ||
2234 | continue; | ||
2235 | |||
2236 | skb = skb_peek(&chan->data_q); | ||
2237 | if (skb->priority >= HCI_PRIO_MAX - 1) | ||
2238 | continue; | ||
2239 | |||
2240 | skb->priority = HCI_PRIO_MAX - 1; | ||
2241 | |||
2242 | BT_DBG("chan %p skb %p promoted to %d", chan, skb, | ||
2243 | skb->priority); | ||
2244 | } | ||
2245 | |||
2246 | if (hci_conn_num(hdev, type) == num) | ||
2247 | break; | ||
2248 | } | ||
2249 | } | ||
2250 | |||
2251 | static inline void hci_sched_acl(struct hci_dev *hdev) | ||
2252 | { | ||
2253 | struct hci_chan *chan; | ||
2106 | struct sk_buff *skb; | 2254 | struct sk_buff *skb; |
2107 | int quote; | 2255 | int quote; |
2256 | unsigned int cnt; | ||
2108 | 2257 | ||
2109 | BT_DBG("%s", hdev->name); | 2258 | BT_DBG("%s", hdev->name); |
2110 | 2259 | ||
@@ -2118,19 +2267,35 @@ static inline void hci_sched_acl(struct hci_dev *hdev) | |||
2118 | hci_link_tx_to(hdev, ACL_LINK); | 2267 | hci_link_tx_to(hdev, ACL_LINK); |
2119 | } | 2268 | } |
2120 | 2269 | ||
2121 | while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, "e))) { | 2270 | cnt = hdev->acl_cnt; |
2122 | while (quote-- && (skb = skb_dequeue(&conn->data_q))) { | 2271 | |
2123 | BT_DBG("skb %p len %d", skb, skb->len); | 2272 | while (hdev->acl_cnt && |
2273 | (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { | ||
2274 | u32 priority = (skb_peek(&chan->data_q))->priority; | ||
2275 | while (quote-- && (skb = skb_peek(&chan->data_q))) { | ||
2276 | BT_DBG("chan %p skb %p len %d priority %u", chan, skb, | ||
2277 | skb->len, skb->priority); | ||
2124 | 2278 | ||
2125 | hci_conn_enter_active_mode(conn, bt_cb(skb)->force_active); | 2279 | /* Stop if priority has changed */ |
2280 | if (skb->priority < priority) | ||
2281 | break; | ||
2282 | |||
2283 | skb = skb_dequeue(&chan->data_q); | ||
2284 | |||
2285 | hci_conn_enter_active_mode(chan->conn, | ||
2286 | bt_cb(skb)->force_active); | ||
2126 | 2287 | ||
2127 | hci_send_frame(skb); | 2288 | hci_send_frame(skb); |
2128 | hdev->acl_last_tx = jiffies; | 2289 | hdev->acl_last_tx = jiffies; |
2129 | 2290 | ||
2130 | hdev->acl_cnt--; | 2291 | hdev->acl_cnt--; |
2131 | conn->sent++; | 2292 | chan->sent++; |
2293 | chan->conn->sent++; | ||
2132 | } | 2294 | } |
2133 | } | 2295 | } |
2296 | |||
2297 | if (cnt != hdev->acl_cnt) | ||
2298 | hci_prio_recalculate(hdev, ACL_LINK); | ||
2134 | } | 2299 | } |
2135 | 2300 | ||
2136 | /* Schedule SCO */ | 2301 | /* Schedule SCO */ |
@@ -2182,9 +2347,9 @@ static inline void hci_sched_esco(struct hci_dev *hdev) | |||
2182 | 2347 | ||
2183 | static inline void hci_sched_le(struct hci_dev *hdev) | 2348 | static inline void hci_sched_le(struct hci_dev *hdev) |
2184 | { | 2349 | { |
2185 | struct hci_conn *conn; | 2350 | struct hci_chan *chan; |
2186 | struct sk_buff *skb; | 2351 | struct sk_buff *skb; |
2187 | int quote, cnt; | 2352 | int quote, cnt, tmp; |
2188 | 2353 | ||
2189 | BT_DBG("%s", hdev->name); | 2354 | BT_DBG("%s", hdev->name); |
2190 | 2355 | ||
@@ -2200,21 +2365,35 @@ static inline void hci_sched_le(struct hci_dev *hdev) | |||
2200 | } | 2365 | } |
2201 | 2366 | ||
2202 | cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; | 2367 | cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; |
2203 | while (cnt && (conn = hci_low_sent(hdev, LE_LINK, "e))) { | 2368 | tmp = cnt; |
2204 | while (quote-- && (skb = skb_dequeue(&conn->data_q))) { | 2369 | while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, "e))) { |
2205 | BT_DBG("skb %p len %d", skb, skb->len); | 2370 | u32 priority = (skb_peek(&chan->data_q))->priority; |
2371 | while (quote-- && (skb = skb_peek(&chan->data_q))) { | ||
2372 | BT_DBG("chan %p skb %p len %d priority %u", chan, skb, | ||
2373 | skb->len, skb->priority); | ||
2374 | |||
2375 | /* Stop if priority has changed */ | ||
2376 | if (skb->priority < priority) | ||
2377 | break; | ||
2378 | |||
2379 | skb = skb_dequeue(&chan->data_q); | ||
2206 | 2380 | ||
2207 | hci_send_frame(skb); | 2381 | hci_send_frame(skb); |
2208 | hdev->le_last_tx = jiffies; | 2382 | hdev->le_last_tx = jiffies; |
2209 | 2383 | ||
2210 | cnt--; | 2384 | cnt--; |
2211 | conn->sent++; | 2385 | chan->sent++; |
2386 | chan->conn->sent++; | ||
2212 | } | 2387 | } |
2213 | } | 2388 | } |
2389 | |||
2214 | if (hdev->le_pkts) | 2390 | if (hdev->le_pkts) |
2215 | hdev->le_cnt = cnt; | 2391 | hdev->le_cnt = cnt; |
2216 | else | 2392 | else |
2217 | hdev->acl_cnt = cnt; | 2393 | hdev->acl_cnt = cnt; |
2394 | |||
2395 | if (cnt != tmp) | ||
2396 | hci_prio_recalculate(hdev, LE_LINK); | ||
2218 | } | 2397 | } |
2219 | 2398 | ||
2220 | static void hci_tx_task(unsigned long arg) | 2399 | static void hci_tx_task(unsigned long arg) |
@@ -2407,3 +2586,31 @@ static void hci_cmd_task(unsigned long arg) | |||
2407 | } | 2586 | } |
2408 | } | 2587 | } |
2409 | } | 2588 | } |
2589 | |||
2590 | int hci_do_inquiry(struct hci_dev *hdev, u8 length) | ||
2591 | { | ||
2592 | /* General inquiry access code (GIAC) */ | ||
2593 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; | ||
2594 | struct hci_cp_inquiry cp; | ||
2595 | |||
2596 | BT_DBG("%s", hdev->name); | ||
2597 | |||
2598 | if (test_bit(HCI_INQUIRY, &hdev->flags)) | ||
2599 | return -EINPROGRESS; | ||
2600 | |||
2601 | memset(&cp, 0, sizeof(cp)); | ||
2602 | memcpy(&cp.lap, lap, sizeof(cp.lap)); | ||
2603 | cp.length = length; | ||
2604 | |||
2605 | return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); | ||
2606 | } | ||
2607 | |||
2608 | int hci_cancel_inquiry(struct hci_dev *hdev) | ||
2609 | { | ||
2610 | BT_DBG("%s", hdev->name); | ||
2611 | |||
2612 | if (!test_bit(HCI_INQUIRY, &hdev->flags)) | ||
2613 | return -EPERM; | ||
2614 | |||
2615 | return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); | ||
2616 | } | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d7d96b6b1f0d..a89cf1f24e47 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -58,9 +58,11 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) | |||
58 | if (status) | 58 | if (status) |
59 | return; | 59 | return; |
60 | 60 | ||
61 | if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) && | 61 | clear_bit(HCI_INQUIRY, &hdev->flags); |
62 | test_bit(HCI_MGMT, &hdev->flags)) | 62 | |
63 | mgmt_discovering(hdev->id, 0); | 63 | hci_dev_lock(hdev); |
64 | mgmt_discovering(hdev, 0); | ||
65 | hci_dev_unlock(hdev); | ||
64 | 66 | ||
65 | hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); | 67 | hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); |
66 | 68 | ||
@@ -76,10 +78,6 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) | |||
76 | if (status) | 78 | if (status) |
77 | return; | 79 | return; |
78 | 80 | ||
79 | if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) && | ||
80 | test_bit(HCI_MGMT, &hdev->flags)) | ||
81 | mgmt_discovering(hdev->id, 0); | ||
82 | |||
83 | hci_conn_check_pending(hdev); | 81 | hci_conn_check_pending(hdev); |
84 | } | 82 | } |
85 | 83 | ||
@@ -205,13 +203,15 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) | |||
205 | if (!sent) | 203 | if (!sent) |
206 | return; | 204 | return; |
207 | 205 | ||
206 | hci_dev_lock(hdev); | ||
207 | |||
208 | if (test_bit(HCI_MGMT, &hdev->flags)) | 208 | if (test_bit(HCI_MGMT, &hdev->flags)) |
209 | mgmt_set_local_name_complete(hdev->id, sent, status); | 209 | mgmt_set_local_name_complete(hdev, sent, status); |
210 | 210 | ||
211 | if (status) | 211 | if (status == 0) |
212 | return; | 212 | memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); |
213 | 213 | ||
214 | memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); | 214 | hci_dev_unlock(hdev); |
215 | } | 215 | } |
216 | 216 | ||
217 | static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) | 217 | static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -274,7 +274,8 @@ static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) | |||
274 | 274 | ||
275 | static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) | 275 | static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) |
276 | { | 276 | { |
277 | __u8 status = *((__u8 *) skb->data); | 277 | __u8 param, status = *((__u8 *) skb->data); |
278 | int old_pscan, old_iscan; | ||
278 | void *sent; | 279 | void *sent; |
279 | 280 | ||
280 | BT_DBG("%s status 0x%x", hdev->name, status); | 281 | BT_DBG("%s status 0x%x", hdev->name, status); |
@@ -283,28 +284,40 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
283 | if (!sent) | 284 | if (!sent) |
284 | return; | 285 | return; |
285 | 286 | ||
286 | if (!status) { | 287 | param = *((__u8 *) sent); |
287 | __u8 param = *((__u8 *) sent); | ||
288 | int old_pscan, old_iscan; | ||
289 | |||
290 | old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags); | ||
291 | old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags); | ||
292 | 288 | ||
293 | if (param & SCAN_INQUIRY) { | 289 | hci_dev_lock(hdev); |
294 | set_bit(HCI_ISCAN, &hdev->flags); | ||
295 | if (!old_iscan) | ||
296 | mgmt_discoverable(hdev->id, 1); | ||
297 | } else if (old_iscan) | ||
298 | mgmt_discoverable(hdev->id, 0); | ||
299 | 290 | ||
300 | if (param & SCAN_PAGE) { | 291 | if (status != 0) { |
301 | set_bit(HCI_PSCAN, &hdev->flags); | 292 | mgmt_write_scan_failed(hdev, param, status); |
302 | if (!old_pscan) | 293 | hdev->discov_timeout = 0; |
303 | mgmt_connectable(hdev->id, 1); | 294 | goto done; |
304 | } else if (old_pscan) | ||
305 | mgmt_connectable(hdev->id, 0); | ||
306 | } | 295 | } |
307 | 296 | ||
297 | old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags); | ||
298 | old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags); | ||
299 | |||
300 | if (param & SCAN_INQUIRY) { | ||
301 | set_bit(HCI_ISCAN, &hdev->flags); | ||
302 | if (!old_iscan) | ||
303 | mgmt_discoverable(hdev, 1); | ||
304 | if (hdev->discov_timeout > 0) { | ||
305 | int to = msecs_to_jiffies(hdev->discov_timeout * 1000); | ||
306 | queue_delayed_work(hdev->workqueue, &hdev->discov_off, | ||
307 | to); | ||
308 | } | ||
309 | } else if (old_iscan) | ||
310 | mgmt_discoverable(hdev, 0); | ||
311 | |||
312 | if (param & SCAN_PAGE) { | ||
313 | set_bit(HCI_PSCAN, &hdev->flags); | ||
314 | if (!old_pscan) | ||
315 | mgmt_connectable(hdev, 1); | ||
316 | } else if (old_pscan) | ||
317 | mgmt_connectable(hdev, 0); | ||
318 | |||
319 | done: | ||
320 | hci_dev_unlock(hdev); | ||
308 | hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status); | 321 | hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status); |
309 | } | 322 | } |
310 | 323 | ||
@@ -748,6 +761,30 @@ static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb) | |||
748 | hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status); | 761 | hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status); |
749 | } | 762 | } |
750 | 763 | ||
764 | static void hci_cc_read_local_amp_info(struct hci_dev *hdev, | ||
765 | struct sk_buff *skb) | ||
766 | { | ||
767 | struct hci_rp_read_local_amp_info *rp = (void *) skb->data; | ||
768 | |||
769 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
770 | |||
771 | if (rp->status) | ||
772 | return; | ||
773 | |||
774 | hdev->amp_status = rp->amp_status; | ||
775 | hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); | ||
776 | hdev->amp_max_bw = __le32_to_cpu(rp->max_bw); | ||
777 | hdev->amp_min_latency = __le32_to_cpu(rp->min_latency); | ||
778 | hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu); | ||
779 | hdev->amp_type = rp->amp_type; | ||
780 | hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap); | ||
781 | hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size); | ||
782 | hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to); | ||
783 | hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); | ||
784 | |||
785 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status); | ||
786 | } | ||
787 | |||
751 | static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, | 788 | static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, |
752 | struct sk_buff *skb) | 789 | struct sk_buff *skb) |
753 | { | 790 | { |
@@ -804,19 +841,24 @@ static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
804 | 841 | ||
805 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 842 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
806 | 843 | ||
844 | hci_dev_lock(hdev); | ||
845 | |||
807 | if (test_bit(HCI_MGMT, &hdev->flags)) | 846 | if (test_bit(HCI_MGMT, &hdev->flags)) |
808 | mgmt_pin_code_reply_complete(hdev->id, &rp->bdaddr, rp->status); | 847 | mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); |
809 | 848 | ||
810 | if (rp->status != 0) | 849 | if (rp->status != 0) |
811 | return; | 850 | goto unlock; |
812 | 851 | ||
813 | cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); | 852 | cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); |
814 | if (!cp) | 853 | if (!cp) |
815 | return; | 854 | goto unlock; |
816 | 855 | ||
817 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | 856 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); |
818 | if (conn) | 857 | if (conn) |
819 | conn->pin_length = cp->pin_len; | 858 | conn->pin_length = cp->pin_len; |
859 | |||
860 | unlock: | ||
861 | hci_dev_unlock(hdev); | ||
820 | } | 862 | } |
821 | 863 | ||
822 | static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) | 864 | static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -825,10 +867,15 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
825 | 867 | ||
826 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 868 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
827 | 869 | ||
870 | hci_dev_lock(hdev); | ||
871 | |||
828 | if (test_bit(HCI_MGMT, &hdev->flags)) | 872 | if (test_bit(HCI_MGMT, &hdev->flags)) |
829 | mgmt_pin_code_neg_reply_complete(hdev->id, &rp->bdaddr, | 873 | mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, |
830 | rp->status); | 874 | rp->status); |
875 | |||
876 | hci_dev_unlock(hdev); | ||
831 | } | 877 | } |
878 | |||
832 | static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, | 879 | static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, |
833 | struct sk_buff *skb) | 880 | struct sk_buff *skb) |
834 | { | 881 | { |
@@ -855,9 +902,13 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
855 | 902 | ||
856 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 903 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
857 | 904 | ||
905 | hci_dev_lock(hdev); | ||
906 | |||
858 | if (test_bit(HCI_MGMT, &hdev->flags)) | 907 | if (test_bit(HCI_MGMT, &hdev->flags)) |
859 | mgmt_user_confirm_reply_complete(hdev->id, &rp->bdaddr, | 908 | mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, |
860 | rp->status); | 909 | rp->status); |
910 | |||
911 | hci_dev_unlock(hdev); | ||
861 | } | 912 | } |
862 | 913 | ||
863 | static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, | 914 | static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, |
@@ -867,9 +918,13 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, | |||
867 | 918 | ||
868 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 919 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
869 | 920 | ||
921 | hci_dev_lock(hdev); | ||
922 | |||
870 | if (test_bit(HCI_MGMT, &hdev->flags)) | 923 | if (test_bit(HCI_MGMT, &hdev->flags)) |
871 | mgmt_user_confirm_neg_reply_complete(hdev->id, &rp->bdaddr, | 924 | mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, |
872 | rp->status); | 925 | rp->status); |
926 | |||
927 | hci_dev_unlock(hdev); | ||
873 | } | 928 | } |
874 | 929 | ||
875 | static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, | 930 | static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, |
@@ -879,8 +934,10 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, | |||
879 | 934 | ||
880 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 935 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
881 | 936 | ||
882 | mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash, | 937 | hci_dev_lock(hdev); |
938 | mgmt_read_local_oob_data_reply_complete(hdev, rp->hash, | ||
883 | rp->randomizer, rp->status); | 939 | rp->randomizer, rp->status); |
940 | hci_dev_unlock(hdev); | ||
884 | } | 941 | } |
885 | 942 | ||
886 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | 943 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, |
@@ -955,12 +1012,18 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | |||
955 | if (status) { | 1012 | if (status) { |
956 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); | 1013 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); |
957 | hci_conn_check_pending(hdev); | 1014 | hci_conn_check_pending(hdev); |
1015 | hci_dev_lock(hdev); | ||
1016 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
1017 | mgmt_inquiry_failed(hdev, status); | ||
1018 | hci_dev_unlock(hdev); | ||
958 | return; | 1019 | return; |
959 | } | 1020 | } |
960 | 1021 | ||
961 | if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags) && | 1022 | set_bit(HCI_INQUIRY, &hdev->flags); |
962 | test_bit(HCI_MGMT, &hdev->flags)) | 1023 | |
963 | mgmt_discovering(hdev->id, 1); | 1024 | hci_dev_lock(hdev); |
1025 | mgmt_discovering(hdev, 1); | ||
1026 | hci_dev_unlock(hdev); | ||
964 | } | 1027 | } |
965 | 1028 | ||
966 | static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) | 1029 | static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) |
@@ -1339,13 +1402,16 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
1339 | 1402 | ||
1340 | BT_DBG("%s status %d", hdev->name, status); | 1403 | BT_DBG("%s status %d", hdev->name, status); |
1341 | 1404 | ||
1342 | if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) && | ||
1343 | test_bit(HCI_MGMT, &hdev->flags)) | ||
1344 | mgmt_discovering(hdev->id, 0); | ||
1345 | |||
1346 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); | 1405 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); |
1347 | 1406 | ||
1348 | hci_conn_check_pending(hdev); | 1407 | hci_conn_check_pending(hdev); |
1408 | |||
1409 | if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) | ||
1410 | return; | ||
1411 | |||
1412 | hci_dev_lock(hdev); | ||
1413 | mgmt_discovering(hdev, 0); | ||
1414 | hci_dev_unlock(hdev); | ||
1349 | } | 1415 | } |
1350 | 1416 | ||
1351 | static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1417 | static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -1361,12 +1427,6 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * | |||
1361 | 1427 | ||
1362 | hci_dev_lock(hdev); | 1428 | hci_dev_lock(hdev); |
1363 | 1429 | ||
1364 | if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) { | ||
1365 | |||
1366 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
1367 | mgmt_discovering(hdev->id, 1); | ||
1368 | } | ||
1369 | |||
1370 | for (; num_rsp; num_rsp--, info++) { | 1430 | for (; num_rsp; num_rsp--, info++) { |
1371 | bacpy(&data.bdaddr, &info->bdaddr); | 1431 | bacpy(&data.bdaddr, &info->bdaddr); |
1372 | data.pscan_rep_mode = info->pscan_rep_mode; | 1432 | data.pscan_rep_mode = info->pscan_rep_mode; |
@@ -1377,8 +1437,8 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * | |||
1377 | data.rssi = 0x00; | 1437 | data.rssi = 0x00; |
1378 | data.ssp_mode = 0x00; | 1438 | data.ssp_mode = 0x00; |
1379 | hci_inquiry_cache_update(hdev, &data); | 1439 | hci_inquiry_cache_update(hdev, &data); |
1380 | mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class, 0, | 1440 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, |
1381 | NULL); | 1441 | info->dev_class, 0, NULL); |
1382 | } | 1442 | } |
1383 | 1443 | ||
1384 | hci_dev_unlock(hdev); | 1444 | hci_dev_unlock(hdev); |
@@ -1412,7 +1472,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1412 | conn->state = BT_CONFIG; | 1472 | conn->state = BT_CONFIG; |
1413 | hci_conn_hold(conn); | 1473 | hci_conn_hold(conn); |
1414 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 1474 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
1415 | mgmt_connected(hdev->id, &ev->bdaddr, conn->type); | 1475 | mgmt_connected(hdev, &ev->bdaddr, conn->type); |
1416 | } else | 1476 | } else |
1417 | conn->state = BT_CONNECTED; | 1477 | conn->state = BT_CONNECTED; |
1418 | 1478 | ||
@@ -1444,7 +1504,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1444 | } else { | 1504 | } else { |
1445 | conn->state = BT_CLOSED; | 1505 | conn->state = BT_CLOSED; |
1446 | if (conn->type == ACL_LINK) | 1506 | if (conn->type == ACL_LINK) |
1447 | mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status); | 1507 | mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, |
1508 | ev->status); | ||
1448 | } | 1509 | } |
1449 | 1510 | ||
1450 | if (conn->type == ACL_LINK) | 1511 | if (conn->type == ACL_LINK) |
@@ -1531,7 +1592,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1531 | struct hci_cp_reject_conn_req cp; | 1592 | struct hci_cp_reject_conn_req cp; |
1532 | 1593 | ||
1533 | bacpy(&cp.bdaddr, &ev->bdaddr); | 1594 | bacpy(&cp.bdaddr, &ev->bdaddr); |
1534 | cp.reason = 0x0f; | 1595 | cp.reason = HCI_ERROR_REJ_BAD_ADDR; |
1535 | hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); | 1596 | hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp); |
1536 | } | 1597 | } |
1537 | } | 1598 | } |
@@ -1544,7 +1605,9 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
1544 | BT_DBG("%s status %d", hdev->name, ev->status); | 1605 | BT_DBG("%s status %d", hdev->name, ev->status); |
1545 | 1606 | ||
1546 | if (ev->status) { | 1607 | if (ev->status) { |
1547 | mgmt_disconnect_failed(hdev->id); | 1608 | hci_dev_lock(hdev); |
1609 | mgmt_disconnect_failed(hdev); | ||
1610 | hci_dev_unlock(hdev); | ||
1548 | return; | 1611 | return; |
1549 | } | 1612 | } |
1550 | 1613 | ||
@@ -1557,7 +1620,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
1557 | conn->state = BT_CLOSED; | 1620 | conn->state = BT_CLOSED; |
1558 | 1621 | ||
1559 | if (conn->type == ACL_LINK || conn->type == LE_LINK) | 1622 | if (conn->type == ACL_LINK || conn->type == LE_LINK) |
1560 | mgmt_disconnected(hdev->id, &conn->dst); | 1623 | mgmt_disconnected(hdev, &conn->dst, conn->type); |
1561 | 1624 | ||
1562 | hci_proto_disconn_cfm(conn, ev->reason); | 1625 | hci_proto_disconn_cfm(conn, ev->reason); |
1563 | hci_conn_del(conn); | 1626 | hci_conn_del(conn); |
@@ -1588,7 +1651,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1588 | conn->sec_level = conn->pending_sec_level; | 1651 | conn->sec_level = conn->pending_sec_level; |
1589 | } | 1652 | } |
1590 | } else { | 1653 | } else { |
1591 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | 1654 | mgmt_auth_failed(hdev, &conn->dst, ev->status); |
1592 | } | 1655 | } |
1593 | 1656 | ||
1594 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); | 1657 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); |
@@ -1643,7 +1706,7 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb | |||
1643 | hci_dev_lock(hdev); | 1706 | hci_dev_lock(hdev); |
1644 | 1707 | ||
1645 | if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags)) | 1708 | if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags)) |
1646 | mgmt_remote_name(hdev->id, &ev->bdaddr, ev->name); | 1709 | mgmt_remote_name(hdev, &ev->bdaddr, ev->name); |
1647 | 1710 | ||
1648 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | 1711 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); |
1649 | if (!conn) | 1712 | if (!conn) |
@@ -1898,6 +1961,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1898 | hci_cc_write_ca_timeout(hdev, skb); | 1961 | hci_cc_write_ca_timeout(hdev, skb); |
1899 | break; | 1962 | break; |
1900 | 1963 | ||
1964 | case HCI_OP_READ_LOCAL_AMP_INFO: | ||
1965 | hci_cc_read_local_amp_info(hdev, skb); | ||
1966 | break; | ||
1967 | |||
1901 | case HCI_OP_DELETE_STORED_LINK_KEY: | 1968 | case HCI_OP_DELETE_STORED_LINK_KEY: |
1902 | hci_cc_delete_stored_link_key(hdev, skb); | 1969 | hci_cc_delete_stored_link_key(hdev, skb); |
1903 | break; | 1970 | break; |
@@ -2029,7 +2096,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2029 | 2096 | ||
2030 | case HCI_OP_DISCONNECT: | 2097 | case HCI_OP_DISCONNECT: |
2031 | if (ev->status != 0) | 2098 | if (ev->status != 0) |
2032 | mgmt_disconnect_failed(hdev->id); | 2099 | mgmt_disconnect_failed(hdev); |
2033 | break; | 2100 | break; |
2034 | 2101 | ||
2035 | case HCI_OP_LE_CREATE_CONN: | 2102 | case HCI_OP_LE_CREATE_CONN: |
@@ -2194,7 +2261,7 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff | |||
2194 | else | 2261 | else |
2195 | secure = 0; | 2262 | secure = 0; |
2196 | 2263 | ||
2197 | mgmt_pin_code_request(hdev->id, &ev->bdaddr, secure); | 2264 | mgmt_pin_code_request(hdev, &ev->bdaddr, secure); |
2198 | } | 2265 | } |
2199 | 2266 | ||
2200 | unlock: | 2267 | unlock: |
@@ -2363,12 +2430,6 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
2363 | 2430 | ||
2364 | hci_dev_lock(hdev); | 2431 | hci_dev_lock(hdev); |
2365 | 2432 | ||
2366 | if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) { | ||
2367 | |||
2368 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
2369 | mgmt_discovering(hdev->id, 1); | ||
2370 | } | ||
2371 | |||
2372 | if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { | 2433 | if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { |
2373 | struct inquiry_info_with_rssi_and_pscan_mode *info; | 2434 | struct inquiry_info_with_rssi_and_pscan_mode *info; |
2374 | info = (void *) (skb->data + 1); | 2435 | info = (void *) (skb->data + 1); |
@@ -2383,7 +2444,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
2383 | data.rssi = info->rssi; | 2444 | data.rssi = info->rssi; |
2384 | data.ssp_mode = 0x00; | 2445 | data.ssp_mode = 0x00; |
2385 | hci_inquiry_cache_update(hdev, &data); | 2446 | hci_inquiry_cache_update(hdev, &data); |
2386 | mgmt_device_found(hdev->id, &info->bdaddr, | 2447 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, |
2387 | info->dev_class, info->rssi, | 2448 | info->dev_class, info->rssi, |
2388 | NULL); | 2449 | NULL); |
2389 | } | 2450 | } |
@@ -2400,7 +2461,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
2400 | data.rssi = info->rssi; | 2461 | data.rssi = info->rssi; |
2401 | data.ssp_mode = 0x00; | 2462 | data.ssp_mode = 0x00; |
2402 | hci_inquiry_cache_update(hdev, &data); | 2463 | hci_inquiry_cache_update(hdev, &data); |
2403 | mgmt_device_found(hdev->id, &info->bdaddr, | 2464 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, |
2404 | info->dev_class, info->rssi, | 2465 | info->dev_class, info->rssi, |
2405 | NULL); | 2466 | NULL); |
2406 | } | 2467 | } |
@@ -2531,12 +2592,6 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct | |||
2531 | if (!num_rsp) | 2592 | if (!num_rsp) |
2532 | return; | 2593 | return; |
2533 | 2594 | ||
2534 | if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags)) { | ||
2535 | |||
2536 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
2537 | mgmt_discovering(hdev->id, 1); | ||
2538 | } | ||
2539 | |||
2540 | hci_dev_lock(hdev); | 2595 | hci_dev_lock(hdev); |
2541 | 2596 | ||
2542 | for (; num_rsp; num_rsp--, info++) { | 2597 | for (; num_rsp; num_rsp--, info++) { |
@@ -2549,8 +2604,8 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct | |||
2549 | data.rssi = info->rssi; | 2604 | data.rssi = info->rssi; |
2550 | data.ssp_mode = 0x01; | 2605 | data.ssp_mode = 0x01; |
2551 | hci_inquiry_cache_update(hdev, &data); | 2606 | hci_inquiry_cache_update(hdev, &data); |
2552 | mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class, | 2607 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, |
2553 | info->rssi, info->data); | 2608 | info->dev_class, info->rssi, info->data); |
2554 | } | 2609 | } |
2555 | 2610 | ||
2556 | hci_dev_unlock(hdev); | 2611 | hci_dev_unlock(hdev); |
@@ -2614,7 +2669,7 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff | |||
2614 | struct hci_cp_io_capability_neg_reply cp; | 2669 | struct hci_cp_io_capability_neg_reply cp; |
2615 | 2670 | ||
2616 | bacpy(&cp.bdaddr, &ev->bdaddr); | 2671 | bacpy(&cp.bdaddr, &ev->bdaddr); |
2617 | cp.reason = 0x18; /* Pairing not allowed */ | 2672 | cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; |
2618 | 2673 | ||
2619 | hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, | 2674 | hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, |
2620 | sizeof(cp), &cp); | 2675 | sizeof(cp), &cp); |
@@ -2706,7 +2761,7 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, | |||
2706 | } | 2761 | } |
2707 | 2762 | ||
2708 | confirm: | 2763 | confirm: |
2709 | mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey, | 2764 | mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey, |
2710 | confirm_hint); | 2765 | confirm_hint); |
2711 | 2766 | ||
2712 | unlock: | 2767 | unlock: |
@@ -2732,7 +2787,7 @@ static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_ | |||
2732 | * event gets always produced as initiator and is also mapped to | 2787 | * event gets always produced as initiator and is also mapped to |
2733 | * the mgmt_auth_failed event */ | 2788 | * the mgmt_auth_failed event */ |
2734 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0) | 2789 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0) |
2735 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | 2790 | mgmt_auth_failed(hdev, &conn->dst, ev->status); |
2736 | 2791 | ||
2737 | hci_conn_put(conn); | 2792 | hci_conn_put(conn); |
2738 | 2793 | ||
@@ -2813,14 +2868,14 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
2813 | } | 2868 | } |
2814 | 2869 | ||
2815 | if (ev->status) { | 2870 | if (ev->status) { |
2816 | mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status); | 2871 | mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, ev->status); |
2817 | hci_proto_connect_cfm(conn, ev->status); | 2872 | hci_proto_connect_cfm(conn, ev->status); |
2818 | conn->state = BT_CLOSED; | 2873 | conn->state = BT_CLOSED; |
2819 | hci_conn_del(conn); | 2874 | hci_conn_del(conn); |
2820 | goto unlock; | 2875 | goto unlock; |
2821 | } | 2876 | } |
2822 | 2877 | ||
2823 | mgmt_connected(hdev->id, &ev->bdaddr, conn->type); | 2878 | mgmt_connected(hdev, &ev->bdaddr, conn->type); |
2824 | 2879 | ||
2825 | conn->sec_level = BT_SECURITY_LOW; | 2880 | conn->sec_level = BT_SECURITY_LOW; |
2826 | conn->handle = __le16_to_cpu(ev->handle); | 2881 | conn->handle = __le16_to_cpu(ev->handle); |
@@ -3104,5 +3159,5 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data) | |||
3104 | kfree_skb(skb); | 3159 | kfree_skb(skb); |
3105 | } | 3160 | } |
3106 | 3161 | ||
3107 | module_param(enable_le, bool, 0444); | 3162 | module_param(enable_le, bool, 0644); |
3108 | MODULE_PARM_DESC(enable_le, "Enable LE support"); | 3163 | MODULE_PARM_DESC(enable_le, "Enable LE support"); |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 661b461cf0b0..c62d254a1379 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -436,17 +436,12 @@ static const struct file_operations inquiry_cache_fops = { | |||
436 | static int blacklist_show(struct seq_file *f, void *p) | 436 | static int blacklist_show(struct seq_file *f, void *p) |
437 | { | 437 | { |
438 | struct hci_dev *hdev = f->private; | 438 | struct hci_dev *hdev = f->private; |
439 | struct list_head *l; | 439 | struct bdaddr_list *b; |
440 | 440 | ||
441 | hci_dev_lock_bh(hdev); | 441 | hci_dev_lock_bh(hdev); |
442 | 442 | ||
443 | list_for_each(l, &hdev->blacklist) { | 443 | list_for_each_entry(b, &hdev->blacklist, list) |
444 | struct bdaddr_list *b; | ||
445 | |||
446 | b = list_entry(l, struct bdaddr_list, list); | ||
447 | |||
448 | seq_printf(f, "%s\n", batostr(&b->bdaddr)); | 444 | seq_printf(f, "%s\n", batostr(&b->bdaddr)); |
449 | } | ||
450 | 445 | ||
451 | hci_dev_unlock_bh(hdev); | 446 | hci_dev_unlock_bh(hdev); |
452 | 447 | ||
@@ -485,17 +480,12 @@ static void print_bt_uuid(struct seq_file *f, u8 *uuid) | |||
485 | static int uuids_show(struct seq_file *f, void *p) | 480 | static int uuids_show(struct seq_file *f, void *p) |
486 | { | 481 | { |
487 | struct hci_dev *hdev = f->private; | 482 | struct hci_dev *hdev = f->private; |
488 | struct list_head *l; | 483 | struct bt_uuid *uuid; |
489 | 484 | ||
490 | hci_dev_lock_bh(hdev); | 485 | hci_dev_lock_bh(hdev); |
491 | 486 | ||
492 | list_for_each(l, &hdev->uuids) { | 487 | list_for_each_entry(uuid, &hdev->uuids, list) |
493 | struct bt_uuid *uuid; | ||
494 | |||
495 | uuid = list_entry(l, struct bt_uuid, list); | ||
496 | |||
497 | print_bt_uuid(f, uuid->uuid); | 488 | print_bt_uuid(f, uuid->uuid); |
498 | } | ||
499 | 489 | ||
500 | hci_dev_unlock_bh(hdev); | 490 | hci_dev_unlock_bh(hdev); |
501 | 491 | ||
@@ -543,22 +533,28 @@ static int auto_accept_delay_get(void *data, u64 *val) | |||
543 | DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, | 533 | DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, |
544 | auto_accept_delay_set, "%llu\n"); | 534 | auto_accept_delay_set, "%llu\n"); |
545 | 535 | ||
546 | int hci_register_sysfs(struct hci_dev *hdev) | 536 | void hci_init_sysfs(struct hci_dev *hdev) |
537 | { | ||
538 | struct device *dev = &hdev->dev; | ||
539 | |||
540 | dev->type = &bt_host; | ||
541 | dev->class = bt_class; | ||
542 | |||
543 | dev_set_drvdata(dev, hdev); | ||
544 | device_initialize(dev); | ||
545 | } | ||
546 | |||
547 | int hci_add_sysfs(struct hci_dev *hdev) | ||
547 | { | 548 | { |
548 | struct device *dev = &hdev->dev; | 549 | struct device *dev = &hdev->dev; |
549 | int err; | 550 | int err; |
550 | 551 | ||
551 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); | 552 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); |
552 | 553 | ||
553 | dev->type = &bt_host; | ||
554 | dev->class = bt_class; | ||
555 | dev->parent = hdev->parent; | 554 | dev->parent = hdev->parent; |
556 | |||
557 | dev_set_name(dev, "%s", hdev->name); | 555 | dev_set_name(dev, "%s", hdev->name); |
558 | 556 | ||
559 | dev_set_drvdata(dev, hdev); | 557 | err = device_add(dev); |
560 | |||
561 | err = device_register(dev); | ||
562 | if (err < 0) | 558 | if (err < 0) |
563 | return err; | 559 | return err; |
564 | 560 | ||
@@ -582,7 +578,7 @@ int hci_register_sysfs(struct hci_dev *hdev) | |||
582 | return 0; | 578 | return 0; |
583 | } | 579 | } |
584 | 580 | ||
585 | void hci_unregister_sysfs(struct hci_dev *hdev) | 581 | void hci_del_sysfs(struct hci_dev *hdev) |
586 | { | 582 | { |
587 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); | 583 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); |
588 | 584 | ||
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 075a3e920caf..3c2d888925d7 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -81,24 +81,20 @@ static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; | |||
81 | static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr) | 81 | static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr) |
82 | { | 82 | { |
83 | struct hidp_session *session; | 83 | struct hidp_session *session; |
84 | struct list_head *p; | ||
85 | 84 | ||
86 | BT_DBG(""); | 85 | BT_DBG(""); |
87 | 86 | ||
88 | list_for_each(p, &hidp_session_list) { | 87 | list_for_each_entry(session, &hidp_session_list, list) { |
89 | session = list_entry(p, struct hidp_session, list); | ||
90 | if (!bacmp(bdaddr, &session->bdaddr)) | 88 | if (!bacmp(bdaddr, &session->bdaddr)) |
91 | return session; | 89 | return session; |
92 | } | 90 | } |
91 | |||
93 | return NULL; | 92 | return NULL; |
94 | } | 93 | } |
95 | 94 | ||
96 | static void __hidp_link_session(struct hidp_session *session) | 95 | static void __hidp_link_session(struct hidp_session *session) |
97 | { | 96 | { |
98 | __module_get(THIS_MODULE); | ||
99 | list_add(&session->list, &hidp_session_list); | 97 | list_add(&session->list, &hidp_session_list); |
100 | |||
101 | hci_conn_hold_device(session->conn); | ||
102 | } | 98 | } |
103 | 99 | ||
104 | static void __hidp_unlink_session(struct hidp_session *session) | 100 | static void __hidp_unlink_session(struct hidp_session *session) |
@@ -106,7 +102,6 @@ static void __hidp_unlink_session(struct hidp_session *session) | |||
106 | hci_conn_put_device(session->conn); | 102 | hci_conn_put_device(session->conn); |
107 | 103 | ||
108 | list_del(&session->list); | 104 | list_del(&session->list); |
109 | module_put(THIS_MODULE); | ||
110 | } | 105 | } |
111 | 106 | ||
112 | static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci) | 107 | static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci) |
@@ -255,6 +250,9 @@ static int __hidp_send_ctrl_message(struct hidp_session *session, | |||
255 | 250 | ||
256 | BT_DBG("session %p data %p size %d", session, data, size); | 251 | BT_DBG("session %p data %p size %d", session, data, size); |
257 | 252 | ||
253 | if (atomic_read(&session->terminate)) | ||
254 | return -EIO; | ||
255 | |||
258 | skb = alloc_skb(size + 1, GFP_ATOMIC); | 256 | skb = alloc_skb(size + 1, GFP_ATOMIC); |
259 | if (!skb) { | 257 | if (!skb) { |
260 | BT_ERR("Can't allocate memory for new frame"); | 258 | BT_ERR("Can't allocate memory for new frame"); |
@@ -329,6 +327,7 @@ static int hidp_get_raw_report(struct hid_device *hid, | |||
329 | struct sk_buff *skb; | 327 | struct sk_buff *skb; |
330 | size_t len; | 328 | size_t len; |
331 | int numbered_reports = hid->report_enum[report_type].numbered; | 329 | int numbered_reports = hid->report_enum[report_type].numbered; |
330 | int ret; | ||
332 | 331 | ||
333 | switch (report_type) { | 332 | switch (report_type) { |
334 | case HID_FEATURE_REPORT: | 333 | case HID_FEATURE_REPORT: |
@@ -352,8 +351,9 @@ static int hidp_get_raw_report(struct hid_device *hid, | |||
352 | session->waiting_report_number = numbered_reports ? report_number : -1; | 351 | session->waiting_report_number = numbered_reports ? report_number : -1; |
353 | set_bit(HIDP_WAITING_FOR_RETURN, &session->flags); | 352 | set_bit(HIDP_WAITING_FOR_RETURN, &session->flags); |
354 | data[0] = report_number; | 353 | data[0] = report_number; |
355 | if (hidp_send_ctrl_message(hid->driver_data, report_type, data, 1)) | 354 | ret = hidp_send_ctrl_message(hid->driver_data, report_type, data, 1); |
356 | goto err_eio; | 355 | if (ret) |
356 | goto err; | ||
357 | 357 | ||
358 | /* Wait for the return of the report. The returned report | 358 | /* Wait for the return of the report. The returned report |
359 | gets put in session->report_return. */ | 359 | gets put in session->report_return. */ |
@@ -365,11 +365,13 @@ static int hidp_get_raw_report(struct hid_device *hid, | |||
365 | 5*HZ); | 365 | 5*HZ); |
366 | if (res == 0) { | 366 | if (res == 0) { |
367 | /* timeout */ | 367 | /* timeout */ |
368 | goto err_eio; | 368 | ret = -EIO; |
369 | goto err; | ||
369 | } | 370 | } |
370 | if (res < 0) { | 371 | if (res < 0) { |
371 | /* signal */ | 372 | /* signal */ |
372 | goto err_restartsys; | 373 | ret = -ERESTARTSYS; |
374 | goto err; | ||
373 | } | 375 | } |
374 | } | 376 | } |
375 | 377 | ||
@@ -390,14 +392,10 @@ static int hidp_get_raw_report(struct hid_device *hid, | |||
390 | 392 | ||
391 | return len; | 393 | return len; |
392 | 394 | ||
393 | err_restartsys: | 395 | err: |
394 | clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); | ||
395 | mutex_unlock(&session->report_mutex); | ||
396 | return -ERESTARTSYS; | ||
397 | err_eio: | ||
398 | clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); | 396 | clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); |
399 | mutex_unlock(&session->report_mutex); | 397 | mutex_unlock(&session->report_mutex); |
400 | return -EIO; | 398 | return ret; |
401 | } | 399 | } |
402 | 400 | ||
403 | static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count, | 401 | static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count, |
@@ -422,11 +420,10 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s | |||
422 | 420 | ||
423 | /* Set up our wait, and send the report request to the device. */ | 421 | /* Set up our wait, and send the report request to the device. */ |
424 | set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); | 422 | set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); |
425 | if (hidp_send_ctrl_message(hid->driver_data, report_type, | 423 | ret = hidp_send_ctrl_message(hid->driver_data, report_type, data, |
426 | data, count)) { | 424 | count); |
427 | ret = -ENOMEM; | 425 | if (ret) |
428 | goto err; | 426 | goto err; |
429 | } | ||
430 | 427 | ||
431 | /* Wait for the ACK from the device. */ | 428 | /* Wait for the ACK from the device. */ |
432 | while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) { | 429 | while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) { |
@@ -496,10 +493,9 @@ static void hidp_process_handshake(struct hidp_session *session, | |||
496 | case HIDP_HSHK_ERR_INVALID_REPORT_ID: | 493 | case HIDP_HSHK_ERR_INVALID_REPORT_ID: |
497 | case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST: | 494 | case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST: |
498 | case HIDP_HSHK_ERR_INVALID_PARAMETER: | 495 | case HIDP_HSHK_ERR_INVALID_PARAMETER: |
499 | if (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) { | 496 | if (test_and_clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) |
500 | clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); | ||
501 | wake_up_interruptible(&session->report_queue); | 497 | wake_up_interruptible(&session->report_queue); |
502 | } | 498 | |
503 | /* FIXME: Call into SET_ GET_ handlers here */ | 499 | /* FIXME: Call into SET_ GET_ handlers here */ |
504 | break; | 500 | break; |
505 | 501 | ||
@@ -520,10 +516,8 @@ static void hidp_process_handshake(struct hidp_session *session, | |||
520 | } | 516 | } |
521 | 517 | ||
522 | /* Wake up the waiting thread. */ | 518 | /* Wake up the waiting thread. */ |
523 | if (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) { | 519 | if (test_and_clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) |
524 | clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); | ||
525 | wake_up_interruptible(&session->report_queue); | 520 | wake_up_interruptible(&session->report_queue); |
526 | } | ||
527 | } | 521 | } |
528 | 522 | ||
529 | static void hidp_process_hid_control(struct hidp_session *session, | 523 | static void hidp_process_hid_control(struct hidp_session *session, |
@@ -663,25 +657,32 @@ static int hidp_send_frame(struct socket *sock, unsigned char *data, int len) | |||
663 | return kernel_sendmsg(sock, &msg, &iv, 1, len); | 657 | return kernel_sendmsg(sock, &msg, &iv, 1, len); |
664 | } | 658 | } |
665 | 659 | ||
666 | static void hidp_process_transmit(struct hidp_session *session) | 660 | static void hidp_process_intr_transmit(struct hidp_session *session) |
667 | { | 661 | { |
668 | struct sk_buff *skb; | 662 | struct sk_buff *skb; |
669 | 663 | ||
670 | BT_DBG("session %p", session); | 664 | BT_DBG("session %p", session); |
671 | 665 | ||
672 | while ((skb = skb_dequeue(&session->ctrl_transmit))) { | 666 | while ((skb = skb_dequeue(&session->intr_transmit))) { |
673 | if (hidp_send_frame(session->ctrl_sock, skb->data, skb->len) < 0) { | 667 | if (hidp_send_frame(session->intr_sock, skb->data, skb->len) < 0) { |
674 | skb_queue_head(&session->ctrl_transmit, skb); | 668 | skb_queue_head(&session->intr_transmit, skb); |
675 | break; | 669 | break; |
676 | } | 670 | } |
677 | 671 | ||
678 | hidp_set_timer(session); | 672 | hidp_set_timer(session); |
679 | kfree_skb(skb); | 673 | kfree_skb(skb); |
680 | } | 674 | } |
675 | } | ||
681 | 676 | ||
682 | while ((skb = skb_dequeue(&session->intr_transmit))) { | 677 | static void hidp_process_ctrl_transmit(struct hidp_session *session) |
683 | if (hidp_send_frame(session->intr_sock, skb->data, skb->len) < 0) { | 678 | { |
684 | skb_queue_head(&session->intr_transmit, skb); | 679 | struct sk_buff *skb; |
680 | |||
681 | BT_DBG("session %p", session); | ||
682 | |||
683 | while ((skb = skb_dequeue(&session->ctrl_transmit))) { | ||
684 | if (hidp_send_frame(session->ctrl_sock, skb->data, skb->len) < 0) { | ||
685 | skb_queue_head(&session->ctrl_transmit, skb); | ||
685 | break; | 686 | break; |
686 | } | 687 | } |
687 | 688 | ||
@@ -700,6 +701,7 @@ static int hidp_session(void *arg) | |||
700 | 701 | ||
701 | BT_DBG("session %p", session); | 702 | BT_DBG("session %p", session); |
702 | 703 | ||
704 | __module_get(THIS_MODULE); | ||
703 | set_user_nice(current, -15); | 705 | set_user_nice(current, -15); |
704 | 706 | ||
705 | init_waitqueue_entry(&ctrl_wait, current); | 707 | init_waitqueue_entry(&ctrl_wait, current); |
@@ -714,23 +716,25 @@ static int hidp_session(void *arg) | |||
714 | intr_sk->sk_state != BT_CONNECTED) | 716 | intr_sk->sk_state != BT_CONNECTED) |
715 | break; | 717 | break; |
716 | 718 | ||
717 | while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) { | 719 | while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) { |
718 | skb_orphan(skb); | 720 | skb_orphan(skb); |
719 | if (!skb_linearize(skb)) | 721 | if (!skb_linearize(skb)) |
720 | hidp_recv_ctrl_frame(session, skb); | 722 | hidp_recv_intr_frame(session, skb); |
721 | else | 723 | else |
722 | kfree_skb(skb); | 724 | kfree_skb(skb); |
723 | } | 725 | } |
724 | 726 | ||
725 | while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) { | 727 | hidp_process_intr_transmit(session); |
728 | |||
729 | while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) { | ||
726 | skb_orphan(skb); | 730 | skb_orphan(skb); |
727 | if (!skb_linearize(skb)) | 731 | if (!skb_linearize(skb)) |
728 | hidp_recv_intr_frame(session, skb); | 732 | hidp_recv_ctrl_frame(session, skb); |
729 | else | 733 | else |
730 | kfree_skb(skb); | 734 | kfree_skb(skb); |
731 | } | 735 | } |
732 | 736 | ||
733 | hidp_process_transmit(session); | 737 | hidp_process_ctrl_transmit(session); |
734 | 738 | ||
735 | schedule(); | 739 | schedule(); |
736 | set_current_state(TASK_INTERRUPTIBLE); | 740 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -739,6 +743,10 @@ static int hidp_session(void *arg) | |||
739 | remove_wait_queue(sk_sleep(intr_sk), &intr_wait); | 743 | remove_wait_queue(sk_sleep(intr_sk), &intr_wait); |
740 | remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); | 744 | remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); |
741 | 745 | ||
746 | clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); | ||
747 | clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); | ||
748 | wake_up_interruptible(&session->report_queue); | ||
749 | |||
742 | down_write(&hidp_session_sem); | 750 | down_write(&hidp_session_sem); |
743 | 751 | ||
744 | hidp_del_timer(session); | 752 | hidp_del_timer(session); |
@@ -772,34 +780,37 @@ static int hidp_session(void *arg) | |||
772 | 780 | ||
773 | kfree(session->rd_data); | 781 | kfree(session->rd_data); |
774 | kfree(session); | 782 | kfree(session); |
783 | module_put_and_exit(0); | ||
775 | return 0; | 784 | return 0; |
776 | } | 785 | } |
777 | 786 | ||
778 | static struct device *hidp_get_device(struct hidp_session *session) | 787 | static struct hci_conn *hidp_get_connection(struct hidp_session *session) |
779 | { | 788 | { |
780 | bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src; | 789 | bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src; |
781 | bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst; | 790 | bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst; |
782 | struct device *device = NULL; | 791 | struct hci_conn *conn; |
783 | struct hci_dev *hdev; | 792 | struct hci_dev *hdev; |
784 | 793 | ||
785 | hdev = hci_get_route(dst, src); | 794 | hdev = hci_get_route(dst, src); |
786 | if (!hdev) | 795 | if (!hdev) |
787 | return NULL; | 796 | return NULL; |
788 | 797 | ||
789 | session->conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); | 798 | hci_dev_lock_bh(hdev); |
790 | if (session->conn) | 799 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); |
791 | device = &session->conn->dev; | 800 | if (conn) |
801 | hci_conn_hold_device(conn); | ||
802 | hci_dev_unlock_bh(hdev); | ||
792 | 803 | ||
793 | hci_dev_put(hdev); | 804 | hci_dev_put(hdev); |
794 | 805 | ||
795 | return device; | 806 | return conn; |
796 | } | 807 | } |
797 | 808 | ||
798 | static int hidp_setup_input(struct hidp_session *session, | 809 | static int hidp_setup_input(struct hidp_session *session, |
799 | struct hidp_connadd_req *req) | 810 | struct hidp_connadd_req *req) |
800 | { | 811 | { |
801 | struct input_dev *input; | 812 | struct input_dev *input; |
802 | int err, i; | 813 | int i; |
803 | 814 | ||
804 | input = input_allocate_device(); | 815 | input = input_allocate_device(); |
805 | if (!input) | 816 | if (!input) |
@@ -842,17 +853,10 @@ static int hidp_setup_input(struct hidp_session *session, | |||
842 | input->relbit[0] |= BIT_MASK(REL_WHEEL); | 853 | input->relbit[0] |= BIT_MASK(REL_WHEEL); |
843 | } | 854 | } |
844 | 855 | ||
845 | input->dev.parent = hidp_get_device(session); | 856 | input->dev.parent = &session->conn->dev; |
846 | 857 | ||
847 | input->event = hidp_input_event; | 858 | input->event = hidp_input_event; |
848 | 859 | ||
849 | err = input_register_device(input); | ||
850 | if (err < 0) { | ||
851 | input_free_device(input); | ||
852 | session->input = NULL; | ||
853 | return err; | ||
854 | } | ||
855 | |||
856 | return 0; | 860 | return 0; |
857 | } | 861 | } |
858 | 862 | ||
@@ -949,7 +953,7 @@ static int hidp_setup_hid(struct hidp_session *session, | |||
949 | strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64); | 953 | strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64); |
950 | strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64); | 954 | strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64); |
951 | 955 | ||
952 | hid->dev.parent = hidp_get_device(session); | 956 | hid->dev.parent = &session->conn->dev; |
953 | hid->ll_driver = &hidp_hid_driver; | 957 | hid->ll_driver = &hidp_hid_driver; |
954 | 958 | ||
955 | hid->hid_get_raw_report = hidp_get_raw_report; | 959 | hid->hid_get_raw_report = hidp_get_raw_report; |
@@ -976,18 +980,20 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
976 | bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst)) | 980 | bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst)) |
977 | return -ENOTUNIQ; | 981 | return -ENOTUNIQ; |
978 | 982 | ||
979 | session = kzalloc(sizeof(struct hidp_session), GFP_KERNEL); | ||
980 | if (!session) | ||
981 | return -ENOMEM; | ||
982 | |||
983 | BT_DBG("rd_data %p rd_size %d", req->rd_data, req->rd_size); | 983 | BT_DBG("rd_data %p rd_size %d", req->rd_data, req->rd_size); |
984 | 984 | ||
985 | down_write(&hidp_session_sem); | 985 | down_write(&hidp_session_sem); |
986 | 986 | ||
987 | s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst); | 987 | s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst); |
988 | if (s && s->state == BT_CONNECTED) { | 988 | if (s && s->state == BT_CONNECTED) { |
989 | err = -EEXIST; | 989 | up_write(&hidp_session_sem); |
990 | goto failed; | 990 | return -EEXIST; |
991 | } | ||
992 | |||
993 | session = kzalloc(sizeof(struct hidp_session), GFP_KERNEL); | ||
994 | if (!session) { | ||
995 | up_write(&hidp_session_sem); | ||
996 | return -ENOMEM; | ||
991 | } | 997 | } |
992 | 998 | ||
993 | bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst); | 999 | bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst); |
@@ -1003,6 +1009,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1003 | session->intr_sock = intr_sock; | 1009 | session->intr_sock = intr_sock; |
1004 | session->state = BT_CONNECTED; | 1010 | session->state = BT_CONNECTED; |
1005 | 1011 | ||
1012 | session->conn = hidp_get_connection(session); | ||
1013 | if (!session->conn) { | ||
1014 | err = -ENOTCONN; | ||
1015 | goto failed; | ||
1016 | } | ||
1017 | |||
1006 | setup_timer(&session->timer, hidp_idle_timeout, (unsigned long)session); | 1018 | setup_timer(&session->timer, hidp_idle_timeout, (unsigned long)session); |
1007 | 1019 | ||
1008 | skb_queue_head_init(&session->ctrl_transmit); | 1020 | skb_queue_head_init(&session->ctrl_transmit); |
@@ -1015,9 +1027,11 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1015 | session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); | 1027 | session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); |
1016 | session->idle_to = req->idle_to; | 1028 | session->idle_to = req->idle_to; |
1017 | 1029 | ||
1030 | __hidp_link_session(session); | ||
1031 | |||
1018 | if (req->rd_size > 0) { | 1032 | if (req->rd_size > 0) { |
1019 | err = hidp_setup_hid(session, req); | 1033 | err = hidp_setup_hid(session, req); |
1020 | if (err && err != -ENODEV) | 1034 | if (err) |
1021 | goto purge; | 1035 | goto purge; |
1022 | } | 1036 | } |
1023 | 1037 | ||
@@ -1027,8 +1041,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1027 | goto purge; | 1041 | goto purge; |
1028 | } | 1042 | } |
1029 | 1043 | ||
1030 | __hidp_link_session(session); | ||
1031 | |||
1032 | hidp_set_timer(session); | 1044 | hidp_set_timer(session); |
1033 | 1045 | ||
1034 | if (session->hid) { | 1046 | if (session->hid) { |
@@ -1054,7 +1066,11 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1054 | !session->waiting_for_startup); | 1066 | !session->waiting_for_startup); |
1055 | } | 1067 | } |
1056 | 1068 | ||
1057 | err = hid_add_device(session->hid); | 1069 | if (session->hid) |
1070 | err = hid_add_device(session->hid); | ||
1071 | else | ||
1072 | err = input_register_device(session->input); | ||
1073 | |||
1058 | if (err < 0) { | 1074 | if (err < 0) { |
1059 | atomic_inc(&session->terminate); | 1075 | atomic_inc(&session->terminate); |
1060 | wake_up_process(session->task); | 1076 | wake_up_process(session->task); |
@@ -1077,8 +1093,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1077 | unlink: | 1093 | unlink: |
1078 | hidp_del_timer(session); | 1094 | hidp_del_timer(session); |
1079 | 1095 | ||
1080 | __hidp_unlink_session(session); | ||
1081 | |||
1082 | if (session->input) { | 1096 | if (session->input) { |
1083 | input_unregister_device(session->input); | 1097 | input_unregister_device(session->input); |
1084 | session->input = NULL; | 1098 | session->input = NULL; |
@@ -1093,6 +1107,8 @@ unlink: | |||
1093 | session->rd_data = NULL; | 1107 | session->rd_data = NULL; |
1094 | 1108 | ||
1095 | purge: | 1109 | purge: |
1110 | __hidp_unlink_session(session); | ||
1111 | |||
1096 | skb_queue_purge(&session->ctrl_transmit); | 1112 | skb_queue_purge(&session->ctrl_transmit); |
1097 | skb_queue_purge(&session->intr_transmit); | 1113 | skb_queue_purge(&session->intr_transmit); |
1098 | 1114 | ||
@@ -1134,19 +1150,16 @@ int hidp_del_connection(struct hidp_conndel_req *req) | |||
1134 | 1150 | ||
1135 | int hidp_get_connlist(struct hidp_connlist_req *req) | 1151 | int hidp_get_connlist(struct hidp_connlist_req *req) |
1136 | { | 1152 | { |
1137 | struct list_head *p; | 1153 | struct hidp_session *session; |
1138 | int err = 0, n = 0; | 1154 | int err = 0, n = 0; |
1139 | 1155 | ||
1140 | BT_DBG(""); | 1156 | BT_DBG(""); |
1141 | 1157 | ||
1142 | down_read(&hidp_session_sem); | 1158 | down_read(&hidp_session_sem); |
1143 | 1159 | ||
1144 | list_for_each(p, &hidp_session_list) { | 1160 | list_for_each_entry(session, &hidp_session_list, list) { |
1145 | struct hidp_session *session; | ||
1146 | struct hidp_conninfo ci; | 1161 | struct hidp_conninfo ci; |
1147 | 1162 | ||
1148 | session = list_entry(p, struct hidp_session, list); | ||
1149 | |||
1150 | __hidp_copy_session(session, &ci); | 1163 | __hidp_copy_session(session, &ci); |
1151 | 1164 | ||
1152 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { | 1165 | if (copy_to_user(req->ci, &ci, sizeof(ci))) { |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 5ea94a1eecf2..e8a6837996cf 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -57,9 +57,10 @@ | |||
57 | #include <net/bluetooth/smp.h> | 57 | #include <net/bluetooth/smp.h> |
58 | 58 | ||
59 | int disable_ertm; | 59 | int disable_ertm; |
60 | int enable_hs; | ||
60 | 61 | ||
61 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; | 62 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; |
62 | static u8 l2cap_fixed_chan[8] = { 0x02, }; | 63 | static u8 l2cap_fixed_chan[8] = { L2CAP_FC_L2CAP, }; |
63 | 64 | ||
64 | static LIST_HEAD(chan_list); | 65 | static LIST_HEAD(chan_list); |
65 | static DEFINE_RWLOCK(chan_list_lock); | 66 | static DEFINE_RWLOCK(chan_list_lock); |
@@ -219,7 +220,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) | |||
219 | 220 | ||
220 | static void l2cap_set_timer(struct l2cap_chan *chan, struct timer_list *timer, long timeout) | 221 | static void l2cap_set_timer(struct l2cap_chan *chan, struct timer_list *timer, long timeout) |
221 | { | 222 | { |
222 | BT_DBG("chan %p state %d timeout %ld", chan->sk, chan->state, timeout); | 223 | BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout); |
223 | 224 | ||
224 | if (!mod_timer(timer, jiffies + msecs_to_jiffies(timeout))) | 225 | if (!mod_timer(timer, jiffies + msecs_to_jiffies(timeout))) |
225 | chan_hold(chan); | 226 | chan_hold(chan); |
@@ -293,6 +294,8 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk) | |||
293 | 294 | ||
294 | atomic_set(&chan->refcnt, 1); | 295 | atomic_set(&chan->refcnt, 1); |
295 | 296 | ||
297 | BT_DBG("sk %p chan %p", sk, chan); | ||
298 | |||
296 | return chan; | 299 | return chan; |
297 | } | 300 | } |
298 | 301 | ||
@@ -310,7 +313,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
310 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, | 313 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, |
311 | chan->psm, chan->dcid); | 314 | chan->psm, chan->dcid); |
312 | 315 | ||
313 | conn->disc_reason = 0x13; | 316 | conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM; |
314 | 317 | ||
315 | chan->conn = conn; | 318 | chan->conn = conn; |
316 | 319 | ||
@@ -337,6 +340,13 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
337 | chan->omtu = L2CAP_DEFAULT_MTU; | 340 | chan->omtu = L2CAP_DEFAULT_MTU; |
338 | } | 341 | } |
339 | 342 | ||
343 | chan->local_id = L2CAP_BESTEFFORT_ID; | ||
344 | chan->local_stype = L2CAP_SERV_BESTEFFORT; | ||
345 | chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE; | ||
346 | chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME; | ||
347 | chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT; | ||
348 | chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO; | ||
349 | |||
340 | chan_hold(chan); | 350 | chan_hold(chan); |
341 | 351 | ||
342 | list_add(&chan->list, &conn->chan_l); | 352 | list_add(&chan->list, &conn->chan_l); |
@@ -556,34 +566,58 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, | |||
556 | flags = ACL_START; | 566 | flags = ACL_START; |
557 | 567 | ||
558 | bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON; | 568 | bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON; |
569 | skb->priority = HCI_PRIO_MAX; | ||
570 | |||
571 | hci_send_acl(conn->hchan, skb, flags); | ||
572 | } | ||
573 | |||
574 | static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) | ||
575 | { | ||
576 | struct hci_conn *hcon = chan->conn->hcon; | ||
577 | u16 flags; | ||
578 | |||
579 | BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len, | ||
580 | skb->priority); | ||
581 | |||
582 | if (!test_bit(FLAG_FLUSHABLE, &chan->flags) && | ||
583 | lmp_no_flush_capable(hcon->hdev)) | ||
584 | flags = ACL_START_NO_FLUSH; | ||
585 | else | ||
586 | flags = ACL_START; | ||
559 | 587 | ||
560 | hci_send_acl(conn->hcon, skb, flags); | 588 | bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags); |
589 | hci_send_acl(chan->conn->hchan, skb, flags); | ||
561 | } | 590 | } |
562 | 591 | ||
563 | static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) | 592 | static inline void l2cap_send_sframe(struct l2cap_chan *chan, u32 control) |
564 | { | 593 | { |
565 | struct sk_buff *skb; | 594 | struct sk_buff *skb; |
566 | struct l2cap_hdr *lh; | 595 | struct l2cap_hdr *lh; |
567 | struct l2cap_conn *conn = chan->conn; | 596 | struct l2cap_conn *conn = chan->conn; |
568 | int count, hlen = L2CAP_HDR_SIZE + 2; | 597 | int count, hlen; |
569 | u8 flags; | ||
570 | 598 | ||
571 | if (chan->state != BT_CONNECTED) | 599 | if (chan->state != BT_CONNECTED) |
572 | return; | 600 | return; |
573 | 601 | ||
602 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
603 | hlen = L2CAP_EXT_HDR_SIZE; | ||
604 | else | ||
605 | hlen = L2CAP_ENH_HDR_SIZE; | ||
606 | |||
574 | if (chan->fcs == L2CAP_FCS_CRC16) | 607 | if (chan->fcs == L2CAP_FCS_CRC16) |
575 | hlen += 2; | 608 | hlen += L2CAP_FCS_SIZE; |
576 | 609 | ||
577 | BT_DBG("chan %p, control 0x%2.2x", chan, control); | 610 | BT_DBG("chan %p, control 0x%8.8x", chan, control); |
578 | 611 | ||
579 | count = min_t(unsigned int, conn->mtu, hlen); | 612 | count = min_t(unsigned int, conn->mtu, hlen); |
580 | control |= L2CAP_CTRL_FRAME_TYPE; | 613 | |
614 | control |= __set_sframe(chan); | ||
581 | 615 | ||
582 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) | 616 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) |
583 | control |= L2CAP_CTRL_FINAL; | 617 | control |= __set_ctrl_final(chan); |
584 | 618 | ||
585 | if (test_and_clear_bit(CONN_SEND_PBIT, &chan->conn_state)) | 619 | if (test_and_clear_bit(CONN_SEND_PBIT, &chan->conn_state)) |
586 | control |= L2CAP_CTRL_POLL; | 620 | control |= __set_ctrl_poll(chan); |
587 | 621 | ||
588 | skb = bt_skb_alloc(count, GFP_ATOMIC); | 622 | skb = bt_skb_alloc(count, GFP_ATOMIC); |
589 | if (!skb) | 623 | if (!skb) |
@@ -592,32 +626,27 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u16 control) | |||
592 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 626 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
593 | lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE); | 627 | lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE); |
594 | lh->cid = cpu_to_le16(chan->dcid); | 628 | lh->cid = cpu_to_le16(chan->dcid); |
595 | put_unaligned_le16(control, skb_put(skb, 2)); | 629 | |
630 | __put_control(chan, control, skb_put(skb, __ctrl_size(chan))); | ||
596 | 631 | ||
597 | if (chan->fcs == L2CAP_FCS_CRC16) { | 632 | if (chan->fcs == L2CAP_FCS_CRC16) { |
598 | u16 fcs = crc16(0, (u8 *)lh, count - 2); | 633 | u16 fcs = crc16(0, (u8 *)lh, count - L2CAP_FCS_SIZE); |
599 | put_unaligned_le16(fcs, skb_put(skb, 2)); | 634 | put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE)); |
600 | } | 635 | } |
601 | 636 | ||
602 | if (lmp_no_flush_capable(conn->hcon->hdev)) | 637 | skb->priority = HCI_PRIO_MAX; |
603 | flags = ACL_START_NO_FLUSH; | 638 | l2cap_do_send(chan, skb); |
604 | else | ||
605 | flags = ACL_START; | ||
606 | |||
607 | bt_cb(skb)->force_active = chan->force_active; | ||
608 | |||
609 | hci_send_acl(chan->conn->hcon, skb, flags); | ||
610 | } | 639 | } |
611 | 640 | ||
612 | static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u16 control) | 641 | static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u32 control) |
613 | { | 642 | { |
614 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { | 643 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { |
615 | control |= L2CAP_SUPER_RCV_NOT_READY; | 644 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); |
616 | set_bit(CONN_RNR_SENT, &chan->conn_state); | 645 | set_bit(CONN_RNR_SENT, &chan->conn_state); |
617 | } else | 646 | } else |
618 | control |= L2CAP_SUPER_RCV_READY; | 647 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); |
619 | 648 | ||
620 | control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 649 | control |= __set_reqseq(chan, chan->buffer_seq); |
621 | 650 | ||
622 | l2cap_send_sframe(chan, control); | 651 | l2cap_send_sframe(chan, control); |
623 | } | 652 | } |
@@ -947,7 +976,7 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) | |||
947 | list_for_each_entry(chan, &conn->chan_l, list) { | 976 | list_for_each_entry(chan, &conn->chan_l, list) { |
948 | struct sock *sk = chan->sk; | 977 | struct sock *sk = chan->sk; |
949 | 978 | ||
950 | if (chan->force_reliable) | 979 | if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) |
951 | sk->sk_err = err; | 980 | sk->sk_err = err; |
952 | } | 981 | } |
953 | 982 | ||
@@ -986,6 +1015,8 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
986 | chan->ops->close(chan->data); | 1015 | chan->ops->close(chan->data); |
987 | } | 1016 | } |
988 | 1017 | ||
1018 | hci_chan_del(conn->hchan); | ||
1019 | |||
989 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) | 1020 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) |
990 | del_timer_sync(&conn->info_timer); | 1021 | del_timer_sync(&conn->info_timer); |
991 | 1022 | ||
@@ -1008,18 +1039,26 @@ static void security_timeout(unsigned long arg) | |||
1008 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | 1039 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) |
1009 | { | 1040 | { |
1010 | struct l2cap_conn *conn = hcon->l2cap_data; | 1041 | struct l2cap_conn *conn = hcon->l2cap_data; |
1042 | struct hci_chan *hchan; | ||
1011 | 1043 | ||
1012 | if (conn || status) | 1044 | if (conn || status) |
1013 | return conn; | 1045 | return conn; |
1014 | 1046 | ||
1047 | hchan = hci_chan_create(hcon); | ||
1048 | if (!hchan) | ||
1049 | return NULL; | ||
1050 | |||
1015 | conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC); | 1051 | conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC); |
1016 | if (!conn) | 1052 | if (!conn) { |
1053 | hci_chan_del(hchan); | ||
1017 | return NULL; | 1054 | return NULL; |
1055 | } | ||
1018 | 1056 | ||
1019 | hcon->l2cap_data = conn; | 1057 | hcon->l2cap_data = conn; |
1020 | conn->hcon = hcon; | 1058 | conn->hcon = hcon; |
1059 | conn->hchan = hchan; | ||
1021 | 1060 | ||
1022 | BT_DBG("hcon %p conn %p", hcon, conn); | 1061 | BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); |
1023 | 1062 | ||
1024 | if (hcon->hdev->le_mtu && hcon->type == LE_LINK) | 1063 | if (hcon->hdev->le_mtu && hcon->type == LE_LINK) |
1025 | conn->mtu = hcon->hdev->le_mtu; | 1064 | conn->mtu = hcon->hdev->le_mtu; |
@@ -1043,7 +1082,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
1043 | setup_timer(&conn->info_timer, l2cap_info_timeout, | 1082 | setup_timer(&conn->info_timer, l2cap_info_timeout, |
1044 | (unsigned long) conn); | 1083 | (unsigned long) conn); |
1045 | 1084 | ||
1046 | conn->disc_reason = 0x13; | 1085 | conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM; |
1047 | 1086 | ||
1048 | return conn; | 1087 | return conn; |
1049 | } | 1088 | } |
@@ -1245,47 +1284,35 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan) | |||
1245 | __clear_retrans_timer(chan); | 1284 | __clear_retrans_timer(chan); |
1246 | } | 1285 | } |
1247 | 1286 | ||
1248 | static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) | ||
1249 | { | ||
1250 | struct hci_conn *hcon = chan->conn->hcon; | ||
1251 | u16 flags; | ||
1252 | |||
1253 | BT_DBG("chan %p, skb %p len %d", chan, skb, skb->len); | ||
1254 | |||
1255 | if (!chan->flushable && lmp_no_flush_capable(hcon->hdev)) | ||
1256 | flags = ACL_START_NO_FLUSH; | ||
1257 | else | ||
1258 | flags = ACL_START; | ||
1259 | |||
1260 | bt_cb(skb)->force_active = chan->force_active; | ||
1261 | hci_send_acl(hcon, skb, flags); | ||
1262 | } | ||
1263 | |||
1264 | static void l2cap_streaming_send(struct l2cap_chan *chan) | 1287 | static void l2cap_streaming_send(struct l2cap_chan *chan) |
1265 | { | 1288 | { |
1266 | struct sk_buff *skb; | 1289 | struct sk_buff *skb; |
1267 | u16 control, fcs; | 1290 | u32 control; |
1291 | u16 fcs; | ||
1268 | 1292 | ||
1269 | while ((skb = skb_dequeue(&chan->tx_q))) { | 1293 | while ((skb = skb_dequeue(&chan->tx_q))) { |
1270 | control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); | 1294 | control = __get_control(chan, skb->data + L2CAP_HDR_SIZE); |
1271 | control |= chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; | 1295 | control |= __set_txseq(chan, chan->next_tx_seq); |
1272 | put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); | 1296 | __put_control(chan, control, skb->data + L2CAP_HDR_SIZE); |
1273 | 1297 | ||
1274 | if (chan->fcs == L2CAP_FCS_CRC16) { | 1298 | if (chan->fcs == L2CAP_FCS_CRC16) { |
1275 | fcs = crc16(0, (u8 *)skb->data, skb->len - 2); | 1299 | fcs = crc16(0, (u8 *)skb->data, |
1276 | put_unaligned_le16(fcs, skb->data + skb->len - 2); | 1300 | skb->len - L2CAP_FCS_SIZE); |
1301 | put_unaligned_le16(fcs, | ||
1302 | skb->data + skb->len - L2CAP_FCS_SIZE); | ||
1277 | } | 1303 | } |
1278 | 1304 | ||
1279 | l2cap_do_send(chan, skb); | 1305 | l2cap_do_send(chan, skb); |
1280 | 1306 | ||
1281 | chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; | 1307 | chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq); |
1282 | } | 1308 | } |
1283 | } | 1309 | } |
1284 | 1310 | ||
1285 | static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) | 1311 | static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u16 tx_seq) |
1286 | { | 1312 | { |
1287 | struct sk_buff *skb, *tx_skb; | 1313 | struct sk_buff *skb, *tx_skb; |
1288 | u16 control, fcs; | 1314 | u16 fcs; |
1315 | u32 control; | ||
1289 | 1316 | ||
1290 | skb = skb_peek(&chan->tx_q); | 1317 | skb = skb_peek(&chan->tx_q); |
1291 | if (!skb) | 1318 | if (!skb) |
@@ -1308,20 +1335,23 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) | |||
1308 | 1335 | ||
1309 | tx_skb = skb_clone(skb, GFP_ATOMIC); | 1336 | tx_skb = skb_clone(skb, GFP_ATOMIC); |
1310 | bt_cb(skb)->retries++; | 1337 | bt_cb(skb)->retries++; |
1311 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1338 | |
1312 | control &= L2CAP_CTRL_SAR; | 1339 | control = __get_control(chan, tx_skb->data + L2CAP_HDR_SIZE); |
1340 | control &= __get_sar_mask(chan); | ||
1313 | 1341 | ||
1314 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) | 1342 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) |
1315 | control |= L2CAP_CTRL_FINAL; | 1343 | control |= __set_ctrl_final(chan); |
1316 | 1344 | ||
1317 | control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1345 | control |= __set_reqseq(chan, chan->buffer_seq); |
1318 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1346 | control |= __set_txseq(chan, tx_seq); |
1319 | 1347 | ||
1320 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1348 | __put_control(chan, control, tx_skb->data + L2CAP_HDR_SIZE); |
1321 | 1349 | ||
1322 | if (chan->fcs == L2CAP_FCS_CRC16) { | 1350 | if (chan->fcs == L2CAP_FCS_CRC16) { |
1323 | fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); | 1351 | fcs = crc16(0, (u8 *)tx_skb->data, |
1324 | put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); | 1352 | tx_skb->len - L2CAP_FCS_SIZE); |
1353 | put_unaligned_le16(fcs, | ||
1354 | tx_skb->data + tx_skb->len - L2CAP_FCS_SIZE); | ||
1325 | } | 1355 | } |
1326 | 1356 | ||
1327 | l2cap_do_send(chan, tx_skb); | 1357 | l2cap_do_send(chan, tx_skb); |
@@ -1330,7 +1360,8 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u8 tx_seq) | |||
1330 | static int l2cap_ertm_send(struct l2cap_chan *chan) | 1360 | static int l2cap_ertm_send(struct l2cap_chan *chan) |
1331 | { | 1361 | { |
1332 | struct sk_buff *skb, *tx_skb; | 1362 | struct sk_buff *skb, *tx_skb; |
1333 | u16 control, fcs; | 1363 | u16 fcs; |
1364 | u32 control; | ||
1334 | int nsent = 0; | 1365 | int nsent = 0; |
1335 | 1366 | ||
1336 | if (chan->state != BT_CONNECTED) | 1367 | if (chan->state != BT_CONNECTED) |
@@ -1348,20 +1379,22 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) | |||
1348 | 1379 | ||
1349 | bt_cb(skb)->retries++; | 1380 | bt_cb(skb)->retries++; |
1350 | 1381 | ||
1351 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1382 | control = __get_control(chan, tx_skb->data + L2CAP_HDR_SIZE); |
1352 | control &= L2CAP_CTRL_SAR; | 1383 | control &= __get_sar_mask(chan); |
1353 | 1384 | ||
1354 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) | 1385 | if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) |
1355 | control |= L2CAP_CTRL_FINAL; | 1386 | control |= __set_ctrl_final(chan); |
1356 | 1387 | ||
1357 | control |= (chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1388 | control |= __set_reqseq(chan, chan->buffer_seq); |
1358 | | (chan->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1389 | control |= __set_txseq(chan, chan->next_tx_seq); |
1359 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | ||
1360 | 1390 | ||
1391 | __put_control(chan, control, tx_skb->data + L2CAP_HDR_SIZE); | ||
1361 | 1392 | ||
1362 | if (chan->fcs == L2CAP_FCS_CRC16) { | 1393 | if (chan->fcs == L2CAP_FCS_CRC16) { |
1363 | fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2); | 1394 | fcs = crc16(0, (u8 *)skb->data, |
1364 | put_unaligned_le16(fcs, skb->data + tx_skb->len - 2); | 1395 | tx_skb->len - L2CAP_FCS_SIZE); |
1396 | put_unaligned_le16(fcs, skb->data + | ||
1397 | tx_skb->len - L2CAP_FCS_SIZE); | ||
1365 | } | 1398 | } |
1366 | 1399 | ||
1367 | l2cap_do_send(chan, tx_skb); | 1400 | l2cap_do_send(chan, tx_skb); |
@@ -1369,7 +1402,8 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) | |||
1369 | __set_retrans_timer(chan); | 1402 | __set_retrans_timer(chan); |
1370 | 1403 | ||
1371 | bt_cb(skb)->tx_seq = chan->next_tx_seq; | 1404 | bt_cb(skb)->tx_seq = chan->next_tx_seq; |
1372 | chan->next_tx_seq = (chan->next_tx_seq + 1) % 64; | 1405 | |
1406 | chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq); | ||
1373 | 1407 | ||
1374 | if (bt_cb(skb)->retries == 1) | 1408 | if (bt_cb(skb)->retries == 1) |
1375 | chan->unacked_frames++; | 1409 | chan->unacked_frames++; |
@@ -1401,12 +1435,12 @@ static int l2cap_retransmit_frames(struct l2cap_chan *chan) | |||
1401 | 1435 | ||
1402 | static void l2cap_send_ack(struct l2cap_chan *chan) | 1436 | static void l2cap_send_ack(struct l2cap_chan *chan) |
1403 | { | 1437 | { |
1404 | u16 control = 0; | 1438 | u32 control = 0; |
1405 | 1439 | ||
1406 | control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 1440 | control |= __set_reqseq(chan, chan->buffer_seq); |
1407 | 1441 | ||
1408 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { | 1442 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { |
1409 | control |= L2CAP_SUPER_RCV_NOT_READY; | 1443 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); |
1410 | set_bit(CONN_RNR_SENT, &chan->conn_state); | 1444 | set_bit(CONN_RNR_SENT, &chan->conn_state); |
1411 | l2cap_send_sframe(chan, control); | 1445 | l2cap_send_sframe(chan, control); |
1412 | return; | 1446 | return; |
@@ -1415,20 +1449,20 @@ static void l2cap_send_ack(struct l2cap_chan *chan) | |||
1415 | if (l2cap_ertm_send(chan) > 0) | 1449 | if (l2cap_ertm_send(chan) > 0) |
1416 | return; | 1450 | return; |
1417 | 1451 | ||
1418 | control |= L2CAP_SUPER_RCV_READY; | 1452 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); |
1419 | l2cap_send_sframe(chan, control); | 1453 | l2cap_send_sframe(chan, control); |
1420 | } | 1454 | } |
1421 | 1455 | ||
1422 | static void l2cap_send_srejtail(struct l2cap_chan *chan) | 1456 | static void l2cap_send_srejtail(struct l2cap_chan *chan) |
1423 | { | 1457 | { |
1424 | struct srej_list *tail; | 1458 | struct srej_list *tail; |
1425 | u16 control; | 1459 | u32 control; |
1426 | 1460 | ||
1427 | control = L2CAP_SUPER_SELECT_REJECT; | 1461 | control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); |
1428 | control |= L2CAP_CTRL_FINAL; | 1462 | control |= __set_ctrl_final(chan); |
1429 | 1463 | ||
1430 | tail = list_entry((&chan->srej_l)->prev, struct srej_list, list); | 1464 | tail = list_entry((&chan->srej_l)->prev, struct srej_list, list); |
1431 | control |= tail->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 1465 | control |= __set_reqseq(chan, tail->tx_seq); |
1432 | 1466 | ||
1433 | l2cap_send_sframe(chan, control); | 1467 | l2cap_send_sframe(chan, control); |
1434 | } | 1468 | } |
@@ -1456,6 +1490,8 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in | |||
1456 | if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) | 1490 | if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) |
1457 | return -EFAULT; | 1491 | return -EFAULT; |
1458 | 1492 | ||
1493 | (*frag)->priority = skb->priority; | ||
1494 | |||
1459 | sent += count; | 1495 | sent += count; |
1460 | len -= count; | 1496 | len -= count; |
1461 | 1497 | ||
@@ -1465,15 +1501,17 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in | |||
1465 | return sent; | 1501 | return sent; |
1466 | } | 1502 | } |
1467 | 1503 | ||
1468 | static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | 1504 | static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, |
1505 | struct msghdr *msg, size_t len, | ||
1506 | u32 priority) | ||
1469 | { | 1507 | { |
1470 | struct sock *sk = chan->sk; | 1508 | struct sock *sk = chan->sk; |
1471 | struct l2cap_conn *conn = chan->conn; | 1509 | struct l2cap_conn *conn = chan->conn; |
1472 | struct sk_buff *skb; | 1510 | struct sk_buff *skb; |
1473 | int err, count, hlen = L2CAP_HDR_SIZE + 2; | 1511 | int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE; |
1474 | struct l2cap_hdr *lh; | 1512 | struct l2cap_hdr *lh; |
1475 | 1513 | ||
1476 | BT_DBG("sk %p len %d", sk, (int)len); | 1514 | BT_DBG("sk %p len %d priority %u", sk, (int)len, priority); |
1477 | 1515 | ||
1478 | count = min_t(unsigned int, (conn->mtu - hlen), len); | 1516 | count = min_t(unsigned int, (conn->mtu - hlen), len); |
1479 | skb = bt_skb_send_alloc(sk, count + hlen, | 1517 | skb = bt_skb_send_alloc(sk, count + hlen, |
@@ -1481,6 +1519,8 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct | |||
1481 | if (!skb) | 1519 | if (!skb) |
1482 | return ERR_PTR(err); | 1520 | return ERR_PTR(err); |
1483 | 1521 | ||
1522 | skb->priority = priority; | ||
1523 | |||
1484 | /* Create L2CAP header */ | 1524 | /* Create L2CAP header */ |
1485 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 1525 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
1486 | lh->cid = cpu_to_le16(chan->dcid); | 1526 | lh->cid = cpu_to_le16(chan->dcid); |
@@ -1495,7 +1535,9 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, struct | |||
1495 | return skb; | 1535 | return skb; |
1496 | } | 1536 | } |
1497 | 1537 | ||
1498 | static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | 1538 | static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, |
1539 | struct msghdr *msg, size_t len, | ||
1540 | u32 priority) | ||
1499 | { | 1541 | { |
1500 | struct sock *sk = chan->sk; | 1542 | struct sock *sk = chan->sk; |
1501 | struct l2cap_conn *conn = chan->conn; | 1543 | struct l2cap_conn *conn = chan->conn; |
@@ -1511,6 +1553,8 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct ms | |||
1511 | if (!skb) | 1553 | if (!skb) |
1512 | return ERR_PTR(err); | 1554 | return ERR_PTR(err); |
1513 | 1555 | ||
1556 | skb->priority = priority; | ||
1557 | |||
1514 | /* Create L2CAP header */ | 1558 | /* Create L2CAP header */ |
1515 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 1559 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
1516 | lh->cid = cpu_to_le16(chan->dcid); | 1560 | lh->cid = cpu_to_le16(chan->dcid); |
@@ -1526,12 +1570,12 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, struct ms | |||
1526 | 1570 | ||
1527 | static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, | 1571 | static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, |
1528 | struct msghdr *msg, size_t len, | 1572 | struct msghdr *msg, size_t len, |
1529 | u16 control, u16 sdulen) | 1573 | u32 control, u16 sdulen) |
1530 | { | 1574 | { |
1531 | struct sock *sk = chan->sk; | 1575 | struct sock *sk = chan->sk; |
1532 | struct l2cap_conn *conn = chan->conn; | 1576 | struct l2cap_conn *conn = chan->conn; |
1533 | struct sk_buff *skb; | 1577 | struct sk_buff *skb; |
1534 | int err, count, hlen = L2CAP_HDR_SIZE + 2; | 1578 | int err, count, hlen; |
1535 | struct l2cap_hdr *lh; | 1579 | struct l2cap_hdr *lh; |
1536 | 1580 | ||
1537 | BT_DBG("sk %p len %d", sk, (int)len); | 1581 | BT_DBG("sk %p len %d", sk, (int)len); |
@@ -1539,11 +1583,16 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, | |||
1539 | if (!conn) | 1583 | if (!conn) |
1540 | return ERR_PTR(-ENOTCONN); | 1584 | return ERR_PTR(-ENOTCONN); |
1541 | 1585 | ||
1586 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
1587 | hlen = L2CAP_EXT_HDR_SIZE; | ||
1588 | else | ||
1589 | hlen = L2CAP_ENH_HDR_SIZE; | ||
1590 | |||
1542 | if (sdulen) | 1591 | if (sdulen) |
1543 | hlen += 2; | 1592 | hlen += L2CAP_SDULEN_SIZE; |
1544 | 1593 | ||
1545 | if (chan->fcs == L2CAP_FCS_CRC16) | 1594 | if (chan->fcs == L2CAP_FCS_CRC16) |
1546 | hlen += 2; | 1595 | hlen += L2CAP_FCS_SIZE; |
1547 | 1596 | ||
1548 | count = min_t(unsigned int, (conn->mtu - hlen), len); | 1597 | count = min_t(unsigned int, (conn->mtu - hlen), len); |
1549 | skb = bt_skb_send_alloc(sk, count + hlen, | 1598 | skb = bt_skb_send_alloc(sk, count + hlen, |
@@ -1555,9 +1604,11 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, | |||
1555 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 1604 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
1556 | lh->cid = cpu_to_le16(chan->dcid); | 1605 | lh->cid = cpu_to_le16(chan->dcid); |
1557 | lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); | 1606 | lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); |
1558 | put_unaligned_le16(control, skb_put(skb, 2)); | 1607 | |
1608 | __put_control(chan, control, skb_put(skb, __ctrl_size(chan))); | ||
1609 | |||
1559 | if (sdulen) | 1610 | if (sdulen) |
1560 | put_unaligned_le16(sdulen, skb_put(skb, 2)); | 1611 | put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE)); |
1561 | 1612 | ||
1562 | err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb); | 1613 | err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb); |
1563 | if (unlikely(err < 0)) { | 1614 | if (unlikely(err < 0)) { |
@@ -1566,7 +1617,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, | |||
1566 | } | 1617 | } |
1567 | 1618 | ||
1568 | if (chan->fcs == L2CAP_FCS_CRC16) | 1619 | if (chan->fcs == L2CAP_FCS_CRC16) |
1569 | put_unaligned_le16(0, skb_put(skb, 2)); | 1620 | put_unaligned_le16(0, skb_put(skb, L2CAP_FCS_SIZE)); |
1570 | 1621 | ||
1571 | bt_cb(skb)->retries = 0; | 1622 | bt_cb(skb)->retries = 0; |
1572 | return skb; | 1623 | return skb; |
@@ -1576,11 +1627,11 @@ static int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, si | |||
1576 | { | 1627 | { |
1577 | struct sk_buff *skb; | 1628 | struct sk_buff *skb; |
1578 | struct sk_buff_head sar_queue; | 1629 | struct sk_buff_head sar_queue; |
1579 | u16 control; | 1630 | u32 control; |
1580 | size_t size = 0; | 1631 | size_t size = 0; |
1581 | 1632 | ||
1582 | skb_queue_head_init(&sar_queue); | 1633 | skb_queue_head_init(&sar_queue); |
1583 | control = L2CAP_SDU_START; | 1634 | control = __set_ctrl_sar(chan, L2CAP_SAR_START); |
1584 | skb = l2cap_create_iframe_pdu(chan, msg, chan->remote_mps, control, len); | 1635 | skb = l2cap_create_iframe_pdu(chan, msg, chan->remote_mps, control, len); |
1585 | if (IS_ERR(skb)) | 1636 | if (IS_ERR(skb)) |
1586 | return PTR_ERR(skb); | 1637 | return PTR_ERR(skb); |
@@ -1593,10 +1644,10 @@ static int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, si | |||
1593 | size_t buflen; | 1644 | size_t buflen; |
1594 | 1645 | ||
1595 | if (len > chan->remote_mps) { | 1646 | if (len > chan->remote_mps) { |
1596 | control = L2CAP_SDU_CONTINUE; | 1647 | control = __set_ctrl_sar(chan, L2CAP_SAR_CONTINUE); |
1597 | buflen = chan->remote_mps; | 1648 | buflen = chan->remote_mps; |
1598 | } else { | 1649 | } else { |
1599 | control = L2CAP_SDU_END; | 1650 | control = __set_ctrl_sar(chan, L2CAP_SAR_END); |
1600 | buflen = len; | 1651 | buflen = len; |
1601 | } | 1652 | } |
1602 | 1653 | ||
@@ -1617,15 +1668,16 @@ static int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, si | |||
1617 | return size; | 1668 | return size; |
1618 | } | 1669 | } |
1619 | 1670 | ||
1620 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | 1671 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, |
1672 | u32 priority) | ||
1621 | { | 1673 | { |
1622 | struct sk_buff *skb; | 1674 | struct sk_buff *skb; |
1623 | u16 control; | 1675 | u32 control; |
1624 | int err; | 1676 | int err; |
1625 | 1677 | ||
1626 | /* Connectionless channel */ | 1678 | /* Connectionless channel */ |
1627 | if (chan->chan_type == L2CAP_CHAN_CONN_LESS) { | 1679 | if (chan->chan_type == L2CAP_CHAN_CONN_LESS) { |
1628 | skb = l2cap_create_connless_pdu(chan, msg, len); | 1680 | skb = l2cap_create_connless_pdu(chan, msg, len, priority); |
1629 | if (IS_ERR(skb)) | 1681 | if (IS_ERR(skb)) |
1630 | return PTR_ERR(skb); | 1682 | return PTR_ERR(skb); |
1631 | 1683 | ||
@@ -1640,7 +1692,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | |||
1640 | return -EMSGSIZE; | 1692 | return -EMSGSIZE; |
1641 | 1693 | ||
1642 | /* Create a basic PDU */ | 1694 | /* Create a basic PDU */ |
1643 | skb = l2cap_create_basic_pdu(chan, msg, len); | 1695 | skb = l2cap_create_basic_pdu(chan, msg, len, priority); |
1644 | if (IS_ERR(skb)) | 1696 | if (IS_ERR(skb)) |
1645 | return PTR_ERR(skb); | 1697 | return PTR_ERR(skb); |
1646 | 1698 | ||
@@ -1652,7 +1704,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) | |||
1652 | case L2CAP_MODE_STREAMING: | 1704 | case L2CAP_MODE_STREAMING: |
1653 | /* Entire SDU fits into one PDU */ | 1705 | /* Entire SDU fits into one PDU */ |
1654 | if (len <= chan->remote_mps) { | 1706 | if (len <= chan->remote_mps) { |
1655 | control = L2CAP_SDU_UNSEGMENTED; | 1707 | control = __set_ctrl_sar(chan, L2CAP_SAR_UNSEGMENTED); |
1656 | skb = l2cap_create_iframe_pdu(chan, msg, len, control, | 1708 | skb = l2cap_create_iframe_pdu(chan, msg, len, control, |
1657 | 0); | 1709 | 0); |
1658 | if (IS_ERR(skb)) | 1710 | if (IS_ERR(skb)) |
@@ -1850,6 +1902,37 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) | |||
1850 | *ptr += L2CAP_CONF_OPT_SIZE + len; | 1902 | *ptr += L2CAP_CONF_OPT_SIZE + len; |
1851 | } | 1903 | } |
1852 | 1904 | ||
1905 | static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) | ||
1906 | { | ||
1907 | struct l2cap_conf_efs efs; | ||
1908 | |||
1909 | switch(chan->mode) { | ||
1910 | case L2CAP_MODE_ERTM: | ||
1911 | efs.id = chan->local_id; | ||
1912 | efs.stype = chan->local_stype; | ||
1913 | efs.msdu = cpu_to_le16(chan->local_msdu); | ||
1914 | efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime); | ||
1915 | efs.acc_lat = cpu_to_le32(L2CAP_DEFAULT_ACC_LAT); | ||
1916 | efs.flush_to = cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO); | ||
1917 | break; | ||
1918 | |||
1919 | case L2CAP_MODE_STREAMING: | ||
1920 | efs.id = 1; | ||
1921 | efs.stype = L2CAP_SERV_BESTEFFORT; | ||
1922 | efs.msdu = cpu_to_le16(chan->local_msdu); | ||
1923 | efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime); | ||
1924 | efs.acc_lat = 0; | ||
1925 | efs.flush_to = 0; | ||
1926 | break; | ||
1927 | |||
1928 | default: | ||
1929 | return; | ||
1930 | } | ||
1931 | |||
1932 | l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs), | ||
1933 | (unsigned long) &efs); | ||
1934 | } | ||
1935 | |||
1853 | static void l2cap_ack_timeout(unsigned long arg) | 1936 | static void l2cap_ack_timeout(unsigned long arg) |
1854 | { | 1937 | { |
1855 | struct l2cap_chan *chan = (void *) arg; | 1938 | struct l2cap_chan *chan = (void *) arg; |
@@ -1896,11 +1979,36 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) | |||
1896 | } | 1979 | } |
1897 | } | 1980 | } |
1898 | 1981 | ||
1982 | static inline bool __l2cap_ews_supported(struct l2cap_chan *chan) | ||
1983 | { | ||
1984 | return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_WINDOW; | ||
1985 | } | ||
1986 | |||
1987 | static inline bool __l2cap_efs_supported(struct l2cap_chan *chan) | ||
1988 | { | ||
1989 | return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW; | ||
1990 | } | ||
1991 | |||
1992 | static inline void l2cap_txwin_setup(struct l2cap_chan *chan) | ||
1993 | { | ||
1994 | if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW && | ||
1995 | __l2cap_ews_supported(chan)) { | ||
1996 | /* use extended control field */ | ||
1997 | set_bit(FLAG_EXT_CTRL, &chan->flags); | ||
1998 | chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW; | ||
1999 | } else { | ||
2000 | chan->tx_win = min_t(u16, chan->tx_win, | ||
2001 | L2CAP_DEFAULT_TX_WINDOW); | ||
2002 | chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; | ||
2003 | } | ||
2004 | } | ||
2005 | |||
1899 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | 2006 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) |
1900 | { | 2007 | { |
1901 | struct l2cap_conf_req *req = data; | 2008 | struct l2cap_conf_req *req = data; |
1902 | struct l2cap_conf_rfc rfc = { .mode = chan->mode }; | 2009 | struct l2cap_conf_rfc rfc = { .mode = chan->mode }; |
1903 | void *ptr = req->data; | 2010 | void *ptr = req->data; |
2011 | u16 size; | ||
1904 | 2012 | ||
1905 | BT_DBG("chan %p", chan); | 2013 | BT_DBG("chan %p", chan); |
1906 | 2014 | ||
@@ -1913,6 +2021,9 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | |||
1913 | if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) | 2021 | if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) |
1914 | break; | 2022 | break; |
1915 | 2023 | ||
2024 | if (__l2cap_efs_supported(chan)) | ||
2025 | set_bit(FLAG_EFS_ENABLE, &chan->flags); | ||
2026 | |||
1916 | /* fall through */ | 2027 | /* fall through */ |
1917 | default: | 2028 | default: |
1918 | chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask); | 2029 | chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask); |
@@ -1942,17 +2053,27 @@ done: | |||
1942 | 2053 | ||
1943 | case L2CAP_MODE_ERTM: | 2054 | case L2CAP_MODE_ERTM: |
1944 | rfc.mode = L2CAP_MODE_ERTM; | 2055 | rfc.mode = L2CAP_MODE_ERTM; |
1945 | rfc.txwin_size = chan->tx_win; | ||
1946 | rfc.max_transmit = chan->max_tx; | 2056 | rfc.max_transmit = chan->max_tx; |
1947 | rfc.retrans_timeout = 0; | 2057 | rfc.retrans_timeout = 0; |
1948 | rfc.monitor_timeout = 0; | 2058 | rfc.monitor_timeout = 0; |
1949 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); | 2059 | |
1950 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > chan->conn->mtu - 10) | 2060 | size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu - |
1951 | rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); | 2061 | L2CAP_EXT_HDR_SIZE - |
2062 | L2CAP_SDULEN_SIZE - | ||
2063 | L2CAP_FCS_SIZE); | ||
2064 | rfc.max_pdu_size = cpu_to_le16(size); | ||
2065 | |||
2066 | l2cap_txwin_setup(chan); | ||
2067 | |||
2068 | rfc.txwin_size = min_t(u16, chan->tx_win, | ||
2069 | L2CAP_DEFAULT_TX_WINDOW); | ||
1952 | 2070 | ||
1953 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | 2071 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), |
1954 | (unsigned long) &rfc); | 2072 | (unsigned long) &rfc); |
1955 | 2073 | ||
2074 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) | ||
2075 | l2cap_add_opt_efs(&ptr, chan); | ||
2076 | |||
1956 | if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) | 2077 | if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) |
1957 | break; | 2078 | break; |
1958 | 2079 | ||
@@ -1961,6 +2082,10 @@ done: | |||
1961 | chan->fcs = L2CAP_FCS_NONE; | 2082 | chan->fcs = L2CAP_FCS_NONE; |
1962 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); | 2083 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); |
1963 | } | 2084 | } |
2085 | |||
2086 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
2087 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, | ||
2088 | chan->tx_win); | ||
1964 | break; | 2089 | break; |
1965 | 2090 | ||
1966 | case L2CAP_MODE_STREAMING: | 2091 | case L2CAP_MODE_STREAMING: |
@@ -1969,13 +2094,19 @@ done: | |||
1969 | rfc.max_transmit = 0; | 2094 | rfc.max_transmit = 0; |
1970 | rfc.retrans_timeout = 0; | 2095 | rfc.retrans_timeout = 0; |
1971 | rfc.monitor_timeout = 0; | 2096 | rfc.monitor_timeout = 0; |
1972 | rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE); | 2097 | |
1973 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > chan->conn->mtu - 10) | 2098 | size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu - |
1974 | rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); | 2099 | L2CAP_EXT_HDR_SIZE - |
2100 | L2CAP_SDULEN_SIZE - | ||
2101 | L2CAP_FCS_SIZE); | ||
2102 | rfc.max_pdu_size = cpu_to_le16(size); | ||
1975 | 2103 | ||
1976 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | 2104 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), |
1977 | (unsigned long) &rfc); | 2105 | (unsigned long) &rfc); |
1978 | 2106 | ||
2107 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) | ||
2108 | l2cap_add_opt_efs(&ptr, chan); | ||
2109 | |||
1979 | if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) | 2110 | if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) |
1980 | break; | 2111 | break; |
1981 | 2112 | ||
@@ -2002,8 +2133,11 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | |||
2002 | int type, hint, olen; | 2133 | int type, hint, olen; |
2003 | unsigned long val; | 2134 | unsigned long val; |
2004 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; | 2135 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; |
2136 | struct l2cap_conf_efs efs; | ||
2137 | u8 remote_efs = 0; | ||
2005 | u16 mtu = L2CAP_DEFAULT_MTU; | 2138 | u16 mtu = L2CAP_DEFAULT_MTU; |
2006 | u16 result = L2CAP_CONF_SUCCESS; | 2139 | u16 result = L2CAP_CONF_SUCCESS; |
2140 | u16 size; | ||
2007 | 2141 | ||
2008 | BT_DBG("chan %p", chan); | 2142 | BT_DBG("chan %p", chan); |
2009 | 2143 | ||
@@ -2033,7 +2167,22 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | |||
2033 | case L2CAP_CONF_FCS: | 2167 | case L2CAP_CONF_FCS: |
2034 | if (val == L2CAP_FCS_NONE) | 2168 | if (val == L2CAP_FCS_NONE) |
2035 | set_bit(CONF_NO_FCS_RECV, &chan->conf_state); | 2169 | set_bit(CONF_NO_FCS_RECV, &chan->conf_state); |
2170 | break; | ||
2171 | |||
2172 | case L2CAP_CONF_EFS: | ||
2173 | remote_efs = 1; | ||
2174 | if (olen == sizeof(efs)) | ||
2175 | memcpy(&efs, (void *) val, olen); | ||
2176 | break; | ||
2177 | |||
2178 | case L2CAP_CONF_EWS: | ||
2179 | if (!enable_hs) | ||
2180 | return -ECONNREFUSED; | ||
2036 | 2181 | ||
2182 | set_bit(FLAG_EXT_CTRL, &chan->flags); | ||
2183 | set_bit(CONF_EWS_RECV, &chan->conf_state); | ||
2184 | chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW; | ||
2185 | chan->remote_tx_win = val; | ||
2037 | break; | 2186 | break; |
2038 | 2187 | ||
2039 | default: | 2188 | default: |
@@ -2058,6 +2207,13 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) | |||
2058 | break; | 2207 | break; |
2059 | } | 2208 | } |
2060 | 2209 | ||
2210 | if (remote_efs) { | ||
2211 | if (__l2cap_efs_supported(chan)) | ||
2212 | set_bit(FLAG_EFS_ENABLE, &chan->flags); | ||
2213 | else | ||
2214 | return -ECONNREFUSED; | ||
2215 | } | ||
2216 | |||
2061 | if (chan->mode != rfc.mode) | 2217 | if (chan->mode != rfc.mode) |
2062 | return -ECONNREFUSED; | 2218 | return -ECONNREFUSED; |
2063 | 2219 | ||
@@ -2076,7 +2232,6 @@ done: | |||
2076 | sizeof(rfc), (unsigned long) &rfc); | 2232 | sizeof(rfc), (unsigned long) &rfc); |
2077 | } | 2233 | } |
2078 | 2234 | ||
2079 | |||
2080 | if (result == L2CAP_CONF_SUCCESS) { | 2235 | if (result == L2CAP_CONF_SUCCESS) { |
2081 | /* Configure output options and let the other side know | 2236 | /* Configure output options and let the other side know |
2082 | * which ones we don't like. */ | 2237 | * which ones we don't like. */ |
@@ -2089,6 +2244,26 @@ done: | |||
2089 | } | 2244 | } |
2090 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu); | 2245 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu); |
2091 | 2246 | ||
2247 | if (remote_efs) { | ||
2248 | if (chan->local_stype != L2CAP_SERV_NOTRAFIC && | ||
2249 | efs.stype != L2CAP_SERV_NOTRAFIC && | ||
2250 | efs.stype != chan->local_stype) { | ||
2251 | |||
2252 | result = L2CAP_CONF_UNACCEPT; | ||
2253 | |||
2254 | if (chan->num_conf_req >= 1) | ||
2255 | return -ECONNREFUSED; | ||
2256 | |||
2257 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, | ||
2258 | sizeof(efs), | ||
2259 | (unsigned long) &efs); | ||
2260 | } else { | ||
2261 | /* Send PENDING Conf Rsp */ | ||
2262 | result = L2CAP_CONF_PENDING; | ||
2263 | set_bit(CONF_LOC_CONF_PEND, &chan->conf_state); | ||
2264 | } | ||
2265 | } | ||
2266 | |||
2092 | switch (rfc.mode) { | 2267 | switch (rfc.mode) { |
2093 | case L2CAP_MODE_BASIC: | 2268 | case L2CAP_MODE_BASIC: |
2094 | chan->fcs = L2CAP_FCS_NONE; | 2269 | chan->fcs = L2CAP_FCS_NONE; |
@@ -2096,13 +2271,20 @@ done: | |||
2096 | break; | 2271 | break; |
2097 | 2272 | ||
2098 | case L2CAP_MODE_ERTM: | 2273 | case L2CAP_MODE_ERTM: |
2099 | chan->remote_tx_win = rfc.txwin_size; | 2274 | if (!test_bit(CONF_EWS_RECV, &chan->conf_state)) |
2100 | chan->remote_max_tx = rfc.max_transmit; | 2275 | chan->remote_tx_win = rfc.txwin_size; |
2276 | else | ||
2277 | rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW; | ||
2101 | 2278 | ||
2102 | if (le16_to_cpu(rfc.max_pdu_size) > chan->conn->mtu - 10) | 2279 | chan->remote_max_tx = rfc.max_transmit; |
2103 | rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); | ||
2104 | 2280 | ||
2105 | chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); | 2281 | size = min_t(u16, le16_to_cpu(rfc.max_pdu_size), |
2282 | chan->conn->mtu - | ||
2283 | L2CAP_EXT_HDR_SIZE - | ||
2284 | L2CAP_SDULEN_SIZE - | ||
2285 | L2CAP_FCS_SIZE); | ||
2286 | rfc.max_pdu_size = cpu_to_le16(size); | ||
2287 | chan->remote_mps = size; | ||
2106 | 2288 | ||
2107 | rfc.retrans_timeout = | 2289 | rfc.retrans_timeout = |
2108 | le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO); | 2290 | le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO); |
@@ -2114,13 +2296,29 @@ done: | |||
2114 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 2296 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
2115 | sizeof(rfc), (unsigned long) &rfc); | 2297 | sizeof(rfc), (unsigned long) &rfc); |
2116 | 2298 | ||
2299 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { | ||
2300 | chan->remote_id = efs.id; | ||
2301 | chan->remote_stype = efs.stype; | ||
2302 | chan->remote_msdu = le16_to_cpu(efs.msdu); | ||
2303 | chan->remote_flush_to = | ||
2304 | le32_to_cpu(efs.flush_to); | ||
2305 | chan->remote_acc_lat = | ||
2306 | le32_to_cpu(efs.acc_lat); | ||
2307 | chan->remote_sdu_itime = | ||
2308 | le32_to_cpu(efs.sdu_itime); | ||
2309 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, | ||
2310 | sizeof(efs), (unsigned long) &efs); | ||
2311 | } | ||
2117 | break; | 2312 | break; |
2118 | 2313 | ||
2119 | case L2CAP_MODE_STREAMING: | 2314 | case L2CAP_MODE_STREAMING: |
2120 | if (le16_to_cpu(rfc.max_pdu_size) > chan->conn->mtu - 10) | 2315 | size = min_t(u16, le16_to_cpu(rfc.max_pdu_size), |
2121 | rfc.max_pdu_size = cpu_to_le16(chan->conn->mtu - 10); | 2316 | chan->conn->mtu - |
2122 | 2317 | L2CAP_EXT_HDR_SIZE - | |
2123 | chan->remote_mps = le16_to_cpu(rfc.max_pdu_size); | 2318 | L2CAP_SDULEN_SIZE - |
2319 | L2CAP_FCS_SIZE); | ||
2320 | rfc.max_pdu_size = cpu_to_le16(size); | ||
2321 | chan->remote_mps = size; | ||
2124 | 2322 | ||
2125 | set_bit(CONF_MODE_DONE, &chan->conf_state); | 2323 | set_bit(CONF_MODE_DONE, &chan->conf_state); |
2126 | 2324 | ||
@@ -2153,6 +2351,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi | |||
2153 | int type, olen; | 2351 | int type, olen; |
2154 | unsigned long val; | 2352 | unsigned long val; |
2155 | struct l2cap_conf_rfc rfc; | 2353 | struct l2cap_conf_rfc rfc; |
2354 | struct l2cap_conf_efs efs; | ||
2156 | 2355 | ||
2157 | BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data); | 2356 | BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data); |
2158 | 2357 | ||
@@ -2188,6 +2387,26 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi | |||
2188 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 2387 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
2189 | sizeof(rfc), (unsigned long) &rfc); | 2388 | sizeof(rfc), (unsigned long) &rfc); |
2190 | break; | 2389 | break; |
2390 | |||
2391 | case L2CAP_CONF_EWS: | ||
2392 | chan->tx_win = min_t(u16, val, | ||
2393 | L2CAP_DEFAULT_EXT_WINDOW); | ||
2394 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, | ||
2395 | chan->tx_win); | ||
2396 | break; | ||
2397 | |||
2398 | case L2CAP_CONF_EFS: | ||
2399 | if (olen == sizeof(efs)) | ||
2400 | memcpy(&efs, (void *)val, olen); | ||
2401 | |||
2402 | if (chan->local_stype != L2CAP_SERV_NOTRAFIC && | ||
2403 | efs.stype != L2CAP_SERV_NOTRAFIC && | ||
2404 | efs.stype != chan->local_stype) | ||
2405 | return -ECONNREFUSED; | ||
2406 | |||
2407 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, | ||
2408 | sizeof(efs), (unsigned long) &efs); | ||
2409 | break; | ||
2191 | } | 2410 | } |
2192 | } | 2411 | } |
2193 | 2412 | ||
@@ -2196,13 +2415,23 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi | |||
2196 | 2415 | ||
2197 | chan->mode = rfc.mode; | 2416 | chan->mode = rfc.mode; |
2198 | 2417 | ||
2199 | if (*result == L2CAP_CONF_SUCCESS) { | 2418 | if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) { |
2200 | switch (rfc.mode) { | 2419 | switch (rfc.mode) { |
2201 | case L2CAP_MODE_ERTM: | 2420 | case L2CAP_MODE_ERTM: |
2202 | chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); | 2421 | chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); |
2203 | chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); | 2422 | chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); |
2204 | chan->mps = le16_to_cpu(rfc.max_pdu_size); | 2423 | chan->mps = le16_to_cpu(rfc.max_pdu_size); |
2424 | |||
2425 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { | ||
2426 | chan->local_msdu = le16_to_cpu(efs.msdu); | ||
2427 | chan->local_sdu_itime = | ||
2428 | le32_to_cpu(efs.sdu_itime); | ||
2429 | chan->local_acc_lat = le32_to_cpu(efs.acc_lat); | ||
2430 | chan->local_flush_to = | ||
2431 | le32_to_cpu(efs.flush_to); | ||
2432 | } | ||
2205 | break; | 2433 | break; |
2434 | |||
2206 | case L2CAP_MODE_STREAMING: | 2435 | case L2CAP_MODE_STREAMING: |
2207 | chan->mps = le16_to_cpu(rfc.max_pdu_size); | 2436 | chan->mps = le16_to_cpu(rfc.max_pdu_size); |
2208 | } | 2437 | } |
@@ -2330,7 +2559,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2330 | /* Check if the ACL is secure enough (if not SDP) */ | 2559 | /* Check if the ACL is secure enough (if not SDP) */ |
2331 | if (psm != cpu_to_le16(0x0001) && | 2560 | if (psm != cpu_to_le16(0x0001) && |
2332 | !hci_conn_check_link_mode(conn->hcon)) { | 2561 | !hci_conn_check_link_mode(conn->hcon)) { |
2333 | conn->disc_reason = 0x05; | 2562 | conn->disc_reason = HCI_ERROR_AUTH_FAILURE; |
2334 | result = L2CAP_CR_SEC_BLOCK; | 2563 | result = L2CAP_CR_SEC_BLOCK; |
2335 | goto response; | 2564 | goto response; |
2336 | } | 2565 | } |
@@ -2602,6 +2831,21 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2602 | chan->num_conf_req++; | 2831 | chan->num_conf_req++; |
2603 | } | 2832 | } |
2604 | 2833 | ||
2834 | /* Got Conf Rsp PENDING from remote side and asume we sent | ||
2835 | Conf Rsp PENDING in the code above */ | ||
2836 | if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) && | ||
2837 | test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) { | ||
2838 | |||
2839 | /* check compatibility */ | ||
2840 | |||
2841 | clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state); | ||
2842 | set_bit(CONF_OUTPUT_DONE, &chan->conf_state); | ||
2843 | |||
2844 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | ||
2845 | l2cap_build_conf_rsp(chan, rsp, | ||
2846 | L2CAP_CONF_SUCCESS, 0x0000), rsp); | ||
2847 | } | ||
2848 | |||
2605 | unlock: | 2849 | unlock: |
2606 | bh_unlock_sock(sk); | 2850 | bh_unlock_sock(sk); |
2607 | return 0; | 2851 | return 0; |
@@ -2631,8 +2875,33 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2631 | switch (result) { | 2875 | switch (result) { |
2632 | case L2CAP_CONF_SUCCESS: | 2876 | case L2CAP_CONF_SUCCESS: |
2633 | l2cap_conf_rfc_get(chan, rsp->data, len); | 2877 | l2cap_conf_rfc_get(chan, rsp->data, len); |
2878 | clear_bit(CONF_REM_CONF_PEND, &chan->conf_state); | ||
2634 | break; | 2879 | break; |
2635 | 2880 | ||
2881 | case L2CAP_CONF_PENDING: | ||
2882 | set_bit(CONF_REM_CONF_PEND, &chan->conf_state); | ||
2883 | |||
2884 | if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) { | ||
2885 | char buf[64]; | ||
2886 | |||
2887 | len = l2cap_parse_conf_rsp(chan, rsp->data, len, | ||
2888 | buf, &result); | ||
2889 | if (len < 0) { | ||
2890 | l2cap_send_disconn_req(conn, chan, ECONNRESET); | ||
2891 | goto done; | ||
2892 | } | ||
2893 | |||
2894 | /* check compatibility */ | ||
2895 | |||
2896 | clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state); | ||
2897 | set_bit(CONF_OUTPUT_DONE, &chan->conf_state); | ||
2898 | |||
2899 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | ||
2900 | l2cap_build_conf_rsp(chan, buf, | ||
2901 | L2CAP_CONF_SUCCESS, 0x0000), buf); | ||
2902 | } | ||
2903 | goto done; | ||
2904 | |||
2636 | case L2CAP_CONF_UNACCEPT: | 2905 | case L2CAP_CONF_UNACCEPT: |
2637 | if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) { | 2906 | if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) { |
2638 | char req[64]; | 2907 | char req[64]; |
@@ -2782,15 +3051,25 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm | |||
2782 | if (!disable_ertm) | 3051 | if (!disable_ertm) |
2783 | feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING | 3052 | feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING |
2784 | | L2CAP_FEAT_FCS; | 3053 | | L2CAP_FEAT_FCS; |
3054 | if (enable_hs) | ||
3055 | feat_mask |= L2CAP_FEAT_EXT_FLOW | ||
3056 | | L2CAP_FEAT_EXT_WINDOW; | ||
3057 | |||
2785 | put_unaligned_le32(feat_mask, rsp->data); | 3058 | put_unaligned_le32(feat_mask, rsp->data); |
2786 | l2cap_send_cmd(conn, cmd->ident, | 3059 | l2cap_send_cmd(conn, cmd->ident, |
2787 | L2CAP_INFO_RSP, sizeof(buf), buf); | 3060 | L2CAP_INFO_RSP, sizeof(buf), buf); |
2788 | } else if (type == L2CAP_IT_FIXED_CHAN) { | 3061 | } else if (type == L2CAP_IT_FIXED_CHAN) { |
2789 | u8 buf[12]; | 3062 | u8 buf[12]; |
2790 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; | 3063 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; |
3064 | |||
3065 | if (enable_hs) | ||
3066 | l2cap_fixed_chan[0] |= L2CAP_FC_A2MP; | ||
3067 | else | ||
3068 | l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP; | ||
3069 | |||
2791 | rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN); | 3070 | rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN); |
2792 | rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); | 3071 | rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); |
2793 | memcpy(buf + 4, l2cap_fixed_chan, 8); | 3072 | memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan)); |
2794 | l2cap_send_cmd(conn, cmd->ident, | 3073 | l2cap_send_cmd(conn, cmd->ident, |
2795 | L2CAP_INFO_RSP, sizeof(buf), buf); | 3074 | L2CAP_INFO_RSP, sizeof(buf), buf); |
2796 | } else { | 3075 | } else { |
@@ -2857,6 +3136,165 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm | |||
2857 | return 0; | 3136 | return 0; |
2858 | } | 3137 | } |
2859 | 3138 | ||
3139 | static inline int l2cap_create_channel_req(struct l2cap_conn *conn, | ||
3140 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, | ||
3141 | void *data) | ||
3142 | { | ||
3143 | struct l2cap_create_chan_req *req = data; | ||
3144 | struct l2cap_create_chan_rsp rsp; | ||
3145 | u16 psm, scid; | ||
3146 | |||
3147 | if (cmd_len != sizeof(*req)) | ||
3148 | return -EPROTO; | ||
3149 | |||
3150 | if (!enable_hs) | ||
3151 | return -EINVAL; | ||
3152 | |||
3153 | psm = le16_to_cpu(req->psm); | ||
3154 | scid = le16_to_cpu(req->scid); | ||
3155 | |||
3156 | BT_DBG("psm %d, scid %d, amp_id %d", psm, scid, req->amp_id); | ||
3157 | |||
3158 | /* Placeholder: Always reject */ | ||
3159 | rsp.dcid = 0; | ||
3160 | rsp.scid = cpu_to_le16(scid); | ||
3161 | rsp.result = L2CAP_CR_NO_MEM; | ||
3162 | rsp.status = L2CAP_CS_NO_INFO; | ||
3163 | |||
3164 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP, | ||
3165 | sizeof(rsp), &rsp); | ||
3166 | |||
3167 | return 0; | ||
3168 | } | ||
3169 | |||
3170 | static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn, | ||
3171 | struct l2cap_cmd_hdr *cmd, void *data) | ||
3172 | { | ||
3173 | BT_DBG("conn %p", conn); | ||
3174 | |||
3175 | return l2cap_connect_rsp(conn, cmd, data); | ||
3176 | } | ||
3177 | |||
3178 | static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident, | ||
3179 | u16 icid, u16 result) | ||
3180 | { | ||
3181 | struct l2cap_move_chan_rsp rsp; | ||
3182 | |||
3183 | BT_DBG("icid %d, result %d", icid, result); | ||
3184 | |||
3185 | rsp.icid = cpu_to_le16(icid); | ||
3186 | rsp.result = cpu_to_le16(result); | ||
3187 | |||
3188 | l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp); | ||
3189 | } | ||
3190 | |||
3191 | static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn, | ||
3192 | struct l2cap_chan *chan, u16 icid, u16 result) | ||
3193 | { | ||
3194 | struct l2cap_move_chan_cfm cfm; | ||
3195 | u8 ident; | ||
3196 | |||
3197 | BT_DBG("icid %d, result %d", icid, result); | ||
3198 | |||
3199 | ident = l2cap_get_ident(conn); | ||
3200 | if (chan) | ||
3201 | chan->ident = ident; | ||
3202 | |||
3203 | cfm.icid = cpu_to_le16(icid); | ||
3204 | cfm.result = cpu_to_le16(result); | ||
3205 | |||
3206 | l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm); | ||
3207 | } | ||
3208 | |||
3209 | static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident, | ||
3210 | u16 icid) | ||
3211 | { | ||
3212 | struct l2cap_move_chan_cfm_rsp rsp; | ||
3213 | |||
3214 | BT_DBG("icid %d", icid); | ||
3215 | |||
3216 | rsp.icid = cpu_to_le16(icid); | ||
3217 | l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp); | ||
3218 | } | ||
3219 | |||
3220 | static inline int l2cap_move_channel_req(struct l2cap_conn *conn, | ||
3221 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data) | ||
3222 | { | ||
3223 | struct l2cap_move_chan_req *req = data; | ||
3224 | u16 icid = 0; | ||
3225 | u16 result = L2CAP_MR_NOT_ALLOWED; | ||
3226 | |||
3227 | if (cmd_len != sizeof(*req)) | ||
3228 | return -EPROTO; | ||
3229 | |||
3230 | icid = le16_to_cpu(req->icid); | ||
3231 | |||
3232 | BT_DBG("icid %d, dest_amp_id %d", icid, req->dest_amp_id); | ||
3233 | |||
3234 | if (!enable_hs) | ||
3235 | return -EINVAL; | ||
3236 | |||
3237 | /* Placeholder: Always refuse */ | ||
3238 | l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result); | ||
3239 | |||
3240 | return 0; | ||
3241 | } | ||
3242 | |||
3243 | static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn, | ||
3244 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data) | ||
3245 | { | ||
3246 | struct l2cap_move_chan_rsp *rsp = data; | ||
3247 | u16 icid, result; | ||
3248 | |||
3249 | if (cmd_len != sizeof(*rsp)) | ||
3250 | return -EPROTO; | ||
3251 | |||
3252 | icid = le16_to_cpu(rsp->icid); | ||
3253 | result = le16_to_cpu(rsp->result); | ||
3254 | |||
3255 | BT_DBG("icid %d, result %d", icid, result); | ||
3256 | |||
3257 | /* Placeholder: Always unconfirmed */ | ||
3258 | l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED); | ||
3259 | |||
3260 | return 0; | ||
3261 | } | ||
3262 | |||
3263 | static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn, | ||
3264 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data) | ||
3265 | { | ||
3266 | struct l2cap_move_chan_cfm *cfm = data; | ||
3267 | u16 icid, result; | ||
3268 | |||
3269 | if (cmd_len != sizeof(*cfm)) | ||
3270 | return -EPROTO; | ||
3271 | |||
3272 | icid = le16_to_cpu(cfm->icid); | ||
3273 | result = le16_to_cpu(cfm->result); | ||
3274 | |||
3275 | BT_DBG("icid %d, result %d", icid, result); | ||
3276 | |||
3277 | l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid); | ||
3278 | |||
3279 | return 0; | ||
3280 | } | ||
3281 | |||
3282 | static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn, | ||
3283 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data) | ||
3284 | { | ||
3285 | struct l2cap_move_chan_cfm_rsp *rsp = data; | ||
3286 | u16 icid; | ||
3287 | |||
3288 | if (cmd_len != sizeof(*rsp)) | ||
3289 | return -EPROTO; | ||
3290 | |||
3291 | icid = le16_to_cpu(rsp->icid); | ||
3292 | |||
3293 | BT_DBG("icid %d", icid); | ||
3294 | |||
3295 | return 0; | ||
3296 | } | ||
3297 | |||
2860 | static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency, | 3298 | static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency, |
2861 | u16 to_multiplier) | 3299 | u16 to_multiplier) |
2862 | { | 3300 | { |
@@ -2969,6 +3407,30 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
2969 | err = l2cap_information_rsp(conn, cmd, data); | 3407 | err = l2cap_information_rsp(conn, cmd, data); |
2970 | break; | 3408 | break; |
2971 | 3409 | ||
3410 | case L2CAP_CREATE_CHAN_REQ: | ||
3411 | err = l2cap_create_channel_req(conn, cmd, cmd_len, data); | ||
3412 | break; | ||
3413 | |||
3414 | case L2CAP_CREATE_CHAN_RSP: | ||
3415 | err = l2cap_create_channel_rsp(conn, cmd, data); | ||
3416 | break; | ||
3417 | |||
3418 | case L2CAP_MOVE_CHAN_REQ: | ||
3419 | err = l2cap_move_channel_req(conn, cmd, cmd_len, data); | ||
3420 | break; | ||
3421 | |||
3422 | case L2CAP_MOVE_CHAN_RSP: | ||
3423 | err = l2cap_move_channel_rsp(conn, cmd, cmd_len, data); | ||
3424 | break; | ||
3425 | |||
3426 | case L2CAP_MOVE_CHAN_CFM: | ||
3427 | err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data); | ||
3428 | break; | ||
3429 | |||
3430 | case L2CAP_MOVE_CHAN_CFM_RSP: | ||
3431 | err = l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data); | ||
3432 | break; | ||
3433 | |||
2972 | default: | 3434 | default: |
2973 | BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code); | 3435 | BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code); |
2974 | err = -EINVAL; | 3436 | err = -EINVAL; |
@@ -3047,10 +3509,15 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, | |||
3047 | static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb) | 3509 | static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb) |
3048 | { | 3510 | { |
3049 | u16 our_fcs, rcv_fcs; | 3511 | u16 our_fcs, rcv_fcs; |
3050 | int hdr_size = L2CAP_HDR_SIZE + 2; | 3512 | int hdr_size; |
3513 | |||
3514 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
3515 | hdr_size = L2CAP_EXT_HDR_SIZE; | ||
3516 | else | ||
3517 | hdr_size = L2CAP_ENH_HDR_SIZE; | ||
3051 | 3518 | ||
3052 | if (chan->fcs == L2CAP_FCS_CRC16) { | 3519 | if (chan->fcs == L2CAP_FCS_CRC16) { |
3053 | skb_trim(skb, skb->len - 2); | 3520 | skb_trim(skb, skb->len - L2CAP_FCS_SIZE); |
3054 | rcv_fcs = get_unaligned_le16(skb->data + skb->len); | 3521 | rcv_fcs = get_unaligned_le16(skb->data + skb->len); |
3055 | our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size); | 3522 | our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size); |
3056 | 3523 | ||
@@ -3062,14 +3529,14 @@ static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb) | |||
3062 | 3529 | ||
3063 | static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) | 3530 | static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) |
3064 | { | 3531 | { |
3065 | u16 control = 0; | 3532 | u32 control = 0; |
3066 | 3533 | ||
3067 | chan->frames_sent = 0; | 3534 | chan->frames_sent = 0; |
3068 | 3535 | ||
3069 | control |= chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3536 | control |= __set_reqseq(chan, chan->buffer_seq); |
3070 | 3537 | ||
3071 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { | 3538 | if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { |
3072 | control |= L2CAP_SUPER_RCV_NOT_READY; | 3539 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); |
3073 | l2cap_send_sframe(chan, control); | 3540 | l2cap_send_sframe(chan, control); |
3074 | set_bit(CONN_RNR_SENT, &chan->conn_state); | 3541 | set_bit(CONN_RNR_SENT, &chan->conn_state); |
3075 | } | 3542 | } |
@@ -3081,12 +3548,12 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) | |||
3081 | 3548 | ||
3082 | if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) && | 3549 | if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) && |
3083 | chan->frames_sent == 0) { | 3550 | chan->frames_sent == 0) { |
3084 | control |= L2CAP_SUPER_RCV_READY; | 3551 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); |
3085 | l2cap_send_sframe(chan, control); | 3552 | l2cap_send_sframe(chan, control); |
3086 | } | 3553 | } |
3087 | } | 3554 | } |
3088 | 3555 | ||
3089 | static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, u8 tx_seq, u8 sar) | 3556 | static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, u16 tx_seq, u8 sar) |
3090 | { | 3557 | { |
3091 | struct sk_buff *next_skb; | 3558 | struct sk_buff *next_skb; |
3092 | int tx_seq_offset, next_tx_seq_offset; | 3559 | int tx_seq_offset, next_tx_seq_offset; |
@@ -3100,18 +3567,14 @@ static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, | |||
3100 | return 0; | 3567 | return 0; |
3101 | } | 3568 | } |
3102 | 3569 | ||
3103 | tx_seq_offset = (tx_seq - chan->buffer_seq) % 64; | 3570 | tx_seq_offset = __seq_offset(chan, tx_seq, chan->buffer_seq); |
3104 | if (tx_seq_offset < 0) | ||
3105 | tx_seq_offset += 64; | ||
3106 | 3571 | ||
3107 | do { | 3572 | do { |
3108 | if (bt_cb(next_skb)->tx_seq == tx_seq) | 3573 | if (bt_cb(next_skb)->tx_seq == tx_seq) |
3109 | return -EINVAL; | 3574 | return -EINVAL; |
3110 | 3575 | ||
3111 | next_tx_seq_offset = (bt_cb(next_skb)->tx_seq - | 3576 | next_tx_seq_offset = __seq_offset(chan, |
3112 | chan->buffer_seq) % 64; | 3577 | bt_cb(next_skb)->tx_seq, chan->buffer_seq); |
3113 | if (next_tx_seq_offset < 0) | ||
3114 | next_tx_seq_offset += 64; | ||
3115 | 3578 | ||
3116 | if (next_tx_seq_offset > tx_seq_offset) { | 3579 | if (next_tx_seq_offset > tx_seq_offset) { |
3117 | __skb_queue_before(&chan->srej_q, next_skb, skb); | 3580 | __skb_queue_before(&chan->srej_q, next_skb, skb); |
@@ -3147,24 +3610,24 @@ static void append_skb_frag(struct sk_buff *skb, | |||
3147 | skb->truesize += new_frag->truesize; | 3610 | skb->truesize += new_frag->truesize; |
3148 | } | 3611 | } |
3149 | 3612 | ||
3150 | static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u16 control) | 3613 | static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u32 control) |
3151 | { | 3614 | { |
3152 | int err = -EINVAL; | 3615 | int err = -EINVAL; |
3153 | 3616 | ||
3154 | switch (control & L2CAP_CTRL_SAR) { | 3617 | switch (__get_ctrl_sar(chan, control)) { |
3155 | case L2CAP_SDU_UNSEGMENTED: | 3618 | case L2CAP_SAR_UNSEGMENTED: |
3156 | if (chan->sdu) | 3619 | if (chan->sdu) |
3157 | break; | 3620 | break; |
3158 | 3621 | ||
3159 | err = chan->ops->recv(chan->data, skb); | 3622 | err = chan->ops->recv(chan->data, skb); |
3160 | break; | 3623 | break; |
3161 | 3624 | ||
3162 | case L2CAP_SDU_START: | 3625 | case L2CAP_SAR_START: |
3163 | if (chan->sdu) | 3626 | if (chan->sdu) |
3164 | break; | 3627 | break; |
3165 | 3628 | ||
3166 | chan->sdu_len = get_unaligned_le16(skb->data); | 3629 | chan->sdu_len = get_unaligned_le16(skb->data); |
3167 | skb_pull(skb, 2); | 3630 | skb_pull(skb, L2CAP_SDULEN_SIZE); |
3168 | 3631 | ||
3169 | if (chan->sdu_len > chan->imtu) { | 3632 | if (chan->sdu_len > chan->imtu) { |
3170 | err = -EMSGSIZE; | 3633 | err = -EMSGSIZE; |
@@ -3181,7 +3644,7 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u1 | |||
3181 | err = 0; | 3644 | err = 0; |
3182 | break; | 3645 | break; |
3183 | 3646 | ||
3184 | case L2CAP_SDU_CONTINUE: | 3647 | case L2CAP_SAR_CONTINUE: |
3185 | if (!chan->sdu) | 3648 | if (!chan->sdu) |
3186 | break; | 3649 | break; |
3187 | 3650 | ||
@@ -3195,7 +3658,7 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u1 | |||
3195 | err = 0; | 3658 | err = 0; |
3196 | break; | 3659 | break; |
3197 | 3660 | ||
3198 | case L2CAP_SDU_END: | 3661 | case L2CAP_SAR_END: |
3199 | if (!chan->sdu) | 3662 | if (!chan->sdu) |
3200 | break; | 3663 | break; |
3201 | 3664 | ||
@@ -3230,14 +3693,14 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u1 | |||
3230 | 3693 | ||
3231 | static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan) | 3694 | static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan) |
3232 | { | 3695 | { |
3233 | u16 control; | 3696 | u32 control; |
3234 | 3697 | ||
3235 | BT_DBG("chan %p, Enter local busy", chan); | 3698 | BT_DBG("chan %p, Enter local busy", chan); |
3236 | 3699 | ||
3237 | set_bit(CONN_LOCAL_BUSY, &chan->conn_state); | 3700 | set_bit(CONN_LOCAL_BUSY, &chan->conn_state); |
3238 | 3701 | ||
3239 | control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3702 | control = __set_reqseq(chan, chan->buffer_seq); |
3240 | control |= L2CAP_SUPER_RCV_NOT_READY; | 3703 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); |
3241 | l2cap_send_sframe(chan, control); | 3704 | l2cap_send_sframe(chan, control); |
3242 | 3705 | ||
3243 | set_bit(CONN_RNR_SENT, &chan->conn_state); | 3706 | set_bit(CONN_RNR_SENT, &chan->conn_state); |
@@ -3247,13 +3710,14 @@ static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan) | |||
3247 | 3710 | ||
3248 | static void l2cap_ertm_exit_local_busy(struct l2cap_chan *chan) | 3711 | static void l2cap_ertm_exit_local_busy(struct l2cap_chan *chan) |
3249 | { | 3712 | { |
3250 | u16 control; | 3713 | u32 control; |
3251 | 3714 | ||
3252 | if (!test_bit(CONN_RNR_SENT, &chan->conn_state)) | 3715 | if (!test_bit(CONN_RNR_SENT, &chan->conn_state)) |
3253 | goto done; | 3716 | goto done; |
3254 | 3717 | ||
3255 | control = chan->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3718 | control = __set_reqseq(chan, chan->buffer_seq); |
3256 | control |= L2CAP_SUPER_RCV_READY | L2CAP_CTRL_POLL; | 3719 | control |= __set_ctrl_poll(chan); |
3720 | control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); | ||
3257 | l2cap_send_sframe(chan, control); | 3721 | l2cap_send_sframe(chan, control); |
3258 | chan->retry_count = 1; | 3722 | chan->retry_count = 1; |
3259 | 3723 | ||
@@ -3279,10 +3743,10 @@ void l2cap_chan_busy(struct l2cap_chan *chan, int busy) | |||
3279 | } | 3743 | } |
3280 | } | 3744 | } |
3281 | 3745 | ||
3282 | static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) | 3746 | static void l2cap_check_srej_gap(struct l2cap_chan *chan, u16 tx_seq) |
3283 | { | 3747 | { |
3284 | struct sk_buff *skb; | 3748 | struct sk_buff *skb; |
3285 | u16 control; | 3749 | u32 control; |
3286 | 3750 | ||
3287 | while ((skb = skb_peek(&chan->srej_q)) && | 3751 | while ((skb = skb_peek(&chan->srej_q)) && |
3288 | !test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { | 3752 | !test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { |
@@ -3292,7 +3756,7 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) | |||
3292 | break; | 3756 | break; |
3293 | 3757 | ||
3294 | skb = skb_dequeue(&chan->srej_q); | 3758 | skb = skb_dequeue(&chan->srej_q); |
3295 | control = bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT; | 3759 | control = __set_ctrl_sar(chan, bt_cb(skb)->sar); |
3296 | err = l2cap_reassemble_sdu(chan, skb, control); | 3760 | err = l2cap_reassemble_sdu(chan, skb, control); |
3297 | 3761 | ||
3298 | if (err < 0) { | 3762 | if (err < 0) { |
@@ -3300,16 +3764,15 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u8 tx_seq) | |||
3300 | break; | 3764 | break; |
3301 | } | 3765 | } |
3302 | 3766 | ||
3303 | chan->buffer_seq_srej = | 3767 | chan->buffer_seq_srej = __next_seq(chan, chan->buffer_seq_srej); |
3304 | (chan->buffer_seq_srej + 1) % 64; | 3768 | tx_seq = __next_seq(chan, tx_seq); |
3305 | tx_seq = (tx_seq + 1) % 64; | ||
3306 | } | 3769 | } |
3307 | } | 3770 | } |
3308 | 3771 | ||
3309 | static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq) | 3772 | static void l2cap_resend_srejframe(struct l2cap_chan *chan, u16 tx_seq) |
3310 | { | 3773 | { |
3311 | struct srej_list *l, *tmp; | 3774 | struct srej_list *l, *tmp; |
3312 | u16 control; | 3775 | u32 control; |
3313 | 3776 | ||
3314 | list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { | 3777 | list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { |
3315 | if (l->tx_seq == tx_seq) { | 3778 | if (l->tx_seq == tx_seq) { |
@@ -3317,45 +3780,48 @@ static void l2cap_resend_srejframe(struct l2cap_chan *chan, u8 tx_seq) | |||
3317 | kfree(l); | 3780 | kfree(l); |
3318 | return; | 3781 | return; |
3319 | } | 3782 | } |
3320 | control = L2CAP_SUPER_SELECT_REJECT; | 3783 | control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); |
3321 | control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3784 | control |= __set_reqseq(chan, l->tx_seq); |
3322 | l2cap_send_sframe(chan, control); | 3785 | l2cap_send_sframe(chan, control); |
3323 | list_del(&l->list); | 3786 | list_del(&l->list); |
3324 | list_add_tail(&l->list, &chan->srej_l); | 3787 | list_add_tail(&l->list, &chan->srej_l); |
3325 | } | 3788 | } |
3326 | } | 3789 | } |
3327 | 3790 | ||
3328 | static void l2cap_send_srejframe(struct l2cap_chan *chan, u8 tx_seq) | 3791 | static void l2cap_send_srejframe(struct l2cap_chan *chan, u16 tx_seq) |
3329 | { | 3792 | { |
3330 | struct srej_list *new; | 3793 | struct srej_list *new; |
3331 | u16 control; | 3794 | u32 control; |
3332 | 3795 | ||
3333 | while (tx_seq != chan->expected_tx_seq) { | 3796 | while (tx_seq != chan->expected_tx_seq) { |
3334 | control = L2CAP_SUPER_SELECT_REJECT; | 3797 | control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); |
3335 | control |= chan->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3798 | control |= __set_reqseq(chan, chan->expected_tx_seq); |
3336 | l2cap_send_sframe(chan, control); | 3799 | l2cap_send_sframe(chan, control); |
3337 | 3800 | ||
3338 | new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); | 3801 | new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); |
3339 | new->tx_seq = chan->expected_tx_seq; | 3802 | new->tx_seq = chan->expected_tx_seq; |
3340 | chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; | 3803 | |
3804 | chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq); | ||
3805 | |||
3341 | list_add_tail(&new->list, &chan->srej_l); | 3806 | list_add_tail(&new->list, &chan->srej_l); |
3342 | } | 3807 | } |
3343 | chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; | 3808 | |
3809 | chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq); | ||
3344 | } | 3810 | } |
3345 | 3811 | ||
3346 | static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) | 3812 | static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u32 rx_control, struct sk_buff *skb) |
3347 | { | 3813 | { |
3348 | u8 tx_seq = __get_txseq(rx_control); | 3814 | u16 tx_seq = __get_txseq(chan, rx_control); |
3349 | u8 req_seq = __get_reqseq(rx_control); | 3815 | u16 req_seq = __get_reqseq(chan, rx_control); |
3350 | u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT; | 3816 | u8 sar = __get_ctrl_sar(chan, rx_control); |
3351 | int tx_seq_offset, expected_tx_seq_offset; | 3817 | int tx_seq_offset, expected_tx_seq_offset; |
3352 | int num_to_ack = (chan->tx_win/6) + 1; | 3818 | int num_to_ack = (chan->tx_win/6) + 1; |
3353 | int err = 0; | 3819 | int err = 0; |
3354 | 3820 | ||
3355 | BT_DBG("chan %p len %d tx_seq %d rx_control 0x%4.4x", chan, skb->len, | 3821 | BT_DBG("chan %p len %d tx_seq %d rx_control 0x%8.8x", chan, skb->len, |
3356 | tx_seq, rx_control); | 3822 | tx_seq, rx_control); |
3357 | 3823 | ||
3358 | if (L2CAP_CTRL_FINAL & rx_control && | 3824 | if (__is_ctrl_final(chan, rx_control) && |
3359 | test_bit(CONN_WAIT_F, &chan->conn_state)) { | 3825 | test_bit(CONN_WAIT_F, &chan->conn_state)) { |
3360 | __clear_monitor_timer(chan); | 3826 | __clear_monitor_timer(chan); |
3361 | if (chan->unacked_frames > 0) | 3827 | if (chan->unacked_frames > 0) |
@@ -3366,9 +3832,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3366 | chan->expected_ack_seq = req_seq; | 3832 | chan->expected_ack_seq = req_seq; |
3367 | l2cap_drop_acked_frames(chan); | 3833 | l2cap_drop_acked_frames(chan); |
3368 | 3834 | ||
3369 | tx_seq_offset = (tx_seq - chan->buffer_seq) % 64; | 3835 | tx_seq_offset = __seq_offset(chan, tx_seq, chan->buffer_seq); |
3370 | if (tx_seq_offset < 0) | ||
3371 | tx_seq_offset += 64; | ||
3372 | 3836 | ||
3373 | /* invalid tx_seq */ | 3837 | /* invalid tx_seq */ |
3374 | if (tx_seq_offset >= chan->tx_win) { | 3838 | if (tx_seq_offset >= chan->tx_win) { |
@@ -3416,10 +3880,8 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3416 | l2cap_send_srejframe(chan, tx_seq); | 3880 | l2cap_send_srejframe(chan, tx_seq); |
3417 | } | 3881 | } |
3418 | } else { | 3882 | } else { |
3419 | expected_tx_seq_offset = | 3883 | expected_tx_seq_offset = __seq_offset(chan, |
3420 | (chan->expected_tx_seq - chan->buffer_seq) % 64; | 3884 | chan->expected_tx_seq, chan->buffer_seq); |
3421 | if (expected_tx_seq_offset < 0) | ||
3422 | expected_tx_seq_offset += 64; | ||
3423 | 3885 | ||
3424 | /* duplicated tx_seq */ | 3886 | /* duplicated tx_seq */ |
3425 | if (tx_seq_offset < expected_tx_seq_offset) | 3887 | if (tx_seq_offset < expected_tx_seq_offset) |
@@ -3444,7 +3906,7 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u16 rx_cont | |||
3444 | return 0; | 3906 | return 0; |
3445 | 3907 | ||
3446 | expected: | 3908 | expected: |
3447 | chan->expected_tx_seq = (chan->expected_tx_seq + 1) % 64; | 3909 | chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq); |
3448 | 3910 | ||
3449 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { | 3911 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { |
3450 | bt_cb(skb)->tx_seq = tx_seq; | 3912 | bt_cb(skb)->tx_seq = tx_seq; |
@@ -3454,13 +3916,14 @@ expected: | |||
3454 | } | 3916 | } |
3455 | 3917 | ||
3456 | err = l2cap_reassemble_sdu(chan, skb, rx_control); | 3918 | err = l2cap_reassemble_sdu(chan, skb, rx_control); |
3457 | chan->buffer_seq = (chan->buffer_seq + 1) % 64; | 3919 | chan->buffer_seq = __next_seq(chan, chan->buffer_seq); |
3920 | |||
3458 | if (err < 0) { | 3921 | if (err < 0) { |
3459 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | 3922 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
3460 | return err; | 3923 | return err; |
3461 | } | 3924 | } |
3462 | 3925 | ||
3463 | if (rx_control & L2CAP_CTRL_FINAL) { | 3926 | if (__is_ctrl_final(chan, rx_control)) { |
3464 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) | 3927 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) |
3465 | l2cap_retransmit_frames(chan); | 3928 | l2cap_retransmit_frames(chan); |
3466 | } | 3929 | } |
@@ -3478,15 +3941,15 @@ drop: | |||
3478 | return 0; | 3941 | return 0; |
3479 | } | 3942 | } |
3480 | 3943 | ||
3481 | static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_control) | 3944 | static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u32 rx_control) |
3482 | { | 3945 | { |
3483 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, __get_reqseq(rx_control), | 3946 | BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, |
3484 | rx_control); | 3947 | __get_reqseq(chan, rx_control), rx_control); |
3485 | 3948 | ||
3486 | chan->expected_ack_seq = __get_reqseq(rx_control); | 3949 | chan->expected_ack_seq = __get_reqseq(chan, rx_control); |
3487 | l2cap_drop_acked_frames(chan); | 3950 | l2cap_drop_acked_frames(chan); |
3488 | 3951 | ||
3489 | if (rx_control & L2CAP_CTRL_POLL) { | 3952 | if (__is_ctrl_poll(chan, rx_control)) { |
3490 | set_bit(CONN_SEND_FBIT, &chan->conn_state); | 3953 | set_bit(CONN_SEND_FBIT, &chan->conn_state); |
3491 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { | 3954 | if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { |
3492 | if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state) && | 3955 | if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state) && |
@@ -3499,7 +3962,7 @@ static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_co | |||
3499 | l2cap_send_i_or_rr_or_rnr(chan); | 3962 | l2cap_send_i_or_rr_or_rnr(chan); |
3500 | } | 3963 | } |
3501 | 3964 | ||
3502 | } else if (rx_control & L2CAP_CTRL_FINAL) { | 3965 | } else if (__is_ctrl_final(chan, rx_control)) { |
3503 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); | 3966 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3504 | 3967 | ||
3505 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) | 3968 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) |
@@ -3518,18 +3981,18 @@ static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u16 rx_co | |||
3518 | } | 3981 | } |
3519 | } | 3982 | } |
3520 | 3983 | ||
3521 | static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_control) | 3984 | static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u32 rx_control) |
3522 | { | 3985 | { |
3523 | u8 tx_seq = __get_reqseq(rx_control); | 3986 | u16 tx_seq = __get_reqseq(chan, rx_control); |
3524 | 3987 | ||
3525 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); | 3988 | BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, tx_seq, rx_control); |
3526 | 3989 | ||
3527 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); | 3990 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3528 | 3991 | ||
3529 | chan->expected_ack_seq = tx_seq; | 3992 | chan->expected_ack_seq = tx_seq; |
3530 | l2cap_drop_acked_frames(chan); | 3993 | l2cap_drop_acked_frames(chan); |
3531 | 3994 | ||
3532 | if (rx_control & L2CAP_CTRL_FINAL) { | 3995 | if (__is_ctrl_final(chan, rx_control)) { |
3533 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) | 3996 | if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) |
3534 | l2cap_retransmit_frames(chan); | 3997 | l2cap_retransmit_frames(chan); |
3535 | } else { | 3998 | } else { |
@@ -3539,15 +4002,15 @@ static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u16 rx_c | |||
3539 | set_bit(CONN_REJ_ACT, &chan->conn_state); | 4002 | set_bit(CONN_REJ_ACT, &chan->conn_state); |
3540 | } | 4003 | } |
3541 | } | 4004 | } |
3542 | static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_control) | 4005 | static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u32 rx_control) |
3543 | { | 4006 | { |
3544 | u8 tx_seq = __get_reqseq(rx_control); | 4007 | u16 tx_seq = __get_reqseq(chan, rx_control); |
3545 | 4008 | ||
3546 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); | 4009 | BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, tx_seq, rx_control); |
3547 | 4010 | ||
3548 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); | 4011 | clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3549 | 4012 | ||
3550 | if (rx_control & L2CAP_CTRL_POLL) { | 4013 | if (__is_ctrl_poll(chan, rx_control)) { |
3551 | chan->expected_ack_seq = tx_seq; | 4014 | chan->expected_ack_seq = tx_seq; |
3552 | l2cap_drop_acked_frames(chan); | 4015 | l2cap_drop_acked_frames(chan); |
3553 | 4016 | ||
@@ -3560,7 +4023,7 @@ static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_ | |||
3560 | chan->srej_save_reqseq = tx_seq; | 4023 | chan->srej_save_reqseq = tx_seq; |
3561 | set_bit(CONN_SREJ_ACT, &chan->conn_state); | 4024 | set_bit(CONN_SREJ_ACT, &chan->conn_state); |
3562 | } | 4025 | } |
3563 | } else if (rx_control & L2CAP_CTRL_FINAL) { | 4026 | } else if (__is_ctrl_final(chan, rx_control)) { |
3564 | if (test_bit(CONN_SREJ_ACT, &chan->conn_state) && | 4027 | if (test_bit(CONN_SREJ_ACT, &chan->conn_state) && |
3565 | chan->srej_save_reqseq == tx_seq) | 4028 | chan->srej_save_reqseq == tx_seq) |
3566 | clear_bit(CONN_SREJ_ACT, &chan->conn_state); | 4029 | clear_bit(CONN_SREJ_ACT, &chan->conn_state); |
@@ -3575,37 +4038,39 @@ static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u16 rx_ | |||
3575 | } | 4038 | } |
3576 | } | 4039 | } |
3577 | 4040 | ||
3578 | static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u16 rx_control) | 4041 | static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u32 rx_control) |
3579 | { | 4042 | { |
3580 | u8 tx_seq = __get_reqseq(rx_control); | 4043 | u16 tx_seq = __get_reqseq(chan, rx_control); |
3581 | 4044 | ||
3582 | BT_DBG("chan %p, req_seq %d ctrl 0x%4.4x", chan, tx_seq, rx_control); | 4045 | BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, tx_seq, rx_control); |
3583 | 4046 | ||
3584 | set_bit(CONN_REMOTE_BUSY, &chan->conn_state); | 4047 | set_bit(CONN_REMOTE_BUSY, &chan->conn_state); |
3585 | chan->expected_ack_seq = tx_seq; | 4048 | chan->expected_ack_seq = tx_seq; |
3586 | l2cap_drop_acked_frames(chan); | 4049 | l2cap_drop_acked_frames(chan); |
3587 | 4050 | ||
3588 | if (rx_control & L2CAP_CTRL_POLL) | 4051 | if (__is_ctrl_poll(chan, rx_control)) |
3589 | set_bit(CONN_SEND_FBIT, &chan->conn_state); | 4052 | set_bit(CONN_SEND_FBIT, &chan->conn_state); |
3590 | 4053 | ||
3591 | if (!test_bit(CONN_SREJ_SENT, &chan->conn_state)) { | 4054 | if (!test_bit(CONN_SREJ_SENT, &chan->conn_state)) { |
3592 | __clear_retrans_timer(chan); | 4055 | __clear_retrans_timer(chan); |
3593 | if (rx_control & L2CAP_CTRL_POLL) | 4056 | if (__is_ctrl_poll(chan, rx_control)) |
3594 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL); | 4057 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL); |
3595 | return; | 4058 | return; |
3596 | } | 4059 | } |
3597 | 4060 | ||
3598 | if (rx_control & L2CAP_CTRL_POLL) | 4061 | if (__is_ctrl_poll(chan, rx_control)) { |
3599 | l2cap_send_srejtail(chan); | 4062 | l2cap_send_srejtail(chan); |
3600 | else | 4063 | } else { |
3601 | l2cap_send_sframe(chan, L2CAP_SUPER_RCV_READY); | 4064 | rx_control = __set_ctrl_super(chan, L2CAP_SUPER_RR); |
4065 | l2cap_send_sframe(chan, rx_control); | ||
4066 | } | ||
3602 | } | 4067 | } |
3603 | 4068 | ||
3604 | static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_control, struct sk_buff *skb) | 4069 | static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u32 rx_control, struct sk_buff *skb) |
3605 | { | 4070 | { |
3606 | BT_DBG("chan %p rx_control 0x%4.4x len %d", chan, rx_control, skb->len); | 4071 | BT_DBG("chan %p rx_control 0x%8.8x len %d", chan, rx_control, skb->len); |
3607 | 4072 | ||
3608 | if (L2CAP_CTRL_FINAL & rx_control && | 4073 | if (__is_ctrl_final(chan, rx_control) && |
3609 | test_bit(CONN_WAIT_F, &chan->conn_state)) { | 4074 | test_bit(CONN_WAIT_F, &chan->conn_state)) { |
3610 | __clear_monitor_timer(chan); | 4075 | __clear_monitor_timer(chan); |
3611 | if (chan->unacked_frames > 0) | 4076 | if (chan->unacked_frames > 0) |
@@ -3613,20 +4078,20 @@ static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_cont | |||
3613 | clear_bit(CONN_WAIT_F, &chan->conn_state); | 4078 | clear_bit(CONN_WAIT_F, &chan->conn_state); |
3614 | } | 4079 | } |
3615 | 4080 | ||
3616 | switch (rx_control & L2CAP_CTRL_SUPERVISE) { | 4081 | switch (__get_ctrl_super(chan, rx_control)) { |
3617 | case L2CAP_SUPER_RCV_READY: | 4082 | case L2CAP_SUPER_RR: |
3618 | l2cap_data_channel_rrframe(chan, rx_control); | 4083 | l2cap_data_channel_rrframe(chan, rx_control); |
3619 | break; | 4084 | break; |
3620 | 4085 | ||
3621 | case L2CAP_SUPER_REJECT: | 4086 | case L2CAP_SUPER_REJ: |
3622 | l2cap_data_channel_rejframe(chan, rx_control); | 4087 | l2cap_data_channel_rejframe(chan, rx_control); |
3623 | break; | 4088 | break; |
3624 | 4089 | ||
3625 | case L2CAP_SUPER_SELECT_REJECT: | 4090 | case L2CAP_SUPER_SREJ: |
3626 | l2cap_data_channel_srejframe(chan, rx_control); | 4091 | l2cap_data_channel_srejframe(chan, rx_control); |
3627 | break; | 4092 | break; |
3628 | 4093 | ||
3629 | case L2CAP_SUPER_RCV_NOT_READY: | 4094 | case L2CAP_SUPER_RNR: |
3630 | l2cap_data_channel_rnrframe(chan, rx_control); | 4095 | l2cap_data_channel_rnrframe(chan, rx_control); |
3631 | break; | 4096 | break; |
3632 | } | 4097 | } |
@@ -3638,12 +4103,12 @@ static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u16 rx_cont | |||
3638 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) | 4103 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) |
3639 | { | 4104 | { |
3640 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 4105 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
3641 | u16 control; | 4106 | u32 control; |
3642 | u8 req_seq; | 4107 | u16 req_seq; |
3643 | int len, next_tx_seq_offset, req_seq_offset; | 4108 | int len, next_tx_seq_offset, req_seq_offset; |
3644 | 4109 | ||
3645 | control = get_unaligned_le16(skb->data); | 4110 | control = __get_control(chan, skb->data); |
3646 | skb_pull(skb, 2); | 4111 | skb_pull(skb, __ctrl_size(chan)); |
3647 | len = skb->len; | 4112 | len = skb->len; |
3648 | 4113 | ||
3649 | /* | 4114 | /* |
@@ -3654,26 +4119,23 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) | |||
3654 | if (l2cap_check_fcs(chan, skb)) | 4119 | if (l2cap_check_fcs(chan, skb)) |
3655 | goto drop; | 4120 | goto drop; |
3656 | 4121 | ||
3657 | if (__is_sar_start(control) && __is_iframe(control)) | 4122 | if (__is_sar_start(chan, control) && !__is_sframe(chan, control)) |
3658 | len -= 2; | 4123 | len -= L2CAP_SDULEN_SIZE; |
3659 | 4124 | ||
3660 | if (chan->fcs == L2CAP_FCS_CRC16) | 4125 | if (chan->fcs == L2CAP_FCS_CRC16) |
3661 | len -= 2; | 4126 | len -= L2CAP_FCS_SIZE; |
3662 | 4127 | ||
3663 | if (len > chan->mps) { | 4128 | if (len > chan->mps) { |
3664 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | 4129 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
3665 | goto drop; | 4130 | goto drop; |
3666 | } | 4131 | } |
3667 | 4132 | ||
3668 | req_seq = __get_reqseq(control); | 4133 | req_seq = __get_reqseq(chan, control); |
3669 | req_seq_offset = (req_seq - chan->expected_ack_seq) % 64; | ||
3670 | if (req_seq_offset < 0) | ||
3671 | req_seq_offset += 64; | ||
3672 | 4134 | ||
3673 | next_tx_seq_offset = | 4135 | req_seq_offset = __seq_offset(chan, req_seq, chan->expected_ack_seq); |
3674 | (chan->next_tx_seq - chan->expected_ack_seq) % 64; | 4136 | |
3675 | if (next_tx_seq_offset < 0) | 4137 | next_tx_seq_offset = __seq_offset(chan, chan->next_tx_seq, |
3676 | next_tx_seq_offset += 64; | 4138 | chan->expected_ack_seq); |
3677 | 4139 | ||
3678 | /* check for invalid req-seq */ | 4140 | /* check for invalid req-seq */ |
3679 | if (req_seq_offset > next_tx_seq_offset) { | 4141 | if (req_seq_offset > next_tx_seq_offset) { |
@@ -3681,7 +4143,7 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb) | |||
3681 | goto drop; | 4143 | goto drop; |
3682 | } | 4144 | } |
3683 | 4145 | ||
3684 | if (__is_iframe(control)) { | 4146 | if (!__is_sframe(chan, control)) { |
3685 | if (len < 0) { | 4147 | if (len < 0) { |
3686 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | 4148 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
3687 | goto drop; | 4149 | goto drop; |
@@ -3709,8 +4171,8 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3709 | { | 4171 | { |
3710 | struct l2cap_chan *chan; | 4172 | struct l2cap_chan *chan; |
3711 | struct sock *sk = NULL; | 4173 | struct sock *sk = NULL; |
3712 | u16 control; | 4174 | u32 control; |
3713 | u8 tx_seq; | 4175 | u16 tx_seq; |
3714 | int len; | 4176 | int len; |
3715 | 4177 | ||
3716 | chan = l2cap_get_chan_by_scid(conn, cid); | 4178 | chan = l2cap_get_chan_by_scid(conn, cid); |
@@ -3751,23 +4213,23 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3751 | goto done; | 4213 | goto done; |
3752 | 4214 | ||
3753 | case L2CAP_MODE_STREAMING: | 4215 | case L2CAP_MODE_STREAMING: |
3754 | control = get_unaligned_le16(skb->data); | 4216 | control = __get_control(chan, skb->data); |
3755 | skb_pull(skb, 2); | 4217 | skb_pull(skb, __ctrl_size(chan)); |
3756 | len = skb->len; | 4218 | len = skb->len; |
3757 | 4219 | ||
3758 | if (l2cap_check_fcs(chan, skb)) | 4220 | if (l2cap_check_fcs(chan, skb)) |
3759 | goto drop; | 4221 | goto drop; |
3760 | 4222 | ||
3761 | if (__is_sar_start(control)) | 4223 | if (__is_sar_start(chan, control)) |
3762 | len -= 2; | 4224 | len -= L2CAP_SDULEN_SIZE; |
3763 | 4225 | ||
3764 | if (chan->fcs == L2CAP_FCS_CRC16) | 4226 | if (chan->fcs == L2CAP_FCS_CRC16) |
3765 | len -= 2; | 4227 | len -= L2CAP_FCS_SIZE; |
3766 | 4228 | ||
3767 | if (len > chan->mps || len < 0 || __is_sframe(control)) | 4229 | if (len > chan->mps || len < 0 || __is_sframe(chan, control)) |
3768 | goto drop; | 4230 | goto drop; |
3769 | 4231 | ||
3770 | tx_seq = __get_txseq(control); | 4232 | tx_seq = __get_txseq(chan, control); |
3771 | 4233 | ||
3772 | if (chan->expected_tx_seq != tx_seq) { | 4234 | if (chan->expected_tx_seq != tx_seq) { |
3773 | /* Frame(s) missing - must discard partial SDU */ | 4235 | /* Frame(s) missing - must discard partial SDU */ |
@@ -3779,7 +4241,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3779 | /* TODO: Notify userland of missing data */ | 4241 | /* TODO: Notify userland of missing data */ |
3780 | } | 4242 | } |
3781 | 4243 | ||
3782 | chan->expected_tx_seq = (tx_seq + 1) % 64; | 4244 | chan->expected_tx_seq = __next_seq(chan, tx_seq); |
3783 | 4245 | ||
3784 | if (l2cap_reassemble_sdu(chan, skb, control) == -EMSGSIZE) | 4246 | if (l2cap_reassemble_sdu(chan, skb, control) == -EMSGSIZE) |
3785 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); | 4247 | l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); |
@@ -3933,12 +4395,12 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
3933 | 4395 | ||
3934 | if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { | 4396 | if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { |
3935 | lm1 |= HCI_LM_ACCEPT; | 4397 | lm1 |= HCI_LM_ACCEPT; |
3936 | if (c->role_switch) | 4398 | if (test_bit(FLAG_ROLE_SWITCH, &c->flags)) |
3937 | lm1 |= HCI_LM_MASTER; | 4399 | lm1 |= HCI_LM_MASTER; |
3938 | exact++; | 4400 | exact++; |
3939 | } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { | 4401 | } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { |
3940 | lm2 |= HCI_LM_ACCEPT; | 4402 | lm2 |= HCI_LM_ACCEPT; |
3941 | if (c->role_switch) | 4403 | if (test_bit(FLAG_ROLE_SWITCH, &c->flags)) |
3942 | lm2 |= HCI_LM_MASTER; | 4404 | lm2 |= HCI_LM_MASTER; |
3943 | } | 4405 | } |
3944 | } | 4406 | } |
@@ -3973,7 +4435,7 @@ static int l2cap_disconn_ind(struct hci_conn *hcon) | |||
3973 | BT_DBG("hcon %p", hcon); | 4435 | BT_DBG("hcon %p", hcon); |
3974 | 4436 | ||
3975 | if ((hcon->type != ACL_LINK && hcon->type != LE_LINK) || !conn) | 4437 | if ((hcon->type != ACL_LINK && hcon->type != LE_LINK) || !conn) |
3976 | return 0x13; | 4438 | return HCI_ERROR_REMOTE_USER_TERM; |
3977 | 4439 | ||
3978 | return conn->disc_reason; | 4440 | return conn->disc_reason; |
3979 | } | 4441 | } |
@@ -4306,3 +4768,6 @@ void l2cap_exit(void) | |||
4306 | 4768 | ||
4307 | module_param(disable_ertm, bool, 0644); | 4769 | module_param(disable_ertm, bool, 0644); |
4308 | MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode"); | 4770 | MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode"); |
4771 | |||
4772 | module_param(enable_hs, bool, 0644); | ||
4773 | MODULE_PARM_DESC(enable_hs, "Enable High Speed"); | ||
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 5c406d3136f7..e2e785c74630 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -334,7 +334,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
334 | opts.mode = chan->mode; | 334 | opts.mode = chan->mode; |
335 | opts.fcs = chan->fcs; | 335 | opts.fcs = chan->fcs; |
336 | opts.max_tx = chan->max_tx; | 336 | opts.max_tx = chan->max_tx; |
337 | opts.txwin_size = (__u16)chan->tx_win; | 337 | opts.txwin_size = chan->tx_win; |
338 | 338 | ||
339 | len = min_t(unsigned int, len, sizeof(opts)); | 339 | len = min_t(unsigned int, len, sizeof(opts)); |
340 | if (copy_to_user(optval, (char *) &opts, len)) | 340 | if (copy_to_user(optval, (char *) &opts, len)) |
@@ -359,10 +359,10 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us | |||
359 | break; | 359 | break; |
360 | } | 360 | } |
361 | 361 | ||
362 | if (chan->role_switch) | 362 | if (test_bit(FLAG_ROLE_SWITCH, &chan->flags)) |
363 | opt |= L2CAP_LM_MASTER; | 363 | opt |= L2CAP_LM_MASTER; |
364 | 364 | ||
365 | if (chan->force_reliable) | 365 | if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) |
366 | opt |= L2CAP_LM_RELIABLE; | 366 | opt |= L2CAP_LM_RELIABLE; |
367 | 367 | ||
368 | if (put_user(opt, (u32 __user *) optval)) | 368 | if (put_user(opt, (u32 __user *) optval)) |
@@ -449,7 +449,8 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
449 | break; | 449 | break; |
450 | 450 | ||
451 | case BT_FLUSHABLE: | 451 | case BT_FLUSHABLE: |
452 | if (put_user(chan->flushable, (u32 __user *) optval)) | 452 | if (put_user(test_bit(FLAG_FLUSHABLE, &chan->flags), |
453 | (u32 __user *) optval)) | ||
453 | err = -EFAULT; | 454 | err = -EFAULT; |
454 | 455 | ||
455 | break; | 456 | break; |
@@ -461,7 +462,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
461 | break; | 462 | break; |
462 | } | 463 | } |
463 | 464 | ||
464 | pwr.force_active = chan->force_active; | 465 | pwr.force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags); |
465 | 466 | ||
466 | len = min_t(unsigned int, len, sizeof(pwr)); | 467 | len = min_t(unsigned int, len, sizeof(pwr)); |
467 | if (copy_to_user(optval, (char *) &pwr, len)) | 468 | if (copy_to_user(optval, (char *) &pwr, len)) |
@@ -469,6 +470,16 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch | |||
469 | 470 | ||
470 | break; | 471 | break; |
471 | 472 | ||
473 | case BT_CHANNEL_POLICY: | ||
474 | if (!enable_hs) { | ||
475 | err = -ENOPROTOOPT; | ||
476 | break; | ||
477 | } | ||
478 | |||
479 | if (put_user(chan->chan_policy, (u32 __user *) optval)) | ||
480 | err = -EFAULT; | ||
481 | break; | ||
482 | |||
472 | default: | 483 | default: |
473 | err = -ENOPROTOOPT; | 484 | err = -ENOPROTOOPT; |
474 | break; | 485 | break; |
@@ -503,7 +514,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
503 | opts.mode = chan->mode; | 514 | opts.mode = chan->mode; |
504 | opts.fcs = chan->fcs; | 515 | opts.fcs = chan->fcs; |
505 | opts.max_tx = chan->max_tx; | 516 | opts.max_tx = chan->max_tx; |
506 | opts.txwin_size = (__u16)chan->tx_win; | 517 | opts.txwin_size = chan->tx_win; |
507 | 518 | ||
508 | len = min_t(unsigned int, sizeof(opts), optlen); | 519 | len = min_t(unsigned int, sizeof(opts), optlen); |
509 | if (copy_from_user((char *) &opts, optval, len)) { | 520 | if (copy_from_user((char *) &opts, optval, len)) { |
@@ -511,7 +522,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
511 | break; | 522 | break; |
512 | } | 523 | } |
513 | 524 | ||
514 | if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) { | 525 | if (opts.txwin_size > L2CAP_DEFAULT_EXT_WINDOW) { |
515 | err = -EINVAL; | 526 | err = -EINVAL; |
516 | break; | 527 | break; |
517 | } | 528 | } |
@@ -535,7 +546,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
535 | chan->omtu = opts.omtu; | 546 | chan->omtu = opts.omtu; |
536 | chan->fcs = opts.fcs; | 547 | chan->fcs = opts.fcs; |
537 | chan->max_tx = opts.max_tx; | 548 | chan->max_tx = opts.max_tx; |
538 | chan->tx_win = (__u8)opts.txwin_size; | 549 | chan->tx_win = opts.txwin_size; |
539 | break; | 550 | break; |
540 | 551 | ||
541 | case L2CAP_LM: | 552 | case L2CAP_LM: |
@@ -551,8 +562,15 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
551 | if (opt & L2CAP_LM_SECURE) | 562 | if (opt & L2CAP_LM_SECURE) |
552 | chan->sec_level = BT_SECURITY_HIGH; | 563 | chan->sec_level = BT_SECURITY_HIGH; |
553 | 564 | ||
554 | chan->role_switch = (opt & L2CAP_LM_MASTER); | 565 | if (opt & L2CAP_LM_MASTER) |
555 | chan->force_reliable = (opt & L2CAP_LM_RELIABLE); | 566 | set_bit(FLAG_ROLE_SWITCH, &chan->flags); |
567 | else | ||
568 | clear_bit(FLAG_ROLE_SWITCH, &chan->flags); | ||
569 | |||
570 | if (opt & L2CAP_LM_RELIABLE) | ||
571 | set_bit(FLAG_FORCE_RELIABLE, &chan->flags); | ||
572 | else | ||
573 | clear_bit(FLAG_FORCE_RELIABLE, &chan->flags); | ||
556 | break; | 574 | break; |
557 | 575 | ||
558 | default: | 576 | default: |
@@ -658,7 +676,10 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
658 | } | 676 | } |
659 | } | 677 | } |
660 | 678 | ||
661 | chan->flushable = opt; | 679 | if (opt) |
680 | set_bit(FLAG_FLUSHABLE, &chan->flags); | ||
681 | else | ||
682 | clear_bit(FLAG_FLUSHABLE, &chan->flags); | ||
662 | break; | 683 | break; |
663 | 684 | ||
664 | case BT_POWER: | 685 | case BT_POWER: |
@@ -675,7 +696,36 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch | |||
675 | err = -EFAULT; | 696 | err = -EFAULT; |
676 | break; | 697 | break; |
677 | } | 698 | } |
678 | chan->force_active = pwr.force_active; | 699 | |
700 | if (pwr.force_active) | ||
701 | set_bit(FLAG_FORCE_ACTIVE, &chan->flags); | ||
702 | else | ||
703 | clear_bit(FLAG_FORCE_ACTIVE, &chan->flags); | ||
704 | break; | ||
705 | |||
706 | case BT_CHANNEL_POLICY: | ||
707 | if (!enable_hs) { | ||
708 | err = -ENOPROTOOPT; | ||
709 | break; | ||
710 | } | ||
711 | |||
712 | if (get_user(opt, (u32 __user *) optval)) { | ||
713 | err = -EFAULT; | ||
714 | break; | ||
715 | } | ||
716 | |||
717 | if (opt > BT_CHANNEL_POLICY_AMP_PREFERRED) { | ||
718 | err = -EINVAL; | ||
719 | break; | ||
720 | } | ||
721 | |||
722 | if (chan->mode != L2CAP_MODE_ERTM && | ||
723 | chan->mode != L2CAP_MODE_STREAMING) { | ||
724 | err = -EOPNOTSUPP; | ||
725 | break; | ||
726 | } | ||
727 | |||
728 | chan->chan_policy = (u8) opt; | ||
679 | break; | 729 | break; |
680 | 730 | ||
681 | default: | 731 | default: |
@@ -709,7 +759,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
709 | return -ENOTCONN; | 759 | return -ENOTCONN; |
710 | } | 760 | } |
711 | 761 | ||
712 | err = l2cap_chan_send(chan, msg, len); | 762 | err = l2cap_chan_send(chan, msg, len, sk->sk_priority); |
713 | 763 | ||
714 | release_sock(sk); | 764 | release_sock(sk); |
715 | return err; | 765 | return err; |
@@ -931,11 +981,9 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
931 | chan->fcs = pchan->fcs; | 981 | chan->fcs = pchan->fcs; |
932 | chan->max_tx = pchan->max_tx; | 982 | chan->max_tx = pchan->max_tx; |
933 | chan->tx_win = pchan->tx_win; | 983 | chan->tx_win = pchan->tx_win; |
984 | chan->tx_win_max = pchan->tx_win_max; | ||
934 | chan->sec_level = pchan->sec_level; | 985 | chan->sec_level = pchan->sec_level; |
935 | chan->role_switch = pchan->role_switch; | 986 | chan->flags = pchan->flags; |
936 | chan->force_reliable = pchan->force_reliable; | ||
937 | chan->flushable = pchan->flushable; | ||
938 | chan->force_active = pchan->force_active; | ||
939 | 987 | ||
940 | security_sk_clone(parent, sk); | 988 | security_sk_clone(parent, sk); |
941 | } else { | 989 | } else { |
@@ -964,12 +1012,10 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) | |||
964 | chan->max_tx = L2CAP_DEFAULT_MAX_TX; | 1012 | chan->max_tx = L2CAP_DEFAULT_MAX_TX; |
965 | chan->fcs = L2CAP_FCS_CRC16; | 1013 | chan->fcs = L2CAP_FCS_CRC16; |
966 | chan->tx_win = L2CAP_DEFAULT_TX_WINDOW; | 1014 | chan->tx_win = L2CAP_DEFAULT_TX_WINDOW; |
1015 | chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; | ||
967 | chan->sec_level = BT_SECURITY_LOW; | 1016 | chan->sec_level = BT_SECURITY_LOW; |
968 | chan->role_switch = 0; | 1017 | chan->flags = 0; |
969 | chan->force_reliable = 0; | 1018 | set_bit(FLAG_FORCE_ACTIVE, &chan->flags); |
970 | chan->flushable = BT_FLUSHABLE_OFF; | ||
971 | chan->force_active = BT_POWER_FORCE_ACTIVE_ON; | ||
972 | |||
973 | } | 1019 | } |
974 | 1020 | ||
975 | /* Default config options */ | 1021 | /* Default config options */ |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 2c7634296866..94739d3c4f59 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -33,22 +33,23 @@ | |||
33 | #define MGMT_VERSION 0 | 33 | #define MGMT_VERSION 0 |
34 | #define MGMT_REVISION 1 | 34 | #define MGMT_REVISION 1 |
35 | 35 | ||
36 | #define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */ | ||
37 | |||
36 | struct pending_cmd { | 38 | struct pending_cmd { |
37 | struct list_head list; | 39 | struct list_head list; |
38 | __u16 opcode; | 40 | u16 opcode; |
39 | int index; | 41 | int index; |
40 | void *param; | 42 | void *param; |
41 | struct sock *sk; | 43 | struct sock *sk; |
42 | void *user_data; | 44 | void *user_data; |
43 | }; | 45 | }; |
44 | 46 | ||
45 | static LIST_HEAD(cmd_list); | ||
46 | |||
47 | static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) | 47 | static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) |
48 | { | 48 | { |
49 | struct sk_buff *skb; | 49 | struct sk_buff *skb; |
50 | struct mgmt_hdr *hdr; | 50 | struct mgmt_hdr *hdr; |
51 | struct mgmt_ev_cmd_status *ev; | 51 | struct mgmt_ev_cmd_status *ev; |
52 | int err; | ||
52 | 53 | ||
53 | BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status); | 54 | BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status); |
54 | 55 | ||
@@ -66,10 +67,11 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) | |||
66 | ev->status = status; | 67 | ev->status = status; |
67 | put_unaligned_le16(cmd, &ev->opcode); | 68 | put_unaligned_le16(cmd, &ev->opcode); |
68 | 69 | ||
69 | if (sock_queue_rcv_skb(sk, skb) < 0) | 70 | err = sock_queue_rcv_skb(sk, skb); |
71 | if (err < 0) | ||
70 | kfree_skb(skb); | 72 | kfree_skb(skb); |
71 | 73 | ||
72 | return 0; | 74 | return err; |
73 | } | 75 | } |
74 | 76 | ||
75 | static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp, | 77 | static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp, |
@@ -78,6 +80,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp, | |||
78 | struct sk_buff *skb; | 80 | struct sk_buff *skb; |
79 | struct mgmt_hdr *hdr; | 81 | struct mgmt_hdr *hdr; |
80 | struct mgmt_ev_cmd_complete *ev; | 82 | struct mgmt_ev_cmd_complete *ev; |
83 | int err; | ||
81 | 84 | ||
82 | BT_DBG("sock %p", sk); | 85 | BT_DBG("sock %p", sk); |
83 | 86 | ||
@@ -97,10 +100,11 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp, | |||
97 | if (rp) | 100 | if (rp) |
98 | memcpy(ev->data, rp, rp_len); | 101 | memcpy(ev->data, rp, rp_len); |
99 | 102 | ||
100 | if (sock_queue_rcv_skb(sk, skb) < 0) | 103 | err = sock_queue_rcv_skb(sk, skb); |
104 | if (err < 0) | ||
101 | kfree_skb(skb); | 105 | kfree_skb(skb); |
102 | 106 | ||
103 | return 0; | 107 | return err;; |
104 | } | 108 | } |
105 | 109 | ||
106 | static int read_version(struct sock *sk) | 110 | static int read_version(struct sock *sk) |
@@ -120,6 +124,7 @@ static int read_index_list(struct sock *sk) | |||
120 | { | 124 | { |
121 | struct mgmt_rp_read_index_list *rp; | 125 | struct mgmt_rp_read_index_list *rp; |
122 | struct list_head *p; | 126 | struct list_head *p; |
127 | struct hci_dev *d; | ||
123 | size_t rp_len; | 128 | size_t rp_len; |
124 | u16 count; | 129 | u16 count; |
125 | int i, err; | 130 | int i, err; |
@@ -143,10 +148,9 @@ static int read_index_list(struct sock *sk) | |||
143 | put_unaligned_le16(count, &rp->num_controllers); | 148 | put_unaligned_le16(count, &rp->num_controllers); |
144 | 149 | ||
145 | i = 0; | 150 | i = 0; |
146 | list_for_each(p, &hci_dev_list) { | 151 | list_for_each_entry(d, &hci_dev_list, list) { |
147 | struct hci_dev *d = list_entry(p, struct hci_dev, list); | 152 | if (test_and_clear_bit(HCI_AUTO_OFF, &d->flags)) |
148 | 153 | cancel_delayed_work(&d->power_off); | |
149 | hci_del_off_timer(d); | ||
150 | 154 | ||
151 | if (test_bit(HCI_SETUP, &d->flags)) | 155 | if (test_bit(HCI_SETUP, &d->flags)) |
152 | continue; | 156 | continue; |
@@ -176,7 +180,8 @@ static int read_controller_info(struct sock *sk, u16 index) | |||
176 | if (!hdev) | 180 | if (!hdev) |
177 | return cmd_status(sk, index, MGMT_OP_READ_INFO, ENODEV); | 181 | return cmd_status(sk, index, MGMT_OP_READ_INFO, ENODEV); |
178 | 182 | ||
179 | hci_del_off_timer(hdev); | 183 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) |
184 | cancel_delayed_work_sync(&hdev->power_off); | ||
180 | 185 | ||
181 | hci_dev_lock_bh(hdev); | 186 | hci_dev_lock_bh(hdev); |
182 | 187 | ||
@@ -221,7 +226,8 @@ static void mgmt_pending_free(struct pending_cmd *cmd) | |||
221 | } | 226 | } |
222 | 227 | ||
223 | static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | 228 | static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, |
224 | u16 index, void *data, u16 len) | 229 | struct hci_dev *hdev, |
230 | void *data, u16 len) | ||
225 | { | 231 | { |
226 | struct pending_cmd *cmd; | 232 | struct pending_cmd *cmd; |
227 | 233 | ||
@@ -230,7 +236,7 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | |||
230 | return NULL; | 236 | return NULL; |
231 | 237 | ||
232 | cmd->opcode = opcode; | 238 | cmd->opcode = opcode; |
233 | cmd->index = index; | 239 | cmd->index = hdev->id; |
234 | 240 | ||
235 | cmd->param = kmalloc(len, GFP_ATOMIC); | 241 | cmd->param = kmalloc(len, GFP_ATOMIC); |
236 | if (!cmd->param) { | 242 | if (!cmd->param) { |
@@ -244,48 +250,36 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | |||
244 | cmd->sk = sk; | 250 | cmd->sk = sk; |
245 | sock_hold(sk); | 251 | sock_hold(sk); |
246 | 252 | ||
247 | list_add(&cmd->list, &cmd_list); | 253 | list_add(&cmd->list, &hdev->mgmt_pending); |
248 | 254 | ||
249 | return cmd; | 255 | return cmd; |
250 | } | 256 | } |
251 | 257 | ||
252 | static void mgmt_pending_foreach(u16 opcode, int index, | 258 | static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, |
253 | void (*cb)(struct pending_cmd *cmd, void *data), | 259 | void (*cb)(struct pending_cmd *cmd, void *data), |
254 | void *data) | 260 | void *data) |
255 | { | 261 | { |
256 | struct list_head *p, *n; | 262 | struct list_head *p, *n; |
257 | 263 | ||
258 | list_for_each_safe(p, n, &cmd_list) { | 264 | list_for_each_safe(p, n, &hdev->mgmt_pending) { |
259 | struct pending_cmd *cmd; | 265 | struct pending_cmd *cmd; |
260 | 266 | ||
261 | cmd = list_entry(p, struct pending_cmd, list); | 267 | cmd = list_entry(p, struct pending_cmd, list); |
262 | 268 | ||
263 | if (cmd->opcode != opcode) | 269 | if (opcode > 0 && cmd->opcode != opcode) |
264 | continue; | ||
265 | |||
266 | if (index >= 0 && cmd->index != index) | ||
267 | continue; | 270 | continue; |
268 | 271 | ||
269 | cb(cmd, data); | 272 | cb(cmd, data); |
270 | } | 273 | } |
271 | } | 274 | } |
272 | 275 | ||
273 | static struct pending_cmd *mgmt_pending_find(u16 opcode, int index) | 276 | static struct pending_cmd *mgmt_pending_find(u16 opcode, struct hci_dev *hdev) |
274 | { | 277 | { |
275 | struct list_head *p; | 278 | struct pending_cmd *cmd; |
276 | |||
277 | list_for_each(p, &cmd_list) { | ||
278 | struct pending_cmd *cmd; | ||
279 | |||
280 | cmd = list_entry(p, struct pending_cmd, list); | ||
281 | |||
282 | if (cmd->opcode != opcode) | ||
283 | continue; | ||
284 | |||
285 | if (index >= 0 && cmd->index != index) | ||
286 | continue; | ||
287 | 279 | ||
288 | return cmd; | 280 | list_for_each_entry(cmd, &hdev->mgmt_pending, list) { |
281 | if (cmd->opcode == opcode) | ||
282 | return cmd; | ||
289 | } | 283 | } |
290 | 284 | ||
291 | return NULL; | 285 | return NULL; |
@@ -323,12 +317,12 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
323 | goto failed; | 317 | goto failed; |
324 | } | 318 | } |
325 | 319 | ||
326 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, index)) { | 320 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) { |
327 | err = cmd_status(sk, index, MGMT_OP_SET_POWERED, EBUSY); | 321 | err = cmd_status(sk, index, MGMT_OP_SET_POWERED, EBUSY); |
328 | goto failed; | 322 | goto failed; |
329 | } | 323 | } |
330 | 324 | ||
331 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, index, data, len); | 325 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev, data, len); |
332 | if (!cmd) { | 326 | if (!cmd) { |
333 | err = -ENOMEM; | 327 | err = -ENOMEM; |
334 | goto failed; | 328 | goto failed; |
@@ -337,7 +331,7 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
337 | if (cp->val) | 331 | if (cp->val) |
338 | queue_work(hdev->workqueue, &hdev->power_on); | 332 | queue_work(hdev->workqueue, &hdev->power_on); |
339 | else | 333 | else |
340 | queue_work(hdev->workqueue, &hdev->power_off); | 334 | queue_work(hdev->workqueue, &hdev->power_off.work); |
341 | 335 | ||
342 | err = 0; | 336 | err = 0; |
343 | 337 | ||
@@ -350,7 +344,7 @@ failed: | |||
350 | static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | 344 | static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, |
351 | u16 len) | 345 | u16 len) |
352 | { | 346 | { |
353 | struct mgmt_mode *cp; | 347 | struct mgmt_cp_set_discoverable *cp; |
354 | struct hci_dev *hdev; | 348 | struct hci_dev *hdev; |
355 | struct pending_cmd *cmd; | 349 | struct pending_cmd *cmd; |
356 | u8 scan; | 350 | u8 scan; |
@@ -374,8 +368,8 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
374 | goto failed; | 368 | goto failed; |
375 | } | 369 | } |
376 | 370 | ||
377 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, index) || | 371 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || |
378 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, index)) { | 372 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { |
379 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EBUSY); | 373 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EBUSY); |
380 | goto failed; | 374 | goto failed; |
381 | } | 375 | } |
@@ -386,7 +380,7 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
386 | goto failed; | 380 | goto failed; |
387 | } | 381 | } |
388 | 382 | ||
389 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, index, data, len); | 383 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, hdev, data, len); |
390 | if (!cmd) { | 384 | if (!cmd) { |
391 | err = -ENOMEM; | 385 | err = -ENOMEM; |
392 | goto failed; | 386 | goto failed; |
@@ -396,11 +390,16 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
396 | 390 | ||
397 | if (cp->val) | 391 | if (cp->val) |
398 | scan |= SCAN_INQUIRY; | 392 | scan |= SCAN_INQUIRY; |
393 | else | ||
394 | cancel_delayed_work(&hdev->discov_off); | ||
399 | 395 | ||
400 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | 396 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); |
401 | if (err < 0) | 397 | if (err < 0) |
402 | mgmt_pending_remove(cmd); | 398 | mgmt_pending_remove(cmd); |
403 | 399 | ||
400 | if (cp->val) | ||
401 | hdev->discov_timeout = get_unaligned_le16(&cp->timeout); | ||
402 | |||
404 | failed: | 403 | failed: |
405 | hci_dev_unlock_bh(hdev); | 404 | hci_dev_unlock_bh(hdev); |
406 | hci_dev_put(hdev); | 405 | hci_dev_put(hdev); |
@@ -435,8 +434,8 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data, | |||
435 | goto failed; | 434 | goto failed; |
436 | } | 435 | } |
437 | 436 | ||
438 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, index) || | 437 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || |
439 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, index)) { | 438 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { |
440 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EBUSY); | 439 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EBUSY); |
441 | goto failed; | 440 | goto failed; |
442 | } | 441 | } |
@@ -446,7 +445,7 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data, | |||
446 | goto failed; | 445 | goto failed; |
447 | } | 446 | } |
448 | 447 | ||
449 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, index, data, len); | 448 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, hdev, data, len); |
450 | if (!cmd) { | 449 | if (!cmd) { |
451 | err = -ENOMEM; | 450 | err = -ENOMEM; |
452 | goto failed; | 451 | goto failed; |
@@ -468,8 +467,8 @@ failed: | |||
468 | return err; | 467 | return err; |
469 | } | 468 | } |
470 | 469 | ||
471 | static int mgmt_event(u16 event, u16 index, void *data, u16 data_len, | 470 | static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, |
472 | struct sock *skip_sk) | 471 | u16 data_len, struct sock *skip_sk) |
473 | { | 472 | { |
474 | struct sk_buff *skb; | 473 | struct sk_buff *skb; |
475 | struct mgmt_hdr *hdr; | 474 | struct mgmt_hdr *hdr; |
@@ -482,7 +481,10 @@ static int mgmt_event(u16 event, u16 index, void *data, u16 data_len, | |||
482 | 481 | ||
483 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | 482 | hdr = (void *) skb_put(skb, sizeof(*hdr)); |
484 | hdr->opcode = cpu_to_le16(event); | 483 | hdr->opcode = cpu_to_le16(event); |
485 | hdr->index = cpu_to_le16(index); | 484 | if (hdev) |
485 | hdr->index = cpu_to_le16(hdev->id); | ||
486 | else | ||
487 | hdr->index = cpu_to_le16(MGMT_INDEX_NONE); | ||
486 | hdr->len = cpu_to_le16(data_len); | 488 | hdr->len = cpu_to_le16(data_len); |
487 | 489 | ||
488 | if (data) | 490 | if (data) |
@@ -534,7 +536,7 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data, | |||
534 | 536 | ||
535 | ev.val = cp->val; | 537 | ev.val = cp->val; |
536 | 538 | ||
537 | err = mgmt_event(MGMT_EV_PAIRABLE, index, &ev, sizeof(ev), sk); | 539 | err = mgmt_event(MGMT_EV_PAIRABLE, hdev, &ev, sizeof(ev), sk); |
538 | 540 | ||
539 | failed: | 541 | failed: |
540 | hci_dev_unlock_bh(hdev); | 542 | hci_dev_unlock_bh(hdev); |
@@ -587,7 +589,7 @@ static void create_eir(struct hci_dev *hdev, u8 *data) | |||
587 | u16 eir_len = 0; | 589 | u16 eir_len = 0; |
588 | u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)]; | 590 | u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)]; |
589 | int i, truncated = 0; | 591 | int i, truncated = 0; |
590 | struct list_head *p; | 592 | struct bt_uuid *uuid; |
591 | size_t name_len; | 593 | size_t name_len; |
592 | 594 | ||
593 | name_len = strlen(hdev->dev_name); | 595 | name_len = strlen(hdev->dev_name); |
@@ -612,8 +614,7 @@ static void create_eir(struct hci_dev *hdev, u8 *data) | |||
612 | memset(uuid16_list, 0, sizeof(uuid16_list)); | 614 | memset(uuid16_list, 0, sizeof(uuid16_list)); |
613 | 615 | ||
614 | /* Group all UUID16 types */ | 616 | /* Group all UUID16 types */ |
615 | list_for_each(p, &hdev->uuids) { | 617 | list_for_each_entry(uuid, &hdev->uuids, list) { |
616 | struct bt_uuid *uuid = list_entry(p, struct bt_uuid, list); | ||
617 | u16 uuid16; | 618 | u16 uuid16; |
618 | 619 | ||
619 | uuid16 = get_uuid16(uuid->uuid); | 620 | uuid16 = get_uuid16(uuid->uuid); |
@@ -689,14 +690,11 @@ static int update_eir(struct hci_dev *hdev) | |||
689 | 690 | ||
690 | static u8 get_service_classes(struct hci_dev *hdev) | 691 | static u8 get_service_classes(struct hci_dev *hdev) |
691 | { | 692 | { |
692 | struct list_head *p; | 693 | struct bt_uuid *uuid; |
693 | u8 val = 0; | 694 | u8 val = 0; |
694 | 695 | ||
695 | list_for_each(p, &hdev->uuids) { | 696 | list_for_each_entry(uuid, &hdev->uuids, list) |
696 | struct bt_uuid *uuid = list_entry(p, struct bt_uuid, list); | ||
697 | |||
698 | val |= uuid->svc_hint; | 697 | val |= uuid->svc_hint; |
699 | } | ||
700 | 698 | ||
701 | return val; | 699 | return val; |
702 | } | 700 | } |
@@ -895,6 +893,9 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data, | |||
895 | if (err == 0) | 893 | if (err == 0) |
896 | err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL, | 894 | err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL, |
897 | 0); | 895 | 0); |
896 | else | ||
897 | cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, -err); | ||
898 | |||
898 | 899 | ||
899 | hci_dev_unlock_bh(hdev); | 900 | hci_dev_unlock_bh(hdev); |
900 | hci_dev_put(hdev); | 901 | hci_dev_put(hdev); |
@@ -902,30 +903,32 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data, | |||
902 | return err; | 903 | return err; |
903 | } | 904 | } |
904 | 905 | ||
905 | static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | 906 | static int load_link_keys(struct sock *sk, u16 index, unsigned char *data, |
907 | u16 len) | ||
906 | { | 908 | { |
907 | struct hci_dev *hdev; | 909 | struct hci_dev *hdev; |
908 | struct mgmt_cp_load_keys *cp; | 910 | struct mgmt_cp_load_link_keys *cp; |
909 | u16 key_count, expected_len; | 911 | u16 key_count, expected_len; |
910 | int i; | 912 | int i; |
911 | 913 | ||
912 | cp = (void *) data; | 914 | cp = (void *) data; |
913 | 915 | ||
914 | if (len < sizeof(*cp)) | 916 | if (len < sizeof(*cp)) |
915 | return -EINVAL; | 917 | return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS, EINVAL); |
916 | 918 | ||
917 | key_count = get_unaligned_le16(&cp->key_count); | 919 | key_count = get_unaligned_le16(&cp->key_count); |
918 | 920 | ||
919 | expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info); | 921 | expected_len = sizeof(*cp) + key_count * |
922 | sizeof(struct mgmt_link_key_info); | ||
920 | if (expected_len != len) { | 923 | if (expected_len != len) { |
921 | BT_ERR("load_keys: expected %u bytes, got %u bytes", | 924 | BT_ERR("load_link_keys: expected %u bytes, got %u bytes", |
922 | len, expected_len); | 925 | len, expected_len); |
923 | return -EINVAL; | 926 | return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS, EINVAL); |
924 | } | 927 | } |
925 | 928 | ||
926 | hdev = hci_dev_get(index); | 929 | hdev = hci_dev_get(index); |
927 | if (!hdev) | 930 | if (!hdev) |
928 | return cmd_status(sk, index, MGMT_OP_LOAD_KEYS, ENODEV); | 931 | return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS, ENODEV); |
929 | 932 | ||
930 | BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys, | 933 | BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys, |
931 | key_count); | 934 | key_count); |
@@ -942,7 +945,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
942 | clear_bit(HCI_DEBUG_KEYS, &hdev->flags); | 945 | clear_bit(HCI_DEBUG_KEYS, &hdev->flags); |
943 | 946 | ||
944 | for (i = 0; i < key_count; i++) { | 947 | for (i = 0; i < key_count; i++) { |
945 | struct mgmt_key_info *key = &cp->keys[i]; | 948 | struct mgmt_link_key_info *key = &cp->keys[i]; |
946 | 949 | ||
947 | hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type, | 950 | hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type, |
948 | key->pin_len); | 951 | key->pin_len); |
@@ -954,27 +957,28 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
954 | return 0; | 957 | return 0; |
955 | } | 958 | } |
956 | 959 | ||
957 | static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len) | 960 | static int remove_keys(struct sock *sk, u16 index, unsigned char *data, |
961 | u16 len) | ||
958 | { | 962 | { |
959 | struct hci_dev *hdev; | 963 | struct hci_dev *hdev; |
960 | struct mgmt_cp_remove_key *cp; | 964 | struct mgmt_cp_remove_keys *cp; |
961 | struct hci_conn *conn; | 965 | struct hci_conn *conn; |
962 | int err; | 966 | int err; |
963 | 967 | ||
964 | cp = (void *) data; | 968 | cp = (void *) data; |
965 | 969 | ||
966 | if (len != sizeof(*cp)) | 970 | if (len != sizeof(*cp)) |
967 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, EINVAL); | 971 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEYS, EINVAL); |
968 | 972 | ||
969 | hdev = hci_dev_get(index); | 973 | hdev = hci_dev_get(index); |
970 | if (!hdev) | 974 | if (!hdev) |
971 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV); | 975 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEYS, ENODEV); |
972 | 976 | ||
973 | hci_dev_lock_bh(hdev); | 977 | hci_dev_lock_bh(hdev); |
974 | 978 | ||
975 | err = hci_remove_link_key(hdev, &cp->bdaddr); | 979 | err = hci_remove_link_key(hdev, &cp->bdaddr); |
976 | if (err < 0) { | 980 | if (err < 0) { |
977 | err = cmd_status(sk, index, MGMT_OP_REMOVE_KEY, -err); | 981 | err = cmd_status(sk, index, MGMT_OP_REMOVE_KEYS, -err); |
978 | goto unlock; | 982 | goto unlock; |
979 | } | 983 | } |
980 | 984 | ||
@@ -1026,7 +1030,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1026 | goto failed; | 1030 | goto failed; |
1027 | } | 1031 | } |
1028 | 1032 | ||
1029 | if (mgmt_pending_find(MGMT_OP_DISCONNECT, index)) { | 1033 | if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) { |
1030 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, EBUSY); | 1034 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, EBUSY); |
1031 | goto failed; | 1035 | goto failed; |
1032 | } | 1036 | } |
@@ -1040,7 +1044,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1040 | goto failed; | 1044 | goto failed; |
1041 | } | 1045 | } |
1042 | 1046 | ||
1043 | cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, index, data, len); | 1047 | cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, hdev, data, len); |
1044 | if (!cmd) { | 1048 | if (!cmd) { |
1045 | err = -ENOMEM; | 1049 | err = -ENOMEM; |
1046 | goto failed; | 1050 | goto failed; |
@@ -1060,10 +1064,23 @@ failed: | |||
1060 | return err; | 1064 | return err; |
1061 | } | 1065 | } |
1062 | 1066 | ||
1067 | static u8 link_to_mgmt(u8 link_type) | ||
1068 | { | ||
1069 | switch (link_type) { | ||
1070 | case LE_LINK: | ||
1071 | return MGMT_ADDR_LE; | ||
1072 | case ACL_LINK: | ||
1073 | return MGMT_ADDR_BREDR; | ||
1074 | default: | ||
1075 | return MGMT_ADDR_INVALID; | ||
1076 | } | ||
1077 | } | ||
1078 | |||
1063 | static int get_connections(struct sock *sk, u16 index) | 1079 | static int get_connections(struct sock *sk, u16 index) |
1064 | { | 1080 | { |
1065 | struct mgmt_rp_get_connections *rp; | 1081 | struct mgmt_rp_get_connections *rp; |
1066 | struct hci_dev *hdev; | 1082 | struct hci_dev *hdev; |
1083 | struct hci_conn *c; | ||
1067 | struct list_head *p; | 1084 | struct list_head *p; |
1068 | size_t rp_len; | 1085 | size_t rp_len; |
1069 | u16 count; | 1086 | u16 count; |
@@ -1082,7 +1099,7 @@ static int get_connections(struct sock *sk, u16 index) | |||
1082 | count++; | 1099 | count++; |
1083 | } | 1100 | } |
1084 | 1101 | ||
1085 | rp_len = sizeof(*rp) + (count * sizeof(bdaddr_t)); | 1102 | rp_len = sizeof(*rp) + (count * sizeof(struct mgmt_addr_info)); |
1086 | rp = kmalloc(rp_len, GFP_ATOMIC); | 1103 | rp = kmalloc(rp_len, GFP_ATOMIC); |
1087 | if (!rp) { | 1104 | if (!rp) { |
1088 | err = -ENOMEM; | 1105 | err = -ENOMEM; |
@@ -1092,12 +1109,17 @@ static int get_connections(struct sock *sk, u16 index) | |||
1092 | put_unaligned_le16(count, &rp->conn_count); | 1109 | put_unaligned_le16(count, &rp->conn_count); |
1093 | 1110 | ||
1094 | i = 0; | 1111 | i = 0; |
1095 | list_for_each(p, &hdev->conn_hash.list) { | 1112 | list_for_each_entry(c, &hdev->conn_hash.list, list) { |
1096 | struct hci_conn *c = list_entry(p, struct hci_conn, list); | 1113 | bacpy(&rp->addr[i].bdaddr, &c->dst); |
1097 | 1114 | rp->addr[i].type = link_to_mgmt(c->type); | |
1098 | bacpy(&rp->conn[i++], &c->dst); | 1115 | if (rp->addr[i].type == MGMT_ADDR_INVALID) |
1116 | continue; | ||
1117 | i++; | ||
1099 | } | 1118 | } |
1100 | 1119 | ||
1120 | /* Recalculate length in case of filtered SCO connections, etc */ | ||
1121 | rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info)); | ||
1122 | |||
1101 | err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len); | 1123 | err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len); |
1102 | 1124 | ||
1103 | unlock: | 1125 | unlock: |
@@ -1113,7 +1135,7 @@ static int send_pin_code_neg_reply(struct sock *sk, u16 index, | |||
1113 | struct pending_cmd *cmd; | 1135 | struct pending_cmd *cmd; |
1114 | int err; | 1136 | int err; |
1115 | 1137 | ||
1116 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, index, cp, | 1138 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, hdev, cp, |
1117 | sizeof(*cp)); | 1139 | sizeof(*cp)); |
1118 | if (!cmd) | 1140 | if (!cmd) |
1119 | return -ENOMEM; | 1141 | return -ENOMEM; |
@@ -1174,7 +1196,7 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1174 | goto failed; | 1196 | goto failed; |
1175 | } | 1197 | } |
1176 | 1198 | ||
1177 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, index, data, len); | 1199 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, hdev, data, len); |
1178 | if (!cmd) { | 1200 | if (!cmd) { |
1179 | err = -ENOMEM; | 1201 | err = -ENOMEM; |
1180 | goto failed; | 1202 | goto failed; |
@@ -1265,19 +1287,12 @@ static int set_io_capability(struct sock *sk, u16 index, unsigned char *data, | |||
1265 | static inline struct pending_cmd *find_pairing(struct hci_conn *conn) | 1287 | static inline struct pending_cmd *find_pairing(struct hci_conn *conn) |
1266 | { | 1288 | { |
1267 | struct hci_dev *hdev = conn->hdev; | 1289 | struct hci_dev *hdev = conn->hdev; |
1268 | struct list_head *p; | 1290 | struct pending_cmd *cmd; |
1269 | |||
1270 | list_for_each(p, &cmd_list) { | ||
1271 | struct pending_cmd *cmd; | ||
1272 | |||
1273 | cmd = list_entry(p, struct pending_cmd, list); | ||
1274 | 1291 | ||
1292 | list_for_each_entry(cmd, &hdev->mgmt_pending, list) { | ||
1275 | if (cmd->opcode != MGMT_OP_PAIR_DEVICE) | 1293 | if (cmd->opcode != MGMT_OP_PAIR_DEVICE) |
1276 | continue; | 1294 | continue; |
1277 | 1295 | ||
1278 | if (cmd->index != hdev->id) | ||
1279 | continue; | ||
1280 | |||
1281 | if (cmd->user_data != conn) | 1296 | if (cmd->user_data != conn) |
1282 | continue; | 1297 | continue; |
1283 | 1298 | ||
@@ -1310,16 +1325,19 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status) | |||
1310 | static void pairing_complete_cb(struct hci_conn *conn, u8 status) | 1325 | static void pairing_complete_cb(struct hci_conn *conn, u8 status) |
1311 | { | 1326 | { |
1312 | struct pending_cmd *cmd; | 1327 | struct pending_cmd *cmd; |
1328 | struct hci_dev *hdev = conn->hdev; | ||
1313 | 1329 | ||
1314 | BT_DBG("status %u", status); | 1330 | BT_DBG("status %u", status); |
1315 | 1331 | ||
1332 | hci_dev_lock_bh(hdev); | ||
1333 | |||
1316 | cmd = find_pairing(conn); | 1334 | cmd = find_pairing(conn); |
1317 | if (!cmd) { | 1335 | if (!cmd) |
1318 | BT_DBG("Unable to find a pending command"); | 1336 | BT_DBG("Unable to find a pending command"); |
1319 | return; | 1337 | else |
1320 | } | 1338 | pairing_complete(cmd, status); |
1321 | 1339 | ||
1322 | pairing_complete(cmd, status); | 1340 | hci_dev_unlock_bh(hdev); |
1323 | } | 1341 | } |
1324 | 1342 | ||
1325 | static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) | 1343 | static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) |
@@ -1370,7 +1388,7 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1370 | goto unlock; | 1388 | goto unlock; |
1371 | } | 1389 | } |
1372 | 1390 | ||
1373 | cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, index, data, len); | 1391 | cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, hdev, data, len); |
1374 | if (!cmd) { | 1392 | if (!cmd) { |
1375 | err = -ENOMEM; | 1393 | err = -ENOMEM; |
1376 | hci_conn_put(conn); | 1394 | hci_conn_put(conn); |
@@ -1432,7 +1450,7 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1432 | goto failed; | 1450 | goto failed; |
1433 | } | 1451 | } |
1434 | 1452 | ||
1435 | cmd = mgmt_pending_add(sk, mgmt_op, index, data, len); | 1453 | cmd = mgmt_pending_add(sk, mgmt_op, hdev, data, len); |
1436 | if (!cmd) { | 1454 | if (!cmd) { |
1437 | err = -ENOMEM; | 1455 | err = -ENOMEM; |
1438 | goto failed; | 1456 | goto failed; |
@@ -1469,7 +1487,7 @@ static int set_local_name(struct sock *sk, u16 index, unsigned char *data, | |||
1469 | 1487 | ||
1470 | hci_dev_lock_bh(hdev); | 1488 | hci_dev_lock_bh(hdev); |
1471 | 1489 | ||
1472 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, index, data, len); | 1490 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, data, len); |
1473 | if (!cmd) { | 1491 | if (!cmd) { |
1474 | err = -ENOMEM; | 1492 | err = -ENOMEM; |
1475 | goto failed; | 1493 | goto failed; |
@@ -1515,12 +1533,12 @@ static int read_local_oob_data(struct sock *sk, u16 index) | |||
1515 | goto unlock; | 1533 | goto unlock; |
1516 | } | 1534 | } |
1517 | 1535 | ||
1518 | if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index)) { | 1536 | if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) { |
1519 | err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, EBUSY); | 1537 | err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, EBUSY); |
1520 | goto unlock; | 1538 | goto unlock; |
1521 | } | 1539 | } |
1522 | 1540 | ||
1523 | cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, index, NULL, 0); | 1541 | cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, hdev, NULL, 0); |
1524 | if (!cmd) { | 1542 | if (!cmd) { |
1525 | err = -ENOMEM; | 1543 | err = -ENOMEM; |
1526 | goto unlock; | 1544 | goto unlock; |
@@ -1607,8 +1625,6 @@ static int remove_remote_oob_data(struct sock *sk, u16 index, | |||
1607 | 1625 | ||
1608 | static int start_discovery(struct sock *sk, u16 index) | 1626 | static int start_discovery(struct sock *sk, u16 index) |
1609 | { | 1627 | { |
1610 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; | ||
1611 | struct hci_cp_inquiry cp; | ||
1612 | struct pending_cmd *cmd; | 1628 | struct pending_cmd *cmd; |
1613 | struct hci_dev *hdev; | 1629 | struct hci_dev *hdev; |
1614 | int err; | 1630 | int err; |
@@ -1621,18 +1637,18 @@ static int start_discovery(struct sock *sk, u16 index) | |||
1621 | 1637 | ||
1622 | hci_dev_lock_bh(hdev); | 1638 | hci_dev_lock_bh(hdev); |
1623 | 1639 | ||
1624 | cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, index, NULL, 0); | 1640 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1641 | err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY, ENETDOWN); | ||
1642 | goto failed; | ||
1643 | } | ||
1644 | |||
1645 | cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, hdev, NULL, 0); | ||
1625 | if (!cmd) { | 1646 | if (!cmd) { |
1626 | err = -ENOMEM; | 1647 | err = -ENOMEM; |
1627 | goto failed; | 1648 | goto failed; |
1628 | } | 1649 | } |
1629 | 1650 | ||
1630 | memset(&cp, 0, sizeof(cp)); | 1651 | err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR); |
1631 | memcpy(&cp.lap, lap, 3); | ||
1632 | cp.length = 0x08; | ||
1633 | cp.num_rsp = 0x00; | ||
1634 | |||
1635 | err = hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); | ||
1636 | if (err < 0) | 1652 | if (err < 0) |
1637 | mgmt_pending_remove(cmd); | 1653 | mgmt_pending_remove(cmd); |
1638 | 1654 | ||
@@ -1657,13 +1673,13 @@ static int stop_discovery(struct sock *sk, u16 index) | |||
1657 | 1673 | ||
1658 | hci_dev_lock_bh(hdev); | 1674 | hci_dev_lock_bh(hdev); |
1659 | 1675 | ||
1660 | cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, index, NULL, 0); | 1676 | cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0); |
1661 | if (!cmd) { | 1677 | if (!cmd) { |
1662 | err = -ENOMEM; | 1678 | err = -ENOMEM; |
1663 | goto failed; | 1679 | goto failed; |
1664 | } | 1680 | } |
1665 | 1681 | ||
1666 | err = hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); | 1682 | err = hci_cancel_inquiry(hdev); |
1667 | if (err < 0) | 1683 | if (err < 0) |
1668 | mgmt_pending_remove(cmd); | 1684 | mgmt_pending_remove(cmd); |
1669 | 1685 | ||
@@ -1678,7 +1694,6 @@ static int block_device(struct sock *sk, u16 index, unsigned char *data, | |||
1678 | u16 len) | 1694 | u16 len) |
1679 | { | 1695 | { |
1680 | struct hci_dev *hdev; | 1696 | struct hci_dev *hdev; |
1681 | struct pending_cmd *cmd; | ||
1682 | struct mgmt_cp_block_device *cp = (void *) data; | 1697 | struct mgmt_cp_block_device *cp = (void *) data; |
1683 | int err; | 1698 | int err; |
1684 | 1699 | ||
@@ -1695,23 +1710,13 @@ static int block_device(struct sock *sk, u16 index, unsigned char *data, | |||
1695 | 1710 | ||
1696 | hci_dev_lock_bh(hdev); | 1711 | hci_dev_lock_bh(hdev); |
1697 | 1712 | ||
1698 | cmd = mgmt_pending_add(sk, MGMT_OP_BLOCK_DEVICE, index, NULL, 0); | ||
1699 | if (!cmd) { | ||
1700 | err = -ENOMEM; | ||
1701 | goto failed; | ||
1702 | } | ||
1703 | |||
1704 | err = hci_blacklist_add(hdev, &cp->bdaddr); | 1713 | err = hci_blacklist_add(hdev, &cp->bdaddr); |
1705 | |||
1706 | if (err < 0) | 1714 | if (err < 0) |
1707 | err = cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, -err); | 1715 | err = cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, -err); |
1708 | else | 1716 | else |
1709 | err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, | 1717 | err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, |
1710 | NULL, 0); | 1718 | NULL, 0); |
1711 | 1719 | ||
1712 | mgmt_pending_remove(cmd); | ||
1713 | |||
1714 | failed: | ||
1715 | hci_dev_unlock_bh(hdev); | 1720 | hci_dev_unlock_bh(hdev); |
1716 | hci_dev_put(hdev); | 1721 | hci_dev_put(hdev); |
1717 | 1722 | ||
@@ -1722,7 +1727,6 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data, | |||
1722 | u16 len) | 1727 | u16 len) |
1723 | { | 1728 | { |
1724 | struct hci_dev *hdev; | 1729 | struct hci_dev *hdev; |
1725 | struct pending_cmd *cmd; | ||
1726 | struct mgmt_cp_unblock_device *cp = (void *) data; | 1730 | struct mgmt_cp_unblock_device *cp = (void *) data; |
1727 | int err; | 1731 | int err; |
1728 | 1732 | ||
@@ -1739,12 +1743,6 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data, | |||
1739 | 1743 | ||
1740 | hci_dev_lock_bh(hdev); | 1744 | hci_dev_lock_bh(hdev); |
1741 | 1745 | ||
1742 | cmd = mgmt_pending_add(sk, MGMT_OP_UNBLOCK_DEVICE, index, NULL, 0); | ||
1743 | if (!cmd) { | ||
1744 | err = -ENOMEM; | ||
1745 | goto failed; | ||
1746 | } | ||
1747 | |||
1748 | err = hci_blacklist_del(hdev, &cp->bdaddr); | 1746 | err = hci_blacklist_del(hdev, &cp->bdaddr); |
1749 | 1747 | ||
1750 | if (err < 0) | 1748 | if (err < 0) |
@@ -1753,9 +1751,6 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data, | |||
1753 | err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, | 1751 | err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, |
1754 | NULL, 0); | 1752 | NULL, 0); |
1755 | 1753 | ||
1756 | mgmt_pending_remove(cmd); | ||
1757 | |||
1758 | failed: | ||
1759 | hci_dev_unlock_bh(hdev); | 1754 | hci_dev_unlock_bh(hdev); |
1760 | hci_dev_put(hdev); | 1755 | hci_dev_put(hdev); |
1761 | 1756 | ||
@@ -1883,11 +1878,11 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
1883 | case MGMT_OP_SET_SERVICE_CACHE: | 1878 | case MGMT_OP_SET_SERVICE_CACHE: |
1884 | err = set_service_cache(sk, index, buf + sizeof(*hdr), len); | 1879 | err = set_service_cache(sk, index, buf + sizeof(*hdr), len); |
1885 | break; | 1880 | break; |
1886 | case MGMT_OP_LOAD_KEYS: | 1881 | case MGMT_OP_LOAD_LINK_KEYS: |
1887 | err = load_keys(sk, index, buf + sizeof(*hdr), len); | 1882 | err = load_link_keys(sk, index, buf + sizeof(*hdr), len); |
1888 | break; | 1883 | break; |
1889 | case MGMT_OP_REMOVE_KEY: | 1884 | case MGMT_OP_REMOVE_KEYS: |
1890 | err = remove_key(sk, index, buf + sizeof(*hdr), len); | 1885 | err = remove_keys(sk, index, buf + sizeof(*hdr), len); |
1891 | break; | 1886 | break; |
1892 | case MGMT_OP_DISCONNECT: | 1887 | case MGMT_OP_DISCONNECT: |
1893 | err = disconnect(sk, index, buf + sizeof(*hdr), len); | 1888 | err = disconnect(sk, index, buf + sizeof(*hdr), len); |
@@ -1958,14 +1953,26 @@ done: | |||
1958 | return err; | 1953 | return err; |
1959 | } | 1954 | } |
1960 | 1955 | ||
1961 | int mgmt_index_added(u16 index) | 1956 | static void cmd_status_rsp(struct pending_cmd *cmd, void *data) |
1962 | { | 1957 | { |
1963 | return mgmt_event(MGMT_EV_INDEX_ADDED, index, NULL, 0, NULL); | 1958 | u8 *status = data; |
1959 | |||
1960 | cmd_status(cmd->sk, cmd->index, cmd->opcode, *status); | ||
1961 | mgmt_pending_remove(cmd); | ||
1964 | } | 1962 | } |
1965 | 1963 | ||
1966 | int mgmt_index_removed(u16 index) | 1964 | int mgmt_index_added(struct hci_dev *hdev) |
1967 | { | 1965 | { |
1968 | return mgmt_event(MGMT_EV_INDEX_REMOVED, index, NULL, 0, NULL); | 1966 | return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL); |
1967 | } | ||
1968 | |||
1969 | int mgmt_index_removed(struct hci_dev *hdev) | ||
1970 | { | ||
1971 | u8 status = ENODEV; | ||
1972 | |||
1973 | mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); | ||
1974 | |||
1975 | return mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL); | ||
1969 | } | 1976 | } |
1970 | 1977 | ||
1971 | struct cmd_lookup { | 1978 | struct cmd_lookup { |
@@ -1993,17 +2000,22 @@ static void mode_rsp(struct pending_cmd *cmd, void *data) | |||
1993 | mgmt_pending_free(cmd); | 2000 | mgmt_pending_free(cmd); |
1994 | } | 2001 | } |
1995 | 2002 | ||
1996 | int mgmt_powered(u16 index, u8 powered) | 2003 | int mgmt_powered(struct hci_dev *hdev, u8 powered) |
1997 | { | 2004 | { |
1998 | struct mgmt_mode ev; | 2005 | struct mgmt_mode ev; |
1999 | struct cmd_lookup match = { powered, NULL }; | 2006 | struct cmd_lookup match = { powered, NULL }; |
2000 | int ret; | 2007 | int ret; |
2001 | 2008 | ||
2002 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match); | 2009 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, mode_rsp, &match); |
2010 | |||
2011 | if (!powered) { | ||
2012 | u8 status = ENETDOWN; | ||
2013 | mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); | ||
2014 | } | ||
2003 | 2015 | ||
2004 | ev.val = powered; | 2016 | ev.val = powered; |
2005 | 2017 | ||
2006 | ret = mgmt_event(MGMT_EV_POWERED, index, &ev, sizeof(ev), match.sk); | 2018 | ret = mgmt_event(MGMT_EV_POWERED, hdev, &ev, sizeof(ev), match.sk); |
2007 | 2019 | ||
2008 | if (match.sk) | 2020 | if (match.sk) |
2009 | sock_put(match.sk); | 2021 | sock_put(match.sk); |
@@ -2011,17 +2023,17 @@ int mgmt_powered(u16 index, u8 powered) | |||
2011 | return ret; | 2023 | return ret; |
2012 | } | 2024 | } |
2013 | 2025 | ||
2014 | int mgmt_discoverable(u16 index, u8 discoverable) | 2026 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) |
2015 | { | 2027 | { |
2016 | struct mgmt_mode ev; | 2028 | struct mgmt_mode ev; |
2017 | struct cmd_lookup match = { discoverable, NULL }; | 2029 | struct cmd_lookup match = { discoverable, NULL }; |
2018 | int ret; | 2030 | int ret; |
2019 | 2031 | ||
2020 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index, mode_rsp, &match); | 2032 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, mode_rsp, &match); |
2021 | 2033 | ||
2022 | ev.val = discoverable; | 2034 | ev.val = discoverable; |
2023 | 2035 | ||
2024 | ret = mgmt_event(MGMT_EV_DISCOVERABLE, index, &ev, sizeof(ev), | 2036 | ret = mgmt_event(MGMT_EV_DISCOVERABLE, hdev, &ev, sizeof(ev), |
2025 | match.sk); | 2037 | match.sk); |
2026 | 2038 | ||
2027 | if (match.sk) | 2039 | if (match.sk) |
@@ -2030,17 +2042,17 @@ int mgmt_discoverable(u16 index, u8 discoverable) | |||
2030 | return ret; | 2042 | return ret; |
2031 | } | 2043 | } |
2032 | 2044 | ||
2033 | int mgmt_connectable(u16 index, u8 connectable) | 2045 | int mgmt_connectable(struct hci_dev *hdev, u8 connectable) |
2034 | { | 2046 | { |
2035 | struct mgmt_mode ev; | 2047 | struct mgmt_mode ev; |
2036 | struct cmd_lookup match = { connectable, NULL }; | 2048 | struct cmd_lookup match = { connectable, NULL }; |
2037 | int ret; | 2049 | int ret; |
2038 | 2050 | ||
2039 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match); | 2051 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, mode_rsp, &match); |
2040 | 2052 | ||
2041 | ev.val = connectable; | 2053 | ev.val = connectable; |
2042 | 2054 | ||
2043 | ret = mgmt_event(MGMT_EV_CONNECTABLE, index, &ev, sizeof(ev), match.sk); | 2055 | ret = mgmt_event(MGMT_EV_CONNECTABLE, hdev, &ev, sizeof(ev), match.sk); |
2044 | 2056 | ||
2045 | if (match.sk) | 2057 | if (match.sk) |
2046 | sock_put(match.sk); | 2058 | sock_put(match.sk); |
@@ -2048,9 +2060,23 @@ int mgmt_connectable(u16 index, u8 connectable) | |||
2048 | return ret; | 2060 | return ret; |
2049 | } | 2061 | } |
2050 | 2062 | ||
2051 | int mgmt_new_key(u16 index, struct link_key *key, u8 persistent) | 2063 | int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status) |
2064 | { | ||
2065 | if (scan & SCAN_PAGE) | ||
2066 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, | ||
2067 | cmd_status_rsp, &status); | ||
2068 | |||
2069 | if (scan & SCAN_INQUIRY) | ||
2070 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, | ||
2071 | cmd_status_rsp, &status); | ||
2072 | |||
2073 | return 0; | ||
2074 | } | ||
2075 | |||
2076 | int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, | ||
2077 | u8 persistent) | ||
2052 | { | 2078 | { |
2053 | struct mgmt_ev_new_key ev; | 2079 | struct mgmt_ev_new_link_key ev; |
2054 | 2080 | ||
2055 | memset(&ev, 0, sizeof(ev)); | 2081 | memset(&ev, 0, sizeof(ev)); |
2056 | 2082 | ||
@@ -2060,17 +2086,17 @@ int mgmt_new_key(u16 index, struct link_key *key, u8 persistent) | |||
2060 | memcpy(ev.key.val, key->val, 16); | 2086 | memcpy(ev.key.val, key->val, 16); |
2061 | ev.key.pin_len = key->pin_len; | 2087 | ev.key.pin_len = key->pin_len; |
2062 | 2088 | ||
2063 | return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL); | 2089 | return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); |
2064 | } | 2090 | } |
2065 | 2091 | ||
2066 | int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type) | 2092 | int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type) |
2067 | { | 2093 | { |
2068 | struct mgmt_ev_connected ev; | 2094 | struct mgmt_addr_info ev; |
2069 | 2095 | ||
2070 | bacpy(&ev.bdaddr, bdaddr); | 2096 | bacpy(&ev.bdaddr, bdaddr); |
2071 | ev.link_type = link_type; | 2097 | ev.type = link_to_mgmt(link_type); |
2072 | 2098 | ||
2073 | return mgmt_event(MGMT_EV_CONNECTED, index, &ev, sizeof(ev), NULL); | 2099 | return mgmt_event(MGMT_EV_CONNECTED, hdev, &ev, sizeof(ev), NULL); |
2074 | } | 2100 | } |
2075 | 2101 | ||
2076 | static void disconnect_rsp(struct pending_cmd *cmd, void *data) | 2102 | static void disconnect_rsp(struct pending_cmd *cmd, void *data) |
@@ -2089,17 +2115,18 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data) | |||
2089 | mgmt_pending_remove(cmd); | 2115 | mgmt_pending_remove(cmd); |
2090 | } | 2116 | } |
2091 | 2117 | ||
2092 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr) | 2118 | int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) |
2093 | { | 2119 | { |
2094 | struct mgmt_ev_disconnected ev; | 2120 | struct mgmt_addr_info ev; |
2095 | struct sock *sk = NULL; | 2121 | struct sock *sk = NULL; |
2096 | int err; | 2122 | int err; |
2097 | 2123 | ||
2098 | mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk); | 2124 | mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk); |
2099 | 2125 | ||
2100 | bacpy(&ev.bdaddr, bdaddr); | 2126 | bacpy(&ev.bdaddr, bdaddr); |
2127 | ev.type = link_to_mgmt(type); | ||
2101 | 2128 | ||
2102 | err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk); | 2129 | err = mgmt_event(MGMT_EV_DISCONNECTED, hdev, &ev, sizeof(ev), sk); |
2103 | 2130 | ||
2104 | if (sk) | 2131 | if (sk) |
2105 | sock_put(sk); | 2132 | sock_put(sk); |
@@ -2107,57 +2134,60 @@ int mgmt_disconnected(u16 index, bdaddr_t *bdaddr) | |||
2107 | return err; | 2134 | return err; |
2108 | } | 2135 | } |
2109 | 2136 | ||
2110 | int mgmt_disconnect_failed(u16 index) | 2137 | int mgmt_disconnect_failed(struct hci_dev *hdev) |
2111 | { | 2138 | { |
2112 | struct pending_cmd *cmd; | 2139 | struct pending_cmd *cmd; |
2113 | int err; | 2140 | int err; |
2114 | 2141 | ||
2115 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, index); | 2142 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev); |
2116 | if (!cmd) | 2143 | if (!cmd) |
2117 | return -ENOENT; | 2144 | return -ENOENT; |
2118 | 2145 | ||
2119 | err = cmd_status(cmd->sk, index, MGMT_OP_DISCONNECT, EIO); | 2146 | err = cmd_status(cmd->sk, hdev->id, MGMT_OP_DISCONNECT, EIO); |
2120 | 2147 | ||
2121 | mgmt_pending_remove(cmd); | 2148 | mgmt_pending_remove(cmd); |
2122 | 2149 | ||
2123 | return err; | 2150 | return err; |
2124 | } | 2151 | } |
2125 | 2152 | ||
2126 | int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status) | 2153 | int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, |
2154 | u8 status) | ||
2127 | { | 2155 | { |
2128 | struct mgmt_ev_connect_failed ev; | 2156 | struct mgmt_ev_connect_failed ev; |
2129 | 2157 | ||
2130 | bacpy(&ev.bdaddr, bdaddr); | 2158 | bacpy(&ev.addr.bdaddr, bdaddr); |
2159 | ev.addr.type = link_to_mgmt(type); | ||
2131 | ev.status = status; | 2160 | ev.status = status; |
2132 | 2161 | ||
2133 | return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL); | 2162 | return mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL); |
2134 | } | 2163 | } |
2135 | 2164 | ||
2136 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure) | 2165 | int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure) |
2137 | { | 2166 | { |
2138 | struct mgmt_ev_pin_code_request ev; | 2167 | struct mgmt_ev_pin_code_request ev; |
2139 | 2168 | ||
2140 | bacpy(&ev.bdaddr, bdaddr); | 2169 | bacpy(&ev.bdaddr, bdaddr); |
2141 | ev.secure = secure; | 2170 | ev.secure = secure; |
2142 | 2171 | ||
2143 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev), | 2172 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, hdev, &ev, sizeof(ev), |
2144 | NULL); | 2173 | NULL); |
2145 | } | 2174 | } |
2146 | 2175 | ||
2147 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2176 | int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2177 | u8 status) | ||
2148 | { | 2178 | { |
2149 | struct pending_cmd *cmd; | 2179 | struct pending_cmd *cmd; |
2150 | struct mgmt_rp_pin_code_reply rp; | 2180 | struct mgmt_rp_pin_code_reply rp; |
2151 | int err; | 2181 | int err; |
2152 | 2182 | ||
2153 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, index); | 2183 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev); |
2154 | if (!cmd) | 2184 | if (!cmd) |
2155 | return -ENOENT; | 2185 | return -ENOENT; |
2156 | 2186 | ||
2157 | bacpy(&rp.bdaddr, bdaddr); | 2187 | bacpy(&rp.bdaddr, bdaddr); |
2158 | rp.status = status; | 2188 | rp.status = status; |
2159 | 2189 | ||
2160 | err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_REPLY, &rp, | 2190 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, &rp, |
2161 | sizeof(rp)); | 2191 | sizeof(rp)); |
2162 | 2192 | ||
2163 | mgmt_pending_remove(cmd); | 2193 | mgmt_pending_remove(cmd); |
@@ -2165,20 +2195,21 @@ int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | |||
2165 | return err; | 2195 | return err; |
2166 | } | 2196 | } |
2167 | 2197 | ||
2168 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2198 | int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2199 | u8 status) | ||
2169 | { | 2200 | { |
2170 | struct pending_cmd *cmd; | 2201 | struct pending_cmd *cmd; |
2171 | struct mgmt_rp_pin_code_reply rp; | 2202 | struct mgmt_rp_pin_code_reply rp; |
2172 | int err; | 2203 | int err; |
2173 | 2204 | ||
2174 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, index); | 2205 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev); |
2175 | if (!cmd) | 2206 | if (!cmd) |
2176 | return -ENOENT; | 2207 | return -ENOENT; |
2177 | 2208 | ||
2178 | bacpy(&rp.bdaddr, bdaddr); | 2209 | bacpy(&rp.bdaddr, bdaddr); |
2179 | rp.status = status; | 2210 | rp.status = status; |
2180 | 2211 | ||
2181 | err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, &rp, | 2212 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY, &rp, |
2182 | sizeof(rp)); | 2213 | sizeof(rp)); |
2183 | 2214 | ||
2184 | mgmt_pending_remove(cmd); | 2215 | mgmt_pending_remove(cmd); |
@@ -2186,97 +2217,93 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | |||
2186 | return err; | 2217 | return err; |
2187 | } | 2218 | } |
2188 | 2219 | ||
2189 | int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value, | 2220 | int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2190 | u8 confirm_hint) | 2221 | __le32 value, u8 confirm_hint) |
2191 | { | 2222 | { |
2192 | struct mgmt_ev_user_confirm_request ev; | 2223 | struct mgmt_ev_user_confirm_request ev; |
2193 | 2224 | ||
2194 | BT_DBG("hci%u", index); | 2225 | BT_DBG("%s", hdev->name); |
2195 | 2226 | ||
2196 | bacpy(&ev.bdaddr, bdaddr); | 2227 | bacpy(&ev.bdaddr, bdaddr); |
2197 | ev.confirm_hint = confirm_hint; | 2228 | ev.confirm_hint = confirm_hint; |
2198 | put_unaligned_le32(value, &ev.value); | 2229 | put_unaligned_le32(value, &ev.value); |
2199 | 2230 | ||
2200 | return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev), | 2231 | return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev), |
2201 | NULL); | 2232 | NULL); |
2202 | } | 2233 | } |
2203 | 2234 | ||
2204 | static int confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status, | 2235 | static int confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2205 | u8 opcode) | 2236 | u8 status, u8 opcode) |
2206 | { | 2237 | { |
2207 | struct pending_cmd *cmd; | 2238 | struct pending_cmd *cmd; |
2208 | struct mgmt_rp_user_confirm_reply rp; | 2239 | struct mgmt_rp_user_confirm_reply rp; |
2209 | int err; | 2240 | int err; |
2210 | 2241 | ||
2211 | cmd = mgmt_pending_find(opcode, index); | 2242 | cmd = mgmt_pending_find(opcode, hdev); |
2212 | if (!cmd) | 2243 | if (!cmd) |
2213 | return -ENOENT; | 2244 | return -ENOENT; |
2214 | 2245 | ||
2215 | bacpy(&rp.bdaddr, bdaddr); | 2246 | bacpy(&rp.bdaddr, bdaddr); |
2216 | rp.status = status; | 2247 | rp.status = status; |
2217 | err = cmd_complete(cmd->sk, index, opcode, &rp, sizeof(rp)); | 2248 | err = cmd_complete(cmd->sk, hdev->id, opcode, &rp, sizeof(rp)); |
2218 | 2249 | ||
2219 | mgmt_pending_remove(cmd); | 2250 | mgmt_pending_remove(cmd); |
2220 | 2251 | ||
2221 | return err; | 2252 | return err; |
2222 | } | 2253 | } |
2223 | 2254 | ||
2224 | int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2255 | int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2256 | u8 status) | ||
2225 | { | 2257 | { |
2226 | return confirm_reply_complete(index, bdaddr, status, | 2258 | return confirm_reply_complete(hdev, bdaddr, status, |
2227 | MGMT_OP_USER_CONFIRM_REPLY); | 2259 | MGMT_OP_USER_CONFIRM_REPLY); |
2228 | } | 2260 | } |
2229 | 2261 | ||
2230 | int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2262 | int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, |
2263 | bdaddr_t *bdaddr, u8 status) | ||
2231 | { | 2264 | { |
2232 | return confirm_reply_complete(index, bdaddr, status, | 2265 | return confirm_reply_complete(hdev, bdaddr, status, |
2233 | MGMT_OP_USER_CONFIRM_NEG_REPLY); | 2266 | MGMT_OP_USER_CONFIRM_NEG_REPLY); |
2234 | } | 2267 | } |
2235 | 2268 | ||
2236 | int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status) | 2269 | int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status) |
2237 | { | 2270 | { |
2238 | struct mgmt_ev_auth_failed ev; | 2271 | struct mgmt_ev_auth_failed ev; |
2239 | 2272 | ||
2240 | bacpy(&ev.bdaddr, bdaddr); | 2273 | bacpy(&ev.bdaddr, bdaddr); |
2241 | ev.status = status; | 2274 | ev.status = status; |
2242 | 2275 | ||
2243 | return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL); | 2276 | return mgmt_event(MGMT_EV_AUTH_FAILED, hdev, &ev, sizeof(ev), NULL); |
2244 | } | 2277 | } |
2245 | 2278 | ||
2246 | int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status) | 2279 | int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) |
2247 | { | 2280 | { |
2248 | struct pending_cmd *cmd; | 2281 | struct pending_cmd *cmd; |
2249 | struct hci_dev *hdev; | ||
2250 | struct mgmt_cp_set_local_name ev; | 2282 | struct mgmt_cp_set_local_name ev; |
2251 | int err; | 2283 | int err; |
2252 | 2284 | ||
2253 | memset(&ev, 0, sizeof(ev)); | 2285 | memset(&ev, 0, sizeof(ev)); |
2254 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); | 2286 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); |
2255 | 2287 | ||
2256 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, index); | 2288 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev); |
2257 | if (!cmd) | 2289 | if (!cmd) |
2258 | goto send_event; | 2290 | goto send_event; |
2259 | 2291 | ||
2260 | if (status) { | 2292 | if (status) { |
2261 | err = cmd_status(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, EIO); | 2293 | err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, |
2294 | EIO); | ||
2262 | goto failed; | 2295 | goto failed; |
2263 | } | 2296 | } |
2264 | 2297 | ||
2265 | hdev = hci_dev_get(index); | 2298 | update_eir(hdev); |
2266 | if (hdev) { | ||
2267 | hci_dev_lock_bh(hdev); | ||
2268 | update_eir(hdev); | ||
2269 | hci_dev_unlock_bh(hdev); | ||
2270 | hci_dev_put(hdev); | ||
2271 | } | ||
2272 | 2299 | ||
2273 | err = cmd_complete(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, &ev, | 2300 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, &ev, |
2274 | sizeof(ev)); | 2301 | sizeof(ev)); |
2275 | if (err < 0) | 2302 | if (err < 0) |
2276 | goto failed; | 2303 | goto failed; |
2277 | 2304 | ||
2278 | send_event: | 2305 | send_event: |
2279 | err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, index, &ev, sizeof(ev), | 2306 | err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev), |
2280 | cmd ? cmd->sk : NULL); | 2307 | cmd ? cmd->sk : NULL); |
2281 | 2308 | ||
2282 | failed: | 2309 | failed: |
@@ -2285,29 +2312,30 @@ failed: | |||
2285 | return err; | 2312 | return err; |
2286 | } | 2313 | } |
2287 | 2314 | ||
2288 | int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, | 2315 | int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, |
2289 | u8 status) | 2316 | u8 *randomizer, u8 status) |
2290 | { | 2317 | { |
2291 | struct pending_cmd *cmd; | 2318 | struct pending_cmd *cmd; |
2292 | int err; | 2319 | int err; |
2293 | 2320 | ||
2294 | BT_DBG("hci%u status %u", index, status); | 2321 | BT_DBG("%s status %u", hdev->name, status); |
2295 | 2322 | ||
2296 | cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index); | 2323 | cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev); |
2297 | if (!cmd) | 2324 | if (!cmd) |
2298 | return -ENOENT; | 2325 | return -ENOENT; |
2299 | 2326 | ||
2300 | if (status) { | 2327 | if (status) { |
2301 | err = cmd_status(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 2328 | err = cmd_status(cmd->sk, hdev->id, |
2302 | EIO); | 2329 | MGMT_OP_READ_LOCAL_OOB_DATA, EIO); |
2303 | } else { | 2330 | } else { |
2304 | struct mgmt_rp_read_local_oob_data rp; | 2331 | struct mgmt_rp_read_local_oob_data rp; |
2305 | 2332 | ||
2306 | memcpy(rp.hash, hash, sizeof(rp.hash)); | 2333 | memcpy(rp.hash, hash, sizeof(rp.hash)); |
2307 | memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer)); | 2334 | memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer)); |
2308 | 2335 | ||
2309 | err = cmd_complete(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 2336 | err = cmd_complete(cmd->sk, hdev->id, |
2310 | &rp, sizeof(rp)); | 2337 | MGMT_OP_READ_LOCAL_OOB_DATA, |
2338 | &rp, sizeof(rp)); | ||
2311 | } | 2339 | } |
2312 | 2340 | ||
2313 | mgmt_pending_remove(cmd); | 2341 | mgmt_pending_remove(cmd); |
@@ -2315,14 +2343,15 @@ int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, | |||
2315 | return err; | 2343 | return err; |
2316 | } | 2344 | } |
2317 | 2345 | ||
2318 | int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, | 2346 | int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, |
2319 | u8 *eir) | 2347 | u8 *dev_class, s8 rssi, u8 *eir) |
2320 | { | 2348 | { |
2321 | struct mgmt_ev_device_found ev; | 2349 | struct mgmt_ev_device_found ev; |
2322 | 2350 | ||
2323 | memset(&ev, 0, sizeof(ev)); | 2351 | memset(&ev, 0, sizeof(ev)); |
2324 | 2352 | ||
2325 | bacpy(&ev.bdaddr, bdaddr); | 2353 | bacpy(&ev.addr.bdaddr, bdaddr); |
2354 | ev.addr.type = link_to_mgmt(type); | ||
2326 | ev.rssi = rssi; | 2355 | ev.rssi = rssi; |
2327 | 2356 | ||
2328 | if (eir) | 2357 | if (eir) |
@@ -2331,10 +2360,10 @@ int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi, | |||
2331 | if (dev_class) | 2360 | if (dev_class) |
2332 | memcpy(ev.dev_class, dev_class, sizeof(ev.dev_class)); | 2361 | memcpy(ev.dev_class, dev_class, sizeof(ev.dev_class)); |
2333 | 2362 | ||
2334 | return mgmt_event(MGMT_EV_DEVICE_FOUND, index, &ev, sizeof(ev), NULL); | 2363 | return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, &ev, sizeof(ev), NULL); |
2335 | } | 2364 | } |
2336 | 2365 | ||
2337 | int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name) | 2366 | int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name) |
2338 | { | 2367 | { |
2339 | struct mgmt_ev_remote_name ev; | 2368 | struct mgmt_ev_remote_name ev; |
2340 | 2369 | ||
@@ -2343,37 +2372,64 @@ int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name) | |||
2343 | bacpy(&ev.bdaddr, bdaddr); | 2372 | bacpy(&ev.bdaddr, bdaddr); |
2344 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); | 2373 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); |
2345 | 2374 | ||
2346 | return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL); | 2375 | return mgmt_event(MGMT_EV_REMOTE_NAME, hdev, &ev, sizeof(ev), NULL); |
2347 | } | 2376 | } |
2348 | 2377 | ||
2349 | int mgmt_discovering(u16 index, u8 discovering) | 2378 | int mgmt_inquiry_failed(struct hci_dev *hdev, u8 status) |
2350 | { | 2379 | { |
2351 | return mgmt_event(MGMT_EV_DISCOVERING, index, &discovering, | 2380 | struct pending_cmd *cmd; |
2381 | int err; | ||
2382 | |||
2383 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev); | ||
2384 | if (!cmd) | ||
2385 | return -ENOENT; | ||
2386 | |||
2387 | err = cmd_status(cmd->sk, hdev->id, cmd->opcode, status); | ||
2388 | mgmt_pending_remove(cmd); | ||
2389 | |||
2390 | return err; | ||
2391 | } | ||
2392 | |||
2393 | int mgmt_discovering(struct hci_dev *hdev, u8 discovering) | ||
2394 | { | ||
2395 | struct pending_cmd *cmd; | ||
2396 | |||
2397 | if (discovering) | ||
2398 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev); | ||
2399 | else | ||
2400 | cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev); | ||
2401 | |||
2402 | if (cmd != NULL) { | ||
2403 | cmd_complete(cmd->sk, hdev->id, cmd->opcode, NULL, 0); | ||
2404 | mgmt_pending_remove(cmd); | ||
2405 | } | ||
2406 | |||
2407 | return mgmt_event(MGMT_EV_DISCOVERING, hdev, &discovering, | ||
2352 | sizeof(discovering), NULL); | 2408 | sizeof(discovering), NULL); |
2353 | } | 2409 | } |
2354 | 2410 | ||
2355 | int mgmt_device_blocked(u16 index, bdaddr_t *bdaddr) | 2411 | int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr) |
2356 | { | 2412 | { |
2357 | struct pending_cmd *cmd; | 2413 | struct pending_cmd *cmd; |
2358 | struct mgmt_ev_device_blocked ev; | 2414 | struct mgmt_ev_device_blocked ev; |
2359 | 2415 | ||
2360 | cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, index); | 2416 | cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, hdev); |
2361 | 2417 | ||
2362 | bacpy(&ev.bdaddr, bdaddr); | 2418 | bacpy(&ev.bdaddr, bdaddr); |
2363 | 2419 | ||
2364 | return mgmt_event(MGMT_EV_DEVICE_BLOCKED, index, &ev, sizeof(ev), | 2420 | return mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &ev, sizeof(ev), |
2365 | cmd ? cmd->sk : NULL); | 2421 | cmd ? cmd->sk : NULL); |
2366 | } | 2422 | } |
2367 | 2423 | ||
2368 | int mgmt_device_unblocked(u16 index, bdaddr_t *bdaddr) | 2424 | int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr) |
2369 | { | 2425 | { |
2370 | struct pending_cmd *cmd; | 2426 | struct pending_cmd *cmd; |
2371 | struct mgmt_ev_device_unblocked ev; | 2427 | struct mgmt_ev_device_unblocked ev; |
2372 | 2428 | ||
2373 | cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, index); | 2429 | cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, hdev); |
2374 | 2430 | ||
2375 | bacpy(&ev.bdaddr, bdaddr); | 2431 | bacpy(&ev.bdaddr, bdaddr); |
2376 | 2432 | ||
2377 | return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, index, &ev, sizeof(ev), | 2433 | return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev), |
2378 | cmd ? cmd->sk : NULL); | 2434 | cmd ? cmd->sk : NULL); |
2379 | } | 2435 | } |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 4e32e18211f9..8743f369ed3f 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -65,7 +65,8 @@ static DEFINE_MUTEX(rfcomm_mutex); | |||
65 | 65 | ||
66 | static LIST_HEAD(session_list); | 66 | static LIST_HEAD(session_list); |
67 | 67 | ||
68 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len); | 68 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len, |
69 | u32 priority); | ||
69 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci); | 70 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci); |
70 | static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci); | 71 | static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci); |
71 | static int rfcomm_queue_disc(struct rfcomm_dlc *d); | 72 | static int rfcomm_queue_disc(struct rfcomm_dlc *d); |
@@ -377,13 +378,11 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d) | |||
377 | static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci) | 378 | static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci) |
378 | { | 379 | { |
379 | struct rfcomm_dlc *d; | 380 | struct rfcomm_dlc *d; |
380 | struct list_head *p; | ||
381 | 381 | ||
382 | list_for_each(p, &s->dlcs) { | 382 | list_for_each_entry(d, &s->dlcs, list) |
383 | d = list_entry(p, struct rfcomm_dlc, list); | ||
384 | if (d->dlci == dlci) | 383 | if (d->dlci == dlci) |
385 | return d; | 384 | return d; |
386 | } | 385 | |
387 | return NULL; | 386 | return NULL; |
388 | } | 387 | } |
389 | 388 | ||
@@ -749,19 +748,34 @@ void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *d | |||
749 | } | 748 | } |
750 | 749 | ||
751 | /* ---- RFCOMM frame sending ---- */ | 750 | /* ---- RFCOMM frame sending ---- */ |
752 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len) | 751 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len, |
752 | u32 priority) | ||
753 | { | 753 | { |
754 | struct socket *sock = s->sock; | 754 | struct socket *sock = s->sock; |
755 | struct sock *sk = sock->sk; | ||
755 | struct kvec iv = { data, len }; | 756 | struct kvec iv = { data, len }; |
756 | struct msghdr msg; | 757 | struct msghdr msg; |
757 | 758 | ||
758 | BT_DBG("session %p len %d", s, len); | 759 | BT_DBG("session %p len %d priority %u", s, len, priority); |
760 | |||
761 | if (sk->sk_priority != priority) { | ||
762 | lock_sock(sk); | ||
763 | sk->sk_priority = priority; | ||
764 | release_sock(sk); | ||
765 | } | ||
759 | 766 | ||
760 | memset(&msg, 0, sizeof(msg)); | 767 | memset(&msg, 0, sizeof(msg)); |
761 | 768 | ||
762 | return kernel_sendmsg(sock, &msg, &iv, 1, len); | 769 | return kernel_sendmsg(sock, &msg, &iv, 1, len); |
763 | } | 770 | } |
764 | 771 | ||
772 | static int rfcomm_send_cmd(struct rfcomm_session *s, struct rfcomm_cmd *cmd) | ||
773 | { | ||
774 | BT_DBG("%p cmd %u", s, cmd->ctrl); | ||
775 | |||
776 | return rfcomm_send_frame(s, (void *) cmd, sizeof(*cmd), HCI_PRIO_MAX); | ||
777 | } | ||
778 | |||
765 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci) | 779 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci) |
766 | { | 780 | { |
767 | struct rfcomm_cmd cmd; | 781 | struct rfcomm_cmd cmd; |
@@ -773,7 +787,7 @@ static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci) | |||
773 | cmd.len = __len8(0); | 787 | cmd.len = __len8(0); |
774 | cmd.fcs = __fcs2((u8 *) &cmd); | 788 | cmd.fcs = __fcs2((u8 *) &cmd); |
775 | 789 | ||
776 | return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd)); | 790 | return rfcomm_send_cmd(s, &cmd); |
777 | } | 791 | } |
778 | 792 | ||
779 | static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci) | 793 | static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci) |
@@ -787,7 +801,7 @@ static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci) | |||
787 | cmd.len = __len8(0); | 801 | cmd.len = __len8(0); |
788 | cmd.fcs = __fcs2((u8 *) &cmd); | 802 | cmd.fcs = __fcs2((u8 *) &cmd); |
789 | 803 | ||
790 | return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd)); | 804 | return rfcomm_send_cmd(s, &cmd); |
791 | } | 805 | } |
792 | 806 | ||
793 | static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci) | 807 | static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci) |
@@ -801,7 +815,7 @@ static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci) | |||
801 | cmd.len = __len8(0); | 815 | cmd.len = __len8(0); |
802 | cmd.fcs = __fcs2((u8 *) &cmd); | 816 | cmd.fcs = __fcs2((u8 *) &cmd); |
803 | 817 | ||
804 | return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd)); | 818 | return rfcomm_send_cmd(s, &cmd); |
805 | } | 819 | } |
806 | 820 | ||
807 | static int rfcomm_queue_disc(struct rfcomm_dlc *d) | 821 | static int rfcomm_queue_disc(struct rfcomm_dlc *d) |
@@ -815,6 +829,8 @@ static int rfcomm_queue_disc(struct rfcomm_dlc *d) | |||
815 | if (!skb) | 829 | if (!skb) |
816 | return -ENOMEM; | 830 | return -ENOMEM; |
817 | 831 | ||
832 | skb->priority = HCI_PRIO_MAX; | ||
833 | |||
818 | cmd = (void *) __skb_put(skb, sizeof(*cmd)); | 834 | cmd = (void *) __skb_put(skb, sizeof(*cmd)); |
819 | cmd->addr = d->addr; | 835 | cmd->addr = d->addr; |
820 | cmd->ctrl = __ctrl(RFCOMM_DISC, 1); | 836 | cmd->ctrl = __ctrl(RFCOMM_DISC, 1); |
@@ -837,7 +853,7 @@ static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci) | |||
837 | cmd.len = __len8(0); | 853 | cmd.len = __len8(0); |
838 | cmd.fcs = __fcs2((u8 *) &cmd); | 854 | cmd.fcs = __fcs2((u8 *) &cmd); |
839 | 855 | ||
840 | return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd)); | 856 | return rfcomm_send_cmd(s, &cmd); |
841 | } | 857 | } |
842 | 858 | ||
843 | static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type) | 859 | static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type) |
@@ -862,7 +878,7 @@ static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type) | |||
862 | 878 | ||
863 | *ptr = __fcs(buf); ptr++; | 879 | *ptr = __fcs(buf); ptr++; |
864 | 880 | ||
865 | return rfcomm_send_frame(s, buf, ptr - buf); | 881 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
866 | } | 882 | } |
867 | 883 | ||
868 | static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d) | 884 | static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d) |
@@ -904,7 +920,7 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d | |||
904 | 920 | ||
905 | *ptr = __fcs(buf); ptr++; | 921 | *ptr = __fcs(buf); ptr++; |
906 | 922 | ||
907 | return rfcomm_send_frame(s, buf, ptr - buf); | 923 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
908 | } | 924 | } |
909 | 925 | ||
910 | int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, | 926 | int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, |
@@ -942,7 +958,7 @@ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, | |||
942 | 958 | ||
943 | *ptr = __fcs(buf); ptr++; | 959 | *ptr = __fcs(buf); ptr++; |
944 | 960 | ||
945 | return rfcomm_send_frame(s, buf, ptr - buf); | 961 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
946 | } | 962 | } |
947 | 963 | ||
948 | static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status) | 964 | static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status) |
@@ -969,7 +985,7 @@ static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status) | |||
969 | 985 | ||
970 | *ptr = __fcs(buf); ptr++; | 986 | *ptr = __fcs(buf); ptr++; |
971 | 987 | ||
972 | return rfcomm_send_frame(s, buf, ptr - buf); | 988 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
973 | } | 989 | } |
974 | 990 | ||
975 | static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig) | 991 | static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig) |
@@ -996,7 +1012,7 @@ static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig | |||
996 | 1012 | ||
997 | *ptr = __fcs(buf); ptr++; | 1013 | *ptr = __fcs(buf); ptr++; |
998 | 1014 | ||
999 | return rfcomm_send_frame(s, buf, ptr - buf); | 1015 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
1000 | } | 1016 | } |
1001 | 1017 | ||
1002 | static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr) | 1018 | static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr) |
@@ -1018,7 +1034,7 @@ static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr) | |||
1018 | 1034 | ||
1019 | *ptr = __fcs(buf); ptr++; | 1035 | *ptr = __fcs(buf); ptr++; |
1020 | 1036 | ||
1021 | return rfcomm_send_frame(s, buf, ptr - buf); | 1037 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
1022 | } | 1038 | } |
1023 | 1039 | ||
1024 | static int rfcomm_send_fcon(struct rfcomm_session *s, int cr) | 1040 | static int rfcomm_send_fcon(struct rfcomm_session *s, int cr) |
@@ -1040,7 +1056,7 @@ static int rfcomm_send_fcon(struct rfcomm_session *s, int cr) | |||
1040 | 1056 | ||
1041 | *ptr = __fcs(buf); ptr++; | 1057 | *ptr = __fcs(buf); ptr++; |
1042 | 1058 | ||
1043 | return rfcomm_send_frame(s, buf, ptr - buf); | 1059 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
1044 | } | 1060 | } |
1045 | 1061 | ||
1046 | static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len) | 1062 | static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len) |
@@ -1091,7 +1107,7 @@ static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits) | |||
1091 | 1107 | ||
1092 | *ptr = __fcs(buf); ptr++; | 1108 | *ptr = __fcs(buf); ptr++; |
1093 | 1109 | ||
1094 | return rfcomm_send_frame(s, buf, ptr - buf); | 1110 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); |
1095 | } | 1111 | } |
1096 | 1112 | ||
1097 | static void rfcomm_make_uih(struct sk_buff *skb, u8 addr) | 1113 | static void rfcomm_make_uih(struct sk_buff *skb, u8 addr) |
@@ -1769,7 +1785,8 @@ static inline int rfcomm_process_tx(struct rfcomm_dlc *d) | |||
1769 | return skb_queue_len(&d->tx_queue); | 1785 | return skb_queue_len(&d->tx_queue); |
1770 | 1786 | ||
1771 | while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) { | 1787 | while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) { |
1772 | err = rfcomm_send_frame(d->session, skb->data, skb->len); | 1788 | err = rfcomm_send_frame(d->session, skb->data, skb->len, |
1789 | skb->priority); | ||
1773 | if (err < 0) { | 1790 | if (err < 0) { |
1774 | skb_queue_head(&d->tx_queue, skb); | 1791 | skb_queue_head(&d->tx_queue, skb); |
1775 | break; | 1792 | break; |
@@ -2120,15 +2137,13 @@ static struct hci_cb rfcomm_cb = { | |||
2120 | static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x) | 2137 | static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x) |
2121 | { | 2138 | { |
2122 | struct rfcomm_session *s; | 2139 | struct rfcomm_session *s; |
2123 | struct list_head *pp, *p; | ||
2124 | 2140 | ||
2125 | rfcomm_lock(); | 2141 | rfcomm_lock(); |
2126 | 2142 | ||
2127 | list_for_each(p, &session_list) { | 2143 | list_for_each_entry(s, &session_list, list) { |
2128 | s = list_entry(p, struct rfcomm_session, list); | 2144 | struct rfcomm_dlc *d; |
2129 | list_for_each(pp, &s->dlcs) { | 2145 | list_for_each_entry(d, &s->dlcs, list) { |
2130 | struct sock *sk = s->sock->sk; | 2146 | struct sock *sk = s->sock->sk; |
2131 | struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list); | ||
2132 | 2147 | ||
2133 | seq_printf(f, "%s %s %ld %d %d %d %d\n", | 2148 | seq_printf(f, "%s %s %ld %d %d %d %d\n", |
2134 | batostr(&bt_sk(sk)->src), | 2149 | batostr(&bt_sk(sk)->src), |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 5417f6127323..aea2bdd1510f 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -600,6 +600,8 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
600 | break; | 600 | break; |
601 | } | 601 | } |
602 | 602 | ||
603 | skb->priority = sk->sk_priority; | ||
604 | |||
603 | err = rfcomm_dlc_send(d, skb); | 605 | err = rfcomm_dlc_send(d, skb); |
604 | if (err < 0) { | 606 | if (err < 0) { |
605 | kfree_skb(skb); | 607 | kfree_skb(skb); |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index c258796313e0..fa8f4de53b99 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/capability.h> | 34 | #include <linux/capability.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/skbuff.h> | 36 | #include <linux/skbuff.h> |
37 | #include <linux/workqueue.h> | ||
37 | 38 | ||
38 | #include <net/bluetooth/bluetooth.h> | 39 | #include <net/bluetooth/bluetooth.h> |
39 | #include <net/bluetooth/hci_core.h> | 40 | #include <net/bluetooth/hci_core.h> |
@@ -65,7 +66,7 @@ struct rfcomm_dev { | |||
65 | struct rfcomm_dlc *dlc; | 66 | struct rfcomm_dlc *dlc; |
66 | struct tty_struct *tty; | 67 | struct tty_struct *tty; |
67 | wait_queue_head_t wait; | 68 | wait_queue_head_t wait; |
68 | struct tasklet_struct wakeup_task; | 69 | struct work_struct wakeup_task; |
69 | 70 | ||
70 | struct device *tty_dev; | 71 | struct device *tty_dev; |
71 | 72 | ||
@@ -81,7 +82,7 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb); | |||
81 | static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err); | 82 | static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err); |
82 | static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig); | 83 | static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig); |
83 | 84 | ||
84 | static void rfcomm_tty_wakeup(unsigned long arg); | 85 | static void rfcomm_tty_wakeup(struct work_struct *work); |
85 | 86 | ||
86 | /* ---- Device functions ---- */ | 87 | /* ---- Device functions ---- */ |
87 | static void rfcomm_dev_destruct(struct rfcomm_dev *dev) | 88 | static void rfcomm_dev_destruct(struct rfcomm_dev *dev) |
@@ -133,13 +134,10 @@ static inline void rfcomm_dev_put(struct rfcomm_dev *dev) | |||
133 | static struct rfcomm_dev *__rfcomm_dev_get(int id) | 134 | static struct rfcomm_dev *__rfcomm_dev_get(int id) |
134 | { | 135 | { |
135 | struct rfcomm_dev *dev; | 136 | struct rfcomm_dev *dev; |
136 | struct list_head *p; | ||
137 | 137 | ||
138 | list_for_each(p, &rfcomm_dev_list) { | 138 | list_for_each_entry(dev, &rfcomm_dev_list, list) |
139 | dev = list_entry(p, struct rfcomm_dev, list); | ||
140 | if (dev->id == id) | 139 | if (dev->id == id) |
141 | return dev; | 140 | return dev; |
142 | } | ||
143 | 141 | ||
144 | return NULL; | 142 | return NULL; |
145 | } | 143 | } |
@@ -197,7 +195,7 @@ static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL); | |||
197 | 195 | ||
198 | static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | 196 | static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) |
199 | { | 197 | { |
200 | struct rfcomm_dev *dev; | 198 | struct rfcomm_dev *dev, *entry; |
201 | struct list_head *head = &rfcomm_dev_list, *p; | 199 | struct list_head *head = &rfcomm_dev_list, *p; |
202 | int err = 0; | 200 | int err = 0; |
203 | 201 | ||
@@ -212,8 +210,8 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | |||
212 | if (req->dev_id < 0) { | 210 | if (req->dev_id < 0) { |
213 | dev->id = 0; | 211 | dev->id = 0; |
214 | 212 | ||
215 | list_for_each(p, &rfcomm_dev_list) { | 213 | list_for_each_entry(entry, &rfcomm_dev_list, list) { |
216 | if (list_entry(p, struct rfcomm_dev, list)->id != dev->id) | 214 | if (entry->id != dev->id) |
217 | break; | 215 | break; |
218 | 216 | ||
219 | dev->id++; | 217 | dev->id++; |
@@ -222,9 +220,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | |||
222 | } else { | 220 | } else { |
223 | dev->id = req->dev_id; | 221 | dev->id = req->dev_id; |
224 | 222 | ||
225 | list_for_each(p, &rfcomm_dev_list) { | 223 | list_for_each_entry(entry, &rfcomm_dev_list, list) { |
226 | struct rfcomm_dev *entry = list_entry(p, struct rfcomm_dev, list); | ||
227 | |||
228 | if (entry->id == dev->id) { | 224 | if (entry->id == dev->id) { |
229 | err = -EADDRINUSE; | 225 | err = -EADDRINUSE; |
230 | goto out; | 226 | goto out; |
@@ -257,7 +253,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | |||
257 | atomic_set(&dev->opened, 0); | 253 | atomic_set(&dev->opened, 0); |
258 | 254 | ||
259 | init_waitqueue_head(&dev->wait); | 255 | init_waitqueue_head(&dev->wait); |
260 | tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev); | 256 | INIT_WORK(&dev->wakeup_task, rfcomm_tty_wakeup); |
261 | 257 | ||
262 | skb_queue_head_init(&dev->pending); | 258 | skb_queue_head_init(&dev->pending); |
263 | 259 | ||
@@ -351,7 +347,7 @@ static void rfcomm_wfree(struct sk_buff *skb) | |||
351 | struct rfcomm_dev *dev = (void *) skb->sk; | 347 | struct rfcomm_dev *dev = (void *) skb->sk; |
352 | atomic_sub(skb->truesize, &dev->wmem_alloc); | 348 | atomic_sub(skb->truesize, &dev->wmem_alloc); |
353 | if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags)) | 349 | if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags)) |
354 | tasklet_schedule(&dev->wakeup_task); | 350 | queue_work(system_nrt_wq, &dev->wakeup_task); |
355 | rfcomm_dev_put(dev); | 351 | rfcomm_dev_put(dev); |
356 | } | 352 | } |
357 | 353 | ||
@@ -455,9 +451,9 @@ static int rfcomm_release_dev(void __user *arg) | |||
455 | 451 | ||
456 | static int rfcomm_get_dev_list(void __user *arg) | 452 | static int rfcomm_get_dev_list(void __user *arg) |
457 | { | 453 | { |
454 | struct rfcomm_dev *dev; | ||
458 | struct rfcomm_dev_list_req *dl; | 455 | struct rfcomm_dev_list_req *dl; |
459 | struct rfcomm_dev_info *di; | 456 | struct rfcomm_dev_info *di; |
460 | struct list_head *p; | ||
461 | int n = 0, size, err; | 457 | int n = 0, size, err; |
462 | u16 dev_num; | 458 | u16 dev_num; |
463 | 459 | ||
@@ -479,8 +475,7 @@ static int rfcomm_get_dev_list(void __user *arg) | |||
479 | 475 | ||
480 | read_lock_bh(&rfcomm_dev_lock); | 476 | read_lock_bh(&rfcomm_dev_lock); |
481 | 477 | ||
482 | list_for_each(p, &rfcomm_dev_list) { | 478 | list_for_each_entry(dev, &rfcomm_dev_list, list) { |
483 | struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list); | ||
484 | if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) | 479 | if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) |
485 | continue; | 480 | continue; |
486 | (di + n)->id = dev->id; | 481 | (di + n)->id = dev->id; |
@@ -635,9 +630,10 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig) | |||
635 | } | 630 | } |
636 | 631 | ||
637 | /* ---- TTY functions ---- */ | 632 | /* ---- TTY functions ---- */ |
638 | static void rfcomm_tty_wakeup(unsigned long arg) | 633 | static void rfcomm_tty_wakeup(struct work_struct *work) |
639 | { | 634 | { |
640 | struct rfcomm_dev *dev = (void *) arg; | 635 | struct rfcomm_dev *dev = container_of(work, struct rfcomm_dev, |
636 | wakeup_task); | ||
641 | struct tty_struct *tty = dev->tty; | 637 | struct tty_struct *tty = dev->tty; |
642 | if (!tty) | 638 | if (!tty) |
643 | return; | 639 | return; |
@@ -762,7 +758,7 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp) | |||
762 | rfcomm_dlc_close(dev->dlc, 0); | 758 | rfcomm_dlc_close(dev->dlc, 0); |
763 | 759 | ||
764 | clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags); | 760 | clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags); |
765 | tasklet_kill(&dev->wakeup_task); | 761 | cancel_work_sync(&dev->wakeup_task); |
766 | 762 | ||
767 | rfcomm_dlc_lock(dev->dlc); | 763 | rfcomm_dlc_lock(dev->dlc); |
768 | tty->driver_data = NULL; | 764 | tty->driver_data = NULL; |
@@ -1155,9 +1151,11 @@ static const struct tty_operations rfcomm_ops = { | |||
1155 | 1151 | ||
1156 | int __init rfcomm_init_ttys(void) | 1152 | int __init rfcomm_init_ttys(void) |
1157 | { | 1153 | { |
1154 | int error; | ||
1155 | |||
1158 | rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS); | 1156 | rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS); |
1159 | if (!rfcomm_tty_driver) | 1157 | if (!rfcomm_tty_driver) |
1160 | return -1; | 1158 | return -ENOMEM; |
1161 | 1159 | ||
1162 | rfcomm_tty_driver->owner = THIS_MODULE; | 1160 | rfcomm_tty_driver->owner = THIS_MODULE; |
1163 | rfcomm_tty_driver->driver_name = "rfcomm"; | 1161 | rfcomm_tty_driver->driver_name = "rfcomm"; |
@@ -1172,10 +1170,11 @@ int __init rfcomm_init_ttys(void) | |||
1172 | rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON; | 1170 | rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON; |
1173 | tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); | 1171 | tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); |
1174 | 1172 | ||
1175 | if (tty_register_driver(rfcomm_tty_driver)) { | 1173 | error = tty_register_driver(rfcomm_tty_driver); |
1174 | if (error) { | ||
1176 | BT_ERR("Can't register RFCOMM TTY driver"); | 1175 | BT_ERR("Can't register RFCOMM TTY driver"); |
1177 | put_tty_driver(rfcomm_tty_driver); | 1176 | put_tty_driver(rfcomm_tty_driver); |
1178 | return -1; | 1177 | return error; |
1179 | } | 1178 | } |
1180 | 1179 | ||
1181 | BT_INFO("RFCOMM TTY layer initialized"); | 1180 | BT_INFO("RFCOMM TTY layer initialized"); |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 759b63572641..94e94ca35384 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -181,7 +181,8 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) | |||
181 | if (!skb) | 181 | if (!skb) |
182 | return; | 182 | return; |
183 | 183 | ||
184 | hci_send_acl(conn->hcon, skb, 0); | 184 | skb->priority = HCI_PRIO_MAX; |
185 | hci_send_acl(conn->hchan, skb, 0); | ||
185 | 186 | ||
186 | mod_timer(&conn->security_timer, jiffies + | 187 | mod_timer(&conn->security_timer, jiffies + |
187 | msecs_to_jiffies(SMP_TIMEOUT)); | 188 | msecs_to_jiffies(SMP_TIMEOUT)); |
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index feb77ea7b58e..a3754ac262c3 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -186,7 +186,8 @@ static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
186 | strcpy(info->bus_info, "N/A"); | 186 | strcpy(info->bus_info, "N/A"); |
187 | } | 187 | } |
188 | 188 | ||
189 | static u32 br_fix_features(struct net_device *dev, u32 features) | 189 | static netdev_features_t br_fix_features(struct net_device *dev, |
190 | netdev_features_t features) | ||
190 | { | 191 | { |
191 | struct net_bridge *br = netdev_priv(dev); | 192 | struct net_bridge *br = netdev_priv(dev); |
192 | 193 | ||
@@ -341,10 +342,10 @@ void br_dev_setup(struct net_device *dev) | |||
341 | dev->priv_flags = IFF_EBRIDGE; | 342 | dev->priv_flags = IFF_EBRIDGE; |
342 | 343 | ||
343 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | | 344 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | |
344 | NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX | | 345 | NETIF_F_GSO_MASK | NETIF_F_HW_CSUM | NETIF_F_LLTX | |
345 | NETIF_F_NETNS_LOCAL | NETIF_F_HW_VLAN_TX; | 346 | NETIF_F_NETNS_LOCAL | NETIF_F_HW_VLAN_TX; |
346 | dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | | 347 | dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | |
347 | NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | | 348 | NETIF_F_GSO_MASK | NETIF_F_HW_CSUM | |
348 | NETIF_F_HW_VLAN_TX; | 349 | NETIF_F_HW_VLAN_TX; |
349 | 350 | ||
350 | br->dev = dev; | 351 | br->dev = dev; |
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index c8e7861b88b0..973813e34428 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
@@ -556,7 +556,7 @@ skip: | |||
556 | return skb->len; | 556 | return skb->len; |
557 | } | 557 | } |
558 | 558 | ||
559 | /* Create new static fdb entry */ | 559 | /* Update (create or replace) forwarding database entry */ |
560 | static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, | 560 | static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, |
561 | __u16 state, __u16 flags) | 561 | __u16 state, __u16 flags) |
562 | { | 562 | { |
@@ -575,16 +575,21 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr, | |||
575 | } else { | 575 | } else { |
576 | if (flags & NLM_F_EXCL) | 576 | if (flags & NLM_F_EXCL) |
577 | return -EEXIST; | 577 | return -EEXIST; |
578 | } | ||
579 | |||
580 | if (fdb_to_nud(fdb) != state) { | ||
581 | if (state & NUD_PERMANENT) | ||
582 | fdb->is_local = fdb->is_static = 1; | ||
583 | else if (state & NUD_NOARP) { | ||
584 | fdb->is_local = 0; | ||
585 | fdb->is_static = 1; | ||
586 | } else | ||
587 | fdb->is_local = fdb->is_static = 0; | ||
578 | 588 | ||
579 | if (flags & NLM_F_REPLACE) | 589 | fdb->updated = fdb->used = jiffies; |
580 | fdb->updated = fdb->used = jiffies; | 590 | fdb_notify(fdb, RTM_NEWNEIGH); |
581 | fdb->is_local = fdb->is_static = 0; | ||
582 | } | 591 | } |
583 | 592 | ||
584 | if (state & NUD_PERMANENT) | ||
585 | fdb->is_local = fdb->is_static = 1; | ||
586 | else if (state & NUD_NOARP) | ||
587 | fdb->is_static = 1; | ||
588 | return 0; | 593 | return 0; |
589 | } | 594 | } |
590 | 595 | ||
@@ -627,6 +632,11 @@ int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
627 | return -EINVAL; | 632 | return -EINVAL; |
628 | } | 633 | } |
629 | 634 | ||
635 | if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) { | ||
636 | pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state); | ||
637 | return -EINVAL; | ||
638 | } | ||
639 | |||
630 | p = br_port_get_rtnl(dev); | 640 | p = br_port_get_rtnl(dev); |
631 | if (p == NULL) { | 641 | if (p == NULL) { |
632 | pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n", | 642 | pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n", |
@@ -634,9 +644,15 @@ int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
634 | return -EINVAL; | 644 | return -EINVAL; |
635 | } | 645 | } |
636 | 646 | ||
637 | spin_lock_bh(&p->br->hash_lock); | 647 | if (ndm->ndm_flags & NTF_USE) { |
638 | err = fdb_add_entry(p, addr, ndm->ndm_state, nlh->nlmsg_flags); | 648 | rcu_read_lock(); |
639 | spin_unlock_bh(&p->br->hash_lock); | 649 | br_fdb_update(p->br, p, addr); |
650 | rcu_read_unlock(); | ||
651 | } else { | ||
652 | spin_lock_bh(&p->br->hash_lock); | ||
653 | err = fdb_add_entry(p, addr, ndm->ndm_state, nlh->nlmsg_flags); | ||
654 | spin_unlock_bh(&p->br->hash_lock); | ||
655 | } | ||
640 | 656 | ||
641 | return err; | 657 | return err; |
642 | } | 658 | } |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index f603e5b0b930..0a942fbccc9a 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -296,10 +296,11 @@ int br_min_mtu(const struct net_bridge *br) | |||
296 | /* | 296 | /* |
297 | * Recomputes features using slave's features | 297 | * Recomputes features using slave's features |
298 | */ | 298 | */ |
299 | u32 br_features_recompute(struct net_bridge *br, u32 features) | 299 | netdev_features_t br_features_recompute(struct net_bridge *br, |
300 | netdev_features_t features) | ||
300 | { | 301 | { |
301 | struct net_bridge_port *p; | 302 | struct net_bridge_port *p; |
302 | u32 mask; | 303 | netdev_features_t mask; |
303 | 304 | ||
304 | if (list_empty(&br->port_list)) | 305 | if (list_empty(&br->port_list)) |
305 | return features; | 306 | return features; |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index a5f4e5769809..7743e0d109ea 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -127,7 +127,7 @@ static struct net_bridge_mdb_entry *br_mdb_ip6_get( | |||
127 | { | 127 | { |
128 | struct br_ip br_dst; | 128 | struct br_ip br_dst; |
129 | 129 | ||
130 | ipv6_addr_copy(&br_dst.u.ip6, dst); | 130 | br_dst.u.ip6 = *dst; |
131 | br_dst.proto = htons(ETH_P_IPV6); | 131 | br_dst.proto = htons(ETH_P_IPV6); |
132 | 132 | ||
133 | return br_mdb_ip_get(mdb, &br_dst); | 133 | return br_mdb_ip_get(mdb, &br_dst); |
@@ -154,7 +154,7 @@ struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, | |||
154 | break; | 154 | break; |
155 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 155 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
156 | case htons(ETH_P_IPV6): | 156 | case htons(ETH_P_IPV6): |
157 | ipv6_addr_copy(&ip.u.ip6, &ipv6_hdr(skb)->daddr); | 157 | ip.u.ip6 = ipv6_hdr(skb)->daddr; |
158 | break; | 158 | break; |
159 | #endif | 159 | #endif |
160 | default: | 160 | default: |
@@ -474,7 +474,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, | |||
474 | mldq->mld_cksum = 0; | 474 | mldq->mld_cksum = 0; |
475 | mldq->mld_maxdelay = htons((u16)jiffies_to_msecs(interval)); | 475 | mldq->mld_maxdelay = htons((u16)jiffies_to_msecs(interval)); |
476 | mldq->mld_reserved = 0; | 476 | mldq->mld_reserved = 0; |
477 | ipv6_addr_copy(&mldq->mld_mca, group); | 477 | mldq->mld_mca = *group; |
478 | 478 | ||
479 | /* checksum */ | 479 | /* checksum */ |
480 | mldq->mld_cksum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, | 480 | mldq->mld_cksum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, |
@@ -783,7 +783,7 @@ static int br_ip6_multicast_add_group(struct net_bridge *br, | |||
783 | if (!ipv6_is_transient_multicast(group)) | 783 | if (!ipv6_is_transient_multicast(group)) |
784 | return 0; | 784 | return 0; |
785 | 785 | ||
786 | ipv6_addr_copy(&br_group.u.ip6, group); | 786 | br_group.u.ip6 = *group; |
787 | br_group.proto = htons(ETH_P_IPV6); | 787 | br_group.proto = htons(ETH_P_IPV6); |
788 | 788 | ||
789 | return br_multicast_add_group(br, port, &br_group); | 789 | return br_multicast_add_group(br, port, &br_group); |
@@ -1344,7 +1344,7 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br, | |||
1344 | if (!ipv6_is_transient_multicast(group)) | 1344 | if (!ipv6_is_transient_multicast(group)) |
1345 | return; | 1345 | return; |
1346 | 1346 | ||
1347 | ipv6_addr_copy(&br_group.u.ip6, group); | 1347 | br_group.u.ip6 = *group; |
1348 | br_group.proto = htons(ETH_P_IPV6); | 1348 | br_group.proto = htons(ETH_P_IPV6); |
1349 | 1349 | ||
1350 | br_multicast_leave_group(br, port, &br_group); | 1350 | br_multicast_leave_group(br, port, &br_group); |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index d7d6fb05411f..4027029aa5e4 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -387,7 +387,8 @@ extern int br_add_if(struct net_bridge *br, | |||
387 | extern int br_del_if(struct net_bridge *br, | 387 | extern int br_del_if(struct net_bridge *br, |
388 | struct net_device *dev); | 388 | struct net_device *dev); |
389 | extern int br_min_mtu(const struct net_bridge *br); | 389 | extern int br_min_mtu(const struct net_bridge *br); |
390 | extern u32 br_features_recompute(struct net_bridge *br, u32 features); | 390 | extern netdev_features_t br_features_recompute(struct net_bridge *br, |
391 | netdev_features_t features); | ||
391 | 392 | ||
392 | /* br_input.c */ | 393 | /* br_input.c */ |
393 | extern int br_handle_frame_finish(struct sk_buff *skb); | 394 | extern int br_handle_frame_finish(struct sk_buff *skb); |
diff --git a/net/core/Makefile b/net/core/Makefile index 0d357b1c4e57..3606d40aae62 100644 --- a/net/core/Makefile +++ b/net/core/Makefile | |||
@@ -19,3 +19,4 @@ obj-$(CONFIG_FIB_RULES) += fib_rules.o | |||
19 | obj-$(CONFIG_TRACEPOINTS) += net-traces.o | 19 | obj-$(CONFIG_TRACEPOINTS) += net-traces.o |
20 | obj-$(CONFIG_NET_DROP_MONITOR) += drop_monitor.o | 20 | obj-$(CONFIG_NET_DROP_MONITOR) += drop_monitor.o |
21 | obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o | 21 | obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o |
22 | obj-$(CONFIG_NETPRIO_CGROUP) += netprio_cgroup.o | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 6ba50a1e404c..8afb244b205f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -137,6 +137,7 @@ | |||
137 | #include <linux/if_pppox.h> | 137 | #include <linux/if_pppox.h> |
138 | #include <linux/ppp_defs.h> | 138 | #include <linux/ppp_defs.h> |
139 | #include <linux/net_tstamp.h> | 139 | #include <linux/net_tstamp.h> |
140 | #include <linux/jump_label.h> | ||
140 | 141 | ||
141 | #include "net-sysfs.h" | 142 | #include "net-sysfs.h" |
142 | 143 | ||
@@ -1320,8 +1321,6 @@ EXPORT_SYMBOL(dev_close); | |||
1320 | */ | 1321 | */ |
1321 | void dev_disable_lro(struct net_device *dev) | 1322 | void dev_disable_lro(struct net_device *dev) |
1322 | { | 1323 | { |
1323 | u32 flags; | ||
1324 | |||
1325 | /* | 1324 | /* |
1326 | * If we're trying to disable lro on a vlan device | 1325 | * If we're trying to disable lro on a vlan device |
1327 | * use the underlying physical device instead | 1326 | * use the underlying physical device instead |
@@ -1329,15 +1328,9 @@ void dev_disable_lro(struct net_device *dev) | |||
1329 | if (is_vlan_dev(dev)) | 1328 | if (is_vlan_dev(dev)) |
1330 | dev = vlan_dev_real_dev(dev); | 1329 | dev = vlan_dev_real_dev(dev); |
1331 | 1330 | ||
1332 | if (dev->ethtool_ops && dev->ethtool_ops->get_flags) | 1331 | dev->wanted_features &= ~NETIF_F_LRO; |
1333 | flags = dev->ethtool_ops->get_flags(dev); | 1332 | netdev_update_features(dev); |
1334 | else | ||
1335 | flags = ethtool_op_get_flags(dev); | ||
1336 | 1333 | ||
1337 | if (!(flags & ETH_FLAG_LRO)) | ||
1338 | return; | ||
1339 | |||
1340 | __ethtool_set_flags(dev, flags & ~ETH_FLAG_LRO); | ||
1341 | if (unlikely(dev->features & NETIF_F_LRO)) | 1334 | if (unlikely(dev->features & NETIF_F_LRO)) |
1342 | netdev_WARN(dev, "failed to disable LRO!\n"); | 1335 | netdev_WARN(dev, "failed to disable LRO!\n"); |
1343 | } | 1336 | } |
@@ -1449,34 +1442,32 @@ int call_netdevice_notifiers(unsigned long val, struct net_device *dev) | |||
1449 | } | 1442 | } |
1450 | EXPORT_SYMBOL(call_netdevice_notifiers); | 1443 | EXPORT_SYMBOL(call_netdevice_notifiers); |
1451 | 1444 | ||
1452 | /* When > 0 there are consumers of rx skb time stamps */ | 1445 | static struct jump_label_key netstamp_needed __read_mostly; |
1453 | static atomic_t netstamp_needed = ATOMIC_INIT(0); | ||
1454 | 1446 | ||
1455 | void net_enable_timestamp(void) | 1447 | void net_enable_timestamp(void) |
1456 | { | 1448 | { |
1457 | atomic_inc(&netstamp_needed); | 1449 | jump_label_inc(&netstamp_needed); |
1458 | } | 1450 | } |
1459 | EXPORT_SYMBOL(net_enable_timestamp); | 1451 | EXPORT_SYMBOL(net_enable_timestamp); |
1460 | 1452 | ||
1461 | void net_disable_timestamp(void) | 1453 | void net_disable_timestamp(void) |
1462 | { | 1454 | { |
1463 | atomic_dec(&netstamp_needed); | 1455 | jump_label_dec(&netstamp_needed); |
1464 | } | 1456 | } |
1465 | EXPORT_SYMBOL(net_disable_timestamp); | 1457 | EXPORT_SYMBOL(net_disable_timestamp); |
1466 | 1458 | ||
1467 | static inline void net_timestamp_set(struct sk_buff *skb) | 1459 | static inline void net_timestamp_set(struct sk_buff *skb) |
1468 | { | 1460 | { |
1469 | if (atomic_read(&netstamp_needed)) | 1461 | skb->tstamp.tv64 = 0; |
1462 | if (static_branch(&netstamp_needed)) | ||
1470 | __net_timestamp(skb); | 1463 | __net_timestamp(skb); |
1471 | else | ||
1472 | skb->tstamp.tv64 = 0; | ||
1473 | } | 1464 | } |
1474 | 1465 | ||
1475 | static inline void net_timestamp_check(struct sk_buff *skb) | 1466 | #define net_timestamp_check(COND, SKB) \ |
1476 | { | 1467 | if (static_branch(&netstamp_needed)) { \ |
1477 | if (!skb->tstamp.tv64 && atomic_read(&netstamp_needed)) | 1468 | if ((COND) && !(SKB)->tstamp.tv64) \ |
1478 | __net_timestamp(skb); | 1469 | __net_timestamp(SKB); \ |
1479 | } | 1470 | } \ |
1480 | 1471 | ||
1481 | static int net_hwtstamp_validate(struct ifreq *ifr) | 1472 | static int net_hwtstamp_validate(struct ifreq *ifr) |
1482 | { | 1473 | { |
@@ -1923,7 +1914,8 @@ EXPORT_SYMBOL(skb_checksum_help); | |||
1923 | * It may return NULL if the skb requires no segmentation. This is | 1914 | * It may return NULL if the skb requires no segmentation. This is |
1924 | * only possible when GSO is used for verifying header integrity. | 1915 | * only possible when GSO is used for verifying header integrity. |
1925 | */ | 1916 | */ |
1926 | struct sk_buff *skb_gso_segment(struct sk_buff *skb, u32 features) | 1917 | struct sk_buff *skb_gso_segment(struct sk_buff *skb, |
1918 | netdev_features_t features) | ||
1927 | { | 1919 | { |
1928 | struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); | 1920 | struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); |
1929 | struct packet_type *ptype; | 1921 | struct packet_type *ptype; |
@@ -1953,9 +1945,9 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, u32 features) | |||
1953 | if (dev && dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) | 1945 | if (dev && dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) |
1954 | dev->ethtool_ops->get_drvinfo(dev, &info); | 1946 | dev->ethtool_ops->get_drvinfo(dev, &info); |
1955 | 1947 | ||
1956 | WARN(1, "%s: caps=(0x%lx, 0x%lx) len=%d data_len=%d ip_summed=%d\n", | 1948 | WARN(1, "%s: caps=(%pNF, %pNF) len=%d data_len=%d ip_summed=%d\n", |
1957 | info.driver, dev ? dev->features : 0L, | 1949 | info.driver, dev ? &dev->features : NULL, |
1958 | skb->sk ? skb->sk->sk_route_caps : 0L, | 1950 | skb->sk ? &skb->sk->sk_route_caps : NULL, |
1959 | skb->len, skb->data_len, skb->ip_summed); | 1951 | skb->len, skb->data_len, skb->ip_summed); |
1960 | 1952 | ||
1961 | if (skb_header_cloned(skb) && | 1953 | if (skb_header_cloned(skb) && |
@@ -2064,7 +2056,7 @@ static void dev_gso_skb_destructor(struct sk_buff *skb) | |||
2064 | * This function segments the given skb and stores the list of segments | 2056 | * This function segments the given skb and stores the list of segments |
2065 | * in skb->next. | 2057 | * in skb->next. |
2066 | */ | 2058 | */ |
2067 | static int dev_gso_segment(struct sk_buff *skb, int features) | 2059 | static int dev_gso_segment(struct sk_buff *skb, netdev_features_t features) |
2068 | { | 2060 | { |
2069 | struct sk_buff *segs; | 2061 | struct sk_buff *segs; |
2070 | 2062 | ||
@@ -2103,7 +2095,7 @@ static inline void skb_orphan_try(struct sk_buff *skb) | |||
2103 | } | 2095 | } |
2104 | } | 2096 | } |
2105 | 2097 | ||
2106 | static bool can_checksum_protocol(unsigned long features, __be16 protocol) | 2098 | static bool can_checksum_protocol(netdev_features_t features, __be16 protocol) |
2107 | { | 2099 | { |
2108 | return ((features & NETIF_F_GEN_CSUM) || | 2100 | return ((features & NETIF_F_GEN_CSUM) || |
2109 | ((features & NETIF_F_V4_CSUM) && | 2101 | ((features & NETIF_F_V4_CSUM) && |
@@ -2114,7 +2106,8 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol) | |||
2114 | protocol == htons(ETH_P_FCOE))); | 2106 | protocol == htons(ETH_P_FCOE))); |
2115 | } | 2107 | } |
2116 | 2108 | ||
2117 | static u32 harmonize_features(struct sk_buff *skb, __be16 protocol, u32 features) | 2109 | static netdev_features_t harmonize_features(struct sk_buff *skb, |
2110 | __be16 protocol, netdev_features_t features) | ||
2118 | { | 2111 | { |
2119 | if (!can_checksum_protocol(features, protocol)) { | 2112 | if (!can_checksum_protocol(features, protocol)) { |
2120 | features &= ~NETIF_F_ALL_CSUM; | 2113 | features &= ~NETIF_F_ALL_CSUM; |
@@ -2126,10 +2119,10 @@ static u32 harmonize_features(struct sk_buff *skb, __be16 protocol, u32 features | |||
2126 | return features; | 2119 | return features; |
2127 | } | 2120 | } |
2128 | 2121 | ||
2129 | u32 netif_skb_features(struct sk_buff *skb) | 2122 | netdev_features_t netif_skb_features(struct sk_buff *skb) |
2130 | { | 2123 | { |
2131 | __be16 protocol = skb->protocol; | 2124 | __be16 protocol = skb->protocol; |
2132 | u32 features = skb->dev->features; | 2125 | netdev_features_t features = skb->dev->features; |
2133 | 2126 | ||
2134 | if (protocol == htons(ETH_P_8021Q)) { | 2127 | if (protocol == htons(ETH_P_8021Q)) { |
2135 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 2128 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
@@ -2175,7 +2168,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
2175 | unsigned int skb_len; | 2168 | unsigned int skb_len; |
2176 | 2169 | ||
2177 | if (likely(!skb->next)) { | 2170 | if (likely(!skb->next)) { |
2178 | u32 features; | 2171 | netdev_features_t features; |
2179 | 2172 | ||
2180 | /* | 2173 | /* |
2181 | * If device doesn't need skb->dst, release it right now while | 2174 | * If device doesn't need skb->dst, release it right now while |
@@ -2456,6 +2449,18 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, | |||
2456 | return rc; | 2449 | return rc; |
2457 | } | 2450 | } |
2458 | 2451 | ||
2452 | #if IS_ENABLED(CONFIG_NETPRIO_CGROUP) | ||
2453 | static void skb_update_prio(struct sk_buff *skb) | ||
2454 | { | ||
2455 | struct netprio_map *map = rcu_dereference(skb->dev->priomap); | ||
2456 | |||
2457 | if ((!skb->priority) && (skb->sk) && map) | ||
2458 | skb->priority = map->priomap[skb->sk->sk_cgrp_prioidx]; | ||
2459 | } | ||
2460 | #else | ||
2461 | #define skb_update_prio(skb) | ||
2462 | #endif | ||
2463 | |||
2459 | static DEFINE_PER_CPU(int, xmit_recursion); | 2464 | static DEFINE_PER_CPU(int, xmit_recursion); |
2460 | #define RECURSION_LIMIT 10 | 2465 | #define RECURSION_LIMIT 10 |
2461 | 2466 | ||
@@ -2496,6 +2501,8 @@ int dev_queue_xmit(struct sk_buff *skb) | |||
2496 | */ | 2501 | */ |
2497 | rcu_read_lock_bh(); | 2502 | rcu_read_lock_bh(); |
2498 | 2503 | ||
2504 | skb_update_prio(skb); | ||
2505 | |||
2499 | txq = dev_pick_tx(dev, skb); | 2506 | txq = dev_pick_tx(dev, skb); |
2500 | q = rcu_dereference_bh(txq->qdisc); | 2507 | q = rcu_dereference_bh(txq->qdisc); |
2501 | 2508 | ||
@@ -2718,6 +2725,8 @@ EXPORT_SYMBOL(__skb_get_rxhash); | |||
2718 | struct rps_sock_flow_table __rcu *rps_sock_flow_table __read_mostly; | 2725 | struct rps_sock_flow_table __rcu *rps_sock_flow_table __read_mostly; |
2719 | EXPORT_SYMBOL(rps_sock_flow_table); | 2726 | EXPORT_SYMBOL(rps_sock_flow_table); |
2720 | 2727 | ||
2728 | struct jump_label_key rps_needed __read_mostly; | ||
2729 | |||
2721 | static struct rps_dev_flow * | 2730 | static struct rps_dev_flow * |
2722 | set_rps_cpu(struct net_device *dev, struct sk_buff *skb, | 2731 | set_rps_cpu(struct net_device *dev, struct sk_buff *skb, |
2723 | struct rps_dev_flow *rflow, u16 next_cpu) | 2732 | struct rps_dev_flow *rflow, u16 next_cpu) |
@@ -2997,12 +3006,11 @@ int netif_rx(struct sk_buff *skb) | |||
2997 | if (netpoll_rx(skb)) | 3006 | if (netpoll_rx(skb)) |
2998 | return NET_RX_DROP; | 3007 | return NET_RX_DROP; |
2999 | 3008 | ||
3000 | if (netdev_tstamp_prequeue) | 3009 | net_timestamp_check(netdev_tstamp_prequeue, skb); |
3001 | net_timestamp_check(skb); | ||
3002 | 3010 | ||
3003 | trace_netif_rx(skb); | 3011 | trace_netif_rx(skb); |
3004 | #ifdef CONFIG_RPS | 3012 | #ifdef CONFIG_RPS |
3005 | { | 3013 | if (static_branch(&rps_needed)) { |
3006 | struct rps_dev_flow voidflow, *rflow = &voidflow; | 3014 | struct rps_dev_flow voidflow, *rflow = &voidflow; |
3007 | int cpu; | 3015 | int cpu; |
3008 | 3016 | ||
@@ -3017,14 +3025,13 @@ int netif_rx(struct sk_buff *skb) | |||
3017 | 3025 | ||
3018 | rcu_read_unlock(); | 3026 | rcu_read_unlock(); |
3019 | preempt_enable(); | 3027 | preempt_enable(); |
3020 | } | 3028 | } else |
3021 | #else | 3029 | #endif |
3022 | { | 3030 | { |
3023 | unsigned int qtail; | 3031 | unsigned int qtail; |
3024 | ret = enqueue_to_backlog(skb, get_cpu(), &qtail); | 3032 | ret = enqueue_to_backlog(skb, get_cpu(), &qtail); |
3025 | put_cpu(); | 3033 | put_cpu(); |
3026 | } | 3034 | } |
3027 | #endif | ||
3028 | return ret; | 3035 | return ret; |
3029 | } | 3036 | } |
3030 | EXPORT_SYMBOL(netif_rx); | 3037 | EXPORT_SYMBOL(netif_rx); |
@@ -3230,8 +3237,7 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
3230 | int ret = NET_RX_DROP; | 3237 | int ret = NET_RX_DROP; |
3231 | __be16 type; | 3238 | __be16 type; |
3232 | 3239 | ||
3233 | if (!netdev_tstamp_prequeue) | 3240 | net_timestamp_check(!netdev_tstamp_prequeue, skb); |
3234 | net_timestamp_check(skb); | ||
3235 | 3241 | ||
3236 | trace_netif_receive_skb(skb); | 3242 | trace_netif_receive_skb(skb); |
3237 | 3243 | ||
@@ -3362,14 +3368,13 @@ out: | |||
3362 | */ | 3368 | */ |
3363 | int netif_receive_skb(struct sk_buff *skb) | 3369 | int netif_receive_skb(struct sk_buff *skb) |
3364 | { | 3370 | { |
3365 | if (netdev_tstamp_prequeue) | 3371 | net_timestamp_check(netdev_tstamp_prequeue, skb); |
3366 | net_timestamp_check(skb); | ||
3367 | 3372 | ||
3368 | if (skb_defer_rx_timestamp(skb)) | 3373 | if (skb_defer_rx_timestamp(skb)) |
3369 | return NET_RX_SUCCESS; | 3374 | return NET_RX_SUCCESS; |
3370 | 3375 | ||
3371 | #ifdef CONFIG_RPS | 3376 | #ifdef CONFIG_RPS |
3372 | { | 3377 | if (static_branch(&rps_needed)) { |
3373 | struct rps_dev_flow voidflow, *rflow = &voidflow; | 3378 | struct rps_dev_flow voidflow, *rflow = &voidflow; |
3374 | int cpu, ret; | 3379 | int cpu, ret; |
3375 | 3380 | ||
@@ -3380,16 +3385,12 @@ int netif_receive_skb(struct sk_buff *skb) | |||
3380 | if (cpu >= 0) { | 3385 | if (cpu >= 0) { |
3381 | ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail); | 3386 | ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail); |
3382 | rcu_read_unlock(); | 3387 | rcu_read_unlock(); |
3383 | } else { | 3388 | return ret; |
3384 | rcu_read_unlock(); | ||
3385 | ret = __netif_receive_skb(skb); | ||
3386 | } | 3389 | } |
3387 | 3390 | rcu_read_unlock(); | |
3388 | return ret; | ||
3389 | } | 3391 | } |
3390 | #else | ||
3391 | return __netif_receive_skb(skb); | ||
3392 | #endif | 3392 | #endif |
3393 | return __netif_receive_skb(skb); | ||
3393 | } | 3394 | } |
3394 | EXPORT_SYMBOL(netif_receive_skb); | 3395 | EXPORT_SYMBOL(netif_receive_skb); |
3395 | 3396 | ||
@@ -5362,7 +5363,8 @@ static void rollback_registered(struct net_device *dev) | |||
5362 | list_del(&single); | 5363 | list_del(&single); |
5363 | } | 5364 | } |
5364 | 5365 | ||
5365 | static u32 netdev_fix_features(struct net_device *dev, u32 features) | 5366 | static netdev_features_t netdev_fix_features(struct net_device *dev, |
5367 | netdev_features_t features) | ||
5366 | { | 5368 | { |
5367 | /* Fix illegal checksum combinations */ | 5369 | /* Fix illegal checksum combinations */ |
5368 | if ((features & NETIF_F_HW_CSUM) && | 5370 | if ((features & NETIF_F_HW_CSUM) && |
@@ -5371,12 +5373,6 @@ static u32 netdev_fix_features(struct net_device *dev, u32 features) | |||
5371 | features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM); | 5373 | features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM); |
5372 | } | 5374 | } |
5373 | 5375 | ||
5374 | if ((features & NETIF_F_NO_CSUM) && | ||
5375 | (features & (NETIF_F_HW_CSUM|NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { | ||
5376 | netdev_warn(dev, "mixed no checksumming and other settings.\n"); | ||
5377 | features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM); | ||
5378 | } | ||
5379 | |||
5380 | /* Fix illegal SG+CSUM combinations. */ | 5376 | /* Fix illegal SG+CSUM combinations. */ |
5381 | if ((features & NETIF_F_SG) && | 5377 | if ((features & NETIF_F_SG) && |
5382 | !(features & NETIF_F_ALL_CSUM)) { | 5378 | !(features & NETIF_F_ALL_CSUM)) { |
@@ -5424,7 +5420,7 @@ static u32 netdev_fix_features(struct net_device *dev, u32 features) | |||
5424 | 5420 | ||
5425 | int __netdev_update_features(struct net_device *dev) | 5421 | int __netdev_update_features(struct net_device *dev) |
5426 | { | 5422 | { |
5427 | u32 features; | 5423 | netdev_features_t features; |
5428 | int err = 0; | 5424 | int err = 0; |
5429 | 5425 | ||
5430 | ASSERT_RTNL(); | 5426 | ASSERT_RTNL(); |
@@ -5440,16 +5436,16 @@ int __netdev_update_features(struct net_device *dev) | |||
5440 | if (dev->features == features) | 5436 | if (dev->features == features) |
5441 | return 0; | 5437 | return 0; |
5442 | 5438 | ||
5443 | netdev_dbg(dev, "Features changed: 0x%08x -> 0x%08x\n", | 5439 | netdev_dbg(dev, "Features changed: %pNF -> %pNF\n", |
5444 | dev->features, features); | 5440 | &dev->features, &features); |
5445 | 5441 | ||
5446 | if (dev->netdev_ops->ndo_set_features) | 5442 | if (dev->netdev_ops->ndo_set_features) |
5447 | err = dev->netdev_ops->ndo_set_features(dev, features); | 5443 | err = dev->netdev_ops->ndo_set_features(dev, features); |
5448 | 5444 | ||
5449 | if (unlikely(err < 0)) { | 5445 | if (unlikely(err < 0)) { |
5450 | netdev_err(dev, | 5446 | netdev_err(dev, |
5451 | "set_features() failed (%d); wanted 0x%08x, left 0x%08x\n", | 5447 | "set_features() failed (%d); wanted %pNF, left %pNF\n", |
5452 | err, features, dev->features); | 5448 | err, &features, &dev->features); |
5453 | return -1; | 5449 | return -1; |
5454 | } | 5450 | } |
5455 | 5451 | ||
@@ -5633,11 +5629,12 @@ int register_netdevice(struct net_device *dev) | |||
5633 | dev->wanted_features = dev->features & dev->hw_features; | 5629 | dev->wanted_features = dev->features & dev->hw_features; |
5634 | 5630 | ||
5635 | /* Turn on no cache copy if HW is doing checksum */ | 5631 | /* Turn on no cache copy if HW is doing checksum */ |
5636 | dev->hw_features |= NETIF_F_NOCACHE_COPY; | 5632 | if (!(dev->flags & IFF_LOOPBACK)) { |
5637 | if ((dev->features & NETIF_F_ALL_CSUM) && | 5633 | dev->hw_features |= NETIF_F_NOCACHE_COPY; |
5638 | !(dev->features & NETIF_F_NO_CSUM)) { | 5634 | if (dev->features & NETIF_F_ALL_CSUM) { |
5639 | dev->wanted_features |= NETIF_F_NOCACHE_COPY; | 5635 | dev->wanted_features |= NETIF_F_NOCACHE_COPY; |
5640 | dev->features |= NETIF_F_NOCACHE_COPY; | 5636 | dev->features |= NETIF_F_NOCACHE_COPY; |
5637 | } | ||
5641 | } | 5638 | } |
5642 | 5639 | ||
5643 | /* Make NETIF_F_HIGHDMA inheritable to VLAN devices. | 5640 | /* Make NETIF_F_HIGHDMA inheritable to VLAN devices. |
@@ -6373,7 +6370,8 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
6373 | * @one to the master device with current feature set @all. Will not | 6370 | * @one to the master device with current feature set @all. Will not |
6374 | * enable anything that is off in @mask. Returns the new feature set. | 6371 | * enable anything that is off in @mask. Returns the new feature set. |
6375 | */ | 6372 | */ |
6376 | u32 netdev_increment_features(u32 all, u32 one, u32 mask) | 6373 | netdev_features_t netdev_increment_features(netdev_features_t all, |
6374 | netdev_features_t one, netdev_features_t mask) | ||
6377 | { | 6375 | { |
6378 | if (mask & NETIF_F_GEN_CSUM) | 6376 | if (mask & NETIF_F_GEN_CSUM) |
6379 | mask |= NETIF_F_ALL_CSUM; | 6377 | mask |= NETIF_F_ALL_CSUM; |
@@ -6382,10 +6380,6 @@ u32 netdev_increment_features(u32 all, u32 one, u32 mask) | |||
6382 | all |= one & (NETIF_F_ONE_FOR_ALL|NETIF_F_ALL_CSUM) & mask; | 6380 | all |= one & (NETIF_F_ONE_FOR_ALL|NETIF_F_ALL_CSUM) & mask; |
6383 | all &= one | ~NETIF_F_ALL_FOR_ALL; | 6381 | all &= one | ~NETIF_F_ALL_FOR_ALL; |
6384 | 6382 | ||
6385 | /* If device needs checksumming, downgrade to it. */ | ||
6386 | if (all & (NETIF_F_ALL_CSUM & ~NETIF_F_NO_CSUM)) | ||
6387 | all &= ~NETIF_F_NO_CSUM; | ||
6388 | |||
6389 | /* If one device supports hw checksumming, set for all. */ | 6383 | /* If one device supports hw checksumming, set for all. */ |
6390 | if (all & NETIF_F_GEN_CSUM) | 6384 | if (all & NETIF_F_GEN_CSUM) |
6391 | all &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM); | 6385 | all &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM); |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index f44481707124..31b0b7f5383e 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -36,235 +36,44 @@ u32 ethtool_op_get_link(struct net_device *dev) | |||
36 | } | 36 | } |
37 | EXPORT_SYMBOL(ethtool_op_get_link); | 37 | EXPORT_SYMBOL(ethtool_op_get_link); |
38 | 38 | ||
39 | u32 ethtool_op_get_tx_csum(struct net_device *dev) | ||
40 | { | ||
41 | return (dev->features & NETIF_F_ALL_CSUM) != 0; | ||
42 | } | ||
43 | EXPORT_SYMBOL(ethtool_op_get_tx_csum); | ||
44 | |||
45 | int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) | ||
46 | { | ||
47 | if (data) | ||
48 | dev->features |= NETIF_F_IP_CSUM; | ||
49 | else | ||
50 | dev->features &= ~NETIF_F_IP_CSUM; | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | EXPORT_SYMBOL(ethtool_op_set_tx_csum); | ||
55 | |||
56 | int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data) | ||
57 | { | ||
58 | if (data) | ||
59 | dev->features |= NETIF_F_HW_CSUM; | ||
60 | else | ||
61 | dev->features &= ~NETIF_F_HW_CSUM; | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum); | ||
66 | |||
67 | int ethtool_op_set_tx_ipv6_csum(struct net_device *dev, u32 data) | ||
68 | { | ||
69 | if (data) | ||
70 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; | ||
71 | else | ||
72 | dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | EXPORT_SYMBOL(ethtool_op_set_tx_ipv6_csum); | ||
77 | |||
78 | u32 ethtool_op_get_sg(struct net_device *dev) | ||
79 | { | ||
80 | return (dev->features & NETIF_F_SG) != 0; | ||
81 | } | ||
82 | EXPORT_SYMBOL(ethtool_op_get_sg); | ||
83 | |||
84 | int ethtool_op_set_sg(struct net_device *dev, u32 data) | ||
85 | { | ||
86 | if (data) | ||
87 | dev->features |= NETIF_F_SG; | ||
88 | else | ||
89 | dev->features &= ~NETIF_F_SG; | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | EXPORT_SYMBOL(ethtool_op_set_sg); | ||
94 | |||
95 | u32 ethtool_op_get_tso(struct net_device *dev) | ||
96 | { | ||
97 | return (dev->features & NETIF_F_TSO) != 0; | ||
98 | } | ||
99 | EXPORT_SYMBOL(ethtool_op_get_tso); | ||
100 | |||
101 | int ethtool_op_set_tso(struct net_device *dev, u32 data) | ||
102 | { | ||
103 | if (data) | ||
104 | dev->features |= NETIF_F_TSO; | ||
105 | else | ||
106 | dev->features &= ~NETIF_F_TSO; | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | EXPORT_SYMBOL(ethtool_op_set_tso); | ||
111 | |||
112 | u32 ethtool_op_get_ufo(struct net_device *dev) | ||
113 | { | ||
114 | return (dev->features & NETIF_F_UFO) != 0; | ||
115 | } | ||
116 | EXPORT_SYMBOL(ethtool_op_get_ufo); | ||
117 | |||
118 | int ethtool_op_set_ufo(struct net_device *dev, u32 data) | ||
119 | { | ||
120 | if (data) | ||
121 | dev->features |= NETIF_F_UFO; | ||
122 | else | ||
123 | dev->features &= ~NETIF_F_UFO; | ||
124 | return 0; | ||
125 | } | ||
126 | EXPORT_SYMBOL(ethtool_op_set_ufo); | ||
127 | |||
128 | /* the following list of flags are the same as their associated | ||
129 | * NETIF_F_xxx values in include/linux/netdevice.h | ||
130 | */ | ||
131 | static const u32 flags_dup_features = | ||
132 | (ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE | | ||
133 | ETH_FLAG_RXHASH); | ||
134 | |||
135 | u32 ethtool_op_get_flags(struct net_device *dev) | ||
136 | { | ||
137 | /* in the future, this function will probably contain additional | ||
138 | * handling for flags which are not so easily handled | ||
139 | * by a simple masking operation | ||
140 | */ | ||
141 | |||
142 | return dev->features & flags_dup_features; | ||
143 | } | ||
144 | EXPORT_SYMBOL(ethtool_op_get_flags); | ||
145 | |||
146 | /* Check if device can enable (or disable) particular feature coded in "data" | ||
147 | * argument. Flags "supported" describe features that can be toggled by device. | ||
148 | * If feature can not be toggled, it state (enabled or disabled) must match | ||
149 | * hardcoded device features state, otherwise flags are marked as invalid. | ||
150 | */ | ||
151 | bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported) | ||
152 | { | ||
153 | u32 features = dev->features & flags_dup_features; | ||
154 | /* "data" can contain only flags_dup_features bits, | ||
155 | * see __ethtool_set_flags */ | ||
156 | |||
157 | return (features & ~supported) != (data & ~supported); | ||
158 | } | ||
159 | EXPORT_SYMBOL(ethtool_invalid_flags); | ||
160 | |||
161 | int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported) | ||
162 | { | ||
163 | if (ethtool_invalid_flags(dev, data, supported)) | ||
164 | return -EINVAL; | ||
165 | |||
166 | dev->features = ((dev->features & ~flags_dup_features) | | ||
167 | (data & flags_dup_features)); | ||
168 | return 0; | ||
169 | } | ||
170 | EXPORT_SYMBOL(ethtool_op_set_flags); | ||
171 | |||
172 | /* Handlers for each ethtool command */ | 39 | /* Handlers for each ethtool command */ |
173 | 40 | ||
174 | #define ETHTOOL_DEV_FEATURE_WORDS 1 | 41 | #define ETHTOOL_DEV_FEATURE_WORDS ((NETDEV_FEATURE_COUNT + 31) / 32) |
175 | 42 | ||
176 | static void ethtool_get_features_compat(struct net_device *dev, | 43 | static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] = { |
177 | struct ethtool_get_features_block *features) | 44 | [NETIF_F_SG_BIT] = "tx-scatter-gather", |
178 | { | 45 | [NETIF_F_IP_CSUM_BIT] = "tx-checksum-ipv4", |
179 | if (!dev->ethtool_ops) | 46 | [NETIF_F_HW_CSUM_BIT] = "tx-checksum-ip-generic", |
180 | return; | 47 | [NETIF_F_IPV6_CSUM_BIT] = "tx-checksum-ipv6", |
181 | 48 | [NETIF_F_HIGHDMA_BIT] = "highdma", | |
182 | /* getting RX checksum */ | 49 | [NETIF_F_FRAGLIST_BIT] = "tx-scatter-gather-fraglist", |
183 | if (dev->ethtool_ops->get_rx_csum) | 50 | [NETIF_F_HW_VLAN_TX_BIT] = "tx-vlan-hw-insert", |
184 | if (dev->ethtool_ops->get_rx_csum(dev)) | 51 | |
185 | features[0].active |= NETIF_F_RXCSUM; | 52 | [NETIF_F_HW_VLAN_RX_BIT] = "rx-vlan-hw-parse", |
186 | 53 | [NETIF_F_HW_VLAN_FILTER_BIT] = "rx-vlan-filter", | |
187 | /* mark legacy-changeable features */ | 54 | [NETIF_F_VLAN_CHALLENGED_BIT] = "vlan-challenged", |
188 | if (dev->ethtool_ops->set_sg) | 55 | [NETIF_F_GSO_BIT] = "tx-generic-segmentation", |
189 | features[0].available |= NETIF_F_SG; | 56 | [NETIF_F_LLTX_BIT] = "tx-lockless", |
190 | if (dev->ethtool_ops->set_tx_csum) | 57 | [NETIF_F_NETNS_LOCAL_BIT] = "netns-local", |
191 | features[0].available |= NETIF_F_ALL_CSUM; | 58 | [NETIF_F_GRO_BIT] = "rx-gro", |
192 | if (dev->ethtool_ops->set_tso) | 59 | [NETIF_F_LRO_BIT] = "rx-lro", |
193 | features[0].available |= NETIF_F_ALL_TSO; | 60 | |
194 | if (dev->ethtool_ops->set_rx_csum) | 61 | [NETIF_F_TSO_BIT] = "tx-tcp-segmentation", |
195 | features[0].available |= NETIF_F_RXCSUM; | 62 | [NETIF_F_UFO_BIT] = "tx-udp-fragmentation", |
196 | if (dev->ethtool_ops->set_flags) | 63 | [NETIF_F_GSO_ROBUST_BIT] = "tx-gso-robust", |
197 | features[0].available |= flags_dup_features; | 64 | [NETIF_F_TSO_ECN_BIT] = "tx-tcp-ecn-segmentation", |
198 | } | 65 | [NETIF_F_TSO6_BIT] = "tx-tcp6-segmentation", |
199 | 66 | [NETIF_F_FSO_BIT] = "tx-fcoe-segmentation", | |
200 | static int ethtool_set_feature_compat(struct net_device *dev, | 67 | |
201 | int (*legacy_set)(struct net_device *, u32), | 68 | [NETIF_F_FCOE_CRC_BIT] = "tx-checksum-fcoe-crc", |
202 | struct ethtool_set_features_block *features, u32 mask) | 69 | [NETIF_F_SCTP_CSUM_BIT] = "tx-checksum-sctp", |
203 | { | 70 | [NETIF_F_FCOE_MTU_BIT] = "fcoe-mtu", |
204 | u32 do_set; | 71 | [NETIF_F_NTUPLE_BIT] = "rx-ntuple-filter", |
205 | 72 | [NETIF_F_RXHASH_BIT] = "rx-hashing", | |
206 | if (!legacy_set) | 73 | [NETIF_F_RXCSUM_BIT] = "rx-checksum", |
207 | return 0; | 74 | [NETIF_F_NOCACHE_COPY_BIT] = "tx-nocache-copy", |
208 | 75 | [NETIF_F_LOOPBACK_BIT] = "loopback", | |
209 | if (!(features[0].valid & mask)) | 76 | }; |
210 | return 0; | ||
211 | |||
212 | features[0].valid &= ~mask; | ||
213 | |||
214 | do_set = !!(features[0].requested & mask); | ||
215 | |||
216 | if (legacy_set(dev, do_set) < 0) | ||
217 | netdev_info(dev, | ||
218 | "Legacy feature change (%s) failed for 0x%08x\n", | ||
219 | do_set ? "set" : "clear", mask); | ||
220 | |||
221 | return 1; | ||
222 | } | ||
223 | |||
224 | static int ethtool_set_flags_compat(struct net_device *dev, | ||
225 | int (*legacy_set)(struct net_device *, u32), | ||
226 | struct ethtool_set_features_block *features, u32 mask) | ||
227 | { | ||
228 | u32 value; | ||
229 | |||
230 | if (!legacy_set) | ||
231 | return 0; | ||
232 | |||
233 | if (!(features[0].valid & mask)) | ||
234 | return 0; | ||
235 | |||
236 | value = dev->features & ~features[0].valid; | ||
237 | value |= features[0].requested; | ||
238 | |||
239 | features[0].valid &= ~mask; | ||
240 | |||
241 | if (legacy_set(dev, value & mask) < 0) | ||
242 | netdev_info(dev, "Legacy flags change failed\n"); | ||
243 | |||
244 | return 1; | ||
245 | } | ||
246 | |||
247 | static int ethtool_set_features_compat(struct net_device *dev, | ||
248 | struct ethtool_set_features_block *features) | ||
249 | { | ||
250 | int compat; | ||
251 | |||
252 | if (!dev->ethtool_ops) | ||
253 | return 0; | ||
254 | |||
255 | compat = ethtool_set_feature_compat(dev, dev->ethtool_ops->set_sg, | ||
256 | features, NETIF_F_SG); | ||
257 | compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_tx_csum, | ||
258 | features, NETIF_F_ALL_CSUM); | ||
259 | compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_tso, | ||
260 | features, NETIF_F_ALL_TSO); | ||
261 | compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_rx_csum, | ||
262 | features, NETIF_F_RXCSUM); | ||
263 | compat |= ethtool_set_flags_compat(dev, dev->ethtool_ops->set_flags, | ||
264 | features, flags_dup_features); | ||
265 | |||
266 | return compat; | ||
267 | } | ||
268 | 77 | ||
269 | static int ethtool_get_features(struct net_device *dev, void __user *useraddr) | 78 | static int ethtool_get_features(struct net_device *dev, void __user *useraddr) |
270 | { | 79 | { |
@@ -272,18 +81,21 @@ static int ethtool_get_features(struct net_device *dev, void __user *useraddr) | |||
272 | .cmd = ETHTOOL_GFEATURES, | 81 | .cmd = ETHTOOL_GFEATURES, |
273 | .size = ETHTOOL_DEV_FEATURE_WORDS, | 82 | .size = ETHTOOL_DEV_FEATURE_WORDS, |
274 | }; | 83 | }; |
275 | struct ethtool_get_features_block features[ETHTOOL_DEV_FEATURE_WORDS] = { | 84 | struct ethtool_get_features_block features[ETHTOOL_DEV_FEATURE_WORDS]; |
276 | { | ||
277 | .available = dev->hw_features, | ||
278 | .requested = dev->wanted_features, | ||
279 | .active = dev->features, | ||
280 | .never_changed = NETIF_F_NEVER_CHANGE, | ||
281 | }, | ||
282 | }; | ||
283 | u32 __user *sizeaddr; | 85 | u32 __user *sizeaddr; |
284 | u32 copy_size; | 86 | u32 copy_size; |
87 | int i; | ||
285 | 88 | ||
286 | ethtool_get_features_compat(dev, features); | 89 | /* in case feature bits run out again */ |
90 | BUILD_BUG_ON(ETHTOOL_DEV_FEATURE_WORDS * sizeof(u32) > sizeof(netdev_features_t)); | ||
91 | |||
92 | for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) { | ||
93 | features[i].available = (u32)(dev->hw_features >> (32 * i)); | ||
94 | features[i].requested = (u32)(dev->wanted_features >> (32 * i)); | ||
95 | features[i].active = (u32)(dev->features >> (32 * i)); | ||
96 | features[i].never_changed = | ||
97 | (u32)(NETIF_F_NEVER_CHANGE >> (32 * i)); | ||
98 | } | ||
287 | 99 | ||
288 | sizeaddr = useraddr + offsetof(struct ethtool_gfeatures, size); | 100 | sizeaddr = useraddr + offsetof(struct ethtool_gfeatures, size); |
289 | if (get_user(copy_size, sizeaddr)) | 101 | if (get_user(copy_size, sizeaddr)) |
@@ -305,7 +117,8 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr) | |||
305 | { | 117 | { |
306 | struct ethtool_sfeatures cmd; | 118 | struct ethtool_sfeatures cmd; |
307 | struct ethtool_set_features_block features[ETHTOOL_DEV_FEATURE_WORDS]; | 119 | struct ethtool_set_features_block features[ETHTOOL_DEV_FEATURE_WORDS]; |
308 | int ret = 0; | 120 | netdev_features_t wanted = 0, valid = 0; |
121 | int i, ret = 0; | ||
309 | 122 | ||
310 | if (copy_from_user(&cmd, useraddr, sizeof(cmd))) | 123 | if (copy_from_user(&cmd, useraddr, sizeof(cmd))) |
311 | return -EFAULT; | 124 | return -EFAULT; |
@@ -317,65 +130,29 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr) | |||
317 | if (copy_from_user(features, useraddr, sizeof(features))) | 130 | if (copy_from_user(features, useraddr, sizeof(features))) |
318 | return -EFAULT; | 131 | return -EFAULT; |
319 | 132 | ||
320 | if (features[0].valid & ~NETIF_F_ETHTOOL_BITS) | 133 | for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) { |
321 | return -EINVAL; | 134 | valid |= (netdev_features_t)features[i].valid << (32 * i); |
135 | wanted |= (netdev_features_t)features[i].requested << (32 * i); | ||
136 | } | ||
322 | 137 | ||
323 | if (ethtool_set_features_compat(dev, features)) | 138 | if (valid & ~NETIF_F_ETHTOOL_BITS) |
324 | ret |= ETHTOOL_F_COMPAT; | 139 | return -EINVAL; |
325 | 140 | ||
326 | if (features[0].valid & ~dev->hw_features) { | 141 | if (valid & ~dev->hw_features) { |
327 | features[0].valid &= dev->hw_features; | 142 | valid &= dev->hw_features; |
328 | ret |= ETHTOOL_F_UNSUPPORTED; | 143 | ret |= ETHTOOL_F_UNSUPPORTED; |
329 | } | 144 | } |
330 | 145 | ||
331 | dev->wanted_features &= ~features[0].valid; | 146 | dev->wanted_features &= ~valid; |
332 | dev->wanted_features |= features[0].valid & features[0].requested; | 147 | dev->wanted_features |= wanted & valid; |
333 | __netdev_update_features(dev); | 148 | __netdev_update_features(dev); |
334 | 149 | ||
335 | if ((dev->wanted_features ^ dev->features) & features[0].valid) | 150 | if ((dev->wanted_features ^ dev->features) & valid) |
336 | ret |= ETHTOOL_F_WISH; | 151 | ret |= ETHTOOL_F_WISH; |
337 | 152 | ||
338 | return ret; | 153 | return ret; |
339 | } | 154 | } |
340 | 155 | ||
341 | static const char netdev_features_strings[ETHTOOL_DEV_FEATURE_WORDS * 32][ETH_GSTRING_LEN] = { | ||
342 | /* NETIF_F_SG */ "tx-scatter-gather", | ||
343 | /* NETIF_F_IP_CSUM */ "tx-checksum-ipv4", | ||
344 | /* NETIF_F_NO_CSUM */ "tx-checksum-unneeded", | ||
345 | /* NETIF_F_HW_CSUM */ "tx-checksum-ip-generic", | ||
346 | /* NETIF_F_IPV6_CSUM */ "tx-checksum-ipv6", | ||
347 | /* NETIF_F_HIGHDMA */ "highdma", | ||
348 | /* NETIF_F_FRAGLIST */ "tx-scatter-gather-fraglist", | ||
349 | /* NETIF_F_HW_VLAN_TX */ "tx-vlan-hw-insert", | ||
350 | |||
351 | /* NETIF_F_HW_VLAN_RX */ "rx-vlan-hw-parse", | ||
352 | /* NETIF_F_HW_VLAN_FILTER */ "rx-vlan-filter", | ||
353 | /* NETIF_F_VLAN_CHALLENGED */ "vlan-challenged", | ||
354 | /* NETIF_F_GSO */ "tx-generic-segmentation", | ||
355 | /* NETIF_F_LLTX */ "tx-lockless", | ||
356 | /* NETIF_F_NETNS_LOCAL */ "netns-local", | ||
357 | /* NETIF_F_GRO */ "rx-gro", | ||
358 | /* NETIF_F_LRO */ "rx-lro", | ||
359 | |||
360 | /* NETIF_F_TSO */ "tx-tcp-segmentation", | ||
361 | /* NETIF_F_UFO */ "tx-udp-fragmentation", | ||
362 | /* NETIF_F_GSO_ROBUST */ "tx-gso-robust", | ||
363 | /* NETIF_F_TSO_ECN */ "tx-tcp-ecn-segmentation", | ||
364 | /* NETIF_F_TSO6 */ "tx-tcp6-segmentation", | ||
365 | /* NETIF_F_FSO */ "tx-fcoe-segmentation", | ||
366 | "", | ||
367 | "", | ||
368 | |||
369 | /* NETIF_F_FCOE_CRC */ "tx-checksum-fcoe-crc", | ||
370 | /* NETIF_F_SCTP_CSUM */ "tx-checksum-sctp", | ||
371 | /* NETIF_F_FCOE_MTU */ "fcoe-mtu", | ||
372 | /* NETIF_F_NTUPLE */ "rx-ntuple-filter", | ||
373 | /* NETIF_F_RXHASH */ "rx-hashing", | ||
374 | /* NETIF_F_RXCSUM */ "rx-checksum", | ||
375 | /* NETIF_F_NOCACHE_COPY */ "tx-nocache-copy", | ||
376 | /* NETIF_F_LOOPBACK */ "loopback", | ||
377 | }; | ||
378 | |||
379 | static int __ethtool_get_sset_count(struct net_device *dev, int sset) | 156 | static int __ethtool_get_sset_count(struct net_device *dev, int sset) |
380 | { | 157 | { |
381 | const struct ethtool_ops *ops = dev->ethtool_ops; | 158 | const struct ethtool_ops *ops = dev->ethtool_ops; |
@@ -402,7 +179,7 @@ static void __ethtool_get_strings(struct net_device *dev, | |||
402 | ops->get_strings(dev, stringset, data); | 179 | ops->get_strings(dev, stringset, data); |
403 | } | 180 | } |
404 | 181 | ||
405 | static u32 ethtool_get_feature_mask(u32 eth_cmd) | 182 | static netdev_features_t ethtool_get_feature_mask(u32 eth_cmd) |
406 | { | 183 | { |
407 | /* feature masks of legacy discrete ethtool ops */ | 184 | /* feature masks of legacy discrete ethtool ops */ |
408 | 185 | ||
@@ -433,136 +210,82 @@ static u32 ethtool_get_feature_mask(u32 eth_cmd) | |||
433 | } | 210 | } |
434 | } | 211 | } |
435 | 212 | ||
436 | static void *__ethtool_get_one_feature_actor(struct net_device *dev, u32 ethcmd) | ||
437 | { | ||
438 | const struct ethtool_ops *ops = dev->ethtool_ops; | ||
439 | |||
440 | if (!ops) | ||
441 | return NULL; | ||
442 | |||
443 | switch (ethcmd) { | ||
444 | case ETHTOOL_GTXCSUM: | ||
445 | return ops->get_tx_csum; | ||
446 | case ETHTOOL_GRXCSUM: | ||
447 | return ops->get_rx_csum; | ||
448 | case ETHTOOL_SSG: | ||
449 | return ops->get_sg; | ||
450 | case ETHTOOL_STSO: | ||
451 | return ops->get_tso; | ||
452 | case ETHTOOL_SUFO: | ||
453 | return ops->get_ufo; | ||
454 | default: | ||
455 | return NULL; | ||
456 | } | ||
457 | } | ||
458 | |||
459 | static u32 __ethtool_get_rx_csum_oldbug(struct net_device *dev) | ||
460 | { | ||
461 | return !!(dev->features & NETIF_F_ALL_CSUM); | ||
462 | } | ||
463 | |||
464 | static int ethtool_get_one_feature(struct net_device *dev, | 213 | static int ethtool_get_one_feature(struct net_device *dev, |
465 | char __user *useraddr, u32 ethcmd) | 214 | char __user *useraddr, u32 ethcmd) |
466 | { | 215 | { |
467 | u32 mask = ethtool_get_feature_mask(ethcmd); | 216 | netdev_features_t mask = ethtool_get_feature_mask(ethcmd); |
468 | struct ethtool_value edata = { | 217 | struct ethtool_value edata = { |
469 | .cmd = ethcmd, | 218 | .cmd = ethcmd, |
470 | .data = !!(dev->features & mask), | 219 | .data = !!(dev->features & mask), |
471 | }; | 220 | }; |
472 | 221 | ||
473 | /* compatibility with discrete get_ ops */ | ||
474 | if (!(dev->hw_features & mask)) { | ||
475 | u32 (*actor)(struct net_device *); | ||
476 | |||
477 | actor = __ethtool_get_one_feature_actor(dev, ethcmd); | ||
478 | |||
479 | /* bug compatibility with old get_rx_csum */ | ||
480 | if (ethcmd == ETHTOOL_GRXCSUM && !actor) | ||
481 | actor = __ethtool_get_rx_csum_oldbug; | ||
482 | |||
483 | if (actor) | ||
484 | edata.data = actor(dev); | ||
485 | } | ||
486 | |||
487 | if (copy_to_user(useraddr, &edata, sizeof(edata))) | 222 | if (copy_to_user(useraddr, &edata, sizeof(edata))) |
488 | return -EFAULT; | 223 | return -EFAULT; |
489 | return 0; | 224 | return 0; |
490 | } | 225 | } |
491 | 226 | ||
492 | static int __ethtool_set_tx_csum(struct net_device *dev, u32 data); | ||
493 | static int __ethtool_set_rx_csum(struct net_device *dev, u32 data); | ||
494 | static int __ethtool_set_sg(struct net_device *dev, u32 data); | ||
495 | static int __ethtool_set_tso(struct net_device *dev, u32 data); | ||
496 | static int __ethtool_set_ufo(struct net_device *dev, u32 data); | ||
497 | |||
498 | static int ethtool_set_one_feature(struct net_device *dev, | 227 | static int ethtool_set_one_feature(struct net_device *dev, |
499 | void __user *useraddr, u32 ethcmd) | 228 | void __user *useraddr, u32 ethcmd) |
500 | { | 229 | { |
501 | struct ethtool_value edata; | 230 | struct ethtool_value edata; |
502 | u32 mask; | 231 | netdev_features_t mask; |
503 | 232 | ||
504 | if (copy_from_user(&edata, useraddr, sizeof(edata))) | 233 | if (copy_from_user(&edata, useraddr, sizeof(edata))) |
505 | return -EFAULT; | 234 | return -EFAULT; |
506 | 235 | ||
507 | mask = ethtool_get_feature_mask(ethcmd); | 236 | mask = ethtool_get_feature_mask(ethcmd); |
508 | mask &= dev->hw_features; | 237 | mask &= dev->hw_features; |
509 | if (mask) { | 238 | if (!mask) |
510 | if (edata.data) | 239 | return -EOPNOTSUPP; |
511 | dev->wanted_features |= mask; | ||
512 | else | ||
513 | dev->wanted_features &= ~mask; | ||
514 | 240 | ||
515 | __netdev_update_features(dev); | 241 | if (edata.data) |
516 | return 0; | 242 | dev->wanted_features |= mask; |
517 | } | 243 | else |
244 | dev->wanted_features &= ~mask; | ||
518 | 245 | ||
519 | /* Driver is not converted to ndo_fix_features or does not | 246 | __netdev_update_features(dev); |
520 | * support changing this offload. In the latter case it won't | ||
521 | * have corresponding ethtool_ops field set. | ||
522 | * | ||
523 | * Following part is to be removed after all drivers advertise | ||
524 | * their changeable features in netdev->hw_features and stop | ||
525 | * using discrete offload setting ops. | ||
526 | */ | ||
527 | 247 | ||
528 | switch (ethcmd) { | 248 | return 0; |
529 | case ETHTOOL_STXCSUM: | 249 | } |
530 | return __ethtool_set_tx_csum(dev, edata.data); | 250 | |
531 | case ETHTOOL_SRXCSUM: | 251 | #define ETH_ALL_FLAGS (ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | \ |
532 | return __ethtool_set_rx_csum(dev, edata.data); | 252 | ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH) |
533 | case ETHTOOL_SSG: | 253 | #define ETH_ALL_FEATURES (NETIF_F_LRO | NETIF_F_HW_VLAN_RX | \ |
534 | return __ethtool_set_sg(dev, edata.data); | 254 | NETIF_F_HW_VLAN_TX | NETIF_F_NTUPLE | NETIF_F_RXHASH) |
535 | case ETHTOOL_STSO: | 255 | |
536 | return __ethtool_set_tso(dev, edata.data); | 256 | static u32 __ethtool_get_flags(struct net_device *dev) |
537 | case ETHTOOL_SUFO: | 257 | { |
538 | return __ethtool_set_ufo(dev, edata.data); | 258 | u32 flags = 0; |
539 | default: | 259 | |
540 | return -EOPNOTSUPP; | 260 | if (dev->features & NETIF_F_LRO) flags |= ETH_FLAG_LRO; |
541 | } | 261 | if (dev->features & NETIF_F_HW_VLAN_RX) flags |= ETH_FLAG_RXVLAN; |
262 | if (dev->features & NETIF_F_HW_VLAN_TX) flags |= ETH_FLAG_TXVLAN; | ||
263 | if (dev->features & NETIF_F_NTUPLE) flags |= ETH_FLAG_NTUPLE; | ||
264 | if (dev->features & NETIF_F_RXHASH) flags |= ETH_FLAG_RXHASH; | ||
265 | |||
266 | return flags; | ||
542 | } | 267 | } |
543 | 268 | ||
544 | int __ethtool_set_flags(struct net_device *dev, u32 data) | 269 | static int __ethtool_set_flags(struct net_device *dev, u32 data) |
545 | { | 270 | { |
546 | u32 changed; | 271 | netdev_features_t features = 0, changed; |
547 | 272 | ||
548 | if (data & ~flags_dup_features) | 273 | if (data & ~ETH_ALL_FLAGS) |
549 | return -EINVAL; | 274 | return -EINVAL; |
550 | 275 | ||
551 | /* legacy set_flags() op */ | 276 | if (data & ETH_FLAG_LRO) features |= NETIF_F_LRO; |
552 | if (dev->ethtool_ops->set_flags) { | 277 | if (data & ETH_FLAG_RXVLAN) features |= NETIF_F_HW_VLAN_RX; |
553 | if (unlikely(dev->hw_features & flags_dup_features)) | 278 | if (data & ETH_FLAG_TXVLAN) features |= NETIF_F_HW_VLAN_TX; |
554 | netdev_warn(dev, | 279 | if (data & ETH_FLAG_NTUPLE) features |= NETIF_F_NTUPLE; |
555 | "driver BUG: mixed hw_features and set_flags()\n"); | 280 | if (data & ETH_FLAG_RXHASH) features |= NETIF_F_RXHASH; |
556 | return dev->ethtool_ops->set_flags(dev, data); | ||
557 | } | ||
558 | 281 | ||
559 | /* allow changing only bits set in hw_features */ | 282 | /* allow changing only bits set in hw_features */ |
560 | changed = (data ^ dev->features) & flags_dup_features; | 283 | changed = (features ^ dev->features) & ETH_ALL_FEATURES; |
561 | if (changed & ~dev->hw_features) | 284 | if (changed & ~dev->hw_features) |
562 | return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP; | 285 | return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP; |
563 | 286 | ||
564 | dev->wanted_features = | 287 | dev->wanted_features = |
565 | (dev->wanted_features & ~changed) | (data & dev->hw_features); | 288 | (dev->wanted_features & ~changed) | (features & changed); |
566 | 289 | ||
567 | __netdev_update_features(dev); | 290 | __netdev_update_features(dev); |
568 | 291 | ||
@@ -1231,81 +954,6 @@ static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr) | |||
1231 | return dev->ethtool_ops->set_pauseparam(dev, &pauseparam); | 954 | return dev->ethtool_ops->set_pauseparam(dev, &pauseparam); |
1232 | } | 955 | } |
1233 | 956 | ||
1234 | static int __ethtool_set_sg(struct net_device *dev, u32 data) | ||
1235 | { | ||
1236 | int err; | ||
1237 | |||
1238 | if (!dev->ethtool_ops->set_sg) | ||
1239 | return -EOPNOTSUPP; | ||
1240 | |||
1241 | if (data && !(dev->features & NETIF_F_ALL_CSUM)) | ||
1242 | return -EINVAL; | ||
1243 | |||
1244 | if (!data && dev->ethtool_ops->set_tso) { | ||
1245 | err = dev->ethtool_ops->set_tso(dev, 0); | ||
1246 | if (err) | ||
1247 | return err; | ||
1248 | } | ||
1249 | |||
1250 | if (!data && dev->ethtool_ops->set_ufo) { | ||
1251 | err = dev->ethtool_ops->set_ufo(dev, 0); | ||
1252 | if (err) | ||
1253 | return err; | ||
1254 | } | ||
1255 | return dev->ethtool_ops->set_sg(dev, data); | ||
1256 | } | ||
1257 | |||
1258 | static int __ethtool_set_tx_csum(struct net_device *dev, u32 data) | ||
1259 | { | ||
1260 | int err; | ||
1261 | |||
1262 | if (!dev->ethtool_ops->set_tx_csum) | ||
1263 | return -EOPNOTSUPP; | ||
1264 | |||
1265 | if (!data && dev->ethtool_ops->set_sg) { | ||
1266 | err = __ethtool_set_sg(dev, 0); | ||
1267 | if (err) | ||
1268 | return err; | ||
1269 | } | ||
1270 | |||
1271 | return dev->ethtool_ops->set_tx_csum(dev, data); | ||
1272 | } | ||
1273 | |||
1274 | static int __ethtool_set_rx_csum(struct net_device *dev, u32 data) | ||
1275 | { | ||
1276 | if (!dev->ethtool_ops->set_rx_csum) | ||
1277 | return -EOPNOTSUPP; | ||
1278 | |||
1279 | if (!data) | ||
1280 | dev->features &= ~NETIF_F_GRO; | ||
1281 | |||
1282 | return dev->ethtool_ops->set_rx_csum(dev, data); | ||
1283 | } | ||
1284 | |||
1285 | static int __ethtool_set_tso(struct net_device *dev, u32 data) | ||
1286 | { | ||
1287 | if (!dev->ethtool_ops->set_tso) | ||
1288 | return -EOPNOTSUPP; | ||
1289 | |||
1290 | if (data && !(dev->features & NETIF_F_SG)) | ||
1291 | return -EINVAL; | ||
1292 | |||
1293 | return dev->ethtool_ops->set_tso(dev, data); | ||
1294 | } | ||
1295 | |||
1296 | static int __ethtool_set_ufo(struct net_device *dev, u32 data) | ||
1297 | { | ||
1298 | if (!dev->ethtool_ops->set_ufo) | ||
1299 | return -EOPNOTSUPP; | ||
1300 | if (data && !(dev->features & NETIF_F_SG)) | ||
1301 | return -EINVAL; | ||
1302 | if (data && !((dev->features & NETIF_F_GEN_CSUM) || | ||
1303 | (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)) | ||
1304 | == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) | ||
1305 | return -EINVAL; | ||
1306 | return dev->ethtool_ops->set_ufo(dev, data); | ||
1307 | } | ||
1308 | |||
1309 | static int ethtool_self_test(struct net_device *dev, char __user *useraddr) | 957 | static int ethtool_self_test(struct net_device *dev, char __user *useraddr) |
1310 | { | 958 | { |
1311 | struct ethtool_test test; | 959 | struct ethtool_test test; |
@@ -1771,9 +1419,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1771 | break; | 1419 | break; |
1772 | case ETHTOOL_GFLAGS: | 1420 | case ETHTOOL_GFLAGS: |
1773 | rc = ethtool_get_value(dev, useraddr, ethcmd, | 1421 | rc = ethtool_get_value(dev, useraddr, ethcmd, |
1774 | (dev->ethtool_ops->get_flags ? | 1422 | __ethtool_get_flags); |
1775 | dev->ethtool_ops->get_flags : | ||
1776 | ethtool_op_get_flags)); | ||
1777 | break; | 1423 | break; |
1778 | case ETHTOOL_SFLAGS: | 1424 | case ETHTOOL_SFLAGS: |
1779 | rc = ethtool_set_value(dev, useraddr, __ethtool_set_flags); | 1425 | rc = ethtool_set_value(dev, useraddr, __ethtool_set_flags); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 5ac07d31fbc9..27d3fefeaa13 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -238,6 +238,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev) | |||
238 | it to safe state. | 238 | it to safe state. |
239 | */ | 239 | */ |
240 | skb_queue_purge(&n->arp_queue); | 240 | skb_queue_purge(&n->arp_queue); |
241 | n->arp_queue_len_bytes = 0; | ||
241 | n->output = neigh_blackhole; | 242 | n->output = neigh_blackhole; |
242 | if (n->nud_state & NUD_VALID) | 243 | if (n->nud_state & NUD_VALID) |
243 | n->nud_state = NUD_NOARP; | 244 | n->nud_state = NUD_NOARP; |
@@ -702,6 +703,7 @@ void neigh_destroy(struct neighbour *neigh) | |||
702 | printk(KERN_WARNING "Impossible event.\n"); | 703 | printk(KERN_WARNING "Impossible event.\n"); |
703 | 704 | ||
704 | skb_queue_purge(&neigh->arp_queue); | 705 | skb_queue_purge(&neigh->arp_queue); |
706 | neigh->arp_queue_len_bytes = 0; | ||
705 | 707 | ||
706 | dev_put(neigh->dev); | 708 | dev_put(neigh->dev); |
707 | neigh_parms_put(neigh->parms); | 709 | neigh_parms_put(neigh->parms); |
@@ -842,6 +844,7 @@ static void neigh_invalidate(struct neighbour *neigh) | |||
842 | write_lock(&neigh->lock); | 844 | write_lock(&neigh->lock); |
843 | } | 845 | } |
844 | skb_queue_purge(&neigh->arp_queue); | 846 | skb_queue_purge(&neigh->arp_queue); |
847 | neigh->arp_queue_len_bytes = 0; | ||
845 | } | 848 | } |
846 | 849 | ||
847 | static void neigh_probe(struct neighbour *neigh) | 850 | static void neigh_probe(struct neighbour *neigh) |
@@ -980,15 +983,20 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) | |||
980 | 983 | ||
981 | if (neigh->nud_state == NUD_INCOMPLETE) { | 984 | if (neigh->nud_state == NUD_INCOMPLETE) { |
982 | if (skb) { | 985 | if (skb) { |
983 | if (skb_queue_len(&neigh->arp_queue) >= | 986 | while (neigh->arp_queue_len_bytes + skb->truesize > |
984 | neigh->parms->queue_len) { | 987 | neigh->parms->queue_len_bytes) { |
985 | struct sk_buff *buff; | 988 | struct sk_buff *buff; |
989 | |||
986 | buff = __skb_dequeue(&neigh->arp_queue); | 990 | buff = __skb_dequeue(&neigh->arp_queue); |
991 | if (!buff) | ||
992 | break; | ||
993 | neigh->arp_queue_len_bytes -= buff->truesize; | ||
987 | kfree_skb(buff); | 994 | kfree_skb(buff); |
988 | NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards); | 995 | NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards); |
989 | } | 996 | } |
990 | skb_dst_force(skb); | 997 | skb_dst_force(skb); |
991 | __skb_queue_tail(&neigh->arp_queue, skb); | 998 | __skb_queue_tail(&neigh->arp_queue, skb); |
999 | neigh->arp_queue_len_bytes += skb->truesize; | ||
992 | } | 1000 | } |
993 | rc = 1; | 1001 | rc = 1; |
994 | } | 1002 | } |
@@ -1175,6 +1183,7 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, | |||
1175 | write_lock_bh(&neigh->lock); | 1183 | write_lock_bh(&neigh->lock); |
1176 | } | 1184 | } |
1177 | skb_queue_purge(&neigh->arp_queue); | 1185 | skb_queue_purge(&neigh->arp_queue); |
1186 | neigh->arp_queue_len_bytes = 0; | ||
1178 | } | 1187 | } |
1179 | out: | 1188 | out: |
1180 | if (update_isrouter) { | 1189 | if (update_isrouter) { |
@@ -1747,7 +1756,11 @@ static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms) | |||
1747 | NLA_PUT_U32(skb, NDTPA_IFINDEX, parms->dev->ifindex); | 1756 | NLA_PUT_U32(skb, NDTPA_IFINDEX, parms->dev->ifindex); |
1748 | 1757 | ||
1749 | NLA_PUT_U32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt)); | 1758 | NLA_PUT_U32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt)); |
1750 | NLA_PUT_U32(skb, NDTPA_QUEUE_LEN, parms->queue_len); | 1759 | NLA_PUT_U32(skb, NDTPA_QUEUE_LENBYTES, parms->queue_len_bytes); |
1760 | /* approximative value for deprecated QUEUE_LEN (in packets) */ | ||
1761 | NLA_PUT_U32(skb, NDTPA_QUEUE_LEN, | ||
1762 | DIV_ROUND_UP(parms->queue_len_bytes, | ||
1763 | SKB_TRUESIZE(ETH_FRAME_LEN))); | ||
1751 | NLA_PUT_U32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen); | 1764 | NLA_PUT_U32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen); |
1752 | NLA_PUT_U32(skb, NDTPA_APP_PROBES, parms->app_probes); | 1765 | NLA_PUT_U32(skb, NDTPA_APP_PROBES, parms->app_probes); |
1753 | NLA_PUT_U32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes); | 1766 | NLA_PUT_U32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes); |
@@ -1974,7 +1987,11 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
1974 | 1987 | ||
1975 | switch (i) { | 1988 | switch (i) { |
1976 | case NDTPA_QUEUE_LEN: | 1989 | case NDTPA_QUEUE_LEN: |
1977 | p->queue_len = nla_get_u32(tbp[i]); | 1990 | p->queue_len_bytes = nla_get_u32(tbp[i]) * |
1991 | SKB_TRUESIZE(ETH_FRAME_LEN); | ||
1992 | break; | ||
1993 | case NDTPA_QUEUE_LENBYTES: | ||
1994 | p->queue_len_bytes = nla_get_u32(tbp[i]); | ||
1978 | break; | 1995 | break; |
1979 | case NDTPA_PROXY_QLEN: | 1996 | case NDTPA_PROXY_QLEN: |
1980 | p->proxy_qlen = nla_get_u32(tbp[i]); | 1997 | p->proxy_qlen = nla_get_u32(tbp[i]); |
@@ -2638,117 +2655,158 @@ EXPORT_SYMBOL(neigh_app_ns); | |||
2638 | 2655 | ||
2639 | #ifdef CONFIG_SYSCTL | 2656 | #ifdef CONFIG_SYSCTL |
2640 | 2657 | ||
2641 | #define NEIGH_VARS_MAX 19 | 2658 | static int proc_unres_qlen(ctl_table *ctl, int write, void __user *buffer, |
2659 | size_t *lenp, loff_t *ppos) | ||
2660 | { | ||
2661 | int size, ret; | ||
2662 | ctl_table tmp = *ctl; | ||
2663 | |||
2664 | tmp.data = &size; | ||
2665 | size = DIV_ROUND_UP(*(int *)ctl->data, SKB_TRUESIZE(ETH_FRAME_LEN)); | ||
2666 | ret = proc_dointvec(&tmp, write, buffer, lenp, ppos); | ||
2667 | if (write && !ret) | ||
2668 | *(int *)ctl->data = size * SKB_TRUESIZE(ETH_FRAME_LEN); | ||
2669 | return ret; | ||
2670 | } | ||
2671 | |||
2672 | enum { | ||
2673 | NEIGH_VAR_MCAST_PROBE, | ||
2674 | NEIGH_VAR_UCAST_PROBE, | ||
2675 | NEIGH_VAR_APP_PROBE, | ||
2676 | NEIGH_VAR_RETRANS_TIME, | ||
2677 | NEIGH_VAR_BASE_REACHABLE_TIME, | ||
2678 | NEIGH_VAR_DELAY_PROBE_TIME, | ||
2679 | NEIGH_VAR_GC_STALETIME, | ||
2680 | NEIGH_VAR_QUEUE_LEN, | ||
2681 | NEIGH_VAR_QUEUE_LEN_BYTES, | ||
2682 | NEIGH_VAR_PROXY_QLEN, | ||
2683 | NEIGH_VAR_ANYCAST_DELAY, | ||
2684 | NEIGH_VAR_PROXY_DELAY, | ||
2685 | NEIGH_VAR_LOCKTIME, | ||
2686 | NEIGH_VAR_RETRANS_TIME_MS, | ||
2687 | NEIGH_VAR_BASE_REACHABLE_TIME_MS, | ||
2688 | NEIGH_VAR_GC_INTERVAL, | ||
2689 | NEIGH_VAR_GC_THRESH1, | ||
2690 | NEIGH_VAR_GC_THRESH2, | ||
2691 | NEIGH_VAR_GC_THRESH3, | ||
2692 | NEIGH_VAR_MAX | ||
2693 | }; | ||
2642 | 2694 | ||
2643 | static struct neigh_sysctl_table { | 2695 | static struct neigh_sysctl_table { |
2644 | struct ctl_table_header *sysctl_header; | 2696 | struct ctl_table_header *sysctl_header; |
2645 | struct ctl_table neigh_vars[NEIGH_VARS_MAX]; | 2697 | struct ctl_table neigh_vars[NEIGH_VAR_MAX + 1]; |
2646 | char *dev_name; | 2698 | char *dev_name; |
2647 | } neigh_sysctl_template __read_mostly = { | 2699 | } neigh_sysctl_template __read_mostly = { |
2648 | .neigh_vars = { | 2700 | .neigh_vars = { |
2649 | { | 2701 | [NEIGH_VAR_MCAST_PROBE] = { |
2650 | .procname = "mcast_solicit", | 2702 | .procname = "mcast_solicit", |
2651 | .maxlen = sizeof(int), | 2703 | .maxlen = sizeof(int), |
2652 | .mode = 0644, | 2704 | .mode = 0644, |
2653 | .proc_handler = proc_dointvec, | 2705 | .proc_handler = proc_dointvec, |
2654 | }, | 2706 | }, |
2655 | { | 2707 | [NEIGH_VAR_UCAST_PROBE] = { |
2656 | .procname = "ucast_solicit", | 2708 | .procname = "ucast_solicit", |
2657 | .maxlen = sizeof(int), | 2709 | .maxlen = sizeof(int), |
2658 | .mode = 0644, | 2710 | .mode = 0644, |
2659 | .proc_handler = proc_dointvec, | 2711 | .proc_handler = proc_dointvec, |
2660 | }, | 2712 | }, |
2661 | { | 2713 | [NEIGH_VAR_APP_PROBE] = { |
2662 | .procname = "app_solicit", | 2714 | .procname = "app_solicit", |
2663 | .maxlen = sizeof(int), | 2715 | .maxlen = sizeof(int), |
2664 | .mode = 0644, | 2716 | .mode = 0644, |
2665 | .proc_handler = proc_dointvec, | 2717 | .proc_handler = proc_dointvec, |
2666 | }, | 2718 | }, |
2667 | { | 2719 | [NEIGH_VAR_RETRANS_TIME] = { |
2668 | .procname = "retrans_time", | 2720 | .procname = "retrans_time", |
2669 | .maxlen = sizeof(int), | 2721 | .maxlen = sizeof(int), |
2670 | .mode = 0644, | 2722 | .mode = 0644, |
2671 | .proc_handler = proc_dointvec_userhz_jiffies, | 2723 | .proc_handler = proc_dointvec_userhz_jiffies, |
2672 | }, | 2724 | }, |
2673 | { | 2725 | [NEIGH_VAR_BASE_REACHABLE_TIME] = { |
2674 | .procname = "base_reachable_time", | 2726 | .procname = "base_reachable_time", |
2675 | .maxlen = sizeof(int), | 2727 | .maxlen = sizeof(int), |
2676 | .mode = 0644, | 2728 | .mode = 0644, |
2677 | .proc_handler = proc_dointvec_jiffies, | 2729 | .proc_handler = proc_dointvec_jiffies, |
2678 | }, | 2730 | }, |
2679 | { | 2731 | [NEIGH_VAR_DELAY_PROBE_TIME] = { |
2680 | .procname = "delay_first_probe_time", | 2732 | .procname = "delay_first_probe_time", |
2681 | .maxlen = sizeof(int), | 2733 | .maxlen = sizeof(int), |
2682 | .mode = 0644, | 2734 | .mode = 0644, |
2683 | .proc_handler = proc_dointvec_jiffies, | 2735 | .proc_handler = proc_dointvec_jiffies, |
2684 | }, | 2736 | }, |
2685 | { | 2737 | [NEIGH_VAR_GC_STALETIME] = { |
2686 | .procname = "gc_stale_time", | 2738 | .procname = "gc_stale_time", |
2687 | .maxlen = sizeof(int), | 2739 | .maxlen = sizeof(int), |
2688 | .mode = 0644, | 2740 | .mode = 0644, |
2689 | .proc_handler = proc_dointvec_jiffies, | 2741 | .proc_handler = proc_dointvec_jiffies, |
2690 | }, | 2742 | }, |
2691 | { | 2743 | [NEIGH_VAR_QUEUE_LEN] = { |
2692 | .procname = "unres_qlen", | 2744 | .procname = "unres_qlen", |
2693 | .maxlen = sizeof(int), | 2745 | .maxlen = sizeof(int), |
2694 | .mode = 0644, | 2746 | .mode = 0644, |
2747 | .proc_handler = proc_unres_qlen, | ||
2748 | }, | ||
2749 | [NEIGH_VAR_QUEUE_LEN_BYTES] = { | ||
2750 | .procname = "unres_qlen_bytes", | ||
2751 | .maxlen = sizeof(int), | ||
2752 | .mode = 0644, | ||
2695 | .proc_handler = proc_dointvec, | 2753 | .proc_handler = proc_dointvec, |
2696 | }, | 2754 | }, |
2697 | { | 2755 | [NEIGH_VAR_PROXY_QLEN] = { |
2698 | .procname = "proxy_qlen", | 2756 | .procname = "proxy_qlen", |
2699 | .maxlen = sizeof(int), | 2757 | .maxlen = sizeof(int), |
2700 | .mode = 0644, | 2758 | .mode = 0644, |
2701 | .proc_handler = proc_dointvec, | 2759 | .proc_handler = proc_dointvec, |
2702 | }, | 2760 | }, |
2703 | { | 2761 | [NEIGH_VAR_ANYCAST_DELAY] = { |
2704 | .procname = "anycast_delay", | 2762 | .procname = "anycast_delay", |
2705 | .maxlen = sizeof(int), | 2763 | .maxlen = sizeof(int), |
2706 | .mode = 0644, | 2764 | .mode = 0644, |
2707 | .proc_handler = proc_dointvec_userhz_jiffies, | 2765 | .proc_handler = proc_dointvec_userhz_jiffies, |
2708 | }, | 2766 | }, |
2709 | { | 2767 | [NEIGH_VAR_PROXY_DELAY] = { |
2710 | .procname = "proxy_delay", | 2768 | .procname = "proxy_delay", |
2711 | .maxlen = sizeof(int), | 2769 | .maxlen = sizeof(int), |
2712 | .mode = 0644, | 2770 | .mode = 0644, |
2713 | .proc_handler = proc_dointvec_userhz_jiffies, | 2771 | .proc_handler = proc_dointvec_userhz_jiffies, |
2714 | }, | 2772 | }, |
2715 | { | 2773 | [NEIGH_VAR_LOCKTIME] = { |
2716 | .procname = "locktime", | 2774 | .procname = "locktime", |
2717 | .maxlen = sizeof(int), | 2775 | .maxlen = sizeof(int), |
2718 | .mode = 0644, | 2776 | .mode = 0644, |
2719 | .proc_handler = proc_dointvec_userhz_jiffies, | 2777 | .proc_handler = proc_dointvec_userhz_jiffies, |
2720 | }, | 2778 | }, |
2721 | { | 2779 | [NEIGH_VAR_RETRANS_TIME_MS] = { |
2722 | .procname = "retrans_time_ms", | 2780 | .procname = "retrans_time_ms", |
2723 | .maxlen = sizeof(int), | 2781 | .maxlen = sizeof(int), |
2724 | .mode = 0644, | 2782 | .mode = 0644, |
2725 | .proc_handler = proc_dointvec_ms_jiffies, | 2783 | .proc_handler = proc_dointvec_ms_jiffies, |
2726 | }, | 2784 | }, |
2727 | { | 2785 | [NEIGH_VAR_BASE_REACHABLE_TIME_MS] = { |
2728 | .procname = "base_reachable_time_ms", | 2786 | .procname = "base_reachable_time_ms", |
2729 | .maxlen = sizeof(int), | 2787 | .maxlen = sizeof(int), |
2730 | .mode = 0644, | 2788 | .mode = 0644, |
2731 | .proc_handler = proc_dointvec_ms_jiffies, | 2789 | .proc_handler = proc_dointvec_ms_jiffies, |
2732 | }, | 2790 | }, |
2733 | { | 2791 | [NEIGH_VAR_GC_INTERVAL] = { |
2734 | .procname = "gc_interval", | 2792 | .procname = "gc_interval", |
2735 | .maxlen = sizeof(int), | 2793 | .maxlen = sizeof(int), |
2736 | .mode = 0644, | 2794 | .mode = 0644, |
2737 | .proc_handler = proc_dointvec_jiffies, | 2795 | .proc_handler = proc_dointvec_jiffies, |
2738 | }, | 2796 | }, |
2739 | { | 2797 | [NEIGH_VAR_GC_THRESH1] = { |
2740 | .procname = "gc_thresh1", | 2798 | .procname = "gc_thresh1", |
2741 | .maxlen = sizeof(int), | 2799 | .maxlen = sizeof(int), |
2742 | .mode = 0644, | 2800 | .mode = 0644, |
2743 | .proc_handler = proc_dointvec, | 2801 | .proc_handler = proc_dointvec, |
2744 | }, | 2802 | }, |
2745 | { | 2803 | [NEIGH_VAR_GC_THRESH2] = { |
2746 | .procname = "gc_thresh2", | 2804 | .procname = "gc_thresh2", |
2747 | .maxlen = sizeof(int), | 2805 | .maxlen = sizeof(int), |
2748 | .mode = 0644, | 2806 | .mode = 0644, |
2749 | .proc_handler = proc_dointvec, | 2807 | .proc_handler = proc_dointvec, |
2750 | }, | 2808 | }, |
2751 | { | 2809 | [NEIGH_VAR_GC_THRESH3] = { |
2752 | .procname = "gc_thresh3", | 2810 | .procname = "gc_thresh3", |
2753 | .maxlen = sizeof(int), | 2811 | .maxlen = sizeof(int), |
2754 | .mode = 0644, | 2812 | .mode = 0644, |
@@ -2781,47 +2839,49 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, | |||
2781 | if (!t) | 2839 | if (!t) |
2782 | goto err; | 2840 | goto err; |
2783 | 2841 | ||
2784 | t->neigh_vars[0].data = &p->mcast_probes; | 2842 | t->neigh_vars[NEIGH_VAR_MCAST_PROBE].data = &p->mcast_probes; |
2785 | t->neigh_vars[1].data = &p->ucast_probes; | 2843 | t->neigh_vars[NEIGH_VAR_UCAST_PROBE].data = &p->ucast_probes; |
2786 | t->neigh_vars[2].data = &p->app_probes; | 2844 | t->neigh_vars[NEIGH_VAR_APP_PROBE].data = &p->app_probes; |
2787 | t->neigh_vars[3].data = &p->retrans_time; | 2845 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME].data = &p->retrans_time; |
2788 | t->neigh_vars[4].data = &p->base_reachable_time; | 2846 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].data = &p->base_reachable_time; |
2789 | t->neigh_vars[5].data = &p->delay_probe_time; | 2847 | t->neigh_vars[NEIGH_VAR_DELAY_PROBE_TIME].data = &p->delay_probe_time; |
2790 | t->neigh_vars[6].data = &p->gc_staletime; | 2848 | t->neigh_vars[NEIGH_VAR_GC_STALETIME].data = &p->gc_staletime; |
2791 | t->neigh_vars[7].data = &p->queue_len; | 2849 | t->neigh_vars[NEIGH_VAR_QUEUE_LEN].data = &p->queue_len_bytes; |
2792 | t->neigh_vars[8].data = &p->proxy_qlen; | 2850 | t->neigh_vars[NEIGH_VAR_QUEUE_LEN_BYTES].data = &p->queue_len_bytes; |
2793 | t->neigh_vars[9].data = &p->anycast_delay; | 2851 | t->neigh_vars[NEIGH_VAR_PROXY_QLEN].data = &p->proxy_qlen; |
2794 | t->neigh_vars[10].data = &p->proxy_delay; | 2852 | t->neigh_vars[NEIGH_VAR_ANYCAST_DELAY].data = &p->anycast_delay; |
2795 | t->neigh_vars[11].data = &p->locktime; | 2853 | t->neigh_vars[NEIGH_VAR_PROXY_DELAY].data = &p->proxy_delay; |
2796 | t->neigh_vars[12].data = &p->retrans_time; | 2854 | t->neigh_vars[NEIGH_VAR_LOCKTIME].data = &p->locktime; |
2797 | t->neigh_vars[13].data = &p->base_reachable_time; | 2855 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].data = &p->retrans_time; |
2856 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].data = &p->base_reachable_time; | ||
2798 | 2857 | ||
2799 | if (dev) { | 2858 | if (dev) { |
2800 | dev_name_source = dev->name; | 2859 | dev_name_source = dev->name; |
2801 | /* Terminate the table early */ | 2860 | /* Terminate the table early */ |
2802 | memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14])); | 2861 | memset(&t->neigh_vars[NEIGH_VAR_GC_INTERVAL], 0, |
2862 | sizeof(t->neigh_vars[NEIGH_VAR_GC_INTERVAL])); | ||
2803 | } else { | 2863 | } else { |
2804 | dev_name_source = neigh_path[NEIGH_CTL_PATH_DEV].procname; | 2864 | dev_name_source = neigh_path[NEIGH_CTL_PATH_DEV].procname; |
2805 | t->neigh_vars[14].data = (int *)(p + 1); | 2865 | t->neigh_vars[NEIGH_VAR_GC_INTERVAL].data = (int *)(p + 1); |
2806 | t->neigh_vars[15].data = (int *)(p + 1) + 1; | 2866 | t->neigh_vars[NEIGH_VAR_GC_THRESH1].data = (int *)(p + 1) + 1; |
2807 | t->neigh_vars[16].data = (int *)(p + 1) + 2; | 2867 | t->neigh_vars[NEIGH_VAR_GC_THRESH2].data = (int *)(p + 1) + 2; |
2808 | t->neigh_vars[17].data = (int *)(p + 1) + 3; | 2868 | t->neigh_vars[NEIGH_VAR_GC_THRESH3].data = (int *)(p + 1) + 3; |
2809 | } | 2869 | } |
2810 | 2870 | ||
2811 | 2871 | ||
2812 | if (handler) { | 2872 | if (handler) { |
2813 | /* RetransTime */ | 2873 | /* RetransTime */ |
2814 | t->neigh_vars[3].proc_handler = handler; | 2874 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME].proc_handler = handler; |
2815 | t->neigh_vars[3].extra1 = dev; | 2875 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME].extra1 = dev; |
2816 | /* ReachableTime */ | 2876 | /* ReachableTime */ |
2817 | t->neigh_vars[4].proc_handler = handler; | 2877 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].proc_handler = handler; |
2818 | t->neigh_vars[4].extra1 = dev; | 2878 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].extra1 = dev; |
2819 | /* RetransTime (in milliseconds)*/ | 2879 | /* RetransTime (in milliseconds)*/ |
2820 | t->neigh_vars[12].proc_handler = handler; | 2880 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].proc_handler = handler; |
2821 | t->neigh_vars[12].extra1 = dev; | 2881 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].extra1 = dev; |
2822 | /* ReachableTime (in milliseconds) */ | 2882 | /* ReachableTime (in milliseconds) */ |
2823 | t->neigh_vars[13].proc_handler = handler; | 2883 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].proc_handler = handler; |
2824 | t->neigh_vars[13].extra1 = dev; | 2884 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].extra1 = dev; |
2825 | } | 2885 | } |
2826 | 2886 | ||
2827 | t->dev_name = kstrdup(dev_name_source, GFP_KERNEL); | 2887 | t->dev_name = kstrdup(dev_name_source, GFP_KERNEL); |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index c71c434a4c05..db6c2f83633f 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -606,9 +606,12 @@ static ssize_t store_rps_map(struct netdev_rx_queue *queue, | |||
606 | rcu_assign_pointer(queue->rps_map, map); | 606 | rcu_assign_pointer(queue->rps_map, map); |
607 | spin_unlock(&rps_map_lock); | 607 | spin_unlock(&rps_map_lock); |
608 | 608 | ||
609 | if (old_map) | 609 | if (map) |
610 | jump_label_inc(&rps_needed); | ||
611 | if (old_map) { | ||
610 | kfree_rcu(old_map, rcu); | 612 | kfree_rcu(old_map, rcu); |
611 | 613 | jump_label_dec(&rps_needed); | |
614 | } | ||
612 | free_cpumask_var(mask); | 615 | free_cpumask_var(mask); |
613 | return len; | 616 | return len; |
614 | } | 617 | } |
@@ -780,7 +783,7 @@ net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num) | |||
780 | #endif | 783 | #endif |
781 | } | 784 | } |
782 | 785 | ||
783 | #ifdef CONFIG_XPS | 786 | #ifdef CONFIG_SYSFS |
784 | /* | 787 | /* |
785 | * netdev_queue sysfs structures and functions. | 788 | * netdev_queue sysfs structures and functions. |
786 | */ | 789 | */ |
@@ -826,6 +829,23 @@ static const struct sysfs_ops netdev_queue_sysfs_ops = { | |||
826 | .store = netdev_queue_attr_store, | 829 | .store = netdev_queue_attr_store, |
827 | }; | 830 | }; |
828 | 831 | ||
832 | static ssize_t show_trans_timeout(struct netdev_queue *queue, | ||
833 | struct netdev_queue_attribute *attribute, | ||
834 | char *buf) | ||
835 | { | ||
836 | unsigned long trans_timeout; | ||
837 | |||
838 | spin_lock_irq(&queue->_xmit_lock); | ||
839 | trans_timeout = queue->trans_timeout; | ||
840 | spin_unlock_irq(&queue->_xmit_lock); | ||
841 | |||
842 | return sprintf(buf, "%lu", trans_timeout); | ||
843 | } | ||
844 | |||
845 | static struct netdev_queue_attribute queue_trans_timeout = | ||
846 | __ATTR(tx_timeout, S_IRUGO, show_trans_timeout, NULL); | ||
847 | |||
848 | #ifdef CONFIG_XPS | ||
829 | static inline unsigned int get_netdev_queue_index(struct netdev_queue *queue) | 849 | static inline unsigned int get_netdev_queue_index(struct netdev_queue *queue) |
830 | { | 850 | { |
831 | struct net_device *dev = queue->dev; | 851 | struct net_device *dev = queue->dev; |
@@ -901,7 +921,7 @@ static ssize_t store_xps_map(struct netdev_queue *queue, | |||
901 | struct xps_map *map, *new_map; | 921 | struct xps_map *map, *new_map; |
902 | struct xps_dev_maps *dev_maps, *new_dev_maps; | 922 | struct xps_dev_maps *dev_maps, *new_dev_maps; |
903 | int nonempty = 0; | 923 | int nonempty = 0; |
904 | int numa_node = -2; | 924 | int numa_node_id = -2; |
905 | 925 | ||
906 | if (!capable(CAP_NET_ADMIN)) | 926 | if (!capable(CAP_NET_ADMIN)) |
907 | return -EPERM; | 927 | return -EPERM; |
@@ -944,10 +964,10 @@ static ssize_t store_xps_map(struct netdev_queue *queue, | |||
944 | need_set = cpumask_test_cpu(cpu, mask) && cpu_online(cpu); | 964 | need_set = cpumask_test_cpu(cpu, mask) && cpu_online(cpu); |
945 | #ifdef CONFIG_NUMA | 965 | #ifdef CONFIG_NUMA |
946 | if (need_set) { | 966 | if (need_set) { |
947 | if (numa_node == -2) | 967 | if (numa_node_id == -2) |
948 | numa_node = cpu_to_node(cpu); | 968 | numa_node_id = cpu_to_node(cpu); |
949 | else if (numa_node != cpu_to_node(cpu)) | 969 | else if (numa_node_id != cpu_to_node(cpu)) |
950 | numa_node = -1; | 970 | numa_node_id = -1; |
951 | } | 971 | } |
952 | #endif | 972 | #endif |
953 | if (need_set && pos >= map_len) { | 973 | if (need_set && pos >= map_len) { |
@@ -997,7 +1017,7 @@ static ssize_t store_xps_map(struct netdev_queue *queue, | |||
997 | if (dev_maps) | 1017 | if (dev_maps) |
998 | kfree_rcu(dev_maps, rcu); | 1018 | kfree_rcu(dev_maps, rcu); |
999 | 1019 | ||
1000 | netdev_queue_numa_node_write(queue, (numa_node >= 0) ? numa_node : | 1020 | netdev_queue_numa_node_write(queue, (numa_node_id >= 0) ? numa_node_id : |
1001 | NUMA_NO_NODE); | 1021 | NUMA_NO_NODE); |
1002 | 1022 | ||
1003 | mutex_unlock(&xps_map_mutex); | 1023 | mutex_unlock(&xps_map_mutex); |
@@ -1020,12 +1040,17 @@ error: | |||
1020 | 1040 | ||
1021 | static struct netdev_queue_attribute xps_cpus_attribute = | 1041 | static struct netdev_queue_attribute xps_cpus_attribute = |
1022 | __ATTR(xps_cpus, S_IRUGO | S_IWUSR, show_xps_map, store_xps_map); | 1042 | __ATTR(xps_cpus, S_IRUGO | S_IWUSR, show_xps_map, store_xps_map); |
1043 | #endif /* CONFIG_XPS */ | ||
1023 | 1044 | ||
1024 | static struct attribute *netdev_queue_default_attrs[] = { | 1045 | static struct attribute *netdev_queue_default_attrs[] = { |
1046 | &queue_trans_timeout.attr, | ||
1047 | #ifdef CONFIG_XPS | ||
1025 | &xps_cpus_attribute.attr, | 1048 | &xps_cpus_attribute.attr, |
1049 | #endif | ||
1026 | NULL | 1050 | NULL |
1027 | }; | 1051 | }; |
1028 | 1052 | ||
1053 | #ifdef CONFIG_XPS | ||
1029 | static void netdev_queue_release(struct kobject *kobj) | 1054 | static void netdev_queue_release(struct kobject *kobj) |
1030 | { | 1055 | { |
1031 | struct netdev_queue *queue = to_netdev_queue(kobj); | 1056 | struct netdev_queue *queue = to_netdev_queue(kobj); |
@@ -1076,10 +1101,13 @@ static void netdev_queue_release(struct kobject *kobj) | |||
1076 | memset(kobj, 0, sizeof(*kobj)); | 1101 | memset(kobj, 0, sizeof(*kobj)); |
1077 | dev_put(queue->dev); | 1102 | dev_put(queue->dev); |
1078 | } | 1103 | } |
1104 | #endif /* CONFIG_XPS */ | ||
1079 | 1105 | ||
1080 | static struct kobj_type netdev_queue_ktype = { | 1106 | static struct kobj_type netdev_queue_ktype = { |
1081 | .sysfs_ops = &netdev_queue_sysfs_ops, | 1107 | .sysfs_ops = &netdev_queue_sysfs_ops, |
1108 | #ifdef CONFIG_XPS | ||
1082 | .release = netdev_queue_release, | 1109 | .release = netdev_queue_release, |
1110 | #endif | ||
1083 | .default_attrs = netdev_queue_default_attrs, | 1111 | .default_attrs = netdev_queue_default_attrs, |
1084 | }; | 1112 | }; |
1085 | 1113 | ||
@@ -1102,12 +1130,12 @@ static int netdev_queue_add_kobject(struct net_device *net, int index) | |||
1102 | 1130 | ||
1103 | return error; | 1131 | return error; |
1104 | } | 1132 | } |
1105 | #endif /* CONFIG_XPS */ | 1133 | #endif /* CONFIG_SYSFS */ |
1106 | 1134 | ||
1107 | int | 1135 | int |
1108 | netdev_queue_update_kobjects(struct net_device *net, int old_num, int new_num) | 1136 | netdev_queue_update_kobjects(struct net_device *net, int old_num, int new_num) |
1109 | { | 1137 | { |
1110 | #ifdef CONFIG_XPS | 1138 | #ifdef CONFIG_SYSFS |
1111 | int i; | 1139 | int i; |
1112 | int error = 0; | 1140 | int error = 0; |
1113 | 1141 | ||
@@ -1125,14 +1153,14 @@ netdev_queue_update_kobjects(struct net_device *net, int old_num, int new_num) | |||
1125 | return error; | 1153 | return error; |
1126 | #else | 1154 | #else |
1127 | return 0; | 1155 | return 0; |
1128 | #endif | 1156 | #endif /* CONFIG_SYSFS */ |
1129 | } | 1157 | } |
1130 | 1158 | ||
1131 | static int register_queue_kobjects(struct net_device *net) | 1159 | static int register_queue_kobjects(struct net_device *net) |
1132 | { | 1160 | { |
1133 | int error = 0, txq = 0, rxq = 0, real_rx = 0, real_tx = 0; | 1161 | int error = 0, txq = 0, rxq = 0, real_rx = 0, real_tx = 0; |
1134 | 1162 | ||
1135 | #if defined(CONFIG_RPS) || defined(CONFIG_XPS) | 1163 | #ifdef CONFIG_SYSFS |
1136 | net->queues_kset = kset_create_and_add("queues", | 1164 | net->queues_kset = kset_create_and_add("queues", |
1137 | NULL, &net->dev.kobj); | 1165 | NULL, &net->dev.kobj); |
1138 | if (!net->queues_kset) | 1166 | if (!net->queues_kset) |
@@ -1173,7 +1201,7 @@ static void remove_queue_kobjects(struct net_device *net) | |||
1173 | 1201 | ||
1174 | net_rx_queue_update_kobjects(net, real_rx, 0); | 1202 | net_rx_queue_update_kobjects(net, real_rx, 0); |
1175 | netdev_queue_update_kobjects(net, real_tx, 0); | 1203 | netdev_queue_update_kobjects(net, real_tx, 0); |
1176 | #if defined(CONFIG_RPS) || defined(CONFIG_XPS) | 1204 | #ifdef CONFIG_SYSFS |
1177 | kset_unregister(net->queues_kset); | 1205 | kset_unregister(net->queues_kset); |
1178 | #endif | 1206 | #endif |
1179 | } | 1207 | } |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index cf64c1ffa4cd..1a7d8e2c9768 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -422,6 +422,7 @@ static void arp_reply(struct sk_buff *skb) | |||
422 | struct sk_buff *send_skb; | 422 | struct sk_buff *send_skb; |
423 | struct netpoll *np, *tmp; | 423 | struct netpoll *np, *tmp; |
424 | unsigned long flags; | 424 | unsigned long flags; |
425 | int hlen, tlen; | ||
425 | int hits = 0; | 426 | int hits = 0; |
426 | 427 | ||
427 | if (list_empty(&npinfo->rx_np)) | 428 | if (list_empty(&npinfo->rx_np)) |
@@ -479,8 +480,9 @@ static void arp_reply(struct sk_buff *skb) | |||
479 | if (tip != np->local_ip) | 480 | if (tip != np->local_ip) |
480 | continue; | 481 | continue; |
481 | 482 | ||
482 | send_skb = find_skb(np, size + LL_ALLOCATED_SPACE(np->dev), | 483 | hlen = LL_RESERVED_SPACE(np->dev); |
483 | LL_RESERVED_SPACE(np->dev)); | 484 | tlen = np->dev->needed_tailroom; |
485 | send_skb = find_skb(np, size + hlen + tlen, hlen); | ||
484 | if (!send_skb) | 486 | if (!send_skb) |
485 | continue; | 487 | continue; |
486 | 488 | ||
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c new file mode 100644 index 000000000000..3a9fd4826b75 --- /dev/null +++ b/net/core/netprio_cgroup.c | |||
@@ -0,0 +1,344 @@ | |||
1 | /* | ||
2 | * net/core/netprio_cgroup.c Priority Control Group | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * Authors: Neil Horman <nhorman@tuxdriver.com> | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/string.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/skbuff.h> | ||
18 | #include <linux/cgroup.h> | ||
19 | #include <linux/rcupdate.h> | ||
20 | #include <linux/atomic.h> | ||
21 | #include <net/rtnetlink.h> | ||
22 | #include <net/pkt_cls.h> | ||
23 | #include <net/sock.h> | ||
24 | #include <net/netprio_cgroup.h> | ||
25 | |||
26 | static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss, | ||
27 | struct cgroup *cgrp); | ||
28 | static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp); | ||
29 | static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp); | ||
30 | |||
31 | struct cgroup_subsys net_prio_subsys = { | ||
32 | .name = "net_prio", | ||
33 | .create = cgrp_create, | ||
34 | .destroy = cgrp_destroy, | ||
35 | .populate = cgrp_populate, | ||
36 | #ifdef CONFIG_NETPRIO_CGROUP | ||
37 | .subsys_id = net_prio_subsys_id, | ||
38 | #endif | ||
39 | .module = THIS_MODULE | ||
40 | }; | ||
41 | |||
42 | #define PRIOIDX_SZ 128 | ||
43 | |||
44 | static unsigned long prioidx_map[PRIOIDX_SZ]; | ||
45 | static DEFINE_SPINLOCK(prioidx_map_lock); | ||
46 | static atomic_t max_prioidx = ATOMIC_INIT(0); | ||
47 | |||
48 | static inline struct cgroup_netprio_state *cgrp_netprio_state(struct cgroup *cgrp) | ||
49 | { | ||
50 | return container_of(cgroup_subsys_state(cgrp, net_prio_subsys_id), | ||
51 | struct cgroup_netprio_state, css); | ||
52 | } | ||
53 | |||
54 | static int get_prioidx(u32 *prio) | ||
55 | { | ||
56 | unsigned long flags; | ||
57 | u32 prioidx; | ||
58 | |||
59 | spin_lock_irqsave(&prioidx_map_lock, flags); | ||
60 | prioidx = find_first_zero_bit(prioidx_map, sizeof(unsigned long) * PRIOIDX_SZ); | ||
61 | set_bit(prioidx, prioidx_map); | ||
62 | spin_unlock_irqrestore(&prioidx_map_lock, flags); | ||
63 | if (prioidx == sizeof(unsigned long) * PRIOIDX_SZ) | ||
64 | return -ENOSPC; | ||
65 | |||
66 | atomic_set(&max_prioidx, prioidx); | ||
67 | *prio = prioidx; | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static void put_prioidx(u32 idx) | ||
72 | { | ||
73 | unsigned long flags; | ||
74 | |||
75 | spin_lock_irqsave(&prioidx_map_lock, flags); | ||
76 | clear_bit(idx, prioidx_map); | ||
77 | spin_unlock_irqrestore(&prioidx_map_lock, flags); | ||
78 | } | ||
79 | |||
80 | static void extend_netdev_table(struct net_device *dev, u32 new_len) | ||
81 | { | ||
82 | size_t new_size = sizeof(struct netprio_map) + | ||
83 | ((sizeof(u32) * new_len)); | ||
84 | struct netprio_map *new_priomap = kzalloc(new_size, GFP_KERNEL); | ||
85 | struct netprio_map *old_priomap; | ||
86 | int i; | ||
87 | |||
88 | old_priomap = rtnl_dereference(dev->priomap); | ||
89 | |||
90 | if (!new_priomap) { | ||
91 | printk(KERN_WARNING "Unable to alloc new priomap!\n"); | ||
92 | return; | ||
93 | } | ||
94 | |||
95 | for (i = 0; | ||
96 | old_priomap && (i < old_priomap->priomap_len); | ||
97 | i++) | ||
98 | new_priomap->priomap[i] = old_priomap->priomap[i]; | ||
99 | |||
100 | new_priomap->priomap_len = new_len; | ||
101 | |||
102 | rcu_assign_pointer(dev->priomap, new_priomap); | ||
103 | if (old_priomap) | ||
104 | kfree_rcu(old_priomap, rcu); | ||
105 | } | ||
106 | |||
107 | static void update_netdev_tables(void) | ||
108 | { | ||
109 | struct net_device *dev; | ||
110 | u32 max_len = atomic_read(&max_prioidx); | ||
111 | struct netprio_map *map; | ||
112 | |||
113 | rtnl_lock(); | ||
114 | for_each_netdev(&init_net, dev) { | ||
115 | map = rtnl_dereference(dev->priomap); | ||
116 | if ((!map) || | ||
117 | (map->priomap_len < max_len)) | ||
118 | extend_netdev_table(dev, max_len); | ||
119 | } | ||
120 | rtnl_unlock(); | ||
121 | } | ||
122 | |||
123 | static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss, | ||
124 | struct cgroup *cgrp) | ||
125 | { | ||
126 | struct cgroup_netprio_state *cs; | ||
127 | int ret; | ||
128 | |||
129 | cs = kzalloc(sizeof(*cs), GFP_KERNEL); | ||
130 | if (!cs) | ||
131 | return ERR_PTR(-ENOMEM); | ||
132 | |||
133 | if (cgrp->parent && cgrp_netprio_state(cgrp->parent)->prioidx) { | ||
134 | kfree(cs); | ||
135 | return ERR_PTR(-EINVAL); | ||
136 | } | ||
137 | |||
138 | ret = get_prioidx(&cs->prioidx); | ||
139 | if (ret != 0) { | ||
140 | printk(KERN_WARNING "No space in priority index array\n"); | ||
141 | kfree(cs); | ||
142 | return ERR_PTR(ret); | ||
143 | } | ||
144 | |||
145 | return &cs->css; | ||
146 | } | ||
147 | |||
148 | static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp) | ||
149 | { | ||
150 | struct cgroup_netprio_state *cs; | ||
151 | struct net_device *dev; | ||
152 | struct netprio_map *map; | ||
153 | |||
154 | cs = cgrp_netprio_state(cgrp); | ||
155 | rtnl_lock(); | ||
156 | for_each_netdev(&init_net, dev) { | ||
157 | map = rtnl_dereference(dev->priomap); | ||
158 | if (map) | ||
159 | map->priomap[cs->prioidx] = 0; | ||
160 | } | ||
161 | rtnl_unlock(); | ||
162 | put_prioidx(cs->prioidx); | ||
163 | kfree(cs); | ||
164 | } | ||
165 | |||
166 | static u64 read_prioidx(struct cgroup *cgrp, struct cftype *cft) | ||
167 | { | ||
168 | return (u64)cgrp_netprio_state(cgrp)->prioidx; | ||
169 | } | ||
170 | |||
171 | static int read_priomap(struct cgroup *cont, struct cftype *cft, | ||
172 | struct cgroup_map_cb *cb) | ||
173 | { | ||
174 | struct net_device *dev; | ||
175 | u32 prioidx = cgrp_netprio_state(cont)->prioidx; | ||
176 | u32 priority; | ||
177 | struct netprio_map *map; | ||
178 | |||
179 | rcu_read_lock(); | ||
180 | for_each_netdev_rcu(&init_net, dev) { | ||
181 | map = rcu_dereference(dev->priomap); | ||
182 | priority = map ? map->priomap[prioidx] : 0; | ||
183 | cb->fill(cb, dev->name, priority); | ||
184 | } | ||
185 | rcu_read_unlock(); | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int write_priomap(struct cgroup *cgrp, struct cftype *cft, | ||
190 | const char *buffer) | ||
191 | { | ||
192 | char *devname = kstrdup(buffer, GFP_KERNEL); | ||
193 | int ret = -EINVAL; | ||
194 | u32 prioidx = cgrp_netprio_state(cgrp)->prioidx; | ||
195 | unsigned long priority; | ||
196 | char *priostr; | ||
197 | struct net_device *dev; | ||
198 | struct netprio_map *map; | ||
199 | |||
200 | if (!devname) | ||
201 | return -ENOMEM; | ||
202 | |||
203 | /* | ||
204 | * Minimally sized valid priomap string | ||
205 | */ | ||
206 | if (strlen(devname) < 3) | ||
207 | goto out_free_devname; | ||
208 | |||
209 | priostr = strstr(devname, " "); | ||
210 | if (!priostr) | ||
211 | goto out_free_devname; | ||
212 | |||
213 | /* | ||
214 | *Separate the devname from the associated priority | ||
215 | *and advance the priostr poitner to the priority value | ||
216 | */ | ||
217 | *priostr = '\0'; | ||
218 | priostr++; | ||
219 | |||
220 | /* | ||
221 | * If the priostr points to NULL, we're at the end of the passed | ||
222 | * in string, and its not a valid write | ||
223 | */ | ||
224 | if (*priostr == '\0') | ||
225 | goto out_free_devname; | ||
226 | |||
227 | ret = kstrtoul(priostr, 10, &priority); | ||
228 | if (ret < 0) | ||
229 | goto out_free_devname; | ||
230 | |||
231 | ret = -ENODEV; | ||
232 | |||
233 | dev = dev_get_by_name(&init_net, devname); | ||
234 | if (!dev) | ||
235 | goto out_free_devname; | ||
236 | |||
237 | update_netdev_tables(); | ||
238 | ret = 0; | ||
239 | rcu_read_lock(); | ||
240 | map = rcu_dereference(dev->priomap); | ||
241 | if (map) | ||
242 | map->priomap[prioidx] = priority; | ||
243 | rcu_read_unlock(); | ||
244 | dev_put(dev); | ||
245 | |||
246 | out_free_devname: | ||
247 | kfree(devname); | ||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | static struct cftype ss_files[] = { | ||
252 | { | ||
253 | .name = "prioidx", | ||
254 | .read_u64 = read_prioidx, | ||
255 | }, | ||
256 | { | ||
257 | .name = "ifpriomap", | ||
258 | .read_map = read_priomap, | ||
259 | .write_string = write_priomap, | ||
260 | }, | ||
261 | }; | ||
262 | |||
263 | static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp) | ||
264 | { | ||
265 | return cgroup_add_files(cgrp, ss, ss_files, ARRAY_SIZE(ss_files)); | ||
266 | } | ||
267 | |||
268 | static int netprio_device_event(struct notifier_block *unused, | ||
269 | unsigned long event, void *ptr) | ||
270 | { | ||
271 | struct net_device *dev = ptr; | ||
272 | struct netprio_map *old; | ||
273 | u32 max_len = atomic_read(&max_prioidx); | ||
274 | |||
275 | /* | ||
276 | * Note this is called with rtnl_lock held so we have update side | ||
277 | * protection on our rcu assignments | ||
278 | */ | ||
279 | |||
280 | switch (event) { | ||
281 | |||
282 | case NETDEV_REGISTER: | ||
283 | if (max_len) | ||
284 | extend_netdev_table(dev, max_len); | ||
285 | break; | ||
286 | case NETDEV_UNREGISTER: | ||
287 | old = rtnl_dereference(dev->priomap); | ||
288 | RCU_INIT_POINTER(dev->priomap, NULL); | ||
289 | if (old) | ||
290 | kfree_rcu(old, rcu); | ||
291 | break; | ||
292 | } | ||
293 | return NOTIFY_DONE; | ||
294 | } | ||
295 | |||
296 | static struct notifier_block netprio_device_notifier = { | ||
297 | .notifier_call = netprio_device_event | ||
298 | }; | ||
299 | |||
300 | static int __init init_cgroup_netprio(void) | ||
301 | { | ||
302 | int ret; | ||
303 | |||
304 | ret = cgroup_load_subsys(&net_prio_subsys); | ||
305 | if (ret) | ||
306 | goto out; | ||
307 | #ifndef CONFIG_NETPRIO_CGROUP | ||
308 | smp_wmb(); | ||
309 | net_prio_subsys_id = net_prio_subsys.subsys_id; | ||
310 | #endif | ||
311 | |||
312 | register_netdevice_notifier(&netprio_device_notifier); | ||
313 | |||
314 | out: | ||
315 | return ret; | ||
316 | } | ||
317 | |||
318 | static void __exit exit_cgroup_netprio(void) | ||
319 | { | ||
320 | struct netprio_map *old; | ||
321 | struct net_device *dev; | ||
322 | |||
323 | unregister_netdevice_notifier(&netprio_device_notifier); | ||
324 | |||
325 | cgroup_unload_subsys(&net_prio_subsys); | ||
326 | |||
327 | #ifndef CONFIG_NETPRIO_CGROUP | ||
328 | net_prio_subsys_id = -1; | ||
329 | synchronize_rcu(); | ||
330 | #endif | ||
331 | |||
332 | rtnl_lock(); | ||
333 | for_each_netdev(&init_net, dev) { | ||
334 | old = rtnl_dereference(dev->priomap); | ||
335 | RCU_INIT_POINTER(dev->priomap, NULL); | ||
336 | if (old) | ||
337 | kfree_rcu(old, rcu); | ||
338 | } | ||
339 | rtnl_unlock(); | ||
340 | } | ||
341 | |||
342 | module_init(init_cgroup_netprio); | ||
343 | module_exit(exit_cgroup_netprio); | ||
344 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 0001c243b35c..aa53a35a631b 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -1304,7 +1304,7 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1304 | scan_ip6(buf, pkt_dev->in6_daddr.s6_addr); | 1304 | scan_ip6(buf, pkt_dev->in6_daddr.s6_addr); |
1305 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_daddr); | 1305 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_daddr); |
1306 | 1306 | ||
1307 | ipv6_addr_copy(&pkt_dev->cur_in6_daddr, &pkt_dev->in6_daddr); | 1307 | pkt_dev->cur_in6_daddr = pkt_dev->in6_daddr; |
1308 | 1308 | ||
1309 | if (debug) | 1309 | if (debug) |
1310 | printk(KERN_DEBUG "pktgen: dst6 set to: %s\n", buf); | 1310 | printk(KERN_DEBUG "pktgen: dst6 set to: %s\n", buf); |
@@ -1327,8 +1327,7 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1327 | scan_ip6(buf, pkt_dev->min_in6_daddr.s6_addr); | 1327 | scan_ip6(buf, pkt_dev->min_in6_daddr.s6_addr); |
1328 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->min_in6_daddr); | 1328 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->min_in6_daddr); |
1329 | 1329 | ||
1330 | ipv6_addr_copy(&pkt_dev->cur_in6_daddr, | 1330 | pkt_dev->cur_in6_daddr = pkt_dev->min_in6_daddr; |
1331 | &pkt_dev->min_in6_daddr); | ||
1332 | if (debug) | 1331 | if (debug) |
1333 | printk(KERN_DEBUG "pktgen: dst6_min set to: %s\n", buf); | 1332 | printk(KERN_DEBUG "pktgen: dst6_min set to: %s\n", buf); |
1334 | 1333 | ||
@@ -1371,7 +1370,7 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1371 | scan_ip6(buf, pkt_dev->in6_saddr.s6_addr); | 1370 | scan_ip6(buf, pkt_dev->in6_saddr.s6_addr); |
1372 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_saddr); | 1371 | snprintf(buf, sizeof(buf), "%pI6c", &pkt_dev->in6_saddr); |
1373 | 1372 | ||
1374 | ipv6_addr_copy(&pkt_dev->cur_in6_saddr, &pkt_dev->in6_saddr); | 1373 | pkt_dev->cur_in6_saddr = pkt_dev->in6_saddr; |
1375 | 1374 | ||
1376 | if (debug) | 1375 | if (debug) |
1377 | printk(KERN_DEBUG "pktgen: src6 set to: %s\n", buf); | 1376 | printk(KERN_DEBUG "pktgen: src6 set to: %s\n", buf); |
@@ -2079,9 +2078,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
2079 | ifp = ifp->if_next) { | 2078 | ifp = ifp->if_next) { |
2080 | if (ifp->scope == IFA_LINK && | 2079 | if (ifp->scope == IFA_LINK && |
2081 | !(ifp->flags & IFA_F_TENTATIVE)) { | 2080 | !(ifp->flags & IFA_F_TENTATIVE)) { |
2082 | ipv6_addr_copy(&pkt_dev-> | 2081 | pkt_dev->cur_in6_saddr = ifp->addr; |
2083 | cur_in6_saddr, | ||
2084 | &ifp->addr); | ||
2085 | err = 0; | 2082 | err = 0; |
2086 | break; | 2083 | break; |
2087 | } | 2084 | } |
@@ -2958,8 +2955,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | |||
2958 | iph->payload_len = htons(sizeof(struct udphdr) + datalen); | 2955 | iph->payload_len = htons(sizeof(struct udphdr) + datalen); |
2959 | iph->nexthdr = IPPROTO_UDP; | 2956 | iph->nexthdr = IPPROTO_UDP; |
2960 | 2957 | ||
2961 | ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr); | 2958 | iph->daddr = pkt_dev->cur_in6_daddr; |
2962 | ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr); | 2959 | iph->saddr = pkt_dev->cur_in6_saddr; |
2963 | 2960 | ||
2964 | skb->mac_header = (skb->network_header - ETH_HLEN - | 2961 | skb->mac_header = (skb->network_header - ETH_HLEN - |
2965 | pkt_dev->pkt_overhead); | 2962 | pkt_dev->pkt_overhead); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 3c30ee4a5710..678ae4e783aa 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -245,6 +245,55 @@ nodata: | |||
245 | EXPORT_SYMBOL(__alloc_skb); | 245 | EXPORT_SYMBOL(__alloc_skb); |
246 | 246 | ||
247 | /** | 247 | /** |
248 | * build_skb - build a network buffer | ||
249 | * @data: data buffer provided by caller | ||
250 | * | ||
251 | * Allocate a new &sk_buff. Caller provides space holding head and | ||
252 | * skb_shared_info. @data must have been allocated by kmalloc() | ||
253 | * The return is the new skb buffer. | ||
254 | * On a failure the return is %NULL, and @data is not freed. | ||
255 | * Notes : | ||
256 | * Before IO, driver allocates only data buffer where NIC put incoming frame | ||
257 | * Driver should add room at head (NET_SKB_PAD) and | ||
258 | * MUST add room at tail (SKB_DATA_ALIGN(skb_shared_info)) | ||
259 | * After IO, driver calls build_skb(), to allocate sk_buff and populate it | ||
260 | * before giving packet to stack. | ||
261 | * RX rings only contains data buffers, not full skbs. | ||
262 | */ | ||
263 | struct sk_buff *build_skb(void *data) | ||
264 | { | ||
265 | struct skb_shared_info *shinfo; | ||
266 | struct sk_buff *skb; | ||
267 | unsigned int size; | ||
268 | |||
269 | skb = kmem_cache_alloc(skbuff_head_cache, GFP_ATOMIC); | ||
270 | if (!skb) | ||
271 | return NULL; | ||
272 | |||
273 | size = ksize(data) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); | ||
274 | |||
275 | memset(skb, 0, offsetof(struct sk_buff, tail)); | ||
276 | skb->truesize = SKB_TRUESIZE(size); | ||
277 | atomic_set(&skb->users, 1); | ||
278 | skb->head = data; | ||
279 | skb->data = data; | ||
280 | skb_reset_tail_pointer(skb); | ||
281 | skb->end = skb->tail + size; | ||
282 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | ||
283 | skb->mac_header = ~0U; | ||
284 | #endif | ||
285 | |||
286 | /* make sure we initialize shinfo sequentially */ | ||
287 | shinfo = skb_shinfo(skb); | ||
288 | memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); | ||
289 | atomic_set(&shinfo->dataref, 1); | ||
290 | kmemcheck_annotate_variable(shinfo->destructor_arg); | ||
291 | |||
292 | return skb; | ||
293 | } | ||
294 | EXPORT_SYMBOL(build_skb); | ||
295 | |||
296 | /** | ||
248 | * __netdev_alloc_skb - allocate an skbuff for rx on a specific device | 297 | * __netdev_alloc_skb - allocate an skbuff for rx on a specific device |
249 | * @dev: network device to receive on | 298 | * @dev: network device to receive on |
250 | * @length: length to allocate | 299 | * @length: length to allocate |
@@ -2621,7 +2670,7 @@ EXPORT_SYMBOL_GPL(skb_pull_rcsum); | |||
2621 | * a pointer to the first in a list of new skbs for the segments. | 2670 | * a pointer to the first in a list of new skbs for the segments. |
2622 | * In case of error it returns ERR_PTR(err). | 2671 | * In case of error it returns ERR_PTR(err). |
2623 | */ | 2672 | */ |
2624 | struct sk_buff *skb_segment(struct sk_buff *skb, u32 features) | 2673 | struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) |
2625 | { | 2674 | { |
2626 | struct sk_buff *segs = NULL; | 2675 | struct sk_buff *segs = NULL; |
2627 | struct sk_buff *tail = NULL; | 2676 | struct sk_buff *tail = NULL; |
@@ -3169,6 +3218,26 @@ void skb_tstamp_tx(struct sk_buff *orig_skb, | |||
3169 | } | 3218 | } |
3170 | EXPORT_SYMBOL_GPL(skb_tstamp_tx); | 3219 | EXPORT_SYMBOL_GPL(skb_tstamp_tx); |
3171 | 3220 | ||
3221 | void skb_complete_wifi_ack(struct sk_buff *skb, bool acked) | ||
3222 | { | ||
3223 | struct sock *sk = skb->sk; | ||
3224 | struct sock_exterr_skb *serr; | ||
3225 | int err; | ||
3226 | |||
3227 | skb->wifi_acked_valid = 1; | ||
3228 | skb->wifi_acked = acked; | ||
3229 | |||
3230 | serr = SKB_EXT_ERR(skb); | ||
3231 | memset(serr, 0, sizeof(*serr)); | ||
3232 | serr->ee.ee_errno = ENOMSG; | ||
3233 | serr->ee.ee_origin = SO_EE_ORIGIN_TXSTATUS; | ||
3234 | |||
3235 | err = sock_queue_err_skb(sk, skb); | ||
3236 | if (err) | ||
3237 | kfree_skb(skb); | ||
3238 | } | ||
3239 | EXPORT_SYMBOL_GPL(skb_complete_wifi_ack); | ||
3240 | |||
3172 | 3241 | ||
3173 | /** | 3242 | /** |
3174 | * skb_partial_csum_set - set up and verify partial csum values for packet | 3243 | * skb_partial_csum_set - set up and verify partial csum values for packet |
diff --git a/net/core/sock.c b/net/core/sock.c index 4ed7b1d12f5e..16069139797c 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -125,6 +125,7 @@ | |||
125 | #include <net/xfrm.h> | 125 | #include <net/xfrm.h> |
126 | #include <linux/ipsec.h> | 126 | #include <linux/ipsec.h> |
127 | #include <net/cls_cgroup.h> | 127 | #include <net/cls_cgroup.h> |
128 | #include <net/netprio_cgroup.h> | ||
128 | 129 | ||
129 | #include <linux/filter.h> | 130 | #include <linux/filter.h> |
130 | 131 | ||
@@ -221,10 +222,16 @@ __u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX; | |||
221 | int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512); | 222 | int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512); |
222 | EXPORT_SYMBOL(sysctl_optmem_max); | 223 | EXPORT_SYMBOL(sysctl_optmem_max); |
223 | 224 | ||
224 | #if defined(CONFIG_CGROUPS) && !defined(CONFIG_NET_CLS_CGROUP) | 225 | #if defined(CONFIG_CGROUPS) |
226 | #if !defined(CONFIG_NET_CLS_CGROUP) | ||
225 | int net_cls_subsys_id = -1; | 227 | int net_cls_subsys_id = -1; |
226 | EXPORT_SYMBOL_GPL(net_cls_subsys_id); | 228 | EXPORT_SYMBOL_GPL(net_cls_subsys_id); |
227 | #endif | 229 | #endif |
230 | #if !defined(CONFIG_NETPRIO_CGROUP) | ||
231 | int net_prio_subsys_id = -1; | ||
232 | EXPORT_SYMBOL_GPL(net_prio_subsys_id); | ||
233 | #endif | ||
234 | #endif | ||
228 | 235 | ||
229 | static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) | 236 | static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) |
230 | { | 237 | { |
@@ -740,6 +747,11 @@ set_rcvbuf: | |||
740 | case SO_RXQ_OVFL: | 747 | case SO_RXQ_OVFL: |
741 | sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool); | 748 | sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool); |
742 | break; | 749 | break; |
750 | |||
751 | case SO_WIFI_STATUS: | ||
752 | sock_valbool_flag(sk, SOCK_WIFI_STATUS, valbool); | ||
753 | break; | ||
754 | |||
743 | default: | 755 | default: |
744 | ret = -ENOPROTOOPT; | 756 | ret = -ENOPROTOOPT; |
745 | break; | 757 | break; |
@@ -961,6 +973,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
961 | v.val = !!sock_flag(sk, SOCK_RXQ_OVFL); | 973 | v.val = !!sock_flag(sk, SOCK_RXQ_OVFL); |
962 | break; | 974 | break; |
963 | 975 | ||
976 | case SO_WIFI_STATUS: | ||
977 | v.val = !!sock_flag(sk, SOCK_WIFI_STATUS); | ||
978 | break; | ||
979 | |||
964 | default: | 980 | default: |
965 | return -ENOPROTOOPT; | 981 | return -ENOPROTOOPT; |
966 | } | 982 | } |
@@ -1111,6 +1127,18 @@ void sock_update_classid(struct sock *sk) | |||
1111 | sk->sk_classid = classid; | 1127 | sk->sk_classid = classid; |
1112 | } | 1128 | } |
1113 | EXPORT_SYMBOL(sock_update_classid); | 1129 | EXPORT_SYMBOL(sock_update_classid); |
1130 | |||
1131 | void sock_update_netprioidx(struct sock *sk) | ||
1132 | { | ||
1133 | struct cgroup_netprio_state *state; | ||
1134 | if (in_interrupt()) | ||
1135 | return; | ||
1136 | rcu_read_lock(); | ||
1137 | state = task_netprio_state(current); | ||
1138 | sk->sk_cgrp_prioidx = state ? state->prioidx : 0; | ||
1139 | rcu_read_unlock(); | ||
1140 | } | ||
1141 | EXPORT_SYMBOL_GPL(sock_update_netprioidx); | ||
1114 | #endif | 1142 | #endif |
1115 | 1143 | ||
1116 | /** | 1144 | /** |
@@ -1138,6 +1166,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, | |||
1138 | atomic_set(&sk->sk_wmem_alloc, 1); | 1166 | atomic_set(&sk->sk_wmem_alloc, 1); |
1139 | 1167 | ||
1140 | sock_update_classid(sk); | 1168 | sock_update_classid(sk); |
1169 | sock_update_netprioidx(sk); | ||
1141 | } | 1170 | } |
1142 | 1171 | ||
1143 | return sk; | 1172 | return sk; |
@@ -1204,7 +1233,14 @@ void sk_release_kernel(struct sock *sk) | |||
1204 | } | 1233 | } |
1205 | EXPORT_SYMBOL(sk_release_kernel); | 1234 | EXPORT_SYMBOL(sk_release_kernel); |
1206 | 1235 | ||
1207 | struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | 1236 | /** |
1237 | * sk_clone_lock - clone a socket, and lock its clone | ||
1238 | * @sk: the socket to clone | ||
1239 | * @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc) | ||
1240 | * | ||
1241 | * Caller must unlock socket even in error path (bh_unlock_sock(newsk)) | ||
1242 | */ | ||
1243 | struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) | ||
1208 | { | 1244 | { |
1209 | struct sock *newsk; | 1245 | struct sock *newsk; |
1210 | 1246 | ||
@@ -1297,7 +1333,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | |||
1297 | out: | 1333 | out: |
1298 | return newsk; | 1334 | return newsk; |
1299 | } | 1335 | } |
1300 | EXPORT_SYMBOL_GPL(sk_clone); | 1336 | EXPORT_SYMBOL_GPL(sk_clone_lock); |
1301 | 1337 | ||
1302 | void sk_setup_caps(struct sock *sk, struct dst_entry *dst) | 1338 | void sk_setup_caps(struct sock *sk, struct dst_entry *dst) |
1303 | { | 1339 | { |
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index 77a65f031488..d05559d4d9cd 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c | |||
@@ -68,8 +68,13 @@ static int rps_sock_flow_sysctl(ctl_table *table, int write, | |||
68 | 68 | ||
69 | if (sock_table != orig_sock_table) { | 69 | if (sock_table != orig_sock_table) { |
70 | rcu_assign_pointer(rps_sock_flow_table, sock_table); | 70 | rcu_assign_pointer(rps_sock_flow_table, sock_table); |
71 | synchronize_rcu(); | 71 | if (sock_table) |
72 | vfree(orig_sock_table); | 72 | jump_label_inc(&rps_needed); |
73 | if (orig_sock_table) { | ||
74 | jump_label_dec(&rps_needed); | ||
75 | synchronize_rcu(); | ||
76 | vfree(orig_sock_table); | ||
77 | } | ||
73 | } | 78 | } |
74 | } | 79 | } |
75 | 80 | ||
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 17ee85ce148d..ce903f747e64 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -150,8 +150,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
150 | */ | 150 | */ |
151 | memset(&fl6, 0, sizeof(fl6)); | 151 | memset(&fl6, 0, sizeof(fl6)); |
152 | fl6.flowi6_proto = IPPROTO_DCCP; | 152 | fl6.flowi6_proto = IPPROTO_DCCP; |
153 | ipv6_addr_copy(&fl6.daddr, &np->daddr); | 153 | fl6.daddr = np->daddr; |
154 | ipv6_addr_copy(&fl6.saddr, &np->saddr); | 154 | fl6.saddr = np->saddr; |
155 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 155 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
156 | fl6.fl6_dport = inet->inet_dport; | 156 | fl6.fl6_dport = inet->inet_dport; |
157 | fl6.fl6_sport = inet->inet_sport; | 157 | fl6.fl6_sport = inet->inet_sport; |
@@ -244,8 +244,8 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, | |||
244 | 244 | ||
245 | memset(&fl6, 0, sizeof(fl6)); | 245 | memset(&fl6, 0, sizeof(fl6)); |
246 | fl6.flowi6_proto = IPPROTO_DCCP; | 246 | fl6.flowi6_proto = IPPROTO_DCCP; |
247 | ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr); | 247 | fl6.daddr = ireq6->rmt_addr; |
248 | ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr); | 248 | fl6.saddr = ireq6->loc_addr; |
249 | fl6.flowlabel = 0; | 249 | fl6.flowlabel = 0; |
250 | fl6.flowi6_oif = ireq6->iif; | 250 | fl6.flowi6_oif = ireq6->iif; |
251 | fl6.fl6_dport = inet_rsk(req)->rmt_port; | 251 | fl6.fl6_dport = inet_rsk(req)->rmt_port; |
@@ -270,7 +270,7 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, | |||
270 | dh->dccph_checksum = dccp_v6_csum_finish(skb, | 270 | dh->dccph_checksum = dccp_v6_csum_finish(skb, |
271 | &ireq6->loc_addr, | 271 | &ireq6->loc_addr, |
272 | &ireq6->rmt_addr); | 272 | &ireq6->rmt_addr); |
273 | ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr); | 273 | fl6.daddr = ireq6->rmt_addr; |
274 | err = ip6_xmit(sk, skb, &fl6, opt, np->tclass); | 274 | err = ip6_xmit(sk, skb, &fl6, opt, np->tclass); |
275 | err = net_xmit_eval(err); | 275 | err = net_xmit_eval(err); |
276 | } | 276 | } |
@@ -313,8 +313,8 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) | |||
313 | &rxip6h->daddr); | 313 | &rxip6h->daddr); |
314 | 314 | ||
315 | memset(&fl6, 0, sizeof(fl6)); | 315 | memset(&fl6, 0, sizeof(fl6)); |
316 | ipv6_addr_copy(&fl6.daddr, &rxip6h->saddr); | 316 | fl6.daddr = rxip6h->saddr; |
317 | ipv6_addr_copy(&fl6.saddr, &rxip6h->daddr); | 317 | fl6.saddr = rxip6h->daddr; |
318 | 318 | ||
319 | fl6.flowi6_proto = IPPROTO_DCCP; | 319 | fl6.flowi6_proto = IPPROTO_DCCP; |
320 | fl6.flowi6_oif = inet6_iif(rxskb); | 320 | fl6.flowi6_oif = inet6_iif(rxskb); |
@@ -419,8 +419,8 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
419 | goto drop_and_free; | 419 | goto drop_and_free; |
420 | 420 | ||
421 | ireq6 = inet6_rsk(req); | 421 | ireq6 = inet6_rsk(req); |
422 | ipv6_addr_copy(&ireq6->rmt_addr, &ipv6_hdr(skb)->saddr); | 422 | ireq6->rmt_addr = ipv6_hdr(skb)->saddr; |
423 | ipv6_addr_copy(&ireq6->loc_addr, &ipv6_hdr(skb)->daddr); | 423 | ireq6->loc_addr = ipv6_hdr(skb)->daddr; |
424 | 424 | ||
425 | if (ipv6_opt_accepted(sk, skb) || | 425 | if (ipv6_opt_accepted(sk, skb) || |
426 | np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || | 426 | np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || |
@@ -491,7 +491,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
491 | 491 | ||
492 | ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr); | 492 | ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr); |
493 | 493 | ||
494 | ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr); | 494 | newnp->rcv_saddr = newnp->saddr; |
495 | 495 | ||
496 | inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped; | 496 | inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped; |
497 | newsk->sk_backlog_rcv = dccp_v4_do_rcv; | 497 | newsk->sk_backlog_rcv = dccp_v4_do_rcv; |
@@ -526,9 +526,9 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
526 | 526 | ||
527 | memset(&fl6, 0, sizeof(fl6)); | 527 | memset(&fl6, 0, sizeof(fl6)); |
528 | fl6.flowi6_proto = IPPROTO_DCCP; | 528 | fl6.flowi6_proto = IPPROTO_DCCP; |
529 | ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr); | 529 | fl6.daddr = ireq6->rmt_addr; |
530 | final_p = fl6_update_dst(&fl6, opt, &final); | 530 | final_p = fl6_update_dst(&fl6, opt, &final); |
531 | ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr); | 531 | fl6.saddr = ireq6->loc_addr; |
532 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 532 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
533 | fl6.fl6_dport = inet_rsk(req)->rmt_port; | 533 | fl6.fl6_dport = inet_rsk(req)->rmt_port; |
534 | fl6.fl6_sport = inet_rsk(req)->loc_port; | 534 | fl6.fl6_sport = inet_rsk(req)->loc_port; |
@@ -559,9 +559,9 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
559 | 559 | ||
560 | memcpy(newnp, np, sizeof(struct ipv6_pinfo)); | 560 | memcpy(newnp, np, sizeof(struct ipv6_pinfo)); |
561 | 561 | ||
562 | ipv6_addr_copy(&newnp->daddr, &ireq6->rmt_addr); | 562 | newnp->daddr = ireq6->rmt_addr; |
563 | ipv6_addr_copy(&newnp->saddr, &ireq6->loc_addr); | 563 | newnp->saddr = ireq6->loc_addr; |
564 | ipv6_addr_copy(&newnp->rcv_saddr, &ireq6->loc_addr); | 564 | newnp->rcv_saddr = ireq6->loc_addr; |
565 | newsk->sk_bound_dev_if = ireq6->iif; | 565 | newsk->sk_bound_dev_if = ireq6->iif; |
566 | 566 | ||
567 | /* Now IPv6 options... | 567 | /* Now IPv6 options... |
@@ -877,7 +877,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
877 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 877 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
878 | if (flowlabel == NULL) | 878 | if (flowlabel == NULL) |
879 | return -EINVAL; | 879 | return -EINVAL; |
880 | ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst); | 880 | usin->sin6_addr = flowlabel->dst; |
881 | fl6_sock_release(flowlabel); | 881 | fl6_sock_release(flowlabel); |
882 | } | 882 | } |
883 | } | 883 | } |
@@ -910,7 +910,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
910 | return -EINVAL; | 910 | return -EINVAL; |
911 | } | 911 | } |
912 | 912 | ||
913 | ipv6_addr_copy(&np->daddr, &usin->sin6_addr); | 913 | np->daddr = usin->sin6_addr; |
914 | np->flow_label = fl6.flowlabel; | 914 | np->flow_label = fl6.flowlabel; |
915 | 915 | ||
916 | /* | 916 | /* |
@@ -949,8 +949,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
949 | saddr = &np->rcv_saddr; | 949 | saddr = &np->rcv_saddr; |
950 | 950 | ||
951 | fl6.flowi6_proto = IPPROTO_DCCP; | 951 | fl6.flowi6_proto = IPPROTO_DCCP; |
952 | ipv6_addr_copy(&fl6.daddr, &np->daddr); | 952 | fl6.daddr = np->daddr; |
953 | ipv6_addr_copy(&fl6.saddr, saddr ? saddr : &np->saddr); | 953 | fl6.saddr = saddr ? *saddr : np->saddr; |
954 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 954 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
955 | fl6.fl6_dport = usin->sin6_port; | 955 | fl6.fl6_dport = usin->sin6_port; |
956 | fl6.fl6_sport = inet->inet_sport; | 956 | fl6.fl6_sport = inet->inet_sport; |
@@ -966,11 +966,11 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
966 | 966 | ||
967 | if (saddr == NULL) { | 967 | if (saddr == NULL) { |
968 | saddr = &fl6.saddr; | 968 | saddr = &fl6.saddr; |
969 | ipv6_addr_copy(&np->rcv_saddr, saddr); | 969 | np->rcv_saddr = *saddr; |
970 | } | 970 | } |
971 | 971 | ||
972 | /* set the source address */ | 972 | /* set the source address */ |
973 | ipv6_addr_copy(&np->saddr, saddr); | 973 | np->saddr = *saddr; |
974 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; | 974 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; |
975 | 975 | ||
976 | __ip6_dst_store(sk, dst, NULL, NULL); | 976 | __ip6_dst_store(sk, dst, NULL, NULL); |
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index d7041a0963af..b50d5fd3d696 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c | |||
@@ -60,8 +60,8 @@ void dccp_time_wait(struct sock *sk, int state, int timeo) | |||
60 | 60 | ||
61 | tw->tw_ipv6_offset = inet6_tw_offset(sk->sk_prot); | 61 | tw->tw_ipv6_offset = inet6_tw_offset(sk->sk_prot); |
62 | tw6 = inet6_twsk((struct sock *)tw); | 62 | tw6 = inet6_twsk((struct sock *)tw); |
63 | ipv6_addr_copy(&tw6->tw_v6_daddr, &np->daddr); | 63 | tw6->tw_v6_daddr = np->daddr; |
64 | ipv6_addr_copy(&tw6->tw_v6_rcv_saddr, &np->rcv_saddr); | 64 | tw6->tw_v6_rcv_saddr = np->rcv_saddr; |
65 | tw->tw_ipv6only = np->ipv6only; | 65 | tw->tw_ipv6only = np->ipv6only; |
66 | } | 66 | } |
67 | #endif | 67 | #endif |
@@ -100,7 +100,7 @@ struct sock *dccp_create_openreq_child(struct sock *sk, | |||
100 | * (* Generate a new socket and switch to that socket *) | 100 | * (* Generate a new socket and switch to that socket *) |
101 | * Set S := new socket for this port pair | 101 | * Set S := new socket for this port pair |
102 | */ | 102 | */ |
103 | struct sock *newsk = inet_csk_clone(sk, req, GFP_ATOMIC); | 103 | struct sock *newsk = inet_csk_clone_lock(sk, req, GFP_ATOMIC); |
104 | 104 | ||
105 | if (newsk != NULL) { | 105 | if (newsk != NULL) { |
106 | struct dccp_request_sock *dreq = dccp_rsk(req); | 106 | struct dccp_request_sock *dreq = dccp_rsk(req); |
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 7f0eb087dc11..3532ac64c82d 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c | |||
@@ -107,7 +107,7 @@ struct neigh_table dn_neigh_table = { | |||
107 | .gc_staletime = 60 * HZ, | 107 | .gc_staletime = 60 * HZ, |
108 | .reachable_time = 30 * HZ, | 108 | .reachable_time = 30 * HZ, |
109 | .delay_probe_time = 5 * HZ, | 109 | .delay_probe_time = 5 * HZ, |
110 | .queue_len = 3, | 110 | .queue_len_bytes = 64*1024, |
111 | .ucast_probes = 0, | 111 | .ucast_probes = 0, |
112 | .app_probes = 0, | 112 | .app_probes = 0, |
113 | .mcast_probes = 0, | 113 | .mcast_probes = 0, |
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 1c1f26c5d672..7e717cb35ad1 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c | |||
@@ -322,6 +322,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
322 | /* Real hardware Econet. We're not worthy etc. */ | 322 | /* Real hardware Econet. We're not worthy etc. */ |
323 | #ifdef CONFIG_ECONET_NATIVE | 323 | #ifdef CONFIG_ECONET_NATIVE |
324 | unsigned short proto = 0; | 324 | unsigned short proto = 0; |
325 | int hlen, tlen; | ||
325 | int res; | 326 | int res; |
326 | 327 | ||
327 | if (len + 15 > dev->mtu) { | 328 | if (len + 15 > dev->mtu) { |
@@ -331,12 +332,14 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
331 | 332 | ||
332 | dev_hold(dev); | 333 | dev_hold(dev); |
333 | 334 | ||
334 | skb = sock_alloc_send_skb(sk, len + LL_ALLOCATED_SPACE(dev), | 335 | hlen = LL_RESERVED_SPACE(dev); |
336 | tlen = dev->needed_tailroom; | ||
337 | skb = sock_alloc_send_skb(sk, len + hlen + tlen, | ||
335 | msg->msg_flags & MSG_DONTWAIT, &err); | 338 | msg->msg_flags & MSG_DONTWAIT, &err); |
336 | if (skb == NULL) | 339 | if (skb == NULL) |
337 | goto out_unlock; | 340 | goto out_unlock; |
338 | 341 | ||
339 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 342 | skb_reserve(skb, hlen); |
340 | skb_reset_network_header(skb); | 343 | skb_reset_network_header(skb); |
341 | 344 | ||
342 | eb = (struct ec_cb *)&skb->cb; | 345 | eb = (struct ec_cb *)&skb->cb; |
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 19d6aefe97d4..e4ecc1eef98c 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c | |||
@@ -50,8 +50,6 @@ | |||
50 | * SUCH DAMAGE. | 50 | * SUCH DAMAGE. |
51 | */ | 51 | */ |
52 | 52 | ||
53 | #define DEBUG | ||
54 | |||
55 | #include <linux/bitops.h> | 53 | #include <linux/bitops.h> |
56 | #include <linux/if_arp.h> | 54 | #include <linux/if_arp.h> |
57 | #include <linux/module.h> | 55 | #include <linux/module.h> |
@@ -113,6 +111,20 @@ struct lowpan_dev_record { | |||
113 | struct list_head list; | 111 | struct list_head list; |
114 | }; | 112 | }; |
115 | 113 | ||
114 | struct lowpan_fragment { | ||
115 | struct sk_buff *skb; /* skb to be assembled */ | ||
116 | spinlock_t lock; /* concurency lock */ | ||
117 | u16 length; /* length to be assemled */ | ||
118 | u32 bytes_rcv; /* bytes received */ | ||
119 | u16 tag; /* current fragment tag */ | ||
120 | struct timer_list timer; /* assembling timer */ | ||
121 | struct list_head list; /* fragments list */ | ||
122 | }; | ||
123 | |||
124 | static unsigned short fragment_tag; | ||
125 | static LIST_HEAD(lowpan_fragments); | ||
126 | spinlock_t flist_lock; | ||
127 | |||
116 | static inline struct | 128 | static inline struct |
117 | lowpan_dev_info *lowpan_dev_info(const struct net_device *dev) | 129 | lowpan_dev_info *lowpan_dev_info(const struct net_device *dev) |
118 | { | 130 | { |
@@ -234,6 +246,50 @@ lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr, | |||
234 | return 0; | 246 | return 0; |
235 | } | 247 | } |
236 | 248 | ||
249 | static void | ||
250 | lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb) | ||
251 | { | ||
252 | struct udphdr *uh = udp_hdr(skb); | ||
253 | |||
254 | pr_debug("(%s): UDP header compression\n", __func__); | ||
255 | |||
256 | if (((uh->source & LOWPAN_NHC_UDP_4BIT_MASK) == | ||
257 | LOWPAN_NHC_UDP_4BIT_PORT) && | ||
258 | ((uh->dest & LOWPAN_NHC_UDP_4BIT_MASK) == | ||
259 | LOWPAN_NHC_UDP_4BIT_PORT)) { | ||
260 | pr_debug("(%s): both ports compression to 4 bits\n", __func__); | ||
261 | **hc06_ptr = LOWPAN_NHC_UDP_CS_P_11; | ||
262 | **(hc06_ptr + 1) = /* subtraction is faster */ | ||
263 | (u8)((uh->dest - LOWPAN_NHC_UDP_4BIT_PORT) + | ||
264 | ((uh->source & LOWPAN_NHC_UDP_4BIT_PORT) << 4)); | ||
265 | *hc06_ptr += 2; | ||
266 | } else if ((uh->dest & LOWPAN_NHC_UDP_8BIT_MASK) == | ||
267 | LOWPAN_NHC_UDP_8BIT_PORT) { | ||
268 | pr_debug("(%s): remove 8 bits of dest\n", __func__); | ||
269 | **hc06_ptr = LOWPAN_NHC_UDP_CS_P_01; | ||
270 | memcpy(*hc06_ptr + 1, &uh->source, 2); | ||
271 | **(hc06_ptr + 3) = (u8)(uh->dest - LOWPAN_NHC_UDP_8BIT_PORT); | ||
272 | *hc06_ptr += 4; | ||
273 | } else if ((uh->source & LOWPAN_NHC_UDP_8BIT_MASK) == | ||
274 | LOWPAN_NHC_UDP_8BIT_PORT) { | ||
275 | pr_debug("(%s): remove 8 bits of source\n", __func__); | ||
276 | **hc06_ptr = LOWPAN_NHC_UDP_CS_P_10; | ||
277 | memcpy(*hc06_ptr + 1, &uh->dest, 2); | ||
278 | **(hc06_ptr + 3) = (u8)(uh->source - LOWPAN_NHC_UDP_8BIT_PORT); | ||
279 | *hc06_ptr += 4; | ||
280 | } else { | ||
281 | pr_debug("(%s): can't compress header\n", __func__); | ||
282 | **hc06_ptr = LOWPAN_NHC_UDP_CS_P_00; | ||
283 | memcpy(*hc06_ptr + 1, &uh->source, 2); | ||
284 | memcpy(*hc06_ptr + 3, &uh->dest, 2); | ||
285 | *hc06_ptr += 5; | ||
286 | } | ||
287 | |||
288 | /* checksum is always inline */ | ||
289 | memcpy(*hc06_ptr, &uh->check, 2); | ||
290 | *hc06_ptr += 2; | ||
291 | } | ||
292 | |||
237 | static u8 lowpan_fetch_skb_u8(struct sk_buff *skb) | 293 | static u8 lowpan_fetch_skb_u8(struct sk_buff *skb) |
238 | { | 294 | { |
239 | u8 ret; | 295 | u8 ret; |
@@ -244,6 +300,73 @@ static u8 lowpan_fetch_skb_u8(struct sk_buff *skb) | |||
244 | return ret; | 300 | return ret; |
245 | } | 301 | } |
246 | 302 | ||
303 | static u16 lowpan_fetch_skb_u16(struct sk_buff *skb) | ||
304 | { | ||
305 | u16 ret; | ||
306 | |||
307 | BUG_ON(!pskb_may_pull(skb, 2)); | ||
308 | |||
309 | ret = skb->data[0] | (skb->data[1] << 8); | ||
310 | skb_pull(skb, 2); | ||
311 | return ret; | ||
312 | } | ||
313 | |||
314 | static int | ||
315 | lowpan_uncompress_udp_header(struct sk_buff *skb) | ||
316 | { | ||
317 | struct udphdr *uh = udp_hdr(skb); | ||
318 | u8 tmp; | ||
319 | |||
320 | tmp = lowpan_fetch_skb_u8(skb); | ||
321 | |||
322 | if ((tmp & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) { | ||
323 | pr_debug("(%s): UDP header uncompression\n", __func__); | ||
324 | switch (tmp & LOWPAN_NHC_UDP_CS_P_11) { | ||
325 | case LOWPAN_NHC_UDP_CS_P_00: | ||
326 | memcpy(&uh->source, &skb->data[0], 2); | ||
327 | memcpy(&uh->dest, &skb->data[2], 2); | ||
328 | skb_pull(skb, 4); | ||
329 | break; | ||
330 | case LOWPAN_NHC_UDP_CS_P_01: | ||
331 | memcpy(&uh->source, &skb->data[0], 2); | ||
332 | uh->dest = | ||
333 | skb->data[2] + LOWPAN_NHC_UDP_8BIT_PORT; | ||
334 | skb_pull(skb, 3); | ||
335 | break; | ||
336 | case LOWPAN_NHC_UDP_CS_P_10: | ||
337 | uh->source = skb->data[0] + LOWPAN_NHC_UDP_8BIT_PORT; | ||
338 | memcpy(&uh->dest, &skb->data[1], 2); | ||
339 | skb_pull(skb, 3); | ||
340 | break; | ||
341 | case LOWPAN_NHC_UDP_CS_P_11: | ||
342 | uh->source = | ||
343 | LOWPAN_NHC_UDP_4BIT_PORT + (skb->data[0] >> 4); | ||
344 | uh->dest = | ||
345 | LOWPAN_NHC_UDP_4BIT_PORT + (skb->data[0] & 0x0f); | ||
346 | skb_pull(skb, 1); | ||
347 | break; | ||
348 | default: | ||
349 | pr_debug("(%s) ERROR: unknown UDP format\n", __func__); | ||
350 | goto err; | ||
351 | break; | ||
352 | } | ||
353 | |||
354 | pr_debug("(%s): uncompressed UDP ports: src = %d, dst = %d\n", | ||
355 | __func__, uh->source, uh->dest); | ||
356 | |||
357 | /* copy checksum */ | ||
358 | memcpy(&uh->check, &skb->data[0], 2); | ||
359 | skb_pull(skb, 2); | ||
360 | } else { | ||
361 | pr_debug("(%s): ERROR: unsupported NH format\n", __func__); | ||
362 | goto err; | ||
363 | } | ||
364 | |||
365 | return 0; | ||
366 | err: | ||
367 | return -EINVAL; | ||
368 | } | ||
369 | |||
247 | static int lowpan_header_create(struct sk_buff *skb, | 370 | static int lowpan_header_create(struct sk_buff *skb, |
248 | struct net_device *dev, | 371 | struct net_device *dev, |
249 | unsigned short type, const void *_daddr, | 372 | unsigned short type, const void *_daddr, |
@@ -342,8 +465,6 @@ static int lowpan_header_create(struct sk_buff *skb, | |||
342 | if (hdr->nexthdr == UIP_PROTO_UDP) | 465 | if (hdr->nexthdr == UIP_PROTO_UDP) |
343 | iphc0 |= LOWPAN_IPHC_NH_C; | 466 | iphc0 |= LOWPAN_IPHC_NH_C; |
344 | 467 | ||
345 | /* TODO: next header compression */ | ||
346 | |||
347 | if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { | 468 | if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { |
348 | *hc06_ptr = hdr->nexthdr; | 469 | *hc06_ptr = hdr->nexthdr; |
349 | hc06_ptr += 1; | 470 | hc06_ptr += 1; |
@@ -431,8 +552,9 @@ static int lowpan_header_create(struct sk_buff *skb, | |||
431 | } | 552 | } |
432 | } | 553 | } |
433 | 554 | ||
434 | /* TODO: UDP header compression */ | 555 | /* UDP header compression */ |
435 | /* TODO: Next Header compression */ | 556 | if (hdr->nexthdr == UIP_PROTO_UDP) |
557 | lowpan_compress_udp_header(&hc06_ptr, skb); | ||
436 | 558 | ||
437 | head[0] = iphc0; | 559 | head[0] = iphc0; |
438 | head[1] = iphc1; | 560 | head[1] = iphc1; |
@@ -467,6 +589,7 @@ static int lowpan_header_create(struct sk_buff *skb, | |||
467 | memcpy(&(sa.hwaddr), saddr, 8); | 589 | memcpy(&(sa.hwaddr), saddr, 8); |
468 | 590 | ||
469 | mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA; | 591 | mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA; |
592 | |||
470 | return dev_hard_header(skb, lowpan_dev_info(dev)->real_dev, | 593 | return dev_hard_header(skb, lowpan_dev_info(dev)->real_dev, |
471 | type, (void *)&da, (void *)&sa, skb->len); | 594 | type, (void *)&da, (void *)&sa, skb->len); |
472 | } | 595 | } |
@@ -511,6 +634,21 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr) | |||
511 | return stat; | 634 | return stat; |
512 | } | 635 | } |
513 | 636 | ||
637 | static void lowpan_fragment_timer_expired(unsigned long entry_addr) | ||
638 | { | ||
639 | struct lowpan_fragment *entry = (struct lowpan_fragment *)entry_addr; | ||
640 | |||
641 | pr_debug("%s: timer expired for frame with tag %d\n", __func__, | ||
642 | entry->tag); | ||
643 | |||
644 | spin_lock(&flist_lock); | ||
645 | list_del(&entry->list); | ||
646 | spin_unlock(&flist_lock); | ||
647 | |||
648 | dev_kfree_skb(entry->skb); | ||
649 | kfree(entry); | ||
650 | } | ||
651 | |||
514 | static int | 652 | static int |
515 | lowpan_process_data(struct sk_buff *skb) | 653 | lowpan_process_data(struct sk_buff *skb) |
516 | { | 654 | { |
@@ -525,6 +663,107 @@ lowpan_process_data(struct sk_buff *skb) | |||
525 | if (skb->len < 2) | 663 | if (skb->len < 2) |
526 | goto drop; | 664 | goto drop; |
527 | iphc0 = lowpan_fetch_skb_u8(skb); | 665 | iphc0 = lowpan_fetch_skb_u8(skb); |
666 | |||
667 | /* fragments assembling */ | ||
668 | switch (iphc0 & LOWPAN_DISPATCH_MASK) { | ||
669 | case LOWPAN_DISPATCH_FRAG1: | ||
670 | case LOWPAN_DISPATCH_FRAGN: | ||
671 | { | ||
672 | struct lowpan_fragment *frame; | ||
673 | u8 len, offset; | ||
674 | u16 tag; | ||
675 | bool found = false; | ||
676 | |||
677 | len = lowpan_fetch_skb_u8(skb); /* frame length */ | ||
678 | tag = lowpan_fetch_skb_u16(skb); | ||
679 | |||
680 | /* | ||
681 | * check if frame assembling with the same tag is | ||
682 | * already in progress | ||
683 | */ | ||
684 | spin_lock(&flist_lock); | ||
685 | |||
686 | list_for_each_entry(frame, &lowpan_fragments, list) | ||
687 | if (frame->tag == tag) { | ||
688 | found = true; | ||
689 | break; | ||
690 | } | ||
691 | |||
692 | /* alloc new frame structure */ | ||
693 | if (!found) { | ||
694 | frame = kzalloc(sizeof(struct lowpan_fragment), | ||
695 | GFP_ATOMIC); | ||
696 | if (!frame) | ||
697 | goto unlock_and_drop; | ||
698 | |||
699 | INIT_LIST_HEAD(&frame->list); | ||
700 | |||
701 | frame->length = (iphc0 & 7) | (len << 3); | ||
702 | frame->tag = tag; | ||
703 | |||
704 | /* allocate buffer for frame assembling */ | ||
705 | frame->skb = alloc_skb(frame->length + | ||
706 | sizeof(struct ipv6hdr), GFP_ATOMIC); | ||
707 | |||
708 | if (!frame->skb) { | ||
709 | kfree(frame); | ||
710 | goto unlock_and_drop; | ||
711 | } | ||
712 | |||
713 | frame->skb->priority = skb->priority; | ||
714 | frame->skb->dev = skb->dev; | ||
715 | |||
716 | /* reserve headroom for uncompressed ipv6 header */ | ||
717 | skb_reserve(frame->skb, sizeof(struct ipv6hdr)); | ||
718 | skb_put(frame->skb, frame->length); | ||
719 | |||
720 | init_timer(&frame->timer); | ||
721 | /* time out is the same as for ipv6 - 60 sec */ | ||
722 | frame->timer.expires = jiffies + LOWPAN_FRAG_TIMEOUT; | ||
723 | frame->timer.data = (unsigned long)frame; | ||
724 | frame->timer.function = lowpan_fragment_timer_expired; | ||
725 | |||
726 | add_timer(&frame->timer); | ||
727 | |||
728 | list_add_tail(&frame->list, &lowpan_fragments); | ||
729 | } | ||
730 | |||
731 | if ((iphc0 & LOWPAN_DISPATCH_MASK) == LOWPAN_DISPATCH_FRAG1) | ||
732 | goto unlock_and_drop; | ||
733 | |||
734 | offset = lowpan_fetch_skb_u8(skb); /* fetch offset */ | ||
735 | |||
736 | /* if payload fits buffer, copy it */ | ||
737 | if (likely((offset * 8 + skb->len) <= frame->length)) | ||
738 | skb_copy_to_linear_data_offset(frame->skb, offset * 8, | ||
739 | skb->data, skb->len); | ||
740 | else | ||
741 | goto unlock_and_drop; | ||
742 | |||
743 | frame->bytes_rcv += skb->len; | ||
744 | |||
745 | /* frame assembling complete */ | ||
746 | if ((frame->bytes_rcv == frame->length) && | ||
747 | frame->timer.expires > jiffies) { | ||
748 | /* if timer haven't expired - first of all delete it */ | ||
749 | del_timer(&frame->timer); | ||
750 | list_del(&frame->list); | ||
751 | spin_unlock(&flist_lock); | ||
752 | |||
753 | dev_kfree_skb(skb); | ||
754 | skb = frame->skb; | ||
755 | kfree(frame); | ||
756 | iphc0 = lowpan_fetch_skb_u8(skb); | ||
757 | break; | ||
758 | } | ||
759 | spin_unlock(&flist_lock); | ||
760 | |||
761 | return kfree_skb(skb), 0; | ||
762 | } | ||
763 | default: | ||
764 | break; | ||
765 | } | ||
766 | |||
528 | iphc1 = lowpan_fetch_skb_u8(skb); | 767 | iphc1 = lowpan_fetch_skb_u8(skb); |
529 | 768 | ||
530 | _saddr = mac_cb(skb)->sa.hwaddr; | 769 | _saddr = mac_cb(skb)->sa.hwaddr; |
@@ -659,7 +898,10 @@ lowpan_process_data(struct sk_buff *skb) | |||
659 | goto drop; | 898 | goto drop; |
660 | } | 899 | } |
661 | 900 | ||
662 | /* TODO: UDP header parse */ | 901 | /* UDP data uncompression */ |
902 | if (iphc0 & LOWPAN_IPHC_NH_C) | ||
903 | if (lowpan_uncompress_udp_header(skb)) | ||
904 | goto drop; | ||
663 | 905 | ||
664 | /* Not fragmented package */ | 906 | /* Not fragmented package */ |
665 | hdr.payload_len = htons(skb->len); | 907 | hdr.payload_len = htons(skb->len); |
@@ -674,6 +916,9 @@ lowpan_process_data(struct sk_buff *skb) | |||
674 | lowpan_raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, | 916 | lowpan_raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, |
675 | sizeof(hdr)); | 917 | sizeof(hdr)); |
676 | return lowpan_skb_deliver(skb, &hdr); | 918 | return lowpan_skb_deliver(skb, &hdr); |
919 | |||
920 | unlock_and_drop: | ||
921 | spin_unlock(&flist_lock); | ||
677 | drop: | 922 | drop: |
678 | kfree_skb(skb); | 923 | kfree_skb(skb); |
679 | return -EINVAL; | 924 | return -EINVAL; |
@@ -692,18 +937,115 @@ static int lowpan_set_address(struct net_device *dev, void *p) | |||
692 | return 0; | 937 | return 0; |
693 | } | 938 | } |
694 | 939 | ||
940 | static int lowpan_get_mac_header_length(struct sk_buff *skb) | ||
941 | { | ||
942 | /* | ||
943 | * Currently long addressing mode is supported only, so the overall | ||
944 | * header size is 21: | ||
945 | * FC SeqNum DPAN DA SA Sec | ||
946 | * 2 + 1 + 2 + 8 + 8 + 0 = 21 | ||
947 | */ | ||
948 | return 21; | ||
949 | } | ||
950 | |||
951 | static int | ||
952 | lowpan_fragment_xmit(struct sk_buff *skb, u8 *head, | ||
953 | int mlen, int plen, int offset) | ||
954 | { | ||
955 | struct sk_buff *frag; | ||
956 | int hlen, ret; | ||
957 | |||
958 | /* if payload length is zero, therefore it's a first fragment */ | ||
959 | hlen = (plen == 0 ? LOWPAN_FRAG1_HEAD_SIZE : LOWPAN_FRAGN_HEAD_SIZE); | ||
960 | |||
961 | lowpan_raw_dump_inline(__func__, "6lowpan fragment header", head, hlen); | ||
962 | |||
963 | frag = dev_alloc_skb(hlen + mlen + plen + IEEE802154_MFR_SIZE); | ||
964 | if (!frag) | ||
965 | return -ENOMEM; | ||
966 | |||
967 | frag->priority = skb->priority; | ||
968 | frag->dev = skb->dev; | ||
969 | |||
970 | /* copy header, MFR and payload */ | ||
971 | memcpy(skb_put(frag, mlen), skb->data, mlen); | ||
972 | memcpy(skb_put(frag, hlen), head, hlen); | ||
973 | |||
974 | if (plen) | ||
975 | skb_copy_from_linear_data_offset(skb, offset + mlen, | ||
976 | skb_put(frag, plen), plen); | ||
977 | |||
978 | lowpan_raw_dump_table(__func__, " raw fragment dump", frag->data, | ||
979 | frag->len); | ||
980 | |||
981 | ret = dev_queue_xmit(frag); | ||
982 | |||
983 | return ret; | ||
984 | } | ||
985 | |||
986 | static int | ||
987 | lowpan_skb_fragmentation(struct sk_buff *skb) | ||
988 | { | ||
989 | int err, header_length, payload_length, tag, offset = 0; | ||
990 | u8 head[5]; | ||
991 | |||
992 | header_length = lowpan_get_mac_header_length(skb); | ||
993 | payload_length = skb->len - header_length; | ||
994 | tag = fragment_tag++; | ||
995 | |||
996 | /* first fragment header */ | ||
997 | head[0] = LOWPAN_DISPATCH_FRAG1 | (payload_length & 0x7); | ||
998 | head[1] = (payload_length >> 3) & 0xff; | ||
999 | head[2] = tag & 0xff; | ||
1000 | head[3] = tag >> 8; | ||
1001 | |||
1002 | err = lowpan_fragment_xmit(skb, head, header_length, 0, 0); | ||
1003 | |||
1004 | /* next fragment header */ | ||
1005 | head[0] &= ~LOWPAN_DISPATCH_FRAG1; | ||
1006 | head[0] |= LOWPAN_DISPATCH_FRAGN; | ||
1007 | |||
1008 | while ((payload_length - offset > 0) && (err >= 0)) { | ||
1009 | int len = LOWPAN_FRAG_SIZE; | ||
1010 | |||
1011 | head[4] = offset / 8; | ||
1012 | |||
1013 | if (payload_length - offset < len) | ||
1014 | len = payload_length - offset; | ||
1015 | |||
1016 | err = lowpan_fragment_xmit(skb, head, header_length, | ||
1017 | len, offset); | ||
1018 | offset += len; | ||
1019 | } | ||
1020 | |||
1021 | return err; | ||
1022 | } | ||
1023 | |||
695 | static netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev) | 1024 | static netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev) |
696 | { | 1025 | { |
697 | int err = 0; | 1026 | int err = -1; |
698 | 1027 | ||
699 | pr_debug("(%s): package xmit\n", __func__); | 1028 | pr_debug("(%s): package xmit\n", __func__); |
700 | 1029 | ||
701 | skb->dev = lowpan_dev_info(dev)->real_dev; | 1030 | skb->dev = lowpan_dev_info(dev)->real_dev; |
702 | if (skb->dev == NULL) { | 1031 | if (skb->dev == NULL) { |
703 | pr_debug("(%s) ERROR: no real wpan device found\n", __func__); | 1032 | pr_debug("(%s) ERROR: no real wpan device found\n", __func__); |
704 | dev_kfree_skb(skb); | 1033 | goto error; |
705 | } else | 1034 | } |
1035 | |||
1036 | if (skb->len <= IEEE802154_MTU) { | ||
706 | err = dev_queue_xmit(skb); | 1037 | err = dev_queue_xmit(skb); |
1038 | goto out; | ||
1039 | } | ||
1040 | |||
1041 | pr_debug("(%s): frame is too big, fragmentation is needed\n", | ||
1042 | __func__); | ||
1043 | err = lowpan_skb_fragmentation(skb); | ||
1044 | error: | ||
1045 | dev_kfree_skb(skb); | ||
1046 | out: | ||
1047 | if (err < 0) | ||
1048 | pr_debug("(%s): ERROR: xmit failed\n", __func__); | ||
707 | 1049 | ||
708 | return (err < 0 ? NETDEV_TX_BUSY : NETDEV_TX_OK); | 1050 | return (err < 0 ? NETDEV_TX_BUSY : NETDEV_TX_OK); |
709 | } | 1051 | } |
@@ -730,13 +1072,12 @@ static void lowpan_setup(struct net_device *dev) | |||
730 | dev->addr_len = IEEE802154_ADDR_LEN; | 1072 | dev->addr_len = IEEE802154_ADDR_LEN; |
731 | memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); | 1073 | memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); |
732 | dev->type = ARPHRD_IEEE802154; | 1074 | dev->type = ARPHRD_IEEE802154; |
733 | dev->features = NETIF_F_NO_CSUM; | ||
734 | /* Frame Control + Sequence Number + Address fields + Security Header */ | 1075 | /* Frame Control + Sequence Number + Address fields + Security Header */ |
735 | dev->hard_header_len = 2 + 1 + 20 + 14; | 1076 | dev->hard_header_len = 2 + 1 + 20 + 14; |
736 | dev->needed_tailroom = 2; /* FCS */ | 1077 | dev->needed_tailroom = 2; /* FCS */ |
737 | dev->mtu = 1281; | 1078 | dev->mtu = 1281; |
738 | dev->tx_queue_len = 0; | 1079 | dev->tx_queue_len = 0; |
739 | dev->flags = IFF_NOARP | IFF_BROADCAST; | 1080 | dev->flags = IFF_BROADCAST | IFF_MULTICAST; |
740 | dev->watchdog_timeo = 0; | 1081 | dev->watchdog_timeo = 0; |
741 | 1082 | ||
742 | dev->netdev_ops = &lowpan_netdev_ops; | 1083 | dev->netdev_ops = &lowpan_netdev_ops; |
@@ -765,8 +1106,15 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, | |||
765 | goto drop; | 1106 | goto drop; |
766 | 1107 | ||
767 | /* check that it's our buffer */ | 1108 | /* check that it's our buffer */ |
768 | if ((skb->data[0] & 0xe0) == 0x60) | 1109 | switch (skb->data[0] & 0xe0) { |
1110 | case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ | ||
1111 | case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ | ||
1112 | case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */ | ||
769 | lowpan_process_data(skb); | 1113 | lowpan_process_data(skb); |
1114 | break; | ||
1115 | default: | ||
1116 | break; | ||
1117 | } | ||
770 | 1118 | ||
771 | return NET_RX_SUCCESS; | 1119 | return NET_RX_SUCCESS; |
772 | 1120 | ||
diff --git a/net/ieee802154/6lowpan.h b/net/ieee802154/6lowpan.h index 5d8cf80b930d..aeff3f310482 100644 --- a/net/ieee802154/6lowpan.h +++ b/net/ieee802154/6lowpan.h | |||
@@ -159,6 +159,24 @@ | |||
159 | #define LOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx */ | 159 | #define LOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx */ |
160 | #define LOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx */ | 160 | #define LOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx */ |
161 | 161 | ||
162 | #define LOWPAN_DISPATCH_MASK 0xf8 /* 11111000 */ | ||
163 | |||
164 | #define LOWPAN_FRAG_TIMEOUT (HZ * 60) /* time-out 60 sec */ | ||
165 | |||
166 | #define LOWPAN_FRAG1_HEAD_SIZE 0x4 | ||
167 | #define LOWPAN_FRAGN_HEAD_SIZE 0x5 | ||
168 | |||
169 | /* | ||
170 | * According IEEE802.15.4 standard: | ||
171 | * - MTU is 127 octets | ||
172 | * - maximum MHR size is 37 octets | ||
173 | * - MFR size is 2 octets | ||
174 | * | ||
175 | * so minimal payload size that we may guarantee is: | ||
176 | * MTU - MHR - MFR = 88 octets | ||
177 | */ | ||
178 | #define LOWPAN_FRAG_SIZE 88 | ||
179 | |||
162 | /* | 180 | /* |
163 | * Values of fields within the IPHC encoding first byte | 181 | * Values of fields within the IPHC encoding first byte |
164 | * (C stands for compressed and I for inline) | 182 | * (C stands for compressed and I for inline) |
@@ -201,6 +219,11 @@ | |||
201 | #define LOWPAN_NHC_UDP_CHECKSUMC 0x04 | 219 | #define LOWPAN_NHC_UDP_CHECKSUMC 0x04 |
202 | #define LOWPAN_NHC_UDP_CHECKSUMI 0x00 | 220 | #define LOWPAN_NHC_UDP_CHECKSUMI 0x00 |
203 | 221 | ||
222 | #define LOWPAN_NHC_UDP_4BIT_PORT 0xF0B0 | ||
223 | #define LOWPAN_NHC_UDP_4BIT_MASK 0xFFF0 | ||
224 | #define LOWPAN_NHC_UDP_8BIT_PORT 0xF000 | ||
225 | #define LOWPAN_NHC_UDP_8BIT_MASK 0xFF00 | ||
226 | |||
204 | /* values for port compression, _with checksum_ ie bit 5 set to 0 */ | 227 | /* values for port compression, _with checksum_ ie bit 5 set to 0 */ |
205 | #define LOWPAN_NHC_UDP_CS_P_00 0xF0 /* all inline */ | 228 | #define LOWPAN_NHC_UDP_CS_P_00 0xF0 /* all inline */ |
206 | #define LOWPAN_NHC_UDP_CS_P_01 0xF1 /* source 16bit inline, | 229 | #define LOWPAN_NHC_UDP_CS_P_01 0xF1 /* source 16bit inline, |
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index faecf648123f..1b09eaabaac1 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c | |||
@@ -209,6 +209,7 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
209 | unsigned mtu; | 209 | unsigned mtu; |
210 | struct sk_buff *skb; | 210 | struct sk_buff *skb; |
211 | struct dgram_sock *ro = dgram_sk(sk); | 211 | struct dgram_sock *ro = dgram_sk(sk); |
212 | int hlen, tlen; | ||
212 | int err; | 213 | int err; |
213 | 214 | ||
214 | if (msg->msg_flags & MSG_OOB) { | 215 | if (msg->msg_flags & MSG_OOB) { |
@@ -229,13 +230,15 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
229 | mtu = dev->mtu; | 230 | mtu = dev->mtu; |
230 | pr_debug("name = %s, mtu = %u\n", dev->name, mtu); | 231 | pr_debug("name = %s, mtu = %u\n", dev->name, mtu); |
231 | 232 | ||
232 | skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + size, | 233 | hlen = LL_RESERVED_SPACE(dev); |
234 | tlen = dev->needed_tailroom; | ||
235 | skb = sock_alloc_send_skb(sk, hlen + tlen + size, | ||
233 | msg->msg_flags & MSG_DONTWAIT, | 236 | msg->msg_flags & MSG_DONTWAIT, |
234 | &err); | 237 | &err); |
235 | if (!skb) | 238 | if (!skb) |
236 | goto out_dev; | 239 | goto out_dev; |
237 | 240 | ||
238 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 241 | skb_reserve(skb, hlen); |
239 | 242 | ||
240 | skb_reset_network_header(skb); | 243 | skb_reset_network_header(skb); |
241 | 244 | ||
diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c index 10970ca85748..f96bae8fd330 100644 --- a/net/ieee802154/raw.c +++ b/net/ieee802154/raw.c | |||
@@ -108,6 +108,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
108 | struct net_device *dev; | 108 | struct net_device *dev; |
109 | unsigned mtu; | 109 | unsigned mtu; |
110 | struct sk_buff *skb; | 110 | struct sk_buff *skb; |
111 | int hlen, tlen; | ||
111 | int err; | 112 | int err; |
112 | 113 | ||
113 | if (msg->msg_flags & MSG_OOB) { | 114 | if (msg->msg_flags & MSG_OOB) { |
@@ -137,12 +138,14 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
137 | goto out_dev; | 138 | goto out_dev; |
138 | } | 139 | } |
139 | 140 | ||
140 | skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + size, | 141 | hlen = LL_RESERVED_SPACE(dev); |
142 | tlen = dev->needed_tailroom; | ||
143 | skb = sock_alloc_send_skb(sk, hlen + tlen + size, | ||
141 | msg->msg_flags & MSG_DONTWAIT, &err); | 144 | msg->msg_flags & MSG_DONTWAIT, &err); |
142 | if (!skb) | 145 | if (!skb) |
143 | goto out_dev; | 146 | goto out_dev; |
144 | 147 | ||
145 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 148 | skb_reserve(skb, hlen); |
146 | 149 | ||
147 | skb_reset_mac_header(skb); | 150 | skb_reset_mac_header(skb); |
148 | skb_reset_network_header(skb); | 151 | skb_reset_network_header(skb); |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 1b5096a9875a..15dc4c4828de 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1250,7 +1250,8 @@ out: | |||
1250 | return err; | 1250 | return err; |
1251 | } | 1251 | } |
1252 | 1252 | ||
1253 | static struct sk_buff *inet_gso_segment(struct sk_buff *skb, u32 features) | 1253 | static struct sk_buff *inet_gso_segment(struct sk_buff *skb, |
1254 | netdev_features_t features) | ||
1254 | { | 1255 | { |
1255 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 1256 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
1256 | struct iphdr *iph; | 1257 | struct iphdr *iph; |
@@ -1572,9 +1573,9 @@ static __net_init int ipv4_mib_init_net(struct net *net) | |||
1572 | sizeof(struct icmp_mib), | 1573 | sizeof(struct icmp_mib), |
1573 | __alignof__(struct icmp_mib)) < 0) | 1574 | __alignof__(struct icmp_mib)) < 0) |
1574 | goto err_icmp_mib; | 1575 | goto err_icmp_mib; |
1575 | if (snmp_mib_init((void __percpu **)net->mib.icmpmsg_statistics, | 1576 | net->mib.icmpmsg_statistics = kzalloc(sizeof(struct icmpmsg_mib), |
1576 | sizeof(struct icmpmsg_mib), | 1577 | GFP_KERNEL); |
1577 | __alignof__(struct icmpmsg_mib)) < 0) | 1578 | if (!net->mib.icmpmsg_statistics) |
1578 | goto err_icmpmsg_mib; | 1579 | goto err_icmpmsg_mib; |
1579 | 1580 | ||
1580 | tcp_mib_init(net); | 1581 | tcp_mib_init(net); |
@@ -1598,7 +1599,7 @@ err_tcp_mib: | |||
1598 | 1599 | ||
1599 | static __net_exit void ipv4_mib_exit_net(struct net *net) | 1600 | static __net_exit void ipv4_mib_exit_net(struct net *net) |
1600 | { | 1601 | { |
1601 | snmp_mib_free((void __percpu **)net->mib.icmpmsg_statistics); | 1602 | kfree(net->mib.icmpmsg_statistics); |
1602 | snmp_mib_free((void __percpu **)net->mib.icmp_statistics); | 1603 | snmp_mib_free((void __percpu **)net->mib.icmp_statistics); |
1603 | snmp_mib_free((void __percpu **)net->mib.udplite_statistics); | 1604 | snmp_mib_free((void __percpu **)net->mib.udplite_statistics); |
1604 | snmp_mib_free((void __percpu **)net->mib.udp_statistics); | 1605 | snmp_mib_free((void __percpu **)net->mib.udp_statistics); |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 96a164aa1367..5c29ac5b0c3a 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -177,7 +177,7 @@ struct neigh_table arp_tbl = { | |||
177 | .gc_staletime = 60 * HZ, | 177 | .gc_staletime = 60 * HZ, |
178 | .reachable_time = 30 * HZ, | 178 | .reachable_time = 30 * HZ, |
179 | .delay_probe_time = 5 * HZ, | 179 | .delay_probe_time = 5 * HZ, |
180 | .queue_len = 3, | 180 | .queue_len_bytes = 64*1024, |
181 | .ucast_probes = 3, | 181 | .ucast_probes = 3, |
182 | .mcast_probes = 3, | 182 | .mcast_probes = 3, |
183 | .anycast_delay = 1 * HZ, | 183 | .anycast_delay = 1 * HZ, |
@@ -592,16 +592,18 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, | |||
592 | struct sk_buff *skb; | 592 | struct sk_buff *skb; |
593 | struct arphdr *arp; | 593 | struct arphdr *arp; |
594 | unsigned char *arp_ptr; | 594 | unsigned char *arp_ptr; |
595 | int hlen = LL_RESERVED_SPACE(dev); | ||
596 | int tlen = dev->needed_tailroom; | ||
595 | 597 | ||
596 | /* | 598 | /* |
597 | * Allocate a buffer | 599 | * Allocate a buffer |
598 | */ | 600 | */ |
599 | 601 | ||
600 | skb = alloc_skb(arp_hdr_len(dev) + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC); | 602 | skb = alloc_skb(arp_hdr_len(dev) + hlen + tlen, GFP_ATOMIC); |
601 | if (skb == NULL) | 603 | if (skb == NULL) |
602 | return NULL; | 604 | return NULL; |
603 | 605 | ||
604 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 606 | skb_reserve(skb, hlen); |
605 | skb_reset_network_header(skb); | 607 | skb_reset_network_header(skb); |
606 | arp = (struct arphdr *) skb_put(skb, arp_hdr_len(dev)); | 608 | arp = (struct arphdr *) skb_put(skb, arp_hdr_len(dev)); |
607 | skb->dev = dev; | 609 | skb->dev = dev; |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index b2ca095cb9da..313ad93d2f7b 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -304,9 +304,11 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | |||
304 | struct igmpv3_report *pig; | 304 | struct igmpv3_report *pig; |
305 | struct net *net = dev_net(dev); | 305 | struct net *net = dev_net(dev); |
306 | struct flowi4 fl4; | 306 | struct flowi4 fl4; |
307 | int hlen = LL_RESERVED_SPACE(dev); | ||
308 | int tlen = dev->needed_tailroom; | ||
307 | 309 | ||
308 | while (1) { | 310 | while (1) { |
309 | skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), | 311 | skb = alloc_skb(size + hlen + tlen, |
310 | GFP_ATOMIC | __GFP_NOWARN); | 312 | GFP_ATOMIC | __GFP_NOWARN); |
311 | if (skb) | 313 | if (skb) |
312 | break; | 314 | break; |
@@ -327,7 +329,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | |||
327 | skb_dst_set(skb, &rt->dst); | 329 | skb_dst_set(skb, &rt->dst); |
328 | skb->dev = dev; | 330 | skb->dev = dev; |
329 | 331 | ||
330 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 332 | skb_reserve(skb, hlen); |
331 | 333 | ||
332 | skb_reset_network_header(skb); | 334 | skb_reset_network_header(skb); |
333 | pip = ip_hdr(skb); | 335 | pip = ip_hdr(skb); |
@@ -647,6 +649,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, | |||
647 | __be32 group = pmc ? pmc->multiaddr : 0; | 649 | __be32 group = pmc ? pmc->multiaddr : 0; |
648 | struct flowi4 fl4; | 650 | struct flowi4 fl4; |
649 | __be32 dst; | 651 | __be32 dst; |
652 | int hlen, tlen; | ||
650 | 653 | ||
651 | if (type == IGMPV3_HOST_MEMBERSHIP_REPORT) | 654 | if (type == IGMPV3_HOST_MEMBERSHIP_REPORT) |
652 | return igmpv3_send_report(in_dev, pmc); | 655 | return igmpv3_send_report(in_dev, pmc); |
@@ -661,7 +664,9 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, | |||
661 | if (IS_ERR(rt)) | 664 | if (IS_ERR(rt)) |
662 | return -1; | 665 | return -1; |
663 | 666 | ||
664 | skb = alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC); | 667 | hlen = LL_RESERVED_SPACE(dev); |
668 | tlen = dev->needed_tailroom; | ||
669 | skb = alloc_skb(IGMP_SIZE + hlen + tlen, GFP_ATOMIC); | ||
665 | if (skb == NULL) { | 670 | if (skb == NULL) { |
666 | ip_rt_put(rt); | 671 | ip_rt_put(rt); |
667 | return -1; | 672 | return -1; |
@@ -669,7 +674,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, | |||
669 | 674 | ||
670 | skb_dst_set(skb, &rt->dst); | 675 | skb_dst_set(skb, &rt->dst); |
671 | 676 | ||
672 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 677 | skb_reserve(skb, hlen); |
673 | 678 | ||
674 | skb_reset_network_header(skb); | 679 | skb_reset_network_header(skb); |
675 | iph = ip_hdr(skb); | 680 | iph = ip_hdr(skb); |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index c14d88ad348d..a598768c616c 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -588,10 +588,19 @@ void inet_csk_reqsk_queue_prune(struct sock *parent, | |||
588 | } | 588 | } |
589 | EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_prune); | 589 | EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_prune); |
590 | 590 | ||
591 | struct sock *inet_csk_clone(struct sock *sk, const struct request_sock *req, | 591 | /** |
592 | const gfp_t priority) | 592 | * inet_csk_clone_lock - clone an inet socket, and lock its clone |
593 | * @sk: the socket to clone | ||
594 | * @req: request_sock | ||
595 | * @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc) | ||
596 | * | ||
597 | * Caller must unlock socket even in error path (bh_unlock_sock(newsk)) | ||
598 | */ | ||
599 | struct sock *inet_csk_clone_lock(const struct sock *sk, | ||
600 | const struct request_sock *req, | ||
601 | const gfp_t priority) | ||
593 | { | 602 | { |
594 | struct sock *newsk = sk_clone(sk, priority); | 603 | struct sock *newsk = sk_clone_lock(sk, priority); |
595 | 604 | ||
596 | if (newsk != NULL) { | 605 | if (newsk != NULL) { |
597 | struct inet_connection_sock *newicsk = inet_csk(newsk); | 606 | struct inet_connection_sock *newicsk = inet_csk(newsk); |
@@ -615,7 +624,7 @@ struct sock *inet_csk_clone(struct sock *sk, const struct request_sock *req, | |||
615 | } | 624 | } |
616 | return newsk; | 625 | return newsk; |
617 | } | 626 | } |
618 | EXPORT_SYMBOL_GPL(inet_csk_clone); | 627 | EXPORT_SYMBOL_GPL(inet_csk_clone_lock); |
619 | 628 | ||
620 | /* | 629 | /* |
621 | * At this point, there should be no process reference to this | 630 | * At this point, there should be no process reference to this |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index ccee270a9b65..0a46c541b477 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -132,13 +132,10 @@ static int inet_csk_diag_fill(struct sock *sk, | |||
132 | if (r->idiag_family == AF_INET6) { | 132 | if (r->idiag_family == AF_INET6) { |
133 | const struct ipv6_pinfo *np = inet6_sk(sk); | 133 | const struct ipv6_pinfo *np = inet6_sk(sk); |
134 | 134 | ||
135 | *(struct in6_addr *)r->id.idiag_src = np->rcv_saddr; | ||
136 | *(struct in6_addr *)r->id.idiag_dst = np->daddr; | ||
135 | if (ext & (1 << (INET_DIAG_TCLASS - 1))) | 137 | if (ext & (1 << (INET_DIAG_TCLASS - 1))) |
136 | RTA_PUT_U8(skb, INET_DIAG_TCLASS, np->tclass); | 138 | RTA_PUT_U8(skb, INET_DIAG_TCLASS, np->tclass); |
137 | |||
138 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_src, | ||
139 | &np->rcv_saddr); | ||
140 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst, | ||
141 | &np->daddr); | ||
142 | } | 139 | } |
143 | #endif | 140 | #endif |
144 | 141 | ||
@@ -228,10 +225,8 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, | |||
228 | const struct inet6_timewait_sock *tw6 = | 225 | const struct inet6_timewait_sock *tw6 = |
229 | inet6_twsk((struct sock *)tw); | 226 | inet6_twsk((struct sock *)tw); |
230 | 227 | ||
231 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_src, | 228 | *(struct in6_addr *)r->id.idiag_src = tw6->tw_v6_rcv_saddr; |
232 | &tw6->tw_v6_rcv_saddr); | 229 | *(struct in6_addr *)r->id.idiag_dst = tw6->tw_v6_daddr; |
233 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst, | ||
234 | &tw6->tw_v6_daddr); | ||
235 | } | 230 | } |
236 | #endif | 231 | #endif |
237 | nlh->nlmsg_len = skb_tail_pointer(skb) - previous_tail; | 232 | nlh->nlmsg_len = skb_tail_pointer(skb) - previous_tail; |
@@ -607,10 +602,8 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, | |||
607 | r->idiag_inode = 0; | 602 | r->idiag_inode = 0; |
608 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | 603 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) |
609 | if (r->idiag_family == AF_INET6) { | 604 | if (r->idiag_family == AF_INET6) { |
610 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_src, | 605 | *(struct in6_addr *)r->id.idiag_src = inet6_rsk(req)->loc_addr; |
611 | &inet6_rsk(req)->loc_addr); | 606 | *(struct in6_addr *)r->id.idiag_dst = inet6_rsk(req)->rmt_addr; |
612 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst, | ||
613 | &inet6_rsk(req)->rmt_addr); | ||
614 | } | 607 | } |
615 | #endif | 608 | #endif |
616 | nlh->nlmsg_len = skb_tail_pointer(skb) - b; | 609 | nlh->nlmsg_len = skb_tail_pointer(skb) - b; |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index d55110e93120..2b32296b7958 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -171,7 +171,7 @@ struct pcpu_tstats { | |||
171 | unsigned long rx_bytes; | 171 | unsigned long rx_bytes; |
172 | unsigned long tx_packets; | 172 | unsigned long tx_packets; |
173 | unsigned long tx_bytes; | 173 | unsigned long tx_bytes; |
174 | }; | 174 | } __attribute__((aligned(4*sizeof(unsigned long)))); |
175 | 175 | ||
176 | static struct net_device_stats *ipgre_get_stats(struct net_device *dev) | 176 | static struct net_device_stats *ipgre_get_stats(struct net_device *dev) |
177 | { | 177 | { |
@@ -835,6 +835,8 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
835 | if (skb_headroom(skb) < max_headroom || skb_shared(skb)|| | 835 | if (skb_headroom(skb) < max_headroom || skb_shared(skb)|| |
836 | (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { | 836 | (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { |
837 | struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); | 837 | struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); |
838 | if (max_headroom > dev->needed_headroom) | ||
839 | dev->needed_headroom = max_headroom; | ||
838 | if (!new_skb) { | 840 | if (!new_skb) { |
839 | ip_rt_put(rt); | 841 | ip_rt_put(rt); |
840 | dev->stats.tx_dropped++; | 842 | dev->stats.tx_dropped++; |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 09ff51bf16a4..80d5fa450210 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -55,20 +55,13 @@ | |||
55 | /* | 55 | /* |
56 | * SOL_IP control messages. | 56 | * SOL_IP control messages. |
57 | */ | 57 | */ |
58 | #define PKTINFO_SKB_CB(__skb) ((struct in_pktinfo *)((__skb)->cb)) | ||
58 | 59 | ||
59 | static void ip_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb) | 60 | static void ip_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb) |
60 | { | 61 | { |
61 | struct in_pktinfo info; | 62 | struct in_pktinfo info = *PKTINFO_SKB_CB(skb); |
62 | struct rtable *rt = skb_rtable(skb); | ||
63 | 63 | ||
64 | info.ipi_addr.s_addr = ip_hdr(skb)->daddr; | 64 | info.ipi_addr.s_addr = ip_hdr(skb)->daddr; |
65 | if (rt) { | ||
66 | info.ipi_ifindex = rt->rt_iif; | ||
67 | info.ipi_spec_dst.s_addr = rt->rt_spec_dst; | ||
68 | } else { | ||
69 | info.ipi_ifindex = 0; | ||
70 | info.ipi_spec_dst.s_addr = 0; | ||
71 | } | ||
72 | 65 | ||
73 | put_cmsg(msg, SOL_IP, IP_PKTINFO, sizeof(info), &info); | 66 | put_cmsg(msg, SOL_IP, IP_PKTINFO, sizeof(info), &info); |
74 | } | 67 | } |
@@ -992,20 +985,28 @@ e_inval: | |||
992 | } | 985 | } |
993 | 986 | ||
994 | /** | 987 | /** |
995 | * ip_queue_rcv_skb - Queue an skb into sock receive queue | 988 | * ipv4_pktinfo_prepare - transfert some info from rtable to skb |
996 | * @sk: socket | 989 | * @sk: socket |
997 | * @skb: buffer | 990 | * @skb: buffer |
998 | * | 991 | * |
999 | * Queues an skb into socket receive queue. If IP_CMSG_PKTINFO option | 992 | * To support IP_CMSG_PKTINFO option, we store rt_iif and rt_spec_dst |
1000 | * is not set, we drop skb dst entry now, while dst cache line is hot. | 993 | * in skb->cb[] before dst drop. |
994 | * This way, receiver doesnt make cache line misses to read rtable. | ||
1001 | */ | 995 | */ |
1002 | int ip_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | 996 | void ipv4_pktinfo_prepare(struct sk_buff *skb) |
1003 | { | 997 | { |
1004 | if (!(inet_sk(sk)->cmsg_flags & IP_CMSG_PKTINFO)) | 998 | struct in_pktinfo *pktinfo = PKTINFO_SKB_CB(skb); |
1005 | skb_dst_drop(skb); | 999 | const struct rtable *rt = skb_rtable(skb); |
1006 | return sock_queue_rcv_skb(sk, skb); | 1000 | |
1001 | if (rt) { | ||
1002 | pktinfo->ipi_ifindex = rt->rt_iif; | ||
1003 | pktinfo->ipi_spec_dst.s_addr = rt->rt_spec_dst; | ||
1004 | } else { | ||
1005 | pktinfo->ipi_ifindex = 0; | ||
1006 | pktinfo->ipi_spec_dst.s_addr = 0; | ||
1007 | } | ||
1008 | skb_dst_drop(skb); | ||
1007 | } | 1009 | } |
1008 | EXPORT_SYMBOL(ip_queue_rcv_skb); | ||
1009 | 1010 | ||
1010 | int ip_setsockopt(struct sock *sk, int level, | 1011 | int ip_setsockopt(struct sock *sk, int level, |
1011 | int optname, char __user *optval, unsigned int optlen) | 1012 | int optname, char __user *optval, unsigned int optlen) |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 0da2afc97f32..915eb5265b2e 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -763,13 +763,15 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d | |||
763 | struct sk_buff *skb; | 763 | struct sk_buff *skb; |
764 | struct bootp_pkt *b; | 764 | struct bootp_pkt *b; |
765 | struct iphdr *h; | 765 | struct iphdr *h; |
766 | int hlen = LL_RESERVED_SPACE(dev); | ||
767 | int tlen = dev->needed_tailroom; | ||
766 | 768 | ||
767 | /* Allocate packet */ | 769 | /* Allocate packet */ |
768 | skb = alloc_skb(sizeof(struct bootp_pkt) + LL_ALLOCATED_SPACE(dev) + 15, | 770 | skb = alloc_skb(sizeof(struct bootp_pkt) + hlen + tlen + 15, |
769 | GFP_KERNEL); | 771 | GFP_KERNEL); |
770 | if (!skb) | 772 | if (!skb) |
771 | return; | 773 | return; |
772 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 774 | skb_reserve(skb, hlen); |
773 | b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt)); | 775 | b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt)); |
774 | memset(b, 0, sizeof(struct bootp_pkt)); | 776 | memset(b, 0, sizeof(struct bootp_pkt)); |
775 | 777 | ||
@@ -822,8 +824,13 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d | |||
822 | skb->dev = dev; | 824 | skb->dev = dev; |
823 | skb->protocol = htons(ETH_P_IP); | 825 | skb->protocol = htons(ETH_P_IP); |
824 | if (dev_hard_header(skb, dev, ntohs(skb->protocol), | 826 | if (dev_hard_header(skb, dev, ntohs(skb->protocol), |
825 | dev->broadcast, dev->dev_addr, skb->len) < 0 || | 827 | dev->broadcast, dev->dev_addr, skb->len) < 0) { |
826 | dev_queue_xmit(skb) < 0) | 828 | kfree_skb(skb); |
829 | printk("E"); | ||
830 | return; | ||
831 | } | ||
832 | |||
833 | if (dev_queue_xmit(skb) < 0) | ||
827 | printk("E"); | 834 | printk("E"); |
828 | } | 835 | } |
829 | 836 | ||
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 065effd8349a..94906908a416 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -148,7 +148,7 @@ struct pcpu_tstats { | |||
148 | unsigned long rx_bytes; | 148 | unsigned long rx_bytes; |
149 | unsigned long tx_packets; | 149 | unsigned long tx_packets; |
150 | unsigned long tx_bytes; | 150 | unsigned long tx_bytes; |
151 | }; | 151 | } __attribute__((aligned(4*sizeof(unsigned long)))); |
152 | 152 | ||
153 | static struct net_device_stats *ipip_get_stats(struct net_device *dev) | 153 | static struct net_device_stats *ipip_get_stats(struct net_device *dev) |
154 | { | 154 | { |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 466ea8bb7a4d..961eed4f510a 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -288,7 +288,7 @@ static void icmpmsg_put(struct seq_file *seq) | |||
288 | 288 | ||
289 | count = 0; | 289 | count = 0; |
290 | for (i = 0; i < ICMPMSG_MIB_MAX; i++) { | 290 | for (i = 0; i < ICMPMSG_MIB_MAX; i++) { |
291 | val = snmp_fold_field((void __percpu **) net->mib.icmpmsg_statistics, i); | 291 | val = atomic_long_read(&net->mib.icmpmsg_statistics->mibs[i]); |
292 | if (val) { | 292 | if (val) { |
293 | type[count] = i; | 293 | type[count] = i; |
294 | vals[count++] = val; | 294 | vals[count++] = val; |
@@ -307,6 +307,7 @@ static void icmp_put(struct seq_file *seq) | |||
307 | { | 307 | { |
308 | int i; | 308 | int i; |
309 | struct net *net = seq->private; | 309 | struct net *net = seq->private; |
310 | atomic_long_t *ptr = net->mib.icmpmsg_statistics->mibs; | ||
310 | 311 | ||
311 | seq_puts(seq, "\nIcmp: InMsgs InErrors"); | 312 | seq_puts(seq, "\nIcmp: InMsgs InErrors"); |
312 | for (i=0; icmpmibmap[i].name != NULL; i++) | 313 | for (i=0; icmpmibmap[i].name != NULL; i++) |
@@ -319,15 +320,13 @@ static void icmp_put(struct seq_file *seq) | |||
319 | snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_INERRORS)); | 320 | snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_INERRORS)); |
320 | for (i=0; icmpmibmap[i].name != NULL; i++) | 321 | for (i=0; icmpmibmap[i].name != NULL; i++) |
321 | seq_printf(seq, " %lu", | 322 | seq_printf(seq, " %lu", |
322 | snmp_fold_field((void __percpu **) net->mib.icmpmsg_statistics, | 323 | atomic_long_read(ptr + icmpmibmap[i].index)); |
323 | icmpmibmap[i].index)); | ||
324 | seq_printf(seq, " %lu %lu", | 324 | seq_printf(seq, " %lu %lu", |
325 | snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_OUTMSGS), | 325 | snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_OUTMSGS), |
326 | snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_OUTERRORS)); | 326 | snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_OUTERRORS)); |
327 | for (i=0; icmpmibmap[i].name != NULL; i++) | 327 | for (i=0; icmpmibmap[i].name != NULL; i++) |
328 | seq_printf(seq, " %lu", | 328 | seq_printf(seq, " %lu", |
329 | snmp_fold_field((void __percpu **) net->mib.icmpmsg_statistics, | 329 | atomic_long_read(ptr + (icmpmibmap[i].index | 0x100))); |
330 | icmpmibmap[i].index | 0x100)); | ||
331 | } | 330 | } |
332 | 331 | ||
333 | /* | 332 | /* |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 007e2eb769d3..3ccda5ae8a27 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -292,7 +292,8 @@ static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb) | |||
292 | { | 292 | { |
293 | /* Charge it to the socket. */ | 293 | /* Charge it to the socket. */ |
294 | 294 | ||
295 | if (ip_queue_rcv_skb(sk, skb) < 0) { | 295 | ipv4_pktinfo_prepare(skb); |
296 | if (sock_queue_rcv_skb(sk, skb) < 0) { | ||
296 | kfree_skb(skb); | 297 | kfree_skb(skb); |
297 | return NET_RX_DROP; | 298 | return NET_RX_DROP; |
298 | } | 299 | } |
@@ -327,6 +328,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, | |||
327 | unsigned int iphlen; | 328 | unsigned int iphlen; |
328 | int err; | 329 | int err; |
329 | struct rtable *rt = *rtp; | 330 | struct rtable *rt = *rtp; |
331 | int hlen, tlen; | ||
330 | 332 | ||
331 | if (length > rt->dst.dev->mtu) { | 333 | if (length > rt->dst.dev->mtu) { |
332 | ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, | 334 | ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, |
@@ -336,12 +338,14 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, | |||
336 | if (flags&MSG_PROBE) | 338 | if (flags&MSG_PROBE) |
337 | goto out; | 339 | goto out; |
338 | 340 | ||
341 | hlen = LL_RESERVED_SPACE(rt->dst.dev); | ||
342 | tlen = rt->dst.dev->needed_tailroom; | ||
339 | skb = sock_alloc_send_skb(sk, | 343 | skb = sock_alloc_send_skb(sk, |
340 | length + LL_ALLOCATED_SPACE(rt->dst.dev) + 15, | 344 | length + hlen + tlen + 15, |
341 | flags & MSG_DONTWAIT, &err); | 345 | flags & MSG_DONTWAIT, &err); |
342 | if (skb == NULL) | 346 | if (skb == NULL) |
343 | goto error; | 347 | goto error; |
344 | skb_reserve(skb, LL_RESERVED_SPACE(rt->dst.dev)); | 348 | skb_reserve(skb, hlen); |
345 | 349 | ||
346 | skb->priority = sk->sk_priority; | 350 | skb->priority = sk->sk_priority; |
347 | skb->mark = sk->sk_mark; | 351 | skb->mark = sk->sk_mark; |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 34f5db1e1c8b..50c359645665 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -2653,7 +2653,8 @@ int compat_tcp_getsockopt(struct sock *sk, int level, int optname, | |||
2653 | EXPORT_SYMBOL(compat_tcp_getsockopt); | 2653 | EXPORT_SYMBOL(compat_tcp_getsockopt); |
2654 | #endif | 2654 | #endif |
2655 | 2655 | ||
2656 | struct sk_buff *tcp_tso_segment(struct sk_buff *skb, u32 features) | 2656 | struct sk_buff *tcp_tso_segment(struct sk_buff *skb, |
2657 | netdev_features_t features) | ||
2657 | { | 2658 | { |
2658 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 2659 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
2659 | struct tcphdr *th; | 2660 | struct tcphdr *th; |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 66363b689ad6..945efffdd929 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -343,8 +343,8 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) | |||
343 | 343 | ||
344 | tw->tw_ipv6_offset = inet6_tw_offset(sk->sk_prot); | 344 | tw->tw_ipv6_offset = inet6_tw_offset(sk->sk_prot); |
345 | tw6 = inet6_twsk((struct sock *)tw); | 345 | tw6 = inet6_twsk((struct sock *)tw); |
346 | ipv6_addr_copy(&tw6->tw_v6_daddr, &np->daddr); | 346 | tw6->tw_v6_daddr = np->daddr; |
347 | ipv6_addr_copy(&tw6->tw_v6_rcv_saddr, &np->rcv_saddr); | 347 | tw6->tw_v6_rcv_saddr = np->rcv_saddr; |
348 | tw->tw_tclass = np->tclass; | 348 | tw->tw_tclass = np->tclass; |
349 | tw->tw_ipv6only = np->ipv6only; | 349 | tw->tw_ipv6only = np->ipv6only; |
350 | } | 350 | } |
@@ -425,7 +425,7 @@ static inline void TCP_ECN_openreq_child(struct tcp_sock *tp, | |||
425 | */ | 425 | */ |
426 | struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, struct sk_buff *skb) | 426 | struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, struct sk_buff *skb) |
427 | { | 427 | { |
428 | struct sock *newsk = inet_csk_clone(sk, req, GFP_ATOMIC); | 428 | struct sock *newsk = inet_csk_clone_lock(sk, req, GFP_ATOMIC); |
429 | 429 | ||
430 | if (newsk != NULL) { | 430 | if (newsk != NULL) { |
431 | const struct inet_request_sock *ireq = inet_rsk(req); | 431 | const struct inet_request_sock *ireq = inet_rsk(req); |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index ab0966df1e2a..b867ea23ece9 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1357,7 +1357,7 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
1357 | if (inet_sk(sk)->inet_daddr) | 1357 | if (inet_sk(sk)->inet_daddr) |
1358 | sock_rps_save_rxhash(sk, skb); | 1358 | sock_rps_save_rxhash(sk, skb); |
1359 | 1359 | ||
1360 | rc = ip_queue_rcv_skb(sk, skb); | 1360 | rc = sock_queue_rcv_skb(sk, skb); |
1361 | if (rc < 0) { | 1361 | if (rc < 0) { |
1362 | int is_udplite = IS_UDPLITE(sk); | 1362 | int is_udplite = IS_UDPLITE(sk); |
1363 | 1363 | ||
@@ -1473,6 +1473,7 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
1473 | 1473 | ||
1474 | rc = 0; | 1474 | rc = 0; |
1475 | 1475 | ||
1476 | ipv4_pktinfo_prepare(skb); | ||
1476 | bh_lock_sock(sk); | 1477 | bh_lock_sock(sk); |
1477 | if (!sock_owned_by_user(sk)) | 1478 | if (!sock_owned_by_user(sk)) |
1478 | rc = __udp_queue_rcv_skb(sk, skb); | 1479 | rc = __udp_queue_rcv_skb(sk, skb); |
@@ -2246,7 +2247,8 @@ int udp4_ufo_send_check(struct sk_buff *skb) | |||
2246 | return 0; | 2247 | return 0; |
2247 | } | 2248 | } |
2248 | 2249 | ||
2249 | struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, u32 features) | 2250 | struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, |
2251 | netdev_features_t features) | ||
2250 | { | 2252 | { |
2251 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 2253 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
2252 | unsigned int mss; | 2254 | unsigned int mss; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index cf88df82e2c2..586051726341 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -636,7 +636,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
636 | goto out; | 636 | goto out; |
637 | } | 637 | } |
638 | 638 | ||
639 | ipv6_addr_copy(&ifa->addr, addr); | 639 | ifa->addr = *addr; |
640 | 640 | ||
641 | spin_lock_init(&ifa->lock); | 641 | spin_lock_init(&ifa->lock); |
642 | spin_lock_init(&ifa->state_lock); | 642 | spin_lock_init(&ifa->state_lock); |
@@ -1228,7 +1228,7 @@ try_nextdev: | |||
1228 | if (!hiscore->ifa) | 1228 | if (!hiscore->ifa) |
1229 | return -EADDRNOTAVAIL; | 1229 | return -EADDRNOTAVAIL; |
1230 | 1230 | ||
1231 | ipv6_addr_copy(saddr, &hiscore->ifa->addr); | 1231 | *saddr = hiscore->ifa->addr; |
1232 | in6_ifa_put(hiscore->ifa); | 1232 | in6_ifa_put(hiscore->ifa); |
1233 | return 0; | 1233 | return 0; |
1234 | } | 1234 | } |
@@ -1249,7 +1249,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, | |||
1249 | list_for_each_entry(ifp, &idev->addr_list, if_list) { | 1249 | list_for_each_entry(ifp, &idev->addr_list, if_list) { |
1250 | if (ifp->scope == IFA_LINK && | 1250 | if (ifp->scope == IFA_LINK && |
1251 | !(ifp->flags & banned_flags)) { | 1251 | !(ifp->flags & banned_flags)) { |
1252 | ipv6_addr_copy(addr, &ifp->addr); | 1252 | *addr = ifp->addr; |
1253 | err = 0; | 1253 | err = 0; |
1254 | break; | 1254 | break; |
1255 | } | 1255 | } |
@@ -1700,7 +1700,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, | |||
1700 | .fc_protocol = RTPROT_KERNEL, | 1700 | .fc_protocol = RTPROT_KERNEL, |
1701 | }; | 1701 | }; |
1702 | 1702 | ||
1703 | ipv6_addr_copy(&cfg.fc_dst, pfx); | 1703 | cfg.fc_dst = *pfx; |
1704 | 1704 | ||
1705 | /* Prevent useless cloning on PtP SIT. | 1705 | /* Prevent useless cloning on PtP SIT. |
1706 | This thing is done here expecting that the whole | 1706 | This thing is done here expecting that the whole |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index d27c797f9f05..7694c82e629d 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -347,7 +347,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
347 | */ | 347 | */ |
348 | v4addr = LOOPBACK4_IPV6; | 348 | v4addr = LOOPBACK4_IPV6; |
349 | if (!(addr_type & IPV6_ADDR_MULTICAST)) { | 349 | if (!(addr_type & IPV6_ADDR_MULTICAST)) { |
350 | if (!inet->transparent && | 350 | if (!(inet->freebind || inet->transparent) && |
351 | !ipv6_chk_addr(net, &addr->sin6_addr, | 351 | !ipv6_chk_addr(net, &addr->sin6_addr, |
352 | dev, 0)) { | 352 | dev, 0)) { |
353 | err = -EADDRNOTAVAIL; | 353 | err = -EADDRNOTAVAIL; |
@@ -361,10 +361,10 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
361 | inet->inet_rcv_saddr = v4addr; | 361 | inet->inet_rcv_saddr = v4addr; |
362 | inet->inet_saddr = v4addr; | 362 | inet->inet_saddr = v4addr; |
363 | 363 | ||
364 | ipv6_addr_copy(&np->rcv_saddr, &addr->sin6_addr); | 364 | np->rcv_saddr = addr->sin6_addr; |
365 | 365 | ||
366 | if (!(addr_type & IPV6_ADDR_MULTICAST)) | 366 | if (!(addr_type & IPV6_ADDR_MULTICAST)) |
367 | ipv6_addr_copy(&np->saddr, &addr->sin6_addr); | 367 | np->saddr = addr->sin6_addr; |
368 | 368 | ||
369 | /* Make sure we are allowed to bind here. */ | 369 | /* Make sure we are allowed to bind here. */ |
370 | if (sk->sk_prot->get_port(sk, snum)) { | 370 | if (sk->sk_prot->get_port(sk, snum)) { |
@@ -458,14 +458,14 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr, | |||
458 | peer == 1) | 458 | peer == 1) |
459 | return -ENOTCONN; | 459 | return -ENOTCONN; |
460 | sin->sin6_port = inet->inet_dport; | 460 | sin->sin6_port = inet->inet_dport; |
461 | ipv6_addr_copy(&sin->sin6_addr, &np->daddr); | 461 | sin->sin6_addr = np->daddr; |
462 | if (np->sndflow) | 462 | if (np->sndflow) |
463 | sin->sin6_flowinfo = np->flow_label; | 463 | sin->sin6_flowinfo = np->flow_label; |
464 | } else { | 464 | } else { |
465 | if (ipv6_addr_any(&np->rcv_saddr)) | 465 | if (ipv6_addr_any(&np->rcv_saddr)) |
466 | ipv6_addr_copy(&sin->sin6_addr, &np->saddr); | 466 | sin->sin6_addr = np->saddr; |
467 | else | 467 | else |
468 | ipv6_addr_copy(&sin->sin6_addr, &np->rcv_saddr); | 468 | sin->sin6_addr = np->rcv_saddr; |
469 | 469 | ||
470 | sin->sin6_port = inet->inet_sport; | 470 | sin->sin6_port = inet->inet_sport; |
471 | } | 471 | } |
@@ -660,8 +660,8 @@ int inet6_sk_rebuild_header(struct sock *sk) | |||
660 | 660 | ||
661 | memset(&fl6, 0, sizeof(fl6)); | 661 | memset(&fl6, 0, sizeof(fl6)); |
662 | fl6.flowi6_proto = sk->sk_protocol; | 662 | fl6.flowi6_proto = sk->sk_protocol; |
663 | ipv6_addr_copy(&fl6.daddr, &np->daddr); | 663 | fl6.daddr = np->daddr; |
664 | ipv6_addr_copy(&fl6.saddr, &np->saddr); | 664 | fl6.saddr = np->saddr; |
665 | fl6.flowlabel = np->flow_label; | 665 | fl6.flowlabel = np->flow_label; |
666 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 666 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
667 | fl6.flowi6_mark = sk->sk_mark; | 667 | fl6.flowi6_mark = sk->sk_mark; |
@@ -769,7 +769,8 @@ out: | |||
769 | return err; | 769 | return err; |
770 | } | 770 | } |
771 | 771 | ||
772 | static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, u32 features) | 772 | static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, |
773 | netdev_features_t features) | ||
773 | { | 774 | { |
774 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 775 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
775 | struct ipv6hdr *ipv6h; | 776 | struct ipv6hdr *ipv6h; |
@@ -985,9 +986,9 @@ static int __net_init ipv6_init_mibs(struct net *net) | |||
985 | sizeof(struct icmpv6_mib), | 986 | sizeof(struct icmpv6_mib), |
986 | __alignof__(struct icmpv6_mib)) < 0) | 987 | __alignof__(struct icmpv6_mib)) < 0) |
987 | goto err_icmp_mib; | 988 | goto err_icmp_mib; |
988 | if (snmp_mib_init((void __percpu **)net->mib.icmpv6msg_statistics, | 989 | net->mib.icmpv6msg_statistics = kzalloc(sizeof(struct icmpv6msg_mib), |
989 | sizeof(struct icmpv6msg_mib), | 990 | GFP_KERNEL); |
990 | __alignof__(struct icmpv6msg_mib)) < 0) | 991 | if (!net->mib.icmpv6msg_statistics) |
991 | goto err_icmpmsg_mib; | 992 | goto err_icmpmsg_mib; |
992 | return 0; | 993 | return 0; |
993 | 994 | ||
@@ -1008,7 +1009,7 @@ static void ipv6_cleanup_mibs(struct net *net) | |||
1008 | snmp_mib_free((void __percpu **)net->mib.udplite_stats_in6); | 1009 | snmp_mib_free((void __percpu **)net->mib.udplite_stats_in6); |
1009 | snmp_mib_free((void __percpu **)net->mib.ipv6_statistics); | 1010 | snmp_mib_free((void __percpu **)net->mib.ipv6_statistics); |
1010 | snmp_mib_free((void __percpu **)net->mib.icmpv6_statistics); | 1011 | snmp_mib_free((void __percpu **)net->mib.icmpv6_statistics); |
1011 | snmp_mib_free((void __percpu **)net->mib.icmpv6msg_statistics); | 1012 | kfree(net->mib.icmpv6msg_statistics); |
1012 | } | 1013 | } |
1013 | 1014 | ||
1014 | static int __net_init inet6_net_init(struct net *net) | 1015 | static int __net_init inet6_net_init(struct net *net) |
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 4c0f894d0843..2ae79dbeec2f 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -193,9 +193,9 @@ static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *des | |||
193 | printk(KERN_WARNING "destopt hao: invalid header length: %u\n", hao->length); | 193 | printk(KERN_WARNING "destopt hao: invalid header length: %u\n", hao->length); |
194 | goto bad; | 194 | goto bad; |
195 | } | 195 | } |
196 | ipv6_addr_copy(&final_addr, &hao->addr); | 196 | final_addr = hao->addr; |
197 | ipv6_addr_copy(&hao->addr, &iph->saddr); | 197 | hao->addr = iph->saddr; |
198 | ipv6_addr_copy(&iph->saddr, &final_addr); | 198 | iph->saddr = final_addr; |
199 | } | 199 | } |
200 | break; | 200 | break; |
201 | } | 201 | } |
@@ -241,13 +241,13 @@ static void ipv6_rearrange_rthdr(struct ipv6hdr *iph, struct ipv6_rt_hdr *rthdr) | |||
241 | segments = rthdr->hdrlen >> 1; | 241 | segments = rthdr->hdrlen >> 1; |
242 | 242 | ||
243 | addrs = ((struct rt0_hdr *)rthdr)->addr; | 243 | addrs = ((struct rt0_hdr *)rthdr)->addr; |
244 | ipv6_addr_copy(&final_addr, addrs + segments - 1); | 244 | final_addr = addrs[segments - 1]; |
245 | 245 | ||
246 | addrs += segments - segments_left; | 246 | addrs += segments - segments_left; |
247 | memmove(addrs + 1, addrs, (segments_left - 1) * sizeof(*addrs)); | 247 | memmove(addrs + 1, addrs, (segments_left - 1) * sizeof(*addrs)); |
248 | 248 | ||
249 | ipv6_addr_copy(addrs, &iph->daddr); | 249 | addrs[0] = iph->daddr; |
250 | ipv6_addr_copy(&iph->daddr, &final_addr); | 250 | iph->daddr = final_addr; |
251 | } | 251 | } |
252 | 252 | ||
253 | static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir) | 253 | static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir) |
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 674255f5e6b7..fc1cdcd7041a 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c | |||
@@ -75,7 +75,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
75 | if (pac == NULL) | 75 | if (pac == NULL) |
76 | return -ENOMEM; | 76 | return -ENOMEM; |
77 | pac->acl_next = NULL; | 77 | pac->acl_next = NULL; |
78 | ipv6_addr_copy(&pac->acl_addr, addr); | 78 | pac->acl_addr = *addr; |
79 | 79 | ||
80 | rcu_read_lock(); | 80 | rcu_read_lock(); |
81 | if (ifindex == 0) { | 81 | if (ifindex == 0) { |
@@ -296,7 +296,7 @@ int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr) | |||
296 | goto out; | 296 | goto out; |
297 | } | 297 | } |
298 | 298 | ||
299 | ipv6_addr_copy(&aca->aca_addr, addr); | 299 | aca->aca_addr = *addr; |
300 | aca->aca_idev = idev; | 300 | aca->aca_idev = idev; |
301 | aca->aca_rt = rt; | 301 | aca->aca_rt = rt; |
302 | aca->aca_users = 1; | 302 | aca->aca_users = 1; |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index e2480691c220..ae08aee1773c 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -71,7 +71,7 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
71 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 71 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
72 | if (flowlabel == NULL) | 72 | if (flowlabel == NULL) |
73 | return -EINVAL; | 73 | return -EINVAL; |
74 | ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst); | 74 | usin->sin6_addr = flowlabel->dst; |
75 | } | 75 | } |
76 | } | 76 | } |
77 | 77 | ||
@@ -143,7 +143,7 @@ ipv4_connected: | |||
143 | } | 143 | } |
144 | } | 144 | } |
145 | 145 | ||
146 | ipv6_addr_copy(&np->daddr, daddr); | 146 | np->daddr = *daddr; |
147 | np->flow_label = fl6.flowlabel; | 147 | np->flow_label = fl6.flowlabel; |
148 | 148 | ||
149 | inet->inet_dport = usin->sin6_port; | 149 | inet->inet_dport = usin->sin6_port; |
@@ -154,8 +154,8 @@ ipv4_connected: | |||
154 | */ | 154 | */ |
155 | 155 | ||
156 | fl6.flowi6_proto = sk->sk_protocol; | 156 | fl6.flowi6_proto = sk->sk_protocol; |
157 | ipv6_addr_copy(&fl6.daddr, &np->daddr); | 157 | fl6.daddr = np->daddr; |
158 | ipv6_addr_copy(&fl6.saddr, &np->saddr); | 158 | fl6.saddr = np->saddr; |
159 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 159 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
160 | fl6.flowi6_mark = sk->sk_mark; | 160 | fl6.flowi6_mark = sk->sk_mark; |
161 | fl6.fl6_dport = inet->inet_dport; | 161 | fl6.fl6_dport = inet->inet_dport; |
@@ -179,10 +179,10 @@ ipv4_connected: | |||
179 | /* source address lookup done in ip6_dst_lookup */ | 179 | /* source address lookup done in ip6_dst_lookup */ |
180 | 180 | ||
181 | if (ipv6_addr_any(&np->saddr)) | 181 | if (ipv6_addr_any(&np->saddr)) |
182 | ipv6_addr_copy(&np->saddr, &fl6.saddr); | 182 | np->saddr = fl6.saddr; |
183 | 183 | ||
184 | if (ipv6_addr_any(&np->rcv_saddr)) { | 184 | if (ipv6_addr_any(&np->rcv_saddr)) { |
185 | ipv6_addr_copy(&np->rcv_saddr, &fl6.saddr); | 185 | np->rcv_saddr = fl6.saddr; |
186 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; | 186 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; |
187 | if (sk->sk_prot->rehash) | 187 | if (sk->sk_prot->rehash) |
188 | sk->sk_prot->rehash(sk); | 188 | sk->sk_prot->rehash(sk); |
@@ -257,7 +257,7 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info) | |||
257 | skb_put(skb, sizeof(struct ipv6hdr)); | 257 | skb_put(skb, sizeof(struct ipv6hdr)); |
258 | skb_reset_network_header(skb); | 258 | skb_reset_network_header(skb); |
259 | iph = ipv6_hdr(skb); | 259 | iph = ipv6_hdr(skb); |
260 | ipv6_addr_copy(&iph->daddr, &fl6->daddr); | 260 | iph->daddr = fl6->daddr; |
261 | 261 | ||
262 | serr = SKB_EXT_ERR(skb); | 262 | serr = SKB_EXT_ERR(skb); |
263 | serr->ee.ee_errno = err; | 263 | serr->ee.ee_errno = err; |
@@ -294,7 +294,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu) | |||
294 | skb_put(skb, sizeof(struct ipv6hdr)); | 294 | skb_put(skb, sizeof(struct ipv6hdr)); |
295 | skb_reset_network_header(skb); | 295 | skb_reset_network_header(skb); |
296 | iph = ipv6_hdr(skb); | 296 | iph = ipv6_hdr(skb); |
297 | ipv6_addr_copy(&iph->daddr, &fl6->daddr); | 297 | iph->daddr = fl6->daddr; |
298 | 298 | ||
299 | mtu_info = IP6CBMTU(skb); | 299 | mtu_info = IP6CBMTU(skb); |
300 | 300 | ||
@@ -303,7 +303,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu) | |||
303 | mtu_info->ip6m_addr.sin6_port = 0; | 303 | mtu_info->ip6m_addr.sin6_port = 0; |
304 | mtu_info->ip6m_addr.sin6_flowinfo = 0; | 304 | mtu_info->ip6m_addr.sin6_flowinfo = 0; |
305 | mtu_info->ip6m_addr.sin6_scope_id = fl6->flowi6_oif; | 305 | mtu_info->ip6m_addr.sin6_scope_id = fl6->flowi6_oif; |
306 | ipv6_addr_copy(&mtu_info->ip6m_addr.sin6_addr, &ipv6_hdr(skb)->daddr); | 306 | mtu_info->ip6m_addr.sin6_addr = ipv6_hdr(skb)->daddr; |
307 | 307 | ||
308 | __skb_pull(skb, skb_tail_pointer(skb) - skb->data); | 308 | __skb_pull(skb, skb_tail_pointer(skb) - skb->data); |
309 | skb_reset_transport_header(skb); | 309 | skb_reset_transport_header(skb); |
@@ -354,8 +354,8 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) | |||
354 | sin->sin6_port = serr->port; | 354 | sin->sin6_port = serr->port; |
355 | sin->sin6_scope_id = 0; | 355 | sin->sin6_scope_id = 0; |
356 | if (skb->protocol == htons(ETH_P_IPV6)) { | 356 | if (skb->protocol == htons(ETH_P_IPV6)) { |
357 | ipv6_addr_copy(&sin->sin6_addr, | 357 | sin->sin6_addr = |
358 | (struct in6_addr *)(nh + serr->addr_offset)); | 358 | *(struct in6_addr *)(nh + serr->addr_offset); |
359 | if (np->sndflow) | 359 | if (np->sndflow) |
360 | sin->sin6_flowinfo = | 360 | sin->sin6_flowinfo = |
361 | (*(__be32 *)(nh + serr->addr_offset - 24) & | 361 | (*(__be32 *)(nh + serr->addr_offset - 24) & |
@@ -376,7 +376,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) | |||
376 | sin->sin6_flowinfo = 0; | 376 | sin->sin6_flowinfo = 0; |
377 | sin->sin6_scope_id = 0; | 377 | sin->sin6_scope_id = 0; |
378 | if (skb->protocol == htons(ETH_P_IPV6)) { | 378 | if (skb->protocol == htons(ETH_P_IPV6)) { |
379 | ipv6_addr_copy(&sin->sin6_addr, &ipv6_hdr(skb)->saddr); | 379 | sin->sin6_addr = ipv6_hdr(skb)->saddr; |
380 | if (np->rxopt.all) | 380 | if (np->rxopt.all) |
381 | datagram_recv_ctl(sk, msg, skb); | 381 | datagram_recv_ctl(sk, msg, skb); |
382 | if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) | 382 | if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) |
@@ -451,7 +451,7 @@ int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len) | |||
451 | sin->sin6_flowinfo = 0; | 451 | sin->sin6_flowinfo = 0; |
452 | sin->sin6_port = 0; | 452 | sin->sin6_port = 0; |
453 | sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id; | 453 | sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id; |
454 | ipv6_addr_copy(&sin->sin6_addr, &mtu_info.ip6m_addr.sin6_addr); | 454 | sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr; |
455 | } | 455 | } |
456 | 456 | ||
457 | put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info); | 457 | put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info); |
@@ -475,7 +475,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) | |||
475 | struct in6_pktinfo src_info; | 475 | struct in6_pktinfo src_info; |
476 | 476 | ||
477 | src_info.ipi6_ifindex = opt->iif; | 477 | src_info.ipi6_ifindex = opt->iif; |
478 | ipv6_addr_copy(&src_info.ipi6_addr, &ipv6_hdr(skb)->daddr); | 478 | src_info.ipi6_addr = ipv6_hdr(skb)->daddr; |
479 | put_cmsg(msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info); | 479 | put_cmsg(msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info); |
480 | } | 480 | } |
481 | 481 | ||
@@ -550,7 +550,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) | |||
550 | struct in6_pktinfo src_info; | 550 | struct in6_pktinfo src_info; |
551 | 551 | ||
552 | src_info.ipi6_ifindex = opt->iif; | 552 | src_info.ipi6_ifindex = opt->iif; |
553 | ipv6_addr_copy(&src_info.ipi6_addr, &ipv6_hdr(skb)->daddr); | 553 | src_info.ipi6_addr = ipv6_hdr(skb)->daddr; |
554 | put_cmsg(msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info); | 554 | put_cmsg(msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info); |
555 | } | 555 | } |
556 | if (np->rxopt.bits.rxohlim) { | 556 | if (np->rxopt.bits.rxohlim) { |
@@ -584,7 +584,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) | |||
584 | */ | 584 | */ |
585 | 585 | ||
586 | sin6.sin6_family = AF_INET6; | 586 | sin6.sin6_family = AF_INET6; |
587 | ipv6_addr_copy(&sin6.sin6_addr, &ipv6_hdr(skb)->daddr); | 587 | sin6.sin6_addr = ipv6_hdr(skb)->daddr; |
588 | sin6.sin6_port = ports[1]; | 588 | sin6.sin6_port = ports[1]; |
589 | sin6.sin6_flowinfo = 0; | 589 | sin6.sin6_flowinfo = 0; |
590 | sin6.sin6_scope_id = 0; | 590 | sin6.sin6_scope_id = 0; |
@@ -654,12 +654,12 @@ int datagram_send_ctl(struct net *net, struct sock *sk, | |||
654 | 654 | ||
655 | if (addr_type != IPV6_ADDR_ANY) { | 655 | if (addr_type != IPV6_ADDR_ANY) { |
656 | int strict = __ipv6_addr_src_scope(addr_type) <= IPV6_ADDR_SCOPE_LINKLOCAL; | 656 | int strict = __ipv6_addr_src_scope(addr_type) <= IPV6_ADDR_SCOPE_LINKLOCAL; |
657 | if (!inet_sk(sk)->transparent && | 657 | if (!(inet_sk(sk)->freebind || inet_sk(sk)->transparent) && |
658 | !ipv6_chk_addr(net, &src_info->ipi6_addr, | 658 | !ipv6_chk_addr(net, &src_info->ipi6_addr, |
659 | strict ? dev : NULL, 0)) | 659 | strict ? dev : NULL, 0)) |
660 | err = -EINVAL; | 660 | err = -EINVAL; |
661 | else | 661 | else |
662 | ipv6_addr_copy(&fl6->saddr, &src_info->ipi6_addr); | 662 | fl6->saddr = src_info->ipi6_addr; |
663 | } | 663 | } |
664 | 664 | ||
665 | rcu_read_unlock(); | 665 | rcu_read_unlock(); |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index bf22a225f422..3d641b6e9b09 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -243,9 +243,9 @@ static int ipv6_dest_hao(struct sk_buff *skb, int optoff) | |||
243 | if (skb->ip_summed == CHECKSUM_COMPLETE) | 243 | if (skb->ip_summed == CHECKSUM_COMPLETE) |
244 | skb->ip_summed = CHECKSUM_NONE; | 244 | skb->ip_summed = CHECKSUM_NONE; |
245 | 245 | ||
246 | ipv6_addr_copy(&tmp_addr, &ipv6h->saddr); | 246 | tmp_addr = ipv6h->saddr; |
247 | ipv6_addr_copy(&ipv6h->saddr, &hao->addr); | 247 | ipv6h->saddr = hao->addr; |
248 | ipv6_addr_copy(&hao->addr, &tmp_addr); | 248 | hao->addr = tmp_addr; |
249 | 249 | ||
250 | if (skb->tstamp.tv64 == 0) | 250 | if (skb->tstamp.tv64 == 0) |
251 | __net_timestamp(skb); | 251 | __net_timestamp(skb); |
@@ -461,9 +461,9 @@ looped_back: | |||
461 | return -1; | 461 | return -1; |
462 | } | 462 | } |
463 | 463 | ||
464 | ipv6_addr_copy(&daddr, addr); | 464 | daddr = *addr; |
465 | ipv6_addr_copy(addr, &ipv6_hdr(skb)->daddr); | 465 | *addr = ipv6_hdr(skb)->daddr; |
466 | ipv6_addr_copy(&ipv6_hdr(skb)->daddr, &daddr); | 466 | ipv6_hdr(skb)->daddr = daddr; |
467 | 467 | ||
468 | skb_dst_drop(skb); | 468 | skb_dst_drop(skb); |
469 | ip6_route_input(skb); | 469 | ip6_route_input(skb); |
@@ -690,7 +690,7 @@ static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto, | |||
690 | memcpy(phdr->addr, ihdr->addr + 1, | 690 | memcpy(phdr->addr, ihdr->addr + 1, |
691 | (hops - 1) * sizeof(struct in6_addr)); | 691 | (hops - 1) * sizeof(struct in6_addr)); |
692 | 692 | ||
693 | ipv6_addr_copy(phdr->addr + (hops - 1), *addr_p); | 693 | phdr->addr[hops - 1] = **addr_p; |
694 | *addr_p = ihdr->addr; | 694 | *addr_p = ihdr->addr; |
695 | 695 | ||
696 | phdr->rt_hdr.nexthdr = *proto; | 696 | phdr->rt_hdr.nexthdr = *proto; |
@@ -888,8 +888,8 @@ struct in6_addr *fl6_update_dst(struct flowi6 *fl6, | |||
888 | if (!opt || !opt->srcrt) | 888 | if (!opt || !opt->srcrt) |
889 | return NULL; | 889 | return NULL; |
890 | 890 | ||
891 | ipv6_addr_copy(orig, &fl6->daddr); | 891 | *orig = fl6->daddr; |
892 | ipv6_addr_copy(&fl6->daddr, ((struct rt0_hdr *)opt->srcrt)->addr); | 892 | fl6->daddr = *((struct rt0_hdr *)opt->srcrt)->addr; |
893 | return orig; | 893 | return orig; |
894 | } | 894 | } |
895 | 895 | ||
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 295571576f83..b6c573152067 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -96,7 +96,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, | |||
96 | if (!ipv6_prefix_equal(&saddr, &r->src.addr, | 96 | if (!ipv6_prefix_equal(&saddr, &r->src.addr, |
97 | r->src.plen)) | 97 | r->src.plen)) |
98 | goto again; | 98 | goto again; |
99 | ipv6_addr_copy(&flp6->saddr, &saddr); | 99 | flp6->saddr = saddr; |
100 | } | 100 | } |
101 | goto out; | 101 | goto out; |
102 | } | 102 | } |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 90868fb42757..9e2bdccf9143 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -290,9 +290,9 @@ static void mip6_addr_swap(struct sk_buff *skb) | |||
290 | if (likely(off >= 0)) { | 290 | if (likely(off >= 0)) { |
291 | hao = (struct ipv6_destopt_hao *) | 291 | hao = (struct ipv6_destopt_hao *) |
292 | (skb_network_header(skb) + off); | 292 | (skb_network_header(skb) + off); |
293 | ipv6_addr_copy(&tmp, &iph->saddr); | 293 | tmp = iph->saddr; |
294 | ipv6_addr_copy(&iph->saddr, &hao->addr); | 294 | iph->saddr = hao->addr; |
295 | ipv6_addr_copy(&hao->addr, &tmp); | 295 | hao->addr = tmp; |
296 | } | 296 | } |
297 | } | 297 | } |
298 | } | 298 | } |
@@ -444,9 +444,9 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | |||
444 | 444 | ||
445 | memset(&fl6, 0, sizeof(fl6)); | 445 | memset(&fl6, 0, sizeof(fl6)); |
446 | fl6.flowi6_proto = IPPROTO_ICMPV6; | 446 | fl6.flowi6_proto = IPPROTO_ICMPV6; |
447 | ipv6_addr_copy(&fl6.daddr, &hdr->saddr); | 447 | fl6.daddr = hdr->saddr; |
448 | if (saddr) | 448 | if (saddr) |
449 | ipv6_addr_copy(&fl6.saddr, saddr); | 449 | fl6.saddr = *saddr; |
450 | fl6.flowi6_oif = iif; | 450 | fl6.flowi6_oif = iif; |
451 | fl6.fl6_icmp_type = type; | 451 | fl6.fl6_icmp_type = type; |
452 | fl6.fl6_icmp_code = code; | 452 | fl6.fl6_icmp_code = code; |
@@ -538,9 +538,9 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
538 | 538 | ||
539 | memset(&fl6, 0, sizeof(fl6)); | 539 | memset(&fl6, 0, sizeof(fl6)); |
540 | fl6.flowi6_proto = IPPROTO_ICMPV6; | 540 | fl6.flowi6_proto = IPPROTO_ICMPV6; |
541 | ipv6_addr_copy(&fl6.daddr, &ipv6_hdr(skb)->saddr); | 541 | fl6.daddr = ipv6_hdr(skb)->saddr; |
542 | if (saddr) | 542 | if (saddr) |
543 | ipv6_addr_copy(&fl6.saddr, saddr); | 543 | fl6.saddr = *saddr; |
544 | fl6.flowi6_oif = skb->dev->ifindex; | 544 | fl6.flowi6_oif = skb->dev->ifindex; |
545 | fl6.fl6_icmp_type = ICMPV6_ECHO_REPLY; | 545 | fl6.fl6_icmp_type = ICMPV6_ECHO_REPLY; |
546 | security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); | 546 | security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); |
@@ -786,8 +786,8 @@ void icmpv6_flow_init(struct sock *sk, struct flowi6 *fl6, | |||
786 | int oif) | 786 | int oif) |
787 | { | 787 | { |
788 | memset(fl6, 0, sizeof(*fl6)); | 788 | memset(fl6, 0, sizeof(*fl6)); |
789 | ipv6_addr_copy(&fl6->saddr, saddr); | 789 | fl6->saddr = *saddr; |
790 | ipv6_addr_copy(&fl6->daddr, daddr); | 790 | fl6->daddr = *daddr; |
791 | fl6->flowi6_proto = IPPROTO_ICMPV6; | 791 | fl6->flowi6_proto = IPPROTO_ICMPV6; |
792 | fl6->fl6_icmp_type = type; | 792 | fl6->fl6_icmp_type = type; |
793 | fl6->fl6_icmp_code = 0; | 793 | fl6->fl6_icmp_code = 0; |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 1567fb120392..02dd203d9eac 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -65,9 +65,9 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, | |||
65 | 65 | ||
66 | memset(&fl6, 0, sizeof(fl6)); | 66 | memset(&fl6, 0, sizeof(fl6)); |
67 | fl6.flowi6_proto = IPPROTO_TCP; | 67 | fl6.flowi6_proto = IPPROTO_TCP; |
68 | ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr); | 68 | fl6.daddr = treq->rmt_addr; |
69 | final_p = fl6_update_dst(&fl6, np->opt, &final); | 69 | final_p = fl6_update_dst(&fl6, np->opt, &final); |
70 | ipv6_addr_copy(&fl6.saddr, &treq->loc_addr); | 70 | fl6.saddr = treq->loc_addr; |
71 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 71 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
72 | fl6.flowi6_mark = sk->sk_mark; | 72 | fl6.flowi6_mark = sk->sk_mark; |
73 | fl6.fl6_dport = inet_rsk(req)->rmt_port; | 73 | fl6.fl6_dport = inet_rsk(req)->rmt_port; |
@@ -157,7 +157,7 @@ void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr) | |||
157 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr; | 157 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr; |
158 | 158 | ||
159 | sin6->sin6_family = AF_INET6; | 159 | sin6->sin6_family = AF_INET6; |
160 | ipv6_addr_copy(&sin6->sin6_addr, &np->daddr); | 160 | sin6->sin6_addr = np->daddr; |
161 | sin6->sin6_port = inet_sk(sk)->inet_dport; | 161 | sin6->sin6_port = inet_sk(sk)->inet_dport; |
162 | /* We do not store received flowlabel for TCP */ | 162 | /* We do not store received flowlabel for TCP */ |
163 | sin6->sin6_flowinfo = 0; | 163 | sin6->sin6_flowinfo = 0; |
@@ -215,8 +215,8 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) | |||
215 | 215 | ||
216 | memset(&fl6, 0, sizeof(fl6)); | 216 | memset(&fl6, 0, sizeof(fl6)); |
217 | fl6.flowi6_proto = sk->sk_protocol; | 217 | fl6.flowi6_proto = sk->sk_protocol; |
218 | ipv6_addr_copy(&fl6.daddr, &np->daddr); | 218 | fl6.daddr = np->daddr; |
219 | ipv6_addr_copy(&fl6.saddr, &np->saddr); | 219 | fl6.saddr = np->saddr; |
220 | fl6.flowlabel = np->flow_label; | 220 | fl6.flowlabel = np->flow_label; |
221 | IP6_ECN_flow_xmit(sk, fl6.flowlabel); | 221 | IP6_ECN_flow_xmit(sk, fl6.flowlabel); |
222 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 222 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
@@ -246,7 +246,7 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) | |||
246 | skb_dst_set_noref(skb, dst); | 246 | skb_dst_set_noref(skb, dst); |
247 | 247 | ||
248 | /* Restore final destination back after routing done */ | 248 | /* Restore final destination back after routing done */ |
249 | ipv6_addr_copy(&fl6.daddr, &np->daddr); | 249 | fl6.daddr = np->daddr; |
250 | 250 | ||
251 | res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); | 251 | res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); |
252 | rcu_read_unlock(); | 252 | rcu_read_unlock(); |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 93718f3db79b..424f063fb229 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -425,7 +425,8 @@ out: | |||
425 | 425 | ||
426 | static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr, | 426 | static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr, |
427 | int addrlen, int plen, | 427 | int addrlen, int plen, |
428 | int offset) | 428 | int offset, int allow_create, |
429 | int replace_required) | ||
429 | { | 430 | { |
430 | struct fib6_node *fn, *in, *ln; | 431 | struct fib6_node *fn, *in, *ln; |
431 | struct fib6_node *pn = NULL; | 432 | struct fib6_node *pn = NULL; |
@@ -447,8 +448,18 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr, | |||
447 | * Prefix match | 448 | * Prefix match |
448 | */ | 449 | */ |
449 | if (plen < fn->fn_bit || | 450 | if (plen < fn->fn_bit || |
450 | !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit)) | 451 | !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit)) { |
452 | if (!allow_create) { | ||
453 | if (replace_required) { | ||
454 | pr_warn("IPv6: Can't replace route, " | ||
455 | "no match found\n"); | ||
456 | return ERR_PTR(-ENOENT); | ||
457 | } | ||
458 | pr_warn("IPv6: NLM_F_CREATE should be set " | ||
459 | "when creating new route\n"); | ||
460 | } | ||
451 | goto insert_above; | 461 | goto insert_above; |
462 | } | ||
452 | 463 | ||
453 | /* | 464 | /* |
454 | * Exact match ? | 465 | * Exact match ? |
@@ -477,6 +488,23 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr, | |||
477 | fn = dir ? fn->right: fn->left; | 488 | fn = dir ? fn->right: fn->left; |
478 | } while (fn); | 489 | } while (fn); |
479 | 490 | ||
491 | if (!allow_create) { | ||
492 | /* We should not create new node because | ||
493 | * NLM_F_REPLACE was specified without NLM_F_CREATE | ||
494 | * I assume it is safe to require NLM_F_CREATE when | ||
495 | * REPLACE flag is used! Later we may want to remove the | ||
496 | * check for replace_required, because according | ||
497 | * to netlink specification, NLM_F_CREATE | ||
498 | * MUST be specified if new route is created. | ||
499 | * That would keep IPv6 consistent with IPv4 | ||
500 | */ | ||
501 | if (replace_required) { | ||
502 | pr_warn("IPv6: Can't replace route, no match found\n"); | ||
503 | return ERR_PTR(-ENOENT); | ||
504 | } | ||
505 | pr_warn("IPv6: NLM_F_CREATE should be set " | ||
506 | "when creating new route\n"); | ||
507 | } | ||
480 | /* | 508 | /* |
481 | * We walked to the bottom of tree. | 509 | * We walked to the bottom of tree. |
482 | * Create new leaf node without children. | 510 | * Create new leaf node without children. |
@@ -614,6 +642,11 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
614 | { | 642 | { |
615 | struct rt6_info *iter = NULL; | 643 | struct rt6_info *iter = NULL; |
616 | struct rt6_info **ins; | 644 | struct rt6_info **ins; |
645 | int replace = (NULL != info->nlh && | ||
646 | (info->nlh->nlmsg_flags&NLM_F_REPLACE)); | ||
647 | int add = (NULL == info->nlh || | ||
648 | (info->nlh->nlmsg_flags&NLM_F_CREATE)); | ||
649 | int found = 0; | ||
617 | 650 | ||
618 | ins = &fn->leaf; | 651 | ins = &fn->leaf; |
619 | 652 | ||
@@ -626,6 +659,13 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
626 | /* | 659 | /* |
627 | * Same priority level | 660 | * Same priority level |
628 | */ | 661 | */ |
662 | if (NULL != info->nlh && | ||
663 | (info->nlh->nlmsg_flags&NLM_F_EXCL)) | ||
664 | return -EEXIST; | ||
665 | if (replace) { | ||
666 | found++; | ||
667 | break; | ||
668 | } | ||
629 | 669 | ||
630 | if (iter->rt6i_dev == rt->rt6i_dev && | 670 | if (iter->rt6i_dev == rt->rt6i_dev && |
631 | iter->rt6i_idev == rt->rt6i_idev && | 671 | iter->rt6i_idev == rt->rt6i_idev && |
@@ -655,17 +695,40 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
655 | /* | 695 | /* |
656 | * insert node | 696 | * insert node |
657 | */ | 697 | */ |
698 | if (!replace) { | ||
699 | if (!add) | ||
700 | pr_warn("IPv6: NLM_F_CREATE should be set when creating new route\n"); | ||
701 | |||
702 | add: | ||
703 | rt->dst.rt6_next = iter; | ||
704 | *ins = rt; | ||
705 | rt->rt6i_node = fn; | ||
706 | atomic_inc(&rt->rt6i_ref); | ||
707 | inet6_rt_notify(RTM_NEWROUTE, rt, info); | ||
708 | info->nl_net->ipv6.rt6_stats->fib_rt_entries++; | ||
709 | |||
710 | if ((fn->fn_flags & RTN_RTINFO) == 0) { | ||
711 | info->nl_net->ipv6.rt6_stats->fib_route_nodes++; | ||
712 | fn->fn_flags |= RTN_RTINFO; | ||
713 | } | ||
658 | 714 | ||
659 | rt->dst.rt6_next = iter; | 715 | } else { |
660 | *ins = rt; | 716 | if (!found) { |
661 | rt->rt6i_node = fn; | 717 | if (add) |
662 | atomic_inc(&rt->rt6i_ref); | 718 | goto add; |
663 | inet6_rt_notify(RTM_NEWROUTE, rt, info); | 719 | pr_warn("IPv6: NLM_F_REPLACE set, but no existing node found!\n"); |
664 | info->nl_net->ipv6.rt6_stats->fib_rt_entries++; | 720 | return -ENOENT; |
665 | 721 | } | |
666 | if ((fn->fn_flags & RTN_RTINFO) == 0) { | 722 | *ins = rt; |
667 | info->nl_net->ipv6.rt6_stats->fib_route_nodes++; | 723 | rt->rt6i_node = fn; |
668 | fn->fn_flags |= RTN_RTINFO; | 724 | rt->dst.rt6_next = iter->dst.rt6_next; |
725 | atomic_inc(&rt->rt6i_ref); | ||
726 | inet6_rt_notify(RTM_NEWROUTE, rt, info); | ||
727 | rt6_release(iter); | ||
728 | if ((fn->fn_flags & RTN_RTINFO) == 0) { | ||
729 | info->nl_net->ipv6.rt6_stats->fib_route_nodes++; | ||
730 | fn->fn_flags |= RTN_RTINFO; | ||
731 | } | ||
669 | } | 732 | } |
670 | 733 | ||
671 | return 0; | 734 | return 0; |
@@ -696,9 +759,25 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info) | |||
696 | { | 759 | { |
697 | struct fib6_node *fn, *pn = NULL; | 760 | struct fib6_node *fn, *pn = NULL; |
698 | int err = -ENOMEM; | 761 | int err = -ENOMEM; |
762 | int allow_create = 1; | ||
763 | int replace_required = 0; | ||
764 | if (NULL != info->nlh) { | ||
765 | if (!(info->nlh->nlmsg_flags&NLM_F_CREATE)) | ||
766 | allow_create = 0; | ||
767 | if ((info->nlh->nlmsg_flags&NLM_F_REPLACE)) | ||
768 | replace_required = 1; | ||
769 | } | ||
770 | if (!allow_create && !replace_required) | ||
771 | pr_warn("IPv6: RTM_NEWROUTE with no NLM_F_CREATE or NLM_F_REPLACE\n"); | ||
699 | 772 | ||
700 | fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr), | 773 | fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr), |
701 | rt->rt6i_dst.plen, offsetof(struct rt6_info, rt6i_dst)); | 774 | rt->rt6i_dst.plen, offsetof(struct rt6_info, rt6i_dst), |
775 | allow_create, replace_required); | ||
776 | |||
777 | if (IS_ERR(fn)) { | ||
778 | err = PTR_ERR(fn); | ||
779 | fn = NULL; | ||
780 | } | ||
702 | 781 | ||
703 | if (fn == NULL) | 782 | if (fn == NULL) |
704 | goto out; | 783 | goto out; |
@@ -736,7 +815,8 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info) | |||
736 | 815 | ||
737 | sn = fib6_add_1(sfn, &rt->rt6i_src.addr, | 816 | sn = fib6_add_1(sfn, &rt->rt6i_src.addr, |
738 | sizeof(struct in6_addr), rt->rt6i_src.plen, | 817 | sizeof(struct in6_addr), rt->rt6i_src.plen, |
739 | offsetof(struct rt6_info, rt6i_src)); | 818 | offsetof(struct rt6_info, rt6i_src), |
819 | allow_create, replace_required); | ||
740 | 820 | ||
741 | if (sn == NULL) { | 821 | if (sn == NULL) { |
742 | /* If it is failed, discard just allocated | 822 | /* If it is failed, discard just allocated |
@@ -753,8 +833,13 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info) | |||
753 | } else { | 833 | } else { |
754 | sn = fib6_add_1(fn->subtree, &rt->rt6i_src.addr, | 834 | sn = fib6_add_1(fn->subtree, &rt->rt6i_src.addr, |
755 | sizeof(struct in6_addr), rt->rt6i_src.plen, | 835 | sizeof(struct in6_addr), rt->rt6i_src.plen, |
756 | offsetof(struct rt6_info, rt6i_src)); | 836 | offsetof(struct rt6_info, rt6i_src), |
837 | allow_create, replace_required); | ||
757 | 838 | ||
839 | if (IS_ERR(sn)) { | ||
840 | err = PTR_ERR(sn); | ||
841 | sn = NULL; | ||
842 | } | ||
758 | if (sn == NULL) | 843 | if (sn == NULL) |
759 | goto st_failure; | 844 | goto st_failure; |
760 | } | 845 | } |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 4566dbd916d3..b7867a1215b1 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -386,7 +386,7 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq, | |||
386 | err = -EINVAL; | 386 | err = -EINVAL; |
387 | goto done; | 387 | goto done; |
388 | } | 388 | } |
389 | ipv6_addr_copy(&fl->dst, &freq->flr_dst); | 389 | fl->dst = freq->flr_dst; |
390 | atomic_set(&fl->users, 1); | 390 | atomic_set(&fl->users, 1); |
391 | switch (fl->share) { | 391 | switch (fl->share) { |
392 | case IPV6_FL_S_EXCL: | 392 | case IPV6_FL_S_EXCL: |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 84d0bd5cac93..a24e15557843 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -238,8 +238,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, | |||
238 | hdr->nexthdr = proto; | 238 | hdr->nexthdr = proto; |
239 | hdr->hop_limit = hlimit; | 239 | hdr->hop_limit = hlimit; |
240 | 240 | ||
241 | ipv6_addr_copy(&hdr->saddr, &fl6->saddr); | 241 | hdr->saddr = fl6->saddr; |
242 | ipv6_addr_copy(&hdr->daddr, first_hop); | 242 | hdr->daddr = *first_hop; |
243 | 243 | ||
244 | skb->priority = sk->sk_priority; | 244 | skb->priority = sk->sk_priority; |
245 | skb->mark = sk->sk_mark; | 245 | skb->mark = sk->sk_mark; |
@@ -290,8 +290,8 @@ int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev, | |||
290 | hdr->nexthdr = proto; | 290 | hdr->nexthdr = proto; |
291 | hdr->hop_limit = np->hop_limit; | 291 | hdr->hop_limit = np->hop_limit; |
292 | 292 | ||
293 | ipv6_addr_copy(&hdr->saddr, saddr); | 293 | hdr->saddr = *saddr; |
294 | ipv6_addr_copy(&hdr->daddr, daddr); | 294 | hdr->daddr = *daddr; |
295 | 295 | ||
296 | return 0; | 296 | return 0; |
297 | } | 297 | } |
@@ -631,6 +631,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
631 | struct ipv6hdr *tmp_hdr; | 631 | struct ipv6hdr *tmp_hdr; |
632 | struct frag_hdr *fh; | 632 | struct frag_hdr *fh; |
633 | unsigned int mtu, hlen, left, len; | 633 | unsigned int mtu, hlen, left, len; |
634 | int hroom, troom; | ||
634 | __be32 frag_id = 0; | 635 | __be32 frag_id = 0; |
635 | int ptr, offset = 0, err=0; | 636 | int ptr, offset = 0, err=0; |
636 | u8 *prevhdr, nexthdr = 0; | 637 | u8 *prevhdr, nexthdr = 0; |
@@ -797,6 +798,8 @@ slow_path: | |||
797 | */ | 798 | */ |
798 | 799 | ||
799 | *prevhdr = NEXTHDR_FRAGMENT; | 800 | *prevhdr = NEXTHDR_FRAGMENT; |
801 | hroom = LL_RESERVED_SPACE(rt->dst.dev); | ||
802 | troom = rt->dst.dev->needed_tailroom; | ||
800 | 803 | ||
801 | /* | 804 | /* |
802 | * Keep copying data until we run out. | 805 | * Keep copying data until we run out. |
@@ -815,7 +818,8 @@ slow_path: | |||
815 | * Allocate buffer. | 818 | * Allocate buffer. |
816 | */ | 819 | */ |
817 | 820 | ||
818 | if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->dst.dev), GFP_ATOMIC)) == NULL) { | 821 | if ((frag = alloc_skb(len + hlen + sizeof(struct frag_hdr) + |
822 | hroom + troom, GFP_ATOMIC)) == NULL) { | ||
819 | NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); | 823 | NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); |
820 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), | 824 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
821 | IPSTATS_MIB_FRAGFAILS); | 825 | IPSTATS_MIB_FRAGFAILS); |
@@ -828,7 +832,7 @@ slow_path: | |||
828 | */ | 832 | */ |
829 | 833 | ||
830 | ip6_copy_metadata(frag, skb); | 834 | ip6_copy_metadata(frag, skb); |
831 | skb_reserve(frag, LL_RESERVED_SPACE(rt->dst.dev)); | 835 | skb_reserve(frag, hroom); |
832 | skb_put(frag, len + hlen + sizeof(struct frag_hdr)); | 836 | skb_put(frag, len + hlen + sizeof(struct frag_hdr)); |
833 | skb_reset_network_header(frag); | 837 | skb_reset_network_header(frag); |
834 | fh = (struct frag_hdr *)(skb_network_header(frag) + hlen); | 838 | fh = (struct frag_hdr *)(skb_network_header(frag) + hlen); |
@@ -1059,7 +1063,7 @@ struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, | |||
1059 | if (err) | 1063 | if (err) |
1060 | return ERR_PTR(err); | 1064 | return ERR_PTR(err); |
1061 | if (final_dst) | 1065 | if (final_dst) |
1062 | ipv6_addr_copy(&fl6->daddr, final_dst); | 1066 | fl6->daddr = *final_dst; |
1063 | if (can_sleep) | 1067 | if (can_sleep) |
1064 | fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP; | 1068 | fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP; |
1065 | 1069 | ||
@@ -1095,7 +1099,7 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, | |||
1095 | if (err) | 1099 | if (err) |
1096 | return ERR_PTR(err); | 1100 | return ERR_PTR(err); |
1097 | if (final_dst) | 1101 | if (final_dst) |
1098 | ipv6_addr_copy(&fl6->daddr, final_dst); | 1102 | fl6->daddr = *final_dst; |
1099 | if (can_sleep) | 1103 | if (can_sleep) |
1100 | fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP; | 1104 | fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP; |
1101 | 1105 | ||
@@ -1588,7 +1592,7 @@ int ip6_push_pending_frames(struct sock *sk) | |||
1588 | if (np->pmtudisc < IPV6_PMTUDISC_DO) | 1592 | if (np->pmtudisc < IPV6_PMTUDISC_DO) |
1589 | skb->local_df = 1; | 1593 | skb->local_df = 1; |
1590 | 1594 | ||
1591 | ipv6_addr_copy(final_dst, &fl6->daddr); | 1595 | *final_dst = fl6->daddr; |
1592 | __skb_pull(skb, skb_network_header_len(skb)); | 1596 | __skb_pull(skb, skb_network_header_len(skb)); |
1593 | if (opt && opt->opt_flen) | 1597 | if (opt && opt->opt_flen) |
1594 | ipv6_push_frag_opts(skb, opt, &proto); | 1598 | ipv6_push_frag_opts(skb, opt, &proto); |
@@ -1604,8 +1608,8 @@ int ip6_push_pending_frames(struct sock *sk) | |||
1604 | 1608 | ||
1605 | hdr->hop_limit = np->cork.hop_limit; | 1609 | hdr->hop_limit = np->cork.hop_limit; |
1606 | hdr->nexthdr = proto; | 1610 | hdr->nexthdr = proto; |
1607 | ipv6_addr_copy(&hdr->saddr, &fl6->saddr); | 1611 | hdr->saddr = fl6->saddr; |
1608 | ipv6_addr_copy(&hdr->daddr, final_dst); | 1612 | hdr->daddr = *final_dst; |
1609 | 1613 | ||
1610 | skb->priority = sk->sk_priority; | 1614 | skb->priority = sk->sk_priority; |
1611 | skb->mark = sk->sk_mark; | 1615 | skb->mark = sk->sk_mark; |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 4e2e9ff67ef2..f5f98f558acb 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -93,7 +93,7 @@ struct pcpu_tstats { | |||
93 | unsigned long rx_bytes; | 93 | unsigned long rx_bytes; |
94 | unsigned long tx_packets; | 94 | unsigned long tx_packets; |
95 | unsigned long tx_bytes; | 95 | unsigned long tx_bytes; |
96 | }; | 96 | } __attribute__((aligned(4*sizeof(unsigned long)))); |
97 | 97 | ||
98 | static struct net_device_stats *ip6_get_stats(struct net_device *dev) | 98 | static struct net_device_stats *ip6_get_stats(struct net_device *dev) |
99 | { | 99 | { |
@@ -979,8 +979,8 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, | |||
979 | ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield); | 979 | ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield); |
980 | ipv6h->hop_limit = t->parms.hop_limit; | 980 | ipv6h->hop_limit = t->parms.hop_limit; |
981 | ipv6h->nexthdr = proto; | 981 | ipv6h->nexthdr = proto; |
982 | ipv6_addr_copy(&ipv6h->saddr, &fl6->saddr); | 982 | ipv6h->saddr = fl6->saddr; |
983 | ipv6_addr_copy(&ipv6h->daddr, &fl6->daddr); | 983 | ipv6h->daddr = fl6->daddr; |
984 | nf_reset(skb); | 984 | nf_reset(skb); |
985 | pkt_len = skb->len; | 985 | pkt_len = skb->len; |
986 | err = ip6_local_out(skb); | 986 | err = ip6_local_out(skb); |
@@ -1155,8 +1155,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) | |||
1155 | memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr)); | 1155 | memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr)); |
1156 | 1156 | ||
1157 | /* Set up flowi template */ | 1157 | /* Set up flowi template */ |
1158 | ipv6_addr_copy(&fl6->saddr, &p->laddr); | 1158 | fl6->saddr = p->laddr; |
1159 | ipv6_addr_copy(&fl6->daddr, &p->raddr); | 1159 | fl6->daddr = p->raddr; |
1160 | fl6->flowi6_oif = p->link; | 1160 | fl6->flowi6_oif = p->link; |
1161 | fl6->flowlabel = 0; | 1161 | fl6->flowlabel = 0; |
1162 | 1162 | ||
@@ -1212,8 +1212,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) | |||
1212 | static int | 1212 | static int |
1213 | ip6_tnl_change(struct ip6_tnl *t, struct ip6_tnl_parm *p) | 1213 | ip6_tnl_change(struct ip6_tnl *t, struct ip6_tnl_parm *p) |
1214 | { | 1214 | { |
1215 | ipv6_addr_copy(&t->parms.laddr, &p->laddr); | 1215 | t->parms.laddr = p->laddr; |
1216 | ipv6_addr_copy(&t->parms.raddr, &p->raddr); | 1216 | t->parms.raddr = p->raddr; |
1217 | t->parms.flags = p->flags; | 1217 | t->parms.flags = p->flags; |
1218 | t->parms.hop_limit = p->hop_limit; | 1218 | t->parms.hop_limit = p->hop_limit; |
1219 | t->parms.encap_limit = p->encap_limit; | 1219 | t->parms.encap_limit = p->encap_limit; |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 449a9185b8f2..c7e95c8c579f 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -1105,8 +1105,8 @@ static int ip6mr_cache_report(struct mr6_table *mrt, struct sk_buff *pkt, | |||
1105 | msg->im6_msgtype = MRT6MSG_WHOLEPKT; | 1105 | msg->im6_msgtype = MRT6MSG_WHOLEPKT; |
1106 | msg->im6_mif = mrt->mroute_reg_vif_num; | 1106 | msg->im6_mif = mrt->mroute_reg_vif_num; |
1107 | msg->im6_pad = 0; | 1107 | msg->im6_pad = 0; |
1108 | ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr); | 1108 | msg->im6_src = ipv6_hdr(pkt)->saddr; |
1109 | ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr); | 1109 | msg->im6_dst = ipv6_hdr(pkt)->daddr; |
1110 | 1110 | ||
1111 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1111 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1112 | } else | 1112 | } else |
@@ -1131,8 +1131,8 @@ static int ip6mr_cache_report(struct mr6_table *mrt, struct sk_buff *pkt, | |||
1131 | msg->im6_msgtype = assert; | 1131 | msg->im6_msgtype = assert; |
1132 | msg->im6_mif = mifi; | 1132 | msg->im6_mif = mifi; |
1133 | msg->im6_pad = 0; | 1133 | msg->im6_pad = 0; |
1134 | ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr); | 1134 | msg->im6_src = ipv6_hdr(pkt)->saddr; |
1135 | ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr); | 1135 | msg->im6_dst = ipv6_hdr(pkt)->daddr; |
1136 | 1136 | ||
1137 | skb_dst_set(skb, dst_clone(skb_dst(pkt))); | 1137 | skb_dst_set(skb, dst_clone(skb_dst(pkt))); |
1138 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1138 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -2181,8 +2181,8 @@ int ip6mr_get_route(struct net *net, | |||
2181 | iph->payload_len = 0; | 2181 | iph->payload_len = 0; |
2182 | iph->nexthdr = IPPROTO_NONE; | 2182 | iph->nexthdr = IPPROTO_NONE; |
2183 | iph->hop_limit = 0; | 2183 | iph->hop_limit = 0; |
2184 | ipv6_addr_copy(&iph->saddr, &rt->rt6i_src.addr); | 2184 | iph->saddr = rt->rt6i_src.addr; |
2185 | ipv6_addr_copy(&iph->daddr, &rt->rt6i_dst.addr); | 2185 | iph->daddr = rt->rt6i_dst.addr; |
2186 | 2186 | ||
2187 | err = ip6mr_cache_unresolved(mrt, vif, skb2); | 2187 | err = ip6mr_cache_unresolved(mrt, vif, skb2); |
2188 | read_unlock(&mrt_lock); | 2188 | read_unlock(&mrt_lock); |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index c99e3ee9781f..29993b7079a5 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -435,7 +435,7 @@ sticky_done: | |||
435 | goto e_inval; | 435 | goto e_inval; |
436 | 436 | ||
437 | np->sticky_pktinfo.ipi6_ifindex = pkt.ipi6_ifindex; | 437 | np->sticky_pktinfo.ipi6_ifindex = pkt.ipi6_ifindex; |
438 | ipv6_addr_copy(&np->sticky_pktinfo.ipi6_addr, &pkt.ipi6_addr); | 438 | np->sticky_pktinfo.ipi6_addr = pkt.ipi6_addr; |
439 | retv = 0; | 439 | retv = 0; |
440 | break; | 440 | break; |
441 | } | 441 | } |
@@ -980,8 +980,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
980 | struct in6_pktinfo src_info; | 980 | struct in6_pktinfo src_info; |
981 | src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : | 981 | src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : |
982 | np->sticky_pktinfo.ipi6_ifindex; | 982 | np->sticky_pktinfo.ipi6_ifindex; |
983 | np->mcast_oif? ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr) : | 983 | src_info.ipi6_addr = np->mcast_oif ? np->daddr : np->sticky_pktinfo.ipi6_addr; |
984 | ipv6_addr_copy(&src_info.ipi6_addr, &(np->sticky_pktinfo.ipi6_addr)); | ||
985 | put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info); | 984 | put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info); |
986 | } | 985 | } |
987 | if (np->rxopt.bits.rxhlim) { | 986 | if (np->rxopt.bits.rxhlim) { |
@@ -992,8 +991,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
992 | struct in6_pktinfo src_info; | 991 | struct in6_pktinfo src_info; |
993 | src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : | 992 | src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : |
994 | np->sticky_pktinfo.ipi6_ifindex; | 993 | np->sticky_pktinfo.ipi6_ifindex; |
995 | np->mcast_oif? ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr) : | 994 | src_info.ipi6_addr = np->mcast_oif ? np->daddr : np->sticky_pktinfo.ipi6_addr; |
996 | ipv6_addr_copy(&src_info.ipi6_addr, &(np->sticky_pktinfo.ipi6_addr)); | ||
997 | put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info); | 995 | put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info); |
998 | } | 996 | } |
999 | if (np->rxopt.bits.rxohlim) { | 997 | if (np->rxopt.bits.rxohlim) { |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index ee7839f4d6e3..6cc4d1fb8c13 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -155,7 +155,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
155 | return -ENOMEM; | 155 | return -ENOMEM; |
156 | 156 | ||
157 | mc_lst->next = NULL; | 157 | mc_lst->next = NULL; |
158 | ipv6_addr_copy(&mc_lst->addr, addr); | 158 | mc_lst->addr = *addr; |
159 | 159 | ||
160 | rcu_read_lock(); | 160 | rcu_read_lock(); |
161 | if (ifindex == 0) { | 161 | if (ifindex == 0) { |
@@ -858,7 +858,7 @@ int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr) | |||
858 | 858 | ||
859 | setup_timer(&mc->mca_timer, igmp6_timer_handler, (unsigned long)mc); | 859 | setup_timer(&mc->mca_timer, igmp6_timer_handler, (unsigned long)mc); |
860 | 860 | ||
861 | ipv6_addr_copy(&mc->mca_addr, addr); | 861 | mc->mca_addr = *addr; |
862 | mc->idev = idev; /* (reference taken) */ | 862 | mc->idev = idev; /* (reference taken) */ |
863 | mc->mca_users = 1; | 863 | mc->mca_users = 1; |
864 | /* mca_stamp should be updated upon changes */ | 864 | /* mca_stamp should be updated upon changes */ |
@@ -1343,13 +1343,15 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) | |||
1343 | struct mld2_report *pmr; | 1343 | struct mld2_report *pmr; |
1344 | struct in6_addr addr_buf; | 1344 | struct in6_addr addr_buf; |
1345 | const struct in6_addr *saddr; | 1345 | const struct in6_addr *saddr; |
1346 | int hlen = LL_RESERVED_SPACE(dev); | ||
1347 | int tlen = dev->needed_tailroom; | ||
1346 | int err; | 1348 | int err; |
1347 | u8 ra[8] = { IPPROTO_ICMPV6, 0, | 1349 | u8 ra[8] = { IPPROTO_ICMPV6, 0, |
1348 | IPV6_TLV_ROUTERALERT, 2, 0, 0, | 1350 | IPV6_TLV_ROUTERALERT, 2, 0, 0, |
1349 | IPV6_TLV_PADN, 0 }; | 1351 | IPV6_TLV_PADN, 0 }; |
1350 | 1352 | ||
1351 | /* we assume size > sizeof(ra) here */ | 1353 | /* we assume size > sizeof(ra) here */ |
1352 | size += LL_ALLOCATED_SPACE(dev); | 1354 | size += hlen + tlen; |
1353 | /* limit our allocations to order-0 page */ | 1355 | /* limit our allocations to order-0 page */ |
1354 | size = min_t(int, size, SKB_MAX_ORDER(0, 0)); | 1356 | size = min_t(int, size, SKB_MAX_ORDER(0, 0)); |
1355 | skb = sock_alloc_send_skb(sk, size, 1, &err); | 1357 | skb = sock_alloc_send_skb(sk, size, 1, &err); |
@@ -1357,7 +1359,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) | |||
1357 | if (!skb) | 1359 | if (!skb) |
1358 | return NULL; | 1360 | return NULL; |
1359 | 1361 | ||
1360 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 1362 | skb_reserve(skb, hlen); |
1361 | 1363 | ||
1362 | if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { | 1364 | if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { |
1363 | /* <draft-ietf-magma-mld-source-05.txt>: | 1365 | /* <draft-ietf-magma-mld-source-05.txt>: |
@@ -1723,6 +1725,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1723 | struct mld_msg *hdr; | 1725 | struct mld_msg *hdr; |
1724 | const struct in6_addr *snd_addr, *saddr; | 1726 | const struct in6_addr *snd_addr, *saddr; |
1725 | struct in6_addr addr_buf; | 1727 | struct in6_addr addr_buf; |
1728 | int hlen = LL_RESERVED_SPACE(dev); | ||
1729 | int tlen = dev->needed_tailroom; | ||
1726 | int err, len, payload_len, full_len; | 1730 | int err, len, payload_len, full_len; |
1727 | u8 ra[8] = { IPPROTO_ICMPV6, 0, | 1731 | u8 ra[8] = { IPPROTO_ICMPV6, 0, |
1728 | IPV6_TLV_ROUTERALERT, 2, 0, 0, | 1732 | IPV6_TLV_ROUTERALERT, 2, 0, 0, |
@@ -1744,7 +1748,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1744 | IPSTATS_MIB_OUT, full_len); | 1748 | IPSTATS_MIB_OUT, full_len); |
1745 | rcu_read_unlock(); | 1749 | rcu_read_unlock(); |
1746 | 1750 | ||
1747 | skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err); | 1751 | skb = sock_alloc_send_skb(sk, hlen + tlen + full_len, 1, &err); |
1748 | 1752 | ||
1749 | if (skb == NULL) { | 1753 | if (skb == NULL) { |
1750 | rcu_read_lock(); | 1754 | rcu_read_lock(); |
@@ -1754,7 +1758,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1754 | return; | 1758 | return; |
1755 | } | 1759 | } |
1756 | 1760 | ||
1757 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 1761 | skb_reserve(skb, hlen); |
1758 | 1762 | ||
1759 | if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { | 1763 | if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { |
1760 | /* <draft-ietf-magma-mld-source-05.txt>: | 1764 | /* <draft-ietf-magma-mld-source-05.txt>: |
@@ -1772,7 +1776,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1772 | hdr = (struct mld_msg *) skb_put(skb, sizeof(struct mld_msg)); | 1776 | hdr = (struct mld_msg *) skb_put(skb, sizeof(struct mld_msg)); |
1773 | memset(hdr, 0, sizeof(struct mld_msg)); | 1777 | memset(hdr, 0, sizeof(struct mld_msg)); |
1774 | hdr->mld_type = type; | 1778 | hdr->mld_type = type; |
1775 | ipv6_addr_copy(&hdr->mld_mca, addr); | 1779 | hdr->mld_mca = *addr; |
1776 | 1780 | ||
1777 | hdr->mld_cksum = csum_ipv6_magic(saddr, snd_addr, len, | 1781 | hdr->mld_cksum = csum_ipv6_magic(saddr, snd_addr, len, |
1778 | IPPROTO_ICMPV6, | 1782 | IPPROTO_ICMPV6, |
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index 43242e6e6103..7e1e0fbfef21 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c | |||
@@ -195,8 +195,8 @@ static inline int mip6_report_rl_allow(struct timeval *stamp, | |||
195 | mip6_report_rl.stamp.tv_sec = stamp->tv_sec; | 195 | mip6_report_rl.stamp.tv_sec = stamp->tv_sec; |
196 | mip6_report_rl.stamp.tv_usec = stamp->tv_usec; | 196 | mip6_report_rl.stamp.tv_usec = stamp->tv_usec; |
197 | mip6_report_rl.iif = iif; | 197 | mip6_report_rl.iif = iif; |
198 | ipv6_addr_copy(&mip6_report_rl.src, src); | 198 | mip6_report_rl.src = *src; |
199 | ipv6_addr_copy(&mip6_report_rl.dst, dst); | 199 | mip6_report_rl.dst = *dst; |
200 | allow = 1; | 200 | allow = 1; |
201 | } | 201 | } |
202 | spin_unlock_bh(&mip6_report_rl.lock); | 202 | spin_unlock_bh(&mip6_report_rl.lock); |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 0cb78d7ddaf5..2854705b15ea 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -141,7 +141,7 @@ struct neigh_table nd_tbl = { | |||
141 | .gc_staletime = 60 * HZ, | 141 | .gc_staletime = 60 * HZ, |
142 | .reachable_time = ND_REACHABLE_TIME, | 142 | .reachable_time = ND_REACHABLE_TIME, |
143 | .delay_probe_time = 5 * HZ, | 143 | .delay_probe_time = 5 * HZ, |
144 | .queue_len = 3, | 144 | .queue_len_bytes = 64*1024, |
145 | .ucast_probes = 3, | 145 | .ucast_probes = 3, |
146 | .mcast_probes = 3, | 146 | .mcast_probes = 3, |
147 | .anycast_delay = 1 * HZ, | 147 | .anycast_delay = 1 * HZ, |
@@ -446,6 +446,8 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev, | |||
446 | struct sock *sk = net->ipv6.ndisc_sk; | 446 | struct sock *sk = net->ipv6.ndisc_sk; |
447 | struct sk_buff *skb; | 447 | struct sk_buff *skb; |
448 | struct icmp6hdr *hdr; | 448 | struct icmp6hdr *hdr; |
449 | int hlen = LL_RESERVED_SPACE(dev); | ||
450 | int tlen = dev->needed_tailroom; | ||
449 | int len; | 451 | int len; |
450 | int err; | 452 | int err; |
451 | u8 *opt; | 453 | u8 *opt; |
@@ -459,7 +461,7 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev, | |||
459 | 461 | ||
460 | skb = sock_alloc_send_skb(sk, | 462 | skb = sock_alloc_send_skb(sk, |
461 | (MAX_HEADER + sizeof(struct ipv6hdr) + | 463 | (MAX_HEADER + sizeof(struct ipv6hdr) + |
462 | len + LL_ALLOCATED_SPACE(dev)), | 464 | len + hlen + tlen), |
463 | 1, &err); | 465 | 1, &err); |
464 | if (!skb) { | 466 | if (!skb) { |
465 | ND_PRINTK0(KERN_ERR | 467 | ND_PRINTK0(KERN_ERR |
@@ -468,7 +470,7 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev, | |||
468 | return NULL; | 470 | return NULL; |
469 | } | 471 | } |
470 | 472 | ||
471 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 473 | skb_reserve(skb, hlen); |
472 | ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len); | 474 | ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len); |
473 | 475 | ||
474 | skb->transport_header = skb->tail; | 476 | skb->transport_header = skb->tail; |
@@ -479,7 +481,7 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev, | |||
479 | 481 | ||
480 | opt = skb_transport_header(skb) + sizeof(struct icmp6hdr); | 482 | opt = skb_transport_header(skb) + sizeof(struct icmp6hdr); |
481 | if (target) { | 483 | if (target) { |
482 | ipv6_addr_copy((struct in6_addr *)opt, target); | 484 | *(struct in6_addr *)opt = *target; |
483 | opt += sizeof(*target); | 485 | opt += sizeof(*target); |
484 | } | 486 | } |
485 | 487 | ||
@@ -1533,6 +1535,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1533 | struct inet6_dev *idev; | 1535 | struct inet6_dev *idev; |
1534 | struct flowi6 fl6; | 1536 | struct flowi6 fl6; |
1535 | u8 *opt; | 1537 | u8 *opt; |
1538 | int hlen, tlen; | ||
1536 | int rd_len; | 1539 | int rd_len; |
1537 | int err; | 1540 | int err; |
1538 | u8 ha_buf[MAX_ADDR_LEN], *ha = NULL; | 1541 | u8 ha_buf[MAX_ADDR_LEN], *ha = NULL; |
@@ -1590,9 +1593,11 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1590 | rd_len &= ~0x7; | 1593 | rd_len &= ~0x7; |
1591 | len += rd_len; | 1594 | len += rd_len; |
1592 | 1595 | ||
1596 | hlen = LL_RESERVED_SPACE(dev); | ||
1597 | tlen = dev->needed_tailroom; | ||
1593 | buff = sock_alloc_send_skb(sk, | 1598 | buff = sock_alloc_send_skb(sk, |
1594 | (MAX_HEADER + sizeof(struct ipv6hdr) + | 1599 | (MAX_HEADER + sizeof(struct ipv6hdr) + |
1595 | len + LL_ALLOCATED_SPACE(dev)), | 1600 | len + hlen + tlen), |
1596 | 1, &err); | 1601 | 1, &err); |
1597 | if (buff == NULL) { | 1602 | if (buff == NULL) { |
1598 | ND_PRINTK0(KERN_ERR | 1603 | ND_PRINTK0(KERN_ERR |
@@ -1601,7 +1606,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1601 | goto release; | 1606 | goto release; |
1602 | } | 1607 | } |
1603 | 1608 | ||
1604 | skb_reserve(buff, LL_RESERVED_SPACE(dev)); | 1609 | skb_reserve(buff, hlen); |
1605 | ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr, | 1610 | ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr, |
1606 | IPPROTO_ICMPV6, len); | 1611 | IPPROTO_ICMPV6, len); |
1607 | 1612 | ||
@@ -1617,9 +1622,9 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1617 | */ | 1622 | */ |
1618 | 1623 | ||
1619 | addrp = (struct in6_addr *)(icmph + 1); | 1624 | addrp = (struct in6_addr *)(icmph + 1); |
1620 | ipv6_addr_copy(addrp, target); | 1625 | *addrp = *target; |
1621 | addrp++; | 1626 | addrp++; |
1622 | ipv6_addr_copy(addrp, &ipv6_hdr(skb)->daddr); | 1627 | *addrp = ipv6_hdr(skb)->daddr; |
1623 | 1628 | ||
1624 | opt = (u8*) (addrp + 1); | 1629 | opt = (u8*) (addrp + 1); |
1625 | 1630 | ||
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index a5a4c5dd5396..b5a2aa58a03a 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -93,8 +93,8 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) | |||
93 | 93 | ||
94 | memset(&fl6, 0, sizeof(fl6)); | 94 | memset(&fl6, 0, sizeof(fl6)); |
95 | fl6.flowi6_proto = IPPROTO_TCP; | 95 | fl6.flowi6_proto = IPPROTO_TCP; |
96 | ipv6_addr_copy(&fl6.saddr, &oip6h->daddr); | 96 | fl6.saddr = oip6h->daddr; |
97 | ipv6_addr_copy(&fl6.daddr, &oip6h->saddr); | 97 | fl6.daddr = oip6h->saddr; |
98 | fl6.fl6_sport = otcph.dest; | 98 | fl6.fl6_sport = otcph.dest; |
99 | fl6.fl6_dport = otcph.source; | 99 | fl6.fl6_dport = otcph.source; |
100 | security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6)); | 100 | security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6)); |
@@ -129,8 +129,8 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) | |||
129 | *(__be32 *)ip6h = htonl(0x60000000 | (tclass << 20)); | 129 | *(__be32 *)ip6h = htonl(0x60000000 | (tclass << 20)); |
130 | ip6h->hop_limit = ip6_dst_hoplimit(dst); | 130 | ip6h->hop_limit = ip6_dst_hoplimit(dst); |
131 | ip6h->nexthdr = IPPROTO_TCP; | 131 | ip6h->nexthdr = IPPROTO_TCP; |
132 | ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr); | 132 | ip6h->saddr = oip6h->daddr; |
133 | ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr); | 133 | ip6h->daddr = oip6h->saddr; |
134 | 134 | ||
135 | tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr)); | 135 | tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr)); |
136 | /* Truncate to length (no data) */ | 136 | /* Truncate to length (no data) */ |
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 1008ce94bc33..fdeb6d03da81 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
@@ -142,11 +142,7 @@ static const struct snmp_mib snmp6_udplite6_list[] = { | |||
142 | SNMP_MIB_SENTINEL | 142 | SNMP_MIB_SENTINEL |
143 | }; | 143 | }; |
144 | 144 | ||
145 | /* can be called either with percpu mib (pcpumib != NULL), | 145 | static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, atomic_long_t *smib) |
146 | * or shared one (smib != NULL) | ||
147 | */ | ||
148 | static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void __percpu **pcpumib, | ||
149 | atomic_long_t *smib) | ||
150 | { | 146 | { |
151 | char name[32]; | 147 | char name[32]; |
152 | int i; | 148 | int i; |
@@ -163,14 +159,14 @@ static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void __percpu **pcpum | |||
163 | snprintf(name, sizeof(name), "Icmp6%s%s", | 159 | snprintf(name, sizeof(name), "Icmp6%s%s", |
164 | i & 0x100 ? "Out" : "In", p); | 160 | i & 0x100 ? "Out" : "In", p); |
165 | seq_printf(seq, "%-32s\t%lu\n", name, | 161 | seq_printf(seq, "%-32s\t%lu\n", name, |
166 | pcpumib ? snmp_fold_field(pcpumib, i) : atomic_long_read(smib + i)); | 162 | atomic_long_read(smib + i)); |
167 | } | 163 | } |
168 | 164 | ||
169 | /* print by number (nonzero only) - ICMPMsgStat format */ | 165 | /* print by number (nonzero only) - ICMPMsgStat format */ |
170 | for (i = 0; i < ICMP6MSG_MIB_MAX; i++) { | 166 | for (i = 0; i < ICMP6MSG_MIB_MAX; i++) { |
171 | unsigned long val; | 167 | unsigned long val; |
172 | 168 | ||
173 | val = pcpumib ? snmp_fold_field(pcpumib, i) : atomic_long_read(smib + i); | 169 | val = atomic_long_read(smib + i); |
174 | if (!val) | 170 | if (!val) |
175 | continue; | 171 | continue; |
176 | snprintf(name, sizeof(name), "Icmp6%sType%u", | 172 | snprintf(name, sizeof(name), "Icmp6%sType%u", |
@@ -215,8 +211,7 @@ static int snmp6_seq_show(struct seq_file *seq, void *v) | |||
215 | snmp6_ipstats_list, offsetof(struct ipstats_mib, syncp)); | 211 | snmp6_ipstats_list, offsetof(struct ipstats_mib, syncp)); |
216 | snmp6_seq_show_item(seq, (void __percpu **)net->mib.icmpv6_statistics, | 212 | snmp6_seq_show_item(seq, (void __percpu **)net->mib.icmpv6_statistics, |
217 | NULL, snmp6_icmp6_list); | 213 | NULL, snmp6_icmp6_list); |
218 | snmp6_seq_show_icmpv6msg(seq, | 214 | snmp6_seq_show_icmpv6msg(seq, net->mib.icmpv6msg_statistics->mibs); |
219 | (void __percpu **)net->mib.icmpv6msg_statistics, NULL); | ||
220 | snmp6_seq_show_item(seq, (void __percpu **)net->mib.udp_stats_in6, | 215 | snmp6_seq_show_item(seq, (void __percpu **)net->mib.udp_stats_in6, |
221 | NULL, snmp6_udp6_list); | 216 | NULL, snmp6_udp6_list); |
222 | snmp6_seq_show_item(seq, (void __percpu **)net->mib.udplite_stats_in6, | 217 | snmp6_seq_show_item(seq, (void __percpu **)net->mib.udplite_stats_in6, |
@@ -246,7 +241,7 @@ static int snmp6_dev_seq_show(struct seq_file *seq, void *v) | |||
246 | snmp6_ipstats_list); | 241 | snmp6_ipstats_list); |
247 | snmp6_seq_show_item(seq, NULL, idev->stats.icmpv6dev->mibs, | 242 | snmp6_seq_show_item(seq, NULL, idev->stats.icmpv6dev->mibs, |
248 | snmp6_icmp6_list); | 243 | snmp6_icmp6_list); |
249 | snmp6_seq_show_icmpv6msg(seq, NULL, idev->stats.icmpv6msgdev->mibs); | 244 | snmp6_seq_show_icmpv6msg(seq, idev->stats.icmpv6msgdev->mibs); |
250 | return 0; | 245 | return 0; |
251 | } | 246 | } |
252 | 247 | ||
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 331af3b882ac..a4894f4f1944 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -299,9 +299,9 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
299 | } | 299 | } |
300 | 300 | ||
301 | inet->inet_rcv_saddr = inet->inet_saddr = v4addr; | 301 | inet->inet_rcv_saddr = inet->inet_saddr = v4addr; |
302 | ipv6_addr_copy(&np->rcv_saddr, &addr->sin6_addr); | 302 | np->rcv_saddr = addr->sin6_addr; |
303 | if (!(addr_type & IPV6_ADDR_MULTICAST)) | 303 | if (!(addr_type & IPV6_ADDR_MULTICAST)) |
304 | ipv6_addr_copy(&np->saddr, &addr->sin6_addr); | 304 | np->saddr = addr->sin6_addr; |
305 | err = 0; | 305 | err = 0; |
306 | out_unlock: | 306 | out_unlock: |
307 | rcu_read_unlock(); | 307 | rcu_read_unlock(); |
@@ -383,7 +383,8 @@ static inline int rawv6_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
383 | } | 383 | } |
384 | 384 | ||
385 | /* Charge it to the socket. */ | 385 | /* Charge it to the socket. */ |
386 | if (ip_queue_rcv_skb(sk, skb) < 0) { | 386 | skb_dst_drop(skb); |
387 | if (sock_queue_rcv_skb(sk, skb) < 0) { | ||
387 | kfree_skb(skb); | 388 | kfree_skb(skb); |
388 | return NET_RX_DROP; | 389 | return NET_RX_DROP; |
389 | } | 390 | } |
@@ -494,7 +495,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
494 | if (sin6) { | 495 | if (sin6) { |
495 | sin6->sin6_family = AF_INET6; | 496 | sin6->sin6_family = AF_INET6; |
496 | sin6->sin6_port = 0; | 497 | sin6->sin6_port = 0; |
497 | ipv6_addr_copy(&sin6->sin6_addr, &ipv6_hdr(skb)->saddr); | 498 | sin6->sin6_addr = ipv6_hdr(skb)->saddr; |
498 | sin6->sin6_flowinfo = 0; | 499 | sin6->sin6_flowinfo = 0; |
499 | sin6->sin6_scope_id = 0; | 500 | sin6->sin6_scope_id = 0; |
500 | if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) | 501 | if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) |
@@ -610,6 +611,8 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, | |||
610 | struct sk_buff *skb; | 611 | struct sk_buff *skb; |
611 | int err; | 612 | int err; |
612 | struct rt6_info *rt = (struct rt6_info *)*dstp; | 613 | struct rt6_info *rt = (struct rt6_info *)*dstp; |
614 | int hlen = LL_RESERVED_SPACE(rt->dst.dev); | ||
615 | int tlen = rt->dst.dev->needed_tailroom; | ||
613 | 616 | ||
614 | if (length > rt->dst.dev->mtu) { | 617 | if (length > rt->dst.dev->mtu) { |
615 | ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu); | 618 | ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu); |
@@ -619,11 +622,11 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, | |||
619 | goto out; | 622 | goto out; |
620 | 623 | ||
621 | skb = sock_alloc_send_skb(sk, | 624 | skb = sock_alloc_send_skb(sk, |
622 | length + LL_ALLOCATED_SPACE(rt->dst.dev) + 15, | 625 | length + hlen + tlen + 15, |
623 | flags & MSG_DONTWAIT, &err); | 626 | flags & MSG_DONTWAIT, &err); |
624 | if (skb == NULL) | 627 | if (skb == NULL) |
625 | goto error; | 628 | goto error; |
626 | skb_reserve(skb, LL_RESERVED_SPACE(rt->dst.dev)); | 629 | skb_reserve(skb, hlen); |
627 | 630 | ||
628 | skb->priority = sk->sk_priority; | 631 | skb->priority = sk->sk_priority; |
629 | skb->mark = sk->sk_mark; | 632 | skb->mark = sk->sk_mark; |
@@ -843,11 +846,11 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
843 | goto out; | 846 | goto out; |
844 | 847 | ||
845 | if (!ipv6_addr_any(daddr)) | 848 | if (!ipv6_addr_any(daddr)) |
846 | ipv6_addr_copy(&fl6.daddr, daddr); | 849 | fl6.daddr = *daddr; |
847 | else | 850 | else |
848 | fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ | 851 | fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ |
849 | if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) | 852 | if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) |
850 | ipv6_addr_copy(&fl6.saddr, &np->saddr); | 853 | fl6.saddr = np->saddr; |
851 | 854 | ||
852 | final_p = fl6_update_dst(&fl6, opt, &final); | 855 | final_p = fl6_update_dst(&fl6, opt, &final); |
853 | 856 | ||
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index dfb164e9051a..b69fae76a6f1 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -153,8 +153,8 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a) | |||
153 | 153 | ||
154 | fq->id = arg->id; | 154 | fq->id = arg->id; |
155 | fq->user = arg->user; | 155 | fq->user = arg->user; |
156 | ipv6_addr_copy(&fq->saddr, arg->src); | 156 | fq->saddr = *arg->src; |
157 | ipv6_addr_copy(&fq->daddr, arg->dst); | 157 | fq->daddr = *arg->dst; |
158 | } | 158 | } |
159 | EXPORT_SYMBOL(ip6_frag_init); | 159 | EXPORT_SYMBOL(ip6_frag_init); |
160 | 160 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 3399dd326287..0e381bb94683 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -731,14 +731,14 @@ static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort, | |||
731 | if (rt->rt6i_dst.plen != 128 && | 731 | if (rt->rt6i_dst.plen != 128 && |
732 | ipv6_addr_equal(&ort->rt6i_dst.addr, daddr)) | 732 | ipv6_addr_equal(&ort->rt6i_dst.addr, daddr)) |
733 | rt->rt6i_flags |= RTF_ANYCAST; | 733 | rt->rt6i_flags |= RTF_ANYCAST; |
734 | ipv6_addr_copy(&rt->rt6i_gateway, daddr); | 734 | rt->rt6i_gateway = *daddr; |
735 | } | 735 | } |
736 | 736 | ||
737 | rt->rt6i_flags |= RTF_CACHE; | 737 | rt->rt6i_flags |= RTF_CACHE; |
738 | 738 | ||
739 | #ifdef CONFIG_IPV6_SUBTREES | 739 | #ifdef CONFIG_IPV6_SUBTREES |
740 | if (rt->rt6i_src.plen && saddr) { | 740 | if (rt->rt6i_src.plen && saddr) { |
741 | ipv6_addr_copy(&rt->rt6i_src.addr, saddr); | 741 | rt->rt6i_src.addr = *saddr; |
742 | rt->rt6i_src.plen = 128; | 742 | rt->rt6i_src.plen = 128; |
743 | } | 743 | } |
744 | #endif | 744 | #endif |
@@ -934,7 +934,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori | |||
934 | in6_dev_hold(rt->rt6i_idev); | 934 | in6_dev_hold(rt->rt6i_idev); |
935 | rt->rt6i_expires = 0; | 935 | rt->rt6i_expires = 0; |
936 | 936 | ||
937 | ipv6_addr_copy(&rt->rt6i_gateway, &ort->rt6i_gateway); | 937 | rt->rt6i_gateway = ort->rt6i_gateway; |
938 | rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; | 938 | rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; |
939 | rt->rt6i_metric = 0; | 939 | rt->rt6i_metric = 0; |
940 | 940 | ||
@@ -1094,7 +1094,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
1094 | rt->dst.output = ip6_output; | 1094 | rt->dst.output = ip6_output; |
1095 | dst_set_neighbour(&rt->dst, neigh); | 1095 | dst_set_neighbour(&rt->dst, neigh); |
1096 | atomic_set(&rt->dst.__refcnt, 1); | 1096 | atomic_set(&rt->dst.__refcnt, 1); |
1097 | ipv6_addr_copy(&rt->rt6i_dst.addr, addr); | 1097 | rt->rt6i_dst.addr = *addr; |
1098 | rt->rt6i_dst.plen = 128; | 1098 | rt->rt6i_dst.plen = 128; |
1099 | rt->rt6i_idev = idev; | 1099 | rt->rt6i_idev = idev; |
1100 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); | 1100 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); |
@@ -1237,9 +1237,18 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1237 | if (cfg->fc_metric == 0) | 1237 | if (cfg->fc_metric == 0) |
1238 | cfg->fc_metric = IP6_RT_PRIO_USER; | 1238 | cfg->fc_metric = IP6_RT_PRIO_USER; |
1239 | 1239 | ||
1240 | table = fib6_new_table(net, cfg->fc_table); | 1240 | err = -ENOBUFS; |
1241 | if (NULL != cfg->fc_nlinfo.nlh && | ||
1242 | !(cfg->fc_nlinfo.nlh->nlmsg_flags&NLM_F_CREATE)) { | ||
1243 | table = fib6_get_table(net, cfg->fc_table); | ||
1244 | if (table == NULL) { | ||
1245 | printk(KERN_WARNING "IPv6: NLM_F_CREATE should be specified when creating new route\n"); | ||
1246 | table = fib6_new_table(net, cfg->fc_table); | ||
1247 | } | ||
1248 | } else { | ||
1249 | table = fib6_new_table(net, cfg->fc_table); | ||
1250 | } | ||
1241 | if (table == NULL) { | 1251 | if (table == NULL) { |
1242 | err = -ENOBUFS; | ||
1243 | goto out; | 1252 | goto out; |
1244 | } | 1253 | } |
1245 | 1254 | ||
@@ -1322,7 +1331,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1322 | int gwa_type; | 1331 | int gwa_type; |
1323 | 1332 | ||
1324 | gw_addr = &cfg->fc_gateway; | 1333 | gw_addr = &cfg->fc_gateway; |
1325 | ipv6_addr_copy(&rt->rt6i_gateway, gw_addr); | 1334 | rt->rt6i_gateway = *gw_addr; |
1326 | gwa_type = ipv6_addr_type(gw_addr); | 1335 | gwa_type = ipv6_addr_type(gw_addr); |
1327 | 1336 | ||
1328 | if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) { | 1337 | if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) { |
@@ -1376,7 +1385,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1376 | err = -EINVAL; | 1385 | err = -EINVAL; |
1377 | goto out; | 1386 | goto out; |
1378 | } | 1387 | } |
1379 | ipv6_addr_copy(&rt->rt6i_prefsrc.addr, &cfg->fc_prefsrc); | 1388 | rt->rt6i_prefsrc.addr = cfg->fc_prefsrc; |
1380 | rt->rt6i_prefsrc.plen = 128; | 1389 | rt->rt6i_prefsrc.plen = 128; |
1381 | } else | 1390 | } else |
1382 | rt->rt6i_prefsrc.plen = 0; | 1391 | rt->rt6i_prefsrc.plen = 0; |
@@ -1573,7 +1582,7 @@ static struct rt6_info *ip6_route_redirect(const struct in6_addr *dest, | |||
1573 | }, | 1582 | }, |
1574 | }; | 1583 | }; |
1575 | 1584 | ||
1576 | ipv6_addr_copy(&rdfl.gateway, gateway); | 1585 | rdfl.gateway = *gateway; |
1577 | 1586 | ||
1578 | if (rt6_need_strict(dest)) | 1587 | if (rt6_need_strict(dest)) |
1579 | flags |= RT6_LOOKUP_F_IFACE; | 1588 | flags |= RT6_LOOKUP_F_IFACE; |
@@ -1629,7 +1638,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, | |||
1629 | if (on_link) | 1638 | if (on_link) |
1630 | nrt->rt6i_flags &= ~RTF_GATEWAY; | 1639 | nrt->rt6i_flags &= ~RTF_GATEWAY; |
1631 | 1640 | ||
1632 | ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key); | 1641 | nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key; |
1633 | dst_set_neighbour(&nrt->dst, neigh_clone(neigh)); | 1642 | dst_set_neighbour(&nrt->dst, neigh_clone(neigh)); |
1634 | 1643 | ||
1635 | if (ip6_ins_rt(nrt)) | 1644 | if (ip6_ins_rt(nrt)) |
@@ -1775,7 +1784,7 @@ static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, | |||
1775 | rt->dst.output = ort->dst.output; | 1784 | rt->dst.output = ort->dst.output; |
1776 | rt->dst.flags |= DST_HOST; | 1785 | rt->dst.flags |= DST_HOST; |
1777 | 1786 | ||
1778 | ipv6_addr_copy(&rt->rt6i_dst.addr, dest); | 1787 | rt->rt6i_dst.addr = *dest; |
1779 | rt->rt6i_dst.plen = 128; | 1788 | rt->rt6i_dst.plen = 128; |
1780 | dst_copy_metrics(&rt->dst, &ort->dst); | 1789 | dst_copy_metrics(&rt->dst, &ort->dst); |
1781 | rt->dst.error = ort->dst.error; | 1790 | rt->dst.error = ort->dst.error; |
@@ -1785,7 +1794,7 @@ static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, | |||
1785 | rt->dst.lastuse = jiffies; | 1794 | rt->dst.lastuse = jiffies; |
1786 | rt->rt6i_expires = 0; | 1795 | rt->rt6i_expires = 0; |
1787 | 1796 | ||
1788 | ipv6_addr_copy(&rt->rt6i_gateway, &ort->rt6i_gateway); | 1797 | rt->rt6i_gateway = ort->rt6i_gateway; |
1789 | rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; | 1798 | rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; |
1790 | rt->rt6i_metric = 0; | 1799 | rt->rt6i_metric = 0; |
1791 | 1800 | ||
@@ -1848,8 +1857,8 @@ static struct rt6_info *rt6_add_route_info(struct net *net, | |||
1848 | .fc_nlinfo.nl_net = net, | 1857 | .fc_nlinfo.nl_net = net, |
1849 | }; | 1858 | }; |
1850 | 1859 | ||
1851 | ipv6_addr_copy(&cfg.fc_dst, prefix); | 1860 | cfg.fc_dst = *prefix; |
1852 | ipv6_addr_copy(&cfg.fc_gateway, gwaddr); | 1861 | cfg.fc_gateway = *gwaddr; |
1853 | 1862 | ||
1854 | /* We should treat it as a default route if prefix length is 0. */ | 1863 | /* We should treat it as a default route if prefix length is 0. */ |
1855 | if (!prefixlen) | 1864 | if (!prefixlen) |
@@ -1898,7 +1907,7 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr, | |||
1898 | .fc_nlinfo.nl_net = dev_net(dev), | 1907 | .fc_nlinfo.nl_net = dev_net(dev), |
1899 | }; | 1908 | }; |
1900 | 1909 | ||
1901 | ipv6_addr_copy(&cfg.fc_gateway, gwaddr); | 1910 | cfg.fc_gateway = *gwaddr; |
1902 | 1911 | ||
1903 | ip6_route_add(&cfg); | 1912 | ip6_route_add(&cfg); |
1904 | 1913 | ||
@@ -1944,9 +1953,9 @@ static void rtmsg_to_fib6_config(struct net *net, | |||
1944 | 1953 | ||
1945 | cfg->fc_nlinfo.nl_net = net; | 1954 | cfg->fc_nlinfo.nl_net = net; |
1946 | 1955 | ||
1947 | ipv6_addr_copy(&cfg->fc_dst, &rtmsg->rtmsg_dst); | 1956 | cfg->fc_dst = rtmsg->rtmsg_dst; |
1948 | ipv6_addr_copy(&cfg->fc_src, &rtmsg->rtmsg_src); | 1957 | cfg->fc_src = rtmsg->rtmsg_src; |
1949 | ipv6_addr_copy(&cfg->fc_gateway, &rtmsg->rtmsg_gateway); | 1958 | cfg->fc_gateway = rtmsg->rtmsg_gateway; |
1950 | } | 1959 | } |
1951 | 1960 | ||
1952 | int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg) | 1961 | int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg) |
@@ -2080,7 +2089,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
2080 | } | 2089 | } |
2081 | dst_set_neighbour(&rt->dst, neigh); | 2090 | dst_set_neighbour(&rt->dst, neigh); |
2082 | 2091 | ||
2083 | ipv6_addr_copy(&rt->rt6i_dst.addr, addr); | 2092 | rt->rt6i_dst.addr = *addr; |
2084 | rt->rt6i_dst.plen = 128; | 2093 | rt->rt6i_dst.plen = 128; |
2085 | rt->rt6i_table = fib6_get_table(net, RT6_TABLE_LOCAL); | 2094 | rt->rt6i_table = fib6_get_table(net, RT6_TABLE_LOCAL); |
2086 | 2095 | ||
@@ -2098,7 +2107,7 @@ int ip6_route_get_saddr(struct net *net, | |||
2098 | struct inet6_dev *idev = ip6_dst_idev((struct dst_entry*)rt); | 2107 | struct inet6_dev *idev = ip6_dst_idev((struct dst_entry*)rt); |
2099 | int err = 0; | 2108 | int err = 0; |
2100 | if (rt->rt6i_prefsrc.plen) | 2109 | if (rt->rt6i_prefsrc.plen) |
2101 | ipv6_addr_copy(saddr, &rt->rt6i_prefsrc.addr); | 2110 | *saddr = rt->rt6i_prefsrc.addr; |
2102 | else | 2111 | else |
2103 | err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL, | 2112 | err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL, |
2104 | daddr, prefs, saddr); | 2113 | daddr, prefs, saddr); |
@@ -2437,7 +2446,7 @@ static int rt6_fill_node(struct net *net, | |||
2437 | 2446 | ||
2438 | if (rt->rt6i_prefsrc.plen) { | 2447 | if (rt->rt6i_prefsrc.plen) { |
2439 | struct in6_addr saddr_buf; | 2448 | struct in6_addr saddr_buf; |
2440 | ipv6_addr_copy(&saddr_buf, &rt->rt6i_prefsrc.addr); | 2449 | saddr_buf = rt->rt6i_prefsrc.addr; |
2441 | NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); | 2450 | NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); |
2442 | } | 2451 | } |
2443 | 2452 | ||
@@ -2511,14 +2520,14 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
2511 | if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr)) | 2520 | if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr)) |
2512 | goto errout; | 2521 | goto errout; |
2513 | 2522 | ||
2514 | ipv6_addr_copy(&fl6.saddr, nla_data(tb[RTA_SRC])); | 2523 | fl6.saddr = *(struct in6_addr *)nla_data(tb[RTA_SRC]); |
2515 | } | 2524 | } |
2516 | 2525 | ||
2517 | if (tb[RTA_DST]) { | 2526 | if (tb[RTA_DST]) { |
2518 | if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr)) | 2527 | if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr)) |
2519 | goto errout; | 2528 | goto errout; |
2520 | 2529 | ||
2521 | ipv6_addr_copy(&fl6.daddr, nla_data(tb[RTA_DST])); | 2530 | fl6.daddr = *(struct in6_addr *)nla_data(tb[RTA_DST]); |
2522 | } | 2531 | } |
2523 | 2532 | ||
2524 | if (tb[RTA_IIF]) | 2533 | if (tb[RTA_IIF]) |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index a7a18602a046..50968f226e75 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -91,7 +91,7 @@ struct pcpu_tstats { | |||
91 | unsigned long rx_bytes; | 91 | unsigned long rx_bytes; |
92 | unsigned long tx_packets; | 92 | unsigned long tx_packets; |
93 | unsigned long tx_bytes; | 93 | unsigned long tx_bytes; |
94 | }; | 94 | } __attribute__((aligned(4*sizeof(unsigned long)))); |
95 | 95 | ||
96 | static struct net_device_stats *ipip6_get_stats(struct net_device *dev) | 96 | static struct net_device_stats *ipip6_get_stats(struct net_device *dev) |
97 | { | 97 | { |
@@ -914,7 +914,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
914 | goto done; | 914 | goto done; |
915 | #ifdef CONFIG_IPV6_SIT_6RD | 915 | #ifdef CONFIG_IPV6_SIT_6RD |
916 | } else { | 916 | } else { |
917 | ipv6_addr_copy(&ip6rd.prefix, &t->ip6rd.prefix); | 917 | ip6rd.prefix = t->ip6rd.prefix; |
918 | ip6rd.relay_prefix = t->ip6rd.relay_prefix; | 918 | ip6rd.relay_prefix = t->ip6rd.relay_prefix; |
919 | ip6rd.prefixlen = t->ip6rd.prefixlen; | 919 | ip6rd.prefixlen = t->ip6rd.prefixlen; |
920 | ip6rd.relay_prefixlen = t->ip6rd.relay_prefixlen; | 920 | ip6rd.relay_prefixlen = t->ip6rd.relay_prefixlen; |
@@ -1082,7 +1082,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1082 | if (relay_prefix != ip6rd.relay_prefix) | 1082 | if (relay_prefix != ip6rd.relay_prefix) |
1083 | goto done; | 1083 | goto done; |
1084 | 1084 | ||
1085 | ipv6_addr_copy(&t->ip6rd.prefix, &prefix); | 1085 | t->ip6rd.prefix = prefix; |
1086 | t->ip6rd.relay_prefix = relay_prefix; | 1086 | t->ip6rd.relay_prefix = relay_prefix; |
1087 | t->ip6rd.prefixlen = ip6rd.prefixlen; | 1087 | t->ip6rd.prefixlen = ip6rd.prefixlen; |
1088 | t->ip6rd.relay_prefixlen = ip6rd.relay_prefixlen; | 1088 | t->ip6rd.relay_prefixlen = ip6rd.relay_prefixlen; |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 5a0d6648bbbc..8e951d8d3b81 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
@@ -200,8 +200,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
200 | req->mss = mss; | 200 | req->mss = mss; |
201 | ireq->rmt_port = th->source; | 201 | ireq->rmt_port = th->source; |
202 | ireq->loc_port = th->dest; | 202 | ireq->loc_port = th->dest; |
203 | ipv6_addr_copy(&ireq6->rmt_addr, &ipv6_hdr(skb)->saddr); | 203 | ireq6->rmt_addr = ipv6_hdr(skb)->saddr; |
204 | ipv6_addr_copy(&ireq6->loc_addr, &ipv6_hdr(skb)->daddr); | 204 | ireq6->loc_addr = ipv6_hdr(skb)->daddr; |
205 | if (ipv6_opt_accepted(sk, skb) || | 205 | if (ipv6_opt_accepted(sk, skb) || |
206 | np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || | 206 | np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || |
207 | np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { | 207 | np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { |
@@ -237,9 +237,9 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
237 | struct flowi6 fl6; | 237 | struct flowi6 fl6; |
238 | memset(&fl6, 0, sizeof(fl6)); | 238 | memset(&fl6, 0, sizeof(fl6)); |
239 | fl6.flowi6_proto = IPPROTO_TCP; | 239 | fl6.flowi6_proto = IPPROTO_TCP; |
240 | ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr); | 240 | fl6.daddr = ireq6->rmt_addr; |
241 | final_p = fl6_update_dst(&fl6, np->opt, &final); | 241 | final_p = fl6_update_dst(&fl6, np->opt, &final); |
242 | ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr); | 242 | fl6.saddr = ireq6->loc_addr; |
243 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 243 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
244 | fl6.flowi6_mark = sk->sk_mark; | 244 | fl6.flowi6_mark = sk->sk_mark; |
245 | fl6.fl6_dport = inet_rsk(req)->rmt_port; | 245 | fl6.fl6_dport = inet_rsk(req)->rmt_port; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 2dea4bb7b54a..9d74eee334d6 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -153,7 +153,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
153 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 153 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
154 | if (flowlabel == NULL) | 154 | if (flowlabel == NULL) |
155 | return -EINVAL; | 155 | return -EINVAL; |
156 | ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst); | 156 | usin->sin6_addr = flowlabel->dst; |
157 | fl6_sock_release(flowlabel); | 157 | fl6_sock_release(flowlabel); |
158 | } | 158 | } |
159 | } | 159 | } |
@@ -195,7 +195,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
195 | tp->write_seq = 0; | 195 | tp->write_seq = 0; |
196 | } | 196 | } |
197 | 197 | ||
198 | ipv6_addr_copy(&np->daddr, &usin->sin6_addr); | 198 | np->daddr = usin->sin6_addr; |
199 | np->flow_label = fl6.flowlabel; | 199 | np->flow_label = fl6.flowlabel; |
200 | 200 | ||
201 | /* | 201 | /* |
@@ -244,9 +244,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
244 | saddr = &np->rcv_saddr; | 244 | saddr = &np->rcv_saddr; |
245 | 245 | ||
246 | fl6.flowi6_proto = IPPROTO_TCP; | 246 | fl6.flowi6_proto = IPPROTO_TCP; |
247 | ipv6_addr_copy(&fl6.daddr, &np->daddr); | 247 | fl6.daddr = np->daddr; |
248 | ipv6_addr_copy(&fl6.saddr, | 248 | fl6.saddr = saddr ? *saddr : np->saddr; |
249 | (saddr ? saddr : &np->saddr)); | ||
250 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 249 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
251 | fl6.flowi6_mark = sk->sk_mark; | 250 | fl6.flowi6_mark = sk->sk_mark; |
252 | fl6.fl6_dport = usin->sin6_port; | 251 | fl6.fl6_dport = usin->sin6_port; |
@@ -264,11 +263,11 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
264 | 263 | ||
265 | if (saddr == NULL) { | 264 | if (saddr == NULL) { |
266 | saddr = &fl6.saddr; | 265 | saddr = &fl6.saddr; |
267 | ipv6_addr_copy(&np->rcv_saddr, saddr); | 266 | np->rcv_saddr = *saddr; |
268 | } | 267 | } |
269 | 268 | ||
270 | /* set the source address */ | 269 | /* set the source address */ |
271 | ipv6_addr_copy(&np->saddr, saddr); | 270 | np->saddr = *saddr; |
272 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; | 271 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; |
273 | 272 | ||
274 | sk->sk_gso_type = SKB_GSO_TCPV6; | 273 | sk->sk_gso_type = SKB_GSO_TCPV6; |
@@ -398,8 +397,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
398 | */ | 397 | */ |
399 | memset(&fl6, 0, sizeof(fl6)); | 398 | memset(&fl6, 0, sizeof(fl6)); |
400 | fl6.flowi6_proto = IPPROTO_TCP; | 399 | fl6.flowi6_proto = IPPROTO_TCP; |
401 | ipv6_addr_copy(&fl6.daddr, &np->daddr); | 400 | fl6.daddr = np->daddr; |
402 | ipv6_addr_copy(&fl6.saddr, &np->saddr); | 401 | fl6.saddr = np->saddr; |
403 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 402 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
404 | fl6.flowi6_mark = sk->sk_mark; | 403 | fl6.flowi6_mark = sk->sk_mark; |
405 | fl6.fl6_dport = inet->inet_dport; | 404 | fl6.fl6_dport = inet->inet_dport; |
@@ -489,8 +488,8 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
489 | 488 | ||
490 | memset(&fl6, 0, sizeof(fl6)); | 489 | memset(&fl6, 0, sizeof(fl6)); |
491 | fl6.flowi6_proto = IPPROTO_TCP; | 490 | fl6.flowi6_proto = IPPROTO_TCP; |
492 | ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr); | 491 | fl6.daddr = treq->rmt_addr; |
493 | ipv6_addr_copy(&fl6.saddr, &treq->loc_addr); | 492 | fl6.saddr = treq->loc_addr; |
494 | fl6.flowlabel = 0; | 493 | fl6.flowlabel = 0; |
495 | fl6.flowi6_oif = treq->iif; | 494 | fl6.flowi6_oif = treq->iif; |
496 | fl6.flowi6_mark = sk->sk_mark; | 495 | fl6.flowi6_mark = sk->sk_mark; |
@@ -512,7 +511,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
512 | if (skb) { | 511 | if (skb) { |
513 | __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); | 512 | __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); |
514 | 513 | ||
515 | ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr); | 514 | fl6.daddr = treq->rmt_addr; |
516 | err = ip6_xmit(sk, skb, &fl6, opt, np->tclass); | 515 | err = ip6_xmit(sk, skb, &fl6, opt, np->tclass); |
517 | err = net_xmit_eval(err); | 516 | err = net_xmit_eval(err); |
518 | } | 517 | } |
@@ -617,8 +616,7 @@ static int tcp_v6_md5_do_add(struct sock *sk, const struct in6_addr *peer, | |||
617 | tp->md5sig_info->alloced6++; | 616 | tp->md5sig_info->alloced6++; |
618 | } | 617 | } |
619 | 618 | ||
620 | ipv6_addr_copy(&tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr, | 619 | tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr = *peer; |
621 | peer); | ||
622 | tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.key = newkey; | 620 | tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.key = newkey; |
623 | tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.keylen = newkeylen; | 621 | tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.keylen = newkeylen; |
624 | 622 | ||
@@ -750,8 +748,8 @@ static int tcp_v6_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp, | |||
750 | 748 | ||
751 | bp = &hp->md5_blk.ip6; | 749 | bp = &hp->md5_blk.ip6; |
752 | /* 1. TCP pseudo-header (RFC2460) */ | 750 | /* 1. TCP pseudo-header (RFC2460) */ |
753 | ipv6_addr_copy(&bp->saddr, saddr); | 751 | bp->saddr = *saddr; |
754 | ipv6_addr_copy(&bp->daddr, daddr); | 752 | bp->daddr = *daddr; |
755 | bp->protocol = cpu_to_be32(IPPROTO_TCP); | 753 | bp->protocol = cpu_to_be32(IPPROTO_TCP); |
756 | bp->len = cpu_to_be32(nbytes); | 754 | bp->len = cpu_to_be32(nbytes); |
757 | 755 | ||
@@ -1039,8 +1037,8 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
1039 | #endif | 1037 | #endif |
1040 | 1038 | ||
1041 | memset(&fl6, 0, sizeof(fl6)); | 1039 | memset(&fl6, 0, sizeof(fl6)); |
1042 | ipv6_addr_copy(&fl6.daddr, &ipv6_hdr(skb)->saddr); | 1040 | fl6.daddr = ipv6_hdr(skb)->saddr; |
1043 | ipv6_addr_copy(&fl6.saddr, &ipv6_hdr(skb)->daddr); | 1041 | fl6.saddr = ipv6_hdr(skb)->daddr; |
1044 | 1042 | ||
1045 | buff->ip_summed = CHECKSUM_PARTIAL; | 1043 | buff->ip_summed = CHECKSUM_PARTIAL; |
1046 | buff->csum = 0; | 1044 | buff->csum = 0; |
@@ -1250,8 +1248,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1250 | tcp_openreq_init(req, &tmp_opt, skb); | 1248 | tcp_openreq_init(req, &tmp_opt, skb); |
1251 | 1249 | ||
1252 | treq = inet6_rsk(req); | 1250 | treq = inet6_rsk(req); |
1253 | ipv6_addr_copy(&treq->rmt_addr, &ipv6_hdr(skb)->saddr); | 1251 | treq->rmt_addr = ipv6_hdr(skb)->saddr; |
1254 | ipv6_addr_copy(&treq->loc_addr, &ipv6_hdr(skb)->daddr); | 1252 | treq->loc_addr = ipv6_hdr(skb)->daddr; |
1255 | if (!want_cookie || tmp_opt.tstamp_ok) | 1253 | if (!want_cookie || tmp_opt.tstamp_ok) |
1256 | TCP_ECN_create_request(req, tcp_hdr(skb)); | 1254 | TCP_ECN_create_request(req, tcp_hdr(skb)); |
1257 | 1255 | ||
@@ -1381,7 +1379,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1381 | 1379 | ||
1382 | ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr); | 1380 | ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr); |
1383 | 1381 | ||
1384 | ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr); | 1382 | newnp->rcv_saddr = newnp->saddr; |
1385 | 1383 | ||
1386 | inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; | 1384 | inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; |
1387 | newsk->sk_backlog_rcv = tcp_v4_do_rcv; | 1385 | newsk->sk_backlog_rcv = tcp_v4_do_rcv; |
@@ -1445,9 +1443,9 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1445 | 1443 | ||
1446 | memcpy(newnp, np, sizeof(struct ipv6_pinfo)); | 1444 | memcpy(newnp, np, sizeof(struct ipv6_pinfo)); |
1447 | 1445 | ||
1448 | ipv6_addr_copy(&newnp->daddr, &treq->rmt_addr); | 1446 | newnp->daddr = treq->rmt_addr; |
1449 | ipv6_addr_copy(&newnp->saddr, &treq->loc_addr); | 1447 | newnp->saddr = treq->loc_addr; |
1450 | ipv6_addr_copy(&newnp->rcv_saddr, &treq->loc_addr); | 1448 | newnp->rcv_saddr = treq->loc_addr; |
1451 | newsk->sk_bound_dev_if = treq->iif; | 1449 | newsk->sk_bound_dev_if = treq->iif; |
1452 | 1450 | ||
1453 | /* Now IPv6 options... | 1451 | /* Now IPv6 options... |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 846f4757eb8d..84ec9db86ee0 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -417,8 +417,7 @@ try_again: | |||
417 | ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, | 417 | ipv6_addr_set_v4mapped(ip_hdr(skb)->saddr, |
418 | &sin6->sin6_addr); | 418 | &sin6->sin6_addr); |
419 | else { | 419 | else { |
420 | ipv6_addr_copy(&sin6->sin6_addr, | 420 | sin6->sin6_addr = ipv6_hdr(skb)->saddr; |
421 | &ipv6_hdr(skb)->saddr); | ||
422 | if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) | 421 | if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) |
423 | sin6->sin6_scope_id = IP6CB(skb)->iif; | 422 | sin6->sin6_scope_id = IP6CB(skb)->iif; |
424 | } | 423 | } |
@@ -538,7 +537,9 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | |||
538 | goto drop; | 537 | goto drop; |
539 | } | 538 | } |
540 | 539 | ||
541 | if ((rc = ip_queue_rcv_skb(sk, skb)) < 0) { | 540 | skb_dst_drop(skb); |
541 | rc = sock_queue_rcv_skb(sk, skb); | ||
542 | if (rc < 0) { | ||
542 | /* Note that an ENOMEM error is charged twice */ | 543 | /* Note that an ENOMEM error is charged twice */ |
543 | if (rc == -ENOMEM) | 544 | if (rc == -ENOMEM) |
544 | UDP6_INC_STATS_BH(sock_net(sk), | 545 | UDP6_INC_STATS_BH(sock_net(sk), |
@@ -1113,11 +1114,11 @@ do_udp_sendmsg: | |||
1113 | 1114 | ||
1114 | fl6.flowi6_proto = sk->sk_protocol; | 1115 | fl6.flowi6_proto = sk->sk_protocol; |
1115 | if (!ipv6_addr_any(daddr)) | 1116 | if (!ipv6_addr_any(daddr)) |
1116 | ipv6_addr_copy(&fl6.daddr, daddr); | 1117 | fl6.daddr = *daddr; |
1117 | else | 1118 | else |
1118 | fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ | 1119 | fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ |
1119 | if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) | 1120 | if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) |
1120 | ipv6_addr_copy(&fl6.saddr, &np->saddr); | 1121 | fl6.saddr = np->saddr; |
1121 | fl6.fl6_sport = inet->inet_sport; | 1122 | fl6.fl6_sport = inet->inet_sport; |
1122 | 1123 | ||
1123 | final_p = fl6_update_dst(&fl6, opt, &final); | 1124 | final_p = fl6_update_dst(&fl6, opt, &final); |
@@ -1298,7 +1299,8 @@ static int udp6_ufo_send_check(struct sk_buff *skb) | |||
1298 | return 0; | 1299 | return 0; |
1299 | } | 1300 | } |
1300 | 1301 | ||
1301 | static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, u32 features) | 1302 | static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, |
1303 | netdev_features_t features) | ||
1302 | { | 1304 | { |
1303 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 1305 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
1304 | unsigned int mss; | 1306 | unsigned int mss; |
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c index 3437d7d4eed6..a81ce9450750 100644 --- a/net/ipv6/xfrm6_mode_beet.c +++ b/net/ipv6/xfrm6_mode_beet.c | |||
@@ -72,8 +72,8 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) | |||
72 | top_iph->nexthdr = IPPROTO_BEETPH; | 72 | top_iph->nexthdr = IPPROTO_BEETPH; |
73 | } | 73 | } |
74 | 74 | ||
75 | ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); | 75 | top_iph->saddr = *(struct in6_addr *)&x->props.saddr; |
76 | ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); | 76 | top_iph->daddr = *(struct in6_addr *)&x->id.daddr; |
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
79 | 79 | ||
@@ -99,8 +99,8 @@ static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) | |||
99 | 99 | ||
100 | ip6h = ipv6_hdr(skb); | 100 | ip6h = ipv6_hdr(skb); |
101 | ip6h->payload_len = htons(skb->len - size); | 101 | ip6h->payload_len = htons(skb->len - size); |
102 | ipv6_addr_copy(&ip6h->daddr, (struct in6_addr *) &x->sel.daddr.a6); | 102 | ip6h->daddr = *(struct in6_addr *)&x->sel.daddr.a6; |
103 | ipv6_addr_copy(&ip6h->saddr, (struct in6_addr *) &x->sel.saddr.a6); | 103 | ip6h->saddr = *(struct in6_addr *)&x->sel.saddr.a6; |
104 | err = 0; | 104 | err = 0; |
105 | out: | 105 | out: |
106 | return err; | 106 | return err; |
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index 4d6edff0498f..261e6e6f487e 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c | |||
@@ -55,8 +55,8 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | |||
55 | dsfield &= ~INET_ECN_MASK; | 55 | dsfield &= ~INET_ECN_MASK; |
56 | ipv6_change_dsfield(top_iph, 0, dsfield); | 56 | ipv6_change_dsfield(top_iph, 0, dsfield); |
57 | top_iph->hop_limit = ip6_dst_hoplimit(dst->child); | 57 | top_iph->hop_limit = ip6_dst_hoplimit(dst->child); |
58 | ipv6_addr_copy(&top_iph->saddr, (const struct in6_addr *)&x->props.saddr); | 58 | top_iph->saddr = *(struct in6_addr *)&x->props.saddr; |
59 | ipv6_addr_copy(&top_iph->daddr, (const struct in6_addr *)&x->id.daddr); | 59 | top_iph->daddr = *(struct in6_addr *)&x->id.daddr; |
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
62 | 62 | ||
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index faae41737fca..4eeff89c1aaa 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c | |||
@@ -49,7 +49,7 @@ static void xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu) | |||
49 | struct sock *sk = skb->sk; | 49 | struct sock *sk = skb->sk; |
50 | 50 | ||
51 | fl6.flowi6_oif = sk->sk_bound_dev_if; | 51 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
52 | ipv6_addr_copy(&fl6.daddr, &ipv6_hdr(skb)->daddr); | 52 | fl6.daddr = ipv6_hdr(skb)->daddr; |
53 | 53 | ||
54 | ipv6_local_rxpmtu(sk, &fl6, mtu); | 54 | ipv6_local_rxpmtu(sk, &fl6, mtu); |
55 | } | 55 | } |
@@ -60,7 +60,7 @@ static void xfrm6_local_error(struct sk_buff *skb, u32 mtu) | |||
60 | struct sock *sk = skb->sk; | 60 | struct sock *sk = skb->sk; |
61 | 61 | ||
62 | fl6.fl6_dport = inet_sk(sk)->inet_dport; | 62 | fl6.fl6_dport = inet_sk(sk)->inet_dport; |
63 | ipv6_addr_copy(&fl6.daddr, &ipv6_hdr(skb)->daddr); | 63 | fl6.daddr = ipv6_hdr(skb)->daddr; |
64 | 64 | ||
65 | ipv6_local_error(sk, EMSGSIZE, &fl6, mtu); | 65 | ipv6_local_error(sk, EMSGSIZE, &fl6, mtu); |
66 | } | 66 | } |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index d879f7efbd10..8ea65e032733 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -132,8 +132,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
132 | memset(fl6, 0, sizeof(struct flowi6)); | 132 | memset(fl6, 0, sizeof(struct flowi6)); |
133 | fl6->flowi6_mark = skb->mark; | 133 | fl6->flowi6_mark = skb->mark; |
134 | 134 | ||
135 | ipv6_addr_copy(&fl6->daddr, reverse ? &hdr->saddr : &hdr->daddr); | 135 | fl6->daddr = reverse ? hdr->saddr : hdr->daddr; |
136 | ipv6_addr_copy(&fl6->saddr, reverse ? &hdr->daddr : &hdr->saddr); | 136 | fl6->saddr = reverse ? hdr->daddr : hdr->saddr; |
137 | 137 | ||
138 | while (nh + offset + 1 < skb->data || | 138 | while (nh + offset + 1 < skb->data || |
139 | pskb_may_pull(skb, nh + offset + 1 - skb->data)) { | 139 | pskb_may_pull(skb, nh + offset + 1 - skb->data)) { |
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index f2d72b8a3faa..3f2f7c4ab721 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
@@ -27,8 +27,8 @@ __xfrm6_init_tempsel(struct xfrm_selector *sel, const struct flowi *fl) | |||
27 | 27 | ||
28 | /* Initialize temporary selector matching only | 28 | /* Initialize temporary selector matching only |
29 | * to current session. */ | 29 | * to current session. */ |
30 | ipv6_addr_copy((struct in6_addr *)&sel->daddr, &fl6->daddr); | 30 | *(struct in6_addr *)&sel->daddr = fl6->daddr; |
31 | ipv6_addr_copy((struct in6_addr *)&sel->saddr, &fl6->saddr); | 31 | *(struct in6_addr *)&sel->saddr = fl6->saddr; |
32 | sel->dport = xfrm_flowi_dport(fl, &fl6->uli); | 32 | sel->dport = xfrm_flowi_dport(fl, &fl6->uli); |
33 | sel->dport_mask = htons(0xffff); | 33 | sel->dport_mask = htons(0xffff); |
34 | sel->sport = xfrm_flowi_sport(fl, &fl6->uli); | 34 | sel->sport = xfrm_flowi_sport(fl, &fl6->uli); |
diff --git a/net/irda/irttp.c b/net/irda/irttp.c index 32e3bb026110..5c93f2952b08 100644 --- a/net/irda/irttp.c +++ b/net/irda/irttp.c | |||
@@ -1461,14 +1461,12 @@ struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance) | |||
1461 | } | 1461 | } |
1462 | 1462 | ||
1463 | /* Allocate a new instance */ | 1463 | /* Allocate a new instance */ |
1464 | new = kmalloc(sizeof(struct tsap_cb), GFP_ATOMIC); | 1464 | new = kmemdup(orig, sizeof(struct tsap_cb), GFP_ATOMIC); |
1465 | if (!new) { | 1465 | if (!new) { |
1466 | IRDA_DEBUG(0, "%s(), unable to kmalloc\n", __func__); | 1466 | IRDA_DEBUG(0, "%s(), unable to kmalloc\n", __func__); |
1467 | spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags); | 1467 | spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags); |
1468 | return NULL; | 1468 | return NULL; |
1469 | } | 1469 | } |
1470 | /* Dup */ | ||
1471 | memcpy(new, orig, sizeof(struct tsap_cb)); | ||
1472 | spin_lock_init(&new->lock); | 1470 | spin_lock_init(&new->lock); |
1473 | 1471 | ||
1474 | /* We don't need the old instance any more */ | 1472 | /* We don't need the old instance any more */ |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 1e733e9073d0..bfc0bef170cb 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -712,7 +712,7 @@ static unsigned int pfkey_sockaddr_fill(const xfrm_address_t *xaddr, __be16 port | |||
712 | sin6->sin6_family = AF_INET6; | 712 | sin6->sin6_family = AF_INET6; |
713 | sin6->sin6_port = port; | 713 | sin6->sin6_port = port; |
714 | sin6->sin6_flowinfo = 0; | 714 | sin6->sin6_flowinfo = 0; |
715 | ipv6_addr_copy(&sin6->sin6_addr, (const struct in6_addr *)xaddr->a6); | 715 | sin6->sin6_addr = *(struct in6_addr *)xaddr->a6; |
716 | sin6->sin6_scope_id = 0; | 716 | sin6->sin6_scope_id = 0; |
717 | return 128; | 717 | return 128; |
718 | } | 718 | } |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 93b243422659..476b106c0b1c 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -177,7 +177,8 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d | |||
177 | memcpy(mgmt->da, da, ETH_ALEN); | 177 | memcpy(mgmt->da, da, ETH_ALEN); |
178 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | 178 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
179 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 179 | if (sdata->vif.type == NL80211_IFTYPE_AP || |
180 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 180 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
181 | sdata->vif.type == NL80211_IFTYPE_MESH_POINT) | ||
181 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); | 182 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
182 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | 183 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) |
183 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); | 184 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index b3f65520e7a7..39d72ccaffb3 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -78,7 +78,8 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, | |||
78 | memcpy(mgmt->da, da, ETH_ALEN); | 78 | memcpy(mgmt->da, da, ETH_ALEN); |
79 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | 79 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
80 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 80 | if (sdata->vif.type == NL80211_IFTYPE_AP || |
81 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 81 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
82 | sdata->vif.type == NL80211_IFTYPE_MESH_POINT) | ||
82 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); | 83 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
83 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | 84 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) |
84 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); | 85 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); |
@@ -372,13 +373,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
372 | pubsta->addr, tid); | 373 | pubsta->addr, tid); |
373 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 374 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
374 | 375 | ||
375 | /* | ||
376 | * The aggregation code is not prepared to handle | ||
377 | * anything but STA/AP due to the BSSID handling. | ||
378 | * IBSS could work in the code but isn't supported | ||
379 | * by drivers or the standard. | ||
380 | */ | ||
381 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 376 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
377 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && | ||
382 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 378 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
383 | sdata->vif.type != NL80211_IFTYPE_AP) | 379 | sdata->vif.type != NL80211_IFTYPE_AP) |
384 | return -EINVAL; | 380 | return -EINVAL; |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d06c65fa5526..1063a7e57d62 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -411,7 +411,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
411 | BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | | 411 | BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | |
412 | BIT(NL80211_STA_FLAG_WME) | | 412 | BIT(NL80211_STA_FLAG_WME) | |
413 | BIT(NL80211_STA_FLAG_MFP) | | 413 | BIT(NL80211_STA_FLAG_MFP) | |
414 | BIT(NL80211_STA_FLAG_AUTHENTICATED); | 414 | BIT(NL80211_STA_FLAG_AUTHENTICATED) | |
415 | BIT(NL80211_STA_FLAG_TDLS_PEER); | ||
415 | if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) | 416 | if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) |
416 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); | 417 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); |
417 | if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) | 418 | if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) |
@@ -422,6 +423,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
422 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); | 423 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); |
423 | if (test_sta_flag(sta, WLAN_STA_AUTH)) | 424 | if (test_sta_flag(sta, WLAN_STA_AUTH)) |
424 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); | 425 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); |
426 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) | ||
427 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); | ||
425 | } | 428 | } |
426 | 429 | ||
427 | 430 | ||
@@ -488,6 +491,31 @@ static void ieee80211_config_ap_ssid(struct ieee80211_sub_if_data *sdata, | |||
488 | (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); | 491 | (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); |
489 | } | 492 | } |
490 | 493 | ||
494 | static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, | ||
495 | u8 *resp, size_t resp_len) | ||
496 | { | ||
497 | struct sk_buff *new, *old; | ||
498 | |||
499 | if (!resp || !resp_len) | ||
500 | return -EINVAL; | ||
501 | |||
502 | old = sdata->u.ap.probe_resp; | ||
503 | |||
504 | new = dev_alloc_skb(resp_len); | ||
505 | if (!new) | ||
506 | return -ENOMEM; | ||
507 | |||
508 | memcpy(skb_put(new, resp_len), resp, resp_len); | ||
509 | |||
510 | rcu_assign_pointer(sdata->u.ap.probe_resp, new); | ||
511 | synchronize_rcu(); | ||
512 | |||
513 | if (old) | ||
514 | dev_kfree_skb(old); | ||
515 | |||
516 | return 0; | ||
517 | } | ||
518 | |||
491 | /* | 519 | /* |
492 | * This handles both adding a beacon and setting new beacon info | 520 | * This handles both adding a beacon and setting new beacon info |
493 | */ | 521 | */ |
@@ -498,6 +526,7 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, | |||
498 | int new_head_len, new_tail_len; | 526 | int new_head_len, new_tail_len; |
499 | int size; | 527 | int size; |
500 | int err = -EINVAL; | 528 | int err = -EINVAL; |
529 | u32 changed = 0; | ||
501 | 530 | ||
502 | old = rtnl_dereference(sdata->u.ap.beacon); | 531 | old = rtnl_dereference(sdata->u.ap.beacon); |
503 | 532 | ||
@@ -581,11 +610,17 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, | |||
581 | 610 | ||
582 | kfree(old); | 611 | kfree(old); |
583 | 612 | ||
613 | err = ieee80211_set_probe_resp(sdata, params->probe_resp, | ||
614 | params->probe_resp_len); | ||
615 | if (!err) | ||
616 | changed |= BSS_CHANGED_AP_PROBE_RESP; | ||
617 | |||
584 | ieee80211_config_ap_ssid(sdata, params); | 618 | ieee80211_config_ap_ssid(sdata, params); |
619 | changed |= BSS_CHANGED_BEACON_ENABLED | | ||
620 | BSS_CHANGED_BEACON | | ||
621 | BSS_CHANGED_SSID; | ||
585 | 622 | ||
586 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | | 623 | ieee80211_bss_info_change_notify(sdata, changed); |
587 | BSS_CHANGED_BEACON | | ||
588 | BSS_CHANGED_SSID); | ||
589 | return 0; | 624 | return 0; |
590 | } | 625 | } |
591 | 626 | ||
@@ -594,6 +629,8 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, | |||
594 | { | 629 | { |
595 | struct ieee80211_sub_if_data *sdata; | 630 | struct ieee80211_sub_if_data *sdata; |
596 | struct beacon_data *old; | 631 | struct beacon_data *old; |
632 | struct ieee80211_sub_if_data *vlan; | ||
633 | int ret; | ||
597 | 634 | ||
598 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 635 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
599 | 636 | ||
@@ -601,7 +638,24 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, | |||
601 | if (old) | 638 | if (old) |
602 | return -EALREADY; | 639 | return -EALREADY; |
603 | 640 | ||
604 | return ieee80211_config_beacon(sdata, params); | 641 | ret = ieee80211_config_beacon(sdata, params); |
642 | if (ret) | ||
643 | return ret; | ||
644 | |||
645 | /* | ||
646 | * Apply control port protocol, this allows us to | ||
647 | * not encrypt dynamic WEP control frames. | ||
648 | */ | ||
649 | sdata->control_port_protocol = params->crypto.control_port_ethertype; | ||
650 | sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt; | ||
651 | list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { | ||
652 | vlan->control_port_protocol = | ||
653 | params->crypto.control_port_ethertype; | ||
654 | vlan->control_port_no_encrypt = | ||
655 | params->crypto.control_port_no_encrypt; | ||
656 | } | ||
657 | |||
658 | return 0; | ||
605 | } | 659 | } |
606 | 660 | ||
607 | static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, | 661 | static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, |
@@ -847,7 +901,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | |||
847 | 901 | ||
848 | sta_apply_parameters(local, sta, params); | 902 | sta_apply_parameters(local, sta, params); |
849 | 903 | ||
850 | rate_control_rate_init(sta); | 904 | /* |
905 | * for TDLS, rate control should be initialized only when supported | ||
906 | * rates are known. | ||
907 | */ | ||
908 | if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) | ||
909 | rate_control_rate_init(sta); | ||
851 | 910 | ||
852 | layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || | 911 | layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
853 | sdata->vif.type == NL80211_IFTYPE_AP; | 912 | sdata->vif.type == NL80211_IFTYPE_AP; |
@@ -931,6 +990,9 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
931 | 990 | ||
932 | sta_apply_parameters(local, sta, params); | 991 | sta_apply_parameters(local, sta, params); |
933 | 992 | ||
993 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && params->supported_rates) | ||
994 | rate_control_rate_init(sta); | ||
995 | |||
934 | rcu_read_unlock(); | 996 | rcu_read_unlock(); |
935 | 997 | ||
936 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | 998 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
@@ -1394,7 +1456,7 @@ static int ieee80211_set_channel(struct wiphy *wiphy, | |||
1394 | (old_oper_type != local->_oper_channel_type)) | 1456 | (old_oper_type != local->_oper_channel_type)) |
1395 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 1457 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
1396 | 1458 | ||
1397 | if ((sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR) && | 1459 | if (sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR && |
1398 | old_vif_oper_type != sdata->vif.bss_conf.channel_type) | 1460 | old_vif_oper_type != sdata->vif.bss_conf.channel_type) |
1399 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); | 1461 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); |
1400 | 1462 | ||
@@ -1917,7 +1979,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
1917 | enum nl80211_channel_type channel_type, | 1979 | enum nl80211_channel_type channel_type, |
1918 | bool channel_type_valid, unsigned int wait, | 1980 | bool channel_type_valid, unsigned int wait, |
1919 | const u8 *buf, size_t len, bool no_cck, | 1981 | const u8 *buf, size_t len, bool no_cck, |
1920 | u64 *cookie) | 1982 | bool dont_wait_for_ack, u64 *cookie) |
1921 | { | 1983 | { |
1922 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1984 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1923 | struct ieee80211_local *local = sdata->local; | 1985 | struct ieee80211_local *local = sdata->local; |
@@ -1925,10 +1987,15 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
1925 | struct sta_info *sta; | 1987 | struct sta_info *sta; |
1926 | struct ieee80211_work *wk; | 1988 | struct ieee80211_work *wk; |
1927 | const struct ieee80211_mgmt *mgmt = (void *)buf; | 1989 | const struct ieee80211_mgmt *mgmt = (void *)buf; |
1928 | u32 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | | 1990 | u32 flags; |
1929 | IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1930 | bool is_offchan = false; | 1991 | bool is_offchan = false; |
1931 | 1992 | ||
1993 | if (dont_wait_for_ack) | ||
1994 | flags = IEEE80211_TX_CTL_NO_ACK; | ||
1995 | else | ||
1996 | flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | | ||
1997 | IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1998 | |||
1932 | /* Check that we are on the requested channel for transmission */ | 1999 | /* Check that we are on the requested channel for transmission */ |
1933 | if (chan != local->tmp_channel && | 2000 | if (chan != local->tmp_channel && |
1934 | chan != local->oper_channel) | 2001 | chan != local->oper_channel) |
@@ -2488,6 +2555,82 @@ static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | |||
2488 | return 0; | 2555 | return 0; |
2489 | } | 2556 | } |
2490 | 2557 | ||
2558 | static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, | ||
2559 | const u8 *peer, u64 *cookie) | ||
2560 | { | ||
2561 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
2562 | struct ieee80211_local *local = sdata->local; | ||
2563 | struct ieee80211_qos_hdr *nullfunc; | ||
2564 | struct sk_buff *skb; | ||
2565 | int size = sizeof(*nullfunc); | ||
2566 | __le16 fc; | ||
2567 | bool qos; | ||
2568 | struct ieee80211_tx_info *info; | ||
2569 | struct sta_info *sta; | ||
2570 | |||
2571 | rcu_read_lock(); | ||
2572 | sta = sta_info_get(sdata, peer); | ||
2573 | if (sta) { | ||
2574 | qos = test_sta_flag(sta, WLAN_STA_WME); | ||
2575 | rcu_read_unlock(); | ||
2576 | } else { | ||
2577 | rcu_read_unlock(); | ||
2578 | return -ENOLINK; | ||
2579 | } | ||
2580 | |||
2581 | if (qos) { | ||
2582 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | | ||
2583 | IEEE80211_STYPE_QOS_NULLFUNC | | ||
2584 | IEEE80211_FCTL_FROMDS); | ||
2585 | } else { | ||
2586 | size -= 2; | ||
2587 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | | ||
2588 | IEEE80211_STYPE_NULLFUNC | | ||
2589 | IEEE80211_FCTL_FROMDS); | ||
2590 | } | ||
2591 | |||
2592 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + size); | ||
2593 | if (!skb) | ||
2594 | return -ENOMEM; | ||
2595 | |||
2596 | skb->dev = dev; | ||
2597 | |||
2598 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
2599 | |||
2600 | nullfunc = (void *) skb_put(skb, size); | ||
2601 | nullfunc->frame_control = fc; | ||
2602 | nullfunc->duration_id = 0; | ||
2603 | memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN); | ||
2604 | memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN); | ||
2605 | memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN); | ||
2606 | nullfunc->seq_ctrl = 0; | ||
2607 | |||
2608 | info = IEEE80211_SKB_CB(skb); | ||
2609 | |||
2610 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS | | ||
2611 | IEEE80211_TX_INTFL_NL80211_FRAME_TX; | ||
2612 | |||
2613 | skb_set_queue_mapping(skb, IEEE80211_AC_VO); | ||
2614 | skb->priority = 7; | ||
2615 | if (qos) | ||
2616 | nullfunc->qos_ctrl = cpu_to_le16(7); | ||
2617 | |||
2618 | local_bh_disable(); | ||
2619 | ieee80211_xmit(sdata, skb); | ||
2620 | local_bh_enable(); | ||
2621 | |||
2622 | *cookie = (unsigned long) skb; | ||
2623 | return 0; | ||
2624 | } | ||
2625 | |||
2626 | static struct ieee80211_channel * | ||
2627 | ieee80211_wiphy_get_channel(struct wiphy *wiphy) | ||
2628 | { | ||
2629 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
2630 | |||
2631 | return local->oper_channel; | ||
2632 | } | ||
2633 | |||
2491 | struct cfg80211_ops mac80211_config_ops = { | 2634 | struct cfg80211_ops mac80211_config_ops = { |
2492 | .add_virtual_intf = ieee80211_add_iface, | 2635 | .add_virtual_intf = ieee80211_add_iface, |
2493 | .del_virtual_intf = ieee80211_del_iface, | 2636 | .del_virtual_intf = ieee80211_del_iface, |
@@ -2553,4 +2696,6 @@ struct cfg80211_ops mac80211_config_ops = { | |||
2553 | .set_rekey_data = ieee80211_set_rekey_data, | 2696 | .set_rekey_data = ieee80211_set_rekey_data, |
2554 | .tdls_oper = ieee80211_tdls_oper, | 2697 | .tdls_oper = ieee80211_tdls_oper, |
2555 | .tdls_mgmt = ieee80211_tdls_mgmt, | 2698 | .tdls_mgmt = ieee80211_tdls_mgmt, |
2699 | .probe_client = ieee80211_probe_client, | ||
2700 | .get_channel = ieee80211_wiphy_get_channel, | ||
2556 | }; | 2701 | }; |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 883996b2f99f..00cefcb493eb 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -190,7 +190,7 @@ static ssize_t uapsd_max_sp_len_write(struct file *file, | |||
190 | return -EFAULT; | 190 | return -EFAULT; |
191 | buf[len] = '\0'; | 191 | buf[len] = '\0'; |
192 | 192 | ||
193 | ret = strict_strtoul(buf, 0, &val); | 193 | ret = kstrtoul(buf, 0, &val); |
194 | 194 | ||
195 | if (ret) | 195 | if (ret) |
196 | return -EINVAL; | 196 | return -EINVAL; |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 5f165d7eb2db..b12ed52732c8 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -5,6 +5,11 @@ | |||
5 | #include "ieee80211_i.h" | 5 | #include "ieee80211_i.h" |
6 | #include "driver-trace.h" | 6 | #include "driver-trace.h" |
7 | 7 | ||
8 | static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) | ||
9 | { | ||
10 | WARN_ON(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER)); | ||
11 | } | ||
12 | |||
8 | static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb) | 13 | static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb) |
9 | { | 14 | { |
10 | local->ops->tx(&local->hw, skb); | 15 | local->ops->tx(&local->hw, skb); |
@@ -69,15 +74,23 @@ static inline int drv_resume(struct ieee80211_local *local) | |||
69 | #endif | 74 | #endif |
70 | 75 | ||
71 | static inline int drv_add_interface(struct ieee80211_local *local, | 76 | static inline int drv_add_interface(struct ieee80211_local *local, |
72 | struct ieee80211_vif *vif) | 77 | struct ieee80211_sub_if_data *sdata) |
73 | { | 78 | { |
74 | int ret; | 79 | int ret; |
75 | 80 | ||
76 | might_sleep(); | 81 | might_sleep(); |
77 | 82 | ||
78 | trace_drv_add_interface(local, vif_to_sdata(vif)); | 83 | if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
79 | ret = local->ops->add_interface(&local->hw, vif); | 84 | sdata->vif.type == NL80211_IFTYPE_MONITOR)) |
85 | return -EINVAL; | ||
86 | |||
87 | trace_drv_add_interface(local, sdata); | ||
88 | ret = local->ops->add_interface(&local->hw, &sdata->vif); | ||
80 | trace_drv_return_int(local, ret); | 89 | trace_drv_return_int(local, ret); |
90 | |||
91 | if (ret == 0) | ||
92 | sdata->flags |= IEEE80211_SDATA_IN_DRIVER; | ||
93 | |||
81 | return ret; | 94 | return ret; |
82 | } | 95 | } |
83 | 96 | ||
@@ -89,6 +102,8 @@ static inline int drv_change_interface(struct ieee80211_local *local, | |||
89 | 102 | ||
90 | might_sleep(); | 103 | might_sleep(); |
91 | 104 | ||
105 | check_sdata_in_driver(sdata); | ||
106 | |||
92 | trace_drv_change_interface(local, sdata, type, p2p); | 107 | trace_drv_change_interface(local, sdata, type, p2p); |
93 | ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); | 108 | ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); |
94 | trace_drv_return_int(local, ret); | 109 | trace_drv_return_int(local, ret); |
@@ -96,12 +111,15 @@ static inline int drv_change_interface(struct ieee80211_local *local, | |||
96 | } | 111 | } |
97 | 112 | ||
98 | static inline void drv_remove_interface(struct ieee80211_local *local, | 113 | static inline void drv_remove_interface(struct ieee80211_local *local, |
99 | struct ieee80211_vif *vif) | 114 | struct ieee80211_sub_if_data *sdata) |
100 | { | 115 | { |
101 | might_sleep(); | 116 | might_sleep(); |
102 | 117 | ||
103 | trace_drv_remove_interface(local, vif_to_sdata(vif)); | 118 | check_sdata_in_driver(sdata); |
104 | local->ops->remove_interface(&local->hw, vif); | 119 | |
120 | trace_drv_remove_interface(local, sdata); | ||
121 | local->ops->remove_interface(&local->hw, &sdata->vif); | ||
122 | sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER; | ||
105 | trace_drv_return_void(local); | 123 | trace_drv_return_void(local); |
106 | } | 124 | } |
107 | 125 | ||
@@ -124,6 +142,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, | |||
124 | { | 142 | { |
125 | might_sleep(); | 143 | might_sleep(); |
126 | 144 | ||
145 | check_sdata_in_driver(sdata); | ||
146 | |||
127 | trace_drv_bss_info_changed(local, sdata, info, changed); | 147 | trace_drv_bss_info_changed(local, sdata, info, changed); |
128 | if (local->ops->bss_info_changed) | 148 | if (local->ops->bss_info_changed) |
129 | local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed); | 149 | local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed); |
@@ -139,6 +159,8 @@ static inline int drv_tx_sync(struct ieee80211_local *local, | |||
139 | 159 | ||
140 | might_sleep(); | 160 | might_sleep(); |
141 | 161 | ||
162 | check_sdata_in_driver(sdata); | ||
163 | |||
142 | trace_drv_tx_sync(local, sdata, bssid, type); | 164 | trace_drv_tx_sync(local, sdata, bssid, type); |
143 | if (local->ops->tx_sync) | 165 | if (local->ops->tx_sync) |
144 | ret = local->ops->tx_sync(&local->hw, &sdata->vif, | 166 | ret = local->ops->tx_sync(&local->hw, &sdata->vif, |
@@ -154,6 +176,8 @@ static inline void drv_finish_tx_sync(struct ieee80211_local *local, | |||
154 | { | 176 | { |
155 | might_sleep(); | 177 | might_sleep(); |
156 | 178 | ||
179 | check_sdata_in_driver(sdata); | ||
180 | |||
157 | trace_drv_finish_tx_sync(local, sdata, bssid, type); | 181 | trace_drv_finish_tx_sync(local, sdata, bssid, type); |
158 | if (local->ops->finish_tx_sync) | 182 | if (local->ops->finish_tx_sync) |
159 | local->ops->finish_tx_sync(&local->hw, &sdata->vif, | 183 | local->ops->finish_tx_sync(&local->hw, &sdata->vif, |
@@ -211,6 +235,8 @@ static inline int drv_set_key(struct ieee80211_local *local, | |||
211 | 235 | ||
212 | might_sleep(); | 236 | might_sleep(); |
213 | 237 | ||
238 | check_sdata_in_driver(sdata); | ||
239 | |||
214 | trace_drv_set_key(local, cmd, sdata, sta, key); | 240 | trace_drv_set_key(local, cmd, sdata, sta, key); |
215 | ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); | 241 | ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); |
216 | trace_drv_return_int(local, ret); | 242 | trace_drv_return_int(local, ret); |
@@ -228,6 +254,8 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local, | |||
228 | if (sta) | 254 | if (sta) |
229 | ista = &sta->sta; | 255 | ista = &sta->sta; |
230 | 256 | ||
257 | check_sdata_in_driver(sdata); | ||
258 | |||
231 | trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); | 259 | trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); |
232 | if (local->ops->update_tkip_key) | 260 | if (local->ops->update_tkip_key) |
233 | local->ops->update_tkip_key(&local->hw, &sdata->vif, conf, | 261 | local->ops->update_tkip_key(&local->hw, &sdata->vif, conf, |
@@ -243,6 +271,8 @@ static inline int drv_hw_scan(struct ieee80211_local *local, | |||
243 | 271 | ||
244 | might_sleep(); | 272 | might_sleep(); |
245 | 273 | ||
274 | check_sdata_in_driver(sdata); | ||
275 | |||
246 | trace_drv_hw_scan(local, sdata); | 276 | trace_drv_hw_scan(local, sdata); |
247 | ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); | 277 | ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); |
248 | trace_drv_return_int(local, ret); | 278 | trace_drv_return_int(local, ret); |
@@ -254,6 +284,8 @@ static inline void drv_cancel_hw_scan(struct ieee80211_local *local, | |||
254 | { | 284 | { |
255 | might_sleep(); | 285 | might_sleep(); |
256 | 286 | ||
287 | check_sdata_in_driver(sdata); | ||
288 | |||
257 | trace_drv_cancel_hw_scan(local, sdata); | 289 | trace_drv_cancel_hw_scan(local, sdata); |
258 | local->ops->cancel_hw_scan(&local->hw, &sdata->vif); | 290 | local->ops->cancel_hw_scan(&local->hw, &sdata->vif); |
259 | trace_drv_return_void(local); | 291 | trace_drv_return_void(local); |
@@ -269,6 +301,8 @@ drv_sched_scan_start(struct ieee80211_local *local, | |||
269 | 301 | ||
270 | might_sleep(); | 302 | might_sleep(); |
271 | 303 | ||
304 | check_sdata_in_driver(sdata); | ||
305 | |||
272 | trace_drv_sched_scan_start(local, sdata); | 306 | trace_drv_sched_scan_start(local, sdata); |
273 | ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, | 307 | ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, |
274 | req, ies); | 308 | req, ies); |
@@ -281,6 +315,8 @@ static inline void drv_sched_scan_stop(struct ieee80211_local *local, | |||
281 | { | 315 | { |
282 | might_sleep(); | 316 | might_sleep(); |
283 | 317 | ||
318 | check_sdata_in_driver(sdata); | ||
319 | |||
284 | trace_drv_sched_scan_stop(local, sdata); | 320 | trace_drv_sched_scan_stop(local, sdata); |
285 | local->ops->sched_scan_stop(&local->hw, &sdata->vif); | 321 | local->ops->sched_scan_stop(&local->hw, &sdata->vif); |
286 | trace_drv_return_void(local); | 322 | trace_drv_return_void(local); |
@@ -377,6 +413,8 @@ static inline void drv_sta_notify(struct ieee80211_local *local, | |||
377 | enum sta_notify_cmd cmd, | 413 | enum sta_notify_cmd cmd, |
378 | struct ieee80211_sta *sta) | 414 | struct ieee80211_sta *sta) |
379 | { | 415 | { |
416 | check_sdata_in_driver(sdata); | ||
417 | |||
380 | trace_drv_sta_notify(local, sdata, cmd, sta); | 418 | trace_drv_sta_notify(local, sdata, cmd, sta); |
381 | if (local->ops->sta_notify) | 419 | if (local->ops->sta_notify) |
382 | local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta); | 420 | local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta); |
@@ -391,6 +429,8 @@ static inline int drv_sta_add(struct ieee80211_local *local, | |||
391 | 429 | ||
392 | might_sleep(); | 430 | might_sleep(); |
393 | 431 | ||
432 | check_sdata_in_driver(sdata); | ||
433 | |||
394 | trace_drv_sta_add(local, sdata, sta); | 434 | trace_drv_sta_add(local, sdata, sta); |
395 | if (local->ops->sta_add) | 435 | if (local->ops->sta_add) |
396 | ret = local->ops->sta_add(&local->hw, &sdata->vif, sta); | 436 | ret = local->ops->sta_add(&local->hw, &sdata->vif, sta); |
@@ -406,6 +446,8 @@ static inline void drv_sta_remove(struct ieee80211_local *local, | |||
406 | { | 446 | { |
407 | might_sleep(); | 447 | might_sleep(); |
408 | 448 | ||
449 | check_sdata_in_driver(sdata); | ||
450 | |||
409 | trace_drv_sta_remove(local, sdata, sta); | 451 | trace_drv_sta_remove(local, sdata, sta); |
410 | if (local->ops->sta_remove) | 452 | if (local->ops->sta_remove) |
411 | local->ops->sta_remove(&local->hw, &sdata->vif, sta); | 453 | local->ops->sta_remove(&local->hw, &sdata->vif, sta); |
@@ -421,6 +463,8 @@ static inline int drv_conf_tx(struct ieee80211_local *local, | |||
421 | 463 | ||
422 | might_sleep(); | 464 | might_sleep(); |
423 | 465 | ||
466 | check_sdata_in_driver(sdata); | ||
467 | |||
424 | trace_drv_conf_tx(local, sdata, queue, params); | 468 | trace_drv_conf_tx(local, sdata, queue, params); |
425 | if (local->ops->conf_tx) | 469 | if (local->ops->conf_tx) |
426 | ret = local->ops->conf_tx(&local->hw, &sdata->vif, | 470 | ret = local->ops->conf_tx(&local->hw, &sdata->vif, |
@@ -436,6 +480,8 @@ static inline u64 drv_get_tsf(struct ieee80211_local *local, | |||
436 | 480 | ||
437 | might_sleep(); | 481 | might_sleep(); |
438 | 482 | ||
483 | check_sdata_in_driver(sdata); | ||
484 | |||
439 | trace_drv_get_tsf(local, sdata); | 485 | trace_drv_get_tsf(local, sdata); |
440 | if (local->ops->get_tsf) | 486 | if (local->ops->get_tsf) |
441 | ret = local->ops->get_tsf(&local->hw, &sdata->vif); | 487 | ret = local->ops->get_tsf(&local->hw, &sdata->vif); |
@@ -449,6 +495,8 @@ static inline void drv_set_tsf(struct ieee80211_local *local, | |||
449 | { | 495 | { |
450 | might_sleep(); | 496 | might_sleep(); |
451 | 497 | ||
498 | check_sdata_in_driver(sdata); | ||
499 | |||
452 | trace_drv_set_tsf(local, sdata, tsf); | 500 | trace_drv_set_tsf(local, sdata, tsf); |
453 | if (local->ops->set_tsf) | 501 | if (local->ops->set_tsf) |
454 | local->ops->set_tsf(&local->hw, &sdata->vif, tsf); | 502 | local->ops->set_tsf(&local->hw, &sdata->vif, tsf); |
@@ -460,6 +508,8 @@ static inline void drv_reset_tsf(struct ieee80211_local *local, | |||
460 | { | 508 | { |
461 | might_sleep(); | 509 | might_sleep(); |
462 | 510 | ||
511 | check_sdata_in_driver(sdata); | ||
512 | |||
463 | trace_drv_reset_tsf(local, sdata); | 513 | trace_drv_reset_tsf(local, sdata); |
464 | if (local->ops->reset_tsf) | 514 | if (local->ops->reset_tsf) |
465 | local->ops->reset_tsf(&local->hw, &sdata->vif); | 515 | local->ops->reset_tsf(&local->hw, &sdata->vif); |
@@ -489,6 +539,8 @@ static inline int drv_ampdu_action(struct ieee80211_local *local, | |||
489 | 539 | ||
490 | might_sleep(); | 540 | might_sleep(); |
491 | 541 | ||
542 | check_sdata_in_driver(sdata); | ||
543 | |||
492 | trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); | 544 | trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); |
493 | 545 | ||
494 | if (local->ops->ampdu_action) | 546 | if (local->ops->ampdu_action) |
@@ -644,6 +696,8 @@ static inline int drv_set_bitrate_mask(struct ieee80211_local *local, | |||
644 | 696 | ||
645 | might_sleep(); | 697 | might_sleep(); |
646 | 698 | ||
699 | check_sdata_in_driver(sdata); | ||
700 | |||
647 | trace_drv_set_bitrate_mask(local, sdata, mask); | 701 | trace_drv_set_bitrate_mask(local, sdata, mask); |
648 | if (local->ops->set_bitrate_mask) | 702 | if (local->ops->set_bitrate_mask) |
649 | ret = local->ops->set_bitrate_mask(&local->hw, | 703 | ret = local->ops->set_bitrate_mask(&local->hw, |
@@ -657,6 +711,8 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local, | |||
657 | struct ieee80211_sub_if_data *sdata, | 711 | struct ieee80211_sub_if_data *sdata, |
658 | struct cfg80211_gtk_rekey_data *data) | 712 | struct cfg80211_gtk_rekey_data *data) |
659 | { | 713 | { |
714 | check_sdata_in_driver(sdata); | ||
715 | |||
660 | trace_drv_set_rekey_data(local, sdata, data); | 716 | trace_drv_set_rekey_data(local, sdata, data); |
661 | if (local->ops->set_rekey_data) | 717 | if (local->ops->set_rekey_data) |
662 | local->ops->set_rekey_data(&local->hw, &sdata->vif, data); | 718 | local->ops->set_rekey_data(&local->hw, &sdata->vif, data); |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index f0fb737efa86..d06975098aad 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -196,7 +196,8 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, | |||
196 | memcpy(mgmt->da, da, ETH_ALEN); | 196 | memcpy(mgmt->da, da, ETH_ALEN); |
197 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | 197 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
198 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 198 | if (sdata->vif.type == NL80211_IFTYPE_AP || |
199 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 199 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
200 | sdata->vif.type == NL80211_IFTYPE_MESH_POINT) | ||
200 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); | 201 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
201 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | 202 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) |
202 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); | 203 | memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index ede9a8b341ac..7d84af70132f 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -97,6 +97,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
97 | /* if merging, indicate to driver that we leave the old IBSS */ | 97 | /* if merging, indicate to driver that we leave the old IBSS */ |
98 | if (sdata->vif.bss_conf.ibss_joined) { | 98 | if (sdata->vif.bss_conf.ibss_joined) { |
99 | sdata->vif.bss_conf.ibss_joined = false; | 99 | sdata->vif.bss_conf.ibss_joined = false; |
100 | netif_carrier_off(sdata->dev); | ||
100 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); | 101 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); |
101 | } | 102 | } |
102 | 103 | ||
@@ -207,6 +208,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
207 | bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, | 208 | bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, |
208 | mgmt, skb->len, 0, GFP_KERNEL); | 209 | mgmt, skb->len, 0, GFP_KERNEL); |
209 | cfg80211_put_bss(bss); | 210 | cfg80211_put_bss(bss); |
211 | netif_carrier_on(sdata->dev); | ||
210 | cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); | 212 | cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); |
211 | } | 213 | } |
212 | 214 | ||
@@ -990,6 +992,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
990 | } | 992 | } |
991 | 993 | ||
992 | sta_info_flush(sdata->local, sdata); | 994 | sta_info_flush(sdata->local, sdata); |
995 | netif_carrier_off(sdata->dev); | ||
993 | 996 | ||
994 | /* remove beacon */ | 997 | /* remove beacon */ |
995 | kfree(sdata->u.ibss.ie); | 998 | kfree(sdata->u.ibss.ie); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ea10a51babda..068cc92d16aa 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
26 | #include <linux/leds.h> | 26 | #include <linux/leds.h> |
27 | #include <linux/idr.h> | ||
27 | #include <net/ieee80211_radiotap.h> | 28 | #include <net/ieee80211_radiotap.h> |
28 | #include <net/cfg80211.h> | 29 | #include <net/cfg80211.h> |
29 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
@@ -184,12 +185,15 @@ enum ieee80211_packet_rx_flags { | |||
184 | * enum ieee80211_rx_flags - RX data flags | 185 | * enum ieee80211_rx_flags - RX data flags |
185 | * | 186 | * |
186 | * @IEEE80211_RX_CMNTR: received on cooked monitor already | 187 | * @IEEE80211_RX_CMNTR: received on cooked monitor already |
188 | * @IEEE80211_RX_BEACON_REPORTED: This frame was already reported | ||
189 | * to cfg80211_report_obss_beacon(). | ||
187 | * | 190 | * |
188 | * These flags are used across handling multiple interfaces | 191 | * These flags are used across handling multiple interfaces |
189 | * for a single frame. | 192 | * for a single frame. |
190 | */ | 193 | */ |
191 | enum ieee80211_rx_flags { | 194 | enum ieee80211_rx_flags { |
192 | IEEE80211_RX_CMNTR = BIT(0), | 195 | IEEE80211_RX_CMNTR = BIT(0), |
196 | IEEE80211_RX_BEACON_REPORTED = BIT(1), | ||
193 | }; | 197 | }; |
194 | 198 | ||
195 | struct ieee80211_rx_data { | 199 | struct ieee80211_rx_data { |
@@ -228,6 +232,7 @@ struct beacon_data { | |||
228 | 232 | ||
229 | struct ieee80211_if_ap { | 233 | struct ieee80211_if_ap { |
230 | struct beacon_data __rcu *beacon; | 234 | struct beacon_data __rcu *beacon; |
235 | struct sk_buff __rcu *probe_resp; | ||
231 | 236 | ||
232 | struct list_head vlans; | 237 | struct list_head vlans; |
233 | 238 | ||
@@ -543,6 +548,7 @@ struct ieee80211_if_mesh { | |||
543 | * associated stations and deliver multicast frames both | 548 | * associated stations and deliver multicast frames both |
544 | * back to wireless media and to the local net stack. | 549 | * back to wireless media and to the local net stack. |
545 | * @IEEE80211_SDATA_DISCONNECT_RESUME: Disconnect after resume. | 550 | * @IEEE80211_SDATA_DISCONNECT_RESUME: Disconnect after resume. |
551 | * @IEEE80211_SDATA_IN_DRIVER: indicates interface was added to driver | ||
546 | */ | 552 | */ |
547 | enum ieee80211_sub_if_data_flags { | 553 | enum ieee80211_sub_if_data_flags { |
548 | IEEE80211_SDATA_ALLMULTI = BIT(0), | 554 | IEEE80211_SDATA_ALLMULTI = BIT(0), |
@@ -550,6 +556,7 @@ enum ieee80211_sub_if_data_flags { | |||
550 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), | 556 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), |
551 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), | 557 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), |
552 | IEEE80211_SDATA_DISCONNECT_RESUME = BIT(4), | 558 | IEEE80211_SDATA_DISCONNECT_RESUME = BIT(4), |
559 | IEEE80211_SDATA_IN_DRIVER = BIT(5), | ||
553 | }; | 560 | }; |
554 | 561 | ||
555 | /** | 562 | /** |
@@ -722,17 +729,16 @@ enum { | |||
722 | * operating channel | 729 | * operating channel |
723 | * @SCAN_SET_CHANNEL: Set the next channel to be scanned | 730 | * @SCAN_SET_CHANNEL: Set the next channel to be scanned |
724 | * @SCAN_SEND_PROBE: Send probe requests and wait for probe responses | 731 | * @SCAN_SEND_PROBE: Send probe requests and wait for probe responses |
725 | * @SCAN_LEAVE_OPER_CHANNEL: Leave the operating channel, notify the AP | 732 | * @SCAN_SUSPEND: Suspend the scan and go back to operating channel to |
726 | * about us leaving the channel and stop all associated STA interfaces | 733 | * send out data |
727 | * @SCAN_ENTER_OPER_CHANNEL: Enter the operating channel again, notify the | 734 | * @SCAN_RESUME: Resume the scan and scan the next channel |
728 | * AP about us being back and restart all associated STA interfaces | ||
729 | */ | 735 | */ |
730 | enum mac80211_scan_state { | 736 | enum mac80211_scan_state { |
731 | SCAN_DECISION, | 737 | SCAN_DECISION, |
732 | SCAN_SET_CHANNEL, | 738 | SCAN_SET_CHANNEL, |
733 | SCAN_SEND_PROBE, | 739 | SCAN_SEND_PROBE, |
734 | SCAN_LEAVE_OPER_CHANNEL, | 740 | SCAN_SUSPEND, |
735 | SCAN_ENTER_OPER_CHANNEL, | 741 | SCAN_RESUME, |
736 | }; | 742 | }; |
737 | 743 | ||
738 | struct ieee80211_local { | 744 | struct ieee80211_local { |
@@ -1012,6 +1018,9 @@ struct ieee80211_local { | |||
1012 | u32 hw_roc_cookie; | 1018 | u32 hw_roc_cookie; |
1013 | bool hw_roc_for_tx; | 1019 | bool hw_roc_for_tx; |
1014 | 1020 | ||
1021 | struct idr ack_status_frames; | ||
1022 | spinlock_t ack_status_lock; | ||
1023 | |||
1015 | /* dummy netdev for use w/ NAPI */ | 1024 | /* dummy netdev for use w/ NAPI */ |
1016 | struct net_device napi_dev; | 1025 | struct net_device napi_dev; |
1017 | 1026 | ||
@@ -1334,6 +1343,12 @@ void ieee80211_recalc_smps(struct ieee80211_local *local); | |||
1334 | size_t ieee80211_ie_split(const u8 *ies, size_t ielen, | 1343 | size_t ieee80211_ie_split(const u8 *ies, size_t ielen, |
1335 | const u8 *ids, int n_ids, size_t offset); | 1344 | const u8 *ids, int n_ids, size_t offset); |
1336 | size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); | 1345 | size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); |
1346 | u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband, | ||
1347 | u16 cap); | ||
1348 | u8 *ieee80211_ie_build_ht_info(u8 *pos, | ||
1349 | struct ieee80211_sta_ht_cap *ht_cap, | ||
1350 | struct ieee80211_channel *channel, | ||
1351 | enum nl80211_channel_type channel_type); | ||
1337 | 1352 | ||
1338 | /* internal work items */ | 1353 | /* internal work items */ |
1339 | void ieee80211_work_init(struct ieee80211_local *local); | 1354 | void ieee80211_work_init(struct ieee80211_local *local); |
@@ -1362,6 +1377,8 @@ ieee80211_get_channel_mode(struct ieee80211_local *local, | |||
1362 | bool ieee80211_set_channel_type(struct ieee80211_local *local, | 1377 | bool ieee80211_set_channel_type(struct ieee80211_local *local, |
1363 | struct ieee80211_sub_if_data *sdata, | 1378 | struct ieee80211_sub_if_data *sdata, |
1364 | enum nl80211_channel_type chantype); | 1379 | enum nl80211_channel_type chantype); |
1380 | enum nl80211_channel_type | ||
1381 | ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info); | ||
1365 | 1382 | ||
1366 | #ifdef CONFIG_MAC80211_NOINLINE | 1383 | #ifdef CONFIG_MAC80211_NOINLINE |
1367 | #define debug_noinline noinline | 1384 | #define debug_noinline noinline |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 30d73552e9ab..12a6d4bb5d37 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -188,11 +188,22 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
188 | if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) | 188 | if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) |
189 | return -ENOLINK; | 189 | return -ENOLINK; |
190 | break; | 190 | break; |
191 | case NL80211_IFTYPE_AP_VLAN: | 191 | case NL80211_IFTYPE_AP_VLAN: { |
192 | struct ieee80211_sub_if_data *master; | ||
193 | |||
192 | if (!sdata->bss) | 194 | if (!sdata->bss) |
193 | return -ENOLINK; | 195 | return -ENOLINK; |
196 | |||
194 | list_add(&sdata->u.vlan.list, &sdata->bss->vlans); | 197 | list_add(&sdata->u.vlan.list, &sdata->bss->vlans); |
198 | |||
199 | master = container_of(sdata->bss, | ||
200 | struct ieee80211_sub_if_data, u.ap); | ||
201 | sdata->control_port_protocol = | ||
202 | master->control_port_protocol; | ||
203 | sdata->control_port_no_encrypt = | ||
204 | master->control_port_no_encrypt; | ||
195 | break; | 205 | break; |
206 | } | ||
196 | case NL80211_IFTYPE_AP: | 207 | case NL80211_IFTYPE_AP: |
197 | sdata->bss = &sdata->u.ap; | 208 | sdata->bss = &sdata->u.ap; |
198 | break; | 209 | break; |
@@ -265,7 +276,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
265 | break; | 276 | break; |
266 | default: | 277 | default: |
267 | if (coming_up) { | 278 | if (coming_up) { |
268 | res = drv_add_interface(local, &sdata->vif); | 279 | res = drv_add_interface(local, sdata); |
269 | if (res) | 280 | if (res) |
270 | goto err_stop; | 281 | goto err_stop; |
271 | } | 282 | } |
@@ -282,10 +293,18 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
282 | changed |= ieee80211_reset_erp_info(sdata); | 293 | changed |= ieee80211_reset_erp_info(sdata); |
283 | ieee80211_bss_info_change_notify(sdata, changed); | 294 | ieee80211_bss_info_change_notify(sdata, changed); |
284 | 295 | ||
285 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 296 | if (sdata->vif.type == NL80211_IFTYPE_STATION || |
297 | sdata->vif.type == NL80211_IFTYPE_ADHOC) | ||
286 | netif_carrier_off(dev); | 298 | netif_carrier_off(dev); |
287 | else | 299 | else |
288 | netif_carrier_on(dev); | 300 | netif_carrier_on(dev); |
301 | |||
302 | /* | ||
303 | * set default queue parameters so drivers don't | ||
304 | * need to initialise the hardware if the hardware | ||
305 | * doesn't start up with sane defaults | ||
306 | */ | ||
307 | ieee80211_set_wmm_default(sdata); | ||
289 | } | 308 | } |
290 | 309 | ||
291 | set_bit(SDATA_STATE_RUNNING, &sdata->state); | 310 | set_bit(SDATA_STATE_RUNNING, &sdata->state); |
@@ -329,15 +348,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
329 | if (coming_up) | 348 | if (coming_up) |
330 | local->open_count++; | 349 | local->open_count++; |
331 | 350 | ||
332 | if (hw_reconf_flags) { | 351 | if (hw_reconf_flags) |
333 | ieee80211_hw_config(local, hw_reconf_flags); | 352 | ieee80211_hw_config(local, hw_reconf_flags); |
334 | /* | ||
335 | * set default queue parameters so drivers don't | ||
336 | * need to initialise the hardware if the hardware | ||
337 | * doesn't start up with sane defaults | ||
338 | */ | ||
339 | ieee80211_set_wmm_default(sdata); | ||
340 | } | ||
341 | 353 | ||
342 | ieee80211_recalc_ps(local, -1); | 354 | ieee80211_recalc_ps(local, -1); |
343 | 355 | ||
@@ -345,7 +357,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
345 | 357 | ||
346 | return 0; | 358 | return 0; |
347 | err_del_interface: | 359 | err_del_interface: |
348 | drv_remove_interface(local, &sdata->vif); | 360 | drv_remove_interface(local, sdata); |
349 | err_stop: | 361 | err_stop: |
350 | if (!local->open_count) | 362 | if (!local->open_count) |
351 | drv_stop(local); | 363 | drv_stop(local); |
@@ -450,15 +462,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
450 | struct ieee80211_sub_if_data *vlan, *tmpsdata; | 462 | struct ieee80211_sub_if_data *vlan, *tmpsdata; |
451 | struct beacon_data *old_beacon = | 463 | struct beacon_data *old_beacon = |
452 | rtnl_dereference(sdata->u.ap.beacon); | 464 | rtnl_dereference(sdata->u.ap.beacon); |
465 | struct sk_buff *old_probe_resp = | ||
466 | rtnl_dereference(sdata->u.ap.probe_resp); | ||
453 | 467 | ||
454 | /* sdata_running will return false, so this will disable */ | 468 | /* sdata_running will return false, so this will disable */ |
455 | ieee80211_bss_info_change_notify(sdata, | 469 | ieee80211_bss_info_change_notify(sdata, |
456 | BSS_CHANGED_BEACON_ENABLED); | 470 | BSS_CHANGED_BEACON_ENABLED); |
457 | 471 | ||
458 | /* remove beacon */ | 472 | /* remove beacon and probe response */ |
459 | RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); | 473 | RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); |
474 | RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL); | ||
460 | synchronize_rcu(); | 475 | synchronize_rcu(); |
461 | kfree(old_beacon); | 476 | kfree(old_beacon); |
477 | kfree(old_probe_resp); | ||
462 | 478 | ||
463 | /* down all dependent devices, that is VLANs */ | 479 | /* down all dependent devices, that is VLANs */ |
464 | list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, | 480 | list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, |
@@ -520,7 +536,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
520 | ieee80211_free_keys(sdata); | 536 | ieee80211_free_keys(sdata); |
521 | 537 | ||
522 | if (going_down) | 538 | if (going_down) |
523 | drv_remove_interface(local, &sdata->vif); | 539 | drv_remove_interface(local, sdata); |
524 | } | 540 | } |
525 | 541 | ||
526 | sdata->bss = NULL; | 542 | sdata->bss = NULL; |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index fb02ea52d2c2..87a89741432d 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -134,9 +134,13 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
134 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; | 134 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; |
135 | 135 | ||
136 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | 136 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || |
137 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))) | 137 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || |
138 | (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | ||
138 | sdata->crypto_tx_tailroom_needed_cnt--; | 139 | sdata->crypto_tx_tailroom_needed_cnt--; |
139 | 140 | ||
141 | WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && | ||
142 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)); | ||
143 | |||
140 | return 0; | 144 | return 0; |
141 | } | 145 | } |
142 | 146 | ||
@@ -179,7 +183,8 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
179 | sdata = key->sdata; | 183 | sdata = key->sdata; |
180 | 184 | ||
181 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | 185 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || |
182 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))) | 186 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || |
187 | (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | ||
183 | increment_tailroom_need_count(sdata); | 188 | increment_tailroom_need_count(sdata); |
184 | 189 | ||
185 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 190 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index d999bf3b84e1..e323d4e6647b 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -100,7 +100,7 @@ static void ieee80211_reconfig_filter(struct work_struct *work) | |||
100 | */ | 100 | */ |
101 | bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) | 101 | bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) |
102 | { | 102 | { |
103 | struct ieee80211_channel *chan, *scan_chan; | 103 | struct ieee80211_channel *chan; |
104 | enum nl80211_channel_type channel_type; | 104 | enum nl80211_channel_type channel_type; |
105 | 105 | ||
106 | /* This logic needs to match logic in ieee80211_hw_config */ | 106 | /* This logic needs to match logic in ieee80211_hw_config */ |
@@ -114,7 +114,7 @@ bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) | |||
114 | else | 114 | else |
115 | channel_type = NL80211_CHAN_NO_HT; | 115 | channel_type = NL80211_CHAN_NO_HT; |
116 | } else if (local->tmp_channel) { | 116 | } else if (local->tmp_channel) { |
117 | chan = scan_chan = local->tmp_channel; | 117 | chan = local->tmp_channel; |
118 | channel_type = local->tmp_channel_type; | 118 | channel_type = local->tmp_channel_type; |
119 | } else { | 119 | } else { |
120 | chan = local->oper_channel; | 120 | chan = local->oper_channel; |
@@ -126,8 +126,8 @@ bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) | |||
126 | return false; | 126 | return false; |
127 | 127 | ||
128 | /* Check current hardware-config against oper_channel. */ | 128 | /* Check current hardware-config against oper_channel. */ |
129 | if ((local->oper_channel != local->hw.conf.channel) || | 129 | if (local->oper_channel != local->hw.conf.channel || |
130 | (local->_oper_channel_type != local->hw.conf.channel_type)) | 130 | local->_oper_channel_type != local->hw.conf.channel_type) |
131 | return false; | 131 | return false; |
132 | 132 | ||
133 | return true; | 133 | return true; |
@@ -135,7 +135,7 @@ bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) | |||
135 | 135 | ||
136 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | 136 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) |
137 | { | 137 | { |
138 | struct ieee80211_channel *chan, *scan_chan; | 138 | struct ieee80211_channel *chan; |
139 | int ret = 0; | 139 | int ret = 0; |
140 | int power; | 140 | int power; |
141 | enum nl80211_channel_type channel_type; | 141 | enum nl80211_channel_type channel_type; |
@@ -143,14 +143,12 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
143 | 143 | ||
144 | might_sleep(); | 144 | might_sleep(); |
145 | 145 | ||
146 | scan_chan = local->scan_channel; | ||
147 | |||
148 | /* If this off-channel logic ever changes, ieee80211_on_oper_channel | 146 | /* If this off-channel logic ever changes, ieee80211_on_oper_channel |
149 | * may need to change as well. | 147 | * may need to change as well. |
150 | */ | 148 | */ |
151 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | 149 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; |
152 | if (scan_chan) { | 150 | if (local->scan_channel) { |
153 | chan = scan_chan; | 151 | chan = local->scan_channel; |
154 | /* If scanning on oper channel, use whatever channel-type | 152 | /* If scanning on oper channel, use whatever channel-type |
155 | * is currently in use. | 153 | * is currently in use. |
156 | */ | 154 | */ |
@@ -159,7 +157,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
159 | else | 157 | else |
160 | channel_type = NL80211_CHAN_NO_HT; | 158 | channel_type = NL80211_CHAN_NO_HT; |
161 | } else if (local->tmp_channel) { | 159 | } else if (local->tmp_channel) { |
162 | chan = scan_chan = local->tmp_channel; | 160 | chan = local->tmp_channel; |
163 | channel_type = local->tmp_channel_type; | 161 | channel_type = local->tmp_channel_type; |
164 | } else { | 162 | } else { |
165 | chan = local->oper_channel; | 163 | chan = local->oper_channel; |
@@ -595,7 +593,10 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
595 | 593 | ||
596 | wiphy->flags |= WIPHY_FLAG_NETNS_OK | | 594 | wiphy->flags |= WIPHY_FLAG_NETNS_OK | |
597 | WIPHY_FLAG_4ADDR_AP | | 595 | WIPHY_FLAG_4ADDR_AP | |
598 | WIPHY_FLAG_4ADDR_STATION; | 596 | WIPHY_FLAG_4ADDR_STATION | |
597 | WIPHY_FLAG_REPORTS_OBSS; | ||
598 | |||
599 | wiphy->features = NL80211_FEATURE_SK_TX_STATUS; | ||
599 | 600 | ||
600 | if (!ops->set_key) | 601 | if (!ops->set_key) |
601 | wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | 602 | wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
@@ -670,6 +671,11 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
670 | INIT_WORK(&local->sched_scan_stopped_work, | 671 | INIT_WORK(&local->sched_scan_stopped_work, |
671 | ieee80211_sched_scan_stopped_work); | 672 | ieee80211_sched_scan_stopped_work); |
672 | 673 | ||
674 | spin_lock_init(&local->ack_status_lock); | ||
675 | idr_init(&local->ack_status_frames); | ||
676 | /* preallocate at least one entry */ | ||
677 | idr_pre_get(&local->ack_status_frames, GFP_KERNEL); | ||
678 | |||
673 | sta_info_init(local); | 679 | sta_info_init(local); |
674 | 680 | ||
675 | for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { | 681 | for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { |
@@ -1045,6 +1051,13 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1045 | } | 1051 | } |
1046 | EXPORT_SYMBOL(ieee80211_unregister_hw); | 1052 | EXPORT_SYMBOL(ieee80211_unregister_hw); |
1047 | 1053 | ||
1054 | static int ieee80211_free_ack_frame(int id, void *p, void *data) | ||
1055 | { | ||
1056 | WARN_ONCE(1, "Have pending ack frames!\n"); | ||
1057 | kfree_skb(p); | ||
1058 | return 0; | ||
1059 | } | ||
1060 | |||
1048 | void ieee80211_free_hw(struct ieee80211_hw *hw) | 1061 | void ieee80211_free_hw(struct ieee80211_hw *hw) |
1049 | { | 1062 | { |
1050 | struct ieee80211_local *local = hw_to_local(hw); | 1063 | struct ieee80211_local *local = hw_to_local(hw); |
@@ -1055,6 +1068,10 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) | |||
1055 | if (local->wiphy_ciphers_allocated) | 1068 | if (local->wiphy_ciphers_allocated) |
1056 | kfree(local->hw.wiphy->cipher_suites); | 1069 | kfree(local->hw.wiphy->cipher_suites); |
1057 | 1070 | ||
1071 | idr_for_each(&local->ack_status_frames, | ||
1072 | ieee80211_free_ack_frame, NULL); | ||
1073 | idr_destroy(&local->ack_status_frames); | ||
1074 | |||
1058 | wiphy_free(local->hw.wiphy); | 1075 | wiphy_free(local->hw.wiphy); |
1059 | } | 1076 | } |
1060 | EXPORT_SYMBOL(ieee80211_free_hw); | 1077 | EXPORT_SYMBOL(ieee80211_free_hw); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index a7078fdba8ca..b3a125f60347 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -76,6 +76,7 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data) | |||
76 | bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_data *sdata) | 76 | bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_data *sdata) |
77 | { | 77 | { |
78 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 78 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
79 | struct ieee80211_local *local = sdata->local; | ||
79 | 80 | ||
80 | /* | 81 | /* |
81 | * As support for each feature is added, check for matching | 82 | * As support for each feature is added, check for matching |
@@ -87,15 +88,23 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_dat | |||
87 | * - MDA enabled | 88 | * - MDA enabled |
88 | * - Power management control on fc | 89 | * - Power management control on fc |
89 | */ | 90 | */ |
90 | if (ifmsh->mesh_id_len == ie->mesh_id_len && | 91 | if (!(ifmsh->mesh_id_len == ie->mesh_id_len && |
91 | memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 && | 92 | memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 && |
92 | (ifmsh->mesh_pp_id == ie->mesh_config->meshconf_psel) && | 93 | (ifmsh->mesh_pp_id == ie->mesh_config->meshconf_psel) && |
93 | (ifmsh->mesh_pm_id == ie->mesh_config->meshconf_pmetric) && | 94 | (ifmsh->mesh_pm_id == ie->mesh_config->meshconf_pmetric) && |
94 | (ifmsh->mesh_cc_id == ie->mesh_config->meshconf_congest) && | 95 | (ifmsh->mesh_cc_id == ie->mesh_config->meshconf_congest) && |
95 | (ifmsh->mesh_sp_id == ie->mesh_config->meshconf_synch) && | 96 | (ifmsh->mesh_sp_id == ie->mesh_config->meshconf_synch) && |
96 | (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)) | 97 | (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth))) |
97 | return true; | 98 | goto mismatch; |
98 | 99 | ||
100 | /* disallow peering with mismatched channel types for now */ | ||
101 | if (ie->ht_info_elem && | ||
102 | (local->_oper_channel_type != | ||
103 | ieee80211_ht_info_to_channel_type(ie->ht_info_elem))) | ||
104 | goto mismatch; | ||
105 | |||
106 | return true; | ||
107 | mismatch: | ||
99 | return false; | 108 | return false; |
100 | } | 109 | } |
101 | 110 | ||
@@ -341,6 +350,49 @@ int mesh_add_ds_params_ie(struct sk_buff *skb, | |||
341 | return 0; | 350 | return 0; |
342 | } | 351 | } |
343 | 352 | ||
353 | int mesh_add_ht_cap_ie(struct sk_buff *skb, | ||
354 | struct ieee80211_sub_if_data *sdata) | ||
355 | { | ||
356 | struct ieee80211_local *local = sdata->local; | ||
357 | struct ieee80211_supported_band *sband; | ||
358 | u8 *pos; | ||
359 | |||
360 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | ||
361 | if (!sband->ht_cap.ht_supported || | ||
362 | local->_oper_channel_type == NL80211_CHAN_NO_HT) | ||
363 | return 0; | ||
364 | |||
365 | if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap)) | ||
366 | return -ENOMEM; | ||
367 | |||
368 | pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_cap)); | ||
369 | ieee80211_ie_build_ht_cap(pos, sband, sband->ht_cap.cap); | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | int mesh_add_ht_info_ie(struct sk_buff *skb, | ||
375 | struct ieee80211_sub_if_data *sdata) | ||
376 | { | ||
377 | struct ieee80211_local *local = sdata->local; | ||
378 | struct ieee80211_channel *channel = local->oper_channel; | ||
379 | enum nl80211_channel_type channel_type = local->_oper_channel_type; | ||
380 | struct ieee80211_supported_band *sband = | ||
381 | local->hw.wiphy->bands[channel->band]; | ||
382 | struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap; | ||
383 | u8 *pos; | ||
384 | |||
385 | if (!ht_cap->ht_supported || channel_type == NL80211_CHAN_NO_HT) | ||
386 | return 0; | ||
387 | |||
388 | if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_info)) | ||
389 | return -ENOMEM; | ||
390 | |||
391 | pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_info)); | ||
392 | ieee80211_ie_build_ht_info(pos, ht_cap, channel, channel_type); | ||
393 | |||
394 | return 0; | ||
395 | } | ||
344 | static void ieee80211_mesh_path_timer(unsigned long data) | 396 | static void ieee80211_mesh_path_timer(unsigned long data) |
345 | { | 397 | { |
346 | struct ieee80211_sub_if_data *sdata = | 398 | struct ieee80211_sub_if_data *sdata = |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 8c00e2d1d636..622cc96eb4de 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -31,6 +31,8 @@ | |||
31 | * @MESH_PATH_FIXED: the mesh path has been manually set and should not be | 31 | * @MESH_PATH_FIXED: the mesh path has been manually set and should not be |
32 | * modified | 32 | * modified |
33 | * @MESH_PATH_RESOLVED: the mesh path can has been resolved | 33 | * @MESH_PATH_RESOLVED: the mesh path can has been resolved |
34 | * @MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination | ||
35 | * already queued up, waiting for the discovery process to start. | ||
34 | * | 36 | * |
35 | * MESH_PATH_RESOLVED is used by the mesh path timer to | 37 | * MESH_PATH_RESOLVED is used by the mesh path timer to |
36 | * decide when to stop or cancel the mesh path discovery. | 38 | * decide when to stop or cancel the mesh path discovery. |
@@ -41,6 +43,7 @@ enum mesh_path_flags { | |||
41 | MESH_PATH_SN_VALID = BIT(2), | 43 | MESH_PATH_SN_VALID = BIT(2), |
42 | MESH_PATH_FIXED = BIT(3), | 44 | MESH_PATH_FIXED = BIT(3), |
43 | MESH_PATH_RESOLVED = BIT(4), | 45 | MESH_PATH_RESOLVED = BIT(4), |
46 | MESH_PATH_REQ_QUEUED = BIT(5), | ||
44 | }; | 47 | }; |
45 | 48 | ||
46 | /** | 49 | /** |
@@ -212,6 +215,10 @@ int mesh_add_vendor_ies(struct sk_buff *skb, | |||
212 | struct ieee80211_sub_if_data *sdata); | 215 | struct ieee80211_sub_if_data *sdata); |
213 | int mesh_add_ds_params_ie(struct sk_buff *skb, | 216 | int mesh_add_ds_params_ie(struct sk_buff *skb, |
214 | struct ieee80211_sub_if_data *sdata); | 217 | struct ieee80211_sub_if_data *sdata); |
218 | int mesh_add_ht_cap_ie(struct sk_buff *skb, | ||
219 | struct ieee80211_sub_if_data *sdata); | ||
220 | int mesh_add_ht_info_ie(struct sk_buff *skb, | ||
221 | struct ieee80211_sub_if_data *sdata); | ||
215 | void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); | 222 | void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); |
216 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); | 223 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); |
217 | void ieee80211s_init(void); | 224 | void ieee80211s_init(void); |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 174040a42887..a7afb2d32def 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -113,20 +113,20 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | |||
113 | struct ieee80211_sub_if_data *sdata) | 113 | struct ieee80211_sub_if_data *sdata) |
114 | { | 114 | { |
115 | struct ieee80211_local *local = sdata->local; | 115 | struct ieee80211_local *local = sdata->local; |
116 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | 116 | struct sk_buff *skb; |
117 | struct ieee80211_mgmt *mgmt; | 117 | struct ieee80211_mgmt *mgmt; |
118 | u8 *pos; | 118 | u8 *pos, ie_len; |
119 | int ie_len; | 119 | int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) + |
120 | sizeof(mgmt->u.action.u.mesh_action); | ||
120 | 121 | ||
122 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | ||
123 | hdr_len + | ||
124 | 2 + 37); /* max HWMP IE */ | ||
121 | if (!skb) | 125 | if (!skb) |
122 | return -1; | 126 | return -1; |
123 | skb_reserve(skb, local->hw.extra_tx_headroom); | 127 | skb_reserve(skb, local->hw.extra_tx_headroom); |
124 | /* 25 is the size of the common mgmt part (24) plus the size of the | 128 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); |
125 | * common action part (1) | 129 | memset(mgmt, 0, hdr_len); |
126 | */ | ||
127 | mgmt = (struct ieee80211_mgmt *) | ||
128 | skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action)); | ||
129 | memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action)); | ||
130 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 130 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
131 | IEEE80211_STYPE_ACTION); | 131 | IEEE80211_STYPE_ACTION); |
132 | 132 | ||
@@ -240,20 +240,20 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, | |||
240 | struct ieee80211_sub_if_data *sdata) | 240 | struct ieee80211_sub_if_data *sdata) |
241 | { | 241 | { |
242 | struct ieee80211_local *local = sdata->local; | 242 | struct ieee80211_local *local = sdata->local; |
243 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | 243 | struct sk_buff *skb; |
244 | struct ieee80211_mgmt *mgmt; | 244 | struct ieee80211_mgmt *mgmt; |
245 | u8 *pos; | 245 | u8 *pos, ie_len; |
246 | int ie_len; | 246 | int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) + |
247 | sizeof(mgmt->u.action.u.mesh_action); | ||
247 | 248 | ||
249 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | ||
250 | hdr_len + | ||
251 | 2 + 15 /* PERR IE */); | ||
248 | if (!skb) | 252 | if (!skb) |
249 | return -1; | 253 | return -1; |
250 | skb_reserve(skb, local->tx_headroom + local->hw.extra_tx_headroom); | 254 | skb_reserve(skb, local->tx_headroom + local->hw.extra_tx_headroom); |
251 | /* 25 is the size of the common mgmt part (24) plus the size of the | 255 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); |
252 | * common action part (1) | 256 | memset(mgmt, 0, hdr_len); |
253 | */ | ||
254 | mgmt = (struct ieee80211_mgmt *) | ||
255 | skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action)); | ||
256 | memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action)); | ||
257 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 257 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
258 | IEEE80211_STYPE_ACTION); | 258 | IEEE80211_STYPE_ACTION); |
259 | 259 | ||
@@ -867,9 +867,19 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) | |||
867 | return; | 867 | return; |
868 | } | 868 | } |
869 | 869 | ||
870 | spin_lock_bh(&mpath->state_lock); | ||
871 | if (mpath->flags & MESH_PATH_REQ_QUEUED) { | ||
872 | spin_unlock_bh(&mpath->state_lock); | ||
873 | spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); | ||
874 | return; | ||
875 | } | ||
876 | |||
870 | memcpy(preq_node->dst, mpath->dst, ETH_ALEN); | 877 | memcpy(preq_node->dst, mpath->dst, ETH_ALEN); |
871 | preq_node->flags = flags; | 878 | preq_node->flags = flags; |
872 | 879 | ||
880 | mpath->flags |= MESH_PATH_REQ_QUEUED; | ||
881 | spin_unlock_bh(&mpath->state_lock); | ||
882 | |||
873 | list_add_tail(&preq_node->list, &ifmsh->preq_queue.list); | 883 | list_add_tail(&preq_node->list, &ifmsh->preq_queue.list); |
874 | ++ifmsh->preq_queue_len; | 884 | ++ifmsh->preq_queue_len; |
875 | spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); | 885 | spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); |
@@ -921,6 +931,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) | |||
921 | goto enddiscovery; | 931 | goto enddiscovery; |
922 | 932 | ||
923 | spin_lock_bh(&mpath->state_lock); | 933 | spin_lock_bh(&mpath->state_lock); |
934 | mpath->flags &= ~MESH_PATH_REQ_QUEUED; | ||
924 | if (preq_node->flags & PREQ_Q_F_START) { | 935 | if (preq_node->flags & PREQ_Q_F_START) { |
925 | if (mpath->flags & MESH_PATH_RESOLVING) { | 936 | if (mpath->flags & MESH_PATH_RESOLVING) { |
926 | spin_unlock_bh(&mpath->state_lock); | 937 | spin_unlock_bh(&mpath->state_lock); |
@@ -1028,11 +1039,11 @@ int mesh_nexthop_lookup(struct sk_buff *skb, | |||
1028 | mesh_queue_preq(mpath, PREQ_Q_F_START); | 1039 | mesh_queue_preq(mpath, PREQ_Q_F_START); |
1029 | } | 1040 | } |
1030 | 1041 | ||
1031 | if (skb_queue_len(&mpath->frame_queue) >= | 1042 | if (skb_queue_len(&mpath->frame_queue) >= MESH_FRAME_QUEUE_LEN) |
1032 | MESH_FRAME_QUEUE_LEN) | ||
1033 | skb_to_free = skb_dequeue(&mpath->frame_queue); | 1043 | skb_to_free = skb_dequeue(&mpath->frame_queue); |
1034 | 1044 | ||
1035 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1045 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1046 | ieee80211_set_qos_hdr(sdata, skb); | ||
1036 | skb_queue_tail(&mpath->frame_queue, skb); | 1047 | skb_queue_tail(&mpath->frame_queue, skb); |
1037 | if (skb_to_free) | 1048 | if (skb_to_free) |
1038 | mesh_path_discard_frame(skb_to_free, sdata); | 1049 | mesh_path_discard_frame(skb_to_free, sdata); |
@@ -1061,6 +1072,7 @@ void mesh_path_timer(unsigned long data) | |||
1061 | } else if (mpath->discovery_retries < max_preq_retries(sdata)) { | 1072 | } else if (mpath->discovery_retries < max_preq_retries(sdata)) { |
1062 | ++mpath->discovery_retries; | 1073 | ++mpath->discovery_retries; |
1063 | mpath->discovery_timeout *= 2; | 1074 | mpath->discovery_timeout *= 2; |
1075 | mpath->flags &= ~MESH_PATH_REQ_QUEUED; | ||
1064 | spin_unlock_bh(&mpath->state_lock); | 1076 | spin_unlock_bh(&mpath->state_lock); |
1065 | mesh_queue_preq(mpath, 0); | 1077 | mesh_queue_preq(mpath, 0); |
1066 | } else { | 1078 | } else { |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 7f54c5042235..4fc23d1b9c3a 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -213,7 +213,6 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta) | |||
213 | struct ieee80211_hdr *hdr; | 213 | struct ieee80211_hdr *hdr; |
214 | struct sk_buff_head tmpq; | 214 | struct sk_buff_head tmpq; |
215 | unsigned long flags; | 215 | unsigned long flags; |
216 | struct ieee80211_sub_if_data *sdata = mpath->sdata; | ||
217 | 216 | ||
218 | rcu_assign_pointer(mpath->next_hop, sta); | 217 | rcu_assign_pointer(mpath->next_hop, sta); |
219 | 218 | ||
@@ -224,8 +223,6 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta) | |||
224 | while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) { | 223 | while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) { |
225 | hdr = (struct ieee80211_hdr *) skb->data; | 224 | hdr = (struct ieee80211_hdr *) skb->data; |
226 | memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN); | 225 | memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN); |
227 | skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb)); | ||
228 | ieee80211_set_qos_hdr(sdata, skb); | ||
229 | __skb_queue_tail(&tmpq, skb); | 226 | __skb_queue_tail(&tmpq, skb); |
230 | } | 227 | } |
231 | 228 | ||
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 7e57f5d07f66..0140e88a8220 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -80,11 +80,15 @@ static inline void mesh_plink_fsm_restart(struct sta_info *sta) | |||
80 | * on it in the lifecycle management section! | 80 | * on it in the lifecycle management section! |
81 | */ | 81 | */ |
82 | static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | 82 | static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, |
83 | u8 *hw_addr, u32 rates) | 83 | u8 *hw_addr, u32 rates, |
84 | struct ieee802_11_elems *elems) | ||
84 | { | 85 | { |
85 | struct ieee80211_local *local = sdata->local; | 86 | struct ieee80211_local *local = sdata->local; |
87 | struct ieee80211_supported_band *sband; | ||
86 | struct sta_info *sta; | 88 | struct sta_info *sta; |
87 | 89 | ||
90 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | ||
91 | |||
88 | if (local->num_sta >= MESH_MAX_PLINKS) | 92 | if (local->num_sta >= MESH_MAX_PLINKS) |
89 | return NULL; | 93 | return NULL; |
90 | 94 | ||
@@ -96,6 +100,9 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
96 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); | 100 | set_sta_flag(sta, WLAN_STA_AUTHORIZED); |
97 | set_sta_flag(sta, WLAN_STA_WME); | 101 | set_sta_flag(sta, WLAN_STA_WME); |
98 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; | 102 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; |
103 | if (elems->ht_cap_elem) | ||
104 | ieee80211_ht_cap_ie_to_sta_ht_cap(sband, elems->ht_cap_elem, | ||
105 | &sta->sta.ht_cap); | ||
99 | rate_control_rate_init(sta); | 106 | rate_control_rate_init(sta); |
100 | 107 | ||
101 | return sta; | 108 | return sta; |
@@ -153,23 +160,31 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
153 | enum ieee80211_self_protected_actioncode action, | 160 | enum ieee80211_self_protected_actioncode action, |
154 | u8 *da, __le16 llid, __le16 plid, __le16 reason) { | 161 | u8 *da, __le16 llid, __le16 plid, __le16 reason) { |
155 | struct ieee80211_local *local = sdata->local; | 162 | struct ieee80211_local *local = sdata->local; |
156 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + | 163 | struct sk_buff *skb; |
157 | sdata->u.mesh.ie_len); | ||
158 | struct ieee80211_mgmt *mgmt; | 164 | struct ieee80211_mgmt *mgmt; |
159 | bool include_plid = false; | 165 | bool include_plid = false; |
160 | int ie_len = 4; | ||
161 | u16 peering_proto = 0; | 166 | u16 peering_proto = 0; |
162 | u8 *pos; | 167 | u8 *pos, ie_len = 4; |
163 | 168 | int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) + | |
169 | sizeof(mgmt->u.action.u.self_prot); | ||
170 | |||
171 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | ||
172 | hdr_len + | ||
173 | 2 + /* capability info */ | ||
174 | 2 + /* AID */ | ||
175 | 2 + 8 + /* supported rates */ | ||
176 | 2 + (IEEE80211_MAX_SUPP_RATES - 8) + | ||
177 | 2 + sdata->u.mesh.mesh_id_len + | ||
178 | 2 + sizeof(struct ieee80211_meshconf_ie) + | ||
179 | 2 + sizeof(struct ieee80211_ht_cap) + | ||
180 | 2 + sizeof(struct ieee80211_ht_info) + | ||
181 | 2 + 8 + /* peering IE */ | ||
182 | sdata->u.mesh.ie_len); | ||
164 | if (!skb) | 183 | if (!skb) |
165 | return -1; | 184 | return -1; |
166 | skb_reserve(skb, local->hw.extra_tx_headroom); | 185 | skb_reserve(skb, local->hw.extra_tx_headroom); |
167 | /* 25 is the size of the common mgmt part (24) plus the size of the | 186 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); |
168 | * common action part (1) | 187 | memset(mgmt, 0, hdr_len); |
169 | */ | ||
170 | mgmt = (struct ieee80211_mgmt *) | ||
171 | skb_put(skb, 25 + sizeof(mgmt->u.action.u.self_prot)); | ||
172 | memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.self_prot)); | ||
173 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 188 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
174 | IEEE80211_STYPE_ACTION); | 189 | IEEE80211_STYPE_ACTION); |
175 | memcpy(mgmt->da, da, ETH_ALEN); | 190 | memcpy(mgmt->da, da, ETH_ALEN); |
@@ -235,6 +250,13 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
235 | memcpy(pos, &reason, 2); | 250 | memcpy(pos, &reason, 2); |
236 | pos += 2; | 251 | pos += 2; |
237 | } | 252 | } |
253 | |||
254 | if (action != WLAN_SP_MESH_PEERING_CLOSE) { | ||
255 | if (mesh_add_ht_cap_ie(skb, sdata) || | ||
256 | mesh_add_ht_info_ie(skb, sdata)) | ||
257 | return -1; | ||
258 | } | ||
259 | |||
238 | if (mesh_add_vendor_ies(skb, sdata)) | 260 | if (mesh_add_vendor_ies(skb, sdata)) |
239 | return -1; | 261 | return -1; |
240 | 262 | ||
@@ -261,7 +283,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, | |||
261 | elems->ie_start, elems->total_len, | 283 | elems->ie_start, elems->total_len, |
262 | GFP_KERNEL); | 284 | GFP_KERNEL); |
263 | else | 285 | else |
264 | sta = mesh_plink_alloc(sdata, hw_addr, rates); | 286 | sta = mesh_plink_alloc(sdata, hw_addr, rates, elems); |
265 | if (!sta) | 287 | if (!sta) |
266 | return; | 288 | return; |
267 | if (sta_info_insert_rcu(sta)) { | 289 | if (sta_info_insert_rcu(sta)) { |
@@ -552,7 +574,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
552 | } | 574 | } |
553 | 575 | ||
554 | rates = ieee80211_sta_get_rates(local, &elems, rx_status->band); | 576 | rates = ieee80211_sta_get_rates(local, &elems, rx_status->band); |
555 | sta = mesh_plink_alloc(sdata, mgmt->sa, rates); | 577 | sta = mesh_plink_alloc(sdata, mgmt->sa, rates, &elems); |
556 | if (!sta) { | 578 | if (!sta) { |
557 | mpl_dbg("Mesh plink error: plink table full\n"); | 579 | mpl_dbg("Mesh plink error: plink table full\n"); |
558 | return; | 580 | return; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b1b1bb368f70..f9ec15b3fe09 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1468,6 +1468,47 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1468 | return RX_MGMT_CFG80211_DISASSOC; | 1468 | return RX_MGMT_CFG80211_DISASSOC; |
1469 | } | 1469 | } |
1470 | 1470 | ||
1471 | static void ieee80211_get_rates(struct ieee80211_supported_band *sband, | ||
1472 | u8 *supp_rates, unsigned int supp_rates_len, | ||
1473 | u32 *rates, u32 *basic_rates, | ||
1474 | bool *have_higher_than_11mbit, | ||
1475 | int *min_rate, int *min_rate_index) | ||
1476 | { | ||
1477 | int i, j; | ||
1478 | |||
1479 | for (i = 0; i < supp_rates_len; i++) { | ||
1480 | int rate = (supp_rates[i] & 0x7f) * 5; | ||
1481 | bool is_basic = !!(supp_rates[i] & 0x80); | ||
1482 | |||
1483 | if (rate > 110) | ||
1484 | *have_higher_than_11mbit = true; | ||
1485 | |||
1486 | /* | ||
1487 | * BSS_MEMBERSHIP_SELECTOR_HT_PHY is defined in 802.11n-2009 | ||
1488 | * 7.3.2.2 as a magic value instead of a rate. Hence, skip it. | ||
1489 | * | ||
1490 | * Note: Even through the membership selector and the basic | ||
1491 | * rate flag share the same bit, they are not exactly | ||
1492 | * the same. | ||
1493 | */ | ||
1494 | if (!!(supp_rates[i] & 0x80) && | ||
1495 | (supp_rates[i] & 0x7f) == BSS_MEMBERSHIP_SELECTOR_HT_PHY) | ||
1496 | continue; | ||
1497 | |||
1498 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1499 | if (sband->bitrates[j].bitrate == rate) { | ||
1500 | *rates |= BIT(j); | ||
1501 | if (is_basic) | ||
1502 | *basic_rates |= BIT(j); | ||
1503 | if (rate < *min_rate) { | ||
1504 | *min_rate = rate; | ||
1505 | *min_rate_index = j; | ||
1506 | } | ||
1507 | break; | ||
1508 | } | ||
1509 | } | ||
1510 | } | ||
1511 | } | ||
1471 | 1512 | ||
1472 | static bool ieee80211_assoc_success(struct ieee80211_work *wk, | 1513 | static bool ieee80211_assoc_success(struct ieee80211_work *wk, |
1473 | struct ieee80211_mgmt *mgmt, size_t len) | 1514 | struct ieee80211_mgmt *mgmt, size_t len) |
@@ -1484,7 +1525,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1484 | struct ieee802_11_elems elems; | 1525 | struct ieee802_11_elems elems; |
1485 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; | 1526 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
1486 | u32 changed = 0; | 1527 | u32 changed = 0; |
1487 | int i, j, err; | 1528 | int err; |
1488 | bool have_higher_than_11mbit = false; | 1529 | bool have_higher_than_11mbit = false; |
1489 | u16 ap_ht_cap_flags; | 1530 | u16 ap_ht_cap_flags; |
1490 | int min_rate = INT_MAX, min_rate_index = -1; | 1531 | int min_rate = INT_MAX, min_rate_index = -1; |
@@ -1542,47 +1583,14 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, | |||
1542 | basic_rates = 0; | 1583 | basic_rates = 0; |
1543 | sband = local->hw.wiphy->bands[wk->chan->band]; | 1584 | sband = local->hw.wiphy->bands[wk->chan->band]; |
1544 | 1585 | ||
1545 | for (i = 0; i < elems.supp_rates_len; i++) { | 1586 | ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len, |
1546 | int rate = (elems.supp_rates[i] & 0x7f) * 5; | 1587 | &rates, &basic_rates, &have_higher_than_11mbit, |
1547 | bool is_basic = !!(elems.supp_rates[i] & 0x80); | 1588 | &min_rate, &min_rate_index); |
1548 | |||
1549 | if (rate > 110) | ||
1550 | have_higher_than_11mbit = true; | ||
1551 | 1589 | ||
1552 | for (j = 0; j < sband->n_bitrates; j++) { | 1590 | ieee80211_get_rates(sband, elems.ext_supp_rates, |
1553 | if (sband->bitrates[j].bitrate == rate) { | 1591 | elems.ext_supp_rates_len, &rates, &basic_rates, |
1554 | rates |= BIT(j); | 1592 | &have_higher_than_11mbit, |
1555 | if (is_basic) | 1593 | &min_rate, &min_rate_index); |
1556 | basic_rates |= BIT(j); | ||
1557 | if (rate < min_rate) { | ||
1558 | min_rate = rate; | ||
1559 | min_rate_index = j; | ||
1560 | } | ||
1561 | break; | ||
1562 | } | ||
1563 | } | ||
1564 | } | ||
1565 | |||
1566 | for (i = 0; i < elems.ext_supp_rates_len; i++) { | ||
1567 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; | ||
1568 | bool is_basic = !!(elems.ext_supp_rates[i] & 0x80); | ||
1569 | |||
1570 | if (rate > 110) | ||
1571 | have_higher_than_11mbit = true; | ||
1572 | |||
1573 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1574 | if (sband->bitrates[j].bitrate == rate) { | ||
1575 | rates |= BIT(j); | ||
1576 | if (is_basic) | ||
1577 | basic_rates |= BIT(j); | ||
1578 | if (rate < min_rate) { | ||
1579 | min_rate = rate; | ||
1580 | min_rate_index = j; | ||
1581 | } | ||
1582 | break; | ||
1583 | } | ||
1584 | } | ||
1585 | } | ||
1586 | 1594 | ||
1587 | /* | 1595 | /* |
1588 | * some buggy APs don't advertise basic_rates. use the lowest | 1596 | * some buggy APs don't advertise basic_rates. use the lowest |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 9ee7164b207c..596efaf50e09 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -125,7 +125,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
125 | ieee80211_bss_info_change_notify(sdata, | 125 | ieee80211_bss_info_change_notify(sdata, |
126 | BSS_CHANGED_BEACON_ENABLED); | 126 | BSS_CHANGED_BEACON_ENABLED); |
127 | 127 | ||
128 | drv_remove_interface(local, &sdata->vif); | 128 | drv_remove_interface(local, sdata); |
129 | } | 129 | } |
130 | 130 | ||
131 | /* stop hardware - this must stop RX */ | 131 | /* stop hardware - this must stop RX */ |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 58a89554b788..b39dda523f39 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -334,8 +334,8 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
334 | 334 | ||
335 | 335 | ||
336 | static void | 336 | static void |
337 | calc_rate_durations(struct minstrel_sta_info *mi, struct ieee80211_local *local, | 337 | calc_rate_durations(struct ieee80211_local *local, struct minstrel_rate *d, |
338 | struct minstrel_rate *d, struct ieee80211_rate *rate) | 338 | struct ieee80211_rate *rate) |
339 | { | 339 | { |
340 | int erp = !!(rate->flags & IEEE80211_RATE_ERP_G); | 340 | int erp = !!(rate->flags & IEEE80211_RATE_ERP_G); |
341 | 341 | ||
@@ -402,8 +402,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
402 | 402 | ||
403 | mr->rix = i; | 403 | mr->rix = i; |
404 | mr->bitrate = sband->bitrates[i].bitrate / 5; | 404 | mr->bitrate = sband->bitrates[i].bitrate / 5; |
405 | calc_rate_durations(mi, local, mr, | 405 | calc_rate_durations(local, mr, &sband->bitrates[i]); |
406 | &sband->bitrates[i]); | ||
407 | 406 | ||
408 | /* calculate maximum number of retransmissions before | 407 | /* calculate maximum number of retransmissions before |
409 | * fallback (based on maximum segment size) */ | 408 | * fallback (based on maximum segment size) */ |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index fb123e2e081a..d1a8869fe05d 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -748,10 +748,11 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) | |||
748 | struct ieee80211_local *local = rx->local; | 748 | struct ieee80211_local *local = rx->local; |
749 | struct ieee80211_hw *hw = &local->hw; | 749 | struct ieee80211_hw *hw = &local->hw; |
750 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 750 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
751 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
751 | struct sta_info *sta = rx->sta; | 752 | struct sta_info *sta = rx->sta; |
752 | struct tid_ampdu_rx *tid_agg_rx; | 753 | struct tid_ampdu_rx *tid_agg_rx; |
753 | u16 sc; | 754 | u16 sc; |
754 | int tid; | 755 | u8 tid, ack_policy; |
755 | 756 | ||
756 | if (!ieee80211_is_data_qos(hdr->frame_control)) | 757 | if (!ieee80211_is_data_qos(hdr->frame_control)) |
757 | goto dont_reorder; | 758 | goto dont_reorder; |
@@ -764,6 +765,8 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) | |||
764 | if (!sta) | 765 | if (!sta) |
765 | goto dont_reorder; | 766 | goto dont_reorder; |
766 | 767 | ||
768 | ack_policy = *ieee80211_get_qos_ctl(hdr) & | ||
769 | IEEE80211_QOS_CTL_ACK_POLICY_MASK; | ||
767 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; | 770 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; |
768 | 771 | ||
769 | tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); | 772 | tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); |
@@ -774,6 +777,15 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) | |||
774 | if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) | 777 | if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) |
775 | goto dont_reorder; | 778 | goto dont_reorder; |
776 | 779 | ||
780 | /* not part of a BA session */ | ||
781 | if (ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK && | ||
782 | ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_NORMAL) | ||
783 | goto dont_reorder; | ||
784 | |||
785 | /* not actually part of this BA session */ | ||
786 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
787 | goto dont_reorder; | ||
788 | |||
777 | /* new, potentially un-ordered, ampdu frame - process it */ | 789 | /* new, potentially un-ordered, ampdu frame - process it */ |
778 | 790 | ||
779 | /* reset session timer */ | 791 | /* reset session timer */ |
@@ -858,6 +870,13 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
858 | rx->sdata->control_port_protocol) | 870 | rx->sdata->control_port_protocol) |
859 | return RX_CONTINUE; | 871 | return RX_CONTINUE; |
860 | } | 872 | } |
873 | |||
874 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && | ||
875 | cfg80211_rx_spurious_frame(rx->sdata->dev, | ||
876 | hdr->addr2, | ||
877 | GFP_ATOMIC)) | ||
878 | return RX_DROP_UNUSABLE; | ||
879 | |||
861 | return RX_DROP_MONITOR; | 880 | return RX_DROP_MONITOR; |
862 | } | 881 | } |
863 | 882 | ||
@@ -1327,15 +1346,20 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1327 | 1346 | ||
1328 | /* | 1347 | /* |
1329 | * If we receive a 4-addr nullfunc frame from a STA | 1348 | * If we receive a 4-addr nullfunc frame from a STA |
1330 | * that was not moved to a 4-addr STA vlan yet, drop | 1349 | * that was not moved to a 4-addr STA vlan yet send |
1331 | * the frame to the monitor interface, to make sure | 1350 | * the event to userspace and for older hostapd drop |
1332 | * that hostapd sees it | 1351 | * the frame to the monitor interface. |
1333 | */ | 1352 | */ |
1334 | if (ieee80211_has_a4(hdr->frame_control) && | 1353 | if (ieee80211_has_a4(hdr->frame_control) && |
1335 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || | 1354 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || |
1336 | (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && | 1355 | (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && |
1337 | !rx->sdata->u.vlan.sta))) | 1356 | !rx->sdata->u.vlan.sta))) { |
1357 | if (!test_and_set_sta_flag(sta, WLAN_STA_4ADDR_EVENT)) | ||
1358 | cfg80211_rx_unexpected_4addr_frame( | ||
1359 | rx->sdata->dev, sta->sta.addr, | ||
1360 | GFP_ATOMIC); | ||
1338 | return RX_DROP_MONITOR; | 1361 | return RX_DROP_MONITOR; |
1362 | } | ||
1339 | /* | 1363 | /* |
1340 | * Update counter and free packet here to avoid | 1364 | * Update counter and free packet here to avoid |
1341 | * counting this as a dropped packed. | 1365 | * counting this as a dropped packed. |
@@ -1933,6 +1957,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1933 | compare_ether_addr(sdata->vif.addr, hdr->addr3) == 0) | 1957 | compare_ether_addr(sdata->vif.addr, hdr->addr3) == 0) |
1934 | return RX_CONTINUE; | 1958 | return RX_CONTINUE; |
1935 | 1959 | ||
1960 | skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb)); | ||
1936 | mesh_hdr->ttl--; | 1961 | mesh_hdr->ttl--; |
1937 | 1962 | ||
1938 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { | 1963 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { |
@@ -1957,12 +1982,10 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1957 | memset(info, 0, sizeof(*info)); | 1982 | memset(info, 0, sizeof(*info)); |
1958 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1983 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1959 | info->control.vif = &rx->sdata->vif; | 1984 | info->control.vif = &rx->sdata->vif; |
1985 | info->control.jiffies = jiffies; | ||
1960 | if (is_multicast_ether_addr(fwd_hdr->addr1)) { | 1986 | if (is_multicast_ether_addr(fwd_hdr->addr1)) { |
1961 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, | 1987 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, |
1962 | fwded_mcast); | 1988 | fwded_mcast); |
1963 | skb_set_queue_mapping(fwd_skb, | ||
1964 | ieee80211_select_queue(sdata, fwd_skb)); | ||
1965 | ieee80211_set_qos_hdr(sdata, fwd_skb); | ||
1966 | } else { | 1989 | } else { |
1967 | int err; | 1990 | int err; |
1968 | /* | 1991 | /* |
@@ -2014,12 +2037,17 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
2014 | return RX_DROP_MONITOR; | 2037 | return RX_DROP_MONITOR; |
2015 | 2038 | ||
2016 | /* | 2039 | /* |
2017 | * Allow the cooked monitor interface of an AP to see 4-addr frames so | 2040 | * Send unexpected-4addr-frame event to hostapd. For older versions, |
2018 | * that a 4-addr station can be detected and moved into a separate VLAN | 2041 | * also drop the frame to cooked monitor interfaces. |
2019 | */ | 2042 | */ |
2020 | if (ieee80211_has_a4(hdr->frame_control) && | 2043 | if (ieee80211_has_a4(hdr->frame_control) && |
2021 | sdata->vif.type == NL80211_IFTYPE_AP) | 2044 | sdata->vif.type == NL80211_IFTYPE_AP) { |
2045 | if (rx->sta && | ||
2046 | !test_and_set_sta_flag(rx->sta, WLAN_STA_4ADDR_EVENT)) | ||
2047 | cfg80211_rx_unexpected_4addr_frame( | ||
2048 | rx->sdata->dev, rx->sta->sta.addr, GFP_ATOMIC); | ||
2022 | return RX_DROP_MONITOR; | 2049 | return RX_DROP_MONITOR; |
2050 | } | ||
2023 | 2051 | ||
2024 | err = __ieee80211_data_to_8023(rx, &port_control); | 2052 | err = __ieee80211_data_to_8023(rx, &port_control); |
2025 | if (unlikely(err)) | 2053 | if (unlikely(err)) |
@@ -2174,6 +2202,18 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) | |||
2174 | if (!ieee80211_is_mgmt(mgmt->frame_control)) | 2202 | if (!ieee80211_is_mgmt(mgmt->frame_control)) |
2175 | return RX_DROP_MONITOR; | 2203 | return RX_DROP_MONITOR; |
2176 | 2204 | ||
2205 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && | ||
2206 | ieee80211_is_beacon(mgmt->frame_control) && | ||
2207 | !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { | ||
2208 | struct ieee80211_rx_status *status; | ||
2209 | |||
2210 | status = IEEE80211_SKB_RXCB(rx->skb); | ||
2211 | cfg80211_report_obss_beacon(rx->local->hw.wiphy, | ||
2212 | rx->skb->data, rx->skb->len, | ||
2213 | status->freq, GFP_ATOMIC); | ||
2214 | rx->flags |= IEEE80211_RX_BEACON_REPORTED; | ||
2215 | } | ||
2216 | |||
2177 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | 2217 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
2178 | return RX_DROP_MONITOR; | 2218 | return RX_DROP_MONITOR; |
2179 | 2219 | ||
@@ -2207,13 +2247,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2207 | 2247 | ||
2208 | switch (mgmt->u.action.category) { | 2248 | switch (mgmt->u.action.category) { |
2209 | case WLAN_CATEGORY_BACK: | 2249 | case WLAN_CATEGORY_BACK: |
2210 | /* | ||
2211 | * The aggregation code is not prepared to handle | ||
2212 | * anything but STA/AP due to the BSSID handling; | ||
2213 | * IBSS could work in the code but isn't supported | ||
2214 | * by drivers or the standard. | ||
2215 | */ | ||
2216 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 2250 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
2251 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && | ||
2217 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 2252 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
2218 | sdata->vif.type != NL80211_IFTYPE_AP) | 2253 | sdata->vif.type != NL80211_IFTYPE_AP) |
2219 | break; | 2254 | break; |
@@ -2493,6 +2528,10 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2493 | goto out_free_skb; | 2528 | goto out_free_skb; |
2494 | rx->flags |= IEEE80211_RX_CMNTR; | 2529 | rx->flags |= IEEE80211_RX_CMNTR; |
2495 | 2530 | ||
2531 | /* If there are no cooked monitor interfaces, just free the SKB */ | ||
2532 | if (!local->cooked_mntrs) | ||
2533 | goto out_free_skb; | ||
2534 | |||
2496 | if (skb_headroom(skb) < sizeof(*rthdr) && | 2535 | if (skb_headroom(skb) < sizeof(*rthdr) && |
2497 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) | 2536 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) |
2498 | goto out_free_skb; | 2537 | goto out_free_skb; |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 105436dbb90d..81863031e0a3 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -213,12 +213,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
213 | if (bss) | 213 | if (bss) |
214 | ieee80211_rx_bss_put(sdata->local, bss); | 214 | ieee80211_rx_bss_put(sdata->local, bss); |
215 | 215 | ||
216 | /* If we are on-operating-channel, and this packet is for the | 216 | if (channel == sdata->local->oper_channel) |
217 | * current channel, pass the pkt on up the stack so that | ||
218 | * the rest of the stack can make use of it. | ||
219 | */ | ||
220 | if (ieee80211_cfg_on_oper_channel(sdata->local) | ||
221 | && (channel == sdata->local->oper_channel)) | ||
222 | return RX_CONTINUE; | 217 | return RX_CONTINUE; |
223 | 218 | ||
224 | dev_kfree_skb(skb); | 219 | dev_kfree_skb(skb); |
@@ -264,8 +259,6 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
264 | bool was_hw_scan) | 259 | bool was_hw_scan) |
265 | { | 260 | { |
266 | struct ieee80211_local *local = hw_to_local(hw); | 261 | struct ieee80211_local *local = hw_to_local(hw); |
267 | bool on_oper_chan; | ||
268 | bool enable_beacons = false; | ||
269 | 262 | ||
270 | lockdep_assert_held(&local->mtx); | 263 | lockdep_assert_held(&local->mtx); |
271 | 264 | ||
@@ -298,25 +291,13 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
298 | local->scanning = 0; | 291 | local->scanning = 0; |
299 | local->scan_channel = NULL; | 292 | local->scan_channel = NULL; |
300 | 293 | ||
301 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); | 294 | /* Set power back to normal operating levels. */ |
302 | 295 | ieee80211_hw_config(local, 0); | |
303 | if (was_hw_scan || !on_oper_chan) | ||
304 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
305 | else | ||
306 | /* Set power back to normal operating levels. */ | ||
307 | ieee80211_hw_config(local, 0); | ||
308 | 296 | ||
309 | if (!was_hw_scan) { | 297 | if (!was_hw_scan) { |
310 | bool on_oper_chan2; | ||
311 | ieee80211_configure_filter(local); | 298 | ieee80211_configure_filter(local); |
312 | drv_sw_scan_complete(local); | 299 | drv_sw_scan_complete(local); |
313 | on_oper_chan2 = ieee80211_cfg_on_oper_channel(local); | 300 | ieee80211_offchannel_return(local, true, true); |
314 | /* We should always be on-channel at this point. */ | ||
315 | WARN_ON(!on_oper_chan2); | ||
316 | if (on_oper_chan2 && (on_oper_chan != on_oper_chan2)) | ||
317 | enable_beacons = true; | ||
318 | |||
319 | ieee80211_offchannel_return(local, enable_beacons, true); | ||
320 | } | 301 | } |
321 | 302 | ||
322 | ieee80211_recalc_idle(local); | 303 | ieee80211_recalc_idle(local); |
@@ -361,11 +342,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
361 | local->next_scan_state = SCAN_DECISION; | 342 | local->next_scan_state = SCAN_DECISION; |
362 | local->scan_channel_idx = 0; | 343 | local->scan_channel_idx = 0; |
363 | 344 | ||
364 | /* We always want to use off-channel PS, even if we | 345 | ieee80211_offchannel_stop_vifs(local, true); |
365 | * are not really leaving oper-channel. Don't | ||
366 | * tell the AP though, as long as we are on-channel. | ||
367 | */ | ||
368 | ieee80211_offchannel_enable_all_ps(local, false); | ||
369 | 346 | ||
370 | ieee80211_configure_filter(local); | 347 | ieee80211_configure_filter(local); |
371 | 348 | ||
@@ -373,8 +350,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
373 | ieee80211_hw_config(local, 0); | 350 | ieee80211_hw_config(local, 0); |
374 | 351 | ||
375 | ieee80211_queue_delayed_work(&local->hw, | 352 | ieee80211_queue_delayed_work(&local->hw, |
376 | &local->scan_work, | 353 | &local->scan_work, 0); |
377 | IEEE80211_CHANNEL_TIME); | ||
378 | 354 | ||
379 | return 0; | 355 | return 0; |
380 | } | 356 | } |
@@ -510,96 +486,39 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, | |||
510 | 486 | ||
511 | next_chan = local->scan_req->channels[local->scan_channel_idx]; | 487 | next_chan = local->scan_req->channels[local->scan_channel_idx]; |
512 | 488 | ||
513 | if (ieee80211_cfg_on_oper_channel(local)) { | ||
514 | /* We're currently on operating channel. */ | ||
515 | if (next_chan == local->oper_channel) | ||
516 | /* We don't need to move off of operating channel. */ | ||
517 | local->next_scan_state = SCAN_SET_CHANNEL; | ||
518 | else | ||
519 | /* | ||
520 | * We do need to leave operating channel, as next | ||
521 | * scan is somewhere else. | ||
522 | */ | ||
523 | local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL; | ||
524 | } else { | ||
525 | /* | ||
526 | * we're currently scanning a different channel, let's | ||
527 | * see if we can scan another channel without interfering | ||
528 | * with the current traffic situation. | ||
529 | * | ||
530 | * Since we don't know if the AP has pending frames for us | ||
531 | * we can only check for our tx queues and use the current | ||
532 | * pm_qos requirements for rx. Hence, if no tx traffic occurs | ||
533 | * at all we will scan as many channels in a row as the pm_qos | ||
534 | * latency allows us to. Additionally we also check for the | ||
535 | * currently negotiated listen interval to prevent losing | ||
536 | * frames unnecessarily. | ||
537 | * | ||
538 | * Otherwise switch back to the operating channel. | ||
539 | */ | ||
540 | |||
541 | bad_latency = time_after(jiffies + | ||
542 | ieee80211_scan_get_channel_time(next_chan), | ||
543 | local->leave_oper_channel_time + | ||
544 | usecs_to_jiffies(pm_qos_request(PM_QOS_NETWORK_LATENCY))); | ||
545 | |||
546 | listen_int_exceeded = time_after(jiffies + | ||
547 | ieee80211_scan_get_channel_time(next_chan), | ||
548 | local->leave_oper_channel_time + | ||
549 | usecs_to_jiffies(min_beacon_int * 1024) * | ||
550 | local->hw.conf.listen_interval); | ||
551 | |||
552 | if (associated && ( !tx_empty || bad_latency || | ||
553 | listen_int_exceeded)) | ||
554 | local->next_scan_state = SCAN_ENTER_OPER_CHANNEL; | ||
555 | else | ||
556 | local->next_scan_state = SCAN_SET_CHANNEL; | ||
557 | } | ||
558 | |||
559 | *next_delay = 0; | ||
560 | } | ||
561 | |||
562 | static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, | ||
563 | unsigned long *next_delay) | ||
564 | { | ||
565 | /* PS will already be in off-channel mode, | ||
566 | * we do that once at the beginning of scanning. | ||
567 | */ | ||
568 | ieee80211_offchannel_stop_vifs(local, false); | ||
569 | |||
570 | /* | 489 | /* |
571 | * What if the nullfunc frames didn't arrive? | 490 | * we're currently scanning a different channel, let's |
491 | * see if we can scan another channel without interfering | ||
492 | * with the current traffic situation. | ||
493 | * | ||
494 | * Since we don't know if the AP has pending frames for us | ||
495 | * we can only check for our tx queues and use the current | ||
496 | * pm_qos requirements for rx. Hence, if no tx traffic occurs | ||
497 | * at all we will scan as many channels in a row as the pm_qos | ||
498 | * latency allows us to. Additionally we also check for the | ||
499 | * currently negotiated listen interval to prevent losing | ||
500 | * frames unnecessarily. | ||
501 | * | ||
502 | * Otherwise switch back to the operating channel. | ||
572 | */ | 503 | */ |
573 | drv_flush(local, false); | ||
574 | if (local->ops->flush) | ||
575 | *next_delay = 0; | ||
576 | else | ||
577 | *next_delay = HZ / 10; | ||
578 | 504 | ||
579 | /* remember when we left the operating channel */ | 505 | bad_latency = time_after(jiffies + |
580 | local->leave_oper_channel_time = jiffies; | 506 | ieee80211_scan_get_channel_time(next_chan), |
507 | local->leave_oper_channel_time + | ||
508 | usecs_to_jiffies(pm_qos_request(PM_QOS_NETWORK_LATENCY))); | ||
581 | 509 | ||
582 | /* advance to the next channel to be scanned */ | 510 | listen_int_exceeded = time_after(jiffies + |
583 | local->next_scan_state = SCAN_SET_CHANNEL; | 511 | ieee80211_scan_get_channel_time(next_chan), |
584 | } | 512 | local->leave_oper_channel_time + |
585 | 513 | usecs_to_jiffies(min_beacon_int * 1024) * | |
586 | static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *local, | 514 | local->hw.conf.listen_interval); |
587 | unsigned long *next_delay) | ||
588 | { | ||
589 | /* switch back to the operating channel */ | ||
590 | local->scan_channel = NULL; | ||
591 | if (!ieee80211_cfg_on_oper_channel(local)) | ||
592 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
593 | 515 | ||
594 | /* | 516 | if (associated && (!tx_empty || bad_latency || listen_int_exceeded)) |
595 | * Re-enable vifs and beaconing. Leave PS | 517 | local->next_scan_state = SCAN_SUSPEND; |
596 | * in off-channel state..will put that back | 518 | else |
597 | * on-channel at the end of scanning. | 519 | local->next_scan_state = SCAN_SET_CHANNEL; |
598 | */ | ||
599 | ieee80211_offchannel_return(local, true, false); | ||
600 | 520 | ||
601 | *next_delay = HZ / 5; | 521 | *next_delay = 0; |
602 | local->next_scan_state = SCAN_DECISION; | ||
603 | } | 522 | } |
604 | 523 | ||
605 | static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, | 524 | static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, |
@@ -613,10 +532,8 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, | |||
613 | 532 | ||
614 | local->scan_channel = chan; | 533 | local->scan_channel = chan; |
615 | 534 | ||
616 | /* Only call hw-config if we really need to change channels. */ | 535 | if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) |
617 | if (chan != local->hw.conf.channel) | 536 | skip = 1; |
618 | if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) | ||
619 | skip = 1; | ||
620 | 537 | ||
621 | /* advance state machine to next channel/band */ | 538 | /* advance state machine to next channel/band */ |
622 | local->scan_channel_idx++; | 539 | local->scan_channel_idx++; |
@@ -673,6 +590,44 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
673 | local->next_scan_state = SCAN_DECISION; | 590 | local->next_scan_state = SCAN_DECISION; |
674 | } | 591 | } |
675 | 592 | ||
593 | static void ieee80211_scan_state_suspend(struct ieee80211_local *local, | ||
594 | unsigned long *next_delay) | ||
595 | { | ||
596 | /* switch back to the operating channel */ | ||
597 | local->scan_channel = NULL; | ||
598 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
599 | |||
600 | /* | ||
601 | * Re-enable vifs and beaconing. Leave PS | ||
602 | * in off-channel state..will put that back | ||
603 | * on-channel at the end of scanning. | ||
604 | */ | ||
605 | ieee80211_offchannel_return(local, true, false); | ||
606 | |||
607 | *next_delay = HZ / 5; | ||
608 | /* afterwards, resume scan & go to next channel */ | ||
609 | local->next_scan_state = SCAN_RESUME; | ||
610 | } | ||
611 | |||
612 | static void ieee80211_scan_state_resume(struct ieee80211_local *local, | ||
613 | unsigned long *next_delay) | ||
614 | { | ||
615 | /* PS already is in off-channel mode */ | ||
616 | ieee80211_offchannel_stop_vifs(local, false); | ||
617 | |||
618 | if (local->ops->flush) { | ||
619 | drv_flush(local, false); | ||
620 | *next_delay = 0; | ||
621 | } else | ||
622 | *next_delay = HZ / 10; | ||
623 | |||
624 | /* remember when we left the operating channel */ | ||
625 | local->leave_oper_channel_time = jiffies; | ||
626 | |||
627 | /* advance to the next channel to be scanned */ | ||
628 | local->next_scan_state = SCAN_DECISION; | ||
629 | } | ||
630 | |||
676 | void ieee80211_scan_work(struct work_struct *work) | 631 | void ieee80211_scan_work(struct work_struct *work) |
677 | { | 632 | { |
678 | struct ieee80211_local *local = | 633 | struct ieee80211_local *local = |
@@ -743,11 +698,11 @@ void ieee80211_scan_work(struct work_struct *work) | |||
743 | case SCAN_SEND_PROBE: | 698 | case SCAN_SEND_PROBE: |
744 | ieee80211_scan_state_send_probe(local, &next_delay); | 699 | ieee80211_scan_state_send_probe(local, &next_delay); |
745 | break; | 700 | break; |
746 | case SCAN_LEAVE_OPER_CHANNEL: | 701 | case SCAN_SUSPEND: |
747 | ieee80211_scan_state_leave_oper_channel(local, &next_delay); | 702 | ieee80211_scan_state_suspend(local, &next_delay); |
748 | break; | 703 | break; |
749 | case SCAN_ENTER_OPER_CHANNEL: | 704 | case SCAN_RESUME: |
750 | ieee80211_scan_state_enter_oper_channel(local, &next_delay); | 705 | ieee80211_scan_state_resume(local, &next_delay); |
751 | break; | 706 | break; |
752 | } | 707 | } |
753 | } while (next_delay == 0); | 708 | } while (next_delay == 0); |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 8c8ce05ad26f..c5923ab8a070 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -52,6 +52,7 @@ | |||
52 | * unblocks the station. | 52 | * unblocks the station. |
53 | * @WLAN_STA_SP: Station is in a service period, so don't try to | 53 | * @WLAN_STA_SP: Station is in a service period, so don't try to |
54 | * reply to other uAPSD trigger frames or PS-Poll. | 54 | * reply to other uAPSD trigger frames or PS-Poll. |
55 | * @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame. | ||
55 | */ | 56 | */ |
56 | enum ieee80211_sta_info_flags { | 57 | enum ieee80211_sta_info_flags { |
57 | WLAN_STA_AUTH, | 58 | WLAN_STA_AUTH, |
@@ -71,6 +72,7 @@ enum ieee80211_sta_info_flags { | |||
71 | WLAN_STA_TDLS_PEER_AUTH, | 72 | WLAN_STA_TDLS_PEER_AUTH, |
72 | WLAN_STA_UAPSD, | 73 | WLAN_STA_UAPSD, |
73 | WLAN_STA_SP, | 74 | WLAN_STA_SP, |
75 | WLAN_STA_4ADDR_EVENT, | ||
74 | }; | 76 | }; |
75 | 77 | ||
76 | #define STA_TID_NUM 16 | 78 | #define STA_TID_NUM 16 |
@@ -390,6 +392,12 @@ static inline int test_and_clear_sta_flag(struct sta_info *sta, | |||
390 | return test_and_clear_bit(flag, &sta->_flags); | 392 | return test_and_clear_bit(flag, &sta->_flags); |
391 | } | 393 | } |
392 | 394 | ||
395 | static inline int test_and_set_sta_flag(struct sta_info *sta, | ||
396 | enum ieee80211_sta_info_flags flag) | ||
397 | { | ||
398 | return test_and_set_bit(flag, &sta->_flags); | ||
399 | } | ||
400 | |||
393 | void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, | 401 | void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, |
394 | struct tid_ampdu_tx *tid_tx); | 402 | struct tid_ampdu_tx *tid_tx); |
395 | 403 | ||
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 16518f386117..46222ce0e5b1 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -517,27 +517,54 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
517 | } | 517 | } |
518 | 518 | ||
519 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { | 519 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { |
520 | struct ieee80211_work *wk; | ||
521 | u64 cookie = (unsigned long)skb; | 520 | u64 cookie = (unsigned long)skb; |
522 | 521 | ||
523 | rcu_read_lock(); | 522 | if (ieee80211_is_nullfunc(hdr->frame_control) || |
524 | list_for_each_entry_rcu(wk, &local->work_list, list) { | 523 | ieee80211_is_qos_nullfunc(hdr->frame_control)) { |
525 | if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX) | 524 | bool acked = info->flags & IEEE80211_TX_STAT_ACK; |
526 | continue; | 525 | cfg80211_probe_status(skb->dev, hdr->addr1, |
527 | if (wk->offchan_tx.frame != skb) | 526 | cookie, acked, GFP_ATOMIC); |
528 | continue; | 527 | } else { |
529 | wk->offchan_tx.status = true; | 528 | struct ieee80211_work *wk; |
530 | break; | 529 | |
531 | } | 530 | rcu_read_lock(); |
532 | rcu_read_unlock(); | 531 | list_for_each_entry_rcu(wk, &local->work_list, list) { |
533 | if (local->hw_roc_skb_for_status == skb) { | 532 | if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX) |
534 | cookie = local->hw_roc_cookie ^ 2; | 533 | continue; |
535 | local->hw_roc_skb_for_status = NULL; | 534 | if (wk->offchan_tx.frame != skb) |
535 | continue; | ||
536 | wk->offchan_tx.status = true; | ||
537 | break; | ||
538 | } | ||
539 | rcu_read_unlock(); | ||
540 | if (local->hw_roc_skb_for_status == skb) { | ||
541 | cookie = local->hw_roc_cookie ^ 2; | ||
542 | local->hw_roc_skb_for_status = NULL; | ||
543 | } | ||
544 | |||
545 | cfg80211_mgmt_tx_status( | ||
546 | skb->dev, cookie, skb->data, skb->len, | ||
547 | !!(info->flags & IEEE80211_TX_STAT_ACK), | ||
548 | GFP_ATOMIC); | ||
536 | } | 549 | } |
550 | } | ||
537 | 551 | ||
538 | cfg80211_mgmt_tx_status( | 552 | if (unlikely(info->ack_frame_id)) { |
539 | skb->dev, cookie, skb->data, skb->len, | 553 | struct sk_buff *ack_skb; |
540 | !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC); | 554 | unsigned long flags; |
555 | |||
556 | spin_lock_irqsave(&local->ack_status_lock, flags); | ||
557 | ack_skb = idr_find(&local->ack_status_frames, | ||
558 | info->ack_frame_id); | ||
559 | if (ack_skb) | ||
560 | idr_remove(&local->ack_status_frames, | ||
561 | info->ack_frame_id); | ||
562 | spin_unlock_irqrestore(&local->ack_status_lock, flags); | ||
563 | |||
564 | /* consumes ack_skb */ | ||
565 | if (ack_skb) | ||
566 | skb_complete_wifi_ack(ack_skb, | ||
567 | info->flags & IEEE80211_TX_STAT_ACK); | ||
541 | } | 568 | } |
542 | 569 | ||
543 | /* this was a transmitted frame, but now we want to reuse it */ | 570 | /* this was a transmitted frame, but now we want to reuse it */ |
@@ -610,3 +637,29 @@ void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets) | |||
610 | num_packets, GFP_ATOMIC); | 637 | num_packets, GFP_ATOMIC); |
611 | } | 638 | } |
612 | EXPORT_SYMBOL(ieee80211_report_low_ack); | 639 | EXPORT_SYMBOL(ieee80211_report_low_ack); |
640 | |||
641 | void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
642 | { | ||
643 | struct ieee80211_local *local = hw_to_local(hw); | ||
644 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
645 | |||
646 | if (unlikely(info->ack_frame_id)) { | ||
647 | struct sk_buff *ack_skb; | ||
648 | unsigned long flags; | ||
649 | |||
650 | spin_lock_irqsave(&local->ack_status_lock, flags); | ||
651 | ack_skb = idr_find(&local->ack_status_frames, | ||
652 | info->ack_frame_id); | ||
653 | if (ack_skb) | ||
654 | idr_remove(&local->ack_status_frames, | ||
655 | info->ack_frame_id); | ||
656 | spin_unlock_irqrestore(&local->ack_status_lock, flags); | ||
657 | |||
658 | /* consumes ack_skb */ | ||
659 | if (ack_skb) | ||
660 | dev_kfree_skb_any(ack_skb); | ||
661 | } | ||
662 | |||
663 | dev_kfree_skb_any(skb); | ||
664 | } | ||
665 | EXPORT_SYMBOL(ieee80211_free_txskb); | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 1f8b120146d1..f044963feb9a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1685,8 +1685,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1685 | int nh_pos, h_pos; | 1685 | int nh_pos, h_pos; |
1686 | struct sta_info *sta = NULL; | 1686 | struct sta_info *sta = NULL; |
1687 | bool wme_sta = false, authorized = false, tdls_auth = false; | 1687 | bool wme_sta = false, authorized = false, tdls_auth = false; |
1688 | struct sk_buff *tmp_skb; | ||
1689 | bool tdls_direct = false; | 1688 | bool tdls_direct = false; |
1689 | bool multicast; | ||
1690 | u32 info_flags = 0; | ||
1691 | u16 info_id = 0; | ||
1690 | 1692 | ||
1691 | if (unlikely(skb->len < ETH_HLEN)) { | 1693 | if (unlikely(skb->len < ETH_HLEN)) { |
1692 | ret = NETDEV_TX_OK; | 1694 | ret = NETDEV_TX_OK; |
@@ -1873,7 +1875,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1873 | * if it is a multicast address (which can only happen | 1875 | * if it is a multicast address (which can only happen |
1874 | * in AP mode) | 1876 | * in AP mode) |
1875 | */ | 1877 | */ |
1876 | if (!is_multicast_ether_addr(hdr.addr1)) { | 1878 | multicast = is_multicast_ether_addr(hdr.addr1); |
1879 | if (!multicast) { | ||
1877 | rcu_read_lock(); | 1880 | rcu_read_lock(); |
1878 | sta = sta_info_get(sdata, hdr.addr1); | 1881 | sta = sta_info_get(sdata, hdr.addr1); |
1879 | if (sta) { | 1882 | if (sta) { |
@@ -1914,11 +1917,54 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1914 | goto fail; | 1917 | goto fail; |
1915 | } | 1918 | } |
1916 | 1919 | ||
1920 | if (unlikely(!multicast && skb->sk && | ||
1921 | skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) { | ||
1922 | struct sk_buff *orig_skb = skb; | ||
1923 | |||
1924 | skb = skb_clone(skb, GFP_ATOMIC); | ||
1925 | if (skb) { | ||
1926 | unsigned long flags; | ||
1927 | int id, r; | ||
1928 | |||
1929 | spin_lock_irqsave(&local->ack_status_lock, flags); | ||
1930 | r = idr_get_new_above(&local->ack_status_frames, | ||
1931 | orig_skb, 1, &id); | ||
1932 | if (r == -EAGAIN) { | ||
1933 | idr_pre_get(&local->ack_status_frames, | ||
1934 | GFP_ATOMIC); | ||
1935 | r = idr_get_new_above(&local->ack_status_frames, | ||
1936 | orig_skb, 1, &id); | ||
1937 | } | ||
1938 | if (WARN_ON(!id) || id > 0xffff) { | ||
1939 | idr_remove(&local->ack_status_frames, id); | ||
1940 | r = -ERANGE; | ||
1941 | } | ||
1942 | spin_unlock_irqrestore(&local->ack_status_lock, flags); | ||
1943 | |||
1944 | if (!r) { | ||
1945 | info_id = id; | ||
1946 | info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1947 | } else if (skb_shared(skb)) { | ||
1948 | kfree_skb(orig_skb); | ||
1949 | } else { | ||
1950 | kfree_skb(skb); | ||
1951 | skb = orig_skb; | ||
1952 | } | ||
1953 | } else { | ||
1954 | /* couldn't clone -- lose tx status ... */ | ||
1955 | skb = orig_skb; | ||
1956 | } | ||
1957 | } | ||
1958 | |||
1917 | /* | 1959 | /* |
1918 | * If the skb is shared we need to obtain our own copy. | 1960 | * If the skb is shared we need to obtain our own copy. |
1919 | */ | 1961 | */ |
1920 | if (skb_shared(skb)) { | 1962 | if (skb_shared(skb)) { |
1921 | tmp_skb = skb; | 1963 | struct sk_buff *tmp_skb = skb; |
1964 | |||
1965 | /* can't happen -- skb is a clone if info_id != 0 */ | ||
1966 | WARN_ON(info_id); | ||
1967 | |||
1922 | skb = skb_clone(skb, GFP_ATOMIC); | 1968 | skb = skb_clone(skb, GFP_ATOMIC); |
1923 | kfree_skb(tmp_skb); | 1969 | kfree_skb(tmp_skb); |
1924 | 1970 | ||
@@ -2019,6 +2065,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2019 | memset(info, 0, sizeof(*info)); | 2065 | memset(info, 0, sizeof(*info)); |
2020 | 2066 | ||
2021 | dev->trans_start = jiffies; | 2067 | dev->trans_start = jiffies; |
2068 | |||
2069 | info->flags = info_flags; | ||
2070 | info->ack_frame_id = info_id; | ||
2071 | |||
2022 | ieee80211_xmit(sdata, skb); | 2072 | ieee80211_xmit(sdata, skb); |
2023 | 2073 | ||
2024 | return NETDEV_TX_OK; | 2074 | return NETDEV_TX_OK; |
@@ -2279,22 +2329,31 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2279 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | 2329 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
2280 | struct ieee80211_mgmt *mgmt; | 2330 | struct ieee80211_mgmt *mgmt; |
2281 | u8 *pos; | 2331 | u8 *pos; |
2332 | int hdr_len = offsetof(struct ieee80211_mgmt, u.beacon) + | ||
2333 | sizeof(mgmt->u.beacon); | ||
2282 | 2334 | ||
2283 | #ifdef CONFIG_MAC80211_MESH | 2335 | #ifdef CONFIG_MAC80211_MESH |
2284 | if (!sdata->u.mesh.mesh_id_len) | 2336 | if (!sdata->u.mesh.mesh_id_len) |
2285 | goto out; | 2337 | goto out; |
2286 | #endif | 2338 | #endif |
2287 | 2339 | ||
2288 | /* headroom, head length, tail length and maximum TIM length */ | 2340 | skb = dev_alloc_skb(local->tx_headroom + |
2289 | skb = dev_alloc_skb(local->tx_headroom + 400 + | 2341 | hdr_len + |
2290 | sdata->u.mesh.ie_len); | 2342 | 2 + /* NULL SSID */ |
2343 | 2 + 8 + /* supported rates */ | ||
2344 | 2 + 3 + /* DS params */ | ||
2345 | 2 + (IEEE80211_MAX_SUPP_RATES - 8) + | ||
2346 | 2 + sizeof(struct ieee80211_ht_cap) + | ||
2347 | 2 + sizeof(struct ieee80211_ht_info) + | ||
2348 | 2 + sdata->u.mesh.mesh_id_len + | ||
2349 | 2 + sizeof(struct ieee80211_meshconf_ie) + | ||
2350 | sdata->u.mesh.ie_len); | ||
2291 | if (!skb) | 2351 | if (!skb) |
2292 | goto out; | 2352 | goto out; |
2293 | 2353 | ||
2294 | skb_reserve(skb, local->hw.extra_tx_headroom); | 2354 | skb_reserve(skb, local->hw.extra_tx_headroom); |
2295 | mgmt = (struct ieee80211_mgmt *) | 2355 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); |
2296 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | 2356 | memset(mgmt, 0, hdr_len); |
2297 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | ||
2298 | mgmt->frame_control = | 2357 | mgmt->frame_control = |
2299 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); | 2358 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); |
2300 | memset(mgmt->da, 0xff, ETH_ALEN); | 2359 | memset(mgmt->da, 0xff, ETH_ALEN); |
@@ -2313,6 +2372,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2313 | mesh_add_ds_params_ie(skb, sdata) || | 2372 | mesh_add_ds_params_ie(skb, sdata) || |
2314 | ieee80211_add_ext_srates_ie(&sdata->vif, skb) || | 2373 | ieee80211_add_ext_srates_ie(&sdata->vif, skb) || |
2315 | mesh_add_rsn_ie(skb, sdata) || | 2374 | mesh_add_rsn_ie(skb, sdata) || |
2375 | mesh_add_ht_cap_ie(skb, sdata) || | ||
2376 | mesh_add_ht_info_ie(skb, sdata) || | ||
2316 | mesh_add_meshid_ie(skb, sdata) || | 2377 | mesh_add_meshid_ie(skb, sdata) || |
2317 | mesh_add_meshconf_ie(skb, sdata) || | 2378 | mesh_add_meshconf_ie(skb, sdata) || |
2318 | mesh_add_vendor_ies(skb, sdata)) { | 2379 | mesh_add_vendor_ies(skb, sdata)) { |
@@ -2355,6 +2416,37 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2355 | } | 2416 | } |
2356 | EXPORT_SYMBOL(ieee80211_beacon_get_tim); | 2417 | EXPORT_SYMBOL(ieee80211_beacon_get_tim); |
2357 | 2418 | ||
2419 | struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw, | ||
2420 | struct ieee80211_vif *vif) | ||
2421 | { | ||
2422 | struct ieee80211_if_ap *ap = NULL; | ||
2423 | struct sk_buff *presp = NULL, *skb = NULL; | ||
2424 | struct ieee80211_hdr *hdr; | ||
2425 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
2426 | |||
2427 | if (sdata->vif.type != NL80211_IFTYPE_AP) | ||
2428 | return NULL; | ||
2429 | |||
2430 | rcu_read_lock(); | ||
2431 | |||
2432 | ap = &sdata->u.ap; | ||
2433 | presp = rcu_dereference(ap->probe_resp); | ||
2434 | if (!presp) | ||
2435 | goto out; | ||
2436 | |||
2437 | skb = skb_copy(presp, GFP_ATOMIC); | ||
2438 | if (!skb) | ||
2439 | goto out; | ||
2440 | |||
2441 | hdr = (struct ieee80211_hdr *) skb->data; | ||
2442 | memset(hdr->addr1, 0, sizeof(hdr->addr1)); | ||
2443 | |||
2444 | out: | ||
2445 | rcu_read_unlock(); | ||
2446 | return skb; | ||
2447 | } | ||
2448 | EXPORT_SYMBOL(ieee80211_proberesp_get); | ||
2449 | |||
2358 | struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw, | 2450 | struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw, |
2359 | struct ieee80211_vif *vif) | 2451 | struct ieee80211_vif *vif) |
2360 | { | 2452 | { |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index eca0fad09709..3a00814699f0 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -812,23 +812,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
812 | offset = noffset; | 812 | offset = noffset; |
813 | } | 813 | } |
814 | 814 | ||
815 | if (sband->ht_cap.ht_supported) { | 815 | if (sband->ht_cap.ht_supported) |
816 | u16 cap = sband->ht_cap.cap; | 816 | pos = ieee80211_ie_build_ht_cap(pos, sband, sband->ht_cap.cap); |
817 | __le16 tmp; | ||
818 | |||
819 | *pos++ = WLAN_EID_HT_CAPABILITY; | ||
820 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
821 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | ||
822 | tmp = cpu_to_le16(cap); | ||
823 | memcpy(pos, &tmp, sizeof(u16)); | ||
824 | pos += sizeof(u16); | ||
825 | *pos++ = sband->ht_cap.ampdu_factor | | ||
826 | (sband->ht_cap.ampdu_density << | ||
827 | IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); | ||
828 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); | ||
829 | pos += sizeof(sband->ht_cap.mcs); | ||
830 | pos += 2 + 4 + 1; /* ext info, BF cap, antsel */ | ||
831 | } | ||
832 | 817 | ||
833 | /* | 818 | /* |
834 | * If adding more here, adjust code in main.c | 819 | * If adding more here, adjust code in main.c |
@@ -1026,7 +1011,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1026 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 1011 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
1027 | sdata->vif.type != NL80211_IFTYPE_MONITOR && | 1012 | sdata->vif.type != NL80211_IFTYPE_MONITOR && |
1028 | ieee80211_sdata_running(sdata)) | 1013 | ieee80211_sdata_running(sdata)) |
1029 | res = drv_add_interface(local, &sdata->vif); | 1014 | res = drv_add_interface(local, sdata); |
1030 | } | 1015 | } |
1031 | 1016 | ||
1032 | /* add STAs back */ | 1017 | /* add STAs back */ |
@@ -1077,7 +1062,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1077 | BSS_CHANGED_BEACON_INT | | 1062 | BSS_CHANGED_BEACON_INT | |
1078 | BSS_CHANGED_BSSID | | 1063 | BSS_CHANGED_BSSID | |
1079 | BSS_CHANGED_CQM | | 1064 | BSS_CHANGED_CQM | |
1080 | BSS_CHANGED_QOS; | 1065 | BSS_CHANGED_QOS | |
1066 | BSS_CHANGED_IDLE; | ||
1081 | 1067 | ||
1082 | switch (sdata->vif.type) { | 1068 | switch (sdata->vif.type) { |
1083 | case NL80211_IFTYPE_STATION: | 1069 | case NL80211_IFTYPE_STATION: |
@@ -1090,7 +1076,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1090 | changed |= BSS_CHANGED_IBSS; | 1076 | changed |= BSS_CHANGED_IBSS; |
1091 | /* fall through */ | 1077 | /* fall through */ |
1092 | case NL80211_IFTYPE_AP: | 1078 | case NL80211_IFTYPE_AP: |
1093 | changed |= BSS_CHANGED_SSID; | 1079 | changed |= BSS_CHANGED_SSID | |
1080 | BSS_CHANGED_AP_PROBE_RESP; | ||
1094 | /* fall through */ | 1081 | /* fall through */ |
1095 | case NL80211_IFTYPE_MESH_POINT: | 1082 | case NL80211_IFTYPE_MESH_POINT: |
1096 | changed |= BSS_CHANGED_BEACON | | 1083 | changed |= BSS_CHANGED_BEACON | |
@@ -1112,6 +1099,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1112 | } | 1099 | } |
1113 | } | 1100 | } |
1114 | 1101 | ||
1102 | ieee80211_recalc_ps(local, -1); | ||
1103 | |||
1115 | /* | 1104 | /* |
1116 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation | 1105 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation |
1117 | * sessions can be established after a resume. | 1106 | * sessions can be established after a resume. |
@@ -1367,6 +1356,103 @@ void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif) | |||
1367 | } | 1356 | } |
1368 | EXPORT_SYMBOL(ieee80211_disable_rssi_reports); | 1357 | EXPORT_SYMBOL(ieee80211_disable_rssi_reports); |
1369 | 1358 | ||
1359 | u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband, | ||
1360 | u16 cap) | ||
1361 | { | ||
1362 | __le16 tmp; | ||
1363 | |||
1364 | *pos++ = WLAN_EID_HT_CAPABILITY; | ||
1365 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
1366 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | ||
1367 | |||
1368 | /* capability flags */ | ||
1369 | tmp = cpu_to_le16(cap); | ||
1370 | memcpy(pos, &tmp, sizeof(u16)); | ||
1371 | pos += sizeof(u16); | ||
1372 | |||
1373 | /* AMPDU parameters */ | ||
1374 | *pos++ = sband->ht_cap.ampdu_factor | | ||
1375 | (sband->ht_cap.ampdu_density << | ||
1376 | IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); | ||
1377 | |||
1378 | /* MCS set */ | ||
1379 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); | ||
1380 | pos += sizeof(sband->ht_cap.mcs); | ||
1381 | |||
1382 | /* extended capabilities */ | ||
1383 | pos += sizeof(__le16); | ||
1384 | |||
1385 | /* BF capabilities */ | ||
1386 | pos += sizeof(__le32); | ||
1387 | |||
1388 | /* antenna selection */ | ||
1389 | pos += sizeof(u8); | ||
1390 | |||
1391 | return pos; | ||
1392 | } | ||
1393 | |||
1394 | u8 *ieee80211_ie_build_ht_info(u8 *pos, | ||
1395 | struct ieee80211_sta_ht_cap *ht_cap, | ||
1396 | struct ieee80211_channel *channel, | ||
1397 | enum nl80211_channel_type channel_type) | ||
1398 | { | ||
1399 | struct ieee80211_ht_info *ht_info; | ||
1400 | /* Build HT Information */ | ||
1401 | *pos++ = WLAN_EID_HT_INFORMATION; | ||
1402 | *pos++ = sizeof(struct ieee80211_ht_info); | ||
1403 | ht_info = (struct ieee80211_ht_info *)pos; | ||
1404 | ht_info->control_chan = | ||
1405 | ieee80211_frequency_to_channel(channel->center_freq); | ||
1406 | switch (channel_type) { | ||
1407 | case NL80211_CHAN_HT40MINUS: | ||
1408 | ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
1409 | break; | ||
1410 | case NL80211_CHAN_HT40PLUS: | ||
1411 | ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
1412 | break; | ||
1413 | case NL80211_CHAN_HT20: | ||
1414 | default: | ||
1415 | ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
1416 | break; | ||
1417 | } | ||
1418 | if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) | ||
1419 | ht_info->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; | ||
1420 | ht_info->operation_mode = 0x0000; | ||
1421 | ht_info->stbc_param = 0x0000; | ||
1422 | |||
1423 | /* It seems that Basic MCS set and Supported MCS set | ||
1424 | are identical for the first 10 bytes */ | ||
1425 | memset(&ht_info->basic_set, 0, 16); | ||
1426 | memcpy(&ht_info->basic_set, &ht_cap->mcs, 10); | ||
1427 | |||
1428 | return pos + sizeof(struct ieee80211_ht_info); | ||
1429 | } | ||
1430 | |||
1431 | enum nl80211_channel_type | ||
1432 | ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info) | ||
1433 | { | ||
1434 | enum nl80211_channel_type channel_type; | ||
1435 | |||
1436 | if (!ht_info) | ||
1437 | return NL80211_CHAN_NO_HT; | ||
1438 | |||
1439 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | ||
1440 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: | ||
1441 | channel_type = NL80211_CHAN_HT20; | ||
1442 | break; | ||
1443 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | ||
1444 | channel_type = NL80211_CHAN_HT40PLUS; | ||
1445 | break; | ||
1446 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | ||
1447 | channel_type = NL80211_CHAN_HT40MINUS; | ||
1448 | break; | ||
1449 | default: | ||
1450 | channel_type = NL80211_CHAN_NO_HT; | ||
1451 | } | ||
1452 | |||
1453 | return channel_type; | ||
1454 | } | ||
1455 | |||
1370 | int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb) | 1456 | int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb) |
1371 | { | 1457 | { |
1372 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 1458 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index fd52e695c071..43327115b490 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -83,7 +83,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
83 | break; | 83 | break; |
84 | #ifdef CONFIG_MAC80211_MESH | 84 | #ifdef CONFIG_MAC80211_MESH |
85 | case NL80211_IFTYPE_MESH_POINT: | 85 | case NL80211_IFTYPE_MESH_POINT: |
86 | ra = skb->data; | 86 | qos = true; |
87 | break; | 87 | break; |
88 | #endif | 88 | #endif |
89 | case NL80211_IFTYPE_STATION: | 89 | case NL80211_IFTYPE_STATION: |
@@ -143,11 +143,15 @@ void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, | |||
143 | /* Fill in the QoS header if there is one. */ | 143 | /* Fill in the QoS header if there is one. */ |
144 | if (ieee80211_is_data_qos(hdr->frame_control)) { | 144 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
145 | u8 *p = ieee80211_get_qos_ctl(hdr); | 145 | u8 *p = ieee80211_get_qos_ctl(hdr); |
146 | u8 ack_policy = 0, tid; | 146 | u8 ack_policy, tid; |
147 | 147 | ||
148 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; | 148 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; |
149 | 149 | ||
150 | if (unlikely(sdata->local->wifi_wme_noack_test)) | 150 | /* preserve EOSP bit */ |
151 | ack_policy = *p & IEEE80211_QOS_CTL_EOSP; | ||
152 | |||
153 | if (unlikely(sdata->local->wifi_wme_noack_test) || | ||
154 | is_multicast_ether_addr(hdr->addr1)) | ||
151 | ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK; | 155 | ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK; |
152 | /* qos header is 2 bytes */ | 156 | /* qos header is 2 bytes */ |
153 | *p++ = ack_policy | tid; | 157 | *p++ = ack_policy | tid; |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 6c53b6d1002b..3dd5a89e99a7 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -103,7 +103,6 @@ static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie, | |||
103 | u8 *pos; | 103 | u8 *pos; |
104 | u32 flags = channel->flags; | 104 | u32 flags = channel->flags; |
105 | u16 cap = sband->ht_cap.cap; | 105 | u16 cap = sband->ht_cap.cap; |
106 | __le16 tmp; | ||
107 | 106 | ||
108 | if (!sband->ht_cap.ht_supported) | 107 | if (!sband->ht_cap.ht_supported) |
109 | return; | 108 | return; |
@@ -154,34 +153,8 @@ static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie, | |||
154 | } | 153 | } |
155 | 154 | ||
156 | /* reserve and fill IE */ | 155 | /* reserve and fill IE */ |
157 | |||
158 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); | 156 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); |
159 | *pos++ = WLAN_EID_HT_CAPABILITY; | 157 | ieee80211_ie_build_ht_cap(pos, sband, cap); |
160 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
161 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | ||
162 | |||
163 | /* capability flags */ | ||
164 | tmp = cpu_to_le16(cap); | ||
165 | memcpy(pos, &tmp, sizeof(u16)); | ||
166 | pos += sizeof(u16); | ||
167 | |||
168 | /* AMPDU parameters */ | ||
169 | *pos++ = sband->ht_cap.ampdu_factor | | ||
170 | (sband->ht_cap.ampdu_density << | ||
171 | IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); | ||
172 | |||
173 | /* MCS set */ | ||
174 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); | ||
175 | pos += sizeof(sband->ht_cap.mcs); | ||
176 | |||
177 | /* extended capabilities */ | ||
178 | pos += sizeof(__le16); | ||
179 | |||
180 | /* BF capabilities */ | ||
181 | pos += sizeof(__le32); | ||
182 | |||
183 | /* antenna selection */ | ||
184 | pos += sizeof(u8); | ||
185 | } | 158 | } |
186 | 159 | ||
187 | static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | 160 | static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, |
@@ -969,10 +942,9 @@ static void ieee80211_work_work(struct work_struct *work) | |||
969 | } | 942 | } |
970 | 943 | ||
971 | if (!started && !local->tmp_channel) { | 944 | if (!started && !local->tmp_channel) { |
972 | bool on_oper_chan; | 945 | bool on_oper_chan, on_oper_chan2; |
973 | bool tmp_chan_changed = false; | ||
974 | bool on_oper_chan2; | ||
975 | enum nl80211_channel_type wk_ct; | 946 | enum nl80211_channel_type wk_ct; |
947 | |||
976 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); | 948 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); |
977 | 949 | ||
978 | /* Work with existing channel type if possible. */ | 950 | /* Work with existing channel type if possible. */ |
@@ -981,11 +953,6 @@ static void ieee80211_work_work(struct work_struct *work) | |||
981 | wk_ct = ieee80211_calc_ct(wk->chan_type, | 953 | wk_ct = ieee80211_calc_ct(wk->chan_type, |
982 | local->hw.conf.channel_type); | 954 | local->hw.conf.channel_type); |
983 | 955 | ||
984 | if (local->tmp_channel) | ||
985 | if ((local->tmp_channel != wk->chan) || | ||
986 | (local->tmp_channel_type != wk_ct)) | ||
987 | tmp_chan_changed = true; | ||
988 | |||
989 | local->tmp_channel = wk->chan; | 956 | local->tmp_channel = wk->chan; |
990 | local->tmp_channel_type = wk_ct; | 957 | local->tmp_channel_type = wk_ct; |
991 | /* | 958 | /* |
@@ -1008,12 +975,7 @@ static void ieee80211_work_work(struct work_struct *work) | |||
1008 | true, | 975 | true, |
1009 | false); | 976 | false); |
1010 | } | 977 | } |
1011 | } else if (tmp_chan_changed) | 978 | } |
1012 | /* Still off-channel, but on some other | ||
1013 | * channel, so update hardware. | ||
1014 | * PS should already be off-channel. | ||
1015 | */ | ||
1016 | ieee80211_hw_config(local, 0); | ||
1017 | 979 | ||
1018 | started = true; | 980 | started = true; |
1019 | wk->timeout = jiffies; | 981 | wk->timeout = jiffies; |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index f614ce7bb6e3..106e15a4649f 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -390,7 +390,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
390 | u8 scratch[6 * AES_BLOCK_SIZE]; | 390 | u8 scratch[6 * AES_BLOCK_SIZE]; |
391 | 391 | ||
392 | if (info->control.hw_key && | 392 | if (info->control.hw_key && |
393 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | 393 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) && |
394 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { | ||
394 | /* | 395 | /* |
395 | * hwaccel has no need for preallocated room for CCMP | 396 | * hwaccel has no need for preallocated room for CCMP |
396 | * header or MIC fields | 397 | * header or MIC fields |
@@ -412,6 +413,12 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
412 | 413 | ||
413 | pos = skb_push(skb, CCMP_HDR_LEN); | 414 | pos = skb_push(skb, CCMP_HDR_LEN); |
414 | memmove(pos, pos + CCMP_HDR_LEN, hdrlen); | 415 | memmove(pos, pos + CCMP_HDR_LEN, hdrlen); |
416 | |||
417 | /* the HW only needs room for the IV, but not the actual IV */ | ||
418 | if (info->control.hw_key && | ||
419 | (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) | ||
420 | return 0; | ||
421 | |||
415 | hdr = (struct ieee80211_hdr *) pos; | 422 | hdr = (struct ieee80211_hdr *) pos; |
416 | pos += hdrlen; | 423 | pos += hdrlen; |
417 | 424 | ||
diff --git a/net/netfilter/core.c b/net/netfilter/core.c index afca6c78948c..4aa0f4b19bd8 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c | |||
@@ -54,6 +54,12 @@ EXPORT_SYMBOL_GPL(nf_unregister_afinfo); | |||
54 | 54 | ||
55 | struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly; | 55 | struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly; |
56 | EXPORT_SYMBOL(nf_hooks); | 56 | EXPORT_SYMBOL(nf_hooks); |
57 | |||
58 | #if defined(CONFIG_JUMP_LABEL) | ||
59 | struct jump_label_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; | ||
60 | EXPORT_SYMBOL(nf_hooks_needed); | ||
61 | #endif | ||
62 | |||
57 | static DEFINE_MUTEX(nf_hook_mutex); | 63 | static DEFINE_MUTEX(nf_hook_mutex); |
58 | 64 | ||
59 | int nf_register_hook(struct nf_hook_ops *reg) | 65 | int nf_register_hook(struct nf_hook_ops *reg) |
@@ -70,6 +76,9 @@ int nf_register_hook(struct nf_hook_ops *reg) | |||
70 | } | 76 | } |
71 | list_add_rcu(®->list, elem->list.prev); | 77 | list_add_rcu(®->list, elem->list.prev); |
72 | mutex_unlock(&nf_hook_mutex); | 78 | mutex_unlock(&nf_hook_mutex); |
79 | #if defined(CONFIG_JUMP_LABEL) | ||
80 | jump_label_inc(&nf_hooks_needed[reg->pf][reg->hooknum]); | ||
81 | #endif | ||
73 | return 0; | 82 | return 0; |
74 | } | 83 | } |
75 | EXPORT_SYMBOL(nf_register_hook); | 84 | EXPORT_SYMBOL(nf_register_hook); |
@@ -79,7 +88,9 @@ void nf_unregister_hook(struct nf_hook_ops *reg) | |||
79 | mutex_lock(&nf_hook_mutex); | 88 | mutex_lock(&nf_hook_mutex); |
80 | list_del_rcu(®->list); | 89 | list_del_rcu(®->list); |
81 | mutex_unlock(&nf_hook_mutex); | 90 | mutex_unlock(&nf_hook_mutex); |
82 | 91 | #if defined(CONFIG_JUMP_LABEL) | |
92 | jump_label_dec(&nf_hooks_needed[reg->pf][reg->hooknum]); | ||
93 | #endif | ||
83 | synchronize_net(); | 94 | synchronize_net(); |
84 | } | 95 | } |
85 | EXPORT_SYMBOL(nf_unregister_hook); | 96 | EXPORT_SYMBOL(nf_unregister_hook); |
diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c index f2d576e6b769..4015fcaf87bc 100644 --- a/net/netfilter/ipset/ip_set_hash_ip.c +++ b/net/netfilter/ipset/ip_set_hash_ip.c | |||
@@ -241,7 +241,7 @@ hash_ip6_data_isnull(const struct hash_ip6_elem *elem) | |||
241 | static inline void | 241 | static inline void |
242 | hash_ip6_data_copy(struct hash_ip6_elem *dst, const struct hash_ip6_elem *src) | 242 | hash_ip6_data_copy(struct hash_ip6_elem *dst, const struct hash_ip6_elem *src) |
243 | { | 243 | { |
244 | ipv6_addr_copy(&dst->ip.in6, &src->ip.in6); | 244 | dst->ip.in6 = src->ip.in6; |
245 | } | 245 | } |
246 | 246 | ||
247 | static inline void | 247 | static inline void |
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c index 60d016541c58..28988196775e 100644 --- a/net/netfilter/ipset/ip_set_hash_net.c +++ b/net/netfilter/ipset/ip_set_hash_net.c | |||
@@ -267,7 +267,7 @@ static inline void | |||
267 | hash_net6_data_copy(struct hash_net6_elem *dst, | 267 | hash_net6_data_copy(struct hash_net6_elem *dst, |
268 | const struct hash_net6_elem *src) | 268 | const struct hash_net6_elem *src) |
269 | { | 269 | { |
270 | ipv6_addr_copy(&dst->ip.in6, &src->ip.in6); | 270 | dst->ip.in6 = src->ip.in6; |
271 | dst->cidr = src->cidr; | 271 | dst->cidr = src->cidr; |
272 | } | 272 | } |
273 | 273 | ||
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 093cc327020f..611c3359b94d 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
@@ -983,7 +983,7 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related, | |||
983 | if (!cp) | 983 | if (!cp) |
984 | return NF_ACCEPT; | 984 | return NF_ACCEPT; |
985 | 985 | ||
986 | ipv6_addr_copy(&snet.in6, &iph->saddr); | 986 | snet.in6 = iph->saddr; |
987 | return handle_response_icmp(AF_INET6, skb, &snet, cih->nexthdr, cp, | 987 | return handle_response_icmp(AF_INET6, skb, &snet, cih->nexthdr, cp, |
988 | pp, offset, sizeof(struct ipv6hdr)); | 988 | pp, offset, sizeof(struct ipv6hdr)); |
989 | } | 989 | } |
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index 3cdd479f9b5d..bcf5563e4837 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c | |||
@@ -603,9 +603,9 @@ sloop: | |||
603 | #ifdef CONFIG_IP_VS_IPV6 | 603 | #ifdef CONFIG_IP_VS_IPV6 |
604 | if (cp->af == AF_INET6) { | 604 | if (cp->af == AF_INET6) { |
605 | p += sizeof(struct ip_vs_sync_v6); | 605 | p += sizeof(struct ip_vs_sync_v6); |
606 | ipv6_addr_copy(&s->v6.caddr, &cp->caddr.in6); | 606 | s->v6.caddr = cp->caddr.in6; |
607 | ipv6_addr_copy(&s->v6.vaddr, &cp->vaddr.in6); | 607 | s->v6.vaddr = cp->vaddr.in6; |
608 | ipv6_addr_copy(&s->v6.daddr, &cp->daddr.in6); | 608 | s->v6.daddr = cp->daddr.in6; |
609 | } else | 609 | } else |
610 | #endif | 610 | #endif |
611 | { | 611 | { |
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index aa2d7206ee8a..38a576d05b4b 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c | |||
@@ -235,7 +235,7 @@ __ip_vs_route_output_v6(struct net *net, struct in6_addr *daddr, | |||
235 | goto out_err; | 235 | goto out_err; |
236 | } | 236 | } |
237 | } | 237 | } |
238 | ipv6_addr_copy(ret_saddr, &fl6.saddr); | 238 | *ret_saddr = fl6.saddr; |
239 | return dst; | 239 | return dst; |
240 | 240 | ||
241 | out_err: | 241 | out_err: |
@@ -279,7 +279,7 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest, | |||
279 | atomic_read(&rt->dst.__refcnt)); | 279 | atomic_read(&rt->dst.__refcnt)); |
280 | } | 280 | } |
281 | if (ret_saddr) | 281 | if (ret_saddr) |
282 | ipv6_addr_copy(ret_saddr, &dest->dst_saddr.in6); | 282 | *ret_saddr = dest->dst_saddr.in6; |
283 | spin_unlock(&dest->dst_lock); | 283 | spin_unlock(&dest->dst_lock); |
284 | } else { | 284 | } else { |
285 | dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm); | 285 | dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm); |
@@ -705,7 +705,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
705 | /* mangle the packet */ | 705 | /* mangle the packet */ |
706 | if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp)) | 706 | if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp)) |
707 | goto tx_error; | 707 | goto tx_error; |
708 | ipv6_addr_copy(&ipv6_hdr(skb)->daddr, &cp->daddr.in6); | 708 | ipv6_hdr(skb)->daddr = cp->daddr.in6; |
709 | 709 | ||
710 | if (!local || !skb->dev) { | 710 | if (!local || !skb->dev) { |
711 | /* drop the old route when skb is not shared */ | 711 | /* drop the old route when skb is not shared */ |
@@ -967,8 +967,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
967 | be16_add_cpu(&iph->payload_len, sizeof(*old_iph)); | 967 | be16_add_cpu(&iph->payload_len, sizeof(*old_iph)); |
968 | iph->priority = old_iph->priority; | 968 | iph->priority = old_iph->priority; |
969 | memset(&iph->flow_lbl, 0, sizeof(iph->flow_lbl)); | 969 | memset(&iph->flow_lbl, 0, sizeof(iph->flow_lbl)); |
970 | ipv6_addr_copy(&iph->daddr, &cp->daddr.in6); | 970 | iph->daddr = cp->daddr.in6; |
971 | ipv6_addr_copy(&iph->saddr, &saddr); | 971 | iph->saddr = saddr; |
972 | iph->hop_limit = old_iph->hop_limit; | 972 | iph->hop_limit = old_iph->hop_limit; |
973 | 973 | ||
974 | /* Another hack: avoid icmp_send in ip_fragment */ | 974 | /* Another hack: avoid icmp_send in ip_fragment */ |
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index f03c2d4539f6..f9368f33e7af 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c | |||
@@ -750,10 +750,10 @@ static int callforward_do_filter(const union nf_inet_addr *src, | |||
750 | struct rt6_info *rt1, *rt2; | 750 | struct rt6_info *rt1, *rt2; |
751 | 751 | ||
752 | memset(&fl1, 0, sizeof(fl1)); | 752 | memset(&fl1, 0, sizeof(fl1)); |
753 | ipv6_addr_copy(&fl1.daddr, &src->in6); | 753 | fl1.daddr = src->in6; |
754 | 754 | ||
755 | memset(&fl2, 0, sizeof(fl2)); | 755 | memset(&fl2, 0, sizeof(fl2)); |
756 | ipv6_addr_copy(&fl2.daddr, &dst->in6); | 756 | fl2.daddr = dst->in6; |
757 | if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, | 757 | if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, |
758 | flowi6_to_flowi(&fl1), false)) { | 758 | flowi6_to_flowi(&fl1), false)) { |
759 | if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, | 759 | if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, |
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index 9e63b43faeed..3ecade3966d5 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c | |||
@@ -161,7 +161,7 @@ static u_int32_t tcpmss_reverse_mtu(const struct sk_buff *skb, | |||
161 | struct flowi6 *fl6 = &fl.u.ip6; | 161 | struct flowi6 *fl6 = &fl.u.ip6; |
162 | 162 | ||
163 | memset(fl6, 0, sizeof(*fl6)); | 163 | memset(fl6, 0, sizeof(*fl6)); |
164 | ipv6_addr_copy(&fl6->daddr, &ipv6_hdr(skb)->saddr); | 164 | fl6->daddr = ipv6_hdr(skb)->saddr; |
165 | } | 165 | } |
166 | rcu_read_lock(); | 166 | rcu_read_lock(); |
167 | ai = nf_get_afinfo(family); | 167 | ai = nf_get_afinfo(family); |
diff --git a/net/netfilter/xt_addrtype.c b/net/netfilter/xt_addrtype.c index b77d383cec78..c047de2046ad 100644 --- a/net/netfilter/xt_addrtype.c +++ b/net/netfilter/xt_addrtype.c | |||
@@ -42,7 +42,7 @@ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, | |||
42 | int route_err; | 42 | int route_err; |
43 | 43 | ||
44 | memset(&flow, 0, sizeof(flow)); | 44 | memset(&flow, 0, sizeof(flow)); |
45 | ipv6_addr_copy(&flow.daddr, addr); | 45 | flow.daddr = *addr; |
46 | if (dev) | 46 | if (dev) |
47 | flow.flowi6_oif = dev->ifindex; | 47 | flow.flowi6_oif = dev->ifindex; |
48 | 48 | ||
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 7b372a763c60..3735297c524d 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
@@ -155,12 +155,12 @@ int netlbl_cfg_unlbl_map_add(const char *domain, | |||
155 | if (map6 == NULL) | 155 | if (map6 == NULL) |
156 | goto cfg_unlbl_map_add_failure; | 156 | goto cfg_unlbl_map_add_failure; |
157 | map6->type = NETLBL_NLTYPE_UNLABELED; | 157 | map6->type = NETLBL_NLTYPE_UNLABELED; |
158 | ipv6_addr_copy(&map6->list.addr, addr6); | 158 | map6->list.addr = *addr6; |
159 | map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0]; | 159 | map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0]; |
160 | map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1]; | 160 | map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1]; |
161 | map6->list.addr.s6_addr32[2] &= mask6->s6_addr32[2]; | 161 | map6->list.addr.s6_addr32[2] &= mask6->s6_addr32[2]; |
162 | map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3]; | 162 | map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3]; |
163 | ipv6_addr_copy(&map6->list.mask, mask6); | 163 | map6->list.mask = *mask6; |
164 | map6->list.valid = 1; | 164 | map6->list.valid = 1; |
165 | ret_val = netlbl_af6list_add(&map6->list, | 165 | ret_val = netlbl_af6list_add(&map6->list, |
166 | &addrmap->list6); | 166 | &addrmap->list6); |
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index bfa555869775..9879300beefd 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c | |||
@@ -216,12 +216,12 @@ static int netlbl_mgmt_add_common(struct genl_info *info, | |||
216 | ret_val = -ENOMEM; | 216 | ret_val = -ENOMEM; |
217 | goto add_failure; | 217 | goto add_failure; |
218 | } | 218 | } |
219 | ipv6_addr_copy(&map->list.addr, addr); | 219 | map->list.addr = *addr; |
220 | map->list.addr.s6_addr32[0] &= mask->s6_addr32[0]; | 220 | map->list.addr.s6_addr32[0] &= mask->s6_addr32[0]; |
221 | map->list.addr.s6_addr32[1] &= mask->s6_addr32[1]; | 221 | map->list.addr.s6_addr32[1] &= mask->s6_addr32[1]; |
222 | map->list.addr.s6_addr32[2] &= mask->s6_addr32[2]; | 222 | map->list.addr.s6_addr32[2] &= mask->s6_addr32[2]; |
223 | map->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; | 223 | map->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; |
224 | ipv6_addr_copy(&map->list.mask, mask); | 224 | map->list.mask = *mask; |
225 | map->list.valid = 1; | 225 | map->list.valid = 1; |
226 | map->type = entry->type; | 226 | map->type = entry->type; |
227 | 227 | ||
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index e251c2c88521..049ccd2447d7 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -300,12 +300,12 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, | |||
300 | if (entry == NULL) | 300 | if (entry == NULL) |
301 | return -ENOMEM; | 301 | return -ENOMEM; |
302 | 302 | ||
303 | ipv6_addr_copy(&entry->list.addr, addr); | 303 | entry->list.addr = *addr; |
304 | entry->list.addr.s6_addr32[0] &= mask->s6_addr32[0]; | 304 | entry->list.addr.s6_addr32[0] &= mask->s6_addr32[0]; |
305 | entry->list.addr.s6_addr32[1] &= mask->s6_addr32[1]; | 305 | entry->list.addr.s6_addr32[1] &= mask->s6_addr32[1]; |
306 | entry->list.addr.s6_addr32[2] &= mask->s6_addr32[2]; | 306 | entry->list.addr.s6_addr32[2] &= mask->s6_addr32[2]; |
307 | entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; | 307 | entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; |
308 | ipv6_addr_copy(&entry->list.mask, mask); | 308 | entry->list.mask = *mask; |
309 | entry->list.valid = 1; | 309 | entry->list.valid = 1; |
310 | entry->secid = secid; | 310 | entry->secid = secid; |
311 | 311 | ||
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 3925c6578767..fe5ca89abfce 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c | |||
@@ -126,7 +126,10 @@ static inline int nci_request(struct nci_dev *ndev, | |||
126 | 126 | ||
127 | static void nci_reset_req(struct nci_dev *ndev, unsigned long opt) | 127 | static void nci_reset_req(struct nci_dev *ndev, unsigned long opt) |
128 | { | 128 | { |
129 | nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 0, NULL); | 129 | struct nci_core_reset_cmd cmd; |
130 | |||
131 | cmd.reset_type = NCI_RESET_TYPE_RESET_CONFIG; | ||
132 | nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 1, &cmd); | ||
130 | } | 133 | } |
131 | 134 | ||
132 | static void nci_init_req(struct nci_dev *ndev, unsigned long opt) | 135 | static void nci_init_req(struct nci_dev *ndev, unsigned long opt) |
@@ -136,17 +139,11 @@ static void nci_init_req(struct nci_dev *ndev, unsigned long opt) | |||
136 | 139 | ||
137 | static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt) | 140 | static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt) |
138 | { | 141 | { |
139 | struct nci_core_conn_create_cmd conn_cmd; | ||
140 | struct nci_rf_disc_map_cmd cmd; | 142 | struct nci_rf_disc_map_cmd cmd; |
141 | struct disc_map_config *cfg = cmd.mapping_configs; | 143 | struct disc_map_config *cfg = cmd.mapping_configs; |
142 | __u8 *num = &cmd.num_mapping_configs; | 144 | __u8 *num = &cmd.num_mapping_configs; |
143 | int i; | 145 | int i; |
144 | 146 | ||
145 | /* create static rf connection */ | ||
146 | conn_cmd.target_handle = 0; | ||
147 | conn_cmd.num_target_specific_params = 0; | ||
148 | nci_send_cmd(ndev, NCI_OP_CORE_CONN_CREATE_CMD, 2, &conn_cmd); | ||
149 | |||
150 | /* set rf mapping configurations */ | 147 | /* set rf mapping configurations */ |
151 | *num = 0; | 148 | *num = 0; |
152 | 149 | ||
@@ -470,7 +467,7 @@ static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx, | |||
470 | ndev->data_exchange_cb = cb; | 467 | ndev->data_exchange_cb = cb; |
471 | ndev->data_exchange_cb_context = cb_context; | 468 | ndev->data_exchange_cb_context = cb_context; |
472 | 469 | ||
473 | rc = nci_send_data(ndev, ndev->conn_id, skb); | 470 | rc = nci_send_data(ndev, NCI_STATIC_RF_CONN_ID, skb); |
474 | if (rc) | 471 | if (rc) |
475 | clear_bit(NCI_DATA_EXCHANGE, &ndev->flags); | 472 | clear_bit(NCI_DATA_EXCHANGE, &ndev->flags); |
476 | 473 | ||
@@ -726,7 +723,10 @@ static void nci_tx_work(struct work_struct *work) | |||
726 | if (!skb) | 723 | if (!skb) |
727 | return; | 724 | return; |
728 | 725 | ||
729 | atomic_dec(&ndev->credits_cnt); | 726 | /* Check if data flow control is used */ |
727 | if (atomic_read(&ndev->credits_cnt) != | ||
728 | NCI_DATA_FLOW_CONTROL_NOT_USED) | ||
729 | atomic_dec(&ndev->credits_cnt); | ||
730 | 730 | ||
731 | nfc_dbg("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d", | 731 | nfc_dbg("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d", |
732 | nci_pbf(skb->data), | 732 | nci_pbf(skb->data), |
diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c index e5ed90fc1a9c..511fb96e21bc 100644 --- a/net/nfc/nci/data.c +++ b/net/nfc/nci/data.c | |||
@@ -95,7 +95,8 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev, | |||
95 | __skb_queue_head_init(&frags_q); | 95 | __skb_queue_head_init(&frags_q); |
96 | 96 | ||
97 | while (total_len) { | 97 | while (total_len) { |
98 | frag_len = min_t(int, total_len, ndev->max_pkt_payload_size); | 98 | frag_len = |
99 | min_t(int, total_len, ndev->max_data_pkt_payload_size); | ||
99 | 100 | ||
100 | skb_frag = nci_skb_alloc(ndev, | 101 | skb_frag = nci_skb_alloc(ndev, |
101 | (NCI_DATA_HDR_SIZE + frag_len), | 102 | (NCI_DATA_HDR_SIZE + frag_len), |
@@ -151,7 +152,7 @@ int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb) | |||
151 | nfc_dbg("entry, conn_id 0x%x, plen %d", conn_id, skb->len); | 152 | nfc_dbg("entry, conn_id 0x%x, plen %d", conn_id, skb->len); |
152 | 153 | ||
153 | /* check if the packet need to be fragmented */ | 154 | /* check if the packet need to be fragmented */ |
154 | if (skb->len <= ndev->max_pkt_payload_size) { | 155 | if (skb->len <= ndev->max_data_pkt_payload_size) { |
155 | /* no need to fragment packet */ | 156 | /* no need to fragment packet */ |
156 | nci_push_data_hdr(ndev, conn_id, skb, NCI_PBF_LAST); | 157 | nci_push_data_hdr(ndev, conn_id, skb, NCI_PBF_LAST); |
157 | 158 | ||
diff --git a/net/nfc/nci/lib.c b/net/nfc/nci/lib.c index b19dc2fa90e1..e99adcfb1bcf 100644 --- a/net/nfc/nci/lib.c +++ b/net/nfc/nci/lib.c | |||
@@ -42,12 +42,9 @@ int nci_to_errno(__u8 code) | |||
42 | case NCI_STATUS_REJECTED: | 42 | case NCI_STATUS_REJECTED: |
43 | return -EBUSY; | 43 | return -EBUSY; |
44 | 44 | ||
45 | case NCI_STATUS_MESSAGE_CORRUPTED: | 45 | case NCI_STATUS_RF_FRAME_CORRUPTED: |
46 | return -EBADMSG; | 46 | return -EBADMSG; |
47 | 47 | ||
48 | case NCI_STATUS_BUFFER_FULL: | ||
49 | return -ENOBUFS; | ||
50 | |||
51 | case NCI_STATUS_NOT_INITIALIZED: | 48 | case NCI_STATUS_NOT_INITIALIZED: |
52 | return -EHOSTDOWN; | 49 | return -EHOSTDOWN; |
53 | 50 | ||
@@ -80,9 +77,6 @@ int nci_to_errno(__u8 code) | |||
80 | case NCI_STATUS_NFCEE_TIMEOUT_ERROR: | 77 | case NCI_STATUS_NFCEE_TIMEOUT_ERROR: |
81 | return -ETIMEDOUT; | 78 | return -ETIMEDOUT; |
82 | 79 | ||
83 | case NCI_STATUS_RF_LINK_LOSS_ERROR: | ||
84 | return -ENOLINK; | ||
85 | |||
86 | case NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED: | 80 | case NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED: |
87 | return -EDQUOT; | 81 | return -EDQUOT; |
88 | 82 | ||
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index 96633f5cda4f..c1bf54172c25 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c | |||
@@ -54,7 +54,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, | |||
54 | ntf->conn_entries[i].conn_id, | 54 | ntf->conn_entries[i].conn_id, |
55 | ntf->conn_entries[i].credits); | 55 | ntf->conn_entries[i].credits); |
56 | 56 | ||
57 | if (ntf->conn_entries[i].conn_id == ndev->conn_id) { | 57 | if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) { |
58 | /* found static rf connection */ | 58 | /* found static rf connection */ |
59 | atomic_add(ntf->conn_entries[i].credits, | 59 | atomic_add(ntf->conn_entries[i].credits, |
60 | &ndev->credits_cnt); | 60 | &ndev->credits_cnt); |
@@ -66,22 +66,12 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, | |||
66 | queue_work(ndev->tx_wq, &ndev->tx_work); | 66 | queue_work(ndev->tx_wq, &ndev->tx_work); |
67 | } | 67 | } |
68 | 68 | ||
69 | static void nci_rf_field_info_ntf_packet(struct nci_dev *ndev, | 69 | static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, |
70 | struct sk_buff *skb) | 70 | struct nci_rf_intf_activated_ntf *ntf, __u8 *data) |
71 | { | ||
72 | struct nci_rf_field_info_ntf *ntf = (void *) skb->data; | ||
73 | |||
74 | nfc_dbg("entry, rf_field_status %d", ntf->rf_field_status); | ||
75 | } | ||
76 | |||
77 | static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev, | ||
78 | struct nci_rf_activate_ntf *ntf, __u8 *data) | ||
79 | { | 71 | { |
80 | struct rf_tech_specific_params_nfca_poll *nfca_poll; | 72 | struct rf_tech_specific_params_nfca_poll *nfca_poll; |
81 | struct activation_params_nfca_poll_iso_dep *nfca_poll_iso_dep; | ||
82 | 73 | ||
83 | nfca_poll = &ntf->rf_tech_specific_params.nfca_poll; | 74 | nfca_poll = &ntf->rf_tech_specific_params.nfca_poll; |
84 | nfca_poll_iso_dep = &ntf->activation_params.nfca_poll_iso_dep; | ||
85 | 75 | ||
86 | nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); | 76 | nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); |
87 | data += 2; | 77 | data += 2; |
@@ -100,32 +90,32 @@ static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev, | |||
100 | if (nfca_poll->sel_res_len != 0) | 90 | if (nfca_poll->sel_res_len != 0) |
101 | nfca_poll->sel_res = *data++; | 91 | nfca_poll->sel_res = *data++; |
102 | 92 | ||
103 | ntf->rf_interface_type = *data++; | 93 | nfc_dbg("sel_res_len %d, sel_res 0x%x", |
104 | ntf->activation_params_len = *data++; | ||
105 | |||
106 | nfc_dbg("sel_res_len %d, sel_res 0x%x, rf_interface_type %d, activation_params_len %d", | ||
107 | nfca_poll->sel_res_len, | 94 | nfca_poll->sel_res_len, |
108 | nfca_poll->sel_res, | 95 | nfca_poll->sel_res); |
109 | ntf->rf_interface_type, | 96 | |
110 | ntf->activation_params_len); | 97 | return data; |
111 | 98 | } | |
112 | switch (ntf->rf_interface_type) { | 99 | |
113 | case NCI_RF_INTERFACE_ISO_DEP: | 100 | static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, |
114 | nfca_poll_iso_dep->rats_res_len = *data++; | 101 | struct nci_rf_intf_activated_ntf *ntf, __u8 *data) |
115 | if (nfca_poll_iso_dep->rats_res_len > 0) { | 102 | { |
116 | memcpy(nfca_poll_iso_dep->rats_res, | 103 | struct activation_params_nfca_poll_iso_dep *nfca_poll; |
104 | |||
105 | switch (ntf->activation_rf_tech_and_mode) { | ||
106 | case NCI_NFC_A_PASSIVE_POLL_MODE: | ||
107 | nfca_poll = &ntf->activation_params.nfca_poll_iso_dep; | ||
108 | nfca_poll->rats_res_len = *data++; | ||
109 | if (nfca_poll->rats_res_len > 0) { | ||
110 | memcpy(nfca_poll->rats_res, | ||
117 | data, | 111 | data, |
118 | nfca_poll_iso_dep->rats_res_len); | 112 | nfca_poll->rats_res_len); |
119 | } | 113 | } |
120 | break; | 114 | break; |
121 | 115 | ||
122 | case NCI_RF_INTERFACE_FRAME: | ||
123 | /* no activation params */ | ||
124 | break; | ||
125 | |||
126 | default: | 116 | default: |
127 | nfc_err("unsupported rf_interface_type 0x%x", | 117 | nfc_err("unsupported activation_rf_tech_and_mode 0x%x", |
128 | ntf->rf_interface_type); | 118 | ntf->activation_rf_tech_and_mode); |
129 | return -EPROTO; | 119 | return -EPROTO; |
130 | } | 120 | } |
131 | 121 | ||
@@ -133,7 +123,7 @@ static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev, | |||
133 | } | 123 | } |
134 | 124 | ||
135 | static void nci_target_found(struct nci_dev *ndev, | 125 | static void nci_target_found(struct nci_dev *ndev, |
136 | struct nci_rf_activate_ntf *ntf) | 126 | struct nci_rf_intf_activated_ntf *ntf) |
137 | { | 127 | { |
138 | struct nfc_target nfc_tgt; | 128 | struct nfc_target nfc_tgt; |
139 | 129 | ||
@@ -141,6 +131,8 @@ static void nci_target_found(struct nci_dev *ndev, | |||
141 | nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK; | 131 | nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK; |
142 | else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP) /* 4A */ | 132 | else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP) /* 4A */ |
143 | nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK; | 133 | nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK; |
134 | else | ||
135 | nfc_tgt.supported_protocols = 0; | ||
144 | 136 | ||
145 | nfc_tgt.sens_res = ntf->rf_tech_specific_params.nfca_poll.sens_res; | 137 | nfc_tgt.sens_res = ntf->rf_tech_specific_params.nfca_poll.sens_res; |
146 | nfc_tgt.sel_res = ntf->rf_tech_specific_params.nfca_poll.sel_res; | 138 | nfc_tgt.sel_res = ntf->rf_tech_specific_params.nfca_poll.sel_res; |
@@ -158,49 +150,86 @@ static void nci_target_found(struct nci_dev *ndev, | |||
158 | nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1); | 150 | nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1); |
159 | } | 151 | } |
160 | 152 | ||
161 | static void nci_rf_activate_ntf_packet(struct nci_dev *ndev, | 153 | static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, |
162 | struct sk_buff *skb) | 154 | struct sk_buff *skb) |
163 | { | 155 | { |
164 | struct nci_rf_activate_ntf ntf; | 156 | struct nci_rf_intf_activated_ntf ntf; |
165 | __u8 *data = skb->data; | 157 | __u8 *data = skb->data; |
166 | int rc = -1; | 158 | int err = 0; |
167 | 159 | ||
168 | clear_bit(NCI_DISCOVERY, &ndev->flags); | 160 | clear_bit(NCI_DISCOVERY, &ndev->flags); |
169 | set_bit(NCI_POLL_ACTIVE, &ndev->flags); | 161 | set_bit(NCI_POLL_ACTIVE, &ndev->flags); |
170 | 162 | ||
171 | ntf.target_handle = *data++; | 163 | ntf.rf_discovery_id = *data++; |
164 | ntf.rf_interface_type = *data++; | ||
172 | ntf.rf_protocol = *data++; | 165 | ntf.rf_protocol = *data++; |
173 | ntf.rf_tech_and_mode = *data++; | 166 | ntf.activation_rf_tech_and_mode = *data++; |
174 | ntf.rf_tech_specific_params_len = *data++; | 167 | ntf.rf_tech_specific_params_len = *data++; |
175 | 168 | ||
176 | nfc_dbg("target_handle %d, rf_protocol 0x%x, rf_tech_and_mode 0x%x, rf_tech_specific_params_len %d", | 169 | nfc_dbg("rf_discovery_id %d", ntf.rf_discovery_id); |
177 | ntf.target_handle, | 170 | nfc_dbg("rf_interface_type 0x%x", ntf.rf_interface_type); |
178 | ntf.rf_protocol, | 171 | nfc_dbg("rf_protocol 0x%x", ntf.rf_protocol); |
179 | ntf.rf_tech_and_mode, | 172 | nfc_dbg("activation_rf_tech_and_mode 0x%x", |
173 | ntf.activation_rf_tech_and_mode); | ||
174 | nfc_dbg("rf_tech_specific_params_len %d", | ||
180 | ntf.rf_tech_specific_params_len); | 175 | ntf.rf_tech_specific_params_len); |
181 | 176 | ||
182 | switch (ntf.rf_tech_and_mode) { | 177 | if (ntf.rf_tech_specific_params_len > 0) { |
183 | case NCI_NFC_A_PASSIVE_POLL_MODE: | 178 | switch (ntf.activation_rf_tech_and_mode) { |
184 | rc = nci_rf_activate_nfca_passive_poll(ndev, &ntf, | 179 | case NCI_NFC_A_PASSIVE_POLL_MODE: |
185 | data); | 180 | data = nci_extract_rf_params_nfca_passive_poll(ndev, |
186 | break; | 181 | &ntf, data); |
182 | break; | ||
183 | |||
184 | default: | ||
185 | nfc_err("unsupported activation_rf_tech_and_mode 0x%x", | ||
186 | ntf.activation_rf_tech_and_mode); | ||
187 | return; | ||
188 | } | ||
189 | } | ||
187 | 190 | ||
188 | default: | 191 | ntf.data_exch_rf_tech_and_mode = *data++; |
189 | nfc_err("unsupported rf_tech_and_mode 0x%x", | 192 | ntf.data_exch_tx_bit_rate = *data++; |
190 | ntf.rf_tech_and_mode); | 193 | ntf.data_exch_rx_bit_rate = *data++; |
191 | return; | 194 | ntf.activation_params_len = *data++; |
195 | |||
196 | nfc_dbg("data_exch_rf_tech_and_mode 0x%x", | ||
197 | ntf.data_exch_rf_tech_and_mode); | ||
198 | nfc_dbg("data_exch_tx_bit_rate 0x%x", | ||
199 | ntf.data_exch_tx_bit_rate); | ||
200 | nfc_dbg("data_exch_rx_bit_rate 0x%x", | ||
201 | ntf.data_exch_rx_bit_rate); | ||
202 | nfc_dbg("activation_params_len %d", | ||
203 | ntf.activation_params_len); | ||
204 | |||
205 | if (ntf.activation_params_len > 0) { | ||
206 | switch (ntf.rf_interface_type) { | ||
207 | case NCI_RF_INTERFACE_ISO_DEP: | ||
208 | err = nci_extract_activation_params_iso_dep(ndev, | ||
209 | &ntf, data); | ||
210 | break; | ||
211 | |||
212 | case NCI_RF_INTERFACE_FRAME: | ||
213 | /* no activation params */ | ||
214 | break; | ||
215 | |||
216 | default: | ||
217 | nfc_err("unsupported rf_interface_type 0x%x", | ||
218 | ntf.rf_interface_type); | ||
219 | return; | ||
220 | } | ||
192 | } | 221 | } |
193 | 222 | ||
194 | if (!rc) | 223 | if (!err) |
195 | nci_target_found(ndev, &ntf); | 224 | nci_target_found(ndev, &ntf); |
196 | } | 225 | } |
197 | 226 | ||
198 | static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, | 227 | static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, |
199 | struct sk_buff *skb) | 228 | struct sk_buff *skb) |
200 | { | 229 | { |
201 | __u8 type = skb->data[0]; | 230 | struct nci_rf_deactivate_ntf *ntf = (void *) skb->data; |
202 | 231 | ||
203 | nfc_dbg("entry, type 0x%x", type); | 232 | nfc_dbg("entry, type 0x%x, reason 0x%x", ntf->type, ntf->reason); |
204 | 233 | ||
205 | clear_bit(NCI_POLL_ACTIVE, &ndev->flags); | 234 | clear_bit(NCI_POLL_ACTIVE, &ndev->flags); |
206 | ndev->target_active_prot = 0; | 235 | ndev->target_active_prot = 0; |
@@ -214,6 +243,9 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, | |||
214 | ndev->rx_data_reassembly = 0; | 243 | ndev->rx_data_reassembly = 0; |
215 | } | 244 | } |
216 | 245 | ||
246 | /* set the available credits to initial value */ | ||
247 | atomic_set(&ndev->credits_cnt, ndev->initial_num_credits); | ||
248 | |||
217 | /* complete the data exchange transaction, if exists */ | 249 | /* complete the data exchange transaction, if exists */ |
218 | if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) | 250 | if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) |
219 | nci_data_exchange_complete(ndev, NULL, -EIO); | 251 | nci_data_exchange_complete(ndev, NULL, -EIO); |
@@ -237,12 +269,8 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
237 | nci_core_conn_credits_ntf_packet(ndev, skb); | 269 | nci_core_conn_credits_ntf_packet(ndev, skb); |
238 | break; | 270 | break; |
239 | 271 | ||
240 | case NCI_OP_RF_FIELD_INFO_NTF: | 272 | case NCI_OP_RF_INTF_ACTIVATED_NTF: |
241 | nci_rf_field_info_ntf_packet(ndev, skb); | 273 | nci_rf_intf_activated_ntf_packet(ndev, skb); |
242 | break; | ||
243 | |||
244 | case NCI_OP_RF_ACTIVATE_NTF: | ||
245 | nci_rf_activate_ntf_packet(ndev, skb); | ||
246 | break; | 274 | break; |
247 | 275 | ||
248 | case NCI_OP_RF_DEACTIVATE_NTF: | 276 | case NCI_OP_RF_DEACTIVATE_NTF: |
diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c index 0403d4cd0917..0591f5aff89f 100644 --- a/net/nfc/nci/rsp.c +++ b/net/nfc/nci/rsp.c | |||
@@ -42,10 +42,11 @@ static void nci_core_reset_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
42 | 42 | ||
43 | nfc_dbg("entry, status 0x%x", rsp->status); | 43 | nfc_dbg("entry, status 0x%x", rsp->status); |
44 | 44 | ||
45 | if (rsp->status == NCI_STATUS_OK) | 45 | if (rsp->status == NCI_STATUS_OK) { |
46 | ndev->nci_ver = rsp->nci_ver; | 46 | ndev->nci_ver = rsp->nci_ver; |
47 | 47 | nfc_dbg("nci_ver 0x%x, config_status 0x%x", | |
48 | nfc_dbg("nci_ver 0x%x", ndev->nci_ver); | 48 | rsp->nci_ver, rsp->config_status); |
49 | } | ||
49 | 50 | ||
50 | nci_req_complete(ndev, rsp->status); | 51 | nci_req_complete(ndev, rsp->status); |
51 | } | 52 | } |
@@ -58,13 +59,13 @@ static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
58 | nfc_dbg("entry, status 0x%x", rsp_1->status); | 59 | nfc_dbg("entry, status 0x%x", rsp_1->status); |
59 | 60 | ||
60 | if (rsp_1->status != NCI_STATUS_OK) | 61 | if (rsp_1->status != NCI_STATUS_OK) |
61 | return; | 62 | goto exit; |
62 | 63 | ||
63 | ndev->nfcc_features = __le32_to_cpu(rsp_1->nfcc_features); | 64 | ndev->nfcc_features = __le32_to_cpu(rsp_1->nfcc_features); |
64 | ndev->num_supported_rf_interfaces = rsp_1->num_supported_rf_interfaces; | 65 | ndev->num_supported_rf_interfaces = rsp_1->num_supported_rf_interfaces; |
65 | 66 | ||
66 | if (ndev->num_supported_rf_interfaces > | 67 | if (ndev->num_supported_rf_interfaces > |
67 | NCI_MAX_SUPPORTED_RF_INTERFACES) { | 68 | NCI_MAX_SUPPORTED_RF_INTERFACES) { |
68 | ndev->num_supported_rf_interfaces = | 69 | ndev->num_supported_rf_interfaces = |
69 | NCI_MAX_SUPPORTED_RF_INTERFACES; | 70 | NCI_MAX_SUPPORTED_RF_INTERFACES; |
70 | } | 71 | } |
@@ -73,20 +74,26 @@ static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
73 | rsp_1->supported_rf_interfaces, | 74 | rsp_1->supported_rf_interfaces, |
74 | ndev->num_supported_rf_interfaces); | 75 | ndev->num_supported_rf_interfaces); |
75 | 76 | ||
76 | rsp_2 = (void *) (skb->data + 6 + ndev->num_supported_rf_interfaces); | 77 | rsp_2 = (void *) (skb->data + 6 + rsp_1->num_supported_rf_interfaces); |
77 | 78 | ||
78 | ndev->max_logical_connections = | 79 | ndev->max_logical_connections = |
79 | rsp_2->max_logical_connections; | 80 | rsp_2->max_logical_connections; |
80 | ndev->max_routing_table_size = | 81 | ndev->max_routing_table_size = |
81 | __le16_to_cpu(rsp_2->max_routing_table_size); | 82 | __le16_to_cpu(rsp_2->max_routing_table_size); |
82 | ndev->max_control_packet_payload_length = | 83 | ndev->max_ctrl_pkt_payload_len = |
83 | rsp_2->max_control_packet_payload_length; | 84 | rsp_2->max_ctrl_pkt_payload_len; |
84 | ndev->rf_sending_buffer_size = | 85 | ndev->max_size_for_large_params = |
85 | __le16_to_cpu(rsp_2->rf_sending_buffer_size); | 86 | __le16_to_cpu(rsp_2->max_size_for_large_params); |
86 | ndev->rf_receiving_buffer_size = | 87 | ndev->max_data_pkt_payload_size = |
87 | __le16_to_cpu(rsp_2->rf_receiving_buffer_size); | 88 | rsp_2->max_data_pkt_payload_size; |
88 | ndev->manufacturer_id = | 89 | ndev->initial_num_credits = |
89 | __le16_to_cpu(rsp_2->manufacturer_id); | 90 | rsp_2->initial_num_credits; |
91 | ndev->manufact_id = | ||
92 | rsp_2->manufact_id; | ||
93 | ndev->manufact_specific_info = | ||
94 | __le32_to_cpu(rsp_2->manufact_specific_info); | ||
95 | |||
96 | atomic_set(&ndev->credits_cnt, ndev->initial_num_credits); | ||
90 | 97 | ||
91 | nfc_dbg("nfcc_features 0x%x", | 98 | nfc_dbg("nfcc_features 0x%x", |
92 | ndev->nfcc_features); | 99 | ndev->nfcc_features); |
@@ -104,39 +111,23 @@ static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
104 | ndev->max_logical_connections); | 111 | ndev->max_logical_connections); |
105 | nfc_dbg("max_routing_table_size %d", | 112 | nfc_dbg("max_routing_table_size %d", |
106 | ndev->max_routing_table_size); | 113 | ndev->max_routing_table_size); |
107 | nfc_dbg("max_control_packet_payload_length %d", | 114 | nfc_dbg("max_ctrl_pkt_payload_len %d", |
108 | ndev->max_control_packet_payload_length); | 115 | ndev->max_ctrl_pkt_payload_len); |
109 | nfc_dbg("rf_sending_buffer_size %d", | 116 | nfc_dbg("max_size_for_large_params %d", |
110 | ndev->rf_sending_buffer_size); | 117 | ndev->max_size_for_large_params); |
111 | nfc_dbg("rf_receiving_buffer_size %d", | 118 | nfc_dbg("max_data_pkt_payload_size %d", |
112 | ndev->rf_receiving_buffer_size); | 119 | ndev->max_data_pkt_payload_size); |
113 | nfc_dbg("manufacturer_id 0x%x", | 120 | nfc_dbg("initial_num_credits %d", |
114 | ndev->manufacturer_id); | 121 | ndev->initial_num_credits); |
115 | 122 | nfc_dbg("manufact_id 0x%x", | |
123 | ndev->manufact_id); | ||
124 | nfc_dbg("manufact_specific_info 0x%x", | ||
125 | ndev->manufact_specific_info); | ||
126 | |||
127 | exit: | ||
116 | nci_req_complete(ndev, rsp_1->status); | 128 | nci_req_complete(ndev, rsp_1->status); |
117 | } | 129 | } |
118 | 130 | ||
119 | static void nci_core_conn_create_rsp_packet(struct nci_dev *ndev, | ||
120 | struct sk_buff *skb) | ||
121 | { | ||
122 | struct nci_core_conn_create_rsp *rsp = (void *) skb->data; | ||
123 | |||
124 | nfc_dbg("entry, status 0x%x", rsp->status); | ||
125 | |||
126 | if (rsp->status != NCI_STATUS_OK) | ||
127 | return; | ||
128 | |||
129 | ndev->max_pkt_payload_size = rsp->max_pkt_payload_size; | ||
130 | ndev->initial_num_credits = rsp->initial_num_credits; | ||
131 | ndev->conn_id = rsp->conn_id; | ||
132 | |||
133 | atomic_set(&ndev->credits_cnt, ndev->initial_num_credits); | ||
134 | |||
135 | nfc_dbg("max_pkt_payload_size %d", ndev->max_pkt_payload_size); | ||
136 | nfc_dbg("initial_num_credits %d", ndev->initial_num_credits); | ||
137 | nfc_dbg("conn_id %d", ndev->conn_id); | ||
138 | } | ||
139 | |||
140 | static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev, | 131 | static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev, |
141 | struct sk_buff *skb) | 132 | struct sk_buff *skb) |
142 | { | 133 | { |
@@ -196,10 +187,6 @@ void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
196 | nci_core_init_rsp_packet(ndev, skb); | 187 | nci_core_init_rsp_packet(ndev, skb); |
197 | break; | 188 | break; |
198 | 189 | ||
199 | case NCI_OP_CORE_CONN_CREATE_RSP: | ||
200 | nci_core_conn_create_rsp_packet(ndev, skb); | ||
201 | break; | ||
202 | |||
203 | case NCI_OP_RF_DISCOVER_MAP_RSP: | 190 | case NCI_OP_RF_DISCOVER_MAP_RSP: |
204 | nci_rf_disc_map_rsp_packet(ndev, skb); | 191 | nci_rf_disc_map_rsp_packet(ndev, skb); |
205 | break; | 192 | break; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 82a6f34d39d0..0da505c9ac23 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1499,10 +1499,11 @@ retry: | |||
1499 | 1499 | ||
1500 | if (!skb) { | 1500 | if (!skb) { |
1501 | size_t reserved = LL_RESERVED_SPACE(dev); | 1501 | size_t reserved = LL_RESERVED_SPACE(dev); |
1502 | int tlen = dev->needed_tailroom; | ||
1502 | unsigned int hhlen = dev->header_ops ? dev->hard_header_len : 0; | 1503 | unsigned int hhlen = dev->header_ops ? dev->hard_header_len : 0; |
1503 | 1504 | ||
1504 | rcu_read_unlock(); | 1505 | rcu_read_unlock(); |
1505 | skb = sock_wmalloc(sk, len + reserved, 0, GFP_KERNEL); | 1506 | skb = sock_wmalloc(sk, len + reserved + tlen, 0, GFP_KERNEL); |
1506 | if (skb == NULL) | 1507 | if (skb == NULL) |
1507 | return -ENOBUFS; | 1508 | return -ENOBUFS; |
1508 | /* FIXME: Save some space for broken drivers that write a hard | 1509 | /* FIXME: Save some space for broken drivers that write a hard |
@@ -1944,7 +1945,7 @@ static void tpacket_destruct_skb(struct sk_buff *skb) | |||
1944 | 1945 | ||
1945 | static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | 1946 | static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, |
1946 | void *frame, struct net_device *dev, int size_max, | 1947 | void *frame, struct net_device *dev, int size_max, |
1947 | __be16 proto, unsigned char *addr) | 1948 | __be16 proto, unsigned char *addr, int hlen) |
1948 | { | 1949 | { |
1949 | union { | 1950 | union { |
1950 | struct tpacket_hdr *h1; | 1951 | struct tpacket_hdr *h1; |
@@ -1978,7 +1979,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | |||
1978 | return -EMSGSIZE; | 1979 | return -EMSGSIZE; |
1979 | } | 1980 | } |
1980 | 1981 | ||
1981 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 1982 | skb_reserve(skb, hlen); |
1982 | skb_reset_network_header(skb); | 1983 | skb_reset_network_header(skb); |
1983 | 1984 | ||
1984 | data = ph.raw + po->tp_hdrlen - sizeof(struct sockaddr_ll); | 1985 | data = ph.raw + po->tp_hdrlen - sizeof(struct sockaddr_ll); |
@@ -2053,6 +2054,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2053 | unsigned char *addr; | 2054 | unsigned char *addr; |
2054 | int len_sum = 0; | 2055 | int len_sum = 0; |
2055 | int status = 0; | 2056 | int status = 0; |
2057 | int hlen, tlen; | ||
2056 | 2058 | ||
2057 | mutex_lock(&po->pg_vec_lock); | 2059 | mutex_lock(&po->pg_vec_lock); |
2058 | 2060 | ||
@@ -2101,16 +2103,17 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2101 | } | 2103 | } |
2102 | 2104 | ||
2103 | status = TP_STATUS_SEND_REQUEST; | 2105 | status = TP_STATUS_SEND_REQUEST; |
2106 | hlen = LL_RESERVED_SPACE(dev); | ||
2107 | tlen = dev->needed_tailroom; | ||
2104 | skb = sock_alloc_send_skb(&po->sk, | 2108 | skb = sock_alloc_send_skb(&po->sk, |
2105 | LL_ALLOCATED_SPACE(dev) | 2109 | hlen + tlen + sizeof(struct sockaddr_ll), |
2106 | + sizeof(struct sockaddr_ll), | ||
2107 | 0, &err); | 2110 | 0, &err); |
2108 | 2111 | ||
2109 | if (unlikely(skb == NULL)) | 2112 | if (unlikely(skb == NULL)) |
2110 | goto out_status; | 2113 | goto out_status; |
2111 | 2114 | ||
2112 | tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto, | 2115 | tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto, |
2113 | addr); | 2116 | addr, hlen); |
2114 | 2117 | ||
2115 | if (unlikely(tp_len < 0)) { | 2118 | if (unlikely(tp_len < 0)) { |
2116 | if (po->tp_loss) { | 2119 | if (po->tp_loss) { |
@@ -2207,6 +2210,7 @@ static int packet_snd(struct socket *sock, | |||
2207 | int vnet_hdr_len; | 2210 | int vnet_hdr_len; |
2208 | struct packet_sock *po = pkt_sk(sk); | 2211 | struct packet_sock *po = pkt_sk(sk); |
2209 | unsigned short gso_type = 0; | 2212 | unsigned short gso_type = 0; |
2213 | int hlen, tlen; | ||
2210 | 2214 | ||
2211 | /* | 2215 | /* |
2212 | * Get and verify the address. | 2216 | * Get and verify the address. |
@@ -2291,8 +2295,9 @@ static int packet_snd(struct socket *sock, | |||
2291 | goto out_unlock; | 2295 | goto out_unlock; |
2292 | 2296 | ||
2293 | err = -ENOBUFS; | 2297 | err = -ENOBUFS; |
2294 | skb = packet_alloc_skb(sk, LL_ALLOCATED_SPACE(dev), | 2298 | hlen = LL_RESERVED_SPACE(dev); |
2295 | LL_RESERVED_SPACE(dev), len, vnet_hdr.hdr_len, | 2299 | tlen = dev->needed_tailroom; |
2300 | skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, vnet_hdr.hdr_len, | ||
2296 | msg->msg_flags & MSG_DONTWAIT, &err); | 2301 | msg->msg_flags & MSG_DONTWAIT, &err); |
2297 | if (skb == NULL) | 2302 | if (skb == NULL) |
2298 | goto out_unlock; | 2303 | goto out_unlock; |
diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 2ba6e9fb4cbc..9f60008740e3 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c | |||
@@ -534,6 +534,29 @@ static int pep_connresp_rcv(struct sock *sk, struct sk_buff *skb) | |||
534 | return pipe_handler_send_created_ind(sk); | 534 | return pipe_handler_send_created_ind(sk); |
535 | } | 535 | } |
536 | 536 | ||
537 | static int pep_enableresp_rcv(struct sock *sk, struct sk_buff *skb) | ||
538 | { | ||
539 | struct pnpipehdr *hdr = pnp_hdr(skb); | ||
540 | |||
541 | if (hdr->error_code != PN_PIPE_NO_ERROR) | ||
542 | return -ECONNREFUSED; | ||
543 | |||
544 | return pep_indicate(sk, PNS_PIPE_ENABLED_IND, 0 /* sub-blocks */, | ||
545 | NULL, 0, GFP_ATOMIC); | ||
546 | |||
547 | } | ||
548 | |||
549 | static void pipe_start_flow_control(struct sock *sk) | ||
550 | { | ||
551 | struct pep_sock *pn = pep_sk(sk); | ||
552 | |||
553 | if (!pn_flow_safe(pn->tx_fc)) { | ||
554 | atomic_set(&pn->tx_credits, 1); | ||
555 | sk->sk_write_space(sk); | ||
556 | } | ||
557 | pipe_grant_credits(sk, GFP_ATOMIC); | ||
558 | } | ||
559 | |||
537 | /* Queue an skb to an actively connected sock. | 560 | /* Queue an skb to an actively connected sock. |
538 | * Socket lock must be held. */ | 561 | * Socket lock must be held. */ |
539 | static int pipe_handler_do_rcv(struct sock *sk, struct sk_buff *skb) | 562 | static int pipe_handler_do_rcv(struct sock *sk, struct sk_buff *skb) |
@@ -579,13 +602,25 @@ static int pipe_handler_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
579 | sk->sk_state = TCP_CLOSE_WAIT; | 602 | sk->sk_state = TCP_CLOSE_WAIT; |
580 | break; | 603 | break; |
581 | } | 604 | } |
605 | if (pn->init_enable == PN_PIPE_DISABLE) | ||
606 | sk->sk_state = TCP_SYN_RECV; | ||
607 | else { | ||
608 | sk->sk_state = TCP_ESTABLISHED; | ||
609 | pipe_start_flow_control(sk); | ||
610 | } | ||
611 | break; | ||
582 | 612 | ||
583 | sk->sk_state = TCP_ESTABLISHED; | 613 | case PNS_PEP_ENABLE_RESP: |
584 | if (!pn_flow_safe(pn->tx_fc)) { | 614 | if (sk->sk_state != TCP_SYN_SENT) |
585 | atomic_set(&pn->tx_credits, 1); | 615 | break; |
586 | sk->sk_write_space(sk); | 616 | |
617 | if (pep_enableresp_rcv(sk, skb)) { | ||
618 | sk->sk_state = TCP_CLOSE_WAIT; | ||
619 | break; | ||
587 | } | 620 | } |
588 | pipe_grant_credits(sk, GFP_ATOMIC); | 621 | |
622 | sk->sk_state = TCP_ESTABLISHED; | ||
623 | pipe_start_flow_control(sk); | ||
589 | break; | 624 | break; |
590 | 625 | ||
591 | case PNS_PEP_DISCONNECT_RESP: | 626 | case PNS_PEP_DISCONNECT_RESP: |
@@ -864,14 +899,32 @@ static int pep_sock_connect(struct sock *sk, struct sockaddr *addr, int len) | |||
864 | int err; | 899 | int err; |
865 | u8 data[4] = { 0 /* sub-blocks */, PAD, PAD, PAD }; | 900 | u8 data[4] = { 0 /* sub-blocks */, PAD, PAD, PAD }; |
866 | 901 | ||
867 | pn->pipe_handle = 1; /* anything but INVALID_HANDLE */ | 902 | if (pn->pipe_handle == PN_PIPE_INVALID_HANDLE) |
903 | pn->pipe_handle = 1; /* anything but INVALID_HANDLE */ | ||
904 | |||
868 | err = pipe_handler_request(sk, PNS_PEP_CONNECT_REQ, | 905 | err = pipe_handler_request(sk, PNS_PEP_CONNECT_REQ, |
869 | PN_PIPE_ENABLE, data, 4); | 906 | pn->init_enable, data, 4); |
870 | if (err) { | 907 | if (err) { |
871 | pn->pipe_handle = PN_PIPE_INVALID_HANDLE; | 908 | pn->pipe_handle = PN_PIPE_INVALID_HANDLE; |
872 | return err; | 909 | return err; |
873 | } | 910 | } |
911 | |||
874 | sk->sk_state = TCP_SYN_SENT; | 912 | sk->sk_state = TCP_SYN_SENT; |
913 | |||
914 | return 0; | ||
915 | } | ||
916 | |||
917 | static int pep_sock_enable(struct sock *sk, struct sockaddr *addr, int len) | ||
918 | { | ||
919 | int err; | ||
920 | |||
921 | err = pipe_handler_request(sk, PNS_PEP_ENABLE_REQ, PAD, | ||
922 | NULL, 0); | ||
923 | if (err) | ||
924 | return err; | ||
925 | |||
926 | sk->sk_state = TCP_SYN_SENT; | ||
927 | |||
875 | return 0; | 928 | return 0; |
876 | } | 929 | } |
877 | 930 | ||
@@ -879,11 +932,14 @@ static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
879 | { | 932 | { |
880 | struct pep_sock *pn = pep_sk(sk); | 933 | struct pep_sock *pn = pep_sk(sk); |
881 | int answ; | 934 | int answ; |
935 | int ret = -ENOIOCTLCMD; | ||
882 | 936 | ||
883 | switch (cmd) { | 937 | switch (cmd) { |
884 | case SIOCINQ: | 938 | case SIOCINQ: |
885 | if (sk->sk_state == TCP_LISTEN) | 939 | if (sk->sk_state == TCP_LISTEN) { |
886 | return -EINVAL; | 940 | ret = -EINVAL; |
941 | break; | ||
942 | } | ||
887 | 943 | ||
888 | lock_sock(sk); | 944 | lock_sock(sk); |
889 | if (sock_flag(sk, SOCK_URGINLINE) && | 945 | if (sock_flag(sk, SOCK_URGINLINE) && |
@@ -894,10 +950,22 @@ static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
894 | else | 950 | else |
895 | answ = 0; | 951 | answ = 0; |
896 | release_sock(sk); | 952 | release_sock(sk); |
897 | return put_user(answ, (int __user *)arg); | 953 | ret = put_user(answ, (int __user *)arg); |
954 | break; | ||
955 | |||
956 | case SIOCPNENABLEPIPE: | ||
957 | lock_sock(sk); | ||
958 | if (sk->sk_state == TCP_SYN_SENT) | ||
959 | ret = -EBUSY; | ||
960 | else if (sk->sk_state == TCP_ESTABLISHED) | ||
961 | ret = -EISCONN; | ||
962 | else | ||
963 | ret = pep_sock_enable(sk, NULL, 0); | ||
964 | release_sock(sk); | ||
965 | break; | ||
898 | } | 966 | } |
899 | 967 | ||
900 | return -ENOIOCTLCMD; | 968 | return ret; |
901 | } | 969 | } |
902 | 970 | ||
903 | static int pep_init(struct sock *sk) | 971 | static int pep_init(struct sock *sk) |
@@ -960,6 +1028,18 @@ static int pep_setsockopt(struct sock *sk, int level, int optname, | |||
960 | } | 1028 | } |
961 | goto out_norel; | 1029 | goto out_norel; |
962 | 1030 | ||
1031 | case PNPIPE_HANDLE: | ||
1032 | if ((sk->sk_state == TCP_CLOSE) && | ||
1033 | (val >= 0) && (val < PN_PIPE_INVALID_HANDLE)) | ||
1034 | pn->pipe_handle = val; | ||
1035 | else | ||
1036 | err = -EINVAL; | ||
1037 | break; | ||
1038 | |||
1039 | case PNPIPE_INITSTATE: | ||
1040 | pn->init_enable = !!val; | ||
1041 | break; | ||
1042 | |||
963 | default: | 1043 | default: |
964 | err = -ENOPROTOOPT; | 1044 | err = -ENOPROTOOPT; |
965 | } | 1045 | } |
@@ -995,6 +1075,10 @@ static int pep_getsockopt(struct sock *sk, int level, int optname, | |||
995 | return -EINVAL; | 1075 | return -EINVAL; |
996 | break; | 1076 | break; |
997 | 1077 | ||
1078 | case PNPIPE_INITSTATE: | ||
1079 | val = pn->init_enable; | ||
1080 | break; | ||
1081 | |||
998 | default: | 1082 | default: |
999 | return -ENOPROTOOPT; | 1083 | return -ENOPROTOOPT; |
1000 | } | 1084 | } |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 5be19575c340..354760ebbbd2 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -644,7 +644,7 @@ static ssize_t rfkill_soft_store(struct device *dev, | |||
644 | if (!capable(CAP_NET_ADMIN)) | 644 | if (!capable(CAP_NET_ADMIN)) |
645 | return -EPERM; | 645 | return -EPERM; |
646 | 646 | ||
647 | err = strict_strtoul(buf, 0, &state); | 647 | err = kstrtoul(buf, 0, &state); |
648 | if (err) | 648 | if (err) |
649 | return err; | 649 | return err; |
650 | 650 | ||
@@ -688,7 +688,7 @@ static ssize_t rfkill_state_store(struct device *dev, | |||
688 | if (!capable(CAP_NET_ADMIN)) | 688 | if (!capable(CAP_NET_ADMIN)) |
689 | return -EPERM; | 689 | return -EPERM; |
690 | 690 | ||
691 | err = strict_strtoul(buf, 0, &state); | 691 | err = kstrtoul(buf, 0, &state); |
692 | if (err) | 692 | if (err) |
693 | return err; | 693 | return err; |
694 | 694 | ||
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c index 43ea7de2fc8e..4cba13e46ffd 100644 --- a/net/rxrpc/ar-key.c +++ b/net/rxrpc/ar-key.c | |||
@@ -306,10 +306,9 @@ static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td, | |||
306 | td->data_len = len; | 306 | td->data_len = len; |
307 | 307 | ||
308 | if (len > 0) { | 308 | if (len > 0) { |
309 | td->data = kmalloc(len, GFP_KERNEL); | 309 | td->data = kmemdup(xdr, len, GFP_KERNEL); |
310 | if (!td->data) | 310 | if (!td->data) |
311 | return -ENOMEM; | 311 | return -ENOMEM; |
312 | memcpy(td->data, xdr, len); | ||
313 | len = (len + 3) & ~3; | 312 | len = (len + 3) & ~3; |
314 | toklen -= len; | 313 | toklen -= len; |
315 | xdr += len >> 2; | 314 | xdr += len >> 2; |
@@ -401,10 +400,9 @@ static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen, | |||
401 | _debug("ticket len %u", len); | 400 | _debug("ticket len %u", len); |
402 | 401 | ||
403 | if (len > 0) { | 402 | if (len > 0) { |
404 | *_ticket = kmalloc(len, GFP_KERNEL); | 403 | *_ticket = kmemdup(xdr, len, GFP_KERNEL); |
405 | if (!*_ticket) | 404 | if (!*_ticket) |
406 | return -ENOMEM; | 405 | return -ENOMEM; |
407 | memcpy(*_ticket, xdr, len); | ||
408 | len = (len + 3) & ~3; | 406 | len = (len + 3) & ~3; |
409 | toklen -= len; | 407 | toklen -= len; |
410 | xdr += len >> 2; | 408 | xdr += len >> 2; |
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c index 3422b25df9e4..061bcb744bbd 100644 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c | |||
@@ -152,15 +152,14 @@ static bool choke_match_flow(struct sk_buff *skb1, | |||
152 | { | 152 | { |
153 | int off1, off2, poff; | 153 | int off1, off2, poff; |
154 | const u32 *ports1, *ports2; | 154 | const u32 *ports1, *ports2; |
155 | u32 _ports1, _ports2; | ||
155 | u8 ip_proto; | 156 | u8 ip_proto; |
156 | __u32 hash1; | 157 | __u32 hash1; |
157 | 158 | ||
158 | if (skb1->protocol != skb2->protocol) | 159 | if (skb1->protocol != skb2->protocol) |
159 | return false; | 160 | return false; |
160 | 161 | ||
161 | /* Use hash value as quick check | 162 | /* Use rxhash value as quick check */ |
162 | * Assumes that __skb_get_rxhash makes IP header and ports linear | ||
163 | */ | ||
164 | hash1 = skb_get_rxhash(skb1); | 163 | hash1 = skb_get_rxhash(skb1); |
165 | if (!hash1 || hash1 != skb_get_rxhash(skb2)) | 164 | if (!hash1 || hash1 != skb_get_rxhash(skb2)) |
166 | return false; | 165 | return false; |
@@ -172,10 +171,12 @@ static bool choke_match_flow(struct sk_buff *skb1, | |||
172 | switch (skb1->protocol) { | 171 | switch (skb1->protocol) { |
173 | case __constant_htons(ETH_P_IP): { | 172 | case __constant_htons(ETH_P_IP): { |
174 | const struct iphdr *ip1, *ip2; | 173 | const struct iphdr *ip1, *ip2; |
174 | struct iphdr _ip1, _ip2; | ||
175 | 175 | ||
176 | ip1 = (const struct iphdr *) (skb1->data + off1); | 176 | ip1 = skb_header_pointer(skb1, off1, sizeof(_ip1), &_ip1); |
177 | ip2 = (const struct iphdr *) (skb2->data + off2); | 177 | ip2 = skb_header_pointer(skb2, off2, sizeof(_ip2), &_ip2); |
178 | 178 | if (!ip1 || !ip2) | |
179 | return false; | ||
179 | ip_proto = ip1->protocol; | 180 | ip_proto = ip1->protocol; |
180 | if (ip_proto != ip2->protocol || | 181 | if (ip_proto != ip2->protocol || |
181 | ip1->saddr != ip2->saddr || ip1->daddr != ip2->daddr) | 182 | ip1->saddr != ip2->saddr || ip1->daddr != ip2->daddr) |
@@ -190,9 +191,12 @@ static bool choke_match_flow(struct sk_buff *skb1, | |||
190 | 191 | ||
191 | case __constant_htons(ETH_P_IPV6): { | 192 | case __constant_htons(ETH_P_IPV6): { |
192 | const struct ipv6hdr *ip1, *ip2; | 193 | const struct ipv6hdr *ip1, *ip2; |
194 | struct ipv6hdr _ip1, _ip2; | ||
193 | 195 | ||
194 | ip1 = (const struct ipv6hdr *) (skb1->data + off1); | 196 | ip1 = skb_header_pointer(skb1, off1, sizeof(_ip1), &_ip1); |
195 | ip2 = (const struct ipv6hdr *) (skb2->data + off2); | 197 | ip2 = skb_header_pointer(skb2, off2, sizeof(_ip2), &_ip2); |
198 | if (!ip1 || !ip2) | ||
199 | return false; | ||
196 | 200 | ||
197 | ip_proto = ip1->nexthdr; | 201 | ip_proto = ip1->nexthdr; |
198 | if (ip_proto != ip2->nexthdr || | 202 | if (ip_proto != ip2->nexthdr || |
@@ -214,8 +218,11 @@ static bool choke_match_flow(struct sk_buff *skb1, | |||
214 | off1 += poff; | 218 | off1 += poff; |
215 | off2 += poff; | 219 | off2 += poff; |
216 | 220 | ||
217 | ports1 = (__force u32 *)(skb1->data + off1); | 221 | ports1 = skb_header_pointer(skb1, off1, sizeof(_ports1), &_ports1); |
218 | ports2 = (__force u32 *)(skb2->data + off2); | 222 | ports2 = skb_header_pointer(skb2, off2, sizeof(_ports2), &_ports2); |
223 | if (!ports1 || !ports2) | ||
224 | return false; | ||
225 | |||
219 | return *ports1 == *ports2; | 226 | return *ports1 == *ports2; |
220 | } | 227 | } |
221 | 228 | ||
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 69fca2798804..79ac1458c2ba 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -246,6 +246,7 @@ static void dev_watchdog(unsigned long arg) | |||
246 | time_after(jiffies, (trans_start + | 246 | time_after(jiffies, (trans_start + |
247 | dev->watchdog_timeo))) { | 247 | dev->watchdog_timeo))) { |
248 | some_queue_timedout = 1; | 248 | some_queue_timedout = 1; |
249 | txq->trans_timeout++; | ||
249 | break; | 250 | break; |
250 | } | 251 | } |
251 | } | 252 | } |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 810427833bcd..91f479121c55 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -107,7 +107,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev, | |||
107 | if (addr) { | 107 | if (addr) { |
108 | addr->a.v6.sin6_family = AF_INET6; | 108 | addr->a.v6.sin6_family = AF_INET6; |
109 | addr->a.v6.sin6_port = 0; | 109 | addr->a.v6.sin6_port = 0; |
110 | ipv6_addr_copy(&addr->a.v6.sin6_addr, &ifa->addr); | 110 | addr->a.v6.sin6_addr = ifa->addr; |
111 | addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex; | 111 | addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex; |
112 | addr->valid = 1; | 112 | addr->valid = 1; |
113 | spin_lock_bh(&sctp_local_addr_lock); | 113 | spin_lock_bh(&sctp_local_addr_lock); |
@@ -219,8 +219,8 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) | |||
219 | /* Fill in the dest address from the route entry passed with the skb | 219 | /* Fill in the dest address from the route entry passed with the skb |
220 | * and the source address from the transport. | 220 | * and the source address from the transport. |
221 | */ | 221 | */ |
222 | ipv6_addr_copy(&fl6.daddr, &transport->ipaddr.v6.sin6_addr); | 222 | fl6.daddr = transport->ipaddr.v6.sin6_addr; |
223 | ipv6_addr_copy(&fl6.saddr, &transport->saddr.v6.sin6_addr); | 223 | fl6.saddr = transport->saddr.v6.sin6_addr; |
224 | 224 | ||
225 | fl6.flowlabel = np->flow_label; | 225 | fl6.flowlabel = np->flow_label; |
226 | IP6_ECN_flow_xmit(sk, fl6.flowlabel); | 226 | IP6_ECN_flow_xmit(sk, fl6.flowlabel); |
@@ -231,7 +231,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) | |||
231 | 231 | ||
232 | if (np->opt && np->opt->srcrt) { | 232 | if (np->opt && np->opt->srcrt) { |
233 | struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; | 233 | struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; |
234 | ipv6_addr_copy(&fl6.daddr, rt0->addr); | 234 | fl6.daddr = *rt0->addr; |
235 | } | 235 | } |
236 | 236 | ||
237 | SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", | 237 | SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", |
@@ -265,7 +265,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |||
265 | sctp_scope_t scope; | 265 | sctp_scope_t scope; |
266 | 266 | ||
267 | memset(fl6, 0, sizeof(struct flowi6)); | 267 | memset(fl6, 0, sizeof(struct flowi6)); |
268 | ipv6_addr_copy(&fl6->daddr, &daddr->v6.sin6_addr); | 268 | fl6->daddr = daddr->v6.sin6_addr; |
269 | fl6->fl6_dport = daddr->v6.sin6_port; | 269 | fl6->fl6_dport = daddr->v6.sin6_port; |
270 | fl6->flowi6_proto = IPPROTO_SCTP; | 270 | fl6->flowi6_proto = IPPROTO_SCTP; |
271 | if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) | 271 | if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) |
@@ -277,7 +277,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |||
277 | fl6->fl6_sport = htons(asoc->base.bind_addr.port); | 277 | fl6->fl6_sport = htons(asoc->base.bind_addr.port); |
278 | 278 | ||
279 | if (saddr) { | 279 | if (saddr) { |
280 | ipv6_addr_copy(&fl6->saddr, &saddr->v6.sin6_addr); | 280 | fl6->saddr = saddr->v6.sin6_addr; |
281 | fl6->fl6_sport = saddr->v6.sin6_port; | 281 | fl6->fl6_sport = saddr->v6.sin6_port; |
282 | SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr); | 282 | SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr); |
283 | } | 283 | } |
@@ -334,7 +334,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |||
334 | } | 334 | } |
335 | rcu_read_unlock(); | 335 | rcu_read_unlock(); |
336 | if (baddr) { | 336 | if (baddr) { |
337 | ipv6_addr_copy(&fl6->saddr, &baddr->v6.sin6_addr); | 337 | fl6->saddr = baddr->v6.sin6_addr; |
338 | fl6->fl6_sport = baddr->v6.sin6_port; | 338 | fl6->fl6_sport = baddr->v6.sin6_port; |
339 | dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); | 339 | dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); |
340 | } | 340 | } |
@@ -375,7 +375,7 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk, | |||
375 | 375 | ||
376 | if (t->dst) { | 376 | if (t->dst) { |
377 | saddr->v6.sin6_family = AF_INET6; | 377 | saddr->v6.sin6_family = AF_INET6; |
378 | ipv6_addr_copy(&saddr->v6.sin6_addr, &fl6->saddr); | 378 | saddr->v6.sin6_addr = fl6->saddr; |
379 | } | 379 | } |
380 | } | 380 | } |
381 | 381 | ||
@@ -400,7 +400,7 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist, | |||
400 | if (addr) { | 400 | if (addr) { |
401 | addr->a.v6.sin6_family = AF_INET6; | 401 | addr->a.v6.sin6_family = AF_INET6; |
402 | addr->a.v6.sin6_port = 0; | 402 | addr->a.v6.sin6_port = 0; |
403 | ipv6_addr_copy(&addr->a.v6.sin6_addr, &ifp->addr); | 403 | addr->a.v6.sin6_addr = ifp->addr; |
404 | addr->a.v6.sin6_scope_id = dev->ifindex; | 404 | addr->a.v6.sin6_scope_id = dev->ifindex; |
405 | addr->valid = 1; | 405 | addr->valid = 1; |
406 | INIT_LIST_HEAD(&addr->list); | 406 | INIT_LIST_HEAD(&addr->list); |
@@ -416,7 +416,6 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist, | |||
416 | static void sctp_v6_from_skb(union sctp_addr *addr,struct sk_buff *skb, | 416 | static void sctp_v6_from_skb(union sctp_addr *addr,struct sk_buff *skb, |
417 | int is_saddr) | 417 | int is_saddr) |
418 | { | 418 | { |
419 | void *from; | ||
420 | __be16 *port; | 419 | __be16 *port; |
421 | struct sctphdr *sh; | 420 | struct sctphdr *sh; |
422 | 421 | ||
@@ -428,12 +427,11 @@ static void sctp_v6_from_skb(union sctp_addr *addr,struct sk_buff *skb, | |||
428 | sh = sctp_hdr(skb); | 427 | sh = sctp_hdr(skb); |
429 | if (is_saddr) { | 428 | if (is_saddr) { |
430 | *port = sh->source; | 429 | *port = sh->source; |
431 | from = &ipv6_hdr(skb)->saddr; | 430 | addr->v6.sin6_addr = ipv6_hdr(skb)->saddr; |
432 | } else { | 431 | } else { |
433 | *port = sh->dest; | 432 | *port = sh->dest; |
434 | from = &ipv6_hdr(skb)->daddr; | 433 | addr->v6.sin6_addr = ipv6_hdr(skb)->daddr; |
435 | } | 434 | } |
436 | ipv6_addr_copy(&addr->v6.sin6_addr, from); | ||
437 | } | 435 | } |
438 | 436 | ||
439 | /* Initialize an sctp_addr from a socket. */ | 437 | /* Initialize an sctp_addr from a socket. */ |
@@ -441,7 +439,7 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk) | |||
441 | { | 439 | { |
442 | addr->v6.sin6_family = AF_INET6; | 440 | addr->v6.sin6_family = AF_INET6; |
443 | addr->v6.sin6_port = 0; | 441 | addr->v6.sin6_port = 0; |
444 | ipv6_addr_copy(&addr->v6.sin6_addr, &inet6_sk(sk)->rcv_saddr); | 442 | addr->v6.sin6_addr = inet6_sk(sk)->rcv_saddr; |
445 | } | 443 | } |
446 | 444 | ||
447 | /* Initialize sk->sk_rcv_saddr from sctp_addr. */ | 445 | /* Initialize sk->sk_rcv_saddr from sctp_addr. */ |
@@ -454,7 +452,7 @@ static void sctp_v6_to_sk_saddr(union sctp_addr *addr, struct sock *sk) | |||
454 | inet6_sk(sk)->rcv_saddr.s6_addr32[3] = | 452 | inet6_sk(sk)->rcv_saddr.s6_addr32[3] = |
455 | addr->v4.sin_addr.s_addr; | 453 | addr->v4.sin_addr.s_addr; |
456 | } else { | 454 | } else { |
457 | ipv6_addr_copy(&inet6_sk(sk)->rcv_saddr, &addr->v6.sin6_addr); | 455 | inet6_sk(sk)->rcv_saddr = addr->v6.sin6_addr; |
458 | } | 456 | } |
459 | } | 457 | } |
460 | 458 | ||
@@ -467,7 +465,7 @@ static void sctp_v6_to_sk_daddr(union sctp_addr *addr, struct sock *sk) | |||
467 | inet6_sk(sk)->daddr.s6_addr32[2] = htonl(0x0000ffff); | 465 | inet6_sk(sk)->daddr.s6_addr32[2] = htonl(0x0000ffff); |
468 | inet6_sk(sk)->daddr.s6_addr32[3] = addr->v4.sin_addr.s_addr; | 466 | inet6_sk(sk)->daddr.s6_addr32[3] = addr->v4.sin_addr.s_addr; |
469 | } else { | 467 | } else { |
470 | ipv6_addr_copy(&inet6_sk(sk)->daddr, &addr->v6.sin6_addr); | 468 | inet6_sk(sk)->daddr = addr->v6.sin6_addr; |
471 | } | 469 | } |
472 | } | 470 | } |
473 | 471 | ||
@@ -479,7 +477,7 @@ static void sctp_v6_from_addr_param(union sctp_addr *addr, | |||
479 | addr->v6.sin6_family = AF_INET6; | 477 | addr->v6.sin6_family = AF_INET6; |
480 | addr->v6.sin6_port = port; | 478 | addr->v6.sin6_port = port; |
481 | addr->v6.sin6_flowinfo = 0; /* BUG */ | 479 | addr->v6.sin6_flowinfo = 0; /* BUG */ |
482 | ipv6_addr_copy(&addr->v6.sin6_addr, ¶m->v6.addr); | 480 | addr->v6.sin6_addr = param->v6.addr; |
483 | addr->v6.sin6_scope_id = iif; | 481 | addr->v6.sin6_scope_id = iif; |
484 | } | 482 | } |
485 | 483 | ||
@@ -493,7 +491,7 @@ static int sctp_v6_to_addr_param(const union sctp_addr *addr, | |||
493 | 491 | ||
494 | param->v6.param_hdr.type = SCTP_PARAM_IPV6_ADDRESS; | 492 | param->v6.param_hdr.type = SCTP_PARAM_IPV6_ADDRESS; |
495 | param->v6.param_hdr.length = htons(length); | 493 | param->v6.param_hdr.length = htons(length); |
496 | ipv6_addr_copy(¶m->v6.addr, &addr->v6.sin6_addr); | 494 | param->v6.addr = addr->v6.sin6_addr; |
497 | 495 | ||
498 | return length; | 496 | return length; |
499 | } | 497 | } |
@@ -504,7 +502,7 @@ static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr, | |||
504 | { | 502 | { |
505 | addr->sa.sa_family = AF_INET6; | 503 | addr->sa.sa_family = AF_INET6; |
506 | addr->v6.sin6_port = port; | 504 | addr->v6.sin6_port = port; |
507 | ipv6_addr_copy(&addr->v6.sin6_addr, saddr); | 505 | addr->v6.sin6_addr = *saddr; |
508 | } | 506 | } |
509 | 507 | ||
510 | /* Compare addresses exactly. | 508 | /* Compare addresses exactly. |
@@ -759,7 +757,7 @@ static void sctp_inet6_event_msgname(struct sctp_ulpevent *event, | |||
759 | } | 757 | } |
760 | 758 | ||
761 | sin6from = &asoc->peer.primary_addr.v6; | 759 | sin6from = &asoc->peer.primary_addr.v6; |
762 | ipv6_addr_copy(&sin6->sin6_addr, &sin6from->sin6_addr); | 760 | sin6->sin6_addr = sin6from->sin6_addr; |
763 | if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) | 761 | if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) |
764 | sin6->sin6_scope_id = sin6from->sin6_scope_id; | 762 | sin6->sin6_scope_id = sin6from->sin6_scope_id; |
765 | } | 763 | } |
@@ -787,7 +785,7 @@ static void sctp_inet6_skb_msgname(struct sk_buff *skb, char *msgname, | |||
787 | } | 785 | } |
788 | 786 | ||
789 | /* Otherwise, just copy the v6 address. */ | 787 | /* Otherwise, just copy the v6 address. */ |
790 | ipv6_addr_copy(&sin6->sin6_addr, &ipv6_hdr(skb)->saddr); | 788 | sin6->sin6_addr = ipv6_hdr(skb)->saddr; |
791 | if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) { | 789 | if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) { |
792 | struct sctp_ulpevent *ev = sctp_skb2event(skb); | 790 | struct sctp_ulpevent *ev = sctp_skb2event(skb); |
793 | sin6->sin6_scope_id = ev->iif; | 791 | sin6->sin6_scope_id = ev->iif; |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 0121e0ab0351..a85eeeb55dd0 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -3400,8 +3400,10 @@ int sctp_process_asconf_ack(struct sctp_association *asoc, | |||
3400 | asconf_len -= length; | 3400 | asconf_len -= length; |
3401 | } | 3401 | } |
3402 | 3402 | ||
3403 | if (no_err && asoc->src_out_of_asoc_ok) | 3403 | if (no_err && asoc->src_out_of_asoc_ok) { |
3404 | asoc->src_out_of_asoc_ok = 0; | 3404 | asoc->src_out_of_asoc_ok = 0; |
3405 | sctp_transport_immediate_rtx(asoc->peer.primary_path); | ||
3406 | } | ||
3405 | 3407 | ||
3406 | /* Free the cached last sent asconf chunk. */ | 3408 | /* Free the cached last sent asconf chunk. */ |
3407 | list_del_init(&asconf->transmitted_list); | 3409 | list_del_init(&asconf->transmitted_list); |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 76388b083f28..1ff51c9d18d5 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -666,6 +666,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, | |||
666 | struct sctp_chunk *chunk) | 666 | struct sctp_chunk *chunk) |
667 | { | 667 | { |
668 | sctp_sender_hb_info_t *hbinfo; | 668 | sctp_sender_hb_info_t *hbinfo; |
669 | int was_unconfirmed = 0; | ||
669 | 670 | ||
670 | /* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of the | 671 | /* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of the |
671 | * HEARTBEAT should clear the error counter of the destination | 672 | * HEARTBEAT should clear the error counter of the destination |
@@ -692,9 +693,11 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, | |||
692 | /* Mark the destination transport address as active if it is not so | 693 | /* Mark the destination transport address as active if it is not so |
693 | * marked. | 694 | * marked. |
694 | */ | 695 | */ |
695 | if ((t->state == SCTP_INACTIVE) || (t->state == SCTP_UNCONFIRMED)) | 696 | if ((t->state == SCTP_INACTIVE) || (t->state == SCTP_UNCONFIRMED)) { |
697 | was_unconfirmed = 1; | ||
696 | sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP, | 698 | sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP, |
697 | SCTP_HEARTBEAT_SUCCESS); | 699 | SCTP_HEARTBEAT_SUCCESS); |
700 | } | ||
698 | 701 | ||
699 | /* The receiver of the HEARTBEAT ACK should also perform an | 702 | /* The receiver of the HEARTBEAT ACK should also perform an |
700 | * RTT measurement for that destination transport address | 703 | * RTT measurement for that destination transport address |
@@ -712,6 +715,9 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, | |||
712 | /* Update the heartbeat timer. */ | 715 | /* Update the heartbeat timer. */ |
713 | if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t))) | 716 | if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t))) |
714 | sctp_transport_hold(t); | 717 | sctp_transport_hold(t); |
718 | |||
719 | if (was_unconfirmed && asoc->peer.transport_count == 1) | ||
720 | sctp_transport_immediate_rtx(t); | ||
715 | } | 721 | } |
716 | 722 | ||
717 | 723 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 13bf5fcdbff1..d56c07a3d435 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -804,7 +804,7 @@ static int sctp_send_asconf_del_ip(struct sock *sk, | |||
804 | struct sockaddr_in6 *sin6; | 804 | struct sockaddr_in6 *sin6; |
805 | 805 | ||
806 | sin6 = (struct sockaddr_in6 *)addrs; | 806 | sin6 = (struct sockaddr_in6 *)addrs; |
807 | ipv6_addr_copy(&asoc->asconf_addr_del_pending->v6.sin6_addr, &sin6->sin6_addr); | 807 | asoc->asconf_addr_del_pending->v6.sin6_addr = sin6->sin6_addr; |
808 | } | 808 | } |
809 | SCTP_DEBUG_PRINTK_IPADDR("send_asconf_del_ip: keep the last address asoc: %p ", | 809 | SCTP_DEBUG_PRINTK_IPADDR("send_asconf_del_ip: keep the last address asoc: %p ", |
810 | " at %p\n", asoc, asoc->asconf_addr_del_pending, | 810 | " at %p\n", asoc, asoc->asconf_addr_del_pending, |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 394c57ca2f54..3889330b7b04 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -641,3 +641,19 @@ void sctp_transport_reset(struct sctp_transport *t) | |||
641 | t->cacc.next_tsn_at_change = 0; | 641 | t->cacc.next_tsn_at_change = 0; |
642 | t->cacc.cacc_saw_newack = 0; | 642 | t->cacc.cacc_saw_newack = 0; |
643 | } | 643 | } |
644 | |||
645 | /* Schedule retransmission on the given transport */ | ||
646 | void sctp_transport_immediate_rtx(struct sctp_transport *t) | ||
647 | { | ||
648 | /* Stop pending T3_rtx_timer */ | ||
649 | if (timer_pending(&t->T3_rtx_timer)) { | ||
650 | (void)del_timer(&t->T3_rtx_timer); | ||
651 | sctp_transport_put(t); | ||
652 | } | ||
653 | sctp_retransmit(&t->asoc->outqueue, t, SCTP_RTXR_T3_RTX); | ||
654 | if (!timer_pending(&t->T3_rtx_timer)) { | ||
655 | if (!mod_timer(&t->T3_rtx_timer, jiffies + t->rto)) | ||
656 | sctp_transport_hold(t); | ||
657 | } | ||
658 | return; | ||
659 | } | ||
diff --git a/net/socket.c b/net/socket.c index 2877647f347b..e62b4f055071 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -538,6 +538,8 @@ int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags) | |||
538 | *tx_flags |= SKBTX_HW_TSTAMP; | 538 | *tx_flags |= SKBTX_HW_TSTAMP; |
539 | if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE)) | 539 | if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE)) |
540 | *tx_flags |= SKBTX_SW_TSTAMP; | 540 | *tx_flags |= SKBTX_SW_TSTAMP; |
541 | if (sock_flag(sk, SOCK_WIFI_STATUS)) | ||
542 | *tx_flags |= SKBTX_WIFI_STATUS; | ||
541 | return 0; | 543 | return 0; |
542 | } | 544 | } |
543 | EXPORT_SYMBOL(sock_tx_timestamp); | 545 | EXPORT_SYMBOL(sock_tx_timestamp); |
@@ -549,6 +551,8 @@ static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock, | |||
549 | 551 | ||
550 | sock_update_classid(sock->sk); | 552 | sock_update_classid(sock->sk); |
551 | 553 | ||
554 | sock_update_netprioidx(sock->sk); | ||
555 | |||
552 | si->sock = sock; | 556 | si->sock = sock; |
553 | si->scm = NULL; | 557 | si->scm = NULL; |
554 | si->msg = msg; | 558 | si->msg = msg; |
@@ -674,6 +678,22 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, | |||
674 | } | 678 | } |
675 | EXPORT_SYMBOL_GPL(__sock_recv_timestamp); | 679 | EXPORT_SYMBOL_GPL(__sock_recv_timestamp); |
676 | 680 | ||
681 | void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, | ||
682 | struct sk_buff *skb) | ||
683 | { | ||
684 | int ack; | ||
685 | |||
686 | if (!sock_flag(sk, SOCK_WIFI_STATUS)) | ||
687 | return; | ||
688 | if (!skb->wifi_acked_valid) | ||
689 | return; | ||
690 | |||
691 | ack = skb->wifi_acked; | ||
692 | |||
693 | put_cmsg(msg, SOL_SOCKET, SCM_WIFI_STATUS, sizeof(ack), &ack); | ||
694 | } | ||
695 | EXPORT_SYMBOL_GPL(__sock_recv_wifi_status); | ||
696 | |||
677 | static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, | 697 | static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, |
678 | struct sk_buff *skb) | 698 | struct sk_buff *skb) |
679 | { | 699 | { |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index ce136323da8b..fe258fc37f50 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
@@ -134,7 +134,7 @@ static void ip_map_init(struct cache_head *cnew, struct cache_head *citem) | |||
134 | struct ip_map *item = container_of(citem, struct ip_map, h); | 134 | struct ip_map *item = container_of(citem, struct ip_map, h); |
135 | 135 | ||
136 | strcpy(new->m_class, item->m_class); | 136 | strcpy(new->m_class, item->m_class); |
137 | ipv6_addr_copy(&new->m_addr, &item->m_addr); | 137 | new->m_addr = item->m_addr; |
138 | } | 138 | } |
139 | static void update(struct cache_head *cnew, struct cache_head *citem) | 139 | static void update(struct cache_head *cnew, struct cache_head *citem) |
140 | { | 140 | { |
@@ -274,7 +274,7 @@ static int ip_map_show(struct seq_file *m, | |||
274 | } | 274 | } |
275 | im = container_of(h, struct ip_map, h); | 275 | im = container_of(h, struct ip_map, h); |
276 | /* class addr domain */ | 276 | /* class addr domain */ |
277 | ipv6_addr_copy(&addr, &im->m_addr); | 277 | addr = im->m_addr; |
278 | 278 | ||
279 | if (test_bit(CACHE_VALID, &h->flags) && | 279 | if (test_bit(CACHE_VALID, &h->flags) && |
280 | !test_bit(CACHE_NEGATIVE, &h->flags)) | 280 | !test_bit(CACHE_NEGATIVE, &h->flags)) |
@@ -297,7 +297,7 @@ static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, | |||
297 | struct cache_head *ch; | 297 | struct cache_head *ch; |
298 | 298 | ||
299 | strcpy(ip.m_class, class); | 299 | strcpy(ip.m_class, class); |
300 | ipv6_addr_copy(&ip.m_addr, addr); | 300 | ip.m_addr = *addr; |
301 | ch = sunrpc_cache_lookup(cd, &ip.h, | 301 | ch = sunrpc_cache_lookup(cd, &ip.h, |
302 | hash_str(class, IP_HASHBITS) ^ | 302 | hash_str(class, IP_HASHBITS) ^ |
303 | hash_ip6(*addr)); | 303 | hash_ip6(*addr)); |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 71bed1c1c77a..4653286fcc9e 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -157,7 +157,7 @@ static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh) | |||
157 | cmh->cmsg_level = SOL_IPV6; | 157 | cmh->cmsg_level = SOL_IPV6; |
158 | cmh->cmsg_type = IPV6_PKTINFO; | 158 | cmh->cmsg_type = IPV6_PKTINFO; |
159 | pki->ipi6_ifindex = daddr->sin6_scope_id; | 159 | pki->ipi6_ifindex = daddr->sin6_scope_id; |
160 | ipv6_addr_copy(&pki->ipi6_addr, &daddr->sin6_addr); | 160 | pki->ipi6_addr = daddr->sin6_addr; |
161 | cmh->cmsg_len = CMSG_LEN(sizeof(*pki)); | 161 | cmh->cmsg_len = CMSG_LEN(sizeof(*pki)); |
162 | } | 162 | } |
163 | break; | 163 | break; |
@@ -523,7 +523,7 @@ static int svc_udp_get_dest_address6(struct svc_rqst *rqstp, | |||
523 | return 0; | 523 | return 0; |
524 | 524 | ||
525 | daddr->sin6_family = AF_INET6; | 525 | daddr->sin6_family = AF_INET6; |
526 | ipv6_addr_copy(&daddr->sin6_addr, &pki->ipi6_addr); | 526 | daddr->sin6_addr = pki->ipi6_addr; |
527 | daddr->sin6_scope_id = pki->ipi6_ifindex; | 527 | daddr->sin6_scope_id = pki->ipi6_ifindex; |
528 | return 1; | 528 | return 1; |
529 | } | 529 | } |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 220f3bd176f8..ccdfed897651 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -492,6 +492,10 @@ int wiphy_register(struct wiphy *wiphy) | |||
492 | !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY))) | 492 | !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY))) |
493 | return -EINVAL; | 493 | return -EINVAL; |
494 | 494 | ||
495 | if (WARN_ON(wiphy->ap_sme_capa && | ||
496 | !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME))) | ||
497 | return -EINVAL; | ||
498 | |||
495 | if (WARN_ON(wiphy->addresses && !wiphy->n_addresses)) | 499 | if (WARN_ON(wiphy->addresses && !wiphy->n_addresses)) |
496 | return -EINVAL; | 500 | return -EINVAL; |
497 | 501 | ||
diff --git a/net/wireless/core.h b/net/wireless/core.h index b9ec3061ed72..1c7d4df5418c 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -54,6 +54,8 @@ struct cfg80211_registered_device { | |||
54 | int opencount; /* also protected by devlist_mtx */ | 54 | int opencount; /* also protected by devlist_mtx */ |
55 | wait_queue_head_t dev_wait; | 55 | wait_queue_head_t dev_wait; |
56 | 56 | ||
57 | u32 ap_beacons_nlpid; | ||
58 | |||
57 | /* BSSes/scanning */ | 59 | /* BSSes/scanning */ |
58 | spinlock_t bss_lock; | 60 | spinlock_t bss_lock; |
59 | struct list_head bss_list; | 61 | struct list_head bss_list; |
@@ -376,7 +378,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
376 | enum nl80211_channel_type channel_type, | 378 | enum nl80211_channel_type channel_type, |
377 | bool channel_type_valid, unsigned int wait, | 379 | bool channel_type_valid, unsigned int wait, |
378 | const u8 *buf, size_t len, bool no_cck, | 380 | const u8 *buf, size_t len, bool no_cck, |
379 | u64 *cookie); | 381 | bool dont_wait_for_ack, u64 *cookie); |
380 | 382 | ||
381 | /* SME */ | 383 | /* SME */ |
382 | int __cfg80211_connect(struct cfg80211_registered_device *rdev, | 384 | int __cfg80211_connect(struct cfg80211_registered_device *rdev, |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 21fc9702f81c..6c1bafd508c8 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -879,6 +879,9 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) | |||
879 | } | 879 | } |
880 | 880 | ||
881 | spin_unlock_bh(&wdev->mgmt_registrations_lock); | 881 | spin_unlock_bh(&wdev->mgmt_registrations_lock); |
882 | |||
883 | if (nlpid == wdev->ap_unexpected_nlpid) | ||
884 | wdev->ap_unexpected_nlpid = 0; | ||
882 | } | 885 | } |
883 | 886 | ||
884 | void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) | 887 | void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) |
@@ -901,7 +904,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
901 | enum nl80211_channel_type channel_type, | 904 | enum nl80211_channel_type channel_type, |
902 | bool channel_type_valid, unsigned int wait, | 905 | bool channel_type_valid, unsigned int wait, |
903 | const u8 *buf, size_t len, bool no_cck, | 906 | const u8 *buf, size_t len, bool no_cck, |
904 | u64 *cookie) | 907 | bool dont_wait_for_ack, u64 *cookie) |
905 | { | 908 | { |
906 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 909 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
907 | const struct ieee80211_mgmt *mgmt; | 910 | const struct ieee80211_mgmt *mgmt; |
@@ -992,7 +995,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
992 | /* Transmit the Action frame as requested by user space */ | 995 | /* Transmit the Action frame as requested by user space */ |
993 | return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan, | 996 | return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan, |
994 | channel_type, channel_type_valid, | 997 | channel_type, channel_type_valid, |
995 | wait, buf, len, no_cck, cookie); | 998 | wait, buf, len, no_cck, dont_wait_for_ack, |
999 | cookie); | ||
996 | } | 1000 | } |
997 | 1001 | ||
998 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, | 1002 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, |
@@ -1107,3 +1111,30 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, | |||
1107 | nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); | 1111 | nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); |
1108 | } | 1112 | } |
1109 | EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); | 1113 | EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); |
1114 | |||
1115 | bool cfg80211_rx_spurious_frame(struct net_device *dev, | ||
1116 | const u8 *addr, gfp_t gfp) | ||
1117 | { | ||
1118 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
1119 | |||
1120 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && | ||
1121 | wdev->iftype != NL80211_IFTYPE_P2P_GO)) | ||
1122 | return false; | ||
1123 | |||
1124 | return nl80211_unexpected_frame(dev, addr, gfp); | ||
1125 | } | ||
1126 | EXPORT_SYMBOL(cfg80211_rx_spurious_frame); | ||
1127 | |||
1128 | bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, | ||
1129 | const u8 *addr, gfp_t gfp) | ||
1130 | { | ||
1131 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
1132 | |||
1133 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && | ||
1134 | wdev->iftype != NL80211_IFTYPE_P2P_GO && | ||
1135 | wdev->iftype != NL80211_IFTYPE_AP_VLAN)) | ||
1136 | return false; | ||
1137 | |||
1138 | return nl80211_unexpected_4addr_frame(dev, addr, gfp); | ||
1139 | } | ||
1140 | EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame); | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index b3a476fe8272..6bc7c4b32fa5 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -98,7 +98,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
98 | [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, | 98 | [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, |
99 | [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, | 99 | [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, |
100 | [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, | 100 | [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, |
101 | [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 }, | 101 | [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 }, |
102 | [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 }, | 102 | [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 }, |
103 | 103 | ||
104 | [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, | 104 | [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, |
@@ -196,6 +196,9 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
196 | [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 }, | 196 | [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 }, |
197 | [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG }, | 197 | [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG }, |
198 | [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG }, | 198 | [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG }, |
199 | [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG }, | ||
200 | [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY, | ||
201 | .len = IEEE80211_MAX_DATA_LEN }, | ||
199 | }; | 202 | }; |
200 | 203 | ||
201 | /* policy for the key attributes */ | 204 | /* policy for the key attributes */ |
@@ -203,7 +206,7 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = { | |||
203 | [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN }, | 206 | [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN }, |
204 | [NL80211_KEY_IDX] = { .type = NLA_U8 }, | 207 | [NL80211_KEY_IDX] = { .type = NLA_U8 }, |
205 | [NL80211_KEY_CIPHER] = { .type = NLA_U32 }, | 208 | [NL80211_KEY_CIPHER] = { .type = NLA_U32 }, |
206 | [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 }, | 209 | [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 }, |
207 | [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, | 210 | [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, |
208 | [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, | 211 | [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, |
209 | [NL80211_KEY_TYPE] = { .type = NLA_U32 }, | 212 | [NL80211_KEY_TYPE] = { .type = NLA_U32 }, |
@@ -758,6 +761,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
758 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, | 761 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, |
759 | dev->wiphy.available_antennas_rx); | 762 | dev->wiphy.available_antennas_rx); |
760 | 763 | ||
764 | if (dev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) | ||
765 | NLA_PUT_U32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD, | ||
766 | dev->wiphy.probe_resp_offload); | ||
767 | |||
761 | if ((dev->wiphy.available_antennas_tx || | 768 | if ((dev->wiphy.available_antennas_tx || |
762 | dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { | 769 | dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { |
763 | u32 tx_ant = 0, rx_ant = 0; | 770 | u32 tx_ant = 0, rx_ant = 0; |
@@ -890,6 +897,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
890 | } | 897 | } |
891 | if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) | 898 | if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) |
892 | CMD(sched_scan_start, START_SCHED_SCAN); | 899 | CMD(sched_scan_start, START_SCHED_SCAN); |
900 | CMD(probe_client, PROBE_CLIENT); | ||
901 | if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) { | ||
902 | i++; | ||
903 | NLA_PUT_U32(msg, i, NL80211_CMD_REGISTER_BEACONS); | ||
904 | } | ||
893 | 905 | ||
894 | #undef CMD | 906 | #undef CMD |
895 | 907 | ||
@@ -1007,6 +1019,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
1007 | if (nl80211_put_iface_combinations(&dev->wiphy, msg)) | 1019 | if (nl80211_put_iface_combinations(&dev->wiphy, msg)) |
1008 | goto nla_put_failure; | 1020 | goto nla_put_failure; |
1009 | 1021 | ||
1022 | if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) | ||
1023 | NLA_PUT_U32(msg, NL80211_ATTR_DEVICE_AP_SME, | ||
1024 | dev->wiphy.ap_sme_capa); | ||
1025 | |||
1026 | NLA_PUT_U32(msg, NL80211_ATTR_FEATURE_FLAGS, dev->wiphy.features); | ||
1027 | |||
1010 | return genlmsg_end(msg, hdr); | 1028 | return genlmsg_end(msg, hdr); |
1011 | 1029 | ||
1012 | nla_put_failure: | 1030 | nla_put_failure: |
@@ -2155,6 +2173,13 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) | |||
2155 | nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); | 2173 | nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); |
2156 | } | 2174 | } |
2157 | 2175 | ||
2176 | if (info->attrs[NL80211_ATTR_PROBE_RESP]) { | ||
2177 | params.probe_resp = | ||
2178 | nla_data(info->attrs[NL80211_ATTR_PROBE_RESP]); | ||
2179 | params.probe_resp_len = | ||
2180 | nla_len(info->attrs[NL80211_ATTR_PROBE_RESP]); | ||
2181 | } | ||
2182 | |||
2158 | err = call(&rdev->wiphy, dev, ¶ms); | 2183 | err = call(&rdev->wiphy, dev, ¶ms); |
2159 | if (!err && params.interval) | 2184 | if (!err && params.interval) |
2160 | wdev->beacon_interval = params.interval; | 2185 | wdev->beacon_interval = params.interval; |
@@ -5271,12 +5296,13 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
5271 | bool channel_type_valid = false; | 5296 | bool channel_type_valid = false; |
5272 | u32 freq; | 5297 | u32 freq; |
5273 | int err; | 5298 | int err; |
5274 | void *hdr; | 5299 | void *hdr = NULL; |
5275 | u64 cookie; | 5300 | u64 cookie; |
5276 | struct sk_buff *msg; | 5301 | struct sk_buff *msg = NULL; |
5277 | unsigned int wait = 0; | 5302 | unsigned int wait = 0; |
5278 | bool offchan; | 5303 | bool offchan, no_cck, dont_wait_for_ack; |
5279 | bool no_cck; | 5304 | |
5305 | dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK]; | ||
5280 | 5306 | ||
5281 | if (!info->attrs[NL80211_ATTR_FRAME] || | 5307 | if (!info->attrs[NL80211_ATTR_FRAME] || |
5282 | !info->attrs[NL80211_ATTR_WIPHY_FREQ]) | 5308 | !info->attrs[NL80211_ATTR_WIPHY_FREQ]) |
@@ -5320,29 +5346,36 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
5320 | if (chan == NULL) | 5346 | if (chan == NULL) |
5321 | return -EINVAL; | 5347 | return -EINVAL; |
5322 | 5348 | ||
5323 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 5349 | if (!dont_wait_for_ack) { |
5324 | if (!msg) | 5350 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
5325 | return -ENOMEM; | 5351 | if (!msg) |
5352 | return -ENOMEM; | ||
5326 | 5353 | ||
5327 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, | 5354 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, |
5328 | NL80211_CMD_FRAME); | 5355 | NL80211_CMD_FRAME); |
5329 | 5356 | ||
5330 | if (IS_ERR(hdr)) { | 5357 | if (IS_ERR(hdr)) { |
5331 | err = PTR_ERR(hdr); | 5358 | err = PTR_ERR(hdr); |
5332 | goto free_msg; | 5359 | goto free_msg; |
5360 | } | ||
5333 | } | 5361 | } |
5362 | |||
5334 | err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type, | 5363 | err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type, |
5335 | channel_type_valid, wait, | 5364 | channel_type_valid, wait, |
5336 | nla_data(info->attrs[NL80211_ATTR_FRAME]), | 5365 | nla_data(info->attrs[NL80211_ATTR_FRAME]), |
5337 | nla_len(info->attrs[NL80211_ATTR_FRAME]), | 5366 | nla_len(info->attrs[NL80211_ATTR_FRAME]), |
5338 | no_cck, &cookie); | 5367 | no_cck, dont_wait_for_ack, &cookie); |
5339 | if (err) | 5368 | if (err) |
5340 | goto free_msg; | 5369 | goto free_msg; |
5341 | 5370 | ||
5342 | NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); | 5371 | if (msg) { |
5372 | NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); | ||
5343 | 5373 | ||
5344 | genlmsg_end(msg, hdr); | 5374 | genlmsg_end(msg, hdr); |
5345 | return genlmsg_reply(msg, info); | 5375 | return genlmsg_reply(msg, info); |
5376 | } | ||
5377 | |||
5378 | return 0; | ||
5346 | 5379 | ||
5347 | nla_put_failure: | 5380 | nla_put_failure: |
5348 | err = -ENOBUFS; | 5381 | err = -ENOBUFS; |
@@ -5832,6 +5865,91 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) | |||
5832 | return err; | 5865 | return err; |
5833 | } | 5866 | } |
5834 | 5867 | ||
5868 | static int nl80211_register_unexpected_frame(struct sk_buff *skb, | ||
5869 | struct genl_info *info) | ||
5870 | { | ||
5871 | struct net_device *dev = info->user_ptr[1]; | ||
5872 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
5873 | |||
5874 | if (wdev->iftype != NL80211_IFTYPE_AP && | ||
5875 | wdev->iftype != NL80211_IFTYPE_P2P_GO) | ||
5876 | return -EINVAL; | ||
5877 | |||
5878 | if (wdev->ap_unexpected_nlpid) | ||
5879 | return -EBUSY; | ||
5880 | |||
5881 | wdev->ap_unexpected_nlpid = info->snd_pid; | ||
5882 | return 0; | ||
5883 | } | ||
5884 | |||
5885 | static int nl80211_probe_client(struct sk_buff *skb, | ||
5886 | struct genl_info *info) | ||
5887 | { | ||
5888 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
5889 | struct net_device *dev = info->user_ptr[1]; | ||
5890 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
5891 | struct sk_buff *msg; | ||
5892 | void *hdr; | ||
5893 | const u8 *addr; | ||
5894 | u64 cookie; | ||
5895 | int err; | ||
5896 | |||
5897 | if (wdev->iftype != NL80211_IFTYPE_AP && | ||
5898 | wdev->iftype != NL80211_IFTYPE_P2P_GO) | ||
5899 | return -EOPNOTSUPP; | ||
5900 | |||
5901 | if (!info->attrs[NL80211_ATTR_MAC]) | ||
5902 | return -EINVAL; | ||
5903 | |||
5904 | if (!rdev->ops->probe_client) | ||
5905 | return -EOPNOTSUPP; | ||
5906 | |||
5907 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
5908 | if (!msg) | ||
5909 | return -ENOMEM; | ||
5910 | |||
5911 | hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, | ||
5912 | NL80211_CMD_PROBE_CLIENT); | ||
5913 | |||
5914 | if (IS_ERR(hdr)) { | ||
5915 | err = PTR_ERR(hdr); | ||
5916 | goto free_msg; | ||
5917 | } | ||
5918 | |||
5919 | addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | ||
5920 | |||
5921 | err = rdev->ops->probe_client(&rdev->wiphy, dev, addr, &cookie); | ||
5922 | if (err) | ||
5923 | goto free_msg; | ||
5924 | |||
5925 | NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); | ||
5926 | |||
5927 | genlmsg_end(msg, hdr); | ||
5928 | |||
5929 | return genlmsg_reply(msg, info); | ||
5930 | |||
5931 | nla_put_failure: | ||
5932 | err = -ENOBUFS; | ||
5933 | free_msg: | ||
5934 | nlmsg_free(msg); | ||
5935 | return err; | ||
5936 | } | ||
5937 | |||
5938 | static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info) | ||
5939 | { | ||
5940 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
5941 | |||
5942 | if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS)) | ||
5943 | return -EOPNOTSUPP; | ||
5944 | |||
5945 | if (rdev->ap_beacons_nlpid) | ||
5946 | return -EBUSY; | ||
5947 | |||
5948 | rdev->ap_beacons_nlpid = info->snd_pid; | ||
5949 | |||
5950 | return 0; | ||
5951 | } | ||
5952 | |||
5835 | #define NL80211_FLAG_NEED_WIPHY 0x01 | 5953 | #define NL80211_FLAG_NEED_WIPHY 0x01 |
5836 | #define NL80211_FLAG_NEED_NETDEV 0x02 | 5954 | #define NL80211_FLAG_NEED_NETDEV 0x02 |
5837 | #define NL80211_FLAG_NEED_RTNL 0x04 | 5955 | #define NL80211_FLAG_NEED_RTNL 0x04 |
@@ -6387,6 +6505,30 @@ static struct genl_ops nl80211_ops[] = { | |||
6387 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 6505 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
6388 | NL80211_FLAG_NEED_RTNL, | 6506 | NL80211_FLAG_NEED_RTNL, |
6389 | }, | 6507 | }, |
6508 | { | ||
6509 | .cmd = NL80211_CMD_UNEXPECTED_FRAME, | ||
6510 | .doit = nl80211_register_unexpected_frame, | ||
6511 | .policy = nl80211_policy, | ||
6512 | .flags = GENL_ADMIN_PERM, | ||
6513 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | ||
6514 | NL80211_FLAG_NEED_RTNL, | ||
6515 | }, | ||
6516 | { | ||
6517 | .cmd = NL80211_CMD_PROBE_CLIENT, | ||
6518 | .doit = nl80211_probe_client, | ||
6519 | .policy = nl80211_policy, | ||
6520 | .flags = GENL_ADMIN_PERM, | ||
6521 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | ||
6522 | NL80211_FLAG_NEED_RTNL, | ||
6523 | }, | ||
6524 | { | ||
6525 | .cmd = NL80211_CMD_REGISTER_BEACONS, | ||
6526 | .doit = nl80211_register_beacons, | ||
6527 | .policy = nl80211_policy, | ||
6528 | .flags = GENL_ADMIN_PERM, | ||
6529 | .internal_flags = NL80211_FLAG_NEED_WIPHY | | ||
6530 | NL80211_FLAG_NEED_RTNL, | ||
6531 | }, | ||
6390 | }; | 6532 | }; |
6391 | 6533 | ||
6392 | static struct genl_multicast_group nl80211_mlme_mcgrp = { | 6534 | static struct genl_multicast_group nl80211_mlme_mcgrp = { |
@@ -6639,10 +6781,7 @@ void nl80211_send_reg_change_event(struct regulatory_request *request) | |||
6639 | if (wiphy_idx_valid(request->wiphy_idx)) | 6781 | if (wiphy_idx_valid(request->wiphy_idx)) |
6640 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx); | 6782 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx); |
6641 | 6783 | ||
6642 | if (genlmsg_end(msg, hdr) < 0) { | 6784 | genlmsg_end(msg, hdr); |
6643 | nlmsg_free(msg); | ||
6644 | return; | ||
6645 | } | ||
6646 | 6785 | ||
6647 | rcu_read_lock(); | 6786 | rcu_read_lock(); |
6648 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, | 6787 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, |
@@ -6678,10 +6817,7 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, | |||
6678 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | 6817 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); |
6679 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); | 6818 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); |
6680 | 6819 | ||
6681 | if (genlmsg_end(msg, hdr) < 0) { | 6820 | genlmsg_end(msg, hdr); |
6682 | nlmsg_free(msg); | ||
6683 | return; | ||
6684 | } | ||
6685 | 6821 | ||
6686 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 6822 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6687 | nl80211_mlme_mcgrp.id, gfp); | 6823 | nl80211_mlme_mcgrp.id, gfp); |
@@ -6762,10 +6898,7 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, | |||
6762 | NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT); | 6898 | NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT); |
6763 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); | 6899 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); |
6764 | 6900 | ||
6765 | if (genlmsg_end(msg, hdr) < 0) { | 6901 | genlmsg_end(msg, hdr); |
6766 | nlmsg_free(msg); | ||
6767 | return; | ||
6768 | } | ||
6769 | 6902 | ||
6770 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 6903 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6771 | nl80211_mlme_mcgrp.id, gfp); | 6904 | nl80211_mlme_mcgrp.id, gfp); |
@@ -6821,10 +6954,7 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, | |||
6821 | if (resp_ie) | 6954 | if (resp_ie) |
6822 | NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie); | 6955 | NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie); |
6823 | 6956 | ||
6824 | if (genlmsg_end(msg, hdr) < 0) { | 6957 | genlmsg_end(msg, hdr); |
6825 | nlmsg_free(msg); | ||
6826 | return; | ||
6827 | } | ||
6828 | 6958 | ||
6829 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 6959 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6830 | nl80211_mlme_mcgrp.id, gfp); | 6960 | nl80211_mlme_mcgrp.id, gfp); |
@@ -6862,10 +6992,7 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, | |||
6862 | if (resp_ie) | 6992 | if (resp_ie) |
6863 | NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie); | 6993 | NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie); |
6864 | 6994 | ||
6865 | if (genlmsg_end(msg, hdr) < 0) { | 6995 | genlmsg_end(msg, hdr); |
6866 | nlmsg_free(msg); | ||
6867 | return; | ||
6868 | } | ||
6869 | 6996 | ||
6870 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 6997 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6871 | nl80211_mlme_mcgrp.id, gfp); | 6998 | nl80211_mlme_mcgrp.id, gfp); |
@@ -6903,10 +7030,7 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, | |||
6903 | if (ie) | 7030 | if (ie) |
6904 | NLA_PUT(msg, NL80211_ATTR_IE, ie_len, ie); | 7031 | NLA_PUT(msg, NL80211_ATTR_IE, ie_len, ie); |
6905 | 7032 | ||
6906 | if (genlmsg_end(msg, hdr) < 0) { | 7033 | genlmsg_end(msg, hdr); |
6907 | nlmsg_free(msg); | ||
6908 | return; | ||
6909 | } | ||
6910 | 7034 | ||
6911 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7035 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6912 | nl80211_mlme_mcgrp.id, GFP_KERNEL); | 7036 | nl80211_mlme_mcgrp.id, GFP_KERNEL); |
@@ -6939,10 +7063,7 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, | |||
6939 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | 7063 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); |
6940 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid); | 7064 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid); |
6941 | 7065 | ||
6942 | if (genlmsg_end(msg, hdr) < 0) { | 7066 | genlmsg_end(msg, hdr); |
6943 | nlmsg_free(msg); | ||
6944 | return; | ||
6945 | } | ||
6946 | 7067 | ||
6947 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7068 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6948 | nl80211_mlme_mcgrp.id, gfp); | 7069 | nl80211_mlme_mcgrp.id, gfp); |
@@ -6977,10 +7098,7 @@ void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, | |||
6977 | if (ie_len && ie) | 7098 | if (ie_len && ie) |
6978 | NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie); | 7099 | NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie); |
6979 | 7100 | ||
6980 | if (genlmsg_end(msg, hdr) < 0) { | 7101 | genlmsg_end(msg, hdr); |
6981 | nlmsg_free(msg); | ||
6982 | return; | ||
6983 | } | ||
6984 | 7102 | ||
6985 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7103 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
6986 | nl80211_mlme_mcgrp.id, gfp); | 7104 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7019,10 +7137,7 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, | |||
7019 | if (tsc) | 7137 | if (tsc) |
7020 | NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc); | 7138 | NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc); |
7021 | 7139 | ||
7022 | if (genlmsg_end(msg, hdr) < 0) { | 7140 | genlmsg_end(msg, hdr); |
7023 | nlmsg_free(msg); | ||
7024 | return; | ||
7025 | } | ||
7026 | 7141 | ||
7027 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7142 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7028 | nl80211_mlme_mcgrp.id, gfp); | 7143 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7073,10 +7188,7 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy, | |||
7073 | goto nla_put_failure; | 7188 | goto nla_put_failure; |
7074 | nla_nest_end(msg, nl_freq); | 7189 | nla_nest_end(msg, nl_freq); |
7075 | 7190 | ||
7076 | if (genlmsg_end(msg, hdr) < 0) { | 7191 | genlmsg_end(msg, hdr); |
7077 | nlmsg_free(msg); | ||
7078 | return; | ||
7079 | } | ||
7080 | 7192 | ||
7081 | rcu_read_lock(); | 7193 | rcu_read_lock(); |
7082 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, | 7194 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, |
@@ -7119,10 +7231,7 @@ static void nl80211_send_remain_on_chan_event( | |||
7119 | if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL) | 7231 | if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL) |
7120 | NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration); | 7232 | NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration); |
7121 | 7233 | ||
7122 | if (genlmsg_end(msg, hdr) < 0) { | 7234 | genlmsg_end(msg, hdr); |
7123 | nlmsg_free(msg); | ||
7124 | return; | ||
7125 | } | ||
7126 | 7235 | ||
7127 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7236 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7128 | nl80211_mlme_mcgrp.id, gfp); | 7237 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7193,10 +7302,7 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, | |||
7193 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); | 7302 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); |
7194 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); | 7303 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); |
7195 | 7304 | ||
7196 | if (genlmsg_end(msg, hdr) < 0) { | 7305 | genlmsg_end(msg, hdr); |
7197 | nlmsg_free(msg); | ||
7198 | return; | ||
7199 | } | ||
7200 | 7306 | ||
7201 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7307 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7202 | nl80211_mlme_mcgrp.id, gfp); | 7308 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7207,13 +7313,68 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, | |||
7207 | nlmsg_free(msg); | 7313 | nlmsg_free(msg); |
7208 | } | 7314 | } |
7209 | 7315 | ||
7316 | static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd, | ||
7317 | const u8 *addr, gfp_t gfp) | ||
7318 | { | ||
7319 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
7320 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
7321 | struct sk_buff *msg; | ||
7322 | void *hdr; | ||
7323 | int err; | ||
7324 | u32 nlpid = ACCESS_ONCE(wdev->ap_unexpected_nlpid); | ||
7325 | |||
7326 | if (!nlpid) | ||
7327 | return false; | ||
7328 | |||
7329 | msg = nlmsg_new(100, gfp); | ||
7330 | if (!msg) | ||
7331 | return true; | ||
7332 | |||
7333 | hdr = nl80211hdr_put(msg, 0, 0, 0, cmd); | ||
7334 | if (!hdr) { | ||
7335 | nlmsg_free(msg); | ||
7336 | return true; | ||
7337 | } | ||
7338 | |||
7339 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | ||
7340 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); | ||
7341 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); | ||
7342 | |||
7343 | err = genlmsg_end(msg, hdr); | ||
7344 | if (err < 0) { | ||
7345 | nlmsg_free(msg); | ||
7346 | return true; | ||
7347 | } | ||
7348 | |||
7349 | genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid); | ||
7350 | return true; | ||
7351 | |||
7352 | nla_put_failure: | ||
7353 | genlmsg_cancel(msg, hdr); | ||
7354 | nlmsg_free(msg); | ||
7355 | return true; | ||
7356 | } | ||
7357 | |||
7358 | bool nl80211_unexpected_frame(struct net_device *dev, const u8 *addr, gfp_t gfp) | ||
7359 | { | ||
7360 | return __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME, | ||
7361 | addr, gfp); | ||
7362 | } | ||
7363 | |||
7364 | bool nl80211_unexpected_4addr_frame(struct net_device *dev, | ||
7365 | const u8 *addr, gfp_t gfp) | ||
7366 | { | ||
7367 | return __nl80211_unexpected_frame(dev, | ||
7368 | NL80211_CMD_UNEXPECTED_4ADDR_FRAME, | ||
7369 | addr, gfp); | ||
7370 | } | ||
7371 | |||
7210 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | 7372 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, |
7211 | struct net_device *netdev, u32 nlpid, | 7373 | struct net_device *netdev, u32 nlpid, |
7212 | int freq, const u8 *buf, size_t len, gfp_t gfp) | 7374 | int freq, const u8 *buf, size_t len, gfp_t gfp) |
7213 | { | 7375 | { |
7214 | struct sk_buff *msg; | 7376 | struct sk_buff *msg; |
7215 | void *hdr; | 7377 | void *hdr; |
7216 | int err; | ||
7217 | 7378 | ||
7218 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 7379 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
7219 | if (!msg) | 7380 | if (!msg) |
@@ -7230,16 +7391,9 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | |||
7230 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); | 7391 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); |
7231 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); | 7392 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); |
7232 | 7393 | ||
7233 | err = genlmsg_end(msg, hdr); | 7394 | genlmsg_end(msg, hdr); |
7234 | if (err < 0) { | ||
7235 | nlmsg_free(msg); | ||
7236 | return err; | ||
7237 | } | ||
7238 | 7395 | ||
7239 | err = genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid); | 7396 | return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid); |
7240 | if (err < 0) | ||
7241 | return err; | ||
7242 | return 0; | ||
7243 | 7397 | ||
7244 | nla_put_failure: | 7398 | nla_put_failure: |
7245 | genlmsg_cancel(msg, hdr); | 7399 | genlmsg_cancel(msg, hdr); |
@@ -7272,10 +7426,7 @@ void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, | |||
7272 | if (ack) | 7426 | if (ack) |
7273 | NLA_PUT_FLAG(msg, NL80211_ATTR_ACK); | 7427 | NLA_PUT_FLAG(msg, NL80211_ATTR_ACK); |
7274 | 7428 | ||
7275 | if (genlmsg_end(msg, hdr) < 0) { | 7429 | genlmsg_end(msg, hdr); |
7276 | nlmsg_free(msg); | ||
7277 | return; | ||
7278 | } | ||
7279 | 7430 | ||
7280 | genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); | 7431 | genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); |
7281 | return; | 7432 | return; |
@@ -7317,10 +7468,7 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev, | |||
7317 | 7468 | ||
7318 | nla_nest_end(msg, pinfoattr); | 7469 | nla_nest_end(msg, pinfoattr); |
7319 | 7470 | ||
7320 | if (genlmsg_end(msg, hdr) < 0) { | 7471 | genlmsg_end(msg, hdr); |
7321 | nlmsg_free(msg); | ||
7322 | return; | ||
7323 | } | ||
7324 | 7472 | ||
7325 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7473 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7326 | nl80211_mlme_mcgrp.id, gfp); | 7474 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7362,10 +7510,7 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, | |||
7362 | 7510 | ||
7363 | nla_nest_end(msg, rekey_attr); | 7511 | nla_nest_end(msg, rekey_attr); |
7364 | 7512 | ||
7365 | if (genlmsg_end(msg, hdr) < 0) { | 7513 | genlmsg_end(msg, hdr); |
7366 | nlmsg_free(msg); | ||
7367 | return; | ||
7368 | } | ||
7369 | 7514 | ||
7370 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7515 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7371 | nl80211_mlme_mcgrp.id, gfp); | 7516 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7408,10 +7553,7 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, | |||
7408 | 7553 | ||
7409 | nla_nest_end(msg, attr); | 7554 | nla_nest_end(msg, attr); |
7410 | 7555 | ||
7411 | if (genlmsg_end(msg, hdr) < 0) { | 7556 | genlmsg_end(msg, hdr); |
7412 | nlmsg_free(msg); | ||
7413 | return; | ||
7414 | } | ||
7415 | 7557 | ||
7416 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7558 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7417 | nl80211_mlme_mcgrp.id, gfp); | 7559 | nl80211_mlme_mcgrp.id, gfp); |
@@ -7453,7 +7595,45 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, | |||
7453 | 7595 | ||
7454 | nla_nest_end(msg, pinfoattr); | 7596 | nla_nest_end(msg, pinfoattr); |
7455 | 7597 | ||
7456 | if (genlmsg_end(msg, hdr) < 0) { | 7598 | genlmsg_end(msg, hdr); |
7599 | |||
7600 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | ||
7601 | nl80211_mlme_mcgrp.id, gfp); | ||
7602 | return; | ||
7603 | |||
7604 | nla_put_failure: | ||
7605 | genlmsg_cancel(msg, hdr); | ||
7606 | nlmsg_free(msg); | ||
7607 | } | ||
7608 | |||
7609 | void cfg80211_probe_status(struct net_device *dev, const u8 *addr, | ||
7610 | u64 cookie, bool acked, gfp_t gfp) | ||
7611 | { | ||
7612 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
7613 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
7614 | struct sk_buff *msg; | ||
7615 | void *hdr; | ||
7616 | int err; | ||
7617 | |||
7618 | msg = nlmsg_new(NLMSG_GOODSIZE, gfp); | ||
7619 | if (!msg) | ||
7620 | return; | ||
7621 | |||
7622 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT); | ||
7623 | if (!hdr) { | ||
7624 | nlmsg_free(msg); | ||
7625 | return; | ||
7626 | } | ||
7627 | |||
7628 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | ||
7629 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); | ||
7630 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); | ||
7631 | NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); | ||
7632 | if (acked) | ||
7633 | NLA_PUT_FLAG(msg, NL80211_ATTR_ACK); | ||
7634 | |||
7635 | err = genlmsg_end(msg, hdr); | ||
7636 | if (err < 0) { | ||
7457 | nlmsg_free(msg); | 7637 | nlmsg_free(msg); |
7458 | return; | 7638 | return; |
7459 | } | 7639 | } |
@@ -7466,6 +7646,45 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, | |||
7466 | genlmsg_cancel(msg, hdr); | 7646 | genlmsg_cancel(msg, hdr); |
7467 | nlmsg_free(msg); | 7647 | nlmsg_free(msg); |
7468 | } | 7648 | } |
7649 | EXPORT_SYMBOL(cfg80211_probe_status); | ||
7650 | |||
7651 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, | ||
7652 | const u8 *frame, size_t len, | ||
7653 | int freq, gfp_t gfp) | ||
7654 | { | ||
7655 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
7656 | struct sk_buff *msg; | ||
7657 | void *hdr; | ||
7658 | u32 nlpid = ACCESS_ONCE(rdev->ap_beacons_nlpid); | ||
7659 | |||
7660 | if (!nlpid) | ||
7661 | return; | ||
7662 | |||
7663 | msg = nlmsg_new(len + 100, gfp); | ||
7664 | if (!msg) | ||
7665 | return; | ||
7666 | |||
7667 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME); | ||
7668 | if (!hdr) { | ||
7669 | nlmsg_free(msg); | ||
7670 | return; | ||
7671 | } | ||
7672 | |||
7673 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | ||
7674 | if (freq) | ||
7675 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); | ||
7676 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame); | ||
7677 | |||
7678 | genlmsg_end(msg, hdr); | ||
7679 | |||
7680 | genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid); | ||
7681 | return; | ||
7682 | |||
7683 | nla_put_failure: | ||
7684 | genlmsg_cancel(msg, hdr); | ||
7685 | nlmsg_free(msg); | ||
7686 | } | ||
7687 | EXPORT_SYMBOL(cfg80211_report_obss_beacon); | ||
7469 | 7688 | ||
7470 | static int nl80211_netlink_notify(struct notifier_block * nb, | 7689 | static int nl80211_netlink_notify(struct notifier_block * nb, |
7471 | unsigned long state, | 7690 | unsigned long state, |
@@ -7480,9 +7699,12 @@ static int nl80211_netlink_notify(struct notifier_block * nb, | |||
7480 | 7699 | ||
7481 | rcu_read_lock(); | 7700 | rcu_read_lock(); |
7482 | 7701 | ||
7483 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) | 7702 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { |
7484 | list_for_each_entry_rcu(wdev, &rdev->netdev_list, list) | 7703 | list_for_each_entry_rcu(wdev, &rdev->netdev_list, list) |
7485 | cfg80211_mlme_unregister_socket(wdev, notify->pid); | 7704 | cfg80211_mlme_unregister_socket(wdev, notify->pid); |
7705 | if (rdev->ap_beacons_nlpid == notify->pid) | ||
7706 | rdev->ap_beacons_nlpid = 0; | ||
7707 | } | ||
7486 | 7708 | ||
7487 | rcu_read_unlock(); | 7709 | rcu_read_unlock(); |
7488 | 7710 | ||
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index f24a1fbeaf19..12bf4d185abe 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -117,4 +117,9 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, | |||
117 | struct net_device *netdev, int index, | 117 | struct net_device *netdev, int index, |
118 | const u8 *bssid, bool preauth, gfp_t gfp); | 118 | const u8 *bssid, bool preauth, gfp_t gfp); |
119 | 119 | ||
120 | bool nl80211_unexpected_frame(struct net_device *dev, | ||
121 | const u8 *addr, gfp_t gfp); | ||
122 | bool nl80211_unexpected_4addr_frame(struct net_device *dev, | ||
123 | const u8 *addr, gfp_t gfp); | ||
124 | |||
120 | #endif /* __NET_WIRELESS_NL80211_H */ | 125 | #endif /* __NET_WIRELESS_NL80211_H */ |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index dc23b31594e0..31119e32e092 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -355,8 +355,8 @@ static bool is_mesh(struct cfg80211_bss *a, | |||
355 | sizeof(struct ieee80211_meshconf_ie) - 2) == 0; | 355 | sizeof(struct ieee80211_meshconf_ie) - 2) == 0; |
356 | } | 356 | } |
357 | 357 | ||
358 | static int cmp_bss(struct cfg80211_bss *a, | 358 | static int cmp_bss_core(struct cfg80211_bss *a, |
359 | struct cfg80211_bss *b) | 359 | struct cfg80211_bss *b) |
360 | { | 360 | { |
361 | int r; | 361 | int r; |
362 | 362 | ||
@@ -378,7 +378,15 @@ static int cmp_bss(struct cfg80211_bss *a, | |||
378 | b->len_information_elements); | 378 | b->len_information_elements); |
379 | } | 379 | } |
380 | 380 | ||
381 | r = memcmp(a->bssid, b->bssid, ETH_ALEN); | 381 | return memcmp(a->bssid, b->bssid, ETH_ALEN); |
382 | } | ||
383 | |||
384 | static int cmp_bss(struct cfg80211_bss *a, | ||
385 | struct cfg80211_bss *b) | ||
386 | { | ||
387 | int r; | ||
388 | |||
389 | r = cmp_bss_core(a, b); | ||
382 | if (r) | 390 | if (r) |
383 | return r; | 391 | return r; |
384 | 392 | ||
@@ -389,6 +397,52 @@ static int cmp_bss(struct cfg80211_bss *a, | |||
389 | b->len_information_elements); | 397 | b->len_information_elements); |
390 | } | 398 | } |
391 | 399 | ||
400 | static int cmp_hidden_bss(struct cfg80211_bss *a, | ||
401 | struct cfg80211_bss *b) | ||
402 | { | ||
403 | const u8 *ie1; | ||
404 | const u8 *ie2; | ||
405 | int i; | ||
406 | int r; | ||
407 | |||
408 | r = cmp_bss_core(a, b); | ||
409 | if (r) | ||
410 | return r; | ||
411 | |||
412 | ie1 = cfg80211_find_ie(WLAN_EID_SSID, | ||
413 | a->information_elements, | ||
414 | a->len_information_elements); | ||
415 | ie2 = cfg80211_find_ie(WLAN_EID_SSID, | ||
416 | b->information_elements, | ||
417 | b->len_information_elements); | ||
418 | |||
419 | /* Key comparator must use same algorithm in any rb-tree | ||
420 | * search function (order is important), otherwise ordering | ||
421 | * of items in the tree is broken and search gives incorrect | ||
422 | * results. This code uses same order as cmp_ies() does. */ | ||
423 | |||
424 | /* sort missing IE before (left of) present IE */ | ||
425 | if (!ie1) | ||
426 | return -1; | ||
427 | if (!ie2) | ||
428 | return 1; | ||
429 | |||
430 | /* zero-size SSID is used as an indication of the hidden bss */ | ||
431 | if (!ie2[1]) | ||
432 | return 0; | ||
433 | |||
434 | /* sort by length first, then by contents */ | ||
435 | if (ie1[1] != ie2[1]) | ||
436 | return ie2[1] - ie1[1]; | ||
437 | |||
438 | /* zeroed SSID ie is another indication of a hidden bss */ | ||
439 | for (i = 0; i < ie2[1]; i++) | ||
440 | if (ie2[i + 2]) | ||
441 | return -1; | ||
442 | |||
443 | return 0; | ||
444 | } | ||
445 | |||
392 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, | 446 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, |
393 | struct ieee80211_channel *channel, | 447 | struct ieee80211_channel *channel, |
394 | const u8 *bssid, | 448 | const u8 *bssid, |
@@ -505,6 +559,48 @@ rb_find_bss(struct cfg80211_registered_device *dev, | |||
505 | } | 559 | } |
506 | 560 | ||
507 | static struct cfg80211_internal_bss * | 561 | static struct cfg80211_internal_bss * |
562 | rb_find_hidden_bss(struct cfg80211_registered_device *dev, | ||
563 | struct cfg80211_internal_bss *res) | ||
564 | { | ||
565 | struct rb_node *n = dev->bss_tree.rb_node; | ||
566 | struct cfg80211_internal_bss *bss; | ||
567 | int r; | ||
568 | |||
569 | while (n) { | ||
570 | bss = rb_entry(n, struct cfg80211_internal_bss, rbn); | ||
571 | r = cmp_hidden_bss(&res->pub, &bss->pub); | ||
572 | |||
573 | if (r == 0) | ||
574 | return bss; | ||
575 | else if (r < 0) | ||
576 | n = n->rb_left; | ||
577 | else | ||
578 | n = n->rb_right; | ||
579 | } | ||
580 | |||
581 | return NULL; | ||
582 | } | ||
583 | |||
584 | static void | ||
585 | copy_hidden_ies(struct cfg80211_internal_bss *res, | ||
586 | struct cfg80211_internal_bss *hidden) | ||
587 | { | ||
588 | if (unlikely(res->pub.beacon_ies)) | ||
589 | return; | ||
590 | if (WARN_ON(!hidden->pub.beacon_ies)) | ||
591 | return; | ||
592 | |||
593 | res->pub.beacon_ies = kmalloc(hidden->pub.len_beacon_ies, GFP_ATOMIC); | ||
594 | if (unlikely(!res->pub.beacon_ies)) | ||
595 | return; | ||
596 | |||
597 | res->beacon_ies_allocated = true; | ||
598 | res->pub.len_beacon_ies = hidden->pub.len_beacon_ies; | ||
599 | memcpy(res->pub.beacon_ies, hidden->pub.beacon_ies, | ||
600 | res->pub.len_beacon_ies); | ||
601 | } | ||
602 | |||
603 | static struct cfg80211_internal_bss * | ||
508 | cfg80211_bss_update(struct cfg80211_registered_device *dev, | 604 | cfg80211_bss_update(struct cfg80211_registered_device *dev, |
509 | struct cfg80211_internal_bss *res) | 605 | struct cfg80211_internal_bss *res) |
510 | { | 606 | { |
@@ -607,6 +703,21 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
607 | 703 | ||
608 | kref_put(&res->ref, bss_release); | 704 | kref_put(&res->ref, bss_release); |
609 | } else { | 705 | } else { |
706 | struct cfg80211_internal_bss *hidden; | ||
707 | |||
708 | /* First check if the beacon is a probe response from | ||
709 | * a hidden bss. If so, copy beacon ies (with nullified | ||
710 | * ssid) into the probe response bss entry (with real ssid). | ||
711 | * It is required basically for PSM implementation | ||
712 | * (probe responses do not contain tim ie) */ | ||
713 | |||
714 | /* TODO: The code is not trying to update existing probe | ||
715 | * response bss entries when beacon ies are | ||
716 | * getting changed. */ | ||
717 | hidden = rb_find_hidden_bss(dev, res); | ||
718 | if (hidden) | ||
719 | copy_hidden_ies(res, hidden); | ||
720 | |||
610 | /* this "consumes" the reference */ | 721 | /* this "consumes" the reference */ |
611 | list_add_tail(&res->list, &dev->bss_list); | 722 | list_add_tail(&res->list, &dev->bss_list); |
612 | rb_insert_bss(dev, res); | 723 | rb_insert_bss(dev, res); |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 6897436b1d3f..3c24eb97e9d7 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -819,12 +819,24 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, | |||
819 | struct iw_freq *freq, char *extra) | 819 | struct iw_freq *freq, char *extra) |
820 | { | 820 | { |
821 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 821 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
822 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
823 | struct ieee80211_channel *chan; | ||
822 | 824 | ||
823 | switch (wdev->iftype) { | 825 | switch (wdev->iftype) { |
824 | case NL80211_IFTYPE_STATION: | 826 | case NL80211_IFTYPE_STATION: |
825 | return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra); | 827 | return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra); |
826 | case NL80211_IFTYPE_ADHOC: | 828 | case NL80211_IFTYPE_ADHOC: |
827 | return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); | 829 | return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); |
830 | case NL80211_IFTYPE_MONITOR: | ||
831 | if (!rdev->ops->get_channel) | ||
832 | return -EINVAL; | ||
833 | |||
834 | chan = rdev->ops->get_channel(wdev->wiphy); | ||
835 | if (!chan) | ||
836 | return -EINVAL; | ||
837 | freq->m = chan->center_freq; | ||
838 | freq->e = 6; | ||
839 | return 0; | ||
828 | default: | 840 | default: |
829 | if (!wdev->channel) | 841 | if (!wdev->channel) |
830 | return -EINVAL; | 842 | return -EINVAL; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 2118d6446630..4fce1cec193e 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -61,8 +61,8 @@ __xfrm4_selector_match(const struct xfrm_selector *sel, const struct flowi *fl) | |||
61 | { | 61 | { |
62 | const struct flowi4 *fl4 = &fl->u.ip4; | 62 | const struct flowi4 *fl4 = &fl->u.ip4; |
63 | 63 | ||
64 | return addr_match(&fl4->daddr, &sel->daddr, sel->prefixlen_d) && | 64 | return addr4_match(fl4->daddr, sel->daddr.a4, sel->prefixlen_d) && |
65 | addr_match(&fl4->saddr, &sel->saddr, sel->prefixlen_s) && | 65 | addr4_match(fl4->saddr, sel->saddr.a4, sel->prefixlen_s) && |
66 | !((xfrm_flowi_dport(fl, &fl4->uli) ^ sel->dport) & sel->dport_mask) && | 66 | !((xfrm_flowi_dport(fl, &fl4->uli) ^ sel->dport) & sel->dport_mask) && |
67 | !((xfrm_flowi_sport(fl, &fl4->uli) ^ sel->sport) & sel->sport_mask) && | 67 | !((xfrm_flowi_sport(fl, &fl4->uli) ^ sel->sport) & sel->sport_mask) && |
68 | (fl4->flowi4_proto == sel->proto || !sel->proto) && | 68 | (fl4->flowi4_proto == sel->proto || !sel->proto) && |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 9414b9c5b1e4..5b228f97d4b3 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -1035,16 +1035,12 @@ static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_mark *m, | |||
1035 | break; | 1035 | break; |
1036 | 1036 | ||
1037 | case AF_INET6: | 1037 | case AF_INET6: |
1038 | ipv6_addr_copy((struct in6_addr *)x->sel.daddr.a6, | 1038 | *(struct in6_addr *)x->sel.daddr.a6 = *(struct in6_addr *)daddr; |
1039 | (const struct in6_addr *)daddr); | 1039 | *(struct in6_addr *)x->sel.saddr.a6 = *(struct in6_addr *)saddr; |
1040 | ipv6_addr_copy((struct in6_addr *)x->sel.saddr.a6, | ||
1041 | (const struct in6_addr *)saddr); | ||
1042 | x->sel.prefixlen_d = 128; | 1040 | x->sel.prefixlen_d = 128; |
1043 | x->sel.prefixlen_s = 128; | 1041 | x->sel.prefixlen_s = 128; |
1044 | ipv6_addr_copy((struct in6_addr *)x->props.saddr.a6, | 1042 | *(struct in6_addr *)x->props.saddr.a6 = *(struct in6_addr *)saddr; |
1045 | (const struct in6_addr *)saddr); | 1043 | *(struct in6_addr *)x->id.daddr.a6 = *(struct in6_addr *)daddr; |
1046 | ipv6_addr_copy((struct in6_addr *)x->id.daddr.a6, | ||
1047 | (const struct in6_addr *)daddr); | ||
1048 | break; | 1044 | break; |
1049 | } | 1045 | } |
1050 | 1046 | ||
diff --git a/security/lsm_audit.c b/security/lsm_audit.c index 893af8a2fa1e..199616bb68d3 100644 --- a/security/lsm_audit.c +++ b/security/lsm_audit.c | |||
@@ -118,8 +118,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, | |||
118 | ip6 = ipv6_hdr(skb); | 118 | ip6 = ipv6_hdr(skb); |
119 | if (ip6 == NULL) | 119 | if (ip6 == NULL) |
120 | return -EINVAL; | 120 | return -EINVAL; |
121 | ipv6_addr_copy(&ad->u.net.v6info.saddr, &ip6->saddr); | 121 | ad->u.net.v6info.saddr = ip6->saddr; |
122 | ipv6_addr_copy(&ad->u.net.v6info.daddr, &ip6->daddr); | 122 | ad->u.net.v6info.daddr = ip6->daddr; |
123 | ret = 0; | 123 | ret = 0; |
124 | /* IPv6 can have several extension header before the Transport header | 124 | /* IPv6 can have several extension header before the Transport header |
125 | * skip them */ | 125 | * skip them */ |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 1126c10a5e82..7e6c2564e741 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -3567,8 +3567,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, | |||
3567 | if (ip6 == NULL) | 3567 | if (ip6 == NULL) |
3568 | goto out; | 3568 | goto out; |
3569 | 3569 | ||
3570 | ipv6_addr_copy(&ad->u.net.v6info.saddr, &ip6->saddr); | 3570 | ad->u.net.v6info.saddr = ip6->saddr; |
3571 | ipv6_addr_copy(&ad->u.net.v6info.daddr, &ip6->daddr); | 3571 | ad->u.net.v6info.daddr = ip6->daddr; |
3572 | ret = 0; | 3572 | ret = 0; |
3573 | 3573 | ||
3574 | nexthdr = ip6->nexthdr; | 3574 | nexthdr = ip6->nexthdr; |
@@ -3871,7 +3871,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3871 | if (family == PF_INET) | 3871 | if (family == PF_INET) |
3872 | ad.u.net.v4info.saddr = addr4->sin_addr.s_addr; | 3872 | ad.u.net.v4info.saddr = addr4->sin_addr.s_addr; |
3873 | else | 3873 | else |
3874 | ipv6_addr_copy(&ad.u.net.v6info.saddr, &addr6->sin6_addr); | 3874 | ad.u.net.v6info.saddr = addr6->sin6_addr; |
3875 | 3875 | ||
3876 | err = avc_has_perm(sksec->sid, sid, | 3876 | err = avc_has_perm(sksec->sid, sid, |
3877 | sksec->sclass, node_perm, &ad); | 3877 | sksec->sclass, node_perm, &ad); |
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c index 3bf46abaa688..86365857c088 100644 --- a/security/selinux/netnode.c +++ b/security/selinux/netnode.c | |||
@@ -220,7 +220,7 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) | |||
220 | case PF_INET6: | 220 | case PF_INET6: |
221 | ret = security_node_sid(PF_INET6, | 221 | ret = security_node_sid(PF_INET6, |
222 | addr, sizeof(struct in6_addr), sid); | 222 | addr, sizeof(struct in6_addr), sid); |
223 | ipv6_addr_copy(&new->nsec.addr.ipv6, addr); | 223 | new->nsec.addr.ipv6 = *(struct in6_addr *)addr; |
224 | break; | 224 | break; |
225 | default: | 225 | default: |
226 | BUG(); | 226 | BUG(); |