bcm63xx: expose the internal switch to b53
Allow b53 access to the internal switch of BCM6328, BCM6362 and BCM6368. Signed-off-by: Jonas Gorski <jogo@openwrt.org> SVN-Revision: 35306
This commit is contained in:
parent
bb0118c66f
commit
17d51121a6
1 changed files with 169 additions and 0 deletions
|
@ -0,0 +1,169 @@
|
||||||
|
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h
|
||||||
|
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
|
||||||
|
@@ -364,6 +364,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"
|
||||||
|
@@ -2013,7 +2014,8 @@ static int __devexit bcm_enet_remove(str
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-struct platform_driver bcm63xx_enet_driver = {
|
||||||
|
+
|
||||||
|
+static struct platform_driver bcm63xx_enet_driver = {
|
||||||
|
.probe = bcm_enet_probe,
|
||||||
|
.remove = __devexit_p(bcm_enet_remove),
|
||||||
|
.driver = {
|
||||||
|
@@ -2022,6 +2024,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
|
||||||
|
*/
|
||||||
|
@@ -2270,29 +2308,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));
|
||||||
|
@@ -2760,6 +2775,9 @@ static int __devinit bcm_enetsw_probe(st
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* stop if shared driver failed, assume driver->probe will be
|
||||||
|
* called in the same order we register devices (correct ?) */
|
||||||
|
@@ -2847,6 +2865,43 @@ static int __devinit bcm_enetsw_probe(st
|
||||||
|
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_put_clk:
|
||||||
|
@@ -2877,6 +2932,9 @@ static int __devexit bcm_enetsw_remove(s
|
||||||
|
priv = netdev_priv(dev);
|
||||||
|
unregister_netdev(dev);
|
||||||
|
|
||||||
|
+ /* remove switch */
|
||||||
|
+ bcmenet_switch_unregister(priv);
|
||||||
|
+
|
||||||
|
/* release device resources */
|
||||||
|
iounmap(priv->base);
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
Loading…
Reference in a new issue