LPC17xx: Add IPv6 support to the LPC17 Ethernet driver. Untested... I no longer have a proper environment for LPC17 debug.
This commit is contained in:
parent
410fcaa0a1
commit
3859ee90f8
@ -60,7 +60,7 @@
|
||||
#endif
|
||||
|
||||
/* Is networking enabled? Is the LPC17xx Ethernet device enabled? Does this chip have
|
||||
* and Ethernet controlloer? Yes... then we will replace the above default definitions.
|
||||
* and Ethernet controller? Yes... then we will replace the above default definitions.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET) && defined(CONFIG_LPC17_ETHERNET) && LPC17_NETHCONTROLLERS > 0
|
||||
@ -124,7 +124,7 @@
|
||||
/* EMAC DMA RAM and descriptor definitions. The configured number of descriptors
|
||||
* will determine the organization and the size of the descriptor and status tables.
|
||||
* There is a complex interaction between the maximum packet size (CONFIG_NET_ETH_MTU)
|
||||
* and the number of Rx and Tx descriptors that can be suppored (CONFIG_NET_NRXDESC
|
||||
* and the number of Rx and Tx descriptors that can be supported (CONFIG_NET_NRXDESC
|
||||
* and CONFIG_NET_NTXDESC): Small buffers -> more packets. This is something that
|
||||
* needs to be tuned for you system.
|
||||
*
|
||||
|
@ -361,11 +361,17 @@ static void lpc17_txtimeout(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
static void lpc17_ipv6multicast(FAR struct lpc17_ethmac_s *priv);
|
||||
#endif
|
||||
static int lpc17_ifup(struct net_driver_s *dev);
|
||||
static int lpc17_ifdown(struct net_driver_s *dev);
|
||||
static int lpc17_txavail(struct net_driver_s *dev);
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static uint32_t lpc17_calcethcrc(const uint8_t *data, size_t length);
|
||||
static int lpc17_addmac(struct net_driver_s *dev, const uint8_t *mac);
|
||||
#endif
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
static int lpc17_rmmac(struct net_driver_s *dev, const uint8_t *mac);
|
||||
#endif
|
||||
|
||||
@ -1422,6 +1428,79 @@ static void lpc17_polltimer(int argc, uint32_t arg, ...)
|
||||
(void)wd_start(priv->lp_txpoll, LPC17_WDDELAY, lpc17_polltimer, 1, arg);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc17_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 lpc17_ipv6multicast(FAR struct lpc17_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.
|
||||
*
|
||||
* 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->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;
|
||||
|
||||
nvdbg("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
|
||||
(void)lpc17_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)lpc17_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)lpc17_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet);
|
||||
|
||||
#endif /* CONFIG_NET_ICMPv6_ROUTER */
|
||||
}
|
||||
#endif /* CONFIG_NET_ICMPv6 */
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc17_ifup
|
||||
*
|
||||
@ -1476,6 +1555,12 @@ static int lpc17_ifup(struct net_driver_s *dev)
|
||||
(uint32_t)priv->lp_dev.d_mac.ether_addr_octet[0];
|
||||
lpc17_putreg(regval, LPC17_ETH_SA2);
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
/* Set up the IPv6 multicast address */
|
||||
|
||||
lpc17_ipv6multicast(priv);
|
||||
#endif
|
||||
|
||||
/* Initialize Ethernet interface for the PHY setup */
|
||||
|
||||
lpc17_macmode(priv->lp_mode);
|
||||
@ -1685,6 +1770,99 @@ static int lpc17_txavail(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc17_calcethcrc
|
||||
*
|
||||
* Description:
|
||||
* Function to calculate the CRC used by LPC17 to check an Ethernet frame
|
||||
*
|
||||
* Algorithm adapted from LPC17xx sample code that contains this notice:
|
||||
*
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
*
|
||||
* Parameters:
|
||||
* data - the data to be checked
|
||||
* length - length of the data
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static uint32_t lpc17_calcethcrc(const uint8_t *data, size_t length)
|
||||
{
|
||||
char byte;
|
||||
int crc;
|
||||
int q0;
|
||||
int q1;
|
||||
int q2;
|
||||
int q3;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
crc = 0xffffffff;
|
||||
for (i = 0; i < frame_len; i++)
|
||||
{
|
||||
byte = *frame_no_fcs++;
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
if (((crc >> 28) ^ (byte >> 3)) & 0x00000001)
|
||||
{
|
||||
q3 = 0x04c11db7;
|
||||
}
|
||||
else
|
||||
{
|
||||
q3 = 0x00000000;
|
||||
}
|
||||
|
||||
if (((crc >> 29) ^ (byte >> 2)) & 0x00000001)
|
||||
{
|
||||
q2 = 0x09823b6e;
|
||||
}
|
||||
else
|
||||
{
|
||||
q2 = 0x00000000;
|
||||
}
|
||||
|
||||
if (((crc >> 30) ^ (byte >> 1)) & 0x00000001)
|
||||
{
|
||||
q1 = 0x130476dc;
|
||||
}
|
||||
else
|
||||
{
|
||||
q1 = 0x00000000;
|
||||
}
|
||||
|
||||
if (((crc >> 31) ^ (byte >> 0)) & 0x00000001)
|
||||
{
|
||||
q0 = 0x2608EDB8;
|
||||
}
|
||||
else
|
||||
{
|
||||
q0 = 0x00000000;
|
||||
}
|
||||
|
||||
crc = (crc << 4) ^ q3 ^ q2 ^ q1 ^ q0;
|
||||
byte >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc17_addmac
|
||||
*
|
||||
@ -1703,17 +1881,62 @@ static int lpc17_txavail(struct net_driver_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static int lpc17_addmac(struct net_driver_s *dev, const uint8_t *mac)
|
||||
{
|
||||
struct lpc17_driver_s *priv = (struct lpc17_driver_s *)dev->d_private;
|
||||
uintptr_t regaddr;
|
||||
uint32_t regval;
|
||||
uint32_t crc;
|
||||
unsigned int ndx;
|
||||
|
||||
/* Add the MAC address to the hardware multicast routing table */
|
||||
nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
|
||||
/* Hash function:
|
||||
*
|
||||
* The standard Ethernet cyclic redundancy check (CRC) function is
|
||||
* calculated from the 6 byte MAC address. Bits [28:23] out of the 32-bit
|
||||
* CRC result are taken to form the hash. The 6-bit hash is used to access
|
||||
* the hash table: it is used as an index in the 64-bit HashFilter register
|
||||
* that has been programmed with accept values. If the selected accept value
|
||||
* is 1, the frame is accepted.
|
||||
*/
|
||||
|
||||
crc = lpc17_calcethcrc(mac, 6);
|
||||
ndx = (crc >> 23) & 0x3f;
|
||||
|
||||
/* Add the MAC address to the hardware multicast hash table */
|
||||
|
||||
if (ndx > 31)
|
||||
{
|
||||
regaddr = LPC17_ETH_HASHFLH; /* Hash filter table MSBs register */
|
||||
ndx -= 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
regaddr = LPC17_ETH_HASHFLL; /* Hash filter table LSBs register */
|
||||
}
|
||||
|
||||
regval = lpc17_getreg(regaddr);
|
||||
regval |= 1 << ndx;
|
||||
lpc17_putreg(regval, regaddr);
|
||||
|
||||
/* Enabled multicast address filtering in the RxFilterControl register:
|
||||
*
|
||||
* AcceptUnicastHashEn: When set to ’1’, unicast frames that pass the
|
||||
* imperfect hash filter are accepted.
|
||||
* AcceptMulticastHashEn When set to ’1’, multicast frames that pass the
|
||||
* imperfect hash filter are accepted.
|
||||
*/
|
||||
|
||||
regval = lpc17_getreg(LPC17_ETH_RXFLCTRL);
|
||||
regval &= ~ETH_RXFLCTRL_UCASTHASHEN;
|
||||
regval |= ETH_RXFLCTRL_MCASTHASHEN;
|
||||
lpc17_putreg(regval, LPC17_ETH_RXFLCTRL);
|
||||
|
||||
#warning "Not implemented"
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_NET_IGMP || CONFIG_NET_ICMPv6 */
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc17_rmmac
|
||||
@ -1736,11 +1959,63 @@ static int lpc17_addmac(struct net_driver_s *dev, const uint8_t *mac)
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
static int lpc17_rmmac(struct net_driver_s *dev, const uint8_t *mac)
|
||||
{
|
||||
struct lpc17_driver_s *priv = (struct lpc17_driver_s *)dev->d_private;
|
||||
uintptr_t regaddr1;
|
||||
uintptr_t regaddr2;
|
||||
uint32_t regval;
|
||||
uint32_t crc;
|
||||
unsigned int ndx;
|
||||
|
||||
/* Add the MAC address to the hardware multicast routing table */
|
||||
nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
|
||||
/* Hash function:
|
||||
*
|
||||
* The standard Ethernet cyclic redundancy check (CRC) function is
|
||||
* calculated from the 6 byte MAC address. Bits [28:23] out of the 32-bit
|
||||
* CRC result are taken to form the hash. The 6-bit hash is used to access
|
||||
* the hash table: it is used as an index in the 64-bit HashFilter register
|
||||
* that has been programmed with accept values. If the selected accept value
|
||||
* is 1, the frame is accepted.
|
||||
*/
|
||||
|
||||
crc = lpc17_calcethcrc(mac, 6);
|
||||
ndx = (crc >> 23) & 0x3f;
|
||||
|
||||
/* Remove the MAC address to the hardware multicast hash table */
|
||||
|
||||
if (ndx > 31)
|
||||
{
|
||||
regaddr1 = LPC17_ETH_HASHFLH; /* Hash filter table MSBs register */
|
||||
regaddr2 = LPC17_ETH_HASHFLL; /* Hash filter table LSBs register */
|
||||
ndx -= 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
regaddr1 = LPC17_ETH_HASHFLL; /* Hash filter table LSBs register */
|
||||
regaddr2 = LPC17_ETH_HASHFLH; /* Hash filter table MSBs register */
|
||||
}
|
||||
|
||||
regval = lpc17_getreg(regaddr1);
|
||||
regval &= ~(1 << ndx);
|
||||
lpc17_putreg(regval, regaddr1);
|
||||
|
||||
/* If there are no longer addresses being filtered , disable multicast
|
||||
* filtering.
|
||||
*/
|
||||
|
||||
if (regval == 0 && lpc17_getreg(regaddr2) == 0)
|
||||
{
|
||||
/* AcceptUnicastHashEn: When set to ’1’, unicast frames that pass the
|
||||
* imperfect hash filter are accepted.
|
||||
* AcceptMulticastHashEn When set to ’1’, multicast frames that pass the
|
||||
* imperfect hash filter are accepted.
|
||||
*/
|
||||
|
||||
regval = lpc17_getreg(LPC17_ETH_RXFLCTRL);
|
||||
regval &= ~(ETH_RXFLCTRL_UCASTHASHEN | ETH_RXFLCTRL_MCASTHASHEN);
|
||||
lpc17_putreg(regval, LPC17_ETH_RXFLCTRL);
|
||||
}
|
||||
|
||||
#warning "Not implemented"
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
@ -50,8 +50,9 @@ fi
|
||||
# This is the Cygwin path to the location where I installed the CodeSourcery
|
||||
# toolchain under windows. You will also have to edit this if you install
|
||||
# the CodeSourcery toolchain in any other location
|
||||
# export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery G++ Lite/bin"
|
||||
# export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin"
|
||||
#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery G++ Lite/bin"
|
||||
#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin"
|
||||
#export TOOLCHAIN_BIN="/cygdrive/c/Users/MyName/MentorGraphics/Sourcery_CodeBench_Lite_for_ARM_EABI/bin"
|
||||
|
||||
# These are the Cygwin paths to the locations where I installed the Atollic
|
||||
# toolchain under windows. You will also have to edit this if you install
|
||||
|
Loading…
Reference in New Issue
Block a user