Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2023 Marvell.
3 : : */
4 : :
5 : : #include "roc_api.h"
6 : : #include "roc_priv.h"
7 : :
8 : : struct mcs_event_cb {
9 : : TAILQ_ENTRY(mcs_event_cb) next;
10 : : enum roc_mcs_event_type event;
11 : : roc_mcs_dev_cb_fn cb_fn;
12 : : void *cb_arg;
13 : : void *userdata;
14 : : void *ret_param;
15 : : uint32_t active;
16 : : };
17 : : TAILQ_HEAD(mcs_event_cb_list, mcs_event_cb);
18 : :
19 : : PLT_STATIC_ASSERT(ROC_MCS_MEM_SZ >= (sizeof(struct mcs_priv) + sizeof(struct mcs_event_cb_list)));
20 : :
21 : : int
22 [ # # ]: 0 : roc_mcs_hw_info_get(struct roc_mcs_hw_info *hw_info)
23 : : {
24 : : struct mcs_hw_info *hw;
25 : : struct npa_lf *npa;
26 : : int rc;
27 : :
28 [ # # # # ]: 0 : MCS_SUPPORT_CHECK;
29 : :
30 [ # # ]: 0 : if (hw_info == NULL)
31 : : return -EINVAL;
32 : :
33 : : /* Use mbox handler of first probed pci_func for
34 : : * initial mcs mbox communication.
35 : : */
36 : 0 : npa = idev_npa_obj_get();
37 [ # # ]: 0 : if (!npa)
38 : : return MCS_ERR_DEVICE_NOT_FOUND;
39 : :
40 : 0 : mbox_alloc_msg_mcs_get_hw_info(npa->mbox);
41 : 0 : rc = mbox_process_msg(npa->mbox, (void *)&hw);
42 [ # # ]: 0 : if (rc)
43 : : return rc;
44 : :
45 : 0 : hw_info->num_mcs_blks = hw->num_mcs_blks;
46 : 0 : hw_info->tcam_entries = hw->tcam_entries;
47 : 0 : hw_info->secy_entries = hw->secy_entries;
48 : 0 : hw_info->sc_entries = hw->sc_entries;
49 : 0 : hw_info->sa_entries = hw->sa_entries;
50 : :
51 : 0 : return rc;
52 : : }
53 : :
54 : : int
55 [ # # ]: 0 : roc_mcs_active_lmac_set(struct roc_mcs *mcs, struct roc_mcs_set_active_lmac *lmac)
56 : : {
57 : : struct mcs_set_active_lmac *req;
58 : : struct msg_rsp *rsp;
59 : :
60 : : /* Only needed for 105N */
61 [ # # ]: 0 : if (!roc_model_is_cnf10kb())
62 : : return 0;
63 : :
64 [ # # ]: 0 : if (lmac == NULL)
65 : : return -EINVAL;
66 : :
67 : : MCS_SUPPORT_CHECK;
68 : :
69 : 0 : req = mbox_alloc_msg_mcs_set_active_lmac(mcs->mbox);
70 [ # # ]: 0 : if (req == NULL)
71 : : return -ENOMEM;
72 : :
73 : 0 : req->lmac_bmap = lmac->lmac_bmap;
74 : 0 : req->channel_base = lmac->channel_base;
75 : 0 : req->mcs_id = mcs->idx;
76 : :
77 : 0 : return mbox_process_msg(mcs->mbox, (void *)&rsp);
78 : : }
79 : :
80 : : static int
81 [ # # ]: 0 : mcs_port_reset_set(struct roc_mcs *mcs, struct roc_mcs_port_reset_req *port, uint8_t reset)
82 : : {
83 : : struct mcs_port_reset_req *req;
84 : : struct msg_rsp *rsp;
85 : :
86 [ # # # # ]: 0 : MCS_SUPPORT_CHECK;
87 : :
88 : 0 : req = mbox_alloc_msg_mcs_port_reset(mcs->mbox);
89 [ # # ]: 0 : if (req == NULL)
90 : : return -ENOMEM;
91 : :
92 : 0 : req->reset = reset;
93 : 0 : req->lmac_id = port->port_id;
94 : 0 : req->mcs_id = mcs->idx;
95 : :
96 : 0 : return mbox_process_msg(mcs->mbox, (void *)&rsp);
97 : : }
98 : :
99 : : int
100 : 0 : roc_mcs_lmac_mode_set(struct roc_mcs *mcs, struct roc_mcs_set_lmac_mode *port)
101 : : {
102 : : struct mcs_set_lmac_mode *req;
103 : : struct msg_rsp *rsp;
104 : :
105 [ # # ]: 0 : if (port == NULL)
106 : : return -EINVAL;
107 : :
108 [ # # # # ]: 0 : MCS_SUPPORT_CHECK;
109 : :
110 : 0 : req = mbox_alloc_msg_mcs_set_lmac_mode(mcs->mbox);
111 [ # # ]: 0 : if (req == NULL)
112 : : return -ENOMEM;
113 : :
114 : 0 : req->lmac_id = port->lmac_id;
115 : 0 : req->mcs_id = mcs->idx;
116 : 0 : req->mode = port->mode;
117 : :
118 : 0 : return mbox_process_msg(mcs->mbox, (void *)&rsp);
119 : : }
120 : :
121 : : int
122 : 0 : roc_mcs_pn_threshold_set(struct roc_mcs *mcs, struct roc_mcs_set_pn_threshold *pn)
123 : : {
124 : : struct mcs_set_pn_threshold *req;
125 : : struct msg_rsp *rsp;
126 : :
127 [ # # ]: 0 : if (pn == NULL)
128 : : return -EINVAL;
129 : :
130 [ # # # # ]: 0 : MCS_SUPPORT_CHECK;
131 : :
132 : 0 : req = mbox_alloc_msg_mcs_set_pn_threshold(mcs->mbox);
133 [ # # ]: 0 : if (req == NULL)
134 : : return -ENOMEM;
135 : :
136 : 0 : req->threshold = pn->threshold;
137 : 0 : req->mcs_id = mcs->idx;
138 : 0 : req->dir = pn->dir;
139 : 0 : req->xpn = pn->xpn;
140 : :
141 : 0 : return mbox_process_msg(mcs->mbox, (void *)&rsp);
142 : : }
143 : :
144 : : int
145 [ # # ]: 0 : roc_mcs_ctrl_pkt_rule_alloc(struct roc_mcs *mcs, struct roc_mcs_alloc_ctrl_pkt_rule_req *req,
146 : : struct roc_mcs_alloc_ctrl_pkt_rule_rsp *rsp)
147 : : {
148 : : struct mcs_alloc_ctrl_pkt_rule_req *rule_req;
149 : : struct mcs_alloc_ctrl_pkt_rule_rsp *rule_rsp;
150 : : int rc;
151 : :
152 [ # # # # ]: 0 : MCS_SUPPORT_CHECK;
153 : :
154 [ # # ]: 0 : if (req == NULL || rsp == NULL)
155 : : return -EINVAL;
156 : :
157 : 0 : rule_req = mbox_alloc_msg_mcs_alloc_ctrl_pkt_rule(mcs->mbox);
158 [ # # ]: 0 : if (rule_req == NULL)
159 : : return -ENOMEM;
160 : :
161 : 0 : rule_req->rule_type = req->rule_type;
162 : 0 : rule_req->mcs_id = mcs->idx;
163 : 0 : rule_req->dir = req->dir;
164 : :
165 : 0 : rc = mbox_process_msg(mcs->mbox, (void *)&rule_rsp);
166 [ # # ]: 0 : if (rc)
167 : : return rc;
168 : :
169 : 0 : rsp->rule_type = rule_rsp->rule_type;
170 : 0 : rsp->rule_idx = rule_rsp->rule_idx;
171 : 0 : rsp->dir = rule_rsp->dir;
172 : :
173 : 0 : return 0;
174 : : }
175 : :
176 : : int
177 [ # # ]: 0 : roc_mcs_ctrl_pkt_rule_free(struct roc_mcs *mcs, struct roc_mcs_free_ctrl_pkt_rule_req *req)
178 : : {
179 : : struct mcs_free_ctrl_pkt_rule_req *rule_req;
180 : : struct msg_rsp *rsp;
181 : :
182 [ # # # # ]: 0 : MCS_SUPPORT_CHECK;
183 : :
184 [ # # ]: 0 : if (req == NULL)
185 : : return -EINVAL;
186 : :
187 : 0 : rule_req = mbox_alloc_msg_mcs_free_ctrl_pkt_rule(mcs->mbox);
188 [ # # ]: 0 : if (rule_req == NULL)
189 : : return -ENOMEM;
190 : :
191 : 0 : rule_req->rule_type = req->rule_type;
192 : 0 : rule_req->rule_idx = req->rule_idx;
193 : 0 : rule_req->mcs_id = mcs->idx;
194 : 0 : rule_req->dir = req->dir;
195 : 0 : rule_req->all = req->all;
196 : :
197 : 0 : return mbox_process_msg(mcs->mbox, (void *)&rsp);
198 : : }
199 : :
200 : : int
201 [ # # ]: 0 : roc_mcs_ctrl_pkt_rule_write(struct roc_mcs *mcs, struct roc_mcs_ctrl_pkt_rule_write_req *req)
202 : : {
203 : : struct mcs_ctrl_pkt_rule_write_req *rule_req;
204 : : struct msg_rsp *rsp;
205 : :
206 [ # # # # ]: 0 : MCS_SUPPORT_CHECK;
207 : :
208 [ # # ]: 0 : if (req == NULL)
209 : : return -EINVAL;
210 : :
211 : 0 : rule_req = mbox_alloc_msg_mcs_ctrl_pkt_rule_write(mcs->mbox);
212 [ # # ]: 0 : if (rule_req == NULL)
213 : : return -ENOMEM;
214 : :
215 : 0 : rule_req->rule_type = req->rule_type;
216 : 0 : rule_req->rule_idx = req->rule_idx;
217 : 0 : rule_req->mcs_id = mcs->idx;
218 : 0 : rule_req->dir = req->dir;
219 : 0 : rule_req->data0 = req->data0;
220 : 0 : rule_req->data1 = req->data1;
221 : 0 : rule_req->data2 = req->data2;
222 : :
223 : 0 : return mbox_process_msg(mcs->mbox, (void *)&rsp);
224 : : }
225 : :
226 : : int
227 [ # # ]: 0 : roc_mcs_port_cfg_set(struct roc_mcs *mcs, struct roc_mcs_port_cfg_set_req *req)
228 : : {
229 : : struct mcs_port_cfg_set_req *set_req;
230 : : struct msg_rsp *rsp;
231 : :
232 [ # # # # ]: 0 : MCS_SUPPORT_CHECK;
233 : :
234 [ # # ]: 0 : if (req == NULL)
235 : : return -EINVAL;
236 : :
237 : 0 : set_req = mbox_alloc_msg_mcs_port_cfg_set(mcs->mbox);
238 [ # # ]: 0 : if (set_req == NULL)
239 : : return -ENOMEM;
240 : :
241 : 0 : set_req->cstm_tag_rel_mode_sel = req->cstm_tag_rel_mode_sel;
242 : 0 : set_req->custom_hdr_enb = req->custom_hdr_enb;
243 : 0 : set_req->fifo_skid = req->fifo_skid;
244 : 0 : set_req->lmac_mode = req->port_mode;
245 : 0 : set_req->lmac_id = req->port_id;
246 : 0 : set_req->mcs_id = mcs->idx;
247 : :
248 : 0 : return mbox_process_msg(mcs->mbox, (void *)&rsp);
249 : : }
250 : :
251 : : int
252 [ # # ]: 0 : roc_mcs_port_cfg_get(struct roc_mcs *mcs, struct roc_mcs_port_cfg_get_req *req,
253 : : struct roc_mcs_port_cfg_get_rsp *rsp)
254 : : {
255 : : struct mcs_port_cfg_get_req *get_req;
256 : : struct mcs_port_cfg_get_rsp *get_rsp;
257 : : int rc;
258 : :
259 [ # # # # ]: 0 : MCS_SUPPORT_CHECK;
260 : :
261 [ # # ]: 0 : if (req == NULL)
262 : : return -EINVAL;
263 : :
264 : 0 : get_req = mbox_alloc_msg_mcs_port_cfg_get(mcs->mbox);
265 [ # # ]: 0 : if (get_req == NULL)
266 : : return -ENOMEM;
267 : :
268 : 0 : get_req->lmac_id = req->port_id;
269 : 0 : get_req->mcs_id = mcs->idx;
270 : :
271 : 0 : rc = mbox_process_msg(mcs->mbox, (void *)&get_rsp);
272 [ # # ]: 0 : if (rc)
273 : : return rc;
274 : :
275 : 0 : rsp->cstm_tag_rel_mode_sel = get_rsp->cstm_tag_rel_mode_sel;
276 : 0 : rsp->custom_hdr_enb = get_rsp->custom_hdr_enb;
277 : 0 : rsp->fifo_skid = get_rsp->fifo_skid;
278 : 0 : rsp->port_mode = get_rsp->lmac_mode;
279 : 0 : rsp->port_id = get_rsp->lmac_id;
280 : :
281 : 0 : return 0;
282 : : }
283 : :
284 : : int
285 [ # # ]: 0 : roc_mcs_custom_tag_cfg_get(struct roc_mcs *mcs, struct roc_mcs_custom_tag_cfg_get_req *req,
286 : : struct roc_mcs_custom_tag_cfg_get_rsp *rsp)
287 : : {
288 : : struct mcs_custom_tag_cfg_get_req *get_req;
289 : : struct mcs_custom_tag_cfg_get_rsp *get_rsp;
290 : : int i, rc;
291 : :
292 [ # # # # ]: 0 : MCS_SUPPORT_CHECK;
293 : :
294 [ # # ]: 0 : if (req == NULL)
295 : : return -EINVAL;
296 : :
297 : 0 : get_req = mbox_alloc_msg_mcs_custom_tag_cfg_get(mcs->mbox);
298 [ # # ]: 0 : if (get_req == NULL)
299 : : return -ENOMEM;
300 : :
301 : 0 : get_req->dir = req->dir;
302 : 0 : get_req->mcs_id = mcs->idx;
303 : :
304 : 0 : rc = mbox_process_msg(mcs->mbox, (void *)&get_rsp);
305 [ # # ]: 0 : if (rc)
306 : : return rc;
307 : :
308 [ # # ]: 0 : for (i = 0; i < 8; i++) {
309 : 0 : rsp->cstm_etype[i] = get_rsp->cstm_etype[i];
310 : 0 : rsp->cstm_indx[i] = get_rsp->cstm_indx[i];
311 : : }
312 : :
313 : 0 : rsp->cstm_etype_en = get_rsp->cstm_etype_en;
314 : 0 : rsp->dir = get_rsp->dir;
315 : :
316 : 0 : return 0;
317 : : }
318 : :
319 : : int
320 : 0 : roc_mcs_intr_configure(struct roc_mcs *mcs, struct roc_mcs_intr_cfg *config)
321 : : {
322 : : struct mcs_intr_cfg *req;
323 : : struct msg_rsp *rsp;
324 : : int rc;
325 : :
326 [ # # ]: 0 : if (config == NULL)
327 : : return -EINVAL;
328 : :
329 [ # # # # ]: 0 : MCS_SUPPORT_CHECK;
330 : :
331 [ # # ]: 0 : if (mcs->intr_cfg_once)
332 : : return 0;
333 : :
334 : 0 : req = mbox_alloc_msg_mcs_intr_cfg(mcs->mbox);
335 [ # # ]: 0 : if (req == NULL)
336 : : return -ENOMEM;
337 : :
338 : 0 : req->intr_mask = config->intr_mask;
339 : 0 : req->mcs_id = mcs->idx;
340 : :
341 : 0 : rc = mbox_process_msg(mcs->mbox, (void *)&rsp);
342 [ # # ]: 0 : if (rc == 0)
343 : 0 : mcs->intr_cfg_once = true;
344 : :
345 : : return rc;
346 : : }
347 : :
348 : : int
349 : 0 : roc_mcs_port_recovery(struct roc_mcs *mcs, union roc_mcs_event_data *mdata, uint8_t port_id)
350 : : {
351 : : struct mcs_priv *priv = roc_mcs_to_mcs_priv(mcs);
352 : 0 : struct roc_mcs_pn_table_write_req pn_table = {0};
353 : 0 : struct roc_mcs_rx_sc_sa_map rx_map = {0};
354 : 0 : struct roc_mcs_tx_sc_sa_map tx_map = {0};
355 : 0 : struct roc_mcs_port_reset_req port = {0};
356 : 0 : struct roc_mcs_clear_stats stats = {0};
357 : : int tx_cnt = 0, rx_cnt = 0, rc = 0;
358 : : uint64_t set;
359 : : int i;
360 : :
361 : 0 : port.port_id = port_id;
362 : 0 : rc = mcs_port_reset_set(mcs, &port, 1);
363 : :
364 : : /* Reset TX/RX PN tables */
365 [ # # ]: 0 : for (i = 0; i < (priv->sa_entries << 1); i++) {
366 [ # # ]: 0 : set = plt_bitmap_get(priv->port_rsrc[port_id].sa_bmap, i);
367 [ # # ]: 0 : if (set) {
368 : 0 : pn_table.pn_id = i;
369 : 0 : pn_table.next_pn = 1;
370 : 0 : pn_table.dir = MCS_RX;
371 [ # # ]: 0 : if (i >= priv->sa_entries) {
372 : 0 : pn_table.dir = MCS_TX;
373 : 0 : pn_table.pn_id -= priv->sa_entries;
374 : : }
375 : 0 : rc = roc_mcs_pn_table_write(mcs, &pn_table);
376 [ # # ]: 0 : if (rc)
377 : 0 : return rc;
378 : :
379 [ # # ]: 0 : if (i >= priv->sa_entries)
380 : 0 : tx_cnt++;
381 : : else
382 : 0 : rx_cnt++;
383 : : }
384 : : }
385 : :
386 [ # # ]: 0 : if (tx_cnt || rx_cnt) {
387 : 0 : mdata->tx_sa_array = plt_zmalloc(tx_cnt * sizeof(uint16_t), 0);
388 [ # # # # ]: 0 : if (tx_cnt && (mdata->tx_sa_array == NULL)) {
389 : : rc = -ENOMEM;
390 : 0 : goto exit;
391 : : }
392 : 0 : mdata->rx_sa_array = plt_zmalloc(rx_cnt * sizeof(uint16_t), 0);
393 [ # # # # ]: 0 : if (rx_cnt && (mdata->rx_sa_array == NULL)) {
394 : : rc = -ENOMEM;
395 : 0 : goto exit;
396 : : }
397 : :
398 : 0 : mdata->num_tx_sa = tx_cnt;
399 : 0 : mdata->num_rx_sa = rx_cnt;
400 [ # # ]: 0 : for (i = 0; i < (priv->sa_entries << 1); i++) {
401 [ # # ]: 0 : set = plt_bitmap_get(priv->port_rsrc[port_id].sa_bmap, i);
402 [ # # ]: 0 : if (set) {
403 [ # # ]: 0 : if (i >= priv->sa_entries)
404 : 0 : mdata->tx_sa_array[--tx_cnt] = i - priv->sa_entries;
405 : : else
406 : 0 : mdata->rx_sa_array[--rx_cnt] = i;
407 : : }
408 : : }
409 : : }
410 : : tx_cnt = 0;
411 : : rx_cnt = 0;
412 : :
413 : : /* Reset Tx active SA to index:0 */
414 [ # # ]: 0 : for (i = priv->sc_entries; i < (priv->sc_entries << 1); i++) {
415 [ # # ]: 0 : set = plt_bitmap_get(priv->port_rsrc[port_id].sc_bmap, i);
416 [ # # ]: 0 : if (set) {
417 : 0 : uint16_t sc_id = i - priv->sc_entries;
418 : :
419 : 0 : tx_map.sa_index0 = priv->port_rsrc[port_id].sc_conf[sc_id].tx.sa_idx0;
420 : 0 : tx_map.sa_index1 = priv->port_rsrc[port_id].sc_conf[sc_id].tx.sa_idx1;
421 : 0 : tx_map.rekey_ena = priv->port_rsrc[port_id].sc_conf[sc_id].tx.rekey_enb;
422 : 0 : tx_map.sectag_sci = priv->port_rsrc[port_id].sc_conf[sc_id].tx.sci;
423 : 0 : tx_map.sa_index0_vld = 1;
424 : 0 : tx_map.sa_index1_vld = 0;
425 : 0 : tx_map.tx_sa_active = 0;
426 : 0 : tx_map.sc_id = sc_id;
427 : 0 : rc = roc_mcs_tx_sc_sa_map_write(mcs, &tx_map);
428 [ # # ]: 0 : if (rc)
429 : 0 : return rc;
430 : :
431 : 0 : tx_cnt++;
432 : : }
433 : : }
434 : :
435 [ # # ]: 0 : if (tx_cnt) {
436 : 0 : mdata->tx_sc_array = plt_zmalloc(tx_cnt * sizeof(uint16_t), 0);
437 [ # # ]: 0 : if (tx_cnt && (mdata->tx_sc_array == NULL)) {
438 : : rc = -ENOMEM;
439 : 0 : goto exit;
440 : : }
441 : :
442 : 0 : mdata->num_tx_sc = tx_cnt;
443 [ # # ]: 0 : for (i = priv->sc_entries; i < (priv->sc_entries << 1); i++) {
444 [ # # ]: 0 : set = plt_bitmap_get(priv->port_rsrc[port_id].sc_bmap, i);
445 [ # # ]: 0 : if (set)
446 : 0 : mdata->tx_sc_array[--tx_cnt] = i - priv->sc_entries;
447 : : }
448 : : }
449 : :
450 : : /* Clear SA_IN_USE for active ANs in RX CPM */
451 [ # # ]: 0 : for (i = 0; i < priv->sc_entries; i++) {
452 [ # # ]: 0 : set = plt_bitmap_get(priv->port_rsrc[port_id].sc_bmap, i);
453 [ # # ]: 0 : if (set) {
454 : 0 : rx_map.sa_index = priv->port_rsrc[port_id].sc_conf[i].rx.sa_idx;
455 : 0 : rx_map.an = priv->port_rsrc[port_id].sc_conf[i].rx.an;
456 : 0 : rx_map.sa_in_use = 0;
457 : 0 : rx_map.sc_id = i;
458 : 0 : rc = roc_mcs_rx_sc_sa_map_write(mcs, &rx_map);
459 [ # # ]: 0 : if (rc)
460 : 0 : return rc;
461 : :
462 : 0 : rx_cnt++;
463 : : }
464 : : }
465 : :
466 : : /* Reset flow(flow/secy/sc/sa) stats mapped to this PORT */
467 [ # # ]: 0 : for (i = 0; i < (priv->tcam_entries << 1); i++) {
468 [ # # ]: 0 : set = plt_bitmap_get(priv->port_rsrc[port_id].tcam_bmap, i);
469 [ # # ]: 0 : if (set) {
470 : 0 : stats.type = MCS_FLOWID_STATS;
471 : 0 : stats.id = i;
472 : 0 : stats.dir = MCS_RX;
473 [ # # ]: 0 : if (i >= priv->sa_entries) {
474 : 0 : stats.dir = MCS_TX;
475 : 0 : stats.id -= priv->tcam_entries;
476 : : }
477 : 0 : rc = roc_mcs_stats_clear(mcs, &stats);
478 [ # # ]: 0 : if (rc)
479 : 0 : return rc;
480 : : }
481 : : }
482 [ # # ]: 0 : for (i = 0; i < (priv->secy_entries << 1); i++) {
483 [ # # ]: 0 : set = plt_bitmap_get(priv->port_rsrc[port_id].secy_bmap, i);
484 [ # # ]: 0 : if (set) {
485 : 0 : stats.type = MCS_SECY_STATS;
486 : 0 : stats.id = i;
487 : 0 : stats.dir = MCS_RX;
488 [ # # ]: 0 : if (i >= priv->sa_entries) {
489 : 0 : stats.dir = MCS_TX;
490 : 0 : stats.id -= priv->secy_entries;
491 : : }
492 : 0 : rc = roc_mcs_stats_clear(mcs, &stats);
493 [ # # ]: 0 : if (rc)
494 : 0 : return rc;
495 : : }
496 : : }
497 [ # # ]: 0 : for (i = 0; i < (priv->sc_entries << 1); i++) {
498 [ # # ]: 0 : set = plt_bitmap_get(priv->port_rsrc[port_id].sc_bmap, i);
499 [ # # ]: 0 : if (set) {
500 : 0 : stats.type = MCS_SC_STATS;
501 : 0 : stats.id = i;
502 : 0 : stats.dir = MCS_RX;
503 [ # # ]: 0 : if (i >= priv->sa_entries) {
504 : 0 : stats.dir = MCS_TX;
505 : 0 : stats.id -= priv->sc_entries;
506 : : }
507 : 0 : rc = roc_mcs_stats_clear(mcs, &stats);
508 [ # # ]: 0 : if (rc)
509 : 0 : return rc;
510 : : }
511 : : }
512 [ # # ]: 0 : if (roc_model_is_cn10kb_a0()) {
513 [ # # ]: 0 : for (i = 0; i < (priv->sa_entries << 1); i++) {
514 [ # # ]: 0 : set = plt_bitmap_get(priv->port_rsrc[port_id].sa_bmap, i);
515 [ # # ]: 0 : if (set) {
516 : 0 : stats.type = MCS_SA_STATS;
517 : 0 : stats.id = i;
518 : 0 : stats.dir = MCS_RX;
519 [ # # ]: 0 : if (i >= priv->sa_entries) {
520 : 0 : stats.dir = MCS_TX;
521 : 0 : stats.id -= priv->sa_entries;
522 : : }
523 : 0 : rc = roc_mcs_stats_clear(mcs, &stats);
524 [ # # ]: 0 : if (rc)
525 : 0 : return rc;
526 : : }
527 : : }
528 : : }
529 : : {
530 : 0 : stats.type = MCS_PORT_STATS;
531 : 0 : stats.id = port_id;
532 : 0 : rc = roc_mcs_stats_clear(mcs, &stats);
533 [ # # ]: 0 : if (rc)
534 : : return rc;
535 : : }
536 : :
537 [ # # ]: 0 : if (rx_cnt) {
538 : 0 : mdata->rx_sc_array = plt_zmalloc(rx_cnt * sizeof(uint16_t), 0);
539 [ # # ]: 0 : if (mdata->rx_sc_array == NULL) {
540 : : rc = -ENOMEM;
541 : 0 : goto exit;
542 : : }
543 : 0 : mdata->sc_an_array = plt_zmalloc(rx_cnt * sizeof(uint8_t), 0);
544 [ # # ]: 0 : if (mdata->sc_an_array == NULL) {
545 : : rc = -ENOMEM;
546 : 0 : goto exit;
547 : : }
548 : :
549 : 0 : mdata->num_rx_sc = rx_cnt;
550 : : }
551 : :
552 : : /* Reactivate in-use ANs for active SCs in RX CPM */
553 [ # # ]: 0 : for (i = 0; i < priv->sc_entries; i++) {
554 [ # # ]: 0 : set = plt_bitmap_get(priv->port_rsrc[port_id].sc_bmap, i);
555 [ # # ]: 0 : if (set) {
556 : 0 : rx_map.sa_index = priv->port_rsrc[port_id].sc_conf[i].rx.sa_idx;
557 : 0 : rx_map.an = priv->port_rsrc[port_id].sc_conf[i].rx.an;
558 : 0 : rx_map.sa_in_use = 1;
559 : 0 : rx_map.sc_id = i;
560 : 0 : rc = roc_mcs_rx_sc_sa_map_write(mcs, &rx_map);
561 [ # # ]: 0 : if (rc)
562 : 0 : return rc;
563 : :
564 : 0 : mdata->rx_sc_array[--rx_cnt] = i;
565 : 0 : mdata->sc_an_array[rx_cnt] = priv->port_rsrc[port_id].sc_conf[i].rx.an;
566 : : }
567 : : }
568 : :
569 : 0 : port.port_id = port_id;
570 : 0 : rc = mcs_port_reset_set(mcs, &port, 0);
571 : :
572 : 0 : return rc;
573 : 0 : exit:
574 [ # # ]: 0 : if (mdata->num_tx_sa)
575 : 0 : plt_free(mdata->tx_sa_array);
576 [ # # ]: 0 : if (mdata->num_rx_sa)
577 : 0 : plt_free(mdata->rx_sa_array);
578 [ # # ]: 0 : if (mdata->num_tx_sc)
579 : 0 : plt_free(mdata->tx_sc_array);
580 [ # # ]: 0 : if (mdata->num_rx_sc) {
581 : 0 : plt_free(mdata->rx_sc_array);
582 : 0 : plt_free(mdata->sc_an_array);
583 : : }
584 : : return rc;
585 : : }
586 : :
587 : : int
588 : 0 : roc_mcs_port_reset(struct roc_mcs *mcs, struct roc_mcs_port_reset_req *port)
589 : : {
590 : 0 : struct roc_mcs_event_desc desc = {0};
591 : : int rc;
592 : :
593 : : /* Initiate port reset and software recovery */
594 : 0 : rc = roc_mcs_port_recovery(mcs, &desc.metadata, port->port_id);
595 [ # # ]: 0 : if (rc)
596 : 0 : goto exit;
597 : :
598 : 0 : desc.type = ROC_MCS_EVENT_PORT_RESET_RECOVERY;
599 : : /* Notify the entity details to the application which are recovered */
600 : 0 : mcs_event_cb_process(mcs, &desc);
601 : :
602 : 0 : exit:
603 [ # # ]: 0 : if (desc.metadata.num_tx_sa)
604 : 0 : plt_free(desc.metadata.tx_sa_array);
605 [ # # ]: 0 : if (desc.metadata.num_rx_sa)
606 : 0 : plt_free(desc.metadata.rx_sa_array);
607 [ # # ]: 0 : if (desc.metadata.num_tx_sc)
608 : 0 : plt_free(desc.metadata.tx_sc_array);
609 [ # # ]: 0 : if (desc.metadata.num_rx_sc) {
610 : 0 : plt_free(desc.metadata.rx_sc_array);
611 : 0 : plt_free(desc.metadata.sc_an_array);
612 : : }
613 : :
614 : 0 : return rc;
615 : : }
616 : :
617 : : int
618 [ # # ]: 0 : roc_mcs_event_cb_register(struct roc_mcs *mcs, enum roc_mcs_event_type event,
619 : : roc_mcs_dev_cb_fn cb_fn, void *cb_arg, void *userdata)
620 : : {
621 : : struct mcs_event_cb_list *cb_list = (struct mcs_event_cb_list *)roc_mcs_to_mcs_cb_list(mcs);
622 : : struct mcs_event_cb *cb;
623 : :
624 [ # # # # ]: 0 : if (cb_fn == NULL || cb_arg == NULL || userdata == NULL)
625 : : return -EINVAL;
626 : :
627 [ # # # # ]: 0 : MCS_SUPPORT_CHECK;
628 : :
629 [ # # ]: 0 : TAILQ_FOREACH(cb, cb_list, next) {
630 [ # # # # : 0 : if (cb->cb_fn == cb_fn && cb->cb_arg == cb_arg && cb->event == event)
# # ]
631 : : break;
632 : : }
633 : :
634 [ # # ]: 0 : if (cb == NULL) {
635 : 0 : cb = plt_zmalloc(sizeof(struct mcs_event_cb), 0);
636 [ # # ]: 0 : if (!cb)
637 : : return -ENOMEM;
638 : :
639 : 0 : cb->cb_fn = cb_fn;
640 : 0 : cb->cb_arg = cb_arg;
641 : 0 : cb->event = event;
642 : 0 : cb->userdata = userdata;
643 : 0 : TAILQ_INSERT_TAIL(cb_list, cb, next);
644 : : }
645 : :
646 : : return 0;
647 : : }
648 : :
649 : : int
650 [ # # ]: 0 : roc_mcs_event_cb_unregister(struct roc_mcs *mcs, enum roc_mcs_event_type event)
651 : : {
652 : : struct mcs_event_cb_list *cb_list = (struct mcs_event_cb_list *)roc_mcs_to_mcs_cb_list(mcs);
653 : : struct mcs_event_cb *cb, *next;
654 : :
655 [ # # # # ]: 0 : MCS_SUPPORT_CHECK;
656 : :
657 [ # # ]: 0 : for (cb = TAILQ_FIRST(cb_list); cb != NULL; cb = next) {
658 : 0 : next = TAILQ_NEXT(cb, next);
659 : :
660 [ # # ]: 0 : if (cb->event != event)
661 : 0 : continue;
662 : :
663 [ # # ]: 0 : if (cb->active == 0) {
664 [ # # ]: 0 : TAILQ_REMOVE(cb_list, cb, next);
665 : 0 : plt_free(cb);
666 : : } else {
667 : : return -EAGAIN;
668 : : }
669 : : }
670 : :
671 : : return 0;
672 : : }
673 : :
674 : : int
675 : 0 : mcs_event_cb_process(struct roc_mcs *mcs, struct roc_mcs_event_desc *desc)
676 : : {
677 : : struct mcs_event_cb_list *cb_list = (struct mcs_event_cb_list *)roc_mcs_to_mcs_cb_list(mcs);
678 : : struct mcs_event_cb mcs_cb;
679 : : struct mcs_event_cb *cb;
680 : : int rc = 0;
681 : :
682 [ # # ]: 0 : TAILQ_FOREACH(cb, cb_list, next) {
683 [ # # # # ]: 0 : if (cb->cb_fn == NULL || cb->event != desc->type)
684 : 0 : continue;
685 : :
686 : 0 : mcs_cb = *cb;
687 : 0 : cb->active = 1;
688 : : mcs_cb.ret_param = desc;
689 : :
690 : 0 : rc = mcs_cb.cb_fn(mcs_cb.userdata, mcs_cb.ret_param, mcs_cb.cb_arg,
691 : 0 : mcs->sa_port_map[desc->metadata.sa_idx]);
692 : 0 : cb->active = 0;
693 : : }
694 : :
695 : 0 : return rc;
696 : : }
697 : :
698 : : static int
699 : 0 : mcs_alloc_bmap(uint16_t entries, void **mem, struct plt_bitmap **bmap)
700 : : {
701 : : size_t bmap_sz;
702 : : int rc = 0;
703 : :
704 : 0 : bmap_sz = plt_bitmap_get_memory_footprint(entries);
705 : 0 : *mem = plt_zmalloc(bmap_sz, PLT_CACHE_LINE_SIZE);
706 [ # # ]: 0 : if (*mem == NULL)
707 : : rc = -ENOMEM;
708 : :
709 : 0 : *bmap = plt_bitmap_init(entries, *mem, bmap_sz);
710 [ # # ]: 0 : if (!*bmap) {
711 : 0 : plt_free(*mem);
712 : 0 : *mem = NULL;
713 : : rc = -ENOMEM;
714 : : }
715 : :
716 : 0 : return rc;
717 : : }
718 : :
719 : : static void
720 : 0 : rsrc_bmap_free(struct mcs_rsrc *rsrc)
721 : : {
722 : : plt_bitmap_free(rsrc->tcam_bmap);
723 : 0 : plt_free(rsrc->tcam_bmap_mem);
724 : : plt_bitmap_free(rsrc->secy_bmap);
725 : 0 : plt_free(rsrc->secy_bmap_mem);
726 : : plt_bitmap_free(rsrc->sc_bmap);
727 : 0 : plt_free(rsrc->sc_bmap_mem);
728 : : plt_bitmap_free(rsrc->sa_bmap);
729 : 0 : plt_free(rsrc->sa_bmap_mem);
730 : 0 : }
731 : :
732 : : static int
733 : 0 : rsrc_bmap_alloc(struct mcs_priv *priv, struct mcs_rsrc *rsrc)
734 : : {
735 : : int rc;
736 : :
737 : 0 : rc = mcs_alloc_bmap(priv->tcam_entries << 1, &rsrc->tcam_bmap_mem, &rsrc->tcam_bmap);
738 [ # # ]: 0 : if (rc)
739 : 0 : goto exit;
740 : :
741 : 0 : rc = mcs_alloc_bmap(priv->secy_entries << 1, &rsrc->secy_bmap_mem, &rsrc->secy_bmap);
742 [ # # ]: 0 : if (rc)
743 : 0 : goto exit;
744 : :
745 : 0 : rc = mcs_alloc_bmap(priv->sc_entries << 1, &rsrc->sc_bmap_mem, &rsrc->sc_bmap);
746 [ # # ]: 0 : if (rc)
747 : 0 : goto exit;
748 : :
749 : 0 : rc = mcs_alloc_bmap(priv->sa_entries << 1, &rsrc->sa_bmap_mem, &rsrc->sa_bmap);
750 [ # # ]: 0 : if (rc)
751 : 0 : goto exit;
752 : :
753 : : return rc;
754 : 0 : exit:
755 : 0 : rsrc_bmap_free(rsrc);
756 : :
757 : 0 : return rc;
758 : : }
759 : :
760 : : static int
761 : 0 : mcs_alloc_rsrc_bmap(struct roc_mcs *mcs)
762 : : {
763 : : struct mcs_priv *priv = roc_mcs_to_mcs_priv(mcs);
764 : : struct mcs_hw_info *hw;
765 : : int i, rc;
766 : :
767 : 0 : mbox_alloc_msg_mcs_get_hw_info(mcs->mbox);
768 : 0 : rc = mbox_process_msg(mcs->mbox, (void *)&hw);
769 [ # # ]: 0 : if (rc)
770 : : return rc;
771 : :
772 : 0 : priv->num_mcs_blks = hw->num_mcs_blks;
773 : 0 : priv->tcam_entries = hw->tcam_entries;
774 : 0 : priv->secy_entries = hw->secy_entries;
775 : 0 : priv->sc_entries = hw->sc_entries;
776 : 0 : priv->sa_entries = hw->sa_entries;
777 : :
778 : 0 : rc = rsrc_bmap_alloc(priv, &priv->dev_rsrc);
779 [ # # ]: 0 : if (rc)
780 : : return rc;
781 : :
782 : 0 : priv->port_rsrc = plt_zmalloc(sizeof(struct mcs_rsrc) * 4, 0);
783 [ # # ]: 0 : if (priv->port_rsrc == NULL) {
784 : 0 : rsrc_bmap_free(&priv->dev_rsrc);
785 : 0 : return -ENOMEM;
786 : : }
787 : :
788 [ # # ]: 0 : for (i = 0; i < MAX_PORTS_PER_MCS; i++) {
789 : 0 : rc = rsrc_bmap_alloc(priv, &priv->port_rsrc[i]);
790 [ # # ]: 0 : if (rc)
791 : 0 : goto exit;
792 : :
793 : 0 : priv->port_rsrc[i].sc_conf =
794 : 0 : plt_zmalloc(priv->sc_entries * sizeof(struct mcs_sc_conf), 0);
795 [ # # ]: 0 : if (priv->port_rsrc[i].sc_conf == NULL) {
796 : 0 : rsrc_bmap_free(&priv->port_rsrc[i]);
797 : 0 : goto exit;
798 : : }
799 : : }
800 : :
801 : 0 : mcs->sa_port_map = plt_zmalloc(sizeof(uint8_t) * hw->sa_entries, 0);
802 [ # # ]: 0 : if (mcs->sa_port_map == NULL)
803 : 0 : goto exit;
804 : :
805 : : return rc;
806 : :
807 : : exit:
808 [ # # ]: 0 : while (i--) {
809 : 0 : rsrc_bmap_free(&priv->port_rsrc[i]);
810 : 0 : plt_free(priv->port_rsrc[i].sc_conf);
811 : : }
812 : 0 : plt_free(priv->port_rsrc);
813 : :
814 : 0 : return -ENOMEM;
815 : : }
816 : :
817 : : struct roc_mcs *
818 [ # # ]: 0 : roc_mcs_dev_init(uint8_t mcs_idx)
819 : : {
820 : : struct mcs_event_cb_list *cb_list;
821 : : struct roc_mcs *mcs;
822 : : struct npa_lf *npa;
823 : :
824 [ # # # # ]: 0 : if (!(roc_feature_bphy_has_macsec() || roc_feature_nix_has_macsec()))
825 : : return NULL;
826 : :
827 : 0 : mcs = roc_idev_mcs_get(mcs_idx);
828 [ # # ]: 0 : if (mcs) {
829 : 0 : plt_info("Skipping device, mcs device already probed");
830 : 0 : mcs->refcount++;
831 : 0 : return mcs;
832 : : }
833 : :
834 : 0 : mcs = plt_zmalloc(sizeof(struct roc_mcs), PLT_CACHE_LINE_SIZE);
835 [ # # ]: 0 : if (!mcs)
836 : : return NULL;
837 : :
838 : 0 : npa = idev_npa_obj_get();
839 [ # # ]: 0 : if (!npa)
840 : 0 : goto exit;
841 : :
842 : 0 : mcs->mbox = npa->mbox;
843 : 0 : mcs->idx = mcs_idx;
844 : :
845 : : /* Add any per mcsv initialization */
846 [ # # ]: 0 : if (mcs_alloc_rsrc_bmap(mcs))
847 : 0 : goto exit;
848 : :
849 : : cb_list = (struct mcs_event_cb_list *)roc_mcs_to_mcs_cb_list(mcs);
850 : 0 : TAILQ_INIT(cb_list);
851 : :
852 : 0 : roc_idev_mcs_set(mcs);
853 : 0 : mcs->refcount++;
854 : :
855 : 0 : return mcs;
856 : 0 : exit:
857 : 0 : plt_free(mcs);
858 : 0 : return NULL;
859 : : }
860 : :
861 : : void
862 : 0 : roc_mcs_dev_fini(struct roc_mcs *mcs)
863 : : {
864 : : struct mcs_priv *priv;
865 : : int i;
866 : :
867 : 0 : mcs->refcount--;
868 [ # # ]: 0 : if (mcs->refcount > 0)
869 : : return;
870 : :
871 : : priv = roc_mcs_to_mcs_priv(mcs);
872 : :
873 : 0 : rsrc_bmap_free(&priv->dev_rsrc);
874 : :
875 [ # # ]: 0 : for (i = 0; i < MAX_PORTS_PER_MCS; i++) {
876 : 0 : rsrc_bmap_free(&priv->port_rsrc[i]);
877 : 0 : plt_free(priv->port_rsrc[i].sc_conf);
878 : : }
879 : :
880 : 0 : plt_free(priv->port_rsrc);
881 : :
882 : 0 : plt_free(mcs->sa_port_map);
883 : :
884 : 0 : roc_idev_mcs_free(mcs);
885 : :
886 : 0 : plt_free(mcs);
887 : : }
|