Lines Matching +full:pre +full:- +full:verified
1 // SPDX-License-Identifier: GPL-2.0-only
46 switch (priv->mode) { in mqprio_enable_offload()
48 if (priv->shaper != TC_MQPRIO_SHAPER_DCB) in mqprio_enable_offload()
49 return -EINVAL; in mqprio_enable_offload()
52 mqprio.flags = priv->flags; in mqprio_enable_offload()
53 if (priv->flags & TC_MQPRIO_F_MODE) in mqprio_enable_offload()
54 mqprio.mode = priv->mode; in mqprio_enable_offload()
55 if (priv->flags & TC_MQPRIO_F_SHAPER) in mqprio_enable_offload()
56 mqprio.shaper = priv->shaper; in mqprio_enable_offload()
57 if (priv->flags & TC_MQPRIO_F_MIN_RATE) in mqprio_enable_offload()
59 mqprio.min_rate[i] = priv->min_rate[i]; in mqprio_enable_offload()
60 if (priv->flags & TC_MQPRIO_F_MAX_RATE) in mqprio_enable_offload()
62 mqprio.max_rate[i] = priv->max_rate[i]; in mqprio_enable_offload()
65 return -EINVAL; in mqprio_enable_offload()
68 mqprio_fp_to_offload(priv->fp, &mqprio); in mqprio_enable_offload()
70 err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_MQPRIO, in mqprio_enable_offload()
75 priv->hw_offload = mqprio.qopt.hw; in mqprio_enable_offload()
86 switch (priv->mode) { in mqprio_disable_offload()
89 dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_MQPRIO, in mqprio_disable_offload()
101 if (priv->qdiscs) { in mqprio_destroy()
103 ntx < dev->num_tx_queues && priv->qdiscs[ntx]; in mqprio_destroy()
105 qdisc_put(priv->qdiscs[ntx]); in mqprio_destroy()
106 kfree(priv->qdiscs); in mqprio_destroy()
109 if (priv->hw_offload && dev->netdev_ops->ndo_setup_tc) in mqprio_destroy()
121 /* Limit qopt->hw to maximum supported offload value. Drivers have in mqprio_parse_opt()
125 if (qopt->hw > TC_MQPRIO_HW_OFFLOAD_MAX) in mqprio_parse_opt()
126 qopt->hw = TC_MQPRIO_HW_OFFLOAD_MAX; in mqprio_parse_opt()
130 * - populate the queue counts itself (and ignore what was requested) in mqprio_parse_opt()
131 * - validate the provided queue counts by itself (and apply them) in mqprio_parse_opt()
132 * - request queue count validation here (and apply them) in mqprio_parse_opt()
135 !qopt->hw || caps->validate_queue_counts, in mqprio_parse_opt()
143 if (qopt->hw && !dev->netdev_ops->ndo_setup_tc) { in mqprio_parse_opt()
146 return -EINVAL; in mqprio_parse_opt()
155 TC_QOPT_MAX_QUEUE - 1),
184 return -EINVAL; in mqprio_parse_tc_entry()
191 return -EINVAL; in mqprio_parse_tc_entry()
216 fp[tc] = priv->fp[tc]; in mqprio_parse_tc_entries()
226 priv->fp[tc] = fp[tc]; in mqprio_parse_tc_entries()
233 return -EOPNOTSUPP; in mqprio_parse_tc_entries()
247 int nlattr_opt_len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt)); in mqprio_parse_nlattr()
261 if (!qopt->hw) { in mqprio_parse_nlattr()
264 return -EINVAL; in mqprio_parse_nlattr()
268 priv->flags |= TC_MQPRIO_F_MODE; in mqprio_parse_nlattr()
269 priv->mode = nla_get_u16(tb[TCA_MQPRIO_MODE]); in mqprio_parse_nlattr()
273 priv->flags |= TC_MQPRIO_F_SHAPER; in mqprio_parse_nlattr()
274 priv->shaper = nla_get_u16(tb[TCA_MQPRIO_SHAPER]); in mqprio_parse_nlattr()
278 if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) { in mqprio_parse_nlattr()
281 return -EINVAL; in mqprio_parse_nlattr()
289 return -EINVAL; in mqprio_parse_nlattr()
295 return -EINVAL; in mqprio_parse_nlattr()
298 if (i >= qopt->num_tc) in mqprio_parse_nlattr()
300 priv->min_rate[i] = nla_get_u64(attr); in mqprio_parse_nlattr()
303 priv->flags |= TC_MQPRIO_F_MIN_RATE; in mqprio_parse_nlattr()
307 if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) { in mqprio_parse_nlattr()
310 return -EINVAL; in mqprio_parse_nlattr()
318 return -EINVAL; in mqprio_parse_nlattr()
324 return -EINVAL; in mqprio_parse_nlattr()
327 if (i >= qopt->num_tc) in mqprio_parse_nlattr()
329 priv->max_rate[i] = nla_get_u64(attr); in mqprio_parse_nlattr()
332 priv->flags |= TC_MQPRIO_F_MAX_RATE; in mqprio_parse_nlattr()
352 int i, err = -EOPNOTSUPP; in mqprio_init()
360 if (sch->parent != TC_H_ROOT) in mqprio_init()
361 return -EOPNOTSUPP; in mqprio_init()
364 return -EOPNOTSUPP; in mqprio_init()
367 if (dev->num_tx_queues >= TC_H_MIN_PRIORITY) in mqprio_init()
368 return -ENOMEM; in mqprio_init()
371 return -EINVAL; in mqprio_init()
374 priv->fp[tc] = TC_FP_EXPRESS; in mqprio_init()
381 return -EINVAL; in mqprio_init()
383 len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt)); in mqprio_init()
390 /* pre-allocate qdisc, attachment can't fail */ in mqprio_init()
391 priv->qdiscs = kcalloc(dev->num_tx_queues, sizeof(priv->qdiscs[0]), in mqprio_init()
393 if (!priv->qdiscs) in mqprio_init()
394 return -ENOMEM; in mqprio_init()
396 for (i = 0; i < dev->num_tx_queues; i++) { in mqprio_init()
400 TC_H_MAKE(TC_H_MAJ(sch->handle), in mqprio_init()
403 return -ENOMEM; in mqprio_init()
405 priv->qdiscs[i] = qdisc; in mqprio_init()
406 qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; in mqprio_init()
411 * supplied and verified mapping in mqprio_init()
413 if (qopt->hw) { in mqprio_init()
418 netdev_set_num_tc(dev, qopt->num_tc); in mqprio_init()
419 for (i = 0; i < qopt->num_tc; i++) in mqprio_init()
421 qopt->count[i], qopt->offset[i]); in mqprio_init()
426 netdev_set_prio_tc_map(dev, i, qopt->prio_tc_map[i]); in mqprio_init()
428 sch->flags |= TCQ_F_MQROOT; in mqprio_init()
440 for (ntx = 0; ntx < dev->num_tx_queues; ntx++) { in mqprio_attach()
441 qdisc = priv->qdiscs[ntx]; in mqprio_attach()
442 old = dev_graft_qdisc(qdisc->dev_queue, qdisc); in mqprio_attach()
445 if (ntx < dev->real_num_tx_queues) in mqprio_attach()
448 kfree(priv->qdiscs); in mqprio_attach()
449 priv->qdiscs = NULL; in mqprio_attach()
456 unsigned long ntx = cl - 1; in mqprio_queue_get()
458 if (ntx >= dev->num_tx_queues) in mqprio_queue_get()
470 return -EINVAL; in mqprio_graft()
472 if (dev->flags & IFF_UP) in mqprio_graft()
478 new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; in mqprio_graft()
480 if (dev->flags & IFF_UP) in mqprio_graft()
492 if (priv->flags & TC_MQPRIO_F_MIN_RATE) { in dump_rates()
497 for (i = 0; i < opt->num_tc; i++) { in dump_rates()
499 sizeof(priv->min_rate[i]), in dump_rates()
500 &priv->min_rate[i])) in dump_rates()
506 if (priv->flags & TC_MQPRIO_F_MAX_RATE) { in dump_rates()
511 for (i = 0; i < opt->num_tc; i++) { in dump_rates()
513 sizeof(priv->max_rate[i]), in dump_rates()
514 &priv->max_rate[i])) in dump_rates()
523 return -1; in dump_rates()
535 return -EMSGSIZE; in mqprio_dump_tc_entries()
540 if (nla_put_u32(skb, TCA_MQPRIO_TC_ENTRY_FP, priv->fp[tc])) in mqprio_dump_tc_entries()
550 return -EMSGSIZE; in mqprio_dump_tc_entries()
562 sch->q.qlen = 0; in mqprio_dump()
563 gnet_stats_basic_sync_init(&sch->bstats); in mqprio_dump()
564 memset(&sch->qstats, 0, sizeof(sch->qstats)); in mqprio_dump()
568 * qdiscs. Percpu stats are added to counters in-band and locking in mqprio_dump()
571 for (ntx = 0; ntx < dev->num_tx_queues; ntx++) { in mqprio_dump()
572 qdisc = rtnl_dereference(netdev_get_tx_queue(dev, ntx)->qdisc_sleeping); in mqprio_dump()
575 gnet_stats_add_basic(&sch->bstats, qdisc->cpu_bstats, in mqprio_dump()
576 &qdisc->bstats, false); in mqprio_dump()
577 gnet_stats_add_queue(&sch->qstats, qdisc->cpu_qstats, in mqprio_dump()
578 &qdisc->qstats); in mqprio_dump()
579 sch->q.qlen += qdisc_qlen(qdisc); in mqprio_dump()
585 opt.hw = priv->hw_offload; in mqprio_dump()
590 if ((priv->flags & TC_MQPRIO_F_MODE) && in mqprio_dump()
591 nla_put_u16(skb, TCA_MQPRIO_MODE, priv->mode)) in mqprio_dump()
594 if ((priv->flags & TC_MQPRIO_F_SHAPER) && in mqprio_dump()
595 nla_put_u16(skb, TCA_MQPRIO_SHAPER, priv->shaper)) in mqprio_dump()
598 if ((priv->flags & TC_MQPRIO_F_MIN_RATE || in mqprio_dump()
599 priv->flags & TC_MQPRIO_F_MAX_RATE) && in mqprio_dump()
609 return -1; in mqprio_dump()
619 return rtnl_dereference(dev_queue->qdisc_sleeping); in mqprio_leaf()
632 return (ntx <= dev->num_tx_queues) ? ntx : 0; in mqprio_find()
636 * TC_H_MIN_PRIORITY + netdev_get_num_tc - 1 in mqprio_find()
638 return ((ntx - TC_H_MIN_PRIORITY) < netdev_get_num_tc(dev)) ? ntx : 0; in mqprio_find()
647 int tc = netdev_txq_to_tc(dev, cl - 1); in mqprio_dump_class()
649 tcm->tcm_parent = (tc < 0) ? 0 : in mqprio_dump_class()
650 TC_H_MAKE(TC_H_MAJ(sch->handle), in mqprio_dump_class()
652 tcm->tcm_info = rtnl_dereference(dev_queue->qdisc_sleeping)->handle; in mqprio_dump_class()
654 tcm->tcm_parent = TC_H_ROOT; in mqprio_dump_class()
655 tcm->tcm_info = 0; in mqprio_dump_class()
657 tcm->tcm_handle |= TC_H_MIN(cl); in mqprio_dump_class()
663 __releases(d->lock) in mqprio_dump_class_stats()
664 __acquires(d->lock) in mqprio_dump_class_stats()
672 struct netdev_tc_txq tc = dev->tc_to_txq[cl & TC_BITMASK]; in mqprio_dump_class_stats()
676 * statistics this is required because the d->lock we in mqprio_dump_class_stats()
677 * hold here is the look on dev_queue->qdisc_sleeping in mqprio_dump_class_stats()
680 if (d->lock) in mqprio_dump_class_stats()
681 spin_unlock_bh(d->lock); in mqprio_dump_class_stats()
685 struct Qdisc *qdisc = rtnl_dereference(q->qdisc); in mqprio_dump_class_stats()
689 gnet_stats_add_basic(&bstats, qdisc->cpu_bstats, in mqprio_dump_class_stats()
690 &qdisc->bstats, false); in mqprio_dump_class_stats()
691 gnet_stats_add_queue(&qstats, qdisc->cpu_qstats, in mqprio_dump_class_stats()
692 &qdisc->qstats); in mqprio_dump_class_stats()
693 sch->q.qlen += qdisc_qlen(qdisc); in mqprio_dump_class_stats()
700 if (d->lock) in mqprio_dump_class_stats()
701 spin_lock_bh(d->lock); in mqprio_dump_class_stats()
704 return -1; in mqprio_dump_class_stats()
708 sch = rtnl_dereference(dev_queue->qdisc_sleeping); in mqprio_dump_class_stats()
709 if (gnet_stats_copy_basic(d, sch->cpu_bstats, in mqprio_dump_class_stats()
710 &sch->bstats, true) < 0 || in mqprio_dump_class_stats()
712 return -1; in mqprio_dump_class_stats()
722 if (arg->stop) in mqprio_walk()
726 arg->count = arg->skip; in mqprio_walk()
727 for (ntx = arg->skip; ntx < netdev_get_num_tc(dev); ntx++) { in mqprio_walk()
734 arg->count = TC_MAX_QUEUE; in mqprio_walk()
738 /* Reset offset, sort out remaining per-queue qdiscs */ in mqprio_walk()
739 for (ntx -= TC_MAX_QUEUE; ntx < dev->num_tx_queues; ntx++) { in mqprio_walk()
740 if (arg->fn(sch, ntx + 1, arg) < 0) { in mqprio_walk()
741 arg->stop = 1; in mqprio_walk()
744 arg->count++; in mqprio_walk()
751 return mqprio_queue_get(sch, TC_H_MIN(tcm->tcm_parent)); in mqprio_select_queue()