Merge remote-tracking branch 'origin/master' into ieee802154

This commit is contained in:
Gregory Nutt 2017-04-19 18:07:33 -06:00
commit 9ff5e83ea7
6 changed files with 240 additions and 37 deletions

View File

@ -86,6 +86,7 @@
#include "cache.h" #include "cache.h"
#include "chip/sam_pinmap.h" #include "chip/sam_pinmap.h"
#include "chip/sam_chipid.h"
#include "sam_gpio.h" #include "sam_gpio.h"
#include "sam_periphclks.h" #include "sam_periphclks.h"
#include "sam_ethernet.h" #include "sam_ethernet.h"
@ -331,7 +332,19 @@
#define EMAC_QUEUE_0 0 #define EMAC_QUEUE_0 0
#define EMAC_QUEUE_1 1 #define EMAC_QUEUE_1 1
#define EMAC_QUEUE_2 2 #define EMAC_QUEUE_2 2
#if defined(CONFIG_ARCH_CHIP_SAMV71)
/* After chip version 1, the SAMV71 increased from 3 to 6 queue */
# define EMAC_QUEUE_3 3
# define EMAC_QUEUE_4 4
# define EMAC_QUEUE_5 5
# define EMAC_NQUEUES (g_emac_nqueues)
# define EMAC_MAX_NQUEUES 6
#else
# define EMAC_NQUEUES 3 # define EMAC_NQUEUES 3
# define EMAC_MAX_NQUEUES 3
#endif
/* Interrupt settings */ /* Interrupt settings */
@ -537,7 +550,7 @@ struct sam_emac_s
/* Transfer queues */ /* Transfer queues */
struct sam_queue_s xfrq[EMAC_NQUEUES]; struct sam_queue_s xfrq[EMAC_MAX_NQUEUES];
/* Debug stuff */ /* Debug stuff */
@ -924,6 +937,16 @@ static uint8_t g_pktbuf1[MAX_NET_DEV_MTU + CONFIG_NET_GUARDSIZE];
/* EMAC1 peripheral state */ /* EMAC1 peripheral state */
static struct sam_emac_s g_emac1; static struct sam_emac_s g_emac1;
#endif /* CONFIG_SAMV7_EMAC1 */
/* The SAMV71 may support from 3 to 6 queue, depending upon the chip
* revision. NOTE that this is a global setting and applies to both
* EMAC peripherals.
*/
#if defined(CONFIG_ARCH_CHIP_SAMV71)
static uint8_t g_emac_nqueues = 3;
#endif #endif
/**************************************************************************** /****************************************************************************
@ -2677,6 +2700,16 @@ static int sam_ifup(struct net_driver_s *dev)
sam_emac_configure(priv); sam_emac_configure(priv);
sam_queue_configure(priv, EMAC_QUEUE_1); sam_queue_configure(priv, EMAC_QUEUE_1);
sam_queue_configure(priv, EMAC_QUEUE_2); sam_queue_configure(priv, EMAC_QUEUE_2);
#if defined(CONFIG_ARCH_CHIP_SAMV71)
if (g_emac_nqueues > 3)
{
sam_queue_configure(priv, EMAC_QUEUE_3);
sam_queue_configure(priv, EMAC_QUEUE_4);
sam_queue_configure(priv, EMAC_QUEUE_5);
}
#endif
sam_queue0_configure(priv); sam_queue0_configure(priv);
/* Set the MAC address (should have been configured while we were down) */ /* Set the MAC address (should have been configured while we were down) */
@ -4540,10 +4573,28 @@ static void sam_emac_reset(struct sam_emac_s *priv)
sam_rxreset(priv, EMAC_QUEUE_1); sam_rxreset(priv, EMAC_QUEUE_1);
sam_rxreset(priv, EMAC_QUEUE_2); sam_rxreset(priv, EMAC_QUEUE_2);
#if defined(CONFIG_ARCH_CHIP_SAMV71)
if (g_emac_nqueues > 3)
{
sam_rxreset(priv, EMAC_QUEUE_3);
sam_rxreset(priv, EMAC_QUEUE_4);
sam_rxreset(priv, EMAC_QUEUE_5);
}
#endif
sam_txreset(priv, EMAC_QUEUE_0); sam_txreset(priv, EMAC_QUEUE_0);
sam_txreset(priv, EMAC_QUEUE_1); sam_txreset(priv, EMAC_QUEUE_1);
sam_txreset(priv, EMAC_QUEUE_2); sam_txreset(priv, EMAC_QUEUE_2);
#if defined(CONFIG_ARCH_CHIP_SAMV71)
if (g_emac_nqueues > 3)
{
sam_txreset(priv, EMAC_QUEUE_3);
sam_txreset(priv, EMAC_QUEUE_4);
sam_txreset(priv, EMAC_QUEUE_5);
}
#endif
/* Disable Rx and Tx, plus the statistics registers. */ /* Disable Rx and Tx, plus the statistics registers. */
regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET);
@ -4561,10 +4612,28 @@ static void sam_emac_reset(struct sam_emac_s *priv)
sam_rxreset(priv, EMAC_QUEUE_1); sam_rxreset(priv, EMAC_QUEUE_1);
sam_rxreset(priv, EMAC_QUEUE_2); sam_rxreset(priv, EMAC_QUEUE_2);
#if defined(CONFIG_ARCH_CHIP_SAMV71)
if (g_emac_nqueues > 3)
{
sam_rxreset(priv, EMAC_QUEUE_3);
sam_rxreset(priv, EMAC_QUEUE_4);
sam_rxreset(priv, EMAC_QUEUE_5);
}
#endif
sam_txreset(priv, EMAC_QUEUE_0); sam_txreset(priv, EMAC_QUEUE_0);
sam_txreset(priv, EMAC_QUEUE_1); sam_txreset(priv, EMAC_QUEUE_1);
sam_txreset(priv, EMAC_QUEUE_2); sam_txreset(priv, EMAC_QUEUE_2);
#if defined(CONFIG_ARCH_CHIP_SAMV71)
if (g_emac_nqueues > 3)
{
sam_txreset(priv, EMAC_QUEUE_3);
sam_txreset(priv, EMAC_QUEUE_4);
sam_txreset(priv, EMAC_QUEUE_5);
}
#endif
/* Make sure that RX and TX are disabled; clear statistics registers */ /* Make sure that RX and TX are disabled; clear statistics registers */
sam_putreg(priv, SAM_EMAC_NCR_OFFSET, EMAC_NCR_CLRSTAT); sam_putreg(priv, SAM_EMAC_NCR_OFFSET, EMAC_NCR_CLRSTAT);
@ -4875,12 +4944,36 @@ int sam_emac_initialize(int intf)
{ {
struct sam_emac_s *priv; struct sam_emac_s *priv;
const struct sam_emacattr_s *attr; const struct sam_emacattr_s *attr;
#if defined(CONFIG_ARCH_CHIP_SAMV71)
uint32_t regval;
#endif
uint8_t *pktbuf; uint8_t *pktbuf;
#if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT) #if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT)
uint8_t phytype; uint8_t phytype;
#endif #endif
int ret; int ret;
#if defined(CONFIG_ARCH_CHIP_SAMV71)
/* Determine if the chip has 3 or 6 queues. This logic is for the
* V71 only -- if you are using a different chip in the family,
* the version number at which to switch from 3 to 6 queues may
* be different. For the V71, versions 1 and higher have 6 queues.
*
* If both emacs are enabled, this code will be run twice, which
* should not be a problem as the result will be the same each time
* it is run.
*/
regval = getreg32(SAM_CHIPID_CIDR);
if ((regval & CHIPID_CIDR_ARCH_MASK) == CHIPID_CIDR_ARCH_SAMV71)
{
if (((regval & CHIPID_CIDR_VERSION_MASK) >> CHIPID_CIDR_VERSION_SHIFT) > 0)
{
g_emac_nqueues = 6;
}
}
#endif
#if defined(CONFIG_SAMV7_EMAC0) #if defined(CONFIG_SAMV7_EMAC0)
if (intf == EMAC0_INTF) if (intf == EMAC0_INTF)
{ {

View File

@ -235,6 +235,12 @@
#define _MTDIOCVALID(c) (_IOC_TYPE(c)==_MTDIOCBASE) #define _MTDIOCVALID(c) (_IOC_TYPE(c)==_MTDIOCBASE)
#define _MTDIOC(nr) _IOC(_MTDIOCBASE,nr) #define _MTDIOC(nr) _IOC(_MTDIOCBASE,nr)
/* Socket IOCTLs ************************************************************/
/* See include/nuttx/net/ioctl.h */
#define _SIOCVALID(c) (_IOC_TYPE(c)==_SIOCBASE)
#define _SIOC(nr) _IOC(_SIOCBASE,nr)
/* NuttX ARP driver ioctl definitions (see netinet/arp.h) *******************/ /* NuttX ARP driver ioctl definitions (see netinet/arp.h) *******************/
#define _ARPIOCVALID(c) (_IOC_TYPE(c)==_ARPIOCBASE) #define _ARPIOCVALID(c) (_IOC_TYPE(c)==_ARPIOCBASE)

View File

@ -51,9 +51,6 @@
* masks, and hardware address, and a few others * masks, and hardware address, and a few others
*/ */
#define _SIOCVALID(c) (_IOC_TYPE(c)==_SIOCBASE)
#define _SIOC(nr) _IOC(_SIOCBASE,nr)
/* IPv4 interface control operations */ /* IPv4 interface control operations */
#define SIOCGIFADDR _SIOC(0x0001) /* Get IP address */ #define SIOCGIFADDR _SIOC(0x0001) /* Get IP address */
@ -128,7 +125,7 @@
* See include/nuttx/net/telnet.h */ * See include/nuttx/net/telnet.h */
/**************************************************************************** /****************************************************************************
* Pulbic Type Definitions * Public Type Definitions
****************************************************************************/ ****************************************************************************/
/* See include/net/if.h, include/net/route.h, and include/net/arp.h */ /* See include/net/if.h, include/net/route.h, and include/net/arp.h */

View File

@ -37,8 +37,8 @@
* (when applicable). * (when applicable).
*/ */
#ifndef __INCLUDE_NUTTX_WIRELESS_H #ifndef __INCLUDE_NUTTX_WIRELESS_WIRELESS_H
#define __INCLUDE_NUTTX_WIRELESS_H #define __INCLUDE_NUTTX_WIRELESS_WIRELESS_H
/************************************************************************************ /************************************************************************************
* Included Files * Included Files
@ -63,6 +63,7 @@
* interface. * interface.
*/ */
/* IEEE802.11 */
/* Wireless identification */ /* Wireless identification */
#define SIOCSIWCOMMIT _WLIOC(0x0001) /* Commit pending changes to driver */ #define SIOCSIWCOMMIT _WLIOC(0x0001) /* Commit pending changes to driver */
@ -153,8 +154,24 @@
#define SIOCSIWPMKSA _WLIOC(0x0032) /* PMKSA cache operation */ #define SIOCSIWPMKSA _WLIOC(0x0032) /* PMKSA cache operation */
#define WL_FIRSTCHAR 0x0033 /* IEEE802.15.4 6loWPAN
#define WL_NNETCMDS 0x0032 *
* IEEE802.15.4 IOCTLs may be directed at one of three layers:
*
* 1. To the 6loWPAN network layer, as documented here,
* 2. To the IEEE802.15.4 MAC layer, as documented in,
* include/nuttx/wireless/ieee802154/ioeee802154_mac.h, or to
* 3. To the IEEE802.15.4 radio device layer, as documented in,
* include/nuttx/wireless/ieee802154/ioeee802154_radio.h.
*
* SIOCSWPANID - Join the specified PAN ID
*/
#define SIOCSWPANID _WLIOC(0x0033) /* Join PAN ID */
#define SIOCGWPANID _WLIOC(0x0034) /* Return PAN ID */
#define WL_FIRSTCHAR 0x0035
#define WL_NNETCMDS 0x0034
/* Character Driver IOCTL commands *************************************************/ /* Character Driver IOCTL commands *************************************************/
/* Non-compatible, NuttX only IOCTL definitions for use with low-level wireless /* Non-compatible, NuttX only IOCTL definitions for use with low-level wireless
@ -162,23 +179,23 @@
* requires a file descriptor created by the open() interface. * requires a file descriptor created by the open() interface.
*/ */
#define WLIOC_SETRADIOFREQ _WLIOC(0x0033) /* arg: Pointer to uint32_t, frequency #define WLIOC_SETRADIOFREQ _WLIOC(0x0035) /* arg: Pointer to uint32_t, frequency
* value (in Mhz) */ * value (in Mhz) */
#define WLIOC_GETRADIOFREQ _WLIOC(0x0034) /* arg: Pointer to uint32_t, frequency #define WLIOC_GETRADIOFREQ _WLIOC(0x0036) /* arg: Pointer to uint32_t, frequency
* value (in Mhz) */ * value (in Mhz) */
#define WLIOC_SETADDR _WLIOC(0x0035) /* arg: Pointer to address value, format #define WLIOC_SETADDR _WLIOC(0x0037) /* arg: Pointer to address value, format
* of the address is driver specific */ * of the address is driver specific */
#define WLIOC_GETADDR _WLIOC(0x0036) /* arg: Pointer to address value, format #define WLIOC_GETADDR _WLIOC(0x0038) /* arg: Pointer to address value, format
* of the address is driver specific */ * of the address is driver specific */
#define WLIOC_SETTXPOWER _WLIOC(0x0037) /* arg: Pointer to int32_t, output power #define WLIOC_SETTXPOWER _WLIOC(0x0039) /* arg: Pointer to int32_t, output power
* (in dBm) */ * (in dBm) */
#define WLIOC_GETTXPOWER _WLIOC(0x0038) /* arg: Pointer to int32_t, output power #define WLIOC_GETTXPOWER _WLIOC(0x003a) /* arg: Pointer to int32_t, output power
* (in dBm) */ * (in dBm) */
/* Device-specific IOCTL commands **************************************************/ /* Device-specific IOCTL commands **************************************************/
#define WL_FIRST 0x0001 /* First common command */ #define WL_FIRST 0x0001 /* First common command */
#define WL_NCMDS 0x0038 /* Number of common commands */ #define WL_NCMDS 0x003a /* Number of common commands */
/* User defined ioctl commands are also supported. These will be forwarded /* User defined ioctl commands are also supported. These will be forwarded
* by the upper-half QE driver to the lower-half QE driver via the ioctl() * by the upper-half QE driver to the lower-half QE driver via the ioctl()
@ -355,5 +372,35 @@ struct iw_event
union iwreq_data u; /* Fixed IOCTL payload */ union iwreq_data u; /* Fixed IOCTL payload */
}; };
/* 6loWPAN */
/* This structure is used with the SIOCSWPANID IOCTL command to select the
* PAN ID to join.
*/
struct sixlowpan_panid_s
{
uint16_t panid; /* The PAN ID to join */
};
/* This union defines the data payload of an 6loWPAN or SIOCGWPANID ioctl
* command and is used in struct sixlowpan_req_s below.
*/
union sixlowpan_data
{
struct sixlowpan_panid_s panid; /* PAN ID to join */
};
/* This is the structure used to exchange data in wireless IOCTLs. This
* structure is the same as 'struct ifreq', but defined for use with
* 6loWPAN IOCTLs.
*/
struct sixlowpan_req_s
{
char ifr_name[IFNAMSIZ]; /* Interface name, e.g. "wpan0" */
union sixlowpan_data u; /* Data payload */
};
#endif /* CONFIG_DRIVERS_WIRELESS */ #endif /* CONFIG_DRIVERS_WIRELESS */
#endif /* __INCLUDE_NUTTX_WIRELESS_H */ #endif /* __INCLUDE_NUTTX_WIRELESS_WIRELESS_H */

View File

@ -61,6 +61,7 @@
#ifdef CONFIG_NET_6LOWPAN #ifdef CONFIG_NET_6LOWPAN
# include <nuttx/net/sixlowpan.h> # include <nuttx/net/sixlowpan.h>
# include <nuttx/wireless/wireless.h>
#endif #endif
#ifdef CONFIG_NET_IGMP #ifdef CONFIG_NET_IGMP
@ -326,32 +327,73 @@ static void ioctl_set_ipv6addr(FAR net_ipv6addr_t outaddr,
#endif #endif
/**************************************************************************** /****************************************************************************
* Name: netdev_wifr_dev * Name: netdev_sixlowpan_ioctl
* *
* Description: * Description:
* Verify the struct iwreq and get the Wireless device. * Perform 6loWPAN network device specific operations.
* *
* Parameters: * Parameters:
* req - The argument of the ioctl cmd * psock Socket structure
* dev Ethernet driver device structure
* cmd The ioctl command
* req The argument of the ioctl cmd
* *
* Return: * Return:
* A pointer to the driver structure on success; NULL on failure. * >=0 on success (positive non-zero values are cmd-specific)
* Negated errno returned on failure.
* *
****************************************************************************/ ****************************************************************************/
#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NETDEV_WIRELESS_IOCTL) #if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NET_6LOWPAN)
static FAR struct net_driver_s *netdev_wifr_dev(FAR struct iwreq *req) static int netdev_sixlowpan_ioctl(FAR struct socket *psock, int cmd,
FAR struct sixlowpan_req_s *req)
{ {
if (req != NULL) FAR struct ieee802154_driver_s *ieee;
{ int ret = -ENOTTY;
/* Find the network device associated with the device name
* in the request data.
*/
return netdev_findbyname(req->ifrn_name); /* Verify that this is a valid wireless network IOCTL command */
if (_WLIOCVALID(cmd) && (unsigned)_IOC_NR(cmd) <= WL_NNETCMDS)
{
switch (cmd)
{
case SIOCSWPANID: /* Join PAN ID */
{
ieee = (FAR struct ieee802154_driver_s *)netdev_findbyname(req->ifr_name);
if (ieee == NULL)
{
ret = -ENODEV;
}
else
{
ieee->i_panid = req->u.panid.panid;
ret = OK;
}
}
break;
case SIOCGWPANID: /* Return PAN ID */
{
ieee = (FAR struct ieee802154_driver_s *)netdev_findbyname(req->ifr_name);
if (ieee == NULL)
{
ret = -ENODEV;
}
else
{
req->u.panid.panid = ieee->i_panid;
ret = OK;
}
}
break;
default:
return -ENOTTY;
}
} }
return NULL; return ret;
} }
#endif #endif
@ -462,8 +504,8 @@ static int netdev_wifr_ioctl(FAR struct socket *psock, int cmd,
{ {
/* Get the wireless device associated with the IOCTL command */ /* Get the wireless device associated with the IOCTL command */
dev = netdev_wifr_dev(req); dev = netdev_findbyname(req->ifrn_name);
if (dev) if (dev != NULL)
{ {
/* Just forward the IOCTL to the wireless driver */ /* Just forward the IOCTL to the wireless driver */
@ -1290,7 +1332,11 @@ int psock_ioctl(FAR struct socket *psock, int cmd, unsigned long arg)
* non-NULL. * non-NULL.
*/ */
#ifdef CONFIG_DRIVERS_WIRELESS
if (!_SIOCVALID(cmd) && !_WLIOCVALID(cmd))
#else
if (!_SIOCVALID(cmd)) if (!_SIOCVALID(cmd))
#endif
{ {
ret = -ENOTTY; ret = -ENOTTY;
goto errout; goto errout;
@ -1308,13 +1354,27 @@ int psock_ioctl(FAR struct socket *psock, int cmd, unsigned long arg)
ret = netdev_ifr_ioctl(psock, cmd, (FAR struct ifreq *)((uintptr_t)arg)); ret = netdev_ifr_ioctl(psock, cmd, (FAR struct ifreq *)((uintptr_t)arg));
#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NET_6LOWPAN)
/* Check for a 6loWPAN network command */
if (ret == -ENOTTY)
{
FAR struct sixlowpan_req_s *slpreq;
slpreq = (FAR struct sixlowpan_req_s *)((uintptr_t)arg);
ret = netdev_sixlowpan_ioctl(psock, cmd, slpreq);
}
#endif
#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NETDEV_WIRELESS_IOCTL) #if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NETDEV_WIRELESS_IOCTL)
/* Check for a wireless network command */ /* Check for a wireless network command */
if (ret == -ENOTTY) if (ret == -ENOTTY)
{ {
ret = netdev_wifr_ioctl(psock, cmd, FAR struct iwreq *wifrreq;
(FAR struct iwreq *)((uintptr_t)arg));
wifrreq = (FAR struct sixlowpan_req_s *)((uintptr_t)arg);
ret = netdev_wifr_ioctl(psock, cmd, wifrreq);
} }
#endif #endif

View File

@ -47,7 +47,7 @@ The length of the fragment header length is four bytes for the first header
(FRAG1) and five bytes for all subsequent headers (FRAGN). For example, (FRAG1) and five bytes for all subsequent headers (FRAGN). For example,
this is a HC1 compressed first frame of a packet this is a HC1 compressed first frame of a packet
41 88 01 0000 3412 cdab ### 9-byte MAC header 41 88 01 cefa 3412 cdab ### 9-byte MAC header
c50e 000b ### 4-byte FRAG1 header c50e 000b ### 4-byte FRAG1 header
42 ### SIXLOWPAN_DISPATCH_HC1 42 ### SIXLOWPAN_DISPATCH_HC1
fb ### RIME_HC1_HC_UDP_HC1_ENCODING fb ### RIME_HC1_HC_UDP_HC1_ENCODING
@ -64,7 +64,7 @@ this is a HC1 compressed first frame of a packet
This is the second frame of the same transfer: This is the second frame of the same transfer:
41 88 01 0000 3412 cdab ### 9-byte MAC header 41 88 01 cefa 3412 cdab ### 9-byte MAC header
e50e 000b 0a ### 5 byte FRAGN header e50e 000b 0a ### 5 byte FRAGN header
42 ### SIXLOWPAN_DISPATCH_HC1 42 ### SIXLOWPAN_DISPATCH_HC1
fb ### RIME_HC1_HC_UDP_HC1_ENCODING fb ### RIME_HC1_HC_UDP_HC1_ENCODING