Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2024 Marvell.
3 : : */
4 : :
5 : : #include "cnxk_flow_common.h"
6 : : #include "cnxk_ethdev_mcs.h"
7 : : #include <cnxk_flow.h>
8 : :
9 : : static int
10 : : cnxk_mtr_connect(struct rte_eth_dev *eth_dev, uint32_t mtr_id)
11 : : {
12 : 0 : return nix_mtr_connect(eth_dev, mtr_id);
13 : : }
14 : :
15 : : int
16 : 0 : cnxk_mtr_destroy(struct rte_eth_dev *eth_dev, uint32_t mtr_id)
17 : : {
18 : : struct rte_mtr_error mtr_error;
19 : :
20 : 0 : return nix_mtr_destroy(eth_dev, mtr_id, &mtr_error);
21 : : }
22 : :
23 : : static int
24 : 0 : cnxk_mtr_configure(struct rte_eth_dev *eth_dev, const struct rte_flow_action actions[])
25 : : {
26 : 0 : uint32_t mtr_id = 0xffff, prev_mtr_id = 0xffff, next_mtr_id = 0xffff;
27 : : const struct rte_flow_action_meter *mtr_conf;
28 : : const struct rte_flow_action_queue *q_conf;
29 : : const struct rte_flow_action_rss *rss_conf;
30 : : struct cnxk_mtr_policy_node *policy;
31 : : bool is_mtr_act = false;
32 : 0 : int tree_level = 0;
33 : : int rc = -EINVAL, i;
34 : :
35 [ # # ]: 0 : for (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {
36 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_METER) {
37 : 0 : mtr_conf = (const struct rte_flow_action_meter *)(actions[i].conf);
38 : 0 : mtr_id = mtr_conf->mtr_id;
39 : : is_mtr_act = true;
40 : : }
41 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_QUEUE) {
42 : 0 : q_conf = (const struct rte_flow_action_queue *)(actions[i].conf);
43 [ # # ]: 0 : if (is_mtr_act)
44 : 0 : nix_mtr_rq_update(eth_dev, mtr_id, 1, &q_conf->index);
45 : : }
46 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_RSS) {
47 : 0 : rss_conf = (const struct rte_flow_action_rss *)(actions[i].conf);
48 [ # # ]: 0 : if (is_mtr_act)
49 : 0 : nix_mtr_rq_update(eth_dev, mtr_id, rss_conf->queue_num,
50 : 0 : rss_conf->queue);
51 : : }
52 : : }
53 : :
54 [ # # ]: 0 : if (!is_mtr_act)
55 : : return rc;
56 : :
57 : 0 : prev_mtr_id = mtr_id;
58 : 0 : next_mtr_id = mtr_id;
59 [ # # ]: 0 : while (next_mtr_id != 0xffff) {
60 : 0 : rc = nix_mtr_validate(eth_dev, next_mtr_id);
61 [ # # ]: 0 : if (rc)
62 : 0 : return rc;
63 : :
64 : 0 : rc = nix_mtr_policy_act_get(eth_dev, next_mtr_id, &policy);
65 [ # # ]: 0 : if (rc)
66 : 0 : return rc;
67 : :
68 : 0 : rc = nix_mtr_color_action_validate(eth_dev, mtr_id, &prev_mtr_id, &next_mtr_id,
69 : : policy, &tree_level);
70 [ # # ]: 0 : if (rc)
71 : 0 : return rc;
72 : : }
73 : :
74 : 0 : return nix_mtr_configure(eth_dev, mtr_id);
75 : : }
76 : :
77 : : static int
78 : 0 : cnxk_rss_action_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
79 : : const struct rte_flow_action *act)
80 : : {
81 : : const struct rte_flow_action_rss *rss;
82 : :
83 [ # # ]: 0 : if (act == NULL)
84 : : return -EINVAL;
85 : :
86 : 0 : rss = (const struct rte_flow_action_rss *)act->conf;
87 : :
88 [ # # ]: 0 : if (attr->egress) {
89 : 0 : plt_err("No support of RSS in egress");
90 : 0 : return -EINVAL;
91 : : }
92 : :
93 [ # # ]: 0 : if (eth_dev->data->dev_conf.rxmode.mq_mode != RTE_ETH_MQ_RX_RSS) {
94 : 0 : plt_err("multi-queue mode is disabled");
95 : 0 : return -ENOTSUP;
96 : : }
97 : :
98 [ # # # # ]: 0 : if (!rss || !rss->queue_num) {
99 : 0 : plt_err("no valid queues");
100 : 0 : return -EINVAL;
101 : : }
102 : :
103 [ # # ]: 0 : if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT) {
104 : 0 : plt_err("non-default RSS hash functions are not supported");
105 : 0 : return -ENOTSUP;
106 : : }
107 : :
108 [ # # ]: 0 : if (rss->key_len && rss->key_len > ROC_NIX_RSS_KEY_LEN) {
109 : 0 : plt_err("RSS hash key too large");
110 : 0 : return -ENOTSUP;
111 : : }
112 : :
113 : : return 0;
114 : : }
115 : :
116 : : struct roc_npc_flow *
117 : 0 : cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
118 : : const struct rte_flow_item pattern[], const struct rte_flow_action actions[],
119 : : struct rte_flow_error *error)
120 : : {
121 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
122 : : const struct rte_flow_action *action_rss = NULL;
123 : : const struct rte_flow_action_meter *mtr = NULL;
124 : : const struct rte_flow_action *act_q = NULL;
125 : : struct roc_npc_flow *flow;
126 : 0 : void *mcs_flow = NULL;
127 : : uint32_t req_act = 0;
128 : : int i, rc;
129 : :
130 [ # # ]: 0 : for (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {
131 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_METER)
132 : 0 : req_act |= ROC_NPC_ACTION_TYPE_METER;
133 : :
134 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_QUEUE) {
135 : 0 : req_act |= ROC_NPC_ACTION_TYPE_QUEUE;
136 : : act_q = &actions[i];
137 : : }
138 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_RSS) {
139 : 0 : req_act |= ROC_NPC_ACTION_TYPE_RSS;
140 : : action_rss = &actions[i];
141 : : }
142 : : }
143 : :
144 [ # # ]: 0 : if (req_act & ROC_NPC_ACTION_TYPE_METER) {
145 [ # # ]: 0 : if ((req_act & ROC_NPC_ACTION_TYPE_RSS) &&
146 : : ((req_act & ROC_NPC_ACTION_TYPE_QUEUE))) {
147 : : return NULL;
148 : : }
149 [ # # ]: 0 : if (req_act & ROC_NPC_ACTION_TYPE_RSS) {
150 : 0 : rc = cnxk_rss_action_validate(eth_dev, attr, action_rss);
151 [ # # ]: 0 : if (rc)
152 : : return NULL;
153 [ # # ]: 0 : } else if (req_act & ROC_NPC_ACTION_TYPE_QUEUE) {
154 : : const struct rte_flow_action_queue *act_queue;
155 : 0 : act_queue = (const struct rte_flow_action_queue *)act_q->conf;
156 [ # # ]: 0 : if (act_queue->index > eth_dev->data->nb_rx_queues)
157 : : return NULL;
158 : : } else {
159 : : return NULL;
160 : : }
161 : : }
162 [ # # ]: 0 : for (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {
163 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_METER) {
164 : 0 : mtr = (const struct rte_flow_action_meter *)actions[i].conf;
165 : 0 : rc = cnxk_mtr_configure(eth_dev, actions);
166 [ # # ]: 0 : if (rc) {
167 : 0 : rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
168 : : "Failed to configure mtr ");
169 : 0 : return NULL;
170 : : }
171 : : break;
172 : : }
173 : : }
174 : :
175 [ # # # # ]: 0 : if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY &&
176 : 0 : cnxk_eth_macsec_sess_get_by_sess(dev, actions[0].conf) != NULL) {
177 : 0 : rc = cnxk_mcs_flow_configure(eth_dev, attr, pattern, actions, error, &mcs_flow);
178 [ # # ]: 0 : if (rc) {
179 : 0 : rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
180 : : "Failed to configure mcs flow");
181 : 0 : return NULL;
182 : : }
183 : 0 : return mcs_flow;
184 : : }
185 : :
186 : 0 : flow = cnxk_flow_create_common(eth_dev, attr, pattern, actions, error, false);
187 [ # # ]: 0 : if (!flow) {
188 [ # # ]: 0 : if (mtr)
189 : 0 : nix_mtr_chain_reset(eth_dev, mtr->mtr_id);
190 : :
191 : : } else {
192 [ # # ]: 0 : if (mtr)
193 : 0 : cnxk_mtr_connect(eth_dev, mtr->mtr_id);
194 : : }
195 : :
196 : : return flow;
197 : : }
198 : :
199 : : int
200 : 0 : cnxk_flow_info_get_common(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
201 : : struct rte_flow_queue_info *queue_info, struct rte_flow_error *err)
202 : : {
203 : : RTE_SET_USED(dev);
204 : : RTE_SET_USED(err);
205 : :
206 : : memset(port_info, 0, sizeof(*port_info));
207 : : memset(queue_info, 0, sizeof(*queue_info));
208 : :
209 : 0 : port_info->max_nb_counters = CNXK_NPC_COUNTERS_MAX;
210 : 0 : port_info->max_nb_meters = CNXK_NIX_MTR_COUNT_MAX;
211 : :
212 : 0 : return 0;
213 : : }
|