mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-15 06:05:13 +08:00
Core WPAN changes:
* Support for active scans * Support for answering BEACON_REQ * Specific MLME handling for limited devices WPAN driver changes: * ca8210: - Flag the devices as limited - Remove stray gpiod_unexport() call -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEE9HuaYnbmDhq/XIDIJWrqGEe9VoQFAmSV2A0ACgkQJWrqGEe9 VoSFxgf+MH6U+kmOU9rAikG12t+qTVBKzUkxUgCXcNKSb8oo2/5xF4jWpPd0Oa0W Ztneu7N/1o8FFTLJiI5l0KkidU2Nq9jBgYJPZPBen1TucrDapyMvQ1UzfA3LF8Vj rnBWXiz9oDWAg33KuSGZwgagvYe+UawQTzsvM+HKfai5VMyCzno0oJ8RXAJ/6jgY GkB9e3I5nkZUT9wVzeFKQXEnqGRjZRS2WoC/a76fRz0larGoVeHY3IWWCkQYamU6 vro18m2yiv/DkZaT5L0YQlYJ8LWojkaCgUVmJlP/9ngMO9WXqriVytMJBpcmFIhp 1us6PVS5ue65C1aVS3uHQSe47WM0SA== =sP6V -----END PGP SIGNATURE----- Merge tag 'ieee802154-for-net-next-2023-06-23' of gitolite.kernel.org:pub/scm/linux/kernel/git/wpan/wpan-next Miquel Raynal says: ==================== Core WPAN changes: - Support for active scans - Support for answering BEACON_REQ - Specific MLME handling for limited devices WPAN driver changes: - ca8210: - Flag the devices as limited - Remove stray gpiod_unexport() call * tag 'ieee802154-for-net-next-2023-06-23' of gitolite.kernel.org:pub/scm/linux/kernel/git/wpan/wpan-next: ieee802154: ca8210: Remove stray gpiod_unexport() call ieee802154: ca8210: Flag the driver as being limited net: ieee802154: Handle limited devices with only datagram support mac802154: Handle received BEACON_REQ ieee802154: Add support for allowing to answer BEACON_REQ mac802154: Handle active scanning ieee802154: Add support for user active scan requests ==================== Link: https://lore.kernel.org/r/20230623195506.40b87b5f@xps-13 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
2ffecf1a42
@ -2855,7 +2855,6 @@ static int ca8210_interrupt_init(struct spi_device *spi)
|
||||
);
|
||||
if (ret) {
|
||||
dev_crit(&spi->dev, "request_irq %d failed\n", pdata->irq_id);
|
||||
gpiod_unexport(gpio_to_desc(pdata->gpio_irq));
|
||||
gpio_free(pdata->gpio_irq);
|
||||
}
|
||||
|
||||
@ -2945,7 +2944,8 @@ static void ca8210_hw_setup(struct ieee802154_hw *ca8210_hw)
|
||||
ca8210_hw->phy->flags =
|
||||
WPAN_PHY_FLAG_TXPOWER |
|
||||
WPAN_PHY_FLAG_CCA_ED_LEVEL |
|
||||
WPAN_PHY_FLAG_CCA_MODE;
|
||||
WPAN_PHY_FLAG_CCA_MODE |
|
||||
WPAN_PHY_FLAG_DATAGRAMS_ONLY;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -178,12 +178,15 @@ wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b)
|
||||
* setting.
|
||||
* @WPAN_PHY_FLAG_STATE_QUEUE_STOPPED: Indicates that the transmit queue was
|
||||
* temporarily stopped.
|
||||
* @WPAN_PHY_FLAG_DATAGRAMS_ONLY: Indicates that transceiver is only able to
|
||||
* send/receive datagrams.
|
||||
*/
|
||||
enum wpan_phy_flags {
|
||||
WPAN_PHY_FLAG_TXPOWER = BIT(1),
|
||||
WPAN_PHY_FLAG_CCA_ED_LEVEL = BIT(2),
|
||||
WPAN_PHY_FLAG_CCA_MODE = BIT(3),
|
||||
WPAN_PHY_FLAG_STATE_QUEUE_STOPPED = BIT(4),
|
||||
WPAN_PHY_FLAG_DATAGRAMS_ONLY = BIT(5),
|
||||
};
|
||||
|
||||
struct wpan_phy {
|
||||
|
@ -74,6 +74,10 @@ struct ieee802154_beacon_hdr {
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
struct ieee802154_mac_cmd_pl {
|
||||
u8 cmd_id;
|
||||
} __packed;
|
||||
|
||||
struct ieee802154_sechdr {
|
||||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
u8 level:3,
|
||||
@ -149,6 +153,16 @@ struct ieee802154_beacon_frame {
|
||||
struct ieee802154_beacon_hdr mac_pl;
|
||||
};
|
||||
|
||||
struct ieee802154_mac_cmd_frame {
|
||||
struct ieee802154_hdr mhr;
|
||||
struct ieee802154_mac_cmd_pl mac_pl;
|
||||
};
|
||||
|
||||
struct ieee802154_beacon_req_frame {
|
||||
struct ieee802154_hdr mhr;
|
||||
struct ieee802154_mac_cmd_pl mac_pl;
|
||||
};
|
||||
|
||||
/* pushes hdr onto the skb. fields of hdr->fc that can be calculated from
|
||||
* the contents of hdr will be, and the actual value of those bits in
|
||||
* hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame
|
||||
@ -174,9 +188,13 @@ int ieee802154_hdr_peek_addrs(const struct sk_buff *skb,
|
||||
*/
|
||||
int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr);
|
||||
|
||||
/* pushes a beacon frame into an skb */
|
||||
/* pushes/pulls various frame types into/from an skb */
|
||||
int ieee802154_beacon_push(struct sk_buff *skb,
|
||||
struct ieee802154_beacon_frame *beacon);
|
||||
int ieee802154_mac_cmd_push(struct sk_buff *skb, void *frame,
|
||||
const void *pl, unsigned int pl_len);
|
||||
int ieee802154_mac_cmd_pl_pull(struct sk_buff *skb,
|
||||
struct ieee802154_mac_cmd_pl *mac_pl);
|
||||
|
||||
int ieee802154_max_payload(const struct ieee802154_hdr *hdr);
|
||||
|
||||
|
@ -120,6 +120,29 @@ ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee802154_hdr_push);
|
||||
|
||||
int ieee802154_mac_cmd_push(struct sk_buff *skb, void *f,
|
||||
const void *pl, unsigned int pl_len)
|
||||
{
|
||||
struct ieee802154_mac_cmd_frame *frame = f;
|
||||
struct ieee802154_mac_cmd_pl *mac_pl = &frame->mac_pl;
|
||||
struct ieee802154_hdr *mhr = &frame->mhr;
|
||||
int ret;
|
||||
|
||||
skb_reserve(skb, sizeof(*mhr));
|
||||
ret = ieee802154_hdr_push(skb, mhr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
skb_reset_mac_header(skb);
|
||||
skb->mac_len = ret;
|
||||
|
||||
skb_put_data(skb, mac_pl, sizeof(*mac_pl));
|
||||
skb_put_data(skb, pl, pl_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee802154_mac_cmd_push);
|
||||
|
||||
int ieee802154_beacon_push(struct sk_buff *skb,
|
||||
struct ieee802154_beacon_frame *beacon)
|
||||
{
|
||||
@ -284,6 +307,19 @@ ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee802154_hdr_pull);
|
||||
|
||||
int ieee802154_mac_cmd_pl_pull(struct sk_buff *skb,
|
||||
struct ieee802154_mac_cmd_pl *mac_pl)
|
||||
{
|
||||
if (!pskb_may_pull(skb, sizeof(*mac_pl)))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(mac_pl, skb->data, sizeof(*mac_pl));
|
||||
skb_pull(skb, sizeof(*mac_pl));
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee802154_mac_cmd_pl_pull);
|
||||
|
||||
int
|
||||
ieee802154_hdr_peek_addrs(const struct sk_buff *skb, struct ieee802154_hdr *hdr)
|
||||
{
|
||||
|
@ -233,7 +233,7 @@ static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX+1] = {
|
||||
NLA_POLICY_RANGE(NLA_U8, NL802154_SCAN_DONE_REASON_FINISHED,
|
||||
NL802154_SCAN_DONE_REASON_ABORTED),
|
||||
[NL802154_ATTR_BEACON_INTERVAL] =
|
||||
NLA_POLICY_MAX(NLA_U8, IEEE802154_MAX_SCAN_DURATION),
|
||||
NLA_POLICY_MAX(NLA_U8, IEEE802154_ACTIVE_SCAN_DURATION),
|
||||
|
||||
#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
|
||||
[NL802154_ATTR_SEC_ENABLED] = { .type = NLA_U8, },
|
||||
@ -1417,6 +1417,11 @@ static int nl802154_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (wpan_phy->flags & WPAN_PHY_FLAG_DATAGRAMS_ONLY) {
|
||||
NL_SET_ERR_MSG(info->extack, "PHY only supports datagrams");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
request = kzalloc(sizeof(*request), GFP_KERNEL);
|
||||
if (!request)
|
||||
return -ENOMEM;
|
||||
@ -1426,6 +1431,7 @@ static int nl802154_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
||||
|
||||
type = nla_get_u8(info->attrs[NL802154_ATTR_SCAN_TYPE]);
|
||||
switch (type) {
|
||||
case NL802154_SCAN_ACTIVE:
|
||||
case NL802154_SCAN_PASSIVE:
|
||||
request->type = type;
|
||||
break;
|
||||
@ -1583,6 +1589,11 @@ nl802154_send_beacons(struct sk_buff *skb, struct genl_info *info)
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (wpan_phy->flags & WPAN_PHY_FLAG_DATAGRAMS_ONLY) {
|
||||
NL_SET_ERR_MSG(info->extack, "PHY only supports datagrams");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
request = kzalloc(sizeof(*request), GFP_KERNEL);
|
||||
if (!request)
|
||||
return -ENOMEM;
|
||||
|
@ -58,6 +58,7 @@ struct ieee802154_local {
|
||||
/* Scanning */
|
||||
u8 scan_page;
|
||||
u8 scan_channel;
|
||||
struct ieee802154_beacon_req_frame scan_beacon_req;
|
||||
struct cfg802154_scan_request __rcu *scan_req;
|
||||
struct delayed_work scan_work;
|
||||
|
||||
@ -70,6 +71,8 @@ struct ieee802154_local {
|
||||
/* Asynchronous tasks */
|
||||
struct list_head rx_beacon_list;
|
||||
struct work_struct rx_beacon_work;
|
||||
struct list_head rx_mac_cmd_list;
|
||||
struct work_struct rx_mac_cmd_work;
|
||||
|
||||
bool started;
|
||||
bool suspended;
|
||||
@ -154,6 +157,22 @@ ieee802154_sdata_running(struct ieee802154_sub_if_data *sdata)
|
||||
return test_bit(SDATA_STATE_RUNNING, &sdata->state);
|
||||
}
|
||||
|
||||
static inline int ieee802154_get_mac_cmd(struct sk_buff *skb, u8 *mac_cmd)
|
||||
{
|
||||
struct ieee802154_mac_cmd_pl mac_pl;
|
||||
int ret;
|
||||
|
||||
if (mac_cb(skb)->type != IEEE802154_FC_TYPE_MAC_CMD)
|
||||
return -EINVAL;
|
||||
|
||||
ret = ieee802154_mac_cmd_pl_pull(skb, &mac_pl);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*mac_cmd = mac_pl.cmd_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern struct ieee802154_mlme_ops mac802154_mlme_wpan;
|
||||
|
||||
void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb);
|
||||
@ -275,6 +294,8 @@ static inline bool mac802154_is_beaconing(struct ieee802154_local *local)
|
||||
return test_bit(IEEE802154_IS_BEACONING, &local->ongoing);
|
||||
}
|
||||
|
||||
void mac802154_rx_mac_cmd_worker(struct work_struct *work);
|
||||
|
||||
/* interface handling */
|
||||
int ieee802154_iface_init(void);
|
||||
void ieee802154_iface_exit(void);
|
||||
|
@ -90,6 +90,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
|
||||
|
||||
INIT_LIST_HEAD(&local->interfaces);
|
||||
INIT_LIST_HEAD(&local->rx_beacon_list);
|
||||
INIT_LIST_HEAD(&local->rx_mac_cmd_list);
|
||||
mutex_init(&local->iflist_mtx);
|
||||
|
||||
tasklet_setup(&local->tasklet, ieee802154_tasklet_handler);
|
||||
@ -100,6 +101,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
|
||||
INIT_DELAYED_WORK(&local->scan_work, mac802154_scan_worker);
|
||||
INIT_WORK(&local->rx_beacon_work, mac802154_rx_beacon_worker);
|
||||
INIT_DELAYED_WORK(&local->beacon_work, mac802154_beacon_worker);
|
||||
INIT_WORK(&local->rx_mac_cmd_work, mac802154_rx_mac_cmd_worker);
|
||||
|
||||
/* init supported flags with 802.15.4 default ranges */
|
||||
phy->supported.max_minbe = 8;
|
||||
|
@ -47,6 +47,62 @@ void mac802154_rx_beacon_worker(struct work_struct *work)
|
||||
kfree(mac_pkt);
|
||||
}
|
||||
|
||||
static bool mac802154_should_answer_beacon_req(struct ieee802154_local *local)
|
||||
{
|
||||
struct cfg802154_beacon_request *beacon_req;
|
||||
unsigned int interval;
|
||||
|
||||
rcu_read_lock();
|
||||
beacon_req = rcu_dereference(local->beacon_req);
|
||||
if (!beacon_req) {
|
||||
rcu_read_unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
interval = beacon_req->interval;
|
||||
rcu_read_unlock();
|
||||
|
||||
if (!mac802154_is_beaconing(local))
|
||||
return false;
|
||||
|
||||
return interval == IEEE802154_ACTIVE_SCAN_DURATION;
|
||||
}
|
||||
|
||||
void mac802154_rx_mac_cmd_worker(struct work_struct *work)
|
||||
{
|
||||
struct ieee802154_local *local =
|
||||
container_of(work, struct ieee802154_local, rx_mac_cmd_work);
|
||||
struct cfg802154_mac_pkt *mac_pkt;
|
||||
u8 mac_cmd;
|
||||
int rc;
|
||||
|
||||
mac_pkt = list_first_entry_or_null(&local->rx_mac_cmd_list,
|
||||
struct cfg802154_mac_pkt, node);
|
||||
if (!mac_pkt)
|
||||
return;
|
||||
|
||||
rc = ieee802154_get_mac_cmd(mac_pkt->skb, &mac_cmd);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
switch (mac_cmd) {
|
||||
case IEEE802154_CMD_BEACON_REQ:
|
||||
dev_dbg(&mac_pkt->sdata->dev->dev, "processing BEACON REQ\n");
|
||||
if (!mac802154_should_answer_beacon_req(local))
|
||||
break;
|
||||
|
||||
queue_delayed_work(local->mac_wq, &local->beacon_work, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
list_del(&mac_pkt->node);
|
||||
kfree_skb(mac_pkt->skb);
|
||||
kfree(mac_pkt);
|
||||
}
|
||||
|
||||
static int
|
||||
ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
|
||||
struct sk_buff *skb, const struct ieee802154_hdr *hdr)
|
||||
@ -140,8 +196,20 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
|
||||
list_add_tail(&mac_pkt->node, &sdata->local->rx_beacon_list);
|
||||
queue_work(sdata->local->mac_wq, &sdata->local->rx_beacon_work);
|
||||
return NET_RX_SUCCESS;
|
||||
case IEEE802154_FC_TYPE_ACK:
|
||||
|
||||
case IEEE802154_FC_TYPE_MAC_CMD:
|
||||
dev_dbg(&sdata->dev->dev, "MAC COMMAND received\n");
|
||||
mac_pkt = kzalloc(sizeof(*mac_pkt), GFP_ATOMIC);
|
||||
if (!mac_pkt)
|
||||
goto fail;
|
||||
|
||||
mac_pkt->skb = skb_get(skb);
|
||||
mac_pkt->sdata = sdata;
|
||||
list_add_tail(&mac_pkt->node, &sdata->local->rx_mac_cmd_list);
|
||||
queue_work(sdata->local->mac_wq, &sdata->local->rx_mac_cmd_work);
|
||||
return NET_RX_SUCCESS;
|
||||
|
||||
case IEEE802154_FC_TYPE_ACK:
|
||||
goto fail;
|
||||
|
||||
case IEEE802154_FC_TYPE_DATA:
|
||||
|
@ -18,8 +18,12 @@
|
||||
|
||||
#define IEEE802154_BEACON_MHR_SZ 13
|
||||
#define IEEE802154_BEACON_PL_SZ 4
|
||||
#define IEEE802154_MAC_CMD_MHR_SZ 23
|
||||
#define IEEE802154_MAC_CMD_PL_SZ 1
|
||||
#define IEEE802154_BEACON_SKB_SZ (IEEE802154_BEACON_MHR_SZ + \
|
||||
IEEE802154_BEACON_PL_SZ)
|
||||
#define IEEE802154_MAC_CMD_SKB_SZ (IEEE802154_MAC_CMD_MHR_SZ + \
|
||||
IEEE802154_MAC_CMD_PL_SZ)
|
||||
|
||||
/* mac802154_scan_cleanup_locked() must be called upon scan completion or abort.
|
||||
* - Completions are asynchronous, not locked by the rtnl and decided by the
|
||||
@ -131,6 +135,42 @@ static int mac802154_scan_find_next_chan(struct ieee802154_local *local,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mac802154_scan_prepare_beacon_req(struct ieee802154_local *local)
|
||||
{
|
||||
memset(&local->scan_beacon_req, 0, sizeof(local->scan_beacon_req));
|
||||
local->scan_beacon_req.mhr.fc.type = IEEE802154_FC_TYPE_MAC_CMD;
|
||||
local->scan_beacon_req.mhr.fc.dest_addr_mode = IEEE802154_SHORT_ADDRESSING;
|
||||
local->scan_beacon_req.mhr.fc.version = IEEE802154_2003_STD;
|
||||
local->scan_beacon_req.mhr.fc.source_addr_mode = IEEE802154_NO_ADDRESSING;
|
||||
local->scan_beacon_req.mhr.dest.mode = IEEE802154_ADDR_SHORT;
|
||||
local->scan_beacon_req.mhr.dest.pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
|
||||
local->scan_beacon_req.mhr.dest.short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
|
||||
local->scan_beacon_req.mac_pl.cmd_id = IEEE802154_CMD_BEACON_REQ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mac802154_transmit_beacon_req(struct ieee802154_local *local,
|
||||
struct ieee802154_sub_if_data *sdata)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = alloc_skb(IEEE802154_MAC_CMD_SKB_SZ, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return -ENOBUFS;
|
||||
|
||||
skb->dev = sdata->dev;
|
||||
|
||||
ret = ieee802154_mac_cmd_push(skb, &local->scan_beacon_req, NULL, 0);
|
||||
if (ret) {
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ieee802154_mlme_tx(local, sdata, skb);
|
||||
}
|
||||
|
||||
void mac802154_scan_worker(struct work_struct *work)
|
||||
{
|
||||
struct ieee802154_local *local =
|
||||
@ -206,6 +246,13 @@ void mac802154_scan_worker(struct work_struct *work)
|
||||
goto end_scan;
|
||||
}
|
||||
|
||||
if (scan_req->type == NL802154_SCAN_ACTIVE) {
|
||||
ret = mac802154_transmit_beacon_req(local, sdata);
|
||||
if (ret)
|
||||
dev_err(&sdata->dev->dev,
|
||||
"Error when transmitting beacon request (%d)\n", ret);
|
||||
}
|
||||
|
||||
ieee802154_configure_durations(wpan_phy, page, channel);
|
||||
scan_duration = mac802154_scan_get_channel_time(scan_req_duration,
|
||||
wpan_phy->symbol_duration);
|
||||
@ -231,8 +278,8 @@ int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata,
|
||||
if (mac802154_is_scanning(local))
|
||||
return -EBUSY;
|
||||
|
||||
/* TODO: support other scanning type */
|
||||
if (request->type != NL802154_SCAN_PASSIVE)
|
||||
if (request->type != NL802154_SCAN_PASSIVE &&
|
||||
request->type != NL802154_SCAN_ACTIVE)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Store scanning parameters */
|
||||
@ -247,6 +294,8 @@ int mac802154_trigger_scan_locked(struct ieee802154_sub_if_data *sdata,
|
||||
local->scan_page = request->page;
|
||||
local->scan_channel = -1;
|
||||
set_bit(IEEE802154_IS_SCANNING, &local->ongoing);
|
||||
if (request->type == NL802154_SCAN_ACTIVE)
|
||||
mac802154_scan_prepare_beacon_req(local);
|
||||
|
||||
nl802154_scan_started(request->wpan_phy, request->wpan_dev);
|
||||
|
||||
@ -354,6 +403,7 @@ void mac802154_beacon_worker(struct work_struct *work)
|
||||
struct cfg802154_beacon_request *beacon_req;
|
||||
struct ieee802154_sub_if_data *sdata;
|
||||
struct wpan_dev *wpan_dev;
|
||||
u8 interval;
|
||||
int ret;
|
||||
|
||||
rcu_read_lock();
|
||||
@ -374,6 +424,7 @@ void mac802154_beacon_worker(struct work_struct *work)
|
||||
}
|
||||
|
||||
wpan_dev = beacon_req->wpan_dev;
|
||||
interval = beacon_req->interval;
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
@ -383,8 +434,9 @@ void mac802154_beacon_worker(struct work_struct *work)
|
||||
dev_err(&sdata->dev->dev,
|
||||
"Beacon could not be transmitted (%d)\n", ret);
|
||||
|
||||
queue_delayed_work(local->mac_wq, &local->beacon_work,
|
||||
local->beacon_interval);
|
||||
if (interval < IEEE802154_ACTIVE_SCAN_DURATION)
|
||||
queue_delayed_work(local->mac_wq, &local->beacon_work,
|
||||
local->beacon_interval);
|
||||
}
|
||||
|
||||
int mac802154_stop_beacons_locked(struct ieee802154_local *local,
|
||||
@ -439,13 +491,17 @@ int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata,
|
||||
local->beacon.mhr.source.pan_id = request->wpan_dev->pan_id;
|
||||
local->beacon.mhr.source.extended_addr = request->wpan_dev->extended_addr;
|
||||
local->beacon.mac_pl.beacon_order = request->interval;
|
||||
local->beacon.mac_pl.superframe_order = request->interval;
|
||||
if (request->interval <= IEEE802154_MAX_SCAN_DURATION)
|
||||
local->beacon.mac_pl.superframe_order = request->interval;
|
||||
local->beacon.mac_pl.final_cap_slot = 0xf;
|
||||
local->beacon.mac_pl.battery_life_ext = 0;
|
||||
/* TODO: Fill this field depending on the coordinator capacity */
|
||||
/* TODO: Fill this field with the coordinator situation in the network */
|
||||
local->beacon.mac_pl.pan_coordinator = 1;
|
||||
local->beacon.mac_pl.assoc_permit = 1;
|
||||
|
||||
if (request->interval == IEEE802154_ACTIVE_SCAN_DURATION)
|
||||
return 0;
|
||||
|
||||
/* Start the beacon work */
|
||||
local->beacon_interval =
|
||||
mac802154_scan_get_channel_time(request->interval,
|
||||
|
Loading…
Reference in New Issue
Block a user