arch/arm/src/lpc54xx: Resolves some design issues with multicast address filtering and also with AVBTP multi-channel operation (the latter design is still incomplete).

This commit is contained in:
Gregory Nutt
2017-12-30 17:19:37 -06:00
parent f23fb9dd14
commit 13b5d4de96
4 changed files with 304 additions and 143 deletions
+70 -1
View File
@@ -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
+29 -7
View File
@@ -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 */
+170 -131
View File
@@ -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
*
+35 -4
View File
@@ -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
****************************************************************************/