Date: | 2010-08-03 22:35:53 (13 years 7 months ago) |
---|---|
Author: | hauke |
Commit: | fa5411e7e4ae9c4c99a897069ac7757d8748d5df |
Message: | brcm47xx: ignore some parts of flash on some netgear devices. This
space is used to store config values. When overwriting it the device
will not start any more. closes #7630 Thank you realopty for testing. git-svn-id: svn://svn.openwrt.org/openwrt/trunk@22475 3c298f89-4303-0410-b956-a3cf2f4a3e73 |
Files: |
target/linux/brcm47xx/files-2.6.34/drivers/mtd/maps/bcm47xx-flash.c (5 diffs) target/linux/brcm47xx/files-2.6.35/drivers/mtd/maps/bcm47xx-flash.c (5 diffs) |
Change Details
target/linux/brcm47xx/files-2.6.34/drivers/mtd/maps/bcm47xx-flash.c | ||
---|---|---|
52 | 52 | #include <linux/ssb/ssb.h> |
53 | 53 | #endif |
54 | 54 | #include <asm/io.h> |
55 | #include <asm/mach-bcm47xx/nvram.h> | |
56 | #include <asm/fw/cfe/cfe_api.h> | |
55 | 57 | |
56 | 58 | |
57 | 59 | #define TRX_MAGIC 0x30524448 /* "HDR0" */ |
... | ... | |
75 | 77 | #define WINDOW_SIZE 0x400000 |
76 | 78 | #define BUSWIDTH 2 |
77 | 79 | |
80 | #define ROUTER_NETGEAR_WGR614L 1 | |
81 | #define ROUTER_NETGEAR_WNR834B 2 | |
82 | #define ROUTER_NETGEAR_WNDR3300 3 | |
83 | #define ROUTER_NETGEAR_WNR3500L 4 | |
84 | ||
78 | 85 | #ifdef CONFIG_SSB |
79 | 86 | extern struct ssb_bus ssb_bcm47xx; |
80 | 87 | #endif |
... | ... | |
344 | 351 | return part->size; |
345 | 352 | } |
346 | 353 | |
354 | static int get_router(void) | |
355 | { | |
356 | char buf[20]; | |
357 | u32 boardnum = 0; | |
358 | u16 boardtype = 0; | |
359 | u16 boardrev = 0; | |
360 | u32 boardflags = 0; | |
361 | u16 sdram_init = 0; | |
362 | u16 cardbus = 0; | |
363 | ||
364 | if (nvram_getenv("boardnum", buf, sizeof(buf)) >= 0 || | |
365 | cfe_getenv("boardnum", buf, sizeof(buf)) >= 0) | |
366 | boardnum = simple_strtoul(buf, NULL, 0); | |
367 | if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0 || | |
368 | cfe_getenv("boardtype", buf, sizeof(buf)) >= 0) | |
369 | boardtype = simple_strtoul(buf, NULL, 0); | |
370 | if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0 || | |
371 | cfe_getenv("boardrev", buf, sizeof(buf)) >= 0) | |
372 | boardrev = simple_strtoul(buf, NULL, 0); | |
373 | if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0 || | |
374 | cfe_getenv("boardflags", buf, sizeof(buf)) >= 0) | |
375 | boardflags = simple_strtoul(buf, NULL, 0); | |
376 | if (nvram_getenv("sdram_init", buf, sizeof(buf)) >= 0 || | |
377 | cfe_getenv("sdram_init", buf, sizeof(buf)) >= 0) | |
378 | sdram_init = simple_strtoul(buf, NULL, 0); | |
379 | if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0 || | |
380 | cfe_getenv("cardbus", buf, sizeof(buf)) >= 0) | |
381 | cardbus = simple_strtoul(buf, NULL, 0); | |
382 | ||
383 | if ((boardnum == 8 || boardnum == 01) | |
384 | && boardtype == 0x0472 && cardbus == 1) { | |
385 | /* Netgear WNR834B, Netgear WNR834Bv2 */ | |
386 | return ROUTER_NETGEAR_WNR834B; | |
387 | } | |
388 | ||
389 | if (boardnum == 01 && boardtype == 0x0472 && boardrev == 0x23) { | |
390 | /* Netgear WNDR-3300 */ | |
391 | return ROUTER_NETGEAR_WNDR3300; | |
392 | } | |
393 | ||
394 | if ((boardnum == 83258 || boardnum == 01) | |
395 | && boardtype == 0x048e | |
396 | && (boardrev == 0x11 || boardrev == 0x10) | |
397 | && boardflags == 0x750 | |
398 | && sdram_init == 0x000A) { | |
399 | /* Netgear WGR614v8/L/WW 16MB ram, cfe v1.3 or v1.5 */ | |
400 | return ROUTER_NETGEAR_WGR614L; | |
401 | } | |
402 | ||
403 | if ((boardnum == 1 || boardnum == 3500) | |
404 | && boardtype == 0x04CF | |
405 | && (boardrev == 0x1213 || boardrev == 02)) { | |
406 | /* Netgear WNR3500v2/U/L */ | |
407 | return ROUTER_NETGEAR_WNR3500L; | |
408 | } | |
409 | ||
410 | return 0; | |
411 | } | |
412 | ||
347 | 413 | struct mtd_partition * __init |
348 | 414 | init_mtd_partitions(struct mtd_info *mtd, size_t size) |
349 | 415 | { |
350 | 416 | int cfe_size; |
351 | 417 | int dual_image_offset = 0; |
418 | /* e.g Netgear 0x003e0000-0x003f0000 : "board_data", we exclude this | |
419 | * part from our mapping to prevent overwriting len/checksum on e.g. | |
420 | * Netgear WGR614v8/L/WW | |
421 | */ | |
422 | int board_data_size = 0; | |
423 | ||
424 | switch (get_router()) { | |
425 | case ROUTER_NETGEAR_WGR614L: | |
426 | case ROUTER_NETGEAR_WNR834B: | |
427 | case ROUTER_NETGEAR_WNDR3300: | |
428 | case ROUTER_NETGEAR_WNR3500L: | |
429 | /* Netgear: checksum is @ 0x003AFFF8 for 4M flash or checksum | |
430 | * is @ 0x007AFFF8 for 8M flash | |
431 | */ | |
432 | board_data_size = 4 * mtd->erasesize; | |
433 | break; | |
434 | } | |
352 | 435 | |
353 | 436 | if ((cfe_size = find_cfe_size(mtd,size)) < 0) |
354 | 437 | return NULL; |
... | ... | |
374 | 457 | if (cfe_size != 384 * 1024) { |
375 | 458 | bcm47xx_parts[1].offset = bcm47xx_parts[0].size; |
376 | 459 | bcm47xx_parts[1].size = bcm47xx_parts[3].offset - dual_image_offset - |
377 | bcm47xx_parts[1].offset; | |
460 | bcm47xx_parts[1].offset - board_data_size; | |
378 | 461 | } else { |
379 | 462 | /* do not count the elf loader, which is on one block */ |
380 | 463 | bcm47xx_parts[1].offset = bcm47xx_parts[0].size + |
... | ... | |
382 | 465 | bcm47xx_parts[1].size = size - |
383 | 466 | bcm47xx_parts[0].size - |
384 | 467 | (2*bcm47xx_parts[3].size) - |
385 | mtd->erasesize; | |
468 | mtd->erasesize - board_data_size; | |
386 | 469 | } |
387 | 470 | |
388 | 471 | /* find and size rootfs */ |
389 | 472 | find_root(mtd,size,&bcm47xx_parts[2]); |
390 | bcm47xx_parts[2].size = size - dual_image_offset - bcm47xx_parts[2].offset - bcm47xx_parts[3].size; | |
473 | bcm47xx_parts[2].size = size - dual_image_offset - | |
474 | bcm47xx_parts[2].offset - | |
475 | bcm47xx_parts[3].size - board_data_size; | |
391 | 476 | |
392 | 477 | return bcm47xx_parts; |
393 | 478 | } |
target/linux/brcm47xx/files-2.6.35/drivers/mtd/maps/bcm47xx-flash.c | ||
---|---|---|
52 | 52 | #include <linux/ssb/ssb.h> |
53 | 53 | #endif |
54 | 54 | #include <asm/io.h> |
55 | #include <asm/mach-bcm47xx/nvram.h> | |
56 | #include <asm/fw/cfe/cfe_api.h> | |
55 | 57 | |
56 | 58 | |
57 | 59 | #define TRX_MAGIC 0x30524448 /* "HDR0" */ |
... | ... | |
75 | 77 | #define WINDOW_SIZE 0x400000 |
76 | 78 | #define BUSWIDTH 2 |
77 | 79 | |
80 | #define ROUTER_NETGEAR_WGR614L 1 | |
81 | #define ROUTER_NETGEAR_WNR834B 2 | |
82 | #define ROUTER_NETGEAR_WNDR3300 3 | |
83 | #define ROUTER_NETGEAR_WNR3500L 4 | |
84 | ||
78 | 85 | #ifdef CONFIG_SSB |
79 | 86 | extern struct ssb_bus ssb_bcm47xx; |
80 | 87 | #endif |
... | ... | |
344 | 351 | return part->size; |
345 | 352 | } |
346 | 353 | |
354 | static int get_router(void) | |
355 | { | |
356 | char buf[20]; | |
357 | u32 boardnum = 0; | |
358 | u16 boardtype = 0; | |
359 | u16 boardrev = 0; | |
360 | u32 boardflags = 0; | |
361 | u16 sdram_init = 0; | |
362 | u16 cardbus = 0; | |
363 | ||
364 | if (nvram_getenv("boardnum", buf, sizeof(buf)) >= 0 || | |
365 | cfe_getenv("boardnum", buf, sizeof(buf)) >= 0) | |
366 | boardnum = simple_strtoul(buf, NULL, 0); | |
367 | if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0 || | |
368 | cfe_getenv("boardtype", buf, sizeof(buf)) >= 0) | |
369 | boardtype = simple_strtoul(buf, NULL, 0); | |
370 | if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0 || | |
371 | cfe_getenv("boardrev", buf, sizeof(buf)) >= 0) | |
372 | boardrev = simple_strtoul(buf, NULL, 0); | |
373 | if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0 || | |
374 | cfe_getenv("boardflags", buf, sizeof(buf)) >= 0) | |
375 | boardflags = simple_strtoul(buf, NULL, 0); | |
376 | if (nvram_getenv("sdram_init", buf, sizeof(buf)) >= 0 || | |
377 | cfe_getenv("sdram_init", buf, sizeof(buf)) >= 0) | |
378 | sdram_init = simple_strtoul(buf, NULL, 0); | |
379 | if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0 || | |
380 | cfe_getenv("cardbus", buf, sizeof(buf)) >= 0) | |
381 | cardbus = simple_strtoul(buf, NULL, 0); | |
382 | ||
383 | if ((boardnum == 8 || boardnum == 01) | |
384 | && boardtype == 0x0472 && cardbus == 1) { | |
385 | /* Netgear WNR834B, Netgear WNR834Bv2 */ | |
386 | return ROUTER_NETGEAR_WNR834B; | |
387 | } | |
388 | ||
389 | if (boardnum == 01 && boardtype == 0x0472 && boardrev == 0x23) { | |
390 | /* Netgear WNDR-3300 */ | |
391 | return ROUTER_NETGEAR_WNDR3300; | |
392 | } | |
393 | ||
394 | if ((boardnum == 83258 || boardnum == 01) | |
395 | && boardtype == 0x048e | |
396 | && (boardrev == 0x11 || boardrev == 0x10) | |
397 | && boardflags == 0x750 | |
398 | && sdram_init == 0x000A) { | |
399 | /* Netgear WGR614v8/L/WW 16MB ram, cfe v1.3 or v1.5 */ | |
400 | return ROUTER_NETGEAR_WGR614L; | |
401 | } | |
402 | ||
403 | if ((boardnum == 1 || boardnum == 3500) | |
404 | && boardtype == 0x04CF | |
405 | && (boardrev == 0x1213 || boardrev == 02)) { | |
406 | /* Netgear WNR3500v2/U/L */ | |
407 | return ROUTER_NETGEAR_WNR3500L; | |
408 | } | |
409 | ||
410 | return 0; | |
411 | } | |
412 | ||
347 | 413 | struct mtd_partition * __init |
348 | 414 | init_mtd_partitions(struct mtd_info *mtd, size_t size) |
349 | 415 | { |
350 | 416 | int cfe_size; |
351 | 417 | int dual_image_offset = 0; |
418 | /* e.g Netgear 0x003e0000-0x003f0000 : "board_data", we exclude this | |
419 | * part from our mapping to prevent overwriting len/checksum on e.g. | |
420 | * Netgear WGR614v8/L/WW | |
421 | */ | |
422 | int board_data_size = 0; | |
423 | ||
424 | switch (get_router()) { | |
425 | case ROUTER_NETGEAR_WGR614L: | |
426 | case ROUTER_NETGEAR_WNR834B: | |
427 | case ROUTER_NETGEAR_WNDR3300: | |
428 | case ROUTER_NETGEAR_WNR3500L: | |
429 | /* Netgear: checksum is @ 0x003AFFF8 for 4M flash or checksum | |
430 | * is @ 0x007AFFF8 for 8M flash | |
431 | */ | |
432 | board_data_size = 4 * mtd->erasesize; | |
433 | break; | |
434 | } | |
352 | 435 | |
353 | 436 | if ((cfe_size = find_cfe_size(mtd,size)) < 0) |
354 | 437 | return NULL; |
... | ... | |
374 | 457 | if (cfe_size != 384 * 1024) { |
375 | 458 | bcm47xx_parts[1].offset = bcm47xx_parts[0].size; |
376 | 459 | bcm47xx_parts[1].size = bcm47xx_parts[3].offset - dual_image_offset - |
377 | bcm47xx_parts[1].offset; | |
460 | bcm47xx_parts[1].offset - board_data_size; | |
378 | 461 | } else { |
379 | 462 | /* do not count the elf loader, which is on one block */ |
380 | 463 | bcm47xx_parts[1].offset = bcm47xx_parts[0].size + |
... | ... | |
382 | 465 | bcm47xx_parts[1].size = size - |
383 | 466 | bcm47xx_parts[0].size - |
384 | 467 | (2*bcm47xx_parts[3].size) - |
385 | mtd->erasesize; | |
468 | mtd->erasesize - board_data_size; | |
386 | 469 | } |
387 | 470 | |
388 | 471 | /* find and size rootfs */ |
389 | 472 | find_root(mtd,size,&bcm47xx_parts[2]); |
390 | bcm47xx_parts[2].size = size - dual_image_offset - bcm47xx_parts[2].offset - bcm47xx_parts[3].size; | |
473 | bcm47xx_parts[2].size = size - dual_image_offset - | |
474 | bcm47xx_parts[2].offset - | |
475 | bcm47xx_parts[3].size - board_data_size; | |
391 | 476 | |
392 | 477 | return bcm47xx_parts; |
393 | 478 | } |