net/ieee802154: Finally removing usage of ll_reserve in L2

Moving towards serialized fragmentation, adapting mac command creation
to avoid the need of ll_reserve etc...

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2018-10-24 15:08:50 +02:00 committed by Carles Cufí
commit 6ea225e34a
11 changed files with 121 additions and 114 deletions

View file

@ -608,8 +608,8 @@ static int cc1200_tx(struct device *dev,
struct net_buf *frag)
{
struct cc1200_context *cc1200 = dev->driver_data;
u8_t *frame = frag->data - net_pkt_ll_reserve(pkt);
u8_t len = net_pkt_ll_reserve(pkt) + frag->len;
u8_t *frame = frag->data;
u8_t len = frag->len;
bool status = false;
LOG_DBG("%p (%u)", frag, len);

View file

@ -813,8 +813,8 @@ static int cc2520_tx(struct device *dev,
struct net_pkt *pkt,
struct net_buf *frag)
{
u8_t *frame = frag->data - net_pkt_ll_reserve(pkt);
u8_t len = net_pkt_ll_reserve(pkt) + frag->len;
u8_t *frame = frag->data;
u8_t len = frag->len;
struct cc2520_context *cc2520 = dev->driver_data;
u8_t retry = 2U;
bool status;

View file

@ -558,7 +558,7 @@ static int kw41z_tx(struct device *dev, struct net_pkt *pkt,
struct net_buf *frag)
{
struct kw41z_context *kw41z = dev->driver_data;
u8_t payload_len = net_pkt_ll_reserve(pkt) + frag->len;
u8_t payload_len = frag->len;
u32_t tx_timeout;
u8_t xcvseq;
int key;
@ -587,11 +587,11 @@ static int kw41z_tx(struct device *dev, struct net_pkt *pkt,
#if CONFIG_SOC_MKW41Z4
((u8_t *)ZLL->PKT_BUFFER_TX)[0] = payload_len + KW41Z_FCS_LENGTH;
memcpy(((u8_t *)ZLL->PKT_BUFFER_TX) + 1,
(void *)(frag->data - net_pkt_ll_reserve(pkt)), payload_len);
(void *)frag->data, payload_len);
#else /* CONFIG_SOC_MKW40Z4 */
((u8_t *)ZLL->PKT_BUFFER)[0] = payload_len + KW41Z_FCS_LENGTH;
memcpy(((u8_t *)ZLL->PKT_BUFFER) + 1,
(void *)(frag->data - net_pkt_ll_reserve(pkt)), payload_len);
(void *)frag->data, payload_len);
#endif
/* Set CCA mode */
@ -612,15 +612,14 @@ static int kw41z_tx(struct device *dev, struct net_pkt *pkt,
KW41Z_ACK_WAIT_TIME;
LOG_DBG("AUTOACK ENABLED: len: %d, timeout: %d, seq: %d",
payload_len, tx_timeout,
(frag->data - net_pkt_ll_reserve(pkt))[2]);
payload_len, tx_timeout, frag->data[2]);
kw41z_tmr3_set_timeout(tx_timeout);
ZLL->PHY_CTRL |= ZLL_PHY_CTRL_RXACKRQD_MASK;
xcvseq = KW41Z_STATE_TXRX;
} else {
LOG_DBG("AUTOACK DISABLED: len: %d, seq: %d",
payload_len, (frag->data - net_pkt_ll_reserve(pkt))[2]);
payload_len, frag->data[2]);
ZLL->PHY_CTRL &= ~ZLL_PHY_CTRL_RXACKRQD_MASK;
xcvseq = KW41Z_STATE_TX;

View file

@ -1065,7 +1065,7 @@ static inline bool write_txfifo_content(struct mcr20a_context *dev,
struct net_pkt *pkt,
struct net_buf *frag)
{
size_t payload_len = net_pkt_ll_reserve(pkt) + frag->len;
size_t payload_len = frag->len;
u8_t cmd_buf[2] = {
MCR20A_BUF_WRITE,
payload_len + MCR20A_FCS_LENGTH
@ -1076,7 +1076,7 @@ static inline bool write_txfifo_content(struct mcr20a_context *dev,
.len = 2
},
{
.buf = frag->data - net_pkt_ll_reserve(pkt),
.buf = frag->data,
.len = payload_len
}
};
@ -1104,8 +1104,7 @@ static int mcr20a_tx(struct device *dev,
k_mutex_lock(&mcr20a->phy_mutex, K_FOREVER);
LOG_DBG("%p (%u)",
frag, net_pkt_ll_reserve(pkt) + frag->len);
LOG_DBG("%p (%u)", frag, frag->len);
if (!mcr20a_mask_irqb(mcr20a, true)) {
LOG_ERR("Failed to mask IRQ_B");

View file

@ -263,8 +263,8 @@ static int nrf5_tx(struct device *dev,
struct net_buf *frag)
{
struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
u8_t payload_len = net_pkt_ll_reserve(pkt) + frag->len;
u8_t *payload = frag->data - net_pkt_ll_reserve(pkt);
u8_t payload_len = frag->len;
u8_t *payload = frag->data;
LOG_DBG("%p (%u)", payload, payload_len);

View file

@ -267,9 +267,9 @@ static int upipe_tx(struct device *dev,
struct net_pkt *pkt,
struct net_buf *frag)
{
u8_t *pkt_buf = frag->data - net_pkt_ll_reserve(pkt);
u8_t len = net_pkt_ll_reserve(pkt) + frag->len;
struct upipe_context *upipe = dev->driver_data;
u8_t *pkt_buf = frag->data;
u8_t len = frag->len;
u8_t i, data;
LOG_DBG("%p (%u)", frag, len);

View file

@ -15,12 +15,8 @@ LOG_MODULE_REGISTER(net_ieee802154, CONFIG_NET_L2_IEEE802154_LOG_LEVEL);
#include <errno.h>
#ifdef CONFIG_NET_6LO
#ifdef CONFIG_NET_L2_IEEE802154_FRAGMENT
#include "ieee802154_fragment.h"
#endif
#include <6lo.h>
#endif /* CONFIG_NET_6LO */
#include <net/ieee802154_radio.h>
@ -32,6 +28,16 @@ LOG_MODULE_REGISTER(net_ieee802154, CONFIG_NET_L2_IEEE802154_LOG_LEVEL);
#define BUF_TIMEOUT K_MSEC(50)
/* No need to hold space for the FCS */
static u8_t frame_buffer_data[IEEE802154_MTU - 2];
static struct net_buf frame_buf = {
.data = frame_buffer_data,
.size = IEEE802154_MTU - 2,
.frags = NULL,
.__buf = frame_buffer_data,
};
#define PKT_TITLE "IEEE 802.15.4 packet content:"
#define TX_PKT_TITLE "> " PKT_TITLE
#define RX_PKT_TITLE "< " PKT_TITLE
@ -41,18 +47,16 @@ LOG_MODULE_REGISTER(net_ieee802154, CONFIG_NET_L2_IEEE802154_LOG_LEVEL);
#include "net_private.h"
static inline void pkt_hexdump(const char *title, struct net_pkt *pkt,
bool in, bool full)
bool in)
{
if ((IS_ENABLED(CONFIG_NET_DEBUG_L2_IEEE802154_DISPLAY_PACKET_RX) ||
IS_ENABLED(CONFIG_NET_DEBUG_L2_IEEE802154_DISPLAY_PACKET_FULL)) &&
if (IS_ENABLED(CONFIG_NET_DEBUG_L2_IEEE802154_DISPLAY_PACKET_RX) &&
in) {
net_hexdump_frags(title, pkt, full);
net_hexdump_frags(title, pkt, false);
}
if ((IS_ENABLED(CONFIG_NET_DEBUG_L2_IEEE802154_DISPLAY_PACKET_TX) ||
IS_ENABLED(CONFIG_NET_DEBUG_L2_IEEE802154_DISPLAY_PACKET_FULL)) &&
if (IS_ENABLED(CONFIG_NET_DEBUG_L2_IEEE802154_DISPLAY_PACKET_TX) &&
!in) {
net_hexdump_frags(title, pkt, full);
net_hexdump_frags(title, pkt, false);
}
}
@ -71,7 +75,7 @@ static inline void ieee802154_acknowledge(struct net_if *iface,
return;
}
pkt = net_pkt_get_reserve_tx(IEEE802154_ACK_PKT_LENGTH, BUF_TIMEOUT);
pkt = net_pkt_get_reserve_tx(0, BUF_TIMEOUT);
if (!pkt) {
return;
}
@ -170,34 +174,12 @@ enum net_verdict ieee802154_manage_recv_packet(struct net_if *iface,
net_pkt_lladdr_src(pkt)->addr = src ? net_pkt_ll(pkt) + src : NULL;
net_pkt_lladdr_dst(pkt)->addr = dst ? net_pkt_ll(pkt) + dst : NULL;
pkt_hexdump(RX_PKT_TITLE, pkt, true, false);
pkt_hexdump(RX_PKT_TITLE, pkt, true);
out:
return verdict;
}
static inline bool ieee802154_manage_send_packet(struct net_if *iface,
struct net_pkt *pkt)
{
int ret;
pkt_hexdump(TX_PKT_TITLE " (before 6lo)", pkt, false, false);
ret = net_6lo_compress(pkt, true);
pkt_hexdump(TX_PKT_TITLE " (after 6lo)", pkt, false, false);
if (ret >= 0 && IS_ENABLED(CONFIG_NET_L2_IEEE802154_FRAGMENT)) {
return ieee802154_fragment(pkt, ret);
}
return (ret >= 0);
}
#else /* CONFIG_NET_6LO */
#define ieee802154_manage_recv_packet(...) NET_CONTINUE
#define ieee802154_manage_send_packet(...) true
#endif /* CONFIG_NET_6LO */
static enum net_verdict ieee802154_recv(struct net_if *iface,
@ -227,9 +209,6 @@ static enum net_verdict ieee802154_recv(struct net_if *iface,
ieee802154_acknowledge(iface, &mpdu);
net_pkt_set_ll_reserve(pkt, (u8_t *)mpdu.payload - net_pkt_ll(pkt));
net_buf_pull(pkt->frags, net_pkt_ll_reserve(pkt));
set_pkt_ll_addr(net_pkt_lladdr_src(pkt), mpdu.mhr.fs->fc.pan_id_comp,
mpdu.mhr.fs->fc.src_addr_mode, mpdu.mhr.src_addr);
@ -240,7 +219,10 @@ static enum net_verdict ieee802154_recv(struct net_if *iface,
return NET_DROP;
}
pkt_hexdump(RX_PKT_TITLE " (with ll)", pkt, true, true);
pkt_hexdump(RX_PKT_TITLE " (with ll)", pkt, true);
net_pkt_set_ll(pkt, net_pkt_ll(pkt));
net_buf_pull(pkt->frags, (u8_t *)mpdu.payload - net_pkt_ll(pkt));
return ieee802154_manage_recv_packet(iface, pkt);
}
@ -248,49 +230,68 @@ static enum net_verdict ieee802154_recv(struct net_if *iface,
static int ieee802154_send(struct net_if *iface, struct net_pkt *pkt)
{
struct ieee802154_context *ctx = net_if_l2_data(iface);
u8_t reserved_space = net_pkt_ll_reserve(pkt);
struct ieee802154_fragment_ctx f_ctx;
struct net_buf *frag;
u8_t ll_hdr_size;
bool fragment;
int len;
if (net_pkt_family(pkt) != AF_INET6) {
return -EINVAL;
}
if (!ieee802154_manage_send_packet(iface, pkt)) {
return -ENOBUFS;
/* len will hold the hdr size difference on success */
len = net_6lo_compress(pkt, true);
if (len < 0) {
return len;
}
len = 0;
ll_hdr_size = ieee802154_compute_header_size(iface,
&NET_IPV6_HDR(pkt)->dst);
fragment = ieee802154_fragment_is_needed(pkt, ll_hdr_size);
ieee802154_fragment_ctx_init(&f_ctx, pkt, len, true);
len = 0;
frame_buf.len = 0;
frag = pkt->frags;
while (frag) {
int ret;
if (frag->len > IEEE802154_MTU) {
NET_ERR("Frag %p as too big length %u",
frag, frag->len);
return -EINVAL;
net_buf_add(&frame_buf, ll_hdr_size);
if (fragment) {
ieee802154_fragment(&f_ctx, &frame_buf, true);
frag = f_ctx.frag;
} else {
memcpy(frame_buf.data + frame_buf.len,
frag->data, frag->len);
net_buf_add(&frame_buf, frag->len);
frag = frag->frags;
}
if (!ieee802154_create_data_frame(ctx, net_pkt_lladdr_dst(pkt),
frag, reserved_space)) {
&frame_buf, ll_hdr_size)) {
return -EINVAL;
}
if (IS_ENABLED(CONFIG_NET_L2_IEEE802154_RADIO_CSMA_CA) &&
ieee802154_get_hw_capabilities(iface) &
IEEE802154_HW_CSMA) {
ret = ieee802154_tx(iface, pkt, frag);
ret = ieee802154_tx(iface, pkt, &frame_buf);
} else {
ret = ieee802154_radio_send(iface, pkt, frag);
ret = ieee802154_radio_send(iface, pkt, &frame_buf);
}
if (ret) {
return ret;
}
len += frag->len;
frag = frag->frags;
len += frame_buf.len;
/* Reinitializing frame_buf */
frame_buf.len = 0;
}
net_pkt_unref(pkt);
@ -300,7 +301,10 @@ static int ieee802154_send(struct net_if *iface, struct net_pkt *pkt)
static u16_t ieee802154_reserve(struct net_if *iface, void *data)
{
return ieee802154_compute_header_size(iface, (struct in6_addr *)data);
ARG_UNUSED(iface);
ARG_UNUSED(data);
return 0;
}
static int ieee802154_enable(struct net_if *iface, bool state)

View file

@ -410,10 +410,10 @@ bool ieee802154_validate_frame(u8_t *buf, u8_t length,
return validate_payload_and_mfr(mpdu, buf, p_buf, length);
}
u16_t ieee802154_compute_header_size(struct net_if *iface,
struct in6_addr *dst)
u8_t ieee802154_compute_header_size(struct net_if *iface,
struct in6_addr *dst)
{
u16_t hdr_len = sizeof(struct ieee802154_fcf_seq);
u8_t hdr_len = sizeof(struct ieee802154_fcf_seq);
#ifdef CONFIG_NET_L2_IEEE802154_SECURITY
struct ieee802154_security_ctx *sec_ctx =
&((struct ieee802154_context *)net_if_l2_data(iface))->sec_ctx;
@ -473,14 +473,13 @@ u16_t ieee802154_compute_header_size(struct net_if *iface,
hdr_len += IEEE8021254_KEY_ID_FIELD_SRC_8_INDEX_LENGTH;
}
/* This is a _HACK_: as net pkt do not let the possibility to
* reserve tailroom - here for authentication tag - it reserves
/* This is a _HACK_: as net_buf do not let the possibility to
* reserve tailroom - here for authentication tag - it "reserves"
* it in headroom so the payload won't occupy all the left space
* and then when it will come to finalize the data frame it will
* reduce the reserve space by the tag size, move the payload
* backward accordingly, and only then:
* run the encryption/authentication which will fill the tag
* space in the end.
* reduce the reserved space by the tag size, move the payload
* backward accordingly, and only then: run the
* encryption/authentication which will fill the tag space in the end.
*/
if (sec_ctx->level < IEEE802154_SECURITY_LEVEL_ENC) {
hdr_len += level_2_tag_size[sec_ctx->level];
@ -656,11 +655,11 @@ u8_t *generate_aux_security_hdr(struct ieee802154_security_ctx *sec_ctx,
bool ieee802154_create_data_frame(struct ieee802154_context *ctx,
struct net_linkaddr *dst,
struct net_buf *frag,
u8_t reserved_len)
u8_t hdr_size)
{
struct ieee802154_frame_params params;
struct ieee802154_fcf_seq *fs;
u8_t *p_buf = frag->data - reserved_len;
u8_t *p_buf = frag->data;
u8_t *frag_start = p_buf;
bool broadcast;
@ -687,7 +686,7 @@ bool ieee802154_create_data_frame(struct ieee802154_context *ctx,
p_buf = generate_aux_security_hdr(&ctx->sec_ctx, p_buf);
/* If tagged, let's retrieve tag space from ll reserved space.
/* If tagged, let's retrieve tag space from hdr reserved space.
* See comment in ieee802154_compute_header_size()
*/
if (ctx->sec_ctx.level != IEEE802154_SECURITY_LEVEL_NONE &&
@ -701,18 +700,18 @@ bool ieee802154_create_data_frame(struct ieee802154_context *ctx,
/* p_buf should point to the right place */
memmove(p_buf, frag->data, frag->len);
reserved_len -= level_2_tag_size[level];
hdr_size -= level_2_tag_size[level];
}
no_security_hdr:
#endif /* CONFIG_NET_L2_IEEE802154_SECURITY */
if ((p_buf - frag_start) != reserved_len) {
/* ll reserve was too small? We probably overwrote
if ((p_buf - frag_start) != hdr_size) {
/* hdr_size was too small? We probably overwrote
* payload bytes
*/
NET_ERR("Could not generate data frame %zu vs %u",
(p_buf - frag_start), reserved_len);
(p_buf - frag_start), hdr_size);
return false;
}
@ -720,7 +719,7 @@ no_security_hdr:
/* Let's encrypt/auth only in the end, is needed */
return ieee802154_encrypt_auth(broadcast ? NULL : &ctx->sec_ctx,
frag_start, reserved_len, frag->len,
frag_start, hdr_size, frag->len,
ctx->ext_addr);
}
@ -789,25 +788,25 @@ static inline bool cfi_to_fs_settings(enum ieee802154_cfi cfi,
static inline u8_t mac_command_length(enum ieee802154_cfi cfi)
{
u8_t reserve = 1U; /* cfi is at least present */
u8_t length = 1U; /* cfi is at least present */
switch (cfi) {
case IEEE802154_CFI_ASSOCIATION_REQUEST:
case IEEE802154_CFI_DISASSOCIATION_NOTIFICATION:
case IEEE802154_CFI_GTS_REQUEST:
reserve += 1;
length += 1;
break;
case IEEE802154_CFI_ASSOCIATION_RESPONSE:
reserve += 3;
length += 3;
break;
case IEEE802154_CFI_COORDINATOR_REALIGNEMENT:
reserve += 8;
length += 8;
break;
default:
break;
}
return reserve;
return length;
}
struct net_pkt *
@ -846,23 +845,11 @@ ieee802154_create_mac_cmd_frame(struct ieee802154_context *ctx,
p_buf = generate_addressing_fields(ctx, fs, params, p_buf);
net_buf_add(frag, p_buf - net_pkt_ll(pkt));
/* Let's insert the cfi */
((struct ieee802154_command *)p_buf)->cfi = type;
/* In MAC command, we consider ll header being the mhr.
* Rest will be the MAC command itself. This will proove
* to be easy to handle afterwards to point directly to MAC
* command space, in order to fill-in its content.
*/
net_pkt_set_ll_reserve(pkt, p_buf - net_pkt_ll(pkt));
net_buf_pull(frag, net_pkt_ll_reserve(pkt));
/* Thus setting the right MAC command length
* Now up to the caller to fill-in this space relevantly.
* See ieee802154_mac_command() helper.
*/
frag->len = mac_command_length(type);
dbg_print_fs(fs);
return pkt;
@ -871,6 +858,13 @@ error:
return NULL;
}
void ieee802154_mac_cmd_finalize(struct net_pkt *pkt,
enum ieee802154_cfi type)
{
net_buf_add(pkt->frags, mac_command_length(type));
}
#endif /* CONFIG_NET_L2_IEEE802154_RFD */
#ifdef CONFIG_NET_L2_IEEE802154_ACK_REPLY
@ -920,7 +914,7 @@ bool ieee802154_decipher_data_frame(struct net_if *iface, struct net_pkt *pkt,
* in order to get the extended address related to it
*/
if (!ieee802154_decrypt_auth(&ctx->sec_ctx, net_pkt_ll(pkt),
net_pkt_ll_reserve(pkt),
(u8_t *)mpdu->payload - net_pkt_ll(pkt),
net_pkt_get_len(pkt),
net_pkt_lladdr_src(pkt)->addr,
sys_le32_to_cpu(

View file

@ -460,23 +460,27 @@ struct ieee802154_fcf_seq *ieee802154_validate_fc_seq(u8_t *buf, u8_t **p_buf);
bool ieee802154_validate_frame(u8_t *buf, u8_t length,
struct ieee802154_mpdu *mpdu);
u16_t ieee802154_compute_header_size(struct net_if *iface,
struct in6_addr *dst);
u8_t ieee802154_compute_header_size(struct net_if *iface,
struct in6_addr *dst);
bool ieee802154_create_data_frame(struct ieee802154_context *ctx,
struct net_linkaddr *dst,
struct net_buf *frag,
u8_t reserved_len);
u8_t hdr_size);
struct net_pkt *
ieee802154_create_mac_cmd_frame(struct ieee802154_context *ctx,
enum ieee802154_cfi type,
struct ieee802154_frame_params *params);
void ieee802154_mac_cmd_finalize(struct net_pkt *pkt,
enum ieee802154_cfi type);
static inline
struct ieee802154_command *ieee802154_get_mac_command(struct net_pkt *pkt)
{
return (struct ieee802154_command *)net_pkt_ip_data(pkt);
return (struct ieee802154_command *)(pkt->frags->data +
pkt->frags->len);
}
#ifdef CONFIG_NET_L2_IEEE802154_ACK_REPLY

View file

@ -109,6 +109,8 @@ static int ieee802154_scan(u32_t mgmt_request, struct net_if *iface,
NET_DBG("Could not create Beacon Request");
return -ENOBUFS;
}
ieee802154_mac_cmd_finalize(pkt, IEEE802154_CFI_BEACON_REQUEST);
}
ctx->scan_ctx = scan;
@ -262,6 +264,8 @@ static int ieee802154_associate(u32_t mgmt_request, struct net_if *iface,
ctx->associated = false;
ieee802154_mac_cmd_finalize(pkt, IEEE802154_CFI_ASSOCIATION_REQUEST);
if (net_if_send_data(iface, pkt)) {
net_pkt_unref(pkt);
ret = -EIO;
@ -326,6 +330,9 @@ static int ieee802154_disassociate(u32_t mgmt_request, struct net_if *iface,
cmd = ieee802154_get_mac_command(pkt);
cmd->disassoc_note.reason = IEEE802154_DRF_DEVICE_WISH;
ieee802154_mac_cmd_finalize(
pkt, IEEE802154_CFI_DISASSOCIATION_NOTIFICATION);
if (net_if_send_data(iface, pkt)) {
net_pkt_unref(pkt);
return -EIO;

View file

@ -28,8 +28,8 @@ static inline bool prepare_for_ack(struct ieee802154_context *ctx,
if (ieee802154_is_ar_flag_set(pkt)) {
struct ieee802154_fcf_seq *fs;
fs = (struct ieee802154_fcf_seq *)(frag->data -
net_pkt_ll_reserve(pkt));
fs = (struct ieee802154_fcf_seq *)net_pkt_ll(pkt);
ctx->ack_seq = fs->sequence;
ctx->ack_received = false;
k_sem_init(&ctx->ack_lock, 0, UINT_MAX);