1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Texas Instruments Ethernet Switch Driver |
4 | * |
5 | * Copyright (C) 2012 Texas Instruments |
6 | * |
7 | */ |
8 | |
9 | #include <linux/kernel.h> |
10 | #include <linux/io.h> |
11 | #include <linux/clk.h> |
12 | #include <linux/timer.h> |
13 | #include <linux/module.h> |
14 | #include <linux/platform_device.h> |
15 | #include <linux/irqreturn.h> |
16 | #include <linux/interrupt.h> |
17 | #include <linux/if_ether.h> |
18 | #include <linux/etherdevice.h> |
19 | #include <linux/netdevice.h> |
20 | #include <linux/net_tstamp.h> |
21 | #include <linux/phy.h> |
22 | #include <linux/phy/phy.h> |
23 | #include <linux/workqueue.h> |
24 | #include <linux/delay.h> |
25 | #include <linux/pm_runtime.h> |
26 | #include <linux/gpio/consumer.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/if_vlan.h> |
32 | #include <linux/kmemleak.h> |
33 | #include <linux/sys_soc.h> |
34 | #include <net/page_pool/helpers.h> |
35 | #include <linux/bpf.h> |
36 | #include <linux/bpf_trace.h> |
37 | |
38 | #include <linux/pinctrl/consumer.h> |
39 | #include <net/pkt_cls.h> |
40 | |
41 | #include "cpsw.h" |
42 | #include "cpsw_ale.h" |
43 | #include "cpsw_priv.h" |
44 | #include "cpsw_sl.h" |
45 | #include "cpts.h" |
46 | #include "davinci_cpdma.h" |
47 | |
48 | #include <net/pkt_sched.h> |
49 | |
50 | static int debug_level; |
51 | module_param(debug_level, int, 0); |
52 | MODULE_PARM_DESC(debug_level, "cpsw debug level (NETIF_MSG bits)" ); |
53 | |
54 | static int ale_ageout = 10; |
55 | module_param(ale_ageout, int, 0); |
56 | MODULE_PARM_DESC(ale_ageout, "cpsw ale ageout interval (seconds)" ); |
57 | |
58 | static int rx_packet_max = CPSW_MAX_PACKET_SIZE; |
59 | module_param(rx_packet_max, int, 0); |
60 | MODULE_PARM_DESC(rx_packet_max, "maximum receive packet size (bytes)" ); |
61 | |
62 | static int descs_pool_size = CPSW_CPDMA_DESCS_POOL_SIZE_DEFAULT; |
63 | module_param(descs_pool_size, int, 0444); |
64 | MODULE_PARM_DESC(descs_pool_size, "Number of CPDMA CPPI descriptors in pool" ); |
65 | |
66 | #define for_each_slave(priv, func, arg...) \ |
67 | do { \ |
68 | struct cpsw_slave *slave; \ |
69 | struct cpsw_common *cpsw = (priv)->cpsw; \ |
70 | int n; \ |
71 | if (cpsw->data.dual_emac) \ |
72 | (func)((cpsw)->slaves + priv->emac_port, ##arg);\ |
73 | else \ |
74 | for (n = cpsw->data.slaves, \ |
75 | slave = cpsw->slaves; \ |
76 | n; n--) \ |
77 | (func)(slave++, ##arg); \ |
78 | } while (0) |
79 | |
80 | static int cpsw_slave_index_priv(struct cpsw_common *cpsw, |
81 | struct cpsw_priv *priv) |
82 | { |
83 | return cpsw->data.dual_emac ? priv->emac_port : cpsw->data.active_slave; |
84 | } |
85 | |
86 | static int cpsw_get_slave_port(u32 slave_num) |
87 | { |
88 | return slave_num + 1; |
89 | } |
90 | |
91 | static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev, |
92 | __be16 proto, u16 vid); |
93 | |
94 | static void cpsw_set_promiscious(struct net_device *ndev, bool enable) |
95 | { |
96 | struct cpsw_common *cpsw = ndev_to_cpsw(ndev); |
97 | struct cpsw_ale *ale = cpsw->ale; |
98 | int i; |
99 | |
100 | if (cpsw->data.dual_emac) { |
101 | bool flag = false; |
102 | |
103 | /* Enabling promiscuous mode for one interface will be |
104 | * common for both the interface as the interface shares |
105 | * the same hardware resource. |
106 | */ |
107 | for (i = 0; i < cpsw->data.slaves; i++) |
108 | if (cpsw->slaves[i].ndev->flags & IFF_PROMISC) |
109 | flag = true; |
110 | |
111 | if (!enable && flag) { |
112 | enable = true; |
113 | dev_err(&ndev->dev, "promiscuity not disabled as the other interface is still in promiscuity mode\n" ); |
114 | } |
115 | |
116 | if (enable) { |
117 | /* Enable Bypass */ |
118 | cpsw_ale_control_set(ale, port: 0, control: ALE_BYPASS, value: 1); |
119 | |
120 | dev_dbg(&ndev->dev, "promiscuity enabled\n" ); |
121 | } else { |
122 | /* Disable Bypass */ |
123 | cpsw_ale_control_set(ale, port: 0, control: ALE_BYPASS, value: 0); |
124 | dev_dbg(&ndev->dev, "promiscuity disabled\n" ); |
125 | } |
126 | } else { |
127 | if (enable) { |
128 | unsigned long timeout = jiffies + HZ; |
129 | |
130 | /* Disable Learn for all ports (host is port 0 and slaves are port 1 and up */ |
131 | for (i = 0; i <= cpsw->data.slaves; i++) { |
132 | cpsw_ale_control_set(ale, port: i, |
133 | control: ALE_PORT_NOLEARN, value: 1); |
134 | cpsw_ale_control_set(ale, port: i, |
135 | control: ALE_PORT_NO_SA_UPDATE, value: 1); |
136 | } |
137 | |
138 | /* Clear All Untouched entries */ |
139 | cpsw_ale_control_set(ale, port: 0, control: ALE_AGEOUT, value: 1); |
140 | do { |
141 | cpu_relax(); |
142 | if (cpsw_ale_control_get(ale, port: 0, control: ALE_AGEOUT)) |
143 | break; |
144 | } while (time_after(timeout, jiffies)); |
145 | cpsw_ale_control_set(ale, port: 0, control: ALE_AGEOUT, value: 1); |
146 | |
147 | /* Clear all mcast from ALE */ |
148 | cpsw_ale_flush_multicast(ale, ALE_ALL_PORTS, vid: -1); |
149 | __hw_addr_ref_unsync_dev(list: &ndev->mc, dev: ndev, NULL); |
150 | |
151 | /* Flood All Unicast Packets to Host port */ |
152 | cpsw_ale_control_set(ale, port: 0, control: ALE_P0_UNI_FLOOD, value: 1); |
153 | dev_dbg(&ndev->dev, "promiscuity enabled\n" ); |
154 | } else { |
155 | /* Don't Flood All Unicast Packets to Host port */ |
156 | cpsw_ale_control_set(ale, port: 0, control: ALE_P0_UNI_FLOOD, value: 0); |
157 | |
158 | /* Enable Learn for all ports (host is port 0 and slaves are port 1 and up */ |
159 | for (i = 0; i <= cpsw->data.slaves; i++) { |
160 | cpsw_ale_control_set(ale, port: i, |
161 | control: ALE_PORT_NOLEARN, value: 0); |
162 | cpsw_ale_control_set(ale, port: i, |
163 | control: ALE_PORT_NO_SA_UPDATE, value: 0); |
164 | } |
165 | dev_dbg(&ndev->dev, "promiscuity disabled\n" ); |
166 | } |
167 | } |
168 | } |
169 | |
170 | /** |
171 | * cpsw_set_mc - adds multicast entry to the table if it's not added or deletes |
172 | * if it's not deleted |
173 | * @ndev: device to sync |
174 | * @addr: address to be added or deleted |
175 | * @vid: vlan id, if vid < 0 set/unset address for real device |
176 | * @add: add address if the flag is set or remove otherwise |
177 | */ |
178 | static int cpsw_set_mc(struct net_device *ndev, const u8 *addr, |
179 | int vid, int add) |
180 | { |
181 | struct cpsw_priv *priv = netdev_priv(dev: ndev); |
182 | struct cpsw_common *cpsw = priv->cpsw; |
183 | int mask, flags, ret; |
184 | |
185 | if (vid < 0) { |
186 | if (cpsw->data.dual_emac) |
187 | vid = cpsw->slaves[priv->emac_port].port_vlan; |
188 | else |
189 | vid = 0; |
190 | } |
191 | |
192 | mask = cpsw->data.dual_emac ? ALE_PORT_HOST : ALE_ALL_PORTS; |
193 | flags = vid ? ALE_VLAN : 0; |
194 | |
195 | if (add) |
196 | ret = cpsw_ale_add_mcast(ale: cpsw->ale, addr, port_mask: mask, flags, vid, mcast_state: 0); |
197 | else |
198 | ret = cpsw_ale_del_mcast(ale: cpsw->ale, addr, port_mask: 0, flags, vid); |
199 | |
200 | return ret; |
201 | } |
202 | |
203 | static int cpsw_update_vlan_mc(struct net_device *vdev, int vid, void *ctx) |
204 | { |
205 | struct addr_sync_ctx *sync_ctx = ctx; |
206 | struct netdev_hw_addr *ha; |
207 | int found = 0, ret = 0; |
208 | |
209 | if (!vdev || !(vdev->flags & IFF_UP)) |
210 | return 0; |
211 | |
212 | /* vlan address is relevant if its sync_cnt != 0 */ |
213 | netdev_for_each_mc_addr(ha, vdev) { |
214 | if (ether_addr_equal(addr1: ha->addr, addr2: sync_ctx->addr)) { |
215 | found = ha->sync_cnt; |
216 | break; |
217 | } |
218 | } |
219 | |
220 | if (found) |
221 | sync_ctx->consumed++; |
222 | |
223 | if (sync_ctx->flush) { |
224 | if (!found) |
225 | cpsw_set_mc(ndev: sync_ctx->ndev, addr: sync_ctx->addr, vid, add: 0); |
226 | return 0; |
227 | } |
228 | |
229 | if (found) |
230 | ret = cpsw_set_mc(ndev: sync_ctx->ndev, addr: sync_ctx->addr, vid, add: 1); |
231 | |
232 | return ret; |
233 | } |
234 | |
235 | static int cpsw_add_mc_addr(struct net_device *ndev, const u8 *addr, int num) |
236 | { |
237 | struct addr_sync_ctx sync_ctx; |
238 | int ret; |
239 | |
240 | sync_ctx.consumed = 0; |
241 | sync_ctx.addr = addr; |
242 | sync_ctx.ndev = ndev; |
243 | sync_ctx.flush = 0; |
244 | |
245 | ret = vlan_for_each(dev: ndev, action: cpsw_update_vlan_mc, arg: &sync_ctx); |
246 | if (sync_ctx.consumed < num && !ret) |
247 | ret = cpsw_set_mc(ndev, addr, vid: -1, add: 1); |
248 | |
249 | return ret; |
250 | } |
251 | |
252 | static int cpsw_del_mc_addr(struct net_device *ndev, const u8 *addr, int num) |
253 | { |
254 | struct addr_sync_ctx sync_ctx; |
255 | |
256 | sync_ctx.consumed = 0; |
257 | sync_ctx.addr = addr; |
258 | sync_ctx.ndev = ndev; |
259 | sync_ctx.flush = 1; |
260 | |
261 | vlan_for_each(dev: ndev, action: cpsw_update_vlan_mc, arg: &sync_ctx); |
262 | if (sync_ctx.consumed == num) |
263 | cpsw_set_mc(ndev, addr, vid: -1, add: 0); |
264 | |
265 | return 0; |
266 | } |
267 | |
268 | static int cpsw_purge_vlan_mc(struct net_device *vdev, int vid, void *ctx) |
269 | { |
270 | struct addr_sync_ctx *sync_ctx = ctx; |
271 | struct netdev_hw_addr *ha; |
272 | int found = 0; |
273 | |
274 | if (!vdev || !(vdev->flags & IFF_UP)) |
275 | return 0; |
276 | |
277 | /* vlan address is relevant if its sync_cnt != 0 */ |
278 | netdev_for_each_mc_addr(ha, vdev) { |
279 | if (ether_addr_equal(addr1: ha->addr, addr2: sync_ctx->addr)) { |
280 | found = ha->sync_cnt; |
281 | break; |
282 | } |
283 | } |
284 | |
285 | if (!found) |
286 | return 0; |
287 | |
288 | sync_ctx->consumed++; |
289 | cpsw_set_mc(ndev: sync_ctx->ndev, addr: sync_ctx->addr, vid, add: 0); |
290 | return 0; |
291 | } |
292 | |
293 | static int cpsw_purge_all_mc(struct net_device *ndev, const u8 *addr, int num) |
294 | { |
295 | struct addr_sync_ctx sync_ctx; |
296 | |
297 | sync_ctx.addr = addr; |
298 | sync_ctx.ndev = ndev; |
299 | sync_ctx.consumed = 0; |
300 | |
301 | vlan_for_each(dev: ndev, action: cpsw_purge_vlan_mc, arg: &sync_ctx); |
302 | if (sync_ctx.consumed < num) |
303 | cpsw_set_mc(ndev, addr, vid: -1, add: 0); |
304 | |
305 | return 0; |
306 | } |
307 | |
308 | static void cpsw_ndo_set_rx_mode(struct net_device *ndev) |
309 | { |
310 | struct cpsw_priv *priv = netdev_priv(dev: ndev); |
311 | struct cpsw_common *cpsw = priv->cpsw; |
312 | int slave_port = -1; |
313 | |
314 | if (cpsw->data.dual_emac) |
315 | slave_port = priv->emac_port + 1; |
316 | |
317 | if (ndev->flags & IFF_PROMISC) { |
318 | /* Enable promiscuous mode */ |
319 | cpsw_set_promiscious(ndev, enable: true); |
320 | cpsw_ale_set_allmulti(ale: cpsw->ale, IFF_ALLMULTI, port: slave_port); |
321 | return; |
322 | } else { |
323 | /* Disable promiscuous mode */ |
324 | cpsw_set_promiscious(ndev, enable: false); |
325 | } |
326 | |
327 | /* Restore allmulti on vlans if necessary */ |
328 | cpsw_ale_set_allmulti(ale: cpsw->ale, |
329 | allmulti: ndev->flags & IFF_ALLMULTI, port: slave_port); |
330 | |
331 | /* add/remove mcast address either for real netdev or for vlan */ |
332 | __hw_addr_ref_sync_dev(list: &ndev->mc, dev: ndev, sync: cpsw_add_mc_addr, |
333 | unsync: cpsw_del_mc_addr); |
334 | } |
335 | |
336 | static unsigned int cpsw_rxbuf_total_len(unsigned int len) |
337 | { |
338 | len += CPSW_HEADROOM_NA; |
339 | len += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); |
340 | |
341 | return SKB_DATA_ALIGN(len); |
342 | } |
343 | |
344 | static void cpsw_rx_handler(void *token, int len, int status) |
345 | { |
346 | struct page *new_page, *page = token; |
347 | void *pa = page_address(page); |
348 | struct cpsw_meta_xdp *xmeta = pa + CPSW_XMETA_OFFSET; |
349 | struct cpsw_common *cpsw = ndev_to_cpsw(xmeta->ndev); |
350 | int pkt_size = cpsw->rx_packet_max; |
351 | int ret = 0, port, ch = xmeta->ch; |
352 | int headroom = CPSW_HEADROOM_NA; |
353 | struct net_device *ndev = xmeta->ndev; |
354 | struct cpsw_priv *priv; |
355 | struct page_pool *pool; |
356 | struct sk_buff *skb; |
357 | struct xdp_buff xdp; |
358 | dma_addr_t dma; |
359 | |
360 | if (cpsw->data.dual_emac && status >= 0) { |
361 | port = CPDMA_RX_SOURCE_PORT(status); |
362 | if (port) |
363 | ndev = cpsw->slaves[--port].ndev; |
364 | } |
365 | |
366 | priv = netdev_priv(dev: ndev); |
367 | pool = cpsw->page_pool[ch]; |
368 | if (unlikely(status < 0) || unlikely(!netif_running(ndev))) { |
369 | /* In dual emac mode check for all interfaces */ |
370 | if (cpsw->data.dual_emac && cpsw->usage_count && |
371 | (status >= 0)) { |
372 | /* The packet received is for the interface which |
373 | * is already down and the other interface is up |
374 | * and running, instead of freeing which results |
375 | * in reducing of the number of rx descriptor in |
376 | * DMA engine, requeue page back to cpdma. |
377 | */ |
378 | new_page = page; |
379 | goto requeue; |
380 | } |
381 | |
382 | /* the interface is going down, pages are purged */ |
383 | page_pool_recycle_direct(pool, page); |
384 | return; |
385 | } |
386 | |
387 | new_page = page_pool_dev_alloc_pages(pool); |
388 | if (unlikely(!new_page)) { |
389 | new_page = page; |
390 | ndev->stats.rx_dropped++; |
391 | goto requeue; |
392 | } |
393 | |
394 | if (priv->xdp_prog) { |
395 | int size = len; |
396 | |
397 | xdp_init_buff(xdp: &xdp, PAGE_SIZE, rxq: &priv->xdp_rxq[ch]); |
398 | if (status & CPDMA_RX_VLAN_ENCAP) { |
399 | headroom += CPSW_RX_VLAN_ENCAP_HDR_SIZE; |
400 | size -= CPSW_RX_VLAN_ENCAP_HDR_SIZE; |
401 | } |
402 | |
403 | xdp_prepare_buff(xdp: &xdp, hard_start: pa, headroom, data_len: size, meta_valid: false); |
404 | |
405 | port = priv->emac_port + cpsw->data.dual_emac; |
406 | ret = cpsw_run_xdp(priv, ch, xdp: &xdp, page, port, len: &len); |
407 | if (ret != CPSW_XDP_PASS) |
408 | goto requeue; |
409 | |
410 | headroom = xdp.data - xdp.data_hard_start; |
411 | |
412 | /* XDP prog can modify vlan tag, so can't use encap header */ |
413 | status &= ~CPDMA_RX_VLAN_ENCAP; |
414 | } |
415 | |
416 | /* pass skb to netstack if no XDP prog or returned XDP_PASS */ |
417 | skb = build_skb(data: pa, frag_size: cpsw_rxbuf_total_len(len: pkt_size)); |
418 | if (!skb) { |
419 | ndev->stats.rx_dropped++; |
420 | page_pool_recycle_direct(pool, page); |
421 | goto requeue; |
422 | } |
423 | |
424 | skb_reserve(skb, len: headroom); |
425 | skb_put(skb, len); |
426 | skb->dev = ndev; |
427 | if (status & CPDMA_RX_VLAN_ENCAP) |
428 | cpsw_rx_vlan_encap(skb); |
429 | if (priv->rx_ts_enabled) |
430 | cpts_rx_timestamp(cpts: cpsw->cpts, skb); |
431 | skb->protocol = eth_type_trans(skb, dev: ndev); |
432 | |
433 | /* mark skb for recycling */ |
434 | skb_mark_for_recycle(skb); |
435 | netif_receive_skb(skb); |
436 | |
437 | ndev->stats.rx_bytes += len; |
438 | ndev->stats.rx_packets++; |
439 | |
440 | requeue: |
441 | xmeta = page_address(new_page) + CPSW_XMETA_OFFSET; |
442 | xmeta->ndev = ndev; |
443 | xmeta->ch = ch; |
444 | |
445 | dma = page_pool_get_dma_addr(page: new_page) + CPSW_HEADROOM_NA; |
446 | ret = cpdma_chan_submit_mapped(chan: cpsw->rxv[ch].ch, token: new_page, data: dma, |
447 | len: pkt_size, directed: 0); |
448 | if (ret < 0) { |
449 | WARN_ON(ret == -ENOMEM); |
450 | page_pool_recycle_direct(pool, page: new_page); |
451 | } |
452 | } |
453 | |
454 | static void _cpsw_adjust_link(struct cpsw_slave *slave, |
455 | struct cpsw_priv *priv, bool *link) |
456 | { |
457 | struct phy_device *phy = slave->phy; |
458 | u32 mac_control = 0; |
459 | u32 slave_port; |
460 | struct cpsw_common *cpsw = priv->cpsw; |
461 | |
462 | if (!phy) |
463 | return; |
464 | |
465 | slave_port = cpsw_get_slave_port(slave_num: slave->slave_num); |
466 | |
467 | if (phy->link) { |
468 | mac_control = CPSW_SL_CTL_GMII_EN; |
469 | |
470 | if (phy->speed == 1000) |
471 | mac_control |= CPSW_SL_CTL_GIG; |
472 | if (phy->duplex) |
473 | mac_control |= CPSW_SL_CTL_FULLDUPLEX; |
474 | |
475 | /* set speed_in input in case RMII mode is used in 100Mbps */ |
476 | if (phy->speed == 100) |
477 | mac_control |= CPSW_SL_CTL_IFCTL_A; |
478 | /* in band mode only works in 10Mbps RGMII mode */ |
479 | else if ((phy->speed == 10) && phy_interface_is_rgmii(phydev: phy)) |
480 | mac_control |= CPSW_SL_CTL_EXT_EN; /* In Band mode */ |
481 | |
482 | if (priv->rx_pause) |
483 | mac_control |= CPSW_SL_CTL_RX_FLOW_EN; |
484 | |
485 | if (priv->tx_pause) |
486 | mac_control |= CPSW_SL_CTL_TX_FLOW_EN; |
487 | |
488 | if (mac_control != slave->mac_control) |
489 | cpsw_sl_ctl_set(sl: slave->mac_sl, ctl_funcs: mac_control); |
490 | |
491 | /* enable forwarding */ |
492 | cpsw_ale_control_set(ale: cpsw->ale, port: slave_port, |
493 | control: ALE_PORT_STATE, value: ALE_PORT_STATE_FORWARD); |
494 | |
495 | *link = true; |
496 | |
497 | if (priv->shp_cfg_speed && |
498 | priv->shp_cfg_speed != slave->phy->speed && |
499 | !cpsw_shp_is_off(priv)) |
500 | dev_warn(priv->dev, |
501 | "Speed was changed, CBS shaper speeds are changed!" ); |
502 | } else { |
503 | mac_control = 0; |
504 | /* disable forwarding */ |
505 | cpsw_ale_control_set(ale: cpsw->ale, port: slave_port, |
506 | control: ALE_PORT_STATE, value: ALE_PORT_STATE_DISABLE); |
507 | |
508 | cpsw_sl_wait_for_idle(sl: slave->mac_sl, tmo: 100); |
509 | |
510 | cpsw_sl_ctl_reset(sl: slave->mac_sl); |
511 | } |
512 | |
513 | if (mac_control != slave->mac_control) |
514 | phy_print_status(phydev: phy); |
515 | |
516 | slave->mac_control = mac_control; |
517 | } |
518 | |
519 | static void cpsw_adjust_link(struct net_device *ndev) |
520 | { |
521 | struct cpsw_priv *priv = netdev_priv(dev: ndev); |
522 | struct cpsw_common *cpsw = priv->cpsw; |
523 | bool link = false; |
524 | |
525 | for_each_slave(priv, _cpsw_adjust_link, priv, &link); |
526 | |
527 | if (link) { |
528 | if (cpsw_need_resplit(cpsw)) |
529 | cpsw_split_res(cpsw); |
530 | |
531 | netif_carrier_on(dev: ndev); |
532 | if (netif_running(dev: ndev)) |
533 | netif_tx_wake_all_queues(dev: ndev); |
534 | } else { |
535 | netif_carrier_off(dev: ndev); |
536 | netif_tx_stop_all_queues(dev: ndev); |
537 | } |
538 | } |
539 | |
540 | static inline void cpsw_add_dual_emac_def_ale_entries( |
541 | struct cpsw_priv *priv, struct cpsw_slave *slave, |
542 | u32 slave_port) |
543 | { |
544 | struct cpsw_common *cpsw = priv->cpsw; |
545 | u32 port_mask = 1 << slave_port | ALE_PORT_HOST; |
546 | |
547 | if (cpsw->version == CPSW_VERSION_1) |
548 | slave_write(slave, val: slave->port_vlan, CPSW1_PORT_VLAN); |
549 | else |
550 | slave_write(slave, val: slave->port_vlan, CPSW2_PORT_VLAN); |
551 | cpsw_ale_add_vlan(ale: cpsw->ale, vid: slave->port_vlan, port: port_mask, |
552 | untag: port_mask, reg_mcast: port_mask, unreg_mcast: 0); |
553 | cpsw_ale_add_mcast(ale: cpsw->ale, addr: priv->ndev->broadcast, |
554 | ALE_PORT_HOST, ALE_VLAN, vid: slave->port_vlan, mcast_state: 0); |
555 | cpsw_ale_add_ucast(ale: cpsw->ale, addr: priv->mac_addr, |
556 | HOST_PORT_NUM, ALE_VLAN | |
557 | ALE_SECURE, vid: slave->port_vlan); |
558 | cpsw_ale_control_set(ale: cpsw->ale, port: slave_port, |
559 | control: ALE_PORT_DROP_UNKNOWN_VLAN, value: 1); |
560 | } |
561 | |
562 | static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) |
563 | { |
564 | u32 slave_port; |
565 | struct phy_device *phy; |
566 | struct cpsw_common *cpsw = priv->cpsw; |
567 | |
568 | cpsw_sl_reset(sl: slave->mac_sl, tmo: 100); |
569 | cpsw_sl_ctl_reset(sl: slave->mac_sl); |
570 | |
571 | /* setup priority mapping */ |
572 | cpsw_sl_reg_write(sl: slave->mac_sl, reg: CPSW_SL_RX_PRI_MAP, |
573 | RX_PRIORITY_MAPPING); |
574 | |
575 | switch (cpsw->version) { |
576 | case CPSW_VERSION_1: |
577 | slave_write(slave, TX_PRIORITY_MAPPING, CPSW1_TX_PRI_MAP); |
578 | /* Increase RX FIFO size to 5 for supporting fullduplex |
579 | * flow control mode |
580 | */ |
581 | slave_write(slave, |
582 | val: (CPSW_MAX_BLKS_TX << CPSW_MAX_BLKS_TX_SHIFT) | |
583 | CPSW_MAX_BLKS_RX, CPSW1_MAX_BLKS); |
584 | break; |
585 | case CPSW_VERSION_2: |
586 | case CPSW_VERSION_3: |
587 | case CPSW_VERSION_4: |
588 | slave_write(slave, TX_PRIORITY_MAPPING, CPSW2_TX_PRI_MAP); |
589 | /* Increase RX FIFO size to 5 for supporting fullduplex |
590 | * flow control mode |
591 | */ |
592 | slave_write(slave, |
593 | val: (CPSW_MAX_BLKS_TX << CPSW_MAX_BLKS_TX_SHIFT) | |
594 | CPSW_MAX_BLKS_RX, CPSW2_MAX_BLKS); |
595 | break; |
596 | } |
597 | |
598 | /* setup max packet size, and mac address */ |
599 | cpsw_sl_reg_write(sl: slave->mac_sl, reg: CPSW_SL_RX_MAXLEN, |
600 | val: cpsw->rx_packet_max); |
601 | cpsw_set_slave_mac(slave, priv); |
602 | |
603 | slave->mac_control = 0; /* no link yet */ |
604 | |
605 | slave_port = cpsw_get_slave_port(slave_num: slave->slave_num); |
606 | |
607 | if (cpsw->data.dual_emac) |
608 | cpsw_add_dual_emac_def_ale_entries(priv, slave, slave_port); |
609 | else |
610 | cpsw_ale_add_mcast(ale: cpsw->ale, addr: priv->ndev->broadcast, |
611 | port_mask: 1 << slave_port, flags: 0, vid: 0, ALE_MCAST_FWD_2); |
612 | |
613 | if (slave->data->phy_node) { |
614 | phy = of_phy_connect(dev: priv->ndev, phy_np: slave->data->phy_node, |
615 | hndlr: &cpsw_adjust_link, flags: 0, iface: slave->data->phy_if); |
616 | if (!phy) { |
617 | dev_err(priv->dev, "phy \"%pOF\" not found on slave %d\n" , |
618 | slave->data->phy_node, |
619 | slave->slave_num); |
620 | return; |
621 | } |
622 | } else { |
623 | phy = phy_connect(dev: priv->ndev, bus_id: slave->data->phy_id, |
624 | handler: &cpsw_adjust_link, interface: slave->data->phy_if); |
625 | if (IS_ERR(ptr: phy)) { |
626 | dev_err(priv->dev, |
627 | "phy \"%s\" not found on slave %d, err %ld\n" , |
628 | slave->data->phy_id, slave->slave_num, |
629 | PTR_ERR(phy)); |
630 | return; |
631 | } |
632 | } |
633 | |
634 | slave->phy = phy; |
635 | |
636 | phy_attached_info(phydev: slave->phy); |
637 | |
638 | phy_start(phydev: slave->phy); |
639 | |
640 | /* Configure GMII_SEL register */ |
641 | if (!IS_ERR(ptr: slave->data->ifphy)) |
642 | phy_set_mode_ext(phy: slave->data->ifphy, mode: PHY_MODE_ETHERNET, |
643 | submode: slave->data->phy_if); |
644 | else |
645 | cpsw_phy_sel(dev: cpsw->dev, phy_mode: slave->phy->interface, |
646 | slave: slave->slave_num); |
647 | } |
648 | |
649 | static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) |
650 | { |
651 | struct cpsw_common *cpsw = priv->cpsw; |
652 | const int vlan = cpsw->data.default_vlan; |
653 | u32 reg; |
654 | int i; |
655 | int unreg_mcast_mask; |
656 | |
657 | reg = (cpsw->version == CPSW_VERSION_1) ? CPSW1_PORT_VLAN : |
658 | CPSW2_PORT_VLAN; |
659 | |
660 | writel(val: vlan, addr: &cpsw->host_port_regs->port_vlan); |
661 | |
662 | for (i = 0; i < cpsw->data.slaves; i++) |
663 | slave_write(slave: cpsw->slaves + i, val: vlan, offset: reg); |
664 | |
665 | if (priv->ndev->flags & IFF_ALLMULTI) |
666 | unreg_mcast_mask = ALE_ALL_PORTS; |
667 | else |
668 | unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; |
669 | |
670 | cpsw_ale_add_vlan(ale: cpsw->ale, vid: vlan, ALE_ALL_PORTS, |
671 | ALE_ALL_PORTS, ALE_ALL_PORTS, |
672 | unreg_mcast: unreg_mcast_mask); |
673 | } |
674 | |
675 | static void cpsw_init_host_port(struct cpsw_priv *priv) |
676 | { |
677 | u32 fifo_mode; |
678 | u32 control_reg; |
679 | struct cpsw_common *cpsw = priv->cpsw; |
680 | |
681 | /* soft reset the controller and initialize ale */ |
682 | soft_reset(module: "cpsw" , reg: &cpsw->regs->soft_reset); |
683 | cpsw_ale_start(ale: cpsw->ale); |
684 | |
685 | /* switch to vlan unaware mode */ |
686 | cpsw_ale_control_set(ale: cpsw->ale, HOST_PORT_NUM, control: ALE_VLAN_AWARE, |
687 | CPSW_ALE_VLAN_AWARE); |
688 | control_reg = readl(addr: &cpsw->regs->control); |
689 | control_reg |= CPSW_VLAN_AWARE | CPSW_RX_VLAN_ENCAP; |
690 | writel(val: control_reg, addr: &cpsw->regs->control); |
691 | fifo_mode = (cpsw->data.dual_emac) ? CPSW_FIFO_DUAL_MAC_MODE : |
692 | CPSW_FIFO_NORMAL_MODE; |
693 | writel(val: fifo_mode, addr: &cpsw->host_port_regs->tx_in_ctl); |
694 | |
695 | /* setup host port priority mapping */ |
696 | writel_relaxed(CPDMA_TX_PRIORITY_MAP, |
697 | &cpsw->host_port_regs->cpdma_tx_pri_map); |
698 | writel_relaxed(0, &cpsw->host_port_regs->cpdma_rx_chan_map); |
699 | |
700 | cpsw_ale_control_set(ale: cpsw->ale, HOST_PORT_NUM, |
701 | control: ALE_PORT_STATE, value: ALE_PORT_STATE_FORWARD); |
702 | |
703 | if (!cpsw->data.dual_emac) { |
704 | cpsw_ale_add_ucast(ale: cpsw->ale, addr: priv->mac_addr, HOST_PORT_NUM, |
705 | flags: 0, vid: 0); |
706 | cpsw_ale_add_mcast(ale: cpsw->ale, addr: priv->ndev->broadcast, |
707 | ALE_PORT_HOST, flags: 0, vid: 0, ALE_MCAST_FWD_2); |
708 | } |
709 | } |
710 | |
711 | static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_common *cpsw) |
712 | { |
713 | u32 slave_port; |
714 | |
715 | slave_port = cpsw_get_slave_port(slave_num: slave->slave_num); |
716 | |
717 | if (!slave->phy) |
718 | return; |
719 | phy_stop(phydev: slave->phy); |
720 | phy_disconnect(phydev: slave->phy); |
721 | slave->phy = NULL; |
722 | cpsw_ale_control_set(ale: cpsw->ale, port: slave_port, |
723 | control: ALE_PORT_STATE, value: ALE_PORT_STATE_DISABLE); |
724 | cpsw_sl_reset(sl: slave->mac_sl, tmo: 100); |
725 | cpsw_sl_ctl_reset(sl: slave->mac_sl); |
726 | } |
727 | |
728 | static int cpsw_restore_vlans(struct net_device *vdev, int vid, void *arg) |
729 | { |
730 | struct cpsw_priv *priv = arg; |
731 | |
732 | if (!vdev) |
733 | return 0; |
734 | |
735 | cpsw_ndo_vlan_rx_add_vid(ndev: priv->ndev, proto: 0, vid); |
736 | return 0; |
737 | } |
738 | |
739 | /* restore resources after port reset */ |
740 | static void cpsw_restore(struct cpsw_priv *priv) |
741 | { |
742 | /* restore vlan configurations */ |
743 | vlan_for_each(dev: priv->ndev, action: cpsw_restore_vlans, arg: priv); |
744 | |
745 | /* restore MQPRIO offload */ |
746 | for_each_slave(priv, cpsw_mqprio_resume, priv); |
747 | |
748 | /* restore CBS offload */ |
749 | for_each_slave(priv, cpsw_cbs_resume, priv); |
750 | } |
751 | |
752 | static int cpsw_ndo_open(struct net_device *ndev) |
753 | { |
754 | struct cpsw_priv *priv = netdev_priv(dev: ndev); |
755 | struct cpsw_common *cpsw = priv->cpsw; |
756 | int ret; |
757 | u32 reg; |
758 | |
759 | ret = pm_runtime_resume_and_get(dev: cpsw->dev); |
760 | if (ret < 0) |
761 | return ret; |
762 | |
763 | netif_carrier_off(dev: ndev); |
764 | |
765 | /* Notify the stack of the actual queue counts. */ |
766 | ret = netif_set_real_num_tx_queues(dev: ndev, txq: cpsw->tx_ch_num); |
767 | if (ret) { |
768 | dev_err(priv->dev, "cannot set real number of tx queues\n" ); |
769 | goto err_cleanup; |
770 | } |
771 | |
772 | ret = netif_set_real_num_rx_queues(dev: ndev, rxq: cpsw->rx_ch_num); |
773 | if (ret) { |
774 | dev_err(priv->dev, "cannot set real number of rx queues\n" ); |
775 | goto err_cleanup; |
776 | } |
777 | |
778 | reg = cpsw->version; |
779 | |
780 | dev_info(priv->dev, "initializing cpsw version %d.%d (%d)\n" , |
781 | CPSW_MAJOR_VERSION(reg), CPSW_MINOR_VERSION(reg), |
782 | CPSW_RTL_VERSION(reg)); |
783 | |
784 | /* Initialize host and slave ports */ |
785 | if (!cpsw->usage_count) |
786 | cpsw_init_host_port(priv); |
787 | for_each_slave(priv, cpsw_slave_open, priv); |
788 | |
789 | /* Add default VLAN */ |
790 | if (!cpsw->data.dual_emac) |
791 | cpsw_add_default_vlan(priv); |
792 | else |
793 | cpsw_ale_add_vlan(ale: cpsw->ale, vid: cpsw->data.default_vlan, |
794 | ALE_ALL_PORTS, ALE_ALL_PORTS, reg_mcast: 0, unreg_mcast: 0); |
795 | |
796 | /* initialize shared resources for every ndev */ |
797 | if (!cpsw->usage_count) { |
798 | /* disable priority elevation */ |
799 | writel_relaxed(0, &cpsw->regs->ptype); |
800 | |
801 | /* enable statistics collection only on all ports */ |
802 | writel_relaxed(0x7, &cpsw->regs->stat_port_en); |
803 | |
804 | /* Enable internal fifo flow control */ |
805 | writel(val: 0x7, addr: &cpsw->regs->flow_control); |
806 | |
807 | napi_enable(n: &cpsw->napi_rx); |
808 | napi_enable(n: &cpsw->napi_tx); |
809 | |
810 | if (cpsw->tx_irq_disabled) { |
811 | cpsw->tx_irq_disabled = false; |
812 | enable_irq(irq: cpsw->irqs_table[1]); |
813 | } |
814 | |
815 | if (cpsw->rx_irq_disabled) { |
816 | cpsw->rx_irq_disabled = false; |
817 | enable_irq(irq: cpsw->irqs_table[0]); |
818 | } |
819 | |
820 | /* create rxqs for both infs in dual mac as they use same pool |
821 | * and must be destroyed together when no users. |
822 | */ |
823 | ret = cpsw_create_xdp_rxqs(cpsw); |
824 | if (ret < 0) |
825 | goto err_cleanup; |
826 | |
827 | ret = cpsw_fill_rx_channels(priv); |
828 | if (ret < 0) |
829 | goto err_cleanup; |
830 | |
831 | if (cpsw->cpts) { |
832 | if (cpts_register(cpts: cpsw->cpts)) |
833 | dev_err(priv->dev, "error registering cpts device\n" ); |
834 | else |
835 | writel(val: 0x10, addr: &cpsw->wr_regs->misc_en); |
836 | } |
837 | } |
838 | |
839 | cpsw_restore(priv); |
840 | |
841 | /* Enable Interrupt pacing if configured */ |
842 | if (cpsw->coal_intvl != 0) { |
843 | struct ethtool_coalesce coal; |
844 | |
845 | coal.rx_coalesce_usecs = cpsw->coal_intvl; |
846 | cpsw_set_coalesce(ndev, coal: &coal, NULL, NULL); |
847 | } |
848 | |
849 | cpdma_ctlr_start(ctlr: cpsw->dma); |
850 | cpsw_intr_enable(cpsw); |
851 | cpsw->usage_count++; |
852 | |
853 | return 0; |
854 | |
855 | err_cleanup: |
856 | if (!cpsw->usage_count) { |
857 | napi_disable(n: &cpsw->napi_rx); |
858 | napi_disable(n: &cpsw->napi_tx); |
859 | cpdma_ctlr_stop(ctlr: cpsw->dma); |
860 | cpsw_destroy_xdp_rxqs(cpsw); |
861 | } |
862 | |
863 | for_each_slave(priv, cpsw_slave_stop, cpsw); |
864 | pm_runtime_put_sync(dev: cpsw->dev); |
865 | netif_carrier_off(dev: priv->ndev); |
866 | return ret; |
867 | } |
868 | |
869 | static int cpsw_ndo_stop(struct net_device *ndev) |
870 | { |
871 | struct cpsw_priv *priv = netdev_priv(dev: ndev); |
872 | struct cpsw_common *cpsw = priv->cpsw; |
873 | |
874 | cpsw_info(priv, ifdown, "shutting down cpsw device\n" ); |
875 | __hw_addr_ref_unsync_dev(list: &ndev->mc, dev: ndev, unsync: cpsw_purge_all_mc); |
876 | netif_tx_stop_all_queues(dev: priv->ndev); |
877 | netif_carrier_off(dev: priv->ndev); |
878 | |
879 | if (cpsw->usage_count <= 1) { |
880 | napi_disable(n: &cpsw->napi_rx); |
881 | napi_disable(n: &cpsw->napi_tx); |
882 | cpts_unregister(cpts: cpsw->cpts); |
883 | cpsw_intr_disable(cpsw); |
884 | cpdma_ctlr_stop(ctlr: cpsw->dma); |
885 | cpsw_ale_stop(ale: cpsw->ale); |
886 | cpsw_destroy_xdp_rxqs(cpsw); |
887 | } |
888 | for_each_slave(priv, cpsw_slave_stop, cpsw); |
889 | |
890 | if (cpsw_need_resplit(cpsw)) |
891 | cpsw_split_res(cpsw); |
892 | |
893 | cpsw->usage_count--; |
894 | pm_runtime_put_sync(dev: cpsw->dev); |
895 | return 0; |
896 | } |
897 | |
898 | static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb, |
899 | struct net_device *ndev) |
900 | { |
901 | struct cpsw_priv *priv = netdev_priv(dev: ndev); |
902 | struct cpsw_common *cpsw = priv->cpsw; |
903 | struct cpts *cpts = cpsw->cpts; |
904 | struct netdev_queue *txq; |
905 | struct cpdma_chan *txch; |
906 | int ret, q_idx; |
907 | |
908 | if (skb_put_padto(skb, CPSW_MIN_PACKET_SIZE)) { |
909 | cpsw_err(priv, tx_err, "packet pad failed\n" ); |
910 | ndev->stats.tx_dropped++; |
911 | return NET_XMIT_DROP; |
912 | } |
913 | |
914 | if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && |
915 | priv->tx_ts_enabled && cpts_can_timestamp(cpts, skb)) |
916 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; |
917 | |
918 | q_idx = skb_get_queue_mapping(skb); |
919 | if (q_idx >= cpsw->tx_ch_num) |
920 | q_idx = q_idx % cpsw->tx_ch_num; |
921 | |
922 | txch = cpsw->txv[q_idx].ch; |
923 | txq = netdev_get_tx_queue(dev: ndev, index: q_idx); |
924 | skb_tx_timestamp(skb); |
925 | ret = cpdma_chan_submit(chan: txch, token: skb, data: skb->data, len: skb->len, |
926 | directed: priv->emac_port + cpsw->data.dual_emac); |
927 | if (unlikely(ret != 0)) { |
928 | cpsw_err(priv, tx_err, "desc submit failed\n" ); |
929 | goto fail; |
930 | } |
931 | |
932 | /* If there is no more tx desc left free then we need to |
933 | * tell the kernel to stop sending us tx frames. |
934 | */ |
935 | if (unlikely(!cpdma_check_free_tx_desc(txch))) { |
936 | netif_tx_stop_queue(dev_queue: txq); |
937 | |
938 | /* Barrier, so that stop_queue visible to other cpus */ |
939 | smp_mb__after_atomic(); |
940 | |
941 | if (cpdma_check_free_tx_desc(chan: txch)) |
942 | netif_tx_wake_queue(dev_queue: txq); |
943 | } |
944 | |
945 | return NETDEV_TX_OK; |
946 | fail: |
947 | ndev->stats.tx_dropped++; |
948 | netif_tx_stop_queue(dev_queue: txq); |
949 | |
950 | /* Barrier, so that stop_queue visible to other cpus */ |
951 | smp_mb__after_atomic(); |
952 | |
953 | if (cpdma_check_free_tx_desc(chan: txch)) |
954 | netif_tx_wake_queue(dev_queue: txq); |
955 | |
956 | return NETDEV_TX_BUSY; |
957 | } |
958 | |
959 | static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) |
960 | { |
961 | struct cpsw_priv *priv = netdev_priv(dev: ndev); |
962 | struct sockaddr *addr = (struct sockaddr *)p; |
963 | struct cpsw_common *cpsw = priv->cpsw; |
964 | int flags = 0; |
965 | u16 vid = 0; |
966 | int ret; |
967 | |
968 | if (!is_valid_ether_addr(addr: addr->sa_data)) |
969 | return -EADDRNOTAVAIL; |
970 | |
971 | ret = pm_runtime_resume_and_get(dev: cpsw->dev); |
972 | if (ret < 0) |
973 | return ret; |
974 | |
975 | if (cpsw->data.dual_emac) { |
976 | vid = cpsw->slaves[priv->emac_port].port_vlan; |
977 | flags = ALE_VLAN; |
978 | } |
979 | |
980 | cpsw_ale_del_ucast(ale: cpsw->ale, addr: priv->mac_addr, HOST_PORT_NUM, |
981 | flags, vid); |
982 | cpsw_ale_add_ucast(ale: cpsw->ale, addr: addr->sa_data, HOST_PORT_NUM, |
983 | flags, vid); |
984 | |
985 | memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); |
986 | eth_hw_addr_set(dev: ndev, addr: priv->mac_addr); |
987 | for_each_slave(priv, cpsw_set_slave_mac, priv); |
988 | |
989 | pm_runtime_put(dev: cpsw->dev); |
990 | |
991 | return 0; |
992 | } |
993 | |
994 | static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, |
995 | unsigned short vid) |
996 | { |
997 | int ret; |
998 | int unreg_mcast_mask = 0; |
999 | int mcast_mask; |
1000 | u32 port_mask; |
1001 | struct cpsw_common *cpsw = priv->cpsw; |
1002 | |
1003 | if (cpsw->data.dual_emac) { |
1004 | port_mask = (1 << (priv->emac_port + 1)) | ALE_PORT_HOST; |
1005 | |
1006 | mcast_mask = ALE_PORT_HOST; |
1007 | if (priv->ndev->flags & IFF_ALLMULTI) |
1008 | unreg_mcast_mask = mcast_mask; |
1009 | } else { |
1010 | port_mask = ALE_ALL_PORTS; |
1011 | mcast_mask = port_mask; |
1012 | |
1013 | if (priv->ndev->flags & IFF_ALLMULTI) |
1014 | unreg_mcast_mask = ALE_ALL_PORTS; |
1015 | else |
1016 | unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; |
1017 | } |
1018 | |
1019 | ret = cpsw_ale_add_vlan(ale: cpsw->ale, vid, port: port_mask, untag: 0, reg_mcast: port_mask, |
1020 | unreg_mcast: unreg_mcast_mask); |
1021 | if (ret != 0) |
1022 | return ret; |
1023 | |
1024 | ret = cpsw_ale_add_ucast(ale: cpsw->ale, addr: priv->mac_addr, |
1025 | HOST_PORT_NUM, ALE_VLAN, vid); |
1026 | if (ret != 0) |
1027 | goto clean_vid; |
1028 | |
1029 | ret = cpsw_ale_add_mcast(ale: cpsw->ale, addr: priv->ndev->broadcast, |
1030 | port_mask: mcast_mask, ALE_VLAN, vid, mcast_state: 0); |
1031 | if (ret != 0) |
1032 | goto clean_vlan_ucast; |
1033 | return 0; |
1034 | |
1035 | clean_vlan_ucast: |
1036 | cpsw_ale_del_ucast(ale: cpsw->ale, addr: priv->mac_addr, |
1037 | HOST_PORT_NUM, ALE_VLAN, vid); |
1038 | clean_vid: |
1039 | cpsw_ale_del_vlan(ale: cpsw->ale, vid, port: 0); |
1040 | return ret; |
1041 | } |
1042 | |
1043 | static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev, |
1044 | __be16 proto, u16 vid) |
1045 | { |
1046 | struct cpsw_priv *priv = netdev_priv(dev: ndev); |
1047 | struct cpsw_common *cpsw = priv->cpsw; |
1048 | int ret; |
1049 | |
1050 | if (vid == cpsw->data.default_vlan) |
1051 | return 0; |
1052 | |
1053 | ret = pm_runtime_resume_and_get(dev: cpsw->dev); |
1054 | if (ret < 0) |
1055 | return ret; |
1056 | |
1057 | if (cpsw->data.dual_emac) { |
1058 | /* In dual EMAC, reserved VLAN id should not be used for |
1059 | * creating VLAN interfaces as this can break the dual |
1060 | * EMAC port separation |
1061 | */ |
1062 | int i; |
1063 | |
1064 | for (i = 0; i < cpsw->data.slaves; i++) { |
1065 | if (vid == cpsw->slaves[i].port_vlan) { |
1066 | ret = -EINVAL; |
1067 | goto err; |
1068 | } |
1069 | } |
1070 | } |
1071 | |
1072 | dev_info(priv->dev, "Adding vlanid %d to vlan filter\n" , vid); |
1073 | ret = cpsw_add_vlan_ale_entry(priv, vid); |
1074 | err: |
1075 | pm_runtime_put(dev: cpsw->dev); |
1076 | return ret; |
1077 | } |
1078 | |
1079 | static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev, |
1080 | __be16 proto, u16 vid) |
1081 | { |
1082 | struct cpsw_priv *priv = netdev_priv(dev: ndev); |
1083 | struct cpsw_common *cpsw = priv->cpsw; |
1084 | int ret; |
1085 | |
1086 | if (vid == cpsw->data.default_vlan) |
1087 | return 0; |
1088 | |
1089 | ret = pm_runtime_resume_and_get(dev: cpsw->dev); |
1090 | if (ret < 0) |
1091 | return ret; |
1092 | |
1093 | if (cpsw->data.dual_emac) { |
1094 | int i; |
1095 | |
1096 | for (i = 0; i < cpsw->data.slaves; i++) { |
1097 | if (vid == cpsw->slaves[i].port_vlan) |
1098 | goto err; |
1099 | } |
1100 | } |
1101 | |
1102 | dev_info(priv->dev, "removing vlanid %d from vlan filter\n" , vid); |
1103 | ret = cpsw_ale_del_vlan(ale: cpsw->ale, vid, port: 0); |
1104 | ret |= cpsw_ale_del_ucast(ale: cpsw->ale, addr: priv->mac_addr, |
1105 | HOST_PORT_NUM, ALE_VLAN, vid); |
1106 | ret |= cpsw_ale_del_mcast(ale: cpsw->ale, addr: priv->ndev->broadcast, |
1107 | port_mask: 0, ALE_VLAN, vid); |
1108 | ret |= cpsw_ale_flush_multicast(ale: cpsw->ale, ALE_PORT_HOST, vid); |
1109 | err: |
1110 | pm_runtime_put(dev: cpsw->dev); |
1111 | return ret; |
1112 | } |
1113 | |
1114 | static int cpsw_ndo_xdp_xmit(struct net_device *ndev, int n, |
1115 | struct xdp_frame **frames, u32 flags) |
1116 | { |
1117 | struct cpsw_priv *priv = netdev_priv(dev: ndev); |
1118 | struct cpsw_common *cpsw = priv->cpsw; |
1119 | struct xdp_frame *xdpf; |
1120 | int i, nxmit = 0, port; |
1121 | |
1122 | if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) |
1123 | return -EINVAL; |
1124 | |
1125 | for (i = 0; i < n; i++) { |
1126 | xdpf = frames[i]; |
1127 | if (xdpf->len < CPSW_MIN_PACKET_SIZE) |
1128 | break; |
1129 | |
1130 | port = priv->emac_port + cpsw->data.dual_emac; |
1131 | if (cpsw_xdp_tx_frame(priv, xdpf, NULL, port)) |
1132 | break; |
1133 | nxmit++; |
1134 | } |
1135 | |
1136 | return nxmit; |
1137 | } |
1138 | |
1139 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1140 | static void cpsw_ndo_poll_controller(struct net_device *ndev) |
1141 | { |
1142 | struct cpsw_common *cpsw = ndev_to_cpsw(ndev); |
1143 | |
1144 | cpsw_intr_disable(cpsw); |
1145 | cpsw_rx_interrupt(irq: cpsw->irqs_table[0], dev_id: cpsw); |
1146 | cpsw_tx_interrupt(irq: cpsw->irqs_table[1], dev_id: cpsw); |
1147 | cpsw_intr_enable(cpsw); |
1148 | } |
1149 | #endif |
1150 | |
1151 | static const struct net_device_ops cpsw_netdev_ops = { |
1152 | .ndo_open = cpsw_ndo_open, |
1153 | .ndo_stop = cpsw_ndo_stop, |
1154 | .ndo_start_xmit = cpsw_ndo_start_xmit, |
1155 | .ndo_set_mac_address = cpsw_ndo_set_mac_address, |
1156 | .ndo_eth_ioctl = cpsw_ndo_ioctl, |
1157 | .ndo_validate_addr = eth_validate_addr, |
1158 | .ndo_tx_timeout = cpsw_ndo_tx_timeout, |
1159 | .ndo_set_rx_mode = cpsw_ndo_set_rx_mode, |
1160 | .ndo_set_tx_maxrate = cpsw_ndo_set_tx_maxrate, |
1161 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1162 | .ndo_poll_controller = cpsw_ndo_poll_controller, |
1163 | #endif |
1164 | .ndo_vlan_rx_add_vid = cpsw_ndo_vlan_rx_add_vid, |
1165 | .ndo_vlan_rx_kill_vid = cpsw_ndo_vlan_rx_kill_vid, |
1166 | .ndo_setup_tc = cpsw_ndo_setup_tc, |
1167 | .ndo_bpf = cpsw_ndo_bpf, |
1168 | .ndo_xdp_xmit = cpsw_ndo_xdp_xmit, |
1169 | }; |
1170 | |
1171 | static void cpsw_get_drvinfo(struct net_device *ndev, |
1172 | struct ethtool_drvinfo *info) |
1173 | { |
1174 | struct cpsw_common *cpsw = ndev_to_cpsw(ndev); |
1175 | struct platform_device *pdev = to_platform_device(cpsw->dev); |
1176 | |
1177 | strscpy(p: info->driver, q: "cpsw" , size: sizeof(info->driver)); |
1178 | strscpy(p: info->version, q: "1.0" , size: sizeof(info->version)); |
1179 | strscpy(p: info->bus_info, q: pdev->name, size: sizeof(info->bus_info)); |
1180 | } |
1181 | |
1182 | static int cpsw_set_pauseparam(struct net_device *ndev, |
1183 | struct ethtool_pauseparam *pause) |
1184 | { |
1185 | struct cpsw_priv *priv = netdev_priv(dev: ndev); |
1186 | bool link; |
1187 | |
1188 | priv->rx_pause = pause->rx_pause ? true : false; |
1189 | priv->tx_pause = pause->tx_pause ? true : false; |
1190 | |
1191 | for_each_slave(priv, _cpsw_adjust_link, priv, &link); |
1192 | return 0; |
1193 | } |
1194 | |
1195 | static int cpsw_set_channels(struct net_device *ndev, |
1196 | struct ethtool_channels *chs) |
1197 | { |
1198 | return cpsw_set_channels_common(ndev, chs, rx_handler: cpsw_rx_handler); |
1199 | } |
1200 | |
1201 | static const struct ethtool_ops cpsw_ethtool_ops = { |
1202 | .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS, |
1203 | .get_drvinfo = cpsw_get_drvinfo, |
1204 | .get_msglevel = cpsw_get_msglevel, |
1205 | .set_msglevel = cpsw_set_msglevel, |
1206 | .get_link = ethtool_op_get_link, |
1207 | .get_ts_info = cpsw_get_ts_info, |
1208 | .get_coalesce = cpsw_get_coalesce, |
1209 | .set_coalesce = cpsw_set_coalesce, |
1210 | .get_sset_count = cpsw_get_sset_count, |
1211 | .get_strings = cpsw_get_strings, |
1212 | .get_ethtool_stats = cpsw_get_ethtool_stats, |
1213 | .get_pauseparam = cpsw_get_pauseparam, |
1214 | .set_pauseparam = cpsw_set_pauseparam, |
1215 | .get_wol = cpsw_get_wol, |
1216 | .set_wol = cpsw_set_wol, |
1217 | .get_regs_len = cpsw_get_regs_len, |
1218 | .get_regs = cpsw_get_regs, |
1219 | .begin = cpsw_ethtool_op_begin, |
1220 | .complete = cpsw_ethtool_op_complete, |
1221 | .get_channels = cpsw_get_channels, |
1222 | .set_channels = cpsw_set_channels, |
1223 | .get_link_ksettings = cpsw_get_link_ksettings, |
1224 | .set_link_ksettings = cpsw_set_link_ksettings, |
1225 | .get_eee = cpsw_get_eee, |
1226 | .set_eee = cpsw_set_eee, |
1227 | .nway_reset = cpsw_nway_reset, |
1228 | .get_ringparam = cpsw_get_ringparam, |
1229 | .set_ringparam = cpsw_set_ringparam, |
1230 | }; |
1231 | |
1232 | static int cpsw_probe_dt(struct cpsw_platform_data *data, |
1233 | struct platform_device *pdev) |
1234 | { |
1235 | struct device_node *node = pdev->dev.of_node; |
1236 | struct device_node *slave_node; |
1237 | int i = 0, ret; |
1238 | u32 prop; |
1239 | |
1240 | if (!node) |
1241 | return -EINVAL; |
1242 | |
1243 | if (of_property_read_u32(np: node, propname: "slaves" , out_value: &prop)) { |
1244 | dev_err(&pdev->dev, "Missing slaves property in the DT.\n" ); |
1245 | return -EINVAL; |
1246 | } |
1247 | data->slaves = prop; |
1248 | |
1249 | if (of_property_read_u32(np: node, propname: "active_slave" , out_value: &prop)) { |
1250 | dev_err(&pdev->dev, "Missing active_slave property in the DT.\n" ); |
1251 | return -EINVAL; |
1252 | } |
1253 | data->active_slave = prop; |
1254 | |
1255 | data->slave_data = devm_kcalloc(dev: &pdev->dev, |
1256 | n: data->slaves, |
1257 | size: sizeof(struct cpsw_slave_data), |
1258 | GFP_KERNEL); |
1259 | if (!data->slave_data) |
1260 | return -ENOMEM; |
1261 | |
1262 | if (of_property_read_u32(np: node, propname: "cpdma_channels" , out_value: &prop)) { |
1263 | dev_err(&pdev->dev, "Missing cpdma_channels property in the DT.\n" ); |
1264 | return -EINVAL; |
1265 | } |
1266 | data->channels = prop; |
1267 | |
1268 | if (of_property_read_u32(np: node, propname: "bd_ram_size" , out_value: &prop)) { |
1269 | dev_err(&pdev->dev, "Missing bd_ram_size property in the DT.\n" ); |
1270 | return -EINVAL; |
1271 | } |
1272 | data->bd_ram_size = prop; |
1273 | |
1274 | if (of_property_read_u32(np: node, propname: "mac_control" , out_value: &prop)) { |
1275 | dev_err(&pdev->dev, "Missing mac_control property in the DT.\n" ); |
1276 | return -EINVAL; |
1277 | } |
1278 | data->mac_control = prop; |
1279 | |
1280 | if (of_property_read_bool(np: node, propname: "dual_emac" )) |
1281 | data->dual_emac = true; |
1282 | |
1283 | /* |
1284 | * Populate all the child nodes here... |
1285 | */ |
1286 | ret = of_platform_populate(root: node, NULL, NULL, parent: &pdev->dev); |
1287 | /* We do not want to force this, as in some cases may not have child */ |
1288 | if (ret) |
1289 | dev_warn(&pdev->dev, "Doesn't have any child node\n" ); |
1290 | |
1291 | for_each_available_child_of_node(node, slave_node) { |
1292 | struct cpsw_slave_data *slave_data = data->slave_data + i; |
1293 | int lenp; |
1294 | const __be32 *parp; |
1295 | |
1296 | /* This is no slave child node, continue */ |
1297 | if (!of_node_name_eq(np: slave_node, name: "slave" )) |
1298 | continue; |
1299 | |
1300 | slave_data->ifphy = devm_of_phy_get(dev: &pdev->dev, np: slave_node, |
1301 | NULL); |
1302 | if (!IS_ENABLED(CONFIG_TI_CPSW_PHY_SEL) && |
1303 | IS_ERR(ptr: slave_data->ifphy)) { |
1304 | ret = PTR_ERR(ptr: slave_data->ifphy); |
1305 | dev_err(&pdev->dev, |
1306 | "%d: Error retrieving port phy: %d\n" , i, ret); |
1307 | goto err_node_put; |
1308 | } |
1309 | |
1310 | slave_data->slave_node = slave_node; |
1311 | slave_data->phy_node = of_parse_phandle(np: slave_node, |
1312 | phandle_name: "phy-handle" , index: 0); |
1313 | parp = of_get_property(node: slave_node, name: "phy_id" , lenp: &lenp); |
1314 | if (slave_data->phy_node) { |
1315 | dev_dbg(&pdev->dev, |
1316 | "slave[%d] using phy-handle=\"%pOF\"\n" , |
1317 | i, slave_data->phy_node); |
1318 | } else if (of_phy_is_fixed_link(np: slave_node)) { |
1319 | /* In the case of a fixed PHY, the DT node associated |
1320 | * to the PHY is the Ethernet MAC DT node. |
1321 | */ |
1322 | ret = of_phy_register_fixed_link(np: slave_node); |
1323 | if (ret) { |
1324 | dev_err_probe(dev: &pdev->dev, err: ret, fmt: "failed to register fixed-link phy\n" ); |
1325 | goto err_node_put; |
1326 | } |
1327 | slave_data->phy_node = of_node_get(node: slave_node); |
1328 | } else if (parp) { |
1329 | u32 phyid; |
1330 | struct device_node *mdio_node; |
1331 | struct platform_device *mdio; |
1332 | |
1333 | if (lenp != (sizeof(__be32) * 2)) { |
1334 | dev_err(&pdev->dev, "Invalid slave[%d] phy_id property\n" , i); |
1335 | goto no_phy_slave; |
1336 | } |
1337 | mdio_node = of_find_node_by_phandle(be32_to_cpup(p: parp)); |
1338 | phyid = be32_to_cpup(p: parp+1); |
1339 | mdio = of_find_device_by_node(np: mdio_node); |
1340 | of_node_put(node: mdio_node); |
1341 | if (!mdio) { |
1342 | dev_err(&pdev->dev, "Missing mdio platform device\n" ); |
1343 | ret = -EINVAL; |
1344 | goto err_node_put; |
1345 | } |
1346 | snprintf(buf: slave_data->phy_id, size: sizeof(slave_data->phy_id), |
1347 | PHY_ID_FMT, mdio->name, phyid); |
1348 | put_device(dev: &mdio->dev); |
1349 | } else { |
1350 | dev_err(&pdev->dev, |
1351 | "No slave[%d] phy_id, phy-handle, or fixed-link property\n" , |
1352 | i); |
1353 | goto no_phy_slave; |
1354 | } |
1355 | ret = of_get_phy_mode(np: slave_node, interface: &slave_data->phy_if); |
1356 | if (ret) { |
1357 | dev_err(&pdev->dev, "Missing or malformed slave[%d] phy-mode property\n" , |
1358 | i); |
1359 | goto err_node_put; |
1360 | } |
1361 | |
1362 | no_phy_slave: |
1363 | ret = of_get_mac_address(np: slave_node, mac: slave_data->mac_addr); |
1364 | if (ret) { |
1365 | ret = ti_cm_get_macid(dev: &pdev->dev, slave: i, |
1366 | mac_addr: slave_data->mac_addr); |
1367 | if (ret) |
1368 | goto err_node_put; |
1369 | } |
1370 | if (data->dual_emac) { |
1371 | if (of_property_read_u32(np: slave_node, propname: "dual_emac_res_vlan" , |
1372 | out_value: &prop)) { |
1373 | dev_err(&pdev->dev, "Missing dual_emac_res_vlan in DT.\n" ); |
1374 | slave_data->dual_emac_res_vlan = i+1; |
1375 | dev_err(&pdev->dev, "Using %d as Reserved VLAN for %d slave\n" , |
1376 | slave_data->dual_emac_res_vlan, i); |
1377 | } else { |
1378 | slave_data->dual_emac_res_vlan = prop; |
1379 | } |
1380 | } |
1381 | |
1382 | i++; |
1383 | if (i == data->slaves) { |
1384 | ret = 0; |
1385 | goto err_node_put; |
1386 | } |
1387 | } |
1388 | |
1389 | return 0; |
1390 | |
1391 | err_node_put: |
1392 | of_node_put(node: slave_node); |
1393 | return ret; |
1394 | } |
1395 | |
1396 | static void cpsw_remove_dt(struct platform_device *pdev) |
1397 | { |
1398 | struct cpsw_common *cpsw = platform_get_drvdata(pdev); |
1399 | struct cpsw_platform_data *data = &cpsw->data; |
1400 | struct device_node *node = pdev->dev.of_node; |
1401 | struct device_node *slave_node; |
1402 | int i = 0; |
1403 | |
1404 | for_each_available_child_of_node(node, slave_node) { |
1405 | struct cpsw_slave_data *slave_data = &data->slave_data[i]; |
1406 | |
1407 | if (!of_node_name_eq(np: slave_node, name: "slave" )) |
1408 | continue; |
1409 | |
1410 | if (of_phy_is_fixed_link(np: slave_node)) |
1411 | of_phy_deregister_fixed_link(np: slave_node); |
1412 | |
1413 | of_node_put(node: slave_data->phy_node); |
1414 | |
1415 | i++; |
1416 | if (i == data->slaves) { |
1417 | of_node_put(node: slave_node); |
1418 | break; |
1419 | } |
1420 | } |
1421 | |
1422 | of_platform_depopulate(parent: &pdev->dev); |
1423 | } |
1424 | |
1425 | static int cpsw_probe_dual_emac(struct cpsw_priv *priv) |
1426 | { |
1427 | struct cpsw_common *cpsw = priv->cpsw; |
1428 | struct cpsw_platform_data *data = &cpsw->data; |
1429 | struct net_device *ndev; |
1430 | struct cpsw_priv *priv_sl2; |
1431 | int ret = 0; |
1432 | |
1433 | ndev = devm_alloc_etherdev_mqs(dev: cpsw->dev, sizeof_priv: sizeof(struct cpsw_priv), |
1434 | CPSW_MAX_QUEUES, CPSW_MAX_QUEUES); |
1435 | if (!ndev) { |
1436 | dev_err(cpsw->dev, "cpsw: error allocating net_device\n" ); |
1437 | return -ENOMEM; |
1438 | } |
1439 | |
1440 | priv_sl2 = netdev_priv(dev: ndev); |
1441 | priv_sl2->cpsw = cpsw; |
1442 | priv_sl2->ndev = ndev; |
1443 | priv_sl2->dev = &ndev->dev; |
1444 | priv_sl2->msg_enable = netif_msg_init(debug_value: debug_level, CPSW_DEBUG); |
1445 | |
1446 | if (is_valid_ether_addr(addr: data->slave_data[1].mac_addr)) { |
1447 | memcpy(priv_sl2->mac_addr, data->slave_data[1].mac_addr, |
1448 | ETH_ALEN); |
1449 | dev_info(cpsw->dev, "cpsw: Detected MACID = %pM\n" , |
1450 | priv_sl2->mac_addr); |
1451 | } else { |
1452 | eth_random_addr(addr: priv_sl2->mac_addr); |
1453 | dev_info(cpsw->dev, "cpsw: Random MACID = %pM\n" , |
1454 | priv_sl2->mac_addr); |
1455 | } |
1456 | eth_hw_addr_set(dev: ndev, addr: priv_sl2->mac_addr); |
1457 | |
1458 | priv_sl2->emac_port = 1; |
1459 | cpsw->slaves[1].ndev = ndev; |
1460 | ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX; |
1461 | ndev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT | |
1462 | NETDEV_XDP_ACT_NDO_XMIT; |
1463 | |
1464 | ndev->netdev_ops = &cpsw_netdev_ops; |
1465 | ndev->ethtool_ops = &cpsw_ethtool_ops; |
1466 | |
1467 | /* register the network device */ |
1468 | SET_NETDEV_DEV(ndev, cpsw->dev); |
1469 | ndev->dev.of_node = cpsw->slaves[1].data->slave_node; |
1470 | ret = register_netdev(dev: ndev); |
1471 | if (ret) |
1472 | dev_err(cpsw->dev, "cpsw: error registering net device\n" ); |
1473 | |
1474 | return ret; |
1475 | } |
1476 | |
1477 | static const struct of_device_id cpsw_of_mtable[] = { |
1478 | { .compatible = "ti,cpsw" }, |
1479 | { .compatible = "ti,am335x-cpsw" }, |
1480 | { .compatible = "ti,am4372-cpsw" }, |
1481 | { .compatible = "ti,dra7-cpsw" }, |
1482 | { /* sentinel */ }, |
1483 | }; |
1484 | MODULE_DEVICE_TABLE(of, cpsw_of_mtable); |
1485 | |
1486 | static const struct soc_device_attribute cpsw_soc_devices[] = { |
1487 | { .family = "AM33xx" , .revision = "ES1.0" }, |
1488 | { /* sentinel */ } |
1489 | }; |
1490 | |
1491 | static int cpsw_probe(struct platform_device *pdev) |
1492 | { |
1493 | struct device *dev = &pdev->dev; |
1494 | struct clk *clk; |
1495 | struct cpsw_platform_data *data; |
1496 | struct net_device *ndev; |
1497 | struct cpsw_priv *priv; |
1498 | void __iomem *ss_regs; |
1499 | struct resource *ss_res; |
1500 | struct gpio_descs *mode; |
1501 | const struct soc_device_attribute *soc; |
1502 | struct cpsw_common *cpsw; |
1503 | int ret = 0, ch; |
1504 | int irq; |
1505 | |
1506 | cpsw = devm_kzalloc(dev, size: sizeof(struct cpsw_common), GFP_KERNEL); |
1507 | if (!cpsw) |
1508 | return -ENOMEM; |
1509 | |
1510 | platform_set_drvdata(pdev, data: cpsw); |
1511 | cpsw_slave_index = cpsw_slave_index_priv; |
1512 | |
1513 | cpsw->dev = dev; |
1514 | |
1515 | mode = devm_gpiod_get_array_optional(dev, con_id: "mode" , flags: GPIOD_OUT_LOW); |
1516 | if (IS_ERR(ptr: mode)) { |
1517 | ret = PTR_ERR(ptr: mode); |
1518 | dev_err(dev, "gpio request failed, ret %d\n" , ret); |
1519 | return ret; |
1520 | } |
1521 | |
1522 | clk = devm_clk_get(dev, id: "fck" ); |
1523 | if (IS_ERR(ptr: clk)) { |
1524 | ret = PTR_ERR(ptr: clk); |
1525 | dev_err(dev, "fck is not found %d\n" , ret); |
1526 | return ret; |
1527 | } |
1528 | cpsw->bus_freq_mhz = clk_get_rate(clk) / 1000000; |
1529 | |
1530 | ss_regs = devm_platform_get_and_ioremap_resource(pdev, index: 0, res: &ss_res); |
1531 | if (IS_ERR(ptr: ss_regs)) |
1532 | return PTR_ERR(ptr: ss_regs); |
1533 | cpsw->regs = ss_regs; |
1534 | |
1535 | cpsw->wr_regs = devm_platform_ioremap_resource(pdev, index: 1); |
1536 | if (IS_ERR(ptr: cpsw->wr_regs)) |
1537 | return PTR_ERR(ptr: cpsw->wr_regs); |
1538 | |
1539 | /* RX IRQ */ |
1540 | irq = platform_get_irq(pdev, 1); |
1541 | if (irq < 0) |
1542 | return irq; |
1543 | cpsw->irqs_table[0] = irq; |
1544 | |
1545 | /* TX IRQ */ |
1546 | irq = platform_get_irq(pdev, 2); |
1547 | if (irq < 0) |
1548 | return irq; |
1549 | cpsw->irqs_table[1] = irq; |
1550 | |
1551 | /* get misc irq*/ |
1552 | irq = platform_get_irq(pdev, 3); |
1553 | if (irq <= 0) |
1554 | return irq; |
1555 | cpsw->misc_irq = irq; |
1556 | |
1557 | /* |
1558 | * This may be required here for child devices. |
1559 | */ |
1560 | pm_runtime_enable(dev); |
1561 | |
1562 | /* Need to enable clocks with runtime PM api to access module |
1563 | * registers |
1564 | */ |
1565 | ret = pm_runtime_resume_and_get(dev); |
1566 | if (ret < 0) |
1567 | goto clean_runtime_disable_ret; |
1568 | |
1569 | ret = cpsw_probe_dt(data: &cpsw->data, pdev); |
1570 | if (ret) |
1571 | goto clean_dt_ret; |
1572 | |
1573 | soc = soc_device_match(matches: cpsw_soc_devices); |
1574 | if (soc) |
1575 | cpsw->quirk_irq = true; |
1576 | |
1577 | data = &cpsw->data; |
1578 | cpsw->slaves = devm_kcalloc(dev, |
1579 | n: data->slaves, size: sizeof(struct cpsw_slave), |
1580 | GFP_KERNEL); |
1581 | if (!cpsw->slaves) { |
1582 | ret = -ENOMEM; |
1583 | goto clean_dt_ret; |
1584 | } |
1585 | |
1586 | cpsw->rx_packet_max = max(rx_packet_max, CPSW_MAX_PACKET_SIZE); |
1587 | cpsw->descs_pool_size = descs_pool_size; |
1588 | |
1589 | ret = cpsw_init_common(cpsw, ss_regs, ale_ageout, |
1590 | desc_mem_phys: ss_res->start + CPSW2_BD_OFFSET, |
1591 | descs_pool_size); |
1592 | if (ret) |
1593 | goto clean_dt_ret; |
1594 | |
1595 | ch = cpsw->quirk_irq ? 0 : 7; |
1596 | cpsw->txv[0].ch = cpdma_chan_create(ctlr: cpsw->dma, chan_num: ch, handler: cpsw_tx_handler, rx_type: 0); |
1597 | if (IS_ERR(ptr: cpsw->txv[0].ch)) { |
1598 | dev_err(dev, "error initializing tx dma channel\n" ); |
1599 | ret = PTR_ERR(ptr: cpsw->txv[0].ch); |
1600 | goto clean_cpts; |
1601 | } |
1602 | |
1603 | cpsw->rxv[0].ch = cpdma_chan_create(ctlr: cpsw->dma, chan_num: 0, handler: cpsw_rx_handler, rx_type: 1); |
1604 | if (IS_ERR(ptr: cpsw->rxv[0].ch)) { |
1605 | dev_err(dev, "error initializing rx dma channel\n" ); |
1606 | ret = PTR_ERR(ptr: cpsw->rxv[0].ch); |
1607 | goto clean_cpts; |
1608 | } |
1609 | cpsw_split_res(cpsw); |
1610 | |
1611 | /* setup netdev */ |
1612 | ndev = devm_alloc_etherdev_mqs(dev, sizeof_priv: sizeof(struct cpsw_priv), |
1613 | CPSW_MAX_QUEUES, CPSW_MAX_QUEUES); |
1614 | if (!ndev) { |
1615 | dev_err(dev, "error allocating net_device\n" ); |
1616 | ret = -ENOMEM; |
1617 | goto clean_cpts; |
1618 | } |
1619 | |
1620 | priv = netdev_priv(dev: ndev); |
1621 | priv->cpsw = cpsw; |
1622 | priv->ndev = ndev; |
1623 | priv->dev = dev; |
1624 | priv->msg_enable = netif_msg_init(debug_value: debug_level, CPSW_DEBUG); |
1625 | priv->emac_port = 0; |
1626 | |
1627 | if (is_valid_ether_addr(addr: data->slave_data[0].mac_addr)) { |
1628 | memcpy(priv->mac_addr, data->slave_data[0].mac_addr, ETH_ALEN); |
1629 | dev_info(dev, "Detected MACID = %pM\n" , priv->mac_addr); |
1630 | } else { |
1631 | eth_random_addr(addr: priv->mac_addr); |
1632 | dev_info(dev, "Random MACID = %pM\n" , priv->mac_addr); |
1633 | } |
1634 | |
1635 | eth_hw_addr_set(dev: ndev, addr: priv->mac_addr); |
1636 | |
1637 | cpsw->slaves[0].ndev = ndev; |
1638 | |
1639 | ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX; |
1640 | ndev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT | |
1641 | NETDEV_XDP_ACT_NDO_XMIT; |
1642 | |
1643 | ndev->netdev_ops = &cpsw_netdev_ops; |
1644 | ndev->ethtool_ops = &cpsw_ethtool_ops; |
1645 | netif_napi_add(dev: ndev, napi: &cpsw->napi_rx, |
1646 | poll: cpsw->quirk_irq ? cpsw_rx_poll : cpsw_rx_mq_poll); |
1647 | netif_napi_add_tx(dev: ndev, napi: &cpsw->napi_tx, |
1648 | poll: cpsw->quirk_irq ? cpsw_tx_poll : cpsw_tx_mq_poll); |
1649 | |
1650 | /* register the network device */ |
1651 | SET_NETDEV_DEV(ndev, dev); |
1652 | ndev->dev.of_node = cpsw->slaves[0].data->slave_node; |
1653 | ret = register_netdev(dev: ndev); |
1654 | if (ret) { |
1655 | dev_err(dev, "error registering net device\n" ); |
1656 | ret = -ENODEV; |
1657 | goto clean_cpts; |
1658 | } |
1659 | |
1660 | if (cpsw->data.dual_emac) { |
1661 | ret = cpsw_probe_dual_emac(priv); |
1662 | if (ret) { |
1663 | cpsw_err(priv, probe, "error probe slave 2 emac interface\n" ); |
1664 | goto clean_unregister_netdev_ret; |
1665 | } |
1666 | } |
1667 | |
1668 | /* Grab RX and TX IRQs. Note that we also have RX_THRESHOLD and |
1669 | * MISC IRQs which are always kept disabled with this driver so |
1670 | * we will not request them. |
1671 | * |
1672 | * If anyone wants to implement support for those, make sure to |
1673 | * first request and append them to irqs_table array. |
1674 | */ |
1675 | ret = devm_request_irq(dev, irq: cpsw->irqs_table[0], handler: cpsw_rx_interrupt, |
1676 | irqflags: 0, devname: dev_name(dev), dev_id: cpsw); |
1677 | if (ret < 0) { |
1678 | dev_err(dev, "error attaching irq (%d)\n" , ret); |
1679 | goto clean_unregister_netdev_ret; |
1680 | } |
1681 | |
1682 | |
1683 | ret = devm_request_irq(dev, irq: cpsw->irqs_table[1], handler: cpsw_tx_interrupt, |
1684 | irqflags: 0, devname: dev_name(dev: &pdev->dev), dev_id: cpsw); |
1685 | if (ret < 0) { |
1686 | dev_err(dev, "error attaching irq (%d)\n" , ret); |
1687 | goto clean_unregister_netdev_ret; |
1688 | } |
1689 | |
1690 | if (!cpsw->cpts) |
1691 | goto skip_cpts; |
1692 | |
1693 | ret = devm_request_irq(dev: &pdev->dev, irq: cpsw->misc_irq, handler: cpsw_misc_interrupt, |
1694 | irqflags: 0, devname: dev_name(dev: &pdev->dev), dev_id: cpsw); |
1695 | if (ret < 0) { |
1696 | dev_err(dev, "error attaching misc irq (%d)\n" , ret); |
1697 | goto clean_unregister_netdev_ret; |
1698 | } |
1699 | |
1700 | /* Enable misc CPTS evnt_pend IRQ */ |
1701 | cpts_set_irqpoll(cpts: cpsw->cpts, en: false); |
1702 | |
1703 | skip_cpts: |
1704 | cpsw_notice(priv, probe, |
1705 | "initialized device (regs %pa, irq %d, pool size %d)\n" , |
1706 | &ss_res->start, cpsw->irqs_table[0], descs_pool_size); |
1707 | |
1708 | pm_runtime_put(dev: &pdev->dev); |
1709 | |
1710 | return 0; |
1711 | |
1712 | clean_unregister_netdev_ret: |
1713 | unregister_netdev(dev: ndev); |
1714 | clean_cpts: |
1715 | cpts_release(cpts: cpsw->cpts); |
1716 | cpdma_ctlr_destroy(ctlr: cpsw->dma); |
1717 | clean_dt_ret: |
1718 | cpsw_remove_dt(pdev); |
1719 | pm_runtime_put_sync(dev: &pdev->dev); |
1720 | clean_runtime_disable_ret: |
1721 | pm_runtime_disable(dev: &pdev->dev); |
1722 | return ret; |
1723 | } |
1724 | |
1725 | static int cpsw_remove(struct platform_device *pdev) |
1726 | { |
1727 | struct cpsw_common *cpsw = platform_get_drvdata(pdev); |
1728 | int i, ret; |
1729 | |
1730 | ret = pm_runtime_resume_and_get(dev: &pdev->dev); |
1731 | if (ret < 0) |
1732 | return ret; |
1733 | |
1734 | for (i = 0; i < cpsw->data.slaves; i++) |
1735 | if (cpsw->slaves[i].ndev) |
1736 | unregister_netdev(dev: cpsw->slaves[i].ndev); |
1737 | |
1738 | cpts_release(cpts: cpsw->cpts); |
1739 | cpdma_ctlr_destroy(ctlr: cpsw->dma); |
1740 | cpsw_remove_dt(pdev); |
1741 | pm_runtime_put_sync(dev: &pdev->dev); |
1742 | pm_runtime_disable(dev: &pdev->dev); |
1743 | return 0; |
1744 | } |
1745 | |
1746 | #ifdef CONFIG_PM_SLEEP |
1747 | static int cpsw_suspend(struct device *dev) |
1748 | { |
1749 | struct cpsw_common *cpsw = dev_get_drvdata(dev); |
1750 | int i; |
1751 | |
1752 | rtnl_lock(); |
1753 | |
1754 | for (i = 0; i < cpsw->data.slaves; i++) |
1755 | if (cpsw->slaves[i].ndev) |
1756 | if (netif_running(dev: cpsw->slaves[i].ndev)) |
1757 | cpsw_ndo_stop(ndev: cpsw->slaves[i].ndev); |
1758 | |
1759 | rtnl_unlock(); |
1760 | |
1761 | /* Select sleep pin state */ |
1762 | pinctrl_pm_select_sleep_state(dev); |
1763 | |
1764 | return 0; |
1765 | } |
1766 | |
1767 | static int cpsw_resume(struct device *dev) |
1768 | { |
1769 | struct cpsw_common *cpsw = dev_get_drvdata(dev); |
1770 | int i; |
1771 | |
1772 | /* Select default pin state */ |
1773 | pinctrl_pm_select_default_state(dev); |
1774 | |
1775 | /* shut up ASSERT_RTNL() warning in netif_set_real_num_tx/rx_queues */ |
1776 | rtnl_lock(); |
1777 | |
1778 | for (i = 0; i < cpsw->data.slaves; i++) |
1779 | if (cpsw->slaves[i].ndev) |
1780 | if (netif_running(dev: cpsw->slaves[i].ndev)) |
1781 | cpsw_ndo_open(ndev: cpsw->slaves[i].ndev); |
1782 | |
1783 | rtnl_unlock(); |
1784 | |
1785 | return 0; |
1786 | } |
1787 | #endif |
1788 | |
1789 | static SIMPLE_DEV_PM_OPS(cpsw_pm_ops, cpsw_suspend, cpsw_resume); |
1790 | |
1791 | static struct platform_driver cpsw_driver = { |
1792 | .driver = { |
1793 | .name = "cpsw" , |
1794 | .pm = &cpsw_pm_ops, |
1795 | .of_match_table = cpsw_of_mtable, |
1796 | }, |
1797 | .probe = cpsw_probe, |
1798 | .remove = cpsw_remove, |
1799 | }; |
1800 | |
1801 | module_platform_driver(cpsw_driver); |
1802 | |
1803 | MODULE_LICENSE("GPL" ); |
1804 | MODULE_AUTHOR("Cyril Chemparathy <cyril@ti.com>" ); |
1805 | MODULE_AUTHOR("Mugunthan V N <mugunthanvnm@ti.com>" ); |
1806 | MODULE_DESCRIPTION("TI CPSW Ethernet driver" ); |
1807 | |