STM32 EMAC: Add support for IGMP hash table update. From Manuel Stühn
This commit is contained in:
parent
5b1e019fdd
commit
7d3d1f79bb
@ -7023,4 +7023,5 @@
|
||||
with a "down" device. From Brennan Ashton (2014-3-20).
|
||||
* configs/sam4e-ek/usbnsh: Add a NSH configuration that uses the
|
||||
NSH console (2014-3-22).
|
||||
|
||||
* arch/arm/src/stm32/stm32_eth.c: Add IGMP hashing support. From
|
||||
Manuel Stühn (2014-3-24).
|
||||
|
@ -2141,6 +2141,50 @@ static int stm32_txavail(struct uip_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_calcethcrc
|
||||
*
|
||||
* Description:
|
||||
* Function to calculate the CRC used by STM32 to check an ethernet frame
|
||||
*
|
||||
* Parameters:
|
||||
* data - the data to be checked
|
||||
* length - length of the data
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
static uint32_t stm32_calcethcrc(const uint8_t *data, size_t length)
|
||||
{
|
||||
uint32_t crc = 0xffffffff;
|
||||
size_t i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (((crc >> 31) ^ (data[i] >> j)) & 0x01)
|
||||
{
|
||||
/* x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 */
|
||||
crc = (crc << 1) ^ 0x04c11db7;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc = crc << 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ~crc;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_addmac
|
||||
*
|
||||
@ -2162,14 +2206,37 @@ static int stm32_txavail(struct uip_driver_s *dev)
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
static int stm32_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
|
||||
{
|
||||
FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)dev->d_private;
|
||||
uint32_t crc;
|
||||
uint32_t hashindex;
|
||||
uint32_t temp;
|
||||
uint32_t registeraddress;
|
||||
|
||||
nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
|
||||
/* Add the MAC address to the hardware multicast routing table */
|
||||
/* Add the MAC address to the hardware multicast routing table */
|
||||
#error "Missing logic"
|
||||
/* Add the MAC address to the hardware multicast hash table */
|
||||
|
||||
crc = stm32_calcethcrc( mac, 6 );
|
||||
|
||||
hashindex = (crc >> 26) & 0x3F;
|
||||
|
||||
if (hashindex > 31)
|
||||
{
|
||||
registeraddress = STM32_ETH_MACHTHR;
|
||||
hashindex -= 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
registeraddress = STM32_ETH_MACHTLR;
|
||||
}
|
||||
|
||||
temp = stm32_getreg(registeraddress);
|
||||
temp |= 1 << hashindex;
|
||||
stm32_putreg(temp, registeraddress);
|
||||
|
||||
temp = stm32_getreg(STM32_ETH_MACFFR);
|
||||
temp |= (ETH_MACFFR_HM | ETH_MACFFR_HPF);
|
||||
stm32_putreg(temp, STM32_ETH_MACFFR);
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -2196,13 +2263,43 @@ static int stm32_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
static int stm32_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
|
||||
{
|
||||
FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)dev->d_private;
|
||||
uint32_t crc;
|
||||
uint32_t hashindex;
|
||||
uint32_t temp;
|
||||
uint32_t registeraddress;
|
||||
|
||||
nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
|
||||
/* Add the MAC address to the hardware multicast routing table */
|
||||
#error "Missing logic"
|
||||
/* Remove the MAC address to the hardware multicast hash table */
|
||||
|
||||
crc = stm32_calcethcrc( mac, 6 );
|
||||
|
||||
hashindex = (crc >> 26) & 0x3F;
|
||||
|
||||
if (hashindex > 31)
|
||||
{
|
||||
registeraddress = STM32_ETH_MACHTHR;
|
||||
hashindex -= 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
registeraddress = STM32_ETH_MACHTLR;
|
||||
}
|
||||
|
||||
temp = stm32_getreg(registeraddress);
|
||||
temp &= ~(1 << hashindex);
|
||||
stm32_putreg(temp, registeraddress);
|
||||
|
||||
/* If there is no address registered any more, delete multicast filtering */
|
||||
|
||||
if (stm32_getreg(STM32_ETH_MACHTHR ) == 0 &&
|
||||
stm32_getreg(STM32_ETH_MACHTLR) == 0)
|
||||
{
|
||||
temp = stm32_getreg(STM32_ETH_MACFFR);
|
||||
temp &= ~(ETH_MACFFR_HM | ETH_MACFFR_HPF);
|
||||
stm32_putreg(temp, STM32_ETH_MACFFR);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user