felix.c (c518afec288351347dbe05ea3d49d18fb9a9fff1) felix.c (2960bb14ea27e8ce48e05534eb6737de1176fe22)
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright 2019-2021 NXP
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>

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

273 */
274static int felix_setup_mmio_filtering(struct felix *felix)
275{
276 unsigned long user_ports = dsa_user_ports(felix->ds);
277 struct ocelot_vcap_filter *redirect_rule;
278 struct ocelot_vcap_filter *tagging_rule;
279 struct ocelot *ocelot = &felix->ocelot;
280 struct dsa_switch *ds = felix->ds;
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright 2019-2021 NXP
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>

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

273 */
274static int felix_setup_mmio_filtering(struct felix *felix)
275{
276 unsigned long user_ports = dsa_user_ports(felix->ds);
277 struct ocelot_vcap_filter *redirect_rule;
278 struct ocelot_vcap_filter *tagging_rule;
279 struct ocelot *ocelot = &felix->ocelot;
280 struct dsa_switch *ds = felix->ds;
281 int cpu = -1, port, ret;
281 struct dsa_port *dp;
282 int cpu = -1, ret;
282
283 tagging_rule = kzalloc(sizeof(struct ocelot_vcap_filter), GFP_KERNEL);
284 if (!tagging_rule)
285 return -ENOMEM;
286
287 redirect_rule = kzalloc(sizeof(struct ocelot_vcap_filter), GFP_KERNEL);
288 if (!redirect_rule) {
289 kfree(tagging_rule);
290 return -ENOMEM;
291 }
292
283
284 tagging_rule = kzalloc(sizeof(struct ocelot_vcap_filter), GFP_KERNEL);
285 if (!tagging_rule)
286 return -ENOMEM;
287
288 redirect_rule = kzalloc(sizeof(struct ocelot_vcap_filter), GFP_KERNEL);
289 if (!redirect_rule) {
290 kfree(tagging_rule);
291 return -ENOMEM;
292 }
293
293 for (port = 0; port < ocelot->num_phys_ports; port++) {
294 if (dsa_is_cpu_port(ds, port)) {
295 cpu = port;
296 break;
297 }
294 dsa_switch_for_each_cpu_port(dp, ds) {
295 cpu = dp->index;
296 break;
298 }
299
300 if (cpu < 0) {
301 kfree(tagging_rule);
302 kfree(redirect_rule);
303 return -EINVAL;
304 }
305

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

396 return ocelot_vcap_filter_del(ocelot, redirect_rule);
397}
398
399static int felix_setup_tag_8021q(struct dsa_switch *ds, int cpu)
400{
401 struct ocelot *ocelot = ds->priv;
402 struct felix *felix = ocelot_to_felix(ocelot);
403 unsigned long cpu_flood;
297 }
298
299 if (cpu < 0) {
300 kfree(tagging_rule);
301 kfree(redirect_rule);
302 return -EINVAL;
303 }
304

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

395 return ocelot_vcap_filter_del(ocelot, redirect_rule);
396}
397
398static int felix_setup_tag_8021q(struct dsa_switch *ds, int cpu)
399{
400 struct ocelot *ocelot = ds->priv;
401 struct felix *felix = ocelot_to_felix(ocelot);
402 unsigned long cpu_flood;
404 int port, err;
403 struct dsa_port *dp;
404 int err;
405
406 felix_8021q_cpu_port_init(ocelot, cpu);
407
405
406 felix_8021q_cpu_port_init(ocelot, cpu);
407
408 for (port = 0; port < ds->num_ports; port++) {
409 if (dsa_is_unused_port(ds, port))
410 continue;
411
408 dsa_switch_for_each_available_port(dp, ds) {
412 /* This overwrites ocelot_init():
413 * Do not forward BPDU frames to the CPU port module,
414 * for 2 reasons:
415 * - When these packets are injected from the tag_8021q
416 * CPU port, we want them to go out, not loop back
417 * into the system.
418 * - STP traffic ingressing on a user port should go to
419 * the tag_8021q CPU port, not to the hardware CPU
420 * port module.
421 */
422 ocelot_write_gix(ocelot,
423 ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(0),
409 /* This overwrites ocelot_init():
410 * Do not forward BPDU frames to the CPU port module,
411 * for 2 reasons:
412 * - When these packets are injected from the tag_8021q
413 * CPU port, we want them to go out, not loop back
414 * into the system.
415 * - STP traffic ingressing on a user port should go to
416 * the tag_8021q CPU port, not to the hardware CPU
417 * port module.
418 */
419 ocelot_write_gix(ocelot,
420 ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(0),
424 ANA_PORT_CPU_FWD_BPDU_CFG, port);
421 ANA_PORT_CPU_FWD_BPDU_CFG, dp->index);
425 }
426
427 /* In tag_8021q mode, the CPU port module is unused, except for PTP
428 * frames. So we want to disable flooding of any kind to the CPU port
429 * module, since packets going there will end in a black hole.
430 */
431 cpu_flood = ANA_PGID_PGID_PGID(BIT(ocelot->num_phys_ports));
432 ocelot_rmw_rix(ocelot, 0, cpu_flood, ANA_PGID_PGID, PGID_UC);

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

447 dsa_tag_8021q_unregister(ds);
448 return err;
449}
450
451static void felix_teardown_tag_8021q(struct dsa_switch *ds, int cpu)
452{
453 struct ocelot *ocelot = ds->priv;
454 struct felix *felix = ocelot_to_felix(ocelot);
422 }
423
424 /* In tag_8021q mode, the CPU port module is unused, except for PTP
425 * frames. So we want to disable flooding of any kind to the CPU port
426 * module, since packets going there will end in a black hole.
427 */
428 cpu_flood = ANA_PGID_PGID_PGID(BIT(ocelot->num_phys_ports));
429 ocelot_rmw_rix(ocelot, 0, cpu_flood, ANA_PGID_PGID, PGID_UC);

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

444 dsa_tag_8021q_unregister(ds);
445 return err;
446}
447
448static void felix_teardown_tag_8021q(struct dsa_switch *ds, int cpu)
449{
450 struct ocelot *ocelot = ds->priv;
451 struct felix *felix = ocelot_to_felix(ocelot);
455 int err, port;
452 struct dsa_port *dp;
453 int err;
456
457 err = felix_teardown_mmio_filtering(felix);
458 if (err)
459 dev_err(ds->dev, "felix_teardown_mmio_filtering returned %d",
460 err);
461
462 dsa_tag_8021q_unregister(ds);
463
454
455 err = felix_teardown_mmio_filtering(felix);
456 if (err)
457 dev_err(ds->dev, "felix_teardown_mmio_filtering returned %d",
458 err);
459
460 dsa_tag_8021q_unregister(ds);
461
464 for (port = 0; port < ds->num_ports; port++) {
465 if (dsa_is_unused_port(ds, port))
466 continue;
467
462 dsa_switch_for_each_available_port(dp, ds) {
468 /* Restore the logic from ocelot_init:
469 * do not forward BPDU frames to the front ports.
470 */
471 ocelot_write_gix(ocelot,
472 ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(0xffff),
473 ANA_PORT_CPU_FWD_BPDU_CFG,
463 /* Restore the logic from ocelot_init:
464 * do not forward BPDU frames to the front ports.
465 */
466 ocelot_write_gix(ocelot,
467 ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(0xffff),
468 ANA_PORT_CPU_FWD_BPDU_CFG,
474 port);
469 dp->index);
475 }
476
477 felix_8021q_cpu_port_deinit(ocelot, cpu);
478}
479
480/* The CPU port module is connected to the Node Processor Interface (NPI). This
481 * is the mode through which frames can be injected from and extracted to an
482 * external CPU, over Ethernet. In NXP SoCs, the "external CPU" is the ARM CPU

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

1187 * devm without fear of dsa_register_switch returning -EPROBE_DEFER and causing
1188 * us to allocate structures twice (leak memory) and map PCI memory twice
1189 * (which will not work).
1190 */
1191static int felix_setup(struct dsa_switch *ds)
1192{
1193 struct ocelot *ocelot = ds->priv;
1194 struct felix *felix = ocelot_to_felix(ocelot);
470 }
471
472 felix_8021q_cpu_port_deinit(ocelot, cpu);
473}
474
475/* The CPU port module is connected to the Node Processor Interface (NPI). This
476 * is the mode through which frames can be injected from and extracted to an
477 * external CPU, over Ethernet. In NXP SoCs, the "external CPU" is the ARM CPU

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

1182 * devm without fear of dsa_register_switch returning -EPROBE_DEFER and causing
1183 * us to allocate structures twice (leak memory) and map PCI memory twice
1184 * (which will not work).
1185 */
1186static int felix_setup(struct dsa_switch *ds)
1187{
1188 struct ocelot *ocelot = ds->priv;
1189 struct felix *felix = ocelot_to_felix(ocelot);
1195 int port, err;
1190 struct dsa_port *dp;
1191 int err;
1196
1197 err = felix_init_structs(felix, ds->num_ports);
1198 if (err)
1199 return err;
1200
1201 err = ocelot_init(ocelot);
1202 if (err)
1203 goto out_mdiobus_free;
1204
1205 if (ocelot->ptp) {
1206 err = ocelot_init_timestamp(ocelot, felix->info->ptp_caps);
1207 if (err) {
1208 dev_err(ocelot->dev,
1209 "Timestamp initialization failed\n");
1210 ocelot->ptp = 0;
1211 }
1212 }
1213
1192
1193 err = felix_init_structs(felix, ds->num_ports);
1194 if (err)
1195 return err;
1196
1197 err = ocelot_init(ocelot);
1198 if (err)
1199 goto out_mdiobus_free;
1200
1201 if (ocelot->ptp) {
1202 err = ocelot_init_timestamp(ocelot, felix->info->ptp_caps);
1203 if (err) {
1204 dev_err(ocelot->dev,
1205 "Timestamp initialization failed\n");
1206 ocelot->ptp = 0;
1207 }
1208 }
1209
1214 for (port = 0; port < ds->num_ports; port++) {
1215 if (dsa_is_unused_port(ds, port))
1216 continue;
1210 dsa_switch_for_each_available_port(dp, ds) {
1211 ocelot_init_port(ocelot, dp->index);
1217
1212
1218 ocelot_init_port(ocelot, port);
1219
1220 /* Set the default QoS Classification based on PCP and DEI
1221 * bits of vlan tag.
1222 */
1213 /* Set the default QoS Classification based on PCP and DEI
1214 * bits of vlan tag.
1215 */
1223 felix_port_qos_map_init(ocelot, port);
1216 felix_port_qos_map_init(ocelot, dp->index);
1224 }
1225
1226 err = ocelot_devlink_sb_register(ocelot);
1227 if (err)
1228 goto out_deinit_ports;
1229
1217 }
1218
1219 err = ocelot_devlink_sb_register(ocelot);
1220 if (err)
1221 goto out_deinit_ports;
1222
1230 for (port = 0; port < ds->num_ports; port++) {
1231 if (!dsa_is_cpu_port(ds, port))
1232 continue;
1233
1223 dsa_switch_for_each_cpu_port(dp, ds) {
1234 /* The initial tag protocol is NPI which always returns 0, so
1235 * there's no real point in checking for errors.
1236 */
1224 /* The initial tag protocol is NPI which always returns 0, so
1225 * there's no real point in checking for errors.
1226 */
1237 felix_set_tag_protocol(ds, port, felix->tag_proto);
1227 felix_set_tag_protocol(ds, dp->index, felix->tag_proto);
1238 break;
1239 }
1240
1241 ds->mtu_enforcement_ingress = true;
1242 ds->assisted_learning_on_cpu_port = true;
1243
1244 return 0;
1245
1246out_deinit_ports:
1228 break;
1229 }
1230
1231 ds->mtu_enforcement_ingress = true;
1232 ds->assisted_learning_on_cpu_port = true;
1233
1234 return 0;
1235
1236out_deinit_ports:
1247 for (port = 0; port < ocelot->num_phys_ports; port++) {
1248 if (dsa_is_unused_port(ds, port))
1249 continue;
1237 dsa_switch_for_each_available_port(dp, ds)
1238 ocelot_deinit_port(ocelot, dp->index);
1250
1239
1251 ocelot_deinit_port(ocelot, port);
1252 }
1253
1254 ocelot_deinit_timestamp(ocelot);
1255 ocelot_deinit(ocelot);
1256
1257out_mdiobus_free:
1258 if (felix->info->mdio_bus_free)
1259 felix->info->mdio_bus_free(ocelot);
1260
1261 return err;
1262}
1263
1264static void felix_teardown(struct dsa_switch *ds)
1265{
1266 struct ocelot *ocelot = ds->priv;
1267 struct felix *felix = ocelot_to_felix(ocelot);
1240 ocelot_deinit_timestamp(ocelot);
1241 ocelot_deinit(ocelot);
1242
1243out_mdiobus_free:
1244 if (felix->info->mdio_bus_free)
1245 felix->info->mdio_bus_free(ocelot);
1246
1247 return err;
1248}
1249
1250static void felix_teardown(struct dsa_switch *ds)
1251{
1252 struct ocelot *ocelot = ds->priv;
1253 struct felix *felix = ocelot_to_felix(ocelot);
1268 int port;
1254 struct dsa_port *dp;
1269
1255
1270 for (port = 0; port < ds->num_ports; port++) {
1271 if (!dsa_is_cpu_port(ds, port))
1272 continue;
1273
1274 felix_del_tag_protocol(ds, port, felix->tag_proto);
1256 dsa_switch_for_each_cpu_port(dp, ds) {
1257 felix_del_tag_protocol(ds, dp->index, felix->tag_proto);
1275 break;
1276 }
1277
1258 break;
1259 }
1260
1278 for (port = 0; port < ocelot->num_phys_ports; port++) {
1279 if (dsa_is_unused_port(ds, port))
1280 continue;
1261 dsa_switch_for_each_available_port(dp, ds)
1262 ocelot_deinit_port(ocelot, dp->index);
1281
1263
1282 ocelot_deinit_port(ocelot, port);
1283 }
1284
1285 ocelot_devlink_sb_unregister(ocelot);
1286 ocelot_deinit_timestamp(ocelot);
1287 ocelot_deinit(ocelot);
1288
1289 if (felix->info->mdio_bus_free)
1290 felix->info->mdio_bus_free(ocelot);
1291}
1292

--- 411 unchanged lines hidden ---
1264 ocelot_devlink_sb_unregister(ocelot);
1265 ocelot_deinit_timestamp(ocelot);
1266 ocelot_deinit(ocelot);
1267
1268 if (felix->info->mdio_bus_free)
1269 felix->info->mdio_bus_free(ocelot);
1270}
1271

--- 411 unchanged lines hidden ---