summaryrefslogtreecommitdiffstats
path: root/target/linux/ixp4xx/patches/139-ixp4xx_net_driver_mtd_load_fw.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ixp4xx/patches/139-ixp4xx_net_driver_mtd_load_fw.patch')
-rw-r--r--target/linux/ixp4xx/patches/139-ixp4xx_net_driver_mtd_load_fw.patch392
1 files changed, 392 insertions, 0 deletions
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 000000000..ef53155c0
--- /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 <chohnstaedt@innominate.com>
++ *
++ * This file is released under the GPLv2
++ */
++
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/firmware.h>
++#include <linux/mtd/mtd.h>
++
++#include <linux/ixp_npe.h>
++
++#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 <a.zummo@towertech.it>");
+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 <linux/firmware.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/byteorder/swab.h>
++#include <linux/crc16.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+
+@@ -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