1c891f3b9SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2367a1092SKalle Valo /******************************************************************************
3367a1092SKalle Valo
4367a1092SKalle Valo Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
5367a1092SKalle Valo
6367a1092SKalle Valo
7367a1092SKalle Valo Contact Information:
8367a1092SKalle Valo Intel Linux Wireless <ilw@linux.intel.com>
9367a1092SKalle Valo Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
10367a1092SKalle Valo
11367a1092SKalle Valo ******************************************************************************/
12367a1092SKalle Valo #include <linux/compiler.h>
13367a1092SKalle Valo #include <linux/errno.h>
14367a1092SKalle Valo #include <linux/if_arp.h>
15367a1092SKalle Valo #include <linux/in6.h>
16367a1092SKalle Valo #include <linux/in.h>
17367a1092SKalle Valo #include <linux/ip.h>
18367a1092SKalle Valo #include <linux/kernel.h>
19367a1092SKalle Valo #include <linux/module.h>
20367a1092SKalle Valo #include <linux/netdevice.h>
21367a1092SKalle Valo #include <linux/proc_fs.h>
22367a1092SKalle Valo #include <linux/skbuff.h>
23367a1092SKalle Valo #include <linux/slab.h>
24367a1092SKalle Valo #include <linux/tcp.h>
25367a1092SKalle Valo #include <linux/types.h>
26367a1092SKalle Valo #include <linux/wireless.h>
27367a1092SKalle Valo #include <linux/etherdevice.h>
287c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
29367a1092SKalle Valo
30367a1092SKalle Valo #include "libipw.h"
31367a1092SKalle Valo
32367a1092SKalle Valo /*
33367a1092SKalle Valo
34367a1092SKalle Valo 802.11 Data Frame
35367a1092SKalle Valo
36367a1092SKalle Valo ,-------------------------------------------------------------------.
37367a1092SKalle Valo Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
38367a1092SKalle Valo |------|------|---------|---------|---------|------|---------|------|
39367a1092SKalle Valo Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
40367a1092SKalle Valo | | tion | (BSSID) | | | ence | data | |
41367a1092SKalle Valo `--------------------------------------------------| |------'
42367a1092SKalle Valo Total: 28 non-data bytes `----.----'
43367a1092SKalle Valo |
44367a1092SKalle Valo .- 'Frame data' expands, if WEP enabled, to <----------'
45367a1092SKalle Valo |
46367a1092SKalle Valo V
47367a1092SKalle Valo ,-----------------------.
48367a1092SKalle Valo Bytes | 4 | 0-2296 | 4 |
49367a1092SKalle Valo |-----|-----------|-----|
50367a1092SKalle Valo Desc. | IV | Encrypted | ICV |
51367a1092SKalle Valo | | Packet | |
52367a1092SKalle Valo `-----| |-----'
53367a1092SKalle Valo `-----.-----'
54367a1092SKalle Valo |
55367a1092SKalle Valo .- 'Encrypted Packet' expands to
56367a1092SKalle Valo |
57367a1092SKalle Valo V
58367a1092SKalle Valo ,---------------------------------------------------.
59367a1092SKalle Valo Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
60367a1092SKalle Valo |------|------|---------|----------|------|---------|
61367a1092SKalle Valo Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
62367a1092SKalle Valo | DSAP | SSAP | | | | Packet |
63367a1092SKalle Valo | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
64367a1092SKalle Valo `----------------------------------------------------
65367a1092SKalle Valo Total: 8 non-data bytes
66367a1092SKalle Valo
67367a1092SKalle Valo 802.3 Ethernet Data Frame
68367a1092SKalle Valo
69367a1092SKalle Valo ,-----------------------------------------.
70367a1092SKalle Valo Bytes | 6 | 6 | 2 | Variable | 4 |
71367a1092SKalle Valo |-------|-------|------|-----------|------|
72367a1092SKalle Valo Desc. | Dest. | Source| Type | IP Packet | fcs |
73367a1092SKalle Valo | MAC | MAC | | | |
74367a1092SKalle Valo `-----------------------------------------'
75367a1092SKalle Valo Total: 18 non-data bytes
76367a1092SKalle Valo
77367a1092SKalle Valo In the event that fragmentation is required, the incoming payload is split into
78367a1092SKalle Valo N parts of size ieee->fts. The first fragment contains the SNAP header and the
79367a1092SKalle Valo remaining packets are just data.
80367a1092SKalle Valo
81367a1092SKalle Valo If encryption is enabled, each fragment payload size is reduced by enough space
82367a1092SKalle Valo to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
83367a1092SKalle Valo So if you have 1500 bytes of payload with ieee->fts set to 500 without
84367a1092SKalle Valo encryption it will take 3 frames. With WEP it will take 4 frames as the
85367a1092SKalle Valo payload of each frame is reduced to 492 bytes.
86367a1092SKalle Valo
87367a1092SKalle Valo * SKB visualization
88367a1092SKalle Valo *
89367a1092SKalle Valo * ,- skb->data
90367a1092SKalle Valo * |
91367a1092SKalle Valo * | ETHERNET HEADER ,-<-- PAYLOAD
92367a1092SKalle Valo * | | 14 bytes from skb->data
93367a1092SKalle Valo * | 2 bytes for Type --> ,T. | (sizeof ethhdr)
94367a1092SKalle Valo * | | | |
95367a1092SKalle Valo * |,-Dest.--. ,--Src.---. | | |
96367a1092SKalle Valo * | 6 bytes| | 6 bytes | | | |
97367a1092SKalle Valo * v | | | | | |
98367a1092SKalle Valo * 0 | v 1 | v | v 2
99367a1092SKalle Valo * 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
100367a1092SKalle Valo * ^ | ^ | ^ |
101367a1092SKalle Valo * | | | | | |
102367a1092SKalle Valo * | | | | `T' <---- 2 bytes for Type
103367a1092SKalle Valo * | | | |
104367a1092SKalle Valo * | | '---SNAP--' <-------- 6 bytes for SNAP
105367a1092SKalle Valo * | |
106367a1092SKalle Valo * `-IV--' <-------------------- 4 bytes for IV (WEP)
107367a1092SKalle Valo *
108367a1092SKalle Valo * SNAP HEADER
109367a1092SKalle Valo *
110367a1092SKalle Valo */
111367a1092SKalle Valo
112367a1092SKalle Valo static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
113367a1092SKalle Valo static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
114367a1092SKalle Valo
libipw_copy_snap(u8 * data,__be16 h_proto)115367a1092SKalle Valo static int libipw_copy_snap(u8 * data, __be16 h_proto)
116367a1092SKalle Valo {
117367a1092SKalle Valo struct libipw_snap_hdr *snap;
118367a1092SKalle Valo u8 *oui;
119367a1092SKalle Valo
120367a1092SKalle Valo snap = (struct libipw_snap_hdr *)data;
121367a1092SKalle Valo snap->dsap = 0xaa;
122367a1092SKalle Valo snap->ssap = 0xaa;
123367a1092SKalle Valo snap->ctrl = 0x03;
124367a1092SKalle Valo
125367a1092SKalle Valo if (h_proto == htons(ETH_P_AARP) || h_proto == htons(ETH_P_IPX))
126367a1092SKalle Valo oui = P802_1H_OUI;
127367a1092SKalle Valo else
128367a1092SKalle Valo oui = RFC1042_OUI;
129367a1092SKalle Valo snap->oui[0] = oui[0];
130367a1092SKalle Valo snap->oui[1] = oui[1];
131367a1092SKalle Valo snap->oui[2] = oui[2];
132367a1092SKalle Valo
133367a1092SKalle Valo memcpy(data + SNAP_SIZE, &h_proto, sizeof(u16));
134367a1092SKalle Valo
135367a1092SKalle Valo return SNAP_SIZE + sizeof(u16);
136367a1092SKalle Valo }
137367a1092SKalle Valo
libipw_encrypt_fragment(struct libipw_device * ieee,struct sk_buff * frag,int hdr_len)138367a1092SKalle Valo static int libipw_encrypt_fragment(struct libipw_device *ieee,
139367a1092SKalle Valo struct sk_buff *frag, int hdr_len)
140367a1092SKalle Valo {
141367a1092SKalle Valo struct lib80211_crypt_data *crypt =
142367a1092SKalle Valo ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
143367a1092SKalle Valo int res;
144367a1092SKalle Valo
145367a1092SKalle Valo if (crypt == NULL)
146367a1092SKalle Valo return -1;
147367a1092SKalle Valo
148367a1092SKalle Valo /* To encrypt, frame format is:
149367a1092SKalle Valo * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
150367a1092SKalle Valo atomic_inc(&crypt->refcnt);
151367a1092SKalle Valo res = 0;
152367a1092SKalle Valo if (crypt->ops && crypt->ops->encrypt_mpdu)
153367a1092SKalle Valo res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
154367a1092SKalle Valo
155367a1092SKalle Valo atomic_dec(&crypt->refcnt);
156367a1092SKalle Valo if (res < 0) {
157367a1092SKalle Valo printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
158367a1092SKalle Valo ieee->dev->name, frag->len);
159367a1092SKalle Valo ieee->ieee_stats.tx_discards++;
160367a1092SKalle Valo return -1;
161367a1092SKalle Valo }
162367a1092SKalle Valo
163367a1092SKalle Valo return 0;
164367a1092SKalle Valo }
165367a1092SKalle Valo
libipw_txb_free(struct libipw_txb * txb)166367a1092SKalle Valo void libipw_txb_free(struct libipw_txb *txb)
167367a1092SKalle Valo {
168367a1092SKalle Valo int i;
169367a1092SKalle Valo if (unlikely(!txb))
170367a1092SKalle Valo return;
171367a1092SKalle Valo for (i = 0; i < txb->nr_frags; i++)
172367a1092SKalle Valo if (txb->fragments[i])
173367a1092SKalle Valo dev_kfree_skb_any(txb->fragments[i]);
174367a1092SKalle Valo kfree(txb);
175367a1092SKalle Valo }
176367a1092SKalle Valo
libipw_alloc_txb(int nr_frags,int txb_size,int headroom,gfp_t gfp_mask)177367a1092SKalle Valo static struct libipw_txb *libipw_alloc_txb(int nr_frags, int txb_size,
178367a1092SKalle Valo int headroom, gfp_t gfp_mask)
179367a1092SKalle Valo {
180367a1092SKalle Valo struct libipw_txb *txb;
181367a1092SKalle Valo int i;
1826f78f4a4SLen Baker
183*3588e643SChen Ni txb = kzalloc(struct_size(txb, fragments, nr_frags), gfp_mask);
184367a1092SKalle Valo if (!txb)
185367a1092SKalle Valo return NULL;
186367a1092SKalle Valo
187367a1092SKalle Valo txb->nr_frags = nr_frags;
188367a1092SKalle Valo txb->frag_size = txb_size;
189367a1092SKalle Valo
190367a1092SKalle Valo for (i = 0; i < nr_frags; i++) {
191367a1092SKalle Valo txb->fragments[i] = __dev_alloc_skb(txb_size + headroom,
192367a1092SKalle Valo gfp_mask);
193367a1092SKalle Valo if (unlikely(!txb->fragments[i])) {
194367a1092SKalle Valo i--;
195367a1092SKalle Valo break;
196367a1092SKalle Valo }
197367a1092SKalle Valo skb_reserve(txb->fragments[i], headroom);
198367a1092SKalle Valo }
199367a1092SKalle Valo if (unlikely(i != nr_frags)) {
200367a1092SKalle Valo while (i >= 0)
201367a1092SKalle Valo dev_kfree_skb_any(txb->fragments[i--]);
202367a1092SKalle Valo kfree(txb);
203367a1092SKalle Valo return NULL;
204367a1092SKalle Valo }
205367a1092SKalle Valo return txb;
206367a1092SKalle Valo }
207367a1092SKalle Valo
libipw_classify(struct sk_buff * skb)208367a1092SKalle Valo static int libipw_classify(struct sk_buff *skb)
209367a1092SKalle Valo {
210367a1092SKalle Valo struct ethhdr *eth;
211367a1092SKalle Valo struct iphdr *ip;
212367a1092SKalle Valo
213367a1092SKalle Valo eth = (struct ethhdr *)skb->data;
214367a1092SKalle Valo if (eth->h_proto != htons(ETH_P_IP))
215367a1092SKalle Valo return 0;
216367a1092SKalle Valo
217367a1092SKalle Valo ip = ip_hdr(skb);
218367a1092SKalle Valo switch (ip->tos & 0xfc) {
219367a1092SKalle Valo case 0x20:
220367a1092SKalle Valo return 2;
221367a1092SKalle Valo case 0x40:
222367a1092SKalle Valo return 1;
223367a1092SKalle Valo case 0x60:
224367a1092SKalle Valo return 3;
225367a1092SKalle Valo case 0x80:
226367a1092SKalle Valo return 4;
227367a1092SKalle Valo case 0xa0:
228367a1092SKalle Valo return 5;
229367a1092SKalle Valo case 0xc0:
230367a1092SKalle Valo return 6;
231367a1092SKalle Valo case 0xe0:
232367a1092SKalle Valo return 7;
233367a1092SKalle Valo default:
234367a1092SKalle Valo return 0;
235367a1092SKalle Valo }
236367a1092SKalle Valo }
237367a1092SKalle Valo
238367a1092SKalle Valo /* Incoming skb is converted to a txb which consists of
239367a1092SKalle Valo * a block of 802.11 fragment packets (stored as skbs) */
libipw_xmit(struct sk_buff * skb,struct net_device * dev)240367a1092SKalle Valo netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
241367a1092SKalle Valo {
242367a1092SKalle Valo struct libipw_device *ieee = netdev_priv(dev);
243367a1092SKalle Valo struct libipw_txb *txb = NULL;
244367a1092SKalle Valo struct libipw_hdr_3addrqos *frag_hdr;
245367a1092SKalle Valo int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
246367a1092SKalle Valo rts_required;
247367a1092SKalle Valo unsigned long flags;
248367a1092SKalle Valo int encrypt, host_encrypt, host_encrypt_msdu;
249367a1092SKalle Valo __be16 ether_type;
250367a1092SKalle Valo int bytes, fc, hdr_len;
251367a1092SKalle Valo struct sk_buff *skb_frag;
252367a1092SKalle Valo struct libipw_hdr_3addrqos header = {/* Ensure zero initialized */
253367a1092SKalle Valo .duration_id = 0,
254367a1092SKalle Valo .seq_ctl = 0,
255367a1092SKalle Valo .qos_ctl = 0
256367a1092SKalle Valo };
257367a1092SKalle Valo u8 dest[ETH_ALEN], src[ETH_ALEN];
258367a1092SKalle Valo struct lib80211_crypt_data *crypt;
259367a1092SKalle Valo int priority = skb->priority;
260367a1092SKalle Valo int snapped = 0;
261367a1092SKalle Valo
262367a1092SKalle Valo if (ieee->is_queue_full && (*ieee->is_queue_full) (dev, priority))
263367a1092SKalle Valo return NETDEV_TX_BUSY;
264367a1092SKalle Valo
265367a1092SKalle Valo spin_lock_irqsave(&ieee->lock, flags);
266367a1092SKalle Valo
267367a1092SKalle Valo /* If there is no driver handler to take the TXB, dont' bother
268367a1092SKalle Valo * creating it... */
269367a1092SKalle Valo if (!ieee->hard_start_xmit) {
270367a1092SKalle Valo printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
271367a1092SKalle Valo goto success;
272367a1092SKalle Valo }
273367a1092SKalle Valo
274367a1092SKalle Valo if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
275367a1092SKalle Valo printk(KERN_WARNING "%s: skb too small (%d).\n",
276367a1092SKalle Valo ieee->dev->name, skb->len);
277367a1092SKalle Valo goto success;
278367a1092SKalle Valo }
279367a1092SKalle Valo
280367a1092SKalle Valo ether_type = ((struct ethhdr *)skb->data)->h_proto;
281367a1092SKalle Valo
282367a1092SKalle Valo crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
283367a1092SKalle Valo
284367a1092SKalle Valo encrypt = !(ether_type == htons(ETH_P_PAE) && ieee->ieee802_1x) &&
285367a1092SKalle Valo ieee->sec.encrypt;
286367a1092SKalle Valo
287367a1092SKalle Valo host_encrypt = ieee->host_encrypt && encrypt && crypt;
288367a1092SKalle Valo host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt;
289367a1092SKalle Valo
290367a1092SKalle Valo if (!encrypt && ieee->ieee802_1x &&
291367a1092SKalle Valo ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) {
292367a1092SKalle Valo dev->stats.tx_dropped++;
293367a1092SKalle Valo goto success;
294367a1092SKalle Valo }
295367a1092SKalle Valo
296367a1092SKalle Valo /* Save source and destination addresses */
297367a1092SKalle Valo skb_copy_from_linear_data(skb, dest, ETH_ALEN);
298367a1092SKalle Valo skb_copy_from_linear_data_offset(skb, ETH_ALEN, src, ETH_ALEN);
299367a1092SKalle Valo
300367a1092SKalle Valo if (host_encrypt)
301367a1092SKalle Valo fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
302367a1092SKalle Valo IEEE80211_FCTL_PROTECTED;
303367a1092SKalle Valo else
304367a1092SKalle Valo fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
305367a1092SKalle Valo
306367a1092SKalle Valo if (ieee->iw_mode == IW_MODE_INFRA) {
307367a1092SKalle Valo fc |= IEEE80211_FCTL_TODS;
308367a1092SKalle Valo /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
309367a1092SKalle Valo memcpy(header.addr1, ieee->bssid, ETH_ALEN);
310367a1092SKalle Valo memcpy(header.addr2, src, ETH_ALEN);
311367a1092SKalle Valo memcpy(header.addr3, dest, ETH_ALEN);
312367a1092SKalle Valo } else if (ieee->iw_mode == IW_MODE_ADHOC) {
313367a1092SKalle Valo /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
314367a1092SKalle Valo memcpy(header.addr1, dest, ETH_ALEN);
315367a1092SKalle Valo memcpy(header.addr2, src, ETH_ALEN);
316367a1092SKalle Valo memcpy(header.addr3, ieee->bssid, ETH_ALEN);
317367a1092SKalle Valo }
318367a1092SKalle Valo hdr_len = LIBIPW_3ADDR_LEN;
319367a1092SKalle Valo
320367a1092SKalle Valo if (ieee->is_qos_active && ieee->is_qos_active(dev, skb)) {
321367a1092SKalle Valo fc |= IEEE80211_STYPE_QOS_DATA;
322367a1092SKalle Valo hdr_len += 2;
323367a1092SKalle Valo
324367a1092SKalle Valo skb->priority = libipw_classify(skb);
325367a1092SKalle Valo header.qos_ctl |= cpu_to_le16(skb->priority & LIBIPW_QCTL_TID);
326367a1092SKalle Valo }
327367a1092SKalle Valo header.frame_ctl = cpu_to_le16(fc);
328367a1092SKalle Valo
329367a1092SKalle Valo /* Advance the SKB to the start of the payload */
330367a1092SKalle Valo skb_pull(skb, sizeof(struct ethhdr));
331367a1092SKalle Valo
332367a1092SKalle Valo /* Determine total amount of storage required for TXB packets */
333367a1092SKalle Valo bytes = skb->len + SNAP_SIZE + sizeof(u16);
334367a1092SKalle Valo
335367a1092SKalle Valo /* Encrypt msdu first on the whole data packet. */
336367a1092SKalle Valo if ((host_encrypt || host_encrypt_msdu) &&
337367a1092SKalle Valo crypt && crypt->ops && crypt->ops->encrypt_msdu) {
338367a1092SKalle Valo int res = 0;
339367a1092SKalle Valo int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len +
340367a1092SKalle Valo crypt->ops->extra_msdu_postfix_len;
341367a1092SKalle Valo struct sk_buff *skb_new = dev_alloc_skb(len);
342367a1092SKalle Valo
343367a1092SKalle Valo if (unlikely(!skb_new))
344367a1092SKalle Valo goto failed;
345367a1092SKalle Valo
346367a1092SKalle Valo skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len);
34759ae1d12SJohannes Berg skb_put_data(skb_new, &header, hdr_len);
348367a1092SKalle Valo snapped = 1;
349367a1092SKalle Valo libipw_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)),
350367a1092SKalle Valo ether_type);
351367a1092SKalle Valo skb_copy_from_linear_data(skb, skb_put(skb_new, skb->len), skb->len);
352367a1092SKalle Valo res = crypt->ops->encrypt_msdu(skb_new, hdr_len, crypt->priv);
353367a1092SKalle Valo if (res < 0) {
354367a1092SKalle Valo LIBIPW_ERROR("msdu encryption failed\n");
355367a1092SKalle Valo dev_kfree_skb_any(skb_new);
356367a1092SKalle Valo goto failed;
357367a1092SKalle Valo }
358367a1092SKalle Valo dev_kfree_skb_any(skb);
359367a1092SKalle Valo skb = skb_new;
360367a1092SKalle Valo bytes += crypt->ops->extra_msdu_prefix_len +
361367a1092SKalle Valo crypt->ops->extra_msdu_postfix_len;
362367a1092SKalle Valo skb_pull(skb, hdr_len);
363367a1092SKalle Valo }
364367a1092SKalle Valo
365367a1092SKalle Valo if (host_encrypt || ieee->host_open_frag) {
366367a1092SKalle Valo /* Determine fragmentation size based on destination (multicast
367367a1092SKalle Valo * and broadcast are not fragmented) */
368367a1092SKalle Valo if (is_multicast_ether_addr(dest) ||
369367a1092SKalle Valo is_broadcast_ether_addr(dest))
370367a1092SKalle Valo frag_size = MAX_FRAG_THRESHOLD;
371367a1092SKalle Valo else
372367a1092SKalle Valo frag_size = ieee->fts;
373367a1092SKalle Valo
374367a1092SKalle Valo /* Determine amount of payload per fragment. Regardless of if
375367a1092SKalle Valo * this stack is providing the full 802.11 header, one will
376367a1092SKalle Valo * eventually be affixed to this fragment -- so we must account
377367a1092SKalle Valo * for it when determining the amount of payload space. */
378367a1092SKalle Valo bytes_per_frag = frag_size - hdr_len;
379367a1092SKalle Valo if (ieee->config &
380367a1092SKalle Valo (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS))
381367a1092SKalle Valo bytes_per_frag -= LIBIPW_FCS_LEN;
382367a1092SKalle Valo
383367a1092SKalle Valo /* Each fragment may need to have room for encryption
384367a1092SKalle Valo * pre/postfix */
385e8366bbaSHaowen Bai if (host_encrypt && crypt && crypt->ops)
386367a1092SKalle Valo bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len +
387367a1092SKalle Valo crypt->ops->extra_mpdu_postfix_len;
388367a1092SKalle Valo
389367a1092SKalle Valo /* Number of fragments is the total
390367a1092SKalle Valo * bytes_per_frag / payload_per_fragment */
391367a1092SKalle Valo nr_frags = bytes / bytes_per_frag;
392367a1092SKalle Valo bytes_last_frag = bytes % bytes_per_frag;
393367a1092SKalle Valo if (bytes_last_frag)
394367a1092SKalle Valo nr_frags++;
395367a1092SKalle Valo else
396367a1092SKalle Valo bytes_last_frag = bytes_per_frag;
397367a1092SKalle Valo } else {
398367a1092SKalle Valo nr_frags = 1;
399367a1092SKalle Valo bytes_per_frag = bytes_last_frag = bytes;
400367a1092SKalle Valo frag_size = bytes + hdr_len;
401367a1092SKalle Valo }
402367a1092SKalle Valo
403367a1092SKalle Valo rts_required = (frag_size > ieee->rts
404367a1092SKalle Valo && ieee->config & CFG_LIBIPW_RTS);
405367a1092SKalle Valo if (rts_required)
406367a1092SKalle Valo nr_frags++;
407367a1092SKalle Valo
408367a1092SKalle Valo /* When we allocate the TXB we allocate enough space for the reserve
409367a1092SKalle Valo * and full fragment bytes (bytes_per_frag doesn't include prefix,
410367a1092SKalle Valo * postfix, header, FCS, etc.) */
411367a1092SKalle Valo txb = libipw_alloc_txb(nr_frags, frag_size,
412367a1092SKalle Valo ieee->tx_headroom, GFP_ATOMIC);
413367a1092SKalle Valo if (unlikely(!txb)) {
414367a1092SKalle Valo printk(KERN_WARNING "%s: Could not allocate TXB\n",
415367a1092SKalle Valo ieee->dev->name);
416367a1092SKalle Valo goto failed;
417367a1092SKalle Valo }
418367a1092SKalle Valo txb->encrypted = encrypt;
419367a1092SKalle Valo if (host_encrypt)
420367a1092SKalle Valo txb->payload_size = frag_size * (nr_frags - 1) +
421367a1092SKalle Valo bytes_last_frag;
422367a1092SKalle Valo else
423367a1092SKalle Valo txb->payload_size = bytes;
424367a1092SKalle Valo
425367a1092SKalle Valo if (rts_required) {
426367a1092SKalle Valo skb_frag = txb->fragments[0];
4274df864c1SJohannes Berg frag_hdr = skb_put(skb_frag, hdr_len);
428367a1092SKalle Valo
429367a1092SKalle Valo /*
430367a1092SKalle Valo * Set header frame_ctl to the RTS.
431367a1092SKalle Valo */
432367a1092SKalle Valo header.frame_ctl =
433367a1092SKalle Valo cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
434367a1092SKalle Valo memcpy(frag_hdr, &header, hdr_len);
435367a1092SKalle Valo
436367a1092SKalle Valo /*
437367a1092SKalle Valo * Restore header frame_ctl to the original data setting.
438367a1092SKalle Valo */
439367a1092SKalle Valo header.frame_ctl = cpu_to_le16(fc);
440367a1092SKalle Valo
441367a1092SKalle Valo if (ieee->config &
442367a1092SKalle Valo (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS))
443367a1092SKalle Valo skb_put(skb_frag, 4);
444367a1092SKalle Valo
445367a1092SKalle Valo txb->rts_included = 1;
446367a1092SKalle Valo i = 1;
447367a1092SKalle Valo } else
448367a1092SKalle Valo i = 0;
449367a1092SKalle Valo
450367a1092SKalle Valo for (; i < nr_frags; i++) {
451367a1092SKalle Valo skb_frag = txb->fragments[i];
452367a1092SKalle Valo
453367a1092SKalle Valo if (host_encrypt)
454367a1092SKalle Valo skb_reserve(skb_frag,
455367a1092SKalle Valo crypt->ops->extra_mpdu_prefix_len);
456367a1092SKalle Valo
45759ae1d12SJohannes Berg frag_hdr = skb_put_data(skb_frag, &header, hdr_len);
458367a1092SKalle Valo
459367a1092SKalle Valo /* If this is not the last fragment, then add the MOREFRAGS
460367a1092SKalle Valo * bit to the frame control */
461367a1092SKalle Valo if (i != nr_frags - 1) {
462367a1092SKalle Valo frag_hdr->frame_ctl =
463367a1092SKalle Valo cpu_to_le16(fc | IEEE80211_FCTL_MOREFRAGS);
464367a1092SKalle Valo bytes = bytes_per_frag;
465367a1092SKalle Valo } else {
466367a1092SKalle Valo /* The last fragment takes the remaining length */
467367a1092SKalle Valo bytes = bytes_last_frag;
468367a1092SKalle Valo }
469367a1092SKalle Valo
470367a1092SKalle Valo if (i == 0 && !snapped) {
471367a1092SKalle Valo libipw_copy_snap(skb_put
472367a1092SKalle Valo (skb_frag, SNAP_SIZE + sizeof(u16)),
473367a1092SKalle Valo ether_type);
474367a1092SKalle Valo bytes -= SNAP_SIZE + sizeof(u16);
475367a1092SKalle Valo }
476367a1092SKalle Valo
477367a1092SKalle Valo skb_copy_from_linear_data(skb, skb_put(skb_frag, bytes), bytes);
478367a1092SKalle Valo
479367a1092SKalle Valo /* Advance the SKB... */
480367a1092SKalle Valo skb_pull(skb, bytes);
481367a1092SKalle Valo
482367a1092SKalle Valo /* Encryption routine will move the header forward in order
483367a1092SKalle Valo * to insert the IV between the header and the payload */
484367a1092SKalle Valo if (host_encrypt)
485367a1092SKalle Valo libipw_encrypt_fragment(ieee, skb_frag, hdr_len);
486367a1092SKalle Valo
487367a1092SKalle Valo if (ieee->config &
488367a1092SKalle Valo (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS))
489367a1092SKalle Valo skb_put(skb_frag, 4);
490367a1092SKalle Valo }
491367a1092SKalle Valo
492367a1092SKalle Valo success:
493367a1092SKalle Valo spin_unlock_irqrestore(&ieee->lock, flags);
494367a1092SKalle Valo
495367a1092SKalle Valo dev_kfree_skb_any(skb);
496367a1092SKalle Valo
497367a1092SKalle Valo if (txb) {
498367a1092SKalle Valo netdev_tx_t ret = (*ieee->hard_start_xmit)(txb, dev, priority);
499367a1092SKalle Valo if (ret == NETDEV_TX_OK) {
500367a1092SKalle Valo dev->stats.tx_packets++;
501367a1092SKalle Valo dev->stats.tx_bytes += txb->payload_size;
502367a1092SKalle Valo return NETDEV_TX_OK;
503367a1092SKalle Valo }
504367a1092SKalle Valo
505367a1092SKalle Valo libipw_txb_free(txb);
506367a1092SKalle Valo }
507367a1092SKalle Valo
508367a1092SKalle Valo return NETDEV_TX_OK;
509367a1092SKalle Valo
510367a1092SKalle Valo failed:
511367a1092SKalle Valo spin_unlock_irqrestore(&ieee->lock, flags);
512367a1092SKalle Valo netif_stop_queue(dev);
513367a1092SKalle Valo dev->stats.tx_errors++;
514367a1092SKalle Valo return NETDEV_TX_BUSY;
515367a1092SKalle Valo }
516367a1092SKalle Valo EXPORT_SYMBOL(libipw_xmit);
517367a1092SKalle Valo
518367a1092SKalle Valo EXPORT_SYMBOL(libipw_txb_free);
519