brcm47xx: prepare brcm47xx patches for sending to mainline.
[openwrt.git] / target / linux / brcm47xx / patches-2.6.34 / 001-backport.patch
1 commit 121915c4ee0812a14bc8d752bc210d0238d755c1
2 Author: Waldemar Brodkorb <mips@waldemar-brodkorb.de>
3 Date:   Tue Jun 8 19:06:01 2010 +0200
4
5     MIPS: BCM47xx: Add NVRAM support devices
6     
7     When trying to netboot a Linksys WRT54GS WLAN router, the bootup fails,
8     because of following error message:
9     
10     ...
11     [    0.424000] b44: b44.c:v2.0
12     [    0.424000] b44: Invalid MAC address found in EEPROM
13     [    0.432000] b44 ssb0:1: Problem fetching invariants of chip,aborting
14     [    0.436000] b44: probe of ssb0:1 failed with error -22
15     ...
16     
17     The router uses a CFE bootloader, but most of the needed environment
18     variables for network card initialization, are not available from CFE
19     via printenv and even though not via cfe_getenv().
20     The required environment variables are saved in a special partition
21     in flash memory. The attached patch implement nvram_getenv and enables
22     bootup via NFS root on my router.
23     
24     Most of the patch is extracted from the OpenWrt subversion repository and
25     stripped down and cleaned up to just fix this issue.
26     
27     [Ralf: sorted out header file inclusions.  Lots of unneded headers and such
28     that should have been included.]
29     
30     Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>
31     Reviewed-by: Phil Sutter <phil@nwl.cc>
32     To: linux-mips@linux-mips.org
33     Cc: Hauke Mehrtens <hauke@hauke-m.de>
34     Patchwork: http://patchwork.linux-mips.org/patch/1359/
35     Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
36
37 --- a/arch/mips/bcm47xx/Makefile
38 +++ b/arch/mips/bcm47xx/Makefile
39 @@ -3,4 +3,4 @@
40  # under Linux.
41  #
42  
43 -obj-y := gpio.o irq.o prom.o serial.o setup.o time.o wgt634u.o
44 +obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o wgt634u.o
45 --- /dev/null
46 +++ b/arch/mips/bcm47xx/nvram.c
47 @@ -0,0 +1,94 @@
48 +/*
49 + * BCM947xx nvram variable access
50 + *
51 + * Copyright (C) 2005 Broadcom Corporation
52 + * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
53 + *
54 + * This program is free software; you can redistribute  it and/or modify it
55 + * under  the terms of  the GNU General  Public License as published by the
56 + * Free Software Foundation;  either version 2 of the  License, or (at your
57 + * option) any later version.
58 + */
59 +
60 +#include <linux/init.h>
61 +#include <linux/types.h>
62 +#include <linux/module.h>
63 +#include <linux/ssb/ssb.h>
64 +#include <linux/kernel.h>
65 +#include <linux/string.h>
66 +#include <asm/addrspace.h>
67 +#include <asm/mach-bcm47xx/nvram.h>
68 +#include <asm/mach-bcm47xx/bcm47xx.h>
69 +
70 +static char nvram_buf[NVRAM_SPACE];
71 +
72 +/* Probe for NVRAM header */
73 +static void __init early_nvram_init(void)
74 +{
75 +       struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
76 +       struct nvram_header *header;
77 +       int i;
78 +       u32 base, lim, off;
79 +       u32 *src, *dst;
80 +
81 +       base = mcore->flash_window;
82 +       lim = mcore->flash_window_size;
83 +
84 +       off = FLASH_MIN;
85 +       while (off <= lim) {
86 +               /* Windowed flash access */
87 +               header = (struct nvram_header *)
88 +                       KSEG1ADDR(base + off - NVRAM_SPACE);
89 +               if (header->magic == NVRAM_HEADER)
90 +                       goto found;
91 +               off <<= 1;
92 +       }
93 +
94 +       /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
95 +       header = (struct nvram_header *) KSEG1ADDR(base + 4096);
96 +       if (header->magic == NVRAM_HEADER)
97 +               goto found;
98 +
99 +       header = (struct nvram_header *) KSEG1ADDR(base + 1024);
100 +       if (header->magic == NVRAM_HEADER)
101 +               goto found;
102 +
103 +       return;
104 +
105 +found:
106 +       src = (u32 *) header;
107 +       dst = (u32 *) nvram_buf;
108 +       for (i = 0; i < sizeof(struct nvram_header); i += 4)
109 +               *dst++ = *src++;
110 +       for (; i < header->len && i < NVRAM_SPACE; i += 4)
111 +               *dst++ = le32_to_cpu(*src++);
112 +}
113 +
114 +int nvram_getenv(char *name, char *val, size_t val_len)
115 +{
116 +       char *var, *value, *end, *eq;
117 +
118 +       if (!name)
119 +               return 1;
120 +
121 +       if (!nvram_buf[0])
122 +               early_nvram_init();
123 +
124 +       /* Look for name=value and return value */
125 +       var = &nvram_buf[sizeof(struct nvram_header)];
126 +       end = nvram_buf + sizeof(nvram_buf) - 2;
127 +       end[0] = end[1] = '\0';
128 +       for (; *var; var = value + strlen(value) + 1) {
129 +               eq = strchr(var, '=');
130 +               if (!eq)
131 +                       break;
132 +               value = eq + 1;
133 +               if ((eq - var) == strlen(name) &&
134 +                       strncmp(var, name, (eq - var)) == 0) {
135 +                       snprintf(val, val_len, "%s", value);
136 +                       return 0;
137 +               }
138 +       }
139 +       return 1;
140 +}
141 +EXPORT_SYMBOL(nvram_getenv);
142 --- a/arch/mips/bcm47xx/setup.c
143 +++ b/arch/mips/bcm47xx/setup.c
144 @@ -1,8 +1,8 @@
145  /*
146   *  Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
147 - *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
148   *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
149   *  Copyright (C) 2006 Michael Buesch <mb@bu3sch.de>
150 + *  Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org>
151   *
152   *  This program is free software; you can redistribute  it and/or modify it
153   *  under  the terms of  the GNU General  Public License as published by the
154 @@ -33,6 +33,7 @@
155  #include <asm/time.h>
156  #include <bcm47xx.h>
157  #include <asm/fw/cfe/cfe_api.h>
158 +#include <asm/mach-bcm47xx/nvram.h>
159  
160  struct ssb_bus ssb_bcm47xx;
161  EXPORT_SYMBOL(ssb_bcm47xx);
162 @@ -81,28 +82,42 @@ static int bcm47xx_get_invariants(struct
163         /* Fill boardinfo structure */
164         memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
165  
166 -       if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0)
167 +       if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0 ||
168 +           nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
169                 iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
170 -       if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0)
171 +       if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0 ||
172 +           nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
173                 iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
174 -       if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0)
175 +       if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0 ||
176 +           nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
177                 iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
178  
179         /* Fill sprom structure */
180         memset(&(iv->sprom), 0, sizeof(struct ssb_sprom));
181         iv->sprom.revision = 3;
182  
183 -       if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
184 +       if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0 ||
185 +           nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
186                 str2eaddr(buf, iv->sprom.et0mac);
187 -       if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
188 +
189 +       if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0 ||
190 +           nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
191                 str2eaddr(buf, iv->sprom.et1mac);
192 -       if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
193 -               iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 10);
194 -       if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
195 -               iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 10);
196 -       if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
197 +
198 +       if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0 ||
199 +           nvram_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
200 +               iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 0);
201 +
202 +       if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0 ||
203 +           nvram_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
204 +               iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 0);
205 +
206 +       if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0 ||
207 +           nvram_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
208                 iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10);
209 -       if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
210 +
211 +       if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0 ||
212 +           nvram_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
213                 iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10);
214  
215         return 0;
216 --- /dev/null
217 +++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h
218 @@ -0,0 +1,36 @@
219 +/*
220 + *  Copyright (C) 2005, Broadcom Corporation
221 + *  Copyright (C) 2006, Felix Fietkau <nbd@openwrt.org>
222 + *
223 + *  This program is free software; you can redistribute  it and/or modify it
224 + *  under  the terms of  the GNU General  Public License as published by the
225 + *  Free Software Foundation;  either version 2 of the  License, or (at your
226 + *  option) any later version.
227 + */
228 +
229 +#ifndef __NVRAM_H
230 +#define __NVRAM_H
231 +
232 +#include <linux/types.h>
233 +
234 +struct nvram_header {
235 +       u32 magic;
236 +       u32 len;
237 +       u32 crc_ver_init;       /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
238 +       u32 config_refresh;     /* 0:15 sdram_config, 16:31 sdram_refresh */
239 +       u32 config_ncdl;        /* ncdl values for memc */
240 +};
241 +
242 +#define NVRAM_HEADER           0x48534C46      /* 'FLSH' */
243 +#define NVRAM_VERSION          1
244 +#define NVRAM_HEADER_SIZE      20
245 +#define NVRAM_SPACE            0x8000
246 +
247 +#define FLASH_MIN              0x00020000      /* Minimum flash size */
248 +
249 +#define NVRAM_MAX_VALUE_LEN 255
250 +#define NVRAM_MAX_PARAM_LEN 64
251 +
252 +extern int nvram_getenv(char *name, char *val, size_t val_len);
253 +
254 +#endif