1 From 3867c2586c0be529d3cb851b34f58d7d97be7c00 Mon Sep 17 00:00:00 2001
2 From: Jonas Gorski <jogo@openwrt.org>
3 Date: Tue, 29 Jan 2013 11:03:29 +0100
4 Subject: [PATCH 078/118] bcm63xx_enet: add b53 support
7 drivers/net/ethernet/broadcom/bcm63xx_enet.c | 106 ++++++++++++++++++++------
8 drivers/net/ethernet/broadcom/bcm63xx_enet.h | 3 +
9 2 files changed, 85 insertions(+), 24 deletions(-)
11 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
12 +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
14 #include <linux/dma-mapping.h>
15 #include <linux/platform_device.h>
16 #include <linux/if_vlan.h>
17 +#include <linux/platform_data/b53.h>
19 #include <bcm63xx_dev_enet.h>
20 #include "bcm63xx_enet.h"
21 @@ -2013,7 +2014,8 @@ static int __devexit bcm_enet_remove(str
25 -struct platform_driver bcm63xx_enet_driver = {
27 +static struct platform_driver bcm63xx_enet_driver = {
28 .probe = bcm_enet_probe,
29 .remove = __devexit_p(bcm_enet_remove),
31 @@ -2022,6 +2024,42 @@ struct platform_driver bcm63xx_enet_driv
35 +struct b53_platform_data bcm63xx_b53_pdata = {
40 +struct platform_device bcm63xx_b53_dev = {
41 + .name = "b53-switch",
44 + .platform_data = &bcm63xx_b53_pdata,
48 +static int bcmenet_switch_register(struct bcm_enet_priv *priv, u16 port_mask)
52 + bcm63xx_b53_pdata.regs = priv->base;
53 + bcm63xx_b53_pdata.enabled_ports = port_mask;
54 + bcm63xx_b53_pdata.alias = priv->net_dev->name;
56 + ret = platform_device_register(&bcm63xx_b53_dev);
58 + priv->b53_device = &bcm63xx_b53_dev;
63 +static void bcmenet_switch_unregister(struct bcm_enet_priv *priv)
65 + if (priv->b53_device)
66 + platform_device_unregister(&bcm63xx_b53_dev);
68 + priv->b53_device = NULL;
72 * switch mii access callbacks
74 @@ -2270,29 +2308,6 @@ static int bcm_enetsw_open(struct net_de
75 enetsw_writeb(priv, rgmii_ctrl, ENETSW_RGMII_CTRL_REG(i));
79 - val = enetsw_readb(priv, ENETSW_GMCR_REG);
80 - val |= ENETSW_GMCR_RST_MIB_MASK;
81 - enetsw_writeb(priv, val, ENETSW_GMCR_REG);
83 - val &= ~ENETSW_GMCR_RST_MIB_MASK;
84 - enetsw_writeb(priv, val, ENETSW_GMCR_REG);
87 - /* force CPU port state */
88 - val = enetsw_readb(priv, ENETSW_IMPOV_REG);
89 - val |= ENETSW_IMPOV_FORCE_MASK | ENETSW_IMPOV_LINKUP_MASK;
90 - enetsw_writeb(priv, val, ENETSW_IMPOV_REG);
92 - /* enable switch forward engine */
93 - val = enetsw_readb(priv, ENETSW_SWMODE_REG);
94 - val |= ENETSW_SWMODE_FWD_EN_MASK;
95 - enetsw_writeb(priv, val, ENETSW_SWMODE_REG);
97 - /* enable jumbo on all ports */
98 - enetsw_writel(priv, 0x1ff, ENETSW_JMBCTL_PORT_REG);
99 - enetsw_writew(priv, 9728, ENETSW_JMBCTL_MAXSIZE_REG);
101 /* initialize flow control buffer allocation */
102 enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
103 ENETDMA_BUFALLOC_REG(priv->rx_chan));
104 @@ -2760,6 +2775,9 @@ static int __devinit bcm_enetsw_probe(st
105 struct bcm63xx_enetsw_platform_data *pd;
106 struct resource *res_mem;
107 int ret, irq_rx, irq_tx;
108 + unsigned i, num_ports = 0;
109 + u16 port_mask = BIT(8);
112 /* stop if shared driver failed, assume driver->probe will be
113 * called in the same order we register devices (correct ?) */
114 @@ -2847,6 +2865,43 @@ static int __devinit bcm_enetsw_probe(st
119 + val = enetsw_readb(priv, ENETSW_GMCR_REG);
120 + val |= ENETSW_GMCR_RST_MIB_MASK;
121 + enetsw_writeb(priv, val, ENETSW_GMCR_REG);
123 + val &= ~ENETSW_GMCR_RST_MIB_MASK;
124 + enetsw_writeb(priv, val, ENETSW_GMCR_REG);
127 + /* force CPU port state */
128 + val = enetsw_readb(priv, ENETSW_IMPOV_REG);
129 + val |= ENETSW_IMPOV_FORCE_MASK | ENETSW_IMPOV_LINKUP_MASK;
130 + enetsw_writeb(priv, val, ENETSW_IMPOV_REG);
132 + /* enable switch forward engine */
133 + val = enetsw_readb(priv, ENETSW_SWMODE_REG);
134 + val |= ENETSW_SWMODE_FWD_EN_MASK;
135 + enetsw_writeb(priv, val, ENETSW_SWMODE_REG);
137 + /* enable jumbo on all ports */
138 + enetsw_writel(priv, 0x1ff, ENETSW_JMBCTL_PORT_REG);
139 + enetsw_writew(priv, 9728, ENETSW_JMBCTL_MAXSIZE_REG);
141 + for (i = 0; i < priv->num_ports; i++) {
142 + struct bcm63xx_enetsw_port *port = &priv->used_ports[i];
148 + port_mask |= BIT(i);
151 + /* only register if there is more than one external port */
153 + bcmenet_switch_register(priv, port_mask);
158 @@ -2877,6 +2932,9 @@ static int __devexit bcm_enetsw_remove(s
159 priv = netdev_priv(dev);
160 unregister_netdev(dev);
162 + /* remove switch */
163 + bcmenet_switch_unregister(priv);
165 /* release device resources */
167 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
168 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h
169 +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
170 @@ -336,6 +336,9 @@ struct bcm_enet_priv {
171 struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT];
172 int sw_port_link[ENETSW_MAX_PORT];
174 + /* platform device for associated switch */
175 + struct platform_device *b53_device;
177 /* used to poll switch port state */
178 struct timer_list swphy_poll;
179 spinlock_t enetsw_mdio_lock;