diff options
author | Sven Eckelmann <sven.eckelmann@open-mesh.com> | 2016-09-30 16:21:03 +0300 |
---|---|---|
committer | Simon Wunderlich <sw@simonwunderlich.de> | 2016-11-08 21:02:37 +0300 |
commit | 10b1bbb46c6c8e571458a9a8913514dbebbaf20c (patch) | |
tree | d6485a43f41c5867811004a8766eaafc3a56ce3f /net/batman-adv/hard-interface.c | |
parent | f44a3ae9a2811cfd5321e0f72c02bc270410db64 (diff) | |
download | linux-10b1bbb46c6c8e571458a9a8913514dbebbaf20c.tar.xz |
batman-adv: Cache the type of wifi device for each hardif
batman-adv is requiring the type of wifi device in different contexts. Some
of them can take the rtnl semaphore and some of them already have the
semaphore taken. But even others don't allow that the semaphore will be
taken.
The data has to be retrieved when the hardif is added to batman-adv because
some of the wifi information for an hardif will only be available with rtnl
lock. It can then be cached in the batadv_hard_iface and the functions
is_wifi_netdev and is_cfg80211_netdev can just compare the correct bits
without imposing extra locking requirements.
Signed-off-by: Sven Eckelmann <sven.eckelmann@open-mesh.com>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
Diffstat (limited to 'net/batman-adv/hard-interface.c')
-rw-r--r-- | net/batman-adv/hard-interface.c | 82 |
1 files changed, 67 insertions, 15 deletions
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index c3fbc1b9c8e3..57e89125ab3e 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -202,6 +202,30 @@ static bool batadv_is_valid_iface(const struct net_device *net_dev) } /** + * batadv_is_wext_netdev - check if the given net_device struct is a + * wext wifi interface + * @net_device: the device to check + * + * Return: true if the net device is a wext wireless device, false + * otherwise. + */ +static bool batadv_is_wext_netdev(struct net_device *net_device) +{ + if (!net_device) + return false; + +#ifdef CONFIG_WIRELESS_EXT + /* pre-cfg80211 drivers have to implement WEXT, so it is possible to + * check for wireless_handlers != NULL + */ + if (net_device->wireless_handlers) + return true; +#endif + + return false; +} + +/** * batadv_is_cfg80211_netdev - check if the given net_device struct is a * cfg80211 wifi interface * @net_device: the device to check @@ -209,7 +233,7 @@ static bool batadv_is_valid_iface(const struct net_device *net_dev) * Return: true if the net device is a cfg80211 wireless device, false * otherwise. */ -bool batadv_is_cfg80211_netdev(struct net_device *net_device) +static bool batadv_is_cfg80211_netdev(struct net_device *net_device) { if (!net_device) return false; @@ -222,26 +246,53 @@ bool batadv_is_cfg80211_netdev(struct net_device *net_device) } /** - * batadv_is_wifi_netdev - check if the given net_device struct is a wifi - * interface + * batadv_wifi_flags_evaluate - calculate wifi flags for net_device * @net_device: the device to check * + * Return: batadv_hard_iface_wifi_flags flags of the device + */ +static u32 batadv_wifi_flags_evaluate(struct net_device *net_device) +{ + u32 wifi_flags = 0; + + if (batadv_is_wext_netdev(net_device)) + wifi_flags |= BATADV_HARDIF_WIFI_WEXT_DIRECT; + + if (batadv_is_cfg80211_netdev(net_device)) + wifi_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT; + + return wifi_flags; +} + +/** + * batadv_is_cfg80211_hardif - check if the given hardif is a cfg80211 wifi + * interface + * @hard_iface: the device to check + * + * Return: true if the net device is a cfg80211 wireless device, false + * otherwise. + */ +bool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface) +{ + u32 allowed_flags = 0; + + allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT; + + return !!(hard_iface->wifi_flags & allowed_flags); +} + +/** + * batadv_is_wifi_hardif - check if the given hardif is a wifi interface + * @hard_iface: the device to check + * * Return: true if the net device is a 802.11 wireless device, false otherwise. */ -bool batadv_is_wifi_netdev(struct net_device *net_device) +bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface) { - if (!net_device) + if (!hard_iface) return false; -#ifdef CONFIG_WIRELESS_EXT - /* pre-cfg80211 drivers have to implement WEXT, so it is possible to - * check for wireless_handlers != NULL - */ - if (net_device->wireless_handlers) - return true; -#endif - - return batadv_is_cfg80211_netdev(net_device); + return hard_iface->wifi_flags != 0; } /** @@ -765,7 +816,8 @@ batadv_hardif_add_interface(struct net_device *net_dev) kref_init(&hard_iface->refcount); hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT; - if (batadv_is_wifi_netdev(net_dev)) + hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev); + if (batadv_is_wifi_hardif(hard_iface)) hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS; batadv_v_hardif_init(hard_iface); |