Skip to content

Commit 69df578

Browse files
vladimirolteandavem330
authored andcommitted
net: mscc: ocelot: eliminate confusion between CPU and NPI port
Ocelot has the concept of a CPU port. The CPU port is represented in the forwarding and the queueing system, but it is not a physical device. The CPU port can either be accessed via register-based injection/extraction (which is the case of Ocelot), via Frame-DMA (similar to the first one), or "connected" to a physical Ethernet port (called NPI in the datasheet) which is the case of the Felix DSA switch. In Ocelot the CPU port is at index 11. In Felix the CPU port is at index 6. The CPU bit is treated special in the forwarding, as it is never cleared from the forwarding port mask (once added to it). Other than that, it is treated the same as a normal front port. Both Felix and Ocelot should use the CPU port in the same way. This means that Felix should not use the NPI port directly when forwarding to the CPU, but instead use the CPU port. This patch is fixing this such that Felix will use port 6 as its CPU port, and just use the NPI port to carry the traffic. Therefore, eliminate the "ocelot->cpu" variable which was holding the index of the NPI port for Felix, and the index of the CPU port module for Ocelot, so the variable was actually configuring different things for different drivers and causing at least part of the confusion. Also remove the "ocelot->num_cpu_ports" variable, which is the result of another confusion. The 2 CPU ports mentioned in the datasheet are because there are two frame extraction channels (register based or DMA based). This is of no relevance to the driver at the moment, and invisible to the analyzer module. Signed-off-by: Vladimir Oltean <[email protected]> Suggested-by: Allan W. Nielsen <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f6f8ef9 commit 69df578

File tree

5 files changed

+52
-39
lines changed

5 files changed

+52
-39
lines changed

drivers/net/dsa/ocelot/felix.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,10 +516,11 @@ static int felix_setup(struct dsa_switch *ds)
516516
for (port = 0; port < ds->num_ports; port++) {
517517
ocelot_init_port(ocelot, port);
518518

519+
/* Bring up the CPU port module and configure the NPI port */
519520
if (dsa_is_cpu_port(ds, port))
520-
ocelot_set_cpu_port(ocelot, port,
521-
OCELOT_TAG_PREFIX_NONE,
522-
OCELOT_TAG_PREFIX_LONG);
521+
ocelot_configure_cpu(ocelot, port,
522+
OCELOT_TAG_PREFIX_NONE,
523+
OCELOT_TAG_PREFIX_LONG);
523524
}
524525

525526
/* It looks like the MAC/PCS interrupt register - PM0_IEVENT (0x8040)

drivers/net/ethernet/mscc/ocelot.c

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,7 @@ void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state)
14131413
* a source for the other ports.
14141414
*/
14151415
for (p = 0; p < ocelot->num_phys_ports; p++) {
1416-
if (p == ocelot->cpu || (ocelot->bridge_fwd_mask & BIT(p))) {
1416+
if (ocelot->bridge_fwd_mask & BIT(p)) {
14171417
unsigned long mask = ocelot->bridge_fwd_mask & ~BIT(p);
14181418

14191419
for (i = 0; i < ocelot->num_phys_ports; i++) {
@@ -1428,18 +1428,10 @@ void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state)
14281428
}
14291429
}
14301430

1431-
/* Avoid the NPI port from looping back to itself */
1432-
if (p != ocelot->cpu)
1433-
mask |= BIT(ocelot->cpu);
1434-
14351431
ocelot_write_rix(ocelot, mask,
14361432
ANA_PGID_PGID, PGID_SRC + p);
14371433
} else {
1438-
/* Only the CPU port, this is compatible with link
1439-
* aggregation.
1440-
*/
1441-
ocelot_write_rix(ocelot,
1442-
BIT(ocelot->cpu),
1434+
ocelot_write_rix(ocelot, 0,
14431435
ANA_PGID_PGID, PGID_SRC + p);
14441436
}
14451437
}
@@ -2308,42 +2300,62 @@ int ocelot_probe_port(struct ocelot *ocelot, u8 port,
23082300
}
23092301
EXPORT_SYMBOL(ocelot_probe_port);
23102302

2311-
void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu,
2312-
enum ocelot_tag_prefix injection,
2313-
enum ocelot_tag_prefix extraction)
2303+
/* Configure and enable the CPU port module, which is a set of queues.
2304+
* If @npi contains a valid port index, the CPU port module is connected
2305+
* to the Node Processor Interface (NPI). This is the mode through which
2306+
* frames can be injected from and extracted to an external CPU,
2307+
* over Ethernet.
2308+
*/
2309+
void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
2310+
enum ocelot_tag_prefix injection,
2311+
enum ocelot_tag_prefix extraction)
23142312
{
2315-
/* Configure and enable the CPU port. */
2313+
int cpu = ocelot->num_phys_ports;
2314+
2315+
/* The unicast destination PGID for the CPU port module is unused */
23162316
ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, cpu);
2317+
/* Instead set up a multicast destination PGID for traffic copied to
2318+
* the CPU. Whitelisted MAC addresses like the port netdevice MAC
2319+
* addresses will be copied to the CPU via this PGID.
2320+
*/
23172321
ocelot_write_rix(ocelot, BIT(cpu), ANA_PGID_PGID, PGID_CPU);
23182322
ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_RECV_ENA |
23192323
ANA_PORT_PORT_CFG_PORTID_VAL(cpu),
23202324
ANA_PORT_PORT_CFG, cpu);
23212325

