xref: /linux/drivers/net/ethernet/ti/icssm/icssm_prueth.c (revision 37a93dd5c49b5fda807fd204edf2547c3493319c)
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", &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