Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
[linux-drm-fsl-dcu.git] / net / mac80211 / tx.c
index c5e8c9c31f7687d9922d0011ea1b31e8244ea8d2..29eb4e678235eff5fcfe48d9304f0db5b84259f1 100644 (file)
@@ -55,7 +55,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
        if (WARN_ON_ONCE(info->control.rates[0].idx < 0))
                return 0;
 
-       sband = local->hw.wiphy->bands[tx->channel->band];
+       sband = local->hw.wiphy->bands[info->band];
        txrate = &sband->bitrates[info->control.rates[0].idx];
 
        erp = txrate->flags & IEEE80211_RATE_ERP_G;
@@ -615,7 +615,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
 
        memset(&txrc, 0, sizeof(txrc));
 
-       sband = tx->local->hw.wiphy->bands[tx->channel->band];
+       sband = tx->local->hw.wiphy->bands[info->band];
 
        len = min_t(u32, tx->skb->len + FCS_LEN,
                         tx->local->hw.wiphy->frag_threshold);
@@ -626,13 +626,13 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
        txrc.bss_conf = &tx->sdata->vif.bss_conf;
        txrc.skb = tx->skb;
        txrc.reported_rate.idx = -1;
-       txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[tx->channel->band];
+       txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[info->band];
        if (txrc.rate_idx_mask == (1 << sband->n_bitrates) - 1)
                txrc.max_rate_idx = -1;
        else
                txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
        memcpy(txrc.rate_idx_mcs_mask,
-              tx->sdata->rc_rateidx_mcs_mask[tx->channel->band],
+              tx->sdata->rc_rateidx_mcs_mask[info->band],
               sizeof(txrc.rate_idx_mcs_mask));
        txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
                    tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
@@ -667,7 +667,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
                 "scanning and associated. Target station: "
                 "%pM on %d GHz band\n",
                 tx->sdata->name, hdr->addr1,
-                tx->channel->band ? 5 : 2))
+                info->band ? 5 : 2))
                return TX_DROP;
 
        /*
@@ -1131,7 +1131,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
        tx->skb = skb;
        tx->local = local;
        tx->sdata = sdata;
-       tx->channel = local->hw.conf.channel;
        __skb_queue_head_init(&tx->skbs);
 
        /*
@@ -1204,6 +1203,7 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
                               struct sk_buff_head *skbs,
                               bool txpending)
 {
+       struct ieee80211_tx_control control;
        struct sk_buff *skb, *tmp;
        unsigned long flags;
 
@@ -1240,10 +1240,10 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
                spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 
                info->control.vif = vif;
-               info->control.sta = sta;
+               control.sta = sta;
 
                __skb_unlink(skb, skbs);
-               drv_tx(local, skb);
+               drv_tx(local, &control, skb);
        }
 
        return true;
@@ -1399,8 +1399,7 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
                goto out;
        }
 
-       tx.channel = local->hw.conf.channel;
-       info->band = tx.channel->band;
+       info->band = local->hw.conf.channel->band;
 
        /* set up hw_queue value early */
        if (!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) ||
@@ -1720,7 +1719,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_tx_info *info;
-       int ret = NETDEV_TX_BUSY, head_need;
+       int head_need;
        u16 ethertype, hdrlen,  meshhdrlen = 0;
        __le16 fc;
        struct ieee80211_hdr hdr;
@@ -1736,10 +1735,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
        u32 info_flags = 0;
        u16 info_id = 0;
 
-       if (unlikely(skb->len < ETH_HLEN)) {
-               ret = NETDEV_TX_OK;
+       if (unlikely(skb->len < ETH_HLEN))
                goto fail;
-       }
 
        /* convert Ethernet header to proper 802.11 header (based on
         * operation mode) */
@@ -1787,7 +1784,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                if (!sdata->u.mesh.mshcfg.dot11MeshTTL) {
                        /* Do not send frames with mesh_ttl == 0 */
                        sdata->u.mesh.mshstats.dropped_frames_ttl++;
-                       ret = NETDEV_TX_OK;
                        goto fail;
                }
                rcu_read_lock();
@@ -1874,10 +1870,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 
                if (tdls_direct) {
                        /* link during setup - throw out frames to peer */
-                       if (!tdls_auth) {
-                               ret = NETDEV_TX_OK;
+                       if (!tdls_auth)
                                goto fail;
-                       }
 
                        /* DA SA BSSID */
                        memcpy(hdr.addr1, skb->data, ETH_ALEN);
@@ -1911,7 +1905,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                hdrlen = 24;
                break;
        default:
-               ret = NETDEV_TX_OK;
                goto fail;
        }
 
@@ -1956,7 +1949,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 
                I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
 
