1*d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause 2*d30ea906Sjfb8856606 * Copyright(c) 2017 Intel Corporation 3*d30ea906Sjfb8856606 */ 4*d30ea906Sjfb8856606 5*d30ea906Sjfb8856606 #include <inttypes.h> 6*d30ea906Sjfb8856606 #include <string.h> 7*d30ea906Sjfb8856606 8*d30ea906Sjfb8856606 #include <rte_bus_vdev.h> 9*d30ea906Sjfb8856606 #include <rte_errno.h> 10*d30ea906Sjfb8856606 #include <rte_cycles.h> 11*d30ea906Sjfb8856606 #include <rte_memzone.h> 12*d30ea906Sjfb8856606 13*d30ea906Sjfb8856606 #include "opdl_evdev.h" 14*d30ea906Sjfb8856606 #include "opdl_ring.h" 15*d30ea906Sjfb8856606 #include "opdl_log.h" 16*d30ea906Sjfb8856606 17*d30ea906Sjfb8856606 18*d30ea906Sjfb8856606 static __rte_always_inline uint32_t 19*d30ea906Sjfb8856606 enqueue_check(struct opdl_port *p, 20*d30ea906Sjfb8856606 const struct rte_event ev[], 21*d30ea906Sjfb8856606 uint16_t num, 22*d30ea906Sjfb8856606 uint16_t num_events) 23*d30ea906Sjfb8856606 { 24*d30ea906Sjfb8856606 uint16_t i; 25*d30ea906Sjfb8856606 26*d30ea906Sjfb8856606 if (p->opdl->do_validation) { 27*d30ea906Sjfb8856606 28*d30ea906Sjfb8856606 for (i = 0; i < num; i++) { 29*d30ea906Sjfb8856606 if (ev[i].queue_id != p->next_external_qid) { 30*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 31*d30ea906Sjfb8856606 "ERROR - port:[%u] - event wants" 32*d30ea906Sjfb8856606 " to enq to q_id[%u]," 33*d30ea906Sjfb8856606 " but should be [%u]", 34*d30ea906Sjfb8856606 opdl_pmd_dev_id(p->opdl), 35*d30ea906Sjfb8856606 p->id, 36*d30ea906Sjfb8856606 ev[i].queue_id, 37*d30ea906Sjfb8856606 p->next_external_qid); 38*d30ea906Sjfb8856606 rte_errno = -EINVAL; 39*d30ea906Sjfb8856606 return 0; 40*d30ea906Sjfb8856606 } 41*d30ea906Sjfb8856606 } 42*d30ea906Sjfb8856606 43*d30ea906Sjfb8856606 /* Stats */ 44*d30ea906Sjfb8856606 if (p->p_type == OPDL_PURE_RX_PORT || 45*d30ea906Sjfb8856606 p->p_type == OPDL_ASYNC_PORT) { 46*d30ea906Sjfb8856606 /* Stats */ 47*d30ea906Sjfb8856606 if (num_events) { 48*d30ea906Sjfb8856606 p->port_stat[claim_pkts_requested] += num; 49*d30ea906Sjfb8856606 p->port_stat[claim_pkts_granted] += num_events; 50*d30ea906Sjfb8856606 p->port_stat[claim_non_empty]++; 51*d30ea906Sjfb8856606 p->start_cycles = rte_rdtsc(); 52*d30ea906Sjfb8856606 } else { 53*d30ea906Sjfb8856606 p->port_stat[claim_empty]++; 54*d30ea906Sjfb8856606 p->start_cycles = 0; 55*d30ea906Sjfb8856606 } 56*d30ea906Sjfb8856606 } else { 57*d30ea906Sjfb8856606 if (p->start_cycles) { 58*d30ea906Sjfb8856606 uint64_t end_cycles = rte_rdtsc(); 59*d30ea906Sjfb8856606 p->port_stat[total_cycles] += 60*d30ea906Sjfb8856606 end_cycles - p->start_cycles; 61*d30ea906Sjfb8856606 } 62*d30ea906Sjfb8856606 } 63*d30ea906Sjfb8856606 } else { 64*d30ea906Sjfb8856606 if (num > 0 && 65*d30ea906Sjfb8856606 ev[0].queue_id != p->next_external_qid) { 66*d30ea906Sjfb8856606 rte_errno = -EINVAL; 67*d30ea906Sjfb8856606 return 0; 68*d30ea906Sjfb8856606 } 69*d30ea906Sjfb8856606 } 70*d30ea906Sjfb8856606 71*d30ea906Sjfb8856606 return num; 72*d30ea906Sjfb8856606 } 73*d30ea906Sjfb8856606 74*d30ea906Sjfb8856606 static __rte_always_inline void 75*d30ea906Sjfb8856606 update_on_dequeue(struct opdl_port *p, 76*d30ea906Sjfb8856606 struct rte_event ev[], 77*d30ea906Sjfb8856606 uint16_t num, 78*d30ea906Sjfb8856606 uint16_t num_events) 79*d30ea906Sjfb8856606 { 80*d30ea906Sjfb8856606 if (p->opdl->do_validation) { 81*d30ea906Sjfb8856606 int16_t i; 82*d30ea906Sjfb8856606 for (i = 0; i < num; i++) 83*d30ea906Sjfb8856606 ev[i].queue_id = 84*d30ea906Sjfb8856606 p->opdl->queue[p->queue_id].external_qid; 85*d30ea906Sjfb8856606 86*d30ea906Sjfb8856606 /* Stats */ 87*d30ea906Sjfb8856606 if (num_events) { 88*d30ea906Sjfb8856606 p->port_stat[claim_pkts_requested] += num; 89*d30ea906Sjfb8856606 p->port_stat[claim_pkts_granted] += num_events; 90*d30ea906Sjfb8856606 p->port_stat[claim_non_empty]++; 91*d30ea906Sjfb8856606 p->start_cycles = rte_rdtsc(); 92*d30ea906Sjfb8856606 } else { 93*d30ea906Sjfb8856606 p->port_stat[claim_empty]++; 94*d30ea906Sjfb8856606 p->start_cycles = 0; 95*d30ea906Sjfb8856606 } 96*d30ea906Sjfb8856606 } else { 97*d30ea906Sjfb8856606 if (num > 0) 98*d30ea906Sjfb8856606 ev[0].queue_id = 99*d30ea906Sjfb8856606 p->opdl->queue[p->queue_id].external_qid; 100*d30ea906Sjfb8856606 } 101*d30ea906Sjfb8856606 } 102*d30ea906Sjfb8856606 103*d30ea906Sjfb8856606 104*d30ea906Sjfb8856606 /* 105*d30ea906Sjfb8856606 * Error RX enqueue: 106*d30ea906Sjfb8856606 * 107*d30ea906Sjfb8856606 * 108*d30ea906Sjfb8856606 */ 109*d30ea906Sjfb8856606 110*d30ea906Sjfb8856606 static uint16_t 111*d30ea906Sjfb8856606 opdl_rx_error_enqueue(struct opdl_port *p, 112*d30ea906Sjfb8856606 const struct rte_event ev[], 113*d30ea906Sjfb8856606 uint16_t num) 114*d30ea906Sjfb8856606 { 115*d30ea906Sjfb8856606 RTE_SET_USED(p); 116*d30ea906Sjfb8856606 RTE_SET_USED(ev); 117*d30ea906Sjfb8856606 RTE_SET_USED(num); 118*d30ea906Sjfb8856606 119*d30ea906Sjfb8856606 rte_errno = -ENOSPC; 120*d30ea906Sjfb8856606 121*d30ea906Sjfb8856606 return 0; 122*d30ea906Sjfb8856606 } 123*d30ea906Sjfb8856606 124*d30ea906Sjfb8856606 /* 125*d30ea906Sjfb8856606 * RX enqueue: 126*d30ea906Sjfb8856606 * 127*d30ea906Sjfb8856606 * This function handles enqueue for a single input stage_inst with 128*d30ea906Sjfb8856606 * threadsafe disabled or enabled. eg 1 thread using a stage_inst or 129*d30ea906Sjfb8856606 * multiple threads sharing a stage_inst 130*d30ea906Sjfb8856606 */ 131*d30ea906Sjfb8856606 132*d30ea906Sjfb8856606 static uint16_t 133*d30ea906Sjfb8856606 opdl_rx_enqueue(struct opdl_port *p, 134*d30ea906Sjfb8856606 const struct rte_event ev[], 135*d30ea906Sjfb8856606 uint16_t num) 136*d30ea906Sjfb8856606 { 137*d30ea906Sjfb8856606 uint16_t enqueued = 0; 138*d30ea906Sjfb8856606 139*d30ea906Sjfb8856606 enqueued = opdl_ring_input(opdl_stage_get_opdl_ring(p->enq_stage_inst), 140*d30ea906Sjfb8856606 ev, 141*d30ea906Sjfb8856606 num, 142*d30ea906Sjfb8856606 false); 143*d30ea906Sjfb8856606 if (!enqueue_check(p, ev, num, enqueued)) 144*d30ea906Sjfb8856606 return 0; 145*d30ea906Sjfb8856606 146*d30ea906Sjfb8856606 147*d30ea906Sjfb8856606 if (enqueued < num) 148*d30ea906Sjfb8856606 rte_errno = -ENOSPC; 149*d30ea906Sjfb8856606 150*d30ea906Sjfb8856606 return enqueued; 151*d30ea906Sjfb8856606 } 152*d30ea906Sjfb8856606 153*d30ea906Sjfb8856606 /* 154*d30ea906Sjfb8856606 * Error TX handler 155*d30ea906Sjfb8856606 * 156*d30ea906Sjfb8856606 */ 157*d30ea906Sjfb8856606 158*d30ea906Sjfb8856606 static uint16_t 159*d30ea906Sjfb8856606 opdl_tx_error_dequeue(struct opdl_port *p, 160*d30ea906Sjfb8856606 struct rte_event ev[], 161*d30ea906Sjfb8856606 uint16_t num) 162*d30ea906Sjfb8856606 { 163*d30ea906Sjfb8856606 RTE_SET_USED(p); 164*d30ea906Sjfb8856606 RTE_SET_USED(ev); 165*d30ea906Sjfb8856606 RTE_SET_USED(num); 166*d30ea906Sjfb8856606 167*d30ea906Sjfb8856606 rte_errno = -ENOSPC; 168*d30ea906Sjfb8856606 169*d30ea906Sjfb8856606 return 0; 170*d30ea906Sjfb8856606 } 171*d30ea906Sjfb8856606 172*d30ea906Sjfb8856606 /* 173*d30ea906Sjfb8856606 * TX single threaded claim 174*d30ea906Sjfb8856606 * 175*d30ea906Sjfb8856606 * This function handles dequeue for a single worker stage_inst with 176*d30ea906Sjfb8856606 * threadsafe disabled. eg 1 thread using an stage_inst 177*d30ea906Sjfb8856606 */ 178*d30ea906Sjfb8856606 179*d30ea906Sjfb8856606 static uint16_t 180*d30ea906Sjfb8856606 opdl_tx_dequeue_single_thread(struct opdl_port *p, 181*d30ea906Sjfb8856606 struct rte_event ev[], 182*d30ea906Sjfb8856606 uint16_t num) 183*d30ea906Sjfb8856606 { 184*d30ea906Sjfb8856606 uint16_t returned; 185*d30ea906Sjfb8856606 186*d30ea906Sjfb8856606 struct opdl_ring *ring; 187*d30ea906Sjfb8856606 188*d30ea906Sjfb8856606 ring = opdl_stage_get_opdl_ring(p->deq_stage_inst); 189*d30ea906Sjfb8856606 190*d30ea906Sjfb8856606 returned = opdl_ring_copy_to_burst(ring, 191*d30ea906Sjfb8856606 p->deq_stage_inst, 192*d30ea906Sjfb8856606 ev, 193*d30ea906Sjfb8856606 num, 194*d30ea906Sjfb8856606 false); 195*d30ea906Sjfb8856606 196*d30ea906Sjfb8856606 update_on_dequeue(p, ev, num, returned); 197*d30ea906Sjfb8856606 198*d30ea906Sjfb8856606 return returned; 199*d30ea906Sjfb8856606 } 200*d30ea906Sjfb8856606 201*d30ea906Sjfb8856606 /* 202*d30ea906Sjfb8856606 * TX multi threaded claim 203*d30ea906Sjfb8856606 * 204*d30ea906Sjfb8856606 * This function handles dequeue for multiple worker stage_inst with 205*d30ea906Sjfb8856606 * threadsafe disabled. eg multiple stage_inst each with its own instance 206*d30ea906Sjfb8856606 */ 207*d30ea906Sjfb8856606 208*d30ea906Sjfb8856606 static uint16_t 209*d30ea906Sjfb8856606 opdl_tx_dequeue_multi_inst(struct opdl_port *p, 210*d30ea906Sjfb8856606 struct rte_event ev[], 211*d30ea906Sjfb8856606 uint16_t num) 212*d30ea906Sjfb8856606 { 213*d30ea906Sjfb8856606 uint32_t num_events = 0; 214*d30ea906Sjfb8856606 215*d30ea906Sjfb8856606 num_events = opdl_stage_claim(p->deq_stage_inst, 216*d30ea906Sjfb8856606 (void *)ev, 217*d30ea906Sjfb8856606 num, 218*d30ea906Sjfb8856606 NULL, 219*d30ea906Sjfb8856606 false, 220*d30ea906Sjfb8856606 false); 221*d30ea906Sjfb8856606 222*d30ea906Sjfb8856606 update_on_dequeue(p, ev, num, num_events); 223*d30ea906Sjfb8856606 224*d30ea906Sjfb8856606 return opdl_stage_disclaim(p->deq_stage_inst, num_events, false); 225*d30ea906Sjfb8856606 } 226*d30ea906Sjfb8856606 227*d30ea906Sjfb8856606 228*d30ea906Sjfb8856606 /* 229*d30ea906Sjfb8856606 * Worker thread claim 230*d30ea906Sjfb8856606 * 231*d30ea906Sjfb8856606 */ 232*d30ea906Sjfb8856606 233*d30ea906Sjfb8856606 static uint16_t 234*d30ea906Sjfb8856606 opdl_claim(struct opdl_port *p, struct rte_event ev[], uint16_t num) 235*d30ea906Sjfb8856606 { 236*d30ea906Sjfb8856606 uint32_t num_events = 0; 237*d30ea906Sjfb8856606 238*d30ea906Sjfb8856606 if (unlikely(num > MAX_OPDL_CONS_Q_DEPTH)) { 239*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 240*d30ea906Sjfb8856606 "Attempt to dequeue num of events larger than port (%d) max", 241*d30ea906Sjfb8856606 opdl_pmd_dev_id(p->opdl), 242*d30ea906Sjfb8856606 p->id); 243*d30ea906Sjfb8856606 rte_errno = -EINVAL; 244*d30ea906Sjfb8856606 return 0; 245*d30ea906Sjfb8856606 } 246*d30ea906Sjfb8856606 247*d30ea906Sjfb8856606 248*d30ea906Sjfb8856606 num_events = opdl_stage_claim(p->deq_stage_inst, 249*d30ea906Sjfb8856606 (void *)ev, 250*d30ea906Sjfb8856606 num, 251*d30ea906Sjfb8856606 NULL, 252*d30ea906Sjfb8856606 false, 253*d30ea906Sjfb8856606 p->atomic_claim); 254*d30ea906Sjfb8856606 255*d30ea906Sjfb8856606 256*d30ea906Sjfb8856606 update_on_dequeue(p, ev, num, num_events); 257*d30ea906Sjfb8856606 258*d30ea906Sjfb8856606 return num_events; 259*d30ea906Sjfb8856606 } 260*d30ea906Sjfb8856606 261*d30ea906Sjfb8856606 /* 262*d30ea906Sjfb8856606 * Worker thread disclaim 263*d30ea906Sjfb8856606 */ 264*d30ea906Sjfb8856606 265*d30ea906Sjfb8856606 static uint16_t 266*d30ea906Sjfb8856606 opdl_disclaim(struct opdl_port *p, const struct rte_event ev[], uint16_t num) 267*d30ea906Sjfb8856606 { 268*d30ea906Sjfb8856606 uint16_t enqueued = 0; 269*d30ea906Sjfb8856606 270*d30ea906Sjfb8856606 uint32_t i = 0; 271*d30ea906Sjfb8856606 272*d30ea906Sjfb8856606 for (i = 0; i < num; i++) 273*d30ea906Sjfb8856606 opdl_ring_cas_slot(p->enq_stage_inst, &ev[i], 274*d30ea906Sjfb8856606 i, p->atomic_claim); 275*d30ea906Sjfb8856606 276*d30ea906Sjfb8856606 enqueued = opdl_stage_disclaim(p->enq_stage_inst, 277*d30ea906Sjfb8856606 num, 278*d30ea906Sjfb8856606 false); 279*d30ea906Sjfb8856606 280*d30ea906Sjfb8856606 return enqueue_check(p, ev, num, enqueued); 281*d30ea906Sjfb8856606 } 282*d30ea906Sjfb8856606 283*d30ea906Sjfb8856606 static __rte_always_inline struct opdl_stage * 284*d30ea906Sjfb8856606 stage_for_port(struct opdl_queue *q, unsigned int i) 285*d30ea906Sjfb8856606 { 286*d30ea906Sjfb8856606 if (q->q_pos == OPDL_Q_POS_START || q->q_pos == OPDL_Q_POS_MIDDLE) 287*d30ea906Sjfb8856606 return q->ports[i]->enq_stage_inst; 288*d30ea906Sjfb8856606 else 289*d30ea906Sjfb8856606 return q->ports[i]->deq_stage_inst; 290*d30ea906Sjfb8856606 } 291*d30ea906Sjfb8856606 292*d30ea906Sjfb8856606 static int opdl_add_deps(struct opdl_evdev *device, 293*d30ea906Sjfb8856606 int q_id, 294*d30ea906Sjfb8856606 int deps_q_id) 295*d30ea906Sjfb8856606 { 296*d30ea906Sjfb8856606 unsigned int i, j; 297*d30ea906Sjfb8856606 int status; 298*d30ea906Sjfb8856606 struct opdl_ring *ring; 299*d30ea906Sjfb8856606 struct opdl_queue *queue = &device->queue[q_id]; 300*d30ea906Sjfb8856606 struct opdl_queue *queue_deps = &device->queue[deps_q_id]; 301*d30ea906Sjfb8856606 struct opdl_stage *dep_stages[OPDL_PORTS_MAX]; 302*d30ea906Sjfb8856606 303*d30ea906Sjfb8856606 /* sanity check that all stages are for same opdl ring */ 304*d30ea906Sjfb8856606 for (i = 0; i < queue->nb_ports; i++) { 305*d30ea906Sjfb8856606 struct opdl_ring *r = 306*d30ea906Sjfb8856606 opdl_stage_get_opdl_ring(stage_for_port(queue, i)); 307*d30ea906Sjfb8856606 for (j = 0; j < queue_deps->nb_ports; j++) { 308*d30ea906Sjfb8856606 struct opdl_ring *rj = 309*d30ea906Sjfb8856606 opdl_stage_get_opdl_ring( 310*d30ea906Sjfb8856606 stage_for_port(queue_deps, j)); 311*d30ea906Sjfb8856606 if (r != rj) { 312*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 313*d30ea906Sjfb8856606 "Stages and dependents" 314*d30ea906Sjfb8856606 " are not for same opdl ring", 315*d30ea906Sjfb8856606 opdl_pmd_dev_id(device)); 316*d30ea906Sjfb8856606 uint32_t k; 317*d30ea906Sjfb8856606 for (k = 0; k < device->nb_opdls; k++) { 318*d30ea906Sjfb8856606 opdl_ring_dump(device->opdl[k], 319*d30ea906Sjfb8856606 stdout); 320*d30ea906Sjfb8856606 } 321*d30ea906Sjfb8856606 return -EINVAL; 322*d30ea906Sjfb8856606 } 323*d30ea906Sjfb8856606 } 324*d30ea906Sjfb8856606 } 325*d30ea906Sjfb8856606 326*d30ea906Sjfb8856606 /* Gather all stages instance in deps */ 327*d30ea906Sjfb8856606 for (i = 0; i < queue_deps->nb_ports; i++) 328*d30ea906Sjfb8856606 dep_stages[i] = stage_for_port(queue_deps, i); 329*d30ea906Sjfb8856606 330*d30ea906Sjfb8856606 331*d30ea906Sjfb8856606 /* Add all deps for each port->stage_inst in this queue */ 332*d30ea906Sjfb8856606 for (i = 0; i < queue->nb_ports; i++) { 333*d30ea906Sjfb8856606 334*d30ea906Sjfb8856606 ring = opdl_stage_get_opdl_ring(stage_for_port(queue, i)); 335*d30ea906Sjfb8856606 336*d30ea906Sjfb8856606 status = opdl_stage_deps_add(ring, 337*d30ea906Sjfb8856606 stage_for_port(queue, i), 338*d30ea906Sjfb8856606 queue->ports[i]->num_instance, 339*d30ea906Sjfb8856606 queue->ports[i]->instance_id, 340*d30ea906Sjfb8856606 dep_stages, 341*d30ea906Sjfb8856606 queue_deps->nb_ports); 342*d30ea906Sjfb8856606 if (status < 0) 343*d30ea906Sjfb8856606 return -EINVAL; 344*d30ea906Sjfb8856606 } 345*d30ea906Sjfb8856606 346*d30ea906Sjfb8856606 return 0; 347*d30ea906Sjfb8856606 } 348*d30ea906Sjfb8856606 349*d30ea906Sjfb8856606 int 350*d30ea906Sjfb8856606 opdl_add_event_handlers(struct rte_eventdev *dev) 351*d30ea906Sjfb8856606 { 352*d30ea906Sjfb8856606 int err = 0; 353*d30ea906Sjfb8856606 354*d30ea906Sjfb8856606 struct opdl_evdev *device = opdl_pmd_priv(dev); 355*d30ea906Sjfb8856606 unsigned int i; 356*d30ea906Sjfb8856606 357*d30ea906Sjfb8856606 for (i = 0; i < device->max_port_nb; i++) { 358*d30ea906Sjfb8856606 359*d30ea906Sjfb8856606 struct opdl_port *port = &device->ports[i]; 360*d30ea906Sjfb8856606 361*d30ea906Sjfb8856606 if (port->configured) { 362*d30ea906Sjfb8856606 if (port->p_type == OPDL_PURE_RX_PORT) { 363*d30ea906Sjfb8856606 port->enq = opdl_rx_enqueue; 364*d30ea906Sjfb8856606 port->deq = opdl_tx_error_dequeue; 365*d30ea906Sjfb8856606 366*d30ea906Sjfb8856606 } else if (port->p_type == OPDL_PURE_TX_PORT) { 367*d30ea906Sjfb8856606 368*d30ea906Sjfb8856606 port->enq = opdl_rx_error_enqueue; 369*d30ea906Sjfb8856606 370*d30ea906Sjfb8856606 if (port->num_instance == 1) 371*d30ea906Sjfb8856606 port->deq = 372*d30ea906Sjfb8856606 opdl_tx_dequeue_single_thread; 373*d30ea906Sjfb8856606 else 374*d30ea906Sjfb8856606 port->deq = opdl_tx_dequeue_multi_inst; 375*d30ea906Sjfb8856606 376*d30ea906Sjfb8856606 } else if (port->p_type == OPDL_REGULAR_PORT) { 377*d30ea906Sjfb8856606 378*d30ea906Sjfb8856606 port->enq = opdl_disclaim; 379*d30ea906Sjfb8856606 port->deq = opdl_claim; 380*d30ea906Sjfb8856606 381*d30ea906Sjfb8856606 } else if (port->p_type == OPDL_ASYNC_PORT) { 382*d30ea906Sjfb8856606 383*d30ea906Sjfb8856606 port->enq = opdl_rx_enqueue; 384*d30ea906Sjfb8856606 385*d30ea906Sjfb8856606 /* Always single instance */ 386*d30ea906Sjfb8856606 port->deq = opdl_tx_dequeue_single_thread; 387*d30ea906Sjfb8856606 } else { 388*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 389*d30ea906Sjfb8856606 "port:[%u] has invalid port type - ", 390*d30ea906Sjfb8856606 opdl_pmd_dev_id(port->opdl), 391*d30ea906Sjfb8856606 port->id); 392*d30ea906Sjfb8856606 err = -EINVAL; 393*d30ea906Sjfb8856606 break; 394*d30ea906Sjfb8856606 } 395*d30ea906Sjfb8856606 port->initialized = 1; 396*d30ea906Sjfb8856606 } 397*d30ea906Sjfb8856606 } 398*d30ea906Sjfb8856606 399*d30ea906Sjfb8856606 if (!err) 400*d30ea906Sjfb8856606 fprintf(stdout, "Success - enqueue/dequeue handler(s) added\n"); 401*d30ea906Sjfb8856606 return err; 402*d30ea906Sjfb8856606 } 403*d30ea906Sjfb8856606 404*d30ea906Sjfb8856606 int 405*d30ea906Sjfb8856606 build_all_dependencies(struct rte_eventdev *dev) 406*d30ea906Sjfb8856606 { 407*d30ea906Sjfb8856606 408*d30ea906Sjfb8856606 int err = 0; 409*d30ea906Sjfb8856606 unsigned int i; 410*d30ea906Sjfb8856606 struct opdl_evdev *device = opdl_pmd_priv(dev); 411*d30ea906Sjfb8856606 412*d30ea906Sjfb8856606 uint8_t start_qid = 0; 413*d30ea906Sjfb8856606 414*d30ea906Sjfb8856606 for (i = 0; i < RTE_EVENT_MAX_QUEUES_PER_DEV; i++) { 415*d30ea906Sjfb8856606 struct opdl_queue *queue = &device->queue[i]; 416*d30ea906Sjfb8856606 if (!queue->initialized) 417*d30ea906Sjfb8856606 break; 418*d30ea906Sjfb8856606 419*d30ea906Sjfb8856606 if (queue->q_pos == OPDL_Q_POS_START) { 420*d30ea906Sjfb8856606 start_qid = i; 421*d30ea906Sjfb8856606 continue; 422*d30ea906Sjfb8856606 } 423*d30ea906Sjfb8856606 424*d30ea906Sjfb8856606 if (queue->q_pos == OPDL_Q_POS_MIDDLE) { 425*d30ea906Sjfb8856606 err = opdl_add_deps(device, i, i-1); 426*d30ea906Sjfb8856606 if (err < 0) { 427*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 428*d30ea906Sjfb8856606 "dependency addition for queue:[%u] - FAILED", 429*d30ea906Sjfb8856606 dev->data->dev_id, 430*d30ea906Sjfb8856606 queue->external_qid); 431*d30ea906Sjfb8856606 break; 432*d30ea906Sjfb8856606 } 433*d30ea906Sjfb8856606 } 434*d30ea906Sjfb8856606 435*d30ea906Sjfb8856606 if (queue->q_pos == OPDL_Q_POS_END) { 436*d30ea906Sjfb8856606 /* Add this dependency */ 437*d30ea906Sjfb8856606 err = opdl_add_deps(device, i, i-1); 438*d30ea906Sjfb8856606 if (err < 0) { 439*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 440*d30ea906Sjfb8856606 "dependency addition for queue:[%u] - FAILED", 441*d30ea906Sjfb8856606 dev->data->dev_id, 442*d30ea906Sjfb8856606 queue->external_qid); 443*d30ea906Sjfb8856606 break; 444*d30ea906Sjfb8856606 } 445*d30ea906Sjfb8856606 /* Add dependency for rx on tx */ 446*d30ea906Sjfb8856606 err = opdl_add_deps(device, start_qid, i); 447*d30ea906Sjfb8856606 if (err < 0) { 448*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 449*d30ea906Sjfb8856606 "dependency addition for queue:[%u] - FAILED", 450*d30ea906Sjfb8856606 dev->data->dev_id, 451*d30ea906Sjfb8856606 queue->external_qid); 452*d30ea906Sjfb8856606 break; 453*d30ea906Sjfb8856606 } 454*d30ea906Sjfb8856606 } 455*d30ea906Sjfb8856606 } 456*d30ea906Sjfb8856606 457*d30ea906Sjfb8856606 if (!err) 458*d30ea906Sjfb8856606 fprintf(stdout, "Success - dependencies built\n"); 459*d30ea906Sjfb8856606 460*d30ea906Sjfb8856606 return err; 461*d30ea906Sjfb8856606 } 462*d30ea906Sjfb8856606 int 463*d30ea906Sjfb8856606 check_queues_linked(struct rte_eventdev *dev) 464*d30ea906Sjfb8856606 { 465*d30ea906Sjfb8856606 466*d30ea906Sjfb8856606 int err = 0; 467*d30ea906Sjfb8856606 unsigned int i; 468*d30ea906Sjfb8856606 struct opdl_evdev *device = opdl_pmd_priv(dev); 469*d30ea906Sjfb8856606 uint32_t nb_iq = 0; 470*d30ea906Sjfb8856606 471*d30ea906Sjfb8856606 for (i = 0; i < RTE_EVENT_MAX_QUEUES_PER_DEV; i++) { 472*d30ea906Sjfb8856606 struct opdl_queue *queue = &device->queue[i]; 473*d30ea906Sjfb8856606 474*d30ea906Sjfb8856606 if (!queue->initialized) 475*d30ea906Sjfb8856606 break; 476*d30ea906Sjfb8856606 477*d30ea906Sjfb8856606 if (queue->external_qid == OPDL_INVALID_QID) 478*d30ea906Sjfb8856606 nb_iq++; 479*d30ea906Sjfb8856606 480*d30ea906Sjfb8856606 if (queue->nb_ports == 0) { 481*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 482*d30ea906Sjfb8856606 "queue:[%u] has no associated ports", 483*d30ea906Sjfb8856606 dev->data->dev_id, 484*d30ea906Sjfb8856606 i); 485*d30ea906Sjfb8856606 err = -EINVAL; 486*d30ea906Sjfb8856606 break; 487*d30ea906Sjfb8856606 } 488*d30ea906Sjfb8856606 } 489*d30ea906Sjfb8856606 if (!err) { 490*d30ea906Sjfb8856606 if ((i - nb_iq) != device->max_queue_nb) { 491*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 492*d30ea906Sjfb8856606 "%u queues counted but should be %u", 493*d30ea906Sjfb8856606 dev->data->dev_id, 494*d30ea906Sjfb8856606 i - nb_iq, 495*d30ea906Sjfb8856606 device->max_queue_nb); 496*d30ea906Sjfb8856606 err = -1; 497*d30ea906Sjfb8856606 } 498*d30ea906Sjfb8856606 499*d30ea906Sjfb8856606 } 500*d30ea906Sjfb8856606 return err; 501*d30ea906Sjfb8856606 } 502*d30ea906Sjfb8856606 503*d30ea906Sjfb8856606 void 504*d30ea906Sjfb8856606 destroy_queues_and_rings(struct rte_eventdev *dev) 505*d30ea906Sjfb8856606 { 506*d30ea906Sjfb8856606 struct opdl_evdev *device = opdl_pmd_priv(dev); 507*d30ea906Sjfb8856606 uint32_t i; 508*d30ea906Sjfb8856606 509*d30ea906Sjfb8856606 for (i = 0; i < device->nb_opdls; i++) { 510*d30ea906Sjfb8856606 if (device->opdl[i]) 511*d30ea906Sjfb8856606 opdl_ring_free(device->opdl[i]); 512*d30ea906Sjfb8856606 } 513*d30ea906Sjfb8856606 514*d30ea906Sjfb8856606 memset(&device->queue, 515*d30ea906Sjfb8856606 0, 516*d30ea906Sjfb8856606 sizeof(struct opdl_queue) 517*d30ea906Sjfb8856606 * RTE_EVENT_MAX_QUEUES_PER_DEV); 518*d30ea906Sjfb8856606 } 519*d30ea906Sjfb8856606 520*d30ea906Sjfb8856606 #define OPDL_ID(d)(d->nb_opdls - 1) 521*d30ea906Sjfb8856606 522*d30ea906Sjfb8856606 static __rte_always_inline void 523*d30ea906Sjfb8856606 initialise_queue(struct opdl_evdev *device, 524*d30ea906Sjfb8856606 enum queue_pos pos, 525*d30ea906Sjfb8856606 int32_t i) 526*d30ea906Sjfb8856606 { 527*d30ea906Sjfb8856606 struct opdl_queue *queue = &device->queue[device->nb_queues]; 528*d30ea906Sjfb8856606 529*d30ea906Sjfb8856606 if (i == -1) { 530*d30ea906Sjfb8856606 queue->q_type = OPDL_Q_TYPE_ORDERED; 531*d30ea906Sjfb8856606 queue->external_qid = OPDL_INVALID_QID; 532*d30ea906Sjfb8856606 } else { 533*d30ea906Sjfb8856606 queue->q_type = device->q_md[i].type; 534*d30ea906Sjfb8856606 queue->external_qid = device->q_md[i].ext_id; 535*d30ea906Sjfb8856606 /* Add ex->in for queues setup */ 536*d30ea906Sjfb8856606 device->q_map_ex_to_in[queue->external_qid] = device->nb_queues; 537*d30ea906Sjfb8856606 } 538*d30ea906Sjfb8856606 queue->opdl_id = OPDL_ID(device); 539*d30ea906Sjfb8856606 queue->q_pos = pos; 540*d30ea906Sjfb8856606 queue->nb_ports = 0; 541*d30ea906Sjfb8856606 queue->configured = 1; 542*d30ea906Sjfb8856606 543*d30ea906Sjfb8856606 device->nb_queues++; 544*d30ea906Sjfb8856606 } 545*d30ea906Sjfb8856606 546*d30ea906Sjfb8856606 547*d30ea906Sjfb8856606 static __rte_always_inline int 548*d30ea906Sjfb8856606 create_opdl(struct opdl_evdev *device) 549*d30ea906Sjfb8856606 { 550*d30ea906Sjfb8856606 int err = 0; 551*d30ea906Sjfb8856606 552*d30ea906Sjfb8856606 char name[RTE_MEMZONE_NAMESIZE]; 553*d30ea906Sjfb8856606 554*d30ea906Sjfb8856606 snprintf(name, RTE_MEMZONE_NAMESIZE, 555*d30ea906Sjfb8856606 "%s_%u", device->service_name, device->nb_opdls); 556*d30ea906Sjfb8856606 557*d30ea906Sjfb8856606 device->opdl[device->nb_opdls] = 558*d30ea906Sjfb8856606 opdl_ring_create(name, 559*d30ea906Sjfb8856606 device->nb_events_limit, 560*d30ea906Sjfb8856606 sizeof(struct rte_event), 561*d30ea906Sjfb8856606 device->max_port_nb * 2, 562*d30ea906Sjfb8856606 device->socket); 563*d30ea906Sjfb8856606 564*d30ea906Sjfb8856606 if (!device->opdl[device->nb_opdls]) { 565*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 566*d30ea906Sjfb8856606 "opdl ring %u creation - FAILED", 567*d30ea906Sjfb8856606 opdl_pmd_dev_id(device), 568*d30ea906Sjfb8856606 device->nb_opdls); 569*d30ea906Sjfb8856606 err = -EINVAL; 570*d30ea906Sjfb8856606 } else { 571*d30ea906Sjfb8856606 device->nb_opdls++; 572*d30ea906Sjfb8856606 } 573*d30ea906Sjfb8856606 return err; 574*d30ea906Sjfb8856606 } 575*d30ea906Sjfb8856606 576*d30ea906Sjfb8856606 static __rte_always_inline int 577*d30ea906Sjfb8856606 create_link_opdl(struct opdl_evdev *device, uint32_t index) 578*d30ea906Sjfb8856606 { 579*d30ea906Sjfb8856606 580*d30ea906Sjfb8856606 int err = 0; 581*d30ea906Sjfb8856606 582*d30ea906Sjfb8856606 if (device->q_md[index + 1].type != 583*d30ea906Sjfb8856606 OPDL_Q_TYPE_SINGLE_LINK) { 584*d30ea906Sjfb8856606 585*d30ea906Sjfb8856606 /* async queue with regular 586*d30ea906Sjfb8856606 * queue following it 587*d30ea906Sjfb8856606 */ 588*d30ea906Sjfb8856606 589*d30ea906Sjfb8856606 /* create a new opdl ring */ 590*d30ea906Sjfb8856606 err = create_opdl(device); 591*d30ea906Sjfb8856606 if (!err) { 592*d30ea906Sjfb8856606 /* create an initial 593*d30ea906Sjfb8856606 * dummy queue for new opdl 594*d30ea906Sjfb8856606 */ 595*d30ea906Sjfb8856606 initialise_queue(device, 596*d30ea906Sjfb8856606 OPDL_Q_POS_START, 597*d30ea906Sjfb8856606 -1); 598*d30ea906Sjfb8856606 } else { 599*d30ea906Sjfb8856606 err = -EINVAL; 600*d30ea906Sjfb8856606 } 601*d30ea906Sjfb8856606 } else { 602*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 603*d30ea906Sjfb8856606 "queue %u, two consecutive" 604*d30ea906Sjfb8856606 " SINGLE_LINK queues, not allowed", 605*d30ea906Sjfb8856606 opdl_pmd_dev_id(device), 606*d30ea906Sjfb8856606 index); 607*d30ea906Sjfb8856606 err = -EINVAL; 608*d30ea906Sjfb8856606 } 609*d30ea906Sjfb8856606 610*d30ea906Sjfb8856606 return err; 611*d30ea906Sjfb8856606 } 612*d30ea906Sjfb8856606 613*d30ea906Sjfb8856606 int 614*d30ea906Sjfb8856606 create_queues_and_rings(struct rte_eventdev *dev) 615*d30ea906Sjfb8856606 { 616*d30ea906Sjfb8856606 int err = 0; 617*d30ea906Sjfb8856606 618*d30ea906Sjfb8856606 struct opdl_evdev *device = opdl_pmd_priv(dev); 619*d30ea906Sjfb8856606 620*d30ea906Sjfb8856606 device->nb_queues = 0; 621*d30ea906Sjfb8856606 622*d30ea906Sjfb8856606 if (device->nb_ports != device->max_port_nb) { 623*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "Number ports setup:%u NOT EQUAL to max port" 624*d30ea906Sjfb8856606 " number:%u for this device", 625*d30ea906Sjfb8856606 device->nb_ports, 626*d30ea906Sjfb8856606 device->max_port_nb); 627*d30ea906Sjfb8856606 err = -1; 628*d30ea906Sjfb8856606 } 629*d30ea906Sjfb8856606 630*d30ea906Sjfb8856606 if (!err) { 631*d30ea906Sjfb8856606 /* We will have at least one opdl so create it now */ 632*d30ea906Sjfb8856606 err = create_opdl(device); 633*d30ea906Sjfb8856606 } 634*d30ea906Sjfb8856606 635*d30ea906Sjfb8856606 if (!err) { 636*d30ea906Sjfb8856606 637*d30ea906Sjfb8856606 /* Create 1st "dummy" queue */ 638*d30ea906Sjfb8856606 initialise_queue(device, 639*d30ea906Sjfb8856606 OPDL_Q_POS_START, 640*d30ea906Sjfb8856606 -1); 641*d30ea906Sjfb8856606 642*d30ea906Sjfb8856606 uint32_t i; 643*d30ea906Sjfb8856606 for (i = 0; i < device->nb_q_md; i++) { 644*d30ea906Sjfb8856606 645*d30ea906Sjfb8856606 /* Check */ 646*d30ea906Sjfb8856606 if (!device->q_md[i].setup) { 647*d30ea906Sjfb8856606 648*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 649*d30ea906Sjfb8856606 "queue meta data slot %u" 650*d30ea906Sjfb8856606 " not setup - FAILING", 651*d30ea906Sjfb8856606 dev->data->dev_id, 652*d30ea906Sjfb8856606 i); 653*d30ea906Sjfb8856606 err = -EINVAL; 654*d30ea906Sjfb8856606 break; 655*d30ea906Sjfb8856606 } else if (device->q_md[i].type != 656*d30ea906Sjfb8856606 OPDL_Q_TYPE_SINGLE_LINK) { 657*d30ea906Sjfb8856606 658*d30ea906Sjfb8856606 if (!device->q_md[i + 1].setup) { 659*d30ea906Sjfb8856606 /* Create a simple ORDERED/ATOMIC 660*d30ea906Sjfb8856606 * queue at the end 661*d30ea906Sjfb8856606 */ 662*d30ea906Sjfb8856606 initialise_queue(device, 663*d30ea906Sjfb8856606 OPDL_Q_POS_END, 664*d30ea906Sjfb8856606 i); 665*d30ea906Sjfb8856606 666*d30ea906Sjfb8856606 } else { 667*d30ea906Sjfb8856606 /* Create a simple ORDERED/ATOMIC 668*d30ea906Sjfb8856606 * queue in the middle 669*d30ea906Sjfb8856606 */ 670*d30ea906Sjfb8856606 initialise_queue(device, 671*d30ea906Sjfb8856606 OPDL_Q_POS_MIDDLE, 672*d30ea906Sjfb8856606 i); 673*d30ea906Sjfb8856606 } 674*d30ea906Sjfb8856606 } else if (device->q_md[i].type == 675*d30ea906Sjfb8856606 OPDL_Q_TYPE_SINGLE_LINK) { 676*d30ea906Sjfb8856606 677*d30ea906Sjfb8856606 /* create last queue for this opdl */ 678*d30ea906Sjfb8856606 initialise_queue(device, 679*d30ea906Sjfb8856606 OPDL_Q_POS_END, 680*d30ea906Sjfb8856606 i); 681*d30ea906Sjfb8856606 682*d30ea906Sjfb8856606 err = create_link_opdl(device, i); 683*d30ea906Sjfb8856606 684*d30ea906Sjfb8856606 if (err) 685*d30ea906Sjfb8856606 break; 686*d30ea906Sjfb8856606 687*d30ea906Sjfb8856606 688*d30ea906Sjfb8856606 } 689*d30ea906Sjfb8856606 } 690*d30ea906Sjfb8856606 } 691*d30ea906Sjfb8856606 if (err) 692*d30ea906Sjfb8856606 destroy_queues_and_rings(dev); 693*d30ea906Sjfb8856606 694*d30ea906Sjfb8856606 return err; 695*d30ea906Sjfb8856606 } 696*d30ea906Sjfb8856606 697*d30ea906Sjfb8856606 698*d30ea906Sjfb8856606 int 699*d30ea906Sjfb8856606 initialise_all_other_ports(struct rte_eventdev *dev) 700*d30ea906Sjfb8856606 { 701*d30ea906Sjfb8856606 int err = 0; 702*d30ea906Sjfb8856606 struct opdl_stage *stage_inst = NULL; 703*d30ea906Sjfb8856606 704*d30ea906Sjfb8856606 struct opdl_evdev *device = opdl_pmd_priv(dev); 705*d30ea906Sjfb8856606 706*d30ea906Sjfb8856606 uint32_t i; 707*d30ea906Sjfb8856606 for (i = 0; i < device->nb_ports; i++) { 708*d30ea906Sjfb8856606 struct opdl_port *port = &device->ports[i]; 709*d30ea906Sjfb8856606 struct opdl_queue *queue = &device->queue[port->queue_id]; 710*d30ea906Sjfb8856606 711*d30ea906Sjfb8856606 if (port->queue_id == 0) { 712*d30ea906Sjfb8856606 continue; 713*d30ea906Sjfb8856606 } else if (queue->q_type != OPDL_Q_TYPE_SINGLE_LINK) { 714*d30ea906Sjfb8856606 715*d30ea906Sjfb8856606 if (queue->q_pos == OPDL_Q_POS_MIDDLE) { 716*d30ea906Sjfb8856606 717*d30ea906Sjfb8856606 /* Regular port with claim/disclaim */ 718*d30ea906Sjfb8856606 stage_inst = opdl_stage_add( 719*d30ea906Sjfb8856606 device->opdl[queue->opdl_id], 720*d30ea906Sjfb8856606 false, 721*d30ea906Sjfb8856606 false); 722*d30ea906Sjfb8856606 port->deq_stage_inst = stage_inst; 723*d30ea906Sjfb8856606 port->enq_stage_inst = stage_inst; 724*d30ea906Sjfb8856606 725*d30ea906Sjfb8856606 if (queue->q_type == OPDL_Q_TYPE_ATOMIC) 726*d30ea906Sjfb8856606 port->atomic_claim = true; 727*d30ea906Sjfb8856606 else 728*d30ea906Sjfb8856606 port->atomic_claim = false; 729*d30ea906Sjfb8856606 730*d30ea906Sjfb8856606 port->p_type = OPDL_REGULAR_PORT; 731*d30ea906Sjfb8856606 732*d30ea906Sjfb8856606 /* Add the port to the queue array of ports */ 733*d30ea906Sjfb8856606 queue->ports[queue->nb_ports] = port; 734*d30ea906Sjfb8856606 port->instance_id = queue->nb_ports; 735*d30ea906Sjfb8856606 queue->nb_ports++; 736*d30ea906Sjfb8856606 opdl_stage_set_queue_id(stage_inst, 737*d30ea906Sjfb8856606 port->queue_id); 738*d30ea906Sjfb8856606 739*d30ea906Sjfb8856606 } else if (queue->q_pos == OPDL_Q_POS_END) { 740*d30ea906Sjfb8856606 741*d30ea906Sjfb8856606 /* tx port */ 742*d30ea906Sjfb8856606 stage_inst = opdl_stage_add( 743*d30ea906Sjfb8856606 device->opdl[queue->opdl_id], 744*d30ea906Sjfb8856606 false, 745*d30ea906Sjfb8856606 false); 746*d30ea906Sjfb8856606 port->deq_stage_inst = stage_inst; 747*d30ea906Sjfb8856606 port->enq_stage_inst = NULL; 748*d30ea906Sjfb8856606 port->p_type = OPDL_PURE_TX_PORT; 749*d30ea906Sjfb8856606 750*d30ea906Sjfb8856606 /* Add the port to the queue array of ports */ 751*d30ea906Sjfb8856606 queue->ports[queue->nb_ports] = port; 752*d30ea906Sjfb8856606 port->instance_id = queue->nb_ports; 753*d30ea906Sjfb8856606 queue->nb_ports++; 754*d30ea906Sjfb8856606 } else { 755*d30ea906Sjfb8856606 756*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 757*d30ea906Sjfb8856606 "port %u:, linked incorrectly" 758*d30ea906Sjfb8856606 " to a q_pos START/INVALID %u", 759*d30ea906Sjfb8856606 opdl_pmd_dev_id(port->opdl), 760*d30ea906Sjfb8856606 port->id, 761*d30ea906Sjfb8856606 queue->q_pos); 762*d30ea906Sjfb8856606 err = -EINVAL; 763*d30ea906Sjfb8856606 break; 764*d30ea906Sjfb8856606 } 765*d30ea906Sjfb8856606 766*d30ea906Sjfb8856606 } else if (queue->q_type == OPDL_Q_TYPE_SINGLE_LINK) { 767*d30ea906Sjfb8856606 768*d30ea906Sjfb8856606 port->p_type = OPDL_ASYNC_PORT; 769*d30ea906Sjfb8856606 770*d30ea906Sjfb8856606 /* -- tx -- */ 771*d30ea906Sjfb8856606 stage_inst = opdl_stage_add( 772*d30ea906Sjfb8856606 device->opdl[queue->opdl_id], 773*d30ea906Sjfb8856606 false, 774*d30ea906Sjfb8856606 false); /* First stage */ 775*d30ea906Sjfb8856606 port->deq_stage_inst = stage_inst; 776*d30ea906Sjfb8856606 777*d30ea906Sjfb8856606 /* Add the port to the queue array of ports */ 778*d30ea906Sjfb8856606 queue->ports[queue->nb_ports] = port; 779*d30ea906Sjfb8856606 port->instance_id = queue->nb_ports; 780*d30ea906Sjfb8856606 queue->nb_ports++; 781*d30ea906Sjfb8856606 782*d30ea906Sjfb8856606 if (queue->nb_ports > 1) { 783*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 784*d30ea906Sjfb8856606 "queue %u:, setup as SINGLE_LINK" 785*d30ea906Sjfb8856606 " but has more than one port linked", 786*d30ea906Sjfb8856606 opdl_pmd_dev_id(port->opdl), 787*d30ea906Sjfb8856606 queue->external_qid); 788*d30ea906Sjfb8856606 err = -EINVAL; 789*d30ea906Sjfb8856606 break; 790*d30ea906Sjfb8856606 } 791*d30ea906Sjfb8856606 792*d30ea906Sjfb8856606 /* -- single instance rx for next opdl -- */ 793*d30ea906Sjfb8856606 uint8_t next_qid = 794*d30ea906Sjfb8856606 device->q_map_ex_to_in[queue->external_qid] + 1; 795*d30ea906Sjfb8856606 if (next_qid < RTE_EVENT_MAX_QUEUES_PER_DEV && 796*d30ea906Sjfb8856606 device->queue[next_qid].configured) { 797*d30ea906Sjfb8856606 798*d30ea906Sjfb8856606 /* Remap the queue */ 799*d30ea906Sjfb8856606 queue = &device->queue[next_qid]; 800*d30ea906Sjfb8856606 801*d30ea906Sjfb8856606 stage_inst = opdl_stage_add( 802*d30ea906Sjfb8856606 device->opdl[queue->opdl_id], 803*d30ea906Sjfb8856606 false, 804*d30ea906Sjfb8856606 true); 805*d30ea906Sjfb8856606 port->enq_stage_inst = stage_inst; 806*d30ea906Sjfb8856606 807*d30ea906Sjfb8856606 /* Add the port to the queue array of ports */ 808*d30ea906Sjfb8856606 queue->ports[queue->nb_ports] = port; 809*d30ea906Sjfb8856606 port->instance_id = queue->nb_ports; 810*d30ea906Sjfb8856606 queue->nb_ports++; 811*d30ea906Sjfb8856606 if (queue->nb_ports > 1) { 812*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 813*d30ea906Sjfb8856606 "dummy queue %u: for " 814*d30ea906Sjfb8856606 "port %u, " 815*d30ea906Sjfb8856606 "SINGLE_LINK but has more " 816*d30ea906Sjfb8856606 "than one port linked", 817*d30ea906Sjfb8856606 opdl_pmd_dev_id(port->opdl), 818*d30ea906Sjfb8856606 next_qid, 819*d30ea906Sjfb8856606 port->id); 820*d30ea906Sjfb8856606 err = -EINVAL; 821*d30ea906Sjfb8856606 break; 822*d30ea906Sjfb8856606 } 823*d30ea906Sjfb8856606 /* Set this queue to initialized as it is never 824*d30ea906Sjfb8856606 * referenced by any ports 825*d30ea906Sjfb8856606 */ 826*d30ea906Sjfb8856606 queue->initialized = 1; 827*d30ea906Sjfb8856606 } 828*d30ea906Sjfb8856606 } 829*d30ea906Sjfb8856606 } 830*d30ea906Sjfb8856606 831*d30ea906Sjfb8856606 /* Now that all ports are initialised we need to 832*d30ea906Sjfb8856606 * setup the last bit of stage md 833*d30ea906Sjfb8856606 */ 834*d30ea906Sjfb8856606 if (!err) { 835*d30ea906Sjfb8856606 for (i = 0; i < device->nb_ports; i++) { 836*d30ea906Sjfb8856606 struct opdl_port *port = &device->ports[i]; 837*d30ea906Sjfb8856606 struct opdl_queue *queue = 838*d30ea906Sjfb8856606 &device->queue[port->queue_id]; 839*d30ea906Sjfb8856606 840*d30ea906Sjfb8856606 if (port->configured && 841*d30ea906Sjfb8856606 (port->queue_id != OPDL_INVALID_QID)) { 842*d30ea906Sjfb8856606 if (queue->nb_ports == 0) { 843*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 844*d30ea906Sjfb8856606 "queue:[%u] has no ports" 845*d30ea906Sjfb8856606 " linked to it", 846*d30ea906Sjfb8856606 opdl_pmd_dev_id(port->opdl), 847*d30ea906Sjfb8856606 port->id); 848*d30ea906Sjfb8856606 err = -EINVAL; 849*d30ea906Sjfb8856606 break; 850*d30ea906Sjfb8856606 } 851*d30ea906Sjfb8856606 852*d30ea906Sjfb8856606 port->num_instance = queue->nb_ports; 853*d30ea906Sjfb8856606 port->initialized = 1; 854*d30ea906Sjfb8856606 queue->initialized = 1; 855*d30ea906Sjfb8856606 } else { 856*d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : " 857*d30ea906Sjfb8856606 "Port:[%u] not configured invalid" 858*d30ea906Sjfb8856606 " queue configuration", 859*d30ea906Sjfb8856606 opdl_pmd_dev_id(port->opdl), 860*d30ea906Sjfb8856606 port->id); 861*d30ea906Sjfb8856606 err = -EINVAL; 862*d30ea906Sjfb8856606 break; 863*d30ea906Sjfb8856606 } 864*d30ea906Sjfb8856606 } 865*d30ea906Sjfb8856606 } 866*d30ea906Sjfb8856606 return err; 867*d30ea906Sjfb8856606 } 868*d30ea906Sjfb8856606 869*d30ea906Sjfb8856606 int 870*d30ea906Sjfb8856606 initialise_queue_zero_ports(struct rte_eventdev *dev) 871*d30ea906Sjfb8856606 { 872*d30ea906Sjfb8856606 int err = 0; 873*d30ea906Sjfb8856606 uint8_t mt_rx = 0; 874*d30ea906Sjfb8856606 struct opdl_stage *stage_inst = NULL; 875*d30ea906Sjfb8856606 struct opdl_queue *queue = NULL; 876*d30ea906Sjfb8856606 877*d30ea906Sjfb8856606 struct opdl_evdev *device = opdl_pmd_priv(dev); 878*d30ea906Sjfb8856606 879*d30ea906Sjfb8856606 /* Assign queue zero and figure out how many Q0 ports we have */ 880*d30ea906Sjfb8856606 uint32_t i; 881*d30ea906Sjfb8856606 for (i = 0; i < device->nb_ports; i++) { 882*d30ea906Sjfb8856606 struct opdl_port *port = &device->ports[i]; 883*d30ea906Sjfb8856606 if (port->queue_id == OPDL_INVALID_QID) { 884*d30ea906Sjfb8856606 port->queue_id = 0; 885*d30ea906Sjfb8856606 port->external_qid = OPDL_INVALID_QID; 886*d30ea906Sjfb8856606 port->p_type = OPDL_PURE_RX_PORT; 887*d30ea906Sjfb8856606 mt_rx++; 888*d30ea906Sjfb8856606 } 889*d30ea906Sjfb8856606 } 890*d30ea906Sjfb8856606 891*d30ea906Sjfb8856606 /* Create the stage */ 892*d30ea906Sjfb8856606 stage_inst = opdl_stage_add(device->opdl[0], 893*d30ea906Sjfb8856606 (mt_rx > 1 ? true : false), 894*d30ea906Sjfb8856606 true); 895*d30ea906Sjfb8856606 if (stage_inst) { 896*d30ea906Sjfb8856606 897*d30ea906Sjfb8856606 /* Assign the new created input stage to all relevant ports */ 898*d30ea906Sjfb8856606 for (i = 0; i < device->nb_ports; i++) { 899*d30ea906Sjfb8856606 struct opdl_port *port = &device->ports[i]; 900*d30ea906Sjfb8856606 if (port->queue_id == 0) { 901*d30ea906Sjfb8856606 queue = &device->queue[port->queue_id]; 902*d30ea906Sjfb8856606 port->enq_stage_inst = stage_inst; 903*d30ea906Sjfb8856606 port->deq_stage_inst = NULL; 904*d30ea906Sjfb8856606 port->configured = 1; 905*d30ea906Sjfb8856606 port->initialized = 1; 906*d30ea906Sjfb8856606 907*d30ea906Sjfb8856606 queue->ports[queue->nb_ports] = port; 908*d30ea906Sjfb8856606 port->instance_id = queue->nb_ports; 909*d30ea906Sjfb8856606 queue->nb_ports++; 910*d30ea906Sjfb8856606 } 911*d30ea906Sjfb8856606 } 912*d30ea906Sjfb8856606 } else { 913*d30ea906Sjfb8856606 err = -1; 914*d30ea906Sjfb8856606 } 915*d30ea906Sjfb8856606 return err; 916*d30ea906Sjfb8856606 } 917*d30ea906Sjfb8856606 918*d30ea906Sjfb8856606 int 919*d30ea906Sjfb8856606 assign_internal_queue_ids(struct rte_eventdev *dev) 920*d30ea906Sjfb8856606 { 921*d30ea906Sjfb8856606 int err = 0; 922*d30ea906Sjfb8856606 struct opdl_evdev *device = opdl_pmd_priv(dev); 923*d30ea906Sjfb8856606 uint32_t i; 924*d30ea906Sjfb8856606 925*d30ea906Sjfb8856606 for (i = 0; i < device->nb_ports; i++) { 926*d30ea906Sjfb8856606 struct opdl_port *port = &device->ports[i]; 927*d30ea906Sjfb8856606 if (port->external_qid != OPDL_INVALID_QID) { 928*d30ea906Sjfb8856606 port->queue_id = 929*d30ea906Sjfb8856606 device->q_map_ex_to_in[port->external_qid]; 930*d30ea906Sjfb8856606 931*d30ea906Sjfb8856606 /* Now do the external_qid of the next queue */ 932*d30ea906Sjfb8856606 struct opdl_queue *queue = 933*d30ea906Sjfb8856606 &device->queue[port->queue_id]; 934*d30ea906Sjfb8856606 if (queue->q_pos == OPDL_Q_POS_END) 935*d30ea906Sjfb8856606 port->next_external_qid = 936*d30ea906Sjfb8856606 device->queue[port->queue_id + 2].external_qid; 937*d30ea906Sjfb8856606 else 938*d30ea906Sjfb8856606 port->next_external_qid = 939*d30ea906Sjfb8856606 device->queue[port->queue_id + 1].external_qid; 940*d30ea906Sjfb8856606 } 941*d30ea906Sjfb8856606 } 942*d30ea906Sjfb8856606 return err; 943*d30ea906Sjfb8856606 } 944