net/ethernet: Let's remove the use for ll reserve

There is no need to reserve any space for each frag, as the l2 will
allocate a frag for the ethernet header, arp will do the same.

This is one step further to removing the concept of ll reserve.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2018-06-27 15:06:18 +02:00 committed by Carles Cufí
commit bff65b6330
11 changed files with 35 additions and 174 deletions

View file

@ -172,21 +172,13 @@ static void eth_tx_data(struct eth_runtime *context, u8_t *data, u16_t len)
static int eth_tx(struct device *dev, struct net_pkt *pkt)
{
struct eth_runtime *context = dev->driver_data;
struct net_buf *frag;
/* Ensure we're clear to transmit. */
eth_tx_spin_wait(context);
if (!pkt->frags) {
eth_tx_data(context, net_pkt_ll(pkt),
net_pkt_ll_reserve(pkt));
} else {
struct net_buf *frag;
eth_tx_data(context, net_pkt_ll(pkt),
net_pkt_ll_reserve(pkt) + pkt->frags->len);
for (frag = pkt->frags->frags; frag; frag = frag->frags) {
eth_tx_data(context, frag->data, frag->len);
}
for (frag = pkt->frags; frag; frag = frag->frags) {
eth_tx_data(context, frag->data, frag->len);
}
return 0;

View file

@ -52,13 +52,10 @@ static enum ethernet_hw_caps e1000_caps(struct device *dev)
static size_t e1000_linearize(struct net_pkt *pkt, void *buf, size_t bufsize)
{
size_t len = net_pkt_ll_reserve(pkt) + pkt->frags->len;
size_t len = 0;
struct net_buf *nb;
/* First fragment contains link layer (Ethernet) header */
memcpy(buf, net_pkt_ll(pkt), len);
for (nb = pkt->frags->frags; nb; nb = nb->frags) {
for (nb = pkt->frags; nb; nb = nb->frags) {
memcpy((u8_t *) buf + len, nb->data, nb->len);
len += nb->len;
}

View file

@ -409,9 +409,8 @@ static void eth_enc28j60_init_phy(struct device *dev)
static int eth_enc28j60_tx(struct device *dev, struct net_pkt *pkt)
{
struct eth_enc28j60_runtime *context = dev->driver_data;
u16_t len = net_pkt_ll_reserve(pkt) + net_pkt_get_len(pkt);
u16_t tx_bufaddr = ENC28J60_TXSTART;
bool first_frag = true;
u16_t len = net_pkt_get_len(pkt);
u8_t per_packet_control;
u16_t tx_bufaddr_end;
struct net_buf *frag;
@ -446,19 +445,7 @@ static int eth_enc28j60_tx(struct device *dev, struct net_pkt *pkt)
eth_enc28j60_write_mem(dev, &per_packet_control, 1);
for (frag = pkt->frags; frag; frag = frag->frags) {
u8_t *data_ptr;
u16_t data_len;
if (first_frag) {
data_ptr = net_pkt_ll(pkt);
data_len = net_pkt_ll_reserve(pkt) + frag->len;
first_frag = false;
} else {
data_ptr = frag->data;
data_len = frag->len;
}
eth_enc28j60_write_mem(dev, data_ptr, data_len);
eth_enc28j60_write_mem(dev, frag->data, frag->len);
}
tx_bufaddr_end = tx_bufaddr + len;

View file

@ -470,7 +470,7 @@ static int eth_tx(struct device *dev, struct net_pkt *pkt)
bool timestamped_frame;
#endif
u16_t total_len = net_pkt_ll_reserve(pkt) + net_pkt_get_len(pkt);
u16_t total_len = net_pkt_get_len(pkt);
k_sem_take(&context->tx_buf_sem, K_FOREVER);
@ -479,18 +479,9 @@ static int eth_tx(struct device *dev, struct net_pkt *pkt)
*/
imask = irq_lock();
/* Gather fragment buffers into flat Ethernet frame buffer
* which can be fed to MCUX Ethernet functions. First
* fragment is special - it contains link layer (Ethernet
* in our case) headers and must be treated specially.
*/
/* Copy the fragments */
dst = context->frame_buf;
memcpy(dst, net_pkt_ll(pkt),
net_pkt_ll_reserve(pkt) + pkt->frags->len);
dst += net_pkt_ll_reserve(pkt) + pkt->frags->len;
/* Continue with the rest of fragments (which contain only data) */
frag = pkt->frags->frags;
frag = pkt->frags;
while (frag) {
memcpy(dst, frag->data, frag->len);
dst += frag->len;

View file

@ -120,16 +120,10 @@ static struct gptp_hdr *check_gptp_msg(struct net_if *iface,
struct net_pkt *pkt,
bool is_tx)
{
u8_t *msg_start = net_pkt_ll(pkt);
struct gptp_hdr *gptp_hdr;
u8_t *msg_start;
int eth_hlen;
if (net_pkt_ll_reserve(pkt)) {
msg_start = net_pkt_ll(pkt);
} else {
msg_start = net_pkt_ip_data(pkt);
}
#if defined(CONFIG_NET_VLAN)
if (net_eth_get_vlan_status(iface)) {
struct net_eth_vlan_hdr *hdr_vlan;
@ -220,13 +214,7 @@ static int eth_send(struct device *dev, struct net_pkt *pkt)
int count = 0;
int ret;
/* First fragment contains link layer (Ethernet) headers.
*/
count = net_pkt_ll_reserve(pkt) + pkt->frags->len;
memcpy(ctx->send, net_pkt_ll(pkt), count);
/* Then the remaining data */
frag = pkt->frags->frags;
frag = pkt->frags;
while (frag) {
memcpy(ctx->send + count, frag->data, frag->len);
count += frag->len;

View file

@ -330,17 +330,12 @@ static struct gptp_hdr *check_gptp_msg(struct net_if *iface,
struct net_pkt *pkt,
bool is_tx)
{
u8_t *msg_start = net_pkt_ll(pkt);
struct ethernet_context *eth_ctx;
struct gptp_hdr *gptp_hdr;
int eth_hlen;
u8_t *msg_start;
if (net_pkt_ll_reserve(pkt)) {
msg_start = net_pkt_ll(pkt);
} else {
msg_start = net_pkt_ip_data(pkt);
}
#if defined(CONFIG_NET_VLAN)
eth_ctx = net_if_l2_data(iface);
if (net_eth_is_vlan_enabled(eth_ctx, iface)) {
@ -1318,7 +1313,7 @@ static int eth_tx(struct device *dev, struct net_pkt *pkt)
struct gmac_desc_list *tx_desc_list;
struct gmac_desc *tx_desc;
struct net_buf *frag;
u8_t *frag_data, *frag_orig;
u8_t *frag_data;
u16_t frag_len;
u32_t err_tx_flushed_count_at_entry;
unsigned int key;
@ -1343,15 +1338,6 @@ static int eth_tx(struct device *dev, struct net_pkt *pkt)
tx_desc_list = &queue->tx_desc_list;
err_tx_flushed_count_at_entry = queue->err_tx_flushed_count;
/* Store the original frag data pointer */
frag_orig = pkt->frags->data;
/* First fragment is special - it contains link layer (Ethernet
* in our case) header. Modify the data pointer to account for more data
* in the beginning of the buffer.
*/
net_buf_push(pkt->frags, net_pkt_ll_reserve(pkt));
frag = pkt->frags;
while (frag) {
frag_data = frag->data;
@ -1403,9 +1389,6 @@ static int eth_tx(struct device *dev, struct net_pkt *pkt)
frag = frag->frags;
}
/* Restore the original frag data pointer */
pkt->frags->data = frag_orig;
key = irq_lock();
/* Check if tx_error_handler() function was executed */

View file

@ -73,13 +73,6 @@ static int eth_stellaris_send(struct device *dev, struct net_pkt *pkt)
eth_stellaris_send_byte(dev, data_len & 0xff);
eth_stellaris_send_byte(dev, (data_len & 0xff00) >> 8);
/* Send the header, header is 14 bytes */
head_len_left = net_pkt_ll_reserve(pkt);
eth_hdr = net_pkt_ll(pkt);
for (i = 0; i < head_len_left; ++i) {
eth_stellaris_send_byte(dev, eth_hdr[i]);
}
/* Send the payload */
for (frag = pkt->frags; frag; frag = frag->frags) {
for (i = 0; i < frag->len; ++i) {

View file

@ -74,7 +74,7 @@ static int eth_tx(struct device *dev, struct net_pkt *pkt)
k_mutex_lock(&dev_data->tx_mutex, K_FOREVER);
total_len = net_pkt_ll_reserve(pkt) + net_pkt_get_len(pkt);
total_len = net_pkt_get_len(pkt);
if (total_len > ETH_TX_BUF_SIZE) {
LOG_ERR("PKT to big");
res = -EIO;
@ -88,11 +88,7 @@ static int eth_tx(struct device *dev, struct net_pkt *pkt)
dma_buffer = (u8_t *)(dma_tx_desc->Buffer1Addr);
memcpy(dma_buffer, net_pkt_ll(pkt),
net_pkt_ll_reserve(pkt) + pkt->frags->len);
dma_buffer += net_pkt_ll_reserve(pkt) + pkt->frags->len;
frag = pkt->frags->frags;
frag = pkt->frags;
while (frag) {
memcpy(dma_buffer, frag->data, frag->len);
dma_buffer += frag->len;

View file

@ -138,10 +138,6 @@ static void slip_writeb_esc(unsigned char c)
static int slip_send(struct device *dev, struct net_pkt *pkt)
{
struct net_buf *frag;
#if defined(CONFIG_SLIP_TAP)
u16_t ll_reserve = net_pkt_ll_reserve(pkt);
bool send_header_once = false;
#endif
u8_t *ptr;
u16_t i;
u8_t c;
@ -156,52 +152,18 @@ static int slip_send(struct device *dev, struct net_pkt *pkt)
slip_writeb(SLIP_END);
for (frag = pkt->frags; frag; frag = frag->frags) {
#if defined(CONFIG_SLIP_TAP)
ptr = frag->data - ll_reserve;
/* This writes ethernet header */
if (!send_header_once && ll_reserve) {
for (i = 0U; i < ll_reserve; i++) {
slip_writeb_esc(*ptr++);
}
}
if (net_if_get_mtu(net_pkt_iface(pkt)) >
net_buf_headroom(frag)) {
/* Do not add link layer header if the mtu is bigger
* than fragment size. The first packet needs the
* link layer header always.
*/
send_header_once = true;
ll_reserve = 0U;
ptr = frag->data;
}
#else
/* There is no ll header in tun device */
ptr = frag->data;
#endif
for (i = 0U; i < frag->len; ++i) {
c = *ptr++;
slip_writeb_esc(c);
}
if (LOG_LEVEL >= LOG_LEVEL_DBG) {
int frag_count = 0;
LOG_DBG("sent data %d bytes",
frag->len + net_pkt_ll_reserve(pkt));
if (frag->len + net_pkt_ll_reserve(pkt)) {
char msg[8 + 1];
snprintf(msg, sizeof(msg), "<slip %2d",
frag_count++);
LOG_DBG("sent data %d bytes", frag->len);
if (frag->len) {
LOG_HEXDUMP_DBG(net_pkt_ll(pkt),
frag->len +
net_pkt_ll_reserve(pkt),
msg);
frag->len, "<slip ");
}
}
}

View file

@ -234,17 +234,10 @@ static inline struct net_pkt *arp_prepare(struct net_if *iface,
struct net_pkt *pending,
struct in_addr *current_ip)
{
struct ethernet_context *ctx = net_if_l2_data(iface);
int eth_hdr_len = sizeof(struct net_eth_hdr);
struct net_pkt *pkt;
struct net_arp_hdr *hdr;
struct in_addr *my_addr;
if (net_eth_is_vlan_enabled(ctx, iface) &&
net_eth_get_vlan_tag(iface) != NET_VLAN_TAG_UNSPEC) {
eth_hdr_len = sizeof(struct net_eth_vlan_hdr);
}
if (current_ip) {
/* This is the IPv4 autoconf case where we have already
* things setup so no need to allocate new net_pkt
@ -253,7 +246,7 @@ static inline struct net_pkt *arp_prepare(struct net_if *iface,
} else {
struct net_buf *frag;
pkt = net_pkt_get_reserve_tx(eth_hdr_len, NET_BUF_TIMEOUT);
pkt = net_pkt_get_reserve_tx(0, NET_BUF_TIMEOUT);
if (!pkt) {
return NULL;
}
@ -332,7 +325,6 @@ struct net_pkt *net_arp_prepare(struct net_pkt *pkt,
struct in_addr *request_ip,
struct in_addr *current_ip)
{
struct ethernet_context *ctx;
struct arp_entry *entry;
struct in_addr *addr;
@ -340,8 +332,6 @@ struct net_pkt *net_arp_prepare(struct net_pkt *pkt,
return NULL;
}
ctx = net_if_l2_data(net_pkt_iface(pkt));
/* Is the destination in the local network, if not route via
* the gateway address.
*/
@ -476,19 +466,12 @@ static void arp_update(struct net_if *iface,
static inline struct net_pkt *arp_prepare_reply(struct net_if *iface,
struct net_pkt *req)
{
struct ethernet_context *ctx = net_if_l2_data(iface);
int eth_hdr_len = sizeof(struct net_eth_hdr);
struct net_pkt *pkt;
struct net_buf *frag;
struct net_arp_hdr *hdr, *query;
struct net_eth_hdr *eth_query;
if (net_eth_is_vlan_enabled(ctx, iface) &&
net_eth_get_vlan_tag(iface) != NET_VLAN_TAG_UNSPEC) {
eth_hdr_len = sizeof(struct net_eth_vlan_hdr);
}
pkt = net_pkt_get_reserve_tx(eth_hdr_len, NET_BUF_TIMEOUT);
pkt = net_pkt_get_reserve_tx(0, NET_BUF_TIMEOUT);
if (!pkt) {
goto fail;
}
@ -561,11 +544,13 @@ enum net_verdict net_arp_input(struct net_pkt *pkt)
struct in_addr *addr;
if (net_pkt_get_len(pkt) < (sizeof(struct net_arp_hdr) -
net_pkt_ll_reserve(pkt))) {
(net_pkt_ip_data(pkt) -
net_pkt_ll(pkt)))) {
NET_DBG("Invalid ARP header (len %zu, min %zu bytes)",
net_pkt_get_len(pkt),
sizeof(struct net_arp_hdr) -
net_pkt_ll_reserve(pkt));
(net_pkt_ip_data(pkt) -
net_pkt_ll(pkt)));
return NET_DROP;
}

View file

@ -178,8 +178,8 @@ static enum net_verdict ethernet_recv(struct net_if *iface,
#endif
case NET_ETH_PTYPE_LLDP:
#if defined(CONFIG_NET_LLDP)
net_pkt_set_ll_reserve(pkt, hdr_len);
net_buf_pull(pkt->frags, net_pkt_ll_reserve(pkt));
net_pkt_set_ll(pkt, pkt->frags->data);
net_buf_pull(pkt->frags, hdr_len);
return net_lldp_recv(iface, pkt);
#else
NET_DBG("LLDP Rx agent not enabled");
@ -232,8 +232,8 @@ static enum net_verdict ethernet_recv(struct net_if *iface,
ethernet_update_rx_stats(iface, pkt, net_pkt_get_len(pkt));
net_pkt_set_ll_reserve(pkt, hdr_len);
net_buf_pull(pkt->frags, net_pkt_ll_reserve(pkt));
net_pkt_set_ll(pkt, pkt->frags->data);
net_buf_pull(pkt->frags, hdr_len);
#ifdef CONFIG_NET_ARP
if (family == AF_INET && type == NET_ETH_PTYPE_ARP) {
@ -444,11 +444,7 @@ static struct net_buf *ethernet_fill_header(struct ethernet_context *ctx,
net_eth_is_vlan_enabled(ctx, net_pkt_iface(pkt))) {
struct net_eth_vlan_hdr *hdr_vlan;
NET_ASSERT(net_buf_headroom(hdr_frag) >=
sizeof(struct net_eth_vlan_hdr));
hdr_vlan = (struct net_eth_vlan_hdr *)(hdr_frag->data -
net_pkt_ll_reserve(pkt));
hdr_vlan = (struct net_eth_vlan_hdr *)(hdr_frag->data);
if (!ethernet_fill_in_dst_on_ipv4_mcast(pkt, &hdr_vlan->dst) &&
!ethernet_fill_in_dst_on_ipv6_mcast(pkt, &hdr_vlan->dst)) {
@ -468,11 +464,7 @@ static struct net_buf *ethernet_fill_header(struct ethernet_context *ctx,
hdr_frag->len,
&hdr_vlan->src, &hdr_vlan->dst);
} else {
NET_ASSERT(net_buf_headroom(hdr_frag) >=
sizeof(struct net_eth_hdr));
hdr = (struct net_eth_hdr *)(hdr_frag->data -
net_pkt_ll_reserve(pkt));
hdr = (struct net_eth_hdr *)(hdr_frag->data);
if (!ethernet_fill_in_dst_on_ipv4_mcast(pkt, &hdr->dst) &&
!ethernet_fill_in_dst_on_ipv6_mcast(pkt, &hdr->dst)) {
@ -484,12 +476,14 @@ static struct net_buf *ethernet_fill_header(struct ethernet_context *ctx,
sizeof(struct net_eth_addr));
hdr->type = ptype;
net_buf_add(hdr_frag, sizeof(struct net_eth_hdr));
print_ll_addrs(pkt, ntohs(hdr->type),
hdr_frag->len, &hdr->src, &hdr->dst);
}
net_pkt_frag_insert(pkt, hdr_frag);
net_pkt_set_ll(pkt, hdr_frag->data);
return hdr_frag;
}
@ -607,17 +601,10 @@ error:
static inline u16_t ethernet_reserve(struct net_if *iface, void *unused)
{
ARG_UNUSED(iface);
ARG_UNUSED(unused);
if (IS_ENABLED(CONFIG_NET_VLAN)) {
struct ethernet_context *ctx = net_if_l2_data(iface);
if (net_eth_is_vlan_enabled(ctx, iface)) {
return sizeof(struct net_eth_vlan_hdr);
}
}
return sizeof(struct net_eth_hdr);
return 0;
}
static inline int ethernet_enable(struct net_if *iface, bool state)