Allow generic element to be set independently for each interface.

Signed-off-by: Jiri Benc <[EMAIL PROTECTED]>

---

 include/net/d80211.h         |   12 +++++++-----
 net/d80211/ieee80211.c       |    6 ++++--
 net/d80211/ieee80211_i.h     |    2 ++
 net/d80211/ieee80211_iface.c |    1 +
 net/d80211/ieee80211_ioctl.c |   19 ++++++++++---------
 5 files changed, 24 insertions(+), 16 deletions(-)

330ee7fb14673a5c69000a2c31c83830d7c6c456
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 065b34c..4bdbdbe 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -249,11 +249,6 @@ struct ieee80211_conf {
        int short_slot_time:1;          /* use IEEE 802.11g Short Slot Time */
         int ssid_hidden:1;             /* do not broadcast the ssid */
 
-        /* these fields are used by low level drivers for hardware
-         * that generate beacons independently */
-       u8 *generic_elem;
-       size_t generic_elem_len;
-
         u8 power_level;                        /* transmit power limit for 
current
                                         * regulatory domain; in dBm */
         u8 antenna_max;                        /* maximum antenna gain */
@@ -347,6 +342,11 @@ struct ieee80211_if_init_conf {
  *     config_interface() callback (so copy the value somewhere if you need
  *     it).
  * @ssid_len: length of the @ssid field.
+ * @generic_elem: used (together with @generic_elem_len) by drivers for
+ *     hardware that generate beacons independently. The pointer is valid
+ *     only during config_interface() callback (so copy the value somewhere
+ *     if you need it).
+ * @generic_elem_len: length of the generic element.
  *
  * This structure is passed to config_interface() callback of
  * &struct ieee80211_hw.
@@ -356,6 +356,8 @@ struct ieee80211_if_conf {
        u8 *bssid;
        u8 *ssid;
        size_t ssid_len;
+       u8 *generic_elem;
+       size_t generic_elem_len;
 };
 
 typedef enum { ALG_NONE, ALG_WEP, ALG_TKIP, ALG_CCMP, ALG_NULL }
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 984c2b0..ad63bab 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1764,9 +1764,13 @@ int ieee80211_if_config(struct net_devic
                conf.bssid = sdata->u.sta.bssid;
                conf.ssid = sdata->u.sta.ssid;
                conf.ssid_len = sdata->u.sta.ssid_len;
+               conf.generic_elem = sdata->u.sta.extra_ie;
+               conf.generic_elem_len = sdata->u.sta.extra_ie_len;
        } else if (sdata->type == IEEE80211_IF_TYPE_AP) {
                conf.ssid = sdata->u.ap.ssid;
                conf.ssid_len = sdata->u.ap.ssid_len;
+               conf.generic_elem = sdata->u.ap.generic_elem;
+               conf.generic_elem_len = sdata->u.ap.generic_elem_len;
        }
        return local->hw->config_interface(local->mdev, dev->ifindex, &conf);
 }
@@ -4342,8 +4346,6 @@ void ieee80211_unregister_hw(struct net_
                kfree(local->basic_rates[i]);
         }
 
-       kfree(local->conf.generic_elem);
-
        ieee80211_proc_deinit_interface(local);
 
        if (skb_queue_len(&local->skb_queue)
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index e78beb2..98c30ff 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -194,6 +194,8 @@ struct ieee80211_if_ap {
 
        u8 ssid[IEEE80211_MAX_SSID_LEN];
        size_t ssid_len;
+       u8 *generic_elem;
+       size_t generic_elem_len;
 
        /* TODO: sta_aid could be replaced by 2008-bit large bitfield of
         * that could be used in TIM element generation. This would also
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index dd809c2..42ea643 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -175,6 +175,7 @@ #endif
 
                kfree(sdata->u.ap.beacon_head);
                kfree(sdata->u.ap.beacon_tail);
+               kfree(sdata->u.ap.generic_elem);
 
                if (dev != local->mdev) {
                        struct sk_buff *skb;
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 6b73e27..3eaad0a 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -1137,7 +1137,6 @@ #endif
 
 static int ieee80211_set_gen_ie(struct net_device *dev, u8 *ie, size_t len)
 {
-       struct ieee80211_local *local = dev->priv;
        struct ieee80211_sub_if_data *sdata;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1145,14 +1144,16 @@ static int ieee80211_set_gen_ie(struct n
            sdata->type == IEEE80211_IF_TYPE_IBSS)
                return ieee80211_sta_set_extra_ie(dev, ie, len);
 
-       kfree(local->conf.generic_elem);
-       local->conf.generic_elem = kmalloc(len, GFP_KERNEL);
-       if (local->conf.generic_elem == NULL)
-               return -ENOMEM;
-       memcpy(local->conf.generic_elem, ie, len);
-       local->conf.generic_elem_len = len;
-
-       return ieee80211_hw_config(dev);
+       if (sdata->type == IEEE80211_IF_TYPE_AP) {
+               kfree(sdata->u.ap.generic_elem);
+               sdata->u.ap.generic_elem = kmalloc(len, GFP_KERNEL);
+               if (sdata->u.ap.generic_elem == NULL)
+                       return -ENOMEM;
+               memcpy(sdata->u.ap.generic_elem, ie, len);
+               sdata->u.ap.generic_elem_len = len;
+               return ieee80211_if_config(dev);
+       }
+       return -EOPNOTSUPP;
 }
 
 
-- 
1.3.0

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to