1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

drivers: net: adapt to iolist-using netdev

This commit is contained in:
Kaspar Schleiser 2018-01-12 00:19:03 +01:00
parent 2f179f26bb
commit 23b414b732
25 changed files with 222 additions and 275 deletions

View File

@ -14,6 +14,7 @@ ifneq (,$(filter can,$(USEMODULE)))
endif
ifneq (,$(filter socket_zep,$(USEMODULE)))
USEMODULE += iolist
USEMODULE += netdev_ieee802154
USEMODULE += checksum
USEMODULE += random

View File

@ -33,22 +33,6 @@
#define _MAX_MHR_OVERHEAD (25)
static int _get(netdev_t *dev, netopt_t opt, void *value, size_t max_len);
static int _set(netdev_t *dev, netopt_t opt, const void *value, size_t value_len);
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count);
static int _recv(netdev_t *netdev, void *buf, size_t len, void *info);
static void _isr(netdev_t *netdev);
static int _init(netdev_t *dev);
const netdev_driver_t cc2538_rf_driver = {
.get = _get,
.set = _set,
.send = _send,
.recv = _recv,
.isr = _isr,
.init = _init,
};
/* Reference pointer for the IRQ handler */
static netdev_t *_dev;
@ -253,7 +237,7 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *value, size_t value_
return res;
}
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
static int _send(netdev_t *netdev, const iolist_t *iolist)
{
(void) netdev;
@ -268,8 +252,8 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
start of the FIFO, so we can come back and update it later */
rfcore_write_byte(0);
for (unsigned i = 0; i < count; i++) {
pkt_len += vector[i].iov_len;
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
pkt_len += iol->iol_len;
if (pkt_len > CC2538_RF_MAX_DATA_LEN) {
DEBUG("cc2538_rf: packet too large (%u > %u)\n",
@ -277,7 +261,7 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
return -EOVERFLOW;
}
rfcore_write_fifo(vector[i].iov_base, vector[i].iov_len);
rfcore_write_fifo(iol->iol_base, iol->iol_len);
}
#ifdef MODULE_NETSTATS_L2
@ -407,3 +391,12 @@ static int _init(netdev_t *netdev)
return 0;
}
const netdev_driver_t cc2538_rf_driver = {
.get = _get,
.set = _set,
.send = _send,
.recv = _recv,
.isr = _isr,
.init = _init,
};

View File

@ -36,23 +36,6 @@
#define _UNIX_NTP_ERA_OFFSET (2208988800U)
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned n);
static int _recv(netdev_t *netdev, void *buf, size_t n, void *info);
static void _isr(netdev_t *netdev);
static int _init(netdev_t *netdev);
static int _get(netdev_t *netdev, netopt_t opt, void *value, size_t max_len);
static int _set(netdev_t *netdev, netopt_t opt, const void *value,
size_t value_len);
static const netdev_driver_t socket_zep_driver = {
.send = _send,
.recv = _recv,
.init = _init,
.isr = _isr,
.get = _get,
.set = _set,
};
static size_t _zep_hdr_fill_v2_data(socket_zep_t *dev, zep_v2_data_hdr_t *hdr,
size_t payload_len)
{
@ -85,24 +68,23 @@ static inline size_t _zep_hdr_fill(socket_zep_t *dev, zep_hdr_t *hdr,
payload_len);
}
static size_t _prep_vector(socket_zep_t *dev, const struct iovec *vector,
static size_t _prep_vector(socket_zep_t *dev, const iolist_t *iolist,
unsigned n, struct iovec *out)
{
size_t bytes = 0;
size_t bytes;
dev->chksum_buf = 0;
for (unsigned i = 0; i < n; i++) {
bytes += vector[i].iov_len;
}
bytes = iolist_size(iolist);
bytes += sizeof(uint16_t); /* FCS field */
out[0].iov_base = &dev->snd_hdr_buf;
out[0].iov_len = _zep_hdr_fill(dev, out[0].iov_base, bytes);
for (unsigned i = 0; i < n; i++) {
/* discard const qualifier, we won't change anything. Promise! */
out[i + 1].iov_base = vector[i].iov_base;
out[i + 1].iov_len = vector[i].iov_len;
out[i + 1].iov_base = iolist->iol_base;
out[i + 1].iov_len = iolist->iol_len;
dev->chksum_buf = ucrc16_calc_le(out[i + 1].iov_base, out[i + 1].iov_len,
UCRC16_CCITT_POLY_LE, dev->chksum_buf);
iolist = iolist->iol_next;
}
dev->chksum_buf = byteorder_btols(byteorder_htons(dev->chksum_buf)).u16;
out[n + 1].iov_base = &dev->chksum_buf;
@ -110,16 +92,17 @@ static size_t _prep_vector(socket_zep_t *dev, const struct iovec *vector,
return bytes;
}
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned n)
static int _send(netdev_t *netdev, const iolist_t *iolist)
{
socket_zep_t *dev = (socket_zep_t *)netdev;
unsigned n = iolist_count(iolist);
struct iovec v[n + 2];
size_t bytes;
int res;
assert((dev != NULL) && (dev->sock_fd != 0));
bytes = _prep_vector(dev, vector, n, v);
DEBUG("socket_zep::send(%p, %p, %u)\n", (void *)netdev, (void *)vector, n);
bytes = _prep_vector(dev, iolist, n, v);
DEBUG("socket_zep::send(%p, %p, %u)\n", (void *)netdev, (void *)iolist, n);
/* simulate TX_STARTED interrupt */
if (netdev->event_callback) {
dev->last_event = NETDEV_EVENT_TX_STARTED;
@ -350,6 +333,14 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *value,
value, value_len);
}
static const netdev_driver_t socket_zep_driver = {
.send = _send,
.recv = _recv,
.init = _init,
.isr = _isr,
.get = _get,
.set = _set,
};
void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params)
{

View File

@ -325,11 +325,11 @@ void isr_radio(void)
cortexm_isr_end();
}
static int nrfmin_send(netdev_t *dev, const struct iovec *vector, unsigned count)
static int nrfmin_send(netdev_t *dev, const iolist_t *iolist)
{
(void)dev;
assert((vector != NULL) && (count > 0) && (state != STATE_OFF));
assert((iolist) && (state != STATE_OFF));
/* wait for any ongoing transmission to finish and go into idle state */
while (state == STATE_TX) {}
@ -337,17 +337,17 @@ static int nrfmin_send(netdev_t *dev, const struct iovec *vector, unsigned count
/* copy packet data into the transmit buffer */
int pos = 0;
for (unsigned i = 0; i < count; i++) {
if ((pos + vector[i].iov_len) > NRFMIN_PKT_MAX) {
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
if ((pos + iol->iol_len) > NRFMIN_PKT_MAX) {
DEBUG("[nrfmin] send: unable to do so, packet is too large!\n");
return -EOVERFLOW;
}
memcpy(&tx_buf.raw[pos], vector[i].iov_base, vector[i].iov_len);
pos += vector[i].iov_len;
memcpy(&tx_buf.raw[pos], iol->iol_base, iol->iol_len);
pos += iol->iol_len;
}
/* set output buffer and destination address */
nrfmin_hdr_t *hdr = (nrfmin_hdr_t *)vector[0].iov_base;
nrfmin_hdr_t *hdr = (nrfmin_hdr_t *)iolist->iol_base;
NRF_RADIO->PACKETPTR = (uint32_t)(&tx_buf);
NRF_RADIO->BASE0 = (CONF_ADDR_BASE | hdr->dst_addr);
@ -356,7 +356,7 @@ static int nrfmin_send(netdev_t *dev, const struct iovec *vector, unsigned count
state = STATE_TX;
NRF_RADIO->TASKS_TXEN = 1;
return (int)count;
return (int)pos;
}
static int nrfmin_recv(netdev_t *dev, void *buf, size_t len, void *info)

View File

@ -79,9 +79,6 @@ static int hdr_netif_to_nrfmin(nrfmin_hdr_t *nrfmin, gnrc_pktsnip_t *pkt)
static int gnrc_nrfmin_send(gnrc_netif_t *dev, gnrc_pktsnip_t *pkt)
{
int res;
struct iovec *vec;
size_t vec_len;
gnrc_pktsnip_t *vec_snip;
nrfmin_hdr_t nrfmin_hdr;
assert(pkt);
@ -95,26 +92,21 @@ static int gnrc_nrfmin_send(gnrc_netif_t *dev, gnrc_pktsnip_t *pkt)
res = hdr_netif_to_nrfmin(&nrfmin_hdr, pkt);
if (res < 0) {
DEBUG("[nrfmin_gnrc] send: failed to build nrfmin header\n");
gnrc_pktbuf_release(pkt);
return res;
goto out;
}
/* create iovec of data */
vec_snip = gnrc_pktbuf_get_iovec(pkt, &vec_len);
if (vec_snip == NULL) {
DEBUG("[nrfmin_gnrc] send: failed to create IO vector\n");
gnrc_pktbuf_release(pkt);
return -ENOBUFS;
}
/* link first entry of the vector to the nrfmin header */
vec = (struct iovec *)vec_snip->data;
vec[0].iov_base = &nrfmin_hdr;
vec[0].iov_len = NRFMIN_HDR_LEN;
/* link first entry after netif hdr of the pkt to the nrfmin header */
iolist_t iolist = {
.iol_next = (iolist_t *)pkt->next,
.iol_base = &nrfmin_hdr,
.iol_len = NRFMIN_HDR_LEN
};
/* and finally send out the data and release the packet */
res = dev->dev->driver->send(dev->dev, vec, vec_len);
gnrc_pktbuf_release(vec_snip);
res = dev->dev->driver->send(dev->dev, &iolist);
out:
gnrc_pktbuf_release(pkt);
return res;
}

View File

@ -112,6 +112,7 @@ ifneq (,$(filter encx24j600,$(USEMODULE)))
endif
ifneq (,$(filter ethos,$(USEMODULE)))
USEMODULE += iolist
USEMODULE += netdev_eth
USEMODULE += random
USEMODULE += tsrb
@ -306,6 +307,7 @@ endif
ifneq (,$(filter sx127%,$(USEMODULE)))
FEATURES_REQUIRED += periph_gpio
FEATURES_REQUIRED += periph_spi
USEMODULE += iolist
USEMODULE += xtimer
USEMODULE += sx127x
USEMODULE += netif

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
* Copyright (C) 2018 Kaspar Schleiser <kaspar@schleiser.de>
* 2015 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
@ -17,6 +18,7 @@
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Kévin Roussel <Kevin.Roussel@inria.fr>
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
* @author Kaspar Schleiser <kaspar@schleiser.de>
*
* @}
*/
@ -25,6 +27,8 @@
#include <assert.h>
#include <errno.h>
#include "iolist.h"
#include "net/eui64.h"
#include "net/ieee802154.h"
#include "net/netdev.h"
@ -40,7 +44,7 @@
#define _MAX_MHR_OVERHEAD (25)
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count);
static int _send(netdev_t *netdev, const iolist_t *iolist);
static int _recv(netdev_t *netdev, void *buf, size_t len, void *info);
static int _init(netdev_t *netdev);
static void _isr(netdev_t *netdev);
@ -93,18 +97,17 @@ static int _init(netdev_t *netdev)
return 0;
}
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
static int _send(netdev_t *netdev, const iolist_t *iolist)
{
at86rf2xx_t *dev = (at86rf2xx_t *)netdev;
const struct iovec *ptr = vector;
size_t len = 0;
at86rf2xx_tx_prepare(dev);
/* load packet data into FIFO */
for (unsigned i = 0; i < count; ++i, ++ptr) {
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
/* current packet data + FCS too long */
if ((len + ptr->iov_len + 2) > AT86RF2XX_MAX_PKT_LENGTH) {
if ((len + iol->iol_len + 2) > AT86RF2XX_MAX_PKT_LENGTH) {
DEBUG("[at86rf2xx] error: packet too large (%u byte) to be send\n",
(unsigned)len + 2);
return -EOVERFLOW;
@ -112,7 +115,7 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
#ifdef MODULE_NETSTATS_L2
netdev->stats.tx_bytes += len;
#endif
len = at86rf2xx_tx_load(dev, ptr->iov_base, ptr->iov_len, len);
len = at86rf2xx_tx_load(dev, iol->iol_base, iol->iol_len, len);
}
/* send data out directly if pre-loading id disabled */

View File

@ -37,14 +37,12 @@
#define ENABLE_DEBUG (0)
#include "debug.h"
static int _send(netdev_t *dev, const struct iovec *vector, unsigned count)
static int _send(netdev_t *dev, const iolist_t *iolist)
{
DEBUG("%s:%u\n", __func__, __LINE__);
(void)count;
netdev_cc110x_t *netdev_cc110x = (netdev_cc110x_t*) dev;
cc110x_pkt_t *cc110x_pkt = vector[0].iov_base;
netdev_cc110x_t *netdev_cc110x = (netdev_cc110x_t *)dev;
cc110x_pkt_t *cc110x_pkt = iolist->iol_base;
return cc110x_send(&netdev_cc110x->cc110x, cc110x_pkt);
}

View File

@ -71,9 +71,10 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
cc110x_pkt.flags = 0;
}
struct iovec vector;
vector.iov_base = (char*)&cc110x_pkt;
vector.iov_len = sizeof(cc110x_pkt_t);
iolist_t iolist = {
.iol_base = (char *)&cc110x_pkt,
.iol_len = sizeof(cc110x_pkt_t)
};
unsigned payload_len = 0;
uint8_t *pos = cc110x_pkt.data;
@ -93,7 +94,7 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
payload = payload->next;
}
/* pkt has been copied into iovec, we're done with it. */
/* pkt has been copied into cc110x_pkt, we're done with it. */
gnrc_pktbuf_release(pkt);
cc110x_pkt.length = (uint8_t) payload_len + CC110X_HEADER_LENGTH;
@ -104,7 +105,7 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
(unsigned)cc110x_pkt.address,
(unsigned)cc110x_pkt.length);
return dev->driver->send(dev, &vector, 1);
return dev->driver->send(dev, &iolist);
}
static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif)

