diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-06-17 11:43:56 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-24 15:05:30 -0400 |
commit | 3b8d81e020f77c9da8b85b0685c8cd2ca7c7b150 (patch) | |
tree | a19fcddbf28fecdbd13ad009fe07b8afc5e95c90 /net/mac80211/main.c | |
parent | c4029083e2acb82229c43b791c07afb089d972ff (diff) |
mac80211: remove master netdev
With the internal 'pending' queue system in place, we can simply
put packets there instead of pushing them off to the master dev,
getting rid of the master interface completely.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 120 |
1 files changed, 3 insertions, 117 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 5b69f5f07299..3234f3751d22 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -83,75 +83,14 @@ void ieee80211_configure_filter(struct ieee80211_local *local) | |||
83 | new_flags |= (1<<31); | 83 | new_flags |= (1<<31); |
84 | 84 | ||
85 | drv_configure_filter(local, changed_flags, &new_flags, | 85 | drv_configure_filter(local, changed_flags, &new_flags, |
86 | local->mdev->mc_count, | 86 | local->mc_count, |
87 | local->mdev->mc_list); | 87 | local->mc_list); |
88 | 88 | ||
89 | WARN_ON(new_flags & (1<<31)); | 89 | WARN_ON(new_flags & (1<<31)); |
90 | 90 | ||
91 | local->filter_flags = new_flags & ~(1<<31); | 91 | local->filter_flags = new_flags & ~(1<<31); |
92 | } | 92 | } |
93 | 93 | ||
94 | /* master interface */ | ||
95 | |||
96 | static int header_parse_80211(const struct sk_buff *skb, unsigned char *haddr) | ||
97 | { | ||
98 | memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */ | ||
99 | return ETH_ALEN; | ||
100 | } | ||
101 | |||
102 | static const struct header_ops ieee80211_header_ops = { | ||
103 | .create = eth_header, | ||
104 | .parse = header_parse_80211, | ||
105 | .rebuild = eth_rebuild_header, | ||
106 | .cache = eth_header_cache, | ||
107 | .cache_update = eth_header_cache_update, | ||
108 | }; | ||
109 | |||
110 | static int ieee80211_master_open(struct net_device *dev) | ||
111 | { | ||
112 | struct ieee80211_master_priv *mpriv = netdev_priv(dev); | ||
113 | struct ieee80211_local *local = mpriv->local; | ||
114 | struct ieee80211_sub_if_data *sdata; | ||
115 | int res = -EOPNOTSUPP; | ||
116 | |||
117 | /* we hold the RTNL here so can safely walk the list */ | ||
118 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
119 | if (netif_running(sdata->dev)) { | ||
120 | res = 0; | ||
121 | break; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | if (res) | ||
126 | return res; | ||
127 | |||
128 | netif_tx_start_all_queues(local->mdev); | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static int ieee80211_master_stop(struct net_device *dev) | ||
134 | { | ||
135 | struct ieee80211_master_priv *mpriv = netdev_priv(dev); | ||
136 | struct ieee80211_local *local = mpriv->local; | ||
137 | struct ieee80211_sub_if_data *sdata; | ||
138 | |||
139 | /* we hold the RTNL here so can safely walk the list */ | ||
140 | list_for_each_entry(sdata, &local->interfaces, list) | ||
141 | if (netif_running(sdata->dev)) | ||
142 | dev_close(sdata->dev); | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static void ieee80211_master_set_multicast_list(struct net_device *dev) | ||
148 | { | ||
149 | struct ieee80211_master_priv *mpriv = netdev_priv(dev); | ||
150 | struct ieee80211_local *local = mpriv->local; | ||
151 | |||
152 | ieee80211_configure_filter(local); | ||
153 | } | ||
154 | |||
155 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | 94 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) |
156 | { | 95 | { |
157 | struct ieee80211_channel *chan, *scan_chan; | 96 | struct ieee80211_channel *chan, *scan_chan; |
@@ -310,7 +249,6 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | |||
310 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 249 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
311 | int tmp; | 250 | int tmp; |
312 | 251 | ||
313 | skb->dev = local->mdev; | ||
314 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; | 252 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; |
315 | skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ? | 253 | skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ? |
316 | &local->skb_queue : &local->skb_queue_unreliable, skb); | 254 | &local->skb_queue : &local->skb_queue_unreliable, skb); |
@@ -716,7 +654,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
716 | mutex_init(&local->scan_mtx); | 654 | mutex_init(&local->scan_mtx); |
717 | 655 | ||
718 | spin_lock_init(&local->key_lock); | 656 | spin_lock_init(&local->key_lock); |
719 | 657 | spin_lock_init(&local->filter_lock); | |
720 | spin_lock_init(&local->queue_stop_reason_lock); | 658 | spin_lock_init(&local->queue_stop_reason_lock); |
721 | 659 | ||
722 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); | 660 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); |
@@ -752,30 +690,11 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
752 | } | 690 | } |
753 | EXPORT_SYMBOL(ieee80211_alloc_hw); | 691 | EXPORT_SYMBOL(ieee80211_alloc_hw); |
754 | 692 | ||
755 | static const struct net_device_ops ieee80211_master_ops = { | ||
756 | .ndo_start_xmit = ieee80211_master_start_xmit, | ||
757 | .ndo_open = ieee80211_master_open, | ||
758 | .ndo_stop = ieee80211_master_stop, | ||
759 | .ndo_set_multicast_list = ieee80211_master_set_multicast_list, | ||
760 | .ndo_select_queue = ieee80211_select_queue, | ||
761 | }; | ||
762 | |||
763 | static void ieee80211_master_setup(struct net_device *mdev) | ||
764 | { | ||
765 | mdev->type = ARPHRD_IEEE80211; | ||
766 | mdev->netdev_ops = &ieee80211_master_ops; | ||
767 | mdev->header_ops = &ieee80211_header_ops; | ||
768 | mdev->tx_queue_len = 1000; | ||
769 | mdev->addr_len = ETH_ALEN; | ||
770 | } | ||
771 | |||
772 | int ieee80211_register_hw(struct ieee80211_hw *hw) | 693 | int ieee80211_register_hw(struct ieee80211_hw *hw) |
773 | { | 694 | { |
774 | struct ieee80211_local *local = hw_to_local(hw); | 695 | struct ieee80211_local *local = hw_to_local(hw); |
775 | int result; | 696 | int result; |
776 | enum ieee80211_band band; | 697 | enum ieee80211_band band; |
777 | struct net_device *mdev; | ||
778 | struct ieee80211_master_priv *mpriv; | ||
779 | int channels, i, j, max_bitrates; | 698 | int channels, i, j, max_bitrates; |
780 | bool supp_ht; | 699 | bool supp_ht; |
781 | static const u32 cipher_suites[] = { | 700 | static const u32 cipher_suites[] = { |
@@ -874,16 +793,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
874 | if (hw->queues > IEEE80211_MAX_QUEUES) | 793 | if (hw->queues > IEEE80211_MAX_QUEUES) |
875 | hw->queues = IEEE80211_MAX_QUEUES; | 794 | hw->queues = IEEE80211_MAX_QUEUES; |
876 | 795 | ||
877 | mdev = alloc_netdev_mq(sizeof(struct ieee80211_master_priv), | ||
878 | "wmaster%d", ieee80211_master_setup, | ||
879 | hw->queues); | ||
880 | if (!mdev) | ||
881 | goto fail_mdev_alloc; | ||
882 | |||
883 | mpriv = netdev_priv(mdev); | ||
884 | mpriv->local = local; | ||
885 | local->mdev = mdev; | ||
886 | |||
887 | local->hw.workqueue = | 796 | local->hw.workqueue = |
888 | create_singlethread_workqueue(wiphy_name(local->hw.wiphy)); | 797 | create_singlethread_workqueue(wiphy_name(local->hw.wiphy)); |
889 | if (!local->hw.workqueue) { | 798 | if (!local->hw.workqueue) { |
@@ -918,17 +827,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
918 | } | 827 | } |
919 | 828 | ||
920 | rtnl_lock(); | 829 | rtnl_lock(); |
921 | result = dev_alloc_name(local->mdev, local->mdev->name); | ||
922 | if (result < 0) | ||
923 | goto fail_dev; | ||
924 | |||
925 | memcpy(local->mdev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); | ||
926 | SET_NETDEV_DEV(local->mdev, wiphy_dev(local->hw.wiphy)); | ||
927 | local->mdev->features |= NETIF_F_NETNS_LOCAL; | ||
928 | |||
929 | result = register_netdevice(local->mdev); | ||
930 | if (result < 0) | ||
931 | goto fail_dev; | ||
932 | 830 | ||
933 | result = ieee80211_init_rate_ctrl_alg(local, | 831 | result = ieee80211_init_rate_ctrl_alg(local, |
934 | hw->rate_control_algorithm); | 832 | hw->rate_control_algorithm); |
@@ -981,9 +879,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
981 | ieee80211_led_exit(local); | 879 | ieee80211_led_exit(local); |
982 | ieee80211_remove_interfaces(local); | 880 | ieee80211_remove_interfaces(local); |
983 | fail_rate: | 881 | fail_rate: |
984 | unregister_netdevice(local->mdev); | ||
985 | local->mdev = NULL; | ||
986 | fail_dev: | ||
987 | rtnl_unlock(); | 882 | rtnl_unlock(); |
988 | ieee80211_wep_free(local); | 883 | ieee80211_wep_free(local); |
989 | fail_wep: | 884 | fail_wep: |
@@ -992,9 +887,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
992 | debugfs_hw_del(local); | 887 | debugfs_hw_del(local); |
993 | destroy_workqueue(local->hw.workqueue); | 888 | destroy_workqueue(local->hw.workqueue); |
994 | fail_workqueue: | 889 | fail_workqueue: |
995 | if (local->mdev) | ||
996 | free_netdev(local->mdev); | ||
997 | fail_mdev_alloc: | ||
998 | wiphy_unregister(local->hw.wiphy); | 890 | wiphy_unregister(local->hw.wiphy); |
999 | fail_wiphy_register: | 891 | fail_wiphy_register: |
1000 | kfree(local->int_scan_req.channels); | 892 | kfree(local->int_scan_req.channels); |
@@ -1019,13 +911,8 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1019 | * because the driver cannot be handing us frames any | 911 | * because the driver cannot be handing us frames any |
1020 | * more and the tasklet is killed. | 912 | * more and the tasklet is killed. |
1021 | */ | 913 | */ |
1022 | |||
1023 | /* First, we remove all virtual interfaces. */ | ||
1024 | ieee80211_remove_interfaces(local); | 914 | ieee80211_remove_interfaces(local); |
1025 | 915 | ||
1026 | /* then, finally, remove the master interface */ | ||
1027 | unregister_netdevice(local->mdev); | ||
1028 | |||
1029 | rtnl_unlock(); | 916 | rtnl_unlock(); |
1030 | 917 | ||
1031 | ieee80211_clear_tx_pending(local); | 918 | ieee80211_clear_tx_pending(local); |
@@ -1044,7 +931,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1044 | wiphy_unregister(local->hw.wiphy); | 931 | wiphy_unregister(local->hw.wiphy); |
1045 | ieee80211_wep_free(local); | 932 | ieee80211_wep_free(local); |
1046 | ieee80211_led_exit(local); | 933 | ieee80211_led_exit(local); |
1047 | free_netdev(local->mdev); | ||
1048 | kfree(local->int_scan_req.channels); | 934 | kfree(local->int_scan_req.channels); |
1049 | } | 935 | } |
1050 | EXPORT_SYMBOL(ieee80211_unregister_hw); | 936 | EXPORT_SYMBOL(ieee80211_unregister_hw); |