xref: /openbmc/linux/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c (revision 27bbf45eae9ca98877a2d52a92a188147cd61b07)
1862cd659SVeerasenareddy Burru // SPDX-License-Identifier: GPL-2.0
2862cd659SVeerasenareddy Burru /* Marvell Octeon EP (EndPoint) Ethernet Driver
3862cd659SVeerasenareddy Burru  *
4862cd659SVeerasenareddy Burru  * Copyright (C) 2020 Marvell.
5862cd659SVeerasenareddy Burru  *
6862cd659SVeerasenareddy Burru  */
7862cd659SVeerasenareddy Burru 
8862cd659SVeerasenareddy Burru #include <linux/pci.h>
9862cd659SVeerasenareddy Burru #include <linux/etherdevice.h>
10397dfb57SVeerasenareddy Burru #include <linux/vmalloc.h>
11862cd659SVeerasenareddy Burru 
12862cd659SVeerasenareddy Burru #include "octep_config.h"
13862cd659SVeerasenareddy Burru #include "octep_main.h"
14862cd659SVeerasenareddy Burru 
15397dfb57SVeerasenareddy Burru /* Reset various index of Tx queue data structure. */
octep_iq_reset_indices(struct octep_iq * iq)16397dfb57SVeerasenareddy Burru static void octep_iq_reset_indices(struct octep_iq *iq)
17397dfb57SVeerasenareddy Burru {
18397dfb57SVeerasenareddy Burru 	iq->fill_cnt = 0;
19397dfb57SVeerasenareddy Burru 	iq->host_write_index = 0;
20397dfb57SVeerasenareddy Burru 	iq->octep_read_index = 0;
21397dfb57SVeerasenareddy Burru 	iq->flush_index = 0;
22397dfb57SVeerasenareddy Burru 	iq->pkts_processed = 0;
23397dfb57SVeerasenareddy Burru 	iq->pkt_in_done = 0;
24397dfb57SVeerasenareddy Burru 	atomic_set(&iq->instr_pending, 0);
25397dfb57SVeerasenareddy Burru }
26397dfb57SVeerasenareddy Burru 
27397dfb57SVeerasenareddy Burru /**
2837d79d05SVeerasenareddy Burru  * octep_iq_process_completions() - Process Tx queue completions.
2937d79d05SVeerasenareddy Burru  *
3037d79d05SVeerasenareddy Burru  * @iq: Octeon Tx queue data structure.
3137d79d05SVeerasenareddy Burru  * @budget: max number of completions to be processed in one invocation.
3237d79d05SVeerasenareddy Burru  */
octep_iq_process_completions(struct octep_iq * iq,u16 budget)3337d79d05SVeerasenareddy Burru int octep_iq_process_completions(struct octep_iq *iq, u16 budget)
3437d79d05SVeerasenareddy Burru {
3537d79d05SVeerasenareddy Burru 	u32 compl_pkts, compl_bytes, compl_sg;
3637d79d05SVeerasenareddy Burru 	struct octep_device *oct = iq->octep_dev;
3737d79d05SVeerasenareddy Burru 	struct octep_tx_buffer *tx_buffer;
3837d79d05SVeerasenareddy Burru 	struct skb_shared_info *shinfo;
3937d79d05SVeerasenareddy Burru 	u32 fi = iq->flush_index;
4037d79d05SVeerasenareddy Burru 	struct sk_buff *skb;
4137d79d05SVeerasenareddy Burru 	u8 frags, i;
4237d79d05SVeerasenareddy Burru 
4337d79d05SVeerasenareddy Burru 	compl_pkts = 0;
4437d79d05SVeerasenareddy Burru 	compl_sg = 0;
4537d79d05SVeerasenareddy Burru 	compl_bytes = 0;
4637d79d05SVeerasenareddy Burru 	iq->octep_read_index = oct->hw_ops.update_iq_read_idx(iq);
4737d79d05SVeerasenareddy Burru 
4837d79d05SVeerasenareddy Burru 	while (likely(budget && (fi != iq->octep_read_index))) {
4937d79d05SVeerasenareddy Burru 		tx_buffer = iq->buff_info + fi;
5037d79d05SVeerasenareddy Burru 		skb = tx_buffer->skb;
5137d79d05SVeerasenareddy Burru 
5237d79d05SVeerasenareddy Burru 		fi++;
5337d79d05SVeerasenareddy Burru 		if (unlikely(fi == iq->max_count))
5437d79d05SVeerasenareddy Burru 			fi = 0;
5537d79d05SVeerasenareddy Burru 		compl_bytes += skb->len;
5637d79d05SVeerasenareddy Burru 		compl_pkts++;
5737d79d05SVeerasenareddy Burru 		budget--;
5837d79d05SVeerasenareddy Burru 
5937d79d05SVeerasenareddy Burru 		if (!tx_buffer->gather) {
6037d79d05SVeerasenareddy Burru 			dma_unmap_single(iq->dev, tx_buffer->dma,
6137d79d05SVeerasenareddy Burru 					 tx_buffer->skb->len, DMA_TO_DEVICE);
6237d79d05SVeerasenareddy Burru 			dev_kfree_skb_any(skb);
6337d79d05SVeerasenareddy Burru 			continue;
6437d79d05SVeerasenareddy Burru 		}
6537d79d05SVeerasenareddy Burru 
6637d79d05SVeerasenareddy Burru 		/* Scatter/Gather */
6737d79d05SVeerasenareddy Burru 		shinfo = skb_shinfo(skb);
6837d79d05SVeerasenareddy Burru 		frags = shinfo->nr_frags;
6937d79d05SVeerasenareddy Burru 		compl_sg++;
7037d79d05SVeerasenareddy Burru 
7137d79d05SVeerasenareddy Burru 		dma_unmap_single(iq->dev, tx_buffer->sglist[0].dma_ptr[0],
72*350db8a5SShinas Rasheed 				 tx_buffer->sglist[0].len[3], DMA_TO_DEVICE);
7337d79d05SVeerasenareddy Burru 
7437d79d05SVeerasenareddy Burru 		i = 1; /* entry 0 is main skb, unmapped above */
7537d79d05SVeerasenareddy Burru 		while (frags--) {
7637d79d05SVeerasenareddy Burru 			dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3],
77*350db8a5SShinas Rasheed 				       tx_buffer->sglist[i >> 2].len[3 - (i & 3)], DMA_TO_DEVICE);
7837d79d05SVeerasenareddy Burru 			i++;
7937d79d05SVeerasenareddy Burru 		}
8037d79d05SVeerasenareddy Burru 
8137d79d05SVeerasenareddy Burru 		dev_kfree_skb_any(skb);
8237d79d05SVeerasenareddy Burru 	}
8337d79d05SVeerasenareddy Burru 
8437d79d05SVeerasenareddy Burru 	iq->pkts_processed += compl_pkts;
8537d79d05SVeerasenareddy Burru 	atomic_sub(compl_pkts, &iq->instr_pending);
8637d79d05SVeerasenareddy Burru 	iq->stats.instr_completed += compl_pkts;
8737d79d05SVeerasenareddy Burru 	iq->stats.bytes_sent += compl_bytes;
8837d79d05SVeerasenareddy Burru 	iq->stats.sgentry_sent += compl_sg;
8937d79d05SVeerasenareddy Burru 	iq->flush_index = fi;
9037d79d05SVeerasenareddy Burru 
9137d79d05SVeerasenareddy Burru 	netdev_tx_completed_queue(iq->netdev_q, compl_pkts, compl_bytes);
9237d79d05SVeerasenareddy Burru 
9337d79d05SVeerasenareddy Burru 	if (unlikely(__netif_subqueue_stopped(iq->netdev, iq->q_no)) &&
9437d79d05SVeerasenareddy Burru 	    ((iq->max_count - atomic_read(&iq->instr_pending)) >
9537d79d05SVeerasenareddy Burru 	     OCTEP_WAKE_QUEUE_THRESHOLD))
9637d79d05SVeerasenareddy Burru 		netif_wake_subqueue(iq->netdev, iq->q_no);
9737d79d05SVeerasenareddy Burru 	return !budget;
9837d79d05SVeerasenareddy Burru }
9937d79d05SVeerasenareddy Burru 
10037d79d05SVeerasenareddy Burru /**
101397dfb57SVeerasenareddy Burru  * octep_iq_free_pending() - Free Tx buffers for pending completions.
102397dfb57SVeerasenareddy Burru  *
103397dfb57SVeerasenareddy Burru  * @iq: Octeon Tx queue data structure.
104397dfb57SVeerasenareddy Burru  */
octep_iq_free_pending(struct octep_iq * iq)105397dfb57SVeerasenareddy Burru static void octep_iq_free_pending(struct octep_iq *iq)
106397dfb57SVeerasenareddy Burru {
107397dfb57SVeerasenareddy Burru 	struct octep_tx_buffer *tx_buffer;
108397dfb57SVeerasenareddy Burru 	struct skb_shared_info *shinfo;
109397dfb57SVeerasenareddy Burru 	u32 fi = iq->flush_index;
110397dfb57SVeerasenareddy Burru 	struct sk_buff *skb;
111397dfb57SVeerasenareddy Burru 	u8 frags, i;
112397dfb57SVeerasenareddy Burru 
113397dfb57SVeerasenareddy Burru 	while (fi != iq->host_write_index) {
114397dfb57SVeerasenareddy Burru 		tx_buffer = iq->buff_info + fi;
115397dfb57SVeerasenareddy Burru 		skb = tx_buffer->skb;
116397dfb57SVeerasenareddy Burru 
117397dfb57SVeerasenareddy Burru 		fi++;
118397dfb57SVeerasenareddy Burru 		if (unlikely(fi == iq->max_count))
119397dfb57SVeerasenareddy Burru 			fi = 0;
120397dfb57SVeerasenareddy Burru 
121397dfb57SVeerasenareddy Burru 		if (!tx_buffer->gather) {
122397dfb57SVeerasenareddy Burru 			dma_unmap_single(iq->dev, tx_buffer->dma,
123397dfb57SVeerasenareddy Burru 					 tx_buffer->skb->len, DMA_TO_DEVICE);
124397dfb57SVeerasenareddy Burru 			dev_kfree_skb_any(skb);
125397dfb57SVeerasenareddy Burru 			continue;
126397dfb57SVeerasenareddy Burru 		}
127397dfb57SVeerasenareddy Burru 
128397dfb57SVeerasenareddy Burru 		/* Scatter/Gather */
129397dfb57SVeerasenareddy Burru 		shinfo = skb_shinfo(skb);
130397dfb57SVeerasenareddy Burru 		frags = shinfo->nr_frags;
131397dfb57SVeerasenareddy Burru 
132397dfb57SVeerasenareddy Burru 		dma_unmap_single(iq->dev,
133397dfb57SVeerasenareddy Burru 				 tx_buffer->sglist[0].dma_ptr[0],
134*350db8a5SShinas Rasheed 				 tx_buffer->sglist[0].len[3],
135397dfb57SVeerasenareddy Burru 				 DMA_TO_DEVICE);
136397dfb57SVeerasenareddy Burru 
137397dfb57SVeerasenareddy Burru 		i = 1; /* entry 0 is main skb, unmapped above */
138397dfb57SVeerasenareddy Burru 		while (frags--) {
139397dfb57SVeerasenareddy Burru 			dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3],
140*350db8a5SShinas Rasheed 				       tx_buffer->sglist[i >> 2].len[3 - (i & 3)], DMA_TO_DEVICE);
141397dfb57SVeerasenareddy Burru 			i++;
142397dfb57SVeerasenareddy Burru 		}
143397dfb57SVeerasenareddy Burru 
144397dfb57SVeerasenareddy Burru 		dev_kfree_skb_any(skb);
145397dfb57SVeerasenareddy Burru 	}
146397dfb57SVeerasenareddy Burru 
147397dfb57SVeerasenareddy Burru 	atomic_set(&iq->instr_pending, 0);
148397dfb57SVeerasenareddy Burru 	iq->flush_index = fi;
149397dfb57SVeerasenareddy Burru 	netdev_tx_reset_queue(netdev_get_tx_queue(iq->netdev, iq->q_no));
150397dfb57SVeerasenareddy Burru }
151397dfb57SVeerasenareddy Burru 
152862cd659SVeerasenareddy Burru /**
153862cd659SVeerasenareddy Burru  * octep_clean_iqs()  - Clean Tx queues to shutdown the device.
154862cd659SVeerasenareddy Burru  *
155862cd659SVeerasenareddy Burru  * @oct: Octeon device private data structure.
156862cd659SVeerasenareddy Burru  *
157862cd659SVeerasenareddy Burru  * Free the buffers in Tx queue descriptors pending completion and
158862cd659SVeerasenareddy Burru  * reset queue indices
159862cd659SVeerasenareddy Burru  */
octep_clean_iqs(struct octep_device * oct)160862cd659SVeerasenareddy Burru void octep_clean_iqs(struct octep_device *oct)
161862cd659SVeerasenareddy Burru {
162397dfb57SVeerasenareddy Burru 	int i;
163397dfb57SVeerasenareddy Burru 
164397dfb57SVeerasenareddy Burru 	for (i = 0; i < oct->num_iqs; i++) {
165397dfb57SVeerasenareddy Burru 		octep_iq_free_pending(oct->iq[i]);
166397dfb57SVeerasenareddy Burru 		octep_iq_reset_indices(oct->iq[i]);
167397dfb57SVeerasenareddy Burru 	}
168397dfb57SVeerasenareddy Burru }
169397dfb57SVeerasenareddy Burru 
170397dfb57SVeerasenareddy Burru /**
171397dfb57SVeerasenareddy Burru  * octep_setup_iq() - Setup a Tx queue.
172397dfb57SVeerasenareddy Burru  *
173397dfb57SVeerasenareddy Burru  * @oct: Octeon device private data structure.
174397dfb57SVeerasenareddy Burru  * @q_no: Tx queue number to be setup.
175397dfb57SVeerasenareddy Burru  *
176397dfb57SVeerasenareddy Burru  * Allocate resources for a Tx queue.
177397dfb57SVeerasenareddy Burru  */
octep_setup_iq(struct octep_device * oct,int q_no)178397dfb57SVeerasenareddy Burru static int octep_setup_iq(struct octep_device *oct, int q_no)
179397dfb57SVeerasenareddy Burru {
180397dfb57SVeerasenareddy Burru 	u32 desc_ring_size, buff_info_size, sglist_size;
181397dfb57SVeerasenareddy Burru 	struct octep_iq *iq;
182397dfb57SVeerasenareddy Burru 	int i;
183397dfb57SVeerasenareddy Burru 
184397dfb57SVeerasenareddy Burru 	iq = vzalloc(sizeof(*iq));
185397dfb57SVeerasenareddy Burru 	if (!iq)
186397dfb57SVeerasenareddy Burru 		goto iq_alloc_err;
187397dfb57SVeerasenareddy Burru 	oct->iq[q_no] = iq;
188397dfb57SVeerasenareddy Burru 
189397dfb57SVeerasenareddy Burru 	iq->octep_dev = oct;
190397dfb57SVeerasenareddy Burru 	iq->netdev = oct->netdev;
191397dfb57SVeerasenareddy Burru 	iq->dev = &oct->pdev->dev;
192397dfb57SVeerasenareddy Burru 	iq->q_no = q_no;
193397dfb57SVeerasenareddy Burru 	iq->max_count = CFG_GET_IQ_NUM_DESC(oct->conf);
194397dfb57SVeerasenareddy Burru 	iq->ring_size_mask = iq->max_count - 1;
195397dfb57SVeerasenareddy Burru 	iq->fill_threshold = CFG_GET_IQ_DB_MIN(oct->conf);
196397dfb57SVeerasenareddy Burru 	iq->netdev_q = netdev_get_tx_queue(iq->netdev, q_no);
197397dfb57SVeerasenareddy Burru 
198397dfb57SVeerasenareddy Burru 	/* Allocate memory for hardware queue descriptors */
199397dfb57SVeerasenareddy Burru 	desc_ring_size = OCTEP_IQ_DESC_SIZE * CFG_GET_IQ_NUM_DESC(oct->conf);
200397dfb57SVeerasenareddy Burru 	iq->desc_ring = dma_alloc_coherent(iq->dev, desc_ring_size,
201397dfb57SVeerasenareddy Burru 					   &iq->desc_ring_dma, GFP_KERNEL);
202397dfb57SVeerasenareddy Burru 	if (unlikely(!iq->desc_ring)) {
203397dfb57SVeerasenareddy Burru 		dev_err(iq->dev,
204397dfb57SVeerasenareddy Burru 			"Failed to allocate DMA memory for IQ-%d\n", q_no);
205397dfb57SVeerasenareddy Burru 		goto desc_dma_alloc_err;
206397dfb57SVeerasenareddy Burru 	}
207397dfb57SVeerasenareddy Burru 
208397dfb57SVeerasenareddy Burru 	/* Allocate memory for hardware SGLIST descriptors */
209397dfb57SVeerasenareddy Burru 	sglist_size = OCTEP_SGLIST_SIZE_PER_PKT *
210397dfb57SVeerasenareddy Burru 		      CFG_GET_IQ_NUM_DESC(oct->conf);
211397dfb57SVeerasenareddy Burru 	iq->sglist = dma_alloc_coherent(iq->dev, sglist_size,
212397dfb57SVeerasenareddy Burru 					&iq->sglist_dma, GFP_KERNEL);
213397dfb57SVeerasenareddy Burru 	if (unlikely(!iq->sglist)) {
214397dfb57SVeerasenareddy Burru 		dev_err(iq->dev,
215397dfb57SVeerasenareddy Burru 			"Failed to allocate DMA memory for IQ-%d SGLIST\n",
216397dfb57SVeerasenareddy Burru 			q_no);
217397dfb57SVeerasenareddy Burru 		goto sglist_alloc_err;
218397dfb57SVeerasenareddy Burru 	}
219397dfb57SVeerasenareddy Burru 
220397dfb57SVeerasenareddy Burru 	/* allocate memory to manage Tx packets pending completion */
221397dfb57SVeerasenareddy Burru 	buff_info_size = OCTEP_IQ_TXBUFF_INFO_SIZE * iq->max_count;
222397dfb57SVeerasenareddy Burru 	iq->buff_info = vzalloc(buff_info_size);
223397dfb57SVeerasenareddy Burru 	if (!iq->buff_info) {
224397dfb57SVeerasenareddy Burru 		dev_err(iq->dev,
225397dfb57SVeerasenareddy Burru 			"Failed to allocate buff info for IQ-%d\n", q_no);
226397dfb57SVeerasenareddy Burru 		goto buff_info_err;
227397dfb57SVeerasenareddy Burru 	}
228397dfb57SVeerasenareddy Burru 
229397dfb57SVeerasenareddy Burru 	/* Setup sglist addresses in tx_buffer entries */
230397dfb57SVeerasenareddy Burru 	for (i = 0; i < CFG_GET_IQ_NUM_DESC(oct->conf); i++) {
231397dfb57SVeerasenareddy Burru 		struct octep_tx_buffer *tx_buffer;
232397dfb57SVeerasenareddy Burru 
233397dfb57SVeerasenareddy Burru 		tx_buffer = &iq->buff_info[i];
234397dfb57SVeerasenareddy Burru 		tx_buffer->sglist =
235397dfb57SVeerasenareddy Burru 			&iq->sglist[i * OCTEP_SGLIST_ENTRIES_PER_PKT];
236397dfb57SVeerasenareddy Burru 		tx_buffer->sglist_dma =
237397dfb57SVeerasenareddy Burru 			iq->sglist_dma + (i * OCTEP_SGLIST_SIZE_PER_PKT);
238397dfb57SVeerasenareddy Burru 	}
239397dfb57SVeerasenareddy Burru 
240397dfb57SVeerasenareddy Burru 	octep_iq_reset_indices(iq);
241397dfb57SVeerasenareddy Burru 	oct->hw_ops.setup_iq_regs(oct, q_no);
242397dfb57SVeerasenareddy Burru 
243397dfb57SVeerasenareddy Burru 	oct->num_iqs++;
244397dfb57SVeerasenareddy Burru 	return 0;
245397dfb57SVeerasenareddy Burru 
246397dfb57SVeerasenareddy Burru buff_info_err:
247397dfb57SVeerasenareddy Burru 	dma_free_coherent(iq->dev, sglist_size, iq->sglist, iq->sglist_dma);
248397dfb57SVeerasenareddy Burru sglist_alloc_err:
249397dfb57SVeerasenareddy Burru 	dma_free_coherent(iq->dev, desc_ring_size,
250397dfb57SVeerasenareddy Burru 			  iq->desc_ring, iq->desc_ring_dma);
251397dfb57SVeerasenareddy Burru desc_dma_alloc_err:
252397dfb57SVeerasenareddy Burru 	vfree(iq);
253397dfb57SVeerasenareddy Burru 	oct->iq[q_no] = NULL;
254397dfb57SVeerasenareddy Burru iq_alloc_err:
255397dfb57SVeerasenareddy Burru 	return -1;
256397dfb57SVeerasenareddy Burru }
257397dfb57SVeerasenareddy Burru 
258397dfb57SVeerasenareddy Burru /**
259397dfb57SVeerasenareddy Burru  * octep_free_iq() - Free Tx queue resources.
260397dfb57SVeerasenareddy Burru  *
261397dfb57SVeerasenareddy Burru  * @iq: Octeon Tx queue data structure.
262397dfb57SVeerasenareddy Burru  *
263397dfb57SVeerasenareddy Burru  * Free all the resources allocated for a Tx queue.
264397dfb57SVeerasenareddy Burru  */
octep_free_iq(struct octep_iq * iq)265397dfb57SVeerasenareddy Burru static void octep_free_iq(struct octep_iq *iq)
266397dfb57SVeerasenareddy Burru {
267397dfb57SVeerasenareddy Burru 	struct octep_device *oct = iq->octep_dev;
268397dfb57SVeerasenareddy Burru 	u64 desc_ring_size, sglist_size;
269397dfb57SVeerasenareddy Burru 	int q_no = iq->q_no;
270397dfb57SVeerasenareddy Burru 
271397dfb57SVeerasenareddy Burru 	desc_ring_size = OCTEP_IQ_DESC_SIZE * CFG_GET_IQ_NUM_DESC(oct->conf);
272397dfb57SVeerasenareddy Burru 
273397dfb57SVeerasenareddy Burru 	vfree(iq->buff_info);
274397dfb57SVeerasenareddy Burru 
275397dfb57SVeerasenareddy Burru 	if (iq->desc_ring)
276397dfb57SVeerasenareddy Burru 		dma_free_coherent(iq->dev, desc_ring_size,
277397dfb57SVeerasenareddy Burru 				  iq->desc_ring, iq->desc_ring_dma);
278397dfb57SVeerasenareddy Burru 
279397dfb57SVeerasenareddy Burru 	sglist_size = OCTEP_SGLIST_SIZE_PER_PKT *
280397dfb57SVeerasenareddy Burru 		      CFG_GET_IQ_NUM_DESC(oct->conf);
281397dfb57SVeerasenareddy Burru 	if (iq->sglist)
282397dfb57SVeerasenareddy Burru 		dma_free_coherent(iq->dev, sglist_size,
283397dfb57SVeerasenareddy Burru 				  iq->sglist, iq->sglist_dma);
284397dfb57SVeerasenareddy Burru 
285397dfb57SVeerasenareddy Burru 	vfree(iq);
286397dfb57SVeerasenareddy Burru 	oct->iq[q_no] = NULL;
287397dfb57SVeerasenareddy Burru 	oct->num_iqs--;
288862cd659SVeerasenareddy Burru }
289862cd659SVeerasenareddy Burru 
290862cd659SVeerasenareddy Burru /**
291862cd659SVeerasenareddy Burru  * octep_setup_iqs() - setup resources for all Tx queues.
292862cd659SVeerasenareddy Burru  *
293862cd659SVeerasenareddy Burru  * @oct: Octeon device private data structure.
294862cd659SVeerasenareddy Burru  */
octep_setup_iqs(struct octep_device * oct)295862cd659SVeerasenareddy Burru int octep_setup_iqs(struct octep_device *oct)
296862cd659SVeerasenareddy Burru {
297397dfb57SVeerasenareddy Burru 	int i;
298397dfb57SVeerasenareddy Burru 
299397dfb57SVeerasenareddy Burru 	oct->num_iqs = 0;
300397dfb57SVeerasenareddy Burru 	for (i = 0; i < CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); i++) {
301397dfb57SVeerasenareddy Burru 		if (octep_setup_iq(oct, i)) {
302397dfb57SVeerasenareddy Burru 			dev_err(&oct->pdev->dev,
303397dfb57SVeerasenareddy Burru 				"Failed to setup IQ(TxQ)-%d.\n", i);
304397dfb57SVeerasenareddy Burru 			goto iq_setup_err;
305397dfb57SVeerasenareddy Burru 		}
306397dfb57SVeerasenareddy Burru 		dev_dbg(&oct->pdev->dev, "Successfully setup IQ(TxQ)-%d.\n", i);
307397dfb57SVeerasenareddy Burru 	}
308397dfb57SVeerasenareddy Burru 
309397dfb57SVeerasenareddy Burru 	return 0;
310397dfb57SVeerasenareddy Burru 
311397dfb57SVeerasenareddy Burru iq_setup_err:
312397dfb57SVeerasenareddy Burru 	while (i) {
313397dfb57SVeerasenareddy Burru 		i--;
314397dfb57SVeerasenareddy Burru 		octep_free_iq(oct->iq[i]);
315397dfb57SVeerasenareddy Burru 	}
316862cd659SVeerasenareddy Burru 	return -1;
317862cd659SVeerasenareddy Burru }
318862cd659SVeerasenareddy Burru 
319862cd659SVeerasenareddy Burru /**
320862cd659SVeerasenareddy Burru  * octep_free_iqs() - Free resources of all Tx queues.
321862cd659SVeerasenareddy Burru  *
322862cd659SVeerasenareddy Burru  * @oct: Octeon device private data structure.
323862cd659SVeerasenareddy Burru  */
octep_free_iqs(struct octep_device * oct)324862cd659SVeerasenareddy Burru void octep_free_iqs(struct octep_device *oct)
325862cd659SVeerasenareddy Burru {
326397dfb57SVeerasenareddy Burru 	int i;
327397dfb57SVeerasenareddy Burru 
328397dfb57SVeerasenareddy Burru 	for (i = 0; i < CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); i++) {
329397dfb57SVeerasenareddy Burru 		octep_free_iq(oct->iq[i]);
330397dfb57SVeerasenareddy Burru 		dev_dbg(&oct->pdev->dev,
331397dfb57SVeerasenareddy Burru 			"Successfully destroyed IQ(TxQ)-%d.\n", i);
332397dfb57SVeerasenareddy Burru 	}
333397dfb57SVeerasenareddy Burru 	oct->num_iqs = 0;
334862cd659SVeerasenareddy Burru }
335