-               ret = NETDEV_TX_OK;
                goto fail;
        }
 
@@ -2011,10 +2003,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                skb = skb_clone(skb, GFP_ATOMIC);
                kfree_skb(tmp_skb);
 
-               if (!skb) {
-                       ret = NETDEV_TX_OK;
+               if (!skb)
                        goto fail;
-               }
        }
 
        hdr.frame_control = fc;
@@ -2117,10 +2107,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
        return NETDEV_TX_OK;
 
  fail:
-       if (ret == NETDEV_TX_OK)
-               dev_kfree_skb(skb);
-
-       return ret;
+       dev_kfree_skb(skb);
+       return NETDEV_TX_OK;
 }
 
 
@@ -2295,12 +2283,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
        struct ieee80211_sub_if_data *sdata = NULL;
        struct ieee80211_if_ap *ap = NULL;
        struct beacon_data *beacon;
-       struct ieee80211_supported_band *sband;
-       enum ieee80211_band band = local->hw.conf.channel->band;
+       enum ieee80211_band band = local->oper_channel->band;
        struct ieee80211_tx_rate_control txrc;
 
-       sband = local->hw.wiphy->bands[band];
-
        rcu_read_lock();
 
        sdata = vif_to_sdata(vif);
@@ -2410,7 +2395,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
                memset(mgmt, 0, hdr_len);
                mgmt->frame_control =
                    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
-               memset(mgmt->da, 0xff, ETH_ALEN);
+               eth_broadcast_addr(mgmt->da);
                memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
                memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
                mgmt->u.beacon.beacon_int =
@@ -2422,9 +2407,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
                *pos++ = WLAN_EID_SSID;
                *pos++ = 0x0;
 
-               if (ieee80211_add_srates_ie(sdata, skb, true) ||
+               if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
                    mesh_add_ds_params_ie(skb, sdata) ||
-                   ieee80211_add_ext_srates_ie(sdata, skb, true) ||
+                   ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
                    mesh_add_rsn_ie(skb, sdata) ||
                    mesh_add_ht_cap_ie(skb, sdata) ||
                    mesh_add_ht_oper_ie(skb, sdata) ||
@@ -2447,12 +2432,12 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
 
        memset(&txrc, 0, sizeof(txrc));
        txrc.hw = hw;
-       txrc.sband = sband;
+       txrc.sband = local->hw.wiphy->bands[band];
        txrc.bss_conf = &sdata->vif.bss_conf;
        txrc.skb = skb;
        txrc.reported_rate.idx = -1;
        txrc.rate_idx_mask = sdata->rc_rateidx_mask[band];
-       if (txrc.rate_idx_mask == (1 << sband->n_bitrates) - 1)
+       if (txrc.rate_idx_mask == (1 << txrc.sband->n_bitrates) - 1)
                txrc.max_rate_idx = -1;
        else
                txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
@@ -2476,7 +2461,8 @@ struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,
                                        struct ieee80211_vif *vif)
 {
        struct ieee80211_if_ap *ap = NULL;
-       struct sk_buff *presp = NULL, *skb = NULL;
+       struct sk_buff *skb = NULL;
+       struct probe_resp *presp = NULL;
        struct ieee80211_hdr *hdr;
        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
 
@@ -2490,10 +2476,12 @@ struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,
        if (!presp)
                goto out;
 
-       skb = skb_copy(presp, GFP_ATOMIC);
+       skb = dev_alloc_skb(presp->len);
        if (!skb)
                goto out;
 
+       memcpy(skb_put(skb, presp->len), presp->data, presp->len);
+
        hdr = (struct ieee80211_hdr *) skb->data;
        memset(hdr->addr1, 0, sizeof(hdr->addr1));
 
@@ -2604,9 +2592,9 @@ struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
        memset(hdr, 0, sizeof(*hdr));
        hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                                         IEEE80211_STYPE_PROBE_REQ);
-       memset(hdr->addr1, 0xff, ETH_ALEN);
+       eth_broadcast_addr(hdr->addr1);
        memcpy(hdr->addr2, vif->addr, ETH_ALEN);
-       memset(hdr->addr3, 0xff, ETH_ALEN);
+       eth_broadcast_addr(hdr->addr3);
 
        pos = skb_put(skb, ie_ssid_len);
        *pos++ = WLAN_EID_SSID;
@@ -2703,8 +2691,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
        info = IEEE80211_SKB_CB(skb);
 
        tx.flags |= IEEE80211_TX_PS_BUFFERED;
-       tx.channel = local->hw.conf.channel;
-       info->band = tx.channel->band;
+       info->band = local->oper_channel->band;
 
        if (invoke_tx_handlers(&tx))
                skb = NULL;