blob: d8afa2dd8ca71f1024f4e80322ecb7e5148fe574 [file] [log] [blame]
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001/*
2 * Faraday FTGMAC100 Gigabit Ethernet
3 *
4 * (C) Copyright 2009-2011 Faraday Technology
5 * Po-Yu Chuang <ratbert@faraday-tech.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
24#include <linux/dma-mapping.h>
25#include <linux/etherdevice.h>
26#include <linux/ethtool.h>
Thomas Faber17f1bbc2012-01-18 13:45:44 +000027#include <linux/interrupt.h>
Po-Yu Chuang69785b72011-06-08 23:32:48 +000028#include <linux/io.h>
29#include <linux/module.h>
30#include <linux/netdevice.h>
31#include <linux/phy.h>
32#include <linux/platform_device.h>
33#include <net/ip.h>
Gavin Shanbd466c32016-07-19 11:54:23 +100034#include <net/ncsi.h>
Po-Yu Chuang69785b72011-06-08 23:32:48 +000035
36#include "ftgmac100.h"
37
38#define DRV_NAME "ftgmac100"
39#define DRV_VERSION "0.7"
40
41#define RX_QUEUE_ENTRIES 256 /* must be power of 2 */
42#define TX_QUEUE_ENTRIES 512 /* must be power of 2 */
43
44#define MAX_PKT_SIZE 1518
45#define RX_BUF_SIZE PAGE_SIZE /* must be smaller than 0x3fff */
46
47/******************************************************************************
48 * private data
49 *****************************************************************************/
50struct ftgmac100_descs {
51 struct ftgmac100_rxdes rxdes[RX_QUEUE_ENTRIES];
52 struct ftgmac100_txdes txdes[TX_QUEUE_ENTRIES];
53};
54
55struct ftgmac100 {
56 struct resource *res;
57 void __iomem *base;
58 int irq;
59
60 struct ftgmac100_descs *descs;
61 dma_addr_t descs_dma_addr;
62
63 unsigned int rx_pointer;
64 unsigned int tx_clean_pointer;
65 unsigned int tx_pointer;
66 unsigned int tx_pending;
67
68 spinlock_t tx_lock;
69
70 struct net_device *netdev;
71 struct device *dev;
Gavin Shanbd466c32016-07-19 11:54:23 +100072 struct ncsi_dev *ndev;
Po-Yu Chuang69785b72011-06-08 23:32:48 +000073 struct napi_struct napi;
74
75 struct mii_bus *mii_bus;
Po-Yu Chuang69785b72011-06-08 23:32:48 +000076 int old_speed;
Gavin Shanbd466c32016-07-19 11:54:23 +100077 bool use_ncsi;
78 bool enabled;
Po-Yu Chuang69785b72011-06-08 23:32:48 +000079};
80
81static int ftgmac100_alloc_rx_page(struct ftgmac100 *priv,
82 struct ftgmac100_rxdes *rxdes, gfp_t gfp);
83
84/******************************************************************************
85 * internal functions (hardware register access)
86 *****************************************************************************/
87#define INT_MASK_ALL_ENABLED (FTGMAC100_INT_RPKT_LOST | \
88 FTGMAC100_INT_XPKT_ETH | \
89 FTGMAC100_INT_XPKT_LOST | \
90 FTGMAC100_INT_AHB_ERR | \
91 FTGMAC100_INT_PHYSTS_CHG | \
92 FTGMAC100_INT_RPKT_BUF | \
93 FTGMAC100_INT_NO_RXBUF)
94
95static void ftgmac100_set_rx_ring_base(struct ftgmac100 *priv, dma_addr_t addr)
96{
97 iowrite32(addr, priv->base + FTGMAC100_OFFSET_RXR_BADR);
98}
99
100static void ftgmac100_set_rx_buffer_size(struct ftgmac100 *priv,
101 unsigned int size)
102{
103 size = FTGMAC100_RBSR_SIZE(size);
104 iowrite32(size, priv->base + FTGMAC100_OFFSET_RBSR);
105}
106
107static void ftgmac100_set_normal_prio_tx_ring_base(struct ftgmac100 *priv,
108 dma_addr_t addr)
109{
110 iowrite32(addr, priv->base + FTGMAC100_OFFSET_NPTXR_BADR);
111}
112
113static void ftgmac100_txdma_normal_prio_start_polling(struct ftgmac100 *priv)
114{
115 iowrite32(1, priv->base + FTGMAC100_OFFSET_NPTXPD);
116}
117
118static int ftgmac100_reset_hw(struct ftgmac100 *priv)
119{
120 struct net_device *netdev = priv->netdev;
121 int i;
122
123 /* NOTE: reset clears all registers */
124 iowrite32(FTGMAC100_MACCR_SW_RST, priv->base + FTGMAC100_OFFSET_MACCR);
125 for (i = 0; i < 5; i++) {
126 unsigned int maccr;
127
128 maccr = ioread32(priv->base + FTGMAC100_OFFSET_MACCR);
129 if (!(maccr & FTGMAC100_MACCR_SW_RST))
130 return 0;
131
132 udelay(1000);
133 }
134
135 netdev_err(netdev, "software reset failed\n");
136 return -EIO;
137}
138
139static void ftgmac100_set_mac(struct ftgmac100 *priv, const unsigned char *mac)
140{
141 unsigned int maddr = mac[0] << 8 | mac[1];
142 unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
143
144 iowrite32(maddr, priv->base + FTGMAC100_OFFSET_MAC_MADR);
145 iowrite32(laddr, priv->base + FTGMAC100_OFFSET_MAC_LADR);
146}
147
Gavin Shan113ce102016-07-19 11:54:22 +1000148static void ftgmac100_setup_mac(struct ftgmac100 *priv)
149{
150 u8 mac[ETH_ALEN];
151 unsigned int m;
152 unsigned int l;
153 void *addr;
154
155 addr = device_get_mac_address(priv->dev, mac, ETH_ALEN);
156 if (addr) {
157 ether_addr_copy(priv->netdev->dev_addr, mac);
158 dev_info(priv->dev, "Read MAC address %pM from device tree\n",
159 mac);
160 return;
161 }
162
163 m = ioread32(priv->base + FTGMAC100_OFFSET_MAC_MADR);
164 l = ioread32(priv->base + FTGMAC100_OFFSET_MAC_LADR);
165
166 mac[0] = (m >> 8) & 0xff;
167 mac[1] = m & 0xff;
168 mac[2] = (l >> 24) & 0xff;
169 mac[3] = (l >> 16) & 0xff;
170 mac[4] = (l >> 8) & 0xff;
171 mac[5] = l & 0xff;
172
173 if (!is_valid_ether_addr(mac)) {
174 mac[5] = (m >> 8) & 0xff;
175 mac[4] = m & 0xff;
176 mac[3] = (l >> 24) & 0xff;
177 mac[2] = (l >> 16) & 0xff;
178 mac[1] = (l >> 8) & 0xff;
179 mac[0] = l & 0xff;
180 }
181
182 if (is_valid_ether_addr(mac)) {
183 ether_addr_copy(priv->netdev->dev_addr, mac);
184 dev_info(priv->dev, "Read MAC address %pM from chip\n", mac);
185 } else {
186 eth_hw_addr_random(priv->netdev);
187 dev_info(priv->dev, "Generated random MAC address %pM\n",
188 priv->netdev->dev_addr);
189 }
190}
191
192static int ftgmac100_set_mac_addr(struct net_device *dev, void *p)
193{
194 int ret;
195
196 ret = eth_prepare_mac_addr_change(dev, p);
197 if (ret < 0)
198 return ret;
199
200 eth_commit_mac_addr_change(dev, p);
201 ftgmac100_set_mac(netdev_priv(dev), dev->dev_addr);
202
203 return 0;
204}
205
Po-Yu Chuang69785b72011-06-08 23:32:48 +0000206static void ftgmac100_init_hw(struct ftgmac100 *priv)
207{
208 /* setup ring buffer base registers */
209 ftgmac100_set_rx_ring_base(priv,
210 priv->descs_dma_addr +
211 offsetof(struct ftgmac100_descs, rxdes));
212 ftgmac100_set_normal_prio_tx_ring_base(priv,
213 priv->descs_dma_addr +
214 offsetof(struct ftgmac100_descs, txdes));
215
216 ftgmac100_set_rx_buffer_size(priv, RX_BUF_SIZE);
217
218 iowrite32(FTGMAC100_APTC_RXPOLL_CNT(1), priv->base + FTGMAC100_OFFSET_APTC);
219
220 ftgmac100_set_mac(priv, priv->netdev->dev_addr);
221}
222
223#define MACCR_ENABLE_ALL (FTGMAC100_MACCR_TXDMA_EN | \
224 FTGMAC100_MACCR_RXDMA_EN | \
225 FTGMAC100_MACCR_TXMAC_EN | \
226 FTGMAC100_MACCR_RXMAC_EN | \
227 FTGMAC100_MACCR_FULLDUP | \
228 FTGMAC100_MACCR_CRC_APD | \
229 FTGMAC100_MACCR_RX_RUNT | \
230 FTGMAC100_MACCR_RX_BROADPKT)
231
232static void ftgmac100_start_hw(struct ftgmac100 *priv, int speed)
233{
234 int maccr = MACCR_ENABLE_ALL;
235
236 switch (speed) {
237 default:
238 case 10:
239 break;
240
241 case 100:
242 maccr |= FTGMAC100_MACCR_FAST_MODE;
243 break;
244
245 case 1000:
246 maccr |= FTGMAC100_MACCR_GIGA_MODE;
247 break;
248 }
249
250 iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR);
251}
252
253static void ftgmac100_stop_hw(struct ftgmac100 *priv)
254{
255 iowrite32(0, priv->base + FTGMAC100_OFFSET_MACCR);
256}
257
258/******************************************************************************
259 * internal functions (receive descriptor)
260 *****************************************************************************/
261static bool ftgmac100_rxdes_first_segment(struct ftgmac100_rxdes *rxdes)
262{
263 return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_FRS);
264}
265
266static bool ftgmac100_rxdes_last_segment(struct ftgmac100_rxdes *rxdes)
267{
268 return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_LRS);
269}
270
271static bool ftgmac100_rxdes_packet_ready(struct ftgmac100_rxdes *rxdes)
272{
273 return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RXPKT_RDY);
274}
275
276static void ftgmac100_rxdes_set_dma_own(struct ftgmac100_rxdes *rxdes)
277{
278 /* clear status bits */
279 rxdes->rxdes0 &= cpu_to_le32(FTGMAC100_RXDES0_EDORR);
280}
281
282static bool ftgmac100_rxdes_rx_error(struct ftgmac100_rxdes *rxdes)
283{
284 return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RX_ERR);
285}
286
287static bool ftgmac100_rxdes_crc_error(struct ftgmac100_rxdes *rxdes)
288{
289 return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_CRC_ERR);
290}
291
292static bool ftgmac100_rxdes_frame_too_long(struct ftgmac100_rxdes *rxdes)
293{
294 return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_FTL);
295}
296
297static bool ftgmac100_rxdes_runt(struct ftgmac100_rxdes *rxdes)
298{
299 return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RUNT);
300}
301
302static bool ftgmac100_rxdes_odd_nibble(struct ftgmac100_rxdes *rxdes)
303{
304 return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RX_ODD_NB);
305}
306
307static unsigned int ftgmac100_rxdes_data_length(struct ftgmac100_rxdes *rxdes)
308{
309 return le32_to_cpu(rxdes->rxdes0) & FTGMAC100_RXDES0_VDBC;
310}
311
312static bool ftgmac100_rxdes_multicast(struct ftgmac100_rxdes *rxdes)
313{
314 return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_MULTICAST);
315}
316
317static void ftgmac100_rxdes_set_end_of_ring(struct ftgmac100_rxdes *rxdes)
318{
319 rxdes->rxdes0 |= cpu_to_le32(FTGMAC100_RXDES0_EDORR);
320}
321
322static void ftgmac100_rxdes_set_dma_addr(struct ftgmac100_rxdes *rxdes,
323 dma_addr_t addr)
324{
325 rxdes->rxdes3 = cpu_to_le32(addr);
326}
327
328static dma_addr_t ftgmac100_rxdes_get_dma_addr(struct ftgmac100_rxdes *rxdes)
329{
330 return le32_to_cpu(rxdes->rxdes3);
331}
332
333static bool ftgmac100_rxdes_is_tcp(struct ftgmac100_rxdes *rxdes)
334{
335 return (rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_PROT_MASK)) ==
336 cpu_to_le32(FTGMAC100_RXDES1_PROT_TCPIP);
337}
338
339static bool ftgmac100_rxdes_is_udp(struct ftgmac100_rxdes *rxdes)
340{
341 return (rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_PROT_MASK)) ==
342 cpu_to_le32(FTGMAC100_RXDES1_PROT_UDPIP);
343}
344
345static bool ftgmac100_rxdes_tcpcs_err(struct ftgmac100_rxdes *rxdes)
346{
347 return rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_TCP_CHKSUM_ERR);
348}
349
350static bool ftgmac100_rxdes_udpcs_err(struct ftgmac100_rxdes *rxdes)
351{
352 return rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_UDP_CHKSUM_ERR);
353}
354
355static bool ftgmac100_rxdes_ipcs_err(struct ftgmac100_rxdes *rxdes)
356{
357 return rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_IP_CHKSUM_ERR);
358}
359
360/*
361 * rxdes2 is not used by hardware. We use it to keep track of page.
362 * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu().
363 */
364static void ftgmac100_rxdes_set_page(struct ftgmac100_rxdes *rxdes, struct page *page)
365{
366 rxdes->rxdes2 = (unsigned int)page;
367}
368
369static struct page *ftgmac100_rxdes_get_page(struct ftgmac100_rxdes *rxdes)
370{
371 return (struct page *)rxdes->rxdes2;
372}
373
374/******************************************************************************
375 * internal functions (receive)
376 *****************************************************************************/
377static int ftgmac100_next_rx_pointer(int pointer)
378{
379 return (pointer + 1) & (RX_QUEUE_ENTRIES - 1);
380}
381
382static void ftgmac100_rx_pointer_advance(struct ftgmac100 *priv)
383{
384 priv->rx_pointer = ftgmac100_next_rx_pointer(priv->rx_pointer);
385}
386
387static struct ftgmac100_rxdes *ftgmac100_current_rxdes(struct ftgmac100 *priv)
388{
389 return &priv->descs->rxdes[priv->rx_pointer];
390}
391
392static struct ftgmac100_rxdes *
393ftgmac100_rx_locate_first_segment(struct ftgmac100 *priv)
394{
395 struct ftgmac100_rxdes *rxdes = ftgmac100_current_rxdes(priv);
396
397 while (ftgmac100_rxdes_packet_ready(rxdes)) {
398 if (ftgmac100_rxdes_first_segment(rxdes))
399 return rxdes;
400
401 ftgmac100_rxdes_set_dma_own(rxdes);
402 ftgmac100_rx_pointer_advance(priv);
403 rxdes = ftgmac100_current_rxdes(priv);
404 }
405
406 return NULL;
407}
408
409static bool ftgmac100_rx_packet_error(struct ftgmac100 *priv,
410 struct ftgmac100_rxdes *rxdes)
411{
412 struct net_device *netdev = priv->netdev;
413 bool error = false;
414
415 if (unlikely(ftgmac100_rxdes_rx_error(rxdes))) {
416 if (net_ratelimit())
417 netdev_info(netdev, "rx err\n");
418
419 netdev->stats.rx_errors++;
420 error = true;
421 }
422
423 if (unlikely(ftgmac100_rxdes_crc_error(rxdes))) {
424 if (net_ratelimit())
425 netdev_info(netdev, "rx crc err\n");
426
427 netdev->stats.rx_crc_errors++;
428 error = true;
429 } else if (unlikely(ftgmac100_rxdes_ipcs_err(rxdes))) {
430 if (net_ratelimit())
431 netdev_info(netdev, "rx IP checksum err\n");
432
433 error = true;
434 }
435
436 if (unlikely(ftgmac100_rxdes_frame_too_long(rxdes))) {
437 if (net_ratelimit())
438 netdev_info(netdev, "rx frame too long\n");
439
440 netdev->stats.rx_length_errors++;
441 error = true;
442 } else if (unlikely(ftgmac100_rxdes_runt(rxdes))) {
443 if (net_ratelimit())
444 netdev_info(netdev, "rx runt\n");
445
446 netdev->stats.rx_length_errors++;
447 error = true;
448 } else if (unlikely(ftgmac100_rxdes_odd_nibble(rxdes))) {
449 if (net_ratelimit())
450 netdev_info(netdev, "rx odd nibble\n");
451
452 netdev->stats.rx_length_errors++;
453 error = true;
454 }
455
456 return error;
457}
458
459static void ftgmac100_rx_drop_packet(struct ftgmac100 *priv)
460{
461 struct net_device *netdev = priv->netdev;
462 struct ftgmac100_rxdes *rxdes = ftgmac100_current_rxdes(priv);
463 bool done = false;
464
465 if (net_ratelimit())
466 netdev_dbg(netdev, "drop packet %p\n", rxdes);
467
468 do {
469 if (ftgmac100_rxdes_last_segment(rxdes))
470 done = true;
471
472 ftgmac100_rxdes_set_dma_own(rxdes);
473 ftgmac100_rx_pointer_advance(priv);
474 rxdes = ftgmac100_current_rxdes(priv);
475 } while (!done && ftgmac100_rxdes_packet_ready(rxdes));
476
477 netdev->stats.rx_dropped++;
478}
479
480static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
481{
482 struct net_device *netdev = priv->netdev;
483 struct ftgmac100_rxdes *rxdes;
484 struct sk_buff *skb;
485 bool done = false;
486
487 rxdes = ftgmac100_rx_locate_first_segment(priv);
488 if (!rxdes)
489 return false;
490
491 if (unlikely(ftgmac100_rx_packet_error(priv, rxdes))) {
492 ftgmac100_rx_drop_packet(priv);
493 return true;
494 }
495
496 /* start processing */
497 skb = netdev_alloc_skb_ip_align(netdev, 128);
498 if (unlikely(!skb)) {
499 if (net_ratelimit())
500 netdev_err(netdev, "rx skb alloc failed\n");
501
502 ftgmac100_rx_drop_packet(priv);
503 return true;
504 }
505
506 if (unlikely(ftgmac100_rxdes_multicast(rxdes)))
507 netdev->stats.multicast++;
508
509 /*
510 * It seems that HW does checksum incorrectly with fragmented packets,
511 * so we are conservative here - if HW checksum error, let software do
512 * the checksum again.
513 */
514 if ((ftgmac100_rxdes_is_tcp(rxdes) && !ftgmac100_rxdes_tcpcs_err(rxdes)) ||
515 (ftgmac100_rxdes_is_udp(rxdes) && !ftgmac100_rxdes_udpcs_err(rxdes)))
516 skb->ip_summed = CHECKSUM_UNNECESSARY;
517
518 do {
519 dma_addr_t map = ftgmac100_rxdes_get_dma_addr(rxdes);
520 struct page *page = ftgmac100_rxdes_get_page(rxdes);
521 unsigned int size;
522
523 dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE);
524
525 size = ftgmac100_rxdes_data_length(rxdes);
526 skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page, 0, size);
527
528 skb->len += size;
529 skb->data_len += size;
Eric Dumazet5935f812011-10-13 11:30:52 +0000530 skb->truesize += PAGE_SIZE;
Po-Yu Chuang69785b72011-06-08 23:32:48 +0000531
532 if (ftgmac100_rxdes_last_segment(rxdes))
533 done = true;
534
535 ftgmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC);
536
537 ftgmac100_rx_pointer_advance(priv);
538 rxdes = ftgmac100_current_rxdes(priv);
539 } while (!done);
540
Eric Dumazet6ecd09d2012-07-12 04:19:38 +0000541 /* Small frames are copied into linear part of skb to free one page */
542 if (skb->len <= 128) {
Eric Dumazet5935f812011-10-13 11:30:52 +0000543 skb->truesize -= PAGE_SIZE;
Eric Dumazet6ecd09d2012-07-12 04:19:38 +0000544 __pskb_pull_tail(skb, skb->len);
545 } else {
546 /* We pull the minimum amount into linear part */
547 __pskb_pull_tail(skb, ETH_HLEN);
548 }
Po-Yu Chuang69785b72011-06-08 23:32:48 +0000549 skb->protocol = eth_type_trans(skb, netdev);
550
551 netdev->stats.rx_packets++;
552 netdev->stats.rx_bytes += skb->len;
553
554 /* push packet to protocol stack */
555 napi_gro_receive(&priv->napi, skb);
556
557 (*processed)++;
558 return true;
559}
560
561/******************************************************************************
562 * internal functions (transmit descriptor)
563 *****************************************************************************/
564static void ftgmac100_txdes_reset(struct ftgmac100_txdes *txdes)
565{
566 /* clear all except end of ring bit */
567 txdes->txdes0 &= cpu_to_le32(FTGMAC100_TXDES0_EDOTR);
568 txdes->txdes1 = 0;
569 txdes->txdes2 = 0;
570 txdes->txdes3 = 0;
571}
572
573static bool ftgmac100_txdes_owned_by_dma(struct ftgmac100_txdes *txdes)
574{
575 return txdes->txdes0 & cpu_to_le32(FTGMAC100_TXDES0_TXDMA_OWN);
576}
577
578static void ftgmac100_txdes_set_dma_own(struct ftgmac100_txdes *txdes)
579{
580 /*
581 * Make sure dma own bit will not be set before any other
582 * descriptor fields.
583 */
584 wmb();
585 txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_TXDMA_OWN);
586}
587
588static void ftgmac100_txdes_set_end_of_ring(struct ftgmac100_txdes *txdes)
589{
590 txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_EDOTR);
591}
592
593static void ftgmac100_txdes_set_first_segment(struct ftgmac100_txdes *txdes)
594{
595 txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_FTS);
596}
597
598static void ftgmac100_txdes_set_last_segment(struct ftgmac100_txdes *txdes)
599{
600 txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_LTS);
601}
602
603static void ftgmac100_txdes_set_buffer_size(struct ftgmac100_txdes *txdes,
604 unsigned int len)
605{
606 txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_TXBUF_SIZE(len));
607}
608
609static void ftgmac100_txdes_set_txint(struct ftgmac100_txdes *txdes)
610{
611 txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_TXIC);
612}
613
614static void ftgmac100_txdes_set_tcpcs(struct ftgmac100_txdes *txdes)
615{
616 txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_TCP_CHKSUM);
617}
618
619static void ftgmac100_txdes_set_udpcs(struct ftgmac100_txdes *txdes)
620{
621 txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_UDP_CHKSUM);
622}
623
624static void ftgmac100_txdes_set_ipcs(struct ftgmac100_txdes *txdes)
625{
626 txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_IP_CHKSUM);
627}
628
629static void ftgmac100_txdes_set_dma_addr(struct ftgmac100_txdes *txdes,
630 dma_addr_t addr)
631{
632 txdes->txdes3 = cpu_to_le32(addr);
633}
634
635static dma_addr_t ftgmac100_txdes_get_dma_addr(struct ftgmac100_txdes *txdes)
636{
637 return le32_to_cpu(txdes->txdes3);
638}
639
640/*
641 * txdes2 is not used by hardware. We use it to keep track of socket buffer.
642 * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu().
643 */
644static void ftgmac100_txdes_set_skb(struct ftgmac100_txdes *txdes,
645 struct sk_buff *skb)
646{
647 txdes->txdes2 = (unsigned int)skb;
648}
649
650static struct sk_buff *ftgmac100_txdes_get_skb(struct ftgmac100_txdes *txdes)
651{
652 return (struct sk_buff *)txdes->txdes2;
653}
654
655/******************************************************************************
656 * internal functions (transmit)
657 *****************************************************************************/
658static int ftgmac100_next_tx_pointer(int pointer)
659{
660 return (pointer + 1) & (TX_QUEUE_ENTRIES - 1);
661}
662
663static void ftgmac100_tx_pointer_advance(struct ftgmac100 *priv)
664{
665 priv->tx_pointer = ftgmac100_next_tx_pointer(priv->tx_pointer);
666}
667
668static void ftgmac100_tx_clean_pointer_advance(struct ftgmac100 *priv)
669{
670 priv->tx_clean_pointer = ftgmac100_next_tx_pointer(priv->tx_clean_pointer);
671}
672
673static struct ftgmac100_txdes *ftgmac100_current_txdes(struct ftgmac100 *priv)
674{
675 return &priv->descs->txdes[priv->tx_pointer];
676}
677
678static struct ftgmac100_txdes *
679ftgmac100_current_clean_txdes(struct ftgmac100 *priv)
680{
681 return &priv->descs->txdes[priv->tx_clean_pointer];
682}
683
684static bool ftgmac100_tx_complete_packet(struct ftgmac100 *priv)
685{
686 struct net_device *netdev = priv->netdev;
687 struct ftgmac100_txdes *txdes;
688 struct sk_buff *skb;
689 dma_addr_t map;
690
691 if (priv->tx_pending == 0)
692 return false;
693
694 txdes = ftgmac100_current_clean_txdes(priv);
695
696 if (ftgmac100_txdes_owned_by_dma(txdes))
697 return false;
698
699 skb = ftgmac100_txdes_get_skb(txdes);
700 map = ftgmac100_txdes_get_dma_addr(txdes);
701
702 netdev->stats.tx_packets++;
703 netdev->stats.tx_bytes += skb->len;
704
705 dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE);
706
707 dev_kfree_skb(skb);
708
709 ftgmac100_txdes_reset(txdes);
710
711 ftgmac100_tx_clean_pointer_advance(priv);
712
713 spin_lock(&priv->tx_lock);
714 priv->tx_pending--;
715 spin_unlock(&priv->tx_lock);
716 netif_wake_queue(netdev);
717
718 return true;
719}
720
721static void ftgmac100_tx_complete(struct ftgmac100 *priv)
722{
723 while (ftgmac100_tx_complete_packet(priv))
724 ;
725}
726
727static int ftgmac100_xmit(struct ftgmac100 *priv, struct sk_buff *skb,
728 dma_addr_t map)
729{
730 struct net_device *netdev = priv->netdev;
731 struct ftgmac100_txdes *txdes;
732 unsigned int len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
733
734 txdes = ftgmac100_current_txdes(priv);
735 ftgmac100_tx_pointer_advance(priv);
736
737 /* setup TX descriptor */
738 ftgmac100_txdes_set_skb(txdes, skb);
739 ftgmac100_txdes_set_dma_addr(txdes, map);
740 ftgmac100_txdes_set_buffer_size(txdes, len);
741
742 ftgmac100_txdes_set_first_segment(txdes);
743 ftgmac100_txdes_set_last_segment(txdes);
744 ftgmac100_txdes_set_txint(txdes);
745 if (skb->ip_summed == CHECKSUM_PARTIAL) {
746 __be16 protocol = skb->protocol;
747
748 if (protocol == cpu_to_be16(ETH_P_IP)) {
749 u8 ip_proto = ip_hdr(skb)->protocol;
750
751 ftgmac100_txdes_set_ipcs(txdes);
752 if (ip_proto == IPPROTO_TCP)
753 ftgmac100_txdes_set_tcpcs(txdes);
754 else if (ip_proto == IPPROTO_UDP)
755 ftgmac100_txdes_set_udpcs(txdes);
756 }
757 }
758
759 spin_lock(&priv->tx_lock);
760 priv->tx_pending++;
761 if (priv->tx_pending == TX_QUEUE_ENTRIES)
762 netif_stop_queue(netdev);
763
764 /* start transmit */
765 ftgmac100_txdes_set_dma_own(txdes);
766 spin_unlock(&priv->tx_lock);
767
768 ftgmac100_txdma_normal_prio_start_polling(priv);
769
770 return NETDEV_TX_OK;
771}
772
773/******************************************************************************
774 * internal functions (buffer)
775 *****************************************************************************/
776static int ftgmac100_alloc_rx_page(struct ftgmac100 *priv,
777 struct ftgmac100_rxdes *rxdes, gfp_t gfp)
778{
779 struct net_device *netdev = priv->netdev;
780 struct page *page;
781 dma_addr_t map;
782
783 page = alloc_page(gfp);
784 if (!page) {
785 if (net_ratelimit())
786 netdev_err(netdev, "failed to allocate rx page\n");
787 return -ENOMEM;
788 }
789
790 map = dma_map_page(priv->dev, page, 0, RX_BUF_SIZE, DMA_FROM_DEVICE);
791 if (unlikely(dma_mapping_error(priv->dev, map))) {
792 if (net_ratelimit())
793 netdev_err(netdev, "failed to map rx page\n");
794 __free_page(page);
795 return -ENOMEM;
796 }
797
798 ftgmac100_rxdes_set_page(rxdes, page);
799 ftgmac100_rxdes_set_dma_addr(rxdes, map);
800 ftgmac100_rxdes_set_dma_own(rxdes);
801 return 0;
802}
803
804static void ftgmac100_free_buffers(struct ftgmac100 *priv)
805{
806 int i;
807
808 for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
809 struct ftgmac100_rxdes *rxdes = &priv->descs->rxdes[i];
810 struct page *page = ftgmac100_rxdes_get_page(rxdes);
811 dma_addr_t map = ftgmac100_rxdes_get_dma_addr(rxdes);
812
813 if (!page)
814 continue;
815
816 dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE);
817 __free_page(page);
818 }
819
820 for (i = 0; i < TX_QUEUE_ENTRIES; i++) {
821 struct ftgmac100_txdes *txdes = &priv->descs->txdes[i];
822 struct sk_buff *skb = ftgmac100_txdes_get_skb(txdes);
823 dma_addr_t map = ftgmac100_txdes_get_dma_addr(txdes);
824
825 if (!skb)
826 continue;
827
828 dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE);
Eric Dumazet0113e342014-01-16 23:38:24 -0800829 kfree_skb(skb);
Po-Yu Chuang69785b72011-06-08 23:32:48 +0000830 }
831
832 dma_free_coherent(priv->dev, sizeof(struct ftgmac100_descs),
833 priv->descs, priv->descs_dma_addr);
834}
835
836static int ftgmac100_alloc_buffers(struct ftgmac100 *priv)
837{
838 int i;
839
Joe Perchesede23fa82013-08-26 22:45:23 -0700840 priv->descs = dma_zalloc_coherent(priv->dev,
841 sizeof(struct ftgmac100_descs),
842 &priv->descs_dma_addr, GFP_KERNEL);
Po-Yu Chuang69785b72011-06-08 23:32:48 +0000843 if (!priv->descs)
844 return -ENOMEM;
845
Po-Yu Chuang69785b72011-06-08 23:32:48 +0000846 /* initialize RX ring */
847 ftgmac100_rxdes_set_end_of_ring(&priv->descs->rxdes[RX_QUEUE_ENTRIES - 1]);
848
849 for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
850 struct ftgmac100_rxdes *rxdes = &priv->descs->rxdes[i];
851
852 if (ftgmac100_alloc_rx_page(priv, rxdes, GFP_KERNEL))
853 goto err;
854 }
855
856 /* initialize TX ring */
857 ftgmac100_txdes_set_end_of_ring(&priv->descs->txdes[TX_QUEUE_ENTRIES - 1]);
858 return 0;
859
860err:
861 ftgmac100_free_buffers(priv);
862 return -ENOMEM;
863}
864
865/******************************************************************************
866 * internal functions (mdio)
867 *****************************************************************************/
868static void ftgmac100_adjust_link(struct net_device *netdev)
869{
870 struct ftgmac100 *priv = netdev_priv(netdev);
Philippe Reynesb3c40ad2016-05-16 01:35:13 +0200871 struct phy_device *phydev = netdev->phydev;
Po-Yu Chuang69785b72011-06-08 23:32:48 +0000872 int ier;
873
874 if (phydev->speed == priv->old_speed)
875 return;
876
877 priv->old_speed = phydev->speed;
878
879 ier = ioread32(priv->base + FTGMAC100_OFFSET_IER);
880
881 /* disable all interrupts */
882 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER);
883
884 netif_stop_queue(netdev);
885 ftgmac100_stop_hw(priv);
886
887 netif_start_queue(netdev);
888 ftgmac100_init_hw(priv);
889 ftgmac100_start_hw(priv, phydev->speed);
890
891 /* re-enable interrupts */
892 iowrite32(ier, priv->base + FTGMAC100_OFFSET_IER);
893}
894
895static int ftgmac100_mii_probe(struct ftgmac100 *priv)
896{
897 struct net_device *netdev = priv->netdev;
Guenter Roecke574f392016-01-10 12:04:32 -0800898 struct phy_device *phydev;
Po-Yu Chuang69785b72011-06-08 23:32:48 +0000899
Guenter Roecke574f392016-01-10 12:04:32 -0800900 phydev = phy_find_first(priv->mii_bus);
Po-Yu Chuang69785b72011-06-08 23:32:48 +0000901 if (!phydev) {
902 netdev_info(netdev, "%s: no PHY found\n", netdev->name);
903 return -ENODEV;
904 }
905
Andrew Lunn84eff6d2016-01-06 20:11:10 +0100906 phydev = phy_connect(netdev, phydev_name(phydev),
Florian Fainellif9a8f832013-01-14 00:52:52 +0000907 &ftgmac100_adjust_link, PHY_INTERFACE_MODE_GMII);
Po-Yu Chuang69785b72011-06-08 23:32:48 +0000908
909 if (IS_ERR(phydev)) {
910 netdev_err(netdev, "%s: Could not attach to PHY\n", netdev->name);
911 return PTR_ERR(phydev);
912 }
913
Po-Yu Chuang69785b72011-06-08 23:32:48 +0000914 return 0;
915}
916
917/******************************************************************************
918 * struct mii_bus functions
919 *****************************************************************************/
920static int ftgmac100_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
921{
922 struct net_device *netdev = bus->priv;
923 struct ftgmac100 *priv = netdev_priv(netdev);
924 unsigned int phycr;
925 int i;
926
927 phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR);
928
929 /* preserve MDC cycle threshold */
930 phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK;
931
932 phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr) |
933 FTGMAC100_PHYCR_REGAD(regnum) |
934 FTGMAC100_PHYCR_MIIRD;
935
936 iowrite32(phycr, priv->base + FTGMAC100_OFFSET_PHYCR);
937
938 for (i = 0; i < 10; i++) {
939 phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR);
940
941 if ((phycr & FTGMAC100_PHYCR_MIIRD) == 0) {
942 int data;
943
944 data = ioread32(priv->base + FTGMAC100_OFFSET_PHYDATA);
945 return FTGMAC100_PHYDATA_MIIRDATA(data);
946 }
947
948 udelay(100);
949 }
950
951 netdev_err(netdev, "mdio read timed out\n");
952 return -EIO;
953}
954
955static int ftgmac100_mdiobus_write(struct mii_bus *bus, int phy_addr,
956 int regnum, u16 value)
957{
958 struct net_device *netdev = bus->priv;
959 struct ftgmac100 *priv = netdev_priv(netdev);
960 unsigned int phycr;
961 int data;
962 int i;
963
964 phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR);
965
966 /* preserve MDC cycle threshold */
967 phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK;
968
969 phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr) |
970 FTGMAC100_PHYCR_REGAD(regnum) |
971 FTGMAC100_PHYCR_MIIWR;
972
973 data = FTGMAC100_PHYDATA_MIIWDATA(value);
974
975 iowrite32(data, priv->base + FTGMAC100_OFFSET_PHYDATA);
976 iowrite32(phycr, priv->base + FTGMAC100_OFFSET_PHYCR);
977
978 for (i = 0; i < 10; i++) {
979 phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR);
980
981 if ((phycr & FTGMAC100_PHYCR_MIIWR) == 0)
982 return 0;
983
984 udelay(100);
985 }
986
987 netdev_err(netdev, "mdio write timed out\n");
988 return -EIO;
989}
990
Po-Yu Chuang69785b72011-06-08 23:32:48 +0000991/******************************************************************************
992 * struct ethtool_ops functions
993 *****************************************************************************/
994static void ftgmac100_get_drvinfo(struct net_device *netdev,
995 struct ethtool_drvinfo *info)
996{
Jiri Pirko7826d432013-01-06 00:44:26 +0000997 strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
998 strlcpy(info->version, DRV_VERSION, sizeof(info->version));
999 strlcpy(info->bus_info, dev_name(&netdev->dev), sizeof(info->bus_info));
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001000}
1001
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001002static const struct ethtool_ops ftgmac100_ethtool_ops = {
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001003 .get_drvinfo = ftgmac100_get_drvinfo,
1004 .get_link = ethtool_op_get_link,
Philippe Reynesfd24d722016-05-16 01:35:14 +02001005 .get_link_ksettings = phy_ethtool_get_link_ksettings,
1006 .set_link_ksettings = phy_ethtool_set_link_ksettings,
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001007};
1008
1009/******************************************************************************
1010 * interrupt handler
1011 *****************************************************************************/
1012static irqreturn_t ftgmac100_interrupt(int irq, void *dev_id)
1013{
1014 struct net_device *netdev = dev_id;
1015 struct ftgmac100 *priv = netdev_priv(netdev);
1016
Gavin Shanbd466c32016-07-19 11:54:23 +10001017 /* When running in NCSI mode, the interface should be ready for
1018 * receiving or transmitting NCSI packets before it's opened.
1019 */
1020 if (likely(priv->use_ncsi || netif_running(netdev))) {
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001021 /* Disable interrupts for polling */
1022 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER);
1023 napi_schedule(&priv->napi);
1024 }
1025
1026 return IRQ_HANDLED;
1027}
1028
1029/******************************************************************************
1030 * struct napi_struct functions
1031 *****************************************************************************/
1032static int ftgmac100_poll(struct napi_struct *napi, int budget)
1033{
1034 struct ftgmac100 *priv = container_of(napi, struct ftgmac100, napi);
1035 struct net_device *netdev = priv->netdev;
1036 unsigned int status;
1037 bool completed = true;
1038 int rx = 0;
1039
1040 status = ioread32(priv->base + FTGMAC100_OFFSET_ISR);
1041 iowrite32(status, priv->base + FTGMAC100_OFFSET_ISR);
1042
1043 if (status & (FTGMAC100_INT_RPKT_BUF | FTGMAC100_INT_NO_RXBUF)) {
1044 /*
1045 * FTGMAC100_INT_RPKT_BUF:
1046 * RX DMA has received packets into RX buffer successfully
1047 *
1048 * FTGMAC100_INT_NO_RXBUF:
1049 * RX buffer unavailable
1050 */
1051 bool retry;
1052
1053 do {
1054 retry = ftgmac100_rx_packet(priv, &rx);
1055 } while (retry && rx < budget);
1056
1057 if (retry && rx == budget)
1058 completed = false;
1059 }
1060
1061 if (status & (FTGMAC100_INT_XPKT_ETH | FTGMAC100_INT_XPKT_LOST)) {
1062 /*
1063 * FTGMAC100_INT_XPKT_ETH:
1064 * packet transmitted to ethernet successfully
1065 *
1066 * FTGMAC100_INT_XPKT_LOST:
1067 * packet transmitted to ethernet lost due to late
1068 * collision or excessive collision
1069 */
1070 ftgmac100_tx_complete(priv);
1071 }
1072
1073 if (status & (FTGMAC100_INT_NO_RXBUF | FTGMAC100_INT_RPKT_LOST |
1074 FTGMAC100_INT_AHB_ERR | FTGMAC100_INT_PHYSTS_CHG)) {
1075 if (net_ratelimit())
1076 netdev_info(netdev, "[ISR] = 0x%x: %s%s%s%s\n", status,
1077 status & FTGMAC100_INT_NO_RXBUF ? "NO_RXBUF " : "",
1078 status & FTGMAC100_INT_RPKT_LOST ? "RPKT_LOST " : "",
1079 status & FTGMAC100_INT_AHB_ERR ? "AHB_ERR " : "",
1080 status & FTGMAC100_INT_PHYSTS_CHG ? "PHYSTS_CHG" : "");
1081
1082 if (status & FTGMAC100_INT_NO_RXBUF) {
1083 /* RX buffer unavailable */
1084 netdev->stats.rx_over_errors++;
1085 }
1086
1087 if (status & FTGMAC100_INT_RPKT_LOST) {
1088 /* received packet lost due to RX FIFO full */
1089 netdev->stats.rx_fifo_errors++;
1090 }
1091 }
1092
1093 if (completed) {
1094 napi_complete(napi);
1095
1096 /* enable all interrupts */
1097 iowrite32(INT_MASK_ALL_ENABLED, priv->base + FTGMAC100_OFFSET_IER);
1098 }
1099
1100 return rx;
1101}
1102
1103/******************************************************************************
1104 * struct net_device_ops functions
1105 *****************************************************************************/
1106static int ftgmac100_open(struct net_device *netdev)
1107{
1108 struct ftgmac100 *priv = netdev_priv(netdev);
1109 int err;
1110
1111 err = ftgmac100_alloc_buffers(priv);
1112 if (err) {
1113 netdev_err(netdev, "failed to allocate buffers\n");
1114 goto err_alloc;
1115 }
1116
1117 err = request_irq(priv->irq, ftgmac100_interrupt, 0, netdev->name, netdev);
1118 if (err) {
1119 netdev_err(netdev, "failed to request irq %d\n", priv->irq);
1120 goto err_irq;
1121 }
1122
1123 priv->rx_pointer = 0;
1124 priv->tx_clean_pointer = 0;
1125 priv->tx_pointer = 0;
1126 priv->tx_pending = 0;
1127
1128 err = ftgmac100_reset_hw(priv);
1129 if (err)
1130 goto err_hw;
1131
1132 ftgmac100_init_hw(priv);
Gavin Shanbd466c32016-07-19 11:54:23 +10001133 ftgmac100_start_hw(priv, priv->use_ncsi ? 100 : 10);
1134 if (netdev->phydev)
1135 phy_start(netdev->phydev);
1136 else if (priv->use_ncsi)
1137 netif_carrier_on(netdev);
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001138
1139 napi_enable(&priv->napi);
1140 netif_start_queue(netdev);
1141
1142 /* enable all interrupts */
1143 iowrite32(INT_MASK_ALL_ENABLED, priv->base + FTGMAC100_OFFSET_IER);
Gavin Shanbd466c32016-07-19 11:54:23 +10001144
1145 /* Start the NCSI device */
1146 if (priv->use_ncsi) {
1147 err = ncsi_start_dev(priv->ndev);
1148 if (err)
1149 goto err_ncsi;
1150 }
1151
1152 priv->enabled = true;
1153
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001154 return 0;
1155
Gavin Shanbd466c32016-07-19 11:54:23 +10001156err_ncsi:
1157 napi_disable(&priv->napi);
1158 netif_stop_queue(netdev);
1159 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER);
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001160err_hw:
1161 free_irq(priv->irq, netdev);
1162err_irq:
1163 ftgmac100_free_buffers(priv);
1164err_alloc:
1165 return err;
1166}
1167
1168static int ftgmac100_stop(struct net_device *netdev)
1169{
1170 struct ftgmac100 *priv = netdev_priv(netdev);
1171
Gavin Shanbd466c32016-07-19 11:54:23 +10001172 if (!priv->enabled)
1173 return 0;
1174
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001175 /* disable all interrupts */
Gavin Shanbd466c32016-07-19 11:54:23 +10001176 priv->enabled = false;
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001177 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER);
1178
1179 netif_stop_queue(netdev);
1180 napi_disable(&priv->napi);
Gavin Shanbd466c32016-07-19 11:54:23 +10001181 if (netdev->phydev)
1182 phy_stop(netdev->phydev);
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001183
1184 ftgmac100_stop_hw(priv);
1185 free_irq(priv->irq, netdev);
1186 ftgmac100_free_buffers(priv);
1187
1188 return 0;
1189}
1190
1191static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
1192 struct net_device *netdev)
1193{
1194 struct ftgmac100 *priv = netdev_priv(netdev);
1195 dma_addr_t map;
1196
1197 if (unlikely(skb->len > MAX_PKT_SIZE)) {
1198 if (net_ratelimit())
1199 netdev_dbg(netdev, "tx packet too big\n");
1200
1201 netdev->stats.tx_dropped++;
Eric Dumazet0113e342014-01-16 23:38:24 -08001202 kfree_skb(skb);
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001203 return NETDEV_TX_OK;
1204 }
1205
1206 map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
1207 if (unlikely(dma_mapping_error(priv->dev, map))) {
1208 /* drop packet */
1209 if (net_ratelimit())
1210 netdev_err(netdev, "map socket buffer failed\n");
1211
1212 netdev->stats.tx_dropped++;
Eric Dumazet0113e342014-01-16 23:38:24 -08001213 kfree_skb(skb);
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001214 return NETDEV_TX_OK;
1215 }
1216
1217 return ftgmac100_xmit(priv, skb, map);
1218}
1219
1220/* optional */
1221static int ftgmac100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
1222{
Gavin Shanbd466c32016-07-19 11:54:23 +10001223 if (!netdev->phydev)
1224 return -ENXIO;
1225
Philippe Reynesb3c40ad2016-05-16 01:35:13 +02001226 return phy_mii_ioctl(netdev->phydev, ifr, cmd);
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001227}
1228
1229static const struct net_device_ops ftgmac100_netdev_ops = {
1230 .ndo_open = ftgmac100_open,
1231 .ndo_stop = ftgmac100_stop,
1232 .ndo_start_xmit = ftgmac100_hard_start_xmit,
Gavin Shan113ce102016-07-19 11:54:22 +10001233 .ndo_set_mac_address = ftgmac100_set_mac_addr,
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001234 .ndo_validate_addr = eth_validate_addr,
1235 .ndo_do_ioctl = ftgmac100_do_ioctl,
1236};
1237
Gavin Shaneb418182016-07-19 11:54:21 +10001238static int ftgmac100_setup_mdio(struct net_device *netdev)
1239{
1240 struct ftgmac100 *priv = netdev_priv(netdev);
1241 struct platform_device *pdev = to_platform_device(priv->dev);
1242 int i, err = 0;
1243
1244 /* initialize mdio bus */
1245 priv->mii_bus = mdiobus_alloc();
1246 if (!priv->mii_bus)
1247 return -EIO;
1248
1249 priv->mii_bus->name = "ftgmac100_mdio";
1250 snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%d",
1251 pdev->name, pdev->id);
1252 priv->mii_bus->priv = priv->netdev;
1253 priv->mii_bus->read = ftgmac100_mdiobus_read;
1254 priv->mii_bus->write = ftgmac100_mdiobus_write;
1255
1256 for (i = 0; i < PHY_MAX_ADDR; i++)
1257 priv->mii_bus->irq[i] = PHY_POLL;
1258
1259 err = mdiobus_register(priv->mii_bus);
1260 if (err) {
1261 dev_err(priv->dev, "Cannot register MDIO bus!\n");
1262 goto err_register_mdiobus;
1263 }
1264
1265 err = ftgmac100_mii_probe(priv);
1266 if (err) {
1267 dev_err(priv->dev, "MII Probe failed!\n");
1268 goto err_mii_probe;
1269 }
1270
1271 return 0;
1272
1273err_mii_probe:
1274 mdiobus_unregister(priv->mii_bus);
1275err_register_mdiobus:
1276 mdiobus_free(priv->mii_bus);
1277 return err;
1278}
1279
1280static void ftgmac100_destroy_mdio(struct net_device *netdev)
1281{
1282 struct ftgmac100 *priv = netdev_priv(netdev);
1283
1284 if (!netdev->phydev)
1285 return;
1286
1287 phy_disconnect(netdev->phydev);
1288 mdiobus_unregister(priv->mii_bus);
1289 mdiobus_free(priv->mii_bus);
1290}
1291
Gavin Shanbd466c32016-07-19 11:54:23 +10001292static void ftgmac100_ncsi_handler(struct ncsi_dev *nd)
1293{
1294 if (unlikely(nd->state != ncsi_dev_state_functional))
1295 return;
1296
1297 netdev_info(nd->dev, "NCSI interface %s\n",
1298 nd->link_up ? "up" : "down");
1299}
1300
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001301/******************************************************************************
1302 * struct platform_driver functions
1303 *****************************************************************************/
1304static int ftgmac100_probe(struct platform_device *pdev)
1305{
1306 struct resource *res;
1307 int irq;
1308 struct net_device *netdev;
1309 struct ftgmac100 *priv;
Gavin Shanbd466c32016-07-19 11:54:23 +10001310 int err = 0;
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001311
1312 if (!pdev)
1313 return -ENODEV;
1314
1315 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1316 if (!res)
1317 return -ENXIO;
1318
1319 irq = platform_get_irq(pdev, 0);
1320 if (irq < 0)
1321 return irq;
1322
1323 /* setup net_device */
1324 netdev = alloc_etherdev(sizeof(*priv));
1325 if (!netdev) {
1326 err = -ENOMEM;
1327 goto err_alloc_etherdev;
1328 }
1329
1330 SET_NETDEV_DEV(netdev, &pdev->dev);
1331
Wilfried Klaebe7ad24ea2014-05-11 00:12:32 +00001332 netdev->ethtool_ops = &ftgmac100_ethtool_ops;
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001333 netdev->netdev_ops = &ftgmac100_netdev_ops;
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001334
1335 platform_set_drvdata(pdev, netdev);
1336
1337 /* setup private data */
1338 priv = netdev_priv(netdev);
1339 priv->netdev = netdev;
1340 priv->dev = &pdev->dev;
1341
1342 spin_lock_init(&priv->tx_lock);
1343
1344 /* initialize NAPI */
1345 netif_napi_add(netdev, &priv->napi, ftgmac100_poll, 64);
1346
1347 /* map io memory */
1348 priv->res = request_mem_region(res->start, resource_size(res),
1349 dev_name(&pdev->dev));
1350 if (!priv->res) {
1351 dev_err(&pdev->dev, "Could not reserve memory region\n");
1352 err = -ENOMEM;
1353 goto err_req_mem;
1354 }
1355
1356 priv->base = ioremap(res->start, resource_size(res));
1357 if (!priv->base) {
1358 dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n");
1359 err = -EIO;
1360 goto err_ioremap;
1361 }
1362
1363 priv->irq = irq;
1364
Gavin Shan113ce102016-07-19 11:54:22 +10001365 /* MAC address from chip or random one */
1366 ftgmac100_setup_mac(priv);
1367
Gavin Shanbd466c32016-07-19 11:54:23 +10001368 if (pdev->dev.of_node &&
1369 of_get_property(pdev->dev.of_node, "use-ncsi", NULL)) {
1370 if (!IS_ENABLED(CONFIG_NET_NCSI)) {
1371 dev_err(&pdev->dev, "NCSI stack not enabled\n");
1372 goto err_ncsi_dev;
1373 }
1374
1375 dev_info(&pdev->dev, "Using NCSI interface\n");
1376 priv->use_ncsi = true;
1377 priv->ndev = ncsi_register_dev(netdev, ftgmac100_ncsi_handler);
1378 if (!priv->ndev)
1379 goto err_ncsi_dev;
1380 } else {
1381 priv->use_ncsi = false;
1382 err = ftgmac100_setup_mdio(netdev);
1383 if (err)
1384 goto err_setup_mdio;
1385 }
1386
1387 /* We have to disable on-chip IP checksum functionality
1388 * when NCSI is enabled on the interface. It doesn't work
1389 * in that case.
1390 */
1391 netdev->features = NETIF_F_IP_CSUM | NETIF_F_GRO;
1392 if (priv->use_ncsi &&
1393 of_get_property(pdev->dev.of_node, "no-hw-checksum", NULL))
1394 netdev->features &= ~NETIF_F_IP_CSUM;
1395
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001396
1397 /* register network device */
1398 err = register_netdev(netdev);
1399 if (err) {
1400 dev_err(&pdev->dev, "Failed to register netdev\n");
1401 goto err_register_netdev;
1402 }
1403
1404 netdev_info(netdev, "irq %d, mapped at %p\n", priv->irq, priv->base);
1405
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001406 return 0;
1407
Gavin Shanbd466c32016-07-19 11:54:23 +10001408err_ncsi_dev:
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001409err_register_netdev:
Gavin Shaneb418182016-07-19 11:54:21 +10001410 ftgmac100_destroy_mdio(netdev);
1411err_setup_mdio:
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001412 iounmap(priv->base);
1413err_ioremap:
1414 release_resource(priv->res);
1415err_req_mem:
1416 netif_napi_del(&priv->napi);
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001417 free_netdev(netdev);
1418err_alloc_etherdev:
1419 return err;
1420}
1421
1422static int __exit ftgmac100_remove(struct platform_device *pdev)
1423{
1424 struct net_device *netdev;
1425 struct ftgmac100 *priv;
1426
1427 netdev = platform_get_drvdata(pdev);
1428 priv = netdev_priv(netdev);
1429
1430 unregister_netdev(netdev);
Gavin Shaneb418182016-07-19 11:54:21 +10001431 ftgmac100_destroy_mdio(netdev);
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001432
1433 iounmap(priv->base);
1434 release_resource(priv->res);
1435
1436 netif_napi_del(&priv->napi);
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001437 free_netdev(netdev);
1438 return 0;
1439}
1440
Gavin Shanbb168e22016-07-19 11:54:24 +10001441static const struct of_device_id ftgmac100_of_match[] = {
1442 { .compatible = "faraday,ftgmac100" },
1443 { }
1444};
1445MODULE_DEVICE_TABLE(of, ftgmac100_of_match);
1446
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001447static struct platform_driver ftgmac100_driver = {
Gavin Shanbb168e22016-07-19 11:54:24 +10001448 .probe = ftgmac100_probe,
1449 .remove = __exit_p(ftgmac100_remove),
1450 .driver = {
1451 .name = DRV_NAME,
1452 .of_match_table = ftgmac100_of_match,
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001453 },
1454};
Sachin Kamat14f645d2013-03-18 01:50:48 +00001455module_platform_driver(ftgmac100_driver);
Po-Yu Chuang69785b72011-06-08 23:32:48 +00001456
1457MODULE_AUTHOR("Po-Yu Chuang <ratbert@faraday-tech.com>");
1458MODULE_DESCRIPTION("FTGMAC100 driver");
1459MODULE_LICENSE("GPL");