aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/amd
diff options
context:
space:
mode:
authorLendacky, Thomas <Thomas.Lendacky@amd.com>2014-06-24 17:19:29 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-26 20:14:04 -0400
commitb85e4d8960f10e4b28613a3e7b76f8889a2089e3 (patch)
tree240e74511042f9bdd930dcb41c030f0eb910c4b1 /drivers/net/ethernet/amd
parent801c62d945c6121c0262924732e430f0553bfb37 (diff)
amd-xgbe: Change destination address filtering support
Currently the driver makes use of the additional mac address registers in the hardware to provide perfect filtering. The hardware can also have a set of hash table registers that can be used for imperfect filtering. By using imperfect filtering the additional mac address registers can be used for layer 2 filtering support. Use the hash table registers if the device has them. Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/amd')
-rw-r--r--drivers/net/ethernet/amd/Kconfig1
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-common.h10
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-dev.c141
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-drv.c27
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-main.c2
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe.h4
6 files changed, 116 insertions, 69 deletions
diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig
index 8e83e4c8fff0..6e314dbba805 100644
--- a/drivers/net/ethernet/amd/Kconfig
+++ b/drivers/net/ethernet/amd/Kconfig
@@ -183,6 +183,7 @@ config AMD_XGBE
183 select PHYLIB 183 select PHYLIB
184 select AMD_XGBE_PHY 184 select AMD_XGBE_PHY
185 select BITREVERSE 185 select BITREVERSE
186 select CRC32
186 ---help--- 187 ---help---
187 This driver supports the AMD 10GbE Ethernet device found on an 188 This driver supports the AMD 10GbE Ethernet device found on an
188 AMD SoC. 189 AMD SoC.
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
index 1de9d0fc594a..ccbceba553e5 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
@@ -276,13 +276,6 @@
276#define MAC_PFR 0x0008 276#define MAC_PFR 0x0008
277#define MAC_WTR 0x000c 277#define MAC_WTR 0x000c
278#define MAC_HTR0 0x0010 278#define MAC_HTR0 0x0010
279#define MAC_HTR1 0x0014
280#define MAC_HTR2 0x0018
281#define MAC_HTR3 0x001c
282#define MAC_HTR4 0x0020
283#define MAC_HTR5 0x0024
284#define MAC_HTR6 0x0028
285#define MAC_HTR7 0x002c
286#define MAC_VLANTR 0x0050 279#define MAC_VLANTR 0x0050
287#define MAC_VLANHTR 0x0058 280#define MAC_VLANHTR 0x0058
288#define MAC_VLANIR 0x0060 281#define MAC_VLANIR 0x0060
@@ -315,6 +308,7 @@
315 308
316#define MAC_QTFCR_INC 4 309#define MAC_QTFCR_INC 4
317#define MAC_MACA_INC 4 310#define MAC_MACA_INC 4
311#define MAC_HTR_INC 4
318 312
319/* MAC register entry bit positions and sizes */ 313/* MAC register entry bit positions and sizes */
320#define MAC_HWF0R_ADDMACADRSEL_INDEX 18 314#define MAC_HWF0R_ADDMACADRSEL_INDEX 18
@@ -387,6 +381,8 @@
387#define MAC_MACA1HR_AE_WIDTH 1 381#define MAC_MACA1HR_AE_WIDTH 1
388#define MAC_PFR_HMC_INDEX 2 382#define MAC_PFR_HMC_INDEX 2
389#define MAC_PFR_HMC_WIDTH 1 383#define MAC_PFR_HMC_WIDTH 1
384#define MAC_PFR_HPF_INDEX 10
385#define MAC_PFR_HPF_WIDTH 1
390#define MAC_PFR_HUC_INDEX 1 386#define MAC_PFR_HUC_INDEX 1
391#define MAC_PFR_HUC_WIDTH 1 387#define MAC_PFR_HUC_WIDTH 1
392#define MAC_PFR_PM_INDEX 4 388#define MAC_PFR_PM_INDEX 4
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index 2c7d582e0859..a56069c91fc4 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -117,6 +117,7 @@
117#include <linux/phy.h> 117#include <linux/phy.h>
118#include <linux/clk.h> 118#include <linux/clk.h>
119#include <linux/bitrev.h> 119#include <linux/bitrev.h>
120#include <linux/crc32.h>
120 121
121#include "xgbe.h" 122#include "xgbe.h"
122#include "xgbe-common.h" 123#include "xgbe-common.h"
@@ -548,24 +549,16 @@ static int xgbe_set_all_multicast_mode(struct xgbe_prv_data *pdata,
548 return 0; 549 return 0;
549} 550}
550 551
551static int xgbe_set_addn_mac_addrs(struct xgbe_prv_data *pdata, 552static void xgbe_set_mac_reg(struct xgbe_prv_data *pdata,
552 unsigned int am_mode) 553 struct netdev_hw_addr *ha, unsigned int *mac_reg)
553{ 554{
554 struct netdev_hw_addr *ha;
555 unsigned int mac_reg;
556 unsigned int mac_addr_hi, mac_addr_lo; 555 unsigned int mac_addr_hi, mac_addr_lo;
557 u8 *mac_addr; 556 u8 *mac_addr;
558 unsigned int i;
559 557
560 XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0); 558 mac_addr_lo = 0;
561 XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HMC, 0); 559 mac_addr_hi = 0;
562
563 i = 0;
564 mac_reg = MAC_MACA1HR;
565 560
566 netdev_for_each_uc_addr(ha, pdata->netdev) { 561 if (ha) {
567 mac_addr_lo = 0;
568 mac_addr_hi = 0;
569 mac_addr = (u8 *)&mac_addr_lo; 562 mac_addr = (u8 *)&mac_addr_lo;
570 mac_addr[0] = ha->addr[0]; 563 mac_addr[0] = ha->addr[0];
571 mac_addr[1] = ha->addr[1]; 564 mac_addr[1] = ha->addr[1];
@@ -575,54 +568,93 @@ static int xgbe_set_addn_mac_addrs(struct xgbe_prv_data *pdata,
575 mac_addr[0] = ha->addr[4]; 568 mac_addr[0] = ha->addr[4];
576 mac_addr[1] = ha->addr[5]; 569 mac_addr[1] = ha->addr[5];
577 570
578 DBGPR(" adding unicast address %pM at 0x%04x\n", 571 DBGPR(" adding mac address %pM at 0x%04x\n", ha->addr,
579 ha->addr, mac_reg); 572 *mac_reg);
580 573
581 XGMAC_SET_BITS(mac_addr_hi, MAC_MACA1HR, AE, 1); 574 XGMAC_SET_BITS(mac_addr_hi, MAC_MACA1HR, AE, 1);
575 }
582 576
583 XGMAC_IOWRITE(pdata, mac_reg, mac_addr_hi); 577 XGMAC_IOWRITE(pdata, *mac_reg, mac_addr_hi);
584 mac_reg += MAC_MACA_INC; 578 *mac_reg += MAC_MACA_INC;
585 XGMAC_IOWRITE(pdata, mac_reg, mac_addr_lo); 579 XGMAC_IOWRITE(pdata, *mac_reg, mac_addr_lo);
586 mac_reg += MAC_MACA_INC; 580 *mac_reg += MAC_MACA_INC;
581}
587 582
588 i++; 583static void xgbe_set_mac_addn_addrs(struct xgbe_prv_data *pdata)
589 } 584{
585 struct net_device *netdev = pdata->netdev;
586 struct netdev_hw_addr *ha;
587 unsigned int mac_reg;
588 unsigned int addn_macs;
589
590 mac_reg = MAC_MACA1HR;
591 addn_macs = pdata->hw_feat.addn_mac;
590 592
591 if (!am_mode) { 593 if (netdev_uc_count(netdev) > addn_macs) {
592 netdev_for_each_mc_addr(ha, pdata->netdev) { 594 xgbe_set_promiscuous_mode(pdata, 1);
593 mac_addr_lo = 0; 595 } else {
594 mac_addr_hi = 0; 596 netdev_for_each_uc_addr(ha, netdev) {
595 mac_addr = (u8 *)&mac_addr_lo; 597 xgbe_set_mac_reg(pdata, ha, &mac_reg);
596 mac_addr[0] = ha->addr[0]; 598 addn_macs--;
597 mac_addr[1] = ha->addr[1]; 599 }
598 mac_addr[2] = ha->addr[2]; 600
599 mac_addr[3] = ha->addr[3]; 601 if (netdev_mc_count(netdev) > addn_macs) {
600 mac_addr = (u8 *)&mac_addr_hi; 602 xgbe_set_all_multicast_mode(pdata, 1);
601 mac_addr[0] = ha->addr[4]; 603 } else {
602 mac_addr[1] = ha->addr[5]; 604 netdev_for_each_mc_addr(ha, netdev) {
603 605 xgbe_set_mac_reg(pdata, ha, &mac_reg);
604 DBGPR(" adding multicast address %pM at 0x%04x\n", 606 addn_macs--;
605 ha->addr, mac_reg); 607 }
606
607 XGMAC_SET_BITS(mac_addr_hi, MAC_MACA1HR, AE, 1);
608
609 XGMAC_IOWRITE(pdata, mac_reg, mac_addr_hi);
610 mac_reg += MAC_MACA_INC;
611 XGMAC_IOWRITE(pdata, mac_reg, mac_addr_lo);
612 mac_reg += MAC_MACA_INC;
613
614 i++;
615 } 608 }
616 } 609 }
617 610
618 /* Clear remaining additional MAC address entries */ 611 /* Clear remaining additional MAC address entries */
619 for (; i < pdata->hw_feat.addn_mac; i++) { 612 while (addn_macs--)
620 XGMAC_IOWRITE(pdata, mac_reg, 0); 613 xgbe_set_mac_reg(pdata, NULL, &mac_reg);
621 mac_reg += MAC_MACA_INC; 614}
622 XGMAC_IOWRITE(pdata, mac_reg, 0); 615
623 mac_reg += MAC_MACA_INC; 616static void xgbe_set_mac_hash_table(struct xgbe_prv_data *pdata)
617{
618 struct net_device *netdev = pdata->netdev;
619 struct netdev_hw_addr *ha;
620 unsigned int hash_reg;
621 unsigned int hash_table_shift, hash_table_count;
622 u32 hash_table[XGBE_MAC_HASH_TABLE_SIZE];
623 u32 crc;
624 unsigned int i;
625
626 hash_table_shift = 26 - (pdata->hw_feat.hash_table_size >> 7);
627 hash_table_count = pdata->hw_feat.hash_table_size / 32;
628 memset(hash_table, 0, sizeof(hash_table));
629
630 /* Build the MAC Hash Table register values */
631 netdev_for_each_uc_addr(ha, netdev) {
632 crc = bitrev32(~crc32_le(~0, ha->addr, ETH_ALEN));
633 crc >>= hash_table_shift;
634 hash_table[crc >> 5] |= (1 << (crc & 0x1f));
635 }
636
637 netdev_for_each_mc_addr(ha, netdev) {
638 crc = bitrev32(~crc32_le(~0, ha->addr, ETH_ALEN));
639 crc >>= hash_table_shift;
640 hash_table[crc >> 5] |= (1 << (crc & 0x1f));
624 } 641 }
625 642
643 /* Set the MAC Hash Table registers */
644 hash_reg = MAC_HTR0;
645 for (i = 0; i < hash_table_count; i++) {
646 XGMAC_IOWRITE(pdata, hash_reg, hash_table[i]);
647 hash_reg += MAC_HTR_INC;
648 }
649}
650
651static int xgbe_add_mac_addresses(struct xgbe_prv_data *pdata)
652{
653 if (pdata->hw_feat.hash_table_size)
654 xgbe_set_mac_hash_table(pdata);
655 else
656 xgbe_set_mac_addn_addrs(pdata);
657
626 return 0; 658 return 0;
627} 659}
628 660
@@ -1606,6 +1638,13 @@ static void xgbe_config_flow_control_threshold(struct xgbe_prv_data *pdata)
1606static void xgbe_config_mac_address(struct xgbe_prv_data *pdata) 1638static void xgbe_config_mac_address(struct xgbe_prv_data *pdata)
1607{ 1639{
1608 xgbe_set_mac_address(pdata, pdata->netdev->dev_addr); 1640 xgbe_set_mac_address(pdata, pdata->netdev->dev_addr);
1641
1642 /* Filtering is done using perfect filtering and hash filtering */
1643 if (pdata->hw_feat.hash_table_size) {
1644 XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
1645 XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
1646 XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HMC, 1);
1647 }
1609} 1648}
1610 1649
1611static void xgbe_config_jumbo_enable(struct xgbe_prv_data *pdata) 1650static void xgbe_config_jumbo_enable(struct xgbe_prv_data *pdata)
@@ -2202,7 +2241,7 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if)
2202 2241
2203 hw_if->set_promiscuous_mode = xgbe_set_promiscuous_mode; 2242 hw_if->set_promiscuous_mode = xgbe_set_promiscuous_mode;
2204 hw_if->set_all_multicast_mode = xgbe_set_all_multicast_mode; 2243 hw_if->set_all_multicast_mode = xgbe_set_all_multicast_mode;
2205 hw_if->set_addn_mac_addrs = xgbe_set_addn_mac_addrs; 2244 hw_if->add_mac_addresses = xgbe_add_mac_addresses;
2206 hw_if->set_mac_address = xgbe_set_mac_address; 2245 hw_if->set_mac_address = xgbe_set_mac_address;
2207 2246
2208 hw_if->enable_rx_csum = xgbe_enable_rx_csum; 2247 hw_if->enable_rx_csum = xgbe_enable_rx_csum;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 2acc37c07d9b..72dd61166a1c 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -378,6 +378,21 @@ void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata)
378 hw_feat->pps_out_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, PPSOUTNUM); 378 hw_feat->pps_out_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, PPSOUTNUM);
379 hw_feat->aux_snap_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, AUXSNAPNUM); 379 hw_feat->aux_snap_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, AUXSNAPNUM);
380 380
381 /* Translate the Hash Table size into actual number */
382 switch (hw_feat->hash_table_size) {
383 case 0:
384 break;
385 case 1:
386 hw_feat->hash_table_size = 64;
387 break;
388 case 2:
389 hw_feat->hash_table_size = 128;
390 break;
391 case 3:
392 hw_feat->hash_table_size = 256;
393 break;
394 }
395
381 /* The Queue and Channel counts are zero based so increment them 396 /* The Queue and Channel counts are zero based so increment them
382 * to get the actual number 397 * to get the actual number
383 */ 398 */
@@ -912,18 +927,10 @@ static void xgbe_set_rx_mode(struct net_device *netdev)
912 pr_mode = ((netdev->flags & IFF_PROMISC) != 0); 927 pr_mode = ((netdev->flags & IFF_PROMISC) != 0);
913 am_mode = ((netdev->flags & IFF_ALLMULTI) != 0); 928 am_mode = ((netdev->flags & IFF_ALLMULTI) != 0);
914 929
915 if (netdev_uc_count(netdev) > pdata->hw_feat.addn_mac)
916 pr_mode = 1;
917 if (netdev_mc_count(netdev) > pdata->hw_feat.addn_mac)
918 am_mode = 1;
919 if ((netdev_uc_count(netdev) + netdev_mc_count(netdev)) >
920 pdata->hw_feat.addn_mac)
921 pr_mode = 1;
922
923 hw_if->set_promiscuous_mode(pdata, pr_mode); 930 hw_if->set_promiscuous_mode(pdata, pr_mode);
924 hw_if->set_all_multicast_mode(pdata, am_mode); 931 hw_if->set_all_multicast_mode(pdata, am_mode);
925 if (!pr_mode) 932
926 hw_if->set_addn_mac_addrs(pdata, am_mode); 933 hw_if->add_mac_addresses(pdata);
927 934
928 DBGPR("<--xgbe_set_rx_mode\n"); 935 DBGPR("<--xgbe_set_rx_mode\n");
929} 936}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
index c3a48b7c2aed..b411ac557c47 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
@@ -397,6 +397,8 @@ static int xgbe_probe(struct platform_device *pdev)
397 netdev->features |= netdev->hw_features; 397 netdev->features |= netdev->hw_features;
398 pdata->netdev_features = netdev->features; 398 pdata->netdev_features = netdev->features;
399 399
400 netdev->priv_flags |= IFF_UNICAST_FLT;
401
400 xgbe_init_rx_coalesce(pdata); 402 xgbe_init_rx_coalesce(pdata);
401 xgbe_init_tx_coalesce(pdata); 403 xgbe_init_tx_coalesce(pdata);
402 404
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index 3cb911f39b60..a2d5f5f5d8b7 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -191,6 +191,8 @@
191/* Flow control queue count */ 191/* Flow control queue count */
192#define XGMAC_MAX_FLOW_CONTROL_QUEUES 8 192#define XGMAC_MAX_FLOW_CONTROL_QUEUES 8
193 193
194/* Maximum MAC address hash table size (256 bits = 8 bytes) */
195#define XGBE_MAC_HASH_TABLE_SIZE 8
194 196
195struct xgbe_prv_data; 197struct xgbe_prv_data;
196 198
@@ -387,7 +389,7 @@ struct xgbe_hw_if {
387 389
388 int (*set_promiscuous_mode)(struct xgbe_prv_data *, unsigned int); 390 int (*set_promiscuous_mode)(struct xgbe_prv_data *, unsigned int);
389 int (*set_all_multicast_mode)(struct xgbe_prv_data *, unsigned int); 391 int (*set_all_multicast_mode)(struct xgbe_prv_data *, unsigned int);
390 int (*set_addn_mac_addrs)(struct xgbe_prv_data *, unsigned int); 392 int (*add_mac_addresses)(struct xgbe_prv_data *);
391 int (*set_mac_address)(struct xgbe_prv_data *, u8 *addr); 393 int (*set_mac_address)(struct xgbe_prv_data *, u8 *addr);
392 394
393 int (*enable_rx_csum)(struct xgbe_prv_data *); 395 int (*enable_rx_csum)(struct xgbe_prv_data *);