1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2021 Marvell.
3 */
4
5 #include "roc_api.h"
6 #include "roc_priv.h"
7
8 int
roc_nix_vlan_mcam_entry_read(struct roc_nix * roc_nix,uint32_t index,struct npc_mcam_read_entry_rsp ** rsp)9 roc_nix_vlan_mcam_entry_read(struct roc_nix *roc_nix, uint32_t index,
10 struct npc_mcam_read_entry_rsp **rsp)
11 {
12 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
13 struct dev *dev = &nix->dev;
14 struct mbox *mbox = mbox_get(dev->mbox);
15 struct npc_mcam_read_entry_req *req;
16 int rc = -ENOSPC;
17
18 req = mbox_alloc_msg_npc_mcam_read_entry(mbox);
19 if (req == NULL)
20 goto exit;
21 req->entry = index;
22
23 rc = mbox_process_msg(mbox, (void **)rsp);
24 exit:
25 mbox_put(mbox);
26 return rc;
27 }
28
29 int
roc_nix_vlan_mcam_entry_write(struct roc_nix * roc_nix,uint32_t index,struct mcam_entry * entry,uint8_t intf,uint8_t enable)30 roc_nix_vlan_mcam_entry_write(struct roc_nix *roc_nix, uint32_t index,
31 struct mcam_entry *entry, uint8_t intf,
32 uint8_t enable)
33 {
34 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
35 struct dev *dev = &nix->dev;
36 struct mbox *mbox = mbox_get(dev->mbox);
37 struct npc_mcam_write_entry_req *req;
38 struct msghdr *rsp;
39 int rc = -ENOSPC;
40
41 req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
42 if (req == NULL)
43 goto exit;
44 req->entry = index;
45 req->intf = intf;
46 req->enable_entry = enable;
47 mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
48
49 rc = mbox_process_msg(mbox, (void *)&rsp);
50 exit:
51 mbox_put(mbox);
52 return rc;
53 }
54
55 int
roc_nix_vlan_mcam_entry_alloc_and_write(struct roc_nix * roc_nix,struct mcam_entry * entry,uint8_t intf,uint8_t priority,uint8_t ref_entry)56 roc_nix_vlan_mcam_entry_alloc_and_write(struct roc_nix *roc_nix,
57 struct mcam_entry *entry, uint8_t intf,
58 uint8_t priority, uint8_t ref_entry)
59 {
60 struct npc_mcam_alloc_and_write_entry_req *req;
61 struct npc_mcam_alloc_and_write_entry_rsp *rsp;
62 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
63 struct dev *dev = &nix->dev;
64 struct mbox *mbox = mbox_get(dev->mbox);
65 int rc = -ENOSPC;
66
67 req = mbox_alloc_msg_npc_mcam_alloc_and_write_entry(mbox);
68 if (req == NULL)
69 goto exit;
70 req->priority = priority;
71 req->ref_entry = ref_entry;
72 req->intf = intf;
73 req->enable_entry = true;
74 mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
75
76 rc = mbox_process_msg(mbox, (void *)&rsp);
77 if (rc)
78 goto exit;
79
80 rc = rsp->entry;
81 exit:
82 mbox_put(mbox);
83 return rc;
84 }
85
86 int
roc_nix_vlan_mcam_entry_free(struct roc_nix * roc_nix,uint32_t index)87 roc_nix_vlan_mcam_entry_free(struct roc_nix *roc_nix, uint32_t index)
88 {
89 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
90 struct dev *dev = &nix->dev;
91 struct mbox *mbox = mbox_get(dev->mbox);
92 struct npc_mcam_free_entry_req *req;
93 int rc = -ENOSPC;
94
95 req = mbox_alloc_msg_npc_mcam_free_entry(mbox);
96 if (req == NULL)
97 goto exit;
98 req->entry = index;
99
100 rc = mbox_process_msg(mbox, NULL);
101 exit:
102 mbox_put(mbox);
103 return rc;
104 }
105
106 int
roc_nix_vlan_mcam_entry_ena_dis(struct roc_nix * roc_nix,uint32_t index,const int enable)107 roc_nix_vlan_mcam_entry_ena_dis(struct roc_nix *roc_nix, uint32_t index,
108 const int enable)
109 {
110 struct npc_mcam_ena_dis_entry_req *req;
111 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
112 struct dev *dev = &nix->dev;
113 struct mbox *mbox = mbox_get(dev->mbox);
114 int rc = -ENOSPC;
115
116 if (enable) {
117 req = mbox_alloc_msg_npc_mcam_ena_entry(mbox);
118 if (req == NULL)
119 goto exit;
120 } else {
121 req = mbox_alloc_msg_npc_mcam_dis_entry(mbox);
122 if (req == NULL)
123 goto exit;
124 }
125
126 req->entry = index;
127 rc = mbox_process_msg(mbox, NULL);
128 exit:
129 mbox_put(mbox);
130 return rc;
131 }
132
133 int
roc_nix_vlan_strip_vtag_ena_dis(struct roc_nix * roc_nix,bool enable)134 roc_nix_vlan_strip_vtag_ena_dis(struct roc_nix *roc_nix, bool enable)
135 {
136 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
137 struct dev *dev = &nix->dev;
138 struct mbox *mbox = mbox_get(dev->mbox);
139 struct nix_vtag_config *vtag_cfg;
140 int rc = -ENOSPC;
141
142 vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox);
143 if (vtag_cfg == NULL)
144 goto exit;
145 vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
146 vtag_cfg->cfg_type = 1; /* Rx VLAN configuration */
147 vtag_cfg->rx.capture_vtag = 1; /* Always capture */
148 vtag_cfg->rx.vtag_type = 0; /* Use index 0 */
149
150 if (enable)
151 vtag_cfg->rx.strip_vtag = 1;
152 else
153 vtag_cfg->rx.strip_vtag = 0;
154
155 rc = mbox_process(mbox);
156 exit:
157 mbox_put(mbox);
158 return rc;
159 }
160
161 int
roc_nix_vlan_insert_ena_dis(struct roc_nix * roc_nix,struct roc_nix_vlan_config * vlan_cfg,uint64_t * mcam_index,bool enable)162 roc_nix_vlan_insert_ena_dis(struct roc_nix *roc_nix,
163 struct roc_nix_vlan_config *vlan_cfg,
164 uint64_t *mcam_index, bool enable)
165 {
166 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
167 struct dev *dev = &nix->dev;
168 struct mbox *mbox = mbox_get(dev->mbox);
169 struct nix_vtag_config *vtag_cfg;
170 struct nix_vtag_config_rsp *rsp;
171 int rc = -ENOSPC;
172
173 vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox);
174 if (vtag_cfg == NULL)
175 goto exit;
176 vtag_cfg->cfg_type = 0; /* Tx VLAN configuration */
177 vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
178
179 if (enable) {
180 if (vlan_cfg->type & ROC_NIX_VLAN_TYPE_INNER) {
181 vtag_cfg->tx.vtag0 = vlan_cfg->vlan.vtag_inner;
182 vtag_cfg->tx.cfg_vtag0 = true;
183 }
184 if (vlan_cfg->type & ROC_NIX_VLAN_TYPE_OUTER) {
185 vtag_cfg->tx.vtag1 = vlan_cfg->vlan.vtag_outer;
186 vtag_cfg->tx.cfg_vtag1 = true;
187 }
188 } else {
189 if (vlan_cfg->type & ROC_NIX_VLAN_TYPE_INNER) {
190 vtag_cfg->tx.vtag0_idx = vlan_cfg->mcam.idx_inner;
191 vtag_cfg->tx.free_vtag0 = true;
192 }
193 if (vlan_cfg->type & ROC_NIX_VLAN_TYPE_OUTER) {
194 vtag_cfg->tx.vtag1_idx = vlan_cfg->mcam.idx_outer;
195 vtag_cfg->tx.free_vtag1 = true;
196 }
197 }
198
199 rc = mbox_process_msg(mbox, (void *)&rsp);
200 if (rc)
201 goto exit;
202
203 if (enable)
204 *mcam_index =
205 (((uint64_t)rsp->vtag1_idx << 32) | rsp->vtag0_idx);
206
207 rc = 0;
208 exit:
209 mbox_put(mbox);
210 return rc;
211 }
212
213 int
nix_vlan_tpid_set(struct mbox * mbox,uint16_t pcifunc,uint32_t type,uint16_t tpid)214 nix_vlan_tpid_set(struct mbox *mbox, uint16_t pcifunc, uint32_t type, uint16_t tpid)
215 {
216 struct nix_set_vlan_tpid *tpid_cfg;
217 int rc = -ENOSPC;
218
219 /* Configuring for PF */
220 tpid_cfg = mbox_alloc_msg_nix_set_vlan_tpid(mbox_get(mbox));
221 if (tpid_cfg == NULL)
222 goto exit;
223 tpid_cfg->tpid = tpid;
224 tpid_cfg->hdr.pcifunc = pcifunc;
225
226 if (type & ROC_NIX_VLAN_TYPE_OUTER)
227 tpid_cfg->vlan_type = NIX_VLAN_TYPE_OUTER;
228 else
229 tpid_cfg->vlan_type = NIX_VLAN_TYPE_INNER;
230
231 rc = mbox_process(mbox);
232 exit:
233 mbox_put(mbox);
234 return rc;
235 }
236
237 int
roc_nix_vlan_tpid_set(struct roc_nix * roc_nix,uint32_t type,uint16_t tpid)238 roc_nix_vlan_tpid_set(struct roc_nix *roc_nix, uint32_t type, uint16_t tpid)
239 {
240 struct nix *nix = roc_nix_to_nix_priv(roc_nix);
241 struct dev *dev = &nix->dev;
242 int rc;
243
244 rc = nix_vlan_tpid_set(dev->mbox, dev->pf_func, type, tpid);
245 if (rc)
246 plt_err("Failed to set tpid for PF, rc %d", rc);
247
248 return rc;
249 }
250