View File

@ -114,9 +114,9 @@ bool cc2420_cca(cc2420_t *dev)
return gpio_read(dev->params.pin_cca);
}
size_t cc2420_send(cc2420_t *dev, const struct iovec *data, unsigned count)
size_t cc2420_send(cc2420_t *dev, const iolist_t *iolist)
{
size_t n = cc2420_tx_prepare(dev, data, count);
size_t n = cc2420_tx_prepare(dev, iolist);
if ((n > 0) && !(dev->options & CC2420_OPT_PRELOADING)) {
cc2420_tx_exec(dev);
@ -125,7 +125,7 @@ size_t cc2420_send(cc2420_t *dev, const struct iovec *data, unsigned count)
return n;
}
size_t cc2420_tx_prepare(cc2420_t *dev, const struct iovec *data, unsigned count)
size_t cc2420_tx_prepare(cc2420_t *dev, const iolist_t *iolist)
{
size_t pkt_len = 2; /* include the FCS (frame check sequence) */
@ -134,8 +134,8 @@ size_t cc2420_tx_prepare(cc2420_t *dev, const struct iovec *data, unsigned count
while (cc2420_get_state(dev) & NETOPT_STATE_TX) {}
/* get and check the length of the packet */
for (unsigned i = 0; i < count; i++) {
pkt_len += data[i].iov_len;
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
pkt_len += iol->iol_len;
}
if (pkt_len >= CC2420_PKT_MAXLEN) {
DEBUG("cc2420: tx_prep: unable to send, pkt too large\n");
@ -147,8 +147,8 @@ size_t cc2420_tx_prepare(cc2420_t *dev, const struct iovec *data, unsigned count
/* push packet length to TX FIFO */
cc2420_fifo_write(dev, (uint8_t *)&pkt_len, 1);
/* push packet to TX FIFO */
for (unsigned i = 0; i < count; i++) {
cc2420_fifo_write(dev, (uint8_t *)data[i].iov_base, data[i].iov_len);
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
cc2420_fifo_write(dev, iol->iol_base, iol->iol_len);
}
DEBUG("cc2420: tx_prep: loaded %i byte into the TX FIFO\n", (int)pkt_len);

View File

@ -39,7 +39,7 @@
#include "debug.h"
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count);
static int _send(netdev_t *netdev, const iolist_t *iolist);
static int _recv(netdev_t *netdev, void *buf, size_t len, void *info);
static int _init(netdev_t *netdev);
static void _isr(netdev_t *netdev);
@ -150,10 +150,10 @@ static void _isr(netdev_t *netdev)
netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE);
}
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
static int _send(netdev_t *netdev, const iolist_t *iolist)
{
cc2420_t *dev = (cc2420_t *)netdev;
return (int)cc2420_send(dev, vector, count);
return (int)cc2420_send(dev, iolist);
}
static int _recv(netdev_t *netdev, void *buf, size_t len, void *info)

View File

@ -240,7 +240,7 @@ static void on_int(void *arg)
netdev->event_callback(arg, NETDEV_EVENT_ISR);
}
static int nd_send(netdev_t *netdev, const struct iovec *data, unsigned count)
static int nd_send(netdev_t *netdev, const iolist_t *iolist)
{
enc28j60_t *dev = (enc28j60_t *)netdev;
uint8_t ctrl = 0;
@ -256,9 +256,9 @@ static int nd_send(netdev_t *netdev, const struct iovec *data, unsigned count)
cmd_w_addr(dev, ADDR_WRITE_PTR, BUF_TX_START);
/* write control byte and the actual data into the buffer */
cmd_wbm(dev, &ctrl, 1);
for (unsigned i = 0; i < count; i++) {
c += data[i].iov_len;
cmd_wbm(dev, (uint8_t *)data[i].iov_base, data[i].iov_len);
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
c += iol->iol_len;
cmd_wbm(dev, iol->iol_base, iol->iol_len);
}
/* set TX end pointer */
cmd_w_addr(dev, ADDR_TX_END, cmd_r_addr(dev, ADDR_WRITE_PTR) - 1);

View File

@ -64,7 +64,7 @@ static inline int _packets_available(encx24j600_t *dev);
static void _get_mac_addr(netdev_t *dev, uint8_t* buf);
/* netdev interface */
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count);
static int _send(netdev_t *netdev, const iolist_t *iolist);
static int _recv(netdev_t *netdev, void *buf, size_t len, void *info);
static int _init(netdev_t *dev);
static void _isr(netdev_t *dev);
@ -291,7 +291,7 @@ static int _init(netdev_t *encdev)
return 0;
}
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) {
static int _send(netdev_t *netdev, const iolist_t *iolist) {
encx24j600_t * dev = (encx24j600_t *) netdev;
lock(dev);
@ -301,9 +301,9 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) {
/* copy packet to SRAM */
size_t len = 0;
for (unsigned i = 0; i < count; i++) {
sram_op(dev, ENC_WGPDATA, (i ? 0xFFFF : TX_BUFFER_START), vector[i].iov_base, vector[i].iov_len);
len += vector[i].iov_len;
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
sram_op(dev, ENC_WGPDATA, ((iol == iolist) ? TX_BUFFER_START : 0xFFFF), iol->iol_base, iol->iol_len);
len += iol->iol_len;
}
/* set start of TX packet and length */

View File

@ -189,12 +189,11 @@ static int _init(netdev_t *encdev)
return 0;
}
static size_t iovec_count_total(const struct iovec *vector, int count)
static size_t iolist_count_total(const iolist_t *iolist)
{
size_t result = 0;
while(count--) {
result += vector->iov_len;
vector++;
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
result += iol->iol_len;
}
return result;
}
@ -256,13 +255,13 @@ void ethos_send_frame(ethos_t *dev, const uint8_t *data, size_t len, unsigned fr
}
}
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
static int _send(netdev_t *netdev, const iolist_t *iolist)
{
ethos_t * dev = (ethos_t *) netdev;
(void)dev;
/* count total packet length */
size_t pktlen = iovec_count_total(vector, count);
size_t pktlen = iolist_count_total(iolist);
/* lock line in order to prevent multiple writes */
mutex_lock(&dev->out_mutex);
@ -271,14 +270,13 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
uint8_t frame_delim = ETHOS_FRAME_DELIMITER;
uart_write(dev->uart, &frame_delim, 1);
/* send iovec */
while(count--) {
size_t n = vector->iov_len;
uint8_t *ptr = vector->iov_base;
/* send iolist */
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
size_t n = iol->iol_len;
uint8_t *ptr = iol->iol_base;
while(n--) {
_write_escaped(dev->uart, *ptr++);
}
vector++;
}
uart_write(dev->uart, &frame_delim, 1);

View File

@ -263,13 +263,12 @@ netopt_state_t cc2420_get_state(cc2420_t *dev);
* @note This function ignores the PRELOADING option
*
* @param[in] dev device to use for sending
* @param[in] data data to send (must include IEEE802.15.4 header)
* @param[in] count length of @p data
* @param[in] iolist data to send (must include IEEE802.15.4 header)
*
* @return number of bytes that were actually send
* @return 0 on error
*/
size_t cc2420_send(cc2420_t *dev, const struct iovec *data, unsigned count);
size_t cc2420_send(cc2420_t *dev, const iolist_t *iolist);
/**
* @brief Prepare for sending of data
@ -278,10 +277,9 @@ size_t cc2420_send(cc2420_t *dev, const struct iovec *data, unsigned count);
* data is possible after it was called.
*
* @param[in] dev device to prepare for sending
* @param[in] data data to prepare (must include IEEE802.15.4 header)
* @param[in] count length of @p data
* @param[in] iolist data to prepare (must include IEEE802.15.4 header)
*/
size_t cc2420_tx_prepare(cc2420_t *dev, const struct iovec *data, unsigned count);
size_t cc2420_tx_prepare(cc2420_t *dev, const iolist_t *iolist);
/**
* @brief Trigger sending of data previously loaded into transmit buffer

View File

@ -138,10 +138,9 @@ static void kw2xrf_wait_idle(kw2xrf_t *dev)
}
}
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
static int _send(netdev_t *netdev, const iolist_t *iolist)
{
kw2xrf_t *dev = (kw2xrf_t *)netdev;
const struct iovec *ptr = vector;
uint8_t *pkt_buf = &(dev->buf[1]);
size_t len = 0;
@ -149,14 +148,14 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
kw2xrf_wait_idle(dev);
/* load packet data into buffer */
for (unsigned i = 0; i < count; i++, ptr++) {
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
/* current packet data + FCS too long */
if ((len + ptr->iov_len + IEEE802154_FCS_LEN) > KW2XRF_MAX_PKT_LENGTH) {
if ((len + iol->iol_len + IEEE802154_FCS_LEN) > KW2XRF_MAX_PKT_LENGTH) {
LOG_ERROR("[kw2xrf] packet too large (%u byte) to be send\n",
(unsigned)len + IEEE802154_FCS_LEN);
return -EOVERFLOW;
}
len = kw2xrf_tx_load(pkt_buf, ptr->iov_base, ptr->iov_len, len);
len = kw2xrf_tx_load(pkt_buf, iol->iol_base, iol->iol_len, len);
}
kw2xrf_set_sequence(dev, XCVSEQ_IDLE);

View File

@ -39,22 +39,6 @@
#define _MAX_MHR_OVERHEAD (25)
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count);
static int _recv(netdev_t *netdev, void *buf, size_t len, void *info);
static int _init(netdev_t *netdev);
static void _isr(netdev_t *netdev);
static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len);
static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len);
const netdev_driver_t mrf24j40_driver = {
.send = _send,
.recv = _recv,
.init = _init,
.isr = _isr,
.get = _get,
.set = _set,
};
static void _irq_handler(void *arg)
{
netdev_t *dev = (netdev_t *) arg;
@ -83,18 +67,17 @@ static int _init(netdev_t *netdev)
return 0;
}
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
static int _send(netdev_t *netdev, const iolist_t *iolist)
{
mrf24j40_t *dev = (mrf24j40_t *)netdev;
const struct iovec *ptr = vector;
size_t len = 0;
mrf24j40_tx_prepare(dev);
/* load packet data into FIFO */
for (unsigned i = 0; i < count; i++, ptr++) {
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
/* current packet data + FCS too long */
if ((len + ptr->iov_len + 2) > IEEE802154_FRAME_LEN_MAX) {
if ((len + iol->iol_len + 2) > IEEE802154_FRAME_LEN_MAX) {
DEBUG("[mrf24j40] error: packet too large (%u byte) to be send\n",
(unsigned)len + 2);
return -EOVERFLOW;
@ -103,11 +86,12 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
#ifdef MODULE_NETSTATS_L2
netdev->stats.tx_bytes += len;
#endif
len = mrf24j40_tx_load(dev, ptr->iov_base, ptr->iov_len, len);
if (i == 0) {
len = mrf24j40_tx_load(dev, iol->iol_base, iol->iol_len, len);
/* only on first iteration: */
if (iol == iolist) {
dev->header_len = len;
/* Grab the FCF bits from the frame header */
dev->fcf_low = *(uint8_t*)(ptr->iov_base);
dev->fcf_low = *(uint8_t*)(iol->iol_base);
}
}
@ -581,3 +565,12 @@ static void _isr(netdev_t *netdev)
}
DEBUG("[mrf24j40] END IRQ\n");
}
const netdev_driver_t mrf24j40_driver = {
.send = _send,
.recv = _recv,
.init = _init,
.isr = _isr,
.get = _get,
.set = _set,
};

View File

@ -27,31 +27,6 @@
#define SLIP_END_ESC (0xdcU)
#define SLIP_ESC_ESC (0xddU)
static int _send(netdev_t *dev, const struct iovec *vector, unsigned count);
static int _recv(netdev_t *dev, void *buf, size_t len, void *info);
static int _init(netdev_t *dev);
static void _isr(netdev_t *dev);
static int _get(netdev_t *dev, netopt_t opt, void *value, size_t max_len);
static int _set(netdev_t *dev, netopt_t opt, const void *value,
size_t value_len);
static const netdev_driver_t slip_driver = {
.send = _send,
.recv = _recv,
.init = _init,
.isr = _isr,
.get = _get,
.set = _set,
};
void slipdev_setup(slipdev_t *dev, const slipdev_params_t *params)
{
/* set device descriptor fields */
memcpy(&dev->config, params, sizeof(dev->config));
dev->inesc = 0U;
dev->netdev.driver = &slip_driver;
}
static void _slip_rx_cb(void *arg, uint8_t byte)
{
slipdev_t *dev = arg;
@ -84,16 +59,16 @@ static inline void _write_byte(slipdev_t *dev, uint8_t byte)
uart_write(dev->config.uart, &byte, 1);
}
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
static int _send(netdev_t *netdev, const iolist_t *iolist)
{
slipdev_t *dev = (slipdev_t *)netdev;
int bytes = 0;
DEBUG("slipdev: sending vector of length %u\n", count);
for (unsigned i = 0; i < count; i++) {
uint8_t *data = vector[i].iov_base;
DEBUG("slipdev: sending iolist\n");
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
uint8_t *data = iol->iol_base;
for (unsigned j = 0; j < vector[i].iov_len; j++, data++) {
for (unsigned j = 0; j < iol->iol_len; j++, data++) {
switch(*data) {
case SLIP_END:
/* escaping END byte*/
@ -223,4 +198,21 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *value,
return -ENOTSUP;
}
static const netdev_driver_t slip_driver = {
.send = _send,
.recv = _recv,
.init = _init,
.isr = _isr,
.get = _get,
.set = _set,
};
void slipdev_setup(slipdev_t *dev, const slipdev_params_t *params)
{
/* set device descriptor fields */
memcpy(&dev->config, params, sizeof(dev->config));
dev->inesc = 0U;
dev->netdev.driver = &slip_driver;
}
/** @} */

View File

@ -34,7 +34,6 @@
#include "debug.h"
/* Internal helper functions */
static uint8_t _get_tx_len(const struct iovec *vector, unsigned count);
static int _set_state(sx127x_t *dev, netopt_state_t state);
static int _get_state(sx127x_t *dev, void *val);
void _on_dio0_irq(void *arg);
@ -42,24 +41,7 @@ void _on_dio1_irq(void *arg);
void _on_dio2_irq(void *arg);
void _on_dio3_irq(void *arg);
/* Netdev driver api functions */
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count);
static int _recv(netdev_t *netdev, void *buf, size_t len, void *info);
static int _init(netdev_t *netdev);
static void _isr(netdev_t *netdev);
static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len);
static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len);
const netdev_driver_t sx127x_driver = {
.send = _send,
.recv = _recv,
.init = _init,
.isr = _isr,
.get = _get,
.set = _set,
};
static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
static int _send(netdev_t *netdev, const iolist_t *iolist)
{
sx127x_t *dev = (sx127x_t*) netdev;
@ -69,8 +51,8 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
return -ENOTSUP;
}
uint8_t size;
size = _get_tx_len(vector, count);
uint8_t size = iolist_size(iolist);
switch (dev->settings.modem) {
case SX127X_MODEM_FSK:
/* todo */
@ -91,8 +73,8 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
}
/* Write payload buffer */
for (size_t i = 0; i < count; i++) {
sx127x_write_fifo(dev, vector[i].iov_base, vector[i].iov_len);
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
sx127x_write_fifo(dev, iol->iol_base, iol->iol_len);
}
break;
default:
@ -489,17 +471,6 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len)
return res;
}
static uint8_t _get_tx_len(const struct iovec *vector, unsigned count)
{
uint8_t len = 0;
for (unsigned i = 0 ; i < count ; i++) {
len += vector[i].iov_len;
}
return len;
}
static int _set_state(sx127x_t *dev, netopt_state_t state)
{
switch (state) {
@ -717,3 +688,12 @@ void _on_dio3_irq(void *arg)
break;
}
}
const netdev_driver_t sx127x_driver = {
.send = _send,
.recv = _recv,
.init = _init,
.isr = _isr,
.get = _get,
.set = _set,
};

View File

@ -194,7 +194,7 @@ static uint16_t tx_upload(w5100_t *dev, uint16_t start, void *data, size_t len)
}
}
static int send(netdev_t *netdev, const struct iovec *vector, unsigned count)
static int send(netdev_t *netdev, const iolist_t *iolist)
{
w5100_t *dev = (w5100_t *)netdev;
int sum = 0;
@ -210,9 +210,10 @@ static int send(netdev_t *netdev, const struct iovec *vector, unsigned count)
pos = S0_TX_BASE;
}
for (unsigned i = 0; i < count; i++) {
pos = tx_upload(dev, pos, vector[i].iov_base, vector[i].iov_len);
sum += vector[i].iov_len;
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
size_t len = iol->iol_len;
pos = tx_upload(dev, pos, iol->iol_base, len);
sum += len;
}
waddr(dev, S0_TX_WR0, S0_TX_WR1, pos);

