diff --git a/ChangeLog b/ChangeLog
index cab2ef20360af178d28fc0cd7bc70d83fd4a7c5f..f14df48b51d6d64a71f54c7d9c3aaa15843b97be 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -234,4 +234,6 @@
 	* Integrated uIP micro webserver
 	* Corrected a serious bug in TCP queue management
 	* Fix leak in socket close logic
-
+	* Add TX notification to driver so that it can respond faster to
+	  the availability of TX data.
+	* Moved urgent data info into device structure.
diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html
index 870918360ed241844ece86cc2b6cfca7d46a69ae..f024189e0aa7a0fb23f4163f4b77a85facd070b6 100644
--- a/Documentation/NuttX.html
+++ b/Documentation/NuttX.html
@@ -705,6 +705,9 @@ Other memory:
 	* Integrated uIP micro webserver
 	* Corrected a serious bug in TCP queue management
 	* Fix leak in socket close logic
+	* Add TX notification to driver so that it can respond faster to
+	  the availability of TX data.
+	* Moved urgent data info into device structure.
 </pre></ul>
 
 <table width ="100%">
diff --git a/Documentation/NuttxPortingGuide.html b/Documentation/NuttxPortingGuide.html
index faf3c5f89012feb9fa2c10de3b43f5a02724164a..98af10dae7e2349eba0d4f584c0071bcabfb7915 100644
--- a/Documentation/NuttxPortingGuide.html
+++ b/Documentation/NuttxPortingGuide.html
@@ -1370,6 +1370,11 @@ The system can be re-made subsequently by just typing <code>make</code>.
   <li>
     <code>CONFIG_NET_NTCP_READAHEAD_BUFFERS</code>: Number of TCP read-ahead buffers (may be zero)
   </li>
+  <li>
+    <code>CONFIG_NET_TCPURGDATA</code>: Determines if support for TCP urgent data
+    notification should be compiled in. Urgent data (out-of-band data)
+    is a rarely used TCP feature that is very seldom would be required.
+  </li>
   <li>
     <code>CONFIG_NET_UDP</code>: UDP support on or off
   </li>
diff --git a/TODO b/TODO
index 0b8220e004fb481373ded7560b8e4903ad2ee568..3c9d5ead7d8a55884f5697f45641ed9347aba50f 100644
--- a/TODO
+++ b/TODO
@@ -33,15 +33,11 @@ o Network
   but is not implemented.
 - uIP's netutils/telnetd (and maybe others) are seriously broken.
   Need to be re-written to use listen() and accept()
-- uIP's netutils/webserver does not work reliably
+- uIP's netutils/webserver hangs
+- uIP's netutils/smtp, dpcpc, resolv, webclient -- untested
 - Should implement SOCK_RAW
 - accept() and recvfrom() need to return connection address
 - Performance Improvements (uIP is not very fast):
-- Improve performance by stimulating the driver to accept new TX data before the
-  next polling interval.
-  Add a txail callback into driver to eliminate send delays.  Since we want to
-  support multiple network devices, this means we will have to add some infrastructure
-  to map to device.
 - uIP polling issues:
   (1) Current logic will not support multiple ethernet drivers.  Each driver should
       poll on TCP connections connect on the network supported by the driver; UDP
diff --git a/configs/README.txt b/configs/README.txt
index da9535e8ab52bd467d243cbdfc966a1d1ec6b2ff..df5a53b433f70bf147417f7544d448088b1d33ff 100644
--- a/configs/README.txt
+++ b/configs/README.txt
@@ -221,6 +221,9 @@ defconfig -- This is a configuration file similar to the Linux
 		CONFIG_NET_TCP_READAHEAD_BUFSIZE - Size of TCP read-ahead buffers
 		CONFIG_NET_NTCP_READAHEAD_BUFFERS - Number of TCP read-ahead buffers
 		  (may be zero)
