diff options
Diffstat (limited to 'drivers/net/ethernet/natsemi')
-rw-r--r-- | drivers/net/ethernet/natsemi/jazzsonic.c | 31 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/macsonic.c | 48 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/sonic.c | 66 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/sonic.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/xtsonic.c | 40 |
5 files changed, 60 insertions, 127 deletions
diff --git a/drivers/net/ethernet/natsemi/jazzsonic.c b/drivers/net/ethernet/natsemi/jazzsonic.c index 51fa82b429a3..bfa0c0d39600 100644 --- a/drivers/net/ethernet/natsemi/jazzsonic.c +++ b/drivers/net/ethernet/natsemi/jazzsonic.c @@ -147,39 +147,12 @@ static int sonic_probe1(struct net_device *dev) dev->dev_addr[i*2+1] = val >> 8; } - err = -ENOMEM; - - /* Initialize the device structure. */ - lp->dma_bitmode = SONIC_BITMODE32; - /* Allocate the entire chunk of memory for the descriptors. - Note that this cannot cross a 64K boundary. */ - lp->descriptors = dma_alloc_coherent(lp->device, - SIZEOF_SONIC_DESC * - SONIC_BUS_SCALE(lp->dma_bitmode), - &lp->descriptors_laddr, - GFP_KERNEL); - if (lp->descriptors == NULL) + err = sonic_alloc_descriptors(dev); + if (err) goto out; - /* Now set up the pointers to point to the appropriate places */ - lp->cda = lp->descriptors; - lp->tda = lp->cda + (SIZEOF_SONIC_CDA - * SONIC_BUS_SCALE(lp->dma_bitmode)); - lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS - * SONIC_BUS_SCALE(lp->dma_bitmode)); - lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS - * SONIC_BUS_SCALE(lp->dma_bitmode)); - - lp->cda_laddr = lp->descriptors_laddr; - lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA - * SONIC_BUS_SCALE(lp->dma_bitmode)); - lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS - * SONIC_BUS_SCALE(lp->dma_bitmode)); - lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS - * SONIC_BUS_SCALE(lp->dma_bitmode)); - dev->netdev_ops = &sonic_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; diff --git a/drivers/net/ethernet/natsemi/macsonic.c b/drivers/net/ethernet/natsemi/macsonic.c index 0937fc2a928e..1b5559aacb38 100644 --- a/drivers/net/ethernet/natsemi/macsonic.c +++ b/drivers/net/ethernet/natsemi/macsonic.c @@ -114,17 +114,6 @@ static inline void bit_reverse_addr(unsigned char addr[6]) addr[i] = bitrev8(addr[i]); } -static irqreturn_t macsonic_interrupt(int irq, void *dev_id) -{ - irqreturn_t result; - unsigned long flags; - - local_irq_save(flags); - result = sonic_interrupt(irq, dev_id); - local_irq_restore(flags); - return result; -} - static int macsonic_open(struct net_device* dev) { int retval; @@ -135,12 +124,12 @@ static int macsonic_open(struct net_device* dev) dev->name, dev->irq); goto err; } - /* Under the A/UX interrupt scheme, the onboard SONIC interrupt comes - * in at priority level 3. However, we sometimes get the level 2 inter- - * rupt as well, which must prevent re-entrance of the sonic handler. + /* Under the A/UX interrupt scheme, the onboard SONIC interrupt gets + * moved from level 2 to level 3. Unfortunately we still get some + * level 2 interrupts so register the handler for both. */ if (dev->irq == IRQ_AUTO_3) { - retval = request_irq(IRQ_NUBUS_9, macsonic_interrupt, 0, + retval = request_irq(IRQ_NUBUS_9, sonic_interrupt, 0, "sonic", dev); if (retval) { printk(KERN_ERR "%s: unable to get IRQ %d.\n", @@ -186,33 +175,10 @@ static const struct net_device_ops macsonic_netdev_ops = { static int macsonic_init(struct net_device *dev) { struct sonic_local* lp = netdev_priv(dev); + int err = sonic_alloc_descriptors(dev); - /* Allocate the entire chunk of memory for the descriptors. - Note that this cannot cross a 64K boundary. */ - lp->descriptors = dma_alloc_coherent(lp->device, - SIZEOF_SONIC_DESC * - SONIC_BUS_SCALE(lp->dma_bitmode), - &lp->descriptors_laddr, - GFP_KERNEL); - if (lp->descriptors == NULL) - return -ENOMEM; - - /* Now set up the pointers to point to the appropriate places */ - lp->cda = lp->descriptors; - lp->tda = lp->cda + (SIZEOF_SONIC_CDA - * SONIC_BUS_SCALE(lp->dma_bitmode)); - lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS - * SONIC_BUS_SCALE(lp->dma_bitmode)); - lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS - * SONIC_BUS_SCALE(lp->dma_bitmode)); - - lp->cda_laddr = lp->descriptors_laddr; - lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA - * SONIC_BUS_SCALE(lp->dma_bitmode)); - lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS - * SONIC_BUS_SCALE(lp->dma_bitmode)); - lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS - * SONIC_BUS_SCALE(lp->dma_bitmode)); + if (err) + return err; dev->netdev_ops = &macsonic_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c index 31be3ba66877..dd3605aa5f23 100644 --- a/drivers/net/ethernet/natsemi/sonic.c +++ b/drivers/net/ethernet/natsemi/sonic.c @@ -50,6 +50,42 @@ static void sonic_msg_init(struct net_device *dev) netif_dbg(lp, drv, dev, "%s", version); } +static int sonic_alloc_descriptors(struct net_device *dev) +{ + struct sonic_local *lp = netdev_priv(dev); + + /* Allocate a chunk of memory for the descriptors. Note that this + * must not cross a 64K boundary. It is smaller than one page which + * means that page alignment is a sufficient condition. + */ + lp->descriptors = + dma_alloc_coherent(lp->device, + SIZEOF_SONIC_DESC * + SONIC_BUS_SCALE(lp->dma_bitmode), + &lp->descriptors_laddr, GFP_KERNEL); + + if (!lp->descriptors) + return -ENOMEM; + + lp->cda = lp->descriptors; + lp->tda = lp->cda + SIZEOF_SONIC_CDA * + SONIC_BUS_SCALE(lp->dma_bitmode); + lp->rda = lp->tda + SIZEOF_SONIC_TD * SONIC_NUM_TDS * + SONIC_BUS_SCALE(lp->dma_bitmode); + lp->rra = lp->rda + SIZEOF_SONIC_RD * SONIC_NUM_RDS * + SONIC_BUS_SCALE(lp->dma_bitmode); + + lp->cda_laddr = lp->descriptors_laddr; + lp->tda_laddr = lp->cda_laddr + SIZEOF_SONIC_CDA * + SONIC_BUS_SCALE(lp->dma_bitmode); + lp->rda_laddr = lp->tda_laddr + SIZEOF_SONIC_TD * SONIC_NUM_TDS * + SONIC_BUS_SCALE(lp->dma_bitmode); + lp->rra_laddr = lp->rda_laddr + SIZEOF_SONIC_RD * SONIC_NUM_RDS * + SONIC_BUS_SCALE(lp->dma_bitmode); + + return 0; +} + /* * Open/initialize the SONIC controller. * @@ -264,7 +300,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) spin_lock_irqsave(&lp->lock, flags); - entry = lp->next_tx; + entry = (lp->eol_tx + 1) & SONIC_TDS_MASK; sonic_tda_put(dev, entry, SONIC_TD_STATUS, 0); /* clear status */ sonic_tda_put(dev, entry, SONIC_TD_FRAG_COUNT, 1); /* single fragment */ @@ -275,27 +311,26 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) sonic_tda_put(dev, entry, SONIC_TD_LINK, sonic_tda_get(dev, entry, SONIC_TD_LINK) | SONIC_EOL); - wmb(); + sonic_tda_put(dev, lp->eol_tx, SONIC_TD_LINK, ~SONIC_EOL & + sonic_tda_get(dev, lp->eol_tx, SONIC_TD_LINK)); + + netif_dbg(lp, tx_queued, dev, "%s: issuing Tx command\n", __func__); + + SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); + lp->tx_len[entry] = length; lp->tx_laddr[entry] = laddr; lp->tx_skb[entry] = skb; - wmb(); - sonic_tda_put(dev, lp->eol_tx, SONIC_TD_LINK, - sonic_tda_get(dev, lp->eol_tx, SONIC_TD_LINK) & ~SONIC_EOL); lp->eol_tx = entry; - lp->next_tx = (entry + 1) & SONIC_TDS_MASK; - if (lp->tx_skb[lp->next_tx] != NULL) { + entry = (entry + 1) & SONIC_TDS_MASK; + if (lp->tx_skb[entry]) { /* The ring is full, the ISR has yet to process the next TD. */ netif_dbg(lp, tx_queued, dev, "%s: stopping queue\n", __func__); netif_stop_queue(dev); /* after this packet, wait for ISR to free up some TDAs */ - } else netif_start_queue(dev); - - netif_dbg(lp, tx_queued, dev, "%s: issuing Tx command\n", __func__); - - SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); + } spin_unlock_irqrestore(&lp->lock, flags); @@ -594,11 +629,6 @@ static void sonic_rx(struct net_device *dev) if (rbe) SONIC_WRITE(SONIC_ISR, SONIC_INT_RBE); - /* - * If any worth-while packets have been received, netif_rx() - * has done a mark_bh(NET_BH) for us and will work on them - * when we get to the bottom-half routine. - */ } @@ -780,7 +810,7 @@ static int sonic_init(struct net_device *dev) SONIC_WRITE(SONIC_UTDA, lp->tda_laddr >> 16); SONIC_WRITE(SONIC_CTDA, lp->tda_laddr & 0xffff); - lp->cur_tx = lp->next_tx = 0; + lp->cur_tx = 0; lp->eol_tx = SONIC_NUM_TDS - 1; /* diff --git a/drivers/net/ethernet/natsemi/sonic.h b/drivers/net/ethernet/natsemi/sonic.h index e0e4cba6f6f6..3cbb62c860c8 100644 --- a/drivers/net/ethernet/natsemi/sonic.h +++ b/drivers/net/ethernet/natsemi/sonic.h @@ -321,7 +321,6 @@ struct sonic_local { unsigned int cur_tx; /* first unacked transmit packet */ unsigned int eol_rx; unsigned int eol_tx; /* last unacked transmit packet */ - unsigned int next_tx; /* next free TD */ int msg_enable; struct device *device; /* generic device */ struct net_device_stats stats; @@ -342,6 +341,7 @@ static void sonic_multicast_list(struct net_device *dev); static int sonic_init(struct net_device *dev); static void sonic_tx_timeout(struct net_device *dev, unsigned int txqueue); static void sonic_msg_init(struct net_device *dev); +static int sonic_alloc_descriptors(struct net_device *dev); /* Internal inlines for reading/writing DMA buffers. Note that bus size and endianness matter here, whereas they don't for registers, diff --git a/drivers/net/ethernet/natsemi/xtsonic.c b/drivers/net/ethernet/natsemi/xtsonic.c index e1b886e87a76..dda9ec7d9cee 100644 --- a/drivers/net/ethernet/natsemi/xtsonic.c +++ b/drivers/net/ethernet/natsemi/xtsonic.c @@ -167,47 +167,11 @@ static int __init sonic_probe1(struct net_device *dev) dev->dev_addr[i*2+1] = val >> 8; } - /* Initialize the device structure. */ - lp->dma_bitmode = SONIC_BITMODE32; - /* - * Allocate local private descriptor areas in uncached space. - * The entire structure must be located within the same 64kb segment. - * A simple way to ensure this is to allocate twice the - * size of the structure -- given that the structure is - * much less than 64 kB, at least one of the halves of - * the allocated area will be contained entirely in 64 kB. - * We also allocate extra space for a pointer to allow freeing - * this structure later on (in xtsonic_cleanup_module()). - */ - lp->descriptors = dma_alloc_coherent(lp->device, - SIZEOF_SONIC_DESC * - SONIC_BUS_SCALE(lp->dma_bitmode), - &lp->descriptors_laddr, - GFP_KERNEL); - if (lp->descriptors == NULL) { - err = -ENOMEM; + err = sonic_alloc_descriptors(dev); + if (err) goto out; - } - - lp->cda = lp->descriptors; - lp->tda = lp->cda + (SIZEOF_SONIC_CDA - * SONIC_BUS_SCALE(lp->dma_bitmode)); - lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS - * SONIC_BUS_SCALE(lp->dma_bitmode)); - lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS - * SONIC_BUS_SCALE(lp->dma_bitmode)); - - /* get the virtual dma address */ - - lp->cda_laddr = lp->descriptors_laddr; - lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA - * SONIC_BUS_SCALE(lp->dma_bitmode)); - lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS - * SONIC_BUS_SCALE(lp->dma_bitmode)); - lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS - * SONIC_BUS_SCALE(lp->dma_bitmode)); dev->netdev_ops = &xtsonic_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; |