net: dsa: b53: Enable Broadcom tags for 531x5/539x families

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>
This commit is contained in:
Florian Fainelli 2020-01-07 21:06:06 -08:00 committed by David S. Miller
parent 4d776482ec
commit 8fab459e69

View 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;
}