aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2012-05-13 18:18:41 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-14 18:53:19 -0400
commitcffb13f4d6fb5976f907c37e7fc7f6e6acb10d5f (patch)
tree2778dd1ed389a91e78af991cad051ff5d64821e6
parent20fb18dae04194486c61666dc1d9317f6f6dbf75 (diff)
stmmac: extend mac addr reg and fix perfect filering
This patch is to extend the number of MAC address registers for 16 to 32. In fact, other new 16 registers are available in new chips and this can help on perfect filter mode for unicast. This patch also fixes the perfect filtering mode by setting the bit 31 in the MAC address registers. v2: fixed Coding Style. Signed-off-by: Gianni Antoniazzi <gianni.antoniazzi-ext@st.com> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000.h11
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c11
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c8
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c4
7 files changed, 29 insertions, 10 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index f5dedcbf4651..7164509e3832 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -280,7 +280,7 @@ struct stmmac_ops {
280 /* Handle extra events on specific interrupts hw dependent */ 280 /* Handle extra events on specific interrupts hw dependent */
281 void (*host_irq_status) (void __iomem *ioaddr); 281 void (*host_irq_status) (void __iomem *ioaddr);
282 /* Multicast filter setting */ 282 /* Multicast filter setting */
283 void (*set_filter) (struct net_device *dev); 283 void (*set_filter) (struct net_device *dev, int id);
284 /* Flow control setting */ 284 /* Flow control setting */
285 void (*flow_ctrl) (void __iomem *ioaddr, unsigned int duplex, 285 void (*flow_ctrl) (void __iomem *ioaddr, unsigned int duplex,
286 unsigned int fc, unsigned int pause_time); 286 unsigned int fc, unsigned int pause_time);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
index 54339a78e358..1527f4ecd11a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -61,9 +61,11 @@ enum power_event {
61}; 61};
62 62
63/* GMAC HW ADDR regs */ 63/* GMAC HW ADDR regs */
64#define GMAC_ADDR_HIGH(reg) (0x00000040+(reg * 8)) 64#define GMAC_ADDR_HIGH(reg) (((reg > 15) ? 0x00000800 : 0x00000040) + \
65#define GMAC_ADDR_LOW(reg) (0x00000044+(reg * 8)) 65 (reg * 8))
66#define GMAC_MAX_UNICAST_ADDRESSES 16 66#define GMAC_ADDR_LOW(reg) (((reg > 15) ? 0x00000804 : 0x00000044) + \
67 (reg * 8))
68#define GMAC_MAX_PERFECT_ADDRESSES 32
67 69
68#define GMAC_AN_CTRL 0x000000c0 /* AN control */ 70#define GMAC_AN_CTRL 0x000000c0 /* AN control */
69#define GMAC_AN_STATUS 0x000000c4 /* AN status */ 71#define GMAC_AN_STATUS 0x000000c4 /* AN status */
@@ -205,4 +207,7 @@ enum rtc_control {
205#define GMAC_MMC_TX_INTR 0x108 207#define GMAC_MMC_TX_INTR 0x108
206#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208 208#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208
207 209
210/* Synopsys Core versions */
211#define DWMAC_CORE_3_40 34
212
208extern const struct stmmac_dma_ops dwmac1000_dma_ops; 213extern const struct stmmac_dma_ops dwmac1000_dma_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index e7cbcd99c2cb..b5e4d02f15c9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -84,10 +84,11 @@ static void dwmac1000_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
84 GMAC_ADDR_LOW(reg_n)); 84 GMAC_ADDR_LOW(reg_n));
85} 85}
86 86
87static void dwmac1000_set_filter(struct net_device *dev) 87static void dwmac1000_set_filter(struct net_device *dev, int id)
88{ 88{
89 void __iomem *ioaddr = (void __iomem *) dev->base_addr; 89 void __iomem *ioaddr = (void __iomem *) dev->base_addr;
90 unsigned int value = 0; 90 unsigned int value = 0;
91 unsigned int perfect_addr_number;
91 92
92 CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n", 93 CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
93 __func__, netdev_mc_count(dev), netdev_uc_count(dev)); 94 __func__, netdev_mc_count(dev), netdev_uc_count(dev));
@@ -121,8 +122,14 @@ static void dwmac1000_set_filter(struct net_device *dev)
121 writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH); 122 writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
122 } 123 }
123 124
125 /* Extra 16 regs are available in cores newer than the 3.40. */
126 if (id > DWMAC_CORE_3_40)
127 perfect_addr_number = GMAC_MAX_PERFECT_ADDRESSES;
128 else
129 perfect_addr_number = GMAC_MAX_PERFECT_ADDRESSES / 2;
130
124 /* Handle multiple unicast addresses (perfect filtering)*/ 131 /* Handle multiple unicast addresses (perfect filtering)*/
125 if (netdev_uc_count(dev) > GMAC_MAX_UNICAST_ADDRESSES) 132 if (netdev_uc_count(dev) > perfect_addr_number)
126 /* Switch to promiscuous mode is more than 16 addrs 133 /* Switch to promiscuous mode is more than 16 addrs
127 are required */ 134 are required */
128 value |= GMAC_FRAME_FILTER_PR; 135 value |= GMAC_FRAME_FILTER_PR;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
index efde50ff03f8..19e0f4eed2bc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
@@ -89,7 +89,7 @@ static void dwmac100_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
89 stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW); 89 stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
90} 90}
91 91
92static void dwmac100_set_filter(struct net_device *dev) 92static void dwmac100_set_filter(struct net_device *dev, int id)
93{ 93{
94 void __iomem *ioaddr = (void __iomem *) dev->base_addr; 94 void __iomem *ioaddr = (void __iomem *) dev->base_addr;
95 u32 value = readl(ioaddr + MAC_CONTROL); 95 u32 value = readl(ioaddr + MAC_CONTROL);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
index f20aa12931d0..4e0e18a44fcc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -31,6 +31,8 @@
31#define DWMAC_LIB_DBG(fmt, args...) do { } while (0) 31#define DWMAC_LIB_DBG(fmt, args...) do { } while (0)
32#endif 32#endif
33 33
34#define GMAC_HI_REG_AE 0x80000000
35
34/* CSR1 enables the transmit DMA to check for new descriptor */ 36/* CSR1 enables the transmit DMA to check for new descriptor */
35void dwmac_enable_dma_transmission(void __iomem *ioaddr) 37void dwmac_enable_dma_transmission(void __iomem *ioaddr)
36{ 38{
@@ -233,7 +235,11 @@ void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
233 unsigned long data; 235 unsigned long data;
234 236
235 data = (addr[5] << 8) | addr[4]; 237 data = (addr[5] << 8) | addr[4];
236 writel(data, ioaddr + high); 238 /* For MAC Addr registers se have to set the Address Enable (AE)
239 * bit that has no effect on the High Reg 0 where the bit 31 (MO)
240 * is RO.
241 */
242 writel(data | GMAC_HI_REG_AE, ioaddr + high);
237 data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; 243 data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
238 writel(data, ioaddr + low); 244 writel(data, ioaddr + low);
239} 245}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index db2de9a49952..6b5d060ee9de 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -85,6 +85,7 @@ struct stmmac_priv {
85 struct clk *stmmac_clk; 85 struct clk *stmmac_clk;
86#endif 86#endif
87 int clk_csr; 87 int clk_csr;
88 int synopsys_id;
88}; 89};
89 90
90extern int phyaddr; 91extern int phyaddr;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 1a4cf8128f91..a9699ae49add 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1465,7 +1465,7 @@ static void stmmac_set_rx_mode(struct net_device *dev)
1465 struct stmmac_priv *priv = netdev_priv(dev); 1465 struct stmmac_priv *priv = netdev_priv(dev);
1466 1466
1467 spin_lock(&priv->lock); 1467 spin_lock(&priv->lock);
1468 priv->hw->mac->set_filter(dev); 1468 priv->hw->mac->set_filter(dev, priv->synopsys_id);
1469 spin_unlock(&priv->lock); 1469 spin_unlock(&priv->lock);
1470} 1470}
1471 1471
@@ -1806,7 +1806,7 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
1806 priv->hw->ring = &ring_mode_ops; 1806 priv->hw->ring = &ring_mode_ops;
1807 1807
1808 /* Get and dump the chip ID */ 1808 /* Get and dump the chip ID */
1809 stmmac_get_synopsys_id(priv); 1809 priv->synopsys_id = stmmac_get_synopsys_id(priv);
1810 1810
1811 /* Get the HW capability (new GMAC newer than 3.50a) */ 1811 /* Get the HW capability (new GMAC newer than 3.50a) */
1812 priv->hw_cap_support = stmmac_get_hw_features(priv); 1812 priv->hw_cap_support = stmmac_get_hw_features(priv);