X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Fixp4xx%2Fpatches%2F139-ixp4xx_net_driver_mtd_load_fw.patch;fp=target%2Flinux%2Fixp4xx%2Fpatches%2F139-ixp4xx_net_driver_mtd_load_fw.patch;h=ef53155c039bef3d822a7c6e980a5d3ccfaffb4c;hb=56231056ea784f1cec6450f649b1adaed1f56366;hp=0000000000000000000000000000000000000000;hpb=e1184aaa1a7a5e5eeef8e072bf0ea98c291be22a;p=openwrt%2Fstaging%2Fwigyori.git diff --git a/target/linux/ixp4xx/patches/139-ixp4xx_net_driver_mtd_load_fw.patch b/target/linux/ixp4xx/patches/139-ixp4xx_net_driver_mtd_load_fw.patch new file mode 100644 index 0000000000..ef53155c03 --- /dev/null +++ b/target/linux/ixp4xx/patches/139-ixp4xx_net_driver_mtd_load_fw.patch @@ -0,0 +1,392 @@ +--- + drivers/net/ixp4xx/Kconfig | 10 + + drivers/net/ixp4xx/Makefile | 1 + drivers/net/ixp4xx/npe_ucode.c | 185 +++++++++++++++++++++++++++++++++ + drivers/net/ixp4xx/ucode_dl.c | 43 ++++--- + include/asm-arm/arch-ixp4xx/platform.h | 19 +++ + include/linux/ixp_npe.h | 1 + 6 files changed, 239 insertions(+), 20 deletions(-) + +Index: linux-2.6.20-rc3/drivers/net/ixp4xx/Kconfig +=================================================================== +--- linux-2.6.20-rc3.orig/drivers/net/ixp4xx/Kconfig ++++ linux-2.6.20-rc3/drivers/net/ixp4xx/Kconfig +@@ -11,6 +11,7 @@ + tristate "IXP4xx NPE support" + depends on ARCH_IXP4XX + depends on NET_ETHERNET ++ select CRC16 + help + The IXP4XX NPE driver supports the 3 CPU co-processors called + "Network Processing Engines" (NPE). It adds support fo downloading +@@ -18,7 +19,7 @@ + More about this at: Documentation/networking/ixp4xx/README. + You can either use this OR the Intel Access Library (IAL) + +-config IXP4XX_FW_LOAD ++config IXP4XX_NPE_FW_LOAD + bool "Use Firmware hotplug for Microcode download" + depends on IXP4XX_NPE + select HOTPLUG +@@ -28,6 +29,13 @@ + /usr/lib/hotplug/firmware/NPE-[ABC] + see Documentation/firmware_class/hotplug-script + ++config IXP4XX_NPE_FW_MTD ++ bool "Load firmware from an mtd partition" ++ depends on IXP4XX_NPE && MTD_IXP4XX ++ help ++ With this option, the driver will search for ++ the firmware into an MTD partition. ++ + config IXP4XX_MAC + tristate "IXP4xx MAC support" + depends on IXP4XX_NPE +Index: linux-2.6.20-rc3/drivers/net/ixp4xx/Makefile +=================================================================== +--- linux-2.6.20-rc3.orig/drivers/net/ixp4xx/Makefile ++++ linux-2.6.20-rc3/drivers/net/ixp4xx/Makefile +@@ -1,5 +1,6 @@ + obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx_qmgr.o + obj-$(CONFIG_IXP4XX_NPE) += ixp4xx_npe.o ++obj-$(CONFIG_IXP4XX_NPE_FW_MTD) += npe_ucode.o + obj-$(CONFIG_IXP4XX_MAC) += ixp4xx_mac.o + obj-$(CONFIG_IXP4XX_CRYPTO) += ixp4xx_crypto.o + +Index: linux-2.6.20-rc3/drivers/net/ixp4xx/npe_ucode.c +=================================================================== +--- /dev/null ++++ linux-2.6.20-rc3/drivers/net/ixp4xx/npe_ucode.c +@@ -0,0 +1,185 @@ ++/* ++ * Provide an NPE platform device for microcode handling ++ * ++ * Copyright (C) 2006 Christian Hohnstaedt ++ * ++ * This file is released under the GPLv2 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define DL_MAGIC 0xfeedf00d ++#define DL_MAGIC_SWAP 0x0df0edfe ++ ++#define IMG_SIZE(image) (((image)->size * sizeof(u32)) + \ ++ sizeof(struct dl_image)) ++ ++#define IMG_REV_MAJOR(id) (((id) >> 8) & 0x0f) ++#define IMG_REV_MINOR(id) ((id) & 0x0f) ++#define IMG_FUNC(id) (((id) >> 16) & 0xff) ++#define IMG_NPE(id) (((id) >> 24) & 0x0f) ++#define IMG_IXP(id) (((id) >> 28) & 0x0f) ++ ++static struct platform_driver ixp4xx_npe_ucode_driver; ++static unsigned char *partition_name = NULL; ++ ++static void print_image_info(u32 id, u32 offset, u32 size) ++{ ++ unsigned char idx; ++ const char *names[] = { "IXP425", "IXP465", "unknown" }; ++ ++ idx = IMG_IXP(id) < 2 ? IMG_IXP(id) : 2; ++ ++ printk(KERN_INFO "npe: found at 0x%x, %s/NPE-%c func: %02x, rev: %x.%x, " ++ "size: %5d, id: %08x\n", offset, names[idx], IMG_NPE(id) + 'A', ++ IMG_FUNC(id), IMG_REV_MAJOR(id), IMG_REV_MINOR(id), size, id); ++} ++ ++void npe_swap_image(struct dl_image *image) ++{ ++ unsigned int i; ++ ++ image->magic = swab32(image->magic); ++ image->id = swab32(image->id); ++ image->size = swab32(image->size); ++ ++ for (i = 0; i < image->size; i++) ++ image->u.data[i] = swab32(image->u.data[i]); ++} ++ ++static void npe_find_microcode(struct mtd_info *mtd) ++{ ++ u32 buf; ++ u32 magic = htonl(DL_MAGIC); ++ u32 id, size; ++ size_t retlen; ++ int err; ++ unsigned int offset = 0; ++ ++ printk("npe: searching for firmware...\n"); ++ ++ while (offset < mtd->size) { ++ ++ err = mtd->read(mtd, offset, 4, &retlen, (u_char *) &buf); ++ offset += retlen; ++ ++ if (buf != magic) ++ continue; ++ ++ err = mtd->read(mtd, offset, 4, &retlen, (u_char *) &id); ++ offset += retlen; ++ ++ if (id == magic) ++ break; ++ ++ id = ntohl(id); ++ ++ err = mtd->read(mtd, offset, 4, &retlen, (u_char *) &size); ++ offset += retlen; ++ ++ size = (ntohl(size) * 4) + 12; ++ ++ print_image_info(id, offset - 12, size); ++ ++ if (size < 24000 && ( IMG_FUNC(id) == 0x01 || IMG_FUNC(id) == 0x00) || IMG_FUNC(id) == 0x05 ) { // XXX fix size/detection ++ ++ struct dl_image *image = kmalloc(size, GFP_KERNEL); ++ ++ /* we are going to load it, rewind offset */ ++ offset -= 12; ++ ++ if (image) { ++ err = mtd->read(mtd, offset, size, &retlen, (u_char *) image); ++ ++ if (err == 0 && retlen == size) { ++ if (image->magic == DL_MAGIC_SWAP) ++ npe_swap_image(image); ++ ++ store_npe_image(image, NULL); ++ } else { ++ printk(KERN_ERR "unable to read firmware\n"); ++ } ++ ++ kfree(image); ++ } ++ ++ offset += size; ++ } ++ } ++} ++ ++static void npe_flash_add(struct mtd_info *mtd) ++{ ++ if (partition_name == NULL) ++ return; ++ ++ if (strcmp(mtd->name, partition_name) == 0) { ++ npe_find_microcode(mtd); ++ } ++} ++ ++static void npe_flash_remove(struct mtd_info *mtd) { ++} ++ ++static struct mtd_notifier npe_flash_notifier = { ++ .add = npe_flash_add, ++ .remove = npe_flash_remove, ++}; ++ ++static int npe_ucode_probe(struct platform_device *pdev) ++{ ++ struct npe_ucode_platform_data *data = pdev->dev.platform_data; ++ ++ if (partition_name) ++ return -EEXIST; ++ ++ if (data && data->mtd_partition) { ++ partition_name = data->mtd_partition; ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ ++static int npe_ucode_remove(struct platform_device *pdev) ++{ ++ return 0; ++} ++ ++static struct platform_driver ixp4xx_npe_ucode_driver = { ++ .driver = { ++ .name = "ixp4xx_npe_ucode", ++ .owner = THIS_MODULE, ++ }, ++ .probe = npe_ucode_probe, ++ .remove = npe_ucode_remove, ++}; ++ ++static int __init npe_ucode_init(void) ++{ ++ int ret; ++ ++ ret = platform_driver_register(&ixp4xx_npe_ucode_driver); ++ register_mtd_user(&npe_flash_notifier); ++ ++ return ret; ++} ++ ++static void __exit npe_ucode_exit(void) ++{ ++ unregister_mtd_user(&npe_flash_notifier); ++ platform_driver_unregister(&ixp4xx_npe_ucode_driver); ++} ++ ++module_init(npe_ucode_init); ++module_exit(npe_ucode_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Alessandro Zummo "); +Index: linux-2.6.20-rc3/drivers/net/ixp4xx/ucode_dl.c +=================================================================== +--- linux-2.6.20-rc3.orig/drivers/net/ixp4xx/ucode_dl.c ++++ linux-2.6.20-rc3/drivers/net/ixp4xx/ucode_dl.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -26,6 +27,12 @@ + #define DL_MAGIC 0xfeedf00d + #define DL_MAGIC_SWAP 0x0df0edfe + ++#define IMG_REV_MAJOR(id) (((id) >> 8) & 0x0f) ++#define IMG_REV_MINOR(id) ((id) & 0x0f) ++#define IMG_FUNC(id) (((id) >> 16) & 0xff) ++#define IMG_NPE(id) (((id) >> 24) & 0x0f) ++#define IMG_IXP(id) (((id) >> 28) & 0x0f) ++ + #define EOF_BLOCK 0xf + #define IMG_SIZE(image) (((image)->size * sizeof(u32)) + \ + sizeof(struct dl_image)) +@@ -38,21 +45,6 @@ + data, + }; + +-struct dl_block { +- u32 type; +- u32 offset; +-}; +- +-struct dl_image { +- u32 magic; +- u32 id; +- u32 size; +- union { +- u32 data[0]; +- struct dl_block block[0]; +- } u; +-}; +- + struct dl_codeblock { + u32 npe_addr; + u32 size; +@@ -127,20 +119,33 @@ + return 0; + } + +-static int store_npe_image(struct dl_image *image, struct device *dev) ++int store_npe_image(struct dl_image *image, struct device *dev) + { + struct dl_block *blk; + struct dl_codeblock *cb; + struct npe_info *npe; + int ret=0; ++ u16 crc; + + if (!dev) { +- dev = get_npe_by_id( (image->id >> 24) & 0xf); ++ dev = get_npe_by_id(IMG_NPE(image->id)); + return_npe_dev(dev); + } + if (!dev) + return -ENODEV; + ++ if (image->size > 24000) { // XXX fix max size ++ printk(KERN_ERR "npe: firmware too large\n"); ++ return -EFBIG; ++ } ++ ++ if (IMG_REV_MAJOR(image->id) != 2) { ++ printk(KERN_ERR "npe: only revision 2 is supported at this time\n"); ++ return -EINVAL; ++ } ++ ++ crc = crc16(0, (u8 *) image, IMG_SIZE(image)); ++ + npe = dev_get_drvdata(dev); + if (npe->loaded && (npe->usage > 0)) { + printk(KERN_INFO "Cowardly refusing to reload an Image " +@@ -267,8 +272,7 @@ + + static void npe_firmware_probe(struct device *dev) + { +-#if (defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)) \ +- && defined(MODULE) ++#ifdef CONFIG_IXP4XX_NPE_FW_LOADER + const struct firmware *fw_entry; + struct npe_info *npe = dev_get_drvdata(dev); + struct dl_image *image; +@@ -477,3 +481,4 @@ + + EXPORT_SYMBOL(get_npe_by_id); + EXPORT_SYMBOL(return_npe_dev); ++EXPORT_SYMBOL(store_npe_image); +Index: linux-2.6.20-rc3/include/asm-arm/arch-ixp4xx/platform.h +=================================================================== +--- linux-2.6.20-rc3.orig/include/asm-arm/arch-ixp4xx/platform.h ++++ linux-2.6.20-rc3/include/asm-arm/arch-ixp4xx/platform.h +@@ -86,6 +86,21 @@ + unsigned long scl_pin; + }; + ++struct dl_block { ++ u32 type; ++ u32 offset; ++}; ++ ++struct dl_image { ++ u32 magic; ++ u32 id; ++ u32 size; ++ union { ++ u32 data[0]; ++ struct dl_block block[0]; ++ } u; ++}; ++ + struct npe_plat_data { + const char *name; + int data_size; +@@ -105,6 +120,10 @@ + + }; + ++struct npe_ucode_platform_data { ++ unsigned char *mtd_partition; ++}; ++ + /* + * This structure provide a means for the board setup code + * to give information to th pata_ixp4xx driver. It is +Index: linux-2.6.20-rc3/include/linux/ixp_npe.h +=================================================================== +--- linux-2.6.20-rc3.orig/include/linux/ixp_npe.h ++++ linux-2.6.20-rc3/include/linux/ixp_npe.h +@@ -99,6 +99,7 @@ + + extern struct device *get_npe_by_id(int id); + extern void return_npe_dev(struct device *dev); ++extern int store_npe_image(struct dl_image *image, struct device *dev); + + /* NPE Messages */ + extern int