Root/target/linux/ar71xx/files/arch/mips/ar71xx/devices.c

1/*
2 * Atheros AR71xx SoC platform devices
3 *
4 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
5 * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * Parts of this file are based on Atheros 2.6.15 BSP
9 * Parts of this file are based on Atheros 2.6.31 BSP
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published
13 * by the Free Software Foundation.
14 */
15
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/etherdevice.h>
20#include <linux/platform_device.h>
21#include <linux/serial_8250.h>
22
23#include <asm/mach-ar71xx/ar71xx.h>
24#include <asm/mach-ar71xx/ar933x_uart_platform.h>
25
26#include "devices.h"
27
28unsigned char ar71xx_mac_base[ETH_ALEN] __initdata;
29
30static struct resource ar71xx_uart_resources[] = {
31    {
32        .start = AR71XX_UART_BASE,
33        .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
34        .flags = IORESOURCE_MEM,
35    },
36};
37
38#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
39static struct plat_serial8250_port ar71xx_uart_data[] = {
40    {
41        .mapbase = AR71XX_UART_BASE,
42        .irq = AR71XX_MISC_IRQ_UART,
43        .flags = AR71XX_UART_FLAGS,
44        .iotype = UPIO_MEM32,
45        .regshift = 2,
46    }, {
47        /* terminating entry */
48    }
49};
50
51static struct platform_device ar71xx_uart_device = {
52    .name = "serial8250",
53    .id = PLAT8250_DEV_PLATFORM,
54    .resource = ar71xx_uart_resources,
55    .num_resources = ARRAY_SIZE(ar71xx_uart_resources),
56    .dev = {
57        .platform_data = ar71xx_uart_data
58    },
59};
60
61static struct resource ar933x_uart_resources[] = {
62    {
63        .start = AR933X_UART_BASE,
64        .end = AR933X_UART_BASE + AR71XX_UART_SIZE - 1,
65        .flags = IORESOURCE_MEM,
66    },
67    {
68        .start = AR71XX_MISC_IRQ_UART,
69        .end = AR71XX_MISC_IRQ_UART,
70        .flags = IORESOURCE_IRQ,
71    },
72};
73
74static struct ar933x_uart_platform_data ar933x_uart_data;
75static struct platform_device ar933x_uart_device = {
76    .name = "ar933x-uart",
77    .id = -1,
78    .resource = ar933x_uart_resources,
79    .num_resources = ARRAY_SIZE(ar933x_uart_resources),
80    .dev = {
81        .platform_data = &ar933x_uart_data,
82    },
83};
84
85void __init ar71xx_add_device_uart(void)
86{
87    struct platform_device *pdev;
88
89    switch (ar71xx_soc) {
90    case AR71XX_SOC_AR7130:
91    case AR71XX_SOC_AR7141:
92    case AR71XX_SOC_AR7161:
93    case AR71XX_SOC_AR7240:
94    case AR71XX_SOC_AR7241:
95    case AR71XX_SOC_AR7242:
96    case AR71XX_SOC_AR9130:
97    case AR71XX_SOC_AR9132:
98        pdev = &ar71xx_uart_device;
99        ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq;
100        break;
101
102    case AR71XX_SOC_AR9330:
103    case AR71XX_SOC_AR9331:
104        pdev = &ar933x_uart_device;
105        ar933x_uart_data.uartclk = ar71xx_ref_freq;
106        break;
107
108    case AR71XX_SOC_AR9341:
109    case AR71XX_SOC_AR9342:
110    case AR71XX_SOC_AR9344:
111        pdev = &ar71xx_uart_device;
112        ar71xx_uart_data[0].uartclk = ar71xx_ref_freq;
113        break;
114
115    default:
116        BUG();
117    }
118
119    platform_device_register(pdev);
120}
121
122static struct resource ar71xx_mdio_resources[] = {
123    {
124        .name = "mdio_base",
125        .flags = IORESOURCE_MEM,
126        .start = AR71XX_GE0_BASE,
127        .end = AR71XX_GE0_BASE + 0x200 - 1,
128    }
129};
130
131static struct ag71xx_mdio_platform_data ar71xx_mdio_data;
132
133struct platform_device ar71xx_mdio_device = {
134    .name = "ag71xx-mdio",
135    .id = -1,
136    .resource = ar71xx_mdio_resources,
137    .num_resources = ARRAY_SIZE(ar71xx_mdio_resources),
138    .dev = {
139        .platform_data = &ar71xx_mdio_data,
140    },
141};
142
143static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift)
144{
145    void __iomem *base;
146    u32 t;
147
148    base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
149
150    t = __raw_readl(base + cfg_reg);
151    t &= ~(3 << shift);
152    t |= (2 << shift);
153    __raw_writel(t, base + cfg_reg);
154    udelay(100);
155
156    __raw_writel(pll_val, base + pll_reg);
157
158    t |= (3 << shift);
159    __raw_writel(t, base + cfg_reg);
160    udelay(100);
161
162    t &= ~(3 << shift);
163    __raw_writel(t, base + cfg_reg);
164    udelay(100);
165
166    printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n",
167        (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg));
168
169    iounmap(base);
170}
171
172void __init ar71xx_add_device_mdio(u32 phy_mask)
173{
174    switch (ar71xx_soc) {
175    case AR71XX_SOC_AR7240:
176        ar71xx_mdio_data.is_ar7240 = 1;
177        break;
178    case AR71XX_SOC_AR7241:
179        ar71xx_mdio_data.is_ar7240 = 1;
180        ar71xx_mdio_resources[0].start = AR71XX_GE1_BASE;
181        ar71xx_mdio_resources[0].end = AR71XX_GE1_BASE + 0x200 - 1;
182        break;
183    case AR71XX_SOC_AR7242:
184        ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG,
185                   AR7242_PLL_REG_ETH0_INT_CLOCK, 0x62000000,
186                   AR71XX_ETH0_PLL_SHIFT);
187        break;
188    case AR71XX_SOC_AR9330:
189    case AR71XX_SOC_AR9331:
190        ar71xx_mdio_data.is_ar7240 = 1;
191        ar71xx_mdio_resources[0].start = AR71XX_GE1_BASE;
192        ar71xx_mdio_resources[0].end = AR71XX_GE1_BASE + 0x200 - 1;
193        break;
194    default:
195        break;
196    }
197
198    ar71xx_mdio_data.phy_mask = phy_mask;
199
200    platform_device_register(&ar71xx_mdio_device);
201}
202
203struct ar71xx_eth_pll_data ar71xx_eth0_pll_data;
204struct ar71xx_eth_pll_data ar71xx_eth1_pll_data;
205
206static u32 ar71xx_get_eth_pll(unsigned int mac, int speed)
207{
208    struct ar71xx_eth_pll_data *pll_data;
209    u32 pll_val;
210
211    switch (mac) {
212    case 0:
213        pll_data = &ar71xx_eth0_pll_data;
214        break;
215    case 1:
216        pll_data = &ar71xx_eth1_pll_data;
217        break;
218    default:
219        BUG();
220    }
221
222    switch (speed) {
223    case SPEED_10:
224        pll_val = pll_data->pll_10;
225        break;
226    case SPEED_100:
227        pll_val = pll_data->pll_100;
228        break;
229    case SPEED_1000:
230        pll_val = pll_data->pll_1000;
231        break;
232    default:
233        BUG();
234    }
235
236    return pll_val;
237}
238
239static void ar71xx_set_pll_ge0(int speed)
240{
241    u32 val = ar71xx_get_eth_pll(0, speed);
242
243    ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK,
244            val, AR71XX_ETH0_PLL_SHIFT);
245}
246
247static void ar71xx_set_pll_ge1(int speed)
248{
249    u32 val = ar71xx_get_eth_pll(1, speed);
250
251    ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK,
252             val, AR71XX_ETH1_PLL_SHIFT);
253}
254
255static void ar724x_set_pll_ge0(int speed)
256{
257    /* TODO */
258}
259
260static void ar724x_set_pll_ge1(int speed)
261{
262    /* TODO */
263}
264
265static void ar7242_set_pll_ge0(int speed)
266{
267    u32 val = ar71xx_get_eth_pll(0, speed);
268    void __iomem *base;
269
270    base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
271    __raw_writel(val, base + AR7242_PLL_REG_ETH0_INT_CLOCK);
272    iounmap(base);
273}
274
275static void ar91xx_set_pll_ge0(int speed)
276{
277    u32 val = ar71xx_get_eth_pll(0, speed);
278
279    ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK,
280             val, AR91XX_ETH0_PLL_SHIFT);
281}
282
283static void ar91xx_set_pll_ge1(int speed)
284{
285    u32 val = ar71xx_get_eth_pll(1, speed);
286
287    ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK,
288             val, AR91XX_ETH1_PLL_SHIFT);
289}
290
291static void ar933x_set_pll_ge0(int speed)
292{
293    /* TODO */
294}
295
296static void ar933x_set_pll_ge1(int speed)
297{
298    /* TODO */
299}
300
301static void ar71xx_ddr_flush_ge0(void)
302{
303    ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0);
304}
305
306static void ar71xx_ddr_flush_ge1(void)
307{
308    ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1);
309}
310
311static void ar724x_ddr_flush_ge0(void)
312{
313    ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE0);
314}
315
316static void ar724x_ddr_flush_ge1(void)
317{
318    ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE1);
319}
320
321static void ar91xx_ddr_flush_ge0(void)
322{
323    ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0);
324}
325
326static void ar91xx_ddr_flush_ge1(void)
327{
328    ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1);
329}
330
331static void ar933x_ddr_flush_ge0(void)
332{
333    ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE0);
334}
335
336static void ar933x_ddr_flush_ge1(void)
337{
338    ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE1);
339}
340
341static struct resource ar71xx_eth0_resources[] = {
342    {
343        .name = "mac_base",
344        .flags = IORESOURCE_MEM,
345        .start = AR71XX_GE0_BASE,
346        .end = AR71XX_GE0_BASE + 0x200 - 1,
347    }, {
348        .name = "mii_ctrl",
349        .flags = IORESOURCE_MEM,
350        .start = AR71XX_MII_BASE + MII_REG_MII0_CTRL,
351        .end = AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3,
352    }, {
353        .name = "mac_irq",
354        .flags = IORESOURCE_IRQ,
355        .start = AR71XX_CPU_IRQ_GE0,
356        .end = AR71XX_CPU_IRQ_GE0,
357    },
358};
359
360struct ag71xx_platform_data ar71xx_eth0_data = {
361    .reset_bit = RESET_MODULE_GE0_MAC,
362};
363
364struct platform_device ar71xx_eth0_device = {
365    .name = "ag71xx",
366    .id = 0,
367    .resource = ar71xx_eth0_resources,
368    .num_resources = ARRAY_SIZE(ar71xx_eth0_resources),
369    .dev = {
370        .platform_data = &ar71xx_eth0_data,
371    },
372};
373
374static struct resource ar71xx_eth1_resources[] = {
375    {
376        .name = "mac_base",
377        .flags = IORESOURCE_MEM,
378        .start = AR71XX_GE1_BASE,
379        .end = AR71XX_GE1_BASE + 0x200 - 1,
380    }, {
381        .name = "mii_ctrl",
382        .flags = IORESOURCE_MEM,
383        .start = AR71XX_MII_BASE + MII_REG_MII1_CTRL,
384        .end = AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3,
385    }, {
386        .name = "mac_irq",
387        .flags = IORESOURCE_IRQ,
388        .start = AR71XX_CPU_IRQ_GE1,
389        .end = AR71XX_CPU_IRQ_GE1,
390    },
391};
392
393struct ag71xx_platform_data ar71xx_eth1_data = {
394    .reset_bit = RESET_MODULE_GE1_MAC,
395};
396
397struct platform_device ar71xx_eth1_device = {
398    .name = "ag71xx",
399    .id = 1,
400    .resource = ar71xx_eth1_resources,
401    .num_resources = ARRAY_SIZE(ar71xx_eth1_resources),
402    .dev = {
403        .platform_data = &ar71xx_eth1_data,
404    },
405};
406
407#define AR71XX_PLL_VAL_1000 0x00110000
408#define AR71XX_PLL_VAL_100 0x00001099
409#define AR71XX_PLL_VAL_10 0x00991099
410
411#define AR724X_PLL_VAL_1000 0x00110000
412#define AR724X_PLL_VAL_100 0x00001099
413#define AR724X_PLL_VAL_10 0x00991099
414
415#define AR7242_PLL_VAL_1000 0x16000000
416#define AR7242_PLL_VAL_100 0x00000101
417#define AR7242_PLL_VAL_10 0x00001616
418
419#define AR91XX_PLL_VAL_1000 0x1a000000
420#define AR91XX_PLL_VAL_100 0x13000a44
421#define AR91XX_PLL_VAL_10 0x00441099
422
423#define AR933X_PLL_VAL_1000 0x00110000
424#define AR933X_PLL_VAL_100 0x00001099
425#define AR933X_PLL_VAL_10 0x00991099
426
427static void __init ar71xx_init_eth_pll_data(unsigned int id)
428{
429    struct ar71xx_eth_pll_data *pll_data;
430    u32 pll_10, pll_100, pll_1000;
431
432    switch (id) {
433    case 0:
434        pll_data = &ar71xx_eth0_pll_data;
435        break;
436    case 1:
437        pll_data = &ar71xx_eth1_pll_data;
438        break;
439    default:
440        BUG();
441    }
442
443    switch (ar71xx_soc) {
444    case AR71XX_SOC_AR7130:
445    case AR71XX_SOC_AR7141:
446    case AR71XX_SOC_AR7161:
447        pll_10 = AR71XX_PLL_VAL_10;
448        pll_100 = AR71XX_PLL_VAL_100;
449        pll_1000 = AR71XX_PLL_VAL_1000;
450        break;
451
452    case AR71XX_SOC_AR7240:
453    case AR71XX_SOC_AR7241:
454        pll_10 = AR724X_PLL_VAL_10;
455        pll_100 = AR724X_PLL_VAL_100;
456        pll_1000 = AR724X_PLL_VAL_1000;
457        break;
458
459    case AR71XX_SOC_AR7242:
460        pll_10 = AR7242_PLL_VAL_10;
461        pll_100 = AR7242_PLL_VAL_100;
462        pll_1000 = AR7242_PLL_VAL_1000;
463        break;
464
465    case AR71XX_SOC_AR9130:
466    case AR71XX_SOC_AR9132:
467        pll_10 = AR91XX_PLL_VAL_10;
468        pll_100 = AR91XX_PLL_VAL_100;
469        pll_1000 = AR91XX_PLL_VAL_1000;
470        break;
471
472    case AR71XX_SOC_AR9330:
473    case AR71XX_SOC_AR9331:
474        pll_10 = AR933X_PLL_VAL_10;
475        pll_100 = AR933X_PLL_VAL_100;
476        pll_1000 = AR933X_PLL_VAL_1000;
477        break;
478
479    default:
480        BUG();
481    }
482
483    if (!pll_data->pll_10)
484        pll_data->pll_10 = pll_10;
485
486    if (!pll_data->pll_100)
487        pll_data->pll_100 = pll_100;
488
489    if (!pll_data->pll_1000)
490        pll_data->pll_1000 = pll_1000;
491}
492
493static int ar71xx_eth_instance __initdata;
494void __init ar71xx_add_device_eth(unsigned int id)
495{
496    struct platform_device *pdev;
497    struct ag71xx_platform_data *pdata;
498
499    ar71xx_init_eth_pll_data(id);
500
501    switch (id) {
502    case 0:
503        switch (ar71xx_eth0_data.phy_if_mode) {
504        case PHY_INTERFACE_MODE_MII:
505            ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII;
506            break;
507        case PHY_INTERFACE_MODE_GMII:
508            ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII;
509            break;
510        case PHY_INTERFACE_MODE_RGMII:
511            ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII;
512            break;
513        case PHY_INTERFACE_MODE_RMII:
514            ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII;
515            break;
516        default:
517            printk(KERN_ERR "ar71xx: invalid PHY interface mode "
518                    "for eth0\n");
519            return;
520        }
521        pdev = &ar71xx_eth0_device;
522        break;
523    case 1:
524        switch (ar71xx_eth1_data.phy_if_mode) {
525        case PHY_INTERFACE_MODE_RMII:
526            ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII;
527            break;
528        case PHY_INTERFACE_MODE_RGMII:
529            ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII;
530            break;
531        default:
532            printk(KERN_ERR "ar71xx: invalid PHY interface mode "
533                    "for eth1\n");
534            return;
535        }
536        pdev = &ar71xx_eth1_device;
537        break;
538    default:
539        printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id);
540        return;
541    }
542
543    pdata = pdev->dev.platform_data;
544
545    switch (ar71xx_soc) {
546    case AR71XX_SOC_AR7130:
547        pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
548                      : ar71xx_ddr_flush_ge0;
549        pdata->set_pll = id ? ar71xx_set_pll_ge1
550                     : ar71xx_set_pll_ge0;
551        break;
552
553    case AR71XX_SOC_AR7141:
554    case AR71XX_SOC_AR7161:
555        pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
556                      : ar71xx_ddr_flush_ge0;
557        pdata->set_pll = id ? ar71xx_set_pll_ge1
558                     : ar71xx_set_pll_ge0;
559        pdata->has_gbit = 1;
560        break;
561
562    case AR71XX_SOC_AR7242:
563        ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO |
564                          RESET_MODULE_GE0_PHY;
565        ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO |
566                          RESET_MODULE_GE1_PHY;
567        pdata->ddr_flush = id ? ar724x_ddr_flush_ge1
568                      : ar724x_ddr_flush_ge0;
569        pdata->set_pll = id ? ar724x_set_pll_ge1
570                     : ar7242_set_pll_ge0;
571        pdata->has_gbit = 1;
572        pdata->is_ar724x = 1;
573
574        if (!pdata->fifo_cfg1)
575            pdata->fifo_cfg1 = 0x0010ffff;
576        if (!pdata->fifo_cfg2)
577            pdata->fifo_cfg2 = 0x015500aa;
578        if (!pdata->fifo_cfg3)
579            pdata->fifo_cfg3 = 0x01f00140;
580        break;
581
582    case AR71XX_SOC_AR7241:
583        ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO;
584        ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO;
585        /* fall through */
586    case AR71XX_SOC_AR7240:
587        ar71xx_eth0_data.reset_bit |= RESET_MODULE_GE0_PHY;
588        ar71xx_eth1_data.reset_bit |= RESET_MODULE_GE1_PHY;
589        pdata->ddr_flush = id ? ar724x_ddr_flush_ge1
590                      : ar724x_ddr_flush_ge0;
591        pdata->set_pll = id ? ar724x_set_pll_ge1
592                     : ar724x_set_pll_ge0;
593        pdata->is_ar724x = 1;
594        if (ar71xx_soc == AR71XX_SOC_AR7240)
595            pdata->is_ar7240 = 1;
596
597        if (!pdata->fifo_cfg1)
598            pdata->fifo_cfg1 = 0x0010ffff;
599        if (!pdata->fifo_cfg2)
600            pdata->fifo_cfg2 = 0x015500aa;
601        if (!pdata->fifo_cfg3)
602            pdata->fifo_cfg3 = 0x01f00140;
603        break;
604
605    case AR71XX_SOC_AR9130:
606        pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
607                      : ar91xx_ddr_flush_ge0;
608        pdata->set_pll = id ? ar91xx_set_pll_ge1
609                     : ar91xx_set_pll_ge0;
610        pdata->is_ar91xx = 1;
611        break;
612
613    case AR71XX_SOC_AR9132:
614        pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
615                      : ar91xx_ddr_flush_ge0;
616        pdata->set_pll = id ? ar91xx_set_pll_ge1
617                      : ar91xx_set_pll_ge0;
618        pdata->is_ar91xx = 1;
619        pdata->has_gbit = 1;
620        break;
621
622    case AR71XX_SOC_AR9330:
623    case AR71XX_SOC_AR9331:
624        ar71xx_eth0_data.reset_bit = AR933X_RESET_GE0_MAC |
625                         AR933X_RESET_GE0_MDIO;
626        ar71xx_eth1_data.reset_bit = AR933X_RESET_GE1_MAC |
627                         AR933X_RESET_GE1_MDIO;
628        pdata->ddr_flush = id ? ar933x_ddr_flush_ge1
629                      : ar933x_ddr_flush_ge0;
630        pdata->set_pll = id ? ar933x_set_pll_ge1
631                     : ar933x_set_pll_ge0;
632        pdata->has_gbit = 1;
633        pdata->is_ar724x = 1;
634
635        if (!pdata->fifo_cfg1)
636            pdata->fifo_cfg1 = 0x0010ffff;
637        if (!pdata->fifo_cfg2)
638            pdata->fifo_cfg2 = 0x015500aa;
639        if (!pdata->fifo_cfg3)
640            pdata->fifo_cfg3 = 0x01f00140;
641        break;
642
643    default:
644        BUG();
645    }
646
647    switch (pdata->phy_if_mode) {
648    case PHY_INTERFACE_MODE_GMII:
649    case PHY_INTERFACE_MODE_RGMII:
650        if (!pdata->has_gbit) {
651            printk(KERN_ERR "ar71xx: no gbit available on eth%d\n",
652                    id);
653            return;
654        }
655        /* fallthrough */
656    default:
657        break;
658    }
659
660    if (!is_valid_ether_addr(pdata->mac_addr)) {
661        random_ether_addr(pdata->mac_addr);
662        printk(KERN_DEBUG
663            "ar71xx: using random MAC address for eth%d\n",
664            ar71xx_eth_instance);
665    }
666
667    if (pdata->mii_bus_dev == NULL)
668        pdata->mii_bus_dev = &ar71xx_mdio_device.dev;
669
670    /* Reset the device */
671    ar71xx_device_stop(pdata->reset_bit);
672    mdelay(100);
673
674    ar71xx_device_start(pdata->reset_bit);
675    mdelay(100);
676
677    platform_device_register(pdev);
678    ar71xx_eth_instance++;
679}
680
681static struct resource ar71xx_spi_resources[] = {
682    [0] = {
683        .start = AR71XX_SPI_BASE,
684        .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
685        .flags = IORESOURCE_MEM,
686    },
687};
688
689static struct platform_device ar71xx_spi_device = {
690    .name = "ar71xx-spi",
691    .id = -1,
692    .resource = ar71xx_spi_resources,
693    .num_resources = ARRAY_SIZE(ar71xx_spi_resources),
694};
695
696void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
697                struct spi_board_info const *info,
698                unsigned n)
699{
700    spi_register_board_info(info, n);
701    ar71xx_spi_device.dev.platform_data = pdata;
702    platform_device_register(&ar71xx_spi_device);
703}
704
705void __init ar71xx_add_device_wdt(void)
706{
707    platform_device_register_simple("ar71xx-wdt", -1, NULL, 0);
708}
709
710void __init ar71xx_set_mac_base(unsigned char *mac)
711{
712    memcpy(ar71xx_mac_base, mac, ETH_ALEN);
713}
714
715void __init ar71xx_parse_mac_addr(char *mac_str)
716{
717    u8 tmp[ETH_ALEN];
718    int t;
719
720    t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
721            &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
722
723    if (t != ETH_ALEN)
724        t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx",
725            &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
726
727    if (t == ETH_ALEN)
728        ar71xx_set_mac_base(tmp);
729    else
730        printk(KERN_DEBUG "ar71xx: failed to parse mac address "
731                "\"%s\"\n", mac_str);
732}
733
734static int __init ar71xx_ethaddr_setup(char *str)
735{
736    ar71xx_parse_mac_addr(str);
737    return 1;
738}
739__setup("ethaddr=", ar71xx_ethaddr_setup);
740
741static int __init ar71xx_kmac_setup(char *str)
742{
743    ar71xx_parse_mac_addr(str);
744    return 1;
745}
746__setup("kmac=", ar71xx_kmac_setup);
747
748void __init ar71xx_init_mac(unsigned char *dst, const unsigned char *src,
749                unsigned offset)
750{
751    u32 t;
752
753    if (!is_valid_ether_addr(src)) {
754        memset(dst, '\0', ETH_ALEN);
755        return;
756    }
757
758    t = (((u32) src[3]) << 16) + (((u32) src[4]) << 8) + ((u32) src[5]);
759    t += offset;
760
761    dst[0] = src[0];
762    dst[1] = src[1];
763    dst[2] = src[2];
764    dst[3] = (t >> 16) & 0xff;
765    dst[4] = (t >> 8) & 0xff;
766    dst[5] = t & 0xff;
767}
768

Archive Download this file



interactive