+		CONFIG_NET_TCPURGDATA - Determines if support for TCP urgent data
+		  notification should be compiled in. Urgent data (out-of-band data)
+		  is a rarely used TCP feature that is very seldom would be required.
 		CONFIG_NET_UDP - UDP support on or off
 		CONFIG_NET_UDP_CHECKSUMS - UDP checksums on or off
 		CONFIG_NET_UDP_CONNS - The maximum amount of concurrent UDP
diff --git a/drivers/net/dm90x0.c b/drivers/net/dm90x0.c
index a604b65a397f4bc0de4454c9c712869dcf30f280..aa3b5837573d806521c01af6cce13857f56b74e2 100644
--- a/drivers/net/dm90x0.c
+++ b/drivers/net/dm90x0.c
@@ -393,6 +393,7 @@ static void dm9x_txtimeout(int argc, uint32 arg, ...);
 
 static int dm9x_ifup(struct uip_driver_s *dev);
 static int dm9x_ifdown(struct uip_driver_s *dev);
+static int dm9x_txavail(struct uip_driver_s *dev);
 
 /* Initialization functions */
 
@@ -825,7 +826,7 @@ static int dm9x_transmit(struct dm9x_driver_s *dm9x)
  *   3. During normal TX polling
  *
  * Parameters:
- *   dm9x  - Reference to the driver state structure
+ *   dev  - Reference to the NuttX driver state structure
  *
  * Returned Value:
  *   OK on success; a negated errno on failure
@@ -1447,6 +1448,46 @@ static int dm9x_ifdown(struct uip_driver_s *dev)
   return OK;
 }
 
+/****************************************************************************
+ * Function: dm9x_txavail
+ *
+ * Description:
+ *   Driver callback invoked when new TX data is available.  This is a 
+ *   stimulus perform an out-of-cycle poll and, thereby, reduce the TX
+ *   latency.
+ *
+ * Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Called in normal user mode
+ *
+ ****************************************************************************/
+
+static int dm9x_txavail(struct uip_driver_s *dev)
+{
+  struct dm9x_driver_s *dm9x = (struct dm9x_driver_s *)dev->d_private;
+  irqstate_t flags;
+
+  dbg("Polling\n");
+  flags = irqsave();
+
+  /* Check if there is room in the DM90x0 to hold another packet.  In 100M mode,
+   * that can be 2 packets, otherwise it is a single packet.
+   */
+
+  if (dm9x->dm_ntxpending < 1 || (dm9x->dm_b100M && dm9x->dm_ntxpending < 2))
+    {
+      /* If so, then poll uIP for new XMIT data */
+
+      (void)uip_poll(&dm9x->dm_dev, dm9x_uiptxpoll);
+    }
+  irqrestore(flags);
+}
+
 /****************************************************************************
  * Function: dm9x_bringup
  *
@@ -1659,6 +1700,7 @@ int dm9x_initialize(void)
   memset(g_dm9x, 0, CONFIG_DM9X_NINTERFACES*sizeof(struct dm9x_driver_s));
   g_dm9x[0].dm_dev.d_ifup    = dm9x_ifup;     /* I/F down callback */
   g_dm9x[0].dm_dev.d_ifdown  = dm9x_ifdown;   /* I/F up (new IP address) callback */
+  g_dm9x[0].dm_dev.d_txavail = dm9x_txavail;  /* New TX data callback */
   g_dm9x[0].dm_dev.d_private = (void*)g_dm9x; /* Used to recover private state from dev */
 
   /* Create a watchdog for timing polling for and timing of transmisstions */
