[PATCH] mac80211: clarify some mac80211 things
authorJohannes Berg <johannes@sipsolutions.net>
Tue, 10 Jul 2007 17:32:10 +0000 (19:32 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 12 Jul 2007 20:07:26 +0000 (16:07 -0400)
The semantics of not having an add_interface callback are not well
defined, this callback is required because otherwise you cannot obtain
the requested MAC address of the device. Change the documentation to
reflect this, add a note about having no MAC address at all, add a
warning that mac_addr in struct ieee80211_if_init_conf can be NULL and
finally verify that a few callbacks are assigned by way of BUG_ON()

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/net/mac80211.h
net/mac80211/ieee80211.c

index 6278857..c34fd9a 100644 (file)
@@ -347,9 +347,16 @@ enum ieee80211_if_types {
  * @mac_addr: pointer to MAC address of the interface. This pointer is valid
  *     until the interface is removed (i.e. it cannot be used after
  *     remove_interface() callback was called for this interface).
+ *     This pointer will be %NULL for monitor interfaces, be careful.
  *
  * This structure is used in add_interface() and remove_interface()
  * callbacks of &struct ieee80211_hw.
+ *
+ * When you allow multiple interfaces to be added to your PHY, take care
+ * that the hardware can actually handle multiple MAC addresses. However,
+ * also take care that when there's no interface left with mac_addr != %NULL
+ * you remove the MAC address from the device to avoid acknowledging packets
+ * in pure monitor mode.
  */
 struct ieee80211_if_init_conf {
        int if_id;
@@ -574,10 +581,11 @@ struct ieee80211_ops {
         * to returning zero. By returning non-zero addition of the interface
         * is inhibited. Unless monitor_during_oper is set, it is guaranteed
         * that monitor interfaces and normal interfaces are mutually
-        * exclusive. The open() handler is called after add_interface()
-        * if this is the first device added. At least one of the open()
-        * open() and add_interface() callbacks has to be assigned. If
-        * add_interface() is NULL, one STA interface is permitted only. */
+        * exclusive. If assigned, the open() handler is called after
+        * add_interface() if this is the first device added. The
+        * add_interface() callback has to be assigned because it is the only
+        * way to obtain the requested MAC address for any interface.
+        */
        int (*add_interface)(struct ieee80211_hw *hw,
                             struct ieee80211_if_init_conf *conf);
 
index 773a103..fe32a2d 100644 (file)
@@ -2605,8 +2605,7 @@ static void ieee80211_start_hard_monitor(struct ieee80211_local *local)
        struct ieee80211_if_init_conf conf;
 
        if (local->open_count && local->open_count == local->monitors &&
-           !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER) &&
-           local->ops->add_interface) {
+           !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER)) {
                conf.if_id = -1;
                conf.type = IEEE80211_IF_TYPE_MNTR;
                conf.mac_addr = NULL;
@@ -2649,21 +2648,14 @@ static int ieee80211_open(struct net_device *dev)
        }
        ieee80211_start_soft_monitor(local);
 
-       if (local->ops->add_interface) {
-               conf.if_id = dev->ifindex;
-               conf.type = sdata->type;
-               conf.mac_addr = dev->dev_addr;
-               res = local->ops->add_interface(local_to_hw(local), &conf);
-               if (res) {
-                       if (sdata->type == IEEE80211_IF_TYPE_MNTR)
-                               ieee80211_start_hard_monitor(local);
-                       return res;
-               }
-       } else {
-               if (sdata->type != IEEE80211_IF_TYPE_STA)
-                       return -EOPNOTSUPP;
-               if (local->open_count > 0)
-                       return -ENOBUFS;
+       conf.if_id = dev->ifindex;
+       conf.type = sdata->type;
+       conf.mac_addr = dev->dev_addr;
+       res = local->ops->add_interface(local_to_hw(local), &conf);
+       if (res) {
+               if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+                       ieee80211_start_hard_monitor(local);
+               return res;
        }
 
        if (local->open_count == 0) {
@@ -4896,6 +4888,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
                         ((sizeof(struct ieee80211_local) +
                           NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
 
+       BUG_ON(!ops->tx);
+       BUG_ON(!ops->config);
+       BUG_ON(!ops->add_interface);
        local->ops = ops;
 
        /* for now, mdev needs sub_if_data :/ */