aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac802154/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac802154/main.c')
-rw-r--r--net/mac802154/main.c102
1 files changed, 14 insertions, 88 deletions
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index 86e533ed3775..7d0ff7fd2cd4 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -28,90 +28,7 @@
28#include <net/cfg802154.h> 28#include <net/cfg802154.h>
29 29
30#include "ieee802154_i.h" 30#include "ieee802154_i.h"
31 31#include "cfg.h"
32static int
33mac802154_netdev_register(struct wpan_phy *phy, struct net_device *dev)
34{
35 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
36 struct ieee802154_local *local;
37 int err;
38
39 local = wpan_phy_priv(phy);
40
41 sdata->dev = dev;
42 sdata->local = local;
43
44 dev->needed_headroom = local->hw.extra_tx_headroom;
45
46 SET_NETDEV_DEV(dev, &local->phy->dev);
47
48 err = register_netdev(dev);
49 if (err < 0)
50 return err;
51
52 rtnl_lock();
53 mutex_lock(&local->iflist_mtx);
54 list_add_tail_rcu(&sdata->list, &local->interfaces);
55 mutex_unlock(&local->iflist_mtx);
56 rtnl_unlock();
57
58 return 0;
59}
60
61static void
62mac802154_del_iface(struct wpan_phy *phy, struct net_device *dev)
63{
64 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
65
66 ASSERT_RTNL();
67
68 BUG_ON(sdata->local->phy != phy);
69
70 mutex_lock(&sdata->local->iflist_mtx);
71 list_del_rcu(&sdata->list);
72 mutex_unlock(&sdata->local->iflist_mtx);
73
74 synchronize_rcu();
75 unregister_netdevice(sdata->dev);
76}
77
78static struct net_device *
79mac802154_add_iface(struct wpan_phy *phy, const char *name, int type)
80{
81 struct net_device *dev;
82 int err = -ENOMEM;
83
84 switch (type) {
85 case IEEE802154_DEV_MONITOR:
86 dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data),
87 name, NET_NAME_UNKNOWN,
88 mac802154_monitor_setup);
89 break;
90 case IEEE802154_DEV_WPAN:
91 dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data),
92 name, NET_NAME_UNKNOWN,
93 mac802154_wpan_setup);
94 break;
95 default:
96 dev = NULL;
97 err = -EINVAL;
98 break;
99 }
100 if (!dev)
101 goto err;
102
103 err = mac802154_netdev_register(phy, dev);
104 if (err)
105 goto err_free;
106
107 dev_hold(dev); /* we return an incremented device refcount */
108 return dev;
109
110err_free:
111 free_netdev(dev);
112err:
113 return ERR_PTR(err);
114}
115 32
116static void ieee802154_tasklet_handler(unsigned long data) 33static void ieee802154_tasklet_handler(unsigned long data)
117{ 34{
@@ -169,7 +86,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
169 86
170 priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; 87 priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len;
171 88
172 phy = wpan_phy_alloc(priv_size); 89 phy = wpan_phy_alloc(&mac802154_config_ops, priv_size);
173 if (!phy) { 90 if (!phy) {
174 pr_err("failure to allocate master IEEE802.15.4 device\n"); 91 pr_err("failure to allocate master IEEE802.15.4 device\n");
175 return NULL; 92 return NULL;
@@ -209,6 +126,7 @@ EXPORT_SYMBOL(ieee802154_free_hw);
209int ieee802154_register_hw(struct ieee802154_hw *hw) 126int ieee802154_register_hw(struct ieee802154_hw *hw)
210{ 127{
211 struct ieee802154_local *local = hw_to_local(hw); 128 struct ieee802154_local *local = hw_to_local(hw);
129 struct net_device *dev;
212 int rc = -ENOSYS; 130 int rc = -ENOSYS;
213 131
214 local->workqueue = 132 local->workqueue =
@@ -220,13 +138,21 @@ int ieee802154_register_hw(struct ieee802154_hw *hw)
220 138
221 wpan_phy_set_dev(local->phy, local->hw.parent); 139 wpan_phy_set_dev(local->phy, local->hw.parent);
222 140
223 local->phy->add_iface = mac802154_add_iface;
224 local->phy->del_iface = mac802154_del_iface;
225
226 rc = wpan_phy_register(local->phy); 141 rc = wpan_phy_register(local->phy);
227 if (rc < 0) 142 if (rc < 0)
228 goto out_wq; 143 goto out_wq;
229 144
145 rtnl_lock();
146
147 dev = ieee802154_if_add(local, "wpan%d", NULL, IEEE802154_DEV_WPAN);
148 if (IS_ERR(dev)) {
149 rtnl_unlock();
150 rc = PTR_ERR(dev);
151 goto out_wq;
152 }
153
154 rtnl_unlock();
155
230 return 0; 156 return 0;
231 157
232out_wq: 158out_wq: