diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2015-01-19 12:43:13 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2015-01-19 12:43:13 -0600 |
commit | 5df9992f53a7e58dc4ff1a1ff7a5940ca38db6a7 (patch) | |
tree | c5b3fdfa73e6aefbcab2e4b7eb59d8b7f5869d3e | |
parent | 187cd324f6b573aa6619797784522455dd40129b (diff) | |
download | nuttx-5df9992f53a7e58dc4ff1a1ff7a5940ca38db6a7.tar.gz nuttx-5df9992f53a7e58dc4ff1a1ff7a5940ca38db6a7.tar.bz2 nuttx-5df9992f53a7e58dc4ff1a1ff7a5940ca38db6a7.zip |
Tiva Ethernet: Add support for receiving IPv6 multicast frames
-rw-r--r-- | nuttx/arch/arm/src/tiva/tm4c_ethernet.c | 73 |
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); |