xref: /linux/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_mqprio.c (revision 189f164e573e18d9f8876dbd3ad8fcbe11f93037)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (C) 2019 Chelsio Communications.  All rights reserved. */
3 
4 #include "cxgb4.h"
5 #include "cxgb4_tc_mqprio.h"
6 #include "sched.h"
7 
cxgb4_mqprio_validate(struct net_device * dev,struct tc_mqprio_qopt_offload * mqprio)8 static int cxgb4_mqprio_validate(struct net_device *dev,
9 				 struct tc_mqprio_qopt_offload *mqprio)
10 {
11 	u64 min_rate = 0, max_rate = 0, max_link_rate;
12 	struct port_info *pi = netdev2pinfo(dev);
13 	struct adapter *adap = netdev2adap(dev);
14 	u32 speed, qcount = 0, qoffset = 0;
15 	u32 start_a, start_b, end_a, end_b;
16 	int ret;
17 	u8 i, j;
18 
19 	if (!mqprio->qopt.num_tc)
20 		return 0;
21 
22 	if (mqprio->qopt.hw != TC_MQPRIO_HW_OFFLOAD_TCS) {
23 		netdev_err(dev, "Only full TC hardware offload is supported\n");
24 		return -EINVAL;
25 	} else if (mqprio->mode != TC_MQPRIO_MODE_CHANNEL) {
26 		netdev_err(dev, "Only channel mode offload is supported\n");
27 		return -EINVAL;
28 	} else if (mqprio->shaper != TC_MQPRIO_SHAPER_BW_RATE) {
29 		netdev_err(dev,	"Only bandwidth rate shaper supported\n");
30 		return -EINVAL;
31 	} else if (mqprio->qopt.num_tc > adap->params.nsched_cls) {
32 		netdev_err(dev,
33 			   "Only %u traffic classes supported by hardware\n",
34 			   adap->params.nsched_cls);
35 		return -ERANGE;
36 	}
37 
38 	ret = t4_get_link_params(pi, NULL, &speed, NULL);
39 	if (ret) {
40 		netdev_err(dev, "Failed to get link speed, ret: %d\n", ret);
41 		return -EINVAL;
42 	}
43 
44 	/* Convert from Mbps to bps */
45 	max_link_rate = (u64)speed * 1000 * 1000;
46 
47 	for (i = 0; i < mqprio->qopt.num_tc; i++) {
48 		qoffset = max_t(u16, mqprio->qopt.offset[i], qoffset);
49 		qcount += mqprio->qopt.count[i];
50 
51 		start_a = mqprio->qopt.offset[i];
52 		end_a = start_a + mqprio->qopt.count[i] - 1;
53 		for (j = i + 1; j < mqprio->qopt.num_tc; j++) {
54 			start_b = mqprio->qopt.offset[j];
55 			end_b = start_b + mqprio->qopt.count[j] - 1;
56 
57 			/* If queue count is 0, then the traffic
58 			 * belonging to this class will not use
59 			 * ETHOFLD queues. So, no need to validate
60 			 * further.
61 			 */
62 			if (!mqprio->qopt.count[i])
63 				break;
64 
65 			if (!mqprio->qopt.count[j])
66 				continue;
67 
68 			if (max_t(u32, start_a, start_b) <=
69 			    min_t(u32, end_a, end_b)) {
70 				netdev_err(dev,
71 					   "Queues can't overlap across tc\n");
72 				return -EINVAL;
73 			}
74 		}
75 
76 		/* Convert byte per second to bits per second */
77 		min_rate += (mqprio->min_rate[i] * 8);
78 		max_rate += (mqprio->max_rate[i] * 8);
79 	}
80 
81 	if (qoffset >= adap->tids.neotids || qcount > adap->tids.neotids)
82 		return -ENOMEM;
83 
84 	if (min_rate > max_link_rate || max_rate > max_link_rate) {
85 		netdev_err(dev,
86 			   "Total Min/Max (%llu/%llu) Rate > supported (%llu)\n",
87 			   min_rate, max_rate, max_link_rate);
88 		return -EINVAL;
89 	}
90 
91 	return 0;
92 }
93 
cxgb4_init_eosw_txq(struct net_device * dev,struct sge_eosw_txq * eosw_txq,u32 eotid,u32 hwqid)94 static int cxgb4_init_eosw_txq(struct net_device *dev,
95 			       struct sge_eosw_txq *eosw_txq,
96 			       u32 eotid, u32 hwqid)
97 {
98 	struct adapter *adap = netdev2adap(dev);
99 	struct tx_sw_desc *ring;
100 
101 	memset(eosw_txq, 0, sizeof(*eosw_txq));
102 
103 	ring = kzalloc_objs(*ring, CXGB4_EOSW_TXQ_DEFAULT_DESC_NUM);
104 	if (!ring)
105 		return -ENOMEM;
106 
107 	eosw_txq->desc = ring;
108 	eosw_txq->ndesc = CXGB4_EOSW_TXQ_DEFAULT_DESC_NUM;
109 	spin_lock_init(&eosw_txq->lock);
110 	eosw_txq->state = CXGB4_EO_STATE_CLOSED;
111 	eosw_txq->eotid = eotid;
112 	eosw_txq->hwtid = adap->tids.eotid_base + eosw_txq->eotid;
113 	eosw_txq->cred = adap->params.ofldq_wr_cred;
114 	eosw_txq->hwqid = hwqid;
115 	eosw_txq->netdev = dev;
116 	tasklet_setup(&eosw_txq->qresume_tsk, cxgb4_ethofld_restart);
117 	return 0;
118 }
119 
cxgb4_clean_eosw_txq(struct net_device * dev,struct sge_eosw_txq * eosw_txq)120 static void cxgb4_clean_eosw_txq(struct net_device *dev,
121 				 struct sge_eosw_txq *eosw_txq)
122 {
123 	struct adapter *adap = netdev2adap(dev);
124 
125 	cxgb4_eosw_txq_free_desc(adap, eosw_txq, eosw_txq->ndesc);
126 	eosw_txq->pidx = 0;
127 	eosw_txq->last_pidx = 0;
128 	eosw_txq->cidx = 0;
129 	eosw_txq->last_cidx = 0;
130 	eosw_txq->flowc_idx = 0;
131 	eosw_txq->inuse = 0;
132 	eosw_txq->cred = adap->params.ofldq_wr_cred;
133 	eosw_txq->ncompl = 0;
134 	eosw_txq->last_compl = 0;
135 	eosw_txq->state = CXGB4_EO_STATE_CLOSED;
136 }
137 
cxgb4_free_eosw_txq(struct net_device * dev,struct sge_eosw_txq * eosw_txq)138 static void cxgb4_free_eosw_txq(struct net_device *dev,
139 				struct sge_eosw_txq *eosw_txq)
140 {
141 	spin_lock_bh(&eosw_txq->lock);
142 	cxgb4_clean_eosw_txq(dev, eosw_txq);
143 	kfree(eosw_txq->desc);
144 	spin_unlock_bh(&eosw_txq->lock);
145 	tasklet_kill(&eosw_txq->qresume_tsk);
146 }
147 
cxgb4_mqprio_alloc_hw_resources(struct net_device * dev)148 static int cxgb4_mqprio_alloc_hw_resources(struct net_device *dev)
149 {
150 	struct port_info *pi = netdev2pinfo(dev);
151 	struct adapter *adap = netdev2adap(dev);
152 	struct sge_ofld_rxq *eorxq;
153 	struct sge_eohw_txq *eotxq;
154 	int ret, msix = 0;
155 	u32 i;
156 
157 	/* Allocate ETHOFLD hardware queue structures if not done already */
158 	if (!refcount_read(&adap->tc_mqprio->refcnt)) {
159 		adap->sge.eohw_rxq = kzalloc_objs(struct sge_ofld_rxq,
160 						  adap->sge.eoqsets);
161 		if (!adap->sge.eohw_rxq)
162 			return -ENOMEM;
163 
164 		adap->sge.eohw_txq = kzalloc_objs(struct sge_eohw_txq,
165 						  adap->sge.eoqsets);
166 		if (!adap->sge.eohw_txq) {
167 			kfree(adap->sge.eohw_rxq);
168 			return -ENOMEM;
169 		}
170 
171 		refcount_set(&adap->tc_mqprio->refcnt, 1);
172 	} else {
173 		refcount_inc(&adap->tc_mqprio->refcnt);
174 	}
175 
176 	if (!(adap->flags & CXGB4_USING_MSIX))
177 		msix = -((int)adap->sge.intrq.abs_id + 1);
178 
179 	for (i = 0; i < pi->nqsets; i++) {
180 		eorxq = &adap->sge.eohw_rxq[pi->first_qset + i];
181 		eotxq = &adap->sge.eohw_txq[pi->first_qset + i];
182 
183 		/* Allocate Rxqs for receiving ETHOFLD Tx completions */
184 		if (msix >= 0) {
185 			msix = cxgb4_get_msix_idx_from_bmap(adap);
186 			if (msix < 0) {
187 				ret = msix;
188 				goto out_free_queues;
189 			}
190 
191 			eorxq->msix = &adap->msix_info[msix];
192 			snprintf(eorxq->msix->desc,
193 				 sizeof(eorxq->msix->desc),
194 				 "%s-eorxq%d", dev->name, i);
195 		}
196 
197 		init_rspq(adap, &eorxq->rspq,
198 			  CXGB4_EOHW_RXQ_DEFAULT_INTR_USEC,
199 			  CXGB4_EOHW_RXQ_DEFAULT_PKT_CNT,
200 			  CXGB4_EOHW_RXQ_DEFAULT_DESC_NUM,
201 			  CXGB4_EOHW_RXQ_DEFAULT_DESC_SIZE);
202 
203 		eorxq->fl.size = CXGB4_EOHW_FLQ_DEFAULT_DESC_NUM;
204 
205 		ret = t4_sge_alloc_rxq(adap, &eorxq->rspq, false,
206 				       dev, msix, &eorxq->fl,
207 				       cxgb4_ethofld_rx_handler,
208 				       NULL, 0);
209 		if (ret)
210 			goto out_free_queues;
211 
212 		/* Allocate ETHOFLD hardware Txqs */
213 		eotxq->q.size = CXGB4_EOHW_TXQ_DEFAULT_DESC_NUM;
214 		ret = t4_sge_alloc_ethofld_txq(adap, eotxq, dev,
215 					       eorxq->rspq.cntxt_id);
216 		if (ret)
217 			goto out_free_queues;
218 
219 		/* Allocate IRQs, set IRQ affinity, and start Rx */
220 		if (adap->flags & CXGB4_USING_MSIX) {
221 			ret = request_irq(eorxq->msix->vec, t4_sge_intr_msix, 0,
222 					  eorxq->msix->desc, &eorxq->rspq);
223 			if (ret)
224 				goto out_free_msix;
225 
226 			cxgb4_set_msix_aff(adap, eorxq->msix->vec,
227 					   &eorxq->msix->aff_mask, i);
228 		}
229 
230 		if (adap->flags & CXGB4_FULL_INIT_DONE)
231 			cxgb4_enable_rx(adap, &eorxq->rspq);
232 	}
233 
234 	return 0;
235 
236 out_free_msix:
237 	while (i-- > 0) {
238 		eorxq = &adap->sge.eohw_rxq[pi->first_qset + i];
239 
240 		if (adap->flags & CXGB4_FULL_INIT_DONE)
241 			cxgb4_quiesce_rx(&eorxq->rspq);
242 
243 		if (adap->flags & CXGB4_USING_MSIX) {
244 			cxgb4_clear_msix_aff(eorxq->msix->vec,
245 					     eorxq->msix->aff_mask);
246 			free_irq(eorxq->msix->vec, &eorxq->rspq);
247 		}
248 	}
249 
250 out_free_queues:
251 	for (i = 0; i < pi->nqsets; i++) {
252 		eorxq = &adap->sge.eohw_rxq[pi->first_qset + i];
253 		eotxq = &adap->sge.eohw_txq[pi->first_qset + i];
254 
255 		if (eorxq->rspq.desc)
256 			free_rspq_fl(adap, &eorxq->rspq, &eorxq->fl);
257 		if (eorxq->msix)
258 			cxgb4_free_msix_idx_in_bmap(adap, eorxq->msix->idx);
259 		t4_sge_free_ethofld_txq(adap, eotxq);
260 	}
261 
262 	if (refcount_dec_and_test(&adap->tc_mqprio->refcnt)) {
263 		kfree(adap->sge.eohw_txq);
264 		kfree(adap->sge.eohw_rxq);
265 	}
266 	return ret;
267 }
268 
cxgb4_mqprio_free_hw_resources(struct net_device * dev)269 static void cxgb4_mqprio_free_hw_resources(struct net_device *dev)
270 {
271 	struct port_info *pi = netdev2pinfo(dev);
272 	struct adapter *adap = netdev2adap(dev);
273 	struct sge_ofld_rxq *eorxq;
274 	struct sge_eohw_txq *eotxq;
275 	u32 i;
276 
277 	/* Return if no ETHOFLD structures have been allocated yet */
278 	if (!refcount_read(&adap->tc_mqprio->refcnt))
279 		return;
280 
281 	/* Return if no hardware queues have been allocated */
282 	if (!adap->sge.eohw_rxq[pi->first_qset].rspq.desc)
283 		return;
284 
285 	for (i = 0; i < pi->nqsets; i++) {
286 		eorxq = &adap->sge.eohw_rxq[pi->first_qset + i];
287 		eotxq = &adap->sge.eohw_txq[pi->first_qset + i];
288 
289 		/* Device removal path will already disable NAPI
290 		 * before unregistering netdevice. So, only disable
291 		 * NAPI if we're not in device removal path
292 		 */
293 		if (!(adap->flags & CXGB4_SHUTTING_DOWN))
294 			cxgb4_quiesce_rx(&eorxq->rspq);
295 
296 		if (adap->flags & CXGB4_USING_MSIX) {
297 			cxgb4_clear_msix_aff(eorxq->msix->vec,
298 					     eorxq->msix->aff_mask);
299 			free_irq(eorxq->msix->vec, &eorxq->rspq);
300 			cxgb4_free_msix_idx_in_bmap(adap, eorxq->msix->idx);
301 		}
302 
303 		free_rspq_fl(adap, &eorxq->rspq, &eorxq->fl);
304 		t4_sge_free_ethofld_txq(adap, eotxq);
305 	}
306 
307 	/* Free up ETHOFLD structures if there are no users */
308 	if (refcount_dec_and_test(&adap->tc_mqprio->refcnt)) {
309 		kfree(adap->sge.eohw_txq);
310 		kfree(adap->sge.eohw_rxq);
311 	}
312 }
313 
cxgb4_mqprio_alloc_tc(struct net_device * dev,struct tc_mqprio_qopt_offload * mqprio)314 static int cxgb4_mqprio_alloc_tc(struct net_device *dev,
315 				 struct tc_mqprio_qopt_offload *mqprio)
316 {
317 	struct ch_sched_params p = {
318 		.type = SCHED_CLASS_TYPE_PACKET,
319 		.u.params.level = SCHED_CLASS_LEVEL_CL_RL,
320 		.u.params.mode = SCHED_CLASS_MODE_FLOW,
321 		.u.params.rateunit = SCHED_CLASS_RATEUNIT_BITS,
322 		.u.params.ratemode = SCHED_CLASS_RATEMODE_ABS,
323 		.u.params.class = SCHED_CLS_NONE,
324 		.u.params.weight = 0,
325 		.u.params.pktsize = dev->mtu,
326 	};
327 	struct cxgb4_tc_port_mqprio *tc_port_mqprio;
328 	struct port_info *pi = netdev2pinfo(dev);
329 	struct adapter *adap = netdev2adap(dev);
330 	struct ch_sched_class *e;
331 	int ret;
332 	u8 i;
333 
334 	tc_port_mqprio = &adap->tc_mqprio->port_mqprio[pi->port_id];
335 	p.u.params.channel = pi->tx_chan;
336 	for (i = 0; i < mqprio->qopt.num_tc; i++) {
337 		/* Convert from bytes per second to Kbps */
338 		p.u.params.minrate = div_u64(mqprio->min_rate[i] * 8, 1000);
339 		p.u.params.maxrate = div_u64(mqprio->max_rate[i] * 8, 1000);
340 
341 		/* Request larger burst buffer for smaller MTU, so
342 		 * that hardware can work on more data per burst
343 		 * cycle.
344 		 */
345 		if (dev->mtu <= ETH_DATA_LEN)
346 			p.u.params.burstsize = 8 * dev->mtu;
347 
348 		e = cxgb4_sched_class_alloc(dev, &p);
349 		if (!e) {
350 			ret = -ENOMEM;
351 			goto out_err;
352 		}
353 
354 		tc_port_mqprio->tc_hwtc_map[i] = e->idx;
355 	}
356 
357 	return 0;
358 
359 out_err:
360 	while (i--)
361 		cxgb4_sched_class_free(dev, tc_port_mqprio->tc_hwtc_map[i]);
362 
363 	return ret;
364 }
365 
cxgb4_mqprio_free_tc(struct net_device * dev)366 static void cxgb4_mqprio_free_tc(struct net_device *dev)
367 {
368 	struct cxgb4_tc_port_mqprio *tc_port_mqprio;
369 	struct port_info *pi = netdev2pinfo(dev);
370 	struct adapter *adap = netdev2adap(dev);
371 	u8 i;
372 
373 	tc_port_mqprio = &adap->tc_mqprio->port_mqprio[pi->port_id];
374 	for (i = 0; i < tc_port_mqprio->mqprio.qopt.num_tc; i++)
375 		cxgb4_sched_class_free(dev, tc_port_mqprio->tc_hwtc_map[i]);
376 }
377 
cxgb4_mqprio_class_bind(struct net_device * dev,struct sge_eosw_txq * eosw_txq,u8 tc)378 static int cxgb4_mqprio_class_bind(struct net_device *dev,
379 				   struct sge_eosw_txq *eosw_txq,
380 				   u8 tc)
381 {
382 	struct ch_sched_flowc fe;
383 	int ret;
384 
385 	init_completion(&eosw_txq->completion);
386 
387 	fe.tid = eosw_txq->eotid;
388 	fe.class = tc;
389 
390 	ret = cxgb4_sched_class_bind(dev, &fe, SCHED_FLOWC);
391 	if (ret)
392 		return ret;
393 
394 	ret = wait_for_completion_timeout(&eosw_txq->completion,
395 					  CXGB4_FLOWC_WAIT_TIMEOUT);
396 	if (!ret)
397 		return -ETIMEDOUT;
398 
399 	return 0;
400 }
401 
cxgb4_mqprio_class_unbind(struct net_device * dev,struct sge_eosw_txq * eosw_txq,u8 tc)402 static void cxgb4_mqprio_class_unbind(struct net_device *dev,
403 				      struct sge_eosw_txq *eosw_txq,
404 				      u8 tc)
405 {
406 	struct adapter *adap = netdev2adap(dev);
407 	struct ch_sched_flowc fe;
408 
409 	/* If we're shutting down, interrupts are disabled and no completions
410 	 * come back. So, skip waiting for completions in this scenario.
411 	 */
412 	if (!(adap->flags & CXGB4_SHUTTING_DOWN))
413 		init_completion(&eosw_txq->completion);
414 
415 	fe.tid = eosw_txq->eotid;
416 	fe.class = tc;
417 	cxgb4_sched_class_unbind(dev, &fe, SCHED_FLOWC);
418 
419 	if (!(adap->flags & CXGB4_SHUTTING_DOWN))
420 		wait_for_completion_timeout(&eosw_txq->completion,
421 					    CXGB4_FLOWC_WAIT_TIMEOUT);
422 }
423 
cxgb4_mqprio_enable_offload(struct net_device * dev,struct tc_mqprio_qopt_offload * mqprio)424 static int cxgb4_mqprio_enable_offload(struct net_device *dev,
425 				       struct tc_mqprio_qopt_offload *mqprio)
426 {
427 	struct cxgb4_tc_port_mqprio *tc_port_mqprio;
428 	u32 qoffset, qcount, tot_qcount, qid, hwqid;
429 	struct port_info *pi = netdev2pinfo(dev);
430 	struct adapter *adap = netdev2adap(dev);
431 	struct sge_eosw_txq *eosw_txq;
432 	int eotid, ret;
433 	u16 i, j;
434 	u8 hwtc;
435 
436 	ret = cxgb4_mqprio_alloc_hw_resources(dev);
437 	if (ret)
438 		return -ENOMEM;
439 
440 	tc_port_mqprio = &adap->tc_mqprio->port_mqprio[pi->port_id];
441 	for (i = 0; i < mqprio->qopt.num_tc; i++) {
442 		qoffset = mqprio->qopt.offset[i];
443 		qcount = mqprio->qopt.count[i];
444 		for (j = 0; j < qcount; j++) {
445 			eotid = cxgb4_get_free_eotid(&adap->tids);
446 			if (eotid < 0) {
447 				ret = -ENOMEM;
448 				goto out_free_eotids;
449 			}
450 
451 			qid = qoffset + j;
452 			hwqid = pi->first_qset + (eotid % pi->nqsets);
453 			eosw_txq = &tc_port_mqprio->eosw_txq[qid];
454 			ret = cxgb4_init_eosw_txq(dev, eosw_txq,
455 						  eotid, hwqid);
456 			if (ret)
457 				goto out_free_eotids;
458 
459 			cxgb4_alloc_eotid(&adap->tids, eotid, eosw_txq);
460 
461 			hwtc = tc_port_mqprio->tc_hwtc_map[i];
462 			ret = cxgb4_mqprio_class_bind(dev, eosw_txq, hwtc);
463 			if (ret)
464 				goto out_free_eotids;
465 		}
466 	}
467 
468 	memcpy(&tc_port_mqprio->mqprio, mqprio,
469 	       sizeof(struct tc_mqprio_qopt_offload));
470 
471 	/* Inform the stack about the configured tc params.
472 	 *
473 	 * Set the correct queue map. If no queue count has been
474 	 * specified, then send the traffic through default NIC
475 	 * queues; instead of ETHOFLD queues.
476 	 */
477 	ret = netdev_set_num_tc(dev, mqprio->qopt.num_tc);
478 	if (ret)
479 		goto out_free_eotids;
480 
481 	tot_qcount = pi->nqsets;
482 	for (i = 0; i < mqprio->qopt.num_tc; i++) {
483 		qcount = mqprio->qopt.count[i];
484 		if (qcount) {
485 			qoffset = mqprio->qopt.offset[i] + pi->nqsets;
486 		} else {
487 			qcount = pi->nqsets;
488 			qoffset = 0;
489 		}
490 
491 		ret = netdev_set_tc_queue(dev, i, qcount, qoffset);
492 		if (ret)
493 			goto out_reset_tc;
494 
495 		tot_qcount += mqprio->qopt.count[i];
496 	}
497 
498 	ret = netif_set_real_num_tx_queues(dev, tot_qcount);
499 	if (ret)
500 		goto out_reset_tc;
501 
502 	tc_port_mqprio->state = CXGB4_MQPRIO_STATE_ACTIVE;
503 	return 0;
504 
505 out_reset_tc:
506 	netdev_reset_tc(dev);
507 	i = mqprio->qopt.num_tc;
508 
509 out_free_eotids:
510 	while (i-- > 0) {
511 		qoffset = mqprio->qopt.offset[i];
512 		qcount = mqprio->qopt.count[i];
513 		for (j = 0; j < qcount; j++) {
514 			eosw_txq = &tc_port_mqprio->eosw_txq[qoffset + j];
515 
516 			hwtc = tc_port_mqprio->tc_hwtc_map[i];
517 			cxgb4_mqprio_class_unbind(dev, eosw_txq, hwtc);
518 
519 			cxgb4_free_eotid(&adap->tids, eosw_txq->eotid);
520 			cxgb4_free_eosw_txq(dev, eosw_txq);
521 		}
522 	}
523 
524 	cxgb4_mqprio_free_hw_resources(dev);
525 	return ret;
526 }
527 
cxgb4_mqprio_disable_offload(struct net_device * dev)528 static void cxgb4_mqprio_disable_offload(struct net_device *dev)
529 {
530 	struct cxgb4_tc_port_mqprio *tc_port_mqprio;
531 	struct port_info *pi = netdev2pinfo(dev);
532 	struct adapter *adap = netdev2adap(dev);
533 	struct sge_eosw_txq *eosw_txq;
534 	u32 qoffset, qcount;
535 	u16 i, j;
536 	u8 hwtc;
537 
538 	tc_port_mqprio = &adap->tc_mqprio->port_mqprio[pi->port_id];
539 	if (tc_port_mqprio->state != CXGB4_MQPRIO_STATE_ACTIVE)
540 		return;
541 
542 	netdev_reset_tc(dev);
543 	netif_set_real_num_tx_queues(dev, pi->nqsets);
544 
545 	for (i = 0; i < tc_port_mqprio->mqprio.qopt.num_tc; i++) {
546 		qoffset = tc_port_mqprio->mqprio.qopt.offset[i];
547 		qcount = tc_port_mqprio->mqprio.qopt.count[i];
548 		for (j = 0; j < qcount; j++) {
549 			eosw_txq = &tc_port_mqprio->eosw_txq[qoffset + j];
550 
551 			hwtc = tc_port_mqprio->tc_hwtc_map[i];
552 			cxgb4_mqprio_class_unbind(dev, eosw_txq, hwtc);
553 
554 			cxgb4_free_eotid(&adap->tids, eosw_txq->eotid);
555 			cxgb4_free_eosw_txq(dev, eosw_txq);
556 		}
557 	}
558 
559 	cxgb4_mqprio_free_hw_resources(dev);
560 
561 	/* Free up the traffic classes */
562 	cxgb4_mqprio_free_tc(dev);
563 
564 	memset(&tc_port_mqprio->mqprio, 0,
565 	       sizeof(struct tc_mqprio_qopt_offload));
566 
567 	tc_port_mqprio->state = CXGB4_MQPRIO_STATE_DISABLED;
568 }
569 
cxgb4_setup_tc_mqprio(struct net_device * dev,struct tc_mqprio_qopt_offload * mqprio)570 int cxgb4_setup_tc_mqprio(struct net_device *dev,
571 			  struct tc_mqprio_qopt_offload *mqprio)
572 {
573 	struct adapter *adap = netdev2adap(dev);
574 	bool needs_bring_up = false;
575 	int ret;
576 
577 	ret = cxgb4_mqprio_validate(dev, mqprio);
578 	if (ret)
579 		return ret;
580 
581 	mutex_lock(&adap->tc_mqprio->mqprio_mutex);
582 
583 	/* To configure tc params, the current allocated EOTIDs must
584 	 * be freed up. However, they can't be freed up if there's
585 	 * traffic running on the interface. So, ensure interface is
586 	 * down before configuring tc params.
587 	 */
588 	if (netif_running(dev)) {
589 		netif_tx_stop_all_queues(dev);
590 		netif_carrier_off(dev);
591 		needs_bring_up = true;
592 	}
593 
594 	cxgb4_mqprio_disable_offload(dev);
595 
596 	/* If requested for clear, then just return since resources are
597 	 * already freed up by now.
598 	 */
599 	if (!mqprio->qopt.num_tc)
600 		goto out;
601 
602 	/* Allocate free available traffic classes and configure
603 	 * their rate parameters.
604 	 */
605 	ret = cxgb4_mqprio_alloc_tc(dev, mqprio);
606 	if (ret)
607 		goto out;
608 
609 	ret = cxgb4_mqprio_enable_offload(dev, mqprio);
610 	if (ret) {
611 		cxgb4_mqprio_free_tc(dev);
612 		goto out;
613 	}
614 
615 out:
616 	if (needs_bring_up) {
617 		netif_tx_start_all_queues(dev);
618 		netif_carrier_on(dev);
619 	}
620 
621 	mutex_unlock(&adap->tc_mqprio->mqprio_mutex);
622 	return ret;
623 }
624 
cxgb4_mqprio_stop_offload(struct adapter * adap)625 void cxgb4_mqprio_stop_offload(struct adapter *adap)
626 {
627 	struct cxgb4_tc_port_mqprio *tc_port_mqprio;
628 	struct net_device *dev;
629 	u8 i;
630 
631 	if (!adap->tc_mqprio || !adap->tc_mqprio->port_mqprio)
632 		return;
633 
634 	mutex_lock(&adap->tc_mqprio->mqprio_mutex);
635 	for_each_port(adap, i) {
636 		dev = adap->port[i];
637 		if (!dev)
638 			continue;
639 
640 		tc_port_mqprio = &adap->tc_mqprio->port_mqprio[i];
641 		if (!tc_port_mqprio->mqprio.qopt.num_tc)
642 			continue;
643 
644 		cxgb4_mqprio_disable_offload(dev);
645 	}
646 	mutex_unlock(&adap->tc_mqprio->mqprio_mutex);
647 }
648 
cxgb4_init_tc_mqprio(struct adapter * adap)649 int cxgb4_init_tc_mqprio(struct adapter *adap)
650 {
651 	struct cxgb4_tc_port_mqprio *tc_port_mqprio, *port_mqprio;
652 	struct cxgb4_tc_mqprio *tc_mqprio;
653 	struct sge_eosw_txq *eosw_txq;
654 	int ret = 0;
655 	u8 i;
656 
657 	tc_mqprio = kzalloc_obj(*tc_mqprio);
658 	if (!tc_mqprio)
659 		return -ENOMEM;
660 
661 	tc_port_mqprio = kzalloc_objs(*tc_port_mqprio, adap->params.nports);
662 	if (!tc_port_mqprio) {
663 		ret = -ENOMEM;
664 		goto out_free_mqprio;
665 	}
666 
667 	mutex_init(&tc_mqprio->mqprio_mutex);
668 
669 	tc_mqprio->port_mqprio = tc_port_mqprio;
670 	for (i = 0; i < adap->params.nports; i++) {
671 		port_mqprio = &tc_mqprio->port_mqprio[i];
672 		eosw_txq = kzalloc_objs(*eosw_txq, adap->tids.neotids);
673 		if (!eosw_txq) {
674 			ret = -ENOMEM;
675 			goto out_free_ports;
676 		}
677 		port_mqprio->eosw_txq = eosw_txq;
678 	}
679 
680 	adap->tc_mqprio = tc_mqprio;
681 	refcount_set(&adap->tc_mqprio->refcnt, 0);
682 	return 0;
683 
684 out_free_ports:
685 	for (i = 0; i < adap->params.nports; i++) {
686 		port_mqprio = &tc_mqprio->port_mqprio[i];
687 		kfree(port_mqprio->eosw_txq);
688 	}
689 	kfree(tc_port_mqprio);
690 
691 out_free_mqprio:
692 	kfree(tc_mqprio);
693 	return ret;
694 }
695 
cxgb4_cleanup_tc_mqprio(struct adapter * adap)696 void cxgb4_cleanup_tc_mqprio(struct adapter *adap)
697 {
698 	struct cxgb4_tc_port_mqprio *port_mqprio;
699 	u8 i;
700 
701 	if (adap->tc_mqprio) {
702 		mutex_lock(&adap->tc_mqprio->mqprio_mutex);
703 		if (adap->tc_mqprio->port_mqprio) {
704 			for (i = 0; i < adap->params.nports; i++) {
705 				struct net_device *dev = adap->port[i];
706 
707 				if (dev)
708 					cxgb4_mqprio_disable_offload(dev);
709 				port_mqprio = &adap->tc_mqprio->port_mqprio[i];
710 				kfree(port_mqprio->eosw_txq);
711 			}
712 			kfree(adap->tc_mqprio->port_mqprio);
713 		}
714 		mutex_unlock(&adap->tc_mqprio->mqprio_mutex);
715 		kfree(adap->tc_mqprio);
716 	}
717 }
718