From 2db954c18993983aa7b3e1d75a18e2a9dba3cb04 Mon Sep 17 00:00:00 2001 From: "Anton D. Kachalov" Date: Mon, 3 Aug 2015 19:43:17 +0300 Subject: [PATCH 1/2] Add support for multicast address (via hashtable) Signed-off-by: Anton D. Kachalov --- drivers/net/ftmac100.c | 93 +++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 19 deletions(-) diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c index 0f353a8b0f..2a7b236ab4 100644 --- a/drivers/net/ftmac100.c +++ b/drivers/net/ftmac100.c @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -107,14 +108,26 @@ #define ETH_ZLEN 60 -#define MACCR_ENABLE_ALL (FTMAC100_MACCR_XMT_EN | \ - FTMAC100_MACCR_RCV_EN | \ - FTMAC100_MACCR_XDMA_EN | \ - FTMAC100_MACCR_RDMA_EN | \ - FTMAC100_MACCR_CRC_APD | \ - FTMAC100_MACCR_FULLDUP | \ - FTMAC100_MACCR_RX_RUNT | \ - FTMAC100_MACCR_RX_BROADPKT) +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +# define MACCR_ENABLE_ALL (FTMAC100_MACCR_XMT_EN | \ + FTMAC100_MACCR_RCV_EN | \ + FTMAC100_MACCR_XDMA_EN | \ + FTMAC100_MACCR_RDMA_EN | \ + FTMAC100_MACCR_CRC_APD | \ + FTMAC100_MACCR_FULLDUP | \ + FTMAC100_MACCR_RX_RUNT | \ + FTMAC100_MACCR_HT_MULTI_EN | \ + FTMAC100_MACCR_RX_BROADPKT) +#else +# define MACCR_ENABLE_ALL (FTMAC100_MACCR_XMT_EN | \ + FTMAC100_MACCR_RCV_EN | \ + FTMAC100_MACCR_XDMA_EN | \ + FTMAC100_MACCR_RDMA_EN | \ + FTMAC100_MACCR_CRC_APD | \ + FTMAC100_MACCR_FULLDUP | \ + FTMAC100_MACCR_RX_RUNT | \ + FTMAC100_MACCR_RX_BROADPKT) +#endif #define MACCR_DISABLE_ALL 0 @@ -919,21 +932,21 @@ static inline void ftmac100_interrupt_process(FAR struct ftmac100_driver_s *priv #if 0 #define REG(x) (*(volatile uint32_t *)(x)) - ndbg("\n=============================================================\n"); - ndbg("TM CNTL=%08x INTRS=%08x MASK=%08x LOAD=%08x COUNT=%08x M1=%08x\n", - REG(0x98400030), REG(0x98400034), REG(0x98400038), REG(0x98400004), - REG(0x98400000), REG(0x98400008)); - ndbg("IRQ STATUS=%08x MASK=%08x MODE=%08x LEVEL=%08x\n", - REG(0x98800014), REG(0x98800004), REG(0x9880000C), REG(0x98800010)); - ndbg("FIQ STATUS=%08x MASK=%08x MODE=%08x LEVEL=%08x\n", REG(0x98800034), - REG(0x98800024), REG(0x9880002C), REG(0x98800020)); - ndbg("=============================================================\n"); + nvdbg("\n=============================================================\n"); + nvdbg("TM CNTL=%08x INTRS=%08x MASK=%08x LOAD=%08x COUNT=%08x M1=%08x\n", + REG(0x98400030), REG(0x98400034), REG(0x98400038), REG(0x98400004), + REG(0x98400000), REG(0x98400008)); + nvdbg("IRQ STATUS=%08x MASK=%08x MODE=%08x LEVEL=%08x\n", + REG(0x98800014), REG(0x98800004), REG(0x9880000C), REG(0x98800010)); + nvdbg("FIQ STATUS=%08x MASK=%08x MODE=%08x LEVEL=%08x\n", REG(0x98800034), + REG(0x98800024), REG(0x9880002C), REG(0x98800020)); + nvdbg("=============================================================\n"); #endif out: putreg32 (INT_MASK_ALL_ENABLED, &iobase->imr); - ndbg("ISR-done\n"); + nvdbg("ISR-done\n"); } /**************************************************************************** @@ -1515,9 +1528,35 @@ static int ftmac100_txavail(struct net_driver_s *dev) static int ftmac100_addmac(struct net_driver_s *dev, FAR const uint8_t *mac) { FAR struct ftmac100_driver_s *priv = (FAR struct ftmac100_driver_s *)dev->d_private; + FAR struct ftmac100_register_s *iobase = (FAR struct ftmac100_register_s *)priv->iobase; + uint32_t hash_value, hash_reg, hash_bit; + uint32_t mta; + + /* Calculate Ethernet CRC32 for MAC */ + + hash_value = crc32part(mac, 6, ~0L); + + /* + * The HASH Table is a register array of 2 32-bit registers. + * It is treated like an array of 64 bits. We want to set + * bit BitArray[hash_value]. So we figure out what register + * the bit is in, read it, OR in the new bit, then write + * back the new value. The register is determined by the + * upper 7 bits of the hash value and the bit within that + * register are determined by the lower 5 bits of the value. + */ + + hash_reg = (hash_value >> 31) & 0x1; + hash_bit = (hash_value >> 26) & 0x1f; /* Add the MAC address to the hardware multicast routing table */ + mta = getreg32(&iobase->maht0 + hash_reg); + + mta |= (1 << hash_bit); + + putreg32(mta, &iobase->maht0 + hash_reg); + return OK; } #endif @@ -1544,8 +1583,24 @@ static int ftmac100_addmac(struct net_driver_s *dev, FAR const uint8_t *mac) static int ftmac100_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac) { FAR struct ftmac100_driver_s *priv = (FAR struct ftmac100_driver_s *)dev->d_private; + FAR struct ftmac100_register_s *iobase = (FAR struct ftmac100_register_s *)priv->iobase; + uint32_t hash_value, hash_reg, hash_bit; + uint32_t mta; - /* Add the MAC address to the hardware multicast routing table */ + /* Calculate Ethernet CRC32 for MAC */ + + hash_value = crc32part(mac, 6, ~0L); + + hash_reg = (hash_value >> 31) & 0x1; + hash_bit = (hash_value >> 26) & 0x1f; + + /* Remove the MAC address to the hardware multicast routing table */ + + mta = getreg32(&iobase->maht0 + hash_reg); + + mta &= ~(1 << hash_bit); + + putreg32(mta, &iobase->maht0 + hash_reg); return OK; } From f62ca5b01a99db273893e98b4c2938e7d7265b74 Mon Sep 17 00:00:00 2001 From: "Anton D. Kachalov" Date: Mon, 3 Aug 2015 19:43:59 +0300 Subject: [PATCH 2/2] Compilation fixup: change "|=" -> "!=" Signed-off-by: Anton D. Kachalov --- sched/semaphore/sem_tickwait.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sched/semaphore/sem_tickwait.c b/sched/semaphore/sem_tickwait.c index 74de8f054d..57e36d1f0c 100644 --- a/sched/semaphore/sem_tickwait.c +++ b/sched/semaphore/sem_tickwait.c @@ -87,7 +87,7 @@ int sem_tickwait(FAR sem_t *sem, uint32_t start, uint32_t delay) uint32_t elapsed; int ret; - DEBUGASSERT(sem |= NULL && up_interrupt_context() == false && + DEBUGASSERT(sem != NULL && up_interrupt_context() == false && rtcb->waitdog == NULL); /* Create a watchdog. We will not actually need this watchdog