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 /* connect PHY */
1567 emac->phydev = of_phy_get_and_connect(ndev, eth_node,
1568 icssm_emac_adjust_link);
1569 if (!emac->phydev) {
1570 dev_dbg(prueth->dev, "PHY connection failed\n");
1571 ret = -ENODEV;
1572 goto free;
1573 }
1574
1575 /* remove unsupported modes */
1576 phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
1577
1578 phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
1579 phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
1580
1581 phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Pause_BIT);
1582 phy_remove_link_mode(emac->phydev, ETHTOOL_LINK_MODE_Asym_Pause_BIT);
1583
1584 /* Protocol switching
1585 * Enabling L2 Firmware offloading
1586 */
1587 if (fw_data->support_switch) {
1588 ndev->features |= NETIF_F_HW_L2FW_DOFFLOAD;
1589 ndev->hw_features |= NETIF_F_HW_L2FW_DOFFLOAD;
1590 }
1591
1592 ndev->dev.of_node = eth_node;
1593 ndev->netdev_ops = &emac_netdev_ops;
1594
1595 netif_napi_add(ndev, &emac->napi, icssm_emac_napi_poll);
1596
1597 hrtimer_setup(&emac->tx_hrtimer, &icssm_emac_tx_timer_callback,
1598 CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED);
1599
1600 return 0;
1601 free:
1602 emac->ndev = NULL;
1603 prueth->emac[mac] = NULL;
1604
1605 return ret;
1606 }
1607
icssm_prueth_netdev_exit(struct prueth * prueth,struct device_node * eth_node)1608 static void icssm_prueth_netdev_exit(struct prueth *prueth,
1609 struct device_node *eth_node)
1610 {
1611 struct prueth_emac *emac;
1612 enum prueth_mac mac;
1613
1614 mac = icssm_prueth_node_mac(eth_node);
1615 if (mac == PRUETH_MAC_INVALID)
1616 return;
1617
1618 emac = prueth->emac[mac];
1619 if (!emac)
1620 return;
1621
1622 phy_disconnect(emac->phydev);
1623
1624 netif_napi_del(&emac->napi);
1625 prueth->emac[mac] = NULL;
1626 }
1627
icssm_prueth_sw_port_dev_check(const struct net_device * ndev)1628 bool icssm_prueth_sw_port_dev_check(const struct net_device *ndev)
1629 {
1630 if (ndev->netdev_ops != &emac_netdev_ops)
1631 return false;
1632
1633 if (ndev->features & NETIF_F_HW_L2FW_DOFFLOAD)
1634 return true;
1635
1636 return false;
1637 }
1638
icssm_prueth_port_offload_fwd_mark_update(struct prueth * prueth)1639 static int icssm_prueth_port_offload_fwd_mark_update(struct prueth *prueth)
1640 {
1641 int set_val = 0;
1642 int i, ret = 0;
1643 u8 all_slaves;
1644
1645 all_slaves = BIT(PRUETH_PORT_MII0) | BIT(PRUETH_PORT_MII1);
1646
1647 if (prueth->br_members == all_slaves)
1648 set_val = 1;
1649
1650 dev_dbg(prueth->dev, "set offload_fwd_mark %d, mbrs=0x%x\n",
1651 set_val, prueth->br_members);
1652
1653 for (i = 0; i < PRUETH_NUM_MACS; i++) {
1654 if (prueth->emac[i])
1655 WRITE_ONCE(prueth->emac[i]->offload_fwd_mark, set_val);
1656 }
1657
1658 /* Bridge is created, load switch firmware,
1659 * if not already in that mode
1660 */
1661 if (set_val && !PRUETH_IS_SWITCH(prueth)) {
1662 ret = icssm_prueth_change_mode(prueth, PRUSS_ETHTYPE_SWITCH);
1663 if (ret < 0)
1664 dev_err(prueth->dev, "Failed to enable Switch mode\n");
1665 else
1666 dev_info(prueth->dev,
1667 "TI PRU ethernet now in Switch mode\n");
1668 }
1669
1670 /* Bridge is deleted, switch to Dual EMAC mode */
1671 if (!prueth->br_members && !PRUETH_IS_EMAC(prueth)) {
1672 ret = icssm_prueth_change_mode(prueth, PRUSS_ETHTYPE_EMAC);
1673 if (ret < 0)
1674 dev_err(prueth->dev, "Failed to enable Dual EMAC mode\n");
1675 else
1676 dev_info(prueth->dev,
1677 "TI PRU ethernet now in Dual EMAC mode\n");
1678 }
1679
1680 return ret;
1681 }
1682
icssm_prueth_ndev_port_link(struct net_device * ndev,struct net_device * br_ndev)1683 static int icssm_prueth_ndev_port_link(struct net_device *ndev,
1684 struct net_device *br_ndev)
1685 {
1686 struct prueth_emac *emac = netdev_priv(ndev);
1687 struct prueth *prueth = emac->prueth;
1688 unsigned long flags;
1689 int ret = 0;
1690
1691 dev_dbg(prueth->dev, "%s: br_mbrs=0x%x %s\n",
1692 __func__, prueth->br_members, ndev->name);
1693
1694 spin_lock_irqsave(&emac->addr_lock, flags);
1695
1696 if (!prueth->br_members) {
1697 prueth->hw_bridge_dev = br_ndev;
1698 } else {
1699 /* This is adding the port to a second bridge,
1700 * this is unsupported
1701 */
1702 if (prueth->hw_bridge_dev != br_ndev) {
1703 spin_unlock_irqrestore(&emac->addr_lock, flags);
1704 return -EOPNOTSUPP;
1705 }
1706 }
1707
1708 prueth->br_members |= BIT(emac->port_id);
1709
1710 spin_unlock_irqrestore(&emac->addr_lock, flags);
1711
1712 ret = icssm_prueth_port_offload_fwd_mark_update(prueth);
1713
1714 return ret;
1715 }
1716
icssm_prueth_ndev_port_unlink(struct net_device * ndev)1717 static int icssm_prueth_ndev_port_unlink(struct net_device *ndev)
1718 {
1719 struct prueth_emac *emac = netdev_priv(ndev);
1720 struct prueth *prueth = emac->prueth;
1721 unsigned long flags;
1722 int ret = 0;
1723
1724 dev_dbg(prueth->dev, "emac_sw_ndev_port_unlink\n");
1725
1726 spin_lock_irqsave(&emac->addr_lock, flags);
1727
1728 prueth->br_members &= ~BIT(emac->port_id);
1729
1730 spin_unlock_irqrestore(&emac->addr_lock, flags);
1731
1732 ret = icssm_prueth_port_offload_fwd_mark_update(prueth);
1733
1734 spin_lock_irqsave(&emac->addr_lock, flags);
1735
1736 if (!prueth->br_members)
1737 prueth->hw_bridge_dev = NULL;
1738
1739 spin_unlock_irqrestore(&emac->addr_lock, flags);
1740
1741 return ret;
1742 }
1743
icssm_prueth_ndev_event(struct notifier_block * unused,unsigned long event,void * ptr)1744 static int icssm_prueth_ndev_event(struct notifier_block *unused,
1745 unsigned long event, void *ptr)
1746 {
1747 struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
1748 struct netdev_notifier_changeupper_info *info;
1749 int ret = NOTIFY_DONE;
1750
1751 if (!icssm_prueth_sw_port_dev_check(ndev))
1752 return NOTIFY_DONE;
1753
1754 switch (event) {
1755 case NETDEV_CHANGEUPPER:
1756 info = ptr;
1757 if (netif_is_bridge_master(info->upper_dev)) {
1758 if (info->linking)
1759 ret = icssm_prueth_ndev_port_link
1760 (ndev, info->upper_dev);
1761 else
1762 ret = icssm_prueth_ndev_port_unlink(ndev);
1763 }
1764 break;
1765 default:
1766 return NOTIFY_DONE;
1767 }
1768
1769 return notifier_from_errno(ret);
1770 }
1771
icssm_prueth_register_notifiers(struct prueth * prueth)1772 static int icssm_prueth_register_notifiers(struct prueth *prueth)
1773 {
1774 int ret = 0;
1775
1776 prueth->prueth_netdevice_nb.notifier_call = icssm_prueth_ndev_event;
1777 ret = register_netdevice_notifier(&prueth->prueth_netdevice_nb);
1778 if (ret) {
1779 dev_err(prueth->dev,
1780 "register netdevice notifier failed ret: %d\n", ret);
1781 return ret;
1782 }
1783
1784 ret = icssm_prueth_sw_register_notifiers(prueth);
1785 if (ret)
1786 unregister_netdevice_notifier(&prueth->prueth_netdevice_nb);
1787
1788 return ret;
1789 }
1790
icssm_prueth_probe(struct platform_device * pdev)1791 static int icssm_prueth_probe(struct platform_device *pdev)
1792 {
1793 struct device_node *eth0_node = NULL, *eth1_node = NULL;
1794 struct device_node *eth_node, *eth_ports_node;
1795 enum pruss_pru_id pruss_id0, pruss_id1;
1796 struct device *dev = &pdev->dev;
1797 struct device_node *np;
1798 struct prueth *prueth;
1799 struct pruss *pruss;
1800 int i, ret;
1801
1802 np = dev->of_node;
1803 if (!np)
1804 return -ENODEV; /* we don't support non DT */
1805
1806 prueth = devm_kzalloc(dev, sizeof(*prueth), GFP_KERNEL);
1807 if (!prueth)
1808 return -ENOMEM;
1809
1810 platform_set_drvdata(pdev, prueth);
1811 prueth->dev = dev;
1812 prueth->fw_data = device_get_match_data(dev);
1813
1814 eth_ports_node = of_get_child_by_name(np, "ethernet-ports");
1815 if (!eth_ports_node)
1816 return -ENOENT;
1817
1818 for_each_child_of_node(eth_ports_node, eth_node) {
1819 u32 reg;
1820
1821 if (strcmp(eth_node->name, "ethernet-port"))
1822 continue;
1823 ret = of_property_read_u32(eth_node, "reg", ®);
1824 if (ret < 0) {
1825 dev_err(dev, "%pOF error reading port_id %d\n",
1826 eth_node, ret);
1827 of_node_put(eth_node);
1828 return ret;
1829 }
1830
1831 of_node_get(eth_node);
1832
1833 if (reg == 0 && !eth0_node) {
1834 eth0_node = eth_node;
1835 if (!of_device_is_available(eth0_node)) {
1836 of_node_put(eth0_node);
1837 eth0_node = NULL;
1838 }
1839 } else if (reg == 1 && !eth1_node) {
1840 eth1_node = eth_node;
1841 if (!of_device_is_available(eth1_node)) {
1842 of_node_put(eth1_node);
1843 eth1_node = NULL;
1844 }
1845 } else {
1846 if (reg == 0 || reg == 1)
1847 dev_err(dev, "duplicate port reg value: %d\n",
1848 reg);
1849 else
1850 dev_err(dev, "invalid port reg value: %d\n",
1851 reg);
1852
1853 of_node_put(eth_node);
1854 }
1855 }
1856
1857 of_node_put(eth_ports_node);
1858
1859 /* At least one node must be present and available else we fail */
1860 if (!eth0_node && !eth1_node) {
1861 dev_err(dev, "neither port0 nor port1 node available\n");
1862 return -ENODEV;
1863 }
1864
1865 prueth->eth_node[PRUETH_MAC0] = eth0_node;
1866 prueth->eth_node[PRUETH_MAC1] = eth1_node;
1867
1868 prueth->mii_rt = syscon_regmap_lookup_by_phandle(np, "ti,mii-rt");
1869 if (IS_ERR(prueth->mii_rt)) {
1870 dev_err(dev, "couldn't get mii-rt syscon regmap\n");
1871 ret = PTR_ERR(prueth->mii_rt);
1872 goto put_eth;
1873 }
1874
1875 if (eth0_node) {
1876 prueth->pru0 = pru_rproc_get(np, 0, &pruss_id0);
1877 if (IS_ERR(prueth->pru0)) {
1878 ret = PTR_ERR(prueth->pru0);
1879 dev_err_probe(dev, ret, "unable to get PRU0");
1880 goto put_eth;
1881 }
1882 }
1883
1884 if (eth1_node) {
1885 prueth->pru1 = pru_rproc_get(np, 1, &pruss_id1);
1886 if (IS_ERR(prueth->pru1)) {
1887 ret = PTR_ERR(prueth->pru1);
1888 dev_err_probe(dev, ret, "unable to get PRU1");
1889 goto put_pru0;
1890 }
1891 }
1892
1893 pruss = pruss_get(prueth->pru0 ? prueth->pru0 : prueth->pru1);
1894 if (IS_ERR(pruss)) {
1895 ret = PTR_ERR(pruss);
1896 dev_err(dev, "unable to get pruss handle\n");
1897 goto put_pru1;
1898 }
1899 prueth->pruss = pruss;
1900
1901 /* Configure PRUSS */
1902 if (eth0_node)
1903 pruss_cfg_gpimode(pruss, pruss_id0, PRUSS_GPI_MODE_MII);
1904 if (eth1_node)
1905 pruss_cfg_gpimode(pruss, pruss_id1, PRUSS_GPI_MODE_MII);
1906 pruss_cfg_miirt_enable(pruss, true);
1907 pruss_cfg_xfr_enable(pruss, PRU_TYPE_PRU, true);
1908
1909 /* Get PRUSS mem resources */
1910 /* OCMC is system resource which we get separately */
1911 for (i = 0; i < ARRAY_SIZE(pruss_mem_ids); i++) {
1912 /* skip appropriate DRAM if not required */
1913 if (!eth0_node && i == PRUETH_MEM_DRAM0)
1914 continue;
1915
1916 if (!eth1_node && i == PRUETH_MEM_DRAM1)
1917 continue;
1918
1919 ret = pruss_request_mem_region(pruss, pruss_mem_ids[i],
1920 &prueth->mem[i]);
1921 if (ret) {
1922 dev_err(dev, "unable to get PRUSS resource %d: %d\n",
1923 i, ret);
1924 goto put_mem;
1925 }
1926 }
1927
1928 prueth->sram_pool = of_gen_pool_get(np, "sram", 0);
1929 if (!prueth->sram_pool) {
1930 dev_err(dev, "unable to get SRAM pool\n");
1931 ret = -ENODEV;
1932 goto put_mem;
1933 }
1934
1935 prueth->ocmc_ram_size = OCMC_RAM_SIZE;
1936 /* Decreased by 8KB to address the reserved region for AM33x */
1937 if (prueth->fw_data->driver_data == PRUSS_AM33XX)
1938 prueth->ocmc_ram_size = (SZ_64K - SZ_8K);
1939
1940 prueth->mem[PRUETH_MEM_OCMC].va =
1941 (void __iomem *)gen_pool_alloc(prueth->sram_pool,
1942 prueth->ocmc_ram_size);
1943 if (!prueth->mem[PRUETH_MEM_OCMC].va) {
1944 dev_err(dev, "unable to allocate OCMC resource\n");
1945 ret = -ENOMEM;
1946 goto put_mem;
1947 }
1948 prueth->mem[PRUETH_MEM_OCMC].pa = gen_pool_virt_to_phys
1949 (prueth->sram_pool, (unsigned long)
1950 prueth->mem[PRUETH_MEM_OCMC].va);
1951 prueth->mem[PRUETH_MEM_OCMC].size = prueth->ocmc_ram_size;
1952 dev_dbg(dev, "ocmc: pa %pa va %p size %#zx\n",
1953 &prueth->mem[PRUETH_MEM_OCMC].pa,
1954 prueth->mem[PRUETH_MEM_OCMC].va,
1955 prueth->mem[PRUETH_MEM_OCMC].size);
1956
1957 /* setup netdev interfaces */
1958 if (eth0_node) {
1959 ret = icssm_prueth_netdev_init(prueth, eth0_node);
1960 if (ret) {
1961 if (ret != -EPROBE_DEFER) {
1962 dev_err(dev, "netdev init %s failed: %d\n",
1963 eth0_node->name, ret);
1964 }
1965 goto free_pool;
1966 }
1967 }
1968
1969 if (eth1_node) {
1970 ret = icssm_prueth_netdev_init(prueth, eth1_node);
1971 if (ret) {
1972 if (ret != -EPROBE_DEFER) {
1973 dev_err(dev, "netdev init %s failed: %d\n",
1974 eth1_node->name, ret);
1975 }
1976 goto netdev_exit;
1977 }
1978 }
1979
1980 prueth->iep = icss_iep_get(np);
1981 if (IS_ERR(prueth->iep)) {
1982 ret = PTR_ERR(prueth->iep);
1983 dev_err(dev, "unable to get IEP\n");
1984 goto netdev_exit;
1985 }
1986
1987 /* register the network devices */
1988 if (eth0_node) {
1989 ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev);
1990 if (ret) {
1991 dev_err(dev, "can't register netdev for port MII0");
1992 goto iep_put;
1993 }
1994
1995 prueth->registered_netdevs[PRUETH_MAC0] =
1996 prueth->emac[PRUETH_MAC0]->ndev;
1997 }
1998
1999 if (eth1_node) {
2000 ret = register_netdev(prueth->emac[PRUETH_MAC1]->ndev);
2001 if (ret) {
2002 dev_err(dev, "can't register netdev for port MII1");
2003 goto netdev_unregister;
2004 }
2005
2006 prueth->registered_netdevs[PRUETH_MAC1] =
2007 prueth->emac[PRUETH_MAC1]->ndev;
2008 }
2009
2010 ret = icssm_prueth_register_notifiers(prueth);
2011 if (ret) {
2012 dev_err(dev, "can't register switchdev notifiers");
2013 goto netdev_unregister;
2014 }
2015
2016 dev_info(dev, "TI PRU ethernet driver initialized: %s EMAC mode\n",
2017 (!eth0_node || !eth1_node) ? "single" : "dual");
2018
2019 if (eth1_node)
2020 of_node_put(eth1_node);
2021 if (eth0_node)
2022 of_node_put(eth0_node);
2023 return 0;
2024
2025 netdev_unregister:
2026 for (i = 0; i < PRUETH_NUM_MACS; i++) {
2027 if (!prueth->registered_netdevs[i])
2028 continue;
2029 unregister_netdev(prueth->registered_netdevs[i]);
2030 }
2031
2032 iep_put:
2033 icss_iep_put(prueth->iep);
2034 prueth->iep = NULL;
2035
2036 netdev_exit:
2037 for (i = 0; i < PRUETH_NUM_MACS; i++) {
2038 eth_node = prueth->eth_node[i];
2039 if (!eth_node)
2040 continue;
2041
2042 icssm_prueth_netdev_exit(prueth, eth_node);
2043 }
2044
2045 free_pool:
2046 gen_pool_free(prueth->sram_pool,
2047 (unsigned long)prueth->mem[PRUETH_MEM_OCMC].va,
2048 prueth->ocmc_ram_size);
2049
2050 put_mem:
2051 for (i = PRUETH_MEM_DRAM0; i < PRUETH_MEM_OCMC; i++) {
2052 if (prueth->mem[i].va)
2053 pruss_release_mem_region(pruss, &prueth->mem[i]);
2054 }
2055 pruss_put(prueth->pruss);
2056
2057 put_pru1:
2058 if (eth1_node)
2059 pru_rproc_put(prueth->pru1);
2060 put_pru0:
2061 if (eth0_node)
2062 pru_rproc_put(prueth->pru0);
2063 put_eth:
2064 of_node_put(eth1_node);
2065 of_node_put(eth0_node);
2066
2067 return ret;
2068 }
2069
icssm_prueth_remove(struct platform_device * pdev)2070 static void icssm_prueth_remove(struct platform_device *pdev)
2071 {
2072 struct prueth *prueth = platform_get_drvdata(pdev);
2073 struct device_node *eth_node;
2074 int i;
2075
2076 unregister_netdevice_notifier(&prueth->prueth_netdevice_nb);
2077 icssm_prueth_sw_unregister_notifiers(prueth);
2078
2079 for (i = 0; i < PRUETH_NUM_MACS; i++) {
2080 if (!prueth->registered_netdevs[i])
2081 continue;
2082 unregister_netdev(prueth->registered_netdevs[i]);
2083 }
2084
2085 for (i = 0; i < PRUETH_NUM_MACS; i++) {
2086 eth_node = prueth->eth_node[i];
2087 if (!eth_node)
2088 continue;
2089
2090 icssm_prueth_netdev_exit(prueth, eth_node);
2091 of_node_put(eth_node);
2092 }
2093
2094 gen_pool_free(prueth->sram_pool,
2095 (unsigned long)prueth->mem[PRUETH_MEM_OCMC].va,
2096 prueth->ocmc_ram_size);
2097
2098 for (i = PRUETH_MEM_DRAM0; i < PRUETH_MEM_OCMC; i++) {
2099 if (prueth->mem[i].va)
2100 pruss_release_mem_region(prueth->pruss,
2101 &prueth->mem[i]);
2102 }
2103
2104 icss_iep_put(prueth->iep);
2105 prueth->iep = NULL;
2106
2107 pruss_put(prueth->pruss);
2108
2109 if (prueth->eth_node[PRUETH_MAC0])
2110 pru_rproc_put(prueth->pru0);
2111 if (prueth->eth_node[PRUETH_MAC1])
2112 pru_rproc_put(prueth->pru1);
2113 }
2114
2115 #ifdef CONFIG_PM_SLEEP
icssm_prueth_suspend(struct device * dev)2116 static int icssm_prueth_suspend(struct device *dev)
2117 {
2118 struct prueth *prueth = dev_get_drvdata(dev);
2119 struct net_device *ndev;
2120 int i, ret;
2121
2122 for (i = 0; i < PRUETH_NUM_MACS; i++) {
2123 ndev = prueth->registered_netdevs[i];
2124
2125 if (!ndev)
2126 continue;
2127
2128 if (netif_running(ndev)) {
2129 netif_device_detach(ndev);
2130 ret = icssm_emac_ndo_stop(ndev);
2131 if (ret < 0) {
2132 netdev_err(ndev, "failed to stop: %d", ret);
2133 return ret;
2134 }
2135 }
2136 }
2137
2138 return 0;
2139 }
2140
icssm_prueth_resume(struct device * dev)2141 static int icssm_prueth_resume(struct device *dev)
2142 {
2143 struct prueth *prueth = dev_get_drvdata(dev);
2144 struct net_device *ndev;
2145 int i, ret;
2146
2147 for (i = 0; i < PRUETH_NUM_MACS; i++) {
2148 ndev = prueth->registered_netdevs[i];
2149
2150 if (!ndev)
2151 continue;
2152
2153 if (netif_running(ndev)) {
2154 ret = icssm_emac_ndo_open(ndev);
2155 if (ret < 0) {
2156 netdev_err(ndev, "failed to start: %d", ret);
2157 return ret;
2158 }
2159 netif_device_attach(ndev);
2160 }
2161 }
2162
2163 return 0;
2164 }
2165
2166 #endif /* CONFIG_PM_SLEEP */
2167
2168 static const struct dev_pm_ops prueth_dev_pm_ops = {
2169 SET_SYSTEM_SLEEP_PM_OPS(icssm_prueth_suspend, icssm_prueth_resume)
2170 };
2171
2172 /* AM335x SoC-specific firmware data */
2173 static struct prueth_private_data am335x_prueth_pdata = {
2174 .driver_data = PRUSS_AM33XX,
2175 .fw_pru[PRUSS_PRU0] = {
2176 .fw_name[PRUSS_ETHTYPE_EMAC] =
2177 "ti-pruss/am335x-pru0-prueth-fw.elf",
2178 .fw_name[PRUSS_ETHTYPE_SWITCH] =
2179 "ti-pruss/am335x-pru0-prusw-fw.elf",
2180 },
2181 .fw_pru[PRUSS_PRU1] = {
2182 .fw_name[PRUSS_ETHTYPE_EMAC] =
2183 "ti-pruss/am335x-pru1-prueth-fw.elf",
2184 .fw_name[PRUSS_ETHTYPE_SWITCH] =
2185 "ti-pruss/am335x-pru1-prusw-fw.elf",
2186 },
2187 .support_switch = true,
2188 };
2189
2190 /* AM437x SoC-specific firmware data */
2191 static struct prueth_private_data am437x_prueth_pdata = {
2192 .driver_data = PRUSS_AM43XX,
2193 .fw_pru[PRUSS_PRU0] = {
2194 .fw_name[PRUSS_ETHTYPE_EMAC] =
2195 "ti-pruss/am437x-pru0-prueth-fw.elf",
2196 .fw_name[PRUSS_ETHTYPE_SWITCH] =
2197 "ti-pruss/am437x-pru0-prusw-fw.elf",
2198 },
2199 .fw_pru[PRUSS_PRU1] = {
2200 .fw_name[PRUSS_ETHTYPE_EMAC] =
2201 "ti-pruss/am437x-pru1-prueth-fw.elf",
2202 .fw_name[PRUSS_ETHTYPE_SWITCH] =
2203 "ti-pruss/am437x-pru1-prusw-fw.elf",
2204 },
2205 .support_switch = true,
2206 };
2207
2208 /* AM57xx SoC-specific firmware data */
2209 static struct prueth_private_data am57xx_prueth_pdata = {
2210 .driver_data = PRUSS_AM57XX,
2211 .fw_pru[PRUSS_PRU0] = {
2212 .fw_name[PRUSS_ETHTYPE_EMAC] =
2213 "ti-pruss/am57xx-pru0-prueth-fw.elf",
2214 .fw_name[PRUSS_ETHTYPE_SWITCH] =
2215 "ti-pruss/am57xx-pru0-prusw-fw.elf",
2216 },
2217 .fw_pru[PRUSS_PRU1] = {
2218 .fw_name[PRUSS_ETHTYPE_EMAC] =
2219 "ti-pruss/am57xx-pru1-prueth-fw.elf",
2220 .fw_name[PRUSS_ETHTYPE_SWITCH] =
2221 "ti-pruss/am57xx-pru1-prusw-fw.elf",
2222
2223 },
2224 .support_switch = true,
2225 };
2226
2227 static const struct of_device_id prueth_dt_match[] = {
2228 { .compatible = "ti,am57-prueth", .data = &am57xx_prueth_pdata, },
2229 { .compatible = "ti,am4376-prueth", .data = &am437x_prueth_pdata, },
2230 { .compatible = "ti,am3359-prueth", .data = &am335x_prueth_pdata, },
2231 { /* sentinel */ }
2232 };
2233 MODULE_DEVICE_TABLE(of, prueth_dt_match);
2234
2235 static struct platform_driver prueth_driver = {
2236 .probe = icssm_prueth_probe,
2237 .remove = icssm_prueth_remove,
2238 .driver = {
2239 .name = "prueth",
2240 .of_match_table = prueth_dt_match,
2241 .pm = &prueth_dev_pm_ops,
2242 },
2243 };
2244 module_platform_driver(prueth_driver);
2245
2246 MODULE_AUTHOR("Roger Quadros <rogerq@ti.com>");
2247 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
2248 MODULE_DESCRIPTION("PRUSS ICSSM Ethernet Driver");
2249 MODULE_LICENSE("GPL");
2250