aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-06-17 11:43:56 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-24 15:05:30 -0400
commit3b8d81e020f77c9da8b85b0685c8cd2ca7c7b150 (patch)
treea19fcddbf28fecdbd13ad009fe07b8afc5e95c90 /net/mac80211/main.c
parentc4029083e2acb82229c43b791c07afb089d972ff (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.c120
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
96static 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
102static 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
110static 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
133static 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
147static 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
155int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) 94int 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}
753EXPORT_SYMBOL(ieee80211_alloc_hw); 691EXPORT_SYMBOL(ieee80211_alloc_hw);
754 692
755static 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
763static 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
772int ieee80211_register_hw(struct ieee80211_hw *hw) 693int 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}
1050EXPORT_SYMBOL(ieee80211_unregister_hw); 936EXPORT_SYMBOL(ieee80211_unregister_hw);