044c5f132eb2fa731867c7eff33b689d9fe3fac0
[dpdk.git] / drivers / event / octeontx2 / otx2_worker.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include "otx2_worker.h"
6
7 static __rte_noinline uint8_t
8 otx2_ssogws_new_event(struct otx2_ssogws *ws, const struct rte_event *ev)
9 {
10         const uint32_t tag = (uint32_t)ev->event;
11         const uint8_t new_tt = ev->sched_type;
12         const uint64_t event_ptr = ev->u64;
13         const uint16_t grp = ev->queue_id;
14
15         if (ws->xaq_lmt <= *ws->fc_mem)
16                 return 0;
17
18         otx2_ssogws_add_work(ws, event_ptr, tag, new_tt, grp);
19
20         return 1;
21 }
22
23 static __rte_always_inline void
24 otx2_ssogws_fwd_swtag(struct otx2_ssogws *ws, const struct rte_event *ev)
25 {
26         const uint32_t tag = (uint32_t)ev->event;
27         const uint8_t new_tt = ev->sched_type;
28         const uint8_t cur_tt = ws->cur_tt;
29
30         /* 96XX model
31          * cur_tt/new_tt     SSO_SYNC_ORDERED SSO_SYNC_ATOMIC SSO_SYNC_UNTAGGED
32          *
33          * SSO_SYNC_ORDERED        norm           norm             untag
34          * SSO_SYNC_ATOMIC         norm           norm             untag
35          * SSO_SYNC_UNTAGGED       norm           norm             NOOP
36          */
37
38         if (new_tt == SSO_SYNC_UNTAGGED) {
39                 if (cur_tt != SSO_SYNC_UNTAGGED)
40                         otx2_ssogws_swtag_untag(ws);
41         } else {
42                 otx2_ssogws_swtag_norm(ws, tag, new_tt);
43         }
44
45         ws->swtag_req = 1;
46 }
47
48 static __rte_always_inline void
49 otx2_ssogws_fwd_group(struct otx2_ssogws *ws, const struct rte_event *ev,
50                       const uint16_t grp)
51 {
52         const uint32_t tag = (uint32_t)ev->event;
53         const uint8_t new_tt = ev->sched_type;
54
55         otx2_write64(ev->u64, OTX2_SSOW_GET_BASE_ADDR(ws->getwrk_op) +
56                      SSOW_LF_GWS_OP_UPD_WQP_GRP1);
57         rte_smp_wmb();
58         otx2_ssogws_swtag_desched(ws, tag, new_tt, grp);
59 }
60
61 static __rte_always_inline void
62 otx2_ssogws_forward_event(struct otx2_ssogws *ws, const struct rte_event *ev)
63 {
64         const uint8_t grp = ev->queue_id;
65
66         /* Group hasn't changed, Use SWTAG to forward the event */
67         if (ws->cur_grp == grp)
68                 otx2_ssogws_fwd_swtag(ws, ev);
69         else
70         /*
71          * Group has been changed for group based work pipelining,
72          * Use deschedule/add_work operation to transfer the event to
73          * new group/core
74          */
75                 otx2_ssogws_fwd_group(ws, ev, grp);
76 }
77
78 static __rte_always_inline void
79 otx2_ssogws_release_event(struct otx2_ssogws *ws)
80 {
81         otx2_ssogws_swtag_flush(ws);
82 }
83
84 uint16_t __hot
85 otx2_ssogws_enq(void *port, const struct rte_event *ev)
86 {
87         struct otx2_ssogws *ws = port;
88
89         switch (ev->op) {
90         case RTE_EVENT_OP_NEW:
91                 rte_smp_mb();
92                 return otx2_ssogws_new_event(ws, ev);
93         case RTE_EVENT_OP_FORWARD:
94                 otx2_ssogws_forward_event(ws, ev);
95                 break;
96         case RTE_EVENT_OP_RELEASE:
97                 otx2_ssogws_release_event(ws);
98                 break;
99         default:
100                 return 0;
101         }
102
103         return 1;
104 }
105
106 uint16_t __hot
107 otx2_ssogws_enq_burst(void *port, const struct rte_event ev[],
108                       uint16_t nb_events)
109 {
110         RTE_SET_USED(nb_events);
111         return otx2_ssogws_enq(port, ev);
112 }
113
114 uint16_t __hot
115 otx2_ssogws_enq_new_burst(void *port, const struct rte_event ev[],
116                           uint16_t nb_events)
117 {
118         struct otx2_ssogws *ws = port;
119         uint16_t i, rc = 1;
120
121         rte_smp_mb();
122         if (ws->xaq_lmt <= *ws->fc_mem)
123                 return 0;
124
125         for (i = 0; i < nb_events && rc; i++)
126                 rc = otx2_ssogws_new_event(ws,  &ev[i]);
127
128         return nb_events;
129 }
130
131 uint16_t __hot
132 otx2_ssogws_enq_fwd_burst(void *port, const struct rte_event ev[],
133                           uint16_t nb_events)
134 {
135         struct otx2_ssogws *ws = port;
136
137         RTE_SET_USED(nb_events);
138         otx2_ssogws_forward_event(ws,  ev);
139
140         return 1;
141 }