blob: ecdf9f7a538fe19745bfeedd9d3bb743e5ca5618 [file] [log] [blame]
Jeff Garzikb4538722005-05-12 22:48:20 -04001/******************************************************************************
2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Contact Information:
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25******************************************************************************/
26#include <linux/compiler.h>
27#include <linux/config.h>
28#include <linux/errno.h>
29#include <linux/if_arp.h>
30#include <linux/in6.h>
31#include <linux/in.h>
32#include <linux/ip.h>
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/netdevice.h>
Jeff Garzikb4538722005-05-12 22:48:20 -040036#include <linux/proc_fs.h>
37#include <linux/skbuff.h>
38#include <linux/slab.h>
39#include <linux/tcp.h>
40#include <linux/types.h>
41#include <linux/version.h>
42#include <linux/wireless.h>
43#include <linux/etherdevice.h>
44#include <asm/uaccess.h>
45
46#include <net/ieee80211.h>
47
Jeff Garzikb4538722005-05-12 22:48:20 -040048/*
49
Jeff Garzikb4538722005-05-12 22:48:20 -040050802.11 Data Frame
51
52 ,-------------------------------------------------------------------.
53Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
54 |------|------|---------|---------|---------|------|---------|------|
55Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
56 | | tion | (BSSID) | | | ence | data | |
57 `--------------------------------------------------| |------'
58Total: 28 non-data bytes `----.----'
59 |
60 .- 'Frame data' expands to <---------------------------'
61 |
62 V
63 ,---------------------------------------------------.
64Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
65 |------|------|---------|----------|------|---------|
66Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
67 | DSAP | SSAP | | | | Packet |
68 | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
69 `-----------------------------------------| |
70Total: 8 non-data bytes `----.----'
71 |
72 .- 'IP Packet' expands, if WEP enabled, to <--'
73 |
74 V
75 ,-----------------------.
76Bytes | 4 | 0-2296 | 4 |
77 |-----|-----------|-----|
78Desc. | IV | Encrypted | ICV |
79 | | IP Packet | |
80 `-----------------------'
81Total: 8 non-data bytes
82
Jeff Garzikb4538722005-05-12 22:48:20 -040083802.3 Ethernet Data Frame
84
85 ,-----------------------------------------.
86Bytes | 6 | 6 | 2 | Variable | 4 |
87 |-------|-------|------|-----------|------|
88Desc. | Dest. | Source| Type | IP Packet | fcs |
89 | MAC | MAC | | | |
90 `-----------------------------------------'
91Total: 18 non-data bytes
92
93In the event that fragmentation is required, the incoming payload is split into
94N parts of size ieee->fts. The first fragment contains the SNAP header and the
95remaining packets are just data.
96
97If encryption is enabled, each fragment payload size is reduced by enough space
98to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
99So if you have 1500 bytes of payload with ieee->fts set to 500 without
100encryption it will take 3 frames. With WEP it will take 4 frames as the
101payload of each frame is reduced to 492 bytes.
102
103* SKB visualization
104*
105* ,- skb->data
106* |
107* | ETHERNET HEADER ,-<-- PAYLOAD
108* | | 14 bytes from skb->data
109* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
110* | | | |
111* |,-Dest.--. ,--Src.---. | | |
112* | 6 bytes| | 6 bytes | | | |
113* v | | | | | |
114* 0 | v 1 | v | v 2
115* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
116* ^ | ^ | ^ |
117* | | | | | |
118* | | | | `T' <---- 2 bytes for Type
119* | | | |
120* | | '---SNAP--' <-------- 6 bytes for SNAP
121* | |
122* `-IV--' <-------------------- 4 bytes for IV (WEP)
123*
124* SNAP HEADER
125*
126*/
127
128static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
129static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
130
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400131static inline int ieee80211_put_snap(u8 * data, u16 h_proto)
Jeff Garzikb4538722005-05-12 22:48:20 -0400132{
133 struct ieee80211_snap_hdr *snap;
134 u8 *oui;
135
136 snap = (struct ieee80211_snap_hdr *)data;
137 snap->dsap = 0xaa;
138 snap->ssap = 0xaa;
139 snap->ctrl = 0x03;
140
141 if (h_proto == 0x8137 || h_proto == 0x80f3)
142 oui = P802_1H_OUI;
143 else
144 oui = RFC1042_OUI;
145 snap->oui[0] = oui[0];
146 snap->oui[1] = oui[1];
147 snap->oui[2] = oui[2];
148
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400149 *(u16 *) (data + SNAP_SIZE) = htons(h_proto);
Jeff Garzikb4538722005-05-12 22:48:20 -0400150
151 return SNAP_SIZE + sizeof(u16);
152}
153
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400154static inline int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
155 struct sk_buff *frag, int hdr_len)
Jeff Garzikb4538722005-05-12 22:48:20 -0400156{
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400157 struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
Jeff Garzikb4538722005-05-12 22:48:20 -0400158 int res;
159
160#ifdef CONFIG_IEEE80211_CRYPT_TKIP
161 struct ieee80211_hdr *header;
162
163 if (ieee->tkip_countermeasures &&
164 crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400165 header = (struct ieee80211_hdr *)frag->data;
Jeff Garzikb4538722005-05-12 22:48:20 -0400166 if (net_ratelimit()) {
167 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
168 "TX packet to " MAC_FMT "\n",
169 ieee->dev->name, MAC_ARG(header->addr1));
170 }
171 return -1;
172 }
173#endif
174 /* To encrypt, frame format is:
175 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
176
177 // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
178 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
179 * call both MSDU and MPDU encryption functions from here. */
180 atomic_inc(&crypt->refcnt);
181 res = 0;
182 if (crypt->ops->encrypt_msdu)
183 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
184 if (res == 0 && crypt->ops->encrypt_mpdu)
185 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
186
187 atomic_dec(&crypt->refcnt);
188 if (res < 0) {
189 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
190 ieee->dev->name, frag->len);
191 ieee->ieee_stats.tx_discards++;
192 return -1;
193 }
194
195 return 0;
196}
197
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400198void ieee80211_txb_free(struct ieee80211_txb *txb)
199{
Jeff Garzikb4538722005-05-12 22:48:20 -0400200 int i;
201 if (unlikely(!txb))
202 return;
203 for (i = 0; i < txb->nr_frags; i++)
204 if (txb->fragments[i])
205 dev_kfree_skb_any(txb->fragments[i]);
206 kfree(txb);
207}
208
Adrian Bunke1572492005-05-06 23:32:39 +0200209static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
Randy Dunlapf36a29d2005-10-03 21:24:45 -0700210 unsigned int __nocast gfp_mask)
Jeff Garzikb4538722005-05-12 22:48:20 -0400211{
212 struct ieee80211_txb *txb;
213 int i;
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400214 txb = kmalloc(sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags),
215 gfp_mask);
Jeff Garzikb4538722005-05-12 22:48:20 -0400216 if (!txb)
217 return NULL;
218
Adrian Bunk0a989b22005-04-11 16:52:15 -0700219 memset(txb, 0, sizeof(struct ieee80211_txb));
Jeff Garzikb4538722005-05-12 22:48:20 -0400220 txb->nr_frags = nr_frags;
221 txb->frag_size = txb_size;
222
223 for (i = 0; i < nr_frags; i++) {
224 txb->fragments[i] = dev_alloc_skb(txb_size);
225 if (unlikely(!txb->fragments[i])) {
226 i--;
227 break;
228 }
229 }
230 if (unlikely(i != nr_frags)) {
231 while (i >= 0)
232 dev_kfree_skb_any(txb->fragments[i--]);
233 kfree(txb);
234 return NULL;
235 }
236 return txb;
237}
238
239/* SKBs are added to the ieee->tx_queue. */
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400240int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
Jeff Garzikb4538722005-05-12 22:48:20 -0400241{
242 struct ieee80211_device *ieee = netdev_priv(dev);
243 struct ieee80211_txb *txb = NULL;
244 struct ieee80211_hdr *frag_hdr;
245 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
246 unsigned long flags;
247 struct net_device_stats *stats = &ieee->stats;
248 int ether_type, encrypt;
249 int bytes, fc, hdr_len;
250 struct sk_buff *skb_frag;
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400251 struct ieee80211_hdr header = { /* Ensure zero initialized */
Jeff Garzikb4538722005-05-12 22:48:20 -0400252 .duration_id = 0,
253 .seq_ctl = 0
254 };
255 u8 dest[ETH_ALEN], src[ETH_ALEN];
256
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400257 struct ieee80211_crypt_data *crypt;
Jeff Garzikb4538722005-05-12 22:48:20 -0400258
259 spin_lock_irqsave(&ieee->lock, flags);
260
261 /* If there is no driver handler to take the TXB, dont' bother
262 * creating it... */
263 if (!ieee->hard_start_xmit) {
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400264 printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
Jeff Garzikb4538722005-05-12 22:48:20 -0400265 goto success;
266 }
267
268 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
269 printk(KERN_WARNING "%s: skb too small (%d).\n",
270 ieee->dev->name, skb->len);
271 goto success;
272 }
273
274 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
275
276 crypt = ieee->crypt[ieee->tx_keyidx];
277
278 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400279 ieee->host_encrypt && crypt && crypt->ops;
Jeff Garzikb4538722005-05-12 22:48:20 -0400280
281 if (!encrypt && ieee->ieee802_1x &&
282 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
283 stats->tx_dropped++;
284 goto success;
285 }
286
Jeff Garzikb4538722005-05-12 22:48:20 -0400287 /* Save source and destination addresses */
288 memcpy(&dest, skb->data, ETH_ALEN);
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400289 memcpy(&src, skb->data + ETH_ALEN, ETH_ALEN);
Jeff Garzikb4538722005-05-12 22:48:20 -0400290
291 /* Advance the SKB to the start of the payload */
292 skb_pull(skb, sizeof(struct ethhdr));
293
294 /* Determine total amount of storage required for TXB packets */
295 bytes = skb->len + SNAP_SIZE + sizeof(u16);
296
297 if (encrypt)
298 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400299 IEEE80211_FCTL_PROTECTED;
Jeff Garzikb4538722005-05-12 22:48:20 -0400300 else
301 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
302
303 if (ieee->iw_mode == IW_MODE_INFRA) {
304 fc |= IEEE80211_FCTL_TODS;
305 /* To DS: Addr1 = BSSID, Addr2 = SA,
306 Addr3 = DA */
307 memcpy(&header.addr1, ieee->bssid, ETH_ALEN);
308 memcpy(&header.addr2, &src, ETH_ALEN);
309 memcpy(&header.addr3, &dest, ETH_ALEN);
310 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
311 /* not From/To DS: Addr1 = DA, Addr2 = SA,
312 Addr3 = BSSID */
313 memcpy(&header.addr1, dest, ETH_ALEN);
314 memcpy(&header.addr2, src, ETH_ALEN);
315 memcpy(&header.addr3, ieee->bssid, ETH_ALEN);
316 }
317 header.frame_ctl = cpu_to_le16(fc);
318 hdr_len = IEEE80211_3ADDR_LEN;
319
320 /* Determine fragmentation size based on destination (multicast
321 * and broadcast are not fragmented) */
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400322 if (is_multicast_ether_addr(dest) || is_broadcast_ether_addr(dest))
Jeff Garzikb4538722005-05-12 22:48:20 -0400323 frag_size = MAX_FRAG_THRESHOLD;
324 else
325 frag_size = ieee->fts;
326
327 /* Determine amount of payload per fragment. Regardless of if
328 * this stack is providing the full 802.11 header, one will
329 * eventually be affixed to this fragment -- so we must account for
330 * it when determining the amount of payload space. */
331 bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
332 if (ieee->config &
333 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
334 bytes_per_frag -= IEEE80211_FCS_LEN;
335
336 /* Each fragment may need to have room for encryptiong pre/postfix */
337 if (encrypt)
338 bytes_per_frag -= crypt->ops->extra_prefix_len +
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400339 crypt->ops->extra_postfix_len;
Jeff Garzikb4538722005-05-12 22:48:20 -0400340
341 /* Number of fragments is the total bytes_per_frag /
342 * payload_per_fragment */
343 nr_frags = bytes / bytes_per_frag;
344 bytes_last_frag = bytes % bytes_per_frag;
345 if (bytes_last_frag)
346 nr_frags++;
347 else
348 bytes_last_frag = bytes_per_frag;
349
350 /* When we allocate the TXB we allocate enough space for the reserve
351 * and full fragment bytes (bytes_per_frag doesn't include prefix,
352 * postfix, header, FCS, etc.) */
353 txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
354 if (unlikely(!txb)) {
355 printk(KERN_WARNING "%s: Could not allocate TXB\n",
356 ieee->dev->name);
357 goto failed;
358 }
359 txb->encrypted = encrypt;
360 txb->payload_size = bytes;
361
362 for (i = 0; i < nr_frags; i++) {
363 skb_frag = txb->fragments[i];
364
365 if (encrypt)
366 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
367
368 frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len);
369 memcpy(frag_hdr, &header, hdr_len);
370
371 /* If this is not the last fragment, then add the MOREFRAGS
372 * bit to the frame control */
373 if (i != nr_frags - 1) {
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400374 frag_hdr->frame_ctl =
375 cpu_to_le16(fc | IEEE80211_FCTL_MOREFRAGS);
Jeff Garzikb4538722005-05-12 22:48:20 -0400376 bytes = bytes_per_frag;
377 } else {
378 /* The last fragment takes the remaining length */
379 bytes = bytes_last_frag;
380 }
381
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400382 /* Put a SNAP header on the first fragment */
Jeff Garzikb4538722005-05-12 22:48:20 -0400383 if (i == 0) {
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400384 ieee80211_put_snap(skb_put
385 (skb_frag, SNAP_SIZE + sizeof(u16)),
386 ether_type);
Jeff Garzikb4538722005-05-12 22:48:20 -0400387 bytes -= SNAP_SIZE + sizeof(u16);
388 }
389
390 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
391
392 /* Advance the SKB... */
393 skb_pull(skb, bytes);
394
395 /* Encryption routine will move the header forward in order
396 * to insert the IV between the header and the payload */
397 if (encrypt)
398 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
399 if (ieee->config &
400 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
401 skb_put(skb_frag, 4);
402 }
403
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400404 success:
Jeff Garzikb4538722005-05-12 22:48:20 -0400405 spin_unlock_irqrestore(&ieee->lock, flags);
406
407 dev_kfree_skb_any(skb);
408
409 if (txb) {
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400410 if ((*ieee->hard_start_xmit) (txb, dev) == 0) {
Jeff Garzikb4538722005-05-12 22:48:20 -0400411 stats->tx_packets++;
412 stats->tx_bytes += txb->payload_size;
413 return 0;
414 }
415 ieee80211_txb_free(txb);
416 }
417
418 return 0;
419
Jeff Garzik0edd5b42005-09-07 00:48:31 -0400420 failed:
Jeff Garzikb4538722005-05-12 22:48:20 -0400421 spin_unlock_irqrestore(&ieee->lock, flags);
422 netif_stop_queue(dev);
423 stats->tx_errors++;
424 return 1;
425
426}
427
428EXPORT_SYMBOL(ieee80211_txb_free);