diff options
Diffstat (limited to 'drivers/smc91111.c')
| -rw-r--r-- | drivers/smc91111.c | 71 | 
1 files changed, 71 insertions, 0 deletions
| diff --git a/drivers/smc91111.c b/drivers/smc91111.c index 8b1103bb6..2a4f00534 100644 --- a/drivers/smc91111.c +++ b/drivers/smc91111.c @@ -220,6 +220,77 @@ int get_rom_mac(char *v_rom_mac);   ------------------------------------------------------------  */ +#ifdef CONFIG_SMC_USE_IOFUNCS +/* + * input and output functions + * + * Implemented due to inx,outx macros accessing the device improperly + * and putting the device into an unkown state. + * + * For instance, on Sharp LPD7A400 SDK, affects were chip memory + * could not be free'd (hence the alloc failures), duplicate packets, + * packets being corrupt (shifted) on the wire, etc.  Switching to the + * inx,outx functions fixed this problem. + */ +static inline word SMC_inw(dword offset); +static inline void SMC_outw(word value, dword offset); +static inline byte SMC_inb(dword offset); +static inline void SMC_outb(byte value, dword offset); +static inline void SMC_insw(dword offset, volatile uchar* buf, dword len); +static inline void SMC_outsw(dword offset, uchar* buf, dword len); + +#define barrier() __asm__ __volatile__("": : :"memory") + +static inline word SMC_inw(dword offset) +{ +	word v; +	v = *((volatile word*)(SMC_BASE_ADDRESS+offset)); +	barrier(); *(volatile u32*)(0xc0000000); +	return v; +} + +static inline void SMC_outw(word value, dword offset) +{ +	*((volatile word*)(SMC_BASE_ADDRESS+offset)) = value; +	barrier(); *(volatile u32*)(0xc0000000); +} + +static inline byte SMC_inb(dword offset) +{ +	word  _w; + +	_w = SMC_inw(offset & ~((dword)1)); +	return (offset & 1) ? (byte)(_w >> 8) : (byte)(_w); +} + +static inline void SMC_outb(byte value, dword offset) +{ +	word  _w; + +	_w = SMC_inw(offset & ~((dword)1)); +	if (offset & 1) +			*((volatile word*)(SMC_BASE_ADDRESS+(offset & ~((dword)1)))) = (value<<8) | (_w & 0x00ff); +	else +			*((volatile word*)(SMC_BASE_ADDRESS+offset)) = value | (_w & 0xff00); +} + +static inline void SMC_insw(dword offset, volatile uchar* buf, dword len) +{ +	while (len-- > 0) { +		*((word*)buf)++ = SMC_inw(offset); +		barrier(); *((volatile u32*)(0xc0000000)); +	} +} + +static inline void SMC_outsw(dword offset, uchar* buf, dword len) +{ +	while (len-- > 0) { +		SMC_outw(*((word*)buf)++, offset); +		barrier(); *(volatile u32*)(0xc0000000); +	} +} +#endif  /* CONFIG_SMC_USE_IOFUNCS */ +  static char unsigned smc_mac_addr[6] = {0x02, 0x80, 0xad, 0x20, 0x31, 0xb8};  /* |