diff options
Diffstat (limited to 'drivers/staging/rtl8192e/rtllib_tx.c')
-rw-r--r-- | drivers/staging/rtl8192e/rtllib_tx.c | 357 |
1 files changed, 188 insertions, 169 deletions
diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index 4f68ffe41475..3b159638bba2 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -53,102 +53,99 @@ #include "rtllib.h" -/* - - -802.11 Data Frame - - -802.11 frame_control for data frames - 2 bytes - ,-----------------------------------------------------------------------------------------. -bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | - |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| -val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x | - |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| -desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep | - | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | | - '-----------------------------------------------------------------------------------------' - /\ - | -802.11 Data Frame | - ,--------- 'ctrl' expands to >-----------' - | - ,--'---,-------------------------------------------------------------. -Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | - |------|------|---------|---------|---------|------|---------|------| -Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs | - | | tion | (BSSID) | | | ence | data | | - `--------------------------------------------------| |------' -Total: 28 non-data bytes `----.----' - | - .- 'Frame data' expands to <---------------------------' - | - V - ,---------------------------------------------------. -Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 | - |------|------|---------|----------|------|---------| -Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP | - | DSAP | SSAP | | | | Packet | - | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | | - `-----------------------------------------| | -Total: 8 non-data bytes `----.----' - | - .- 'IP Packet' expands, if WEP enabled, to <--' - | - V - ,-----------------------. -Bytes | 4 | 0-2296 | 4 | - |-----|-----------|-----| -Desc. | IV | Encrypted | ICV | - | | IP Packet | | - `-----------------------' -Total: 8 non-data bytes - - -802.3 Ethernet Data Frame - - ,-----------------------------------------. -Bytes | 6 | 6 | 2 | Variable | 4 | - |-------|-------|------|-----------|------| -Desc. | Dest. | Source| Type | IP Packet | fcs | - | MAC | MAC | | | | - `-----------------------------------------' -Total: 18 non-data bytes - -In the event that fragmentation is required, the incoming payload is split into -N parts of size ieee->fts. The first fragment contains the SNAP header and the -remaining packets are just data. - -If encryption is enabled, each fragment payload size is reduced by enough space -to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP) -So if you have 1500 bytes of payload with ieee->fts set to 500 without -encryption it will take 3 frames. With WEP it will take 4 frames as the -payload of each frame is reduced to 492 bytes. - -* SKB visualization -* -* ,- skb->data -* | -* | ETHERNET HEADER ,-<-- PAYLOAD -* | | 14 bytes from skb->data -* | 2 bytes for Type --> ,T. | (sizeof ethhdr) -* | | | | -* |,-Dest.--. ,--Src.---. | | | -* | 6 bytes| | 6 bytes | | | | -* v | | | | | | -* 0 | v 1 | v | v 2 -* 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 -* ^ | ^ | ^ | -* | | | | | | -* | | | | `T' <---- 2 bytes for Type -* | | | | -* | | '---SNAP--' <-------- 6 bytes for SNAP -* | | -* `-IV--' <-------------------- 4 bytes for IV (WEP) -* -* SNAP HEADER -* -*/ +/* 802.11 Data Frame + * + * + * 802.11 frame_control for data frames - 2 bytes + * ,-----------------------------------------------------------------------------------------. + * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | + * |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| + * val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x | + * |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| + * desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep | + * | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | | + * '-----------------------------------------------------------------------------------------' + * /\ + * | + * 802.11 Data Frame | + * ,--------- 'ctrl' expands to >-----------' + * | + * ,--'---,-------------------------------------------------------------. + * Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | + * |------|------|---------|---------|---------|------|---------|------| + * Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs | + * | | tion | (BSSID) | | | ence | data | | + * `--------------------------------------------------| |------' + * Total: 28 non-data bytes `----.----' + * | + * .- 'Frame data' expands to <---------------------------' + * | + * V + * ,---------------------------------------------------. + * Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 | + * |------|------|---------|----------|------|---------| + * Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP | + * | DSAP | SSAP | | | | Packet | + * | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | | + * `-----------------------------------------| | + * Total: 8 non-data bytes `----.----' + * | + * .- 'IP Packet' expands, if WEP enabled, to <--' + * | + * V + * ,-----------------------. + * Bytes | 4 | 0-2296 | 4 | + * |-----|-----------|-----| + * Desc. | IV | Encrypted | ICV | + * | | IP Packet | | + * `-----------------------' + * Total: 8 non-data bytes + * + * + * 802.3 Ethernet Data Frame + * + * ,-----------------------------------------. + * Bytes | 6 | 6 | 2 | Variable | 4 | + * |-------|-------|------|-----------|------| + * Desc. | Dest. | Source| Type | IP Packet | fcs | + * | MAC | MAC | | | | + * `-----------------------------------------' + * Total: 18 non-data bytes + * + * In the event that fragmentation is required, the incoming payload is split into + * N parts of size ieee->fts. The first fragment contains the SNAP header and the + * remaining packets are just data. + * + * If encryption is enabled, each fragment payload size is reduced by enough space + * to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP) + * So if you have 1500 bytes of payload with ieee->fts set to 500 without + * encryption it will take 3 frames. With WEP it will take 4 frames as the + * payload of each frame is reduced to 492 bytes. + * + * SKB visualization + * + * ,- skb->data + * | + * | ETHERNET HEADER ,-<-- PAYLOAD + * | | 14 bytes from skb->data + * | 2 bytes for Type --> ,T. | (sizeof ethhdr) + * | | | | + * |,-Dest.--. ,--Src.---. | | | + * | 6 bytes| | 6 bytes | | | | + * v | | | | | | + * 0 | v 1 | v | v 2 + * 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 + * ^ | ^ | ^ | + * | | | | | | + * | | | | `T' <---- 2 bytes for Type + * | | | | + * | | '---SNAP--' <-------- 6 bytes for SNAP + * | | + * `-IV--' <-------------------- 4 bytes for IV (WEP) + * + * SNAP HEADER + * + */ static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; @@ -185,14 +182,17 @@ int rtllib_encrypt_fragment(struct rtllib_device *ieee, struct sk_buff *frag, crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; if (!(crypt && crypt->ops)) { - printk(KERN_INFO "=========>%s(), crypt is null\n", __func__); + netdev_info(ieee->dev, "=========>%s(), crypt is null\n", + __func__); return -1; } /* To encrypt, frame format is: - * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */ + * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) + */ /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so - * call both MSDU and MPDU encryption functions from here. */ + * call both MSDU and MPDU encryption functions from here. + */ atomic_inc(&crypt->refcnt); res = 0; if (crypt->ops->encrypt_msdu) @@ -202,8 +202,8 @@ int rtllib_encrypt_fragment(struct rtllib_device *ieee, struct sk_buff *frag, atomic_dec(&crypt->refcnt); if (res < 0) { - printk(KERN_INFO "%s: Encryption failed: len=%d.\n", - ieee->dev->name, frag->len); + netdev_info(ieee->dev, "%s: Encryption failed: len=%d.\n", + ieee->dev->name, frag->len); ieee->ieee_stats.tx_discards++; return -1; } @@ -311,7 +311,7 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, if (pHTInfo->bCurrentAMPDUEnable) { if (!GetTs(ieee, (struct ts_common_info **)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true)) { - printk(KERN_INFO "%s: can't get TS\n", __func__); + netdev_info(ieee->dev, "%s: can't get TS\n", __func__); return; } if (pTxTs->TxAdmittedBARecord.bValid == false) { @@ -412,6 +412,8 @@ static void rtllib_query_protectionmode(struct rtllib_device *ieee, struct cb_desc *tcb_desc, struct sk_buff *skb) { + struct rt_hi_throughput *pHTInfo; + tcb_desc->bRTSSTBC = false; tcb_desc->bRTSUseShortGI = false; tcb_desc->bCTSEnable = false; @@ -434,50 +436,50 @@ static void rtllib_query_protectionmode(struct rtllib_device *ieee, tcb_desc->rts_rate = MGN_24M; } return; - } else { - struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + } - while (true) { - if (pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) { - tcb_desc->bCTSEnable = true; - tcb_desc->rts_rate = MGN_24M; - tcb_desc->bRTSEnable = true; - break; - } else if (pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS | - HT_IOT_ACT_PURE_N_MODE)) { - tcb_desc->bRTSEnable = true; - tcb_desc->rts_rate = MGN_24M; - break; - } - if (ieee->current_network.buseprotection) { - tcb_desc->bRTSEnable = true; - tcb_desc->bCTSEnable = true; - tcb_desc->rts_rate = MGN_24M; - break; - } - if (pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT) { - u8 HTOpMode = pHTInfo->CurrentOpMode; - - if ((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || - HTOpMode == 3)) || - (!pHTInfo->bCurBW40MHz && HTOpMode == 3)) { - tcb_desc->rts_rate = MGN_24M; - tcb_desc->bRTSEnable = true; - break; - } - } - if (skb->len > ieee->rts) { + pHTInfo = ieee->pHTInfo; + + while (true) { + if (pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) { + tcb_desc->bCTSEnable = true; + tcb_desc->rts_rate = MGN_24M; + tcb_desc->bRTSEnable = true; + break; + } else if (pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS | + HT_IOT_ACT_PURE_N_MODE)) { + tcb_desc->bRTSEnable = true; + tcb_desc->rts_rate = MGN_24M; + break; + } + if (ieee->current_network.buseprotection) { + tcb_desc->bRTSEnable = true; + tcb_desc->bCTSEnable = true; + tcb_desc->rts_rate = MGN_24M; + break; + } + if (pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT) { + u8 HTOpMode = pHTInfo->CurrentOpMode; + + if ((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || + HTOpMode == 3)) || + (!pHTInfo->bCurBW40MHz && HTOpMode == 3)) { tcb_desc->rts_rate = MGN_24M; tcb_desc->bRTSEnable = true; break; } - if (tcb_desc->bAMPDUEnable) { - tcb_desc->rts_rate = MGN_24M; - tcb_desc->bRTSEnable = false; - break; - } - goto NO_PROTECTION; } + if (skb->len > ieee->rts) { + tcb_desc->rts_rate = MGN_24M; + tcb_desc->bRTSEnable = true; + break; + } + if (tcb_desc->bAMPDUEnable) { + tcb_desc->rts_rate = MGN_24M; + tcb_desc->bRTSEnable = false; + break; + } + goto NO_PROTECTION; } if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) tcb_desc->bUseShortPreamble = true; @@ -549,6 +551,17 @@ static int wme_downgrade_ac(struct sk_buff *skb) } } +static u8 rtllib_current_rate(struct rtllib_device *ieee) +{ + if (ieee->mode & IEEE_MODE_MASK) + return ieee->rate; + + if (ieee->HTCurrentOperaRate) + return ieee->HTCurrentOperaRate; + else + return ieee->rate & 0x7F; +} + int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) { struct rtllib_device *ieee = (struct rtllib_device *) @@ -577,21 +590,21 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) spin_lock_irqsave(&ieee->lock, flags); /* If there is no driver handler to take the TXB, don't bother - * creating it... */ + * creating it... + */ if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)) || ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { - printk(KERN_WARNING "%s: No xmit handler.\n", - ieee->dev->name); + netdev_warn(ieee->dev, "No xmit handler.\n"); goto success; } if (likely(ieee->raw_tx == 0)) { if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { - printk(KERN_WARNING "%s: skb too small (%d).\n", - ieee->dev->name, skb->len); + netdev_warn(ieee->dev, "skb too small (%d).\n", + skb->len); goto success; } /* Save source and destination addresses */ @@ -604,9 +617,8 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) if (ieee->iw_mode == IW_MODE_MONITOR) { txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC); if (unlikely(!txb)) { - printk(KERN_WARNING "%s: Could not allocate " - "TXB\n", - ieee->dev->name); + netdev_warn(ieee->dev, + "Could not allocate TXB\n"); goto failed; } @@ -636,8 +648,8 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) } } } else if (ETH_P_ARP == ether_type) { - printk(KERN_INFO "=================>DHCP " - "Protocol start tx ARP pkt!!\n"); + netdev_info(ieee->dev, + "=================>DHCP Protocol start tx ARP pkt!!\n"); bdhcp = true; ieee->LPSDelayCnt = ieee->current_network.tim.tim_count; @@ -680,7 +692,8 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) if (ieee->iw_mode == IW_MODE_INFRA) { fc |= RTLLIB_FCTL_TODS; /* To DS: Addr1 = BSSID, Addr2 = SA, - Addr3 = DA */ + * Addr3 = DA + */ memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN); memcpy(&header.addr2, &src, ETH_ALEN); @@ -691,7 +704,8 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) memcpy(&header.addr3, &dest, ETH_ALEN); } else if (ieee->iw_mode == IW_MODE_ADHOC) { /* not From/To DS: Addr1 = DA, Addr2 = SA, - Addr3 = BSSID */ + * Addr3 = BSSID + */ memcpy(&header.addr1, dest, ETH_ALEN); memcpy(&header.addr2, src, ETH_ALEN); memcpy(&header.addr3, ieee->current_network.bssid, @@ -703,7 +717,8 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) header.frame_ctl = cpu_to_le16(fc); /* Determine fragmentation size based on destination (multicast - * and broadcast are not fragmented) */ + * and broadcast are not fragmented) + */ if (bIsMulticast) { frag_size = MAX_FRAG_THRESHOLD; qos_ctl |= QOS_CTL_NOTCONTAIN_ACK; @@ -717,10 +732,11 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) /* in case we are a client verify acm is not set for this ac */ while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) { - printk(KERN_INFO "skb->priority = %x\n", skb->priority); + netdev_info(ieee->dev, "skb->priority = %x\n", + skb->priority); if (wme_downgrade_ac(skb)) break; - printk(KERN_INFO "converted skb->priority = %x\n", + netdev_info(ieee->dev, "converted skb->priority = %x\n", skb->priority); } qos_ctl |= skb->priority; @@ -731,14 +747,16 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) /* Determine amount of payload per fragment. Regardless of if * this stack is providing the full 802.11 header, one will * eventually be affixed to this fragment -- so we must account - * for it when determining the amount of payload space. */ + * for it when determining the amount of payload space. + */ bytes_per_frag = frag_size - hdr_len; if (ieee->config & (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) bytes_per_frag -= RTLLIB_FCS_LEN; /* Each fragment may need to have room for encrypting - * pre/postfix */ + * pre/postfix + */ if (encrypt) { bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len + crypt->ops->extra_mpdu_postfix_len + @@ -746,7 +764,8 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) crypt->ops->extra_msdu_postfix_len; } /* Number of fragments is the total bytes_per_frag / - * payload_per_fragment */ + * payload_per_fragment + */ nr_frags = bytes / bytes_per_frag; bytes_last_frag = bytes % bytes_per_frag; if (bytes_last_frag) @@ -756,12 +775,12 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) /* When we allocate the TXB we allocate enough space for the * reserve and full fragment bytes (bytes_per_frag doesn't - * include prefix, postfix, header, FCS, etc.) */ + * include prefix, postfix, header, FCS, etc.) + */ txb = rtllib_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC); if (unlikely(!txb)) { - printk(KERN_WARNING "%s: Could not allocate TXB\n", - ieee->dev->name); + netdev_warn(ieee->dev, "Could not allocate TXB\n"); goto failed; } txb->encrypted = encrypt; @@ -801,7 +820,8 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) memcpy(frag_hdr, &header, hdr_len); /* If this is not the last fragment, then add the - * MOREFRAGS bit to the frame control */ + * MOREFRAGS bit to the frame control + */ if (i != nr_frags - 1) { frag_hdr->frame_ctl = cpu_to_le16( fc | RTLLIB_FCTL_MOREFRAGS); @@ -836,7 +856,8 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) /* Encryption routine will move the header forward in * order to insert the IV between the header and the - * payload */ + * payload + */ if (encrypt) rtllib_encrypt_fragment(ieee, skb_frag, hdr_len); @@ -858,15 +879,14 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) } } else { if (unlikely(skb->len < sizeof(struct rtllib_hdr_3addr))) { - printk(KERN_WARNING "%s: skb too small (%d).\n", - ieee->dev->name, skb->len); + netdev_warn(ieee->dev, "skb too small (%d).\n", + skb->len); goto success; } txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC); if (!txb) { - printk(KERN_WARNING "%s: Could not allocate TXB\n", - ieee->dev->name); + netdev_warn(ieee->dev, "Could not allocate TXB\n"); goto failed; } @@ -906,8 +926,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) if (tcb_desc->bMulticast || tcb_desc->bBroadcast) tcb_desc->data_rate = ieee->basic_rate; else - tcb_desc->data_rate = CURRENT_RATE(ieee->mode, - ieee->rate, ieee->HTCurrentOperaRate); + tcb_desc->data_rate = rtllib_current_rate(ieee); if (bdhcp) { if (ieee->pHTInfo->IOTAction & |