diff -Nru linux-source-2.4.26-vrs1-pxa1-arcom3/drivers/net/smc91x.c.orig linux-source-2.4.26-vrs1-pxa1-arcom3/drivers/net/smc91x.c --- linux-source-2.4.26-vrs1-pxa1-arcom3/drivers/net/smc91x.c.orig 2004-08-11 03:23:18.000000000 -0700 +++ linux-source-2.4.26-vrs1-pxa1-arcom3/drivers/net/smc91x.c 2005-09-12 16:30:23.000000000 -0700 @@ -79,19 +79,307 @@ #include #include -#include "smc91x.h" +#include + +static u_int16_t smc91c111_mii_get_2(unsigned long); +static void smc91c111_mii_set_2(unsigned long, u_int16_t); +static unsigned long smc91_base; + +#define _INCLUDE_ONCE_smc91c111 1 +#include "smc-91c111-mac+phy.hail.h" + +#if 1 + +#define SMC_CAN_USE_ISA 0 +#define SMC_IOADDR (VIPER_ETH_PHYS + 0x300) +#define SMC_DATACSADDR (VIPER_ETH_DATA_PHYS) +#define SMC_IRQ VIPER_ETH_IRQ +#define SMC_USE_DATACS 0 +#define SMC_NOWAIT 1 + +#define MII_MSK_CRS100 0x4000 // Disables CRS100 detection during tx half dup +#define MII_MDOE 0x0008 // MII Output Enable +#define MII_MCLK 0x0004 // MII Clock, pin MDCLK +#define MII_MDI 0x0002 // MII Input, pin MDI +#define MII_MDO 0x0001 // MII Output, pin MDO + +/* when to use datacs */ +//#undef SMC_USE_DATACS_RX +//#undef SMC_USE_DATACS_TX +//#undef SMC_USE_DATACS_BOTH +#define SMC_USE_DATACS_RX 1 +#define SMC_USE_DATACS_TX 2 +#define SMC_USE_DATACS_BOTH 3 + +//#undef SMC_IO_EXTENT +//#undef SMC_DATA_EXTENT +//#undef SMC_IO_SHIFT +#define SMC_IO_SHIFT 0 +#define SMC_IO_EXTENT (16 << SMC_IO_SHIFT) +#define SMC_DATA_EXTENT 4 + +// Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low +//#undef CONFIG_DEFAULT +#define CONFIG_DEFAULT CR_EPH_Power_EN_VAL(1) + +#define TCR_CLEAR 0 /* do NOTHING */ +/* the default settings for the TCR register : */ +#define TCR_DEFAULT (TCR_TXENA_VAL(1) | TCR_PAD_EN_VAL(1)) + +/* the normal settings for the RCR register : */ +#define RCR_DEFAULT (RCR_STRIP_CRC_VAL(1) | RCR_RXEN_VAL(1)) +#define RCR_CLEAR 0x0 // set it to a base state + +//#undef RPC_DEFAULT +#define RPC_DEFAULT (RPCR_ANEG_VAL(1) | RPCR_LEDA_VAL(RPCR_LINK10or100) | RPCR_LEDB_VAL(RPCR_FDX) | RPCR_SPEED_VAL(1) | RPCR_DPLX_VAL(1)) + +#define CHIP_9192 3 +#define CHIP_9194 4 +#define CHIP_9195 5 +#define CHIP_9196 6 +#define CHIP_91100 7 +#define CHIP_91100FD 8 +#define CHIP_91111FD 9 + +static const char * chip_ids[ 16 ] = { + NULL, NULL, NULL, + /* 3 */ "SMC91C90/91C92", + /* 4 */ "SMC91C94", + /* 5 */ "SMC91C95", + /* 6 */ "SMC91C96", + /* 7 */ "SMC91C100", + /* 8 */ "SMC91C100FD", + /* 9 */ "SMC91C11xFD", + NULL, NULL, NULL, + NULL, NULL, NULL}; + + +/* + . Transmit status bits +*/ +#define TS_SUCCESS 0x0001 +#define TS_LOSTCAR 0x0400 +#define TS_LATCOL 0x0200 +#define TS_16COL 0x0010 -#ifdef SMC91X_CAN_USE_ISA /* - . the LAN91C111 can be at any of the following port addresses. To change, - . for a slightly different card, you can add it to the array. Keep in - . mind that the array must end in zero. + . Receive status bits */ -static unsigned int smc_portlist[] __initdata = { - 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, - 0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0 +#define RS_ALGNERR 0x8000 +#define RS_BRODCAST 0x4000 +#define RS_BADCRC 0x2000 +#define RS_ODDFRAME 0x1000 +#define RS_TOOLONG 0x0800 +#define RS_TOOSHORT 0x0400 +#define RS_MULTICAST 0x0001 +#define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) + + +// PHY Types +enum { + PHY_LAN83C183 = 1, // LAN91C111 Internal PHY + PHY_LAN83C180 }; -#endif /* SMC91X_CAN_USE_ISA */ + + +// PHY Register Addresses (LAN91C111 Internal PHY) +// these are unused when using HAIL + +// PHY Control Register +//#define PHY_CNTL_REG 0x00 +//#define PHY_CNTL_RST 0x8000 // 1=PHY Reset +//#define PHY_CNTL_LPBK 0x4000 // 1=PHY Loopback +//#define PHY_CNTL_SPEED 0x2000 // 1=100Mbps, 0=10Mpbs +//#define PHY_CNTL_ANEG_EN 0x1000 // 1=Enable Auto negotiation +//#define PHY_CNTL_PDN 0x0800 // 1=PHY Power Down mode +//#define PHY_CNTL_MII_DIS 0x0400 // 1=MII 4 bit interface disabled +//#define PHY_CNTL_ANEG_RST 0x0200 // 1=Reset Auto negotiate +//#define PHY_CNTL_DPLX 0x0100 // 1=Full Duplex, 0=Half Duplex +//#define PHY_CNTL_COLTST 0x0080 // 1= MII Colision Test + +// PHY Status Register +//#define PHY_STAT_REG 0x01 +//#define PHY_STAT_CAP_T4 0x8000 // 1=100Base-T4 capable +//#define PHY_STAT_CAP_TXF 0x4000 // 1=100Base-X full duplex capable +//#define PHY_STAT_CAP_TXH 0x2000 // 1=100Base-X half duplex capable +//#define PHY_STAT_CAP_TF 0x1000 // 1=10Mbps full duplex capable +//#define PHY_STAT_CAP_TH 0x0800 // 1=10Mbps half duplex capable +//#define PHY_STAT_CAP_SUPR 0x0040 // 1=recv mgmt frames with not preamble +//#define PHY_STAT_ANEG_ACK 0x0020 // 1=ANEG has completed +//#define PHY_STAT_REM_FLT 0x0010 // 1=Remote Fault detected +//#define PHY_STAT_CAP_ANEG 0x0008 // 1=Auto negotiate capable +//#define PHY_STAT_LINK 0x0004 // 1=valid link +//#define PHY_STAT_JAB 0x0002 // 1=10Mbps jabber condition +//#define PHY_STAT_EXREG 0x0001 // 1=extended registers implemented + +// PHY Identifier Registers +//#define PHY_ID1_REG 0x02 // PHY Identifier 1 +//#define PHY_ID2_REG 0x03 // PHY Identifier 2 + +// PHY Auto-Negotiation Advertisement Register +//#define PHY_AD_REG 0x04 +//#define PHY_AD_NP 0x8000 // 1=PHY requests exchange of Next Page +//#define PHY_AD_ACK 0x4000 // 1=got link code word from remote +//#define PHY_AD_RF 0x2000 // 1=advertise remote fault +//#define PHY_AD_T4 0x0200 // 1=PHY is capable of 100Base-T4 +//#define PHY_AD_TX_FDX 0x0100 // 1=PHY is capable of 100Base-TX FDPLX +//#define PHY_AD_TX_HDX 0x0080 // 1=PHY is capable of 100Base-TX HDPLX +//#define PHY_AD_10_FDX 0x0040 // 1=PHY is capable of 10Base-T FDPLX +//#define PHY_AD_10_HDX 0x0020 // 1=PHY is capable of 10Base-T HDPLX +//#define PHY_AD_CSMA 0x0001 // 1=PHY is capable of 802.3 CMSA + +// PHY Auto-negotiation Remote End Capability Register +//#define PHY_RMT_REG 0x05 +// Uses same bit definitions as PHY_AD_REG + +// PHY Configuration Register 1 +//#define PHY_CFG1_REG 0x10 +//#define PHY_CFG1_LNKDIS 0x8000 // 1=Rx Link Detect Function disabled +//#define PHY_CFG1_XMTDIS 0x4000 // 1=TP Transmitter Disabled +//#define PHY_CFG1_XMTPDN 0x2000 // 1=TP Transmitter Powered Down +//#define PHY_CFG1_BYPSCR 0x0400 // 1=Bypass scrambler/descrambler +//#define PHY_CFG1_UNSCDS 0x0200 // 1=Unscramble Idle Reception Disable +//#define PHY_CFG1_EQLZR 0x0100 // 1=Rx Equalizer Disabled +//#define PHY_CFG1_CABLE 0x0080 // 1=STP(150ohm), 0=UTP(100ohm) +//#define PHY_CFG1_RLVL0 0x0040 // 1=Rx Squelch level reduced by 4.5db +//#define PHY_CFG1_TLVL_SHIFT 2 // Transmit Output Level Adjust +//#define PHY_CFG1_TLVL_MASK 0x003C +//#define PHY_CFG1_TRF_MASK 0x0003 // Transmitter Rise/Fall time + + +// PHY Configuration Register 2 +//#define PHY_CFG2_REG 0x11 +//#define PHY_CFG2_APOLDIS 0x0020 // 1=Auto Polarity Correction disabled +//#define PHY_CFG2_JABDIS 0x0010 // 1=Jabber disabled +//#define PHY_CFG2_MREG 0x0008 // 1=Multiple register access (MII mgt) +//#define PHY_CFG2_INTMDIO 0x0004 // 1=Interrupt signaled with MDIO pulseo + +// PHY Status Output (and Interrupt status) Register +//#define PHY_INT_REG 0x12 // Status Output (Interrupt Status) +//#define PHY_INT_INT 0x8000 // 1=bits have changed since last read +//#define PHY_INT_LNKFAIL 0x4000 // 1=Link Not detected +//#define PHY_INT_LOSSSYNC 0x2000 // 1=Descrambler has lost sync +//#define PHY_INT_CWRD 0x1000 // 1=Invalid 4B5B code detected on rx +//#define PHY_INT_SSD 0x0800 // 1=No Start Of Stream detected on rx +//#define PHY_INT_ESD 0x0400 // 1=No End Of Stream detected on rx +//#define PHY_INT_RPOL 0x0200 // 1=Reverse Polarity detected +//#define PHY_INT_JAB 0x0100 // 1=Jabber detected +//#define PHY_INT_SPDDET 0x0080 // 1=100Base-TX mode, 0=10Base-T mode +//#define PHY_INT_DPLXDET 0x0040 // 1=Device in Full Duplex + +// PHY Interrupt/Status Mask Register +//#define PHY_MASK_REG 0x13 // Interrupt Mask +// Uses the same bit definitions as PHY_INT_REG +#endif + +#if 1 +//#undef SMC_GET_MAC_ADDR +#define SMC_GET_MAC_ADDR(addr) \ + do { \ + unsigned int __v; \ + __v = get_IAR1_0(); \ + addr[0] = __v; addr[1] = __v >> 8; \ + __v = get_IAR3_2(); \ + addr[2] = __v; addr[3] = __v >> 8; \ + __v = get_IAR5_4(); \ + addr[4] = __v; addr[5] = __v >> 8; \ + } while (0) + +//#undef SMC_SET_MAC_ADDR +#define SMC_SET_MAC_ADDR(addr) \ + do { \ + set_IAR1_0( addr[0]|(addr[1] << 8)); \ + set_IAR3_2( addr[2]|(addr[3] << 8)); \ + set_IAR5_4( addr[4]|(addr[5] << 8)); \ + } while (0) + +//#undef SMC_CLEAR_MCAST +#define SMC_CLEAR_MCAST() \ + do { \ + set_MT1_0(0); \ + set_MT3_2(0); \ + set_MT5_4(0); \ + set_MT7_6(0); \ + } while (0) +//#undef SMC_SET_MCAST +#define SMC_SET_MCAST(x) \ + do { \ + unsigned char *mt = (x); \ + set_MT1_0( mt[0] | (mt[1] << 8)); \ + set_MT3_2( mt[2] | (mt[3] << 8)); \ + set_MT5_4( mt[4] | (mt[5] << 8)); \ + set_MT7_6( mt[6] | (mt[7] << 8)); \ + } while (0) + +//#undef SMC_PUT_PKT_HDR +#define SMC_PUT_PKT_HDR(status, length) \ + do { \ + set_DATA( status); \ + set_DATA( length); \ + } while (0) +//#undef SMC_GET_PKT_HDR +#define SMC_GET_PKT_HDR(status, length) \ + do { \ + (status) = get_DATA(); \ + (length) = get_DATA(); \ + } while (0) + +//#undef SMC_ACK_INT +#define SMC_ACK_INT(x) \ + do { \ + unsigned long __flags; \ + int __mask; \ + local_irq_save(__flags); \ + __mask = get_MSK() & ~0xff; \ + set_ACK( __mask | (x)); \ + local_irq_restore(__flags); \ + } while (0) + + +//#undef SMC_PUSH_DATA +#define SMC_PUSH_DATA(p, l) \ + if ( lp->datacs && ( lp->use_datacs & SMC_USE_DATACS_TX ) ) { \ + char *__ptr = (p); \ + int __len = (l); \ + if (__len >= 2 && (long)__ptr & 2) { \ + __len -= 2; \ + set_DATA( *((u16 *)__ptr)++);\ + } \ + outsl(lp->datacs, __ptr, __len >> 2); \ + if (__len & 2) { \ + __ptr += (__len & ~3); \ + set_DATA( *((u16 *)__ptr)); \ + } \ + } else { \ + /* _SMC_PUSH_DATA(p, l); */ \ + outsw(smc91_base+8, p, (l)>>1); \ + } /* HACK, jsun */ + +//#undef SMC_PULL_DATA +#define SMC_PULL_DATA(p, l) \ + if ( lp->datacs && ( lp->use_datacs & SMC_USE_DATACS_RX ) ) { \ + char *__ptr = (p); \ + int __len = (l); \ + if ((long)__ptr & 2) { \ + /* \ + * We want 32bit alignment here. \ + * Since some buses perform a full 32bit \ + * fetch even for 16bit data we can't use \ + * SMC_inw() here. Back both source (on chip \ + * and destination) pointers of 2 bytes. \ + */ \ + (long)__ptr &= ~2; \ + __len += 2; \ + set_PTR( 2|PTR_READ_VAL(1)|PTR_RCV_VAL(1)|PTR_AUTO_INCR_VAL(1) ); \ + } \ + __len += 2; \ + insl( lp->datacs, __ptr, __len >> 2); \ + } else { \ + /* _SMC_PULL_DATA(p, l); */ \ + insw(smc91_base+8, p, (l)>>1);/* HACK, jsun */ \ + } + +#endif #ifndef SMC_IOADDR # define SMC_IOADDR -1 @@ -189,13 +477,15 @@ int lastPhy18; // Contains the current active transmission mode - int tcr_cur_mode; + // int tcr_cur_mode; + unsigned short tcr_cur_mode; // Contains the current active receive mode - int rcr_cur_mode; + unsigned short rcr_cur_mode; // Contains the current active receive/phy mode - int rpc_cur_mode; + // int rpc_cur_mode; + unsigned short rpc_cur_mode; int ctl_autoneg; int ctl_rfduplx; int ctl_rspeed; @@ -266,32 +556,32 @@ /* this enables an interrupt in the interrupt mask register */ -#define SMC_ENABLE_INT(x) do { \ +#define smc_ENABLE_INT(x) do { \ unsigned long flags; \ - unsigned char mask; \ + unsigned short mask; \ local_irq_save(flags); \ - mask = SMC_GET_INT_MASK(); \ + mask = get_MSK(); \ mask |= (x); \ - SMC_SET_INT_MASK(mask); \ + set_MSK(mask & 0xff00); \ local_irq_restore(flags); \ } while (0) /* this disables an interrupt from the interrupt mask register */ -#define SMC_DISABLE_INT(x) do { \ +#define smc_DISABLE_INT(x) do { \ unsigned long flags; \ - unsigned char mask; \ + unsigned short mask; \ local_irq_save(flags); \ - mask = SMC_GET_INT_MASK(); \ + mask = get_MSK(); \ mask &= ~(x); \ - SMC_SET_INT_MASK(mask); \ + set_MSK(mask & 0xff00); \ local_irq_restore(flags); \ } while (0) /* wait while MMU is busy */ -#define SMC_WAIT_MMU_BUSY() do { \ - if (unlikely(SMC_GET_MMU_CMD() & MC_BUSY)) { \ +#define smc_WAIT_MMU_BUSY() do { \ + if (get_MMUCR_BUSY() != 0 ) { \ unsigned long timeout = jiffies + 2; \ - while (SMC_GET_MMU_CMD() & MC_BUSY) { \ + while (get_MMUCR_BUSY() !=0 ) { \ if (time_after(jiffies, timeout)) { \ PRINTK("%s: timeout %s line %d\n", \ dev->name, __FILE__, __LINE__); \ @@ -302,46 +592,58 @@ } while (0) /* prototypes */ + static int smc_read_phy_register(unsigned long ioaddr, int phyaddr, int phyreg); static void smc_write_phy_register( unsigned long ioaddr, int phyaddr, int phyreg, int phydata ); +/* HAIL gated spec callback support */ +//static u_int16_t smc91c111_mii_get_2(unsigned long); +//static void smc91c111_mii_set_2(unsigned long, u_int16_t); +static int smc91c111_mii_ioaddr; /* XXX HACK compensates for weak HAIL gated spec callback API */ +static int smc91c111_mii_phyaddr; /* XXX " " " " " " " */ + +static u_int16_t +smc91c111_mii_get_2(unsigned long regoff) +{ + return smc_read_phy_register(smc91c111_mii_ioaddr, smc91c111_mii_phyaddr, regoff); +} +static void +smc91c111_mii_set_2(unsigned long regoff, u_int16_t val) +{ + smc_write_phy_register(smc91c111_mii_ioaddr, smc91c111_mii_phyaddr, regoff, val); +} + /* this does a soft reset on the device */ static void smc_reset(struct net_device *dev) { - unsigned long ioaddr = dev->base_addr; PRINTK2("%s: %s\n", dev->name, __FUNCTION__); /* This resets the registers mostly to defaults, but doesn't affect EEPROM. That seems unnecessary */ - SMC_SELECT_BANK( 0 ); - SMC_SET_RCR( RCR_SOFTRST ); - + set_BSR_BANK( 0 ); + set_RCR(RCR_SOFT_RST_VAL(1)); + /* Setup the Configuration Register */ /* This is necessary because the CONFIG_REG is not affected */ /* by a soft reset */ - SMC_SELECT_BANK( 1 ); - SMC_SET_CONFIG( CONFIG_DEFAULT ); + set_BSR_BANK( 1 ); + set_CR( CONFIG_DEFAULT ); /* Setup for fast accesses if requested */ /* If the card/system can't handle it then there will */ /* be no recovery except for a hard reset or power cycle */ if (nowait) - SMC_SET_CONFIG( SMC_GET_CONFIG() | CONFIG_NO_WAIT ); + set_CR_NO_WAIT(1); #ifdef POWER_DOWN { - int status; - struct smc_local *lp = (struct smc_local *)dev->priv; - int phyaddr = lp->phyaddr; - /* Release from possible power-down state */ /* Configuration register is not affected by Soft Reset */ - SMC_SELECT_BANK( 1 ); - SMC_SET_CONFIG( SMC_GET_CONFIG() | CONFIG_EPH_POWER_EN ); - status = smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG); - status &= ~PHY_CNTL_PDN; - smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, status); + set_BSR_BANK( 1 ); + // set_CR( SMC_GET_CONFIG() | CONFIG_EPH_POWER_EN ); + set_CR_EPH_Power_EN(1); + set_Control_PDN(0); } #endif @@ -349,80 +651,78 @@ udelay(1); /* Disable transmit and receive functionality */ - SMC_SELECT_BANK( 0 ); - SMC_SET_RCR( RCR_CLEAR ); - SMC_SET_TCR( TCR_CLEAR ); + set_BSR_BANK( 0 ); + set_RCR( RCR_CLEAR ); + set_TCR( TCR_CLEAR ); /* set the control register to automatically release successfully transmitted packets, to make the best use out of our limited memory */ - SMC_SELECT_BANK( 1 ); + set_BSR_BANK( 1 ); #if ! THROTTLE_TX_PKTS - SMC_SET_CTL( SMC_GET_CTL() | CTL_AUTO_RELEASE ); + //SMC_SET_CTL( SMC_GET_CTL() | CTL_AUTO_RELEASE ); + set_CTR_AUTO_RELEASE(1); #else - SMC_SET_CTL( SMC_GET_CTL() & ~CTL_AUTO_RELEASE ); + //SMC_SET_CTL( SMC_GET_CTL() & ~CTL_AUTO_RELEASE ); + set_CTR_AUTO_RELEASE(0); #endif /* Disable all interrupts */ - SMC_SELECT_BANK( 2 ); - SMC_SET_INT_MASK( 0 ); + set_BSR_BANK( 2 ); + set_MSK( 0 ); /* Reset the MMU */ - SMC_SET_MMU_CMD( MC_RESET ); - SMC_WAIT_MMU_BUSY(); + set_MMUCR_CMD(MMUCR_MMU_RESET ); + smc_WAIT_MMU_BUSY(); } /* Enable Interrupts, Receive, and Transmit */ static void smc_enable(struct net_device *dev) { - unsigned long ioaddr = dev->base_addr; + // unsigned long ioaddr = dev->base_addr; struct smc_local *lp = (struct smc_local *)dev->priv; - int mask; + unsigned short mask=0; PRINTK2("%s: %s\n", dev->name, __FUNCTION__); /* see the header file for options in TCR/RCR DEFAULT*/ - SMC_SELECT_BANK( 0 ); - SMC_SET_TCR( lp->tcr_cur_mode ); - SMC_SET_RCR( lp->rcr_cur_mode ); + set_BSR_BANK( 0 ); + set_TCR( lp->tcr_cur_mode ); + set_RCR( lp->rcr_cur_mode ); /* now, enable interrupts */ - mask = IM_EPH_INT|IM_RX_OVRN_INT|IM_RCV_INT; + mem_set_MSK_EPH_INT(&mask, 1); + mem_set_MSK_RX_OVRN_INT(&mask, 1); + mem_set_MSK_RCV_INT(&mask, 1); if (lp->version >= 0x70) - mask |= IM_MDINT; - SMC_SELECT_BANK( 2 ); - SMC_SET_INT_MASK( mask ); + mem_set_MSK_MDINT(&mask,1); + set_BSR_BANK( 2 ); + set_MSK( mask ); } /* this puts the device in an inactive state */ static void smc_shutdown(struct net_device *dev) { - int ioaddr = dev->base_addr; - struct smc_local *lp = (struct smc_local *)dev->priv; - int phyaddr = lp->phyaddr; - int status; - PRINTK2("%s: %s\n", CARDNAME, __FUNCTION__); /* no more interrupts for me */ - SMC_SELECT_BANK( 2 ); - SMC_SET_INT_MASK( 0 ); + set_BSR_BANK( 2 ); + set_MSK( 0 ); /* and tell the card to stay away from that nasty outside world */ - SMC_SELECT_BANK( 0 ); - SMC_SET_RCR( RCR_CLEAR ); - SMC_SET_TCR( TCR_CLEAR ); + set_BSR_BANK( 0 ); + set_RCR( RCR_CLEAR ); + set_TCR( TCR_CLEAR ); #ifdef POWER_DOWN - status = smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG); - status |= PHY_CNTL_PDN; - smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, status); + set_Control_PDN(1); /* finally, shut the chip down */ - SMC_SELECT_BANK( 1 ); - SMC_SET_CONFIG( SMC_GET_CONFIG() & ~CONFIG_EPH_POWER_EN ); + set_BSR_BANK( 1 ); + // set_CR( SMC_GET_CONFIG() & ~CONFIG_EPH_POWER_EN ); + set_CR_EPH_Power_EN(0); #endif } @@ -431,19 +731,19 @@ smc_rcv(struct net_device *dev) { struct smc_local *lp = (struct smc_local *)dev->priv; - unsigned long ioaddr = dev->base_addr; unsigned int packet_number, status, packet_len; PRINTK3("%s: %s\n", dev->name, __FUNCTION__); - packet_number = SMC_GET_RXFIFO(); - if (unlikely(packet_number & RXFIFO_REMPTY)) { + packet_number = get_FIFO(); + if (mem_get_FIFO_REMPTY(packet_number)) { printk(KERN_WARNING "%s: smc_rcv with nothing on FIFO.\n", dev->name); return; } + packet_number = mem_get_FIFO_RX_FIFO_PACKET_NUMBER(packet_number); /* read from start of packet */ - SMC_SET_PTR( PTR_READ | PTR_RCV | PTR_AUTOINC ); + set_PTR(PTR_READ_VAL(1) | PTR_RCV_VAL(1) | PTR_AUTO_INCR_VAL(1) ); /* First two words are status and packet length */ SMC_GET_PKT_HDR(status, packet_len); @@ -509,8 +809,8 @@ } done: - SMC_WAIT_MMU_BUSY(); - SMC_SET_MMU_CMD( MC_RELEASE ); + smc_WAIT_MMU_BUSY(); + set_MMUCR_CMD(MMUCR_RX_FIFO_RnR); } /* @@ -521,7 +821,6 @@ smc_hardware_send_packet(struct net_device *dev) { struct smc_local *lp = (struct smc_local *)dev->priv; - unsigned long ioaddr = dev->base_addr; struct sk_buff *skb = lp->saved_skb; unsigned int packet_no, len; unsigned char *buf; @@ -533,8 +832,8 @@ return; } - packet_no = SMC_GET_AR(); - if (unlikely(packet_no & AR_FAILED)) { + packet_no = get_ARR(); + if (unlikely(mem_get_ARR_FAILED(packet_no)!=0)) { printk(KERN_WARNING "%s: Memory allocation failed.\n", dev->name); lp->saved_skb = NULL; lp->stats.tx_errors++; @@ -542,10 +841,11 @@ dev_kfree_skb_any(skb); return; } + packet_no >>=8; /* FIXME, jsun */ /* point to the beginning of the packet */ - SMC_SET_PN( packet_no ); - SMC_SET_PTR( PTR_AUTOINC ); + set_PNR( packet_no ); + set_PTR( PTR_AUTO_INCR_VAL(1) ); buf = skb->data; len = skb->len; @@ -563,11 +863,11 @@ SMC_PUSH_DATA(buf, len & ~1); /* Send final ctl word with the last byte if there is one */ - SMC_outw( ((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG ); + set_DATA( ((len & 1) ? (0x2000 | buf[len-1]) : 0)); /* and let the chipset deal with it */ - SMC_SET_MMU_CMD( MC_ENQUEUE ); - SMC_ACK_INT( IM_TX_EMPTY_INT ); + set_MMUCR_CMD( MMUCR_ENQUEUE_PNO); + SMC_ACK_INT( ACK_TX_EMPTY_INT_VAL(1) ); dev->trans_start = jiffies; dev_kfree_skb_any(skb); @@ -586,7 +886,6 @@ smc_hard_start_xmit( struct sk_buff * skb, struct net_device * dev ) { struct smc_local *lp = (struct smc_local *)dev->priv; - unsigned long ioaddr = dev->base_addr; unsigned int numPages, poll_count, status, saved_bank; PRINTK3("%s: %s\n", dev->name, __FUNCTION__); @@ -625,9 +924,10 @@ } /* now, try to allocate the memory */ - saved_bank = SMC_CURRENT_BANK(); - SMC_SELECT_BANK( 2 ); - SMC_SET_MMU_CMD( MC_ALLOC | numPages ); + saved_bank = get_BSR_BANK(); + set_BSR_BANK( 2 ); + // SMC_SET_MMU_CMD( MC_ALLOC | numPages ); + set_MMUCR( MMUCR_CMD_VAL(MMUCR_TX_ALLOC) | numPages ); /* * Poll the chip for a short amount of time in case the @@ -635,9 +935,9 @@ */ poll_count = MEMORY_WAIT_TIME; do { - status = SMC_GET_INT(); - if (status & IM_ALLOC_INT) { - SMC_ACK_INT( IM_ALLOC_INT ); + status = get_IST(); + if (mem_get_IST_ALLOC_INT(status)) { + SMC_ACK_INT( IST_ALLOC_INT_VAL(1) ); break; } } while (--poll_count); @@ -646,17 +946,17 @@ /* oh well, wait until the chip finds memory later */ netif_stop_queue(dev); PRINTK2("%s: TX memory allocation deferred.\n", dev->name); - SMC_ENABLE_INT( IM_ALLOC_INT ); + smc_ENABLE_INT( MSK_ALLOC_INT_VAL(1) ); } else { /* Send current packet immediately.. */ #if THROTTLE_TX_PKTS netif_stop_queue(dev); #endif smc_hardware_send_packet(dev); - SMC_ENABLE_INT( IM_TX_INT | IM_TX_EMPTY_INT ); + smc_ENABLE_INT( MSK_TX_INT_VAL(1) | MSK_TX_EMPTY_INT_VAL(1) ); } - SMC_SELECT_BANK( saved_bank ); + set_BSR_BANK( saved_bank ); return 0; } @@ -667,25 +967,26 @@ static void smc_tx(struct net_device *dev) { - unsigned long ioaddr = dev->base_addr; struct smc_local *lp = (struct smc_local *)dev->priv; unsigned int saved_packet, packet_no, tx_status, pkt_len; PRINTK3("%s: %s\n", dev->name, __FUNCTION__); /* If the TX FIFO is empty then nothing to do */ - packet_no = SMC_GET_TXFIFO(); - if (unlikely(packet_no & TXFIFO_TEMPTY)) { + //packet_no = SMC_GET_TXFIFO(); + packet_no = get_FIFO(); + if (unlikely(mem_get_FIFO_TEMPTY(packet_no) != 0)) { PRINTK("%s: smc_tx with nothing on FIFO.\n", dev->name); return; } + packet_no &= 0xff; /* FIXME, jsun */ /* select packet to read from */ - saved_packet = SMC_GET_PN(); - SMC_SET_PN( packet_no ); + saved_packet = get_PNR(); + set_PNR( packet_no ); /* read the first word (status word) from this packet */ - SMC_SET_PTR( PTR_AUTOINC | PTR_READ ); + set_PTR( PTR_AUTO_INCR_VAL(1) | PTR_READ_VAL(1) ); SMC_GET_PKT_HDR(tx_status, pkt_len); PRINTK2("%s: TX STATUS 0x%04x PNR 0x%02x\n", dev->name, tx_status, packet_no); @@ -702,17 +1003,17 @@ } /* kill the packet */ - SMC_WAIT_MMU_BUSY(); - SMC_SET_MMU_CMD( MC_FREEPKT ); + smc_WAIT_MMU_BUSY(); + set_MMUCR_CMD( MMUCR_RELEASE_PNO); /* Don't restore Packet Number Reg until busy bit is cleared */ - SMC_WAIT_MMU_BUSY(); - SMC_SET_PN( saved_packet ); + smc_WAIT_MMU_BUSY(); + set_PNR( saved_packet ); /* re-enable transmit */ - SMC_SELECT_BANK( 0 ); - SMC_SET_TCR( lp->tcr_cur_mode ); - SMC_SELECT_BANK( 2 ); + set_BSR_BANK( 0 ); + set_TCR( lp->tcr_cur_mode ); + set_BSR_BANK( 2 ); } @@ -824,13 +1125,13 @@ bits[clk_idx++] = 0; // Save the current bank - oldBank = SMC_CURRENT_BANK(); + oldBank = get_BSR_BANK(); // Select bank 3 - SMC_SELECT_BANK( 3 ); + set_BSR_BANK( 3 ); // Get the current MII register value - mii_reg = SMC_GET_MII(); + mii_reg = get_MGMT(); // Turn off all MII Interface bits mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO); @@ -838,22 +1139,22 @@ // Clock all 64 cycles for (i = 0; i < sizeof bits; ++i) { // Clock Low - output data - SMC_SET_MII( mii_reg | bits[i] ); + set_MGMT( mii_reg | bits[i] ); udelay(50); // Clock Hi - input data - SMC_SET_MII( mii_reg | bits[i] | MII_MCLK ); + set_MGMT( mii_reg | bits[i] | MII_MCLK ); udelay(50); - bits[i] |= SMC_GET_MII() & MII_MDI; + bits[i] |= get_MGMT() & MII_MDI; } // Return to idle state // Set clock to low, data to low, and output tristated - SMC_SET_MII( mii_reg ); + set_MGMT( mii_reg ); udelay(50); // Restore original bank select - SMC_SELECT_BANK( oldBank ); + set_BSR_BANK( oldBank ); // Recover input data phydata = 0; @@ -939,13 +1240,13 @@ bits[clk_idx++] = 0; // Save the current bank - oldBank = SMC_CURRENT_BANK(); + oldBank = get_BSR_BANK(); // Select bank 3 - SMC_SELECT_BANK( 3 ); + set_BSR_BANK( 3 ); // Get the current MII register value - mii_reg = SMC_GET_MII(); + mii_reg = get_MGMT(); // Turn off all MII Interface bits mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO); @@ -953,22 +1254,22 @@ // Clock all cycles for (i = 0; i < sizeof bits; ++i) { // Clock Low - output data - SMC_SET_MII( mii_reg | bits[i] ); + set_MGMT( mii_reg | bits[i] ); udelay(50); // Clock Hi - input data - SMC_SET_MII( mii_reg | bits[i] | MII_MCLK ); + set_MGMT( mii_reg | bits[i] | MII_MCLK ); udelay(50); - bits[i] |= SMC_GET_MII() & MII_MDI; + bits[i] |= get_MGMT() & MII_MDI; } // Return to idle state // Set clock to low, data to low, and output tristated - SMC_SET_MII( mii_reg ); + set_MGMT( mii_reg ); udelay(50); // Restore original bank select - SMC_SELECT_BANK( oldBank ); + set_BSR_BANK( oldBank ); PRINTK3("%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", __FUNCTION__, phyaddr, phyreg, phydata); @@ -982,7 +1283,6 @@ static int smc_detect_phy(struct net_device* dev) { struct smc_local *lp = (struct smc_local *)dev->priv; - unsigned long ioaddr = dev->base_addr; int phy_id1, phy_id2; int phyaddr; int found = 0; @@ -992,8 +1292,8 @@ // Scan all 32 PHY addresses if necessary for (phyaddr = 0; phyaddr < 32; ++phyaddr) { // Read the PHY identifiers - phy_id1 = smc_read_phy_register(ioaddr, phyaddr, PHY_ID1_REG); - phy_id2 = smc_read_phy_register(ioaddr, phyaddr, PHY_ID2_REG); + phy_id1 = get_PHY_ID1(); + phy_id2 = get_PHY_ID2(); PRINTK3("%s: phy_id1=0x%x, phy_id2=0x%x\n", dev->name, phy_id1, phy_id2); @@ -1003,7 +1303,7 @@ (phy_id1 > 0x0000) && (phy_id1 < 0xffff)) { if ((phy_id1 != 0x8000) && (phy_id2 != 0x8000)) { // Save the PHY's address - lp->phyaddr = phyaddr; + smc91c111_mii_phyaddr = lp->phyaddr = phyaddr; found = 1; break; } @@ -1052,33 +1352,29 @@ static int smc_phy_fixed(struct net_device *dev) { - unsigned long ioaddr = dev->base_addr; struct smc_local *lp = (struct smc_local *)dev->priv; - int phyaddr = lp->phyaddr; - int my_fixed_caps, cfg1; + int my_fixed_caps; PRINTK3("%s: %s\n", dev->name, __FUNCTION__); // Enter Link Disable state - cfg1 = smc_read_phy_register(ioaddr, phyaddr, PHY_CFG1_REG); - cfg1 |= PHY_CFG1_LNKDIS; - smc_write_phy_register(ioaddr, phyaddr, PHY_CFG1_REG, cfg1); + set_Config1_LNKDIS(1); // Set our fixed capabilities // Disable auto-negotiation my_fixed_caps = 0; if (lp->ctl_rfduplx) - my_fixed_caps |= PHY_CNTL_DPLX; + my_fixed_caps |= Control_DPLX_VAL(1); if (lp->ctl_rspeed == 100) - my_fixed_caps |= PHY_CNTL_SPEED; + my_fixed_caps |= Control_SPEED_VAL(1); // Write our capabilities to the phy control register - smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, my_fixed_caps); + set_Control(my_fixed_caps); // Re-Configure the Receive/Phy Control register - SMC_SET_RPC( lp->rpc_cur_mode ); + set_RPCR( lp->rpc_cur_mode ); // Success return(1); @@ -1092,12 +1388,11 @@ static void smc_phy_configure(struct net_device* dev) { - unsigned long ioaddr = dev->base_addr; struct smc_local *lp = (struct smc_local *)dev->priv; int timeout; int phyaddr; - int my_phy_caps; // My PHY capabilities - int my_ad_caps; // My Advertised capabilities + u_int16_t my_phy_caps; // My PHY capabilities + u_int16_t my_ad_caps; // My Advertised capabilities int status; PRINTK3("%s:smc_program_phy()\n", dev->name); @@ -1113,13 +1408,12 @@ phyaddr = lp->phyaddr; // Reset the PHY, setting all other bits to zero - smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, PHY_CNTL_RST); + set_Control(Control_RST_VAL(1)); // Wait for the reset to complete, or time out timeout = 6; // Wait up to 3 seconds while (timeout--) { - if (!(smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG) - & PHY_CNTL_RST)) + if (! get_Control_RST()) // reset complete break; smc_wait_ms(500); // wait 500 millisecs @@ -1137,21 +1431,19 @@ } // Read PHY Register 18, Status Output - lp->lastPhy18 = smc_read_phy_register(ioaddr, phyaddr, PHY_INT_REG); + lp->lastPhy18 = get_Status_Output(); // Enable PHY Interrupts (for register 18) // Interrupts listed here are disabled - smc_write_phy_register(ioaddr, phyaddr, PHY_MASK_REG, - PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD | - PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB | - PHY_INT_SPDDET | PHY_INT_DPLXDET); - + set_Mask(Mask_MLOSSSYN_VAL(1) | Mask_MCWRD_VAL(1) | Mask_MSSD_VAL(1) | Mask_MESD_VAL(1) | Mask_MRPOL_VAL(1) + | Mask_MJAB_VAL(1) | Mask_MSPDDT_VAL(1) | Mask_MDPLDT_VAL(1)); /* Configure the Receive/Phy Control register */ - SMC_SELECT_BANK( 0 ); - SMC_SET_RPC( lp->rpc_cur_mode ); + set_BSR_BANK( 0 ); + set_RPCR( lp->rpc_cur_mode ); // Copy our capabilities from PHY_STAT_REG to PHY_AD_REG - my_phy_caps = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG); + printk("We are here! _raw_read_CR_EXT_PHY() = %d, _raw_read_BSR_BANK() = %d\n", _raw_read_CR_EXT_PHY(), _raw_read_BSR_BANK()); + my_phy_caps = get_Status(); // If the user requested no auto neg, then go set his request if (!(lp->ctl_autoneg)) { @@ -1159,59 +1451,56 @@ goto smc_phy_configure_exit; } - if( !( my_phy_caps & PHY_STAT_CAP_ANEG)) - { + if(! mem_get_Status_CAP_ANEG(my_phy_caps)) { printk(KERN_INFO "Auto negotiation NOT supported\n"); smc_phy_fixed(dev); goto smc_phy_configure_exit; } - my_ad_caps = PHY_AD_CSMA; // I am CSMA capable + my_ad_caps = ANA_CSMA_VAL(1); // I am CSMA capable - if (my_phy_caps & PHY_STAT_CAP_T4) - my_ad_caps |= PHY_AD_T4; + if (mem_get_Status_CAP_T4(my_phy_caps)) + mem_set_ANA_T4(&my_ad_caps, 1); - if (my_phy_caps & PHY_STAT_CAP_TXF) - my_ad_caps |= PHY_AD_TX_FDX; + if (mem_get_Status_CAP_TXF(my_phy_caps)) + mem_set_ANA_TX_FDX(&my_ad_caps, 1); - if (my_phy_caps & PHY_STAT_CAP_TXH) - my_ad_caps |= PHY_AD_TX_HDX; + if (mem_get_Status_CAP_TXH(my_phy_caps)) + mem_set_ANA_TX_HDX(&my_ad_caps, 1); - if (my_phy_caps & PHY_STAT_CAP_TF) - my_ad_caps |= PHY_AD_10_FDX; + if (mem_get_Status_CAP_TF(my_phy_caps)) + mem_set_ANA_TEN_FDX(&my_ad_caps, 1); - if (my_phy_caps & PHY_STAT_CAP_TH) - my_ad_caps |= PHY_AD_10_HDX; + if (mem_get_Status_CAP_TH(my_phy_caps)) + mem_set_ANA_TEN_HDX(&my_ad_caps, 1); // Disable capabilities not selected by our user if (lp->ctl_rspeed != 100) - my_ad_caps &= ~(PHY_AD_T4|PHY_AD_TX_FDX|PHY_AD_TX_HDX); + my_ad_caps &= ~(ANA_T4_VAL(1)|ANA_TX_FDX_VAL(1)|ANA_TX_HDX_VAL(1)); if (!lp->ctl_rfduplx) - my_ad_caps &= ~(PHY_AD_TX_FDX|PHY_AD_10_FDX); + my_ad_caps &= ~(ANA_TX_FDX_VAL(1)|ANA_TEN_FDX_VAL(1)); // Update our Auto-Neg Advertisement Register - smc_write_phy_register(ioaddr, phyaddr, PHY_AD_REG, my_ad_caps); + set_ANA(my_ad_caps); // Read the register back. Without this, it appears that when // auto-negotiation is restarted, sometimes it isn't ready and // the link does not come up. - status = smc_read_phy_register(ioaddr, phyaddr, PHY_AD_REG); + status = get_ANA(); PRINTK2("%s: phy caps=%x\n", dev->name, my_phy_caps); PRINTK2("%s: phy advertised caps=%x\n", dev->name, my_ad_caps); // Restart auto-negotiation process in order to advertise my caps - smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG, - PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST ); + set_Control(Control_ANEG_EN_VAL(1) | Control_ANEG_RST_VAL(1)); // Wait for the auto-negotiation to complete. This may take from // 2 to 3 seconds. // Wait for the reset to complete, or time out timeout = 20; // Wait up to 10 seconds while (timeout--) { - status = smc_read_phy_register(ioaddr, phyaddr, PHY_RMT_REG); - if (status & PHY_AD_ACK) + if (get_ANREC_ACK()) // auto-negotiate complete break; @@ -1219,8 +1508,8 @@ // otherwise auto-negotiation never completes and we // wait for the entire timeout. There doesn't appear // to be any need to reset the PHY. - status = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG); - if (status & PHY_STAT_ANEG_ACK) /* Since we read it, we might as well check */ + status = get_Status(); + if (mem_get_Status_ANEG_ACK(status)) /* Since we read it, we might as well check */ // auto-negotiate complete break; @@ -1233,19 +1522,19 @@ break; } - if (status & PHY_STAT_REM_FLT) { + if (mem_get_Status_REM_FLT(status)) { PRINTK(KERN_NOTICE "%s: PHY remote fault detected while waiting for auto-negotiate to complete\n", dev->name); - smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG, PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST ); + set_Control(Control_ANEG_EN_VAL(1) | Control_ANEG_RST_VAL(1)); } } - status = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG); + status = get_Status(); if (timeout < 1) { PRINTK(KERN_NOTICE "%s: PHY auto-negotiate timed out\n", dev->name); } // Fail if we detected an auto-negotiate remote fault - if (status & PHY_STAT_REM_FLT) { + if (mem_get_Status_REM_FLT(status)) { PRINTK(KERN_NOTICE "%s: PHY remote fault detected\n", dev->name); } @@ -1254,10 +1543,10 @@ do { udelay(100); - status = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG); - } while ( ((status & PHY_STAT_LINK)==0) && --timeout); + status = get_Status(); + } while ( (mem_get_Status_LINK(status)==0) && --timeout); - if (status & PHY_STAT_LINK) + if (mem_get_Status_LINK(status)) { PRINTK(KERN_NOTICE "%s: Ethernet Link Detected\n", dev->name); } @@ -1265,27 +1554,33 @@ // The smc_phy_interrupt() routine will be called to update lastPhy18 // Set our sysctl parameters to match auto-negotiation results - if ( lp->lastPhy18 & PHY_INT_SPDDET ) { + if (mem_get_Status_Output_SPDDET(lp->lastPhy18)) { PRINTK("%s: PHY 100BaseT\n", dev->name); - lp->rpc_cur_mode |= RPC_SPEED; + // lp->rpc_cur_mode |= RPC_SPEED; + mem_set_RPCR_SPEED(&lp->rpc_cur_mode, 1); } else { PRINTK("%s: PHY 10BaseT\n", dev->name); - lp->rpc_cur_mode &= ~RPC_SPEED; + // lp->rpc_cur_mode &= ~RPC_SPEED; + mem_set_RPCR_SPEED(&lp->rpc_cur_mode, 0); } - if ( lp->lastPhy18 & PHY_INT_DPLXDET ) { + if (mem_get_Status_Output_DPLXDET(lp->lastPhy18)) { PRINTK("%s: PHY Full Duplex\n", dev->name); - lp->rpc_cur_mode |= RPC_DPLX; - lp->tcr_cur_mode |= TCR_SWFDUP; + //lp->rpc_cur_mode |= RPC_DPLX; + mem_set_RPCR_DPLX(&lp->rpc_cur_mode, 1); + //lp->tcr_cur_mode |= TCR_SWFDUP; + mem_set_TCR_SWFDUP(&lp->tcr_cur_mode, 1); } else { PRINTK("%s: PHY Half Duplex\n", dev->name); - lp->rpc_cur_mode &= ~RPC_DPLX; - lp->tcr_cur_mode &= ~TCR_SWFDUP; + // lp->rpc_cur_mode &= ~RPC_DPLX; + mem_set_RPCR_DPLX(&lp->rpc_cur_mode, 0); + // lp->tcr_cur_mode &= ~TCR_SWFDUP; + mem_set_TCR_SWFDUP(&lp->tcr_cur_mode, 0); } // Re-Configure the Receive/Phy Control register and TCR - SMC_SET_RPC( lp->rpc_cur_mode ); - SMC_SET_TCR( lp->tcr_cur_mode ); + set_RPCR( lp->rpc_cur_mode ); + set_TCR( lp->tcr_cur_mode ); smc_phy_configure_exit: // Exit auto-negotiation @@ -1302,16 +1597,14 @@ static void smc_phy_interrupt(struct net_device* dev) { - unsigned long ioaddr = dev->base_addr; struct smc_local *lp = (struct smc_local *)dev->priv; - int phyaddr = lp->phyaddr; int phy18; PRINTK2("%s: %s\n", dev->name, __FUNCTION__); for(;;) { // Read PHY Register 18, Status Output - phy18 = smc_read_phy_register(ioaddr, phyaddr, PHY_INT_REG); + phy18 = get_Status_Output(); // Exit if not more changes if (phy18 == lp->lastPhy18) @@ -1322,46 +1615,41 @@ PRINTK2("%s: lastPhy18=0x%04x\n", dev->name, lp->lastPhy18); // Handle events - if ((phy18 & PHY_INT_LNKFAIL) != - (lp->lastPhy18 & PHY_INT_LNKFAIL)) + if (mem_get_Status_Output_LNKFAIL(phy18) != mem_get_Status_Output_LNKFAIL(lp->lastPhy18)) PRINTK2("%s: PHY Link Fail=%x\n", dev->name, - phy18 & PHY_INT_LNKFAIL); + phy18 & Status_Output_LNKFAIL_VAL(1)); - if ((phy18 & PHY_INT_LOSSSYNC) != - (lp->lastPhy18 & PHY_INT_LOSSSYNC)) + if (mem_get_Status_Output_LOSSSYNC(phy18) != mem_get_Status_Output_LOSSSYNC(lp->lastPhy18)) PRINTK2("%s: PHY LOSS SYNC=%x\n", dev->name, - phy18 & PHY_INT_LOSSSYNC); + phy18 & Status_Output_LOSSSYNC_VAL(1)); - if ((phy18 & PHY_INT_CWRD) != (lp->lastPhy18 & PHY_INT_CWRD)) + if (mem_get_Status_Output_CWRD(phy18) != mem_get_Status_Output_CWRD(lp->lastPhy18)) PRINTK2("%s: PHY INVALID 4B5B code=%x\n", dev->name, - phy18 & PHY_INT_CWRD); + phy18 & Status_Output_CWRD_VAL(1)); - if ((phy18 & PHY_INT_SSD) != (lp->lastPhy18 & PHY_INT_SSD)) + if (mem_get_Status_Output_SSD(phy18) != mem_get_Status_Output_SSD(lp->lastPhy18)) PRINTK2("%s: PHY No Start Of Stream=%x\n", dev->name, - phy18 & PHY_INT_SSD); - - if ((phy18 & PHY_INT_ESD) != (lp->lastPhy18 & PHY_INT_ESD)) + phy18 & Status_Output_SSD_VAL(1)); + if (mem_get_Status_Output_ESD(phy18) != mem_get_Status_Output_ESD(lp->lastPhy18)) PRINTK2("%s: PHY No End Of Stream=%x\n", dev->name, - phy18 & PHY_INT_ESD); + phy18 & Status_Output_ESD_VAL(1)); - if ((phy18 & PHY_INT_RPOL) != (lp->lastPhy18 & PHY_INT_RPOL)) + if (mem_get_Status_Output_RPOL(phy18) != mem_get_Status_Output_RPOL(lp->lastPhy18)) PRINTK2("%s: PHY Reverse Polarity Detected=%x\n", - dev->name, phy18 & PHY_INT_RPOL); + dev->name, phy18 & Status_Output_RPOL_VAL(1)); - if ((phy18 & PHY_INT_JAB) != (lp->lastPhy18 & PHY_INT_JAB)) + if (mem_get_Status_Output_JAB(phy18) != mem_get_Status_Output_JAB(lp->lastPhy18)) PRINTK2("%s: PHY Jabber Detected=%x\n", dev->name, - phy18 & PHY_INT_JAB); + phy18 & Status_Output_JAB_VAL(1)); - if ((phy18 & PHY_INT_SPDDET) != - (lp->lastPhy18 & PHY_INT_SPDDET)) + if (mem_get_Status_Output_SPDDET(phy18) != mem_get_Status_Output_SPDDET(lp->lastPhy18)) PRINTK2("%s: PHY Speed Detect=%x\n", dev->name, - phy18 & PHY_INT_SPDDET); + phy18 & Status_Output_SPDDET_VAL(1)); - if ((phy18 & PHY_INT_DPLXDET) != - (lp->lastPhy18 & PHY_INT_DPLXDET)) + if (mem_get_Status_Output_DPLXDET(phy18) != mem_get_Status_Output_DPLXDET(lp->lastPhy18)) PRINTK2("%s: PHY Duplex Detect=%x\n", dev->name, - phy18 & PHY_INT_DPLXDET); + phy18 & Status_Output_DPLXDET_VAL(1)); #endif // Update the last phy 18 variable lp->lastPhy18 = phy18; @@ -1379,89 +1667,89 @@ smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; - unsigned long ioaddr = dev->base_addr; struct smc_local *lp = (struct smc_local *)dev->priv; - int status, mask, timeout, card_stats; + int status, timeout, card_stats; + unsigned short mask; int saved_bank, saved_pointer; PRINTK3("%s: %s\n", dev->name, __FUNCTION__); - saved_bank = SMC_CURRENT_BANK(); - SMC_SELECT_BANK(2); - saved_pointer = SMC_GET_PTR(); - mask = SMC_GET_INT_MASK(); - SMC_SET_INT_MASK( 0 ); + saved_bank = get_BSR_BANK(); + set_BSR_BANK(2); + saved_pointer = get_PTR(); + mask = get_MSK(); + set_MSK( 0 ); /* set a timeout value, so I don't stay here forever */ timeout = 8; do { - status = SMC_GET_INT(); + status = get_IST(); PRINTK2("%s: IRQ 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n", - dev->name, status, mask, - ({ int meminfo; SMC_SELECT_BANK(0); + dev->name, status, mask>>8, + ({ int meminfo; set_BSR_BANK(0); meminfo = SMC_GET_MIR(); - SMC_SELECT_BANK(2); meminfo; }), - SMC_GET_FIFO()); + set_BSR_BANK(2); meminfo; }), + get_FIFO()); - status &= mask; + status &= mask>>8; /* HACK, jsun */ if (!status) break; - if (status & IM_RCV_INT) { + if (mem_get_IST_RCV_INT(status)) { PRINTK3("%s: RX irq\n", dev->name); smc_rcv(dev); - } else if (status & IM_TX_INT) { + } else if (mem_get_IST_TX_INT(status)) { PRINTK3("%s: TX int\n", dev->name); smc_tx(dev); - SMC_ACK_INT( IM_TX_INT ); + SMC_ACK_INT( ACK_TX_INT_VAL(1) ); #if THROTTLE_TX_PKTS netif_wake_queue(dev); #endif - } else if (status & IM_ALLOC_INT) { + } else if (mem_get_IST_ALLOC_INT(status)) { PRINTK3("%s: Allocation irq\n", dev->name); smc_hardware_send_packet(dev); - mask |= (IM_TX_INT | IM_TX_EMPTY_INT); - mask &= ~IM_ALLOC_INT; + mem_set_MSK_TX_INT(&mask, 1); + mem_set_MSK_TX_EMPTY_INT(&mask, 1); + mem_set_MSK_ALLOC_INT(&mask, 0); #if ! THROTTLE_TX_PKTS netif_wake_queue(dev); #endif - } else if (status & IM_TX_EMPTY_INT) { + } else if (mem_get_IST_TX_EMPTY_INT(status)) { PRINTK3("%s: TX empty\n", dev->name); - mask &= ~IM_TX_EMPTY_INT; + mem_set_MSK_TX_EMPTY_INT(&mask, 0); /* update stats */ - SMC_SELECT_BANK( 0 ); - card_stats = SMC_GET_COUNTER(); - SMC_SELECT_BANK( 2 ); + set_BSR_BANK( 0 ); + card_stats = get_ECR(); + set_BSR_BANK( 2 ); /* single collisions */ - lp->stats.collisions += card_stats & 0xF; - card_stats >>= 4; + lp->stats.collisions += mem_get_ECR_COLN(card_stats); /* multiple collisions */ - lp->stats.collisions += card_stats & 0xF; - } else if (status & IM_RX_OVRN_INT) { + lp->stats.collisions += mem_get_ECR_MCOLN(card_stats); + } else if (mem_get_IST_RX_OVRN_INT(status)) { PRINTK1( "%s: RX overrun\n", dev->name); - SMC_ACK_INT( IM_RX_OVRN_INT ); + SMC_ACK_INT( ACK_RX_OVRN_INT_VAL(1) ); lp->stats.rx_errors++; lp->stats.rx_fifo_errors++; - } else if (status & IM_EPH_INT) { + } else if (mem_get_IST_EPH_INT(status)) { PRINTK("%s: UNSUPPORTED: EPH INTERRUPT\n", dev->name); - } else if (status & IM_MDINT) { - SMC_ACK_INT( IM_MDINT ); + } else if (mem_get_IST_MDINT(status)) { + SMC_ACK_INT( ACK_MDINT_VAL(1) ); smc_phy_interrupt(dev); - } else if (status & IM_ERCV_INT ) { - SMC_ACK_INT( IM_ERCV_INT ); + } else if (mem_get_IST_ERCV_INT(status)) { + SMC_ACK_INT( ACK_ERCV_INT_VAL(1) ); PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT \n", dev->name); } } while (--timeout); /* restore register states */ - SMC_SET_INT_MASK( mask ); - SMC_SET_PTR( saved_pointer ); - SMC_SELECT_BANK( saved_bank ); + set_MSK( mask); + set_PTR( saved_pointer ); + set_BSR_BANK( saved_bank ); PRINTK3("%s: Interrupt done\n", dev->name); } @@ -1582,7 +1870,7 @@ } /* now, the table can be loaded into the chipset */ - SMC_SELECT_BANK( 3 ); + set_BSR_BANK( 3 ); SMC_SET_MCAST( multicast_table ); } @@ -1599,11 +1887,12 @@ PRINTK2("%s: %s\n", dev->name, __FUNCTION__); - SMC_SELECT_BANK(0); + set_BSR_BANK(0); if ( dev->flags & IFF_PROMISC ) { PRINTK2("%s: RCR_PRMS\n", dev->name); - lp->rcr_cur_mode |= RCR_PRMS; - SMC_SET_RCR( lp->rcr_cur_mode ); + // lp->rcr_cur_mode |= RCR_PRMS; + mem_set_RCR_PRMS(&lp->rcr_cur_mode, 1); + set_RCR( lp->rcr_cur_mode ); } /* BUG? I never disable promiscuous mode if multicasting was turned on. @@ -1616,8 +1905,9 @@ checked before the table is */ else if (dev->flags & IFF_ALLMULTI) { - lp->rcr_cur_mode |= RCR_ALMUL; - SMC_SET_RCR( lp->rcr_cur_mode ); + // lp->rcr_cur_mode |= RCR_ALMUL; + mem_set_RCR_ALMUL(&lp->rcr_cur_mode, 1); + set_RCR( lp->rcr_cur_mode ); PRINTK2("%s: RCR_ALMUL\n", dev->name); } @@ -1628,21 +1918,25 @@ /* support hardware multicasting */ /* be sure I get rid of flags I might have set */ - lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL); - SMC_SET_RCR( lp->rcr_cur_mode ); + // lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL); + mem_set_RCR_PRMS(&lp->rcr_cur_mode, 0); + mem_set_RCR_ALMUL(&lp->rcr_cur_mode, 0); + set_RCR( lp->rcr_cur_mode ); /* NOTE: this has to set the bank, so make sure it is the last thing called. The bank is set to zero at the top */ smc_setmulticast( ioaddr, dev->mc_count, dev->mc_list ); } else { PRINTK2("%s: ~(RCR_PRMS|RCR_ALMUL)\n", dev->name); - lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL); - SMC_SET_RCR( lp->rcr_cur_mode ); + // lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL); + mem_set_RCR_PRMS(&lp->rcr_cur_mode, 0); + mem_set_RCR_ALMUL(&lp->rcr_cur_mode, 0); + set_RCR( lp->rcr_cur_mode ); /* since I'm disabling all multicast entirely, I need to clear the multicast list */ - SMC_SELECT_BANK( 3 ); + set_BSR_BANK( 3 ); SMC_CLEAR_MCAST(); } } @@ -1659,7 +1953,6 @@ struct smc_local *lp = (struct smc_local *)dev->priv; unsigned long datacs = lp->datacs; int use_datacs = lp->use_datacs; - unsigned long ioaddr = dev->base_addr; PRINTK2("%s: %s\n", dev->name, __FUNCTION__); @@ -1685,14 +1978,14 @@ lp->ctl_rspeed = 100; #endif - SMC_SELECT_BANK(3); - lp->version = SMC_GET_REV() & 0xff; + set_BSR_BANK(3); + lp->version = get_REV() & 0xff; /* reset the hardware */ smc_reset(dev); smc_enable(dev); - SMC_SELECT_BANK( 1 ); + set_BSR_BANK( 1 ); SMC_SET_MAC_ADDR(dev->dev_addr); /* Configure the PHY */ @@ -1762,23 +2055,24 @@ */ /* enable ALLOCation interrupts ONLY */ - SMC_SELECT_BANK(2); - SMC_SET_INT_MASK( IM_ALLOC_INT ); + set_BSR_BANK(2); + set_MSK( MSK_ALLOC_INT_VAL(1) ); /* . Allocate 512 bytes of memory. Note that the chip was just . reset so all the memory is available */ - SMC_SET_MMU_CMD( MC_ALLOC | 1 ); + set_MMUCR( MMUCR_CMD_VAL(MMUCR_TX_ALLOC) | 1 ); /* . Wait until positive that the interrupt has been generated */ do { - int int_status; + // int int_status; udelay(10); - int_status = SMC_GET_INT(); - if (int_status & IM_ALLOC_INT) + // int_status = get_IST(); + // if (int_status & IM_ALLOC_INT) /* FIXME< jsun */ + if (get_IST_ALLOC_INT()!=0) break; /* got the interrupt */ } while (--timeout); @@ -1788,7 +2082,7 @@ cases. */ /* and disable all interrupts again */ - SMC_SET_INT_MASK( 0 ); + set_MSK( 0 ); /* and return what I found */ return probe_irq_off(cookie); @@ -1846,7 +2140,7 @@ } /* First, see if the high byte is 0x33 */ - val = SMC_CURRENT_BANK(); + val = get_BSR(); PRINTK2("%s: bank signature probe returned 0x%04x\n", CARDNAME, val); if ( (val & 0xFF00) != 0x3300 ) { if ( (val & 0xFF) == 0x33 ) { @@ -1860,8 +2154,8 @@ /* The above MIGHT indicate a device, but I need to write to further test this. */ - SMC_SELECT_BANK(0); - val = SMC_CURRENT_BANK(); + set_BSR_BANK(0); + val = get_BSR(); if ( (val & 0xFF00 ) != 0x3300 ) { retval = -ENODEV; goto err_out; @@ -1870,8 +2164,8 @@ /* well, we've already written once, so hopefully another time won't hurt. This time, I need to switch the bank register to bank 1, so I can access the base address register */ - SMC_SELECT_BANK(1); - val = SMC_GET_BASE(); + set_BSR_BANK(1); + val = get_BAR(); val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT; if ( (ioaddr & ((PAGE_SIZE-1)<> 4) & 0xF]; + printk("%s: revision = 0x%04x\n", CARDNAME, revision_register); + version_string = chip_ids[mem_get_REV_CHIP(revision_register)]; if (!version_string || (revision_register & 0xff00) != 0x3300) { /* I don't recognize this chip, so... */ printk( "%s: IO 0x%lx: Unrecognized revision register 0x%04x" @@ -1897,19 +2192,19 @@ /* At this point I'll assume that the chip is an SMC91x. */ if (version_printed++ == 0) - printk(KERN_INFO "%s", version); + printk("%s", version); /* set the private data to zero by default */ memset(lp, 0, sizeof(struct smc_local)); /* fill in some of the fields */ - dev->base_addr = ioaddr; + smc91c111_mii_ioaddr = dev->base_addr = ioaddr; lp->datacs = datacs; lp->use_datacs = use_datacs; lp->version = revision_register & 0xff; /* Get the MAC address */ - SMC_SELECT_BANK( 1 ); + set_BSR_BANK( 1 ); SMC_GET_MAC_ADDR(dev->dev_addr); /* now, reset the chip, and put it into a known state */ @@ -2012,7 +2307,6 @@ { struct net_device *dev = (struct net_device *)pdev->data; struct smc_local *lp = (struct smc_local *)dev->priv; - unsigned long ioaddr = dev->base_addr; if(!netif_running(dev)) return 0; @@ -2025,7 +2319,7 @@ case PM_RESUME: smc_reset(dev); smc_enable(dev); - SMC_SELECT_BANK( 1 ); + set_BSR_BANK( 1 ); SMC_SET_MAC_ADDR(dev->dev_addr); if (lp->version >= 0x70) smc_phy_configure(dev); @@ -2127,6 +2421,8 @@ ret = -ENXIO; } else { void *ioaddr = ioremap(global_dev->base_addr, SMC_IO_EXTENT); + smc91_base = (unsigned long)ioaddr; + printk("smc91_base = %08lx\n", smc91_base); void *datacs; if ( lp->datacs ) datacs = ioremap(lp->datacs, SMC_DATA_EXTENT); diff -Nru linux-source-2.4.26-vrs1-pxa1-arcom3/drivers/net/smc91x.h.orig linux-source-2.4.26-vrs1-pxa1-arcom3/drivers/net/smc91x.h --- linux-source-2.4.26-vrs1-pxa1-arcom3/drivers/net/smc91x.h.orig 2004-08-11 03:23:18.000000000 -0700 +++ linux-source-2.4.26-vrs1-pxa1-arcom3/drivers/net/smc91x.h 2005-09-12 16:34:23.000000000 -0700 @@ -1,950 +0,0 @@ -/*------------------------------------------------------------------------ - . smc91x.h - macros for SMSC's 91C9x/91C1xx single-chip Ethernet device. - . - . Copyright (C) 1996 by Erik Stahlman - . Copyright (C) 2001 Standard Microsystems Corporation - . Developed by Simple Network Magic Corporation - . Copyright (C) 2003 Monta Vista Software, Inc. - . Unified SMC91x driver by Nicolas Pitre - . - . This program is free software; you can redistribute it and/or modify - . it under the terms of the GNU General Public License as published by - . the Free Software Foundation; either version 2 of the License, or - . (at your option) any later version. - . - . This program is distributed in the hope that it will be useful, - . but WITHOUT ANY WARRANTY; without even the implied warranty of - . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - . GNU General Public License for more details. - . - . You should have received a copy of the GNU General Public License - . along with this program; if not, write to the Free Software - . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - . - . Information contained in this file was obtained from the LAN91C111 - . manual from SMC. To get a copy, if you really want one, you can find - . information under www.smsc.com. - . - . Authors - . Erik Stahlman - . Daris A Nevil - . Nicolas Pitre - . - ---------------------------------------------------------------------------*/ -#ifndef _SMC91X_H_ -#define _SMC91X_H_ - -/* - * Define your architecture specific configuration parameters here. - */ - -#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || \ - defined(CONFIG_SA1100_PFS168) || \ - defined(CONFIG_SA1100_FLEXANET) || \ - defined(CONFIG_SA1100_GRAPHICSMASTER) || \ - defined(CONFIG_ARCH_LUBBOCK) - -/* We can only do 16-bit reads and writes in the static memory space. */ -#define SMC_CAN_USE_8BIT 0 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 0 -#define SMC_NOWAIT 1 - -/* The first two address lines aren't connected... */ -#define SMC_IO_SHIFT 2 - -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_insw(a, r, p, l) insw((a) + (r), p, l) -#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) - -#ifdef CONFIG_ARCH_LUBBOCK -#define SMC_IOADDR LUBBOCK_ETH_PHYS -#endif - -#elif defined(CONFIG_ARCH_VIPER) - -/* We can only do 16-bit reads and writes in the static memory space. */ -#define SMC_CAN_USE_8BIT 0 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 0 -#define SMC_CAN_USE_DATACS 1 -#define SMC_CAN_USE_ISA 0 -#define SMC_NOWAIT 1 - -#define SMC_IO_SHIFT 0 - -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_insw(a, r, p, l) insw((a) + (r), p, l) -#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) - -#ifdef CONFIG_ARCH_VIPER -#include -#define SMC_IOADDR (VIPER_ETH_PHYS + 0x300) -#define SMC_DATACSADDR (VIPER_ETH_DATA_PHYS) -#define SMC_IRQ VIPER_ETH_IRQ -#define RPC_LSA_DEFAULT RPC_LED_100_10 -#define RPC_LSB_DEFAULT RPC_LED_TX_RX -#define SMC_USE_DATACS 0 - -#endif - -#elif defined CONFIG_ARCH_INNOKOM - -#include - -/* We can only do 16-bit reads and writes in the static memory space. */ -#define SMC_CAN_USE_8BIT 0 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 0 -#define SMC_NOWAIT 0 - -/* The first two address lines are connected... */ -#define SMC_IO_SHIFT 0 - -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_insw(a, r, p, l) insw((a) + (r), p, l) -#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) - -#define SMC_IOADDR (INNOKOM_ETH_PHYS + 0x300) -#define SMC_IRQ INNOKOM_ETH_IRQ - -#elif defined(CONFIG_ARCH_MAINSTONE) || \ - defined(CONFIG_ARCH_PXA_IDP) || \ - defined(CONFIG_ARCH_RAMSES) - -#ifdef CONFIG_ARCH_MAINSTONE -#include -#define SMC_IOADDR (MST_ETH_PHYS + 0x300) -#define SMC_IRQ MAINSTONE_IRQ(3) - -#elif CONFIG_ARCH_PXA_IDP -#include -#define SMC_IOADDR (IDP_ETH_PHYS + 0x300) -#define SMC_IRQ ETHERNET_IRQ - -#elif CONFIG_ARCH_RAMSES -#include -#define SMC_IOADDR (RAMSES_ETH_PHYS + 0x300) -#define SMC_IRQ ETHERNET_IRQ -#endif - -#define SMC_CAN_USE_8BIT 1 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 1 -#define SMC_IO_SHIFT 0 -#define SMC_NOWAIT 1 -#define SMC_USE_PXA_DMA 1 - -#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_outl(v, a, r) writel(v, (a) + (r)) -#define SMC_insl(a, r, p, l) insl((a) + (r), p, l) -#define SMC_outsl(a, r, p, l) outsl((a) + (r), p, l) - -/* We actually can't write halfwords properly if not word aligned */ -static inline void -SMC_outw(u16 val, unsigned long ioaddr, int reg) -{ - if (reg & 2) { - unsigned int v = val << 16; - v |= readl(ioaddr + (reg & ~2)) & 0xffff; - writel(v, ioaddr + (reg & ~2)); - } else { - writew(val, ioaddr + reg); - } -} - -#elif defined(CONFIG_ISA) - -#define SMC_CAN_USE_8BIT 1 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 0 - -#define SMC_inb(a, r) inb((a) + (r)) -#define SMC_inw(a, r) inw((a) + (r)) -#define SMC_outb(v, a, r) outb(v, (a) + (r)) -#define SMC_outw(v, a, r) outw(v, (a) + (r)) -#define SMC_insw(a, r, p, l) insw((a) + (r), p, l) -#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) - -#endif - -#ifndef SMC_CAN_USE_ISA -# ifdef CONFIG_ISA -# define SMC_CAN_USE_ISA 1 -# else -# define SMC_CAN_USE_ISA 0 -# endif -#endif - -#ifdef SMC_USE_PXA_DMA -/* - * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is - * always happening in irq context so no need to worry about races. TX is - * different and probably not worth it for that reason, and not as critical - * as RX which can overrun memory and lose packets. - */ -#include -#include - -#ifdef SMC_insl -#undef SMC_insl -#define SMC_insl(a, r, p, l) smc_pxa_dma_insl(a, r, dev->dma, p, l) -static inline void -smc_pxa_dma_insl(u_long ioaddr, int reg, int dma, u_char *buf, int len) -{ - dma_addr_t dmabuf; - - /* fallback if no DMA available */ - if (dma == -1) { - insl(ioaddr + reg, buf, len); - return; - } - - /* 64 bit alignment is required for memory to memory DMA */ - if ((long)buf & 4) { - *((u32 *)buf)++ = SMC_inl(ioaddr, reg); - len--; - } - - len *= 4; - dmabuf = pci_map_single(NULL, buf, len, PCI_DMA_FROMDEVICE); - DCSR(dma) = DCSR_NODESC; - DTADR(dma) = dmabuf; - DSADR(dma) = SMC_IOADDR + reg; - DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | - DCMD_WIDTH4 | (DCMD_LENGTH & len)); - DCSR(dma) = DCSR_NODESC | DCSR_RUN; - while (!(DCSR(dma) & DCSR_STOPSTATE)); - DCSR(dma) = 0; - pci_unmap_single(NULL, dmabuf,len, PCI_DMA_FROMDEVICE); -} -#endif - -#ifdef SMC_insw -#undef SMC_insw -#define SMC_insw(a, r, p, l) smc_pxa_dma_insw(a, r, dev->dma, p, l) -static inline void -smc_pxa_dma_insw(u_long ioaddr, int reg, int dma, u_char *buf, int len) -{ - dma_addr_t dmabuf; - - /* fallback if no DMA available */ - if (dma == -1) { - insw(ioaddr + reg, buf, len); - return; - } - - /* 64 bit alignment is required for memory to memory DMA */ - while ((long)buf & 6) { - *((u16 *)buf)++ = SMC_inw(ioaddr, reg); - len--; - } - - len *= 2; - dmabuf = pci_map_single(NULL, buf, len, PCI_DMA_FROMDEVICE); - DCSR(dma) = DCSR_NODESC; - DTADR(dma) = dmabuf; - DSADR(dma) = SMC_IOADDR + reg; - DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | - DCMD_WIDTH2 | (DCMD_LENGTH & len)); - DCSR(dma) = DCSR_NODESC | DCSR_RUN; - while (!(DCSR(dma) & DCSR_STOPSTATE)); - DCSR(dma) = 0; - pci_unmap_single(NULL, dmabuf,len, PCI_DMA_FROMDEVICE); -} -#endif - -static void -smc_pxa_dma_irq(int dma, void *dummy, struct pt_regs *regs) -{ - DCSR(dma) = 0; -} -#endif /* SMC_USE_PXA_DMA */ - -/* when to use datacs */ -#define SMC_USE_DATACS_RX 1 -#define SMC_USE_DATACS_TX 2 -#define SMC_USE_DATACS_BOTH 3 - -/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */ -#ifndef SMC_IO_SHIFT -#define SMC_IO_SHIFT 0 -#endif -#define SMC_IO_EXTENT (16 << SMC_IO_SHIFT) -#define SMC_DATA_EXTENT 4 - -/* - . Bank Select Register: - . - . yyyy yyyy 0000 00xx - . xx = bank number - . yyyy yyyy = 0x33, for identification purposes. -*/ -#define BANK_SELECT (14 << SMC_IO_SHIFT) - - -// Transmit Control Register -/* BANK 0 */ -#define TCR_REG SMC_REG(0x0000, 0) -#define TCR_ENABLE 0x0001 // When 1 we can transmit -#define TCR_LOOP 0x0002 // Controls output pin LBK -#define TCR_FORCOL 0x0004 // When 1 will force a collision -#define TCR_PAD_EN 0x0080 // When 1 will pad tx frames < 64 bytes w/0 -#define TCR_NOCRC 0x0100 // When 1 will not append CRC to tx frames -#define TCR_MON_CSN 0x0400 // When 1 tx monitors carrier -#define TCR_FDUPLX 0x0800 // When 1 enables full duplex operation -#define TCR_STP_SQET 0x1000 // When 1 stops tx if Signal Quality Error -#define TCR_EPH_LOOP 0x2000 // When 1 enables EPH block loopback -#define TCR_SWFDUP 0x8000 // When 1 enables Switched Full Duplex mode - -#define TCR_CLEAR 0 /* do NOTHING */ -/* the default settings for the TCR register : */ -#define TCR_DEFAULT (TCR_ENABLE | TCR_PAD_EN) - - -// EPH Status Register -/* BANK 0 */ -#define EPH_STATUS_REG SMC_REG(0x0002, 0) -#define ES_TX_SUC 0x0001 // Last TX was successful -#define ES_SNGL_COL 0x0002 // Single collision detected for last tx -#define ES_MUL_COL 0x0004 // Multiple collisions detected for last tx -#define ES_LTX_MULT 0x0008 // Last tx was a multicast -#define ES_16COL 0x0010 // 16 Collisions Reached -#define ES_SQET 0x0020 // Signal Quality Error Test -#define ES_LTXBRD 0x0040 // Last tx was a broadcast -#define ES_TXDEFR 0x0080 // Transmit Deferred -#define ES_LATCOL 0x0200 // Late collision detected on last tx -#define ES_LOSTCARR 0x0400 // Lost Carrier Sense -#define ES_EXC_DEF 0x0800 // Excessive Deferral -#define ES_CTR_ROL 0x1000 // Counter Roll Over indication -#define ES_LINK_OK 0x4000 // Driven by inverted value of nLNK pin -#define ES_TXUNRN 0x8000 // Tx Underrun - - -// Receive Control Register -/* BANK 0 */ -#define RCR_REG SMC_REG(0x0004, 0) -#define RCR_RX_ABORT 0x0001 // Set if a rx frame was aborted -#define RCR_PRMS 0x0002 // Enable promiscuous mode -#define RCR_ALMUL 0x0004 // When set accepts all multicast frames -#define RCR_RXEN 0x0100 // IFF this is set, we can receive packets -#define RCR_STRIP_CRC 0x0200 // When set strips CRC from rx packets -#define RCR_ABORT_ENB 0x0200 // When set will abort rx on collision -#define RCR_FILT_CAR 0x0400 // When set filters leading 12 bit s of carrier -#define RCR_SOFTRST 0x8000 // resets the chip - -/* the normal settings for the RCR register : */ -#define RCR_DEFAULT (RCR_STRIP_CRC | RCR_RXEN) -#define RCR_CLEAR 0x0 // set it to a base state - - -// Counter Register -/* BANK 0 */ -#define COUNTER_REG SMC_REG(0x0006, 0) - - -// Memory Information Register -/* BANK 0 */ -#define MIR_REG SMC_REG(0x0008, 0) - - -// Receive/Phy Control Register -/* BANK 0 */ -#define RPC_REG SMC_REG(0x000A, 0) -#define RPC_SPEED 0x2000 // When 1 PHY is in 100Mbps mode. -#define RPC_DPLX 0x1000 // When 1 PHY is in Full-Duplex Mode -#define RPC_ANEG 0x0800 // When 1 PHY is in Auto-Negotiate Mode -#define RPC_LSXA_SHFT 5 // Bits to shift LS2A,LS1A,LS0A to lsb -#define RPC_LSXB_SHFT 2 // Bits to get LS2B,LS1B,LS0B to lsb -#define RPC_LED_100_10 (0x00) // LED = 100Mbps OR's with 10Mbps link detect -#define RPC_LED_RES (0x01) // LED = Reserved -#define RPC_LED_10 (0x02) // LED = 10Mbps link detect -#define RPC_LED_FD (0x03) // LED = Full Duplex Mode -#define RPC_LED_TX_RX (0x04) // LED = TX or RX packet occurred -#define RPC_LED_100 (0x05) // LED = 100Mbps link dectect -#define RPC_LED_TX (0x06) // LED = TX packet occurred -#define RPC_LED_RX (0x07) // LED = RX packet occurred - -#ifndef RPC_LSA_DEFAULT -#define RPC_LSA_DEFAULT RPC_LED_100 -#endif -#ifndef RPC_LSB_DEFAULT -#define RPC_LSB_DEFAULT RPC_LED_FD -#endif - -#define RPC_DEFAULT (RPC_ANEG | (RPC_LSA_DEFAULT << RPC_LSXA_SHFT) | (RPC_LSB_DEFAULT << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX) - - -/* Bank 0 0x0C is reserved */ - -// Bank Select Register -/* All Banks */ -#define BSR_REG 0x000E - - -// Configuration Reg -/* BANK 1 */ -#define CONFIG_REG SMC_REG(0x0000, 1) -#define CONFIG_EXT_PHY 0x0200 // 1=external MII, 0=internal Phy -#define CONFIG_GPCNTRL 0x0400 // Inverse value drives pin nCNTRL -#define CONFIG_NO_WAIT 0x1000 // When 1 no extra wait states on ISA bus -#define CONFIG_EPH_POWER_EN 0x8000 // When 0 EPH is placed into low power mode. - -// Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low -#define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN) - - -// Base Address Register -/* BANK 1 */ -#define BASE_REG SMC_REG(0x0002, 1) - - -// Individual Address Registers -/* BANK 1 */ -#define ADDR0_REG SMC_REG(0x0004, 1) -#define ADDR1_REG SMC_REG(0x0006, 1) -#define ADDR2_REG SMC_REG(0x0008, 1) - - -// General Purpose Register -/* BANK 1 */ -#define GP_REG SMC_REG(0x000A, 1) - - -// Control Register -/* BANK 1 */ -#define CTL_REG SMC_REG(0x000C, 1) -#define CTL_RCV_BAD 0x4000 // When 1 bad CRC packets are received -#define CTL_AUTO_RELEASE 0x0800 // When 1 tx pages are released automatically -#define CTL_LE_ENABLE 0x0080 // When 1 enables Link Error interrupt -#define CTL_CR_ENABLE 0x0040 // When 1 enables Counter Rollover interrupt -#define CTL_TE_ENABLE 0x0020 // When 1 enables Transmit Error interrupt -#define CTL_EEPROM_SELECT 0x0004 // Controls EEPROM reload & store -#define CTL_RELOAD 0x0002 // When set reads EEPROM into registers -#define CTL_STORE 0x0001 // When set stores registers into EEPROM - - -// MMU Command Register -/* BANK 2 */ -#define MMU_CMD_REG SMC_REG(0x0000, 2) -#define MC_BUSY 1 // When 1 the last release has not completed -#define MC_NOP (0<<5) // No Op -#define MC_ALLOC (1<<5) // OR with number of 256 byte packets -#define MC_RESET (2<<5) // Reset MMU to initial state -#define MC_REMOVE (3<<5) // Remove the current rx packet -#define MC_RELEASE (4<<5) // Remove and release the current rx packet -#define MC_FREEPKT (5<<5) // Release packet in PNR register -#define MC_ENQUEUE (6<<5) // Enqueue the packet for transmit -#define MC_RSTTXFIFO (7<<5) // Reset the TX FIFOs - - -// Packet Number Register -/* BANK 2 */ -#define PN_REG SMC_REG(0x0002, 2) - - -// Allocation Result Register -/* BANK 2 */ -#define AR_REG SMC_REG(0x0003, 2) -#define AR_FAILED 0x80 // Alocation Failed - - -// TX FIFO Ports Register -/* BANK 2 */ -#define TXFIFO_REG SMC_REG(0x0004, 2) -#define TXFIFO_TEMPTY 0x80 // TX FIFO Empty - -// RX FIFO Ports Register -/* BANK 2 */ -#define RXFIFO_REG SMC_REG(0x0005, 2) -#define RXFIFO_REMPTY 0x80 // RX FIFO Empty - -#define FIFO_REG SMC_REG(0x0004, 2) - -// Pointer Register -/* BANK 2 */ -#define PTR_REG SMC_REG(0x0006, 2) -#define PTR_RCV 0x8000 // 1=Receive area, 0=Transmit area -#define PTR_AUTOINC 0x4000 // Auto increment the pointer on each access -#define PTR_READ 0x2000 // When 1 the operation is a read - -#define FIFO_REG SMC_REG(0x0004, 2) - -// Data Register -/* BANK 2 */ -#define DATA_REG SMC_REG(0x0008, 2) - - -// Interrupt Status/Acknowledge Register -/* BANK 2 */ -#define INT_REG SMC_REG(0x000C, 2) - - -// Interrupt Mask Register -/* BANK 2 */ -#define IM_REG SMC_REG(0x000D, 2) -#define IM_MDINT 0x80 // PHY MI Register 18 Interrupt -#define IM_ERCV_INT 0x40 // Early Receive Interrupt -#define IM_EPH_INT 0x20 // Set by Ethernet Protocol Handler section -#define IM_RX_OVRN_INT 0x10 // Set by Receiver Overruns -#define IM_ALLOC_INT 0x08 // Set when allocation request is completed -#define IM_TX_EMPTY_INT 0x04 // Set if the TX FIFO goes empty -#define IM_TX_INT 0x02 // Transmit Interrupt -#define IM_RCV_INT 0x01 // Receive Interrupt - - -// Multicast Table Registers -/* BANK 3 */ -#define MCAST_REG1 SMC_REG(0x0000, 3) -#define MCAST_REG2 SMC_REG(0x0002, 3) -#define MCAST_REG3 SMC_REG(0x0004, 3) -#define MCAST_REG4 SMC_REG(0x0006, 3) - - -// Management Interface Register (MII) -/* BANK 3 */ -#define MII_REG SMC_REG(0x0008, 3) -#define MII_MSK_CRS100 0x4000 // Disables CRS100 detection during tx half dup -#define MII_MDOE 0x0008 // MII Output Enable -#define MII_MCLK 0x0004 // MII Clock, pin MDCLK -#define MII_MDI 0x0002 // MII Input, pin MDI -#define MII_MDO 0x0001 // MII Output, pin MDO - - -// Revision Register -/* BANK 3 */ -/* ( hi: chip id low: rev # ) */ -#define REV_REG SMC_REG(0x000A, 3) - - -// Early RCV Register -/* BANK 3 */ -/* this is NOT on SMC9192 */ -#define ERCV_REG SMC_REG(0x000C, 3) -#define ERCV_RCV_DISCRD 0x0080 // When 1 discards a packet being received -#define ERCV_THRESHOLD 0x001F // ERCV Threshold Mask - - -// External Register -/* BANK 7 */ -#define EXT_REG SMC_REG(0x0000, 7) - - -#define CHIP_9192 3 -#define CHIP_9194 4 -#define CHIP_9195 5 -#define CHIP_9196 6 -#define CHIP_91100 7 -#define CHIP_91100FD 8 -#define CHIP_91111FD 9 - -static const char * chip_ids[ 16 ] = { - NULL, NULL, NULL, - /* 3 */ "SMC91C90/91C92", - /* 4 */ "SMC91C94", - /* 5 */ "SMC91C95", - /* 6 */ "SMC91C96", - /* 7 */ "SMC91C100", - /* 8 */ "SMC91C100FD", - /* 9 */ "SMC91C11xFD", - NULL, NULL, NULL, - NULL, NULL, NULL}; - - -/* - . Transmit status bits -*/ -#define TS_SUCCESS 0x0001 -#define TS_LOSTCAR 0x0400 -#define TS_LATCOL 0x0200 -#define TS_16COL 0x0010 - -/* - . Receive status bits -*/ -#define RS_ALGNERR 0x8000 -#define RS_BRODCAST 0x4000 -#define RS_BADCRC 0x2000 -#define RS_ODDFRAME 0x1000 -#define RS_TOOLONG 0x0800 -#define RS_TOOSHORT 0x0400 -#define RS_MULTICAST 0x0001 -#define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) - - -// PHY Types -enum { - PHY_LAN83C183 = 1, // LAN91C111 Internal PHY - PHY_LAN83C180 -}; - - -// PHY Register Addresses (LAN91C111 Internal PHY) - -// PHY Control Register -#define PHY_CNTL_REG 0x00 -#define PHY_CNTL_RST 0x8000 // 1=PHY Reset -#define PHY_CNTL_LPBK 0x4000 // 1=PHY Loopback -#define PHY_CNTL_SPEED 0x2000 // 1=100Mbps, 0=10Mpbs -#define PHY_CNTL_ANEG_EN 0x1000 // 1=Enable Auto negotiation -#define PHY_CNTL_PDN 0x0800 // 1=PHY Power Down mode -#define PHY_CNTL_MII_DIS 0x0400 // 1=MII 4 bit interface disabled -#define PHY_CNTL_ANEG_RST 0x0200 // 1=Reset Auto negotiate -#define PHY_CNTL_DPLX 0x0100 // 1=Full Duplex, 0=Half Duplex -#define PHY_CNTL_COLTST 0x0080 // 1= MII Colision Test - -// PHY Status Register -#define PHY_STAT_REG 0x01 -#define PHY_STAT_CAP_T4 0x8000 // 1=100Base-T4 capable -#define PHY_STAT_CAP_TXF 0x4000 // 1=100Base-X full duplex capable -#define PHY_STAT_CAP_TXH 0x2000 // 1=100Base-X half duplex capable -#define PHY_STAT_CAP_TF 0x1000 // 1=10Mbps full duplex capable -#define PHY_STAT_CAP_TH 0x0800 // 1=10Mbps half duplex capable -#define PHY_STAT_CAP_SUPR 0x0040 // 1=recv mgmt frames with not preamble -#define PHY_STAT_ANEG_ACK 0x0020 // 1=ANEG has completed -#define PHY_STAT_REM_FLT 0x0010 // 1=Remote Fault detected -#define PHY_STAT_CAP_ANEG 0x0008 // 1=Auto negotiate capable -#define PHY_STAT_LINK 0x0004 // 1=valid link -#define PHY_STAT_JAB 0x0002 // 1=10Mbps jabber condition -#define PHY_STAT_EXREG 0x0001 // 1=extended registers implemented - -// PHY Identifier Registers -#define PHY_ID1_REG 0x02 // PHY Identifier 1 -#define PHY_ID2_REG 0x03 // PHY Identifier 2 - -// PHY Auto-Negotiation Advertisement Register -#define PHY_AD_REG 0x04 -#define PHY_AD_NP 0x8000 // 1=PHY requests exchange of Next Page -#define PHY_AD_ACK 0x4000 // 1=got link code word from remote -#define PHY_AD_RF 0x2000 // 1=advertise remote fault -#define PHY_AD_T4 0x0200 // 1=PHY is capable of 100Base-T4 -#define PHY_AD_TX_FDX 0x0100 // 1=PHY is capable of 100Base-TX FDPLX -#define PHY_AD_TX_HDX 0x0080 // 1=PHY is capable of 100Base-TX HDPLX -#define PHY_AD_10_FDX 0x0040 // 1=PHY is capable of 10Base-T FDPLX -#define PHY_AD_10_HDX 0x0020 // 1=PHY is capable of 10Base-T HDPLX -#define PHY_AD_CSMA 0x0001 // 1=PHY is capable of 802.3 CMSA - -// PHY Auto-negotiation Remote End Capability Register -#define PHY_RMT_REG 0x05 -// Uses same bit definitions as PHY_AD_REG - -// PHY Configuration Register 1 -#define PHY_CFG1_REG 0x10 -#define PHY_CFG1_LNKDIS 0x8000 // 1=Rx Link Detect Function disabled -#define PHY_CFG1_XMTDIS 0x4000 // 1=TP Transmitter Disabled -#define PHY_CFG1_XMTPDN 0x2000 // 1=TP Transmitter Powered Down -#define PHY_CFG1_BYPSCR 0x0400 // 1=Bypass scrambler/descrambler -#define PHY_CFG1_UNSCDS 0x0200 // 1=Unscramble Idle Reception Disable -#define PHY_CFG1_EQLZR 0x0100 // 1=Rx Equalizer Disabled -#define PHY_CFG1_CABLE 0x0080 // 1=STP(150ohm), 0=UTP(100ohm) -#define PHY_CFG1_RLVL0 0x0040 // 1=Rx Squelch level reduced by 4.5db -#define PHY_CFG1_TLVL_SHIFT 2 // Transmit Output Level Adjust -#define PHY_CFG1_TLVL_MASK 0x003C -#define PHY_CFG1_TRF_MASK 0x0003 // Transmitter Rise/Fall time - - -// PHY Configuration Register 2 -#define PHY_CFG2_REG 0x11 -#define PHY_CFG2_APOLDIS 0x0020 // 1=Auto Polarity Correction disabled -#define PHY_CFG2_JABDIS 0x0010 // 1=Jabber disabled -#define PHY_CFG2_MREG 0x0008 // 1=Multiple register access (MII mgt) -#define PHY_CFG2_INTMDIO 0x0004 // 1=Interrupt signaled with MDIO pulseo - -// PHY Status Output (and Interrupt status) Register -#define PHY_INT_REG 0x12 // Status Output (Interrupt Status) -#define PHY_INT_INT 0x8000 // 1=bits have changed since last read -#define PHY_INT_LNKFAIL 0x4000 // 1=Link Not detected -#define PHY_INT_LOSSSYNC 0x2000 // 1=Descrambler has lost sync -#define PHY_INT_CWRD 0x1000 // 1=Invalid 4B5B code detected on rx -#define PHY_INT_SSD 0x0800 // 1=No Start Of Stream detected on rx -#define PHY_INT_ESD 0x0400 // 1=No End Of Stream detected on rx -#define PHY_INT_RPOL 0x0200 // 1=Reverse Polarity detected -#define PHY_INT_JAB 0x0100 // 1=Jabber detected -#define PHY_INT_SPDDET 0x0080 // 1=100Base-TX mode, 0=10Base-T mode -#define PHY_INT_DPLXDET 0x0040 // 1=Device in Full Duplex - -// PHY Interrupt/Status Mask Register -#define PHY_MASK_REG 0x13 // Interrupt Mask -// Uses the same bit definitions as PHY_INT_REG - - -/* - * SMC91C96 ethernet config and status registers. - * These are in the "attribute" space. - */ -#define ECOR 0x8000 -#define ECOR_RESET 0x80 -#define ECOR_LEVEL_IRQ 0x40 -#define ECOR_WR_ATTRIB 0x04 -#define ECOR_ENABLE 0x01 - -#define ECSR 0x8002 -#define ECSR_IOIS8 0x20 -#define ECSR_PWRDWN 0x04 -#define ECSR_INT 0x02 - - -/* - * Macros to abstract register access according to the data bus - * capabilities. Please try to use those and not the in/out primitives. - * Note: the following macros do *not* select the bank -- this must - * be done separately as needed in the main code. The SMC_REG() macro - * only uses the bank argument for debugging purposes. - */ - -#if SMC_DEBUG > 0 -#define SMC_REG(reg, bank) \ - ({ \ - int __b = SMC_CURRENT_BANK(); \ - if ((__b & ~0xf0) != (0x3300 | bank)) { \ - printk( "%s: bank reg screwed (0x%04x)\n", \ - CARDNAME, __b ); \ - BUG(); \ - } \ - reg<> 8) -#define SMC_GET_TXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) & 0xFF) -#define SMC_GET_RXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) >> 8) -#define SMC_GET_INT() (SMC_inw( ioaddr, INT_REG ) & 0xFF) -#define SMC_ACK_INT(x) \ - do { \ - unsigned long __flags; \ - int __mask; \ - local_irq_save(__flags); \ - __mask = SMC_inw( ioaddr, INT_REG ) & ~0xff; \ - SMC_outw( __mask | (x), ioaddr, INT_REG ); \ - local_irq_restore(__flags); \ - } while (0) -#define SMC_GET_INT_MASK() (SMC_inw( ioaddr, INT_REG ) >> 8) -#define SMC_SET_INT_MASK(x) SMC_outw( (x) << 8, ioaddr, INT_REG ) -#endif - -#define SMC_CURRENT_BANK() SMC_inw( ioaddr, BANK_SELECT ) -#define SMC_SELECT_BANK(x) SMC_outw( x, ioaddr, BANK_SELECT ) -#define SMC_GET_BASE() SMC_inw( ioaddr, BASE_REG ) -#define SMC_SET_BASE(x) SMC_outw( x, ioaddr, BASE_REG ) -#define SMC_GET_CONFIG() SMC_inw( ioaddr, CONFIG_REG ) -#define SMC_SET_CONFIG(x) SMC_outw( x, ioaddr, CONFIG_REG ) -#define SMC_GET_COUNTER() SMC_inw( ioaddr, COUNTER_REG ) -#define SMC_GET_CTL() SMC_inw( ioaddr, CTL_REG ) -#define SMC_SET_CTL(x) SMC_outw( x, ioaddr, CTL_REG ) -#define SMC_GET_MII() SMC_inw( ioaddr, MII_REG ) -#define SMC_SET_MII(x) SMC_outw( x, ioaddr, MII_REG ) -#define SMC_GET_MIR() SMC_inw( ioaddr, MIR_REG ) -#define SMC_SET_MIR(x) SMC_outw( x, ioaddr, MIR_REG ) -#define SMC_GET_MMU_CMD() SMC_inw( ioaddr, MMU_CMD_REG ) -#define SMC_SET_MMU_CMD(x) SMC_outw( x, ioaddr, MMU_CMD_REG ) -#define SMC_GET_FIFO() SMC_inw( ioaddr, FIFO_REG ) -#define SMC_GET_PTR() SMC_inw( ioaddr, PTR_REG ) -#define SMC_SET_PTR(x) SMC_outw( x, ioaddr, PTR_REG ) -#define SMC_GET_EPH_STATUS() SMC_inw( ioaddr, EPH_STATUS_REG ) -#define SMC_SET_EPH_STATUS(x) SMC_outw( x, ioaddr, EPH_STATUS_REG ) -#define SMC_GET_RCR() SMC_inw( ioaddr, RCR_REG ) -#define SMC_SET_RCR(x) SMC_outw( x, ioaddr, RCR_REG ) -#define SMC_GET_REV() SMC_inw( ioaddr, REV_REG ) -#define SMC_GET_RPC() SMC_inw( ioaddr, RPC_REG ) -#define SMC_SET_RPC(x) SMC_outw( x, ioaddr, RPC_REG ) -#define SMC_GET_TCR() SMC_inw( ioaddr, TCR_REG ) -#define SMC_SET_TCR(x) SMC_outw( x, ioaddr, TCR_REG ) - -#ifndef SMC_GET_MAC_ADDR -#define SMC_GET_MAC_ADDR(addr) \ - do { \ - unsigned int __v; \ - __v = SMC_inw( ioaddr, ADDR0_REG ); \ - addr[0] = __v; addr[1] = __v >> 8; \ - __v = SMC_inw( ioaddr, ADDR1_REG ); \ - addr[2] = __v; addr[3] = __v >> 8; \ - __v = SMC_inw( ioaddr, ADDR2_REG ); \ - addr[4] = __v; addr[5] = __v >> 8; \ - } while (0) -#endif - -#define SMC_SET_MAC_ADDR(addr) \ - do { \ - SMC_outw( addr[0]|(addr[1] << 8), ioaddr, ADDR0_REG ); \ - SMC_outw( addr[2]|(addr[3] << 8), ioaddr, ADDR1_REG ); \ - SMC_outw( addr[4]|(addr[5] << 8), ioaddr, ADDR2_REG ); \ - } while (0) - -#define SMC_CLEAR_MCAST() \ - do { \ - SMC_outw( 0, ioaddr, MCAST_REG1 ); \ - SMC_outw( 0, ioaddr, MCAST_REG2 ); \ - SMC_outw( 0, ioaddr, MCAST_REG3 ); \ - SMC_outw( 0, ioaddr, MCAST_REG4 ); \ - } while (0) -#define SMC_SET_MCAST(x) \ - do { \ - unsigned char *mt = (x); \ - SMC_outw( mt[0] | (mt[1] << 8), ioaddr, MCAST_REG1 ); \ - SMC_outw( mt[2] | (mt[3] << 8), ioaddr, MCAST_REG2 ); \ - SMC_outw( mt[4] | (mt[5] << 8), ioaddr, MCAST_REG3 ); \ - SMC_outw( mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4 ); \ - } while (0) - -#if SMC_CAN_USE_32BIT -/* - * Some setups just can't write 8 or 16 bits reliably when not aligned - * to a 32 bit boundary. I tell you that exists! - * We do the ones that can have their low parts written to 0 here. - */ -#undef SMC_SELECT_BANK -#define SMC_SELECT_BANK(x) SMC_outl( (x)<<16, ioaddr, 12<> 16; \ - } while (0) -#else -#define SMC_PUT_PKT_HDR(status, length) \ - do { \ - SMC_outw( status, ioaddr, DATA_REG ); \ - SMC_outw( length, ioaddr, DATA_REG ); \ - } while (0) -#define SMC_GET_PKT_HDR(status, length) \ - do { \ - (status) = SMC_inw( ioaddr, DATA_REG ); \ - (length) = SMC_inw( ioaddr, DATA_REG ); \ - } while (0) -#endif - -#if SMC_CAN_USE_32BIT -#define _SMC_PUSH_DATA(p, l) \ - do { \ - char *__ptr = (p); \ - int __len = (l); \ - if (__len >= 2 && (long)__ptr & 2) { \ - __len -= 2; \ - SMC_outw( *((u16 *)__ptr)++, ioaddr, DATA_REG );\ - } \ - SMC_outsl( ioaddr, DATA_REG, __ptr, __len >> 2); \ - if (__len & 2) { \ - __ptr += (__len & ~3); \ - SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \ - } \ - } while (0) -#define _SMC_PULL_DATA(p, l) \ - do { \ - char *__ptr = (p); \ - int __len = (l); \ - if ((long)__ptr & 2) { \ - /* \ - * We want 32bit alignment here. \ - * Since some buses perform a full 32bit \ - * fetch even for 16bit data we can't use \ - * SMC_inw() here. Back both source (on chip \ - * and destination) pointers of 2 bytes. \ - */ \ - (long)__ptr &= ~2; \ - __len += 2; \ - SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \ - } \ - __len += 2; \ - SMC_insl( ioaddr, DATA_REG, __ptr, __len >> 2); \ - } while (0) -#elif SMC_CAN_USE_16BIT -#define _SMC_PUSH_DATA(p, l) SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 ) -#define _SMC_PULL_DATA(p, l) SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 ) -#elif SMC_CAN_USE_8BIT -#define _SMC_PUSH_DATA(p, l) SMC_outsb( ioaddr, DATA_REG, p, l ) -#define _SMC_PULL_DATA(p, l) SMC_insb ( ioaddr, DATA_REG, p, l ) -#endif - -#if ! SMC_CAN_USE_16BIT -#define SMC_outw(x, ioaddr, reg) \ - do { \ - unsigned int __val16 = (x); \ - SMC_outb( __val16, ioaddr, reg ); \ - SMC_outb( __val16 >> 8, ioaddr, reg + 1 ); \ - } while (0) -#define SMC_inw(ioaddr, reg) \ - ({ \ - unsigned int __val16; \ - __val16 = SMC_inb( ioaddr, reg ); \ - __val16 |= SMC_inb( ioaddr, reg + 1 ) << 8; \ - __val16; \ - }) -#endif - -#if SMC_CAN_USE_DATACS -#define SMC_PUSH_DATA(p, l) \ - if ( lp->datacs && ( lp->use_datacs & SMC_USE_DATACS_TX ) ) { \ - char *__ptr = (p); \ - int __len = (l); \ - if (__len >= 2 && (long)__ptr & 2) { \ - __len -= 2; \ - SMC_outw( *((u16 *)__ptr)++, ioaddr, DATA_REG );\ - } \ - outsl(lp->datacs, __ptr, __len >> 2); \ - if (__len & 2) { \ - __ptr += (__len & ~3); \ - SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \ - } \ - } else { \ - _SMC_PUSH_DATA(p, l); \ - } - -#define SMC_PULL_DATA(p, l) \ - if ( lp->datacs && ( lp->use_datacs & SMC_USE_DATACS_RX ) ) { \ - char *__ptr = (p); \ - int __len = (l); \ - if ((long)__ptr & 2) { \ - /* \ - * We want 32bit alignment here. \ - * Since some buses perform a full 32bit \ - * fetch even for 16bit data we can't use \ - * SMC_inw() here. Back both source (on chip \ - * and destination) pointers of 2 bytes. \ - */ \ - (long)__ptr &= ~2; \ - __len += 2; \ - SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \ - } \ - __len += 2; \ - insl( lp->datacs, __ptr, __len >> 2); \ - } else { \ - _SMC_PULL_DATA(p, l); \ - } -#else -#define SMC_PUSH_DATA(p, l) _SMC_PUSH_DATA(p, l) -#define SMC_PULL_DATA(p, l) _SMC_PULL_DATA(p, l) -#endif - -#endif /* _SMC91X_H_ */