Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2023 Intel Corporation
3 : : */
4 : : #include "cpfl_ethdev.h"
5 : :
6 : : #include "cpfl_fxp_rule.h"
7 : : #include "cpfl_logs.h"
8 : :
9 : : #define CTLQ_SEND_RETRIES 100
10 : : #define CTLQ_RECEIVE_RETRIES 100
11 : :
12 : : int
13 : 0 : cpfl_send_ctlq_msg(struct idpf_hw *hw, struct idpf_ctlq_info *cq, u16 num_q_msg,
14 : : struct idpf_ctlq_msg q_msg[])
15 : : {
16 : : struct idpf_ctlq_msg **msg_ptr_list;
17 : 0 : u16 clean_count = 0;
18 : : int num_cleaned = 0;
19 : : int retries = 0;
20 : : int ret = 0;
21 : :
22 : 0 : msg_ptr_list = calloc(num_q_msg, sizeof(struct idpf_ctlq_msg *));
23 [ # # ]: 0 : if (!msg_ptr_list) {
24 : 0 : PMD_INIT_LOG(ERR, "no memory for cleaning ctlq");
25 : : ret = -ENOMEM;
26 : 0 : goto err;
27 : : }
28 : :
29 : 0 : ret = cpfl_vport_ctlq_send(hw, cq, num_q_msg, q_msg);
30 [ # # ]: 0 : if (ret) {
31 : 0 : PMD_INIT_LOG(ERR, "cpfl_vport_ctlq_send() failed with error: 0x%4x", ret);
32 : 0 : goto send_err;
33 : : }
34 : :
35 [ # # ]: 0 : while (retries <= CTLQ_SEND_RETRIES) {
36 : 0 : clean_count = num_q_msg - num_cleaned;
37 : 0 : ret = cpfl_vport_ctlq_clean_sq(cq, &clean_count,
38 : 0 : &msg_ptr_list[num_cleaned]);
39 [ # # ]: 0 : if (ret) {
40 : 0 : PMD_INIT_LOG(ERR, "clean ctlq failed: 0x%4x", ret);
41 : 0 : goto send_err;
42 : : }
43 : :
44 : 0 : num_cleaned += clean_count;
45 : 0 : retries++;
46 [ # # ]: 0 : if (num_cleaned >= num_q_msg)
47 : : break;
48 : 0 : rte_delay_us_sleep(10);
49 : : }
50 : :
51 [ # # ]: 0 : if (retries > CTLQ_SEND_RETRIES) {
52 : 0 : PMD_INIT_LOG(ERR, "timed out while polling for completions");
53 : : ret = -1;
54 : 0 : goto send_err;
55 : : }
56 : :
57 : 0 : send_err:
58 : 0 : free(msg_ptr_list);
59 : 0 : err:
60 : 0 : return ret;
61 : : }
62 : :
63 : : int
64 : 0 : cpfl_receive_ctlq_msg(struct idpf_hw *hw, struct idpf_ctlq_info *cq, u16 num_q_msg,
65 : : struct idpf_ctlq_msg q_msg[])
66 : : {
67 : : int retries = 0;
68 : : struct idpf_dma_mem *dma;
69 : : u16 i;
70 : : uint16_t buff_cnt;
71 : : int ret = 0;
72 : :
73 : : retries = 0;
74 [ # # ]: 0 : while (retries <= CTLQ_RECEIVE_RETRIES) {
75 : 0 : rte_delay_us_sleep(10);
76 : 0 : ret = cpfl_vport_ctlq_recv(cq, &num_q_msg, &q_msg[0]);
77 : :
78 [ # # ]: 0 : if (ret && ret != CPFL_ERR_CTLQ_NO_WORK && ret != CPFL_ERR_CTLQ_ERROR &&
79 [ # # ]: 0 : ret != CPFL_ERR_CTLQ_EMPTY) {
80 : 0 : PMD_INIT_LOG(ERR, "failed to recv ctrlq msg. err: 0x%4x", ret);
81 : 0 : retries++;
82 : 0 : continue;
83 : : }
84 : :
85 [ # # ]: 0 : if (ret == CPFL_ERR_CTLQ_NO_WORK) {
86 : 0 : retries++;
87 : 0 : continue;
88 : : }
89 : :
90 [ # # ]: 0 : if (ret == CPFL_ERR_CTLQ_EMPTY)
91 : : break;
92 : :
93 : : /* TODO - process rx controlq message */
94 [ # # ]: 0 : for (i = 0; i < num_q_msg; i++) {
95 : 0 : ret = q_msg[i].status;
96 [ # # ]: 0 : if (ret != CPFL_CFG_PKT_ERR_OK &&
97 [ # # ]: 0 : q_msg[i].opcode != cpfl_ctlq_sem_query_del_rule_hash_addr) {
98 : 0 : PMD_INIT_LOG(ERR, "Failed to process rx_ctrlq msg: %s",
99 : : cpfl_cfg_pkt_errormsg[ret]);
100 : 0 : return ret;
101 : : }
102 : :
103 [ # # ]: 0 : if (q_msg[i].data_len > 0)
104 : 0 : dma = q_msg[i].ctx.indirect.payload;
105 : : else
106 : 0 : dma = NULL;
107 : :
108 : 0 : buff_cnt = dma ? 1 : 0;
109 : 0 : ret = cpfl_vport_ctlq_post_rx_buffs(hw, cq, &buff_cnt, &dma);
110 [ # # ]: 0 : if (ret)
111 : 0 : PMD_INIT_LOG(WARNING, "could not posted recv bufs");
112 : : }
113 : : break;
114 : : }
115 : :
116 [ # # ]: 0 : if (retries > CTLQ_RECEIVE_RETRIES) {
117 : 0 : PMD_INIT_LOG(ERR, "timed out while polling for receive response");
118 : : ret = -1;
119 : : }
120 : :
121 : : return ret;
122 : : }
123 : :
124 : : static int
125 : 0 : cpfl_mod_rule_pack(struct cpfl_rule_info *rinfo, struct idpf_dma_mem *dma,
126 : : struct idpf_ctlq_msg *msg)
127 : : {
128 : : struct cpfl_mod_rule_info *minfo = &rinfo->mod;
129 : : union cpfl_rule_cfg_pkt_record *blob = NULL;
130 : 0 : struct cpfl_rule_cfg_data cfg = {0};
131 : :
132 : : /* prepare rule blob */
133 [ # # ]: 0 : if (!dma->va) {
134 : 0 : PMD_INIT_LOG(ERR, "dma mem passed to %s is null", __func__);
135 : 0 : return -1;
136 : : }
137 : : blob = (union cpfl_rule_cfg_pkt_record *)dma->va;
138 : : memset(blob, 0, sizeof(*blob));
139 : : memset(&cfg, 0, sizeof(cfg));
140 : :
141 : : /* fill info for both query and add/update */
142 : 0 : cpfl_fill_rule_mod_content(minfo->mod_obj_size,
143 : 0 : minfo->pin_mod_content,
144 : : minfo->mod_index,
145 : : &cfg.ext.mod_content);
146 : :
147 : : /* only fill content for add/update */
148 : 0 : memcpy(blob->mod_blob, minfo->mod_content,
149 : 0 : minfo->mod_content_byte_len);
150 : :
151 : : #define NO_HOST_NEEDED 0
152 : : /* pack message */
153 : 0 : cpfl_fill_rule_cfg_data_common(cpfl_ctlq_mod_add_update_rule,
154 : : rinfo->cookie,
155 : : 0, /* vsi_id not used for mod */
156 : 0 : rinfo->port_num,
157 : : NO_HOST_NEEDED,
158 : : 0, /* time_sel */
159 : : 0, /* time_sel_val */
160 : : 0, /* cache_wr_thru */
161 : 0 : rinfo->resp_req,
162 : : (u16)sizeof(*blob),
163 : : (void *)dma,
164 : : &cfg.common);
165 : 0 : cpfl_prep_rule_desc(&cfg, msg);
166 : 0 : return 0;
167 : : }
168 : :
169 : : static int
170 : 0 : cpfl_default_rule_pack(struct cpfl_rule_info *rinfo, struct idpf_dma_mem *dma,
171 : : struct idpf_ctlq_msg *msg, bool add)
172 : : {
173 : : union cpfl_rule_cfg_pkt_record *blob = NULL;
174 : : enum cpfl_ctlq_rule_cfg_opc opc;
175 : 0 : struct cpfl_rule_cfg_data cfg = {0};
176 : : uint16_t cfg_ctrl;
177 : :
178 [ # # ]: 0 : if (!dma->va) {
179 : 0 : PMD_INIT_LOG(ERR, "dma mem passed to %s is null", __func__);
180 : 0 : return -1;
181 : : }
182 : : blob = (union cpfl_rule_cfg_pkt_record *)dma->va;
183 : : memset(blob, 0, sizeof(*blob));
184 : : memset(msg, 0, sizeof(*msg));
185 : :
186 [ # # ]: 0 : if (rinfo->type == CPFL_RULE_TYPE_SEM) {
187 : 0 : cfg_ctrl = CPFL_GET_MEV_SEM_RULE_CFG_CTRL(rinfo->sem.prof_id,
188 : : rinfo->sem.sub_prof_id,
189 : : rinfo->sem.pin_to_cache,
190 : : rinfo->sem.fixed_fetch);
191 : 0 : cpfl_prep_sem_rule_blob(rinfo->sem.key, rinfo->sem.key_byte_len,
192 : 0 : rinfo->act_bytes, rinfo->act_byte_len,
193 : : cfg_ctrl, blob);
194 [ # # ]: 0 : opc = add ? cpfl_ctlq_sem_add_rule : cpfl_ctlq_sem_del_rule;
195 : : } else {
196 : 0 : PMD_INIT_LOG(ERR, "not support %d rule.", rinfo->type);
197 : 0 : return -1;
198 : : }
199 : :
200 : 0 : cpfl_fill_rule_cfg_data_common(opc,
201 : : rinfo->cookie,
202 : 0 : rinfo->vsi,
203 : 0 : rinfo->port_num,
204 : 0 : rinfo->host_id,
205 : : 0, /* time_sel */
206 : : 0, /* time_sel_val */
207 : : 0, /* cache_wr_thru */
208 : 0 : rinfo->resp_req,
209 : : sizeof(union cpfl_rule_cfg_pkt_record),
210 : : dma,
211 : : &cfg.common);
212 : 0 : cpfl_prep_rule_desc(&cfg, msg);
213 : 0 : return 0;
214 : : }
215 : :
216 : : static int
217 : 0 : cpfl_rule_pack(struct cpfl_rule_info *rinfo, struct idpf_dma_mem *dma,
218 : : struct idpf_ctlq_msg *msg, bool add)
219 : : {
220 : : int ret = 0;
221 : :
222 [ # # ]: 0 : if (rinfo->type == CPFL_RULE_TYPE_SEM) {
223 [ # # ]: 0 : if (cpfl_default_rule_pack(rinfo, dma, msg, add) < 0)
224 : : ret = -1;
225 [ # # ]: 0 : } else if (rinfo->type == CPFL_RULE_TYPE_MOD) {
226 [ # # ]: 0 : if (cpfl_mod_rule_pack(rinfo, dma, msg) < 0)
227 : : ret = -1;
228 : : } else {
229 : 0 : PMD_INIT_LOG(ERR, "Invalid type of rule");
230 : : ret = -1;
231 : : }
232 : :
233 : 0 : return ret;
234 : : }
235 : :
236 : : int
237 : 0 : cpfl_rule_process(struct cpfl_itf *itf,
238 : : struct idpf_ctlq_info *tx_cq,
239 : : struct idpf_ctlq_info *rx_cq,
240 : : struct cpfl_rule_info *rinfo,
241 : : int rule_num,
242 : : bool add)
243 : : {
244 : 0 : struct idpf_hw *hw = &itf->adapter->base.hw;
245 : : int i;
246 : : int ret = 0;
247 : :
248 [ # # ]: 0 : if (rule_num == 0)
249 : : return 0;
250 : :
251 [ # # ]: 0 : for (i = 0; i < rule_num; i++) {
252 : 0 : ret = cpfl_rule_pack(&rinfo[i], &itf->dma[i], &itf->msg[i], add);
253 [ # # ]: 0 : if (ret) {
254 : 0 : PMD_INIT_LOG(ERR, "Could not pack rule");
255 : 0 : return ret;
256 : : }
257 : : }
258 : 0 : ret = cpfl_send_ctlq_msg(hw, tx_cq, rule_num, itf->msg);
259 [ # # ]: 0 : if (ret) {
260 : 0 : PMD_INIT_LOG(ERR, "Failed to send control message");
261 : 0 : return ret;
262 : : }
263 : 0 : ret = cpfl_receive_ctlq_msg(hw, rx_cq, rule_num, itf->msg);
264 [ # # ]: 0 : if (ret) {
265 : 0 : PMD_INIT_LOG(ERR, "Failed to update rule");
266 : 0 : return ret;
267 : : }
268 : :
269 : : return 0;
270 : : }
|