1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Applied Micro X-Gene SoC Ethernet v2 Driver |
4 | * |
5 | * Copyright (c) 2017, Applied Micro Circuits Corporation |
6 | * Author(s): Iyappan Subramanian <isubramanian@apm.com> |
7 | * Keyur Chudgar <kchudgar@apm.com> |
8 | */ |
9 | |
10 | #include "main.h" |
11 | |
12 | static const struct acpi_device_id xge_acpi_match[]; |
13 | |
14 | static int xge_get_resources(struct xge_pdata *pdata) |
15 | { |
16 | struct platform_device *pdev; |
17 | struct net_device *ndev; |
18 | int phy_mode, ret = 0; |
19 | struct resource *res; |
20 | struct device *dev; |
21 | |
22 | pdev = pdata->pdev; |
23 | dev = &pdev->dev; |
24 | ndev = pdata->ndev; |
25 | |
26 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
27 | if (!res) { |
28 | dev_err(dev, "Resource enet_csr not defined\n" ); |
29 | return -ENODEV; |
30 | } |
31 | |
32 | pdata->resources.base_addr = devm_ioremap(dev, offset: res->start, |
33 | size: resource_size(res)); |
34 | if (!pdata->resources.base_addr) { |
35 | dev_err(dev, "Unable to retrieve ENET Port CSR region\n" ); |
36 | return -ENOMEM; |
37 | } |
38 | |
39 | if (device_get_ethdev_address(dev, netdev: ndev)) |
40 | eth_hw_addr_random(dev: ndev); |
41 | |
42 | memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len); |
43 | |
44 | phy_mode = device_get_phy_mode(dev); |
45 | if (phy_mode < 0) { |
46 | dev_err(dev, "Unable to get phy-connection-type\n" ); |
47 | return phy_mode; |
48 | } |
49 | pdata->resources.phy_mode = phy_mode; |
50 | |
51 | if (pdata->resources.phy_mode != PHY_INTERFACE_MODE_RGMII) { |
52 | dev_err(dev, "Incorrect phy-connection-type specified\n" ); |
53 | return -ENODEV; |
54 | } |
55 | |
56 | ret = platform_get_irq(pdev, 0); |
57 | if (ret < 0) |
58 | return ret; |
59 | pdata->resources.irq = ret; |
60 | |
61 | return 0; |
62 | } |
63 | |
64 | static int xge_refill_buffers(struct net_device *ndev, u32 nbuf) |
65 | { |
66 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
67 | struct xge_desc_ring *ring = pdata->rx_ring; |
68 | const u8 slots = XGENE_ENET_NUM_DESC - 1; |
69 | struct device *dev = &pdata->pdev->dev; |
70 | struct xge_raw_desc *raw_desc; |
71 | u64 addr_lo, addr_hi; |
72 | u8 tail = ring->tail; |
73 | struct sk_buff *skb; |
74 | dma_addr_t dma_addr; |
75 | u16 len; |
76 | int i; |
77 | |
78 | for (i = 0; i < nbuf; i++) { |
79 | raw_desc = &ring->raw_desc[tail]; |
80 | |
81 | len = XGENE_ENET_STD_MTU; |
82 | skb = netdev_alloc_skb(dev: ndev, length: len); |
83 | if (unlikely(!skb)) |
84 | return -ENOMEM; |
85 | |
86 | dma_addr = dma_map_single(dev, skb->data, len, DMA_FROM_DEVICE); |
87 | if (dma_mapping_error(dev, dma_addr)) { |
88 | netdev_err(dev: ndev, format: "DMA mapping error\n" ); |
89 | dev_kfree_skb_any(skb); |
90 | return -EINVAL; |
91 | } |
92 | |
93 | ring->pkt_info[tail].skb = skb; |
94 | ring->pkt_info[tail].dma_addr = dma_addr; |
95 | |
96 | addr_hi = GET_BITS(NEXT_DESC_ADDRH, le64_to_cpu(raw_desc->m1)); |
97 | addr_lo = GET_BITS(NEXT_DESC_ADDRL, le64_to_cpu(raw_desc->m1)); |
98 | raw_desc->m1 = cpu_to_le64(SET_BITS(NEXT_DESC_ADDRL, addr_lo) | |
99 | SET_BITS(NEXT_DESC_ADDRH, addr_hi) | |
100 | SET_BITS(PKT_ADDRH, |
101 | upper_32_bits(dma_addr))); |
102 | |
103 | dma_wmb(); |
104 | raw_desc->m0 = cpu_to_le64(SET_BITS(PKT_ADDRL, dma_addr) | |
105 | SET_BITS(E, 1)); |
106 | tail = (tail + 1) & slots; |
107 | } |
108 | |
109 | ring->tail = tail; |
110 | |
111 | return 0; |
112 | } |
113 | |
114 | static int xge_init_hw(struct net_device *ndev) |
115 | { |
116 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
117 | int ret; |
118 | |
119 | ret = xge_port_reset(ndev); |
120 | if (ret) |
121 | return ret; |
122 | |
123 | xge_port_init(ndev); |
124 | pdata->nbufs = NUM_BUFS; |
125 | |
126 | return 0; |
127 | } |
128 | |
129 | static irqreturn_t xge_irq(const int irq, void *data) |
130 | { |
131 | struct xge_pdata *pdata = data; |
132 | |
133 | if (napi_schedule_prep(n: &pdata->napi)) { |
134 | xge_intr_disable(pdata); |
135 | __napi_schedule(n: &pdata->napi); |
136 | } |
137 | |
138 | return IRQ_HANDLED; |
139 | } |
140 | |
141 | static int xge_request_irq(struct net_device *ndev) |
142 | { |
143 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
144 | int ret; |
145 | |
146 | snprintf(buf: pdata->irq_name, IRQ_ID_SIZE, fmt: "%s" , ndev->name); |
147 | |
148 | ret = request_irq(irq: pdata->resources.irq, handler: xge_irq, flags: 0, name: pdata->irq_name, |
149 | dev: pdata); |
150 | if (ret) |
151 | netdev_err(dev: ndev, format: "Failed to request irq %s\n" , pdata->irq_name); |
152 | |
153 | return ret; |
154 | } |
155 | |
156 | static void xge_free_irq(struct net_device *ndev) |
157 | { |
158 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
159 | |
160 | free_irq(pdata->resources.irq, pdata); |
161 | } |
162 | |
163 | static bool is_tx_slot_available(struct xge_raw_desc *raw_desc) |
164 | { |
165 | if (GET_BITS(E, le64_to_cpu(raw_desc->m0)) && |
166 | (GET_BITS(PKT_SIZE, le64_to_cpu(raw_desc->m0)) == SLOT_EMPTY)) |
167 | return true; |
168 | |
169 | return false; |
170 | } |
171 | |
172 | static netdev_tx_t xge_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
173 | { |
174 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
175 | struct device *dev = &pdata->pdev->dev; |
176 | struct xge_desc_ring *tx_ring; |
177 | struct xge_raw_desc *raw_desc; |
178 | static dma_addr_t dma_addr; |
179 | u64 addr_lo, addr_hi; |
180 | void *pkt_buf; |
181 | u8 tail; |
182 | u16 len; |
183 | |
184 | tx_ring = pdata->tx_ring; |
185 | tail = tx_ring->tail; |
186 | len = skb_headlen(skb); |
187 | raw_desc = &tx_ring->raw_desc[tail]; |
188 | |
189 | if (!is_tx_slot_available(raw_desc)) { |
190 | netif_stop_queue(dev: ndev); |
191 | return NETDEV_TX_BUSY; |
192 | } |
193 | |
194 | /* Packet buffers should be 64B aligned */ |
195 | pkt_buf = dma_alloc_coherent(dev, XGENE_ENET_STD_MTU, dma_handle: &dma_addr, |
196 | GFP_ATOMIC); |
197 | if (unlikely(!pkt_buf)) { |
198 | dev_kfree_skb_any(skb); |
199 | return NETDEV_TX_OK; |
200 | } |
201 | memcpy(pkt_buf, skb->data, len); |
202 | |
203 | addr_hi = GET_BITS(NEXT_DESC_ADDRH, le64_to_cpu(raw_desc->m1)); |
204 | addr_lo = GET_BITS(NEXT_DESC_ADDRL, le64_to_cpu(raw_desc->m1)); |
205 | raw_desc->m1 = cpu_to_le64(SET_BITS(NEXT_DESC_ADDRL, addr_lo) | |
206 | SET_BITS(NEXT_DESC_ADDRH, addr_hi) | |
207 | SET_BITS(PKT_ADDRH, |
208 | upper_32_bits(dma_addr))); |
209 | |
210 | tx_ring->pkt_info[tail].skb = skb; |
211 | tx_ring->pkt_info[tail].dma_addr = dma_addr; |
212 | tx_ring->pkt_info[tail].pkt_buf = pkt_buf; |
213 | |
214 | dma_wmb(); |
215 | |
216 | raw_desc->m0 = cpu_to_le64(SET_BITS(PKT_ADDRL, dma_addr) | |
217 | SET_BITS(PKT_SIZE, len) | |
218 | SET_BITS(E, 0)); |
219 | skb_tx_timestamp(skb); |
220 | xge_wr_csr(pdata, DMATXCTRL, val: 1); |
221 | |
222 | tx_ring->tail = (tail + 1) & (XGENE_ENET_NUM_DESC - 1); |
223 | |
224 | return NETDEV_TX_OK; |
225 | } |
226 | |
227 | static bool is_tx_hw_done(struct xge_raw_desc *raw_desc) |
228 | { |
229 | if (GET_BITS(E, le64_to_cpu(raw_desc->m0)) && |
230 | !GET_BITS(PKT_SIZE, le64_to_cpu(raw_desc->m0))) |
231 | return true; |
232 | |
233 | return false; |
234 | } |
235 | |
236 | static void xge_txc_poll(struct net_device *ndev) |
237 | { |
238 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
239 | struct device *dev = &pdata->pdev->dev; |
240 | struct xge_desc_ring *tx_ring; |
241 | struct xge_raw_desc *raw_desc; |
242 | dma_addr_t dma_addr; |
243 | struct sk_buff *skb; |
244 | void *pkt_buf; |
245 | u32 data; |
246 | u8 head; |
247 | |
248 | tx_ring = pdata->tx_ring; |
249 | head = tx_ring->head; |
250 | |
251 | data = xge_rd_csr(pdata, DMATXSTATUS); |
252 | if (!GET_BITS(TXPKTCOUNT, data)) |
253 | return; |
254 | |
255 | while (1) { |
256 | raw_desc = &tx_ring->raw_desc[head]; |
257 | |
258 | if (!is_tx_hw_done(raw_desc)) |
259 | break; |
260 | |
261 | dma_rmb(); |
262 | |
263 | skb = tx_ring->pkt_info[head].skb; |
264 | dma_addr = tx_ring->pkt_info[head].dma_addr; |
265 | pkt_buf = tx_ring->pkt_info[head].pkt_buf; |
266 | pdata->stats.tx_packets++; |
267 | pdata->stats.tx_bytes += skb->len; |
268 | dma_free_coherent(dev, XGENE_ENET_STD_MTU, cpu_addr: pkt_buf, dma_handle: dma_addr); |
269 | dev_kfree_skb_any(skb); |
270 | |
271 | /* clear pktstart address and pktsize */ |
272 | raw_desc->m0 = cpu_to_le64(SET_BITS(E, 1) | |
273 | SET_BITS(PKT_SIZE, SLOT_EMPTY)); |
274 | xge_wr_csr(pdata, DMATXSTATUS, val: 1); |
275 | |
276 | head = (head + 1) & (XGENE_ENET_NUM_DESC - 1); |
277 | } |
278 | |
279 | if (netif_queue_stopped(dev: ndev)) |
280 | netif_wake_queue(dev: ndev); |
281 | |
282 | tx_ring->head = head; |
283 | } |
284 | |
285 | static int xge_rx_poll(struct net_device *ndev, unsigned int budget) |
286 | { |
287 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
288 | struct device *dev = &pdata->pdev->dev; |
289 | struct xge_desc_ring *rx_ring; |
290 | struct xge_raw_desc *raw_desc; |
291 | struct sk_buff *skb; |
292 | dma_addr_t dma_addr; |
293 | int processed = 0; |
294 | u8 head, rx_error; |
295 | int i, ret; |
296 | u32 data; |
297 | u16 len; |
298 | |
299 | rx_ring = pdata->rx_ring; |
300 | head = rx_ring->head; |
301 | |
302 | data = xge_rd_csr(pdata, DMARXSTATUS); |
303 | if (!GET_BITS(RXPKTCOUNT, data)) |
304 | return 0; |
305 | |
306 | for (i = 0; i < budget; i++) { |
307 | raw_desc = &rx_ring->raw_desc[head]; |
308 | |
309 | if (GET_BITS(E, le64_to_cpu(raw_desc->m0))) |
310 | break; |
311 | |
312 | dma_rmb(); |
313 | |
314 | skb = rx_ring->pkt_info[head].skb; |
315 | rx_ring->pkt_info[head].skb = NULL; |
316 | dma_addr = rx_ring->pkt_info[head].dma_addr; |
317 | len = GET_BITS(PKT_SIZE, le64_to_cpu(raw_desc->m0)); |
318 | dma_unmap_single(dev, dma_addr, XGENE_ENET_STD_MTU, |
319 | DMA_FROM_DEVICE); |
320 | |
321 | rx_error = GET_BITS(D, le64_to_cpu(raw_desc->m2)); |
322 | if (unlikely(rx_error)) { |
323 | pdata->stats.rx_errors++; |
324 | dev_kfree_skb_any(skb); |
325 | goto out; |
326 | } |
327 | |
328 | skb_put(skb, len); |
329 | skb->protocol = eth_type_trans(skb, dev: ndev); |
330 | |
331 | pdata->stats.rx_packets++; |
332 | pdata->stats.rx_bytes += len; |
333 | napi_gro_receive(napi: &pdata->napi, skb); |
334 | out: |
335 | ret = xge_refill_buffers(ndev, nbuf: 1); |
336 | xge_wr_csr(pdata, DMARXSTATUS, val: 1); |
337 | xge_wr_csr(pdata, DMARXCTRL, val: 1); |
338 | |
339 | if (ret) |
340 | break; |
341 | |
342 | head = (head + 1) & (XGENE_ENET_NUM_DESC - 1); |
343 | processed++; |
344 | } |
345 | |
346 | rx_ring->head = head; |
347 | |
348 | return processed; |
349 | } |
350 | |
351 | static void xge_delete_desc_ring(struct net_device *ndev, |
352 | struct xge_desc_ring *ring) |
353 | { |
354 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
355 | struct device *dev = &pdata->pdev->dev; |
356 | u16 size; |
357 | |
358 | if (!ring) |
359 | return; |
360 | |
361 | size = XGENE_ENET_DESC_SIZE * XGENE_ENET_NUM_DESC; |
362 | if (ring->desc_addr) |
363 | dma_free_coherent(dev, size, cpu_addr: ring->desc_addr, dma_handle: ring->dma_addr); |
364 | |
365 | kfree(objp: ring->pkt_info); |
366 | kfree(objp: ring); |
367 | } |
368 | |
369 | static void xge_free_buffers(struct net_device *ndev) |
370 | { |
371 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
372 | struct xge_desc_ring *ring = pdata->rx_ring; |
373 | struct device *dev = &pdata->pdev->dev; |
374 | struct sk_buff *skb; |
375 | dma_addr_t dma_addr; |
376 | int i; |
377 | |
378 | for (i = 0; i < XGENE_ENET_NUM_DESC; i++) { |
379 | skb = ring->pkt_info[i].skb; |
380 | dma_addr = ring->pkt_info[i].dma_addr; |
381 | |
382 | if (!skb) |
383 | continue; |
384 | |
385 | dma_unmap_single(dev, dma_addr, XGENE_ENET_STD_MTU, |
386 | DMA_FROM_DEVICE); |
387 | dev_kfree_skb_any(skb); |
388 | } |
389 | } |
390 | |
391 | static void xge_delete_desc_rings(struct net_device *ndev) |
392 | { |
393 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
394 | |
395 | xge_txc_poll(ndev); |
396 | xge_delete_desc_ring(ndev, ring: pdata->tx_ring); |
397 | |
398 | xge_rx_poll(ndev, budget: 64); |
399 | xge_free_buffers(ndev); |
400 | xge_delete_desc_ring(ndev, ring: pdata->rx_ring); |
401 | } |
402 | |
403 | static struct xge_desc_ring *xge_create_desc_ring(struct net_device *ndev) |
404 | { |
405 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
406 | struct device *dev = &pdata->pdev->dev; |
407 | struct xge_desc_ring *ring; |
408 | u16 size; |
409 | |
410 | ring = kzalloc(size: sizeof(*ring), GFP_KERNEL); |
411 | if (!ring) |
412 | return NULL; |
413 | |
414 | ring->ndev = ndev; |
415 | |
416 | size = XGENE_ENET_DESC_SIZE * XGENE_ENET_NUM_DESC; |
417 | ring->desc_addr = dma_alloc_coherent(dev, size, dma_handle: &ring->dma_addr, |
418 | GFP_KERNEL); |
419 | if (!ring->desc_addr) |
420 | goto err; |
421 | |
422 | ring->pkt_info = kcalloc(XGENE_ENET_NUM_DESC, size: sizeof(*ring->pkt_info), |
423 | GFP_KERNEL); |
424 | if (!ring->pkt_info) |
425 | goto err; |
426 | |
427 | xge_setup_desc(ring); |
428 | |
429 | return ring; |
430 | |
431 | err: |
432 | xge_delete_desc_ring(ndev, ring); |
433 | |
434 | return NULL; |
435 | } |
436 | |
437 | static int xge_create_desc_rings(struct net_device *ndev) |
438 | { |
439 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
440 | struct xge_desc_ring *ring; |
441 | int ret; |
442 | |
443 | /* create tx ring */ |
444 | ring = xge_create_desc_ring(ndev); |
445 | if (!ring) |
446 | goto err; |
447 | |
448 | pdata->tx_ring = ring; |
449 | xge_update_tx_desc_addr(pdata); |
450 | |
451 | /* create rx ring */ |
452 | ring = xge_create_desc_ring(ndev); |
453 | if (!ring) |
454 | goto err; |
455 | |
456 | pdata->rx_ring = ring; |
457 | xge_update_rx_desc_addr(pdata); |
458 | |
459 | ret = xge_refill_buffers(ndev, XGENE_ENET_NUM_DESC); |
460 | if (ret) |
461 | goto err; |
462 | |
463 | return 0; |
464 | err: |
465 | xge_delete_desc_rings(ndev); |
466 | |
467 | return -ENOMEM; |
468 | } |
469 | |
470 | static int xge_open(struct net_device *ndev) |
471 | { |
472 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
473 | int ret; |
474 | |
475 | ret = xge_create_desc_rings(ndev); |
476 | if (ret) |
477 | return ret; |
478 | |
479 | napi_enable(n: &pdata->napi); |
480 | ret = xge_request_irq(ndev); |
481 | if (ret) |
482 | return ret; |
483 | |
484 | xge_intr_enable(pdata); |
485 | xge_wr_csr(pdata, DMARXCTRL, val: 1); |
486 | |
487 | phy_start(phydev: ndev->phydev); |
488 | xge_mac_enable(pdata); |
489 | netif_start_queue(dev: ndev); |
490 | |
491 | return 0; |
492 | } |
493 | |
494 | static int xge_close(struct net_device *ndev) |
495 | { |
496 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
497 | |
498 | netif_stop_queue(dev: ndev); |
499 | xge_mac_disable(pdata); |
500 | phy_stop(phydev: ndev->phydev); |
501 | |
502 | xge_intr_disable(pdata); |
503 | xge_free_irq(ndev); |
504 | napi_disable(n: &pdata->napi); |
505 | xge_delete_desc_rings(ndev); |
506 | |
507 | return 0; |
508 | } |
509 | |
510 | static int xge_napi(struct napi_struct *napi, const int budget) |
511 | { |
512 | struct net_device *ndev = napi->dev; |
513 | struct xge_pdata *pdata; |
514 | int processed; |
515 | |
516 | pdata = netdev_priv(dev: ndev); |
517 | |
518 | xge_txc_poll(ndev); |
519 | processed = xge_rx_poll(ndev, budget); |
520 | |
521 | if (processed < budget) { |
522 | napi_complete_done(n: napi, work_done: processed); |
523 | xge_intr_enable(pdata); |
524 | } |
525 | |
526 | return processed; |
527 | } |
528 | |
529 | static int xge_set_mac_addr(struct net_device *ndev, void *addr) |
530 | { |
531 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
532 | int ret; |
533 | |
534 | ret = eth_mac_addr(dev: ndev, p: addr); |
535 | if (ret) |
536 | return ret; |
537 | |
538 | xge_mac_set_station_addr(pdata); |
539 | |
540 | return 0; |
541 | } |
542 | |
543 | static bool is_tx_pending(struct xge_raw_desc *raw_desc) |
544 | { |
545 | if (!GET_BITS(E, le64_to_cpu(raw_desc->m0))) |
546 | return true; |
547 | |
548 | return false; |
549 | } |
550 | |
551 | static void xge_free_pending_skb(struct net_device *ndev) |
552 | { |
553 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
554 | struct device *dev = &pdata->pdev->dev; |
555 | struct xge_desc_ring *tx_ring; |
556 | struct xge_raw_desc *raw_desc; |
557 | dma_addr_t dma_addr; |
558 | struct sk_buff *skb; |
559 | void *pkt_buf; |
560 | int i; |
561 | |
562 | tx_ring = pdata->tx_ring; |
563 | |
564 | for (i = 0; i < XGENE_ENET_NUM_DESC; i++) { |
565 | raw_desc = &tx_ring->raw_desc[i]; |
566 | |
567 | if (!is_tx_pending(raw_desc)) |
568 | continue; |
569 | |
570 | skb = tx_ring->pkt_info[i].skb; |
571 | dma_addr = tx_ring->pkt_info[i].dma_addr; |
572 | pkt_buf = tx_ring->pkt_info[i].pkt_buf; |
573 | dma_free_coherent(dev, XGENE_ENET_STD_MTU, cpu_addr: pkt_buf, dma_handle: dma_addr); |
574 | dev_kfree_skb_any(skb); |
575 | } |
576 | } |
577 | |
578 | static void xge_timeout(struct net_device *ndev, unsigned int txqueue) |
579 | { |
580 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
581 | |
582 | rtnl_lock(); |
583 | |
584 | if (!netif_running(dev: ndev)) |
585 | goto out; |
586 | |
587 | netif_stop_queue(dev: ndev); |
588 | xge_intr_disable(pdata); |
589 | napi_disable(n: &pdata->napi); |
590 | |
591 | xge_wr_csr(pdata, DMATXCTRL, val: 0); |
592 | xge_txc_poll(ndev); |
593 | xge_free_pending_skb(ndev); |
594 | xge_wr_csr(pdata, DMATXSTATUS, val: ~0U); |
595 | |
596 | xge_setup_desc(ring: pdata->tx_ring); |
597 | xge_update_tx_desc_addr(pdata); |
598 | xge_mac_init(pdata); |
599 | |
600 | napi_enable(n: &pdata->napi); |
601 | xge_intr_enable(pdata); |
602 | xge_mac_enable(pdata); |
603 | netif_start_queue(dev: ndev); |
604 | |
605 | out: |
606 | rtnl_unlock(); |
607 | } |
608 | |
609 | static void xge_get_stats64(struct net_device *ndev, |
610 | struct rtnl_link_stats64 *storage) |
611 | { |
612 | struct xge_pdata *pdata = netdev_priv(dev: ndev); |
613 | struct xge_stats *stats = &pdata->stats; |
614 | |
615 | storage->tx_packets += stats->tx_packets; |
616 | storage->tx_bytes += stats->tx_bytes; |
617 | |
618 | storage->rx_packets += stats->rx_packets; |
619 | storage->rx_bytes += stats->rx_bytes; |
620 | storage->rx_errors += stats->rx_errors; |
621 | } |
622 | |
623 | static const struct net_device_ops xgene_ndev_ops = { |
624 | .ndo_open = xge_open, |
625 | .ndo_stop = xge_close, |
626 | .ndo_start_xmit = xge_start_xmit, |
627 | .ndo_set_mac_address = xge_set_mac_addr, |
628 | .ndo_tx_timeout = xge_timeout, |
629 | .ndo_get_stats64 = xge_get_stats64, |
630 | }; |
631 | |
632 | static int xge_probe(struct platform_device *pdev) |
633 | { |
634 | struct device *dev = &pdev->dev; |
635 | struct net_device *ndev; |
636 | struct xge_pdata *pdata; |
637 | int ret; |
638 | |
639 | ndev = alloc_etherdev(sizeof(*pdata)); |
640 | if (!ndev) |
641 | return -ENOMEM; |
642 | |
643 | pdata = netdev_priv(dev: ndev); |
644 | |
645 | pdata->pdev = pdev; |
646 | pdata->ndev = ndev; |
647 | SET_NETDEV_DEV(ndev, dev); |
648 | platform_set_drvdata(pdev, data: pdata); |
649 | ndev->netdev_ops = &xgene_ndev_ops; |
650 | |
651 | ndev->features |= NETIF_F_GSO | |
652 | NETIF_F_GRO; |
653 | |
654 | ret = xge_get_resources(pdata); |
655 | if (ret) |
656 | goto err; |
657 | |
658 | ndev->hw_features = ndev->features; |
659 | xge_set_ethtool_ops(ndev); |
660 | |
661 | ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64)); |
662 | if (ret) { |
663 | netdev_err(dev: ndev, format: "No usable DMA configuration\n" ); |
664 | goto err; |
665 | } |
666 | |
667 | ret = xge_init_hw(ndev); |
668 | if (ret) |
669 | goto err; |
670 | |
671 | ret = xge_mdio_config(ndev); |
672 | if (ret) |
673 | goto err; |
674 | |
675 | netif_napi_add(dev: ndev, napi: &pdata->napi, poll: xge_napi); |
676 | |
677 | ret = register_netdev(dev: ndev); |
678 | if (ret) { |
679 | netdev_err(dev: ndev, format: "Failed to register netdev\n" ); |
680 | goto err_mdio_remove; |
681 | } |
682 | |
683 | return 0; |
684 | |
685 | err_mdio_remove: |
686 | xge_mdio_remove(ndev); |
687 | err: |
688 | free_netdev(dev: ndev); |
689 | |
690 | return ret; |
691 | } |
692 | |
693 | static void xge_remove(struct platform_device *pdev) |
694 | { |
695 | struct xge_pdata *pdata; |
696 | struct net_device *ndev; |
697 | |
698 | pdata = platform_get_drvdata(pdev); |
699 | ndev = pdata->ndev; |
700 | |
701 | rtnl_lock(); |
702 | if (netif_running(dev: ndev)) |
703 | dev_close(dev: ndev); |
704 | rtnl_unlock(); |
705 | |
706 | xge_mdio_remove(ndev); |
707 | unregister_netdev(dev: ndev); |
708 | free_netdev(dev: ndev); |
709 | } |
710 | |
711 | static void xge_shutdown(struct platform_device *pdev) |
712 | { |
713 | struct xge_pdata *pdata; |
714 | |
715 | pdata = platform_get_drvdata(pdev); |
716 | if (!pdata) |
717 | return; |
718 | |
719 | if (!pdata->ndev) |
720 | return; |
721 | |
722 | xge_remove(pdev); |
723 | } |
724 | |
725 | static const struct acpi_device_id xge_acpi_match[] = { |
726 | { "APMC0D80" }, |
727 | { } |
728 | }; |
729 | MODULE_DEVICE_TABLE(acpi, xge_acpi_match); |
730 | |
731 | static struct platform_driver xge_driver = { |
732 | .driver = { |
733 | .name = "xgene-enet-v2" , |
734 | .acpi_match_table = ACPI_PTR(xge_acpi_match), |
735 | }, |
736 | .probe = xge_probe, |
737 | .remove_new = xge_remove, |
738 | .shutdown = xge_shutdown, |
739 | }; |
740 | module_platform_driver(xge_driver); |
741 | |
742 | MODULE_DESCRIPTION("APM X-Gene SoC Ethernet v2 driver" ); |
743 | MODULE_AUTHOR("Iyappan Subramanian <isubramanian@apm.com>" ); |
744 | MODULE_LICENSE("GPL" ); |
745 | |