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