aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);