1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Ethernet device driver for Cortina Systems Gemini SoC |
3 | * Also known as the StorLink SL3512 and SL3516 (SL351x) or Lepus |
4 | * Net Engine and Gigabit Ethernet MAC (GMAC) |
5 | * This hardware contains a TCP Offload Engine (TOE) but currently the |
6 | * driver does not make use of it. |
7 | * |
8 | * Authors: |
9 | * Linus Walleij <linus.walleij@linaro.org> |
10 | * Tobias Waldvogel <tobias.waldvogel@gmail.com> (OpenWRT) |
11 | * Michał Mirosław <mirq-linux@rere.qmqm.pl> |
12 | * Paulius Zaleckas <paulius.zaleckas@gmail.com> |
13 | * Giuseppe De Robertis <Giuseppe.DeRobertis@ba.infn.it> |
14 | * Gary Chen & Ch Hsu Storlink Semiconductor |
15 | */ |
16 | #include <linux/kernel.h> |
17 | #include <linux/init.h> |
18 | #include <linux/module.h> |
19 | #include <linux/platform_device.h> |
20 | #include <linux/spinlock.h> |
21 | #include <linux/slab.h> |
22 | #include <linux/dma-mapping.h> |
23 | #include <linux/cache.h> |
24 | #include <linux/interrupt.h> |
25 | #include <linux/reset.h> |
26 | #include <linux/clk.h> |
27 | #include <linux/of.h> |
28 | #include <linux/of_mdio.h> |
29 | #include <linux/of_net.h> |
30 | #include <linux/of_platform.h> |
31 | #include <linux/etherdevice.h> |
32 | #include <linux/if_vlan.h> |
33 | #include <linux/skbuff.h> |
34 | #include <linux/phy.h> |
35 | #include <linux/crc32.h> |
36 | #include <linux/ethtool.h> |
37 | #include <linux/tcp.h> |
38 | #include <linux/u64_stats_sync.h> |
39 | |
40 | #include <linux/in.h> |
41 | #include <linux/ip.h> |
42 | #include <linux/ipv6.h> |
43 | |
44 | #include "gemini.h" |
45 | |
46 | #define DRV_NAME "gmac-gemini" |
47 | |
48 | #define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK) |
49 | static int debug = -1; |
50 | module_param(debug, int, 0); |
51 | MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)" ); |
52 | |
53 | #define HSIZE_8 0x00 |
54 | #define HSIZE_16 0x01 |
55 | #define HSIZE_32 0x02 |
56 | |
57 | #define HBURST_SINGLE 0x00 |
58 | #define HBURST_INCR 0x01 |
59 | #define HBURST_INCR4 0x02 |
60 | #define HBURST_INCR8 0x03 |
61 | |
62 | #define HPROT_DATA_CACHE BIT(0) |
63 | #define HPROT_PRIVILIGED BIT(1) |
64 | #define HPROT_BUFFERABLE BIT(2) |
65 | #define HPROT_CACHABLE BIT(3) |
66 | |
67 | #define DEFAULT_RX_COALESCE_NSECS 0 |
68 | #define DEFAULT_GMAC_RXQ_ORDER 9 |
69 | #define DEFAULT_GMAC_TXQ_ORDER 8 |
70 | #define DEFAULT_RX_BUF_ORDER 11 |
71 | #define TX_MAX_FRAGS 16 |
72 | #define TX_QUEUE_NUM 1 /* max: 6 */ |
73 | #define RX_MAX_ALLOC_ORDER 2 |
74 | |
75 | #define GMAC0_IRQ0_2 (GMAC0_TXDERR_INT_BIT | GMAC0_TXPERR_INT_BIT | \ |
76 | GMAC0_RXDERR_INT_BIT | GMAC0_RXPERR_INT_BIT) |
77 | #define GMAC0_IRQ0_TXQ0_INTS (GMAC0_SWTQ00_EOF_INT_BIT | \ |
78 | GMAC0_SWTQ00_FIN_INT_BIT) |
79 | #define GMAC0_IRQ4_8 (GMAC0_MIB_INT_BIT | GMAC0_RX_OVERRUN_INT_BIT) |
80 | |
81 | #define GMAC_OFFLOAD_FEATURES (NETIF_F_SG | NETIF_F_IP_CSUM | \ |
82 | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM) |
83 | |
84 | /** |
85 | * struct gmac_queue_page - page buffer per-page info |
86 | * @page: the page struct |
87 | * @mapping: the dma address handle |
88 | */ |
89 | struct gmac_queue_page { |
90 | struct page *page; |
91 | dma_addr_t mapping; |
92 | }; |
93 | |
94 | struct gmac_txq { |
95 | struct gmac_txdesc *ring; |
96 | struct sk_buff **skb; |
97 | unsigned int cptr; |
98 | unsigned int noirq_packets; |
99 | }; |
100 | |
101 | struct gemini_ethernet; |
102 | |
103 | struct gemini_ethernet_port { |
104 | u8 id; /* 0 or 1 */ |
105 | |
106 | struct gemini_ethernet *geth; |
107 | struct net_device *netdev; |
108 | struct device *dev; |
109 | void __iomem *dma_base; |
110 | void __iomem *gmac_base; |
111 | struct clk *pclk; |
112 | struct reset_control *reset; |
113 | int irq; |
114 | __le32 mac_addr[3]; |
115 | |
116 | void __iomem *rxq_rwptr; |
117 | struct gmac_rxdesc *rxq_ring; |
118 | unsigned int rxq_order; |
119 | |
120 | struct napi_struct napi; |
121 | struct hrtimer rx_coalesce_timer; |
122 | unsigned int rx_coalesce_nsecs; |
123 | unsigned int freeq_refill; |
124 | struct gmac_txq txq[TX_QUEUE_NUM]; |
125 | unsigned int txq_order; |
126 | unsigned int irq_every_tx_packets; |
127 | |
128 | dma_addr_t rxq_dma_base; |
129 | dma_addr_t txq_dma_base; |
130 | |
131 | unsigned int msg_enable; |
132 | spinlock_t config_lock; /* Locks config register */ |
133 | |
134 | struct u64_stats_sync tx_stats_syncp; |
135 | struct u64_stats_sync rx_stats_syncp; |
136 | struct u64_stats_sync ir_stats_syncp; |
137 | |
138 | struct rtnl_link_stats64 stats; |
139 | u64 hw_stats[RX_STATS_NUM]; |
140 | u64 rx_stats[RX_STATUS_NUM]; |
141 | u64 rx_csum_stats[RX_CHKSUM_NUM]; |
142 | u64 rx_napi_exits; |
143 | u64 tx_frag_stats[TX_MAX_FRAGS]; |
144 | u64 tx_frags_linearized; |
145 | u64 tx_hw_csummed; |
146 | }; |
147 | |
148 | struct gemini_ethernet { |
149 | struct device *dev; |
150 | void __iomem *base; |
151 | struct gemini_ethernet_port *port0; |
152 | struct gemini_ethernet_port *port1; |
153 | bool initialized; |
154 | |
155 | spinlock_t irq_lock; /* Locks IRQ-related registers */ |
156 | unsigned int freeq_order; |
157 | unsigned int freeq_frag_order; |
158 | struct gmac_rxdesc *freeq_ring; |
159 | dma_addr_t freeq_dma_base; |
160 | struct gmac_queue_page *freeq_pages; |
161 | unsigned int num_freeq_pages; |
162 | spinlock_t freeq_lock; /* Locks queue from reentrance */ |
163 | }; |
164 | |
165 | #define GMAC_STATS_NUM ( \ |
166 | RX_STATS_NUM + RX_STATUS_NUM + RX_CHKSUM_NUM + 1 + \ |
167 | TX_MAX_FRAGS + 2) |
168 | |
169 | static const char gmac_stats_strings[GMAC_STATS_NUM][ETH_GSTRING_LEN] = { |
170 | "GMAC_IN_DISCARDS" , |
171 | "GMAC_IN_ERRORS" , |
172 | "GMAC_IN_MCAST" , |
173 | "GMAC_IN_BCAST" , |
174 | "GMAC_IN_MAC1" , |
175 | "GMAC_IN_MAC2" , |
176 | "RX_STATUS_GOOD_FRAME" , |
177 | "RX_STATUS_TOO_LONG_GOOD_CRC" , |
178 | "RX_STATUS_RUNT_FRAME" , |
179 | "RX_STATUS_SFD_NOT_FOUND" , |
180 | "RX_STATUS_CRC_ERROR" , |
181 | "RX_STATUS_TOO_LONG_BAD_CRC" , |
182 | "RX_STATUS_ALIGNMENT_ERROR" , |
183 | "RX_STATUS_TOO_LONG_BAD_ALIGN" , |
184 | "RX_STATUS_RX_ERR" , |
185 | "RX_STATUS_DA_FILTERED" , |
186 | "RX_STATUS_BUFFER_FULL" , |
187 | "RX_STATUS_11" , |
188 | "RX_STATUS_12" , |
189 | "RX_STATUS_13" , |
190 | "RX_STATUS_14" , |
191 | "RX_STATUS_15" , |
192 | "RX_CHKSUM_IP_UDP_TCP_OK" , |
193 | "RX_CHKSUM_IP_OK_ONLY" , |
194 | "RX_CHKSUM_NONE" , |
195 | "RX_CHKSUM_3" , |
196 | "RX_CHKSUM_IP_ERR_UNKNOWN" , |
197 | "RX_CHKSUM_IP_ERR" , |
198 | "RX_CHKSUM_TCP_UDP_ERR" , |
199 | "RX_CHKSUM_7" , |
200 | "RX_NAPI_EXITS" , |
201 | "TX_FRAGS[1]" , |
202 | "TX_FRAGS[2]" , |
203 | "TX_FRAGS[3]" , |
204 | "TX_FRAGS[4]" , |
205 | "TX_FRAGS[5]" , |
206 | "TX_FRAGS[6]" , |
207 | "TX_FRAGS[7]" , |
208 | "TX_FRAGS[8]" , |
209 | "TX_FRAGS[9]" , |
210 | "TX_FRAGS[10]" , |
211 | "TX_FRAGS[11]" , |
212 | "TX_FRAGS[12]" , |
213 | "TX_FRAGS[13]" , |
214 | "TX_FRAGS[14]" , |
215 | "TX_FRAGS[15]" , |
216 | "TX_FRAGS[16+]" , |
217 | "TX_FRAGS_LINEARIZED" , |
218 | "TX_HW_CSUMMED" , |
219 | }; |
220 | |
221 | static void gmac_dump_dma_state(struct net_device *netdev); |
222 | |
223 | static void gmac_update_config0_reg(struct net_device *netdev, |
224 | u32 val, u32 vmask) |
225 | { |
226 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
227 | unsigned long flags; |
228 | u32 reg; |
229 | |
230 | spin_lock_irqsave(&port->config_lock, flags); |
231 | |
232 | reg = readl(addr: port->gmac_base + GMAC_CONFIG0); |
233 | reg = (reg & ~vmask) | val; |
234 | writel(val: reg, addr: port->gmac_base + GMAC_CONFIG0); |
235 | |
236 | spin_unlock_irqrestore(lock: &port->config_lock, flags); |
237 | } |
238 | |
239 | static void gmac_enable_tx_rx(struct net_device *netdev) |
240 | { |
241 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
242 | unsigned long flags; |
243 | u32 reg; |
244 | |
245 | spin_lock_irqsave(&port->config_lock, flags); |
246 | |
247 | reg = readl(addr: port->gmac_base + GMAC_CONFIG0); |
248 | reg &= ~CONFIG0_TX_RX_DISABLE; |
249 | writel(val: reg, addr: port->gmac_base + GMAC_CONFIG0); |
250 | |
251 | spin_unlock_irqrestore(lock: &port->config_lock, flags); |
252 | } |
253 | |
254 | static void gmac_disable_tx_rx(struct net_device *netdev) |
255 | { |
256 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
257 | unsigned long flags; |
258 | u32 val; |
259 | |
260 | spin_lock_irqsave(&port->config_lock, flags); |
261 | |
262 | val = readl(addr: port->gmac_base + GMAC_CONFIG0); |
263 | val |= CONFIG0_TX_RX_DISABLE; |
264 | writel(val, addr: port->gmac_base + GMAC_CONFIG0); |
265 | |
266 | spin_unlock_irqrestore(lock: &port->config_lock, flags); |
267 | |
268 | mdelay(10); /* let GMAC consume packet */ |
269 | } |
270 | |
271 | static void gmac_set_flow_control(struct net_device *netdev, bool tx, bool rx) |
272 | { |
273 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
274 | unsigned long flags; |
275 | u32 val; |
276 | |
277 | spin_lock_irqsave(&port->config_lock, flags); |
278 | |
279 | val = readl(addr: port->gmac_base + GMAC_CONFIG0); |
280 | val &= ~CONFIG0_FLOW_CTL; |
281 | if (tx) |
282 | val |= CONFIG0_FLOW_TX; |
283 | if (rx) |
284 | val |= CONFIG0_FLOW_RX; |
285 | writel(val, addr: port->gmac_base + GMAC_CONFIG0); |
286 | |
287 | spin_unlock_irqrestore(lock: &port->config_lock, flags); |
288 | } |
289 | |
290 | static void gmac_speed_set(struct net_device *netdev) |
291 | { |
292 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
293 | struct phy_device *phydev = netdev->phydev; |
294 | union gmac_status status, old_status; |
295 | int pause_tx = 0; |
296 | int pause_rx = 0; |
297 | |
298 | status.bits32 = readl(addr: port->gmac_base + GMAC_STATUS); |
299 | old_status.bits32 = status.bits32; |
300 | status.bits.link = phydev->link; |
301 | status.bits.duplex = phydev->duplex; |
302 | |
303 | switch (phydev->speed) { |
304 | case 1000: |
305 | status.bits.speed = GMAC_SPEED_1000; |
306 | if (phy_interface_mode_is_rgmii(mode: phydev->interface)) |
307 | status.bits.mii_rmii = GMAC_PHY_RGMII_1000; |
308 | netdev_dbg(netdev, "connect %s to RGMII @ 1Gbit\n" , |
309 | phydev_name(phydev)); |
310 | break; |
311 | case 100: |
312 | status.bits.speed = GMAC_SPEED_100; |
313 | if (phy_interface_mode_is_rgmii(mode: phydev->interface)) |
314 | status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; |
315 | netdev_dbg(netdev, "connect %s to RGMII @ 100 Mbit\n" , |
316 | phydev_name(phydev)); |
317 | break; |
318 | case 10: |
319 | status.bits.speed = GMAC_SPEED_10; |
320 | if (phy_interface_mode_is_rgmii(mode: phydev->interface)) |
321 | status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; |
322 | netdev_dbg(netdev, "connect %s to RGMII @ 10 Mbit\n" , |
323 | phydev_name(phydev)); |
324 | break; |
325 | default: |
326 | netdev_warn(dev: netdev, format: "Unsupported PHY speed (%d) on %s\n" , |
327 | phydev->speed, phydev_name(phydev)); |
328 | } |
329 | |
330 | if (phydev->duplex == DUPLEX_FULL) { |
331 | u16 lcladv = phy_read(phydev, MII_ADVERTISE); |
332 | u16 rmtadv = phy_read(phydev, MII_LPA); |
333 | u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv); |
334 | |
335 | if (cap & FLOW_CTRL_RX) |
336 | pause_rx = 1; |
337 | if (cap & FLOW_CTRL_TX) |
338 | pause_tx = 1; |
339 | } |
340 | |
341 | gmac_set_flow_control(netdev, tx: pause_tx, rx: pause_rx); |
342 | |
343 | if (old_status.bits32 == status.bits32) |
344 | return; |
345 | |
346 | if (netif_msg_link(port)) { |
347 | phy_print_status(phydev); |
348 | netdev_info(dev: netdev, format: "link flow control: %s\n" , |
349 | phydev->pause |
350 | ? (phydev->asym_pause ? "tx" : "both" ) |
351 | : (phydev->asym_pause ? "rx" : "none" ) |
352 | ); |
353 | } |
354 | |
355 | gmac_disable_tx_rx(netdev); |
356 | writel(val: status.bits32, addr: port->gmac_base + GMAC_STATUS); |
357 | gmac_enable_tx_rx(netdev); |
358 | } |
359 | |
360 | static int gmac_setup_phy(struct net_device *netdev) |
361 | { |
362 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
363 | union gmac_status status = { .bits32 = 0 }; |
364 | struct device *dev = port->dev; |
365 | struct phy_device *phy; |
366 | |
367 | phy = of_phy_get_and_connect(dev: netdev, |
368 | np: dev->of_node, |
369 | hndlr: gmac_speed_set); |
370 | if (!phy) |
371 | return -ENODEV; |
372 | netdev->phydev = phy; |
373 | |
374 | phy_set_max_speed(phydev: phy, SPEED_1000); |
375 | phy_support_asym_pause(phydev: phy); |
376 | |
377 | /* set PHY interface type */ |
378 | switch (phy->interface) { |
379 | case PHY_INTERFACE_MODE_MII: |
380 | netdev_dbg(netdev, |
381 | "MII: set GMAC0 to GMII mode, GMAC1 disabled\n" ); |
382 | status.bits.mii_rmii = GMAC_PHY_MII; |
383 | break; |
384 | case PHY_INTERFACE_MODE_GMII: |
385 | netdev_dbg(netdev, |
386 | "GMII: set GMAC0 to GMII mode, GMAC1 disabled\n" ); |
387 | status.bits.mii_rmii = GMAC_PHY_GMII; |
388 | break; |
389 | case PHY_INTERFACE_MODE_RGMII: |
390 | case PHY_INTERFACE_MODE_RGMII_ID: |
391 | case PHY_INTERFACE_MODE_RGMII_TXID: |
392 | case PHY_INTERFACE_MODE_RGMII_RXID: |
393 | netdev_dbg(netdev, |
394 | "RGMII: set GMAC0 and GMAC1 to MII/RGMII mode\n" ); |
395 | status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; |
396 | break; |
397 | default: |
398 | netdev_err(dev: netdev, format: "Unsupported MII interface\n" ); |
399 | phy_disconnect(phydev: phy); |
400 | netdev->phydev = NULL; |
401 | return -EINVAL; |
402 | } |
403 | writel(val: status.bits32, addr: port->gmac_base + GMAC_STATUS); |
404 | |
405 | if (netif_msg_link(port)) |
406 | phy_attached_info(phydev: phy); |
407 | |
408 | return 0; |
409 | } |
410 | |
411 | /* The maximum frame length is not logically enumerated in the |
412 | * hardware, so we do a table lookup to find the applicable max |
413 | * frame length. |
414 | */ |
415 | struct gmac_max_framelen { |
416 | unsigned int max_l3_len; |
417 | u8 val; |
418 | }; |
419 | |
420 | static const struct gmac_max_framelen gmac_maxlens[] = { |
421 | { |
422 | .max_l3_len = 1518, |
423 | .val = CONFIG0_MAXLEN_1518, |
424 | }, |
425 | { |
426 | .max_l3_len = 1522, |
427 | .val = CONFIG0_MAXLEN_1522, |
428 | }, |
429 | { |
430 | .max_l3_len = 1536, |
431 | .val = CONFIG0_MAXLEN_1536, |
432 | }, |
433 | { |
434 | .max_l3_len = 1548, |
435 | .val = CONFIG0_MAXLEN_1548, |
436 | }, |
437 | { |
438 | .max_l3_len = 9212, |
439 | .val = CONFIG0_MAXLEN_9k, |
440 | }, |
441 | { |
442 | .max_l3_len = 10236, |
443 | .val = CONFIG0_MAXLEN_10k, |
444 | }, |
445 | }; |
446 | |
447 | static int gmac_pick_rx_max_len(unsigned int max_l3_len) |
448 | { |
449 | const struct gmac_max_framelen *maxlen; |
450 | int maxtot; |
451 | int i; |
452 | |
453 | maxtot = max_l3_len + ETH_HLEN + VLAN_HLEN; |
454 | |
455 | for (i = 0; i < ARRAY_SIZE(gmac_maxlens); i++) { |
456 | maxlen = &gmac_maxlens[i]; |
457 | if (maxtot <= maxlen->max_l3_len) |
458 | return maxlen->val; |
459 | } |
460 | |
461 | return -1; |
462 | } |
463 | |
464 | static int gmac_init(struct net_device *netdev) |
465 | { |
466 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
467 | union gmac_config0 config0 = { .bits = { |
468 | .dis_tx = 1, |
469 | .dis_rx = 1, |
470 | .ipv4_rx_chksum = 1, |
471 | .ipv6_rx_chksum = 1, |
472 | .rx_err_detect = 1, |
473 | .rgmm_edge = 1, |
474 | .port0_chk_hwq = 1, |
475 | .port1_chk_hwq = 1, |
476 | .port0_chk_toeq = 1, |
477 | .port1_chk_toeq = 1, |
478 | .port0_chk_classq = 1, |
479 | .port1_chk_classq = 1, |
480 | } }; |
481 | union gmac_ahb_weight ahb_weight = { .bits = { |
482 | .rx_weight = 1, |
483 | .tx_weight = 1, |
484 | .hash_weight = 1, |
485 | .pre_req = 0x1f, |
486 | .tq_dv_threshold = 0, |
487 | } }; |
488 | union gmac_tx_wcr0 hw_weigh = { .bits = { |
489 | .hw_tq3 = 1, |
490 | .hw_tq2 = 1, |
491 | .hw_tq1 = 1, |
492 | .hw_tq0 = 1, |
493 | } }; |
494 | union gmac_tx_wcr1 sw_weigh = { .bits = { |
495 | .sw_tq5 = 1, |
496 | .sw_tq4 = 1, |
497 | .sw_tq3 = 1, |
498 | .sw_tq2 = 1, |
499 | .sw_tq1 = 1, |
500 | .sw_tq0 = 1, |
501 | } }; |
502 | union gmac_config1 config1 = { .bits = { |
503 | .set_threshold = 16, |
504 | .rel_threshold = 24, |
505 | } }; |
506 | union gmac_config2 config2 = { .bits = { |
507 | .set_threshold = 16, |
508 | .rel_threshold = 32, |
509 | } }; |
510 | union gmac_config3 config3 = { .bits = { |
511 | .set_threshold = 0, |
512 | .rel_threshold = 0, |
513 | } }; |
514 | union gmac_config0 tmp; |
515 | |
516 | config0.bits.max_len = gmac_pick_rx_max_len(max_l3_len: netdev->mtu); |
517 | tmp.bits32 = readl(addr: port->gmac_base + GMAC_CONFIG0); |
518 | config0.bits.reserved = tmp.bits.reserved; |
519 | writel(val: config0.bits32, addr: port->gmac_base + GMAC_CONFIG0); |
520 | writel(val: config1.bits32, addr: port->gmac_base + GMAC_CONFIG1); |
521 | writel(val: config2.bits32, addr: port->gmac_base + GMAC_CONFIG2); |
522 | writel(val: config3.bits32, addr: port->gmac_base + GMAC_CONFIG3); |
523 | |
524 | readl(addr: port->dma_base + GMAC_AHB_WEIGHT_REG); |
525 | writel(val: ahb_weight.bits32, addr: port->dma_base + GMAC_AHB_WEIGHT_REG); |
526 | |
527 | writel(val: hw_weigh.bits32, |
528 | addr: port->dma_base + GMAC_TX_WEIGHTING_CTRL_0_REG); |
529 | writel(val: sw_weigh.bits32, |
530 | addr: port->dma_base + GMAC_TX_WEIGHTING_CTRL_1_REG); |
531 | |
532 | port->rxq_order = DEFAULT_GMAC_RXQ_ORDER; |
533 | port->txq_order = DEFAULT_GMAC_TXQ_ORDER; |
534 | port->rx_coalesce_nsecs = DEFAULT_RX_COALESCE_NSECS; |
535 | |
536 | /* Mark every quarter of the queue a packet for interrupt |
537 | * in order to be able to wake up the queue if it was stopped |
538 | */ |
539 | port->irq_every_tx_packets = 1 << (port->txq_order - 2); |
540 | |
541 | return 0; |
542 | } |
543 | |
544 | static int gmac_setup_txqs(struct net_device *netdev) |
545 | { |
546 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
547 | unsigned int n_txq = netdev->num_tx_queues; |
548 | struct gemini_ethernet *geth = port->geth; |
549 | size_t entries = 1 << port->txq_order; |
550 | struct gmac_txq *txq = port->txq; |
551 | struct gmac_txdesc *desc_ring; |
552 | size_t len = n_txq * entries; |
553 | struct sk_buff **skb_tab; |
554 | void __iomem *rwptr_reg; |
555 | unsigned int r; |
556 | int i; |
557 | |
558 | rwptr_reg = port->dma_base + GMAC_SW_TX_QUEUE0_PTR_REG; |
559 | |
560 | skb_tab = kcalloc(n: len, size: sizeof(*skb_tab), GFP_KERNEL); |
561 | if (!skb_tab) |
562 | return -ENOMEM; |
563 | |
564 | desc_ring = dma_alloc_coherent(dev: geth->dev, size: len * sizeof(*desc_ring), |
565 | dma_handle: &port->txq_dma_base, GFP_KERNEL); |
566 | |
567 | if (!desc_ring) { |
568 | kfree(objp: skb_tab); |
569 | return -ENOMEM; |
570 | } |
571 | |
572 | if (port->txq_dma_base & ~DMA_Q_BASE_MASK) { |
573 | dev_warn(geth->dev, "TX queue base is not aligned\n" ); |
574 | dma_free_coherent(dev: geth->dev, size: len * sizeof(*desc_ring), |
575 | cpu_addr: desc_ring, dma_handle: port->txq_dma_base); |
576 | kfree(objp: skb_tab); |
577 | return -ENOMEM; |
578 | } |
579 | |
580 | writel(val: port->txq_dma_base | port->txq_order, |
581 | addr: port->dma_base + GMAC_SW_TX_QUEUE_BASE_REG); |
582 | |
583 | for (i = 0; i < n_txq; i++) { |
584 | txq->ring = desc_ring; |
585 | txq->skb = skb_tab; |
586 | txq->noirq_packets = 0; |
587 | |
588 | r = readw(addr: rwptr_reg); |
589 | rwptr_reg += 2; |
590 | writew(val: r, addr: rwptr_reg); |
591 | rwptr_reg += 2; |
592 | txq->cptr = r; |
593 | |
594 | txq++; |
595 | desc_ring += entries; |
596 | skb_tab += entries; |
597 | } |
598 | |
599 | return 0; |
600 | } |
601 | |
602 | static void gmac_clean_txq(struct net_device *netdev, struct gmac_txq *txq, |
603 | unsigned int r) |
604 | { |
605 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
606 | unsigned int m = (1 << port->txq_order) - 1; |
607 | struct gemini_ethernet *geth = port->geth; |
608 | unsigned int c = txq->cptr; |
609 | union gmac_txdesc_0 word0; |
610 | union gmac_txdesc_1 word1; |
611 | unsigned int hwchksum = 0; |
612 | unsigned long bytes = 0; |
613 | struct gmac_txdesc *txd; |
614 | unsigned short nfrags; |
615 | unsigned int errs = 0; |
616 | unsigned int pkts = 0; |
617 | unsigned int word3; |
618 | dma_addr_t mapping; |
619 | |
620 | if (c == r) |
621 | return; |
622 | |
623 | while (c != r) { |
624 | txd = txq->ring + c; |
625 | word0 = txd->word0; |
626 | word1 = txd->word1; |
627 | mapping = txd->word2.buf_adr; |
628 | word3 = txd->word3.bits32; |
629 | |
630 | dma_unmap_single(geth->dev, mapping, |
631 | word0.bits.buffer_size, DMA_TO_DEVICE); |
632 | |
633 | if (word3 & EOF_BIT) |
634 | dev_kfree_skb(txq->skb[c]); |
635 | |
636 | c++; |
637 | c &= m; |
638 | |
639 | if (!(word3 & SOF_BIT)) |
640 | continue; |
641 | |
642 | if (!word0.bits.status_tx_ok) { |
643 | errs++; |
644 | continue; |
645 | } |
646 | |
647 | pkts++; |
648 | bytes += txd->word1.bits.byte_count; |
649 | |
650 | if (word1.bits32 & TSS_CHECKUM_ENABLE) |
651 | hwchksum++; |
652 | |
653 | nfrags = word0.bits.desc_count - 1; |
654 | if (nfrags) { |
655 | if (nfrags >= TX_MAX_FRAGS) |
656 | nfrags = TX_MAX_FRAGS - 1; |
657 | |
658 | u64_stats_update_begin(syncp: &port->tx_stats_syncp); |
659 | port->tx_frag_stats[nfrags]++; |
660 | u64_stats_update_end(syncp: &port->tx_stats_syncp); |
661 | } |
662 | } |
663 | |
664 | u64_stats_update_begin(syncp: &port->ir_stats_syncp); |
665 | port->stats.tx_errors += errs; |
666 | port->stats.tx_packets += pkts; |
667 | port->stats.tx_bytes += bytes; |
668 | port->tx_hw_csummed += hwchksum; |
669 | u64_stats_update_end(syncp: &port->ir_stats_syncp); |
670 | |
671 | txq->cptr = c; |
672 | } |
673 | |
674 | static void gmac_cleanup_txqs(struct net_device *netdev) |
675 | { |
676 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
677 | unsigned int n_txq = netdev->num_tx_queues; |
678 | struct gemini_ethernet *geth = port->geth; |
679 | void __iomem *rwptr_reg; |
680 | unsigned int r, i; |
681 | |
682 | rwptr_reg = port->dma_base + GMAC_SW_TX_QUEUE0_PTR_REG; |
683 | |
684 | for (i = 0; i < n_txq; i++) { |
685 | r = readw(addr: rwptr_reg); |
686 | rwptr_reg += 2; |
687 | writew(val: r, addr: rwptr_reg); |
688 | rwptr_reg += 2; |
689 | |
690 | gmac_clean_txq(netdev, txq: port->txq + i, r); |
691 | } |
692 | writel(val: 0, addr: port->dma_base + GMAC_SW_TX_QUEUE_BASE_REG); |
693 | |
694 | kfree(objp: port->txq->skb); |
695 | dma_free_coherent(dev: geth->dev, |
696 | size: n_txq * sizeof(*port->txq->ring) << port->txq_order, |
697 | cpu_addr: port->txq->ring, dma_handle: port->txq_dma_base); |
698 | } |
699 | |
700 | static int gmac_setup_rxq(struct net_device *netdev) |
701 | { |
702 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
703 | struct gemini_ethernet *geth = port->geth; |
704 | struct nontoe_qhdr __iomem *qhdr; |
705 | |
706 | qhdr = geth->base + TOE_DEFAULT_Q_HDR_BASE(netdev->dev_id); |
707 | port->rxq_rwptr = &qhdr->word1; |
708 | |
709 | /* Remap a slew of memory to use for the RX queue */ |
710 | port->rxq_ring = dma_alloc_coherent(dev: geth->dev, |
711 | size: sizeof(*port->rxq_ring) << port->rxq_order, |
712 | dma_handle: &port->rxq_dma_base, GFP_KERNEL); |
713 | if (!port->rxq_ring) |
714 | return -ENOMEM; |
715 | if (port->rxq_dma_base & ~NONTOE_QHDR0_BASE_MASK) { |
716 | dev_warn(geth->dev, "RX queue base is not aligned\n" ); |
717 | return -ENOMEM; |
718 | } |
719 | |
720 | writel(val: port->rxq_dma_base | port->rxq_order, addr: &qhdr->word0); |
721 | writel(val: 0, addr: port->rxq_rwptr); |
722 | return 0; |
723 | } |
724 | |
725 | static struct gmac_queue_page * |
726 | gmac_get_queue_page(struct gemini_ethernet *geth, |
727 | struct gemini_ethernet_port *port, |
728 | dma_addr_t addr) |
729 | { |
730 | struct gmac_queue_page *gpage; |
731 | dma_addr_t mapping; |
732 | int i; |
733 | |
734 | /* Only look for even pages */ |
735 | mapping = addr & PAGE_MASK; |
736 | |
737 | if (!geth->freeq_pages) { |
738 | dev_err(geth->dev, "try to get page with no page list\n" ); |
739 | return NULL; |
740 | } |
741 | |
742 | /* Look up a ring buffer page from virtual mapping */ |
743 | for (i = 0; i < geth->num_freeq_pages; i++) { |
744 | gpage = &geth->freeq_pages[i]; |
745 | if (gpage->mapping == mapping) |
746 | return gpage; |
747 | } |
748 | |
749 | return NULL; |
750 | } |
751 | |
752 | static void gmac_cleanup_rxq(struct net_device *netdev) |
753 | { |
754 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
755 | struct gemini_ethernet *geth = port->geth; |
756 | struct gmac_rxdesc *rxd = port->rxq_ring; |
757 | static struct gmac_queue_page *gpage; |
758 | struct nontoe_qhdr __iomem *qhdr; |
759 | void __iomem *dma_reg; |
760 | void __iomem *ptr_reg; |
761 | dma_addr_t mapping; |
762 | union dma_rwptr rw; |
763 | unsigned int r, w; |
764 | |
765 | qhdr = geth->base + |
766 | TOE_DEFAULT_Q_HDR_BASE(netdev->dev_id); |
767 | dma_reg = &qhdr->word0; |
768 | ptr_reg = &qhdr->word1; |
769 | |
770 | rw.bits32 = readl(addr: ptr_reg); |
771 | r = rw.bits.rptr; |
772 | w = rw.bits.wptr; |
773 | writew(val: r, addr: ptr_reg + 2); |
774 | |
775 | writel(val: 0, addr: dma_reg); |
776 | |
777 | /* Loop from read pointer to write pointer of the RX queue |
778 | * and free up all pages by the queue. |
779 | */ |
780 | while (r != w) { |
781 | mapping = rxd[r].word2.buf_adr; |
782 | r++; |
783 | r &= ((1 << port->rxq_order) - 1); |
784 | |
785 | if (!mapping) |
786 | continue; |
787 | |
788 | /* Freeq pointers are one page off */ |
789 | gpage = gmac_get_queue_page(geth, port, addr: mapping + PAGE_SIZE); |
790 | if (!gpage) { |
791 | dev_err(geth->dev, "could not find page\n" ); |
792 | continue; |
793 | } |
794 | /* Release the RX queue reference to the page */ |
795 | put_page(page: gpage->page); |
796 | } |
797 | |
798 | dma_free_coherent(dev: geth->dev, size: sizeof(*port->rxq_ring) << port->rxq_order, |
799 | cpu_addr: port->rxq_ring, dma_handle: port->rxq_dma_base); |
800 | } |
801 | |
802 | static struct page *geth_freeq_alloc_map_page(struct gemini_ethernet *geth, |
803 | int pn) |
804 | { |
805 | struct gmac_rxdesc *freeq_entry; |
806 | struct gmac_queue_page *gpage; |
807 | unsigned int fpp_order; |
808 | unsigned int frag_len; |
809 | dma_addr_t mapping; |
810 | struct page *page; |
811 | int i; |
812 | |
813 | /* First allocate and DMA map a single page */ |
814 | page = alloc_page(GFP_ATOMIC); |
815 | if (!page) |
816 | return NULL; |
817 | |
818 | mapping = dma_map_single(geth->dev, page_address(page), |
819 | PAGE_SIZE, DMA_FROM_DEVICE); |
820 | if (dma_mapping_error(dev: geth->dev, dma_addr: mapping)) { |
821 | put_page(page); |
822 | return NULL; |
823 | } |
824 | |
825 | /* The assign the page mapping (physical address) to the buffer address |
826 | * in the hardware queue. PAGE_SHIFT on ARM is 12 (1 page is 4096 bytes, |
827 | * 4k), and the default RX frag order is 11 (fragments are up 20 2048 |
828 | * bytes, 2k) so fpp_order (fragments per page order) is default 1. Thus |
829 | * each page normally needs two entries in the queue. |
830 | */ |
831 | frag_len = 1 << geth->freeq_frag_order; /* Usually 2048 */ |
832 | fpp_order = PAGE_SHIFT - geth->freeq_frag_order; |
833 | freeq_entry = geth->freeq_ring + (pn << fpp_order); |
834 | dev_dbg(geth->dev, "allocate page %d fragment length %d fragments per page %d, freeq entry %p\n" , |
835 | pn, frag_len, (1 << fpp_order), freeq_entry); |
836 | for (i = (1 << fpp_order); i > 0; i--) { |
837 | freeq_entry->word2.buf_adr = mapping; |
838 | freeq_entry++; |
839 | mapping += frag_len; |
840 | } |
841 | |
842 | /* If the freeq entry already has a page mapped, then unmap it. */ |
843 | gpage = &geth->freeq_pages[pn]; |
844 | if (gpage->page) { |
845 | mapping = geth->freeq_ring[pn << fpp_order].word2.buf_adr; |
846 | dma_unmap_single(geth->dev, mapping, frag_len, DMA_FROM_DEVICE); |
847 | /* This should be the last reference to the page so it gets |
848 | * released |
849 | */ |
850 | put_page(page: gpage->page); |
851 | } |
852 | |
853 | /* Then put our new mapping into the page table */ |
854 | dev_dbg(geth->dev, "page %d, DMA addr: %08x, page %p\n" , |
855 | pn, (unsigned int)mapping, page); |
856 | gpage->mapping = mapping; |
857 | gpage->page = page; |
858 | |
859 | return page; |
860 | } |
861 | |
862 | /** |
863 | * geth_fill_freeq() - Fill the freeq with empty fragments to use |
864 | * @geth: the ethernet adapter |
865 | * @refill: whether to reset the queue by filling in all freeq entries or |
866 | * just refill it, usually the interrupt to refill the queue happens when |
867 | * the queue is half empty. |
868 | */ |
869 | static unsigned int geth_fill_freeq(struct gemini_ethernet *geth, bool refill) |
870 | { |
871 | unsigned int fpp_order = PAGE_SHIFT - geth->freeq_frag_order; |
872 | unsigned int count = 0; |
873 | unsigned int pn, epn; |
874 | unsigned long flags; |
875 | union dma_rwptr rw; |
876 | unsigned int m_pn; |
877 | |
878 | /* Mask for page */ |
879 | m_pn = (1 << (geth->freeq_order - fpp_order)) - 1; |
880 | |
881 | spin_lock_irqsave(&geth->freeq_lock, flags); |
882 | |
883 | rw.bits32 = readl(addr: geth->base + GLOBAL_SWFQ_RWPTR_REG); |
884 | pn = (refill ? rw.bits.wptr : rw.bits.rptr) >> fpp_order; |
885 | epn = (rw.bits.rptr >> fpp_order) - 1; |
886 | epn &= m_pn; |
887 | |
888 | /* Loop over the freeq ring buffer entries */ |
889 | while (pn != epn) { |
890 | struct gmac_queue_page *gpage; |
891 | struct page *page; |
892 | |
893 | gpage = &geth->freeq_pages[pn]; |
894 | page = gpage->page; |
895 | |
896 | dev_dbg(geth->dev, "fill entry %d page ref count %d add %d refs\n" , |
897 | pn, page_ref_count(page), 1 << fpp_order); |
898 | |
899 | if (page_ref_count(page) > 1) { |
900 | unsigned int fl = (pn - epn) & m_pn; |
901 | |
902 | if (fl > 64 >> fpp_order) |
903 | break; |
904 | |
905 | page = geth_freeq_alloc_map_page(geth, pn); |
906 | if (!page) |
907 | break; |
908 | } |
909 | |
910 | /* Add one reference per fragment in the page */ |
911 | page_ref_add(page, nr: 1 << fpp_order); |
912 | count += 1 << fpp_order; |
913 | pn++; |
914 | pn &= m_pn; |
915 | } |
916 | |
917 | writew(val: pn << fpp_order, addr: geth->base + GLOBAL_SWFQ_RWPTR_REG + 2); |
918 | |
919 | spin_unlock_irqrestore(lock: &geth->freeq_lock, flags); |
920 | |
921 | return count; |
922 | } |
923 | |
924 | static int geth_setup_freeq(struct gemini_ethernet *geth) |
925 | { |
926 | unsigned int fpp_order = PAGE_SHIFT - geth->freeq_frag_order; |
927 | unsigned int frag_len = 1 << geth->freeq_frag_order; |
928 | unsigned int len = 1 << geth->freeq_order; |
929 | unsigned int pages = len >> fpp_order; |
930 | union queue_threshold qt; |
931 | union dma_skb_size skbsz; |
932 | unsigned int filled; |
933 | unsigned int pn; |
934 | |
935 | geth->freeq_ring = dma_alloc_coherent(dev: geth->dev, |
936 | size: sizeof(*geth->freeq_ring) << geth->freeq_order, |
937 | dma_handle: &geth->freeq_dma_base, GFP_KERNEL); |
938 | if (!geth->freeq_ring) |
939 | return -ENOMEM; |
940 | if (geth->freeq_dma_base & ~DMA_Q_BASE_MASK) { |
941 | dev_warn(geth->dev, "queue ring base is not aligned\n" ); |
942 | goto err_freeq; |
943 | } |
944 | |
945 | /* Allocate a mapping to page look-up index */ |
946 | geth->freeq_pages = kcalloc(n: pages, size: sizeof(*geth->freeq_pages), |
947 | GFP_KERNEL); |
948 | if (!geth->freeq_pages) |
949 | goto err_freeq; |
950 | geth->num_freeq_pages = pages; |
951 | |
952 | dev_info(geth->dev, "allocate %d pages for queue\n" , pages); |
953 | for (pn = 0; pn < pages; pn++) |
954 | if (!geth_freeq_alloc_map_page(geth, pn)) |
955 | goto err_freeq_alloc; |
956 | |
957 | filled = geth_fill_freeq(geth, refill: false); |
958 | if (!filled) |
959 | goto err_freeq_alloc; |
960 | |
961 | qt.bits32 = readl(addr: geth->base + GLOBAL_QUEUE_THRESHOLD_REG); |
962 | qt.bits.swfq_empty = 32; |
963 | writel(val: qt.bits32, addr: geth->base + GLOBAL_QUEUE_THRESHOLD_REG); |
964 | |
965 | skbsz.bits.sw_skb_size = 1 << geth->freeq_frag_order; |
966 | writel(val: skbsz.bits32, addr: geth->base + GLOBAL_DMA_SKB_SIZE_REG); |
967 | writel(val: geth->freeq_dma_base | geth->freeq_order, |
968 | addr: geth->base + GLOBAL_SW_FREEQ_BASE_SIZE_REG); |
969 | |
970 | return 0; |
971 | |
972 | err_freeq_alloc: |
973 | while (pn > 0) { |
974 | struct gmac_queue_page *gpage; |
975 | dma_addr_t mapping; |
976 | |
977 | --pn; |
978 | mapping = geth->freeq_ring[pn << fpp_order].word2.buf_adr; |
979 | dma_unmap_single(geth->dev, mapping, frag_len, DMA_FROM_DEVICE); |
980 | gpage = &geth->freeq_pages[pn]; |
981 | put_page(page: gpage->page); |
982 | } |
983 | |
984 | kfree(objp: geth->freeq_pages); |
985 | err_freeq: |
986 | dma_free_coherent(dev: geth->dev, |
987 | size: sizeof(*geth->freeq_ring) << geth->freeq_order, |
988 | cpu_addr: geth->freeq_ring, dma_handle: geth->freeq_dma_base); |
989 | geth->freeq_ring = NULL; |
990 | return -ENOMEM; |
991 | } |
992 | |
993 | /** |
994 | * geth_cleanup_freeq() - cleanup the DMA mappings and free the queue |
995 | * @geth: the Gemini global ethernet state |
996 | */ |
997 | static void geth_cleanup_freeq(struct gemini_ethernet *geth) |
998 | { |
999 | unsigned int fpp_order = PAGE_SHIFT - geth->freeq_frag_order; |
1000 | unsigned int frag_len = 1 << geth->freeq_frag_order; |
1001 | unsigned int len = 1 << geth->freeq_order; |
1002 | unsigned int pages = len >> fpp_order; |
1003 | unsigned int pn; |
1004 | |
1005 | writew(readw(addr: geth->base + GLOBAL_SWFQ_RWPTR_REG), |
1006 | addr: geth->base + GLOBAL_SWFQ_RWPTR_REG + 2); |
1007 | writel(val: 0, addr: geth->base + GLOBAL_SW_FREEQ_BASE_SIZE_REG); |
1008 | |
1009 | for (pn = 0; pn < pages; pn++) { |
1010 | struct gmac_queue_page *gpage; |
1011 | dma_addr_t mapping; |
1012 | |
1013 | mapping = geth->freeq_ring[pn << fpp_order].word2.buf_adr; |
1014 | dma_unmap_single(geth->dev, mapping, frag_len, DMA_FROM_DEVICE); |
1015 | |
1016 | gpage = &geth->freeq_pages[pn]; |
1017 | while (page_ref_count(page: gpage->page) > 0) |
1018 | put_page(page: gpage->page); |
1019 | } |
1020 | |
1021 | kfree(objp: geth->freeq_pages); |
1022 | |
1023 | dma_free_coherent(dev: geth->dev, |
1024 | size: sizeof(*geth->freeq_ring) << geth->freeq_order, |
1025 | cpu_addr: geth->freeq_ring, dma_handle: geth->freeq_dma_base); |
1026 | } |
1027 | |
1028 | /** |
1029 | * geth_resize_freeq() - resize the software queue depth |
1030 | * @port: the port requesting the change |
1031 | * |
1032 | * This gets called at least once during probe() so the device queue gets |
1033 | * "resized" from the hardware defaults. Since both ports/net devices share |
1034 | * the same hardware queue, some synchronization between the ports is |
1035 | * needed. |
1036 | */ |
1037 | static int geth_resize_freeq(struct gemini_ethernet_port *port) |
1038 | { |
1039 | struct gemini_ethernet *geth = port->geth; |
1040 | struct net_device *netdev = port->netdev; |
1041 | struct gemini_ethernet_port *other_port; |
1042 | struct net_device *other_netdev; |
1043 | unsigned int new_size = 0; |
1044 | unsigned int new_order; |
1045 | unsigned long flags; |
1046 | u32 en; |
1047 | int ret; |
1048 | |
1049 | if (netdev->dev_id == 0) |
1050 | other_netdev = geth->port1->netdev; |
1051 | else |
1052 | other_netdev = geth->port0->netdev; |
1053 | |
1054 | if (other_netdev && netif_running(dev: other_netdev)) |
1055 | return -EBUSY; |
1056 | |
1057 | new_size = 1 << (port->rxq_order + 1); |
1058 | netdev_dbg(netdev, "port %d size: %d order %d\n" , |
1059 | netdev->dev_id, |
1060 | new_size, |
1061 | port->rxq_order); |
1062 | if (other_netdev) { |
1063 | other_port = netdev_priv(dev: other_netdev); |
1064 | new_size += 1 << (other_port->rxq_order + 1); |
1065 | netdev_dbg(other_netdev, "port %d size: %d order %d\n" , |
1066 | other_netdev->dev_id, |
1067 | (1 << (other_port->rxq_order + 1)), |
1068 | other_port->rxq_order); |
1069 | } |
1070 | |
1071 | new_order = min(15, ilog2(new_size - 1) + 1); |
1072 | dev_dbg(geth->dev, "set shared queue to size %d order %d\n" , |
1073 | new_size, new_order); |
1074 | if (geth->freeq_order == new_order) |
1075 | return 0; |
1076 | |
1077 | spin_lock_irqsave(&geth->irq_lock, flags); |
1078 | |
1079 | /* Disable the software queue IRQs */ |
1080 | en = readl(addr: geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); |
1081 | en &= ~SWFQ_EMPTY_INT_BIT; |
1082 | writel(val: en, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); |
1083 | spin_unlock_irqrestore(lock: &geth->irq_lock, flags); |
1084 | |
1085 | /* Drop the old queue */ |
1086 | if (geth->freeq_ring) |
1087 | geth_cleanup_freeq(geth); |
1088 | |
1089 | /* Allocate a new queue with the desired order */ |
1090 | geth->freeq_order = new_order; |
1091 | ret = geth_setup_freeq(geth); |
1092 | |
1093 | /* Restart the interrupts - NOTE if this is the first resize |
1094 | * after probe(), this is where the interrupts get turned on |
1095 | * in the first place. |
1096 | */ |
1097 | spin_lock_irqsave(&geth->irq_lock, flags); |
1098 | en |= SWFQ_EMPTY_INT_BIT; |
1099 | writel(val: en, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); |
1100 | spin_unlock_irqrestore(lock: &geth->irq_lock, flags); |
1101 | |
1102 | return ret; |
1103 | } |
1104 | |
1105 | static void gmac_tx_irq_enable(struct net_device *netdev, |
1106 | unsigned int txq, int en) |
1107 | { |
1108 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1109 | struct gemini_ethernet *geth = port->geth; |
1110 | u32 val, mask; |
1111 | |
1112 | netdev_dbg(netdev, "%s device %d\n" , __func__, netdev->dev_id); |
1113 | |
1114 | mask = GMAC0_IRQ0_TXQ0_INTS << (6 * netdev->dev_id + txq); |
1115 | |
1116 | if (en) |
1117 | writel(val: mask, addr: geth->base + GLOBAL_INTERRUPT_STATUS_0_REG); |
1118 | |
1119 | val = readl(addr: geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); |
1120 | val = en ? val | mask : val & ~mask; |
1121 | writel(val, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); |
1122 | } |
1123 | |
1124 | static void gmac_tx_irq(struct net_device *netdev, unsigned int txq_num) |
1125 | { |
1126 | struct netdev_queue *ntxq = netdev_get_tx_queue(dev: netdev, index: txq_num); |
1127 | |
1128 | gmac_tx_irq_enable(netdev, txq: txq_num, en: 0); |
1129 | netif_tx_wake_queue(dev_queue: ntxq); |
1130 | } |
1131 | |
1132 | static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, |
1133 | struct gmac_txq *txq, unsigned short *desc) |
1134 | { |
1135 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1136 | struct skb_shared_info *skb_si = skb_shinfo(skb); |
1137 | unsigned short m = (1 << port->txq_order) - 1; |
1138 | short frag, last_frag = skb_si->nr_frags - 1; |
1139 | struct gemini_ethernet *geth = port->geth; |
1140 | unsigned int word1, word3, buflen; |
1141 | unsigned short w = *desc; |
1142 | struct gmac_txdesc *txd; |
1143 | skb_frag_t *skb_frag; |
1144 | dma_addr_t mapping; |
1145 | void *buffer; |
1146 | int ret; |
1147 | |
1148 | /* TODO: implement proper TSO using MTU in word3 */ |
1149 | word1 = skb->len; |
1150 | word3 = SOF_BIT; |
1151 | |
1152 | if (skb->len >= ETH_FRAME_LEN) { |
1153 | /* Hardware offloaded checksumming isn't working on frames |
1154 | * bigger than 1514 bytes. A hypothesis about this is that the |
1155 | * checksum buffer is only 1518 bytes, so when the frames get |
1156 | * bigger they get truncated, or the last few bytes get |
1157 | * overwritten by the FCS. |
1158 | * |
1159 | * Just use software checksumming and bypass on bigger frames. |
1160 | */ |
1161 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
1162 | ret = skb_checksum_help(skb); |
1163 | if (ret) |
1164 | return ret; |
1165 | } |
1166 | word1 |= TSS_BYPASS_BIT; |
1167 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
1168 | int tcp = 0; |
1169 | |
1170 | /* We do not switch off the checksumming on non TCP/UDP |
1171 | * frames: as is shown from tests, the checksumming engine |
1172 | * is smart enough to see that a frame is not actually TCP |
1173 | * or UDP and then just pass it through without any changes |
1174 | * to the frame. |
1175 | */ |
1176 | if (skb->protocol == htons(ETH_P_IP)) { |
1177 | word1 |= TSS_IP_CHKSUM_BIT; |
1178 | tcp = ip_hdr(skb)->protocol == IPPROTO_TCP; |
1179 | } else { /* IPv6 */ |
1180 | word1 |= TSS_IPV6_ENABLE_BIT; |
1181 | tcp = ipv6_hdr(skb)->nexthdr == IPPROTO_TCP; |
1182 | } |
1183 | |
1184 | word1 |= tcp ? TSS_TCP_CHKSUM_BIT : TSS_UDP_CHKSUM_BIT; |
1185 | } |
1186 | |
1187 | frag = -1; |
1188 | while (frag <= last_frag) { |
1189 | if (frag == -1) { |
1190 | buffer = skb->data; |
1191 | buflen = skb_headlen(skb); |
1192 | } else { |
1193 | skb_frag = skb_si->frags + frag; |
1194 | buffer = skb_frag_address(frag: skb_frag); |
1195 | buflen = skb_frag_size(frag: skb_frag); |
1196 | } |
1197 | |
1198 | if (frag == last_frag) { |
1199 | word3 |= EOF_BIT; |
1200 | txq->skb[w] = skb; |
1201 | } |
1202 | |
1203 | mapping = dma_map_single(geth->dev, buffer, buflen, |
1204 | DMA_TO_DEVICE); |
1205 | if (dma_mapping_error(dev: geth->dev, dma_addr: mapping)) |
1206 | goto map_error; |
1207 | |
1208 | txd = txq->ring + w; |
1209 | txd->word0.bits32 = buflen; |
1210 | txd->word1.bits32 = word1; |
1211 | txd->word2.buf_adr = mapping; |
1212 | txd->word3.bits32 = word3; |
1213 | |
1214 | word3 &= MTU_SIZE_BIT_MASK; |
1215 | w++; |
1216 | w &= m; |
1217 | frag++; |
1218 | } |
1219 | |
1220 | *desc = w; |
1221 | return 0; |
1222 | |
1223 | map_error: |
1224 | while (w != *desc) { |
1225 | w--; |
1226 | w &= m; |
1227 | |
1228 | dma_unmap_page(geth->dev, txq->ring[w].word2.buf_adr, |
1229 | txq->ring[w].word0.bits.buffer_size, |
1230 | DMA_TO_DEVICE); |
1231 | } |
1232 | return -ENOMEM; |
1233 | } |
1234 | |
1235 | static netdev_tx_t gmac_start_xmit(struct sk_buff *skb, |
1236 | struct net_device *netdev) |
1237 | { |
1238 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1239 | unsigned short m = (1 << port->txq_order) - 1; |
1240 | struct netdev_queue *ntxq; |
1241 | unsigned short r, w, d; |
1242 | void __iomem *ptr_reg; |
1243 | struct gmac_txq *txq; |
1244 | int txq_num, nfrags; |
1245 | union dma_rwptr rw; |
1246 | |
1247 | if (skb->len >= 0x10000) |
1248 | goto out_drop_free; |
1249 | |
1250 | txq_num = skb_get_queue_mapping(skb); |
1251 | ptr_reg = port->dma_base + GMAC_SW_TX_QUEUE_PTR_REG(txq_num); |
1252 | txq = &port->txq[txq_num]; |
1253 | ntxq = netdev_get_tx_queue(dev: netdev, index: txq_num); |
1254 | nfrags = skb_shinfo(skb)->nr_frags; |
1255 | |
1256 | rw.bits32 = readl(addr: ptr_reg); |
1257 | r = rw.bits.rptr; |
1258 | w = rw.bits.wptr; |
1259 | |
1260 | d = txq->cptr - w - 1; |
1261 | d &= m; |
1262 | |
1263 | if (d < nfrags + 2) { |
1264 | gmac_clean_txq(netdev, txq, r); |
1265 | d = txq->cptr - w - 1; |
1266 | d &= m; |
1267 | |
1268 | if (d < nfrags + 2) { |
1269 | netif_tx_stop_queue(dev_queue: ntxq); |
1270 | |
1271 | d = txq->cptr + nfrags + 16; |
1272 | d &= m; |
1273 | txq->ring[d].word3.bits.eofie = 1; |
1274 | gmac_tx_irq_enable(netdev, txq: txq_num, en: 1); |
1275 | |
1276 | u64_stats_update_begin(syncp: &port->tx_stats_syncp); |
1277 | netdev->stats.tx_fifo_errors++; |
1278 | u64_stats_update_end(syncp: &port->tx_stats_syncp); |
1279 | return NETDEV_TX_BUSY; |
1280 | } |
1281 | } |
1282 | |
1283 | if (gmac_map_tx_bufs(netdev, skb, txq, desc: &w)) { |
1284 | if (skb_linearize(skb)) |
1285 | goto out_drop; |
1286 | |
1287 | u64_stats_update_begin(syncp: &port->tx_stats_syncp); |
1288 | port->tx_frags_linearized++; |
1289 | u64_stats_update_end(syncp: &port->tx_stats_syncp); |
1290 | |
1291 | if (gmac_map_tx_bufs(netdev, skb, txq, desc: &w)) |
1292 | goto out_drop_free; |
1293 | } |
1294 | |
1295 | writew(val: w, addr: ptr_reg + 2); |
1296 | |
1297 | gmac_clean_txq(netdev, txq, r); |
1298 | return NETDEV_TX_OK; |
1299 | |
1300 | out_drop_free: |
1301 | dev_kfree_skb(skb); |
1302 | out_drop: |
1303 | u64_stats_update_begin(syncp: &port->tx_stats_syncp); |
1304 | port->stats.tx_dropped++; |
1305 | u64_stats_update_end(syncp: &port->tx_stats_syncp); |
1306 | return NETDEV_TX_OK; |
1307 | } |
1308 | |
1309 | static void gmac_tx_timeout(struct net_device *netdev, unsigned int txqueue) |
1310 | { |
1311 | netdev_err(dev: netdev, format: "Tx timeout\n" ); |
1312 | gmac_dump_dma_state(netdev); |
1313 | } |
1314 | |
1315 | static void gmac_enable_irq(struct net_device *netdev, int enable) |
1316 | { |
1317 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1318 | struct gemini_ethernet *geth = port->geth; |
1319 | unsigned long flags; |
1320 | u32 val, mask; |
1321 | |
1322 | netdev_dbg(netdev, "%s device %d %s\n" , __func__, |
1323 | netdev->dev_id, enable ? "enable" : "disable" ); |
1324 | spin_lock_irqsave(&geth->irq_lock, flags); |
1325 | |
1326 | mask = GMAC0_IRQ0_2 << (netdev->dev_id * 2); |
1327 | val = readl(addr: geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); |
1328 | val = enable ? (val | mask) : (val & ~mask); |
1329 | writel(val, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); |
1330 | |
1331 | mask = DEFAULT_Q0_INT_BIT << netdev->dev_id; |
1332 | val = readl(addr: geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); |
1333 | val = enable ? (val | mask) : (val & ~mask); |
1334 | writel(val, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); |
1335 | |
1336 | mask = GMAC0_IRQ4_8 << (netdev->dev_id * 8); |
1337 | val = readl(addr: geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); |
1338 | val = enable ? (val | mask) : (val & ~mask); |
1339 | writel(val, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); |
1340 | |
1341 | spin_unlock_irqrestore(lock: &geth->irq_lock, flags); |
1342 | } |
1343 | |
1344 | static void gmac_enable_rx_irq(struct net_device *netdev, int enable) |
1345 | { |
1346 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1347 | struct gemini_ethernet *geth = port->geth; |
1348 | unsigned long flags; |
1349 | u32 val, mask; |
1350 | |
1351 | netdev_dbg(netdev, "%s device %d %s\n" , __func__, netdev->dev_id, |
1352 | enable ? "enable" : "disable" ); |
1353 | spin_lock_irqsave(&geth->irq_lock, flags); |
1354 | mask = DEFAULT_Q0_INT_BIT << netdev->dev_id; |
1355 | |
1356 | val = readl(addr: geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); |
1357 | val = enable ? (val | mask) : (val & ~mask); |
1358 | writel(val, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); |
1359 | |
1360 | spin_unlock_irqrestore(lock: &geth->irq_lock, flags); |
1361 | } |
1362 | |
1363 | static struct sk_buff *gmac_skb_if_good_frame(struct gemini_ethernet_port *port, |
1364 | union gmac_rxdesc_0 word0, |
1365 | unsigned int frame_len) |
1366 | { |
1367 | unsigned int rx_csum = word0.bits.chksum_status; |
1368 | unsigned int rx_status = word0.bits.status; |
1369 | struct sk_buff *skb = NULL; |
1370 | |
1371 | port->rx_stats[rx_status]++; |
1372 | port->rx_csum_stats[rx_csum]++; |
1373 | |
1374 | if (word0.bits.derr || word0.bits.perr || |
1375 | rx_status || frame_len < ETH_ZLEN || |
1376 | rx_csum >= RX_CHKSUM_IP_ERR_UNKNOWN) { |
1377 | port->stats.rx_errors++; |
1378 | |
1379 | if (frame_len < ETH_ZLEN || RX_ERROR_LENGTH(rx_status)) |
1380 | port->stats.rx_length_errors++; |
1381 | if (RX_ERROR_OVER(rx_status)) |
1382 | port->stats.rx_over_errors++; |
1383 | if (RX_ERROR_CRC(rx_status)) |
1384 | port->stats.rx_crc_errors++; |
1385 | if (RX_ERROR_FRAME(rx_status)) |
1386 | port->stats.rx_frame_errors++; |
1387 | return NULL; |
1388 | } |
1389 | |
1390 | skb = napi_get_frags(napi: &port->napi); |
1391 | if (!skb) |
1392 | goto update_exit; |
1393 | |
1394 | if (rx_csum == RX_CHKSUM_IP_UDP_TCP_OK) |
1395 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1396 | |
1397 | update_exit: |
1398 | port->stats.rx_bytes += frame_len; |
1399 | port->stats.rx_packets++; |
1400 | return skb; |
1401 | } |
1402 | |
1403 | static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget) |
1404 | { |
1405 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1406 | unsigned short m = (1 << port->rxq_order) - 1; |
1407 | struct gemini_ethernet *geth = port->geth; |
1408 | void __iomem *ptr_reg = port->rxq_rwptr; |
1409 | unsigned int frame_len, frag_len; |
1410 | struct gmac_rxdesc *rx = NULL; |
1411 | struct gmac_queue_page *gpage; |
1412 | static struct sk_buff *skb; |
1413 | union gmac_rxdesc_0 word0; |
1414 | union gmac_rxdesc_1 word1; |
1415 | union gmac_rxdesc_3 word3; |
1416 | struct page *page = NULL; |
1417 | unsigned int page_offs; |
1418 | unsigned short r, w; |
1419 | union dma_rwptr rw; |
1420 | dma_addr_t mapping; |
1421 | int frag_nr = 0; |
1422 | |
1423 | rw.bits32 = readl(addr: ptr_reg); |
1424 | /* Reset interrupt as all packages until here are taken into account */ |
1425 | writel(DEFAULT_Q0_INT_BIT << netdev->dev_id, |
1426 | addr: geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); |
1427 | r = rw.bits.rptr; |
1428 | w = rw.bits.wptr; |
1429 | |
1430 | while (budget && w != r) { |
1431 | rx = port->rxq_ring + r; |
1432 | word0 = rx->word0; |
1433 | word1 = rx->word1; |
1434 | mapping = rx->word2.buf_adr; |
1435 | word3 = rx->word3; |
1436 | |
1437 | r++; |
1438 | r &= m; |
1439 | |
1440 | frag_len = word0.bits.buffer_size; |
1441 | frame_len = word1.bits.byte_count; |
1442 | page_offs = mapping & ~PAGE_MASK; |
1443 | |
1444 | if (!mapping) { |
1445 | netdev_err(dev: netdev, |
1446 | format: "rxq[%u]: HW BUG: zero DMA desc\n" , r); |
1447 | goto err_drop; |
1448 | } |
1449 | |
1450 | /* Freeq pointers are one page off */ |
1451 | gpage = gmac_get_queue_page(geth, port, addr: mapping + PAGE_SIZE); |
1452 | if (!gpage) { |
1453 | dev_err(geth->dev, "could not find mapping\n" ); |
1454 | continue; |
1455 | } |
1456 | page = gpage->page; |
1457 | |
1458 | if (word3.bits32 & SOF_BIT) { |
1459 | if (skb) { |
1460 | napi_free_frags(napi: &port->napi); |
1461 | port->stats.rx_dropped++; |
1462 | } |
1463 | |
1464 | skb = gmac_skb_if_good_frame(port, word0, frame_len); |
1465 | if (!skb) |
1466 | goto err_drop; |
1467 | |
1468 | page_offs += NET_IP_ALIGN; |
1469 | frag_len -= NET_IP_ALIGN; |
1470 | frag_nr = 0; |
1471 | |
1472 | } else if (!skb) { |
1473 | put_page(page); |
1474 | continue; |
1475 | } |
1476 | |
1477 | if (word3.bits32 & EOF_BIT) |
1478 | frag_len = frame_len - skb->len; |
1479 | |
1480 | /* append page frag to skb */ |
1481 | if (frag_nr == MAX_SKB_FRAGS) |
1482 | goto err_drop; |
1483 | |
1484 | if (frag_len == 0) |
1485 | netdev_err(dev: netdev, format: "Received fragment with len = 0\n" ); |
1486 | |
1487 | skb_fill_page_desc(skb, i: frag_nr, page, off: page_offs, size: frag_len); |
1488 | skb->len += frag_len; |
1489 | skb->data_len += frag_len; |
1490 | skb->truesize += frag_len; |
1491 | frag_nr++; |
1492 | |
1493 | if (word3.bits32 & EOF_BIT) { |
1494 | napi_gro_frags(napi: &port->napi); |
1495 | skb = NULL; |
1496 | --budget; |
1497 | } |
1498 | continue; |
1499 | |
1500 | err_drop: |
1501 | if (skb) { |
1502 | napi_free_frags(napi: &port->napi); |
1503 | skb = NULL; |
1504 | } |
1505 | |
1506 | if (mapping) |
1507 | put_page(page); |
1508 | |
1509 | port->stats.rx_dropped++; |
1510 | } |
1511 | |
1512 | writew(val: r, addr: ptr_reg); |
1513 | return budget; |
1514 | } |
1515 | |
1516 | static int gmac_napi_poll(struct napi_struct *napi, int budget) |
1517 | { |
1518 | struct gemini_ethernet_port *port = netdev_priv(dev: napi->dev); |
1519 | struct gemini_ethernet *geth = port->geth; |
1520 | unsigned int freeq_threshold; |
1521 | unsigned int received; |
1522 | |
1523 | freeq_threshold = 1 << (geth->freeq_order - 1); |
1524 | u64_stats_update_begin(syncp: &port->rx_stats_syncp); |
1525 | |
1526 | received = gmac_rx(netdev: napi->dev, budget); |
1527 | if (received < budget) { |
1528 | napi_gro_flush(napi, flush_old: false); |
1529 | napi_complete_done(n: napi, work_done: received); |
1530 | gmac_enable_rx_irq(netdev: napi->dev, enable: 1); |
1531 | ++port->rx_napi_exits; |
1532 | } |
1533 | |
1534 | port->freeq_refill += (budget - received); |
1535 | if (port->freeq_refill > freeq_threshold) { |
1536 | port->freeq_refill -= freeq_threshold; |
1537 | geth_fill_freeq(geth, refill: true); |
1538 | } |
1539 | |
1540 | u64_stats_update_end(syncp: &port->rx_stats_syncp); |
1541 | return received; |
1542 | } |
1543 | |
1544 | static void gmac_dump_dma_state(struct net_device *netdev) |
1545 | { |
1546 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1547 | struct gemini_ethernet *geth = port->geth; |
1548 | void __iomem *ptr_reg; |
1549 | u32 reg[5]; |
1550 | |
1551 | /* Interrupt status */ |
1552 | reg[0] = readl(addr: geth->base + GLOBAL_INTERRUPT_STATUS_0_REG); |
1553 | reg[1] = readl(addr: geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); |
1554 | reg[2] = readl(addr: geth->base + GLOBAL_INTERRUPT_STATUS_2_REG); |
1555 | reg[3] = readl(addr: geth->base + GLOBAL_INTERRUPT_STATUS_3_REG); |
1556 | reg[4] = readl(addr: geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); |
1557 | netdev_err(dev: netdev, format: "IRQ status: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n" , |
1558 | reg[0], reg[1], reg[2], reg[3], reg[4]); |
1559 | |
1560 | /* Interrupt enable */ |
1561 | reg[0] = readl(addr: geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); |
1562 | reg[1] = readl(addr: geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); |
1563 | reg[2] = readl(addr: geth->base + GLOBAL_INTERRUPT_ENABLE_2_REG); |
1564 | reg[3] = readl(addr: geth->base + GLOBAL_INTERRUPT_ENABLE_3_REG); |
1565 | reg[4] = readl(addr: geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); |
1566 | netdev_err(dev: netdev, format: "IRQ enable: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n" , |
1567 | reg[0], reg[1], reg[2], reg[3], reg[4]); |
1568 | |
1569 | /* RX DMA status */ |
1570 | reg[0] = readl(addr: port->dma_base + GMAC_DMA_RX_FIRST_DESC_REG); |
1571 | reg[1] = readl(addr: port->dma_base + GMAC_DMA_RX_CURR_DESC_REG); |
1572 | reg[2] = GET_RPTR(port->rxq_rwptr); |
1573 | reg[3] = GET_WPTR(port->rxq_rwptr); |
1574 | netdev_err(dev: netdev, format: "RX DMA regs: 0x%08x 0x%08x, ptr: %u %u\n" , |
1575 | reg[0], reg[1], reg[2], reg[3]); |
1576 | |
1577 | reg[0] = readl(addr: port->dma_base + GMAC_DMA_RX_DESC_WORD0_REG); |
1578 | reg[1] = readl(addr: port->dma_base + GMAC_DMA_RX_DESC_WORD1_REG); |
1579 | reg[2] = readl(addr: port->dma_base + GMAC_DMA_RX_DESC_WORD2_REG); |
1580 | reg[3] = readl(addr: port->dma_base + GMAC_DMA_RX_DESC_WORD3_REG); |
1581 | netdev_err(dev: netdev, format: "RX DMA descriptor: 0x%08x 0x%08x 0x%08x 0x%08x\n" , |
1582 | reg[0], reg[1], reg[2], reg[3]); |
1583 | |
1584 | /* TX DMA status */ |
1585 | ptr_reg = port->dma_base + GMAC_SW_TX_QUEUE0_PTR_REG; |
1586 | |
1587 | reg[0] = readl(addr: port->dma_base + GMAC_DMA_TX_FIRST_DESC_REG); |
1588 | reg[1] = readl(addr: port->dma_base + GMAC_DMA_TX_CURR_DESC_REG); |
1589 | reg[2] = GET_RPTR(ptr_reg); |
1590 | reg[3] = GET_WPTR(ptr_reg); |
1591 | netdev_err(dev: netdev, format: "TX DMA regs: 0x%08x 0x%08x, ptr: %u %u\n" , |
1592 | reg[0], reg[1], reg[2], reg[3]); |
1593 | |
1594 | reg[0] = readl(addr: port->dma_base + GMAC_DMA_TX_DESC_WORD0_REG); |
1595 | reg[1] = readl(addr: port->dma_base + GMAC_DMA_TX_DESC_WORD1_REG); |
1596 | reg[2] = readl(addr: port->dma_base + GMAC_DMA_TX_DESC_WORD2_REG); |
1597 | reg[3] = readl(addr: port->dma_base + GMAC_DMA_TX_DESC_WORD3_REG); |
1598 | netdev_err(dev: netdev, format: "TX DMA descriptor: 0x%08x 0x%08x 0x%08x 0x%08x\n" , |
1599 | reg[0], reg[1], reg[2], reg[3]); |
1600 | |
1601 | /* FREE queues status */ |
1602 | ptr_reg = geth->base + GLOBAL_SWFQ_RWPTR_REG; |
1603 | |
1604 | reg[0] = GET_RPTR(ptr_reg); |
1605 | reg[1] = GET_WPTR(ptr_reg); |
1606 | |
1607 | ptr_reg = geth->base + GLOBAL_HWFQ_RWPTR_REG; |
1608 | |
1609 | reg[2] = GET_RPTR(ptr_reg); |
1610 | reg[3] = GET_WPTR(ptr_reg); |
1611 | netdev_err(dev: netdev, format: "FQ SW ptr: %u %u, HW ptr: %u %u\n" , |
1612 | reg[0], reg[1], reg[2], reg[3]); |
1613 | } |
1614 | |
1615 | static void gmac_update_hw_stats(struct net_device *netdev) |
1616 | { |
1617 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1618 | unsigned int rx_discards, rx_mcast, rx_bcast; |
1619 | struct gemini_ethernet *geth = port->geth; |
1620 | unsigned long flags; |
1621 | |
1622 | spin_lock_irqsave(&geth->irq_lock, flags); |
1623 | u64_stats_update_begin(syncp: &port->ir_stats_syncp); |
1624 | |
1625 | rx_discards = readl(addr: port->gmac_base + GMAC_IN_DISCARDS); |
1626 | port->hw_stats[0] += rx_discards; |
1627 | port->hw_stats[1] += readl(addr: port->gmac_base + GMAC_IN_ERRORS); |
1628 | rx_mcast = readl(addr: port->gmac_base + GMAC_IN_MCAST); |
1629 | port->hw_stats[2] += rx_mcast; |
1630 | rx_bcast = readl(addr: port->gmac_base + GMAC_IN_BCAST); |
1631 | port->hw_stats[3] += rx_bcast; |
1632 | port->hw_stats[4] += readl(addr: port->gmac_base + GMAC_IN_MAC1); |
1633 | port->hw_stats[5] += readl(addr: port->gmac_base + GMAC_IN_MAC2); |
1634 | |
1635 | port->stats.rx_missed_errors += rx_discards; |
1636 | port->stats.multicast += rx_mcast; |
1637 | port->stats.multicast += rx_bcast; |
1638 | |
1639 | writel(GMAC0_MIB_INT_BIT << (netdev->dev_id * 8), |
1640 | addr: geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); |
1641 | |
1642 | u64_stats_update_end(syncp: &port->ir_stats_syncp); |
1643 | spin_unlock_irqrestore(lock: &geth->irq_lock, flags); |
1644 | } |
1645 | |
1646 | /** |
1647 | * gmac_get_intr_flags() - get interrupt status flags for a port from |
1648 | * @netdev: the net device for the port to get flags from |
1649 | * @i: the interrupt status register 0..4 |
1650 | */ |
1651 | static u32 gmac_get_intr_flags(struct net_device *netdev, int i) |
1652 | { |
1653 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1654 | struct gemini_ethernet *geth = port->geth; |
1655 | void __iomem *irqif_reg, *irqen_reg; |
1656 | unsigned int offs, val; |
1657 | |
1658 | /* Calculate the offset using the stride of the status registers */ |
1659 | offs = i * (GLOBAL_INTERRUPT_STATUS_1_REG - |
1660 | GLOBAL_INTERRUPT_STATUS_0_REG); |
1661 | |
1662 | irqif_reg = geth->base + GLOBAL_INTERRUPT_STATUS_0_REG + offs; |
1663 | irqen_reg = geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG + offs; |
1664 | |
1665 | val = readl(addr: irqif_reg) & readl(addr: irqen_reg); |
1666 | return val; |
1667 | } |
1668 | |
1669 | static enum hrtimer_restart gmac_coalesce_delay_expired(struct hrtimer *timer) |
1670 | { |
1671 | struct gemini_ethernet_port *port = |
1672 | container_of(timer, struct gemini_ethernet_port, |
1673 | rx_coalesce_timer); |
1674 | |
1675 | napi_schedule(n: &port->napi); |
1676 | return HRTIMER_NORESTART; |
1677 | } |
1678 | |
1679 | static irqreturn_t gmac_irq(int irq, void *data) |
1680 | { |
1681 | struct gemini_ethernet_port *port; |
1682 | struct net_device *netdev = data; |
1683 | struct gemini_ethernet *geth; |
1684 | u32 val, orr = 0; |
1685 | |
1686 | port = netdev_priv(dev: netdev); |
1687 | geth = port->geth; |
1688 | |
1689 | val = gmac_get_intr_flags(netdev, i: 0); |
1690 | orr |= val; |
1691 | |
1692 | if (val & (GMAC0_IRQ0_2 << (netdev->dev_id * 2))) { |
1693 | /* Oh, crap */ |
1694 | netdev_err(dev: netdev, format: "hw failure/sw bug\n" ); |
1695 | gmac_dump_dma_state(netdev); |
1696 | |
1697 | /* don't know how to recover, just reduce losses */ |
1698 | gmac_enable_irq(netdev, enable: 0); |
1699 | return IRQ_HANDLED; |
1700 | } |
1701 | |
1702 | if (val & (GMAC0_IRQ0_TXQ0_INTS << (netdev->dev_id * 6))) |
1703 | gmac_tx_irq(netdev, txq_num: 0); |
1704 | |
1705 | val = gmac_get_intr_flags(netdev, i: 1); |
1706 | orr |= val; |
1707 | |
1708 | if (val & (DEFAULT_Q0_INT_BIT << netdev->dev_id)) { |
1709 | gmac_enable_rx_irq(netdev, enable: 0); |
1710 | |
1711 | if (!port->rx_coalesce_nsecs) { |
1712 | napi_schedule(n: &port->napi); |
1713 | } else { |
1714 | ktime_t ktime; |
1715 | |
1716 | ktime = ktime_set(secs: 0, nsecs: port->rx_coalesce_nsecs); |
1717 | hrtimer_start(timer: &port->rx_coalesce_timer, tim: ktime, |
1718 | mode: HRTIMER_MODE_REL); |
1719 | } |
1720 | } |
1721 | |
1722 | val = gmac_get_intr_flags(netdev, i: 4); |
1723 | orr |= val; |
1724 | |
1725 | if (val & (GMAC0_MIB_INT_BIT << (netdev->dev_id * 8))) |
1726 | gmac_update_hw_stats(netdev); |
1727 | |
1728 | if (val & (GMAC0_RX_OVERRUN_INT_BIT << (netdev->dev_id * 8))) { |
1729 | writel(GMAC0_RXDERR_INT_BIT << (netdev->dev_id * 8), |
1730 | addr: geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); |
1731 | |
1732 | spin_lock(lock: &geth->irq_lock); |
1733 | u64_stats_update_begin(syncp: &port->ir_stats_syncp); |
1734 | ++port->stats.rx_fifo_errors; |
1735 | u64_stats_update_end(syncp: &port->ir_stats_syncp); |
1736 | spin_unlock(lock: &geth->irq_lock); |
1737 | } |
1738 | |
1739 | return orr ? IRQ_HANDLED : IRQ_NONE; |
1740 | } |
1741 | |
1742 | static void gmac_start_dma(struct gemini_ethernet_port *port) |
1743 | { |
1744 | void __iomem *dma_ctrl_reg = port->dma_base + GMAC_DMA_CTRL_REG; |
1745 | union gmac_dma_ctrl dma_ctrl; |
1746 | |
1747 | dma_ctrl.bits32 = readl(addr: dma_ctrl_reg); |
1748 | dma_ctrl.bits.rd_enable = 1; |
1749 | dma_ctrl.bits.td_enable = 1; |
1750 | dma_ctrl.bits.loopback = 0; |
1751 | dma_ctrl.bits.drop_small_ack = 0; |
1752 | dma_ctrl.bits.rd_insert_bytes = NET_IP_ALIGN; |
1753 | dma_ctrl.bits.rd_prot = HPROT_DATA_CACHE | HPROT_PRIVILIGED; |
1754 | dma_ctrl.bits.rd_burst_size = HBURST_INCR8; |
1755 | dma_ctrl.bits.rd_bus = HSIZE_8; |
1756 | dma_ctrl.bits.td_prot = HPROT_DATA_CACHE; |
1757 | dma_ctrl.bits.td_burst_size = HBURST_INCR8; |
1758 | dma_ctrl.bits.td_bus = HSIZE_8; |
1759 | |
1760 | writel(val: dma_ctrl.bits32, addr: dma_ctrl_reg); |
1761 | } |
1762 | |
1763 | static void gmac_stop_dma(struct gemini_ethernet_port *port) |
1764 | { |
1765 | void __iomem *dma_ctrl_reg = port->dma_base + GMAC_DMA_CTRL_REG; |
1766 | union gmac_dma_ctrl dma_ctrl; |
1767 | |
1768 | dma_ctrl.bits32 = readl(addr: dma_ctrl_reg); |
1769 | dma_ctrl.bits.rd_enable = 0; |
1770 | dma_ctrl.bits.td_enable = 0; |
1771 | writel(val: dma_ctrl.bits32, addr: dma_ctrl_reg); |
1772 | } |
1773 | |
1774 | static int gmac_open(struct net_device *netdev) |
1775 | { |
1776 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1777 | int err; |
1778 | |
1779 | err = request_irq(irq: netdev->irq, handler: gmac_irq, |
1780 | IRQF_SHARED, name: netdev->name, dev: netdev); |
1781 | if (err) { |
1782 | netdev_err(dev: netdev, format: "no IRQ\n" ); |
1783 | return err; |
1784 | } |
1785 | |
1786 | netif_carrier_off(dev: netdev); |
1787 | phy_start(phydev: netdev->phydev); |
1788 | |
1789 | err = geth_resize_freeq(port); |
1790 | /* It's fine if it's just busy, the other port has set up |
1791 | * the freeq in that case. |
1792 | */ |
1793 | if (err && (err != -EBUSY)) { |
1794 | netdev_err(dev: netdev, format: "could not resize freeq\n" ); |
1795 | goto err_stop_phy; |
1796 | } |
1797 | |
1798 | err = gmac_setup_rxq(netdev); |
1799 | if (err) { |
1800 | netdev_err(dev: netdev, format: "could not setup RXQ\n" ); |
1801 | goto err_stop_phy; |
1802 | } |
1803 | |
1804 | err = gmac_setup_txqs(netdev); |
1805 | if (err) { |
1806 | netdev_err(dev: netdev, format: "could not setup TXQs\n" ); |
1807 | gmac_cleanup_rxq(netdev); |
1808 | goto err_stop_phy; |
1809 | } |
1810 | |
1811 | napi_enable(n: &port->napi); |
1812 | |
1813 | gmac_start_dma(port); |
1814 | gmac_enable_irq(netdev, enable: 1); |
1815 | gmac_enable_tx_rx(netdev); |
1816 | netif_tx_start_all_queues(dev: netdev); |
1817 | |
1818 | hrtimer_init(timer: &port->rx_coalesce_timer, CLOCK_MONOTONIC, |
1819 | mode: HRTIMER_MODE_REL); |
1820 | port->rx_coalesce_timer.function = &gmac_coalesce_delay_expired; |
1821 | |
1822 | netdev_dbg(netdev, "opened\n" ); |
1823 | |
1824 | return 0; |
1825 | |
1826 | err_stop_phy: |
1827 | phy_stop(phydev: netdev->phydev); |
1828 | free_irq(netdev->irq, netdev); |
1829 | return err; |
1830 | } |
1831 | |
1832 | static int gmac_stop(struct net_device *netdev) |
1833 | { |
1834 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1835 | |
1836 | hrtimer_cancel(timer: &port->rx_coalesce_timer); |
1837 | netif_tx_stop_all_queues(dev: netdev); |
1838 | gmac_disable_tx_rx(netdev); |
1839 | gmac_stop_dma(port); |
1840 | napi_disable(n: &port->napi); |
1841 | |
1842 | gmac_enable_irq(netdev, enable: 0); |
1843 | gmac_cleanup_rxq(netdev); |
1844 | gmac_cleanup_txqs(netdev); |
1845 | |
1846 | phy_stop(phydev: netdev->phydev); |
1847 | free_irq(netdev->irq, netdev); |
1848 | |
1849 | gmac_update_hw_stats(netdev); |
1850 | return 0; |
1851 | } |
1852 | |
1853 | static void gmac_set_rx_mode(struct net_device *netdev) |
1854 | { |
1855 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1856 | union gmac_rx_fltr filter = { .bits = { |
1857 | .broadcast = 1, |
1858 | .multicast = 1, |
1859 | .unicast = 1, |
1860 | } }; |
1861 | struct netdev_hw_addr *ha; |
1862 | unsigned int bit_nr; |
1863 | u32 mc_filter[2]; |
1864 | |
1865 | mc_filter[1] = 0; |
1866 | mc_filter[0] = 0; |
1867 | |
1868 | if (netdev->flags & IFF_PROMISC) { |
1869 | filter.bits.error = 1; |
1870 | filter.bits.promiscuous = 1; |
1871 | mc_filter[1] = ~0; |
1872 | mc_filter[0] = ~0; |
1873 | } else if (netdev->flags & IFF_ALLMULTI) { |
1874 | mc_filter[1] = ~0; |
1875 | mc_filter[0] = ~0; |
1876 | } else { |
1877 | netdev_for_each_mc_addr(ha, netdev) { |
1878 | bit_nr = ~crc32_le(crc: ~0, p: ha->addr, ETH_ALEN) & 0x3f; |
1879 | mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 0x1f); |
1880 | } |
1881 | } |
1882 | |
1883 | writel(val: mc_filter[0], addr: port->gmac_base + GMAC_MCAST_FIL0); |
1884 | writel(val: mc_filter[1], addr: port->gmac_base + GMAC_MCAST_FIL1); |
1885 | writel(val: filter.bits32, addr: port->gmac_base + GMAC_RX_FLTR); |
1886 | } |
1887 | |
1888 | static void gmac_write_mac_address(struct net_device *netdev) |
1889 | { |
1890 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1891 | __le32 addr[3]; |
1892 | |
1893 | memset(addr, 0, sizeof(addr)); |
1894 | memcpy(addr, netdev->dev_addr, ETH_ALEN); |
1895 | |
1896 | writel(le32_to_cpu(addr[0]), addr: port->gmac_base + GMAC_STA_ADD0); |
1897 | writel(le32_to_cpu(addr[1]), addr: port->gmac_base + GMAC_STA_ADD1); |
1898 | writel(le32_to_cpu(addr[2]), addr: port->gmac_base + GMAC_STA_ADD2); |
1899 | } |
1900 | |
1901 | static int gmac_set_mac_address(struct net_device *netdev, void *addr) |
1902 | { |
1903 | struct sockaddr *sa = addr; |
1904 | |
1905 | eth_hw_addr_set(dev: netdev, addr: sa->sa_data); |
1906 | gmac_write_mac_address(netdev); |
1907 | |
1908 | return 0; |
1909 | } |
1910 | |
1911 | static void gmac_clear_hw_stats(struct net_device *netdev) |
1912 | { |
1913 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1914 | |
1915 | readl(addr: port->gmac_base + GMAC_IN_DISCARDS); |
1916 | readl(addr: port->gmac_base + GMAC_IN_ERRORS); |
1917 | readl(addr: port->gmac_base + GMAC_IN_MCAST); |
1918 | readl(addr: port->gmac_base + GMAC_IN_BCAST); |
1919 | readl(addr: port->gmac_base + GMAC_IN_MAC1); |
1920 | readl(addr: port->gmac_base + GMAC_IN_MAC2); |
1921 | } |
1922 | |
1923 | static void gmac_get_stats64(struct net_device *netdev, |
1924 | struct rtnl_link_stats64 *stats) |
1925 | { |
1926 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1927 | unsigned int start; |
1928 | |
1929 | gmac_update_hw_stats(netdev); |
1930 | |
1931 | /* Racing with RX NAPI */ |
1932 | do { |
1933 | start = u64_stats_fetch_begin(syncp: &port->rx_stats_syncp); |
1934 | |
1935 | stats->rx_packets = port->stats.rx_packets; |
1936 | stats->rx_bytes = port->stats.rx_bytes; |
1937 | stats->rx_errors = port->stats.rx_errors; |
1938 | stats->rx_dropped = port->stats.rx_dropped; |
1939 | |
1940 | stats->rx_length_errors = port->stats.rx_length_errors; |
1941 | stats->rx_over_errors = port->stats.rx_over_errors; |
1942 | stats->rx_crc_errors = port->stats.rx_crc_errors; |
1943 | stats->rx_frame_errors = port->stats.rx_frame_errors; |
1944 | |
1945 | } while (u64_stats_fetch_retry(syncp: &port->rx_stats_syncp, start)); |
1946 | |
1947 | /* Racing with MIB and TX completion interrupts */ |
1948 | do { |
1949 | start = u64_stats_fetch_begin(syncp: &port->ir_stats_syncp); |
1950 | |
1951 | stats->tx_errors = port->stats.tx_errors; |
1952 | stats->tx_packets = port->stats.tx_packets; |
1953 | stats->tx_bytes = port->stats.tx_bytes; |
1954 | |
1955 | stats->multicast = port->stats.multicast; |
1956 | stats->rx_missed_errors = port->stats.rx_missed_errors; |
1957 | stats->rx_fifo_errors = port->stats.rx_fifo_errors; |
1958 | |
1959 | } while (u64_stats_fetch_retry(syncp: &port->ir_stats_syncp, start)); |
1960 | |
1961 | /* Racing with hard_start_xmit */ |
1962 | do { |
1963 | start = u64_stats_fetch_begin(syncp: &port->tx_stats_syncp); |
1964 | |
1965 | stats->tx_dropped = port->stats.tx_dropped; |
1966 | |
1967 | } while (u64_stats_fetch_retry(syncp: &port->tx_stats_syncp, start)); |
1968 | |
1969 | stats->rx_dropped += stats->rx_missed_errors; |
1970 | } |
1971 | |
1972 | static int gmac_change_mtu(struct net_device *netdev, int new_mtu) |
1973 | { |
1974 | int max_len = gmac_pick_rx_max_len(max_l3_len: new_mtu); |
1975 | |
1976 | if (max_len < 0) |
1977 | return -EINVAL; |
1978 | |
1979 | gmac_disable_tx_rx(netdev); |
1980 | |
1981 | netdev->mtu = new_mtu; |
1982 | gmac_update_config0_reg(netdev, val: max_len << CONFIG0_MAXLEN_SHIFT, |
1983 | CONFIG0_MAXLEN_MASK); |
1984 | |
1985 | netdev_update_features(dev: netdev); |
1986 | |
1987 | gmac_enable_tx_rx(netdev); |
1988 | |
1989 | return 0; |
1990 | } |
1991 | |
1992 | static int gmac_set_features(struct net_device *netdev, |
1993 | netdev_features_t features) |
1994 | { |
1995 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
1996 | int enable = features & NETIF_F_RXCSUM; |
1997 | unsigned long flags; |
1998 | u32 reg; |
1999 | |
2000 | spin_lock_irqsave(&port->config_lock, flags); |
2001 | |
2002 | reg = readl(addr: port->gmac_base + GMAC_CONFIG0); |
2003 | reg = enable ? reg | CONFIG0_RX_CHKSUM : reg & ~CONFIG0_RX_CHKSUM; |
2004 | writel(val: reg, addr: port->gmac_base + GMAC_CONFIG0); |
2005 | |
2006 | spin_unlock_irqrestore(lock: &port->config_lock, flags); |
2007 | return 0; |
2008 | } |
2009 | |
2010 | static int gmac_get_sset_count(struct net_device *netdev, int sset) |
2011 | { |
2012 | return sset == ETH_SS_STATS ? GMAC_STATS_NUM : 0; |
2013 | } |
2014 | |
2015 | static void gmac_get_strings(struct net_device *netdev, u32 stringset, u8 *data) |
2016 | { |
2017 | if (stringset != ETH_SS_STATS) |
2018 | return; |
2019 | |
2020 | memcpy(data, gmac_stats_strings, sizeof(gmac_stats_strings)); |
2021 | } |
2022 | |
2023 | static void gmac_get_ethtool_stats(struct net_device *netdev, |
2024 | struct ethtool_stats *estats, u64 *values) |
2025 | { |
2026 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
2027 | unsigned int start; |
2028 | u64 *p; |
2029 | int i; |
2030 | |
2031 | gmac_update_hw_stats(netdev); |
2032 | |
2033 | /* Racing with MIB interrupt */ |
2034 | do { |
2035 | p = values; |
2036 | start = u64_stats_fetch_begin(syncp: &port->ir_stats_syncp); |
2037 | |
2038 | for (i = 0; i < RX_STATS_NUM; i++) |
2039 | *p++ = port->hw_stats[i]; |
2040 | |
2041 | } while (u64_stats_fetch_retry(syncp: &port->ir_stats_syncp, start)); |
2042 | values = p; |
2043 | |
2044 | /* Racing with RX NAPI */ |
2045 | do { |
2046 | p = values; |
2047 | start = u64_stats_fetch_begin(syncp: &port->rx_stats_syncp); |
2048 | |
2049 | for (i = 0; i < RX_STATUS_NUM; i++) |
2050 | *p++ = port->rx_stats[i]; |
2051 | for (i = 0; i < RX_CHKSUM_NUM; i++) |
2052 | *p++ = port->rx_csum_stats[i]; |
2053 | *p++ = port->rx_napi_exits; |
2054 | |
2055 | } while (u64_stats_fetch_retry(syncp: &port->rx_stats_syncp, start)); |
2056 | values = p; |
2057 | |
2058 | /* Racing with TX start_xmit */ |
2059 | do { |
2060 | p = values; |
2061 | start = u64_stats_fetch_begin(syncp: &port->tx_stats_syncp); |
2062 | |
2063 | for (i = 0; i < TX_MAX_FRAGS; i++) { |
2064 | *values++ = port->tx_frag_stats[i]; |
2065 | port->tx_frag_stats[i] = 0; |
2066 | } |
2067 | *values++ = port->tx_frags_linearized; |
2068 | *values++ = port->tx_hw_csummed; |
2069 | |
2070 | } while (u64_stats_fetch_retry(syncp: &port->tx_stats_syncp, start)); |
2071 | } |
2072 | |
2073 | static int gmac_get_ksettings(struct net_device *netdev, |
2074 | struct ethtool_link_ksettings *cmd) |
2075 | { |
2076 | if (!netdev->phydev) |
2077 | return -ENXIO; |
2078 | phy_ethtool_ksettings_get(phydev: netdev->phydev, cmd); |
2079 | |
2080 | return 0; |
2081 | } |
2082 | |
2083 | static int gmac_set_ksettings(struct net_device *netdev, |
2084 | const struct ethtool_link_ksettings *cmd) |
2085 | { |
2086 | if (!netdev->phydev) |
2087 | return -ENXIO; |
2088 | return phy_ethtool_ksettings_set(phydev: netdev->phydev, cmd); |
2089 | } |
2090 | |
2091 | static int gmac_nway_reset(struct net_device *netdev) |
2092 | { |
2093 | if (!netdev->phydev) |
2094 | return -ENXIO; |
2095 | return phy_start_aneg(phydev: netdev->phydev); |
2096 | } |
2097 | |
2098 | static void gmac_get_pauseparam(struct net_device *netdev, |
2099 | struct ethtool_pauseparam *pparam) |
2100 | { |
2101 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
2102 | union gmac_config0 config0; |
2103 | |
2104 | config0.bits32 = readl(addr: port->gmac_base + GMAC_CONFIG0); |
2105 | |
2106 | pparam->rx_pause = config0.bits.rx_fc_en; |
2107 | pparam->tx_pause = config0.bits.tx_fc_en; |
2108 | pparam->autoneg = true; |
2109 | } |
2110 | |
2111 | static void gmac_get_ringparam(struct net_device *netdev, |
2112 | struct ethtool_ringparam *rp, |
2113 | struct kernel_ethtool_ringparam *kernel_rp, |
2114 | struct netlink_ext_ack *extack) |
2115 | { |
2116 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
2117 | |
2118 | readl(addr: port->gmac_base + GMAC_CONFIG0); |
2119 | |
2120 | rp->rx_max_pending = 1 << 15; |
2121 | rp->rx_mini_max_pending = 0; |
2122 | rp->rx_jumbo_max_pending = 0; |
2123 | rp->tx_max_pending = 1 << 15; |
2124 | |
2125 | rp->rx_pending = 1 << port->rxq_order; |
2126 | rp->rx_mini_pending = 0; |
2127 | rp->rx_jumbo_pending = 0; |
2128 | rp->tx_pending = 1 << port->txq_order; |
2129 | } |
2130 | |
2131 | static int gmac_set_ringparam(struct net_device *netdev, |
2132 | struct ethtool_ringparam *rp, |
2133 | struct kernel_ethtool_ringparam *kernel_rp, |
2134 | struct netlink_ext_ack *extack) |
2135 | { |
2136 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
2137 | int err = 0; |
2138 | |
2139 | if (netif_running(dev: netdev)) |
2140 | return -EBUSY; |
2141 | |
2142 | if (rp->rx_pending) { |
2143 | port->rxq_order = min(15, ilog2(rp->rx_pending - 1) + 1); |
2144 | err = geth_resize_freeq(port); |
2145 | } |
2146 | if (rp->tx_pending) { |
2147 | port->txq_order = min(15, ilog2(rp->tx_pending - 1) + 1); |
2148 | port->irq_every_tx_packets = 1 << (port->txq_order - 2); |
2149 | } |
2150 | |
2151 | return err; |
2152 | } |
2153 | |
2154 | static int gmac_get_coalesce(struct net_device *netdev, |
2155 | struct ethtool_coalesce *ecmd, |
2156 | struct kernel_ethtool_coalesce *kernel_coal, |
2157 | struct netlink_ext_ack *extack) |
2158 | { |
2159 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
2160 | |
2161 | ecmd->rx_max_coalesced_frames = 1; |
2162 | ecmd->tx_max_coalesced_frames = port->irq_every_tx_packets; |
2163 | ecmd->rx_coalesce_usecs = port->rx_coalesce_nsecs / 1000; |
2164 | |
2165 | return 0; |
2166 | } |
2167 | |
2168 | static int gmac_set_coalesce(struct net_device *netdev, |
2169 | struct ethtool_coalesce *ecmd, |
2170 | struct kernel_ethtool_coalesce *kernel_coal, |
2171 | struct netlink_ext_ack *extack) |
2172 | { |
2173 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
2174 | |
2175 | if (ecmd->tx_max_coalesced_frames < 1) |
2176 | return -EINVAL; |
2177 | if (ecmd->tx_max_coalesced_frames >= 1 << port->txq_order) |
2178 | return -EINVAL; |
2179 | |
2180 | port->irq_every_tx_packets = ecmd->tx_max_coalesced_frames; |
2181 | port->rx_coalesce_nsecs = ecmd->rx_coalesce_usecs * 1000; |
2182 | |
2183 | return 0; |
2184 | } |
2185 | |
2186 | static u32 gmac_get_msglevel(struct net_device *netdev) |
2187 | { |
2188 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
2189 | |
2190 | return port->msg_enable; |
2191 | } |
2192 | |
2193 | static void gmac_set_msglevel(struct net_device *netdev, u32 level) |
2194 | { |
2195 | struct gemini_ethernet_port *port = netdev_priv(dev: netdev); |
2196 | |
2197 | port->msg_enable = level; |
2198 | } |
2199 | |
2200 | static void gmac_get_drvinfo(struct net_device *netdev, |
2201 | struct ethtool_drvinfo *info) |
2202 | { |
2203 | strcpy(p: info->driver, DRV_NAME); |
2204 | strcpy(p: info->bus_info, q: netdev->dev_id ? "1" : "0" ); |
2205 | } |
2206 | |
2207 | static const struct net_device_ops gmac_351x_ops = { |
2208 | .ndo_init = gmac_init, |
2209 | .ndo_open = gmac_open, |
2210 | .ndo_stop = gmac_stop, |
2211 | .ndo_start_xmit = gmac_start_xmit, |
2212 | .ndo_tx_timeout = gmac_tx_timeout, |
2213 | .ndo_set_rx_mode = gmac_set_rx_mode, |
2214 | .ndo_set_mac_address = gmac_set_mac_address, |
2215 | .ndo_get_stats64 = gmac_get_stats64, |
2216 | .ndo_change_mtu = gmac_change_mtu, |
2217 | .ndo_set_features = gmac_set_features, |
2218 | }; |
2219 | |
2220 | static const struct ethtool_ops gmac_351x_ethtool_ops = { |
2221 | .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS | |
2222 | ETHTOOL_COALESCE_MAX_FRAMES, |
2223 | .get_sset_count = gmac_get_sset_count, |
2224 | .get_strings = gmac_get_strings, |
2225 | .get_ethtool_stats = gmac_get_ethtool_stats, |
2226 | .get_link = ethtool_op_get_link, |
2227 | .get_link_ksettings = gmac_get_ksettings, |
2228 | .set_link_ksettings = gmac_set_ksettings, |
2229 | .nway_reset = gmac_nway_reset, |
2230 | .get_pauseparam = gmac_get_pauseparam, |
2231 | .get_ringparam = gmac_get_ringparam, |
2232 | .set_ringparam = gmac_set_ringparam, |
2233 | .get_coalesce = gmac_get_coalesce, |
2234 | .set_coalesce = gmac_set_coalesce, |
2235 | .get_msglevel = gmac_get_msglevel, |
2236 | .set_msglevel = gmac_set_msglevel, |
2237 | .get_drvinfo = gmac_get_drvinfo, |
2238 | }; |
2239 | |
2240 | static irqreturn_t gemini_port_irq_thread(int irq, void *data) |
2241 | { |
2242 | unsigned long irqmask = SWFQ_EMPTY_INT_BIT; |
2243 | struct gemini_ethernet_port *port = data; |
2244 | struct gemini_ethernet *geth; |
2245 | unsigned long flags; |
2246 | |
2247 | geth = port->geth; |
2248 | /* The queue is half empty so refill it */ |
2249 | geth_fill_freeq(geth, refill: true); |
2250 | |
2251 | spin_lock_irqsave(&geth->irq_lock, flags); |
2252 | /* ACK queue interrupt */ |
2253 | writel(val: irqmask, addr: geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); |
2254 | /* Enable queue interrupt again */ |
2255 | irqmask |= readl(addr: geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); |
2256 | writel(val: irqmask, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); |
2257 | spin_unlock_irqrestore(lock: &geth->irq_lock, flags); |
2258 | |
2259 | return IRQ_HANDLED; |
2260 | } |
2261 | |
2262 | static irqreturn_t gemini_port_irq(int irq, void *data) |
2263 | { |
2264 | struct gemini_ethernet_port *port = data; |
2265 | struct gemini_ethernet *geth; |
2266 | irqreturn_t ret = IRQ_NONE; |
2267 | u32 val, en; |
2268 | |
2269 | geth = port->geth; |
2270 | spin_lock(lock: &geth->irq_lock); |
2271 | |
2272 | val = readl(addr: geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); |
2273 | en = readl(addr: geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); |
2274 | |
2275 | if (val & en & SWFQ_EMPTY_INT_BIT) { |
2276 | /* Disable the queue empty interrupt while we work on |
2277 | * processing the queue. Also disable overrun interrupts |
2278 | * as there is not much we can do about it here. |
2279 | */ |
2280 | en &= ~(SWFQ_EMPTY_INT_BIT | GMAC0_RX_OVERRUN_INT_BIT |
2281 | | GMAC1_RX_OVERRUN_INT_BIT); |
2282 | writel(val: en, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); |
2283 | ret = IRQ_WAKE_THREAD; |
2284 | } |
2285 | |
2286 | spin_unlock(lock: &geth->irq_lock); |
2287 | |
2288 | return ret; |
2289 | } |
2290 | |
2291 | static void gemini_port_remove(struct gemini_ethernet_port *port) |
2292 | { |
2293 | if (port->netdev) { |
2294 | phy_disconnect(phydev: port->netdev->phydev); |
2295 | unregister_netdev(dev: port->netdev); |
2296 | } |
2297 | clk_disable_unprepare(clk: port->pclk); |
2298 | geth_cleanup_freeq(geth: port->geth); |
2299 | } |
2300 | |
2301 | static void gemini_ethernet_init(struct gemini_ethernet *geth) |
2302 | { |
2303 | /* Only do this once both ports are online */ |
2304 | if (geth->initialized) |
2305 | return; |
2306 | if (geth->port0 && geth->port1) |
2307 | geth->initialized = true; |
2308 | else |
2309 | return; |
2310 | |
2311 | writel(val: 0, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); |
2312 | writel(val: 0, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); |
2313 | writel(val: 0, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_2_REG); |
2314 | writel(val: 0, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_3_REG); |
2315 | writel(val: 0, addr: geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); |
2316 | |
2317 | /* Interrupt config: |
2318 | * |
2319 | * GMAC0 intr bits ------> int0 ----> eth0 |
2320 | * GMAC1 intr bits ------> int1 ----> eth1 |
2321 | * TOE intr -------------> int1 ----> eth1 |
2322 | * Classification Intr --> int0 ----> eth0 |
2323 | * Default Q0 -----------> int0 ----> eth0 |
2324 | * Default Q1 -----------> int1 ----> eth1 |
2325 | * FreeQ intr -----------> int1 ----> eth1 |
2326 | */ |
2327 | writel(val: 0xCCFC0FC0, addr: geth->base + GLOBAL_INTERRUPT_SELECT_0_REG); |
2328 | writel(val: 0x00F00002, addr: geth->base + GLOBAL_INTERRUPT_SELECT_1_REG); |
2329 | writel(val: 0xFFFFFFFF, addr: geth->base + GLOBAL_INTERRUPT_SELECT_2_REG); |
2330 | writel(val: 0xFFFFFFFF, addr: geth->base + GLOBAL_INTERRUPT_SELECT_3_REG); |
2331 | writel(val: 0xFF000003, addr: geth->base + GLOBAL_INTERRUPT_SELECT_4_REG); |
2332 | |
2333 | /* edge-triggered interrupts packed to level-triggered one... */ |
2334 | writel(val: ~0, addr: geth->base + GLOBAL_INTERRUPT_STATUS_0_REG); |
2335 | writel(val: ~0, addr: geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); |
2336 | writel(val: ~0, addr: geth->base + GLOBAL_INTERRUPT_STATUS_2_REG); |
2337 | writel(val: ~0, addr: geth->base + GLOBAL_INTERRUPT_STATUS_3_REG); |
2338 | writel(val: ~0, addr: geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); |
2339 | |
2340 | /* Set up queue */ |
2341 | writel(val: 0, addr: geth->base + GLOBAL_SW_FREEQ_BASE_SIZE_REG); |
2342 | writel(val: 0, addr: geth->base + GLOBAL_HW_FREEQ_BASE_SIZE_REG); |
2343 | writel(val: 0, addr: geth->base + GLOBAL_SWFQ_RWPTR_REG); |
2344 | writel(val: 0, addr: geth->base + GLOBAL_HWFQ_RWPTR_REG); |
2345 | |
2346 | geth->freeq_frag_order = DEFAULT_RX_BUF_ORDER; |
2347 | /* This makes the queue resize on probe() so that we |
2348 | * set up and enable the queue IRQ. FIXME: fragile. |
2349 | */ |
2350 | geth->freeq_order = 1; |
2351 | } |
2352 | |
2353 | static void gemini_port_save_mac_addr(struct gemini_ethernet_port *port) |
2354 | { |
2355 | port->mac_addr[0] = |
2356 | cpu_to_le32(readl(port->gmac_base + GMAC_STA_ADD0)); |
2357 | port->mac_addr[1] = |
2358 | cpu_to_le32(readl(port->gmac_base + GMAC_STA_ADD1)); |
2359 | port->mac_addr[2] = |
2360 | cpu_to_le32(readl(port->gmac_base + GMAC_STA_ADD2)); |
2361 | } |
2362 | |
2363 | static int gemini_ethernet_port_probe(struct platform_device *pdev) |
2364 | { |
2365 | char *port_names[2] = { "ethernet0" , "ethernet1" }; |
2366 | struct device_node *np = pdev->dev.of_node; |
2367 | struct gemini_ethernet_port *port; |
2368 | struct device *dev = &pdev->dev; |
2369 | struct gemini_ethernet *geth; |
2370 | struct net_device *netdev; |
2371 | struct device *parent; |
2372 | u8 mac[ETH_ALEN]; |
2373 | unsigned int id; |
2374 | int irq; |
2375 | int ret; |
2376 | |
2377 | parent = dev->parent; |
2378 | geth = dev_get_drvdata(dev: parent); |
2379 | |
2380 | if (!strcmp(dev_name(dev), "60008000.ethernet-port" )) |
2381 | id = 0; |
2382 | else if (!strcmp(dev_name(dev), "6000c000.ethernet-port" )) |
2383 | id = 1; |
2384 | else |
2385 | return -ENODEV; |
2386 | |
2387 | dev_info(dev, "probe %s ID %d\n" , dev_name(dev), id); |
2388 | |
2389 | netdev = devm_alloc_etherdev_mqs(dev, sizeof_priv: sizeof(*port), TX_QUEUE_NUM, TX_QUEUE_NUM); |
2390 | if (!netdev) { |
2391 | dev_err(dev, "Can't allocate ethernet device #%d\n" , id); |
2392 | return -ENOMEM; |
2393 | } |
2394 | |
2395 | port = netdev_priv(dev: netdev); |
2396 | SET_NETDEV_DEV(netdev, dev); |
2397 | port->netdev = netdev; |
2398 | port->id = id; |
2399 | port->geth = geth; |
2400 | port->dev = dev; |
2401 | port->msg_enable = netif_msg_init(debug_value: debug, DEFAULT_MSG_ENABLE); |
2402 | |
2403 | /* DMA memory */ |
2404 | port->dma_base = devm_platform_get_and_ioremap_resource(pdev, index: 0, NULL); |
2405 | if (IS_ERR(ptr: port->dma_base)) { |
2406 | dev_err(dev, "get DMA address failed\n" ); |
2407 | return PTR_ERR(ptr: port->dma_base); |
2408 | } |
2409 | |
2410 | /* GMAC config memory */ |
2411 | port->gmac_base = devm_platform_get_and_ioremap_resource(pdev, index: 1, NULL); |
2412 | if (IS_ERR(ptr: port->gmac_base)) { |
2413 | dev_err(dev, "get GMAC address failed\n" ); |
2414 | return PTR_ERR(ptr: port->gmac_base); |
2415 | } |
2416 | |
2417 | /* Interrupt */ |
2418 | irq = platform_get_irq(pdev, 0); |
2419 | if (irq < 0) |
2420 | return irq; |
2421 | port->irq = irq; |
2422 | |
2423 | /* Clock the port */ |
2424 | port->pclk = devm_clk_get(dev, id: "PCLK" ); |
2425 | if (IS_ERR(ptr: port->pclk)) { |
2426 | dev_err(dev, "no PCLK\n" ); |
2427 | return PTR_ERR(ptr: port->pclk); |
2428 | } |
2429 | ret = clk_prepare_enable(clk: port->pclk); |
2430 | if (ret) |
2431 | return ret; |
2432 | |
2433 | /* Maybe there is a nice ethernet address we should use */ |
2434 | gemini_port_save_mac_addr(port); |
2435 | |
2436 | /* Reset the port */ |
2437 | port->reset = devm_reset_control_get_exclusive(dev, NULL); |
2438 | if (IS_ERR(ptr: port->reset)) { |
2439 | dev_err(dev, "no reset\n" ); |
2440 | ret = PTR_ERR(ptr: port->reset); |
2441 | goto unprepare; |
2442 | } |
2443 | reset_control_reset(rstc: port->reset); |
2444 | usleep_range(min: 100, max: 500); |
2445 | |
2446 | /* Assign pointer in the main state container */ |
2447 | if (!id) |
2448 | geth->port0 = port; |
2449 | else |
2450 | geth->port1 = port; |
2451 | |
2452 | /* This will just be done once both ports are up and reset */ |
2453 | gemini_ethernet_init(geth); |
2454 | |
2455 | platform_set_drvdata(pdev, data: port); |
2456 | |
2457 | /* Set up and register the netdev */ |
2458 | netdev->dev_id = port->id; |
2459 | netdev->irq = irq; |
2460 | netdev->netdev_ops = &gmac_351x_ops; |
2461 | netdev->ethtool_ops = &gmac_351x_ethtool_ops; |
2462 | |
2463 | spin_lock_init(&port->config_lock); |
2464 | gmac_clear_hw_stats(netdev); |
2465 | |
2466 | netdev->hw_features = GMAC_OFFLOAD_FEATURES; |
2467 | netdev->features |= GMAC_OFFLOAD_FEATURES | NETIF_F_GRO; |
2468 | /* We can receive jumbo frames up to 10236 bytes but only |
2469 | * transmit 2047 bytes so, let's accept payloads of 2047 |
2470 | * bytes minus VLAN and ethernet header |
2471 | */ |
2472 | netdev->min_mtu = ETH_MIN_MTU; |
2473 | netdev->max_mtu = MTU_SIZE_BIT_MASK - VLAN_ETH_HLEN; |
2474 | |
2475 | port->freeq_refill = 0; |
2476 | netif_napi_add(dev: netdev, napi: &port->napi, poll: gmac_napi_poll); |
2477 | |
2478 | ret = of_get_mac_address(np, mac); |
2479 | if (!ret) { |
2480 | dev_info(dev, "Setting macaddr from DT %pM\n" , mac); |
2481 | memcpy(port->mac_addr, mac, ETH_ALEN); |
2482 | } |
2483 | |
2484 | if (is_valid_ether_addr(addr: (void *)port->mac_addr)) { |
2485 | eth_hw_addr_set(dev: netdev, addr: (u8 *)port->mac_addr); |
2486 | } else { |
2487 | dev_dbg(dev, "ethernet address 0x%08x%08x%08x invalid\n" , |
2488 | port->mac_addr[0], port->mac_addr[1], |
2489 | port->mac_addr[2]); |
2490 | dev_info(dev, "using a random ethernet address\n" ); |
2491 | eth_hw_addr_random(dev: netdev); |
2492 | } |
2493 | gmac_write_mac_address(netdev); |
2494 | |
2495 | ret = devm_request_threaded_irq(dev: port->dev, |
2496 | irq: port->irq, |
2497 | handler: gemini_port_irq, |
2498 | thread_fn: gemini_port_irq_thread, |
2499 | IRQF_SHARED, |
2500 | devname: port_names[port->id], |
2501 | dev_id: port); |
2502 | if (ret) |
2503 | goto unprepare; |
2504 | |
2505 | ret = gmac_setup_phy(netdev); |
2506 | if (ret) { |
2507 | netdev_err(dev: netdev, |
2508 | format: "PHY init failed\n" ); |
2509 | goto unprepare; |
2510 | } |
2511 | |
2512 | ret = register_netdev(dev: netdev); |
2513 | if (ret) |
2514 | goto unprepare; |
2515 | |
2516 | return 0; |
2517 | |
2518 | unprepare: |
2519 | clk_disable_unprepare(clk: port->pclk); |
2520 | return ret; |
2521 | } |
2522 | |
2523 | static void gemini_ethernet_port_remove(struct platform_device *pdev) |
2524 | { |
2525 | struct gemini_ethernet_port *port = platform_get_drvdata(pdev); |
2526 | |
2527 | gemini_port_remove(port); |
2528 | } |
2529 | |
2530 | static const struct of_device_id gemini_ethernet_port_of_match[] = { |
2531 | { |
2532 | .compatible = "cortina,gemini-ethernet-port" , |
2533 | }, |
2534 | {}, |
2535 | }; |
2536 | MODULE_DEVICE_TABLE(of, gemini_ethernet_port_of_match); |
2537 | |
2538 | static struct platform_driver gemini_ethernet_port_driver = { |
2539 | .driver = { |
2540 | .name = "gemini-ethernet-port" , |
2541 | .of_match_table = gemini_ethernet_port_of_match, |
2542 | }, |
2543 | .probe = gemini_ethernet_port_probe, |
2544 | .remove_new = gemini_ethernet_port_remove, |
2545 | }; |
2546 | |
2547 | static int gemini_ethernet_probe(struct platform_device *pdev) |
2548 | { |
2549 | struct device *dev = &pdev->dev; |
2550 | struct gemini_ethernet *geth; |
2551 | unsigned int retry = 5; |
2552 | u32 val; |
2553 | |
2554 | /* Global registers */ |
2555 | geth = devm_kzalloc(dev, size: sizeof(*geth), GFP_KERNEL); |
2556 | if (!geth) |
2557 | return -ENOMEM; |
2558 | geth->base = devm_platform_get_and_ioremap_resource(pdev, index: 0, NULL); |
2559 | if (IS_ERR(ptr: geth->base)) |
2560 | return PTR_ERR(ptr: geth->base); |
2561 | geth->dev = dev; |
2562 | |
2563 | /* Wait for ports to stabilize */ |
2564 | do { |
2565 | udelay(2); |
2566 | val = readl(addr: geth->base + GLOBAL_TOE_VERSION_REG); |
2567 | barrier(); |
2568 | } while (!val && --retry); |
2569 | if (!retry) { |
2570 | dev_err(dev, "failed to reset ethernet\n" ); |
2571 | return -EIO; |
2572 | } |
2573 | dev_info(dev, "Ethernet device ID: 0x%03x, revision 0x%01x\n" , |
2574 | (val >> 4) & 0xFFFU, val & 0xFU); |
2575 | |
2576 | spin_lock_init(&geth->irq_lock); |
2577 | spin_lock_init(&geth->freeq_lock); |
2578 | |
2579 | /* The children will use this */ |
2580 | platform_set_drvdata(pdev, data: geth); |
2581 | |
2582 | /* Spawn child devices for the two ports */ |
2583 | return devm_of_platform_populate(dev); |
2584 | } |
2585 | |
2586 | static void gemini_ethernet_remove(struct platform_device *pdev) |
2587 | { |
2588 | struct gemini_ethernet *geth = platform_get_drvdata(pdev); |
2589 | |
2590 | geth_cleanup_freeq(geth); |
2591 | geth->initialized = false; |
2592 | } |
2593 | |
2594 | static const struct of_device_id gemini_ethernet_of_match[] = { |
2595 | { |
2596 | .compatible = "cortina,gemini-ethernet" , |
2597 | }, |
2598 | {}, |
2599 | }; |
2600 | MODULE_DEVICE_TABLE(of, gemini_ethernet_of_match); |
2601 | |
2602 | static struct platform_driver gemini_ethernet_driver = { |
2603 | .driver = { |
2604 | .name = DRV_NAME, |
2605 | .of_match_table = gemini_ethernet_of_match, |
2606 | }, |
2607 | .probe = gemini_ethernet_probe, |
2608 | .remove_new = gemini_ethernet_remove, |
2609 | }; |
2610 | |
2611 | static int __init gemini_ethernet_module_init(void) |
2612 | { |
2613 | int ret; |
2614 | |
2615 | ret = platform_driver_register(&gemini_ethernet_port_driver); |
2616 | if (ret) |
2617 | return ret; |
2618 | |
2619 | ret = platform_driver_register(&gemini_ethernet_driver); |
2620 | if (ret) { |
2621 | platform_driver_unregister(&gemini_ethernet_port_driver); |
2622 | return ret; |
2623 | } |
2624 | |
2625 | return 0; |
2626 | } |
2627 | module_init(gemini_ethernet_module_init); |
2628 | |
2629 | static void __exit gemini_ethernet_module_exit(void) |
2630 | { |
2631 | platform_driver_unregister(&gemini_ethernet_driver); |
2632 | platform_driver_unregister(&gemini_ethernet_port_driver); |
2633 | } |
2634 | module_exit(gemini_ethernet_module_exit); |
2635 | |
2636 | MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>" ); |
2637 | MODULE_DESCRIPTION("StorLink SL351x (Gemini) ethernet driver" ); |
2638 | MODULE_LICENSE("GPL" ); |
2639 | MODULE_ALIAS("platform:" DRV_NAME); |
2640 | |