aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/iface.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-25 11:46:19 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-21 18:38:52 -0500
commit47846c9b0c10808d9337d2e7d09361f3e0a0a71a (patch)
tree8e5d0dbf3309b7868fa73a888f9561ffea1580e3 /net/mac80211/iface.c
parentabe60632f311d515b082b450504ee24006023951 (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.c62
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
63static 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
63static inline int identical_mac_addr_allowed(int type1, int type2) 79static 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
657static const struct net_device_ops ieee80211_monitorif_ops = { 673static 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
967static 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
991static struct notifier_block mac80211_netdev_notifier = {
992 .notifier_call = netdev_notify,
993};
994
995int ieee80211_iface_init(void)
996{
997 return register_netdevice_notifier(&mac80211_netdev_notifier);
998}
999
1000void ieee80211_iface_exit(void)
1001{
1002 unregister_netdevice_notifier(&mac80211_netdev_notifier);
1003}