summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-01-19 12:43:13 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-01-19 12:43:13 -0600
commit5df9992f53a7e58dc4ff1a1ff7a5940ca38db6a7 (patch)
treec5b3fdfa73e6aefbcab2e4b7eb59d8b7f5869d3e /nuttx
parent187cd324f6b573aa6619797784522455dd40129b (diff)
downloadnuttx-5df9992f53a7e58dc4ff1a1ff7a5940ca38db6a7.tar.gz
nuttx-5df9992f53a7e58dc4ff1a1ff7a5940ca38db6a7.tar.bz2
nuttx-5df9992f53a7e58dc4ff1a1ff7a5940ca38db6a7.zip
Tiva Ethernet: Add support for receiving IPv6 multicast frames
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/arch/arm/src/tiva/tm4c_ethernet.c73
1 files changed, 67 insertions, 6 deletions
diff --git a/nuttx/arch/arm/src/tiva/tm4c_ethernet.c b/nuttx/arch/arm/src/tiva/tm4c_ethernet.c
index 597a08961..3cc476998 100644
--- a/nuttx/arch/arm/src/tiva/tm4c_ethernet.c
+++ b/nuttx/arch/arm/src/tiva/tm4c_ethernet.c
@@ -731,8 +731,10 @@ static inline void tiva_txavail_process(FAR struct tiva_ethmac_s *priv);
static void tiva_txavail_work(FAR void *arg);
#endif
static int tiva_txavail(struct net_driver_s *dev);
-#ifdef CONFIG_NET_IGMP
+#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
static int tiva_addmac(struct net_driver_s *dev, FAR const uint8_t *mac);
+#endif
+#ifdef CONFIG_NET_IGMP
static int tiva_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac);
#endif
#ifdef CONFIG_NETDEV_PHY_IOCTL
@@ -761,6 +763,9 @@ static inline void tiva_phy_initialize(FAR struct tiva_ethmac_s *priv);
static void tiva_ethreset(FAR struct tiva_ethmac_s *priv);
static int tiva_macconfig(FAR struct tiva_ethmac_s *priv);
static void tiva_macaddress(FAR struct tiva_ethmac_s *priv);
+#ifdef CONFIG_NET_ICMPv6
+static void tiva_ipv6multicast(FAR struct tiva_ethmac_s *priv);
+#endif
static int tiva_macenable(FAR struct tiva_ethmac_s *priv);
static int tive_emac_configure(FAR struct tiva_ethmac_s *priv);
@@ -1725,7 +1730,7 @@ static void tiva_receive(FAR struct tiva_ethmac_s *priv)
#ifdef CONFIG_NET_IPv6
if (BUF->type == HTONS(ETHTYPE_IP6))
{
- nllvdbg("Iv6 frame\n");
+ nllvdbg("IPv6 frame\n");
/* Give the IPv6 packet to the network layer */
@@ -2643,7 +2648,7 @@ static int tiva_txavail(struct net_driver_s *dev)
*
****************************************************************************/
-#ifdef CONFIG_NET_IGMP
+#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
static uint32_t tiva_calcethcrc(const uint8_t *data, size_t length)
{
uint32_t crc = 0xffffffff;
@@ -2668,7 +2673,7 @@ static uint32_t tiva_calcethcrc(const uint8_t *data, size_t length)
return ~crc;
}
-#endif
+#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */
/****************************************************************************
* Function: tiva_addmac
@@ -2688,7 +2693,7 @@ static uint32_t tiva_calcethcrc(const uint8_t *data, size_t length)
*
****************************************************************************/
-#ifdef CONFIG_NET_IGMP
+#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
static int tiva_addmac(struct net_driver_s *dev, FAR const uint8_t *mac)
{
uint32_t crc;
@@ -3805,7 +3810,7 @@ static int tiva_macconfig(FAR struct tiva_ethmac_s *priv)
if (priv->mbps100)
{
- /* Set the FES bit for 100Mbps fast ethernet support */
+ /* Set the FES bit for 100Mbps fast Ethernet support */
regval |= EMAC_CFG_FES;
}
@@ -3896,6 +3901,56 @@ static void tiva_macaddress(FAR struct tiva_ethmac_s *priv)
}
/****************************************************************************
+ * Function: tiva_ipv6multicast
+ *
+ * Description:
+ * Configure the IPv6 multicast MAC address.
+ *
+ * Parameters:
+ * priv - A reference to the private driver state structure
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_ICMPv6
+static void tiva_ipv6multicast(FAR struct tiva_ethmac_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.
+ */
+
+ mac[0] = 0x33;
+ mac[1] = 0x33;
+
+ dev = &priv->dev;
+ tmp16 = dev->d_ipv6addr[6];
+ mac[2] = tmp16 & 0xff;
+ mac[3] = tmp16 >> 8;
+
+ tmp16 = dev->d_ipv6addr[7];
+ mac[4] = tmp16 & 0xff;
+ mac[5] = tmp16 >> 8;
+
+ nvdbg("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ (void)tiva_addmac(dev, mac);
+}
+#endif /* CONFIG_NET_ICMPv6 */
+
+/****************************************************************************
* Function: tiva_macenable
*
* Description:
@@ -3919,6 +3974,12 @@ static int tiva_macenable(FAR struct tiva_ethmac_s *priv)
tiva_macaddress(priv);
+#ifdef CONFIG_NET_ICMPv6
+ /* Set up the IPv6 multicast address */
+
+ tiva_ipv6multicast(priv);
+#endif
+
/* Enable transmit state machine of the MAC for transmission on the MII */
regval = tiva_getreg(TIVA_EMAC_CFG);