| 2454 | |
| 2455 | |
| 2456 | static inline int |
| 2457 | grinder_schedule(struct rte_sched_port *port, |
| 2458 | struct rte_sched_subport *subport, uint32_t pos) |
| 2459 | { |
| 2460 | struct rte_sched_grinder *grinder = subport->grinder + pos; |
| 2461 | struct rte_sched_queue *queue = grinder->queue[grinder->qpos]; |
| 2462 | uint32_t qindex = grinder->qindex[grinder->qpos]; |
| 2463 | struct rte_mbuf *pkt = grinder->pkt; |
| 2464 | uint32_t pkt_len = pkt->pkt_len + port->frame_overhead; |
| 2465 | uint32_t be_tc_active; |
| 2466 | |
| 2467 | if (subport->tc_ov_enabled) { |
| 2468 | if (!grinder_credits_check_with_tc_ov(port, subport, pos)) |
| 2469 | return 0; |
| 2470 | } else { |
| 2471 | if (!grinder_credits_check(port, subport, pos)) |
| 2472 | return 0; |
| 2473 | } |
| 2474 | |
| 2475 | /* Advance port time */ |
| 2476 | port->time += pkt_len; |
| 2477 | |
| 2478 | /* Send packet */ |
| 2479 | port->pkts_out[port->n_pkts_out++] = pkt; |
| 2480 | queue->qr++; |
| 2481 | |
| 2482 | be_tc_active = (grinder->tc_index == RTE_SCHED_TRAFFIC_CLASS_BE) ? ~0x0 : 0x0; |
| 2483 | grinder->wrr_tokens[grinder->qpos] += |
| 2484 | (pkt_len * grinder->wrr_cost[grinder->qpos]) & be_tc_active; |
| 2485 | |
| 2486 | if (queue->qr == queue->qw) { |
| 2487 | rte_bitmap_clear(subport->bmp, qindex); |
| 2488 | grinder->qmask &= ~(1 << grinder->qpos); |
| 2489 | if (be_tc_active) |
| 2490 | grinder->wrr_mask[grinder->qpos] = 0; |
| 2491 | |
| 2492 | rte_sched_port_red_set_queue_empty_timestamp(port, subport, qindex); |
| 2493 | } |
| 2494 | |
| 2495 | rte_sched_port_pie_dequeue(subport, qindex, pkt_len, port->time_cpu_cycles); |
| 2496 | |
| 2497 | /* Reset pipe loop detection */ |
| 2498 | subport->pipe_loop = RTE_SCHED_PIPE_INVALID; |
| 2499 | grinder->productive = 1; |
| 2500 | |
| 2501 | return 1; |
| 2502 | } |
| 2503 | |
| 2504 | static inline int |
| 2505 | grinder_pipe_exists(struct rte_sched_subport *subport, uint32_t base_pipe) |
no test coverage detected