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 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 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 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 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 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) */ 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 */ 386*e8366bbaSHaowen 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