1 // SPDX-License-Identifier: GPL-2.0
2
3 /* Texas Instruments ICSSM Ethernet Driver
4 *
5 * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
6 *
7 */
8
9 #include <linux/etherdevice.h>
10 #include <linux/genalloc.h>
11 #include <linux/if_bridge.h>
12 #include <linux/if_hsr.h>
13 #include <linux/if_vlan.h>
14 #include <linux/interrupt.h>
15 #include <linux/kernel.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/module.h>
18 #include <linux/net_tstamp.h>
19 #include <linux/of.h>
20 #include <linux/of_irq.h>
21 #include <linux/of_mdio.h>
22 #include <linux/of_net.h>
23 #include <linux/platform_device.h>
24 #include <linux/phy.h>
25 #include <linux/remoteproc/pruss.h>
26 #include <linux/ptp_classify.h>
27 #include <linux/regmap.h>
28 #include <linux/remoteproc.h>
29 #include <net/pkt_cls.h>
30
31 #include "icssm_prueth.h"
32 #include "icssm_prueth_switch.h"
33 #include "icssm_vlan_mcast_filter_mmap.h"
34 #include "../icssg/icssg_mii_rt.h"
35 #include "../icssg/icss_iep.h"
36
37 #define OCMC_RAM_SIZE (SZ_64K)
38
39 #define TX_START_DELAY 0x40
40 #define TX_CLK_DELAY_100M 0x6
41 #define HR_TIMER_TX_DELAY_US 100
42
icssm_prueth_write_reg(struct prueth * prueth,enum prueth_mem region,unsigned int reg,u32 val)43 static void icssm_prueth_write_reg(struct prueth *prueth,
44 enum prueth_mem region,
45 unsigned int reg, u32 val)
46 {
47 writel_relaxed(val, prueth->mem[region].va + reg);
48 }
49
50 /* Below macro is for 1528 Byte Frame support, to Allow even with
51 * Redundancy tag
52 */
53 #define PRUSS_MII_RT_RX_FRMS_MAX_SUPPORT_EMAC (VLAN_ETH_FRAME_LEN + \
54 ETH_FCS_LEN + \
55 ICSSM_LRE_TAG_SIZE)
56
57 /* ensure that order of PRUSS mem regions is same as enum prueth_mem */
58 static enum pruss_mem pruss_mem_ids[] = { PRUSS_MEM_DRAM0, PRUSS_MEM_DRAM1,
59 PRUSS_MEM_SHRD_RAM2 };
60
61 static const struct prueth_queue_info queue_infos[][NUM_QUEUES] = {
62 [PRUETH_PORT_QUEUE_HOST] = {
63 [PRUETH_QUEUE1] = {
64 P0_Q1_BUFFER_OFFSET,
65 HOST_QUEUE_DESC_OFFSET,
66 P0_Q1_BD_OFFSET,
67 P0_Q1_BD_OFFSET + ((HOST_QUEUE_1_SIZE - 1) * BD_SIZE),
68 },
69 [PRUETH_QUEUE2] = {
70 P0_Q2_BUFFER_OFFSET,
71 HOST_QUEUE_DESC_OFFSET + 8,
72 P0_Q2_BD_OFFSET,
73 P0_Q2_BD_OFFSET + ((HOST_QUEUE_2_SIZE - 1) * BD_SIZE),
74 },
75 [PRUETH_QUEUE3] = {
76 P0_Q3_BUFFER_OFFSET,
77 HOST_QUEUE_DESC_OFFSET + 16,
78 P0_Q3_BD_OFFSET,
79 P0_Q3_BD_OFFSET + ((HOST_QUEUE_3_SIZE - 1) * BD_SIZE),
80 },
81 [PRUETH_QUEUE4] = {
82 P0_Q4_BUFFER_OFFSET,
83 HOST_QUEUE_DESC_OFFSET + 24,
84 P0_Q4_BD_OFFSET,
85 P0_Q4_BD_OFFSET + ((HOST_QUEUE_4_SIZE - 1) * BD_SIZE),
86 },
87 },
88 [PRUETH_PORT_QUEUE_MII0] = {
89 [PRUETH_QUEUE1] = {
90 P1_Q1_BUFFER_OFFSET,
91 P1_Q1_BUFFER_OFFSET + ((QUEUE_1_SIZE - 1) *
92 ICSS_BLOCK_SIZE),
93 P1_Q1_BD_OFFSET,
94 P1_Q1_BD_OFFSET + ((QUEUE_1_SIZE - 1) * BD_SIZE),
95 },
96 [PRUETH_QUEUE2] = {
97 P1_Q2_BUFFER_OFFSET,
98 P1_Q2_BUFFER_OFFSET + ((QUEUE_2_SIZE - 1) *
99 ICSS_BLOCK_SIZE),
100 P1_Q2_BD_OFFSET,
101 P1_Q2_BD_OFFSET + ((QUEUE_2_SIZE - 1) * BD_SIZE),
102 },
103 [PRUETH_QUEUE3] = {
104 P1_Q3_BUFFER_OFFSET,
105 P1_Q3_BUFFER_OFFSET + ((QUEUE_3_SIZE - 1) *
106 ICSS_BLOCK_SIZE),
107 P1_Q3_BD_OFFSET,
108 P1_Q3_BD_OFFSET + ((QUEUE_3_SIZE - 1) * BD_SIZE),
109 },
110 [PRUETH_QUEUE4] = {
111 P1_Q4_BUFFER_OFFSET,
112 P1_Q4_BUFFER_OFFSET + ((QUEUE_4_SIZE - 1) *
113 ICSS_BLOCK_SIZE),
114 P1_Q4_BD_OFFSET,
115 P1_Q4_BD_OFFSET + ((QUEUE_4_SIZE - 1) * BD_SIZE),
116 },
117 },
118 [PRUETH_PORT_QUEUE_MII1] = {
119 [PRUETH_QUEUE1] = {
120 P2_Q1_BUFFER_OFFSET,
121 P2_Q1_BUFFER_OFFSET + ((QUEUE_1_SIZE - 1) *
122 ICSS_BLOCK_SIZE),
123 P2_Q1_BD_OFFSET,
124 P2_Q1_BD_OFFSET + ((QUEUE_1_SIZE - 1) * BD_SIZE),
125 },
126 [PRUETH_QUEUE2] = {
127 P2_Q2_BUFFER_OFFSET,
128 P2_Q2_BUFFER_OFFSET + ((QUEUE_2_SIZE - 1) *
129 ICSS_BLOCK_SIZE),
130 P2_Q2_BD_OFFSET,
131 P2_Q2_BD_OFFSET + ((QUEUE_2_SIZE - 1) * BD_SIZE),
132 },
133 [PRUETH_QUEUE3] = {
134 P2_Q3_BUFFER_OFFSET,
135 P2_Q3_BUFFER_OFFSET + ((QUEUE_3_SIZE - 1) *
136 ICSS_BLOCK_SIZE),
137 P2_Q3_BD_OFFSET,
138 P2_Q3_BD_OFFSET + ((QUEUE_3_SIZE - 1) * BD_SIZE),
139 },
140 [PRUETH_QUEUE4] = {
141 P2_Q4_BUFFER_OFFSET,
142 P2_Q4_BUFFER_OFFSET + ((QUEUE_4_SIZE - 1) *
143 ICSS_BLOCK_SIZE),
144 P2_Q4_BD_OFFSET,
145 P2_Q4_BD_OFFSET + ((QUEUE_4_SIZE - 1) * BD_SIZE),
146 },
147 },
148 };
149
150 const struct prueth_queue_desc queue_descs[][NUM_QUEUES] = {
151 [PRUETH_PORT_QUEUE_HOST] = {
152 { .rd_ptr = P0_Q1_BD_OFFSET, .wr_ptr = P0_Q1_BD_OFFSET, },
153 { .rd_ptr = P0_Q2_BD_OFFSET, .wr_ptr = P0_Q2_BD_OFFSET, },
154 { .rd_ptr = P0_Q3_BD_OFFSET, .wr_ptr = P0_Q3_BD_OFFSET, },
155 { .rd_ptr = P0_Q4_BD_OFFSET, .wr_ptr = P0_Q4_BD_OFFSET, },
156 },
157 [PRUETH_PORT_QUEUE_MII0] = {
158 { .rd_ptr = P1_Q1_BD_OFFSET, .wr_ptr = P1_Q1_BD_OFFSET, },
159 { .rd_ptr = P1_Q2_BD_OFFSET, .wr_ptr = P1_Q2_BD_OFFSET, },
160 { .rd_ptr = P1_Q3_BD_OFFSET, .wr_ptr = P1_Q3_BD_OFFSET, },
161 { .rd_ptr = P1_Q4_BD_OFFSET, .wr_ptr = P1_Q4_BD_OFFSET, },
162 },
163 [PRUETH_PORT_QUEUE_MII1] = {
164 { .rd_ptr = P2_Q1_BD_OFFSET, .wr_ptr = P2_Q1_BD_OFFSET, },
165 { .rd_ptr = P2_Q2_BD_OFFSET, .wr_ptr = P2_Q2_BD_OFFSET, },
166 { .rd_ptr = P2_Q3_BD_OFFSET, .wr_ptr = P2_Q3_BD_OFFSET, },
167 { .rd_ptr = P2_Q4_BD_OFFSET, .wr_ptr = P2_Q4_BD_OFFSET, },
168 }
169 };
170
icssm_prueth_hostconfig(struct prueth * prueth)171 static void icssm_prueth_hostconfig(struct prueth *prueth)
172 {
173 void __iomem *sram_base = prueth->mem[PRUETH_MEM_SHARED_RAM].va;
174 void __iomem *sram;
175
176 /* queue size lookup table */
177 sram = sram_base + HOST_QUEUE_SIZE_ADDR;
178 writew(HOST_QUEUE_1_SIZE, sram);
179 writew(HOST_QUEUE_2_SIZE, sram + 2);
180 writew(HOST_QUEUE_3_SIZE, sram + 4);
181 writew(HOST_QUEUE_4_SIZE, sram + 6);
182
183 /* queue information table */
184 sram = sram_base + HOST_Q1_RX_CONTEXT_OFFSET;
185 memcpy_toio(sram, queue_infos[PRUETH_PORT_QUEUE_HOST],
186 sizeof(queue_infos[PRUETH_PORT_QUEUE_HOST]));
187
188 /* buffer offset table */
189 sram = sram_base + HOST_QUEUE_OFFSET_ADDR;
190 writew(P0_Q1_BUFFER_OFFSET, sram);
191 writew(P0_Q2_BUFFER_OFFSET, sram + 2);
192 writew(P0_Q3_BUFFER_OFFSET, sram + 4);
193 writew(P0_Q4_BUFFER_OFFSET, sram + 6);
194
195 /* buffer descriptor offset table*/
196 sram = sram_base + HOST_QUEUE_DESCRIPTOR_OFFSET_ADDR;
197 writew(P0_Q1_BD_OFFSET, sram);
198 writew(P0_Q2_BD_OFFSET, sram + 2);
199 writew(P0_Q3_BD_OFFSET, sram + 4);
200 writew(P0_Q4_BD_OFFSET, sram + 6);
201
202 /* queue table */
203 sram = sram_base + HOST_QUEUE_DESC_OFFSET;
204 memcpy_toio(sram, queue_descs[PRUETH_PORT_QUEUE_HOST],
205 sizeof(queue_descs[PRUETH_PORT_QUEUE_HOST]));
206 }
207
icssm_prueth_mii_init(struct prueth * prueth)208 static void icssm_prueth_mii_init(struct prueth *prueth)
209 {
210 u32 txcfg_reg, txcfg, txcfg2;
211 struct regmap *mii_rt;
212 u32 rxcfg_reg, rxcfg;
213
214 mii_rt = prueth->mii_rt;
215
216 rxcfg = PRUSS_MII_RT_RXCFG_RX_ENABLE |
217 PRUSS_MII_RT_RXCFG_RX_DATA_RDY_MODE_DIS |
218 PRUSS_MII_RT_RXCFG_RX_L2_EN |
219 PRUSS_MII_RT_RXCFG_RX_CUT_PREAMBLE |
220 PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS;
221
222 /* Configuration of Port 0 Rx */
223 rxcfg_reg = PRUSS_MII_RT_RXCFG0;
224
225 regmap_write(mii_rt, rxcfg_reg, rxcfg);
226
227 /* Configuration of Port 1 Rx */
228 rxcfg_reg = PRUSS_MII_RT_RXCFG1;
229
230 rxcfg |= PRUSS_MII_RT_RXCFG_RX_MUX_SEL;
231
232 regmap_write(mii_rt, rxcfg_reg, rxcfg);
233
234 txcfg = PRUSS_MII_RT_TXCFG_TX_ENABLE |
235 PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE |
236 PRUSS_MII_RT_TXCFG_TX_32_MODE_EN |
237 (TX_START_DELAY << PRUSS_MII_RT_TXCFG_TX_START_DELAY_SHIFT) |
238 (TX_CLK_DELAY_100M << PRUSS_MII_RT_TXCFG_TX_CLK_DELAY_SHIFT);
239
240 txcfg2 = txcfg;
241 if (!PRUETH_IS_EMAC(prueth))
242 txcfg2 |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
243
244 /* Configuration of Port 0 Tx */
245 txcfg_reg = PRUSS_MII_RT_TXCFG0;
246
247 regmap_write(mii_rt, txcfg_reg, txcfg2);
248
249 txcfg2 = txcfg;
250 if (PRUETH_IS_EMAC(prueth))
251 txcfg2 |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
252
253 /* Configuration of Port 1 Tx */
254 txcfg_reg = PRUSS_MII_RT_TXCFG1;
255
256 regmap_write(mii_rt, txcfg_reg, txcfg2);
257
258 txcfg_reg = PRUSS_MII_RT_RX_FRMS0;
259
260 /* Min frame length should be set to 64 to allow receive of standard
261 * Ethernet frames such as PTP, LLDP that will not have the tag/rct.
262 * Actual size written to register is size - 1 per TRM. This also
263 * includes CRC/FCS.
264 */
265 txcfg = FIELD_PREP(PRUSS_MII_RT_RX_FRMS_MIN_FRM_MASK,
266 (PRUSS_MII_RT_RX_FRMS_MIN_FRM - 1));
267
268 /* For EMAC, set Max frame size to 1528 i.e size with VLAN.
269 * Actual size written to register is size - 1 as per TRM.
270 * Since driver support run time change of protocol, driver
271 * must overwrite the values based on Ethernet type.
272 */
273 txcfg |= FIELD_PREP(PRUSS_MII_RT_RX_FRMS_MAX_FRM_MASK,
274 (PRUSS_MII_RT_RX_FRMS_MAX_SUPPORT_EMAC - 1));
275
276 regmap_write(mii_rt, txcfg_reg, txcfg);
277
278 txcfg_reg = PRUSS_MII_RT_RX_FRMS1;
279
280 regmap_write(mii_rt, txcfg_reg, txcfg);
281 }
282
icssm_prueth_clearmem(struct prueth * prueth,enum prueth_mem region)283 static void icssm_prueth_clearmem(struct prueth *prueth, enum prueth_mem region)
284 {
285 memset_io(prueth->mem[region].va, 0, prueth->mem[region].size);
286 }
287
icssm_prueth_hostinit(struct prueth * prueth)288 static void icssm_prueth_hostinit(struct prueth *prueth)
289 {
290 /* Clear shared RAM */
291 icssm_prueth_clearmem(prueth, PRUETH_MEM_SHARED_RAM);
292
293 /* Clear OCMC RAM */
294 icssm_prueth_clearmem(prueth, PRUETH_MEM_OCMC);
295
296 /* Clear data RAMs */
297 if (prueth->eth_node[PRUETH_MAC0])
298 icssm_prueth_clearmem(prueth, PRUETH_MEM_DRAM0);
299 if (prueth->eth_node[PRUETH_MAC1])
300 icssm_prueth_clearmem(prueth, PRUETH_MEM_DRAM1);
301
302 /* Initialize host queues in shared RAM */
303 if (!PRUETH_IS_EMAC(prueth))
304 icssm_prueth_sw_hostconfig(prueth);
305 else
306 icssm_prueth_hostconfig(prueth);
307
308 /* Configure MII_RT */
309 icssm_prueth_mii_init(prueth);
310 }
311
312 /* This function initialize the driver in EMAC mode
313 * based on eth_type
314 */
icssm_prueth_init_ethernet_mode(struct prueth * prueth)315 static void icssm_prueth_init_ethernet_mode(struct prueth *prueth)
316 {
317 icssm_prueth_hostinit(prueth);
318 }
319
icssm_prueth_port_enable(struct prueth_emac * emac,bool enable)320 static void icssm_prueth_port_enable(struct prueth_emac *emac, bool enable)
321 {
322 struct prueth *prueth = emac->prueth;
323 void __iomem *port_ctrl;
324 void __iomem *ram;
325
326 ram = prueth->mem[emac->dram].va;
327 port_ctrl = ram + PORT_CONTROL_ADDR;
328 writeb(!!enable, port_ctrl);
329 }
330
icssm_prueth_emac_config(struct prueth_emac * emac)331 static int icssm_prueth_emac_config(struct prueth_emac *emac)
332 {
333 struct prueth *prueth = emac->prueth;
334 u32 sharedramaddr, ocmcaddr;
335 void __iomem *dram_base;
336 void __iomem *mac_addr;
337 void __iomem *dram;
338 void __iomem *sram;
339
340 /* PRU needs local shared RAM address for C28 */
341 sharedramaddr = ICSS_LOCAL_SHARED_RAM;
342 /* PRU needs real global OCMC address for C30*/
343 ocmcaddr = (u32)prueth->mem[PRUETH_MEM_OCMC].pa;
344 sram = prueth->mem[PRUETH_MEM_SHARED_RAM].va;
345
346 /* Clear data RAM */
347 icssm_prueth_clearmem(prueth, emac->dram);
348
349 dram_base = prueth->mem[emac->dram].va;
350
351 /* setup mac address */
352 mac_addr = dram_base + PORT_MAC_ADDR;
353 memcpy_toio(mac_addr, emac->mac_addr, 6);
354
355 /* queue information table */
356 dram = dram_base + TX_CONTEXT_Q1_OFFSET_ADDR;
357 memcpy_toio(dram, queue_infos[emac->port_id],
358 sizeof(queue_infos[emac->port_id]));
359
360 /* queue table */
361 dram = dram_base + PORT_QUEUE_DESC_OFFSET;
362 memcpy_toio(dram, queue_descs[emac->port_id],
363 sizeof(queue_descs[emac->port_id]));
364
365 emac->rx_queue_descs = sram + HOST_QUEUE_DESC_OFFSET;
366 emac->tx_queue_descs = dram;
367
368 /* Set in constant table C28 of PRU0 to ICSS Shared memory */
369 pru_rproc_set_ctable(emac->pru, PRU_C28, sharedramaddr);
370
371 /* Set in constant table C30 of PRU0 to OCMC memory */
372 pru_rproc_set_ctable(emac->pru, PRU_C30, ocmcaddr);
373
374 return 0;
375 }
376
377 /* called back by PHY layer if there is change in link state of hw port*/
icssm_emac_adjust_link(struct net_device * ndev)378 static void icssm_emac_adjust_link(struct net_device *ndev)
379 {
380 struct prueth_emac *emac = netdev_priv(ndev);
381 struct phy_device *phydev = emac->phydev;
382 struct prueth *prueth = emac->prueth;
383 bool new_state = false;
384 enum prueth_mem region;
385 unsigned long flags;
386 u32 port_status = 0;
387 u32 txcfg, mask;
388 u32 delay;
389
390 spin_lock_irqsave(&emac->lock, flags);
391
392 if (phydev->link) {
393 /* check the mode of operation */
394 if (phydev->duplex != emac->duplex) {
395 new_state = true;
396 emac->duplex = phydev->duplex;
397 }
398 if (phydev->speed != emac->speed) {
399 new_state = true;
400 emac->speed = phydev->speed;
401 }
402 if (!emac->link) {
403 new_state = true;
404 emac->link = 1;
405 }
406 } else if (emac->link) {
407 new_state = true;
408 emac->link = 0;
409 }
410
411 if (new_state) {
412 phy_print_status(phydev);
413 region = emac->dram;
414
415 /* update phy/port status information based on PHY values*/
416 if (emac->link) {
417 port_status |= PORT_LINK_MASK;
418
419 icssm_prueth_write_reg(prueth, region, PHY_SPEED_OFFSET,
420 emac->speed);
421
422 delay = TX_CLK_DELAY_100M;
423 delay = delay << PRUSS_MII_RT_TXCFG_TX_CLK_DELAY_SHIFT;
424 mask = PRUSS_MII_RT_TXCFG_TX_CLK_DELAY_MASK;
425
426 if (emac->port_id)
427 txcfg = PRUSS_MII_RT_TXCFG1;
428 else
429 txcfg = PRUSS_MII_RT_TXCFG0;
430
431 regmap_update_bits(prueth->mii_rt, txcfg, mask, delay);
432 }
433
434 writeb(port_status, prueth->mem[region].va +
435 PORT_STATUS_OFFSET);
436 }
437
438 if (emac->link) {
439 /* reactivate the transmit queue if it is stopped */
440 if (netif_running(ndev) && netif_queue_stopped(ndev))
441 netif_wake_queue(ndev);
442 } else {
443 if (!netif_queue_stopped(ndev))
444 netif_stop_queue(ndev);
445 }
446
447 spin_unlock_irqrestore(&emac->lock, flags);
448 }
449
450 static unsigned int
icssm_get_buff_desc_count(const struct prueth_queue_info * queue)451 icssm_get_buff_desc_count(const struct prueth_queue_info *queue)
452 {
453 unsigned int buffer_desc_count;
454
455 buffer_desc_count = queue->buffer_desc_end -
456 queue->buffer_desc_offset;
457 buffer_desc_count /= BD_SIZE;
458 buffer_desc_count++;
459
460 return buffer_desc_count;
461 }
462
icssm_get_block(struct prueth_queue_desc __iomem * queue_desc,const struct prueth_queue_info * queue,int * write_block,int * read_block)463 static void icssm_get_block(struct prueth_queue_desc __iomem *queue_desc,
464 const struct prueth_queue_info *queue,
465 int *write_block, int *read_block)
466 {
467 *write_block = (readw(&queue_desc->wr_ptr) -
468 queue->buffer_desc_offset) / BD_SIZE;
469 *read_block = (readw(&queue_desc->rd_ptr) -
470 queue->buffer_desc_offset) / BD_SIZE;
471 }
472
473 /**
474 * icssm_emac_rx_irq - EMAC Rx interrupt handler
475 * @irq: interrupt number
476 * @dev_id: pointer to net_device
477 *
478 * EMAC Interrupt handler - we only schedule NAPI and not process any packets
479 * here.
480 *
481 * Return: IRQ_HANDLED if the interrupt handled
482 */
icssm_emac_rx_irq(int irq,void * dev_id)483 static irqreturn_t icssm_emac_rx_irq(int irq, void *dev_id)
484 {
485 struct net_device *ndev = (struct net_device *)dev_id;
486 struct prueth_emac *emac = netdev_priv(ndev);
487
488 if (likely(netif_running(ndev))) {
489 /* disable Rx system event */
490 disable_irq_nosync(emac->rx_irq);
491 napi_schedule(&emac->napi);
492 }
493
494 return IRQ_HANDLED;
495 }
496
497 /**
498 * icssm_prueth_tx_enqueue - queue a packet to firmware for transmission
499 *
500 * @emac: EMAC data structure
501 * @skb: packet data buffer
502 * @queue_id: priority queue id
503 *
504 * Return: 0 (Success)
505 */
icssm_prueth_tx_enqueue(struct prueth_emac * emac,struct sk_buff * skb,enum prueth_queue_id queue_id)506 static int icssm_prueth_tx_enqueue(struct prueth_emac *emac,
507 struct sk_buff *skb,
508 enum prueth_queue_id queue_id)
509 {
510 struct prueth_queue_desc __iomem *queue_desc;
511 const struct prueth_queue_info *txqueue;
512 struct net_device *ndev = emac->ndev;
513 struct prueth *prueth = emac->prueth;
514 unsigned int buffer_desc_count;
515 int free_blocks, update_block;
516 bool buffer_wrapped = false;
517 int write_block, read_block;
518 void *src_addr, *dst_addr;
519 int pkt_block_size;
520 void __iomem *sram;
521 void __iomem *dram;
522 int txport, pktlen;
523 u16 update_wr_ptr;
524 u32 wr_buf_desc;
525 void *ocmc_ram;
526
527 if (!PRUETH_IS_EMAC(prueth))
528 dram = prueth->mem[PRUETH_MEM_DRAM1].va;
529 else
530 dram = emac->prueth->mem[emac->dram].va;
531 if (eth_skb_pad(skb)) {
532 if (netif_msg_tx_err(emac) && net_ratelimit())
533 netdev_err(ndev, "packet pad failed\n");
534 return -ENOMEM;
535 }
536
537 /* which port to tx: MII0 or MII1 */
538 txport = emac->tx_port_queue;
539 src_addr = skb->data;
540 pktlen = skb->len;
541 /* Get the tx queue */
542 queue_desc = emac->tx_queue_descs + queue_id;
543 if (!PRUETH_IS_EMAC(prueth))
544 txqueue = &sw_queue_infos[txport][queue_id];
545 else
546 txqueue = &queue_infos[txport][queue_id];
547
548 buffer_desc_count = icssm_get_buff_desc_count(txqueue);
549
550 /* the PRU firmware deals mostly in pointers already
551 * offset into ram, we would like to deal in indexes
552 * within the queue we are working with for code
553 * simplicity, calculate this here
554 */
555 icssm_get_block(queue_desc, txqueue, &write_block, &read_block);
556
557 if (write_block > read_block) {
558 free_blocks = buffer_desc_count - write_block;
559 free_blocks += read_block;
560 } else if (write_block < read_block) {
561 free_blocks = read_block - write_block;
562 } else { /* they are all free */
563 free_blocks = buffer_desc_count;
564 }
565
566 pkt_block_size = DIV_ROUND_UP(pktlen, ICSS_BLOCK_SIZE);
567 if (pkt_block_size > free_blocks) /* out of queue space */
568 return -ENOBUFS;
569
570 /* calculate end BD address post write */
571 update_block = write_block + pkt_block_size;
572
573 /* Check for wrap around */
574 if (update_block >= buffer_desc_count) {
575 update_block %= buffer_desc_count;
576 buffer_wrapped = true;
577 }
578
579 /* OCMC RAM is not cached and write order is not important */
580 ocmc_ram = (__force void *)emac->prueth->mem[PRUETH_MEM_OCMC].va;
581 dst_addr = ocmc_ram + txqueue->buffer_offset +
582 (write_block * ICSS_BLOCK_SIZE);
583
584 /* Copy the data from socket buffer(DRAM) to PRU buffers(OCMC) */
585 if (buffer_wrapped) { /* wrapped around buffer */
586 int bytes = (buffer_desc_count - write_block) * ICSS_BLOCK_SIZE;
587 int remaining;
588
589 /* bytes is integral multiple of ICSS_BLOCK_SIZE but
590 * entire packet may have fit within the last BD
591 * if pkt_info.length is not integral multiple of
592 * ICSS_BLOCK_SIZE
593 */
594 if (pktlen < bytes)
595 bytes = pktlen;
596
597 /* copy non-wrapped part */
598 memcpy(dst_addr, src_addr, bytes);
599
600 /* copy wrapped part */
601 src_addr += bytes;
602 remaining = pktlen - bytes;
603 dst_addr = ocmc_ram + txqueue->buffer_offset;
604 memcpy(dst_addr, src_addr, remaining);
605 } else {
606 memcpy(dst_addr, src_addr, pktlen);
607 }
608
609 /* update first buffer descriptor */
610 wr_buf_desc = (pktlen << PRUETH_BD_LENGTH_SHIFT) &
611 PRUETH_BD_LENGTH_MASK;
612 sram = prueth->mem[PRUETH_MEM_SHARED_RAM].va;
613 if (!PRUETH_IS_EMAC(prueth))
614 writel(wr_buf_desc, sram + readw(&queue_desc->wr_ptr));
615 else
616 writel(wr_buf_desc, dram + readw(&queue_desc->wr_ptr));
617
618 /* update the write pointer in this queue descriptor, the firmware
619 * polls for this change so this will signal the start of transmission
620 */
621 update_wr_ptr = txqueue->buffer_desc_offset + (update_block * BD_SIZE);
622 writew(update_wr_ptr, &queue_desc->wr_ptr);
623
624 return 0;
625 }
626
icssm_parse_packet_info(struct prueth * prueth,u32 buffer_descriptor,struct prueth_packet_info * pkt_info)627 void icssm_parse_packet_info(struct prueth *prueth, u32 buffer_descriptor,
628 struct prueth_packet_info *pkt_info)
629 {
630 pkt_info->port = (buffer_descriptor & PRUETH_BD_PORT_MASK) >>
631 PRUETH_BD_PORT_SHIFT;
632 pkt_info->length = (buffer_descriptor & PRUETH_BD_LENGTH_MASK) >>
633 PRUETH_BD_LENGTH_SHIFT;
634 pkt_info->broadcast = !!(buffer_descriptor & PRUETH_BD_BROADCAST_MASK);
635 pkt_info->error = !!(buffer_descriptor & PRUETH_BD_ERROR_MASK);
636 pkt_info->lookup_success = !!(buffer_descriptor &
637 PRUETH_BD_LOOKUP_SUCCESS_MASK);
638 pkt_info->flood = !!(buffer_descriptor & PRUETH_BD_SW_FLOOD_MASK);
639 pkt_info->timestamp = !!(buffer_descriptor & PRUETH_BD_TIMESTAMP_MASK);
640 }
641
642 /**
643 * icssm_emac_rx_packet - EMAC Receive function
644 *
645 * @emac: EMAC data structure
646 * @bd_rd_ptr: Buffer descriptor read pointer
647 * @pkt_info: packet information structure
648 * @rxqueue: Receive queue information structure
649 *
650 * Get a packet from receive queue
651 *
652 * Return: 0 (Success)
653 */
icssm_emac_rx_packet(struct prueth_emac * emac,u16 * bd_rd_ptr,struct prueth_packet_info * pkt_info,const struct prueth_queue_info * rxqueue)654 int icssm_emac_rx_packet(struct prueth_emac *emac, u16 *bd_rd_ptr,
655 struct prueth_packet_info *pkt_info,
656 const struct prueth_queue_info *rxqueue)
657 {
658 struct net_device *ndev = emac->ndev;
659 unsigned int buffer_desc_count;
660 int read_block, update_block;
661 unsigned int actual_pkt_len;
662 bool buffer_wrapped = false;
663 void *src_addr, *dst_addr;
664 struct sk_buff *skb;
665 int pkt_block_size;
666 void *ocmc_ram;
667
668 /* the PRU firmware deals mostly in pointers already
669 * offset into ram, we would like to deal in indexes
670 * within the queue we are working with for code
671 * simplicity, calculate this here
672 */
673 buffer_desc_count = icssm_get_buff_desc_count(rxqueue);
674 read_block = (*bd_rd_ptr - rxqueue->buffer_desc_offset) / BD_SIZE;
675 pkt_block_size = DIV_ROUND_UP(pkt_info->length, ICSS_BLOCK_SIZE);
676
677 /* calculate end BD address post read */
678 update_block = read_block + pkt_block_size;
679
680 /* Check for wrap around */
681 if (update_block >= buffer_desc_count) {
682 update_block %= buffer_desc_count;
683 if (update_block)
684 buffer_wrapped = true;
685 }
686
687 /* calculate new pointer in ram */
688 *bd_rd_ptr = rxqueue->buffer_desc_offset + (update_block * BD_SIZE);
689
690 actual_pkt_len = pkt_info->length;
691
692 /* Allocate a socket buffer for this packet */
693 skb = netdev_alloc_skb_ip_align(ndev, actual_pkt_len);
694 if (!skb) {
695 if (netif_msg_rx_err(emac) && net_ratelimit())
696 netdev_err(ndev, "failed rx buffer alloc\n");
697 return -ENOMEM;
698 }
699
700 dst_addr = skb->data;
701
702 /* OCMC RAM is not cached and read order is not important */
703 ocmc_ram = (__force void *)emac->prueth->mem[PRUETH_MEM_OCMC].va;
704
705 /* Get the start address of the first buffer from
706 * the read buffer description
707 */
708 src_addr = ocmc_ram + rxqueue->buffer_offset +
709 (read_block * ICSS_BLOCK_SIZE);
710
711 /* Copy the data from PRU buffers(OCMC) to socket buffer(DRAM) */
712 if (buffer_wrapped) { /* wrapped around buffer */
713 int bytes = (buffer_desc_count - read_block) * ICSS_BLOCK_SIZE;
714 int remaining;
715 /* bytes is integral multiple of ICSS_BLOCK_SIZE but
716 * entire packet may have fit within the last BD
717 * if pkt_info.length is not integral multiple of
718 * ICSS_BLOCK_SIZE
719 */
720 if (pkt_info->length < bytes)
721 bytes = pkt_info->length;
722
723 /* copy non-wrapped part */
724 memcpy(dst_addr, src_addr, bytes);
725
726 /* copy wrapped part */
727 dst_addr += bytes;
728 remaining = actual_pkt_len - bytes;
729
730 src_addr = ocmc_ram + rxqueue->buffer_offset;
731 memcpy(dst_addr, src_addr, remaining);
732 src_addr += remaining;
733 } else {
734 memcpy(dst_addr, src_addr, actual_pkt_len);
735 src_addr += actual_pkt_len;
736 }
737
738 if (PRUETH_IS_SWITCH(emac->prueth)) {
739 skb->offload_fwd_mark = READ_ONCE(emac->offload_fwd_mark);
740 if (!pkt_info->lookup_success)
741 icssm_prueth_sw_learn_fdb(emac, skb->data + ETH_ALEN);
742 }
743
744 skb_put(skb, actual_pkt_len);
745
746 /* send packet up the stack */
747 skb->protocol = eth_type_trans(skb, ndev);
748 local_bh_disable();
749 netif_receive_skb(skb);
750 local_bh_enable();
751
752 /* update stats */
753 emac->stats.rx_bytes += actual_pkt_len;
754 emac->stats.rx_packets++;
755
756 return 0;
757 }
758
icssm_emac_rx_packets(struct prueth_emac * emac,int budget)759 static int icssm_emac_rx_packets(struct prueth_emac *emac, int budget)
760 {
761 struct prueth_queue_desc __iomem *queue_desc;
762 const struct prueth_queue_info *rxqueue;
763 struct prueth *prueth = emac->prueth;
764 struct prueth_packet_info pkt_info;
765 int start_queue, end_queue;
766 void __iomem *shared_ram;
767 u16 bd_rd_ptr, bd_wr_ptr;
768 u16 update_rd_ptr;
769 u8 overflow_cnt;
770 u32 rd_buf_desc;
771 int used = 0;
772 int i, ret;
773
774 shared_ram = emac->prueth->mem[PRUETH_MEM_SHARED_RAM].va;
775
776 /* Start and end queue is made common for EMAC, RSTP */
777 start_queue = emac->rx_queue_start;
778 end_queue = emac->rx_queue_end;
779
780 /* skip Rx if budget is 0 */
781 if (!budget)
782 return 0;
783
784 /* search host queues for packets */
785 for (i = start_queue; i <= end_queue; i++) {
786 queue_desc = emac->rx_queue_descs + i;
787 if (PRUETH_IS_SWITCH(emac->prueth))
788 rxqueue = &sw_queue_infos[PRUETH_PORT_HOST][i];
789 else
790 rxqueue = &queue_infos[PRUETH_PORT_HOST][i];
791 overflow_cnt = readb(&queue_desc->overflow_cnt);
792 if (overflow_cnt > 0) {
793 emac->stats.rx_over_errors += overflow_cnt;
794 /* reset to zero */
795 writeb(0, &queue_desc->overflow_cnt);
796 }
797
798 bd_rd_ptr = readw(&queue_desc->rd_ptr);
799 bd_wr_ptr = readw(&queue_desc->wr_ptr);
800
801 /* while packets are available in this queue */
802 while (bd_rd_ptr != bd_wr_ptr) {
803 /* get packet info from the read buffer descriptor */
804 rd_buf_desc = readl(shared_ram + bd_rd_ptr);
805 icssm_parse_packet_info(prueth, rd_buf_desc, &pkt_info);
806
807 if (pkt_info.length <= 0) {
808 /* a packet length of zero will cause us to
809 * never move the read pointer ahead, locking
810 * the driver, so we manually have to move it
811 * to the write pointer, discarding all
812 * remaining packets in this queue. This should
813 * never happen.
814 */
815 update_rd_ptr = bd_wr_ptr;
816 emac->stats.rx_length_errors++;
817 } else if (pkt_info.length > EMAC_MAX_FRM_SUPPORT) {
818 /* if the packet is too large we skip it but we
819 * still need to move the read pointer ahead
820 * and assume something is wrong with the read
821 * pointer as the firmware should be filtering
822 * these packets
823 */
824 update_rd_ptr = bd_wr_ptr;
825 emac->stats.rx_length_errors++;
826 } else {
827 update_rd_ptr = bd_rd_ptr;
828 ret = icssm_emac_rx_packet(emac, &update_rd_ptr,
829 &pkt_info, rxqueue);
830 if (ret)
831 return used;
832 used++;
833 }
834
835 /* after reading the buffer descriptor we clear it
836 * to prevent improperly moved read pointer errors
837 * from simply looking like old packets.
838 */
839 writel(0, shared_ram + bd_rd_ptr);
840
841 /* update read pointer in queue descriptor */
842 writew(update_rd_ptr, &queue_desc->rd_ptr);
843 bd_rd_ptr = update_rd_ptr;
844
845 /* all we have room for? */
846 if (used >= budget)
847 return used;
848 }
849 }
850
851 return used;
852 }
853
icssm_emac_napi_poll(struct napi_struct * napi,int budget)854 static int icssm_emac_napi_poll(struct napi_struct *napi, int budget)
855 {
856 struct prueth_emac *emac = container_of(napi, struct prueth_emac, napi);
857 int num_rx;
858
859 num_rx = icssm_emac_rx_packets(emac, budget);
860
861 if (num_rx < budget && napi_complete_done(napi, num_rx))
862 enable_irq(emac->rx_irq);
863
864 return num_rx;
865 }
866
icssm_emac_set_boot_pru(struct prueth_emac * emac,struct net_device * ndev)867 static int icssm_emac_set_boot_pru(struct prueth_emac *emac,
868 struct net_device *ndev)
869 {
870 const struct prueth_firmware *pru_firmwares;
871 struct prueth *prueth = emac->prueth;
872 const char *fw_name;
873 int ret;
874
875 pru_firmwares = &prueth->fw_data->fw_pru[emac->port_id - 1];
876 fw_name = pru_firmwares->fw_name[prueth->eth_type];
877 if (!fw_name) {
878 netdev_err(ndev, "eth_type %d not supported\n",
879 prueth->eth_type);
880 return -ENODEV;
881 }
882
883 ret = rproc_set_firmware(emac->pru, fw_name);
884 if (ret) {
885 netdev_err(ndev, "failed to set %s firmware: %d\n",
886 fw_name, ret);
887 return ret;
888 }
889
890 ret = rproc_boot(emac->pru);
891 if (ret) {
892 netdev_err(ndev, "failed to boot %s firmware: %d\n",
893 fw_name, ret);
894 return ret;
895 }
896 return ret;
897 }
898
icssm_emac_request_irqs(struct prueth_emac * emac)899 static int icssm_emac_request_irqs(struct prueth_emac *emac)
900 {
901 struct net_device *ndev = emac->ndev;
902 int ret;
903
904 ret = request_irq(emac->rx_irq, icssm_emac_rx_irq,
905 IRQF_TRIGGER_HIGH,
906 ndev->name, ndev);
907 if (ret) {
908 netdev_err(ndev, "unable to request RX IRQ\n");
909 return ret;
910 }
911
912 return ret;
913 }
914
915 /* Function to free memory related to sw */
icssm_prueth_free_memory(struct prueth * prueth)916 static void icssm_prueth_free_memory(struct prueth *prueth)
917 {
918 if (PRUETH_IS_SWITCH(prueth))
919 icssm_prueth_sw_free_fdb_table(prueth);
920 }
921
icssm_ptp_dram_init(struct prueth_emac * emac)922 static void icssm_ptp_dram_init(struct prueth_emac *emac)
923 {
924 void __iomem *sram = emac->prueth->mem[PRUETH_MEM_SHARED_RAM].va;
925 u64 temp64;
926
927 writew(0, sram + MII_RX_CORRECTION_OFFSET);
928 writew(0, sram + MII_TX_CORRECTION_OFFSET);
929
930 /* Initialize RCF to 1 (Linux N/A) */
931 writel(1 * 1024, sram + TIMESYNC_TC_RCF_OFFSET);
932
933 /* This flag will be set and cleared by firmware */
934 /* Write Sync0 period for sync signal generation in PTP
935 * memory in shared RAM
936 */
937 writel(200000000 / 50, sram + TIMESYNC_SYNC0_WIDTH_OFFSET);
938
939 /* Write CMP1 period for sync signal generation in PTP
940 * memory in shared RAM
941 */
942 temp64 = 1000000;
943 memcpy_toio(sram + TIMESYNC_CMP1_CMP_OFFSET, &temp64, sizeof(temp64));
944
945 /* Write Sync0 period for sync signal generation in PTP
946 * memory in shared RAM
947 */
948 writel(1000000, sram + TIMESYNC_CMP1_PERIOD_OFFSET);
949
950 /* Configures domainNumber list. Firmware supports 2 domains */
951 writeb(0, sram + TIMESYNC_DOMAIN_NUMBER_LIST);
952 writeb(0, sram + TIMESYNC_DOMAIN_NUMBER_LIST + 1);
953
954 /* Configure 1-step/2-step */
955 writeb(1, sram + DISABLE_SWITCH_SYNC_RELAY_OFFSET);
956
957 /* Configures the setting to Link local frame without HSR tag */
958 writeb(0, sram + LINK_LOCAL_FRAME_HAS_HSR_TAG);
959
960 /* Enable E2E/UDP PTP message timestamping */
961 writeb(1, sram + PTP_IPV4_UDP_E2E_ENABLE);
962 }
963
964 /**
965 * icssm_emac_ndo_open - EMAC device open
966 * @ndev: network adapter device
967 *
968 * Called when system wants to start the interface.
969 *
970 * Return: 0 for a successful open, or appropriate error code
971 */
icssm_emac_ndo_open(struct net_device * ndev)972 static int icssm_emac_ndo_open(struct net_device *ndev)
973 {
974 struct prueth_emac *emac = netdev_priv(ndev);
975 struct prueth *prueth = emac->prueth;
976 int ret;
977
978 /* set h/w MAC as user might have re-configured */
979 ether_addr_copy(emac->mac_addr, ndev->dev_addr);
980
981 if (!prueth->emac_configured)
982 icssm_prueth_init_ethernet_mode(prueth);
983
984 /* reset and start PRU firmware */
985 if (PRUETH_IS_SWITCH(prueth)) {
986 ret = icssm_prueth_sw_emac_config(emac);
987 if (ret)
988 return ret;
989
990 ret = icssm_prueth_sw_init_fdb_table(prueth);
991 if (ret)
992 return ret;
993 } else {
994 icssm_prueth_emac_config(emac);
995 }
996
997 if (!prueth->emac_configured) {
998 icssm_ptp_dram_init(emac);
999 ret = icss_iep_init(prueth->iep, NULL, NULL, 0);
1000 if (ret) {
1001 netdev_err(ndev, "Failed to initialize iep: %d\n", ret);
1002 goto free_mem;
1003 }
1004 }
1005
1006 if (!PRUETH_IS_EMAC(prueth)) {
1007 ret = icssm_prueth_sw_boot_prus(prueth, ndev);
1008 if (ret)
1009 goto iep_exit;
1010 } else {
1011 /* boot the PRU */
1012 ret = icssm_emac_set_boot_pru(emac, ndev);
1013 if (ret)
1014 goto iep_exit;
1015 }
1016
1017 ret = icssm_emac_request_irqs(emac);
1018 if (ret)
1019 goto rproc_shutdown;
1020
1021 napi_enable(&emac->napi);
1022
1023 /* start PHY */
1024 phy_start(emac->phydev);
1025
1026 /* enable the port and vlan */
1027 icssm_prueth_port_enable(emac, true);
1028
1029 prueth->emac_configured |= BIT(emac->port_id);
1030 if (PRUETH_IS_SWITCH(prueth))
1031 icssm_prueth_sw_set_stp_state(prueth, emac->port_id,
1032 BR_STATE_LEARNING);
1033 if (netif_msg_drv(emac))
1034 dev_notice(&ndev->dev, "started\n");
1035
1036 return 0;
1037
1038 rproc_shutdown:
1039 if (!PRUETH_IS_EMAC(prueth))
1040 icssm_prueth_sw_shutdown_prus(emac, ndev);
1041 else
1042 rproc_shutdown(emac->pru);
1043
1044 iep_exit:
1045 if (!prueth->emac_configured)
1046 icss_iep_exit(prueth->iep);
1047 free_mem:
1048 icssm_prueth_free_memory(emac->prueth);
1049 return ret;
1050 }
1051
1052 /**
1053 * icssm_emac_ndo_stop - EMAC device stop
1054 * @ndev: network adapter device
1055 *
1056 * Called when system wants to stop or down the interface.
1057 *
1058 * Return: Always 0 (Success)
1059 */
icssm_emac_ndo_stop(struct net_device * ndev)1060 static int icssm_emac_ndo_stop(struct net_device *ndev)
1061 {
1062 struct prueth_emac *emac = netdev_priv(ndev);
1063 struct prueth *prueth = emac->prueth;
1064
1065 prueth->emac_configured &= ~BIT(emac->port_id);
1066
1067 /* disable the mac port */
1068 icssm_prueth_port_enable(emac, false);
1069
1070 /* stop PHY */
1071 phy_stop(emac->phydev);
1072
1073 napi_disable(&emac->napi);
1074 hrtimer_cancel(&emac->tx_hrtimer);
1075
1076 /* stop the PRU */
1077 if (!PRUETH_IS_EMAC(prueth))
1078 icssm_prueth_sw_shutdown_prus(emac, ndev);
1079 else
1080 rproc_shutdown(emac->pru);
1081
1082 /* free rx interrupts */
1083 free_irq(emac->rx_irq, ndev);
1084
1085 /* free memory related to sw */
1086 icssm_prueth_free_memory(emac->prueth);
1087
1088 if (!prueth->emac_configured)
1089 icss_iep_exit(prueth->iep);
1090
1091 if (netif_msg_drv(emac))
1092 dev_notice(&ndev->dev, "stopped\n");
1093
1094 return 0;
1095 }
1096
icssm_prueth_change_mode(struct prueth * prueth,enum pruss_ethtype mode)1097 static int icssm_prueth_change_mode(struct prueth *prueth,
1098 enum pruss_ethtype mode)
1099 {
1100 bool portstatus[PRUETH_NUM_MACS];
1101 struct prueth_emac *emac;
1102 struct net_device *ndev;
1103 int i, ret;
1104
1105 for (i = 0; i < PRUETH_NUM_MACS; i++) {
1106 if (!prueth->emac[i]) {
1107 dev_err(prueth->dev, "Unknown MAC port\n");
1108 return -EINVAL;
1109 }
1110
1111 emac = prueth->emac[i];
1112 ndev = emac->ndev;
1113
1114 portstatus[i] = netif_running(ndev);
1115 if (!portstatus[i])
1116 continue;
1117
1118 ret = ndev->netdev_ops->ndo_stop(ndev);
1119 if (ret < 0) {
1120 netdev_err(ndev, "failed to stop: %d", ret);
1121 return ret;
1122 }
1123 }
1124
1125 if (mode == PRUSS_ETHTYPE_EMAC || mode == PRUSS_ETHTYPE_SWITCH) {
1126 prueth->eth_type = mode;
1127 } else {
1128 dev_err(prueth->dev, "unknown mode\n");
1129 return -EINVAL;
1130 }
1131
1132 for (i = 0; i < PRUETH_NUM_MACS; i++) {
1133 if (!prueth->emac[i]) {
1134 dev_err(prueth->dev, "Unknown MAC port\n");
1135 return -EINVAL;
1136 }
1137
1138 emac = prueth->emac[i];
1139 ndev = emac->ndev;
1140
1141 if (!portstatus[i])
1142 continue;
1143
1144 ret = ndev->netdev_ops->ndo_open(ndev);
1145 if (ret < 0) {
1146 netdev_err(ndev, "failed to start: %d", ret);
1147 return ret;
1148 }
1149 }
1150
1151 return 0;
1152 }
1153
1154 /* VLAN-tag PCP to priority queue map for EMAC/Switch/HSR/PRP used by driver
1155 * Index is PCP val / 2.
1156 * low - pcp 0..3 maps to Q4 for Host
1157 * high - pcp 4..7 maps to Q3 for Host
1158 * low - pcp 0..3 maps to Q2 (FWD Queue) for PRU-x
1159 * where x = 1 for PRUETH_PORT_MII0
1160 * 0 for PRUETH_PORT_MII1
1161 * high - pcp 4..7 maps to Q1 (FWD Queue) for PRU-x
1162 */
1163 static const unsigned short emac_pcp_tx_priority_queue_map[] = {
1164 PRUETH_QUEUE4, PRUETH_QUEUE4,
1165 PRUETH_QUEUE3, PRUETH_QUEUE3,
1166 PRUETH_QUEUE2, PRUETH_QUEUE2,
1167 PRUETH_QUEUE1, PRUETH_QUEUE1,
1168 };
1169
icssm_prueth_get_tx_queue_id(struct prueth * prueth,struct sk_buff * skb)1170 static u16 icssm_prueth_get_tx_queue_id(struct prueth *prueth,
1171 struct sk_buff *skb)
1172 {
1173 u16 vlan_tci, pcp;
1174 int err;
1175
1176 err = vlan_get_tag(skb, &vlan_tci);
1177 if (likely(err))
1178 pcp = 0;
1179 else
1180 pcp = (vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
1181
1182 /* Below code (pcp >>= 1) is made common for all
1183 * protocols (i.e., EMAC, RSTP, HSR and PRP)*
1184 * pcp value 0,1 will be updated to 0 mapped to QUEUE4
1185 * pcp value 2,3 will be updated to 1 mapped to QUEUE4
1186 * pcp value 4,5 will be updated to 2 mapped to QUEUE3
1187 * pcp value 6,7 will be updated to 3 mapped to QUEUE3
1188 */
1189 pcp >>= 1;
1190
1191 return emac_pcp_tx_priority_queue_map[pcp];
1192 }
1193
1194 /**
1195 * icssm_emac_ndo_start_xmit - EMAC Transmit function
1196 * @skb: SKB pointer
1197 * @ndev: EMAC network adapter
1198 *
1199 * Called by the system to transmit a packet - we queue the packet in
1200 * EMAC hardware transmit queue
1201 *
1202 * Return: enum netdev_tx
1203 */
icssm_emac_ndo_start_xmit(struct sk_buff * skb,struct net_device * ndev)1204 static enum netdev_tx icssm_emac_ndo_start_xmit(struct sk_buff *skb,
1205 struct net_device *ndev)
1206 {
1207 struct prueth_emac *emac = netdev_priv(ndev);
1208 int ret;
1209 u16 qid;
1210
1211 qid = icssm_prueth_get_tx_queue_id(emac->prueth, skb);
1212 ret = icssm_prueth_tx_enqueue(emac, skb, qid);
1213 if (ret) {
1214 if (ret != -ENOBUFS && netif_msg_tx_err(emac) &&
1215 net_ratelimit())
1216 netdev_err(ndev, "packet queue failed: %d\n", ret);
1217 goto fail_tx;
1218 }
1219
1220 emac->stats.tx_packets++;
1221 emac->stats.tx_bytes += skb->len;
1222 dev_kfree_skb_any(skb);
1223
1224 return NETDEV_TX_OK;
1225
1226 fail_tx:
1227 if (ret == -ENOBUFS) {
1228 netif_stop_queue(ndev);
1229 hrtimer_start(&emac->tx_hrtimer,
1230 us_to_ktime(HR_TIMER_TX_DELAY_US),
1231 HRTIMER_MODE_REL_PINNED);
1232 ret = NETDEV_TX_BUSY;
1233 } else {
1234 /* error */
1235 emac->stats.tx_dropped++;
1236 ret = NET_XMIT_DROP;
1237 }
1238
1239 return ret;
1240 }
1241
1242 /**
1243 * icssm_emac_ndo_get_stats64 - EMAC get statistics function
1244 * @ndev: The EMAC network adapter
1245 * @stats: rtnl_link_stats structure
1246 *
1247 * Called when system wants to get statistics from the device.
1248 *
1249 */
icssm_emac_ndo_get_stats64(struct net_device * ndev,struct rtnl_link_stats64 * stats)1250 static void icssm_emac_ndo_get_stats64(struct net_device *ndev,
1251 struct rtnl_link_stats64 *stats)
1252 {
1253 struct prueth_emac *emac = netdev_priv(ndev);
1254
1255 stats->rx_packets = emac->stats.rx_packets;
1256 stats->rx_bytes = emac->stats.rx_bytes;
1257 stats->tx_packets = emac->stats.tx_packets;
1258 stats->tx_bytes = emac->stats.tx_bytes;
1259 stats->tx_dropped = emac->stats.tx_dropped;
1260 stats->rx_over_errors = emac->stats.rx_over_errors;
1261 stats->rx_length_errors = emac->stats.rx_length_errors;
1262 }
1263
1264 /* enable/disable MC filter */
icssm_emac_mc_filter_ctrl(struct prueth_emac * emac,bool enable)1265 static void icssm_emac_mc_filter_ctrl(struct prueth_emac *emac, bool enable)
1266 {
1267 struct prueth *prueth = emac->prueth;
1268 void __iomem *mc_filter_ctrl;
1269 void __iomem *ram;
1270 u32 reg;
1271
1272 ram = prueth->mem[emac->dram].va;
1273 mc_filter_ctrl = ram + ICSS_EMAC_FW_MULTICAST_FILTER_CTRL_OFFSET;
1274
1275 if (enable)
1276 reg = ICSS_EMAC_FW_MULTICAST_FILTER_CTRL_ENABLED;
1277 else
1278 reg = ICSS_EMAC_FW_MULTICAST_FILTER_CTRL_DISABLED;
1279
1280 writeb(reg, mc_filter_ctrl);
1281 }
1282
1283 /* reset MC filter bins */
icssm_emac_mc_filter_reset(struct prueth_emac * emac)1284 static void icssm_emac_mc_filter_reset(struct prueth_emac *emac)
1285 {
1286 struct prueth *prueth = emac->prueth;
1287 void __iomem *mc_filter_tbl;
1288 u32 mc_filter_tbl_base;
1289 void __iomem *ram;
1290
1291 ram = prueth->mem[emac->dram].va;
1292 mc_filter_tbl_base = ICSS_EMAC_FW_MULTICAST_FILTER_TABLE;
1293
1294 mc_filter_tbl = ram + mc_filter_tbl_base;
1295 memset_io(mc_filter_tbl, 0, ICSS_EMAC_FW_MULTICAST_TABLE_SIZE_BYTES);
1296 }
1297
1298 /* set MC filter hashmask */
icssm_emac_mc_filter_hashmask(struct prueth_emac * emac,u8 mask[ICSS_EMAC_FW_MULTICAST_FILTER_MASK_SIZE_BYTES])1299 static void icssm_emac_mc_filter_hashmask
1300 (struct prueth_emac *emac,
1301 u8 mask[ICSS_EMAC_FW_MULTICAST_FILTER_MASK_SIZE_BYTES])
1302 {
1303 struct prueth *prueth = emac->prueth;
1304 void __iomem *mc_filter_mask;
1305 void __iomem *ram;
1306
1307 ram = prueth->mem[emac->dram].va;
1308
1309 mc_filter_mask = ram + ICSS_EMAC_FW_MULTICAST_FILTER_MASK_OFFSET;
1310 memcpy_toio(mc_filter_mask, mask,
1311 ICSS_EMAC_FW_MULTICAST_FILTER_MASK_SIZE_BYTES);
1312 }
1313
icssm_emac_mc_filter_bin_update(struct prueth_emac * emac,u8 hash,u8 val)1314 static void icssm_emac_mc_filter_bin_update(struct prueth_emac *emac, u8 hash,
1315 u8 val)
1316 {
1317 struct prueth *prueth = emac->prueth;
1318 void __iomem *mc_filter_tbl;
1319 void __iomem *ram;
1320
1321 ram = prueth->mem[emac->dram].va;
1322
1323 mc_filter_tbl = ram + ICSS_EMAC_FW_MULTICAST_FILTER_TABLE;
1324 writeb(val, mc_filter_tbl + hash);
1325 }
1326
icssm_emac_mc_filter_bin_allow(struct prueth_emac * emac,u8 hash)1327 void icssm_emac_mc_filter_bin_allow(struct prueth_emac *emac, u8 hash)
1328 {
1329 icssm_emac_mc_filter_bin_update
1330 (emac, hash,
1331 ICSS_EMAC_FW_MULTICAST_FILTER_HOST_RCV_ALLOWED);
1332 }
1333
icssm_emac_mc_filter_bin_disallow(struct prueth_emac * emac,u8 hash)1334 void icssm_emac_mc_filter_bin_disallow(struct prueth_emac *emac, u8 hash)
1335 {
1336 icssm_emac_mc_filter_bin_update
1337 (emac, hash,
1338 ICSS_EMAC_FW_MULTICAST_FILTER_HOST_RCV_NOT_ALLOWED);
1339 }
1340
icssm_emac_get_mc_hash(u8 * mac,u8 * mask)1341 u8 icssm_emac_get_mc_hash(u8 *mac, u8 *mask)
1342 {
1343 u8 hash;
1344 int j;
1345
1346 for (j = 0, hash = 0; j < ETH_ALEN; j++)
1347 hash ^= (mac[j] & mask[j]);
1348
1349 return hash;
1350 }
1351
1352 /**
1353 * icssm_emac_ndo_set_rx_mode - EMAC set receive mode function
1354 * @ndev: The EMAC network adapter
1355 *
1356 * Called when system wants to set the receive mode of the device.
1357 *
1358 */
icssm_emac_ndo_set_rx_mode(struct net_device * ndev)1359 static void icssm_emac_ndo_set_rx_mode(struct net_device *ndev)
1360 {
1361 struct prueth_emac *emac = netdev_priv(ndev);
1362 bool promisc = ndev->flags & IFF_PROMISC;
1363 struct netdev_hw_addr *ha;
1364 struct prueth *prueth;
1365 unsigned long flags;
1366 void __iomem *sram;
1367 u32 mask, reg;
1368 u8 hash;
1369
1370 prueth = emac->prueth;
1371 sram = prueth->mem[PRUETH_MEM_SHARED_RAM].va;
1372 reg = readl(sram + EMAC_PROMISCUOUS_MODE_OFFSET);
1373
1374 /* It is a shared table. So lock the access */
1375 spin_lock_irqsave(&emac->addr_lock, flags);
1376
1377 /* Disable and reset multicast filter, allows allmulti */
1378 icssm_emac_mc_filter_ctrl(emac, false);
1379 icssm_emac_mc_filter_reset(emac);
1380 icssm_emac_mc_filter_hashmask(emac, emac->mc_filter_mask);
1381
1382 if (PRUETH_IS_EMAC(prueth)) {
1383 switch (emac->port_id) {
1384 case PRUETH_PORT_MII0:
1385 mask = EMAC_P1_PROMISCUOUS_BIT;
1386 break;
1387 case PRUETH_PORT_MII1:
1388 mask = EMAC_P2_PROMISCUOUS_BIT;
1389 break;
1390 default:
1391 netdev_err(ndev, "%s: invalid port\n", __func__);
1392 goto unlock;
1393 }
1394
1395 if (promisc) {
1396 /* Enable promiscuous mode */
1397 reg |= mask;
1398 } else {
1399 /* Disable promiscuous mode */
1400 reg &= ~mask;
1401 }
1402
1403 writel(reg, sram + EMAC_PROMISCUOUS_MODE_OFFSET);
1404
1405 if (promisc)
1406 goto unlock;
1407 }
1408
1409 if (ndev->flags & IFF_ALLMULTI && !PRUETH_IS_SWITCH(prueth))
1410 goto unlock;
1411
1412 icssm_emac_mc_filter_ctrl(emac, true); /* all multicast blocked */
1413
1414 if (netdev_mc_empty(ndev))
1415 goto unlock;
1416
1417 netdev_for_each_mc_addr(ha, ndev) {
1418 hash = icssm_emac_get_mc_hash(ha->addr, emac->mc_filter_mask);
1419 icssm_emac_mc_filter_bin_allow(emac, hash);
1420 }
1421
1422 /* Add bridge device's MC addresses as well */
1423 if (prueth->hw_bridge_dev) {
1424 netdev_for_each_mc_addr(ha, prueth->hw_bridge_dev) {
1425 hash = icssm_emac_get_mc_hash(ha->addr,
1426 emac->mc_filter_mask);
1427 icssm_emac_mc_filter_bin_allow(emac, hash);
1428 }
1429 }
1430
1431 unlock:
1432 spin_unlock_irqrestore(&emac->addr_lock, flags);
1433 }
1434
1435 static const struct net_device_ops emac_netdev_ops = {
1436 .ndo_open = icssm_emac_ndo_open,
1437 .ndo_stop = icssm_emac_ndo_stop,
1438 .ndo_start_xmit = icssm_emac_ndo_start_xmit,
1439 .ndo_get_stats64 = icssm_emac_ndo_get_stats64,
1440 .ndo_set_rx_mode = icssm_emac_ndo_set_rx_mode,
1441 };
1442
1443 /* get emac_port corresponding to eth_node name */
icssm_prueth_node_port(struct device_node * eth_node)1444 static int icssm_prueth_node_port(struct device_node *eth_node)
1445 {
1446 u32 port_id;
1447 int ret;
1448
1449 ret = of_property_read_u32(eth_node, "reg", &port_id);
1450 if (ret)
1451 return ret;
1452
1453 if (port_id == 0)
1454 return PRUETH_PORT_MII0;
1455 else if (port_id == 1)
1456 return PRUETH_PORT_MII1;
1457 else
1458 return PRUETH_PORT_INVALID;
1459 }
1460
1461 /* get MAC instance corresponding to eth_node name */
icssm_prueth_node_mac(struct device_node * eth_node)1462 static int icssm_prueth_node_mac(struct device_node *eth_node)
1463 {
1464 u32 port_id;
1465 int ret;
1466
1467 ret = of_property_read_u32(eth_node, "reg", &port_id);
1468 if (ret)
1469 return ret;
1470
1471 if (port_id == 0)
1472 return PRUETH_MAC0;
1473 else if (port_id == 1)
1474 return PRUETH_MAC1;
1475 else
1476 return PRUETH_MAC_INVALID;
1477 }
1478
icssm_emac_tx_timer_callback(struct hrtimer * timer)1479 static enum hrtimer_restart icssm_emac_tx_timer_callback(struct hrtimer *timer)
1480 {
1481 struct prueth_emac *emac =
1482 container_of(timer, struct prueth_emac, tx_hrtimer);
1483
1484 if (netif_queue_stopped(emac->ndev))
1485 netif_wake_queue(emac->ndev);
1486
1487 return HRTIMER_NORESTART;
1488 }
1489
icssm_prueth_netdev_init(struct prueth * prueth,struct device_node * eth_node)1490 static int icssm_prueth_netdev_init(struct prueth *prueth,
1491 struct device_node *eth_node)
1492 {
1493 const struct prueth_private_data *fw_data = prueth->fw_data;
1494 struct prueth_emac *emac;
1495 struct net_device *ndev;
1496 enum prueth_port port;
1497 enum prueth_mac mac;
1498 int ret;
1499
1500 port = icssm_prueth_node_port(eth_node);
1501 if (port == PRUETH_PORT_INVALID)
1502 return -EINVAL;
1503
1504 mac = icssm_prueth_node_mac(eth_node);
1505 if (mac == PRUETH_MAC_INVALID)
1506 return -EINVAL;
1507
1508 ndev = devm_alloc_etherdev(prueth->dev, sizeof(*emac));
1509 if (!ndev)
1510 return -ENOMEM;
1511
1512 SET_NETDEV_DEV(ndev, prueth->dev);
1513 emac = netdev_priv(ndev);
1514 prueth->emac[mac] = emac;
1515 emac->prueth = prueth;
1516 emac->ndev = ndev;
1517 emac->port_id = port;
1518 memset(&emac->mc_filter_mask[0], 0xff, ETH_ALEN);
1519
1520 /* by default eth_type is EMAC */
1521 switch (port) {
1522 case PRUETH_PORT_MII0:
1523 emac->tx_port_queue = PRUETH_PORT_QUEUE_MII0;
1524
1525 /* packets from MII0 are on queues 1 through 2 */
1526 emac->rx_queue_start = PRUETH_QUEUE1;
1527 emac->rx_queue_end = PRUETH_QUEUE2;
1528
1529 emac->dram = PRUETH_MEM_DRAM0;
1530 emac->pru = prueth->pru0;
1531 break;
1532 case PRUETH_PORT_MII1:
1533 emac->tx_port_queue = PRUETH_PORT_QUEUE_MII1;
1534
1535 /* packets from MII1 are on queues 3 through 4 */
1536 emac->rx_queue_start = PRUETH_QUEUE3;
1537 emac->rx_queue_end = PRUETH_QUEUE4;
1538
1539 emac->dram = PRUETH_MEM_DRAM1;
1540 emac->pru = prueth->pru1;
1541 break;
1542 default:
1543 return -EINVAL;
1544 }
1545
1546 emac->rx_irq = of_irq_get_byname(eth_node, "rx");
1547 if (emac->rx_irq < 0) {
1548 ret = emac->rx_irq;
1549 if (ret != -EPROBE_DEFER)
1550 dev_err(prueth->dev, "could not get rx irq\n");
1551 goto free;
1552 }
1553
1554 spin_lock_init(&emac->lock);
1555 spin_lock_init(&emac->addr_lock);
1556
1557 /* get mac address from DT and set private and netdev addr */
1558 ret = of_get_ethdev_address(eth_node, ndev);
1559 if (!is_valid_ether_addr(ndev->dev_addr)) {
1560 eth_hw_addr_random(ndev);
1561 dev_warn(prueth->dev, "port %d: using random MAC addr: %pM\n",
1562 port, ndev->dev_addr);
1563 }
1564 ether_addr_copy(emac->mac_addr, ndev->dev_addr);
1565
1566 ndev->netdev_ops = &emac_netdev_ops;
1567
1568 /* connect PHY */
1569 emac->phydev = of_phy_get_and_connect(ndev, eth_node,
1570 icssm_emac_adjust_link);
1571 if (!emac->phydev) {
1572 dev_dbg(prueth->dev, "PHY connection failed\n");
1573 ret = -ENODEV;
1574 goto free;
1575 }
1576
1577 /* remove unsupported modes */
1578 phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
1579
1580 phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
1581 phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
1582
1583 phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Pause_BIT);
1584 phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT);
1585
1586 /* Protocol switching
1587 * Enabling L2 Firmware offloading
1588 */
1589 if (fw_data->support_switch) {
1590 ndev->features |= NETIF_F_HW_L2FW_DOFFLOAD;
1591 ndev->hw_features |= NETIF_F_HW_L2FW_DOFFLOAD;
1592 }
1593
1594 ndev->dev.of_node = eth_node;
1595
1596 netif_napi_add(ndev, &emac->napi, icssm_emac_napi_poll);
1597
1598 hrtimer_setup(&emac->tx_hrtimer, &icssm_emac_tx_timer_callback,
1599 CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED);
1600
1601 return 0;
1602 free:
1603 emac->ndev = NULL;
1604 prueth->emac[mac] = NULL;
1605
1606 return ret;
1607 }
1608
icssm_prueth_netdev_exit(struct prueth * prueth,struct device_node * eth_node)1609 static void icssm_prueth_netdev_exit(struct prueth *prueth,
1610 struct device_node *eth_node)
1611 {
1612 struct prueth_emac *emac;
1613 enum prueth_mac mac;
1614
1615 mac = icssm_prueth_node_mac(eth_node);
1616 if (mac == PRUETH_MAC_INVALID)
1617 return;
1618
1619 emac = prueth->emac[mac];
1620 if (!emac)
1621 return;
1622
1623 phy_disconnect(emac->phydev);
1624
1625 netif_napi_del(&emac->napi);
1626 prueth->emac[mac] = NULL;
1627 }
1628
icssm_prueth_sw_port_dev_check(const struct net_device * ndev)1629 bool icssm_prueth_sw_port_dev_check(const struct net_device *ndev)
1630 {
1631 if (ndev->netdev_ops != &emac_netdev_ops)
1632 return false;
1633
1634 if (ndev->features & NETIF_F_HW_L2FW_DOFFLOAD)
1635 return true;
1636
1637 return false;
1638 }
1639
icssm_prueth_port_offload_fwd_mark_update(struct prueth * prueth)1640 static int icssm_prueth_port_offload_fwd_mark_update(struct prueth *prueth)
1641 {
1642 int set_val = 0;
1643 int i, ret = 0;
1644 u8 all_slaves;
1645
1646 all_slaves = BIT(PRUETH_PORT_MII0) | BIT(PRUETH_PORT_MII1);
1647
1648 if (prueth->br_members == all_slaves)
1649 set_val = 1;
1650
1651 dev_dbg(prueth->dev, "set offload_fwd_mark %d, mbrs=0x%x\n",
1652 set_val, prueth->br_members);
1653
1654 for (i = 0; i < PRUETH_NUM_MACS; i++) {
1655 if (prueth->emac[i])
1656 WRITE_ONCE(prueth->emac[i]->offload_fwd_mark, set_val);
1657 }
1658
1659 /* Bridge is created, load switch firmware,
1660 * if not already in that mode
1661 */
1662 if (set_val && !PRUETH_IS_SWITCH(prueth)) {
1663 ret = icssm_prueth_change_mode(prueth, PRUSS_ETHTYPE_SWITCH);
1664 if (ret < 0)
1665 dev_err(prueth->dev, "Failed to enable Switch mode\n");
1666 else
1667 dev_info(prueth->dev,
1668 "TI PRU ethernet now in Switch mode\n");
1669 }
1670
1671 /* Bridge is deleted, switch to Dual EMAC mode */
1672 if (!prueth->br_members && !PRUETH_IS_EMAC(prueth)) {
1673 ret = icssm_prueth_change_mode(prueth, PRUSS_ETHTYPE_EMAC);
1674 if (ret < 0)
1675 dev_err(prueth->dev, "Failed to enable Dual EMAC mode\n");
1676 else
1677 dev_info(prueth->dev,
1678 "TI PRU ethernet now in Dual EMAC mode\n");
1679 }
1680
1681 return ret;
1682 }
1683
icssm_prueth_ndev_port_link(struct net_device * ndev,struct net_device * br_ndev)1684 static int icssm_prueth_ndev_port_link(struct net_device *ndev,
1685 struct net_device *br_ndev)
1686 {
1687 struct prueth_emac *emac = netdev_priv(ndev);
1688 struct prueth *prueth = emac->prueth;
1689 unsigned long flags;
1690 int ret = 0;
1691
1692 dev_dbg(prueth->dev, "%s: br_mbrs=0x%x %s\n",
1693 __func__, prueth->br_members, ndev->name);
1694
1695 spin_lock_irqsave(&emac->addr_lock, flags);
1696
1697 if (!prueth->br_members) {
1698 prueth->hw_bridge_dev = br_ndev;
1699 } else {
1700 /* This is adding the port to a second bridge,
1701 * this is unsupported
1702 */
1703 if (prueth->hw_bridge_dev != br_ndev) {
1704 spin_unlock_irqrestore(&emac->addr_lock, flags);
1705 return -EOPNOTSUPP;
1706 }
1707 }
1708
1709 prueth->br_members |= BIT(emac->port_id);
1710
1711 spin_unlock_irqrestore(&emac->addr_lock, flags);
1712
1713 ret = icssm_prueth_port_offload_fwd_mark_update(prueth);
1714
1715 return ret;
1716 }
1717
icssm_prueth_ndev_port_unlink(struct net_device * ndev)1718 static int icssm_prueth_ndev_port_unlink(struct net_device *ndev)
1719 {
1720 struct prueth_emac *emac = netdev_priv(ndev);
1721 struct prueth *prueth = emac->prueth;
1722 unsigned long flags;
1723 int ret = 0;
1724
1725 dev_dbg(prueth->dev, "emac_sw_ndev_port_unlink\n");
1726
1727 spin_lock_irqsave(&emac->addr_lock, flags);
1728
1729 prueth->br_members &= ~BIT(emac->port_id);
1730
1731 spin_unlock_irqrestore(&emac->addr_lock, flags);
1732
1733 ret = icssm_prueth_port_offload_fwd_mark_update(prueth);
1734
1735 spin_lock_irqsave(&emac->addr_lock, flags);
1736
1737 if (!prueth->br_members)
1738 prueth->hw_bridge_dev = NULL;
1739
1740 spin_unlock_irqrestore(&emac->addr_lock, flags);
1741
1742 return ret;
1743 }
1744
icssm_prueth_ndev_event(struct notifier_block * unused,unsigned long event,void * ptr)1745 static int icssm_prueth_ndev_event(struct notifier_block *unused,
1746 unsigned long event, void *ptr)
1747 {
1748 struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
1749 struct netdev_notifier_changeupper_info *info;
1750 int ret = NOTIFY_DONE;
1751
1752 if (!icssm_prueth_sw_port_dev_check(ndev))
1753 return NOTIFY_DONE;
1754
1755 switch (event) {
1756 case NETDEV_CHANGEUPPER:
1757 info = ptr;
1758 if (netif_is_bridge_master(info->upper_dev)) {
1759 if (info->linking)
1760 ret = icssm_prueth_ndev_port_link
1761 (ndev, info->upper_dev);
1762 else
1763 ret = icssm_prueth_ndev_port_unlink(ndev);
1764 }
1765 break;
1766 default:
1767 return NOTIFY_DONE;
1768 }
1769
1770 return notifier_from_errno(ret);
1771 }
1772
icssm_prueth_register_notifiers(struct prueth * prueth)1773 static int icssm_prueth_register_notifiers(struct prueth *prueth)
1774 {
1775 int ret = 0;
1776
1777 prueth->prueth_netdevice_nb.notifier_call = icssm_prueth_ndev_event;
1778 ret = register_netdevice_notifier(&prueth->prueth_netdevice_nb);
1779 if (ret) {
1780 dev_err(prueth->dev,
1781 "register netdevice notifier failed ret: %d\n", ret);
1782 return ret;
1783 }
1784
1785 ret = icssm_prueth_sw_register_notifiers(prueth);
1786 if (ret)
1787 unregister_netdevice_notifier(&prueth->prueth_netdevice_nb);
1788
1789 return ret;
1790 }
1791
icssm_prueth_probe(struct platform_device * pdev)1792 static int icssm_prueth_probe(struct platform_device *pdev)
1793 {
1794 struct device_node *eth0_node = NULL, *eth1_node = NULL;
1795 struct device_node *eth_node, *eth_ports_node;
1796 enum pruss_pru_id pruss_id0, pruss_id1;
1797 struct device *dev = &pdev->dev;
1798 struct device_node *np;
1799 struct prueth *prueth;
1800 struct pruss *pruss;
1801 int i, ret;
1802
1803 np = dev->of_node;
1804 if (!np)
1805 return -ENODEV; /* we don't support non DT */
1806
1807 prueth = devm_kzalloc(dev, sizeof(*prueth), GFP_KERNEL);
1808 if (!prueth)
1809 return -ENOMEM;
1810
1811 platform_set_drvdata(pdev, prueth);
1812 prueth->dev = dev;
1813 prueth->fw_data = device_get_match_data(dev);
1814
1815 eth_ports_node = of_get_child_by_name(np, "ethernet-ports");
1816 if (!eth_ports_node)
1817 return -ENOENT;
1818
1819 for_each_child_of_node(eth_ports_node, eth_node) {
1820 u32 reg;
1821
1822 if (strcmp(eth_node->name, "ethernet-port"))
1823 continue;
1824 ret = of_property_read_u32(eth_node, "reg", ®);
1825 if (ret < 0) {
1826 dev_err(dev, "%pOF error reading port_id %d\n",
1827 eth_node, ret);
1828 of_node_put(eth_node);
1829 of_node_put(eth_ports_node);
1830 return ret;
1831 }
1832
1833 of_node_get(eth_node);
1834
1835 if (reg == 0 && !eth0_node) {
1836 eth0_node = eth_node;
1837 if (!of_device_is_available(eth0_node)) {
1838 of_node_put(eth0_node);
1839 eth0_node = NULL;
1840 }
1841 } else if (reg == 1 && !eth1_node) {
1842 eth1_node = eth_node;
1843 if (!of_device_is_available(eth1_node)) {
1844 of_node_put(eth1_node);
1845 eth1_node = NULL;
1846 }
1847 } else {
1848 if (reg == 0 || reg == 1)
1849 dev_err(dev, "duplicate port reg value: %d\n",
1850 reg);
1851 else
1852 dev_err(dev, "invalid port reg value: %d\n",
1853 reg);
1854
1855 of_node_put(eth_node);
1856 }
1857 }
1858
1859 of_node_put(eth_ports_node);
1860
1861 /* At least one node must be present and available else we fail */
1862 if (!eth0_node && !eth1_node) {
1863 dev_err(dev, "neither port0 nor port1 node available\n");
1864 return -ENODEV;
1865 }
1866
1867 prueth->eth_node[PRUETH_MAC0] = eth0_node;
1868 prueth->eth_node[PRUETH_MAC1] = eth1_node;
1869
1870 prueth->mii_rt = syscon_regmap_lookup_by_phandle(np, "ti,mii-rt");
1871 if (IS_ERR(prueth->mii_rt)) {
1872 dev_err(dev, "couldn't get mii-rt syscon regmap\n");
1873 ret = PTR_ERR(prueth->mii_rt);
1874 goto put_eth;
1875 }
1876
1877 if (eth0_node) {
1878 prueth->pru0 = pru_rproc_get(np, 0, &pruss_id0);
1879 if (IS_ERR(prueth->pru0)) {
1880 ret = PTR_ERR(prueth->pru0);
1881 dev_err_probe(dev, ret, "unable to get PRU0");
1882 goto put_eth;
1883 }
1884 }
1885
1886 if (eth1_node) {
1887 prueth->pru1 = pru_rproc_get(np, 1, &pruss_id1);
1888 if (IS_ERR(prueth->pru1)) {
1889 ret = PTR_ERR(prueth->pru1);
1890 dev_err_probe(dev, ret, "unable to get PRU1");
1891 goto put_pru0;
1892 }
1893 }
1894
1895 pruss = pruss_get(prueth->pru0 ? prueth->pru0 : prueth->pru1);
1896 if (IS_ERR(pruss)) {
1897 ret = PTR_ERR(pruss);
1898 dev_err(dev, "unable to get pruss handle\n");
1899 goto put_pru1;
1900 }
1901 prueth->pruss = pruss;
1902
1903 /* Configure PRUSS */
1904 if (eth0_node)
1905 pruss_cfg_gpimode(pruss, pruss_id0, PRUSS_GPI_MODE_MII);
1906 if (eth1_node)
1907 pruss_cfg_gpimode(pruss, pruss_id1, PRUSS_GPI_MODE_MII);
1908 pruss_cfg_miirt_enable(pruss, true);
1909 pruss_cfg_xfr_enable(pruss, PRU_TYPE_PRU, true);
1910
1911 /* Get PRUSS mem resources */
1912 /* OCMC is system resource which we get separately */
1913 for (i = 0; i < ARRAY_SIZE(pruss_mem_ids); i++) {
1914 /* skip appropriate DRAM if not required */
1915 if (!eth0_node && i == PRUETH_MEM_DRAM0)
1916 continue;
1917
1918 if (!eth1_node && i == PRUETH_MEM_DRAM1)
1919 continue;
1920
1921 ret = pruss_request_mem_region(pruss, pruss_mem_ids[i],
1922 &prueth->mem[i]);
1923 if (ret) {
1924 dev_err(dev, "unable to get PRUSS resource %d: %d\n",
1925 i, ret);
1926 goto put_mem;
1927 }
1928 }
1929
1930 prueth->sram_pool = of_gen_pool_get(np, "sram", 0);
1931 if (!prueth->sram_pool) {
1932 dev_err(dev, "unable to get SRAM pool\n");
1933 ret = -ENODEV;
1934 goto put_mem;
1935 }
1936
1937 prueth->ocmc_ram_size = OCMC_RAM_SIZE;
1938 /* Decreased by 8KB to address the reserved region for AM33x */
1939 if (prueth->fw_data->driver_data == PRUSS_AM33XX)
1940 prueth->ocmc_ram_size = (SZ_64K - SZ_8K);
1941
1942 prueth->mem[PRUETH_MEM_OCMC].va =
1943 (void __iomem *)gen_pool_alloc(prueth->sram_pool,
1944 prueth->ocmc_ram_size);
1945 if (!prueth->mem[PRUETH_MEM_OCMC].va) {
1946 dev_err(dev, "unable to allocate OCMC resource\n");
1947 ret = -ENOMEM;
1948 goto put_mem;
1949 }
1950 prueth->mem[PRUETH_MEM_OCMC].pa = gen_pool_virt_to_phys
1951 (prueth->sram_pool, (unsigned long)
1952 prueth->mem[PRUETH_MEM_OCMC].va);
1953 prueth->mem[PRUETH_MEM_OCMC].size = prueth->ocmc_ram_size;
1954 dev_dbg(dev, "ocmc: pa %pa va %p size %#zx\n",
1955 &prueth->mem[PRUETH_MEM_OCMC].pa,
1956 prueth->mem[PRUETH_MEM_OCMC].va,
1957 prueth->mem[PRUETH_MEM_OCMC].size);
1958
1959 /* setup netdev interfaces */
1960 if (eth0_node) {
1961 ret = icssm_prueth_netdev_init(prueth, eth0_node);
1962 if (ret) {
1963 if (ret != -EPROBE_DEFER) {
1964 dev_err(dev, "netdev init %s failed: %d\n",
1965 eth0_node->name, ret);
1966 }
1967 goto free_pool;
1968 }
1969 }
1970
1971 if (eth1_node) {
1972 ret = icssm_prueth_netdev_init(prueth, eth1_node);
1973 if (ret) {
1974 if (ret != -EPROBE_DEFER) {
1975 dev_err(dev, "netdev init %s failed: %d\n",
1976 eth1_node->name, ret);
1977 }
1978 goto netdev_exit;
1979 }
1980 }
1981
1982 prueth->iep = icss_iep_get(np);
1983 if (IS_ERR(prueth->iep)) {
1984 ret = PTR_ERR(prueth->iep);
1985 dev_err(dev, "unable to get IEP\n");
1986 goto netdev_exit;
1987 }
1988
1989 /* register the network devices */
1990 if (eth0_node) {
1991 ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev);
1992 if (ret) {
1993 dev_err(dev, "can't register netdev for port MII0");
1994 goto iep_put;
1995 }
1996
1997 prueth->registered_netdevs[PRUETH_MAC0] =
1998 prueth->emac[PRUETH_MAC0]->ndev;
1999 }
2000
2001 if (eth1_node) {
2002 ret = register_netdev(prueth->emac[PRUETH_MAC1]->ndev);
2003 if (ret) {
2004 dev_err(dev, "can't register netdev for port MII1");
2005 goto netdev_unregister;
2006 }
2007
2008 prueth->registered_netdevs[PRUETH_MAC1] =
2009 prueth->emac[PRUETH_MAC1]->ndev;
2010 }
2011
2012 ret = icssm_prueth_register_notifiers(prueth);
2013 if (ret) {
2014 dev_err(dev, "can't register switchdev notifiers");
2015 goto netdev_unregister;
2016 }
2017
2018 dev_info(dev, "TI PRU ethernet driver initialized: %s EMAC mode\n",
2019 (!eth0_node || !eth1_node) ? "single" : "dual");
2020
2021 if (eth1_node)
2022 of_node_put(eth1_node);
2023 if (eth0_node)
2024 of_node_put(eth0_node);
2025 return 0;
2026
2027 netdev_unregister:
2028 for (i = 0; i < PRUETH_NUM_MACS; i++) {
2029 if (!prueth->registered_netdevs[i])
2030 continue;
2031 unregister_netdev(prueth->registered_netdevs[i]);
2032 }
2033
2034 iep_put:
2035 icss_iep_put(prueth->iep);
2036 prueth->iep = NULL;
2037
2038 netdev_exit:
2039 for (i = 0; i < PRUETH_NUM_MACS; i++) {
2040 eth_node = prueth->eth_node[i];
2041 if (!eth_node)
2042 continue;
2043
2044 icssm_prueth_netdev_exit(prueth, eth_node);
2045 }
2046
2047 free_pool:
2048 gen_pool_free(prueth->sram_pool,
2049 (unsigned long)prueth->mem[PRUETH_MEM_OCMC].va,
2050 prueth->ocmc_ram_size);
2051
2052 put_mem:
2053 for (i = PRUETH_MEM_DRAM0; i < PRUETH_MEM_OCMC; i++) {
2054 if (prueth->mem[i].va)
2055 pruss_release_mem_region(pruss, &prueth->mem[i]);
2056 }
2057 pruss_put(prueth->pruss);
2058
2059 put_pru1:
2060 if (eth1_node)
2061 pru_rproc_put(prueth->pru1);
2062 put_pru0:
2063 if (eth0_node)
2064 pru_rproc_put(prueth->pru0);
2065 put_eth:
2066 of_node_put(eth1_node);
2067 of_node_put(eth0_node);
2068
2069 return ret;
2070 }
2071
icssm_prueth_remove(struct platform_device * pdev)2072 static void icssm_prueth_remove(struct platform_device *pdev)
2073 {
2074 struct prueth *prueth = platform_get_drvdata(pdev);
2075 struct device_node *eth_node;
2076 int i;
2077
2078 unregister_netdevice_notifier(&prueth->prueth_netdevice_nb);
2079 icssm_prueth_sw_unregister_notifiers(prueth);
2080
2081 for (i = 0; i < PRUETH_NUM_MACS; i++) {
2082 if (!prueth->registered_netdevs[i])
2083 continue;
2084 unregister_netdev(prueth->registered_netdevs[i]);
2085 }
2086
2087 for (i = 0; i < PRUETH_NUM_MACS; i++) {
2088 eth_node = prueth->eth_node[i];
2089 if (!eth_node)
2090 continue;
2091
2092 icssm_prueth_netdev_exit(prueth, eth_node);
2093 of_node_put(eth_node);
2094 }
2095
2096 gen_pool_free(prueth->sram_pool,
2097 (unsigned long)prueth->mem[PRUETH_MEM_OCMC].va,
2098 prueth->ocmc_ram_size);
2099
2100 for (i = PRUETH_MEM_DRAM0; i < PRUETH_MEM_OCMC; i++) {
2101 if (prueth->mem[i].va)
2102 pruss_release_mem_region(prueth->pruss,
2103 &prueth->mem[i]);
2104 }
2105
2106 icss_iep_put(prueth->iep);
2107 prueth->iep = NULL;
2108
2109 pruss_put(prueth->pruss);
2110
2111 if (prueth->eth_node[PRUETH_MAC0])
2112 pru_rproc_put(prueth->pru0);
2113 if (prueth->eth_node[PRUETH_MAC1])
2114 pru_rproc_put(prueth->pru1);
2115 }
2116
2117 #ifdef CONFIG_PM_SLEEP
icssm_prueth_suspend(struct device * dev)2118 static int icssm_prueth_suspend(struct device *dev)
2119 {
2120 struct prueth *prueth = dev_get_drvdata(dev);
2121 struct net_device *ndev;
2122 int i, ret;
2123
2124 for (i = 0; i < PRUETH_NUM_MACS; i++) {
2125 ndev = prueth->registered_netdevs[i];
2126
2127 if (!ndev)
2128 continue;
2129
2130 if (netif_running(ndev)) {
2131 netif_device_detach(ndev);
2132 ret = icssm_emac_ndo_stop(ndev);
2133 if (ret < 0) {
2134 netdev_err(ndev, "failed to stop: %d", ret);
2135 return ret;
2136 }
2137 }
2138 }
2139
2140 return 0;
2141 }
2142
icssm_prueth_resume(struct device * dev)2143 static int icssm_prueth_resume(struct device *dev)
2144 {
2145 struct prueth *prueth = dev_get_drvdata(dev);
2146 struct net_device *ndev;
2147 int i, ret;
2148
2149 for (i = 0; i < PRUETH_NUM_MACS; i++) {
2150 ndev = prueth->registered_netdevs[i];
2151
2152 if (!ndev)
2153 continue;
2154
2155 if (netif_running(ndev)) {
2156 ret = icssm_emac_ndo_open(ndev);
2157 if (ret < 0) {
2158 netdev_err(ndev, "failed to start: %d", ret);
2159 return ret;
2160 }
2161 netif_device_attach(ndev);
2162 }
2163 }
2164
2165 return 0;
2166 }
2167
2168 #endif /* CONFIG_PM_SLEEP */
2169
2170 static const struct dev_pm_ops prueth_dev_pm_ops = {
2171 SET_SYSTEM_SLEEP_PM_OPS(icssm_prueth_suspend, icssm_prueth_resume)
2172 };
2173
2174 /* AM335x SoC-specific firmware data */
2175 static struct prueth_private_data am335x_prueth_pdata = {
2176 .driver_data = PRUSS_AM33XX,
2177 .fw_pru[PRUSS_PRU0] = {
2178 .fw_name[PRUSS_ETHTYPE_EMAC] =
2179 "ti-pruss/am335x-pru0-prueth-fw.elf",
2180 .fw_name[PRUSS_ETHTYPE_SWITCH] =
2181 "ti-pruss/am335x-pru0-prusw-fw.elf",
2182 },
2183 .fw_pru[PRUSS_PRU1] = {
2184 .fw_name[PRUSS_ETHTYPE_EMAC] =
2185 "ti-pruss/am335x-pru1-prueth-fw.elf",
2186 .fw_name[PRUSS_ETHTYPE_SWITCH] =
2187 "ti-pruss/am335x-pru1-prusw-fw.elf",
2188 },
2189 .support_switch = true,
2190 };
2191
2192 /* AM437x SoC-specific firmware data */
2193 static struct prueth_private_data am437x_prueth_pdata = {
2194 .driver_data = PRUSS_AM43XX,
2195 .fw_pru[PRUSS_PRU0] = {
2196 .fw_name[PRUSS_ETHTYPE_EMAC] =
2197 "ti-pruss/am437x-pru0-prueth-fw.elf",
2198 .fw_name[PRUSS_ETHTYPE_SWITCH] =
2199 "ti-pruss/am437x-pru0-prusw-fw.elf",
2200 },
2201 .fw_pru[PRUSS_PRU1] = {
2202 .fw_name[PRUSS_ETHTYPE_EMAC] =
2203 "ti-pruss/am437x-pru1-prueth-fw.elf",
2204 .fw_name[PRUSS_ETHTYPE_SWITCH] =
2205 "ti-pruss/am437x-pru1-prusw-fw.elf",
2206 },
2207 .support_switch = true,
2208 };
2209
2210 /* AM57xx SoC-specific firmware data */
2211 static struct prueth_private_data am57xx_prueth_pdata = {
2212 .driver_data = PRUSS_AM57XX,
2213 .fw_pru[PRUSS_PRU0] = {
2214 .fw_name[PRUSS_ETHTYPE_EMAC] =
2215 "ti-pruss/am57xx-pru0-prueth-fw.elf",
2216 .fw_name[PRUSS_ETHTYPE_SWITCH] =
2217 "ti-pruss/am57xx-pru0-prusw-fw.elf",
2218 },
2219 .fw_pru[PRUSS_PRU1] = {
2220 .fw_name[PRUSS_ETHTYPE_EMAC] =
2221 "ti-pruss/am57xx-pru1-prueth-fw.elf",
2222 .fw_name[PRUSS_ETHTYPE_SWITCH] =
2223 "ti-pruss/am57xx-pru1-prusw-fw.elf",
2224
2225 },
2226 .support_switch = true,
2227 };
2228
2229 static const struct of_device_id prueth_dt_match[] = {
2230 { .compatible = "ti,am57-prueth", .data = &am57xx_prueth_pdata, },
2231 { .compatible = "ti,am4376-prueth", .data = &am437x_prueth_pdata, },
2232 { .compatible = "ti,am3359-prueth", .data = &am335x_prueth_pdata, },
2233 { /* sentinel */ }
2234 };
2235 MODULE_DEVICE_TABLE(of, prueth_dt_match);
2236
2237 static struct platform_driver prueth_driver = {
2238 .probe = icssm_prueth_probe,
2239 .remove = icssm_prueth_remove,
2240 .driver = {
2241 .name = "prueth",
2242 .of_match_table = prueth_dt_match,
2243 .pm = &prueth_dev_pm_ops,
2244 },
2245 };
2246 module_platform_driver(prueth_driver);
2247
2248 MODULE_AUTHOR("Roger Quadros <rogerq@ti.com>");
2249 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
2250 MODULE_DESCRIPTION("PRUSS ICSSM Ethernet Driver");
2251 MODULE_LICENSE("GPL");
2252