diff options
Diffstat (limited to 'drivers/net/smc91x.c')
-rw-r--r-- | drivers/net/smc91x.c | 337 |
1 files changed, 182 insertions, 155 deletions
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 63a54e29d56..a188e33484e 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -132,6 +132,7 @@ module_param(watchdog, int, 0400); MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:smc91x"); /* * The internal workings of the driver. If you are changing anything @@ -220,22 +221,22 @@ static void PRINT_PKT(u_char *buf, int length) /* this enables an interrupt in the interrupt mask register */ -#define SMC_ENABLE_INT(x) do { \ +#define SMC_ENABLE_INT(lp, x) do { \ unsigned char mask; \ spin_lock_irq(&lp->lock); \ - mask = SMC_GET_INT_MASK(); \ + mask = SMC_GET_INT_MASK(lp); \ mask |= (x); \ - SMC_SET_INT_MASK(mask); \ + SMC_SET_INT_MASK(lp, mask); \ spin_unlock_irq(&lp->lock); \ } while (0) /* this disables an interrupt from the interrupt mask register */ -#define SMC_DISABLE_INT(x) do { \ +#define SMC_DISABLE_INT(lp, x) do { \ unsigned char mask; \ spin_lock_irq(&lp->lock); \ - mask = SMC_GET_INT_MASK(); \ + mask = SMC_GET_INT_MASK(lp); \ mask &= ~(x); \ - SMC_SET_INT_MASK(mask); \ + SMC_SET_INT_MASK(lp, mask); \ spin_unlock_irq(&lp->lock); \ } while (0) @@ -244,10 +245,10 @@ static void PRINT_PKT(u_char *buf, int length) * if at all, but let's avoid deadlocking the system if the hardware * decides to go south. */ -#define SMC_WAIT_MMU_BUSY() do { \ - if (unlikely(SMC_GET_MMU_CMD() & MC_BUSY)) { \ +#define SMC_WAIT_MMU_BUSY(lp) do { \ + if (unlikely(SMC_GET_MMU_CMD(lp) & MC_BUSY)) { \ unsigned long timeout = jiffies + 2; \ - while (SMC_GET_MMU_CMD() & MC_BUSY) { \ + while (SMC_GET_MMU_CMD(lp) & MC_BUSY) { \ if (time_after(jiffies, timeout)) { \ printk("%s: timeout %s line %d\n", \ dev->name, __FILE__, __LINE__); \ @@ -273,8 +274,8 @@ static void smc_reset(struct net_device *dev) /* Disable all interrupts, block TX tasklet */ spin_lock_irq(&lp->lock); - SMC_SELECT_BANK(2); - SMC_SET_INT_MASK(0); + SMC_SELECT_BANK(lp, 2); + SMC_SET_INT_MASK(lp, 0); pending_skb = lp->pending_tx_skb; lp->pending_tx_skb = NULL; spin_unlock_irq(&lp->lock); @@ -290,15 +291,15 @@ static void smc_reset(struct net_device *dev) * This resets the registers mostly to defaults, but doesn't * affect EEPROM. That seems unnecessary */ - SMC_SELECT_BANK(0); - SMC_SET_RCR(RCR_SOFTRST); + SMC_SELECT_BANK(lp, 0); + SMC_SET_RCR(lp, RCR_SOFTRST); /* * Setup the Configuration Register * This is necessary because the CONFIG_REG is not affected * by a soft reset */ - SMC_SELECT_BANK(1); + SMC_SELECT_BANK(lp, 1); cfg = CONFIG_DEFAULT; @@ -316,7 +317,7 @@ static void smc_reset(struct net_device *dev) */ cfg |= CONFIG_EPH_POWER_EN; - SMC_SET_CONFIG(cfg); + SMC_SET_CONFIG(lp, cfg); /* this should pause enough for the chip to be happy */ /* @@ -329,12 +330,12 @@ static void smc_reset(struct net_device *dev) udelay(1); /* Disable transmit and receive functionality */ - SMC_SELECT_BANK(0); - SMC_SET_RCR(RCR_CLEAR); - SMC_SET_TCR(TCR_CLEAR); + SMC_SELECT_BANK(lp, 0); + SMC_SET_RCR(lp, RCR_CLEAR); + SMC_SET_TCR(lp, TCR_CLEAR); - SMC_SELECT_BANK(1); - ctl = SMC_GET_CTL() | CTL_LE_ENABLE; + SMC_SELECT_BANK(lp, 1); + ctl = SMC_GET_CTL(lp) | CTL_LE_ENABLE; /* * Set the control register to automatically release successfully @@ -345,12 +346,12 @@ static void smc_reset(struct net_device *dev) ctl |= CTL_AUTO_RELEASE; else ctl &= ~CTL_AUTO_RELEASE; - SMC_SET_CTL(ctl); + SMC_SET_CTL(lp, ctl); /* Reset the MMU */ - SMC_SELECT_BANK(2); - SMC_SET_MMU_CMD(MC_RESET); - SMC_WAIT_MMU_BUSY(); + SMC_SELECT_BANK(lp, 2); + SMC_SET_MMU_CMD(lp, MC_RESET); + SMC_WAIT_MMU_BUSY(lp); } /* @@ -365,19 +366,19 @@ static void smc_enable(struct net_device *dev) DBG(2, "%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); + SMC_SELECT_BANK(lp, 0); + SMC_SET_TCR(lp, lp->tcr_cur_mode); + SMC_SET_RCR(lp, lp->rcr_cur_mode); - SMC_SELECT_BANK(1); - SMC_SET_MAC_ADDR(dev->dev_addr); + SMC_SELECT_BANK(lp, 1); + SMC_SET_MAC_ADDR(lp, dev->dev_addr); /* now, enable interrupts */ mask = IM_EPH_INT|IM_RX_OVRN_INT|IM_RCV_INT; if (lp->version >= (CHIP_91100 << 4)) mask |= IM_MDINT; - SMC_SELECT_BANK(2); - SMC_SET_INT_MASK(mask); + SMC_SELECT_BANK(lp, 2); + SMC_SET_INT_MASK(lp, mask); /* * From this point the register bank must _NOT_ be switched away @@ -400,8 +401,8 @@ static void smc_shutdown(struct net_device *dev) /* no more interrupts for me */ spin_lock_irq(&lp->lock); - SMC_SELECT_BANK(2); - SMC_SET_INT_MASK(0); + SMC_SELECT_BANK(lp, 2); + SMC_SET_INT_MASK(lp, 0); pending_skb = lp->pending_tx_skb; lp->pending_tx_skb = NULL; spin_unlock_irq(&lp->lock); @@ -409,14 +410,14 @@ static void smc_shutdown(struct net_device *dev) dev_kfree_skb(pending_skb); /* 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); + SMC_SELECT_BANK(lp, 0); + SMC_SET_RCR(lp, RCR_CLEAR); + SMC_SET_TCR(lp, TCR_CLEAR); #ifdef POWER_DOWN /* finally, shut the chip down */ - SMC_SELECT_BANK(1); - SMC_SET_CONFIG(SMC_GET_CONFIG() & ~CONFIG_EPH_POWER_EN); + SMC_SELECT_BANK(lp, 1); + SMC_SET_CONFIG(lp, SMC_GET_CONFIG(lp) & ~CONFIG_EPH_POWER_EN); #endif } @@ -431,17 +432,17 @@ static inline void smc_rcv(struct net_device *dev) DBG(3, "%s: %s\n", dev->name, __FUNCTION__); - packet_number = SMC_GET_RXFIFO(); + packet_number = SMC_GET_RXFIFO(lp); if (unlikely(packet_number & RXFIFO_REMPTY)) { PRINTK("%s: smc_rcv with nothing on FIFO.\n", dev->name); return; } /* read from start of packet */ - SMC_SET_PTR(PTR_READ | PTR_RCV | PTR_AUTOINC); + SMC_SET_PTR(lp, PTR_READ | PTR_RCV | PTR_AUTOINC); /* First two words are status and packet length */ - SMC_GET_PKT_HDR(status, packet_len); + SMC_GET_PKT_HDR(lp, status, packet_len); packet_len &= 0x07ff; /* mask off top bits */ DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n", dev->name, packet_number, status, @@ -460,8 +461,8 @@ static inline void smc_rcv(struct net_device *dev) dev->name, packet_len, status); status |= RS_TOOSHORT; } - SMC_WAIT_MMU_BUSY(); - SMC_SET_MMU_CMD(MC_RELEASE); + SMC_WAIT_MMU_BUSY(lp); + SMC_SET_MMU_CMD(lp, MC_RELEASE); dev->stats.rx_errors++; if (status & RS_ALGNERR) dev->stats.rx_frame_errors++; @@ -490,8 +491,8 @@ static inline void smc_rcv(struct net_device *dev) if (unlikely(skb == NULL)) { printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", dev->name); - SMC_WAIT_MMU_BUSY(); - SMC_SET_MMU_CMD(MC_RELEASE); + SMC_WAIT_MMU_BUSY(lp); + SMC_SET_MMU_CMD(lp, MC_RELEASE); dev->stats.rx_dropped++; return; } @@ -510,10 +511,10 @@ static inline void smc_rcv(struct net_device *dev) */ data_len = packet_len - ((status & RS_ODDFRAME) ? 5 : 6); data = skb_put(skb, data_len); - SMC_PULL_DATA(data, packet_len - 4); + SMC_PULL_DATA(lp, data, packet_len - 4); - SMC_WAIT_MMU_BUSY(); - SMC_SET_MMU_CMD(MC_RELEASE); + SMC_WAIT_MMU_BUSY(lp); + SMC_SET_MMU_CMD(lp, MC_RELEASE); PRINT_PKT(data, packet_len - 4); @@ -591,7 +592,7 @@ static void smc_hardware_send_pkt(unsigned long data) } lp->pending_tx_skb = NULL; - packet_no = SMC_GET_AR(); + packet_no = SMC_GET_AR(lp); if (unlikely(packet_no & AR_FAILED)) { printk("%s: Memory allocation failed.\n", dev->name); dev->stats.tx_errors++; @@ -601,8 +602,8 @@ static void smc_hardware_send_pkt(unsigned long data) } /* point to the beginning of the packet */ - SMC_SET_PN(packet_no); - SMC_SET_PTR(PTR_AUTOINC); + SMC_SET_PN(lp, packet_no); + SMC_SET_PTR(lp, PTR_AUTOINC); buf = skb->data; len = skb->len; @@ -614,13 +615,13 @@ static void smc_hardware_send_pkt(unsigned long data) * Send the packet length (+6 for status words, length, and ctl. * The card will pad to 64 bytes with zeroes if packet is too small. */ - SMC_PUT_PKT_HDR(0, len + 6); + SMC_PUT_PKT_HDR(lp, 0, len + 6); /* send the actual data */ - SMC_PUSH_DATA(buf, len & ~1); + SMC_PUSH_DATA(lp, 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); + SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG(lp)); /* * If THROTTLE_TX_PKTS is set, we stop the queue here. This will @@ -634,14 +635,14 @@ static void smc_hardware_send_pkt(unsigned long data) netif_stop_queue(dev); /* queue the packet for TX */ - SMC_SET_MMU_CMD(MC_ENQUEUE); + SMC_SET_MMU_CMD(lp, MC_ENQUEUE); smc_special_unlock(&lp->lock); dev->trans_start = jiffies; dev->stats.tx_packets++; dev->stats.tx_bytes += len; - SMC_ENABLE_INT(IM_TX_INT | IM_TX_EMPTY_INT); + SMC_ENABLE_INT(lp, IM_TX_INT | IM_TX_EMPTY_INT); done: if (!THROTTLE_TX_PKTS) netif_wake_queue(dev); @@ -688,7 +689,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) smc_special_lock(&lp->lock); /* now, try to allocate the memory */ - SMC_SET_MMU_CMD(MC_ALLOC | numPages); + SMC_SET_MMU_CMD(lp, MC_ALLOC | numPages); /* * Poll the chip for a short amount of time in case the @@ -696,9 +697,9 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) */ poll_count = MEMORY_WAIT_TIME; do { - status = SMC_GET_INT(); + status = SMC_GET_INT(lp); if (status & IM_ALLOC_INT) { - SMC_ACK_INT(IM_ALLOC_INT); + SMC_ACK_INT(lp, IM_ALLOC_INT); break; } } while (--poll_count); @@ -710,7 +711,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) /* oh well, wait until the chip finds memory later */ netif_stop_queue(dev); DBG(2, "%s: TX memory allocation deferred.\n", dev->name); - SMC_ENABLE_INT(IM_ALLOC_INT); + SMC_ENABLE_INT(lp, IM_ALLOC_INT); } else { /* * Allocation succeeded: push packet to the chip's own memory @@ -736,19 +737,19 @@ static void smc_tx(struct net_device *dev) DBG(3, "%s: %s\n", dev->name, __FUNCTION__); /* If the TX FIFO is empty then nothing to do */ - packet_no = SMC_GET_TXFIFO(); + packet_no = SMC_GET_TXFIFO(lp); if (unlikely(packet_no & TXFIFO_TEMPTY)) { PRINTK("%s: smc_tx with nothing on FIFO.\n", dev->name); return; } /* select packet to read from */ - saved_packet = SMC_GET_PN(); - SMC_SET_PN(packet_no); + saved_packet = SMC_GET_PN(lp); + SMC_SET_PN(lp, packet_no); /* read the first word (status word) from this packet */ - SMC_SET_PTR(PTR_AUTOINC | PTR_READ); - SMC_GET_PKT_HDR(tx_status, pkt_len); + SMC_SET_PTR(lp, PTR_AUTOINC | PTR_READ); + SMC_GET_PKT_HDR(lp, tx_status, pkt_len); DBG(2, "%s: TX STATUS 0x%04x PNR 0x%02x\n", dev->name, tx_status, packet_no); @@ -771,17 +772,17 @@ static void smc_tx(struct net_device *dev) } /* kill the packet */ - SMC_WAIT_MMU_BUSY(); - SMC_SET_MMU_CMD(MC_FREEPKT); + SMC_WAIT_MMU_BUSY(lp); + SMC_SET_MMU_CMD(lp, MC_FREEPKT); /* Don't restore Packet Number Reg until busy bit is cleared */ - SMC_WAIT_MMU_BUSY(); - SMC_SET_PN(saved_packet); + SMC_WAIT_MMU_BUSY(lp); + SMC_SET_PN(lp, saved_packet); /* re-enable transmit */ - SMC_SELECT_BANK(0); - SMC_SET_TCR(lp->tcr_cur_mode); - SMC_SELECT_BANK(2); + SMC_SELECT_BANK(lp, 0); + SMC_SET_TCR(lp, lp->tcr_cur_mode); + SMC_SELECT_BANK(lp, 2); } @@ -793,7 +794,7 @@ static void smc_mii_out(struct net_device *dev, unsigned int val, int bits) void __iomem *ioaddr = lp->base; unsigned int mii_reg, mask; - mii_reg = SMC_GET_MII() & ~(MII_MCLK | MII_MDOE | MII_MDO); + mii_reg = SMC_GET_MII(lp) & ~(MII_MCLK | MII_MDOE | MII_MDO); mii_reg |= MII_MDOE; for (mask = 1 << (bits - 1); mask; mask >>= 1) { @@ -802,9 +803,9 @@ static void smc_mii_out(struct net_device *dev, unsigned int val, int bits) else mii_reg &= ~MII_MDO; - SMC_SET_MII(mii_reg); + SMC_SET_MII(lp, mii_reg); udelay(MII_DELAY); - SMC_SET_MII(mii_reg | MII_MCLK); + SMC_SET_MII(lp, mii_reg | MII_MCLK); udelay(MII_DELAY); } } @@ -815,16 +816,16 @@ static unsigned int smc_mii_in(struct net_device *dev, int bits) void __iomem *ioaddr = lp->base; unsigned int mii_reg, mask, val; - mii_reg = SMC_GET_MII() & ~(MII_MCLK | MII_MDOE | MII_MDO); - SMC_SET_MII(mii_reg); + mii_reg = SMC_GET_MII(lp) & ~(MII_MCLK | MII_MDOE | MII_MDO); + SMC_SET_MII(lp, mii_reg); for (mask = 1 << (bits - 1), val = 0; mask; mask >>= 1) { - if (SMC_GET_MII() & MII_MDI) + if (SMC_GET_MII(lp) & MII_MDI) val |= mask; - SMC_SET_MII(mii_reg); + SMC_SET_MII(lp, mii_reg); udelay(MII_DELAY); - SMC_SET_MII(mii_reg | MII_MCLK); + SMC_SET_MII(lp, mii_reg | MII_MCLK); udelay(MII_DELAY); } @@ -840,7 +841,7 @@ static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg) void __iomem *ioaddr = lp->base; unsigned int phydata; - SMC_SELECT_BANK(3); + SMC_SELECT_BANK(lp, 3); /* Idle - 32 ones */ smc_mii_out(dev, 0xffffffff, 32); @@ -852,12 +853,12 @@ static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg) phydata = smc_mii_in(dev, 18); /* Return to idle state */ - SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO)); + SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO)); DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", __FUNCTION__, phyaddr, phyreg, phydata); - SMC_SELECT_BANK(2); + SMC_SELECT_BANK(lp, 2); return phydata; } @@ -870,7 +871,7 @@ static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg, struct smc_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; - SMC_SELECT_BANK(3); + SMC_SELECT_BANK(lp, 3); /* Idle - 32 ones */ smc_mii_out(dev, 0xffffffff, 32); @@ -879,12 +880,12 @@ static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg, smc_mii_out(dev, 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, 32); /* Return to idle state */ - SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO)); + SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO)); DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", __FUNCTION__, phyaddr, phyreg, phydata); - SMC_SELECT_BANK(2); + SMC_SELECT_BANK(lp, 2); } /* @@ -957,9 +958,9 @@ static int smc_phy_fixed(struct net_device *dev) smc_phy_write(dev, phyaddr, MII_BMCR, bmcr); /* Re-Configure the Receive/Phy Control register */ - SMC_SELECT_BANK(0); - SMC_SET_RPC(lp->rpc_cur_mode); - SMC_SELECT_BANK(2); + SMC_SELECT_BANK(lp, 0); + SMC_SET_RPC(lp, lp->rpc_cur_mode); + SMC_SELECT_BANK(lp, 2); return 1; } @@ -1050,8 +1051,8 @@ static void smc_phy_check_media(struct net_device *dev, int init) lp->tcr_cur_mode &= ~TCR_SWFDUP; } - SMC_SELECT_BANK(0); - SMC_SET_TCR(lp->tcr_cur_mode); + SMC_SELECT_BANK(lp, 0); + SMC_SET_TCR(lp, lp->tcr_cur_mode); } } @@ -1100,8 +1101,8 @@ static void smc_phy_configure(struct work_struct *work) PHY_INT_SPDDET | PHY_INT_DPLXDET); /* Configure the Receive/Phy Control register */ - SMC_SELECT_BANK(0); - SMC_SET_RPC(lp->rpc_cur_mode); + SMC_SELECT_BANK(lp, 0); + SMC_SET_RPC(lp, lp->rpc_cur_mode); /* If the user requested no auto neg, then go set his request */ if (lp->mii.force_media) { @@ -1158,7 +1159,7 @@ static void smc_phy_configure(struct work_struct *work) smc_phy_check_media(dev, 1); smc_phy_configure_exit: - SMC_SELECT_BANK(2); + SMC_SELECT_BANK(lp, 2); spin_unlock_irq(&lp->lock); lp->work_pending = 0; } @@ -1200,9 +1201,9 @@ static void smc_10bt_check_media(struct net_device *dev, int init) old_carrier = netif_carrier_ok(dev) ? 1 : 0; - SMC_SELECT_BANK(0); - new_carrier = (SMC_GET_EPH_STATUS() & ES_LINK_OK) ? 1 : 0; - SMC_SELECT_BANK(2); + SMC_SELECT_BANK(lp, 0); + new_carrier = (SMC_GET_EPH_STATUS(lp) & ES_LINK_OK) ? 1 : 0; + SMC_SELECT_BANK(lp, 2); if (init || (old_carrier != new_carrier)) { if (!new_carrier) { @@ -1224,11 +1225,11 @@ static void smc_eph_interrupt(struct net_device *dev) smc_10bt_check_media(dev, 0); - SMC_SELECT_BANK(1); - ctl = SMC_GET_CTL(); - SMC_SET_CTL(ctl & ~CTL_LE_ENABLE); - SMC_SET_CTL(ctl); - SMC_SELECT_BANK(2); + SMC_SELECT_BANK(lp, 1); + ctl = SMC_GET_CTL(lp); + SMC_SET_CTL(lp, ctl & ~CTL_LE_ENABLE); + SMC_SET_CTL(lp, ctl); + SMC_SELECT_BANK(lp, 2); } /* @@ -1252,22 +1253,22 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) * ISR. */ SMC_INTERRUPT_PREAMBLE; - saved_pointer = SMC_GET_PTR(); - mask = SMC_GET_INT_MASK(); - SMC_SET_INT_MASK(0); + saved_pointer = SMC_GET_PTR(lp); + mask = SMC_GET_INT_MASK(lp); + SMC_SET_INT_MASK(lp, 0); /* set a timeout value, so I don't stay here forever */ timeout = MAX_IRQ_LOOPS; do { - status = SMC_GET_INT(); + status = SMC_GET_INT(lp); DBG(2, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n", dev->name, status, mask, - ({ int meminfo; SMC_SELECT_BANK(0); - meminfo = SMC_GET_MIR(); - SMC_SELECT_BANK(2); meminfo; }), - SMC_GET_FIFO()); + ({ int meminfo; SMC_SELECT_BANK(lp, 0); + meminfo = SMC_GET_MIR(lp); + SMC_SELECT_BANK(lp, 2); meminfo; }), + SMC_GET_FIFO(lp)); status &= mask; if (!status) @@ -1277,7 +1278,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) /* do this before RX as it will free memory quickly */ DBG(3, "%s: TX int\n", dev->name); smc_tx(dev); - SMC_ACK_INT(IM_TX_INT); + SMC_ACK_INT(lp, IM_TX_INT); if (THROTTLE_TX_PKTS) netif_wake_queue(dev); } else if (status & IM_RCV_INT) { @@ -1292,9 +1293,9 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) mask &= ~IM_TX_EMPTY_INT; /* update stats */ - SMC_SELECT_BANK(0); - card_stats = SMC_GET_COUNTER(); - SMC_SELECT_BANK(2); + SMC_SELECT_BANK(lp, 0); + card_stats = SMC_GET_COUNTER(lp); + SMC_SELECT_BANK(lp, 2); /* single collisions */ dev->stats.collisions += card_stats & 0xF; @@ -1304,26 +1305,26 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) dev->stats.collisions += card_stats & 0xF; } else if (status & IM_RX_OVRN_INT) { DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name, - ({ int eph_st; SMC_SELECT_BANK(0); - eph_st = SMC_GET_EPH_STATUS(); - SMC_SELECT_BANK(2); eph_st; }) ); - SMC_ACK_INT(IM_RX_OVRN_INT); + ({ int eph_st; SMC_SELECT_BANK(lp, 0); + eph_st = SMC_GET_EPH_STATUS(lp); + SMC_SELECT_BANK(lp, 2); eph_st; })); + SMC_ACK_INT(lp, IM_RX_OVRN_INT); dev->stats.rx_errors++; dev->stats.rx_fifo_errors++; } else if (status & IM_EPH_INT) { smc_eph_interrupt(dev); } else if (status & IM_MDINT) { - SMC_ACK_INT(IM_MDINT); + SMC_ACK_INT(lp, IM_MDINT); smc_phy_interrupt(dev); } else if (status & IM_ERCV_INT) { - SMC_ACK_INT(IM_ERCV_INT); + SMC_ACK_INT(lp, IM_ERCV_INT); PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT \n", dev->name); } } while (--timeout); /* restore register states */ - SMC_SET_PTR(saved_pointer); - SMC_SET_INT_MASK(mask); + SMC_SET_PTR(lp, saved_pointer); + SMC_SET_INT_MASK(lp, mask); spin_unlock(&lp->lock); #ifndef CONFIG_NET_POLL_CONTROLLER @@ -1368,13 +1369,13 @@ static void smc_timeout(struct net_device *dev) DBG(2, "%s: %s\n", dev->name, __FUNCTION__); spin_lock_irq(&lp->lock); - status = SMC_GET_INT(); - mask = SMC_GET_INT_MASK(); - fifo = SMC_GET_FIFO(); - SMC_SELECT_BANK(0); - eph_st = SMC_GET_EPH_STATUS(); - meminfo = SMC_GET_MIR(); - SMC_SELECT_BANK(2); + status = SMC_GET_INT(lp); + mask = SMC_GET_INT_MASK(lp); + fifo = SMC_GET_FIFO(lp); + SMC_SELECT_BANK(lp, 0); + eph_st = SMC_GET_EPH_STATUS(lp); + meminfo = SMC_GET_MIR(lp); + SMC_SELECT_BANK(lp, 2); spin_unlock_irq(&lp->lock); PRINTK( "%s: TX timeout (INT 0x%02x INTMASK 0x%02x " "MEM 0x%04x FIFO 0x%04x EPH_ST 0x%04x)\n", @@ -1494,13 +1495,13 @@ static void smc_set_multicast_list(struct net_device *dev) } spin_lock_irq(&lp->lock); - SMC_SELECT_BANK(0); - SMC_SET_RCR(lp->rcr_cur_mode); + SMC_SELECT_BANK(lp, 0); + SMC_SET_RCR(lp, lp->rcr_cur_mode); if (update_multicast) { - SMC_SELECT_BANK(3); - SMC_SET_MCAST(multicast_table); + SMC_SELECT_BANK(lp, 3); + SMC_SET_MCAST(lp, multicast_table); } - SMC_SELECT_BANK(2); + SMC_SELECT_BANK(lp, 2); spin_unlock_irq(&lp->lock); } @@ -1704,8 +1705,9 @@ static const struct ethtool_ops smc_ethtool_ops = { * I just deleted auto_irq.c, since it was never built... * --jgarzik */ -static int __init smc_findirq(void __iomem *ioaddr) +static int __init smc_findirq(struct smc_local *lp) { + void __iomem *ioaddr = lp->base; int timeout = 20; unsigned long cookie; @@ -1719,14 +1721,14 @@ static int __init smc_findirq(void __iomem *ioaddr) * when done. */ /* enable ALLOCation interrupts ONLY */ - SMC_SELECT_BANK(2); - SMC_SET_INT_MASK(IM_ALLOC_INT); + SMC_SELECT_BANK(lp, 2); + SMC_SET_INT_MASK(lp, IM_ALLOC_INT); /* * 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); + SMC_SET_MMU_CMD(lp, MC_ALLOC | 1); /* * Wait until positive that the interrupt has been generated @@ -1734,7 +1736,7 @@ static int __init smc_findirq(void __iomem *ioaddr) do { int int_status; udelay(10); - int_status = SMC_GET_INT(); + int_status = SMC_GET_INT(lp); if (int_status & IM_ALLOC_INT) break; /* got the interrupt */ } while (--timeout); @@ -1747,7 +1749,7 @@ static int __init smc_findirq(void __iomem *ioaddr) */ /* and disable all interrupts again */ - SMC_SET_INT_MASK(0); + SMC_SET_INT_MASK(lp, 0); /* and return what I found */ return probe_irq_off(cookie); @@ -1790,7 +1792,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr, DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__); /* First, see if the high byte is 0x33 */ - val = SMC_CURRENT_BANK(); + val = SMC_CURRENT_BANK(lp); DBG(2, "%s: bank signature probe returned 0x%04x\n", CARDNAME, val); if ((val & 0xFF00) != 0x3300) { if ((val & 0xFF) == 0x33) { @@ -1806,8 +1808,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr, * The above MIGHT indicate a device, but I need to write to * further test this. */ - SMC_SELECT_BANK(0); - val = SMC_CURRENT_BANK(); + SMC_SELECT_BANK(lp, 0); + val = SMC_CURRENT_BANK(lp); if ((val & 0xFF00) != 0x3300) { retval = -ENODEV; goto err_out; @@ -1819,8 +1821,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr, * register to bank 1, so I can access the base address * register */ - SMC_SELECT_BANK(1); - val = SMC_GET_BASE(); + SMC_SELECT_BANK(lp, 1); + val = SMC_GET_BASE(lp); val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT; if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) { printk("%s: IOADDR %p doesn't match configuration (%x).\n", @@ -1832,8 +1834,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr, * recognize. These might need to be added to later, * as future revisions could be added. */ - SMC_SELECT_BANK(3); - revision_register = SMC_GET_REV(); + SMC_SELECT_BANK(lp, 3); + revision_register = SMC_GET_REV(lp); DBG(2, "%s: revision = 0x%04x\n", CARDNAME, revision_register); version_string = chip_ids[ (revision_register >> 4) & 0xF]; if (!version_string || (revision_register & 0xff00) != 0x3300) { @@ -1857,8 +1859,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr, spin_lock_init(&lp->lock); /* Get the MAC address */ - SMC_SELECT_BANK(1); - SMC_GET_MAC_ADDR(dev->dev_addr); + SMC_SELECT_BANK(lp, 1); + SMC_GET_MAC_ADDR(lp, dev->dev_addr); /* now, reset the chip, and put it into a known state */ smc_reset(dev); @@ -1883,7 +1885,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr, trials = 3; while (trials--) { - dev->irq = smc_findirq(ioaddr); + dev->irq = smc_findirq(lp); if (dev->irq) break; /* kick the card and try again */ @@ -1998,6 +2000,8 @@ err_out: static int smc_enable_device(struct platform_device *pdev) { + struct net_device *ndev = platform_get_drvdata(pdev); + struct smc_local *lp = netdev_priv(ndev); unsigned long flags; unsigned char ecor, ecsr; void __iomem *addr; @@ -2040,7 +2044,7 @@ static int smc_enable_device(struct platform_device *pdev) * Set the appropriate byte/word mode. */ ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8; - if (!SMC_CAN_USE_16BIT) + if (!SMC_16BIT(lp)) ecsr |= ECSR_IOIS8; writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT)); local_irq_restore(flags); @@ -2125,10 +2129,11 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device * */ static int smc_drv_probe(struct platform_device *pdev) { + struct smc91x_platdata *pd = pdev->dev.platform_data; + struct smc_local *lp; struct net_device *ndev; struct resource *res, *ires; unsigned int __iomem *addr; - unsigned long irq_flags = SMC_IRQ_FLAGS; int ret; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); @@ -2153,6 +2158,27 @@ static int smc_drv_probe(struct platform_device *pdev) } SET_NETDEV_DEV(ndev, &pdev->dev); + /* get configuration from platform data, only allow use of + * bus width if both SMC_CAN_USE_xxx and SMC91X_USE_xxx are set. + */ + + lp = netdev_priv(ndev); + lp->cfg.irq_flags = SMC_IRQ_FLAGS; + +#ifdef SMC_DYNAMIC_BUS_CONFIG + if (pd) + memcpy(&lp->cfg, pd, sizeof(lp->cfg)); + else { + lp->cfg.flags = SMC91X_USE_8BIT; + lp->cfg.flags |= SMC91X_USE_16BIT; + lp->cfg.flags |= SMC91X_USE_32BIT; + } + + lp->cfg.flags &= ~(SMC_CAN_USE_8BIT ? 0 : SMC91X_USE_8BIT); + lp->cfg.flags &= ~(SMC_CAN_USE_16BIT ? 0 : SMC91X_USE_16BIT); + lp->cfg.flags &= ~(SMC_CAN_USE_32BIT ? 0 : SMC91X_USE_32BIT); +#endif + ndev->dma = (unsigned char)-1; ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); @@ -2163,7 +2189,7 @@ static int smc_drv_probe(struct platform_device *pdev) ndev->irq = ires->start; if (SMC_IRQ_FLAGS == -1) - irq_flags = ires->flags & IRQF_TRIGGER_MASK; + lp->cfg.irq_flags = ires->flags & IRQF_TRIGGER_MASK; ret = smc_request_attrib(pdev); if (ret) @@ -2171,6 +2197,7 @@ static int smc_drv_probe(struct platform_device *pdev) #if defined(CONFIG_SA1100_ASSABET) NCR_0 |= NCR_ENET_OSC_EN; #endif + platform_set_drvdata(pdev, ndev); ret = smc_enable_device(pdev); if (ret) goto out_release_attrib; @@ -2189,8 +2216,7 @@ static int smc_drv_probe(struct platform_device *pdev) } #endif - platform_set_drvdata(pdev, ndev); - ret = smc_probe(ndev, addr, irq_flags); + ret = smc_probe(ndev, addr, lp->cfg.irq_flags); if (ret != 0) goto out_iounmap; @@ -2283,6 +2309,7 @@ static struct platform_driver smc_driver = { .resume = smc_drv_resume, .driver = { .name = CARDNAME, + .owner = THIS_MODULE, }, }; |