1 // SPDX-License-Identifier: GPL-2.0
3 #include <net/macsec.h>
6 static int nsim_macsec_find_secy(struct netdevsim *ns, sci_t sci)
10 for (i = 0; i < NSIM_MACSEC_MAX_SECY_COUNT; i++) {
11 if (ns->macsec.nsim_secy[i].sci == sci)
18 static int nsim_macsec_find_rxsc(struct nsim_secy *ns_secy, sci_t sci)
22 for (i = 0; i < NSIM_MACSEC_MAX_RXSC_COUNT; i++) {
23 if (ns_secy->nsim_rxsc[i].sci == sci)
30 static int nsim_macsec_add_secy(struct macsec_context *ctx)
32 struct netdevsim *ns = netdev_priv(ctx->netdev);
35 if (ns->macsec.nsim_secy_count == NSIM_MACSEC_MAX_SECY_COUNT)
38 for (idx = 0; idx < NSIM_MACSEC_MAX_SECY_COUNT; idx++) {
39 if (!ns->macsec.nsim_secy[idx].used)
43 if (idx == NSIM_MACSEC_MAX_SECY_COUNT) {
44 netdev_err(ctx->netdev, "%s: nsim_secy_count not full but all SecYs used\n",
49 netdev_dbg(ctx->netdev, "%s: adding new secy with sci %016llx at index %d\n",
50 __func__, sci_to_cpu(ctx->secy->sci), idx);
51 ns->macsec.nsim_secy[idx].used = true;
52 ns->macsec.nsim_secy[idx].nsim_rxsc_count = 0;
53 ns->macsec.nsim_secy[idx].sci = ctx->secy->sci;
54 ns->macsec.nsim_secy_count++;
59 static int nsim_macsec_upd_secy(struct macsec_context *ctx)
61 struct netdevsim *ns = netdev_priv(ctx->netdev);
64 idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
66 netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
67 __func__, sci_to_cpu(ctx->secy->sci));
71 netdev_dbg(ctx->netdev, "%s: updating secy with sci %016llx at index %d\n",
72 __func__, sci_to_cpu(ctx->secy->sci), idx);
77 static int nsim_macsec_del_secy(struct macsec_context *ctx)
79 struct netdevsim *ns = netdev_priv(ctx->netdev);
82 idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
84 netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
85 __func__, sci_to_cpu(ctx->secy->sci));
89 netdev_dbg(ctx->netdev, "%s: removing SecY with SCI %016llx at index %d\n",
90 __func__, sci_to_cpu(ctx->secy->sci), idx);
92 ns->macsec.nsim_secy[idx].used = false;
93 memset(&ns->macsec.nsim_secy[idx], 0, sizeof(ns->macsec.nsim_secy[idx]));
94 ns->macsec.nsim_secy_count--;
99 static int nsim_macsec_add_rxsc(struct macsec_context *ctx)
101 struct netdevsim *ns = netdev_priv(ctx->netdev);
102 struct nsim_secy *secy;
105 idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
107 netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
108 __func__, sci_to_cpu(ctx->secy->sci));
111 secy = &ns->macsec.nsim_secy[idx];
113 if (secy->nsim_rxsc_count == NSIM_MACSEC_MAX_RXSC_COUNT)
116 for (idx = 0; idx < NSIM_MACSEC_MAX_RXSC_COUNT; idx++) {
117 if (!secy->nsim_rxsc[idx].used)
121 if (idx == NSIM_MACSEC_MAX_RXSC_COUNT)
122 netdev_err(ctx->netdev, "%s: nsim_rxsc_count not full but all RXSCs used\n",
125 netdev_dbg(ctx->netdev, "%s: adding new rxsc with sci %016llx at index %d\n",
126 __func__, sci_to_cpu(ctx->rx_sc->sci), idx);
127 secy->nsim_rxsc[idx].used = true;
128 secy->nsim_rxsc[idx].sci = ctx->rx_sc->sci;
129 secy->nsim_rxsc_count++;
134 static int nsim_macsec_upd_rxsc(struct macsec_context *ctx)
136 struct netdevsim *ns = netdev_priv(ctx->netdev);
137 struct nsim_secy *secy;
140 idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
142 netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
143 __func__, sci_to_cpu(ctx->secy->sci));
146 secy = &ns->macsec.nsim_secy[idx];
148 idx = nsim_macsec_find_rxsc(secy, ctx->rx_sc->sci);
150 netdev_err(ctx->netdev, "%s: sci %016llx not found in RXSC table\n",
151 __func__, sci_to_cpu(ctx->rx_sc->sci));
155 netdev_dbg(ctx->netdev, "%s: updating RXSC with sci %016llx at index %d\n",
156 __func__, sci_to_cpu(ctx->rx_sc->sci), idx);
161 static int nsim_macsec_del_rxsc(struct macsec_context *ctx)
163 struct netdevsim *ns = netdev_priv(ctx->netdev);
164 struct nsim_secy *secy;
167 idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
169 netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
170 __func__, sci_to_cpu(ctx->secy->sci));
173 secy = &ns->macsec.nsim_secy[idx];
175 idx = nsim_macsec_find_rxsc(secy, ctx->rx_sc->sci);
177 netdev_err(ctx->netdev, "%s: sci %016llx not found in RXSC table\n",
178 __func__, sci_to_cpu(ctx->rx_sc->sci));
182 netdev_dbg(ctx->netdev, "%s: removing RXSC with sci %016llx at index %d\n",
183 __func__, sci_to_cpu(ctx->rx_sc->sci), idx);
185 secy->nsim_rxsc[idx].used = false;
186 memset(&secy->nsim_rxsc[idx], 0, sizeof(secy->nsim_rxsc[idx]));
187 secy->nsim_rxsc_count--;
192 static int nsim_macsec_add_rxsa(struct macsec_context *ctx)
194 struct netdevsim *ns = netdev_priv(ctx->netdev);
195 struct nsim_secy *secy;
198 idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
200 netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
201 __func__, sci_to_cpu(ctx->secy->sci));
204 secy = &ns->macsec.nsim_secy[idx];
206 idx = nsim_macsec_find_rxsc(secy, ctx->sa.rx_sa->sc->sci);
208 netdev_err(ctx->netdev, "%s: sci %016llx not found in RXSC table\n",
209 __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci));
213 netdev_dbg(ctx->netdev, "%s: RXSC with sci %016llx, AN %u\n",
214 __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci), ctx->sa.assoc_num);
219 static int nsim_macsec_upd_rxsa(struct macsec_context *ctx)
221 struct netdevsim *ns = netdev_priv(ctx->netdev);
222 struct nsim_secy *secy;
225 idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
227 netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
228 __func__, sci_to_cpu(ctx->secy->sci));
231 secy = &ns->macsec.nsim_secy[idx];
233 idx = nsim_macsec_find_rxsc(secy, ctx->sa.rx_sa->sc->sci);
235 netdev_err(ctx->netdev, "%s: sci %016llx not found in RXSC table\n",
236 __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci));
240 netdev_dbg(ctx->netdev, "%s: RXSC with sci %016llx, AN %u\n",
241 __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci), ctx->sa.assoc_num);
246 static int nsim_macsec_del_rxsa(struct macsec_context *ctx)
248 struct netdevsim *ns = netdev_priv(ctx->netdev);
249 struct nsim_secy *secy;
252 idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
254 netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
255 __func__, sci_to_cpu(ctx->secy->sci));
258 secy = &ns->macsec.nsim_secy[idx];
260 idx = nsim_macsec_find_rxsc(secy, ctx->sa.rx_sa->sc->sci);
262 netdev_err(ctx->netdev, "%s: sci %016llx not found in RXSC table\n",
263 __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci));
267 netdev_dbg(ctx->netdev, "%s: RXSC with sci %016llx, AN %u\n",
268 __func__, sci_to_cpu(ctx->sa.rx_sa->sc->sci), ctx->sa.assoc_num);
273 static int nsim_macsec_add_txsa(struct macsec_context *ctx)
275 struct netdevsim *ns = netdev_priv(ctx->netdev);
278 idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
280 netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
281 __func__, sci_to_cpu(ctx->secy->sci));
285 netdev_dbg(ctx->netdev, "%s: SECY with sci %016llx, AN %u\n",
286 __func__, sci_to_cpu(ctx->secy->sci), ctx->sa.assoc_num);
291 static int nsim_macsec_upd_txsa(struct macsec_context *ctx)
293 struct netdevsim *ns = netdev_priv(ctx->netdev);
296 idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
298 netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
299 __func__, sci_to_cpu(ctx->secy->sci));
303 netdev_dbg(ctx->netdev, "%s: SECY with sci %016llx, AN %u\n",
304 __func__, sci_to_cpu(ctx->secy->sci), ctx->sa.assoc_num);
309 static int nsim_macsec_del_txsa(struct macsec_context *ctx)
311 struct netdevsim *ns = netdev_priv(ctx->netdev);
314 idx = nsim_macsec_find_secy(ns, ctx->secy->sci);
316 netdev_err(ctx->netdev, "%s: sci %016llx not found in secy table\n",
317 __func__, sci_to_cpu(ctx->secy->sci));
321 netdev_dbg(ctx->netdev, "%s: SECY with sci %016llx, AN %u\n",
322 __func__, sci_to_cpu(ctx->secy->sci), ctx->sa.assoc_num);
327 static const struct macsec_ops nsim_macsec_ops = {
328 .mdo_add_secy = nsim_macsec_add_secy,
329 .mdo_upd_secy = nsim_macsec_upd_secy,
330 .mdo_del_secy = nsim_macsec_del_secy,
331 .mdo_add_rxsc = nsim_macsec_add_rxsc,
332 .mdo_upd_rxsc = nsim_macsec_upd_rxsc,
333 .mdo_del_rxsc = nsim_macsec_del_rxsc,
334 .mdo_add_rxsa = nsim_macsec_add_rxsa,
335 .mdo_upd_rxsa = nsim_macsec_upd_rxsa,
336 .mdo_del_rxsa = nsim_macsec_del_rxsa,
337 .mdo_add_txsa = nsim_macsec_add_txsa,
338 .mdo_upd_txsa = nsim_macsec_upd_txsa,
339 .mdo_del_txsa = nsim_macsec_del_txsa,
342 void nsim_macsec_init(struct netdevsim *ns)
344 ns->netdev->macsec_ops = &nsim_macsec_ops;
345 ns->netdev->features |= NETIF_F_HW_MACSEC;
346 memset(&ns->macsec, 0, sizeof(ns->macsec));
349 void nsim_macsec_teardown(struct netdevsim *ns)