diff options
author | Rob Herring <rob.herring@calxeda.com> | 2013-09-30 16:12:17 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-02 16:10:29 -0400 |
commit | 0cf2f380073867e5d0cfb526fdf9bee0e7f8a9c6 (patch) | |
tree | 5576b9f7fe99866eecfeba289b547c34d242ad8f /drivers/net | |
parent | 8a8c3f5bebe2455200cd488aea8546d01645b06b (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.c | 15 |
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 | ||
1342 | out: | 1342 | out: |
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) { |