1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * |
4 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> |
5 | */ |
6 | |
7 | #include <linux/kernel.h> |
8 | #include <linux/slab.h> |
9 | #include <linux/errno.h> |
10 | #include <linux/types.h> |
11 | #include <linux/interrupt.h> |
12 | #include <linux/uaccess.h> |
13 | #include <linux/in.h> |
14 | #include <linux/netdevice.h> |
15 | #include <linux/etherdevice.h> |
16 | #include <linux/phy.h> |
17 | #include <linux/ip.h> |
18 | #include <linux/tcp.h> |
19 | #include <linux/skbuff.h> |
20 | #include <linux/mm.h> |
21 | #include <linux/platform_device.h> |
22 | #include <linux/ethtool.h> |
23 | #include <linux/init.h> |
24 | #include <linux/delay.h> |
25 | #include <linux/io.h> |
26 | #include <linux/dma-mapping.h> |
27 | #include <linux/module.h> |
28 | #include <linux/property.h> |
29 | |
30 | #include <asm/checksum.h> |
31 | |
32 | #include <lantiq_soc.h> |
33 | #include <xway_dma.h> |
34 | #include <lantiq_platform.h> |
35 | |
36 | #define LTQ_ETOP_MDIO 0x11804 |
37 | #define MDIO_REQUEST 0x80000000 |
38 | #define MDIO_READ 0x40000000 |
39 | #define MDIO_ADDR_MASK 0x1f |
40 | #define MDIO_ADDR_OFFSET 0x15 |
41 | #define MDIO_REG_MASK 0x1f |
42 | #define MDIO_REG_OFFSET 0x10 |
43 | #define MDIO_VAL_MASK 0xffff |
44 | |
45 | #define PPE32_CGEN 0x800 |
46 | #define LQ_PPE32_ENET_MAC_CFG 0x1840 |
47 | |
48 | #define LTQ_ETOP_ENETS0 0x11850 |
49 | #define LTQ_ETOP_MAC_DA0 0x1186C |
50 | #define LTQ_ETOP_MAC_DA1 0x11870 |
51 | #define LTQ_ETOP_CFG 0x16020 |
52 | #define LTQ_ETOP_IGPLEN 0x16080 |
53 | |
54 | #define MAX_DMA_CHAN 0x8 |
55 | #define MAX_DMA_CRC_LEN 0x4 |
56 | #define MAX_DMA_DATA_LEN 0x600 |
57 | |
58 | #define ETOP_FTCU BIT(28) |
59 | #define ETOP_MII_MASK 0xf |
60 | #define ETOP_MII_NORMAL 0xd |
61 | #define ETOP_MII_REVERSE 0xe |
62 | #define ETOP_PLEN_UNDER 0x40 |
63 | #define ETOP_CGEN 0x800 |
64 | |
65 | /* use 2 static channels for TX/RX */ |
66 | #define LTQ_ETOP_TX_CHANNEL 1 |
67 | #define LTQ_ETOP_RX_CHANNEL 6 |
68 | #define IS_TX(x) ((x) == LTQ_ETOP_TX_CHANNEL) |
69 | #define IS_RX(x) ((x) == LTQ_ETOP_RX_CHANNEL) |
70 | |
71 | #define ltq_etop_r32(x) ltq_r32(ltq_etop_membase + (x)) |
72 | #define ltq_etop_w32(x, y) ltq_w32(x, ltq_etop_membase + (y)) |
73 | #define ltq_etop_w32_mask(x, y, z) \ |
74 | ltq_w32_mask(x, y, ltq_etop_membase + (z)) |
75 | |
76 | #define DRV_VERSION "1.0" |
77 | |
78 | static void __iomem *ltq_etop_membase; |
79 | |
80 | struct ltq_etop_chan { |
81 | int idx; |
82 | int tx_free; |
83 | struct net_device *netdev; |
84 | struct napi_struct napi; |
85 | struct ltq_dma_channel dma; |
86 | struct sk_buff *skb[LTQ_DESC_NUM]; |
87 | }; |
88 | |
89 | struct ltq_etop_priv { |
90 | struct net_device *netdev; |
91 | struct platform_device *pdev; |
92 | struct ltq_eth_data *pldata; |
93 | struct resource *res; |
94 | |
95 | struct mii_bus *mii_bus; |
96 | |
97 | struct ltq_etop_chan ch[MAX_DMA_CHAN]; |
98 | int tx_free[MAX_DMA_CHAN >> 1]; |
99 | |
100 | int tx_burst_len; |
101 | int rx_burst_len; |
102 | |
103 | spinlock_t lock; |
104 | }; |
105 | |
106 | static int |
107 | ltq_etop_alloc_skb(struct ltq_etop_chan *ch) |
108 | { |
109 | struct ltq_etop_priv *priv = netdev_priv(dev: ch->netdev); |
110 | |
111 | ch->skb[ch->dma.desc] = netdev_alloc_skb(dev: ch->netdev, MAX_DMA_DATA_LEN); |
112 | if (!ch->skb[ch->dma.desc]) |
113 | return -ENOMEM; |
114 | ch->dma.desc_base[ch->dma.desc].addr = |
115 | dma_map_single(&priv->pdev->dev, ch->skb[ch->dma.desc]->data, |
116 | MAX_DMA_DATA_LEN, DMA_FROM_DEVICE); |
117 | ch->dma.desc_base[ch->dma.desc].addr = |
118 | CPHYSADDR(ch->skb[ch->dma.desc]->data); |
119 | ch->dma.desc_base[ch->dma.desc].ctl = |
120 | LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | |
121 | MAX_DMA_DATA_LEN; |
122 | skb_reserve(skb: ch->skb[ch->dma.desc], NET_IP_ALIGN); |
123 | return 0; |
124 | } |
125 | |
126 | static void |
127 | ltq_etop_hw_receive(struct ltq_etop_chan *ch) |
128 | { |
129 | struct ltq_etop_priv *priv = netdev_priv(dev: ch->netdev); |
130 | struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; |
131 | struct sk_buff *skb = ch->skb[ch->dma.desc]; |
132 | int len = (desc->ctl & LTQ_DMA_SIZE_MASK) - MAX_DMA_CRC_LEN; |
133 | unsigned long flags; |
134 | |
135 | spin_lock_irqsave(&priv->lock, flags); |
136 | if (ltq_etop_alloc_skb(ch)) { |
137 | netdev_err(dev: ch->netdev, |
138 | format: "failed to allocate new rx buffer, stopping DMA\n" ); |
139 | ltq_dma_close(&ch->dma); |
140 | } |
141 | ch->dma.desc++; |
142 | ch->dma.desc %= LTQ_DESC_NUM; |
143 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
144 | |
145 | skb_put(skb, len); |
146 | skb->protocol = eth_type_trans(skb, dev: ch->netdev); |
147 | netif_receive_skb(skb); |
148 | } |
149 | |
150 | static int |
151 | ltq_etop_poll_rx(struct napi_struct *napi, int budget) |
152 | { |
153 | struct ltq_etop_chan *ch = container_of(napi, |
154 | struct ltq_etop_chan, napi); |
155 | int work_done = 0; |
156 | |
157 | while (work_done < budget) { |
158 | struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; |
159 | |
160 | if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) != LTQ_DMA_C) |
161 | break; |
162 | ltq_etop_hw_receive(ch); |
163 | work_done++; |
164 | } |
165 | if (work_done < budget) { |
166 | napi_complete_done(n: &ch->napi, work_done); |
167 | ltq_dma_ack_irq(&ch->dma); |
168 | } |
169 | return work_done; |
170 | } |
171 | |
172 | static int |
173 | ltq_etop_poll_tx(struct napi_struct *napi, int budget) |
174 | { |
175 | struct ltq_etop_chan *ch = |
176 | container_of(napi, struct ltq_etop_chan, napi); |
177 | struct ltq_etop_priv *priv = netdev_priv(dev: ch->netdev); |
178 | struct netdev_queue *txq = |
179 | netdev_get_tx_queue(dev: ch->netdev, index: ch->idx >> 1); |
180 | unsigned long flags; |
181 | |
182 | spin_lock_irqsave(&priv->lock, flags); |
183 | while ((ch->dma.desc_base[ch->tx_free].ctl & |
184 | (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) { |
185 | dev_kfree_skb_any(skb: ch->skb[ch->tx_free]); |
186 | ch->skb[ch->tx_free] = NULL; |
187 | memset(&ch->dma.desc_base[ch->tx_free], 0, |
188 | sizeof(struct ltq_dma_desc)); |
189 | ch->tx_free++; |
190 | ch->tx_free %= LTQ_DESC_NUM; |
191 | } |
192 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
193 | |
194 | if (netif_tx_queue_stopped(dev_queue: txq)) |
195 | netif_tx_start_queue(dev_queue: txq); |
196 | napi_complete(n: &ch->napi); |
197 | ltq_dma_ack_irq(&ch->dma); |
198 | return 1; |
199 | } |
200 | |
201 | static irqreturn_t |
202 | ltq_etop_dma_irq(int irq, void *_priv) |
203 | { |
204 | struct ltq_etop_priv *priv = _priv; |
205 | int ch = irq - LTQ_DMA_CH0_INT; |
206 | |
207 | napi_schedule(n: &priv->ch[ch].napi); |
208 | return IRQ_HANDLED; |
209 | } |
210 | |
211 | static void |
212 | ltq_etop_free_channel(struct net_device *dev, struct ltq_etop_chan *ch) |
213 | { |
214 | struct ltq_etop_priv *priv = netdev_priv(dev); |
215 | |
216 | ltq_dma_free(&ch->dma); |
217 | if (ch->dma.irq) |
218 | free_irq(ch->dma.irq, priv); |
219 | if (IS_RX(ch->idx)) { |
220 | int desc; |
221 | |
222 | for (desc = 0; desc < LTQ_DESC_NUM; desc++) |
223 | dev_kfree_skb_any(skb: ch->skb[ch->dma.desc]); |
224 | } |
225 | } |
226 | |
227 | static void |
228 | ltq_etop_hw_exit(struct net_device *dev) |
229 | { |
230 | struct ltq_etop_priv *priv = netdev_priv(dev); |
231 | int i; |
232 | |
233 | ltq_pmu_disable(PMU_PPE); |
234 | for (i = 0; i < MAX_DMA_CHAN; i++) |
235 | if (IS_TX(i) || IS_RX(i)) |
236 | ltq_etop_free_channel(dev, ch: &priv->ch[i]); |
237 | } |
238 | |
239 | static int |
240 | ltq_etop_hw_init(struct net_device *dev) |
241 | { |
242 | struct ltq_etop_priv *priv = netdev_priv(dev); |
243 | int i; |
244 | int err; |
245 | |
246 | ltq_pmu_enable(PMU_PPE); |
247 | |
248 | switch (priv->pldata->mii_mode) { |
249 | case PHY_INTERFACE_MODE_RMII: |
250 | ltq_etop_w32_mask(ETOP_MII_MASK, ETOP_MII_REVERSE, |
251 | LTQ_ETOP_CFG); |
252 | break; |
253 | |
254 | case PHY_INTERFACE_MODE_MII: |
255 | ltq_etop_w32_mask(ETOP_MII_MASK, ETOP_MII_NORMAL, |
256 | LTQ_ETOP_CFG); |
257 | break; |
258 | |
259 | default: |
260 | netdev_err(dev, format: "unknown mii mode %d\n" , |
261 | priv->pldata->mii_mode); |
262 | return -ENOTSUPP; |
263 | } |
264 | |
265 | /* enable crc generation */ |
266 | ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG); |
267 | |
268 | ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, priv->rx_burst_len); |
269 | |
270 | for (i = 0; i < MAX_DMA_CHAN; i++) { |
271 | int irq = LTQ_DMA_CH0_INT + i; |
272 | struct ltq_etop_chan *ch = &priv->ch[i]; |
273 | |
274 | ch->dma.nr = i; |
275 | ch->idx = ch->dma.nr; |
276 | ch->dma.dev = &priv->pdev->dev; |
277 | |
278 | if (IS_TX(i)) { |
279 | ltq_dma_alloc_tx(&ch->dma); |
280 | err = request_irq(irq, handler: ltq_etop_dma_irq, flags: 0, name: "etop_tx" , dev: priv); |
281 | if (err) { |
282 | netdev_err(dev, |
283 | format: "Unable to get Tx DMA IRQ %d\n" , |
284 | irq); |
285 | return err; |
286 | } |
287 | } else if (IS_RX(i)) { |
288 | ltq_dma_alloc_rx(&ch->dma); |
289 | for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM; |
290 | ch->dma.desc++) |
291 | if (ltq_etop_alloc_skb(ch)) |
292 | return -ENOMEM; |
293 | ch->dma.desc = 0; |
294 | err = request_irq(irq, handler: ltq_etop_dma_irq, flags: 0, name: "etop_rx" , dev: priv); |
295 | if (err) { |
296 | netdev_err(dev, |
297 | format: "Unable to get Rx DMA IRQ %d\n" , |
298 | irq); |
299 | return err; |
300 | } |
301 | } |
302 | ch->dma.irq = irq; |
303 | } |
304 | return 0; |
305 | } |
306 | |
307 | static void |
308 | ltq_etop_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
309 | { |
310 | strscpy(p: info->driver, q: "Lantiq ETOP" , size: sizeof(info->driver)); |
311 | strscpy(p: info->bus_info, q: "internal" , size: sizeof(info->bus_info)); |
312 | strscpy(p: info->version, DRV_VERSION, size: sizeof(info->version)); |
313 | } |
314 | |
315 | static const struct ethtool_ops ltq_etop_ethtool_ops = { |
316 | .get_drvinfo = ltq_etop_get_drvinfo, |
317 | .nway_reset = phy_ethtool_nway_reset, |
318 | .get_link_ksettings = phy_ethtool_get_link_ksettings, |
319 | .set_link_ksettings = phy_ethtool_set_link_ksettings, |
320 | }; |
321 | |
322 | static int |
323 | ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data) |
324 | { |
325 | u32 val = MDIO_REQUEST | |
326 | ((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) | |
327 | ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET) | |
328 | phy_data; |
329 | |
330 | while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST) |
331 | ; |
332 | ltq_etop_w32(val, LTQ_ETOP_MDIO); |
333 | return 0; |
334 | } |
335 | |
336 | static int |
337 | ltq_etop_mdio_rd(struct mii_bus *bus, int phy_addr, int phy_reg) |
338 | { |
339 | u32 val = MDIO_REQUEST | MDIO_READ | |
340 | ((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) | |
341 | ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET); |
342 | |
343 | while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST) |
344 | ; |
345 | ltq_etop_w32(val, LTQ_ETOP_MDIO); |
346 | while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST) |
347 | ; |
348 | val = ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_VAL_MASK; |
349 | return val; |
350 | } |
351 | |
352 | static void |
353 | ltq_etop_mdio_link(struct net_device *dev) |
354 | { |
355 | /* nothing to do */ |
356 | } |
357 | |
358 | static int |
359 | ltq_etop_mdio_probe(struct net_device *dev) |
360 | { |
361 | struct ltq_etop_priv *priv = netdev_priv(dev); |
362 | struct phy_device *phydev; |
363 | |
364 | phydev = phy_find_first(bus: priv->mii_bus); |
365 | |
366 | if (!phydev) { |
367 | netdev_err(dev, format: "no PHY found\n" ); |
368 | return -ENODEV; |
369 | } |
370 | |
371 | phydev = phy_connect(dev, bus_id: phydev_name(phydev), |
372 | handler: <q_etop_mdio_link, interface: priv->pldata->mii_mode); |
373 | |
374 | if (IS_ERR(ptr: phydev)) { |
375 | netdev_err(dev, format: "Could not attach to PHY\n" ); |
376 | return PTR_ERR(ptr: phydev); |
377 | } |
378 | |
379 | phy_set_max_speed(phydev, SPEED_100); |
380 | |
381 | phy_attached_info(phydev); |
382 | |
383 | return 0; |
384 | } |
385 | |
386 | static int |
387 | ltq_etop_mdio_init(struct net_device *dev) |
388 | { |
389 | struct ltq_etop_priv *priv = netdev_priv(dev); |
390 | int err; |
391 | |
392 | priv->mii_bus = mdiobus_alloc(); |
393 | if (!priv->mii_bus) { |
394 | netdev_err(dev, format: "failed to allocate mii bus\n" ); |
395 | err = -ENOMEM; |
396 | goto err_out; |
397 | } |
398 | |
399 | priv->mii_bus->priv = dev; |
400 | priv->mii_bus->read = ltq_etop_mdio_rd; |
401 | priv->mii_bus->write = ltq_etop_mdio_wr; |
402 | priv->mii_bus->name = "ltq_mii" ; |
403 | snprintf(buf: priv->mii_bus->id, MII_BUS_ID_SIZE, fmt: "%s-%x" , |
404 | priv->pdev->name, priv->pdev->id); |
405 | if (mdiobus_register(priv->mii_bus)) { |
406 | err = -ENXIO; |
407 | goto err_out_free_mdiobus; |
408 | } |
409 | |
410 | if (ltq_etop_mdio_probe(dev)) { |
411 | err = -ENXIO; |
412 | goto err_out_unregister_bus; |
413 | } |
414 | return 0; |
415 | |
416 | err_out_unregister_bus: |
417 | mdiobus_unregister(bus: priv->mii_bus); |
418 | err_out_free_mdiobus: |
419 | mdiobus_free(bus: priv->mii_bus); |
420 | err_out: |
421 | return err; |
422 | } |
423 | |
424 | static void |
425 | ltq_etop_mdio_cleanup(struct net_device *dev) |
426 | { |
427 | struct ltq_etop_priv *priv = netdev_priv(dev); |
428 | |
429 | phy_disconnect(phydev: dev->phydev); |
430 | mdiobus_unregister(bus: priv->mii_bus); |
431 | mdiobus_free(bus: priv->mii_bus); |
432 | } |
433 | |
434 | static int |
435 | ltq_etop_open(struct net_device *dev) |
436 | { |
437 | struct ltq_etop_priv *priv = netdev_priv(dev); |
438 | int i; |
439 | |
440 | for (i = 0; i < MAX_DMA_CHAN; i++) { |
441 | struct ltq_etop_chan *ch = &priv->ch[i]; |
442 | |
443 | if (!IS_TX(i) && (!IS_RX(i))) |
444 | continue; |
445 | ltq_dma_open(&ch->dma); |
446 | ltq_dma_enable_irq(&ch->dma); |
447 | napi_enable(n: &ch->napi); |
448 | } |
449 | phy_start(phydev: dev->phydev); |
450 | netif_tx_start_all_queues(dev); |
451 | return 0; |
452 | } |
453 | |
454 | static int |
455 | ltq_etop_stop(struct net_device *dev) |
456 | { |
457 | struct ltq_etop_priv *priv = netdev_priv(dev); |
458 | int i; |
459 | |
460 | netif_tx_stop_all_queues(dev); |
461 | phy_stop(phydev: dev->phydev); |
462 | for (i = 0; i < MAX_DMA_CHAN; i++) { |
463 | struct ltq_etop_chan *ch = &priv->ch[i]; |
464 | |
465 | if (!IS_RX(i) && !IS_TX(i)) |
466 | continue; |
467 | napi_disable(n: &ch->napi); |
468 | ltq_dma_close(&ch->dma); |
469 | } |
470 | return 0; |
471 | } |
472 | |
473 | static netdev_tx_t |
474 | ltq_etop_tx(struct sk_buff *skb, struct net_device *dev) |
475 | { |
476 | int queue = skb_get_queue_mapping(skb); |
477 | struct netdev_queue *txq = netdev_get_tx_queue(dev, index: queue); |
478 | struct ltq_etop_priv *priv = netdev_priv(dev); |
479 | struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1]; |
480 | struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; |
481 | int len; |
482 | unsigned long flags; |
483 | u32 byte_offset; |
484 | |
485 | len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; |
486 | |
487 | if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) { |
488 | netdev_err(dev, format: "tx ring full\n" ); |
489 | netif_tx_stop_queue(dev_queue: txq); |
490 | return NETDEV_TX_BUSY; |
491 | } |
492 | |
493 | /* dma needs to start on a burst length value aligned address */ |
494 | byte_offset = CPHYSADDR(skb->data) % (priv->tx_burst_len * 4); |
495 | ch->skb[ch->dma.desc] = skb; |
496 | |
497 | netif_trans_update(dev); |
498 | |
499 | spin_lock_irqsave(&priv->lock, flags); |
500 | desc->addr = ((unsigned int)dma_map_single(&priv->pdev->dev, skb->data, len, |
501 | DMA_TO_DEVICE)) - byte_offset; |
502 | /* Make sure the address is written before we give it to HW */ |
503 | wmb(); |
504 | desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP | |
505 | LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK); |
506 | ch->dma.desc++; |
507 | ch->dma.desc %= LTQ_DESC_NUM; |
508 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
509 | |
510 | if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN) |
511 | netif_tx_stop_queue(dev_queue: txq); |
512 | |
513 | return NETDEV_TX_OK; |
514 | } |
515 | |
516 | static int |
517 | ltq_etop_change_mtu(struct net_device *dev, int new_mtu) |
518 | { |
519 | struct ltq_etop_priv *priv = netdev_priv(dev); |
520 | unsigned long flags; |
521 | |
522 | dev->mtu = new_mtu; |
523 | |
524 | spin_lock_irqsave(&priv->lock, flags); |
525 | ltq_etop_w32((ETOP_PLEN_UNDER << 16) | new_mtu, LTQ_ETOP_IGPLEN); |
526 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
527 | |
528 | return 0; |
529 | } |
530 | |
531 | static int |
532 | ltq_etop_set_mac_address(struct net_device *dev, void *p) |
533 | { |
534 | int ret = eth_mac_addr(dev, p); |
535 | |
536 | if (!ret) { |
537 | struct ltq_etop_priv *priv = netdev_priv(dev); |
538 | unsigned long flags; |
539 | |
540 | /* store the mac for the unicast filter */ |
541 | spin_lock_irqsave(&priv->lock, flags); |
542 | ltq_etop_w32(*((u32 *)dev->dev_addr), LTQ_ETOP_MAC_DA0); |
543 | ltq_etop_w32(*((u16 *)&dev->dev_addr[4]) << 16, |
544 | LTQ_ETOP_MAC_DA1); |
545 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
546 | } |
547 | return ret; |
548 | } |
549 | |
550 | static void |
551 | ltq_etop_set_multicast_list(struct net_device *dev) |
552 | { |
553 | struct ltq_etop_priv *priv = netdev_priv(dev); |
554 | unsigned long flags; |
555 | |
556 | /* ensure that the unicast filter is not enabled in promiscious mode */ |
557 | spin_lock_irqsave(&priv->lock, flags); |
558 | if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) |
559 | ltq_etop_w32_mask(ETOP_FTCU, 0, LTQ_ETOP_ENETS0); |
560 | else |
561 | ltq_etop_w32_mask(0, ETOP_FTCU, LTQ_ETOP_ENETS0); |
562 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
563 | } |
564 | |
565 | static int |
566 | ltq_etop_init(struct net_device *dev) |
567 | { |
568 | struct ltq_etop_priv *priv = netdev_priv(dev); |
569 | struct sockaddr mac; |
570 | int err; |
571 | bool random_mac = false; |
572 | |
573 | dev->watchdog_timeo = 10 * HZ; |
574 | err = ltq_etop_hw_init(dev); |
575 | if (err) |
576 | goto err_hw; |
577 | ltq_etop_change_mtu(dev, new_mtu: 1500); |
578 | |
579 | memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr)); |
580 | if (!is_valid_ether_addr(addr: mac.sa_data)) { |
581 | pr_warn("etop: invalid MAC, using random\n" ); |
582 | eth_random_addr(addr: mac.sa_data); |
583 | random_mac = true; |
584 | } |
585 | |
586 | err = ltq_etop_set_mac_address(dev, p: &mac); |
587 | if (err) |
588 | goto err_netdev; |
589 | |
590 | /* Set addr_assign_type here, ltq_etop_set_mac_address would reset it. */ |
591 | if (random_mac) |
592 | dev->addr_assign_type = NET_ADDR_RANDOM; |
593 | |
594 | ltq_etop_set_multicast_list(dev); |
595 | err = ltq_etop_mdio_init(dev); |
596 | if (err) |
597 | goto err_netdev; |
598 | return 0; |
599 | |
600 | err_netdev: |
601 | unregister_netdev(dev); |
602 | free_netdev(dev); |
603 | err_hw: |
604 | ltq_etop_hw_exit(dev); |
605 | return err; |
606 | } |
607 | |
608 | static void |
609 | ltq_etop_tx_timeout(struct net_device *dev, unsigned int txqueue) |
610 | { |
611 | int err; |
612 | |
613 | ltq_etop_hw_exit(dev); |
614 | err = ltq_etop_hw_init(dev); |
615 | if (err) |
616 | goto err_hw; |
617 | netif_trans_update(dev); |
618 | netif_wake_queue(dev); |
619 | return; |
620 | |
621 | err_hw: |
622 | ltq_etop_hw_exit(dev); |
623 | netdev_err(dev, format: "failed to restart etop after TX timeout\n" ); |
624 | } |
625 | |
626 | static const struct net_device_ops ltq_eth_netdev_ops = { |
627 | .ndo_open = ltq_etop_open, |
628 | .ndo_stop = ltq_etop_stop, |
629 | .ndo_start_xmit = ltq_etop_tx, |
630 | .ndo_change_mtu = ltq_etop_change_mtu, |
631 | .ndo_eth_ioctl = phy_do_ioctl, |
632 | .ndo_set_mac_address = ltq_etop_set_mac_address, |
633 | .ndo_validate_addr = eth_validate_addr, |
634 | .ndo_set_rx_mode = ltq_etop_set_multicast_list, |
635 | .ndo_select_queue = dev_pick_tx_zero, |
636 | .ndo_init = ltq_etop_init, |
637 | .ndo_tx_timeout = ltq_etop_tx_timeout, |
638 | }; |
639 | |
640 | static int __init |
641 | ltq_etop_probe(struct platform_device *pdev) |
642 | { |
643 | struct net_device *dev; |
644 | struct ltq_etop_priv *priv; |
645 | struct resource *res; |
646 | int err; |
647 | int i; |
648 | |
649 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
650 | if (!res) { |
651 | dev_err(&pdev->dev, "failed to get etop resource\n" ); |
652 | err = -ENOENT; |
653 | goto err_out; |
654 | } |
655 | |
656 | res = devm_request_mem_region(&pdev->dev, res->start, |
657 | resource_size(res), dev_name(&pdev->dev)); |
658 | if (!res) { |
659 | dev_err(&pdev->dev, "failed to request etop resource\n" ); |
660 | err = -EBUSY; |
661 | goto err_out; |
662 | } |
663 | |
664 | ltq_etop_membase = devm_ioremap(dev: &pdev->dev, offset: res->start, |
665 | size: resource_size(res)); |
666 | if (!ltq_etop_membase) { |
667 | dev_err(&pdev->dev, "failed to remap etop engine %d\n" , |
668 | pdev->id); |
669 | err = -ENOMEM; |
670 | goto err_out; |
671 | } |
672 | |
673 | dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4); |
674 | if (!dev) { |
675 | err = -ENOMEM; |
676 | goto err_out; |
677 | } |
678 | strcpy(p: dev->name, q: "eth%d" ); |
679 | dev->netdev_ops = <q_eth_netdev_ops; |
680 | dev->ethtool_ops = <q_etop_ethtool_ops; |
681 | priv = netdev_priv(dev); |
682 | priv->res = res; |
683 | priv->pdev = pdev; |
684 | priv->pldata = dev_get_platdata(dev: &pdev->dev); |
685 | priv->netdev = dev; |
686 | spin_lock_init(&priv->lock); |
687 | SET_NETDEV_DEV(dev, &pdev->dev); |
688 | |
689 | err = device_property_read_u32(dev: &pdev->dev, propname: "lantiq,tx-burst-length" , val: &priv->tx_burst_len); |
690 | if (err < 0) { |
691 | dev_err(&pdev->dev, "unable to read tx-burst-length property\n" ); |
692 | goto err_free; |
693 | } |
694 | |
695 | err = device_property_read_u32(dev: &pdev->dev, propname: "lantiq,rx-burst-length" , val: &priv->rx_burst_len); |
696 | if (err < 0) { |
697 | dev_err(&pdev->dev, "unable to read rx-burst-length property\n" ); |
698 | goto err_free; |
699 | } |
700 | |
701 | for (i = 0; i < MAX_DMA_CHAN; i++) { |
702 | if (IS_TX(i)) |
703 | netif_napi_add_weight(dev, napi: &priv->ch[i].napi, |
704 | poll: ltq_etop_poll_tx, weight: 8); |
705 | else if (IS_RX(i)) |
706 | netif_napi_add_weight(dev, napi: &priv->ch[i].napi, |
707 | poll: ltq_etop_poll_rx, weight: 32); |
708 | priv->ch[i].netdev = dev; |
709 | } |
710 | |
711 | err = register_netdev(dev); |
712 | if (err) |
713 | goto err_free; |
714 | |
715 | platform_set_drvdata(pdev, data: dev); |
716 | return 0; |
717 | |
718 | err_free: |
719 | free_netdev(dev); |
720 | err_out: |
721 | return err; |
722 | } |
723 | |
724 | static void ltq_etop_remove(struct platform_device *pdev) |
725 | { |
726 | struct net_device *dev = platform_get_drvdata(pdev); |
727 | |
728 | if (dev) { |
729 | netif_tx_stop_all_queues(dev); |
730 | ltq_etop_hw_exit(dev); |
731 | ltq_etop_mdio_cleanup(dev); |
732 | unregister_netdev(dev); |
733 | } |
734 | } |
735 | |
736 | static struct platform_driver ltq_mii_driver = { |
737 | .remove_new = ltq_etop_remove, |
738 | .driver = { |
739 | .name = "ltq_etop" , |
740 | }, |
741 | }; |
742 | |
743 | static int __init |
744 | init_ltq_etop(void) |
745 | { |
746 | int ret = platform_driver_probe(<q_mii_driver, ltq_etop_probe); |
747 | |
748 | if (ret) |
749 | pr_err("ltq_etop: Error registering platform driver!" ); |
750 | return ret; |
751 | } |
752 | |
753 | static void __exit |
754 | exit_ltq_etop(void) |
755 | { |
756 | platform_driver_unregister(<q_mii_driver); |
757 | } |
758 | |
759 | module_init(init_ltq_etop); |
760 | module_exit(exit_ltq_etop); |
761 | |
762 | MODULE_AUTHOR("John Crispin <blogic@openwrt.org>" ); |
763 | MODULE_DESCRIPTION("Lantiq SoC ETOP" ); |
764 | MODULE_LICENSE("GPL" ); |
765 | |