Add Atari specific code to the smc91x Ethernet driver. This code is used on the EtherNAT adapter card for the Atari Falcon extension port. Without the patch to smc91x.h, the first two bytes of every ethernet packet sent out are swapped, resulting in a wrong MAC address being read by the packet's target, and failure to establish communication. Signed-off-by: Michael Schmitz <schmitz@xxxxxxxxxx> --- arch/m68k/Kconfig.devices | 10 ++++++ drivers/net/ethernet/smsc/Kconfig | 4 +- drivers/net/ethernet/smsc/smc91x.h | 63 ++++++++++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices index 4bc945d..d50ecbf 100644 --- a/arch/m68k/Kconfig.devices +++ b/arch/m68k/Kconfig.devices @@ -55,6 +55,16 @@ config NFETH which will emulate a regular ethernet device while presenting an ethertap device to the host system. +config ATARI_ETHERNAT + bool "Atari EtherNAT Ethernet support" + depends on ATARI + ---help--- + Say Y to include support for the EtherNAT network adapter for the + CT/60 extension port. + + To compile the actual ethernet driver, choose Y or M for the SMC91X + option in the network device section; the module will be called smc91x. + endmenu menu "Character devices" diff --git a/drivers/net/ethernet/smsc/Kconfig b/drivers/net/ethernet/smsc/Kconfig index 5a689af..d3485cf 100644 --- a/drivers/net/ethernet/smsc/Kconfig +++ b/drivers/net/ethernet/smsc/Kconfig @@ -6,7 +6,7 @@ config NET_VENDOR_SMSC bool "SMC (SMSC)/Western Digital devices" default y depends on ARM || ISA || MAC || ARM || MIPS || M32R || SUPERH || \ - BLACKFIN || MN10300 || COLDFIRE || PCI || PCMCIA + BLACKFIN || MN10300 || COLDFIRE || PCI || PCMCIA || ATARI ---help--- If you have a network (Ethernet) card belonging to this class, say Y and read the Ethernet-HOWTO, available from @@ -40,7 +40,7 @@ config SMC91X select NET_CORE select MII depends on (ARM || M32R || SUPERH || MIPS || BLACKFIN || \ - MN10300 || COLDFIRE) + MN10300 || COLDFIRE || ATARI_ETHERNAT) ---help--- This is a driver for SMC's 91x series of Ethernet chipsets, including the SMC91C94 and the SMC91C111. Say Y if you want it diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h index 370e13d..528f7ba 100644 --- a/drivers/net/ethernet/smsc/smc91x.h +++ b/drivers/net/ethernet/smsc/smc91x.h @@ -231,6 +231,30 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #include <unit/smc91111.h> +#elif defined(CONFIG_ATARI) + +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 1 +#define SMC_NOWAIT 1 + +#define writew_be(val, addr) out_be16((addr), (val)) + +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_outw_be(v, a, r) writew_be(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) +#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) +#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) + +#define RPC_LSA_DEFAULT RPC_LED_100_10 +#define RPC_LSB_DEFAULT RPC_LED_TX_RX + #elif defined(CONFIG_ARCH_MSM) #define SMC_CAN_USE_8BIT 0 @@ -1116,6 +1140,40 @@ static const char * chip_ids[ 16 ] = { } \ } while (0) +#if defined(CONFIG_ATARI) +/* + * MSch: EtherNAT is 32 bit, so the misaligned data buffer hack applies. + * This appears to hurt quite a lot ... we actually need to byte swap the + * misaligned write because the data end up in the packet buffer swapped + * otherwise (resulting in the first two bytes of the target MAC address + * being swapped) + */ +#define SMC_PUSH_DATA(lp, p, l) \ + do { \ + if (SMC_32BIT(lp)) { \ + void *__ptr = (p); \ + int __len = (l); \ + void __iomem *__ioaddr = ioaddr; \ + if (__len >= 2 && (unsigned long)__ptr & 2) { \ + __len -= 2; \ + SMC_outw_be(*(u16 *)__ptr, ioaddr, \ + DATA_REG(lp)); \ + __ptr += 2; \ + } \ + if (SMC_CAN_USE_DATACS && lp->datacs) \ + __ioaddr = lp->datacs; \ + SMC_outsl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \ + if (__len & 2) { \ + __ptr += (__len & ~3); \ + SMC_outw_be(*((u16 *)__ptr), ioaddr, \ + DATA_REG(lp)); \ + } \ + } else if (SMC_16BIT(lp)) \ + SMC_outsw(ioaddr, DATA_REG(lp), (u16 *) p, (l) >> 1); \ + else if (SMC_8BIT(lp)) \ + SMC_outsb(ioaddr, DATA_REG(lp), p, l); \ + } while (0) +#else #define SMC_PUSH_DATA(lp, p, l) \ do { \ if (SMC_32BIT(lp)) { \ @@ -1137,10 +1195,11 @@ static const char * chip_ids[ 16 ] = { DATA_REG(lp)); \ } \ } else if (SMC_16BIT(lp)) \ - SMC_outsw(ioaddr, DATA_REG(lp), p, (l) >> 1); \ + SMC_outsw(ioaddr, DATA_REG(lp), (u16 *) p, (l) >> 1); \ else if (SMC_8BIT(lp)) \ SMC_outsb(ioaddr, DATA_REG(lp), p, l); \ } while (0) +#endif #define SMC_PULL_DATA(lp, p, l) \ do { \ @@ -1172,7 +1231,7 @@ static const char * chip_ids[ 16 ] = { __len += 2; \ SMC_insl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \ } else if (SMC_16BIT(lp)) \ - SMC_insw(ioaddr, DATA_REG(lp), p, (l) >> 1); \ + SMC_insw(ioaddr, DATA_REG(lp), (u16 *) p, (l) >> 1); \ else if (SMC_8BIT(lp)) \ SMC_insb(ioaddr, DATA_REG(lp), p, l); \ } while (0) -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-m68k" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html