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