Commit 4480f15c authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

[PATCH] mac80211: clarify some mac80211 things

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: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJiri Benc <jbenc@suse.cz>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 5558235c
...@@ -347,9 +347,16 @@ enum ieee80211_if_types { ...@@ -347,9 +347,16 @@ enum ieee80211_if_types {
* @mac_addr: pointer to MAC address of the interface. This pointer is valid * @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 * until the interface is removed (i.e. it cannot be used after
* remove_interface() callback was called for this interface). * 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() * This structure is used in add_interface() and remove_interface()
* callbacks of &struct ieee80211_hw. * 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 { struct ieee80211_if_init_conf {
int if_id; int if_id;
...@@ -574,10 +581,11 @@ struct ieee80211_ops { ...@@ -574,10 +581,11 @@ struct ieee80211_ops {
* to returning zero. By returning non-zero addition of the interface * to returning zero. By returning non-zero addition of the interface
* is inhibited. Unless monitor_during_oper is set, it is guaranteed * is inhibited. Unless monitor_during_oper is set, it is guaranteed
* that monitor interfaces and normal interfaces are mutually * that monitor interfaces and normal interfaces are mutually
* exclusive. The open() handler is called after add_interface() * exclusive. If assigned, the open() handler is called after
* if this is the first device added. At least one of the open() * add_interface() if this is the first device added. The
* open() and add_interface() callbacks has to be assigned. If * add_interface() callback has to be assigned because it is the only
* add_interface() is NULL, one STA interface is permitted only. */ * way to obtain the requested MAC address for any interface.
*/
int (*add_interface)(struct ieee80211_hw *hw, int (*add_interface)(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf); struct ieee80211_if_init_conf *conf);
......
...@@ -2605,8 +2605,7 @@ static void ieee80211_start_hard_monitor(struct ieee80211_local *local) ...@@ -2605,8 +2605,7 @@ static void ieee80211_start_hard_monitor(struct ieee80211_local *local)
struct ieee80211_if_init_conf conf; struct ieee80211_if_init_conf conf;
if (local->open_count && local->open_count == local->monitors && if (local->open_count && local->open_count == local->monitors &&
!(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER) && !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER)) {
local->ops->add_interface) {
conf.if_id = -1; conf.if_id = -1;
conf.type = IEEE80211_IF_TYPE_MNTR; conf.type = IEEE80211_IF_TYPE_MNTR;
conf.mac_addr = NULL; conf.mac_addr = NULL;
...@@ -2649,21 +2648,14 @@ static int ieee80211_open(struct net_device *dev) ...@@ -2649,21 +2648,14 @@ static int ieee80211_open(struct net_device *dev)
} }
ieee80211_start_soft_monitor(local); ieee80211_start_soft_monitor(local);
if (local->ops->add_interface) { conf.if_id = dev->ifindex;
conf.if_id = dev->ifindex; conf.type = sdata->type;
conf.type = sdata->type; conf.mac_addr = dev->dev_addr;
conf.mac_addr = dev->dev_addr; res = local->ops->add_interface(local_to_hw(local), &conf);
res = local->ops->add_interface(local_to_hw(local), &conf); if (res) {
if (res) { if (sdata->type == IEEE80211_IF_TYPE_MNTR)
if (sdata->type == IEEE80211_IF_TYPE_MNTR) ieee80211_start_hard_monitor(local);
ieee80211_start_hard_monitor(local); return res;
return res;
}
} else {
if (sdata->type != IEEE80211_IF_TYPE_STA)
return -EOPNOTSUPP;
if (local->open_count > 0)
return -ENOBUFS;
} }
if (local->open_count == 0) { if (local->open_count == 0) {
...@@ -4896,6 +4888,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, ...@@ -4896,6 +4888,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
((sizeof(struct ieee80211_local) + ((sizeof(struct ieee80211_local) +
NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
BUG_ON(!ops->tx);
BUG_ON(!ops->config);
BUG_ON(!ops->add_interface);
local->ops = ops; local->ops = ops;
/* for now, mdev needs sub_if_data :/ */ /* for now, mdev needs sub_if_data :/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment