aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorRob Herring <rob.herring@calxeda.com>2013-09-30 16:12:17 -0400
committerDavid S. Miller <davem@davemloft.net>2013-10-02 16:10:29 -0400
commit0cf2f380073867e5d0cfb526fdf9bee0e7f8a9c6 (patch)
tree5576b9f7fe99866eecfeba289b547c34d242ad8f /drivers/net
parent8a8c3f5bebe2455200cd488aea8546d01645b06b (diff)
net: calxedaxgmac: determine number of address filters at runtime
Highbank and Midway xgmac h/w have different number of MAC address filter registers with 7 and 31, respectively. Highbank has been wrong, so fix it and detect the number of filter registers at run-time. Unfortunately, the version register is the same on both SOCs, so simply test if write to the last filter register will take a value. It always reads as 0 if not. Signed-off-by: Rob Herring <rob.herring@calxeda.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/calxeda/xgmac.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 35da09b80c7c..48f52882a22b 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -106,7 +106,6 @@
106#define XGMAC_DMA_HW_FEATURE 0x00000f58 /* Enabled Hardware Features */ 106#define XGMAC_DMA_HW_FEATURE 0x00000f58 /* Enabled Hardware Features */
107 107
108#define XGMAC_ADDR_AE 0x80000000 108#define XGMAC_ADDR_AE 0x80000000
109#define XGMAC_MAX_FILTER_ADDR 31
110 109
111/* PMT Control and Status */ 110/* PMT Control and Status */
112#define XGMAC_PMT_POINTER_RESET 0x80000000 111#define XGMAC_PMT_POINTER_RESET 0x80000000
@@ -384,6 +383,7 @@ struct xgmac_priv {
384 struct device *device; 383 struct device *device;
385 struct napi_struct napi; 384 struct napi_struct napi;
386 385
386 int max_macs;
387 struct xgmac_extra_stats xstats; 387 struct xgmac_extra_stats xstats;
388 388
389 spinlock_t stats_lock; 389 spinlock_t stats_lock;
@@ -1296,7 +1296,7 @@ static void xgmac_set_rx_mode(struct net_device *dev)
1296 1296
1297 memset(hash_filter, 0, sizeof(hash_filter)); 1297 memset(hash_filter, 0, sizeof(hash_filter));
1298 1298
1299 if (netdev_uc_count(dev) > XGMAC_MAX_FILTER_ADDR) { 1299 if (netdev_uc_count(dev) > priv->max_macs) {
1300 use_hash = true; 1300 use_hash = true;
1301 value |= XGMAC_FRAME_FILTER_HUC | XGMAC_FRAME_FILTER_HPF; 1301 value |= XGMAC_FRAME_FILTER_HUC | XGMAC_FRAME_FILTER_HPF;
1302 } 1302 }
@@ -1319,7 +1319,7 @@ static void xgmac_set_rx_mode(struct net_device *dev)
1319 goto out; 1319 goto out;
1320 } 1320 }
1321 1321
1322 if ((netdev_mc_count(dev) + reg - 1) > XGMAC_MAX_FILTER_ADDR) { 1322 if ((netdev_mc_count(dev) + reg - 1) > priv->max_macs) {
1323 use_hash = true; 1323 use_hash = true;
1324 value |= XGMAC_FRAME_FILTER_HMC | XGMAC_FRAME_FILTER_HPF; 1324 value |= XGMAC_FRAME_FILTER_HMC | XGMAC_FRAME_FILTER_HPF;
1325 } else { 1325 } else {
@@ -1340,7 +1340,7 @@ static void xgmac_set_rx_mode(struct net_device *dev)
1340 } 1340 }
1341 1341
1342out: 1342out:
1343 for (i = reg; i <= XGMAC_MAX_FILTER_ADDR; i++) 1343 for (i = reg; i <= priv->max_macs; i++)
1344 xgmac_set_mac_addr(ioaddr, NULL, i); 1344 xgmac_set_mac_addr(ioaddr, NULL, i);
1345 for (i = 0; i < XGMAC_NUM_HASH; i++) 1345 for (i = 0; i < XGMAC_NUM_HASH; i++)
1346 writel(hash_filter[i], ioaddr + XGMAC_HASH(i)); 1346 writel(hash_filter[i], ioaddr + XGMAC_HASH(i));
@@ -1759,6 +1759,13 @@ static int xgmac_probe(struct platform_device *pdev)
1759 uid = readl(priv->base + XGMAC_VERSION); 1759 uid = readl(priv->base + XGMAC_VERSION);
1760 netdev_info(ndev, "h/w version is 0x%x\n", uid); 1760 netdev_info(ndev, "h/w version is 0x%x\n", uid);
1761 1761
1762 /* Figure out how many valid mac address filter registers we have */
1763 writel(1, priv->base + XGMAC_ADDR_HIGH(31));
1764 if (readl(priv->base + XGMAC_ADDR_HIGH(31)) == 1)
1765 priv->max_macs = 31;
1766 else
1767 priv->max_macs = 7;
1768
1762 writel(0, priv->base + XGMAC_DMA_INTR_ENA); 1769 writel(0, priv->base + XGMAC_DMA_INTR_ENA);
1763 ndev->irq = platform_get_irq(pdev, 0); 1770 ndev->irq = platform_get_irq(pdev, 0);
1764 if (ndev->irq == -ENXIO) { 1771 if (ndev->irq == -ENXIO) {