net/iface: Switch fully to a one-pass sending logic in net_if
Now instead of such path: net_if_send_data -> L2's send -> net_if tx_queue -> net_if_tx -> driver net_if's send It will be: net_if_send_data -> net_if tx_queue -> net_if_tx -> L2's send -> driver net_if's send Only Ethernet is adapted, but 15.4 and bt will follow up. All Ethernet drivers are made compatible with that new scheme also. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
114521c4bf
commit
9464ec3343
12 changed files with 72 additions and 112 deletions
|
@ -42,9 +42,9 @@ static inline void eth_write(u32_t base_addr, u32_t offset,
|
|||
sys_write32(val, base_addr + offset);
|
||||
}
|
||||
|
||||
static void eth_rx(struct device *port)
|
||||
static void eth_rx(struct device *dev)
|
||||
{
|
||||
struct eth_runtime *context = port->driver_data;
|
||||
struct eth_runtime *context = dev->driver_data;
|
||||
struct net_pkt *pkt;
|
||||
u32_t frm_len;
|
||||
int r;
|
||||
|
@ -164,10 +164,9 @@ static void eth_tx_data(struct eth_runtime *context, u8_t *data, u16_t len)
|
|||
* from each fragment's data pointer. This procedure might yield to
|
||||
* other threads while waiting for the DMA transfer to finish.
|
||||
*/
|
||||
static int eth_tx(struct net_if *iface, struct net_pkt *pkt)
|
||||
static int eth_tx(struct device *dev, struct net_pkt *pkt)
|
||||
{
|
||||
struct device *port = net_if_get_device(iface);
|
||||
struct eth_runtime *context = port->driver_data;
|
||||
struct eth_runtime *context = dev->driver_data;
|
||||
|
||||
/* Ensure we're clear to transmit. */
|
||||
eth_tx_spin_wait(context);
|
||||
|
@ -185,13 +184,12 @@ static int eth_tx(struct net_if *iface, struct net_pkt *pkt)
|
|||
}
|
||||
}
|
||||
|
||||
net_pkt_unref(pkt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void eth_dw_isr(struct device *port)
|
||||
static void eth_dw_isr(struct device *dev)
|
||||
{
|
||||
struct eth_runtime *context = port->driver_data;
|
||||
struct eth_runtime *context = dev->driver_data;
|
||||
#ifdef CONFIG_SHARED_IRQ
|
||||
u32_t int_status;
|
||||
|
||||
|
@ -205,7 +203,7 @@ static void eth_dw_isr(struct device *port)
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
eth_rx(port);
|
||||
eth_rx(dev);
|
||||
|
||||
/* Acknowledge the interrupt. */
|
||||
eth_write(context->base_addr, REG_ADDR_STATUS,
|
||||
|
@ -238,9 +236,9 @@ static inline int eth_setup(struct device *dev)
|
|||
|
||||
static int eth_initialize_internal(struct net_if *iface)
|
||||
{
|
||||
struct device *port = net_if_get_device(iface);
|
||||
struct eth_runtime *context = port->driver_data;
|
||||
const struct eth_config *config = port->config->config_info;
|
||||
struct device *dev = net_if_get_device(iface);
|
||||
struct eth_runtime *context = dev->driver_data;
|
||||
const struct eth_config *config = dev->config->config_info;
|
||||
u32_t base_addr;
|
||||
|
||||
context->iface = iface;
|
||||
|
@ -317,7 +315,7 @@ static int eth_initialize_internal(struct net_if *iface)
|
|||
|
||||
LOG_INF("Enabled 100M full-duplex mode");
|
||||
|
||||
config->config_func(port);
|
||||
config->config_func(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -340,16 +338,16 @@ static enum ethernet_hw_caps eth_dw_get_capabilities(struct device *dev)
|
|||
|
||||
static const struct ethernet_api api_funcs = {
|
||||
.iface_api.init = eth_initialize,
|
||||
.iface_api.send = eth_tx,
|
||||
|
||||
.get_capabilities = eth_dw_get_capabilities,
|
||||
.send = eth_tx,
|
||||
};
|
||||
|
||||
/* Bindings to the plaform */
|
||||
#if CONFIG_ETH_DW_0
|
||||
static void eth_config_0_irq(struct device *port)
|
||||
static void eth_config_0_irq(struct device *dev)
|
||||
{
|
||||
const struct eth_config *config = port->config->config_info;
|
||||
const struct eth_config *config = dev->config->config_info;
|
||||
struct device *shared_irq_dev;
|
||||
|
||||
#ifdef CONFIG_ETH_DW_0_IRQ_DIRECT
|
||||
|
@ -360,8 +358,8 @@ static void eth_config_0_irq(struct device *port)
|
|||
#elif defined(CONFIG_ETH_DW_0_IRQ_SHARED)
|
||||
shared_irq_dev = device_get_binding(config->shared_irq_dev_name);
|
||||
__ASSERT(shared_irq_dev != NULL, "Failed to get eth_dw device binding");
|
||||
shared_irq_isr_register(shared_irq_dev, (isr_t)eth_dw_isr, port);
|
||||
shared_irq_enable(shared_irq_dev, port);
|
||||
shared_irq_isr_register(shared_irq_dev, (isr_t)eth_dw_isr, dev);
|
||||
shared_irq_enable(shared_irq_dev, dev);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -82,19 +82,12 @@ static int e1000_tx(struct e1000_dev *dev, void *data, size_t data_len)
|
|||
return (dev->tx.sta & TDESC_STA_DD) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static int e1000_send(struct net_if *iface, struct net_pkt *pkt)
|
||||
static int e1000_send(struct device *device, struct net_pkt *pkt)
|
||||
{
|
||||
struct e1000_dev *dev = net_if_get_device(iface)->driver_data;
|
||||
|
||||
struct e1000_dev *dev = device->driver_data;
|
||||
size_t len = e1000_linearize(pkt, dev->txb, sizeof(dev->txb));
|
||||
|
||||
int err = e1000_tx(dev, dev->txb, len);
|
||||
|
||||
if (!err) {
|
||||
net_pkt_unref(pkt);
|
||||
}
|
||||
|
||||
return err;
|
||||
return e1000_tx(dev, dev->txb, len);
|
||||
}
|
||||
|
||||
static struct net_pkt *e1000_rx(struct e1000_dev *dev)
|
||||
|
@ -235,8 +228,8 @@ static struct e1000_dev e1000_dev = {
|
|||
|
||||
static const struct ethernet_api e1000_api = {
|
||||
.iface_api.init = e1000_init,
|
||||
.iface_api.send = e1000_send,
|
||||
.get_capabilities = e1000_caps,
|
||||
.send = e1000_send,
|
||||
};
|
||||
|
||||
NET_DEVICE_INIT(eth_e1000,
|
||||
|
|
|
@ -405,9 +405,8 @@ static void eth_enc28j60_init_phy(struct device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static int eth_enc28j60_tx(struct net_if *iface, struct net_pkt *pkt)
|
||||
static int eth_enc28j60_tx(struct device *dev, struct net_pkt *pkt)
|
||||
{
|
||||
struct device *dev = net_if_get_device(iface);
|
||||
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;
|
||||
|
@ -487,8 +486,6 @@ static int eth_enc28j60_tx(struct net_if *iface, struct net_pkt *pkt)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
net_pkt_unref(pkt);
|
||||
|
||||
LOG_DBG("Tx successful");
|
||||
|
||||
return 0;
|
||||
|
@ -672,9 +669,9 @@ static void eth_enc28j60_iface_init(struct net_if *iface)
|
|||
|
||||
static const struct ethernet_api api_funcs = {
|
||||
.iface_api.init = eth_enc28j60_iface_init,
|
||||
.iface_api.send = eth_enc28j60_tx,
|
||||
|
||||
.get_capabilities = eth_enc28j60_get_capabilities,
|
||||
.send = eth_enc28j60_tx,
|
||||
};
|
||||
|
||||
static int eth_enc28j60_init(struct device *dev)
|
||||
|
|
|
@ -449,9 +449,9 @@ static bool eth_get_ptp_data(struct net_if *iface, struct net_pkt *pkt,
|
|||
}
|
||||
#endif /* CONFIG_PTP_CLOCK_MCUX */
|
||||
|
||||
static int eth_tx(struct net_if *iface, struct net_pkt *pkt)
|
||||
static int eth_tx(struct device *dev, struct net_pkt *pkt)
|
||||
{
|
||||
struct eth_context *context = net_if_get_device(iface)->driver_data;
|
||||
struct eth_context *context = dev->driver_data;
|
||||
const struct net_buf *frag;
|
||||
u8_t *dst;
|
||||
status_t status;
|
||||
|
@ -501,7 +501,7 @@ static int eth_tx(struct net_if *iface, struct net_pkt *pkt)
|
|||
total_len);
|
||||
|
||||
#if defined(CONFIG_PTP_CLOCK_MCUX)
|
||||
timestamped_frame = eth_get_ptp_data(iface, pkt, NULL);
|
||||
timestamped_frame = eth_get_ptp_data(net_pkt_iface(pkt), pkt, NULL);
|
||||
if (timestamped_frame) {
|
||||
if (!status) {
|
||||
ts_tx_pkt[ts_tx_wr] = net_pkt_ref(pkt);
|
||||
|
@ -523,8 +523,6 @@ static int eth_tx(struct net_if *iface, struct net_pkt *pkt)
|
|||
return -1;
|
||||
}
|
||||
|
||||
net_pkt_unref(pkt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -929,14 +927,12 @@ static struct device *eth_mcux_get_ptp_clock(struct device *dev)
|
|||
#endif
|
||||
|
||||
static const struct ethernet_api api_funcs = {
|
||||
.iface_api.init = eth_iface_init,
|
||||
.iface_api.send = eth_tx,
|
||||
|
||||
.get_capabilities = eth_mcux_get_capabilities,
|
||||
|
||||
.iface_api.init = eth_iface_init,
|
||||
#if defined(CONFIG_PTP_CLOCK_MCUX)
|
||||
.get_ptp_clock = eth_mcux_get_ptp_clock,
|
||||
.get_ptp_clock = eth_mcux_get_ptp_clock,
|
||||
#endif
|
||||
.get_capabilities = eth_mcux_get_capabilities,
|
||||
.send = eth_tx,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_PTP_CLOCK_MCUX)
|
||||
|
|
|
@ -107,11 +107,6 @@ static struct k_thread rx_thread_data;
|
|||
/* TODO: support multiple interfaces */
|
||||
static struct eth_context eth_context_data;
|
||||
|
||||
static struct eth_context *get_context(struct net_if *iface)
|
||||
{
|
||||
return net_if_get_device(iface)->driver_data;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_GPTP)
|
||||
static bool need_timestamping(struct gptp_hdr *hdr)
|
||||
{
|
||||
|
@ -205,9 +200,9 @@ static void update_gptp(struct net_if *iface, struct net_pkt *pkt,
|
|||
#define update_gptp(iface, pkt, send)
|
||||
#endif /* CONFIG_NET_GPTP */
|
||||
|
||||
static int eth_send(struct net_if *iface, struct net_pkt *pkt)
|
||||
static int eth_send(struct device *dev, struct net_pkt *pkt)
|
||||
{
|
||||
struct eth_context *ctx = get_context(iface);
|
||||
struct eth_context *ctx = dev->driver_data;
|
||||
struct net_buf *frag;
|
||||
int count = 0;
|
||||
int ret;
|
||||
|
@ -225,29 +220,27 @@ static int eth_send(struct net_if *iface, struct net_pkt *pkt)
|
|||
frag = frag->frags;
|
||||
}
|
||||
|
||||
eth_stats_update_bytes_tx(iface, count);
|
||||
eth_stats_update_pkts_tx(iface);
|
||||
eth_stats_update_bytes_tx(net_pkt_iface(pkt), count);
|
||||
eth_stats_update_pkts_tx(net_pkt_iface(pkt));
|
||||
|
||||
if (IS_ENABLED(CONFIG_NET_STATISTICS_ETHERNET)) {
|
||||
if (net_eth_is_addr_broadcast(
|
||||
&((struct net_eth_hdr *)NET_ETH_HDR(pkt))->dst)) {
|
||||
eth_stats_update_broadcast_tx(iface);
|
||||
eth_stats_update_broadcast_tx(net_pkt_iface(pkt));
|
||||
} else if (net_eth_is_addr_multicast(
|
||||
&((struct net_eth_hdr *)
|
||||
NET_ETH_HDR(pkt))->dst)) {
|
||||
eth_stats_update_multicast_tx(iface);
|
||||
eth_stats_update_multicast_tx(net_pkt_iface(pkt));
|
||||
}
|
||||
}
|
||||
|
||||
update_gptp(iface, pkt, true);
|
||||
update_gptp(net_pkt_iface(pkt), pkt, true);
|
||||
|
||||
LOG_DBG("Send pkt %p len %d", pkt, count);
|
||||
|
||||
ret = eth_write_data(ctx->dev_fd, ctx->send, count);
|
||||
if (ret < 0) {
|
||||
LOG_DBG("Cannot send pkt %p (%d)", pkt, ret);
|
||||
} else {
|
||||
net_pkt_unref(pkt);
|
||||
}
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
|
@ -565,12 +558,12 @@ static int eth_stop_device(struct device *dev)
|
|||
|
||||
static const struct ethernet_api eth_if_api = {
|
||||
.iface_api.init = eth_iface_init,
|
||||
.iface_api.send = eth_send,
|
||||
|
||||
.get_capabilities = eth_posix_native_get_capabilities,
|
||||
.set_config = set_config,
|
||||
.start = eth_start_device,
|
||||
.stop = eth_stop_device,
|
||||
.send = eth_send,
|
||||
|
||||
#if defined(CONFIG_NET_VLAN)
|
||||
.vlan_setup = vlan_setup,
|
||||
|
|
|
@ -1290,9 +1290,8 @@ static int priority2queue(enum net_priority priority)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int eth_tx(struct net_if *iface, struct net_pkt *pkt)
|
||||
static int eth_tx(struct device *dev, struct net_pkt *pkt)
|
||||
{
|
||||
struct device *const dev = net_if_get_device(iface);
|
||||
const struct eth_sam_dev_cfg *const cfg = DEV_CFG(dev);
|
||||
struct eth_sam_dev_data *const dev_data = DEV_DATA(dev);
|
||||
Gmac *gmac = cfg->regs;
|
||||
|
@ -1405,6 +1404,9 @@ static int eth_tx(struct net_if *iface, struct net_pkt *pkt)
|
|||
|
||||
irq_unlock(key);
|
||||
|
||||
/* pkt is internally queued, so it requires to hold a reference */
|
||||
net_pkt_ref(pkt);
|
||||
|
||||
/* Start transmission */
|
||||
gmac->GMAC_NCR |= GMAC_NCR_TSTART;
|
||||
|
||||
|
@ -1864,11 +1866,11 @@ static struct device *eth_sam_gmac_get_ptp_clock(struct device *dev)
|
|||
|
||||
static const struct ethernet_api eth_api = {
|
||||
.iface_api.init = eth0_iface_init,
|
||||
.iface_api.send = eth_tx,
|
||||
|
||||
.get_capabilities = eth_sam_gmac_get_capabilities,
|
||||
.set_config = eth_sam_gmac_set_config,
|
||||
.get_config = eth_sam_gmac_get_config,
|
||||
.send = eth_tx,
|
||||
|
||||
#if defined(CONFIG_PTP_CLOCK_SAM_GMAC)
|
||||
.get_ptp_clock = eth_sam_gmac_get_ptp_clock,
|
||||
|
|
|
@ -54,10 +54,9 @@ static inline void disable_mcast_filter(ETH_HandleTypeDef *heth)
|
|||
heth->Instance->MACFFR = tmp;
|
||||
}
|
||||
|
||||
static int eth_tx(struct net_if *iface, struct net_pkt *pkt)
|
||||
static int eth_tx(struct device *dev, struct net_pkt *pkt)
|
||||
{
|
||||
struct device *dev;
|
||||
struct eth_stm32_hal_dev_data *dev_data;
|
||||
struct eth_stm32_hal_dev_data *dev_data = DEV_DATA(dev);
|
||||
ETH_HandleTypeDef *heth;
|
||||
u8_t *dma_buffer;
|
||||
int res;
|
||||
|
@ -65,13 +64,8 @@ static int eth_tx(struct net_if *iface, struct net_pkt *pkt)
|
|||
u16_t total_len;
|
||||
__IO ETH_DMADescTypeDef *dma_tx_desc;
|
||||
|
||||
__ASSERT_NO_MSG(iface != NULL);
|
||||
__ASSERT_NO_MSG(pkt != NULL);
|
||||
__ASSERT_NO_MSG(pkt->frags != NULL);
|
||||
|
||||
dev = net_if_get_device(iface);
|
||||
dev_data = DEV_DATA(dev);
|
||||
|
||||
__ASSERT_NO_MSG(dev != NULL);
|
||||
__ASSERT_NO_MSG(dev_data != NULL);
|
||||
|
||||
|
@ -122,8 +116,6 @@ static int eth_tx(struct net_if *iface, struct net_pkt *pkt)
|
|||
goto error;
|
||||
}
|
||||
|
||||
net_pkt_unref(pkt);
|
||||
|
||||
res = 0;
|
||||
error:
|
||||
k_mutex_unlock(&dev_data->tx_mutex);
|
||||
|
@ -387,9 +379,9 @@ static enum ethernet_hw_caps eth_stm32_hal_get_capabilities(struct device *dev)
|
|||
|
||||
static const struct ethernet_api eth_api = {
|
||||
.iface_api.init = eth_iface_init,
|
||||
.iface_api.send = eth_tx,
|
||||
|
||||
.get_capabilities = eth_stm32_hal_get_capabilities,
|
||||
.send = eth_tx,
|
||||
};
|
||||
|
||||
static struct device DEVICE_NAME_GET(eth0_stm32_hal);
|
||||
|
|
|
@ -538,8 +538,6 @@ static inline bool net_eth_get_vlan_status(struct net_if *iface)
|
|||
}
|
||||
#endif /* CONFIG_NET_VLAN */
|
||||
|
||||
int net_eth_send(struct net_if *iface, struct net_pkt *pkt);
|
||||
|
||||
/**
|
||||
* @brief Inform ethernet L2 driver that ethernet carrier is detected.
|
||||
* This happens when cable is connected.
|
||||
|
|
|
@ -49,8 +49,9 @@ struct net_l2 {
|
|||
* This function is used by net core to push a packet to lower layer
|
||||
* (interface's L2), which in turn might work on the packet relevantly.
|
||||
* (adding proper header etc...)
|
||||
* Returns a negative error code, or the number of bytes sent otherwise.
|
||||
*/
|
||||
enum net_verdict (*send)(struct net_if *iface, struct net_pkt *pkt);
|
||||
int (*send)(struct net_if *iface, struct net_pkt *pkt);
|
||||
|
||||
/**
|
||||
* This function is used to get the amount of bytes the net core should
|
||||
|
|
|
@ -148,7 +148,6 @@ static inline void net_context_send_cb(struct net_context *context,
|
|||
|
||||
static bool net_if_tx(struct net_if *iface, struct net_pkt *pkt)
|
||||
{
|
||||
const struct net_if_api *api = net_if_get_device(iface)->driver_api;
|
||||
struct net_linkaddr *dst;
|
||||
struct net_context *context;
|
||||
void *context_token;
|
||||
|
@ -170,7 +169,7 @@ static bool net_if_tx(struct net_if *iface, struct net_pkt *pkt)
|
|||
net_pkt_set_queued(pkt, false);
|
||||
}
|
||||
|
||||
status = api->send(iface, pkt);
|
||||
status = net_if_l2(iface)->send(iface, pkt);
|
||||
} else {
|
||||
/* Drop packet if interface is not up */
|
||||
NET_WARN("iface %p is down", iface);
|
||||
|
@ -184,7 +183,7 @@ static bool net_if_tx(struct net_if *iface, struct net_pkt *pkt)
|
|||
|
||||
net_pkt_unref(pkt);
|
||||
} else {
|
||||
net_stats_update_bytes_sent(iface, pkt->total_pkt_len);
|
||||
net_stats_update_bytes_sent(iface, status);
|
||||
}
|
||||
|
||||
if (context) {
|
||||
|
@ -252,8 +251,8 @@ enum net_verdict net_if_send_data(struct net_if *iface, struct net_pkt *pkt)
|
|||
{
|
||||
struct net_context *context = net_pkt_context(pkt);
|
||||
struct net_linkaddr *dst = net_pkt_lladdr_dst(pkt);
|
||||
enum net_verdict verdict = NET_OK;
|
||||
void *token = net_pkt_token(pkt);
|
||||
enum net_verdict verdict;
|
||||
int status = -EIO;
|
||||
|
||||
if (!atomic_test_bit(iface->if_dev->flags, NET_IF_UP)) {
|
||||
|
@ -280,7 +279,7 @@ enum net_verdict net_if_send_data(struct net_if *iface, struct net_pkt *pkt)
|
|||
* additional checks, so let the packet through.
|
||||
*/
|
||||
if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) {
|
||||
goto send;
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -297,14 +296,8 @@ enum net_verdict net_if_send_data(struct net_if *iface, struct net_pkt *pkt)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NET_LOOPBACK)
|
||||
send:
|
||||
#endif
|
||||
verdict = net_if_l2(iface)->send(iface, pkt);
|
||||
|
||||
done:
|
||||
/* The L2 send() function can return
|
||||
* NET_OK in which case packet was sent successfully. In this case
|
||||
/* NET_OK in which case packet has checked successfully. In this case
|
||||
* the net_context callback is called after successful delivery in
|
||||
* net_if_tx_thread().
|
||||
*
|
||||
|
@ -315,15 +308,19 @@ done:
|
|||
* This can happen for example if we need to do IPv6 ND to figure
|
||||
* out link layer address.
|
||||
*/
|
||||
if (context && verdict == NET_DROP) {
|
||||
NET_DBG("Calling context send cb %p token %p verdict %d",
|
||||
context, token, verdict);
|
||||
if (verdict == NET_DROP) {
|
||||
if (context) {
|
||||
NET_DBG("Calling ctx send cb %p token %p verdict %d",
|
||||
context, token, verdict);
|
||||
net_context_send_cb(context, token, status);
|
||||
}
|
||||
|
||||
net_context_send_cb(context, token, status);
|
||||
}
|
||||
|
||||
if (verdict == NET_DROP && dst->addr) {
|
||||
net_if_call_link_cb(iface, dst, status);
|
||||
if (dst->addr) {
|
||||
net_if_call_link_cb(iface, dst, status);
|
||||
}
|
||||
} else if (verdict == NET_OK) {
|
||||
/* Packet is ready to be sent by L2, let's queue */
|
||||
net_if_queue_tx(iface, pkt);
|
||||
}
|
||||
|
||||
return verdict;
|
||||
|
|
|
@ -464,15 +464,7 @@ static struct net_buf *ethernet_fill_header(struct ethernet_context *ctx,
|
|||
return hdr_frag;
|
||||
}
|
||||
|
||||
static enum net_verdict ethernet_send(struct net_if *iface,
|
||||
struct net_pkt *pkt)
|
||||
{
|
||||
net_if_queue_tx(iface, pkt);
|
||||
|
||||
return NET_OK;
|
||||
}
|
||||
|
||||
int net_eth_send(struct net_if *iface, struct net_pkt *pkt)
|
||||
static int ethernet_send(struct net_if *iface, struct net_pkt *pkt)
|
||||
{
|
||||
const struct ethernet_api *api = net_if_get_device(iface)->driver_api;
|
||||
struct ethernet_context *ctx = net_if_l2_data(iface);
|
||||
|
@ -538,6 +530,7 @@ int net_eth_send(struct net_if *iface, struct net_pkt *pkt)
|
|||
|
||||
ret = api->send(net_if_get_device(iface), pkt);
|
||||
if (!ret) {
|
||||
ret = net_pkt_get_len(pkt);
|
||||
net_pkt_unref(pkt);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,10 +36,12 @@ static struct __netusb {
|
|||
static u8_t interface_data[300];
|
||||
#endif
|
||||
|
||||
static int netusb_send(struct net_if *iface, struct net_pkt *pkt)
|
||||
static int netusb_send(struct device *dev, struct net_pkt *pkt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
LOG_DBG("Send pkt, len %u", net_pkt_get_len(pkt));
|
||||
|
||||
if (!netusb_enabled()) {
|
||||
|
@ -52,7 +54,6 @@ static int netusb_send(struct net_if *iface, struct net_pkt *pkt)
|
|||
return ret;
|
||||
}
|
||||
|
||||
net_pkt_unref(pkt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -222,11 +223,10 @@ static void netusb_init(struct net_if *iface)
|
|||
}
|
||||
|
||||
static const struct ethernet_api netusb_api_funcs = {
|
||||
.iface_api = {
|
||||
.init = netusb_init,
|
||||
.send = netusb_send,
|
||||
},
|
||||
.iface_api.init = netusb_init,
|
||||
|
||||
.get_capabilities = NULL,
|
||||
.send = netusb_send,
|
||||
};
|
||||
|
||||
static int netusb_init_dev(struct device *dev)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue