aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/fec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/fec.c')
-rw-r--r--drivers/net/fec.c99
1 files changed, 51 insertions, 48 deletions
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 672566b89ecf..6ac1b90c5820 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1517,57 +1517,60 @@ static void set_multicast_list(struct net_device *dev)
1517 tmp = readl(fep->hwp + FEC_R_CNTRL); 1517 tmp = readl(fep->hwp + FEC_R_CNTRL);
1518 tmp |= 0x8; 1518 tmp |= 0x8;
1519 writel(tmp, fep->hwp + FEC_R_CNTRL); 1519 writel(tmp, fep->hwp + FEC_R_CNTRL);
1520 } else { 1520 return;
1521 tmp = readl(fep->hwp + FEC_R_CNTRL); 1521 }
1522 tmp &= ~0x8;
1523 writel(tmp, fep->hwp + FEC_R_CNTRL);
1524 1522
1525 if (dev->flags & IFF_ALLMULTI) { 1523 tmp = readl(fep->hwp + FEC_R_CNTRL);
1526 /* Catch all multicast addresses, so set the 1524 tmp &= ~0x8;
1527 * filter to all 1's 1525 writel(tmp, fep->hwp + FEC_R_CNTRL);
1528 */ 1526
1529 writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); 1527 if (dev->flags & IFF_ALLMULTI) {
1530 writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_LOW); 1528 /* Catch all multicast addresses, so set the
1531 } else { 1529 * filter to all 1's
1532 /* Clear filter and add the addresses in hash register 1530 */
1533 */ 1531 writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
1534 writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); 1532 writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
1535 writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); 1533
1536 1534 return;
1537 dmi = dev->mc_list; 1535 }
1538 1536
1539 for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) { 1537 /* Clear filter and add the addresses in hash register
1540 /* Only support group multicast for now */ 1538 */
1541 if (!(dmi->dmi_addr[0] & 1)) 1539 writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
1542 continue; 1540 writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
1543 1541
1544 /* calculate crc32 value of mac address */ 1542 dmi = dev->mc_list;
1545 crc = 0xffffffff; 1543
1546 1544 for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) {
1547 for (i = 0; i < dmi->dmi_addrlen; i++) { 1545 /* Only support group multicast for now */
1548 data = dmi->dmi_addr[i]; 1546 if (!(dmi->dmi_addr[0] & 1))
1549 for (bit = 0; bit < 8; bit++, data >>= 1) { 1547 continue;
1550 crc = (crc >> 1) ^ 1548
1551 (((crc ^ data) & 1) ? CRC32_POLY : 0); 1549 /* calculate crc32 value of mac address */
1552 } 1550 crc = 0xffffffff;
1553 } 1551
1554 1552 for (i = 0; i < dmi->dmi_addrlen; i++) {
1555 /* only upper 6 bits (HASH_BITS) are used 1553 data = dmi->dmi_addr[i];
1556 * which point to specific bit in he hash registers 1554 for (bit = 0; bit < 8; bit++, data >>= 1) {
1557 */ 1555 crc = (crc >> 1) ^
1558 hash = (crc >> (32 - HASH_BITS)) & 0x3f; 1556 (((crc ^ data) & 1) ? CRC32_POLY : 0);
1559
1560 if (hash > 31) {
1561 tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
1562 tmp |= 1 << (hash - 32);
1563 writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
1564 } else {
1565 tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_LOW);
1566 tmp |= 1 << hash;
1567 writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
1568 }
1569 } 1557 }
1570 } 1558 }
1559
1560 /* only upper 6 bits (HASH_BITS) are used
1561 * which point to specific bit in he hash registers
1562 */
1563 hash = (crc >> (32 - HASH_BITS)) & 0x3f;
1564
1565 if (hash > 31) {
1566 tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
1567 tmp |= 1 << (hash - 32);
1568 writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
1569 } else {
1570 tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_LOW);
1571 tmp |= 1 << hash;
1572 writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
1573 }
1571 } 1574 }
1572} 1575}
1573 1576