diff options
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 204 |
1 files changed, 102 insertions, 102 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index ce06e791bf43..52ab85c4341b 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -52,9 +52,8 @@ static inline void ieee80211_include_sequence(struct ieee80211_sub_if_data *sdat | |||
52 | static void ieee80211_dump_frame(const char *ifname, const char *title, | 52 | static void ieee80211_dump_frame(const char *ifname, const char *title, |
53 | const struct sk_buff *skb) | 53 | const struct sk_buff *skb) |
54 | { | 54 | { |
55 | const struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 55 | const struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
56 | u16 fc; | 56 | unsigned int hdrlen; |
57 | int hdrlen; | ||
58 | DECLARE_MAC_BUF(mac); | 57 | DECLARE_MAC_BUF(mac); |
59 | 58 | ||
60 | printk(KERN_DEBUG "%s: %s (len=%d)", ifname, title, skb->len); | 59 | printk(KERN_DEBUG "%s: %s (len=%d)", ifname, title, skb->len); |
@@ -63,13 +62,12 @@ static void ieee80211_dump_frame(const char *ifname, const char *title, | |||
63 | return; | 62 | return; |
64 | } | 63 | } |
65 | 64 | ||
66 | fc = le16_to_cpu(hdr->frame_control); | 65 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
67 | hdrlen = ieee80211_get_hdrlen(fc); | ||
68 | if (hdrlen > skb->len) | 66 | if (hdrlen > skb->len) |
69 | hdrlen = skb->len; | 67 | hdrlen = skb->len; |
70 | if (hdrlen >= 4) | 68 | if (hdrlen >= 4) |
71 | printk(" FC=0x%04x DUR=0x%04x", | 69 | printk(" FC=0x%04x DUR=0x%04x", |
72 | fc, le16_to_cpu(hdr->duration_id)); | 70 | le16_to_cpu(hdr->frame_control), le16_to_cpu(hdr->duration_id)); |
73 | if (hdrlen >= 10) | 71 | if (hdrlen >= 10) |
74 | printk(" A1=%s", print_mac(mac, hdr->addr1)); | 72 | printk(" A1=%s", print_mac(mac, hdr->addr1)); |
75 | if (hdrlen >= 16) | 73 | if (hdrlen >= 16) |
@@ -87,8 +85,8 @@ static inline void ieee80211_dump_frame(const char *ifname, const char *title, | |||
87 | } | 85 | } |
88 | #endif /* CONFIG_MAC80211_LOWTX_FRAME_DUMP */ | 86 | #endif /* CONFIG_MAC80211_LOWTX_FRAME_DUMP */ |
89 | 87 | ||
90 | static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | 88 | static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, |
91 | int next_frag_len) | 89 | int next_frag_len) |
92 | { | 90 | { |
93 | int rate, mrate, erp, dur, i; | 91 | int rate, mrate, erp, dur, i; |
94 | struct ieee80211_rate *txrate; | 92 | struct ieee80211_rate *txrate; |
@@ -140,7 +138,7 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
140 | 138 | ||
141 | /* data/mgmt */ | 139 | /* data/mgmt */ |
142 | if (0 /* FIX: data/mgmt during CFP */) | 140 | if (0 /* FIX: data/mgmt during CFP */) |
143 | return 32768; | 141 | return cpu_to_le16(32768); |
144 | 142 | ||
145 | if (group_addr) /* Group address as the destination - no ACK */ | 143 | if (group_addr) /* Group address as the destination - no ACK */ |
146 | return 0; | 144 | return 0; |
@@ -210,7 +208,7 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
210 | tx->sdata->bss_conf.use_short_preamble); | 208 | tx->sdata->bss_conf.use_short_preamble); |
211 | } | 209 | } |
212 | 210 | ||
213 | return dur; | 211 | return cpu_to_le16(dur); |
214 | } | 212 | } |
215 | 213 | ||
216 | static int inline is_ieee80211_device(struct net_device *dev, | 214 | static int inline is_ieee80211_device(struct net_device *dev, |
@@ -281,7 +279,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | |||
281 | { | 279 | { |
282 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 280 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
283 | 281 | ||
284 | if (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)) >= 24) | 282 | if (ieee80211_hdrlen(hdr->frame_control) >= 24) |
285 | ieee80211_include_sequence(tx->sdata, hdr); | 283 | ieee80211_include_sequence(tx->sdata, hdr); |
286 | 284 | ||
287 | return TX_CONTINUE; | 285 | return TX_CONTINUE; |
@@ -542,9 +540,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
542 | static ieee80211_tx_result | 540 | static ieee80211_tx_result |
543 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | 541 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) |
544 | { | 542 | { |
545 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; | 543 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
546 | u16 fc = le16_to_cpu(hdr->frame_control); | ||
547 | u16 dur; | ||
548 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 544 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
549 | struct ieee80211_supported_band *sband; | 545 | struct ieee80211_supported_band *sband; |
550 | 546 | ||
@@ -595,21 +591,13 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
595 | /* Transmit data frames using short preambles if the driver supports | 591 | /* Transmit data frames using short preambles if the driver supports |
596 | * short preambles at the selected rate and short preambles are | 592 | * short preambles at the selected rate and short preambles are |
597 | * available on the network at the current point in time. */ | 593 | * available on the network at the current point in time. */ |
598 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | 594 | if (ieee80211_is_data(hdr->frame_control) && |
599 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) && | 595 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) && |
600 | tx->sdata->bss_conf.use_short_preamble && | 596 | tx->sdata->bss_conf.use_short_preamble && |
601 | (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) { | 597 | (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) { |
602 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | 598 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; |
603 | } | 599 | } |
604 | 600 | ||
605 | /* Setup duration field for the first fragment of the frame. Duration | ||
606 | * for remaining fragments will be updated when they are being sent | ||
607 | * to low-level driver in ieee80211_tx(). */ | ||
608 | dur = ieee80211_duration(tx, is_multicast_ether_addr(hdr->addr1), | ||
609 | (tx->flags & IEEE80211_TX_FRAGMENTED) ? | ||
610 | tx->extra_frag[0]->len : 0); | ||
611 | hdr->duration_id = cpu_to_le16(dur); | ||
612 | |||
613 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | 601 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || |
614 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) { | 602 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) { |
615 | struct ieee80211_rate *rate; | 603 | struct ieee80211_rate *rate; |
@@ -647,7 +635,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
647 | static ieee80211_tx_result | 635 | static ieee80211_tx_result |
648 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | 636 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) |
649 | { | 637 | { |
650 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; | 638 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
651 | size_t hdrlen, per_fragm, num_fragm, payload_len, left; | 639 | size_t hdrlen, per_fragm, num_fragm, payload_len, left; |
652 | struct sk_buff **frags, *first, *frag; | 640 | struct sk_buff **frags, *first, *frag; |
653 | int i; | 641 | int i; |
@@ -670,7 +658,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
670 | 658 | ||
671 | first = tx->skb; | 659 | first = tx->skb; |
672 | 660 | ||
673 | hdrlen = ieee80211_get_hdrlen(tx->fc); | 661 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
674 | payload_len = first->len - hdrlen; | 662 | payload_len = first->len - hdrlen; |
675 | per_fragm = frag_threshold - hdrlen - FCS_LEN; | 663 | per_fragm = frag_threshold - hdrlen - FCS_LEN; |
676 | num_fragm = DIV_ROUND_UP(payload_len, per_fragm); | 664 | num_fragm = DIV_ROUND_UP(payload_len, per_fragm); |
@@ -711,6 +699,8 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
711 | fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG)); | 699 | fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG)); |
712 | copylen = left > per_fragm ? per_fragm : left; | 700 | copylen = left > per_fragm ? per_fragm : left; |
713 | memcpy(skb_put(frag, copylen), pos, copylen); | 701 | memcpy(skb_put(frag, copylen), pos, copylen); |
702 | memcpy(frag->cb, first->cb, sizeof(frag->cb)); | ||
703 | skb_copy_queue_mapping(frag, first); | ||
714 | 704 | ||
715 | pos += copylen; | 705 | pos += copylen; |
716 | left -= copylen; | 706 | left -= copylen; |
@@ -755,6 +745,36 @@ ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) | |||
755 | } | 745 | } |
756 | 746 | ||
757 | static ieee80211_tx_result | 747 | static ieee80211_tx_result |
748 | ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) | ||
749 | { | ||
750 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | ||
751 | int next_len, i; | ||
752 | int group_addr = is_multicast_ether_addr(hdr->addr1); | ||
753 | |||
754 | if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) { | ||
755 | hdr->duration_id = ieee80211_duration(tx, group_addr, 0); | ||
756 | return TX_CONTINUE; | ||
757 | } | ||
758 | |||
759 | hdr->duration_id = ieee80211_duration(tx, group_addr, | ||
760 | tx->extra_frag[0]->len); | ||
761 | |||
762 | for (i = 0; i < tx->num_extra_frag; i++) { | ||
763 | if (i + 1 < tx->num_extra_frag) { | ||
764 | next_len = tx->extra_frag[i + 1]->len; | ||
765 | } else { | ||
766 | next_len = 0; | ||
767 | tx->rate_idx = tx->last_frag_rate_idx; | ||
768 | } | ||
769 | |||
770 | hdr = (struct ieee80211_hdr *)tx->extra_frag[i]->data; | ||
771 | hdr->duration_id = ieee80211_duration(tx, 0, next_len); | ||
772 | } | ||
773 | |||
774 | return TX_CONTINUE; | ||
775 | } | ||
776 | |||
777 | static ieee80211_tx_result | ||
758 | ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) | 778 | ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) |
759 | { | 779 | { |
760 | int i; | 780 | int i; |
@@ -788,6 +808,7 @@ static ieee80211_tx_handler ieee80211_tx_handlers[] = | |||
788 | ieee80211_tx_h_fragment, | 808 | ieee80211_tx_h_fragment, |
789 | /* handlers after fragment must be aware of tx info fragmentation! */ | 809 | /* handlers after fragment must be aware of tx info fragmentation! */ |
790 | ieee80211_tx_h_encrypt, | 810 | ieee80211_tx_h_encrypt, |
811 | ieee80211_tx_h_calculate_duration, | ||
791 | ieee80211_tx_h_stats, | 812 | ieee80211_tx_h_stats, |
792 | NULL | 813 | NULL |
793 | }; | 814 | }; |
@@ -1083,13 +1104,46 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | |||
1083 | return IEEE80211_TX_OK; | 1104 | return IEEE80211_TX_OK; |
1084 | } | 1105 | } |
1085 | 1106 | ||
1107 | /* | ||
1108 | * Invoke TX handlers, return 0 on success and non-zero if the | ||
1109 | * frame was dropped or queued. | ||
1110 | */ | ||
1111 | static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | ||
1112 | { | ||
1113 | struct ieee80211_local *local = tx->local; | ||
1114 | struct sk_buff *skb = tx->skb; | ||
1115 | ieee80211_tx_handler *handler; | ||
1116 | ieee80211_tx_result res = TX_DROP; | ||
1117 | int i; | ||
1118 | |||
1119 | for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) { | ||
1120 | res = (*handler)(tx); | ||
1121 | if (res != TX_CONTINUE) | ||
1122 | break; | ||
1123 | } | ||
1124 | |||
1125 | if (unlikely(res == TX_DROP)) { | ||
1126 | I802_DEBUG_INC(local->tx_handlers_drop); | ||
1127 | dev_kfree_skb(skb); | ||
1128 | for (i = 0; i < tx->num_extra_frag; i++) | ||
1129 | if (tx->extra_frag[i]) | ||
1130 | dev_kfree_skb(tx->extra_frag[i]); | ||
1131 | kfree(tx->extra_frag); | ||
1132 | return -1; | ||
1133 | } else if (unlikely(res == TX_QUEUED)) { | ||
1134 | I802_DEBUG_INC(local->tx_handlers_queued); | ||
1135 | return -1; | ||
1136 | } | ||
1137 | |||
1138 | return 0; | ||
1139 | } | ||
1140 | |||
1086 | static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb) | 1141 | static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb) |
1087 | { | 1142 | { |
1088 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1143 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1089 | struct sta_info *sta; | 1144 | struct sta_info *sta; |
1090 | ieee80211_tx_handler *handler; | ||
1091 | struct ieee80211_tx_data tx; | 1145 | struct ieee80211_tx_data tx; |
1092 | ieee80211_tx_result res = TX_DROP, res_prepare; | 1146 | ieee80211_tx_result res_prepare; |
1093 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1147 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1094 | int ret, i; | 1148 | int ret, i; |
1095 | u16 queue; | 1149 | u16 queue; |
@@ -1118,44 +1172,8 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb) | |||
1118 | tx.channel = local->hw.conf.channel; | 1172 | tx.channel = local->hw.conf.channel; |
1119 | info->band = tx.channel->band; | 1173 | info->band = tx.channel->band; |
1120 | 1174 | ||
1121 | for (handler = ieee80211_tx_handlers; *handler != NULL; | 1175 | if (invoke_tx_handlers(&tx)) |
1122 | handler++) { | 1176 | goto out; |
1123 | res = (*handler)(&tx); | ||
1124 | if (res != TX_CONTINUE) | ||
1125 | break; | ||
1126 | } | ||
1127 | |||
1128 | if (WARN_ON(tx.skb != skb)) | ||
1129 | goto drop; | ||
1130 | |||
1131 | if (unlikely(res == TX_DROP)) { | ||
1132 | I802_DEBUG_INC(local->tx_handlers_drop); | ||
1133 | goto drop; | ||
1134 | } | ||
1135 | |||
1136 | if (unlikely(res == TX_QUEUED)) { | ||
1137 | I802_DEBUG_INC(local->tx_handlers_queued); | ||
1138 | rcu_read_unlock(); | ||
1139 | return 0; | ||
1140 | } | ||
1141 | |||
1142 | if (tx.extra_frag) { | ||
1143 | for (i = 0; i < tx.num_extra_frag; i++) { | ||
1144 | int next_len, dur; | ||
1145 | struct ieee80211_hdr *hdr = | ||
1146 | (struct ieee80211_hdr *) | ||
1147 | tx.extra_frag[i]->data; | ||
1148 | |||
1149 | if (i + 1 < tx.num_extra_frag) { | ||
1150 | next_len = tx.extra_frag[i + 1]->len; | ||
1151 | } else { | ||
1152 | next_len = 0; | ||
1153 | tx.rate_idx = tx.last_frag_rate_idx; | ||
1154 | } | ||
1155 | dur = ieee80211_duration(&tx, 0, next_len); | ||
1156 | hdr->duration_id = cpu_to_le16(dur); | ||
1157 | } | ||
1158 | } | ||
1159 | 1177 | ||
1160 | retry: | 1178 | retry: |
1161 | ret = __ieee80211_tx(local, skb, &tx); | 1179 | ret = __ieee80211_tx(local, skb, &tx); |
@@ -1198,6 +1216,7 @@ retry: | |||
1198 | store->last_frag_rate_ctrl_probe = | 1216 | store->last_frag_rate_ctrl_probe = |
1199 | !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); | 1217 | !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); |
1200 | } | 1218 | } |
1219 | out: | ||
1201 | rcu_read_unlock(); | 1220 | rcu_read_unlock(); |
1202 | return 0; | 1221 | return 0; |
1203 | 1222 | ||
@@ -1379,7 +1398,8 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1379 | struct ieee80211_tx_info *info; | 1398 | struct ieee80211_tx_info *info; |
1380 | struct ieee80211_sub_if_data *sdata; | 1399 | struct ieee80211_sub_if_data *sdata; |
1381 | int ret = 1, head_need; | 1400 | int ret = 1, head_need; |
1382 | u16 ethertype, hdrlen, meshhdrlen = 0, fc; | 1401 | u16 ethertype, hdrlen, meshhdrlen = 0; |
1402 | __le16 fc; | ||
1383 | struct ieee80211_hdr hdr; | 1403 | struct ieee80211_hdr hdr; |
1384 | struct ieee80211s_hdr mesh_hdr; | 1404 | struct ieee80211s_hdr mesh_hdr; |
1385 | const u8 *encaps_data; | 1405 | const u8 *encaps_data; |
@@ -1402,12 +1422,12 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1402 | /* convert Ethernet header to proper 802.11 header (based on | 1422 | /* convert Ethernet header to proper 802.11 header (based on |
1403 | * operation mode) */ | 1423 | * operation mode) */ |
1404 | ethertype = (skb->data[12] << 8) | skb->data[13]; | 1424 | ethertype = (skb->data[12] << 8) | skb->data[13]; |
1405 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA; | 1425 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); |
1406 | 1426 | ||
1407 | switch (sdata->vif.type) { | 1427 | switch (sdata->vif.type) { |
1408 | case IEEE80211_IF_TYPE_AP: | 1428 | case IEEE80211_IF_TYPE_AP: |
1409 | case IEEE80211_IF_TYPE_VLAN: | 1429 | case IEEE80211_IF_TYPE_VLAN: |
1410 | fc |= IEEE80211_FCTL_FROMDS; | 1430 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); |
1411 | /* DA BSSID SA */ | 1431 | /* DA BSSID SA */ |
1412 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | 1432 | memcpy(hdr.addr1, skb->data, ETH_ALEN); |
1413 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); | 1433 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); |
@@ -1415,7 +1435,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1415 | hdrlen = 24; | 1435 | hdrlen = 24; |
1416 | break; | 1436 | break; |
1417 | case IEEE80211_IF_TYPE_WDS: | 1437 | case IEEE80211_IF_TYPE_WDS: |
1418 | fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS; | 1438 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1419 | /* RA TA DA SA */ | 1439 | /* RA TA DA SA */ |
1420 | memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN); | 1440 | memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN); |
1421 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); | 1441 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); |
@@ -1425,7 +1445,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1425 | break; | 1445 | break; |
1426 | #ifdef CONFIG_MAC80211_MESH | 1446 | #ifdef CONFIG_MAC80211_MESH |
1427 | case IEEE80211_IF_TYPE_MESH_POINT: | 1447 | case IEEE80211_IF_TYPE_MESH_POINT: |
1428 | fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS; | 1448 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1429 | /* RA TA DA SA */ | 1449 | /* RA TA DA SA */ |
1430 | if (is_multicast_ether_addr(skb->data)) | 1450 | if (is_multicast_ether_addr(skb->data)) |
1431 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | 1451 | memcpy(hdr.addr1, skb->data, ETH_ALEN); |
@@ -1455,7 +1475,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1455 | break; | 1475 | break; |
1456 | #endif | 1476 | #endif |
1457 | case IEEE80211_IF_TYPE_STA: | 1477 | case IEEE80211_IF_TYPE_STA: |
1458 | fc |= IEEE80211_FCTL_TODS; | 1478 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); |
1459 | /* BSSID SA DA */ | 1479 | /* BSSID SA DA */ |
1460 | memcpy(hdr.addr1, sdata->u.sta.bssid, ETH_ALEN); | 1480 | memcpy(hdr.addr1, sdata->u.sta.bssid, ETH_ALEN); |
1461 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); | 1481 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); |
@@ -1490,7 +1510,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1490 | /* receiver and we are QoS enabled, use a QoS type frame */ | 1510 | /* receiver and we are QoS enabled, use a QoS type frame */ |
1491 | if (sta_flags & WLAN_STA_WME && | 1511 | if (sta_flags & WLAN_STA_WME && |
1492 | ieee80211_num_regular_queues(&local->hw) >= 4) { | 1512 | ieee80211_num_regular_queues(&local->hw) >= 4) { |
1493 | fc |= IEEE80211_STYPE_QOS_DATA; | 1513 | fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); |
1494 | hdrlen += 2; | 1514 | hdrlen += 2; |
1495 | } | 1515 | } |
1496 | 1516 | ||
@@ -1518,7 +1538,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1518 | goto fail; | 1538 | goto fail; |
1519 | } | 1539 | } |
1520 | 1540 | ||
1521 | hdr.frame_control = cpu_to_le16(fc); | 1541 | hdr.frame_control = fc; |
1522 | hdr.duration_id = 0; | 1542 | hdr.duration_id = 0; |
1523 | hdr.seq_ctrl = 0; | 1543 | hdr.seq_ctrl = 0; |
1524 | 1544 | ||
@@ -1587,7 +1607,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1587 | h_pos += meshhdrlen; | 1607 | h_pos += meshhdrlen; |
1588 | } | 1608 | } |
1589 | 1609 | ||
1590 | if (fc & IEEE80211_STYPE_QOS_DATA) { | 1610 | if (ieee80211_is_data_qos(fc)) { |
1591 | __le16 *qos_control; | 1611 | __le16 *qos_control; |
1592 | 1612 | ||
1593 | qos_control = (__le16*) skb_push(skb, 2); | 1613 | qos_control = (__le16*) skb_push(skb, 2); |
@@ -1845,8 +1865,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1845 | mgmt = (struct ieee80211_mgmt *) | 1865 | mgmt = (struct ieee80211_mgmt *) |
1846 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | 1866 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); |
1847 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | 1867 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); |
1848 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | 1868 | mgmt->frame_control = |
1849 | IEEE80211_STYPE_BEACON); | 1869 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); |
1850 | memset(mgmt->da, 0xff, ETH_ALEN); | 1870 | memset(mgmt->da, 0xff, ETH_ALEN); |
1851 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); | 1871 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); |
1852 | /* BSSID is left zeroed, wildcard value */ | 1872 | /* BSSID is left zeroed, wildcard value */ |
@@ -1914,10 +1934,9 @@ void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
1914 | struct ieee80211_rts *rts) | 1934 | struct ieee80211_rts *rts) |
1915 | { | 1935 | { |
1916 | const struct ieee80211_hdr *hdr = frame; | 1936 | const struct ieee80211_hdr *hdr = frame; |
1917 | u16 fctl; | ||
1918 | 1937 | ||
1919 | fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS; | 1938 | rts->frame_control = |
1920 | rts->frame_control = cpu_to_le16(fctl); | 1939 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); |
1921 | rts->duration = ieee80211_rts_duration(hw, vif, frame_len, | 1940 | rts->duration = ieee80211_rts_duration(hw, vif, frame_len, |
1922 | frame_txctl); | 1941 | frame_txctl); |
1923 | memcpy(rts->ra, hdr->addr1, sizeof(rts->ra)); | 1942 | memcpy(rts->ra, hdr->addr1, sizeof(rts->ra)); |
@@ -1931,10 +1950,9 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
1931 | struct ieee80211_cts *cts) | 1950 | struct ieee80211_cts *cts) |
1932 | { | 1951 | { |
1933 | const struct ieee80211_hdr *hdr = frame; | 1952 | const struct ieee80211_hdr *hdr = frame; |
1934 | u16 fctl; | ||
1935 | 1953 | ||
1936 | fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS; | 1954 | cts->frame_control = |
1937 | cts->frame_control = cpu_to_le16(fctl); | 1955 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); |
1938 | cts->duration = ieee80211_ctstoself_duration(hw, vif, | 1956 | cts->duration = ieee80211_ctstoself_duration(hw, vif, |
1939 | frame_len, frame_txctl); | 1957 | frame_len, frame_txctl); |
1940 | memcpy(cts->ra, hdr->addr1, sizeof(cts->ra)); | 1958 | memcpy(cts->ra, hdr->addr1, sizeof(cts->ra)); |
@@ -1948,9 +1966,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
1948 | struct ieee80211_local *local = hw_to_local(hw); | 1966 | struct ieee80211_local *local = hw_to_local(hw); |
1949 | struct sk_buff *skb = NULL; | 1967 | struct sk_buff *skb = NULL; |
1950 | struct sta_info *sta; | 1968 | struct sta_info *sta; |
1951 | ieee80211_tx_handler *handler; | ||
1952 | struct ieee80211_tx_data tx; | 1969 | struct ieee80211_tx_data tx; |
1953 | ieee80211_tx_result res = TX_DROP; | ||
1954 | struct net_device *bdev; | 1970 | struct net_device *bdev; |
1955 | struct ieee80211_sub_if_data *sdata; | 1971 | struct ieee80211_sub_if_data *sdata; |
1956 | struct ieee80211_if_ap *bss = NULL; | 1972 | struct ieee80211_if_ap *bss = NULL; |
@@ -2001,25 +2017,9 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2001 | tx.channel = local->hw.conf.channel; | 2017 | tx.channel = local->hw.conf.channel; |
2002 | info->band = tx.channel->band; | 2018 | info->band = tx.channel->band; |
2003 | 2019 | ||
2004 | for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) { | 2020 | if (invoke_tx_handlers(&tx)) |
2005 | res = (*handler)(&tx); | ||
2006 | if (res == TX_DROP || res == TX_QUEUED) | ||
2007 | break; | ||
2008 | } | ||
2009 | |||
2010 | if (WARN_ON(tx.skb != skb)) | ||
2011 | res = TX_DROP; | ||
2012 | |||
2013 | if (res == TX_DROP) { | ||
2014 | I802_DEBUG_INC(local->tx_handlers_drop); | ||
2015 | dev_kfree_skb(skb); | ||
2016 | skb = NULL; | 2021 | skb = NULL; |
2017 | } else if (res == TX_QUEUED) { | 2022 | out: |
2018 | I802_DEBUG_INC(local->tx_handlers_queued); | ||
2019 | skb = NULL; | ||
2020 | } | ||
2021 | |||
2022 | out: | ||
2023 | rcu_read_unlock(); | 2023 | rcu_read_unlock(); |
2024 | 2024 | ||
2025 | return skb; | 2025 | return skb; |