diff options
184 files changed, 5977 insertions, 2123 deletions
diff --git a/Documentation/isdn/INTERFACE.CAPI b/Documentation/isdn/INTERFACE.CAPI index 786d619b36e5..686e107923ec 100644 --- a/Documentation/isdn/INTERFACE.CAPI +++ b/Documentation/isdn/INTERFACE.CAPI | |||
@@ -45,7 +45,7 @@ From then on, Kernel CAPI may call the registered callback functions for the | |||
45 | device. | 45 | device. |
46 | 46 | ||
47 | If the device becomes unusable for any reason (shutdown, disconnect ...), the | 47 | If the device becomes unusable for any reason (shutdown, disconnect ...), the |
48 | driver has to call capi_ctr_reseted(). This will prevent further calls to the | 48 | driver has to call capi_ctr_down(). This will prevent further calls to the |
49 | callback functions by Kernel CAPI. | 49 | callback functions by Kernel CAPI. |
50 | 50 | ||
51 | 51 | ||
@@ -114,20 +114,36 @@ char *driver_name | |||
114 | int (*load_firmware)(struct capi_ctr *ctrlr, capiloaddata *ldata) | 114 | int (*load_firmware)(struct capi_ctr *ctrlr, capiloaddata *ldata) |
115 | (optional) pointer to a callback function for sending firmware and | 115 | (optional) pointer to a callback function for sending firmware and |
116 | configuration data to the device | 116 | configuration data to the device |
117 | Return value: 0 on success, error code on error | ||
118 | Called in process context. | ||
117 | 119 | ||
118 | void (*reset_ctr)(struct capi_ctr *ctrlr) | 120 | void (*reset_ctr)(struct capi_ctr *ctrlr) |
119 | pointer to a callback function for performing a reset on the device, | 121 | (optional) pointer to a callback function for performing a reset on |
120 | releasing all registered applications | 122 | the device, releasing all registered applications |
123 | Called in process context. | ||
121 | 124 | ||
122 | void (*register_appl)(struct capi_ctr *ctrlr, u16 applid, | 125 | void (*register_appl)(struct capi_ctr *ctrlr, u16 applid, |
123 | capi_register_params *rparam) | 126 | capi_register_params *rparam) |
124 | void (*release_appl)(struct capi_ctr *ctrlr, u16 applid) | 127 | void (*release_appl)(struct capi_ctr *ctrlr, u16 applid) |
125 | pointers to callback functions for registration and deregistration of | 128 | pointers to callback functions for registration and deregistration of |
126 | applications with the device | 129 | applications with the device |
130 | Calls to these functions are serialized by Kernel CAPI so that only | ||
131 | one call to any of them is active at any time. | ||
127 | 132 | ||
128 | u16 (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb) | 133 | u16 (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb) |
129 | pointer to a callback function for sending a CAPI message to the | 134 | pointer to a callback function for sending a CAPI message to the |
130 | device | 135 | device |
136 | Return value: CAPI error code | ||
137 | If the method returns 0 (CAPI_NOERROR) the driver has taken ownership | ||
138 | of the skb and the caller may no longer access it. If it returns a | ||
139 | non-zero (error) value then ownership of the skb returns to the caller | ||
140 | who may reuse or free it. | ||
141 | The return value should only be used to signal problems with respect | ||
142 | to accepting or queueing the message. Errors occurring during the | ||
143 | actual processing of the message should be signaled with an | ||
144 | appropriate reply message. | ||
145 | Calls to this function are not serialized by Kernel CAPI, ie. it must | ||
146 | be prepared to be re-entered. | ||
131 | 147 | ||
132 | char *(*procinfo)(struct capi_ctr *ctrlr) | 148 | char *(*procinfo)(struct capi_ctr *ctrlr) |
133 | pointer to a callback function returning the entry for the device in | 149 | pointer to a callback function returning the entry for the device in |
@@ -138,6 +154,8 @@ read_proc_t *ctr_read_proc | |||
138 | system entry, /proc/capi/controllers/<n>; will be called with a | 154 | system entry, /proc/capi/controllers/<n>; will be called with a |
139 | pointer to the device's capi_ctr structure as the last (data) argument | 155 | pointer to the device's capi_ctr structure as the last (data) argument |
140 | 156 | ||
157 | Note: Callback functions are never called in interrupt context. | ||
158 | |||
141 | - to be filled in before calling capi_ctr_ready(): | 159 | - to be filled in before calling capi_ctr_ready(): |
142 | 160 | ||
143 | u8 manu[CAPI_MANUFACTURER_LEN] | 161 | u8 manu[CAPI_MANUFACTURER_LEN] |
@@ -153,6 +171,45 @@ u8 serial[CAPI_SERIAL_LEN] | |||
153 | value to return for CAPI_GET_SERIAL | 171 | value to return for CAPI_GET_SERIAL |
154 | 172 | ||
155 | 173 | ||
174 | 4.3 The _cmsg Structure | ||
175 | |||
176 | (declared in <linux/isdn/capiutil.h>) | ||
177 | |||
178 | The _cmsg structure stores the contents of a CAPI 2.0 message in an easily | ||
179 | accessible form. It contains members for all possible CAPI 2.0 parameters, of | ||
180 | which only those appearing in the message type currently being processed are | ||
181 | actually used. Unused members should be set to zero. | ||
182 | |||
183 | Members are named after the CAPI 2.0 standard names of the parameters they | ||
184 | represent. See <linux/isdn/capiutil.h> for the exact spelling. Member data | ||
185 | types are: | ||
186 | |||
187 | u8 for CAPI parameters of type 'byte' | ||
188 | |||
189 | u16 for CAPI parameters of type 'word' | ||
190 | |||
191 | u32 for CAPI parameters of type 'dword' | ||
192 | |||
193 | _cstruct for CAPI parameters of type 'struct' not containing any | ||
194 | variably-sized (struct) subparameters (eg. 'Called Party Number') | ||
195 | The member is a pointer to a buffer containing the parameter in | ||
196 | CAPI encoding (length + content). It may also be NULL, which will | ||
197 | be taken to represent an empty (zero length) parameter. | ||
198 | |||
199 | _cmstruct for CAPI parameters of type 'struct' containing 'struct' | ||
200 | subparameters ('Additional Info' and 'B Protocol') | ||
201 | The representation is a single byte containing one of the values: | ||
202 | CAPI_DEFAULT: the parameter is empty | ||
203 | CAPI_COMPOSE: the values of the subparameters are stored | ||
204 | individually in the corresponding _cmsg structure members | ||
205 | |||
206 | Functions capi_cmsg2message() and capi_message2cmsg() are provided to convert | ||
207 | messages between their transport encoding described in the CAPI 2.0 standard | ||
208 | and their _cmsg structure representation. Note that capi_cmsg2message() does | ||
209 | not know or check the size of its destination buffer. The caller must make | ||
210 | sure it is big enough to accomodate the resulting CAPI message. | ||
211 | |||
212 | |||
156 | 5. Lower Layer Interface Functions | 213 | 5. Lower Layer Interface Functions |
157 | 214 | ||
158 | (declared in <linux/isdn/capilli.h>) | 215 | (declared in <linux/isdn/capilli.h>) |
@@ -166,7 +223,7 @@ int detach_capi_ctr(struct capi_ctr *ctrlr) | |||
166 | register/unregister a device (controller) with Kernel CAPI | 223 | register/unregister a device (controller) with Kernel CAPI |
167 | 224 | ||
168 | void capi_ctr_ready(struct capi_ctr *ctrlr) | 225 | void capi_ctr_ready(struct capi_ctr *ctrlr) |
169 | void capi_ctr_reseted(struct capi_ctr *ctrlr) | 226 | void capi_ctr_down(struct capi_ctr *ctrlr) |
170 | signal controller ready/not ready | 227 | signal controller ready/not ready |
171 | 228 | ||
172 | void capi_ctr_suspend_output(struct capi_ctr *ctrlr) | 229 | void capi_ctr_suspend_output(struct capi_ctr *ctrlr) |
@@ -211,3 +268,32 @@ CAPIMSG_CONTROL(m) CAPIMSG_SETCONTROL(m, contr) Controller/PLCI/NCCI | |||
211 | (u32) | 268 | (u32) |
212 | CAPIMSG_DATALEN(m) CAPIMSG_SETDATALEN(m, len) Data Length (u16) | 269 | CAPIMSG_DATALEN(m) CAPIMSG_SETDATALEN(m, len) Data Length (u16) |
213 | 270 | ||
271 | |||
272 | Library functions for working with _cmsg structures | ||
273 | (from <linux/isdn/capiutil.h>): | ||
274 | |||
275 | unsigned capi_cmsg2message(_cmsg *cmsg, u8 *msg) | ||
276 | Assembles a CAPI 2.0 message from the parameters in *cmsg, storing the | ||
277 | result in *msg. | ||
278 | |||
279 | unsigned capi_message2cmsg(_cmsg *cmsg, u8 *msg) | ||
280 | Disassembles the CAPI 2.0 message in *msg, storing the parameters in | ||
281 | *cmsg. | ||
282 | |||
283 | unsigned capi_cmsg_header(_cmsg *cmsg, u16 ApplId, u8 Command, u8 Subcommand, | ||
284 | u16 Messagenumber, u32 Controller) | ||
285 | Fills the header part and address field of the _cmsg structure *cmsg | ||
286 | with the given values, zeroing the remainder of the structure so only | ||
287 | parameters with non-default values need to be changed before sending | ||
288 | the message. | ||
289 | |||
290 | void capi_cmsg_answer(_cmsg *cmsg) | ||
291 | Sets the low bit of the Subcommand field in *cmsg, thereby converting | ||
292 | _REQ to _CONF and _IND to _RESP. | ||
293 | |||
294 | char *capi_cmd2str(u8 Command, u8 Subcommand) | ||
295 | Returns the CAPI 2.0 message name corresponding to the given command | ||
296 | and subcommand values, as a static ASCII string. The return value may | ||
297 | be NULL if the command/subcommand is not one of those defined in the | ||
298 | CAPI 2.0 standard. | ||
299 | |||
diff --git a/Documentation/networking/ieee802154.txt b/Documentation/networking/ieee802154.txt new file mode 100644 index 000000000000..a0280ad2edc9 --- /dev/null +++ b/Documentation/networking/ieee802154.txt | |||
@@ -0,0 +1,76 @@ | |||
1 | |||
2 | Linux IEEE 802.15.4 implementation | ||
3 | |||
4 | |||
5 | Introduction | ||
6 | ============ | ||
7 | |||
8 | The Linux-ZigBee project goal is to provide complete implementation | ||
9 | of IEEE 802.15.4 / ZigBee / 6LoWPAN protocols. IEEE 802.15.4 is a stack | ||
10 | of protocols for organizing Low-Rate Wireless Personal Area Networks. | ||
11 | |||
12 | Currently only IEEE 802.15.4 layer is implemented. We have choosen | ||
13 | to use plain Berkeley socket API, the generic Linux networking stack | ||
14 | to transfer IEEE 802.15.4 messages and a special protocol over genetlink | ||
15 | for configuration/management | ||
16 | |||
17 | |||
18 | Socket API | ||
19 | ========== | ||
20 | |||
21 | int sd = socket(PF_IEEE802154, SOCK_DGRAM, 0); | ||
22 | ..... | ||
23 | |||
24 | The address family, socket addresses etc. are defined in the | ||
25 | include/net/ieee802154/af_ieee802154.h header or in the special header | ||
26 | in our userspace package (see either linux-zigbee sourceforge download page | ||
27 | or git tree at git://linux-zigbee.git.sourceforge.net/gitroot/linux-zigbee). | ||
28 | |||
29 | One can use SOCK_RAW for passing raw data towards device xmit function. YMMV. | ||
30 | |||
31 | |||
32 | MLME - MAC Level Management | ||
33 | ============================ | ||
34 | |||
35 | Most of IEEE 802.15.4 MLME interfaces are directly mapped on netlink commands. | ||
36 | See the include/net/ieee802154/nl802154.h header. Our userspace tools package | ||
37 | (see above) provides CLI configuration utility for radio interfaces and simple | ||
38 | coordinator for IEEE 802.15.4 networks as an example users of MLME protocol. | ||
39 | |||
40 | |||
41 | Kernel side | ||
42 | ============= | ||
43 | |||
44 | Like with WiFi, there are several types of devices implementing IEEE 802.15.4. | ||
45 | 1) 'HardMAC'. The MAC layer is implemented in the device itself, the device | ||
46 | exports MLME and data API. | ||
47 | 2) 'SoftMAC' or just radio. These types of devices are just radio transceivers | ||
48 | possibly with some kinds of acceleration like automatic CRC computation and | ||
49 | comparation, automagic ACK handling, address matching, etc. | ||
50 | |||
51 | Those types of devices require different approach to be hooked into Linux kernel. | ||
52 | |||
53 | |||
54 | HardMAC | ||
55 | ======= | ||
56 | |||
57 | See the header include/net/ieee802154/netdevice.h. You have to implement Linux | ||
58 | net_device, with .type = ARPHRD_IEEE802154. Data is exchanged with socket family | ||
59 | code via plain sk_buffs. The control block of sk_buffs will contain additional | ||
60 | info as described in the struct ieee802154_mac_cb. | ||
61 | |||
62 | To hook the MLME interface you have to populate the ml_priv field of your | ||
63 | net_device with a pointer to struct ieee802154_mlme_ops instance. All fields are | ||
64 | required. | ||
65 | |||
66 | We provide an example of simple HardMAC driver at drivers/ieee802154/fakehard.c | ||
67 | |||
68 | |||
69 | SoftMAC | ||
70 | ======= | ||
71 | |||
72 | We are going to provide intermediate layer impelementing IEEE 802.15.4 MAC | ||
73 | in software. This is currently WIP. | ||
74 | |||
75 | See header include/net/ieee802154/mac802154.h and several drivers in | ||
76 | drivers/ieee802154/ | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 2f6a8fcfb1f2..a6df68fad9ba 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2819,6 +2819,18 @@ L: linux1394-devel@lists.sourceforge.net | |||
2819 | S: Maintained | 2819 | S: Maintained |
2820 | F: drivers/ieee1394/raw1394* | 2820 | F: drivers/ieee1394/raw1394* |
2821 | 2821 | ||
2822 | IEEE 802.15.4 SUBSYSTEM | ||
2823 | P: Dmitry Eremin-Solenikov | ||
2824 | M: dbaryshkov@gmail.com | ||
2825 | P: Sergey Lapin | ||
2826 | M: slapin@ossfans.org | ||
2827 | L: linux-zigbee-devel@lists.sourceforge.net | ||
2828 | W: http://apps.sourceforge.net/trac/linux-zigbee | ||
2829 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lumag/lowpan.git | ||
2830 | S: Maintained | ||
2831 | F: net/ieee802154/ | ||
2832 | F: drivers/ieee801254/ | ||
2833 | |||
2822 | INTEGRITY MEASUREMENT ARCHITECTURE (IMA) | 2834 | INTEGRITY MEASUREMENT ARCHITECTURE (IMA) |
2823 | P: Mimi Zohar | 2835 | P: Mimi Zohar |
2824 | M: zohar@us.ibm.com | 2836 | M: zohar@us.ibm.com |
diff --git a/drivers/Makefile b/drivers/Makefile index 1266ead6ace0..9e7d4e56c85b 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -107,3 +107,4 @@ obj-$(CONFIG_SSB) += ssb/ | |||
107 | obj-$(CONFIG_VIRTIO) += virtio/ | 107 | obj-$(CONFIG_VIRTIO) += virtio/ |
108 | obj-$(CONFIG_STAGING) += staging/ | 108 | obj-$(CONFIG_STAGING) += staging/ |
109 | obj-y += platform/ | 109 | obj-y += platform/ |
110 | obj-y += ieee802154/ | ||
diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig new file mode 100644 index 000000000000..25740bd54975 --- /dev/null +++ b/drivers/ieee802154/Kconfig | |||
@@ -0,0 +1,22 @@ | |||
1 | menuconfig IEEE802154_DRIVERS | ||
2 | bool "IEEE 802.15.4 drivers" | ||
3 | depends on NETDEVICES && IEEE802154 | ||
4 | default y | ||
5 | ---help--- | ||
6 | Say Y here to get to see options for IEEE 802.15.4 Low-Rate | ||
7 | Wireless Personal Area Network device drivers. This option alone | ||
8 | does not add any kernel code. | ||
9 | |||
10 | If you say N, all options in this submenu will be skipped and | ||
11 | disabled. | ||
12 | |||
13 | config IEEE802154_FAKEHARD | ||
14 | tristate "Fake LR-WPAN driver with several interconnected devices" | ||
15 | depends on IEEE802154_DRIVERS | ||
16 | ---help--- | ||
17 | Say Y here to enable the fake driver that serves as an example | ||
18 | of HardMAC device driver. | ||
19 | |||
20 | This driver can also be built as a module. To do so say M here. | ||
21 | The module will be called 'fakehard'. | ||
22 | |||
diff --git a/drivers/ieee802154/Makefile b/drivers/ieee802154/Makefile new file mode 100644 index 000000000000..e0e8e1a184ff --- /dev/null +++ b/drivers/ieee802154/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o | ||
2 | |||
3 | EXTRA_CFLAGS += -DDEBUG -DCONFIG_FFD | ||
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c new file mode 100644 index 000000000000..0384144c0b34 --- /dev/null +++ b/drivers/ieee802154/fakehard.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | * Sample driver for HardMAC IEEE 802.15.4 devices | ||
3 | * | ||
4 | * Copyright (C) 2009 Siemens AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | * | ||
19 | * Written by: | ||
20 | * Dmitry Eremin-Solenikov <dmitry.baryshkov@siemens.com> | ||
21 | */ | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/netdevice.h> | ||
26 | #include <linux/skbuff.h> | ||
27 | #include <linux/if_arp.h> | ||
28 | |||
29 | #include <net/ieee802154/af_ieee802154.h> | ||
30 | #include <net/ieee802154/netdevice.h> | ||
31 | #include <net/ieee802154/mac_def.h> | ||
32 | #include <net/ieee802154/nl802154.h> | ||
33 | |||
34 | static u16 fake_get_pan_id(struct net_device *dev) | ||
35 | { | ||
36 | BUG_ON(dev->type != ARPHRD_IEEE802154); | ||
37 | |||
38 | return 0xeba1; | ||
39 | } | ||
40 | |||
41 | static u16 fake_get_short_addr(struct net_device *dev) | ||
42 | { | ||
43 | BUG_ON(dev->type != ARPHRD_IEEE802154); | ||
44 | |||
45 | return 0x1; | ||
46 | } | ||
47 | |||
48 | static u8 fake_get_dsn(struct net_device *dev) | ||
49 | { | ||
50 | BUG_ON(dev->type != ARPHRD_IEEE802154); | ||
51 | |||
52 | return 0x00; /* DSN are implemented in HW, so return just 0 */ | ||
53 | } | ||
54 | |||
55 | static u8 fake_get_bsn(struct net_device *dev) | ||
56 | { | ||
57 | BUG_ON(dev->type != ARPHRD_IEEE802154); | ||
58 | |||
59 | return 0x00; /* BSN are implemented in HW, so return just 0 */ | ||
60 | } | ||
61 | |||
62 | static int fake_assoc_req(struct net_device *dev, | ||
63 | struct ieee802154_addr *addr, u8 channel, u8 cap) | ||
64 | { | ||
65 | /* We simply emulate it here */ | ||
66 | return ieee802154_nl_assoc_confirm(dev, fake_get_short_addr(dev), | ||
67 | IEEE802154_SUCCESS); | ||
68 | } | ||
69 | |||
70 | static int fake_assoc_resp(struct net_device *dev, | ||
71 | struct ieee802154_addr *addr, u16 short_addr, u8 status) | ||
72 | { | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static int fake_disassoc_req(struct net_device *dev, | ||
77 | struct ieee802154_addr *addr, u8 reason) | ||
78 | { | ||
79 | return ieee802154_nl_disassoc_confirm(dev, IEEE802154_SUCCESS); | ||
80 | } | ||
81 | |||
82 | static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr, | ||
83 | u8 channel, | ||
84 | u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx, | ||
85 | u8 coord_realign) | ||
86 | { | ||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static int fake_scan_req(struct net_device *dev, u8 type, u32 channels, | ||
91 | u8 duration) | ||
92 | { | ||
93 | u8 edl[27] = {}; | ||
94 | return ieee802154_nl_scan_confirm(dev, IEEE802154_SUCCESS, type, | ||
95 | channels, | ||
96 | type == IEEE802154_MAC_SCAN_ED ? edl : NULL); | ||
97 | } | ||
98 | |||
99 | static struct ieee802154_mlme_ops fake_mlme = { | ||
100 | .assoc_req = fake_assoc_req, | ||
101 | .assoc_resp = fake_assoc_resp, | ||
102 | .disassoc_req = fake_disassoc_req, | ||
103 | .start_req = fake_start_req, | ||
104 | .scan_req = fake_scan_req, | ||
105 | |||
106 | .get_pan_id = fake_get_pan_id, | ||
107 | .get_short_addr = fake_get_short_addr, | ||
108 | .get_dsn = fake_get_dsn, | ||
109 | .get_bsn = fake_get_bsn, | ||
110 | }; | ||
111 | |||
112 | static int ieee802154_fake_open(struct net_device *dev) | ||
113 | { | ||
114 | netif_start_queue(dev); | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int ieee802154_fake_close(struct net_device *dev) | ||
119 | { | ||
120 | netif_stop_queue(dev); | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static int ieee802154_fake_xmit(struct sk_buff *skb, struct net_device *dev) | ||
125 | { | ||
126 | skb->iif = dev->ifindex; | ||
127 | skb->dev = dev; | ||
128 | dev->stats.tx_packets++; | ||
129 | dev->stats.tx_bytes += skb->len; | ||
130 | |||
131 | dev->trans_start = jiffies; | ||
132 | |||
133 | /* FIXME: do hardware work here ... */ | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | |||
139 | static int ieee802154_fake_ioctl(struct net_device *dev, struct ifreq *ifr, | ||
140 | int cmd) | ||
141 | { | ||
142 | struct sockaddr_ieee802154 *sa = | ||
143 | (struct sockaddr_ieee802154 *)&ifr->ifr_addr; | ||
144 | u16 pan_id, short_addr; | ||
145 | |||
146 | switch (cmd) { | ||
147 | case SIOCGIFADDR: | ||
148 | /* FIXME: fixed here, get from device IRL */ | ||
149 | pan_id = fake_get_pan_id(dev); | ||
150 | short_addr = fake_get_short_addr(dev); | ||
151 | if (pan_id == IEEE802154_PANID_BROADCAST || | ||
152 | short_addr == IEEE802154_ADDR_BROADCAST) | ||
153 | return -EADDRNOTAVAIL; | ||
154 | |||
155 | sa->family = AF_IEEE802154; | ||
156 | sa->addr.addr_type = IEEE802154_ADDR_SHORT; | ||
157 | sa->addr.pan_id = pan_id; | ||
158 | sa->addr.short_addr = short_addr; | ||
159 | return 0; | ||
160 | } | ||
161 | return -ENOIOCTLCMD; | ||
162 | } | ||
163 | |||
164 | static int ieee802154_fake_mac_addr(struct net_device *dev, void *p) | ||
165 | { | ||
166 | return -EBUSY; /* HW address is built into the device */ | ||
167 | } | ||
168 | |||
169 | static const struct net_device_ops fake_ops = { | ||
170 | .ndo_open = ieee802154_fake_open, | ||
171 | .ndo_stop = ieee802154_fake_close, | ||
172 | .ndo_start_xmit = ieee802154_fake_xmit, | ||
173 | .ndo_do_ioctl = ieee802154_fake_ioctl, | ||
174 | .ndo_set_mac_address = ieee802154_fake_mac_addr, | ||
175 | }; | ||
176 | |||
177 | |||
178 | static void ieee802154_fake_setup(struct net_device *dev) | ||
179 | { | ||
180 | dev->addr_len = IEEE802154_ADDR_LEN; | ||
181 | memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); | ||
182 | dev->features = NETIF_F_NO_CSUM; | ||
183 | dev->needed_tailroom = 2; /* FCS */ | ||
184 | dev->mtu = 127; | ||
185 | dev->tx_queue_len = 10; | ||
186 | dev->type = ARPHRD_IEEE802154; | ||
187 | dev->flags = IFF_NOARP | IFF_BROADCAST; | ||
188 | dev->watchdog_timeo = 0; | ||
189 | } | ||
190 | |||
191 | |||
192 | static int __devinit ieee802154fake_probe(struct platform_device *pdev) | ||
193 | { | ||
194 | struct net_device *dev = | ||
195 | alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup); | ||
196 | int err; | ||
197 | |||
198 | if (!dev) | ||
199 | return -ENOMEM; | ||
200 | |||
201 | memcpy(dev->dev_addr, "\xba\xbe\xca\xfe\xde\xad\xbe\xef", | ||
202 | dev->addr_len); | ||
203 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | ||
204 | |||
205 | dev->netdev_ops = &fake_ops; | ||
206 | dev->ml_priv = &fake_mlme; | ||
207 | |||
208 | /* | ||
209 | * If the name is a format string the caller wants us to do a | ||
210 | * name allocation. | ||
211 | */ | ||
212 | if (strchr(dev->name, '%')) { | ||
213 | err = dev_alloc_name(dev, dev->name); | ||
214 | if (err < 0) | ||
215 | goto out; | ||
216 | } | ||
217 | |||
218 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
219 | |||
220 | platform_set_drvdata(pdev, dev); | ||
221 | |||
222 | err = register_netdev(dev); | ||
223 | if (err < 0) | ||
224 | goto out; | ||
225 | |||
226 | |||
227 | dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n"); | ||
228 | return 0; | ||
229 | |||
230 | out: | ||
231 | unregister_netdev(dev); | ||
232 | return err; | ||
233 | } | ||
234 | |||
235 | static int __devexit ieee802154fake_remove(struct platform_device *pdev) | ||
236 | { | ||
237 | struct net_device *dev = platform_get_drvdata(pdev); | ||
238 | unregister_netdev(dev); | ||
239 | free_netdev(dev); | ||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | static struct platform_device *ieee802154fake_dev; | ||
244 | |||
245 | static struct platform_driver ieee802154fake_driver = { | ||
246 | .probe = ieee802154fake_probe, | ||
247 | .remove = __devexit_p(ieee802154fake_remove), | ||
248 | .driver = { | ||
249 | .name = "ieee802154hardmac", | ||
250 | .owner = THIS_MODULE, | ||
251 | }, | ||
252 | }; | ||
253 | |||
254 | static __init int fake_init(void) | ||
255 | { | ||
256 | ieee802154fake_dev = platform_device_register_simple( | ||
257 | "ieee802154hardmac", -1, NULL, 0); | ||
258 | return platform_driver_register(&ieee802154fake_driver); | ||
259 | } | ||
260 | |||
261 | static __exit void fake_exit(void) | ||
262 | { | ||
263 | platform_driver_unregister(&ieee802154fake_driver); | ||
264 | platform_device_unregister(ieee802154fake_dev); | ||
265 | } | ||
266 | |||
267 | module_init(fake_init); | ||
268 | module_exit(fake_exit); | ||
269 | MODULE_LICENSE("GPL"); | ||
270 | |||
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c index 29419a8d31dc..16f2e465e5f9 100644 --- a/drivers/isdn/capi/capiutil.c +++ b/drivers/isdn/capi/capiutil.c | |||
@@ -490,7 +490,14 @@ static void pars_2_message(_cmsg * cmsg) | |||
490 | } | 490 | } |
491 | } | 491 | } |
492 | 492 | ||
493 | /*-------------------------------------------------------*/ | 493 | /** |
494 | * capi_cmsg2message() - assemble CAPI 2.0 message from _cmsg structure | ||
495 | * @cmsg: _cmsg structure | ||
496 | * @msg: buffer for assembled message | ||
497 | * | ||
498 | * Return value: 0 for success | ||
499 | */ | ||
500 | |||
494 | unsigned capi_cmsg2message(_cmsg * cmsg, u8 * msg) | 501 | unsigned capi_cmsg2message(_cmsg * cmsg, u8 * msg) |
495 | { | 502 | { |
496 | cmsg->m = msg; | 503 | cmsg->m = msg; |
@@ -553,7 +560,14 @@ static void message_2_pars(_cmsg * cmsg) | |||
553 | } | 560 | } |
554 | } | 561 | } |
555 | 562 | ||
556 | /*-------------------------------------------------------*/ | 563 | /** |
564 | * capi_message2cmsg() - disassemble CAPI 2.0 message into _cmsg structure | ||
565 | * @cmsg: _cmsg structure | ||
566 | * @msg: buffer for assembled message | ||
567 | * | ||
568 | * Return value: 0 for success | ||
569 | */ | ||
570 | |||
557 | unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg) | 571 | unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg) |
558 | { | 572 | { |
559 | memset(cmsg, 0, sizeof(_cmsg)); | 573 | memset(cmsg, 0, sizeof(_cmsg)); |
@@ -573,7 +587,18 @@ unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg) | |||
573 | return 0; | 587 | return 0; |
574 | } | 588 | } |
575 | 589 | ||
576 | /*-------------------------------------------------------*/ | 590 | /** |
591 | * capi_cmsg_header() - initialize header part of _cmsg structure | ||
592 | * @cmsg: _cmsg structure | ||
593 | * @_ApplId: ApplID field value | ||
594 | * @_Command: Command field value | ||
595 | * @_Subcommand: Subcommand field value | ||
596 | * @_Messagenumber: Message Number field value | ||
597 | * @_Controller: Controller/PLCI/NCCI field value | ||
598 | * | ||
599 | * Return value: 0 for success | ||
600 | */ | ||
601 | |||
577 | unsigned capi_cmsg_header(_cmsg * cmsg, u16 _ApplId, | 602 | unsigned capi_cmsg_header(_cmsg * cmsg, u16 _ApplId, |
578 | u8 _Command, u8 _Subcommand, | 603 | u8 _Command, u8 _Subcommand, |
579 | u16 _Messagenumber, u32 _Controller) | 604 | u16 _Messagenumber, u32 _Controller) |
@@ -641,6 +666,14 @@ static char *mnames[] = | |||
641 | [0x4e] = "MANUFACTURER_RESP" | 666 | [0x4e] = "MANUFACTURER_RESP" |
642 | }; | 667 | }; |
643 | 668 | ||
669 | /** | ||
670 | * capi_cmd2str() - convert CAPI 2.0 command/subcommand number to name | ||
671 | * @cmd: command number | ||
672 | * @subcmd: subcommand number | ||
673 | * | ||
674 | * Return value: static string, NULL if command/subcommand unknown | ||
675 | */ | ||
676 | |||
644 | char *capi_cmd2str(u8 cmd, u8 subcmd) | 677 | char *capi_cmd2str(u8 cmd, u8 subcmd) |
645 | { | 678 | { |
646 | return mnames[command_2_index(cmd, subcmd)]; | 679 | return mnames[command_2_index(cmd, subcmd)]; |
@@ -879,6 +912,11 @@ init: | |||
879 | return cdb; | 912 | return cdb; |
880 | } | 913 | } |
881 | 914 | ||
915 | /** | ||
916 | * cdebbuf_free() - free CAPI debug buffer | ||
917 | * @cdb: buffer to free | ||
918 | */ | ||
919 | |||
882 | void cdebbuf_free(_cdebbuf *cdb) | 920 | void cdebbuf_free(_cdebbuf *cdb) |
883 | { | 921 | { |
884 | if (likely(cdb == g_debbuf)) { | 922 | if (likely(cdb == g_debbuf)) { |
@@ -891,6 +929,16 @@ void cdebbuf_free(_cdebbuf *cdb) | |||
891 | } | 929 | } |
892 | 930 | ||
893 | 931 | ||
932 | /** | ||
933 | * capi_message2str() - format CAPI 2.0 message for printing | ||
934 | * @msg: CAPI 2.0 message | ||
935 | * | ||
936 | * Allocates a CAPI debug buffer and fills it with a printable representation | ||
937 | * of the CAPI 2.0 message in @msg. | ||
938 | * Return value: allocated debug buffer, NULL on error | ||
939 | * The returned buffer should be freed by a call to cdebbuf_free() after use. | ||
940 | */ | ||
941 | |||
894 | _cdebbuf *capi_message2str(u8 * msg) | 942 | _cdebbuf *capi_message2str(u8 * msg) |
895 | { | 943 | { |
896 | _cdebbuf *cdb; | 944 | _cdebbuf *cdb; |
@@ -926,10 +974,23 @@ _cdebbuf *capi_message2str(u8 * msg) | |||
926 | return cdb; | 974 | return cdb; |
927 | } | 975 | } |
928 | 976 | ||
977 | /** | ||
978 | * capi_cmsg2str() - format _cmsg structure for printing | ||
979 | * @cmsg: _cmsg structure | ||
980 | * | ||
981 | * Allocates a CAPI debug buffer and fills it with a printable representation | ||
982 | * of the CAPI 2.0 message stored in @cmsg by a previous call to | ||
983 | * capi_cmsg2message() or capi_message2cmsg(). | ||
984 | * Return value: allocated debug buffer, NULL on error | ||
985 | * The returned buffer should be freed by a call to cdebbuf_free() after use. | ||
986 | */ | ||
987 | |||
929 | _cdebbuf *capi_cmsg2str(_cmsg * cmsg) | 988 | _cdebbuf *capi_cmsg2str(_cmsg * cmsg) |
930 | { | 989 | { |
931 | _cdebbuf *cdb; | 990 | _cdebbuf *cdb; |
932 | 991 | ||
992 | if (!cmsg->m) | ||
993 | return NULL; /* no message */ | ||
933 | cdb = cdebbuf_alloc(); | 994 | cdb = cdebbuf_alloc(); |
934 | if (!cdb) | 995 | if (!cdb) |
935 | return NULL; | 996 | return NULL; |
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index f33170368cd1..57d26360f64e 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c | |||
@@ -377,14 +377,14 @@ void capi_ctr_ready(struct capi_ctr * card) | |||
377 | EXPORT_SYMBOL(capi_ctr_ready); | 377 | EXPORT_SYMBOL(capi_ctr_ready); |
378 | 378 | ||
379 | /** | 379 | /** |
380 | * capi_ctr_reseted() - signal CAPI controller reset | 380 | * capi_ctr_down() - signal CAPI controller not ready |
381 | * @card: controller descriptor structure. | 381 | * @card: controller descriptor structure. |
382 | * | 382 | * |
383 | * Called by hardware driver to signal that the controller is down and | 383 | * Called by hardware driver to signal that the controller is down and |
384 | * unavailable for use. | 384 | * unavailable for use. |
385 | */ | 385 | */ |
386 | 386 | ||
387 | void capi_ctr_reseted(struct capi_ctr * card) | 387 | void capi_ctr_down(struct capi_ctr * card) |
388 | { | 388 | { |
389 | u16 appl; | 389 | u16 appl; |
390 | 390 | ||
@@ -413,7 +413,7 @@ void capi_ctr_reseted(struct capi_ctr * card) | |||
413 | notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); | 413 | notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); |
414 | } | 414 | } |
415 | 415 | ||
416 | EXPORT_SYMBOL(capi_ctr_reseted); | 416 | EXPORT_SYMBOL(capi_ctr_down); |
417 | 417 | ||
418 | /** | 418 | /** |
419 | * capi_ctr_suspend_output() - suspend controller | 419 | * capi_ctr_suspend_output() - suspend controller |
@@ -517,7 +517,7 @@ EXPORT_SYMBOL(attach_capi_ctr); | |||
517 | int detach_capi_ctr(struct capi_ctr *card) | 517 | int detach_capi_ctr(struct capi_ctr *card) |
518 | { | 518 | { |
519 | if (card->cardstate != CARD_DETECTED) | 519 | if (card->cardstate != CARD_DETECTED) |
520 | capi_ctr_reseted(card); | 520 | capi_ctr_down(card); |
521 | 521 | ||
522 | ncards--; | 522 | ncards--; |
523 | 523 | ||
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c index abf05ec31760..a7c0083e78a7 100644 --- a/drivers/isdn/hardware/avm/b1.c +++ b/drivers/isdn/hardware/avm/b1.c | |||
@@ -330,7 +330,7 @@ void b1_reset_ctr(struct capi_ctr *ctrl) | |||
330 | spin_lock_irqsave(&card->lock, flags); | 330 | spin_lock_irqsave(&card->lock, flags); |
331 | capilib_release(&cinfo->ncci_head); | 331 | capilib_release(&cinfo->ncci_head); |
332 | spin_unlock_irqrestore(&card->lock, flags); | 332 | spin_unlock_irqrestore(&card->lock, flags); |
333 | capi_ctr_reseted(ctrl); | 333 | capi_ctr_down(ctrl); |
334 | } | 334 | } |
335 | 335 | ||
336 | void b1_register_appl(struct capi_ctr *ctrl, | 336 | void b1_register_appl(struct capi_ctr *ctrl, |
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c index da34b98e3de7..0e84aaae43fd 100644 --- a/drivers/isdn/hardware/avm/b1dma.c +++ b/drivers/isdn/hardware/avm/b1dma.c | |||
@@ -759,7 +759,7 @@ void b1dma_reset_ctr(struct capi_ctr *ctrl) | |||
759 | memset(cinfo->version, 0, sizeof(cinfo->version)); | 759 | memset(cinfo->version, 0, sizeof(cinfo->version)); |
760 | capilib_release(&cinfo->ncci_head); | 760 | capilib_release(&cinfo->ncci_head); |
761 | spin_unlock_irqrestore(&card->lock, flags); | 761 | spin_unlock_irqrestore(&card->lock, flags); |
762 | capi_ctr_reseted(ctrl); | 762 | capi_ctr_down(ctrl); |
763 | } | 763 | } |
764 | 764 | ||
765 | /* ------------------------------------------------------------- */ | 765 | /* ------------------------------------------------------------- */ |
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c index 9df1d3f66c87..6833301a45fc 100644 --- a/drivers/isdn/hardware/avm/c4.c +++ b/drivers/isdn/hardware/avm/c4.c | |||
@@ -681,7 +681,7 @@ static irqreturn_t c4_handle_interrupt(avmcard *card) | |||
681 | spin_lock_irqsave(&card->lock, flags); | 681 | spin_lock_irqsave(&card->lock, flags); |
682 | capilib_release(&cinfo->ncci_head); | 682 | capilib_release(&cinfo->ncci_head); |
683 | spin_unlock_irqrestore(&card->lock, flags); | 683 | spin_unlock_irqrestore(&card->lock, flags); |
684 | capi_ctr_reseted(&cinfo->capi_ctrl); | 684 | capi_ctr_down(&cinfo->capi_ctrl); |
685 | } | 685 | } |
686 | card->nlogcontr = 0; | 686 | card->nlogcontr = 0; |
687 | return IRQ_HANDLED; | 687 | return IRQ_HANDLED; |
@@ -909,7 +909,7 @@ static void c4_reset_ctr(struct capi_ctr *ctrl) | |||
909 | for (i=0; i < card->nr_controllers; i++) { | 909 | for (i=0; i < card->nr_controllers; i++) { |
910 | cinfo = &card->ctrlinfo[i]; | 910 | cinfo = &card->ctrlinfo[i]; |
911 | memset(cinfo->version, 0, sizeof(cinfo->version)); | 911 | memset(cinfo->version, 0, sizeof(cinfo->version)); |
912 | capi_ctr_reseted(&cinfo->capi_ctrl); | 912 | capi_ctr_down(&cinfo->capi_ctrl); |
913 | } | 913 | } |
914 | card->nlogcontr = 0; | 914 | card->nlogcontr = 0; |
915 | } | 915 | } |
diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c index e7724493738c..1c53fd49adb6 100644 --- a/drivers/isdn/hardware/avm/t1isa.c +++ b/drivers/isdn/hardware/avm/t1isa.c | |||
@@ -339,7 +339,7 @@ static void t1isa_reset_ctr(struct capi_ctr *ctrl) | |||
339 | spin_lock_irqsave(&card->lock, flags); | 339 | spin_lock_irqsave(&card->lock, flags); |
340 | capilib_release(&cinfo->ncci_head); | 340 | capilib_release(&cinfo->ncci_head); |
341 | spin_unlock_irqrestore(&card->lock, flags); | 341 | spin_unlock_irqrestore(&card->lock, flags); |
342 | capi_ctr_reseted(ctrl); | 342 | capi_ctr_down(ctrl); |
343 | } | 343 | } |
344 | 344 | ||
345 | static void t1isa_remove(struct pci_dev *pdev) | 345 | static void t1isa_remove(struct pci_dev *pdev) |
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c index 53f6ad1235db..4ffaa14b9fc4 100644 --- a/drivers/isdn/hysdn/hycapi.c +++ b/drivers/isdn/hysdn/hycapi.c | |||
@@ -67,7 +67,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl) | |||
67 | printk(KERN_NOTICE "HYCAPI hycapi_reset_ctr\n"); | 67 | printk(KERN_NOTICE "HYCAPI hycapi_reset_ctr\n"); |
68 | #endif | 68 | #endif |
69 | capilib_release(&cinfo->ncci_head); | 69 | capilib_release(&cinfo->ncci_head); |
70 | capi_ctr_reseted(ctrl); | 70 | capi_ctr_down(ctrl); |
71 | } | 71 | } |
72 | 72 | ||
73 | /****************************** | 73 | /****************************** |
@@ -347,7 +347,7 @@ int hycapi_capi_stop(hysdn_card *card) | |||
347 | if(cinfo) { | 347 | if(cinfo) { |
348 | ctrl = &cinfo->capi_ctrl; | 348 | ctrl = &cinfo->capi_ctrl; |
349 | /* ctrl->suspend_output(ctrl); */ | 349 | /* ctrl->suspend_output(ctrl); */ |
350 | capi_ctr_reseted(ctrl); | 350 | capi_ctr_down(ctrl); |
351 | } | 351 | } |
352 | return 0; | 352 | return 0; |
353 | } | 353 | } |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 3df8fc4376dd..3f739cfd92fa 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -1001,7 +1001,7 @@ config SMC911X | |||
1001 | 1001 | ||
1002 | config SMSC911X | 1002 | config SMSC911X |
1003 | tristate "SMSC LAN911x/LAN921x families embedded ethernet support" | 1003 | tristate "SMSC LAN911x/LAN921x families embedded ethernet support" |
1004 | depends on ARM || SUPERH | 1004 | depends on ARM || SUPERH || BLACKFIN |
1005 | select CRC32 | 1005 | select CRC32 |
1006 | select MII | 1006 | select MII |
1007 | select PHYLIB | 1007 | select PHYLIB |
@@ -1723,6 +1723,11 @@ config TLAN | |||
1723 | 1723 | ||
1724 | Please email feedback to <torben.mathiasen@compaq.com>. | 1724 | Please email feedback to <torben.mathiasen@compaq.com>. |
1725 | 1725 | ||
1726 | config KS8842 | ||
1727 | tristate "Micrel KSZ8842" | ||
1728 | help | ||
1729 | This platform driver is for Micrel KSZ8842 chip. | ||
1730 | |||
1726 | config VIA_RHINE | 1731 | config VIA_RHINE |
1727 | tristate "VIA Rhine support" | 1732 | tristate "VIA Rhine support" |
1728 | depends on NET_PCI && PCI | 1733 | depends on NET_PCI && PCI |
@@ -2720,6 +2725,8 @@ source "drivers/net/wan/Kconfig" | |||
2720 | 2725 | ||
2721 | source "drivers/atm/Kconfig" | 2726 | source "drivers/atm/Kconfig" |
2722 | 2727 | ||
2728 | source "drivers/ieee802154/Kconfig" | ||
2729 | |||
2723 | source "drivers/s390/net/Kconfig" | 2730 | source "drivers/s390/net/Kconfig" |
2724 | 2731 | ||
2725 | config XEN_NETDEV_FRONTEND | 2732 | config XEN_NETDEV_FRONTEND |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 774c2b45bdb8..1c378dd5933e 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -86,6 +86,7 @@ obj-$(CONFIG_TC35815) += tc35815.o | |||
86 | obj-$(CONFIG_SKGE) += skge.o | 86 | obj-$(CONFIG_SKGE) += skge.o |
87 | obj-$(CONFIG_SKY2) += sky2.o | 87 | obj-$(CONFIG_SKY2) += sky2.o |
88 | obj-$(CONFIG_SKFP) += skfp/ | 88 | obj-$(CONFIG_SKFP) += skfp/ |
89 | obj-$(CONFIG_KS8842) += ks8842.o | ||
89 | obj-$(CONFIG_VIA_RHINE) += via-rhine.o | 90 | obj-$(CONFIG_VIA_RHINE) += via-rhine.o |
90 | obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o | 91 | obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o |
91 | obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o | 92 | obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o |
diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c index 45c5b7332cd3..e4afbd628c23 100644 --- a/drivers/net/atl1c/atl1c_ethtool.c +++ b/drivers/net/atl1c/atl1c_ethtool.c | |||
@@ -271,7 +271,7 @@ static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
271 | struct atl1c_adapter *adapter = netdev_priv(netdev); | 271 | struct atl1c_adapter *adapter = netdev_priv(netdev); |
272 | 272 | ||
273 | if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | | 273 | if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | |
274 | WAKE_MCAST | WAKE_BCAST | WAKE_MCAST)) | 274 | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)) |
275 | return -EOPNOTSUPP; | 275 | return -EOPNOTSUPP; |
276 | /* these settings will always override what we currently have */ | 276 | /* these settings will always override what we currently have */ |
277 | adapter->wol = 0; | 277 | adapter->wol = 0; |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 5f17d80300ae..66bb56874d9b 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -168,6 +168,7 @@ static void netdev_stats_update(struct be_adapter *adapter) | |||
168 | struct be_port_rxf_stats *port_stats = | 168 | struct be_port_rxf_stats *port_stats = |
169 | &rxf_stats->port[adapter->port_num]; | 169 | &rxf_stats->port[adapter->port_num]; |
170 | struct net_device_stats *dev_stats = &adapter->stats.net_stats; | 170 | struct net_device_stats *dev_stats = &adapter->stats.net_stats; |
171 | struct be_erx_stats *erx_stats = &hw_stats->erx; | ||
171 | 172 | ||
172 | dev_stats->rx_packets = port_stats->rx_total_frames; | 173 | dev_stats->rx_packets = port_stats->rx_total_frames; |
173 | dev_stats->tx_packets = port_stats->tx_unicastframes + | 174 | dev_stats->tx_packets = port_stats->tx_unicastframes + |
@@ -181,29 +182,33 @@ static void netdev_stats_update(struct be_adapter *adapter) | |||
181 | dev_stats->rx_errors = port_stats->rx_crc_errors + | 182 | dev_stats->rx_errors = port_stats->rx_crc_errors + |
182 | port_stats->rx_alignment_symbol_errors + | 183 | port_stats->rx_alignment_symbol_errors + |
183 | port_stats->rx_in_range_errors + | 184 | port_stats->rx_in_range_errors + |
184 | port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; | 185 | port_stats->rx_out_range_errors + |
185 | 186 | port_stats->rx_frame_too_long + | |
186 | /* packet transmit problems */ | 187 | port_stats->rx_dropped_too_small + |
187 | dev_stats->tx_errors = 0; | 188 | port_stats->rx_dropped_too_short + |
188 | 189 | port_stats->rx_dropped_header_too_small + | |
189 | /* no space in linux buffers */ | 190 | port_stats->rx_dropped_tcp_length + |
190 | dev_stats->rx_dropped = 0; | 191 | port_stats->rx_dropped_runt + |
191 | 192 | port_stats->rx_tcp_checksum_errs + | |
192 | /* no space available in linux */ | 193 | port_stats->rx_ip_checksum_errs + |
193 | dev_stats->tx_dropped = 0; | 194 | port_stats->rx_udp_checksum_errs; |
194 | 195 | ||
195 | dev_stats->multicast = port_stats->tx_multicastframes; | 196 | /* no space in linux buffers: best possible approximation */ |
196 | dev_stats->collisions = 0; | 197 | dev_stats->rx_dropped = erx_stats->rx_drops_no_fragments[0]; |
197 | 198 | ||
198 | /* detailed rx errors */ | 199 | /* detailed rx errors */ |
199 | dev_stats->rx_length_errors = port_stats->rx_in_range_errors + | 200 | dev_stats->rx_length_errors = port_stats->rx_in_range_errors + |
200 | port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; | 201 | port_stats->rx_out_range_errors + |
202 | port_stats->rx_frame_too_long; | ||
203 | |||
201 | /* receive ring buffer overflow */ | 204 | /* receive ring buffer overflow */ |
202 | dev_stats->rx_over_errors = 0; | 205 | dev_stats->rx_over_errors = 0; |
206 | |||
203 | dev_stats->rx_crc_errors = port_stats->rx_crc_errors; | 207 | dev_stats->rx_crc_errors = port_stats->rx_crc_errors; |
204 | 208 | ||
205 | /* frame alignment errors */ | 209 | /* frame alignment errors */ |
206 | dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors; | 210 | dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors; |
211 | |||
207 | /* receiver fifo overrun */ | 212 | /* receiver fifo overrun */ |
208 | /* drops_no_pbuf is no per i/f, it's per BE card */ | 213 | /* drops_no_pbuf is no per i/f, it's per BE card */ |
209 | dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow + | 214 | dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow + |
@@ -211,6 +216,16 @@ static void netdev_stats_update(struct be_adapter *adapter) | |||
211 | rxf_stats->rx_drops_no_pbuf; | 216 | rxf_stats->rx_drops_no_pbuf; |
212 | /* receiver missed packetd */ | 217 | /* receiver missed packetd */ |
213 | dev_stats->rx_missed_errors = 0; | 218 | dev_stats->rx_missed_errors = 0; |
219 | |||
220 | /* packet transmit problems */ | ||
221 | dev_stats->tx_errors = 0; | ||
222 | |||
223 | /* no space available in linux */ | ||
224 | dev_stats->tx_dropped = 0; | ||
225 | |||
226 | dev_stats->multicast = port_stats->tx_multicastframes; | ||
227 | dev_stats->collisions = 0; | ||
228 | |||
214 | /* detailed tx_errors */ | 229 | /* detailed tx_errors */ |
215 | dev_stats->tx_aborted_errors = 0; | 230 | dev_stats->tx_aborted_errors = 0; |
216 | dev_stats->tx_carrier_errors = 0; | 231 | dev_stats->tx_carrier_errors = 0; |
@@ -337,13 +352,10 @@ static void be_tx_stats_update(struct be_adapter *adapter, | |||
337 | /* Determine number of WRB entries needed to xmit data in an skb */ | 352 | /* Determine number of WRB entries needed to xmit data in an skb */ |
338 | static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy) | 353 | static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy) |
339 | { | 354 | { |
340 | int cnt = 0; | 355 | int cnt = (skb->len > skb->data_len); |
341 | while (skb) { | 356 | |
342 | if (skb->len > skb->data_len) | 357 | cnt += skb_shinfo(skb)->nr_frags; |
343 | cnt++; | 358 | |
344 | cnt += skb_shinfo(skb)->nr_frags; | ||
345 | skb = skb_shinfo(skb)->frag_list; | ||
346 | } | ||
347 | /* to account for hdr wrb */ | 359 | /* to account for hdr wrb */ |
348 | cnt++; | 360 | cnt++; |
349 | if (cnt & 1) { | 361 | if (cnt & 1) { |
@@ -409,31 +421,28 @@ static int make_tx_wrbs(struct be_adapter *adapter, | |||
409 | hdr = queue_head_node(txq); | 421 | hdr = queue_head_node(txq); |
410 | queue_head_inc(txq); | 422 | queue_head_inc(txq); |
411 | 423 | ||
412 | while (skb) { | 424 | if (skb->len > skb->data_len) { |
413 | if (skb->len > skb->data_len) { | 425 | int len = skb->len - skb->data_len; |
414 | int len = skb->len - skb->data_len; | 426 | busaddr = pci_map_single(pdev, skb->data, len, |
415 | busaddr = pci_map_single(pdev, skb->data, len, | 427 | PCI_DMA_TODEVICE); |
416 | PCI_DMA_TODEVICE); | 428 | wrb = queue_head_node(txq); |
417 | wrb = queue_head_node(txq); | 429 | wrb_fill(wrb, busaddr, len); |
418 | wrb_fill(wrb, busaddr, len); | 430 | be_dws_cpu_to_le(wrb, sizeof(*wrb)); |
419 | be_dws_cpu_to_le(wrb, sizeof(*wrb)); | 431 | queue_head_inc(txq); |
420 | queue_head_inc(txq); | 432 | copied += len; |
421 | copied += len; | 433 | } |
422 | } | ||
423 | 434 | ||
424 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | 435 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
425 | struct skb_frag_struct *frag = | 436 | struct skb_frag_struct *frag = |
426 | &skb_shinfo(skb)->frags[i]; | 437 | &skb_shinfo(skb)->frags[i]; |
427 | busaddr = pci_map_page(pdev, frag->page, | 438 | busaddr = pci_map_page(pdev, frag->page, |
428 | frag->page_offset, | 439 | frag->page_offset, |
429 | frag->size, PCI_DMA_TODEVICE); | 440 | frag->size, PCI_DMA_TODEVICE); |
430 | wrb = queue_head_node(txq); | 441 | wrb = queue_head_node(txq); |
431 | wrb_fill(wrb, busaddr, frag->size); | 442 | wrb_fill(wrb, busaddr, frag->size); |
432 | be_dws_cpu_to_le(wrb, sizeof(*wrb)); | 443 | be_dws_cpu_to_le(wrb, sizeof(*wrb)); |
433 | queue_head_inc(txq); | 444 | queue_head_inc(txq); |
434 | copied += frag->size; | 445 | copied += frag->size; |
435 | } | ||
436 | skb = skb_shinfo(skb)->frag_list; | ||
437 | } | 446 | } |
438 | 447 | ||
439 | if (dummy_wrb) { | 448 | if (dummy_wrb) { |
@@ -734,7 +743,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
734 | 743 | ||
735 | if (pktsize <= rx_frag_size) { | 744 | if (pktsize <= rx_frag_size) { |
736 | BUG_ON(num_rcvd != 1); | 745 | BUG_ON(num_rcvd != 1); |
737 | return; | 746 | goto done; |
738 | } | 747 | } |
739 | 748 | ||
740 | /* More frags present for this completion */ | 749 | /* More frags present for this completion */ |
@@ -756,6 +765,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
756 | memset(page_info, 0, sizeof(*page_info)); | 765 | memset(page_info, 0, sizeof(*page_info)); |
757 | } | 766 | } |
758 | 767 | ||
768 | done: | ||
759 | be_rx_stats_update(adapter, pktsize, num_rcvd); | 769 | be_rx_stats_update(adapter, pktsize, num_rcvd); |
760 | return; | 770 | return; |
761 | } | 771 | } |
@@ -866,12 +876,19 @@ static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) | |||
866 | 876 | ||
867 | be_dws_le_to_cpu(rxcp, sizeof(*rxcp)); | 877 | be_dws_le_to_cpu(rxcp, sizeof(*rxcp)); |
868 | 878 | ||
869 | rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0; | ||
870 | |||
871 | queue_tail_inc(&adapter->rx_obj.cq); | 879 | queue_tail_inc(&adapter->rx_obj.cq); |
872 | return rxcp; | 880 | return rxcp; |
873 | } | 881 | } |
874 | 882 | ||
883 | /* To reset the valid bit, we need to reset the whole word as | ||
884 | * when walking the queue the valid entries are little-endian | ||
885 | * and invalid entries are host endian | ||
886 | */ | ||
887 | static inline void be_rx_compl_reset(struct be_eth_rx_compl *rxcp) | ||
888 | { | ||
889 | rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0; | ||
890 | } | ||
891 | |||
875 | static inline struct page *be_alloc_pages(u32 size) | 892 | static inline struct page *be_alloc_pages(u32 size) |
876 | { | 893 | { |
877 | gfp_t alloc_flags = GFP_ATOMIC; | 894 | gfp_t alloc_flags = GFP_ATOMIC; |
@@ -1003,6 +1020,7 @@ static void be_rx_q_clean(struct be_adapter *adapter) | |||
1003 | /* First cleanup pending rx completions */ | 1020 | /* First cleanup pending rx completions */ |
1004 | while ((rxcp = be_rx_compl_get(adapter)) != NULL) { | 1021 | while ((rxcp = be_rx_compl_get(adapter)) != NULL) { |
1005 | be_rx_compl_discard(adapter, rxcp); | 1022 | be_rx_compl_discard(adapter, rxcp); |
1023 | be_rx_compl_reset(rxcp); | ||
1006 | be_cq_notify(&adapter->ctrl, rx_cq->id, true, 1); | 1024 | be_cq_notify(&adapter->ctrl, rx_cq->id, true, 1); |
1007 | } | 1025 | } |
1008 | 1026 | ||
@@ -1038,8 +1056,13 @@ static void be_tx_queues_destroy(struct be_adapter *adapter) | |||
1038 | struct be_queue_info *q; | 1056 | struct be_queue_info *q; |
1039 | 1057 | ||
1040 | q = &adapter->tx_obj.q; | 1058 | q = &adapter->tx_obj.q; |
1041 | if (q->created) | 1059 | if (q->created) { |
1042 | be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_TXQ); | 1060 | be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_TXQ); |
1061 | |||
1062 | /* No more tx completions can be rcvd now; clean up if there | ||
1063 | * are any pending completions or pending tx requests */ | ||
1064 | be_tx_q_clean(adapter); | ||
1065 | } | ||
1043 | be_queue_free(adapter, q); | 1066 | be_queue_free(adapter, q); |
1044 | 1067 | ||
1045 | q = &adapter->tx_obj.cq; | 1068 | q = &adapter->tx_obj.cq; |
@@ -1047,10 +1070,6 @@ static void be_tx_queues_destroy(struct be_adapter *adapter) | |||
1047 | be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ); | 1070 | be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ); |
1048 | be_queue_free(adapter, q); | 1071 | be_queue_free(adapter, q); |
1049 | 1072 | ||
1050 | /* No more tx completions can be rcvd now; clean up if there are | ||
1051 | * any pending completions or pending tx requests */ | ||
1052 | be_tx_q_clean(adapter); | ||
1053 | |||
1054 | q = &adapter->tx_eq.q; | 1073 | q = &adapter->tx_eq.q; |
1055 | if (q->created) | 1074 | if (q->created) |
1056 | be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ); | 1075 | be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ); |
@@ -1284,6 +1303,8 @@ int be_poll_rx(struct napi_struct *napi, int budget) | |||
1284 | be_rx_compl_process_lro(adapter, rxcp); | 1303 | be_rx_compl_process_lro(adapter, rxcp); |
1285 | else | 1304 | else |
1286 | be_rx_compl_process(adapter, rxcp); | 1305 | be_rx_compl_process(adapter, rxcp); |
1306 | |||
1307 | be_rx_compl_reset(rxcp); | ||
1287 | } | 1308 | } |
1288 | 1309 | ||
1289 | lro_flush_all(&adapter->rx_obj.lro_mgr); | 1310 | lro_flush_all(&adapter->rx_obj.lro_mgr); |
@@ -1539,7 +1560,7 @@ static int be_close(struct net_device *netdev) | |||
1539 | struct be_eq_obj *tx_eq = &adapter->tx_eq; | 1560 | struct be_eq_obj *tx_eq = &adapter->tx_eq; |
1540 | int vec; | 1561 | int vec; |
1541 | 1562 | ||
1542 | cancel_delayed_work(&adapter->work); | 1563 | cancel_delayed_work_sync(&adapter->work); |
1543 | 1564 | ||
1544 | netif_stop_queue(netdev); | 1565 | netif_stop_queue(netdev); |
1545 | netif_carrier_off(netdev); | 1566 | netif_carrier_off(netdev); |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index f53017250e09..f99e17e0a319 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -546,8 +546,7 @@ bnx2_free_rx_mem(struct bnx2 *bp) | |||
546 | rxr->rx_desc_mapping[j]); | 546 | rxr->rx_desc_mapping[j]); |
547 | rxr->rx_desc_ring[j] = NULL; | 547 | rxr->rx_desc_ring[j] = NULL; |
548 | } | 548 | } |
549 | if (rxr->rx_buf_ring) | 549 | vfree(rxr->rx_buf_ring); |
550 | vfree(rxr->rx_buf_ring); | ||
551 | rxr->rx_buf_ring = NULL; | 550 | rxr->rx_buf_ring = NULL; |
552 | 551 | ||
553 | for (j = 0; j < bp->rx_max_pg_ring; j++) { | 552 | for (j = 0; j < bp->rx_max_pg_ring; j++) { |
@@ -557,8 +556,7 @@ bnx2_free_rx_mem(struct bnx2 *bp) | |||
557 | rxr->rx_pg_desc_mapping[j]); | 556 | rxr->rx_pg_desc_mapping[j]); |
558 | rxr->rx_pg_desc_ring[j] = NULL; | 557 | rxr->rx_pg_desc_ring[j] = NULL; |
559 | } | 558 | } |
560 | if (rxr->rx_pg_ring) | 559 | vfree(rxr->rx_pg_ring); |
561 | vfree(rxr->rx_pg_ring); | ||
562 | rxr->rx_pg_ring = NULL; | 560 | rxr->rx_pg_ring = NULL; |
563 | } | 561 | } |
564 | } | 562 | } |
@@ -5487,7 +5485,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
5487 | dev_kfree_skb(skb); | 5485 | dev_kfree_skb(skb); |
5488 | return -EIO; | 5486 | return -EIO; |
5489 | } | 5487 | } |
5490 | map = skb_shinfo(skb)->dma_maps[0]; | 5488 | map = skb_shinfo(skb)->dma_head; |
5491 | 5489 | ||
5492 | REG_WR(bp, BNX2_HC_COMMAND, | 5490 | REG_WR(bp, BNX2_HC_COMMAND, |
5493 | bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); | 5491 | bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); |
@@ -6167,7 +6165,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
6167 | } | 6165 | } |
6168 | 6166 | ||
6169 | sp = skb_shinfo(skb); | 6167 | sp = skb_shinfo(skb); |
6170 | mapping = sp->dma_maps[0]; | 6168 | mapping = sp->dma_head; |
6171 | 6169 | ||
6172 | tx_buf = &txr->tx_buf_ring[ring_prod]; | 6170 | tx_buf = &txr->tx_buf_ring[ring_prod]; |
6173 | tx_buf->skb = skb; | 6171 | tx_buf->skb = skb; |
@@ -6191,7 +6189,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
6191 | txbd = &txr->tx_desc_ring[ring_prod]; | 6189 | txbd = &txr->tx_desc_ring[ring_prod]; |
6192 | 6190 | ||
6193 | len = frag->size; | 6191 | len = frag->size; |
6194 | mapping = sp->dma_maps[i + 1]; | 6192 | mapping = sp->dma_maps[i]; |
6195 | 6193 | ||
6196 | txbd->tx_bd_haddr_hi = (u64) mapping >> 32; | 6194 | txbd->tx_bd_haddr_hi = (u64) mapping >> 32; |
6197 | txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff; | 6195 | txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff; |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 3a1b7b04eb79..5fb861a08664 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -1541,6 +1541,7 @@ int bond_create_sysfs(void) | |||
1541 | printk(KERN_ERR | 1541 | printk(KERN_ERR |
1542 | "network device named %s already exists in sysfs", | 1542 | "network device named %s already exists in sysfs", |
1543 | class_attr_bonding_masters.attr.name); | 1543 | class_attr_bonding_masters.attr.name); |
1544 | ret = 0; | ||
1544 | } | 1545 | } |
1545 | 1546 | ||
1546 | return ret; | 1547 | return ret; |
diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index aa953fb4b8d0..3373560405ba 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c | |||
@@ -108,15 +108,17 @@ static int __devinit sja1000_ofp_probe(struct of_device *ofdev, | |||
108 | res_size = resource_size(&res); | 108 | res_size = resource_size(&res); |
109 | 109 | ||
110 | if (!request_mem_region(res.start, res_size, DRV_NAME)) { | 110 | if (!request_mem_region(res.start, res_size, DRV_NAME)) { |
111 | dev_err(&ofdev->dev, "couldn't request %#x..%#x\n", | 111 | dev_err(&ofdev->dev, "couldn't request %#llx..%#llx\n", |
112 | res.start, res.end); | 112 | (unsigned long long)res.start, |
113 | (unsigned long long)res.end); | ||
113 | return -EBUSY; | 114 | return -EBUSY; |
114 | } | 115 | } |
115 | 116 | ||
116 | base = ioremap_nocache(res.start, res_size); | 117 | base = ioremap_nocache(res.start, res_size); |
117 | if (!base) { | 118 | if (!base) { |
118 | dev_err(&ofdev->dev, "couldn't ioremap %#x..%#x\n", | 119 | dev_err(&ofdev->dev, "couldn't ioremap %#llx..%#llx\n", |
119 | res.start, res.end); | 120 | (unsigned long long)res.start, |
121 | (unsigned long long)res.end); | ||
120 | err = -ENOMEM; | 122 | err = -ENOMEM; |
121 | goto exit_release_mem; | 123 | goto exit_release_mem; |
122 | } | 124 | } |
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index e48e508b9632..1694fad38720 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h | |||
@@ -253,6 +253,8 @@ struct adapter { | |||
253 | struct mutex mdio_lock; | 253 | struct mutex mdio_lock; |
254 | spinlock_t stats_lock; | 254 | spinlock_t stats_lock; |
255 | spinlock_t work_lock; | 255 | spinlock_t work_lock; |
256 | |||
257 | struct sk_buff *nofail_skb; | ||
256 | }; | 258 | }; |
257 | 259 | ||
258 | static inline u32 t3_read_reg(struct adapter *adapter, u32 reg_addr) | 260 | static inline u32 t3_read_reg(struct adapter *adapter, u32 reg_addr) |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index aef3ab21f5f7..538dda4422dc 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -433,40 +433,78 @@ static int init_tp_parity(struct adapter *adap) | |||
433 | for (i = 0; i < 16; i++) { | 433 | for (i = 0; i < 16; i++) { |
434 | struct cpl_smt_write_req *req; | 434 | struct cpl_smt_write_req *req; |
435 | 435 | ||
436 | skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); | 436 | skb = alloc_skb(sizeof(*req), GFP_KERNEL); |
437 | if (!skb) | ||
438 | skb = adap->nofail_skb; | ||
439 | if (!skb) | ||
440 | goto alloc_skb_fail; | ||
441 | |||
437 | req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req)); | 442 | req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req)); |
438 | memset(req, 0, sizeof(*req)); | 443 | memset(req, 0, sizeof(*req)); |
439 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | 444 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); |
440 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i)); | 445 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i)); |
441 | req->iff = i; | 446 | req->iff = i; |
442 | t3_mgmt_tx(adap, skb); | 447 | t3_mgmt_tx(adap, skb); |
448 | if (skb == adap->nofail_skb) { | ||
449 | await_mgmt_replies(adap, cnt, i + 1); | ||
450 | adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); | ||
451 | if (!adap->nofail_skb) | ||
452 | goto alloc_skb_fail; | ||
453 | } | ||
443 | } | 454 | } |
444 | 455 | ||
445 | for (i = 0; i < 2048; i++) { | 456 | for (i = 0; i < 2048; i++) { |
446 | struct cpl_l2t_write_req *req; | 457 | struct cpl_l2t_write_req *req; |
447 | 458 | ||
448 | skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); | 459 | skb = alloc_skb(sizeof(*req), GFP_KERNEL); |
460 | if (!skb) | ||
461 | skb = adap->nofail_skb; | ||
462 | if (!skb) | ||
463 | goto alloc_skb_fail; | ||
464 | |||
449 | req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req)); | 465 | req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req)); |
450 | memset(req, 0, sizeof(*req)); | 466 | memset(req, 0, sizeof(*req)); |
451 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | 467 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); |
452 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i)); | 468 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i)); |
453 | req->params = htonl(V_L2T_W_IDX(i)); | 469 | req->params = htonl(V_L2T_W_IDX(i)); |
454 | t3_mgmt_tx(adap, skb); | 470 | t3_mgmt_tx(adap, skb); |
471 | if (skb == adap->nofail_skb) { | ||
472 | await_mgmt_replies(adap, cnt, 16 + i + 1); | ||
473 | adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); | ||
474 | if (!adap->nofail_skb) | ||
475 | goto alloc_skb_fail; | ||
476 | } | ||
455 | } | 477 | } |
456 | 478 | ||
457 | for (i = 0; i < 2048; i++) { | 479 | for (i = 0; i < 2048; i++) { |
458 | struct cpl_rte_write_req *req; | 480 | struct cpl_rte_write_req *req; |
459 | 481 | ||
460 | skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); | 482 | skb = alloc_skb(sizeof(*req), GFP_KERNEL); |
483 | if (!skb) | ||
484 | skb = adap->nofail_skb; | ||
485 | if (!skb) | ||
486 | goto alloc_skb_fail; | ||
487 | |||
461 | req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req)); | 488 | req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req)); |
462 | memset(req, 0, sizeof(*req)); | 489 | memset(req, 0, sizeof(*req)); |
463 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | 490 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); |
464 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i)); | 491 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i)); |
465 | req->l2t_idx = htonl(V_L2T_W_IDX(i)); | 492 | req->l2t_idx = htonl(V_L2T_W_IDX(i)); |
466 | t3_mgmt_tx(adap, skb); | 493 | t3_mgmt_tx(adap, skb); |
494 | if (skb == adap->nofail_skb) { | ||
495 | await_mgmt_replies(adap, cnt, 16 + 2048 + i + 1); | ||
496 | adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); | ||
497 | if (!adap->nofail_skb) | ||
498 | goto alloc_skb_fail; | ||
499 | } | ||
467 | } | 500 | } |
468 | 501 | ||
469 | skb = alloc_skb(sizeof(*greq), GFP_KERNEL | __GFP_NOFAIL); | 502 | skb = alloc_skb(sizeof(*greq), GFP_KERNEL); |
503 | if (!skb) | ||
504 | skb = adap->nofail_skb; | ||
505 | if (!skb) | ||
506 | goto alloc_skb_fail; | ||
507 | |||
470 | greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq)); | 508 | greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq)); |
471 | memset(greq, 0, sizeof(*greq)); | 509 | memset(greq, 0, sizeof(*greq)); |
472 | greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | 510 | greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); |
@@ -475,8 +513,17 @@ static int init_tp_parity(struct adapter *adap) | |||
475 | t3_mgmt_tx(adap, skb); | 513 | t3_mgmt_tx(adap, skb); |
476 | 514 | ||
477 | i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1); | 515 | i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1); |
516 | if (skb == adap->nofail_skb) { | ||
517 | i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1); | ||
518 | adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); | ||
519 | } | ||
520 | |||
478 | t3_tp_set_offload_mode(adap, 0); | 521 | t3_tp_set_offload_mode(adap, 0); |
479 | return i; | 522 | return i; |
523 | |||
524 | alloc_skb_fail: | ||
525 | t3_tp_set_offload_mode(adap, 0); | ||
526 | return -ENOMEM; | ||
480 | } | 527 | } |
481 | 528 | ||
482 | /** | 529 | /** |
@@ -871,7 +918,12 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo, | |||
871 | struct mngt_pktsched_wr *req; | 918 | struct mngt_pktsched_wr *req; |
872 | int ret; | 919 | int ret; |
873 | 920 | ||
874 | skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); | 921 | skb = alloc_skb(sizeof(*req), GFP_KERNEL); |
922 | if (!skb) | ||
923 | skb = adap->nofail_skb; | ||
924 | if (!skb) | ||
925 | return -ENOMEM; | ||
926 | |||
875 | req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req)); | 927 | req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req)); |
876 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT)); | 928 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT)); |
877 | req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET; | 929 | req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET; |
@@ -881,6 +933,12 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo, | |||
881 | req->max = hi; | 933 | req->max = hi; |
882 | req->binding = port; | 934 | req->binding = port; |
883 | ret = t3_mgmt_tx(adap, skb); | 935 | ret = t3_mgmt_tx(adap, skb); |
936 | if (skb == adap->nofail_skb) { | ||
937 | adap->nofail_skb = alloc_skb(sizeof(struct cpl_set_tcb_field), | ||
938 | GFP_KERNEL); | ||
939 | if (!adap->nofail_skb) | ||
940 | ret = -ENOMEM; | ||
941 | } | ||
884 | 942 | ||
885 | return ret; | 943 | return ret; |
886 | } | 944 | } |
@@ -3020,6 +3078,14 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3020 | goto out_disable_device; | 3078 | goto out_disable_device; |
3021 | } | 3079 | } |
3022 | 3080 | ||
3081 | adapter->nofail_skb = | ||
3082 | alloc_skb(sizeof(struct cpl_set_tcb_field), GFP_KERNEL); | ||
3083 | if (!adapter->nofail_skb) { | ||
3084 | dev_err(&pdev->dev, "cannot allocate nofail buffer\n"); | ||
3085 | err = -ENOMEM; | ||
3086 | goto out_free_adapter; | ||
3087 | } | ||
3088 | |||
3023 | adapter->regs = ioremap_nocache(mmio_start, mmio_len); | 3089 | adapter->regs = ioremap_nocache(mmio_start, mmio_len); |
3024 | if (!adapter->regs) { | 3090 | if (!adapter->regs) { |
3025 | dev_err(&pdev->dev, "cannot map device registers\n"); | 3091 | dev_err(&pdev->dev, "cannot map device registers\n"); |
@@ -3176,6 +3242,8 @@ static void __devexit remove_one(struct pci_dev *pdev) | |||
3176 | free_netdev(adapter->port[i]); | 3242 | free_netdev(adapter->port[i]); |
3177 | 3243 | ||
3178 | iounmap(adapter->regs); | 3244 | iounmap(adapter->regs); |
3245 | if (adapter->nofail_skb) | ||
3246 | kfree_skb(adapter->nofail_skb); | ||
3179 | kfree(adapter); | 3247 | kfree(adapter); |
3180 | pci_release_regions(pdev); | 3248 | pci_release_regions(pdev); |
3181 | pci_disable_device(pdev); | 3249 | pci_disable_device(pdev); |
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index 620d80be6aac..f9f54b57b28c 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c | |||
@@ -566,13 +566,31 @@ static void t3_process_tid_release_list(struct work_struct *work) | |||
566 | spin_unlock_bh(&td->tid_release_lock); | 566 | spin_unlock_bh(&td->tid_release_lock); |
567 | 567 | ||
568 | skb = alloc_skb(sizeof(struct cpl_tid_release), | 568 | skb = alloc_skb(sizeof(struct cpl_tid_release), |
569 | GFP_KERNEL | __GFP_NOFAIL); | 569 | GFP_KERNEL); |
570 | if (!skb) | ||
571 | skb = td->nofail_skb; | ||
572 | if (!skb) { | ||
573 | spin_lock_bh(&td->tid_release_lock); | ||
574 | p->ctx = (void *)td->tid_release_list; | ||
575 | td->tid_release_list = (struct t3c_tid_entry *)p; | ||
576 | break; | ||
577 | } | ||
570 | mk_tid_release(skb, p - td->tid_maps.tid_tab); | 578 | mk_tid_release(skb, p - td->tid_maps.tid_tab); |
571 | cxgb3_ofld_send(tdev, skb); | 579 | cxgb3_ofld_send(tdev, skb); |
572 | p->ctx = NULL; | 580 | p->ctx = NULL; |
581 | if (skb == td->nofail_skb) | ||
582 | td->nofail_skb = | ||
583 | alloc_skb(sizeof(struct cpl_tid_release), | ||
584 | GFP_KERNEL); | ||
573 | spin_lock_bh(&td->tid_release_lock); | 585 | spin_lock_bh(&td->tid_release_lock); |
574 | } | 586 | } |
587 | td->release_list_incomplete = (td->tid_release_list == NULL) ? 0 : 1; | ||
575 | spin_unlock_bh(&td->tid_release_lock); | 588 | spin_unlock_bh(&td->tid_release_lock); |
589 | |||
590 | if (!td->nofail_skb) | ||
591 | td->nofail_skb = | ||
592 | alloc_skb(sizeof(struct cpl_tid_release), | ||
593 | GFP_KERNEL); | ||
576 | } | 594 | } |
577 | 595 | ||
578 | /* use ctx as a next pointer in the tid release list */ | 596 | /* use ctx as a next pointer in the tid release list */ |
@@ -585,7 +603,7 @@ void cxgb3_queue_tid_release(struct t3cdev *tdev, unsigned int tid) | |||
585 | p->ctx = (void *)td->tid_release_list; | 603 | p->ctx = (void *)td->tid_release_list; |
586 | p->client = NULL; | 604 | p->client = NULL; |
587 | td->tid_release_list = p; | 605 | td->tid_release_list = p; |
588 | if (!p->ctx) | 606 | if (!p->ctx || td->release_list_incomplete) |
589 | schedule_work(&td->tid_release_task); | 607 | schedule_work(&td->tid_release_task); |
590 | spin_unlock_bh(&td->tid_release_lock); | 608 | spin_unlock_bh(&td->tid_release_lock); |
591 | } | 609 | } |
@@ -1274,6 +1292,9 @@ int cxgb3_offload_activate(struct adapter *adapter) | |||
1274 | if (list_empty(&adapter_list)) | 1292 | if (list_empty(&adapter_list)) |
1275 | register_netevent_notifier(&nb); | 1293 | register_netevent_notifier(&nb); |
1276 | 1294 | ||
1295 | t->nofail_skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_KERNEL); | ||
1296 | t->release_list_incomplete = 0; | ||
1297 | |||
1277 | add_adapter(adapter); | 1298 | add_adapter(adapter); |
1278 | return 0; | 1299 | return 0; |
1279 | 1300 | ||
@@ -1298,6 +1319,8 @@ void cxgb3_offload_deactivate(struct adapter *adapter) | |||
1298 | T3C_DATA(tdev) = NULL; | 1319 | T3C_DATA(tdev) = NULL; |
1299 | t3_free_l2t(L2DATA(tdev)); | 1320 | t3_free_l2t(L2DATA(tdev)); |
1300 | L2DATA(tdev) = NULL; | 1321 | L2DATA(tdev) = NULL; |
1322 | if (t->nofail_skb) | ||
1323 | kfree_skb(t->nofail_skb); | ||
1301 | kfree(t); | 1324 | kfree(t); |
1302 | } | 1325 | } |
1303 | 1326 | ||
diff --git a/drivers/net/cxgb3/cxgb3_offload.h b/drivers/net/cxgb3/cxgb3_offload.h index a8e8e5fcdf84..55945f422aec 100644 --- a/drivers/net/cxgb3/cxgb3_offload.h +++ b/drivers/net/cxgb3/cxgb3_offload.h | |||
@@ -191,6 +191,9 @@ struct t3c_data { | |||
191 | struct t3c_tid_entry *tid_release_list; | 191 | struct t3c_tid_entry *tid_release_list; |
192 | spinlock_t tid_release_lock; | 192 | spinlock_t tid_release_lock; |
193 | struct work_struct tid_release_task; | 193 | struct work_struct tid_release_task; |
194 | |||
195 | struct sk_buff *nofail_skb; | ||
196 | unsigned int release_list_incomplete; | ||
194 | }; | 197 | }; |
195 | 198 | ||
196 | /* | 199 | /* |
diff --git a/drivers/net/declance.c b/drivers/net/declance.c index b62405a69180..2b22e580c4de 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c | |||
@@ -895,6 +895,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
895 | struct lance_private *lp = netdev_priv(dev); | 895 | struct lance_private *lp = netdev_priv(dev); |
896 | volatile struct lance_regs *ll = lp->ll; | 896 | volatile struct lance_regs *ll = lp->ll; |
897 | volatile u16 *ib = (volatile u16 *)dev->mem_start; | 897 | volatile u16 *ib = (volatile u16 *)dev->mem_start; |
898 | unsigned long flags; | ||
898 | int entry, len; | 899 | int entry, len; |
899 | 900 | ||
900 | len = skb->len; | 901 | len = skb->len; |
@@ -907,6 +908,8 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
907 | 908 | ||
908 | dev->stats.tx_bytes += len; | 909 | dev->stats.tx_bytes += len; |
909 | 910 | ||
911 | spin_lock_irqsave(&lp->lock, flags); | ||
912 | |||
910 | entry = lp->tx_new; | 913 | entry = lp->tx_new; |
911 | *lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len); | 914 | *lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len); |
912 | *lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0; | 915 | *lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0; |
@@ -925,6 +928,8 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
925 | /* Kick the lance: transmit now */ | 928 | /* Kick the lance: transmit now */ |
926 | writereg(&ll->rdp, LE_C0_INEA | LE_C0_TDMD); | 929 | writereg(&ll->rdp, LE_C0_INEA | LE_C0_TDMD); |
927 | 930 | ||
931 | spin_unlock_irqrestore(&lp->lock, flags); | ||
932 | |||
928 | dev->trans_start = jiffies; | 933 | dev->trans_start = jiffies; |
929 | dev_kfree_skb(skb); | 934 | dev_kfree_skb(skb); |
930 | 935 | ||
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 0f9ee1348552..119dc5300f9d 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -143,6 +143,8 @@ | |||
143 | * FIXES: | 143 | * FIXES: |
144 | * 2005/12/02 - Michael O'Donnell <Michael.ODonnell at stratus dot com> | 144 | * 2005/12/02 - Michael O'Donnell <Michael.ODonnell at stratus dot com> |
145 | * - Stratus87247: protect MDI control register manipulations | 145 | * - Stratus87247: protect MDI control register manipulations |
146 | * 2009/06/01 - Andreas Mohr <andi at lisas dot de> | ||
147 | * - add clean lowlevel I/O emulation for cards with MII-lacking PHYs | ||
146 | */ | 148 | */ |
147 | 149 | ||
148 | #include <linux/module.h> | 150 | #include <linux/module.h> |
@@ -372,6 +374,7 @@ enum eeprom_op { | |||
372 | 374 | ||
373 | enum eeprom_offsets { | 375 | enum eeprom_offsets { |
374 | eeprom_cnfg_mdix = 0x03, | 376 | eeprom_cnfg_mdix = 0x03, |
377 | eeprom_phy_iface = 0x06, | ||
375 | eeprom_id = 0x0A, | 378 | eeprom_id = 0x0A, |
376 | eeprom_config_asf = 0x0D, | 379 | eeprom_config_asf = 0x0D, |
377 | eeprom_smbus_addr = 0x90, | 380 | eeprom_smbus_addr = 0x90, |
@@ -381,6 +384,18 @@ enum eeprom_cnfg_mdix { | |||
381 | eeprom_mdix_enabled = 0x0080, | 384 | eeprom_mdix_enabled = 0x0080, |
382 | }; | 385 | }; |
383 | 386 | ||
387 | enum eeprom_phy_iface { | ||
388 | NoSuchPhy = 0, | ||
389 | I82553AB, | ||
390 | I82553C, | ||
391 | I82503, | ||
392 | DP83840, | ||
393 | S80C240, | ||
394 | S80C24, | ||
395 | I82555, | ||
396 | DP83840A = 10, | ||
397 | }; | ||
398 | |||
384 | enum eeprom_id { | 399 | enum eeprom_id { |
385 | eeprom_id_wol = 0x0020, | 400 | eeprom_id_wol = 0x0020, |
386 | }; | 401 | }; |
@@ -545,6 +560,7 @@ struct nic { | |||
545 | u32 msg_enable ____cacheline_aligned; | 560 | u32 msg_enable ____cacheline_aligned; |
546 | struct net_device *netdev; | 561 | struct net_device *netdev; |
547 | struct pci_dev *pdev; | 562 | struct pci_dev *pdev; |
563 | u16 (*mdio_ctrl)(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data); | ||
548 | 564 | ||
549 | struct rx *rxs ____cacheline_aligned; | 565 | struct rx *rxs ____cacheline_aligned; |
550 | struct rx *rx_to_use; | 566 | struct rx *rx_to_use; |
@@ -899,7 +915,21 @@ err_unlock: | |||
899 | return err; | 915 | return err; |
900 | } | 916 | } |
901 | 917 | ||
902 | static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data) | 918 | static int mdio_read(struct net_device *netdev, int addr, int reg) |
919 | { | ||
920 | struct nic *nic = netdev_priv(netdev); | ||
921 | return nic->mdio_ctrl(nic, addr, mdi_read, reg, 0); | ||
922 | } | ||
923 | |||
924 | static void mdio_write(struct net_device *netdev, int addr, int reg, int data) | ||
925 | { | ||
926 | struct nic *nic = netdev_priv(netdev); | ||
927 | |||
928 | nic->mdio_ctrl(nic, addr, mdi_write, reg, data); | ||
929 | } | ||
930 | |||
931 | /* the standard mdio_ctrl() function for usual MII-compliant hardware */ | ||
932 | static u16 mdio_ctrl_hw(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data) | ||
903 | { | 933 | { |
904 | u32 data_out = 0; | 934 | u32 data_out = 0; |
905 | unsigned int i; | 935 | unsigned int i; |
@@ -938,30 +968,83 @@ static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data) | |||
938 | return (u16)data_out; | 968 | return (u16)data_out; |
939 | } | 969 | } |
940 | 970 | ||
941 | static int mdio_read(struct net_device *netdev, int addr, int reg) | 971 | /* slightly tweaked mdio_ctrl() function for phy_82552_v specifics */ |
942 | { | 972 | static u16 mdio_ctrl_phy_82552_v(struct nic *nic, |
943 | return mdio_ctrl(netdev_priv(netdev), addr, mdi_read, reg, 0); | 973 | u32 addr, |
974 | u32 dir, | ||
975 | u32 reg, | ||
976 | u16 data) | ||
977 | { | ||
978 | if ((reg == MII_BMCR) && (dir == mdi_write)) { | ||
979 | if (data & (BMCR_ANRESTART | BMCR_ANENABLE)) { | ||
980 | u16 advert = mdio_read(nic->netdev, nic->mii.phy_id, | ||
981 | MII_ADVERTISE); | ||
982 | |||
983 | /* | ||
984 | * Workaround Si issue where sometimes the part will not | ||
985 | * autoneg to 100Mbps even when advertised. | ||
986 | */ | ||
987 | if (advert & ADVERTISE_100FULL) | ||
988 | data |= BMCR_SPEED100 | BMCR_FULLDPLX; | ||
989 | else if (advert & ADVERTISE_100HALF) | ||
990 | data |= BMCR_SPEED100; | ||
991 | } | ||
992 | } | ||
993 | return mdio_ctrl_hw(nic, addr, dir, reg, data); | ||
944 | } | 994 | } |
945 | 995 | ||
946 | static void mdio_write(struct net_device *netdev, int addr, int reg, int data) | 996 | /* Fully software-emulated mdio_ctrl() function for cards without |
947 | { | 997 | * MII-compliant PHYs. |
948 | struct nic *nic = netdev_priv(netdev); | 998 | * For now, this is mainly geared towards 80c24 support; in case of further |
949 | 999 | * requirements for other types (i82503, ...?) either extend this mechanism | |
950 | if ((nic->phy == phy_82552_v) && (reg == MII_BMCR) && | 1000 | * or split it, whichever is cleaner. |
951 | (data & (BMCR_ANRESTART | BMCR_ANENABLE))) { | 1001 | */ |
952 | u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE); | 1002 | static u16 mdio_ctrl_phy_mii_emulated(struct nic *nic, |
953 | 1003 | u32 addr, | |
954 | /* | 1004 | u32 dir, |
955 | * Workaround Si issue where sometimes the part will not | 1005 | u32 reg, |
956 | * autoneg to 100Mbps even when advertised. | 1006 | u16 data) |
957 | */ | 1007 | { |
958 | if (advert & ADVERTISE_100FULL) | 1008 | /* might need to allocate a netdev_priv'ed register array eventually |
959 | data |= BMCR_SPEED100 | BMCR_FULLDPLX; | 1009 | * to be able to record state changes, but for now |
960 | else if (advert & ADVERTISE_100HALF) | 1010 | * some fully hardcoded register handling ought to be ok I guess. */ |
961 | data |= BMCR_SPEED100; | 1011 | |
1012 | if (dir == mdi_read) { | ||
1013 | switch (reg) { | ||
1014 | case MII_BMCR: | ||
1015 | /* Auto-negotiation, right? */ | ||
1016 | return BMCR_ANENABLE | | ||
1017 | BMCR_FULLDPLX; | ||
1018 | case MII_BMSR: | ||
1019 | return BMSR_LSTATUS /* for mii_link_ok() */ | | ||
1020 | BMSR_ANEGCAPABLE | | ||
1021 | BMSR_10FULL; | ||
1022 | case MII_ADVERTISE: | ||
1023 | /* 80c24 is a "combo card" PHY, right? */ | ||
1024 | return ADVERTISE_10HALF | | ||
1025 | ADVERTISE_10FULL; | ||
1026 | default: | ||
1027 | DPRINTK(HW, DEBUG, | ||
1028 | "%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n", | ||
1029 | dir == mdi_read ? "READ" : "WRITE", addr, reg, data); | ||
1030 | return 0xFFFF; | ||
1031 | } | ||
1032 | } else { | ||
1033 | switch (reg) { | ||
1034 | default: | ||
1035 | DPRINTK(HW, DEBUG, | ||
1036 | "%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n", | ||
1037 | dir == mdi_read ? "READ" : "WRITE", addr, reg, data); | ||
1038 | return 0xFFFF; | ||
1039 | } | ||
962 | } | 1040 | } |
963 | 1041 | } | |
964 | mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data); | 1042 | static inline int e100_phy_supports_mii(struct nic *nic) |
1043 | { | ||
1044 | /* for now, just check it by comparing whether we | ||
1045 | are using MII software emulation. | ||
1046 | */ | ||
1047 | return (nic->mdio_ctrl != mdio_ctrl_phy_mii_emulated); | ||
965 | } | 1048 | } |
966 | 1049 | ||
967 | static void e100_get_defaults(struct nic *nic) | 1050 | static void e100_get_defaults(struct nic *nic) |
@@ -1013,7 +1096,8 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) | |||
1013 | config->standard_stat_counter = 0x1; /* 1=standard, 0=extended */ | 1096 | config->standard_stat_counter = 0x1; /* 1=standard, 0=extended */ |
1014 | config->rx_discard_short_frames = 0x1; /* 1=discard, 0=pass */ | 1097 | config->rx_discard_short_frames = 0x1; /* 1=discard, 0=pass */ |
1015 | config->tx_underrun_retry = 0x3; /* # of underrun retries */ | 1098 | config->tx_underrun_retry = 0x3; /* # of underrun retries */ |
1016 | config->mii_mode = 0x1; /* 1=MII mode, 0=503 mode */ | 1099 | if (e100_phy_supports_mii(nic)) |
1100 | config->mii_mode = 1; /* 1=MII mode, 0=i82503 mode */ | ||
1017 | config->pad10 = 0x6; | 1101 | config->pad10 = 0x6; |
1018 | config->no_source_addr_insertion = 0x1; /* 1=no, 0=yes */ | 1102 | config->no_source_addr_insertion = 0x1; /* 1=no, 0=yes */ |
1019 | config->preamble_length = 0x2; /* 0=1, 1=3, 2=7, 3=15 bytes */ | 1103 | config->preamble_length = 0x2; /* 0=1, 1=3, 2=7, 3=15 bytes */ |
@@ -1270,6 +1354,42 @@ static void e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb) | |||
1270 | offsetof(struct mem, dump_buf)); | 1354 | offsetof(struct mem, dump_buf)); |
1271 | } | 1355 | } |
1272 | 1356 | ||
1357 | static int e100_phy_check_without_mii(struct nic *nic) | ||
1358 | { | ||
1359 | u8 phy_type; | ||
1360 | int without_mii; | ||
1361 | |||
1362 | phy_type = (nic->eeprom[eeprom_phy_iface] >> 8) & 0x0f; | ||
1363 | |||
1364 | switch (phy_type) { | ||
1365 | case NoSuchPhy: /* Non-MII PHY; UNTESTED! */ | ||
1366 | case I82503: /* Non-MII PHY; UNTESTED! */ | ||
1367 | case S80C24: /* Non-MII PHY; tested and working */ | ||
1368 | /* paragraph from the FreeBSD driver, "FXP_PHY_80C24": | ||
1369 | * The Seeq 80c24 AutoDUPLEX(tm) Ethernet Interface Adapter | ||
1370 | * doesn't have a programming interface of any sort. The | ||
1371 | * media is sensed automatically based on how the link partner | ||
1372 | * is configured. This is, in essence, manual configuration. | ||
1373 | */ | ||
1374 | DPRINTK(PROBE, INFO, | ||
1375 | "found MII-less i82503 or 80c24 or other PHY\n"); | ||
1376 | |||
1377 | nic->mdio_ctrl = mdio_ctrl_phy_mii_emulated; | ||
1378 | nic->mii.phy_id = 0; /* is this ok for an MII-less PHY? */ | ||
1379 | |||
1380 | /* these might be needed for certain MII-less cards... | ||
1381 | * nic->flags |= ich; | ||
1382 | * nic->flags |= ich_10h_workaround; */ | ||
1383 | |||
1384 | without_mii = 1; | ||
1385 | break; | ||
1386 | default: | ||
1387 | without_mii = 0; | ||
1388 | break; | ||
1389 | } | ||
1390 | return without_mii; | ||
1391 | } | ||
1392 | |||
1273 | #define NCONFIG_AUTO_SWITCH 0x0080 | 1393 | #define NCONFIG_AUTO_SWITCH 0x0080 |
1274 | #define MII_NSC_CONG MII_RESV1 | 1394 | #define MII_NSC_CONG MII_RESV1 |
1275 | #define NSC_CONG_ENABLE 0x0100 | 1395 | #define NSC_CONG_ENABLE 0x0100 |
@@ -1290,9 +1410,21 @@ static int e100_phy_init(struct nic *nic) | |||
1290 | if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0)))) | 1410 | if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0)))) |
1291 | break; | 1411 | break; |
1292 | } | 1412 | } |
1293 | DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id); | 1413 | if (addr == 32) { |
1294 | if (addr == 32) | 1414 | /* uhoh, no PHY detected: check whether we seem to be some |
1295 | return -EAGAIN; | 1415 | * weird, rare variant which is *known* to not have any MII. |
1416 | * But do this AFTER MII checking only, since this does | ||
1417 | * lookup of EEPROM values which may easily be unreliable. */ | ||
1418 | if (e100_phy_check_without_mii(nic)) | ||
1419 | return 0; /* simply return and hope for the best */ | ||
1420 | else { | ||
1421 | /* for unknown cases log a fatal error */ | ||
1422 | DPRINTK(HW, ERR, | ||
1423 | "Failed to locate any known PHY, aborting.\n"); | ||
1424 | return -EAGAIN; | ||
1425 | } | ||
1426 | } else | ||
1427 | DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id); | ||
1296 | 1428 | ||
1297 | /* Isolate all the PHY ids */ | 1429 | /* Isolate all the PHY ids */ |
1298 | for (addr = 0; addr < 32; addr++) | 1430 | for (addr = 0; addr < 32; addr++) |
@@ -1320,6 +1452,9 @@ static int e100_phy_init(struct nic *nic) | |||
1320 | if (nic->phy == phy_82552_v) { | 1452 | if (nic->phy == phy_82552_v) { |
1321 | u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE); | 1453 | u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE); |
1322 | 1454 | ||
1455 | /* assign special tweaked mdio_ctrl() function */ | ||
1456 | nic->mdio_ctrl = mdio_ctrl_phy_82552_v; | ||
1457 | |||
1323 | /* Workaround Si not advertising flow-control during autoneg */ | 1458 | /* Workaround Si not advertising flow-control during autoneg */ |
1324 | advert |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; | 1459 | advert |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; |
1325 | mdio_write(netdev, nic->mii.phy_id, MII_ADVERTISE, advert); | 1460 | mdio_write(netdev, nic->mii.phy_id, MII_ADVERTISE, advert); |
@@ -2585,6 +2720,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, | |||
2585 | nic->netdev = netdev; | 2720 | nic->netdev = netdev; |
2586 | nic->pdev = pdev; | 2721 | nic->pdev = pdev; |
2587 | nic->msg_enable = (1 << debug) - 1; | 2722 | nic->msg_enable = (1 << debug) - 1; |
2723 | nic->mdio_ctrl = mdio_ctrl_hw; | ||
2588 | pci_set_drvdata(pdev, netdev); | 2724 | pci_set_drvdata(pdev, netdev); |
2589 | 2725 | ||
2590 | if ((err = pci_enable_device(pdev))) { | 2726 | if ((err = pci_enable_device(pdev))) { |
@@ -2822,12 +2958,13 @@ static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel | |||
2822 | struct net_device *netdev = pci_get_drvdata(pdev); | 2958 | struct net_device *netdev = pci_get_drvdata(pdev); |
2823 | struct nic *nic = netdev_priv(netdev); | 2959 | struct nic *nic = netdev_priv(netdev); |
2824 | 2960 | ||
2825 | /* Similar to calling e100_down(), but avoids adapter I/O. */ | ||
2826 | e100_close(netdev); | ||
2827 | |||
2828 | /* Detach; put netif into a state similar to hotplug unplug. */ | ||
2829 | napi_enable(&nic->napi); | ||
2830 | netif_device_detach(netdev); | 2961 | netif_device_detach(netdev); |
2962 | |||
2963 | if (state == pci_channel_io_perm_failure) | ||
2964 | return PCI_ERS_RESULT_DISCONNECT; | ||
2965 | |||
2966 | if (netif_running(netdev)) | ||
2967 | e100_down(nic); | ||
2831 | pci_disable_device(pdev); | 2968 | pci_disable_device(pdev); |
2832 | 2969 | ||
2833 | /* Request a slot reset. */ | 2970 | /* Request a slot reset. */ |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 05e87a59f1c6..8d36743c8140 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -2998,7 +2998,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, | |||
2998 | size -= 4; | 2998 | size -= 4; |
2999 | 2999 | ||
3000 | buffer_info->length = size; | 3000 | buffer_info->length = size; |
3001 | buffer_info->dma = map[0] + offset; | 3001 | buffer_info->dma = skb_shinfo(skb)->dma_head + offset; |
3002 | buffer_info->time_stamp = jiffies; | 3002 | buffer_info->time_stamp = jiffies; |
3003 | buffer_info->next_to_watch = i; | 3003 | buffer_info->next_to_watch = i; |
3004 | 3004 | ||
@@ -3039,7 +3039,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, | |||
3039 | size -= 4; | 3039 | size -= 4; |
3040 | 3040 | ||
3041 | buffer_info->length = size; | 3041 | buffer_info->length = size; |
3042 | buffer_info->dma = map[f + 1] + offset; | 3042 | buffer_info->dma = map[f] + offset; |
3043 | buffer_info->time_stamp = jiffies; | 3043 | buffer_info->time_stamp = jiffies; |
3044 | buffer_info->next_to_watch = i; | 3044 | buffer_info->next_to_watch = i; |
3045 | 3045 | ||
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index c4b3f4fe91ae..b53b40ba88a8 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -71,6 +71,7 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw); | |||
71 | static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); | 71 | static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); |
72 | static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); | 72 | static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); |
73 | static s32 e1000_led_on_82574(struct e1000_hw *hw); | 73 | static s32 e1000_led_on_82574(struct e1000_hw *hw); |
74 | static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); | ||
74 | 75 | ||
75 | /** | 76 | /** |
76 | * e1000_init_phy_params_82571 - Init PHY func ptrs. | 77 | * e1000_init_phy_params_82571 - Init PHY func ptrs. |
@@ -212,6 +213,9 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) | |||
212 | struct e1000_hw *hw = &adapter->hw; | 213 | struct e1000_hw *hw = &adapter->hw; |
213 | struct e1000_mac_info *mac = &hw->mac; | 214 | struct e1000_mac_info *mac = &hw->mac; |
214 | struct e1000_mac_operations *func = &mac->ops; | 215 | struct e1000_mac_operations *func = &mac->ops; |
216 | u32 swsm = 0; | ||
217 | u32 swsm2 = 0; | ||
218 | bool force_clear_smbi = false; | ||
215 | 219 | ||
216 | /* Set media type */ | 220 | /* Set media type */ |
217 | switch (adapter->pdev->device) { | 221 | switch (adapter->pdev->device) { |
@@ -276,6 +280,50 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) | |||
276 | break; | 280 | break; |
277 | } | 281 | } |
278 | 282 | ||
283 | /* | ||
284 | * Ensure that the inter-port SWSM.SMBI lock bit is clear before | ||
285 | * first NVM or PHY acess. This should be done for single-port | ||
286 | * devices, and for one port only on dual-port devices so that | ||
287 | * for those devices we can still use the SMBI lock to synchronize | ||
288 | * inter-port accesses to the PHY & NVM. | ||
289 | */ | ||
290 | switch (hw->mac.type) { | ||
291 | case e1000_82571: | ||
292 | case e1000_82572: | ||
293 | swsm2 = er32(SWSM2); | ||
294 | |||
295 | if (!(swsm2 & E1000_SWSM2_LOCK)) { | ||
296 | /* Only do this for the first interface on this card */ | ||
297 | ew32(SWSM2, | ||
298 | swsm2 | E1000_SWSM2_LOCK); | ||
299 | force_clear_smbi = true; | ||
300 | } else | ||
301 | force_clear_smbi = false; | ||
302 | break; | ||
303 | default: | ||
304 | force_clear_smbi = true; | ||
305 | break; | ||
306 | } | ||
307 | |||
308 | if (force_clear_smbi) { | ||
309 | /* Make sure SWSM.SMBI is clear */ | ||
310 | swsm = er32(SWSM); | ||
311 | if (swsm & E1000_SWSM_SMBI) { | ||
312 | /* This bit should not be set on a first interface, and | ||
313 | * indicates that the bootagent or EFI code has | ||
314 | * improperly left this bit enabled | ||
315 | */ | ||
316 | hw_dbg(hw, "Please update your 82571 Bootagent\n"); | ||
317 | } | ||
318 | ew32(SWSM, swsm & ~E1000_SWSM_SMBI); | ||
319 | } | ||
320 | |||
321 | /* | ||
322 | * Initialze device specific counter of SMBI acquisition | ||
323 | * timeouts. | ||
324 | */ | ||
325 | hw->dev_spec.e82571.smb_counter = 0; | ||
326 | |||
279 | return 0; | 327 | return 0; |
280 | } | 328 | } |
281 | 329 | ||
@@ -413,11 +461,37 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) | |||
413 | static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) | 461 | static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) |
414 | { | 462 | { |
415 | u32 swsm; | 463 | u32 swsm; |
416 | s32 timeout = hw->nvm.word_size + 1; | 464 | s32 sw_timeout = hw->nvm.word_size + 1; |
465 | s32 fw_timeout = hw->nvm.word_size + 1; | ||
417 | s32 i = 0; | 466 | s32 i = 0; |
418 | 467 | ||
468 | /* | ||
469 | * If we have timedout 3 times on trying to acquire | ||
470 | * the inter-port SMBI semaphore, there is old code | ||
471 | * operating on the other port, and it is not | ||
472 | * releasing SMBI. Modify the number of times that | ||
473 | * we try for the semaphore to interwork with this | ||
474 | * older code. | ||
475 | */ | ||
476 | if (hw->dev_spec.e82571.smb_counter > 2) | ||
477 | sw_timeout = 1; | ||
478 | |||
479 | /* Get the SW semaphore */ | ||
480 | while (i < sw_timeout) { | ||
481 | swsm = er32(SWSM); | ||
482 | if (!(swsm & E1000_SWSM_SMBI)) | ||
483 | break; | ||
484 | |||
485 | udelay(50); | ||
486 | i++; | ||
487 | } | ||
488 | |||
489 | if (i == sw_timeout) { | ||
490 | hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n"); | ||
491 | hw->dev_spec.e82571.smb_counter++; | ||
492 | } | ||
419 | /* Get the FW semaphore. */ | 493 | /* Get the FW semaphore. */ |
420 | for (i = 0; i < timeout; i++) { | 494 | for (i = 0; i < fw_timeout; i++) { |
421 | swsm = er32(SWSM); | 495 | swsm = er32(SWSM); |
422 | ew32(SWSM, swsm | E1000_SWSM_SWESMBI); | 496 | ew32(SWSM, swsm | E1000_SWSM_SWESMBI); |
423 | 497 | ||
@@ -428,9 +502,9 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) | |||
428 | udelay(50); | 502 | udelay(50); |
429 | } | 503 | } |
430 | 504 | ||
431 | if (i == timeout) { | 505 | if (i == fw_timeout) { |
432 | /* Release semaphores */ | 506 | /* Release semaphores */ |
433 | e1000e_put_hw_semaphore(hw); | 507 | e1000_put_hw_semaphore_82571(hw); |
434 | hw_dbg(hw, "Driver can't access the NVM\n"); | 508 | hw_dbg(hw, "Driver can't access the NVM\n"); |
435 | return -E1000_ERR_NVM; | 509 | return -E1000_ERR_NVM; |
436 | } | 510 | } |
@@ -449,9 +523,7 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) | |||
449 | u32 swsm; | 523 | u32 swsm; |
450 | 524 | ||
451 | swsm = er32(SWSM); | 525 | swsm = er32(SWSM); |
452 | 526 | swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); | |
453 | swsm &= ~E1000_SWSM_SWESMBI; | ||
454 | |||
455 | ew32(SWSM, swsm); | 527 | ew32(SWSM, swsm); |
456 | } | 528 | } |
457 | 529 | ||
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 674a47e43034..8890c97e1120 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h | |||
@@ -376,6 +376,8 @@ | |||
376 | #define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ | 376 | #define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ |
377 | #define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ | 377 | #define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ |
378 | 378 | ||
379 | #define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */ | ||
380 | |||
379 | /* Interrupt Cause Read */ | 381 | /* Interrupt Cause Read */ |
380 | #define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ | 382 | #define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ |
381 | #define E1000_ICR_LSC 0x00000004 /* Link Status Change */ | 383 | #define E1000_ICR_LSC 0x00000004 /* Link Status Change */ |
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 3d6435617527..1bf4d2a5d34f 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c | |||
@@ -167,6 +167,15 @@ static int e1000_get_settings(struct net_device *netdev, | |||
167 | 167 | ||
168 | ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) || | 168 | ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) || |
169 | hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE; | 169 | hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE; |
170 | |||
171 | /* MDI-X => 2; MDI =>1; Invalid =>0 */ | ||
172 | if ((hw->phy.media_type == e1000_media_type_copper) && | ||
173 | !hw->mac.get_link_status) | ||
174 | ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X : | ||
175 | ETH_TP_MDI; | ||
176 | else | ||
177 | ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID; | ||
178 | |||
170 | return 0; | 179 | return 0; |
171 | } | 180 | } |
172 | 181 | ||
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index fce3f0529e4c..163c1c0cfee7 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h | |||
@@ -214,6 +214,7 @@ enum e1e_registers { | |||
214 | E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */ | 214 | E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */ |
215 | E1000_SWSM = 0x05B50, /* SW Semaphore */ | 215 | E1000_SWSM = 0x05B50, /* SW Semaphore */ |
216 | E1000_FWSM = 0x05B54, /* FW Semaphore */ | 216 | E1000_FWSM = 0x05B54, /* FW Semaphore */ |
217 | E1000_SWSM2 = 0x05B58, /* Driver-only SW semaphore */ | ||
217 | E1000_HICR = 0x08F00, /* Host Interface Control */ | 218 | E1000_HICR = 0x08F00, /* Host Interface Control */ |
218 | }; | 219 | }; |
219 | 220 | ||
@@ -883,6 +884,7 @@ struct e1000_fc_info { | |||
883 | struct e1000_dev_spec_82571 { | 884 | struct e1000_dev_spec_82571 { |
884 | bool laa_is_present; | 885 | bool laa_is_present; |
885 | bool alt_mac_addr_is_present; | 886 | bool alt_mac_addr_is_present; |
887 | u32 smb_counter; | ||
886 | }; | 888 | }; |
887 | 889 | ||
888 | struct e1000_shadow_ram { | 890 | struct e1000_shadow_ram { |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 38694c79edcc..677f60490f67 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -2256,8 +2256,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) | |||
2256 | ew32(TARC(1), tarc); | 2256 | ew32(TARC(1), tarc); |
2257 | } | 2257 | } |
2258 | 2258 | ||
2259 | e1000e_config_collision_dist(hw); | ||
2260 | |||
2261 | /* Setup Transmit Descriptor Settings for eop descriptor */ | 2259 | /* Setup Transmit Descriptor Settings for eop descriptor */ |
2262 | adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS; | 2260 | adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS; |
2263 | 2261 | ||
@@ -2270,6 +2268,8 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) | |||
2270 | 2268 | ||
2271 | ew32(TCTL, tctl); | 2269 | ew32(TCTL, tctl); |
2272 | 2270 | ||
2271 | e1000e_config_collision_dist(hw); | ||
2272 | |||
2273 | adapter->tx_queue_len = adapter->netdev->tx_queue_len; | 2273 | adapter->tx_queue_len = adapter->netdev->tx_queue_len; |
2274 | } | 2274 | } |
2275 | 2275 | ||
@@ -3916,7 +3916,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, | |||
3916 | buffer_info->length = size; | 3916 | buffer_info->length = size; |
3917 | buffer_info->time_stamp = jiffies; | 3917 | buffer_info->time_stamp = jiffies; |
3918 | buffer_info->next_to_watch = i; | 3918 | buffer_info->next_to_watch = i; |
3919 | buffer_info->dma = map[0] + offset; | 3919 | buffer_info->dma = skb_shinfo(skb)->dma_head + offset; |
3920 | count++; | 3920 | count++; |
3921 | 3921 | ||
3922 | len -= size; | 3922 | len -= size; |
@@ -3947,7 +3947,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, | |||
3947 | buffer_info->length = size; | 3947 | buffer_info->length = size; |
3948 | buffer_info->time_stamp = jiffies; | 3948 | buffer_info->time_stamp = jiffies; |
3949 | buffer_info->next_to_watch = i; | 3949 | buffer_info->next_to_watch = i; |
3950 | buffer_info->dma = map[f + 1] + offset; | 3950 | buffer_info->dma = map[f] + offset; |
3951 | 3951 | ||
3952 | len -= size; | 3952 | len -= size; |
3953 | offset += size; | 3953 | offset += size; |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 958b2879da48..ea17319624aa 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -3139,8 +3139,7 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter, | |||
3139 | /* set time_stamp *before* dma to help avoid a possible race */ | 3139 | /* set time_stamp *before* dma to help avoid a possible race */ |
3140 | buffer_info->time_stamp = jiffies; | 3140 | buffer_info->time_stamp = jiffies; |
3141 | buffer_info->next_to_watch = i; | 3141 | buffer_info->next_to_watch = i; |
3142 | buffer_info->dma = map[count]; | 3142 | buffer_info->dma = skb_shinfo(skb)->dma_head; |
3143 | count++; | ||
3144 | 3143 | ||
3145 | for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { | 3144 | for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { |
3146 | struct skb_frag_struct *frag; | 3145 | struct skb_frag_struct *frag; |
@@ -3164,7 +3163,7 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter, | |||
3164 | tx_ring->buffer_info[i].skb = skb; | 3163 | tx_ring->buffer_info[i].skb = skb; |
3165 | tx_ring->buffer_info[first].next_to_watch = i; | 3164 | tx_ring->buffer_info[first].next_to_watch = i; |
3166 | 3165 | ||
3167 | return count; | 3166 | return count + 1; |
3168 | } | 3167 | } |
3169 | 3168 | ||
3170 | static inline void igb_tx_queue_adv(struct igb_adapter *adapter, | 3169 | static inline void igb_tx_queue_adv(struct igb_adapter *adapter, |
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 5f7ba1a4990b..22aadb7884fa 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c | |||
@@ -2119,8 +2119,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, | |||
2119 | /* set time_stamp *before* dma to help avoid a possible race */ | 2119 | /* set time_stamp *before* dma to help avoid a possible race */ |
2120 | buffer_info->time_stamp = jiffies; | 2120 | buffer_info->time_stamp = jiffies; |
2121 | buffer_info->next_to_watch = i; | 2121 | buffer_info->next_to_watch = i; |
2122 | buffer_info->dma = map[count]; | 2122 | buffer_info->dma = skb_shinfo(skb)->dma_head; |
2123 | count++; | ||
2124 | 2123 | ||
2125 | for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { | 2124 | for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { |
2126 | struct skb_frag_struct *frag; | 2125 | struct skb_frag_struct *frag; |
@@ -2144,7 +2143,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, | |||
2144 | tx_ring->buffer_info[i].skb = skb; | 2143 | tx_ring->buffer_info[i].skb = skb; |
2145 | tx_ring->buffer_info[first].next_to_watch = i; | 2144 | tx_ring->buffer_info[first].next_to_watch = i; |
2146 | 2145 | ||
2147 | return count; | 2146 | return count + 1; |
2148 | } | 2147 | } |
2149 | 2148 | ||
2150 | static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter, | 2149 | static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter, |
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 6eb7f37a113b..9c897cf86b9f 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c | |||
@@ -1300,7 +1300,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, | |||
1300 | buffer_info->length = size; | 1300 | buffer_info->length = size; |
1301 | WARN_ON(buffer_info->dma != 0); | 1301 | WARN_ON(buffer_info->dma != 0); |
1302 | buffer_info->time_stamp = jiffies; | 1302 | buffer_info->time_stamp = jiffies; |
1303 | buffer_info->dma = map[0] + offset; | 1303 | buffer_info->dma = skb_shinfo(skb)->dma_head + offset; |
1304 | pci_map_single(adapter->pdev, | 1304 | pci_map_single(adapter->pdev, |
1305 | skb->data + offset, | 1305 | skb->data + offset, |
1306 | size, | 1306 | size, |
@@ -1340,7 +1340,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, | |||
1340 | 1340 | ||
1341 | buffer_info->length = size; | 1341 | buffer_info->length = size; |
1342 | buffer_info->time_stamp = jiffies; | 1342 | buffer_info->time_stamp = jiffies; |
1343 | buffer_info->dma = map[f + 1] + offset; | 1343 | buffer_info->dma = map[f] + offset; |
1344 | buffer_info->next_to_watch = 0; | 1344 | buffer_info->next_to_watch = 0; |
1345 | 1345 | ||
1346 | len -= size; | 1346 | len -= size; |
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index d5939de8ba28..3c3bf1f07b81 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c | |||
@@ -280,7 +280,9 @@ out_noddp_unmap: | |||
280 | * | 280 | * |
281 | * This checks ddp status. | 281 | * This checks ddp status. |
282 | * | 282 | * |
283 | * Returns : 0 for success and skb will not be delivered to ULD | 283 | * Returns : < 0 indicates an error or not a FCiE ddp, 0 indicates |
284 | * not passing the skb to ULD, > 0 indicates is the length of data | ||
285 | * being ddped. | ||
284 | */ | 286 | */ |
285 | int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, | 287 | int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, |
286 | union ixgbe_adv_rx_desc *rx_desc, | 288 | union ixgbe_adv_rx_desc *rx_desc, |
@@ -334,6 +336,8 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, | |||
334 | /* return 0 to bypass going to ULD for DDPed data */ | 336 | /* return 0 to bypass going to ULD for DDPed data */ |
335 | if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_DDP) | 337 | if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_DDP) |
336 | rc = 0; | 338 | rc = 0; |
339 | else | ||
340 | rc = ddp->len; | ||
337 | } | 341 | } |
338 | 342 | ||
339 | ddp_out: | 343 | ddp_out: |
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h index b7f9b63aa49f..c5b50026a897 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/drivers/net/ixgbe/ixgbe_fcoe.h | |||
@@ -28,6 +28,7 @@ | |||
28 | #ifndef _IXGBE_FCOE_H | 28 | #ifndef _IXGBE_FCOE_H |
29 | #define _IXGBE_FCOE_H | 29 | #define _IXGBE_FCOE_H |
30 | 30 | ||
31 | #include <scsi/fc/fc_fs.h> | ||
31 | #include <scsi/fc/fc_fcoe.h> | 32 | #include <scsi/fc/fc_fcoe.h> |
32 | 33 | ||
33 | /* shift bits within STAT fo FCSTAT */ | 34 | /* shift bits within STAT fo FCSTAT */ |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index d36003cbb6d4..a551a96ce676 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -293,12 +293,24 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, | |||
293 | 293 | ||
294 | if (cleaned && skb) { | 294 | if (cleaned && skb) { |
295 | unsigned int segs, bytecount; | 295 | unsigned int segs, bytecount; |
296 | unsigned int hlen = skb_headlen(skb); | ||
296 | 297 | ||
297 | /* gso_segs is currently only valid for tcp */ | 298 | /* gso_segs is currently only valid for tcp */ |
298 | segs = skb_shinfo(skb)->gso_segs ?: 1; | 299 | segs = skb_shinfo(skb)->gso_segs ?: 1; |
300 | #ifdef IXGBE_FCOE | ||
301 | /* adjust for FCoE Sequence Offload */ | ||
302 | if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) | ||
303 | && (skb->protocol == htons(ETH_P_FCOE)) && | ||
304 | skb_is_gso(skb)) { | ||
305 | hlen = skb_transport_offset(skb) + | ||
306 | sizeof(struct fc_frame_header) + | ||
307 | sizeof(struct fcoe_crc_eof); | ||
308 | segs = DIV_ROUND_UP(skb->len - hlen, | ||
309 | skb_shinfo(skb)->gso_size); | ||
310 | } | ||
311 | #endif /* IXGBE_FCOE */ | ||
299 | /* multiply data chunks by size of headers */ | 312 | /* multiply data chunks by size of headers */ |
300 | bytecount = ((segs - 1) * skb_headlen(skb)) + | 313 | bytecount = ((segs - 1) * hlen) + skb->len; |
301 | skb->len; | ||
302 | total_packets += segs; | 314 | total_packets += segs; |
303 | total_bytes += bytecount; | 315 | total_bytes += bytecount; |
304 | } | 316 | } |
@@ -683,6 +695,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, | |||
683 | bool cleaned = false; | 695 | bool cleaned = false; |
684 | int cleaned_count = 0; | 696 | int cleaned_count = 0; |
685 | unsigned int total_rx_bytes = 0, total_rx_packets = 0; | 697 | unsigned int total_rx_bytes = 0, total_rx_packets = 0; |
698 | #ifdef IXGBE_FCOE | ||
699 | int ddp_bytes = 0; | ||
700 | #endif /* IXGBE_FCOE */ | ||
686 | 701 | ||
687 | i = rx_ring->next_to_clean; | 702 | i = rx_ring->next_to_clean; |
688 | rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i); | 703 | rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i); |
@@ -793,9 +808,11 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, | |||
793 | skb->protocol = eth_type_trans(skb, adapter->netdev); | 808 | skb->protocol = eth_type_trans(skb, adapter->netdev); |
794 | #ifdef IXGBE_FCOE | 809 | #ifdef IXGBE_FCOE |
795 | /* if ddp, not passing to ULD unless for FCP_RSP or error */ | 810 | /* if ddp, not passing to ULD unless for FCP_RSP or error */ |
796 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) | 811 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { |
797 | if (!ixgbe_fcoe_ddp(adapter, rx_desc, skb)) | 812 | ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb); |
813 | if (!ddp_bytes) | ||
798 | goto next_desc; | 814 | goto next_desc; |
815 | } | ||
799 | #endif /* IXGBE_FCOE */ | 816 | #endif /* IXGBE_FCOE */ |
800 | ixgbe_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc); | 817 | ixgbe_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc); |
801 | 818 | ||
@@ -821,6 +838,21 @@ next_desc: | |||
821 | if (cleaned_count) | 838 | if (cleaned_count) |
822 | ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count); | 839 | ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count); |
823 | 840 | ||
841 | #ifdef IXGBE_FCOE | ||
842 | /* include DDPed FCoE data */ | ||
843 | if (ddp_bytes > 0) { | ||
844 | unsigned int mss; | ||
845 | |||
846 | mss = adapter->netdev->mtu - sizeof(struct fcoe_hdr) - | ||
847 | sizeof(struct fc_frame_header) - | ||
848 | sizeof(struct fcoe_crc_eof); | ||
849 | if (mss > 512) | ||
850 | mss &= ~511; | ||
851 | total_rx_bytes += ddp_bytes; | ||
852 | total_rx_packets += DIV_ROUND_UP(ddp_bytes, mss); | ||
853 | } | ||
854 | #endif /* IXGBE_FCOE */ | ||
855 | |||
824 | rx_ring->total_packets += total_rx_packets; | 856 | rx_ring->total_packets += total_rx_packets; |
825 | rx_ring->total_bytes += total_rx_bytes; | 857 | rx_ring->total_bytes += total_rx_bytes; |
826 | adapter->net_stats.rx_bytes += total_rx_bytes; | 858 | adapter->net_stats.rx_bytes += total_rx_bytes; |
@@ -4837,7 +4869,7 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, | |||
4837 | size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); | 4869 | size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); |
4838 | 4870 | ||
4839 | tx_buffer_info->length = size; | 4871 | tx_buffer_info->length = size; |
4840 | tx_buffer_info->dma = map[0] + offset; | 4872 | tx_buffer_info->dma = skb_shinfo(skb)->dma_head + offset; |
4841 | tx_buffer_info->time_stamp = jiffies; | 4873 | tx_buffer_info->time_stamp = jiffies; |
4842 | tx_buffer_info->next_to_watch = i; | 4874 | tx_buffer_info->next_to_watch = i; |
4843 | 4875 | ||
@@ -4869,7 +4901,7 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, | |||
4869 | size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); | 4901 | size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); |
4870 | 4902 | ||
4871 | tx_buffer_info->length = size; | 4903 | tx_buffer_info->length = size; |
4872 | tx_buffer_info->dma = map[f + 1] + offset; | 4904 | tx_buffer_info->dma = map[f] + offset; |
4873 | tx_buffer_info->time_stamp = jiffies; | 4905 | tx_buffer_info->time_stamp = jiffies; |
4874 | tx_buffer_info->next_to_watch = i; | 4906 | tx_buffer_info->next_to_watch = i; |
4875 | 4907 | ||
diff --git a/drivers/net/ks8842.c b/drivers/net/ks8842.c new file mode 100644 index 000000000000..39b0aea2aab3 --- /dev/null +++ b/drivers/net/ks8842.c | |||
@@ -0,0 +1,732 @@ | |||
1 | /* | ||
2 | * ks8842_main.c timberdale KS8842 ethernet driver | ||
3 | * Copyright (c) 2009 Intel Corporation | ||
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 version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | |||
19 | /* Supports: | ||
20 | * The Micrel KS8842 behind the timberdale FPGA | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/ethtool.h> | ||
29 | |||
30 | #define DRV_NAME "ks8842" | ||
31 | |||
32 | /* Timberdale specific Registers */ | ||
33 | #define REG_TIMB_RST 0x1c | ||
34 | |||
35 | /* KS8842 registers */ | ||
36 | |||
37 | #define REG_SELECT_BANK 0x0e | ||
38 | |||
39 | /* bank 0 registers */ | ||
40 | #define REG_QRFCR 0x04 | ||
41 | |||
42 | /* bank 2 registers */ | ||
43 | #define REG_MARL 0x00 | ||
44 | #define REG_MARM 0x02 | ||
45 | #define REG_MARH 0x04 | ||
46 | |||
47 | /* bank 3 registers */ | ||
48 | #define REG_GRR 0x06 | ||
49 | |||
50 | /* bank 16 registers */ | ||
51 | #define REG_TXCR 0x00 | ||
52 | #define REG_TXSR 0x02 | ||
53 | #define REG_RXCR 0x04 | ||
54 | #define REG_TXMIR 0x08 | ||
55 | #define REG_RXMIR 0x0A | ||
56 | |||
57 | /* bank 17 registers */ | ||
58 | #define REG_TXQCR 0x00 | ||
59 | #define REG_RXQCR 0x02 | ||
60 | #define REG_TXFDPR 0x04 | ||
61 | #define REG_RXFDPR 0x06 | ||
62 | #define REG_QMU_DATA_LO 0x08 | ||
63 | #define REG_QMU_DATA_HI 0x0A | ||
64 | |||
65 | /* bank 18 registers */ | ||
66 | #define REG_IER 0x00 | ||
67 | #define IRQ_LINK_CHANGE 0x8000 | ||
68 | #define IRQ_TX 0x4000 | ||
69 | #define IRQ_RX 0x2000 | ||
70 | #define IRQ_RX_OVERRUN 0x0800 | ||
71 | #define IRQ_TX_STOPPED 0x0200 | ||
72 | #define IRQ_RX_STOPPED 0x0100 | ||
73 | #define IRQ_RX_ERROR 0x0080 | ||
74 | #define ENABLED_IRQS (IRQ_LINK_CHANGE | IRQ_TX | IRQ_RX | IRQ_RX_STOPPED | \ | ||
75 | IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR) | ||
76 | #define REG_ISR 0x02 | ||
77 | #define REG_RXSR 0x04 | ||
78 | #define RXSR_VALID 0x8000 | ||
79 | #define RXSR_BROADCAST 0x80 | ||
80 | #define RXSR_MULTICAST 0x40 | ||
81 | #define RXSR_UNICAST 0x20 | ||
82 | #define RXSR_FRAMETYPE 0x08 | ||
83 | #define RXSR_TOO_LONG 0x04 | ||
84 | #define RXSR_RUNT 0x02 | ||
85 | #define RXSR_CRC_ERROR 0x01 | ||
86 | #define RXSR_ERROR (RXSR_TOO_LONG | RXSR_RUNT | RXSR_CRC_ERROR) | ||
87 | |||
88 | /* bank 32 registers */ | ||
89 | #define REG_SW_ID_AND_ENABLE 0x00 | ||
90 | #define REG_SGCR1 0x02 | ||
91 | #define REG_SGCR2 0x04 | ||
92 | #define REG_SGCR3 0x06 | ||
93 | |||
94 | /* bank 39 registers */ | ||
95 | #define REG_MACAR1 0x00 | ||
96 | #define REG_MACAR2 0x02 | ||
97 | #define REG_MACAR3 0x04 | ||
98 | |||
99 | /* bank 45 registers */ | ||
100 | #define REG_P1MBCR 0x00 | ||
101 | #define REG_P1MBSR 0x02 | ||
102 | |||
103 | /* bank 46 registers */ | ||
104 | #define REG_P2MBCR 0x00 | ||
105 | #define REG_P2MBSR 0x02 | ||
106 | |||
107 | /* bank 48 registers */ | ||
108 | #define REG_P1CR2 0x02 | ||
109 | |||
110 | /* bank 49 registers */ | ||
111 | #define REG_P1CR4 0x02 | ||
112 | #define REG_P1SR 0x04 | ||
113 | |||
114 | struct ks8842_adapter { | ||
115 | void __iomem *hw_addr; | ||
116 | int irq; | ||
117 | struct tasklet_struct tasklet; | ||
118 | spinlock_t lock; /* spinlock to be interrupt safe */ | ||
119 | struct platform_device *pdev; | ||
120 | }; | ||
121 | |||
122 | static inline void ks8842_select_bank(struct ks8842_adapter *adapter, u16 bank) | ||
123 | { | ||
124 | iowrite16(bank, adapter->hw_addr + REG_SELECT_BANK); | ||
125 | } | ||
126 | |||
127 | static inline void ks8842_write8(struct ks8842_adapter *adapter, u16 bank, | ||
128 | u8 value, int offset) | ||
129 | { | ||
130 | ks8842_select_bank(adapter, bank); | ||
131 | iowrite8(value, adapter->hw_addr + offset); | ||
132 | } | ||
133 | |||
134 | static inline void ks8842_write16(struct ks8842_adapter *adapter, u16 bank, | ||
135 | u16 value, int offset) | ||
136 | { | ||
137 | ks8842_select_bank(adapter, bank); | ||
138 | iowrite16(value, adapter->hw_addr + offset); | ||
139 | } | ||
140 | |||
141 | static inline void ks8842_enable_bits(struct ks8842_adapter *adapter, u16 bank, | ||
142 | u16 bits, int offset) | ||
143 | { | ||
144 | u16 reg; | ||
145 | ks8842_select_bank(adapter, bank); | ||
146 | reg = ioread16(adapter->hw_addr + offset); | ||
147 | reg |= bits; | ||
148 | iowrite16(reg, adapter->hw_addr + offset); | ||
149 | } | ||
150 | |||
151 | static inline void ks8842_clear_bits(struct ks8842_adapter *adapter, u16 bank, | ||
152 | u16 bits, int offset) | ||
153 | { | ||
154 | u16 reg; | ||
155 | ks8842_select_bank(adapter, bank); | ||
156 | reg = ioread16(adapter->hw_addr + offset); | ||
157 | reg &= ~bits; | ||
158 | iowrite16(reg, adapter->hw_addr + offset); | ||
159 | } | ||
160 | |||
161 | static inline void ks8842_write32(struct ks8842_adapter *adapter, u16 bank, | ||
162 | u32 value, int offset) | ||
163 | { | ||
164 | ks8842_select_bank(adapter, bank); | ||
165 | iowrite32(value, adapter->hw_addr + offset); | ||
166 | } | ||
167 | |||
168 | static inline u8 ks8842_read8(struct ks8842_adapter *adapter, u16 bank, | ||
169 | int offset) | ||
170 | { | ||
171 | ks8842_select_bank(adapter, bank); | ||
172 | return ioread8(adapter->hw_addr + offset); | ||
173 | } | ||
174 | |||
175 | static inline u16 ks8842_read16(struct ks8842_adapter *adapter, u16 bank, | ||
176 | int offset) | ||
177 | { | ||
178 | ks8842_select_bank(adapter, bank); | ||
179 | return ioread16(adapter->hw_addr + offset); | ||
180 | } | ||
181 | |||
182 | static inline u32 ks8842_read32(struct ks8842_adapter *adapter, u16 bank, | ||
183 | int offset) | ||
184 | { | ||
185 | ks8842_select_bank(adapter, bank); | ||
186 | return ioread32(adapter->hw_addr + offset); | ||
187 | } | ||
188 | |||
189 | static void ks8842_reset(struct ks8842_adapter *adapter) | ||
190 | { | ||
191 | /* The KS8842 goes haywire when doing softare reset | ||
192 | * a work around in the timberdale IP is implemented to | ||
193 | * do a hardware reset instead | ||
194 | ks8842_write16(adapter, 3, 1, REG_GRR); | ||
195 | msleep(10); | ||
196 | iowrite16(0, adapter->hw_addr + REG_GRR); | ||
197 | */ | ||
198 | iowrite16(32, adapter->hw_addr + REG_SELECT_BANK); | ||
199 | iowrite32(0x1, adapter->hw_addr + REG_TIMB_RST); | ||
200 | msleep(20); | ||
201 | } | ||
202 | |||
203 | static void ks8842_update_link_status(struct net_device *netdev, | ||
204 | struct ks8842_adapter *adapter) | ||
205 | { | ||
206 | /* check the status of the link */ | ||
207 | if (ks8842_read16(adapter, 45, REG_P1MBSR) & 0x4) { | ||
208 | netif_carrier_on(netdev); | ||
209 | netif_wake_queue(netdev); | ||
210 | } else { | ||
211 | netif_stop_queue(netdev); | ||
212 | netif_carrier_off(netdev); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | static void ks8842_enable_tx(struct ks8842_adapter *adapter) | ||
217 | { | ||
218 | ks8842_enable_bits(adapter, 16, 0x01, REG_TXCR); | ||
219 | } | ||
220 | |||
221 | static void ks8842_disable_tx(struct ks8842_adapter *adapter) | ||
222 | { | ||
223 | ks8842_clear_bits(adapter, 16, 0x01, REG_TXCR); | ||
224 | } | ||
225 | |||
226 | static void ks8842_enable_rx(struct ks8842_adapter *adapter) | ||
227 | { | ||
228 | ks8842_enable_bits(adapter, 16, 0x01, REG_RXCR); | ||
229 | } | ||
230 | |||
231 | static void ks8842_disable_rx(struct ks8842_adapter *adapter) | ||
232 | { | ||
233 | ks8842_clear_bits(adapter, 16, 0x01, REG_RXCR); | ||
234 | } | ||
235 | |||
236 | static void ks8842_reset_hw(struct ks8842_adapter *adapter) | ||
237 | { | ||
238 | /* reset the HW */ | ||
239 | ks8842_reset(adapter); | ||
240 | |||
241 | /* Enable QMU Transmit flow control / transmit padding / Transmit CRC */ | ||
242 | ks8842_write16(adapter, 16, 0x000E, REG_TXCR); | ||
243 | |||
244 | /* enable the receiver, uni + multi + broadcast + flow ctrl | ||
245 | + crc strip */ | ||
246 | ks8842_write16(adapter, 16, 0x8 | 0x20 | 0x40 | 0x80 | 0x400, | ||
247 | REG_RXCR); | ||
248 | |||
249 | /* TX frame pointer autoincrement */ | ||
250 | ks8842_write16(adapter, 17, 0x4000, REG_TXFDPR); | ||
251 | |||
252 | /* RX frame pointer autoincrement */ | ||
253 | ks8842_write16(adapter, 17, 0x4000, REG_RXFDPR); | ||
254 | |||
255 | /* RX 2 kb high watermark */ | ||
256 | ks8842_write16(adapter, 0, 0x1000, REG_QRFCR); | ||
257 | |||
258 | /* aggresive back off in half duplex */ | ||
259 | ks8842_enable_bits(adapter, 32, 1 << 8, REG_SGCR1); | ||
260 | |||
261 | /* enable no excessive collison drop */ | ||
262 | ks8842_enable_bits(adapter, 32, 1 << 3, REG_SGCR2); | ||
263 | |||
264 | /* Enable port 1 force flow control / back pressure / transmit / recv */ | ||
265 | ks8842_write16(adapter, 48, 0x1E07, REG_P1CR2); | ||
266 | |||
267 | /* restart port auto-negotiation */ | ||
268 | ks8842_enable_bits(adapter, 49, 1 << 13, REG_P1CR4); | ||
269 | /* only advertise 10Mbps */ | ||
270 | ks8842_clear_bits(adapter, 49, 3 << 2, REG_P1CR4); | ||
271 | |||
272 | /* Enable the transmitter */ | ||
273 | ks8842_enable_tx(adapter); | ||
274 | |||
275 | /* Enable the receiver */ | ||
276 | ks8842_enable_rx(adapter); | ||
277 | |||
278 | /* clear all interrupts */ | ||
279 | ks8842_write16(adapter, 18, 0xffff, REG_ISR); | ||
280 | |||
281 | /* enable interrupts */ | ||
282 | ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER); | ||
283 | |||
284 | /* enable the switch */ | ||
285 | ks8842_write16(adapter, 32, 0x1, REG_SW_ID_AND_ENABLE); | ||
286 | } | ||
287 | |||
288 | static void ks8842_read_mac_addr(struct ks8842_adapter *adapter, u8 *dest) | ||
289 | { | ||
290 | int i; | ||
291 | u16 mac; | ||
292 | |||
293 | for (i = 0; i < ETH_ALEN; i++) | ||
294 | dest[ETH_ALEN - i - 1] = ks8842_read8(adapter, 2, REG_MARL + i); | ||
295 | |||
296 | /* make sure the switch port uses the same MAC as the QMU */ | ||
297 | mac = ks8842_read16(adapter, 2, REG_MARL); | ||
298 | ks8842_write16(adapter, 39, mac, REG_MACAR1); | ||
299 | mac = ks8842_read16(adapter, 2, REG_MARM); | ||
300 | ks8842_write16(adapter, 39, mac, REG_MACAR2); | ||
301 | mac = ks8842_read16(adapter, 2, REG_MARH); | ||
302 | ks8842_write16(adapter, 39, mac, REG_MACAR3); | ||
303 | } | ||
304 | |||
305 | static inline u16 ks8842_tx_fifo_space(struct ks8842_adapter *adapter) | ||
306 | { | ||
307 | return ks8842_read16(adapter, 16, REG_TXMIR) & 0x1fff; | ||
308 | } | ||
309 | |||
310 | static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev) | ||
311 | { | ||
312 | struct ks8842_adapter *adapter = netdev_priv(netdev); | ||
313 | int len = skb->len; | ||
314 | u32 *ptr = (u32 *)skb->data; | ||
315 | u32 ctrl; | ||
316 | |||
317 | dev_dbg(&adapter->pdev->dev, | ||
318 | "%s: len %u head %p data %p tail %p end %p\n", | ||
319 | __func__, skb->len, skb->head, skb->data, | ||
320 | skb_tail_pointer(skb), skb_end_pointer(skb)); | ||
321 | |||
322 | /* check FIFO buffer space, we need space for CRC and command bits */ | ||
323 | if (ks8842_tx_fifo_space(adapter) < len + 8) | ||
324 | return NETDEV_TX_BUSY; | ||
325 | |||
326 | /* the control word, enable IRQ, port 1 and the length */ | ||
327 | ctrl = 0x8000 | 0x100 | (len << 16); | ||
328 | ks8842_write32(adapter, 17, ctrl, REG_QMU_DATA_LO); | ||
329 | |||
330 | netdev->stats.tx_bytes += len; | ||
331 | |||
332 | /* copy buffer */ | ||
333 | while (len > 0) { | ||
334 | iowrite32(*ptr, adapter->hw_addr + REG_QMU_DATA_LO); | ||
335 | len -= sizeof(u32); | ||
336 | ptr++; | ||
337 | } | ||
338 | |||
339 | /* enqueue packet */ | ||
340 | ks8842_write16(adapter, 17, 1, REG_TXQCR); | ||
341 | |||
342 | dev_kfree_skb(skb); | ||
343 | |||
344 | return NETDEV_TX_OK; | ||
345 | } | ||
346 | |||
347 | static void ks8842_rx_frame(struct net_device *netdev, | ||
348 | struct ks8842_adapter *adapter) | ||
349 | { | ||
350 | u32 status = ks8842_read32(adapter, 17, REG_QMU_DATA_LO); | ||
351 | int len = (status >> 16) & 0x7ff; | ||
352 | |||
353 | status &= 0xffff; | ||
354 | |||
355 | dev_dbg(&adapter->pdev->dev, "%s - rx_data: status: %x\n", | ||
356 | __func__, status); | ||
357 | |||
358 | /* check the status */ | ||
359 | if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) { | ||
360 | struct sk_buff *skb = netdev_alloc_skb(netdev, len + 2); | ||
361 | |||
362 | dev_dbg(&adapter->pdev->dev, "%s, got package, len: %d\n", | ||
363 | __func__, len); | ||
364 | if (skb) { | ||
365 | u32 *data; | ||
366 | |||
367 | netdev->stats.rx_packets++; | ||
368 | netdev->stats.rx_bytes += len; | ||
369 | if (status & RXSR_MULTICAST) | ||
370 | netdev->stats.multicast++; | ||
371 | |||
372 | /* Align socket buffer in 4-byte boundary for | ||
373 | better performance. */ | ||
374 | skb_reserve(skb, 2); | ||
375 | data = (u32 *)skb_put(skb, len); | ||
376 | |||
377 | ks8842_select_bank(adapter, 17); | ||
378 | while (len > 0) { | ||
379 | *data++ = ioread32(adapter->hw_addr + | ||
380 | REG_QMU_DATA_LO); | ||
381 | len -= sizeof(u32); | ||
382 | } | ||
383 | |||
384 | skb->protocol = eth_type_trans(skb, netdev); | ||
385 | netif_rx(skb); | ||
386 | } else | ||
387 | netdev->stats.rx_dropped++; | ||
388 | } else { | ||
389 | dev_dbg(&adapter->pdev->dev, "RX error, status: %x\n", status); | ||
390 | netdev->stats.rx_errors++; | ||
391 | if (status & RXSR_TOO_LONG) | ||
392 | netdev->stats.rx_length_errors++; | ||
393 | if (status & RXSR_CRC_ERROR) | ||
394 | netdev->stats.rx_crc_errors++; | ||
395 | if (status & RXSR_RUNT) | ||
396 | netdev->stats.rx_frame_errors++; | ||
397 | } | ||
398 | |||
399 | /* set high watermark to 3K */ | ||
400 | ks8842_clear_bits(adapter, 0, 1 << 12, REG_QRFCR); | ||
401 | |||
402 | /* release the frame */ | ||
403 | ks8842_write16(adapter, 17, 0x01, REG_RXQCR); | ||
404 | |||
405 | /* set high watermark to 2K */ | ||
406 | ks8842_enable_bits(adapter, 0, 1 << 12, REG_QRFCR); | ||
407 | } | ||
408 | |||
409 | void ks8842_handle_rx(struct net_device *netdev, struct ks8842_adapter *adapter) | ||
410 | { | ||
411 | u16 rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff; | ||
412 | dev_dbg(&adapter->pdev->dev, "%s Entry - rx_data: %d\n", | ||
413 | __func__, rx_data); | ||
414 | while (rx_data) { | ||
415 | ks8842_rx_frame(netdev, adapter); | ||
416 | rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff; | ||
417 | } | ||
418 | } | ||
419 | |||
420 | void ks8842_handle_tx(struct net_device *netdev, struct ks8842_adapter *adapter) | ||
421 | { | ||
422 | u16 sr = ks8842_read16(adapter, 16, REG_TXSR); | ||
423 | dev_dbg(&adapter->pdev->dev, "%s - entry, sr: %x\n", __func__, sr); | ||
424 | netdev->stats.tx_packets++; | ||
425 | if (netif_queue_stopped(netdev)) | ||
426 | netif_wake_queue(netdev); | ||
427 | } | ||
428 | |||
429 | void ks8842_handle_rx_overrun(struct net_device *netdev, | ||
430 | struct ks8842_adapter *adapter) | ||
431 | { | ||
432 | dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__); | ||
433 | netdev->stats.rx_errors++; | ||
434 | netdev->stats.rx_fifo_errors++; | ||
435 | } | ||
436 | |||
437 | void ks8842_tasklet(unsigned long arg) | ||
438 | { | ||
439 | struct net_device *netdev = (struct net_device *)arg; | ||
440 | struct ks8842_adapter *adapter = netdev_priv(netdev); | ||
441 | u16 isr; | ||
442 | unsigned long flags; | ||
443 | u16 entry_bank; | ||
444 | |||
445 | /* read current bank to be able to set it back */ | ||
446 | spin_lock_irqsave(&adapter->lock, flags); | ||
447 | entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK); | ||
448 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
449 | |||
450 | isr = ks8842_read16(adapter, 18, REG_ISR); | ||
451 | dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr); | ||
452 | |||
453 | /* Ack */ | ||
454 | ks8842_write16(adapter, 18, isr, REG_ISR); | ||
455 | |||
456 | if (!netif_running(netdev)) | ||
457 | return; | ||
458 | |||
459 | if (isr & IRQ_LINK_CHANGE) | ||
460 | ks8842_update_link_status(netdev, adapter); | ||
461 | |||
462 | if (isr & (IRQ_RX | IRQ_RX_ERROR)) | ||
463 | ks8842_handle_rx(netdev, adapter); | ||
464 | |||
465 | if (isr & IRQ_TX) | ||
466 | ks8842_handle_tx(netdev, adapter); | ||
467 | |||
468 | if (isr & IRQ_RX_OVERRUN) | ||
469 | ks8842_handle_rx_overrun(netdev, adapter); | ||
470 | |||
471 | if (isr & IRQ_TX_STOPPED) { | ||
472 | ks8842_disable_tx(adapter); | ||
473 | ks8842_enable_tx(adapter); | ||
474 | } | ||
475 | |||
476 | if (isr & IRQ_RX_STOPPED) { | ||
477 | ks8842_disable_rx(adapter); | ||
478 | ks8842_enable_rx(adapter); | ||
479 | } | ||
480 | |||
481 | /* re-enable interrupts, put back the bank selection register */ | ||
482 | spin_lock_irqsave(&adapter->lock, flags); | ||
483 | ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER); | ||
484 | iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK); | ||
485 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
486 | } | ||
487 | |||
488 | static irqreturn_t ks8842_irq(int irq, void *devid) | ||
489 | { | ||
490 | struct ks8842_adapter *adapter = devid; | ||
491 | u16 isr; | ||
492 | u16 entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK); | ||
493 | irqreturn_t ret = IRQ_NONE; | ||
494 | |||
495 | isr = ks8842_read16(adapter, 18, REG_ISR); | ||
496 | dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr); | ||
497 | |||
498 | if (isr) { | ||
499 | /* disable IRQ */ | ||
500 | ks8842_write16(adapter, 18, 0x00, REG_IER); | ||
501 | |||
502 | /* schedule tasklet */ | ||
503 | tasklet_schedule(&adapter->tasklet); | ||
504 | |||
505 | ret = IRQ_HANDLED; | ||
506 | } | ||
507 | |||
508 | iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK); | ||
509 | |||
510 | return ret; | ||
511 | } | ||
512 | |||
513 | |||
514 | /* Netdevice operations */ | ||
515 | |||
516 | static int ks8842_open(struct net_device *netdev) | ||
517 | { | ||
518 | struct ks8842_adapter *adapter = netdev_priv(netdev); | ||
519 | int err; | ||
520 | |||
521 | dev_dbg(&adapter->pdev->dev, "%s - entry\n", __func__); | ||
522 | |||
523 | /* reset the HW */ | ||
524 | ks8842_reset_hw(adapter); | ||
525 | |||
526 | ks8842_update_link_status(netdev, adapter); | ||
527 | |||
528 | err = request_irq(adapter->irq, ks8842_irq, IRQF_SHARED, DRV_NAME, | ||
529 | adapter); | ||
530 | if (err) { | ||
531 | printk(KERN_ERR "Failed to request IRQ: %d: %d\n", | ||
532 | adapter->irq, err); | ||
533 | return err; | ||
534 | } | ||
535 | |||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | static int ks8842_close(struct net_device *netdev) | ||
540 | { | ||
541 | struct ks8842_adapter *adapter = netdev_priv(netdev); | ||
542 | |||
543 | dev_dbg(&adapter->pdev->dev, "%s - entry\n", __func__); | ||
544 | |||
545 | /* free the irq */ | ||
546 | free_irq(adapter->irq, adapter); | ||
547 | |||
548 | /* disable the switch */ | ||
549 | ks8842_write16(adapter, 32, 0x0, REG_SW_ID_AND_ENABLE); | ||
550 | |||
551 | return 0; | ||
552 | } | ||
553 | |||
554 | static int ks8842_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | ||
555 | { | ||
556 | int ret; | ||
557 | struct ks8842_adapter *adapter = netdev_priv(netdev); | ||
558 | |||
559 | dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__); | ||
560 | |||
561 | ret = ks8842_tx_frame(skb, netdev); | ||
562 | |||
563 | if (ks8842_tx_fifo_space(adapter) < netdev->mtu + 8) | ||
564 | netif_stop_queue(netdev); | ||
565 | |||
566 | return ret; | ||
567 | } | ||
568 | |||
569 | static int ks8842_set_mac(struct net_device *netdev, void *p) | ||
570 | { | ||
571 | struct ks8842_adapter *adapter = netdev_priv(netdev); | ||
572 | unsigned long flags; | ||
573 | struct sockaddr *addr = p; | ||
574 | char *mac = (u8 *)addr->sa_data; | ||
575 | int i; | ||
576 | |||
577 | dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__); | ||
578 | |||
579 | if (!is_valid_ether_addr(addr->sa_data)) | ||
580 | return -EADDRNOTAVAIL; | ||
581 | |||
582 | memcpy(netdev->dev_addr, mac, netdev->addr_len); | ||
583 | |||
584 | spin_lock_irqsave(&adapter->lock, flags); | ||
585 | for (i = 0; i < ETH_ALEN; i++) { | ||
586 | ks8842_write8(adapter, 2, mac[ETH_ALEN - i - 1], REG_MARL + i); | ||
587 | ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1], | ||
588 | REG_MACAR1 + i); | ||
589 | } | ||
590 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | static void ks8842_tx_timeout(struct net_device *netdev) | ||
595 | { | ||
596 | struct ks8842_adapter *adapter = netdev_priv(netdev); | ||
597 | unsigned long flags; | ||
598 | |||
599 | dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__); | ||
600 | |||
601 | spin_lock_irqsave(&adapter->lock, flags); | ||
602 | /* disable interrupts */ | ||
603 | ks8842_write16(adapter, 18, 0, REG_IER); | ||
604 | ks8842_write16(adapter, 18, 0xFFFF, REG_ISR); | ||
605 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
606 | |||
607 | ks8842_reset_hw(adapter); | ||
608 | |||
609 | ks8842_update_link_status(netdev, adapter); | ||
610 | } | ||
611 | |||
612 | static const struct net_device_ops ks8842_netdev_ops = { | ||
613 | .ndo_open = ks8842_open, | ||
614 | .ndo_stop = ks8842_close, | ||
615 | .ndo_start_xmit = ks8842_xmit_frame, | ||
616 | .ndo_set_mac_address = ks8842_set_mac, | ||
617 | .ndo_tx_timeout = ks8842_tx_timeout, | ||
618 | .ndo_validate_addr = eth_validate_addr | ||
619 | }; | ||
620 | |||
621 | static struct ethtool_ops ks8842_ethtool_ops = { | ||
622 | .get_link = ethtool_op_get_link, | ||
623 | }; | ||
624 | |||
625 | static int __devinit ks8842_probe(struct platform_device *pdev) | ||
626 | { | ||
627 | int err = -ENOMEM; | ||
628 | struct resource *iomem; | ||
629 | struct net_device *netdev; | ||
630 | struct ks8842_adapter *adapter; | ||
631 | u16 id; | ||
632 | |||
633 | iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
634 | if (!request_mem_region(iomem->start, resource_size(iomem), DRV_NAME)) | ||
635 | goto err_mem_region; | ||
636 | |||
637 | netdev = alloc_etherdev(sizeof(struct ks8842_adapter)); | ||
638 | if (!netdev) | ||
639 | goto err_alloc_etherdev; | ||
640 | |||
641 | SET_NETDEV_DEV(netdev, &pdev->dev); | ||
642 | |||
643 | adapter = netdev_priv(netdev); | ||
644 | adapter->hw_addr = ioremap(iomem->start, resource_size(iomem)); | ||
645 | if (!adapter->hw_addr) | ||
646 | goto err_ioremap; | ||
647 | |||
648 | adapter->irq = platform_get_irq(pdev, 0); | ||
649 | if (adapter->irq < 0) { | ||
650 | err = adapter->irq; | ||
651 | goto err_get_irq; | ||
652 | } | ||
653 | |||
654 | adapter->pdev = pdev; | ||
655 | |||
656 | tasklet_init(&adapter->tasklet, ks8842_tasklet, (unsigned long)netdev); | ||
657 | spin_lock_init(&adapter->lock); | ||
658 | |||
659 | netdev->netdev_ops = &ks8842_netdev_ops; | ||
660 | netdev->ethtool_ops = &ks8842_ethtool_ops; | ||
661 | |||
662 | ks8842_read_mac_addr(adapter, netdev->dev_addr); | ||
663 | |||
664 | id = ks8842_read16(adapter, 32, REG_SW_ID_AND_ENABLE); | ||
665 | |||
666 | strcpy(netdev->name, "eth%d"); | ||
667 | err = register_netdev(netdev); | ||
668 | if (err) | ||
669 | goto err_register; | ||
670 | |||
671 | platform_set_drvdata(pdev, netdev); | ||
672 | |||
673 | printk(KERN_INFO DRV_NAME | ||
674 | " Found chip, family: 0x%x, id: 0x%x, rev: 0x%x\n", | ||
675 | (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7); | ||
676 | |||
677 | return 0; | ||
678 | |||
679 | err_register: | ||
680 | err_get_irq: | ||
681 | iounmap(adapter->hw_addr); | ||
682 | err_ioremap: | ||
683 | free_netdev(netdev); | ||
684 | err_alloc_etherdev: | ||
685 | release_mem_region(iomem->start, resource_size(iomem)); | ||
686 | err_mem_region: | ||
687 | return err; | ||
688 | } | ||
689 | |||
690 | static int __devexit ks8842_remove(struct platform_device *pdev) | ||
691 | { | ||
692 | struct net_device *netdev = platform_get_drvdata(pdev); | ||
693 | struct ks8842_adapter *adapter = netdev_priv(netdev); | ||
694 | struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
695 | |||
696 | unregister_netdev(netdev); | ||
697 | tasklet_kill(&adapter->tasklet); | ||
698 | iounmap(adapter->hw_addr); | ||
699 | free_netdev(netdev); | ||
700 | release_mem_region(iomem->start, resource_size(iomem)); | ||
701 | platform_set_drvdata(pdev, NULL); | ||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | |||
706 | static struct platform_driver ks8842_platform_driver = { | ||
707 | .driver = { | ||
708 | .name = DRV_NAME, | ||
709 | .owner = THIS_MODULE, | ||
710 | }, | ||
711 | .probe = ks8842_probe, | ||
712 | .remove = ks8842_remove, | ||
713 | }; | ||
714 | |||
715 | static int __init ks8842_init(void) | ||
716 | { | ||
717 | return platform_driver_register(&ks8842_platform_driver); | ||
718 | } | ||
719 | |||
720 | static void __exit ks8842_exit(void) | ||
721 | { | ||
722 | platform_driver_unregister(&ks8842_platform_driver); | ||
723 | } | ||
724 | |||
725 | module_init(ks8842_init); | ||
726 | module_exit(ks8842_exit); | ||
727 | |||
728 | MODULE_DESCRIPTION("Timberdale KS8842 ethernet driver"); | ||
729 | MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>"); | ||
730 | MODULE_LICENSE("GPL v2"); | ||
731 | MODULE_ALIAS("platform:ks8842"); | ||
732 | |||
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 021d9941c292..99eed9f37c84 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -359,6 +359,7 @@ static int macvlan_init(struct net_device *dev) | |||
359 | (lowerdev->state & MACVLAN_STATE_MASK); | 359 | (lowerdev->state & MACVLAN_STATE_MASK); |
360 | dev->features = lowerdev->features & MACVLAN_FEATURES; | 360 | dev->features = lowerdev->features & MACVLAN_FEATURES; |
361 | dev->iflink = lowerdev->ifindex; | 361 | dev->iflink = lowerdev->ifindex; |
362 | dev->hard_header_len = lowerdev->hard_header_len; | ||
362 | 363 | ||
363 | macvlan_set_lockdep_class(dev); | 364 | macvlan_set_lockdep_class(dev); |
364 | 365 | ||
diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c index 66483035f683..dc45e9856c35 100644 --- a/drivers/net/mdio.c +++ b/drivers/net/mdio.c | |||
@@ -296,6 +296,23 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, | |||
296 | ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX || | 296 | ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX || |
297 | ecmd->speed == SPEED_10000); | 297 | ecmd->speed == SPEED_10000); |
298 | } | 298 | } |
299 | |||
300 | /* 10GBASE-T MDI/MDI-X */ | ||
301 | if (ecmd->port == PORT_TP && ecmd->speed == SPEED_10000) { | ||
302 | switch (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, | ||
303 | MDIO_PMA_10GBT_SWAPPOL)) { | ||
304 | case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX: | ||
305 | ecmd->eth_tp_mdix = ETH_TP_MDI; | ||
306 | break; | ||
307 | case 0: | ||
308 | ecmd->eth_tp_mdix = ETH_TP_MDI_X; | ||
309 | break; | ||
310 | default: | ||
311 | /* It's complicated... */ | ||
312 | ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID; | ||
313 | break; | ||
314 | } | ||
315 | } | ||
299 | } | 316 | } |
300 | EXPORT_SYMBOL(mdio45_ethtool_gset_npage); | 317 | EXPORT_SYMBOL(mdio45_ethtool_gset_npage); |
301 | 318 | ||
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index 8830dcb92ec8..dee188761a3c 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c | |||
@@ -623,8 +623,10 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) | |||
623 | err = mlx4_create_eq(dev, dev->caps.num_cqs + MLX4_NUM_SPARE_EQE, | 623 | err = mlx4_create_eq(dev, dev->caps.num_cqs + MLX4_NUM_SPARE_EQE, |
624 | (dev->flags & MLX4_FLAG_MSI_X) ? i : 0, | 624 | (dev->flags & MLX4_FLAG_MSI_X) ? i : 0, |
625 | &priv->eq_table.eq[i]); | 625 | &priv->eq_table.eq[i]); |
626 | if (err) | 626 | if (err) { |
627 | --i; | ||
627 | goto err_out_unmap; | 628 | goto err_out_unmap; |
629 | } | ||
628 | } | 630 | } |
629 | 631 | ||
630 | err = mlx4_create_eq(dev, MLX4_NUM_ASYNC_EQE + MLX4_NUM_SPARE_EQE, | 632 | err = mlx4_create_eq(dev, MLX4_NUM_ASYNC_EQE + MLX4_NUM_SPARE_EQE, |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 4a51c31330da..6f77ad58e3b3 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -178,10 +178,8 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter) | |||
178 | 178 | ||
179 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { | 179 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { |
180 | rds_ring = &recv_ctx->rds_rings[ring]; | 180 | rds_ring = &recv_ctx->rds_rings[ring]; |
181 | if (rds_ring->rx_buf_arr) { | 181 | vfree(rds_ring->rx_buf_arr); |
182 | vfree(rds_ring->rx_buf_arr); | 182 | rds_ring->rx_buf_arr = NULL; |
183 | rds_ring->rx_buf_arr = NULL; | ||
184 | } | ||
185 | } | 183 | } |
186 | kfree(recv_ctx->rds_rings); | 184 | kfree(recv_ctx->rds_rings); |
187 | 185 | ||
@@ -190,8 +188,7 @@ skip_rds: | |||
190 | return; | 188 | return; |
191 | 189 | ||
192 | tx_ring = adapter->tx_ring; | 190 | tx_ring = adapter->tx_ring; |
193 | if (tx_ring->cmd_buf_arr) | 191 | vfree(tx_ring->cmd_buf_arr); |
194 | vfree(tx_ring->cmd_buf_arr); | ||
195 | } | 192 | } |
196 | 193 | ||
197 | int netxen_alloc_sw_resources(struct netxen_adapter *adapter) | 194 | int netxen_alloc_sw_resources(struct netxen_adapter *adapter) |
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index fcb159e4df54..156e02e8905d 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h | |||
@@ -27,6 +27,8 @@ | |||
27 | "%s: " fmt, __func__, ##args); \ | 27 | "%s: " fmt, __func__, ##args); \ |
28 | } while (0) | 28 | } while (0) |
29 | 29 | ||
30 | #define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ | ||
31 | |||
30 | #define QLGE_VENDOR_ID 0x1077 | 32 | #define QLGE_VENDOR_ID 0x1077 |
31 | #define QLGE_DEVICE_ID_8012 0x8012 | 33 | #define QLGE_DEVICE_ID_8012 0x8012 |
32 | #define QLGE_DEVICE_ID_8000 0x8000 | 34 | #define QLGE_DEVICE_ID_8000 0x8000 |
@@ -39,7 +41,18 @@ | |||
39 | 41 | ||
40 | #define NUM_SMALL_BUFFERS 512 | 42 | #define NUM_SMALL_BUFFERS 512 |
41 | #define NUM_LARGE_BUFFERS 512 | 43 | #define NUM_LARGE_BUFFERS 512 |
44 | #define DB_PAGE_SIZE 4096 | ||
45 | |||
46 | /* Calculate the number of (4k) pages required to | ||
47 | * contain a buffer queue of the given length. | ||
48 | */ | ||
49 | #define MAX_DB_PAGES_PER_BQ(x) \ | ||
50 | (((x * sizeof(u64)) / DB_PAGE_SIZE) + \ | ||
51 | (((x * sizeof(u64)) % DB_PAGE_SIZE) ? 1 : 0)) | ||
42 | 52 | ||
53 | #define RX_RING_SHADOW_SPACE (sizeof(u64) + \ | ||
54 | MAX_DB_PAGES_PER_BQ(NUM_SMALL_BUFFERS) * sizeof(u64) + \ | ||
55 | MAX_DB_PAGES_PER_BQ(NUM_LARGE_BUFFERS) * sizeof(u64)) | ||
43 | #define SMALL_BUFFER_SIZE 256 | 56 | #define SMALL_BUFFER_SIZE 256 |
44 | #define LARGE_BUFFER_SIZE PAGE_SIZE | 57 | #define LARGE_BUFFER_SIZE PAGE_SIZE |
45 | #define MAX_SPLIT_SIZE 1023 | 58 | #define MAX_SPLIT_SIZE 1023 |
@@ -50,7 +63,7 @@ | |||
50 | #define MAX_INTER_FRAME_WAIT 10 /* 10 usec max interframe-wait for coalescing */ | 63 | #define MAX_INTER_FRAME_WAIT 10 /* 10 usec max interframe-wait for coalescing */ |
51 | #define DFLT_INTER_FRAME_WAIT (MAX_INTER_FRAME_WAIT/2) | 64 | #define DFLT_INTER_FRAME_WAIT (MAX_INTER_FRAME_WAIT/2) |
52 | #define UDELAY_COUNT 3 | 65 | #define UDELAY_COUNT 3 |
53 | #define UDELAY_DELAY 10 | 66 | #define UDELAY_DELAY 100 |
54 | 67 | ||
55 | 68 | ||
56 | #define TX_DESC_PER_IOCB 8 | 69 | #define TX_DESC_PER_IOCB 8 |
@@ -63,7 +76,16 @@ | |||
63 | #define TX_DESC_PER_OAL 0 | 76 | #define TX_DESC_PER_OAL 0 |
64 | #endif | 77 | #endif |
65 | 78 | ||
66 | #define DB_PAGE_SIZE 4096 | 79 | /* MPI test register definitions. This register |
80 | * is used for determining alternate NIC function's | ||
81 | * PCI->func number. | ||
82 | */ | ||
83 | enum { | ||
84 | MPI_TEST_FUNC_PORT_CFG = 0x1002, | ||
85 | MPI_TEST_NIC1_FUNC_SHIFT = 1, | ||
86 | MPI_TEST_NIC2_FUNC_SHIFT = 5, | ||
87 | MPI_TEST_NIC_FUNC_MASK = 0x00000007, | ||
88 | }; | ||
67 | 89 | ||
68 | /* | 90 | /* |
69 | * Processor Address Register (PROC_ADDR) bit definitions. | 91 | * Processor Address Register (PROC_ADDR) bit definitions. |
@@ -1430,7 +1452,10 @@ struct ql_adapter { | |||
1430 | 1452 | ||
1431 | /* Hardware information */ | 1453 | /* Hardware information */ |
1432 | u32 chip_rev_id; | 1454 | u32 chip_rev_id; |
1455 | u32 fw_rev_id; | ||
1433 | u32 func; /* PCI function for this adapter */ | 1456 | u32 func; /* PCI function for this adapter */ |
1457 | u32 alt_func; /* PCI function for alternate adapter */ | ||
1458 | u32 port; /* Port number this adapter */ | ||
1434 | 1459 | ||
1435 | spinlock_t adapter_lock; | 1460 | spinlock_t adapter_lock; |
1436 | spinlock_t hw_lock; | 1461 | spinlock_t hw_lock; |
@@ -1580,6 +1605,8 @@ void ql_mpi_idc_work(struct work_struct *work); | |||
1580 | void ql_mpi_port_cfg_work(struct work_struct *work); | 1605 | void ql_mpi_port_cfg_work(struct work_struct *work); |
1581 | int ql_mb_get_fw_state(struct ql_adapter *qdev); | 1606 | int ql_mb_get_fw_state(struct ql_adapter *qdev); |
1582 | int ql_cam_route_initialize(struct ql_adapter *qdev); | 1607 | int ql_cam_route_initialize(struct ql_adapter *qdev); |
1608 | int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data); | ||
1609 | int ql_mb_about_fw(struct ql_adapter *qdev); | ||
1583 | 1610 | ||
1584 | #if 1 | 1611 | #if 1 |
1585 | #define QL_ALL_DUMP | 1612 | #define QL_ALL_DUMP |
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c index 913b2a5fafc9..37c99fe79770 100644 --- a/drivers/net/qlge/qlge_ethtool.c +++ b/drivers/net/qlge/qlge_ethtool.c | |||
@@ -293,7 +293,10 @@ static void ql_get_drvinfo(struct net_device *ndev, | |||
293 | struct ql_adapter *qdev = netdev_priv(ndev); | 293 | struct ql_adapter *qdev = netdev_priv(ndev); |
294 | strncpy(drvinfo->driver, qlge_driver_name, 32); | 294 | strncpy(drvinfo->driver, qlge_driver_name, 32); |
295 | strncpy(drvinfo->version, qlge_driver_version, 32); | 295 | strncpy(drvinfo->version, qlge_driver_version, 32); |
296 | strncpy(drvinfo->fw_version, "N/A", 32); | 296 | snprintf(drvinfo->fw_version, 32, "v%d.%d.%d", |
297 | (qdev->fw_rev_id & 0x00ff0000) >> 16, | ||
298 | (qdev->fw_rev_id & 0x0000ff00) >> 8, | ||
299 | (qdev->fw_rev_id & 0x000000ff)); | ||
297 | strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32); | 300 | strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32); |
298 | drvinfo->n_stats = 0; | 301 | drvinfo->n_stats = 0; |
299 | drvinfo->testinfo_len = 0; | 302 | drvinfo->testinfo_len = 0; |
@@ -401,6 +404,7 @@ const struct ethtool_ops qlge_ethtool_ops = { | |||
401 | .get_rx_csum = ql_get_rx_csum, | 404 | .get_rx_csum = ql_get_rx_csum, |
402 | .set_rx_csum = ql_set_rx_csum, | 405 | .set_rx_csum = ql_set_rx_csum, |
403 | .get_tx_csum = ethtool_op_get_tx_csum, | 406 | .get_tx_csum = ethtool_op_get_tx_csum, |
407 | .set_tx_csum = ethtool_op_set_tx_csum, | ||
404 | .get_sg = ethtool_op_get_sg, | 408 | .get_sg = ethtool_op_get_sg, |
405 | .set_sg = ethtool_op_set_sg, | 409 | .set_sg = ethtool_op_set_sg, |
406 | .get_tso = ethtool_op_get_tso, | 410 | .get_tso = ethtool_op_get_tso, |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 0b0778d9919c..b9a5f59d6c9b 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -675,11 +675,12 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev) | |||
675 | int status; | 675 | int status; |
676 | __le32 *p = (__le32 *)&qdev->flash; | 676 | __le32 *p = (__le32 *)&qdev->flash; |
677 | u32 offset; | 677 | u32 offset; |
678 | u8 mac_addr[6]; | ||
678 | 679 | ||
679 | /* Get flash offset for function and adjust | 680 | /* Get flash offset for function and adjust |
680 | * for dword access. | 681 | * for dword access. |
681 | */ | 682 | */ |
682 | if (!qdev->func) | 683 | if (!qdev->port) |
683 | offset = FUNC0_FLASH_OFFSET / sizeof(u32); | 684 | offset = FUNC0_FLASH_OFFSET / sizeof(u32); |
684 | else | 685 | else |
685 | offset = FUNC1_FLASH_OFFSET / sizeof(u32); | 686 | offset = FUNC1_FLASH_OFFSET / sizeof(u32); |
@@ -705,14 +706,26 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev) | |||
705 | goto exit; | 706 | goto exit; |
706 | } | 707 | } |
707 | 708 | ||
708 | if (!is_valid_ether_addr(qdev->flash.flash_params_8000.mac_addr)) { | 709 | /* Extract either manufacturer or BOFM modified |
710 | * MAC address. | ||
711 | */ | ||
712 | if (qdev->flash.flash_params_8000.data_type1 == 2) | ||
713 | memcpy(mac_addr, | ||
714 | qdev->flash.flash_params_8000.mac_addr1, | ||
715 | qdev->ndev->addr_len); | ||
716 | else | ||
717 | memcpy(mac_addr, | ||
718 | qdev->flash.flash_params_8000.mac_addr, | ||
719 | qdev->ndev->addr_len); | ||
720 | |||
721 | if (!is_valid_ether_addr(mac_addr)) { | ||
709 | QPRINTK(qdev, IFUP, ERR, "Invalid MAC address.\n"); | 722 | QPRINTK(qdev, IFUP, ERR, "Invalid MAC address.\n"); |
710 | status = -EINVAL; | 723 | status = -EINVAL; |
711 | goto exit; | 724 | goto exit; |
712 | } | 725 | } |
713 | 726 | ||
714 | memcpy(qdev->ndev->dev_addr, | 727 | memcpy(qdev->ndev->dev_addr, |
715 | qdev->flash.flash_params_8000.mac_addr, | 728 | mac_addr, |
716 | qdev->ndev->addr_len); | 729 | qdev->ndev->addr_len); |
717 | 730 | ||
718 | exit: | 731 | exit: |
@@ -731,7 +744,7 @@ static int ql_get_8012_flash_params(struct ql_adapter *qdev) | |||
731 | /* Second function's parameters follow the first | 744 | /* Second function's parameters follow the first |
732 | * function's. | 745 | * function's. |
733 | */ | 746 | */ |
734 | if (qdev->func) | 747 | if (qdev->port) |
735 | offset = size; | 748 | offset = size; |
736 | 749 | ||
737 | if (ql_sem_spinlock(qdev, SEM_FLASH_MASK)) | 750 | if (ql_sem_spinlock(qdev, SEM_FLASH_MASK)) |
@@ -837,6 +850,13 @@ exit: | |||
837 | static int ql_8000_port_initialize(struct ql_adapter *qdev) | 850 | static int ql_8000_port_initialize(struct ql_adapter *qdev) |
838 | { | 851 | { |
839 | int status; | 852 | int status; |
853 | /* | ||
854 | * Get MPI firmware version for driver banner | ||
855 | * and ethool info. | ||
856 | */ | ||
857 | status = ql_mb_about_fw(qdev); | ||
858 | if (status) | ||
859 | goto exit; | ||
840 | status = ql_mb_get_fw_state(qdev); | 860 | status = ql_mb_get_fw_state(qdev); |
841 | if (status) | 861 | if (status) |
842 | goto exit; | 862 | goto exit; |
@@ -1518,6 +1538,22 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev, | |||
1518 | return; | 1538 | return; |
1519 | } | 1539 | } |
1520 | 1540 | ||
1541 | /* Frame error, so drop the packet. */ | ||
1542 | if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { | ||
1543 | QPRINTK(qdev, DRV, ERR, "Receive error, flags2 = 0x%x\n", | ||
1544 | ib_mac_rsp->flags2); | ||
1545 | dev_kfree_skb_any(skb); | ||
1546 | return; | ||
1547 | } | ||
1548 | |||
1549 | /* The max framesize filter on this chip is set higher than | ||
1550 | * MTU since FCoE uses 2k frames. | ||
1551 | */ | ||
1552 | if (skb->len > ndev->mtu + ETH_HLEN) { | ||
1553 | dev_kfree_skb_any(skb); | ||
1554 | return; | ||
1555 | } | ||
1556 | |||
1521 | prefetch(skb->data); | 1557 | prefetch(skb->data); |
1522 | skb->dev = ndev; | 1558 | skb->dev = ndev; |
1523 | if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) { | 1559 | if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) { |
@@ -1540,7 +1576,6 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev, | |||
1540 | * csum or frame errors. | 1576 | * csum or frame errors. |
1541 | */ | 1577 | */ |
1542 | if (qdev->rx_csum && | 1578 | if (qdev->rx_csum && |
1543 | !(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) && | ||
1544 | !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { | 1579 | !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { |
1545 | /* TCP frame. */ | 1580 | /* TCP frame. */ |
1546 | if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { | 1581 | if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { |
@@ -2202,7 +2237,7 @@ static int ql_alloc_tx_resources(struct ql_adapter *qdev, | |||
2202 | &tx_ring->wq_base_dma); | 2237 | &tx_ring->wq_base_dma); |
2203 | 2238 | ||
2204 | if ((tx_ring->wq_base == NULL) | 2239 | if ((tx_ring->wq_base == NULL) |
2205 | || tx_ring->wq_base_dma & (tx_ring->wq_size - 1)) { | 2240 | || tx_ring->wq_base_dma & WQ_ADDR_ALIGN) { |
2206 | QPRINTK(qdev, IFUP, ERR, "tx_ring alloc failed.\n"); | 2241 | QPRINTK(qdev, IFUP, ERR, "tx_ring alloc failed.\n"); |
2207 | return -ENOMEM; | 2242 | return -ENOMEM; |
2208 | } | 2243 | } |
@@ -2517,14 +2552,16 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) | |||
2517 | { | 2552 | { |
2518 | struct cqicb *cqicb = &rx_ring->cqicb; | 2553 | struct cqicb *cqicb = &rx_ring->cqicb; |
2519 | void *shadow_reg = qdev->rx_ring_shadow_reg_area + | 2554 | void *shadow_reg = qdev->rx_ring_shadow_reg_area + |
2520 | (rx_ring->cq_id * sizeof(u64) * 4); | 2555 | (rx_ring->cq_id * RX_RING_SHADOW_SPACE); |
2521 | u64 shadow_reg_dma = qdev->rx_ring_shadow_reg_dma + | 2556 | u64 shadow_reg_dma = qdev->rx_ring_shadow_reg_dma + |
2522 | (rx_ring->cq_id * sizeof(u64) * 4); | 2557 | (rx_ring->cq_id * RX_RING_SHADOW_SPACE); |
2523 | void __iomem *doorbell_area = | 2558 | void __iomem *doorbell_area = |
2524 | qdev->doorbell_area + (DB_PAGE_SIZE * (128 + rx_ring->cq_id)); | 2559 | qdev->doorbell_area + (DB_PAGE_SIZE * (128 + rx_ring->cq_id)); |
2525 | int err = 0; | 2560 | int err = 0; |
2526 | u16 bq_len; | 2561 | u16 bq_len; |
2527 | u64 tmp; | 2562 | u64 tmp; |
2563 | __le64 *base_indirect_ptr; | ||
2564 | int page_entries; | ||
2528 | 2565 | ||
2529 | /* Set up the shadow registers for this ring. */ | 2566 | /* Set up the shadow registers for this ring. */ |
2530 | rx_ring->prod_idx_sh_reg = shadow_reg; | 2567 | rx_ring->prod_idx_sh_reg = shadow_reg; |
@@ -2533,8 +2570,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) | |||
2533 | shadow_reg_dma += sizeof(u64); | 2570 | shadow_reg_dma += sizeof(u64); |
2534 | rx_ring->lbq_base_indirect = shadow_reg; | 2571 | rx_ring->lbq_base_indirect = shadow_reg; |
2535 | rx_ring->lbq_base_indirect_dma = shadow_reg_dma; | 2572 | rx_ring->lbq_base_indirect_dma = shadow_reg_dma; |
2536 | shadow_reg += sizeof(u64); | 2573 | shadow_reg += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len)); |
2537 | shadow_reg_dma += sizeof(u64); | 2574 | shadow_reg_dma += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len)); |
2538 | rx_ring->sbq_base_indirect = shadow_reg; | 2575 | rx_ring->sbq_base_indirect = shadow_reg; |
2539 | rx_ring->sbq_base_indirect_dma = shadow_reg_dma; | 2576 | rx_ring->sbq_base_indirect_dma = shadow_reg_dma; |
2540 | 2577 | ||
@@ -2571,7 +2608,14 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) | |||
2571 | if (rx_ring->lbq_len) { | 2608 | if (rx_ring->lbq_len) { |
2572 | cqicb->flags |= FLAGS_LL; /* Load lbq values */ | 2609 | cqicb->flags |= FLAGS_LL; /* Load lbq values */ |
2573 | tmp = (u64)rx_ring->lbq_base_dma;; | 2610 | tmp = (u64)rx_ring->lbq_base_dma;; |
2574 | *((__le64 *) rx_ring->lbq_base_indirect) = cpu_to_le64(tmp); | 2611 | base_indirect_ptr = (__le64 *) rx_ring->lbq_base_indirect; |
2612 | page_entries = 0; | ||
2613 | do { | ||
2614 | *base_indirect_ptr = cpu_to_le64(tmp); | ||
2615 | tmp += DB_PAGE_SIZE; | ||
2616 | base_indirect_ptr++; | ||
2617 | page_entries++; | ||
2618 | } while (page_entries < MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len)); | ||
2575 | cqicb->lbq_addr = | 2619 | cqicb->lbq_addr = |
2576 | cpu_to_le64(rx_ring->lbq_base_indirect_dma); | 2620 | cpu_to_le64(rx_ring->lbq_base_indirect_dma); |
2577 | bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 : | 2621 | bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 : |
@@ -2588,7 +2632,14 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) | |||
2588 | if (rx_ring->sbq_len) { | 2632 | if (rx_ring->sbq_len) { |
2589 | cqicb->flags |= FLAGS_LS; /* Load sbq values */ | 2633 | cqicb->flags |= FLAGS_LS; /* Load sbq values */ |
2590 | tmp = (u64)rx_ring->sbq_base_dma;; | 2634 | tmp = (u64)rx_ring->sbq_base_dma;; |
2591 | *((__le64 *) rx_ring->sbq_base_indirect) = cpu_to_le64(tmp); | 2635 | base_indirect_ptr = (__le64 *) rx_ring->sbq_base_indirect; |
2636 | page_entries = 0; | ||
2637 | do { | ||
2638 | *base_indirect_ptr = cpu_to_le64(tmp); | ||
2639 | tmp += DB_PAGE_SIZE; | ||
2640 | base_indirect_ptr++; | ||
2641 | page_entries++; | ||
2642 | } while (page_entries < MAX_DB_PAGES_PER_BQ(rx_ring->sbq_len)); | ||
2592 | cqicb->sbq_addr = | 2643 | cqicb->sbq_addr = |
2593 | cpu_to_le64(rx_ring->sbq_base_indirect_dma); | 2644 | cpu_to_le64(rx_ring->sbq_base_indirect_dma); |
2594 | cqicb->sbq_buf_size = | 2645 | cqicb->sbq_buf_size = |
@@ -3185,9 +3236,10 @@ static void ql_display_dev_info(struct net_device *ndev) | |||
3185 | struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); | 3236 | struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); |
3186 | 3237 | ||
3187 | QPRINTK(qdev, PROBE, INFO, | 3238 | QPRINTK(qdev, PROBE, INFO, |
3188 | "Function #%d, NIC Roll %d, NIC Rev = %d, " | 3239 | "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, " |
3189 | "XG Roll = %d, XG Rev = %d.\n", | 3240 | "XG Roll = %d, XG Rev = %d.\n", |
3190 | qdev->func, | 3241 | qdev->func, |
3242 | qdev->port, | ||
3191 | qdev->chip_rev_id & 0x0000000f, | 3243 | qdev->chip_rev_id & 0x0000000f, |
3192 | qdev->chip_rev_id >> 4 & 0x0000000f, | 3244 | qdev->chip_rev_id >> 4 & 0x0000000f, |
3193 | qdev->chip_rev_id >> 8 & 0x0000000f, | 3245 | qdev->chip_rev_id >> 8 & 0x0000000f, |
@@ -3263,7 +3315,6 @@ static int ql_adapter_up(struct ql_adapter *qdev) | |||
3263 | err = ql_adapter_initialize(qdev); | 3315 | err = ql_adapter_initialize(qdev); |
3264 | if (err) { | 3316 | if (err) { |
3265 | QPRINTK(qdev, IFUP, INFO, "Unable to initialize adapter.\n"); | 3317 | QPRINTK(qdev, IFUP, INFO, "Unable to initialize adapter.\n"); |
3266 | spin_unlock(&qdev->hw_lock); | ||
3267 | goto err_init; | 3318 | goto err_init; |
3268 | } | 3319 | } |
3269 | set_bit(QL_ADAPTER_UP, &qdev->flags); | 3320 | set_bit(QL_ADAPTER_UP, &qdev->flags); |
@@ -3360,7 +3411,6 @@ static int ql_configure_rings(struct ql_adapter *qdev) | |||
3360 | * completion handler rx_rings. | 3411 | * completion handler rx_rings. |
3361 | */ | 3412 | */ |
3362 | qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count + 1; | 3413 | qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count + 1; |
3363 | netif_set_gso_max_size(qdev->ndev, 65536); | ||
3364 | 3414 | ||
3365 | for (i = 0; i < qdev->tx_ring_count; i++) { | 3415 | for (i = 0; i < qdev->tx_ring_count; i++) { |
3366 | tx_ring = &qdev->tx_ring[i]; | 3416 | tx_ring = &qdev->tx_ring[i]; |
@@ -3643,12 +3693,53 @@ static struct nic_operations qla8000_nic_ops = { | |||
3643 | .port_initialize = ql_8000_port_initialize, | 3693 | .port_initialize = ql_8000_port_initialize, |
3644 | }; | 3694 | }; |
3645 | 3695 | ||
3696 | /* Find the pcie function number for the other NIC | ||
3697 | * on this chip. Since both NIC functions share a | ||
3698 | * common firmware we have the lowest enabled function | ||
3699 | * do any common work. Examples would be resetting | ||
3700 | * after a fatal firmware error, or doing a firmware | ||
3701 | * coredump. | ||
3702 | */ | ||
3703 | static int ql_get_alt_pcie_func(struct ql_adapter *qdev) | ||
3704 | { | ||
3705 | int status = 0; | ||
3706 | u32 temp; | ||
3707 | u32 nic_func1, nic_func2; | ||
3708 | |||
3709 | status = ql_read_mpi_reg(qdev, MPI_TEST_FUNC_PORT_CFG, | ||
3710 | &temp); | ||
3711 | if (status) | ||
3712 | return status; | ||
3713 | |||
3714 | nic_func1 = ((temp >> MPI_TEST_NIC1_FUNC_SHIFT) & | ||
3715 | MPI_TEST_NIC_FUNC_MASK); | ||
3716 | nic_func2 = ((temp >> MPI_TEST_NIC2_FUNC_SHIFT) & | ||
3717 | MPI_TEST_NIC_FUNC_MASK); | ||
3718 | |||
3719 | if (qdev->func == nic_func1) | ||
3720 | qdev->alt_func = nic_func2; | ||
3721 | else if (qdev->func == nic_func2) | ||
3722 | qdev->alt_func = nic_func1; | ||
3723 | else | ||
3724 | status = -EIO; | ||
3725 | |||
3726 | return status; | ||
3727 | } | ||
3646 | 3728 | ||
3647 | static void ql_get_board_info(struct ql_adapter *qdev) | 3729 | static int ql_get_board_info(struct ql_adapter *qdev) |
3648 | { | 3730 | { |
3731 | int status; | ||
3649 | qdev->func = | 3732 | qdev->func = |
3650 | (ql_read32(qdev, STS) & STS_FUNC_ID_MASK) >> STS_FUNC_ID_SHIFT; | 3733 | (ql_read32(qdev, STS) & STS_FUNC_ID_MASK) >> STS_FUNC_ID_SHIFT; |
3651 | if (qdev->func) { | 3734 | if (qdev->func > 3) |
3735 | return -EIO; | ||
3736 | |||
3737 | status = ql_get_alt_pcie_func(qdev); | ||
3738 | if (status) | ||
3739 | return status; | ||
3740 | |||
3741 | qdev->port = (qdev->func < qdev->alt_func) ? 0 : 1; | ||
3742 | if (qdev->port) { | ||
3652 | qdev->xg_sem_mask = SEM_XGMAC1_MASK; | 3743 | qdev->xg_sem_mask = SEM_XGMAC1_MASK; |
3653 | qdev->port_link_up = STS_PL1; | 3744 | qdev->port_link_up = STS_PL1; |
3654 | qdev->port_init = STS_PI1; | 3745 | qdev->port_init = STS_PI1; |
@@ -3667,6 +3758,7 @@ static void ql_get_board_info(struct ql_adapter *qdev) | |||
3667 | qdev->nic_ops = &qla8012_nic_ops; | 3758 | qdev->nic_ops = &qla8012_nic_ops; |
3668 | else if (qdev->device_id == QLGE_DEVICE_ID_8000) | 3759 | else if (qdev->device_id == QLGE_DEVICE_ID_8000) |
3669 | qdev->nic_ops = &qla8000_nic_ops; | 3760 | qdev->nic_ops = &qla8000_nic_ops; |
3761 | return status; | ||
3670 | } | 3762 | } |
3671 | 3763 | ||
3672 | static void ql_release_all(struct pci_dev *pdev) | 3764 | static void ql_release_all(struct pci_dev *pdev) |
@@ -3761,7 +3853,12 @@ static int __devinit ql_init_device(struct pci_dev *pdev, | |||
3761 | 3853 | ||
3762 | qdev->ndev = ndev; | 3854 | qdev->ndev = ndev; |
3763 | qdev->pdev = pdev; | 3855 | qdev->pdev = pdev; |
3764 | ql_get_board_info(qdev); | 3856 | err = ql_get_board_info(qdev); |
3857 | if (err) { | ||
3858 | dev_err(&pdev->dev, "Register access failed.\n"); | ||
3859 | err = -EIO; | ||
3860 | goto err_out; | ||
3861 | } | ||
3765 | qdev->msg_enable = netif_msg_init(debug, default_msg); | 3862 | qdev->msg_enable = netif_msg_init(debug, default_msg); |
3766 | spin_lock_init(&qdev->hw_lock); | 3863 | spin_lock_init(&qdev->hw_lock); |
3767 | spin_lock_init(&qdev->stats_lock); | 3864 | spin_lock_init(&qdev->stats_lock); |
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c index 9f81b797f10b..a67c14a7befd 100644 --- a/drivers/net/qlge/qlge_mpi.c +++ b/drivers/net/qlge/qlge_mpi.c | |||
@@ -90,14 +90,14 @@ static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp) | |||
90 | */ | 90 | */ |
91 | static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev) | 91 | static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev) |
92 | { | 92 | { |
93 | int count = 50; /* TODO: arbitrary for now. */ | 93 | int count = 100; |
94 | u32 value; | 94 | u32 value; |
95 | 95 | ||
96 | do { | 96 | do { |
97 | value = ql_read32(qdev, STS); | 97 | value = ql_read32(qdev, STS); |
98 | if (value & STS_PI) | 98 | if (value & STS_PI) |
99 | return 0; | 99 | return 0; |
100 | udelay(UDELAY_DELAY); /* 10us */ | 100 | mdelay(UDELAY_DELAY); /* 100ms */ |
101 | } while (--count); | 101 | } while (--count); |
102 | return -ETIMEDOUT; | 102 | return -ETIMEDOUT; |
103 | } | 103 | } |
@@ -453,6 +453,13 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) | |||
453 | } | 453 | } |
454 | end: | 454 | end: |
455 | ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT); | 455 | ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT); |
456 | /* Restore the original mailbox count to | ||
457 | * what the caller asked for. This can get | ||
458 | * changed when a mailbox command is waiting | ||
459 | * for a response and an AEN arrives and | ||
460 | * is handled. | ||
461 | * */ | ||
462 | mbcp->out_count = orig_count; | ||
456 | return status; | 463 | return status; |
457 | } | 464 | } |
458 | 465 | ||
@@ -540,6 +547,40 @@ end: | |||
540 | return status; | 547 | return status; |
541 | } | 548 | } |
542 | 549 | ||
550 | |||
551 | /* Get MPI firmware version. This will be used for | ||
552 | * driver banner and for ethtool info. | ||
553 | * Returns zero on success. | ||
554 | */ | ||
555 | int ql_mb_about_fw(struct ql_adapter *qdev) | ||
556 | { | ||
557 | struct mbox_params mbc; | ||
558 | struct mbox_params *mbcp = &mbc; | ||
559 | int status = 0; | ||
560 | |||
561 | memset(mbcp, 0, sizeof(struct mbox_params)); | ||
562 | |||
563 | mbcp->in_count = 1; | ||
564 | mbcp->out_count = 3; | ||
565 | |||
566 | mbcp->mbox_in[0] = MB_CMD_ABOUT_FW; | ||
567 | |||
568 | status = ql_mailbox_command(qdev, mbcp); | ||
569 | if (status) | ||
570 | return status; | ||
571 | |||
572 | if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) { | ||
573 | QPRINTK(qdev, DRV, ERR, | ||
574 | "Failed about firmware command\n"); | ||
575 | status = -EIO; | ||
576 | } | ||
577 | |||
578 | /* Store the firmware version */ | ||
579 | qdev->fw_rev_id = mbcp->mbox_out[1]; | ||
580 | |||
581 | return status; | ||
582 | } | ||
583 | |||
543 | /* Get functional state for MPI firmware. | 584 | /* Get functional state for MPI firmware. |
544 | * Returns zero on success. | 585 | * Returns zero on success. |
545 | */ | 586 | */ |
@@ -754,7 +795,6 @@ void ql_mpi_port_cfg_work(struct work_struct *work) | |||
754 | { | 795 | { |
755 | struct ql_adapter *qdev = | 796 | struct ql_adapter *qdev = |
756 | container_of(work, struct ql_adapter, mpi_port_cfg_work.work); | 797 | container_of(work, struct ql_adapter, mpi_port_cfg_work.work); |
757 | struct net_device *ndev = qdev->ndev; | ||
758 | int status; | 798 | int status; |
759 | 799 | ||
760 | status = ql_mb_get_port_cfg(qdev); | 800 | status = ql_mb_get_port_cfg(qdev); |
@@ -764,9 +804,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work) | |||
764 | goto err; | 804 | goto err; |
765 | } | 805 | } |
766 | 806 | ||
767 | if (ndev->mtu <= 2500) | 807 | if (qdev->link_config & CFG_JUMBO_FRAME_SIZE && |
768 | goto end; | ||
769 | else if (qdev->link_config & CFG_JUMBO_FRAME_SIZE && | ||
770 | qdev->max_frame_size == | 808 | qdev->max_frame_size == |
771 | CFG_DEFAULT_MAX_FRAME_SIZE) | 809 | CFG_DEFAULT_MAX_FRAME_SIZE) |
772 | goto end; | 810 | goto end; |
@@ -831,13 +869,19 @@ void ql_mpi_work(struct work_struct *work) | |||
831 | container_of(work, struct ql_adapter, mpi_work.work); | 869 | container_of(work, struct ql_adapter, mpi_work.work); |
832 | struct mbox_params mbc; | 870 | struct mbox_params mbc; |
833 | struct mbox_params *mbcp = &mbc; | 871 | struct mbox_params *mbcp = &mbc; |
872 | int err = 0; | ||
834 | 873 | ||
835 | mutex_lock(&qdev->mpi_mutex); | 874 | mutex_lock(&qdev->mpi_mutex); |
836 | 875 | ||
837 | while (ql_read32(qdev, STS) & STS_PI) { | 876 | while (ql_read32(qdev, STS) & STS_PI) { |
838 | memset(mbcp, 0, sizeof(struct mbox_params)); | 877 | memset(mbcp, 0, sizeof(struct mbox_params)); |
839 | mbcp->out_count = 1; | 878 | mbcp->out_count = 1; |
840 | ql_mpi_handler(qdev, mbcp); | 879 | /* Don't continue if an async event |
880 | * did not complete properly. | ||
881 | */ | ||
882 | err = ql_mpi_handler(qdev, mbcp); | ||
883 | if (err) | ||
884 | break; | ||
841 | } | 885 | } |
842 | 886 | ||
843 | mutex_unlock(&qdev->mpi_mutex); | 887 | mutex_unlock(&qdev->mpi_mutex); |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index e94316b7868b..007c881896d2 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -3379,7 +3379,7 @@ static void rtl8169_tx_interrupt(struct net_device *dev, | |||
3379 | rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry); | 3379 | rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry); |
3380 | 3380 | ||
3381 | if (status & LastFrag) { | 3381 | if (status & LastFrag) { |
3382 | dev_kfree_skb_irq(tx_skb->skb); | 3382 | dev_kfree_skb(tx_skb->skb); |
3383 | tx_skb->skb = NULL; | 3383 | tx_skb->skb = NULL; |
3384 | } | 3384 | } |
3385 | dirty_tx++; | 3385 | dirty_tx++; |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 2bc73ede4312..458daa06ed41 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -1764,7 +1764,7 @@ static int init_nic(struct s2io_nic *nic) | |||
1764 | * by then we return error. | 1764 | * by then we return error. |
1765 | */ | 1765 | */ |
1766 | time = 0; | 1766 | time = 0; |
1767 | while (TRUE) { | 1767 | while (true) { |
1768 | val64 = readq(&bar0->rti_command_mem); | 1768 | val64 = readq(&bar0->rti_command_mem); |
1769 | if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD)) | 1769 | if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD)) |
1770 | break; | 1770 | break; |
@@ -2137,7 +2137,7 @@ static int verify_pcc_quiescent(struct s2io_nic *sp, int flag) | |||
2137 | 2137 | ||
2138 | herc = (sp->device_type == XFRAME_II_DEVICE); | 2138 | herc = (sp->device_type == XFRAME_II_DEVICE); |
2139 | 2139 | ||
2140 | if (flag == FALSE) { | 2140 | if (flag == false) { |
2141 | if ((!herc && (sp->pdev->revision >= 4)) || herc) { | 2141 | if ((!herc && (sp->pdev->revision >= 4)) || herc) { |
2142 | if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE)) | 2142 | if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE)) |
2143 | ret = 1; | 2143 | ret = 1; |
@@ -3587,7 +3587,7 @@ static void s2io_reset(struct s2io_nic * sp) | |||
3587 | writeq(val64, &bar0->pcc_err_reg); | 3587 | writeq(val64, &bar0->pcc_err_reg); |
3588 | } | 3588 | } |
3589 | 3589 | ||
3590 | sp->device_enabled_once = FALSE; | 3590 | sp->device_enabled_once = false; |
3591 | } | 3591 | } |
3592 | 3592 | ||
3593 | /** | 3593 | /** |
@@ -5572,10 +5572,10 @@ static void s2io_ethtool_getpause_data(struct net_device *dev, | |||
5572 | 5572 | ||
5573 | val64 = readq(&bar0->rmac_pause_cfg); | 5573 | val64 = readq(&bar0->rmac_pause_cfg); |
5574 | if (val64 & RMAC_PAUSE_GEN_ENABLE) | 5574 | if (val64 & RMAC_PAUSE_GEN_ENABLE) |
5575 | ep->tx_pause = TRUE; | 5575 | ep->tx_pause = true; |
5576 | if (val64 & RMAC_PAUSE_RX_ENABLE) | 5576 | if (val64 & RMAC_PAUSE_RX_ENABLE) |
5577 | ep->rx_pause = TRUE; | 5577 | ep->rx_pause = true; |
5578 | ep->autoneg = FALSE; | 5578 | ep->autoneg = false; |
5579 | } | 5579 | } |
5580 | 5580 | ||
5581 | /** | 5581 | /** |
@@ -6806,7 +6806,7 @@ static void s2io_set_link(struct work_struct *work) | |||
6806 | val64 |= ADAPTER_LED_ON; | 6806 | val64 |= ADAPTER_LED_ON; |
6807 | writeq(val64, &bar0->adapter_control); | 6807 | writeq(val64, &bar0->adapter_control); |
6808 | } | 6808 | } |
6809 | nic->device_enabled_once = TRUE; | 6809 | nic->device_enabled_once = true; |
6810 | } else { | 6810 | } else { |
6811 | DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name); | 6811 | DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name); |
6812 | DBG_PRINT(ERR_DBG, "device is not Quiescent\n"); | 6812 | DBG_PRINT(ERR_DBG, "device is not Quiescent\n"); |
@@ -7754,7 +7754,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7754 | struct s2io_nic *sp; | 7754 | struct s2io_nic *sp; |
7755 | struct net_device *dev; | 7755 | struct net_device *dev; |
7756 | int i, j, ret; | 7756 | int i, j, ret; |
7757 | int dma_flag = FALSE; | 7757 | int dma_flag = false; |
7758 | u32 mac_up, mac_down; | 7758 | u32 mac_up, mac_down; |
7759 | u64 val64 = 0, tmp64 = 0; | 7759 | u64 val64 = 0, tmp64 = 0; |
7760 | struct XENA_dev_config __iomem *bar0 = NULL; | 7760 | struct XENA_dev_config __iomem *bar0 = NULL; |
@@ -7777,7 +7777,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7777 | 7777 | ||
7778 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { | 7778 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { |
7779 | DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n"); | 7779 | DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n"); |
7780 | dma_flag = TRUE; | 7780 | dma_flag = true; |
7781 | if (pci_set_consistent_dma_mask | 7781 | if (pci_set_consistent_dma_mask |
7782 | (pdev, DMA_BIT_MASK(64))) { | 7782 | (pdev, DMA_BIT_MASK(64))) { |
7783 | DBG_PRINT(ERR_DBG, | 7783 | DBG_PRINT(ERR_DBG, |
@@ -7818,7 +7818,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7818 | sp->dev = dev; | 7818 | sp->dev = dev; |
7819 | sp->pdev = pdev; | 7819 | sp->pdev = pdev; |
7820 | sp->high_dma_flag = dma_flag; | 7820 | sp->high_dma_flag = dma_flag; |
7821 | sp->device_enabled_once = FALSE; | 7821 | sp->device_enabled_once = false; |
7822 | if (rx_ring_mode == 1) | 7822 | if (rx_ring_mode == 1) |
7823 | sp->rxd_mode = RXD_MODE_1; | 7823 | sp->rxd_mode = RXD_MODE_1; |
7824 | if (rx_ring_mode == 2) | 7824 | if (rx_ring_mode == 2) |
@@ -7964,7 +7964,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7964 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 7964 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
7965 | 7965 | ||
7966 | dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; | 7966 | dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; |
7967 | if (sp->high_dma_flag == TRUE) | 7967 | if (sp->high_dma_flag == true) |
7968 | dev->features |= NETIF_F_HIGHDMA; | 7968 | dev->features |= NETIF_F_HIGHDMA; |
7969 | dev->features |= NETIF_F_TSO; | 7969 | dev->features |= NETIF_F_TSO; |
7970 | dev->features |= NETIF_F_TSO6; | 7970 | dev->features |= NETIF_F_TSO6; |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 55cb943f23f8..d5c5be6c07b9 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -18,15 +18,6 @@ | |||
18 | #define vBIT(val, loc, sz) (((u64)val) << (64-loc-sz)) | 18 | #define vBIT(val, loc, sz) (((u64)val) << (64-loc-sz)) |
19 | #define INV(d) ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff) | 19 | #define INV(d) ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff) |
20 | 20 | ||
21 | #ifndef BOOL | ||
22 | #define BOOL int | ||
23 | #endif | ||
24 | |||
25 | #ifndef TRUE | ||
26 | #define TRUE 1 | ||
27 | #define FALSE 0 | ||
28 | #endif | ||
29 | |||
30 | #undef SUCCESS | 21 | #undef SUCCESS |
31 | #define SUCCESS 0 | 22 | #define SUCCESS 0 |
32 | #define FAILURE -1 | 23 | #define FAILURE -1 |
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index db723c58f6f1..f4d509015f75 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
@@ -63,6 +63,7 @@ | |||
63 | 63 | ||
64 | /* extended status register */ | 64 | /* extended status register */ |
65 | #define PMA_PMD_XSTATUS_REG 49153 | 65 | #define PMA_PMD_XSTATUS_REG 49153 |
66 | #define PMA_PMD_XSTAT_MDIX_LBN 14 | ||
66 | #define PMA_PMD_XSTAT_FLP_LBN (12) | 67 | #define PMA_PMD_XSTAT_FLP_LBN (12) |
67 | 68 | ||
68 | /* LED control register */ | 69 | /* LED control register */ |
@@ -741,9 +742,17 @@ tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | |||
741 | 742 | ||
742 | mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa); | 743 | mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa); |
743 | 744 | ||
744 | if (efx->phy_type != PHY_TYPE_SFX7101) | 745 | if (efx->phy_type != PHY_TYPE_SFX7101) { |
745 | ecmd->supported |= (SUPPORTED_100baseT_Full | | 746 | ecmd->supported |= (SUPPORTED_100baseT_Full | |
746 | SUPPORTED_1000baseT_Full); | 747 | SUPPORTED_1000baseT_Full); |
748 | if (ecmd->speed != SPEED_10000) { | ||
749 | ecmd->eth_tp_mdix = | ||
750 | (efx_mdio_read(efx, MDIO_MMD_PMAPMD, | ||
751 | PMA_PMD_XSTATUS_REG) & | ||
752 | (1 << PMA_PMD_XSTAT_MDIX_LBN)) | ||
753 | ? ETH_TP_MDI_X : ETH_TP_MDI; | ||
754 | } | ||
755 | } | ||
747 | 756 | ||
748 | /* In loopback, the PHY automatically brings up the correct interface, | 757 | /* In loopback, the PHY automatically brings up the correct interface, |
749 | * but doesn't advertise the correct speed. So override it */ | 758 | * but doesn't advertise the correct speed. So override it */ |
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 13b8ca41d571..e2247669a495 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #define PHY_ID_ANY 0x1f | 47 | #define PHY_ID_ANY 0x1f |
48 | #define MII_REG_ANY 0x1f | 48 | #define MII_REG_ANY 0x1f |
49 | 49 | ||
50 | #define DRV_VERSION "1.2" | 50 | #define DRV_VERSION "1.3" |
51 | #define DRV_NAME "sis190" | 51 | #define DRV_NAME "sis190" |
52 | #define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION | 52 | #define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION |
53 | #define PFX DRV_NAME ": " | 53 | #define PFX DRV_NAME ": " |
@@ -317,6 +317,7 @@ static struct mii_chip_info { | |||
317 | unsigned int type; | 317 | unsigned int type; |
318 | u32 feature; | 318 | u32 feature; |
319 | } mii_chip_table[] = { | 319 | } mii_chip_table[] = { |
320 | { "Atheros PHY", { 0x004d, 0xd010 }, LAN, 0 }, | ||
320 | { "Atheros PHY AR8012", { 0x004d, 0xd020 }, LAN, 0 }, | 321 | { "Atheros PHY AR8012", { 0x004d, 0xd020 }, LAN, 0 }, |
321 | { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 }, | 322 | { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 }, |
322 | { "Broadcom PHY AC131", { 0x0143, 0xbc70 }, LAN, 0 }, | 323 | { "Broadcom PHY AC131", { 0x0143, 0xbc70 }, LAN, 0 }, |
@@ -347,7 +348,7 @@ static struct { | |||
347 | u32 msg_enable; | 348 | u32 msg_enable; |
348 | } debug = { -1 }; | 349 | } debug = { -1 }; |
349 | 350 | ||
350 | MODULE_DESCRIPTION("SiS sis190 Gigabit Ethernet driver"); | 351 | MODULE_DESCRIPTION("SiS sis190/191 Gigabit Ethernet driver"); |
351 | module_param(rx_copybreak, int, 0); | 352 | module_param(rx_copybreak, int, 0); |
352 | MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); | 353 | MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); |
353 | module_param_named(debug, debug.msg_enable, int, 0); | 354 | module_param_named(debug, debug.msg_enable, int, 0); |
@@ -539,8 +540,8 @@ static bool sis190_try_rx_copy(struct sis190_private *tp, | |||
539 | if (!skb) | 540 | if (!skb) |
540 | goto out; | 541 | goto out; |
541 | 542 | ||
542 | pci_dma_sync_single_for_device(tp->pci_dev, addr, pkt_size, | 543 | pci_dma_sync_single_for_cpu(tp->pci_dev, addr, tp->rx_buf_sz, |
543 | PCI_DMA_FROMDEVICE); | 544 | PCI_DMA_FROMDEVICE); |
544 | skb_reserve(skb, 2); | 545 | skb_reserve(skb, 2); |
545 | skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size); | 546 | skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size); |
546 | *sk_buff = skb; | 547 | *sk_buff = skb; |
@@ -942,9 +943,9 @@ static void sis190_phy_task(struct work_struct *work) | |||
942 | u32 ctl; | 943 | u32 ctl; |
943 | const char *msg; | 944 | const char *msg; |
944 | } reg31[] = { | 945 | } reg31[] = { |
945 | { LPA_1000XFULL | LPA_SLCT, 0x07000c00 | 0x00001000, | 946 | { LPA_1000FULL, 0x07000c00 | 0x00001000, |
946 | "1000 Mbps Full Duplex" }, | 947 | "1000 Mbps Full Duplex" }, |
947 | { LPA_1000XHALF | LPA_SLCT, 0x07000c00, | 948 | { LPA_1000HALF, 0x07000c00, |
948 | "1000 Mbps Half Duplex" }, | 949 | "1000 Mbps Half Duplex" }, |
949 | { LPA_100FULL, 0x04000800 | 0x00001000, | 950 | { LPA_100FULL, 0x04000800 | 0x00001000, |
950 | "100 Mbps Full Duplex" }, | 951 | "100 Mbps Full Duplex" }, |
@@ -955,22 +956,35 @@ static void sis190_phy_task(struct work_struct *work) | |||
955 | { LPA_10HALF, 0x04000400, | 956 | { LPA_10HALF, 0x04000400, |
956 | "10 Mbps Half Duplex" }, | 957 | "10 Mbps Half Duplex" }, |
957 | { 0, 0x04000400, "unknown" } | 958 | { 0, 0x04000400, "unknown" } |
958 | }, *p; | 959 | }, *p = NULL; |
959 | u16 adv; | 960 | u16 adv, autoexp, gigadv, gigrec; |
960 | 961 | ||
961 | val = mdio_read(ioaddr, phy_id, 0x1f); | 962 | val = mdio_read(ioaddr, phy_id, 0x1f); |
962 | net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val); | 963 | net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val); |
963 | 964 | ||
964 | val = mdio_read(ioaddr, phy_id, MII_LPA); | 965 | val = mdio_read(ioaddr, phy_id, MII_LPA); |
965 | adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE); | 966 | adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE); |
966 | net_link(tp, KERN_INFO "%s: mii lpa = %04x adv = %04x.\n", | 967 | autoexp = mdio_read(ioaddr, phy_id, MII_EXPANSION); |
967 | dev->name, val, adv); | 968 | net_link(tp, KERN_INFO "%s: mii lpa=%04x adv=%04x exp=%04x.\n", |
968 | 969 | dev->name, val, adv, autoexp); | |
969 | val &= adv; | 970 | |
971 | if (val & LPA_NPAGE && autoexp & EXPANSION_NWAY) { | ||
972 | /* check for gigabit speed */ | ||
973 | gigadv = mdio_read(ioaddr, phy_id, MII_CTRL1000); | ||
974 | gigrec = mdio_read(ioaddr, phy_id, MII_STAT1000); | ||
975 | val = (gigadv & (gigrec >> 2)); | ||
976 | if (val & ADVERTISE_1000FULL) | ||
977 | p = reg31; | ||
978 | else if (val & ADVERTISE_1000HALF) | ||
979 | p = reg31 + 1; | ||
980 | } | ||
981 | if (!p) { | ||
982 | val &= adv; | ||
970 | 983 | ||
971 | for (p = reg31; p->val; p++) { | 984 | for (p = reg31; p->val; p++) { |
972 | if ((val & p->val) == p->val) | 985 | if ((val & p->val) == p->val) |
973 | break; | 986 | break; |
987 | } | ||
974 | } | 988 | } |
975 | 989 | ||
976 | p->ctl |= SIS_R32(StationControl) & ~0x0f001c00; | 990 | p->ctl |= SIS_R32(StationControl) & ~0x0f001c00; |
@@ -1313,12 +1327,15 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp, | |||
1313 | ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ? | 1327 | ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ? |
1314 | LAN : HOME) : p->type; | 1328 | LAN : HOME) : p->type; |
1315 | tp->features |= p->feature; | 1329 | tp->features |= p->feature; |
1316 | } else | 1330 | net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n", |
1331 | pci_name(tp->pci_dev), p->name, phy_id); | ||
1332 | } else { | ||
1317 | phy->type = UNKNOWN; | 1333 | phy->type = UNKNOWN; |
1318 | 1334 | net_probe(tp, KERN_INFO | |
1319 | net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n", | 1335 | "%s: unknown PHY 0x%x:0x%x transceiver at address %d\n", |
1320 | pci_name(tp->pci_dev), | 1336 | pci_name(tp->pci_dev), |
1321 | (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id); | 1337 | phy->id[0], (phy->id[1] & 0xfff0), phy_id); |
1338 | } | ||
1322 | } | 1339 | } |
1323 | 1340 | ||
1324 | static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp) | 1341 | static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp) |
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 3cff84078a9e..b60639bd181b 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c | |||
@@ -2155,7 +2155,7 @@ static int smsc911x_resume(struct platform_device *pdev) | |||
2155 | 2155 | ||
2156 | static struct platform_driver smsc911x_driver = { | 2156 | static struct platform_driver smsc911x_driver = { |
2157 | .probe = smsc911x_drv_probe, | 2157 | .probe = smsc911x_drv_probe, |
2158 | .remove = smsc911x_drv_remove, | 2158 | .remove = __devexit_p(smsc911x_drv_remove), |
2159 | .driver = { | 2159 | .driver = { |
2160 | .name = SMSC_CHIPNAME, | 2160 | .name = SMSC_CHIPNAME, |
2161 | }, | 2161 | }, |
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 093807a182f2..3c2679cd196b 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c | |||
@@ -948,8 +948,7 @@ static void print_rxfd(struct rxf_desc *rxfd); | |||
948 | 948 | ||
949 | static void bdx_rxdb_destroy(struct rxdb *db) | 949 | static void bdx_rxdb_destroy(struct rxdb *db) |
950 | { | 950 | { |
951 | if (db) | 951 | vfree(db); |
952 | vfree(db); | ||
953 | } | 952 | } |
954 | 953 | ||
955 | static struct rxdb *bdx_rxdb_create(int nelem) | 954 | static struct rxdb *bdx_rxdb_create(int nelem) |
@@ -1482,10 +1481,8 @@ static void bdx_tx_db_close(struct txdb *d) | |||
1482 | { | 1481 | { |
1483 | BDX_ASSERT(d == NULL); | 1482 | BDX_ASSERT(d == NULL); |
1484 | 1483 | ||
1485 | if (d->start) { | 1484 | vfree(d->start); |
1486 | vfree(d->start); | 1485 | d->start = NULL; |
1487 | d->start = NULL; | ||
1488 | } | ||
1489 | } | 1486 | } |
1490 | 1487 | ||
1491 | /************************************************************************* | 1488 | /************************************************************************* |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a39b534fb43e..46a3f86125be 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -5021,7 +5021,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, | |||
5021 | /* New SKB is guaranteed to be linear. */ | 5021 | /* New SKB is guaranteed to be linear. */ |
5022 | entry = *start; | 5022 | entry = *start; |
5023 | ret = skb_dma_map(&tp->pdev->dev, new_skb, DMA_TO_DEVICE); | 5023 | ret = skb_dma_map(&tp->pdev->dev, new_skb, DMA_TO_DEVICE); |
5024 | new_addr = skb_shinfo(new_skb)->dma_maps[0]; | 5024 | new_addr = skb_shinfo(new_skb)->dma_head; |
5025 | 5025 | ||
5026 | /* Make sure new skb does not cross any 4G boundaries. | 5026 | /* Make sure new skb does not cross any 4G boundaries. |
5027 | * Drop the packet if it does. | 5027 | * Drop the packet if it does. |
@@ -5155,7 +5155,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
5155 | 5155 | ||
5156 | sp = skb_shinfo(skb); | 5156 | sp = skb_shinfo(skb); |
5157 | 5157 | ||
5158 | mapping = sp->dma_maps[0]; | 5158 | mapping = sp->dma_head; |
5159 | 5159 | ||
5160 | tp->tx_buffers[entry].skb = skb; | 5160 | tp->tx_buffers[entry].skb = skb; |
5161 | 5161 | ||
@@ -5173,7 +5173,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
5173 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 5173 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
5174 | 5174 | ||
5175 | len = frag->size; | 5175 | len = frag->size; |
5176 | mapping = sp->dma_maps[i + 1]; | 5176 | mapping = sp->dma_maps[i]; |
5177 | tp->tx_buffers[entry].skb = NULL; | 5177 | tp->tx_buffers[entry].skb = NULL; |
5178 | 5178 | ||
5179 | tg3_set_txd(tp, entry, mapping, len, | 5179 | tg3_set_txd(tp, entry, mapping, len, |
@@ -5331,7 +5331,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) | |||
5331 | 5331 | ||
5332 | sp = skb_shinfo(skb); | 5332 | sp = skb_shinfo(skb); |
5333 | 5333 | ||
5334 | mapping = sp->dma_maps[0]; | 5334 | mapping = sp->dma_head; |
5335 | 5335 | ||
5336 | tp->tx_buffers[entry].skb = skb; | 5336 | tp->tx_buffers[entry].skb = skb; |
5337 | 5337 | ||
@@ -5356,7 +5356,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) | |||
5356 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 5356 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
5357 | 5357 | ||
5358 | len = frag->size; | 5358 | len = frag->size; |
5359 | mapping = sp->dma_maps[i + 1]; | 5359 | mapping = sp->dma_maps[i]; |
5360 | 5360 | ||
5361 | tp->tx_buffers[entry].skb = NULL; | 5361 | tp->tx_buffers[entry].skb = NULL; |
5362 | 5362 | ||
diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig index d913405bc393..1cc8cf4425d1 100644 --- a/drivers/net/tulip/Kconfig +++ b/drivers/net/tulip/Kconfig | |||
@@ -27,6 +27,18 @@ config DE2104X | |||
27 | To compile this driver as a module, choose M here. The module will | 27 | To compile this driver as a module, choose M here. The module will |
28 | be called de2104x. | 28 | be called de2104x. |
29 | 29 | ||
30 | config DE2104X_DSL | ||
31 | int "Descriptor Skip Length in 32 bit longwords" | ||
32 | depends on DE2104X | ||
33 | range 0 31 | ||
34 | default 0 | ||
35 | help | ||
36 | Setting this value allows to align ring buffer descriptors into their | ||
37 | own cache lines. Value of 4 corresponds to the typical 32 byte line | ||
38 | (the descriptor is 16 bytes). This is necessary on systems that lack | ||
39 | cache coherence, an example is PowerMac 5500. Otherwise 0 is safe. | ||
40 | Default is 0, and range is 0 to 31. | ||
41 | |||
30 | config TULIP | 42 | config TULIP |
31 | tristate "DECchip Tulip (dc2114x) PCI support" | 43 | tristate "DECchip Tulip (dc2114x) PCI support" |
32 | depends on PCI | 44 | depends on PCI |
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index d4c5ecc51f77..e7609a05032d 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c | |||
@@ -82,6 +82,13 @@ MODULE_PARM_DESC (rx_copybreak, "de2104x Breakpoint at which Rx packets are copi | |||
82 | NETIF_MSG_RX_ERR | \ | 82 | NETIF_MSG_RX_ERR | \ |
83 | NETIF_MSG_TX_ERR) | 83 | NETIF_MSG_TX_ERR) |
84 | 84 | ||
85 | /* Descriptor skip length in 32 bit longwords. */ | ||
86 | #ifndef CONFIG_DE2104X_DSL | ||
87 | #define DSL 0 | ||
88 | #else | ||
89 | #define DSL CONFIG_DE2104X_DSL | ||
90 | #endif | ||
91 | |||
85 | #define DE_RX_RING_SIZE 64 | 92 | #define DE_RX_RING_SIZE 64 |
86 | #define DE_TX_RING_SIZE 64 | 93 | #define DE_TX_RING_SIZE 64 |
87 | #define DE_RING_BYTES \ | 94 | #define DE_RING_BYTES \ |
@@ -153,6 +160,7 @@ enum { | |||
153 | CmdReset = (1 << 0), | 160 | CmdReset = (1 << 0), |
154 | CacheAlign16 = 0x00008000, | 161 | CacheAlign16 = 0x00008000, |
155 | BurstLen4 = 0x00000400, | 162 | BurstLen4 = 0x00000400, |
163 | DescSkipLen = (DSL << 2), | ||
156 | 164 | ||
157 | /* Rx/TxPoll bits */ | 165 | /* Rx/TxPoll bits */ |
158 | NormalTxPoll = (1 << 0), | 166 | NormalTxPoll = (1 << 0), |
@@ -246,7 +254,7 @@ static const u32 de_intr_mask = | |||
246 | * Set the programmable burst length to 4 longwords for all: | 254 | * Set the programmable burst length to 4 longwords for all: |
247 | * DMA errors result without these values. Cache align 16 long. | 255 | * DMA errors result without these values. Cache align 16 long. |
248 | */ | 256 | */ |
249 | static const u32 de_bus_mode = CacheAlign16 | BurstLen4; | 257 | static const u32 de_bus_mode = CacheAlign16 | BurstLen4 | DescSkipLen; |
250 | 258 | ||
251 | struct de_srom_media_block { | 259 | struct de_srom_media_block { |
252 | u8 opts; | 260 | u8 opts; |
@@ -266,6 +274,9 @@ struct de_desc { | |||
266 | __le32 opts2; | 274 | __le32 opts2; |
267 | __le32 addr1; | 275 | __le32 addr1; |
268 | __le32 addr2; | 276 | __le32 addr2; |
277 | #if DSL | ||
278 | __le32 skip[DSL]; | ||
279 | #endif | ||
269 | }; | 280 | }; |
270 | 281 | ||
271 | struct media_info { | 282 | struct media_info { |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 3f0cdc14be82..811d3517fce0 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -565,9 +565,13 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, | |||
565 | if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) | 565 | if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) |
566 | return -EFAULT; | 566 | return -EFAULT; |
567 | 567 | ||
568 | if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && | ||
569 | gso.csum_start + gso.csum_offset + 2 > gso.hdr_len) | ||
570 | gso.hdr_len = gso.csum_start + gso.csum_offset + 2; | ||
571 | |||
568 | if (gso.hdr_len > len) | 572 | if (gso.hdr_len > len) |
569 | return -EINVAL; | 573 | return -EINVAL; |
570 | offset += sizeof(pi); | 574 | offset += sizeof(gso); |
571 | } | 575 | } |
572 | 576 | ||
573 | if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { | 577 | if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { |
@@ -1318,21 +1322,22 @@ static int tun_chr_open(struct inode *inode, struct file * file) | |||
1318 | static int tun_chr_close(struct inode *inode, struct file *file) | 1322 | static int tun_chr_close(struct inode *inode, struct file *file) |
1319 | { | 1323 | { |
1320 | struct tun_file *tfile = file->private_data; | 1324 | struct tun_file *tfile = file->private_data; |
1321 | struct tun_struct *tun = __tun_get(tfile); | 1325 | struct tun_struct *tun; |
1322 | 1326 | ||
1323 | 1327 | ||
1328 | rtnl_lock(); | ||
1329 | tun = __tun_get(tfile); | ||
1324 | if (tun) { | 1330 | if (tun) { |
1325 | DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name); | 1331 | DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name); |
1326 | 1332 | ||
1327 | rtnl_lock(); | ||
1328 | __tun_detach(tun); | 1333 | __tun_detach(tun); |
1329 | 1334 | ||
1330 | /* If desireable, unregister the netdevice. */ | 1335 | /* If desireable, unregister the netdevice. */ |
1331 | if (!(tun->flags & TUN_PERSIST)) | 1336 | if (!(tun->flags & TUN_PERSIST)) |
1332 | unregister_netdevice(tun->dev); | 1337 | unregister_netdevice(tun->dev); |
1333 | 1338 | ||
1334 | rtnl_unlock(); | ||
1335 | } | 1339 | } |
1340 | rtnl_unlock(); | ||
1336 | 1341 | ||
1337 | tun = tfile->tun; | 1342 | tun = tfile->tun; |
1338 | if (tun) | 1343 | if (tun) |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 5ddd8c4f9019..e3580f42c899 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -899,15 +899,14 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, | |||
899 | continue; | 899 | continue; |
900 | } | 900 | } |
901 | /* Allocate an sk_buff */ | 901 | /* Allocate an sk_buff */ |
902 | odev->skb_rx_buf = dev_alloc_skb(frame_len); | 902 | odev->skb_rx_buf = netdev_alloc_skb(odev->net, |
903 | frame_len); | ||
903 | if (!odev->skb_rx_buf) { | 904 | if (!odev->skb_rx_buf) { |
904 | /* We got no receive buffer. */ | 905 | /* We got no receive buffer. */ |
905 | D1("could not allocate memory"); | 906 | D1("could not allocate memory"); |
906 | odev->rx_parse_state = WAIT_SYNC; | 907 | odev->rx_parse_state = WAIT_SYNC; |
907 | return; | 908 | return; |
908 | } | 909 | } |
909 | /* Here's where it came from */ | ||
910 | odev->skb_rx_buf->dev = odev->net; | ||
911 | 910 | ||
912 | /* Copy what we got so far. make room for iphdr | 911 | /* Copy what we got so far. make room for iphdr |
913 | * after tail. */ | 912 | * after tail. */ |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 0c9ca67f66e6..09bd4410fa65 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -470,7 +470,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) | |||
470 | } | 470 | } |
471 | 471 | ||
472 | if (skb_is_gso(skb)) { | 472 | if (skb_is_gso(skb)) { |
473 | hdr->hdr_len = skb_transport_header(skb) - skb->data; | 473 | hdr->hdr_len = skb_headlen(skb); |
474 | hdr->gso_size = skb_shinfo(skb)->gso_size; | 474 | hdr->gso_size = skb_shinfo(skb)->gso_size; |
475 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) | 475 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) |
476 | hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; | 476 | hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; |
diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 6b41c884a337..26cde573af43 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c | |||
@@ -1884,17 +1884,13 @@ void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool) | |||
1884 | mempool->memblock_size, dma_object); | 1884 | mempool->memblock_size, dma_object); |
1885 | } | 1885 | } |
1886 | 1886 | ||
1887 | if (mempool->items_arr) | 1887 | vfree(mempool->items_arr); |
1888 | vfree(mempool->items_arr); | ||
1889 | 1888 | ||
1890 | if (mempool->memblocks_dma_arr) | 1889 | vfree(mempool->memblocks_dma_arr); |
1891 | vfree(mempool->memblocks_dma_arr); | ||
1892 | 1890 | ||
1893 | if (mempool->memblocks_priv_arr) | 1891 | vfree(mempool->memblocks_priv_arr); |
1894 | vfree(mempool->memblocks_priv_arr); | ||
1895 | 1892 | ||
1896 | if (mempool->memblocks_arr) | 1893 | vfree(mempool->memblocks_arr); |
1897 | vfree(mempool->memblocks_arr); | ||
1898 | 1894 | ||
1899 | vfree(mempool); | 1895 | vfree(mempool); |
1900 | } | 1896 | } |
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index daf4c805be58..fb7541c28e58 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -153,7 +153,7 @@ config LIBERTAS_SDIO | |||
153 | 153 | ||
154 | config LIBERTAS_SPI | 154 | config LIBERTAS_SPI |
155 | tristate "Marvell Libertas 8686 SPI 802.11b/g cards" | 155 | tristate "Marvell Libertas 8686 SPI 802.11b/g cards" |
156 | depends on LIBERTAS && SPI && GENERIC_GPIO | 156 | depends on LIBERTAS && SPI |
157 | ---help--- | 157 | ---help--- |
158 | A driver for Marvell Libertas 8686 SPI devices. | 158 | A driver for Marvell Libertas 8686 SPI devices. |
159 | 159 | ||
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index c7cba66b63cb..bb97981fb248 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h | |||
@@ -109,6 +109,11 @@ struct ar9170_rxstream_mpdu_merge { | |||
109 | bool has_plcp; | 109 | bool has_plcp; |
110 | }; | 110 | }; |
111 | 111 | ||
112 | #define AR9170_QUEUE_TIMEOUT 64 | ||
113 | #define AR9170_TX_TIMEOUT 8 | ||
114 | #define AR9170_JANITOR_DELAY 128 | ||
115 | #define AR9170_TX_INVALID_RATE 0xffffffff | ||
116 | |||
112 | struct ar9170 { | 117 | struct ar9170 { |
113 | struct ieee80211_hw *hw; | 118 | struct ieee80211_hw *hw; |
114 | struct mutex mutex; | 119 | struct mutex mutex; |
@@ -117,10 +122,11 @@ struct ar9170 { | |||
117 | 122 | ||
118 | int (*open)(struct ar9170 *); | 123 | int (*open)(struct ar9170 *); |
119 | void (*stop)(struct ar9170 *); | 124 | void (*stop)(struct ar9170 *); |
120 | int (*tx)(struct ar9170 *, struct sk_buff *, bool, unsigned int); | 125 | int (*tx)(struct ar9170 *, struct sk_buff *); |
121 | int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 , | 126 | int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 , |
122 | void *, u32 , void *); | 127 | void *, u32 , void *); |
123 | void (*callback_cmd)(struct ar9170 *, u32 , void *); | 128 | void (*callback_cmd)(struct ar9170 *, u32 , void *); |
129 | int (*flush)(struct ar9170 *); | ||
124 | 130 | ||
125 | /* interface mode settings */ | 131 | /* interface mode settings */ |
126 | struct ieee80211_vif *vif; | 132 | struct ieee80211_vif *vif; |
@@ -177,10 +183,10 @@ struct ar9170 { | |||
177 | struct ar9170_eeprom eeprom; | 183 | struct ar9170_eeprom eeprom; |
178 | struct ath_regulatory regulatory; | 184 | struct ath_regulatory regulatory; |
179 | 185 | ||
180 | /* global tx status for unregistered Stations. */ | 186 | /* tx queues - as seen by hw - */ |
181 | struct sk_buff_head global_tx_status; | 187 | struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; |
182 | struct sk_buff_head global_tx_status_waste; | 188 | struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; |
183 | struct delayed_work tx_status_janitor; | 189 | struct delayed_work tx_janitor; |
184 | 190 | ||
185 | /* rxstream mpdu merge */ | 191 | /* rxstream mpdu merge */ |
186 | struct ar9170_rxstream_mpdu_merge rx_mpdu; | 192 | struct ar9170_rxstream_mpdu_merge rx_mpdu; |
@@ -189,11 +195,19 @@ struct ar9170 { | |||
189 | }; | 195 | }; |
190 | 196 | ||
191 | struct ar9170_sta_info { | 197 | struct ar9170_sta_info { |
192 | struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; | ||
193 | }; | 198 | }; |
194 | 199 | ||
195 | #define IS_STARTED(a) (a->state >= AR9170_STARTED) | 200 | #define AR9170_TX_FLAG_WAIT_FOR_ACK BIT(0) |
196 | #define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE) | 201 | #define AR9170_TX_FLAG_NO_ACK BIT(1) |
202 | #define AR9170_TX_FLAG_BLOCK_ACK BIT(2) | ||
203 | |||
204 | struct ar9170_tx_info { | ||
205 | unsigned long timeout; | ||
206 | unsigned int flags; | ||
207 | }; | ||
208 | |||
209 | #define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) | ||
210 | #define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE) | ||
197 | 211 | ||
198 | #define AR9170_FILTER_CHANGED_MODE BIT(0) | 212 | #define AR9170_FILTER_CHANGED_MODE BIT(0) |
199 | #define AR9170_FILTER_CHANGED_MULTICAST BIT(1) | 213 | #define AR9170_FILTER_CHANGED_MULTICAST BIT(1) |
@@ -204,9 +218,9 @@ void *ar9170_alloc(size_t priv_size); | |||
204 | int ar9170_register(struct ar9170 *ar, struct device *pdev); | 218 | int ar9170_register(struct ar9170 *ar, struct device *pdev); |
205 | void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb); | 219 | void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb); |
206 | void ar9170_unregister(struct ar9170 *ar); | 220 | void ar9170_unregister(struct ar9170 *ar); |
207 | void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, | 221 | void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb); |
208 | bool update_statistics, u16 tx_status); | ||
209 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); | 222 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); |
223 | int ar9170_nag_limiter(struct ar9170 *ar); | ||
210 | 224 | ||
211 | /* MAC */ | 225 | /* MAC */ |
212 | int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | 226 | int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); |
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h index 3c8004fb7307..6cbfb2f83391 100644 --- a/drivers/net/wireless/ath/ar9170/hw.h +++ b/drivers/net/wireless/ath/ar9170/hw.h | |||
@@ -420,4 +420,7 @@ enum ar9170_txq { | |||
420 | __AR9170_NUM_TXQ, | 420 | __AR9170_NUM_TXQ, |
421 | }; | 421 | }; |
422 | 422 | ||
423 | #define AR9170_TXQ_DEPTH 32 | ||
424 | #define AR9170_TX_MAX_PENDING 128 | ||
425 | |||
423 | #endif /* __AR9170_HW_H */ | 426 | #endif /* __AR9170_HW_H */ |
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index b104d7efd676..9d38cf60a0db 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -173,59 +173,122 @@ static struct ieee80211_supported_band ar9170_band_5GHz = { | |||
173 | .ht_cap = AR9170_HT_CAP, | 173 | .ht_cap = AR9170_HT_CAP, |
174 | }; | 174 | }; |
175 | 175 | ||
176 | #ifdef AR9170_QUEUE_DEBUG | 176 | static void ar9170_tx(struct ar9170 *ar); |
177 | /* | ||
178 | * In case some wants works with AR9170's crazy tx_status queueing techniques. | ||
179 | * He might need this rather useful probing function. | ||
180 | * | ||
181 | * NOTE: caller must hold the queue's spinlock! | ||
182 | */ | ||
183 | 177 | ||
178 | #ifdef AR9170_QUEUE_DEBUG | ||
184 | static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) | 179 | static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) |
185 | { | 180 | { |
186 | struct ar9170_tx_control *txc = (void *) skb->data; | 181 | struct ar9170_tx_control *txc = (void *) skb->data; |
187 | struct ieee80211_hdr *hdr = (void *)txc->frame_data; | 182 | struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); |
183 | struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; | ||
184 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; | ||
188 | 185 | ||
189 | printk(KERN_DEBUG "%s: => FRAME [skb:%p, queue:%d, DA:[%pM] " | 186 | printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x " |
190 | "mac_control:%04x, phy_control:%08x]\n", | 187 | "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", |
191 | wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), | 188 | wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), |
192 | ieee80211_get_DA(hdr), le16_to_cpu(txc->mac_control), | 189 | ieee80211_get_DA(hdr), arinfo->flags, |
193 | le32_to_cpu(txc->phy_control)); | 190 | le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), |
191 | jiffies_to_msecs(arinfo->timeout - jiffies)); | ||
194 | } | 192 | } |
195 | 193 | ||
196 | static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar, | 194 | static void __ar9170_dump_txqueue(struct ar9170 *ar, |
197 | struct sk_buff_head *queue) | 195 | struct sk_buff_head *queue) |
198 | { | 196 | { |
199 | struct sk_buff *skb; | 197 | struct sk_buff *skb; |
200 | int i = 0; | 198 | int i = 0; |
201 | 199 | ||
202 | printk(KERN_DEBUG "---[ cut here ]---\n"); | 200 | printk(KERN_DEBUG "---[ cut here ]---\n"); |
203 | printk(KERN_DEBUG "%s: %d entries in tx_status queue.\n", | 201 | printk(KERN_DEBUG "%s: %d entries in queue.\n", |
204 | wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); | 202 | wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); |
205 | 203 | ||
206 | skb_queue_walk(queue, skb) { | 204 | skb_queue_walk(queue, skb) { |
207 | struct ar9170_tx_control *txc = (void *) skb->data; | 205 | printk(KERN_DEBUG "index:%d => \n", i++); |
208 | struct ieee80211_hdr *hdr = (void *)txc->frame_data; | ||
209 | |||
210 | printk(KERN_DEBUG "index:%d => \n", i); | ||
211 | ar9170_print_txheader(ar, skb); | 206 | ar9170_print_txheader(ar, skb); |
212 | } | 207 | } |
208 | if (i != skb_queue_len(queue)) | ||
209 | printk(KERN_DEBUG "WARNING: queue frame counter " | ||
210 | "mismatch %d != %d\n", skb_queue_len(queue), i); | ||
213 | printk(KERN_DEBUG "---[ end ]---\n"); | 211 | printk(KERN_DEBUG "---[ end ]---\n"); |
214 | } | 212 | } |
215 | #endif /* AR9170_QUEUE_DEBUG */ | ||
216 | 213 | ||
217 | void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, | 214 | static void ar9170_dump_txqueue(struct ar9170 *ar, |
218 | bool valid_status, u16 tx_status) | 215 | struct sk_buff_head *queue) |
216 | { | ||
217 | unsigned long flags; | ||
218 | |||
219 | spin_lock_irqsave(&queue->lock, flags); | ||
220 | __ar9170_dump_txqueue(ar, queue); | ||
221 | spin_unlock_irqrestore(&queue->lock, flags); | ||
222 | } | ||
223 | |||
224 | static void __ar9170_dump_txstats(struct ar9170 *ar) | ||
225 | { | ||
226 | int i; | ||
227 | |||
228 | printk(KERN_DEBUG "%s: QoS queue stats\n", | ||
229 | wiphy_name(ar->hw->wiphy)); | ||
230 | |||
231 | for (i = 0; i < __AR9170_NUM_TXQ; i++) | ||
232 | printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d\n", | ||
233 | wiphy_name(ar->hw->wiphy), i, ar->tx_stats[i].limit, | ||
234 | ar->tx_stats[i].len, skb_queue_len(&ar->tx_status[i])); | ||
235 | } | ||
236 | |||
237 | static void ar9170_dump_txstats(struct ar9170 *ar) | ||
219 | { | 238 | { |
220 | struct ieee80211_tx_info *txinfo; | ||
221 | unsigned int retries = 0, queue = skb_get_queue_mapping(skb); | ||
222 | unsigned long flags; | 239 | unsigned long flags; |
223 | 240 | ||
224 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | 241 | spin_lock_irqsave(&ar->tx_stats_lock, flags); |
225 | ar->tx_stats[queue].len--; | 242 | __ar9170_dump_txstats(ar); |
226 | if (ieee80211_queue_stopped(ar->hw, queue)) | ||
227 | ieee80211_wake_queue(ar->hw, queue); | ||
228 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | 243 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); |
244 | } | ||
245 | #endif /* AR9170_QUEUE_DEBUG */ | ||
246 | |||
247 | /* caller must guarantee exclusive access for _bin_ queue. */ | ||
248 | static void ar9170_recycle_expired(struct ar9170 *ar, | ||
249 | struct sk_buff_head *queue, | ||
250 | struct sk_buff_head *bin) | ||
251 | { | ||
252 | struct sk_buff *skb, *old = NULL; | ||
253 | unsigned long flags; | ||
254 | |||
255 | spin_lock_irqsave(&queue->lock, flags); | ||
256 | while ((skb = skb_peek(queue))) { | ||
257 | struct ieee80211_tx_info *txinfo; | ||
258 | struct ar9170_tx_info *arinfo; | ||
259 | |||
260 | txinfo = IEEE80211_SKB_CB(skb); | ||
261 | arinfo = (void *) txinfo->rate_driver_data; | ||
262 | |||
263 | if (time_is_before_jiffies(arinfo->timeout)) { | ||
264 | #ifdef AR9170_QUEUE_DEBUG | ||
265 | printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => " | ||
266 | "recycle \n", wiphy_name(ar->hw->wiphy), | ||
267 | jiffies, arinfo->timeout); | ||
268 | ar9170_print_txheader(ar, skb); | ||
269 | #endif /* AR9170_QUEUE_DEBUG */ | ||
270 | __skb_unlink(skb, queue); | ||
271 | __skb_queue_tail(bin, skb); | ||
272 | } else { | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | if (unlikely(old == skb)) { | ||
277 | /* bail out - queue is shot. */ | ||
278 | |||
279 | WARN_ON(1); | ||
280 | break; | ||
281 | } | ||
282 | old = skb; | ||
283 | } | ||
284 | spin_unlock_irqrestore(&queue->lock, flags); | ||
285 | } | ||
286 | |||
287 | static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, | ||
288 | u16 tx_status) | ||
289 | { | ||
290 | struct ieee80211_tx_info *txinfo; | ||
291 | unsigned int retries = 0; | ||
229 | 292 | ||
230 | txinfo = IEEE80211_SKB_CB(skb); | 293 | txinfo = IEEE80211_SKB_CB(skb); |
231 | ieee80211_tx_info_clear_status(txinfo); | 294 | ieee80211_tx_info_clear_status(txinfo); |
@@ -247,45 +310,61 @@ void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, | |||
247 | break; | 310 | break; |
248 | } | 311 | } |
249 | 312 | ||
250 | if (valid_status) | 313 | txinfo->status.rates[0].count = retries + 1; |
251 | txinfo->status.rates[0].count = retries + 1; | ||
252 | |||
253 | skb_pull(skb, sizeof(struct ar9170_tx_control)); | 314 | skb_pull(skb, sizeof(struct ar9170_tx_control)); |
254 | ieee80211_tx_status_irqsafe(ar->hw, skb); | 315 | ieee80211_tx_status_irqsafe(ar->hw, skb); |
255 | } | 316 | } |
256 | 317 | ||
257 | static struct sk_buff *ar9170_find_skb_in_queue(struct ar9170 *ar, | 318 | void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) |
258 | const u8 *mac, | ||
259 | const u32 queue, | ||
260 | struct sk_buff_head *q) | ||
261 | { | 319 | { |
320 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
321 | struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data; | ||
322 | unsigned int queue = skb_get_queue_mapping(skb); | ||
262 | unsigned long flags; | 323 | unsigned long flags; |
263 | struct sk_buff *skb; | ||
264 | 324 | ||
265 | spin_lock_irqsave(&q->lock, flags); | 325 | spin_lock_irqsave(&ar->tx_stats_lock, flags); |
266 | skb_queue_walk(q, skb) { | 326 | ar->tx_stats[queue].len--; |
267 | struct ar9170_tx_control *txc = (void *) skb->data; | ||
268 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; | ||
269 | u32 txc_queue = (le32_to_cpu(txc->phy_control) & | ||
270 | AR9170_TX_PHY_QOS_MASK) >> | ||
271 | AR9170_TX_PHY_QOS_SHIFT; | ||
272 | 327 | ||
273 | if ((queue != txc_queue) || | 328 | if (skb_queue_empty(&ar->tx_pending[queue])) { |
274 | (compare_ether_addr(ieee80211_get_DA(hdr), mac))) | 329 | #ifdef AR9170_QUEUE_STOP_DEBUG |
275 | continue; | 330 | printk(KERN_DEBUG "%s: wake queue %d\n", |
331 | wiphy_name(ar->hw->wiphy), queue); | ||
332 | __ar9170_dump_txstats(ar); | ||
333 | #endif /* AR9170_QUEUE_STOP_DEBUG */ | ||
334 | ieee80211_wake_queue(ar->hw, queue); | ||
335 | } | ||
336 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
276 | 337 | ||
277 | __skb_unlink(skb, q); | 338 | if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) { |
278 | spin_unlock_irqrestore(&q->lock, flags); | 339 | dev_kfree_skb_any(skb); |
279 | return skb; | 340 | } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) { |
341 | arinfo->timeout = jiffies + | ||
342 | msecs_to_jiffies(AR9170_TX_TIMEOUT); | ||
343 | |||
344 | skb_queue_tail(&ar->tx_status[queue], skb); | ||
345 | } else if (arinfo->flags & AR9170_TX_FLAG_NO_ACK) { | ||
346 | ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); | ||
347 | } else { | ||
348 | #ifdef AR9170_QUEUE_DEBUG | ||
349 | printk(KERN_DEBUG "%s: unsupported frame flags!\n", | ||
350 | wiphy_name(ar->hw->wiphy)); | ||
351 | ar9170_print_txheader(ar, skb); | ||
352 | #endif /* AR9170_QUEUE_DEBUG */ | ||
353 | dev_kfree_skb_any(skb); | ||
354 | } | ||
355 | |||
356 | if (!ar->tx_stats[queue].len && | ||
357 | !skb_queue_empty(&ar->tx_pending[queue])) { | ||
358 | ar9170_tx(ar); | ||
280 | } | 359 | } |
281 | spin_unlock_irqrestore(&q->lock, flags); | ||
282 | return NULL; | ||
283 | } | 360 | } |
284 | 361 | ||
285 | static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac, | 362 | static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, |
286 | const u32 queue) | 363 | const u8 *mac, |
364 | struct sk_buff_head *queue, | ||
365 | const u32 rate) | ||
287 | { | 366 | { |
288 | struct ieee80211_sta *sta; | 367 | unsigned long flags; |
289 | struct sk_buff *skb; | 368 | struct sk_buff *skb; |
290 | 369 | ||
291 | /* | 370 | /* |
@@ -296,78 +375,91 @@ static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac, | |||
296 | * the firmware provided (-> destination MAC, and phy_control) - | 375 | * the firmware provided (-> destination MAC, and phy_control) - |
297 | * and hope that we picked the right one... | 376 | * and hope that we picked the right one... |
298 | */ | 377 | */ |
299 | rcu_read_lock(); | ||
300 | sta = ieee80211_find_sta(ar->hw, mac); | ||
301 | |||
302 | if (likely(sta)) { | ||
303 | struct ar9170_sta_info *sta_priv = (void *) sta->drv_priv; | ||
304 | skb = skb_dequeue(&sta_priv->tx_status[queue]); | ||
305 | rcu_read_unlock(); | ||
306 | if (likely(skb)) | ||
307 | return skb; | ||
308 | } else | ||
309 | rcu_read_unlock(); | ||
310 | |||
311 | /* scan the waste queue for candidates */ | ||
312 | skb = ar9170_find_skb_in_queue(ar, mac, queue, | ||
313 | &ar->global_tx_status_waste); | ||
314 | if (!skb) { | ||
315 | /* so it still _must_ be in the global list. */ | ||
316 | skb = ar9170_find_skb_in_queue(ar, mac, queue, | ||
317 | &ar->global_tx_status); | ||
318 | } | ||
319 | 378 | ||
379 | spin_lock_irqsave(&queue->lock, flags); | ||
380 | skb_queue_walk(queue, skb) { | ||
381 | struct ar9170_tx_control *txc = (void *) skb->data; | ||
382 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; | ||
383 | u32 r; | ||
384 | |||
385 | if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) { | ||
320 | #ifdef AR9170_QUEUE_DEBUG | 386 | #ifdef AR9170_QUEUE_DEBUG |
321 | if (unlikely((!skb) && net_ratelimit())) { | 387 | printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n", |
322 | printk(KERN_ERR "%s: ESS:[%pM] does not have any " | 388 | wiphy_name(ar->hw->wiphy), mac, |
323 | "outstanding frames in this queue (%d).\n", | 389 | ieee80211_get_DA(hdr)); |
324 | wiphy_name(ar->hw->wiphy), mac, queue); | 390 | ar9170_print_txheader(ar, skb); |
391 | #endif /* AR9170_QUEUE_DEBUG */ | ||
392 | continue; | ||
393 | } | ||
394 | |||
395 | r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >> | ||
396 | AR9170_TX_PHY_MCS_SHIFT; | ||
397 | |||
398 | if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) { | ||
399 | #ifdef AR9170_QUEUE_DEBUG | ||
400 | printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n", | ||
401 | wiphy_name(ar->hw->wiphy), rate, r); | ||
402 | ar9170_print_txheader(ar, skb); | ||
403 | #endif /* AR9170_QUEUE_DEBUG */ | ||
404 | continue; | ||
405 | } | ||
406 | |||
407 | __skb_unlink(skb, queue); | ||
408 | spin_unlock_irqrestore(&queue->lock, flags); | ||
409 | return skb; | ||
325 | } | 410 | } |
411 | |||
412 | #ifdef AR9170_QUEUE_DEBUG | ||
413 | printk(KERN_ERR "%s: ESS:[%pM] does not have any " | ||
414 | "outstanding frames in queue.\n", | ||
415 | wiphy_name(ar->hw->wiphy), mac); | ||
416 | __ar9170_dump_txqueue(ar, queue); | ||
326 | #endif /* AR9170_QUEUE_DEBUG */ | 417 | #endif /* AR9170_QUEUE_DEBUG */ |
327 | return skb; | 418 | spin_unlock_irqrestore(&queue->lock, flags); |
419 | |||
420 | return NULL; | ||
328 | } | 421 | } |
329 | 422 | ||
330 | /* | 423 | /* |
331 | * This worker tries to keep the global tx_status queue empty. | 424 | * This worker tries to keeps an maintain tx_status queues. |
332 | * So we can guarantee that incoming tx_status reports for | 425 | * So we can guarantee that incoming tx_status reports are |
333 | * unregistered stations are always synced with the actual | 426 | * actually for a pending frame. |
334 | * frame - which we think - belongs to. | ||
335 | */ | 427 | */ |
336 | 428 | ||
337 | static void ar9170_tx_status_janitor(struct work_struct *work) | 429 | static void ar9170_tx_janitor(struct work_struct *work) |
338 | { | 430 | { |
339 | struct ar9170 *ar = container_of(work, struct ar9170, | 431 | struct ar9170 *ar = container_of(work, struct ar9170, |
340 | tx_status_janitor.work); | 432 | tx_janitor.work); |
341 | struct sk_buff *skb; | 433 | struct sk_buff_head waste; |
434 | unsigned int i; | ||
435 | bool resched = false; | ||
342 | 436 | ||
343 | if (unlikely(!IS_STARTED(ar))) | 437 | if (unlikely(!IS_STARTED(ar))) |
344 | return ; | 438 | return ; |
345 | 439 | ||
346 | /* recycle the garbage back to mac80211... one by one. */ | 440 | skb_queue_head_init(&waste); |
347 | while ((skb = skb_dequeue(&ar->global_tx_status_waste))) { | 441 | |
442 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | ||
348 | #ifdef AR9170_QUEUE_DEBUG | 443 | #ifdef AR9170_QUEUE_DEBUG |
349 | printk(KERN_DEBUG "%s: dispose queued frame =>\n", | 444 | printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n", |
350 | wiphy_name(ar->hw->wiphy)); | 445 | wiphy_name(ar->hw->wiphy), i); |
351 | ar9170_print_txheader(ar, skb); | 446 | ar9170_dump_txqueue(ar, &ar->tx_pending[i]); |
447 | ar9170_dump_txqueue(ar, &ar->tx_status[i]); | ||
352 | #endif /* AR9170_QUEUE_DEBUG */ | 448 | #endif /* AR9170_QUEUE_DEBUG */ |
353 | ar9170_handle_tx_status(ar, skb, false, | ||
354 | AR9170_TX_STATUS_FAILED); | ||
355 | } | ||
356 | 449 | ||
357 | while ((skb = skb_dequeue(&ar->global_tx_status))) { | 450 | ar9170_recycle_expired(ar, &ar->tx_status[i], &waste); |
358 | #ifdef AR9170_QUEUE_DEBUG | 451 | ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste); |
359 | printk(KERN_DEBUG "%s: moving frame into waste queue =>\n", | 452 | skb_queue_purge(&waste); |
360 | wiphy_name(ar->hw->wiphy)); | ||
361 | 453 | ||
362 | ar9170_print_txheader(ar, skb); | 454 | if (!skb_queue_empty(&ar->tx_status[i]) || |
363 | #endif /* AR9170_QUEUE_DEBUG */ | 455 | !skb_queue_empty(&ar->tx_pending[i])) |
364 | skb_queue_tail(&ar->global_tx_status_waste, skb); | 456 | resched = true; |
365 | } | 457 | } |
366 | 458 | ||
367 | /* recall the janitor in 100ms - if there's garbage in the can. */ | 459 | if (resched) |
368 | if (skb_queue_len(&ar->global_tx_status_waste) > 0) | 460 | queue_delayed_work(ar->hw->workqueue, |
369 | queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor, | 461 | &ar->tx_janitor, |
370 | msecs_to_jiffies(100)); | 462 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); |
371 | } | 463 | } |
372 | 464 | ||
373 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | 465 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) |
@@ -394,15 +486,21 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | |||
394 | */ | 486 | */ |
395 | 487 | ||
396 | struct sk_buff *skb; | 488 | struct sk_buff *skb; |
397 | u32 queue = (le32_to_cpu(cmd->tx_status.rate) & | 489 | u32 phy = le32_to_cpu(cmd->tx_status.rate); |
398 | AR9170_TX_PHY_QOS_MASK) >> AR9170_TX_PHY_QOS_SHIFT; | 490 | u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >> |
491 | AR9170_TX_PHY_QOS_SHIFT; | ||
492 | #ifdef AR9170_QUEUE_DEBUG | ||
493 | printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n", | ||
494 | wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q); | ||
495 | #endif /* AR9170_QUEUE_DEBUG */ | ||
399 | 496 | ||
400 | skb = ar9170_find_queued_skb(ar, cmd->tx_status.dst, queue); | 497 | skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst, |
498 | &ar->tx_status[q], | ||
499 | AR9170_TX_INVALID_RATE); | ||
401 | if (unlikely(!skb)) | 500 | if (unlikely(!skb)) |
402 | return ; | 501 | return ; |
403 | 502 | ||
404 | ar9170_handle_tx_status(ar, skb, true, | 503 | ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status)); |
405 | le16_to_cpu(cmd->tx_status.status)); | ||
406 | break; | 504 | break; |
407 | } | 505 | } |
408 | 506 | ||
@@ -442,6 +540,38 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | |||
442 | /* retransmission issue / SIFS/EIFS collision ?! */ | 540 | /* retransmission issue / SIFS/EIFS collision ?! */ |
443 | break; | 541 | break; |
444 | 542 | ||
543 | /* firmware debug */ | ||
544 | case 0xca: | ||
545 | printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, (char *)buf + 4); | ||
546 | break; | ||
547 | case 0xcb: | ||
548 | len -= 4; | ||
549 | |||
550 | switch (len) { | ||
551 | case 1: | ||
552 | printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n", | ||
553 | *((char *)buf + 4)); | ||
554 | break; | ||
555 | case 2: | ||
556 | printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n", | ||
557 | le16_to_cpup((__le16 *)((char *)buf + 4))); | ||
558 | break; | ||
559 | case 4: | ||
560 | printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n", | ||
561 | le32_to_cpup((__le32 *)((char *)buf + 4))); | ||
562 | break; | ||
563 | case 8: | ||
564 | printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n", | ||
565 | (unsigned long)le64_to_cpup( | ||
566 | (__le64 *)((char *)buf + 4))); | ||
567 | break; | ||
568 | } | ||
569 | break; | ||
570 | case 0xcc: | ||
571 | print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE, | ||
572 | (char *)buf + 4, len - 4); | ||
573 | break; | ||
574 | |||
445 | default: | 575 | default: |
446 | printk(KERN_INFO "received unhandled event %x\n", cmd->type); | 576 | printk(KERN_INFO "received unhandled event %x\n", cmd->type); |
447 | print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); | 577 | print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); |
@@ -455,7 +585,7 @@ static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar) | |||
455 | ar->rx_mpdu.has_plcp = false; | 585 | ar->rx_mpdu.has_plcp = false; |
456 | } | 586 | } |
457 | 587 | ||
458 | static int ar9170_nag_limiter(struct ar9170 *ar) | 588 | int ar9170_nag_limiter(struct ar9170 *ar) |
459 | { | 589 | { |
460 | bool print_message; | 590 | bool print_message; |
461 | 591 | ||
@@ -956,8 +1086,8 @@ static int ar9170_op_start(struct ieee80211_hw *hw) | |||
956 | 1086 | ||
957 | /* reinitialize queues statistics */ | 1087 | /* reinitialize queues statistics */ |
958 | memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); | 1088 | memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); |
959 | for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++) | 1089 | for (i = 0; i < __AR9170_NUM_TXQ; i++) |
960 | ar->tx_stats[i].limit = 8; | 1090 | ar->tx_stats[i].limit = AR9170_TXQ_DEPTH; |
961 | 1091 | ||
962 | /* reset QoS defaults */ | 1092 | /* reset QoS defaults */ |
963 | AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/ | 1093 | AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/ |
@@ -1003,18 +1133,17 @@ out: | |||
1003 | static void ar9170_op_stop(struct ieee80211_hw *hw) | 1133 | static void ar9170_op_stop(struct ieee80211_hw *hw) |
1004 | { | 1134 | { |
1005 | struct ar9170 *ar = hw->priv; | 1135 | struct ar9170 *ar = hw->priv; |
1136 | unsigned int i; | ||
1006 | 1137 | ||
1007 | if (IS_STARTED(ar)) | 1138 | if (IS_STARTED(ar)) |
1008 | ar->state = AR9170_IDLE; | 1139 | ar->state = AR9170_IDLE; |
1009 | 1140 | ||
1010 | flush_workqueue(ar->hw->workqueue); | 1141 | flush_workqueue(ar->hw->workqueue); |
1011 | 1142 | ||
1012 | cancel_delayed_work_sync(&ar->tx_status_janitor); | 1143 | cancel_delayed_work_sync(&ar->tx_janitor); |
1013 | cancel_work_sync(&ar->filter_config_work); | 1144 | cancel_work_sync(&ar->filter_config_work); |
1014 | cancel_work_sync(&ar->beacon_work); | 1145 | cancel_work_sync(&ar->beacon_work); |
1015 | mutex_lock(&ar->mutex); | 1146 | mutex_lock(&ar->mutex); |
1016 | skb_queue_purge(&ar->global_tx_status_waste); | ||
1017 | skb_queue_purge(&ar->global_tx_status); | ||
1018 | 1147 | ||
1019 | if (IS_ACCEPTING_CMD(ar)) { | 1148 | if (IS_ACCEPTING_CMD(ar)) { |
1020 | ar9170_set_leds_state(ar, 0); | 1149 | ar9170_set_leds_state(ar, 0); |
@@ -1024,51 +1153,32 @@ static void ar9170_op_stop(struct ieee80211_hw *hw) | |||
1024 | ar->stop(ar); | 1153 | ar->stop(ar); |
1025 | } | 1154 | } |
1026 | 1155 | ||
1156 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | ||
1157 | skb_queue_purge(&ar->tx_pending[i]); | ||
1158 | skb_queue_purge(&ar->tx_status[i]); | ||
1159 | } | ||
1027 | mutex_unlock(&ar->mutex); | 1160 | mutex_unlock(&ar->mutex); |
1028 | } | 1161 | } |
1029 | 1162 | ||
1030 | int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 1163 | static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) |
1031 | { | 1164 | { |
1032 | struct ar9170 *ar = hw->priv; | ||
1033 | struct ieee80211_hdr *hdr; | 1165 | struct ieee80211_hdr *hdr; |
1034 | struct ar9170_tx_control *txc; | 1166 | struct ar9170_tx_control *txc; |
1035 | struct ieee80211_tx_info *info; | 1167 | struct ieee80211_tx_info *info; |
1036 | struct ieee80211_rate *rate = NULL; | ||
1037 | struct ieee80211_tx_rate *txrate; | 1168 | struct ieee80211_tx_rate *txrate; |
1169 | struct ar9170_tx_info *arinfo; | ||
1038 | unsigned int queue = skb_get_queue_mapping(skb); | 1170 | unsigned int queue = skb_get_queue_mapping(skb); |
1039 | unsigned long flags = 0; | ||
1040 | struct ar9170_sta_info *sta_info = NULL; | ||
1041 | u32 power, chains; | ||
1042 | u16 keytype = 0; | 1171 | u16 keytype = 0; |
1043 | u16 len, icv = 0; | 1172 | u16 len, icv = 0; |
1044 | int err; | ||
1045 | bool tx_status; | ||
1046 | 1173 | ||
1047 | if (unlikely(!IS_STARTED(ar))) | 1174 | BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); |
1048 | goto err_free; | ||
1049 | 1175 | ||
1050 | hdr = (void *)skb->data; | 1176 | hdr = (void *)skb->data; |
1051 | info = IEEE80211_SKB_CB(skb); | 1177 | info = IEEE80211_SKB_CB(skb); |
1052 | len = skb->len; | 1178 | len = skb->len; |
1053 | 1179 | ||
1054 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||
1055 | if (ar->tx_stats[queue].limit < ar->tx_stats[queue].len) { | ||
1056 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1057 | return NETDEV_TX_OK; | ||
1058 | } | ||
1059 | |||
1060 | ar->tx_stats[queue].len++; | ||
1061 | ar->tx_stats[queue].count++; | ||
1062 | if (ar->tx_stats[queue].limit == ar->tx_stats[queue].len) | ||
1063 | ieee80211_stop_queue(hw, queue); | ||
1064 | |||
1065 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1066 | |||
1067 | txc = (void *)skb_push(skb, sizeof(*txc)); | 1180 | txc = (void *)skb_push(skb, sizeof(*txc)); |
1068 | 1181 | ||
1069 | tx_status = (((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) != 0) || | ||
1070 | ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) != 0)); | ||
1071 | |||
1072 | if (info->control.hw_key) { | 1182 | if (info->control.hw_key) { |
1073 | icv = info->control.hw_key->icv_len; | 1183 | icv = info->control.hw_key->icv_len; |
1074 | 1184 | ||
@@ -1084,7 +1194,7 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1084 | break; | 1194 | break; |
1085 | default: | 1195 | default: |
1086 | WARN_ON(1); | 1196 | WARN_ON(1); |
1087 | goto err_dequeue; | 1197 | goto err_out; |
1088 | } | 1198 | } |
1089 | } | 1199 | } |
1090 | 1200 | ||
@@ -1101,16 +1211,65 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1101 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) | 1211 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) |
1102 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); | 1212 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); |
1103 | 1213 | ||
1104 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | ||
1105 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); | ||
1106 | |||
1107 | txrate = &info->control.rates[0]; | 1214 | txrate = &info->control.rates[0]; |
1108 | |||
1109 | if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | 1215 | if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
1110 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); | 1216 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); |
1111 | else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS) | 1217 | else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS) |
1112 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); | 1218 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); |
1113 | 1219 | ||
1220 | arinfo = (void *)info->rate_driver_data; | ||
1221 | arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT); | ||
1222 | |||
1223 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && | ||
1224 | (is_valid_ether_addr(ieee80211_get_DA(hdr)))) { | ||
1225 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
1226 | if (unlikely(!info->control.sta)) | ||
1227 | goto err_out; | ||
1228 | |||
1229 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); | ||
1230 | arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK; | ||
1231 | goto out; | ||
1232 | } | ||
1233 | |||
1234 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); | ||
1235 | /* | ||
1236 | * WARNING: | ||
1237 | * Putting the QoS queue bits into an unexplored territory is | ||
1238 | * certainly not elegant. | ||
1239 | * | ||
1240 | * In my defense: This idea provides a reasonable way to | ||
1241 | * smuggle valuable information to the tx_status callback. | ||
1242 | * Also, the idea behind this bit-abuse came straight from | ||
1243 | * the original driver code. | ||
1244 | */ | ||
1245 | |||
1246 | txc->phy_control |= | ||
1247 | cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); | ||
1248 | arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK; | ||
1249 | } else { | ||
1250 | arinfo->flags = AR9170_TX_FLAG_NO_ACK; | ||
1251 | } | ||
1252 | |||
1253 | out: | ||
1254 | return 0; | ||
1255 | |||
1256 | err_out: | ||
1257 | skb_pull(skb, sizeof(*txc)); | ||
1258 | return -EINVAL; | ||
1259 | } | ||
1260 | |||
1261 | static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb) | ||
1262 | { | ||
1263 | struct ar9170_tx_control *txc; | ||
1264 | struct ieee80211_tx_info *info; | ||
1265 | struct ieee80211_rate *rate = NULL; | ||
1266 | struct ieee80211_tx_rate *txrate; | ||
1267 | u32 power, chains; | ||
1268 | |||
1269 | txc = (void *) skb->data; | ||
1270 | info = IEEE80211_SKB_CB(skb); | ||
1271 | txrate = &info->control.rates[0]; | ||
1272 | |||
1114 | if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) | 1273 | if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) |
1115 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); | 1274 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); |
1116 | 1275 | ||
@@ -1130,9 +1289,12 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1130 | u32 r = txrate->idx; | 1289 | u32 r = txrate->idx; |
1131 | u8 *txpower; | 1290 | u8 *txpower; |
1132 | 1291 | ||
1292 | /* heavy clip control */ | ||
1293 | txc->phy_control |= cpu_to_le32((r & 0x7) << 7); | ||
1294 | |||
1133 | r <<= AR9170_TX_PHY_MCS_SHIFT; | 1295 | r <<= AR9170_TX_PHY_MCS_SHIFT; |
1134 | if (WARN_ON(r & ~AR9170_TX_PHY_MCS_MASK)) | 1296 | BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK); |
1135 | goto err_dequeue; | 1297 | |
1136 | txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK); | 1298 | txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK); |
1137 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); | 1299 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); |
1138 | 1300 | ||
@@ -1194,53 +1356,154 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1194 | chains = AR9170_TX_PHY_TXCHAIN_1; | 1356 | chains = AR9170_TX_PHY_TXCHAIN_1; |
1195 | } | 1357 | } |
1196 | txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT); | 1358 | txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT); |
1359 | } | ||
1197 | 1360 | ||
1198 | if (tx_status) { | 1361 | static void ar9170_tx(struct ar9170 *ar) |
1199 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); | 1362 | { |
1200 | /* | 1363 | struct sk_buff *skb; |
1201 | * WARNING: | 1364 | unsigned long flags; |
1202 | * Putting the QoS queue bits into an unexplored territory is | 1365 | struct ieee80211_tx_info *info; |
1203 | * certainly not elegant. | 1366 | struct ar9170_tx_info *arinfo; |
1204 | * | 1367 | unsigned int i, frames, frames_failed, remaining_space; |
1205 | * In my defense: This idea provides a reasonable way to | 1368 | int err; |
1206 | * smuggle valuable information to the tx_status callback. | 1369 | bool schedule_garbagecollector = false; |
1207 | * Also, the idea behind this bit-abuse came straight from | ||
1208 | * the original driver code. | ||
1209 | */ | ||
1210 | 1370 | ||
1211 | txc->phy_control |= | 1371 | BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); |
1212 | cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); | ||
1213 | 1372 | ||
1214 | if (info->control.sta) { | 1373 | if (unlikely(!IS_STARTED(ar))) |
1215 | sta_info = (void *) info->control.sta->drv_priv; | 1374 | return ; |
1216 | skb_queue_tail(&sta_info->tx_status[queue], skb); | 1375 | |
1217 | } else { | 1376 | remaining_space = AR9170_TX_MAX_PENDING; |
1218 | skb_queue_tail(&ar->global_tx_status, skb); | 1377 | |
1378 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | ||
1379 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||
1380 | if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { | ||
1381 | #ifdef AR9170_QUEUE_DEBUG | ||
1382 | printk(KERN_DEBUG "%s: queue %d full\n", | ||
1383 | wiphy_name(ar->hw->wiphy), i); | ||
1384 | |||
1385 | __ar9170_dump_txstats(ar); | ||
1386 | printk(KERN_DEBUG "stuck frames: ===> \n"); | ||
1387 | ar9170_dump_txqueue(ar, &ar->tx_pending[i]); | ||
1388 | ar9170_dump_txqueue(ar, &ar->tx_status[i]); | ||
1389 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1390 | ieee80211_stop_queue(ar->hw, i); | ||
1391 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1392 | continue; | ||
1393 | } | ||
1394 | |||
1395 | frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len, | ||
1396 | skb_queue_len(&ar->tx_pending[i])); | ||
1397 | |||
1398 | if (remaining_space < frames) { | ||
1399 | #ifdef AR9170_QUEUE_DEBUG | ||
1400 | printk(KERN_DEBUG "%s: tx quota reached queue:%d, " | ||
1401 | "remaining slots:%d, needed:%d\n", | ||
1402 | wiphy_name(ar->hw->wiphy), i, remaining_space, | ||
1403 | frames); | ||
1404 | |||
1405 | ar9170_dump_txstats(ar); | ||
1406 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1407 | frames = remaining_space; | ||
1408 | } | ||
1409 | |||
1410 | ar->tx_stats[i].len += frames; | ||
1411 | ar->tx_stats[i].count += frames; | ||
1412 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1413 | |||
1414 | if (!frames) | ||
1415 | continue; | ||
1416 | |||
1417 | frames_failed = 0; | ||
1418 | while (frames) { | ||
1419 | skb = skb_dequeue(&ar->tx_pending[i]); | ||
1420 | if (unlikely(!skb)) { | ||
1421 | frames_failed += frames; | ||
1422 | frames = 0; | ||
1423 | break; | ||
1424 | } | ||
1425 | |||
1426 | info = IEEE80211_SKB_CB(skb); | ||
1427 | arinfo = (void *) info->rate_driver_data; | ||
1428 | |||
1429 | /* TODO: cancel stuck frames */ | ||
1430 | arinfo->timeout = jiffies + | ||
1431 | msecs_to_jiffies(AR9170_TX_TIMEOUT); | ||
1432 | |||
1433 | #ifdef AR9170_QUEUE_DEBUG | ||
1434 | printk(KERN_DEBUG "%s: send frame q:%d =>\n", | ||
1435 | wiphy_name(ar->hw->wiphy), i); | ||
1436 | ar9170_print_txheader(ar, skb); | ||
1437 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1438 | |||
1439 | err = ar->tx(ar, skb); | ||
1440 | if (unlikely(err)) { | ||
1441 | frames_failed++; | ||
1442 | dev_kfree_skb_any(skb); | ||
1443 | } else { | ||
1444 | remaining_space--; | ||
1445 | schedule_garbagecollector = true; | ||
1446 | } | ||
1447 | |||
1448 | frames--; | ||
1449 | } | ||
1219 | 1450 | ||
1220 | queue_delayed_work(ar->hw->workqueue, | 1451 | #ifdef AR9170_QUEUE_DEBUG |
1221 | &ar->tx_status_janitor, | 1452 | printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n", |
1222 | msecs_to_jiffies(100)); | 1453 | wiphy_name(ar->hw->wiphy), i); |
1454 | |||
1455 | printk(KERN_DEBUG "%s: unprocessed pending frames left:\n", | ||
1456 | wiphy_name(ar->hw->wiphy)); | ||
1457 | ar9170_dump_txqueue(ar, &ar->tx_pending[i]); | ||
1458 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1459 | |||
1460 | if (unlikely(frames_failed)) { | ||
1461 | #ifdef AR9170_QUEUE_DEBUG | ||
1462 | printk(KERN_DEBUG "%s: frames failed =>\n", | ||
1463 | wiphy_name(ar->hw->wiphy), frames_failed); | ||
1464 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1465 | |||
1466 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||
1467 | ar->tx_stats[i].len -= frames_failed; | ||
1468 | ar->tx_stats[i].count -= frames_failed; | ||
1469 | ieee80211_wake_queue(ar->hw, i); | ||
1470 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1223 | } | 1471 | } |
1224 | } | 1472 | } |
1225 | 1473 | ||
1226 | err = ar->tx(ar, skb, tx_status, 0); | 1474 | if (schedule_garbagecollector) |
1227 | if (unlikely(tx_status && err)) { | 1475 | queue_delayed_work(ar->hw->workqueue, |
1228 | if (info->control.sta) | 1476 | &ar->tx_janitor, |
1229 | skb_unlink(skb, &sta_info->tx_status[queue]); | 1477 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); |
1230 | else | 1478 | } |
1231 | skb_unlink(skb, &ar->global_tx_status); | 1479 | |
1480 | int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1481 | { | ||
1482 | struct ar9170 *ar = hw->priv; | ||
1483 | struct ieee80211_tx_info *info; | ||
1484 | |||
1485 | if (unlikely(!IS_STARTED(ar))) | ||
1486 | goto err_free; | ||
1487 | |||
1488 | if (unlikely(ar9170_tx_prepare(ar, skb))) | ||
1489 | goto err_free; | ||
1490 | |||
1491 | info = IEEE80211_SKB_CB(skb); | ||
1492 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
1493 | /* drop frame, we do not allow TX A-MPDU aggregation yet. */ | ||
1494 | goto err_free; | ||
1495 | } else { | ||
1496 | unsigned int queue = skb_get_queue_mapping(skb); | ||
1497 | |||
1498 | ar9170_tx_prepare_phy(ar, skb); | ||
1499 | skb_queue_tail(&ar->tx_pending[queue], skb); | ||
1232 | } | 1500 | } |
1233 | 1501 | ||
1502 | ar9170_tx(ar); | ||
1234 | return NETDEV_TX_OK; | 1503 | return NETDEV_TX_OK; |
1235 | 1504 | ||
1236 | err_dequeue: | ||
1237 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||
1238 | ar->tx_stats[queue].len--; | ||
1239 | ar->tx_stats[queue].count--; | ||
1240 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1241 | |||
1242 | err_free: | 1505 | err_free: |
1243 | dev_kfree_skb(skb); | 1506 | dev_kfree_skb_any(skb); |
1244 | return NETDEV_TX_OK; | 1507 | return NETDEV_TX_OK; |
1245 | } | 1508 | } |
1246 | 1509 | ||
@@ -1666,43 +1929,6 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw, | |||
1666 | enum sta_notify_cmd cmd, | 1929 | enum sta_notify_cmd cmd, |
1667 | struct ieee80211_sta *sta) | 1930 | struct ieee80211_sta *sta) |
1668 | { | 1931 | { |
1669 | struct ar9170 *ar = hw->priv; | ||
1670 | struct ar9170_sta_info *info = (void *) sta->drv_priv; | ||
1671 | struct sk_buff *skb; | ||
1672 | unsigned int i; | ||
1673 | |||
1674 | switch (cmd) { | ||
1675 | case STA_NOTIFY_ADD: | ||
1676 | for (i = 0; i < ar->hw->queues; i++) | ||
1677 | skb_queue_head_init(&info->tx_status[i]); | ||
1678 | break; | ||
1679 | |||
1680 | case STA_NOTIFY_REMOVE: | ||
1681 | |||
1682 | /* | ||
1683 | * transfer all outstanding frames that need a tx_status | ||
1684 | * reports to the global tx_status queue | ||
1685 | */ | ||
1686 | |||
1687 | for (i = 0; i < ar->hw->queues; i++) { | ||
1688 | while ((skb = skb_dequeue(&info->tx_status[i]))) { | ||
1689 | #ifdef AR9170_QUEUE_DEBUG | ||
1690 | printk(KERN_DEBUG "%s: queueing frame in " | ||
1691 | "global tx_status queue =>\n", | ||
1692 | wiphy_name(ar->hw->wiphy)); | ||
1693 | |||
1694 | ar9170_print_txheader(ar, skb); | ||
1695 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1696 | skb_queue_tail(&ar->global_tx_status, skb); | ||
1697 | } | ||
1698 | } | ||
1699 | queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor, | ||
1700 | msecs_to_jiffies(100)); | ||
1701 | break; | ||
1702 | |||
1703 | default: | ||
1704 | break; | ||
1705 | } | ||
1706 | } | 1932 | } |
1707 | 1933 | ||
1708 | static int ar9170_get_stats(struct ieee80211_hw *hw, | 1934 | static int ar9170_get_stats(struct ieee80211_hw *hw, |
@@ -1741,7 +1967,7 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
1741 | int ret; | 1967 | int ret; |
1742 | 1968 | ||
1743 | mutex_lock(&ar->mutex); | 1969 | mutex_lock(&ar->mutex); |
1744 | if ((param) && !(queue > ar->hw->queues)) { | 1970 | if ((param) && !(queue > __AR9170_NUM_TXQ)) { |
1745 | memcpy(&ar->edcf[ar9170_qos_hwmap[queue]], | 1971 | memcpy(&ar->edcf[ar9170_qos_hwmap[queue]], |
1746 | param, sizeof(*param)); | 1972 | param, sizeof(*param)); |
1747 | 1973 | ||
@@ -1817,12 +2043,14 @@ void *ar9170_alloc(size_t priv_size) | |||
1817 | mutex_init(&ar->mutex); | 2043 | mutex_init(&ar->mutex); |
1818 | spin_lock_init(&ar->cmdlock); | 2044 | spin_lock_init(&ar->cmdlock); |
1819 | spin_lock_init(&ar->tx_stats_lock); | 2045 | spin_lock_init(&ar->tx_stats_lock); |
1820 | skb_queue_head_init(&ar->global_tx_status); | 2046 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { |
1821 | skb_queue_head_init(&ar->global_tx_status_waste); | 2047 | skb_queue_head_init(&ar->tx_status[i]); |
2048 | skb_queue_head_init(&ar->tx_pending[i]); | ||
2049 | } | ||
1822 | ar9170_rx_reset_rx_mpdu(ar); | 2050 | ar9170_rx_reset_rx_mpdu(ar); |
1823 | INIT_WORK(&ar->filter_config_work, ar9170_set_filters); | 2051 | INIT_WORK(&ar->filter_config_work, ar9170_set_filters); |
1824 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); | 2052 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); |
1825 | INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor); | 2053 | INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); |
1826 | 2054 | ||
1827 | /* all hw supports 2.4 GHz, so set channel to 1 by default */ | 2055 | /* all hw supports 2.4 GHz, so set channel to 1 by default */ |
1828 | ar->channel = &ar9170_2ghz_chantable[0]; | 2056 | ar->channel = &ar9170_2ghz_chantable[0]; |
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index f752698669d2..754b1f8d8da9 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c | |||
@@ -96,7 +96,49 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
96 | }; | 96 | }; |
97 | MODULE_DEVICE_TABLE(usb, ar9170_usb_ids); | 97 | MODULE_DEVICE_TABLE(usb, ar9170_usb_ids); |
98 | 98 | ||
99 | static void ar9170_usb_tx_urb_complete_free(struct urb *urb) | 99 | static void ar9170_usb_submit_urb(struct ar9170_usb *aru) |
100 | { | ||
101 | struct urb *urb; | ||
102 | unsigned long flags; | ||
103 | int err; | ||
104 | |||
105 | if (unlikely(!IS_STARTED(&aru->common))) | ||
106 | return ; | ||
107 | |||
108 | spin_lock_irqsave(&aru->tx_urb_lock, flags); | ||
109 | if (aru->tx_submitted_urbs >= AR9170_NUM_TX_URBS) { | ||
110 | spin_unlock_irqrestore(&aru->tx_urb_lock, flags); | ||
111 | return ; | ||
112 | } | ||
113 | aru->tx_submitted_urbs++; | ||
114 | |||
115 | urb = usb_get_from_anchor(&aru->tx_pending); | ||
116 | if (!urb) { | ||
117 | aru->tx_submitted_urbs--; | ||
118 | spin_unlock_irqrestore(&aru->tx_urb_lock, flags); | ||
119 | |||
120 | return ; | ||
121 | } | ||
122 | spin_unlock_irqrestore(&aru->tx_urb_lock, flags); | ||
123 | |||
124 | aru->tx_pending_urbs--; | ||
125 | usb_anchor_urb(urb, &aru->tx_submitted); | ||
126 | |||
127 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
128 | if (unlikely(err)) { | ||
129 | if (ar9170_nag_limiter(&aru->common)) | ||
130 | dev_err(&aru->udev->dev, "submit_urb failed (%d).\n", | ||
131 | err); | ||
132 | |||
133 | usb_unanchor_urb(urb); | ||
134 | aru->tx_submitted_urbs--; | ||
135 | ar9170_tx_callback(&aru->common, urb->context); | ||
136 | } | ||
137 | |||
138 | usb_free_urb(urb); | ||
139 | } | ||
140 | |||
141 | static void ar9170_usb_tx_urb_complete_frame(struct urb *urb) | ||
100 | { | 142 | { |
101 | struct sk_buff *skb = urb->context; | 143 | struct sk_buff *skb = urb->context; |
102 | struct ar9170_usb *aru = (struct ar9170_usb *) | 144 | struct ar9170_usb *aru = (struct ar9170_usb *) |
@@ -107,8 +149,11 @@ static void ar9170_usb_tx_urb_complete_free(struct urb *urb) | |||
107 | return ; | 149 | return ; |
108 | } | 150 | } |
109 | 151 | ||
110 | ar9170_handle_tx_status(&aru->common, skb, false, | 152 | aru->tx_submitted_urbs--; |
111 | AR9170_TX_STATUS_COMPLETE); | 153 | |
154 | ar9170_tx_callback(&aru->common, skb); | ||
155 | |||
156 | ar9170_usb_submit_urb(aru); | ||
112 | } | 157 | } |
113 | 158 | ||
114 | static void ar9170_usb_tx_urb_complete(struct urb *urb) | 159 | static void ar9170_usb_tx_urb_complete(struct urb *urb) |
@@ -290,21 +335,47 @@ err_out: | |||
290 | return err; | 335 | return err; |
291 | } | 336 | } |
292 | 337 | ||
293 | static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) | 338 | static int ar9170_usb_flush(struct ar9170 *ar) |
294 | { | 339 | { |
295 | int ret; | 340 | struct ar9170_usb *aru = (void *) ar; |
341 | struct urb *urb; | ||
342 | int ret, err = 0; | ||
296 | 343 | ||
297 | aru->common.state = AR9170_UNKNOWN_STATE; | 344 | if (IS_STARTED(ar)) |
345 | aru->common.state = AR9170_IDLE; | ||
298 | 346 | ||
299 | usb_unlink_anchored_urbs(&aru->tx_submitted); | 347 | usb_wait_anchor_empty_timeout(&aru->tx_pending, |
348 | msecs_to_jiffies(800)); | ||
349 | while ((urb = usb_get_from_anchor(&aru->tx_pending))) { | ||
350 | ar9170_tx_callback(&aru->common, (void *) urb->context); | ||
351 | usb_free_urb(urb); | ||
352 | } | ||
300 | 353 | ||
301 | /* give the LED OFF command and the deauth frame a chance to air. */ | 354 | /* lets wait a while until the tx - queues are dried out */ |
302 | ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, | 355 | ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, |
303 | msecs_to_jiffies(100)); | 356 | msecs_to_jiffies(100)); |
304 | if (ret == 0) | 357 | if (ret == 0) |
305 | dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); | 358 | err = -ETIMEDOUT; |
306 | usb_poison_anchored_urbs(&aru->tx_submitted); | 359 | |
360 | usb_kill_anchored_urbs(&aru->tx_submitted); | ||
361 | |||
362 | if (IS_ACCEPTING_CMD(ar)) | ||
363 | aru->common.state = AR9170_STARTED; | ||
364 | |||
365 | return err; | ||
366 | } | ||
367 | |||
368 | static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) | ||
369 | { | ||
370 | int err; | ||
307 | 371 | ||
372 | aru->common.state = AR9170_UNKNOWN_STATE; | ||
373 | |||
374 | err = ar9170_usb_flush(&aru->common); | ||
375 | if (err) | ||
376 | dev_err(&aru->udev->dev, "stuck tx urbs!\n"); | ||
377 | |||
378 | usb_poison_anchored_urbs(&aru->tx_submitted); | ||
308 | usb_poison_anchored_urbs(&aru->rx_submitted); | 379 | usb_poison_anchored_urbs(&aru->rx_submitted); |
309 | } | 380 | } |
310 | 381 | ||
@@ -388,12 +459,10 @@ err_free: | |||
388 | return err; | 459 | return err; |
389 | } | 460 | } |
390 | 461 | ||
391 | static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb, | 462 | static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) |
392 | bool txstatus_needed, unsigned int extra_len) | ||
393 | { | 463 | { |
394 | struct ar9170_usb *aru = (struct ar9170_usb *) ar; | 464 | struct ar9170_usb *aru = (struct ar9170_usb *) ar; |
395 | struct urb *urb; | 465 | struct urb *urb; |
396 | int err; | ||
397 | 466 | ||
398 | if (unlikely(!IS_STARTED(ar))) { | 467 | if (unlikely(!IS_STARTED(ar))) { |
399 | /* Seriously, what were you drink... err... thinking!? */ | 468 | /* Seriously, what were you drink... err... thinking!? */ |
@@ -406,18 +475,17 @@ static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb, | |||
406 | 475 | ||
407 | usb_fill_bulk_urb(urb, aru->udev, | 476 | usb_fill_bulk_urb(urb, aru->udev, |
408 | usb_sndbulkpipe(aru->udev, AR9170_EP_TX), | 477 | usb_sndbulkpipe(aru->udev, AR9170_EP_TX), |
409 | skb->data, skb->len + extra_len, (txstatus_needed ? | 478 | skb->data, skb->len, |
410 | ar9170_usb_tx_urb_complete : | 479 | ar9170_usb_tx_urb_complete_frame, skb); |
411 | ar9170_usb_tx_urb_complete_free), skb); | ||
412 | urb->transfer_flags |= URB_ZERO_PACKET; | 480 | urb->transfer_flags |= URB_ZERO_PACKET; |
413 | 481 | ||
414 | usb_anchor_urb(urb, &aru->tx_submitted); | 482 | usb_anchor_urb(urb, &aru->tx_pending); |
415 | err = usb_submit_urb(urb, GFP_ATOMIC); | 483 | aru->tx_pending_urbs++; |
416 | if (unlikely(err)) | ||
417 | usb_unanchor_urb(urb); | ||
418 | 484 | ||
419 | usb_free_urb(urb); | 485 | usb_free_urb(urb); |
420 | return err; | 486 | |
487 | ar9170_usb_submit_urb(aru); | ||
488 | return 0; | ||
421 | } | 489 | } |
422 | 490 | ||
423 | static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer) | 491 | static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer) |
@@ -617,10 +685,8 @@ static void ar9170_usb_stop(struct ar9170 *ar) | |||
617 | if (IS_ACCEPTING_CMD(ar)) | 685 | if (IS_ACCEPTING_CMD(ar)) |
618 | aru->common.state = AR9170_STOPPED; | 686 | aru->common.state = AR9170_STOPPED; |
619 | 687 | ||
620 | /* lets wait a while until the tx - queues are dried out */ | 688 | ret = ar9170_usb_flush(ar); |
621 | ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, | 689 | if (ret) |
622 | msecs_to_jiffies(1000)); | ||
623 | if (ret == 0) | ||
624 | dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); | 690 | dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); |
625 | 691 | ||
626 | usb_poison_anchored_urbs(&aru->tx_submitted); | 692 | usb_poison_anchored_urbs(&aru->tx_submitted); |
@@ -716,10 +782,16 @@ static int ar9170_usb_probe(struct usb_interface *intf, | |||
716 | SET_IEEE80211_DEV(ar->hw, &udev->dev); | 782 | SET_IEEE80211_DEV(ar->hw, &udev->dev); |
717 | 783 | ||
718 | init_usb_anchor(&aru->rx_submitted); | 784 | init_usb_anchor(&aru->rx_submitted); |
785 | init_usb_anchor(&aru->tx_pending); | ||
719 | init_usb_anchor(&aru->tx_submitted); | 786 | init_usb_anchor(&aru->tx_submitted); |
720 | init_completion(&aru->cmd_wait); | 787 | init_completion(&aru->cmd_wait); |
788 | spin_lock_init(&aru->tx_urb_lock); | ||
789 | |||
790 | aru->tx_pending_urbs = 0; | ||
791 | aru->tx_submitted_urbs = 0; | ||
721 | 792 | ||
722 | aru->common.stop = ar9170_usb_stop; | 793 | aru->common.stop = ar9170_usb_stop; |
794 | aru->common.flush = ar9170_usb_flush; | ||
723 | aru->common.open = ar9170_usb_open; | 795 | aru->common.open = ar9170_usb_open; |
724 | aru->common.tx = ar9170_usb_tx; | 796 | aru->common.tx = ar9170_usb_tx; |
725 | aru->common.exec_cmd = ar9170_usb_exec_cmd; | 797 | aru->common.exec_cmd = ar9170_usb_exec_cmd; |
diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h index 69f4bceb0af3..d098f4d5d2f2 100644 --- a/drivers/net/wireless/ath/ar9170/usb.h +++ b/drivers/net/wireless/ath/ar9170/usb.h | |||
@@ -51,6 +51,7 @@ | |||
51 | #include "ar9170.h" | 51 | #include "ar9170.h" |
52 | 52 | ||
53 | #define AR9170_NUM_RX_URBS 16 | 53 | #define AR9170_NUM_RX_URBS 16 |
54 | #define AR9170_NUM_TX_URBS 8 | ||
54 | 55 | ||
55 | struct firmware; | 56 | struct firmware; |
56 | 57 | ||
@@ -60,11 +61,15 @@ struct ar9170_usb { | |||
60 | struct usb_interface *intf; | 61 | struct usb_interface *intf; |
61 | 62 | ||
62 | struct usb_anchor rx_submitted; | 63 | struct usb_anchor rx_submitted; |
64 | struct usb_anchor tx_pending; | ||
63 | struct usb_anchor tx_submitted; | 65 | struct usb_anchor tx_submitted; |
64 | 66 | ||
65 | bool req_one_stage_fw; | 67 | bool req_one_stage_fw; |
66 | 68 | ||
67 | spinlock_t cmdlock; | 69 | spinlock_t tx_urb_lock; |
70 | unsigned int tx_submitted_urbs; | ||
71 | unsigned int tx_pending_urbs; | ||
72 | |||
68 | struct completion cmd_wait; | 73 | struct completion cmd_wait; |
69 | int readlen; | 74 | int readlen; |
70 | u8 *readbuf; | 75 | u8 *readbuf; |
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile index 84a74c5248e5..090dc6d268a3 100644 --- a/drivers/net/wireless/ath/ath5k/Makefile +++ b/drivers/net/wireless/ath/ath5k/Makefile | |||
@@ -11,5 +11,6 @@ ath5k-y += reset.o | |||
11 | ath5k-y += attach.o | 11 | ath5k-y += attach.o |
12 | ath5k-y += base.o | 12 | ath5k-y += base.o |
13 | ath5k-y += led.o | 13 | ath5k-y += led.o |
14 | ath5k-y += rfkill.o | ||
14 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o | 15 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o |
15 | obj-$(CONFIG_ATH5K) += ath5k.o | 16 | obj-$(CONFIG_ATH5K) += ath5k.o |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 813718210338..6358233bac99 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -1256,6 +1256,10 @@ extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); | |||
1256 | extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); | 1256 | extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); |
1257 | extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); | 1257 | extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); |
1258 | 1258 | ||
1259 | /* rfkill Functions */ | ||
1260 | extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah); | ||
1261 | extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); | ||
1262 | |||
1259 | /* Misc functions */ | 1263 | /* Misc functions */ |
1260 | int ath5k_hw_set_capabilities(struct ath5k_hw *ah); | 1264 | int ath5k_hw_set_capabilities(struct ath5k_hw *ah); |
1261 | extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); | 1265 | extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 85a00db4867d..55f7de09d134 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -2360,6 +2360,8 @@ ath5k_init(struct ath5k_softc *sc) | |||
2360 | if (ret) | 2360 | if (ret) |
2361 | goto done; | 2361 | goto done; |
2362 | 2362 | ||
2363 | ath5k_rfkill_hw_start(ah); | ||
2364 | |||
2363 | /* | 2365 | /* |
2364 | * Reset the key cache since some parts do not reset the | 2366 | * Reset the key cache since some parts do not reset the |
2365 | * contents on initial power up or resume from suspend. | 2367 | * contents on initial power up or resume from suspend. |
@@ -2468,6 +2470,8 @@ ath5k_stop_hw(struct ath5k_softc *sc) | |||
2468 | tasklet_kill(&sc->restq); | 2470 | tasklet_kill(&sc->restq); |
2469 | tasklet_kill(&sc->beacontq); | 2471 | tasklet_kill(&sc->beacontq); |
2470 | 2472 | ||
2473 | ath5k_rfkill_hw_stop(sc->ah); | ||
2474 | |||
2471 | return ret; | 2475 | return ret; |
2472 | } | 2476 | } |
2473 | 2477 | ||
@@ -2526,6 +2530,9 @@ ath5k_intr(int irq, void *dev_id) | |||
2526 | */ | 2530 | */ |
2527 | ath5k_hw_update_mib_counters(ah, &sc->ll_stats); | 2531 | ath5k_hw_update_mib_counters(ah, &sc->ll_stats); |
2528 | } | 2532 | } |
2533 | if (status & AR5K_INT_GPIO) | ||
2534 | tasklet_schedule(&sc->rf_kill.toggleq); | ||
2535 | |||
2529 | } | 2536 | } |
2530 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); | 2537 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); |
2531 | 2538 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 852b2c189fd8..f9b7f2f819b7 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/wireless.h> | 46 | #include <linux/wireless.h> |
47 | #include <linux/if_ether.h> | 47 | #include <linux/if_ether.h> |
48 | #include <linux/leds.h> | 48 | #include <linux/leds.h> |
49 | #include <linux/rfkill.h> | ||
49 | 50 | ||
50 | #include "ath5k.h" | 51 | #include "ath5k.h" |
51 | #include "debug.h" | 52 | #include "debug.h" |
@@ -91,6 +92,15 @@ struct ath5k_led | |||
91 | struct led_classdev led_dev; /* led classdev */ | 92 | struct led_classdev led_dev; /* led classdev */ |
92 | }; | 93 | }; |
93 | 94 | ||
95 | /* Rfkill */ | ||
96 | struct ath5k_rfkill { | ||
97 | /* GPIO PIN for rfkill */ | ||
98 | u16 gpio; | ||
99 | /* polarity of rfkill GPIO PIN */ | ||
100 | bool polarity; | ||
101 | /* RFKILL toggle tasklet */ | ||
102 | struct tasklet_struct toggleq; | ||
103 | }; | ||
94 | 104 | ||
95 | #if CHAN_DEBUG | 105 | #if CHAN_DEBUG |
96 | #define ATH_CHAN_MAX (26+26+26+200+200) | 106 | #define ATH_CHAN_MAX (26+26+26+200+200) |
@@ -167,6 +177,8 @@ struct ath5k_softc { | |||
167 | struct tasklet_struct txtq; /* tx intr tasklet */ | 177 | struct tasklet_struct txtq; /* tx intr tasklet */ |
168 | struct ath5k_led tx_led; /* tx led */ | 178 | struct ath5k_led tx_led; /* tx led */ |
169 | 179 | ||
180 | struct ath5k_rfkill rf_kill; | ||
181 | |||
170 | spinlock_t block; /* protects beacon */ | 182 | spinlock_t block; /* protects beacon */ |
171 | struct tasklet_struct beacontq; /* beacon intr tasklet */ | 183 | struct tasklet_struct beacontq; /* beacon intr tasklet */ |
172 | struct ath5k_buf *bbuf; /* beacon buffer */ | 184 | struct ath5k_buf *bbuf; /* beacon buffer */ |
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 66067733ddd3..bd0a97a38d34 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
@@ -1304,23 +1304,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1304 | if (ah->ah_version != AR5K_AR5210) | 1304 | if (ah->ah_version != AR5K_AR5210) |
1305 | ath5k_hw_set_imr(ah, ah->ah_imr); | 1305 | ath5k_hw_set_imr(ah, ah->ah_imr); |
1306 | 1306 | ||
1307 | /* | ||
1308 | * Setup RFKill interrupt if rfkill flag is set on eeprom. | ||
1309 | * TODO: Use gpio pin and polarity infos from eeprom | ||
1310 | * TODO: Handle this in ath5k_intr because it'll result | ||
1311 | * a nasty interrupt storm. | ||
1312 | */ | ||
1313 | #if 0 | ||
1314 | if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) { | ||
1315 | ath5k_hw_set_gpio_input(ah, 0); | ||
1316 | ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0); | ||
1317 | if (ah->ah_gpio[0] == 0) | ||
1318 | ath5k_hw_set_gpio_intr(ah, 0, 1); | ||
1319 | else | ||
1320 | ath5k_hw_set_gpio_intr(ah, 0, 0); | ||
1321 | } | ||
1322 | #endif | ||
1323 | |||
1324 | /* Enable 32KHz clock function for AR5212+ chips | 1307 | /* Enable 32KHz clock function for AR5212+ chips |
1325 | * Set clocks to 32KHz operation and use an | 1308 | * Set clocks to 32KHz operation and use an |
1326 | * external 32KHz crystal when sleeping if one | 1309 | * external 32KHz crystal when sleeping if one |
diff --git a/drivers/net/wireless/ath/ath5k/rfkill.c b/drivers/net/wireless/ath/ath5k/rfkill.c new file mode 100644 index 000000000000..41a877b73fce --- /dev/null +++ b/drivers/net/wireless/ath/ath5k/rfkill.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * RFKILL support for ath5k | ||
3 | * | ||
4 | * Copyright (c) 2009 Tobias Doerffel <tobias.doerffel@gmail.com> | ||
5 | * | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer, | ||
13 | * without modification. | ||
14 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
15 | * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any | ||
16 | * redistribution must be conditioned upon including a substantially | ||
17 | * similar Disclaimer requirement for further binary redistribution. | ||
18 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
19 | * of any contributors may be used to endorse or promote products derived | ||
20 | * from this software without specific prior written permission. | ||
21 | * | ||
22 | * NO WARRANTY | ||
23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
25 | * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY | ||
26 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | ||
27 | * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, | ||
28 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER | ||
31 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||
33 | * THE POSSIBILITY OF SUCH DAMAGES. | ||
34 | */ | ||
35 | |||
36 | #include "base.h" | ||
37 | |||
38 | |||
39 | static inline void ath5k_rfkill_disable(struct ath5k_softc *sc) | ||
40 | { | ||
41 | ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill disable (gpio:%d polarity:%d)\n", | ||
42 | sc->rf_kill.gpio, sc->rf_kill.polarity); | ||
43 | ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio); | ||
44 | ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, !sc->rf_kill.polarity); | ||
45 | } | ||
46 | |||
47 | |||
48 | static inline void ath5k_rfkill_enable(struct ath5k_softc *sc) | ||
49 | { | ||
50 | ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill enable (gpio:%d polarity:%d)\n", | ||
51 | sc->rf_kill.gpio, sc->rf_kill.polarity); | ||
52 | ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio); | ||
53 | ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, sc->rf_kill.polarity); | ||
54 | } | ||
55 | |||
56 | static inline void ath5k_rfkill_set_intr(struct ath5k_softc *sc, bool enable) | ||
57 | { | ||
58 | struct ath5k_hw *ah = sc->ah; | ||
59 | u32 curval; | ||
60 | |||
61 | ath5k_hw_set_gpio_input(ah, sc->rf_kill.gpio); | ||
62 | curval = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio); | ||
63 | ath5k_hw_set_gpio_intr(ah, sc->rf_kill.gpio, enable ? | ||
64 | !!curval : !curval); | ||
65 | } | ||
66 | |||
67 | static bool | ||
68 | ath5k_is_rfkill_set(struct ath5k_softc *sc) | ||
69 | { | ||
70 | /* configuring GPIO for input for some reason disables rfkill */ | ||
71 | /*ath5k_hw_set_gpio_input(sc->ah, sc->rf_kill.gpio);*/ | ||
72 | return ath5k_hw_get_gpio(sc->ah, sc->rf_kill.gpio) == | ||
73 | sc->rf_kill.polarity; | ||
74 | } | ||
75 | |||
76 | static void | ||
77 | ath5k_tasklet_rfkill_toggle(unsigned long data) | ||
78 | { | ||
79 | struct ath5k_softc *sc = (void *)data; | ||
80 | bool blocked; | ||
81 | |||
82 | blocked = ath5k_is_rfkill_set(sc); | ||
83 | wiphy_rfkill_set_hw_state(sc->hw->wiphy, blocked); | ||
84 | } | ||
85 | |||
86 | |||
87 | void | ||
88 | ath5k_rfkill_hw_start(struct ath5k_hw *ah) | ||
89 | { | ||
90 | struct ath5k_softc *sc = ah->ah_sc; | ||
91 | |||
92 | /* read rfkill GPIO configuration from EEPROM header */ | ||
93 | sc->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin; | ||
94 | sc->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol; | ||
95 | |||
96 | tasklet_init(&sc->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle, | ||
97 | (unsigned long)sc); | ||
98 | |||
99 | ath5k_rfkill_disable(sc); | ||
100 | |||
101 | /* enable interrupt for rfkill switch */ | ||
102 | if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) | ||
103 | ath5k_rfkill_set_intr(sc, true); | ||
104 | } | ||
105 | |||
106 | |||
107 | void | ||
108 | ath5k_rfkill_hw_stop(struct ath5k_hw *ah) | ||
109 | { | ||
110 | struct ath5k_softc *sc = ah->ah_sc; | ||
111 | |||
112 | /* disable interrupt for rfkill switch */ | ||
113 | if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) | ||
114 | ath5k_rfkill_set_intr(sc, false); | ||
115 | |||
116 | tasklet_kill(&sc->rf_kill.toggleq); | ||
117 | |||
118 | /* enable RFKILL when stopping HW so Wifi LED is turned off */ | ||
119 | ath5k_rfkill_enable(sc); | ||
120 | } | ||
121 | |||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index a8def4fa449c..b61a071788a5 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -711,6 +711,7 @@ int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | |||
711 | return 0; | 711 | return 0; |
712 | 712 | ||
713 | if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { | 713 | if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { |
714 | txtid->state &= ~AGGR_ADDBA_PROGRESS; | ||
714 | txtid->addba_exchangeattempts = 0; | 715 | txtid->addba_exchangeattempts = 0; |
715 | return 0; | 716 | return 0; |
716 | } | 717 | } |
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 07a99e3faf94..67f564e37225 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig | |||
@@ -98,13 +98,6 @@ config B43_LEDS | |||
98 | depends on B43 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43) | 98 | depends on B43 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43) |
99 | default y | 99 | default y |
100 | 100 | ||
101 | # This config option automatically enables b43 RFKILL support, | ||
102 | # if it's possible. | ||
103 | config B43_RFKILL | ||
104 | bool | ||
105 | depends on B43 && (RFKILL = y || RFKILL = B43) | ||
106 | default y | ||
107 | |||
108 | # This config option automatically enables b43 HW-RNG support, | 101 | # This config option automatically enables b43 HW-RNG support, |
109 | # if the HW-RNG core is enabled. | 102 | # if the HW-RNG core is enabled. |
110 | config B43_HWRNG | 103 | config B43_HWRNG |
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 281ef8310350..da379f4b0c3a 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile | |||
@@ -13,7 +13,7 @@ b43-y += lo.o | |||
13 | b43-y += wa.o | 13 | b43-y += wa.o |
14 | b43-y += dma.o | 14 | b43-y += dma.o |
15 | b43-$(CONFIG_B43_PIO) += pio.o | 15 | b43-$(CONFIG_B43_PIO) += pio.o |
16 | b43-$(CONFIG_B43_RFKILL) += rfkill.o | 16 | b43-y += rfkill.o |
17 | b43-$(CONFIG_B43_LEDS) += leds.o | 17 | b43-$(CONFIG_B43_LEDS) += leds.o |
18 | b43-$(CONFIG_B43_PCMCIA) += pcmcia.o | 18 | b43-$(CONFIG_B43_PCMCIA) += pcmcia.o |
19 | b43-$(CONFIG_B43_DEBUG) += debugfs.o | 19 | b43-$(CONFIG_B43_DEBUG) += debugfs.o |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 4e8ad841c3c5..f580c2812d91 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -163,6 +163,7 @@ enum { | |||
163 | #define B43_SHM_SH_WLCOREREV 0x0016 /* 802.11 core revision */ | 163 | #define B43_SHM_SH_WLCOREREV 0x0016 /* 802.11 core revision */ |
164 | #define B43_SHM_SH_PCTLWDPOS 0x0008 | 164 | #define B43_SHM_SH_PCTLWDPOS 0x0008 |
165 | #define B43_SHM_SH_RXPADOFF 0x0034 /* RX Padding data offset (PIO only) */ | 165 | #define B43_SHM_SH_RXPADOFF 0x0034 /* RX Padding data offset (PIO only) */ |
166 | #define B43_SHM_SH_FWCAPA 0x0042 /* Firmware capabilities (Opensource firmware only) */ | ||
166 | #define B43_SHM_SH_PHYVER 0x0050 /* PHY version */ | 167 | #define B43_SHM_SH_PHYVER 0x0050 /* PHY version */ |
167 | #define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */ | 168 | #define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */ |
168 | #define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */ | 169 | #define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */ |
@@ -297,6 +298,10 @@ enum { | |||
297 | #define B43_HF_MLADVW 0x001000000000ULL /* N PHY ML ADV workaround (rev >= 13 only) */ | 298 | #define B43_HF_MLADVW 0x001000000000ULL /* N PHY ML ADV workaround (rev >= 13 only) */ |
298 | #define B43_HF_PR45960W 0x080000000000ULL /* PR 45960 workaround (rev >= 13 only) */ | 299 | #define B43_HF_PR45960W 0x080000000000ULL /* PR 45960 workaround (rev >= 13 only) */ |
299 | 300 | ||
301 | /* Firmware capabilities field in SHM (Opensource firmware only) */ | ||
302 | #define B43_FWCAPA_HWCRYPTO 0x0001 | ||
303 | #define B43_FWCAPA_QOS 0x0002 | ||
304 | |||
300 | /* MacFilter offsets. */ | 305 | /* MacFilter offsets. */ |
301 | #define B43_MACFILTER_SELF 0x0000 | 306 | #define B43_MACFILTER_SELF 0x0000 |
302 | #define B43_MACFILTER_BSSID 0x0003 | 307 | #define B43_MACFILTER_BSSID 0x0003 |
@@ -596,6 +601,13 @@ struct b43_wl { | |||
596 | /* Pointer to the ieee80211 hardware data structure */ | 601 | /* Pointer to the ieee80211 hardware data structure */ |
597 | struct ieee80211_hw *hw; | 602 | struct ieee80211_hw *hw; |
598 | 603 | ||
604 | /* The number of queues that were registered with the mac80211 subsystem | ||
605 | * initially. This is a backup copy of hw->queues in case hw->queues has | ||
606 | * to be dynamically lowered at runtime (Firmware does not support QoS). | ||
607 | * hw->queues has to be restored to the original value before unregistering | ||
608 | * from the mac80211 subsystem. */ | ||
609 | u16 mac80211_initially_registered_queues; | ||
610 | |||
599 | struct mutex mutex; | 611 | struct mutex mutex; |
600 | spinlock_t irq_lock; | 612 | spinlock_t irq_lock; |
601 | /* R/W lock for data transmission. | 613 | /* R/W lock for data transmission. |
@@ -631,9 +643,6 @@ struct b43_wl { | |||
631 | char rng_name[30 + 1]; | 643 | char rng_name[30 + 1]; |
632 | #endif /* CONFIG_B43_HWRNG */ | 644 | #endif /* CONFIG_B43_HWRNG */ |
633 | 645 | ||
634 | /* The RF-kill button */ | ||
635 | struct b43_rfkill rfkill; | ||
636 | |||
637 | /* List of all wireless devices on this chip */ | 646 | /* List of all wireless devices on this chip */ |
638 | struct list_head devlist; | 647 | struct list_head devlist; |
639 | u8 nr_devs; | 648 | u8 nr_devs; |
@@ -752,6 +761,8 @@ struct b43_wldev { | |||
752 | bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ | 761 | bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ |
753 | bool radio_hw_enable; /* saved state of radio hardware enabled state */ | 762 | bool radio_hw_enable; /* saved state of radio hardware enabled state */ |
754 | bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ | 763 | bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ |
764 | bool qos_enabled; /* TRUE, if QoS is used. */ | ||
765 | bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ | ||
755 | 766 | ||
756 | /* PHY/Radio device. */ | 767 | /* PHY/Radio device. */ |
757 | struct b43_phy phy; | 768 | struct b43_phy phy; |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index eae680b53052..7964cc32b258 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -1285,7 +1285,7 @@ static struct b43_dmaring *select_ring_by_priority(struct b43_wldev *dev, | |||
1285 | { | 1285 | { |
1286 | struct b43_dmaring *ring; | 1286 | struct b43_dmaring *ring; |
1287 | 1287 | ||
1288 | if (b43_modparam_qos) { | 1288 | if (dev->qos_enabled) { |
1289 | /* 0 = highest priority */ | 1289 | /* 0 = highest priority */ |
1290 | switch (queue_prio) { | 1290 | switch (queue_prio) { |
1291 | default: | 1291 | default: |
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index 9a498d3fc653..c8b317094c31 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include "b43.h" | 29 | #include "b43.h" |
30 | #include "leds.h" | 30 | #include "leds.h" |
31 | #include "rfkill.h" | ||
31 | 32 | ||
32 | 33 | ||
33 | static void b43_led_turn_on(struct b43_wldev *dev, u8 led_index, | 34 | static void b43_led_turn_on(struct b43_wldev *dev, u8 led_index, |
@@ -164,10 +165,10 @@ static void b43_map_led(struct b43_wldev *dev, | |||
164 | snprintf(name, sizeof(name), | 165 | snprintf(name, sizeof(name), |
165 | "b43-%s::radio", wiphy_name(hw->wiphy)); | 166 | "b43-%s::radio", wiphy_name(hw->wiphy)); |
166 | b43_register_led(dev, &dev->led_radio, name, | 167 | b43_register_led(dev, &dev->led_radio, name, |
167 | b43_rfkill_led_name(dev), | 168 | ieee80211_get_radio_led_name(hw), |
168 | led_index, activelow); | 169 | led_index, activelow); |
169 | /* Sync the RF-kill LED state with the switch state. */ | 170 | /* Sync the RF-kill LED state with radio and switch states. */ |
170 | if (dev->radio_hw_enable) | 171 | if (dev->phy.radio_on && b43_is_hw_radio_enabled(dev)) |
171 | b43_led_turn_on(dev, led_index, activelow); | 172 | b43_led_turn_on(dev, led_index, activelow); |
172 | break; | 173 | break; |
173 | case B43_LED_WEIRD: | 174 | case B43_LED_WEIRD: |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 1d3e40095ada..6456afebdba1 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -80,8 +80,8 @@ static int modparam_nohwcrypt; | |||
80 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); | 80 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); |
81 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 81 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
82 | 82 | ||
83 | int b43_modparam_qos = 1; | 83 | static int modparam_qos = 1; |
84 | module_param_named(qos, b43_modparam_qos, int, 0444); | 84 | module_param_named(qos, modparam_qos, int, 0444); |
85 | MODULE_PARM_DESC(qos, "Enable QOS support (default on)"); | 85 | MODULE_PARM_DESC(qos, "Enable QOS support (default on)"); |
86 | 86 | ||
87 | static int modparam_btcoex = 1; | 87 | static int modparam_btcoex = 1; |
@@ -538,6 +538,13 @@ void b43_hf_write(struct b43_wldev *dev, u64 value) | |||
538 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi); | 538 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi); |
539 | } | 539 | } |
540 | 540 | ||
541 | /* Read the firmware capabilities bitmask (Opensource firmware only) */ | ||
542 | static u16 b43_fwcapa_read(struct b43_wldev *dev) | ||
543 | { | ||
544 | B43_WARN_ON(!dev->fw.opensource); | ||
545 | return b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_FWCAPA); | ||
546 | } | ||
547 | |||
541 | void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) | 548 | void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) |
542 | { | 549 | { |
543 | u32 low, high; | 550 | u32 low, high; |
@@ -2307,12 +2314,34 @@ static int b43_upload_microcode(struct b43_wldev *dev) | |||
2307 | dev->fw.patch = fwpatch; | 2314 | dev->fw.patch = fwpatch; |
2308 | dev->fw.opensource = (fwdate == 0xFFFF); | 2315 | dev->fw.opensource = (fwdate == 0xFFFF); |
2309 | 2316 | ||
2317 | /* Default to use-all-queues. */ | ||
2318 | dev->wl->hw->queues = dev->wl->mac80211_initially_registered_queues; | ||
2319 | dev->qos_enabled = !!modparam_qos; | ||
2320 | /* Default to firmware/hardware crypto acceleration. */ | ||
2321 | dev->hwcrypto_enabled = 1; | ||
2322 | |||
2310 | if (dev->fw.opensource) { | 2323 | if (dev->fw.opensource) { |
2324 | u16 fwcapa; | ||
2325 | |||
2311 | /* Patchlevel info is encoded in the "time" field. */ | 2326 | /* Patchlevel info is encoded in the "time" field. */ |
2312 | dev->fw.patch = fwtime; | 2327 | dev->fw.patch = fwtime; |
2313 | b43info(dev->wl, "Loading OpenSource firmware version %u.%u%s\n", | 2328 | b43info(dev->wl, "Loading OpenSource firmware version %u.%u\n", |
2314 | dev->fw.rev, dev->fw.patch, | 2329 | dev->fw.rev, dev->fw.patch); |
2315 | dev->fw.pcm_request_failed ? " (Hardware crypto not supported)" : ""); | 2330 | |
2331 | fwcapa = b43_fwcapa_read(dev); | ||
2332 | if (!(fwcapa & B43_FWCAPA_HWCRYPTO) || dev->fw.pcm_request_failed) { | ||
2333 | b43info(dev->wl, "Hardware crypto acceleration not supported by firmware\n"); | ||
2334 | /* Disable hardware crypto and fall back to software crypto. */ | ||
2335 | dev->hwcrypto_enabled = 0; | ||
2336 | } | ||
2337 | if (!(fwcapa & B43_FWCAPA_QOS)) { | ||
2338 | b43info(dev->wl, "QoS not supported by firmware\n"); | ||
2339 | /* Disable QoS. Tweak hw->queues to 1. It will be restored before | ||
2340 | * ieee80211_unregister to make sure the networking core can | ||
2341 | * properly free possible resources. */ | ||
2342 | dev->wl->hw->queues = 1; | ||
2343 | dev->qos_enabled = 0; | ||
2344 | } | ||
2316 | } else { | 2345 | } else { |
2317 | b43info(dev->wl, "Loading firmware version %u.%u " | 2346 | b43info(dev->wl, "Loading firmware version %u.%u " |
2318 | "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", | 2347 | "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", |
@@ -3627,7 +3656,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3627 | if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) | 3656 | if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) |
3628 | goto out_unlock; | 3657 | goto out_unlock; |
3629 | 3658 | ||
3630 | if (dev->fw.pcm_request_failed) { | 3659 | if (dev->fw.pcm_request_failed || !dev->hwcrypto_enabled) { |
3631 | /* We don't have firmware for the crypto engine. | 3660 | /* We don't have firmware for the crypto engine. |
3632 | * Must use software-crypto. */ | 3661 | * Must use software-crypto. */ |
3633 | err = -EOPNOTSUPP; | 3662 | err = -EOPNOTSUPP; |
@@ -4298,7 +4327,6 @@ static int b43_op_start(struct ieee80211_hw *hw) | |||
4298 | struct b43_wldev *dev = wl->current_dev; | 4327 | struct b43_wldev *dev = wl->current_dev; |
4299 | int did_init = 0; | 4328 | int did_init = 0; |
4300 | int err = 0; | 4329 | int err = 0; |
4301 | bool do_rfkill_exit = 0; | ||
4302 | 4330 | ||
4303 | /* Kill all old instance specific information to make sure | 4331 | /* Kill all old instance specific information to make sure |
4304 | * the card won't use it in the short timeframe between start | 4332 | * the card won't use it in the short timeframe between start |
@@ -4312,18 +4340,12 @@ static int b43_op_start(struct ieee80211_hw *hw) | |||
4312 | wl->beacon1_uploaded = 0; | 4340 | wl->beacon1_uploaded = 0; |
4313 | wl->beacon_templates_virgin = 1; | 4341 | wl->beacon_templates_virgin = 1; |
4314 | 4342 | ||
4315 | /* First register RFkill. | ||
4316 | * LEDs that are registered later depend on it. */ | ||
4317 | b43_rfkill_init(dev); | ||
4318 | |||
4319 | mutex_lock(&wl->mutex); | 4343 | mutex_lock(&wl->mutex); |
4320 | 4344 | ||
4321 | if (b43_status(dev) < B43_STAT_INITIALIZED) { | 4345 | if (b43_status(dev) < B43_STAT_INITIALIZED) { |
4322 | err = b43_wireless_core_init(dev); | 4346 | err = b43_wireless_core_init(dev); |
4323 | if (err) { | 4347 | if (err) |
4324 | do_rfkill_exit = 1; | ||
4325 | goto out_mutex_unlock; | 4348 | goto out_mutex_unlock; |
4326 | } | ||
4327 | did_init = 1; | 4349 | did_init = 1; |
4328 | } | 4350 | } |
4329 | 4351 | ||
@@ -4332,17 +4354,16 @@ static int b43_op_start(struct ieee80211_hw *hw) | |||
4332 | if (err) { | 4354 | if (err) { |
4333 | if (did_init) | 4355 | if (did_init) |
4334 | b43_wireless_core_exit(dev); | 4356 | b43_wireless_core_exit(dev); |
4335 | do_rfkill_exit = 1; | ||
4336 | goto out_mutex_unlock; | 4357 | goto out_mutex_unlock; |
4337 | } | 4358 | } |
4338 | } | 4359 | } |
4339 | 4360 | ||
4361 | /* XXX: only do if device doesn't support rfkill irq */ | ||
4362 | wiphy_rfkill_start_polling(hw->wiphy); | ||
4363 | |||
4340 | out_mutex_unlock: | 4364 | out_mutex_unlock: |
4341 | mutex_unlock(&wl->mutex); | 4365 | mutex_unlock(&wl->mutex); |
4342 | 4366 | ||
4343 | if (do_rfkill_exit) | ||
4344 | b43_rfkill_exit(dev); | ||
4345 | |||
4346 | return err; | 4367 | return err; |
4347 | } | 4368 | } |
4348 | 4369 | ||
@@ -4351,7 +4372,6 @@ static void b43_op_stop(struct ieee80211_hw *hw) | |||
4351 | struct b43_wl *wl = hw_to_b43_wl(hw); | 4372 | struct b43_wl *wl = hw_to_b43_wl(hw); |
4352 | struct b43_wldev *dev = wl->current_dev; | 4373 | struct b43_wldev *dev = wl->current_dev; |
4353 | 4374 | ||
4354 | b43_rfkill_exit(dev); | ||
4355 | cancel_work_sync(&(wl->beacon_update_trigger)); | 4375 | cancel_work_sync(&(wl->beacon_update_trigger)); |
4356 | 4376 | ||
4357 | mutex_lock(&wl->mutex); | 4377 | mutex_lock(&wl->mutex); |
@@ -4433,6 +4453,7 @@ static const struct ieee80211_ops b43_hw_ops = { | |||
4433 | .sta_notify = b43_op_sta_notify, | 4453 | .sta_notify = b43_op_sta_notify, |
4434 | .sw_scan_start = b43_op_sw_scan_start_notifier, | 4454 | .sw_scan_start = b43_op_sw_scan_start_notifier, |
4435 | .sw_scan_complete = b43_op_sw_scan_complete_notifier, | 4455 | .sw_scan_complete = b43_op_sw_scan_complete_notifier, |
4456 | .rfkill_poll = b43_rfkill_poll, | ||
4436 | }; | 4457 | }; |
4437 | 4458 | ||
4438 | /* Hard-reset the chip. Do not call this directly. | 4459 | /* Hard-reset the chip. Do not call this directly. |
@@ -4735,6 +4756,7 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4735 | b43err(NULL, "Could not allocate ieee80211 device\n"); | 4756 | b43err(NULL, "Could not allocate ieee80211 device\n"); |
4736 | goto out; | 4757 | goto out; |
4737 | } | 4758 | } |
4759 | wl = hw_to_b43_wl(hw); | ||
4738 | 4760 | ||
4739 | /* fill hw info */ | 4761 | /* fill hw info */ |
4740 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 4762 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
@@ -4748,7 +4770,8 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4748 | BIT(NL80211_IFTYPE_WDS) | | 4770 | BIT(NL80211_IFTYPE_WDS) | |
4749 | BIT(NL80211_IFTYPE_ADHOC); | 4771 | BIT(NL80211_IFTYPE_ADHOC); |
4750 | 4772 | ||
4751 | hw->queues = b43_modparam_qos ? 4 : 1; | 4773 | hw->queues = modparam_qos ? 4 : 1; |
4774 | wl->mac80211_initially_registered_queues = hw->queues; | ||
4752 | hw->max_rates = 2; | 4775 | hw->max_rates = 2; |
4753 | SET_IEEE80211_DEV(hw, dev->dev); | 4776 | SET_IEEE80211_DEV(hw, dev->dev); |
4754 | if (is_valid_ether_addr(sprom->et1mac)) | 4777 | if (is_valid_ether_addr(sprom->et1mac)) |
@@ -4756,9 +4779,7 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4756 | else | 4779 | else |
4757 | SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac); | 4780 | SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac); |
4758 | 4781 | ||
4759 | /* Get and initialize struct b43_wl */ | 4782 | /* Initialize struct b43_wl */ |
4760 | wl = hw_to_b43_wl(hw); | ||
4761 | memset(wl, 0, sizeof(*wl)); | ||
4762 | wl->hw = hw; | 4783 | wl->hw = hw; |
4763 | spin_lock_init(&wl->irq_lock); | 4784 | spin_lock_init(&wl->irq_lock); |
4764 | rwlock_init(&wl->tx_lock); | 4785 | rwlock_init(&wl->tx_lock); |
@@ -4824,8 +4845,13 @@ static void b43_remove(struct ssb_device *dev) | |||
4824 | cancel_work_sync(&wldev->restart_work); | 4845 | cancel_work_sync(&wldev->restart_work); |
4825 | 4846 | ||
4826 | B43_WARN_ON(!wl); | 4847 | B43_WARN_ON(!wl); |
4827 | if (wl->current_dev == wldev) | 4848 | if (wl->current_dev == wldev) { |
4849 | /* Restore the queues count before unregistering, because firmware detect | ||
4850 | * might have modified it. Restoring is important, so the networking | ||
4851 | * stack can properly free resources. */ | ||
4852 | wl->hw->queues = wl->mac80211_initially_registered_queues; | ||
4828 | ieee80211_unregister_hw(wl->hw); | 4853 | ieee80211_unregister_hw(wl->hw); |
4854 | } | ||
4829 | 4855 | ||
4830 | b43_one_core_detach(dev); | 4856 | b43_one_core_detach(dev); |
4831 | 4857 | ||
@@ -4920,7 +4946,7 @@ static struct ssb_driver b43_ssb_driver = { | |||
4920 | static void b43_print_driverinfo(void) | 4946 | static void b43_print_driverinfo(void) |
4921 | { | 4947 | { |
4922 | const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", | 4948 | const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", |
4923 | *feat_leds = "", *feat_rfkill = ""; | 4949 | *feat_leds = ""; |
4924 | 4950 | ||
4925 | #ifdef CONFIG_B43_PCI_AUTOSELECT | 4951 | #ifdef CONFIG_B43_PCI_AUTOSELECT |
4926 | feat_pci = "P"; | 4952 | feat_pci = "P"; |
@@ -4934,14 +4960,11 @@ static void b43_print_driverinfo(void) | |||
4934 | #ifdef CONFIG_B43_LEDS | 4960 | #ifdef CONFIG_B43_LEDS |
4935 | feat_leds = "L"; | 4961 | feat_leds = "L"; |
4936 | #endif | 4962 | #endif |
4937 | #ifdef CONFIG_B43_RFKILL | ||
4938 | feat_rfkill = "R"; | ||
4939 | #endif | ||
4940 | printk(KERN_INFO "Broadcom 43xx driver loaded " | 4963 | printk(KERN_INFO "Broadcom 43xx driver loaded " |
4941 | "[ Features: %s%s%s%s%s, Firmware-ID: " | 4964 | "[ Features: %s%s%s%s, Firmware-ID: " |
4942 | B43_SUPPORTED_FIRMWARE_ID " ]\n", | 4965 | B43_SUPPORTED_FIRMWARE_ID " ]\n", |
4943 | feat_pci, feat_pcmcia, feat_nphy, | 4966 | feat_pci, feat_pcmcia, feat_nphy, |
4944 | feat_leds, feat_rfkill); | 4967 | feat_leds); |
4945 | } | 4968 | } |
4946 | 4969 | ||
4947 | static int __init b43_init(void) | 4970 | static int __init b43_init(void) |
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h index 40abcf5d1b43..950fb1b0546d 100644 --- a/drivers/net/wireless/b43/main.h +++ b/drivers/net/wireless/b43/main.h | |||
@@ -39,7 +39,6 @@ | |||
39 | #define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes)) | 39 | #define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes)) |
40 | 40 | ||
41 | 41 | ||
42 | extern int b43_modparam_qos; | ||
43 | extern int b43_modparam_verbose; | 42 | extern int b43_modparam_verbose; |
44 | 43 | ||
45 | /* Logmessage verbosity levels. Update the b43_modparam_verbose helptext, if | 44 | /* Logmessage verbosity levels. Update the b43_modparam_verbose helptext, if |
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index f4c2d79cbc89..44cc918e4fc6 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef LINUX_B43_PHY_COMMON_H_ | 1 | #ifndef LINUX_B43_PHY_COMMON_H_ |
2 | #define LINUX_B43_PHY_COMMON_H_ | 2 | #define LINUX_B43_PHY_COMMON_H_ |
3 | 3 | ||
4 | #include <linux/rfkill.h> | 4 | #include <linux/types.h> |
5 | 5 | ||
6 | struct b43_wldev; | 6 | struct b43_wldev; |
7 | 7 | ||
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index 8cd9776752e6..69138e8c1db6 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c | |||
@@ -313,7 +313,7 @@ static struct b43_pio_txqueue *select_queue_by_priority(struct b43_wldev *dev, | |||
313 | { | 313 | { |
314 | struct b43_pio_txqueue *q; | 314 | struct b43_pio_txqueue *q; |
315 | 315 | ||
316 | if (b43_modparam_qos) { | 316 | if (dev->qos_enabled) { |
317 | /* 0 = highest priority */ | 317 | /* 0 = highest priority */ |
318 | switch (queue_prio) { | 318 | switch (queue_prio) { |
319 | default: | 319 | default: |
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 96047843cd56..31e55999893f 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c | |||
@@ -22,15 +22,11 @@ | |||
22 | 22 | ||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "rfkill.h" | ||
26 | #include "b43.h" | 25 | #include "b43.h" |
27 | #include "phy_common.h" | ||
28 | |||
29 | #include <linux/kmod.h> | ||
30 | 26 | ||
31 | 27 | ||
32 | /* Returns TRUE, if the radio is enabled in hardware. */ | 28 | /* Returns TRUE, if the radio is enabled in hardware. */ |
33 | static bool b43_is_hw_radio_enabled(struct b43_wldev *dev) | 29 | bool b43_is_hw_radio_enabled(struct b43_wldev *dev) |
34 | { | 30 | { |
35 | if (dev->phy.rev >= 3) { | 31 | if (dev->phy.rev >= 3) { |
36 | if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI) | 32 | if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI) |
@@ -45,110 +41,39 @@ static bool b43_is_hw_radio_enabled(struct b43_wldev *dev) | |||
45 | } | 41 | } |
46 | 42 | ||
47 | /* The poll callback for the hardware button. */ | 43 | /* The poll callback for the hardware button. */ |
48 | static void b43_rfkill_poll(struct rfkill *rfkill, void *data) | 44 | void b43_rfkill_poll(struct ieee80211_hw *hw) |
49 | { | 45 | { |
50 | struct b43_wldev *dev = data; | 46 | struct b43_wl *wl = hw_to_b43_wl(hw); |
51 | struct b43_wl *wl = dev->wl; | 47 | struct b43_wldev *dev = wl->current_dev; |
48 | struct ssb_bus *bus = dev->dev->bus; | ||
52 | bool enabled; | 49 | bool enabled; |
50 | bool brought_up = false; | ||
53 | 51 | ||
54 | mutex_lock(&wl->mutex); | 52 | mutex_lock(&wl->mutex); |
55 | if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { | 53 | if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { |
56 | mutex_unlock(&wl->mutex); | 54 | if (ssb_bus_powerup(bus, 0)) { |
57 | return; | 55 | mutex_unlock(&wl->mutex); |
56 | return; | ||
57 | } | ||
58 | ssb_device_enable(dev->dev, 0); | ||
59 | brought_up = true; | ||
58 | } | 60 | } |
61 | |||
59 | enabled = b43_is_hw_radio_enabled(dev); | 62 | enabled = b43_is_hw_radio_enabled(dev); |
63 | |||
60 | if (unlikely(enabled != dev->radio_hw_enable)) { | 64 | if (unlikely(enabled != dev->radio_hw_enable)) { |
61 | dev->radio_hw_enable = enabled; | 65 | dev->radio_hw_enable = enabled; |
62 | b43info(wl, "Radio hardware status changed to %s\n", | 66 | b43info(wl, "Radio hardware status changed to %s\n", |
63 | enabled ? "ENABLED" : "DISABLED"); | 67 | enabled ? "ENABLED" : "DISABLED"); |
64 | enabled = !rfkill_set_hw_state(rfkill, !enabled); | 68 | wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); |
65 | if (enabled != dev->phy.radio_on) | 69 | if (enabled != dev->phy.radio_on) |
66 | b43_software_rfkill(dev, !enabled); | 70 | b43_software_rfkill(dev, !enabled); |
67 | } | 71 | } |
68 | mutex_unlock(&wl->mutex); | ||
69 | } | ||
70 | |||
71 | /* Called when the RFKILL toggled in software. */ | ||
72 | static int b43_rfkill_soft_set(void *data, bool blocked) | ||
73 | { | ||
74 | struct b43_wldev *dev = data; | ||
75 | struct b43_wl *wl = dev->wl; | ||
76 | int err = -EINVAL; | ||
77 | |||
78 | if (WARN_ON(!wl->rfkill.registered)) | ||
79 | return -EINVAL; | ||
80 | 72 | ||
81 | mutex_lock(&wl->mutex); | 73 | if (brought_up) { |
82 | 74 | ssb_device_disable(dev->dev, 0); | |
83 | if (b43_status(dev) < B43_STAT_INITIALIZED) | 75 | ssb_bus_may_powerdown(bus); |
84 | goto out_unlock; | 76 | } |
85 | |||
86 | if (!dev->radio_hw_enable) | ||
87 | goto out_unlock; | ||
88 | 77 | ||
89 | if (!blocked != dev->phy.radio_on) | ||
90 | b43_software_rfkill(dev, blocked); | ||
91 | err = 0; | ||
92 | out_unlock: | ||
93 | mutex_unlock(&wl->mutex); | 78 | mutex_unlock(&wl->mutex); |
94 | return err; | ||
95 | } | ||
96 | |||
97 | const char *b43_rfkill_led_name(struct b43_wldev *dev) | ||
98 | { | ||
99 | struct b43_rfkill *rfk = &(dev->wl->rfkill); | ||
100 | |||
101 | if (!rfk->registered) | ||
102 | return NULL; | ||
103 | return rfkill_get_led_trigger_name(rfk->rfkill); | ||
104 | } | ||
105 | |||
106 | static const struct rfkill_ops b43_rfkill_ops = { | ||
107 | .set_block = b43_rfkill_soft_set, | ||
108 | .poll = b43_rfkill_poll, | ||
109 | }; | ||
110 | |||
111 | void b43_rfkill_init(struct b43_wldev *dev) | ||
112 | { | ||
113 | struct b43_wl *wl = dev->wl; | ||
114 | struct b43_rfkill *rfk = &(wl->rfkill); | ||
115 | int err; | ||
116 | |||
117 | rfk->registered = 0; | ||
118 | |||
119 | snprintf(rfk->name, sizeof(rfk->name), | ||
120 | "b43-%s", wiphy_name(wl->hw->wiphy)); | ||
121 | |||
122 | rfk->rfkill = rfkill_alloc(rfk->name, | ||
123 | dev->dev->dev, | ||
124 | RFKILL_TYPE_WLAN, | ||
125 | &b43_rfkill_ops, dev); | ||
126 | if (!rfk->rfkill) | ||
127 | goto out_error; | ||
128 | |||
129 | err = rfkill_register(rfk->rfkill); | ||
130 | if (err) | ||
131 | goto err_free; | ||
132 | |||
133 | rfk->registered = 1; | ||
134 | |||
135 | return; | ||
136 | err_free: | ||
137 | rfkill_destroy(rfk->rfkill); | ||
138 | out_error: | ||
139 | rfk->registered = 0; | ||
140 | b43warn(wl, "RF-kill button init failed\n"); | ||
141 | } | ||
142 | |||
143 | void b43_rfkill_exit(struct b43_wldev *dev) | ||
144 | { | ||
145 | struct b43_rfkill *rfk = &(dev->wl->rfkill); | ||
146 | |||
147 | if (!rfk->registered) | ||
148 | return; | ||
149 | rfk->registered = 0; | ||
150 | |||
151 | rfkill_unregister(rfk->rfkill); | ||
152 | rfkill_destroy(rfk->rfkill); | ||
153 | rfk->rfkill = NULL; | ||
154 | } | 79 | } |
diff --git a/drivers/net/wireless/b43/rfkill.h b/drivers/net/wireless/b43/rfkill.h index da497e01bbb1..f046c3ca0519 100644 --- a/drivers/net/wireless/b43/rfkill.h +++ b/drivers/net/wireless/b43/rfkill.h | |||
@@ -1,49 +1,11 @@ | |||
1 | #ifndef B43_RFKILL_H_ | 1 | #ifndef B43_RFKILL_H_ |
2 | #define B43_RFKILL_H_ | 2 | #define B43_RFKILL_H_ |
3 | 3 | ||
4 | struct ieee80211_hw; | ||
4 | struct b43_wldev; | 5 | struct b43_wldev; |
5 | 6 | ||
7 | void b43_rfkill_poll(struct ieee80211_hw *hw); | ||
6 | 8 | ||
7 | #ifdef CONFIG_B43_RFKILL | 9 | bool b43_is_hw_radio_enabled(struct b43_wldev *dev); |
8 | |||
9 | #include <linux/rfkill.h> | ||
10 | |||
11 | |||
12 | struct b43_rfkill { | ||
13 | /* The RFKILL subsystem data structure */ | ||
14 | struct rfkill *rfkill; | ||
15 | /* Did initialization succeed? Used for freeing. */ | ||
16 | bool registered; | ||
17 | /* The unique name of this rfkill switch */ | ||
18 | char name[sizeof("b43-phy4294967295")]; | ||
19 | }; | ||
20 | |||
21 | /* The init function returns void, because we are not interested | ||
22 | * in failing the b43 init process when rfkill init failed. */ | ||
23 | void b43_rfkill_init(struct b43_wldev *dev); | ||
24 | void b43_rfkill_exit(struct b43_wldev *dev); | ||
25 | |||
26 | const char *b43_rfkill_led_name(struct b43_wldev *dev); | ||
27 | |||
28 | |||
29 | #else /* CONFIG_B43_RFKILL */ | ||
30 | /* No RFKILL support. */ | ||
31 | |||
32 | struct b43_rfkill { | ||
33 | /* empty */ | ||
34 | }; | ||
35 | |||
36 | static inline void b43_rfkill_init(struct b43_wldev *dev) | ||
37 | { | ||
38 | } | ||
39 | static inline void b43_rfkill_exit(struct b43_wldev *dev) | ||
40 | { | ||
41 | } | ||
42 | static inline char * b43_rfkill_led_name(struct b43_wldev *dev) | ||
43 | { | ||
44 | return NULL; | ||
45 | } | ||
46 | |||
47 | #endif /* CONFIG_B43_RFKILL */ | ||
48 | 10 | ||
49 | #endif /* B43_RFKILL_H_ */ | 11 | #endif /* B43_RFKILL_H_ */ |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index a63d88841df8..55f36a7254d9 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -118,7 +118,6 @@ u8 b43_plcp_get_ratecode_ofdm(const u8 bitrate) | |||
118 | void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, | 118 | void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, |
119 | const u16 octets, const u8 bitrate) | 119 | const u16 octets, const u8 bitrate) |
120 | { | 120 | { |
121 | __le32 *data = &(plcp->data); | ||
122 | __u8 *raw = plcp->raw; | 121 | __u8 *raw = plcp->raw; |
123 | 122 | ||
124 | if (b43_is_ofdm_rate(bitrate)) { | 123 | if (b43_is_ofdm_rate(bitrate)) { |
@@ -127,7 +126,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, | |||
127 | d = b43_plcp_get_ratecode_ofdm(bitrate); | 126 | d = b43_plcp_get_ratecode_ofdm(bitrate); |
128 | B43_WARN_ON(octets & 0xF000); | 127 | B43_WARN_ON(octets & 0xF000); |
129 | d |= (octets << 5); | 128 | d |= (octets << 5); |
130 | *data = cpu_to_le32(d); | 129 | plcp->data = cpu_to_le32(d); |
131 | } else { | 130 | } else { |
132 | u32 plen; | 131 | u32 plen; |
133 | 132 | ||
@@ -141,7 +140,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, | |||
141 | raw[1] = 0x04; | 140 | raw[1] = 0x04; |
142 | } else | 141 | } else |
143 | raw[1] = 0x04; | 142 | raw[1] = 0x04; |
144 | *data |= cpu_to_le32(plen << 16); | 143 | plcp->data |= cpu_to_le32(plen << 16); |
145 | raw[0] = b43_plcp_get_ratecode_cck(bitrate); | 144 | raw[0] = b43_plcp_get_ratecode_cck(bitrate); |
146 | } | 145 | } |
147 | } | 146 | } |
diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig index 6893f439df70..94a463478053 100644 --- a/drivers/net/wireless/b43legacy/Kconfig +++ b/drivers/net/wireless/b43legacy/Kconfig | |||
@@ -42,14 +42,6 @@ config B43LEGACY_LEDS | |||
42 | depends on B43LEGACY && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43LEGACY) | 42 | depends on B43LEGACY && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43LEGACY) |
43 | default y | 43 | default y |
44 | 44 | ||
45 | # RFKILL support | ||
46 | # This config option automatically enables b43legacy RFKILL support, | ||
47 | # if it's possible. | ||
48 | config B43LEGACY_RFKILL | ||
49 | bool | ||
50 | depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY) | ||
51 | default y | ||
52 | |||
53 | # This config option automatically enables b43 HW-RNG support, | 45 | # This config option automatically enables b43 HW-RNG support, |
54 | # if the HW-RNG core is enabled. | 46 | # if the HW-RNG core is enabled. |
55 | config B43LEGACY_HWRNG | 47 | config B43LEGACY_HWRNG |
diff --git a/drivers/net/wireless/b43legacy/Makefile b/drivers/net/wireless/b43legacy/Makefile index 80cdb73bd140..227a77e84362 100644 --- a/drivers/net/wireless/b43legacy/Makefile +++ b/drivers/net/wireless/b43legacy/Makefile | |||
@@ -6,7 +6,7 @@ b43legacy-y += radio.o | |||
6 | b43legacy-y += sysfs.o | 6 | b43legacy-y += sysfs.o |
7 | b43legacy-y += xmit.o | 7 | b43legacy-y += xmit.o |
8 | # b43 RFKILL button support | 8 | # b43 RFKILL button support |
9 | b43legacy-$(CONFIG_B43LEGACY_RFKILL) += rfkill.o | 9 | b43legacy-y += rfkill.o |
10 | # b43legacy LED support | 10 | # b43legacy LED support |
11 | b43legacy-$(CONFIG_B43LEGACY_LEDS) += leds.o | 11 | b43legacy-$(CONFIG_B43LEGACY_LEDS) += leds.o |
12 | # b43legacy debugging | 12 | # b43legacy debugging |
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 19a4b0bc0d87..77fda148ac46 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h | |||
@@ -602,9 +602,6 @@ struct b43legacy_wl { | |||
602 | char rng_name[30 + 1]; | 602 | char rng_name[30 + 1]; |
603 | #endif | 603 | #endif |
604 | 604 | ||
605 | /* The RF-kill button */ | ||
606 | struct b43legacy_rfkill rfkill; | ||
607 | |||
608 | /* List of all wireless devices on this chip */ | 605 | /* List of all wireless devices on this chip */ |
609 | struct list_head devlist; | 606 | struct list_head devlist; |
610 | u8 nr_devs; | 607 | u8 nr_devs; |
diff --git a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c index 538d3117594b..37e9be893560 100644 --- a/drivers/net/wireless/b43legacy/leds.c +++ b/drivers/net/wireless/b43legacy/leds.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include "b43legacy.h" | 29 | #include "b43legacy.h" |
30 | #include "leds.h" | 30 | #include "leds.h" |
31 | #include "rfkill.h" | ||
31 | 32 | ||
32 | 33 | ||
33 | static void b43legacy_led_turn_on(struct b43legacy_wldev *dev, u8 led_index, | 34 | static void b43legacy_led_turn_on(struct b43legacy_wldev *dev, u8 led_index, |
@@ -164,10 +165,10 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev, | |||
164 | snprintf(name, sizeof(name), | 165 | snprintf(name, sizeof(name), |
165 | "b43legacy-%s::radio", wiphy_name(hw->wiphy)); | 166 | "b43legacy-%s::radio", wiphy_name(hw->wiphy)); |
166 | b43legacy_register_led(dev, &dev->led_radio, name, | 167 | b43legacy_register_led(dev, &dev->led_radio, name, |
167 | b43legacy_rfkill_led_name(dev), | 168 | ieee80211_get_radio_led_name(hw), |
168 | led_index, activelow); | 169 | led_index, activelow); |
169 | /* Sync the RF-kill LED state with the switch state. */ | 170 | /* Sync the RF-kill LED state with radio and switch states. */ |
170 | if (dev->radio_hw_enable) | 171 | if (dev->phy.radio_on && b43legacy_is_hw_radio_enabled(dev)) |
171 | b43legacy_led_turn_on(dev, led_index, activelow); | 172 | b43legacy_led_turn_on(dev, led_index, activelow); |
172 | break; | 173 | break; |
173 | case B43legacy_LED_WEIRD: | 174 | case B43legacy_LED_WEIRD: |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index f6f3fbf0a2f4..e5136fb65ddd 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -3431,11 +3431,6 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) | |||
3431 | struct b43legacy_wldev *dev = wl->current_dev; | 3431 | struct b43legacy_wldev *dev = wl->current_dev; |
3432 | int did_init = 0; | 3432 | int did_init = 0; |
3433 | int err = 0; | 3433 | int err = 0; |
3434 | bool do_rfkill_exit = 0; | ||
3435 | |||
3436 | /* First register RFkill. | ||
3437 | * LEDs that are registered later depend on it. */ | ||
3438 | b43legacy_rfkill_init(dev); | ||
3439 | 3434 | ||
3440 | /* Kill all old instance specific information to make sure | 3435 | /* Kill all old instance specific information to make sure |
3441 | * the card won't use it in the short timeframe between start | 3436 | * the card won't use it in the short timeframe between start |
@@ -3451,10 +3446,8 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) | |||
3451 | 3446 | ||
3452 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { | 3447 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { |
3453 | err = b43legacy_wireless_core_init(dev); | 3448 | err = b43legacy_wireless_core_init(dev); |
3454 | if (err) { | 3449 | if (err) |
3455 | do_rfkill_exit = 1; | ||
3456 | goto out_mutex_unlock; | 3450 | goto out_mutex_unlock; |
3457 | } | ||
3458 | did_init = 1; | 3451 | did_init = 1; |
3459 | } | 3452 | } |
3460 | 3453 | ||
@@ -3463,17 +3456,15 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) | |||
3463 | if (err) { | 3456 | if (err) { |
3464 | if (did_init) | 3457 | if (did_init) |
3465 | b43legacy_wireless_core_exit(dev); | 3458 | b43legacy_wireless_core_exit(dev); |
3466 | do_rfkill_exit = 1; | ||
3467 | goto out_mutex_unlock; | 3459 | goto out_mutex_unlock; |
3468 | } | 3460 | } |
3469 | } | 3461 | } |
3470 | 3462 | ||
3463 | wiphy_rfkill_start_polling(hw->wiphy); | ||
3464 | |||
3471 | out_mutex_unlock: | 3465 | out_mutex_unlock: |
3472 | mutex_unlock(&wl->mutex); | 3466 | mutex_unlock(&wl->mutex); |
3473 | 3467 | ||
3474 | if (do_rfkill_exit) | ||
3475 | b43legacy_rfkill_exit(dev); | ||
3476 | |||
3477 | return err; | 3468 | return err; |
3478 | } | 3469 | } |
3479 | 3470 | ||
@@ -3482,7 +3473,6 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw) | |||
3482 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); | 3473 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); |
3483 | struct b43legacy_wldev *dev = wl->current_dev; | 3474 | struct b43legacy_wldev *dev = wl->current_dev; |
3484 | 3475 | ||
3485 | b43legacy_rfkill_exit(dev); | ||
3486 | cancel_work_sync(&(wl->beacon_update_trigger)); | 3476 | cancel_work_sync(&(wl->beacon_update_trigger)); |
3487 | 3477 | ||
3488 | mutex_lock(&wl->mutex); | 3478 | mutex_lock(&wl->mutex); |
@@ -3518,6 +3508,7 @@ static const struct ieee80211_ops b43legacy_hw_ops = { | |||
3518 | .start = b43legacy_op_start, | 3508 | .start = b43legacy_op_start, |
3519 | .stop = b43legacy_op_stop, | 3509 | .stop = b43legacy_op_stop, |
3520 | .set_tim = b43legacy_op_beacon_set_tim, | 3510 | .set_tim = b43legacy_op_beacon_set_tim, |
3511 | .rfkill_poll = b43legacy_rfkill_poll, | ||
3521 | }; | 3512 | }; |
3522 | 3513 | ||
3523 | /* Hard-reset the chip. Do not call this directly. | 3514 | /* Hard-reset the chip. Do not call this directly. |
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index c6230a64505a..8783022db11e 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c | |||
@@ -22,15 +22,12 @@ | |||
22 | 22 | ||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "rfkill.h" | ||
26 | #include "radio.h" | 25 | #include "radio.h" |
27 | #include "b43legacy.h" | 26 | #include "b43legacy.h" |
28 | 27 | ||
29 | #include <linux/kmod.h> | ||
30 | |||
31 | 28 | ||
32 | /* Returns TRUE, if the radio is enabled in hardware. */ | 29 | /* Returns TRUE, if the radio is enabled in hardware. */ |
33 | static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | 30 | bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) |
34 | { | 31 | { |
35 | if (dev->phy.rev >= 3) { | 32 | if (dev->phy.rev >= 3) { |
36 | if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) | 33 | if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) |
@@ -45,23 +42,31 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | |||
45 | } | 42 | } |
46 | 43 | ||
47 | /* The poll callback for the hardware button. */ | 44 | /* The poll callback for the hardware button. */ |
48 | static void b43legacy_rfkill_poll(struct rfkill *rfkill, void *data) | 45 | void b43legacy_rfkill_poll(struct ieee80211_hw *hw) |
49 | { | 46 | { |
50 | struct b43legacy_wldev *dev = data; | 47 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); |
51 | struct b43legacy_wl *wl = dev->wl; | 48 | struct b43legacy_wldev *dev = wl->current_dev; |
49 | struct ssb_bus *bus = dev->dev->bus; | ||
52 | bool enabled; | 50 | bool enabled; |
51 | bool brought_up = false; | ||
53 | 52 | ||
54 | mutex_lock(&wl->mutex); | 53 | mutex_lock(&wl->mutex); |
55 | if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { | 54 | if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { |
56 | mutex_unlock(&wl->mutex); | 55 | if (ssb_bus_powerup(bus, 0)) { |
57 | return; | 56 | mutex_unlock(&wl->mutex); |
57 | return; | ||
58 | } | ||
59 | ssb_device_enable(dev->dev, 0); | ||
60 | brought_up = true; | ||
58 | } | 61 | } |
62 | |||
59 | enabled = b43legacy_is_hw_radio_enabled(dev); | 63 | enabled = b43legacy_is_hw_radio_enabled(dev); |
64 | |||
60 | if (unlikely(enabled != dev->radio_hw_enable)) { | 65 | if (unlikely(enabled != dev->radio_hw_enable)) { |
61 | dev->radio_hw_enable = enabled; | 66 | dev->radio_hw_enable = enabled; |
62 | b43legacyinfo(wl, "Radio hardware status changed to %s\n", | 67 | b43legacyinfo(wl, "Radio hardware status changed to %s\n", |
63 | enabled ? "ENABLED" : "DISABLED"); | 68 | enabled ? "ENABLED" : "DISABLED"); |
64 | enabled = !rfkill_set_hw_state(rfkill, !enabled); | 69 | wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); |
65 | if (enabled != dev->phy.radio_on) { | 70 | if (enabled != dev->phy.radio_on) { |
66 | if (enabled) | 71 | if (enabled) |
67 | b43legacy_radio_turn_on(dev); | 72 | b43legacy_radio_turn_on(dev); |
@@ -69,95 +74,11 @@ static void b43legacy_rfkill_poll(struct rfkill *rfkill, void *data) | |||
69 | b43legacy_radio_turn_off(dev, 0); | 74 | b43legacy_radio_turn_off(dev, 0); |
70 | } | 75 | } |
71 | } | 76 | } |
72 | mutex_unlock(&wl->mutex); | ||
73 | } | ||
74 | |||
75 | /* Called when the RFKILL toggled in software. | ||
76 | * This is called without locking. */ | ||
77 | static int b43legacy_rfkill_soft_set(void *data, bool blocked) | ||
78 | { | ||
79 | struct b43legacy_wldev *dev = data; | ||
80 | struct b43legacy_wl *wl = dev->wl; | ||
81 | int ret = -EINVAL; | ||
82 | 77 | ||
83 | if (!wl->rfkill.registered) | 78 | if (brought_up) { |
84 | return -EINVAL; | 79 | ssb_device_disable(dev->dev, 0); |
85 | 80 | ssb_bus_may_powerdown(bus); | |
86 | mutex_lock(&wl->mutex); | ||
87 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) | ||
88 | goto out_unlock; | ||
89 | |||
90 | if (!dev->radio_hw_enable) | ||
91 | goto out_unlock; | ||
92 | |||
93 | if (!blocked != dev->phy.radio_on) { | ||
94 | if (!blocked) | ||
95 | b43legacy_radio_turn_on(dev); | ||
96 | else | ||
97 | b43legacy_radio_turn_off(dev, 0); | ||
98 | } | 81 | } |
99 | ret = 0; | ||
100 | 82 | ||
101 | out_unlock: | ||
102 | mutex_unlock(&wl->mutex); | 83 | mutex_unlock(&wl->mutex); |
103 | return ret; | ||
104 | } | ||
105 | |||
106 | const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) | ||
107 | { | ||
108 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); | ||
109 | |||
110 | if (!rfk->registered) | ||
111 | return NULL; | ||
112 | return rfkill_get_led_trigger_name(rfk->rfkill); | ||
113 | } | 84 | } |
114 | |||
115 | static const struct rfkill_ops b43legacy_rfkill_ops = { | ||
116 | .set_block = b43legacy_rfkill_soft_set, | ||
117 | .poll = b43legacy_rfkill_poll, | ||
118 | }; | ||
119 | |||
120 | void b43legacy_rfkill_init(struct b43legacy_wldev *dev) | ||
121 | { | ||
122 | struct b43legacy_wl *wl = dev->wl; | ||
123 | struct b43legacy_rfkill *rfk = &(wl->rfkill); | ||
124 | int err; | ||
125 | |||
126 | rfk->registered = 0; | ||
127 | |||
128 | snprintf(rfk->name, sizeof(rfk->name), | ||
129 | "b43legacy-%s", wiphy_name(wl->hw->wiphy)); | ||
130 | rfk->rfkill = rfkill_alloc(rfk->name, | ||
131 | dev->dev->dev, | ||
132 | RFKILL_TYPE_WLAN, | ||
133 | &b43legacy_rfkill_ops, dev); | ||
134 | if (!rfk->rfkill) | ||
135 | goto out_error; | ||
136 | |||
137 | err = rfkill_register(rfk->rfkill); | ||
138 | if (err) | ||
139 | goto err_free; | ||
140 | |||
141 | rfk->registered = 1; | ||
142 | |||
143 | return; | ||
144 | err_free: | ||
145 | rfkill_destroy(rfk->rfkill); | ||
146 | out_error: | ||
147 | rfk->registered = 0; | ||
148 | b43legacywarn(wl, "RF-kill button init failed\n"); | ||
149 | } | ||
150 | |||
151 | void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) | ||
152 | { | ||
153 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); | ||
154 | |||
155 | if (!rfk->registered) | ||
156 | return; | ||
157 | rfk->registered = 0; | ||
158 | |||
159 | rfkill_unregister(rfk->rfkill); | ||
160 | rfkill_destroy(rfk->rfkill); | ||
161 | rfk->rfkill = NULL; | ||
162 | } | ||
163 | |||
diff --git a/drivers/net/wireless/b43legacy/rfkill.h b/drivers/net/wireless/b43legacy/rfkill.h index adffc503a6a1..75585571c544 100644 --- a/drivers/net/wireless/b43legacy/rfkill.h +++ b/drivers/net/wireless/b43legacy/rfkill.h | |||
@@ -1,55 +1,11 @@ | |||
1 | #ifndef B43legacy_RFKILL_H_ | 1 | #ifndef B43legacy_RFKILL_H_ |
2 | #define B43legacy_RFKILL_H_ | 2 | #define B43legacy_RFKILL_H_ |
3 | 3 | ||
4 | struct ieee80211_hw; | ||
4 | struct b43legacy_wldev; | 5 | struct b43legacy_wldev; |
5 | 6 | ||
6 | #ifdef CONFIG_B43LEGACY_RFKILL | 7 | void b43legacy_rfkill_poll(struct ieee80211_hw *hw); |
7 | 8 | ||
8 | #include <linux/rfkill.h> | 9 | bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev); |
9 | |||
10 | |||
11 | |||
12 | struct b43legacy_rfkill { | ||
13 | /* The RFKILL subsystem data structure */ | ||
14 | struct rfkill *rfkill; | ||
15 | /* Did initialization succeed? Used for freeing. */ | ||
16 | bool registered; | ||
17 | /* The unique name of this rfkill switch */ | ||
18 | char name[sizeof("b43legacy-phy4294967295")]; | ||
19 | }; | ||
20 | |||
21 | /* The init function returns void, because we are not interested | ||
22 | * in failing the b43 init process when rfkill init failed. */ | ||
23 | void b43legacy_rfkill_init(struct b43legacy_wldev *dev); | ||
24 | void b43legacy_rfkill_exit(struct b43legacy_wldev *dev); | ||
25 | |||
26 | const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev); | ||
27 | |||
28 | |||
29 | #else /* CONFIG_B43LEGACY_RFKILL */ | ||
30 | /* No RFKILL support. */ | ||
31 | |||
32 | struct b43legacy_rfkill { | ||
33 | /* empty */ | ||
34 | }; | ||
35 | |||
36 | static inline void b43legacy_rfkill_alloc(struct b43legacy_wldev *dev) | ||
37 | { | ||
38 | } | ||
39 | static inline void b43legacy_rfkill_free(struct b43legacy_wldev *dev) | ||
40 | { | ||
41 | } | ||
42 | static inline void b43legacy_rfkill_init(struct b43legacy_wldev *dev) | ||
43 | { | ||
44 | } | ||
45 | static inline void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) | ||
46 | { | ||
47 | } | ||
48 | static inline char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) | ||
49 | { | ||
50 | return NULL; | ||
51 | } | ||
52 | |||
53 | #endif /* CONFIG_B43LEGACY_RFKILL */ | ||
54 | 10 | ||
55 | #endif /* B43legacy_RFKILL_H_ */ | 11 | #endif /* B43legacy_RFKILL_H_ */ |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 6fe259fcfb8f..029ccb6bdbaa 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -10,10 +10,6 @@ config IWLWIFI_LEDS | |||
10 | bool "Enable LED support in iwlagn and iwl3945 drivers" | 10 | bool "Enable LED support in iwlagn and iwl3945 drivers" |
11 | depends on IWLWIFI | 11 | depends on IWLWIFI |
12 | 12 | ||
13 | config IWLWIFI_RFKILL | ||
14 | def_bool y | ||
15 | depends on IWLWIFI && RFKILL | ||
16 | |||
17 | config IWLWIFI_SPECTRUM_MEASUREMENT | 13 | config IWLWIFI_SPECTRUM_MEASUREMENT |
18 | bool "Enable Spectrum Measurement in iwlagn driver" | 14 | bool "Enable Spectrum Measurement in iwlagn driver" |
19 | depends on IWLWIFI | 15 | depends on IWLWIFI |
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index d79d97ad61a5..1d4e0a226fd4 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -4,7 +4,6 @@ iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o | |||
4 | iwlcore-objs += iwl-scan.o | 4 | iwlcore-objs += iwl-scan.o |
5 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | 5 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o |
6 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o | 6 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o |
7 | iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o | ||
8 | iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o | 7 | iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o |
9 | 8 | ||
10 | obj-$(CONFIG_IWLAGN) += iwlagn.o | 9 | obj-$(CONFIG_IWLAGN) += iwlagn.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 4d8a325ea9d8..fbb3a573463e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -36,10 +36,6 @@ | |||
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <net/ieee80211_radiotap.h> | 37 | #include <net/ieee80211_radiotap.h> |
38 | 38 | ||
39 | /*used for rfkill*/ | ||
40 | #include <linux/rfkill.h> | ||
41 | #include <linux/input.h> | ||
42 | |||
43 | /* Hardware specific file defines the PCI IDs table for that hardware module */ | 39 | /* Hardware specific file defines the PCI IDs table for that hardware module */ |
44 | extern struct pci_device_id iwl3945_hw_card_ids[]; | 40 | extern struct pci_device_id iwl3945_hw_card_ids[]; |
45 | 41 | ||
@@ -155,7 +151,6 @@ struct iwl3945_frame { | |||
155 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ | 151 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ |
156 | #define STATUS_INT_ENABLED 2 | 152 | #define STATUS_INT_ENABLED 2 |
157 | #define STATUS_RF_KILL_HW 3 | 153 | #define STATUS_RF_KILL_HW 3 |
158 | #define STATUS_RF_KILL_SW 4 | ||
159 | #define STATUS_INIT 5 | 154 | #define STATUS_INIT 5 |
160 | #define STATUS_ALIVE 6 | 155 | #define STATUS_ALIVE 6 |
161 | #define STATUS_READY 7 | 156 | #define STATUS_READY 7 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b77208de92ad..a5637c4aa85d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -737,19 +737,13 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, | |||
737 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 737 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
738 | 738 | ||
739 | 739 | ||
740 | if (flags & SW_CARD_DISABLED) | ||
741 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
742 | else | ||
743 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
744 | |||
745 | if (!(flags & RXON_CARD_DISABLED)) | 740 | if (!(flags & RXON_CARD_DISABLED)) |
746 | iwl_scan_cancel(priv); | 741 | iwl_scan_cancel(priv); |
747 | 742 | ||
748 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 743 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
749 | test_bit(STATUS_RF_KILL_HW, &priv->status)) || | 744 | test_bit(STATUS_RF_KILL_HW, &priv->status))) |
750 | (test_bit(STATUS_RF_KILL_SW, &status) != | 745 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
751 | test_bit(STATUS_RF_KILL_SW, &priv->status))) | 746 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
752 | queue_work(priv->workqueue, &priv->rf_kill); | ||
753 | else | 747 | else |
754 | wake_up_interruptible(&priv->wait_command_queue); | 748 | wake_up_interruptible(&priv->wait_command_queue); |
755 | } | 749 | } |
@@ -1045,7 +1039,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
1045 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 1039 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
1046 | else | 1040 | else |
1047 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 1041 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
1048 | queue_work(priv->workqueue, &priv->rf_kill); | 1042 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); |
1049 | } | 1043 | } |
1050 | 1044 | ||
1051 | handled |= CSR_INT_BIT_RF_KILL; | 1045 | handled |= CSR_INT_BIT_RF_KILL; |
@@ -1218,7 +1212,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1218 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 1212 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
1219 | else | 1213 | else |
1220 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 1214 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
1221 | queue_work(priv->workqueue, &priv->rf_kill); | 1215 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); |
1222 | } | 1216 | } |
1223 | 1217 | ||
1224 | handled |= CSR_INT_BIT_RF_KILL; | 1218 | handled |= CSR_INT_BIT_RF_KILL; |
@@ -1726,12 +1720,10 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1726 | ieee80211_stop_queues(priv->hw); | 1720 | ieee80211_stop_queues(priv->hw); |
1727 | 1721 | ||
1728 | /* If we have not previously called iwl_init() then | 1722 | /* If we have not previously called iwl_init() then |
1729 | * clear all bits but the RF Kill bits and return */ | 1723 | * clear all bits but the RF Kill bit and return */ |
1730 | if (!iwl_is_init(priv)) { | 1724 | if (!iwl_is_init(priv)) { |
1731 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << | 1725 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << |
1732 | STATUS_RF_KILL_HW | | 1726 | STATUS_RF_KILL_HW | |
1733 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
1734 | STATUS_RF_KILL_SW | | ||
1735 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 1727 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
1736 | STATUS_GEO_CONFIGURED | | 1728 | STATUS_GEO_CONFIGURED | |
1737 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 1729 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
@@ -1740,11 +1732,9 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1740 | } | 1732 | } |
1741 | 1733 | ||
1742 | /* ...otherwise clear out all the status bits but the RF Kill | 1734 | /* ...otherwise clear out all the status bits but the RF Kill |
1743 | * bits and continue taking the NIC down. */ | 1735 | * bit and continue taking the NIC down. */ |
1744 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << | 1736 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << |
1745 | STATUS_RF_KILL_HW | | 1737 | STATUS_RF_KILL_HW | |
1746 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
1747 | STATUS_RF_KILL_SW | | ||
1748 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 1738 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
1749 | STATUS_GEO_CONFIGURED | | 1739 | STATUS_GEO_CONFIGURED | |
1750 | test_bit(STATUS_FW_ERROR, &priv->status) << | 1740 | test_bit(STATUS_FW_ERROR, &priv->status) << |
@@ -1866,9 +1856,10 @@ static int __iwl_up(struct iwl_priv *priv) | |||
1866 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 1856 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
1867 | 1857 | ||
1868 | if (iwl_is_rfkill(priv)) { | 1858 | if (iwl_is_rfkill(priv)) { |
1859 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, true); | ||
1860 | |||
1869 | iwl_enable_interrupts(priv); | 1861 | iwl_enable_interrupts(priv); |
1870 | IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n", | 1862 | IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); |
1871 | test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); | ||
1872 | return 0; | 1863 | return 0; |
1873 | } | 1864 | } |
1874 | 1865 | ||
@@ -2001,7 +1992,6 @@ static void iwl_bg_up(struct work_struct *data) | |||
2001 | mutex_lock(&priv->mutex); | 1992 | mutex_lock(&priv->mutex); |
2002 | __iwl_up(priv); | 1993 | __iwl_up(priv); |
2003 | mutex_unlock(&priv->mutex); | 1994 | mutex_unlock(&priv->mutex); |
2004 | iwl_rfkill_set_hw_state(priv); | ||
2005 | } | 1995 | } |
2006 | 1996 | ||
2007 | static void iwl_bg_restart(struct work_struct *data) | 1997 | static void iwl_bg_restart(struct work_struct *data) |
@@ -2179,8 +2169,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2179 | 2169 | ||
2180 | mutex_unlock(&priv->mutex); | 2170 | mutex_unlock(&priv->mutex); |
2181 | 2171 | ||
2182 | iwl_rfkill_set_hw_state(priv); | ||
2183 | |||
2184 | if (ret) | 2172 | if (ret) |
2185 | return ret; | 2173 | return ret; |
2186 | 2174 | ||
@@ -2775,7 +2763,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
2775 | INIT_WORK(&priv->up, iwl_bg_up); | 2763 | INIT_WORK(&priv->up, iwl_bg_up); |
2776 | INIT_WORK(&priv->restart, iwl_bg_restart); | 2764 | INIT_WORK(&priv->restart, iwl_bg_restart); |
2777 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); | 2765 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); |
2778 | INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); | ||
2779 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); | 2766 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); |
2780 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); | 2767 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); |
2781 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); | 2768 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); |
@@ -3046,12 +3033,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3046 | else | 3033 | else |
3047 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 3034 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
3048 | 3035 | ||
3049 | err = iwl_rfkill_init(priv); | 3036 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
3050 | if (err) | 3037 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
3051 | IWL_ERR(priv, "Unable to initialize RFKILL system. " | ||
3052 | "Ignoring error: %d\n", err); | ||
3053 | else | ||
3054 | iwl_rfkill_set_hw_state(priv); | ||
3055 | 3038 | ||
3056 | iwl_power_initialize(priv); | 3039 | iwl_power_initialize(priv); |
3057 | return 0; | 3040 | return 0; |
@@ -3115,7 +3098,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3115 | 3098 | ||
3116 | iwl_synchronize_irq(priv); | 3099 | iwl_synchronize_irq(priv); |
3117 | 3100 | ||
3118 | iwl_rfkill_unregister(priv); | ||
3119 | iwl_dealloc_ucode_pci(priv); | 3101 | iwl_dealloc_ucode_pci(priv); |
3120 | 3102 | ||
3121 | if (priv->rxq.bd) | 3103 | if (priv->rxq.bd) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 51cae4ec26a5..f9d16ca5b3d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include "iwl-debug.h" | 36 | #include "iwl-debug.h" |
37 | #include "iwl-core.h" | 37 | #include "iwl-core.h" |
38 | #include "iwl-io.h" | 38 | #include "iwl-io.h" |
39 | #include "iwl-rfkill.h" | ||
40 | #include "iwl-power.h" | 39 | #include "iwl-power.h" |
41 | #include "iwl-sta.h" | 40 | #include "iwl-sta.h" |
42 | #include "iwl-helpers.h" | 41 | #include "iwl-helpers.h" |
@@ -2211,126 +2210,6 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) | |||
2211 | } | 2210 | } |
2212 | EXPORT_SYMBOL(iwl_send_card_state); | 2211 | EXPORT_SYMBOL(iwl_send_card_state); |
2213 | 2212 | ||
2214 | void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv) | ||
2215 | { | ||
2216 | unsigned long flags; | ||
2217 | |||
2218 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) | ||
2219 | return; | ||
2220 | |||
2221 | IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO OFF\n"); | ||
2222 | |||
2223 | iwl_scan_cancel(priv); | ||
2224 | /* FIXME: This is a workaround for AP */ | ||
2225 | if (priv->iw_mode != NL80211_IFTYPE_AP) { | ||
2226 | spin_lock_irqsave(&priv->lock, flags); | ||
2227 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, | ||
2228 | CSR_UCODE_SW_BIT_RFKILL); | ||
2229 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2230 | /* call the host command only if no hw rf-kill set */ | ||
2231 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status) && | ||
2232 | iwl_is_ready(priv)) | ||
2233 | iwl_send_card_state(priv, | ||
2234 | CARD_STATE_CMD_DISABLE, 0); | ||
2235 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
2236 | /* make sure mac80211 stop sending Tx frame */ | ||
2237 | if (priv->mac80211_registered) | ||
2238 | ieee80211_stop_queues(priv->hw); | ||
2239 | } | ||
2240 | } | ||
2241 | EXPORT_SYMBOL(iwl_radio_kill_sw_disable_radio); | ||
2242 | |||
2243 | int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv) | ||
2244 | { | ||
2245 | unsigned long flags; | ||
2246 | |||
2247 | if (!test_bit(STATUS_RF_KILL_SW, &priv->status)) | ||
2248 | return 0; | ||
2249 | |||
2250 | IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO ON\n"); | ||
2251 | |||
2252 | spin_lock_irqsave(&priv->lock, flags); | ||
2253 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
2254 | |||
2255 | /* If the driver is up it will receive CARD_STATE_NOTIFICATION | ||
2256 | * notification where it will clear SW rfkill status. | ||
2257 | * Setting it here would break the handler. Only if the | ||
2258 | * interface is down we can set here since we don't | ||
2259 | * receive any further notification. | ||
2260 | */ | ||
2261 | if (!priv->is_open) | ||
2262 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
2263 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2264 | |||
2265 | /* wake up ucode */ | ||
2266 | msleep(10); | ||
2267 | |||
2268 | iwl_read32(priv, CSR_UCODE_DRV_GP1); | ||
2269 | spin_lock_irqsave(&priv->reg_lock, flags); | ||
2270 | if (!iwl_grab_nic_access(priv)) | ||
2271 | iwl_release_nic_access(priv); | ||
2272 | spin_unlock_irqrestore(&priv->reg_lock, flags); | ||
2273 | |||
2274 | if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { | ||
2275 | IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - " | ||
2276 | "disabled by HW switch\n"); | ||
2277 | return 0; | ||
2278 | } | ||
2279 | |||
2280 | /* when driver is up while rfkill is on, it wont receive | ||
2281 | * any CARD_STATE_NOTIFICATION notifications so we have to | ||
2282 | * restart it in here | ||
2283 | */ | ||
2284 | if (priv->is_open && !test_bit(STATUS_ALIVE, &priv->status)) { | ||
2285 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
2286 | if (!iwl_is_rfkill(priv)) | ||
2287 | queue_work(priv->workqueue, &priv->up); | ||
2288 | } | ||
2289 | |||
2290 | /* If the driver is already loaded, it will receive | ||
2291 | * CARD_STATE_NOTIFICATION notifications and the handler will | ||
2292 | * call restart to reload the driver. | ||
2293 | */ | ||
2294 | return 1; | ||
2295 | } | ||
2296 | EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio); | ||
2297 | |||
2298 | void iwl_bg_rf_kill(struct work_struct *work) | ||
2299 | { | ||
2300 | struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill); | ||
2301 | |||
2302 | wake_up_interruptible(&priv->wait_command_queue); | ||
2303 | |||
2304 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
2305 | return; | ||
2306 | |||
2307 | mutex_lock(&priv->mutex); | ||
2308 | |||
2309 | if (!iwl_is_rfkill(priv)) { | ||
2310 | IWL_DEBUG_RF_KILL(priv, | ||
2311 | "HW and/or SW RF Kill no longer active, restarting " | ||
2312 | "device\n"); | ||
2313 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status) && | ||
2314 | priv->is_open) | ||
2315 | queue_work(priv->workqueue, &priv->restart); | ||
2316 | } else { | ||
2317 | /* make sure mac80211 stop sending Tx frame */ | ||
2318 | if (priv->mac80211_registered) | ||
2319 | ieee80211_stop_queues(priv->hw); | ||
2320 | |||
2321 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status)) | ||
2322 | IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - " | ||
2323 | "disabled by SW switch\n"); | ||
2324 | else | ||
2325 | IWL_WARN(priv, "Radio Frequency Kill Switch is On:\n" | ||
2326 | "Kill switch must be turned off for " | ||
2327 | "wireless networking to work.\n"); | ||
2328 | } | ||
2329 | mutex_unlock(&priv->mutex); | ||
2330 | iwl_rfkill_set_hw_state(priv); | ||
2331 | } | ||
2332 | EXPORT_SYMBOL(iwl_bg_rf_kill); | ||
2333 | |||
2334 | void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, | 2213 | void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, |
2335 | struct iwl_rx_mem_buffer *rxb) | 2214 | struct iwl_rx_mem_buffer *rxb) |
2336 | { | 2215 | { |
@@ -2849,23 +2728,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2849 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 2728 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
2850 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | 2729 | priv->cfg->ops->hcmd->set_rxon_chain(priv); |
2851 | 2730 | ||
2852 | if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { | ||
2853 | if (conf->radio_enabled && | ||
2854 | iwl_radio_kill_sw_enable_radio(priv)) { | ||
2855 | IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - " | ||
2856 | "waiting for uCode\n"); | ||
2857 | goto out; | ||
2858 | } | ||
2859 | |||
2860 | if (!conf->radio_enabled) | ||
2861 | iwl_radio_kill_sw_disable_radio(priv); | ||
2862 | } | ||
2863 | |||
2864 | if (!conf->radio_enabled) { | ||
2865 | IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); | ||
2866 | goto out; | ||
2867 | } | ||
2868 | |||
2869 | if (!iwl_is_ready(priv)) { | 2731 | if (!iwl_is_ready(priv)) { |
2870 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | 2732 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); |
2871 | goto out; | 2733 | goto out; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index b52d0fb16060..dabf663e36e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -348,14 +348,6 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id); | |||
348 | ****************************************************/ | 348 | ****************************************************/ |
349 | int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); | 349 | int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); |
350 | 350 | ||
351 | /***************************************************** | ||
352 | * RF -Kill - here and not in iwl-rfkill.h to be available when | ||
353 | * RF-kill subsystem is not compiled. | ||
354 | ****************************************************/ | ||
355 | void iwl_bg_rf_kill(struct work_struct *work); | ||
356 | void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv); | ||
357 | int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv); | ||
358 | |||
359 | /******************************************************************************* | 351 | /******************************************************************************* |
360 | * Rate | 352 | * Rate |
361 | ******************************************************************************/ | 353 | ******************************************************************************/ |
@@ -498,7 +490,6 @@ void iwlcore_free_geos(struct iwl_priv *priv); | |||
498 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ | 490 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ |
499 | #define STATUS_INT_ENABLED 2 | 491 | #define STATUS_INT_ENABLED 2 |
500 | #define STATUS_RF_KILL_HW 3 | 492 | #define STATUS_RF_KILL_HW 3 |
501 | #define STATUS_RF_KILL_SW 4 | ||
502 | #define STATUS_INIT 5 | 493 | #define STATUS_INIT 5 |
503 | #define STATUS_ALIVE 6 | 494 | #define STATUS_ALIVE 6 |
504 | #define STATUS_READY 7 | 495 | #define STATUS_READY 7 |
@@ -533,11 +524,6 @@ static inline int iwl_is_init(struct iwl_priv *priv) | |||
533 | return test_bit(STATUS_INIT, &priv->status); | 524 | return test_bit(STATUS_INIT, &priv->status); |
534 | } | 525 | } |
535 | 526 | ||
536 | static inline int iwl_is_rfkill_sw(struct iwl_priv *priv) | ||
537 | { | ||
538 | return test_bit(STATUS_RF_KILL_SW, &priv->status); | ||
539 | } | ||
540 | |||
541 | static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) | 527 | static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) |
542 | { | 528 | { |
543 | return test_bit(STATUS_RF_KILL_HW, &priv->status); | 529 | return test_bit(STATUS_RF_KILL_HW, &priv->status); |
@@ -545,7 +531,7 @@ static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) | |||
545 | 531 | ||
546 | static inline int iwl_is_rfkill(struct iwl_priv *priv) | 532 | static inline int iwl_is_rfkill(struct iwl_priv *priv) |
547 | { | 533 | { |
548 | return iwl_is_rfkill_hw(priv) || iwl_is_rfkill_sw(priv); | 534 | return iwl_is_rfkill_hw(priv); |
549 | } | 535 | } |
550 | 536 | ||
551 | static inline int iwl_is_ready_rf(struct iwl_priv *priv) | 537 | static inline int iwl_is_ready_rf(struct iwl_priv *priv) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index af70229144b3..11e08c068917 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -449,8 +449,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, | |||
449 | test_bit(STATUS_INT_ENABLED, &priv->status)); | 449 | test_bit(STATUS_INT_ENABLED, &priv->status)); |
450 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", | 450 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", |
451 | test_bit(STATUS_RF_KILL_HW, &priv->status)); | 451 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
452 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_SW:\t %d\n", | ||
453 | test_bit(STATUS_RF_KILL_SW, &priv->status)); | ||
454 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", | 452 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", |
455 | test_bit(STATUS_INIT, &priv->status)); | 453 | test_bit(STATUS_INIT, &priv->status)); |
456 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", | 454 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 28c39cf8b126..e2d620f0b6e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -41,7 +41,6 @@ | |||
41 | #include "iwl-prph.h" | 41 | #include "iwl-prph.h" |
42 | #include "iwl-fh.h" | 42 | #include "iwl-fh.h" |
43 | #include "iwl-debug.h" | 43 | #include "iwl-debug.h" |
44 | #include "iwl-rfkill.h" | ||
45 | #include "iwl-4965-hw.h" | 44 | #include "iwl-4965-hw.h" |
46 | #include "iwl-3945-hw.h" | 45 | #include "iwl-3945-hw.h" |
47 | #include "iwl-3945-led.h" | 46 | #include "iwl-3945-led.h" |
@@ -936,9 +935,6 @@ struct iwl_priv { | |||
936 | * 4965's initialize alive response contains some calibration data. */ | 935 | * 4965's initialize alive response contains some calibration data. */ |
937 | struct iwl_init_alive_resp card_alive_init; | 936 | struct iwl_init_alive_resp card_alive_init; |
938 | struct iwl_alive_resp card_alive; | 937 | struct iwl_alive_resp card_alive; |
939 | #if defined(CONFIG_IWLWIFI_RFKILL) | ||
940 | struct rfkill *rfkill; | ||
941 | #endif | ||
942 | 938 | ||
943 | #ifdef CONFIG_IWLWIFI_LEDS | 939 | #ifdef CONFIG_IWLWIFI_LEDS |
944 | unsigned long last_blink_time; | 940 | unsigned long last_blink_time; |
@@ -1072,7 +1068,6 @@ struct iwl_priv { | |||
1072 | struct work_struct calibrated_work; | 1068 | struct work_struct calibrated_work; |
1073 | struct work_struct scan_completed; | 1069 | struct work_struct scan_completed; |
1074 | struct work_struct rx_replenish; | 1070 | struct work_struct rx_replenish; |
1075 | struct work_struct rf_kill; | ||
1076 | struct work_struct abort_scan; | 1071 | struct work_struct abort_scan; |
1077 | struct work_struct update_link_led; | 1072 | struct work_struct update_link_led; |
1078 | struct work_struct auth_work; | 1073 | struct work_struct auth_work; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c deleted file mode 100644 index 13149936fd26..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2009 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 | #include <linux/kernel.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | |||
32 | #include <net/mac80211.h> | ||
33 | |||
34 | #include "iwl-eeprom.h" | ||
35 | #include "iwl-dev.h" | ||
36 | #include "iwl-core.h" | ||
37 | |||
38 | /* software rf-kill from user */ | ||
39 | static int iwl_rfkill_soft_rf_kill(void *data, bool blocked) | ||
40 | { | ||
41 | struct iwl_priv *priv = data; | ||
42 | |||
43 | if (!priv->rfkill) | ||
44 | return -EINVAL; | ||
45 | |||
46 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
47 | return 0; | ||
48 | |||
49 | IWL_DEBUG_RF_KILL(priv, "received soft RFKILL: block=%d\n", blocked); | ||
50 | |||
51 | mutex_lock(&priv->mutex); | ||
52 | |||
53 | if (iwl_is_rfkill_hw(priv)) | ||
54 | goto out_unlock; | ||
55 | |||
56 | if (!blocked) | ||
57 | iwl_radio_kill_sw_enable_radio(priv); | ||
58 | else | ||
59 | iwl_radio_kill_sw_disable_radio(priv); | ||
60 | |||
61 | out_unlock: | ||
62 | mutex_unlock(&priv->mutex); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static const struct rfkill_ops iwl_rfkill_ops = { | ||
67 | .set_block = iwl_rfkill_soft_rf_kill, | ||
68 | }; | ||
69 | |||
70 | int iwl_rfkill_init(struct iwl_priv *priv) | ||
71 | { | ||
72 | struct device *device = wiphy_dev(priv->hw->wiphy); | ||
73 | int ret = 0; | ||
74 | |||
75 | BUG_ON(device == NULL); | ||
76 | |||
77 | IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n"); | ||
78 | priv->rfkill = rfkill_alloc(priv->cfg->name, | ||
79 | device, | ||
80 | RFKILL_TYPE_WLAN, | ||
81 | &iwl_rfkill_ops, priv); | ||
82 | if (!priv->rfkill) { | ||
83 | IWL_ERR(priv, "Unable to allocate RFKILL device.\n"); | ||
84 | ret = -ENOMEM; | ||
85 | goto error; | ||
86 | } | ||
87 | |||
88 | ret = rfkill_register(priv->rfkill); | ||
89 | if (ret) { | ||
90 | IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret); | ||
91 | goto free_rfkill; | ||
92 | } | ||
93 | |||
94 | IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n"); | ||
95 | return 0; | ||
96 | |||
97 | free_rfkill: | ||
98 | rfkill_destroy(priv->rfkill); | ||
99 | priv->rfkill = NULL; | ||
100 | |||
101 | error: | ||
102 | IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n"); | ||
103 | return ret; | ||
104 | } | ||
105 | EXPORT_SYMBOL(iwl_rfkill_init); | ||
106 | |||
107 | void iwl_rfkill_unregister(struct iwl_priv *priv) | ||
108 | { | ||
109 | |||
110 | if (priv->rfkill) { | ||
111 | rfkill_unregister(priv->rfkill); | ||
112 | rfkill_destroy(priv->rfkill); | ||
113 | } | ||
114 | |||
115 | priv->rfkill = NULL; | ||
116 | } | ||
117 | EXPORT_SYMBOL(iwl_rfkill_unregister); | ||
118 | |||
119 | /* set RFKILL to the right state. */ | ||
120 | void iwl_rfkill_set_hw_state(struct iwl_priv *priv) | ||
121 | { | ||
122 | if (!priv->rfkill) | ||
123 | return; | ||
124 | |||
125 | if (rfkill_set_hw_state(priv->rfkill, | ||
126 | !!iwl_is_rfkill_hw(priv))) | ||
127 | iwl_radio_kill_sw_disable_radio(priv); | ||
128 | else | ||
129 | iwl_radio_kill_sw_enable_radio(priv); | ||
130 | } | ||
131 | EXPORT_SYMBOL(iwl_rfkill_set_hw_state); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h deleted file mode 100644 index 633dafb4bf1b..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2009 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 | #ifndef __iwl_rf_kill_h__ | ||
29 | #define __iwl_rf_kill_h__ | ||
30 | |||
31 | struct iwl_priv; | ||
32 | |||
33 | #include <linux/rfkill.h> | ||
34 | |||
35 | #ifdef CONFIG_IWLWIFI_RFKILL | ||
36 | |||
37 | void iwl_rfkill_set_hw_state(struct iwl_priv *priv); | ||
38 | void iwl_rfkill_unregister(struct iwl_priv *priv); | ||
39 | int iwl_rfkill_init(struct iwl_priv *priv); | ||
40 | #else | ||
41 | static inline void iwl_rfkill_set_hw_state(struct iwl_priv *priv) {} | ||
42 | static inline void iwl_rfkill_unregister(struct iwl_priv *priv) {} | ||
43 | static inline int iwl_rfkill_init(struct iwl_priv *priv) { return 0; } | ||
44 | #endif | ||
45 | |||
46 | |||
47 | |||
48 | #endif /* __iwl_rf_kill_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 92fa1a39c446..83d31606dd00 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -1009,18 +1009,12 @@ static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, | |||
1009 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 1009 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
1010 | 1010 | ||
1011 | 1011 | ||
1012 | if (flags & SW_CARD_DISABLED) | ||
1013 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
1014 | else | ||
1015 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
1016 | |||
1017 | iwl_scan_cancel(priv); | 1012 | iwl_scan_cancel(priv); |
1018 | 1013 | ||
1019 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 1014 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
1020 | test_bit(STATUS_RF_KILL_HW, &priv->status)) || | 1015 | test_bit(STATUS_RF_KILL_HW, &priv->status))) |
1021 | (test_bit(STATUS_RF_KILL_SW, &status) != | 1016 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
1022 | test_bit(STATUS_RF_KILL_SW, &priv->status))) | 1017 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
1023 | queue_work(priv->workqueue, &priv->rf_kill); | ||
1024 | else | 1018 | else |
1025 | wake_up_interruptible(&priv->wait_command_queue); | 1019 | wake_up_interruptible(&priv->wait_command_queue); |
1026 | } | 1020 | } |
@@ -2586,8 +2580,6 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
2586 | if (!iwl_is_init(priv)) { | 2580 | if (!iwl_is_init(priv)) { |
2587 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << | 2581 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << |
2588 | STATUS_RF_KILL_HW | | 2582 | STATUS_RF_KILL_HW | |
2589 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
2590 | STATUS_RF_KILL_SW | | ||
2591 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 2583 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
2592 | STATUS_GEO_CONFIGURED | | 2584 | STATUS_GEO_CONFIGURED | |
2593 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 2585 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
@@ -2596,11 +2588,9 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
2596 | } | 2588 | } |
2597 | 2589 | ||
2598 | /* ...otherwise clear out all the status bits but the RF Kill | 2590 | /* ...otherwise clear out all the status bits but the RF Kill |
2599 | * bits and continue taking the NIC down. */ | 2591 | * bit and continue taking the NIC down. */ |
2600 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << | 2592 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << |
2601 | STATUS_RF_KILL_HW | | 2593 | STATUS_RF_KILL_HW | |
2602 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
2603 | STATUS_RF_KILL_SW | | ||
2604 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 2594 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
2605 | STATUS_GEO_CONFIGURED | | 2595 | STATUS_GEO_CONFIGURED | |
2606 | test_bit(STATUS_FW_ERROR, &priv->status) << | 2596 | test_bit(STATUS_FW_ERROR, &priv->status) << |
@@ -2657,12 +2647,6 @@ static int __iwl3945_up(struct iwl_priv *priv) | |||
2657 | return -EIO; | 2647 | return -EIO; |
2658 | } | 2648 | } |
2659 | 2649 | ||
2660 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { | ||
2661 | IWL_WARN(priv, "Radio disabled by SW RF kill (module " | ||
2662 | "parameter)\n"); | ||
2663 | return -ENODEV; | ||
2664 | } | ||
2665 | |||
2666 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { | 2650 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { |
2667 | IWL_ERR(priv, "ucode not available for device bring up\n"); | 2651 | IWL_ERR(priv, "ucode not available for device bring up\n"); |
2668 | return -EIO; | 2652 | return -EIO; |
@@ -2779,15 +2763,14 @@ static void iwl3945_rfkill_poll(struct work_struct *data) | |||
2779 | { | 2763 | { |
2780 | struct iwl_priv *priv = | 2764 | struct iwl_priv *priv = |
2781 | container_of(data, struct iwl_priv, rfkill_poll.work); | 2765 | container_of(data, struct iwl_priv, rfkill_poll.work); |
2782 | unsigned long status = priv->status; | ||
2783 | 2766 | ||
2784 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 2767 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) |
2785 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 2768 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
2786 | else | 2769 | else |
2787 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 2770 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
2788 | 2771 | ||
2789 | if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status)) | 2772 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
2790 | queue_work(priv->workqueue, &priv->rf_kill); | 2773 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
2791 | 2774 | ||
2792 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | 2775 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, |
2793 | round_jiffies_relative(2 * HZ)); | 2776 | round_jiffies_relative(2 * HZ)); |
@@ -3019,7 +3002,6 @@ static void iwl3945_bg_up(struct work_struct *data) | |||
3019 | mutex_lock(&priv->mutex); | 3002 | mutex_lock(&priv->mutex); |
3020 | __iwl3945_up(priv); | 3003 | __iwl3945_up(priv); |
3021 | mutex_unlock(&priv->mutex); | 3004 | mutex_unlock(&priv->mutex); |
3022 | iwl_rfkill_set_hw_state(priv); | ||
3023 | } | 3005 | } |
3024 | 3006 | ||
3025 | static void iwl3945_bg_restart(struct work_struct *data) | 3007 | static void iwl3945_bg_restart(struct work_struct *data) |
@@ -3182,8 +3164,6 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) | |||
3182 | 3164 | ||
3183 | mutex_unlock(&priv->mutex); | 3165 | mutex_unlock(&priv->mutex); |
3184 | 3166 | ||
3185 | iwl_rfkill_set_hw_state(priv); | ||
3186 | |||
3187 | if (ret) | 3167 | if (ret) |
3188 | goto out_release_irq; | 3168 | goto out_release_irq; |
3189 | 3169 | ||
@@ -3836,7 +3816,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv) | |||
3836 | INIT_WORK(&priv->up, iwl3945_bg_up); | 3816 | INIT_WORK(&priv->up, iwl3945_bg_up); |
3837 | INIT_WORK(&priv->restart, iwl3945_bg_restart); | 3817 | INIT_WORK(&priv->restart, iwl3945_bg_restart); |
3838 | INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); | 3818 | INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); |
3839 | INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); | ||
3840 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); | 3819 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); |
3841 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); | 3820 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); |
3842 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); | 3821 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); |
@@ -4203,13 +4182,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
4203 | if (err) | 4182 | if (err) |
4204 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); | 4183 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); |
4205 | 4184 | ||
4206 | err = iwl_rfkill_init(priv); | ||
4207 | if (err) | ||
4208 | IWL_ERR(priv, "Unable to initialize RFKILL system. " | ||
4209 | "Ignoring error: %d\n", err); | ||
4210 | else | ||
4211 | iwl_rfkill_set_hw_state(priv); | ||
4212 | |||
4213 | /* Start monitoring the killswitch */ | 4185 | /* Start monitoring the killswitch */ |
4214 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | 4186 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, |
4215 | 2 * HZ); | 4187 | 2 * HZ); |
@@ -4275,7 +4247,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
4275 | 4247 | ||
4276 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 4248 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
4277 | 4249 | ||
4278 | iwl_rfkill_unregister(priv); | ||
4279 | cancel_delayed_work_sync(&priv->rfkill_poll); | 4250 | cancel_delayed_work_sync(&priv->rfkill_poll); |
4280 | 4251 | ||
4281 | iwl3945_dealloc_ucode_pci(priv); | 4252 | iwl3945_dealloc_ucode_pci(priv); |
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index ea23c5de1420..f8c2898d82b0 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -19,7 +19,6 @@ | |||
19 | 19 | ||
20 | #include <linux/moduleparam.h> | 20 | #include <linux/moduleparam.h> |
21 | #include <linux/firmware.h> | 21 | #include <linux/firmware.h> |
22 | #include <linux/gpio.h> | ||
23 | #include <linux/jiffies.h> | 22 | #include <linux/jiffies.h> |
24 | #include <linux/kthread.h> | 23 | #include <linux/kthread.h> |
25 | #include <linux/list.h> | 24 | #include <linux/list.h> |
@@ -51,13 +50,6 @@ struct if_spi_card { | |||
51 | u16 card_id; | 50 | u16 card_id; |
52 | u8 card_rev; | 51 | u8 card_rev; |
53 | 52 | ||
54 | /* Pin number for our GPIO chip-select. */ | ||
55 | /* TODO: Once the generic SPI layer has some additional features, we | ||
56 | * should take this out and use the normal chip select here. | ||
57 | * We need support for chip select delays, and not dropping chipselect | ||
58 | * after each word. */ | ||
59 | int gpio_cs; | ||
60 | |||
61 | /* The last time that we initiated an SPU operation */ | 53 | /* The last time that we initiated an SPU operation */ |
62 | unsigned long prev_xfer_time; | 54 | unsigned long prev_xfer_time; |
63 | 55 | ||
@@ -130,12 +122,10 @@ static void spu_transaction_init(struct if_spi_card *card) | |||
130 | * If not, we have to busy-wait to be on the safe side. */ | 122 | * If not, we have to busy-wait to be on the safe side. */ |
131 | ndelay(400); | 123 | ndelay(400); |
132 | } | 124 | } |
133 | gpio_set_value(card->gpio_cs, 0); /* assert CS */ | ||
134 | } | 125 | } |
135 | 126 | ||
136 | static void spu_transaction_finish(struct if_spi_card *card) | 127 | static void spu_transaction_finish(struct if_spi_card *card) |
137 | { | 128 | { |
138 | gpio_set_value(card->gpio_cs, 1); /* drop CS */ | ||
139 | card->prev_xfer_time = jiffies; | 129 | card->prev_xfer_time = jiffies; |
140 | } | 130 | } |
141 | 131 | ||
@@ -145,6 +135,13 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) | |||
145 | { | 135 | { |
146 | int err = 0; | 136 | int err = 0; |
147 | u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK); | 137 | u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK); |
138 | struct spi_message m; | ||
139 | struct spi_transfer reg_trans; | ||
140 | struct spi_transfer data_trans; | ||
141 | |||
142 | spi_message_init(&m); | ||
143 | memset(®_trans, 0, sizeof(reg_trans)); | ||
144 | memset(&data_trans, 0, sizeof(data_trans)); | ||
148 | 145 | ||
149 | /* You must give an even number of bytes to the SPU, even if it | 146 | /* You must give an even number of bytes to the SPU, even if it |
150 | * doesn't care about the last one. */ | 147 | * doesn't care about the last one. */ |
@@ -153,13 +150,16 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) | |||
153 | spu_transaction_init(card); | 150 | spu_transaction_init(card); |
154 | 151 | ||
155 | /* write SPU register index */ | 152 | /* write SPU register index */ |
156 | err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); | 153 | reg_trans.tx_buf = ®_out; |
157 | if (err) | 154 | reg_trans.len = sizeof(reg_out); |
158 | goto out; | ||
159 | 155 | ||
160 | err = spi_write(card->spi, buf, len); | 156 | data_trans.tx_buf = buf; |
157 | data_trans.len = len; | ||
161 | 158 | ||
162 | out: | 159 | spi_message_add_tail(®_trans, &m); |
160 | spi_message_add_tail(&data_trans, &m); | ||
161 | |||
162 | err = spi_sync(card->spi, &m); | ||
163 | spu_transaction_finish(card); | 163 | spu_transaction_finish(card); |
164 | return err; | 164 | return err; |
165 | } | 165 | } |
@@ -186,10 +186,13 @@ static inline int spu_reg_is_port_reg(u16 reg) | |||
186 | 186 | ||
187 | static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) | 187 | static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) |
188 | { | 188 | { |
189 | unsigned int i, delay; | 189 | unsigned int delay; |
190 | int err = 0; | 190 | int err = 0; |
191 | u16 zero = 0; | ||
192 | u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK); | 191 | u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK); |
192 | struct spi_message m; | ||
193 | struct spi_transfer reg_trans; | ||
194 | struct spi_transfer dummy_trans; | ||
195 | struct spi_transfer data_trans; | ||
193 | 196 | ||
194 | /* You must take an even number of bytes from the SPU, even if you | 197 | /* You must take an even number of bytes from the SPU, even if you |
195 | * don't care about the last one. */ | 198 | * don't care about the last one. */ |
@@ -197,29 +200,34 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) | |||
197 | 200 | ||
198 | spu_transaction_init(card); | 201 | spu_transaction_init(card); |
199 | 202 | ||
203 | spi_message_init(&m); | ||
204 | memset(®_trans, 0, sizeof(reg_trans)); | ||
205 | memset(&dummy_trans, 0, sizeof(dummy_trans)); | ||
206 | memset(&data_trans, 0, sizeof(data_trans)); | ||
207 | |||
200 | /* write SPU register index */ | 208 | /* write SPU register index */ |
201 | err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); | 209 | reg_trans.tx_buf = ®_out; |
202 | if (err) | 210 | reg_trans.len = sizeof(reg_out); |
203 | goto out; | 211 | spi_message_add_tail(®_trans, &m); |
204 | 212 | ||
205 | delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay : | 213 | delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay : |
206 | card->spu_reg_delay; | 214 | card->spu_reg_delay; |
207 | if (card->use_dummy_writes) { | 215 | if (card->use_dummy_writes) { |
208 | /* Clock in dummy cycles while the SPU fills the FIFO */ | 216 | /* Clock in dummy cycles while the SPU fills the FIFO */ |
209 | for (i = 0; i < delay / 16; ++i) { | 217 | dummy_trans.len = delay / 8; |
210 | err = spi_write(card->spi, (u8 *)&zero, sizeof(u16)); | 218 | spi_message_add_tail(&dummy_trans, &m); |
211 | if (err) | ||
212 | return err; | ||
213 | } | ||
214 | } else { | 219 | } else { |
215 | /* Busy-wait while the SPU fills the FIFO */ | 220 | /* Busy-wait while the SPU fills the FIFO */ |
216 | ndelay(100 + (delay * 10)); | 221 | reg_trans.delay_usecs = |
222 | DIV_ROUND_UP((100 + (delay * 10)), 1000); | ||
217 | } | 223 | } |
218 | 224 | ||
219 | /* read in data */ | 225 | /* read in data */ |
220 | err = spi_read(card->spi, buf, len); | 226 | data_trans.rx_buf = buf; |
227 | data_trans.len = len; | ||
228 | spi_message_add_tail(&data_trans, &m); | ||
221 | 229 | ||
222 | out: | 230 | err = spi_sync(card->spi, &m); |
223 | spu_transaction_finish(card); | 231 | spu_transaction_finish(card); |
224 | return err; | 232 | return err; |
225 | } | 233 | } |
@@ -1049,7 +1057,6 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1049 | spi_set_drvdata(spi, card); | 1057 | spi_set_drvdata(spi, card); |
1050 | card->pdata = pdata; | 1058 | card->pdata = pdata; |
1051 | card->spi = spi; | 1059 | card->spi = spi; |
1052 | card->gpio_cs = pdata->gpio_cs; | ||
1053 | card->prev_xfer_time = jiffies; | 1060 | card->prev_xfer_time = jiffies; |
1054 | 1061 | ||
1055 | sema_init(&card->spi_ready, 0); | 1062 | sema_init(&card->spi_ready, 0); |
@@ -1058,26 +1065,18 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1058 | INIT_LIST_HEAD(&card->data_packet_list); | 1065 | INIT_LIST_HEAD(&card->data_packet_list); |
1059 | spin_lock_init(&card->buffer_lock); | 1066 | spin_lock_init(&card->buffer_lock); |
1060 | 1067 | ||
1061 | /* set up GPIO CS line. TODO: use regular CS line */ | ||
1062 | err = gpio_request(card->gpio_cs, "if_spi_gpio_chip_select"); | ||
1063 | if (err) | ||
1064 | goto free_card; | ||
1065 | err = gpio_direction_output(card->gpio_cs, 1); | ||
1066 | if (err) | ||
1067 | goto free_gpio; | ||
1068 | |||
1069 | /* Initialize the SPI Interface Unit */ | 1068 | /* Initialize the SPI Interface Unit */ |
1070 | err = spu_init(card, pdata->use_dummy_writes); | 1069 | err = spu_init(card, pdata->use_dummy_writes); |
1071 | if (err) | 1070 | if (err) |
1072 | goto free_gpio; | 1071 | goto free_card; |
1073 | err = spu_get_chip_revision(card, &card->card_id, &card->card_rev); | 1072 | err = spu_get_chip_revision(card, &card->card_id, &card->card_rev); |
1074 | if (err) | 1073 | if (err) |
1075 | goto free_gpio; | 1074 | goto free_card; |
1076 | 1075 | ||
1077 | /* Firmware load */ | 1076 | /* Firmware load */ |
1078 | err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); | 1077 | err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); |
1079 | if (err) | 1078 | if (err) |
1080 | goto free_gpio; | 1079 | goto free_card; |
1081 | if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) | 1080 | if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) |
1082 | lbs_deb_spi("Firmware is already loaded for " | 1081 | lbs_deb_spi("Firmware is already loaded for " |
1083 | "Marvell WLAN 802.11 adapter\n"); | 1082 | "Marvell WLAN 802.11 adapter\n"); |
@@ -1085,7 +1084,7 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1085 | err = if_spi_calculate_fw_names(card->card_id, | 1084 | err = if_spi_calculate_fw_names(card->card_id, |
1086 | card->helper_fw_name, card->main_fw_name); | 1085 | card->helper_fw_name, card->main_fw_name); |
1087 | if (err) | 1086 | if (err) |
1088 | goto free_gpio; | 1087 | goto free_card; |
1089 | 1088 | ||
1090 | lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " | 1089 | lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " |
1091 | "(chip_id = 0x%04x, chip_rev = 0x%02x) " | 1090 | "(chip_id = 0x%04x, chip_rev = 0x%02x) " |
@@ -1096,23 +1095,23 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1096 | spi->max_speed_hz); | 1095 | spi->max_speed_hz); |
1097 | err = if_spi_prog_helper_firmware(card); | 1096 | err = if_spi_prog_helper_firmware(card); |
1098 | if (err) | 1097 | if (err) |
1099 | goto free_gpio; | 1098 | goto free_card; |
1100 | err = if_spi_prog_main_firmware(card); | 1099 | err = if_spi_prog_main_firmware(card); |
1101 | if (err) | 1100 | if (err) |
1102 | goto free_gpio; | 1101 | goto free_card; |
1103 | lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); | 1102 | lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); |
1104 | } | 1103 | } |
1105 | 1104 | ||
1106 | err = spu_set_interrupt_mode(card, 0, 1); | 1105 | err = spu_set_interrupt_mode(card, 0, 1); |
1107 | if (err) | 1106 | if (err) |
1108 | goto free_gpio; | 1107 | goto free_card; |
1109 | 1108 | ||
1110 | /* Register our card with libertas. | 1109 | /* Register our card with libertas. |
1111 | * This will call alloc_etherdev */ | 1110 | * This will call alloc_etherdev */ |
1112 | priv = lbs_add_card(card, &spi->dev); | 1111 | priv = lbs_add_card(card, &spi->dev); |
1113 | if (!priv) { | 1112 | if (!priv) { |
1114 | err = -ENOMEM; | 1113 | err = -ENOMEM; |
1115 | goto free_gpio; | 1114 | goto free_card; |
1116 | } | 1115 | } |
1117 | card->priv = priv; | 1116 | card->priv = priv; |
1118 | priv->card = card; | 1117 | priv->card = card; |
@@ -1157,8 +1156,6 @@ terminate_thread: | |||
1157 | if_spi_terminate_spi_thread(card); | 1156 | if_spi_terminate_spi_thread(card); |
1158 | remove_card: | 1157 | remove_card: |
1159 | lbs_remove_card(priv); /* will call free_netdev */ | 1158 | lbs_remove_card(priv); /* will call free_netdev */ |
1160 | free_gpio: | ||
1161 | gpio_free(card->gpio_cs); | ||
1162 | free_card: | 1159 | free_card: |
1163 | free_if_spi_card(card); | 1160 | free_if_spi_card(card); |
1164 | out: | 1161 | out: |
@@ -1179,7 +1176,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) | |||
1179 | free_irq(spi->irq, card); | 1176 | free_irq(spi->irq, card); |
1180 | if_spi_terminate_spi_thread(card); | 1177 | if_spi_terminate_spi_thread(card); |
1181 | lbs_remove_card(priv); /* will call free_netdev */ | 1178 | lbs_remove_card(priv); /* will call free_netdev */ |
1182 | gpio_free(card->gpio_cs); | ||
1183 | if (card->pdata->teardown) | 1179 | if (card->pdata->teardown) |
1184 | card->pdata->teardown(spi); | 1180 | card->pdata->teardown(spi); |
1185 | free_if_spi_card(card); | 1181 | free_if_spi_card(card); |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index c254fdf446fd..7441d5585110 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -157,55 +157,55 @@ MODULE_PARM_DESC(workaround_interval, | |||
157 | #define NDIS_802_11_LENGTH_RATES_EX 16 | 157 | #define NDIS_802_11_LENGTH_RATES_EX 16 |
158 | 158 | ||
159 | enum ndis_80211_net_type { | 159 | enum ndis_80211_net_type { |
160 | ndis_80211_type_freq_hop, | 160 | NDIS_80211_TYPE_FREQ_HOP, |
161 | ndis_80211_type_direct_seq, | 161 | NDIS_80211_TYPE_DIRECT_SEQ, |
162 | ndis_80211_type_ofdm_a, | 162 | NDIS_80211_TYPE_OFDM_A, |
163 | ndis_80211_type_ofdm_g | 163 | NDIS_80211_TYPE_OFDM_G |
164 | }; | 164 | }; |
165 | 165 | ||
166 | enum ndis_80211_net_infra { | 166 | enum ndis_80211_net_infra { |
167 | ndis_80211_infra_adhoc, | 167 | NDIS_80211_INFRA_ADHOC, |
168 | ndis_80211_infra_infra, | 168 | NDIS_80211_INFRA_INFRA, |
169 | ndis_80211_infra_auto_unknown | 169 | NDIS_80211_INFRA_AUTO_UNKNOWN |
170 | }; | 170 | }; |
171 | 171 | ||
172 | enum ndis_80211_auth_mode { | 172 | enum ndis_80211_auth_mode { |
173 | ndis_80211_auth_open, | 173 | NDIS_80211_AUTH_OPEN, |
174 | ndis_80211_auth_shared, | 174 | NDIS_80211_AUTH_SHARED, |
175 | ndis_80211_auth_auto_switch, | 175 | NDIS_80211_AUTH_AUTO_SWITCH, |
176 | ndis_80211_auth_wpa, | 176 | NDIS_80211_AUTH_WPA, |
177 | ndis_80211_auth_wpa_psk, | 177 | NDIS_80211_AUTH_WPA_PSK, |
178 | ndis_80211_auth_wpa_none, | 178 | NDIS_80211_AUTH_WPA_NONE, |
179 | ndis_80211_auth_wpa2, | 179 | NDIS_80211_AUTH_WPA2, |
180 | ndis_80211_auth_wpa2_psk | 180 | NDIS_80211_AUTH_WPA2_PSK |
181 | }; | 181 | }; |
182 | 182 | ||
183 | enum ndis_80211_encr_status { | 183 | enum ndis_80211_encr_status { |
184 | ndis_80211_encr_wep_enabled, | 184 | NDIS_80211_ENCR_WEP_ENABLED, |
185 | ndis_80211_encr_disabled, | 185 | NDIS_80211_ENCR_DISABLED, |
186 | ndis_80211_encr_wep_key_absent, | 186 | NDIS_80211_ENCR_WEP_KEY_ABSENT, |
187 | ndis_80211_encr_not_supported, | 187 | NDIS_80211_ENCR_NOT_SUPPORTED, |
188 | ndis_80211_encr_tkip_enabled, | 188 | NDIS_80211_ENCR_TKIP_ENABLED, |
189 | ndis_80211_encr_tkip_key_absent, | 189 | NDIS_80211_ENCR_TKIP_KEY_ABSENT, |
190 | ndis_80211_encr_ccmp_enabled, | 190 | NDIS_80211_ENCR_CCMP_ENABLED, |
191 | ndis_80211_encr_ccmp_key_absent | 191 | NDIS_80211_ENCR_CCMP_KEY_ABSENT |
192 | }; | 192 | }; |
193 | 193 | ||
194 | enum ndis_80211_priv_filter { | 194 | enum ndis_80211_priv_filter { |
195 | ndis_80211_priv_accept_all, | 195 | NDIS_80211_PRIV_ACCEPT_ALL, |
196 | ndis_80211_priv_8021x_wep | 196 | NDIS_80211_PRIV_8021X_WEP |
197 | }; | 197 | }; |
198 | 198 | ||
199 | enum ndis_80211_addkey_bits { | 199 | enum ndis_80211_addkey_bits { |
200 | ndis_80211_addkey_8021x_auth = cpu_to_le32(1 << 28), | 200 | NDIS_80211_ADDKEY_8021X_AUTH = cpu_to_le32(1 << 28), |
201 | ndis_80211_addkey_set_init_recv_seq = cpu_to_le32(1 << 29), | 201 | NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ = cpu_to_le32(1 << 29), |
202 | ndis_80211_addkey_pairwise_key = cpu_to_le32(1 << 30), | 202 | NDIS_80211_ADDKEY_PAIRWISE_KEY = cpu_to_le32(1 << 30), |
203 | ndis_80211_addkey_transmit_key = cpu_to_le32(1 << 31), | 203 | NDIS_80211_ADDKEY_TRANSMIT_KEY = cpu_to_le32(1 << 31) |
204 | }; | 204 | }; |
205 | 205 | ||
206 | enum ndis_80211_addwep_bits { | 206 | enum ndis_80211_addwep_bits { |
207 | ndis_80211_addwep_perclient_key = cpu_to_le32(1 << 30), | 207 | NDIS_80211_ADDWEP_PERCLIENT_KEY = cpu_to_le32(1 << 30), |
208 | ndis_80211_addwep_transmit_key = cpu_to_le32(1 << 31), | 208 | NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31) |
209 | }; | 209 | }; |
210 | 210 | ||
211 | struct ndis_80211_ssid { | 211 | struct ndis_80211_ssid { |
@@ -361,7 +361,7 @@ static const struct ieee80211_rate rndis_rates[] = { | |||
361 | }; | 361 | }; |
362 | 362 | ||
363 | /* RNDIS device private data */ | 363 | /* RNDIS device private data */ |
364 | struct rndis_wext_private { | 364 | struct rndis_wlan_private { |
365 | struct usbnet *usbdev; | 365 | struct usbnet *usbdev; |
366 | 366 | ||
367 | struct wireless_dev wdev; | 367 | struct wireless_dev wdev; |
@@ -441,13 +441,13 @@ static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff, | |||
441 | 0xff, 0xff, 0xff }; | 441 | 0xff, 0xff, 0xff }; |
442 | 442 | ||
443 | 443 | ||
444 | static struct rndis_wext_private *get_rndis_wext_priv(struct usbnet *dev) | 444 | static struct rndis_wlan_private *get_rndis_wlan_priv(struct usbnet *dev) |
445 | { | 445 | { |
446 | return (struct rndis_wext_private *)dev->driver_priv; | 446 | return (struct rndis_wlan_private *)dev->driver_priv; |
447 | } | 447 | } |
448 | 448 | ||
449 | 449 | ||
450 | static u32 get_bcm4320_power(struct rndis_wext_private *priv) | 450 | static u32 get_bcm4320_power(struct rndis_wlan_private *priv) |
451 | { | 451 | { |
452 | return BCM4320_DEFAULT_TXPOWER * | 452 | return BCM4320_DEFAULT_TXPOWER * |
453 | bcm4320_power_output[priv->param_power_output] / 100; | 453 | bcm4320_power_output[priv->param_power_output] / 100; |
@@ -480,7 +480,7 @@ static int rndis_error_status(__le32 rndis_status) | |||
480 | 480 | ||
481 | static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | 481 | static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) |
482 | { | 482 | { |
483 | struct rndis_wext_private *priv = get_rndis_wext_priv(dev); | 483 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); |
484 | union { | 484 | union { |
485 | void *buf; | 485 | void *buf; |
486 | struct rndis_msg_hdr *header; | 486 | struct rndis_msg_hdr *header; |
@@ -526,7 +526,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | |||
526 | 526 | ||
527 | static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) | 527 | static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) |
528 | { | 528 | { |
529 | struct rndis_wext_private *priv = get_rndis_wext_priv(dev); | 529 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); |
530 | union { | 530 | union { |
531 | void *buf; | 531 | void *buf; |
532 | struct rndis_msg_hdr *header; | 532 | struct rndis_msg_hdr *header; |
@@ -747,7 +747,7 @@ static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) | |||
747 | 747 | ||
748 | static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) | 748 | static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) |
749 | { | 749 | { |
750 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 750 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
751 | int ret; | 751 | int ret; |
752 | 752 | ||
753 | ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid)); | 753 | ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid)); |
@@ -794,7 +794,7 @@ static int is_associated(struct usbnet *usbdev) | |||
794 | 794 | ||
795 | static int disassociate(struct usbnet *usbdev, int reset_ssid) | 795 | static int disassociate(struct usbnet *usbdev, int reset_ssid) |
796 | { | 796 | { |
797 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 797 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
798 | struct ndis_80211_ssid ssid; | 798 | struct ndis_80211_ssid ssid; |
799 | int i, ret = 0; | 799 | int i, ret = 0; |
800 | 800 | ||
@@ -826,7 +826,7 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid) | |||
826 | 826 | ||
827 | static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) | 827 | static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) |
828 | { | 828 | { |
829 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 829 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
830 | __le32 tmp; | 830 | __le32 tmp; |
831 | int auth_mode, ret; | 831 | int auth_mode, ret; |
832 | 832 | ||
@@ -835,23 +835,23 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) | |||
835 | 835 | ||
836 | if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) { | 836 | if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) { |
837 | if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) | 837 | if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) |
838 | auth_mode = ndis_80211_auth_wpa2; | 838 | auth_mode = NDIS_80211_AUTH_WPA2; |
839 | else | 839 | else |
840 | auth_mode = ndis_80211_auth_wpa2_psk; | 840 | auth_mode = NDIS_80211_AUTH_WPA2_PSK; |
841 | } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) { | 841 | } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) { |
842 | if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) | 842 | if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) |
843 | auth_mode = ndis_80211_auth_wpa; | 843 | auth_mode = NDIS_80211_AUTH_WPA; |
844 | else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK) | 844 | else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK) |
845 | auth_mode = ndis_80211_auth_wpa_psk; | 845 | auth_mode = NDIS_80211_AUTH_WPA_PSK; |
846 | else | 846 | else |
847 | auth_mode = ndis_80211_auth_wpa_none; | 847 | auth_mode = NDIS_80211_AUTH_WPA_NONE; |
848 | } else if (authalg & IW_AUTH_ALG_SHARED_KEY) { | 848 | } else if (authalg & IW_AUTH_ALG_SHARED_KEY) { |
849 | if (authalg & IW_AUTH_ALG_OPEN_SYSTEM) | 849 | if (authalg & IW_AUTH_ALG_OPEN_SYSTEM) |
850 | auth_mode = ndis_80211_auth_auto_switch; | 850 | auth_mode = NDIS_80211_AUTH_AUTO_SWITCH; |
851 | else | 851 | else |
852 | auth_mode = ndis_80211_auth_shared; | 852 | auth_mode = NDIS_80211_AUTH_SHARED; |
853 | } else | 853 | } else |
854 | auth_mode = ndis_80211_auth_open; | 854 | auth_mode = NDIS_80211_AUTH_OPEN; |
855 | 855 | ||
856 | tmp = cpu_to_le32(auth_mode); | 856 | tmp = cpu_to_le32(auth_mode); |
857 | ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp, | 857 | ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp, |
@@ -869,16 +869,16 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) | |||
869 | 869 | ||
870 | static int set_priv_filter(struct usbnet *usbdev) | 870 | static int set_priv_filter(struct usbnet *usbdev) |
871 | { | 871 | { |
872 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 872 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
873 | __le32 tmp; | 873 | __le32 tmp; |
874 | 874 | ||
875 | devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version); | 875 | devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version); |
876 | 876 | ||
877 | if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 || | 877 | if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 || |
878 | priv->wpa_version & IW_AUTH_WPA_VERSION_WPA) | 878 | priv->wpa_version & IW_AUTH_WPA_VERSION_WPA) |
879 | tmp = cpu_to_le32(ndis_80211_priv_8021x_wep); | 879 | tmp = cpu_to_le32(NDIS_80211_PRIV_8021X_WEP); |
880 | else | 880 | else |
881 | tmp = cpu_to_le32(ndis_80211_priv_accept_all); | 881 | tmp = cpu_to_le32(NDIS_80211_PRIV_ACCEPT_ALL); |
882 | 882 | ||
883 | return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp, | 883 | return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp, |
884 | sizeof(tmp)); | 884 | sizeof(tmp)); |
@@ -887,7 +887,7 @@ static int set_priv_filter(struct usbnet *usbdev) | |||
887 | 887 | ||
888 | static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) | 888 | static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) |
889 | { | 889 | { |
890 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 890 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
891 | __le32 tmp; | 891 | __le32 tmp; |
892 | int encr_mode, ret; | 892 | int encr_mode, ret; |
893 | 893 | ||
@@ -896,18 +896,18 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) | |||
896 | groupwise); | 896 | groupwise); |
897 | 897 | ||
898 | if (pairwise & IW_AUTH_CIPHER_CCMP) | 898 | if (pairwise & IW_AUTH_CIPHER_CCMP) |
899 | encr_mode = ndis_80211_encr_ccmp_enabled; | 899 | encr_mode = NDIS_80211_ENCR_CCMP_ENABLED; |
900 | else if (pairwise & IW_AUTH_CIPHER_TKIP) | 900 | else if (pairwise & IW_AUTH_CIPHER_TKIP) |
901 | encr_mode = ndis_80211_encr_tkip_enabled; | 901 | encr_mode = NDIS_80211_ENCR_TKIP_ENABLED; |
902 | else if (pairwise & | 902 | else if (pairwise & |
903 | (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) | 903 | (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) |
904 | encr_mode = ndis_80211_encr_wep_enabled; | 904 | encr_mode = NDIS_80211_ENCR_WEP_ENABLED; |
905 | else if (groupwise & IW_AUTH_CIPHER_CCMP) | 905 | else if (groupwise & IW_AUTH_CIPHER_CCMP) |
906 | encr_mode = ndis_80211_encr_ccmp_enabled; | 906 | encr_mode = NDIS_80211_ENCR_CCMP_ENABLED; |
907 | else if (groupwise & IW_AUTH_CIPHER_TKIP) | 907 | else if (groupwise & IW_AUTH_CIPHER_TKIP) |
908 | encr_mode = ndis_80211_encr_tkip_enabled; | 908 | encr_mode = NDIS_80211_ENCR_TKIP_ENABLED; |
909 | else | 909 | else |
910 | encr_mode = ndis_80211_encr_disabled; | 910 | encr_mode = NDIS_80211_ENCR_DISABLED; |
911 | 911 | ||
912 | tmp = cpu_to_le32(encr_mode); | 912 | tmp = cpu_to_le32(encr_mode); |
913 | ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp, | 913 | ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp, |
@@ -925,7 +925,7 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) | |||
925 | 925 | ||
926 | static int set_assoc_params(struct usbnet *usbdev) | 926 | static int set_assoc_params(struct usbnet *usbdev) |
927 | { | 927 | { |
928 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 928 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
929 | 929 | ||
930 | set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg); | 930 | set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg); |
931 | set_priv_filter(usbdev); | 931 | set_priv_filter(usbdev); |
@@ -937,7 +937,7 @@ static int set_assoc_params(struct usbnet *usbdev) | |||
937 | 937 | ||
938 | static int set_infra_mode(struct usbnet *usbdev, int mode) | 938 | static int set_infra_mode(struct usbnet *usbdev, int mode) |
939 | { | 939 | { |
940 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 940 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
941 | __le32 tmp; | 941 | __le32 tmp; |
942 | int ret, i; | 942 | int ret, i; |
943 | 943 | ||
@@ -970,12 +970,12 @@ static int set_infra_mode(struct usbnet *usbdev, int mode) | |||
970 | 970 | ||
971 | static void set_default_iw_params(struct usbnet *usbdev) | 971 | static void set_default_iw_params(struct usbnet *usbdev) |
972 | { | 972 | { |
973 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 973 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
974 | 974 | ||
975 | priv->wpa_keymgmt = 0; | 975 | priv->wpa_keymgmt = 0; |
976 | priv->wpa_version = 0; | 976 | priv->wpa_version = 0; |
977 | 977 | ||
978 | set_infra_mode(usbdev, ndis_80211_infra_infra); | 978 | set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA); |
979 | set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED, | 979 | set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED, |
980 | IW_AUTH_ALG_OPEN_SYSTEM); | 980 | IW_AUTH_ALG_OPEN_SYSTEM); |
981 | set_priv_filter(usbdev); | 981 | set_priv_filter(usbdev); |
@@ -996,7 +996,7 @@ static int deauthenticate(struct usbnet *usbdev) | |||
996 | /* index must be 0 - N, as per NDIS */ | 996 | /* index must be 0 - N, as per NDIS */ |
997 | static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) | 997 | static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) |
998 | { | 998 | { |
999 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 999 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1000 | struct ndis_80211_wep_key ndis_key; | 1000 | struct ndis_80211_wep_key ndis_key; |
1001 | int ret; | 1001 | int ret; |
1002 | 1002 | ||
@@ -1011,7 +1011,7 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) | |||
1011 | memcpy(&ndis_key.material, key, key_len); | 1011 | memcpy(&ndis_key.material, key, key_len); |
1012 | 1012 | ||
1013 | if (index == priv->encr_tx_key_index) { | 1013 | if (index == priv->encr_tx_key_index) { |
1014 | ndis_key.index |= ndis_80211_addwep_transmit_key; | 1014 | ndis_key.index |= NDIS_80211_ADDWEP_TRANSMIT_KEY; |
1015 | ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104, | 1015 | ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104, |
1016 | IW_AUTH_CIPHER_NONE); | 1016 | IW_AUTH_CIPHER_NONE); |
1017 | if (ret) | 1017 | if (ret) |
@@ -1039,7 +1039,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1039 | int index, const struct sockaddr *addr, | 1039 | int index, const struct sockaddr *addr, |
1040 | const u8 *rx_seq, int alg, int flags) | 1040 | const u8 *rx_seq, int alg, int flags) |
1041 | { | 1041 | { |
1042 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1042 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1043 | struct ndis_80211_key ndis_key; | 1043 | struct ndis_80211_key ndis_key; |
1044 | int ret; | 1044 | int ret; |
1045 | 1045 | ||
@@ -1047,15 +1047,15 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1047 | return -EINVAL; | 1047 | return -EINVAL; |
1048 | if (key_len > sizeof(ndis_key.material) || key_len < 0) | 1048 | if (key_len > sizeof(ndis_key.material) || key_len < 0) |
1049 | return -EINVAL; | 1049 | return -EINVAL; |
1050 | if ((flags & ndis_80211_addkey_set_init_recv_seq) && !rx_seq) | 1050 | if ((flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) && !rx_seq) |
1051 | return -EINVAL; | 1051 | return -EINVAL; |
1052 | if ((flags & ndis_80211_addkey_pairwise_key) && !addr) | 1052 | if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !addr) |
1053 | return -EINVAL; | 1053 | return -EINVAL; |
1054 | 1054 | ||
1055 | devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index, | 1055 | devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index, |
1056 | !!(flags & ndis_80211_addkey_transmit_key), | 1056 | !!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY), |
1057 | !!(flags & ndis_80211_addkey_pairwise_key), | 1057 | !!(flags & NDIS_80211_ADDKEY_PAIRWISE_KEY), |
1058 | !!(flags & ndis_80211_addkey_set_init_recv_seq)); | 1058 | !!(flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ)); |
1059 | 1059 | ||
1060 | memset(&ndis_key, 0, sizeof(ndis_key)); | 1060 | memset(&ndis_key, 0, sizeof(ndis_key)); |
1061 | 1061 | ||
@@ -1073,15 +1073,15 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1073 | } else | 1073 | } else |
1074 | memcpy(ndis_key.material, key, key_len); | 1074 | memcpy(ndis_key.material, key, key_len); |
1075 | 1075 | ||
1076 | if (flags & ndis_80211_addkey_set_init_recv_seq) | 1076 | if (flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) |
1077 | memcpy(ndis_key.rsc, rx_seq, 6); | 1077 | memcpy(ndis_key.rsc, rx_seq, 6); |
1078 | 1078 | ||
1079 | if (flags & ndis_80211_addkey_pairwise_key) { | 1079 | if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) { |
1080 | /* pairwise key */ | 1080 | /* pairwise key */ |
1081 | memcpy(ndis_key.bssid, addr->sa_data, ETH_ALEN); | 1081 | memcpy(ndis_key.bssid, addr->sa_data, ETH_ALEN); |
1082 | } else { | 1082 | } else { |
1083 | /* group key */ | 1083 | /* group key */ |
1084 | if (priv->infra_mode == ndis_80211_infra_adhoc) | 1084 | if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) |
1085 | memset(ndis_key.bssid, 0xff, ETH_ALEN); | 1085 | memset(ndis_key.bssid, 0xff, ETH_ALEN); |
1086 | else | 1086 | else |
1087 | get_bssid(usbdev, ndis_key.bssid); | 1087 | get_bssid(usbdev, ndis_key.bssid); |
@@ -1096,7 +1096,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1096 | priv->encr_key_len[index] = key_len; | 1096 | priv->encr_key_len[index] = key_len; |
1097 | priv->encr_key_wpa[index] = 1; | 1097 | priv->encr_key_wpa[index] = 1; |
1098 | 1098 | ||
1099 | if (flags & ndis_80211_addkey_transmit_key) | 1099 | if (flags & NDIS_80211_ADDKEY_TRANSMIT_KEY) |
1100 | priv->encr_tx_key_index = index; | 1100 | priv->encr_tx_key_index = index; |
1101 | 1101 | ||
1102 | return 0; | 1102 | return 0; |
@@ -1106,7 +1106,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1106 | /* remove_key is for both wep and wpa */ | 1106 | /* remove_key is for both wep and wpa */ |
1107 | static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) | 1107 | static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) |
1108 | { | 1108 | { |
1109 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1109 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1110 | struct ndis_80211_remove_key remove_key; | 1110 | struct ndis_80211_remove_key remove_key; |
1111 | __le32 keyindex; | 1111 | __le32 keyindex; |
1112 | int ret; | 1112 | int ret; |
@@ -1128,7 +1128,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) | |||
1128 | /* pairwise key */ | 1128 | /* pairwise key */ |
1129 | if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0) | 1129 | if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0) |
1130 | remove_key.index |= | 1130 | remove_key.index |= |
1131 | ndis_80211_addkey_pairwise_key; | 1131 | NDIS_80211_ADDKEY_PAIRWISE_KEY; |
1132 | memcpy(remove_key.bssid, bssid, | 1132 | memcpy(remove_key.bssid, bssid, |
1133 | sizeof(remove_key.bssid)); | 1133 | sizeof(remove_key.bssid)); |
1134 | } else | 1134 | } else |
@@ -1161,7 +1161,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) | |||
1161 | 1161 | ||
1162 | static void set_multicast_list(struct usbnet *usbdev) | 1162 | static void set_multicast_list(struct usbnet *usbdev) |
1163 | { | 1163 | { |
1164 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1164 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1165 | struct dev_mc_list *mclist; | 1165 | struct dev_mc_list *mclist; |
1166 | __le32 filter; | 1166 | __le32 filter; |
1167 | int ret, i, size; | 1167 | int ret, i, size; |
@@ -1238,10 +1238,10 @@ static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex, | |||
1238 | 1238 | ||
1239 | switch (type) { | 1239 | switch (type) { |
1240 | case NL80211_IFTYPE_ADHOC: | 1240 | case NL80211_IFTYPE_ADHOC: |
1241 | mode = ndis_80211_infra_adhoc; | 1241 | mode = NDIS_80211_INFRA_ADHOC; |
1242 | break; | 1242 | break; |
1243 | case NL80211_IFTYPE_STATION: | 1243 | case NL80211_IFTYPE_STATION: |
1244 | mode = ndis_80211_infra_infra; | 1244 | mode = NDIS_80211_INFRA_INFRA; |
1245 | break; | 1245 | break; |
1246 | default: | 1246 | default: |
1247 | return -EINVAL; | 1247 | return -EINVAL; |
@@ -1256,7 +1256,7 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, | |||
1256 | struct cfg80211_scan_request *request) | 1256 | struct cfg80211_scan_request *request) |
1257 | { | 1257 | { |
1258 | struct usbnet *usbdev = netdev_priv(dev); | 1258 | struct usbnet *usbdev = netdev_priv(dev); |
1259 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1259 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1260 | int ret; | 1260 | int ret; |
1261 | __le32 tmp; | 1261 | __le32 tmp; |
1262 | 1262 | ||
@@ -1286,7 +1286,7 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, | |||
1286 | static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, | 1286 | static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, |
1287 | struct ndis_80211_bssid_ex *bssid) | 1287 | struct ndis_80211_bssid_ex *bssid) |
1288 | { | 1288 | { |
1289 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1289 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1290 | struct ieee80211_channel *channel; | 1290 | struct ieee80211_channel *channel; |
1291 | s32 signal; | 1291 | s32 signal; |
1292 | u64 timestamp; | 1292 | u64 timestamp; |
@@ -1371,8 +1371,8 @@ out: | |||
1371 | 1371 | ||
1372 | static void rndis_get_scan_results(struct work_struct *work) | 1372 | static void rndis_get_scan_results(struct work_struct *work) |
1373 | { | 1373 | { |
1374 | struct rndis_wext_private *priv = | 1374 | struct rndis_wlan_private *priv = |
1375 | container_of(work, struct rndis_wext_private, scan_work.work); | 1375 | container_of(work, struct rndis_wlan_private, scan_work.work); |
1376 | struct usbnet *usbdev = priv->usbdev; | 1376 | struct usbnet *usbdev = priv->usbdev; |
1377 | int ret; | 1377 | int ret; |
1378 | 1378 | ||
@@ -1497,7 +1497,7 @@ static int rndis_iw_set_auth(struct net_device *dev, | |||
1497 | { | 1497 | { |
1498 | struct iw_param *p = &wrqu->param; | 1498 | struct iw_param *p = &wrqu->param; |
1499 | struct usbnet *usbdev = netdev_priv(dev); | 1499 | struct usbnet *usbdev = netdev_priv(dev); |
1500 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1500 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1501 | int ret = -ENOTSUPP; | 1501 | int ret = -ENOTSUPP; |
1502 | 1502 | ||
1503 | switch (p->flags & IW_AUTH_INDEX) { | 1503 | switch (p->flags & IW_AUTH_INDEX) { |
@@ -1578,7 +1578,7 @@ static int rndis_iw_get_auth(struct net_device *dev, | |||
1578 | { | 1578 | { |
1579 | struct iw_param *p = &wrqu->param; | 1579 | struct iw_param *p = &wrqu->param; |
1580 | struct usbnet *usbdev = netdev_priv(dev); | 1580 | struct usbnet *usbdev = netdev_priv(dev); |
1581 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1581 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1582 | 1582 | ||
1583 | switch (p->flags & IW_AUTH_INDEX) { | 1583 | switch (p->flags & IW_AUTH_INDEX) { |
1584 | case IW_AUTH_WPA_VERSION: | 1584 | case IW_AUTH_WPA_VERSION: |
@@ -1609,7 +1609,7 @@ static int rndis_iw_set_encode(struct net_device *dev, | |||
1609 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) | 1609 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) |
1610 | { | 1610 | { |
1611 | struct usbnet *usbdev = netdev_priv(dev); | 1611 | struct usbnet *usbdev = netdev_priv(dev); |
1612 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1612 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1613 | int ret, index, key_len; | 1613 | int ret, index, key_len; |
1614 | u8 *key; | 1614 | u8 *key; |
1615 | 1615 | ||
@@ -1672,7 +1672,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, | |||
1672 | { | 1672 | { |
1673 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | 1673 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; |
1674 | struct usbnet *usbdev = netdev_priv(dev); | 1674 | struct usbnet *usbdev = netdev_priv(dev); |
1675 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1675 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1676 | int keyidx, flags; | 1676 | int keyidx, flags; |
1677 | 1677 | ||
1678 | keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; | 1678 | keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; |
@@ -1698,11 +1698,11 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, | |||
1698 | 1698 | ||
1699 | flags = 0; | 1699 | flags = 0; |
1700 | if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) | 1700 | if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) |
1701 | flags |= ndis_80211_addkey_set_init_recv_seq; | 1701 | flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ; |
1702 | if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)) | 1702 | if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)) |
1703 | flags |= ndis_80211_addkey_pairwise_key; | 1703 | flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY; |
1704 | if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) | 1704 | if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) |
1705 | flags |= ndis_80211_addkey_transmit_key; | 1705 | flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY; |
1706 | 1706 | ||
1707 | return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, &ext->addr, | 1707 | return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, &ext->addr, |
1708 | ext->rx_seq, ext->alg, flags); | 1708 | ext->rx_seq, ext->alg, flags); |
@@ -1713,7 +1713,7 @@ static int rndis_iw_set_genie(struct net_device *dev, | |||
1713 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) | 1713 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) |
1714 | { | 1714 | { |
1715 | struct usbnet *usbdev = netdev_priv(dev); | 1715 | struct usbnet *usbdev = netdev_priv(dev); |
1716 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1716 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1717 | int ret = 0; | 1717 | int ret = 0; |
1718 | 1718 | ||
1719 | #ifdef DEBUG | 1719 | #ifdef DEBUG |
@@ -1747,7 +1747,7 @@ static int rndis_iw_get_genie(struct net_device *dev, | |||
1747 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) | 1747 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) |
1748 | { | 1748 | { |
1749 | struct usbnet *usbdev = netdev_priv(dev); | 1749 | struct usbnet *usbdev = netdev_priv(dev); |
1750 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1750 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1751 | 1751 | ||
1752 | devdbg(usbdev, "SIOCGIWGENIE"); | 1752 | devdbg(usbdev, "SIOCGIWGENIE"); |
1753 | 1753 | ||
@@ -1886,7 +1886,7 @@ static int rndis_iw_get_txpower(struct net_device *dev, | |||
1886 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) | 1886 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) |
1887 | { | 1887 | { |
1888 | struct usbnet *usbdev = netdev_priv(dev); | 1888 | struct usbnet *usbdev = netdev_priv(dev); |
1889 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1889 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1890 | __le32 tx_power; | 1890 | __le32 tx_power; |
1891 | 1891 | ||
1892 | if (priv->radio_on) { | 1892 | if (priv->radio_on) { |
@@ -1912,7 +1912,7 @@ static int rndis_iw_set_txpower(struct net_device *dev, | |||
1912 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) | 1912 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) |
1913 | { | 1913 | { |
1914 | struct usbnet *usbdev = netdev_priv(dev); | 1914 | struct usbnet *usbdev = netdev_priv(dev); |
1915 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1915 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1916 | __le32 tx_power = 0; | 1916 | __le32 tx_power = 0; |
1917 | 1917 | ||
1918 | if (!wrqu->txpower.disabled) { | 1918 | if (!wrqu->txpower.disabled) { |
@@ -1969,7 +1969,7 @@ static int rndis_iw_set_mlme(struct net_device *dev, | |||
1969 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) | 1969 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) |
1970 | { | 1970 | { |
1971 | struct usbnet *usbdev = netdev_priv(dev); | 1971 | struct usbnet *usbdev = netdev_priv(dev); |
1972 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1972 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1973 | struct iw_mlme *mlme = (struct iw_mlme *)extra; | 1973 | struct iw_mlme *mlme = (struct iw_mlme *)extra; |
1974 | unsigned char bssid[ETH_ALEN]; | 1974 | unsigned char bssid[ETH_ALEN]; |
1975 | 1975 | ||
@@ -1994,7 +1994,7 @@ static int rndis_iw_set_mlme(struct net_device *dev, | |||
1994 | static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev) | 1994 | static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev) |
1995 | { | 1995 | { |
1996 | struct usbnet *usbdev = netdev_priv(dev); | 1996 | struct usbnet *usbdev = netdev_priv(dev); |
1997 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1997 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1998 | unsigned long flags; | 1998 | unsigned long flags; |
1999 | 1999 | ||
2000 | spin_lock_irqsave(&priv->stats_lock, flags); | 2000 | spin_lock_irqsave(&priv->stats_lock, flags); |
@@ -2037,28 +2037,28 @@ static const iw_handler rndis_iw_handler[] = | |||
2037 | IW_IOCTL(SIOCSIWMLME) = rndis_iw_set_mlme, | 2037 | IW_IOCTL(SIOCSIWMLME) = rndis_iw_set_mlme, |
2038 | }; | 2038 | }; |
2039 | 2039 | ||
2040 | static const iw_handler rndis_wext_private_handler[] = { | 2040 | static const iw_handler rndis_wlan_private_handler[] = { |
2041 | }; | 2041 | }; |
2042 | 2042 | ||
2043 | static const struct iw_priv_args rndis_wext_private_args[] = { | 2043 | static const struct iw_priv_args rndis_wlan_private_args[] = { |
2044 | }; | 2044 | }; |
2045 | 2045 | ||
2046 | 2046 | ||
2047 | static const struct iw_handler_def rndis_iw_handlers = { | 2047 | static const struct iw_handler_def rndis_iw_handlers = { |
2048 | .num_standard = ARRAY_SIZE(rndis_iw_handler), | 2048 | .num_standard = ARRAY_SIZE(rndis_iw_handler), |
2049 | .num_private = ARRAY_SIZE(rndis_wext_private_handler), | 2049 | .num_private = ARRAY_SIZE(rndis_wlan_private_handler), |
2050 | .num_private_args = ARRAY_SIZE(rndis_wext_private_args), | 2050 | .num_private_args = ARRAY_SIZE(rndis_wlan_private_args), |
2051 | .standard = (iw_handler *)rndis_iw_handler, | 2051 | .standard = (iw_handler *)rndis_iw_handler, |
2052 | .private = (iw_handler *)rndis_wext_private_handler, | 2052 | .private = (iw_handler *)rndis_wlan_private_handler, |
2053 | .private_args = (struct iw_priv_args *)rndis_wext_private_args, | 2053 | .private_args = (struct iw_priv_args *)rndis_wlan_private_args, |
2054 | .get_wireless_stats = rndis_get_wireless_stats, | 2054 | .get_wireless_stats = rndis_get_wireless_stats, |
2055 | }; | 2055 | }; |
2056 | 2056 | ||
2057 | 2057 | ||
2058 | static void rndis_wext_worker(struct work_struct *work) | 2058 | static void rndis_wlan_worker(struct work_struct *work) |
2059 | { | 2059 | { |
2060 | struct rndis_wext_private *priv = | 2060 | struct rndis_wlan_private *priv = |
2061 | container_of(work, struct rndis_wext_private, work); | 2061 | container_of(work, struct rndis_wlan_private, work); |
2062 | struct usbnet *usbdev = priv->usbdev; | 2062 | struct usbnet *usbdev = priv->usbdev; |
2063 | union iwreq_data evt; | 2063 | union iwreq_data evt; |
2064 | unsigned char bssid[ETH_ALEN]; | 2064 | unsigned char bssid[ETH_ALEN]; |
@@ -2119,10 +2119,10 @@ get_bssid: | |||
2119 | set_multicast_list(usbdev); | 2119 | set_multicast_list(usbdev); |
2120 | } | 2120 | } |
2121 | 2121 | ||
2122 | static void rndis_wext_set_multicast_list(struct net_device *dev) | 2122 | static void rndis_wlan_set_multicast_list(struct net_device *dev) |
2123 | { | 2123 | { |
2124 | struct usbnet *usbdev = netdev_priv(dev); | 2124 | struct usbnet *usbdev = netdev_priv(dev); |
2125 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 2125 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
2126 | 2126 | ||
2127 | if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) | 2127 | if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) |
2128 | return; | 2128 | return; |
@@ -2131,9 +2131,9 @@ static void rndis_wext_set_multicast_list(struct net_device *dev) | |||
2131 | queue_work(priv->workqueue, &priv->work); | 2131 | queue_work(priv->workqueue, &priv->work); |
2132 | } | 2132 | } |
2133 | 2133 | ||
2134 | static void rndis_wext_link_change(struct usbnet *usbdev, int state) | 2134 | static void rndis_wlan_link_change(struct usbnet *usbdev, int state) |
2135 | { | 2135 | { |
2136 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 2136 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
2137 | 2137 | ||
2138 | /* queue work to avoid recursive calls into rndis_command */ | 2138 | /* queue work to avoid recursive calls into rndis_command */ |
2139 | set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending); | 2139 | set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending); |
@@ -2141,14 +2141,14 @@ static void rndis_wext_link_change(struct usbnet *usbdev, int state) | |||
2141 | } | 2141 | } |
2142 | 2142 | ||
2143 | 2143 | ||
2144 | static int rndis_wext_get_caps(struct usbnet *usbdev) | 2144 | static int rndis_wlan_get_caps(struct usbnet *usbdev) |
2145 | { | 2145 | { |
2146 | struct { | 2146 | struct { |
2147 | __le32 num_items; | 2147 | __le32 num_items; |
2148 | __le32 items[8]; | 2148 | __le32 items[8]; |
2149 | } networks_supported; | 2149 | } networks_supported; |
2150 | int len, retval, i, n; | 2150 | int len, retval, i, n; |
2151 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 2151 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
2152 | 2152 | ||
2153 | /* determine supported modes */ | 2153 | /* determine supported modes */ |
2154 | len = sizeof(networks_supported); | 2154 | len = sizeof(networks_supported); |
@@ -2160,14 +2160,14 @@ static int rndis_wext_get_caps(struct usbnet *usbdev) | |||
2160 | n = 8; | 2160 | n = 8; |
2161 | for (i = 0; i < n; i++) { | 2161 | for (i = 0; i < n; i++) { |
2162 | switch (le32_to_cpu(networks_supported.items[i])) { | 2162 | switch (le32_to_cpu(networks_supported.items[i])) { |
2163 | case ndis_80211_type_freq_hop: | 2163 | case NDIS_80211_TYPE_FREQ_HOP: |
2164 | case ndis_80211_type_direct_seq: | 2164 | case NDIS_80211_TYPE_DIRECT_SEQ: |
2165 | priv->caps |= CAP_MODE_80211B; | 2165 | priv->caps |= CAP_MODE_80211B; |
2166 | break; | 2166 | break; |
2167 | case ndis_80211_type_ofdm_a: | 2167 | case NDIS_80211_TYPE_OFDM_A: |
2168 | priv->caps |= CAP_MODE_80211A; | 2168 | priv->caps |= CAP_MODE_80211A; |
2169 | break; | 2169 | break; |
2170 | case ndis_80211_type_ofdm_g: | 2170 | case NDIS_80211_TYPE_OFDM_G: |
2171 | priv->caps |= CAP_MODE_80211G; | 2171 | priv->caps |= CAP_MODE_80211G; |
2172 | break; | 2172 | break; |
2173 | } | 2173 | } |
@@ -2181,8 +2181,8 @@ static int rndis_wext_get_caps(struct usbnet *usbdev) | |||
2181 | #define STATS_UPDATE_JIFFIES (HZ) | 2181 | #define STATS_UPDATE_JIFFIES (HZ) |
2182 | static void rndis_update_wireless_stats(struct work_struct *work) | 2182 | static void rndis_update_wireless_stats(struct work_struct *work) |
2183 | { | 2183 | { |
2184 | struct rndis_wext_private *priv = | 2184 | struct rndis_wlan_private *priv = |
2185 | container_of(work, struct rndis_wext_private, stats_work.work); | 2185 | container_of(work, struct rndis_wlan_private, stats_work.work); |
2186 | struct usbnet *usbdev = priv->usbdev; | 2186 | struct usbnet *usbdev = priv->usbdev; |
2187 | struct iw_statistics iwstats; | 2187 | struct iw_statistics iwstats; |
2188 | __le32 rssi, tmp; | 2188 | __le32 rssi, tmp; |
@@ -2297,7 +2297,7 @@ static int bcm4320a_early_init(struct usbnet *usbdev) | |||
2297 | 2297 | ||
2298 | static int bcm4320b_early_init(struct usbnet *usbdev) | 2298 | static int bcm4320b_early_init(struct usbnet *usbdev) |
2299 | { | 2299 | { |
2300 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 2300 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
2301 | char buf[8]; | 2301 | char buf[8]; |
2302 | 2302 | ||
2303 | /* Early initialization settings, setting these won't have effect | 2303 | /* Early initialization settings, setting these won't have effect |
@@ -2363,21 +2363,21 @@ static int bcm4320b_early_init(struct usbnet *usbdev) | |||
2363 | } | 2363 | } |
2364 | 2364 | ||
2365 | /* same as rndis_netdev_ops but with local multicast handler */ | 2365 | /* same as rndis_netdev_ops but with local multicast handler */ |
2366 | static const struct net_device_ops rndis_wext_netdev_ops = { | 2366 | static const struct net_device_ops rndis_wlan_netdev_ops = { |
2367 | .ndo_open = usbnet_open, | 2367 | .ndo_open = usbnet_open, |
2368 | .ndo_stop = usbnet_stop, | 2368 | .ndo_stop = usbnet_stop, |
2369 | .ndo_start_xmit = usbnet_start_xmit, | 2369 | .ndo_start_xmit = usbnet_start_xmit, |
2370 | .ndo_tx_timeout = usbnet_tx_timeout, | 2370 | .ndo_tx_timeout = usbnet_tx_timeout, |
2371 | .ndo_set_mac_address = eth_mac_addr, | 2371 | .ndo_set_mac_address = eth_mac_addr, |
2372 | .ndo_validate_addr = eth_validate_addr, | 2372 | .ndo_validate_addr = eth_validate_addr, |
2373 | .ndo_set_multicast_list = rndis_wext_set_multicast_list, | 2373 | .ndo_set_multicast_list = rndis_wlan_set_multicast_list, |
2374 | }; | 2374 | }; |
2375 | 2375 | ||
2376 | 2376 | ||
2377 | static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | 2377 | static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) |
2378 | { | 2378 | { |
2379 | struct wiphy *wiphy; | 2379 | struct wiphy *wiphy; |
2380 | struct rndis_wext_private *priv; | 2380 | struct rndis_wlan_private *priv; |
2381 | int retval, len; | 2381 | int retval, len; |
2382 | __le32 tmp; | 2382 | __le32 tmp; |
2383 | 2383 | ||
@@ -2385,7 +2385,7 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2385 | * NOTE: We only support a single virtual interface, so wiphy | 2385 | * NOTE: We only support a single virtual interface, so wiphy |
2386 | * and wireless_dev are somewhat synonymous for this device. | 2386 | * and wireless_dev are somewhat synonymous for this device. |
2387 | */ | 2387 | */ |
2388 | wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wext_private)); | 2388 | wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wlan_private)); |
2389 | if (!wiphy) | 2389 | if (!wiphy) |
2390 | return -ENOMEM; | 2390 | return -ENOMEM; |
2391 | 2391 | ||
@@ -2395,7 +2395,7 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2395 | priv->wdev.iftype = NL80211_IFTYPE_STATION; | 2395 | priv->wdev.iftype = NL80211_IFTYPE_STATION; |
2396 | 2396 | ||
2397 | /* These have to be initialized before calling generic_rndis_bind(). | 2397 | /* These have to be initialized before calling generic_rndis_bind(). |
2398 | * Otherwise we'll be in big trouble in rndis_wext_early_init(). | 2398 | * Otherwise we'll be in big trouble in rndis_wlan_early_init(). |
2399 | */ | 2399 | */ |
2400 | usbdev->driver_priv = priv; | 2400 | usbdev->driver_priv = priv; |
2401 | usbdev->net->wireless_handlers = &rndis_iw_handlers; | 2401 | usbdev->net->wireless_handlers = &rndis_iw_handlers; |
@@ -2406,7 +2406,7 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2406 | 2406 | ||
2407 | /* because rndis_command() sleeps we need to use workqueue */ | 2407 | /* because rndis_command() sleeps we need to use workqueue */ |
2408 | priv->workqueue = create_singlethread_workqueue("rndis_wlan"); | 2408 | priv->workqueue = create_singlethread_workqueue("rndis_wlan"); |
2409 | INIT_WORK(&priv->work, rndis_wext_worker); | 2409 | INIT_WORK(&priv->work, rndis_wlan_worker); |
2410 | INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats); | 2410 | INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats); |
2411 | INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results); | 2411 | INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results); |
2412 | 2412 | ||
@@ -2420,9 +2420,9 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2420 | * picks up rssi to closest station instead of to access point). | 2420 | * picks up rssi to closest station instead of to access point). |
2421 | * | 2421 | * |
2422 | * rndis_host wants to avoid all OID as much as possible | 2422 | * rndis_host wants to avoid all OID as much as possible |
2423 | * so do promisc/multicast handling in rndis_wext. | 2423 | * so do promisc/multicast handling in rndis_wlan. |
2424 | */ | 2424 | */ |
2425 | usbdev->net->netdev_ops = &rndis_wext_netdev_ops; | 2425 | usbdev->net->netdev_ops = &rndis_wlan_netdev_ops; |
2426 | 2426 | ||
2427 | tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; | 2427 | tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; |
2428 | retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, | 2428 | retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, |
@@ -2455,7 +2455,7 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2455 | wiphy->max_scan_ssids = 1; | 2455 | wiphy->max_scan_ssids = 1; |
2456 | 2456 | ||
2457 | /* TODO: fill-out band information based on priv->caps */ | 2457 | /* TODO: fill-out band information based on priv->caps */ |
2458 | rndis_wext_get_caps(usbdev); | 2458 | rndis_wlan_get_caps(usbdev); |
2459 | 2459 | ||
2460 | memcpy(priv->channels, rndis_channels, sizeof(rndis_channels)); | 2460 | memcpy(priv->channels, rndis_channels, sizeof(rndis_channels)); |
2461 | memcpy(priv->rates, rndis_rates, sizeof(rndis_rates)); | 2461 | memcpy(priv->rates, rndis_rates, sizeof(rndis_rates)); |
@@ -2497,9 +2497,9 @@ fail: | |||
2497 | } | 2497 | } |
2498 | 2498 | ||
2499 | 2499 | ||
2500 | static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf) | 2500 | static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf) |
2501 | { | 2501 | { |
2502 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 2502 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
2503 | 2503 | ||
2504 | /* turn radio off */ | 2504 | /* turn radio off */ |
2505 | disassociate(usbdev, 0); | 2505 | disassociate(usbdev, 0); |
@@ -2520,7 +2520,7 @@ static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2520 | } | 2520 | } |
2521 | 2521 | ||
2522 | 2522 | ||
2523 | static int rndis_wext_reset(struct usbnet *usbdev) | 2523 | static int rndis_wlan_reset(struct usbnet *usbdev) |
2524 | { | 2524 | { |
2525 | return deauthenticate(usbdev); | 2525 | return deauthenticate(usbdev); |
2526 | } | 2526 | } |
@@ -2529,40 +2529,40 @@ static int rndis_wext_reset(struct usbnet *usbdev) | |||
2529 | static const struct driver_info bcm4320b_info = { | 2529 | static const struct driver_info bcm4320b_info = { |
2530 | .description = "Wireless RNDIS device, BCM4320b based", | 2530 | .description = "Wireless RNDIS device, BCM4320b based", |
2531 | .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, | 2531 | .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, |
2532 | .bind = rndis_wext_bind, | 2532 | .bind = rndis_wlan_bind, |
2533 | .unbind = rndis_wext_unbind, | 2533 | .unbind = rndis_wlan_unbind, |
2534 | .status = rndis_status, | 2534 | .status = rndis_status, |
2535 | .rx_fixup = rndis_rx_fixup, | 2535 | .rx_fixup = rndis_rx_fixup, |
2536 | .tx_fixup = rndis_tx_fixup, | 2536 | .tx_fixup = rndis_tx_fixup, |
2537 | .reset = rndis_wext_reset, | 2537 | .reset = rndis_wlan_reset, |
2538 | .early_init = bcm4320b_early_init, | 2538 | .early_init = bcm4320b_early_init, |
2539 | .link_change = rndis_wext_link_change, | 2539 | .link_change = rndis_wlan_link_change, |
2540 | }; | 2540 | }; |
2541 | 2541 | ||
2542 | static const struct driver_info bcm4320a_info = { | 2542 | static const struct driver_info bcm4320a_info = { |
2543 | .description = "Wireless RNDIS device, BCM4320a based", | 2543 | .description = "Wireless RNDIS device, BCM4320a based", |
2544 | .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, | 2544 | .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, |
2545 | .bind = rndis_wext_bind, | 2545 | .bind = rndis_wlan_bind, |
2546 | .unbind = rndis_wext_unbind, | 2546 | .unbind = rndis_wlan_unbind, |
2547 | .status = rndis_status, | 2547 | .status = rndis_status, |
2548 | .rx_fixup = rndis_rx_fixup, | 2548 | .rx_fixup = rndis_rx_fixup, |
2549 | .tx_fixup = rndis_tx_fixup, | 2549 | .tx_fixup = rndis_tx_fixup, |
2550 | .reset = rndis_wext_reset, | 2550 | .reset = rndis_wlan_reset, |
2551 | .early_init = bcm4320a_early_init, | 2551 | .early_init = bcm4320a_early_init, |
2552 | .link_change = rndis_wext_link_change, | 2552 | .link_change = rndis_wlan_link_change, |
2553 | }; | 2553 | }; |
2554 | 2554 | ||
2555 | static const struct driver_info rndis_wext_info = { | 2555 | static const struct driver_info rndis_wlan_info = { |
2556 | .description = "Wireless RNDIS device", | 2556 | .description = "Wireless RNDIS device", |
2557 | .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, | 2557 | .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, |
2558 | .bind = rndis_wext_bind, | 2558 | .bind = rndis_wlan_bind, |
2559 | .unbind = rndis_wext_unbind, | 2559 | .unbind = rndis_wlan_unbind, |
2560 | .status = rndis_status, | 2560 | .status = rndis_status, |
2561 | .rx_fixup = rndis_rx_fixup, | 2561 | .rx_fixup = rndis_rx_fixup, |
2562 | .tx_fixup = rndis_tx_fixup, | 2562 | .tx_fixup = rndis_tx_fixup, |
2563 | .reset = rndis_wext_reset, | 2563 | .reset = rndis_wlan_reset, |
2564 | .early_init = bcm4320a_early_init, | 2564 | .early_init = bcm4320a_early_init, |
2565 | .link_change = rndis_wext_link_change, | 2565 | .link_change = rndis_wlan_link_change, |
2566 | }; | 2566 | }; |
2567 | 2567 | ||
2568 | /*-------------------------------------------------------------------------*/ | 2568 | /*-------------------------------------------------------------------------*/ |
@@ -2672,11 +2672,11 @@ static const struct usb_device_id products [] = { | |||
2672 | { | 2672 | { |
2673 | /* RNDIS is MSFT's un-official variant of CDC ACM */ | 2673 | /* RNDIS is MSFT's un-official variant of CDC ACM */ |
2674 | USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), | 2674 | USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), |
2675 | .driver_info = (unsigned long) &rndis_wext_info, | 2675 | .driver_info = (unsigned long) &rndis_wlan_info, |
2676 | }, { | 2676 | }, { |
2677 | /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ | 2677 | /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ |
2678 | USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), | 2678 | USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), |
2679 | .driver_info = (unsigned long) &rndis_wext_info, | 2679 | .driver_info = (unsigned long) &rndis_wlan_info, |
2680 | }, | 2680 | }, |
2681 | { }, // END | 2681 | { }, // END |
2682 | }; | 2682 | }; |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index b618fa51db2d..09a503e5da6a 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -988,7 +988,6 @@ static struct rfkill *acer_rfkill_register(struct device *dev, | |||
988 | char *name, u32 cap) | 988 | char *name, u32 cap) |
989 | { | 989 | { |
990 | int err; | 990 | int err; |
991 | u32 state; | ||
992 | struct rfkill *rfkill_dev; | 991 | struct rfkill *rfkill_dev; |
993 | 992 | ||
994 | rfkill_dev = rfkill_alloc(name, dev, type, | 993 | rfkill_dev = rfkill_alloc(name, dev, type, |
@@ -996,8 +995,6 @@ static struct rfkill *acer_rfkill_register(struct device *dev, | |||
996 | (void *)(unsigned long)cap); | 995 | (void *)(unsigned long)cap); |
997 | if (!rfkill_dev) | 996 | if (!rfkill_dev) |
998 | return ERR_PTR(-ENOMEM); | 997 | return ERR_PTR(-ENOMEM); |
999 | get_u32(&state, cap); | ||
1000 | rfkill_set_sw_state(rfkill_dev, !state); | ||
1001 | 998 | ||
1002 | err = rfkill_register(rfkill_dev); | 999 | err = rfkill_register(rfkill_dev); |
1003 | if (err) { | 1000 | if (err) { |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 1208d0cedd15..03bf522bd7ab 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -675,8 +675,8 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
675 | if (!ehotk->eeepc_wlan_rfkill) | 675 | if (!ehotk->eeepc_wlan_rfkill) |
676 | goto wlan_fail; | 676 | goto wlan_fail; |
677 | 677 | ||
678 | rfkill_set_global_sw_state(RFKILL_TYPE_WLAN, | 678 | rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, |
679 | get_acpi(CM_ASL_WLAN) != 1); | 679 | get_acpi(CM_ASL_WLAN) != 1); |
680 | result = rfkill_register(ehotk->eeepc_wlan_rfkill); | 680 | result = rfkill_register(ehotk->eeepc_wlan_rfkill); |
681 | if (result) | 681 | if (result) |
682 | goto wlan_fail; | 682 | goto wlan_fail; |
@@ -693,8 +693,8 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
693 | if (!ehotk->eeepc_bluetooth_rfkill) | 693 | if (!ehotk->eeepc_bluetooth_rfkill) |
694 | goto bluetooth_fail; | 694 | goto bluetooth_fail; |
695 | 695 | ||
696 | rfkill_set_global_sw_state(RFKILL_TYPE_BLUETOOTH, | 696 | rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill, |
697 | get_acpi(CM_ASL_BLUETOOTH) != 1); | 697 | get_acpi(CM_ASL_BLUETOOTH) != 1); |
698 | result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); | 698 | result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); |
699 | if (result) | 699 | if (result) |
700 | goto bluetooth_fail; | 700 | goto bluetooth_fail; |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 8d931145cbfa..16fffe44e333 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -422,7 +422,6 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) | |||
422 | RFKILL_TYPE_WLAN, | 422 | RFKILL_TYPE_WLAN, |
423 | &hp_wmi_rfkill_ops, | 423 | &hp_wmi_rfkill_ops, |
424 | (void *) 0); | 424 | (void *) 0); |
425 | rfkill_set_sw_state(wifi_rfkill, hp_wmi_wifi_state()); | ||
426 | err = rfkill_register(wifi_rfkill); | 425 | err = rfkill_register(wifi_rfkill); |
427 | if (err) | 426 | if (err) |
428 | goto register_wifi_error; | 427 | goto register_wifi_error; |
@@ -433,8 +432,6 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) | |||
433 | RFKILL_TYPE_BLUETOOTH, | 432 | RFKILL_TYPE_BLUETOOTH, |
434 | &hp_wmi_rfkill_ops, | 433 | &hp_wmi_rfkill_ops, |
435 | (void *) 1); | 434 | (void *) 1); |
436 | rfkill_set_sw_state(bluetooth_rfkill, | ||
437 | hp_wmi_bluetooth_state()); | ||
438 | err = rfkill_register(bluetooth_rfkill); | 435 | err = rfkill_register(bluetooth_rfkill); |
439 | if (err) | 436 | if (err) |
440 | goto register_bluetooth_error; | 437 | goto register_bluetooth_error; |
@@ -445,7 +442,6 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) | |||
445 | RFKILL_TYPE_WWAN, | 442 | RFKILL_TYPE_WWAN, |
446 | &hp_wmi_rfkill_ops, | 443 | &hp_wmi_rfkill_ops, |
447 | (void *) 2); | 444 | (void *) 2); |
448 | rfkill_set_sw_state(wwan_rfkill, hp_wmi_wwan_state()); | ||
449 | err = rfkill_register(wwan_rfkill); | 445 | err = rfkill_register(wwan_rfkill); |
450 | if (err) | 446 | if (err) |
451 | goto register_wwan_err; | 447 | goto register_wwan_err; |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index aec0b27fd774..e48d9a4506ff 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -1114,7 +1114,6 @@ static int sony_nc_setup_rfkill(struct acpi_device *device, | |||
1114 | return err; | 1114 | return err; |
1115 | } | 1115 | } |
1116 | sony_rfkill_devices[nc_type] = rfk; | 1116 | sony_rfkill_devices[nc_type] = rfk; |
1117 | sony_nc_rfkill_set((void *)nc_type, false); | ||
1118 | return err; | 1117 | return err; |
1119 | } | 1118 | } |
1120 | 1119 | ||
@@ -1135,8 +1134,7 @@ static void sony_nc_rfkill_update() | |||
1135 | 1134 | ||
1136 | if (hwblock) { | 1135 | if (hwblock) { |
1137 | if (rfkill_set_hw_state(sony_rfkill_devices[i], true)) | 1136 | if (rfkill_set_hw_state(sony_rfkill_devices[i], true)) |
1138 | sony_nc_rfkill_set(sony_rfkill_devices[i], | 1137 | sony_nc_rfkill_set((void *)i, true); |
1139 | true); | ||
1140 | continue; | 1138 | continue; |
1141 | } | 1139 | } |
1142 | 1140 | ||
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index cfcafa4e9473..86e958539f46 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -1168,21 +1168,6 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, | |||
1168 | 1168 | ||
1169 | BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]); | 1169 | BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]); |
1170 | 1170 | ||
1171 | initial_sw_status = (tp_rfkops->get_status)(); | ||
1172 | if (initial_sw_status < 0) { | ||
1173 | printk(TPACPI_ERR | ||
1174 | "failed to read initial state for %s, error %d; " | ||
1175 | "will turn radio off\n", name, initial_sw_status); | ||
1176 | } else { | ||
1177 | initial_sw_state = (initial_sw_status == TPACPI_RFK_RADIO_OFF); | ||
1178 | if (set_default) { | ||
1179 | /* try to set the initial state as the default for the | ||
1180 | * rfkill type, since we ask the firmware to preserve | ||
1181 | * it across S5 in NVRAM */ | ||
1182 | rfkill_set_global_sw_state(rfktype, initial_sw_state); | ||
1183 | } | ||
1184 | } | ||
1185 | |||
1186 | atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL); | 1171 | atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL); |
1187 | if (atp_rfk) | 1172 | if (atp_rfk) |
1188 | atp_rfk->rfkill = rfkill_alloc(name, | 1173 | atp_rfk->rfkill = rfkill_alloc(name, |
@@ -1200,8 +1185,20 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, | |||
1200 | atp_rfk->id = id; | 1185 | atp_rfk->id = id; |
1201 | atp_rfk->ops = tp_rfkops; | 1186 | atp_rfk->ops = tp_rfkops; |
1202 | 1187 | ||
1203 | rfkill_set_states(atp_rfk->rfkill, initial_sw_state, | 1188 | initial_sw_status = (tp_rfkops->get_status)(); |
1204 | tpacpi_rfk_check_hwblock_state()); | 1189 | if (initial_sw_status < 0) { |
1190 | printk(TPACPI_ERR | ||
1191 | "failed to read initial state for %s, error %d\n", | ||
1192 | name, initial_sw_status); | ||
1193 | } else { | ||
1194 | initial_sw_state = (initial_sw_status == TPACPI_RFK_RADIO_OFF); | ||
1195 | if (set_default) { | ||
1196 | /* try to keep the initial state, since we ask the | ||
1197 | * firmware to preserve it across S5 in NVRAM */ | ||
1198 | rfkill_set_sw_state(atp_rfk->rfkill, initial_sw_state); | ||
1199 | } | ||
1200 | } | ||
1201 | rfkill_set_hw_state(atp_rfk->rfkill, tpacpi_rfk_check_hwblock_state()); | ||
1205 | 1202 | ||
1206 | res = rfkill_register(atp_rfk->rfkill); | 1203 | res = rfkill_register(atp_rfk->rfkill); |
1207 | if (res < 0) { | 1204 | if (res < 0) { |
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 380b04272bf1..9b660bd2e2b3 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h | |||
@@ -30,7 +30,8 @@ struct ethtool_cmd { | |||
30 | __u32 maxtxpkt; /* Tx pkts before generating tx int */ | 30 | __u32 maxtxpkt; /* Tx pkts before generating tx int */ |
31 | __u32 maxrxpkt; /* Rx pkts before generating rx int */ | 31 | __u32 maxrxpkt; /* Rx pkts before generating rx int */ |
32 | __u16 speed_hi; | 32 | __u16 speed_hi; |
33 | __u16 reserved2; | 33 | __u8 eth_tp_mdix; |
34 | __u8 reserved2; | ||
34 | __u32 lp_advertising; /* Features the link partner advertises */ | 35 | __u32 lp_advertising; /* Features the link partner advertises */ |
35 | __u32 reserved[2]; | 36 | __u32 reserved[2]; |
36 | }; | 37 | }; |
@@ -632,6 +633,11 @@ struct ethtool_ops { | |||
632 | #define AUTONEG_DISABLE 0x00 | 633 | #define AUTONEG_DISABLE 0x00 |
633 | #define AUTONEG_ENABLE 0x01 | 634 | #define AUTONEG_ENABLE 0x01 |
634 | 635 | ||
636 | /* Mode MDI or MDI-X */ | ||
637 | #define ETH_TP_MDI_INVALID 0x00 | ||
638 | #define ETH_TP_MDI 0x01 | ||
639 | #define ETH_TP_MDI_X 0x02 | ||
640 | |||
635 | /* Wake-On-Lan options. */ | 641 | /* Wake-On-Lan options. */ |
636 | #define WAKE_PHY (1 << 0) | 642 | #define WAKE_PHY (1 << 0) |
637 | #define WAKE_UCAST (1 << 1) | 643 | #define WAKE_UCAST (1 << 1) |
diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h index 5ff89809a581..b554300ef8bf 100644 --- a/include/linux/if_arp.h +++ b/include/linux/if_arp.h | |||
@@ -86,6 +86,8 @@ | |||
86 | #define ARPHRD_IEEE80211 801 /* IEEE 802.11 */ | 86 | #define ARPHRD_IEEE80211 801 /* IEEE 802.11 */ |
87 | #define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */ | 87 | #define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */ |
88 | #define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */ | 88 | #define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */ |
89 | #define ARPHRD_IEEE802154 804 | ||
90 | #define ARPHRD_IEEE802154_PHY 805 | ||
89 | 91 | ||
90 | #define ARPHRD_PHONET 820 /* PhoNet media type */ | 92 | #define ARPHRD_PHONET 820 /* PhoNet media type */ |
91 | #define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */ | 93 | #define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */ |
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index cfe4fe1b7132..11a60e4f0a66 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h | |||
@@ -106,6 +106,7 @@ | |||
106 | #define ETH_P_DSA 0x001B /* Distributed Switch Arch. */ | 106 | #define ETH_P_DSA 0x001B /* Distributed Switch Arch. */ |
107 | #define ETH_P_TRAILER 0x001C /* Trailer switch tagging */ | 107 | #define ETH_P_TRAILER 0x001C /* Trailer switch tagging */ |
108 | #define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */ | 108 | #define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */ |
109 | #define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */ | ||
109 | 110 | ||
110 | /* | 111 | /* |
111 | * This is an Ethernet frame header. | 112 | * This is an Ethernet frame header. |
diff --git a/include/linux/isdn/capilli.h b/include/linux/isdn/capilli.h index 35e9b0fd014b..7acb87a44872 100644 --- a/include/linux/isdn/capilli.h +++ b/include/linux/isdn/capilli.h | |||
@@ -79,7 +79,7 @@ int attach_capi_ctr(struct capi_ctr *); | |||
79 | int detach_capi_ctr(struct capi_ctr *); | 79 | int detach_capi_ctr(struct capi_ctr *); |
80 | 80 | ||
81 | void capi_ctr_ready(struct capi_ctr * card); | 81 | void capi_ctr_ready(struct capi_ctr * card); |
82 | void capi_ctr_reseted(struct capi_ctr * card); | 82 | void capi_ctr_down(struct capi_ctr * card); |
83 | void capi_ctr_suspend_output(struct capi_ctr * card); | 83 | void capi_ctr_suspend_output(struct capi_ctr * card); |
84 | void capi_ctr_resume_output(struct capi_ctr * card); | 84 | void capi_ctr_resume_output(struct capi_ctr * card); |
85 | void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb); | 85 | void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb); |
diff --git a/include/linux/mdio.h b/include/linux/mdio.h index 56851646529a..cfdf1df2875e 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #define MDIO_PHYXS_LNSTAT 24 /* PHY XGXS lane state */ | 45 | #define MDIO_PHYXS_LNSTAT 24 /* PHY XGXS lane state */ |
46 | 46 | ||
47 | /* Media-dependent registers. */ | 47 | /* Media-dependent registers. */ |
48 | #define MDIO_PMA_10GBT_SWAPPOL 130 /* 10GBASE-T pair swap & polarity */ | ||
48 | #define MDIO_PMA_10GBT_TXPWR 131 /* 10GBASE-T TX power control */ | 49 | #define MDIO_PMA_10GBT_TXPWR 131 /* 10GBASE-T TX power control */ |
49 | #define MDIO_PMA_10GBT_SNR 133 /* 10GBASE-T SNR margin, lane A. | 50 | #define MDIO_PMA_10GBT_SNR 133 /* 10GBASE-T SNR margin, lane A. |
50 | * Lanes B-D are numbered 134-136. */ | 51 | * Lanes B-D are numbered 134-136. */ |
@@ -195,6 +196,14 @@ | |||
195 | #define MDIO_PHYXS_LNSTAT_SYNC3 0x0008 | 196 | #define MDIO_PHYXS_LNSTAT_SYNC3 0x0008 |
196 | #define MDIO_PHYXS_LNSTAT_ALIGN 0x1000 | 197 | #define MDIO_PHYXS_LNSTAT_ALIGN 0x1000 |
197 | 198 | ||
199 | /* PMA 10GBASE-T pair swap & polarity */ | ||
200 | #define MDIO_PMA_10GBT_SWAPPOL_ABNX 0x0001 /* Pair A/B uncrossed */ | ||
201 | #define MDIO_PMA_10GBT_SWAPPOL_CDNX 0x0002 /* Pair C/D uncrossed */ | ||
202 | #define MDIO_PMA_10GBT_SWAPPOL_AREV 0x0100 /* Pair A polarity reversed */ | ||
203 | #define MDIO_PMA_10GBT_SWAPPOL_BREV 0x0200 /* Pair B polarity reversed */ | ||
204 | #define MDIO_PMA_10GBT_SWAPPOL_CREV 0x0400 /* Pair C polarity reversed */ | ||
205 | #define MDIO_PMA_10GBT_SWAPPOL_DREV 0x0800 /* Pair D polarity reversed */ | ||
206 | |||
198 | /* PMA 10GBASE-T TX power register. */ | 207 | /* PMA 10GBASE-T TX power register. */ |
199 | #define MDIO_PMA_10GBT_TXPWR_SHORT 0x0001 /* Short-reach mode */ | 208 | #define MDIO_PMA_10GBT_TXPWR_SHORT 0x0001 /* Short-reach mode */ |
200 | 209 | ||
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 2a801380b502..9ea8d6dfe540 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -1904,7 +1904,7 @@ static inline int net_gso_ok(int features, int gso_type) | |||
1904 | static inline int skb_gso_ok(struct sk_buff *skb, int features) | 1904 | static inline int skb_gso_ok(struct sk_buff *skb, int features) |
1905 | { | 1905 | { |
1906 | return net_gso_ok(features, skb_shinfo(skb)->gso_type) && | 1906 | return net_gso_ok(features, skb_shinfo(skb)->gso_type) && |
1907 | (!skb_shinfo(skb)->frag_list || (features & NETIF_F_FRAGLIST)); | 1907 | (!skb_has_frags(skb) || (features & NETIF_F_FRAGLIST)); |
1908 | } | 1908 | } |
1909 | 1909 | ||
1910 | static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) | 1910 | static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) |
diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h new file mode 100644 index 000000000000..2cda00ccfcca --- /dev/null +++ b/include/linux/nl802154.h | |||
@@ -0,0 +1,119 @@ | |||
1 | /* | ||
2 | * nl802154.h | ||
3 | * | ||
4 | * Copyright (C) 2007, 2008, 2009 Siemens AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #ifndef NL802154_H | ||
22 | #define NL802154_H | ||
23 | |||
24 | #define IEEE802154_NL_NAME "802.15.4 MAC" | ||
25 | #define IEEE802154_MCAST_COORD_NAME "coordinator" | ||
26 | #define IEEE802154_MCAST_BEACON_NAME "beacon" | ||
27 | |||
28 | enum { | ||
29 | __IEEE802154_ATTR_INVALID, | ||
30 | |||
31 | IEEE802154_ATTR_DEV_NAME, | ||
32 | IEEE802154_ATTR_DEV_INDEX, | ||
33 | |||
34 | IEEE802154_ATTR_STATUS, | ||
35 | |||
36 | IEEE802154_ATTR_SHORT_ADDR, | ||
37 | IEEE802154_ATTR_HW_ADDR, | ||
38 | IEEE802154_ATTR_PAN_ID, | ||
39 | |||
40 | IEEE802154_ATTR_CHANNEL, | ||
41 | |||
42 | IEEE802154_ATTR_COORD_SHORT_ADDR, | ||
43 | IEEE802154_ATTR_COORD_HW_ADDR, | ||
44 | IEEE802154_ATTR_COORD_PAN_ID, | ||
45 | |||
46 | IEEE802154_ATTR_SRC_SHORT_ADDR, | ||
47 | IEEE802154_ATTR_SRC_HW_ADDR, | ||
48 | IEEE802154_ATTR_SRC_PAN_ID, | ||
49 | |||
50 | IEEE802154_ATTR_DEST_SHORT_ADDR, | ||
51 | IEEE802154_ATTR_DEST_HW_ADDR, | ||
52 | IEEE802154_ATTR_DEST_PAN_ID, | ||
53 | |||
54 | IEEE802154_ATTR_CAPABILITY, | ||
55 | IEEE802154_ATTR_REASON, | ||
56 | IEEE802154_ATTR_SCAN_TYPE, | ||
57 | IEEE802154_ATTR_CHANNELS, | ||
58 | IEEE802154_ATTR_DURATION, | ||
59 | IEEE802154_ATTR_ED_LIST, | ||
60 | IEEE802154_ATTR_BCN_ORD, | ||
61 | IEEE802154_ATTR_SF_ORD, | ||
62 | IEEE802154_ATTR_PAN_COORD, | ||
63 | IEEE802154_ATTR_BAT_EXT, | ||
64 | IEEE802154_ATTR_COORD_REALIGN, | ||
65 | IEEE802154_ATTR_SEC, | ||
66 | |||
67 | __IEEE802154_ATTR_MAX, | ||
68 | }; | ||
69 | |||
70 | #define IEEE802154_ATTR_MAX (__IEEE802154_ATTR_MAX - 1) | ||
71 | |||
72 | extern struct nla_policy ieee802154_policy[]; | ||
73 | |||
74 | /* commands */ | ||
75 | /* REQ should be responded with CONF | ||
76 | * and INDIC with RESP | ||
77 | */ | ||
78 | enum { | ||
79 | __IEEE802154_COMMAND_INVALID, | ||
80 | |||
81 | IEEE802154_ASSOCIATE_REQ, | ||
82 | IEEE802154_ASSOCIATE_CONF, | ||
83 | IEEE802154_DISASSOCIATE_REQ, | ||
84 | IEEE802154_DISASSOCIATE_CONF, | ||
85 | IEEE802154_GET_REQ, | ||
86 | IEEE802154_GET_CONF, | ||
87 | IEEE802154_RESET_REQ, | ||
88 | IEEE802154_RESET_CONF, | ||
89 | IEEE802154_SCAN_REQ, | ||
90 | IEEE802154_SCAN_CONF, | ||
91 | IEEE802154_SET_REQ, | ||
92 | IEEE802154_SET_CONF, | ||
93 | IEEE802154_START_REQ, | ||
94 | IEEE802154_START_CONF, | ||
95 | IEEE802154_SYNC_REQ, | ||
96 | IEEE802154_POLL_REQ, | ||
97 | IEEE802154_POLL_CONF, | ||
98 | |||
99 | IEEE802154_ASSOCIATE_INDIC, | ||
100 | IEEE802154_ASSOCIATE_RESP, | ||
101 | IEEE802154_DISASSOCIATE_INDIC, | ||
102 | IEEE802154_BEACON_NOTIFY_INDIC, | ||
103 | IEEE802154_ORPHAN_INDIC, | ||
104 | IEEE802154_ORPHAN_RESP, | ||
105 | IEEE802154_COMM_STATUS_INDIC, | ||
106 | IEEE802154_SYNC_LOSS_INDIC, | ||
107 | |||
108 | IEEE802154_GTS_REQ, /* Not supported yet */ | ||
109 | IEEE802154_GTS_INDIC, /* Not supported yet */ | ||
110 | IEEE802154_GTS_CONF, /* Not supported yet */ | ||
111 | IEEE802154_RX_ENABLE_REQ, /* Not supported yet */ | ||
112 | IEEE802154_RX_ENABLE_CONF, /* Not supported yet */ | ||
113 | |||
114 | __IEEE802154_CMD_MAX, | ||
115 | }; | ||
116 | |||
117 | #define IEEE802154_CMD_MAX (__IEEE802154_CMD_MAX - 1) | ||
118 | |||
119 | #endif | ||
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index ee3eddea8568..16e39c7a67fc 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h | |||
@@ -105,6 +105,7 @@ enum rfkill_user_states { | |||
105 | #include <linux/mutex.h> | 105 | #include <linux/mutex.h> |
106 | #include <linux/device.h> | 106 | #include <linux/device.h> |
107 | #include <linux/leds.h> | 107 | #include <linux/leds.h> |
108 | #include <linux/err.h> | ||
108 | 109 | ||
109 | /* this is opaque */ | 110 | /* this is opaque */ |
110 | struct rfkill; | 111 | struct rfkill; |
@@ -156,8 +157,14 @@ struct rfkill * __must_check rfkill_alloc(const char *name, | |||
156 | * @rfkill: rfkill structure to be registered | 157 | * @rfkill: rfkill structure to be registered |
157 | * | 158 | * |
158 | * This function should be called by the transmitter driver to register | 159 | * This function should be called by the transmitter driver to register |
159 | * the rfkill structure needs to be registered. Before calling this function | 160 | * the rfkill structure. Before calling this function the driver needs |
160 | * the driver needs to be ready to service method calls from rfkill. | 161 | * to be ready to service method calls from rfkill. |
162 | * | ||
163 | * If the software blocked state is not set before registration, | ||
164 | * set_block will be called to initialize it to a default value. | ||
165 | * | ||
166 | * If the hardware blocked state is not set before registration, | ||
167 | * it is assumed to be unblocked. | ||
161 | */ | 168 | */ |
162 | int __must_check rfkill_register(struct rfkill *rfkill); | 169 | int __must_check rfkill_register(struct rfkill *rfkill); |
163 | 170 | ||
@@ -205,7 +212,7 @@ void rfkill_destroy(struct rfkill *rfkill); | |||
205 | * | 212 | * |
206 | * rfkill drivers that get events when the hard-blocked state changes | 213 | * rfkill drivers that get events when the hard-blocked state changes |
207 | * use this function to notify the rfkill core (and through that also | 214 | * use this function to notify the rfkill core (and through that also |
208 | * userspace) of the current state -- they should also use this after | 215 | * userspace) of the current state. They should also use this after |
209 | * resume if the state could have changed. | 216 | * resume if the state could have changed. |
210 | * | 217 | * |
211 | * You need not (but may) call this function if poll_state is assigned. | 218 | * You need not (but may) call this function if poll_state is assigned. |
@@ -227,8 +234,9 @@ bool __must_check rfkill_set_hw_state(struct rfkill *rfkill, bool blocked); | |||
227 | * rfkill drivers that get events when the soft-blocked state changes | 234 | * rfkill drivers that get events when the soft-blocked state changes |
228 | * (yes, some platforms directly act on input but allow changing again) | 235 | * (yes, some platforms directly act on input but allow changing again) |
229 | * use this function to notify the rfkill core (and through that also | 236 | * use this function to notify the rfkill core (and through that also |
230 | * userspace) of the current state -- they should also use this after | 237 | * userspace) of the current state. It is not necessary to notify on |
231 | * resume if the state could have changed. | 238 | * resume; since hibernation can always change the soft-blocked state, |
239 | * the rfkill core will unconditionally restore the previous state. | ||
232 | * | 240 | * |
233 | * This function can be called in any context, even from within rfkill | 241 | * This function can be called in any context, even from within rfkill |
234 | * callbacks. | 242 | * callbacks. |
@@ -250,19 +258,6 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked); | |||
250 | void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw); | 258 | void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw); |
251 | 259 | ||
252 | /** | 260 | /** |
253 | * rfkill_set_global_sw_state - set global sw block default | ||
254 | * @type: rfkill type to set default for | ||
255 | * @blocked: default to set | ||
256 | * | ||
257 | * This function sets the global default -- use at boot if your platform has | ||
258 | * an rfkill switch. If not early enough this call may be ignored. | ||
259 | * | ||
260 | * XXX: instead of ignoring -- how about just updating all currently | ||
261 | * registered drivers? | ||
262 | */ | ||
263 | void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked); | ||
264 | |||
265 | /** | ||
266 | * rfkill_blocked - query rfkill block | 261 | * rfkill_blocked - query rfkill block |
267 | * | 262 | * |
268 | * @rfkill: rfkill struct to query | 263 | * @rfkill: rfkill struct to query |
@@ -316,11 +311,6 @@ static inline void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) | |||
316 | { | 311 | { |
317 | } | 312 | } |
318 | 313 | ||
319 | static inline void rfkill_set_global_sw_state(const enum rfkill_type type, | ||
320 | bool blocked) | ||
321 | { | ||
322 | } | ||
323 | |||
324 | static inline bool rfkill_blocked(struct rfkill *rfkill) | 314 | static inline bool rfkill_blocked(struct rfkill *rfkill) |
325 | { | 315 | { |
326 | return false; | 316 | return false; |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 7305da92be8f..fa51293f2708 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -189,19 +189,19 @@ struct skb_shared_info { | |||
189 | atomic_t dataref; | 189 | atomic_t dataref; |
190 | unsigned short nr_frags; | 190 | unsigned short nr_frags; |
191 | unsigned short gso_size; | 191 | unsigned short gso_size; |
192 | #ifdef CONFIG_HAS_DMA | ||
193 | dma_addr_t dma_head; | ||
194 | #endif | ||
192 | /* Warning: this field is not always filled in (UFO)! */ | 195 | /* Warning: this field is not always filled in (UFO)! */ |
193 | unsigned short gso_segs; | 196 | unsigned short gso_segs; |
194 | unsigned short gso_type; | 197 | unsigned short gso_type; |
195 | __be32 ip6_frag_id; | 198 | __be32 ip6_frag_id; |
196 | union skb_shared_tx tx_flags; | 199 | union skb_shared_tx tx_flags; |
197 | #ifdef CONFIG_HAS_DMA | ||
198 | unsigned int num_dma_maps; | ||
199 | #endif | ||
200 | struct sk_buff *frag_list; | 200 | struct sk_buff *frag_list; |
201 | struct skb_shared_hwtstamps hwtstamps; | 201 | struct skb_shared_hwtstamps hwtstamps; |
202 | skb_frag_t frags[MAX_SKB_FRAGS]; | 202 | skb_frag_t frags[MAX_SKB_FRAGS]; |
203 | #ifdef CONFIG_HAS_DMA | 203 | #ifdef CONFIG_HAS_DMA |
204 | dma_addr_t dma_maps[MAX_SKB_FRAGS + 1]; | 204 | dma_addr_t dma_maps[MAX_SKB_FRAGS]; |
205 | #endif | 205 | #endif |
206 | /* Intermediate layers must ensure that destructor_arg | 206 | /* Intermediate layers must ensure that destructor_arg |
207 | * remains valid until skb destructor */ | 207 | * remains valid until skb destructor */ |
@@ -304,9 +304,6 @@ typedef unsigned char *sk_buff_data_t; | |||
304 | * @tc_verd: traffic control verdict | 304 | * @tc_verd: traffic control verdict |
305 | * @ndisc_nodetype: router type (from link layer) | 305 | * @ndisc_nodetype: router type (from link layer) |
306 | * @do_not_encrypt: set to prevent encryption of this frame | 306 | * @do_not_encrypt: set to prevent encryption of this frame |
307 | * @requeue: set to indicate that the wireless core should attempt | ||
308 | * a software retry on this frame if we failed to | ||
309 | * receive an ACK for it | ||
310 | * @dma_cookie: a cookie to one of several possible DMA operations | 307 | * @dma_cookie: a cookie to one of several possible DMA operations |
311 | * done by skb DMA functions | 308 | * done by skb DMA functions |
312 | * @secmark: security marking | 309 | * @secmark: security marking |
@@ -380,7 +377,6 @@ struct sk_buff { | |||
380 | #endif | 377 | #endif |
381 | #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) | 378 | #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) |
382 | __u8 do_not_encrypt:1; | 379 | __u8 do_not_encrypt:1; |
383 | __u8 requeue:1; | ||
384 | #endif | 380 | #endif |
385 | /* 0/13/14 bit hole */ | 381 | /* 0/13/14 bit hole */ |
386 | 382 | ||
@@ -1077,7 +1073,7 @@ extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, | |||
1077 | int off, int size); | 1073 | int off, int size); |
1078 | 1074 | ||
1079 | #define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags) | 1075 | #define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags) |
1080 | #define SKB_FRAG_ASSERT(skb) BUG_ON(skb_shinfo(skb)->frag_list) | 1076 | #define SKB_FRAG_ASSERT(skb) BUG_ON(skb_has_frags(skb)) |
1081 | #define SKB_LINEAR_ASSERT(skb) BUG_ON(skb_is_nonlinear(skb)) | 1077 | #define SKB_LINEAR_ASSERT(skb) BUG_ON(skb_is_nonlinear(skb)) |
1082 | 1078 | ||
1083 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | 1079 | #ifdef NET_SKBUFF_DATA_USES_OFFSET |
@@ -1716,6 +1712,25 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) | |||
1716 | skb = skb->prev) | 1712 | skb = skb->prev) |
1717 | 1713 | ||
1718 | 1714 | ||
1715 | static inline bool skb_has_frags(const struct sk_buff *skb) | ||
1716 | { | ||
1717 | return skb_shinfo(skb)->frag_list != NULL; | ||
1718 | } | ||
1719 | |||
1720 | static inline void skb_frag_list_init(struct sk_buff *skb) | ||
1721 | { | ||
1722 | skb_shinfo(skb)->frag_list = NULL; | ||
1723 | } | ||
1724 | |||
1725 | static inline void skb_frag_add_head(struct sk_buff *skb, struct sk_buff *frag) | ||
1726 | { | ||
1727 | frag->next = skb_shinfo(skb)->frag_list; | ||
1728 | skb_shinfo(skb)->frag_list = frag; | ||
1729 | } | ||
1730 | |||
1731 | #define skb_walk_frags(skb, iter) \ | ||
1732 | for (iter = skb_shinfo(skb)->frag_list; iter; iter = iter->next) | ||
1733 | |||
1719 | extern struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags, | 1734 | extern struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags, |
1720 | int *peeked, int *err); | 1735 | int *peeked, int *err); |
1721 | extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, | 1736 | extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, |
diff --git a/include/linux/socket.h b/include/linux/socket.h index d2310cb45d2f..3b461dffe244 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h | |||
@@ -194,7 +194,8 @@ struct ucred { | |||
194 | #define AF_RXRPC 33 /* RxRPC sockets */ | 194 | #define AF_RXRPC 33 /* RxRPC sockets */ |
195 | #define AF_ISDN 34 /* mISDN sockets */ | 195 | #define AF_ISDN 34 /* mISDN sockets */ |
196 | #define AF_PHONET 35 /* Phonet sockets */ | 196 | #define AF_PHONET 35 /* Phonet sockets */ |
197 | #define AF_MAX 36 /* For now.. */ | 197 | #define AF_IEEE802154 36 /* IEEE802154 sockets */ |
198 | #define AF_MAX 37 /* For now.. */ | ||
198 | 199 | ||
199 | /* Protocol families, same as address families. */ | 200 | /* Protocol families, same as address families. */ |
200 | #define PF_UNSPEC AF_UNSPEC | 201 | #define PF_UNSPEC AF_UNSPEC |
@@ -233,6 +234,7 @@ struct ucred { | |||
233 | #define PF_RXRPC AF_RXRPC | 234 | #define PF_RXRPC AF_RXRPC |
234 | #define PF_ISDN AF_ISDN | 235 | #define PF_ISDN AF_ISDN |
235 | #define PF_PHONET AF_PHONET | 236 | #define PF_PHONET AF_PHONET |
237 | #define PF_IEEE802154 AF_IEEE802154 | ||
236 | #define PF_MAX AF_MAX | 238 | #define PF_MAX AF_MAX |
237 | 239 | ||
238 | /* Maximum queue length specifiable by listen. */ | 240 | /* Maximum queue length specifiable by listen. */ |
diff --git a/include/linux/spi/libertas_spi.h b/include/linux/spi/libertas_spi.h index 79506f5f9e67..1b5d5384fcd3 100644 --- a/include/linux/spi/libertas_spi.h +++ b/include/linux/spi/libertas_spi.h | |||
@@ -22,9 +22,6 @@ struct libertas_spi_platform_data { | |||
22 | * speed, you may want to use 0 here. */ | 22 | * speed, you may want to use 0 here. */ |
23 | u16 use_dummy_writes; | 23 | u16 use_dummy_writes; |
24 | 24 | ||
25 | /* GPIO number to use as chip select */ | ||
26 | u16 gpio_cs; | ||
27 | |||
28 | /* Board specific setup/teardown */ | 25 | /* Board specific setup/teardown */ |
29 | int (*setup)(struct spi_device *spi); | 26 | int (*setup)(struct spi_device *spi); |
30 | int (*teardown)(struct spi_device *spi); | 27 | int (*teardown)(struct spi_device *spi); |
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index cf8bcb255333..968166a45f86 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -165,15 +165,6 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long l | |||
165 | return skb; | 165 | return skb; |
166 | } | 166 | } |
167 | 167 | ||
168 | static inline int skb_frags_no(struct sk_buff *skb) | ||
169 | { | ||
170 | register struct sk_buff *frag = skb_shinfo(skb)->frag_list; | ||
171 | register int n = 1; | ||
172 | |||
173 | for (; frag; frag=frag->next, n++); | ||
174 | return n; | ||
175 | } | ||
176 | |||
177 | int bt_err(__u16 code); | 168 | int bt_err(__u16 code); |
178 | 169 | ||
179 | extern int hci_sock_init(void); | 170 | extern int hci_sock_init(void); |
diff --git a/include/net/ieee802154/af_ieee802154.h b/include/net/ieee802154/af_ieee802154.h new file mode 100644 index 000000000000..0d78605fb1a6 --- /dev/null +++ b/include/net/ieee802154/af_ieee802154.h | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * IEEE 802.15.4 inteface for userspace | ||
3 | * | ||
4 | * Copyright 2007, 2008 Siemens AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | * | ||
19 | * Written by: | ||
20 | * Sergey Lapin <slapin@ossfans.org> | ||
21 | * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | ||
22 | */ | ||
23 | |||
24 | #ifndef _AF_IEEE802154_H | ||
25 | #define _AF_IEEE802154_H | ||
26 | |||
27 | #include <linux/socket.h> /* for sa_family_t */ | ||
28 | |||
29 | enum { | ||
30 | IEEE802154_ADDR_NONE = 0x0, | ||
31 | /* RESERVED = 0x01, */ | ||
32 | IEEE802154_ADDR_SHORT = 0x2, /* 16-bit address + PANid */ | ||
33 | IEEE802154_ADDR_LONG = 0x3, /* 64-bit address + PANid */ | ||
34 | }; | ||
35 | |||
36 | /* address length, octets */ | ||
37 | #define IEEE802154_ADDR_LEN 8 | ||
38 | |||
39 | struct ieee802154_addr { | ||
40 | int addr_type; | ||
41 | u16 pan_id; | ||
42 | union { | ||
43 | u8 hwaddr[IEEE802154_ADDR_LEN]; | ||
44 | u16 short_addr; | ||
45 | }; | ||
46 | }; | ||
47 | |||
48 | #define IEEE802154_PANID_BROADCAST 0xffff | ||
49 | #define IEEE802154_ADDR_BROADCAST 0xffff | ||
50 | #define IEEE802154_ADDR_UNDEF 0xfffe | ||
51 | |||
52 | struct sockaddr_ieee802154 { | ||
53 | sa_family_t family; /* AF_IEEE802154 */ | ||
54 | struct ieee802154_addr addr; | ||
55 | }; | ||
56 | |||
57 | /* master device */ | ||
58 | #define IEEE802154_SIOC_ADD_SLAVE (SIOCDEVPRIVATE + 0) | ||
59 | |||
60 | #endif | ||
diff --git a/include/net/ieee802154/mac_def.h b/include/net/ieee802154/mac_def.h new file mode 100644 index 000000000000..8cb684635650 --- /dev/null +++ b/include/net/ieee802154/mac_def.h | |||
@@ -0,0 +1,160 @@ | |||
1 | /* | ||
2 | * IEEE802.15.4-2003 specification | ||
3 | * | ||
4 | * Copyright (C) 2007, 2008 Siemens AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | * | ||
19 | * Written by: | ||
20 | * Pavel Smolenskiy <pavel.smolenskiy@gmail.com> | ||
21 | * Maxim Gorbachyov <maxim.gorbachev@siemens.com> | ||
22 | * Maxim Osipov <maxim.osipov@siemens.com> | ||
23 | * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | ||
24 | */ | ||
25 | |||
26 | #ifndef IEEE802154_MAC_DEF_H | ||
27 | #define IEEE802154_MAC_DEF_H | ||
28 | |||
29 | #define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */ | ||
30 | #define IEEE802154_FC_TYPE_DATA 0x1 /* Frame is data */ | ||
31 | #define IEEE802154_FC_TYPE_ACK 0x2 /* Frame is acknowledgment */ | ||
32 | #define IEEE802154_FC_TYPE_MAC_CMD 0x3 /* Frame is MAC command */ | ||
33 | |||
34 | #define IEEE802154_FC_TYPE_SHIFT 0 | ||
35 | #define IEEE802154_FC_TYPE_MASK ((1 << 3) - 1) | ||
36 | #define IEEE802154_FC_TYPE(x) ((x & IEEE802154_FC_TYPE_MASK) >> IEEE802154_FC_TYPE_SHIFT) | ||
37 | #define IEEE802154_FC_SET_TYPE(v, x) do { \ | ||
38 | v = (((v) & ~IEEE802154_FC_TYPE_MASK) | \ | ||
39 | (((x) << IEEE802154_FC_TYPE_SHIFT) & IEEE802154_FC_TYPE_MASK)); \ | ||
40 | } while (0) | ||
41 | |||
42 | #define IEEE802154_FC_SECEN (1 << 3) | ||
43 | #define IEEE802154_FC_FRPEND (1 << 4) | ||
44 | #define IEEE802154_FC_ACK_REQ (1 << 5) | ||
45 | #define IEEE802154_FC_INTRA_PAN (1 << 6) | ||
46 | |||
47 | #define IEEE802154_FC_SAMODE_SHIFT 14 | ||
48 | #define IEEE802154_FC_SAMODE_MASK (3 << IEEE802154_FC_SAMODE_SHIFT) | ||
49 | #define IEEE802154_FC_DAMODE_SHIFT 10 | ||
50 | #define IEEE802154_FC_DAMODE_MASK (3 << IEEE802154_FC_DAMODE_SHIFT) | ||
51 | |||
52 | #define IEEE802154_FC_SAMODE(x) \ | ||
53 | (((x) & IEEE802154_FC_SAMODE_MASK) >> IEEE802154_FC_SAMODE_SHIFT) | ||
54 | |||
55 | #define IEEE802154_FC_DAMODE(x) \ | ||
56 | (((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT) | ||
57 | |||
58 | |||
59 | /* MAC's Command Frames Identifiers */ | ||
60 | #define IEEE802154_CMD_ASSOCIATION_REQ 0x01 | ||
61 | #define IEEE802154_CMD_ASSOCIATION_RESP 0x02 | ||
62 | #define IEEE802154_CMD_DISASSOCIATION_NOTIFY 0x03 | ||
63 | #define IEEE802154_CMD_DATA_REQ 0x04 | ||
64 | #define IEEE802154_CMD_PANID_CONFLICT_NOTIFY 0x05 | ||
65 | #define IEEE802154_CMD_ORPHAN_NOTIFY 0x06 | ||
66 | #define IEEE802154_CMD_BEACON_REQ 0x07 | ||
67 | #define IEEE802154_CMD_COORD_REALIGN_NOTIFY 0x08 | ||
68 | #define IEEE802154_CMD_GTS_REQ 0x09 | ||
69 | |||
70 | /* | ||
71 | * The return values of MAC operations | ||
72 | */ | ||
73 | enum { | ||
74 | /* | ||
75 | * The requested operation was completed successfully. | ||
76 | * For a transmission request, this value indicates | ||
77 | * a successful transmission. | ||
78 | */ | ||
79 | IEEE802154_SUCCESS = 0x0, | ||
80 | |||
81 | /* The beacon was lost following a synchronization request. */ | ||
82 | IEEE802154_BEACON_LOSS = 0xe0, | ||
83 | /* | ||
84 | * A transmission could not take place due to activity on the | ||
85 | * channel, i.e., the CSMA-CA mechanism has failed. | ||
86 | */ | ||
87 | IEEE802154_CHNL_ACCESS_FAIL = 0xe1, | ||
88 | /* The GTS request has been denied by the PAN coordinator. */ | ||
89 | IEEE802154_DENINED = 0xe2, | ||
90 | /* The attempt to disable the transceiver has failed. */ | ||
91 | IEEE802154_DISABLE_TRX_FAIL = 0xe3, | ||
92 | /* | ||
93 | * The received frame induces a failed security check according to | ||
94 | * the security suite. | ||
95 | */ | ||
96 | IEEE802154_FAILED_SECURITY_CHECK = 0xe4, | ||
97 | /* | ||
98 | * The frame resulting from secure processing has a length that is | ||
99 | * greater than aMACMaxFrameSize. | ||
100 | */ | ||
101 | IEEE802154_FRAME_TOO_LONG = 0xe5, | ||
102 | /* | ||
103 | * The requested GTS transmission failed because the specified GTS | ||
104 | * either did not have a transmit GTS direction or was not defined. | ||
105 | */ | ||
106 | IEEE802154_INVALID_GTS = 0xe6, | ||
107 | /* | ||
108 | * A request to purge an MSDU from the transaction queue was made using | ||
109 | * an MSDU handle that was not found in the transaction table. | ||
110 | */ | ||
111 | IEEE802154_INVALID_HANDLE = 0xe7, | ||
112 | /* A parameter in the primitive is out of the valid range.*/ | ||
113 | IEEE802154_INVALID_PARAMETER = 0xe8, | ||
114 | /* No acknowledgment was received after aMaxFrameRetries. */ | ||
115 | IEEE802154_NO_ACK = 0xe9, | ||
116 | /* A scan operation failed to find any network beacons.*/ | ||
117 | IEEE802154_NO_BEACON = 0xea, | ||
118 | /* No response data were available following a request. */ | ||
119 | IEEE802154_NO_DATA = 0xeb, | ||
120 | /* The operation failed because a short address was not allocated. */ | ||
121 | IEEE802154_NO_SHORT_ADDRESS = 0xec, | ||
122 | /* | ||
123 | * A receiver enable request was unsuccessful because it could not be | ||
124 | * completed within the CAP. | ||
125 | */ | ||
126 | IEEE802154_OUT_OF_CAP = 0xed, | ||
127 | /* | ||
128 | * A PAN identifier conflict has been detected and communicated to the | ||
129 | * PAN coordinator. | ||
130 | */ | ||
131 | IEEE802154_PANID_CONFLICT = 0xee, | ||
132 | /* A coordinator realignment command has been received. */ | ||
133 | IEEE802154_REALIGMENT = 0xef, | ||
134 | /* The transaction has expired and its information discarded. */ | ||
135 | IEEE802154_TRANSACTION_EXPIRED = 0xf0, | ||
136 | /* There is no capacity to store the transaction. */ | ||
137 | IEEE802154_TRANSACTION_OVERFLOW = 0xf1, | ||
138 | /* | ||
139 | * The transceiver was in the transmitter enabled state when the | ||
140 | * receiver was requested to be enabled. | ||
141 | */ | ||
142 | IEEE802154_TX_ACTIVE = 0xf2, | ||
143 | /* The appropriate key is not available in the ACL. */ | ||
144 | IEEE802154_UNAVAILABLE_KEY = 0xf3, | ||
145 | /* | ||
146 | * A SET/GET request was issued with the identifier of a PIB attribute | ||
147 | * that is not supported. | ||
148 | */ | ||
149 | IEEE802154_UNSUPPORTED_ATTR = 0xf4, | ||
150 | /* | ||
151 | * A request to perform a scan operation failed because the MLME was | ||
152 | * in the process of performing a previously initiated scan operation. | ||
153 | */ | ||
154 | IEEE802154_SCAN_IN_PROGRESS = 0xfc, | ||
155 | }; | ||
156 | |||
157 | |||
158 | #endif | ||
159 | |||
160 | |||
diff --git a/include/net/ieee802154/netdevice.h b/include/net/ieee802154/netdevice.h new file mode 100644 index 000000000000..e2506af3e7c8 --- /dev/null +++ b/include/net/ieee802154/netdevice.h | |||
@@ -0,0 +1,115 @@ | |||
1 | /* | ||
2 | * An interface between IEEE802.15.4 device and rest of the kernel. | ||
3 | * | ||
4 | * Copyright (C) 2007, 2008, 2009 Siemens AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | * | ||
19 | * Written by: | ||
20 | * Pavel Smolenskiy <pavel.smolenskiy@gmail.com> | ||
21 | * Maxim Gorbachyov <maxim.gorbachev@siemens.com> | ||
22 | * Maxim Osipov <maxim.osipov@siemens.com> | ||
23 | * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | ||
24 | */ | ||
25 | |||
26 | #ifndef IEEE802154_NETDEVICE_H | ||
27 | #define IEEE802154_NETDEVICE_H | ||
28 | |||
29 | /* | ||
30 | * A control block of skb passed between the ARPHRD_IEEE802154 device | ||
31 | * and other stack parts. | ||
32 | */ | ||
33 | struct ieee802154_mac_cb { | ||
34 | u8 lqi; | ||
35 | struct ieee802154_addr sa; | ||
36 | struct ieee802154_addr da; | ||
37 | u8 flags; | ||
38 | u8 seq; | ||
39 | }; | ||
40 | |||
41 | static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb) | ||
42 | { | ||
43 | return (struct ieee802154_mac_cb *)skb->cb; | ||
44 | } | ||
45 | |||
46 | #define MAC_CB_FLAG_TYPEMASK ((1 << 3) - 1) | ||
47 | |||
48 | #define MAC_CB_FLAG_ACKREQ (1 << 3) | ||
49 | #define MAC_CB_FLAG_SECEN (1 << 4) | ||
50 | #define MAC_CB_FLAG_INTRAPAN (1 << 5) | ||
51 | |||
52 | static inline int mac_cb_is_ackreq(struct sk_buff *skb) | ||
53 | { | ||
54 | return mac_cb(skb)->flags & MAC_CB_FLAG_ACKREQ; | ||
55 | } | ||
56 | |||
57 | static inline int mac_cb_is_secen(struct sk_buff *skb) | ||
58 | { | ||
59 | return mac_cb(skb)->flags & MAC_CB_FLAG_SECEN; | ||
60 | } | ||
61 | |||
62 | static inline int mac_cb_is_intrapan(struct sk_buff *skb) | ||
63 | { | ||
64 | return mac_cb(skb)->flags & MAC_CB_FLAG_INTRAPAN; | ||
65 | } | ||
66 | |||
67 | static inline int mac_cb_type(struct sk_buff *skb) | ||
68 | { | ||
69 | return mac_cb(skb)->flags & MAC_CB_FLAG_TYPEMASK; | ||
70 | } | ||
71 | |||
72 | #define IEEE802154_MAC_SCAN_ED 0 | ||
73 | #define IEEE802154_MAC_SCAN_ACTIVE 1 | ||
74 | #define IEEE802154_MAC_SCAN_PASSIVE 2 | ||
75 | #define IEEE802154_MAC_SCAN_ORPHAN 3 | ||
76 | |||
77 | /* | ||
78 | * This should be located at net_device->ml_priv | ||
79 | */ | ||
80 | struct ieee802154_mlme_ops { | ||
81 | int (*assoc_req)(struct net_device *dev, | ||
82 | struct ieee802154_addr *addr, | ||
83 | u8 channel, u8 cap); | ||
84 | int (*assoc_resp)(struct net_device *dev, | ||
85 | struct ieee802154_addr *addr, | ||
86 | u16 short_addr, u8 status); | ||
87 | int (*disassoc_req)(struct net_device *dev, | ||
88 | struct ieee802154_addr *addr, | ||
89 | u8 reason); | ||
90 | int (*start_req)(struct net_device *dev, | ||
91 | struct ieee802154_addr *addr, | ||
92 | u8 channel, u8 bcn_ord, u8 sf_ord, | ||
93 | u8 pan_coord, u8 blx, u8 coord_realign); | ||
94 | int (*scan_req)(struct net_device *dev, | ||
95 | u8 type, u32 channels, u8 duration); | ||
96 | |||
97 | /* | ||
98 | * FIXME: these should become the part of PIB/MIB interface. | ||
99 | * However we still don't have IB interface of any kind | ||
100 | */ | ||
101 | u16 (*get_pan_id)(struct net_device *dev); | ||
102 | u16 (*get_short_addr)(struct net_device *dev); | ||
103 | u8 (*get_dsn)(struct net_device *dev); | ||
104 | u8 (*get_bsn)(struct net_device *dev); | ||
105 | }; | ||
106 | |||
107 | static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops( | ||
108 | struct net_device *dev) | ||
109 | { | ||
110 | return dev->ml_priv; | ||
111 | } | ||
112 | |||
113 | #endif | ||
114 | |||
115 | |||
diff --git a/include/net/ieee802154/nl802154.h b/include/net/ieee802154/nl802154.h new file mode 100644 index 000000000000..78efcdf52b59 --- /dev/null +++ b/include/net/ieee802154/nl802154.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * nl802154.h | ||
3 | * | ||
4 | * Copyright (C) 2007, 2008, 2009 Siemens AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #ifndef IEEE802154_NL_H | ||
22 | #define IEEE802154_NL_H | ||
23 | |||
24 | struct net_device; | ||
25 | struct ieee802154_addr; | ||
26 | |||
27 | int ieee802154_nl_assoc_indic(struct net_device *dev, | ||
28 | struct ieee802154_addr *addr, u8 cap); | ||
29 | int ieee802154_nl_assoc_confirm(struct net_device *dev, | ||
30 | u16 short_addr, u8 status); | ||
31 | int ieee802154_nl_disassoc_indic(struct net_device *dev, | ||
32 | struct ieee802154_addr *addr, u8 reason); | ||
33 | int ieee802154_nl_disassoc_confirm(struct net_device *dev, | ||
34 | u8 status); | ||
35 | int ieee802154_nl_scan_confirm(struct net_device *dev, | ||
36 | u8 status, u8 scan_type, u32 unscanned, | ||
37 | u8 *edl/*, struct list_head *pan_desc_list */); | ||
38 | int ieee802154_nl_beacon_indic(struct net_device *dev, u16 panid, | ||
39 | u16 coord_addr); | ||
40 | |||
41 | #endif | ||
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 17d61d19d912..c06104476973 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -239,6 +239,8 @@ struct ieee80211_bss_conf { | |||
239 | * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211, | 239 | * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211, |
240 | * used to indicate that a pending frame requires TX processing before | 240 | * used to indicate that a pending frame requires TX processing before |
241 | * it can be sent out. | 241 | * it can be sent out. |
242 | * @IEEE80211_TX_INTFL_RETRIED: completely internal to mac80211, | ||
243 | * used to indicate that a frame was already retried due to PS | ||
242 | */ | 244 | */ |
243 | enum mac80211_tx_control_flags { | 245 | enum mac80211_tx_control_flags { |
244 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), | 246 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), |
@@ -256,6 +258,7 @@ enum mac80211_tx_control_flags { | |||
256 | IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), | 258 | IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), |
257 | IEEE80211_TX_INTFL_RCALGO = BIT(13), | 259 | IEEE80211_TX_INTFL_RCALGO = BIT(13), |
258 | IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14), | 260 | IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14), |
261 | IEEE80211_TX_INTFL_RETRIED = BIT(15), | ||
259 | }; | 262 | }; |
260 | 263 | ||
261 | /** | 264 | /** |
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index e37fe3129c17..120935b2abd8 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h | |||
@@ -41,9 +41,10 @@ static inline void *qdisc_priv(struct Qdisc *q) | |||
41 | typedef u64 psched_time_t; | 41 | typedef u64 psched_time_t; |
42 | typedef long psched_tdiff_t; | 42 | typedef long psched_tdiff_t; |
43 | 43 | ||
44 | /* Avoid doing 64 bit divide by 1000 */ | 44 | /* Avoid doing 64 bit divide */ |
45 | #define PSCHED_US2NS(x) ((s64)(x) << 10) | 45 | #define PSCHED_SHIFT 6 |
46 | #define PSCHED_NS2US(x) ((x) >> 10) | 46 | #define PSCHED_US2NS(x) ((s64)(x) << PSCHED_SHIFT) |
47 | #define PSCHED_NS2US(x) ((x) >> PSCHED_SHIFT) | ||
47 | 48 | ||
48 | #define PSCHED_TICKS_PER_SEC PSCHED_NS2US(NSEC_PER_SEC) | 49 | #define PSCHED_TICKS_PER_SEC PSCHED_NS2US(NSEC_PER_SEC) |
49 | #define PSCHED_PASTPERFECT 0 | 50 | #define PSCHED_PASTPERFECT 0 |
diff --git a/include/net/sock.h b/include/net/sock.h index 4bb1ff9fd15b..010e14a93c92 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -1217,9 +1217,13 @@ static inline int skb_copy_to_page(struct sock *sk, char __user *from, | |||
1217 | 1217 | ||
1218 | static inline void skb_set_owner_w(struct sk_buff *skb, struct sock *sk) | 1218 | static inline void skb_set_owner_w(struct sk_buff *skb, struct sock *sk) |
1219 | { | 1219 | { |
1220 | sock_hold(sk); | ||
1221 | skb->sk = sk; | 1220 | skb->sk = sk; |
1222 | skb->destructor = sock_wfree; | 1221 | skb->destructor = sock_wfree; |
1222 | /* | ||
1223 | * We used to take a refcount on sk, but following operation | ||
1224 | * is enough to guarantee sk_free() wont free this sock until | ||
1225 | * all in-flight packets are completed | ||
1226 | */ | ||
1223 | atomic_add(skb->truesize, &sk->sk_wmem_alloc); | 1227 | atomic_add(skb->truesize, &sk->sk_wmem_alloc); |
1224 | } | 1228 | } |
1225 | 1229 | ||
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 714e1c3536be..fe649081fbdc 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -758,7 +758,7 @@ static void __exit vlan_cleanup_module(void) | |||
758 | BUG_ON(!hlist_empty(&vlan_group_hash[i])); | 758 | BUG_ON(!hlist_empty(&vlan_group_hash[i])); |
759 | 759 | ||
760 | unregister_pernet_gen_device(vlan_net_id, &vlan_net_ops); | 760 | unregister_pernet_gen_device(vlan_net_id, &vlan_net_ops); |
761 | synchronize_net(); | 761 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ |
762 | 762 | ||
763 | vlan_gvrp_uninit(); | 763 | vlan_gvrp_uninit(); |
764 | } | 764 | } |
diff --git a/net/Kconfig b/net/Kconfig index c19f549c8e74..7051b9710675 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
@@ -179,6 +179,7 @@ source "net/lapb/Kconfig" | |||
179 | source "net/econet/Kconfig" | 179 | source "net/econet/Kconfig" |
180 | source "net/wanrouter/Kconfig" | 180 | source "net/wanrouter/Kconfig" |
181 | source "net/phonet/Kconfig" | 181 | source "net/phonet/Kconfig" |
182 | source "net/ieee802154/Kconfig" | ||
182 | source "net/sched/Kconfig" | 183 | source "net/sched/Kconfig" |
183 | source "net/dcb/Kconfig" | 184 | source "net/dcb/Kconfig" |
184 | 185 | ||
diff --git a/net/Makefile b/net/Makefile index 9e00a55a901b..ba324aefda73 100644 --- a/net/Makefile +++ b/net/Makefile | |||
@@ -60,6 +60,7 @@ obj-$(CONFIG_NET_9P) += 9p/ | |||
60 | ifneq ($(CONFIG_DCB),) | 60 | ifneq ($(CONFIG_DCB),) |
61 | obj-y += dcb/ | 61 | obj-y += dcb/ |
62 | endif | 62 | endif |
63 | obj-y += ieee802154/ | ||
63 | 64 | ||
64 | ifeq ($(CONFIG_NET),y) | 65 | ifeq ($(CONFIG_NET),y) |
65 | obj-$(CONFIG_SYSCTL) += sysctl_net.o | 66 | obj-$(CONFIG_SYSCTL) += sysctl_net.o |
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index d6a9243641af..b603cbacdc58 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
@@ -939,6 +939,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, | |||
939 | int len, unsigned long sum) | 939 | int len, unsigned long sum) |
940 | { | 940 | { |
941 | int start = skb_headlen(skb); | 941 | int start = skb_headlen(skb); |
942 | struct sk_buff *frag_iter; | ||
942 | int i, copy; | 943 | int i, copy; |
943 | 944 | ||
944 | /* checksum stuff in header space */ | 945 | /* checksum stuff in header space */ |
@@ -977,26 +978,22 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, | |||
977 | start = end; | 978 | start = end; |
978 | } | 979 | } |
979 | 980 | ||
980 | if (skb_shinfo(skb)->frag_list) { | 981 | skb_walk_frags(skb, frag_iter) { |
981 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 982 | int end; |
982 | |||
983 | for (; list; list = list->next) { | ||
984 | int end; | ||
985 | 983 | ||
986 | WARN_ON(start > offset + len); | 984 | WARN_ON(start > offset + len); |
987 | 985 | ||
988 | end = start + list->len; | 986 | end = start + frag_iter->len; |
989 | if ((copy = end - offset) > 0) { | 987 | if ((copy = end - offset) > 0) { |
990 | if (copy > len) | 988 | if (copy > len) |
991 | copy = len; | 989 | copy = len; |
992 | sum = atalk_sum_skb(list, offset - start, | 990 | sum = atalk_sum_skb(frag_iter, offset - start, |
993 | copy, sum); | 991 | copy, sum); |
994 | if ((len -= copy) == 0) | 992 | if ((len -= copy) == 0) |
995 | return sum; | 993 | return sum; |
996 | offset += copy; | 994 | offset += copy; |
997 | } | ||
998 | start = end; | ||
999 | } | 995 | } |
996 | start = end; | ||
1000 | } | 997 | } |
1001 | 998 | ||
1002 | BUG_ON(len > 0); | 999 | BUG_ON(len > 0); |
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index 78958c0f9a40..97f8d68d574d 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c | |||
@@ -382,7 +382,7 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl) | |||
382 | 382 | ||
383 | BT_DBG("ctrl %p", ctrl); | 383 | BT_DBG("ctrl %p", ctrl); |
384 | 384 | ||
385 | capi_ctr_reseted(ctrl); | 385 | capi_ctr_down(ctrl); |
386 | 386 | ||
387 | atomic_inc(&session->terminate); | 387 | atomic_inc(&session->terminate); |
388 | cmtp_schedule(session); | 388 | cmtp_schedule(session); |
diff --git a/net/can/af_can.c b/net/can/af_can.c index 10f0528c3bf5..e733725b11d4 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
@@ -903,6 +903,8 @@ static __exit void can_exit(void) | |||
903 | } | 903 | } |
904 | spin_unlock(&can_rcvlists_lock); | 904 | spin_unlock(&can_rcvlists_lock); |
905 | 905 | ||
906 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | ||
907 | |||
906 | kmem_cache_destroy(rcv_cache); | 908 | kmem_cache_destroy(rcv_cache); |
907 | } | 909 | } |
908 | 910 | ||
diff --git a/net/core/datagram.c b/net/core/datagram.c index e2a36f05cdf7..58abee1f1df1 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -282,6 +282,7 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, | |||
282 | { | 282 | { |
283 | int start = skb_headlen(skb); | 283 | int start = skb_headlen(skb); |
284 | int i, copy = start - offset; | 284 | int i, copy = start - offset; |
285 | struct sk_buff *frag_iter; | ||
285 | 286 | ||
286 | /* Copy header. */ | 287 | /* Copy header. */ |
287 | if (copy > 0) { | 288 | if (copy > 0) { |
@@ -322,28 +323,24 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, | |||
322 | start = end; | 323 | start = end; |
323 | } | 324 | } |
324 | 325 | ||
325 | if (skb_shinfo(skb)->frag_list) { | 326 | skb_walk_frags(skb, frag_iter) { |
326 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 327 | int end; |
327 | 328 | ||
328 | for (; list; list = list->next) { | 329 | WARN_ON(start > offset + len); |
329 | int end; | 330 | |
330 | 331 | end = start + frag_iter->len; | |
331 | WARN_ON(start > offset + len); | 332 | if ((copy = end - offset) > 0) { |
332 | 333 | if (copy > len) | |
333 | end = start + list->len; | 334 | copy = len; |
334 | if ((copy = end - offset) > 0) { | 335 | if (skb_copy_datagram_iovec(frag_iter, |
335 | if (copy > len) | 336 | offset - start, |
336 | copy = len; | 337 | to, copy)) |
337 | if (skb_copy_datagram_iovec(list, | 338 | goto fault; |
338 | offset - start, | 339 | if ((len -= copy) == 0) |
339 | to, copy)) | 340 | return 0; |
340 | goto fault; | 341 | offset += copy; |
341 | if ((len -= copy) == 0) | ||
342 | return 0; | ||
343 | offset += copy; | ||
344 | } | ||
345 | start = end; | ||
346 | } | 342 | } |
343 | start = end; | ||
347 | } | 344 | } |
348 | if (!len) | 345 | if (!len) |
349 | return 0; | 346 | return 0; |
@@ -369,6 +366,7 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset, | |||
369 | { | 366 | { |
370 | int start = skb_headlen(skb); | 367 | int start = skb_headlen(skb); |
371 | int i, copy = start - offset; | 368 | int i, copy = start - offset; |
369 | struct sk_buff *frag_iter; | ||
372 | 370 | ||
373 | /* Copy header. */ | 371 | /* Copy header. */ |
374 | if (copy > 0) { | 372 | if (copy > 0) { |
@@ -411,30 +409,26 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset, | |||
411 | start = end; | 409 | start = end; |
412 | } | 410 | } |
413 | 411 | ||
414 | if (skb_shinfo(skb)->frag_list) { | 412 | skb_walk_frags(skb, frag_iter) { |
415 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 413 | int end; |
416 | 414 | ||
417 | for (; list; list = list->next) { | 415 | WARN_ON(start > offset + len); |
418 | int end; | 416 | |
419 | 417 | end = start + frag_iter->len; | |
420 | WARN_ON(start > offset + len); | 418 | if ((copy = end - offset) > 0) { |
421 | 419 | if (copy > len) | |
422 | end = start + list->len; | 420 | copy = len; |
423 | if ((copy = end - offset) > 0) { | 421 | if (skb_copy_datagram_const_iovec(frag_iter, |
424 | if (copy > len) | 422 | offset - start, |
425 | copy = len; | 423 | to, to_offset, |
426 | if (skb_copy_datagram_const_iovec(list, | 424 | copy)) |
427 | offset - start, | 425 | goto fault; |
428 | to, to_offset, | 426 | if ((len -= copy) == 0) |
429 | copy)) | 427 | return 0; |
430 | goto fault; | 428 | offset += copy; |
431 | if ((len -= copy) == 0) | 429 | to_offset += copy; |
432 | return 0; | ||
433 | offset += copy; | ||
434 | to_offset += copy; | ||
435 | } | ||
436 | start = end; | ||
437 | } | 430 | } |
431 | start = end; | ||
438 | } | 432 | } |
439 | if (!len) | 433 | if (!len) |
440 | return 0; | 434 | return 0; |
@@ -461,12 +455,14 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, | |||
461 | { | 455 | { |
462 | int start = skb_headlen(skb); | 456 | int start = skb_headlen(skb); |
463 | int i, copy = start - offset; | 457 | int i, copy = start - offset; |
458 | struct sk_buff *frag_iter; | ||
464 | 459 | ||
465 | /* Copy header. */ | 460 | /* Copy header. */ |
466 | if (copy > 0) { | 461 | if (copy > 0) { |
467 | if (copy > len) | 462 | if (copy > len) |
468 | copy = len; | 463 | copy = len; |
469 | if (memcpy_fromiovecend(skb->data + offset, from, 0, copy)) | 464 | if (memcpy_fromiovecend(skb->data + offset, from, from_offset, |
465 | copy)) | ||
470 | goto fault; | 466 | goto fault; |
471 | if ((len -= copy) == 0) | 467 | if ((len -= copy) == 0) |
472 | return 0; | 468 | return 0; |
@@ -505,31 +501,27 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, | |||
505 | start = end; | 501 | start = end; |
506 | } | 502 | } |
507 | 503 | ||
508 | if (skb_shinfo(skb)->frag_list) { | 504 | skb_walk_frags(skb, frag_iter) { |
509 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 505 | int end; |
510 | 506 | ||
511 | for (; list; list = list->next) { | 507 | WARN_ON(start > offset + len); |
512 | int end; | 508 | |
513 | 509 | end = start + frag_iter->len; | |
514 | WARN_ON(start > offset + len); | 510 | if ((copy = end - offset) > 0) { |
515 | 511 | if (copy > len) | |
516 | end = start + list->len; | 512 | copy = len; |
517 | if ((copy = end - offset) > 0) { | 513 | if (skb_copy_datagram_from_iovec(frag_iter, |
518 | if (copy > len) | 514 | offset - start, |
519 | copy = len; | 515 | from, |
520 | if (skb_copy_datagram_from_iovec(list, | 516 | from_offset, |
521 | offset - start, | 517 | copy)) |
522 | from, | 518 | goto fault; |
523 | from_offset, | 519 | if ((len -= copy) == 0) |
524 | copy)) | 520 | return 0; |
525 | goto fault; | 521 | offset += copy; |
526 | if ((len -= copy) == 0) | 522 | from_offset += copy; |
527 | return 0; | ||
528 | offset += copy; | ||
529 | from_offset += copy; | ||
530 | } | ||
531 | start = end; | ||
532 | } | 523 | } |
524 | start = end; | ||
533 | } | 525 | } |
534 | if (!len) | 526 | if (!len) |
535 | return 0; | 527 | return 0; |
@@ -544,8 +536,9 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, | |||
544 | __wsum *csump) | 536 | __wsum *csump) |
545 | { | 537 | { |
546 | int start = skb_headlen(skb); | 538 | int start = skb_headlen(skb); |
547 | int pos = 0; | ||
548 | int i, copy = start - offset; | 539 | int i, copy = start - offset; |
540 | struct sk_buff *frag_iter; | ||
541 | int pos = 0; | ||
549 | 542 | ||
550 | /* Copy header. */ | 543 | /* Copy header. */ |
551 | if (copy > 0) { | 544 | if (copy > 0) { |
@@ -596,33 +589,29 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, | |||
596 | start = end; | 589 | start = end; |
597 | } | 590 | } |
598 | 591 | ||
599 | if (skb_shinfo(skb)->frag_list) { | 592 | skb_walk_frags(skb, frag_iter) { |
600 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 593 | int end; |
601 | 594 | ||
602 | for (; list; list=list->next) { | 595 | WARN_ON(start > offset + len); |
603 | int end; | 596 | |
604 | 597 | end = start + frag_iter->len; | |
605 | WARN_ON(start > offset + len); | 598 | if ((copy = end - offset) > 0) { |
606 | 599 | __wsum csum2 = 0; | |
607 | end = start + list->len; | 600 | if (copy > len) |
608 | if ((copy = end - offset) > 0) { | 601 | copy = len; |
609 | __wsum csum2 = 0; | 602 | if (skb_copy_and_csum_datagram(frag_iter, |
610 | if (copy > len) | 603 | offset - start, |
611 | copy = len; | 604 | to, copy, |
612 | if (skb_copy_and_csum_datagram(list, | 605 | &csum2)) |
613 | offset - start, | 606 | goto fault; |
614 | to, copy, | 607 | *csump = csum_block_add(*csump, csum2, pos); |
615 | &csum2)) | 608 | if ((len -= copy) == 0) |
616 | goto fault; | 609 | return 0; |
617 | *csump = csum_block_add(*csump, csum2, pos); | 610 | offset += copy; |
618 | if ((len -= copy) == 0) | 611 | to += copy; |
619 | return 0; | 612 | pos += copy; |
620 | offset += copy; | ||
621 | to += copy; | ||
622 | pos += copy; | ||
623 | } | ||
624 | start = end; | ||
625 | } | 613 | } |
614 | start = end; | ||
626 | } | 615 | } |
627 | if (!len) | 616 | if (!len) |
628 | return 0; | 617 | return 0; |
diff --git a/net/core/dev.c b/net/core/dev.c index 1f38401fc028..11560e3258b5 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -269,7 +269,8 @@ static const unsigned short netdev_lock_type[] = | |||
269 | ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, | 269 | ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, |
270 | ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211, | 270 | ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211, |
271 | ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, | 271 | ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, |
272 | ARPHRD_PHONET_PIPE, ARPHRD_VOID, ARPHRD_NONE}; | 272 | ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, ARPHRD_IEEE802154_PHY, |
273 | ARPHRD_VOID, ARPHRD_NONE}; | ||
273 | 274 | ||
274 | static const char *netdev_lock_name[] = | 275 | static const char *netdev_lock_name[] = |
275 | {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25", | 276 | {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25", |
@@ -286,7 +287,8 @@ static const char *netdev_lock_name[] = | |||
286 | "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL", | 287 | "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL", |
287 | "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211", | 288 | "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211", |
288 | "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", | 289 | "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", |
289 | "_xmit_PHONET_PIPE", "_xmit_VOID", "_xmit_NONE"}; | 290 | "_xmit_PHONET_PIPE", "_xmit_IEEE802154", "_xmit_IEEE802154_PHY", |
291 | "_xmit_VOID", "_xmit_NONE"}; | ||
290 | 292 | ||
291 | static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; | 293 | static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; |
292 | static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)]; | 294 | static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)]; |
@@ -1820,7 +1822,7 @@ int dev_queue_xmit(struct sk_buff *skb) | |||
1820 | if (netif_needs_gso(dev, skb)) | 1822 | if (netif_needs_gso(dev, skb)) |
1821 | goto gso; | 1823 | goto gso; |
1822 | 1824 | ||
1823 | if (skb_shinfo(skb)->frag_list && | 1825 | if (skb_has_frags(skb) && |
1824 | !(dev->features & NETIF_F_FRAGLIST) && | 1826 | !(dev->features & NETIF_F_FRAGLIST) && |
1825 | __skb_linearize(skb)) | 1827 | __skb_linearize(skb)) |
1826 | goto out_kfree_skb; | 1828 | goto out_kfree_skb; |
@@ -2407,7 +2409,7 @@ int dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
2407 | if (!(skb->dev->features & NETIF_F_GRO)) | 2409 | if (!(skb->dev->features & NETIF_F_GRO)) |
2408 | goto normal; | 2410 | goto normal; |
2409 | 2411 | ||
2410 | if (skb_is_gso(skb) || skb_shinfo(skb)->frag_list) | 2412 | if (skb_is_gso(skb) || skb_has_frags(skb)) |
2411 | goto normal; | 2413 | goto normal; |
2412 | 2414 | ||
2413 | rcu_read_lock(); | 2415 | rcu_read_lock(); |
@@ -3655,8 +3657,8 @@ static int dev_addr_init(struct net_device *dev) | |||
3655 | /* rtnl_mutex must be held here */ | 3657 | /* rtnl_mutex must be held here */ |
3656 | 3658 | ||
3657 | INIT_LIST_HEAD(&dev->dev_addr_list); | 3659 | INIT_LIST_HEAD(&dev->dev_addr_list); |
3658 | memset(addr, 0, sizeof(*addr)); | 3660 | memset(addr, 0, sizeof(addr)); |
3659 | err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, sizeof(*addr), | 3661 | err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, sizeof(addr), |
3660 | NETDEV_HW_ADDR_T_LAN); | 3662 | NETDEV_HW_ADDR_T_LAN); |
3661 | if (!err) { | 3663 | if (!err) { |
3662 | /* | 3664 | /* |
diff --git a/net/core/iovec.c b/net/core/iovec.c index 40a76ce19d9f..16ad45d4882b 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c | |||
@@ -112,9 +112,9 @@ int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata, | |||
112 | continue; | 112 | continue; |
113 | } | 113 | } |
114 | copy = min_t(unsigned int, iov->iov_len - offset, len); | 114 | copy = min_t(unsigned int, iov->iov_len - offset, len); |
115 | offset = 0; | 115 | if (copy_to_user(iov->iov_base + offset, kdata, copy)) |
116 | if (copy_to_user(iov->iov_base, kdata, copy)) | ||
117 | return -EFAULT; | 116 | return -EFAULT; |
117 | offset = 0; | ||
118 | kdata += copy; | 118 | kdata += copy; |
119 | len -= copy; | 119 | len -= copy; |
120 | } | 120 | } |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index c54229befcfe..163b4f5b0365 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -771,6 +771,28 @@ static __inline__ int neigh_max_probes(struct neighbour *n) | |||
771 | p->ucast_probes + p->app_probes + p->mcast_probes); | 771 | p->ucast_probes + p->app_probes + p->mcast_probes); |
772 | } | 772 | } |
773 | 773 | ||
774 | static void neigh_invalidate(struct neighbour *neigh) | ||
775 | { | ||
776 | struct sk_buff *skb; | ||
777 | |||
778 | NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed); | ||
779 | NEIGH_PRINTK2("neigh %p is failed.\n", neigh); | ||
780 | neigh->updated = jiffies; | ||
781 | |||
782 | /* It is very thin place. report_unreachable is very complicated | ||
783 | routine. Particularly, it can hit the same neighbour entry! | ||
784 | |||
785 | So that, we try to be accurate and avoid dead loop. --ANK | ||
786 | */ | ||
787 | while (neigh->nud_state == NUD_FAILED && | ||
788 | (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) { | ||
789 | write_unlock(&neigh->lock); | ||
790 | neigh->ops->error_report(neigh, skb); | ||
791 | write_lock(&neigh->lock); | ||
792 | } | ||
793 | skb_queue_purge(&neigh->arp_queue); | ||
794 | } | ||
795 | |||
774 | /* Called when a timer expires for a neighbour entry. */ | 796 | /* Called when a timer expires for a neighbour entry. */ |
775 | 797 | ||
776 | static void neigh_timer_handler(unsigned long arg) | 798 | static void neigh_timer_handler(unsigned long arg) |
@@ -835,26 +857,9 @@ static void neigh_timer_handler(unsigned long arg) | |||
835 | 857 | ||
836 | if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) && | 858 | if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) && |
837 | atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) { | 859 | atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) { |
838 | struct sk_buff *skb; | ||
839 | |||
840 | neigh->nud_state = NUD_FAILED; | 860 | neigh->nud_state = NUD_FAILED; |
841 | neigh->updated = jiffies; | ||
842 | notify = 1; | 861 | notify = 1; |
843 | NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed); | 862 | neigh_invalidate(neigh); |
844 | NEIGH_PRINTK2("neigh %p is failed.\n", neigh); | ||
845 | |||
846 | /* It is very thin place. report_unreachable is very complicated | ||
847 | routine. Particularly, it can hit the same neighbour entry! | ||
848 | |||
849 | So that, we try to be accurate and avoid dead loop. --ANK | ||
850 | */ | ||
851 | while (neigh->nud_state == NUD_FAILED && | ||
852 | (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) { | ||
853 | write_unlock(&neigh->lock); | ||
854 | neigh->ops->error_report(neigh, skb); | ||
855 | write_lock(&neigh->lock); | ||
856 | } | ||
857 | skb_queue_purge(&neigh->arp_queue); | ||
858 | } | 863 | } |
859 | 864 | ||
860 | if (neigh->nud_state & NUD_IN_TIMER) { | 865 | if (neigh->nud_state & NUD_IN_TIMER) { |
@@ -1001,6 +1006,11 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, | |||
1001 | neigh->nud_state = new; | 1006 | neigh->nud_state = new; |
1002 | err = 0; | 1007 | err = 0; |
1003 | notify = old & NUD_VALID; | 1008 | notify = old & NUD_VALID; |
1009 | if ((old & (NUD_INCOMPLETE | NUD_PROBE)) && | ||
1010 | (new & NUD_FAILED)) { | ||
1011 | neigh_invalidate(neigh); | ||
1012 | notify = 1; | ||
1013 | } | ||
1004 | goto out; | 1014 | goto out; |
1005 | } | 1015 | } |
1006 | 1016 | ||
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index b8ccd3c88d63..19b8c20e98a4 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -3691,8 +3691,7 @@ out1: | |||
3691 | #ifdef CONFIG_XFRM | 3691 | #ifdef CONFIG_XFRM |
3692 | free_SAs(pkt_dev); | 3692 | free_SAs(pkt_dev); |
3693 | #endif | 3693 | #endif |
3694 | if (pkt_dev->flows) | 3694 | vfree(pkt_dev->flows); |
3695 | vfree(pkt_dev->flows); | ||
3696 | kfree(pkt_dev); | 3695 | kfree(pkt_dev); |
3697 | return err; | 3696 | return err; |
3698 | } | 3697 | } |
@@ -3791,8 +3790,7 @@ static int pktgen_remove_device(struct pktgen_thread *t, | |||
3791 | #ifdef CONFIG_XFRM | 3790 | #ifdef CONFIG_XFRM |
3792 | free_SAs(pkt_dev); | 3791 | free_SAs(pkt_dev); |
3793 | #endif | 3792 | #endif |
3794 | if (pkt_dev->flows) | 3793 | vfree(pkt_dev->flows); |
3795 | vfree(pkt_dev->flows); | ||
3796 | kfree(pkt_dev); | 3794 | kfree(pkt_dev); |
3797 | return 0; | 3795 | return 0; |
3798 | } | 3796 | } |
diff --git a/net/core/skb_dma_map.c b/net/core/skb_dma_map.c index 86234923a3b7..79687dfd6957 100644 --- a/net/core/skb_dma_map.c +++ b/net/core/skb_dma_map.c | |||
@@ -20,7 +20,7 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb, | |||
20 | if (dma_mapping_error(dev, map)) | 20 | if (dma_mapping_error(dev, map)) |
21 | goto out_err; | 21 | goto out_err; |
22 | 22 | ||
23 | sp->dma_maps[0] = map; | 23 | sp->dma_head = map; |
24 | for (i = 0; i < sp->nr_frags; i++) { | 24 | for (i = 0; i < sp->nr_frags; i++) { |
25 | skb_frag_t *fp = &sp->frags[i]; | 25 | skb_frag_t *fp = &sp->frags[i]; |
26 | 26 | ||
@@ -28,9 +28,8 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb, | |||
28 | fp->size, dir); | 28 | fp->size, dir); |
29 | if (dma_mapping_error(dev, map)) | 29 | if (dma_mapping_error(dev, map)) |
30 | goto unwind; | 30 | goto unwind; |
31 | sp->dma_maps[i + 1] = map; | 31 | sp->dma_maps[i] = map; |
32 | } | 32 | } |
33 | sp->num_dma_maps = i + 1; | ||
34 | 33 | ||
35 | return 0; | 34 | return 0; |
36 | 35 | ||
@@ -38,10 +37,10 @@ unwind: | |||
38 | while (--i >= 0) { | 37 | while (--i >= 0) { |
39 | skb_frag_t *fp = &sp->frags[i]; | 38 | skb_frag_t *fp = &sp->frags[i]; |
40 | 39 | ||
41 | dma_unmap_page(dev, sp->dma_maps[i + 1], | 40 | dma_unmap_page(dev, sp->dma_maps[i], |
42 | fp->size, dir); | 41 | fp->size, dir); |
43 | } | 42 | } |
44 | dma_unmap_single(dev, sp->dma_maps[0], | 43 | dma_unmap_single(dev, sp->dma_head, |
45 | skb_headlen(skb), dir); | 44 | skb_headlen(skb), dir); |
46 | out_err: | 45 | out_err: |
47 | return -ENOMEM; | 46 | return -ENOMEM; |
@@ -54,12 +53,12 @@ void skb_dma_unmap(struct device *dev, struct sk_buff *skb, | |||
54 | struct skb_shared_info *sp = skb_shinfo(skb); | 53 | struct skb_shared_info *sp = skb_shinfo(skb); |
55 | int i; | 54 | int i; |
56 | 55 | ||
57 | dma_unmap_single(dev, sp->dma_maps[0], | 56 | dma_unmap_single(dev, sp->dma_head, |
58 | skb_headlen(skb), dir); | 57 | skb_headlen(skb), dir); |
59 | for (i = 0; i < sp->nr_frags; i++) { | 58 | for (i = 0; i < sp->nr_frags; i++) { |
60 | skb_frag_t *fp = &sp->frags[i]; | 59 | skb_frag_t *fp = &sp->frags[i]; |
61 | 60 | ||
62 | dma_unmap_page(dev, sp->dma_maps[i + 1], | 61 | dma_unmap_page(dev, sp->dma_maps[i], |
63 | fp->size, dir); | 62 | fp->size, dir); |
64 | } | 63 | } |
65 | } | 64 | } |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 6adf19ec95cc..b94d777e3eb4 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -210,7 +210,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
210 | shinfo->gso_type = 0; | 210 | shinfo->gso_type = 0; |
211 | shinfo->ip6_frag_id = 0; | 211 | shinfo->ip6_frag_id = 0; |
212 | shinfo->tx_flags.flags = 0; | 212 | shinfo->tx_flags.flags = 0; |
213 | shinfo->frag_list = NULL; | 213 | skb_frag_list_init(skb); |
214 | memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); | 214 | memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); |
215 | 215 | ||
216 | if (fclone) { | 216 | if (fclone) { |
@@ -323,7 +323,7 @@ static void skb_clone_fraglist(struct sk_buff *skb) | |||
323 | { | 323 | { |
324 | struct sk_buff *list; | 324 | struct sk_buff *list; |
325 | 325 | ||
326 | for (list = skb_shinfo(skb)->frag_list; list; list = list->next) | 326 | skb_walk_frags(skb, list) |
327 | skb_get(list); | 327 | skb_get(list); |
328 | } | 328 | } |
329 | 329 | ||
@@ -338,7 +338,7 @@ static void skb_release_data(struct sk_buff *skb) | |||
338 | put_page(skb_shinfo(skb)->frags[i].page); | 338 | put_page(skb_shinfo(skb)->frags[i].page); |
339 | } | 339 | } |
340 | 340 | ||
341 | if (skb_shinfo(skb)->frag_list) | 341 | if (skb_has_frags(skb)) |
342 | skb_drop_fraglist(skb); | 342 | skb_drop_fraglist(skb); |
343 | 343 | ||
344 | kfree(skb->head); | 344 | kfree(skb->head); |
@@ -503,7 +503,7 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size) | |||
503 | shinfo->gso_type = 0; | 503 | shinfo->gso_type = 0; |
504 | shinfo->ip6_frag_id = 0; | 504 | shinfo->ip6_frag_id = 0; |
505 | shinfo->tx_flags.flags = 0; | 505 | shinfo->tx_flags.flags = 0; |
506 | shinfo->frag_list = NULL; | 506 | skb_frag_list_init(skb); |
507 | memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); | 507 | memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); |
508 | 508 | ||
509 | memset(skb, 0, offsetof(struct sk_buff, tail)); | 509 | memset(skb, 0, offsetof(struct sk_buff, tail)); |
@@ -552,7 +552,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
552 | new->vlan_tci = old->vlan_tci; | 552 | new->vlan_tci = old->vlan_tci; |
553 | #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) | 553 | #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) |
554 | new->do_not_encrypt = old->do_not_encrypt; | 554 | new->do_not_encrypt = old->do_not_encrypt; |
555 | new->requeue = old->requeue; | ||
556 | #endif | 555 | #endif |
557 | 556 | ||
558 | skb_copy_secmark(new, old); | 557 | skb_copy_secmark(new, old); |
@@ -758,7 +757,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) | |||
758 | skb_shinfo(n)->nr_frags = i; | 757 | skb_shinfo(n)->nr_frags = i; |
759 | } | 758 | } |
760 | 759 | ||
761 | if (skb_shinfo(skb)->frag_list) { | 760 | if (skb_has_frags(skb)) { |
762 | skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list; | 761 | skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list; |
763 | skb_clone_fraglist(n); | 762 | skb_clone_fraglist(n); |
764 | } | 763 | } |
@@ -821,7 +820,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
821 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | 820 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) |
822 | get_page(skb_shinfo(skb)->frags[i].page); | 821 | get_page(skb_shinfo(skb)->frags[i].page); |
823 | 822 | ||
824 | if (skb_shinfo(skb)->frag_list) | 823 | if (skb_has_frags(skb)) |
825 | skb_clone_fraglist(skb); | 824 | skb_clone_fraglist(skb); |
826 | 825 | ||
827 | skb_release_data(skb); | 826 | skb_release_data(skb); |
@@ -1093,7 +1092,7 @@ drop_pages: | |||
1093 | for (; i < nfrags; i++) | 1092 | for (; i < nfrags; i++) |
1094 | put_page(skb_shinfo(skb)->frags[i].page); | 1093 | put_page(skb_shinfo(skb)->frags[i].page); |
1095 | 1094 | ||
1096 | if (skb_shinfo(skb)->frag_list) | 1095 | if (skb_has_frags(skb)) |
1097 | skb_drop_fraglist(skb); | 1096 | skb_drop_fraglist(skb); |
1098 | goto done; | 1097 | goto done; |
1099 | } | 1098 | } |
@@ -1188,7 +1187,7 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta) | |||
1188 | /* Optimization: no fragments, no reasons to preestimate | 1187 | /* Optimization: no fragments, no reasons to preestimate |
1189 | * size of pulled pages. Superb. | 1188 | * size of pulled pages. Superb. |
1190 | */ | 1189 | */ |
1191 | if (!skb_shinfo(skb)->frag_list) | 1190 | if (!skb_has_frags(skb)) |
1192 | goto pull_pages; | 1191 | goto pull_pages; |
1193 | 1192 | ||
1194 | /* Estimate size of pulled pages. */ | 1193 | /* Estimate size of pulled pages. */ |
@@ -1285,8 +1284,9 @@ EXPORT_SYMBOL(__pskb_pull_tail); | |||
1285 | 1284 | ||
1286 | int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) | 1285 | int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) |
1287 | { | 1286 | { |
1288 | int i, copy; | ||
1289 | int start = skb_headlen(skb); | 1287 | int start = skb_headlen(skb); |
1288 | struct sk_buff *frag_iter; | ||
1289 | int i, copy; | ||
1290 | 1290 | ||
1291 | if (offset > (int)skb->len - len) | 1291 | if (offset > (int)skb->len - len) |
1292 | goto fault; | 1292 | goto fault; |
@@ -1328,28 +1328,23 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) | |||
1328 | start = end; | 1328 | start = end; |
1329 | } | 1329 | } |
1330 | 1330 | ||
1331 | if (skb_shinfo(skb)->frag_list) { | 1331 | skb_walk_frags(skb, frag_iter) { |
1332 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 1332 | int end; |
1333 | 1333 | ||
1334 | for (; list; list = list->next) { | 1334 | WARN_ON(start > offset + len); |
1335 | int end; | 1335 | |
1336 | 1336 | end = start + frag_iter->len; | |
1337 | WARN_ON(start > offset + len); | 1337 | if ((copy = end - offset) > 0) { |
1338 | 1338 | if (copy > len) | |
1339 | end = start + list->len; | 1339 | copy = len; |
1340 | if ((copy = end - offset) > 0) { | 1340 | if (skb_copy_bits(frag_iter, offset - start, to, copy)) |
1341 | if (copy > len) | 1341 | goto fault; |
1342 | copy = len; | 1342 | if ((len -= copy) == 0) |
1343 | if (skb_copy_bits(list, offset - start, | 1343 | return 0; |
1344 | to, copy)) | 1344 | offset += copy; |
1345 | goto fault; | 1345 | to += copy; |
1346 | if ((len -= copy) == 0) | ||
1347 | return 0; | ||
1348 | offset += copy; | ||
1349 | to += copy; | ||
1350 | } | ||
1351 | start = end; | ||
1352 | } | 1346 | } |
1347 | start = end; | ||
1353 | } | 1348 | } |
1354 | if (!len) | 1349 | if (!len) |
1355 | return 0; | 1350 | return 0; |
@@ -1534,6 +1529,7 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset, | |||
1534 | .ops = &sock_pipe_buf_ops, | 1529 | .ops = &sock_pipe_buf_ops, |
1535 | .spd_release = sock_spd_release, | 1530 | .spd_release = sock_spd_release, |
1536 | }; | 1531 | }; |
1532 | struct sk_buff *frag_iter; | ||
1537 | struct sock *sk = skb->sk; | 1533 | struct sock *sk = skb->sk; |
1538 | 1534 | ||
1539 | /* | 1535 | /* |
@@ -1548,13 +1544,11 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset, | |||
1548 | /* | 1544 | /* |
1549 | * now see if we have a frag_list to map | 1545 | * now see if we have a frag_list to map |
1550 | */ | 1546 | */ |
1551 | if (skb_shinfo(skb)->frag_list) { | 1547 | skb_walk_frags(skb, frag_iter) { |
1552 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 1548 | if (!tlen) |
1553 | 1549 | break; | |
1554 | for (; list && tlen; list = list->next) { | 1550 | if (__skb_splice_bits(frag_iter, &offset, &tlen, &spd, sk)) |
1555 | if (__skb_splice_bits(list, &offset, &tlen, &spd, sk)) | 1551 | break; |
1556 | break; | ||
1557 | } | ||
1558 | } | 1552 | } |
1559 | 1553 | ||
1560 | done: | 1554 | done: |
@@ -1593,8 +1587,9 @@ done: | |||
1593 | 1587 | ||
1594 | int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) | 1588 | int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) |
1595 | { | 1589 | { |
1596 | int i, copy; | ||
1597 | int start = skb_headlen(skb); | 1590 | int start = skb_headlen(skb); |
1591 | struct sk_buff *frag_iter; | ||
1592 | int i, copy; | ||
1598 | 1593 | ||
1599 | if (offset > (int)skb->len - len) | 1594 | if (offset > (int)skb->len - len) |
1600 | goto fault; | 1595 | goto fault; |
@@ -1635,28 +1630,24 @@ int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) | |||
1635 | start = end; | 1630 | start = end; |
1636 | } | 1631 | } |
1637 | 1632 | ||
1638 | if (skb_shinfo(skb)->frag_list) { | 1633 | skb_walk_frags(skb, frag_iter) { |
1639 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 1634 | int end; |
1640 | 1635 | ||
1641 | for (; list; list = list->next) { | 1636 | WARN_ON(start > offset + len); |
1642 | int end; | 1637 | |
1643 | 1638 | end = start + frag_iter->len; | |
1644 | WARN_ON(start > offset + len); | 1639 | if ((copy = end - offset) > 0) { |
1645 | 1640 | if (copy > len) | |
1646 | end = start + list->len; | 1641 | copy = len; |
1647 | if ((copy = end - offset) > 0) { | 1642 | if (skb_store_bits(frag_iter, offset - start, |
1648 | if (copy > len) | 1643 | from, copy)) |
1649 | copy = len; | 1644 | goto fault; |
1650 | if (skb_store_bits(list, offset - start, | 1645 | if ((len -= copy) == 0) |
1651 | from, copy)) | 1646 | return 0; |
1652 | goto fault; | 1647 | offset += copy; |
1653 | if ((len -= copy) == 0) | 1648 | from += copy; |
1654 | return 0; | ||
1655 | offset += copy; | ||
1656 | from += copy; | ||
1657 | } | ||
1658 | start = end; | ||
1659 | } | 1649 | } |
1650 | start = end; | ||
1660 | } | 1651 | } |
1661 | if (!len) | 1652 | if (!len) |
1662 | return 0; | 1653 | return 0; |
@@ -1673,6 +1664,7 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, | |||
1673 | { | 1664 | { |
1674 | int start = skb_headlen(skb); | 1665 | int start = skb_headlen(skb); |
1675 | int i, copy = start - offset; | 1666 | int i, copy = start - offset; |
1667 | struct sk_buff *frag_iter; | ||
1676 | int pos = 0; | 1668 | int pos = 0; |
1677 | 1669 | ||
1678 | /* Checksum header. */ | 1670 | /* Checksum header. */ |
@@ -1712,29 +1704,25 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, | |||
1712 | start = end; | 1704 | start = end; |
1713 | } | 1705 | } |
1714 | 1706 | ||
1715 | if (skb_shinfo(skb)->frag_list) { | 1707 | skb_walk_frags(skb, frag_iter) { |
1716 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 1708 | int end; |
1717 | 1709 | ||
1718 | for (; list; list = list->next) { | 1710 | WARN_ON(start > offset + len); |
1719 | int end; | 1711 | |
1720 | 1712 | end = start + frag_iter->len; | |
1721 | WARN_ON(start > offset + len); | 1713 | if ((copy = end - offset) > 0) { |
1722 | 1714 | __wsum csum2; | |
1723 | end = start + list->len; | 1715 | if (copy > len) |
1724 | if ((copy = end - offset) > 0) { | 1716 | copy = len; |
1725 | __wsum csum2; | 1717 | csum2 = skb_checksum(frag_iter, offset - start, |
1726 | if (copy > len) | 1718 | copy, 0); |
1727 | copy = len; | 1719 | csum = csum_block_add(csum, csum2, pos); |
1728 | csum2 = skb_checksum(list, offset - start, | 1720 | if ((len -= copy) == 0) |
1729 | copy, 0); | 1721 | return csum; |
1730 | csum = csum_block_add(csum, csum2, pos); | 1722 | offset += copy; |
1731 | if ((len -= copy) == 0) | 1723 | pos += copy; |
1732 | return csum; | ||
1733 | offset += copy; | ||
1734 | pos += copy; | ||
1735 | } | ||
1736 | start = end; | ||
1737 | } | 1724 | } |
1725 | start = end; | ||
1738 | } | 1726 | } |
1739 | BUG_ON(len); | 1727 | BUG_ON(len); |
1740 | 1728 | ||
@@ -1749,6 +1737,7 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, | |||
1749 | { | 1737 | { |
1750 | int start = skb_headlen(skb); | 1738 | int start = skb_headlen(skb); |
1751 | int i, copy = start - offset; | 1739 | int i, copy = start - offset; |
1740 | struct sk_buff *frag_iter; | ||
1752 | int pos = 0; | 1741 | int pos = 0; |
1753 | 1742 | ||
1754 | /* Copy header. */ | 1743 | /* Copy header. */ |
@@ -1793,31 +1782,27 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, | |||
1793 | start = end; | 1782 | start = end; |
1794 | } | 1783 | } |
1795 | 1784 | ||
1796 | if (skb_shinfo(skb)->frag_list) { | 1785 | skb_walk_frags(skb, frag_iter) { |
1797 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 1786 | __wsum csum2; |
1787 | int end; | ||
1798 | 1788 | ||
1799 | for (; list; list = list->next) { | 1789 | WARN_ON(start > offset + len); |
1800 | __wsum csum2; | 1790 | |
1801 | int end; | 1791 | end = start + frag_iter->len; |
1802 | 1792 | if ((copy = end - offset) > 0) { | |
1803 | WARN_ON(start > offset + len); | 1793 | if (copy > len) |
1804 | 1794 | copy = len; | |
1805 | end = start + list->len; | 1795 | csum2 = skb_copy_and_csum_bits(frag_iter, |
1806 | if ((copy = end - offset) > 0) { | 1796 | offset - start, |
1807 | if (copy > len) | 1797 | to, copy, 0); |
1808 | copy = len; | 1798 | csum = csum_block_add(csum, csum2, pos); |
1809 | csum2 = skb_copy_and_csum_bits(list, | 1799 | if ((len -= copy) == 0) |
1810 | offset - start, | 1800 | return csum; |
1811 | to, copy, 0); | 1801 | offset += copy; |
1812 | csum = csum_block_add(csum, csum2, pos); | 1802 | to += copy; |
1813 | if ((len -= copy) == 0) | 1803 | pos += copy; |
1814 | return csum; | ||
1815 | offset += copy; | ||
1816 | to += copy; | ||
1817 | pos += copy; | ||
1818 | } | ||
1819 | start = end; | ||
1820 | } | 1804 | } |
1805 | start = end; | ||
1821 | } | 1806 | } |
1822 | BUG_ON(len); | 1807 | BUG_ON(len); |
1823 | return csum; | 1808 | return csum; |
@@ -2327,8 +2312,7 @@ next_skb: | |||
2327 | st->frag_data = NULL; | 2312 | st->frag_data = NULL; |
2328 | } | 2313 | } |
2329 | 2314 | ||
2330 | if (st->root_skb == st->cur_skb && | 2315 | if (st->root_skb == st->cur_skb && skb_has_frags(st->root_skb)) { |
2331 | skb_shinfo(st->root_skb)->frag_list) { | ||
2332 | st->cur_skb = skb_shinfo(st->root_skb)->frag_list; | 2316 | st->cur_skb = skb_shinfo(st->root_skb)->frag_list; |
2333 | st->frag_idx = 0; | 2317 | st->frag_idx = 0; |
2334 | goto next_skb; | 2318 | goto next_skb; |
@@ -2639,7 +2623,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) | |||
2639 | } else | 2623 | } else |
2640 | skb_get(fskb2); | 2624 | skb_get(fskb2); |
2641 | 2625 | ||
2642 | BUG_ON(skb_shinfo(nskb)->frag_list); | 2626 | SKB_FRAG_ASSERT(nskb); |
2643 | skb_shinfo(nskb)->frag_list = fskb2; | 2627 | skb_shinfo(nskb)->frag_list = fskb2; |
2644 | } | 2628 | } |
2645 | 2629 | ||
@@ -2796,6 +2780,7 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) | |||
2796 | { | 2780 | { |
2797 | int start = skb_headlen(skb); | 2781 | int start = skb_headlen(skb); |
2798 | int i, copy = start - offset; | 2782 | int i, copy = start - offset; |
2783 | struct sk_buff *frag_iter; | ||
2799 | int elt = 0; | 2784 | int elt = 0; |
2800 | 2785 | ||
2801 | if (copy > 0) { | 2786 | if (copy > 0) { |
@@ -2829,26 +2814,22 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) | |||
2829 | start = end; | 2814 | start = end; |
2830 | } | 2815 | } |
2831 | 2816 | ||
2832 | if (skb_shinfo(skb)->frag_list) { | 2817 | skb_walk_frags(skb, frag_iter) { |
2833 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 2818 | int end; |
2834 | |||
2835 | for (; list; list = list->next) { | ||
2836 | int end; | ||
2837 | 2819 | ||
2838 | WARN_ON(start > offset + len); | 2820 | WARN_ON(start > offset + len); |
2839 | 2821 | ||
2840 | end = start + list->len; | 2822 | end = start + frag_iter->len; |
2841 | if ((copy = end - offset) > 0) { | 2823 | if ((copy = end - offset) > 0) { |
2842 | if (copy > len) | 2824 | if (copy > len) |
2843 | copy = len; | 2825 | copy = len; |
2844 | elt += __skb_to_sgvec(list, sg+elt, offset - start, | 2826 | elt += __skb_to_sgvec(frag_iter, sg+elt, offset - start, |
2845 | copy); | 2827 | copy); |
2846 | if ((len -= copy) == 0) | 2828 | if ((len -= copy) == 0) |
2847 | return elt; | 2829 | return elt; |
2848 | offset += copy; | 2830 | offset += copy; |
2849 | } | ||
2850 | start = end; | ||
2851 | } | 2831 | } |
2832 | start = end; | ||
2852 | } | 2833 | } |
2853 | BUG_ON(len); | 2834 | BUG_ON(len); |
2854 | return elt; | 2835 | return elt; |
@@ -2896,7 +2877,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) | |||
2896 | return -ENOMEM; | 2877 | return -ENOMEM; |
2897 | 2878 | ||
2898 | /* Easy case. Most of packets will go this way. */ | 2879 | /* Easy case. Most of packets will go this way. */ |
2899 | if (!skb_shinfo(skb)->frag_list) { | 2880 | if (!skb_has_frags(skb)) { |
2900 | /* A little of trouble, not enough of space for trailer. | 2881 | /* A little of trouble, not enough of space for trailer. |
2901 | * This should not happen, when stack is tuned to generate | 2882 | * This should not happen, when stack is tuned to generate |
2902 | * good frames. OK, on miss we reallocate and reserve even more | 2883 | * good frames. OK, on miss we reallocate and reserve even more |
@@ -2931,7 +2912,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) | |||
2931 | 2912 | ||
2932 | if (skb1->next == NULL && tailbits) { | 2913 | if (skb1->next == NULL && tailbits) { |
2933 | if (skb_shinfo(skb1)->nr_frags || | 2914 | if (skb_shinfo(skb1)->nr_frags || |
2934 | skb_shinfo(skb1)->frag_list || | 2915 | skb_has_frags(skb1) || |
2935 | skb_tailroom(skb1) < tailbits) | 2916 | skb_tailroom(skb1) < tailbits) |
2936 | ntail = tailbits + 128; | 2917 | ntail = tailbits + 128; |
2937 | } | 2918 | } |
@@ -2940,7 +2921,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) | |||
2940 | skb_cloned(skb1) || | 2921 | skb_cloned(skb1) || |
2941 | ntail || | 2922 | ntail || |
2942 | skb_shinfo(skb1)->nr_frags || | 2923 | skb_shinfo(skb1)->nr_frags || |
2943 | skb_shinfo(skb1)->frag_list) { | 2924 | skb_has_frags(skb1)) { |
2944 | struct sk_buff *skb2; | 2925 | struct sk_buff *skb2; |
2945 | 2926 | ||
2946 | /* Fuck, we are miserable poor guys... */ | 2927 | /* Fuck, we are miserable poor guys... */ |
@@ -3026,12 +3007,12 @@ EXPORT_SYMBOL_GPL(skb_tstamp_tx); | |||
3026 | */ | 3007 | */ |
3027 | bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off) | 3008 | bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off) |
3028 | { | 3009 | { |
3029 | if (unlikely(start > skb->len - 2) || | 3010 | if (unlikely(start > skb_headlen(skb)) || |
3030 | unlikely((int)start + off > skb->len - 2)) { | 3011 | unlikely((int)start + off > skb_headlen(skb) - 2)) { |
3031 | if (net_ratelimit()) | 3012 | if (net_ratelimit()) |
3032 | printk(KERN_WARNING | 3013 | printk(KERN_WARNING |
3033 | "bad partial csum: csum=%u/%u len=%u\n", | 3014 | "bad partial csum: csum=%u/%u len=%u\n", |
3034 | start, off, skb->len); | 3015 | start, off, skb_headlen(skb)); |
3035 | return false; | 3016 | return false; |
3036 | } | 3017 | } |
3037 | skb->ip_summed = CHECKSUM_PARTIAL; | 3018 | skb->ip_summed = CHECKSUM_PARTIAL; |
diff --git a/net/core/sock.c b/net/core/sock.c index 58dec9dff99a..06e26b77ad9e 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -155,6 +155,7 @@ static const char *af_family_key_strings[AF_MAX+1] = { | |||
155 | "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , | 155 | "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , |
156 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , | 156 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , |
157 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , | 157 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , |
158 | "sk_lock-AF_IEEE802154", | ||
158 | "sk_lock-AF_MAX" | 159 | "sk_lock-AF_MAX" |
159 | }; | 160 | }; |
160 | static const char *af_family_slock_key_strings[AF_MAX+1] = { | 161 | static const char *af_family_slock_key_strings[AF_MAX+1] = { |
@@ -170,6 +171,7 @@ static const char *af_family_slock_key_strings[AF_MAX+1] = { | |||
170 | "slock-27" , "slock-28" , "slock-AF_CAN" , | 171 | "slock-27" , "slock-28" , "slock-AF_CAN" , |
171 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , | 172 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , |
172 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , | 173 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , |
174 | "slock-AF_IEEE802154", | ||
173 | "slock-AF_MAX" | 175 | "slock-AF_MAX" |
174 | }; | 176 | }; |
175 | static const char *af_family_clock_key_strings[AF_MAX+1] = { | 177 | static const char *af_family_clock_key_strings[AF_MAX+1] = { |
@@ -185,6 +187,7 @@ static const char *af_family_clock_key_strings[AF_MAX+1] = { | |||
185 | "clock-27" , "clock-28" , "clock-AF_CAN" , | 187 | "clock-27" , "clock-28" , "clock-AF_CAN" , |
186 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , | 188 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , |
187 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , | 189 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , |
190 | "clock-AF_IEEE802154", | ||
188 | "clock-AF_MAX" | 191 | "clock-AF_MAX" |
189 | }; | 192 | }; |
190 | 193 | ||
@@ -1005,7 +1008,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, | |||
1005 | } | 1008 | } |
1006 | EXPORT_SYMBOL(sk_alloc); | 1009 | EXPORT_SYMBOL(sk_alloc); |
1007 | 1010 | ||
1008 | void sk_free(struct sock *sk) | 1011 | static void __sk_free(struct sock *sk) |
1009 | { | 1012 | { |
1010 | struct sk_filter *filter; | 1013 | struct sk_filter *filter; |
1011 | 1014 | ||
@@ -1028,6 +1031,17 @@ void sk_free(struct sock *sk) | |||
1028 | put_net(sock_net(sk)); | 1031 | put_net(sock_net(sk)); |
1029 | sk_prot_free(sk->sk_prot_creator, sk); | 1032 | sk_prot_free(sk->sk_prot_creator, sk); |
1030 | } | 1033 | } |
1034 | |||
1035 | void sk_free(struct sock *sk) | ||
1036 | { | ||
1037 | /* | ||
1038 | * We substract one from sk_wmem_alloc and can know if | ||
1039 | * some packets are still in some tx queue. | ||
1040 | * If not null, sock_wfree() will call __sk_free(sk) later | ||
1041 | */ | ||
1042 | if (atomic_dec_and_test(&sk->sk_wmem_alloc)) | ||
1043 | __sk_free(sk); | ||
1044 | } | ||
1031 | EXPORT_SYMBOL(sk_free); | 1045 | EXPORT_SYMBOL(sk_free); |
1032 | 1046 | ||
1033 | /* | 1047 | /* |
@@ -1068,7 +1082,10 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | |||
1068 | newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; | 1082 | newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; |
1069 | 1083 | ||
1070 | atomic_set(&newsk->sk_rmem_alloc, 0); | 1084 | atomic_set(&newsk->sk_rmem_alloc, 0); |
1071 | atomic_set(&newsk->sk_wmem_alloc, 0); | 1085 | /* |
1086 | * sk_wmem_alloc set to one (see sk_free() and sock_wfree()) | ||
1087 | */ | ||
1088 | atomic_set(&newsk->sk_wmem_alloc, 1); | ||
1072 | atomic_set(&newsk->sk_omem_alloc, 0); | 1089 | atomic_set(&newsk->sk_omem_alloc, 0); |
1073 | skb_queue_head_init(&newsk->sk_receive_queue); | 1090 | skb_queue_head_init(&newsk->sk_receive_queue); |
1074 | skb_queue_head_init(&newsk->sk_write_queue); | 1091 | skb_queue_head_init(&newsk->sk_write_queue); |
@@ -1172,12 +1189,18 @@ void __init sk_init(void) | |||
1172 | void sock_wfree(struct sk_buff *skb) | 1189 | void sock_wfree(struct sk_buff *skb) |
1173 | { | 1190 | { |
1174 | struct sock *sk = skb->sk; | 1191 | struct sock *sk = skb->sk; |
1192 | int res; | ||
1175 | 1193 | ||
1176 | /* In case it might be waiting for more memory. */ | 1194 | /* In case it might be waiting for more memory. */ |
1177 | atomic_sub(skb->truesize, &sk->sk_wmem_alloc); | 1195 | res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc); |
1178 | if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) | 1196 | if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) |
1179 | sk->sk_write_space(sk); | 1197 | sk->sk_write_space(sk); |
1180 | sock_put(sk); | 1198 | /* |
1199 | * if sk_wmem_alloc reached 0, we are last user and should | ||
1200 | * free this sock, as sk_free() call could not do it. | ||
1201 | */ | ||
1202 | if (res == 0) | ||
1203 | __sk_free(sk); | ||
1181 | } | 1204 | } |
1182 | EXPORT_SYMBOL(sock_wfree); | 1205 | EXPORT_SYMBOL(sock_wfree); |
1183 | 1206 | ||
@@ -1816,6 +1839,7 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
1816 | sk->sk_stamp = ktime_set(-1L, 0); | 1839 | sk->sk_stamp = ktime_set(-1L, 0); |
1817 | 1840 | ||
1818 | atomic_set(&sk->sk_refcnt, 1); | 1841 | atomic_set(&sk->sk_refcnt, 1); |
1842 | atomic_set(&sk->sk_wmem_alloc, 1); | ||
1819 | atomic_set(&sk->sk_drops, 0); | 1843 | atomic_set(&sk->sk_drops, 0); |
1820 | } | 1844 | } |
1821 | EXPORT_SYMBOL(sock_init_data); | 1845 | EXPORT_SYMBOL(sock_init_data); |
diff --git a/net/core/user_dma.c b/net/core/user_dma.c index 164b090d5ac3..25d717ebc92e 100644 --- a/net/core/user_dma.c +++ b/net/core/user_dma.c | |||
@@ -51,6 +51,7 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan, | |||
51 | { | 51 | { |
52 | int start = skb_headlen(skb); | 52 | int start = skb_headlen(skb); |
53 | int i, copy = start - offset; | 53 | int i, copy = start - offset; |
54 | struct sk_buff *frag_iter; | ||
54 | dma_cookie_t cookie = 0; | 55 | dma_cookie_t cookie = 0; |
55 | 56 | ||
56 | /* Copy header. */ | 57 | /* Copy header. */ |
@@ -94,31 +95,28 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan, | |||
94 | start = end; | 95 | start = end; |
95 | } | 96 | } |
96 | 97 | ||
97 | if (skb_shinfo(skb)->frag_list) { | 98 | skb_walk_frags(skb, frag_iter) { |
98 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 99 | int end; |
99 | 100 | ||
100 | for (; list; list = list->next) { | 101 | WARN_ON(start > offset + len); |
101 | int end; | 102 | |
102 | 103 | end = start + frag_iter->len; | |
103 | WARN_ON(start > offset + len); | 104 | copy = end - offset; |
104 | 105 | if (copy > 0) { | |
105 | end = start + list->len; | 106 | if (copy > len) |
106 | copy = end - offset; | 107 | copy = len; |
107 | if (copy > 0) { | 108 | cookie = dma_skb_copy_datagram_iovec(chan, frag_iter, |
108 | if (copy > len) | 109 | offset - start, |
109 | copy = len; | 110 | to, copy, |
110 | cookie = dma_skb_copy_datagram_iovec(chan, list, | 111 | pinned_list); |
111 | offset - start, to, copy, | 112 | if (cookie < 0) |
112 | pinned_list); | 113 | goto fault; |
113 | if (cookie < 0) | 114 | len -= copy; |
114 | goto fault; | 115 | if (len == 0) |
115 | len -= copy; | 116 | goto end; |
116 | if (len == 0) | 117 | offset += copy; |
117 | goto end; | ||
118 | offset += copy; | ||
119 | } | ||
120 | start = end; | ||
121 | } | 118 | } |
119 | start = end; | ||
122 | } | 120 | } |
123 | 121 | ||
124 | end: | 122 | end: |
diff --git a/net/ieee802154/Kconfig b/net/ieee802154/Kconfig new file mode 100644 index 000000000000..1c1de97d264a --- /dev/null +++ b/net/ieee802154/Kconfig | |||
@@ -0,0 +1,12 @@ | |||
1 | config IEEE802154 | ||
2 | tristate "IEEE Std 802.15.4 Low-Rate Wireless Personal Area Networks support (EXPERIMENTAL)" | ||
3 | depends on EXPERIMENTAL | ||
4 | ---help--- | ||
5 | IEEE Std 802.15.4 defines a low data rate, low power and low | ||
6 | complexity short range wireless personal area networks. It was | ||
7 | designed to organise networks of sensors, switches, etc automation | ||
8 | devices. Maximum allowed data rate is 250 kb/s and typical personal | ||
9 | operating space around 10m. | ||
10 | |||
11 | Say Y here to compile LR-WPAN support into the kernel or say M to | ||
12 | compile it as modules. | ||
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile new file mode 100644 index 000000000000..f99338a26100 --- /dev/null +++ b/net/ieee802154/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | obj-$(CONFIG_IEEE802154) += nl802154.o af_802154.o | ||
2 | nl802154-y := netlink.o nl_policy.o | ||
3 | af_802154-y := af_ieee802154.o raw.o dgram.o | ||
4 | |||
5 | ccflags-y += -Wall -DDEBUG | ||
diff --git a/net/ieee802154/af802154.h b/net/ieee802154/af802154.h new file mode 100644 index 000000000000..b1ec52537522 --- /dev/null +++ b/net/ieee802154/af802154.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * Internal interfaces for ieee 802.15.4 address family. | ||
3 | * | ||
4 | * Copyright 2007, 2008, 2009 Siemens AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | * | ||
19 | * Written by: | ||
20 | * Sergey Lapin <slapin@ossfans.org> | ||
21 | * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | ||
22 | */ | ||
23 | |||
24 | #ifndef AF802154_H | ||
25 | #define AF802154_H | ||
26 | |||
27 | struct sk_buff; | ||
28 | struct net_devce; | ||
29 | extern struct proto ieee802154_raw_prot; | ||
30 | extern struct proto ieee802154_dgram_prot; | ||
31 | void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb); | ||
32 | int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb); | ||
33 | struct net_device *ieee802154_get_dev(struct net *net, | ||
34 | struct ieee802154_addr *addr); | ||
35 | |||
36 | #endif | ||
diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c new file mode 100644 index 000000000000..882a927cefae --- /dev/null +++ b/net/ieee802154/af_ieee802154.c | |||
@@ -0,0 +1,372 @@ | |||
1 | /* | ||
2 | * IEEE802154.4 socket interface | ||
3 | * | ||
4 | * Copyright 2007, 2008 Siemens AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | * | ||
19 | * Written by: | ||
20 | * Sergey Lapin <slapin@ossfans.org> | ||
21 | * Maxim Gorbachyov <maxim.gorbachev@siemens.com> | ||
22 | */ | ||
23 | |||
24 | #include <linux/net.h> | ||
25 | #include <linux/capability.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/if_arp.h> | ||
28 | #include <linux/if.h> | ||
29 | #include <linux/termios.h> /* For TIOCOUTQ/INQ */ | ||
30 | #include <linux/list.h> | ||
31 | #include <net/datalink.h> | ||
32 | #include <net/psnap.h> | ||
33 | #include <net/sock.h> | ||
34 | #include <net/tcp_states.h> | ||
35 | #include <net/route.h> | ||
36 | |||
37 | #include <net/ieee802154/af_ieee802154.h> | ||
38 | #include <net/ieee802154/netdevice.h> | ||
39 | |||
40 | #include "af802154.h" | ||
41 | |||
42 | #define DBG_DUMP(data, len) { \ | ||
43 | int i; \ | ||
44 | pr_debug("function: %s: data: len %d:\n", __func__, len); \ | ||
45 | for (i = 0; i < len; i++) {\ | ||
46 | pr_debug("%02x: %02x\n", i, (data)[i]); \ | ||
47 | } \ | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * Utility function for families | ||
52 | */ | ||
53 | struct net_device *ieee802154_get_dev(struct net *net, | ||
54 | struct ieee802154_addr *addr) | ||
55 | { | ||
56 | struct net_device *dev = NULL; | ||
57 | struct net_device *tmp; | ||
58 | u16 pan_id, short_addr; | ||
59 | |||
60 | switch (addr->addr_type) { | ||
61 | case IEEE802154_ADDR_LONG: | ||
62 | rtnl_lock(); | ||
63 | dev = dev_getbyhwaddr(net, ARPHRD_IEEE802154, addr->hwaddr); | ||
64 | if (dev) | ||
65 | dev_hold(dev); | ||
66 | rtnl_unlock(); | ||
67 | break; | ||
68 | case IEEE802154_ADDR_SHORT: | ||
69 | if (addr->pan_id == 0xffff || | ||
70 | addr->short_addr == IEEE802154_ADDR_UNDEF || | ||
71 | addr->short_addr == 0xffff) | ||
72 | break; | ||
73 | |||
74 | rtnl_lock(); | ||
75 | |||
76 | for_each_netdev(net, tmp) { | ||
77 | if (tmp->type != ARPHRD_IEEE802154) | ||
78 | continue; | ||
79 | |||
80 | pan_id = ieee802154_mlme_ops(tmp)->get_pan_id(tmp); | ||
81 | short_addr = | ||
82 | ieee802154_mlme_ops(tmp)->get_short_addr(tmp); | ||
83 | |||
84 | if (pan_id == addr->pan_id && | ||
85 | short_addr == addr->short_addr) { | ||
86 | dev = tmp; | ||
87 | dev_hold(dev); | ||
88 | break; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | rtnl_unlock(); | ||
93 | break; | ||
94 | default: | ||
95 | pr_warning("Unsupported ieee802154 address type: %d\n", | ||
96 | addr->addr_type); | ||
97 | break; | ||
98 | } | ||
99 | |||
100 | return dev; | ||
101 | } | ||
102 | |||
103 | static int ieee802154_sock_release(struct socket *sock) | ||
104 | { | ||
105 | struct sock *sk = sock->sk; | ||
106 | |||
107 | if (sk) { | ||
108 | sock->sk = NULL; | ||
109 | sk->sk_prot->close(sk, 0); | ||
110 | } | ||
111 | return 0; | ||
112 | } | ||
113 | static int ieee802154_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | ||
114 | struct msghdr *msg, size_t len) | ||
115 | { | ||
116 | struct sock *sk = sock->sk; | ||
117 | |||
118 | return sk->sk_prot->sendmsg(iocb, sk, msg, len); | ||
119 | } | ||
120 | |||
121 | static int ieee802154_sock_bind(struct socket *sock, struct sockaddr *uaddr, | ||
122 | int addr_len) | ||
123 | { | ||
124 | struct sock *sk = sock->sk; | ||
125 | |||
126 | if (sk->sk_prot->bind) | ||
127 | return sk->sk_prot->bind(sk, uaddr, addr_len); | ||
128 | |||
129 | return sock_no_bind(sock, uaddr, addr_len); | ||
130 | } | ||
131 | |||
132 | static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr, | ||
133 | int addr_len, int flags) | ||
134 | { | ||
135 | struct sock *sk = sock->sk; | ||
136 | |||
137 | if (uaddr->sa_family == AF_UNSPEC) | ||
138 | return sk->sk_prot->disconnect(sk, flags); | ||
139 | |||
140 | return sk->sk_prot->connect(sk, uaddr, addr_len); | ||
141 | } | ||
142 | |||
143 | static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg, | ||
144 | unsigned int cmd) | ||
145 | { | ||
146 | struct ifreq ifr; | ||
147 | int ret = -EINVAL; | ||
148 | struct net_device *dev; | ||
149 | |||
150 | if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) | ||
151 | return -EFAULT; | ||
152 | |||
153 | ifr.ifr_name[IFNAMSIZ-1] = 0; | ||
154 | |||
155 | dev_load(sock_net(sk), ifr.ifr_name); | ||
156 | dev = dev_get_by_name(sock_net(sk), ifr.ifr_name); | ||
157 | if (dev->type == ARPHRD_IEEE802154 || | ||
158 | dev->type == ARPHRD_IEEE802154_PHY) | ||
159 | ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd); | ||
160 | |||
161 | if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq))) | ||
162 | ret = -EFAULT; | ||
163 | dev_put(dev); | ||
164 | |||
165 | return ret; | ||
166 | } | ||
167 | |||
168 | static int ieee802154_sock_ioctl(struct socket *sock, unsigned int cmd, | ||
169 | unsigned long arg) | ||
170 | { | ||
171 | struct sock *sk = sock->sk; | ||
172 | |||
173 | switch (cmd) { | ||
174 | case SIOCGSTAMP: | ||
175 | return sock_get_timestamp(sk, (struct timeval __user *)arg); | ||
176 | case SIOCGSTAMPNS: | ||
177 | return sock_get_timestampns(sk, (struct timespec __user *)arg); | ||
178 | case SIOCGIFADDR: | ||
179 | case SIOCSIFADDR: | ||
180 | return ieee802154_dev_ioctl(sk, (struct ifreq __user *)arg, | ||
181 | cmd); | ||
182 | default: | ||
183 | if (!sk->sk_prot->ioctl) | ||
184 | return -ENOIOCTLCMD; | ||
185 | return sk->sk_prot->ioctl(sk, cmd, arg); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | static const struct proto_ops ieee802154_raw_ops = { | ||
190 | .family = PF_IEEE802154, | ||
191 | .owner = THIS_MODULE, | ||
192 | .release = ieee802154_sock_release, | ||
193 | .bind = ieee802154_sock_bind, | ||
194 | .connect = ieee802154_sock_connect, | ||
195 | .socketpair = sock_no_socketpair, | ||
196 | .accept = sock_no_accept, | ||
197 | .getname = sock_no_getname, | ||
198 | .poll = datagram_poll, | ||
199 | .ioctl = ieee802154_sock_ioctl, | ||
200 | .listen = sock_no_listen, | ||
201 | .shutdown = sock_no_shutdown, | ||
202 | .setsockopt = sock_common_setsockopt, | ||
203 | .getsockopt = sock_common_getsockopt, | ||
204 | .sendmsg = ieee802154_sock_sendmsg, | ||
205 | .recvmsg = sock_common_recvmsg, | ||
206 | .mmap = sock_no_mmap, | ||
207 | .sendpage = sock_no_sendpage, | ||
208 | #ifdef CONFIG_COMPAT | ||
209 | .compat_setsockopt = compat_sock_common_setsockopt, | ||
210 | .compat_getsockopt = compat_sock_common_getsockopt, | ||
211 | #endif | ||
212 | }; | ||
213 | |||
214 | static const struct proto_ops ieee802154_dgram_ops = { | ||
215 | .family = PF_IEEE802154, | ||
216 | .owner = THIS_MODULE, | ||
217 | .release = ieee802154_sock_release, | ||
218 | .bind = ieee802154_sock_bind, | ||
219 | .connect = ieee802154_sock_connect, | ||
220 | .socketpair = sock_no_socketpair, | ||
221 | .accept = sock_no_accept, | ||
222 | .getname = sock_no_getname, | ||
223 | .poll = datagram_poll, | ||
224 | .ioctl = ieee802154_sock_ioctl, | ||
225 | .listen = sock_no_listen, | ||
226 | .shutdown = sock_no_shutdown, | ||
227 | .setsockopt = sock_common_setsockopt, | ||
228 | .getsockopt = sock_common_getsockopt, | ||
229 | .sendmsg = ieee802154_sock_sendmsg, | ||
230 | .recvmsg = sock_common_recvmsg, | ||
231 | .mmap = sock_no_mmap, | ||
232 | .sendpage = sock_no_sendpage, | ||
233 | #ifdef CONFIG_COMPAT | ||
234 | .compat_setsockopt = compat_sock_common_setsockopt, | ||
235 | .compat_getsockopt = compat_sock_common_getsockopt, | ||
236 | #endif | ||
237 | }; | ||
238 | |||
239 | |||
240 | /* | ||
241 | * Create a socket. Initialise the socket, blank the addresses | ||
242 | * set the state. | ||
243 | */ | ||
244 | static int ieee802154_create(struct net *net, struct socket *sock, | ||
245 | int protocol) | ||
246 | { | ||
247 | struct sock *sk; | ||
248 | int rc; | ||
249 | struct proto *proto; | ||
250 | const struct proto_ops *ops; | ||
251 | |||
252 | if (net != &init_net) | ||
253 | return -EAFNOSUPPORT; | ||
254 | |||
255 | switch (sock->type) { | ||
256 | case SOCK_RAW: | ||
257 | proto = &ieee802154_raw_prot; | ||
258 | ops = &ieee802154_raw_ops; | ||
259 | break; | ||
260 | case SOCK_DGRAM: | ||
261 | proto = &ieee802154_dgram_prot; | ||
262 | ops = &ieee802154_dgram_ops; | ||
263 | break; | ||
264 | default: | ||
265 | rc = -ESOCKTNOSUPPORT; | ||
266 | goto out; | ||
267 | } | ||
268 | |||
269 | rc = -ENOMEM; | ||
270 | sk = sk_alloc(net, PF_IEEE802154, GFP_KERNEL, proto); | ||
271 | if (!sk) | ||
272 | goto out; | ||
273 | rc = 0; | ||
274 | |||
275 | sock->ops = ops; | ||
276 | |||
277 | sock_init_data(sock, sk); | ||
278 | /* FIXME: sk->sk_destruct */ | ||
279 | sk->sk_family = PF_IEEE802154; | ||
280 | |||
281 | /* Checksums on by default */ | ||
282 | sock_set_flag(sk, SOCK_ZAPPED); | ||
283 | |||
284 | if (sk->sk_prot->hash) | ||
285 | sk->sk_prot->hash(sk); | ||
286 | |||
287 | if (sk->sk_prot->init) { | ||
288 | rc = sk->sk_prot->init(sk); | ||
289 | if (rc) | ||
290 | sk_common_release(sk); | ||
291 | } | ||
292 | out: | ||
293 | return rc; | ||
294 | } | ||
295 | |||
296 | static struct net_proto_family ieee802154_family_ops = { | ||
297 | .family = PF_IEEE802154, | ||
298 | .create = ieee802154_create, | ||
299 | .owner = THIS_MODULE, | ||
300 | }; | ||
301 | |||
302 | static int ieee802154_rcv(struct sk_buff *skb, struct net_device *dev, | ||
303 | struct packet_type *pt, struct net_device *orig_dev) | ||
304 | { | ||
305 | DBG_DUMP(skb->data, skb->len); | ||
306 | if (!netif_running(dev)) | ||
307 | return -ENODEV; | ||
308 | pr_debug("got frame, type %d, dev %p\n", dev->type, dev); | ||
309 | |||
310 | if (!net_eq(dev_net(dev), &init_net)) | ||
311 | goto drop; | ||
312 | |||
313 | ieee802154_raw_deliver(dev, skb); | ||
314 | |||
315 | if (dev->type != ARPHRD_IEEE802154) | ||
316 | goto drop; | ||
317 | |||
318 | if (skb->pkt_type != PACKET_OTHERHOST) | ||
319 | return ieee802154_dgram_deliver(dev, skb); | ||
320 | |||
321 | drop: | ||
322 | kfree_skb(skb); | ||
323 | return NET_RX_DROP; | ||
324 | } | ||
325 | |||
326 | |||
327 | static struct packet_type ieee802154_packet_type = { | ||
328 | .type = __constant_htons(ETH_P_IEEE802154), | ||
329 | .func = ieee802154_rcv, | ||
330 | }; | ||
331 | |||
332 | static int __init af_ieee802154_init(void) | ||
333 | { | ||
334 | int rc = -EINVAL; | ||
335 | |||
336 | rc = proto_register(&ieee802154_raw_prot, 1); | ||
337 | if (rc) | ||
338 | goto out; | ||
339 | |||
340 | rc = proto_register(&ieee802154_dgram_prot, 1); | ||
341 | if (rc) | ||
342 | goto err_dgram; | ||
343 | |||
344 | /* Tell SOCKET that we are alive */ | ||
345 | rc = sock_register(&ieee802154_family_ops); | ||
346 | if (rc) | ||
347 | goto err_sock; | ||
348 | dev_add_pack(&ieee802154_packet_type); | ||
349 | |||
350 | rc = 0; | ||
351 | goto out; | ||
352 | |||
353 | err_sock: | ||
354 | proto_unregister(&ieee802154_dgram_prot); | ||
355 | err_dgram: | ||
356 | proto_unregister(&ieee802154_raw_prot); | ||
357 | out: | ||
358 | return rc; | ||
359 | } | ||
360 | static void __exit af_ieee802154_remove(void) | ||
361 | { | ||
362 | dev_remove_pack(&ieee802154_packet_type); | ||
363 | sock_unregister(PF_IEEE802154); | ||
364 | proto_unregister(&ieee802154_dgram_prot); | ||
365 | proto_unregister(&ieee802154_raw_prot); | ||
366 | } | ||
367 | |||
368 | module_init(af_ieee802154_init); | ||
369 | module_exit(af_ieee802154_remove); | ||
370 | |||
371 | MODULE_LICENSE("GPL"); | ||
372 | MODULE_ALIAS_NETPROTO(PF_IEEE802154); | ||
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c new file mode 100644 index 000000000000..1779677aed46 --- /dev/null +++ b/net/ieee802154/dgram.c | |||
@@ -0,0 +1,394 @@ | |||
1 | /* | ||
2 | * ZigBee socket interface | ||
3 | * | ||
4 | * Copyright 2007, 2008 Siemens AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | * | ||
19 | * Written by: | ||
20 | * Sergey Lapin <slapin@ossfans.org> | ||
21 | * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | ||
22 | */ | ||
23 | |||
24 | #include <linux/net.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/if_arp.h> | ||
27 | #include <linux/list.h> | ||
28 | #include <net/sock.h> | ||
29 | #include <net/ieee802154/af_ieee802154.h> | ||
30 | #include <net/ieee802154/mac_def.h> | ||
31 | #include <net/ieee802154/netdevice.h> | ||
32 | |||
33 | #include <asm/ioctls.h> | ||
34 | |||
35 | #include "af802154.h" | ||
36 | |||
37 | static HLIST_HEAD(dgram_head); | ||
38 | static DEFINE_RWLOCK(dgram_lock); | ||
39 | |||
40 | struct dgram_sock { | ||
41 | struct sock sk; | ||
42 | |||
43 | int bound; | ||
44 | struct ieee802154_addr src_addr; | ||
45 | struct ieee802154_addr dst_addr; | ||
46 | }; | ||
47 | |||
48 | static inline struct dgram_sock *dgram_sk(const struct sock *sk) | ||
49 | { | ||
50 | return container_of(sk, struct dgram_sock, sk); | ||
51 | } | ||
52 | |||
53 | |||
54 | static void dgram_hash(struct sock *sk) | ||
55 | { | ||
56 | write_lock_bh(&dgram_lock); | ||
57 | sk_add_node(sk, &dgram_head); | ||
58 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | ||
59 | write_unlock_bh(&dgram_lock); | ||
60 | } | ||
61 | |||
62 | static void dgram_unhash(struct sock *sk) | ||
63 | { | ||
64 | write_lock_bh(&dgram_lock); | ||
65 | if (sk_del_node_init(sk)) | ||
66 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); | ||
67 | write_unlock_bh(&dgram_lock); | ||
68 | } | ||
69 | |||
70 | static int dgram_init(struct sock *sk) | ||
71 | { | ||
72 | struct dgram_sock *ro = dgram_sk(sk); | ||
73 | |||
74 | ro->dst_addr.addr_type = IEEE802154_ADDR_LONG; | ||
75 | ro->dst_addr.pan_id = 0xffff; | ||
76 | memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr)); | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static void dgram_close(struct sock *sk, long timeout) | ||
81 | { | ||
82 | sk_common_release(sk); | ||
83 | } | ||
84 | |||
85 | static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len) | ||
86 | { | ||
87 | struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; | ||
88 | struct dgram_sock *ro = dgram_sk(sk); | ||
89 | int err = 0; | ||
90 | struct net_device *dev; | ||
91 | |||
92 | ro->bound = 0; | ||
93 | |||
94 | if (len < sizeof(*addr)) | ||
95 | return -EINVAL; | ||
96 | |||
97 | if (addr->family != AF_IEEE802154) | ||
98 | return -EINVAL; | ||
99 | |||
100 | lock_sock(sk); | ||
101 | |||
102 | dev = ieee802154_get_dev(sock_net(sk), &addr->addr); | ||
103 | if (!dev) { | ||
104 | err = -ENODEV; | ||
105 | goto out; | ||
106 | } | ||
107 | |||
108 | if (dev->type != ARPHRD_IEEE802154) { | ||
109 | err = -ENODEV; | ||
110 | goto out_put; | ||
111 | } | ||
112 | |||
113 | memcpy(&ro->src_addr, &addr->addr, sizeof(struct ieee802154_addr)); | ||
114 | |||
115 | ro->bound = 1; | ||
116 | out_put: | ||
117 | dev_put(dev); | ||
118 | out: | ||
119 | release_sock(sk); | ||
120 | |||
121 | return err; | ||
122 | } | ||
123 | |||
124 | static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg) | ||
125 | { | ||
126 | switch (cmd) { | ||
127 | case SIOCOUTQ: | ||
128 | { | ||
129 | int amount = atomic_read(&sk->sk_wmem_alloc); | ||
130 | return put_user(amount, (int __user *)arg); | ||
131 | } | ||
132 | |||
133 | case SIOCINQ: | ||
134 | { | ||
135 | struct sk_buff *skb; | ||
136 | unsigned long amount; | ||
137 | |||
138 | amount = 0; | ||
139 | spin_lock_bh(&sk->sk_receive_queue.lock); | ||
140 | skb = skb_peek(&sk->sk_receive_queue); | ||
141 | if (skb != NULL) { | ||
142 | /* | ||
143 | * We will only return the amount | ||
144 | * of this packet since that is all | ||
145 | * that will be read. | ||
146 | */ | ||
147 | /* FIXME: parse the header for more correct value */ | ||
148 | amount = skb->len - (3+8+8); | ||
149 | } | ||
150 | spin_unlock_bh(&sk->sk_receive_queue.lock); | ||
151 | return put_user(amount, (int __user *)arg); | ||
152 | } | ||
153 | |||
154 | } | ||
155 | return -ENOIOCTLCMD; | ||
156 | } | ||
157 | |||
158 | /* FIXME: autobind */ | ||
159 | static int dgram_connect(struct sock *sk, struct sockaddr *uaddr, | ||
160 | int len) | ||
161 | { | ||
162 | struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; | ||
163 | struct dgram_sock *ro = dgram_sk(sk); | ||
164 | int err = 0; | ||
165 | |||
166 | if (len < sizeof(*addr)) | ||
167 | return -EINVAL; | ||
168 | |||
169 | if (addr->family != AF_IEEE802154) | ||
170 | return -EINVAL; | ||
171 | |||
172 | lock_sock(sk); | ||
173 | |||
174 | if (!ro->bound) { | ||
175 | err = -ENETUNREACH; | ||
176 | goto out; | ||
177 | } | ||
178 | |||
179 | memcpy(&ro->dst_addr, &addr->addr, sizeof(struct ieee802154_addr)); | ||
180 | |||
181 | out: | ||
182 | release_sock(sk); | ||
183 | return err; | ||
184 | } | ||
185 | |||
186 | static int dgram_disconnect(struct sock *sk, int flags) | ||
187 | { | ||
188 | struct dgram_sock *ro = dgram_sk(sk); | ||
189 | |||
190 | lock_sock(sk); | ||
191 | |||
192 | ro->dst_addr.addr_type = IEEE802154_ADDR_LONG; | ||
193 | memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr)); | ||
194 | |||
195 | release_sock(sk); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, | ||
201 | struct msghdr *msg, size_t size) | ||
202 | { | ||
203 | struct net_device *dev; | ||
204 | unsigned mtu; | ||
205 | struct sk_buff *skb; | ||
206 | struct dgram_sock *ro = dgram_sk(sk); | ||
207 | int err; | ||
208 | |||
209 | if (msg->msg_flags & MSG_OOB) { | ||
210 | pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags); | ||
211 | return -EOPNOTSUPP; | ||
212 | } | ||
213 | |||
214 | if (!ro->bound) | ||
215 | dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); | ||
216 | else | ||
217 | dev = ieee802154_get_dev(sock_net(sk), &ro->src_addr); | ||
218 | |||
219 | if (!dev) { | ||
220 | pr_debug("no dev\n"); | ||
221 | err = -ENXIO; | ||
222 | goto out; | ||
223 | } | ||
224 | mtu = dev->mtu; | ||
225 | pr_debug("name = %s, mtu = %u\n", dev->name, mtu); | ||
226 | |||
227 | skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + size, | ||
228 | msg->msg_flags & MSG_DONTWAIT, | ||
229 | &err); | ||
230 | if (!skb) | ||
231 | goto out_dev; | ||
232 | |||
233 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | ||
234 | |||
235 | skb_reset_network_header(skb); | ||
236 | |||
237 | mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA | MAC_CB_FLAG_ACKREQ; | ||
238 | mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_dsn(dev); | ||
239 | err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &ro->dst_addr, | ||
240 | ro->bound ? &ro->src_addr : NULL, size); | ||
241 | if (err < 0) | ||
242 | goto out_skb; | ||
243 | |||
244 | skb_reset_mac_header(skb); | ||
245 | |||
246 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | ||
247 | if (err < 0) | ||
248 | goto out_skb; | ||
249 | |||
250 | if (size > mtu) { | ||
251 | pr_debug("size = %Zu, mtu = %u\n", size, mtu); | ||
252 | err = -EINVAL; | ||
253 | goto out_skb; | ||
254 | } | ||
255 | |||
256 | skb->dev = dev; | ||
257 | skb->sk = sk; | ||
258 | skb->protocol = htons(ETH_P_IEEE802154); | ||
259 | |||
260 | dev_put(dev); | ||
261 | |||
262 | err = dev_queue_xmit(skb); | ||
263 | if (err > 0) | ||
264 | err = net_xmit_errno(err); | ||
265 | |||
266 | return err ?: size; | ||
267 | |||
268 | out_skb: | ||
269 | kfree_skb(skb); | ||
270 | out_dev: | ||
271 | dev_put(dev); | ||
272 | out: | ||
273 | return err; | ||
274 | } | ||
275 | |||
276 | static int dgram_recvmsg(struct kiocb *iocb, struct sock *sk, | ||
277 | struct msghdr *msg, size_t len, int noblock, int flags, | ||
278 | int *addr_len) | ||
279 | { | ||
280 | size_t copied = 0; | ||
281 | int err = -EOPNOTSUPP; | ||
282 | struct sk_buff *skb; | ||
283 | |||
284 | skb = skb_recv_datagram(sk, flags, noblock, &err); | ||
285 | if (!skb) | ||
286 | goto out; | ||
287 | |||
288 | copied = skb->len; | ||
289 | if (len < copied) { | ||
290 | msg->msg_flags |= MSG_TRUNC; | ||
291 | copied = len; | ||
292 | } | ||
293 | |||
294 | /* FIXME: skip headers if necessary ?! */ | ||
295 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); | ||
296 | if (err) | ||
297 | goto done; | ||
298 | |||
299 | sock_recv_timestamp(msg, sk, skb); | ||
300 | |||
301 | if (flags & MSG_TRUNC) | ||
302 | copied = skb->len; | ||
303 | done: | ||
304 | skb_free_datagram(sk, skb); | ||
305 | out: | ||
306 | if (err) | ||
307 | return err; | ||
308 | return copied; | ||
309 | } | ||
310 | |||
311 | static int dgram_rcv_skb(struct sock *sk, struct sk_buff *skb) | ||
312 | { | ||
313 | if (sock_queue_rcv_skb(sk, skb) < 0) { | ||
314 | atomic_inc(&sk->sk_drops); | ||
315 | kfree_skb(skb); | ||
316 | return NET_RX_DROP; | ||
317 | } | ||
318 | |||
319 | return NET_RX_SUCCESS; | ||
320 | } | ||
321 | |||
322 | static inline int ieee802154_match_sock(u8 *hw_addr, u16 pan_id, | ||
323 | u16 short_addr, struct dgram_sock *ro) | ||
324 | { | ||
325 | if (!ro->bound) | ||
326 | return 1; | ||
327 | |||
328 | if (ro->src_addr.addr_type == IEEE802154_ADDR_LONG && | ||
329 | !memcmp(ro->src_addr.hwaddr, hw_addr, IEEE802154_ADDR_LEN)) | ||
330 | return 1; | ||
331 | |||
332 | if (ro->src_addr.addr_type == IEEE802154_ADDR_SHORT && | ||
333 | pan_id == ro->src_addr.pan_id && | ||
334 | short_addr == ro->src_addr.short_addr) | ||
335 | return 1; | ||
336 | |||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb) | ||
341 | { | ||
342 | struct sock *sk, *prev = NULL; | ||
343 | struct hlist_node *node; | ||
344 | int ret = NET_RX_SUCCESS; | ||
345 | u16 pan_id, short_addr; | ||
346 | |||
347 | /* Data frame processing */ | ||
348 | BUG_ON(dev->type != ARPHRD_IEEE802154); | ||
349 | |||
350 | pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); | ||
351 | short_addr = ieee802154_mlme_ops(dev)->get_short_addr(dev); | ||
352 | |||
353 | read_lock(&dgram_lock); | ||
354 | sk_for_each(sk, node, &dgram_head) { | ||
355 | if (ieee802154_match_sock(dev->dev_addr, pan_id, short_addr, | ||
356 | dgram_sk(sk))) { | ||
357 | if (prev) { | ||
358 | struct sk_buff *clone; | ||
359 | clone = skb_clone(skb, GFP_ATOMIC); | ||
360 | if (clone) | ||
361 | dgram_rcv_skb(prev, clone); | ||
362 | } | ||
363 | |||
364 | prev = sk; | ||
365 | } | ||
366 | } | ||
367 | |||
368 | if (prev) | ||
369 | dgram_rcv_skb(prev, skb); | ||
370 | else { | ||
371 | kfree_skb(skb); | ||
372 | ret = NET_RX_DROP; | ||
373 | } | ||
374 | read_unlock(&dgram_lock); | ||
375 | |||
376 | return ret; | ||
377 | } | ||
378 | |||
379 | struct proto ieee802154_dgram_prot = { | ||
380 | .name = "IEEE-802.15.4-MAC", | ||
381 | .owner = THIS_MODULE, | ||
382 | .obj_size = sizeof(struct dgram_sock), | ||
383 | .init = dgram_init, | ||
384 | .close = dgram_close, | ||
385 | .bind = dgram_bind, | ||
386 | .sendmsg = dgram_sendmsg, | ||
387 | .recvmsg = dgram_recvmsg, | ||
388 | .hash = dgram_hash, | ||
389 | .unhash = dgram_unhash, | ||
390 | .connect = dgram_connect, | ||
391 | .disconnect = dgram_disconnect, | ||
392 | .ioctl = dgram_ioctl, | ||
393 | }; | ||
394 | |||
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c new file mode 100644 index 000000000000..105ad10876af --- /dev/null +++ b/net/ieee802154/netlink.c | |||
@@ -0,0 +1,523 @@ | |||
1 | /* | ||
2 | * Netlink inteface for IEEE 802.15.4 stack | ||
3 | * | ||
4 | * Copyright 2007, 2008 Siemens AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | * | ||
19 | * Written by: | ||
20 | * Sergey Lapin <slapin@ossfans.org> | ||
21 | * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/if_arp.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <net/netlink.h> | ||
28 | #include <net/genetlink.h> | ||
29 | #include <linux/nl802154.h> | ||
30 | #include <net/ieee802154/af_ieee802154.h> | ||
31 | #include <net/ieee802154/nl802154.h> | ||
32 | #include <net/ieee802154/netdevice.h> | ||
33 | |||
34 | static unsigned int ieee802154_seq_num; | ||
35 | |||
36 | static struct genl_family ieee802154_coordinator_family = { | ||
37 | .id = GENL_ID_GENERATE, | ||
38 | .hdrsize = 0, | ||
39 | .name = IEEE802154_NL_NAME, | ||
40 | .version = 1, | ||
41 | .maxattr = IEEE802154_ATTR_MAX, | ||
42 | }; | ||
43 | |||
44 | static struct genl_multicast_group ieee802154_coord_mcgrp = { | ||
45 | .name = IEEE802154_MCAST_COORD_NAME, | ||
46 | }; | ||
47 | |||
48 | static struct genl_multicast_group ieee802154_beacon_mcgrp = { | ||
49 | .name = IEEE802154_MCAST_BEACON_NAME, | ||
50 | }; | ||
51 | |||
52 | /* Requests to userspace */ | ||
53 | static struct sk_buff *ieee802154_nl_create(int flags, u8 req) | ||
54 | { | ||
55 | void *hdr; | ||
56 | struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); | ||
57 | |||
58 | if (!msg) | ||
59 | return NULL; | ||
60 | |||
61 | hdr = genlmsg_put(msg, 0, ieee802154_seq_num++, | ||
62 | &ieee802154_coordinator_family, flags, req); | ||
63 | if (!hdr) { | ||
64 | nlmsg_free(msg); | ||
65 | return NULL; | ||
66 | } | ||
67 | |||
68 | return msg; | ||
69 | } | ||
70 | |||
71 | static int ieee802154_nl_finish(struct sk_buff *msg) | ||
72 | { | ||
73 | /* XXX: nlh is right at the start of msg */ | ||
74 | void *hdr = genlmsg_data(NLMSG_DATA(msg->data)); | ||
75 | |||
76 | if (!genlmsg_end(msg, hdr)) | ||
77 | goto out; | ||
78 | |||
79 | return genlmsg_multicast(msg, 0, ieee802154_coord_mcgrp.id, | ||
80 | GFP_ATOMIC); | ||
81 | out: | ||
82 | nlmsg_free(msg); | ||
83 | return -ENOBUFS; | ||
84 | } | ||
85 | |||
86 | int ieee802154_nl_assoc_indic(struct net_device *dev, | ||
87 | struct ieee802154_addr *addr, u8 cap) | ||
88 | { | ||
89 | struct sk_buff *msg; | ||
90 | |||
91 | pr_debug("%s\n", __func__); | ||
92 | |||
93 | if (addr->addr_type != IEEE802154_ADDR_LONG) { | ||
94 | pr_err("%s: received non-long source address!\n", __func__); | ||
95 | return -EINVAL; | ||
96 | } | ||
97 | |||
98 | msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_INDIC); | ||
99 | if (!msg) | ||
100 | return -ENOBUFS; | ||
101 | |||
102 | NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); | ||
103 | NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); | ||
104 | NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, | ||
105 | dev->dev_addr); | ||
106 | |||
107 | NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN, | ||
108 | addr->hwaddr); | ||
109 | |||
110 | NLA_PUT_U8(msg, IEEE802154_ATTR_CAPABILITY, cap); | ||
111 | |||
112 | return ieee802154_nl_finish(msg); | ||
113 | |||
114 | nla_put_failure: | ||
115 | nlmsg_free(msg); | ||
116 | return -ENOBUFS; | ||
117 | } | ||
118 | EXPORT_SYMBOL(ieee802154_nl_assoc_indic); | ||
119 | |||
120 | int ieee802154_nl_assoc_confirm(struct net_device *dev, u16 short_addr, | ||
121 | u8 status) | ||
122 | { | ||
123 | struct sk_buff *msg; | ||
124 | |||
125 | pr_debug("%s\n", __func__); | ||
126 | |||
127 | msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_CONF); | ||
128 | if (!msg) | ||
129 | return -ENOBUFS; | ||
130 | |||
131 | NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); | ||
132 | NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); | ||
133 | NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, | ||
134 | dev->dev_addr); | ||
135 | |||
136 | NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr); | ||
137 | NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status); | ||
138 | |||
139 | return ieee802154_nl_finish(msg); | ||
140 | |||
141 | nla_put_failure: | ||
142 | nlmsg_free(msg); | ||
143 | return -ENOBUFS; | ||
144 | } | ||
145 | EXPORT_SYMBOL(ieee802154_nl_assoc_confirm); | ||
146 | |||
147 | int ieee802154_nl_disassoc_indic(struct net_device *dev, | ||
148 | struct ieee802154_addr *addr, u8 reason) | ||
149 | { | ||
150 | struct sk_buff *msg; | ||
151 | |||
152 | pr_debug("%s\n", __func__); | ||
153 | |||
154 | msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_INDIC); | ||
155 | if (!msg) | ||
156 | return -ENOBUFS; | ||
157 | |||
158 | NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); | ||
159 | NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); | ||
160 | NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, | ||
161 | dev->dev_addr); | ||
162 | |||
163 | if (addr->addr_type == IEEE802154_ADDR_LONG) | ||
164 | NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN, | ||
165 | addr->hwaddr); | ||
166 | else | ||
167 | NLA_PUT_U16(msg, IEEE802154_ATTR_SRC_SHORT_ADDR, | ||
168 | addr->short_addr); | ||
169 | |||
170 | NLA_PUT_U8(msg, IEEE802154_ATTR_REASON, reason); | ||
171 | |||
172 | return ieee802154_nl_finish(msg); | ||
173 | |||
174 | nla_put_failure: | ||
175 | nlmsg_free(msg); | ||
176 | return -ENOBUFS; | ||
177 | } | ||
178 | EXPORT_SYMBOL(ieee802154_nl_disassoc_indic); | ||
179 | |||
180 | int ieee802154_nl_disassoc_confirm(struct net_device *dev, u8 status) | ||
181 | { | ||
182 | struct sk_buff *msg; | ||
183 | |||
184 | pr_debug("%s\n", __func__); | ||
185 | |||
186 | msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_CONF); | ||
187 | if (!msg) | ||
188 | return -ENOBUFS; | ||
189 | |||
190 | NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); | ||
191 | NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); | ||
192 | NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, | ||
193 | dev->dev_addr); | ||
194 | |||
195 | NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status); | ||
196 | |||
197 | return ieee802154_nl_finish(msg); | ||
198 | |||
199 | nla_put_failure: | ||
200 | nlmsg_free(msg); | ||
201 | return -ENOBUFS; | ||
202 | } | ||
203 | EXPORT_SYMBOL(ieee802154_nl_disassoc_confirm); | ||
204 | |||
205 | int ieee802154_nl_beacon_indic(struct net_device *dev, | ||
206 | u16 panid, u16 coord_addr) | ||
207 | { | ||
208 | struct sk_buff *msg; | ||
209 | |||
210 | pr_debug("%s\n", __func__); | ||
211 | |||
212 | msg = ieee802154_nl_create(0, IEEE802154_BEACON_NOTIFY_INDIC); | ||
213 | if (!msg) | ||
214 | return -ENOBUFS; | ||
215 | |||
216 | NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); | ||
217 | NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); | ||
218 | NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, | ||
219 | dev->dev_addr); | ||
220 | NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr); | ||
221 | NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid); | ||
222 | |||
223 | return ieee802154_nl_finish(msg); | ||
224 | |||
225 | nla_put_failure: | ||
226 | nlmsg_free(msg); | ||
227 | return -ENOBUFS; | ||
228 | } | ||
229 | EXPORT_SYMBOL(ieee802154_nl_beacon_indic); | ||
230 | |||
231 | int ieee802154_nl_scan_confirm(struct net_device *dev, | ||
232 | u8 status, u8 scan_type, u32 unscanned, | ||
233 | u8 *edl/* , struct list_head *pan_desc_list */) | ||
234 | { | ||
235 | struct sk_buff *msg; | ||
236 | |||
237 | pr_debug("%s\n", __func__); | ||
238 | |||
239 | msg = ieee802154_nl_create(0, IEEE802154_SCAN_CONF); | ||
240 | if (!msg) | ||
241 | return -ENOBUFS; | ||
242 | |||
243 | NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); | ||
244 | NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); | ||
245 | NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, | ||
246 | dev->dev_addr); | ||
247 | |||
248 | NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status); | ||
249 | NLA_PUT_U8(msg, IEEE802154_ATTR_SCAN_TYPE, scan_type); | ||
250 | NLA_PUT_U32(msg, IEEE802154_ATTR_CHANNELS, unscanned); | ||
251 | |||
252 | if (edl) | ||
253 | NLA_PUT(msg, IEEE802154_ATTR_ED_LIST, 27, edl); | ||
254 | |||
255 | return ieee802154_nl_finish(msg); | ||
256 | |||
257 | nla_put_failure: | ||
258 | nlmsg_free(msg); | ||
259 | return -ENOBUFS; | ||
260 | } | ||
261 | EXPORT_SYMBOL(ieee802154_nl_scan_confirm); | ||
262 | |||
263 | /* Requests from userspace */ | ||
264 | static struct net_device *ieee802154_nl_get_dev(struct genl_info *info) | ||
265 | { | ||
266 | struct net_device *dev; | ||
267 | |||
268 | if (info->attrs[IEEE802154_ATTR_DEV_NAME]) { | ||
269 | char name[IFNAMSIZ + 1]; | ||
270 | nla_strlcpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME], | ||
271 | sizeof(name)); | ||
272 | dev = dev_get_by_name(&init_net, name); | ||
273 | } else if (info->attrs[IEEE802154_ATTR_DEV_INDEX]) | ||
274 | dev = dev_get_by_index(&init_net, | ||
275 | nla_get_u32(info->attrs[IEEE802154_ATTR_DEV_INDEX])); | ||
276 | else | ||
277 | return NULL; | ||
278 | |||
279 | if (dev->type != ARPHRD_IEEE802154) { | ||
280 | dev_put(dev); | ||
281 | return NULL; | ||
282 | } | ||
283 | |||
284 | return dev; | ||
285 | } | ||
286 | |||
287 | static int ieee802154_associate_req(struct sk_buff *skb, | ||
288 | struct genl_info *info) | ||
289 | { | ||
290 | struct net_device *dev; | ||
291 | struct ieee802154_addr addr; | ||
292 | int ret = -EINVAL; | ||
293 | |||
294 | if (!info->attrs[IEEE802154_ATTR_CHANNEL] || | ||
295 | !info->attrs[IEEE802154_ATTR_COORD_PAN_ID] || | ||
296 | (!info->attrs[IEEE802154_ATTR_COORD_HW_ADDR] && | ||
297 | !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]) || | ||
298 | !info->attrs[IEEE802154_ATTR_CAPABILITY]) | ||
299 | return -EINVAL; | ||
300 | |||
301 | dev = ieee802154_nl_get_dev(info); | ||
302 | if (!dev) | ||
303 | return -ENODEV; | ||
304 | |||
305 | if (info->attrs[IEEE802154_ATTR_COORD_HW_ADDR]) { | ||
306 | addr.addr_type = IEEE802154_ADDR_LONG; | ||
307 | nla_memcpy(addr.hwaddr, | ||
308 | info->attrs[IEEE802154_ATTR_COORD_HW_ADDR], | ||
309 | IEEE802154_ADDR_LEN); | ||
310 | } else { | ||
311 | addr.addr_type = IEEE802154_ADDR_SHORT; | ||
312 | addr.short_addr = nla_get_u16( | ||
313 | info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]); | ||
314 | } | ||
315 | addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]); | ||
316 | |||
317 | ret = ieee802154_mlme_ops(dev)->assoc_req(dev, &addr, | ||
318 | nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]), | ||
319 | nla_get_u8(info->attrs[IEEE802154_ATTR_CAPABILITY])); | ||
320 | |||
321 | dev_put(dev); | ||
322 | return ret; | ||
323 | } | ||
324 | |||
325 | static int ieee802154_associate_resp(struct sk_buff *skb, | ||
326 | struct genl_info *info) | ||
327 | { | ||
328 | struct net_device *dev; | ||
329 | struct ieee802154_addr addr; | ||
330 | int ret = -EINVAL; | ||
331 | |||
332 | if (!info->attrs[IEEE802154_ATTR_STATUS] || | ||
333 | !info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] || | ||
334 | !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]) | ||
335 | return -EINVAL; | ||
336 | |||
337 | dev = ieee802154_nl_get_dev(info); | ||
338 | if (!dev) | ||
339 | return -ENODEV; | ||
340 | |||
341 | addr.addr_type = IEEE802154_ADDR_LONG; | ||
342 | nla_memcpy(addr.hwaddr, info->attrs[IEEE802154_ATTR_DEST_HW_ADDR], | ||
343 | IEEE802154_ADDR_LEN); | ||
344 | addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); | ||
345 | |||
346 | |||
347 | ret = ieee802154_mlme_ops(dev)->assoc_resp(dev, &addr, | ||
348 | nla_get_u16(info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]), | ||
349 | nla_get_u8(info->attrs[IEEE802154_ATTR_STATUS])); | ||
350 | |||
351 | dev_put(dev); | ||
352 | return ret; | ||
353 | } | ||
354 | |||
355 | static int ieee802154_disassociate_req(struct sk_buff *skb, | ||
356 | struct genl_info *info) | ||
357 | { | ||
358 | struct net_device *dev; | ||
359 | struct ieee802154_addr addr; | ||
360 | int ret = -EINVAL; | ||
361 | |||
362 | if ((!info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] && | ||
363 | !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]) || | ||
364 | !info->attrs[IEEE802154_ATTR_REASON]) | ||
365 | return -EINVAL; | ||
366 | |||
367 | dev = ieee802154_nl_get_dev(info); | ||
368 | if (!dev) | ||
369 | return -ENODEV; | ||
370 | |||
371 | if (info->attrs[IEEE802154_ATTR_DEST_HW_ADDR]) { | ||
372 | addr.addr_type = IEEE802154_ADDR_LONG; | ||
373 | nla_memcpy(addr.hwaddr, | ||
374 | info->attrs[IEEE802154_ATTR_DEST_HW_ADDR], | ||
375 | IEEE802154_ADDR_LEN); | ||
376 | } else { | ||
377 | addr.addr_type = IEEE802154_ADDR_SHORT; | ||
378 | addr.short_addr = nla_get_u16( | ||
379 | info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]); | ||
380 | } | ||
381 | addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); | ||
382 | |||
383 | ret = ieee802154_mlme_ops(dev)->disassoc_req(dev, &addr, | ||
384 | nla_get_u8(info->attrs[IEEE802154_ATTR_REASON])); | ||
385 | |||
386 | dev_put(dev); | ||
387 | return ret; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * PANid, channel, beacon_order = 15, superframe_order = 15, | ||
392 | * PAN_coordinator, battery_life_extension = 0, | ||
393 | * coord_realignment = 0, security_enable = 0 | ||
394 | */ | ||
395 | static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info) | ||
396 | { | ||
397 | struct net_device *dev; | ||
398 | struct ieee802154_addr addr; | ||
399 | |||
400 | u8 channel, bcn_ord, sf_ord; | ||
401 | int pan_coord, blx, coord_realign; | ||
402 | int ret; | ||
403 | |||
404 | if (!info->attrs[IEEE802154_ATTR_COORD_PAN_ID] || | ||
405 | !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR] || | ||
406 | !info->attrs[IEEE802154_ATTR_CHANNEL] || | ||
407 | !info->attrs[IEEE802154_ATTR_BCN_ORD] || | ||
408 | !info->attrs[IEEE802154_ATTR_SF_ORD] || | ||
409 | !info->attrs[IEEE802154_ATTR_PAN_COORD] || | ||
410 | !info->attrs[IEEE802154_ATTR_BAT_EXT] || | ||
411 | !info->attrs[IEEE802154_ATTR_COORD_REALIGN] | ||
412 | ) | ||
413 | return -EINVAL; | ||
414 | |||
415 | dev = ieee802154_nl_get_dev(info); | ||
416 | if (!dev) | ||
417 | return -ENODEV; | ||
418 | |||
419 | addr.addr_type = IEEE802154_ADDR_SHORT; | ||
420 | addr.short_addr = nla_get_u16( | ||
421 | info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]); | ||
422 | addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]); | ||
423 | |||
424 | channel = nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]); | ||
425 | bcn_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_BCN_ORD]); | ||
426 | sf_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_SF_ORD]); | ||
427 | pan_coord = nla_get_u8(info->attrs[IEEE802154_ATTR_PAN_COORD]); | ||
428 | blx = nla_get_u8(info->attrs[IEEE802154_ATTR_BAT_EXT]); | ||
429 | coord_realign = nla_get_u8(info->attrs[IEEE802154_ATTR_COORD_REALIGN]); | ||
430 | |||
431 | ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel, | ||
432 | bcn_ord, sf_ord, pan_coord, blx, coord_realign); | ||
433 | |||
434 | dev_put(dev); | ||
435 | return ret; | ||
436 | } | ||
437 | |||
438 | static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info) | ||
439 | { | ||
440 | struct net_device *dev; | ||
441 | int ret; | ||
442 | u8 type; | ||
443 | u32 channels; | ||
444 | u8 duration; | ||
445 | |||
446 | if (!info->attrs[IEEE802154_ATTR_SCAN_TYPE] || | ||
447 | !info->attrs[IEEE802154_ATTR_CHANNELS] || | ||
448 | !info->attrs[IEEE802154_ATTR_DURATION]) | ||
449 | return -EINVAL; | ||
450 | |||
451 | dev = ieee802154_nl_get_dev(info); | ||
452 | if (!dev) | ||
453 | return -ENODEV; | ||
454 | |||
455 | type = nla_get_u8(info->attrs[IEEE802154_ATTR_SCAN_TYPE]); | ||
456 | channels = nla_get_u32(info->attrs[IEEE802154_ATTR_CHANNELS]); | ||
457 | duration = nla_get_u8(info->attrs[IEEE802154_ATTR_DURATION]); | ||
458 | |||
459 | ret = ieee802154_mlme_ops(dev)->scan_req(dev, type, channels, | ||
460 | duration); | ||
461 | |||
462 | dev_put(dev); | ||
463 | return ret; | ||
464 | } | ||
465 | |||
466 | #define IEEE802154_OP(_cmd, _func) \ | ||
467 | { \ | ||
468 | .cmd = _cmd, \ | ||
469 | .policy = ieee802154_policy, \ | ||
470 | .doit = _func, \ | ||
471 | .dumpit = NULL, \ | ||
472 | .flags = GENL_ADMIN_PERM, \ | ||
473 | } | ||
474 | |||
475 | static struct genl_ops ieee802154_coordinator_ops[] = { | ||
476 | IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req), | ||
477 | IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp), | ||
478 | IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req), | ||
479 | IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req), | ||
480 | IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req), | ||
481 | }; | ||
482 | |||
483 | static int __init ieee802154_nl_init(void) | ||
484 | { | ||
485 | int rc; | ||
486 | int i; | ||
487 | |||
488 | rc = genl_register_family(&ieee802154_coordinator_family); | ||
489 | if (rc) | ||
490 | goto fail; | ||
491 | |||
492 | rc = genl_register_mc_group(&ieee802154_coordinator_family, | ||
493 | &ieee802154_coord_mcgrp); | ||
494 | if (rc) | ||
495 | goto fail; | ||
496 | |||
497 | rc = genl_register_mc_group(&ieee802154_coordinator_family, | ||
498 | &ieee802154_beacon_mcgrp); | ||
499 | if (rc) | ||
500 | goto fail; | ||
501 | |||
502 | |||
503 | for (i = 0; i < ARRAY_SIZE(ieee802154_coordinator_ops); i++) { | ||
504 | rc = genl_register_ops(&ieee802154_coordinator_family, | ||
505 | &ieee802154_coordinator_ops[i]); | ||
506 | if (rc) | ||
507 | goto fail; | ||
508 | } | ||
509 | |||
510 | return 0; | ||
511 | |||
512 | fail: | ||
513 | genl_unregister_family(&ieee802154_coordinator_family); | ||
514 | return rc; | ||
515 | } | ||
516 | module_init(ieee802154_nl_init); | ||
517 | |||
518 | static void __exit ieee802154_nl_exit(void) | ||
519 | { | ||
520 | genl_unregister_family(&ieee802154_coordinator_family); | ||
521 | } | ||
522 | module_exit(ieee802154_nl_exit); | ||
523 | |||
diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c new file mode 100644 index 000000000000..c7d71d1adcac --- /dev/null +++ b/net/ieee802154/nl_policy.c | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * nl802154.h | ||
3 | * | ||
4 | * Copyright (C) 2007, 2008 Siemens AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <net/netlink.h> | ||
23 | #include <linux/nl802154.h> | ||
24 | |||
25 | #define NLA_HW_ADDR NLA_U64 | ||
26 | |||
27 | struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = { | ||
28 | [IEEE802154_ATTR_DEV_NAME] = { .type = NLA_STRING, }, | ||
29 | [IEEE802154_ATTR_DEV_INDEX] = { .type = NLA_U32, }, | ||
30 | |||
31 | [IEEE802154_ATTR_STATUS] = { .type = NLA_U8, }, | ||
32 | [IEEE802154_ATTR_SHORT_ADDR] = { .type = NLA_U16, }, | ||
33 | [IEEE802154_ATTR_HW_ADDR] = { .type = NLA_HW_ADDR, }, | ||
34 | [IEEE802154_ATTR_PAN_ID] = { .type = NLA_U16, }, | ||
35 | [IEEE802154_ATTR_CHANNEL] = { .type = NLA_U8, }, | ||
36 | [IEEE802154_ATTR_COORD_SHORT_ADDR] = { .type = NLA_U16, }, | ||
37 | [IEEE802154_ATTR_COORD_HW_ADDR] = { .type = NLA_HW_ADDR, }, | ||
38 | [IEEE802154_ATTR_COORD_PAN_ID] = { .type = NLA_U16, }, | ||
39 | [IEEE802154_ATTR_SRC_SHORT_ADDR] = { .type = NLA_U16, }, | ||
40 | [IEEE802154_ATTR_SRC_HW_ADDR] = { .type = NLA_HW_ADDR, }, | ||
41 | [IEEE802154_ATTR_SRC_PAN_ID] = { .type = NLA_U16, }, | ||
42 | [IEEE802154_ATTR_DEST_SHORT_ADDR] = { .type = NLA_U16, }, | ||
43 | [IEEE802154_ATTR_DEST_HW_ADDR] = { .type = NLA_HW_ADDR, }, | ||
44 | [IEEE802154_ATTR_DEST_PAN_ID] = { .type = NLA_U16, }, | ||
45 | |||
46 | [IEEE802154_ATTR_CAPABILITY] = { .type = NLA_U8, }, | ||
47 | [IEEE802154_ATTR_REASON] = { .type = NLA_U8, }, | ||
48 | [IEEE802154_ATTR_SCAN_TYPE] = { .type = NLA_U8, }, | ||
49 | [IEEE802154_ATTR_CHANNELS] = { .type = NLA_U32, }, | ||
50 | [IEEE802154_ATTR_DURATION] = { .type = NLA_U8, }, | ||
51 | [IEEE802154_ATTR_ED_LIST] = { .len = 27 }, | ||
52 | }; | ||
diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c new file mode 100644 index 000000000000..fca44d59f97e --- /dev/null +++ b/net/ieee802154/raw.c | |||
@@ -0,0 +1,254 @@ | |||
1 | /* | ||
2 | * Raw IEEE 802.15.4 sockets | ||
3 | * | ||
4 | * Copyright 2007, 2008 Siemens AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | * | ||
19 | * Written by: | ||
20 | * Sergey Lapin <slapin@ossfans.org> | ||
21 | * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | ||
22 | */ | ||
23 | |||
24 | #include <linux/net.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/if_arp.h> | ||
27 | #include <linux/list.h> | ||
28 | #include <net/sock.h> | ||
29 | #include <net/ieee802154/af_ieee802154.h> | ||
30 | |||
31 | #include "af802154.h" | ||
32 | |||
33 | static HLIST_HEAD(raw_head); | ||
34 | static DEFINE_RWLOCK(raw_lock); | ||
35 | |||
36 | static void raw_hash(struct sock *sk) | ||
37 | { | ||
38 | write_lock_bh(&raw_lock); | ||
39 | sk_add_node(sk, &raw_head); | ||
40 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | ||
41 | write_unlock_bh(&raw_lock); | ||
42 | } | ||
43 | |||
44 | static void raw_unhash(struct sock *sk) | ||
45 | { | ||
46 | write_lock_bh(&raw_lock); | ||
47 | if (sk_del_node_init(sk)) | ||
48 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); | ||
49 | write_unlock_bh(&raw_lock); | ||
50 | } | ||
51 | |||
52 | static void raw_close(struct sock *sk, long timeout) | ||
53 | { | ||
54 | sk_common_release(sk); | ||
55 | } | ||
56 | |||
57 | static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int len) | ||
58 | { | ||
59 | struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; | ||
60 | int err = 0; | ||
61 | struct net_device *dev = NULL; | ||
62 | |||
63 | if (len < sizeof(*addr)) | ||
64 | return -EINVAL; | ||
65 | |||
66 | if (addr->family != AF_IEEE802154) | ||
67 | return -EINVAL; | ||
68 | |||
69 | lock_sock(sk); | ||
70 | |||
71 | dev = ieee802154_get_dev(sock_net(sk), &addr->addr); | ||
72 | if (!dev) { | ||
73 | err = -ENODEV; | ||
74 | goto out; | ||
75 | } | ||
76 | |||
77 | if (dev->type != ARPHRD_IEEE802154_PHY && | ||
78 | dev->type != ARPHRD_IEEE802154) { | ||
79 | err = -ENODEV; | ||
80 | goto out_put; | ||
81 | } | ||
82 | |||
83 | sk->sk_bound_dev_if = dev->ifindex; | ||
84 | sk_dst_reset(sk); | ||
85 | |||
86 | out_put: | ||
87 | dev_put(dev); | ||
88 | out: | ||
89 | release_sock(sk); | ||
90 | |||
91 | return err; | ||
92 | } | ||
93 | |||
94 | static int raw_connect(struct sock *sk, struct sockaddr *uaddr, | ||
95 | int addr_len) | ||
96 | { | ||
97 | return -ENOTSUPP; | ||
98 | } | ||
99 | |||
100 | static int raw_disconnect(struct sock *sk, int flags) | ||
101 | { | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | ||
106 | size_t size) | ||
107 | { | ||
108 | struct net_device *dev; | ||
109 | unsigned mtu; | ||
110 | struct sk_buff *skb; | ||
111 | int err; | ||
112 | |||
113 | if (msg->msg_flags & MSG_OOB) { | ||
114 | pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags); | ||
115 | return -EOPNOTSUPP; | ||
116 | } | ||
117 | |||
118 | lock_sock(sk); | ||
119 | if (!sk->sk_bound_dev_if) | ||
120 | dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); | ||
121 | else | ||
122 | dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if); | ||
123 | release_sock(sk); | ||
124 | |||
125 | if (!dev) { | ||
126 | pr_debug("no dev\n"); | ||
127 | err = -ENXIO; | ||
128 | goto out; | ||
129 | } | ||
130 | |||
131 | mtu = dev->mtu; | ||
132 | pr_debug("name = %s, mtu = %u\n", dev->name, mtu); | ||
133 | |||
134 | if (size > mtu) { | ||
135 | pr_debug("size = %Zu, mtu = %u\n", size, mtu); | ||
136 | err = -EINVAL; | ||
137 | goto out_dev; | ||
138 | } | ||
139 | |||
140 | skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + size, | ||
141 | msg->msg_flags & MSG_DONTWAIT, &err); | ||
142 | if (!skb) | ||
143 | goto out_dev; | ||
144 | |||
145 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | ||
146 | |||
147 | skb_reset_mac_header(skb); | ||
148 | skb_reset_network_header(skb); | ||
149 | |||
150 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | ||
151 | if (err < 0) | ||
152 | goto out_skb; | ||
153 | |||
154 | skb->dev = dev; | ||
155 | skb->sk = sk; | ||
156 | skb->protocol = htons(ETH_P_IEEE802154); | ||
157 | |||
158 | dev_put(dev); | ||
159 | |||
160 | err = dev_queue_xmit(skb); | ||
161 | if (err > 0) | ||
162 | err = net_xmit_errno(err); | ||
163 | |||
164 | return err ?: size; | ||
165 | |||
166 | out_skb: | ||
167 | kfree_skb(skb); | ||
168 | out_dev: | ||
169 | dev_put(dev); | ||
170 | out: | ||
171 | return err; | ||
172 | } | ||
173 | |||
174 | static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | ||
175 | size_t len, int noblock, int flags, int *addr_len) | ||
176 | { | ||
177 | size_t copied = 0; | ||
178 | int err = -EOPNOTSUPP; | ||
179 | struct sk_buff *skb; | ||
180 | |||
181 | skb = skb_recv_datagram(sk, flags, noblock, &err); | ||
182 | if (!skb) | ||
183 | goto out; | ||
184 | |||
185 | copied = skb->len; | ||
186 | if (len < copied) { | ||
187 | msg->msg_flags |= MSG_TRUNC; | ||
188 | copied = len; | ||
189 | } | ||
190 | |||
191 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); | ||
192 | if (err) | ||
193 | goto done; | ||
194 | |||
195 | sock_recv_timestamp(msg, sk, skb); | ||
196 | |||
197 | if (flags & MSG_TRUNC) | ||
198 | copied = skb->len; | ||
199 | done: | ||
200 | skb_free_datagram(sk, skb); | ||
201 | out: | ||
202 | if (err) | ||
203 | return err; | ||
204 | return copied; | ||
205 | } | ||
206 | |||
207 | static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb) | ||
208 | { | ||
209 | if (sock_queue_rcv_skb(sk, skb) < 0) { | ||
210 | atomic_inc(&sk->sk_drops); | ||
211 | kfree_skb(skb); | ||
212 | return NET_RX_DROP; | ||
213 | } | ||
214 | |||
215 | return NET_RX_SUCCESS; | ||
216 | } | ||
217 | |||
218 | |||
219 | void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb) | ||
220 | { | ||
221 | struct sock *sk; | ||
222 | struct hlist_node *node; | ||
223 | |||
224 | read_lock(&raw_lock); | ||
225 | sk_for_each(sk, node, &raw_head) { | ||
226 | bh_lock_sock(sk); | ||
227 | if (!sk->sk_bound_dev_if || | ||
228 | sk->sk_bound_dev_if == dev->ifindex) { | ||
229 | |||
230 | struct sk_buff *clone; | ||
231 | |||
232 | clone = skb_clone(skb, GFP_ATOMIC); | ||
233 | if (clone) | ||
234 | raw_rcv_skb(sk, clone); | ||
235 | } | ||
236 | bh_unlock_sock(sk); | ||
237 | } | ||
238 | read_unlock(&raw_lock); | ||
239 | } | ||
240 | |||
241 | struct proto ieee802154_raw_prot = { | ||
242 | .name = "IEEE-802.15.4-RAW", | ||
243 | .owner = THIS_MODULE, | ||
244 | .obj_size = sizeof(struct sock), | ||
245 | .close = raw_close, | ||
246 | .bind = raw_bind, | ||
247 | .sendmsg = raw_sendmsg, | ||
248 | .recvmsg = raw_recvmsg, | ||
249 | .hash = raw_hash, | ||
250 | .unhash = raw_unhash, | ||
251 | .connect = raw_connect, | ||
252 | .disconnect = raw_disconnect, | ||
253 | }; | ||
254 | |||
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 1f1b82475eaf..575f9bd51ccd 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -507,7 +507,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, | |||
507 | /* If the first fragment is fragmented itself, we split | 507 | /* If the first fragment is fragmented itself, we split |
508 | * it to two chunks: the first with data and paged part | 508 | * it to two chunks: the first with data and paged part |
509 | * and the second, holding only fragments. */ | 509 | * and the second, holding only fragments. */ |
510 | if (skb_shinfo(head)->frag_list) { | 510 | if (skb_has_frags(head)) { |
511 | struct sk_buff *clone; | 511 | struct sk_buff *clone; |
512 | int i, plen = 0; | 512 | int i, plen = 0; |
513 | 513 | ||
@@ -516,7 +516,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, | |||
516 | clone->next = head->next; | 516 | clone->next = head->next; |
517 | head->next = clone; | 517 | head->next = clone; |
518 | skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; | 518 | skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; |
519 | skb_shinfo(head)->frag_list = NULL; | 519 | skb_frag_list_init(head); |
520 | for (i=0; i<skb_shinfo(head)->nr_frags; i++) | 520 | for (i=0; i<skb_shinfo(head)->nr_frags; i++) |
521 | plen += skb_shinfo(head)->frags[i].size; | 521 | plen += skb_shinfo(head)->frags[i].size; |
522 | clone->len = clone->data_len = head->data_len - plen; | 522 | clone->len = clone->data_len = head->data_len - plen; |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 3d6167fb2d97..247026282669 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -474,7 +474,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
474 | * LATER: this step can be merged to real generation of fragments, | 474 | * LATER: this step can be merged to real generation of fragments, |
475 | * we can switch to copy when see the first bad fragment. | 475 | * we can switch to copy when see the first bad fragment. |
476 | */ | 476 | */ |
477 | if (skb_shinfo(skb)->frag_list) { | 477 | if (skb_has_frags(skb)) { |
478 | struct sk_buff *frag; | 478 | struct sk_buff *frag; |
479 | int first_len = skb_pagelen(skb); | 479 | int first_len = skb_pagelen(skb); |
480 | int truesizes = 0; | 480 | int truesizes = 0; |
@@ -485,7 +485,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
485 | skb_cloned(skb)) | 485 | skb_cloned(skb)) |
486 | goto slow_path; | 486 | goto slow_path; |
487 | 487 | ||
488 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { | 488 | skb_walk_frags(skb, frag) { |
489 | /* Correct geometry. */ | 489 | /* Correct geometry. */ |
490 | if (frag->len > mtu || | 490 | if (frag->len > mtu || |
491 | ((frag->len & 7) && frag->next) || | 491 | ((frag->len & 7) && frag->next) || |
@@ -498,7 +498,6 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
498 | 498 | ||
499 | BUG_ON(frag->sk); | 499 | BUG_ON(frag->sk); |
500 | if (skb->sk) { | 500 | if (skb->sk) { |
501 | sock_hold(skb->sk); | ||
502 | frag->sk = skb->sk; | 501 | frag->sk = skb->sk; |
503 | frag->destructor = sock_wfree; | 502 | frag->destructor = sock_wfree; |
504 | truesizes += frag->truesize; | 503 | truesizes += frag->truesize; |
@@ -510,7 +509,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
510 | err = 0; | 509 | err = 0; |
511 | offset = 0; | 510 | offset = 0; |
512 | frag = skb_shinfo(skb)->frag_list; | 511 | frag = skb_shinfo(skb)->frag_list; |
513 | skb_shinfo(skb)->frag_list = NULL; | 512 | skb_frag_list_init(skb); |
514 | skb->data_len = first_len - skb_headlen(skb); | 513 | skb->data_len = first_len - skb_headlen(skb); |
515 | skb->truesize -= truesizes; | 514 | skb->truesize -= truesizes; |
516 | skb->len = first_len; | 515 | skb->len = first_len; |
diff --git a/net/ipv4/netfilter/nf_nat_proto_sctp.c b/net/ipv4/netfilter/nf_nat_proto_sctp.c index 65e470bc6123..3fc598eeeb1a 100644 --- a/net/ipv4/netfilter/nf_nat_proto_sctp.c +++ b/net/ipv4/netfilter/nf_nat_proto_sctp.c | |||
@@ -33,6 +33,7 @@ sctp_manip_pkt(struct sk_buff *skb, | |||
33 | enum nf_nat_manip_type maniptype) | 33 | enum nf_nat_manip_type maniptype) |
34 | { | 34 | { |
35 | const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff); | 35 | const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff); |
36 | struct sk_buff *frag; | ||
36 | sctp_sctphdr_t *hdr; | 37 | sctp_sctphdr_t *hdr; |
37 | unsigned int hdroff = iphdroff + iph->ihl*4; | 38 | unsigned int hdroff = iphdroff + iph->ihl*4; |
38 | __be32 oldip, newip; | 39 | __be32 oldip, newip; |
@@ -57,8 +58,8 @@ sctp_manip_pkt(struct sk_buff *skb, | |||
57 | } | 58 | } |
58 | 59 | ||
59 | crc32 = sctp_start_cksum((u8 *)hdr, skb_headlen(skb) - hdroff); | 60 | crc32 = sctp_start_cksum((u8 *)hdr, skb_headlen(skb) - hdroff); |
60 | for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) | 61 | skb_walk_frags(skb, frag) |
61 | crc32 = sctp_update_cksum((u8 *)skb->data, skb_headlen(skb), | 62 | crc32 = sctp_update_cksum((u8 *)frag->data, skb_headlen(frag), |
62 | crc32); | 63 | crc32); |
63 | crc32 = sctp_end_cksum(crc32); | 64 | crc32 = sctp_end_cksum(crc32); |
64 | hdr->checksum = crc32; | 65 | hdr->checksum = crc32; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index c8dc8e5a822f..7c76e3d18215 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -658,7 +658,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
658 | } | 658 | } |
659 | mtu -= hlen + sizeof(struct frag_hdr); | 659 | mtu -= hlen + sizeof(struct frag_hdr); |
660 | 660 | ||
661 | if (skb_shinfo(skb)->frag_list) { | 661 | if (skb_has_frags(skb)) { |
662 | int first_len = skb_pagelen(skb); | 662 | int first_len = skb_pagelen(skb); |
663 | int truesizes = 0; | 663 | int truesizes = 0; |
664 | 664 | ||
@@ -667,7 +667,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
667 | skb_cloned(skb)) | 667 | skb_cloned(skb)) |
668 | goto slow_path; | 668 | goto slow_path; |
669 | 669 | ||
670 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { | 670 | skb_walk_frags(skb, frag) { |
671 | /* Correct geometry. */ | 671 | /* Correct geometry. */ |
672 | if (frag->len > mtu || | 672 | if (frag->len > mtu || |
673 | ((frag->len & 7) && frag->next) || | 673 | ((frag->len & 7) && frag->next) || |
@@ -680,7 +680,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
680 | 680 | ||
681 | BUG_ON(frag->sk); | 681 | BUG_ON(frag->sk); |
682 | if (skb->sk) { | 682 | if (skb->sk) { |
683 | sock_hold(skb->sk); | ||
684 | frag->sk = skb->sk; | 683 | frag->sk = skb->sk; |
685 | frag->destructor = sock_wfree; | 684 | frag->destructor = sock_wfree; |
686 | truesizes += frag->truesize; | 685 | truesizes += frag->truesize; |
@@ -690,7 +689,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
690 | err = 0; | 689 | err = 0; |
691 | offset = 0; | 690 | offset = 0; |
692 | frag = skb_shinfo(skb)->frag_list; | 691 | frag = skb_shinfo(skb)->frag_list; |
693 | skb_shinfo(skb)->frag_list = NULL; | 692 | skb_frag_list_init(skb); |
694 | /* BUILD HEADER */ | 693 | /* BUILD HEADER */ |
695 | 694 | ||
696 | *prevhdr = NEXTHDR_FRAGMENT; | 695 | *prevhdr = NEXTHDR_FRAGMENT; |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 058a5e4a60c3..f3aba255ad9f 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -409,7 +409,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) | |||
409 | /* If the first fragment is fragmented itself, we split | 409 | /* If the first fragment is fragmented itself, we split |
410 | * it to two chunks: the first with data and paged part | 410 | * it to two chunks: the first with data and paged part |
411 | * and the second, holding only fragments. */ | 411 | * and the second, holding only fragments. */ |
412 | if (skb_shinfo(head)->frag_list) { | 412 | if (skb_has_frags(head)) { |
413 | struct sk_buff *clone; | 413 | struct sk_buff *clone; |
414 | int i, plen = 0; | 414 | int i, plen = 0; |
415 | 415 | ||
@@ -420,7 +420,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) | |||
420 | clone->next = head->next; | 420 | clone->next = head->next; |
421 | head->next = clone; | 421 | head->next = clone; |
422 | skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; | 422 | skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; |
423 | skb_shinfo(head)->frag_list = NULL; | 423 | skb_frag_list_init(head); |
424 | for (i=0; i<skb_shinfo(head)->nr_frags; i++) | 424 | for (i=0; i<skb_shinfo(head)->nr_frags; i++) |
425 | plen += skb_shinfo(head)->frags[i].size; | 425 | plen += skb_shinfo(head)->frags[i].size; |
426 | clone->len = clone->data_len = head->data_len - plen; | 426 | clone->len = clone->data_len = head->data_len - plen; |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 54a387d31e1a..2642a41a8535 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -494,7 +494,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, | |||
494 | /* If the first fragment is fragmented itself, we split | 494 | /* If the first fragment is fragmented itself, we split |
495 | * it to two chunks: the first with data and paged part | 495 | * it to two chunks: the first with data and paged part |
496 | * and the second, holding only fragments. */ | 496 | * and the second, holding only fragments. */ |
497 | if (skb_shinfo(head)->frag_list) { | 497 | if (skb_has_frags(head)) { |
498 | struct sk_buff *clone; | 498 | struct sk_buff *clone; |
499 | int i, plen = 0; | 499 | int i, plen = 0; |
500 | 500 | ||
@@ -503,7 +503,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, | |||
503 | clone->next = head->next; | 503 | clone->next = head->next; |
504 | head->next = clone; | 504 | head->next = clone; |
505 | skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; | 505 | skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; |
506 | skb_shinfo(head)->frag_list = NULL; | 506 | skb_frag_list_init(head); |
507 | for (i=0; i<skb_shinfo(head)->nr_frags; i++) | 507 | for (i=0; i<skb_shinfo(head)->nr_frags; i++) |
508 | plen += skb_shinfo(head)->frags[i].size; | 508 | plen += skb_shinfo(head)->frags[i].size; |
509 | clone->len = clone->data_len = head->data_len - plen; | 509 | clone->len = clone->data_len = head->data_len - plen; |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 43d00ffd3988..9e5762ad307d 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -132,6 +132,9 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
132 | 132 | ||
133 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 133 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
134 | 134 | ||
135 | if (*state == HT_AGG_STATE_OPERATIONAL) | ||
136 | sta->ampdu_mlme.addba_req_num[tid] = 0; | ||
137 | |||
135 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | | 138 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | |
136 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 139 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); |
137 | 140 | ||
@@ -337,6 +340,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
337 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, | 340 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, |
338 | sta->ampdu_mlme.tid_tx[tid]->ssn, | 341 | sta->ampdu_mlme.tid_tx[tid]->ssn, |
339 | 0x40, 5000); | 342 | 0x40, 5000); |
343 | sta->ampdu_mlme.addba_req_num[tid]++; | ||
340 | /* activate the timer for the recipient's addBA response */ | 344 | /* activate the timer for the recipient's addBA response */ |
341 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = | 345 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = |
342 | jiffies + ADDBA_RESP_INTERVAL; | 346 | jiffies + ADDBA_RESP_INTERVAL; |
@@ -606,7 +610,6 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
606 | 610 | ||
607 | *state = HT_AGG_STATE_IDLE; | 611 | *state = HT_AGG_STATE_IDLE; |
608 | /* from now on packets are no longer put onto sta->pending */ | 612 | /* from now on packets are no longer put onto sta->pending */ |
609 | sta->ampdu_mlme.addba_req_num[tid] = 0; | ||
610 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 613 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
611 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 614 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
612 | 615 | ||
@@ -689,7 +692,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
689 | 692 | ||
690 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 693 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
691 | } else { | 694 | } else { |
692 | sta->ampdu_mlme.addba_req_num[tid]++; | ||
693 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); | 695 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); |
694 | } | 696 | } |
695 | spin_unlock_bh(&sta->lock); | 697 | spin_unlock_bh(&sta->lock); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a9211cc183cb..3f47276caeb8 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1122,8 +1122,8 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, | |||
1122 | p.txop = params->txop; | 1122 | p.txop = params->txop; |
1123 | if (drv_conf_tx(local, params->queue, &p)) { | 1123 | if (drv_conf_tx(local, params->queue, &p)) { |
1124 | printk(KERN_DEBUG "%s: failed to set TX queue " | 1124 | printk(KERN_DEBUG "%s: failed to set TX queue " |
1125 | "parameters for queue %d\n", local->mdev->name, | 1125 | "parameters for queue %d\n", |
1126 | params->queue); | 1126 | wiphy_name(local->hw.wiphy), params->queue); |
1127 | return -EINVAL; | 1127 | return -EINVAL; |
1128 | } | 1128 | } |
1129 | 1129 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c088c46704a3..4dbc28964196 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -589,6 +589,7 @@ enum queue_stop_reason { | |||
589 | IEEE80211_QUEUE_STOP_REASON_AGGREGATION, | 589 | IEEE80211_QUEUE_STOP_REASON_AGGREGATION, |
590 | IEEE80211_QUEUE_STOP_REASON_SUSPEND, | 590 | IEEE80211_QUEUE_STOP_REASON_SUSPEND, |
591 | IEEE80211_QUEUE_STOP_REASON_PENDING, | 591 | IEEE80211_QUEUE_STOP_REASON_PENDING, |
592 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD, | ||
592 | }; | 593 | }; |
593 | 594 | ||
594 | struct ieee80211_master_priv { | 595 | struct ieee80211_master_priv { |
@@ -1121,6 +1122,10 @@ void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, | |||
1121 | enum queue_stop_reason reason); | 1122 | enum queue_stop_reason reason); |
1122 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, | 1123 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, |
1123 | enum queue_stop_reason reason); | 1124 | enum queue_stop_reason reason); |
1125 | void ieee80211_add_pending_skb(struct ieee80211_local *local, | ||
1126 | struct sk_buff *skb); | ||
1127 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, | ||
1128 | struct sk_buff_head *skbs); | ||
1124 | 1129 | ||
1125 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 1130 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, |
1126 | u16 transaction, u16 auth_alg, | 1131 | u16 transaction, u16 auth_alg, |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 2683df918073..092a017b237e 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -369,60 +369,12 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
369 | } | 369 | } |
370 | } | 370 | } |
371 | 371 | ||
372 | /* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to | ||
373 | * make a prepared TX frame (one that has been given to hw) to look like brand | ||
374 | * new IEEE 802.11 frame that is ready to go through TX processing again. | ||
375 | */ | ||
376 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | ||
377 | struct ieee80211_key *key, | ||
378 | struct sk_buff *skb) | ||
379 | { | ||
380 | unsigned int hdrlen, iv_len, mic_len; | ||
381 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
382 | |||
383 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | ||
384 | |||
385 | if (!key) | ||
386 | goto no_key; | ||
387 | |||
388 | switch (key->conf.alg) { | ||
389 | case ALG_WEP: | ||
390 | iv_len = WEP_IV_LEN; | ||
391 | mic_len = WEP_ICV_LEN; | ||
392 | break; | ||
393 | case ALG_TKIP: | ||
394 | iv_len = TKIP_IV_LEN; | ||
395 | mic_len = TKIP_ICV_LEN; | ||
396 | break; | ||
397 | case ALG_CCMP: | ||
398 | iv_len = CCMP_HDR_LEN; | ||
399 | mic_len = CCMP_MIC_LEN; | ||
400 | break; | ||
401 | default: | ||
402 | goto no_key; | ||
403 | } | ||
404 | |||
405 | if (skb->len >= hdrlen + mic_len && | ||
406 | !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | ||
407 | skb_trim(skb, skb->len - mic_len); | ||
408 | if (skb->len >= hdrlen + iv_len) { | ||
409 | memmove(skb->data + iv_len, skb->data, hdrlen); | ||
410 | hdr = (struct ieee80211_hdr *)skb_pull(skb, iv_len); | ||
411 | } | ||
412 | |||
413 | no_key: | ||
414 | if (ieee80211_is_data_qos(hdr->frame_control)) { | ||
415 | hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA); | ||
416 | memmove(skb->data + IEEE80211_QOS_CTL_LEN, skb->data, | ||
417 | hdrlen - IEEE80211_QOS_CTL_LEN); | ||
418 | skb_pull(skb, IEEE80211_QOS_CTL_LEN); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | 372 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, |
423 | struct sta_info *sta, | 373 | struct sta_info *sta, |
424 | struct sk_buff *skb) | 374 | struct sk_buff *skb) |
425 | { | 375 | { |
376 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
377 | |||
426 | sta->tx_filtered_count++; | 378 | sta->tx_filtered_count++; |
427 | 379 | ||
428 | /* | 380 | /* |
@@ -464,16 +416,15 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
464 | */ | 416 | */ |
465 | if (test_sta_flags(sta, WLAN_STA_PS) && | 417 | if (test_sta_flags(sta, WLAN_STA_PS) && |
466 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | 418 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { |
467 | ieee80211_remove_tx_extra(local, sta->key, skb); | ||
468 | skb_queue_tail(&sta->tx_filtered, skb); | 419 | skb_queue_tail(&sta->tx_filtered, skb); |
469 | return; | 420 | return; |
470 | } | 421 | } |
471 | 422 | ||
472 | if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) { | 423 | if (!test_sta_flags(sta, WLAN_STA_PS) && |
424 | !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { | ||
473 | /* Software retry the packet once */ | 425 | /* Software retry the packet once */ |
474 | skb->requeue = 1; | 426 | info->flags |= IEEE80211_TX_INTFL_RETRIED; |
475 | ieee80211_remove_tx_extra(local, sta->key, skb); | 427 | ieee80211_add_pending_skb(local, skb); |
476 | dev_queue_xmit(skb); | ||
477 | return; | 428 | return; |
478 | } | 429 | } |
479 | 430 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 509469cb9265..d779c57a8220 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -621,9 +621,6 @@ static void ieee80211_change_ps(struct ieee80211_local *local) | |||
621 | struct ieee80211_conf *conf = &local->hw.conf; | 621 | struct ieee80211_conf *conf = &local->hw.conf; |
622 | 622 | ||
623 | if (local->ps_sdata) { | 623 | if (local->ps_sdata) { |
624 | if (!(local->ps_sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED)) | ||
625 | return; | ||
626 | |||
627 | ieee80211_enable_ps(local, local->ps_sdata); | 624 | ieee80211_enable_ps(local, local->ps_sdata); |
628 | } else if (conf->flags & IEEE80211_CONF_PS) { | 625 | } else if (conf->flags & IEEE80211_CONF_PS) { |
629 | conf->flags &= ~IEEE80211_CONF_PS; | 626 | conf->flags &= ~IEEE80211_CONF_PS; |
@@ -653,7 +650,9 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | |||
653 | count++; | 650 | count++; |
654 | } | 651 | } |
655 | 652 | ||
656 | if (count == 1 && found->u.mgd.powersave) { | 653 | if (count == 1 && found->u.mgd.powersave && |
654 | (found->u.mgd.flags & IEEE80211_STA_ASSOCIATED) && | ||
655 | !(found->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL)) { | ||
657 | s32 beaconint_us; | 656 | s32 beaconint_us; |
658 | 657 | ||
659 | if (latency < 0) | 658 | if (latency < 0) |
@@ -793,13 +792,13 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
793 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 792 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
794 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " | 793 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " |
795 | "cWmin=%d cWmax=%d txop=%d\n", | 794 | "cWmin=%d cWmax=%d txop=%d\n", |
796 | local->mdev->name, queue, aci, acm, params.aifs, params.cw_min, | 795 | wiphy_name(local->hw.wiphy), queue, aci, acm, |
797 | params.cw_max, params.txop); | 796 | params.aifs, params.cw_min, params.cw_max, params.txop); |
798 | #endif | 797 | #endif |
799 | if (drv_conf_tx(local, queue, ¶ms) && local->ops->conf_tx) | 798 | if (drv_conf_tx(local, queue, ¶ms) && local->ops->conf_tx) |
800 | printk(KERN_DEBUG "%s: failed to set TX queue " | 799 | printk(KERN_DEBUG "%s: failed to set TX queue " |
801 | "parameters for queue %d\n", local->mdev->name, | 800 | "parameters for queue %d\n", |
802 | queue); | 801 | wiphy_name(local->hw.wiphy), queue); |
803 | } | 802 | } |
804 | } | 803 | } |
805 | 804 | ||
@@ -1322,6 +1321,11 @@ void ieee80211_beacon_loss_work(struct work_struct *work) | |||
1322 | #endif | 1321 | #endif |
1323 | 1322 | ||
1324 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; | 1323 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; |
1324 | |||
1325 | mutex_lock(&sdata->local->iflist_mtx); | ||
1326 | ieee80211_recalc_ps(sdata->local, -1); | ||
1327 | mutex_unlock(&sdata->local->iflist_mtx); | ||
1328 | |||
1325 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, | 1329 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, |
1326 | ifmgd->ssid_len, NULL, 0); | 1330 | ifmgd->ssid_len, NULL, 0); |
1327 | 1331 | ||
@@ -1342,6 +1346,7 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) | |||
1342 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1346 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1343 | struct ieee80211_local *local = sdata->local; | 1347 | struct ieee80211_local *local = sdata->local; |
1344 | struct sta_info *sta; | 1348 | struct sta_info *sta; |
1349 | unsigned long last_rx; | ||
1345 | bool disassoc = false; | 1350 | bool disassoc = false; |
1346 | 1351 | ||
1347 | /* TODO: start monitoring current AP signal quality and number of | 1352 | /* TODO: start monitoring current AP signal quality and number of |
@@ -1358,17 +1363,21 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) | |||
1358 | printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", | 1363 | printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", |
1359 | sdata->dev->name, ifmgd->bssid); | 1364 | sdata->dev->name, ifmgd->bssid); |
1360 | disassoc = true; | 1365 | disassoc = true; |
1361 | goto unlock; | 1366 | rcu_read_unlock(); |
1367 | goto out; | ||
1362 | } | 1368 | } |
1363 | 1369 | ||
1370 | last_rx = sta->last_rx; | ||
1371 | rcu_read_unlock(); | ||
1372 | |||
1364 | if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) && | 1373 | if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) && |
1365 | time_after(jiffies, sta->last_rx + IEEE80211_PROBE_WAIT)) { | 1374 | time_after(jiffies, last_rx + IEEE80211_PROBE_WAIT)) { |
1366 | printk(KERN_DEBUG "%s: no probe response from AP %pM " | 1375 | printk(KERN_DEBUG "%s: no probe response from AP %pM " |
1367 | "- disassociating\n", | 1376 | "- disassociating\n", |
1368 | sdata->dev->name, ifmgd->bssid); | 1377 | sdata->dev->name, ifmgd->bssid); |
1369 | disassoc = true; | 1378 | disassoc = true; |
1370 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; | 1379 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; |
1371 | goto unlock; | 1380 | goto out; |
1372 | } | 1381 | } |
1373 | 1382 | ||
1374 | /* | 1383 | /* |
@@ -1387,26 +1396,29 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) | |||
1387 | } | 1396 | } |
1388 | #endif | 1397 | #endif |
1389 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; | 1398 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; |
1399 | mutex_lock(&local->iflist_mtx); | ||
1400 | ieee80211_recalc_ps(local, -1); | ||
1401 | mutex_unlock(&local->iflist_mtx); | ||
1390 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, | 1402 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, |
1391 | ifmgd->ssid_len, NULL, 0); | 1403 | ifmgd->ssid_len, NULL, 0); |
1392 | mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT); | 1404 | mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT); |
1393 | goto unlock; | 1405 | goto out; |
1394 | } | 1406 | } |
1395 | 1407 | ||
1396 | if (time_after(jiffies, sta->last_rx + IEEE80211_PROBE_IDLE_TIME)) { | 1408 | if (time_after(jiffies, last_rx + IEEE80211_PROBE_IDLE_TIME)) { |
1397 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; | 1409 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; |
1410 | mutex_lock(&local->iflist_mtx); | ||
1411 | ieee80211_recalc_ps(local, -1); | ||
1412 | mutex_unlock(&local->iflist_mtx); | ||
1398 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, | 1413 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, |
1399 | ifmgd->ssid_len, NULL, 0); | 1414 | ifmgd->ssid_len, NULL, 0); |
1400 | } | 1415 | } |
1401 | 1416 | ||
1417 | out: | ||
1402 | if (!disassoc) | 1418 | if (!disassoc) |
1403 | mod_timer(&ifmgd->timer, | 1419 | mod_timer(&ifmgd->timer, |
1404 | jiffies + IEEE80211_MONITORING_INTERVAL); | 1420 | jiffies + IEEE80211_MONITORING_INTERVAL); |
1405 | 1421 | else | |
1406 | unlock: | ||
1407 | rcu_read_unlock(); | ||
1408 | |||
1409 | if (disassoc) | ||
1410 | ieee80211_set_disassoc(sdata, true, true, | 1422 | ieee80211_set_disassoc(sdata, true, true, |
1411 | WLAN_REASON_PREV_AUTH_NOT_VALID); | 1423 | WLAN_REASON_PREV_AUTH_NOT_VALID); |
1412 | } | 1424 | } |
@@ -1889,8 +1901,12 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
1889 | ieee80211_authenticate(sdata); | 1901 | ieee80211_authenticate(sdata); |
1890 | } | 1902 | } |
1891 | 1903 | ||
1892 | if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) | 1904 | if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) { |
1893 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; | 1905 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; |
1906 | mutex_lock(&sdata->local->iflist_mtx); | ||
1907 | ieee80211_recalc_ps(sdata->local, -1); | ||
1908 | mutex_unlock(&sdata->local->iflist_mtx); | ||
1909 | } | ||
1894 | } | 1910 | } |
1895 | 1911 | ||
1896 | /* | 1912 | /* |
@@ -1948,6 +1964,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1948 | } | 1964 | } |
1949 | #endif | 1965 | #endif |
1950 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; | 1966 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; |
1967 | mutex_lock(&local->iflist_mtx); | ||
1968 | ieee80211_recalc_ps(local, -1); | ||
1969 | mutex_unlock(&local->iflist_mtx); | ||
1951 | } | 1970 | } |
1952 | 1971 | ||
1953 | ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); | 1972 | ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 0a11515341ba..b218b98fba7f 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -215,7 +215,7 @@ minstrel_get_next_sample(struct minstrel_sta_info *mi) | |||
215 | unsigned int sample_ndx; | 215 | unsigned int sample_ndx; |
216 | sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column); | 216 | sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column); |
217 | mi->sample_idx++; | 217 | mi->sample_idx++; |
218 | if (mi->sample_idx > (mi->n_rates - 2)) { | 218 | if ((int) mi->sample_idx > (mi->n_rates - 2)) { |
219 | mi->sample_idx = 0; | 219 | mi->sample_idx = 0; |
220 | mi->sample_column++; | 220 | mi->sample_column++; |
221 | if (mi->sample_column >= SAMPLE_COLUMNS) | 221 | if (mi->sample_column >= SAMPLE_COLUMNS) |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 6a9b8e63a6bf..de5bba7f910a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -797,8 +797,7 @@ static int ap_sta_ps_end(struct sta_info *sta) | |||
797 | { | 797 | { |
798 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 798 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
799 | struct ieee80211_local *local = sdata->local; | 799 | struct ieee80211_local *local = sdata->local; |
800 | struct sk_buff *skb; | 800 | int sent, buffered; |
801 | int sent = 0; | ||
802 | 801 | ||
803 | atomic_dec(&sdata->bss->num_sta_ps); | 802 | atomic_dec(&sdata->bss->num_sta_ps); |
804 | 803 | ||
@@ -814,22 +813,16 @@ static int ap_sta_ps_end(struct sta_info *sta) | |||
814 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 813 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
815 | 814 | ||
816 | /* Send all buffered frames to the station */ | 815 | /* Send all buffered frames to the station */ |
817 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { | 816 | sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered); |
818 | sent++; | 817 | buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf); |
819 | skb->requeue = 1; | 818 | sent += buffered; |
820 | dev_queue_xmit(skb); | 819 | local->total_ps_buffered -= buffered; |
821 | } | 820 | |
822 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { | ||
823 | local->total_ps_buffered--; | ||
824 | sent++; | ||
825 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 821 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
826 | printk(KERN_DEBUG "%s: STA %pM aid %d send PS frame " | 822 | printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " |
827 | "since STA not sleeping anymore\n", sdata->dev->name, | 823 | "since STA not sleeping anymore\n", sdata->dev->name, |
828 | sta->sta.addr, sta->sta.aid); | 824 | sta->sta.addr, sta->sta.aid, sent - buffered, buffered); |
829 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 825 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
830 | skb->requeue = 1; | ||
831 | dev_queue_xmit(skb); | ||
832 | } | ||
833 | 826 | ||
834 | return sent; | 827 | return sent; |
835 | } | 828 | } |
@@ -1335,7 +1328,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1335 | * mac80211. That also explains the __skb_push() | 1328 | * mac80211. That also explains the __skb_push() |
1336 | * below. | 1329 | * below. |
1337 | */ | 1330 | */ |
1338 | align = (unsigned long)skb->data & 3; | 1331 | align = ((unsigned long)(skb->data + sizeof(struct ethhdr))) & 3; |
1339 | if (align) { | 1332 | if (align) { |
1340 | if (WARN_ON(skb_headroom(skb) < 3)) { | 1333 | if (WARN_ON(skb_headroom(skb) < 3)) { |
1341 | dev_kfree_skb(skb); | 1334 | dev_kfree_skb(skb); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 1436f747531a..364222bfb10d 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -400,6 +400,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
400 | sta_info_set_tim_bit(sta); | 400 | sta_info_set_tim_bit(sta); |
401 | 401 | ||
402 | info->control.jiffies = jiffies; | 402 | info->control.jiffies = jiffies; |
403 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | ||
403 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); | 404 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); |
404 | return TX_QUEUED; | 405 | return TX_QUEUED; |
405 | } | 406 | } |
@@ -420,7 +421,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
420 | * frame filtering and keeps a station blacklist on its own | 421 | * frame filtering and keeps a station blacklist on its own |
421 | * (e.g: p54), so that frames can be delivered unimpeded. | 422 | * (e.g: p54), so that frames can be delivered unimpeded. |
422 | * | 423 | * |
423 | * Note: It should be save to disable the filter now. | 424 | * Note: It should be safe to disable the filter now. |
424 | * As, it is really unlikely that we still have any pending | 425 | * As, it is really unlikely that we still have any pending |
425 | * frame for this station in the hw's buffers/fifos left, | 426 | * frame for this station in the hw's buffers/fifos left, |
426 | * that is not rejected with a unsuccessful tx_status yet. | 427 | * that is not rejected with a unsuccessful tx_status yet. |
@@ -907,9 +908,8 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) | |||
907 | * deal with packet injection down monitor interface | 908 | * deal with packet injection down monitor interface |
908 | * with Radiotap Header -- only called for monitor mode interface | 909 | * with Radiotap Header -- only called for monitor mode interface |
909 | */ | 910 | */ |
910 | static ieee80211_tx_result | 911 | static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, |
911 | __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | 912 | struct sk_buff *skb) |
912 | struct sk_buff *skb) | ||
913 | { | 913 | { |
914 | /* | 914 | /* |
915 | * this is the moment to interpret and discard the radiotap header that | 915 | * this is the moment to interpret and discard the radiotap header that |
@@ -960,7 +960,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
960 | * on transmission | 960 | * on transmission |
961 | */ | 961 | */ |
962 | if (skb->len < (iterator.max_length + FCS_LEN)) | 962 | if (skb->len < (iterator.max_length + FCS_LEN)) |
963 | return TX_DROP; | 963 | return false; |
964 | 964 | ||
965 | skb_trim(skb, skb->len - FCS_LEN); | 965 | skb_trim(skb, skb->len - FCS_LEN); |
966 | } | 966 | } |
@@ -982,7 +982,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
982 | } | 982 | } |
983 | 983 | ||
984 | if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */ | 984 | if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */ |
985 | return TX_DROP; | 985 | return false; |
986 | 986 | ||
987 | /* | 987 | /* |
988 | * remove the radiotap header | 988 | * remove the radiotap header |
@@ -991,7 +991,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
991 | */ | 991 | */ |
992 | skb_pull(skb, iterator.max_length); | 992 | skb_pull(skb, iterator.max_length); |
993 | 993 | ||
994 | return TX_CONTINUE; | 994 | return true; |
995 | } | 995 | } |
996 | 996 | ||
997 | /* | 997 | /* |
@@ -1025,7 +1025,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
1025 | /* process and remove the injection radiotap header */ | 1025 | /* process and remove the injection radiotap header */ |
1026 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1026 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1027 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) { | 1027 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) { |
1028 | if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP) | 1028 | if (!__ieee80211_parse_tx_radiotap(tx, skb)) |
1029 | return TX_DROP; | 1029 | return TX_DROP; |
1030 | 1030 | ||
1031 | /* | 1031 | /* |
@@ -1415,7 +1415,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1415 | } | 1415 | } |
1416 | 1416 | ||
1417 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && | 1417 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && |
1418 | local->hw.conf.dynamic_ps_timeout > 0) { | 1418 | local->hw.conf.dynamic_ps_timeout > 0 && |
1419 | !local->sw_scanning && !local->hw_scanning && local->ps_sdata) { | ||
1419 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 1420 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
1420 | ieee80211_stop_queues_by_reason(&local->hw, | 1421 | ieee80211_stop_queues_by_reason(&local->hw, |
1421 | IEEE80211_QUEUE_STOP_REASON_PS); | 1422 | IEEE80211_QUEUE_STOP_REASON_PS); |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 22f63815fb36..66ce96a69f31 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -341,6 +341,52 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) | |||
341 | } | 341 | } |
342 | EXPORT_SYMBOL(ieee80211_stop_queue); | 342 | EXPORT_SYMBOL(ieee80211_stop_queue); |
343 | 343 | ||
344 | void ieee80211_add_pending_skb(struct ieee80211_local *local, | ||
345 | struct sk_buff *skb) | ||
346 | { | ||
347 | struct ieee80211_hw *hw = &local->hw; | ||
348 | unsigned long flags; | ||
349 | int queue = skb_get_queue_mapping(skb); | ||
350 | |||
351 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
352 | __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | ||
353 | __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_PENDING); | ||
354 | skb_queue_tail(&local->pending[queue], skb); | ||
355 | __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | ||
356 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
357 | } | ||
358 | |||
359 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, | ||
360 | struct sk_buff_head *skbs) | ||
361 | { | ||
362 | struct ieee80211_hw *hw = &local->hw; | ||
363 | struct sk_buff *skb; | ||
364 | unsigned long flags; | ||
365 | int queue, ret = 0, i; | ||
366 | |||
367 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
368 | for (i = 0; i < hw->queues; i++) | ||
369 | __ieee80211_stop_queue(hw, i, | ||
370 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | ||
371 | |||
372 | while ((skb = skb_dequeue(skbs))) { | ||
373 | ret++; | ||
374 | queue = skb_get_queue_mapping(skb); | ||
375 | skb_queue_tail(&local->pending[queue], skb); | ||
376 | } | ||
377 | |||
378 | for (i = 0; i < hw->queues; i++) { | ||
379 | if (ret) | ||
380 | __ieee80211_stop_queue(hw, i, | ||
381 | IEEE80211_QUEUE_STOP_REASON_PENDING); | ||
382 | __ieee80211_wake_queue(hw, i, | ||
383 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | ||
384 | } | ||
385 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
386 | |||
387 | return ret; | ||
388 | } | ||
389 | |||
344 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, | 390 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, |
345 | enum queue_stop_reason reason) | 391 | enum queue_stop_reason reason) |
346 | { | 392 | { |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 694343b9102b..116a923b14d6 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -101,7 +101,7 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb) | |||
101 | * Now we know the 1d priority, fill in the QoS header if | 101 | * Now we know the 1d priority, fill in the QoS header if |
102 | * there is one (and we haven't done this before). | 102 | * there is one (and we haven't done this before). |
103 | */ | 103 | */ |
104 | if (!skb->requeue && ieee80211_is_data_qos(hdr->frame_control)) { | 104 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
105 | u8 *p = ieee80211_get_qos_ctl(hdr); | 105 | u8 *p = ieee80211_get_qos_ctl(hdr); |
106 | u8 ack_policy = 0; | 106 | u8 ack_policy = 0; |
107 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; | 107 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 8c860112ce05..71daa0934b6c 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * This is a module which is used for queueing packets and communicating with | 2 | * This is a module which is used for queueing packets and communicating with |
3 | * userspace via nfetlink. | 3 | * userspace via nfnetlink. |
4 | * | 4 | * |
5 | * (C) 2005 by Harald Welte <laforge@netfilter.org> | 5 | * (C) 2005 by Harald Welte <laforge@netfilter.org> |
6 | * (C) 2007 by Patrick McHardy <kaber@trash.net> | 6 | * (C) 2007 by Patrick McHardy <kaber@trash.net> |
@@ -932,6 +932,8 @@ static void __exit nfnetlink_queue_fini(void) | |||
932 | #endif | 932 | #endif |
933 | nfnetlink_subsys_unregister(&nfqnl_subsys); | 933 | nfnetlink_subsys_unregister(&nfqnl_subsys); |
934 | netlink_unregister_notifier(&nfqnl_rtnl_notifier); | 934 | netlink_unregister_notifier(&nfqnl_rtnl_notifier); |
935 | |||
936 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | ||
935 | } | 937 | } |
936 | 938 | ||
937 | MODULE_DESCRIPTION("netfilter packet queue handler"); | 939 | MODULE_DESCRIPTION("netfilter packet queue handler"); |
diff --git a/net/phonet/pep-gprs.c b/net/phonet/pep-gprs.c index 851f6a3f8ddd..480839dfc560 100644 --- a/net/phonet/pep-gprs.c +++ b/net/phonet/pep-gprs.c | |||
@@ -115,10 +115,10 @@ static int gprs_recv(struct gprs_dev *gp, struct sk_buff *skb) | |||
115 | rskb->truesize += rskb->len; | 115 | rskb->truesize += rskb->len; |
116 | 116 | ||
117 | /* Avoid nested fragments */ | 117 | /* Avoid nested fragments */ |
118 | for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next) | 118 | skb_walk_frags(skb, fs) |
119 | flen += fs->len; | 119 | flen += fs->len; |
120 | skb->next = skb_shinfo(skb)->frag_list; | 120 | skb->next = skb_shinfo(skb)->frag_list; |
121 | skb_shinfo(skb)->frag_list = NULL; | 121 | skb_frag_list_init(skb); |
122 | skb->len -= flen; | 122 | skb->len -= flen; |
123 | skb->data_len -= flen; | 123 | skb->data_len -= flen; |
124 | skb->truesize -= flen; | 124 | skb->truesize -= flen; |
diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 8ad2b5333881..eef833ea6d7b 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c | |||
@@ -940,10 +940,10 @@ int pep_write(struct sock *sk, struct sk_buff *skb) | |||
940 | rskb->truesize += rskb->len; | 940 | rskb->truesize += rskb->len; |
941 | 941 | ||
942 | /* Avoid nested fragments */ | 942 | /* Avoid nested fragments */ |
943 | for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next) | 943 | skb_walk_frags(skb, fs) |
944 | flen += fs->len; | 944 | flen += fs->len; |
945 | skb->next = skb_shinfo(skb)->frag_list; | 945 | skb->next = skb_shinfo(skb)->frag_list; |
946 | skb_shinfo(skb)->frag_list = NULL; | 946 | skb_frag_list_init(skb); |
947 | skb->len -= flen; | 947 | skb->len -= flen; |
948 | skb->data_len -= flen; | 948 | skb->data_len -= flen; |
949 | skb->truesize -= flen; | 949 | skb->truesize -= flen; |
diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig index fd7600d8ab14..eaf765876458 100644 --- a/net/rfkill/Kconfig +++ b/net/rfkill/Kconfig | |||
@@ -18,7 +18,7 @@ config RFKILL_LEDS | |||
18 | default y | 18 | default y |
19 | 19 | ||
20 | config RFKILL_INPUT | 20 | config RFKILL_INPUT |
21 | bool "RF switch input support" | 21 | bool "RF switch input support" if EMBEDDED |
22 | depends on RFKILL | 22 | depends on RFKILL |
23 | depends on INPUT = y || RFKILL = INPUT | 23 | depends on INPUT = y || RFKILL = INPUT |
24 | default y if !EMBEDDED | 24 | default y if !EMBEDDED |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 11b7314723df..4e68ab439d5d 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -57,6 +57,7 @@ struct rfkill { | |||
57 | 57 | ||
58 | bool registered; | 58 | bool registered; |
59 | bool suspended; | 59 | bool suspended; |
60 | bool persistent; | ||
60 | 61 | ||
61 | const struct rfkill_ops *ops; | 62 | const struct rfkill_ops *ops; |
62 | void *data; | 63 | void *data; |
@@ -116,11 +117,9 @@ MODULE_PARM_DESC(default_state, | |||
116 | "Default initial state for all radio types, 0 = radio off"); | 117 | "Default initial state for all radio types, 0 = radio off"); |
117 | 118 | ||
118 | static struct { | 119 | static struct { |
119 | bool cur, def; | 120 | bool cur, sav; |
120 | } rfkill_global_states[NUM_RFKILL_TYPES]; | 121 | } rfkill_global_states[NUM_RFKILL_TYPES]; |
121 | 122 | ||
122 | static unsigned long rfkill_states_default_locked; | ||
123 | |||
124 | static bool rfkill_epo_lock_active; | 123 | static bool rfkill_epo_lock_active; |
125 | 124 | ||
126 | 125 | ||
@@ -392,7 +391,7 @@ void rfkill_epo(void) | |||
392 | rfkill_set_block(rfkill, true); | 391 | rfkill_set_block(rfkill, true); |
393 | 392 | ||
394 | for (i = 0; i < NUM_RFKILL_TYPES; i++) { | 393 | for (i = 0; i < NUM_RFKILL_TYPES; i++) { |
395 | rfkill_global_states[i].def = rfkill_global_states[i].cur; | 394 | rfkill_global_states[i].sav = rfkill_global_states[i].cur; |
396 | rfkill_global_states[i].cur = true; | 395 | rfkill_global_states[i].cur = true; |
397 | } | 396 | } |
398 | 397 | ||
@@ -417,7 +416,7 @@ void rfkill_restore_states(void) | |||
417 | 416 | ||
418 | rfkill_epo_lock_active = false; | 417 | rfkill_epo_lock_active = false; |
419 | for (i = 0; i < NUM_RFKILL_TYPES; i++) | 418 | for (i = 0; i < NUM_RFKILL_TYPES; i++) |
420 | __rfkill_switch_all(i, rfkill_global_states[i].def); | 419 | __rfkill_switch_all(i, rfkill_global_states[i].sav); |
421 | mutex_unlock(&rfkill_global_mutex); | 420 | mutex_unlock(&rfkill_global_mutex); |
422 | } | 421 | } |
423 | 422 | ||
@@ -464,29 +463,6 @@ bool rfkill_get_global_sw_state(const enum rfkill_type type) | |||
464 | } | 463 | } |
465 | #endif | 464 | #endif |
466 | 465 | ||
467 | void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked) | ||
468 | { | ||
469 | BUG_ON(type == RFKILL_TYPE_ALL); | ||
470 | |||
471 | mutex_lock(&rfkill_global_mutex); | ||
472 | |||
473 | /* don't allow unblock when epo */ | ||
474 | if (rfkill_epo_lock_active && !blocked) | ||
475 | goto out; | ||
476 | |||
477 | /* too late */ | ||
478 | if (rfkill_states_default_locked & BIT(type)) | ||
479 | goto out; | ||
480 | |||
481 | rfkill_states_default_locked |= BIT(type); | ||
482 | |||
483 | rfkill_global_states[type].cur = blocked; | ||
484 | rfkill_global_states[type].def = blocked; | ||
485 | out: | ||
486 | mutex_unlock(&rfkill_global_mutex); | ||
487 | } | ||
488 | EXPORT_SYMBOL(rfkill_set_global_sw_state); | ||
489 | |||
490 | 466 | ||
491 | bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) | 467 | bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) |
492 | { | 468 | { |
@@ -532,13 +508,14 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked) | |||
532 | blocked = blocked || hwblock; | 508 | blocked = blocked || hwblock; |
533 | spin_unlock_irqrestore(&rfkill->lock, flags); | 509 | spin_unlock_irqrestore(&rfkill->lock, flags); |
534 | 510 | ||
535 | if (!rfkill->registered) | 511 | if (!rfkill->registered) { |
536 | return blocked; | 512 | rfkill->persistent = true; |
537 | 513 | } else { | |
538 | if (prev != blocked && !hwblock) | 514 | if (prev != blocked && !hwblock) |
539 | schedule_work(&rfkill->uevent_work); | 515 | schedule_work(&rfkill->uevent_work); |
540 | 516 | ||
541 | rfkill_led_trigger_event(rfkill); | 517 | rfkill_led_trigger_event(rfkill); |
518 | } | ||
542 | 519 | ||
543 | return blocked; | 520 | return blocked; |
544 | } | 521 | } |
@@ -563,13 +540,14 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) | |||
563 | 540 | ||
564 | spin_unlock_irqrestore(&rfkill->lock, flags); | 541 | spin_unlock_irqrestore(&rfkill->lock, flags); |
565 | 542 | ||
566 | if (!rfkill->registered) | 543 | if (!rfkill->registered) { |
567 | return; | 544 | rfkill->persistent = true; |
568 | 545 | } else { | |
569 | if (swprev != sw || hwprev != hw) | 546 | if (swprev != sw || hwprev != hw) |
570 | schedule_work(&rfkill->uevent_work); | 547 | schedule_work(&rfkill->uevent_work); |
571 | 548 | ||
572 | rfkill_led_trigger_event(rfkill); | 549 | rfkill_led_trigger_event(rfkill); |
550 | } | ||
573 | } | 551 | } |
574 | EXPORT_SYMBOL(rfkill_set_states); | 552 | EXPORT_SYMBOL(rfkill_set_states); |
575 | 553 | ||
@@ -750,15 +728,11 @@ static int rfkill_resume(struct device *dev) | |||
750 | struct rfkill *rfkill = to_rfkill(dev); | 728 | struct rfkill *rfkill = to_rfkill(dev); |
751 | bool cur; | 729 | bool cur; |
752 | 730 | ||
753 | mutex_lock(&rfkill_global_mutex); | 731 | cur = !!(rfkill->state & RFKILL_BLOCK_SW); |
754 | cur = rfkill_global_states[rfkill->type].cur; | ||
755 | rfkill_set_block(rfkill, cur); | 732 | rfkill_set_block(rfkill, cur); |
756 | mutex_unlock(&rfkill_global_mutex); | ||
757 | 733 | ||
758 | rfkill->suspended = false; | 734 | rfkill->suspended = false; |
759 | 735 | ||
760 | schedule_work(&rfkill->uevent_work); | ||
761 | |||
762 | rfkill_resume_polling(rfkill); | 736 | rfkill_resume_polling(rfkill); |
763 | 737 | ||
764 | return 0; | 738 | return 0; |
@@ -888,15 +862,6 @@ int __must_check rfkill_register(struct rfkill *rfkill) | |||
888 | dev_set_name(dev, "rfkill%lu", rfkill_no); | 862 | dev_set_name(dev, "rfkill%lu", rfkill_no); |
889 | rfkill_no++; | 863 | rfkill_no++; |
890 | 864 | ||
891 | if (!(rfkill_states_default_locked & BIT(rfkill->type))) { | ||
892 | /* first of its kind */ | ||
893 | BUILD_BUG_ON(NUM_RFKILL_TYPES > | ||
894 | sizeof(rfkill_states_default_locked) * 8); | ||
895 | rfkill_states_default_locked |= BIT(rfkill->type); | ||
896 | rfkill_global_states[rfkill->type].cur = | ||
897 | rfkill_global_states[rfkill->type].def; | ||
898 | } | ||
899 | |||
900 | list_add_tail(&rfkill->node, &rfkill_list); | 865 | list_add_tail(&rfkill->node, &rfkill_list); |
901 | 866 | ||
902 | error = device_add(dev); | 867 | error = device_add(dev); |
@@ -916,7 +881,17 @@ int __must_check rfkill_register(struct rfkill *rfkill) | |||
916 | if (rfkill->ops->poll) | 881 | if (rfkill->ops->poll) |
917 | schedule_delayed_work(&rfkill->poll_work, | 882 | schedule_delayed_work(&rfkill->poll_work, |
918 | round_jiffies_relative(POLL_INTERVAL)); | 883 | round_jiffies_relative(POLL_INTERVAL)); |
919 | schedule_work(&rfkill->sync_work); | 884 | |
885 | if (!rfkill->persistent || rfkill_epo_lock_active) { | ||
886 | schedule_work(&rfkill->sync_work); | ||
887 | } else { | ||
888 | #ifdef CONFIG_RFKILL_INPUT | ||
889 | bool soft_blocked = !!(rfkill->state & RFKILL_BLOCK_SW); | ||
890 | |||
891 | if (!atomic_read(&rfkill_input_disabled)) | ||
892 | __rfkill_switch_all(rfkill->type, soft_blocked); | ||
893 | #endif | ||
894 | } | ||
920 | 895 | ||
921 | rfkill_send_events(rfkill, RFKILL_OP_ADD); | 896 | rfkill_send_events(rfkill, RFKILL_OP_ADD); |
922 | 897 | ||
@@ -1134,7 +1109,8 @@ static int rfkill_fop_release(struct inode *inode, struct file *file) | |||
1134 | 1109 | ||
1135 | #ifdef CONFIG_RFKILL_INPUT | 1110 | #ifdef CONFIG_RFKILL_INPUT |
1136 | if (data->input_handler) | 1111 | if (data->input_handler) |
1137 | atomic_dec(&rfkill_input_disabled); | 1112 | if (atomic_dec_return(&rfkill_input_disabled) == 0) |
1113 | printk(KERN_DEBUG "rfkill: input handler enabled\n"); | ||
1138 | #endif | 1114 | #endif |
1139 | 1115 | ||
1140 | kfree(data); | 1116 | kfree(data); |
@@ -1157,7 +1133,8 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd, | |||
1157 | mutex_lock(&data->mtx); | 1133 | mutex_lock(&data->mtx); |
1158 | 1134 | ||
1159 | if (!data->input_handler) { | 1135 | if (!data->input_handler) { |
1160 | atomic_inc(&rfkill_input_disabled); | 1136 | if (atomic_inc_return(&rfkill_input_disabled) == 1) |
1137 | printk(KERN_DEBUG "rfkill: input handler disabled\n"); | ||
1161 | data->input_handler = true; | 1138 | data->input_handler = true; |
1162 | } | 1139 | } |
1163 | 1140 | ||
@@ -1191,7 +1168,7 @@ static int __init rfkill_init(void) | |||
1191 | int i; | 1168 | int i; |
1192 | 1169 | ||
1193 | for (i = 0; i < NUM_RFKILL_TYPES; i++) | 1170 | for (i = 0; i < NUM_RFKILL_TYPES; i++) |
1194 | rfkill_global_states[i].def = !rfkill_default_state; | 1171 | rfkill_global_states[i].cur = !rfkill_default_state; |
1195 | 1172 | ||
1196 | error = class_register(&rfkill_class); | 1173 | error = class_register(&rfkill_class); |
1197 | if (error) | 1174 | if (error) |
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 5022f9c1f34b..362c2811b2df 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c | |||
@@ -372,7 +372,7 @@ cftree_update(struct hfsc_class *cl) | |||
372 | * ism: (psched_us/byte) << ISM_SHIFT | 372 | * ism: (psched_us/byte) << ISM_SHIFT |
373 | * dx: psched_us | 373 | * dx: psched_us |
374 | * | 374 | * |
375 | * The clock source resolution with ktime is 1.024us. | 375 | * The clock source resolution with ktime and PSCHED_SHIFT 10 is 1.024us. |
376 | * | 376 | * |
377 | * sm and ism are scaled in order to keep effective digits. | 377 | * sm and ism are scaled in order to keep effective digits. |
378 | * SM_SHIFT and ISM_SHIFT are selected to keep at least 4 effective | 378 | * SM_SHIFT and ISM_SHIFT are selected to keep at least 4 effective |
@@ -383,9 +383,11 @@ cftree_update(struct hfsc_class *cl) | |||
383 | * bytes/1.024us 12.8e-3 128e-3 1280e-3 12800e-3 128000e-3 | 383 | * bytes/1.024us 12.8e-3 128e-3 1280e-3 12800e-3 128000e-3 |
384 | * | 384 | * |
385 | * 1.024us/byte 78.125 7.8125 0.78125 0.078125 0.0078125 | 385 | * 1.024us/byte 78.125 7.8125 0.78125 0.078125 0.0078125 |
386 | * | ||
387 | * So, for PSCHED_SHIFT 10 we need: SM_SHIFT 20, ISM_SHIFT 18. | ||
386 | */ | 388 | */ |
387 | #define SM_SHIFT 20 | 389 | #define SM_SHIFT (30 - PSCHED_SHIFT) |
388 | #define ISM_SHIFT 18 | 390 | #define ISM_SHIFT (8 + PSCHED_SHIFT) |
389 | 391 | ||
390 | #define SM_MASK ((1ULL << SM_SHIFT) - 1) | 392 | #define SM_MASK ((1ULL << SM_SHIFT) - 1) |
391 | #define ISM_MASK ((1ULL << ISM_SHIFT) - 1) | 393 | #define ISM_MASK ((1ULL << ISM_SHIFT) - 1) |
diff --git a/net/sctp/input.c b/net/sctp/input.c index d2e98803ffe3..c0c973e67add 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -81,13 +81,13 @@ static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb); | |||
81 | /* Calculate the SCTP checksum of an SCTP packet. */ | 81 | /* Calculate the SCTP checksum of an SCTP packet. */ |
82 | static inline int sctp_rcv_checksum(struct sk_buff *skb) | 82 | static inline int sctp_rcv_checksum(struct sk_buff *skb) |
83 | { | 83 | { |
84 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | ||
85 | struct sctphdr *sh = sctp_hdr(skb); | 84 | struct sctphdr *sh = sctp_hdr(skb); |
86 | __le32 cmp = sh->checksum; | 85 | __le32 cmp = sh->checksum; |
86 | struct sk_buff *list; | ||
87 | __le32 val; | 87 | __le32 val; |
88 | __u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb)); | 88 | __u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb)); |
89 | 89 | ||
90 | for (; list; list = list->next) | 90 | skb_walk_frags(skb, list) |
91 | tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list), | 91 | tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list), |
92 | tmp); | 92 | tmp); |
93 | 93 | ||
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index cb2c50dbd421..79cbd47f4df7 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -1370,6 +1370,8 @@ SCTP_STATIC __exit void sctp_exit(void) | |||
1370 | sctp_proc_exit(); | 1370 | sctp_proc_exit(); |
1371 | cleanup_sctp_mibs(); | 1371 | cleanup_sctp_mibs(); |
1372 | 1372 | ||
1373 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | ||
1374 | |||
1373 | kmem_cache_destroy(sctp_chunk_cachep); | 1375 | kmem_cache_destroy(sctp_chunk_cachep); |
1374 | kmem_cache_destroy(sctp_bucket_cachep); | 1376 | kmem_cache_destroy(sctp_bucket_cachep); |
1375 | } | 1377 | } |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 7c3dfd2d9489..0f01e5d8a24f 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1881,7 +1881,7 @@ static int sctp_skb_pull(struct sk_buff *skb, int len) | |||
1881 | len -= skb_len; | 1881 | len -= skb_len; |
1882 | __skb_pull(skb, skb_len); | 1882 | __skb_pull(skb, skb_len); |
1883 | 1883 | ||
1884 | for (list = skb_shinfo(skb)->frag_list; list; list = list->next) { | 1884 | skb_walk_frags(skb, list) { |
1885 | rlen = sctp_skb_pull(list, len); | 1885 | rlen = sctp_skb_pull(list, len); |
1886 | skb->len -= (len-rlen); | 1886 | skb->len -= (len-rlen); |
1887 | skb->data_len -= (len-rlen); | 1887 | skb->data_len -= (len-rlen); |
@@ -6660,7 +6660,7 @@ static void sctp_sock_rfree_frag(struct sk_buff *skb) | |||
6660 | goto done; | 6660 | goto done; |
6661 | 6661 | ||
6662 | /* Don't forget the fragments. */ | 6662 | /* Don't forget the fragments. */ |
6663 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) | 6663 | skb_walk_frags(skb, frag) |
6664 | sctp_sock_rfree_frag(frag); | 6664 | sctp_sock_rfree_frag(frag); |
6665 | 6665 | ||
6666 | done: | 6666 | done: |
@@ -6675,7 +6675,7 @@ static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) | |||
6675 | goto done; | 6675 | goto done; |
6676 | 6676 | ||
6677 | /* Don't forget the fragments. */ | 6677 | /* Don't forget the fragments. */ |
6678 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) | 6678 | skb_walk_frags(skb, frag) |
6679 | sctp_skb_set_owner_r_frag(frag, sk); | 6679 | sctp_skb_set_owner_r_frag(frag, sk); |
6680 | 6680 | ||
6681 | done: | 6681 | done: |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 5f186ca550d7..8b3560fd876d 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
@@ -976,9 +976,8 @@ static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event, | |||
976 | * In general, the skb passed from IP can have only 1 level of | 976 | * In general, the skb passed from IP can have only 1 level of |
977 | * fragments. But we allow multiple levels of fragments. | 977 | * fragments. But we allow multiple levels of fragments. |
978 | */ | 978 | */ |
979 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { | 979 | skb_walk_frags(skb, frag) |
980 | sctp_ulpevent_receive_data(sctp_skb2event(frag), asoc); | 980 | sctp_ulpevent_receive_data(sctp_skb2event(frag), asoc); |
981 | } | ||
982 | } | 981 | } |
983 | 982 | ||
984 | /* Do accounting for bytes just read by user and release the references to | 983 | /* Do accounting for bytes just read by user and release the references to |
@@ -1003,7 +1002,7 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) | |||
1003 | goto done; | 1002 | goto done; |
1004 | 1003 | ||
1005 | /* Don't forget the fragments. */ | 1004 | /* Don't forget the fragments. */ |
1006 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { | 1005 | skb_walk_frags(skb, frag) { |
1007 | /* NOTE: skb_shinfos are recursive. Although IP returns | 1006 | /* NOTE: skb_shinfos are recursive. Although IP returns |
1008 | * skb's with only 1 level of fragments, SCTP reassembly can | 1007 | * skb's with only 1 level of fragments, SCTP reassembly can |
1009 | * increase the levels. | 1008 | * increase the levels. |
@@ -1026,7 +1025,7 @@ static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event) | |||
1026 | goto done; | 1025 | goto done; |
1027 | 1026 | ||
1028 | /* Don't forget the fragments. */ | 1027 | /* Don't forget the fragments. */ |
1029 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { | 1028 | skb_walk_frags(skb, frag) { |
1030 | /* NOTE: skb_shinfos are recursive. Although IP returns | 1029 | /* NOTE: skb_shinfos are recursive. Although IP returns |
1031 | * skb's with only 1 level of fragments, SCTP reassembly can | 1030 | * skb's with only 1 level of fragments, SCTP reassembly can |
1032 | * increase the levels. | 1031 | * increase the levels. |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index e630b38a6047..66d458fc6920 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -1548,6 +1548,7 @@ static void __exit exit_rpcsec_gss(void) | |||
1548 | { | 1548 | { |
1549 | gss_svc_shutdown(); | 1549 | gss_svc_shutdown(); |
1550 | rpcauth_unregister(&authgss_ops); | 1550 | rpcauth_unregister(&authgss_ops); |
1551 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | ||
1551 | } | 1552 | } |
1552 | 1553 | ||
1553 | MODULE_LICENSE("GPL"); | 1554 | MODULE_LICENSE("GPL"); |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 3b74b88e10a3..d5850292b3df 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -395,21 +395,23 @@ int wiphy_register(struct wiphy *wiphy) | |||
395 | /* check and set up bitrates */ | 395 | /* check and set up bitrates */ |
396 | ieee80211_set_bitrate_flags(wiphy); | 396 | ieee80211_set_bitrate_flags(wiphy); |
397 | 397 | ||
398 | mutex_lock(&cfg80211_mutex); | ||
399 | |||
400 | /* set up regulatory info */ | ||
401 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); | ||
402 | |||
403 | res = device_add(&drv->wiphy.dev); | 398 | res = device_add(&drv->wiphy.dev); |
404 | if (res) | 399 | if (res) |
405 | goto out_unlock; | 400 | return res; |
406 | 401 | ||
407 | res = rfkill_register(drv->rfkill); | 402 | res = rfkill_register(drv->rfkill); |
408 | if (res) | 403 | if (res) |
409 | goto out_rm_dev; | 404 | goto out_rm_dev; |
410 | 405 | ||
406 | mutex_lock(&cfg80211_mutex); | ||
407 | |||
408 | /* set up regulatory info */ | ||
409 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); | ||
410 | |||
411 | list_add(&drv->list, &cfg80211_drv_list); | 411 | list_add(&drv->list, &cfg80211_drv_list); |
412 | 412 | ||
413 | mutex_unlock(&cfg80211_mutex); | ||
414 | |||
413 | /* add to debugfs */ | 415 | /* add to debugfs */ |
414 | drv->wiphy.debugfsdir = | 416 | drv->wiphy.debugfsdir = |
415 | debugfs_create_dir(wiphy_name(&drv->wiphy), | 417 | debugfs_create_dir(wiphy_name(&drv->wiphy), |
@@ -430,13 +432,10 @@ int wiphy_register(struct wiphy *wiphy) | |||
430 | 432 | ||
431 | cfg80211_debugfs_drv_add(drv); | 433 | cfg80211_debugfs_drv_add(drv); |
432 | 434 | ||
433 | res = 0; | 435 | return 0; |
434 | goto out_unlock; | ||
435 | 436 | ||
436 | out_rm_dev: | 437 | out_rm_dev: |
437 | device_del(&drv->wiphy.dev); | 438 | device_del(&drv->wiphy.dev); |
438 | out_unlock: | ||
439 | mutex_unlock(&cfg80211_mutex); | ||
440 | return res; | 439 | return res; |
441 | } | 440 | } |
442 | EXPORT_SYMBOL(wiphy_register); | 441 | EXPORT_SYMBOL(wiphy_register); |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index ea4c299fbe3b..5e14371cda70 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -2129,7 +2129,12 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2129 | * driver wanted to the wiphy to deal with conflicts | 2129 | * driver wanted to the wiphy to deal with conflicts |
2130 | */ | 2130 | */ |
2131 | 2131 | ||
2132 | BUG_ON(request_wiphy->regd); | 2132 | /* |
2133 | * Userspace could have sent two replies with only | ||
2134 | * one kernel request. | ||
2135 | */ | ||
2136 | if (request_wiphy->regd) | ||
2137 | return -EALREADY; | ||
2133 | 2138 | ||
2134 | r = reg_copy_regd(&request_wiphy->regd, rd); | 2139 | r = reg_copy_regd(&request_wiphy->regd, rd); |
2135 | if (r) | 2140 | if (r) |
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 96036cf2216d..d31ccb487730 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c | |||
@@ -696,8 +696,9 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, | |||
696 | { | 696 | { |
697 | int start = skb_headlen(skb); | 697 | int start = skb_headlen(skb); |
698 | int i, copy = start - offset; | 698 | int i, copy = start - offset; |
699 | int err; | 699 | struct sk_buff *frag_iter; |
700 | struct scatterlist sg; | 700 | struct scatterlist sg; |
701 | int err; | ||
701 | 702 | ||
702 | /* Checksum header. */ | 703 | /* Checksum header. */ |
703 | if (copy > 0) { | 704 | if (copy > 0) { |
@@ -742,28 +743,24 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, | |||
742 | start = end; | 743 | start = end; |
743 | } | 744 | } |
744 | 745 | ||
745 | if (skb_shinfo(skb)->frag_list) { | 746 | skb_walk_frags(skb, frag_iter) { |
746 | struct sk_buff *list = skb_shinfo(skb)->frag_list; | 747 | int end; |
747 | 748 | ||
748 | for (; list; list = list->next) { | 749 | WARN_ON(start > offset + len); |
749 | int end; | 750 | |
750 | 751 | end = start + frag_iter->len; | |
751 | WARN_ON(start > offset + len); | 752 | if ((copy = end - offset) > 0) { |
752 | 753 | if (copy > len) | |
753 | end = start + list->len; | 754 | copy = len; |
754 | if ((copy = end - offset) > 0) { | 755 | err = skb_icv_walk(frag_iter, desc, offset-start, |
755 | if (copy > len) | 756 | copy, icv_update); |
756 | copy = len; | 757 | if (unlikely(err)) |
757 | err = skb_icv_walk(list, desc, offset-start, | 758 | return err; |
758 | copy, icv_update); | 759 | if ((len -= copy) == 0) |
759 | if (unlikely(err)) | 760 | return 0; |
760 | return err; | 761 | offset += copy; |
761 | if ((len -= copy) == 0) | ||
762 | return 0; | ||
763 | offset += copy; | ||
764 | } | ||
765 | start = end; | ||
766 | } | 762 | } |
763 | start = end; | ||
767 | } | 764 | } |
768 | BUG_ON(len); | 765 | BUG_ON(len); |
769 | return 0; | 766 | return 0; |