From 08a012619a0349b8e02797bdfe57051fe7df3d3b Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Mon, 9 May 2016 13:22:50 -0400 Subject: [PATCH] net: dsa: mv88e6xxx: factorize global setup Every driver is calling mv88e6xxx_setup_global after mv88e6xxx_setup_common. Call the former in the latter. Signed-off-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6123.c | 4 - drivers/net/dsa/mv88e6131.c | 4 - drivers/net/dsa/mv88e6171.c | 4 - drivers/net/dsa/mv88e6352.c | 4 - drivers/net/dsa/mv88e6xxx.c | 341 ++++++++++++++++++------------------ drivers/net/dsa/mv88e6xxx.h | 1 - 6 files changed, 172 insertions(+), 186 deletions(-) diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index fadec7a0e6b5..d74695ac0be6 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -58,10 +58,6 @@ static int mv88e6123_setup_global(struct dsa_switch *ds) int ret; u32 reg; - ret = mv88e6xxx_setup_global(ds); - if (ret) - return ret; - /* Disable the PHY polling unit (since there won't be any * external PHYs to poll), don't discard packets with * excessive collisions, and mask all interrupt sources. diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 25ed82372df5..e22ca7b7fa51 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -65,10 +65,6 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) int ret; u32 reg; - ret = mv88e6xxx_setup_global(ds); - if (ret) - return ret; - /* Enable the PHY polling unit, don't discard packets with * excessive collisions, use a weighted fair queueing scheme * to arbitrate between packet queues, set the maximum frame diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index caaa4b66abc1..4bbf2e1a90aa 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -65,10 +65,6 @@ static int mv88e6171_setup_global(struct dsa_switch *ds) int ret; u32 reg; - ret = mv88e6xxx_setup_global(ds); - if (ret) - return ret; - /* Discard packets with excessive collisions, mask all * interrupt sources, enable PPU. */ diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index 470789a3f8ec..3e0be872df95 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c @@ -84,10 +84,6 @@ static int mv88e6352_setup_global(struct dsa_switch *ds) int ret; u32 reg; - ret = mv88e6xxx_setup_global(ds); - if (ret) - return ret; - /* Discard packets with excessive collisions, * mask all interrupt sources, enable PPU (bit 14, undocumented). */ diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index b631a5d07ba0..32b36a8fb446 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -2920,6 +2920,177 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds) return 0; } +static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps) +{ + int err; + int i; + + /* Set the default address aging time to 5 minutes, and + * enable address learn messages to be sent to all message + * ports. + */ + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_CONTROL, + 0x0140 | GLOBAL_ATU_CONTROL_LEARN2ALL); + if (err) + return err; + + /* Configure the IP ToS mapping registers. */ + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_0, 0x0000); + if (err) + return err; + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_1, 0x0000); + if (err) + return err; + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_2, 0x5555); + if (err) + return err; + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_3, 0x5555); + if (err) + return err; + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_4, 0xaaaa); + if (err) + return err; + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_5, 0xaaaa); + if (err) + return err; + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_6, 0xffff); + if (err) + return err; + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_7, 0xffff); + if (err) + return err; + + /* Configure the IEEE 802.1p priority mapping register. */ + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IEEE_PRI, 0xfa41); + if (err) + return err; + + /* Send all frames with destination addresses matching + * 01:80:c2:00:00:0x to the CPU port. + */ + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_MGMT_EN_0X, 0xffff); + if (err) + return err; + + /* Ignore removed tag data on doubly tagged packets, disable + * flow control messages, force flow control priority to the + * highest, and send all special multicast frames to the CPU + * port at the highest priority. + */ + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SWITCH_MGMT, + 0x7 | GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x70 | + GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI); + if (err) + return err; + + /* Program the DSA routing table. */ + for (i = 0; i < 32; i++) { + int nexthop = 0x1f; + + if (ps->ds->pd->rtable && + i != ps->ds->index && i < ps->ds->dst->pd->nr_chips) + nexthop = ps->ds->pd->rtable[i] & 0x1f; + + err = _mv88e6xxx_reg_write( + ps, REG_GLOBAL2, + GLOBAL2_DEVICE_MAPPING, + GLOBAL2_DEVICE_MAPPING_UPDATE | + (i << GLOBAL2_DEVICE_MAPPING_TARGET_SHIFT) | nexthop); + if (err) + return err; + } + + /* Clear all trunk masks. */ + for (i = 0; i < 8; i++) { + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_TRUNK_MASK, + 0x8000 | + (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) | + ((1 << ps->info->num_ports) - 1)); + if (err) + return err; + } + + /* Clear all trunk mappings. */ + for (i = 0; i < 16; i++) { + err = _mv88e6xxx_reg_write( + ps, REG_GLOBAL2, + GLOBAL2_TRUNK_MAPPING, + GLOBAL2_TRUNK_MAPPING_UPDATE | + (i << GLOBAL2_TRUNK_MAPPING_ID_SHIFT)); + if (err) + return err; + } + + if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || + mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || + mv88e6xxx_6320_family(ps)) { + /* Send all frames with destination addresses matching + * 01:80:c2:00:00:2x to the CPU port. + */ + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, + GLOBAL2_MGMT_EN_2X, 0xffff); + if (err) + return err; + + /* Initialise cross-chip port VLAN table to reset + * defaults. + */ + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, + GLOBAL2_PVT_ADDR, 0x9000); + if (err) + return err; + + /* Clear the priority override table. */ + for (i = 0; i < 16; i++) { + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, + GLOBAL2_PRIO_OVERRIDE, + 0x8000 | (i << 8)); + if (err) + return err; + } + } + + if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || + mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || + mv88e6xxx_6185_family(ps) || mv88e6xxx_6095_family(ps) || + mv88e6xxx_6320_family(ps)) { + /* Disable ingress rate limiting by resetting all + * ingress rate limit registers to their initial + * state. + */ + for (i = 0; i < ps->info->num_ports; i++) { + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, + GLOBAL2_INGRESS_OP, + 0x9000 | (i << 8)); + if (err) + return err; + } + } + + /* Clear the statistics counters for all ports */ + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_STATS_OP, + GLOBAL_STATS_OP_FLUSH_ALL); + if (err) + return err; + + /* Wait for the flush to complete. */ + err = _mv88e6xxx_stats_wait(ps); + if (err) + return err; + + /* Clear all ATU entries */ + err = _mv88e6xxx_atu_flush(ps, 0, true); + if (err) + return err; + + /* Clear all the VTU and STU entries */ + err = _mv88e6xxx_vtu_stu_flush(ps); + if (err < 0) + return err; + + return err; +} + int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps) { int err; @@ -2937,179 +3108,11 @@ int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps) mutex_lock(&ps->smi_mutex); err = mv88e6xxx_switch_reset(ps); - - mutex_unlock(&ps->smi_mutex); - - return err; -} - -int mv88e6xxx_setup_global(struct dsa_switch *ds) -{ - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); - int err; - int i; - - mutex_lock(&ps->smi_mutex); - /* Set the default address aging time to 5 minutes, and - * enable address learn messages to be sent to all message - * ports. - */ - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_CONTROL, - 0x0140 | GLOBAL_ATU_CONTROL_LEARN2ALL); if (err) goto unlock; - /* Configure the IP ToS mapping registers. */ - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_0, 0x0000); - if (err) - goto unlock; - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_1, 0x0000); - if (err) - goto unlock; - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_2, 0x5555); - if (err) - goto unlock; - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_3, 0x5555); - if (err) - goto unlock; - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_4, 0xaaaa); - if (err) - goto unlock; - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_5, 0xaaaa); - if (err) - goto unlock; - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_6, 0xffff); - if (err) - goto unlock; - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_7, 0xffff); - if (err) - goto unlock; + err = mv88e6xxx_setup_global(ps); - /* Configure the IEEE 802.1p priority mapping register. */ - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IEEE_PRI, 0xfa41); - if (err) - goto unlock; - - /* Send all frames with destination addresses matching - * 01:80:c2:00:00:0x to the CPU port. - */ - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_MGMT_EN_0X, 0xffff); - if (err) - goto unlock; - - /* Ignore removed tag data on doubly tagged packets, disable - * flow control messages, force flow control priority to the - * highest, and send all special multicast frames to the CPU - * port at the highest priority. - */ - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SWITCH_MGMT, - 0x7 | GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x70 | - GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI); - if (err) - goto unlock; - - /* Program the DSA routing table. */ - for (i = 0; i < 32; i++) { - int nexthop = 0x1f; - - if (ds->pd->rtable && - i != ds->index && i < ds->dst->pd->nr_chips) - nexthop = ds->pd->rtable[i] & 0x1f; - - err = _mv88e6xxx_reg_write( - ps, REG_GLOBAL2, - GLOBAL2_DEVICE_MAPPING, - GLOBAL2_DEVICE_MAPPING_UPDATE | - (i << GLOBAL2_DEVICE_MAPPING_TARGET_SHIFT) | nexthop); - if (err) - goto unlock; - } - - /* Clear all trunk masks. */ - for (i = 0; i < 8; i++) { - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_TRUNK_MASK, - 0x8000 | - (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) | - ((1 << ps->info->num_ports) - 1)); - if (err) - goto unlock; - } - - /* Clear all trunk mappings. */ - for (i = 0; i < 16; i++) { - err = _mv88e6xxx_reg_write( - ps, REG_GLOBAL2, - GLOBAL2_TRUNK_MAPPING, - GLOBAL2_TRUNK_MAPPING_UPDATE | - (i << GLOBAL2_TRUNK_MAPPING_ID_SHIFT)); - if (err) - goto unlock; - } - - if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || - mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || - mv88e6xxx_6320_family(ps)) { - /* Send all frames with destination addresses matching - * 01:80:c2:00:00:2x to the CPU port. - */ - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, - GLOBAL2_MGMT_EN_2X, 0xffff); - if (err) - goto unlock; - - /* Initialise cross-chip port VLAN table to reset - * defaults. - */ - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, - GLOBAL2_PVT_ADDR, 0x9000); - if (err) - goto unlock; - - /* Clear the priority override table. */ - for (i = 0; i < 16; i++) { - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, - GLOBAL2_PRIO_OVERRIDE, - 0x8000 | (i << 8)); - if (err) - goto unlock; - } - } - - if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || - mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || - mv88e6xxx_6185_family(ps) || mv88e6xxx_6095_family(ps) || - mv88e6xxx_6320_family(ps)) { - /* Disable ingress rate limiting by resetting all - * ingress rate limit registers to their initial - * state. - */ - for (i = 0; i < ps->info->num_ports; i++) { - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, - GLOBAL2_INGRESS_OP, - 0x9000 | (i << 8)); - if (err) - goto unlock; - } - } - - /* Clear the statistics counters for all ports */ - err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_STATS_OP, - GLOBAL_STATS_OP_FLUSH_ALL); - if (err) - goto unlock; - - /* Wait for the flush to complete. */ - err = _mv88e6xxx_stats_wait(ps); - if (err < 0) - goto unlock; - - /* Clear all ATU entries */ - err = _mv88e6xxx_atu_flush(ps, 0, true); - if (err < 0) - goto unlock; - - /* Clear all the VTU and STU entries */ - err = _mv88e6xxx_vtu_stu_flush(ps); unlock: mutex_unlock(&ps->smi_mutex); diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index efd6ebde8eb4..62f6fc9510aa 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -590,7 +590,6 @@ const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, int mv88e6xxx_setup_ports(struct dsa_switch *ds); int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps); -int mv88e6xxx_setup_global(struct dsa_switch *ds); int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg); int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr, int reg, u16 val);