/branches/18.06.1/target/linux/brcm63xx/patches-4.14/423-bcm63xx_enet_add_b53_support.patch |
@@ -0,0 +1,169 @@ |
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h |
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h |
@@ -332,6 +332,9 @@ struct bcm_enet_priv { |
struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT]; |
int sw_port_link[ENETSW_MAX_PORT]; |
|
+ /* platform device for associated switch */ |
+ struct platform_device *b53_device; |
+ |
/* used to poll switch port state */ |
struct timer_list swphy_poll; |
spinlock_t enetsw_mdio_lock; |
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c |
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c |
@@ -30,6 +30,7 @@ |
#include <linux/dma-mapping.h> |
#include <linux/platform_device.h> |
#include <linux/if_vlan.h> |
+#include <linux/platform_data/b53.h> |
|
#include <bcm63xx_dev_enet.h> |
#include "bcm63xx_enet.h" |
@@ -1936,7 +1937,8 @@ static int bcm_enet_remove(struct platfo |
return 0; |
} |
|
-struct platform_driver bcm63xx_enet_driver = { |
+ |
+static struct platform_driver bcm63xx_enet_driver = { |
.probe = bcm_enet_probe, |
.remove = bcm_enet_remove, |
.driver = { |
@@ -1945,6 +1947,42 @@ struct platform_driver bcm63xx_enet_driv |
}, |
}; |
|
+struct b53_platform_data bcm63xx_b53_pdata = { |
+ .chip_id = 0x6300, |
+ .big_endian = 1, |
+}; |
+ |
+struct platform_device bcm63xx_b53_dev = { |
+ .name = "b53-switch", |
+ .id = -1, |
+ .dev = { |
+ .platform_data = &bcm63xx_b53_pdata, |
+ }, |
+}; |
+ |
+static int bcmenet_switch_register(struct bcm_enet_priv *priv, u16 port_mask) |
+{ |
+ int ret; |
+ |
+ bcm63xx_b53_pdata.regs = priv->base; |
+ bcm63xx_b53_pdata.enabled_ports = port_mask; |
+ bcm63xx_b53_pdata.alias = priv->net_dev->name; |
+ |
+ ret = platform_device_register(&bcm63xx_b53_dev); |
+ if (!ret) |
+ priv->b53_device = &bcm63xx_b53_dev; |
+ |
+ return ret; |
+} |
+ |
+static void bcmenet_switch_unregister(struct bcm_enet_priv *priv) |
+{ |
+ if (priv->b53_device) |
+ platform_device_unregister(&bcm63xx_b53_dev); |
+ |
+ priv->b53_device = NULL; |
+} |
+ |
/* |
* switch mii access callbacks |
*/ |
@@ -2203,29 +2241,6 @@ static int bcm_enetsw_open(struct net_de |
enetsw_writeb(priv, rgmii_ctrl, ENETSW_RGMII_CTRL_REG(i)); |
} |
|
- /* reset mib */ |
- val = enetsw_readb(priv, ENETSW_GMCR_REG); |
- val |= ENETSW_GMCR_RST_MIB_MASK; |
- enetsw_writeb(priv, val, ENETSW_GMCR_REG); |
- mdelay(1); |
- val &= ~ENETSW_GMCR_RST_MIB_MASK; |
- enetsw_writeb(priv, val, ENETSW_GMCR_REG); |
- mdelay(1); |
- |
- /* force CPU port state */ |
- val = enetsw_readb(priv, ENETSW_IMPOV_REG); |
- val |= ENETSW_IMPOV_FORCE_MASK | ENETSW_IMPOV_LINKUP_MASK; |
- enetsw_writeb(priv, val, ENETSW_IMPOV_REG); |
- |
- /* enable switch forward engine */ |
- val = enetsw_readb(priv, ENETSW_SWMODE_REG); |
- val |= ENETSW_SWMODE_FWD_EN_MASK; |
- enetsw_writeb(priv, val, ENETSW_SWMODE_REG); |
- |
- /* enable jumbo on all ports */ |
- enetsw_writel(priv, 0x1ff, ENETSW_JMBCTL_PORT_REG); |
- enetsw_writew(priv, 9728, ENETSW_JMBCTL_MAXSIZE_REG); |
- |
/* initialize flow control buffer allocation */ |
enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0, |
ENETDMA_BUFALLOC_REG(priv->rx_chan)); |
@@ -2684,6 +2699,9 @@ static int bcm_enetsw_probe(struct platf |
struct bcm63xx_enetsw_platform_data *pd; |
struct resource *res_mem; |
int ret, irq_rx, irq_tx; |
+ unsigned i, num_ports = 0; |
+ u16 port_mask = BIT(8); |
+ u8 val; |
|
if (!bcm_enet_shared_base[0]) |
return -EPROBE_DEFER; |
@@ -2766,6 +2784,43 @@ static int bcm_enetsw_probe(struct platf |
priv->pdev = pdev; |
priv->net_dev = dev; |
|
+ /* reset mib */ |
+ val = enetsw_readb(priv, ENETSW_GMCR_REG); |
+ val |= ENETSW_GMCR_RST_MIB_MASK; |
+ enetsw_writeb(priv, val, ENETSW_GMCR_REG); |
+ mdelay(1); |
+ val &= ~ENETSW_GMCR_RST_MIB_MASK; |
+ enetsw_writeb(priv, val, ENETSW_GMCR_REG); |
+ mdelay(1); |
+ |
+ /* force CPU port state */ |
+ val = enetsw_readb(priv, ENETSW_IMPOV_REG); |
+ val |= ENETSW_IMPOV_FORCE_MASK | ENETSW_IMPOV_LINKUP_MASK; |
+ enetsw_writeb(priv, val, ENETSW_IMPOV_REG); |
+ |
+ /* enable switch forward engine */ |
+ val = enetsw_readb(priv, ENETSW_SWMODE_REG); |
+ val |= ENETSW_SWMODE_FWD_EN_MASK; |
+ enetsw_writeb(priv, val, ENETSW_SWMODE_REG); |
+ |
+ /* enable jumbo on all ports */ |
+ enetsw_writel(priv, 0x1ff, ENETSW_JMBCTL_PORT_REG); |
+ enetsw_writew(priv, 9728, ENETSW_JMBCTL_MAXSIZE_REG); |
+ |
+ for (i = 0; i < priv->num_ports; i++) { |
+ struct bcm63xx_enetsw_port *port = &priv->used_ports[i]; |
+ |
+ if (!port->used) |
+ continue; |
+ |
+ num_ports++; |
+ port_mask |= BIT(i); |
+ } |
+ |
+ /* only register if there is more than one external port */ |
+ if (num_ports > 1) |
+ bcmenet_switch_register(priv, port_mask); |
+ |
return 0; |
|
out_disable_clk: |
@@ -2787,6 +2842,9 @@ static int bcm_enetsw_remove(struct plat |
priv = netdev_priv(dev); |
unregister_netdev(dev); |
|
+ /* remove switch */ |
+ bcmenet_switch_unregister(priv); |
+ |
clk_disable_unprepare(priv->mac_clk); |
|
free_netdev(dev); |