diff options
Diffstat (limited to 'drivers/net/smc911x.c')
-rw-r--r-- | drivers/net/smc911x.c | 40 |
1 files changed, 18 insertions, 22 deletions
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 8aa7460ef0e3..5051554ff05b 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -155,23 +155,17 @@ static void PRINT_PKT(u_char *buf, int length) /* this enables an interrupt in the interrupt mask register */ #define SMC_ENABLE_INT(lp, x) do { \ unsigned int __mask; \ - unsigned long __flags; \ - spin_lock_irqsave(&lp->lock, __flags); \ __mask = SMC_GET_INT_EN((lp)); \ __mask |= (x); \ SMC_SET_INT_EN((lp), __mask); \ - spin_unlock_irqrestore(&lp->lock, __flags); \ } while (0) /* this disables an interrupt from the interrupt mask register */ #define SMC_DISABLE_INT(lp, x) do { \ unsigned int __mask; \ - unsigned long __flags; \ - spin_lock_irqsave(&lp->lock, __flags); \ __mask = SMC_GET_INT_EN((lp)); \ __mask &= ~(x); \ SMC_SET_INT_EN((lp), __mask); \ - spin_unlock_irqrestore(&lp->lock, __flags); \ } while (0) /* @@ -180,7 +174,7 @@ static void PRINT_PKT(u_char *buf, int length) static void smc911x_reset(struct net_device *dev) { struct smc911x_local *lp = netdev_priv(dev); - unsigned int reg, timeout=0, resets=1; + unsigned int reg, timeout=0, resets=1, irq_cfg; unsigned long flags; DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); @@ -252,7 +246,12 @@ static void smc911x_reset(struct net_device *dev) * Deassert IRQ for 1*10us for edge type interrupts * and drive IRQ pin push-pull */ - SMC_SET_IRQ_CFG(lp, (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_); + irq_cfg = (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_; +#ifdef SMC_DYNAMIC_BUS_CONFIG + if (lp->cfg.irq_polarity) + irq_cfg |= INT_CFG_IRQ_POL_; +#endif + SMC_SET_IRQ_CFG(lp, irq_cfg); /* clear anything saved */ if (lp->pending_tx_skb != NULL) { @@ -274,6 +273,8 @@ static void smc911x_enable(struct net_device *dev) DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); + spin_lock_irqsave(&lp->lock, flags); + SMC_SET_MAC_ADDR(lp, dev->dev_addr); /* Enable TX */ @@ -286,12 +287,10 @@ static void smc911x_enable(struct net_device *dev) SMC_SET_FIFO_TSL(lp, 64); SMC_SET_GPT_CFG(lp, GPT_CFG_TIMER_EN_ | 10000); - spin_lock_irqsave(&lp->lock, flags); SMC_GET_MAC_CR(lp, cr); cr |= MAC_CR_TXEN_ | MAC_CR_HBDIS_; SMC_SET_MAC_CR(lp, cr); SMC_SET_TX_CFG(lp, TX_CFG_TX_ON_); - spin_unlock_irqrestore(&lp->lock, flags); /* Add 2 byte padding to start of packets */ SMC_SET_RX_CFG(lp, (2<<8) & RX_CFG_RXDOFF_); @@ -300,9 +299,7 @@ static void smc911x_enable(struct net_device *dev) if (cr & MAC_CR_RXEN_) DBG(SMC_DEBUG_RX, "%s: Receiver already enabled\n", dev->name); - spin_lock_irqsave(&lp->lock, flags); SMC_SET_MAC_CR(lp, cr | MAC_CR_RXEN_); - spin_unlock_irqrestore(&lp->lock, flags); /* Interrupt on every received packet */ SMC_SET_FIFO_RSA(lp, 0x01); @@ -318,6 +315,8 @@ static void smc911x_enable(struct net_device *dev) mask|=INT_EN_RDFO_EN_; } SMC_ENABLE_INT(lp, mask); + + spin_unlock_irqrestore(&lp->lock, flags); } /* @@ -458,7 +457,6 @@ static void smc911x_hardware_send_pkt(struct net_device *dev) struct sk_buff *skb; unsigned int cmdA, cmdB, len; unsigned char *buf; - unsigned long flags; DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __func__); BUG_ON(lp->pending_tx_skb == NULL); @@ -501,13 +499,11 @@ static void smc911x_hardware_send_pkt(struct net_device *dev) #else SMC_PUSH_DATA(lp, buf, len); dev->trans_start = jiffies; - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); #endif - spin_lock_irqsave(&lp->lock, flags); if (!lp->tx_throttle) { netif_wake_queue(dev); } - spin_unlock_irqrestore(&lp->lock, flags); SMC_ENABLE_INT(lp, INT_EN_TDFA_EN_ | INT_EN_TSFL_EN_); } @@ -526,6 +522,8 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __func__); + spin_lock_irqsave(&lp->lock, flags); + BUG_ON(lp->pending_tx_skb != NULL); free = SMC_GET_TX_FIFO_INF(lp) & TX_FIFO_INF_TDFREE_; @@ -535,12 +533,10 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) if (free <= SMC911X_TX_FIFO_LOW_THRESHOLD) { DBG(SMC_DEBUG_TX, "%s: Disabling data flow due to low FIFO space (%d)\n", dev->name, free); - spin_lock_irqsave(&lp->lock, flags); /* Reenable when at least 1 packet of size MTU present */ SMC_SET_FIFO_TDA(lp, (SMC911X_TX_FIFO_LOW_THRESHOLD)/64); lp->tx_throttle = 1; netif_stop_queue(dev); - spin_unlock_irqrestore(&lp->lock, flags); } /* Drop packets when we run out of space in TX FIFO @@ -556,6 +552,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) lp->pending_tx_skb = NULL; dev->stats.tx_errors++; dev->stats.tx_dropped++; + spin_unlock_irqrestore(&lp->lock, flags); dev_kfree_skb(skb); return 0; } @@ -565,7 +562,6 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) /* If the DMA is already running then defer this packet Tx until * the DMA IRQ starts it */ - spin_lock_irqsave(&lp->lock, flags); if (lp->txdma_active) { DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: Tx DMA running, deferring packet\n", dev->name); lp->pending_tx_skb = skb; @@ -576,11 +572,11 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: Activating Tx DMA\n", dev->name); lp->txdma_active = 1; } - spin_unlock_irqrestore(&lp->lock, flags); } #endif lp->pending_tx_skb = skb; smc911x_hardware_send_pkt(dev); + spin_unlock_irqrestore(&lp->lock, flags); return 0; } @@ -1242,7 +1238,7 @@ smc911x_rx_dma_irq(int dma, void *data) netif_rx(skb); spin_lock_irqsave(&lp->lock, flags); - pkts = (SMC_GET_RX_FIFO_INF() & RX_FIFO_INF_RXSUSED_) >> 16; + pkts = (SMC_GET_RX_FIFO_INF(lp) & RX_FIFO_INF_RXSUSED_) >> 16; if (pkts != 0) { smc911x_rcv(dev); }else { @@ -2054,7 +2050,7 @@ err_out: */ static int smc911x_drv_probe(struct platform_device *pdev) { - struct smc91x_platdata *pd = pdev->dev.platform_data; + struct smc911x_platdata *pd = pdev->dev.platform_data; struct net_device *ndev; struct resource *res; struct smc911x_local *lp; |