From: Magnus D. <mag...@gm...> - 2007-07-26 14:53:53
|
sh: add on board ethernet support for r7785rp board This patch glues together various kernel components to get the on board ethernet controller working on a Highlander sh7785 board. The following kernel areas are affected: - Board specific SuperH code - The aX88796 driver - The eeprom_93cx6 driver The patch is not that polished, but my intention with posting it in this condition is to get it out there and let you guys comment. The patch works just fine for me, but if someone else happen to have a Highlander sh7785 please test and report back. Open questions / issues: - Using the eeprom_93cx6 driver seems like a good idea to me. Or? - Is the Kconfig option CONFIG_AX88796_93CX6 the right way to go? - I'd like to add Highlander sh7780 support as well, but need a working board. - readsl() and writesl() already exists, but doesn't use machvec. Hm.. Thanks. Signed-off-by: Magnus Damm <da...@ig...> --- Tested on a Highlander sh7785 board. arch/sh/boards/renesas/r7780rp/setup.c | 39 +++++++++++++++++++++++++ drivers/net/Kconfig | 9 +++++ drivers/net/ax88796.c | 49 ++++++++++++++++++++++++++++++++ include/asm-sh/io.h | 28 ++++++++++++++++++ include/linux/eeprom_93cx6.h | 3 + include/net/ax88796.h | 1 6 files changed, 127 insertions(+), 2 deletions(-) --- 0001/arch/sh/boards/renesas/r7780rp/setup.c +++ work/arch/sh/boards/renesas/r7780rp/setup.c 2007-07-26 20:04:32.000000000 +0900 @@ -20,6 +20,7 @@ #include <asm/r7780rp.h> #include <asm/clock.h> #include <asm/io.h> +#include <net/ax88796.h> static struct resource r8a66597_usb_host_resources[] = { [0] = { @@ -132,11 +133,49 @@ static struct platform_device heartbeat_ .resource = heartbeat_resources, }; +#ifdef CONFIG_SH_R7785RP +static struct ax_plat_data ax88796_platdata = { + .flags = AXFLG_HAS_93CX6, + .wordlength = 2, + .dcr_val = 0x1, + .rcr_val = 0x40, +}; + +static struct resource ax88796_resources[] = { + [0] = { + .start = 0xa4100400, + .end = 0xa4100400 + (0x20 * 0x2) - 1, + .flags = IORESOURCE_MEM, + }, + + [1] = { + .start = 10, + .end = 10, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ax88796_device = { + .name = "ax88796", + .id = 0, + + .dev = { + .platform_data = &ax88796_platdata, + }, + + .num_resources = ARRAY_SIZE(ax88796_resources), + .resource = ax88796_resources, +}; +#endif + static struct platform_device *r7780rp_devices[] __initdata = { &r8a66597_usb_host_device, &m66592_usb_peripheral_device, &cf_ide_device, &heartbeat_device, +#ifdef CONFIG_SH_R7785RP + &ax88796_device, +#endif }; static int __init r7780rp_devices_setup(void) --- 0001/drivers/net/Kconfig +++ work/drivers/net/Kconfig 2007-07-26 19:59:25.000000000 +0900 @@ -218,13 +218,20 @@ source "drivers/net/arm/Kconfig" config AX88796 tristate "ASIX AX88796 NE2000 clone support" - depends on ARM || MIPS + depends on ARM || MIPS || SUPERH select CRC32 select MII help AX88796 driver, using platform bus to provide chip detection and resources +config AX88796_93CX6 + bool "ASIX AX88796 external 93CX6 eeprom support" + depends on AX88796 + select EEPROM_93CX6 + help + Select this if your platform comes with an external 93CX6 eeprom. + config MACE tristate "MACE (Power Mac ethernet) support" depends on PPC_PMAC && PPC32 --- 0001/drivers/net/ax88796.c +++ work/drivers/net/ax88796.c 2007-07-26 20:02:25.000000000 +0900 @@ -24,6 +24,7 @@ #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/mii.h> +#include <linux/eeprom_93cx6.h> #include <net/ax88796.h> @@ -583,6 +584,37 @@ static const struct ethtool_ops ax_ethto .get_perm_addr = ethtool_op_get_perm_addr, }; +#ifdef CONFIG_AX88796_93CX6 +static void ax_eeprom_register_read(struct eeprom_93cx6 *eeprom) +{ + struct ei_device *ei_local = eeprom->data; + u8 reg = ei_inb(ei_local->mem + AX_MEMR); + + eeprom->reg_data_in = reg & AX_MEMR_EEI; + eeprom->reg_data_out = reg & AX_MEMR_EEO; /* Input pin */ + eeprom->reg_data_clock = reg & AX_MEMR_EECLK; + eeprom->reg_chip_select = reg & AX_MEMR_EECS; +} + +static void ax_eeprom_register_write(struct eeprom_93cx6 *eeprom) +{ + struct ei_device *ei_local = eeprom->data; + u8 reg = ei_inb(ei_local->mem + AX_MEMR); + + reg &= ~(AX_MEMR_EEI | AX_MEMR_EECLK | AX_MEMR_EECS); + + if (eeprom->reg_data_in) + reg |= AX_MEMR_EEI; + if (eeprom->reg_data_clock) + reg |= AX_MEMR_EECLK; + if (eeprom->reg_chip_select) + reg |= AX_MEMR_EECS; + + ei_outb(reg, ei_local->mem + AX_MEMR); + udelay(10); +} +#endif + /* setup code */ static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local) @@ -641,6 +673,23 @@ static int ax_init_dev(struct net_device memcpy(dev->dev_addr, SA_prom, 6); } +#ifdef CONFIG_AX88796_93CX6 + if (first_init && ax->plat->flags & AXFLG_HAS_93CX6) { + unsigned char mac_addr[6]; + struct eeprom_93cx6 eeprom; + + eeprom.data = ei_local; + eeprom.register_read = ax_eeprom_register_read; + eeprom.register_write = ax_eeprom_register_write; + eeprom.width = PCI_EEPROM_WIDTH_93C56B; + + eeprom_93cx6_multiread(&eeprom, 0, + (__le16 __force *)mac_addr, + sizeof(mac_addr) >> 1); + + memcpy(dev->dev_addr, mac_addr, 6); + } +#endif if (ax->plat->wordlength == 2) { /* We must set the 8390 for word mode. */ ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG); --- 0001/include/asm-sh/io.h +++ work/include/asm-sh/io.h 2007-07-26 15:07:23.000000000 +0900 @@ -138,6 +138,34 @@ void __raw_readsl(unsigned long addr, vo #define writesl __raw_writesl #define readsl __raw_readsl +#define __BUILD_MEMORY_STRING(bwlq, type) \ + \ +static inline void writes##bwlq(volatile void __iomem *mem, \ + const void *addr, unsigned int count) \ +{ \ + const volatile type *__addr = addr; \ + \ + while (count--) { \ + __raw_write##bwlq(*__addr, mem); \ + __addr++; \ + } \ +} \ + \ +static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \ + unsigned int count) \ +{ \ + volatile type *__addr = addr; \ + \ + while (count--) { \ + *__addr = __raw_read##bwlq(mem); \ + __addr++; \ + } \ +} + +__BUILD_MEMORY_STRING(b, u8) +__BUILD_MEMORY_STRING(w, u16) +//BUILD_MEMORY_STRING(l, u32) + #define readb_relaxed(a) readb(a) #define readw_relaxed(a) readw(a) #define readl_relaxed(a) readl(a) --- 0001/include/linux/eeprom_93cx6.h +++ work/include/linux/eeprom_93cx6.h 2007-07-26 19:55:29.000000000 +0900 @@ -21,13 +21,14 @@ /* Module: eeprom_93cx6 Abstract: EEPROM reader datastructures for 93cx6 chipsets. - Supported chipsets: 93c46 & 93c66. + Supported chipsets: 93c46, 93c56B and 93c66. */ /* * EEPROM operation defines. */ #define PCI_EEPROM_WIDTH_93C46 6 +#define PCI_EEPROM_WIDTH_93C56B 8 #define PCI_EEPROM_WIDTH_93C66 8 #define PCI_EEPROM_WIDTH_OPCODE 3 #define PCI_EEPROM_WRITE_OPCODE 0x05 --- 0001/include/net/ax88796.h +++ work/include/net/ax88796.h 2007-07-26 19:56:58.000000000 +0900 @@ -14,6 +14,7 @@ #define AXFLG_HAS_EEPROM (1<<0) #define AXFLG_MAC_FROMDEV (1<<1) /* device already has MAC */ +#define AXFLG_HAS_93CX6 (1<<2) /* use eeprom_93cx6 driver */ struct ax_plat_data { unsigned int flags; |