perf tools: Don't clone maps from parent when synthesizing forks
[linux/fpc-iii.git] / drivers / net / ieee802154 / mac802154_hwsim.c
blob51b5198d5943422bc61e2201e830176d733d006b
1 /*
2 * HWSIM IEEE 802.15.4 interface
4 * (C) 2018 Mojatau, Alexander Aring <aring@mojatau.com>
5 * Copyright 2007-2012 Siemens AG
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2
9 * as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * Based on fakelb, original Written by:
17 * Sergey Lapin <slapin@ossfans.org>
18 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
19 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
22 #include <linux/module.h>
23 #include <linux/timer.h>
24 #include <linux/platform_device.h>
25 #include <linux/rtnetlink.h>
26 #include <linux/netdevice.h>
27 #include <linux/device.h>
28 #include <linux/spinlock.h>
29 #include <net/mac802154.h>
30 #include <net/cfg802154.h>
31 #include <net/genetlink.h>
32 #include "mac802154_hwsim.h"
34 MODULE_DESCRIPTION("Software simulator of IEEE 802.15.4 radio(s) for mac802154");
35 MODULE_LICENSE("GPL");
37 static LIST_HEAD(hwsim_phys);
38 static DEFINE_MUTEX(hwsim_phys_lock);
40 static struct platform_device *mac802154hwsim_dev;
42 /* MAC802154_HWSIM netlink family */
43 static struct genl_family hwsim_genl_family;
45 static int hwsim_radio_idx;
47 enum hwsim_multicast_groups {
48 HWSIM_MCGRP_CONFIG,
51 static const struct genl_multicast_group hwsim_mcgrps[] = {
52 [HWSIM_MCGRP_CONFIG] = { .name = "config", },
55 struct hwsim_pib {
56 u8 page;
57 u8 channel;
59 struct rcu_head rcu;
62 struct hwsim_edge_info {
63 u8 lqi;
65 struct rcu_head rcu;
68 struct hwsim_edge {
69 struct hwsim_phy *endpoint;
70 struct hwsim_edge_info __rcu *info;
72 struct list_head list;
73 struct rcu_head rcu;
76 struct hwsim_phy {
77 struct ieee802154_hw *hw;
78 u32 idx;
80 struct hwsim_pib __rcu *pib;
82 bool suspended;
83 struct list_head edges;
85 struct list_head list;
88 static int hwsim_add_one(struct genl_info *info, struct device *dev,
89 bool init);
90 static void hwsim_del(struct hwsim_phy *phy);
92 static int hwsim_hw_ed(struct ieee802154_hw *hw, u8 *level)
94 *level = 0xbe;
96 return 0;
99 static int hwsim_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
101 struct hwsim_phy *phy = hw->priv;
102 struct hwsim_pib *pib, *pib_old;
104 pib = kzalloc(sizeof(*pib), GFP_KERNEL);
105 if (!pib)
106 return -ENOMEM;
108 pib->page = page;
109 pib->channel = channel;
111 pib_old = rtnl_dereference(phy->pib);
112 rcu_assign_pointer(phy->pib, pib);
113 kfree_rcu(pib_old, rcu);
114 return 0;
117 static int hwsim_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
119 struct hwsim_phy *current_phy = hw->priv;
120 struct hwsim_pib *current_pib, *endpoint_pib;
121 struct hwsim_edge_info *einfo;
122 struct hwsim_edge *e;
124 WARN_ON(current_phy->suspended);
126 rcu_read_lock();
127 current_pib = rcu_dereference(current_phy->pib);
128 list_for_each_entry_rcu(e, &current_phy->edges, list) {
129 /* Can be changed later in rx_irqsafe, but this is only a
130 * performance tweak. Received radio should drop the frame
131 * in mac802154 stack anyway... so we don't need to be
132 * 100% of locking here to check on suspended
134 if (e->endpoint->suspended)
135 continue;
137 endpoint_pib = rcu_dereference(e->endpoint->pib);
138 if (current_pib->page == endpoint_pib->page &&
139 current_pib->channel == endpoint_pib->channel) {
140 struct sk_buff *newskb = pskb_copy(skb, GFP_ATOMIC);
142 einfo = rcu_dereference(e->info);
143 if (newskb)
144 ieee802154_rx_irqsafe(e->endpoint->hw, newskb,
145 einfo->lqi);
148 rcu_read_unlock();
150 ieee802154_xmit_complete(hw, skb, false);
151 return 0;
154 static int hwsim_hw_start(struct ieee802154_hw *hw)
156 struct hwsim_phy *phy = hw->priv;
158 phy->suspended = false;
159 return 0;
162 static void hwsim_hw_stop(struct ieee802154_hw *hw)
164 struct hwsim_phy *phy = hw->priv;
166 phy->suspended = true;
169 static int
170 hwsim_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on)
172 return 0;
175 static const struct ieee802154_ops hwsim_ops = {
176 .owner = THIS_MODULE,
177 .xmit_async = hwsim_hw_xmit,
178 .ed = hwsim_hw_ed,
179 .set_channel = hwsim_hw_channel,
180 .start = hwsim_hw_start,
181 .stop = hwsim_hw_stop,
182 .set_promiscuous_mode = hwsim_set_promiscuous_mode,
185 static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
187 return hwsim_add_one(info, &mac802154hwsim_dev->dev, false);
190 static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
192 struct hwsim_phy *phy, *tmp;
193 s64 idx = -1;
195 if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID])
196 return -EINVAL;
198 idx = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]);
200 mutex_lock(&hwsim_phys_lock);
201 list_for_each_entry_safe(phy, tmp, &hwsim_phys, list) {
202 if (idx == phy->idx) {
203 hwsim_del(phy);
204 mutex_unlock(&hwsim_phys_lock);
205 return 0;
208 mutex_unlock(&hwsim_phys_lock);
210 return -ENODEV;
213 static int append_radio_msg(struct sk_buff *skb, struct hwsim_phy *phy)
215 struct nlattr *nl_edges, *nl_edge;
216 struct hwsim_edge_info *einfo;
217 struct hwsim_edge *e;
218 int ret;
220 ret = nla_put_u32(skb, MAC802154_HWSIM_ATTR_RADIO_ID, phy->idx);
221 if (ret < 0)
222 return ret;
224 rcu_read_lock();
225 if (list_empty(&phy->edges)) {
226 rcu_read_unlock();
227 return 0;
230 nl_edges = nla_nest_start(skb, MAC802154_HWSIM_ATTR_RADIO_EDGES);
231 if (!nl_edges) {
232 rcu_read_unlock();
233 return -ENOBUFS;
236 list_for_each_entry_rcu(e, &phy->edges, list) {
237 nl_edge = nla_nest_start(skb, MAC802154_HWSIM_ATTR_RADIO_EDGE);
238 if (!nl_edge) {
239 rcu_read_unlock();
240 nla_nest_cancel(skb, nl_edges);
241 return -ENOBUFS;
244 ret = nla_put_u32(skb, MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID,
245 e->endpoint->idx);
246 if (ret < 0) {
247 rcu_read_unlock();
248 nla_nest_cancel(skb, nl_edge);
249 nla_nest_cancel(skb, nl_edges);
250 return ret;
253 einfo = rcu_dereference(e->info);
254 ret = nla_put_u8(skb, MAC802154_HWSIM_EDGE_ATTR_LQI,
255 einfo->lqi);
256 if (ret < 0) {
257 rcu_read_unlock();
258 nla_nest_cancel(skb, nl_edge);
259 nla_nest_cancel(skb, nl_edges);
260 return ret;
263 nla_nest_end(skb, nl_edge);
265 rcu_read_unlock();
267 nla_nest_end(skb, nl_edges);
269 return 0;
272 static int hwsim_get_radio(struct sk_buff *skb, struct hwsim_phy *phy,
273 u32 portid, u32 seq,
274 struct netlink_callback *cb, int flags)
276 void *hdr;
277 int res = -EMSGSIZE;
279 hdr = genlmsg_put(skb, portid, seq, &hwsim_genl_family, flags,
280 MAC802154_HWSIM_CMD_GET_RADIO);
281 if (!hdr)
282 return -EMSGSIZE;
284 if (cb)
285 genl_dump_check_consistent(cb, hdr);
287 res = append_radio_msg(skb, phy);
288 if (res < 0)
289 goto out_err;
291 genlmsg_end(skb, hdr);
292 return 0;
294 out_err:
295 genlmsg_cancel(skb, hdr);
296 return res;
299 static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info)
301 struct hwsim_phy *phy;
302 struct sk_buff *skb;
303 int idx, res = -ENODEV;
305 if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID])
306 return -EINVAL;
307 idx = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]);
309 mutex_lock(&hwsim_phys_lock);
310 list_for_each_entry(phy, &hwsim_phys, list) {
311 if (phy->idx != idx)
312 continue;
314 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
315 if (!skb) {
316 res = -ENOMEM;
317 goto out_err;
320 res = hwsim_get_radio(skb, phy, info->snd_portid,
321 info->snd_seq, NULL, 0);
322 if (res < 0) {
323 nlmsg_free(skb);
324 goto out_err;
327 genlmsg_reply(skb, info);
328 break;
331 out_err:
332 mutex_unlock(&hwsim_phys_lock);
334 return res;
337 static int hwsim_dump_radio_nl(struct sk_buff *skb,
338 struct netlink_callback *cb)
340 int idx = cb->args[0];
341 struct hwsim_phy *phy;
342 int res;
344 mutex_lock(&hwsim_phys_lock);
346 if (idx == hwsim_radio_idx)
347 goto done;
349 list_for_each_entry(phy, &hwsim_phys, list) {
350 if (phy->idx < idx)
351 continue;
353 res = hwsim_get_radio(skb, phy, NETLINK_CB(cb->skb).portid,
354 cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
355 if (res < 0)
356 break;
358 idx = phy->idx + 1;
361 cb->args[0] = idx;
363 done:
364 mutex_unlock(&hwsim_phys_lock);
365 return skb->len;
368 /* caller need to held hwsim_phys_lock */
369 static struct hwsim_phy *hwsim_get_radio_by_id(uint32_t idx)
371 struct hwsim_phy *phy;
373 list_for_each_entry(phy, &hwsim_phys, list) {
374 if (phy->idx == idx)
375 return phy;
378 return NULL;
381 static const struct nla_policy hwsim_edge_policy[MAC802154_HWSIM_EDGE_ATTR_MAX + 1] = {
382 [MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID] = { .type = NLA_U32 },
383 [MAC802154_HWSIM_EDGE_ATTR_LQI] = { .type = NLA_U8 },
386 static struct hwsim_edge *hwsim_alloc_edge(struct hwsim_phy *endpoint, u8 lqi)
388 struct hwsim_edge_info *einfo;
389 struct hwsim_edge *e;
391 e = kzalloc(sizeof(*e), GFP_KERNEL);
392 if (!e)
393 return NULL;
395 einfo = kzalloc(sizeof(*einfo), GFP_KERNEL);
396 if (!einfo) {
397 kfree(e);
398 return NULL;
401 einfo->lqi = 0xff;
402 rcu_assign_pointer(e->info, einfo);
403 e->endpoint = endpoint;
405 return e;
408 static void hwsim_free_edge(struct hwsim_edge *e)
410 struct hwsim_edge_info *einfo;
412 rcu_read_lock();
413 einfo = rcu_dereference(e->info);
414 rcu_read_unlock();
416 kfree_rcu(einfo, rcu);
417 kfree_rcu(e, rcu);
420 static int hwsim_new_edge_nl(struct sk_buff *msg, struct genl_info *info)
422 struct nlattr *edge_attrs[MAC802154_HWSIM_EDGE_ATTR_MAX + 1];
423 struct hwsim_phy *phy_v0, *phy_v1;
424 struct hwsim_edge *e;
425 u32 v0, v1;
427 if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] &&
428 !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE])
429 return -EINVAL;
431 if (nla_parse_nested(edge_attrs, MAC802154_HWSIM_EDGE_ATTR_MAX,
432 info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE],
433 hwsim_edge_policy, NULL))
434 return -EINVAL;
436 if (!edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID])
437 return -EINVAL;
439 v0 = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]);
440 v1 = nla_get_u32(edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID]);
442 if (v0 == v1)
443 return -EINVAL;
445 mutex_lock(&hwsim_phys_lock);
446 phy_v0 = hwsim_get_radio_by_id(v0);
447 if (!phy_v0) {
448 mutex_unlock(&hwsim_phys_lock);
449 return -ENOENT;
452 phy_v1 = hwsim_get_radio_by_id(v1);
453 if (!phy_v1) {
454 mutex_unlock(&hwsim_phys_lock);
455 return -ENOENT;
458 rcu_read_lock();
459 list_for_each_entry_rcu(e, &phy_v0->edges, list) {
460 if (e->endpoint->idx == v1) {
461 mutex_unlock(&hwsim_phys_lock);
462 rcu_read_unlock();
463 return -EEXIST;
466 rcu_read_unlock();
468 e = hwsim_alloc_edge(phy_v1, 0xff);
469 if (!e) {
470 mutex_unlock(&hwsim_phys_lock);
471 return -ENOMEM;
473 list_add_rcu(&e->list, &phy_v0->edges);
474 /* wait until changes are done under hwsim_phys_lock lock
475 * should prevent of calling this function twice while
476 * edges list has not the changes yet.
478 synchronize_rcu();
479 mutex_unlock(&hwsim_phys_lock);
481 return 0;
484 static int hwsim_del_edge_nl(struct sk_buff *msg, struct genl_info *info)
486 struct nlattr *edge_attrs[MAC802154_HWSIM_EDGE_ATTR_MAX + 1];
487 struct hwsim_phy *phy_v0;
488 struct hwsim_edge *e;
489 u32 v0, v1;
491 if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] &&
492 !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE])
493 return -EINVAL;
495 if (nla_parse_nested(edge_attrs, MAC802154_HWSIM_EDGE_ATTR_MAX + 1,
496 info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE],
497 hwsim_edge_policy, NULL))
498 return -EINVAL;
500 if (!edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID])
501 return -EINVAL;
503 v0 = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]);
504 v1 = nla_get_u32(edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID]);
506 mutex_lock(&hwsim_phys_lock);
507 phy_v0 = hwsim_get_radio_by_id(v0);
508 if (!phy_v0) {
509 mutex_unlock(&hwsim_phys_lock);
510 return -ENOENT;
513 rcu_read_lock();
514 list_for_each_entry_rcu(e, &phy_v0->edges, list) {
515 if (e->endpoint->idx == v1) {
516 rcu_read_unlock();
517 list_del_rcu(&e->list);
518 hwsim_free_edge(e);
519 /* same again - wait until list changes are done */
520 synchronize_rcu();
521 mutex_unlock(&hwsim_phys_lock);
522 return 0;
525 rcu_read_unlock();
527 mutex_unlock(&hwsim_phys_lock);
529 return -ENOENT;
532 static int hwsim_set_edge_lqi(struct sk_buff *msg, struct genl_info *info)
534 struct nlattr *edge_attrs[MAC802154_HWSIM_EDGE_ATTR_MAX + 1];
535 struct hwsim_edge_info *einfo;
536 struct hwsim_phy *phy_v0;
537 struct hwsim_edge *e;
538 u32 v0, v1;
539 u8 lqi;
541 if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] &&
542 !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE])
543 return -EINVAL;
545 if (nla_parse_nested(edge_attrs, MAC802154_HWSIM_EDGE_ATTR_MAX + 1,
546 info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE],
547 hwsim_edge_policy, NULL))
548 return -EINVAL;
550 if (!edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID] &&
551 !edge_attrs[MAC802154_HWSIM_EDGE_ATTR_LQI])
552 return -EINVAL;
554 v0 = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]);
555 v1 = nla_get_u32(edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID]);
556 lqi = nla_get_u8(edge_attrs[MAC802154_HWSIM_EDGE_ATTR_LQI]);
558 mutex_lock(&hwsim_phys_lock);
559 phy_v0 = hwsim_get_radio_by_id(v0);
560 if (!phy_v0) {
561 mutex_unlock(&hwsim_phys_lock);
562 return -ENOENT;
565 einfo = kzalloc(sizeof(*einfo), GFP_KERNEL);
566 if (!einfo) {
567 mutex_unlock(&hwsim_phys_lock);
568 return -ENOMEM;
571 rcu_read_lock();
572 list_for_each_entry_rcu(e, &phy_v0->edges, list) {
573 if (e->endpoint->idx == v1) {
574 einfo->lqi = lqi;
575 rcu_assign_pointer(e->info, einfo);
576 rcu_read_unlock();
577 mutex_unlock(&hwsim_phys_lock);
578 return 0;
581 rcu_read_unlock();
583 kfree(einfo);
584 mutex_unlock(&hwsim_phys_lock);
586 return -ENOENT;
589 /* MAC802154_HWSIM netlink policy */
591 static const struct nla_policy hwsim_genl_policy[MAC802154_HWSIM_ATTR_MAX + 1] = {
592 [MAC802154_HWSIM_ATTR_RADIO_ID] = { .type = NLA_U32 },
593 [MAC802154_HWSIM_ATTR_RADIO_EDGE] = { .type = NLA_NESTED },
594 [MAC802154_HWSIM_ATTR_RADIO_EDGES] = { .type = NLA_NESTED },
597 /* Generic Netlink operations array */
598 static const struct genl_ops hwsim_nl_ops[] = {
600 .cmd = MAC802154_HWSIM_CMD_NEW_RADIO,
601 .policy = hwsim_genl_policy,
602 .doit = hwsim_new_radio_nl,
603 .flags = GENL_UNS_ADMIN_PERM,
606 .cmd = MAC802154_HWSIM_CMD_DEL_RADIO,
607 .policy = hwsim_genl_policy,
608 .doit = hwsim_del_radio_nl,
609 .flags = GENL_UNS_ADMIN_PERM,
612 .cmd = MAC802154_HWSIM_CMD_GET_RADIO,
613 .policy = hwsim_genl_policy,
614 .doit = hwsim_get_radio_nl,
615 .dumpit = hwsim_dump_radio_nl,
618 .cmd = MAC802154_HWSIM_CMD_NEW_EDGE,
619 .policy = hwsim_genl_policy,
620 .doit = hwsim_new_edge_nl,
621 .flags = GENL_UNS_ADMIN_PERM,
624 .cmd = MAC802154_HWSIM_CMD_DEL_EDGE,
625 .policy = hwsim_genl_policy,
626 .doit = hwsim_del_edge_nl,
627 .flags = GENL_UNS_ADMIN_PERM,
630 .cmd = MAC802154_HWSIM_CMD_SET_EDGE,
631 .policy = hwsim_genl_policy,
632 .doit = hwsim_set_edge_lqi,
633 .flags = GENL_UNS_ADMIN_PERM,
637 static struct genl_family hwsim_genl_family __ro_after_init = {
638 .name = "MAC802154_HWSIM",
639 .version = 1,
640 .maxattr = MAC802154_HWSIM_ATTR_MAX,
641 .module = THIS_MODULE,
642 .ops = hwsim_nl_ops,
643 .n_ops = ARRAY_SIZE(hwsim_nl_ops),
644 .mcgrps = hwsim_mcgrps,
645 .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps),
648 static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
649 struct genl_info *info)
651 if (info)
652 genl_notify(&hwsim_genl_family, mcast_skb, info,
653 HWSIM_MCGRP_CONFIG, GFP_KERNEL);
654 else
655 genlmsg_multicast(&hwsim_genl_family, mcast_skb, 0,
656 HWSIM_MCGRP_CONFIG, GFP_KERNEL);
659 static void hwsim_mcast_new_radio(struct genl_info *info, struct hwsim_phy *phy)
661 struct sk_buff *mcast_skb;
662 void *data;
664 mcast_skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
665 if (!mcast_skb)
666 return;
668 data = genlmsg_put(mcast_skb, 0, 0, &hwsim_genl_family, 0,
669 MAC802154_HWSIM_CMD_NEW_RADIO);
670 if (!data)
671 goto out_err;
673 if (append_radio_msg(mcast_skb, phy) < 0)
674 goto out_err;
676 genlmsg_end(mcast_skb, data);
678 hwsim_mcast_config_msg(mcast_skb, info);
679 return;
681 out_err:
682 genlmsg_cancel(mcast_skb, data);
683 nlmsg_free(mcast_skb);
686 static void hwsim_edge_unsubscribe_me(struct hwsim_phy *phy)
688 struct hwsim_phy *tmp;
689 struct hwsim_edge *e;
691 rcu_read_lock();
692 /* going to all phy edges and remove phy from it */
693 list_for_each_entry(tmp, &hwsim_phys, list) {
694 list_for_each_entry_rcu(e, &tmp->edges, list) {
695 if (e->endpoint->idx == phy->idx) {
696 list_del_rcu(&e->list);
697 hwsim_free_edge(e);
701 rcu_read_unlock();
703 synchronize_rcu();
706 static int hwsim_subscribe_all_others(struct hwsim_phy *phy)
708 struct hwsim_phy *sub;
709 struct hwsim_edge *e;
711 list_for_each_entry(sub, &hwsim_phys, list) {
712 e = hwsim_alloc_edge(sub, 0xff);
713 if (!e)
714 goto me_fail;
716 list_add_rcu(&e->list, &phy->edges);
719 list_for_each_entry(sub, &hwsim_phys, list) {
720 e = hwsim_alloc_edge(phy, 0xff);
721 if (!e)
722 goto sub_fail;
724 list_add_rcu(&e->list, &sub->edges);
727 return 0;
729 me_fail:
730 rcu_read_lock();
731 list_for_each_entry_rcu(e, &phy->edges, list) {
732 list_del_rcu(&e->list);
733 hwsim_free_edge(e);
735 rcu_read_unlock();
736 sub_fail:
737 hwsim_edge_unsubscribe_me(phy);
738 return -ENOMEM;
741 static int hwsim_add_one(struct genl_info *info, struct device *dev,
742 bool init)
744 struct ieee802154_hw *hw;
745 struct hwsim_phy *phy;
746 struct hwsim_pib *pib;
747 int idx;
748 int err;
750 idx = hwsim_radio_idx++;
752 hw = ieee802154_alloc_hw(sizeof(*phy), &hwsim_ops);
753 if (!hw)
754 return -ENOMEM;
756 phy = hw->priv;
757 phy->hw = hw;
759 /* 868 MHz BPSK 802.15.4-2003 */
760 hw->phy->supported.channels[0] |= 1;
761 /* 915 MHz BPSK 802.15.4-2003 */
762 hw->phy->supported.channels[0] |= 0x7fe;
763 /* 2.4 GHz O-QPSK 802.15.4-2003 */
764 hw->phy->supported.channels[0] |= 0x7FFF800;
765 /* 868 MHz ASK 802.15.4-2006 */
766 hw->phy->supported.channels[1] |= 1;
767 /* 915 MHz ASK 802.15.4-2006 */
768 hw->phy->supported.channels[1] |= 0x7fe;
769 /* 868 MHz O-QPSK 802.15.4-2006 */
770 hw->phy->supported.channels[2] |= 1;
771 /* 915 MHz O-QPSK 802.15.4-2006 */
772 hw->phy->supported.channels[2] |= 0x7fe;
773 /* 2.4 GHz CSS 802.15.4a-2007 */
774 hw->phy->supported.channels[3] |= 0x3fff;
775 /* UWB Sub-gigahertz 802.15.4a-2007 */
776 hw->phy->supported.channels[4] |= 1;
777 /* UWB Low band 802.15.4a-2007 */
778 hw->phy->supported.channels[4] |= 0x1e;
779 /* UWB High band 802.15.4a-2007 */
780 hw->phy->supported.channels[4] |= 0xffe0;
781 /* 750 MHz O-QPSK 802.15.4c-2009 */
782 hw->phy->supported.channels[5] |= 0xf;
783 /* 750 MHz MPSK 802.15.4c-2009 */
784 hw->phy->supported.channels[5] |= 0xf0;
785 /* 950 MHz BPSK 802.15.4d-2009 */
786 hw->phy->supported.channels[6] |= 0x3ff;
787 /* 950 MHz GFSK 802.15.4d-2009 */
788 hw->phy->supported.channels[6] |= 0x3ffc00;
790 ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
792 /* hwsim phy channel 13 as default */
793 hw->phy->current_channel = 13;
794 pib = kzalloc(sizeof(*pib), GFP_KERNEL);
795 if (!pib) {
796 err = -ENOMEM;
797 goto err_pib;
800 rcu_assign_pointer(phy->pib, pib);
801 phy->idx = idx;
802 INIT_LIST_HEAD(&phy->edges);
804 hw->flags = IEEE802154_HW_PROMISCUOUS;
805 hw->parent = dev;
807 err = ieee802154_register_hw(hw);
808 if (err)
809 goto err_reg;
811 mutex_lock(&hwsim_phys_lock);
812 if (init) {
813 err = hwsim_subscribe_all_others(phy);
814 if (err < 0) {
815 mutex_unlock(&hwsim_phys_lock);
816 goto err_reg;
819 list_add_tail(&phy->list, &hwsim_phys);
820 mutex_unlock(&hwsim_phys_lock);
822 hwsim_mcast_new_radio(info, phy);
824 return idx;
826 err_reg:
827 kfree(pib);
828 err_pib:
829 ieee802154_free_hw(phy->hw);
830 return err;
833 static void hwsim_del(struct hwsim_phy *phy)
835 struct hwsim_pib *pib;
837 hwsim_edge_unsubscribe_me(phy);
839 list_del(&phy->list);
841 rcu_read_lock();
842 pib = rcu_dereference(phy->pib);
843 rcu_read_unlock();
845 kfree_rcu(pib, rcu);
847 ieee802154_unregister_hw(phy->hw);
848 ieee802154_free_hw(phy->hw);
851 static int hwsim_probe(struct platform_device *pdev)
853 struct hwsim_phy *phy, *tmp;
854 int err, i;
856 for (i = 0; i < 2; i++) {
857 err = hwsim_add_one(NULL, &pdev->dev, true);
858 if (err < 0)
859 goto err_slave;
862 dev_info(&pdev->dev, "Added 2 mac802154 hwsim hardware radios\n");
863 return 0;
865 err_slave:
866 mutex_lock(&hwsim_phys_lock);
867 list_for_each_entry_safe(phy, tmp, &hwsim_phys, list)
868 hwsim_del(phy);
869 mutex_unlock(&hwsim_phys_lock);
870 return err;
873 static int hwsim_remove(struct platform_device *pdev)
875 struct hwsim_phy *phy, *tmp;
877 mutex_lock(&hwsim_phys_lock);
878 list_for_each_entry_safe(phy, tmp, &hwsim_phys, list)
879 hwsim_del(phy);
880 mutex_unlock(&hwsim_phys_lock);
882 return 0;
885 static struct platform_driver mac802154hwsim_driver = {
886 .probe = hwsim_probe,
887 .remove = hwsim_remove,
888 .driver = {
889 .name = "mac802154_hwsim",
893 static __init int hwsim_init_module(void)
895 int rc;
897 rc = genl_register_family(&hwsim_genl_family);
898 if (rc)
899 return rc;
901 mac802154hwsim_dev = platform_device_register_simple("mac802154_hwsim",
902 -1, NULL, 0);
903 if (IS_ERR(mac802154hwsim_dev)) {
904 rc = PTR_ERR(mac802154hwsim_dev);
905 goto platform_dev;
908 rc = platform_driver_register(&mac802154hwsim_driver);
909 if (rc < 0)
910 goto platform_drv;
912 return 0;
914 platform_drv:
915 genl_unregister_family(&hwsim_genl_family);
916 platform_dev:
917 platform_device_unregister(mac802154hwsim_dev);
918 return rc;
921 static __exit void hwsim_remove_module(void)
923 genl_unregister_family(&hwsim_genl_family);
924 platform_driver_unregister(&mac802154hwsim_driver);
925 platform_device_unregister(mac802154hwsim_dev);
928 module_init(hwsim_init_module);
929 module_exit(hwsim_remove_module);