mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 15:11:31 +00:00
[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: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Jiri Benc <jbenc@suse.cz> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
5558235c6b
commit
4480f15ca6
@ -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 {
|
|||||||
* 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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
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,
|
|||||||
((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 :/ */
|
||||||
|
Loading…
Reference in New Issue
Block a user