diff --git a/ChangeLog b/ChangeLog index c6e19b7ac5..650e3d8d1c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6489,4 +6489,7 @@ getopt() make like the optind variable in an undefined state (2014-1-20). * configs/olimex-stm32-p107: Failes to build is SPI3 for UEXT is not remapped. From Max Holtzberg (2014-1-21). + * Several network related files: Changes from Max Holtzberg to improve + how network status is reported. New controls to manage carrier + detect. (2014-1-21). diff --git a/drivers/net/encx24j600.c b/drivers/net/encx24j600.c index e8c4a1df2a..548340e978 100644 --- a/drivers/net/encx24j600.c +++ b/drivers/net/encx24j600.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/net/encx24j600.c * - * Copyright (C) 2013 UVC Ingenieure. All rights reserved. + * Copyright (C) 2013-1014 UVC Ingenieure. All rights reserved. * Author: Max Holtzberg * * References: @@ -208,7 +208,8 @@ enum enc_state_e { ENCSTATE_UNINIT = 0, /* The interface is in an uninitialized state */ ENCSTATE_DOWN, /* The interface is down */ - ENCSTATE_UP /* The interface is up */ + ENCSTATE_UP, /* The interface is up */ + ENCSTATE_RUNNING /* The interface is has a cable plugged in and is ready to use */ }; struct enc_descr_s @@ -1241,8 +1242,6 @@ static void enc_linkstatus(FAR struct enc_driver_s *priv) { uint16_t regval; - nllvdbg("link status changed\n"); - /* Before transmitting the first packet after link establishment or * auto-negotiation, the MAC duplex configuration must be manually set to * match the duplex configuration of the PHY. To do this, configure @@ -1251,19 +1250,30 @@ static void enc_linkstatus(FAR struct enc_driver_s *priv) regval = enc_rdreg(priv, ENC_ESTAT); - if (regval & ESTAT_PHYDPX) + if (regval & ESTAT_PHYLNK) { - /* Configure full-duplex */ + if (regval & ESTAT_PHYDPX) + { + /* Configure full-duplex */ - enc_wrreg(priv, ENC_MABBIPG, 0x15); - enc_bfs(priv, ENC_MACON2, MACON2_FULDPX); + enc_wrreg(priv, ENC_MABBIPG, 0x15); + enc_bfs(priv, ENC_MACON2, MACON2_FULDPX); + } + else + { + /* Configure half-duplex */ + + enc_wrreg(priv, ENC_MABBIPG, 0x12); + enc_bfc(priv, ENC_MACON2, MACON2_FULDPX); + } + + netdev_carrier_on(&priv->dev); + priv->ifstate = ENCSTATE_RUNNING; } else { - /* Configure half-duplex */ - - enc_wrreg(priv, ENC_MABBIPG, 0x12); - enc_bfc(priv, ENC_MACON2, MACON2_FULDPX); + netdev_carrier_off(&priv->dev); + priv->ifstate = ENCSTATE_UP; } } @@ -2175,10 +2185,7 @@ static int enc_ifup(struct uip_driver_s *dev) ret = enc_reset(priv); if (ret == OK) { - enc_setmacaddr(priv); - /* enc_pwrfull(priv); */ - /* Enable interrupts at the ENCX24J600. Interrupts are still disabled * at the interrupt controller. @@ -2302,7 +2309,7 @@ static int enc_txavail(struct uip_driver_s *dev) /* Ignore the notification if the interface is not yet up */ flags = irqsave(); - if (priv->ifstate == ENCSTATE_UP) + if (priv->ifstate == ENCSTATE_RUNNING) { /* Check if the hardware is ready to send another packet. The driver * starts a transmission process by setting ECON1.TXRTS. When the packet is @@ -2735,11 +2742,19 @@ static int enc_reset(FAR struct enc_driver_s *priv) enc_wrreg(priv, ENC_MAMXFL, CONFIG_NET_BUFSIZE + 4); ret = enc_waitreg(priv, ENC_ESTAT, ESTAT_PHYLNK, ESTAT_PHYLNK); + + if (ret == OK) + { + enc_linkstatus(priv); + } + +#if 0 if (ret != OK) { nlldbg("ERROR: encx24j600 failed to establish link\n"); return -ENODEV; } +#endif return OK; } diff --git a/include/net/if.h b/include/net/if.h index 1ff8ebc383..9c1f2a5517 100644 --- a/include/net/if.h +++ b/include/net/if.h @@ -52,9 +52,10 @@ #define IF_NAMESIZE 6 /* Newer naming standard */ #define IFHWADDRLEN 6 -#define IFF_RUNNING (1 << 0) -#define IF_FLAG_IFUP (1 << 0) -#define IF_FLAG_IFDOWN (2 << 0) +#define IFF_DOWN (1 << 0) +#define IFF_UP (1 << 1) +#define IFF_RUNNING (1 << 2) + /******************************************************************************************* * Public Type Definitions diff --git a/include/nuttx/net/uip/uip-arch.h b/include/nuttx/net/uip/uip-arch.h index 7704a7f342..65c86db27c 100644 --- a/include/nuttx/net/uip/uip-arch.h +++ b/include/nuttx/net/uip/uip-arch.h @@ -252,7 +252,7 @@ struct uip_driver_s * } */ -extern int uip_input(struct uip_driver_s *dev); +int uip_input(struct uip_driver_s *dev); /* Polling of connections * @@ -305,8 +305,19 @@ extern int uip_input(struct uip_driver_s *dev); */ typedef int (*uip_poll_callback_t)(struct uip_driver_s *dev); -extern int uip_poll(struct uip_driver_s *dev, uip_poll_callback_t callback); -extern int uip_timer(struct uip_driver_s *dev, uip_poll_callback_t callback, int hsec); +int uip_poll(struct uip_driver_s *dev, uip_poll_callback_t callback); +int uip_timer(struct uip_driver_s *dev, uip_poll_callback_t callback, int hsec); + +/* Carrier detection + * Call netdev_carrier_on when the carrier has become available and the device + * is ready to receive/transmit packets. + * + * Call detdev_carrier_off when the carrier disappeared and the device has moved + * into non operational state. + */ + +int netdev_carrier_on(FAR struct uip_driver_s *dev); +int netdev_carrier_off(FAR struct uip_driver_s *dev); /* By defining UIP_ARCH_CHKSUM, the architecture can replace up_incr32 * with hardware assisted solutions. @@ -321,7 +332,7 @@ extern int uip_timer(struct uip_driver_s *dev, uip_poll_callback_t callback, int * op16 - A 16-bit integer in host byte order. */ -extern void uip_incr32(uint8_t *op32, uint16_t op16); +void uip_incr32(uint8_t *op32, uint16_t op16); /* Calculate the Internet checksum over a buffer. * @@ -342,7 +353,7 @@ extern void uip_incr32(uint8_t *op32, uint16_t op16); * Return: The Internet checksum of the buffer. */ -extern uint16_t uip_chksum(uint16_t *buf, uint16_t len); +uint16_t uip_chksum(uint16_t *buf, uint16_t len); /* Calculate the IP header checksum of the packet header in d_buf. * @@ -353,7 +364,7 @@ extern uint16_t uip_chksum(uint16_t *buf, uint16_t len); * buffer. */ -extern uint16_t uip_ipchksum(struct uip_driver_s *dev); +uint16_t uip_ipchksum(struct uip_driver_s *dev); /* Calculate the TCP checksum of the packet in d_buf and d_appdata. * @@ -368,10 +379,10 @@ extern uint16_t uip_ipchksum(struct uip_driver_s *dev); * to by d_appdata. */ -extern uint16_t uip_tcpchksum(struct uip_driver_s *dev); +uint16_t uip_tcpchksum(struct uip_driver_s *dev); -extern uint16_t uip_udpchksum(struct uip_driver_s *dev); -extern uint16_t uip_icmpchksum(struct uip_driver_s *dev, int len); +uint16_t uip_udpchksum(struct uip_driver_s *dev); +uint16_t uip_icmpchksum(struct uip_driver_s *dev, int len); #endif /* __INCLUDE_NUTTX_NET_UIP_UIP_ARCH_H */ diff --git a/net/Makefile b/net/Makefile index fe2d35624f..7c92bb21a6 100644 --- a/net/Makefile +++ b/net/Makefile @@ -92,7 +92,8 @@ endif NETDEV_ASRCS = NETDEV_CSRCS = netdev_register.c netdev_ioctl.c net_poll.c netdev_txnotify.c \ netdev_findbyname.c netdev_findbyaddr.c netdev_count.c \ - netdev_foreach.c netdev_unregister.c netdev_sem.c + netdev_foreach.c netdev_unregister.c netdev_sem.c \ + netdev_carrier.c ifeq ($(CONFIG_NET_RXAVAIL),y) NETDEV_CSRCS += netdev_rxnotify.c diff --git a/net/netdev_carrier.c b/net/netdev_carrier.c new file mode 100644 index 0000000000..b32c1d6665 --- /dev/null +++ b/net/netdev_carrier.c @@ -0,0 +1,133 @@ +/**************************************************************************** + * net/netdev_carrier.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Max Holtzberg + * + * 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 +#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "net_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: netdev_carrier_on + * + * Description: + * Notifies the uip layer about an available carrier. + * (e.g. a cable was plugged in) + * + * Parameters: + * dev - The device driver structure + * + * Returned Value: + * 0:Success; negated errno on failure + * + ****************************************************************************/ + +int netdev_carrier_on(FAR struct uip_driver_s *dev) +{ + if (dev) + { + dev->d_flags |= IFF_RUNNING; + return OK; + } + + return -EINVAL; +} + +/**************************************************************************** + * Function: netdev_carrier_off + * + * Description: + * Notifies the uip layer about an disappeared carrier. + * (e.g. a cable was unplugged) + * + * Parameters: + * dev - The device driver structure + * + * Returned Value: + * 0:Success; negated errno on failure + * + ****************************************************************************/ + +int netdev_carrier_off(FAR struct uip_driver_s *dev) +{ + if (dev) + { + dev->d_flags &= ~IFF_RUNNING; + return OK; + } + + return -EINVAL; +} + +#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */ diff --git a/net/netdev_ioctl.c b/net/netdev_ioctl.c index ff94ed5c29..a8394edb29 100644 --- a/net/netdev_ioctl.c +++ b/net/netdev_ioctl.c @@ -150,7 +150,7 @@ static void ioctl_ifup(FAR struct uip_driver_s *dev) { /* Is the interface already up? */ - if ((dev->d_flags & IFF_RUNNING) == 0) + if ((dev->d_flags & IFF_UP) == 0) { /* No, bring the interface up now */ @@ -158,7 +158,7 @@ static void ioctl_ifup(FAR struct uip_driver_s *dev) { /* Mark the interface as up */ - dev->d_flags |= IFF_RUNNING; + dev->d_flags |= IFF_UP; } } } @@ -172,7 +172,7 @@ static void ioctl_ifdown(FAR struct uip_driver_s *dev) { /* Is the interface already down? */ - if ((dev->d_flags & IFF_RUNNING) != 0) + if ((dev->d_flags & IFF_UP) != 0) { /* No, take the interface down now */ @@ -180,7 +180,7 @@ static void ioctl_ifdown(FAR struct uip_driver_s *dev) { /* Mark the interface as down */ - dev->d_flags &= ~IFF_RUNNING; + dev->d_flags &= ~IFF_UP; } } } @@ -326,7 +326,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd, dev = netdev_ifrdev(req); if (dev) { - if (req->ifr_flags & IF_FLAG_IFUP) + if (req->ifr_flags & IFF_UP) { /* Yes.. bring the interface up */ @@ -335,7 +335,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd, /* Is this a request to take the interface down? */ - else if (req->ifr_flags & IF_FLAG_IFDOWN) + else if (req->ifr_flags & IFF_DOWN) { /* Yes.. take the interface down */ @@ -352,22 +352,7 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd, dev = netdev_ifrdev(req); if (dev) { - req->ifr_flags = 0; - - /* Is the interface running? */ - - if (dev->d_flags & IFF_RUNNING) - { - /* Yes.. report interface up */ - - req->ifr_flags |= IF_FLAG_IFUP; - } - else - { - /* No.. report interface down */ - - req->ifr_flags |= IF_FLAG_IFDOWN; - } + req->ifr_flags = dev->d_flags; } ret = OK;