diff --git a/arch/arm/src/lpc54xx/Kconfig b/arch/arm/src/lpc54xx/Kconfig index d06b01ba2b9..59ec6865122 100644 --- a/arch/arm/src/lpc54xx/Kconfig +++ b/arch/arm/src/lpc54xx/Kconfig @@ -688,7 +688,70 @@ config LPC54_ETH_MULTIQUEUE default n depends on EXPERIMENTAL ---help--- - Support not yet implemented. + Enables software drivers for the special hardware support for + IEEE 802.1q VLAN Audio/Visual Bridge Types (AVBTP). In this + configuration two queues are available: One for normal traffic + and one dedicated to the AVBTP traffic. + +if LPC54_ETH_MULTIQUEUE + +config LPC54_ETH_BURSTLEN + bool "DMA Tx burst length" + default n + range 1 256 + ---help--- + Transmit programmable burst length. These bits indicate the maximum + number of beats to be transferred in one DMA data transfer. This is + the maximum value that is used in a single block read or write. The + DMA always attempts to burst as specified in PBL each time it starts + a burst transfer on the application bus. You can program PBL with + any of the following values: 1, 2, 4, 8, 16, 32, 64, 128, or 256. + Any other value results in undefined behavior. + +config LPC54_ETH_TXRR + bool "Tx round robin" + default y + ---help--- + Selects round-robin Tx scheduling. The alternative is strict + priority scheduling. + +config LPC54_ETH_RXRR + bool "Rx round robin" + default y + ---help--- + Selects round-robin Rx scheduling. The alternative is strict + priority scheduling. + +config LPC54_ETH_DYNAMICMAP + bool "Dynamic Rx queue mapping" + default n + ---help--- + If selected, the received frame in in Rx Qn, n=0..1, maps to the DMA + channel m, m=0..1 related with the same MAC. Otherwise, static + mapping is used: The received fame in Rx Qn, n=0..1 maps directly + to DMA channel n. + +config LPC54_ETH_RXQ0WEIGHT + int "Rx queue 0 weight" + default 0 + range 0 7 + +config LPC54_ETH_RXQ1WEIGHT + int "Rx queue 1 weight" + default 0 + range 0 7 + +config LPC54_ETH_TXQ0WEIGHT + int "Tx queue 0 weight" + default 0 + range 0 2097151 + +config LPC54_ETH_TXQ1WEIGHT + int "Tx queue 1 weight" + default 0 + range 0 2097151 + +endif # LPC54_ETH_MULTIQUEUE config LPC54_ETH_TX_STRFWD bool "Tx store and forward" @@ -728,6 +791,12 @@ config LPC54_ETH_RX_ALLMULTICAST address (first bit in the destination address field is '1') are accepted. + This feature will will be selected automatically if ICMPv6 or + IGMP are enabled. Unlike other Ethernet hardware, the LPC54xx + does not seem to support explicit Multicast address filtering + as needed for ICMPv6 and for IGMP. In these cases, I am simpl + accepting all multicast packets. + config LPC54_ETH_FLOWCONTROL bool "Enable flow control" default n diff --git a/arch/arm/src/lpc54xx/chip/lpc54_ethernet.h b/arch/arm/src/lpc54xx/chip/lpc54_ethernet.h index 75bdc0aaa2d..d31adaa4640 100644 --- a/arch/arm/src/lpc54xx/chip/lpc54_ethernet.h +++ b/arch/arm/src/lpc54xx/chip/lpc54_ethernet.h @@ -106,7 +106,7 @@ #define LPC54_ETH_MTL_TXQ_DBG_OFFSET 0x0008 /* MTL TxQn debug */ #define LPC54_ETH_MTL_TXQ_ETS_CTRL_OFFSET 0x0010 /* MTL TxQ1 (only) ETS control */ #define LPC54_ETH_MTL_TXQ_ETS_STAT_OFFSET 0x0014 /* MTL TxQn ETS status */ -#define LPC54_ETH_MTL_TXQ_QNTM_WGHT_OFFSET 0x0018 /* MTL TxQn quantum or weights */ +#define LPC54_ETH_MTL_TXQ_QNTM_WGHT_OFFSET 0x0018 /* MTL TxQn idleSlopeCredit, quantum or weights */ #define LPC54_ETH_MTL_TXQ_SNDSLP_CRDT_OFFSET 0x001c /* MTL TxQ1 (only) SendSlopCredit */ #define LPC54_ETH_MTL_TXQ_HI_CRDT_OFFSET 0x0020 /* MTL TxQ1 (only) hiCredit */ #define LPC54_ETH_MTL_TXQ_LO_CRDT_OFFSET 0x0024 /* MTL TxQ1 (only) loCredit */ @@ -448,11 +448,25 @@ #define ETH_MAC_TIMESTAMP_EGRESS_CORR_NSEC_ /* MTL operation mode */ -#define ETH_MTL_OP_MODE_ + +#define ETH_MTL_OP_MODE_DTXSTS (1 << 1) /* Bit 1: Drop transmit status */ +#define ETH_MTL_OP_MODE_RAA (1 << 1) /* Bit 2: Receive arbitration algorithm */ +# define ETH_MTL_OP_MODE_RAA_SP (0) /* Strict priority */ +# define ETH_MTL_OP_MODE_RAA_WSP (1 << 1) /* Weighted Strict Priority */ +#define ETH_MTL_OP_MODE_SHALG_SHIFT (5) /* Bits 5-6: Tx Scheduling Algorithm */ +#define ETH_MTL_OP_MODE_SHALG_MASK (3 << ETH_MTL_OP_MODE_SHALG_SHIFT) +# define ETH_MTL_OP_MODE_SHALG_SP (0 << ETH_MTL_OP_MODE_SHALG_SHIFT) /* Strict priority */ +# define ETH_MTL_OP_MODE_SHALG_WSP (3 << ETH_MTL_OP_MODE_SHALG_SHIFT) /* Weighted Strict */ + /* MTL interrupt status */ #define ETH_MTL_INTR_STAT_ + /* MTL Rx Queue and DMA channel mapping */ -#define ETH_MTL_RXQ_DMA_MAP_ + +#define ETH_MTL_RXQ_DMA_MAP_Q0MDMACH (1 << 0) /* Bit 0: Queue 0 mapped to DMA channel 1 */ +#define ETH_MTL_RXQ_DMA_MAP_Q0DDMACH (1 << 4) /* Bit 4: Queue 0 enabled for DA-based DMA channel selection */ +#define ETH_MTL_RXQ_DMA_MAP_Q1MDMACH (1 << 8) /* Bit 8: Queue 1 mapped to DMA channel 1 */ +#define ETH_MTL_RXQ_DMA_MAP_Q1DDMACH (1 << 12) /* Bit 12: Queue 1 enabled for DA-based DMA channel selection */ /* MTL TxQn operation mode */ @@ -484,8 +498,11 @@ #define ETH_MTL_TXQ1_ETS_CTRL_ /* MTL TxQn ETS status */ #define ETH_MTL_TXQ_ETS_STAT_ -/* Queue 0 quantum or weights */ -#define ETH_MTL_TXQ_QNTM_WGHT_ + +/* MTL TxQn idleSlopeCredit,quantum or weights */ + +#define ETH_MTL_TXQ_QNTM_WGHT_MASK 0x001fffff /* Bits 0-20: IdleSlopeCredit, quantum or weights */ + /* MTL TxQ1 (only) SendSlopCredit */ #define ETH_MTL_TXQ1_SNDSLP_CRDT_ /* MTL TxQ1 (only) hiCredit */ @@ -508,15 +525,20 @@ #define ETH_MTL_RXQ_OP_MODE_RSF (1 << 5) /* Bit 5 Rx Queue store and forward */ #define ETH_MTL_RXQ_OP_MODE_DIS_TCP_EF (1 << 6) /* Bit 6 Disable dropping of TCP/IP checksum error packets */ #define ETH_MTL_RXQ_OP_MODE_RQS_SHIFT (20) /* Bits 20-22: Rx Queue size (x256) */ -#define ETH_MTL_RXQ_OP_MODE_RQS_MASK (7 << ETH_MTL_RXQ_OP_MODE_RQS_SHIFT) +#define ETH_MTL_RXQ_OP_MODE_RQS_MASK (7 << ETH_MTL_RXQ_OP_MODE_RQS_SHIFT) # define ETH_MTL_RXQ_OP_MODE_RQS(n) ((uint32_t)((n)-1) << ETH_MTL_RXQ_OP_MODE_RQS_SHIFT) /* MTL RxQn missed packet overflow counter */ #define ETH_MTL_RXQ_MISSPKT_OVRFLW_CNT_ /* MTL RxQn debug */ #define ETH_MTL_RXQ_DBG_ + /* MTL RxQn control */ -#define ETH_MTL_RXQ_CTRL_ + +#define ETH_MTL_RXQ_CTRL_WEGT_SHIFT (0) /* Bits 0-2: Rx Queue weight */ +#define ETH_MTL_RXQ_CTRL_WEGT_MASK (7 << ETH_MTL_RXQ_CTRL_WEGT) +# define ETH_MTL_RXQ_CTRL_WEGT(n) ((uint32_t)(n) << ETH_MTL_RXQ_CTRL_WEGT) +#define ETH_MTL_RXQ_CTRL_FRM_ARBIT (1 << 3) /* Bit 3: Rx Queue packet arbitration */ /* DMA mode */ diff --git a/arch/arm/src/lpc54xx/lpc54_ethernet.c b/arch/arm/src/lpc54xx/lpc54_ethernet.c index db3bbc41cf1..05b24b0c4db 100644 --- a/arch/arm/src/lpc54xx/lpc54_ethernet.c +++ b/arch/arm/src/lpc54xx/lpc54_ethernet.c @@ -50,6 +50,12 @@ * The second queue is intended to support QVLAN, AVB type packets. That * is awkward in the current design because we select the queue first, * then poll for the data to send. + * + * 3. Multicast address filtering. Unlike other hardware, this Ethernet + * does not seem to support explicit Multicast address filtering as + * needed for ICMPv6 and for IGMP. In these cases, I am simply accepting + * all multicast packets. I am not sure if that is the right thing to + * do. */ /**************************************************************************** @@ -105,6 +111,18 @@ # error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE) #endif +/* Multicast address filtering. Unlike other hardware, this Ethernet does + * not seem to support explicit Multicast address filtering as needed for + * ICMPv6 and for IGMP. In these cases, I am simply accepting all multicast + * packets. + */ + +#undef LPC54_ACCEPT_ALLMULTICAST +#if defined(CONFIG_LPC54_ETH_RX_ALLMULTICAST) || \ + defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +# define LPC54_ACCEPT_ALLMULTICAST 1 +#endif + /* The low priority work queue is preferred. If it is not enabled, LPWORK * will be the same as HPWORK. */ @@ -131,9 +149,21 @@ /* MTL-related definitions */ -#define LPC54_MTL_QUEUE_UNIT 256 -#define LPC54_MTL_RXQUEUE_UNITS 8 /* Rx queue size = 2048 bytes */ -#define LPC54_MTL_TXQUEUE_UNITS 8 /* Tx queue size = 2048 bytes */ +#define LPC54_MTL_QUEUE_UNIT 256 +#define LPC54_MTL_RXQUEUE_UNITS 8 /* Rx queue size = 2048 bytes */ +#define LPC54_MTL_TXQUEUE_UNITS 8 /* Tx queue size = 2048 bytes */ + +#ifdef CONFIG_LPC54_ETH_TXRR +# define LPC54_MTL_OPMODE_SCHALG ETH_MTL_OP_MODE_SHALG_WSP +#else +# define LPC54_MTL_OPMODE_SCHALG ETH_MTL_OP_MODE_SHALG_SP +#endif + +#ifdef CONFIG_LPC54_ETH_RXRR +# define LPC54_MTL_OPMODE_RAA ETH_MTL_OP_MODE_RAA_WSP +#else +# define LPC54_MTL_OPMODE_RAA ETH_MTL_OP_MODE_RAA_SP +#endif /* MAC-related definitinons */ @@ -156,7 +186,7 @@ #define LPC54_BUFFER_WORDS ((MAX_NET_DEV_MTU + CONFIG_NET_GUARDSIZE + 3) >> 2) #define LPC54_BUFFER_MAX 16384 -/* DMA descriptor definitions */ +/* DMA and DMA descriptor definitions */ #define LPC54_MIN_RINGLEN 4 /* Min length of a ring */ #define LPC54_MAX_RINGLEN 1023 /* Max length of a ring */ @@ -167,6 +197,46 @@ # define LPC54_NRINGS 1 /* Use 1 Rx and 1 Tx ring */ #endif +#ifndef CONFIG_LPC54_ETH_BURSTLEN +# define CONFIG_LPC54_ETH_BURSTLEN 1 +#endif + +#if CONFIG_LPC54_ETH_BURSTLEN < 2 +# define LPC54_BURSTLEN 1 +# define LPC54_PBLx8 0 +#elif CONFIG_LPC54_ETH_BURSTLEN < 4 +# define LPC54_BURSTLEN 2 +# define LPC54_PBLx8 0 +#elif CONFIG_LPC54_ETH_BURSTLEN < 8 +# define LPC54_BURSTLEN 4 +# define LPC54_PBLx8 0 +#elif CONFIG_LPC54_ETH_BURSTLEN < 16 +# define LPC54_BURSTLEN 8 +# define LPC54_PBLx8 0 +#elif CONFIG_LPC54_ETH_BURSTLEN < 32 +# define LPC54_BURSTLEN 16 +# define LPC54_PBLx8 0 +#elif CONFIG_LPC54_ETH_BURSTLEN < 64 +# define LPC54_BURSTLEN 32 +# define LPC54_PBLx8 0 +#elif CONFIG_LPC54_ETH_BURSTLEN < 128 +# define LPC54_BURSTLEN 8 +# define LPC54_PBLx8 ETH_DMACH_CTRL_PBLx8 +#elif CONFIG_LPC54_ETH_BURSTLEN < 256 +# define LPC54_BURSTLEN 16 +# define LPC54_PBLx8 ETH_DMACH_CTRL_PBLx8 +#else +# define LPC54_BURSTLEN 32 +# define LPC54_PBLx8 ETH_DMACH_CTRL_PBLx8 +#endif + +#ifdef CONFIG_LPC54_ETH_DYNAMICMAP +# define LPC54_QUEUEMAP (ETH_MTL_RXQ_DMA_MAP_Q0DDMACH | \ + ETH_MTL_RXQ_DMA_MAP_Q1DDMACH) +#else +# define LPC54_QUEUEMAP ETH_MTL_RXQ_DMA_MAP_Q1MDMACH +#endif + /* Interrupt masks */ #define LPC54_ABNORM_INTMASK (ETH_DMACH_INT_TS | ETH_DMACH_INT_RBU | \ @@ -184,7 +254,8 @@ * header. */ -#define BUF ((struct eth_hdr_s *)priv->eth_dev.d_buf) +#define ETHBUF ((struct eth_hdr_s *)priv->eth_dev.d_buf) +#define ETH8021QWBUF ((struct eth_8021qhdr_s *)priv->eth_dev.d_buf) /**************************************************************************** * Private Types @@ -311,6 +382,9 @@ static int lpc54_eth_txpoll(struct net_driver_s *dev); static void lpc54_eth_rxdisptch(struct lpc54_ethdriver_s *priv); static void lpc54_eth_receive(struct lpc54_ethdriver_s *priv, unsigned int chan); +#if 0 /* Not used yet */ +static unsigned int lpc54_eth_getring(struct lpc54_ethdriver_s *priv); +#endif static void lpc54_eth_txdone(struct lpc54_ethdriver_s *priv, unsigned int chan); @@ -344,17 +418,12 @@ static int lpc54_eth_ifdown(struct net_driver_s *dev); static void lpc54_eth_txavail_work(void *arg); static int lpc54_eth_txavail(struct net_driver_s *dev); -#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +#ifdef CONFIG_NET_IGMP static int lpc54_eth_addmac(struct net_driver_s *dev, const uint8_t *mac); -#ifdef CONFIG_NET_IGMP static int lpc54_eth_rmmac(struct net_driver_s *dev, const uint8_t *mac); #endif -#ifdef CONFIG_NET_ICMPv6 -static void lpc54_eth_ipv6multicast(struct lpc54_ethdriver_s *priv); -#endif -#endif #ifdef CONFIG_NETDEV_IOCTL static int lpc54_eth_ioctl(struct net_driver_s *dev, int cmd, unsigned long arg); @@ -647,7 +716,7 @@ static void lpc54_eth_rxdisptch(struct lpc54_ethdriver_s *priv) /* We only accept IP packets of the configured type and ARP packets */ #ifdef CONFIG_NET_IPv4 - if (BUF->type == HTONS(ETHTYPE_IP)) + if (ETHBUF->type == HTONS(ETHTYPE_IP)) { ninfo("IPv4 packet\n"); NETDEV_RXIPV4(&priv->eth_dev); @@ -688,7 +757,7 @@ static void lpc54_eth_rxdisptch(struct lpc54_ethdriver_s *priv) else #endif #ifdef CONFIG_NET_IPv6 - if (BUF->type == HTONS(ETHTYPE_IP6)) + if (ETHBUF->type == HTONS(ETHTYPE_IP6)) { ninfo("Iv6 packet\n"); NETDEV_RXIPV6(&priv->eth_dev); @@ -726,7 +795,7 @@ static void lpc54_eth_rxdisptch(struct lpc54_ethdriver_s *priv) else #endif #ifdef CONFIG_NET_ARP - if (BUF->type == htons(ETHTYPE_ARP)) + if (ETHBUF->type == htons(ETHTYPE_ARP)) { arp_arpin(&priv->eth_dev); NETDEV_RXARP(&priv->eth_dev); @@ -920,6 +989,50 @@ static void lpc54_eth_receive(struct lpc54_ethdriver_s *priv, } } +/**************************************************************************** + * Name: lpc54_eth_getring + * + * Description: + * An output message is ready to send, but which queue should we send it + * on? The rule is this: + * + * "Normal" packets (or CONFIG_LPC54_ETH_MULTIQUEUE not selected): + * Always send on ring 0 + * 8021QVLAN AVB packets (and CONFIG_LPC54_ETH_MULTIQUEUE not selected): + * Always send on ring 1 + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * The ring to use when sending the packet. + * + * Assumptions: + * The network is locked. + * + ****************************************************************************/ + +#if 0 /* Not used yet */ +static unsigned int lpc54_eth_getring(struct lpc54_ethdriver_s *priv) +{ + unsigned int ring = 0; + +#ifdef CONFIG_LPC54_ETH_MULTIQUEUE + /* Choose the ring ID for different types of frames. For 802.1q VLAN AVB + * frames, uses ring 1. Everything else goes on ring 0. + */ + + if (ETH8021QWBUF->tpid == HTONS(TPID_8021QVLAN) && + ETH8021QWBUF->type == HTONS(ETHTYPE_AVBTP)) + { + ring = 1; + } +#endif + + return ring +} +#endif + /**************************************************************************** * Name: lpc54_eth_txdone * @@ -1534,7 +1647,6 @@ static int lpc54_eth_ifup(struct net_driver_s *dev) uint8_t *mptr; uintptr_t base; uint32_t regval; - uint32_t burstlen; int ret; int i; @@ -1577,39 +1689,36 @@ static int lpc54_eth_ifup(struct net_driver_s *dev) for (i = 0; i < LPC54_NRINGS; i++) { base = LPC54_ETH_DMACH_CTRL_BASE(i); - -#ifdef CONFIG_LPC54_ETH_MULTIQUEUE - /* REVISIT: burstlen setting for the case of multi-queuing. */ -# warning Missing logic -#else - /* REVISIT: Additional logic needed if burstlen > 32 */ - - burstlen = 1; /* DMA burst length = 1 */ -#endif - - /* REVISIT: We would need to set ETH_DMACH_CTRL_PBLx8 in LPC54_ETH_DMACH_CTRL - * is required for the burst length setting. - */ - - putreg32(0, base + LPC54_ETH_DMACH_CTRL_OFFSET); + putreg32(LPC54_PBLx8, base + LPC54_ETH_DMACH_CTRL_OFFSET); regval = getreg32(base + LPC54_ETH_DMACH_TX_CTRL_OFFSET); regval &= ~ETH_DMACH_TX_CTRL_TxPBL_MASK; - regval |= ETH_DMACH_TX_CTRL_TxPBL(burstlen); + regval |= ETH_DMACH_TX_CTRL_TxPBL(LPC54_BURSTLEN); putreg32(regval, base + LPC54_ETH_DMACH_TX_CTRL_OFFSET); regval = getreg32(base + LPC54_ETH_DMACH_RX_CTRL_OFFSET); regval &= ~ETH_DMACH_RX_CTRL_RxPBL_MASK; - regval |= ETH_DMACH_RX_CTRL_RxPBL(burstlen); + regval |= ETH_DMACH_RX_CTRL_RxPBL(LPC54_BURSTLEN); putreg32(regval, base + LPC54_ETH_DMACH_RX_CTRL_OFFSET); } /* Initializes the Ethernet MTL *******************************************/ - /* Set transmit operation mode +#ifdef CONFIG_LPC54_ETH_MULTIQUEUE + /* Set the schedule/arbitration for multiple queues */ + + putreg32(LPC54_MTL_OPMODE_SCHALG | LPC54_MTL_OPMODE_RAA, + LPC54_ETH_MTL_OP_MODE); + + /* Set the Rx queue mapping to DMA channel. */ + + putreg32(LPC54_QUEUEMAP, LPC54_ETH_MTL_RXQ_DMA_MAP); +#endif + + /* Set transmit queue operation mode * * FTQ - Set to flush the queue * TSF - Depends on configuration - * TXQEN - Queue 0 disabled; queue 1 enabled + * TXQEN - Queue 0 enabled; queue 1 may be disabled * TTC - Set to 32 bytes (ignored if TSF set) * TQS - Set to 2048 bytes */ @@ -1622,12 +1731,17 @@ static int lpc54_eth_ifup(struct net_driver_s *dev) regval |= ETH_MTL_TXQ_OP_MODE_FTQ | ETH_MTL_TXQ_OP_MODE_TTC_32 | ETH_MTL_TXQ_OP_MODE_TQS(LPC54_MTL_TXQUEUE_UNITS); - putreg32(regval | ETH_MTL_TXQ_OP_MODE_TXQEN_DISABLE, + putreg32(regval | ETH_MTL_TXQ_OP_MODE_TXQEN_ENABLE, LPC54_ETH_MTL_TXQ_OP_MODE(0)); +#ifdef CONFIG_LPC54_ETH_MULTIQUEUE putreg32(regval | ETH_MTL_TXQ_OP_MODE_TXQEN_ENABLE, LPC54_ETH_MTL_TXQ_OP_MODE(1)); +#else + putreg32(regval | ETH_MTL_TXQ_OP_MODE_TXQEN_DISABLE, + LPC54_ETH_MTL_TXQ_OP_MODE(1)); +#endif - /* Set receive operation mode (queue 0 only) + /* Set receive receive operation mode * * RTC - Set to 64 bytes (ignored if RSF selected) * FUP - enabled @@ -1646,13 +1760,16 @@ static int lpc54_eth_ifup(struct net_driver_s *dev) regval |= ETH_MTL_RXQ_OP_MODE_RTC_64 | ETH_MTL_RXQ_OP_MODE_FUP | ETH_MTL_RXQ_OP_MODE_RQS(LPC54_MTL_RXQUEUE_UNITS); putreg32(regval, LPC54_ETH_MTL_RXQ_OP_MODE(0)); - #ifdef CONFIG_LPC54_ETH_MULTIQUEUE - /* Set the schedule/arbitration(set for multiple queues) */ - /* Set the rx queue mapping to dma channel */ - /* Set the tx/rx queue weight. */ - /* REVISIT: Missing multi-queue configuration here. */ -# warning Missing Logic + putreg32(regval, LPC54_ETH_MTL_RXQ_OP_MODE(1)); + + /* Set the Tx/Rx queue weights. */ + + putreg32(CONFIG_LPC54_ETH_TXQ0WEIGHT, LPC54_ETH_MTL_TXQ_QNTM_WGHT(0)); + putreg32(CONFIG_LPC54_ETH_TXQ1WEIGHT, LPC54_ETH_MTL_TXQ_QNTM_WGHT(1)); + + putreg32(CONFIG_LPC54_ETH_RXQ0WEIGHT, LPC54_ETH_MTL_RXQ_CTRL(0)); + putreg32(CONFIG_LPC54_ETH_RXQ1WEIGHT, LPC54_ETH_MTL_RXQ_CTRL(1)); #endif /* Initialize the Ethernet MAC ********************************************/ @@ -1677,7 +1794,7 @@ static int lpc54_eth_ifup(struct net_driver_s *dev) #ifndef CONFIG_LPC54_ETH_RX_BROADCAST regval |= ETH_MAC_FRAME_FILTER_DBF; #endif -#ifdef CONFIG_LPC54_ETH_RX_ALLMULTICAST +#ifdef LPC54_ACCEPT_ALLMULTICAST regval |= ETH_MAC_FRAME_FILTER_PM; #endif putreg32(regval, LPC54_ETH_MAC_FRAME_FILTER); @@ -1743,12 +1860,6 @@ static int lpc54_eth_ifup(struct net_driver_s *dev) putreg32(0, LPC54_ETH_MAC_INTR_EN); -#ifdef CONFIG_NET_ICMPv6 - /* Set up IPv6 multicast address filtering */ - - lpc54_eth_ipv6multicast(priv); -#endif - /* Initialize packet buffers */ lpc54_pktbuf_initialize(priv); @@ -1960,13 +2071,13 @@ static int lpc54_eth_txavail(struct net_driver_s *dev) * ****************************************************************************/ -#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +#ifdef CONFIG_NET_IGMP static int lpc54_eth_addmac(struct net_driver_s *dev, const uint8_t *mac) { - struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)dev->d_private; - - /* Add the MAC address to the hardware multicast routing table */ -#warning Missing logic + /* Unlike other Ethernet hardware, the LPC54xx does not seem to support + * explicit Multicast address filtering as needed for ICMPv6 and for IGMP. + * In these cases, I am simply accepting all multicast packets. + */ return OK; } @@ -1991,87 +2102,15 @@ static int lpc54_eth_addmac(struct net_driver_s *dev, const uint8_t *mac) #ifdef CONFIG_NET_IGMP static int lpc54_eth_rmmac(struct net_driver_s *dev, const uint8_t *mac) { - struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)dev->d_private; + /* Unlike other Ethernet hardware, the LPC54xx does not seem to support + * explicit Multicast address filtering as needed for ICMPv6 and for IGMP. + * In these cases, I am simply accepting all multicast packets. + */ - /* Add the MAC address to the hardware multicast routing table */ -#warning Missing logic - - return OK; + return -ENOSYS; } #endif -/**************************************************************************** - * Name: lpc54_eth_ipv6multicast - * - * Description: - * Configure the IPv6 multicast MAC address. - * - * Parameters: - * priv - A reference to the private driver state structure - * - * Returned Value: - * Zero (OK) on success; a negated errno value on failure. - * - ****************************************************************************/ - -#ifdef CONFIG_NET_ICMPv6 -static void lpc54_eth_ipv6multicast(struct lpc54_ethdriver_s *priv) -{ - struct net_driver_s *dev; - uint16_t tmp16; - uint8_t mac[6]; - - /* For ICMPv6, we need to add the IPv6 multicast address - * - * For IPv6 multicast addresses, the Ethernet MAC is derived by - * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, - * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map - * to the Ethernet MAC address 33:33:00:01:00:03. - * - * NOTES: This appears correct for the ICMPv6 Router Solicitation - * Message, but the ICMPv6 Neighbor Solicitation message seems to - * use 33:33:ff:01:00:03. - */ - - mac[0] = 0x33; - mac[1] = 0x33; - - dev = &priv->eth_dev; - tmp16 = dev->d_ipv6addr[6]; - mac[2] = 0xff; - mac[3] = tmp16 >> 8; - - tmp16 = dev->d_ipv6addr[7]; - mac[4] = tmp16 & 0xff; - mac[5] = tmp16 >> 8; - - ninfo("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - (void)lpc54_eth_addmac(dev, mac); - -#ifdef CONFIG_NET_ICMPv6_AUTOCONF - /* Add the IPv6 all link-local nodes Ethernet address. This is the - * address that we expect to receive ICMPv6 Router Advertisement - * packets. - */ - - (void)lpc54_eth_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet); - -#endif /* CONFIG_NET_ICMPv6_AUTOCONF */ - -#ifdef CONFIG_NET_ICMPv6_ROUTER - /* Add the IPv6 all link-local routers Ethernet address. This is the - * address that we expect to receive ICMPv6 Router Solicitation - * packets. - */ - - (void)lpc54_eth_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet); - -#endif /* CONFIG_NET_ICMPv6_ROUTER */ -} -#endif /* CONFIG_NET_ICMPv6 */ - /**************************************************************************** * Name: lpc54_eth_ioctl * diff --git a/include/nuttx/net/ethernet.h b/include/nuttx/net/ethernet.h index dbf8b7e8e72..86f19e4a58e 100644 --- a/include/nuttx/net/ethernet.h +++ b/include/nuttx/net/ethernet.h @@ -57,13 +57,28 @@ /* Recognized values of the type bytes in the Ethernet header */ -#define ETHTYPE_ARP 0x0806 /* Address resolution protocol */ -#define ETHTYPE_IP 0x0800 /* IP protocol */ -#define ETHTYPE_IP6 0x86dd /* IP protocol version 6 */ +#define ETHTYPE_ARP 0x0806 /* Address resolution protocol */ +#define ETHTYPE_IP 0x0800 /* IP protocol */ +#define ETHTYPE_IP6 0x86dd /* IP protocol version 6 */ + +/* Tag protocol identifier (TPID) of 0x8100 identifies the frame as an + * IEEE 802.1Q-tagged frame. This field is located at the same position as + * the Ethernet type field in untagged frames and is thus used to + * distinguish the frame from untagged frames. + */ + +#define TPID_8021QVLAN 0x8100 + +/* These are some of the types then associated with withe QVLAN tagged + * Ethernet packets. + */ + +#define ETHTYPE_AVBTP 0x22f0 /* Audio/Video bridging type */ /* Size of the Ethernet header */ -#define ETH_HDRLEN 14 /* Minimum size: 2*6 + 2 */ +#define ETH_HDRLEN 14 /* Minimum size: 2*6 + 2 */ +#define ETH_8021Q_HDRLEN 18 /* Minimum size: 2*6 + 4 + 2 */ /**************************************************************************** * Public Types @@ -81,6 +96,22 @@ struct eth_hdr_s uint16_t type; /* Type code (2 bytes) */ }; +/* IEEE 802.1Q adds a 32-bit field between the source MAC address and the + * type fields of the original Ethernet header. Two bytes are used for the + * tag protocol identifier (TPID), the other two bytes for tag control + * information TCI). The TCI field is further divided into PCP, DEI, and + * VID. + */ + +struct eth_8021qhdr_s +{ + uint8_t dest[6]; /* Ethernet destination address (6 bytes) */ + uint8_t src[6]; /* Ethernet source address (6 bytes) */ + uint16_t tpid; /* TCI: Tag protocol identifier (2 bytes) */ + uint16_t tci; /* TCI: Tag control information: PCP, DEI, VID (2 bytes) */ + uint16_t type; /* Type code (2 bytes) */ +}; + /**************************************************************************** * Public Data ****************************************************************************/