1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. |
4 | * |
5 | * Contact Information: |
6 | * James P. Ketrenos <ipw2100-admin@linux.intel.com> |
7 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
8 | * |
9 | * Few modifications for Realtek's Wi-Fi drivers by |
10 | * Andrea Merello <andrea.merello@gmail.com> |
11 | * |
12 | * A special thanks goes to Realtek for their support ! |
13 | */ |
14 | #include <linux/compiler.h> |
15 | #include <linux/errno.h> |
16 | #include <linux/if_arp.h> |
17 | #include <linux/in6.h> |
18 | #include <linux/in.h> |
19 | #include <linux/ip.h> |
20 | #include <linux/kernel.h> |
21 | #include <linux/module.h> |
22 | #include <linux/netdevice.h> |
23 | #include <linux/pci.h> |
24 | #include <linux/proc_fs.h> |
25 | #include <linux/skbuff.h> |
26 | #include <linux/slab.h> |
27 | #include <linux/tcp.h> |
28 | #include <linux/types.h> |
29 | #include <linux/wireless.h> |
30 | #include <linux/etherdevice.h> |
31 | #include <linux/uaccess.h> |
32 | #include <linux/if_vlan.h> |
33 | |
34 | #include "rtllib.h" |
35 | |
36 | /* 802.11 Data Frame |
37 | * |
38 | * |
39 | * 802.11 frame_control for data frames - 2 bytes |
40 | * ,--------------------------------------------------------------------. |
41 | * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | |
42 | * |---|---|---|---|---|---|---|---|---|----|----|-----|-----|-----|----| |
43 | * val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x | |
44 | * |---|---|---|---|---|---|---|---|---|----|----|-----|-----|-----|----| |
45 | * desc | ver | type | ^-subtype-^ |to |from|more|retry| pwr |more |wep | |
46 | * | | | x=0 data |DS | DS |frag| | mgm |data | | |
47 | * | | | x=1 data+ack | | | | | | | | |
48 | * '--------------------------------------------------------------------' |
49 | * /\ |
50 | * | |
51 | * 802.11 Data Frame | |
52 | * ,--------- 'ctrl' expands to >---' |
53 | * | |
54 | * ,--'---,-------------------------------------------------------------. |
55 | * Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | |
56 | * |------|------|---------|---------|---------|------|---------|------| |
57 | * Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs | |
58 | * | | tion | (BSSID) | | | ence | data | | |
59 | * `--------------------------------------------------| |------' |
60 | * Total: 28 non-data bytes `----.----' |
61 | * | |
62 | * .- 'Frame data' expands to <---------------------------' |
63 | * | |
64 | * V |
65 | * ,---------------------------------------------------. |
66 | * Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 | |
67 | * |------|------|---------|----------|------|---------| |
68 | * Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP | |
69 | * | DSAP | SSAP | | | | Packet | |
70 | * | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | | |
71 | * `-----------------------------------------| | |
72 | * Total: 8 non-data bytes `----.----' |
73 | * | |
74 | * .- 'IP Packet' expands, if WEP enabled, to <--' |
75 | * | |
76 | * V |
77 | * ,-----------------------. |
78 | * Bytes | 4 | 0-2296 | 4 | |
79 | * |-----|-----------|-----| |
80 | * Desc. | IV | Encrypted | ICV | |
81 | * | | IP Packet | | |
82 | * `-----------------------' |
83 | * Total: 8 non-data bytes |
84 | * |
85 | * |
86 | * 802.3 Ethernet Data Frame |
87 | * |
88 | * ,-----------------------------------------. |
89 | * Bytes | 6 | 6 | 2 | Variable | 4 | |
90 | * |-------|-------|------|-----------|------| |
91 | * Desc. | Dest. | Source| Type | IP Packet | fcs | |
92 | * | MAC | MAC | | | | |
93 | * `-----------------------------------------' |
94 | * Total: 18 non-data bytes |
95 | * |
96 | * In the event that fragmentation is required, the incoming payload is split |
97 | * into N parts of size ieee->fts. The first fragment contains the SNAP header |
98 | * and the remaining packets are just data. |
99 | * |
100 | * If encryption is enabled, each fragment payload size is reduced by enough |
101 | * space to add the prefix and postfix (IV and ICV totalling 8 bytes in |
102 | * the case of WEP) So if you have 1500 bytes of payload with ieee->fts set to |
103 | * 500 without encryption it will take 3 frames. With WEP it will take 4 frames |
104 | * as the payload of each frame is reduced to 492 bytes. |
105 | * |
106 | * SKB visualization |
107 | * |
108 | * ,- skb->data |
109 | * | |
110 | * | ETHERNET HEADER ,-<-- PAYLOAD |
111 | * | | 14 bytes from skb->data |
112 | * | 2 bytes for Type --> ,T. | (sizeof ethhdr) |
113 | * | | | | |
114 | * |,-Dest.--. ,--Src.---. | | | |
115 | * | 6 bytes| | 6 bytes | | | | |
116 | * v | | | | | | |
117 | * 0 | v 1 | v | v 2 |
118 | * 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 |
119 | * ^ | ^ | ^ | |
120 | * | | | | | | |
121 | * | | | | `T' <---- 2 bytes for Type |
122 | * | | | | |
123 | * | | '---SNAP--' <-------- 6 bytes for SNAP |
124 | * | | |
125 | * `-IV--' <-------------------- 4 bytes for IV (WEP) |
126 | * |
127 | * SNAP HEADER |
128 | * |
129 | */ |
130 | |
131 | static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; |
132 | static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; |
133 | |
134 | static int rtllib_put_snap(u8 *data, u16 h_proto) |
135 | { |
136 | struct rtllib_snap_hdr *snap; |
137 | u8 *oui; |
138 | |
139 | snap = (struct rtllib_snap_hdr *)data; |
140 | snap->dsap = 0xaa; |
141 | snap->ssap = 0xaa; |
142 | snap->ctrl = 0x03; |
143 | |
144 | if (h_proto == 0x8137 || h_proto == 0x80f3) |
145 | oui = P802_1H_OUI; |
146 | else |
147 | oui = RFC1042_OUI; |
148 | snap->oui[0] = oui[0]; |
149 | snap->oui[1] = oui[1]; |
150 | snap->oui[2] = oui[2]; |
151 | |
152 | *(__be16 *)(data + SNAP_SIZE) = htons(h_proto); |
153 | |
154 | return SNAP_SIZE + sizeof(u16); |
155 | } |
156 | |
157 | int rtllib_encrypt_fragment(struct rtllib_device *ieee, struct sk_buff *frag, |
158 | int hdr_len) |
159 | { |
160 | struct lib80211_crypt_data *crypt = NULL; |
161 | int res; |
162 | |
163 | crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; |
164 | |
165 | if (!(crypt && crypt->ops)) { |
166 | netdev_info(dev: ieee->dev, format: "=========>%s(), crypt is null\n" , |
167 | __func__); |
168 | return -1; |
169 | } |
170 | /* To encrypt, frame format is: |
171 | * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) |
172 | */ |
173 | |
174 | /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so |
175 | * call both MSDU and MPDU encryption functions from here. |
176 | */ |
177 | atomic_inc(v: &crypt->refcnt); |
178 | res = 0; |
179 | if (crypt->ops->encrypt_msdu) |
180 | res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv); |
181 | if (res == 0 && crypt->ops->encrypt_mpdu) |
182 | res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv); |
183 | |
184 | atomic_dec(v: &crypt->refcnt); |
185 | if (res < 0) { |
186 | netdev_info(dev: ieee->dev, format: "%s: Encryption failed: len=%d.\n" , |
187 | ieee->dev->name, frag->len); |
188 | return -1; |
189 | } |
190 | |
191 | return 0; |
192 | } |
193 | |
194 | void rtllib_txb_free(struct rtllib_txb *txb) |
195 | { |
196 | if (unlikely(!txb)) |
197 | return; |
198 | kfree(objp: txb); |
199 | } |
200 | |
201 | static struct rtllib_txb *rtllib_alloc_txb(int nr_frags, int txb_size, |
202 | gfp_t gfp_mask) |
203 | { |
204 | struct rtllib_txb *txb; |
205 | int i; |
206 | |
207 | txb = kzalloc(struct_size(txb, fragments, nr_frags), flags: gfp_mask); |
208 | if (!txb) |
209 | return NULL; |
210 | |
211 | txb->nr_frags = nr_frags; |
212 | txb->frag_size = cpu_to_le16(txb_size); |
213 | |
214 | for (i = 0; i < nr_frags; i++) { |
215 | txb->fragments[i] = dev_alloc_skb(length: txb_size); |
216 | if (unlikely(!txb->fragments[i])) |
217 | goto err_free; |
218 | memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb)); |
219 | } |
220 | |
221 | return txb; |
222 | |
223 | err_free: |
224 | while (--i >= 0) |
225 | dev_kfree_skb_any(skb: txb->fragments[i]); |
226 | kfree(objp: txb); |
227 | |
228 | return NULL; |
229 | } |
230 | |
231 | static int rtllib_classify(struct sk_buff *skb, u8 bIsAmsdu) |
232 | { |
233 | struct ethhdr *eth; |
234 | struct iphdr *ip; |
235 | |
236 | eth = (struct ethhdr *)skb->data; |
237 | if (eth->h_proto != htons(ETH_P_IP)) |
238 | return 0; |
239 | |
240 | #ifdef VERBOSE_DEBUG |
241 | print_hex_dump_bytes("%s: " , __func__, DUMP_PREFIX_NONE, skb->data, |
242 | skb->len); |
243 | #endif |
244 | ip = ip_hdr(skb); |
245 | switch (ip->tos & 0xfc) { |
246 | case 0x20: |
247 | return 2; |
248 | case 0x40: |
249 | return 1; |
250 | case 0x60: |
251 | return 3; |
252 | case 0x80: |
253 | return 4; |
254 | case 0xa0: |
255 | return 5; |
256 | case 0xc0: |
257 | return 6; |
258 | case 0xe0: |
259 | return 7; |
260 | default: |
261 | return 0; |
262 | } |
263 | } |
264 | |
265 | static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, |
266 | struct sk_buff *skb, |
267 | struct cb_desc *tcb_desc) |
268 | { |
269 | struct rt_hi_throughput *ht_info = ieee->ht_info; |
270 | struct tx_ts_record *ts = NULL; |
271 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
272 | |
273 | if (rtllib_act_scanning(ieee, sync_scan: false)) |
274 | return; |
275 | |
276 | if (!ht_info->current_ht_support || !ht_info->enable_ht) |
277 | return; |
278 | if (!IsQoSDataFrame(skb->data)) |
279 | return; |
280 | if (is_multicast_ether_addr(addr: hdr->addr1)) |
281 | return; |
282 | |
283 | if (tcb_desc->bdhcp || ieee->CntAfterLink < 2) |
284 | return; |
285 | |
286 | if (ht_info->iot_action & HT_IOT_ACT_TX_NO_AGGREGATION) |
287 | return; |
288 | |
289 | if (!ieee->get_nmode_support_by_sec_cfg(ieee->dev)) |
290 | return; |
291 | if (ht_info->current_ampdu_enable) { |
292 | if (!rtllib_get_ts(ieee, ppTS: (struct ts_common_info **)(&ts), addr: hdr->addr1, |
293 | TID: skb->priority, tx_rx_select: TX_DIR, bAddNewTs: true)) { |
294 | netdev_info(dev: ieee->dev, format: "%s: can't get TS\n" , __func__); |
295 | return; |
296 | } |
297 | if (!ts->tx_admitted_ba_record.b_valid) { |
298 | if (ieee->wpa_ie_len && (ieee->pairwise_key_type == |
299 | KEY_TYPE_NA)) { |
300 | ; |
301 | } else if (tcb_desc->bdhcp == 1) { |
302 | ; |
303 | } else if (!ts->disable_add_ba) { |
304 | TsStartAddBaProcess(ieee, pTxTS: ts); |
305 | } |
306 | return; |
307 | } else if (!ts->using_ba) { |
308 | if (SN_LESS(ts->tx_admitted_ba_record.ba_start_seq_ctrl.field.seq_num, |
309 | (ts->tx_cur_seq + 1) % 4096)) |
310 | ts->using_ba = true; |
311 | else |
312 | return; |
313 | } |
314 | if (ieee->iw_mode == IW_MODE_INFRA) { |
315 | tcb_desc->ampdu_enable = true; |
316 | tcb_desc->ampdu_factor = ht_info->CurrentAMPDUFactor; |
317 | tcb_desc->ampdu_density = ht_info->current_mpdu_density; |
318 | } |
319 | } |
320 | } |
321 | |
322 | static void rtllib_query_ShortPreambleMode(struct rtllib_device *ieee, |
323 | struct cb_desc *tcb_desc) |
324 | { |
325 | tcb_desc->bUseShortPreamble = false; |
326 | if (tcb_desc->data_rate == 2) |
327 | return; |
328 | else if (ieee->current_network.capability & |
329 | WLAN_CAPABILITY_SHORT_PREAMBLE) |
330 | tcb_desc->bUseShortPreamble = true; |
331 | } |
332 | |
333 | static void rtllib_query_HTCapShortGI(struct rtllib_device *ieee, |
334 | struct cb_desc *tcb_desc) |
335 | { |
336 | struct rt_hi_throughput *ht_info = ieee->ht_info; |
337 | |
338 | tcb_desc->bUseShortGI = false; |
339 | |
340 | if (!ht_info->current_ht_support || !ht_info->enable_ht) |
341 | return; |
342 | |
343 | if (ht_info->cur_bw_40mhz && ht_info->cur_short_gi_40mhz) |
344 | tcb_desc->bUseShortGI = true; |
345 | else if (!ht_info->cur_bw_40mhz && ht_info->cur_short_gi_20mhz) |
346 | tcb_desc->bUseShortGI = true; |
347 | } |
348 | |
349 | static void rtllib_query_BandwidthMode(struct rtllib_device *ieee, |
350 | struct cb_desc *tcb_desc) |
351 | { |
352 | struct rt_hi_throughput *ht_info = ieee->ht_info; |
353 | |
354 | tcb_desc->bPacketBW = false; |
355 | |
356 | if (!ht_info->current_ht_support || !ht_info->enable_ht) |
357 | return; |
358 | |
359 | if (tcb_desc->multicast || tcb_desc->bBroadcast) |
360 | return; |
361 | |
362 | if ((tcb_desc->data_rate & 0x80) == 0) |
363 | return; |
364 | if (ht_info->cur_bw_40mhz && ht_info->cur_tx_bw40mhz && |
365 | !ieee->bandwidth_auto_switch.bforced_tx20Mhz) |
366 | tcb_desc->bPacketBW = true; |
367 | } |
368 | |
369 | static void rtllib_query_protectionmode(struct rtllib_device *ieee, |
370 | struct cb_desc *tcb_desc, |
371 | struct sk_buff *skb) |
372 | { |
373 | struct rt_hi_throughput *ht_info; |
374 | |
375 | tcb_desc->bRTSSTBC = false; |
376 | tcb_desc->bRTSUseShortGI = false; |
377 | tcb_desc->bCTSEnable = false; |
378 | tcb_desc->RTSSC = 0; |
379 | tcb_desc->bRTSBW = false; |
380 | |
381 | if (tcb_desc->bBroadcast || tcb_desc->multicast) |
382 | return; |
383 | |
384 | if (is_broadcast_ether_addr(addr: skb->data + 16)) |
385 | return; |
386 | |
387 | if (ieee->mode < WIRELESS_MODE_N_24G) { |
388 | if (skb->len > ieee->rts) { |
389 | tcb_desc->bRTSEnable = true; |
390 | tcb_desc->rts_rate = MGN_24M; |
391 | } else if (ieee->current_network.buseprotection) { |
392 | tcb_desc->bRTSEnable = true; |
393 | tcb_desc->bCTSEnable = true; |
394 | tcb_desc->rts_rate = MGN_24M; |
395 | } |
396 | return; |
397 | } |
398 | |
399 | ht_info = ieee->ht_info; |
400 | |
401 | while (true) { |
402 | if (ht_info->iot_action & HT_IOT_ACT_FORCED_CTS2SELF) { |
403 | tcb_desc->bCTSEnable = true; |
404 | tcb_desc->rts_rate = MGN_24M; |
405 | tcb_desc->bRTSEnable = true; |
406 | break; |
407 | } else if (ht_info->iot_action & (HT_IOT_ACT_FORCED_RTS | |
408 | HT_IOT_ACT_PURE_N_MODE)) { |
409 | tcb_desc->bRTSEnable = true; |
410 | tcb_desc->rts_rate = MGN_24M; |
411 | break; |
412 | } |
413 | if (ieee->current_network.buseprotection) { |
414 | tcb_desc->bRTSEnable = true; |
415 | tcb_desc->bCTSEnable = true; |
416 | tcb_desc->rts_rate = MGN_24M; |
417 | break; |
418 | } |
419 | if (ht_info->current_ht_support && ht_info->enable_ht) { |
420 | u8 HTOpMode = ht_info->current_op_mode; |
421 | |
422 | if ((ht_info->cur_bw_40mhz && (HTOpMode == 2 || |
423 | HTOpMode == 3)) || |
424 | (!ht_info->cur_bw_40mhz && HTOpMode == 3)) { |
425 | tcb_desc->rts_rate = MGN_24M; |
426 | tcb_desc->bRTSEnable = true; |
427 | break; |
428 | } |
429 | } |
430 | if (skb->len > ieee->rts) { |
431 | tcb_desc->rts_rate = MGN_24M; |
432 | tcb_desc->bRTSEnable = true; |
433 | break; |
434 | } |
435 | if (tcb_desc->ampdu_enable) { |
436 | tcb_desc->rts_rate = MGN_24M; |
437 | tcb_desc->bRTSEnable = false; |
438 | break; |
439 | } |
440 | goto NO_PROTECTION; |
441 | } |
442 | if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) |
443 | tcb_desc->bUseShortPreamble = true; |
444 | return; |
445 | NO_PROTECTION: |
446 | tcb_desc->bRTSEnable = false; |
447 | tcb_desc->bCTSEnable = false; |
448 | tcb_desc->rts_rate = 0; |
449 | tcb_desc->RTSSC = 0; |
450 | tcb_desc->bRTSBW = false; |
451 | } |
452 | |
453 | static void rtllib_txrate_selectmode(struct rtllib_device *ieee, |
454 | struct cb_desc *tcb_desc) |
455 | { |
456 | if (ieee->tx_dis_rate_fallback) |
457 | tcb_desc->tx_dis_rate_fallback = true; |
458 | |
459 | if (ieee->tx_use_drv_assinged_rate) |
460 | tcb_desc->tx_use_drv_assinged_rate = true; |
461 | if (!tcb_desc->tx_dis_rate_fallback || |
462 | !tcb_desc->tx_use_drv_assinged_rate) { |
463 | if (ieee->iw_mode == IW_MODE_INFRA) |
464 | tcb_desc->ratr_index = 0; |
465 | } |
466 | } |
467 | |
468 | static u16 rtllib_query_seqnum(struct rtllib_device *ieee, struct sk_buff *skb, |
469 | u8 *dst) |
470 | { |
471 | u16 seqnum = 0; |
472 | |
473 | if (is_multicast_ether_addr(addr: dst)) |
474 | return 0; |
475 | if (IsQoSDataFrame(skb->data)) { |
476 | struct tx_ts_record *ts = NULL; |
477 | |
478 | if (!rtllib_get_ts(ieee, ppTS: (struct ts_common_info **)(&ts), addr: dst, |
479 | TID: skb->priority, tx_rx_select: TX_DIR, bAddNewTs: true)) |
480 | return 0; |
481 | seqnum = ts->tx_cur_seq; |
482 | ts->tx_cur_seq = (ts->tx_cur_seq + 1) % 4096; |
483 | return seqnum; |
484 | } |
485 | return 0; |
486 | } |
487 | |
488 | static int wme_downgrade_ac(struct sk_buff *skb) |
489 | { |
490 | switch (skb->priority) { |
491 | case 6: |
492 | case 7: |
493 | skb->priority = 5; /* VO -> VI */ |
494 | return 0; |
495 | case 4: |
496 | case 5: |
497 | skb->priority = 3; /* VI -> BE */ |
498 | return 0; |
499 | case 0: |
500 | case 3: |
501 | skb->priority = 1; /* BE -> BK */ |
502 | return 0; |
503 | default: |
504 | return -1; |
505 | } |
506 | } |
507 | |
508 | static u8 rtllib_current_rate(struct rtllib_device *ieee) |
509 | { |
510 | if (ieee->mode & IEEE_MODE_MASK) |
511 | return ieee->rate; |
512 | |
513 | if (ieee->HTCurrentOperaRate) |
514 | return ieee->HTCurrentOperaRate; |
515 | else |
516 | return ieee->rate & 0x7F; |
517 | } |
518 | |
519 | static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) |
520 | { |
521 | struct rtllib_device *ieee = (struct rtllib_device *) |
522 | netdev_priv_rsl(dev); |
523 | struct rtllib_txb *txb = NULL; |
524 | struct ieee80211_qos_hdr *frag_hdr; |
525 | int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; |
526 | unsigned long flags; |
527 | struct net_device_stats *stats = &ieee->stats; |
528 | int ether_type = 0, encrypt; |
529 | int bytes, fc, qos_ctl = 0, hdr_len; |
530 | struct sk_buff *skb_frag; |
531 | struct ieee80211_qos_hdr = { /* Ensure zero initialized */ |
532 | .duration_id = 0, |
533 | .seq_ctrl = 0, |
534 | .qos_ctrl = 0 |
535 | }; |
536 | int qos_activated = ieee->current_network.qos_data.active; |
537 | u8 dest[ETH_ALEN]; |
538 | u8 src[ETH_ALEN]; |
539 | struct lib80211_crypt_data *crypt = NULL; |
540 | struct cb_desc *tcb_desc; |
541 | u8 bIsMulticast = false; |
542 | u8 IsAmsdu = false; |
543 | bool bdhcp = false; |
544 | |
545 | spin_lock_irqsave(&ieee->lock, flags); |
546 | |
547 | /* If there is no driver handler to take the TXB, don't bother |
548 | * creating it... |
549 | */ |
550 | if (!(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) || |
551 | ((!ieee->softmac_data_hard_start_xmit && |
552 | (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { |
553 | netdev_warn(dev: ieee->dev, format: "No xmit handler.\n" ); |
554 | goto success; |
555 | } |
556 | |
557 | if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { |
558 | netdev_warn(dev: ieee->dev, format: "skb too small (%d).\n" , |
559 | skb->len); |
560 | goto success; |
561 | } |
562 | /* Save source and destination addresses */ |
563 | ether_addr_copy(dst: dest, src: skb->data); |
564 | ether_addr_copy(dst: src, src: skb->data + ETH_ALEN); |
565 | |
566 | memset(skb->cb, 0, sizeof(skb->cb)); |
567 | ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); |
568 | |
569 | if (ieee->iw_mode == IW_MODE_MONITOR) { |
570 | txb = rtllib_alloc_txb(nr_frags: 1, txb_size: skb->len, GFP_ATOMIC); |
571 | if (unlikely(!txb)) { |
572 | netdev_warn(dev: ieee->dev, |
573 | format: "Could not allocate TXB\n" ); |
574 | goto failed; |
575 | } |
576 | |
577 | txb->encrypted = 0; |
578 | txb->payload_size = cpu_to_le16(skb->len); |
579 | skb_put_data(skb: txb->fragments[0], data: skb->data, len: skb->len); |
580 | |
581 | goto success; |
582 | } |
583 | |
584 | if (skb->len > 282) { |
585 | if (ether_type == ETH_P_IP) { |
586 | const struct iphdr *ip = (struct iphdr *) |
587 | ((u8 *)skb->data + 14); |
588 | if (ip->protocol == IPPROTO_UDP) { |
589 | struct udphdr *udp; |
590 | |
591 | udp = (struct udphdr *)((u8 *)ip + |
592 | (ip->ihl << 2)); |
593 | if (((((u8 *)udp)[1] == 68) && |
594 | (((u8 *)udp)[3] == 67)) || |
595 | ((((u8 *)udp)[1] == 67) && |
596 | (((u8 *)udp)[3] == 68))) { |
597 | bdhcp = true; |
598 | ieee->lps_delay_cnt = 200; |
599 | } |
600 | } |
601 | } else if (ether_type == ETH_P_ARP) { |
602 | netdev_info(dev: ieee->dev, |
603 | format: "=================>DHCP Protocol start tx ARP pkt!!\n" ); |
604 | bdhcp = true; |
605 | ieee->lps_delay_cnt = |
606 | ieee->current_network.tim.tim_count; |
607 | } |
608 | } |
609 | |
610 | skb->priority = rtllib_classify(skb, bIsAmsdu: IsAmsdu); |
611 | crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx]; |
612 | encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && crypt && crypt->ops; |
613 | if (!encrypt && ieee->ieee802_1x && |
614 | ieee->drop_unencrypted && ether_type != ETH_P_PAE) { |
615 | stats->tx_dropped++; |
616 | goto success; |
617 | } |
618 | if (crypt && !encrypt && ether_type == ETH_P_PAE) { |
619 | struct eapol *eap = (struct eapol *)(skb->data + |
620 | sizeof(struct ethhdr) - SNAP_SIZE - |
621 | sizeof(u16)); |
622 | netdev_dbg(ieee->dev, |
623 | "TX: IEEE 802.11 EAPOL frame: %s\n" , |
624 | eap_get_type(eap->type)); |
625 | } |
626 | |
627 | /* Advance the SKB to the start of the payload */ |
628 | skb_pull(skb, len: sizeof(struct ethhdr)); |
629 | |
630 | /* Determine total amount of storage required for TXB packets */ |
631 | bytes = skb->len + SNAP_SIZE + sizeof(u16); |
632 | |
633 | if (encrypt) |
634 | fc = RTLLIB_FTYPE_DATA | IEEE80211_FCTL_PROTECTED; |
635 | else |
636 | fc = RTLLIB_FTYPE_DATA; |
637 | |
638 | if (qos_activated) |
639 | fc |= IEEE80211_STYPE_QOS_DATA; |
640 | else |
641 | fc |= IEEE80211_STYPE_DATA; |
642 | |
643 | if (ieee->iw_mode == IW_MODE_INFRA) { |
644 | fc |= IEEE80211_FCTL_TODS; |
645 | /* To DS: Addr1 = BSSID, Addr2 = SA, |
646 | * Addr3 = DA |
647 | */ |
648 | ether_addr_copy(dst: header.addr1, |
649 | src: ieee->current_network.bssid); |
650 | ether_addr_copy(dst: header.addr2, src); |
651 | if (IsAmsdu) |
652 | ether_addr_copy(dst: header.addr3, |
653 | src: ieee->current_network.bssid); |
654 | else |
655 | ether_addr_copy(dst: header.addr3, src: dest); |
656 | } |
657 | |
658 | bIsMulticast = is_multicast_ether_addr(addr: header.addr1); |
659 | |
660 | header.frame_control = cpu_to_le16(fc); |
661 | |
662 | /* Determine fragmentation size based on destination (multicast |
663 | * and broadcast are not fragmented) |
664 | */ |
665 | if (bIsMulticast) { |
666 | frag_size = MAX_FRAG_THRESHOLD; |
667 | qos_ctl |= QOS_CTL_NOTCONTAIN_ACK; |
668 | } else { |
669 | frag_size = ieee->fts; |
670 | qos_ctl = 0; |
671 | } |
672 | |
673 | if (qos_activated) { |
674 | hdr_len = RTLLIB_3ADDR_LEN + 2; |
675 | |
676 | /* in case we are a client verify acm is not set for this ac */ |
677 | while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) { |
678 | netdev_info(dev: ieee->dev, format: "skb->priority = %x\n" , |
679 | skb->priority); |
680 | if (wme_downgrade_ac(skb)) |
681 | break; |
682 | netdev_info(dev: ieee->dev, format: "converted skb->priority = %x\n" , |
683 | skb->priority); |
684 | } |
685 | |
686 | qos_ctl |= skb->priority; |
687 | header.qos_ctrl = cpu_to_le16(qos_ctl & RTLLIB_QOS_TID); |
688 | |
689 | } else { |
690 | hdr_len = RTLLIB_3ADDR_LEN; |
691 | } |
692 | /* Determine amount of payload per fragment. Regardless of if |
693 | * this stack is providing the full 802.11 header, one will |
694 | * eventually be affixed to this fragment -- so we must account |
695 | * for it when determining the amount of payload space. |
696 | */ |
697 | bytes_per_frag = frag_size - hdr_len; |
698 | if (ieee->config & |
699 | (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) |
700 | bytes_per_frag -= RTLLIB_FCS_LEN; |
701 | |
702 | /* Each fragment may need to have room for encrypting |
703 | * pre/postfix |
704 | */ |
705 | if (encrypt) { |
706 | bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len + |
707 | crypt->ops->extra_mpdu_postfix_len + |
708 | crypt->ops->extra_msdu_prefix_len + |
709 | crypt->ops->extra_msdu_postfix_len; |
710 | } |
711 | /* Number of fragments is the total bytes_per_frag / |
712 | * payload_per_fragment |
713 | */ |
714 | nr_frags = bytes / bytes_per_frag; |
715 | bytes_last_frag = bytes % bytes_per_frag; |
716 | if (bytes_last_frag) |
717 | nr_frags++; |
718 | else |
719 | bytes_last_frag = bytes_per_frag; |
720 | |
721 | /* When we allocate the TXB we allocate enough space for the |
722 | * reserve and full fragment bytes (bytes_per_frag doesn't |
723 | * include prefix, postfix, header, FCS, etc.) |
724 | */ |
725 | txb = rtllib_alloc_txb(nr_frags, txb_size: frag_size + |
726 | ieee->tx_headroom, GFP_ATOMIC); |
727 | if (unlikely(!txb)) { |
728 | netdev_warn(dev: ieee->dev, format: "Could not allocate TXB\n" ); |
729 | goto failed; |
730 | } |
731 | txb->encrypted = encrypt; |
732 | txb->payload_size = cpu_to_le16(bytes); |
733 | |
734 | if (qos_activated) |
735 | txb->queue_index = UP2AC(skb->priority); |
736 | else |
737 | txb->queue_index = WME_AC_BE; |
738 | |
739 | for (i = 0; i < nr_frags; i++) { |
740 | skb_frag = txb->fragments[i]; |
741 | tcb_desc = (struct cb_desc *)(skb_frag->cb + |
742 | MAX_DEV_ADDR_SIZE); |
743 | if (qos_activated) { |
744 | skb_frag->priority = skb->priority; |
745 | tcb_desc->queue_index = UP2AC(skb->priority); |
746 | } else { |
747 | skb_frag->priority = WME_AC_BE; |
748 | tcb_desc->queue_index = WME_AC_BE; |
749 | } |
750 | skb_reserve(skb: skb_frag, len: ieee->tx_headroom); |
751 | |
752 | if (encrypt) { |
753 | if (ieee->hwsec_active) |
754 | tcb_desc->bHwSec = 1; |
755 | else |
756 | tcb_desc->bHwSec = 0; |
757 | skb_reserve(skb: skb_frag, |
758 | len: crypt->ops->extra_mpdu_prefix_len + |
759 | crypt->ops->extra_msdu_prefix_len); |
760 | } else { |
761 | tcb_desc->bHwSec = 0; |
762 | } |
763 | frag_hdr = skb_put_data(skb: skb_frag, data: &header, len: hdr_len); |
764 | |
765 | /* If this is not the last fragment, then add the |
766 | * MOREFRAGS bit to the frame control |
767 | */ |
768 | if (i != nr_frags - 1) { |
769 | frag_hdr->frame_control = cpu_to_le16(fc | |
770 | IEEE80211_FCTL_MOREFRAGS); |
771 | bytes = bytes_per_frag; |
772 | |
773 | } else { |
774 | /* The last fragment has the remaining length */ |
775 | bytes = bytes_last_frag; |
776 | } |
777 | if ((qos_activated) && (!bIsMulticast)) { |
778 | frag_hdr->seq_ctrl = |
779 | cpu_to_le16(rtllib_query_seqnum(ieee, skb_frag, |
780 | header.addr1)); |
781 | frag_hdr->seq_ctrl = |
782 | cpu_to_le16(le16_to_cpu(frag_hdr->seq_ctrl) << 4 | i); |
783 | } else { |
784 | frag_hdr->seq_ctrl = |
785 | cpu_to_le16(ieee->seq_ctrl[0] << 4 | i); |
786 | } |
787 | /* Put a SNAP header on the first fragment */ |
788 | if (i == 0) { |
789 | rtllib_put_snap(data: skb_put(skb: skb_frag, |
790 | SNAP_SIZE + |
791 | sizeof(u16)), h_proto: ether_type); |
792 | bytes -= SNAP_SIZE + sizeof(u16); |
793 | } |
794 | |
795 | skb_put_data(skb: skb_frag, data: skb->data, len: bytes); |
796 | |
797 | /* Advance the SKB... */ |
798 | skb_pull(skb, len: bytes); |
799 | |
800 | /* Encryption routine will move the header forward in |
801 | * order to insert the IV between the header and the |
802 | * payload |
803 | */ |
804 | if (encrypt) |
805 | rtllib_encrypt_fragment(ieee, frag: skb_frag, |
806 | hdr_len); |
807 | if (ieee->config & |
808 | (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) |
809 | skb_put(skb: skb_frag, len: 4); |
810 | } |
811 | |
812 | if ((qos_activated) && (!bIsMulticast)) { |
813 | if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF) |
814 | ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0; |
815 | else |
816 | ieee->seq_ctrl[UP2AC(skb->priority) + 1]++; |
817 | } else { |
818 | if (ieee->seq_ctrl[0] == 0xFFF) |
819 | ieee->seq_ctrl[0] = 0; |
820 | else |
821 | ieee->seq_ctrl[0]++; |
822 | } |
823 | |
824 | success: |
825 | if (txb) { |
826 | tcb_desc = (struct cb_desc *) |
827 | (txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); |
828 | tcb_desc->tx_enable_fw_calc_dur = 1; |
829 | tcb_desc->priority = skb->priority; |
830 | |
831 | if (ether_type == ETH_P_PAE) { |
832 | if (ieee->ht_info->iot_action & |
833 | HT_IOT_ACT_WA_IOT_Broadcom) { |
834 | tcb_desc->data_rate = |
835 | mgnt_query_tx_rate_exclude_cck_rates(ieee); |
836 | tcb_desc->tx_dis_rate_fallback = false; |
837 | } else { |
838 | tcb_desc->data_rate = ieee->basic_rate; |
839 | tcb_desc->tx_dis_rate_fallback = 1; |
840 | } |
841 | |
842 | tcb_desc->ratr_index = 7; |
843 | tcb_desc->tx_use_drv_assinged_rate = 1; |
844 | } else { |
845 | if (is_multicast_ether_addr(addr: header.addr1)) |
846 | tcb_desc->multicast = 1; |
847 | if (is_broadcast_ether_addr(addr: header.addr1)) |
848 | tcb_desc->bBroadcast = 1; |
849 | rtllib_txrate_selectmode(ieee, tcb_desc); |
850 | if (tcb_desc->multicast || tcb_desc->bBroadcast) |
851 | tcb_desc->data_rate = ieee->basic_rate; |
852 | else |
853 | tcb_desc->data_rate = rtllib_current_rate(ieee); |
854 | |
855 | if (bdhcp) { |
856 | if (ieee->ht_info->iot_action & |
857 | HT_IOT_ACT_WA_IOT_Broadcom) { |
858 | tcb_desc->data_rate = |
859 | mgnt_query_tx_rate_exclude_cck_rates(ieee); |
860 | tcb_desc->tx_dis_rate_fallback = false; |
861 | } else { |
862 | tcb_desc->data_rate = MGN_1M; |
863 | tcb_desc->tx_dis_rate_fallback = 1; |
864 | } |
865 | |
866 | tcb_desc->ratr_index = 7; |
867 | tcb_desc->tx_use_drv_assinged_rate = 1; |
868 | tcb_desc->bdhcp = 1; |
869 | } |
870 | |
871 | rtllib_query_ShortPreambleMode(ieee, tcb_desc); |
872 | rtllib_tx_query_agg_cap(ieee, skb: txb->fragments[0], |
873 | tcb_desc); |
874 | rtllib_query_HTCapShortGI(ieee, tcb_desc); |
875 | rtllib_query_BandwidthMode(ieee, tcb_desc); |
876 | rtllib_query_protectionmode(ieee, tcb_desc, |
877 | skb: txb->fragments[0]); |
878 | } |
879 | } |
880 | spin_unlock_irqrestore(lock: &ieee->lock, flags); |
881 | dev_kfree_skb_any(skb); |
882 | if (txb) { |
883 | if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) { |
884 | dev->stats.tx_packets++; |
885 | dev->stats.tx_bytes += le16_to_cpu(txb->payload_size); |
886 | rtllib_softmac_xmit(txb, ieee); |
887 | } else { |
888 | rtllib_txb_free(txb); |
889 | } |
890 | } |
891 | |
892 | return 0; |
893 | |
894 | failed: |
895 | spin_unlock_irqrestore(lock: &ieee->lock, flags); |
896 | netif_stop_queue(dev); |
897 | stats->tx_errors++; |
898 | return 1; |
899 | } |
900 | |
901 | netdev_tx_t rtllib_xmit(struct sk_buff *skb, struct net_device *dev) |
902 | { |
903 | memset(skb->cb, 0, sizeof(skb->cb)); |
904 | return rtllib_xmit_inter(skb, dev) ? NETDEV_TX_BUSY : NETDEV_TX_OK; |
905 | } |
906 | EXPORT_SYMBOL(rtllib_xmit); |
907 | |