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 
1836f78f4a4SLen Baker 	txb = kmalloc(struct_size(txb, fragments, nr_frags), gfp_mask);
184367a1092SKalle Valo 	if (!txb)
185367a1092SKalle Valo 		return NULL;
186367a1092SKalle Valo 
187367a1092SKalle Valo 	memset(txb, 0, sizeof(struct libipw_txb));
188367a1092SKalle Valo 	txb->nr_frags = nr_frags;
189367a1092SKalle Valo 	txb->frag_size = txb_size;
190367a1092SKalle Valo 
191367a1092SKalle Valo 	for (i = 0; i < nr_frags; i++) {
192367a1092SKalle Valo 		txb->fragments[i] = __dev_alloc_skb(txb_size + headroom,
193367a1092SKalle Valo 						    gfp_mask);
194367a1092SKalle Valo 		if (unlikely(!txb->fragments[i])) {
195367a1092SKalle Valo 			i--;
196367a1092SKalle Valo 			break;
197367a1092SKalle Valo 		}
198367a1092SKalle Valo 		skb_reserve(txb->fragments[i], headroom);
199367a1092SKalle Valo 	}
200367a1092SKalle Valo 	if (unlikely(i != nr_frags)) {
201367a1092SKalle Valo 		while (i >= 0)
202367a1092SKalle Valo 			dev_kfree_skb_any(txb->fragments[i--]);
203367a1092SKalle Valo 		kfree(txb);
204367a1092SKalle Valo 		return NULL;
205367a1092SKalle Valo 	}
206367a1092SKalle Valo 	return txb;
207367a1092SKalle Valo }
208367a1092SKalle Valo 
libipw_classify(struct sk_buff * skb)209367a1092SKalle Valo static int libipw_classify(struct sk_buff *skb)
210367a1092SKalle Valo {
211367a1092SKalle Valo 	struct ethhdr *eth;
212367a1092SKalle Valo 	struct iphdr *ip;
213367a1092SKalle Valo 
214367a1092SKalle Valo 	eth = (struct ethhdr *)skb->data;
215367a1092SKalle Valo 	if (eth->h_proto != htons(ETH_P_IP))
216367a1092SKalle Valo 		return 0;
217367a1092SKalle Valo 
218367a1092SKalle Valo 	ip = ip_hdr(skb);
219367a1092SKalle Valo 	switch (ip->tos & 0xfc) {
220367a1092SKalle Valo 	case 0x20:
221367a1092SKalle Valo 		return 2;
222367a1092SKalle Valo 	case 0x40:
223367a1092SKalle Valo 		return 1;
224367a1092SKalle Valo 	case 0x60:
225367a1092SKalle Valo 		return 3;
226367a1092SKalle Valo 	case 0x80:
227367a1092SKalle Valo 		return 4;
228367a1092SKalle Valo 	case 0xa0:
229367a1092SKalle Valo 		return 5;
230367a1092SKalle Valo 	case 0xc0:
231367a1092SKalle Valo 		return 6;
232367a1092SKalle Valo 	case 0xe0:
233367a1092SKalle Valo 		return 7;
234367a1092SKalle Valo 	default:
235367a1092SKalle Valo 		return 0;
236367a1092SKalle Valo 	}
237367a1092SKalle Valo }
238367a1092SKalle Valo 
239367a1092SKalle Valo /* Incoming skb is converted to a txb which consists of
240367a1092SKalle Valo  * a block of 802.11 fragment packets (stored as skbs) */
libipw_xmit(struct sk_buff * skb,struct net_device * dev)241367a1092SKalle Valo netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
242367a1092SKalle Valo {
243367a1092SKalle Valo 	struct libipw_device *ieee = netdev_priv(dev);
244367a1092SKalle Valo 	struct libipw_txb *txb = NULL;
245367a1092SKalle Valo 	struct libipw_hdr_3addrqos *frag_hdr;
246367a1092SKalle Valo 	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
247367a1092SKalle Valo 	    rts_required;
248367a1092SKalle Valo 	unsigned long flags;
249367a1092SKalle Valo 	int encrypt, host_encrypt, host_encrypt_msdu;
250367a1092SKalle Valo 	__be16 ether_type;
251367a1092SKalle Valo 	int bytes, fc, hdr_len;
252367a1092SKalle Valo 	struct sk_buff *skb_frag;
253367a1092SKalle Valo 	struct libipw_hdr_3addrqos header = {/* Ensure zero initialized */
254367a1092SKalle Valo 		.duration_id = 0,
255367a1092SKalle Valo 		.seq_ctl = 0,
256367a1092SKalle Valo 		.qos_ctl = 0
257367a1092SKalle Valo 	};
258367a1092SKalle Valo 	u8 dest[ETH_ALEN], src[ETH_ALEN];
259367a1092SKalle Valo 	struct lib80211_crypt_data *crypt;
260367a1092SKalle Valo 	int priority = skb->priority;
261367a1092SKalle Valo 	int snapped = 0;
262367a1092SKalle Valo 
263367a1092SKalle Valo 	if (ieee->is_queue_full && (*ieee->is_queue_full) (dev, priority))
264367a1092SKalle Valo 		return NETDEV_TX_BUSY;
265367a1092SKalle Valo 
266367a1092SKalle Valo 	spin_lock_irqsave(&ieee->lock, flags);
267367a1092SKalle Valo 
268367a1092SKalle Valo 	/* If there is no driver handler to take the TXB, dont' bother
269367a1092SKalle Valo 	 * creating it... */
270367a1092SKalle Valo 	if (!ieee->hard_start_xmit) {
271367a1092SKalle Valo 		printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
272367a1092SKalle Valo 		goto success;
273367a1092SKalle Valo 	}
274367a1092SKalle Valo 
275367a1092SKalle Valo 	if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
276367a1092SKalle Valo 		printk(KERN_WARNING "%s: skb too small (%d).\n",
277367a1092SKalle Valo 		       ieee->dev->name, skb->len);
278367a1092SKalle Valo 		goto success;
279367a1092SKalle Valo 	}
280367a1092SKalle Valo 
281367a1092SKalle Valo 	ether_type = ((struct ethhdr *)skb->data)->h_proto;
282367a1092SKalle Valo 
283367a1092SKalle Valo 	crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
284367a1092SKalle Valo 
285367a1092SKalle Valo 	encrypt = !(ether_type == htons(ETH_P_PAE) && ieee->ieee802_1x) &&
286367a1092SKalle Valo 	    ieee->sec.encrypt;
287367a1092SKalle Valo 
288367a1092SKalle Valo 	host_encrypt = ieee->host_encrypt && encrypt && crypt;
289367a1092SKalle Valo 	host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt;
290367a1092SKalle Valo 
291367a1092SKalle Valo 	if (!encrypt && ieee->ieee802_1x &&
292367a1092SKalle Valo 	    ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) {
293367a1092SKalle Valo 		dev->stats.tx_dropped++;
294367a1092SKalle Valo 		goto success;
295367a1092SKalle Valo 	}
296367a1092SKalle Valo 
297367a1092SKalle Valo 	/* Save source and destination addresses */
298367a1092SKalle Valo 	skb_copy_from_linear_data(skb, dest, ETH_ALEN);
299367a1092SKalle Valo 	skb_copy_from_linear_data_offset(skb, ETH_ALEN, src, ETH_ALEN);
300367a1092SKalle Valo 
301367a1092SKalle Valo 	if (host_encrypt)
302367a1092SKalle Valo 		fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
303367a1092SKalle Valo 		    IEEE80211_FCTL_PROTECTED;
304367a1092SKalle Valo 	else
305367a1092SKalle Valo 		fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
306367a1092SKalle Valo 
307367a1092SKalle Valo 	if (ieee->iw_mode == IW_MODE_INFRA) {
308367a1092SKalle Valo 		fc |= IEEE80211_FCTL_TODS;
309367a1092SKalle Valo 		/* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
310367a1092SKalle Valo 		memcpy(header.addr1, ieee->bssid, ETH_ALEN);
311367a1092SKalle Valo 		memcpy(header.addr2, src, ETH_ALEN);
312367a1092SKalle Valo 		memcpy(header.addr3, dest, ETH_ALEN);
313367a1092SKalle Valo 	} else if (ieee->iw_mode == IW_MODE_ADHOC) {
314367a1092SKalle Valo 		/* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
315367a1092SKalle Valo 		memcpy(header.addr1, dest, ETH_ALEN);
316367a1092SKalle Valo 		memcpy(header.addr2, src, ETH_ALEN);
317367a1092SKalle Valo 		memcpy(header.addr3, ieee->bssid, ETH_ALEN);
318367a1092SKalle Valo 	}
319367a1092SKalle Valo 	hdr_len = LIBIPW_3ADDR_LEN;
320367a1092SKalle Valo 
321367a1092SKalle Valo 	if (ieee->is_qos_active && ieee->is_qos_active(dev, skb)) {
322367a1092SKalle Valo 		fc |= IEEE80211_STYPE_QOS_DATA;
323367a1092SKalle Valo 		hdr_len += 2;
324367a1092SKalle Valo 
325367a1092SKalle Valo 		skb->priority = libipw_classify(skb);
326367a1092SKalle Valo 		header.qos_ctl |= cpu_to_le16(skb->priority & LIBIPW_QCTL_TID);
327367a1092SKalle Valo 	}
328367a1092SKalle Valo 	header.frame_ctl = cpu_to_le16(fc);
329367a1092SKalle Valo 
330367a1092SKalle Valo 	/* Advance the SKB to the start of the payload */
331367a1092SKalle Valo 	skb_pull(skb, sizeof(struct ethhdr));
332367a1092SKalle Valo 
333367a1092SKalle Valo 	/* Determine total amount of storage required for TXB packets */
334367a1092SKalle Valo 	bytes = skb->len + SNAP_SIZE + sizeof(u16);
335367a1092SKalle Valo 
336367a1092SKalle Valo 	/* Encrypt msdu first on the whole data packet. */
337367a1092SKalle Valo 	if ((host_encrypt || host_encrypt_msdu) &&
338367a1092SKalle Valo 	    crypt && crypt->ops && crypt->ops->encrypt_msdu) {
339367a1092SKalle Valo 		int res = 0;
340367a1092SKalle Valo 		int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len +
341367a1092SKalle Valo 		    crypt->ops->extra_msdu_postfix_len;
342367a1092SKalle Valo 		struct sk_buff *skb_new = dev_alloc_skb(len);
343367a1092SKalle Valo 
344367a1092SKalle Valo 		if (unlikely(!skb_new))
345367a1092SKalle Valo 			goto failed;
346367a1092SKalle Valo 
347367a1092SKalle Valo 		skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len);
34859ae1d12SJohannes Berg 		skb_put_data(skb_new, &header, hdr_len);
349367a1092SKalle Valo 		snapped = 1;
350367a1092SKalle Valo 		libipw_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)),
351367a1092SKalle Valo 				    ether_type);
352367a1092SKalle Valo 		skb_copy_from_linear_data(skb, skb_put(skb_new, skb->len), skb->len);
353367a1092SKalle Valo 		res = crypt->ops->encrypt_msdu(skb_new, hdr_len, crypt->priv);
354367a1092SKalle Valo 		if (res < 0) {
355367a1092SKalle Valo 			LIBIPW_ERROR("msdu encryption failed\n");
356367a1092SKalle Valo 			dev_kfree_skb_any(skb_new);
357367a1092SKalle Valo 			goto failed;
358367a1092SKalle Valo 		}
359367a1092SKalle Valo 		dev_kfree_skb_any(skb);
360367a1092SKalle Valo 		skb = skb_new;
361367a1092SKalle Valo 		bytes += crypt->ops->extra_msdu_prefix_len +
362367a1092SKalle Valo 		    crypt->ops->extra_msdu_postfix_len;
363367a1092SKalle Valo 		skb_pull(skb, hdr_len);
364367a1092SKalle Valo 	}
365367a1092SKalle Valo 
366367a1092SKalle Valo 	if (host_encrypt || ieee->host_open_frag) {
367367a1092SKalle Valo 		/* Determine fragmentation size based on destination (multicast
368367a1092SKalle Valo 		 * and broadcast are not fragmented) */
369367a1092SKalle Valo 		if (is_multicast_ether_addr(dest) ||
370367a1092SKalle Valo 		    is_broadcast_ether_addr(dest))
371367a1092SKalle Valo 			frag_size = MAX_FRAG_THRESHOLD;
372367a1092SKalle Valo 		else
373367a1092SKalle Valo 			frag_size = ieee->fts;
374367a1092SKalle Valo 
375367a1092SKalle Valo 		/* Determine amount of payload per fragment.  Regardless of if
376367a1092SKalle Valo 		 * this stack is providing the full 802.11 header, one will
377367a1092SKalle Valo 		 * eventually be affixed to this fragment -- so we must account
378367a1092SKalle Valo 		 * for it when determining the amount of payload space. */
379367a1092SKalle Valo 		bytes_per_frag = frag_size - hdr_len;
380367a1092SKalle Valo 		if (ieee->config &
381367a1092SKalle Valo 		    (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS))
382367a1092SKalle Valo 			bytes_per_frag -= LIBIPW_FCS_LEN;
383367a1092SKalle Valo 
384367a1092SKalle Valo 		/* Each fragment may need to have room for encryption
385367a1092SKalle Valo 		 * pre/postfix */
38648d4a820SHaowen Bai 		if (host_encrypt && crypt && crypt->ops)
387367a1092SKalle Valo 			bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len +
388367a1092SKalle Valo 			    crypt->ops->extra_mpdu_postfix_len;
389367a1092SKalle Valo 
390367a1092SKalle Valo 		/* Number of fragments is the total
391367a1092SKalle Valo 		 * bytes_per_frag / payload_per_fragment */
392367a1092SKalle Valo 		nr_frags = bytes / bytes_per_frag;
393367a1092SKalle Valo 		bytes_last_frag = bytes % bytes_per_frag;
394367a1092SKalle Valo 		if (bytes_last_frag)
395367a1092SKalle Valo 			nr_frags++;
396367a1092SKalle Valo 		else
397367a1092SKalle Valo 			bytes_last_frag = bytes_per_frag;
398367a1092SKalle Valo 	} else {
399367a1092SKalle Valo 		nr_frags = 1;
400367a1092SKalle Valo 		bytes_per_frag = bytes_last_frag = bytes;
401367a1092SKalle Valo 		frag_size = bytes + hdr_len;
402367a1092SKalle Valo 	}
403367a1092SKalle Valo 
404367a1092SKalle Valo 	rts_required = (frag_size > ieee->rts
405367a1092SKalle Valo 			&& ieee->config & CFG_LIBIPW_RTS);
406367a1092SKalle Valo 	if (rts_required)
407367a1092SKalle Valo 		nr_frags++;
408367a1092SKalle Valo 
409367a1092SKalle Valo 	/* When we allocate the TXB we allocate enough space for the reserve
410367a1092SKalle Valo 	 * and full fragment bytes (bytes_per_frag doesn't include prefix,
411367a1092SKalle Valo 	 * postfix, header, FCS, etc.) */
412367a1092SKalle Valo 	txb = libipw_alloc_txb(nr_frags, frag_size,
413367a1092SKalle Valo 				  ieee->tx_headroom, GFP_ATOMIC);
414367a1092SKalle Valo 	if (unlikely(!txb)) {
415367a1092SKalle Valo 		printk(KERN_WARNING "%s: Could not allocate TXB\n",
416367a1092SKalle Valo 		       ieee->dev->name);
417367a1092SKalle Valo 		goto failed;
418367a1092SKalle Valo 	}
419367a1092SKalle Valo 	txb->encrypted = encrypt;
420367a1092SKalle Valo 	if (host_encrypt)
421367a1092SKalle Valo 		txb->payload_size = frag_size * (nr_frags - 1) +
422367a1092SKalle Valo 		    bytes_last_frag;
423367a1092SKalle Valo 	else
424367a1092SKalle Valo 		txb->payload_size = bytes;
425367a1092SKalle Valo 
426367a1092SKalle Valo 	if (rts_required) {
427367a1092SKalle Valo 		skb_frag = txb->fragments[0];
4284df864c1SJohannes Berg 		frag_hdr = skb_put(skb_frag, hdr_len);
429367a1092SKalle Valo 
430367a1092SKalle Valo 		/*
431367a1092SKalle Valo 		 * Set header frame_ctl to the RTS.
432367a1092SKalle Valo 		 */
433367a1092SKalle Valo 		header.frame_ctl =
434367a1092SKalle Valo 		    cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
435367a1092SKalle Valo 		memcpy(frag_hdr, &header, hdr_len);
436367a1092SKalle Valo 
437367a1092SKalle Valo 		/*
438367a1092SKalle Valo 		 * Restore header frame_ctl to the original data setting.
439367a1092SKalle Valo 		 */
440367a1092SKalle Valo 		header.frame_ctl = cpu_to_le16(fc);
441367a1092SKalle Valo 
442367a1092SKalle Valo 		if (ieee->config &
443367a1092SKalle Valo 		    (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS))
444367a1092SKalle Valo 			skb_put(skb_frag, 4);
445367a1092SKalle Valo 
446367a1092SKalle Valo 		txb->rts_included = 1;
447367a1092SKalle Valo 		i = 1;
448367a1092SKalle Valo 	} else
449367a1092SKalle Valo 		i = 0;
450367a1092SKalle Valo 
451367a1092SKalle Valo 	for (; i < nr_frags; i++) {
452367a1092SKalle Valo 		skb_frag = txb->fragments[i];
453367a1092SKalle Valo 
454367a1092SKalle Valo 		if (host_encrypt)
455367a1092SKalle Valo 			skb_reserve(skb_frag,
456367a1092SKalle Valo 				    crypt->ops->extra_mpdu_prefix_len);
457367a1092SKalle Valo 
45859ae1d12SJohannes Berg 		frag_hdr = skb_put_data(skb_frag, &header, hdr_len);
459367a1092SKalle Valo 
460367a1092SKalle Valo 		/* If this is not the last fragment, then add the MOREFRAGS
461367a1092SKalle Valo 		 * bit to the frame control */
462367a1092SKalle Valo 		if (i != nr_frags - 1) {
463367a1092SKalle Valo 			frag_hdr->frame_ctl =
464367a1092SKalle Valo 			    cpu_to_le16(fc | IEEE80211_FCTL_MOREFRAGS);
465367a1092SKalle Valo 			bytes = bytes_per_frag;
466367a1092SKalle Valo 		} else {
467367a1092SKalle Valo 			/* The last fragment takes the remaining length */
468367a1092SKalle Valo 			bytes = bytes_last_frag;
469367a1092SKalle Valo 		}
470367a1092SKalle Valo 
471367a1092SKalle Valo 		if (i == 0 && !snapped) {
472367a1092SKalle Valo 			libipw_copy_snap(skb_put
473367a1092SKalle Valo 					    (skb_frag, SNAP_SIZE + sizeof(u16)),
474367a1092SKalle Valo 					    ether_type);
475367a1092SKalle Valo 			bytes -= SNAP_SIZE + sizeof(u16);
476367a1092SKalle Valo 		}
477367a1092SKalle Valo 
478367a1092SKalle Valo 		skb_copy_from_linear_data(skb, skb_put(skb_frag, bytes), bytes);
479367a1092SKalle Valo 
480367a1092SKalle Valo 		/* Advance the SKB... */
481367a1092SKalle Valo 		skb_pull(skb, bytes);
482367a1092SKalle Valo 
483367a1092SKalle Valo 		/* Encryption routine will move the header forward in order
484367a1092SKalle Valo 		 * to insert the IV between the header and the payload */
485367a1092SKalle Valo 		if (host_encrypt)
486367a1092SKalle Valo 			libipw_encrypt_fragment(ieee, skb_frag, hdr_len);
487367a1092SKalle Valo 
488367a1092SKalle Valo 		if (ieee->config &
489367a1092SKalle Valo 		    (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS))
490367a1092SKalle Valo 			skb_put(skb_frag, 4);
491367a1092SKalle Valo 	}
492367a1092SKalle Valo 
493367a1092SKalle Valo       success:
494367a1092SKalle Valo 	spin_unlock_irqrestore(&ieee->lock, flags);
495367a1092SKalle Valo 
496367a1092SKalle Valo 	dev_kfree_skb_any(skb);
497367a1092SKalle Valo 
498367a1092SKalle Valo 	if (txb) {
499367a1092SKalle Valo 		netdev_tx_t ret = (*ieee->hard_start_xmit)(txb, dev, priority);
500367a1092SKalle Valo 		if (ret == NETDEV_TX_OK) {
501367a1092SKalle Valo 			dev->stats.tx_packets++;
502367a1092SKalle Valo 			dev->stats.tx_bytes += txb->payload_size;
503367a1092SKalle Valo 			return NETDEV_TX_OK;
504367a1092SKalle Valo 		}
505367a1092SKalle Valo 
506367a1092SKalle Valo 		libipw_txb_free(txb);
507367a1092SKalle Valo 	}
508367a1092SKalle Valo 
509367a1092SKalle Valo 	return NETDEV_TX_OK;
510367a1092SKalle Valo 
511367a1092SKalle Valo       failed:
512367a1092SKalle Valo 	spin_unlock_irqrestore(&ieee->lock, flags);
513367a1092SKalle Valo 	netif_stop_queue(dev);
514367a1092SKalle Valo 	dev->stats.tx_errors++;
515367a1092SKalle Valo 	return NETDEV_TX_BUSY;
516367a1092SKalle Valo }
517367a1092SKalle Valo EXPORT_SYMBOL(libipw_xmit);
518367a1092SKalle Valo 
519367a1092SKalle Valo EXPORT_SYMBOL(libipw_txb_free);
520