1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#include <linux/crc32.h>
30#include <linux/slab.h>
31#include <linux/ethtool.h>
32#include <asm/io.h>
33#include "dwmac1000.h"
34
35static void dwmac1000_core_init(struct mac_device_info *hw, int mtu)
36{
37 void __iomem *ioaddr = hw->pcsr;
38 u32 value = readl(ioaddr + GMAC_CONTROL);
39 value |= GMAC_CORE_INIT;
40 if (mtu > 1500)
41 value |= GMAC_CONTROL_2K;
42 if (mtu > 2000)
43 value |= GMAC_CONTROL_JE;
44
45 writel(value, ioaddr + GMAC_CONTROL);
46
47
48 writel(0x207, ioaddr + GMAC_INT_MASK);
49
50#ifdef STMMAC_VLAN_TAG_USED
51
52 writel(0x0, ioaddr + GMAC_VLAN_TAG);
53#endif
54}
55
56static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw)
57{
58 void __iomem *ioaddr = hw->pcsr;
59 u32 value = readl(ioaddr + GMAC_CONTROL);
60
61 if (hw->rx_csum)
62 value |= GMAC_CONTROL_IPC;
63 else
64 value &= ~GMAC_CONTROL_IPC;
65
66 writel(value, ioaddr + GMAC_CONTROL);
67
68 value = readl(ioaddr + GMAC_CONTROL);
69
70 return !!(value & GMAC_CONTROL_IPC);
71}
72
73static void dwmac1000_dump_regs(struct mac_device_info *hw)
74{
75 void __iomem *ioaddr = hw->pcsr;
76 int i;
77 pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr);
78
79 for (i = 0; i < 55; i++) {
80 int offset = i * 4;
81 pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
82 offset, readl(ioaddr + offset));
83 }
84}
85
86static void dwmac1000_set_umac_addr(struct mac_device_info *hw,
87 unsigned char *addr,
88 unsigned int reg_n)
89{
90 void __iomem *ioaddr = hw->pcsr;
91 stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
92 GMAC_ADDR_LOW(reg_n));
93}
94
95static void dwmac1000_get_umac_addr(struct mac_device_info *hw,
96 unsigned char *addr,
97 unsigned int reg_n)
98{
99 void __iomem *ioaddr = hw->pcsr;
100 stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
101 GMAC_ADDR_LOW(reg_n));
102}
103
104static void dwmac1000_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
105 int mcbitslog2)
106{
107 int numhashregs, regs;
108
109 switch (mcbitslog2) {
110 case 6:
111 writel(mcfilterbits[0], ioaddr + GMAC_HASH_LOW);
112 writel(mcfilterbits[1], ioaddr + GMAC_HASH_HIGH);
113 return;
114 break;
115 case 7:
116 numhashregs = 4;
117 break;
118 case 8:
119 numhashregs = 8;
120 break;
121 default:
122 pr_debug("STMMAC: err in setting mulitcast filter\n");
123 return;
124 break;
125 }
126 for (regs = 0; regs < numhashregs; regs++)
127 writel(mcfilterbits[regs],
128 ioaddr + GMAC_EXTHASH_BASE + regs * 4);
129}
130
131static void dwmac1000_set_filter(struct mac_device_info *hw,
132 struct net_device *dev)
133{
134 void __iomem *ioaddr = (void __iomem *)dev->base_addr;
135 unsigned int value = 0;
136 unsigned int perfect_addr_number = hw->unicast_filter_entries;
137 u32 mc_filter[8];
138 int mcbitslog2 = hw->mcast_bits_log2;
139
140 pr_debug("%s: # mcasts %d, # unicast %d\n", __func__,
141 netdev_mc_count(dev), netdev_uc_count(dev));
142
143 memset(mc_filter, 0, sizeof(mc_filter));
144
145 if (dev->flags & IFF_PROMISC) {
146 value = GMAC_FRAME_FILTER_PR;
147 } else if (dev->flags & IFF_ALLMULTI) {
148 value = GMAC_FRAME_FILTER_PM;
149 } else if (!netdev_mc_empty(dev)) {
150 struct netdev_hw_addr *ha;
151
152
153 value = GMAC_FRAME_FILTER_HMC;
154
155 netdev_for_each_mc_addr(ha, dev) {
156
157
158
159
160
161 int bit_nr = bitrev32(~crc32_le(~0, ha->addr,
162 ETH_ALEN)) >>
163 (32 - mcbitslog2);
164
165
166
167
168 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
169 }
170 }
171
172 dwmac1000_set_mchash(ioaddr, mc_filter, mcbitslog2);
173
174
175 if (netdev_uc_count(dev) > perfect_addr_number)
176
177
178
179 value |= GMAC_FRAME_FILTER_PR;
180 else {
181 int reg = 1;
182 struct netdev_hw_addr *ha;
183
184 netdev_for_each_uc_addr(ha, dev) {
185 stmmac_set_mac_addr(ioaddr, ha->addr,
186 GMAC_ADDR_HIGH(reg),
187 GMAC_ADDR_LOW(reg));
188 reg++;
189 }
190 }
191
192#ifdef FRAME_FILTER_DEBUG
193
194 value |= GMAC_FRAME_FILTER_RA;
195#endif
196 writel(value, ioaddr + GMAC_FRAME_FILTER);
197}
198
199
200static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
201 unsigned int fc, unsigned int pause_time)
202{
203 void __iomem *ioaddr = hw->pcsr;
204
205
206
207 unsigned int flow = GMAC_FLOW_CTRL_UP;
208
209 pr_debug("GMAC Flow-Control:\n");
210 if (fc & FLOW_RX) {
211 pr_debug("\tReceive Flow-Control ON\n");
212 flow |= GMAC_FLOW_CTRL_RFE;
213 }
214 if (fc & FLOW_TX) {
215 pr_debug("\tTransmit Flow-Control ON\n");
216 flow |= GMAC_FLOW_CTRL_TFE;
217 }
218
219 if (duplex) {
220 pr_debug("\tduplex mode: PAUSE %d\n", pause_time);
221 flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
222 }
223
224 writel(flow, ioaddr + GMAC_FLOW_CTRL);
225}
226
227static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
228{
229 void __iomem *ioaddr = hw->pcsr;
230 unsigned int pmt = 0;
231
232 if (mode & WAKE_MAGIC) {
233 pr_debug("GMAC: WOL Magic frame\n");
234 pmt |= power_down | magic_pkt_en;
235 }
236 if (mode & WAKE_UCAST) {
237 pr_debug("GMAC: WOL on global unicast\n");
238 pmt |= global_unicast;
239 }
240
241 writel(pmt, ioaddr + GMAC_PMT);
242}
243
244static int dwmac1000_irq_status(struct mac_device_info *hw,
245 struct stmmac_extra_stats *x)
246{
247 void __iomem *ioaddr = hw->pcsr;
248 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
249 int ret = 0;
250
251
252 if ((intr_status & mmc_tx_irq))
253 x->mmc_tx_irq_n++;
254 if (unlikely(intr_status & mmc_rx_irq))
255 x->mmc_rx_irq_n++;
256 if (unlikely(intr_status & mmc_rx_csum_offload_irq))
257 x->mmc_rx_csum_offload_irq_n++;
258 if (unlikely(intr_status & pmt_irq)) {
259
260 readl(ioaddr + GMAC_PMT);
261 x->irq_receive_pmt_irq_n++;
262 }
263
264 if (intr_status & lpiis_irq) {
265
266 ret = readl(ioaddr + LPI_CTRL_STATUS);
267
268 if (ret & LPI_CTRL_STATUS_TLPIEN)
269 x->irq_tx_path_in_lpi_mode_n++;
270 if (ret & LPI_CTRL_STATUS_TLPIEX)
271 x->irq_tx_path_exit_lpi_mode_n++;
272 if (ret & LPI_CTRL_STATUS_RLPIEN)
273 x->irq_rx_path_in_lpi_mode_n++;
274 if (ret & LPI_CTRL_STATUS_RLPIEX)
275 x->irq_rx_path_exit_lpi_mode_n++;
276 }
277
278 if ((intr_status & pcs_ane_irq) || (intr_status & pcs_link_irq)) {
279 readl(ioaddr + GMAC_AN_STATUS);
280 x->irq_pcs_ane_n++;
281 }
282 if (intr_status & rgmii_irq) {
283 u32 status = readl(ioaddr + GMAC_S_R_GMII);
284 x->irq_rgmii_n++;
285
286
287 if (status & GMAC_S_R_GMII_LINK) {
288 int speed_value = (status & GMAC_S_R_GMII_SPEED) >>
289 GMAC_S_R_GMII_SPEED_SHIFT;
290 x->pcs_duplex = (status & GMAC_S_R_GMII_MODE);
291
292 if (speed_value == GMAC_S_R_GMII_SPEED_125)
293 x->pcs_speed = SPEED_1000;
294 else if (speed_value == GMAC_S_R_GMII_SPEED_25)
295 x->pcs_speed = SPEED_100;
296 else
297 x->pcs_speed = SPEED_10;
298
299 x->pcs_link = 1;
300 pr_debug("%s: Link is Up - %d/%s\n", __func__,
301 (int)x->pcs_speed,
302 x->pcs_duplex ? "Full" : "Half");
303 } else {
304 x->pcs_link = 0;
305 pr_debug("%s: Link is Down\n", __func__);
306 }
307 }
308
309 return ret;
310}
311
312static void dwmac1000_set_eee_mode(struct mac_device_info *hw)
313{
314 void __iomem *ioaddr = hw->pcsr;
315 u32 value;
316
317
318
319
320
321 value = readl(ioaddr + LPI_CTRL_STATUS);
322 value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA;
323 writel(value, ioaddr + LPI_CTRL_STATUS);
324}
325
326static void dwmac1000_reset_eee_mode(struct mac_device_info *hw)
327{
328 void __iomem *ioaddr = hw->pcsr;
329 u32 value;
330
331 value = readl(ioaddr + LPI_CTRL_STATUS);
332 value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA);
333 writel(value, ioaddr + LPI_CTRL_STATUS);
334}
335
336static void dwmac1000_set_eee_pls(struct mac_device_info *hw, int link)
337{
338 void __iomem *ioaddr = hw->pcsr;
339 u32 value;
340
341 value = readl(ioaddr + LPI_CTRL_STATUS);
342
343 if (link)
344 value |= LPI_CTRL_STATUS_PLS;
345 else
346 value &= ~LPI_CTRL_STATUS_PLS;
347
348 writel(value, ioaddr + LPI_CTRL_STATUS);
349}
350
351static void dwmac1000_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
352{
353 void __iomem *ioaddr = hw->pcsr;
354 int value = ((tw & 0xffff)) | ((ls & 0x7ff) << 16);
355
356
357
358
359
360
361
362
363 writel(value, ioaddr + LPI_TIMER_CTRL);
364}
365
366static void dwmac1000_ctrl_ane(struct mac_device_info *hw, bool restart)
367{
368 void __iomem *ioaddr = hw->pcsr;
369
370 u32 value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE;
371
372 if (restart)
373 value |= GMAC_AN_CTRL_RAN;
374
375 writel(value, ioaddr + GMAC_AN_CTRL);
376}
377
378static void dwmac1000_get_adv(struct mac_device_info *hw, struct rgmii_adv *adv)
379{
380 void __iomem *ioaddr = hw->pcsr;
381 u32 value = readl(ioaddr + GMAC_ANE_ADV);
382
383 if (value & GMAC_ANE_FD)
384 adv->duplex = DUPLEX_FULL;
385 if (value & GMAC_ANE_HD)
386 adv->duplex |= DUPLEX_HALF;
387
388 adv->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
389
390 value = readl(ioaddr + GMAC_ANE_LPA);
391
392 if (value & GMAC_ANE_FD)
393 adv->lp_duplex = DUPLEX_FULL;
394 if (value & GMAC_ANE_HD)
395 adv->lp_duplex = DUPLEX_HALF;
396
397 adv->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
398}
399
400static const struct stmmac_ops dwmac1000_ops = {
401 .core_init = dwmac1000_core_init,
402 .rx_ipc = dwmac1000_rx_ipc_enable,
403 .dump_regs = dwmac1000_dump_regs,
404 .host_irq_status = dwmac1000_irq_status,
405 .set_filter = dwmac1000_set_filter,
406 .flow_ctrl = dwmac1000_flow_ctrl,
407 .pmt = dwmac1000_pmt,
408 .set_umac_addr = dwmac1000_set_umac_addr,
409 .get_umac_addr = dwmac1000_get_umac_addr,
410 .set_eee_mode = dwmac1000_set_eee_mode,
411 .reset_eee_mode = dwmac1000_reset_eee_mode,
412 .set_eee_timer = dwmac1000_set_eee_timer,
413 .set_eee_pls = dwmac1000_set_eee_pls,
414 .ctrl_ane = dwmac1000_ctrl_ane,
415 .get_adv = dwmac1000_get_adv,
416};
417
418struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
419 int perfect_uc_entries)
420{
421 struct mac_device_info *mac;
422 u32 hwid = readl(ioaddr + GMAC_VERSION);
423
424 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
425 if (!mac)
426 return NULL;
427
428 mac->pcsr = ioaddr;
429 mac->multicast_filter_bins = mcbins;
430 mac->unicast_filter_entries = perfect_uc_entries;
431 mac->mcast_bits_log2 = 0;
432
433 if (mac->multicast_filter_bins)
434 mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
435
436 mac->mac = &dwmac1000_ops;
437 mac->dma = &dwmac1000_dma_ops;
438
439 mac->link.port = GMAC_CONTROL_PS;
440 mac->link.duplex = GMAC_CONTROL_DM;
441 mac->link.speed = GMAC_CONTROL_FES;
442 mac->mii.addr = GMAC_MII_ADDR;
443 mac->mii.data = GMAC_MII_DATA;
444 mac->synopsys_uid = hwid;
445
446 return mac;
447}
448