diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h index 40cb84d2b1b..deccb9a6563 100644 --- a/include/nuttx/net/netdev.h +++ b/include/nuttx/net/netdev.h @@ -411,6 +411,10 @@ struct net_driver_s net_ipv6addr_t d_ipv6draddr; /* Default router IPv6 address */ #endif /* CONFIG_NET_IPv6 */ + uint32_t d_polltype; /* The collection of protocols that need to + * be processed in devif_poll + */ + /* This is a new design that uses d_iob as packets input and output * buffer which used by some NICs such as celluler net driver. Case for * data input, note that d_iob maybe a linked chain only when using diff --git a/net/arp/arp_send.c b/net/arp/arp_send.c index ecc255ff2da..17cf96d2218 100644 --- a/net/arp/arp_send.c +++ b/net/arp/arp_send.c @@ -371,7 +371,7 @@ int arp_send(in_addr_t ipaddr) /* Notify the device driver that new TX data is available. */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, ARP_POLL); /* Wait for the send to complete or an error to occur. * net_sem_wait will also terminate if a signal is received. @@ -504,7 +504,7 @@ int arp_send_async(in_addr_t ipaddr, arp_send_finish_cb_t cb) /* Notify the device driver that new TX data is available. */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, ARP_POLL); errout_with_lock: netdev_unlock(dev); diff --git a/net/arp/arp_table.c b/net/arp/arp_table.c index 9057846fefc..438ae1d6a8f 100644 --- a/net/arp/arp_table.c +++ b/net/arp/arp_table.c @@ -412,7 +412,7 @@ int arp_update(FAR struct net_driver_s *dev, in_addr_t ipaddr, dev->d_iob = NULL; dev->d_buf = NULL; - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, ARP_POLL); netdev_iob_replace(dev, iob); dev->d_len = len; } diff --git a/net/bluetooth/bluetooth_sendmsg.c b/net/bluetooth/bluetooth_sendmsg.c index 94f4dd924bd..201393b72c7 100644 --- a/net/bluetooth/bluetooth_sendmsg.c +++ b/net/bluetooth/bluetooth_sendmsg.c @@ -338,13 +338,13 @@ static ssize_t bluetooth_sendto(FAR struct socket *psock, { /* Set up the callback in the connection */ - state.is_cb->flags = PKT_POLL; + state.is_cb->flags = BLUETOOTH_POLL; state.is_cb->priv = (FAR void *)&state; state.is_cb->event = bluetooth_sendto_eventhandler; /* Notify the device driver that new TX data is available. */ - netdev_txnotify_dev(&radio->r_dev); + netdev_txnotify_dev(&radio->r_dev, BLUETOOTH_POLL); /* Wait for the send to complete or an error to occur. * net_sem_wait will also terminate if a signal is received. diff --git a/net/can/can_sendmsg.c b/net/can/can_sendmsg.c index 0939d94aaef..846d8ecc2d3 100644 --- a/net/can/can_sendmsg.c +++ b/net/can/can_sendmsg.c @@ -261,7 +261,7 @@ ssize_t can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, /* Notify the device driver that new TX data is available. */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, CAN_POLL); /* Wait for the send to complete or an error to occur. * net_sem_timedwait will also terminate if a signal is received. diff --git a/net/can/can_sendmsg_buffered.c b/net/can/can_sendmsg_buffered.c index 2619d8cc609..b5977c2a9ba 100644 --- a/net/can/can_sendmsg_buffered.c +++ b/net/can/can_sendmsg_buffered.c @@ -133,7 +133,7 @@ static uint32_t psock_send_eventhandler(FAR struct net_driver_s *dev, /* Notify the device driver that new TX data is available. */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, CAN_POLL); } else { @@ -378,12 +378,12 @@ ssize_t can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, /* Set up the callback in the connection */ conn->sndcb->flags = CAN_POLL; - conn->sndcb->priv = (FAR void *)conn; + conn->sndcb->priv = (FAR void *)conn; conn->sndcb->event = psock_send_eventhandler; /* Notify the device driver that new TX data is available. */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, CAN_POLL); } /* unlock */ diff --git a/net/devif/devif.h b/net/devif/devif.h index 94c3eb6b805..b067a782aab 100644 --- a/net/devif/devif.h +++ b/net/devif/devif.h @@ -96,7 +96,7 @@ * PKT_POLL (1) timed operations, and (2) to check if the * BLUETOOTH_POLL socket layer has data that it wants to send. * IEEE802154_POLL These are socket oriented callbacks where the - * context depends on the specific set. + * CAN_POLL context depends on the specific set. * OUT: Not used * * TCP_BACKLOG IN: There is a new connection in the backlog list set @@ -137,9 +137,10 @@ * ARP_POLL IN: Used for polling the socket layer. This is * provided periodically from the drivers to support * (1) timed operations, and (2) to check if the ARP - * layer needs to send an ARP request. This is a - * device oriented event, not associated with a - * socket. + * layer needs to send an ARP request, and (3) polling + * the ARP send queue to send out pending ARP + * requests. This is a device oriented event, + * not associated with a socket. * OUT: Not used * * ICMP_POLL IN: Used for polling the socket layer. This is @@ -167,9 +168,26 @@ * event, not associated with a socket. The appdata * pointer is not used in this case. * OUT: Not used + * IGMP_POLL IN: Used for polling the socket layer. This is + * provided periodically from the drivers to support + * (1) timed operations, and (2) to check if the IGMP + * layer needs to send an IGMP report. This is a + * device oriented event, not associated with a + * socket. + * OUT: Not used + * MLD_POLL IN: Used for polling the socket layer. This is + * provided periodically from the drivers to support + * (1) timed operations, and (2) to check if the MLD + * layer needs to send an MLD report. This is a + * device oriented event, not associated with a + * socket. + * IPFRAG_POLL IN: Used for polling the IP fragment send queue to send + * out pending IP fragments. This is a device + * oriented event, not associated with a socket. + * OUT: Not used */ -/* Bits 0-11: Connection specific event bits */ +/* Bits 0-10: Connection specific event bits */ #define TCP_ACKDATA (1 << 0) #define TCP_NEWDATA (1 << 1) @@ -185,37 +203,36 @@ #define TCP_SNDACK (1 << 2) #define TCP_REXMIT (1 << 3) #define TCP_POLL (1 << 4) -#define UDP_POLL TCP_POLL -#define PKT_POLL TCP_POLL -#define CAN_POLL TCP_POLL -#define BLUETOOTH_POLL TCP_POLL -#define IEEE802154_POLL TCP_POLL -#define WPAN_POLL TCP_POLL -#define TCP_BACKLOG (1 << 5) -#define TCP_ABORT (1 << 6) -#define TCP_CONNECTED (1 << 7) -#define TCP_TIMEDOUT (1 << 8) -#define TCP_WAITALL (1 << 9) -#define TCP_TXCLOSE (1 << 10) -#define TCP_RXCLOSE (1 << 11) +#define UDP_POLL (1 << 5) +#define PKT_POLL (1 << 6) +#define CAN_POLL (1 << 7) +#define BLUETOOTH_POLL (1 << 8) +#define IEEE802154_POLL (1 << 9) +#define TCP_BACKLOG (1 << 10) +#define TCP_ABORT (1 << 11) +#define TCP_CONNECTED (1 << 12) +#define TCP_TIMEDOUT (1 << 13) +#define TCP_WAITALL (1 << 14) +#define TCP_TXCLOSE (1 << 15) +#define TCP_RXCLOSE (1 << 16) -/* Bit 12: Device specific event bits */ +/* Bit 17: Device specific event bits */ -#define NETDEV_DOWN (1 << 12) +#define NETDEV_DOWN (1 << 17) -/* Bits 13-15: Encoded device specific poll events. Unlike connection +/* Bits 18-24: device specific poll events. Unlike connection * oriented poll events, device related poll events must distinguish * between what is being polled for since the callbacks all reside in * the same list in the network device structure. */ -#define DEVPOLL_SHIFT (13) -#define DEVPOLL_MASK (7 << DEVPOLL_SHIFT) -# define DEVPOLL_NONE (0 << DEVPOLL_SHIFT) -# define ARP_POLL (1 << DEVPOLL_SHIFT) -# define ICMP_POLL (2 << DEVPOLL_SHIFT) -# define ICMPv6_POLL (3 << DEVPOLL_SHIFT) -# define IPFWD_POLL (4 << DEVPOLL_SHIFT) +#define IPFRAG_POLL (1 << 18) +#define ARP_POLL (1 << 19) +#define IGMP_POLL (1 << 20) +#define MLD_POLL (1 << 21) +#define ICMP_POLL (1 << 22) +#define ICMPv6_POLL (1 << 23) +#define IPFWD_POLL (1 << 24) /* The set of events that and implications to the TCP connection state */ diff --git a/net/devif/devif_callback.c b/net/devif/devif_callback.c index 271b897ee25..01c49878a51 100644 --- a/net/devif/devif_callback.c +++ b/net/devif/devif_callback.c @@ -216,30 +216,11 @@ static void devif_callback_free(FAR struct net_driver_s *dev, * ****************************************************************************/ -static bool devif_event_trigger(uint32_t events, uint32_t triggers) +static inline bool devif_event_trigger(uint32_t events, uint32_t triggers) { - /* The events are divided into a set of individual bits that may be ORed - * together PLUS a field that encodes a single poll event. - * - * First check if any of the individual event bits will trigger the - * callback. - */ + /* check if any of the individual event bits will trigger the callback. */ - if ((events & triggers & ~DEVPOLL_MASK) != 0) - { - return true; - } - - /* No... check the encoded device event. */ - - if ((events & DEVPOLL_MASK) == (triggers & DEVPOLL_MASK)) - { - return (triggers & DEVPOLL_MASK) != 0; - } - - /* No.. this event set will not generate the callback */ - - return false; + return (events & triggers) != 0; } /**************************************************************************** diff --git a/net/devif/devif_poll.c b/net/devif/devif_poll.c index fda45637450..0f1c865e4e1 100644 --- a/net/devif/devif_poll.c +++ b/net/devif/devif_poll.c @@ -734,13 +734,6 @@ static int devif_poll_queue(FAR struct iob_queue_s *iobq, } } - /* Notify the device driver that iob is available. */ - - if (iob_peek_queue(iobq) != NULL) - { - netdev_txnotify_dev(dev); - } - /* Reuse iob buffer */ if (!bstop && reused) @@ -799,11 +792,23 @@ static int devif_poll_ipfrag(FAR struct net_driver_s *dev, * ****************************************************************************/ -#ifdef CONFIG_NET_ARP_SEND_QUEUE +#if defined(CONFIG_NET_ARP_SEND_QUEUE) || defined(CONFIG_NET_ARP_SEND) static int devif_poll_arp(FAR struct net_driver_s *dev, devif_poll_callback_t callback) { - return devif_poll_queue(&dev->d_arpout, dev, callback); + int bstop; + +# ifdef CONFIG_NET_ARP_SEND + bstop = arp_poll(dev, callback); + if (!bstop) +# endif + { +# ifdef CONFIG_NET_ARP_SEND_QUEUE + bstop = devif_poll_queue(&dev->d_arpout, dev, callback); +# endif + } + + return bstop; } #endif @@ -836,6 +841,7 @@ static int devif_poll_connections(FAR struct net_driver_s *dev, devif_poll_callback_t callback) { int bstop = false; + int i; /* Reset device buffer length */ @@ -845,136 +851,143 @@ static int devif_poll_connections(FAR struct net_driver_s *dev, * action. */ -#ifdef CONFIG_NET_ARP_SEND_QUEUE - bstop = devif_poll_arp(dev, callback); - if (bstop) + while (!bstop) { - return bstop; - } -#endif + i = ffsl(dev->d_polltype); + if (i == 0) + { + break; + } + switch (1 << (i - 1)) + { +#if defined(CONFIG_NET_ARP_SEND_QUEUE) || defined(CONFIG_NET_ARP_SEND) + case ARP_POLL: + + /* Traverse all of arp request or arp send queue pending iobs + * for available packets to transfer + */ + + bstop = devif_poll_arp(dev, callback); + break; +#endif #ifdef CONFIG_NET_IPFRAG - /* Traverse all of ip fragments for available packets to transfer */ + case IPFRAG_POLL: - bstop = devif_poll_ipfrag(dev, callback); - if (!bstop) -#endif -#ifdef CONFIG_NET_ARP_SEND - { - /* Check for pending ARP requests */ + /* Traverse all of ip fragments for available packets to + * transfer + */ - bstop = arp_poll(dev, callback); - } - - if (!bstop) + bstop = devif_poll_ipfrag(dev, callback); + break; #endif #ifdef CONFIG_NET_PKT - { - /* Check for pending packet socket transfer */ + case PKT_POLL: - bstop = devif_poll_pkt_connections(dev, callback); - } + /* Check for pending packet socket transfer */ - if (!bstop) + bstop = devif_poll_pkt_connections(dev, callback); + break; #endif #ifdef CONFIG_NET_CAN - { - /* Check for pending CAN socket transfer */ + case CAN_POLL: - bstop = devif_poll_can_connections(dev, callback); - } + /* Check for pending CAN socket transfer */ - if (!bstop) + bstop = devif_poll_can_connections(dev, callback); + break; #endif #ifdef CONFIG_NET_BLUETOOTH - { - /* Check for pending PF_BLUETOOTH socket transfer */ + case BLUETOOTH_POLL: - bstop = devif_poll_bluetooth_connections(dev, callback); - } + /* Check for pending PF_BLUETOOTH socket transfer */ - if (!bstop) + bstop = devif_poll_bluetooth_connections(dev, callback); + break; #endif #ifdef CONFIG_NET_IEEE802154 - { - /* Check for pending PF_IEEE802154 socket transfer */ + case IEEE802154_POLL: - bstop = devif_poll_ieee802154_connections(dev, callback); - } + /* Check for pending PF_IEEE802154 socket transfer */ - if (!bstop) + bstop = devif_poll_ieee802154_connections(dev, callback); + break; #endif #ifdef CONFIG_NET_IGMP - { - /* Check for pending IGMP messages */ + case IGMP_POLL: - bstop = devif_poll_igmp(dev, callback); - } + /* Check for pending IGMP messages */ - if (!bstop) + bstop = devif_poll_igmp(dev, callback); + break; #endif #ifdef CONFIG_NET_MLD - { - /* Check for pending MLD messages */ + case MLD_POLL: - bstop = devif_poll_mld(dev, callback); - } + /* Check for pending MLD messages */ - if (!bstop) + bstop = devif_poll_mld(dev, callback); + break; #endif #ifdef NET_TCP_HAVE_STACK - { - /* Traverse all of the active TCP connections and perform the poll - * action. - */ + case TCP_POLL: - bstop = devif_poll_tcp_connections(dev, callback); - } + /* Traverse all of the active TCP connections and perform the + * poll action. + */ - if (!bstop) + bstop = devif_poll_tcp_connections(dev, callback); + break; #endif #ifdef NET_UDP_HAVE_STACK - { - /* Traverse all of the allocated UDP connections and perform - * the poll action - */ + case UDP_POLL: - bstop = devif_poll_udp_connections(dev, callback); - } + /* Traverse all of the allocated UDP connections and perform + * the poll action + */ - if (!bstop) + bstop = devif_poll_udp_connections(dev, callback); + break; #endif #if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_SOCKET) - { - /* Traverse all of the tasks waiting to send an ICMP ECHO request. */ + case ICMP_POLL: - bstop = devif_poll_icmp(dev, callback); - } + /* Traverse all of the tasks waiting to send an ICMP ECHO + * request. + */ - if (!bstop) + bstop = devif_poll_icmp(dev, callback); + break; #endif #if defined(CONFIG_NET_ICMPv6_SOCKET) || defined(CONFIG_NET_ICMPv6_NEIGHBOR) - { - /* Traverse all of the tasks waiting to send an ICMPv6 ECHO request. */ + case ICMPv6_POLL: - bstop = devif_poll_icmpv6(dev, callback); - } + /* Traverse all of the tasks waiting to send an ICMPv6 ECHO + * request. + */ - if (!bstop) + bstop = devif_poll_icmpv6(dev, callback); + break; #endif #ifdef CONFIG_NET_IPFORWARD - { - /* Traverse all of the tasks waiting to forward a packet to this - * device. - */ - bstop = devif_poll_forward(dev, callback); - } + /* Traverse all of the tasks waiting to forward a packet to this + * device. + */ - if (!bstop) + case IPFWD_POLL: + bstop = devif_poll_forward(dev, callback); + break; #endif - { - /* Nothing more to do */ + default: + nerr("ERROR: Unhandled poll type: %d\n", i - 1); + break; + } + + if (!bstop) + { + dev->d_polltype &= ~(1 << (i - 1)); + } } return bstop; diff --git a/net/icmp/icmp_sendmsg.c b/net/icmp/icmp_sendmsg.c index 659af82b1b3..808db35ac96 100644 --- a/net/icmp/icmp_sendmsg.c +++ b/net/icmp/icmp_sendmsg.c @@ -403,7 +403,7 @@ ssize_t icmp_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, /* Notify the device driver of the availability of TX data */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, ICMP_POLL); /* Wait for either the send to complete or for timeout to occur. * net_sem_timedwait will also terminate if a signal is received. diff --git a/net/icmpv6/icmpv6_autoconfig.c b/net/icmpv6/icmpv6_autoconfig.c index bb7f5412a1b..c8603b57802 100644 --- a/net/icmpv6/icmpv6_autoconfig.c +++ b/net/icmpv6/icmpv6_autoconfig.c @@ -224,7 +224,7 @@ static int icmpv6_send_message(FAR struct net_driver_s *dev, bool advertise) /* Notify the device driver that new TX data is available. */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, ICMPv6_POLL); /* Wait for the send to complete or an error to occur * net_sem_wait will also terminate if a signal is received. diff --git a/net/icmpv6/icmpv6_neighbor.c b/net/icmpv6/icmpv6_neighbor.c index a689c8fb0fd..0756ac1cbcf 100644 --- a/net/icmpv6/icmpv6_neighbor.c +++ b/net/icmpv6/icmpv6_neighbor.c @@ -336,7 +336,7 @@ int icmpv6_neighbor(FAR struct net_driver_s *dev, /* Notify the device driver that new TX data is available. */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, ICMPv6_POLL); /* Wait for the send to complete or an error to occur. * net_sem_wait will also terminate if a signal is received. diff --git a/net/icmpv6/icmpv6_sendmsg.c b/net/icmpv6/icmpv6_sendmsg.c index 3e076611311..03a3b3e83c9 100644 --- a/net/icmpv6/icmpv6_sendmsg.c +++ b/net/icmpv6/icmpv6_sendmsg.c @@ -384,9 +384,9 @@ ssize_t icmpv6_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, state.snd_cb = icmpv6_callback_alloc(dev, conn); if (state.snd_cb) { - state.snd_cb->flags = (ICMPv6_POLL | NETDEV_DOWN); - state.snd_cb->priv = (FAR void *)&state; - state.snd_cb->event = sendto_eventhandler; + state.snd_cb->flags = (ICMPv6_POLL | NETDEV_DOWN); + state.snd_cb->priv = (FAR void *)&state; + state.snd_cb->event = sendto_eventhandler; /* Setup to receive ICMPv6 ECHO replies */ @@ -399,7 +399,7 @@ ssize_t icmpv6_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, /* Notify the device driver of the availability of TX data */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, ICMPv6_POLL); /* Wait for either the send to complete or for timeout to occur. * net_sem_timedwait will also terminate if a signal is received. diff --git a/net/ieee802154/ieee802154_sendmsg.c b/net/ieee802154/ieee802154_sendmsg.c index 4531d1f30cf..a54e8b65da3 100644 --- a/net/ieee802154/ieee802154_sendmsg.c +++ b/net/ieee802154/ieee802154_sendmsg.c @@ -492,13 +492,13 @@ static ssize_t ieee802154_sendto(FAR struct socket *psock, { /* Set up the callback in the connection */ - state.is_cb->flags = PKT_POLL; + state.is_cb->flags = IEEE802154_POLL; state.is_cb->priv = (FAR void *)&state; state.is_cb->event = ieee802154_sendto_eventhandler; /* Notify the device driver that new TX data is available. */ - netdev_txnotify_dev(&radio->r_dev); + netdev_txnotify_dev(&radio->r_dev, IEEE802154_POLL); /* Wait for the send to complete or an error to occur. * net_sem_wait will also terminate if a signal is received. diff --git a/net/igmp/igmp_msg.c b/net/igmp/igmp_msg.c index ba044aeecfe..7d57033e527 100644 --- a/net/igmp/igmp_msg.c +++ b/net/igmp/igmp_msg.c @@ -106,7 +106,7 @@ int igmp_schedmsg(FAR struct igmp_group_s *group, uint8_t msgid) /* Notify the device that we have a packet to send */ netdev_lock(dev); - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, IGMP_POLL); netdev_unlock(dev); return OK; } diff --git a/net/ipforward/ipfwd_forward.c b/net/ipforward/ipfwd_forward.c index 50e7deb1b5d..7cec2833dea 100644 --- a/net/ipforward/ipfwd_forward.c +++ b/net/ipforward/ipfwd_forward.c @@ -166,7 +166,7 @@ static uint32_t ipfwd_eventhandler(FAR struct net_driver_s *dev, /* Copy the user data into d_appdata and send it. */ devif_forward(fwd); - flags &= ~DEVPOLL_MASK; + flags &= ~IPFWD_POLL; #if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) /* If both IPv4 and IPv6 support are enabled, then we will need to @@ -244,7 +244,7 @@ int ipfwd_forward(FAR struct forward_s *fwd) /* Notify the device driver of the availability of TX data */ - netdev_txnotify_dev(fwd->f_dev); + netdev_txnotify_dev(fwd->f_dev, IPFWD_POLL); return OK; } diff --git a/net/ipforward/ipfwd_poll.c b/net/ipforward/ipfwd_poll.c index 2add1f963a5..53fe7bd94e5 100644 --- a/net/ipforward/ipfwd_poll.c +++ b/net/ipforward/ipfwd_poll.c @@ -175,7 +175,7 @@ void ipfwd_poll(FAR struct net_driver_s *dev) flags = devif_conn_event(dev, IPFWD_POLL, dev->d_conncb); #ifdef CONFIG_NET_6LOWPAN - if ((flags & DEVPOLL_MASK) == 0) + if ((flags & IPFWD_POLL) == 0) { /* Get the L2 protocol of packet in the device's d_buf */ diff --git a/net/ipfrag/ipfrag.c b/net/ipfrag/ipfrag.c index 09618dbd8a9..efc1f58989b 100644 --- a/net/ipfrag/ipfrag.c +++ b/net/ipfrag/ipfrag.c @@ -263,7 +263,7 @@ static void ip_fragin_timerwork(FAR void *arg) ninfo("Send Time Exceeded ICMP%s Message to source " "host\n", node->frags->isipv4 ? "v4" : "v6"); - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, IPFRAG_POLL); } net_unlock(); diff --git a/net/ipfrag/ipv4_frag.c b/net/ipfrag/ipv4_frag.c index b3f82329136..d62d09ee913 100644 --- a/net/ipfrag/ipv4_frag.c +++ b/net/ipfrag/ipv4_frag.c @@ -435,7 +435,7 @@ int32_t ipv4_fragout(FAR struct net_driver_s *dev, uint16_t mtu) g_netstats.ipv4.sent += nfrags - 1; #endif - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, IPFRAG_POLL); return OK; diff --git a/net/ipfrag/ipv6_frag.c b/net/ipfrag/ipv6_frag.c index 69b09580d69..ffae571ef48 100644 --- a/net/ipfrag/ipv6_frag.c +++ b/net/ipfrag/ipv6_frag.c @@ -662,7 +662,7 @@ int32_t ipv6_fragout(FAR struct net_driver_s *dev, uint16_t mtu) g_netstats.ipv6.sent += nfrags - 1; #endif - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, IPFRAG_POLL); return OK; diff --git a/net/mld/mld_msg.c b/net/mld/mld_msg.c index 8b1d71ce40c..4cb6a6b1d4a 100644 --- a/net/mld/mld_msg.c +++ b/net/mld/mld_msg.c @@ -81,7 +81,7 @@ int mld_schedmsg(FAR struct mld_group_s *group, uint8_t msgtype) /* Notify the device that we have a packet to send */ netdev_lock(dev); - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, MLD_POLL); netdev_unlock(dev); return OK; } diff --git a/net/mld/mld_timer.c b/net/mld/mld_timer.c index 0556082c487..2ffeb977f06 100644 --- a/net/mld/mld_timer.c +++ b/net/mld/mld_timer.c @@ -159,7 +159,7 @@ static void mld_gendog_work(FAR void *arg) /* Notify the device that we have a packet to send */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, MLD_POLL); /* Restart the Querier timer */ diff --git a/net/netdev/netdev.h b/net/netdev/netdev.h index 5f4a541cb19..1e3003de02d 100644 --- a/net/netdev/netdev.h +++ b/net/netdev/netdev.h @@ -310,8 +310,9 @@ FAR struct net_driver_s *netdev_default(void); * data is available. * * Input Parameters: - * lipaddr - The local address bound to the socket - * ripaddr - The remote address to send the data + * lipaddr - The local address bound to the socket + * ripaddr - The remote address to send the data + * polltype - The type of poll to be triggered for the device. * * Returned Value: * None @@ -319,7 +320,8 @@ FAR struct net_driver_s *netdev_default(void); ****************************************************************************/ #ifdef CONFIG_NET_IPv4 -void netdev_ipv4_txnotify(in_addr_t lipaddr, in_addr_t ripaddr); +void netdev_ipv4_txnotify(in_addr_t lipaddr, in_addr_t ripaddr, + uint32_t polltype); #endif /* CONFIG_NET_IPv4 */ /**************************************************************************** @@ -330,8 +332,9 @@ void netdev_ipv4_txnotify(in_addr_t lipaddr, in_addr_t ripaddr); * data is available. * * Input Parameters: - * lipaddr - The local address bound to the socket - * ripaddr - The remote address to send the data + * lipaddr - The local address bound to the socket + * ripaddr - The remote address to send the data + * polltype - The type of poll to be triggered for the device. * * Returned Value: * None @@ -340,7 +343,8 @@ void netdev_ipv4_txnotify(in_addr_t lipaddr, in_addr_t ripaddr); #ifdef CONFIG_NET_IPv6 void netdev_ipv6_txnotify(FAR const net_ipv6addr_t lipaddr, - FAR const net_ipv6addr_t ripaddr); + FAR const net_ipv6addr_t ripaddr, + uint32_t polltype); #endif /* CONFIG_NET_IPv6 */ /**************************************************************************** @@ -352,14 +356,15 @@ void netdev_ipv6_txnotify(FAR const net_ipv6addr_t lipaddr, * packet will be routed. * * Input Parameters: - * dev - The network device driver state structure. + * dev - The network device driver state structure. + * polltype - The type of poll to be triggered for the device. * * Returned Value: * None * ****************************************************************************/ -void netdev_txnotify_dev(FAR struct net_driver_s *dev); +void netdev_txnotify_dev(FAR struct net_driver_s *dev, uint32_t polltype); /**************************************************************************** * Name: netdev_count diff --git a/net/netdev/netdev_register.c b/net/netdev/netdev_register.c index e23daa44082..f8e5679487e 100644 --- a/net/netdev/netdev_register.c +++ b/net/netdev/netdev_register.c @@ -425,6 +425,8 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype) dev->d_conncb_tail = NULL; dev->d_devcb = NULL; + dev->d_polltype = 0; + nxrmutex_init(&dev->d_lock); /* We need exclusive access for the following operations */ diff --git a/net/netdev/netdev_txnotify.c b/net/netdev/netdev_txnotify.c index 1320a871f74..95884feda43 100644 --- a/net/netdev/netdev_txnotify.c +++ b/net/netdev/netdev_txnotify.c @@ -57,11 +57,12 @@ ****************************************************************************/ #ifdef CONFIG_NET_IPv4 -void netdev_ipv4_txnotify(in_addr_t lipaddr, in_addr_t ripaddr) +void netdev_ipv4_txnotify(in_addr_t lipaddr, in_addr_t ripaddr, + uint32_t polltype) { /* Find the device driver that serves the subnet of the remote address */ - netdev_txnotify_dev(netdev_findby_ripv4addr(lipaddr, ripaddr)); + netdev_txnotify_dev(netdev_findby_ripv4addr(lipaddr, ripaddr), polltype); } #endif /* CONFIG_NET_IPv4 */ @@ -83,11 +84,12 @@ void netdev_ipv4_txnotify(in_addr_t lipaddr, in_addr_t ripaddr) #ifdef CONFIG_NET_IPv6 void netdev_ipv6_txnotify(FAR const net_ipv6addr_t lipaddr, - FAR const net_ipv6addr_t ripaddr) + FAR const net_ipv6addr_t ripaddr, + uint32_t polltype) { /* Find the device driver that serves the subnet of the remote address */ - netdev_txnotify_dev(netdev_findby_ripv6addr(lipaddr, ripaddr)); + netdev_txnotify_dev(netdev_findby_ripv6addr(lipaddr, ripaddr), polltype); } #endif /* CONFIG_NET_IPv6 */ @@ -107,10 +109,14 @@ void netdev_ipv6_txnotify(FAR const net_ipv6addr_t lipaddr, * ****************************************************************************/ -void netdev_txnotify_dev(FAR struct net_driver_s *dev) +void netdev_txnotify_dev(FAR struct net_driver_s *dev, uint32_t polltype) { if (dev != NULL && dev->d_txavail != NULL) { + /* Set the poll type flags */ + + dev->d_polltype |= polltype; + /* Notify the device driver that new TX data is available. */ dev->d_txavail(dev); diff --git a/net/pkt/pkt_sendmsg_buffered.c b/net/pkt/pkt_sendmsg_buffered.c index 9bfc97fb6a2..2ebbdc01507 100644 --- a/net/pkt/pkt_sendmsg_buffered.c +++ b/net/pkt/pkt_sendmsg_buffered.c @@ -156,7 +156,7 @@ static uint32_t psock_send_eventhandler(FAR struct net_driver_s *dev, /* Notify the device driver that new TX data is available. */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, PKT_POLL); } else { @@ -375,7 +375,7 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR const struct msghdr *msg, /* Notify the device driver that new TX data is available. */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, PKT_POLL); conn_dev_unlock(&conn->sconn, dev); } diff --git a/net/pkt/pkt_sendmsg_unbuffered.c b/net/pkt/pkt_sendmsg_unbuffered.c index afcbad3e314..db954e0d746 100644 --- a/net/pkt/pkt_sendmsg_unbuffered.c +++ b/net/pkt/pkt_sendmsg_unbuffered.c @@ -239,7 +239,7 @@ ssize_t pkt_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, /* Notify the device driver that new TX data is available. */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, PKT_POLL); /* Wait for the send to complete or an error to occur. * net_sem_wait will also terminate if a signal is received. diff --git a/net/sixlowpan/sixlowpan_send.c b/net/sixlowpan/sixlowpan_send.c index d2d4230ddb0..0f9e3a2b4c0 100644 --- a/net/sixlowpan/sixlowpan_send.c +++ b/net/sixlowpan/sixlowpan_send.c @@ -133,7 +133,7 @@ static uint32_t send_eventhandler(FAR struct net_driver_s *dev, if ((flags & WPAN_NEWDATA) == 0) { - DEBUGASSERT((flags & WPAN_POLL) != 0); + DEBUGASSERT((flags & UDP_POLL) != 0); /* Transfer the frame list to the IEEE802.15.4 MAC device */ @@ -142,7 +142,7 @@ static uint32_t send_eventhandler(FAR struct net_driver_s *dev, sinfo->s_ipv6hdr, sinfo->s_buf, sinfo->s_len, sinfo->s_destmac); - flags &= ~WPAN_POLL; + flags &= ~UDP_POLL; neighbor_reachable(dev); goto end_wait; } @@ -239,13 +239,13 @@ int sixlowpan_send(FAR struct net_driver_s *dev, /* Set up the callback in the connection */ - sinfo.s_cb->flags = (NETDEV_DOWN | WPAN_POLL); + sinfo.s_cb->flags = (NETDEV_DOWN | UDP_POLL); sinfo.s_cb->priv = (FAR void *)&sinfo; sinfo.s_cb->event = send_eventhandler; /* Notify the IEEE802.15.4 MAC that we have data to send. */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, UDP_POLL); /* Wait for the send to complete or an error to occur. * net_sem_timedwait will also terminate if a signal is received. diff --git a/net/sixlowpan/sixlowpan_tcpsend.c b/net/sixlowpan/sixlowpan_tcpsend.c index 26344b2ba91..043a239b6eb 100644 --- a/net/sixlowpan/sixlowpan_tcpsend.c +++ b/net/sixlowpan/sixlowpan_tcpsend.c @@ -628,7 +628,7 @@ static int sixlowpan_send_packet(FAR struct socket *psock, /* Set up the callback in the connection */ sinfo.s_cb->flags = (NETDEV_DOWN | TCP_ACKDATA | TCP_REXMIT | - TCP_DISCONN_EVENTS | WPAN_POLL); + TCP_DISCONN_EVENTS | TCP_POLL); sinfo.s_cb->priv = (FAR void *)&sinfo; sinfo.s_cb->event = tcp_send_eventhandler; @@ -640,7 +640,7 @@ static int sixlowpan_send_packet(FAR struct socket *psock, /* Notify the IEEE802.15.4 MAC that we have data to send. */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, TCP_POLL); /* Wait for the send to complete or an error to occur. * net_sem_timedwait will also terminate if a signal is received. diff --git a/net/tcp/tcp_connect.c b/net/tcp/tcp_connect.c index eb8ee1691b6..abc2e12711e 100644 --- a/net/tcp/tcp_connect.c +++ b/net/tcp/tcp_connect.c @@ -103,11 +103,11 @@ static inline int psock_setup_callbacks(FAR struct socket *psock, { /* Set up the connection event handler */ - pstate->tc_cb->flags = (TCP_NEWDATA | TCP_ABORT | TCP_TIMEDOUT | - TCP_CONNECTED | NETDEV_DOWN); - pstate->tc_cb->priv = (FAR void *)pstate; - pstate->tc_cb->event = psock_connect_eventhandler; - ret = OK; + pstate->tc_cb->flags = (TCP_NEWDATA | TCP_ABORT | TCP_TIMEDOUT | + TCP_CONNECTED | NETDEV_DOWN); + pstate->tc_cb->priv = (FAR void *)pstate; + pstate->tc_cb->event = psock_connect_eventhandler; + ret = OK; } return ret; @@ -379,7 +379,7 @@ int psock_tcp_connect(FAR struct socket *psock, /* Notify the device driver that new connection is available. */ - netdev_txnotify_dev(conn->dev); + netdev_txnotify_dev(conn->dev, TCP_POLL); /* Wait for either the connect to complete or for an * error/timeout to occur. @@ -442,7 +442,7 @@ int psock_tcp_connect(FAR struct socket *psock, /* Notify the device driver that new connection is available. */ - netdev_txnotify_dev(conn->dev); + netdev_txnotify_dev(conn->dev, TCP_POLL); } } diff --git a/net/tcp/tcp_recvfrom.c b/net/tcp/tcp_recvfrom.c index f7f6e44fac0..736fc12c131 100644 --- a/net/tcp/tcp_recvfrom.c +++ b/net/tcp/tcp_recvfrom.c @@ -839,7 +839,7 @@ static ssize_t tcp_recvfrom_one(FAR struct tcp_conn_s *conn, FAR void *buf, { conn_unlock(&conn->sconn); netdev_lock(conn->dev); - netdev_txnotify_dev(conn->dev); + netdev_txnotify_dev(conn->dev, TCP_POLL); netdev_unlock(conn->dev); conn_lock(&conn->sconn); } diff --git a/net/tcp/tcp_send.c b/net/tcp/tcp_send.c index ce09b57c2f6..5713d2d7eed 100644 --- a/net/tcp/tcp_send.c +++ b/net/tcp/tcp_send.c @@ -699,7 +699,7 @@ void tcp_send_txnotify(FAR struct socket *psock, { /* Notify the device driver that send data is available */ - netdev_ipv4_txnotify(conn->u.ipv4.laddr, conn->u.ipv4.raddr); + netdev_ipv4_txnotify(conn->u.ipv4.laddr, conn->u.ipv4.raddr, TCP_POLL); } #endif /* CONFIG_NET_IPv4 */ @@ -711,7 +711,7 @@ void tcp_send_txnotify(FAR struct socket *psock, /* Notify the device driver that send data is available */ DEBUGASSERT(psock->s_domain == PF_INET6); - netdev_ipv6_txnotify(conn->u.ipv6.laddr, conn->u.ipv6.raddr); + netdev_ipv6_txnotify(conn->u.ipv6.laddr, conn->u.ipv6.raddr, TCP_POLL); } #endif /* CONFIG_NET_IPv6 */ } diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index 68711453a8c..5ab17b54c91 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -626,8 +626,7 @@ static uint32_t psock_send_eventhandler(FAR struct net_driver_s *dev, */ conn->timeout = true; - - netdev_txnotify_dev(conn->dev); + netdev_txnotify_dev(conn->dev, TCP_POLL); netdev_iob_replace(dev, iob); dev->d_buf = buf; dev->d_appdata = appdata; diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index fa5844b9866..77a62ef30ad 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -597,10 +597,10 @@ ssize_t psock_tcp_send(FAR struct socket *psock, /* Set up the callback in the connection */ - state.snd_cb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL | - TCP_DISCONN_EVENTS | TCP_TXCLOSE); - state.snd_cb->priv = (FAR void *)&state; - state.snd_cb->event = tcpsend_eventhandler; + state.snd_cb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL | + TCP_DISCONN_EVENTS | TCP_TXCLOSE); + state.snd_cb->priv = (FAR void *)&state; + state.snd_cb->event = tcpsend_eventhandler; /* Notify the device driver of the availability of TX data */ diff --git a/net/tcp/tcp_sendfile.c b/net/tcp/tcp_sendfile.c index 429c6449f3f..0aabc9c88d1 100644 --- a/net/tcp/tcp_sendfile.c +++ b/net/tcp/tcp_sendfile.c @@ -511,10 +511,10 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile, /* Set up the callback in the connection */ - state.snd_cb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL | - TCP_DISCONN_EVENTS); - state.snd_cb->priv = (FAR void *)&state; - state.snd_cb->event = sendfile_eventhandler; + state.snd_cb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL | + TCP_DISCONN_EVENTS); + state.snd_cb->priv = (FAR void *)&state; + state.snd_cb->event = sendfile_eventhandler; /* Notify the device driver of the availability of TX data */ diff --git a/net/tcp/tcp_timer.c b/net/tcp/tcp_timer.c index 5422616d407..368a3379b20 100644 --- a/net/tcp/tcp_timer.c +++ b/net/tcp/tcp_timer.c @@ -155,7 +155,7 @@ static void tcp_timer_expiry(FAR void *arg) tcp_conn_list_unlock(); conn->timeout = true; netdev_lock(conn->dev); - netdev_txnotify_dev(conn->dev); + netdev_txnotify_dev(conn->dev, TCP_POLL); netdev_unlock(conn->dev); return; } diff --git a/net/udp/udp_sendto_buffered.c b/net/udp/udp_sendto_buffered.c index 194ce3c5dfd..683879577e6 100644 --- a/net/udp/udp_sendto_buffered.c +++ b/net/udp/udp_sendto_buffered.c @@ -357,7 +357,7 @@ static int sendto_next_transfer(FAR struct udp_conn_s *conn) /* Notify the device driver of the availability of TX data */ - netdev_txnotify_dev(dev); + netdev_txnotify_dev(dev, UDP_POLL); out: conn_dev_unlock(&conn->sconn, dev); diff --git a/net/udp/udp_sendto_unbuffered.c b/net/udp/udp_sendto_unbuffered.c index ffa190f6e2a..5eecb9f7402 100644 --- a/net/udp/udp_sendto_unbuffered.c +++ b/net/udp/udp_sendto_unbuffered.c @@ -471,13 +471,13 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, state.st_cb = udp_callback_alloc(state.st_dev, conn); if (state.st_cb) { - state.st_cb->flags = (UDP_POLL | NETDEV_DOWN); - state.st_cb->priv = (FAR void *)&state; - state.st_cb->event = sendto_eventhandler; + state.st_cb->flags = (UDP_POLL | NETDEV_DOWN); + state.st_cb->priv = (FAR void *)&state; + state.st_cb->event = sendto_eventhandler; /* Notify the device driver of the availability of TX data */ - netdev_txnotify_dev(state.st_dev); + netdev_txnotify_dev(state.st_dev, UDP_POLL); /* Wait for either the receive to complete or for an error/timeout to * occur. NOTES: net_sem_timedwait will also terminate if a signal