1 // SPDX-License-Identifier: GPL-2.0+
2 /* Microchip Sparx5 Switch driver
3  *
4  * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries.
5  *
6  * The Sparx5 Chip Register Model can be browsed at this location:
7  * https://github.com/microchip-ung/sparx-5_reginfo
8  */
9 
10 #include <linux/types.h>
11 #include <linux/skbuff.h>
12 #include <linux/netdevice.h>
13 #include <linux/interrupt.h>
14 #include <linux/ip.h>
15 #include <linux/dma-mapping.h>
16 
17 #include "sparx5_main_regs.h"
18 #include "sparx5_main.h"
19 #include "sparx5_port.h"
20 
21 #define FDMA_XTR_CHANNEL		6
22 #define FDMA_INJ_CHANNEL		0
23 
24 #define FDMA_DCB_INFO_DATAL(x)		((x) & GENMASK(15, 0))
25 #define FDMA_DCB_INFO_TOKEN		BIT(17)
26 #define FDMA_DCB_INFO_INTR		BIT(18)
27 #define FDMA_DCB_INFO_SW(x)		(((x) << 24) & GENMASK(31, 24))
28 
29 #define FDMA_DCB_STATUS_BLOCKL(x)	((x) & GENMASK(15, 0))
30 #define FDMA_DCB_STATUS_SOF		BIT(16)
31 #define FDMA_DCB_STATUS_EOF		BIT(17)
32 #define FDMA_DCB_STATUS_INTR		BIT(18)
33 #define FDMA_DCB_STATUS_DONE		BIT(19)
34 #define FDMA_DCB_STATUS_BLOCKO(x)	(((x) << 20) & GENMASK(31, 20))
35 #define FDMA_DCB_INVALID_DATA		0x1
36 
37 #define FDMA_XTR_BUFFER_SIZE		2048
38 #define FDMA_WEIGHT			4
39 
40 /* Frame DMA DCB format
41  *
42  * +---------------------------+
43  * |         Next Ptr          |
44  * +---------------------------+
45  * |   Reserved  |    Info     |
46  * +---------------------------+
47  * |         Data0 Ptr         |
48  * +---------------------------+
49  * |   Reserved  |    Status0  |
50  * +---------------------------+
51  * |         Data1 Ptr         |
52  * +---------------------------+
53  * |   Reserved  |    Status1  |
54  * +---------------------------+
55  * |         Data2 Ptr         |
56  * +---------------------------+
57  * |   Reserved  |    Status2  |
58  * |-------------|-------------|
59  * |                           |
60  * |                           |
61  * |                           |
62  * |                           |
63  * |                           |
64  * |---------------------------|
65  * |         Data14 Ptr        |
66  * +-------------|-------------+
67  * |   Reserved  |    Status14 |
68  * +-------------|-------------+
69  */
70 
71 /* For each hardware DB there is an entry in this list and when the HW DB
72  * entry is used, this SW DB entry is moved to the back of the list
73  */
74 struct sparx5_db {
75 	struct list_head list;
76 	void *cpu_addr;
77 };
78 
79 static void sparx5_fdma_rx_add_dcb(struct sparx5_rx *rx,
80 				   struct sparx5_rx_dcb_hw *dcb,
81 				   u64 nextptr)
82 {
83 	int idx = 0;
84 
85 	/* Reset the status of the DB */
86 	for (idx = 0; idx < FDMA_RX_DCB_MAX_DBS; ++idx) {
87 		struct sparx5_db_hw *db = &dcb->db[idx];
88 
89 		db->status = FDMA_DCB_STATUS_INTR;
90 	}
91 	dcb->nextptr = FDMA_DCB_INVALID_DATA;
92 	dcb->info = FDMA_DCB_INFO_DATAL(FDMA_XTR_BUFFER_SIZE);
93 	rx->last_entry->nextptr = nextptr;
94 	rx->last_entry = dcb;
95 }
96 
97 static void sparx5_fdma_tx_add_dcb(struct sparx5_tx *tx,
98 				   struct sparx5_tx_dcb_hw *dcb,
99 				   u64 nextptr)
100 {
101 	int idx = 0;
102 
103 	/* Reset the status of the DB */
104 	for (idx = 0; idx < FDMA_TX_DCB_MAX_DBS; ++idx) {
105 		struct sparx5_db_hw *db = &dcb->db[idx];
106 
107 		db->status = FDMA_DCB_STATUS_DONE;
108 	}
109 	dcb->nextptr = FDMA_DCB_INVALID_DATA;
110 	dcb->info = FDMA_DCB_INFO_DATAL(FDMA_XTR_BUFFER_SIZE);
111 }
112 
113 static void sparx5_fdma_rx_activate(struct sparx5 *sparx5, struct sparx5_rx *rx)
114 {
115 	/* Write the buffer address in the LLP and LLP1 regs */
116 	spx5_wr(((u64)rx->dma) & GENMASK(31, 0), sparx5,
117 		FDMA_DCB_LLP(rx->channel_id));
118 	spx5_wr(((u64)rx->dma) >> 32, sparx5, FDMA_DCB_LLP1(rx->channel_id));
119 
120 	/* Set the number of RX DBs to be used, and DB end-of-frame interrupt */
121 	spx5_wr(FDMA_CH_CFG_CH_DCB_DB_CNT_SET(FDMA_RX_DCB_MAX_DBS) |
122 		FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY_SET(1) |
123 		FDMA_CH_CFG_CH_INJ_PORT_SET(XTR_QUEUE),
124 		sparx5, FDMA_CH_CFG(rx->channel_id));
125 
126 	/* Set the RX Watermark to max */
127 	spx5_rmw(FDMA_XTR_CFG_XTR_FIFO_WM_SET(31), FDMA_XTR_CFG_XTR_FIFO_WM,
128 		 sparx5,
129 		 FDMA_XTR_CFG);
130 
131 	/* Start RX fdma */
132 	spx5_rmw(FDMA_PORT_CTRL_XTR_STOP_SET(0), FDMA_PORT_CTRL_XTR_STOP,
133 		 sparx5, FDMA_PORT_CTRL(0));
134 
135 	/* Enable RX channel DB interrupt */
136 	spx5_rmw(BIT(rx->channel_id),
137 		 BIT(rx->channel_id) & FDMA_INTR_DB_ENA_INTR_DB_ENA,
138 		 sparx5, FDMA_INTR_DB_ENA);
139 
140 	/* Activate the RX channel */
141 	spx5_wr(BIT(rx->channel_id), sparx5, FDMA_CH_ACTIVATE);
142 }
143 
144 static void sparx5_fdma_rx_deactivate(struct sparx5 *sparx5, struct sparx5_rx *rx)
145 {
146 	/* Dectivate the RX channel */
147 	spx5_rmw(0, BIT(rx->channel_id) & FDMA_CH_ACTIVATE_CH_ACTIVATE,
148 		 sparx5, FDMA_CH_ACTIVATE);
149 
150 	/* Disable RX channel DB interrupt */
151 	spx5_rmw(0, BIT(rx->channel_id) & FDMA_INTR_DB_ENA_INTR_DB_ENA,
152 		 sparx5, FDMA_INTR_DB_ENA);
153 
154 	/* Stop RX fdma */
155 	spx5_rmw(FDMA_PORT_CTRL_XTR_STOP_SET(1), FDMA_PORT_CTRL_XTR_STOP,
156 		 sparx5, FDMA_PORT_CTRL(0));
157 }
158 
159 static void sparx5_fdma_tx_activate(struct sparx5 *sparx5, struct sparx5_tx *tx)
160 {
161 	/* Write the buffer address in the LLP and LLP1 regs */
162 	spx5_wr(((u64)tx->dma) & GENMASK(31, 0), sparx5,
163 		FDMA_DCB_LLP(tx->channel_id));
164 	spx5_wr(((u64)tx->dma) >> 32, sparx5, FDMA_DCB_LLP1(tx->channel_id));
165 
166 	/* Set the number of TX DBs to be used, and DB end-of-frame interrupt */
167 	spx5_wr(FDMA_CH_CFG_CH_DCB_DB_CNT_SET(FDMA_TX_DCB_MAX_DBS) |
168 		FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY_SET(1) |
169 		FDMA_CH_CFG_CH_INJ_PORT_SET(INJ_QUEUE),
170 		sparx5, FDMA_CH_CFG(tx->channel_id));
171 
172 	/* Start TX fdma */
173 	spx5_rmw(FDMA_PORT_CTRL_INJ_STOP_SET(0), FDMA_PORT_CTRL_INJ_STOP,
174 		 sparx5, FDMA_PORT_CTRL(0));
175 
176 	/* Activate the channel */
177 	spx5_wr(BIT(tx->channel_id), sparx5, FDMA_CH_ACTIVATE);
178 }
179 
180 static void sparx5_fdma_tx_deactivate(struct sparx5 *sparx5, struct sparx5_tx *tx)
181 {
182 	/* Disable the channel */
183 	spx5_rmw(0, BIT(tx->channel_id) & FDMA_CH_ACTIVATE_CH_ACTIVATE,
184 		 sparx5, FDMA_CH_ACTIVATE);
185 }
186 
187 static void sparx5_fdma_rx_reload(struct sparx5 *sparx5, struct sparx5_rx *rx)
188 {
189 	/* Reload the RX channel */
190 	spx5_wr(BIT(rx->channel_id), sparx5, FDMA_CH_RELOAD);
191 }
192 
193 static void sparx5_fdma_tx_reload(struct sparx5 *sparx5, struct sparx5_tx *tx)
194 {
195 	/* Reload the TX channel */
196 	spx5_wr(BIT(tx->channel_id), sparx5, FDMA_CH_RELOAD);
197 }
198 
199 static struct sk_buff *sparx5_fdma_rx_alloc_skb(struct sparx5_rx *rx)
200 {
201 	return __netdev_alloc_skb(rx->ndev, FDMA_XTR_BUFFER_SIZE,
202 				  GFP_ATOMIC);
203 }
204 
205 static bool sparx5_fdma_rx_get_frame(struct sparx5 *sparx5, struct sparx5_rx *rx)
206 {
207 	struct sparx5_db_hw *db_hw;
208 	unsigned int packet_size;
209 	struct sparx5_port *port;
210 	struct sk_buff *new_skb;
211 	struct frame_info fi;
212 	struct sk_buff *skb;
213 	dma_addr_t dma_addr;
214 
215 	/* Check if the DCB is done */
216 	db_hw = &rx->dcb_entries[rx->dcb_index].db[rx->db_index];
217 	if (unlikely(!(db_hw->status & FDMA_DCB_STATUS_DONE)))
218 		return false;
219 	skb = rx->skb[rx->dcb_index][rx->db_index];
220 	/* Replace the DB entry with a new SKB */
221 	new_skb = sparx5_fdma_rx_alloc_skb(rx);
222 	if (unlikely(!new_skb))
223 		return false;
224 	/* Map the new skb data and set the new skb */
225 	dma_addr = virt_to_phys(new_skb->data);
226 	rx->skb[rx->dcb_index][rx->db_index] = new_skb;
227 	db_hw->dataptr = dma_addr;
228 	packet_size = FDMA_DCB_STATUS_BLOCKL(db_hw->status);
229 	skb_put(skb, packet_size);
230 	/* Now do the normal processing of the skb */
231 	sparx5_ifh_parse((u32 *)skb->data, &fi);
232 	/* Map to port netdev */
233 	port = fi.src_port < SPX5_PORTS ?  sparx5->ports[fi.src_port] : NULL;
234 	if (!port || !port->ndev) {
235 		dev_err(sparx5->dev, "Data on inactive port %d\n", fi.src_port);
236 		sparx5_xtr_flush(sparx5, XTR_QUEUE);
237 		return false;
238 	}
239 	skb->dev = port->ndev;
240 	skb_pull(skb, IFH_LEN * sizeof(u32));
241 	if (likely(!(skb->dev->features & NETIF_F_RXFCS)))
242 		skb_trim(skb, skb->len - ETH_FCS_LEN);
243 	skb->protocol = eth_type_trans(skb, skb->dev);
244 	/* Everything we see on an interface that is in the HW bridge
245 	 * has already been forwarded
246 	 */
247 	if (test_bit(port->portno, sparx5->bridge_mask))
248 		skb->offload_fwd_mark = 1;
249 	skb->dev->stats.rx_bytes += skb->len;
250 	skb->dev->stats.rx_packets++;
251 	rx->packets++;
252 	netif_receive_skb(skb);
253 	return true;
254 }
255 
256 static int sparx5_fdma_napi_callback(struct napi_struct *napi, int weight)
257 {
258 	struct sparx5_rx *rx = container_of(napi, struct sparx5_rx, napi);
259 	struct sparx5 *sparx5 = container_of(rx, struct sparx5, rx);
260 	int counter = 0;
261 
262 	while (counter < weight && sparx5_fdma_rx_get_frame(sparx5, rx)) {
263 		struct sparx5_rx_dcb_hw *old_dcb;
264 
265 		rx->db_index++;
266 		counter++;
267 		/* Check if the DCB can be reused */
268 		if (rx->db_index != FDMA_RX_DCB_MAX_DBS)
269 			continue;
270 		/* As the DCB  can be reused, just advance the dcb_index
271 		 * pointer and set the nextptr in the DCB
272 		 */
273 		rx->db_index = 0;
274 		old_dcb = &rx->dcb_entries[rx->dcb_index];
275 		rx->dcb_index++;
276 		rx->dcb_index &= FDMA_DCB_MAX - 1;
277 		sparx5_fdma_rx_add_dcb(rx, old_dcb,
278 				       rx->dma +
279 				       ((unsigned long)old_dcb -
280 					(unsigned long)rx->dcb_entries));
281 	}
282 	if (counter < weight) {
283 		napi_complete_done(&rx->napi, counter);
284 		spx5_rmw(BIT(rx->channel_id),
285 			 BIT(rx->channel_id) & FDMA_INTR_DB_ENA_INTR_DB_ENA,
286 			 sparx5, FDMA_INTR_DB_ENA);
287 	}
288 	if (counter)
289 		sparx5_fdma_rx_reload(sparx5, rx);
290 	return counter;
291 }
292 
293 static struct sparx5_tx_dcb_hw *sparx5_fdma_next_dcb(struct sparx5_tx *tx,
294 						     struct sparx5_tx_dcb_hw *dcb)
295 {
296 	struct sparx5_tx_dcb_hw *next_dcb;
297 
298 	next_dcb = dcb;
299 	next_dcb++;
300 	/* Handle wrap-around */
301 	if ((unsigned long)next_dcb >=
302 	    ((unsigned long)tx->first_entry + FDMA_DCB_MAX * sizeof(*dcb)))
303 		next_dcb = tx->first_entry;
304 	return next_dcb;
305 }
306 
307 int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb)
308 {
309 	struct sparx5_tx_dcb_hw *next_dcb_hw;
310 	struct sparx5_tx *tx = &sparx5->tx;
311 	static bool first_time = true;
312 	struct sparx5_db_hw *db_hw;
313 	struct sparx5_db *db;
314 
315 	next_dcb_hw = sparx5_fdma_next_dcb(tx, tx->curr_entry);
316 	db_hw = &next_dcb_hw->db[0];
317 	if (!(db_hw->status & FDMA_DCB_STATUS_DONE))
318 		tx->dropped++;
319 	db = list_first_entry(&tx->db_list, struct sparx5_db, list);
320 	list_move_tail(&db->list, &tx->db_list);
321 	next_dcb_hw->nextptr = FDMA_DCB_INVALID_DATA;
322 	tx->curr_entry->nextptr = tx->dma +
323 		((unsigned long)next_dcb_hw -
324 		 (unsigned long)tx->first_entry);
325 	tx->curr_entry = next_dcb_hw;
326 	memset(db->cpu_addr, 0, FDMA_XTR_BUFFER_SIZE);
327 	memcpy(db->cpu_addr, ifh, IFH_LEN * 4);
328 	memcpy(db->cpu_addr + IFH_LEN * 4, skb->data, skb->len);
329 	db_hw->status = FDMA_DCB_STATUS_SOF |
330 			FDMA_DCB_STATUS_EOF |
331 			FDMA_DCB_STATUS_BLOCKO(0) |
332 			FDMA_DCB_STATUS_BLOCKL(skb->len + IFH_LEN * 4 + 4);
333 	if (first_time) {
334 		sparx5_fdma_tx_activate(sparx5, tx);
335 		first_time = false;
336 	} else {
337 		sparx5_fdma_tx_reload(sparx5, tx);
338 	}
339 	return NETDEV_TX_OK;
340 }
341 
342 static int sparx5_fdma_rx_alloc(struct sparx5 *sparx5)
343 {
344 	struct sparx5_rx *rx = &sparx5->rx;
345 	struct sparx5_rx_dcb_hw *dcb;
346 	int idx, jdx;
347 	int size;
348 
349 	size = sizeof(struct sparx5_rx_dcb_hw) * FDMA_DCB_MAX;
350 	size = ALIGN(size, PAGE_SIZE);
351 	rx->dcb_entries = devm_kzalloc(sparx5->dev, size, GFP_KERNEL);
352 	if (!rx->dcb_entries)
353 		return -ENOMEM;
354 	rx->dma = virt_to_phys(rx->dcb_entries);
355 	rx->last_entry = rx->dcb_entries;
356 	rx->db_index = 0;
357 	rx->dcb_index = 0;
358 	/* Now for each dcb allocate the db */
359 	for (idx = 0; idx < FDMA_DCB_MAX; ++idx) {
360 		dcb = &rx->dcb_entries[idx];
361 		dcb->info = 0;
362 		/* For each db allocate an skb and map skb data pointer to the DB
363 		 * dataptr. In this way when the frame is received the skb->data
364 		 * will contain the frame, so no memcpy is needed
365 		 */
366 		for (jdx = 0; jdx < FDMA_RX_DCB_MAX_DBS; ++jdx) {
367 			struct sparx5_db_hw *db_hw = &dcb->db[jdx];
368 			dma_addr_t dma_addr;
369 			struct sk_buff *skb;
370 
371 			skb = sparx5_fdma_rx_alloc_skb(rx);
372 			if (!skb)
373 				return -ENOMEM;
374 
375 			dma_addr = virt_to_phys(skb->data);
376 			db_hw->dataptr = dma_addr;
377 			db_hw->status = 0;
378 			rx->skb[idx][jdx] = skb;
379 		}
380 		sparx5_fdma_rx_add_dcb(rx, dcb, rx->dma + sizeof(*dcb) * idx);
381 	}
382 	netif_napi_add(rx->ndev, &rx->napi, sparx5_fdma_napi_callback, FDMA_WEIGHT);
383 	napi_enable(&rx->napi);
384 	sparx5_fdma_rx_activate(sparx5, rx);
385 	return 0;
386 }
387 
388 static int sparx5_fdma_tx_alloc(struct sparx5 *sparx5)
389 {
390 	struct sparx5_tx *tx = &sparx5->tx;
391 	struct sparx5_tx_dcb_hw *dcb;
392 	int idx, jdx;
393 	int size;
394 
395 	size = sizeof(struct sparx5_tx_dcb_hw) * FDMA_DCB_MAX;
396 	size = ALIGN(size, PAGE_SIZE);
397 	tx->curr_entry = devm_kzalloc(sparx5->dev, size, GFP_KERNEL);
398 	if (!tx->curr_entry)
399 		return -ENOMEM;
400 	tx->dma = virt_to_phys(tx->curr_entry);
401 	tx->first_entry = tx->curr_entry;
402 	INIT_LIST_HEAD(&tx->db_list);
403 	/* Now for each dcb allocate the db */
404 	for (idx = 0; idx < FDMA_DCB_MAX; ++idx) {
405 		dcb = &tx->curr_entry[idx];
406 		dcb->info = 0;
407 		/* TX databuffers must be 16byte aligned */
408 		for (jdx = 0; jdx < FDMA_TX_DCB_MAX_DBS; ++jdx) {
409 			struct sparx5_db_hw *db_hw = &dcb->db[jdx];
410 			struct sparx5_db *db;
411 			dma_addr_t phys;
412 			void *cpu_addr;
413 
414 			cpu_addr = devm_kzalloc(sparx5->dev,
415 						FDMA_XTR_BUFFER_SIZE,
416 						GFP_KERNEL);
417 			if (!cpu_addr)
418 				return -ENOMEM;
419 			phys = virt_to_phys(cpu_addr);
420 			db_hw->dataptr = phys;
421 			db_hw->status = 0;
422 			db = devm_kzalloc(sparx5->dev, sizeof(*db), GFP_KERNEL);
423 			db->cpu_addr = cpu_addr;
424 			list_add_tail(&db->list, &tx->db_list);
425 		}
426 		sparx5_fdma_tx_add_dcb(tx, dcb, tx->dma + sizeof(*dcb) * idx);
427 		/* Let the curr_entry to point to the last allocated entry */
428 		if (idx == FDMA_DCB_MAX - 1)
429 			tx->curr_entry = dcb;
430 	}
431 	return 0;
432 }
433 
434 static void sparx5_fdma_rx_init(struct sparx5 *sparx5,
435 				struct sparx5_rx *rx, int channel)
436 {
437 	int idx;
438 
439 	rx->channel_id = channel;
440 	/* Fetch a netdev for SKB and NAPI use, any will do */
441 	for (idx = 0; idx < SPX5_PORTS; ++idx) {
442 		struct sparx5_port *port = sparx5->ports[idx];
443 
444 		if (port && port->ndev) {
445 			rx->ndev = port->ndev;
446 			break;
447 		}
448 	}
449 }
450 
451 static void sparx5_fdma_tx_init(struct sparx5 *sparx5,
452 				struct sparx5_tx *tx, int channel)
453 {
454 	tx->channel_id = channel;
455 }
456 
457 irqreturn_t sparx5_fdma_handler(int irq, void *args)
458 {
459 	struct sparx5 *sparx5 = args;
460 	u32 db = 0, err = 0;
461 
462 	db = spx5_rd(sparx5, FDMA_INTR_DB);
463 	err = spx5_rd(sparx5, FDMA_INTR_ERR);
464 	/* Clear interrupt */
465 	if (db) {
466 		spx5_wr(0, sparx5, FDMA_INTR_DB_ENA);
467 		spx5_wr(db, sparx5, FDMA_INTR_DB);
468 		napi_schedule(&sparx5->rx.napi);
469 	}
470 	if (err) {
471 		u32 err_type = spx5_rd(sparx5, FDMA_ERRORS);
472 
473 		dev_err_ratelimited(sparx5->dev,
474 				    "ERR: int: %#x, type: %#x\n",
475 				    err, err_type);
476 		spx5_wr(err, sparx5, FDMA_INTR_ERR);
477 		spx5_wr(err_type, sparx5, FDMA_ERRORS);
478 	}
479 	return IRQ_HANDLED;
480 }
481 
482 static void sparx5_fdma_injection_mode(struct sparx5 *sparx5)
483 {
484 	const int byte_swap = 1;
485 	int portno;
486 	int urgency;
487 
488 	/* Change mode to fdma extraction and injection */
489 	spx5_wr(QS_XTR_GRP_CFG_MODE_SET(2) |
490 		QS_XTR_GRP_CFG_STATUS_WORD_POS_SET(1) |
491 		QS_XTR_GRP_CFG_BYTE_SWAP_SET(byte_swap),
492 		sparx5, QS_XTR_GRP_CFG(XTR_QUEUE));
493 	spx5_wr(QS_INJ_GRP_CFG_MODE_SET(2) |
494 		QS_INJ_GRP_CFG_BYTE_SWAP_SET(byte_swap),
495 		sparx5, QS_INJ_GRP_CFG(INJ_QUEUE));
496 
497 	/* CPU ports capture setup */
498 	for (portno = SPX5_PORT_CPU_0; portno <= SPX5_PORT_CPU_1; portno++) {
499 		/* ASM CPU port: No preamble, IFH, enable padding */
500 		spx5_wr(ASM_PORT_CFG_PAD_ENA_SET(1) |
501 			ASM_PORT_CFG_NO_PREAMBLE_ENA_SET(1) |
502 			ASM_PORT_CFG_INJ_FORMAT_CFG_SET(1), /* 1 = IFH */
503 			sparx5, ASM_PORT_CFG(portno));
504 
505 		/* Reset WM cnt to unclog queued frames */
506 		spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV_TX_CNT_CLR_SET(1),
507 			 DSM_DEV_TX_STOP_WM_CFG_DEV_TX_CNT_CLR,
508 			 sparx5,
509 			 DSM_DEV_TX_STOP_WM_CFG(portno));
510 
511 		/* Set Disassembler Stop Watermark level */
512 		spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV_TX_STOP_WM_SET(100),
513 			 DSM_DEV_TX_STOP_WM_CFG_DEV_TX_STOP_WM,
514 			 sparx5,
515 			 DSM_DEV_TX_STOP_WM_CFG(portno));
516 
517 		/* Enable port in queue system */
518 		urgency = sparx5_port_fwd_urg(sparx5, SPEED_2500);
519 		spx5_rmw(QFWD_SWITCH_PORT_MODE_PORT_ENA_SET(1) |
520 			 QFWD_SWITCH_PORT_MODE_FWD_URGENCY_SET(urgency),
521 			 QFWD_SWITCH_PORT_MODE_PORT_ENA |
522 			 QFWD_SWITCH_PORT_MODE_FWD_URGENCY,
523 			 sparx5,
524 			 QFWD_SWITCH_PORT_MODE(portno));
525 
526 		/* Disable Disassembler buffer underrun watchdog
527 		 * to avoid truncated packets in XTR
528 		 */
529 		spx5_rmw(DSM_BUF_CFG_UNDERFLOW_WATCHDOG_DIS_SET(1),
530 			 DSM_BUF_CFG_UNDERFLOW_WATCHDOG_DIS,
531 			 sparx5,
532 			 DSM_BUF_CFG(portno));
533 
534 		/* Disabling frame aging */
535 		spx5_rmw(HSCH_PORT_MODE_AGE_DIS_SET(1),
536 			 HSCH_PORT_MODE_AGE_DIS,
537 			 sparx5,
538 			 HSCH_PORT_MODE(portno));
539 	}
540 }
541 
542 int sparx5_fdma_start(struct sparx5 *sparx5)
543 {
544 	int err;
545 
546 	/* Reset FDMA state */
547 	spx5_wr(FDMA_CTRL_NRESET_SET(0), sparx5, FDMA_CTRL);
548 	spx5_wr(FDMA_CTRL_NRESET_SET(1), sparx5, FDMA_CTRL);
549 
550 	/* Force ACP caching but disable read/write allocation */
551 	spx5_rmw(CPU_PROC_CTRL_ACP_CACHE_FORCE_ENA_SET(1) |
552 		 CPU_PROC_CTRL_ACP_AWCACHE_SET(0) |
553 		 CPU_PROC_CTRL_ACP_ARCACHE_SET(0),
554 		 CPU_PROC_CTRL_ACP_CACHE_FORCE_ENA |
555 		 CPU_PROC_CTRL_ACP_AWCACHE |
556 		 CPU_PROC_CTRL_ACP_ARCACHE,
557 		 sparx5, CPU_PROC_CTRL);
558 
559 	sparx5_fdma_injection_mode(sparx5);
560 	sparx5_fdma_rx_init(sparx5, &sparx5->rx, FDMA_XTR_CHANNEL);
561 	sparx5_fdma_tx_init(sparx5, &sparx5->tx, FDMA_INJ_CHANNEL);
562 	err = sparx5_fdma_rx_alloc(sparx5);
563 	if (err) {
564 		dev_err(sparx5->dev, "Could not allocate RX buffers: %d\n", err);
565 		return err;
566 	}
567 	err = sparx5_fdma_tx_alloc(sparx5);
568 	if (err) {
569 		dev_err(sparx5->dev, "Could not allocate TX buffers: %d\n", err);
570 		return err;
571 	}
572 	return err;
573 }
574 
575 static u32 sparx5_fdma_port_ctrl(struct sparx5 *sparx5)
576 {
577 	return spx5_rd(sparx5, FDMA_PORT_CTRL(0));
578 }
579 
580 int sparx5_fdma_stop(struct sparx5 *sparx5)
581 {
582 	u32 val;
583 
584 	napi_disable(&sparx5->rx.napi);
585 	/* Stop the fdma and channel interrupts */
586 	sparx5_fdma_rx_deactivate(sparx5, &sparx5->rx);
587 	sparx5_fdma_tx_deactivate(sparx5, &sparx5->tx);
588 	/* Wait for the RX channel to stop */
589 	read_poll_timeout(sparx5_fdma_port_ctrl, val,
590 			  FDMA_PORT_CTRL_XTR_BUF_IS_EMPTY_GET(val) == 0,
591 			  500, 10000, 0, sparx5);
592 	return 0;
593 }
594