Lines Matching +full:hw +full:- +full:channels

1 // SPDX-License-Identifier: GPL-2.0-only
6 * Copyright 2007-2012 Siemens AG
10 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
72 struct ieee802154_hw *hw; member
87 static int hwsim_hw_ed(struct ieee802154_hw *hw, u8 *level) in hwsim_hw_ed() argument
94 static int hwsim_update_pib(struct ieee802154_hw *hw, u8 page, u8 channel, in hwsim_update_pib() argument
98 struct hwsim_phy *phy = hw->priv; in hwsim_update_pib()
103 return -ENOMEM; in hwsim_update_pib()
105 pib_old = rtnl_dereference(phy->pib); in hwsim_update_pib()
107 pib->page = page; in hwsim_update_pib()
108 pib->channel = channel; in hwsim_update_pib()
109 pib->filt.short_addr = filt->short_addr; in hwsim_update_pib()
110 pib->filt.pan_id = filt->pan_id; in hwsim_update_pib()
111 pib->filt.ieee_addr = filt->ieee_addr; in hwsim_update_pib()
112 pib->filt.pan_coord = filt->pan_coord; in hwsim_update_pib()
113 pib->filt_level = filt_level; in hwsim_update_pib()
115 rcu_assign_pointer(phy->pib, pib); in hwsim_update_pib()
120 static int hwsim_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel) in hwsim_hw_channel() argument
122 struct hwsim_phy *phy = hw->priv; in hwsim_hw_channel()
127 pib = rcu_dereference(phy->pib); in hwsim_hw_channel()
128 ret = hwsim_update_pib(hw, page, channel, &pib->filt, pib->filt_level); in hwsim_hw_channel()
134 static int hwsim_hw_addr_filt(struct ieee802154_hw *hw, in hwsim_hw_addr_filt() argument
138 struct hwsim_phy *phy = hw->priv; in hwsim_hw_addr_filt()
143 pib = rcu_dereference(phy->pib); in hwsim_hw_addr_filt()
144 ret = hwsim_update_pib(hw, pib->page, pib->channel, filt, pib->filt_level); in hwsim_hw_addr_filt()
150 static void hwsim_hw_receive(struct ieee802154_hw *hw, struct sk_buff *skb, in hwsim_hw_receive() argument
154 struct hwsim_phy *phy = hw->priv; in hwsim_hw_receive()
158 pib = rcu_dereference(phy->pib); in hwsim_hw_receive()
161 dev_dbg(hw->parent, "invalid frame\n"); in hwsim_hw_receive()
165 memcpy(&hdr, skb->data, 3); in hwsim_hw_receive()
168 if (pib->filt_level == IEEE802154_FILTERING_4_FRAME_FIELDS) { in hwsim_hw_receive()
170 switch (mac_cb(skb)->type) { in hwsim_hw_receive()
177 dev_dbg(hw->parent, "unrecognized frame type 0x%x\n", in hwsim_hw_receive()
178 mac_cb(skb)->type); in hwsim_hw_receive()
189 dev_dbg(hw->parent, in hwsim_hw_receive()
196 if ((mac_cb(skb)->dest.mode == IEEE802154_ADDR_LONG || in hwsim_hw_receive()
197 mac_cb(skb)->dest.mode == IEEE802154_ADDR_SHORT) && in hwsim_hw_receive()
198 mac_cb(skb)->dest.pan_id != pib->filt.pan_id && in hwsim_hw_receive()
199 mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) { in hwsim_hw_receive()
200 dev_dbg(hw->parent, in hwsim_hw_receive()
202 le16_to_cpu(mac_cb(skb)->dest.pan_id)); in hwsim_hw_receive()
207 if (mac_cb(skb)->dest.mode == IEEE802154_ADDR_SHORT && in hwsim_hw_receive()
208 mac_cb(skb)->dest.short_addr != pib->filt.short_addr && in hwsim_hw_receive()
209 mac_cb(skb)->dest.short_addr != cpu_to_le16(IEEE802154_ADDR_BROADCAST)) { in hwsim_hw_receive()
210 dev_dbg(hw->parent, in hwsim_hw_receive()
212 le16_to_cpu(mac_cb(skb)->dest.short_addr)); in hwsim_hw_receive()
217 if (mac_cb(skb)->dest.mode == IEEE802154_ADDR_LONG && in hwsim_hw_receive()
218 mac_cb(skb)->dest.extended_addr != pib->filt.ieee_addr) { in hwsim_hw_receive()
219 dev_dbg(hw->parent, in hwsim_hw_receive()
221 mac_cb(skb)->dest.extended_addr); in hwsim_hw_receive()
226 if ((mac_cb(skb)->type == IEEE802154_FC_TYPE_DATA || in hwsim_hw_receive()
227 mac_cb(skb)->type == IEEE802154_FC_TYPE_MAC_CMD) && in hwsim_hw_receive()
228 mac_cb(skb)->dest.mode == IEEE802154_ADDR_NONE) { in hwsim_hw_receive()
229 dev_dbg(hw->parent, in hwsim_hw_receive()
235 if (mac_cb(skb)->type == IEEE802154_FC_TYPE_BEACON && in hwsim_hw_receive()
236 pib->filt.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST) && in hwsim_hw_receive()
237 mac_cb(skb)->dest.pan_id != pib->filt.pan_id) { in hwsim_hw_receive()
238 dev_dbg(hw->parent, in hwsim_hw_receive()
240 le16_to_cpu(mac_cb(skb)->dest.pan_id)); in hwsim_hw_receive()
247 ieee802154_rx_irqsafe(hw, skb, lqi); in hwsim_hw_receive()
256 static int hwsim_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) in hwsim_hw_xmit() argument
258 struct hwsim_phy *current_phy = hw->priv; in hwsim_hw_xmit()
263 WARN_ON(current_phy->suspended); in hwsim_hw_xmit()
266 current_pib = rcu_dereference(current_phy->pib); in hwsim_hw_xmit()
267 list_for_each_entry_rcu(e, &current_phy->edges, list) { in hwsim_hw_xmit()
273 if (e->endpoint->suspended) in hwsim_hw_xmit()
276 endpoint_pib = rcu_dereference(e->endpoint->pib); in hwsim_hw_xmit()
277 if (current_pib->page == endpoint_pib->page && in hwsim_hw_xmit()
278 current_pib->channel == endpoint_pib->channel) { in hwsim_hw_xmit()
281 einfo = rcu_dereference(e->info); in hwsim_hw_xmit()
283 hwsim_hw_receive(e->endpoint->hw, newskb, einfo->lqi); in hwsim_hw_xmit()
288 ieee802154_xmit_complete(hw, skb, false); in hwsim_hw_xmit()
292 static int hwsim_hw_start(struct ieee802154_hw *hw) in hwsim_hw_start() argument
294 struct hwsim_phy *phy = hw->priv; in hwsim_hw_start()
296 phy->suspended = false; in hwsim_hw_start()
301 static void hwsim_hw_stop(struct ieee802154_hw *hw) in hwsim_hw_stop() argument
303 struct hwsim_phy *phy = hw->priv; in hwsim_hw_stop()
305 phy->suspended = true; in hwsim_hw_stop()
309 hwsim_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on) in hwsim_set_promiscuous_mode() argument
312 struct hwsim_phy *phy = hw->priv; in hwsim_set_promiscuous_mode()
322 pib = rcu_dereference(phy->pib); in hwsim_set_promiscuous_mode()
323 ret = hwsim_update_pib(hw, pib->page, pib->channel, &pib->filt, filt_level); in hwsim_set_promiscuous_mode()
342 return hwsim_add_one(info, &mac802154hwsim_dev->dev, false); in hwsim_new_radio_nl()
348 s64 idx = -1; in hwsim_del_radio_nl()
350 if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]) in hwsim_del_radio_nl()
351 return -EINVAL; in hwsim_del_radio_nl()
353 idx = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]); in hwsim_del_radio_nl()
357 if (idx == phy->idx) { in hwsim_del_radio_nl()
365 return -ENODEV; in hwsim_del_radio_nl()
375 ret = nla_put_u32(skb, MAC802154_HWSIM_ATTR_RADIO_ID, phy->idx); in append_radio_msg()
380 if (list_empty(&phy->edges)) { in append_radio_msg()
389 return -ENOBUFS; in append_radio_msg()
392 list_for_each_entry_rcu(e, &phy->edges, list) { in append_radio_msg()
398 return -ENOBUFS; in append_radio_msg()
402 e->endpoint->idx); in append_radio_msg()
410 einfo = rcu_dereference(e->info); in append_radio_msg()
412 einfo->lqi); in append_radio_msg()
439 return -EMSGSIZE; in hwsim_get_radio()
460 int idx, res = -ENODEV; in hwsim_get_radio_nl()
462 if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]) in hwsim_get_radio_nl()
463 return -EINVAL; in hwsim_get_radio_nl()
464 idx = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]); in hwsim_get_radio_nl()
468 if (phy->idx != idx) in hwsim_get_radio_nl()
473 res = -ENOMEM; in hwsim_get_radio_nl()
477 res = hwsim_get_radio(skb, phy, info->snd_portid, in hwsim_get_radio_nl()
478 info->snd_seq, NULL, 0); in hwsim_get_radio_nl()
497 int idx = cb->args[0]; in hwsim_dump_radio_nl()
507 if (phy->idx < idx) in hwsim_dump_radio_nl()
510 res = hwsim_get_radio(skb, phy, NETLINK_CB(cb->skb).portid, in hwsim_dump_radio_nl()
511 cb->nlh->nlmsg_seq, cb, NLM_F_MULTI); in hwsim_dump_radio_nl()
515 idx = phy->idx + 1; in hwsim_dump_radio_nl()
518 cb->args[0] = idx; in hwsim_dump_radio_nl()
522 return skb->len; in hwsim_dump_radio_nl()
531 if (phy->idx == idx) in hwsim_get_radio_by_id()
558 einfo->lqi = 0xff; in hwsim_alloc_edge()
559 rcu_assign_pointer(e->info, einfo); in hwsim_alloc_edge()
560 e->endpoint = endpoint; in hwsim_alloc_edge()
570 einfo = rcu_dereference(e->info); in hwsim_free_edge()
584 if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] || in hwsim_new_edge_nl()
585 !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE]) in hwsim_new_edge_nl()
586 return -EINVAL; in hwsim_new_edge_nl()
588 …if (nla_parse_nested_deprecated(edge_attrs, MAC802154_HWSIM_EDGE_ATTR_MAX, info->attrs[MAC802154_H… in hwsim_new_edge_nl()
589 return -EINVAL; in hwsim_new_edge_nl()
592 return -EINVAL; in hwsim_new_edge_nl()
594 v0 = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]); in hwsim_new_edge_nl()
598 return -EINVAL; in hwsim_new_edge_nl()
604 return -ENOENT; in hwsim_new_edge_nl()
610 return -ENOENT; in hwsim_new_edge_nl()
614 list_for_each_entry_rcu(e, &phy_v0->edges, list) { in hwsim_new_edge_nl()
615 if (e->endpoint->idx == v1) { in hwsim_new_edge_nl()
618 return -EEXIST; in hwsim_new_edge_nl()
626 return -ENOMEM; in hwsim_new_edge_nl()
628 list_add_rcu(&e->list, &phy_v0->edges); in hwsim_new_edge_nl()
646 if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] || in hwsim_del_edge_nl()
647 !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE]) in hwsim_del_edge_nl()
648 return -EINVAL; in hwsim_del_edge_nl()
650 …if (nla_parse_nested_deprecated(edge_attrs, MAC802154_HWSIM_EDGE_ATTR_MAX, info->attrs[MAC802154_H… in hwsim_del_edge_nl()
651 return -EINVAL; in hwsim_del_edge_nl()
654 return -EINVAL; in hwsim_del_edge_nl()
656 v0 = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]); in hwsim_del_edge_nl()
663 return -ENOENT; in hwsim_del_edge_nl()
667 list_for_each_entry_rcu(e, &phy_v0->edges, list) { in hwsim_del_edge_nl()
668 if (e->endpoint->idx == v1) { in hwsim_del_edge_nl()
670 list_del_rcu(&e->list); in hwsim_del_edge_nl()
672 /* same again - wait until list changes are done */ in hwsim_del_edge_nl()
682 return -ENOENT; in hwsim_del_edge_nl()
694 if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] || in hwsim_set_edge_lqi()
695 !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE]) in hwsim_set_edge_lqi()
696 return -EINVAL; in hwsim_set_edge_lqi()
698 …if (nla_parse_nested_deprecated(edge_attrs, MAC802154_HWSIM_EDGE_ATTR_MAX, info->attrs[MAC802154_H… in hwsim_set_edge_lqi()
699 return -EINVAL; in hwsim_set_edge_lqi()
703 return -EINVAL; in hwsim_set_edge_lqi()
705 v0 = nla_get_u32(info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID]); in hwsim_set_edge_lqi()
713 return -ENOENT; in hwsim_set_edge_lqi()
719 return -ENOMEM; in hwsim_set_edge_lqi()
723 list_for_each_entry_rcu(e, &phy_v0->edges, list) { in hwsim_set_edge_lqi()
724 if (e->endpoint->idx == v1) { in hwsim_set_edge_lqi()
725 einfo->lqi = lqi; in hwsim_set_edge_lqi()
726 einfo_old = rcu_replace_pointer(e->info, einfo, in hwsim_set_edge_lqi()
739 return -ENOENT; in hwsim_set_edge_lqi()
849 list_for_each_entry_rcu(e, &tmp->edges, list) { in hwsim_edge_unsubscribe_me()
850 if (e->endpoint->idx == phy->idx) { in hwsim_edge_unsubscribe_me()
851 list_del_rcu(&e->list); in hwsim_edge_unsubscribe_me()
871 list_add_rcu(&e->list, &phy->edges); in hwsim_subscribe_all_others()
879 list_add_rcu(&e->list, &sub->edges); in hwsim_subscribe_all_others()
888 list_for_each_entry_rcu(e, &phy->edges, list) { in hwsim_subscribe_all_others()
889 list_del_rcu(&e->list); in hwsim_subscribe_all_others()
893 return -ENOMEM; in hwsim_subscribe_all_others()
899 struct ieee802154_hw *hw; in hwsim_add_one() local
907 hw = ieee802154_alloc_hw(sizeof(*phy), &hwsim_ops); in hwsim_add_one()
908 if (!hw) in hwsim_add_one()
909 return -ENOMEM; in hwsim_add_one()
911 phy = hw->priv; in hwsim_add_one()
912 phy->hw = hw; in hwsim_add_one()
914 /* 868 MHz BPSK 802.15.4-2003 */ in hwsim_add_one()
915 hw->phy->supported.channels[0] |= 1; in hwsim_add_one()
916 /* 915 MHz BPSK 802.15.4-2003 */ in hwsim_add_one()
917 hw->phy->supported.channels[0] |= 0x7fe; in hwsim_add_one()
918 /* 2.4 GHz O-QPSK 802.15.4-2003 */ in hwsim_add_one()
919 hw->phy->supported.channels[0] |= 0x7FFF800; in hwsim_add_one()
920 /* 868 MHz ASK 802.15.4-2006 */ in hwsim_add_one()
921 hw->phy->supported.channels[1] |= 1; in hwsim_add_one()
922 /* 915 MHz ASK 802.15.4-2006 */ in hwsim_add_one()
923 hw->phy->supported.channels[1] |= 0x7fe; in hwsim_add_one()
924 /* 868 MHz O-QPSK 802.15.4-2006 */ in hwsim_add_one()
925 hw->phy->supported.channels[2] |= 1; in hwsim_add_one()
926 /* 915 MHz O-QPSK 802.15.4-2006 */ in hwsim_add_one()
927 hw->phy->supported.channels[2] |= 0x7fe; in hwsim_add_one()
928 /* 2.4 GHz CSS 802.15.4a-2007 */ in hwsim_add_one()
929 hw->phy->supported.channels[3] |= 0x3fff; in hwsim_add_one()
930 /* UWB Sub-gigahertz 802.15.4a-2007 */ in hwsim_add_one()
931 hw->phy->supported.channels[4] |= 1; in hwsim_add_one()
932 /* UWB Low band 802.15.4a-2007 */ in hwsim_add_one()
933 hw->phy->supported.channels[4] |= 0x1e; in hwsim_add_one()
934 /* UWB High band 802.15.4a-2007 */ in hwsim_add_one()
935 hw->phy->supported.channels[4] |= 0xffe0; in hwsim_add_one()
936 /* 750 MHz O-QPSK 802.15.4c-2009 */ in hwsim_add_one()
937 hw->phy->supported.channels[5] |= 0xf; in hwsim_add_one()
938 /* 750 MHz MPSK 802.15.4c-2009 */ in hwsim_add_one()
939 hw->phy->supported.channels[5] |= 0xf0; in hwsim_add_one()
940 /* 950 MHz BPSK 802.15.4d-2009 */ in hwsim_add_one()
941 hw->phy->supported.channels[6] |= 0x3ff; in hwsim_add_one()
942 /* 950 MHz GFSK 802.15.4d-2009 */ in hwsim_add_one()
943 hw->phy->supported.channels[6] |= 0x3ffc00; in hwsim_add_one()
945 ieee802154_random_extended_addr(&hw->phy->perm_extended_addr); in hwsim_add_one()
948 hw->phy->current_channel = 13; in hwsim_add_one()
951 err = -ENOMEM; in hwsim_add_one()
955 pib->channel = 13; in hwsim_add_one()
956 pib->filt.short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); in hwsim_add_one()
957 pib->filt.pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); in hwsim_add_one()
958 rcu_assign_pointer(phy->pib, pib); in hwsim_add_one()
959 phy->idx = idx; in hwsim_add_one()
960 INIT_LIST_HEAD(&phy->edges); in hwsim_add_one()
962 hw->flags = IEEE802154_HW_PROMISCUOUS; in hwsim_add_one()
963 hw->parent = dev; in hwsim_add_one()
965 err = ieee802154_register_hw(hw); in hwsim_add_one()
977 list_add_tail(&phy->list, &hwsim_phys); in hwsim_add_one()
985 ieee802154_unregister_hw(phy->hw); in hwsim_add_one()
989 ieee802154_free_hw(phy->hw); in hwsim_add_one()
1000 list_del(&phy->list); in hwsim_del()
1003 list_for_each_entry_rcu(e, &phy->edges, list) { in hwsim_del()
1004 list_del_rcu(&e->list); in hwsim_del()
1007 pib = rcu_dereference(phy->pib); in hwsim_del()
1012 ieee802154_unregister_hw(phy->hw); in hwsim_del()
1013 ieee802154_free_hw(phy->hw); in hwsim_del()
1022 err = hwsim_add_one(NULL, &pdev->dev, true); in hwsim_probe()
1027 dev_info(&pdev->dev, "Added 2 mac802154 hwsim hardware radios\n"); in hwsim_probe()
1065 -1, NULL, 0); in hwsim_init_module()