1 | // SPDX-License-Identifier: GPL-2.0-or-later |
---|---|
2 | /* |
3 | * Faraday FTGMAC100 Gigabit Ethernet |
4 | * |
5 | * (C) Copyright 2009-2011 Faraday Technology |
6 | * Po-Yu Chuang <ratbert@faraday-tech.com> |
7 | */ |
8 | |
9 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
10 | |
11 | #include <linux/clk.h> |
12 | #include <linux/dma-mapping.h> |
13 | #include <linux/etherdevice.h> |
14 | #include <linux/ethtool.h> |
15 | #include <linux/interrupt.h> |
16 | #include <linux/io.h> |
17 | #include <linux/module.h> |
18 | #include <linux/netdevice.h> |
19 | #include <linux/of.h> |
20 | #include <linux/of_mdio.h> |
21 | #include <linux/phy.h> |
22 | #include <linux/platform_device.h> |
23 | #include <linux/property.h> |
24 | #include <linux/crc32.h> |
25 | #include <linux/if_vlan.h> |
26 | #include <linux/of_net.h> |
27 | #include <linux/phy_fixed.h> |
28 | #include <net/ip.h> |
29 | #include <net/ncsi.h> |
30 | |
31 | #include "ftgmac100.h" |
32 | |
33 | #define DRV_NAME "ftgmac100" |
34 | |
35 | /* Arbitrary values, I am not sure the HW has limits */ |
36 | #define MAX_RX_QUEUE_ENTRIES 1024 |
37 | #define MAX_TX_QUEUE_ENTRIES 1024 |
38 | #define MIN_RX_QUEUE_ENTRIES 32 |
39 | #define MIN_TX_QUEUE_ENTRIES 32 |
40 | |
41 | /* Defaults */ |
42 | #define DEF_RX_QUEUE_ENTRIES 128 |
43 | #define DEF_TX_QUEUE_ENTRIES 128 |
44 | |
45 | #define MAX_PKT_SIZE 1536 |
46 | #define RX_BUF_SIZE MAX_PKT_SIZE /* must be smaller than 0x3fff */ |
47 | |
48 | /* Min number of tx ring entries before stopping queue */ |
49 | #define TX_THRESHOLD (MAX_SKB_FRAGS + 1) |
50 | |
51 | #define FTGMAC_100MHZ 100000000 |
52 | #define FTGMAC_25MHZ 25000000 |
53 | |
54 | /* For NC-SI to register a fixed-link phy device */ |
55 | static struct fixed_phy_status ncsi_phy_status = { |
56 | .link = 1, |
57 | .speed = SPEED_100, |
58 | .duplex = DUPLEX_FULL, |
59 | .pause = 0, |
60 | .asym_pause = 0 |
61 | }; |
62 | |
63 | struct ftgmac100 { |
64 | /* Registers */ |
65 | struct resource *res; |
66 | void __iomem *base; |
67 | |
68 | /* Rx ring */ |
69 | unsigned int rx_q_entries; |
70 | struct ftgmac100_rxdes *rxdes; |
71 | dma_addr_t rxdes_dma; |
72 | struct sk_buff **rx_skbs; |
73 | unsigned int rx_pointer; |
74 | u32 rxdes0_edorr_mask; |
75 | |
76 | /* Tx ring */ |
77 | unsigned int tx_q_entries; |
78 | struct ftgmac100_txdes *txdes; |
79 | dma_addr_t txdes_dma; |
80 | struct sk_buff **tx_skbs; |
81 | unsigned int tx_clean_pointer; |
82 | unsigned int tx_pointer; |
83 | u32 txdes0_edotr_mask; |
84 | |
85 | /* Used to signal the reset task of ring change request */ |
86 | unsigned int new_rx_q_entries; |
87 | unsigned int new_tx_q_entries; |
88 | |
89 | /* Scratch page to use when rx skb alloc fails */ |
90 | void *rx_scratch; |
91 | dma_addr_t rx_scratch_dma; |
92 | |
93 | /* Component structures */ |
94 | struct net_device *netdev; |
95 | struct device *dev; |
96 | struct ncsi_dev *ndev; |
97 | struct napi_struct napi; |
98 | struct work_struct reset_task; |
99 | struct mii_bus *mii_bus; |
100 | struct clk *clk; |
101 | |
102 | /* AST2500/AST2600 RMII ref clock gate */ |
103 | struct clk *rclk; |
104 | |
105 | /* Link management */ |
106 | int cur_speed; |
107 | int cur_duplex; |
108 | bool use_ncsi; |
109 | |
110 | /* Multicast filter settings */ |
111 | u32 maht0; |
112 | u32 maht1; |
113 | |
114 | /* Flow control settings */ |
115 | bool tx_pause; |
116 | bool rx_pause; |
117 | bool aneg_pause; |
118 | |
119 | /* Misc */ |
120 | bool need_mac_restart; |
121 | bool is_aspeed; |
122 | }; |
123 | |
124 | static int ftgmac100_reset_mac(struct ftgmac100 *priv, u32 maccr) |
125 | { |
126 | struct net_device *netdev = priv->netdev; |
127 | int i; |
128 | |
129 | /* NOTE: reset clears all registers */ |
130 | iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR); |
131 | iowrite32(maccr | FTGMAC100_MACCR_SW_RST, |
132 | priv->base + FTGMAC100_OFFSET_MACCR); |
133 | for (i = 0; i < 200; i++) { |
134 | unsigned int maccr; |
135 | |
136 | maccr = ioread32(priv->base + FTGMAC100_OFFSET_MACCR); |
137 | if (!(maccr & FTGMAC100_MACCR_SW_RST)) |
138 | return 0; |
139 | |
140 | udelay(usec: 1); |
141 | } |
142 | |
143 | netdev_err(dev: netdev, format: "Hardware reset failed\n"); |
144 | return -EIO; |
145 | } |
146 | |
147 | static int ftgmac100_reset_and_config_mac(struct ftgmac100 *priv) |
148 | { |
149 | u32 maccr = 0; |
150 | |
151 | switch (priv->cur_speed) { |
152 | case SPEED_10: |
153 | case 0: /* no link */ |
154 | break; |
155 | |
156 | case SPEED_100: |
157 | maccr |= FTGMAC100_MACCR_FAST_MODE; |
158 | break; |
159 | |
160 | case SPEED_1000: |
161 | maccr |= FTGMAC100_MACCR_GIGA_MODE; |
162 | break; |
163 | default: |
164 | netdev_err(dev: priv->netdev, format: "Unknown speed %d !\n", |
165 | priv->cur_speed); |
166 | break; |
167 | } |
168 | |
169 | /* (Re)initialize the queue pointers */ |
170 | priv->rx_pointer = 0; |
171 | priv->tx_clean_pointer = 0; |
172 | priv->tx_pointer = 0; |
173 | |
174 | /* The doc says reset twice with 10us interval */ |
175 | if (ftgmac100_reset_mac(priv, maccr)) |
176 | return -EIO; |
177 | usleep_range(min: 10, max: 1000); |
178 | return ftgmac100_reset_mac(priv, maccr); |
179 | } |
180 | |
181 | static void ftgmac100_write_mac_addr(struct ftgmac100 *priv, const u8 *mac) |
182 | { |
183 | unsigned int maddr = mac[0] << 8 | mac[1]; |
184 | unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; |
185 | |
186 | iowrite32(maddr, priv->base + FTGMAC100_OFFSET_MAC_MADR); |
187 | iowrite32(laddr, priv->base + FTGMAC100_OFFSET_MAC_LADR); |
188 | } |
189 | |
190 | static int ftgmac100_initial_mac(struct ftgmac100 *priv) |
191 | { |
192 | u8 mac[ETH_ALEN]; |
193 | unsigned int m; |
194 | unsigned int l; |
195 | int err; |
196 | |
197 | err = of_get_ethdev_address(np: priv->dev->of_node, dev: priv->netdev); |
198 | if (err == -EPROBE_DEFER) |
199 | return err; |
200 | if (!err) { |
201 | dev_info(priv->dev, "Read MAC address %pM from device tree\n", |
202 | priv->netdev->dev_addr); |
203 | return 0; |
204 | } |
205 | |
206 | m = ioread32(priv->base + FTGMAC100_OFFSET_MAC_MADR); |
207 | l = ioread32(priv->base + FTGMAC100_OFFSET_MAC_LADR); |
208 | |
209 | mac[0] = (m >> 8) & 0xff; |
210 | mac[1] = m & 0xff; |
211 | mac[2] = (l >> 24) & 0xff; |
212 | mac[3] = (l >> 16) & 0xff; |
213 | mac[4] = (l >> 8) & 0xff; |
214 | mac[5] = l & 0xff; |
215 | |
216 | if (is_valid_ether_addr(addr: mac)) { |
217 | eth_hw_addr_set(dev: priv->netdev, addr: mac); |
218 | dev_info(priv->dev, "Read MAC address %pM from chip\n", mac); |
219 | } else { |
220 | eth_hw_addr_random(dev: priv->netdev); |
221 | dev_info(priv->dev, "Generated random MAC address %pM\n", |
222 | priv->netdev->dev_addr); |
223 | } |
224 | |
225 | return 0; |
226 | } |
227 | |
228 | static int ftgmac100_set_mac_addr(struct net_device *dev, void *p) |
229 | { |
230 | int ret; |
231 | |
232 | ret = eth_prepare_mac_addr_change(dev, p); |
233 | if (ret < 0) |
234 | return ret; |
235 | |
236 | eth_commit_mac_addr_change(dev, p); |
237 | ftgmac100_write_mac_addr(priv: netdev_priv(dev), mac: dev->dev_addr); |
238 | |
239 | return 0; |
240 | } |
241 | |
242 | static void ftgmac100_config_pause(struct ftgmac100 *priv) |
243 | { |
244 | u32 fcr = FTGMAC100_FCR_PAUSE_TIME(16); |
245 | |
246 | /* Throttle tx queue when receiving pause frames */ |
247 | if (priv->rx_pause) |
248 | fcr |= FTGMAC100_FCR_FC_EN; |
249 | |
250 | /* Enables sending pause frames when the RX queue is past a |
251 | * certain threshold. |
252 | */ |
253 | if (priv->tx_pause) |
254 | fcr |= FTGMAC100_FCR_FCTHR_EN; |
255 | |
256 | iowrite32(fcr, priv->base + FTGMAC100_OFFSET_FCR); |
257 | } |
258 | |
259 | static void ftgmac100_init_hw(struct ftgmac100 *priv) |
260 | { |
261 | u32 reg, rfifo_sz, tfifo_sz; |
262 | |
263 | /* Clear stale interrupts */ |
264 | reg = ioread32(priv->base + FTGMAC100_OFFSET_ISR); |
265 | iowrite32(reg, priv->base + FTGMAC100_OFFSET_ISR); |
266 | |
267 | /* Setup RX ring buffer base */ |
268 | iowrite32(priv->rxdes_dma, priv->base + FTGMAC100_OFFSET_RXR_BADR); |
269 | |
270 | /* Setup TX ring buffer base */ |
271 | iowrite32(priv->txdes_dma, priv->base + FTGMAC100_OFFSET_NPTXR_BADR); |
272 | |
273 | /* Configure RX buffer size */ |
274 | iowrite32(FTGMAC100_RBSR_SIZE(RX_BUF_SIZE), |
275 | priv->base + FTGMAC100_OFFSET_RBSR); |
276 | |
277 | /* Set RX descriptor autopoll */ |
278 | iowrite32(FTGMAC100_APTC_RXPOLL_CNT(1), |
279 | priv->base + FTGMAC100_OFFSET_APTC); |
280 | |
281 | /* Write MAC address */ |
282 | ftgmac100_write_mac_addr(priv, mac: priv->netdev->dev_addr); |
283 | |
284 | /* Write multicast filter */ |
285 | iowrite32(priv->maht0, priv->base + FTGMAC100_OFFSET_MAHT0); |
286 | iowrite32(priv->maht1, priv->base + FTGMAC100_OFFSET_MAHT1); |
287 | |
288 | /* Configure descriptor sizes and increase burst sizes according |
289 | * to values in Aspeed SDK. The FIFO arbitration is enabled and |
290 | * the thresholds set based on the recommended values in the |
291 | * AST2400 specification. |
292 | */ |
293 | iowrite32(FTGMAC100_DBLAC_RXDES_SIZE(2) | /* 2*8 bytes RX descs */ |
294 | FTGMAC100_DBLAC_TXDES_SIZE(2) | /* 2*8 bytes TX descs */ |
295 | FTGMAC100_DBLAC_RXBURST_SIZE(3) | /* 512 bytes max RX bursts */ |
296 | FTGMAC100_DBLAC_TXBURST_SIZE(3) | /* 512 bytes max TX bursts */ |
297 | FTGMAC100_DBLAC_RX_THR_EN | /* Enable fifo threshold arb */ |
298 | FTGMAC100_DBLAC_RXFIFO_HTHR(6) | /* 6/8 of FIFO high threshold */ |
299 | FTGMAC100_DBLAC_RXFIFO_LTHR(2), /* 2/8 of FIFO low threshold */ |
300 | priv->base + FTGMAC100_OFFSET_DBLAC); |
301 | |
302 | /* Interrupt mitigation configured for 1 interrupt/packet. HW interrupt |
303 | * mitigation doesn't seem to provide any benefit with NAPI so leave |
304 | * it at that. |
305 | */ |
306 | iowrite32(FTGMAC100_ITC_RXINT_THR(1) | |
307 | FTGMAC100_ITC_TXINT_THR(1), |
308 | priv->base + FTGMAC100_OFFSET_ITC); |
309 | |
310 | /* Configure FIFO sizes in the TPAFCR register */ |
311 | reg = ioread32(priv->base + FTGMAC100_OFFSET_FEAR); |
312 | rfifo_sz = reg & 0x00000007; |
313 | tfifo_sz = (reg >> 3) & 0x00000007; |
314 | reg = ioread32(priv->base + FTGMAC100_OFFSET_TPAFCR); |
315 | reg &= ~0x3f000000; |
316 | reg |= (tfifo_sz << 27); |
317 | reg |= (rfifo_sz << 24); |
318 | iowrite32(reg, priv->base + FTGMAC100_OFFSET_TPAFCR); |
319 | } |
320 | |
321 | static void ftgmac100_start_hw(struct ftgmac100 *priv) |
322 | { |
323 | u32 maccr = ioread32(priv->base + FTGMAC100_OFFSET_MACCR); |
324 | |
325 | /* Keep the original GMAC and FAST bits */ |
326 | maccr &= (FTGMAC100_MACCR_FAST_MODE | FTGMAC100_MACCR_GIGA_MODE); |
327 | |
328 | /* Add all the main enable bits */ |
329 | maccr |= FTGMAC100_MACCR_TXDMA_EN | |
330 | FTGMAC100_MACCR_RXDMA_EN | |
331 | FTGMAC100_MACCR_TXMAC_EN | |
332 | FTGMAC100_MACCR_RXMAC_EN | |
333 | FTGMAC100_MACCR_CRC_APD | |
334 | FTGMAC100_MACCR_PHY_LINK_LEVEL | |
335 | FTGMAC100_MACCR_RX_RUNT | |
336 | FTGMAC100_MACCR_RX_BROADPKT; |
337 | |
338 | /* Add other bits as needed */ |
339 | if (priv->cur_duplex == DUPLEX_FULL) |
340 | maccr |= FTGMAC100_MACCR_FULLDUP; |
341 | if (priv->netdev->flags & IFF_PROMISC) |
342 | maccr |= FTGMAC100_MACCR_RX_ALL; |
343 | if (priv->netdev->flags & IFF_ALLMULTI) |
344 | maccr |= FTGMAC100_MACCR_RX_MULTIPKT; |
345 | else if (netdev_mc_count(priv->netdev)) |
346 | maccr |= FTGMAC100_MACCR_HT_MULTI_EN; |
347 | |
348 | /* Vlan filtering enabled */ |
349 | if (priv->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) |
350 | maccr |= FTGMAC100_MACCR_RM_VLAN; |
351 | |
352 | /* Hit the HW */ |
353 | iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR); |
354 | } |
355 | |
356 | static void ftgmac100_stop_hw(struct ftgmac100 *priv) |
357 | { |
358 | iowrite32(0, priv->base + FTGMAC100_OFFSET_MACCR); |
359 | } |
360 | |
361 | static void ftgmac100_calc_mc_hash(struct ftgmac100 *priv) |
362 | { |
363 | struct netdev_hw_addr *ha; |
364 | |
365 | priv->maht1 = 0; |
366 | priv->maht0 = 0; |
367 | netdev_for_each_mc_addr(ha, priv->netdev) { |
368 | u32 crc_val = ether_crc_le(ETH_ALEN, ha->addr); |
369 | |
370 | crc_val = (~(crc_val >> 2)) & 0x3f; |
371 | if (crc_val >= 32) |
372 | priv->maht1 |= 1ul << (crc_val - 32); |
373 | else |
374 | priv->maht0 |= 1ul << (crc_val); |
375 | } |
376 | } |
377 | |
378 | static void ftgmac100_set_rx_mode(struct net_device *netdev) |
379 | { |
380 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
381 | |
382 | /* Setup the hash filter */ |
383 | ftgmac100_calc_mc_hash(priv); |
384 | |
385 | /* Interface down ? that's all there is to do */ |
386 | if (!netif_running(dev: netdev)) |
387 | return; |
388 | |
389 | /* Update the HW */ |
390 | iowrite32(priv->maht0, priv->base + FTGMAC100_OFFSET_MAHT0); |
391 | iowrite32(priv->maht1, priv->base + FTGMAC100_OFFSET_MAHT1); |
392 | |
393 | /* Reconfigure MACCR */ |
394 | ftgmac100_start_hw(priv); |
395 | } |
396 | |
397 | static int ftgmac100_alloc_rx_buf(struct ftgmac100 *priv, unsigned int entry, |
398 | struct ftgmac100_rxdes *rxdes, gfp_t gfp) |
399 | { |
400 | struct net_device *netdev = priv->netdev; |
401 | struct sk_buff *skb; |
402 | dma_addr_t map; |
403 | int err = 0; |
404 | |
405 | skb = netdev_alloc_skb_ip_align(dev: netdev, RX_BUF_SIZE); |
406 | if (unlikely(!skb)) { |
407 | if (net_ratelimit()) |
408 | netdev_warn(dev: netdev, format: "failed to allocate rx skb\n"); |
409 | err = -ENOMEM; |
410 | map = priv->rx_scratch_dma; |
411 | } else { |
412 | map = dma_map_single(priv->dev, skb->data, RX_BUF_SIZE, |
413 | DMA_FROM_DEVICE); |
414 | if (unlikely(dma_mapping_error(priv->dev, map))) { |
415 | if (net_ratelimit()) |
416 | netdev_err(dev: netdev, format: "failed to map rx page\n"); |
417 | dev_kfree_skb_any(skb); |
418 | map = priv->rx_scratch_dma; |
419 | skb = NULL; |
420 | err = -ENOMEM; |
421 | } |
422 | } |
423 | |
424 | /* Store skb */ |
425 | priv->rx_skbs[entry] = skb; |
426 | |
427 | /* Store DMA address into RX desc */ |
428 | rxdes->rxdes3 = cpu_to_le32(map); |
429 | |
430 | /* Ensure the above is ordered vs clearing the OWN bit */ |
431 | dma_wmb(); |
432 | |
433 | /* Clean status (which resets own bit) */ |
434 | if (entry == (priv->rx_q_entries - 1)) |
435 | rxdes->rxdes0 = cpu_to_le32(priv->rxdes0_edorr_mask); |
436 | else |
437 | rxdes->rxdes0 = 0; |
438 | |
439 | return err; |
440 | } |
441 | |
442 | static unsigned int ftgmac100_next_rx_pointer(struct ftgmac100 *priv, |
443 | unsigned int pointer) |
444 | { |
445 | return (pointer + 1) & (priv->rx_q_entries - 1); |
446 | } |
447 | |
448 | static void ftgmac100_rx_packet_error(struct ftgmac100 *priv, u32 status) |
449 | { |
450 | struct net_device *netdev = priv->netdev; |
451 | |
452 | if (status & FTGMAC100_RXDES0_RX_ERR) |
453 | netdev->stats.rx_errors++; |
454 | |
455 | if (status & FTGMAC100_RXDES0_CRC_ERR) |
456 | netdev->stats.rx_crc_errors++; |
457 | |
458 | if (status & (FTGMAC100_RXDES0_FTL | |
459 | FTGMAC100_RXDES0_RUNT | |
460 | FTGMAC100_RXDES0_RX_ODD_NB)) |
461 | netdev->stats.rx_length_errors++; |
462 | } |
463 | |
464 | static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed) |
465 | { |
466 | struct net_device *netdev = priv->netdev; |
467 | struct ftgmac100_rxdes *rxdes; |
468 | struct sk_buff *skb; |
469 | unsigned int pointer, size; |
470 | u32 status, csum_vlan; |
471 | dma_addr_t map; |
472 | |
473 | /* Grab next RX descriptor */ |
474 | pointer = priv->rx_pointer; |
475 | rxdes = &priv->rxdes[pointer]; |
476 | |
477 | /* Grab descriptor status */ |
478 | status = le32_to_cpu(rxdes->rxdes0); |
479 | |
480 | /* Do we have a packet ? */ |
481 | if (!(status & FTGMAC100_RXDES0_RXPKT_RDY)) |
482 | return false; |
483 | |
484 | /* Order subsequent reads with the test for the ready bit */ |
485 | dma_rmb(); |
486 | |
487 | /* We don't cope with fragmented RX packets */ |
488 | if (unlikely(!(status & FTGMAC100_RXDES0_FRS) || |
489 | !(status & FTGMAC100_RXDES0_LRS))) |
490 | goto drop; |
491 | |
492 | /* Grab received size and csum vlan field in the descriptor */ |
493 | size = status & FTGMAC100_RXDES0_VDBC; |
494 | csum_vlan = le32_to_cpu(rxdes->rxdes1); |
495 | |
496 | /* Any error (other than csum offload) flagged ? */ |
497 | if (unlikely(status & RXDES0_ANY_ERROR)) { |
498 | /* Correct for incorrect flagging of runt packets |
499 | * with vlan tags... Just accept a runt packet that |
500 | * has been flagged as vlan and whose size is at |
501 | * least 60 bytes. |
502 | */ |
503 | if ((status & FTGMAC100_RXDES0_RUNT) && |
504 | (csum_vlan & FTGMAC100_RXDES1_VLANTAG_AVAIL) && |
505 | (size >= 60)) |
506 | status &= ~FTGMAC100_RXDES0_RUNT; |
507 | |
508 | /* Any error still in there ? */ |
509 | if (status & RXDES0_ANY_ERROR) { |
510 | ftgmac100_rx_packet_error(priv, status); |
511 | goto drop; |
512 | } |
513 | } |
514 | |
515 | /* If the packet had no skb (failed to allocate earlier) |
516 | * then try to allocate one and skip |
517 | */ |
518 | skb = priv->rx_skbs[pointer]; |
519 | if (!unlikely(skb)) { |
520 | ftgmac100_alloc_rx_buf(priv, entry: pointer, rxdes, GFP_ATOMIC); |
521 | goto drop; |
522 | } |
523 | |
524 | if (unlikely(status & FTGMAC100_RXDES0_MULTICAST)) |
525 | netdev->stats.multicast++; |
526 | |
527 | /* If the HW found checksum errors, bounce it to software. |
528 | * |
529 | * If we didn't, we need to see if the packet was recognized |
530 | * by HW as one of the supported checksummed protocols before |
531 | * we accept the HW test results. |
532 | */ |
533 | if (netdev->features & NETIF_F_RXCSUM) { |
534 | u32 err_bits = FTGMAC100_RXDES1_TCP_CHKSUM_ERR | |
535 | FTGMAC100_RXDES1_UDP_CHKSUM_ERR | |
536 | FTGMAC100_RXDES1_IP_CHKSUM_ERR; |
537 | if ((csum_vlan & err_bits) || |
538 | !(csum_vlan & FTGMAC100_RXDES1_PROT_MASK)) |
539 | skb->ip_summed = CHECKSUM_NONE; |
540 | else |
541 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
542 | } |
543 | |
544 | /* Transfer received size to skb */ |
545 | skb_put(skb, len: size); |
546 | |
547 | /* Extract vlan tag */ |
548 | if ((netdev->features & NETIF_F_HW_VLAN_CTAG_RX) && |
549 | (csum_vlan & FTGMAC100_RXDES1_VLANTAG_AVAIL)) |
550 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), |
551 | vlan_tci: csum_vlan & 0xffff); |
552 | |
553 | /* Tear down DMA mapping, do necessary cache management */ |
554 | map = le32_to_cpu(rxdes->rxdes3); |
555 | |
556 | #if defined(CONFIG_ARM) && !defined(CONFIG_ARM_DMA_USE_IOMMU) |
557 | /* When we don't have an iommu, we can save cycles by not |
558 | * invalidating the cache for the part of the packet that |
559 | * wasn't received. |
560 | */ |
561 | dma_unmap_single(priv->dev, map, size, DMA_FROM_DEVICE); |
562 | #else |
563 | dma_unmap_single(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); |
564 | #endif |
565 | |
566 | |
567 | /* Resplenish rx ring */ |
568 | ftgmac100_alloc_rx_buf(priv, entry: pointer, rxdes, GFP_ATOMIC); |
569 | priv->rx_pointer = ftgmac100_next_rx_pointer(priv, pointer); |
570 | |
571 | skb->protocol = eth_type_trans(skb, dev: netdev); |
572 | |
573 | netdev->stats.rx_packets++; |
574 | netdev->stats.rx_bytes += size; |
575 | |
576 | /* push packet to protocol stack */ |
577 | if (skb->ip_summed == CHECKSUM_NONE) |
578 | netif_receive_skb(skb); |
579 | else |
580 | napi_gro_receive(napi: &priv->napi, skb); |
581 | |
582 | (*processed)++; |
583 | return true; |
584 | |
585 | drop: |
586 | /* Clean rxdes0 (which resets own bit) */ |
587 | rxdes->rxdes0 = cpu_to_le32(status & priv->rxdes0_edorr_mask); |
588 | priv->rx_pointer = ftgmac100_next_rx_pointer(priv, pointer); |
589 | netdev->stats.rx_dropped++; |
590 | return true; |
591 | } |
592 | |
593 | static u32 ftgmac100_base_tx_ctlstat(struct ftgmac100 *priv, |
594 | unsigned int index) |
595 | { |
596 | if (index == (priv->tx_q_entries - 1)) |
597 | return priv->txdes0_edotr_mask; |
598 | else |
599 | return 0; |
600 | } |
601 | |
602 | static unsigned int ftgmac100_next_tx_pointer(struct ftgmac100 *priv, |
603 | unsigned int pointer) |
604 | { |
605 | return (pointer + 1) & (priv->tx_q_entries - 1); |
606 | } |
607 | |
608 | static u32 ftgmac100_tx_buf_avail(struct ftgmac100 *priv) |
609 | { |
610 | /* Returns the number of available slots in the TX queue |
611 | * |
612 | * This always leaves one free slot so we don't have to |
613 | * worry about empty vs. full, and this simplifies the |
614 | * test for ftgmac100_tx_buf_cleanable() below |
615 | */ |
616 | return (priv->tx_clean_pointer - priv->tx_pointer - 1) & |
617 | (priv->tx_q_entries - 1); |
618 | } |
619 | |
620 | static bool ftgmac100_tx_buf_cleanable(struct ftgmac100 *priv) |
621 | { |
622 | return priv->tx_pointer != priv->tx_clean_pointer; |
623 | } |
624 | |
625 | static void ftgmac100_free_tx_packet(struct ftgmac100 *priv, |
626 | unsigned int pointer, |
627 | struct sk_buff *skb, |
628 | struct ftgmac100_txdes *txdes, |
629 | u32 ctl_stat) |
630 | { |
631 | dma_addr_t map = le32_to_cpu(txdes->txdes3); |
632 | size_t len; |
633 | |
634 | if (ctl_stat & FTGMAC100_TXDES0_FTS) { |
635 | len = skb_headlen(skb); |
636 | dma_unmap_single(priv->dev, map, len, DMA_TO_DEVICE); |
637 | } else { |
638 | len = FTGMAC100_TXDES0_TXBUF_SIZE(ctl_stat); |
639 | dma_unmap_page(priv->dev, map, len, DMA_TO_DEVICE); |
640 | } |
641 | |
642 | /* Free SKB on last segment */ |
643 | if (ctl_stat & FTGMAC100_TXDES0_LTS) |
644 | dev_kfree_skb(skb); |
645 | priv->tx_skbs[pointer] = NULL; |
646 | } |
647 | |
648 | static bool ftgmac100_tx_complete_packet(struct ftgmac100 *priv) |
649 | { |
650 | struct net_device *netdev = priv->netdev; |
651 | struct ftgmac100_txdes *txdes; |
652 | struct sk_buff *skb; |
653 | unsigned int pointer; |
654 | u32 ctl_stat; |
655 | |
656 | pointer = priv->tx_clean_pointer; |
657 | txdes = &priv->txdes[pointer]; |
658 | |
659 | ctl_stat = le32_to_cpu(txdes->txdes0); |
660 | if (ctl_stat & FTGMAC100_TXDES0_TXDMA_OWN) |
661 | return false; |
662 | |
663 | skb = priv->tx_skbs[pointer]; |
664 | netdev->stats.tx_packets++; |
665 | netdev->stats.tx_bytes += skb->len; |
666 | ftgmac100_free_tx_packet(priv, pointer, skb, txdes, ctl_stat); |
667 | txdes->txdes0 = cpu_to_le32(ctl_stat & priv->txdes0_edotr_mask); |
668 | |
669 | /* Ensure the descriptor config is visible before setting the tx |
670 | * pointer. |
671 | */ |
672 | smp_wmb(); |
673 | |
674 | priv->tx_clean_pointer = ftgmac100_next_tx_pointer(priv, pointer); |
675 | |
676 | return true; |
677 | } |
678 | |
679 | static void ftgmac100_tx_complete(struct ftgmac100 *priv) |
680 | { |
681 | struct net_device *netdev = priv->netdev; |
682 | |
683 | /* Process all completed packets */ |
684 | while (ftgmac100_tx_buf_cleanable(priv) && |
685 | ftgmac100_tx_complete_packet(priv)) |
686 | ; |
687 | |
688 | /* Restart queue if needed */ |
689 | smp_mb(); |
690 | if (unlikely(netif_queue_stopped(netdev) && |
691 | ftgmac100_tx_buf_avail(priv) >= TX_THRESHOLD)) { |
692 | struct netdev_queue *txq; |
693 | |
694 | txq = netdev_get_tx_queue(dev: netdev, index: 0); |
695 | __netif_tx_lock(txq, smp_processor_id()); |
696 | if (netif_queue_stopped(dev: netdev) && |
697 | ftgmac100_tx_buf_avail(priv) >= TX_THRESHOLD) |
698 | netif_wake_queue(dev: netdev); |
699 | __netif_tx_unlock(txq); |
700 | } |
701 | } |
702 | |
703 | static bool ftgmac100_prep_tx_csum(struct sk_buff *skb, u32 *csum_vlan) |
704 | { |
705 | if (skb->protocol == cpu_to_be16(ETH_P_IP)) { |
706 | u8 ip_proto = ip_hdr(skb)->protocol; |
707 | |
708 | *csum_vlan |= FTGMAC100_TXDES1_IP_CHKSUM; |
709 | switch(ip_proto) { |
710 | case IPPROTO_TCP: |
711 | *csum_vlan |= FTGMAC100_TXDES1_TCP_CHKSUM; |
712 | return true; |
713 | case IPPROTO_UDP: |
714 | *csum_vlan |= FTGMAC100_TXDES1_UDP_CHKSUM; |
715 | return true; |
716 | case IPPROTO_IP: |
717 | return true; |
718 | } |
719 | } |
720 | return skb_checksum_help(skb) == 0; |
721 | } |
722 | |
723 | static netdev_tx_t ftgmac100_hard_start_xmit(struct sk_buff *skb, |
724 | struct net_device *netdev) |
725 | { |
726 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
727 | struct ftgmac100_txdes *txdes, *first; |
728 | unsigned int pointer, nfrags, len, i, j; |
729 | u32 f_ctl_stat, ctl_stat, csum_vlan; |
730 | dma_addr_t map; |
731 | |
732 | /* The HW doesn't pad small frames */ |
733 | if (eth_skb_pad(skb)) { |
734 | netdev->stats.tx_dropped++; |
735 | return NETDEV_TX_OK; |
736 | } |
737 | |
738 | /* Reject oversize packets */ |
739 | if (unlikely(skb->len > MAX_PKT_SIZE)) { |
740 | if (net_ratelimit()) |
741 | netdev_dbg(netdev, "tx packet too big\n"); |
742 | goto drop; |
743 | } |
744 | |
745 | /* Do we have a limit on #fragments ? I yet have to get a reply |
746 | * from Aspeed. If there's one I haven't hit it. |
747 | */ |
748 | nfrags = skb_shinfo(skb)->nr_frags; |
749 | |
750 | /* Setup HW checksumming */ |
751 | csum_vlan = 0; |
752 | if (skb->ip_summed == CHECKSUM_PARTIAL && |
753 | !ftgmac100_prep_tx_csum(skb, csum_vlan: &csum_vlan)) |
754 | goto drop; |
755 | |
756 | /* Add VLAN tag */ |
757 | if (skb_vlan_tag_present(skb)) { |
758 | csum_vlan |= FTGMAC100_TXDES1_INS_VLANTAG; |
759 | csum_vlan |= skb_vlan_tag_get(skb) & 0xffff; |
760 | } |
761 | |
762 | /* Get header len */ |
763 | len = skb_headlen(skb); |
764 | |
765 | /* Map the packet head */ |
766 | map = dma_map_single(priv->dev, skb->data, len, DMA_TO_DEVICE); |
767 | if (dma_mapping_error(dev: priv->dev, dma_addr: map)) { |
768 | if (net_ratelimit()) |
769 | netdev_err(dev: netdev, format: "map tx packet head failed\n"); |
770 | goto drop; |
771 | } |
772 | |
773 | /* Grab the next free tx descriptor */ |
774 | pointer = priv->tx_pointer; |
775 | txdes = first = &priv->txdes[pointer]; |
776 | |
777 | /* Setup it up with the packet head. Don't write the head to the |
778 | * ring just yet |
779 | */ |
780 | priv->tx_skbs[pointer] = skb; |
781 | f_ctl_stat = ftgmac100_base_tx_ctlstat(priv, index: pointer); |
782 | f_ctl_stat |= FTGMAC100_TXDES0_TXDMA_OWN; |
783 | f_ctl_stat |= FTGMAC100_TXDES0_TXBUF_SIZE(len); |
784 | f_ctl_stat |= FTGMAC100_TXDES0_FTS; |
785 | if (nfrags == 0) |
786 | f_ctl_stat |= FTGMAC100_TXDES0_LTS; |
787 | txdes->txdes3 = cpu_to_le32(map); |
788 | txdes->txdes1 = cpu_to_le32(csum_vlan); |
789 | |
790 | /* Next descriptor */ |
791 | pointer = ftgmac100_next_tx_pointer(priv, pointer); |
792 | |
793 | /* Add the fragments */ |
794 | for (i = 0; i < nfrags; i++) { |
795 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
796 | |
797 | len = skb_frag_size(frag); |
798 | |
799 | /* Map it */ |
800 | map = skb_frag_dma_map(priv->dev, frag, 0, len, |
801 | DMA_TO_DEVICE); |
802 | if (dma_mapping_error(dev: priv->dev, dma_addr: map)) |
803 | goto dma_err; |
804 | |
805 | /* Setup descriptor */ |
806 | priv->tx_skbs[pointer] = skb; |
807 | txdes = &priv->txdes[pointer]; |
808 | ctl_stat = ftgmac100_base_tx_ctlstat(priv, index: pointer); |
809 | ctl_stat |= FTGMAC100_TXDES0_TXDMA_OWN; |
810 | ctl_stat |= FTGMAC100_TXDES0_TXBUF_SIZE(len); |
811 | if (i == (nfrags - 1)) |
812 | ctl_stat |= FTGMAC100_TXDES0_LTS; |
813 | txdes->txdes0 = cpu_to_le32(ctl_stat); |
814 | txdes->txdes1 = 0; |
815 | txdes->txdes3 = cpu_to_le32(map); |
816 | |
817 | /* Next one */ |
818 | pointer = ftgmac100_next_tx_pointer(priv, pointer); |
819 | } |
820 | |
821 | /* Order the previous packet and descriptor udpates |
822 | * before setting the OWN bit on the first descriptor. |
823 | */ |
824 | dma_wmb(); |
825 | first->txdes0 = cpu_to_le32(f_ctl_stat); |
826 | |
827 | /* Ensure the descriptor config is visible before setting the tx |
828 | * pointer. |
829 | */ |
830 | smp_wmb(); |
831 | |
832 | /* Update next TX pointer */ |
833 | priv->tx_pointer = pointer; |
834 | |
835 | /* If there isn't enough room for all the fragments of a new packet |
836 | * in the TX ring, stop the queue. The sequence below is race free |
837 | * vs. a concurrent restart in ftgmac100_poll() |
838 | */ |
839 | if (unlikely(ftgmac100_tx_buf_avail(priv) < TX_THRESHOLD)) { |
840 | netif_stop_queue(dev: netdev); |
841 | /* Order the queue stop with the test below */ |
842 | smp_mb(); |
843 | if (ftgmac100_tx_buf_avail(priv) >= TX_THRESHOLD) |
844 | netif_wake_queue(dev: netdev); |
845 | } |
846 | |
847 | /* Poke transmitter to read the updated TX descriptors */ |
848 | iowrite32(1, priv->base + FTGMAC100_OFFSET_NPTXPD); |
849 | |
850 | return NETDEV_TX_OK; |
851 | |
852 | dma_err: |
853 | if (net_ratelimit()) |
854 | netdev_err(dev: netdev, format: "map tx fragment failed\n"); |
855 | |
856 | /* Free head */ |
857 | pointer = priv->tx_pointer; |
858 | ftgmac100_free_tx_packet(priv, pointer, skb, txdes: first, ctl_stat: f_ctl_stat); |
859 | first->txdes0 = cpu_to_le32(f_ctl_stat & priv->txdes0_edotr_mask); |
860 | |
861 | /* Then all fragments */ |
862 | for (j = 0; j < i; j++) { |
863 | pointer = ftgmac100_next_tx_pointer(priv, pointer); |
864 | txdes = &priv->txdes[pointer]; |
865 | ctl_stat = le32_to_cpu(txdes->txdes0); |
866 | ftgmac100_free_tx_packet(priv, pointer, skb, txdes, ctl_stat); |
867 | txdes->txdes0 = cpu_to_le32(ctl_stat & priv->txdes0_edotr_mask); |
868 | } |
869 | |
870 | /* This cannot be reached if we successfully mapped the |
871 | * last fragment, so we know ftgmac100_free_tx_packet() |
872 | * hasn't freed the skb yet. |
873 | */ |
874 | drop: |
875 | /* Drop the packet */ |
876 | dev_kfree_skb_any(skb); |
877 | netdev->stats.tx_dropped++; |
878 | |
879 | return NETDEV_TX_OK; |
880 | } |
881 | |
882 | static void ftgmac100_free_buffers(struct ftgmac100 *priv) |
883 | { |
884 | int i; |
885 | |
886 | /* Free all RX buffers */ |
887 | for (i = 0; i < priv->rx_q_entries; i++) { |
888 | struct ftgmac100_rxdes *rxdes = &priv->rxdes[i]; |
889 | struct sk_buff *skb = priv->rx_skbs[i]; |
890 | dma_addr_t map = le32_to_cpu(rxdes->rxdes3); |
891 | |
892 | if (!skb) |
893 | continue; |
894 | |
895 | priv->rx_skbs[i] = NULL; |
896 | dma_unmap_single(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); |
897 | dev_kfree_skb_any(skb); |
898 | } |
899 | |
900 | /* Free all TX buffers */ |
901 | for (i = 0; i < priv->tx_q_entries; i++) { |
902 | struct ftgmac100_txdes *txdes = &priv->txdes[i]; |
903 | struct sk_buff *skb = priv->tx_skbs[i]; |
904 | |
905 | if (!skb) |
906 | continue; |
907 | ftgmac100_free_tx_packet(priv, pointer: i, skb, txdes, |
908 | le32_to_cpu(txdes->txdes0)); |
909 | } |
910 | } |
911 | |
912 | static void ftgmac100_free_rings(struct ftgmac100 *priv) |
913 | { |
914 | /* Free skb arrays */ |
915 | kfree(objp: priv->rx_skbs); |
916 | kfree(objp: priv->tx_skbs); |
917 | |
918 | /* Free descriptors */ |
919 | if (priv->rxdes) |
920 | dma_free_coherent(dev: priv->dev, MAX_RX_QUEUE_ENTRIES * |
921 | sizeof(struct ftgmac100_rxdes), |
922 | cpu_addr: priv->rxdes, dma_handle: priv->rxdes_dma); |
923 | priv->rxdes = NULL; |
924 | |
925 | if (priv->txdes) |
926 | dma_free_coherent(dev: priv->dev, MAX_TX_QUEUE_ENTRIES * |
927 | sizeof(struct ftgmac100_txdes), |
928 | cpu_addr: priv->txdes, dma_handle: priv->txdes_dma); |
929 | priv->txdes = NULL; |
930 | |
931 | /* Free scratch packet buffer */ |
932 | if (priv->rx_scratch) |
933 | dma_free_coherent(dev: priv->dev, RX_BUF_SIZE, |
934 | cpu_addr: priv->rx_scratch, dma_handle: priv->rx_scratch_dma); |
935 | } |
936 | |
937 | static int ftgmac100_alloc_rings(struct ftgmac100 *priv) |
938 | { |
939 | /* Allocate skb arrays */ |
940 | priv->rx_skbs = kcalloc(MAX_RX_QUEUE_ENTRIES, sizeof(void *), |
941 | GFP_KERNEL); |
942 | if (!priv->rx_skbs) |
943 | return -ENOMEM; |
944 | priv->tx_skbs = kcalloc(MAX_TX_QUEUE_ENTRIES, sizeof(void *), |
945 | GFP_KERNEL); |
946 | if (!priv->tx_skbs) |
947 | return -ENOMEM; |
948 | |
949 | /* Allocate descriptors */ |
950 | priv->rxdes = dma_alloc_coherent(dev: priv->dev, |
951 | MAX_RX_QUEUE_ENTRIES * sizeof(struct ftgmac100_rxdes), |
952 | dma_handle: &priv->rxdes_dma, GFP_KERNEL); |
953 | if (!priv->rxdes) |
954 | return -ENOMEM; |
955 | priv->txdes = dma_alloc_coherent(dev: priv->dev, |
956 | MAX_TX_QUEUE_ENTRIES * sizeof(struct ftgmac100_txdes), |
957 | dma_handle: &priv->txdes_dma, GFP_KERNEL); |
958 | if (!priv->txdes) |
959 | return -ENOMEM; |
960 | |
961 | /* Allocate scratch packet buffer */ |
962 | priv->rx_scratch = dma_alloc_coherent(dev: priv->dev, |
963 | RX_BUF_SIZE, |
964 | dma_handle: &priv->rx_scratch_dma, |
965 | GFP_KERNEL); |
966 | if (!priv->rx_scratch) |
967 | return -ENOMEM; |
968 | |
969 | return 0; |
970 | } |
971 | |
972 | static void ftgmac100_init_rings(struct ftgmac100 *priv) |
973 | { |
974 | struct ftgmac100_rxdes *rxdes = NULL; |
975 | struct ftgmac100_txdes *txdes = NULL; |
976 | int i; |
977 | |
978 | /* Update entries counts */ |
979 | priv->rx_q_entries = priv->new_rx_q_entries; |
980 | priv->tx_q_entries = priv->new_tx_q_entries; |
981 | |
982 | if (WARN_ON(priv->rx_q_entries < MIN_RX_QUEUE_ENTRIES)) |
983 | return; |
984 | |
985 | /* Initialize RX ring */ |
986 | for (i = 0; i < priv->rx_q_entries; i++) { |
987 | rxdes = &priv->rxdes[i]; |
988 | rxdes->rxdes0 = 0; |
989 | rxdes->rxdes3 = cpu_to_le32(priv->rx_scratch_dma); |
990 | } |
991 | /* Mark the end of the ring */ |
992 | rxdes->rxdes0 |= cpu_to_le32(priv->rxdes0_edorr_mask); |
993 | |
994 | if (WARN_ON(priv->tx_q_entries < MIN_RX_QUEUE_ENTRIES)) |
995 | return; |
996 | |
997 | /* Initialize TX ring */ |
998 | for (i = 0; i < priv->tx_q_entries; i++) { |
999 | txdes = &priv->txdes[i]; |
1000 | txdes->txdes0 = 0; |
1001 | } |
1002 | txdes->txdes0 |= cpu_to_le32(priv->txdes0_edotr_mask); |
1003 | } |
1004 | |
1005 | static int ftgmac100_alloc_rx_buffers(struct ftgmac100 *priv) |
1006 | { |
1007 | int i; |
1008 | |
1009 | for (i = 0; i < priv->rx_q_entries; i++) { |
1010 | struct ftgmac100_rxdes *rxdes = &priv->rxdes[i]; |
1011 | |
1012 | if (ftgmac100_alloc_rx_buf(priv, entry: i, rxdes, GFP_KERNEL)) |
1013 | return -ENOMEM; |
1014 | } |
1015 | return 0; |
1016 | } |
1017 | |
1018 | static int ftgmac100_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) |
1019 | { |
1020 | struct net_device *netdev = bus->priv; |
1021 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1022 | unsigned int phycr; |
1023 | int i; |
1024 | |
1025 | phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); |
1026 | |
1027 | /* preserve MDC cycle threshold */ |
1028 | phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK; |
1029 | |
1030 | phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr) | |
1031 | FTGMAC100_PHYCR_REGAD(regnum) | |
1032 | FTGMAC100_PHYCR_MIIRD; |
1033 | |
1034 | iowrite32(phycr, priv->base + FTGMAC100_OFFSET_PHYCR); |
1035 | |
1036 | for (i = 0; i < 10; i++) { |
1037 | phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); |
1038 | |
1039 | if ((phycr & FTGMAC100_PHYCR_MIIRD) == 0) { |
1040 | int data; |
1041 | |
1042 | data = ioread32(priv->base + FTGMAC100_OFFSET_PHYDATA); |
1043 | return FTGMAC100_PHYDATA_MIIRDATA(data); |
1044 | } |
1045 | |
1046 | udelay(usec: 100); |
1047 | } |
1048 | |
1049 | netdev_err(dev: netdev, format: "mdio read timed out\n"); |
1050 | return -EIO; |
1051 | } |
1052 | |
1053 | static int ftgmac100_mdiobus_write(struct mii_bus *bus, int phy_addr, |
1054 | int regnum, u16 value) |
1055 | { |
1056 | struct net_device *netdev = bus->priv; |
1057 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1058 | unsigned int phycr; |
1059 | int data; |
1060 | int i; |
1061 | |
1062 | phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); |
1063 | |
1064 | /* preserve MDC cycle threshold */ |
1065 | phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK; |
1066 | |
1067 | phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr) | |
1068 | FTGMAC100_PHYCR_REGAD(regnum) | |
1069 | FTGMAC100_PHYCR_MIIWR; |
1070 | |
1071 | data = FTGMAC100_PHYDATA_MIIWDATA(value); |
1072 | |
1073 | iowrite32(data, priv->base + FTGMAC100_OFFSET_PHYDATA); |
1074 | iowrite32(phycr, priv->base + FTGMAC100_OFFSET_PHYCR); |
1075 | |
1076 | for (i = 0; i < 10; i++) { |
1077 | phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); |
1078 | |
1079 | if ((phycr & FTGMAC100_PHYCR_MIIWR) == 0) |
1080 | return 0; |
1081 | |
1082 | udelay(usec: 100); |
1083 | } |
1084 | |
1085 | netdev_err(dev: netdev, format: "mdio write timed out\n"); |
1086 | return -EIO; |
1087 | } |
1088 | |
1089 | static void ftgmac100_get_drvinfo(struct net_device *netdev, |
1090 | struct ethtool_drvinfo *info) |
1091 | { |
1092 | strscpy(info->driver, DRV_NAME, sizeof(info->driver)); |
1093 | strscpy(info->bus_info, dev_name(&netdev->dev), sizeof(info->bus_info)); |
1094 | } |
1095 | |
1096 | static void |
1097 | ftgmac100_get_ringparam(struct net_device *netdev, |
1098 | struct ethtool_ringparam *ering, |
1099 | struct kernel_ethtool_ringparam *kernel_ering, |
1100 | struct netlink_ext_ack *extack) |
1101 | { |
1102 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1103 | |
1104 | memset(ering, 0, sizeof(*ering)); |
1105 | ering->rx_max_pending = MAX_RX_QUEUE_ENTRIES; |
1106 | ering->tx_max_pending = MAX_TX_QUEUE_ENTRIES; |
1107 | ering->rx_pending = priv->rx_q_entries; |
1108 | ering->tx_pending = priv->tx_q_entries; |
1109 | } |
1110 | |
1111 | static int |
1112 | ftgmac100_set_ringparam(struct net_device *netdev, |
1113 | struct ethtool_ringparam *ering, |
1114 | struct kernel_ethtool_ringparam *kernel_ering, |
1115 | struct netlink_ext_ack *extack) |
1116 | { |
1117 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1118 | |
1119 | if (ering->rx_pending > MAX_RX_QUEUE_ENTRIES || |
1120 | ering->tx_pending > MAX_TX_QUEUE_ENTRIES || |
1121 | ering->rx_pending < MIN_RX_QUEUE_ENTRIES || |
1122 | ering->tx_pending < MIN_TX_QUEUE_ENTRIES || |
1123 | !is_power_of_2(n: ering->rx_pending) || |
1124 | !is_power_of_2(n: ering->tx_pending)) |
1125 | return -EINVAL; |
1126 | |
1127 | priv->new_rx_q_entries = ering->rx_pending; |
1128 | priv->new_tx_q_entries = ering->tx_pending; |
1129 | if (netif_running(dev: netdev)) |
1130 | schedule_work(work: &priv->reset_task); |
1131 | |
1132 | return 0; |
1133 | } |
1134 | |
1135 | static void ftgmac100_get_pauseparam(struct net_device *netdev, |
1136 | struct ethtool_pauseparam *pause) |
1137 | { |
1138 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1139 | |
1140 | pause->autoneg = priv->aneg_pause; |
1141 | pause->tx_pause = priv->tx_pause; |
1142 | pause->rx_pause = priv->rx_pause; |
1143 | } |
1144 | |
1145 | static int ftgmac100_set_pauseparam(struct net_device *netdev, |
1146 | struct ethtool_pauseparam *pause) |
1147 | { |
1148 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1149 | struct phy_device *phydev = netdev->phydev; |
1150 | |
1151 | priv->aneg_pause = pause->autoneg; |
1152 | priv->tx_pause = pause->tx_pause; |
1153 | priv->rx_pause = pause->rx_pause; |
1154 | |
1155 | if (phydev) |
1156 | phy_set_asym_pause(phydev, rx: pause->rx_pause, tx: pause->tx_pause); |
1157 | |
1158 | if (netif_running(dev: netdev)) { |
1159 | if (!(phydev && priv->aneg_pause)) |
1160 | ftgmac100_config_pause(priv); |
1161 | } |
1162 | |
1163 | return 0; |
1164 | } |
1165 | |
1166 | static const struct ethtool_ops ftgmac100_ethtool_ops = { |
1167 | .get_drvinfo = ftgmac100_get_drvinfo, |
1168 | .get_link = ethtool_op_get_link, |
1169 | .get_link_ksettings = phy_ethtool_get_link_ksettings, |
1170 | .set_link_ksettings = phy_ethtool_set_link_ksettings, |
1171 | .nway_reset = phy_ethtool_nway_reset, |
1172 | .get_ringparam = ftgmac100_get_ringparam, |
1173 | .set_ringparam = ftgmac100_set_ringparam, |
1174 | .get_pauseparam = ftgmac100_get_pauseparam, |
1175 | .set_pauseparam = ftgmac100_set_pauseparam, |
1176 | }; |
1177 | |
1178 | static irqreturn_t ftgmac100_interrupt(int irq, void *dev_id) |
1179 | { |
1180 | struct net_device *netdev = dev_id; |
1181 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1182 | unsigned int status, new_mask = FTGMAC100_INT_BAD; |
1183 | |
1184 | /* Fetch and clear interrupt bits, process abnormal ones */ |
1185 | status = ioread32(priv->base + FTGMAC100_OFFSET_ISR); |
1186 | iowrite32(status, priv->base + FTGMAC100_OFFSET_ISR); |
1187 | if (unlikely(status & FTGMAC100_INT_BAD)) { |
1188 | |
1189 | /* RX buffer unavailable */ |
1190 | if (status & FTGMAC100_INT_NO_RXBUF) |
1191 | netdev->stats.rx_over_errors++; |
1192 | |
1193 | /* received packet lost due to RX FIFO full */ |
1194 | if (status & FTGMAC100_INT_RPKT_LOST) |
1195 | netdev->stats.rx_fifo_errors++; |
1196 | |
1197 | /* sent packet lost due to excessive TX collision */ |
1198 | if (status & FTGMAC100_INT_XPKT_LOST) |
1199 | netdev->stats.tx_fifo_errors++; |
1200 | |
1201 | /* AHB error -> Reset the chip */ |
1202 | if (status & FTGMAC100_INT_AHB_ERR) { |
1203 | if (net_ratelimit()) |
1204 | netdev_warn(dev: netdev, |
1205 | format: "AHB bus error ! Resetting chip.\n"); |
1206 | iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); |
1207 | schedule_work(work: &priv->reset_task); |
1208 | return IRQ_HANDLED; |
1209 | } |
1210 | |
1211 | /* We may need to restart the MAC after such errors, delay |
1212 | * this until after we have freed some Rx buffers though |
1213 | */ |
1214 | priv->need_mac_restart = true; |
1215 | |
1216 | /* Disable those errors until we restart */ |
1217 | new_mask &= ~status; |
1218 | } |
1219 | |
1220 | /* Only enable "bad" interrupts while NAPI is on */ |
1221 | iowrite32(new_mask, priv->base + FTGMAC100_OFFSET_IER); |
1222 | |
1223 | /* Schedule NAPI bh */ |
1224 | napi_schedule_irqoff(n: &priv->napi); |
1225 | |
1226 | return IRQ_HANDLED; |
1227 | } |
1228 | |
1229 | static bool ftgmac100_check_rx(struct ftgmac100 *priv) |
1230 | { |
1231 | struct ftgmac100_rxdes *rxdes = &priv->rxdes[priv->rx_pointer]; |
1232 | |
1233 | /* Do we have a packet ? */ |
1234 | return !!(rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RXPKT_RDY)); |
1235 | } |
1236 | |
1237 | static int ftgmac100_poll(struct napi_struct *napi, int budget) |
1238 | { |
1239 | struct ftgmac100 *priv = container_of(napi, struct ftgmac100, napi); |
1240 | int work_done = 0; |
1241 | bool more; |
1242 | |
1243 | /* Handle TX completions */ |
1244 | if (ftgmac100_tx_buf_cleanable(priv)) |
1245 | ftgmac100_tx_complete(priv); |
1246 | |
1247 | /* Handle RX packets */ |
1248 | do { |
1249 | more = ftgmac100_rx_packet(priv, processed: &work_done); |
1250 | } while (more && work_done < budget); |
1251 | |
1252 | |
1253 | /* The interrupt is telling us to kick the MAC back to life |
1254 | * after an RX overflow |
1255 | */ |
1256 | if (unlikely(priv->need_mac_restart)) { |
1257 | ftgmac100_start_hw(priv); |
1258 | priv->need_mac_restart = false; |
1259 | |
1260 | /* Re-enable "bad" interrupts */ |
1261 | iowrite32(FTGMAC100_INT_BAD, |
1262 | priv->base + FTGMAC100_OFFSET_IER); |
1263 | } |
1264 | |
1265 | /* As long as we are waiting for transmit packets to be |
1266 | * completed we keep NAPI going |
1267 | */ |
1268 | if (ftgmac100_tx_buf_cleanable(priv)) |
1269 | work_done = budget; |
1270 | |
1271 | if (work_done < budget) { |
1272 | /* We are about to re-enable all interrupts. However |
1273 | * the HW has been latching RX/TX packet interrupts while |
1274 | * they were masked. So we clear them first, then we need |
1275 | * to re-check if there's something to process |
1276 | */ |
1277 | iowrite32(FTGMAC100_INT_RXTX, |
1278 | priv->base + FTGMAC100_OFFSET_ISR); |
1279 | |
1280 | /* Push the above (and provides a barrier vs. subsequent |
1281 | * reads of the descriptor). |
1282 | */ |
1283 | ioread32(priv->base + FTGMAC100_OFFSET_ISR); |
1284 | |
1285 | /* Check RX and TX descriptors for more work to do */ |
1286 | if (ftgmac100_check_rx(priv) || |
1287 | ftgmac100_tx_buf_cleanable(priv)) |
1288 | return budget; |
1289 | |
1290 | /* deschedule NAPI */ |
1291 | napi_complete(n: napi); |
1292 | |
1293 | /* enable all interrupts */ |
1294 | iowrite32(FTGMAC100_INT_ALL, |
1295 | priv->base + FTGMAC100_OFFSET_IER); |
1296 | } |
1297 | |
1298 | return work_done; |
1299 | } |
1300 | |
1301 | static int ftgmac100_init_all(struct ftgmac100 *priv, bool ignore_alloc_err) |
1302 | { |
1303 | int err = 0; |
1304 | |
1305 | /* Re-init descriptors (adjust queue sizes) */ |
1306 | ftgmac100_init_rings(priv); |
1307 | |
1308 | /* Realloc rx descriptors */ |
1309 | err = ftgmac100_alloc_rx_buffers(priv); |
1310 | if (err && !ignore_alloc_err) |
1311 | return err; |
1312 | |
1313 | /* Reinit and restart HW */ |
1314 | ftgmac100_init_hw(priv); |
1315 | ftgmac100_config_pause(priv); |
1316 | ftgmac100_start_hw(priv); |
1317 | |
1318 | /* Re-enable the device */ |
1319 | napi_enable(n: &priv->napi); |
1320 | netif_start_queue(dev: priv->netdev); |
1321 | |
1322 | /* Enable all interrupts */ |
1323 | iowrite32(FTGMAC100_INT_ALL, priv->base + FTGMAC100_OFFSET_IER); |
1324 | |
1325 | return err; |
1326 | } |
1327 | |
1328 | static void ftgmac100_reset(struct ftgmac100 *priv) |
1329 | { |
1330 | struct net_device *netdev = priv->netdev; |
1331 | int err; |
1332 | |
1333 | netdev_dbg(netdev, "Resetting NIC...\n"); |
1334 | |
1335 | /* Lock the world */ |
1336 | rtnl_lock(); |
1337 | if (netdev->phydev) |
1338 | mutex_lock(&netdev->phydev->lock); |
1339 | if (priv->mii_bus) |
1340 | mutex_lock(&priv->mii_bus->mdio_lock); |
1341 | |
1342 | |
1343 | /* Check if the interface is still up */ |
1344 | if (!netif_running(dev: netdev)) |
1345 | goto bail; |
1346 | |
1347 | /* Stop the network stack */ |
1348 | netif_trans_update(dev: netdev); |
1349 | napi_disable(n: &priv->napi); |
1350 | netif_tx_disable(dev: netdev); |
1351 | |
1352 | /* Stop and reset the MAC */ |
1353 | ftgmac100_stop_hw(priv); |
1354 | err = ftgmac100_reset_and_config_mac(priv); |
1355 | if (err) { |
1356 | /* Not much we can do ... it might come back... */ |
1357 | netdev_err(dev: netdev, format: "attempting to continue...\n"); |
1358 | } |
1359 | |
1360 | /* Free all rx and tx buffers */ |
1361 | ftgmac100_free_buffers(priv); |
1362 | |
1363 | /* Setup everything again and restart chip */ |
1364 | ftgmac100_init_all(priv, ignore_alloc_err: true); |
1365 | |
1366 | netdev_dbg(netdev, "Reset done !\n"); |
1367 | bail: |
1368 | if (priv->mii_bus) |
1369 | mutex_unlock(lock: &priv->mii_bus->mdio_lock); |
1370 | if (netdev->phydev) |
1371 | mutex_unlock(lock: &netdev->phydev->lock); |
1372 | rtnl_unlock(); |
1373 | } |
1374 | |
1375 | static void ftgmac100_reset_task(struct work_struct *work) |
1376 | { |
1377 | struct ftgmac100 *priv = container_of(work, struct ftgmac100, |
1378 | reset_task); |
1379 | |
1380 | ftgmac100_reset(priv); |
1381 | } |
1382 | |
1383 | static void ftgmac100_adjust_link(struct net_device *netdev) |
1384 | { |
1385 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1386 | struct phy_device *phydev = netdev->phydev; |
1387 | bool tx_pause, rx_pause; |
1388 | int new_speed; |
1389 | |
1390 | /* We store "no link" as speed 0 */ |
1391 | if (!phydev->link) |
1392 | new_speed = 0; |
1393 | else |
1394 | new_speed = phydev->speed; |
1395 | |
1396 | /* Grab pause settings from PHY if configured to do so */ |
1397 | if (priv->aneg_pause) { |
1398 | rx_pause = tx_pause = phydev->pause; |
1399 | if (phydev->asym_pause) |
1400 | tx_pause = !rx_pause; |
1401 | } else { |
1402 | rx_pause = priv->rx_pause; |
1403 | tx_pause = priv->tx_pause; |
1404 | } |
1405 | |
1406 | /* Link hasn't changed, do nothing */ |
1407 | if (phydev->speed == priv->cur_speed && |
1408 | phydev->duplex == priv->cur_duplex && |
1409 | rx_pause == priv->rx_pause && |
1410 | tx_pause == priv->tx_pause) |
1411 | return; |
1412 | |
1413 | /* Print status if we have a link or we had one and just lost it, |
1414 | * don't print otherwise. |
1415 | */ |
1416 | if (new_speed || priv->cur_speed) |
1417 | phy_print_status(phydev); |
1418 | |
1419 | priv->cur_speed = new_speed; |
1420 | priv->cur_duplex = phydev->duplex; |
1421 | priv->rx_pause = rx_pause; |
1422 | priv->tx_pause = tx_pause; |
1423 | |
1424 | /* Link is down, do nothing else */ |
1425 | if (!new_speed) |
1426 | return; |
1427 | |
1428 | /* Disable all interrupts */ |
1429 | iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); |
1430 | |
1431 | /* Release phy lock to allow ftgmac100_reset to aquire it, keeping lock |
1432 | * order consistent to prevent dead lock. |
1433 | */ |
1434 | if (netdev->phydev) |
1435 | mutex_unlock(lock: &netdev->phydev->lock); |
1436 | |
1437 | ftgmac100_reset(priv); |
1438 | |
1439 | if (netdev->phydev) |
1440 | mutex_lock(&netdev->phydev->lock); |
1441 | |
1442 | } |
1443 | |
1444 | static int ftgmac100_mii_probe(struct net_device *netdev) |
1445 | { |
1446 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1447 | struct platform_device *pdev = to_platform_device(priv->dev); |
1448 | struct device_node *np = pdev->dev.of_node; |
1449 | struct phy_device *phydev; |
1450 | phy_interface_t phy_intf; |
1451 | int err; |
1452 | |
1453 | /* Default to RGMII. It's a gigabit part after all */ |
1454 | err = of_get_phy_mode(np, interface: &phy_intf); |
1455 | if (err) |
1456 | phy_intf = PHY_INTERFACE_MODE_RGMII; |
1457 | |
1458 | /* Aspeed only supports these. I don't know about other IP |
1459 | * block vendors so I'm going to just let them through for |
1460 | * now. Note that this is only a warning if for some obscure |
1461 | * reason the DT really means to lie about it or it's a newer |
1462 | * part we don't know about. |
1463 | * |
1464 | * On the Aspeed SoC there are additionally straps and SCU |
1465 | * control bits that could tell us what the interface is |
1466 | * (or allow us to configure it while the IP block is held |
1467 | * in reset). For now I chose to keep this driver away from |
1468 | * those SoC specific bits and assume the device-tree is |
1469 | * right and the SCU has been configured properly by pinmux |
1470 | * or the firmware. |
1471 | */ |
1472 | if (priv->is_aspeed && !(phy_interface_mode_is_rgmii(mode: phy_intf))) { |
1473 | netdev_warn(dev: netdev, |
1474 | format: "Unsupported PHY mode %s !\n", |
1475 | phy_modes(interface: phy_intf)); |
1476 | } |
1477 | |
1478 | phydev = phy_find_first(bus: priv->mii_bus); |
1479 | if (!phydev) { |
1480 | netdev_info(dev: netdev, format: "%s: no PHY found\n", netdev->name); |
1481 | return -ENODEV; |
1482 | } |
1483 | |
1484 | phydev = phy_connect(dev: netdev, bus_id: phydev_name(phydev), |
1485 | handler: &ftgmac100_adjust_link, interface: phy_intf); |
1486 | |
1487 | if (IS_ERR(ptr: phydev)) { |
1488 | netdev_err(dev: netdev, format: "%s: Could not attach to PHY\n", netdev->name); |
1489 | return PTR_ERR(ptr: phydev); |
1490 | } |
1491 | |
1492 | /* Indicate that we support PAUSE frames (see comment in |
1493 | * Documentation/networking/phy.rst) |
1494 | */ |
1495 | phy_support_asym_pause(phydev); |
1496 | |
1497 | /* Display what we found */ |
1498 | phy_attached_info(phydev); |
1499 | |
1500 | return 0; |
1501 | } |
1502 | |
1503 | static int ftgmac100_open(struct net_device *netdev) |
1504 | { |
1505 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1506 | int err; |
1507 | |
1508 | /* Allocate ring buffers */ |
1509 | err = ftgmac100_alloc_rings(priv); |
1510 | if (err) { |
1511 | netdev_err(dev: netdev, format: "Failed to allocate descriptors\n"); |
1512 | return err; |
1513 | } |
1514 | |
1515 | /* When using NC-SI we force the speed to 100Mbit/s full duplex, |
1516 | * |
1517 | * Otherwise we leave it set to 0 (no link), the link |
1518 | * message from the PHY layer will handle setting it up to |
1519 | * something else if needed. |
1520 | */ |
1521 | if (priv->use_ncsi) { |
1522 | priv->cur_duplex = DUPLEX_FULL; |
1523 | priv->cur_speed = SPEED_100; |
1524 | } else { |
1525 | priv->cur_duplex = 0; |
1526 | priv->cur_speed = 0; |
1527 | } |
1528 | |
1529 | /* Reset the hardware */ |
1530 | err = ftgmac100_reset_and_config_mac(priv); |
1531 | if (err) |
1532 | goto err_hw; |
1533 | |
1534 | /* Initialize NAPI */ |
1535 | netif_napi_add(dev: netdev, napi: &priv->napi, poll: ftgmac100_poll); |
1536 | |
1537 | /* Grab our interrupt */ |
1538 | err = request_irq(irq: netdev->irq, handler: ftgmac100_interrupt, flags: 0, name: netdev->name, dev: netdev); |
1539 | if (err) { |
1540 | netdev_err(dev: netdev, format: "failed to request irq %d\n", netdev->irq); |
1541 | goto err_irq; |
1542 | } |
1543 | |
1544 | /* Start things up */ |
1545 | err = ftgmac100_init_all(priv, ignore_alloc_err: false); |
1546 | if (err) { |
1547 | netdev_err(dev: netdev, format: "Failed to allocate packet buffers\n"); |
1548 | goto err_alloc; |
1549 | } |
1550 | |
1551 | if (netdev->phydev) { |
1552 | /* If we have a PHY, start polling */ |
1553 | phy_start(phydev: netdev->phydev); |
1554 | } |
1555 | if (priv->use_ncsi) { |
1556 | /* If using NC-SI, set our carrier on and start the stack */ |
1557 | netif_carrier_on(dev: netdev); |
1558 | |
1559 | /* Start the NCSI device */ |
1560 | err = ncsi_start_dev(nd: priv->ndev); |
1561 | if (err) |
1562 | goto err_ncsi; |
1563 | } |
1564 | |
1565 | return 0; |
1566 | |
1567 | err_ncsi: |
1568 | phy_stop(phydev: netdev->phydev); |
1569 | napi_disable(n: &priv->napi); |
1570 | netif_stop_queue(dev: netdev); |
1571 | err_alloc: |
1572 | ftgmac100_free_buffers(priv); |
1573 | free_irq(netdev->irq, netdev); |
1574 | err_irq: |
1575 | netif_napi_del(napi: &priv->napi); |
1576 | err_hw: |
1577 | iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); |
1578 | ftgmac100_free_rings(priv); |
1579 | return err; |
1580 | } |
1581 | |
1582 | static int ftgmac100_stop(struct net_device *netdev) |
1583 | { |
1584 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1585 | |
1586 | /* Note about the reset task: We are called with the rtnl lock |
1587 | * held, so we are synchronized against the core of the reset |
1588 | * task. We must not try to synchronously cancel it otherwise |
1589 | * we can deadlock. But since it will test for netif_running() |
1590 | * which has already been cleared by the net core, we don't |
1591 | * anything special to do. |
1592 | */ |
1593 | |
1594 | /* disable all interrupts */ |
1595 | iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); |
1596 | |
1597 | netif_stop_queue(dev: netdev); |
1598 | napi_disable(n: &priv->napi); |
1599 | netif_napi_del(napi: &priv->napi); |
1600 | if (netdev->phydev) |
1601 | phy_stop(phydev: netdev->phydev); |
1602 | if (priv->use_ncsi) |
1603 | ncsi_stop_dev(nd: priv->ndev); |
1604 | |
1605 | ftgmac100_stop_hw(priv); |
1606 | free_irq(netdev->irq, netdev); |
1607 | ftgmac100_free_buffers(priv); |
1608 | ftgmac100_free_rings(priv); |
1609 | |
1610 | return 0; |
1611 | } |
1612 | |
1613 | static void ftgmac100_tx_timeout(struct net_device *netdev, unsigned int txqueue) |
1614 | { |
1615 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1616 | |
1617 | /* Disable all interrupts */ |
1618 | iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); |
1619 | |
1620 | /* Do the reset outside of interrupt context */ |
1621 | schedule_work(work: &priv->reset_task); |
1622 | } |
1623 | |
1624 | static int ftgmac100_set_features(struct net_device *netdev, |
1625 | netdev_features_t features) |
1626 | { |
1627 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1628 | netdev_features_t changed = netdev->features ^ features; |
1629 | |
1630 | if (!netif_running(dev: netdev)) |
1631 | return 0; |
1632 | |
1633 | /* Update the vlan filtering bit */ |
1634 | if (changed & NETIF_F_HW_VLAN_CTAG_RX) { |
1635 | u32 maccr; |
1636 | |
1637 | maccr = ioread32(priv->base + FTGMAC100_OFFSET_MACCR); |
1638 | if (priv->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) |
1639 | maccr |= FTGMAC100_MACCR_RM_VLAN; |
1640 | else |
1641 | maccr &= ~FTGMAC100_MACCR_RM_VLAN; |
1642 | iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR); |
1643 | } |
1644 | |
1645 | return 0; |
1646 | } |
1647 | |
1648 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1649 | static void ftgmac100_poll_controller(struct net_device *netdev) |
1650 | { |
1651 | unsigned long flags; |
1652 | |
1653 | local_irq_save(flags); |
1654 | ftgmac100_interrupt(irq: netdev->irq, dev_id: netdev); |
1655 | local_irq_restore(flags); |
1656 | } |
1657 | #endif |
1658 | |
1659 | static const struct net_device_ops ftgmac100_netdev_ops = { |
1660 | .ndo_open = ftgmac100_open, |
1661 | .ndo_stop = ftgmac100_stop, |
1662 | .ndo_start_xmit = ftgmac100_hard_start_xmit, |
1663 | .ndo_set_mac_address = ftgmac100_set_mac_addr, |
1664 | .ndo_validate_addr = eth_validate_addr, |
1665 | .ndo_eth_ioctl = phy_do_ioctl, |
1666 | .ndo_tx_timeout = ftgmac100_tx_timeout, |
1667 | .ndo_set_rx_mode = ftgmac100_set_rx_mode, |
1668 | .ndo_set_features = ftgmac100_set_features, |
1669 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1670 | .ndo_poll_controller = ftgmac100_poll_controller, |
1671 | #endif |
1672 | .ndo_vlan_rx_add_vid = ncsi_vlan_rx_add_vid, |
1673 | .ndo_vlan_rx_kill_vid = ncsi_vlan_rx_kill_vid, |
1674 | }; |
1675 | |
1676 | static int ftgmac100_setup_mdio(struct net_device *netdev) |
1677 | { |
1678 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1679 | struct platform_device *pdev = to_platform_device(priv->dev); |
1680 | struct device_node *np = pdev->dev.of_node; |
1681 | struct device_node *mdio_np; |
1682 | int i, err = 0; |
1683 | u32 reg; |
1684 | |
1685 | /* initialize mdio bus */ |
1686 | priv->mii_bus = mdiobus_alloc(); |
1687 | if (!priv->mii_bus) |
1688 | return -EIO; |
1689 | |
1690 | if (of_device_is_compatible(device: np, "aspeed,ast2400-mac") || |
1691 | of_device_is_compatible(device: np, "aspeed,ast2500-mac")) { |
1692 | /* The AST2600 has a separate MDIO controller */ |
1693 | |
1694 | /* For the AST2400 and AST2500 this driver only supports the |
1695 | * old MDIO interface |
1696 | */ |
1697 | reg = ioread32(priv->base + FTGMAC100_OFFSET_REVR); |
1698 | reg &= ~FTGMAC100_REVR_NEW_MDIO_INTERFACE; |
1699 | iowrite32(reg, priv->base + FTGMAC100_OFFSET_REVR); |
1700 | } |
1701 | |
1702 | priv->mii_bus->name = "ftgmac100_mdio"; |
1703 | snprintf(buf: priv->mii_bus->id, MII_BUS_ID_SIZE, fmt: "%s-%d", |
1704 | pdev->name, pdev->id); |
1705 | priv->mii_bus->parent = priv->dev; |
1706 | priv->mii_bus->priv = priv->netdev; |
1707 | priv->mii_bus->read = ftgmac100_mdiobus_read; |
1708 | priv->mii_bus->write = ftgmac100_mdiobus_write; |
1709 | |
1710 | for (i = 0; i < PHY_MAX_ADDR; i++) |
1711 | priv->mii_bus->irq[i] = PHY_POLL; |
1712 | |
1713 | mdio_np = of_get_child_by_name(node: np, name: "mdio"); |
1714 | |
1715 | err = of_mdiobus_register(mdio: priv->mii_bus, np: mdio_np); |
1716 | if (err) { |
1717 | dev_err(priv->dev, "Cannot register MDIO bus!\n"); |
1718 | goto err_register_mdiobus; |
1719 | } |
1720 | |
1721 | of_node_put(node: mdio_np); |
1722 | |
1723 | return 0; |
1724 | |
1725 | err_register_mdiobus: |
1726 | mdiobus_free(bus: priv->mii_bus); |
1727 | return err; |
1728 | } |
1729 | |
1730 | static void ftgmac100_phy_disconnect(struct net_device *netdev) |
1731 | { |
1732 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1733 | |
1734 | if (!netdev->phydev) |
1735 | return; |
1736 | |
1737 | phy_disconnect(phydev: netdev->phydev); |
1738 | if (of_phy_is_fixed_link(np: priv->dev->of_node)) |
1739 | of_phy_deregister_fixed_link(np: priv->dev->of_node); |
1740 | |
1741 | if (priv->use_ncsi) |
1742 | fixed_phy_unregister(phydev: netdev->phydev); |
1743 | } |
1744 | |
1745 | static void ftgmac100_destroy_mdio(struct net_device *netdev) |
1746 | { |
1747 | struct ftgmac100 *priv = netdev_priv(dev: netdev); |
1748 | |
1749 | if (!priv->mii_bus) |
1750 | return; |
1751 | |
1752 | mdiobus_unregister(bus: priv->mii_bus); |
1753 | mdiobus_free(bus: priv->mii_bus); |
1754 | } |
1755 | |
1756 | static void ftgmac100_ncsi_handler(struct ncsi_dev *nd) |
1757 | { |
1758 | if (unlikely(nd->state != ncsi_dev_state_functional)) |
1759 | return; |
1760 | |
1761 | netdev_dbg(nd->dev, "NCSI interface %s\n", |
1762 | nd->link_up ? "up": "down"); |
1763 | } |
1764 | |
1765 | static int ftgmac100_setup_clk(struct ftgmac100 *priv) |
1766 | { |
1767 | struct clk *clk; |
1768 | int rc; |
1769 | |
1770 | clk = devm_clk_get(dev: priv->dev, NULL /* MACCLK */); |
1771 | if (IS_ERR(ptr: clk)) |
1772 | return PTR_ERR(ptr: clk); |
1773 | priv->clk = clk; |
1774 | rc = clk_prepare_enable(clk: priv->clk); |
1775 | if (rc) |
1776 | return rc; |
1777 | |
1778 | /* Aspeed specifies a 100MHz clock is required for up to |
1779 | * 1000Mbit link speeds. As NCSI is limited to 100Mbit, 25MHz |
1780 | * is sufficient |
1781 | */ |
1782 | rc = clk_set_rate(clk: priv->clk, rate: priv->use_ncsi ? FTGMAC_25MHZ : |
1783 | FTGMAC_100MHZ); |
1784 | if (rc) |
1785 | goto cleanup_clk; |
1786 | |
1787 | /* RCLK is for RMII, typically used for NCSI. Optional because it's not |
1788 | * necessary if it's the AST2400 MAC, or the MAC is configured for |
1789 | * RGMII, or the controller is not an ASPEED-based controller. |
1790 | */ |
1791 | priv->rclk = devm_clk_get_optional(dev: priv->dev, id: "RCLK"); |
1792 | rc = clk_prepare_enable(clk: priv->rclk); |
1793 | if (!rc) |
1794 | return 0; |
1795 | |
1796 | cleanup_clk: |
1797 | clk_disable_unprepare(clk: priv->clk); |
1798 | |
1799 | return rc; |
1800 | } |
1801 | |
1802 | static bool ftgmac100_has_child_node(struct device_node *np, const char *name) |
1803 | { |
1804 | struct device_node *child_np = of_get_child_by_name(node: np, name); |
1805 | bool ret = false; |
1806 | |
1807 | if (child_np) { |
1808 | ret = true; |
1809 | of_node_put(node: child_np); |
1810 | } |
1811 | |
1812 | return ret; |
1813 | } |
1814 | |
1815 | static int ftgmac100_probe(struct platform_device *pdev) |
1816 | { |
1817 | struct resource *res; |
1818 | int irq; |
1819 | struct net_device *netdev; |
1820 | struct phy_device *phydev; |
1821 | struct ftgmac100 *priv; |
1822 | struct device_node *np; |
1823 | int err = 0; |
1824 | |
1825 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1826 | if (!res) |
1827 | return -ENXIO; |
1828 | |
1829 | irq = platform_get_irq(pdev, 0); |
1830 | if (irq < 0) |
1831 | return irq; |
1832 | |
1833 | /* setup net_device */ |
1834 | netdev = alloc_etherdev(sizeof(*priv)); |
1835 | if (!netdev) { |
1836 | err = -ENOMEM; |
1837 | goto err_alloc_etherdev; |
1838 | } |
1839 | |
1840 | SET_NETDEV_DEV(netdev, &pdev->dev); |
1841 | |
1842 | netdev->ethtool_ops = &ftgmac100_ethtool_ops; |
1843 | netdev->netdev_ops = &ftgmac100_netdev_ops; |
1844 | netdev->watchdog_timeo = 5 * HZ; |
1845 | |
1846 | platform_set_drvdata(pdev, data: netdev); |
1847 | |
1848 | /* setup private data */ |
1849 | priv = netdev_priv(dev: netdev); |
1850 | priv->netdev = netdev; |
1851 | priv->dev = &pdev->dev; |
1852 | INIT_WORK(&priv->reset_task, ftgmac100_reset_task); |
1853 | |
1854 | /* map io memory */ |
1855 | priv->res = request_mem_region(res->start, resource_size(res), |
1856 | dev_name(&pdev->dev)); |
1857 | if (!priv->res) { |
1858 | dev_err(&pdev->dev, "Could not reserve memory region\n"); |
1859 | err = -ENOMEM; |
1860 | goto err_req_mem; |
1861 | } |
1862 | |
1863 | priv->base = ioremap(offset: res->start, size: resource_size(res)); |
1864 | if (!priv->base) { |
1865 | dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n"); |
1866 | err = -EIO; |
1867 | goto err_ioremap; |
1868 | } |
1869 | |
1870 | netdev->irq = irq; |
1871 | |
1872 | /* Enable pause */ |
1873 | priv->tx_pause = true; |
1874 | priv->rx_pause = true; |
1875 | priv->aneg_pause = true; |
1876 | |
1877 | /* MAC address from chip or random one */ |
1878 | err = ftgmac100_initial_mac(priv); |
1879 | if (err) |
1880 | goto err_phy_connect; |
1881 | |
1882 | np = pdev->dev.of_node; |
1883 | if (np && (of_device_is_compatible(device: np, "aspeed,ast2400-mac") || |
1884 | of_device_is_compatible(device: np, "aspeed,ast2500-mac") || |
1885 | of_device_is_compatible(device: np, "aspeed,ast2600-mac"))) { |
1886 | priv->rxdes0_edorr_mask = BIT(30); |
1887 | priv->txdes0_edotr_mask = BIT(30); |
1888 | priv->is_aspeed = true; |
1889 | } else { |
1890 | priv->rxdes0_edorr_mask = BIT(15); |
1891 | priv->txdes0_edotr_mask = BIT(15); |
1892 | } |
1893 | |
1894 | if (np && of_get_property(node: np, name: "use-ncsi", NULL)) { |
1895 | if (!IS_ENABLED(CONFIG_NET_NCSI)) { |
1896 | dev_err(&pdev->dev, "NCSI stack not enabled\n"); |
1897 | err = -EINVAL; |
1898 | goto err_phy_connect; |
1899 | } |
1900 | |
1901 | dev_info(&pdev->dev, "Using NCSI interface\n"); |
1902 | priv->use_ncsi = true; |
1903 | priv->ndev = ncsi_register_dev(dev: netdev, notifier: ftgmac100_ncsi_handler); |
1904 | if (!priv->ndev) { |
1905 | err = -EINVAL; |
1906 | goto err_phy_connect; |
1907 | } |
1908 | |
1909 | phydev = fixed_phy_register(status: &ncsi_phy_status, np); |
1910 | if (IS_ERR(ptr: phydev)) { |
1911 | dev_err(&pdev->dev, "failed to register fixed PHY device\n"); |
1912 | err = PTR_ERR(ptr: phydev); |
1913 | goto err_phy_connect; |
1914 | } |
1915 | err = phy_connect_direct(dev: netdev, phydev, handler: ftgmac100_adjust_link, |
1916 | interface: PHY_INTERFACE_MODE_RMII); |
1917 | if (err) { |
1918 | dev_err(&pdev->dev, "Connecting PHY failed\n"); |
1919 | goto err_phy_connect; |
1920 | } |
1921 | } else if (np && (of_phy_is_fixed_link(np) || |
1922 | of_get_property(node: np, name: "phy-handle", NULL))) { |
1923 | struct phy_device *phy; |
1924 | |
1925 | /* Support "mdio"/"phy" child nodes for ast2400/2500 with |
1926 | * an embedded MDIO controller. Automatically scan the DTS for |
1927 | * available PHYs and register them. |
1928 | */ |
1929 | if (of_get_property(node: np, name: "phy-handle", NULL) && |
1930 | (of_device_is_compatible(device: np, "aspeed,ast2400-mac") || |
1931 | of_device_is_compatible(device: np, "aspeed,ast2500-mac"))) { |
1932 | err = ftgmac100_setup_mdio(netdev); |
1933 | if (err) |
1934 | goto err_setup_mdio; |
1935 | } |
1936 | |
1937 | phy = of_phy_get_and_connect(dev: priv->netdev, np, |
1938 | hndlr: &ftgmac100_adjust_link); |
1939 | if (!phy) { |
1940 | dev_err(&pdev->dev, "Failed to connect to phy\n"); |
1941 | err = -EINVAL; |
1942 | goto err_phy_connect; |
1943 | } |
1944 | |
1945 | /* Indicate that we support PAUSE frames (see comment in |
1946 | * Documentation/networking/phy.rst) |
1947 | */ |
1948 | phy_support_asym_pause(phydev: phy); |
1949 | |
1950 | /* Display what we found */ |
1951 | phy_attached_info(phydev: phy); |
1952 | } else if (np && !ftgmac100_has_child_node(np, name: "mdio")) { |
1953 | /* Support legacy ASPEED devicetree descriptions that decribe a |
1954 | * MAC with an embedded MDIO controller but have no "mdio" |
1955 | * child node. Automatically scan the MDIO bus for available |
1956 | * PHYs. |
1957 | */ |
1958 | priv->use_ncsi = false; |
1959 | err = ftgmac100_setup_mdio(netdev); |
1960 | if (err) |
1961 | goto err_setup_mdio; |
1962 | |
1963 | err = ftgmac100_mii_probe(netdev); |
1964 | if (err) { |
1965 | dev_err(priv->dev, "MII probe failed!\n"); |
1966 | goto err_ncsi_dev; |
1967 | } |
1968 | |
1969 | } |
1970 | |
1971 | if (priv->is_aspeed) { |
1972 | err = ftgmac100_setup_clk(priv); |
1973 | if (err) |
1974 | goto err_phy_connect; |
1975 | |
1976 | /* Disable ast2600 problematic HW arbitration */ |
1977 | if (of_device_is_compatible(device: np, "aspeed,ast2600-mac")) |
1978 | iowrite32(FTGMAC100_TM_DEFAULT, |
1979 | priv->base + FTGMAC100_OFFSET_TM); |
1980 | } |
1981 | |
1982 | /* Default ring sizes */ |
1983 | priv->rx_q_entries = priv->new_rx_q_entries = DEF_RX_QUEUE_ENTRIES; |
1984 | priv->tx_q_entries = priv->new_tx_q_entries = DEF_TX_QUEUE_ENTRIES; |
1985 | |
1986 | /* Base feature set */ |
1987 | netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_HW_CSUM | |
1988 | NETIF_F_GRO | NETIF_F_SG | NETIF_F_HW_VLAN_CTAG_RX | |
1989 | NETIF_F_HW_VLAN_CTAG_TX; |
1990 | |
1991 | if (priv->use_ncsi) |
1992 | netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; |
1993 | |
1994 | /* AST2400 doesn't have working HW checksum generation */ |
1995 | if (np && (of_device_is_compatible(device: np, "aspeed,ast2400-mac"))) |
1996 | netdev->hw_features &= ~NETIF_F_HW_CSUM; |
1997 | |
1998 | /* AST2600 tx checksum with NCSI is broken */ |
1999 | if (priv->use_ncsi && of_device_is_compatible(device: np, "aspeed,ast2600-mac")) |
2000 | netdev->hw_features &= ~NETIF_F_HW_CSUM; |
2001 | |
2002 | if (np && of_get_property(node: np, name: "no-hw-checksum", NULL)) |
2003 | netdev->hw_features &= ~(NETIF_F_HW_CSUM | NETIF_F_RXCSUM); |
2004 | netdev->features |= netdev->hw_features; |
2005 | |
2006 | /* register network device */ |
2007 | err = register_netdev(dev: netdev); |
2008 | if (err) { |
2009 | dev_err(&pdev->dev, "Failed to register netdev\n"); |
2010 | goto err_register_netdev; |
2011 | } |
2012 | |
2013 | netdev_info(dev: netdev, format: "irq %d, mapped at %p\n", netdev->irq, priv->base); |
2014 | |
2015 | return 0; |
2016 | |
2017 | err_register_netdev: |
2018 | clk_disable_unprepare(clk: priv->rclk); |
2019 | clk_disable_unprepare(clk: priv->clk); |
2020 | err_phy_connect: |
2021 | ftgmac100_phy_disconnect(netdev); |
2022 | err_ncsi_dev: |
2023 | if (priv->ndev) |
2024 | ncsi_unregister_dev(nd: priv->ndev); |
2025 | ftgmac100_destroy_mdio(netdev); |
2026 | err_setup_mdio: |
2027 | iounmap(addr: priv->base); |
2028 | err_ioremap: |
2029 | release_resource(new: priv->res); |
2030 | err_req_mem: |
2031 | free_netdev(dev: netdev); |
2032 | err_alloc_etherdev: |
2033 | return err; |
2034 | } |
2035 | |
2036 | static void ftgmac100_remove(struct platform_device *pdev) |
2037 | { |
2038 | struct net_device *netdev; |
2039 | struct ftgmac100 *priv; |
2040 | |
2041 | netdev = platform_get_drvdata(pdev); |
2042 | priv = netdev_priv(dev: netdev); |
2043 | |
2044 | if (priv->ndev) |
2045 | ncsi_unregister_dev(nd: priv->ndev); |
2046 | unregister_netdev(dev: netdev); |
2047 | |
2048 | clk_disable_unprepare(clk: priv->rclk); |
2049 | clk_disable_unprepare(clk: priv->clk); |
2050 | |
2051 | /* There's a small chance the reset task will have been re-queued, |
2052 | * during stop, make sure it's gone before we free the structure. |
2053 | */ |
2054 | cancel_work_sync(work: &priv->reset_task); |
2055 | |
2056 | ftgmac100_phy_disconnect(netdev); |
2057 | ftgmac100_destroy_mdio(netdev); |
2058 | |
2059 | iounmap(addr: priv->base); |
2060 | release_resource(new: priv->res); |
2061 | |
2062 | netif_napi_del(napi: &priv->napi); |
2063 | free_netdev(dev: netdev); |
2064 | } |
2065 | |
2066 | static const struct of_device_id ftgmac100_of_match[] = { |
2067 | { .compatible = "faraday,ftgmac100"}, |
2068 | { } |
2069 | }; |
2070 | MODULE_DEVICE_TABLE(of, ftgmac100_of_match); |
2071 | |
2072 | static struct platform_driver ftgmac100_driver = { |
2073 | .probe = ftgmac100_probe, |
2074 | .remove = ftgmac100_remove, |
2075 | .driver = { |
2076 | .name = DRV_NAME, |
2077 | .of_match_table = ftgmac100_of_match, |
2078 | }, |
2079 | }; |
2080 | module_platform_driver(ftgmac100_driver); |
2081 | |
2082 | MODULE_AUTHOR("Po-Yu Chuang <ratbert@faraday-tech.com>"); |
2083 | MODULE_DESCRIPTION("FTGMAC100 driver"); |
2084 | MODULE_LICENSE("GPL"); |
2085 |
Definitions
- ncsi_phy_status
- ftgmac100
- ftgmac100_reset_mac
- ftgmac100_reset_and_config_mac
- ftgmac100_write_mac_addr
- ftgmac100_initial_mac
- ftgmac100_set_mac_addr
- ftgmac100_config_pause
- ftgmac100_init_hw
- ftgmac100_start_hw
- ftgmac100_stop_hw
- ftgmac100_calc_mc_hash
- ftgmac100_set_rx_mode
- ftgmac100_alloc_rx_buf
- ftgmac100_next_rx_pointer
- ftgmac100_rx_packet_error
- ftgmac100_rx_packet
- ftgmac100_base_tx_ctlstat
- ftgmac100_next_tx_pointer
- ftgmac100_tx_buf_avail
- ftgmac100_tx_buf_cleanable
- ftgmac100_free_tx_packet
- ftgmac100_tx_complete_packet
- ftgmac100_tx_complete
- ftgmac100_prep_tx_csum
- ftgmac100_hard_start_xmit
- ftgmac100_free_buffers
- ftgmac100_free_rings
- ftgmac100_alloc_rings
- ftgmac100_init_rings
- ftgmac100_alloc_rx_buffers
- ftgmac100_mdiobus_read
- ftgmac100_mdiobus_write
- ftgmac100_get_drvinfo
- ftgmac100_get_ringparam
- ftgmac100_set_ringparam
- ftgmac100_get_pauseparam
- ftgmac100_set_pauseparam
- ftgmac100_ethtool_ops
- ftgmac100_interrupt
- ftgmac100_check_rx
- ftgmac100_poll
- ftgmac100_init_all
- ftgmac100_reset
- ftgmac100_reset_task
- ftgmac100_adjust_link
- ftgmac100_mii_probe
- ftgmac100_open
- ftgmac100_stop
- ftgmac100_tx_timeout
- ftgmac100_set_features
- ftgmac100_poll_controller
- ftgmac100_netdev_ops
- ftgmac100_setup_mdio
- ftgmac100_phy_disconnect
- ftgmac100_destroy_mdio
- ftgmac100_ncsi_handler
- ftgmac100_setup_clk
- ftgmac100_has_child_node
- ftgmac100_probe
- ftgmac100_remove
- ftgmac100_of_match
Improve your Profiling and Debugging skills
Find out more