aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-11-11 21:55:16 +0900
committerDavid S. Miller <davem@davemloft.net>2017-11-11 21:55:16 +0900
commit93f7ea74371273db09b30b9a19ff4d5de22f464d (patch)
treebf15a534c047a6e84ac335399f45f33e6d5e011b
parentMerge branch 'dsa-lan9303-IGMP-handling' (diff)
parentnet: dsa: b53: Turn on Broadcom tags (diff)
downloadlinux-dev-93f7ea74371273db09b30b9a19ff4d5de22f464d.tar.xz
linux-dev-93f7ea74371273db09b30b9a19ff4d5de22f464d.zip
Merge branch 'dsa-b53-Turn-on-Broadcom-tags'
Florian Fainelli says: ==================== net: dsa: b53: Turn on Broadcom tags This was long overdue, with this patch series, the b53 driver now turns on Broadcom tags except for 5325 and 5365 which use an older format that we do not support yet (TBD). First patch is necessary in order for bgmac, used on BCM5301X and Northstar Plus to work correctly and successfully send ARP packets back to the requsester. Second patch is actually a bug fix, but because net/master and net-next/master diverge in that area, I am targeting net-next/master here. Finally, the last patch enables Broadcom tags after checking that the CPU port selected is either, 5, 7 or 8, since those are the only valid combinations given currently supported HW. Changes in v3: - guarded padding with netdev_uses_dsa() to let the non-DSA use cases not have a performance hit for smaller packets - added missing select NET_DSA_TAG_BRCM to drivers/net/dsa/b53/Kconfig Changes in v2: - moved a hunk between patch 2 and patch 3 to avoid a bisectability issue ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/dsa/b53/Kconfig1
-rw-r--r--drivers/net/dsa/b53/b53_common.c58
-rw-r--r--drivers/net/ethernet/broadcom/bgmac.c16
3 files changed, 60 insertions, 15 deletions
diff --git a/drivers/net/dsa/b53/Kconfig b/drivers/net/dsa/b53/Kconfig
index 27f32a50df57..b413d100c6b3 100644
--- a/drivers/net/dsa/b53/Kconfig
+++ b/drivers/net/dsa/b53/Kconfig
@@ -1,6 +1,7 @@
menuconfig B53
tristate "Broadcom BCM53xx managed switch support"
depends on NET_DSA
+ select NET_DSA_TAG_BRCM
help
This driver adds support for Broadcom managed switch chips. It supports
BCM5325E, BCM5365, BCM539x, BCM53115 and BCM53125 as well as BCM63XX
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index a7ca62ba27b7..44a9a03bff55 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -325,7 +325,6 @@ static void b53_get_vlan_entry(struct b53_device *dev, u16 vid,
static void b53_set_forwarding(struct b53_device *dev, int enable)
{
- struct dsa_switch *ds = dev->ds;
u8 mgmt;
b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt);
@@ -337,14 +336,11 @@ static void b53_set_forwarding(struct b53_device *dev, int enable)
b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt);
- /* Include IMP port in dumb forwarding mode when no tagging protocol is
- * set
+ /* Include IMP port in dumb forwarding mode
*/
- if (ds->ops->get_tag_protocol(ds) == DSA_TAG_PROTO_NONE) {
- b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, &mgmt);
- mgmt |= B53_MII_DUMB_FWDG_EN;
- b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt);
- }
+ b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, &mgmt);
+ mgmt |= B53_MII_DUMB_FWDG_EN;
+ b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt);
}
static void b53_enable_vlan(struct b53_device *dev, bool enable)
@@ -505,7 +501,7 @@ EXPORT_SYMBOL(b53_imp_vlan_setup);
int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
{
struct b53_device *dev = ds->priv;
- unsigned int cpu_port = dev->cpu_port;
+ unsigned int cpu_port = ds->ports[port].cpu_dp->index;
u16 pvlan;
/* Clear the Rx and Tx disable bits and set to no spanning tree */
@@ -612,6 +608,8 @@ static void b53_enable_cpu_port(struct b53_device *dev, int port)
PORT_CTRL_RX_MCST_EN |
PORT_CTRL_RX_UCST_EN;
b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), port_ctrl);
+
+ b53_brcm_hdr_setup(dev->ds, port);
}
static void b53_enable_mib(struct b53_device *dev)
@@ -1054,7 +1052,6 @@ void b53_vlan_add(struct dsa_switch *ds, int port,
struct b53_device *dev = ds->priv;
bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
- unsigned int cpu_port = dev->cpu_port;
struct b53_vlan *vl;
u16 vid;
@@ -1063,12 +1060,11 @@ void b53_vlan_add(struct dsa_switch *ds, int port,
b53_get_vlan_entry(dev, vid, vl);
- vl->members |= BIT(port) | BIT(cpu_port);
+ vl->members |= BIT(port);
if (untagged)
vl->untag |= BIT(port);
else
vl->untag &= ~BIT(port);
- vl->untag &= ~BIT(cpu_port);
b53_set_vlan_entry(dev, vid, vl);
b53_fast_age_vlan(dev, vid);
@@ -1432,8 +1428,8 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br)
b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg);
} else {
b53_get_vlan_entry(dev, pvid, vl);
- vl->members |= BIT(port) | BIT(dev->cpu_port);
- vl->untag |= BIT(port) | BIT(dev->cpu_port);
+ vl->members |= BIT(port) | BIT(cpu_port);
+ vl->untag |= BIT(port) | BIT(cpu_port);
b53_set_vlan_entry(dev, pvid, vl);
}
}
@@ -1482,9 +1478,41 @@ void b53_br_fast_age(struct dsa_switch *ds, int port)
}
EXPORT_SYMBOL(b53_br_fast_age);
+static bool b53_can_enable_brcm_tags(struct dsa_switch *ds)
+{
+ unsigned int brcm_tag_mask;
+ unsigned int i;
+
+ /* Broadcom switches will accept enabling Broadcom tags on the
+ * following ports: 5, 7 and 8, any other port is not supported
+ */
+ brcm_tag_mask = BIT(B53_CPU_PORT_25) | BIT(7) | BIT(B53_CPU_PORT);
+
+ for (i = 0; i < ds->num_ports; i++) {
+ if (dsa_is_cpu_port(ds, i)) {
+ if (!(BIT(i) & brcm_tag_mask)) {
+ dev_warn(ds->dev,
+ "Port %d is not Broadcom tag capable\n",
+ i);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
static enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds)
{
- return DSA_TAG_PROTO_NONE;
+ struct b53_device *dev = ds->priv;
+
+ /* Older models support a different tag format that we do not
+ * support in net/dsa/tag_brcm.c yet.
+ */
+ if (is5325(dev) || is5365(dev) || !b53_can_enable_brcm_tags(ds))
+ return DSA_TAG_PROTO_NONE;
+ else
+ return DSA_TAG_PROTO_BRCM;
}
int b53_mirror_add(struct dsa_switch *ds, int port,
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
index 48d672b204a4..1d96cd594ade 100644
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -15,6 +15,7 @@
#include <linux/bcm47xx_nvram.h>
#include <linux/phy.h>
#include <linux/phy_fixed.h>
+#include <net/dsa.h>
#include "bgmac.h"
static bool bgmac_wait_value(struct bgmac *bgmac, u16 reg, u32 mask,
@@ -127,6 +128,8 @@ bgmac_dma_tx_add_buf(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
dma_desc->ctl1 = cpu_to_le32(ctl1);
}
+#define ENET_BRCM_TAG_LEN 4
+
static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac,
struct bgmac_dma_ring *ring,
struct sk_buff *skb)
@@ -139,6 +142,18 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac,
u32 flags;
int i;
+ /* The Ethernet switch we are interfaced with needs packets to be at
+ * least 64 bytes (including FCS) otherwise they will be discarded when
+ * they enter the switch port logic. When Broadcom tags are enabled, we
+ * need to make sure that packets are at least 68 bytes
+ * (including FCS and tag) because the length verification is done after
+ * the Broadcom tag is stripped off the ingress packet.
+ */
+ if (netdev_uses_dsa(net_dev)) {
+ if (skb_put_padto(skb, ETH_ZLEN + ENET_BRCM_TAG_LEN))
+ goto err_stats;
+ }
+
if (skb->len > BGMAC_DESC_CTL1_LEN) {
netdev_err(bgmac->net_dev, "Too long skb (%d)\n", skb->len);
goto err_drop;
@@ -225,6 +240,7 @@ err_dma_head:
err_drop:
dev_kfree_skb(skb);
+err_stats:
net_dev->stats.tx_dropped++;
net_dev->stats.tx_errors++;
return NETDEV_TX_OK;