blob: f038aa930830defd38a4503d7b7f0b576ba6f00f [file] [log] [blame]
Larry Finger94a79942011-08-23 19:00:42 -05001/******************************************************************************
2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Contact Information:
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25******************************************************************************
26
27 Few modifications for Realtek's Wi-Fi drivers by
28 Andrea Merello <andreamrl@tiscali.it>
29
30 A special thanks goes to Realtek for their support !
31
32******************************************************************************/
33
34#include <linux/compiler.h>
35#include <linux/errno.h>
36#include <linux/if_arp.h>
37#include <linux/in6.h>
38#include <linux/in.h>
39#include <linux/ip.h>
40#include <linux/kernel.h>
41#include <linux/module.h>
42#include <linux/netdevice.h>
43#include <linux/pci.h>
44#include <linux/proc_fs.h>
45#include <linux/skbuff.h>
46#include <linux/slab.h>
47#include <linux/tcp.h>
48#include <linux/types.h>
49#include <linux/version.h>
50#include <linux/wireless.h>
51#include <linux/etherdevice.h>
Larry Fingerf38d2232011-08-25 11:48:28 -050052#include <linux/uaccess.h>
Larry Finger94a79942011-08-23 19:00:42 -050053#include <linux/if_vlan.h>
54
55#include "rtllib.h"
56
Larry Finger94a79942011-08-23 19:00:42 -050057/*
58
59
60802.11 Data Frame
61
62
63802.11 frame_contorl for data frames - 2 bytes
64 ,-----------------------------------------------------------------------------------------.
65bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
66 |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
67val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
68 |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
69desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
Larry Fingerf38d2232011-08-25 11:48:28 -050070 | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
Larry Finger94a79942011-08-23 19:00:42 -050071 '-----------------------------------------------------------------------------------------'
Larry Fingerf38d2232011-08-25 11:48:28 -050072 /\
73 |
74802.11 Data Frame |
75 ,--------- 'ctrl' expands to >-----------'
76 |
Larry Finger94a79942011-08-23 19:00:42 -050077 ,--'---,-------------------------------------------------------------.
78Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
79 |------|------|---------|---------|---------|------|---------|------|
80Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
Larry Fingerf38d2232011-08-25 11:48:28 -050081 | | tion | (BSSID) | | | ence | data | |
82 `--------------------------------------------------| |------'
83Total: 28 non-data bytes `----.----'
84 |
Larry Finger94a79942011-08-23 19:00:42 -050085 .- 'Frame data' expands to <---------------------------'
86 |
87 V
88 ,---------------------------------------------------.
89Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
90 |------|------|---------|----------|------|---------|
91Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
Larry Fingerf38d2232011-08-25 11:48:28 -050092 | DSAP | SSAP | | | | Packet |
93 | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
94 `-----------------------------------------| |
95Total: 8 non-data bytes `----.----'
96 |
Larry Finger94a79942011-08-23 19:00:42 -050097 .- 'IP Packet' expands, if WEP enabled, to <--'
98 |
99 V
100 ,-----------------------.
101Bytes | 4 | 0-2296 | 4 |
102 |-----|-----------|-----|
103Desc. | IV | Encrypted | ICV |
104 | | IP Packet | |
105 `-----------------------'
106Total: 8 non-data bytes
107
108
109802.3 Ethernet Data Frame
110
111 ,-----------------------------------------.
112Bytes | 6 | 6 | 2 | Variable | 4 |
113 |-------|-------|------|-----------|------|
114Desc. | Dest. | Source| Type | IP Packet | fcs |
Larry Fingerf38d2232011-08-25 11:48:28 -0500115 | MAC | MAC | | | |
Larry Finger94a79942011-08-23 19:00:42 -0500116 `-----------------------------------------'
117Total: 18 non-data bytes
118
119In the event that fragmentation is required, the incoming payload is split into
120N parts of size ieee->fts. The first fragment contains the SNAP header and the
121remaining packets are just data.
122
123If encryption is enabled, each fragment payload size is reduced by enough space
124to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
125So if you have 1500 bytes of payload with ieee->fts set to 500 without
126encryption it will take 3 frames. With WEP it will take 4 frames as the
127payload of each frame is reduced to 492 bytes.
128
129* SKB visualization
130*
131* ,- skb->data
132* |
Larry Fingerf38d2232011-08-25 11:48:28 -0500133* | ETHERNET HEADER ,-<-- PAYLOAD
134* | | 14 bytes from skb->data
Larry Finger94a79942011-08-23 19:00:42 -0500135* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
Larry Fingerf38d2232011-08-25 11:48:28 -0500136* | | | |
Larry Finger94a79942011-08-23 19:00:42 -0500137* |,-Dest.--. ,--Src.---. | | |
138* | 6 bytes| | 6 bytes | | | |
Larry Fingerf38d2232011-08-25 11:48:28 -0500139* v | | | | | |
140* 0 | v 1 | v | v 2
Larry Finger94a79942011-08-23 19:00:42 -0500141* 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
Larry Fingerf38d2232011-08-25 11:48:28 -0500142* ^ | ^ | ^ |
143* | | | | | |
144* | | | | `T' <---- 2 bytes for Type
145* | | | |
Larry Finger94a79942011-08-23 19:00:42 -0500146* | | '---SNAP--' <-------- 6 bytes for SNAP
147* | |
148* `-IV--' <-------------------- 4 bytes for IV (WEP)
149*
150* SNAP HEADER
151*
152*/
153
154static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
155static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
156
157inline int rtllib_put_snap(u8 *data, u16 h_proto)
158{
159 struct rtllib_snap_hdr *snap;
160 u8 *oui;
161
162 snap = (struct rtllib_snap_hdr *)data;
163 snap->dsap = 0xaa;
164 snap->ssap = 0xaa;
165 snap->ctrl = 0x03;
166
167 if (h_proto == 0x8137 || h_proto == 0x80f3)
168 oui = P802_1H_OUI;
169 else
170 oui = RFC1042_OUI;
171 snap->oui[0] = oui[0];
172 snap->oui[1] = oui[1];
173 snap->oui[2] = oui[2];
174
175 *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
176
177 return SNAP_SIZE + sizeof(u16);
178}
179
Larry Fingerf38d2232011-08-25 11:48:28 -0500180int rtllib_encrypt_fragment(struct rtllib_device *ieee, struct sk_buff *frag,
181 int hdr_len)
Larry Finger94a79942011-08-23 19:00:42 -0500182{
Larry Fingerf38d2232011-08-25 11:48:28 -0500183 struct rtllib_crypt_data *crypt = NULL;
Larry Finger94a79942011-08-23 19:00:42 -0500184 int res;
185
186 crypt = ieee->crypt[ieee->tx_keyidx];
187
Larry Fingerf38d2232011-08-25 11:48:28 -0500188 if (!(crypt && crypt->ops)) {
189 printk(KERN_INFO "=========>%s(), crypt is null\n", __func__);
Larry Finger94a79942011-08-23 19:00:42 -0500190 return -1;
191 }
Larry Finger94a79942011-08-23 19:00:42 -0500192 /* To encrypt, frame format is:
193 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
194
195 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
196 * call both MSDU and MPDU encryption functions from here. */
197 atomic_inc(&crypt->refcnt);
198 res = 0;
199 if (crypt->ops->encrypt_msdu)
200 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
201 if (res == 0 && crypt->ops->encrypt_mpdu)
202 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
203
204 atomic_dec(&crypt->refcnt);
205 if (res < 0) {
206 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
207 ieee->dev->name, frag->len);
208 ieee->ieee_stats.tx_discards++;
209 return -1;
210 }
211
212 return 0;
213}
214
215
Larry Fingerf38d2232011-08-25 11:48:28 -0500216void rtllib_txb_free(struct rtllib_txb *txb)
217{
Larry Finger94a79942011-08-23 19:00:42 -0500218 if (unlikely(!txb))
219 return;
220 kfree(txb);
221}
222
223struct rtllib_txb *rtllib_alloc_txb(int nr_frags, int txb_size,
Larry Fingerf38d2232011-08-25 11:48:28 -0500224 int gfp_mask)
Larry Finger94a79942011-08-23 19:00:42 -0500225{
Larry Finger94a79942011-08-23 19:00:42 -0500226 struct rtllib_txb *txb;
227 int i;
Larry Fingerf38d2232011-08-25 11:48:28 -0500228 txb = kmalloc(sizeof(struct rtllib_txb) + (sizeof(u8 *) * nr_frags),
229 gfp_mask);
Larry Finger94a79942011-08-23 19:00:42 -0500230 if (!txb)
231 return NULL;
232
233 memset(txb, 0, sizeof(struct rtllib_txb));
234 txb->nr_frags = nr_frags;
235 txb->frag_size = txb_size;
236
237 for (i = 0; i < nr_frags; i++) {
Larry Finger94a79942011-08-23 19:00:42 -0500238 txb->fragments[i] = dev_alloc_skb(txb_size);
Larry Finger94a79942011-08-23 19:00:42 -0500239 if (unlikely(!txb->fragments[i])) {
240 i--;
241 break;
242 }
Larry Finger94a79942011-08-23 19:00:42 -0500243 memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
244 }
245 if (unlikely(i != nr_frags)) {
246 while (i >= 0)
247 dev_kfree_skb_any(txb->fragments[i--]);
248 kfree(txb);
249 return NULL;
250 }
251 return txb;
252}
253
254int
255rtllib_classify(struct sk_buff *skb, u8 bIsAmsdu)
256{
257 struct ethhdr *eth;
258 struct iphdr *ip;
259
260 eth = (struct ethhdr *)skb->data;
261 if (eth->h_proto != htons(ETH_P_IP))
262 return 0;
263
264 RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA, skb->data, skb->len);
265 ip = ip_hdr(skb);
266 switch (ip->tos & 0xfc) {
267 case 0x20:
268 return 2;
269 case 0x40:
270 return 1;
271 case 0x60:
272 return 3;
273 case 0x80:
274 return 4;
275 case 0xa0:
276 return 5;
277 case 0xc0:
278 return 6;
279 case 0xe0:
280 return 7;
281 default:
282 return 0;
283 }
284}
285
Larry Fingerf38d2232011-08-25 11:48:28 -0500286void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, struct sk_buff *skb,
287 struct cb_desc *tcb_desc)
Larry Finger94a79942011-08-23 19:00:42 -0500288{
Larry Finger7796d932011-07-18 20:22:19 -0500289 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
Larry Finger60554f22011-07-18 20:10:03 -0500290 struct tx_ts_record *pTxTs = NULL;
Larry Fingerf38d2232011-08-25 11:48:28 -0500291 struct rtllib_hdr_1addr* hdr = (struct rtllib_hdr_1addr *)skb->data;
Larry Finger94a79942011-08-23 19:00:42 -0500292
Larry Fingerf38d2232011-08-25 11:48:28 -0500293 if (rtllib_act_scanning(ieee, false))
Larry Finger94a79942011-08-23 19:00:42 -0500294 return;
295
Larry Fingerf38d2232011-08-25 11:48:28 -0500296 if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT)
Larry Finger94a79942011-08-23 19:00:42 -0500297 return;
298 if (!IsQoSDataFrame(skb->data))
299 return;
Larry Fingerf38d2232011-08-25 11:48:28 -0500300 if (is_multicast_ether_addr(hdr->addr1) ||
301 is_broadcast_ether_addr(hdr->addr1))
Larry Finger94a79942011-08-23 19:00:42 -0500302 return;
Larry Finger94a79942011-08-23 19:00:42 -0500303
Larry Fingerf38d2232011-08-25 11:48:28 -0500304 if (tcb_desc->bdhcp || ieee->CntAfterLink < 2)
Larry Finger94a79942011-08-23 19:00:42 -0500305 return;
306
307 if (pHTInfo->IOTAction & HT_IOT_ACT_TX_NO_AGGREGATION)
308 return;
309
310 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
311 return;
Larry Fingerf38d2232011-08-25 11:48:28 -0500312 if (pHTInfo->bCurrentAMPDUEnable) {
313 if (!GetTs(ieee, (struct ts_common_info **)(&pTxTs), hdr->addr1,
314 skb->priority, TX_DIR, true)) {
315 printk(KERN_INFO "%s: can't get TS\n", __func__);
Larry Finger94a79942011-08-23 19:00:42 -0500316 return;
317 }
Larry Fingerf38d2232011-08-25 11:48:28 -0500318 if (pTxTs->TxAdmittedBARecord.bValid == false) {
319 if (ieee->wpa_ie_len && (ieee->pairwise_key_type ==
320 KEY_TYPE_NA)) {
Larry Finger94a79942011-08-23 19:00:42 -0500321 ;
Larry Fingerf38d2232011-08-25 11:48:28 -0500322 } else if (tcb_desc->bdhcp == 1) {
Larry Finger94a79942011-08-23 19:00:42 -0500323 ;
Larry Fingerf38d2232011-08-25 11:48:28 -0500324 } else if (!pTxTs->bDisable_AddBa) {
Larry Finger94a79942011-08-23 19:00:42 -0500325 TsStartAddBaProcess(ieee, pTxTs);
326 }
327 goto FORCED_AGG_SETTING;
328 } else if (pTxTs->bUsingBa == false) {
Larry Fingerf38d2232011-08-25 11:48:28 -0500329 if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum,
330 (pTxTs->TxCurSeq+1)%4096))
Larry Finger94a79942011-08-23 19:00:42 -0500331 pTxTs->bUsingBa = true;
332 else
333 goto FORCED_AGG_SETTING;
334 }
335 if (ieee->iw_mode == IW_MODE_INFRA) {
336 tcb_desc->bAMPDUEnable = true;
337 tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
338 tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
339 }
340 }
341FORCED_AGG_SETTING:
342 switch (pHTInfo->ForcedAMPDUMode) {
Larry Fingerf38d2232011-08-25 11:48:28 -0500343 case HT_AGG_AUTO:
344 break;
Larry Finger94a79942011-08-23 19:00:42 -0500345
Larry Fingerf38d2232011-08-25 11:48:28 -0500346 case HT_AGG_FORCE_ENABLE:
347 tcb_desc->bAMPDUEnable = true;
348 tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
349 tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
350 break;
Larry Finger94a79942011-08-23 19:00:42 -0500351
Larry Fingerf38d2232011-08-25 11:48:28 -0500352 case HT_AGG_FORCE_DISABLE:
353 tcb_desc->bAMPDUEnable = false;
354 tcb_desc->ampdu_density = 0;
355 tcb_desc->ampdu_factor = 0;
356 break;
Larry Finger94a79942011-08-23 19:00:42 -0500357 }
358 return;
359}
360
Larry Fingerf38d2232011-08-25 11:48:28 -0500361extern void rtllib_qurey_ShortPreambleMode(struct rtllib_device *ieee,
362 struct cb_desc *tcb_desc)
363{
364 tcb_desc->bUseShortPreamble = false;
365 if (tcb_desc->data_rate == 2)
366 return;
367 else if (ieee->current_network.capability &
368 WLAN_CAPABILITY_SHORT_PREAMBLE)
369 tcb_desc->bUseShortPreamble = true;
370 return;
371}
372
373extern void rtllib_query_HTCapShortGI(struct rtllib_device *ieee,
374 struct cb_desc *tcb_desc)
Larry Finger94a79942011-08-23 19:00:42 -0500375{
Larry Finger7796d932011-07-18 20:22:19 -0500376 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
Larry Finger94a79942011-08-23 19:00:42 -0500377
378 tcb_desc->bUseShortGI = false;
379
Larry Fingerf38d2232011-08-25 11:48:28 -0500380 if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT)
Larry Finger94a79942011-08-23 19:00:42 -0500381 return;
382
Larry Fingerf38d2232011-08-25 11:48:28 -0500383 if (pHTInfo->bForcedShortGI) {
Larry Finger94a79942011-08-23 19:00:42 -0500384 tcb_desc->bUseShortGI = true;
385 return;
386 }
387
Larry Fingerf38d2232011-08-25 11:48:28 -0500388 if ((pHTInfo->bCurBW40MHz == true) && pHTInfo->bCurShortGI40MHz)
Larry Finger94a79942011-08-23 19:00:42 -0500389 tcb_desc->bUseShortGI = true;
Larry Fingerf38d2232011-08-25 11:48:28 -0500390 else if ((pHTInfo->bCurBW40MHz == false) && pHTInfo->bCurShortGI20MHz)
Larry Finger94a79942011-08-23 19:00:42 -0500391 tcb_desc->bUseShortGI = true;
392}
393
Larry Fingerf38d2232011-08-25 11:48:28 -0500394void rtllib_query_BandwidthMode(struct rtllib_device *ieee,
395 struct cb_desc *tcb_desc)
Larry Finger94a79942011-08-23 19:00:42 -0500396{
Larry Finger7796d932011-07-18 20:22:19 -0500397 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
Larry Finger94a79942011-08-23 19:00:42 -0500398
399 tcb_desc->bPacketBW = false;
400
Larry Fingerf38d2232011-08-25 11:48:28 -0500401 if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT)
Larry Finger94a79942011-08-23 19:00:42 -0500402 return;
403
404 if (tcb_desc->bMulticast || tcb_desc->bBroadcast)
405 return;
406
Larry Fingerf38d2232011-08-25 11:48:28 -0500407 if ((tcb_desc->data_rate & 0x80) == 0)
Larry Finger94a79942011-08-23 19:00:42 -0500408 return;
Larry Fingerf38d2232011-08-25 11:48:28 -0500409 if (pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz &&
410 !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
Larry Finger94a79942011-08-23 19:00:42 -0500411 tcb_desc->bPacketBW = true;
412 return;
413}
Larry Finger94a79942011-08-23 19:00:42 -0500414
Larry Fingerf38d2232011-08-25 11:48:28 -0500415void rtllib_query_protectionmode(struct rtllib_device *ieee,
416 struct cb_desc *tcb_desc, struct sk_buff *skb)
Larry Finger94a79942011-08-23 19:00:42 -0500417{
418 tcb_desc->bRTSSTBC = false;
419 tcb_desc->bRTSUseShortGI = false;
420 tcb_desc->bCTSEnable = false;
421 tcb_desc->RTSSC = 0;
422 tcb_desc->bRTSBW = false;
423
424 if (tcb_desc->bBroadcast || tcb_desc->bMulticast)
425 return;
426
427 if (is_broadcast_ether_addr(skb->data+16))
428 return;
429
Larry Fingerf38d2232011-08-25 11:48:28 -0500430 if (ieee->mode < IEEE_N_24G) {
431 if (skb->len > ieee->rts) {
Larry Finger94a79942011-08-23 19:00:42 -0500432 tcb_desc->bRTSEnable = true;
433 tcb_desc->rts_rate = MGN_24M;
Larry Fingerf38d2232011-08-25 11:48:28 -0500434 } else if (ieee->current_network.buseprotection) {
Larry Finger94a79942011-08-23 19:00:42 -0500435 tcb_desc->bRTSEnable = true;
436 tcb_desc->bCTSEnable = true;
437 tcb_desc->rts_rate = MGN_24M;
438 }
439 return;
Larry Fingerf38d2232011-08-25 11:48:28 -0500440 } else {
Larry Finger7796d932011-07-18 20:22:19 -0500441 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
Larry Fingerf38d2232011-08-25 11:48:28 -0500442 while (true) {
443 if (pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) {
Larry Finger94a79942011-08-23 19:00:42 -0500444 tcb_desc->bCTSEnable = true;
445 tcb_desc->rts_rate = MGN_24M;
446 tcb_desc->bRTSEnable = true;
447 break;
Larry Fingerf38d2232011-08-25 11:48:28 -0500448 } else if (pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS |
449 HT_IOT_ACT_PURE_N_MODE)) {
Larry Finger94a79942011-08-23 19:00:42 -0500450 tcb_desc->bRTSEnable = true;
451 tcb_desc->rts_rate = MGN_24M;
452 break;
453 }
Larry Fingerf38d2232011-08-25 11:48:28 -0500454 if (ieee->current_network.buseprotection) {
Larry Finger94a79942011-08-23 19:00:42 -0500455 tcb_desc->bRTSEnable = true;
456 tcb_desc->bCTSEnable = true;
457 tcb_desc->rts_rate = MGN_24M;
458 break;
459 }
Larry Fingerf38d2232011-08-25 11:48:28 -0500460 if (pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT) {
Larry Finger94a79942011-08-23 19:00:42 -0500461 u8 HTOpMode = pHTInfo->CurrentOpMode;
Larry Fingerf38d2232011-08-25 11:48:28 -0500462 if ((pHTInfo->bCurBW40MHz && (HTOpMode == 2 ||
463 HTOpMode == 3)) ||
464 (!pHTInfo->bCurBW40MHz && HTOpMode == 3)) {
Larry Finger94a79942011-08-23 19:00:42 -0500465 tcb_desc->rts_rate = MGN_24M;
466 tcb_desc->bRTSEnable = true;
467 break;
468 }
469 }
Larry Fingerf38d2232011-08-25 11:48:28 -0500470 if (skb->len > ieee->rts) {
Larry Finger94a79942011-08-23 19:00:42 -0500471 tcb_desc->rts_rate = MGN_24M;
472 tcb_desc->bRTSEnable = true;
473 break;
474 }
Larry Fingerf38d2232011-08-25 11:48:28 -0500475 if (tcb_desc->bAMPDUEnable) {
Larry Finger94a79942011-08-23 19:00:42 -0500476 tcb_desc->rts_rate = MGN_24M;
477 tcb_desc->bRTSEnable = false;
478 break;
479 }
480 goto NO_PROTECTION;
481 }
Larry Finger94a79942011-08-23 19:00:42 -0500482 }
483 if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
484 tcb_desc->bUseShortPreamble = true;
485 if (ieee->iw_mode == IW_MODE_MASTER)
486 goto NO_PROTECTION;
487 return;
488NO_PROTECTION:
489 tcb_desc->bRTSEnable = false;
490 tcb_desc->bCTSEnable = false;
Larry Fingerf38d2232011-08-25 11:48:28 -0500491 tcb_desc->rts_rate = 0;
Larry Finger94a79942011-08-23 19:00:42 -0500492 tcb_desc->RTSSC = 0;
Larry Fingerf38d2232011-08-25 11:48:28 -0500493 tcb_desc->bRTSBW = false;
Larry Finger94a79942011-08-23 19:00:42 -0500494}
495
496
Larry Fingerf38d2232011-08-25 11:48:28 -0500497void rtllib_txrate_selectmode(struct rtllib_device *ieee,
498 struct cb_desc *tcb_desc)
Larry Finger94a79942011-08-23 19:00:42 -0500499{
Larry Finger94a79942011-08-23 19:00:42 -0500500 if (ieee->bTxDisableRateFallBack)
501 tcb_desc->bTxDisableRateFallBack = true;
502
503 if (ieee->bTxUseDriverAssingedRate)
504 tcb_desc->bTxUseDriverAssingedRate = true;
Larry Fingerf38d2232011-08-25 11:48:28 -0500505 if (!tcb_desc->bTxDisableRateFallBack ||
506 !tcb_desc->bTxUseDriverAssingedRate) {
507 if (ieee->iw_mode == IW_MODE_INFRA ||
508 ieee->iw_mode == IW_MODE_ADHOC)
Larry Finger94a79942011-08-23 19:00:42 -0500509 tcb_desc->RATRIndex = 0;
510 }
511}
512
Larry Fingerf38d2232011-08-25 11:48:28 -0500513u16 rtllib_query_seqnum(struct rtllib_device *ieee, struct sk_buff *skb,
514 u8 *dst)
Larry Finger94a79942011-08-23 19:00:42 -0500515{
516 u16 seqnum = 0;
517
518 if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
519 return 0;
Larry Fingerf38d2232011-08-25 11:48:28 -0500520 if (IsQoSDataFrame(skb->data)) {
Larry Finger60554f22011-07-18 20:10:03 -0500521 struct tx_ts_record *pTS = NULL;
Larry Fingerf38d2232011-08-25 11:48:28 -0500522 if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst,
523 skb->priority, TX_DIR, true))
Larry Finger94a79942011-08-23 19:00:42 -0500524 return 0;
Larry Finger94a79942011-08-23 19:00:42 -0500525 seqnum = pTS->TxCurSeq;
526 pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
527 return seqnum;
528 }
529 return 0;
530}
531
532static int wme_downgrade_ac(struct sk_buff *skb)
533{
534 switch (skb->priority) {
Larry Fingerf38d2232011-08-25 11:48:28 -0500535 case 6:
536 case 7:
537 skb->priority = 5; /* VO -> VI */
538 return 0;
539 case 4:
540 case 5:
541 skb->priority = 3; /* VI -> BE */
542 return 0;
543 case 0:
544 case 3:
545 skb->priority = 1; /* BE -> BK */
546 return 0;
547 default:
548 return -1;
Larry Finger94a79942011-08-23 19:00:42 -0500549 }
550}
551
552int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
553{
Larry Fingerf38d2232011-08-25 11:48:28 -0500554 struct rtllib_device *ieee = (struct rtllib_device *)
555 netdev_priv_rsl(dev);
Larry Finger94a79942011-08-23 19:00:42 -0500556 struct rtllib_txb *txb = NULL;
557 struct rtllib_hdr_3addrqos *frag_hdr;
558 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
559 unsigned long flags;
560 struct net_device_stats *stats = &ieee->stats;
561 int ether_type = 0, encrypt;
562 int bytes, fc, qos_ctl = 0, hdr_len;
563 struct sk_buff *skb_frag;
564 struct rtllib_hdr_3addrqos header = { /* Ensure zero initialized */
565 .duration_id = 0,
566 .seq_ctl = 0,
567 .qos_ctl = 0
568 };
569 u8 dest[ETH_ALEN], src[ETH_ALEN];
570 int qos_actived = ieee->current_network.qos_data.active;
Larry Fingerf38d2232011-08-25 11:48:28 -0500571 struct rtllib_crypt_data *crypt = NULL;
Larry Finger3b83db42011-07-19 00:01:29 -0500572 struct cb_desc *tcb_desc;
Larry Finger94a79942011-08-23 19:00:42 -0500573 u8 bIsMulticast = false;
574 u8 IsAmsdu = false;
Larry Fingerf38d2232011-08-25 11:48:28 -0500575 bool bdhcp = false;
Larry Finger94a79942011-08-23 19:00:42 -0500576
Larry Finger94a79942011-08-23 19:00:42 -0500577 spin_lock_irqsave(&ieee->lock, flags);
578
579 /* If there is no driver handler to take the TXB, dont' bother
580 * creating it... */
Larry Fingerf38d2232011-08-25 11:48:28 -0500581 if ((!ieee->hard_start_xmit && !(ieee->softmac_features &
582 IEEE_SOFTMAC_TX_QUEUE)) ||
583 ((!ieee->softmac_data_hard_start_xmit &&
584 (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
Larry Finger94a79942011-08-23 19:00:42 -0500585 printk(KERN_WARNING "%s: No xmit handler.\n",
586 ieee->dev->name);
587 goto success;
588 }
589
590
Larry Fingerf38d2232011-08-25 11:48:28 -0500591 if (likely(ieee->raw_tx == 0)) {
Larry Finger94a79942011-08-23 19:00:42 -0500592 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
593 printk(KERN_WARNING "%s: skb too small (%d).\n",
594 ieee->dev->name, skb->len);
595 goto success;
596 }
597 /* Save source and destination addresses */
598 memcpy(dest, skb->data, ETH_ALEN);
599 memcpy(src, skb->data+ETH_ALEN, ETH_ALEN);
600
601 memset(skb->cb, 0, sizeof(skb->cb));
602 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
603
Larry Fingerf38d2232011-08-25 11:48:28 -0500604 if (ieee->iw_mode == IW_MODE_MONITOR) {
Larry Finger94a79942011-08-23 19:00:42 -0500605 txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC);
606 if (unlikely(!txb)) {
Larry Fingerf38d2232011-08-25 11:48:28 -0500607 printk(KERN_WARNING "%s: Could not allocate "
608 "TXB\n",
Larry Finger94a79942011-08-23 19:00:42 -0500609 ieee->dev->name);
610 goto failed;
611 }
612
613 txb->encrypted = 0;
614 txb->payload_size = skb->len;
Larry Fingerf38d2232011-08-25 11:48:28 -0500615 memcpy(skb_put(txb->fragments[0], skb->len), skb->data,
616 skb->len);
Larry Finger94a79942011-08-23 19:00:42 -0500617
618 goto success;
619 }
620
Larry Finger55dc4eb2011-08-25 11:48:13 -0500621 if (skb->len > 282) {
Larry Finger94a79942011-08-23 19:00:42 -0500622 if (ETH_P_IP == ether_type) {
Larry Fingerf38d2232011-08-25 11:48:28 -0500623 const struct iphdr *ip = (struct iphdr *)
624 ((u8 *)skb->data+14);
Larry Finger94a79942011-08-23 19:00:42 -0500625 if (IPPROTO_UDP == ip->protocol) {
Larry Fingerf38d2232011-08-25 11:48:28 -0500626 struct udphdr *udp;
627
628 udp = (struct udphdr *)((u8 *)ip +
629 (ip->ihl << 2));
630 if (((((u8 *)udp)[1] == 68) &&
631 (((u8 *)udp)[3] == 67)) ||
632 ((((u8 *)udp)[1] == 67) &&
633 (((u8 *)udp)[3] == 68))) {
Larry Finger94a79942011-08-23 19:00:42 -0500634 bdhcp = true;
635 ieee->LPSDelayCnt = 200;
636 }
637 }
Larry Fingerf38d2232011-08-25 11:48:28 -0500638 } else if (ETH_P_ARP == ether_type) {
639 printk(KERN_INFO "=================>DHCP "
640 "Protocol start tx ARP pkt!!\n");
Larry Finger94a79942011-08-23 19:00:42 -0500641 bdhcp = true;
Larry Fingerf38d2232011-08-25 11:48:28 -0500642 ieee->LPSDelayCnt =
643 ieee->current_network.tim.tim_count;
Larry Finger94a79942011-08-23 19:00:42 -0500644 }
645 }
646
647 skb->priority = rtllib_classify(skb, IsAmsdu);
648 crypt = ieee->crypt[ieee->tx_keyidx];
649 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
650 ieee->host_encrypt && crypt && crypt->ops;
651 if (!encrypt && ieee->ieee802_1x &&
Larry Fingerf38d2232011-08-25 11:48:28 -0500652 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
Larry Finger94a79942011-08-23 19:00:42 -0500653 stats->tx_dropped++;
654 goto success;
655 }
Larry Finger94a79942011-08-23 19:00:42 -0500656 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
657 struct eapol *eap = (struct eapol *)(skb->data +
Larry Fingerf38d2232011-08-25 11:48:28 -0500658 sizeof(struct ethhdr) - SNAP_SIZE -
659 sizeof(u16));
Larry Finger94a79942011-08-23 19:00:42 -0500660 RTLLIB_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
661 eap_get_type(eap->type));
662 }
Larry Finger94a79942011-08-23 19:00:42 -0500663
664 /* Advance the SKB to the start of the payload */
665 skb_pull(skb, sizeof(struct ethhdr));
666
Larry Fingerf38d2232011-08-25 11:48:28 -0500667 /* Determine total amount of storage required for TXB packets */
Larry Finger94a79942011-08-23 19:00:42 -0500668 bytes = skb->len + SNAP_SIZE + sizeof(u16);
669
670 if (encrypt)
671 fc = RTLLIB_FTYPE_DATA | RTLLIB_FCTL_WEP;
672 else
673 fc = RTLLIB_FTYPE_DATA;
674
675 if (qos_actived)
676 fc |= RTLLIB_STYPE_QOS_DATA;
677 else
678 fc |= RTLLIB_STYPE_DATA;
679
680 if (ieee->iw_mode == IW_MODE_INFRA) {
681 fc |= RTLLIB_FCTL_TODS;
682 /* To DS: Addr1 = BSSID, Addr2 = SA,
683 Addr3 = DA */
Larry Fingerf38d2232011-08-25 11:48:28 -0500684 memcpy(&header.addr1, ieee->current_network.bssid,
685 ETH_ALEN);
Larry Finger94a79942011-08-23 19:00:42 -0500686 memcpy(&header.addr2, &src, ETH_ALEN);
687 if (IsAmsdu)
Larry Fingerf38d2232011-08-25 11:48:28 -0500688 memcpy(&header.addr3,
689 ieee->current_network.bssid, ETH_ALEN);
Larry Finger94a79942011-08-23 19:00:42 -0500690 else
691 memcpy(&header.addr3, &dest, ETH_ALEN);
692 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
693 /* not From/To DS: Addr1 = DA, Addr2 = SA,
694 Addr3 = BSSID */
695 memcpy(&header.addr1, dest, ETH_ALEN);
696 memcpy(&header.addr2, src, ETH_ALEN);
Larry Fingerf38d2232011-08-25 11:48:28 -0500697 memcpy(&header.addr3, ieee->current_network.bssid,
698 ETH_ALEN);
Larry Finger94a79942011-08-23 19:00:42 -0500699 }
700
Larry Fingerf38d2232011-08-25 11:48:28 -0500701 bIsMulticast = is_broadcast_ether_addr(header.addr1) ||
702 is_multicast_ether_addr(header.addr1);
Larry Finger94a79942011-08-23 19:00:42 -0500703
Larry Fingerf38d2232011-08-25 11:48:28 -0500704 header.frame_ctl = cpu_to_le16(fc);
Larry Finger94a79942011-08-23 19:00:42 -0500705
706 /* Determine fragmentation size based on destination (multicast
707 * and broadcast are not fragmented) */
708 if (bIsMulticast) {
709 frag_size = MAX_FRAG_THRESHOLD;
710 qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
711 } else {
712 frag_size = ieee->fts;
713 qos_ctl = 0;
714 }
715
716 if (qos_actived) {
717 hdr_len = RTLLIB_3ADDR_LEN + 2;
718
Larry Fingerf38d2232011-08-25 11:48:28 -0500719 /* in case we are a client verify acm is not set for this ac */
720 while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) {
721 printk(KERN_INFO "skb->priority = %x\n", skb->priority);
722 if (wme_downgrade_ac(skb))
723 break;
724 printk(KERN_INFO "converted skb->priority = %x\n",
725 skb->priority);
726 }
727 qos_ctl |= skb->priority;
728 header.qos_ctl = cpu_to_le16(qos_ctl & RTLLIB_QOS_TID);
Larry Finger94a79942011-08-23 19:00:42 -0500729 } else {
730 hdr_len = RTLLIB_3ADDR_LEN;
731 }
732 /* Determine amount of payload per fragment. Regardless of if
Larry Fingerf38d2232011-08-25 11:48:28 -0500733 * this stack is providing the full 802.11 header, one will
734 * eventually be affixed to this fragment -- so we must account
735 * for it when determining the amount of payload space. */
Larry Finger94a79942011-08-23 19:00:42 -0500736 bytes_per_frag = frag_size - hdr_len;
737 if (ieee->config &
Larry Fingerf38d2232011-08-25 11:48:28 -0500738 (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS))
Larry Finger94a79942011-08-23 19:00:42 -0500739 bytes_per_frag -= RTLLIB_FCS_LEN;
740
Larry Fingerf38d2232011-08-25 11:48:28 -0500741 /* Each fragment may need to have room for encryptiong
742 * pre/postfix */
Larry Finger94a79942011-08-23 19:00:42 -0500743 if (encrypt) {
744 bytes_per_frag -= crypt->ops->extra_prefix_len +
745 crypt->ops->extra_postfix_len;
746 }
747 /* Number of fragments is the total bytes_per_frag /
748 * payload_per_fragment */
749 nr_frags = bytes / bytes_per_frag;
750 bytes_last_frag = bytes % bytes_per_frag;
751 if (bytes_last_frag)
752 nr_frags++;
753 else
754 bytes_last_frag = bytes_per_frag;
755
Larry Fingerf38d2232011-08-25 11:48:28 -0500756 /* When we allocate the TXB we allocate enough space for the
757 * reserve and full fragment bytes (bytes_per_frag doesn't
758 * include prefix, postfix, header, FCS, etc.) */
759 txb = rtllib_alloc_txb(nr_frags, frag_size +
760 ieee->tx_headroom, GFP_ATOMIC);
Larry Finger94a79942011-08-23 19:00:42 -0500761 if (unlikely(!txb)) {
762 printk(KERN_WARNING "%s: Could not allocate TXB\n",
763 ieee->dev->name);
764 goto failed;
765 }
766 txb->encrypted = encrypt;
767 txb->payload_size = bytes;
768
769 if (qos_actived)
Larry Finger94a79942011-08-23 19:00:42 -0500770 txb->queue_index = UP2AC(skb->priority);
Larry Fingerf38d2232011-08-25 11:48:28 -0500771 else
772 txb->queue_index = WME_AC_BE;
Larry Finger94a79942011-08-23 19:00:42 -0500773
774 for (i = 0; i < nr_frags; i++) {
775 skb_frag = txb->fragments[i];
Larry Fingerf38d2232011-08-25 11:48:28 -0500776 tcb_desc = (struct cb_desc *)(skb_frag->cb +
777 MAX_DEV_ADDR_SIZE);
778 if (qos_actived) {
Larry Finger94a79942011-08-23 19:00:42 -0500779 skb_frag->priority = skb->priority;
780 tcb_desc->queue_index = UP2AC(skb->priority);
781 } else {
782 skb_frag->priority = WME_AC_BE;
783 tcb_desc->queue_index = WME_AC_BE;
784 }
785 skb_reserve(skb_frag, ieee->tx_headroom);
786
Larry Fingerf38d2232011-08-25 11:48:28 -0500787 if (encrypt) {
Larry Finger94a79942011-08-23 19:00:42 -0500788 if (ieee->hwsec_active)
789 tcb_desc->bHwSec = 1;
790 else
791 tcb_desc->bHwSec = 0;
Larry Fingerf38d2232011-08-25 11:48:28 -0500792 skb_reserve(skb_frag,
793 crypt->ops->extra_prefix_len);
Larry Finger94a79942011-08-23 19:00:42 -0500794 } else {
795 tcb_desc->bHwSec = 0;
796 }
Larry Fingerf38d2232011-08-25 11:48:28 -0500797 frag_hdr = (struct rtllib_hdr_3addrqos *)
798 skb_put(skb_frag, hdr_len);
Larry Finger94a79942011-08-23 19:00:42 -0500799 memcpy(frag_hdr, &header, hdr_len);
800
Larry Fingerf38d2232011-08-25 11:48:28 -0500801 /* If this is not the last fragment, then add the
802 * MOREFRAGS bit to the frame control */
Larry Finger94a79942011-08-23 19:00:42 -0500803 if (i != nr_frags - 1) {
804 frag_hdr->frame_ctl = cpu_to_le16(
805 fc | RTLLIB_FCTL_MOREFRAGS);
806 bytes = bytes_per_frag;
807
808 } else {
Larry Fingerf38d2232011-08-25 11:48:28 -0500809 /* The last fragment has the remaining length */
Larry Finger94a79942011-08-23 19:00:42 -0500810 bytes = bytes_last_frag;
811 }
Larry Fingerf38d2232011-08-25 11:48:28 -0500812 if ((qos_actived) && (!bIsMulticast)) {
813 frag_hdr->seq_ctl =
814 rtllib_query_seqnum(ieee, skb_frag,
815 header.addr1);
816 frag_hdr->seq_ctl =
817 cpu_to_le16(frag_hdr->seq_ctl<<4 | i);
Larry Finger94a79942011-08-23 19:00:42 -0500818 } else {
Larry Fingerf38d2232011-08-25 11:48:28 -0500819 frag_hdr->seq_ctl =
820 cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
Larry Finger94a79942011-08-23 19:00:42 -0500821 }
822 /* Put a SNAP header on the first fragment */
823 if (i == 0) {
824 rtllib_put_snap(
Larry Fingerf38d2232011-08-25 11:48:28 -0500825 skb_put(skb_frag, SNAP_SIZE +
826 sizeof(u16)), ether_type);
Larry Finger94a79942011-08-23 19:00:42 -0500827 bytes -= SNAP_SIZE + sizeof(u16);
828 }
829
830 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
831
832 /* Advance the SKB... */
833 skb_pull(skb, bytes);
834
Larry Fingerf38d2232011-08-25 11:48:28 -0500835 /* Encryption routine will move the header forward in
836 * order to insert the IV between the header and the
837 * payload */
Larry Finger94a79942011-08-23 19:00:42 -0500838 if (encrypt)
Larry Fingerf38d2232011-08-25 11:48:28 -0500839 rtllib_encrypt_fragment(ieee, skb_frag,
840 hdr_len);
Larry Finger94a79942011-08-23 19:00:42 -0500841 if (ieee->config &
Larry Fingerf38d2232011-08-25 11:48:28 -0500842 (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS))
Larry Finger94a79942011-08-23 19:00:42 -0500843 skb_put(skb_frag, 4);
844 }
845
846 if ((qos_actived) && (!bIsMulticast)) {
Larry Fingerf38d2232011-08-25 11:48:28 -0500847 if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
848 ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
849 else
850 ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
Larry Finger94a79942011-08-23 19:00:42 -0500851 } else {
Larry Fingerf38d2232011-08-25 11:48:28 -0500852 if (ieee->seq_ctrl[0] == 0xFFF)
853 ieee->seq_ctrl[0] = 0;
854 else
855 ieee->seq_ctrl[0]++;
Larry Finger94a79942011-08-23 19:00:42 -0500856 }
Larry Fingerf38d2232011-08-25 11:48:28 -0500857 } else {
Larry Finger94a79942011-08-23 19:00:42 -0500858 if (unlikely(skb->len < sizeof(struct rtllib_hdr_3addr))) {
859 printk(KERN_WARNING "%s: skb too small (%d).\n",
860 ieee->dev->name, skb->len);
861 goto success;
862 }
863
864 txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC);
Larry Fingerf38d2232011-08-25 11:48:28 -0500865 if (!txb) {
Larry Finger94a79942011-08-23 19:00:42 -0500866 printk(KERN_WARNING "%s: Could not allocate TXB\n",
867 ieee->dev->name);
868 goto failed;
869 }
870
871 txb->encrypted = 0;
872 txb->payload_size = skb->len;
Larry Fingerf38d2232011-08-25 11:48:28 -0500873 memcpy(skb_put(txb->fragments[0], skb->len), skb->data,
874 skb->len);
Larry Finger94a79942011-08-23 19:00:42 -0500875 }
876
877 success:
Larry Fingerf38d2232011-08-25 11:48:28 -0500878 if (txb) {
879 struct cb_desc *tcb_desc = (struct cb_desc *)
880 (txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
Larry Finger94a79942011-08-23 19:00:42 -0500881 tcb_desc->bTxEnableFwCalcDur = 1;
882 tcb_desc->priority = skb->priority;
883
884 if (ether_type == ETH_P_PAE) {
Larry Fingerf38d2232011-08-25 11:48:28 -0500885 if (ieee->pHTInfo->IOTAction &
886 HT_IOT_ACT_WA_IOT_Broadcom) {
887 tcb_desc->data_rate =
888 MgntQuery_TxRateExcludeCCKRates(ieee);
Larry Finger94a79942011-08-23 19:00:42 -0500889 tcb_desc->bTxDisableRateFallBack = false;
Larry Fingerf38d2232011-08-25 11:48:28 -0500890 } else {
Larry Finger94a79942011-08-23 19:00:42 -0500891 tcb_desc->data_rate = ieee->basic_rate;
892 tcb_desc->bTxDisableRateFallBack = 1;
893 }
894
895
896 tcb_desc->RATRIndex = 7;
897 tcb_desc->bTxUseDriverAssingedRate = 1;
898 } else {
899 if (is_multicast_ether_addr(header.addr1))
900 tcb_desc->bMulticast = 1;
901 if (is_broadcast_ether_addr(header.addr1))
902 tcb_desc->bBroadcast = 1;
Larry Finger94a79942011-08-23 19:00:42 -0500903 rtllib_txrate_selectmode(ieee, tcb_desc);
Larry Fingerf38d2232011-08-25 11:48:28 -0500904 if (tcb_desc->bMulticast || tcb_desc->bBroadcast)
Larry Finger94a79942011-08-23 19:00:42 -0500905 tcb_desc->data_rate = ieee->basic_rate;
906 else
Larry Fingerf38d2232011-08-25 11:48:28 -0500907 tcb_desc->data_rate = CURRENT_RATE(ieee->mode,
908 ieee->rate, ieee->HTCurrentOperaRate);
Larry Finger94a79942011-08-23 19:00:42 -0500909
Larry Fingerf38d2232011-08-25 11:48:28 -0500910 if (bdhcp == true) {
911 if (ieee->pHTInfo->IOTAction &
912 HT_IOT_ACT_WA_IOT_Broadcom) {
913 tcb_desc->data_rate =
914 MgntQuery_TxRateExcludeCCKRates(ieee);
Larry Finger94a79942011-08-23 19:00:42 -0500915 tcb_desc->bTxDisableRateFallBack = false;
Larry Fingerf38d2232011-08-25 11:48:28 -0500916 } else {
Larry Finger94a79942011-08-23 19:00:42 -0500917 tcb_desc->data_rate = MGN_1M;
918 tcb_desc->bTxDisableRateFallBack = 1;
919 }
920
921
922 tcb_desc->RATRIndex = 7;
923 tcb_desc->bTxUseDriverAssingedRate = 1;
924 tcb_desc->bdhcp = 1;
925 }
926
927 rtllib_qurey_ShortPreambleMode(ieee, tcb_desc);
Larry Fingerf38d2232011-08-25 11:48:28 -0500928 rtllib_tx_query_agg_cap(ieee, txb->fragments[0],
929 tcb_desc);
Larry Finger94a79942011-08-23 19:00:42 -0500930 rtllib_query_HTCapShortGI(ieee, tcb_desc);
931 rtllib_query_BandwidthMode(ieee, tcb_desc);
Larry Fingerf38d2232011-08-25 11:48:28 -0500932 rtllib_query_protectionmode(ieee, tcb_desc,
933 txb->fragments[0]);
Larry Finger94a79942011-08-23 19:00:42 -0500934 }
Larry Finger94a79942011-08-23 19:00:42 -0500935 }
936 spin_unlock_irqrestore(&ieee->lock, flags);
937 dev_kfree_skb_any(skb);
938 if (txb) {
Larry Fingerf38d2232011-08-25 11:48:28 -0500939 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) {
Larry Finger94a79942011-08-23 19:00:42 -0500940 dev->stats.tx_packets++;
941 dev->stats.tx_bytes += txb->payload_size;
942 rtllib_softmac_xmit(txb, ieee);
Larry Fingerf38d2232011-08-25 11:48:28 -0500943 } else {
Larry Finger94a79942011-08-23 19:00:42 -0500944 if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
945 stats->tx_packets++;
946 stats->tx_bytes += txb->payload_size;
947 return 0;
948 }
949 rtllib_txb_free(txb);
950 }
951 }
952
953 return 0;
954
955 failed:
956 spin_unlock_irqrestore(&ieee->lock, flags);
957 netif_stop_queue(dev);
958 stats->tx_errors++;
959 return 1;
960
961}
962int rtllib_xmit(struct sk_buff *skb, struct net_device *dev)
963{
964 memset(skb->cb, 0, sizeof(skb->cb));
965 return rtllib_xmit_inter(skb, dev);
966}