2016-08-17 22:48:36 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2016 Intel Corporation.
|
|
|
|
*
|
2017-01-19 09:01:01 +08:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2016-08-17 22:48:36 +08:00
|
|
|
*/
|
|
|
|
|
2022-07-18 17:40:20 +08:00
|
|
|
#define DT_DRV_COMPAT zephyr_ieee802154_uart_pipe
|
|
|
|
|
2018-09-03 22:28:47 +08:00
|
|
|
#define LOG_MODULE_NAME ieee802154_uart_pipe
|
2018-11-09 22:30:56 +08:00
|
|
|
#define LOG_LEVEL CONFIG_IEEE802154_DRIVER_LOG_LEVEL
|
2018-09-03 22:28:47 +08:00
|
|
|
|
2022-05-06 16:25:46 +08:00
|
|
|
#include <zephyr/logging/log.h>
|
2018-09-03 22:28:47 +08:00
|
|
|
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
2016-08-17 22:48:36 +08:00
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
2022-05-06 16:25:46 +08:00
|
|
|
#include <zephyr/kernel.h>
|
|
|
|
#include <zephyr/arch/cpu.h>
|
2016-08-17 22:48:36 +08:00
|
|
|
|
2022-05-06 16:25:46 +08:00
|
|
|
#include <zephyr/device.h>
|
|
|
|
#include <zephyr/init.h>
|
|
|
|
#include <zephyr/net/net_if.h>
|
|
|
|
#include <zephyr/net/net_pkt.h>
|
2023-10-07 06:38:53 +08:00
|
|
|
#include <zephyr/random/random.h>
|
2016-08-17 22:48:36 +08:00
|
|
|
|
2021-09-01 18:15:16 +08:00
|
|
|
#include <zephyr/drivers/uart_pipe.h>
|
2022-05-06 16:25:46 +08:00
|
|
|
#include <zephyr/net/ieee802154_radio.h>
|
2016-08-17 22:48:36 +08:00
|
|
|
|
|
|
|
#include "ieee802154_uart_pipe.h"
|
|
|
|
|
2018-02-14 21:03:15 +08:00
|
|
|
#define PAN_ID_OFFSET 3 /* Pan Id offset */
|
|
|
|
#define DEST_ADDR_OFFSET 5 /* Destination offset address*/
|
|
|
|
#define DEST_ADDR_TYPE_OFFSET 1 /* Destination address type */
|
|
|
|
|
|
|
|
#define DEST_ADDR_TYPE_MASK 0x0c /* Mask for destination address type */
|
|
|
|
|
|
|
|
#define DEST_ADDR_TYPE_SHORT 0x08 /* Short destination address type */
|
|
|
|
#define DEST_ADDR_TYPE_EXTENDED 0x0c /* Extended destination address type */
|
|
|
|
|
|
|
|
#define PAN_ID_SIZE 2 /* Size of Pan Id */
|
|
|
|
#define SHORT_ADDRESS_SIZE 2 /* Size of Short Mac Address */
|
|
|
|
#define EXTENDED_ADDRESS_SIZE 8 /* Size of Extended Mac Address */
|
|
|
|
|
|
|
|
/* Broadcast Short Address */
|
|
|
|
#define BROADCAST_ADDRESS ((uint8_t [SHORT_ADDRESS_SIZE]) {0xff, 0xff})
|
|
|
|
|
2020-05-28 00:26:57 +08:00
|
|
|
static uint8_t dev_pan_id[PAN_ID_SIZE]; /* Device Pan Id */
|
|
|
|
static uint8_t dev_short_addr[SHORT_ADDRESS_SIZE]; /* Device Short Address */
|
|
|
|
static uint8_t dev_ext_addr[EXTENDED_ADDRESS_SIZE]; /* Device Extended Address */
|
2018-02-14 21:03:15 +08:00
|
|
|
|
2016-08-17 22:48:36 +08:00
|
|
|
/** Singleton device used in uart pipe callback */
|
2020-05-01 02:33:38 +08:00
|
|
|
static const struct device *upipe_dev;
|
2016-08-17 22:48:36 +08:00
|
|
|
|
2018-02-14 21:03:15 +08:00
|
|
|
#if defined(CONFIG_IEEE802154_UPIPE_HW_FILTER)
|
|
|
|
|
2020-05-28 00:26:57 +08:00
|
|
|
static bool received_dest_addr_matched(uint8_t *rx_buffer)
|
2018-02-14 21:03:15 +08:00
|
|
|
{
|
2020-05-29 03:23:02 +08:00
|
|
|
struct upipe_context *upipe = upipe_dev->data;
|
2018-02-14 21:03:15 +08:00
|
|
|
|
|
|
|
/* Check destination PAN Id */
|
|
|
|
if (memcmp(&rx_buffer[PAN_ID_OFFSET],
|
|
|
|
dev_pan_id, PAN_ID_SIZE) != 0 &&
|
|
|
|
memcmp(&rx_buffer[PAN_ID_OFFSET],
|
|
|
|
BROADCAST_ADDRESS, PAN_ID_SIZE) != 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check destination address */
|
|
|
|
switch (rx_buffer[DEST_ADDR_TYPE_OFFSET] & DEST_ADDR_TYPE_MASK) {
|
|
|
|
case DEST_ADDR_TYPE_SHORT:
|
|
|
|
/* First check if the destination is broadcast */
|
2019-06-19 02:45:40 +08:00
|
|
|
/* If not broadcast, check if length and address matches */
|
2018-02-14 21:03:15 +08:00
|
|
|
if (memcmp(&rx_buffer[DEST_ADDR_OFFSET],
|
|
|
|
BROADCAST_ADDRESS,
|
|
|
|
SHORT_ADDRESS_SIZE) != 0 &&
|
2018-01-11 22:06:53 +08:00
|
|
|
(net_if_get_link_addr(upipe->iface)->len !=
|
|
|
|
SHORT_ADDRESS_SIZE ||
|
2018-02-14 21:03:15 +08:00
|
|
|
memcmp(&rx_buffer[DEST_ADDR_OFFSET],
|
|
|
|
dev_short_addr,
|
|
|
|
SHORT_ADDRESS_SIZE) != 0)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DEST_ADDR_TYPE_EXTENDED:
|
2019-06-19 02:45:40 +08:00
|
|
|
/* If not broadcast, check if length and address matches */
|
2018-01-11 22:06:53 +08:00
|
|
|
if (net_if_get_link_addr(upipe->iface)->len !=
|
|
|
|
EXTENDED_ADDRESS_SIZE ||
|
2018-02-14 21:03:15 +08:00
|
|
|
memcmp(&rx_buffer[DEST_ADDR_OFFSET],
|
|
|
|
dev_ext_addr, EXTENDED_ADDRESS_SIZE) != 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2020-05-28 00:26:57 +08:00
|
|
|
static uint8_t *upipe_rx(uint8_t *buf, size_t *off)
|
2016-08-17 22:48:36 +08:00
|
|
|
{
|
2017-04-05 14:37:44 +08:00
|
|
|
struct net_pkt *pkt = NULL;
|
drivers/ieee802154: Fix UPIPE driver at boot
Before it is initialized, upipe_dev is not set. Fixes this issue:
SeaBIOS (version rel-1.11.2-0-gf9626ccb91-prebuilt.qemu-project.org)
Booting from ROM..***** CPU Page Fault (error code 0x00000000)
Supervisor thread read address 0x00000008
PDE: 0x025 Present, Read-only, User, Execute Enabled
PTE: 0x00 Non-present, Read-only, Supervisor, Execute Enabled
Current thread ID = 0x00401a40
eax: 0x00000000, ebx: 0x0040c668, ecx: 0x00000001, edx: 0x000002f8
esi: 0x0040ac5b, edi: 0x0040ac38, ebp: 0x0040b4a8, esp: 0x0040b498
eflags: 0x00000202 cs: 0x0008
call trace:
eip: 0x00008651
0x000082a3 (0x400a8d)
0x00008b12 (0x40c668)
0x00008632
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2019-01-07 20:05:18 +08:00
|
|
|
struct upipe_context *upipe;
|
2016-08-17 22:48:36 +08:00
|
|
|
|
|
|
|
if (!upipe_dev) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2020-05-29 03:23:02 +08:00
|
|
|
upipe = upipe_dev->data;
|
2016-08-17 22:48:36 +08:00
|
|
|
if (!upipe->rx && *buf == UART_PIPE_RADIO_15_4_FRAME_TYPE) {
|
|
|
|
upipe->rx = true;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!upipe->rx_len) {
|
2023-12-07 18:17:17 +08:00
|
|
|
if (*buf > IEEE802154_MAX_PHY_PACKET_SIZE) {
|
2016-08-17 22:48:36 +08:00
|
|
|
goto flush;
|
|
|
|
}
|
|
|
|
|
|
|
|
upipe->rx_len = *buf;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
upipe->rx_buf[upipe->rx_off++] = *buf;
|
|
|
|
|
|
|
|
if (upipe->rx_len == upipe->rx_off) {
|
2023-12-07 18:17:17 +08:00
|
|
|
pkt = net_pkt_rx_alloc_with_buffer(upipe->iface, upipe->rx_len,
|
|
|
|
AF_UNSPEC, 0, K_NO_WAIT);
|
2017-04-03 23:14:35 +08:00
|
|
|
if (!pkt) {
|
2018-09-03 22:28:47 +08:00
|
|
|
LOG_DBG("No pkt available");
|
2016-08-17 22:48:36 +08:00
|
|
|
goto flush;
|
|
|
|
}
|
|
|
|
|
2023-12-07 18:17:17 +08:00
|
|
|
if (net_pkt_write(pkt, upipe->rx_buf, upipe->rx_len)) {
|
|
|
|
LOG_DBG("No content read?");
|
2016-08-17 22:48:36 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2018-02-14 21:03:15 +08:00
|
|
|
#if defined(CONFIG_IEEE802154_UPIPE_HW_FILTER)
|
2023-12-07 18:17:17 +08:00
|
|
|
if (received_dest_addr_matched(pkt->buffer->data) == false) {
|
2018-09-03 22:28:47 +08:00
|
|
|
LOG_DBG("Packet received is not addressed to me");
|
2018-02-14 21:03:15 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2023-06-03 01:56:49 +08:00
|
|
|
if (ieee802154_handle_ack(upipe->iface, pkt) == NET_OK) {
|
2018-09-03 22:28:47 +08:00
|
|
|
LOG_DBG("ACK packet handled");
|
2016-08-17 22:48:36 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2018-09-03 22:28:47 +08:00
|
|
|
LOG_DBG("Caught a packet (%u)", upipe->rx_len);
|
2017-04-03 23:14:35 +08:00
|
|
|
if (net_recv_data(upipe->iface, pkt) < 0) {
|
2018-09-03 22:28:47 +08:00
|
|
|
LOG_DBG("Packet dropped by NET stack");
|
2016-08-17 22:48:36 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
goto flush;
|
|
|
|
out:
|
2017-04-03 23:14:35 +08:00
|
|
|
net_pkt_unref(pkt);
|
2016-08-17 22:48:36 +08:00
|
|
|
flush:
|
|
|
|
upipe->rx = false;
|
2018-11-30 03:12:22 +08:00
|
|
|
upipe->rx_len = 0U;
|
|
|
|
upipe->rx_off = 0U;
|
2016-08-17 22:48:36 +08:00
|
|
|
}
|
|
|
|
done:
|
|
|
|
*off = 0;
|
|
|
|
|
2017-10-04 14:54:20 +08:00
|
|
|
return buf;
|
2016-08-17 22:48:36 +08:00
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static enum ieee802154_hw_caps upipe_get_capabilities(const struct device *dev)
|
2017-09-04 21:24:36 +08:00
|
|
|
{
|
2023-09-02 20:26:44 +08:00
|
|
|
return IEEE802154_HW_FCS | IEEE802154_HW_FILTER;
|
2017-09-04 21:24:36 +08:00
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static int upipe_cca(const struct device *dev)
|
2016-08-17 22:48:36 +08:00
|
|
|
{
|
2020-05-29 03:23:02 +08:00
|
|
|
struct upipe_context *upipe = dev->data;
|
2016-08-17 22:48:36 +08:00
|
|
|
|
|
|
|
if (upipe->stopped) {
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static int upipe_set_channel(const struct device *dev, uint16_t channel)
|
2016-08-17 22:48:36 +08:00
|
|
|
{
|
2018-07-23 16:59:20 +08:00
|
|
|
ARG_UNUSED(dev);
|
|
|
|
ARG_UNUSED(channel);
|
2016-08-17 22:48:36 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static int upipe_set_pan_id(const struct device *dev, uint16_t pan_id)
|
2018-02-14 21:03:15 +08:00
|
|
|
{
|
2020-05-28 00:26:57 +08:00
|
|
|
uint8_t pan_id_le[2];
|
2018-02-14 21:03:15 +08:00
|
|
|
|
|
|
|
ARG_UNUSED(dev);
|
|
|
|
|
|
|
|
sys_put_le16(pan_id, pan_id_le);
|
|
|
|
memcpy(dev_pan_id, pan_id_le, PAN_ID_SIZE);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static int upipe_set_short_addr(const struct device *dev, uint16_t short_addr)
|
2018-02-14 21:03:15 +08:00
|
|
|
{
|
2020-05-28 00:26:57 +08:00
|
|
|
uint8_t short_addr_le[2];
|
2018-02-14 21:03:15 +08:00
|
|
|
|
|
|
|
ARG_UNUSED(dev);
|
|
|
|
|
|
|
|
sys_put_le16(short_addr, short_addr_le);
|
|
|
|
memcpy(dev_short_addr, short_addr_le, SHORT_ADDRESS_SIZE);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static int upipe_set_ieee_addr(const struct device *dev,
|
|
|
|
const uint8_t *ieee_addr)
|
2018-02-14 21:03:15 +08:00
|
|
|
{
|
|
|
|
ARG_UNUSED(dev);
|
|
|
|
|
|
|
|
memcpy(dev_ext_addr, ieee_addr, EXTENDED_ADDRESS_SIZE);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static int upipe_filter(const struct device *dev,
|
2018-03-19 16:53:29 +08:00
|
|
|
bool set,
|
|
|
|
enum ieee802154_filter_type type,
|
|
|
|
const struct ieee802154_filter *filter)
|
2018-02-14 21:03:15 +08:00
|
|
|
{
|
2018-09-03 22:28:47 +08:00
|
|
|
LOG_DBG("Applying filter %u", type);
|
2018-02-14 21:03:15 +08:00
|
|
|
|
2018-03-19 16:53:29 +08:00
|
|
|
if (!set) {
|
|
|
|
return -ENOTSUP;
|
|
|
|
}
|
|
|
|
|
2018-02-14 21:03:15 +08:00
|
|
|
if (type == IEEE802154_FILTER_TYPE_IEEE_ADDR) {
|
|
|
|
return upipe_set_ieee_addr(dev, filter->ieee_addr);
|
|
|
|
} else if (type == IEEE802154_FILTER_TYPE_SHORT_ADDR) {
|
|
|
|
return upipe_set_short_addr(dev, filter->short_addr);
|
|
|
|
} else if (type == IEEE802154_FILTER_TYPE_PAN_ID) {
|
|
|
|
return upipe_set_pan_id(dev, filter->pan_id);
|
|
|
|
}
|
|
|
|
|
2018-03-19 16:53:29 +08:00
|
|
|
return -ENOTSUP;
|
2018-02-14 21:03:15 +08:00
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static int upipe_set_txpower(const struct device *dev, int16_t dbm)
|
2016-08-17 22:48:36 +08:00
|
|
|
{
|
2018-07-23 16:59:20 +08:00
|
|
|
ARG_UNUSED(dev);
|
|
|
|
ARG_UNUSED(dbm);
|
2016-08-17 22:48:36 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static int upipe_tx(const struct device *dev,
|
net: ieee802154_radio: Allow to specify TX mode
Even though radio driver can report in its capabilities that it does
support CSMA CA, there's no way in the driver to select how the frame
should be transmitted (with CSMA or without). As layers above radio
driver (Thread, Zigbee) can expect that both TX modes are available, we
need to extend the API to allow either of these modes.
This commits extends the API `tx` function with an extra parameter,
`ieee802154_tx_mode`, which informs the driver how the packet should be
transmitted. Currently, the following modes are specified:
* direct (regular tx, no cca, just how it worked so far),
* CCA before transmission,
* CSMA CA before transmission,
* delayed TX,
* delayed TX with CCA
Assume that radios that reported CSMA CA capability transmit in CSMA CA
mode by default, all others will support direct mode.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-02-28 20:57:49 +08:00
|
|
|
enum ieee802154_tx_mode mode,
|
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-08-17 22:48:36 +08:00
|
|
|
{
|
2020-05-29 03:23:02 +08:00
|
|
|
struct upipe_context *upipe = dev->data;
|
2020-05-28 00:26:57 +08:00
|
|
|
uint8_t *pkt_buf = frag->data;
|
|
|
|
uint8_t len = frag->len;
|
|
|
|
uint8_t i, data;
|
2016-08-17 22:48:36 +08:00
|
|
|
|
net: ieee802154_radio: Allow to specify TX mode
Even though radio driver can report in its capabilities that it does
support CSMA CA, there's no way in the driver to select how the frame
should be transmitted (with CSMA or without). As layers above radio
driver (Thread, Zigbee) can expect that both TX modes are available, we
need to extend the API to allow either of these modes.
This commits extends the API `tx` function with an extra parameter,
`ieee802154_tx_mode`, which informs the driver how the packet should be
transmitted. Currently, the following modes are specified:
* direct (regular tx, no cca, just how it worked so far),
* CCA before transmission,
* CSMA CA before transmission,
* delayed TX,
* delayed TX with CCA
Assume that radios that reported CSMA CA capability transmit in CSMA CA
mode by default, all others will support direct mode.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-02-28 20:57:49 +08:00
|
|
|
if (mode != IEEE802154_TX_MODE_DIRECT) {
|
|
|
|
NET_ERR("TX mode %d not supported", mode);
|
|
|
|
return -ENOTSUP;
|
|
|
|
}
|
|
|
|
|
2018-09-03 22:28:47 +08:00
|
|
|
LOG_DBG("%p (%u)", frag, len);
|
2016-08-17 22:48:36 +08:00
|
|
|
|
|
|
|
if (upipe->stopped) {
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
data = UART_PIPE_RADIO_15_4_FRAME_TYPE;
|
|
|
|
uart_pipe_send(&data, 1);
|
|
|
|
|
2017-10-18 22:37:08 +08:00
|
|
|
data = len;
|
2016-08-17 22:48:36 +08:00
|
|
|
uart_pipe_send(&data, 1);
|
|
|
|
|
2018-11-30 03:12:22 +08:00
|
|
|
for (i = 0U; i < len; i++) {
|
2016-08-17 22:48:36 +08:00
|
|
|
uart_pipe_send(pkt_buf+i, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static int upipe_start(const struct device *dev)
|
2016-08-17 22:48:36 +08:00
|
|
|
{
|
2020-05-29 03:23:02 +08:00
|
|
|
struct upipe_context *upipe = dev->data;
|
2016-08-17 22:48:36 +08:00
|
|
|
|
|
|
|
if (!upipe->stopped) {
|
|
|
|
return -EALREADY;
|
|
|
|
}
|
|
|
|
|
|
|
|
upipe->stopped = false;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static int upipe_stop(const struct device *dev)
|
2016-08-17 22:48:36 +08:00
|
|
|
{
|
2020-05-29 03:23:02 +08:00
|
|
|
struct upipe_context *upipe = dev->data;
|
2016-08-17 22:48:36 +08:00
|
|
|
|
|
|
|
if (upipe->stopped) {
|
|
|
|
return -EALREADY;
|
|
|
|
}
|
|
|
|
|
|
|
|
upipe->stopped = true;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-09-02 20:26:44 +08:00
|
|
|
/* driver-allocated attribute memory - constant across all driver instances */
|
|
|
|
IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26);
|
|
|
|
|
|
|
|
/* API implementation: attr_get */
|
|
|
|
static int upipe_attr_get(const struct device *dev, enum ieee802154_attr attr,
|
|
|
|
struct ieee802154_attr_value *value)
|
|
|
|
{
|
|
|
|
ARG_UNUSED(dev);
|
|
|
|
|
|
|
|
return ieee802154_attr_get_channel_page_and_range(
|
|
|
|
attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915,
|
|
|
|
&drv_attr.phy_supported_channels, value);
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static int upipe_init(const struct device *dev)
|
2016-08-17 22:48:36 +08:00
|
|
|
{
|
2020-05-29 03:23:02 +08:00
|
|
|
struct upipe_context *upipe = dev->data;
|
2016-08-17 22:48:36 +08:00
|
|
|
|
2018-09-12 10:09:03 +08:00
|
|
|
(void)memset(upipe, 0, sizeof(struct upipe_context));
|
2016-08-17 22:48:36 +08:00
|
|
|
|
|
|
|
uart_pipe_register(upipe->uart_pipe_buf, 1, upipe_rx);
|
|
|
|
|
|
|
|
upipe_stop(dev);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static inline uint8_t *get_mac(const struct device *dev)
|
2016-08-17 22:48:36 +08:00
|
|
|
{
|
2020-05-29 03:23:02 +08:00
|
|
|
struct upipe_context *upipe = dev->data;
|
2016-08-17 22:48:36 +08:00
|
|
|
|
|
|
|
upipe->mac_addr[0] = 0x00;
|
|
|
|
upipe->mac_addr[1] = 0x10;
|
|
|
|
upipe->mac_addr[2] = 0x20;
|
|
|
|
upipe->mac_addr[3] = 0x30;
|
|
|
|
|
2018-02-14 21:03:15 +08:00
|
|
|
#if defined(CONFIG_IEEE802154_UPIPE_RANDOM_MAC)
|
2024-04-03 17:38:07 +08:00
|
|
|
sys_rand_get(&upipe->mac_addr[4], 4U);
|
2018-02-14 21:03:15 +08:00
|
|
|
#else
|
|
|
|
upipe->mac_addr[4] = CONFIG_IEEE802154_UPIPE_MAC4;
|
|
|
|
upipe->mac_addr[5] = CONFIG_IEEE802154_UPIPE_MAC5;
|
|
|
|
upipe->mac_addr[6] = CONFIG_IEEE802154_UPIPE_MAC6;
|
|
|
|
upipe->mac_addr[7] = CONFIG_IEEE802154_UPIPE_MAC7;
|
|
|
|
#endif
|
2016-08-17 22:48:36 +08:00
|
|
|
|
|
|
|
return upipe->mac_addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void upipe_iface_init(struct net_if *iface)
|
|
|
|
{
|
2020-05-01 02:33:38 +08:00
|
|
|
const struct device *dev = net_if_get_device(iface);
|
2020-05-29 03:23:02 +08:00
|
|
|
struct upipe_context *upipe = dev->data;
|
2020-05-28 00:26:57 +08:00
|
|
|
uint8_t *mac = get_mac(dev);
|
2016-08-17 22:48:36 +08:00
|
|
|
|
2017-02-15 19:20:31 +08:00
|
|
|
net_if_set_link_addr(iface, mac, 8, NET_LINK_IEEE802154);
|
2016-08-17 22:48:36 +08:00
|
|
|
|
|
|
|
upipe_dev = dev;
|
|
|
|
upipe->iface = iface;
|
|
|
|
|
|
|
|
ieee802154_init(iface);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct upipe_context upipe_context_data;
|
|
|
|
|
2023-12-25 23:16:28 +08:00
|
|
|
static const struct ieee802154_radio_api upipe_radio_api = {
|
2016-08-17 22:48:36 +08:00
|
|
|
.iface_api.init = upipe_iface_init,
|
|
|
|
|
2017-09-04 21:24:36 +08:00
|
|
|
.get_capabilities = upipe_get_capabilities,
|
2016-08-17 22:48:36 +08:00
|
|
|
.cca = upipe_cca,
|
|
|
|
.set_channel = upipe_set_channel,
|
2018-03-19 16:53:29 +08:00
|
|
|
.filter = upipe_filter,
|
2016-08-17 22:48:36 +08:00
|
|
|
.set_txpower = upipe_set_txpower,
|
|
|
|
.tx = upipe_tx,
|
|
|
|
.start = upipe_start,
|
|
|
|
.stop = upipe_stop,
|
2023-09-02 20:26:44 +08:00
|
|
|
.attr_get = upipe_attr_get,
|
2016-08-17 22:48:36 +08:00
|
|
|
};
|
|
|
|
|
2022-07-18 17:40:20 +08:00
|
|
|
NET_DEVICE_DT_INST_DEFINE(0, upipe_init, NULL, &upipe_context_data, NULL,
|
|
|
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &upipe_radio_api,
|
|
|
|
IEEE802154_L2, NET_L2_GET_CTX_TYPE(IEEE802154_L2),
|
2024-09-06 17:52:05 +08:00
|
|
|
IEEE802154_MTU);
|