2 drivers/net/ixp4xx/Kconfig | 10 +
3 drivers/net/ixp4xx/Makefile | 1
4 drivers/net/ixp4xx/npe_ucode.c | 185 +++++++++++++++++++++++++++++++++
5 drivers/net/ixp4xx/ucode_dl.c | 43 ++++---
6 include/asm-arm/arch-ixp4xx/platform.h | 19 +++
7 include/linux/ixp_npe.h | 1
8 6 files changed, 239 insertions(+), 20 deletions(-)
10 Index: linux-2.6.21.7/drivers/net/ixp4xx/Kconfig
11 ===================================================================
12 --- linux-2.6.21.7.orig/drivers/net/ixp4xx/Kconfig
13 +++ linux-2.6.21.7/drivers/net/ixp4xx/Kconfig
14 @@ -11,6 +11,7 @@ config IXP4XX_NPE
15 tristate "IXP4xx NPE support"
16 depends on ARCH_IXP4XX
17 depends on NET_ETHERNET
20 The IXP4XX NPE driver supports the 3 CPU co-processors called
21 "Network Processing Engines" (NPE). It adds support fo downloading
22 @@ -18,7 +19,7 @@ config IXP4XX_NPE
23 More about this at: Documentation/networking/ixp4xx/README.
24 You can either use this OR the Intel Access Library (IAL)
26 -config IXP4XX_FW_LOAD
27 +config IXP4XX_NPE_FW_LOAD
28 bool "Use Firmware hotplug for Microcode download"
31 @@ -28,6 +29,13 @@ config IXP4XX_FW_LOAD
32 /usr/lib/hotplug/firmware/NPE-[ABC]
33 see Documentation/firmware_class/hotplug-script
35 +config IXP4XX_NPE_FW_MTD
36 + bool "Load firmware from an mtd partition"
37 + depends on IXP4XX_NPE && MTD_IXP4XX
39 + With this option, the driver will search for
40 + the firmware into an MTD partition.
43 tristate "IXP4xx MAC support"
45 Index: linux-2.6.21.7/drivers/net/ixp4xx/Makefile
46 ===================================================================
47 --- linux-2.6.21.7.orig/drivers/net/ixp4xx/Makefile
48 +++ linux-2.6.21.7/drivers/net/ixp4xx/Makefile
50 obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx_qmgr.o
51 obj-$(CONFIG_IXP4XX_NPE) += ixp4xx_npe.o
52 +obj-$(CONFIG_IXP4XX_NPE_FW_MTD) += npe_ucode.o
53 obj-$(CONFIG_IXP4XX_MAC) += ixp4xx_mac.o
54 obj-$(CONFIG_IXP4XX_CRYPTO) += ixp4xx_crypto.o
56 Index: linux-2.6.21.7/drivers/net/ixp4xx/npe_ucode.c
57 ===================================================================
59 +++ linux-2.6.21.7/drivers/net/ixp4xx/npe_ucode.c
62 + * Provide an NPE platform device for microcode handling
64 + * Copyright (C) 2006 Christian Hohnstaedt <chohnstaedt@innominate.com>
66 + * This file is released under the GPLv2
69 +#include <linux/kernel.h>
70 +#include <linux/platform_device.h>
71 +#include <linux/init.h>
72 +#include <linux/slab.h>
73 +#include <linux/firmware.h>
74 +#include <linux/mtd/mtd.h>
76 +#include <linux/ixp_npe.h>
78 +#define DL_MAGIC 0xfeedf00d
79 +#define DL_MAGIC_SWAP 0x0df0edfe
81 +#define IMG_SIZE(image) (((image)->size * sizeof(u32)) + \
82 + sizeof(struct dl_image))
84 +#define IMG_REV_MAJOR(id) (((id) >> 8) & 0x0f)
85 +#define IMG_REV_MINOR(id) ((id) & 0x0f)
86 +#define IMG_FUNC(id) (((id) >> 16) & 0xff)
87 +#define IMG_NPE(id) (((id) >> 24) & 0x0f)
88 +#define IMG_IXP(id) (((id) >> 28) & 0x0f)
90 +static struct platform_driver ixp4xx_npe_ucode_driver;
91 +static unsigned char *partition_name = NULL;
93 +static void print_image_info(u32 id, u32 offset, u32 size)
96 + const char *names[] = { "IXP425", "IXP465", "unknown" };
98 + idx = IMG_IXP(id) < 2 ? IMG_IXP(id) : 2;
100 + printk(KERN_INFO "npe: found at 0x%x, %s/NPE-%c func: %02x, rev: %x.%x, "
101 + "size: %5d, id: %08x\n", offset, names[idx], IMG_NPE(id) + 'A',
102 + IMG_FUNC(id), IMG_REV_MAJOR(id), IMG_REV_MINOR(id), size, id);
105 +void npe_swap_image(struct dl_image *image)
109 + image->magic = swab32(image->magic);
110 + image->id = swab32(image->id);
111 + image->size = swab32(image->size);
113 + for (i = 0; i < image->size; i++)
114 + image->u.data[i] = swab32(image->u.data[i]);
117 +static void npe_find_microcode(struct mtd_info *mtd)
120 + u32 magic = htonl(DL_MAGIC);
124 + unsigned int offset = 0;
126 + printk("npe: searching for firmware...\n");
128 + while (offset < mtd->size) {
130 + err = mtd->read(mtd, offset, 4, &retlen, (u_char *) &buf);
136 + err = mtd->read(mtd, offset, 4, &retlen, (u_char *) &id);
144 + err = mtd->read(mtd, offset, 4, &retlen, (u_char *) &size);
147 + size = (ntohl(size) * 4) + 12;
149 + print_image_info(id, offset - 12, size);
151 + if (size < 24000 && ( IMG_FUNC(id) == 0x01 || IMG_FUNC(id) == 0x00) || IMG_FUNC(id) == 0x05 ) { // XXX fix size/detection
153 + struct dl_image *image = kmalloc(size, GFP_KERNEL);
155 + /* we are going to load it, rewind offset */
159 + err = mtd->read(mtd, offset, size, &retlen, (u_char *) image);
161 + if (err == 0 && retlen == size) {
162 + if (image->magic == DL_MAGIC_SWAP)
163 + npe_swap_image(image);
165 + store_npe_image(image, NULL);
167 + printk(KERN_ERR "unable to read firmware\n");
178 +static void npe_flash_add(struct mtd_info *mtd)
180 + if (partition_name == NULL)
183 + if (strcmp(mtd->name, partition_name) == 0) {
184 + npe_find_microcode(mtd);
188 +static void npe_flash_remove(struct mtd_info *mtd) {
191 +static struct mtd_notifier npe_flash_notifier = {
192 + .add = npe_flash_add,
193 + .remove = npe_flash_remove,
196 +static int npe_ucode_probe(struct platform_device *pdev)
198 + struct npe_ucode_platform_data *data = pdev->dev.platform_data;
200 + if (partition_name)
203 + if (data && data->mtd_partition) {
204 + partition_name = data->mtd_partition;
211 +static int npe_ucode_remove(struct platform_device *pdev)
216 +static struct platform_driver ixp4xx_npe_ucode_driver = {
218 + .name = "ixp4xx_npe_ucode",
219 + .owner = THIS_MODULE,
221 + .probe = npe_ucode_probe,
222 + .remove = npe_ucode_remove,
225 +static int __init npe_ucode_init(void)
229 + ret = platform_driver_register(&ixp4xx_npe_ucode_driver);
230 + register_mtd_user(&npe_flash_notifier);
235 +static void __exit npe_ucode_exit(void)
237 + unregister_mtd_user(&npe_flash_notifier);
238 + platform_driver_unregister(&ixp4xx_npe_ucode_driver);
241 +module_init(npe_ucode_init);
242 +module_exit(npe_ucode_exit);
244 +MODULE_LICENSE("GPL");
245 +MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
246 Index: linux-2.6.21.7/drivers/net/ixp4xx/ucode_dl.c
247 ===================================================================
248 --- linux-2.6.21.7.orig/drivers/net/ixp4xx/ucode_dl.c
249 +++ linux-2.6.21.7/drivers/net/ixp4xx/ucode_dl.c
251 #include <linux/firmware.h>
252 #include <linux/dma-mapping.h>
253 #include <linux/byteorder/swab.h>
254 +#include <linux/crc16.h>
255 #include <asm/uaccess.h>
259 #define DL_MAGIC 0xfeedf00d
260 #define DL_MAGIC_SWAP 0x0df0edfe
262 +#define IMG_REV_MAJOR(id) (((id) >> 8) & 0x0f)
263 +#define IMG_REV_MINOR(id) ((id) & 0x0f)
264 +#define IMG_FUNC(id) (((id) >> 16) & 0xff)
265 +#define IMG_NPE(id) (((id) >> 24) & 0x0f)
266 +#define IMG_IXP(id) (((id) >> 28) & 0x0f)
268 #define EOF_BLOCK 0xf
269 #define IMG_SIZE(image) (((image)->size * sizeof(u32)) + \
270 sizeof(struct dl_image))
271 @@ -38,21 +45,6 @@ enum blk_type {
286 - struct dl_block block[0];
290 struct dl_codeblock {
293 @@ -127,20 +119,33 @@ download_block(struct npe_info *npe, str
297 -static int store_npe_image(struct dl_image *image, struct device *dev)
298 +int store_npe_image(struct dl_image *image, struct device *dev)
300 struct dl_block *blk;
301 struct dl_codeblock *cb;
302 struct npe_info *npe;
307 - dev = get_npe_by_id( (image->id >> 24) & 0xf);
308 + dev = get_npe_by_id(IMG_NPE(image->id));
314 + if (image->size > 24000) { // XXX fix max size
315 + printk(KERN_ERR "npe: firmware too large\n");
319 + if (IMG_REV_MAJOR(image->id) != 2) {
320 + printk(KERN_ERR "npe: only revision 2 is supported at this time\n");
324 + crc = crc16(0, (u8 *) image, IMG_SIZE(image));
326 npe = dev_get_drvdata(dev);
327 if (npe->loaded && (npe->usage > 0)) {
328 printk(KERN_INFO "Cowardly refusing to reload an Image "
329 @@ -267,8 +272,7 @@ static ssize_t ucode_write(struct file *
331 static void npe_firmware_probe(struct device *dev)
333 -#if (defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)) \
335 +#ifdef CONFIG_IXP4XX_NPE_FW_LOADER
336 const struct firmware *fw_entry;
337 struct npe_info *npe = dev_get_drvdata(dev);
338 struct dl_image *image;
339 @@ -477,3 +481,4 @@ MODULE_AUTHOR("Christian Hohnstaedt <cho
341 EXPORT_SYMBOL(get_npe_by_id);
342 EXPORT_SYMBOL(return_npe_dev);
343 +EXPORT_SYMBOL(store_npe_image);
344 Index: linux-2.6.21.7/include/asm-arm/arch-ixp4xx/platform.h
345 ===================================================================
346 --- linux-2.6.21.7.orig/include/asm-arm/arch-ixp4xx/platform.h
347 +++ linux-2.6.21.7/include/asm-arm/arch-ixp4xx/platform.h
348 @@ -86,6 +86,21 @@ struct ixp4xx_i2c_pins {
349 unsigned long scl_pin;
363 + struct dl_block block[0];
367 struct npe_plat_data {
370 @@ -105,6 +120,10 @@ struct mac_plat_info {
374 +struct npe_ucode_platform_data {
375 + unsigned char *mtd_partition;
379 * This structure provide a means for the board setup code
380 * to give information to th pata_ixp4xx driver. It is
381 Index: linux-2.6.21.7/include/linux/ixp_npe.h
382 ===================================================================
383 --- linux-2.6.21.7.orig/include/linux/ixp_npe.h
384 +++ linux-2.6.21.7/include/linux/ixp_npe.h
385 @@ -99,6 +99,7 @@ extern void npe_reset(struct npe_info *n
387 extern struct device *get_npe_by_id(int id);
388 extern void return_npe_dev(struct device *dev);
389 +extern int store_npe_image(struct dl_image *image, struct device *dev);