2016-06-14 16:52:57 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2016 Intel Corporation.
|
|
|
|
*
|
2017-01-19 09:01:01 +08:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2016-06-14 16:52:57 +08:00
|
|
|
*/
|
|
|
|
|
2016-11-12 06:13:24 +08:00
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* @brief Public IEEE 802.15.4 Radio API
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __IEEE802154_RADIO_H__
|
|
|
|
#define __IEEE802154_RADIO_H__
|
|
|
|
|
|
|
|
#include <device.h>
|
|
|
|
#include <net/net_if.h>
|
2018-03-16 16:07:30 +08:00
|
|
|
#include <net/net_pkt.h>
|
2017-12-07 17:13:56 +08:00
|
|
|
#include <net/ieee802154.h>
|
2016-11-12 06:13:24 +08:00
|
|
|
|
2017-07-24 21:23:14 +08:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2017-07-20 21:29:45 +08:00
|
|
|
/**
|
|
|
|
* @addtogroup ieee802154
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
2017-09-04 19:06:49 +08:00
|
|
|
enum ieee802154_hw_caps {
|
|
|
|
IEEE802154_HW_FCS = BIT(0), /* Frame Check-Sum supported */
|
|
|
|
IEEE802154_HW_PROMISC = BIT(1), /* Promiscuous mode supported */
|
|
|
|
IEEE802154_HW_FILTER = BIT(2), /* Filters PAN ID, long/short addr */
|
|
|
|
IEEE802154_HW_CSMA = BIT(3), /* CSMA-CA supported */
|
|
|
|
IEEE802154_HW_2_4_GHZ = BIT(4), /* 2.4Ghz radio supported */
|
2017-10-03 16:32:59 +08:00
|
|
|
IEEE802154_HW_TX_RX_ACK = BIT(5), /* Handles ACK request on TX */
|
2017-09-11 15:59:25 +08:00
|
|
|
IEEE802154_HW_SUB_GHZ = BIT(6), /* Sub-GHz radio supported */
|
2017-09-04 19:06:49 +08:00
|
|
|
};
|
|
|
|
|
2017-09-05 19:50:36 +08:00
|
|
|
enum ieee802154_filter_type {
|
|
|
|
IEEE802154_FILTER_TYPE_IEEE_ADDR,
|
|
|
|
IEEE802154_FILTER_TYPE_SHORT_ADDR,
|
|
|
|
IEEE802154_FILTER_TYPE_PAN_ID,
|
2018-03-19 16:53:29 +08:00
|
|
|
IEEE802154_FILTER_TYPE_SRC_IEEE_ADDR,
|
|
|
|
IEEE802154_FILTER_TYPE_SRC_SHORT_ADDR,
|
2017-09-05 19:50:36 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct ieee802154_filter {
|
|
|
|
/** @cond ignore */
|
|
|
|
union {
|
|
|
|
u8_t *ieee_addr;
|
|
|
|
u16_t short_addr;
|
|
|
|
u16_t pan_id;
|
|
|
|
};
|
|
|
|
/* @endcond */
|
|
|
|
};
|
|
|
|
|
2016-11-12 06:13:24 +08:00
|
|
|
struct ieee802154_radio_api {
|
|
|
|
/**
|
|
|
|
* Mandatory to get in first position.
|
|
|
|
* A network device should indeed provide a pointer on such
|
|
|
|
* net_if_api structure. So we make current structure pointer
|
|
|
|
* that can be casted to a net_if_api structure pointer.
|
|
|
|
*/
|
|
|
|
struct net_if_api iface_api;
|
|
|
|
|
2017-09-04 19:06:49 +08:00
|
|
|
/** Get the device capabilities */
|
|
|
|
enum ieee802154_hw_caps (*get_capabilities)(struct device *dev);
|
|
|
|
|
2016-11-12 06:13:24 +08:00
|
|
|
/** Clear Channel Assesment - Check channel's activity */
|
|
|
|
int (*cca)(struct device *dev);
|
|
|
|
|
|
|
|
/** Set current channel */
|
2017-04-21 22:27:50 +08:00
|
|
|
int (*set_channel)(struct device *dev, u16_t channel);
|
2016-11-12 06:13:24 +08:00
|
|
|
|
2018-03-19 16:53:29 +08:00
|
|
|
/** Set/Unset filters (for IEEE802154_HW_FILTER ) */
|
|
|
|
int (*filter)(struct device *dev,
|
|
|
|
bool set,
|
|
|
|
enum ieee802154_filter_type type,
|
|
|
|
const struct ieee802154_filter *filter);
|
2017-09-05 19:50:36 +08:00
|
|
|
|
2016-11-12 06:13:24 +08:00
|
|
|
/** Set TX power level in dbm */
|
2017-04-21 22:27:50 +08:00
|
|
|
int (*set_txpower)(struct device *dev, s16_t dbm);
|
2016-11-12 06:13:24 +08:00
|
|
|
|
2017-04-05 14:37:44 +08:00
|
|
|
/** Transmit a packet fragment */
|
net/ieee802154: Modify radio TX function signature
The cause for this change is TCP. Until now, the radio strategy driver
(ALOHA or CSMA) was providing the actual nbuf, and not the buffer
fragment, counting on the fact that the loop was using
net_buf_frag_del() which made so, iteration after iteration, buffer
framgent to be always buf->frags. The problem with this logic is loosing
the fragments that might be still referenced by TCP, in case the whole
buffer did not make it so TCP can retry later and so on.
Instead, TX now takes the nbuf and the actual frag to send. It could
have been working with just a pointer on the data, and the whole length
of the frame. But it has been avoided due to possible future devices,
that will be smarter and run CSMA directly in the hw, thus it will
require to access the whole buffer list through the nbuf.
Change-Id: I8d77b1e13b648c0ec3645cb2d55d1910d00381ea
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2017-01-26 21:31:30 +08:00
|
|
|
int (*tx)(struct device *dev,
|
2017-04-05 14:37:44 +08:00
|
|
|
struct net_pkt *pkt,
|
net/ieee802154: Modify radio TX function signature
The cause for this change is TCP. Until now, the radio strategy driver
(ALOHA or CSMA) was providing the actual nbuf, and not the buffer
fragment, counting on the fact that the loop was using
net_buf_frag_del() which made so, iteration after iteration, buffer
framgent to be always buf->frags. The problem with this logic is loosing
the fragments that might be still referenced by TCP, in case the whole
buffer did not make it so TCP can retry later and so on.
Instead, TX now takes the nbuf and the actual frag to send. It could
have been working with just a pointer on the data, and the whole length
of the frame. But it has been avoided due to possible future devices,
that will be smarter and run CSMA directly in the hw, thus it will
require to access the whole buffer list through the nbuf.
Change-Id: I8d77b1e13b648c0ec3645cb2d55d1910d00381ea
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2017-01-26 21:31:30 +08:00
|
|
|
struct net_buf *frag);
|
2016-11-12 06:13:24 +08:00
|
|
|
|
|
|
|
/** Start the device */
|
|
|
|
int (*start)(struct device *dev);
|
|
|
|
|
|
|
|
/** Stop the device */
|
|
|
|
int (*stop)(struct device *dev);
|
2017-09-11 15:59:25 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_NET_L2_IEEE802154_SUB_GHZ
|
|
|
|
/** Get the available amount of Sub-GHz channels */
|
|
|
|
u16_t (*get_subg_channel_count)(struct device *dev);
|
|
|
|
#endif /* CONFIG_NET_L2_IEEE802154_SUB_GHZ */
|
2018-03-19 18:20:26 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_NET_L2_OPENTHREAD
|
|
|
|
/** Run an energy detection scan.
|
|
|
|
* Note: channel must be set prior to request this function.
|
|
|
|
* duration parameter is in ms.
|
|
|
|
*/
|
|
|
|
int (*ed_scan)(struct device *dev,
|
|
|
|
u16_t duration,
|
|
|
|
void (*done_cb)(struct device *dev,
|
|
|
|
s16_t max_ed));
|
|
|
|
#endif /* CONFIG_NET_L2_OPENTHREAD */
|
2016-11-12 06:13:24 +08:00
|
|
|
} __packed;
|
|
|
|
|
2018-03-16 16:07:30 +08:00
|
|
|
#define IEEE802154_AR_FLAG_SET (0x20)
|
|
|
|
|
2017-11-16 18:11:51 +08:00
|
|
|
/**
|
|
|
|
* @brief Check if AR flag is set on the frame inside given net_pkt
|
|
|
|
*
|
2018-03-16 16:07:30 +08:00
|
|
|
* @param pkt A valid pointer on a net_pkt structure, must not be NULL,
|
|
|
|
* and its length should be at least made of 1 byte (ACK frames
|
|
|
|
* are the smallest frames on 15.4 and made of 3 bytes, not
|
|
|
|
* not counting the FCS part).
|
2017-11-16 18:11:51 +08:00
|
|
|
*
|
|
|
|
* @return True if AR flag is set, False otherwise
|
|
|
|
*/
|
2018-03-16 16:07:30 +08:00
|
|
|
static inline bool ieee802154_is_ar_flag_set(struct net_pkt *pkt)
|
|
|
|
{
|
|
|
|
return (*net_pkt_ll(pkt) & IEEE802154_AR_FLAG_SET);
|
|
|
|
}
|
2017-11-16 18:11:51 +08:00
|
|
|
|
|
|
|
#ifndef CONFIG_IEEE802154_RAW_MODE
|
|
|
|
|
2016-11-12 06:13:24 +08:00
|
|
|
/**
|
|
|
|
* @brief Radio driver sending function that hw drivers should use
|
|
|
|
*
|
2017-08-08 19:41:23 +08:00
|
|
|
* @details This function should be used to fill in struct net_if's send
|
|
|
|
* pointer.
|
2016-11-12 06:13:24 +08:00
|
|
|
*
|
|
|
|
* @param iface A valid pointer on a network interface to send from
|
2017-04-05 14:37:44 +08:00
|
|
|
* @param pkt A valid pointer on a packet to send
|
2016-11-12 06:13:24 +08:00
|
|
|
*
|
|
|
|
* @return 0 on success, negative value otherwise
|
|
|
|
*/
|
|
|
|
extern int ieee802154_radio_send(struct net_if *iface,
|
2017-04-05 14:37:44 +08:00
|
|
|
struct net_pkt *pkt);
|
2016-11-12 06:13:24 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Radio driver ACK handling function that hw drivers should use
|
|
|
|
*
|
|
|
|
* @details ACK handling requires fast handling and thus such function
|
2017-05-03 08:21:56 +08:00
|
|
|
* helps to hook directly the hw drivers to the radio driver.
|
2016-11-12 06:13:24 +08:00
|
|
|
*
|
|
|
|
* @param iface A valid pointer on a network interface that received the packet
|
2017-04-05 14:37:44 +08:00
|
|
|
* @param pkt A valid pointer on a packet to check
|
2016-11-12 06:13:24 +08:00
|
|
|
*
|
|
|
|
* @return NET_OK if it was handled, NET_CONTINUE otherwise
|
|
|
|
*/
|
|
|
|
extern enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface,
|
2017-04-05 14:37:44 +08:00
|
|
|
struct net_pkt *pkt);
|
2016-11-12 06:13:24 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Initialize L2 stack for a given interface
|
|
|
|
*
|
|
|
|
* @param iface A valid pointer on a network interface
|
|
|
|
*/
|
|
|
|
void ieee802154_init(struct net_if *iface);
|
|
|
|
|
2017-11-16 18:11:51 +08:00
|
|
|
#else /* CONFIG_IEEE802154_RAW_MODE */
|
|
|
|
|
|
|
|
static inline int ieee802154_radio_send(struct net_if *iface,
|
|
|
|
struct net_pkt *pkt)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface,
|
|
|
|
struct net_pkt *pkt)
|
|
|
|
{
|
|
|
|
return NET_CONTINUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define ieee802154_init(_iface_)
|
2017-10-09 17:49:28 +08:00
|
|
|
|
2017-11-16 18:11:51 +08:00
|
|
|
#endif /* CONFIG_IEEE802154_RAW_MODE */
|
2017-10-09 17:49:28 +08:00
|
|
|
|
2017-07-24 21:23:14 +08:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-07-20 21:29:45 +08:00
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2016-11-12 06:13:24 +08:00
|
|
|
#endif /* __IEEE802154_RADIO_H__ */
|