123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- From c6f39379529e74eccbe317e70bb11d18110c63d4 Mon Sep 17 00:00:00 2001
- From: Vladimir Oltean <[email protected]>
- Date: Sat, 9 Nov 2019 15:03:00 +0200
- Subject: [PATCH] net: mscc: ocelot: split assignment of the cpu port into a
- separate function
- Now that the places that configure routing destinations for the CPU port
- have been marked as such, allow callers to specify their own CPU port
- that is different than ocelot->num_phys_ports. A user will be the Felix
- DSA driver, where the CPU port is one of the physical ports (NPI mode).
- Signed-off-by: Vladimir Oltean <[email protected]>
- Signed-off-by: David S. Miller <[email protected]>
- ---
- drivers/net/ethernet/mscc/ocelot.c | 65 +++++++++++++++++++++-----------
- drivers/net/ethernet/mscc/ocelot.h | 12 ++++++
- drivers/net/ethernet/mscc/ocelot_board.c | 2 +
- 3 files changed, 57 insertions(+), 22 deletions(-)
- --- a/drivers/net/ethernet/mscc/ocelot.c
- +++ b/drivers/net/ethernet/mscc/ocelot.c
- @@ -380,12 +380,6 @@ static void ocelot_vlan_init(struct ocel
- ocelot->vlan_mask[0] = GENMASK(ocelot->num_phys_ports - 1, 0);
- ocelot_vlant_set_mask(ocelot, 0, ocelot->vlan_mask[0]);
-
- - /* Configure the CPU port to be VLAN aware */
- - ocelot_write_gix(ocelot, ANA_PORT_VLAN_CFG_VLAN_VID(0) |
- - ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
- - ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1),
- - ANA_PORT_VLAN_CFG, ocelot->num_phys_ports);
- -
- /* Set vlan ingress filter mask to all ports but the CPU port by
- * default.
- */
- @@ -2226,11 +2220,52 @@ int ocelot_probe_port(struct ocelot *oce
- }
- EXPORT_SYMBOL(ocelot_probe_port);
-
- +void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu,
- + enum ocelot_tag_prefix injection,
- + enum ocelot_tag_prefix extraction)
- +{
- + /* Configure and enable the CPU port. */
- + ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, cpu);
- + ocelot_write_rix(ocelot, BIT(cpu), ANA_PGID_PGID, PGID_CPU);
- + ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_RECV_ENA |
- + ANA_PORT_PORT_CFG_PORTID_VAL(cpu),
- + ANA_PORT_PORT_CFG, cpu);
- +
- + /* If the CPU port is a physical port, set up the port in Node
- + * Processor Interface (NPI) mode. This is the mode through which
- + * frames can be injected from and extracted to an external CPU.
- + * Only one port can be an NPI at the same time.
- + */
- + if (cpu < ocelot->num_phys_ports) {
- + ocelot_write(ocelot, QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M |
- + QSYS_EXT_CPU_CFG_EXT_CPU_PORT(cpu),
- + QSYS_EXT_CPU_CFG);
- + }
- +
- + /* CPU port Injection/Extraction configuration */
- + ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
- + QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) |
- + QSYS_SWITCH_PORT_MODE_PORT_ENA,
- + QSYS_SWITCH_PORT_MODE, cpu);
- + ocelot_write_rix(ocelot, SYS_PORT_MODE_INCL_XTR_HDR(extraction) |
- + SYS_PORT_MODE_INCL_INJ_HDR(injection),
- + SYS_PORT_MODE, cpu);
- +
- + /* Configure the CPU port to be VLAN aware */
- + ocelot_write_gix(ocelot, ANA_PORT_VLAN_CFG_VLAN_VID(0) |
- + ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
- + ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1),
- + ANA_PORT_VLAN_CFG, cpu);
- +
- + ocelot->cpu = cpu;
- +}
- +EXPORT_SYMBOL(ocelot_set_cpu_port);
- +
- int ocelot_init(struct ocelot *ocelot)
- {
- - u32 port;
- - int i, ret, cpu = ocelot->num_phys_ports;
- char queue_name[32];
- + int i, ret;
- + u32 port;
-
- ocelot->lags = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports,
- sizeof(u32), GFP_KERNEL);
- @@ -2310,13 +2345,6 @@ int ocelot_init(struct ocelot *ocelot)
- ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_SRC + port);
- }
-
- - /* Configure and enable the CPU port. */
- - ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, cpu);
- - ocelot_write_rix(ocelot, BIT(cpu), ANA_PGID_PGID, PGID_CPU);
- - ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_RECV_ENA |
- - ANA_PORT_PORT_CFG_PORTID_VAL(cpu),
- - ANA_PORT_PORT_CFG, cpu);
- -
- /* Allow broadcast MAC frames. */
- for (i = ocelot->num_phys_ports + 1; i < PGID_CPU; i++) {
- u32 val = ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports - 1, 0));
- @@ -2329,13 +2357,6 @@ int ocelot_init(struct ocelot *ocelot)
- ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_MCIPV4);
- ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_MCIPV6);
-
- - /* CPU port Injection/Extraction configuration */
- - ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
- - QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) |
- - QSYS_SWITCH_PORT_MODE_PORT_ENA,
- - QSYS_SWITCH_PORT_MODE, cpu);
- - ocelot_write_rix(ocelot, SYS_PORT_MODE_INCL_XTR_HDR(1) |
- - SYS_PORT_MODE_INCL_INJ_HDR(1), SYS_PORT_MODE, cpu);
- /* Allow manual injection via DEVCPU_QS registers, and byte swap these
- * registers endianness.
- */
- --- a/drivers/net/ethernet/mscc/ocelot.h
- +++ b/drivers/net/ethernet/mscc/ocelot.h
- @@ -427,6 +427,13 @@ struct ocelot_multicast {
- u16 ports;
- };
-
- +enum ocelot_tag_prefix {
- + OCELOT_TAG_PREFIX_DISABLED = 0,
- + OCELOT_TAG_PREFIX_NONE,
- + OCELOT_TAG_PREFIX_SHORT,
- + OCELOT_TAG_PREFIX_LONG,
- +};
- +
- struct ocelot_port;
-
- struct ocelot_stat_layout {
- @@ -455,6 +462,7 @@ struct ocelot {
-
- u8 num_phys_ports;
- u8 num_cpu_ports;
- + u8 cpu;
- struct ocelot_port **ports;
-
- u32 *lags;
- @@ -552,6 +560,10 @@ int ocelot_probe_port(struct ocelot *oce
- void __iomem *regs,
- struct phy_device *phy);
-
- +void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu,
- + enum ocelot_tag_prefix injection,
- + enum ocelot_tag_prefix extraction);
- +
- extern struct notifier_block ocelot_netdevice_nb;
- extern struct notifier_block ocelot_switchdev_nb;
- extern struct notifier_block ocelot_switchdev_blocking_nb;
- --- a/drivers/net/ethernet/mscc/ocelot_board.c
- +++ b/drivers/net/ethernet/mscc/ocelot_board.c
- @@ -373,6 +373,8 @@ static int mscc_ocelot_probe(struct plat
- sizeof(struct ocelot_port *), GFP_KERNEL);
-
- ocelot_init(ocelot);
- + ocelot_set_cpu_port(ocelot, ocelot->num_phys_ports,
- + OCELOT_TAG_PREFIX_NONE, OCELOT_TAG_PREFIX_NONE);
-
- for_each_available_child_of_node(ports, portnp) {
- struct ocelot_port_private *priv;
|