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\n", 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 : if (q_msg[i].data_len > 0)
96 : 0 : dma = q_msg[i].ctx.indirect.payload;
97 : : else
98 : 0 : dma = NULL;
99 : :
100 : 0 : buff_cnt = dma ? 1 : 0;
101 : 0 : ret = cpfl_vport_ctlq_post_rx_buffs(hw, cq, &buff_cnt, &dma);
102 [ # # ]: 0 : if (ret)
103 : 0 : PMD_INIT_LOG(WARNING, "could not posted recv bufs\n");
104 : : }
105 : : break;
106 : : }
107 : :
108 [ # # ]: 0 : if (retries > CTLQ_RECEIVE_RETRIES) {
109 : 0 : PMD_INIT_LOG(ERR, "timed out while polling for receive response");
110 : : ret = -1;
111 : : }
112 : :
113 : 0 : return ret;
114 : : }
115 : :
116 : : static int
117 : 0 : cpfl_mod_rule_pack(struct cpfl_rule_info *rinfo, struct idpf_dma_mem *dma,
118 : : struct idpf_ctlq_msg *msg)
119 : : {
120 : : struct cpfl_mod_rule_info *minfo = &rinfo->mod;
121 : : union cpfl_rule_cfg_pkt_record *blob = NULL;
122 : 0 : struct cpfl_rule_cfg_data cfg = {0};
123 : :
124 : : /* prepare rule blob */
125 [ # # ]: 0 : if (!dma->va) {
126 : 0 : PMD_INIT_LOG(ERR, "dma mem passed to %s is null\n", __func__);
127 : 0 : return -1;
128 : : }
129 : : blob = (union cpfl_rule_cfg_pkt_record *)dma->va;
130 : : memset(blob, 0, sizeof(*blob));
131 : : memset(&cfg, 0, sizeof(cfg));
132 : :
133 : : /* fill info for both query and add/update */
134 : 0 : cpfl_fill_rule_mod_content(minfo->mod_obj_size,
135 : 0 : minfo->pin_mod_content,
136 : : minfo->mod_index,
137 : : &cfg.ext.mod_content);
138 : :
139 : : /* only fill content for add/update */
140 : 0 : memcpy(blob->mod_blob, minfo->mod_content,
141 : 0 : minfo->mod_content_byte_len);
142 : :
143 : : #define NO_HOST_NEEDED 0
144 : : /* pack message */
145 : 0 : cpfl_fill_rule_cfg_data_common(cpfl_ctlq_mod_add_update_rule,
146 : : rinfo->cookie,
147 : : 0, /* vsi_id not used for mod */
148 : 0 : rinfo->port_num,
149 : : NO_HOST_NEEDED,
150 : : 0, /* time_sel */
151 : : 0, /* time_sel_val */
152 : : 0, /* cache_wr_thru */
153 : 0 : rinfo->resp_req,
154 : : (u16)sizeof(*blob),
155 : : (void *)dma,
156 : : &cfg.common);
157 : 0 : cpfl_prep_rule_desc(&cfg, msg);
158 : 0 : return 0;
159 : : }
160 : :
161 : : static int
162 : 0 : cpfl_default_rule_pack(struct cpfl_rule_info *rinfo, struct idpf_dma_mem *dma,
163 : : struct idpf_ctlq_msg *msg, bool add)
164 : : {
165 : : union cpfl_rule_cfg_pkt_record *blob = NULL;
166 : : enum cpfl_ctlq_rule_cfg_opc opc;
167 : 0 : struct cpfl_rule_cfg_data cfg = {0};
168 : : uint16_t cfg_ctrl;
169 : :
170 [ # # ]: 0 : if (!dma->va) {
171 : 0 : PMD_INIT_LOG(ERR, "dma mem passed to %s is null\n", __func__);
172 : 0 : return -1;
173 : : }
174 : : blob = (union cpfl_rule_cfg_pkt_record *)dma->va;
175 : : memset(blob, 0, sizeof(*blob));
176 : : memset(msg, 0, sizeof(*msg));
177 : :
178 [ # # ]: 0 : if (rinfo->type == CPFL_RULE_TYPE_SEM) {
179 : 0 : cfg_ctrl = CPFL_GET_MEV_SEM_RULE_CFG_CTRL(rinfo->sem.prof_id,
180 : : rinfo->sem.sub_prof_id,
181 : : rinfo->sem.pin_to_cache,
182 : : rinfo->sem.fixed_fetch);
183 : 0 : cpfl_prep_sem_rule_blob(rinfo->sem.key, rinfo->sem.key_byte_len,
184 : 0 : rinfo->act_bytes, rinfo->act_byte_len,
185 : : cfg_ctrl, blob);
186 [ # # ]: 0 : opc = add ? cpfl_ctlq_sem_add_rule : cpfl_ctlq_sem_del_rule;
187 : : } else {
188 : 0 : PMD_INIT_LOG(ERR, "not support %d rule.", rinfo->type);
189 : 0 : return -1;
190 : : }
191 : :
192 : 0 : cpfl_fill_rule_cfg_data_common(opc,
193 : : rinfo->cookie,
194 : 0 : rinfo->vsi,
195 : 0 : rinfo->port_num,
196 : 0 : rinfo->host_id,
197 : : 0, /* time_sel */
198 : : 0, /* time_sel_val */
199 : : 0, /* cache_wr_thru */
200 : 0 : rinfo->resp_req,
201 : : sizeof(union cpfl_rule_cfg_pkt_record),
202 : : dma,
203 : : &cfg.common);
204 : 0 : cpfl_prep_rule_desc(&cfg, msg);
205 : 0 : return 0;
206 : : }
207 : :
208 : : static int
209 : 0 : cpfl_rule_pack(struct cpfl_rule_info *rinfo, struct idpf_dma_mem *dma,
210 : : struct idpf_ctlq_msg *msg, bool add)
211 : : {
212 : : int ret = 0;
213 : :
214 [ # # ]: 0 : if (rinfo->type == CPFL_RULE_TYPE_SEM) {
215 [ # # ]: 0 : if (cpfl_default_rule_pack(rinfo, dma, msg, add) < 0)
216 : : ret = -1;
217 [ # # ]: 0 : } else if (rinfo->type == CPFL_RULE_TYPE_MOD) {
218 [ # # ]: 0 : if (cpfl_mod_rule_pack(rinfo, dma, msg) < 0)
219 : : ret = -1;
220 : : } else {
221 : 0 : PMD_INIT_LOG(ERR, "Invalid type of rule");
222 : : ret = -1;
223 : : }
224 : :
225 : 0 : return ret;
226 : : }
227 : :
228 : : int
229 : 0 : cpfl_rule_process(struct cpfl_itf *itf,
230 : : struct idpf_ctlq_info *tx_cq,
231 : : struct idpf_ctlq_info *rx_cq,
232 : : struct cpfl_rule_info *rinfo,
233 : : int rule_num,
234 : : bool add)
235 : : {
236 : 0 : struct idpf_hw *hw = &itf->adapter->base.hw;
237 : : int i;
238 : : int ret = 0;
239 : :
240 [ # # ]: 0 : if (rule_num == 0)
241 : : return 0;
242 : :
243 [ # # ]: 0 : for (i = 0; i < rule_num; i++) {
244 : 0 : ret = cpfl_rule_pack(&rinfo[i], &itf->dma[i], &itf->msg[i], add);
245 [ # # ]: 0 : if (ret) {
246 : 0 : PMD_INIT_LOG(ERR, "Could not pack rule");
247 : 0 : return ret;
248 : : }
249 : : }
250 : 0 : ret = cpfl_send_ctlq_msg(hw, tx_cq, rule_num, itf->msg);
251 [ # # ]: 0 : if (ret) {
252 : 0 : PMD_INIT_LOG(ERR, "Failed to send control message");
253 : 0 : return ret;
254 : : }
255 : 0 : ret = cpfl_receive_ctlq_msg(hw, rx_cq, rule_num, itf->msg);
256 [ # # ]: 0 : if (ret) {
257 : 0 : PMD_INIT_LOG(ERR, "Failed to update rule");
258 : 0 : return ret;
259 : : }
260 : :
261 : : return 0;
262 : : }
|