[lantiq] bump kernel to 3.2.12
[openwrt/svn-archive/archive.git] / target / linux / lantiq / patches-3.2 / 0019-NET-MIPS-lantiq-make-etop-ethernet-work-on-ase-ar9.patch
1 From 4b24c79196e5777baff0f5d53b62cf2a964e26ff Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Wed, 10 Aug 2011 15:32:16 +0200
4 Subject: [PATCH 19/70] NET: MIPS: lantiq: make etop ethernet work on ase/ar9
5
6 Extend the driver to handle the different DMA channel layout for AR9 and
7 Amazon-SE SoCs. The patch also adds support for the integrated PHY found
8 on Amazon-SE and the gigabit switch found inside the AR9.
9
10 Signed-off-by: John Crispin <blogic@openwrt.org>
11 Cc: netdev@vger.kernel.org
12 ---
13 .../mips/include/asm/mach-lantiq/xway/lantiq_irq.h | 22 +---
14 .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 10 ++
15 arch/mips/lantiq/xway/devices.c | 11 +-
16 drivers/net/ethernet/lantiq_etop.c | 171 ++++++++++++++++++--
17 4 files changed, 174 insertions(+), 40 deletions(-)
18
19 diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
20 index b4465a8..2a8d5ad 100644
21 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
22 +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
23 @@ -38,26 +38,8 @@
24
25 #define MIPS_CPU_TIMER_IRQ 7
26
27 -#define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0)
28 -#define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1)
29 -#define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2)
30 -#define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3)
31 -#define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4)
32 -#define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5)
33 -#define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6)
34 -#define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7)
35 -#define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8)
36 -#define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9)
37 -#define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10)
38 -#define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11)
39 -#define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25)
40 -#define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26)
41 -#define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27)
42 -#define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28)
43 -#define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29)
44 -#define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30)
45 -#define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16)
46 -#define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21)
47 +#define LTQ_DMA_ETOP ((ltq_is_ase()) ? \
48 + (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0))
49
50 #define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24)
51
52 diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
53 index e31f52d..6983d75 100644
54 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
55 +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
56 @@ -82,6 +82,7 @@
57 #define LTQ_PMU_SIZE 0x1000
58
59 #define PMU_DMA 0x0020
60 +#define PMU_EPHY 0x0080
61 #define PMU_USB 0x8041
62 #define PMU_LED 0x0800
63 #define PMU_GPT 0x1000
64 @@ -93,6 +94,10 @@
65 #define LTQ_ETOP_BASE_ADDR 0x1E180000
66 #define LTQ_ETOP_SIZE 0x40000
67
68 +/* GBIT - gigabit switch */
69 +#define LTQ_GBIT_BASE_ADDR 0x1E108000
70 +#define LTQ_GBIT_SIZE 0x200
71 +
72 /* DMA */
73 #define LTQ_DMA_BASE_ADDR 0x1E104100
74 #define LTQ_DMA_SIZE 0x800
75 @@ -147,6 +152,11 @@ extern void ltq_pmu_enable(unsigned int module);
76 extern void ltq_pmu_disable(unsigned int module);
77 extern void ltq_cgu_enable(unsigned int clk);
78
79 +static inline int ltq_is_ase(void)
80 +{
81 + return (ltq_get_soc_type() == SOC_TYPE_AMAZON_SE);
82 +}
83 +
84 static inline int ltq_is_ar9(void)
85 {
86 return (ltq_get_soc_type() == SOC_TYPE_AR9);
87 diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
88 index f97e565..eab4644d 100644
89 --- a/arch/mips/lantiq/xway/devices.c
90 +++ b/arch/mips/lantiq/xway/devices.c
91 @@ -74,18 +74,23 @@ void __init ltq_register_ase_asc(void)
92 }
93
94 /* ethernet */
95 -static struct resource ltq_etop_resources =
96 - MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE);
97 +static struct resource ltq_etop_resources[] = {
98 + MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE),
99 + MEM_RES("gbit", LTQ_GBIT_BASE_ADDR, LTQ_GBIT_SIZE),
100 +};
101
102 static struct platform_device ltq_etop = {
103 .name = "ltq_etop",
104 - .resource = &ltq_etop_resources,
105 + .resource = ltq_etop_resources,
106 .num_resources = 1,
107 };
108
109 void __init
110 ltq_register_etop(struct ltq_eth_data *eth)
111 {
112 + /* only register the gphy on socs that have one */
113 + if (ltq_is_ar9() | ltq_is_vr9())
114 + ltq_etop.num_resources = 2;
115 if (eth) {
116 ltq_etop.dev.platform_data = eth;
117 platform_device_register(&ltq_etop);
118 diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
119 index 0b3567a..d3d4931 100644
120 --- a/drivers/net/ethernet/lantiq_etop.c
121 +++ b/drivers/net/ethernet/lantiq_etop.c
122 @@ -71,10 +71,43 @@
123 #define ETOP_MII_REVERSE 0xe
124 #define ETOP_PLEN_UNDER 0x40
125 #define ETOP_CGEN 0x800
126 -
127 -/* use 2 static channels for TX/RX */
128 +#define ETOP_CFG_MII0 0x01
129 +
130 +#define LTQ_GBIT_MDIO_CTL 0xCC
131 +#define LTQ_GBIT_MDIO_DATA 0xd0
132 +#define LTQ_GBIT_GCTL0 0x68
133 +#define LTQ_GBIT_PMAC_HD_CTL 0x8c
134 +#define LTQ_GBIT_P0_CTL 0x4
135 +#define LTQ_GBIT_PMAC_RX_IPG 0xa8
136 +
137 +#define PMAC_HD_CTL_AS (1 << 19)
138 +#define PMAC_HD_CTL_RXSH (1 << 22)
139 +
140 +/* Switch Enable (0=disable, 1=enable) */
141 +#define GCTL0_SE 0x80000000
142 +/* Disable MDIO auto polling (0=disable, 1=enable) */
143 +#define PX_CTL_DMDIO 0x00400000
144 +
145 +/* register information for the gbit's MDIO bus */
146 +#define MDIO_XR9_REQUEST 0x00008000
147 +#define MDIO_XR9_READ 0x00000800
148 +#define MDIO_XR9_WRITE 0x00000400
149 +#define MDIO_XR9_REG_MASK 0x1f
150 +#define MDIO_XR9_ADDR_MASK 0x1f
151 +#define MDIO_XR9_RD_MASK 0xffff
152 +#define MDIO_XR9_REG_OFFSET 0
153 +#define MDIO_XR9_ADDR_OFFSET 5
154 +#define MDIO_XR9_WR_OFFSET 16
155 +
156 +/* the newer xway socks have a embedded 3/7 port gbit multiplexer */
157 +#define ltq_has_gbit() (ltq_is_ar9() || ltq_is_vr9())
158 +
159 +/* use 2 static channels for TX/RX
160 + depending on the SoC we need to use different DMA channels for ethernet */
161 #define LTQ_ETOP_TX_CHANNEL 1
162 -#define LTQ_ETOP_RX_CHANNEL 6
163 +#define LTQ_ETOP_RX_CHANNEL ((ltq_is_ase()) ? (5) : \
164 + ((ltq_has_gbit()) ? (0) : (6)))
165 +
166 #define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
167 #define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL)
168
169 @@ -83,9 +116,15 @@
170 #define ltq_etop_w32_mask(x, y, z) \
171 ltq_w32_mask(x, y, ltq_etop_membase + (z))
172
173 +#define ltq_gbit_r32(x) ltq_r32(ltq_gbit_membase + (x))
174 +#define ltq_gbit_w32(x, y) ltq_w32(x, ltq_gbit_membase + (y))
175 +#define ltq_gbit_w32_mask(x, y, z) \
176 + ltq_w32_mask(x, y, ltq_gbit_membase + (z))
177 +
178 #define DRV_VERSION "1.0"
179
180 static void __iomem *ltq_etop_membase;
181 +static void __iomem *ltq_gbit_membase;
182
183 struct ltq_etop_chan {
184 int idx;
185 @@ -110,6 +149,9 @@ struct ltq_etop_priv {
186 spinlock_t lock;
187 };
188
189 +static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr,
190 + int phy_reg, u16 phy_data);
191 +
192 static int
193 ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
194 {
195 @@ -211,7 +253,7 @@ static irqreturn_t
196 ltq_etop_dma_irq(int irq, void *_priv)
197 {
198 struct ltq_etop_priv *priv = _priv;
199 - int ch = irq - LTQ_DMA_CH0_INT;
200 + int ch = irq - LTQ_DMA_ETOP;
201
202 napi_schedule(&priv->ch[ch].napi);
203 return IRQ_HANDLED;
204 @@ -244,15 +286,43 @@ ltq_etop_hw_exit(struct net_device *dev)
205 ltq_etop_free_channel(dev, &priv->ch[i]);
206 }
207
208 +static void
209 +ltq_etop_gbit_init(void)
210 +{
211 + ltq_pmu_enable(PMU_SWITCH);
212 +
213 + ltq_gpio_request(42, 2, 1, "MDIO");
214 + ltq_gpio_request(43, 2, 1, "MDC");
215 +
216 + ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0);
217 + /** Disable MDIO auto polling mode */
218 + ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL);
219 + /* set 1522 packet size */
220 + ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0);
221 + /* disable pmac & dmac headers */
222 + ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0,
223 + LTQ_GBIT_PMAC_HD_CTL);
224 + /* Due to traffic halt when burst length 8,
225 + replace default IPG value with 0x3B */
226 + ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG);
227 +}
228 +
229 static int
230 ltq_etop_hw_init(struct net_device *dev)
231 {
232 struct ltq_etop_priv *priv = netdev_priv(dev);
233 + unsigned int mii_mode = priv->pldata->mii_mode;
234 int i;
235
236 ltq_pmu_enable(PMU_PPE);
237
238 - switch (priv->pldata->mii_mode) {
239 + if (ltq_has_gbit()) {
240 + ltq_etop_gbit_init();
241 + /* force the etops link to the gbit to MII */
242 + mii_mode = PHY_INTERFACE_MODE_MII;
243 + }
244 +
245 + switch (mii_mode) {
246 case PHY_INTERFACE_MODE_RMII:
247 ltq_etop_w32_mask(ETOP_MII_MASK,
248 ETOP_MII_REVERSE, LTQ_ETOP_CFG);
249 @@ -264,6 +334,18 @@ ltq_etop_hw_init(struct net_device *dev)
250 break;
251
252 default:
253 + if (ltq_is_ase()) {
254 + ltq_pmu_enable(PMU_EPHY);
255 + /* disable external MII */
256 + ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG);
257 + /* enable clock for internal PHY */
258 + ltq_cgu_enable(CGU_EPHY);
259 + /* we need to write this magic to the internal phy to
260 + make it work */
261 + ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
262 + pr_info("Selected EPHY mode\n");
263 + break;
264 + }
265 netdev_err(dev, "unknown mii mode %d\n",
266 priv->pldata->mii_mode);
267 return -ENOTSUPP;
268 @@ -275,7 +357,7 @@ ltq_etop_hw_init(struct net_device *dev)
269 ltq_dma_init_port(DMA_PORT_ETOP);
270
271 for (i = 0; i < MAX_DMA_CHAN; i++) {
272 - int irq = LTQ_DMA_CH0_INT + i;
273 + int irq = LTQ_DMA_ETOP + i;
274 struct ltq_etop_chan *ch = &priv->ch[i];
275
276 ch->idx = ch->dma.nr = i;
277 @@ -339,6 +421,39 @@ static const struct ethtool_ops ltq_etop_ethtool_ops = {
278 };
279
280 static int
281 +ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr,
282 + int phy_reg, u16 phy_data)
283 +{
284 + u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE |
285 + (phy_data << MDIO_XR9_WR_OFFSET) |
286 + ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
287 + ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
288 +
289 + while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
290 + ;
291 + ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
292 + while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
293 + ;
294 + return 0;
295 +}
296 +
297 +static int
298 +ltq_etop_mdio_rd_xr9(struct mii_bus *bus, int phy_addr, int phy_reg)
299 +{
300 + u32 val = MDIO_XR9_REQUEST | MDIO_XR9_READ |
301 + ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
302 + ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
303 +
304 + while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
305 + ;
306 + ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
307 + while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
308 + ;
309 + val = ltq_gbit_r32(LTQ_GBIT_MDIO_DATA) & MDIO_XR9_RD_MASK;
310 + return val;
311 +}
312 +
313 +static int
314 ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
315 {
316 u32 val = MDIO_REQUEST |
317 @@ -379,14 +494,11 @@ ltq_etop_mdio_probe(struct net_device *dev)
318 {
319 struct ltq_etop_priv *priv = netdev_priv(dev);
320 struct phy_device *phydev = NULL;
321 - int phy_addr;
322
323 - for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
324 - if (priv->mii_bus->phy_map[phy_addr]) {
325 - phydev = priv->mii_bus->phy_map[phy_addr];
326 - break;
327 - }
328 - }
329 + if (ltq_is_ase())
330 + phydev = priv->mii_bus->phy_map[8];
331 + else
332 + phydev = priv->mii_bus->phy_map[0];
333
334 if (!phydev) {
335 netdev_err(dev, "no PHY found\n");
336 @@ -408,6 +520,9 @@ ltq_etop_mdio_probe(struct net_device *dev)
337 | SUPPORTED_Autoneg
338 | SUPPORTED_MII
339 | SUPPORTED_TP);
340 + if (ltq_has_gbit())
341 + phydev->supported &= SUPPORTED_1000baseT_Half
342 + | SUPPORTED_1000baseT_Full;
343
344 phydev->advertising = phydev->supported;
345 priv->phydev = phydev;
346 @@ -433,8 +548,13 @@ ltq_etop_mdio_init(struct net_device *dev)
347 }
348
349 priv->mii_bus->priv = dev;
350 - priv->mii_bus->read = ltq_etop_mdio_rd;
351 - priv->mii_bus->write = ltq_etop_mdio_wr;
352 + if (ltq_has_gbit()) {
353 + priv->mii_bus->read = ltq_etop_mdio_rd_xr9;
354 + priv->mii_bus->write = ltq_etop_mdio_wr_xr9;
355 + } else {
356 + priv->mii_bus->read = ltq_etop_mdio_rd;
357 + priv->mii_bus->write = ltq_etop_mdio_wr;
358 + }
359 priv->mii_bus->name = "ltq_mii";
360 snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
361 priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
362 @@ -524,9 +644,9 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
363 struct ltq_etop_priv *priv = netdev_priv(dev);
364 struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
365 struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
366 - int len;
367 unsigned long flags;
368 u32 byte_offset;
369 + int len;
370
371 len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
372
373 @@ -700,7 +820,7 @@ ltq_etop_probe(struct platform_device *pdev)
374 {
375 struct net_device *dev;
376 struct ltq_etop_priv *priv;
377 - struct resource *res;
378 + struct resource *res, *gbit_res;
379 int err;
380 int i;
381
382 @@ -728,6 +848,23 @@ ltq_etop_probe(struct platform_device *pdev)
383 goto err_out;
384 }
385
386 + if (ltq_has_gbit()) {
387 + gbit_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
388 + if (!gbit_res) {
389 + dev_err(&pdev->dev, "failed to get gbit resource\n");
390 + err = -ENOENT;
391 + goto err_out;
392 + }
393 + ltq_gbit_membase = devm_ioremap_nocache(&pdev->dev,
394 + gbit_res->start, resource_size(gbit_res));
395 + if (!ltq_gbit_membase) {
396 + dev_err(&pdev->dev, "failed to remap gigabit switch %d\n",
397 + pdev->id);
398 + err = -ENOMEM;
399 + goto err_out;
400 + }
401 + }
402 +
403 dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
404 strcpy(dev->name, "eth%d");
405 dev->netdev_ops = &ltq_eth_netdev_ops;
406 --
407 1.7.7.1
408