X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fsmc91111.c;h=f91e4b984369fca9c75138be33a808134e779610;hb=58e3b14c18ed3288ceef8d086946dbf3df64ccf2;hp=2a4f005345db4f3294a65186386bd9abb8847746;hpb=c3c7f861aef5abb5173f16af66c3941149954553;p=u-boot diff --git a/drivers/smc91111.c b/drivers/smc91111.c index 2a4f005345..f91e4b9843 100644 --- a/drivers/smc91111.c +++ b/drivers/smc91111.c @@ -160,6 +160,9 @@ extern void eth_halt(void); extern int eth_rx(void); extern int eth_send(volatile void *packet, int length); +#ifdef SHARED_RESOURCES + extern void swap_to(int device_id); +#endif /* . This is called by register_netdev(). It is responsible for @@ -210,7 +213,7 @@ static int smc_rcv(void); . If an EEPROM is present it really should be consulted. */ int smc_get_ethaddr(bd_t *bd); -int get_rom_mac(char *v_rom_mac); +int get_rom_mac(uchar *v_rom_mac); /* ------------------------------------------------------------ @@ -276,17 +279,23 @@ static inline void SMC_outb(byte value, dword offset) static inline void SMC_insw(dword offset, volatile uchar* buf, dword len) { + volatile word *p = (volatile word *)buf; + while (len-- > 0) { - *((word*)buf)++ = SMC_inw(offset); - barrier(); *((volatile u32*)(0xc0000000)); + *p++ = SMC_inw(offset); + barrier(); + *((volatile u32*)(0xc0000000)); } } static inline void SMC_outsw(dword offset, uchar* buf, dword len) { + volatile word *p = (volatile word *)buf; + while (len-- > 0) { - SMC_outw(*((word*)buf)++, offset); - barrier(); *(volatile u32*)(0xc0000000); + SMC_outw(*p++, offset); + barrier(); + *(volatile u32*)(0xc0000000); } } #endif /* CONFIG_SMC_USE_IOFUNCS */ @@ -298,7 +307,7 @@ static char unsigned smc_mac_addr[6] = {0x02, 0x80, 0xad, 0x20, 0x31, 0xb8}; * the default mac address. */ -void smc_set_mac_addr(const char *addr) { +void smc_set_mac_addr(const unsigned char *addr) { int i; for (i=0; i < sizeof(smc_mac_addr); i++){ @@ -527,6 +536,9 @@ static void smc_shutdown() SMC_SELECT_BANK( 0 ); SMC_outb( RCR_CLEAR, RCR_REG ); SMC_outb( TCR_CLEAR, TCR_REG ); +#ifdef SHARED_RESOURCES + swap_to(FLASH); +#endif } @@ -640,8 +652,15 @@ again: } /* we have a packet address, so tell the card to use it */ +#ifndef CONFIG_XAENIAX SMC_outb (packet_no, PN_REG); - +#else + /* On Xaeniax board, we can't use SMC_outb here because that way + * the Allocate MMU command will end up written to the command register + * as well, which will lead to a problem. + */ + SMC_outl (packet_no << 16, 0); +#endif /* do not write new ptr value if Write data fifo not empty */ while ( saved_ptr & PTR_NOTEMPTY ) printf ("Write data fifo not empty!\n"); @@ -676,19 +695,39 @@ again: */ #ifdef USE_32_BIT SMC_outsl (SMC91111_DATA_REG, buf, length >> 2); +#ifndef CONFIG_XAENIAX if (length & 0x2) SMC_outw (*((word *) (buf + (length & 0xFFFFFFFC))), SMC91111_DATA_REG); +#else + /* On XANEIAX, we can only use 32-bit writes, so we need to handle + * unaligned tail part specially. The standard code doesn't work. + */ + if ((length & 3) == 3) { + u16 * ptr = (u16*) &buf[length-3]; + SMC_outl((*ptr) | ((0x2000 | buf[length-1]) << 16), + SMC91111_DATA_REG); + } else if ((length & 2) == 2) { + u16 * ptr = (u16*) &buf[length-2]; + SMC_outl(*ptr, SMC91111_DATA_REG); + } else if (length & 1) { + SMC_outl((0x2000 | buf[length-1]), SMC91111_DATA_REG); + } else { + SMC_outl(0, SMC91111_DATA_REG); + } +#endif #else SMC_outsw (SMC91111_DATA_REG, buf, (length) >> 1); #endif /* USE_32_BIT */ +#ifndef CONFIG_XAENIAX /* Send the last byte, if there is one. */ if ((length & 1) == 0) { SMC_outw (0, SMC91111_DATA_REG); } else { SMC_outw (buf[length - 1] | 0x2000, SMC91111_DATA_REG); } +#endif /* and let the chipset deal with it */ SMC_outw (MC_ENQUEUE, MMU_CMD_REG); @@ -702,7 +741,9 @@ again: /* release packet */ /* no need to release, MMU does that now */ - /* SMC_outw (MC_FREEPKT, MMU_CMD_REG); */ +#ifdef CONFIG_XAENIAX + SMC_outw (MC_FREEPKT, MMU_CMD_REG); +#endif /* wait for MMU getting ready (low) */ while (SMC_inw (MMU_CMD_REG) & MC_BUSY) { @@ -722,7 +763,9 @@ again: /* release packet */ /* no need to release, MMU does that now */ - /* SMC_outw (MC_FREEPKT, MMU_CMD_REG); */ +#ifdef CONFIG_XAENIAX + SMC_outw (MC_FREEPKT, MMU_CMD_REG); +#endif /* wait for MMU getting ready (low) */ while (SMC_inw (MMU_CMD_REG) & MC_BUSY) { @@ -735,7 +778,15 @@ again: } /* restore previously saved registers */ +#ifndef CONFIG_XAENIAX SMC_outb( saved_pnr, PN_REG ); +#else + /* On Xaeniax board, we can't use SMC_outb here because that way + * the Allocate MMU command will end up written to the command register + * as well, which will lead to a problem. + */ + SMC_outl(saved_pnr << 16, 0); +#endif SMC_outw( saved_ptr, PTR_REG ); return length; @@ -795,11 +846,11 @@ static int smc_open (bd_t * bd) address = smc_mac_addr[i + 1] << 8; address |= smc_mac_addr[i]; - SMC_outw (address, ADDR0_REG + i); + SMC_outw (address, (ADDR0_REG + i)); } #else for (i = 0; i < 6; i++) - SMC_outb (smc_mac_addr[i], ADDR0_REG + i); + SMC_outb (smc_mac_addr[i], (ADDR0_REG + i)); #endif return 0; @@ -913,7 +964,15 @@ static int smc_rcv() udelay(1); /* Wait until not busy */ /* restore saved registers */ +#ifndef CONFIG_XAENIAX SMC_outb( saved_pnr, PN_REG ); +#else + /* On Xaeniax board, we can't use SMC_outb here because that way + * the Allocate MMU command will end up written to the command register + * as well, which will lead to a problem. + */ + SMC_outl( saved_pnr << 16, 0); +#endif SMC_outw( saved_ptr, PTR_REG ); if (!is_error) { @@ -1414,7 +1473,7 @@ static void smc_phy_configure () /* Re-Configure the Receive/Phy Control register */ SMC_outw (RPC_DEFAULT, RPC_REG); - smc_phy_configure_exit: +smc_phy_configure_exit: ; } #endif /* !CONFIG_SMC91111_EXT_PHY */ @@ -1458,6 +1517,9 @@ static void print_packet( byte * buf, int length ) #endif int eth_init(bd_t *bd) { +#ifdef SHARED_RESOURCES + swap_to(ETHERNET); +#endif return (smc_open(bd)); } @@ -1477,7 +1539,8 @@ int smc_get_ethaddr (bd_t * bd) { int env_size, rom_valid, env_present = 0, reg; char *s = NULL, *e, *v_mac, es[] = "11:22:33:44:55:66"; - uchar s_env_mac[64], v_env_mac[6], v_rom_mac[6]; + char s_env_mac[64]; + uchar v_env_mac[6], v_rom_mac[6]; env_size = getenv_r ("ethaddr", s_env_mac, sizeof (s_env_mac)); if ((env_size > 0) && (env_size < sizeof (es))) { /* exit if env is bad */ @@ -1500,7 +1563,7 @@ int smc_get_ethaddr (bd_t * bd) if (!env_present) { /* if NO env */ if (rom_valid) { /* but ROM is valid */ - v_mac = v_rom_mac; + v_mac = (char *)v_rom_mac; sprintf (s_env_mac, "%02X:%02X:%02X:%02X:%02X:%02X", v_mac[0], v_mac[1], v_mac[2], v_mac[3], v_mac[4], v_mac[5]); @@ -1510,7 +1573,7 @@ int smc_get_ethaddr (bd_t * bd) return (-1); } } else { /* good env, don't care ROM */ - v_mac = v_env_mac; /* always use a good env over a ROM */ + v_mac = (char *)v_env_mac; /* always use a good env over a ROM */ } if (env_present && rom_valid) { /* if both env and ROM are good */ @@ -1530,13 +1593,13 @@ int smc_get_ethaddr (bd_t * bd) } } memcpy (bd->bi_enetaddr, v_mac, 6); /* update global address to match env (allows env changing) */ - smc_set_mac_addr (v_mac); /* use old function to update smc default */ + smc_set_mac_addr ((uchar *)v_mac); /* use old function to update smc default */ PRINTK("Using MAC Address %02X:%02X:%02X:%02X:%02X:%02X\n", v_mac[0], v_mac[1], v_mac[2], v_mac[3], v_mac[4], v_mac[5]); return (0); } -int get_rom_mac (char *v_rom_mac) +int get_rom_mac (uchar *v_rom_mac) { #ifdef HARDCODE_MAC /* used for testing or to supress run time warnings */ char hw_mac_addr[] = { 0x02, 0x80, 0xad, 0x20, 0x31, 0xb8 }; @@ -1550,7 +1613,7 @@ int get_rom_mac (char *v_rom_mac) SMC_SELECT_BANK (1); for (i=0; i<6; i++) { - v_rom_mac[i] = SMC_inb (ADDR0_REG + i); + v_rom_mac[i] = SMC_inb ((ADDR0_REG + i)); valid_mac |= v_rom_mac[i]; }