diff options
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/common.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 |
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 | |||
208 | extern const struct stmmac_dma_ops dwmac1000_dma_ops; | 213 | extern 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 | ||
87 | static void dwmac1000_set_filter(struct net_device *dev) | 87 | static 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 | ||
92 | static void dwmac100_set_filter(struct net_device *dev) | 92 | static 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 */ |
35 | void dwmac_enable_dma_transmission(void __iomem *ioaddr) | 37 | void 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 | ||
90 | extern int phyaddr; | 91 | extern 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); |