From eb5e2e4b208a06985db1fd807384165dc82c7293 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 16 Aug 2014 14:08:04 -0600 Subject: [PATCH] Finishes the ioctl definition to subscribe to PHY events. Revamp network ioctl signature to support arguments other than struct mii_ioctl_data. --- drivers/net/phy_notify.c | 13 +++- include/net/if.h | 135 ++++++++++++++++++++----------------- include/nuttx/net/ioctl.h | 3 +- include/nuttx/net/netdev.h | 26 +++---- include/nuttx/net/phy.h | 3 +- net/netdev/netdev_ioctl.c | 4 +- 6 files changed, 104 insertions(+), 80 deletions(-) diff --git a/drivers/net/phy_notify.c b/drivers/net/phy_notify.c index 3aba800ac49..29b68c3d8fa 100644 --- a/drivers/net/phy_notify.c +++ b/drivers/net/phy_notify.c @@ -39,6 +39,7 @@ #include +#include #include #include #include @@ -311,7 +312,8 @@ static int phy_handler_3(int irq, FAR void *context) * intf - Provides the name of the network interface, for example, "eth0". * The length of intf must not exceed 4 bytes (excluding NULL * terminator). Configurable with CONFIG_PHY_NOTIFICATION_MAXINTFLEN. - * pid - Identifies the task to receive the signal. + * pid - Identifies the task to receive the signal. The special value + * of zero means to use the pid of the current task. * signo - This is the signal number to use when notifying the task. * arg - An argument that will accompany the notification signal. * @@ -335,6 +337,13 @@ int phy_notify_subscribe(FAR const char *intf, pid_t pid, int signo, return -ENOMEM; } + /* The special value pid == 0 means to use the pid of the current task. */ + + if (pid == 0) + { + pid = getpid(); + } + /* Initialize the client entry */ client->signo = signo; @@ -388,7 +397,7 @@ int phy_notify_unsubscribe(FAR const char *intf, pid_t pid) /* Detach and disable the PHY interrupt */ - phy_semtask(); + phy_semtake(); (void)arch_phy_irq(intf, NULL); /* Un-initialize the client entry */ diff --git a/include/net/if.h b/include/net/if.h index bad4a212405..c9ffc0709e1 100644 --- a/include/net/if.h +++ b/include/net/if.h @@ -61,11 +61,22 @@ * Public Type Definitions *******************************************************************************************/ -/* Part of the I/F request used to read from or write to the MII/PHY management - * interface when SIOCxMIIREG ioctl was called. +/* Structure passed with the SIOCMIINOTIFY ioctl command to enable notification of + * of PHY state changes. */ -struct mii_ioctl_data +struct mii_iotcl_notify_s +{ + pid_t pid; /* PID of the task to receive the signal. Zero means "this task" */ + uint8_t signo; /* Signal number to use when signalling */ + FAR void *arg; /* An argument that will accompany the signal callback */ +}; + +/* Structure passed to read from or write to the MII/PHY management interface via the + * SIOCxMIIREG ioctl commands. + */ + +struct mii_ioctl_data_s { uint16_t phy_id; /* PHY device address */ uint16_t reg_num; /* PHY register address */ @@ -79,33 +90,34 @@ struct mii_ioctl_data struct lifreq { - char lifr_name[IFNAMSIZ]; /* Network device name (e.g. "eth0") */ + char lifr_name[IFNAMSIZ]; /* Network device name (e.g. "eth0") */ union { - struct sockaddr_storage lifru_addr; /* IP Address */ - struct sockaddr_storage lifru_dstaddr; /* P-to-P Address */ - struct sockaddr_storage lifru_broadaddr; /* Broadcast address */ - struct sockaddr_storage lifru_netmask; /* Netmask */ - struct sockaddr lifru_hwaddr; /* MAC address */ - int lifru_count; /* Number of devices */ - int lifru_mtu; /* MTU size */ - uint8_t lifru_flags; /* Interface flags */ - struct mii_ioctl_data lifru_mii_data; /* MII request data */ + struct sockaddr_storage lifru_addr; /* IP Address */ + struct sockaddr_storage lifru_dstaddr; /* P-to-P Address */ + struct sockaddr_storage lifru_broadaddr; /* Broadcast address */ + struct sockaddr_storage lifru_netmask; /* Netmask */ + struct sockaddr lifru_hwaddr; /* MAC address */ + int lifru_count; /* Number of devices */ + int lifru_mtu; /* MTU size */ + uint8_t lifru_flags; /* Interface flags */ + struct mii_iotcl_notify_s llfru_mii_notify; /* PHY event notification */ + struct mii_ioctl_data_s lifru_mii_data; /* MII request data */ } lifr_ifru; }; -#define lifr_addr lifr_ifru.lifru_addr /* IP address */ -#define lifr_dstaddr lifr_ifru.lifru_dstaddr /* P-to-P Address */ -#define lifr_broadaddr lifr_ifru.lifru_broadaddr /* Broadcast address */ -#define lifr_netmask lifr_ifru.lifru_netmask /* Interface net mask */ -#define lifr_hwaddr lifr_ifru.lifru_hwaddr /* MAC address */ -#define lifr_mtu lifr_ifru.lifru_mtu /* MTU */ -#define lifr_count lifr_ifru.lifru_count /* Number of devices */ -#define lifr_flags lifr_ifru.lifru_flags /* interface flags */ -#define lifr_mii_phy_id lifr_ifru.lifru_mii_data.phy_id /* PHY device address */ -#define lifr_mii_reg_num lifr_ifru.lifru_mii_data.reg_num /* PHY register address */ -#define lifr_mii_val_in lifr_ifru.lifru_mii_data.val_in /* PHY input data */ -#define lifr_mii_val_out lifr_ifru.lifru_mii_data.val_out /* PHY output data */ +#define lifr_addr lifr_ifru.lifru_addr /* IP address */ +#define lifr_dstaddr lifr_ifru.lifru_dstaddr /* P-to-P Address */ +#define lifr_broadaddr lifr_ifru.lifru_broadaddr /* Broadcast address */ +#define lifr_netmask lifr_ifru.lifru_netmask /* Interface net mask */ +#define lifr_hwaddr lifr_ifru.lifru_hwaddr /* MAC address */ +#define lifr_mtu lifr_ifru.lifru_mtu /* MTU */ +#define lifr_count lifr_ifru.lifru_count /* Number of devices */ +#define lifr_flags lifr_ifru.lifru_flags /* interface flags */ +#define lifr_mii_phy_id lifr_ifru.lifru_mii_data.phy_id /* PHY device address */ +#define lifr_mii_reg_num lifr_ifru.lifru_mii_data.reg_num /* PHY register address */ +#define lifr_mii_val_in lifr_ifru.lifru_mii_data.val_in /* PHY input data */ +#define lifr_mii_val_out lifr_ifru.lifru_mii_data.val_out /* PHY output data */ /* This is the older I/F request that should only be used with IPv4. However, since * NuttX only supports IPv4 or 6 (not both), we can force the older structure to @@ -115,50 +127,51 @@ struct lifreq #ifndef CONFIG_NET_IPv6 struct ifreq { - char ifr_name[IFNAMSIZ]; /* Network device name (e.g. "eth0") */ + char ifr_name[IFNAMSIZ]; /* Network device name (e.g. "eth0") */ union { - struct sockaddr ifru_addr; /* IP Address */ - struct sockaddr ifru_dstaddr; /* P-to-P Address */ - struct sockaddr ifru_broadaddr; /* Broadcast address */ - struct sockaddr ifru_netmask; /* Netmask */ - struct sockaddr ifru_hwaddr; /* MAC address */ - int ifru_count; /* Number of devices */ - int ifru_mtu; /* MTU size */ - uint8_t ifru_flags; /* Interface flags */ - struct mii_ioctl_data ifru_mii_data; /* MII request data */ + struct sockaddr ifru_addr; /* IP Address */ + struct sockaddr ifru_dstaddr; /* P-to-P Address */ + struct sockaddr ifru_broadaddr; /* Broadcast address */ + struct sockaddr ifru_netmask; /* Netmask */ + struct sockaddr ifru_hwaddr; /* MAC address */ + int ifru_count; /* Number of devices */ + int ifru_mtu; /* MTU size */ + uint8_t ifru_flags; /* Interface flags */ + struct mii_iotcl_notify_s llfru_mii_notify; /* PHY event notification */ + struct mii_ioctl_data_s ifru_mii_data; /* MII request data */ } ifr_ifru; }; -#define ifr_addr ifr_ifru.ifru_addr /* IP address */ -#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* P-to-P Address */ -#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* Broadcast address */ -#define ifr_netmask ifr_ifru.ifru_netmask /* Interface net mask */ -#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ -#define ifr_mtu ifr_ifru.ifru_mtu /* MTU */ -#define ifr_count ifr_ifru.ifru_count /* Number of devices */ -#define ifr_flags ifr_ifru.ifru_flags /* interface flags */ -#define ifr_mii_phy_id ifr_ifru.ifru_mii_data.phy_id /* PHY device address */ -#define ifr_mii_reg_num ifr_ifru.ifru_mii_data.reg_num /* PHY register address */ -#define ifr_mii_val_in ifr_ifru.ifru_mii_data.val_in /* PHY input data */ -#define ifr_mii_val_out ifr_ifru.ifru_mii_data.val_out /* PHY output data */ +#define ifr_addr ifr_ifru.ifru_addr /* IP address */ +#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* P-to-P Address */ +#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* Broadcast address */ +#define ifr_netmask ifr_ifru.ifru_netmask /* Interface net mask */ +#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ +#define ifr_mtu ifr_ifru.ifru_mtu /* MTU */ +#define ifr_count ifr_ifru.ifru_count /* Number of devices */ +#define ifr_flags ifr_ifru.ifru_flags /* interface flags */ +#define ifr_mii_phy_id ifr_ifru.ifru_mii_data.phy_id /* PHY device address */ +#define ifr_mii_reg_num ifr_ifru.ifru_mii_data.reg_num /* PHY register address */ +#define ifr_mii_val_in ifr_ifru.ifru_mii_data.val_in /* PHY input data */ +#define ifr_mii_val_out ifr_ifru.ifru_mii_data.val_out /* PHY output data */ #else /* CONFIG_NET_IPv6 */ -#define ifreq lifreq /* Replace ifreq with lifreq */ -#define ifr_name lifr_name /* Network device name */ -#define ifr_addr lifr_ifru.lifru_addr /* IP address */ -#define ifr_dstaddr lifr_ifru.lifru_dstaddr /* P-to-P Address */ -#define ifr_broadaddr lifr_ifru.lifru_broadaddr /* Broadcast address */ -#define ifr_netmask lifr_ifru.lifru_netmask /* Interface net mask */ -#define ifr_hwaddr lifr_ifru.lifru_hwaddr /* MAC address */ -#define ifr_mtu lifr_ifru.lifru_mtu /* MTU */ -#define ifr_count lifr_ifru.lifru_count /* Number of devices */ -#define ifr_flags lifr_ifru.lifru_flags /* interface flags */ -#define ifr_mii_phy_id lifr_ifru.lifru_mii_data.phy_id /* PHY device address */ -#define ifr_mii_reg_num lifr_ifru.lifru_mii_data.reg_num /* PHY register address */ -#define ifr_mii_val_in lifr_ifru.lifru_mii_data.val_in /* PHY input data */ -#define ifr_mii_val_out lifr_ifru.lifru_mii_data.val_out /* PHY output data */ +#define ifreq lifreq /* Replace ifreq with lifreq */ +#define ifr_name lifr_name /* Network device name */ +#define ifr_addr lifr_ifru.lifru_addr /* IP address */ +#define ifr_dstaddr lifr_ifru.lifru_dstaddr /* P-to-P Address */ +#define ifr_broadaddr lifr_ifru.lifru_broadaddr /* Broadcast address */ +#define ifr_netmask lifr_ifru.lifru_netmask /* Interface net mask */ +#define ifr_hwaddr lifr_ifru.lifru_hwaddr /* MAC address */ +#define ifr_mtu lifr_ifru.lifru_mtu /* MTU */ +#define ifr_count lifr_ifru.lifru_count /* Number of devices */ +#define ifr_flags lifr_ifru.lifru_flags /* interface flags */ +#define ifr_mii_phy_id lifr_ifru.lifru_mii_data.phy_id /* PHY device address */ +#define ifr_mii_reg_num lifr_ifru.lifru_mii_data.reg_num /* PHY register address */ +#define ifr_mii_val_in lifr_ifru.lifru_mii_data.val_in /* PHY input data */ +#define ifr_mii_val_out lifr_ifru.lifru_mii_data.val_out /* PHY output data */ #endif /* CONFIG_NET_IPv6 */ diff --git a/include/nuttx/net/ioctl.h b/include/nuttx/net/ioctl.h index 549d571eac4..2bbeb1b917b 100644 --- a/include/nuttx/net/ioctl.h +++ b/include/nuttx/net/ioctl.h @@ -162,7 +162,8 @@ /* MDIO/MCD *****************************************************************/ -#define SIOCMIISIG _SIOC(0x0042) /* Receive signal on PHY interrupt */ +#define SIOCMIINOTIFY _SIOC(0x0042) /* Receive notificaion via signal on + * PHY state change */ #define SIOCGMIIPHY _SIOC(0x0043) /* Get address of MII PHY in use */ #define SIOCGMIIREG _SIOC(0x0044) /* Get a MII register via MDIO */ #define SIOCSMIIREG _SIOC(0x0045) /* Set a MII register via MDIO */ diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h index 6eb06ca5a3f..e71e446e14a 100644 --- a/include/nuttx/net/netdev.h +++ b/include/nuttx/net/netdev.h @@ -179,18 +179,18 @@ struct net_driver_s /* Driver callbacks */ - int (*d_ifup)(struct net_driver_s *dev); - int (*d_ifdown)(struct net_driver_s *dev); - int (*d_txavail)(struct net_driver_s *dev); + int (*d_ifup)(FAR struct net_driver_s *dev); + int (*d_ifdown)(FAR struct net_driver_s *dev); + int (*d_txavail)(FAR struct net_driver_s *dev); #ifdef CONFIG_NET_RXAVAIL - int (*d_rxavail)(struct net_driver_s *dev); + int (*d_rxavail)(FAR struct net_driver_s *dev); #endif #ifdef CONFIG_NET_IGMP - int (*d_addmac)(struct net_driver_s *dev, FAR const uint8_t *mac); - int (*d_rmmac)(struct net_driver_s *dev, FAR const uint8_t *mac); + int (*d_addmac)(FAR struct net_driver_s *dev, FAR const uint8_t *mac); + int (*d_rmmac)(FAR struct net_driver_s *dev, FAR const uint8_t *mac); #endif #ifdef CONFIG_NETDEV_PHY_IOCTL - int (*d_ioctl)(int cmd, struct mii_ioctl_data *req); + int (*d_ioctl)(FAR struct net_driver_s *dev, int cmd, long arg); #endif /* Drivers may attached device-specific, private information */ @@ -198,7 +198,7 @@ struct net_driver_s void *d_private; }; -typedef int (*devif_poll_callback_t)(struct net_driver_s *dev); +typedef int (*devif_poll_callback_t)(FAR struct net_driver_s *dev); /**************************************************************************** * Public Variables @@ -269,7 +269,7 @@ typedef int (*devif_poll_callback_t)(struct net_driver_s *dev); * ****************************************************************************/ -int devif_input(struct net_driver_s *dev); +int devif_input(FAR struct net_driver_s *dev); /**************************************************************************** * Polling of connections @@ -292,7 +292,7 @@ int devif_input(struct net_driver_s *dev); * out the packet. * * Example: - * int driver_callback(struct net_driver_s *dev) + * int driver_callback(FAR struct net_driver_s *dev) * { * if (dev->d_len > 0) * { @@ -310,7 +310,7 @@ int devif_input(struct net_driver_s *dev); * need to call the arp_out() function in the callback function * before sending the packet: * - * int driver_callback(struct net_driver_s *dev) + * int driver_callback(FAR struct net_driver_s *dev) * { * if (dev->d_len > 0) * { @@ -324,8 +324,8 @@ int devif_input(struct net_driver_s *dev); * ****************************************************************************/ -int devif_poll(struct net_driver_s *dev, devif_poll_callback_t callback); -int devif_timer(struct net_driver_s *dev, devif_poll_callback_t callback, int hsec); +int devif_poll(FAR struct net_driver_s *dev, devif_poll_callback_t callback); +int devif_timer(FAR struct net_driver_s *dev, devif_poll_callback_t callback, int hsec); /**************************************************************************** * Carrier detection diff --git a/include/nuttx/net/phy.h b/include/nuttx/net/phy.h index 6e7645af34c..c2bf9e99fde 100644 --- a/include/nuttx/net/phy.h +++ b/include/nuttx/net/phy.h @@ -101,7 +101,8 @@ extern "C" * intf - Provides the name of the network interface, for example, "eth0". * The length of intf must not exceed 4 bytes (excluding NULL * terminator). Configurable with CONFIG_PHY_NOTIFICATION_MAXINTFLEN. - * pid - Identifies the task to receive the signal. + * pid - Identifies the task to receive the signal. The special value + * of zero means to use the pid of the current task. * signo - This is the signal number to use when notifying the task. * arg - An argument that will accompany the notification signal. * diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index 3a6fa4d3e99..ea9f59fa476 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -432,8 +432,8 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd, dev = netdev_ifrdev(req); if (dev && dev->d_ioctl) { - struct mii_ioctl_data *mii_data = &req->ifr_ifru.ifru_mii_data; - ret = dev->d_ioctl(cmd, mii_data); + struct mii_ioctl_data_s *mii_data = &req->ifr_ifru.ifru_mii_data; + ret = dev->d_ioctl(dev, cmd, ((long)(uintptr_t)mii_data); } } break;