diff options
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); |