mac80211: remove probe response temporary buffer allocation
authorJohannes Berg <johannes.berg@intel.com>
Thu, 29 Nov 2012 12:00:10 +0000 (13:00 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 30 Nov 2012 12:41:27 +0000 (13:41 +0100)
Instead of allocating a temporary buffer to build IEs
build them right into the SKB.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/ti/wl1251/main.c
drivers/net/wireless/ti/wlcore/cmd.c
include/net/mac80211.h
net/mac80211/tx.c
net/mac80211/util.c

index 2aa8a1a..8a61dbd 100644 (file)
@@ -1347,9 +1347,14 @@ static void hw_scan_work(struct work_struct *work)
                                                       hwsim->hw_scan_vif,
                                                       req->ssids[i].ssid,
                                                       req->ssids[i].ssid_len,
-                                                      req->ie, req->ie_len);
+                                                      req->ie_len);
                        if (!probe)
                                continue;
+
+                       if (req->ie_len)
+                               memcpy(skb_put(probe, req->ie_len), req->ie,
+                                      req->ie_len);
+
                        local_bh_disable();
                        mac80211_hwsim_tx_frame(hwsim->hw, probe,
                                                hwsim->tmp_chan);
index 441cbcc..f47e8b0 100644 (file)
@@ -896,11 +896,13 @@ static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
                goto out;
 
        skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
-                                    req->ie, req->ie_len);
+                                    req->ie_len);
        if (!skb) {
                ret = -ENOMEM;
                goto out;
        }
+       if (req->ie_len)
+               memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len);
 
        ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data,
                                      skb->len);
index eaef3f4..27f83f7 100644 (file)
@@ -1038,11 +1038,13 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
        u16 template_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
 
        skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len,
-                                    ie, ie_len);
+                                    ie_len);
        if (!skb) {
                ret = -ENOMEM;
                goto out;
        }
+       if (ie_len)
+               memcpy(skb_put(skb, ie_len), ie, ie_len);
 
        wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
 
index e806f1d..0472d80 100644 (file)
@@ -3144,8 +3144,7 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
  * @vif: &struct ieee80211_vif pointer from the add_interface callback.
  * @ssid: SSID buffer
  * @ssid_len: length of SSID
- * @ie: buffer containing all IEs except SSID for the template
- * @ie_len: length of the IE buffer
+ * @tailroom: tailroom to reserve at end of SKB for IEs
  *
  * Creates a Probe Request template which can, for example, be uploaded to
  * hardware.
@@ -3153,7 +3152,7 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
 struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
                                       struct ieee80211_vif *vif,
                                       const u8 *ssid, size_t ssid_len,
-                                      const u8 *ie, size_t ie_len);
+                                      size_t tailroom);
 
 /**
  * ieee80211_rts_get - RTS frame generation function
index d8ef341..ba1ac9d 100644 (file)
@@ -2620,7 +2620,7 @@ EXPORT_SYMBOL(ieee80211_nullfunc_get);
 struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
                                       struct ieee80211_vif *vif,
                                       const u8 *ssid, size_t ssid_len,
-                                      const u8 *ie, size_t ie_len)
+                                      size_t tailroom)
 {
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_local *local;
@@ -2634,7 +2634,7 @@ struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
        ie_ssid_len = 2 + ssid_len;
 
        skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*hdr) +
-                           ie_ssid_len + ie_len);
+                           ie_ssid_len + tailroom);
        if (!skb)
                return NULL;
 
@@ -2655,11 +2655,6 @@ struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
                memcpy(pos, ssid, ssid_len);
        pos += ssid_len;
 
-       if (ie) {
-               pos = skb_put(skb, ie_len);
-               memcpy(pos, ie, ie_len);
-       }
-
        return skb;
 }
 EXPORT_SYMBOL(ieee80211_probereq_get);
index f119b1b..41c9841 100644 (file)
@@ -1239,14 +1239,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sk_buff *skb;
        struct ieee80211_mgmt *mgmt;
-       size_t buf_len;
-       u8 *buf;
        u8 chan_no;
-
-       /* FIXME: come up with a proper value */
-       buf = kmalloc(200 + ie_len, GFP_KERNEL);
-       if (!buf)
-               return NULL;
+       int ies_len;
 
        /*
         * Do not send DS Channel parameter for directed probe requests
@@ -1258,15 +1252,16 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
        else
                chan_no = ieee80211_frequency_to_channel(chan->center_freq);
 
-       buf_len = ieee80211_build_preq_ies(local, buf, 200 + ie_len,
-                                          ie, ie_len, chan->band,
-                                          ratemask, chan_no);
-
        skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
-                                    ssid, ssid_len,
-                                    buf, buf_len);
+                                    ssid, ssid_len, 100 + ie_len);
        if (!skb)
-               goto out;
+               return NULL;
+
+       ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb),
+                                          skb_tailroom(skb),
+                                          ie, ie_len, chan->band,
+                                          ratemask, chan_no);
+       skb_put(skb, ies_len);
 
        if (dst) {
                mgmt = (struct ieee80211_mgmt *) skb->data;
@@ -1276,9 +1271,6 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
 
        IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
 
- out:
-       kfree(buf);
-
        return skb;
 }