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