View File

@ -104,8 +104,6 @@ static int xbee_adpt_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
{
int res;
size_t size;
size_t count;
gnrc_pktsnip_t *vec;
gnrc_netif_hdr_t *hdr;
uint8_t xhdr[XBEE_MAX_TXHDR_LENGTH];
@ -146,27 +144,23 @@ static int xbee_adpt_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
}
}
/* now let's extract the iovector and send out the stuff */
vec = gnrc_pktbuf_get_iovec(pkt, &count);
if (vec != NULL) {
pkt = vec;
struct iovec *vector = (struct iovec *)pkt->data;
vector[0].iov_base = xhdr;
vector[0].iov_len = res;
/* now let's send out the stuff */
iolist_t iolist = {
.iol_next = (iolist_t *)pkt->next,
.iol_base = xhdr,
.iol_len = res
};
#ifdef MODULE_NETSTATS_L2
if (hdr->flags & BCAST) {
netif->dev->stats.tx_mcast_count++;
}
else {
netif->dev->stats.tx_unicast_count++;
}
#endif
DEBUG("[xbee-gnrc] send: triggering the drivers send function\n");
res = netif->dev->driver->send(netif->dev, vector, count);
if (hdr->flags & BCAST) {
netif->dev->stats.tx_mcast_count++;
}
else {
DEBUG("[xbee-gnrc] send: unable to create iovec\n");
netif->dev->stats.tx_unicast_count++;
}
#endif
DEBUG("[xbee-gnrc] send: triggering the drivers send function\n");
res = netif->dev->driver->send(netif->dev, &iolist);
gnrc_pktbuf_release(pkt);

View File

@ -634,21 +634,23 @@ int xbee_init(netdev_t *dev)
return 0;
}
static int xbee_send(netdev_t *dev, const struct iovec *vector, unsigned count)
static int xbee_send(netdev_t *dev, const iolist_t *iolist)
{
xbee_t *xbee = (xbee_t *)dev;
size_t size;
uint8_t csum;
assert(xbee && vector && (count > 0));
assert(xbee && iolist);
/* calculate the checksum and the packet size */
size = vector[0].iov_len;
csum = _cksum(3, (uint8_t *)vector[0].iov_base, size);
for (unsigned i = 1; i < count; i++) {
size += vector[i].iov_len;
for (size_t p = 0; p < vector[i].iov_len; p++) {
csum -= ((uint8_t *)vector[i].iov_base)[p];
size = iolist->iol_len;
csum = _cksum(3, (uint8_t *)iolist->iol_base, size);
for (const iolist_t *iol = iolist->iol_next; iol; iol = iol->iol_next) {
size_t len = iol->iol_len;
size += len;
for (size_t p = 0; p < len; p++) {
csum -= ((uint8_t *)iol->iol_base)[p];
}
}
@ -661,13 +663,13 @@ static int xbee_send(netdev_t *dev, const struct iovec *vector, unsigned count)
/* send the actual data packet */
DEBUG("[xbee] send: now sending out %i byte\n", (int)size);
mutex_lock(&(xbee->tx_lock));
for (unsigned i = 0; i < count; i++) {
uart_write(xbee->p.uart, vector[i].iov_base, vector[i].iov_len);
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
uart_write(xbee->p.uart, iol->iol_base, iol->iol_len);
}
uart_write(xbee->p.uart, &csum, 1);
mutex_unlock(&(xbee->tx_lock));
/* return number of payload byte */
/* return number of payload bytes */
return (int)size;
}

View File

@ -250,7 +250,6 @@ static int send(int iface, le_uint16_t dst_pan, uint8_t *dst, size_t dst_len,
{
int res;
netdev_ieee802154_t *dev;
struct iovec vector[MAC_VECTOR_SIZE];
uint8_t *src;
size_t src_len;
uint8_t mhr[IEEE802154_MAX_HDR_LEN];
@ -262,11 +261,14 @@ static int send(int iface, le_uint16_t dst_pan, uint8_t *dst, size_t dst_len,
return 1;
}
iolist_t iol_data = {
.iol_base = data,
.iol_len = strlen(data)
};
dev = (netdev_ieee802154_t *)&devs[iface];
flags = (uint8_t)(dev->flags & NETDEV_IEEE802154_SEND_MASK);
flags |= IEEE802154_FCF_TYPE_DATA;
vector[1].iov_base = data;
vector[1].iov_len = strlen(data);
src_pan = byteorder_btols(byteorder_htons(dev->pan));
if (dst_pan.u16 == 0) {
dst_pan = src_pan;
@ -287,15 +289,20 @@ static int send(int iface, le_uint16_t dst_pan, uint8_t *dst, size_t dst_len,
puts("txtsnd: Error preperaring frame");
return 1;
}
vector[0].iov_base = mhr;
vector[0].iov_len = (size_t)res;
res = dev->netdev.driver->send((netdev_t *)dev, vector, MAC_VECTOR_SIZE);
iolist_t iol_hdr = {
.iol_next = &iol_data,
.iol_base = mhr,
.iol_len = (size_t)res
};
res = dev->netdev.driver->send((netdev_t *)dev, &iol_hdr);
if (res < 0) {
puts("txtsnd: Error on sending");
return 1;
}
else {
printf("txtsnd: send %u bytes to ", (unsigned)vector[1].iov_len);
printf("txtsnd: send %u bytes to ", (unsigned)iol_data.iol_len);
print_addr(dst, dst_len);
printf(" (PAN: ");
print_addr((uint8_t *)&dst_pan, sizeof(dst_pan));

View File

@ -224,10 +224,12 @@ int send_cmd(int argc, char **argv)
printf("sending \"%s\" payload (%d bytes)\n",
argv[1], strlen(argv[1]) + 1);
struct iovec vec[1];
vec[0].iov_base = argv[1];
vec[0].iov_len = strlen(argv[1]) + 1;
if (netdev->driver->send(netdev, vec, 1) == -ENOTSUP) {
iolist_t iolist = {
.iol_base = argv[1],
.iol_len = (strlen(argv[1]) + 1)
};
if (netdev->driver->send(netdev, &iolist) == -ENOTSUP) {
puts("Cannot send: radio is still transmitting");
}

View File

@ -56,29 +56,29 @@ static void test_init(void)
_print_info(netdev);
}
static void test_send__vector_NULL__count_0(void)
static void test_send__iolist_NULL(void)
{
netdev_t *netdev = (netdev_t *)(&_dev);
int res;
puts("Send zero-length packet");
res = netdev->driver->send(netdev, NULL, 0);
int res = netdev->driver->send(netdev, NULL);
assert((res < 0) || (res == 0));
if ((res < 0) && (errno == ECONNREFUSED)) {
puts("No remote socket exists (use scripts in `tests/` to have proper tests)");
}
}
static void test_send__vector_not_NULL__count_2(void)
static void test_send__iolist_not_NULL(void)
{
struct iovec vector[] = { { .iov_base = "Hello", .iov_len = sizeof("Hello") },
{ .iov_base = "World", .iov_len = sizeof("World") } };
iolist_t iolist[] = { { .iol_base = "Hello", .iol_len = sizeof("Hello") },
{ .iol_base = "World", .iol_len = sizeof("World") } };
iolist[0].iol_next = &iolist[1];
netdev_t *netdev = (netdev_t *)(&_dev);
int res;
puts("Send 'Hello\\0World\\0'");
res = netdev->driver->send(netdev, vector,
sizeof(vector) / sizeof(struct iovec));
int res = netdev->driver->send(netdev, iolist);
assert((res < 0) || (res == (sizeof("Hello")) + sizeof("World")));
if ((res < 0) && (errno == ECONNREFUSED)) {
puts("No remote socket exists (use scripts in `tests/` to have proper tests)");
@ -109,8 +109,8 @@ int main(void)
_main_pid = sched_active_pid;
test_init();
test_send__vector_NULL__count_0();
test_send__vector_not_NULL__count_2();
test_send__iolist_NULL();
test_send__iolist_not_NULL();
test_recv(); /* does not return */
puts("ALL TESTS SUCCESSFUL");
return 0;