]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
net: dsa: b53: Enable Broadcom tags for 531x5/539x families
authorFlorian Fainelli <f.fainelli@gmail.com>
Wed, 8 Jan 2020 05:06:06 +0000 (21:06 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 9 Jan 2020 00:01:13 +0000 (16:01 -0800)
The BCM531x5 and BCM539x families require that the IMP port be enabled
within the management page and that management mode (SM_SW_FWD_MODE) be
turned on. Once this is done, everything works as expected, including
multicast with standalone DSA devices or bridge devices.

Because such switches are frequencly cascaded with other internal
Broadcom switches on which we want to enable Broadcom tags, update
b53_can_enable_brcm_tags() to check the kind of DSA master tagging
protocol being used, if it is one of the two supported Broadcom tagging
protocols, force DSA_TAG_PROTO_NONE.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/b53/b53_common.c

index 2b530a31ef0fdafc524514d68e9272d363ba7bd3..06049751215925d3a9f33856ae0b31d4f491db08 100644 (file)
@@ -371,8 +371,6 @@ static void b53_enable_vlan(struct b53_device *dev, bool enable,
                b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, &vc5);
        }
 
-       mgmt &= ~SM_SW_FWD_MODE;
-
        if (enable) {
                vc0 |= VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID;
                vc1 |= VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN;
@@ -594,6 +592,22 @@ void b53_brcm_hdr_setup(struct dsa_switch *ds, int port)
                break;
        }
 
+       /* Enable management mode if tagging is requested */
+       b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &hdr_ctl);
+       if (tag_en)
+               hdr_ctl |= SM_SW_FWD_MODE;
+       else
+               hdr_ctl &= ~SM_SW_FWD_MODE;
+       b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, hdr_ctl);
+
+       /* Configure the appropriate IMP port */
+       b53_read8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &hdr_ctl);
+       if (port == 8)
+               hdr_ctl |= GC_FRM_MGMT_PORT_MII;
+       else if (port == 5)
+               hdr_ctl |= GC_FRM_MGMT_PORT_M;
+       b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, hdr_ctl);
+
        /* Enable Broadcom tags for IMP port */
        b53_read8(dev, B53_MGMT_PAGE, B53_BRCM_HDR, &hdr_ctl);
        if (tag_en)
@@ -1865,13 +1879,29 @@ static bool b53_possible_cpu_port(struct dsa_switch *ds, int port)
        return false;
 }
 
-static bool b53_can_enable_brcm_tags(struct dsa_switch *ds, int port)
+static bool b53_can_enable_brcm_tags(struct dsa_switch *ds, int port,
+                                    enum dsa_tag_protocol tag_protocol)
 {
        bool ret = b53_possible_cpu_port(ds, port);
 
-       if (!ret)
+       if (!ret) {
                dev_warn(ds->dev, "Port %d is not Broadcom tag capable\n",
                         port);
+               return ret;
+       }
+
+       switch (tag_protocol) {
+       case DSA_TAG_PROTO_BRCM:
+       case DSA_TAG_PROTO_BRCM_PREPEND:
+               dev_warn(ds->dev,
+                        "Port %d is stacked to Broadcom tag switch\n", port);
+               ret = false;
+               break;
+       default:
+               ret = true;
+               break;
+       }
+
        return ret;
 }
 
@@ -1881,12 +1911,10 @@ enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port,
        struct b53_device *dev = ds->priv;
 
        /* Older models (5325, 5365) support a different tag format that we do
-        * not support in net/dsa/tag_brcm.c yet. 539x and 531x5 require managed
-        * mode to be turned on which means we need to specifically manage ARL
-        * misses on multicast addresses (TBD).
+        * not support in net/dsa/tag_brcm.c yet.
         */
-       if (is5325(dev) || is5365(dev) || is539x(dev) || is531x5(dev) ||
-           !b53_can_enable_brcm_tags(ds, port)) {
+       if (is5325(dev) || is5365(dev) ||
+           !b53_can_enable_brcm_tags(ds, port, mprot)) {
                dev->tag_protocol = DSA_TAG_PROTO_NONE;
                goto out;
        }