diff options
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 71 |
1 files changed, 29 insertions, 42 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index acf712ffb5e6..3b807bcb8fc9 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -55,7 +55,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, | |||
55 | if (WARN_ON_ONCE(info->control.rates[0].idx < 0)) | 55 | if (WARN_ON_ONCE(info->control.rates[0].idx < 0)) |
56 | return 0; | 56 | return 0; |
57 | 57 | ||
58 | sband = local->hw.wiphy->bands[tx->channel->band]; | 58 | sband = local->hw.wiphy->bands[info->band]; |
59 | txrate = &sband->bitrates[info->control.rates[0].idx]; | 59 | txrate = &sband->bitrates[info->control.rates[0].idx]; |
60 | 60 | ||
61 | erp = txrate->flags & IEEE80211_RATE_ERP_G; | 61 | erp = txrate->flags & IEEE80211_RATE_ERP_G; |
@@ -615,7 +615,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
615 | 615 | ||
616 | memset(&txrc, 0, sizeof(txrc)); | 616 | memset(&txrc, 0, sizeof(txrc)); |
617 | 617 | ||
618 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 618 | sband = tx->local->hw.wiphy->bands[info->band]; |
619 | 619 | ||
620 | len = min_t(u32, tx->skb->len + FCS_LEN, | 620 | len = min_t(u32, tx->skb->len + FCS_LEN, |
621 | tx->local->hw.wiphy->frag_threshold); | 621 | tx->local->hw.wiphy->frag_threshold); |
@@ -626,13 +626,13 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
626 | txrc.bss_conf = &tx->sdata->vif.bss_conf; | 626 | txrc.bss_conf = &tx->sdata->vif.bss_conf; |
627 | txrc.skb = tx->skb; | 627 | txrc.skb = tx->skb; |
628 | txrc.reported_rate.idx = -1; | 628 | txrc.reported_rate.idx = -1; |
629 | txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[tx->channel->band]; | 629 | txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[info->band]; |
630 | if (txrc.rate_idx_mask == (1 << sband->n_bitrates) - 1) | 630 | if (txrc.rate_idx_mask == (1 << sband->n_bitrates) - 1) |
631 | txrc.max_rate_idx = -1; | 631 | txrc.max_rate_idx = -1; |
632 | else | 632 | else |
633 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; | 633 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; |
634 | memcpy(txrc.rate_idx_mcs_mask, | 634 | memcpy(txrc.rate_idx_mcs_mask, |
635 | tx->sdata->rc_rateidx_mcs_mask[tx->channel->band], | 635 | tx->sdata->rc_rateidx_mcs_mask[info->band], |
636 | sizeof(txrc.rate_idx_mcs_mask)); | 636 | sizeof(txrc.rate_idx_mcs_mask)); |
637 | txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP || | 637 | txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP || |
638 | tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT || | 638 | tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT || |
@@ -667,7 +667,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
667 | "scanning and associated. Target station: " | 667 | "scanning and associated. Target station: " |
668 | "%pM on %d GHz band\n", | 668 | "%pM on %d GHz band\n", |
669 | tx->sdata->name, hdr->addr1, | 669 | tx->sdata->name, hdr->addr1, |
670 | tx->channel->band ? 5 : 2)) | 670 | info->band ? 5 : 2)) |
671 | return TX_DROP; | 671 | return TX_DROP; |
672 | 672 | ||
673 | /* | 673 | /* |
@@ -1131,7 +1131,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1131 | tx->skb = skb; | 1131 | tx->skb = skb; |
1132 | tx->local = local; | 1132 | tx->local = local; |
1133 | tx->sdata = sdata; | 1133 | tx->sdata = sdata; |
1134 | tx->channel = local->hw.conf.channel; | ||
1135 | __skb_queue_head_init(&tx->skbs); | 1134 | __skb_queue_head_init(&tx->skbs); |
1136 | 1135 | ||
1137 | /* | 1136 | /* |
@@ -1204,6 +1203,7 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local, | |||
1204 | struct sk_buff_head *skbs, | 1203 | struct sk_buff_head *skbs, |
1205 | bool txpending) | 1204 | bool txpending) |
1206 | { | 1205 | { |
1206 | struct ieee80211_tx_control control; | ||
1207 | struct sk_buff *skb, *tmp; | 1207 | struct sk_buff *skb, *tmp; |
1208 | unsigned long flags; | 1208 | unsigned long flags; |
1209 | 1209 | ||
@@ -1240,10 +1240,10 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local, | |||
1240 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 1240 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
1241 | 1241 | ||
1242 | info->control.vif = vif; | 1242 | info->control.vif = vif; |
1243 | info->control.sta = sta; | 1243 | control.sta = sta; |
1244 | 1244 | ||
1245 | __skb_unlink(skb, skbs); | 1245 | __skb_unlink(skb, skbs); |
1246 | drv_tx(local, skb); | 1246 | drv_tx(local, &control, skb); |
1247 | } | 1247 | } |
1248 | 1248 | ||
1249 | return true; | 1249 | return true; |
@@ -1399,8 +1399,7 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, | |||
1399 | goto out; | 1399 | goto out; |
1400 | } | 1400 | } |
1401 | 1401 | ||
1402 | tx.channel = local->hw.conf.channel; | 1402 | info->band = local->hw.conf.channel->band; |
1403 | info->band = tx.channel->band; | ||
1404 | 1403 | ||
1405 | /* set up hw_queue value early */ | 1404 | /* set up hw_queue value early */ |
1406 | if (!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) || | 1405 | if (!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) || |
@@ -1720,7 +1719,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1720 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1719 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1721 | struct ieee80211_local *local = sdata->local; | 1720 | struct ieee80211_local *local = sdata->local; |
1722 | struct ieee80211_tx_info *info; | 1721 | struct ieee80211_tx_info *info; |
1723 | int ret = NETDEV_TX_BUSY, head_need; | 1722 | int head_need; |
1724 | u16 ethertype, hdrlen, meshhdrlen = 0; | 1723 | u16 ethertype, hdrlen, meshhdrlen = 0; |
1725 | __le16 fc; | 1724 | __le16 fc; |
1726 | struct ieee80211_hdr hdr; | 1725 | struct ieee80211_hdr hdr; |
@@ -1736,10 +1735,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1736 | u32 info_flags = 0; | 1735 | u32 info_flags = 0; |
1737 | u16 info_id = 0; | 1736 | u16 info_id = 0; |
1738 | 1737 | ||
1739 | if (unlikely(skb->len < ETH_HLEN)) { | 1738 | if (unlikely(skb->len < ETH_HLEN)) |
1740 | ret = NETDEV_TX_OK; | ||
1741 | goto fail; | 1739 | goto fail; |
1742 | } | ||
1743 | 1740 | ||
1744 | /* convert Ethernet header to proper 802.11 header (based on | 1741 | /* convert Ethernet header to proper 802.11 header (based on |
1745 | * operation mode) */ | 1742 | * operation mode) */ |
@@ -1787,7 +1784,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1787 | if (!sdata->u.mesh.mshcfg.dot11MeshTTL) { | 1784 | if (!sdata->u.mesh.mshcfg.dot11MeshTTL) { |
1788 | /* Do not send frames with mesh_ttl == 0 */ | 1785 | /* Do not send frames with mesh_ttl == 0 */ |
1789 | sdata->u.mesh.mshstats.dropped_frames_ttl++; | 1786 | sdata->u.mesh.mshstats.dropped_frames_ttl++; |
1790 | ret = NETDEV_TX_OK; | ||
1791 | goto fail; | 1787 | goto fail; |
1792 | } | 1788 | } |
1793 | rcu_read_lock(); | 1789 | rcu_read_lock(); |
@@ -1880,10 +1876,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1880 | 1876 | ||
1881 | if (tdls_direct) { | 1877 | if (tdls_direct) { |
1882 | /* link during setup - throw out frames to peer */ | 1878 | /* link during setup - throw out frames to peer */ |
1883 | if (!tdls_auth) { | 1879 | if (!tdls_auth) |
1884 | ret = NETDEV_TX_OK; | ||
1885 | goto fail; | 1880 | goto fail; |
1886 | } | ||
1887 | 1881 | ||
1888 | /* DA SA BSSID */ | 1882 | /* DA SA BSSID */ |
1889 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | 1883 | memcpy(hdr.addr1, skb->data, ETH_ALEN); |
@@ -1917,7 +1911,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1917 | hdrlen = 24; | 1911 | hdrlen = 24; |
1918 | break; | 1912 | break; |
1919 | default: | 1913 | default: |
1920 | ret = NETDEV_TX_OK; | ||
1921 | goto fail; | 1914 | goto fail; |
1922 | } | 1915 | } |
1923 | 1916 | ||
@@ -1962,7 +1955,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1962 | 1955 | ||
1963 | I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); | 1956 | I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); |
1964 | 1957 | ||
1965 | ret = NETDEV_TX_OK; | ||
1966 | goto fail; | 1958 | goto fail; |
1967 | } | 1959 | } |
1968 | 1960 | ||
@@ -2017,10 +2009,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2017 | skb = skb_clone(skb, GFP_ATOMIC); | 2009 | skb = skb_clone(skb, GFP_ATOMIC); |
2018 | kfree_skb(tmp_skb); | 2010 | kfree_skb(tmp_skb); |
2019 | 2011 | ||
2020 | if (!skb) { | 2012 | if (!skb) |
2021 | ret = NETDEV_TX_OK; | ||
2022 | goto fail; | 2013 | goto fail; |
2023 | } | ||
2024 | } | 2014 | } |
2025 | 2015 | ||
2026 | hdr.frame_control = fc; | 2016 | hdr.frame_control = fc; |
@@ -2123,10 +2113,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2123 | return NETDEV_TX_OK; | 2113 | return NETDEV_TX_OK; |
2124 | 2114 | ||
2125 | fail: | 2115 | fail: |
2126 | if (ret == NETDEV_TX_OK) | 2116 | dev_kfree_skb(skb); |
2127 | dev_kfree_skb(skb); | 2117 | return NETDEV_TX_OK; |
2128 | |||
2129 | return ret; | ||
2130 | } | 2118 | } |
2131 | 2119 | ||
2132 | 2120 | ||
@@ -2301,12 +2289,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2301 | struct ieee80211_sub_if_data *sdata = NULL; | 2289 | struct ieee80211_sub_if_data *sdata = NULL; |
2302 | struct ieee80211_if_ap *ap = NULL; | 2290 | struct ieee80211_if_ap *ap = NULL; |
2303 | struct beacon_data *beacon; | 2291 | struct beacon_data *beacon; |
2304 | struct ieee80211_supported_band *sband; | 2292 | enum ieee80211_band band = local->oper_channel->band; |
2305 | enum ieee80211_band band = local->hw.conf.channel->band; | ||
2306 | struct ieee80211_tx_rate_control txrc; | 2293 | struct ieee80211_tx_rate_control txrc; |
2307 | 2294 | ||
2308 | sband = local->hw.wiphy->bands[band]; | ||
2309 | |||
2310 | rcu_read_lock(); | 2295 | rcu_read_lock(); |
2311 | 2296 | ||
2312 | sdata = vif_to_sdata(vif); | 2297 | sdata = vif_to_sdata(vif); |
@@ -2416,7 +2401,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2416 | memset(mgmt, 0, hdr_len); | 2401 | memset(mgmt, 0, hdr_len); |
2417 | mgmt->frame_control = | 2402 | mgmt->frame_control = |
2418 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); | 2403 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); |
2419 | memset(mgmt->da, 0xff, ETH_ALEN); | 2404 | eth_broadcast_addr(mgmt->da); |
2420 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | 2405 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
2421 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); | 2406 | memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); |
2422 | mgmt->u.beacon.beacon_int = | 2407 | mgmt->u.beacon.beacon_int = |
@@ -2428,9 +2413,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2428 | *pos++ = WLAN_EID_SSID; | 2413 | *pos++ = WLAN_EID_SSID; |
2429 | *pos++ = 0x0; | 2414 | *pos++ = 0x0; |
2430 | 2415 | ||
2431 | if (ieee80211_add_srates_ie(sdata, skb, true) || | 2416 | if (ieee80211_add_srates_ie(sdata, skb, true, band) || |
2432 | mesh_add_ds_params_ie(skb, sdata) || | 2417 | mesh_add_ds_params_ie(skb, sdata) || |
2433 | ieee80211_add_ext_srates_ie(sdata, skb, true) || | 2418 | ieee80211_add_ext_srates_ie(sdata, skb, true, band) || |
2434 | mesh_add_rsn_ie(skb, sdata) || | 2419 | mesh_add_rsn_ie(skb, sdata) || |
2435 | mesh_add_ht_cap_ie(skb, sdata) || | 2420 | mesh_add_ht_cap_ie(skb, sdata) || |
2436 | mesh_add_ht_oper_ie(skb, sdata) || | 2421 | mesh_add_ht_oper_ie(skb, sdata) || |
@@ -2453,12 +2438,12 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2453 | 2438 | ||
2454 | memset(&txrc, 0, sizeof(txrc)); | 2439 | memset(&txrc, 0, sizeof(txrc)); |
2455 | txrc.hw = hw; | 2440 | txrc.hw = hw; |
2456 | txrc.sband = sband; | 2441 | txrc.sband = local->hw.wiphy->bands[band]; |
2457 | txrc.bss_conf = &sdata->vif.bss_conf; | 2442 | txrc.bss_conf = &sdata->vif.bss_conf; |
2458 | txrc.skb = skb; | 2443 | txrc.skb = skb; |
2459 | txrc.reported_rate.idx = -1; | 2444 | txrc.reported_rate.idx = -1; |
2460 | txrc.rate_idx_mask = sdata->rc_rateidx_mask[band]; | 2445 | txrc.rate_idx_mask = sdata->rc_rateidx_mask[band]; |
2461 | if (txrc.rate_idx_mask == (1 << sband->n_bitrates) - 1) | 2446 | if (txrc.rate_idx_mask == (1 << txrc.sband->n_bitrates) - 1) |
2462 | txrc.max_rate_idx = -1; | 2447 | txrc.max_rate_idx = -1; |
2463 | else | 2448 | else |
2464 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; | 2449 | txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; |
@@ -2482,7 +2467,8 @@ struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw, | |||
2482 | struct ieee80211_vif *vif) | 2467 | struct ieee80211_vif *vif) |
2483 | { | 2468 | { |
2484 | struct ieee80211_if_ap *ap = NULL; | 2469 | struct ieee80211_if_ap *ap = NULL; |
2485 | struct sk_buff *presp = NULL, *skb = NULL; | 2470 | struct sk_buff *skb = NULL; |
2471 | struct probe_resp *presp = NULL; | ||
2486 | struct ieee80211_hdr *hdr; | 2472 | struct ieee80211_hdr *hdr; |
2487 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 2473 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
2488 | 2474 | ||
@@ -2496,10 +2482,12 @@ struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw, | |||
2496 | if (!presp) | 2482 | if (!presp) |
2497 | goto out; | 2483 | goto out; |
2498 | 2484 | ||
2499 | skb = skb_copy(presp, GFP_ATOMIC); | 2485 | skb = dev_alloc_skb(presp->len); |
2500 | if (!skb) | 2486 | if (!skb) |
2501 | goto out; | 2487 | goto out; |
2502 | 2488 | ||
2489 | memcpy(skb_put(skb, presp->len), presp->data, presp->len); | ||
2490 | |||
2503 | hdr = (struct ieee80211_hdr *) skb->data; | 2491 | hdr = (struct ieee80211_hdr *) skb->data; |
2504 | memset(hdr->addr1, 0, sizeof(hdr->addr1)); | 2492 | memset(hdr->addr1, 0, sizeof(hdr->addr1)); |
2505 | 2493 | ||
@@ -2610,9 +2598,9 @@ struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw, | |||
2610 | memset(hdr, 0, sizeof(*hdr)); | 2598 | memset(hdr, 0, sizeof(*hdr)); |
2611 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 2599 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
2612 | IEEE80211_STYPE_PROBE_REQ); | 2600 | IEEE80211_STYPE_PROBE_REQ); |
2613 | memset(hdr->addr1, 0xff, ETH_ALEN); | 2601 | eth_broadcast_addr(hdr->addr1); |
2614 | memcpy(hdr->addr2, vif->addr, ETH_ALEN); | 2602 | memcpy(hdr->addr2, vif->addr, ETH_ALEN); |
2615 | memset(hdr->addr3, 0xff, ETH_ALEN); | 2603 | eth_broadcast_addr(hdr->addr3); |
2616 | 2604 | ||
2617 | pos = skb_put(skb, ie_ssid_len); | 2605 | pos = skb_put(skb, ie_ssid_len); |
2618 | *pos++ = WLAN_EID_SSID; | 2606 | *pos++ = WLAN_EID_SSID; |
@@ -2709,8 +2697,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2709 | info = IEEE80211_SKB_CB(skb); | 2697 | info = IEEE80211_SKB_CB(skb); |
2710 | 2698 | ||
2711 | tx.flags |= IEEE80211_TX_PS_BUFFERED; | 2699 | tx.flags |= IEEE80211_TX_PS_BUFFERED; |
2712 | tx.channel = local->hw.conf.channel; | 2700 | info->band = local->oper_channel->band; |
2713 | info->band = tx.channel->band; | ||
2714 | 2701 | ||
2715 | if (invoke_tx_handlers(&tx)) | 2702 | if (invoke_tx_handlers(&tx)) |
2716 | skb = NULL; | 2703 | skb = NULL; |