felix.c (7c4bb540e9173c914c2091fdd9b6aee3c2a3e1e5) felix.c (c8c0ba4fe2479033be946cfb5651d45c876c4c86)
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright 2019-2021 NXP Semiconductors
3 *
4 * This is an umbrella module for all network switches that are
5 * register-compatible with Ocelot and that perform I/O to their host CPU
6 * through an NPI (Node Processor Interface) Ethernet port.
7 */
8#include <uapi/linux/if_bridge.h>

--- 250 unchanged lines hidden (view full) ---

259
260 /* Restore PGID_CPU */
261 ocelot_write_rix(ocelot, BIT(ocelot->num_phys_ports), ANA_PGID_PGID,
262 PGID_CPU);
263
264 ocelot_apply_bridge_fwd_mask(ocelot);
265}
266
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright 2019-2021 NXP Semiconductors
3 *
4 * This is an umbrella module for all network switches that are
5 * register-compatible with Ocelot and that perform I/O to their host CPU
6 * through an NPI (Node Processor Interface) Ethernet port.
7 */
8#include <uapi/linux/if_bridge.h>

--- 250 unchanged lines hidden (view full) ---

259
260 /* Restore PGID_CPU */
261 ocelot_write_rix(ocelot, BIT(ocelot->num_phys_ports), ANA_PGID_PGID,
262 PGID_CPU);
263
264 ocelot_apply_bridge_fwd_mask(ocelot);
265}
266
267/* Set up a VCAP IS2 rule for delivering PTP frames to the CPU port module.
268 * If the quirk_no_xtr_irq is in place, then also copy those PTP frames to the
269 * tag_8021q CPU port.
270 */
271static int felix_setup_mmio_filtering(struct felix *felix)
272{
273 unsigned long user_ports = 0, cpu_ports = 0;
274 struct ocelot_vcap_filter *redirect_rule;
275 struct ocelot_vcap_filter *tagging_rule;
276 struct ocelot *ocelot = &felix->ocelot;
277 struct dsa_switch *ds = felix->ds;
278 int port, ret;
279
280 tagging_rule = kzalloc(sizeof(struct ocelot_vcap_filter), GFP_KERNEL);
281 if (!tagging_rule)
282 return -ENOMEM;
283
284 redirect_rule = kzalloc(sizeof(struct ocelot_vcap_filter), GFP_KERNEL);
285 if (!redirect_rule) {
286 kfree(tagging_rule);
287 return -ENOMEM;
288 }
289
290 for (port = 0; port < ocelot->num_phys_ports; port++) {
291 if (dsa_is_user_port(ds, port))
292 user_ports |= BIT(port);
293 if (dsa_is_cpu_port(ds, port))
294 cpu_ports |= BIT(port);
295 }
296
297 tagging_rule->key_type = OCELOT_VCAP_KEY_ETYPE;
298 *(__be16 *)tagging_rule->key.etype.etype.value = htons(ETH_P_1588);
299 *(__be16 *)tagging_rule->key.etype.etype.mask = htons(0xffff);
300 tagging_rule->ingress_port_mask = user_ports;
301 tagging_rule->prio = 1;
302 tagging_rule->id.cookie = ocelot->num_phys_ports;
303 tagging_rule->id.tc_offload = false;
304 tagging_rule->block_id = VCAP_IS1;
305 tagging_rule->type = OCELOT_VCAP_FILTER_OFFLOAD;
306 tagging_rule->lookup = 0;
307 tagging_rule->action.pag_override_mask = 0xff;
308 tagging_rule->action.pag_val = ocelot->num_phys_ports;
309
310 ret = ocelot_vcap_filter_add(ocelot, tagging_rule, NULL);
311 if (ret) {
312 kfree(tagging_rule);
313 kfree(redirect_rule);
314 return ret;
315 }
316
317 redirect_rule->key_type = OCELOT_VCAP_KEY_ANY;
318 redirect_rule->ingress_port_mask = user_ports;
319 redirect_rule->pag = ocelot->num_phys_ports;
320 redirect_rule->prio = 1;
321 redirect_rule->id.cookie = ocelot->num_phys_ports;
322 redirect_rule->id.tc_offload = false;
323 redirect_rule->block_id = VCAP_IS2;
324 redirect_rule->type = OCELOT_VCAP_FILTER_OFFLOAD;
325 redirect_rule->lookup = 0;
326 redirect_rule->action.cpu_copy_ena = true;
327 if (felix->info->quirk_no_xtr_irq) {
328 /* Redirect to the tag_8021q CPU but also copy PTP packets to
329 * the CPU port module
330 */
331 redirect_rule->action.mask_mode = OCELOT_MASK_MODE_REDIRECT;
332 redirect_rule->action.port_mask = cpu_ports;
333 } else {
334 /* Trap PTP packets only to the CPU port module (which is
335 * redirected to the NPI port)
336 */
337 redirect_rule->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY;
338 redirect_rule->action.port_mask = 0;
339 }
340
341 ret = ocelot_vcap_filter_add(ocelot, redirect_rule, NULL);
342 if (ret) {
343 ocelot_vcap_filter_del(ocelot, tagging_rule);
344 kfree(redirect_rule);
345 return ret;
346 }
347
348 return 0;
349}
350
351static int felix_teardown_mmio_filtering(struct felix *felix)
352{
353 struct ocelot_vcap_filter *tagging_rule, *redirect_rule;
354 struct ocelot_vcap_block *block_vcap_is1;
355 struct ocelot_vcap_block *block_vcap_is2;
356 struct ocelot *ocelot = &felix->ocelot;
357 int err;
358
359 block_vcap_is1 = &ocelot->block[VCAP_IS1];
360 block_vcap_is2 = &ocelot->block[VCAP_IS2];
361
362 tagging_rule = ocelot_vcap_block_find_filter_by_id(block_vcap_is1,
363 ocelot->num_phys_ports,
364 false);
365 if (!tagging_rule)
366 return -ENOENT;
367
368 err = ocelot_vcap_filter_del(ocelot, tagging_rule);
369 if (err)
370 return err;
371
372 redirect_rule = ocelot_vcap_block_find_filter_by_id(block_vcap_is2,
373 ocelot->num_phys_ports,
374 false);
375 if (!redirect_rule)
376 return -ENOENT;
377
378 return ocelot_vcap_filter_del(ocelot, redirect_rule);
379}
380
267static int felix_setup_tag_8021q(struct dsa_switch *ds, int cpu)
268{
269 struct ocelot *ocelot = ds->priv;
270 struct felix *felix = ocelot_to_felix(ocelot);
271 unsigned long cpu_flood;
272 int port, err;
273
274 felix_8021q_cpu_port_init(ocelot, cpu);

--- 12 unchanged lines hidden (view full) ---

287 * the tag_8021q CPU port, not to the hardware CPU
288 * port module.
289 */
290 ocelot_write_gix(ocelot,
291 ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(0),
292 ANA_PORT_CPU_FWD_BPDU_CFG, port);
293 }
294
381static int felix_setup_tag_8021q(struct dsa_switch *ds, int cpu)
382{
383 struct ocelot *ocelot = ds->priv;
384 struct felix *felix = ocelot_to_felix(ocelot);
385 unsigned long cpu_flood;
386 int port, err;
387
388 felix_8021q_cpu_port_init(ocelot, cpu);

--- 12 unchanged lines hidden (view full) ---

401 * the tag_8021q CPU port, not to the hardware CPU
402 * port module.
403 */
404 ocelot_write_gix(ocelot,
405 ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(0),
406 ANA_PORT_CPU_FWD_BPDU_CFG, port);
407 }
408
295 /* In tag_8021q mode, the CPU port module is unused. So we
296 * want to disable flooding of any kind to the CPU port module,
297 * since packets going there will end in a black hole.
409 /* In tag_8021q mode, the CPU port module is unused, except for PTP
410 * frames. So we want to disable flooding of any kind to the CPU port
411 * module, since packets going there will end in a black hole.
298 */
299 cpu_flood = ANA_PGID_PGID_PGID(BIT(ocelot->num_phys_ports));
300 ocelot_rmw_rix(ocelot, 0, cpu_flood, ANA_PGID_PGID, PGID_UC);
301 ocelot_rmw_rix(ocelot, 0, cpu_flood, ANA_PGID_PGID, PGID_MC);
302 ocelot_rmw_rix(ocelot, 0, cpu_flood, ANA_PGID_PGID, PGID_BC);
303
304 felix->dsa_8021q_ctx = kzalloc(sizeof(*felix->dsa_8021q_ctx),
305 GFP_KERNEL);
306 if (!felix->dsa_8021q_ctx)
307 return -ENOMEM;
308
309 felix->dsa_8021q_ctx->ops = &felix_tag_8021q_ops;
310 felix->dsa_8021q_ctx->proto = htons(ETH_P_8021AD);
311 felix->dsa_8021q_ctx->ds = ds;
312
313 err = dsa_8021q_setup(felix->dsa_8021q_ctx, true);
314 if (err)
315 goto out_free_dsa_8021_ctx;
316
412 */
413 cpu_flood = ANA_PGID_PGID_PGID(BIT(ocelot->num_phys_ports));
414 ocelot_rmw_rix(ocelot, 0, cpu_flood, ANA_PGID_PGID, PGID_UC);
415 ocelot_rmw_rix(ocelot, 0, cpu_flood, ANA_PGID_PGID, PGID_MC);
416 ocelot_rmw_rix(ocelot, 0, cpu_flood, ANA_PGID_PGID, PGID_BC);
417
418 felix->dsa_8021q_ctx = kzalloc(sizeof(*felix->dsa_8021q_ctx),
419 GFP_KERNEL);
420 if (!felix->dsa_8021q_ctx)
421 return -ENOMEM;
422
423 felix->dsa_8021q_ctx->ops = &felix_tag_8021q_ops;
424 felix->dsa_8021q_ctx->proto = htons(ETH_P_8021AD);
425 felix->dsa_8021q_ctx->ds = ds;
426
427 err = dsa_8021q_setup(felix->dsa_8021q_ctx, true);
428 if (err)
429 goto out_free_dsa_8021_ctx;
430
431 err = felix_setup_mmio_filtering(felix);
432 if (err)
433 goto out_teardown_dsa_8021q;
434
317 return 0;
318
435 return 0;
436
437out_teardown_dsa_8021q:
438 dsa_8021q_setup(felix->dsa_8021q_ctx, false);
319out_free_dsa_8021_ctx:
320 kfree(felix->dsa_8021q_ctx);
321 return err;
322}
323
324static void felix_teardown_tag_8021q(struct dsa_switch *ds, int cpu)
325{
326 struct ocelot *ocelot = ds->priv;
327 struct felix *felix = ocelot_to_felix(ocelot);
328 int err, port;
329
439out_free_dsa_8021_ctx:
440 kfree(felix->dsa_8021q_ctx);
441 return err;
442}
443
444static void felix_teardown_tag_8021q(struct dsa_switch *ds, int cpu)
445{
446 struct ocelot *ocelot = ds->priv;
447 struct felix *felix = ocelot_to_felix(ocelot);
448 int err, port;
449
450 err = felix_teardown_mmio_filtering(felix);
451 if (err)
452 dev_err(ds->dev, "felix_teardown_mmio_filtering returned %d",
453 err);
454
330 err = dsa_8021q_setup(felix->dsa_8021q_ctx, false);
331 if (err)
332 dev_err(ds->dev, "dsa_8021q_setup returned %d", err);
333
334 kfree(felix->dsa_8021q_ctx);
335
336 for (port = 0; port < ds->num_ports; port++) {
337 if (dsa_is_unused_port(ds, port))

--- 1107 unchanged lines hidden ---
455 err = dsa_8021q_setup(felix->dsa_8021q_ctx, false);
456 if (err)
457 dev_err(ds->dev, "dsa_8021q_setup returned %d", err);
458
459 kfree(felix->dsa_8021q_ctx);
460
461 for (port = 0; port < ds->num_ports; port++) {
462 if (dsa_is_unused_port(ds, port))

--- 1107 unchanged lines hidden ---