diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-11-25 11:46:19 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-12-21 18:38:52 -0500 |
commit | 47846c9b0c10808d9337d2e7d09361f3e0a0a71a (patch) | |
tree | 8e5d0dbf3309b7868fa73a888f9561ffea1580e3 /net/mac80211/iface.c | |
parent | abe60632f311d515b082b450504ee24006023951 (diff) |
mac80211: reduce reliance on netdev
For bluetooth 3, we will most likely not have
a netdev for a virtual interface (sdata), so
prepare for that by reducing the reliance on
having a netdev. This patch moves the name
and address fields into the sdata struct and
uses them from there all over. Some work is
needed to keep them sync'ed, but that's not
a lot of work and in slow paths anyway.
In doing so, this also reduces the number of
pointer dereferences in many places, because
of things like sdata->dev->dev_addr becoming
sdata->vif.addr.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 62 |
1 files changed, 59 insertions, 3 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 80c16f6e2af6..a6e6da3cab70 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -60,6 +60,22 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | |||
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
62 | 62 | ||
63 | static int ieee80211_change_mac(struct net_device *dev, void *addr) | ||
64 | { | ||
65 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
66 | int ret; | ||
67 | |||
68 | if (netif_running(dev)) | ||
69 | return -EBUSY; | ||
70 | |||
71 | ret = eth_mac_addr(dev, addr); | ||
72 | |||
73 | if (ret == 0) | ||
74 | memcpy(sdata->vif.addr, addr, ETH_ALEN); | ||
75 | |||
76 | return ret; | ||
77 | } | ||
78 | |||
63 | static inline int identical_mac_addr_allowed(int type1, int type2) | 79 | static inline int identical_mac_addr_allowed(int type1, int type2) |
64 | { | 80 | { |
65 | return type1 == NL80211_IFTYPE_MONITOR || | 81 | return type1 == NL80211_IFTYPE_MONITOR || |
@@ -234,7 +250,7 @@ static int ieee80211_open(struct net_device *dev) | |||
234 | default: | 250 | default: |
235 | conf.vif = &sdata->vif; | 251 | conf.vif = &sdata->vif; |
236 | conf.type = sdata->vif.type; | 252 | conf.type = sdata->vif.type; |
237 | conf.mac_addr = dev->dev_addr; | 253 | conf.mac_addr = sdata->vif.addr; |
238 | res = drv_add_interface(local, &conf); | 254 | res = drv_add_interface(local, &conf); |
239 | if (res) | 255 | if (res) |
240 | goto err_stop; | 256 | goto err_stop; |
@@ -514,7 +530,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
514 | 530 | ||
515 | conf.vif = &sdata->vif; | 531 | conf.vif = &sdata->vif; |
516 | conf.type = sdata->vif.type; | 532 | conf.type = sdata->vif.type; |
517 | conf.mac_addr = dev->dev_addr; | 533 | conf.mac_addr = sdata->vif.addr; |
518 | /* disable all keys for as long as this netdev is down */ | 534 | /* disable all keys for as long as this netdev is down */ |
519 | ieee80211_disable_keys(sdata); | 535 | ieee80211_disable_keys(sdata); |
520 | drv_remove_interface(local, &conf); | 536 | drv_remove_interface(local, &conf); |
@@ -651,7 +667,7 @@ static const struct net_device_ops ieee80211_dataif_ops = { | |||
651 | .ndo_start_xmit = ieee80211_subif_start_xmit, | 667 | .ndo_start_xmit = ieee80211_subif_start_xmit, |
652 | .ndo_set_multicast_list = ieee80211_set_multicast_list, | 668 | .ndo_set_multicast_list = ieee80211_set_multicast_list, |
653 | .ndo_change_mtu = ieee80211_change_mtu, | 669 | .ndo_change_mtu = ieee80211_change_mtu, |
654 | .ndo_set_mac_address = eth_mac_addr, | 670 | .ndo_set_mac_address = ieee80211_change_mac, |
655 | }; | 671 | }; |
656 | 672 | ||
657 | static const struct net_device_ops ieee80211_monitorif_ops = { | 673 | static const struct net_device_ops ieee80211_monitorif_ops = { |
@@ -794,6 +810,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
794 | /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ | 810 | /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ |
795 | sdata = netdev_priv(ndev); | 811 | sdata = netdev_priv(ndev); |
796 | ndev->ieee80211_ptr = &sdata->wdev; | 812 | ndev->ieee80211_ptr = &sdata->wdev; |
813 | memcpy(sdata->vif.addr, ndev->dev_addr, ETH_ALEN); | ||
814 | memcpy(sdata->name, ndev->name, IFNAMSIZ); | ||
797 | 815 | ||
798 | /* initialise type-independent data */ | 816 | /* initialise type-independent data */ |
799 | sdata->wdev.wiphy = local->hw.wiphy; | 817 | sdata->wdev.wiphy = local->hw.wiphy; |
@@ -945,3 +963,41 @@ void ieee80211_recalc_idle(struct ieee80211_local *local) | |||
945 | if (chg) | 963 | if (chg) |
946 | ieee80211_hw_config(local, chg); | 964 | ieee80211_hw_config(local, chg); |
947 | } | 965 | } |
966 | |||
967 | static int netdev_notify(struct notifier_block *nb, | ||
968 | unsigned long state, | ||
969 | void *ndev) | ||
970 | { | ||
971 | struct net_device *dev = ndev; | ||
972 | struct ieee80211_sub_if_data *sdata; | ||
973 | |||
974 | if (state != NETDEV_CHANGENAME) | ||
975 | return 0; | ||
976 | |||
977 | if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy) | ||
978 | return 0; | ||
979 | |||
980 | if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid) | ||
981 | return 0; | ||
982 | |||
983 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
984 | |||
985 | memcpy(sdata->name, sdata->name, IFNAMSIZ); | ||
986 | |||
987 | ieee80211_debugfs_rename_netdev(sdata); | ||
988 | return 0; | ||
989 | } | ||
990 | |||
991 | static struct notifier_block mac80211_netdev_notifier = { | ||
992 | .notifier_call = netdev_notify, | ||
993 | }; | ||
994 | |||
995 | int ieee80211_iface_init(void) | ||
996 | { | ||
997 | return register_netdevice_notifier(&mac80211_netdev_notifier); | ||
998 | } | ||
999 | |||
1000 | void ieee80211_iface_exit(void) | ||
1001 | { | ||
1002 | unregister_netdevice_notifier(&mac80211_netdev_notifier); | ||
1003 | } | ||