1 | /* |
2 | * Allwinner EMAC Fast Ethernet driver for Linux. |
3 | * |
4 | * Copyright 2012-2013 Stefan Roese <sr@denx.de> |
5 | * Copyright 2013 Maxime Ripard <maxime.ripard@free-electrons.com> |
6 | * |
7 | * Based on the Linux driver provided by Allwinner: |
8 | * Copyright (C) 1997 Sten Wang |
9 | * |
10 | * This file is licensed under the terms of the GNU General Public |
11 | * License version 2. This program is licensed "as is" without any |
12 | * warranty of any kind, whether express or implied. |
13 | */ |
14 | |
15 | #include <linux/clk.h> |
16 | #include <linux/etherdevice.h> |
17 | #include <linux/ethtool.h> |
18 | #include <linux/gpio.h> |
19 | #include <linux/interrupt.h> |
20 | #include <linux/irq.h> |
21 | #include <linux/mii.h> |
22 | #include <linux/module.h> |
23 | #include <linux/netdevice.h> |
24 | #include <linux/of_address.h> |
25 | #include <linux/of_irq.h> |
26 | #include <linux/of_mdio.h> |
27 | #include <linux/of_net.h> |
28 | #include <linux/of_platform.h> |
29 | #include <linux/platform_device.h> |
30 | #include <linux/phy.h> |
31 | #include <linux/soc/sunxi/sunxi_sram.h> |
32 | #include <linux/dmaengine.h> |
33 | |
34 | #include "sun4i-emac.h" |
35 | |
36 | #define DRV_NAME "sun4i-emac" |
37 | |
38 | #define EMAC_MAX_FRAME_LEN 0x0600 |
39 | |
40 | #define EMAC_DEFAULT_MSG_ENABLE 0x0000 |
41 | static int debug = -1; /* defaults above */; |
42 | module_param(debug, int, 0); |
43 | MODULE_PARM_DESC(debug, "debug message flags" ); |
44 | |
45 | /* Transmit timeout, default 5 seconds. */ |
46 | static int watchdog = 5000; |
47 | module_param(watchdog, int, 0400); |
48 | MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds" ); |
49 | |
50 | /* EMAC register address locking. |
51 | * |
52 | * The EMAC uses an address register to control where data written |
53 | * to the data register goes. This means that the address register |
54 | * must be preserved over interrupts or similar calls. |
55 | * |
56 | * During interrupt and other critical calls, a spinlock is used to |
57 | * protect the system, but the calls themselves save the address |
58 | * in the address register in case they are interrupting another |
59 | * access to the device. |
60 | * |
61 | * For general accesses a lock is provided so that calls which are |
62 | * allowed to sleep are serialised so that the address register does |
63 | * not need to be saved. This lock also serves to serialise access |
64 | * to the EEPROM and PHY access registers which are shared between |
65 | * these two devices. |
66 | */ |
67 | |
68 | /* The driver supports the original EMACE, and now the two newer |
69 | * devices, EMACA and EMACB. |
70 | */ |
71 | |
72 | struct emac_board_info { |
73 | struct clk *clk; |
74 | struct device *dev; |
75 | struct platform_device *pdev; |
76 | spinlock_t lock; |
77 | void __iomem *membase; |
78 | u32 msg_enable; |
79 | struct net_device *ndev; |
80 | u16 tx_fifo_stat; |
81 | |
82 | int emacrx_completed_flag; |
83 | |
84 | struct device_node *phy_node; |
85 | unsigned int link; |
86 | unsigned int speed; |
87 | unsigned int duplex; |
88 | |
89 | phy_interface_t phy_interface; |
90 | struct dma_chan *rx_chan; |
91 | phys_addr_t emac_rx_fifo; |
92 | }; |
93 | |
94 | struct emac_dma_req { |
95 | struct emac_board_info *db; |
96 | struct dma_async_tx_descriptor *desc; |
97 | struct sk_buff *skb; |
98 | dma_addr_t rxbuf; |
99 | int count; |
100 | }; |
101 | |
102 | static void emac_update_speed(struct net_device *dev) |
103 | { |
104 | struct emac_board_info *db = netdev_priv(dev); |
105 | unsigned int reg_val; |
106 | |
107 | /* set EMAC SPEED, depend on PHY */ |
108 | reg_val = readl(addr: db->membase + EMAC_MAC_SUPP_REG); |
109 | reg_val &= ~EMAC_MAC_SUPP_100M; |
110 | if (db->speed == SPEED_100) |
111 | reg_val |= EMAC_MAC_SUPP_100M; |
112 | writel(val: reg_val, addr: db->membase + EMAC_MAC_SUPP_REG); |
113 | } |
114 | |
115 | static void emac_update_duplex(struct net_device *dev) |
116 | { |
117 | struct emac_board_info *db = netdev_priv(dev); |
118 | unsigned int reg_val; |
119 | |
120 | /* set duplex depend on phy */ |
121 | reg_val = readl(addr: db->membase + EMAC_MAC_CTL1_REG); |
122 | reg_val &= ~EMAC_MAC_CTL1_DUPLEX_EN; |
123 | if (db->duplex) |
124 | reg_val |= EMAC_MAC_CTL1_DUPLEX_EN; |
125 | writel(val: reg_val, addr: db->membase + EMAC_MAC_CTL1_REG); |
126 | } |
127 | |
128 | static void emac_handle_link_change(struct net_device *dev) |
129 | { |
130 | struct emac_board_info *db = netdev_priv(dev); |
131 | struct phy_device *phydev = dev->phydev; |
132 | unsigned long flags; |
133 | int status_change = 0; |
134 | |
135 | if (phydev->link) { |
136 | if (db->speed != phydev->speed) { |
137 | spin_lock_irqsave(&db->lock, flags); |
138 | db->speed = phydev->speed; |
139 | emac_update_speed(dev); |
140 | spin_unlock_irqrestore(lock: &db->lock, flags); |
141 | status_change = 1; |
142 | } |
143 | |
144 | if (db->duplex != phydev->duplex) { |
145 | spin_lock_irqsave(&db->lock, flags); |
146 | db->duplex = phydev->duplex; |
147 | emac_update_duplex(dev); |
148 | spin_unlock_irqrestore(lock: &db->lock, flags); |
149 | status_change = 1; |
150 | } |
151 | } |
152 | |
153 | if (phydev->link != db->link) { |
154 | if (!phydev->link) { |
155 | db->speed = 0; |
156 | db->duplex = -1; |
157 | } |
158 | db->link = phydev->link; |
159 | |
160 | status_change = 1; |
161 | } |
162 | |
163 | if (status_change) |
164 | phy_print_status(phydev); |
165 | } |
166 | |
167 | static int emac_mdio_probe(struct net_device *dev) |
168 | { |
169 | struct emac_board_info *db = netdev_priv(dev); |
170 | struct phy_device *phydev; |
171 | |
172 | /* to-do: PHY interrupts are currently not supported */ |
173 | |
174 | /* attach the mac to the phy */ |
175 | phydev = of_phy_connect(dev: db->ndev, phy_np: db->phy_node, |
176 | hndlr: &emac_handle_link_change, flags: 0, |
177 | iface: db->phy_interface); |
178 | if (!phydev) { |
179 | netdev_err(dev: db->ndev, format: "could not find the PHY\n" ); |
180 | return -ENODEV; |
181 | } |
182 | |
183 | /* mask with MAC supported features */ |
184 | phy_set_max_speed(phydev, SPEED_100); |
185 | |
186 | db->link = 0; |
187 | db->speed = 0; |
188 | db->duplex = -1; |
189 | |
190 | return 0; |
191 | } |
192 | |
193 | static void emac_mdio_remove(struct net_device *dev) |
194 | { |
195 | phy_disconnect(phydev: dev->phydev); |
196 | } |
197 | |
198 | static void emac_reset(struct emac_board_info *db) |
199 | { |
200 | dev_dbg(db->dev, "resetting device\n" ); |
201 | |
202 | /* RESET device */ |
203 | writel(val: 0, addr: db->membase + EMAC_CTL_REG); |
204 | udelay(200); |
205 | writel(EMAC_CTL_RESET, addr: db->membase + EMAC_CTL_REG); |
206 | udelay(200); |
207 | } |
208 | |
209 | static void emac_outblk_32bit(void __iomem *reg, void *data, int count) |
210 | { |
211 | writesl(addr: reg, buffer: data, round_up(count, 4) / 4); |
212 | } |
213 | |
214 | static void emac_inblk_32bit(void __iomem *reg, void *data, int count) |
215 | { |
216 | readsl(addr: reg, buffer: data, round_up(count, 4) / 4); |
217 | } |
218 | |
219 | static struct emac_dma_req * |
220 | emac_alloc_dma_req(struct emac_board_info *db, |
221 | struct dma_async_tx_descriptor *desc, struct sk_buff *skb, |
222 | dma_addr_t rxbuf, int count) |
223 | { |
224 | struct emac_dma_req *req; |
225 | |
226 | req = kzalloc(size: sizeof(struct emac_dma_req), GFP_ATOMIC); |
227 | if (!req) |
228 | return NULL; |
229 | |
230 | req->db = db; |
231 | req->desc = desc; |
232 | req->skb = skb; |
233 | req->rxbuf = rxbuf; |
234 | req->count = count; |
235 | return req; |
236 | } |
237 | |
238 | static void emac_free_dma_req(struct emac_dma_req *req) |
239 | { |
240 | kfree(objp: req); |
241 | } |
242 | |
243 | static void emac_dma_done_callback(void *arg) |
244 | { |
245 | struct emac_dma_req *req = arg; |
246 | struct emac_board_info *db = req->db; |
247 | struct sk_buff *skb = req->skb; |
248 | struct net_device *dev = db->ndev; |
249 | int rxlen = req->count; |
250 | u32 reg_val; |
251 | |
252 | dma_unmap_single(db->dev, req->rxbuf, rxlen, DMA_FROM_DEVICE); |
253 | |
254 | skb->protocol = eth_type_trans(skb, dev); |
255 | netif_rx(skb); |
256 | dev->stats.rx_bytes += rxlen; |
257 | /* Pass to upper layer */ |
258 | dev->stats.rx_packets++; |
259 | |
260 | /* re enable cpu receive */ |
261 | reg_val = readl(addr: db->membase + EMAC_RX_CTL_REG); |
262 | reg_val &= ~EMAC_RX_CTL_DMA_EN; |
263 | writel(val: reg_val, addr: db->membase + EMAC_RX_CTL_REG); |
264 | |
265 | /* re enable interrupt */ |
266 | reg_val = readl(addr: db->membase + EMAC_INT_CTL_REG); |
267 | reg_val |= EMAC_INT_CTL_RX_EN; |
268 | writel(val: reg_val, addr: db->membase + EMAC_INT_CTL_REG); |
269 | |
270 | db->emacrx_completed_flag = 1; |
271 | emac_free_dma_req(req); |
272 | } |
273 | |
274 | static int emac_dma_inblk_32bit(struct emac_board_info *db, |
275 | struct sk_buff *skb, void *rdptr, int count) |
276 | { |
277 | struct dma_async_tx_descriptor *desc; |
278 | dma_cookie_t cookie; |
279 | dma_addr_t rxbuf; |
280 | struct emac_dma_req *req; |
281 | int ret = 0; |
282 | |
283 | rxbuf = dma_map_single(db->dev, rdptr, count, DMA_FROM_DEVICE); |
284 | ret = dma_mapping_error(dev: db->dev, dma_addr: rxbuf); |
285 | if (ret) { |
286 | dev_err(db->dev, "dma mapping error.\n" ); |
287 | return ret; |
288 | } |
289 | |
290 | desc = dmaengine_prep_slave_single(chan: db->rx_chan, buf: rxbuf, len: count, |
291 | dir: DMA_DEV_TO_MEM, |
292 | flags: DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
293 | if (!desc) { |
294 | dev_err(db->dev, "prepare slave single failed\n" ); |
295 | ret = -ENOMEM; |
296 | goto prepare_err; |
297 | } |
298 | |
299 | req = emac_alloc_dma_req(db, desc, skb, rxbuf, count); |
300 | if (!req) { |
301 | dev_err(db->dev, "alloc emac dma req error.\n" ); |
302 | ret = -ENOMEM; |
303 | goto alloc_req_err; |
304 | } |
305 | |
306 | desc->callback_param = req; |
307 | desc->callback = emac_dma_done_callback; |
308 | |
309 | cookie = dmaengine_submit(desc); |
310 | ret = dma_submit_error(cookie); |
311 | if (ret) { |
312 | dev_err(db->dev, "dma submit error.\n" ); |
313 | goto submit_err; |
314 | } |
315 | |
316 | dma_async_issue_pending(chan: db->rx_chan); |
317 | return ret; |
318 | |
319 | submit_err: |
320 | emac_free_dma_req(req); |
321 | |
322 | alloc_req_err: |
323 | dmaengine_desc_free(desc); |
324 | |
325 | prepare_err: |
326 | dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE); |
327 | return ret; |
328 | } |
329 | |
330 | /* ethtool ops */ |
331 | static void emac_get_drvinfo(struct net_device *dev, |
332 | struct ethtool_drvinfo *info) |
333 | { |
334 | strscpy(info->driver, DRV_NAME, sizeof(info->driver)); |
335 | strscpy(info->bus_info, dev_name(&dev->dev), sizeof(info->bus_info)); |
336 | } |
337 | |
338 | static u32 emac_get_msglevel(struct net_device *dev) |
339 | { |
340 | struct emac_board_info *db = netdev_priv(dev); |
341 | |
342 | return db->msg_enable; |
343 | } |
344 | |
345 | static void emac_set_msglevel(struct net_device *dev, u32 value) |
346 | { |
347 | struct emac_board_info *db = netdev_priv(dev); |
348 | |
349 | db->msg_enable = value; |
350 | } |
351 | |
352 | static const struct ethtool_ops emac_ethtool_ops = { |
353 | .get_drvinfo = emac_get_drvinfo, |
354 | .get_link = ethtool_op_get_link, |
355 | .get_link_ksettings = phy_ethtool_get_link_ksettings, |
356 | .set_link_ksettings = phy_ethtool_set_link_ksettings, |
357 | .get_msglevel = emac_get_msglevel, |
358 | .set_msglevel = emac_set_msglevel, |
359 | }; |
360 | |
361 | static unsigned int emac_setup(struct net_device *ndev) |
362 | { |
363 | struct emac_board_info *db = netdev_priv(dev: ndev); |
364 | unsigned int reg_val; |
365 | |
366 | /* set up TX */ |
367 | reg_val = readl(addr: db->membase + EMAC_TX_MODE_REG); |
368 | |
369 | writel(val: reg_val | EMAC_TX_MODE_ABORTED_FRAME_EN, |
370 | addr: db->membase + EMAC_TX_MODE_REG); |
371 | |
372 | /* set MAC */ |
373 | /* set MAC CTL0 */ |
374 | reg_val = readl(addr: db->membase + EMAC_MAC_CTL0_REG); |
375 | writel(val: reg_val | EMAC_MAC_CTL0_RX_FLOW_CTL_EN | |
376 | EMAC_MAC_CTL0_TX_FLOW_CTL_EN, |
377 | addr: db->membase + EMAC_MAC_CTL0_REG); |
378 | |
379 | /* set MAC CTL1 */ |
380 | reg_val = readl(addr: db->membase + EMAC_MAC_CTL1_REG); |
381 | reg_val |= EMAC_MAC_CTL1_LEN_CHECK_EN; |
382 | reg_val |= EMAC_MAC_CTL1_CRC_EN; |
383 | reg_val |= EMAC_MAC_CTL1_PAD_EN; |
384 | writel(val: reg_val, addr: db->membase + EMAC_MAC_CTL1_REG); |
385 | |
386 | /* set up IPGT */ |
387 | writel(EMAC_MAC_IPGT_FULL_DUPLEX, addr: db->membase + EMAC_MAC_IPGT_REG); |
388 | |
389 | /* set up IPGR */ |
390 | writel(val: (EMAC_MAC_IPGR_IPG1 << 8) | EMAC_MAC_IPGR_IPG2, |
391 | addr: db->membase + EMAC_MAC_IPGR_REG); |
392 | |
393 | /* set up Collison window */ |
394 | writel(val: (EMAC_MAC_CLRT_COLLISION_WINDOW << 8) | EMAC_MAC_CLRT_RM, |
395 | addr: db->membase + EMAC_MAC_CLRT_REG); |
396 | |
397 | /* set up Max Frame Length */ |
398 | writel(EMAC_MAX_FRAME_LEN, |
399 | addr: db->membase + EMAC_MAC_MAXF_REG); |
400 | |
401 | return 0; |
402 | } |
403 | |
404 | static void emac_set_rx_mode(struct net_device *ndev) |
405 | { |
406 | struct emac_board_info *db = netdev_priv(dev: ndev); |
407 | unsigned int reg_val; |
408 | |
409 | /* set up RX */ |
410 | reg_val = readl(addr: db->membase + EMAC_RX_CTL_REG); |
411 | |
412 | if (ndev->flags & IFF_PROMISC) |
413 | reg_val |= EMAC_RX_CTL_PASS_ALL_EN; |
414 | else |
415 | reg_val &= ~EMAC_RX_CTL_PASS_ALL_EN; |
416 | |
417 | writel(val: reg_val | EMAC_RX_CTL_PASS_LEN_OOR_EN | |
418 | EMAC_RX_CTL_ACCEPT_UNICAST_EN | EMAC_RX_CTL_DA_FILTER_EN | |
419 | EMAC_RX_CTL_ACCEPT_MULTICAST_EN | |
420 | EMAC_RX_CTL_ACCEPT_BROADCAST_EN, |
421 | addr: db->membase + EMAC_RX_CTL_REG); |
422 | } |
423 | |
424 | static unsigned int emac_powerup(struct net_device *ndev) |
425 | { |
426 | struct emac_board_info *db = netdev_priv(dev: ndev); |
427 | unsigned int reg_val; |
428 | |
429 | /* initial EMAC */ |
430 | /* flush RX FIFO */ |
431 | reg_val = readl(addr: db->membase + EMAC_RX_CTL_REG); |
432 | reg_val |= EMAC_RX_CTL_FLUSH_FIFO; |
433 | writel(val: reg_val, addr: db->membase + EMAC_RX_CTL_REG); |
434 | udelay(1); |
435 | |
436 | /* initial MAC */ |
437 | /* soft reset MAC */ |
438 | reg_val = readl(addr: db->membase + EMAC_MAC_CTL0_REG); |
439 | reg_val &= ~EMAC_MAC_CTL0_SOFT_RESET; |
440 | writel(val: reg_val, addr: db->membase + EMAC_MAC_CTL0_REG); |
441 | |
442 | /* set MII clock */ |
443 | reg_val = readl(addr: db->membase + EMAC_MAC_MCFG_REG); |
444 | reg_val &= ~EMAC_MAC_MCFG_MII_CLKD_MASK; |
445 | reg_val |= EMAC_MAC_MCFG_MII_CLKD_72; |
446 | writel(val: reg_val, addr: db->membase + EMAC_MAC_MCFG_REG); |
447 | |
448 | /* clear RX counter */ |
449 | writel(val: 0x0, addr: db->membase + EMAC_RX_FBC_REG); |
450 | |
451 | /* disable all interrupt and clear interrupt status */ |
452 | writel(val: 0, addr: db->membase + EMAC_INT_CTL_REG); |
453 | reg_val = readl(addr: db->membase + EMAC_INT_STA_REG); |
454 | writel(val: reg_val, addr: db->membase + EMAC_INT_STA_REG); |
455 | |
456 | udelay(1); |
457 | |
458 | /* set up EMAC */ |
459 | emac_setup(ndev); |
460 | |
461 | /* set mac_address to chip */ |
462 | writel(val: ndev->dev_addr[0] << 16 | ndev->dev_addr[1] << 8 | ndev-> |
463 | dev_addr[2], addr: db->membase + EMAC_MAC_A1_REG); |
464 | writel(val: ndev->dev_addr[3] << 16 | ndev->dev_addr[4] << 8 | ndev-> |
465 | dev_addr[5], addr: db->membase + EMAC_MAC_A0_REG); |
466 | |
467 | mdelay(1); |
468 | |
469 | return 0; |
470 | } |
471 | |
472 | static int emac_set_mac_address(struct net_device *dev, void *p) |
473 | { |
474 | struct sockaddr *addr = p; |
475 | struct emac_board_info *db = netdev_priv(dev); |
476 | |
477 | if (netif_running(dev)) |
478 | return -EBUSY; |
479 | |
480 | eth_hw_addr_set(dev, addr: addr->sa_data); |
481 | |
482 | writel(val: dev->dev_addr[0] << 16 | dev->dev_addr[1] << 8 | dev-> |
483 | dev_addr[2], addr: db->membase + EMAC_MAC_A1_REG); |
484 | writel(val: dev->dev_addr[3] << 16 | dev->dev_addr[4] << 8 | dev-> |
485 | dev_addr[5], addr: db->membase + EMAC_MAC_A0_REG); |
486 | |
487 | return 0; |
488 | } |
489 | |
490 | /* Initialize emac board */ |
491 | static void emac_init_device(struct net_device *dev) |
492 | { |
493 | struct emac_board_info *db = netdev_priv(dev); |
494 | unsigned long flags; |
495 | unsigned int reg_val; |
496 | |
497 | spin_lock_irqsave(&db->lock, flags); |
498 | |
499 | emac_update_speed(dev); |
500 | emac_update_duplex(dev); |
501 | |
502 | /* enable RX/TX */ |
503 | reg_val = readl(addr: db->membase + EMAC_CTL_REG); |
504 | writel(val: reg_val | EMAC_CTL_RESET | EMAC_CTL_TX_EN | EMAC_CTL_RX_EN, |
505 | addr: db->membase + EMAC_CTL_REG); |
506 | |
507 | /* enable RX/TX0/RX Hlevel interrup */ |
508 | reg_val = readl(addr: db->membase + EMAC_INT_CTL_REG); |
509 | reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN); |
510 | writel(val: reg_val, addr: db->membase + EMAC_INT_CTL_REG); |
511 | |
512 | spin_unlock_irqrestore(lock: &db->lock, flags); |
513 | } |
514 | |
515 | /* Our watchdog timed out. Called by the networking layer */ |
516 | static void emac_timeout(struct net_device *dev, unsigned int txqueue) |
517 | { |
518 | struct emac_board_info *db = netdev_priv(dev); |
519 | unsigned long flags; |
520 | |
521 | if (netif_msg_timer(db)) |
522 | dev_err(db->dev, "tx time out.\n" ); |
523 | |
524 | /* Save previous register address */ |
525 | spin_lock_irqsave(&db->lock, flags); |
526 | |
527 | netif_stop_queue(dev); |
528 | emac_reset(db); |
529 | emac_init_device(dev); |
530 | /* We can accept TX packets again */ |
531 | netif_trans_update(dev); |
532 | netif_wake_queue(dev); |
533 | |
534 | /* Restore previous register address */ |
535 | spin_unlock_irqrestore(lock: &db->lock, flags); |
536 | } |
537 | |
538 | /* Hardware start transmission. |
539 | * Send a packet to media from the upper layer. |
540 | */ |
541 | static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev) |
542 | { |
543 | struct emac_board_info *db = netdev_priv(dev); |
544 | unsigned long channel; |
545 | unsigned long flags; |
546 | |
547 | channel = db->tx_fifo_stat & 3; |
548 | if (channel == 3) |
549 | return NETDEV_TX_BUSY; |
550 | |
551 | channel = (channel == 1 ? 1 : 0); |
552 | |
553 | spin_lock_irqsave(&db->lock, flags); |
554 | |
555 | writel(val: channel, addr: db->membase + EMAC_TX_INS_REG); |
556 | |
557 | emac_outblk_32bit(reg: db->membase + EMAC_TX_IO_DATA_REG, |
558 | data: skb->data, count: skb->len); |
559 | dev->stats.tx_bytes += skb->len; |
560 | |
561 | db->tx_fifo_stat |= 1 << channel; |
562 | /* TX control: First packet immediately send, second packet queue */ |
563 | if (channel == 0) { |
564 | /* set TX len */ |
565 | writel(val: skb->len, addr: db->membase + EMAC_TX_PL0_REG); |
566 | /* start translate from fifo to phy */ |
567 | writel(readl(addr: db->membase + EMAC_TX_CTL0_REG) | 1, |
568 | addr: db->membase + EMAC_TX_CTL0_REG); |
569 | |
570 | /* save the time stamp */ |
571 | netif_trans_update(dev); |
572 | } else if (channel == 1) { |
573 | /* set TX len */ |
574 | writel(val: skb->len, addr: db->membase + EMAC_TX_PL1_REG); |
575 | /* start translate from fifo to phy */ |
576 | writel(readl(addr: db->membase + EMAC_TX_CTL1_REG) | 1, |
577 | addr: db->membase + EMAC_TX_CTL1_REG); |
578 | |
579 | /* save the time stamp */ |
580 | netif_trans_update(dev); |
581 | } |
582 | |
583 | if ((db->tx_fifo_stat & 3) == 3) { |
584 | /* Second packet */ |
585 | netif_stop_queue(dev); |
586 | } |
587 | |
588 | spin_unlock_irqrestore(lock: &db->lock, flags); |
589 | |
590 | /* free this SKB */ |
591 | dev_consume_skb_any(skb); |
592 | |
593 | return NETDEV_TX_OK; |
594 | } |
595 | |
596 | /* EMAC interrupt handler |
597 | * receive the packet to upper layer, free the transmitted packet |
598 | */ |
599 | static void emac_tx_done(struct net_device *dev, struct emac_board_info *db, |
600 | unsigned int tx_status) |
601 | { |
602 | /* One packet sent complete */ |
603 | db->tx_fifo_stat &= ~(tx_status & 3); |
604 | if (3 == (tx_status & 3)) |
605 | dev->stats.tx_packets += 2; |
606 | else |
607 | dev->stats.tx_packets++; |
608 | |
609 | if (netif_msg_tx_done(db)) |
610 | dev_dbg(db->dev, "tx done, NSR %02x\n" , tx_status); |
611 | |
612 | netif_wake_queue(dev); |
613 | } |
614 | |
615 | /* Received a packet and pass to upper layer |
616 | */ |
617 | static void emac_rx(struct net_device *dev) |
618 | { |
619 | struct emac_board_info *db = netdev_priv(dev); |
620 | struct sk_buff *skb; |
621 | u8 *rdptr; |
622 | bool good_packet; |
623 | unsigned int reg_val; |
624 | u32 rxhdr, rxstatus, rxcount, rxlen; |
625 | |
626 | /* Check packet ready or not */ |
627 | while (1) { |
628 | /* race warning: the first packet might arrive with |
629 | * the interrupts disabled, but the second will fix |
630 | * it |
631 | */ |
632 | rxcount = readl(addr: db->membase + EMAC_RX_FBC_REG); |
633 | |
634 | if (netif_msg_rx_status(db)) |
635 | dev_dbg(db->dev, "RXCount: %x\n" , rxcount); |
636 | |
637 | if (!rxcount) { |
638 | db->emacrx_completed_flag = 1; |
639 | reg_val = readl(addr: db->membase + EMAC_INT_CTL_REG); |
640 | reg_val |= (EMAC_INT_CTL_TX_EN | |
641 | EMAC_INT_CTL_TX_ABRT_EN | |
642 | EMAC_INT_CTL_RX_EN); |
643 | writel(val: reg_val, addr: db->membase + EMAC_INT_CTL_REG); |
644 | |
645 | /* had one stuck? */ |
646 | rxcount = readl(addr: db->membase + EMAC_RX_FBC_REG); |
647 | if (!rxcount) |
648 | return; |
649 | } |
650 | |
651 | reg_val = readl(addr: db->membase + EMAC_RX_IO_DATA_REG); |
652 | if (netif_msg_rx_status(db)) |
653 | dev_dbg(db->dev, "receive header: %x\n" , reg_val); |
654 | if (reg_val != EMAC_UNDOCUMENTED_MAGIC) { |
655 | /* disable RX */ |
656 | reg_val = readl(addr: db->membase + EMAC_CTL_REG); |
657 | writel(val: reg_val & ~EMAC_CTL_RX_EN, |
658 | addr: db->membase + EMAC_CTL_REG); |
659 | |
660 | /* Flush RX FIFO */ |
661 | reg_val = readl(addr: db->membase + EMAC_RX_CTL_REG); |
662 | writel(val: reg_val | (1 << 3), |
663 | addr: db->membase + EMAC_RX_CTL_REG); |
664 | |
665 | do { |
666 | reg_val = readl(addr: db->membase + EMAC_RX_CTL_REG); |
667 | } while (reg_val & (1 << 3)); |
668 | |
669 | /* enable RX */ |
670 | reg_val = readl(addr: db->membase + EMAC_CTL_REG); |
671 | writel(val: reg_val | EMAC_CTL_RX_EN, |
672 | addr: db->membase + EMAC_CTL_REG); |
673 | reg_val = readl(addr: db->membase + EMAC_INT_CTL_REG); |
674 | reg_val |= (EMAC_INT_CTL_TX_EN | |
675 | EMAC_INT_CTL_TX_ABRT_EN | |
676 | EMAC_INT_CTL_RX_EN); |
677 | writel(val: reg_val, addr: db->membase + EMAC_INT_CTL_REG); |
678 | |
679 | db->emacrx_completed_flag = 1; |
680 | |
681 | return; |
682 | } |
683 | |
684 | /* A packet ready now & Get status/length */ |
685 | good_packet = true; |
686 | |
687 | rxhdr = readl(addr: db->membase + EMAC_RX_IO_DATA_REG); |
688 | |
689 | if (netif_msg_rx_status(db)) |
690 | dev_dbg(db->dev, "rxhdr: %x\n" , *((int *)(&rxhdr))); |
691 | |
692 | rxlen = EMAC_RX_IO_DATA_LEN(rxhdr); |
693 | rxstatus = EMAC_RX_IO_DATA_STATUS(rxhdr); |
694 | |
695 | if (netif_msg_rx_status(db)) |
696 | dev_dbg(db->dev, "RX: status %02x, length %04x\n" , |
697 | rxstatus, rxlen); |
698 | |
699 | /* Packet Status check */ |
700 | if (rxlen < 0x40) { |
701 | good_packet = false; |
702 | if (netif_msg_rx_err(db)) |
703 | dev_dbg(db->dev, "RX: Bad Packet (runt)\n" ); |
704 | } |
705 | |
706 | if (unlikely(!(rxstatus & EMAC_RX_IO_DATA_STATUS_OK))) { |
707 | good_packet = false; |
708 | |
709 | if (rxstatus & EMAC_RX_IO_DATA_STATUS_CRC_ERR) { |
710 | if (netif_msg_rx_err(db)) |
711 | dev_dbg(db->dev, "crc error\n" ); |
712 | dev->stats.rx_crc_errors++; |
713 | } |
714 | |
715 | if (rxstatus & EMAC_RX_IO_DATA_STATUS_LEN_ERR) { |
716 | if (netif_msg_rx_err(db)) |
717 | dev_dbg(db->dev, "length error\n" ); |
718 | dev->stats.rx_length_errors++; |
719 | } |
720 | } |
721 | |
722 | /* Move data from EMAC */ |
723 | if (good_packet) { |
724 | skb = netdev_alloc_skb(dev, length: rxlen + 4); |
725 | if (!skb) |
726 | continue; |
727 | skb_reserve(skb, len: 2); |
728 | rdptr = skb_put(skb, len: rxlen - 4); |
729 | |
730 | /* Read received packet from RX SRAM */ |
731 | if (netif_msg_rx_status(db)) |
732 | dev_dbg(db->dev, "RxLen %x\n" , rxlen); |
733 | |
734 | if (rxlen >= dev->mtu && db->rx_chan) { |
735 | reg_val = readl(addr: db->membase + EMAC_RX_CTL_REG); |
736 | reg_val |= EMAC_RX_CTL_DMA_EN; |
737 | writel(val: reg_val, addr: db->membase + EMAC_RX_CTL_REG); |
738 | if (!emac_dma_inblk_32bit(db, skb, rdptr, count: rxlen)) |
739 | break; |
740 | |
741 | /* re enable cpu receive. then try to receive by emac_inblk_32bit */ |
742 | reg_val = readl(addr: db->membase + EMAC_RX_CTL_REG); |
743 | reg_val &= ~EMAC_RX_CTL_DMA_EN; |
744 | writel(val: reg_val, addr: db->membase + EMAC_RX_CTL_REG); |
745 | } |
746 | |
747 | emac_inblk_32bit(reg: db->membase + EMAC_RX_IO_DATA_REG, |
748 | data: rdptr, count: rxlen); |
749 | dev->stats.rx_bytes += rxlen; |
750 | |
751 | /* Pass to upper layer */ |
752 | skb->protocol = eth_type_trans(skb, dev); |
753 | netif_rx(skb); |
754 | dev->stats.rx_packets++; |
755 | } |
756 | } |
757 | } |
758 | |
759 | static irqreturn_t emac_interrupt(int irq, void *dev_id) |
760 | { |
761 | struct net_device *dev = dev_id; |
762 | struct emac_board_info *db = netdev_priv(dev); |
763 | int int_status; |
764 | unsigned int reg_val; |
765 | |
766 | /* A real interrupt coming */ |
767 | |
768 | spin_lock(lock: &db->lock); |
769 | |
770 | /* Disable all interrupts */ |
771 | writel(val: 0, addr: db->membase + EMAC_INT_CTL_REG); |
772 | |
773 | /* Got EMAC interrupt status */ |
774 | /* Got ISR */ |
775 | int_status = readl(addr: db->membase + EMAC_INT_STA_REG); |
776 | /* Clear ISR status */ |
777 | writel(val: int_status, addr: db->membase + EMAC_INT_STA_REG); |
778 | |
779 | if (netif_msg_intr(db)) |
780 | dev_dbg(db->dev, "emac interrupt %02x\n" , int_status); |
781 | |
782 | /* Received the coming packet */ |
783 | if ((int_status & 0x100) && (db->emacrx_completed_flag == 1)) { |
784 | /* carrier lost */ |
785 | db->emacrx_completed_flag = 0; |
786 | emac_rx(dev); |
787 | } |
788 | |
789 | /* Transmit Interrupt check */ |
790 | if (int_status & EMAC_INT_STA_TX_COMPLETE) |
791 | emac_tx_done(dev, db, tx_status: int_status); |
792 | |
793 | if (int_status & EMAC_INT_STA_TX_ABRT) |
794 | netdev_info(dev, format: " ab : %x\n" , int_status); |
795 | |
796 | /* Re-enable interrupt mask */ |
797 | if (db->emacrx_completed_flag == 1) { |
798 | reg_val = readl(addr: db->membase + EMAC_INT_CTL_REG); |
799 | reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN); |
800 | writel(val: reg_val, addr: db->membase + EMAC_INT_CTL_REG); |
801 | } else { |
802 | reg_val = readl(addr: db->membase + EMAC_INT_CTL_REG); |
803 | reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN); |
804 | writel(val: reg_val, addr: db->membase + EMAC_INT_CTL_REG); |
805 | } |
806 | |
807 | spin_unlock(lock: &db->lock); |
808 | |
809 | return IRQ_HANDLED; |
810 | } |
811 | |
812 | #ifdef CONFIG_NET_POLL_CONTROLLER |
813 | /* |
814 | * Used by netconsole |
815 | */ |
816 | static void emac_poll_controller(struct net_device *dev) |
817 | { |
818 | disable_irq(irq: dev->irq); |
819 | emac_interrupt(irq: dev->irq, dev_id: dev); |
820 | enable_irq(irq: dev->irq); |
821 | } |
822 | #endif |
823 | |
824 | /* Open the interface. |
825 | * The interface is opened whenever "ifconfig" actives it. |
826 | */ |
827 | static int emac_open(struct net_device *dev) |
828 | { |
829 | struct emac_board_info *db = netdev_priv(dev); |
830 | int ret; |
831 | |
832 | if (netif_msg_ifup(db)) |
833 | dev_dbg(db->dev, "enabling %s\n" , dev->name); |
834 | |
835 | if (request_irq(irq: dev->irq, handler: &emac_interrupt, flags: 0, name: dev->name, dev)) |
836 | return -EAGAIN; |
837 | |
838 | /* Initialize EMAC board */ |
839 | emac_reset(db); |
840 | emac_init_device(dev); |
841 | |
842 | ret = emac_mdio_probe(dev); |
843 | if (ret < 0) { |
844 | free_irq(dev->irq, dev); |
845 | netdev_err(dev, format: "cannot probe MDIO bus\n" ); |
846 | return ret; |
847 | } |
848 | |
849 | phy_start(phydev: dev->phydev); |
850 | netif_start_queue(dev); |
851 | |
852 | return 0; |
853 | } |
854 | |
855 | static void emac_shutdown(struct net_device *dev) |
856 | { |
857 | unsigned int reg_val; |
858 | struct emac_board_info *db = netdev_priv(dev); |
859 | |
860 | /* Disable all interrupt */ |
861 | writel(val: 0, addr: db->membase + EMAC_INT_CTL_REG); |
862 | |
863 | /* clear interrupt status */ |
864 | reg_val = readl(addr: db->membase + EMAC_INT_STA_REG); |
865 | writel(val: reg_val, addr: db->membase + EMAC_INT_STA_REG); |
866 | |
867 | /* Disable RX/TX */ |
868 | reg_val = readl(addr: db->membase + EMAC_CTL_REG); |
869 | reg_val &= ~(EMAC_CTL_TX_EN | EMAC_CTL_RX_EN | EMAC_CTL_RESET); |
870 | writel(val: reg_val, addr: db->membase + EMAC_CTL_REG); |
871 | } |
872 | |
873 | /* Stop the interface. |
874 | * The interface is stopped when it is brought. |
875 | */ |
876 | static int emac_stop(struct net_device *ndev) |
877 | { |
878 | struct emac_board_info *db = netdev_priv(dev: ndev); |
879 | |
880 | if (netif_msg_ifdown(db)) |
881 | dev_dbg(db->dev, "shutting down %s\n" , ndev->name); |
882 | |
883 | netif_stop_queue(dev: ndev); |
884 | netif_carrier_off(dev: ndev); |
885 | |
886 | phy_stop(phydev: ndev->phydev); |
887 | |
888 | emac_mdio_remove(dev: ndev); |
889 | |
890 | emac_shutdown(dev: ndev); |
891 | |
892 | free_irq(ndev->irq, ndev); |
893 | |
894 | return 0; |
895 | } |
896 | |
897 | static const struct net_device_ops emac_netdev_ops = { |
898 | .ndo_open = emac_open, |
899 | .ndo_stop = emac_stop, |
900 | .ndo_start_xmit = emac_start_xmit, |
901 | .ndo_tx_timeout = emac_timeout, |
902 | .ndo_set_rx_mode = emac_set_rx_mode, |
903 | .ndo_eth_ioctl = phy_do_ioctl_running, |
904 | .ndo_validate_addr = eth_validate_addr, |
905 | .ndo_set_mac_address = emac_set_mac_address, |
906 | #ifdef CONFIG_NET_POLL_CONTROLLER |
907 | .ndo_poll_controller = emac_poll_controller, |
908 | #endif |
909 | }; |
910 | |
911 | static int emac_configure_dma(struct emac_board_info *db) |
912 | { |
913 | struct platform_device *pdev = db->pdev; |
914 | struct net_device *ndev = db->ndev; |
915 | struct dma_slave_config conf = {}; |
916 | struct resource *regs; |
917 | int err = 0; |
918 | |
919 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
920 | if (!regs) { |
921 | netdev_err(dev: ndev, format: "get io resource from device failed.\n" ); |
922 | err = -ENOMEM; |
923 | goto out_clear_chan; |
924 | } |
925 | |
926 | netdev_info(dev: ndev, format: "get io resource from device: %pa, size = %u\n" , |
927 | ®s->start, (unsigned int)resource_size(res: regs)); |
928 | db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG; |
929 | |
930 | db->rx_chan = dma_request_chan(dev: &pdev->dev, name: "rx" ); |
931 | if (IS_ERR(ptr: db->rx_chan)) { |
932 | netdev_err(dev: ndev, |
933 | format: "failed to request dma channel. dma is disabled\n" ); |
934 | err = PTR_ERR(ptr: db->rx_chan); |
935 | goto out_clear_chan; |
936 | } |
937 | |
938 | conf.direction = DMA_DEV_TO_MEM; |
939 | conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
940 | conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
941 | conf.src_addr = db->emac_rx_fifo; |
942 | conf.dst_maxburst = 4; |
943 | conf.src_maxburst = 4; |
944 | conf.device_fc = false; |
945 | |
946 | err = dmaengine_slave_config(chan: db->rx_chan, config: &conf); |
947 | if (err) { |
948 | netdev_err(dev: ndev, format: "config dma slave failed\n" ); |
949 | err = -EINVAL; |
950 | goto out_slave_configure_err; |
951 | } |
952 | |
953 | return err; |
954 | |
955 | out_slave_configure_err: |
956 | dma_release_channel(chan: db->rx_chan); |
957 | |
958 | out_clear_chan: |
959 | db->rx_chan = NULL; |
960 | return err; |
961 | } |
962 | |
963 | /* Search EMAC board, allocate space and register it |
964 | */ |
965 | static int emac_probe(struct platform_device *pdev) |
966 | { |
967 | struct device_node *np = pdev->dev.of_node; |
968 | struct emac_board_info *db; |
969 | struct net_device *ndev; |
970 | int ret = 0; |
971 | |
972 | ndev = alloc_etherdev(sizeof(struct emac_board_info)); |
973 | if (!ndev) { |
974 | dev_err(&pdev->dev, "could not allocate device.\n" ); |
975 | return -ENOMEM; |
976 | } |
977 | |
978 | SET_NETDEV_DEV(ndev, &pdev->dev); |
979 | |
980 | db = netdev_priv(dev: ndev); |
981 | |
982 | db->dev = &pdev->dev; |
983 | db->ndev = ndev; |
984 | db->pdev = pdev; |
985 | db->msg_enable = netif_msg_init(debug_value: debug, EMAC_DEFAULT_MSG_ENABLE); |
986 | |
987 | spin_lock_init(&db->lock); |
988 | |
989 | db->membase = of_iomap(node: np, index: 0); |
990 | if (!db->membase) { |
991 | dev_err(&pdev->dev, "failed to remap registers\n" ); |
992 | ret = -ENOMEM; |
993 | goto out; |
994 | } |
995 | |
996 | /* fill in parameters for net-dev structure */ |
997 | ndev->base_addr = (unsigned long)db->membase; |
998 | ndev->irq = irq_of_parse_and_map(node: np, index: 0); |
999 | if (ndev->irq == -ENXIO) { |
1000 | netdev_err(dev: ndev, format: "No irq resource\n" ); |
1001 | ret = ndev->irq; |
1002 | goto out_iounmap; |
1003 | } |
1004 | |
1005 | if (emac_configure_dma(db)) |
1006 | netdev_info(dev: ndev, format: "configure dma failed. disable dma.\n" ); |
1007 | |
1008 | db->clk = devm_clk_get(dev: &pdev->dev, NULL); |
1009 | if (IS_ERR(ptr: db->clk)) { |
1010 | ret = PTR_ERR(ptr: db->clk); |
1011 | goto out_dispose_mapping; |
1012 | } |
1013 | |
1014 | ret = clk_prepare_enable(clk: db->clk); |
1015 | if (ret) { |
1016 | dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n" , ret); |
1017 | goto out_dispose_mapping; |
1018 | } |
1019 | |
1020 | ret = sunxi_sram_claim(dev: &pdev->dev); |
1021 | if (ret) { |
1022 | dev_err(&pdev->dev, "Error couldn't map SRAM to device\n" ); |
1023 | goto out_clk_disable_unprepare; |
1024 | } |
1025 | |
1026 | db->phy_node = of_parse_phandle(np, phandle_name: "phy-handle" , index: 0); |
1027 | if (!db->phy_node) |
1028 | db->phy_node = of_parse_phandle(np, phandle_name: "phy" , index: 0); |
1029 | if (!db->phy_node) { |
1030 | dev_err(&pdev->dev, "no associated PHY\n" ); |
1031 | ret = -ENODEV; |
1032 | goto out_release_sram; |
1033 | } |
1034 | |
1035 | /* Read MAC-address from DT */ |
1036 | ret = of_get_ethdev_address(np, dev: ndev); |
1037 | if (ret) { |
1038 | /* if the MAC address is invalid get a random one */ |
1039 | eth_hw_addr_random(dev: ndev); |
1040 | dev_warn(&pdev->dev, "using random MAC address %pM\n" , |
1041 | ndev->dev_addr); |
1042 | } |
1043 | |
1044 | db->emacrx_completed_flag = 1; |
1045 | emac_powerup(ndev); |
1046 | emac_reset(db); |
1047 | |
1048 | ndev->netdev_ops = &emac_netdev_ops; |
1049 | ndev->watchdog_timeo = msecs_to_jiffies(m: watchdog); |
1050 | ndev->ethtool_ops = &emac_ethtool_ops; |
1051 | |
1052 | platform_set_drvdata(pdev, data: ndev); |
1053 | |
1054 | /* Carrier starts down, phylib will bring it up */ |
1055 | netif_carrier_off(dev: ndev); |
1056 | |
1057 | ret = register_netdev(dev: ndev); |
1058 | if (ret) { |
1059 | dev_err(&pdev->dev, "Registering netdev failed!\n" ); |
1060 | ret = -ENODEV; |
1061 | goto out_release_sram; |
1062 | } |
1063 | |
1064 | dev_info(&pdev->dev, "%s: at %p, IRQ %d MAC: %pM\n" , |
1065 | ndev->name, db->membase, ndev->irq, ndev->dev_addr); |
1066 | |
1067 | return 0; |
1068 | |
1069 | out_release_sram: |
1070 | sunxi_sram_release(dev: &pdev->dev); |
1071 | out_clk_disable_unprepare: |
1072 | clk_disable_unprepare(clk: db->clk); |
1073 | out_dispose_mapping: |
1074 | irq_dispose_mapping(virq: ndev->irq); |
1075 | dma_release_channel(chan: db->rx_chan); |
1076 | out_iounmap: |
1077 | iounmap(addr: db->membase); |
1078 | out: |
1079 | dev_err(db->dev, "not found (%d).\n" , ret); |
1080 | |
1081 | free_netdev(dev: ndev); |
1082 | |
1083 | return ret; |
1084 | } |
1085 | |
1086 | static void emac_remove(struct platform_device *pdev) |
1087 | { |
1088 | struct net_device *ndev = platform_get_drvdata(pdev); |
1089 | struct emac_board_info *db = netdev_priv(dev: ndev); |
1090 | |
1091 | if (db->rx_chan) { |
1092 | dmaengine_terminate_all(chan: db->rx_chan); |
1093 | dma_release_channel(chan: db->rx_chan); |
1094 | } |
1095 | |
1096 | unregister_netdev(dev: ndev); |
1097 | sunxi_sram_release(dev: &pdev->dev); |
1098 | clk_disable_unprepare(clk: db->clk); |
1099 | irq_dispose_mapping(virq: ndev->irq); |
1100 | iounmap(addr: db->membase); |
1101 | free_netdev(dev: ndev); |
1102 | |
1103 | dev_dbg(&pdev->dev, "released and freed device\n" ); |
1104 | } |
1105 | |
1106 | static int emac_suspend(struct platform_device *dev, pm_message_t state) |
1107 | { |
1108 | struct net_device *ndev = platform_get_drvdata(pdev: dev); |
1109 | |
1110 | netif_carrier_off(dev: ndev); |
1111 | netif_device_detach(dev: ndev); |
1112 | emac_shutdown(dev: ndev); |
1113 | |
1114 | return 0; |
1115 | } |
1116 | |
1117 | static int emac_resume(struct platform_device *dev) |
1118 | { |
1119 | struct net_device *ndev = platform_get_drvdata(pdev: dev); |
1120 | struct emac_board_info *db = netdev_priv(dev: ndev); |
1121 | |
1122 | emac_reset(db); |
1123 | emac_init_device(dev: ndev); |
1124 | netif_device_attach(dev: ndev); |
1125 | |
1126 | return 0; |
1127 | } |
1128 | |
1129 | static const struct of_device_id emac_of_match[] = { |
1130 | {.compatible = "allwinner,sun4i-a10-emac" ,}, |
1131 | |
1132 | /* Deprecated */ |
1133 | {.compatible = "allwinner,sun4i-emac" ,}, |
1134 | {}, |
1135 | }; |
1136 | |
1137 | MODULE_DEVICE_TABLE(of, emac_of_match); |
1138 | |
1139 | static struct platform_driver emac_driver = { |
1140 | .driver = { |
1141 | .name = "sun4i-emac" , |
1142 | .of_match_table = emac_of_match, |
1143 | }, |
1144 | .probe = emac_probe, |
1145 | .remove_new = emac_remove, |
1146 | .suspend = emac_suspend, |
1147 | .resume = emac_resume, |
1148 | }; |
1149 | |
1150 | module_platform_driver(emac_driver); |
1151 | |
1152 | MODULE_AUTHOR("Stefan Roese <sr@denx.de>" ); |
1153 | MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>" ); |
1154 | MODULE_DESCRIPTION("Allwinner A10 emac network driver" ); |
1155 | MODULE_LICENSE("GPL" ); |
1156 | |