diff -urN linux-2.6.26.2-orig/Makefile linux-2.6.26.2-blanca/Makefile --- linux-2.6.26.2-orig/Makefile 2008-08-07 01:19:01.000000000 +0900 +++ linux-2.6.26.2-blanca/Makefile 2009-07-22 21:34:22.000000000 +0900 @@ -181,6 +181,8 @@ # Another way is to have ARCH set in the environment. # The default ARCH is the host where make is executed. +ARCH=sh + # CROSS_COMPILE specify the prefix used for all executables used # during compilation. Only gcc and related bin-utils executables # are prefixed with $(CROSS_COMPILE). @@ -189,6 +191,8 @@ # Alternatively CROSS_COMPILE can be set in the environment. # Default value for CROSS_COMPILE is not to prefix executables # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile +CROSS_COMPILE=sh4-linux-gnu- + export KBUILD_BUILDHOST := $(SUBARCH) ARCH ?= $(SUBARCH) CROSS_COMPILE ?= @@ -584,6 +588,7 @@ # relocations required by build roots. This is not defined in the # makefile but the argument can be passed to make if needed. # +INSTALL_MOD_PATH=/tmp/ MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) export MODLIB @@ -1157,7 +1162,7 @@ distclean: mrproper @find $(srctree) $(RCS_FIND_IGNORE) \ - \( -name '*.orig' -o -name '*.rej' -o -name '*~' \ + \( -name '*.orig' -o -name '*.rej' -o -name '*~' -o -name '*.BAK' \ -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \ -o -name '.*.rej' -o -size 0 \ -o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \ diff -urN linux-2.6.26.2-orig/arch/sh/Kconfig linux-2.6.26.2-blanca/arch/sh/Kconfig --- linux-2.6.26.2-orig/arch/sh/Kconfig 2008-08-07 01:19:01.000000000 +0900 +++ linux-2.6.26.2-blanca/arch/sh/Kconfig 2008-08-25 20:42:00.000000000 +0900 @@ -414,6 +414,13 @@ Select 7780 SolutionEngine if configuring for a Renesas SH7780 evaluation board. +config SH_CQBLANCA + bool "CQPublic BLANCA SH4A" + select SYS_SUPPORTS_PCI + depends on CPU_SUBTYPE_SH7780 + help + CQPublic BLANCA and SH4A CPU board + config SH_7343_SOLUTION_ENGINE bool "SolutionEngine7343" select SOLUTION_ENGINE @@ -838,6 +845,11 @@ tristate "SuperHyway Bus support" depends on CPU_SUBTYPE_SH4_202 +config BLANCA_BUS + bool "BLANCA BUS BIOS" + help + CQ Public BLANCA BIOS + config MAPLE bool "Maple Bus support" depends on SH_DREAMCAST diff -urN linux-2.6.26.2-orig/arch/sh/Makefile linux-2.6.26.2-blanca/arch/sh/Makefile --- linux-2.6.26.2-orig/arch/sh/Makefile 2008-08-07 01:19:01.000000000 +0900 +++ linux-2.6.26.2-blanca/arch/sh/Makefile 2008-08-25 20:42:00.000000000 +0900 @@ -130,6 +130,7 @@ machdir-$(CONFIG_SH_LBOX_RE2) += lboxre2 machdir-$(CONFIG_SH_MAGIC_PANEL_R2) += magicpanelr2 machdir-$(CONFIG_SH_CAYMAN) += cayman +machdir-$(CONFIG_SH_CQBLANCA) += cqblanca incdir-y := $(notdir $(machdir-y)) diff -urN linux-2.6.26.2-orig/arch/sh/boards/cqblanca/Makefile linux-2.6.26.2-blanca/arch/sh/boards/cqblanca/Makefile --- linux-2.6.26.2-orig/arch/sh/boards/cqblanca/Makefile 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.26.2-blanca/arch/sh/boards/cqblanca/Makefile 2008-08-25 20:42:00.000000000 +0900 @@ -0,0 +1,4 @@ +# +# Makefile for the CQBLANCA specific parts of the kernel +# +obj-y := setup.o diff -urN linux-2.6.26.2-orig/arch/sh/boards/cqblanca/setup.c linux-2.6.26.2-blanca/arch/sh/boards/cqblanca/setup.c --- linux-2.6.26.2-orig/arch/sh/boards/cqblanca/setup.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.26.2-blanca/arch/sh/boards/cqblanca/setup.c 2009-07-22 21:10:07.000000000 +0900 @@ -0,0 +1,88 @@ +/* + * arch/sh/boards/cqblanca/setup.c + * + * CQ Public Blanca SH4A (SH7780) Board support. + * + * Copyright (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2005 - 2008 Paul Mundt + * Copyright (C) 2008 Yutaro Ebihara + * + */ + +#include +#include +#include +#include +#include +#include + +/* + * resource info + */ + +static struct resource blanca_bios_resources[] = { + { + .start = 0xA4000000, + .end = 0xA4000000, + .flags = IORESOURCE_MEM, + }, + { + .start = evt2irq(0x3c0), /* IRL[3:0] = HHHL */ + .end = evt2irq(0x3c0), /* IRL[3:0] = HHHL */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cqblanca_bios_device = { + .name = "blanca_bios", + .id = -1, + .num_resources = ARRAY_SIZE(blanca_bios_resources), + .resource = blanca_bios_resources, +}; + + +static struct platform_device *cqblanca_devices[] __initdata = { + &cqblanca_bios_device, +}; + + +static int __init cqblanca_devices_setup(void) +{ + int ret = 0; + + printk("%s()\n",__FUNCTION__); + + + ret |= platform_add_devices(cqblanca_devices, + ARRAY_SIZE(cqblanca_devices)); + + return ret; +} + + +/* + * Initialize the board + */ +static void __init cqblanca_setup(char **cmdline_p) +{ + printk("%s()\n",__FUNCTION__); +} + +void __init cqblanca_irq_setup(void) +{ + printk("%s()\n",__FUNCTION__); + plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK); +} + + +extern void cqblanca_irq_setup(void); +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_cqblanca __initmv = { + .mv_name = "CQPublic Blanca SH7780", + .mv_setup = cqblanca_setup, + .mv_init_irq = cqblanca_irq_setup, +}; + +device_initcall(cqblanca_devices_setup); diff -urN linux-2.6.26.2-orig/arch/sh/drivers/pci/Makefile linux-2.6.26.2-blanca/arch/sh/drivers/pci/Makefile --- linux-2.6.26.2-orig/arch/sh/drivers/pci/Makefile 2008-08-07 01:19:01.000000000 +0900 +++ linux-2.6.26.2-blanca/arch/sh/drivers/pci/Makefile 2009-07-16 13:22:01.000000000 +0900 @@ -23,3 +23,5 @@ obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-se7780.o obj-$(CONFIG_SH_CAYMAN) += ops-cayman.o +obj-$(CONFIG_SH_CQBLANCA) += ops-blanca7780.o fixups-r7780rp.o + diff -urN linux-2.6.26.2-orig/arch/sh/drivers/pci/ops-blanca7780.c linux-2.6.26.2-blanca/arch/sh/drivers/pci/ops-blanca7780.c --- linux-2.6.26.2-orig/arch/sh/drivers/pci/ops-blanca7780.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.26.2-blanca/arch/sh/drivers/pci/ops-blanca7780.c 2009-07-16 13:21:49.000000000 +0900 @@ -0,0 +1,73 @@ +/* + * CQPub blanca SH4A board + * based from Highly leveraged from pci-bigsur.c, written by Dustin McIntire. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * PCI initialization for the Renesas SH7780 CQPub BLANCA board + */ +#include +#include +#include +#include +#include +#include +#include +#include "pci-sh4.h" + +/* + * INTA-INTD are IRQ65-IRQ8 + * + */ + +#define PCI_INTA_IRQ 65 + +int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +{ + int irq = ((slot + pin - 1) & 0x3) + PCI_INTA_IRQ; + printk("%s() slot=%d, pin=%d,irq=%d\n",__FUNCTION__, + slot,pin,irq); + return irq; +} + +static struct resource sh7780_io_resource = { + .name = "SH7780_IO", + .start = SH7780_PCI_IO_BASE, + .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO +}; + +static struct resource sh7780_mem_resource = { + .name = "SH7780_mem", + .start = SH7780_PCI_MEMORY_BASE, + .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM +}; + +extern struct pci_ops sh7780_pci_ops; + +struct pci_channel board_pci_channels[] = { + { &sh4_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff }, + { NULL, NULL, NULL, 0, 0 }, +}; +EXPORT_SYMBOL(board_pci_channels); + +static struct sh4_pci_address_map sh7780_pci_map = { + .window0 = { + .base = SH7780_CS2_BASE_ADDR, + .size = 0x04000000, + }, + + .window1 = { + .base = SH7780_CS3_BASE_ADDR, + .size = 0x04000000, + }, + + .flags = SH4_PCIC_NO_RESET, +}; + +int __init pcibios_init_platform(void) +{ + return sh7780_pcic_init(&sh7780_pci_map); +} diff -urN linux-2.6.26.2-orig/drivers/Makefile linux-2.6.26.2-blanca/drivers/Makefile --- linux-2.6.26.2-orig/drivers/Makefile 2008-08-07 01:19:01.000000000 +0900 +++ linux-2.6.26.2-blanca/drivers/Makefile 2008-08-25 20:42:00.000000000 +0900 @@ -7,6 +7,7 @@ obj-$(CONFIG_HAVE_GPIO_LIB) += gpio/ obj-$(CONFIG_PCI) += pci/ +obj-$(CONFIG_BLANCA_BUS) += blanca/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ obj-y += video/ diff -urN linux-2.6.26.2-orig/drivers/blanca/Makefile linux-2.6.26.2-blanca/drivers/blanca/Makefile --- linux-2.6.26.2-orig/drivers/blanca/Makefile 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.26.2-blanca/drivers/blanca/Makefile 2008-08-25 20:42:00.000000000 +0900 @@ -0,0 +1,2 @@ +obj-$(CONFIG_BLANCA_BUS) += blanca_bios.o + diff -urN linux-2.6.26.2-orig/drivers/blanca/blanca_bios.c linux-2.6.26.2-blanca/drivers/blanca/blanca_bios.c --- linux-2.6.26.2-orig/drivers/blanca/blanca_bios.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.26.2-blanca/drivers/blanca/blanca_bios.c 2009-07-22 21:31:13.000000000 +0900 @@ -0,0 +1,201 @@ +#include +#include +#include +#include +#include +#include + +#define BLANCAAVP "BLANCA AVP " // 12 chars +#define BLANCAIOP "BLANCA IOP " // 12 chars + +#define SH_IRQ_PRIORITY 0x0E + +static unsigned long local_address_offset(unsigned long iobase){ +#ifdef __sh__ + iobase |= 0xA0000000; +#endif + return iobase; +} + +static unsigned long avp_base = 0; +static int avp_irq = 0; + +struct blanca_resource_table{ + union { + char name[4]; + unsigned long i; + } id; + unsigned long iobase; + unsigned long size; + unsigned long reserve; +}; + + + +int blanca_bios_search_resource_table(struct blanca_resource_table *res, unsigned char *name, struct blanca_bus *bbus){ + int i; + for(i=0; i<16; i++){ + if( res[i].id.i != 0){ + if(strncmp(res[i].id.name, name, 4) == 0){ + // match + bbus->iobase = res[i].iobase; + bbus->size = res[i].size; + bbus->cs = i; + printk("match %lx,%lx,%d\n", + bbus->iobase, + bbus->size, + bbus->cs); + return i; + } + } + } + return -ENODEV; /* no such device */ +} + + + +int get_blanca_bus(char *name, struct blanca_bus *bbus){ + struct blanca_resource_table *res; + int cs; + + unsigned long base = avp_base; + if(base==0){ + printk("%s() avp coundn't find\n",__FUNCTION__); + return -EINVAL; + } + + bbus->irq = avp_irq; + + /* 名前で検索 */ + res = (struct blanca_resource_table *)base; + cs = blanca_bios_search_resource_table(&res[2], name, bbus); + if(cs>=0){ + /* 発見 */ + bbus->iobase = local_address_offset(bbus->iobase); + bbus->cs = cs; + bbus->irq = avp_irq; + return cs; + } + + /* 発見できなかったら今度は LBUS を探す */ + cs = blanca_bios_search_resource_table(&res[2], "LBUS", bbus); + if(cs<0){ + /* LBUS も無かった */ + printk("%s(): error. cannot find %s \n",__FUNCTION__,"LBUS"); + return -ENODEV; /* no such device */ + } + + /* LBUS があったなら */ + base = local_address_offset(bbus->iobase); + + /* リソーステーブルの先頭が BLANCAIOP であるか確認 */ + if(strncmp( (char*)base, BLANCAIOP, 12) != 0){ + printk("%s(): error. cannot find %s \n",__FUNCTION__,BLANCAIOP); + return -ENODEV; /* no such device */ + } + + /* 名前で検索 */ + res = (struct blanca_resource_table *)base; + cs = blanca_bios_search_resource_table(&res[2], name, bbus); + if(cs>=0){ + /* 発見 */ + bbus->iobase = local_address_offset(bbus->iobase); + cs += 16; + bbus->cs = cs; + bbus->irq = avp_irq; + return cs; + } + + printk("%s(): error. cannot find %s \n",__FUNCTION__,name); + return -ENODEV; /* no such device */ +} + +int blanca_irq_enable(int cs) +{ + if(avp_base==0){ + printk("%s() avp coundn't find\n",__FUNCTION__); + return -EINVAL; + } + + *(volatile unsigned long*)(avp_base+0x14) |= (1 << cs); +#ifdef __sh__ + *(volatile unsigned long*)(avp_base+0x18) = SH_IRQ_PRIORITY; +#endif + return 0; +} + +int blanca_irq_disable(int cs) +{ + if(avp_base==0){ + printk("%s() avp coundn't find\n",__FUNCTION__); + return -EINVAL; + } + + *(volatile unsigned long*)(avp_base+0x14) &= ~(1 << cs); + return 0; +} + + +int blanca_bios_probe(struct platform_device *pdev) +{ + unsigned long base; + int irq; + struct resource *regs; + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = regs->start; + + regs = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + irq = regs->start; + + base = local_address_offset(base); + + printk("%s(), base=0x%08lx, irq=%d\n",__FUNCTION__,base,irq); + + /* 最初にリソーステーブルの先頭が BLANCAAVP であるか確認 */ + if(strncmp( (char*)base, BLANCAAVP, 12) != 0){ + printk("%s(): error. cannot find %s \n",__FUNCTION__,BLANCAAVP); + return -EINVAL; + } + + avp_base = base; + avp_irq = irq; + + return 0; +} + +static int blanca_bios_remove(struct platform_device *_dev) +{ + return 0; +} + + +static struct platform_driver blanca_bios_driver = { + .driver = { + .name = "blanca_bios", + .owner = THIS_MODULE, + }, + .probe = blanca_bios_probe, + .remove = blanca_bios_remove, +}; + + +static int __init blanca_bios_init(void) +{ + return platform_driver_register(&blanca_bios_driver); +} + +static void __exit blanca_bios_exit(void) +{ + platform_driver_unregister(&blanca_bios_driver); +} + + + + +module_init(blanca_bios_init); +module_exit(blanca_bios_exit); + +MODULE_DESCRIPTION("CQ BLANCA bus driver"); +MODULE_AUTHOR("yutaro ebihara "); +MODULE_LICENSE("GPL v2"); diff -urN linux-2.6.26.2-orig/drivers/mtd/maps/Kconfig linux-2.6.26.2-blanca/drivers/mtd/maps/Kconfig --- linux-2.6.26.2-orig/drivers/mtd/maps/Kconfig 2008-08-07 01:19:01.000000000 +0900 +++ linux-2.6.26.2-blanca/drivers/mtd/maps/Kconfig 2008-08-25 20:42:00.000000000 +0900 @@ -570,6 +570,14 @@ help This enables access to the flash chip on the Sharp SL Series of PDAs. +config MTD_CQBLANCASH4A + tristate "FLASH MAP on CQPub BLANCA SH4A" + select MTD_PARTITIONS + depends on SH_CQBLANCA + help + This enables access to the flash chip on the Sharp SL Series of PDAs. + + config MTD_INTEL_VR_NOR tristate "NOR flash on Intel Vermilion Range Expansion Bus CS0" depends on PCI diff -urN linux-2.6.26.2-orig/drivers/mtd/maps/Makefile linux-2.6.26.2-blanca/drivers/mtd/maps/Makefile --- linux-2.6.26.2-orig/drivers/mtd/maps/Makefile 2008-08-07 01:19:01.000000000 +0900 +++ linux-2.6.26.2-blanca/drivers/mtd/maps/Makefile 2008-08-25 20:42:00.000000000 +0900 @@ -63,6 +63,7 @@ obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o obj-$(CONFIG_MTD_DMV182) += dmv182.o obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o +obj-$(CONFIG_MTD_CQBLANCASH4A) += cqblancash4a.o obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o diff -urN linux-2.6.26.2-orig/drivers/mtd/maps/cqblancash4a.c linux-2.6.26.2-blanca/drivers/mtd/maps/cqblancash4a.c --- linux-2.6.26.2-orig/drivers/mtd/maps/cqblancash4a.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.26.2-blanca/drivers/mtd/maps/cqblancash4a.c 2008-08-25 20:42:00.000000000 +0900 @@ -0,0 +1,77 @@ +/* + * Flash on CQPublic Blanca SH4A + * + * (C) 2008 Yutaro Ebihara ebihara@si-linux.co.jp + * + * GPL'd + */ + +#include +#include +#include +#include +#include +#include +#include + +static struct mtd_info *flash_mtd; + +#define FLASH_SIZE 16*1024*1024 + +struct map_info cqblancash4a_flash_map = { + .name = "flash", + .size = FLASH_SIZE, + .bankwidth = 2, + .phys = 0 +}; + +static struct mtd_partition cqblancash4a_partitions[] = { + { + .name = "ipl", + .offset = 0, + .size = 0x10000, + }, + { + .name = "kernel", + .offset = MTDPART_OFS_NXTBLK, + .size = 0x170000, + }, + { + .name = "rootfs", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + } +}; + +static int __init init_cqblancash4a_maps(void) +{ + cqblancash4a_flash_map.virt = + (void __iomem *)P2SEGADDR(cqblancash4a_flash_map.phys); + simple_map_init(&cqblancash4a_flash_map); + + flash_mtd = do_map_probe("cfi_probe", &cqblancash4a_flash_map); + if (!flash_mtd) { + printk(KERN_NOTICE "%s() flash memory cannot found\n",__FUNCTION__); + return -ENXIO; + } + flash_mtd->owner = THIS_MODULE; + add_mtd_partitions(flash_mtd, + cqblancash4a_partitions, ARRAY_SIZE(cqblancash4a_partitions)); + + return 0; +} + +static void __exit cleanup_cqblancash4a_maps(void) +{ + if (flash_mtd) { + del_mtd_partitions(flash_mtd); + map_destroy(flash_mtd); + } +} + +module_init(init_cqblancash4a_maps); +module_exit(cleanup_cqblancash4a_maps); + +MODULE_AUTHOR("ebihara@si-linux.co.jp"); +MODULE_DESCRIPTION("CQPublic BLANCA SH7780 board flash mtd map driver"); +MODULE_LICENSE("GPL"); diff -urN linux-2.6.26.2-orig/drivers/net/Kconfig linux-2.6.26.2-blanca/drivers/net/Kconfig --- linux-2.6.26.2-orig/drivers/net/Kconfig 2008-08-07 01:19:01.000000000 +0900 +++ linux-2.6.26.2-blanca/drivers/net/Kconfig 2008-08-25 20:42:00.000000000 +0900 @@ -872,6 +872,21 @@ help Use Reduced PHY MII Interface +config IFNIC_PCI + tristate "CQ pub Interface BLANCA PCI-NIC support" + depends on PCI + select MII + depends on NET_ETHERNET + help + This is a driver for CQ pub Interface 10/100 Ethernet controller. + +config IFNIC_BLANCA + tristate "CQ pub Interface LANC (BLANCA BUS)support" + select MII + depends on NET_ETHERNET + help + This is a driver for CQ pub Interface 10/100 Ethernet controller. + config SMC9194 tristate "SMC 9194 support" depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN) diff -urN linux-2.6.26.2-orig/drivers/net/Makefile linux-2.6.26.2-blanca/drivers/net/Makefile --- linux-2.6.26.2-orig/drivers/net/Makefile 2008-08-07 01:19:01.000000000 +0900 +++ linux-2.6.26.2-blanca/drivers/net/Makefile 2008-08-25 20:42:00.000000000 +0900 @@ -222,6 +222,8 @@ pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o obj-$(CONFIG_MLX4_CORE) += mlx4/ obj-$(CONFIG_ENC28J60) += enc28j60.o +obj-$(CONFIG_IFNIC_PCI) += ifnic.o ifnic_pci.o +obj-$(CONFIG_IFNIC_BLANCA) += ifnic.o ifnic_blanca.o obj-$(CONFIG_MACB) += macb.o diff -urN linux-2.6.26.2-orig/drivers/net/ifnic.c linux-2.6.26.2-blanca/drivers/net/ifnic.c --- linux-2.6.26.2-orig/drivers/net/ifnic.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.26.2-blanca/drivers/net/ifnic.c 2008-08-25 20:42:00.000000000 +0900 @@ -0,0 +1,493 @@ +/* + * ifnic.c network driver for CQ Publishing's Blanca base board. + * this device is soft core, build on FPGA. + * + * (C) Copyright 2007 Media Lab. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation + */ +/*#define DEBUG 1*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ifnic.h" + + +static inline void if_writel(void __iomem *addr, u32 data) +{ + *(volatile u32 *)addr = cpu_to_le32(data); +} + +static inline u32 if_readl(void __iomem *addr) +{ + return le32_to_cpu(*(volatile u32 *)addr); +} + +static void wait_bitclear(void __iomem *base, u_long bit) +{ + while( if_readl(base) & bit ) + ; +} + +#define phy_wait(base) wait_bitclear((base+IFNIC_MIIPHY), MIIPHY_BUSY) +#define rom_wait(base) wait_bitclear((base+IFNIC_ROM), ROM_BUSY) + +int ifnic_phy_read(struct net_device *dev, int phyaddr, int reg ) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + int val; + + spin_lock(&ifnic->lock_mii); + phy_wait(ifnic->iobase); + + /* Issue the MII 'read' command. */ + if_writel(ifnic->iobase + IFNIC_MIIPHY, + MIIPHY_BUSY|MIIPHY_READ|MIIPHY_ADDR(phyaddr)|MIIPHY_REG(reg)); + + /* Wait for the command to complete. */ + phy_wait(ifnic->iobase); + val = MIIPHY_READDATA(if_readl(ifnic->iobase+IFNIC_MIIPHYDATA)); + spin_unlock(&ifnic->lock_mii); + return val; +} + +void ifnic_phy_write(struct net_device *dev, int phyaddr, int reg, int value ) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + + spin_lock(&ifnic->lock_mii); + phy_wait(ifnic->iobase); + + /* set write value */ + if_writel(ifnic->iobase + IFNIC_MIIPHYDATA, value); + + /* Issue the MII 'write' command. */ + if_writel(ifnic->iobase + IFNIC_MIIPHY, MIIPHY_BUSY|MIIPHY_ADDR(phyaddr)|MIIPHY_REG(reg)); + + /* Wait for the command to complete. */ + phy_wait(ifnic->iobase); + spin_unlock(&ifnic->lock_mii); +} + +static int rom_read(struct ifnic_private *ifnic, u_short offset) +{ + int val; + + spin_lock(&ifnic->lock_rom); + + rom_wait(ifnic->iobase); + + /* Issue the ROM 'read' command. */ + if_writel(ifnic->iobase + IFNIC_ROM, ROM_BUSY|ROM_READ|ROM_ADDR(offset)); + + /* Wait for the command to complete. */ + rom_wait(ifnic->iobase); + val = ROM_READDATA( if_readl( ifnic->iobase + IFNIC_ROM ) ); + spin_unlock(&ifnic->lock_rom); + return val; +} + + +static void ifnic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + DPRINTK( "%s\n", __FUNCTION__ ); + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); +#ifdef CONFIG_IFNIC_PCI + strcpy(info->bus_info, pci_name(ifnic->pdev)); +#else + strcpy(info->bus_info, "blanca"); +#endif + info->regdump_len = 0; +} + +static int ifnic_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + mii_ethtool_gset(&ifnic->mii, cmd); + DPRINTK( "%s\n", __FUNCTION__ ); + return 0; +} + +static int ifnic_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + int rc; + DPRINTK( "%s\n", __FUNCTION__ ); + rc = mii_ethtool_sset(&ifnic->mii, cmd); + return rc; +} + +static int ifnic_nway_reset(struct net_device *dev) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + DPRINTK( "%s\n", __FUNCTION__ ); + return mii_nway_restart(&ifnic->mii); +} + +static u32 ifnic_get_link(struct net_device *dev) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + u32 linkstat = if_readl(ifnic->iobase + IFNIC_MIISTATUS); + DPRINTK( "%s\n", __FUNCTION__ ); +/* return mii_link_ok(&ifnic->mii); */ + if ( linkstat & LINK_STATUS ) + return 1; + return 0; +} + +int ifnic_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + DPRINTK( "%s\n", __FUNCTION__ ); + return generic_mii_ioctl(&ifnic->mii, if_mii(ifr), cmd, NULL); +} + +struct ethtool_ops ifnic_ethtool = { + .get_drvinfo = ifnic_get_drvinfo, + .get_settings = ifnic_get_settings, + .set_settings = ifnic_set_settings, + .nway_reset = ifnic_nway_reset, + .get_link = ifnic_get_link, +}; + +static void ifnic_recv (struct net_device *dev) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + struct sk_buff *skb; + unsigned int rxstatus = if_readl(ifnic->iobase + IFNIC_RXBUF_STATUS); + int len; + + len = rxstatus & RXBUF_SIZE_MASK; + skb = dev_alloc_skb(len+2); + if (skb == NULL) { + ifnic->stats.rx_dropped++; + return; + } + skb->dev = dev; + + /* Align IP header to 32bits */ + skb_reserve(skb,2); + memcpy( skb->data, ifnic->iobase + IFNIC_RXBUF, len ); + skb_put(skb, len); + + ifnic->stats.rx_packets++; + ifnic->stats.rx_bytes += len; + dev->last_rx = jiffies; + + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); +} + +static void ifnic_print_link(struct net_device *dev, unsigned int linkstat ) +{ + if ( linkstat & LINK_STATUS ) { + printk(KERN_INFO "%s:Link %dMbps %sDuplex\n", + dev->name, + (linkstat&SPEED_STATUS)?100:10, + (linkstat&DUPLEX_STATUS)?"Full":"Harf"); + } else { + printk(KERN_NOTICE "%s:Link is down\n", dev->name ); + } +} + +static irqreturn_t ifnic_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct ifnic_private *ifnic = netdev_priv(dev); + unsigned int intstat, txstat, linkstat; + + intstat = if_readl(ifnic->iobase + IFNIC_INTSTAT); + if ( !intstat ) + return IRQ_NONE; + + /* Ack interrupt(s) */ + if_writel(ifnic->iobase + IFNIC_INTSTAT, intstat); + + /* TX complete */ + if ((intstat & (INT_TXERR|INT_TXDONE))) { + txstat = if_readl(ifnic->iobase + IFNIC_TXBUF_STATUS); + if ( intstat & INT_TXDONE ) { + ifnic->stats.tx_packets ++; + ifnic->stats.tx_bytes += txstat & TXBUF_SIZE_MASK; + } + if ( intstat & INT_TXERR ) { + ifnic->stats.tx_errors ++; + } + DPRINTK( "%s:netif_wake_queue\n", __FUNCTION__ ); + netif_wake_queue(dev); + } + + /* Rx complete */ + if (intstat & (INT_RXERR|INT_RXDONE) ) { + if ( intstat & INT_RXERR ) { + ifnic->stats.rx_errors ++; + } + if ( intstat & INT_RXDONE ) { + ifnic_recv(dev); + } + if_writel(ifnic->iobase + IFNIC_RXBUF_STATUS, RXBUF_FREE ); + } + + /* Link status change */ + if (intstat & INT_LINKSTATUS ) { + unsigned long flags; + local_irq_save(flags); + linkstat = if_readl(ifnic->iobase + IFNIC_MIISTATUS); + if_writel(ifnic->iobase + IFNIC_MIISTATUS, linkstat); + if_writel(ifnic->iobase + IFNIC_INTSTAT, INT_LINKSTATUS); + local_irq_restore(flags); + DPRINTK( "linkstatus:%X\n", linkstat ); + /* fixme: check (linkstat & LINK_CHANGE) is better, + * but it dose not work. + */ + ifnic_print_link(dev, linkstat); + if ( linkstat & LINK_STATUS ) { + netif_carrier_on(dev); + } else { + netif_carrier_off(dev); + } + } + return IRQ_HANDLED; +} + + +/* + * Open + */ +int ifnic_open(struct net_device *dev) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + int retval, i; + u32 linkstat; + + retval = request_irq(dev->irq, ifnic_interrupt, IRQF_SHARED, dev->name, dev); + if (retval) { + return retval; + } + + /* set Mac addr */ + for (i = 0; i < 6; i++) { + if_writel( ifnic->iobase + IFNIC_MAC_ADDR, + MAC_WRITE|MAC_ADDR(i)|MAC_DATA(dev->dev_addr[i])); + } + + linkstat = if_readl(ifnic->iobase + IFNIC_MIISTATUS); + if_writel(ifnic->iobase + IFNIC_MIISTATUS, linkstat); + if_writel(ifnic->iobase + IFNIC_INTSTAT, + (INT_LINKSTATUS|INT_TXERR|INT_TXDONE|INT_RXERR|INT_RXDONE)); + if_writel(ifnic->iobase + IFNIC_INTMASK, + (INT_LINKSTATUS|INT_TXERR|INT_TXDONE|INT_RXERR|INT_RXDONE)); + + ifnic_print_link(dev, linkstat ); + if ( linkstat & LINK_STATUS ) { + netif_carrier_on(dev); + } else { + netif_carrier_off(dev); + } + + if_writel(ifnic->iobase + IFNIC_TXCFG, 0); + if ( dev->flags & IFF_PROMISC ) { + if_writel(ifnic->iobase + IFNIC_RXCFG, PROMISC ); + } else + if_writel(ifnic->iobase + IFNIC_RXCFG, 0); + + DPRINTK( "netif_start_queue\n" ); + netif_start_queue(dev); + + return 0; +} + +int ifnic_stop(struct net_device *dev) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + + netif_carrier_off(dev); + DPRINTK( "%s:netif_stop_queue\n", __FUNCTION__ ); + netif_stop_queue (dev); + + if_writel(ifnic->iobase + IFNIC_INTMASK, 0); + if_writel(ifnic->iobase + IFNIC_RXCFG, RXRST); + if_writel(ifnic->iobase + IFNIC_TXCFG, TXRST ); + + free_irq (dev->irq, dev); + + return 0; +} + +int ifnic_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + + DPRINTK( "ifnic_start_xmit %d\n", skb->len ); + + if (skb->len < ETH_ZLEN) { + skb_padto(skb, ETH_ZLEN); + skb->len = ETH_ZLEN; + } + DPRINTK( "%s:netif_stop_queue\n", __FUNCTION__ ); + netif_stop_queue (dev); + + /* Write to send buffer */ + memcpy(ifnic->iobase + IFNIC_TXBUF, skb->data, skb->len ); + + dev->trans_start = jiffies; + /* Tx enable */ + if_writel(ifnic->iobase + IFNIC_TXBUF_STATUS, (TXBUF_BUSY | (skb->len & TXBUF_SIZE_MASK))); + + dev_kfree_skb(skb); + + return NETDEV_TX_OK; +} + +struct net_device_stats *ifnic_get_stats(struct net_device *dev) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + DPRINTK( "%s\n", __FUNCTION__ ); + ifnic->stats.rx_crc_errors += if_readl(ifnic->iobase + IFNIC_STAT_CRCERR); + if_writel(ifnic->iobase + IFNIC_STAT_CRCERR, 0); + + ifnic->stats.rx_frame_errors += if_readl(ifnic->iobase + IFNIC_STAT_FRAMEERR); + if_writel(ifnic->iobase + IFNIC_STAT_FRAMEERR, 0); + + ifnic->stats.rx_missed_errors += if_readl(ifnic->iobase + IFNIC_STAT_LOST); + if_writel(ifnic->iobase + IFNIC_STAT_LOST, 0); + + ifnic->stats.collisions += if_readl(ifnic->iobase + IFNIC_STAT_COLLISION); + if_writel(ifnic->iobase + IFNIC_STAT_COLLISION, 0); + + return &ifnic->stats; +} + +void ifnic_tx_timeout(struct net_device *dev) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + + /* Tx RESET */ + if_writel(ifnic->iobase + IFNIC_TXCFG, TXRST ); + if_writel(ifnic->iobase + IFNIC_TXCFG, 0 ); + + dev->trans_start = jiffies; + DPRINTK( "%s:netif_wake_queue\n", __FUNCTION__ ); + netif_wake_queue(dev); +} + +void ifnic_cleanup_dev(struct net_device *dev) +{ +#ifdef CONFIG_IFNIC_PCI + struct ifnic_private *ifnic = netdev_priv(dev); + struct pci_dev *pdev = ifnic->pdev; + if ( ifnic->iobase ) + pci_iounmap (pdev, ifnic->iobase ); + pci_release_regions (pdev); + pci_set_drvdata (pdev, NULL); +#endif + free_netdev(dev); +} + +int ifnic_set_mac_address(struct net_device *dev, void *p) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + struct sockaddr *addr = p; + int i; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + /* set Mac addr */ + for (i = 0; i < 6; i++) { + if_writel( ifnic->iobase + IFNIC_MAC_ADDR, + MAC_WRITE|MAC_ADDR(i)|MAC_DATA(dev->dev_addr[i])); + } + return 0; +} + +#if 0 +static void ifnic_set_multicast_list(struct net_device *dev) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + if ( dev->flags & (IFF_PROMISC | IFF_ALLMULTI) || + dev->mc_count > 0 ) + if_writel(ifnic->iobase + IFNIC_RXCFG, /*PROMISC*/0); + else + if_writel(ifnic->iobase + IFNIC_RXCFG, 0); +} +#endif + +int ifnic_change_mtu(struct net_device *dev, int new_mtu) +{ + if(new_mtu < ETH_ZLEN || new_mtu > ETH_DATA_LEN ) + return -EINVAL; + dev->mtu = new_mtu; + return 0; +} + +int ifnic_hw_initialize(struct net_device *dev) +{ + struct ifnic_private *ifnic = netdev_priv(dev); + int i; + u32 dev_id, rev; + + /* sanity check */ + dev_id = if_readl(ifnic->iobase + IFNIC_DEVID); + if (dev_id != IFNIC_DEVID_VALUE) { + dev_err(dev, "%s: Error, ID not match.\n", dev->name ); + return -1; + } + + rev = if_readl(ifnic->iobase + IFNIC_REV); + for (i = 0; i < 6; i++) { + dev->dev_addr[i] = rom_read( ifnic, IFNIC_MAC_ROMADDR + i ); + } + +#ifdef CONFIG_IFNIC_PCI + { + struct pci_dev *pdev = ifnic->pdev; + printk( KERN_INFO DRV_NAME " rev %02X.%02X at %s, irq %d\n", + rev>>16, rev&0xFF, pci_name(ifnic->pdev), + dev->irq ); + } +#else + printk( KERN_INFO DRV_NAME " rev %02X.%02X at %s, irq %d\n", + rev>>16, rev&0xFF, "blanca", + dev->irq ); +#endif + if_writel( ifnic->iobase + IFNIC_INTMASK, 0); + if_writel( ifnic->iobase + IFNIC_INTSTAT, 0xFFFFFFFF); + if_writel( ifnic->iobase + IFNIC_MIISTATUS, 0xFFFFFFFF); + if_writel( ifnic->iobase + IFNIC_RXCFG, RXRST); + if_writel( ifnic->iobase + IFNIC_TXCFG, TXRST); + if_writel( ifnic->iobase + IFNIC_RXBUF_STATUS, RXBUF_FREE); + if_writel( ifnic->iobase + IFNIC_STAT_LOST, 0); + if_writel( ifnic->iobase + IFNIC_STAT_PHYERR, 0); + if_writel( ifnic->iobase + IFNIC_STAT_FRAMEERR, 0); + if_writel( ifnic->iobase + IFNIC_STAT_CRCERR, 0); + if_writel( ifnic->iobase + IFNIC_STAT_COLLISION, 0); + +#if 1 + /* reset PHY */ + ifnic_phy_write(dev, PHY_ADDR, MII_BMCR, BMCR_RESET|BMCR_ANENABLE|BMCR_ANRESTART ); +#endif + return 0; +} + diff -urN linux-2.6.26.2-orig/drivers/net/ifnic.h linux-2.6.26.2-blanca/drivers/net/ifnic.h --- linux-2.6.26.2-orig/drivers/net/ifnic.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.26.2-blanca/drivers/net/ifnic.h 2008-08-25 20:42:00.000000000 +0900 @@ -0,0 +1,139 @@ +/* + * (C) Copyright 2007 Media Lab. + * + * for CQ Pub. Interface BLANCA PCI LAN Controller + */ +#ifndef IFNIC_H +#define IFNIC_H + + +#define DRV_NAME "ifnic" +#define DRV_VERSION "0.91" +#define TX_TIMEOUT (1*HZ) +#define PHY_ADDR 6 + + +#define IFNIC_DEVID (0x00) +#define IFNIC_DEVID_VALUE (0x434e414c) +#define IFNIC_REV (0x04) + +#define IFNIC_INTSTAT (0x10) +#define IFNIC_INTMASK (0x14) +#define INT_LINKSTATUS (1<<31) +#define INT_TXERR (1<<17) +#define INT_TXDONE (1<<16) +#define INT_RXERR (1<<1) +#define INT_RXDONE (1<<0) + +#define IFNIC_MIISTATUS (0x20) +#define DUPLEX_CHANGE (1<<18) +#define SPEED_CHANGE (1<<17) +#define LINK_CHANGE (1<<16) +#define DUPLEX_STATUS (1<<2) +#define SPEED_STATUS (1<<1) +#define LINK_STATUS (1<<0) + + +#define IFNIC_MAC_ADDR (0x28) +#define MAC_WRITE (1<<31) +#define MAC_ADDR(a) ((a)<<16) +#define MAC_DATA(d) ((d)&0xFF) + +#define IFNIC_MAC_ROMADDR (0x10) +#define IFNIC_ROM (0x2c) +#define ROM_BUSY (1<<31) +#define ROM_READ (1<<30) +#define ROM_ADDR(a) (((a)&0xFF)<<16) +#define ROM_WRITEDATA(d) (((d)&0xFF)<<8) +#define ROM_READDATA(d) ((d)&0xFF) + + +#define IFNIC_RXCFG (0x40) +#define RXRST (1<<31) +#define NO_BROADCAST (1<<2) +#define PROMISC (1<<1) +#define RXERROR (1<<0) +#define IFNIC_RXBUF_STATUS (0x44) +#define RXBUF_VALID (1<<31) +#define RXBUF_FREE (1<<31) +#define RXBUF_OF (1<<30) +#define RXBUF_PHYERR (1<<28) +#define RXBUF_FERR2 (1<<27) +#define RXBUF_FERR1 (1<<26) +#define RXBUF_FERR0 (1<<25) +#define RXBUF_CRCERR (1<<24) +#define RXBUF_SIZE_MASK ((1<<11)-1) + +#define IFNIC_STAT_LOST (0x50) +#define IFNIC_STAT_PHYERR (0x54) +#define IFNIC_STAT_FRAMEERR (0x58) +#define IFNIC_STAT_CRCERR (0x5C) + +#define IFNIC_TXCFG (0x60) +#define TXRST (1<<31) +#define IFNIC_TXBUF_STATUS (0x64) +#define TXBUF_BUSY (1<<31) +#define TXBUF_ERR (1<<30) +#define TXBUF_SIZE_MASK ((1<<11)-1) + +#define IFNIC_COLLISION (0x68) +#define IFNIC_STAT_COLLISION (0x70) + +#define IFNIC_MIIPHY (0x80) +#define MIIPHY_BUSY (1<<31) +#define MIIPHY_READ (1<<30) +#define MIIPHY_ADDR_MASK (0x1F) +#define MIIPHY_ADDR(a) (((a)&MIIPHY_ADDR_MASK)<<8) +#define MIIPHY_REG_MASK (0x0F) +#define MIIPHY_REG(d) ((d)&MIIPHY_REG_MASK) + +#define IFNIC_MIIPHYDATA (0x84) +#define MIIPHY_READDATA(a) (((a)>>16)&0xFFFF) +#define MIIPHY_WRITEDATA(a) ((a)&0xFFFF) + +#define IFNIC_TXBUF (0x4000) +#define IFNIC_RXBUF (0x8000) + + +struct ifnic_private { + void __iomem *iobase; +#ifdef CONFIG_IFNIC_PCI + struct pci_dev *pdev; +#endif + struct net_device_stats stats; + struct mii_if_info mii; + spinlock_t lock_mii; /* Serialise access to mii */ + spinlock_t lock_rom; /* Serialise access to rom */ +}; + + + +#ifdef DEBUG +# define DPRINTK(fmt, args...) printk(/*KERN_DEBUG*/ "c%d q%d " fmt,\ + netif_carrier_ok(dev), \ + netif_queue_stopped(dev), ## args) +#else +# define DPRINTK(fmt, args...) +#endif + + +extern struct ethtool_ops ifnic_ethtool; + +int ifnic_phy_read(struct net_device *dev, int phyaddr, int reg ); +void ifnic_phy_write(struct net_device *dev, int phyaddr, int reg, int value ); + +int ifnic_open(struct net_device *dev); +int ifnic_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); + +int ifnic_stop(struct net_device *dev); +int ifnic_start_xmit(struct sk_buff *skb, struct net_device *dev); +struct net_device_stats *ifnic_get_stats(struct net_device *dev); +void ifnic_tx_timeout(struct net_device *dev); +int ifnic_set_mac_address(struct net_device *dev, void *p); +int ifnic_change_mtu(struct net_device *dev, int new_mtu); + + +int ifnic_hw_initialize(struct net_device *dev); +void ifnic_cleanup_dev(struct net_device *dev); + +#endif /* IFNIC_H */ diff -urN linux-2.6.26.2-orig/drivers/net/ifnic_blanca.c linux-2.6.26.2-blanca/drivers/net/ifnic_blanca.c --- linux-2.6.26.2-orig/drivers/net/ifnic_blanca.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.26.2-blanca/drivers/net/ifnic_blanca.c 2009-07-22 20:32:27.000000000 +0900 @@ -0,0 +1,141 @@ +/* + * ifnic_blanca.c network driver for CQ Publishing's Blanca base board. + * this device is soft core, build on FPGA. + * + * (C) Copyright 2007 Media Lab. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation + */ +/*#define DEBUG 1*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ifnic.h" +#include + +char ifnic_version[] __devinitdata = +KERN_INFO DRV_NAME ".c:v" DRV_VERSION "Aug 25. 2008 \n"; + + +static struct net_device *ifnic_dev = NULL; + +/* + * Probe for the device + */ +static int __init ifnic_blanca_probe(struct blanca_bus *bbus) +{ + int rc; + struct net_device *dev; + struct ifnic_private *ifnic; + + dev = alloc_etherdev(sizeof(struct ifnic_private)); + if (!dev) { + rc = -ENOMEM; + printk("alloc_etherdev failed\n"); + return -ENOMEM; + } + // SET_MODULE_OWNER(dev); // out 2008-08-25 EBIHARA + ifnic = netdev_priv(dev); + spin_lock_init(&ifnic->lock_mii); + spin_lock_init(&ifnic->lock_rom); + + + ifnic->iobase = bbus->iobase; + if ( !ifnic->iobase ) { + printk("cannot find 'LANC', aborting\n"); + rc = -EIO; + goto err_out; + } + + dev->irq = bbus->irq; + /* Read Device-ID register */ + if ( ifnic_hw_initialize(dev) ) { + rc = -ENODEV; + goto err_out; + } + + dev->open = ifnic_open; + dev->stop = ifnic_stop; + dev->hard_start_xmit = ifnic_start_xmit; + dev->get_stats = ifnic_get_stats; + dev->watchdog_timeo = TX_TIMEOUT; + dev->tx_timeout = ifnic_tx_timeout; +/* dev->set_multicast_list = ifnic_set_multicast_list;*/ + dev->set_mac_address = ifnic_set_mac_address; + dev->change_mtu = ifnic_change_mtu; + dev->do_ioctl = ifnic_do_ioctl; + dev->ethtool_ops = &ifnic_ethtool; + + ifnic->mii.dev = dev; + ifnic->mii.mdio_read = ifnic_phy_read; + ifnic->mii.mdio_write = ifnic_phy_write; + ifnic->mii.phy_id_mask = MIIPHY_ADDR_MASK; + ifnic->mii.reg_num_mask = MIIPHY_REG_MASK; + ifnic->mii.phy_id = PHY_ADDR; + + rc = register_netdev(dev); + if (rc) + goto err_out; + + ifnic_dev = dev; + return 0; + +err_out: + ifnic_cleanup_dev(dev); + return rc; +} + +int __init ifnic_blanca_init(void) +{ + int rc; + struct blanca_bus bbus; + + printk(ifnic_version); + + rc = get_blanca_bus("LANC", &bbus); + if(rc <= 0){ + printk("%s() cannot find LANC\n",__FUNCTION__); + return -EIO; + } + printk("blanca found at 0x%x (size=0x%x) irq=%d, cs=%d\n", + bbus.iobase, + bbus.size, + bbus.irq, + bbus.cs); + + rc = ifnic_blanca_probe(&bbus); + blanca_irq_enable(bbus.cs); + return rc; +} + +static void __exit ifnic_blanca_exit(void) +{ + if(ifnic_dev){ + unregister_netdev(ifnic_dev); + ifnic_cleanup_dev(ifnic_dev); + } +} + +module_init(ifnic_blanca_init); +module_exit(ifnic_blanca_exit); + +MODULE_DESCRIPTION("CQ Pub Interface BLANCA LAN Controller Driver"); +MODULE_AUTHOR("SiliconLinux. Inc."); +MODULE_LICENSE("GPL"); + diff -urN linux-2.6.26.2-orig/drivers/net/ifnic_pci.c linux-2.6.26.2-blanca/drivers/net/ifnic_pci.c --- linux-2.6.26.2-orig/drivers/net/ifnic_pci.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.26.2-blanca/drivers/net/ifnic_pci.c 2008-08-25 20:42:00.000000000 +0900 @@ -0,0 +1,162 @@ +/* + * ifnic_pci.c network driver for CQ Publishing's Blanca base board. + * this device is soft core, build on FPGA. + * + * (C) Copyright 2007 Media Lab. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation + */ +/*#define DEBUG 1*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ifnic.h" + + +char ifnic_version[] __devinitdata = +KERN_INFO DRV_NAME ".c:v" DRV_VERSION "Sept 6, 2007 Written by Media Lab. Inc.\n"; + +static struct pci_device_id ifnic_pci_tbl[] = { + { 0x6809, 0x8228, PCI_ANY_ID, PCI_ANY_ID, }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, ifnic_pci_tbl); + + +/* + * Probe for the device + */ +static int __init ifnic_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int rc; + struct net_device *dev; + struct ifnic_private *ifnic; + + dev = alloc_etherdev(sizeof(struct ifnic_private)); + if (!dev) { + rc = -ENOMEM; + dev_err(&pdev->dev, "alloc_etherdev failed\n"); + return -ENOMEM; + } + // SET_MODULE_OWNER(dev); // out 2008-08-25 EBIHARA + SET_NETDEV_DEV(dev, &pdev->dev); + ifnic = netdev_priv(dev); + ifnic->pdev = pdev; + spin_lock_init(&ifnic->lock_mii); + spin_lock_init(&ifnic->lock_rom); + + rc = pci_request_regions (pdev, DRV_NAME); + if (rc) { + dev_err(&pdev->dev, "pci_request_regions fail, aborting\n"); + goto err_out; + } + + rc = pci_enable_device(pdev); + if (rc) { + dev_err(&pdev->dev, "pci_enable_device fail, aborting\n"); + goto err_out; + } + + ifnic->iobase = pci_iomap(pdev, 0, 0); + if ( !ifnic->iobase ) { + dev_err(&pdev->dev, "cannot remap PCI memory region, aborting\n"); + rc = -EIO; + goto err_out; + } + + /* Read Device-ID register */ + if ( ifnic_hw_initialize(dev) ) { + rc = -ENODEV; + goto err_out; + } + + dev->open = ifnic_open; + dev->stop = ifnic_stop; + dev->hard_start_xmit = ifnic_start_xmit; + dev->get_stats = ifnic_get_stats; + dev->watchdog_timeo = TX_TIMEOUT; + dev->tx_timeout = ifnic_tx_timeout; +/* dev->set_multicast_list = ifnic_set_multicast_list;*/ + dev->set_mac_address = ifnic_set_mac_address; + dev->change_mtu = ifnic_change_mtu; + dev->do_ioctl = ifnic_do_ioctl; + dev->ethtool_ops = &ifnic_ethtool; + dev->irq = pdev->irq; + + ifnic->mii.dev = dev; + ifnic->mii.mdio_read = ifnic_phy_read; + ifnic->mii.mdio_write = ifnic_phy_write; + ifnic->mii.phy_id_mask = MIIPHY_ADDR_MASK; + ifnic->mii.reg_num_mask = MIIPHY_REG_MASK; + ifnic->mii.phy_id = PHY_ADDR; + + rc = register_netdev(dev); + if (rc) + goto err_out; + pci_set_drvdata(pdev, dev); + + return 0; + +err_out: + ifnic_cleanup_dev(dev); + pci_disable_device(pdev); + return rc; +} + +/* + * Remove a device + */ +static void __devexit ifnic_pci_remove(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata (pdev); + + unregister_netdev(dev); + ifnic_cleanup_dev(dev); + pci_disable_device(pdev); +} + +static struct pci_driver ifnic_pci_driver = { + .name = DRV_NAME, + .id_table = ifnic_pci_tbl, + .probe = ifnic_pci_probe, + .remove = ifnic_pci_remove, +}; + +static int __init ifnic_pci_init(void) +{ + printk(ifnic_version); + return pci_register_driver(&ifnic_pci_driver); +} + +static void __exit ifnic_pci_exit(void) +{ + pci_unregister_driver(&ifnic_pci_driver); +} + +module_init(ifnic_pci_init); +module_exit(ifnic_pci_exit); + +MODULE_DESCRIPTION("CQ Pub Interface PCI LAN Controller Driver"); +MODULE_AUTHOR("Media Lab. Inc."); +MODULE_LICENSE("GPL"); + diff -urN linux-2.6.26.2-orig/drivers/serial/sh-sci.h linux-2.6.26.2-blanca/drivers/serial/sh-sci.h --- linux-2.6.26.2-orig/drivers/serial/sh-sci.h 2008-08-07 01:19:01.000000000 +0900 +++ linux-2.6.26.2-blanca/drivers/serial/sh-sci.h 2008-08-25 20:42:00.000000000 +0900 @@ -137,7 +137,7 @@ # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ # define SCSPTR1 0xffe10024 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* Overrun error bit */ -# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ +# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCIF_ONLY #elif defined(CONFIG_CPU_SUBTYPE_SH7785) # define SCSPTR0 0xffea0024 /* 16 bit SCIF */ @@ -767,7 +767,8 @@ #if defined(CONFIG_CPU_SUBTYPE_SH7763) || \ defined(CONFIG_CPU_SUBTYPE_SH7780) || \ defined(CONFIG_CPU_SUBTYPE_SH7785) -#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1) +//#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1) +#define SCBRR_VALUE(bps, clk) ((clk)/(32*bps)-1) #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) diff -urN linux-2.6.26.2-orig/include/linux/blanca_bios.h linux-2.6.26.2-blanca/include/linux/blanca_bios.h --- linux-2.6.26.2-orig/include/linux/blanca_bios.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.26.2-blanca/include/linux/blanca_bios.h 2009-07-22 20:29:27.000000000 +0900 @@ -0,0 +1,16 @@ +#ifndef BLANCA_BIOS_H +#define BLANCA_BIOS_H + +struct blanca_bus{ + unsigned long iobase; + unsigned long size; + int irq; + int cs; +}; + +int get_blanca_bus(char *name, struct blanca_bus *bbus); +int blanca_irq_enable(int cs); +int blanca_irq_disable(int cs); + + +#endif