Linux-libre 5.4.49-gnu
[librecmc/linux-libre.git] / drivers / net / ieee802154 / mac802154_hwsim.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * HWSIM IEEE 802.15.4 interface
4  *
5  * (C) 2018 Mojatau, Alexander Aring <aring@mojatau.com>
6  * Copyright 2007-2012 Siemens AG
7  *
8  * Based on fakelb, original Written by:
9  * Sergey Lapin <slapin@ossfans.org>
10  * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
11  * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
12  */
13
14 #include <linux/module.h>
15 #include <linux/timer.h>
16 #include <linux/platform_device.h>
17 #include <linux/rtnetlink.h>
18 #include <linux/netdevice.h>
19 #include <linux/device.h>
20 #include <linux/spinlock.h>
21 #include <net/mac802154.h>
22 #include <net/cfg802154.h>
23 #include <net/genetlink.h>
24 #include "mac802154_hwsim.h"
25
26 MODULE_DESCRIPTION("Software simulator of IEEE 802.15.4 radio(s) for mac802154");
27 MODULE_LICENSE("GPL");
28
29 static LIST_HEAD(hwsim_phys);
30 static DEFINE_MUTEX(hwsim_phys_lock);
31
32 static struct platform_device *mac802154hwsim_dev;
33
34 /* MAC802154_HWSIM netlink family */
35 static struct genl_family hwsim_genl_family;
36
37 static int hwsim_radio_idx;
38
39 enum hwsim_multicast_groups {
40         HWSIM_MCGRP_CONFIG,
41 };
42
43 static const struct genl_multicast_group hwsim_mcgrps[] = {
44         [HWSIM_MCGRP_CONFIG] = { .name = "config", },
45 };
46
47 struct hwsim_pib {
48         u8 page;
49         u8 channel;
50
51         struct rcu_head rcu;
52 };
53
54 struct hwsim_edge_info {
55         u8 lqi;
56
57         struct rcu_head rcu;
58 };
59
60 struct hwsim_edge {
61         struct hwsim_phy *endpoint;
62         struct hwsim_edge_info __rcu *info;
63
64         struct list_head list;
65         struct rcu_head rcu;
66 };
67
68 struct hwsim_phy {
69         struct ieee802154_hw *hw;
70         u32 idx;
71
72         struct hwsim_pib __rcu *pib;
73
74         bool suspended;
75         struct list_head edges;
76
77         struct list_head list;
78 };
79
80 static int hwsim_add_one(struct genl_info *info, struct device *dev,
81                          bool init);
82 static void hwsim_del(struct hwsim_phy *phy);
83
84 static int hwsim_hw_ed(struct ieee802154_hw *hw, u8 *level)
85 {
86         *level = 0xbe;
87
88         return 0;
89 }
90
91 static int hwsim_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
92 {
93         struct hwsim_phy *phy = hw->priv;
94         struct hwsim_pib *pib, *pib_old;
95
96         pib = kzalloc(sizeof(*pib), GFP_KERNEL);
97         if (!pib)
98                 return -ENOMEM;
99
100         pib->page = page;
101         pib->channel = channel;
102
103         pib_old = rtnl_dereference(phy->pib);
104         rcu_assign_pointer(phy->pib, pib);
105         kfree_rcu(pib_old, rcu);
106         return 0;
107 }
108
109 static int hwsim_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
110 {
111         struct hwsim_phy *current_phy = hw->priv;
112         struct hwsim_pib *current_pib, *endpoint_pib;
113         struct hwsim_edge_info *einfo;
114         struct hwsim_edge *e;
115
116         WARN_ON(current_phy->suspended);
117
118         rcu_read_lock();
119         current_pib = rcu_dereference(current_phy->pib);
120         list_for_each_entry_rcu(e, &current_phy->edges, list) {
121                 /* Can be changed later in rx_irqsafe, but this is only a
122                  * performance tweak. Received radio should drop the frame
123                  * in mac802154 stack anyway... so we don't need to be
124                  * 100% of locking here to check on suspended
125                  */
126                 if (e->endpoint->suspended)
127                         continue;
128
129                 endpoint_pib = rcu_dereference(e->endpoint->pib);
130                 if (current_pib->page == endpoint_pib->page &&
131                     current_pib->channel == endpoint_pib->channel) {
132                         struct sk_buff *newskb = pskb_copy(skb, GFP_ATOMIC);
133
134                         einfo = rcu_dereference(e->info);
135                         if (newskb)
136                                 ieee802154_rx_irqsafe(e->endpoint->hw, newskb,
137                                                       einfo->lqi);
138                 }
139         }
140         rcu_read_unlock();
141
142         ieee802154_xmit_complete(hw, skb, false);
143         return 0;
144 }
145
146 static int hwsim_hw_start(struct ieee802154_hw *hw)
147 {
148         struct hwsim_phy *phy = hw->priv;
149
150         phy->suspended = false;
151         return 0;
152 }
153
154 static void hwsim_hw_stop(struct ieee802154_hw *hw)
155 {
156         struct hwsim_phy *phy = hw->priv;
157
158         phy->suspended = true;
159 }
160
161 static int
162 hwsim_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on)
163 {
164         return 0;
165 }
166
167 static const struct ieee802154_ops hwsim_ops = {
168         .owner = THIS_MODULE,
169         .xmit_async = hwsim_hw_xmit,
170         .ed = hwsim_hw_ed,
171         .set_channel = hwsim_hw_channel,
172         .start = hwsim_hw_start,
173         .stop = hwsim_hw_stop,
174         .set_promiscuous_mode = hwsim_set_promiscuous_mode,
175 };
176
177 static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
178 {
179         return hwsim_add_one(info, &mac802154hwsim_dev->dev, false);
180 }
181
182 static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
183 {
184         struct hwsim_phy *phy, *tmp;
185         s64 idx = -1;
186
187         if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID])
188                 return -EINVAL;
189
190         idx = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]);
191
192         mutex_lock(&hwsim_phys_lock);
193         list_for_each_entry_safe(phy, tmp, &hwsim_phys, list) {
194                 if (idx == phy->idx) {
195                         hwsim_del(phy);
196                         mutex_unlock(&hwsim_phys_lock);
197                         return 0;
198                 }
199         }
200         mutex_unlock(&hwsim_phys_lock);
201
202         return -ENODEV;
203 }
204
205 static int append_radio_msg(struct sk_buff *skb, struct hwsim_phy *phy)
206 {
207         struct nlattr *nl_edges, *nl_edge;
208         struct hwsim_edge_info *einfo;
209         struct hwsim_edge *e;
210         int ret;
211
212         ret = nla_put_u32(skb, MAC802154_HWSIM_ATTR_RADIO_ID, phy->idx);
213         if (ret < 0)
214                 return ret;
215
216         rcu_read_lock();
217         if (list_empty(&phy->edges)) {
218                 rcu_read_unlock();
219                 return 0;
220         }
221
222         nl_edges = nla_nest_start_noflag(skb,
223                                          MAC802154_HWSIM_ATTR_RADIO_EDGES);
224         if (!nl_edges) {
225                 rcu_read_unlock();
226                 return -ENOBUFS;
227         }
228
229         list_for_each_entry_rcu(e, &phy->edges, list) {
230                 nl_edge = nla_nest_start_noflag(skb,
231                                                 MAC802154_HWSIM_ATTR_RADIO_EDGE);
232                 if (!nl_edge) {
233                         rcu_read_unlock();
234                         nla_nest_cancel(skb, nl_edges);
235                         return -ENOBUFS;
236                 }
237
238                 ret = nla_put_u32(skb, MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID,
239                                   e->endpoint->idx);
240                 if (ret < 0) {
241                         rcu_read_unlock();
242                         nla_nest_cancel(skb, nl_edge);
243                         nla_nest_cancel(skb, nl_edges);
244                         return ret;
245                 }
246
247                 einfo = rcu_dereference(e->info);
248                 ret = nla_put_u8(skb, MAC802154_HWSIM_EDGE_ATTR_LQI,
249                                  einfo->lqi);
250                 if (ret < 0) {
251                         rcu_read_unlock();
252                         nla_nest_cancel(skb, nl_edge);
253                         nla_nest_cancel(skb, nl_edges);
254                         return ret;
255                 }
256
257                 nla_nest_end(skb, nl_edge);
258         }
259         rcu_read_unlock();
260
261         nla_nest_end(skb, nl_edges);
262
263         return 0;
264 }
265
266 static int hwsim_get_radio(struct sk_buff *skb, struct hwsim_phy *phy,
267                            u32 portid, u32 seq,
268                            struct netlink_callback *cb, int flags)
269 {
270         void *hdr;
271         int res = -EMSGSIZE;
272
273         hdr = genlmsg_put(skb, portid, seq, &hwsim_genl_family, flags,
274                           MAC802154_HWSIM_CMD_GET_RADIO);
275         if (!hdr)
276                 return -EMSGSIZE;
277
278         if (cb)
279                 genl_dump_check_consistent(cb, hdr);
280
281         res = append_radio_msg(skb, phy);
282         if (res < 0)
283                 goto out_err;
284
285         genlmsg_end(skb, hdr);
286         return 0;
287
288 out_err:
289         genlmsg_cancel(skb, hdr);
290         return res;
291 }
292
293 static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info)
294 {
295         struct hwsim_phy *phy;
296         struct sk_buff *skb;
297         int idx, res = -ENODEV;
298
299         if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID])
300                 return -EINVAL;
301         idx = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]);
302
303         mutex_lock(&hwsim_phys_lock);
304         list_for_each_entry(phy, &hwsim_phys, list) {
305                 if (phy->idx != idx)
306                         continue;
307
308                 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
309                 if (!skb) {
310                         res = -ENOMEM;
311                         goto out_err;
312                 }
313
314                 res = hwsim_get_radio(skb, phy, info->snd_portid,
315                                       info->snd_seq, NULL, 0);
316                 if (res < 0) {
317                         nlmsg_free(skb);
318                         goto out_err;
319                 }
320
321                 res = genlmsg_reply(skb, info);
322                 break;
323         }
324
325 out_err:
326         mutex_unlock(&hwsim_phys_lock);
327
328         return res;
329 }
330
331 static int hwsim_dump_radio_nl(struct sk_buff *skb,
332                                struct netlink_callback *cb)
333 {
334         int idx = cb->args[0];
335         struct hwsim_phy *phy;
336         int res;
337
338         mutex_lock(&hwsim_phys_lock);
339
340         if (idx == hwsim_radio_idx)
341                 goto done;
342
343         list_for_each_entry(phy, &hwsim_phys, list) {
344                 if (phy->idx < idx)
345                         continue;
346
347                 res = hwsim_get_radio(skb, phy, NETLINK_CB(cb->skb).portid,
348                                       cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
349                 if (res < 0)
350                         break;
351
352                 idx = phy->idx + 1;
353         }
354
355         cb->args[0] = idx;
356
357 done:
358         mutex_unlock(&hwsim_phys_lock);
359         return skb->len;
360 }
361
362 /* caller need to held hwsim_phys_lock */
363 static struct hwsim_phy *hwsim_get_radio_by_id(uint32_t idx)
364 {
365         struct hwsim_phy *phy;
366
367         list_for_each_entry(phy, &hwsim_phys, list) {
368                 if (phy->idx == idx)
369                         return phy;
370         }
371
372         return NULL;
373 }
374
375 static const struct nla_policy hwsim_edge_policy[MAC802154_HWSIM_EDGE_ATTR_MAX + 1] = {
376         [MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID] = { .type = NLA_U32 },
377         [MAC802154_HWSIM_EDGE_ATTR_LQI] = { .type = NLA_U8 },
378 };
379
380 static struct hwsim_edge *hwsim_alloc_edge(struct hwsim_phy *endpoint, u8 lqi)
381 {
382         struct hwsim_edge_info *einfo;
383         struct hwsim_edge *e;
384
385         e = kzalloc(sizeof(*e), GFP_KERNEL);
386         if (!e)
387                 return NULL;
388
389         einfo = kzalloc(sizeof(*einfo), GFP_KERNEL);
390         if (!einfo) {
391                 kfree(e);
392                 return NULL;
393         }
394
395         einfo->lqi = 0xff;
396         rcu_assign_pointer(e->info, einfo);
397         e->endpoint = endpoint;
398
399         return e;
400 }
401
402 static void hwsim_free_edge(struct hwsim_edge *e)
403 {
404         struct hwsim_edge_info *einfo;
405
406         rcu_read_lock();
407         einfo = rcu_dereference(e->info);
408         rcu_read_unlock();
409
410         kfree_rcu(einfo, rcu);
411         kfree_rcu(e, rcu);
412 }
413
414 static int hwsim_new_edge_nl(struct sk_buff *msg, struct genl_info *info)
415 {
416         struct nlattr *edge_attrs[MAC802154_HWSIM_EDGE_ATTR_MAX + 1];
417         struct hwsim_phy *phy_v0, *phy_v1;
418         struct hwsim_edge *e;
419         u32 v0, v1;
420
421         if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] &&
422             !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE])
423                 return -EINVAL;
424
425         if (nla_parse_nested_deprecated(edge_attrs, MAC802154_HWSIM_EDGE_ATTR_MAX, info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE], hwsim_edge_policy, NULL))
426                 return -EINVAL;
427
428         if (!edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID])
429                 return -EINVAL;
430
431         v0 = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]);
432         v1 = nla_get_u32(edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID]);
433
434         if (v0 == v1)
435                 return -EINVAL;
436
437         mutex_lock(&hwsim_phys_lock);
438         phy_v0 = hwsim_get_radio_by_id(v0);
439         if (!phy_v0) {
440                 mutex_unlock(&hwsim_phys_lock);
441                 return -ENOENT;
442         }
443
444         phy_v1 = hwsim_get_radio_by_id(v1);
445         if (!phy_v1) {
446                 mutex_unlock(&hwsim_phys_lock);
447                 return -ENOENT;
448         }
449
450         rcu_read_lock();
451         list_for_each_entry_rcu(e, &phy_v0->edges, list) {
452                 if (e->endpoint->idx == v1) {
453                         mutex_unlock(&hwsim_phys_lock);
454                         rcu_read_unlock();
455                         return -EEXIST;
456                 }
457         }
458         rcu_read_unlock();
459
460         e = hwsim_alloc_edge(phy_v1, 0xff);
461         if (!e) {
462                 mutex_unlock(&hwsim_phys_lock);
463                 return -ENOMEM;
464         }
465         list_add_rcu(&e->list, &phy_v0->edges);
466         /* wait until changes are done under hwsim_phys_lock lock
467          * should prevent of calling this function twice while
468          * edges list has not the changes yet.
469          */
470         synchronize_rcu();
471         mutex_unlock(&hwsim_phys_lock);
472
473         return 0;
474 }
475
476 static int hwsim_del_edge_nl(struct sk_buff *msg, struct genl_info *info)
477 {
478         struct nlattr *edge_attrs[MAC802154_HWSIM_EDGE_ATTR_MAX + 1];
479         struct hwsim_phy *phy_v0;
480         struct hwsim_edge *e;
481         u32 v0, v1;
482
483         if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] &&
484             !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE])
485                 return -EINVAL;
486
487         if (nla_parse_nested_deprecated(edge_attrs, MAC802154_HWSIM_EDGE_ATTR_MAX, info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE], hwsim_edge_policy, NULL))
488                 return -EINVAL;
489
490         if (!edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID])
491                 return -EINVAL;
492
493         v0 = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]);
494         v1 = nla_get_u32(edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID]);
495
496         mutex_lock(&hwsim_phys_lock);
497         phy_v0 = hwsim_get_radio_by_id(v0);
498         if (!phy_v0) {
499                 mutex_unlock(&hwsim_phys_lock);
500                 return -ENOENT;
501         }
502
503         rcu_read_lock();
504         list_for_each_entry_rcu(e, &phy_v0->edges, list) {
505                 if (e->endpoint->idx == v1) {
506                         rcu_read_unlock();
507                         list_del_rcu(&e->list);
508                         hwsim_free_edge(e);
509                         /* same again - wait until list changes are done */
510                         synchronize_rcu();
511                         mutex_unlock(&hwsim_phys_lock);
512                         return 0;
513                 }
514         }
515         rcu_read_unlock();
516
517         mutex_unlock(&hwsim_phys_lock);
518
519         return -ENOENT;
520 }
521
522 static int hwsim_set_edge_lqi(struct sk_buff *msg, struct genl_info *info)
523 {
524         struct nlattr *edge_attrs[MAC802154_HWSIM_EDGE_ATTR_MAX + 1];
525         struct hwsim_edge_info *einfo;
526         struct hwsim_phy *phy_v0;
527         struct hwsim_edge *e;
528         u32 v0, v1;
529         u8 lqi;
530
531         if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] &&
532             !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE])
533                 return -EINVAL;
534
535         if (nla_parse_nested_deprecated(edge_attrs, MAC802154_HWSIM_EDGE_ATTR_MAX, info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE], hwsim_edge_policy, NULL))
536                 return -EINVAL;
537
538         if (!edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID] &&
539             !edge_attrs[MAC802154_HWSIM_EDGE_ATTR_LQI])
540                 return -EINVAL;
541
542         v0 = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]);
543         v1 = nla_get_u32(edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID]);
544         lqi = nla_get_u8(edge_attrs[MAC802154_HWSIM_EDGE_ATTR_LQI]);
545
546         mutex_lock(&hwsim_phys_lock);
547         phy_v0 = hwsim_get_radio_by_id(v0);
548         if (!phy_v0) {
549                 mutex_unlock(&hwsim_phys_lock);
550                 return -ENOENT;
551         }
552
553         einfo = kzalloc(sizeof(*einfo), GFP_KERNEL);
554         if (!einfo) {
555                 mutex_unlock(&hwsim_phys_lock);
556                 return -ENOMEM;
557         }
558
559         rcu_read_lock();
560         list_for_each_entry_rcu(e, &phy_v0->edges, list) {
561                 if (e->endpoint->idx == v1) {
562                         einfo->lqi = lqi;
563                         rcu_assign_pointer(e->info, einfo);
564                         rcu_read_unlock();
565                         mutex_unlock(&hwsim_phys_lock);
566                         return 0;
567                 }
568         }
569         rcu_read_unlock();
570
571         kfree(einfo);
572         mutex_unlock(&hwsim_phys_lock);
573
574         return -ENOENT;
575 }
576
577 /* MAC802154_HWSIM netlink policy */
578
579 static const struct nla_policy hwsim_genl_policy[MAC802154_HWSIM_ATTR_MAX + 1] = {
580         [MAC802154_HWSIM_ATTR_RADIO_ID] = { .type = NLA_U32 },
581         [MAC802154_HWSIM_ATTR_RADIO_EDGE] = { .type = NLA_NESTED },
582         [MAC802154_HWSIM_ATTR_RADIO_EDGES] = { .type = NLA_NESTED },
583 };
584
585 /* Generic Netlink operations array */
586 static const struct genl_ops hwsim_nl_ops[] = {
587         {
588                 .cmd = MAC802154_HWSIM_CMD_NEW_RADIO,
589                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
590                 .doit = hwsim_new_radio_nl,
591                 .flags = GENL_UNS_ADMIN_PERM,
592         },
593         {
594                 .cmd = MAC802154_HWSIM_CMD_DEL_RADIO,
595                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
596                 .doit = hwsim_del_radio_nl,
597                 .flags = GENL_UNS_ADMIN_PERM,
598         },
599         {
600                 .cmd = MAC802154_HWSIM_CMD_GET_RADIO,
601                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
602                 .doit = hwsim_get_radio_nl,
603                 .dumpit = hwsim_dump_radio_nl,
604         },
605         {
606                 .cmd = MAC802154_HWSIM_CMD_NEW_EDGE,
607                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
608                 .doit = hwsim_new_edge_nl,
609                 .flags = GENL_UNS_ADMIN_PERM,
610         },
611         {
612                 .cmd = MAC802154_HWSIM_CMD_DEL_EDGE,
613                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
614                 .doit = hwsim_del_edge_nl,
615                 .flags = GENL_UNS_ADMIN_PERM,
616         },
617         {
618                 .cmd = MAC802154_HWSIM_CMD_SET_EDGE,
619                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
620                 .doit = hwsim_set_edge_lqi,
621                 .flags = GENL_UNS_ADMIN_PERM,
622         },
623 };
624
625 static struct genl_family hwsim_genl_family __ro_after_init = {
626         .name = "MAC802154_HWSIM",
627         .version = 1,
628         .maxattr = MAC802154_HWSIM_ATTR_MAX,
629         .policy = hwsim_genl_policy,
630         .module = THIS_MODULE,
631         .ops = hwsim_nl_ops,
632         .n_ops = ARRAY_SIZE(hwsim_nl_ops),
633         .mcgrps = hwsim_mcgrps,
634         .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps),
635 };
636
637 static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
638                                    struct genl_info *info)
639 {
640         if (info)
641                 genl_notify(&hwsim_genl_family, mcast_skb, info,
642                             HWSIM_MCGRP_CONFIG, GFP_KERNEL);
643         else
644                 genlmsg_multicast(&hwsim_genl_family, mcast_skb, 0,
645                                   HWSIM_MCGRP_CONFIG, GFP_KERNEL);
646 }
647
648 static void hwsim_mcast_new_radio(struct genl_info *info, struct hwsim_phy *phy)
649 {
650         struct sk_buff *mcast_skb;
651         void *data;
652
653         mcast_skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
654         if (!mcast_skb)
655                 return;
656
657         data = genlmsg_put(mcast_skb, 0, 0, &hwsim_genl_family, 0,
658                            MAC802154_HWSIM_CMD_NEW_RADIO);
659         if (!data)
660                 goto out_err;
661
662         if (append_radio_msg(mcast_skb, phy) < 0)
663                 goto out_err;
664
665         genlmsg_end(mcast_skb, data);
666
667         hwsim_mcast_config_msg(mcast_skb, info);
668         return;
669
670 out_err:
671         genlmsg_cancel(mcast_skb, data);
672         nlmsg_free(mcast_skb);
673 }
674
675 static void hwsim_edge_unsubscribe_me(struct hwsim_phy *phy)
676 {
677         struct hwsim_phy *tmp;
678         struct hwsim_edge *e;
679
680         rcu_read_lock();
681         /* going to all phy edges and remove phy from it */
682         list_for_each_entry(tmp, &hwsim_phys, list) {
683                 list_for_each_entry_rcu(e, &tmp->edges, list) {
684                         if (e->endpoint->idx == phy->idx) {
685                                 list_del_rcu(&e->list);
686                                 hwsim_free_edge(e);
687                         }
688                 }
689         }
690         rcu_read_unlock();
691
692         synchronize_rcu();
693 }
694
695 static int hwsim_subscribe_all_others(struct hwsim_phy *phy)
696 {
697         struct hwsim_phy *sub;
698         struct hwsim_edge *e;
699
700         list_for_each_entry(sub, &hwsim_phys, list) {
701                 e = hwsim_alloc_edge(sub, 0xff);
702                 if (!e)
703                         goto me_fail;
704
705                 list_add_rcu(&e->list, &phy->edges);
706         }
707
708         list_for_each_entry(sub, &hwsim_phys, list) {
709                 e = hwsim_alloc_edge(phy, 0xff);
710                 if (!e)
711                         goto sub_fail;
712
713                 list_add_rcu(&e->list, &sub->edges);
714         }
715
716         return 0;
717
718 me_fail:
719         rcu_read_lock();
720         list_for_each_entry_rcu(e, &phy->edges, list) {
721                 list_del_rcu(&e->list);
722                 hwsim_free_edge(e);
723         }
724         rcu_read_unlock();
725 sub_fail:
726         hwsim_edge_unsubscribe_me(phy);
727         return -ENOMEM;
728 }
729
730 static int hwsim_add_one(struct genl_info *info, struct device *dev,
731                          bool init)
732 {
733         struct ieee802154_hw *hw;
734         struct hwsim_phy *phy;
735         struct hwsim_pib *pib;
736         int idx;
737         int err;
738
739         idx = hwsim_radio_idx++;
740
741         hw = ieee802154_alloc_hw(sizeof(*phy), &hwsim_ops);
742         if (!hw)
743                 return -ENOMEM;
744
745         phy = hw->priv;
746         phy->hw = hw;
747
748         /* 868 MHz BPSK 802.15.4-2003 */
749         hw->phy->supported.channels[0] |= 1;
750         /* 915 MHz BPSK 802.15.4-2003 */
751         hw->phy->supported.channels[0] |= 0x7fe;
752         /* 2.4 GHz O-QPSK 802.15.4-2003 */
753         hw->phy->supported.channels[0] |= 0x7FFF800;
754         /* 868 MHz ASK 802.15.4-2006 */
755         hw->phy->supported.channels[1] |= 1;
756         /* 915 MHz ASK 802.15.4-2006 */
757         hw->phy->supported.channels[1] |= 0x7fe;
758         /* 868 MHz O-QPSK 802.15.4-2006 */
759         hw->phy->supported.channels[2] |= 1;
760         /* 915 MHz O-QPSK 802.15.4-2006 */
761         hw->phy->supported.channels[2] |= 0x7fe;
762         /* 2.4 GHz CSS 802.15.4a-2007 */
763         hw->phy->supported.channels[3] |= 0x3fff;
764         /* UWB Sub-gigahertz 802.15.4a-2007 */
765         hw->phy->supported.channels[4] |= 1;
766         /* UWB Low band 802.15.4a-2007 */
767         hw->phy->supported.channels[4] |= 0x1e;
768         /* UWB High band 802.15.4a-2007 */
769         hw->phy->supported.channels[4] |= 0xffe0;
770         /* 750 MHz O-QPSK 802.15.4c-2009 */
771         hw->phy->supported.channels[5] |= 0xf;
772         /* 750 MHz MPSK 802.15.4c-2009 */
773         hw->phy->supported.channels[5] |= 0xf0;
774         /* 950 MHz BPSK 802.15.4d-2009 */
775         hw->phy->supported.channels[6] |= 0x3ff;
776         /* 950 MHz GFSK 802.15.4d-2009 */
777         hw->phy->supported.channels[6] |= 0x3ffc00;
778
779         ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
780
781         /* hwsim phy channel 13 as default */
782         hw->phy->current_channel = 13;
783         pib = kzalloc(sizeof(*pib), GFP_KERNEL);
784         if (!pib) {
785                 err = -ENOMEM;
786                 goto err_pib;
787         }
788
789         rcu_assign_pointer(phy->pib, pib);
790         phy->idx = idx;
791         INIT_LIST_HEAD(&phy->edges);
792
793         hw->flags = IEEE802154_HW_PROMISCUOUS;
794         hw->parent = dev;
795
796         err = ieee802154_register_hw(hw);
797         if (err)
798                 goto err_reg;
799
800         mutex_lock(&hwsim_phys_lock);
801         if (init) {
802                 err = hwsim_subscribe_all_others(phy);
803                 if (err < 0) {
804                         mutex_unlock(&hwsim_phys_lock);
805                         goto err_subscribe;
806                 }
807         }
808         list_add_tail(&phy->list, &hwsim_phys);
809         mutex_unlock(&hwsim_phys_lock);
810
811         hwsim_mcast_new_radio(info, phy);
812
813         return idx;
814
815 err_subscribe:
816         ieee802154_unregister_hw(phy->hw);
817 err_reg:
818         kfree(pib);
819 err_pib:
820         ieee802154_free_hw(phy->hw);
821         return err;
822 }
823
824 static void hwsim_del(struct hwsim_phy *phy)
825 {
826         struct hwsim_pib *pib;
827
828         hwsim_edge_unsubscribe_me(phy);
829
830         list_del(&phy->list);
831
832         rcu_read_lock();
833         pib = rcu_dereference(phy->pib);
834         rcu_read_unlock();
835
836         kfree_rcu(pib, rcu);
837
838         ieee802154_unregister_hw(phy->hw);
839         ieee802154_free_hw(phy->hw);
840 }
841
842 static int hwsim_probe(struct platform_device *pdev)
843 {
844         struct hwsim_phy *phy, *tmp;
845         int err, i;
846
847         for (i = 0; i < 2; i++) {
848                 err = hwsim_add_one(NULL, &pdev->dev, true);
849                 if (err < 0)
850                         goto err_slave;
851         }
852
853         dev_info(&pdev->dev, "Added 2 mac802154 hwsim hardware radios\n");
854         return 0;
855
856 err_slave:
857         mutex_lock(&hwsim_phys_lock);
858         list_for_each_entry_safe(phy, tmp, &hwsim_phys, list)
859                 hwsim_del(phy);
860         mutex_unlock(&hwsim_phys_lock);
861         return err;
862 }
863
864 static int hwsim_remove(struct platform_device *pdev)
865 {
866         struct hwsim_phy *phy, *tmp;
867
868         mutex_lock(&hwsim_phys_lock);
869         list_for_each_entry_safe(phy, tmp, &hwsim_phys, list)
870                 hwsim_del(phy);
871         mutex_unlock(&hwsim_phys_lock);
872
873         return 0;
874 }
875
876 static struct platform_driver mac802154hwsim_driver = {
877         .probe = hwsim_probe,
878         .remove = hwsim_remove,
879         .driver = {
880                         .name = "mac802154_hwsim",
881         },
882 };
883
884 static __init int hwsim_init_module(void)
885 {
886         int rc;
887
888         rc = genl_register_family(&hwsim_genl_family);
889         if (rc)
890                 return rc;
891
892         mac802154hwsim_dev = platform_device_register_simple("mac802154_hwsim",
893                                                              -1, NULL, 0);
894         if (IS_ERR(mac802154hwsim_dev)) {
895                 rc = PTR_ERR(mac802154hwsim_dev);
896                 goto platform_dev;
897         }
898
899         rc = platform_driver_register(&mac802154hwsim_driver);
900         if (rc < 0)
901                 goto platform_drv;
902
903         return 0;
904
905 platform_drv:
906         platform_device_unregister(mac802154hwsim_dev);
907 platform_dev:
908         genl_unregister_family(&hwsim_genl_family);
909         return rc;
910 }
911
912 static __exit void hwsim_remove_module(void)
913 {
914         genl_unregister_family(&hwsim_genl_family);
915         platform_driver_unregister(&mac802154hwsim_driver);
916         platform_device_unregister(mac802154hwsim_dev);
917 }
918
919 module_init(hwsim_init_module);
920 module_exit(hwsim_remove_module);