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