brcm63xx: add preliminary support for 3.13
[openwrt.git] / target / linux / brcm63xx / patches-3.13 / 423-bcm63xx_enet_add_b53_support.patch
1 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h
2 +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
3 @@ -336,6 +336,9 @@ struct bcm_enet_priv {
4         struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT];
5         int sw_port_link[ENETSW_MAX_PORT];
6  
7 +       /* platform device for associated switch */
8 +       struct platform_device *b53_device;
9 +
10         /* used to poll switch port state */
11         struct timer_list swphy_poll;
12         spinlock_t enetsw_mdio_lock;
13 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
14 +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
15 @@ -30,6 +30,7 @@
16  #include <linux/dma-mapping.h>
17  #include <linux/platform_device.h>
18  #include <linux/if_vlan.h>
19 +#include <linux/platform_data/b53.h>
20  
21  #include <bcm63xx_dev_enet.h>
22  #include "bcm63xx_enet.h"
23 @@ -1978,7 +1979,8 @@ static int bcm_enet_remove(struct platfo
24         return 0;
25  }
26  
27 -struct platform_driver bcm63xx_enet_driver = {
28 +
29 +static struct platform_driver bcm63xx_enet_driver = {
30         .probe  = bcm_enet_probe,
31         .remove = bcm_enet_remove,
32         .driver = {
33 @@ -1987,6 +1989,42 @@ struct platform_driver bcm63xx_enet_driv
34         },
35  };
36  
37 +struct b53_platform_data bcm63xx_b53_pdata = {
38 +       .chip_id = 0x6300,
39 +       .big_endian = 1,
40 +};
41 +
42 +struct platform_device bcm63xx_b53_dev = {
43 +       .name           = "b53-switch",
44 +       .id             = -1,
45 +       .dev            = {
46 +               .platform_data = &bcm63xx_b53_pdata,
47 +       },
48 +};
49 +
50 +static int bcmenet_switch_register(struct bcm_enet_priv *priv, u16 port_mask)
51 +{
52 +       int ret;
53 +
54 +       bcm63xx_b53_pdata.regs = priv->base;
55 +       bcm63xx_b53_pdata.enabled_ports = port_mask;
56 +       bcm63xx_b53_pdata.alias = priv->net_dev->name;
57 +
58 +       ret = platform_device_register(&bcm63xx_b53_dev);
59 +       if (!ret)
60 +               priv->b53_device = &bcm63xx_b53_dev;
61 +
62 +       return ret;
63 +}
64 +
65 +static void bcmenet_switch_unregister(struct bcm_enet_priv *priv)
66 +{
67 +       if (priv->b53_device)
68 +               platform_device_unregister(&bcm63xx_b53_dev);
69 +
70 +       priv->b53_device = NULL;
71 +}
72 +
73  /*
74   * switch mii access callbacks
75   */
76 @@ -2240,29 +2278,6 @@ static int bcm_enetsw_open(struct net_de
77                 enetsw_writeb(priv, rgmii_ctrl, ENETSW_RGMII_CTRL_REG(i));
78         }
79  
80 -       /* reset mib */
81 -       val = enetsw_readb(priv, ENETSW_GMCR_REG);
82 -       val |= ENETSW_GMCR_RST_MIB_MASK;
83 -       enetsw_writeb(priv, val, ENETSW_GMCR_REG);
84 -       mdelay(1);
85 -       val &= ~ENETSW_GMCR_RST_MIB_MASK;
86 -       enetsw_writeb(priv, val, ENETSW_GMCR_REG);
87 -       mdelay(1);
88 -
89 -       /* force CPU port state */
90 -       val = enetsw_readb(priv, ENETSW_IMPOV_REG);
91 -       val |= ENETSW_IMPOV_FORCE_MASK | ENETSW_IMPOV_LINKUP_MASK;
92 -       enetsw_writeb(priv, val, ENETSW_IMPOV_REG);
93 -
94 -       /* enable switch forward engine */
95 -       val = enetsw_readb(priv, ENETSW_SWMODE_REG);
96 -       val |= ENETSW_SWMODE_FWD_EN_MASK;
97 -       enetsw_writeb(priv, val, ENETSW_SWMODE_REG);
98 -
99 -       /* enable jumbo on all ports */
100 -       enetsw_writel(priv, 0x1ff, ENETSW_JMBCTL_PORT_REG);
101 -       enetsw_writew(priv, 9728, ENETSW_JMBCTL_MAXSIZE_REG);
102 -
103         /* initialize flow control buffer allocation */
104         enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
105                         ENETDMA_BUFALLOC_REG(priv->rx_chan));
106 @@ -2722,6 +2737,9 @@ static int bcm_enetsw_probe(struct platf
107         struct bcm63xx_enetsw_platform_data *pd;
108         struct resource *res_mem;
109         int ret, irq_rx, irq_tx;
110 +       unsigned i, num_ports = 0;
111 +       u16 port_mask = BIT(8);
112 +       u8 val;
113  
114         /* stop if shared driver failed, assume driver->probe will be
115          * called in the same order we register devices (correct ?)
116 @@ -2811,6 +2829,43 @@ static int bcm_enetsw_probe(struct platf
117         priv->pdev = pdev;
118         priv->net_dev = dev;
119  
120 +       /* reset mib */
121 +       val = enetsw_readb(priv, ENETSW_GMCR_REG);
122 +       val |= ENETSW_GMCR_RST_MIB_MASK;
123 +       enetsw_writeb(priv, val, ENETSW_GMCR_REG);
124 +       mdelay(1);
125 +       val &= ~ENETSW_GMCR_RST_MIB_MASK;
126 +       enetsw_writeb(priv, val, ENETSW_GMCR_REG);
127 +       mdelay(1);
128 +
129 +       /* force CPU port state */
130 +       val = enetsw_readb(priv, ENETSW_IMPOV_REG);
131 +       val |= ENETSW_IMPOV_FORCE_MASK | ENETSW_IMPOV_LINKUP_MASK;
132 +       enetsw_writeb(priv, val, ENETSW_IMPOV_REG);
133 +
134 +       /* enable switch forward engine */
135 +       val = enetsw_readb(priv, ENETSW_SWMODE_REG);
136 +       val |= ENETSW_SWMODE_FWD_EN_MASK;
137 +       enetsw_writeb(priv, val, ENETSW_SWMODE_REG);
138 +
139 +       /* enable jumbo on all ports */
140 +       enetsw_writel(priv, 0x1ff, ENETSW_JMBCTL_PORT_REG);
141 +       enetsw_writew(priv, 9728, ENETSW_JMBCTL_MAXSIZE_REG);
142 +
143 +       for (i = 0; i < priv->num_ports; i++) {
144 +               struct bcm63xx_enetsw_port *port = &priv->used_ports[i];
145 +
146 +               if (!port->used)
147 +                       continue;
148 +
149 +               num_ports++;
150 +               port_mask |= BIT(i);
151 +       }
152 +
153 +       /* only register if there is more than one external port */
154 +       if (num_ports > 1)
155 +               bcmenet_switch_register(priv, port_mask);
156 +
157         return 0;
158  
159  out_put_clk:
160 @@ -2839,6 +2894,9 @@ static int bcm_enetsw_remove(struct plat
161         priv = netdev_priv(dev);
162         unregister_netdev(dev);
163  
164 +       /* remove switch */
165 +       bcmenet_switch_unregister(priv);
166 +
167         /* release device resources */
168         iounmap(priv->base);
169         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);