1 // SPDX-License-Identifier: GPL-2.0-only
3 * HWSIM IEEE 802.15.4 interface
5 * (C) 2018 Mojatau, Alexander Aring <aring@mojatau.com>
6 * Copyright 2007-2012 Siemens AG
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>
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/ieee802154_netdev.h>
22 #include <net/mac802154.h>
23 #include <net/cfg802154.h>
24 #include <net/genetlink.h>
25 #include "mac802154_hwsim.h"
27 MODULE_DESCRIPTION("Software simulator of IEEE 802.15.4 radio(s) for mac802154");
28 MODULE_LICENSE("GPL");
30 static LIST_HEAD(hwsim_phys
);
31 static DEFINE_MUTEX(hwsim_phys_lock
);
33 static struct platform_device
*mac802154hwsim_dev
;
35 /* MAC802154_HWSIM netlink family */
36 static struct genl_family hwsim_genl_family
;
38 static int hwsim_radio_idx
;
40 enum hwsim_multicast_groups
{
44 static const struct genl_multicast_group hwsim_mcgrps
[] = {
45 [HWSIM_MCGRP_CONFIG
] = { .name
= "config", },
51 struct ieee802154_hw_addr_filt filt
;
52 enum ieee802154_filtering_level filt_level
;
57 struct hwsim_edge_info
{
64 struct hwsim_phy
*endpoint
;
65 struct hwsim_edge_info __rcu
*info
;
67 struct list_head list
;
72 struct ieee802154_hw
*hw
;
75 struct hwsim_pib __rcu
*pib
;
78 struct list_head edges
;
80 struct list_head list
;
83 static int hwsim_add_one(struct genl_info
*info
, struct device
*dev
,
85 static void hwsim_del(struct hwsim_phy
*phy
);
87 static int hwsim_hw_ed(struct ieee802154_hw
*hw
, u8
*level
)
94 static int hwsim_update_pib(struct ieee802154_hw
*hw
, u8 page
, u8 channel
,
95 struct ieee802154_hw_addr_filt
*filt
,
96 enum ieee802154_filtering_level filt_level
)
98 struct hwsim_phy
*phy
= hw
->priv
;
99 struct hwsim_pib
*pib
, *pib_old
;
101 pib
= kzalloc(sizeof(*pib
), GFP_ATOMIC
);
105 pib_old
= rtnl_dereference(phy
->pib
);
108 pib
->channel
= channel
;
109 pib
->filt
.short_addr
= filt
->short_addr
;
110 pib
->filt
.pan_id
= filt
->pan_id
;
111 pib
->filt
.ieee_addr
= filt
->ieee_addr
;
112 pib
->filt
.pan_coord
= filt
->pan_coord
;
113 pib
->filt_level
= filt_level
;
115 rcu_assign_pointer(phy
->pib
, pib
);
116 kfree_rcu(pib_old
, rcu
);
120 static int hwsim_hw_channel(struct ieee802154_hw
*hw
, u8 page
, u8 channel
)
122 struct hwsim_phy
*phy
= hw
->priv
;
123 struct hwsim_pib
*pib
;
127 pib
= rcu_dereference(phy
->pib
);
128 ret
= hwsim_update_pib(hw
, page
, channel
, &pib
->filt
, pib
->filt_level
);
134 static int hwsim_hw_addr_filt(struct ieee802154_hw
*hw
,
135 struct ieee802154_hw_addr_filt
*filt
,
136 unsigned long changed
)
138 struct hwsim_phy
*phy
= hw
->priv
;
139 struct hwsim_pib
*pib
;
143 pib
= rcu_dereference(phy
->pib
);
144 ret
= hwsim_update_pib(hw
, pib
->page
, pib
->channel
, filt
, pib
->filt_level
);
150 static void hwsim_hw_receive(struct ieee802154_hw
*hw
, struct sk_buff
*skb
,
153 struct ieee802154_hdr hdr
;
154 struct hwsim_phy
*phy
= hw
->priv
;
155 struct hwsim_pib
*pib
;
158 pib
= rcu_dereference(phy
->pib
);
160 if (!pskb_may_pull(skb
, 3)) {
161 dev_dbg(hw
->parent
, "invalid frame\n");
165 memcpy(&hdr
, skb
->data
, 3);
167 /* Level 4 filtering: Frame fields validity */
168 if (pib
->filt_level
== IEEE802154_FILTERING_4_FRAME_FIELDS
) {
169 /* a) Drop reserved frame types */
170 switch (mac_cb(skb
)->type
) {
171 case IEEE802154_FC_TYPE_BEACON
:
172 case IEEE802154_FC_TYPE_DATA
:
173 case IEEE802154_FC_TYPE_ACK
:
174 case IEEE802154_FC_TYPE_MAC_CMD
:
177 dev_dbg(hw
->parent
, "unrecognized frame type 0x%x\n",
182 /* b) Drop reserved frame versions */
183 switch (hdr
.fc
.version
) {
184 case IEEE802154_2003_STD
:
185 case IEEE802154_2006_STD
:
190 "unrecognized frame version 0x%x\n",
195 /* c) PAN ID constraints */
196 if ((mac_cb(skb
)->dest
.mode
== IEEE802154_ADDR_LONG
||
197 mac_cb(skb
)->dest
.mode
== IEEE802154_ADDR_SHORT
) &&
198 mac_cb(skb
)->dest
.pan_id
!= pib
->filt
.pan_id
&&
199 mac_cb(skb
)->dest
.pan_id
!= cpu_to_le16(IEEE802154_PANID_BROADCAST
)) {
201 "unrecognized PAN ID %04x\n",
202 le16_to_cpu(mac_cb(skb
)->dest
.pan_id
));
206 /* d1) Short address constraints */
207 if (mac_cb(skb
)->dest
.mode
== IEEE802154_ADDR_SHORT
&&
208 mac_cb(skb
)->dest
.short_addr
!= pib
->filt
.short_addr
&&
209 mac_cb(skb
)->dest
.short_addr
!= cpu_to_le16(IEEE802154_ADDR_BROADCAST
)) {
211 "unrecognized short address %04x\n",
212 le16_to_cpu(mac_cb(skb
)->dest
.short_addr
));
216 /* d2) Extended address constraints */
217 if (mac_cb(skb
)->dest
.mode
== IEEE802154_ADDR_LONG
&&
218 mac_cb(skb
)->dest
.extended_addr
!= pib
->filt
.ieee_addr
) {
220 "unrecognized long address 0x%016llx\n",
221 mac_cb(skb
)->dest
.extended_addr
);
225 /* d4) Specific PAN coordinator case (no parent) */
226 if ((mac_cb(skb
)->type
== IEEE802154_FC_TYPE_DATA
||
227 mac_cb(skb
)->type
== IEEE802154_FC_TYPE_MAC_CMD
) &&
228 mac_cb(skb
)->dest
.mode
== IEEE802154_ADDR_NONE
) {
230 "relaying is not supported\n");
234 /* e) Beacon frames follow specific PAN ID rules */
235 if (mac_cb(skb
)->type
== IEEE802154_FC_TYPE_BEACON
&&
236 pib
->filt
.pan_id
!= cpu_to_le16(IEEE802154_PANID_BROADCAST
) &&
237 mac_cb(skb
)->dest
.pan_id
!= pib
->filt
.pan_id
) {
239 "invalid beacon PAN ID %04x\n",
240 le16_to_cpu(mac_cb(skb
)->dest
.pan_id
));
247 ieee802154_rx_irqsafe(hw
, skb
, lqi
);
256 static int hwsim_hw_xmit(struct ieee802154_hw
*hw
, struct sk_buff
*skb
)
258 struct hwsim_phy
*current_phy
= hw
->priv
;
259 struct hwsim_pib
*current_pib
, *endpoint_pib
;
260 struct hwsim_edge_info
*einfo
;
261 struct hwsim_edge
*e
;
263 WARN_ON(current_phy
->suspended
);
266 current_pib
= rcu_dereference(current_phy
->pib
);
267 list_for_each_entry_rcu(e
, ¤t_phy
->edges
, list
) {
268 /* Can be changed later in rx_irqsafe, but this is only a
269 * performance tweak. Received radio should drop the frame
270 * in mac802154 stack anyway... so we don't need to be
271 * 100% of locking here to check on suspended
273 if (e
->endpoint
->suspended
)
276 endpoint_pib
= rcu_dereference(e
->endpoint
->pib
);
277 if (current_pib
->page
== endpoint_pib
->page
&&
278 current_pib
->channel
== endpoint_pib
->channel
) {
279 struct sk_buff
*newskb
= pskb_copy(skb
, GFP_ATOMIC
);
281 einfo
= rcu_dereference(e
->info
);
283 hwsim_hw_receive(e
->endpoint
->hw
, newskb
, einfo
->lqi
);
288 ieee802154_xmit_complete(hw
, skb
, false);
292 static int hwsim_hw_start(struct ieee802154_hw
*hw
)
294 struct hwsim_phy
*phy
= hw
->priv
;
296 phy
->suspended
= false;
301 static void hwsim_hw_stop(struct ieee802154_hw
*hw
)
303 struct hwsim_phy
*phy
= hw
->priv
;
305 phy
->suspended
= true;
309 hwsim_set_promiscuous_mode(struct ieee802154_hw
*hw
, const bool on
)
311 enum ieee802154_filtering_level filt_level
;
312 struct hwsim_phy
*phy
= hw
->priv
;
313 struct hwsim_pib
*pib
;
317 filt_level
= IEEE802154_FILTERING_NONE
;
319 filt_level
= IEEE802154_FILTERING_4_FRAME_FIELDS
;
322 pib
= rcu_dereference(phy
->pib
);
323 ret
= hwsim_update_pib(hw
, pib
->page
, pib
->channel
, &pib
->filt
, filt_level
);
329 static const struct ieee802154_ops hwsim_ops
= {
330 .owner
= THIS_MODULE
,
331 .xmit_async
= hwsim_hw_xmit
,
333 .set_channel
= hwsim_hw_channel
,
334 .start
= hwsim_hw_start
,
335 .stop
= hwsim_hw_stop
,
336 .set_promiscuous_mode
= hwsim_set_promiscuous_mode
,
337 .set_hw_addr_filt
= hwsim_hw_addr_filt
,
340 static int hwsim_new_radio_nl(struct sk_buff
*msg
, struct genl_info
*info
)
342 return hwsim_add_one(info
, &mac802154hwsim_dev
->dev
, false);
345 static int hwsim_del_radio_nl(struct sk_buff
*msg
, struct genl_info
*info
)
347 struct hwsim_phy
*phy
, *tmp
;
350 if (!info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_ID
])
353 idx
= nla_get_u32(info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_ID
]);
355 mutex_lock(&hwsim_phys_lock
);
356 list_for_each_entry_safe(phy
, tmp
, &hwsim_phys
, list
) {
357 if (idx
== phy
->idx
) {
359 mutex_unlock(&hwsim_phys_lock
);
363 mutex_unlock(&hwsim_phys_lock
);
368 static int append_radio_msg(struct sk_buff
*skb
, struct hwsim_phy
*phy
)
370 struct nlattr
*nl_edges
, *nl_edge
;
371 struct hwsim_edge_info
*einfo
;
372 struct hwsim_edge
*e
;
375 ret
= nla_put_u32(skb
, MAC802154_HWSIM_ATTR_RADIO_ID
, phy
->idx
);
380 if (list_empty(&phy
->edges
)) {
385 nl_edges
= nla_nest_start_noflag(skb
,
386 MAC802154_HWSIM_ATTR_RADIO_EDGES
);
392 list_for_each_entry_rcu(e
, &phy
->edges
, list
) {
393 nl_edge
= nla_nest_start_noflag(skb
,
394 MAC802154_HWSIM_ATTR_RADIO_EDGE
);
397 nla_nest_cancel(skb
, nl_edges
);
401 ret
= nla_put_u32(skb
, MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID
,
405 nla_nest_cancel(skb
, nl_edge
);
406 nla_nest_cancel(skb
, nl_edges
);
410 einfo
= rcu_dereference(e
->info
);
411 ret
= nla_put_u8(skb
, MAC802154_HWSIM_EDGE_ATTR_LQI
,
415 nla_nest_cancel(skb
, nl_edge
);
416 nla_nest_cancel(skb
, nl_edges
);
420 nla_nest_end(skb
, nl_edge
);
424 nla_nest_end(skb
, nl_edges
);
429 static int hwsim_get_radio(struct sk_buff
*skb
, struct hwsim_phy
*phy
,
431 struct netlink_callback
*cb
, int flags
)
436 hdr
= genlmsg_put(skb
, portid
, seq
, &hwsim_genl_family
, flags
,
437 MAC802154_HWSIM_CMD_GET_RADIO
);
442 genl_dump_check_consistent(cb
, hdr
);
444 res
= append_radio_msg(skb
, phy
);
448 genlmsg_end(skb
, hdr
);
452 genlmsg_cancel(skb
, hdr
);
456 static int hwsim_get_radio_nl(struct sk_buff
*msg
, struct genl_info
*info
)
458 struct hwsim_phy
*phy
;
460 int idx
, res
= -ENODEV
;
462 if (!info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_ID
])
464 idx
= nla_get_u32(info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_ID
]);
466 mutex_lock(&hwsim_phys_lock
);
467 list_for_each_entry(phy
, &hwsim_phys
, list
) {
471 skb
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_ATOMIC
);
477 res
= hwsim_get_radio(skb
, phy
, info
->snd_portid
,
478 info
->snd_seq
, NULL
, 0);
484 res
= genlmsg_reply(skb
, info
);
489 mutex_unlock(&hwsim_phys_lock
);
494 static int hwsim_dump_radio_nl(struct sk_buff
*skb
,
495 struct netlink_callback
*cb
)
497 int idx
= cb
->args
[0];
498 struct hwsim_phy
*phy
;
501 mutex_lock(&hwsim_phys_lock
);
503 if (idx
== hwsim_radio_idx
)
506 list_for_each_entry(phy
, &hwsim_phys
, list
) {
510 res
= hwsim_get_radio(skb
, phy
, NETLINK_CB(cb
->skb
).portid
,
511 cb
->nlh
->nlmsg_seq
, cb
, NLM_F_MULTI
);
521 mutex_unlock(&hwsim_phys_lock
);
525 /* caller need to held hwsim_phys_lock */
526 static struct hwsim_phy
*hwsim_get_radio_by_id(uint32_t idx
)
528 struct hwsim_phy
*phy
;
530 list_for_each_entry(phy
, &hwsim_phys
, list
) {
538 static const struct nla_policy hwsim_edge_policy
[MAC802154_HWSIM_EDGE_ATTR_MAX
+ 1] = {
539 [MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID
] = { .type
= NLA_U32
},
540 [MAC802154_HWSIM_EDGE_ATTR_LQI
] = { .type
= NLA_U8
},
543 static struct hwsim_edge
*hwsim_alloc_edge(struct hwsim_phy
*endpoint
, u8 lqi
)
545 struct hwsim_edge_info
*einfo
;
546 struct hwsim_edge
*e
;
548 e
= kzalloc(sizeof(*e
), GFP_KERNEL
);
552 einfo
= kzalloc(sizeof(*einfo
), GFP_KERNEL
);
559 rcu_assign_pointer(e
->info
, einfo
);
560 e
->endpoint
= endpoint
;
565 static void hwsim_free_edge(struct hwsim_edge
*e
)
567 struct hwsim_edge_info
*einfo
;
570 einfo
= rcu_dereference(e
->info
);
573 kfree_rcu(einfo
, rcu
);
577 static int hwsim_new_edge_nl(struct sk_buff
*msg
, struct genl_info
*info
)
579 struct nlattr
*edge_attrs
[MAC802154_HWSIM_EDGE_ATTR_MAX
+ 1];
580 struct hwsim_phy
*phy_v0
, *phy_v1
;
581 struct hwsim_edge
*e
;
584 if (!info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_ID
] ||
585 !info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_EDGE
])
588 if (nla_parse_nested_deprecated(edge_attrs
, MAC802154_HWSIM_EDGE_ATTR_MAX
, info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_EDGE
], hwsim_edge_policy
, NULL
))
591 if (!edge_attrs
[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID
])
594 v0
= nla_get_u32(info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_ID
]);
595 v1
= nla_get_u32(edge_attrs
[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID
]);
600 mutex_lock(&hwsim_phys_lock
);
601 phy_v0
= hwsim_get_radio_by_id(v0
);
603 mutex_unlock(&hwsim_phys_lock
);
607 phy_v1
= hwsim_get_radio_by_id(v1
);
609 mutex_unlock(&hwsim_phys_lock
);
614 list_for_each_entry_rcu(e
, &phy_v0
->edges
, list
) {
615 if (e
->endpoint
->idx
== v1
) {
616 mutex_unlock(&hwsim_phys_lock
);
623 e
= hwsim_alloc_edge(phy_v1
, 0xff);
625 mutex_unlock(&hwsim_phys_lock
);
628 list_add_rcu(&e
->list
, &phy_v0
->edges
);
629 /* wait until changes are done under hwsim_phys_lock lock
630 * should prevent of calling this function twice while
631 * edges list has not the changes yet.
634 mutex_unlock(&hwsim_phys_lock
);
639 static int hwsim_del_edge_nl(struct sk_buff
*msg
, struct genl_info
*info
)
641 struct nlattr
*edge_attrs
[MAC802154_HWSIM_EDGE_ATTR_MAX
+ 1];
642 struct hwsim_phy
*phy_v0
;
643 struct hwsim_edge
*e
;
646 if (!info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_ID
] ||
647 !info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_EDGE
])
650 if (nla_parse_nested_deprecated(edge_attrs
, MAC802154_HWSIM_EDGE_ATTR_MAX
, info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_EDGE
], hwsim_edge_policy
, NULL
))
653 if (!edge_attrs
[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID
])
656 v0
= nla_get_u32(info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_ID
]);
657 v1
= nla_get_u32(edge_attrs
[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID
]);
659 mutex_lock(&hwsim_phys_lock
);
660 phy_v0
= hwsim_get_radio_by_id(v0
);
662 mutex_unlock(&hwsim_phys_lock
);
667 list_for_each_entry_rcu(e
, &phy_v0
->edges
, list
) {
668 if (e
->endpoint
->idx
== v1
) {
670 list_del_rcu(&e
->list
);
672 /* same again - wait until list changes are done */
674 mutex_unlock(&hwsim_phys_lock
);
680 mutex_unlock(&hwsim_phys_lock
);
685 static int hwsim_set_edge_lqi(struct sk_buff
*msg
, struct genl_info
*info
)
687 struct nlattr
*edge_attrs
[MAC802154_HWSIM_EDGE_ATTR_MAX
+ 1];
688 struct hwsim_edge_info
*einfo
, *einfo_old
;
689 struct hwsim_phy
*phy_v0
;
690 struct hwsim_edge
*e
;
694 if (!info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_ID
] ||
695 !info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_EDGE
])
698 if (nla_parse_nested_deprecated(edge_attrs
, MAC802154_HWSIM_EDGE_ATTR_MAX
, info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_EDGE
], hwsim_edge_policy
, NULL
))
701 if (!edge_attrs
[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID
] ||
702 !edge_attrs
[MAC802154_HWSIM_EDGE_ATTR_LQI
])
705 v0
= nla_get_u32(info
->attrs
[MAC802154_HWSIM_ATTR_RADIO_ID
]);
706 v1
= nla_get_u32(edge_attrs
[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID
]);
707 lqi
= nla_get_u8(edge_attrs
[MAC802154_HWSIM_EDGE_ATTR_LQI
]);
709 mutex_lock(&hwsim_phys_lock
);
710 phy_v0
= hwsim_get_radio_by_id(v0
);
712 mutex_unlock(&hwsim_phys_lock
);
716 einfo
= kzalloc(sizeof(*einfo
), GFP_KERNEL
);
718 mutex_unlock(&hwsim_phys_lock
);
723 list_for_each_entry_rcu(e
, &phy_v0
->edges
, list
) {
724 if (e
->endpoint
->idx
== v1
) {
726 einfo_old
= rcu_replace_pointer(e
->info
, einfo
,
727 lockdep_is_held(&hwsim_phys_lock
));
729 kfree_rcu(einfo_old
, rcu
);
730 mutex_unlock(&hwsim_phys_lock
);
737 mutex_unlock(&hwsim_phys_lock
);
742 /* MAC802154_HWSIM netlink policy */
744 static const struct nla_policy hwsim_genl_policy
[MAC802154_HWSIM_ATTR_MAX
+ 1] = {
745 [MAC802154_HWSIM_ATTR_RADIO_ID
] = { .type
= NLA_U32
},
746 [MAC802154_HWSIM_ATTR_RADIO_EDGE
] = { .type
= NLA_NESTED
},
747 [MAC802154_HWSIM_ATTR_RADIO_EDGES
] = { .type
= NLA_NESTED
},
750 /* Generic Netlink operations array */
751 static const struct genl_small_ops hwsim_nl_ops
[] = {
753 .cmd
= MAC802154_HWSIM_CMD_NEW_RADIO
,
754 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
755 .doit
= hwsim_new_radio_nl
,
756 .flags
= GENL_UNS_ADMIN_PERM
,
759 .cmd
= MAC802154_HWSIM_CMD_DEL_RADIO
,
760 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
761 .doit
= hwsim_del_radio_nl
,
762 .flags
= GENL_UNS_ADMIN_PERM
,
765 .cmd
= MAC802154_HWSIM_CMD_GET_RADIO
,
766 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
767 .doit
= hwsim_get_radio_nl
,
768 .dumpit
= hwsim_dump_radio_nl
,
771 .cmd
= MAC802154_HWSIM_CMD_NEW_EDGE
,
772 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
773 .doit
= hwsim_new_edge_nl
,
774 .flags
= GENL_UNS_ADMIN_PERM
,
777 .cmd
= MAC802154_HWSIM_CMD_DEL_EDGE
,
778 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
779 .doit
= hwsim_del_edge_nl
,
780 .flags
= GENL_UNS_ADMIN_PERM
,
783 .cmd
= MAC802154_HWSIM_CMD_SET_EDGE
,
784 .validate
= GENL_DONT_VALIDATE_STRICT
| GENL_DONT_VALIDATE_DUMP
,
785 .doit
= hwsim_set_edge_lqi
,
786 .flags
= GENL_UNS_ADMIN_PERM
,
790 static struct genl_family hwsim_genl_family __ro_after_init
= {
791 .name
= "MAC802154_HWSIM",
793 .maxattr
= MAC802154_HWSIM_ATTR_MAX
,
794 .policy
= hwsim_genl_policy
,
795 .module
= THIS_MODULE
,
796 .small_ops
= hwsim_nl_ops
,
797 .n_small_ops
= ARRAY_SIZE(hwsim_nl_ops
),
798 .resv_start_op
= MAC802154_HWSIM_CMD_NEW_EDGE
+ 1,
799 .mcgrps
= hwsim_mcgrps
,
800 .n_mcgrps
= ARRAY_SIZE(hwsim_mcgrps
),
803 static void hwsim_mcast_config_msg(struct sk_buff
*mcast_skb
,
804 struct genl_info
*info
)
807 genl_notify(&hwsim_genl_family
, mcast_skb
, info
,
808 HWSIM_MCGRP_CONFIG
, GFP_KERNEL
);
810 genlmsg_multicast(&hwsim_genl_family
, mcast_skb
, 0,
811 HWSIM_MCGRP_CONFIG
, GFP_KERNEL
);
814 static void hwsim_mcast_new_radio(struct genl_info
*info
, struct hwsim_phy
*phy
)
816 struct sk_buff
*mcast_skb
;
819 mcast_skb
= genlmsg_new(GENLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
823 data
= genlmsg_put(mcast_skb
, 0, 0, &hwsim_genl_family
, 0,
824 MAC802154_HWSIM_CMD_NEW_RADIO
);
828 if (append_radio_msg(mcast_skb
, phy
) < 0)
831 genlmsg_end(mcast_skb
, data
);
833 hwsim_mcast_config_msg(mcast_skb
, info
);
837 genlmsg_cancel(mcast_skb
, data
);
838 nlmsg_free(mcast_skb
);
841 static void hwsim_edge_unsubscribe_me(struct hwsim_phy
*phy
)
843 struct hwsim_phy
*tmp
;
844 struct hwsim_edge
*e
;
847 /* going to all phy edges and remove phy from it */
848 list_for_each_entry(tmp
, &hwsim_phys
, list
) {
849 list_for_each_entry_rcu(e
, &tmp
->edges
, list
) {
850 if (e
->endpoint
->idx
== phy
->idx
) {
851 list_del_rcu(&e
->list
);
861 static int hwsim_subscribe_all_others(struct hwsim_phy
*phy
)
863 struct hwsim_phy
*sub
;
864 struct hwsim_edge
*e
;
866 list_for_each_entry(sub
, &hwsim_phys
, list
) {
867 e
= hwsim_alloc_edge(sub
, 0xff);
871 list_add_rcu(&e
->list
, &phy
->edges
);
874 list_for_each_entry(sub
, &hwsim_phys
, list
) {
875 e
= hwsim_alloc_edge(phy
, 0xff);
879 list_add_rcu(&e
->list
, &sub
->edges
);
885 hwsim_edge_unsubscribe_me(phy
);
888 list_for_each_entry_rcu(e
, &phy
->edges
, list
) {
889 list_del_rcu(&e
->list
);
896 static int hwsim_add_one(struct genl_info
*info
, struct device
*dev
,
899 struct ieee802154_hw
*hw
;
900 struct hwsim_phy
*phy
;
901 struct hwsim_pib
*pib
;
905 idx
= hwsim_radio_idx
++;
907 hw
= ieee802154_alloc_hw(sizeof(*phy
), &hwsim_ops
);
914 /* 868 MHz BPSK 802.15.4-2003 */
915 hw
->phy
->supported
.channels
[0] |= 1;
916 /* 915 MHz BPSK 802.15.4-2003 */
917 hw
->phy
->supported
.channels
[0] |= 0x7fe;
918 /* 2.4 GHz O-QPSK 802.15.4-2003 */
919 hw
->phy
->supported
.channels
[0] |= 0x7FFF800;
920 /* 868 MHz ASK 802.15.4-2006 */
921 hw
->phy
->supported
.channels
[1] |= 1;
922 /* 915 MHz ASK 802.15.4-2006 */
923 hw
->phy
->supported
.channels
[1] |= 0x7fe;
924 /* 868 MHz O-QPSK 802.15.4-2006 */
925 hw
->phy
->supported
.channels
[2] |= 1;
926 /* 915 MHz O-QPSK 802.15.4-2006 */
927 hw
->phy
->supported
.channels
[2] |= 0x7fe;
928 /* 2.4 GHz CSS 802.15.4a-2007 */
929 hw
->phy
->supported
.channels
[3] |= 0x3fff;
930 /* UWB Sub-gigahertz 802.15.4a-2007 */
931 hw
->phy
->supported
.channels
[4] |= 1;
932 /* UWB Low band 802.15.4a-2007 */
933 hw
->phy
->supported
.channels
[4] |= 0x1e;
934 /* UWB High band 802.15.4a-2007 */
935 hw
->phy
->supported
.channels
[4] |= 0xffe0;
936 /* 750 MHz O-QPSK 802.15.4c-2009 */
937 hw
->phy
->supported
.channels
[5] |= 0xf;
938 /* 750 MHz MPSK 802.15.4c-2009 */
939 hw
->phy
->supported
.channels
[5] |= 0xf0;
940 /* 950 MHz BPSK 802.15.4d-2009 */
941 hw
->phy
->supported
.channels
[6] |= 0x3ff;
942 /* 950 MHz GFSK 802.15.4d-2009 */
943 hw
->phy
->supported
.channels
[6] |= 0x3ffc00;
945 ieee802154_random_extended_addr(&hw
->phy
->perm_extended_addr
);
947 /* hwsim phy channel 13 as default */
948 hw
->phy
->current_channel
= 13;
949 pib
= kzalloc(sizeof(*pib
), GFP_KERNEL
);
956 pib
->filt
.short_addr
= cpu_to_le16(IEEE802154_ADDR_BROADCAST
);
957 pib
->filt
.pan_id
= cpu_to_le16(IEEE802154_PANID_BROADCAST
);
958 rcu_assign_pointer(phy
->pib
, pib
);
960 INIT_LIST_HEAD(&phy
->edges
);
962 hw
->flags
= IEEE802154_HW_PROMISCUOUS
;
965 err
= ieee802154_register_hw(hw
);
969 mutex_lock(&hwsim_phys_lock
);
971 err
= hwsim_subscribe_all_others(phy
);
973 mutex_unlock(&hwsim_phys_lock
);
977 list_add_tail(&phy
->list
, &hwsim_phys
);
978 mutex_unlock(&hwsim_phys_lock
);
980 hwsim_mcast_new_radio(info
, phy
);
985 ieee802154_unregister_hw(phy
->hw
);
989 ieee802154_free_hw(phy
->hw
);
993 static void hwsim_del(struct hwsim_phy
*phy
)
995 struct hwsim_pib
*pib
;
996 struct hwsim_edge
*e
;
998 hwsim_edge_unsubscribe_me(phy
);
1000 list_del(&phy
->list
);
1003 list_for_each_entry_rcu(e
, &phy
->edges
, list
) {
1004 list_del_rcu(&e
->list
);
1007 pib
= rcu_dereference(phy
->pib
);
1010 kfree_rcu(pib
, rcu
);
1012 ieee802154_unregister_hw(phy
->hw
);
1013 ieee802154_free_hw(phy
->hw
);
1016 static int hwsim_probe(struct platform_device
*pdev
)
1018 struct hwsim_phy
*phy
, *tmp
;
1021 for (i
= 0; i
< 2; i
++) {
1022 err
= hwsim_add_one(NULL
, &pdev
->dev
, true);
1027 dev_info(&pdev
->dev
, "Added 2 mac802154 hwsim hardware radios\n");
1031 mutex_lock(&hwsim_phys_lock
);
1032 list_for_each_entry_safe(phy
, tmp
, &hwsim_phys
, list
)
1034 mutex_unlock(&hwsim_phys_lock
);
1038 static void hwsim_remove(struct platform_device
*pdev
)
1040 struct hwsim_phy
*phy
, *tmp
;
1042 mutex_lock(&hwsim_phys_lock
);
1043 list_for_each_entry_safe(phy
, tmp
, &hwsim_phys
, list
)
1045 mutex_unlock(&hwsim_phys_lock
);
1048 static struct platform_driver mac802154hwsim_driver
= {
1049 .probe
= hwsim_probe
,
1050 .remove
= hwsim_remove
,
1052 .name
= "mac802154_hwsim",
1056 static __init
int hwsim_init_module(void)
1060 rc
= genl_register_family(&hwsim_genl_family
);
1064 mac802154hwsim_dev
= platform_device_register_simple("mac802154_hwsim",
1066 if (IS_ERR(mac802154hwsim_dev
)) {
1067 rc
= PTR_ERR(mac802154hwsim_dev
);
1071 rc
= platform_driver_register(&mac802154hwsim_driver
);
1078 platform_device_unregister(mac802154hwsim_dev
);
1080 genl_unregister_family(&hwsim_genl_family
);
1084 static __exit
void hwsim_remove_module(void)
1086 genl_unregister_family(&hwsim_genl_family
);
1087 platform_driver_unregister(&mac802154hwsim_driver
);
1088 platform_device_unregister(mac802154hwsim_dev
);
1091 module_init(hwsim_init_module
);
1092 module_exit(hwsim_remove_module
);