2322-
/* If the CPU port is a physical port, set up the port in Node
2323-
* Processor Interface (NPI) mode. This is the mode through which
2324-
* frames can be injected from and extracted to an external CPU.
2325-
* Only one port can be an NPI at the same time.
2326-
*/
2327-
if (cpu < ocelot->num_phys_ports) {
2326+
if (npi >= 0 && npi < ocelot->num_phys_ports) {
23282327
int mtu = VLAN_ETH_FRAME_LEN + OCELOT_TAG_LEN;
23292328

23302329
ocelot_write(ocelot, QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M |
2331-
QSYS_EXT_CPU_CFG_EXT_CPU_PORT(cpu),
2330+
QSYS_EXT_CPU_CFG_EXT_CPU_PORT(npi),
23322331
QSYS_EXT_CPU_CFG);
23332332

23342333
if (injection == OCELOT_TAG_PREFIX_SHORT)
23352334
mtu += OCELOT_SHORT_PREFIX_LEN;
23362335
else if (injection == OCELOT_TAG_PREFIX_LONG)
23372336
mtu += OCELOT_LONG_PREFIX_LEN;
23382337

2339-
ocelot_port_set_mtu(ocelot, cpu, mtu);
2338+
ocelot_port_set_mtu(ocelot, npi, mtu);
2339+
2340+
/* Enable NPI port */
2341+
ocelot_write_rix(ocelot,
2342+
QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
2343+
QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) |
2344+
QSYS_SWITCH_PORT_MODE_PORT_ENA,
2345+
QSYS_SWITCH_PORT_MODE, npi);
2346+
/* NPI port Injection/Extraction configuration */
2347+
ocelot_write_rix(ocelot,
2348+
SYS_PORT_MODE_INCL_XTR_HDR(extraction) |
2349+
SYS_PORT_MODE_INCL_INJ_HDR(injection),
2350+
SYS_PORT_MODE, npi);
23402351
}
23412352

2342-
/* CPU port Injection/Extraction configuration */
2353+
/* Enable CPU port module */
23432354
ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
23442355
QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) |
23452356
QSYS_SWITCH_PORT_MODE_PORT_ENA,
23462357
QSYS_SWITCH_PORT_MODE, cpu);
2358+
/* CPU port Injection/Extraction configuration */
23472359
ocelot_write_rix(ocelot, SYS_PORT_MODE_INCL_XTR_HDR(extraction) |
23482360
SYS_PORT_MODE_INCL_INJ_HDR(injection),
23492361
SYS_PORT_MODE, cpu);
@@ -2353,10 +2365,8 @@ void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu,
23532365
ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
23542366
ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1),
23552367
ANA_PORT_VLAN_CFG, cpu);
2356-
2357-
ocelot->cpu = cpu;
23582368
}
2359-
EXPORT_SYMBOL(ocelot_set_cpu_port);
2369+
EXPORT_SYMBOL(ocelot_configure_cpu);
23602370

23612371
int ocelot_init(struct ocelot *ocelot)
23622372
{

drivers/net/ethernet/mscc/ocelot_board.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,6 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
453453
ocelot->ptp = 1;
454454
}
455455

456-
ocelot->num_cpu_ports = 1; /* 1 port on the switch, two groups */
457-
458456
ports = of_get_child_by_name(np, "ethernet-ports");
459457
if (!ports) {
460458
dev_err(&pdev->dev, "no ethernet-ports child node found\n");
@@ -471,8 +469,9 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
471469
ocelot->vcap = vsc7514_vcap_props;
472470

473471
ocelot_init(ocelot);
474-
ocelot_set_cpu_port(ocelot, ocelot->num_phys_ports,
475-
OCELOT_TAG_PREFIX_NONE, OCELOT_TAG_PREFIX_NONE);
472+
/* No NPI port */
473+
ocelot_configure_cpu(ocelot, -1, OCELOT_TAG_PREFIX_NONE,
474+
OCELOT_TAG_PREFIX_NONE);
476475

477476
for_each_available_child_of_node(ports, portnp) {
478477
struct ocelot_port_private *priv;

include/soc/mscc/ocelot.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -451,9 +451,11 @@ struct ocelot {
451451
/* Keep track of the vlan port masks */
452452
u32 vlan_mask[VLAN_N_VID];
453453

454+
/* In tables like ANA:PORT and the ANA:PGID:PGID mask,
455+
* the CPU is located after the physical ports (at the
456+
* num_phys_ports index).
457+
*/
454458
u8 num_phys_ports;
455-
u8 num_cpu_ports;
456-
u8 cpu;
457459

458460
u32 *lags;
459461

@@ -508,9 +510,9 @@ void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg,
508510
int ocelot_regfields_init(struct ocelot *ocelot,
509511
const struct reg_field *const regfields);
510512
struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res);
511-
void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu,
512-
enum ocelot_tag_prefix injection,
513-
enum ocelot_tag_prefix extraction);
513+
void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
514+
enum ocelot_tag_prefix injection,
515+
enum ocelot_tag_prefix extraction);
514516
int ocelot_init(struct ocelot *ocelot);
515517
void ocelot_deinit(struct ocelot *ocelot);
516518
void ocelot_init_port(struct ocelot *ocelot, int port);

net/dsa/tag_ocelot.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
153153

154154
memset(injection, 0, OCELOT_TAG_LEN);
155155

156-
src = dsa_upstream_port(ds, port);
156+
/* Set the source port as the CPU port module and not the NPI port */
157+
src = ocelot->num_phys_ports;
157158
dest = BIT(port);
158159
bypass = true;
159160
qos_class = skb->priority;

0 commit comments

Comments
 (0)