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 --- |