Not all combinations of interfaces (in fact, very few combination of
interfaces) are possible to be UP together. When an interface is going UP,
let's ask the driver if this is possible.

Please note that ieee80211_if_conf structure is not complete yet - new
fields will need to be added to allow drivers to decide.

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

Index: dscape/include/net/d80211.h
===================================================================
--- dscape.orig/include/net/d80211.h    2006-03-06 14:10:07.000000000 +0100
+++ dscape/include/net/d80211.h 2006-03-06 14:10:18.000000000 +0100
@@ -305,6 +305,18 @@ struct ieee80211_conf {
        u8 pulse_inband_threshold;
 };
 
+#define IEEE80211_SUB_IF_TYPE_AP   0x00000000
+#define IEEE80211_SUB_IF_TYPE_MGMT 0x00000001
+#define IEEE80211_SUB_IF_TYPE_STA  0x00000002
+#define IEEE80211_SUB_IF_TYPE_IBSS 0x00000003
+#define IEEE80211_SUB_IF_TYPE_MNTR 0x00000004
+#define IEEE80211_SUB_IF_TYPE_WDS  0x5A580211
+#define IEEE80211_SUB_IF_TYPE_VLAN 0x00080211
+
+struct ieee80211_if_conf {
+       int type;
+       void *mac_addr;
+};
 
 typedef enum { ALG_NONE, ALG_WEP, ALG_TKIP, ALG_CCMP, ALG_NULL }
 ieee80211_key_alg;
@@ -452,6 +464,22 @@ struct ieee80211_hw {
         * interrupts and beacon sending. */
        int (*stop)(struct net_device *dev);
 
+       /* Handler for asking a driver if a new interface can be added (or,
+        * more exactly, set UP). If the handler returns zero, the interface
+        * is added. Driver should perform any initialization it needs prior
+        * to returning zero. By returning non-zero, adding of the interface
+        * is not permitted. The open() handler is called after
+        * add_interface() if this is the first device added. At least one
+        * of open() and add_interface() handler has to be non-NULL. If
+        * add_interface() is NULL, one STA interface is permitted only. */
+       int (*add_interface)(struct net_device *dev,
+                            struct ieee80211_if_conf *conf);
+
+       /* Notify a driver that interface is going down. The stop() handler
+        * is called prior to this if this is a last interface. */
+       void (*remove_interface)(struct net_device *dev,
+                                struct ieee80211_if_conf *conf);
+
        /* Handler for configuration requests. IEEE 802.11 code calls this
         * function to change hardware configuration, e.g., channel. */
        int (*config)(struct net_device *dev, struct ieee80211_conf *conf);
Index: dscape/net/d80211/ieee80211_i.h
===================================================================
--- dscape.orig/net/d80211/ieee80211_i.h        2006-03-06 14:10:15.000000000 
+0100
+++ dscape/net/d80211/ieee80211_i.h     2006-03-06 14:10:18.000000000 +0100
@@ -256,14 +256,6 @@ struct ieee80211_if_sta {
 };
 
 
-#define IEEE80211_SUB_IF_TYPE_AP   0x00000000
-#define IEEE80211_SUB_IF_TYPE_MGMT 0x00000001
-#define IEEE80211_SUB_IF_TYPE_STA  0x00000002
-#define IEEE80211_SUB_IF_TYPE_IBSS 0x00000003
-#define IEEE80211_SUB_IF_TYPE_MNTR 0x00000004
-#define IEEE80211_SUB_IF_TYPE_WDS  0x5A580211
-#define IEEE80211_SUB_IF_TYPE_VLAN 0x00080211
-
 struct ieee80211_sub_if_data {
         struct list_head list;
         unsigned int type;
Index: dscape/net/d80211/ieee80211.c
===================================================================
--- dscape.orig/net/d80211/ieee80211.c  2006-03-06 14:10:15.000000000 +0100
+++ dscape/net/d80211/ieee80211.c       2006-03-06 14:10:18.000000000 +0100
@@ -1828,11 +1828,22 @@ static int ieee80211_open(struct net_dev
        int res;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       if (local->hw->add_interface) {
+               struct ieee80211_if_conf conf;
 
-        if (local->open_count == 0) {
-               res = local->hw->open(sdata->master);
+               conf.type = sdata->type;
+               conf.mac_addr = dev->dev_addr;
+               res = local->hw->add_interface(sdata->master, &conf);
                if (res)
                        return res;
+       }
+
+        if (local->open_count == 0) {
+               if (local->hw->open) {
+                       res = local->hw->open(sdata->master);
+                       if (res)
+                               return res;
+               }
                ieee80211_init_scan(sdata->master);
        }
         local->open_count++;
@@ -1855,10 +1866,19 @@ static int ieee80211_stop(struct net_dev
        local->open_count--;
         if (local->open_count == 0) {
                ieee80211_stop_scan(sdata->master);
-               res = local->hw->stop(sdata->master);
-               if (res)
-                       return res;
+               if (local->hw->stop) {
+                       res = local->hw->stop(sdata->master);
+                       if (res)
+                               return res;
+               }
         }
+       if (local->hw->remove_interface) {
+               struct ieee80211_if_conf conf;
+
+               conf.type = sdata->type;
+               conf.mac_addr = dev->dev_addr;
+               local->hw->remove_interface(sdata->master, &conf);
+       }
 
        return 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