diff --git a/include/net/uip/uip-arch.h b/include/net/uip/uip-arch.h
index b4f21fb64218ab880c554fe8f67271e35a0d2c24..eb5a0e5ba275dfcbed6d38b26a8bfa49916258ce 100644
--- a/include/net/uip/uip-arch.h
+++ b/include/net/uip/uip-arch.h
@@ -106,14 +106,17 @@ struct uip_driver_s
    *    void
    *    devicedriver_send(void)
    *    {
-   *       hwsend(&dev->d_buf[0], UIP_LLH_LEN);
-   *       if(dev->d_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
-   *         hwsend(&dev->d_buf[UIP_LLH_LEN], dev->d_len - UIP_LLH_LEN);
-   *       } else {
-   *         hwsend(&dev->d_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
-   *         hwsend(dev->d_appdata, dev->d_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
-   *       }
-   *   }
+   *      hwsend(&dev->d_buf[0], UIP_LLH_LEN);
+   *      if(dev->d_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN)
+   *        {
+   *          hwsend(&dev->d_buf[UIP_LLH_LEN], dev->d_len - UIP_LLH_LEN);
+   *        }
+   *      else
+   *        {
+   *          hwsend(&dev->d_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
+   *          hwsend(dev->d_appdata, dev->d_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
+   *        }
+   *    }
    */
 
   uint8 d_buf[CONFIG_NET_BUFSIZE + 2];
@@ -130,6 +133,18 @@ struct uip_driver_s
 
   uint8 *d_snddata;
 
+#ifdef CONFIG_NET_TCPURGDATA
+  /* This pointer points to any urgent TCP data that has been received. Only
+   * present if compiled with support for urgent data (CONFIG_NET_TCPURGDATA).
+   */
+
+  uint8 *d_urgdata;
+
+  /* Length of the (received) urgent data */
+
+  uint16 d_urglen;
+#endif
+
 /* The length of the packet in the d_buf buffer.
  *
  * Holds the length of the packet in the d_buf buffer.
@@ -155,6 +170,7 @@ struct uip_driver_s
 
   int (*d_ifup)(struct uip_driver_s *dev);
   int (*d_ifdown)(struct uip_driver_s *dev);
+  int (*d_txavail)(struct uip_driver_s *dev);
 
   /* Drivers may attached device-specific, private information */
 
diff --git a/include/net/uip/uip.h b/include/net/uip/uip.h
index 20027622542fb1ad60ea41e99d1999c78eceaebf..59bd615bcfbd1578353b68731c2bbef09c01b741 100644
--- a/include/net/uip/uip.h
+++ b/include/net/uip/uip.h
@@ -161,7 +161,9 @@ struct uip_driver_s;      /* Forward reference */
 struct uip_conn
 {
   dq_entry_t node;        /* Implements a doubly linked list */
+#if 0 /* Not used */
   uip_ipaddr_t lipaddr;   /* The local IP address */
+#endif
   uip_ipaddr_t ripaddr;   /* The IP address of the remote host */
   uint16 lport;           /* The local TCP port, in network byte order */
   uint16 rport;           /* The remoteTCP port, in network byte order */
@@ -467,26 +469,6 @@ struct uip_eth_addr
  * Public Data
  ****************************************************************************/
 
-#if UIP_URGDATA > 0
-/* uint8 *uip_urgdata:
- *
- * This pointer points to any urgent data that has been received. Only
- * present if compiled with support for urgent data (UIP_URGDATA).
- */
-extern void *uip_urgdata;
-#endif /* UIP_URGDATA > 0 */
-
-
-/* Variables used in uIP device drivers
- *
- * uIP has a few global variables that are used in device drivers for
- * uIP.
- */
-
-#if UIP_URGDATA > 0
-extern uint16 uip_urglen; /* Length of (received) urgent data */
-#endif /* UIP_URGDATA > 0 */
-
 /* The current UDP connection */
 
 #ifdef CONFIG_NET_UDP
@@ -504,8 +486,6 @@ extern struct uip_stats uip_stat;
  * Public Function Prototypes
  ****************************************************************************/
 
-/* uIP configuration functions */
-
 /* uIP initialization functions
  *
  * The uIP initialization functions are used for booting uIP.
@@ -625,15 +605,6 @@ extern void uip_tcpreadaheadrelease(struct uip_readahead_s *buf);
 
 #define uip_datalen(dev)    ((dev)->d_len)
 
-/* The length of any out-of-band data (urgent data) that has arrived
- * on the connection.
- *
- * Note: The configuration parameter UIP_URGDATA must be set for this
- * function to be enabled.
- */
-
-#define uip_urgdatalen()    uip_urglen
-
 /* Tell the sending host to stop sending data.
  *
  * This function will close our receiver's window so that we stop
@@ -909,9 +880,10 @@ extern void uip_udpdisable(struct uip_udp_conn *conn);
  *   uip_ipaddr(&mask, 255,255,255,0);
  *   uip_ipaddr(&ipaddr1, 192,16,1,2);
  *   uip_ipaddr(&ipaddr2, 192,16,1,3);
- *   if(uip_ipaddr_maskcmp(ipaddr1, ipaddr2, &mask)) {
- *      printf("They are the same");
- *   }
+ *   if(uip_ipaddr_maskcmp(ipaddr1, ipaddr2, &mask))
+ *     {
+ *       printf("They are the same");
+ *     }
  *
  * addr1 The first IP address.
  * addr2 The second IP address.
@@ -920,9 +892,12 @@ extern void uip_udpdisable(struct uip_udp_conn *conn);
 
 #ifndef CONFIG_NET_IPv6
 #  define uip_ipaddr_maskcmp(addr1, addr2, mask) \
-  (((in_addr_t)(addr1) & (in_addr_t)(mask)) == ((in_addr_t)(addr2) & (in_addr_t)(mask)))
-#else /* !CONFIG_NET_IPv6 */
-#endif /* !CONFIG_NET_IPv6 */
+  (((in_addr_t)(addr1) & (in_addr_t)(mask)) == \
+   ((in_addr_t)(addr2) & (in_addr_t)(mask)))
+#else
+extern boolean uip_ipaddr_maskcmp(uip_addr_t addr1, uip_addr_t addr2,
+                                  uip_addr_t mask);
+#endif
 
 /* Mask out the network part of an IP address.
  *
diff --git a/include/net/uip/uipopt.h b/include/net/uip/uipopt.h
index b5088470340c619dc759609ebe671324a168e26a..68148393a3862b33730290fc4d9b6995684ff400 100644
--- a/include/net/uip/uipopt.h
+++ b/include/net/uip/uipopt.h
@@ -128,15 +128,6 @@
 # define CONFIG_NET_MAX_LISTENPORTS 20
 #endif
 
-/* Determines if support for TCP urgent data notification should be
- * compiled in.
- *
- * Urgent data (out-of-band data) is a rarely used TCP feature that
- * very seldom would be required.
- */
-
-#define UIP_URGDATA 0
-
 /* The initial retransmission timeout counted in timer pulses.
  *
  * This should not be changed.
diff --git a/net/Makefile b/net/Makefile
index cf6f35081bae321bbfe9a053659804572305d073..e429d623617511ac791c13cac1b22776a665234c 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -51,7 +51,8 @@ endif
 endif
 
 NETDEV_ASRCS	=
-NETDEV_CSRCS	= netdev-register.c netdev-ioctl.c netdev-find.c netdev-count.c 
+NETDEV_CSRCS	= netdev-register.c netdev-ioctl.c netdev-txnotify.c \
+		  netdev-findbyname.c netdev-findbyaddr.c netdev-count.c 
 
 include uip/Make.defs
 endif
diff --git a/net/net-internal.h b/net/net-internal.h
index 2354e54c1198bdbe2a9273d1187d3cdbc50cf4f1..1b57162a6f800629f1ef651b4fce0674a1e38aff 100644
--- a/net/net-internal.h
+++ b/net/net-internal.h
@@ -45,6 +45,7 @@
 
 #include <time.h>
 #include <nuttx/net.h>
+#include <net/uip/uip.h>
 
 #include "net-internal.h"
 
@@ -164,10 +165,22 @@ EXTERN void netdev_semtake(void);
 # define netdev_semgive() sem_post(&g_netdev_sem)
 #endif
 
-/* net-find.c ****************************************************************/
+/* net-findbyname.c **********************************************************/
 
 #if CONFIG_NSOCKET_DESCRIPTORS > 0
-EXTERN FAR struct uip_driver_s *netdev_find(const char *ifname);
+EXTERN FAR struct uip_driver_s *netdev_findbyname(const char *ifname);
+#endif
+
+/* net-findbyaddr.c **********************************************************/
+
+#if CONFIG_NSOCKET_DESCRIPTORS > 0
+EXTERN FAR struct uip_driver_s *netdev_findbyaddr(uip_ipaddr_t *raddr);
+#endif
+
+/* net-txnotify.c ************************************************************/
+
+#if CONFIG_NSOCKET_DESCRIPTORS > 0
+EXTERN void netdev_txnotify(uip_ipaddr_t *raddr);
 #endif
 
 /* net-count.c ***************************************************************/
diff --git a/net/netdev-findbyaddr.c b/net/netdev-findbyaddr.c
new file mode 100644
index 0000000000000000000000000000000000000000..c751960bf2cceb82833d8aa2c5f360abd6e05a0f
--- /dev/null
+++ b/net/netdev-findbyaddr.c
@@ -0,0 +1,128 @@
+/****************************************************************************
+ * net/netdev-findbyaddr.c
+ *
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
+
+#include <sys/types.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <net/uip/uip-arch.h>
+
+#include "net-internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Priviate Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: netdev_maskcmp
+ ****************************************************************************/
+
+static inline boolean netdev_maskcmp(uip_ipaddr_t *ipaddr, uip_ipaddr_t *raddr,
+                                     uip_ipaddr_t *netmask)
+{
+#ifndef CONFIG_NET_IPv6
+  return (*ipaddr & *netmask) == (*raddr & *netmask);
+#else
+# warning "Not implemented for IPv6"
+#endif
+}
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: netdev_findbyaddr
+ *
+ * Description:
+ *   Find a previously registered network device by matching a remote address
+ *   with the subnet served by the device
+ *
+ * Parameters:
+ *   raddr - Pointer to the remote address of a connection
+ *
+ * Returned Value:
+ *  Pointer to driver on success; null on failure
+ *
+ * Assumptions:
+ *  Called from normal user mode
+ *
+ ****************************************************************************/
+
+FAR struct uip_driver_s *netdev_findbyaddr(uip_ipaddr_t *raddr)
+{
+  struct uip_driver_s *dev;
+
+  if (raddr)
+    {
+      netdev_semtake();
+      for (dev = g_netdevices; dev; dev = dev->flink)
+        {
+          if (netdev_maskcmp(&dev->d_ipaddr, raddr, &dev->d_netmask))
+            {
+              netdev_semgive();
+              return dev;
+            }
+        }
+      netdev_semgive();
+    }
+  return NULL;
+}
+
+#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */
diff --git a/net/netdev-find.c b/net/netdev-findbyname.c
similarity index 94%
rename from net/netdev-find.c
rename to net/netdev-findbyname.c
index a975569d2e51d5cb25e10fa67ea00936d4e087a3..6c3d59ae3524de9b7a381c1b4fb4e495216945f2 100644
--- a/net/netdev-find.c
+++ b/net/netdev-findbyname.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * net/netdev-find.c
+ * net/netdev-findbyname.c
  *
  *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
@@ -73,10 +73,11 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Function: netdev_find
+ * Function: netdev_findbyname
  *
  * Description:
- *   Find a previously registered network device
+ *   Find a previously registered network device using its assigned
+ *   network interface name
  *
  * Parameters:
  *   ifname The interface name of the device of interest
@@ -89,7 +90,7 @@
  *
  ****************************************************************************/
 
-FAR struct uip_driver_s *netdev_find(const char *ifname)
+FAR struct uip_driver_s *netdev_findbyname(const char *ifname)
 {
   struct uip_driver_s *dev;
   if (ifname)
diff --git a/net/netdev-ioctl.c b/net/netdev-ioctl.c
index e13a22170f137d957b86bb908d01412a5d35037d..9adc2ae0ae47d3994df8a4420465d7434264a7e7 100644
--- a/net/netdev-ioctl.c
+++ b/net/netdev-ioctl.c
@@ -177,7 +177,7 @@ int netdev_ioctl(int sockfd, int cmd, struct ifreq *req)
    * in the request data.
    */
 
-  dev = netdev_find(req->ifr_name);
+  dev = netdev_findbyname(req->ifr_name);
   if (!dev)
     {
       err = EINVAL;
diff --git a/net/netdev-txnotify.c b/net/netdev-txnotify.c
new file mode 100644
index 0000000000000000000000000000000000000000..91a225effecbd48554994187e2e47a19b5bb5776
--- /dev/null
+++ b/net/netdev-txnotify.c
@@ -0,0 +1,106 @@
+/****************************************************************************
+ * net/netdev-txnotify.c
+ *
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
+
+#include <sys/types.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <net/uip/uip-arch.h>
+
+#include "net-internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Priviate Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: netdev_txnotify
+ *
+ * Description:
+ *   Notify the device driver that new TX data is available.
+ *
+ * Parameters:
+ *   raddr - Pointer to the remote address to send the data
+ *
+ * Returned Value:
+ *  None
+ *
+ * Assumptions:
+ *  Called from normal user mode
+ *
+ ****************************************************************************/
+
+void netdev_txnotify(uip_ipaddr_t *raddr)
+{
+  /* Find the device driver that serves the subnet of the remote address */
+
+  struct uip_driver_s *dev = netdev_findbyaddr(raddr);
+  if (dev && dev->d_txavail)
+    {
+      /* Notify the device driver that new TX data is available. */
+
+      (void)dev->d_txavail(dev);
+    }
+}
+
+#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */
diff --git a/net/send.c b/net/send.c
index c758b8eba9820b11c20623f9a7da1ba401e97b00..29633b3801d9394bca708f05b4aca1dad7673d5d 100644
--- a/net/send.c
+++ b/net/send.c
@@ -304,19 +304,23 @@ ssize_t send(int sockfd, const void *buf, size_t len, int flags)
       conn->data_private = (void*)&state;
       conn->data_event   = send_interrupt;
 
-    /* Wait for the send to complete or an error to occur:  NOTES: (1)
-     * sem_wait will also terminate if a signal is received, (2) interrupts
-     * are disabled!  They will be re-enabled while the task sleeps and
-     * automatically re-enabled when the task restarts.
-     */
+      /* Notify the device driver of the availaibilty of TX data */
 
-    ret = sem_wait(&state. snd_sem);
+      netdev_txnotify(&conn->ripaddr);
 
-    /* Make sure that no further interrupts are processed */
+      /* Wait for the send to complete or an error to occur:  NOTES: (1)
+       * sem_wait will also terminate if a signal is received, (2) interrupts
+       * are disabled!  They will be re-enabled while the task sleeps and
+       * automatically re-enabled when the task restarts.
+       */
 
-    conn->data_private = NULL;
-    conn->data_event   = NULL;
-  }
+      ret = sem_wait(&state. snd_sem);
+
+      /* Make sure that no further interrupts are processed */
+
+      conn->data_private = NULL;
+      conn->data_event   = NULL;
+    }
 
   sem_destroy(&state. snd_sem);
   irqrestore(save);
diff --git a/net/sendto.c b/net/sendto.c
index d18ea8e3d810f2cf410d6486517fc7dea2366c32..bbcf65b807c11bb207c497369a5c3eb1ae0924c7 100644
--- a/net/sendto.c
+++ b/net/sendto.c
@@ -283,6 +283,10 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
 
   uip_udpenable(psock->s_conn);
 
+  /* Notify the device driver of the availaibilty of TX data */
+
+  netdev_txnotify(&udp_conn->ripaddr);
+
   /* Wait for either the receive to complete or for an error/timeout to occur.
    * NOTES:  (1) sem_wait will also terminate if a signal is received, (2)
    * interrupts are disabled!  They will be re-enabled while the task sleeps
diff --git a/net/uip/uip-initialize.c b/net/uip/uip-initialize.c
index 2e00c5d9cf7487ced27be88ea0f6858d063527cc..a3338d082c44742866095b2c1b6d4c88a0933bad 100644
--- a/net/uip/uip-initialize.c
+++ b/net/uip/uip-initialize.c
@@ -56,10 +56,7 @@
  * Public Variables
  ****************************************************************************/
 
-#if UIP_URGDATA > 0
-void *uip_urgdata;           /* urgent data (out-of-band data), if present. */
-uint16 uip_urglen;           /* Length of (received) urgent data */
-#endif
+/* IP/TCP/UDP/ICMP statistics for all network interfaces */
 
 #ifdef CONFIG_NET_STATISTICS
 struct uip_stats uip_stat;
@@ -69,16 +66,16 @@ struct uip_stats uip_stat;
 
 uint16 g_ipid;
 
-const uip_ipaddr_t all_ones_addr =
+const uip_ipaddr_t g_alloneaddr =
 #ifdef CONFIG_NET_IPv6
-  {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};
-#else /* CONFIG_NET_IPv6 */
+  {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
+#else
   {0xffffffff};
-#endif /* CONFIG_NET_IPv6 */
+#endif
 
-const uip_ipaddr_t all_zeroes_addr =
+const uip_ipaddr_t g_allzeroaddr =
 #ifdef CONFIG_NET_IPv6
-  {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
+  {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
 #else
   {0x00000000};
 #endif
diff --git a/net/uip/uip-input.c b/net/uip/uip-input.c
index 71f9b8b9a1372f3b64fbe08dfa390377d8cf1223..b8d8ebb7e10ecdcbb75aa889348e5eeb1f939ba3 100644
--- a/net/uip/uip-input.c
+++ b/net/uip/uip-input.c
@@ -385,7 +385,7 @@ void uip_input(struct uip_driver_s *dev)
     }
 #endif /* CONFIG_NET_IPv6 */
 
-  if (uip_ipaddr_cmp(dev->d_ipaddr, all_zeroes_addr))
+  if (uip_ipaddr_cmp(dev->d_ipaddr, g_allzeroaddr))
     {
       /* If we are configured to use ping IP address configuration and
        * hasn't been assigned an IP address yet, we accept all ICMP
@@ -413,7 +413,7 @@ void uip_input(struct uip_driver_s *dev)
        */
 
 #ifdef CONFIG_NET_BROADCAST
-      if (BUF->proto == UIP_PROTO_UDP && uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)
+      if (BUF->proto == UIP_PROTO_UDP && uip_ipaddr_cmp(BUF->destipaddr, g_alloneaddr)
         {
           uip_udpinput(dev);
           return;
diff --git a/net/uip/uip-internal.h b/net/uip/uip-internal.h
index c358d431f111927a39301461eee32775a851bdce..ccc1c86bde93e1b96c180c6ddc1036fa553d4040 100644
--- a/net/uip/uip-internal.h
+++ b/net/uip/uip-internal.h
@@ -94,8 +94,8 @@
  * Public Data
  ****************************************************************************/
 
-extern const uip_ipaddr_t all_ones_addr;
-extern const uip_ipaddr_t all_zeroes_addr;
+extern const uip_ipaddr_t g_alloneaddr;
+extern const uip_ipaddr_t g_allzeroaddr;
 
 /* Increasing number used for the IP ID field. */
 
diff --git a/net/uip/uip-tcpconn.c b/net/uip/uip-tcpconn.c
index 96849d92623015d5f251d20e74befff537c51ea5..eb84d8f31d8d8cc252fb6a4478c26a146729d917 100644
--- a/net/uip/uip-tcpconn.c
+++ b/net/uip/uip-tcpconn.c
@@ -545,10 +545,13 @@ int uip_tcpbind(struct uip_conn *conn, const struct sockaddr_in *addr)
    */
 
   conn->lport = addr->sin_port;
+
+#if 0 /* Not used */
 #ifdef CONFIG_NET_IPv6
   uip_ipaddr_copy(conn->lipaddr, addr->sin6_addr.in6_u.u6_addr16);
 #else
   uip_ipaddr_copy(conn->lipaddr, addr->sin_addr.s_addr);
+#endif
 #endif
 
   return OK;
diff --git a/net/uip/uip-tcpinput.c b/net/uip/uip-tcpinput.c
index 1a74d5f8118f68365633e1bf7b63028d53e23562..ba11fcb8189d1336d505b098a558c88dbdf860b6 100644
--- a/net/uip/uip-tcpinput.c
+++ b/net/uip/uip-tcpinput.c
@@ -547,32 +547,34 @@ found:
           }
 
         /* Check the URG flag. If this is set, the segment carries urgent
-           data that we must pass to the application. */
+         * data that we must pass to the application.
+         */
+
         if ((BUF->flags & TCP_URG) != 0)
           {
-#if UIP_URGDATA > 0
-            uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
-            if (uip_urglen > dev->d_len)
+#ifdef CONFIG_NET_TCPURGDATA
+            dev->d_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
+            if (dev->d_urglen > dev->d_len)
               {
                 /* There is more urgent data in the next segment to come. */
 
-                uip_urglen = dev->d_len;
+                dev->d_urglen = dev->d_len;
               }
 
-            uip_incr32(conn->rcv_nxt, uip_urglen);
-            dev->d_len     -= uip_urglen;
-            uip_urgdata     = dev->d_appdata;
-            dev->d_appdata += uip_urglen;
+            uip_incr32(conn->rcv_nxt, dev->d_urglen);
+            dev->d_len     -= dev->d_urglen;
+            dev->d_urgdata  = dev->d_appdata;
+            dev->d_appdata += dev->d_urglen;
           }
         else
           {
-            uip_urglen     = 0;
-#else /* UIP_URGDATA > 0 */
+            dev->d_urglen   = 0;
+#else /* CONFIG_NET_TCPURGDATA */
             dev->d_appdata =
               ((uint8*)dev->d_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
             dev->d_len    -=
               (BUF->urgp[0] << 8) | BUF->urgp[1];
-#endif /* UIP_URGDATA > 0 */
+#endif /* CONFIG_NET_TCPURGDATA */
           }
 
         /* If d_len > 0 we have TCP data in the packet, and we flag this
diff --git a/net/uip/uip-udpconn.c b/net/uip/uip-udpconn.c
index b904aaac592867b6c0f51f671cf27e987f6ebcea..e8116d71af2c020af9d61bfdbafe7f53763f9fbe 100644
--- a/net/uip/uip-udpconn.c
+++ b/net/uip/uip-udpconn.c
@@ -247,8 +247,8 @@ struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
 
       if (conn->lport != 0 && buf->destport == conn->lport &&
           (conn->rport == 0 || buf->srcport == conn->rport) &&
-            (uip_ipaddr_cmp(conn->ripaddr, all_zeroes_addr) ||
-             uip_ipaddr_cmp(conn->ripaddr, all_ones_addr) ||
+            (uip_ipaddr_cmp(conn->ripaddr, g_allzeroaddr) ||
+             uip_ipaddr_cmp(conn->ripaddr, g_alloneaddr) ||
              uiphdr_ipaddr_cmp(buf->srcipaddr, &conn->ripaddr)))
         {
           /* Matching connection found.. return a reference to it */
@@ -385,7 +385,7 @@ int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
   else
     {
       conn->rport = 0;
-      uip_ipaddr_copy(conn->ripaddr, all_zeroes_addr);
+      uip_ipaddr_copy(conn->ripaddr, g_allzeroaddr);
     }
 
   conn->ttl   = UIP_TTL;