diff options
Diffstat (limited to 'net/mac802154/main.c')
-rw-r--r-- | net/mac802154/main.c | 102 |
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" | |
32 | static int | ||
33 | mac802154_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 | |||
61 | static void | ||
62 | mac802154_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 | |||
78 | static struct net_device * | ||
79 | mac802154_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 | |||
110 | err_free: | ||
111 | free_netdev(dev); | ||
112 | err: | ||
113 | return ERR_PTR(err); | ||
114 | } | ||
115 | 32 | ||
116 | static void ieee802154_tasklet_handler(unsigned long data) | 33 | static 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); | |||
209 | int ieee802154_register_hw(struct ieee802154_hw *hw) | 126 | int 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 | ||
232 | out_wq: | 158 | out_wq: |