]> err.no Git - linux-2.6/blobdiff - drivers/net/spider_net.c
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/drzeus/mmc
[linux-2.6] / drivers / net / spider_net.c
index 6bb8f1f9437c48fa7e3b09b6995d15b3acbf69d3..cef7e6671c49b658d9ce618eafad16213b7b09f9 100644 (file)
@@ -301,7 +301,7 @@ static int
 spider_net_init_chain(struct spider_net_card *card,
                       struct spider_net_descr_chain *chain,
                       struct spider_net_descr *start_descr,
-                      int direction, int no)
+                      int no)
 {
        int i;
        struct spider_net_descr *descr;
@@ -316,7 +316,7 @@ spider_net_init_chain(struct spider_net_card *card,
 
                buf = pci_map_single(card->pdev, descr,
                                     SPIDER_NET_DESCR_SIZE,
-                                    direction);
+                                    PCI_DMA_BIDIRECTIONAL);
 
                if (pci_dma_mapping_error(buf))
                        goto iommu_error;
@@ -330,11 +330,6 @@ spider_net_init_chain(struct spider_net_card *card,
        (descr-1)->next = start_descr;
        start_descr->prev = descr-1;
 
-       descr = start_descr;
-       if (direction == PCI_DMA_FROMDEVICE)
-               for (i=0; i < no; i++, descr++)
-                       descr->next_descr_addr = descr->next->bus_addr;
-
        spin_lock_init(&chain->lock);
        chain->head = start_descr;
        chain->tail = start_descr;
@@ -347,7 +342,7 @@ iommu_error:
                if (descr->bus_addr)
                        pci_unmap_single(card->pdev, descr->bus_addr,
                                         SPIDER_NET_DESCR_SIZE,
-                                        direction);
+                                        PCI_DMA_BIDIRECTIONAL);
        return -ENOMEM;
 }
 
@@ -363,15 +358,15 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card)
        struct spider_net_descr *descr;
 
        descr = card->rx_chain.head;
-       while (descr->next != card->rx_chain.head) {
+       do {
                if (descr->skb) {
                        dev_kfree_skb(descr->skb);
                        pci_unmap_single(card->pdev, descr->buf_addr,
                                         SPIDER_NET_MAX_FRAME,
-                                        PCI_DMA_FROMDEVICE);
+                                        PCI_DMA_BIDIRECTIONAL);
                }
                descr = descr->next;
-       }
+       } while (descr != card->rx_chain.head);
 }
 
 /**
@@ -649,20 +644,12 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
        struct spider_net_descr *descr;
        dma_addr_t buf;
        unsigned long flags;
-       int length;
 
-       length = skb->len;
-       if (length < ETH_ZLEN) {
-               if (skb_pad(skb, ETH_ZLEN-length))
-                       return 0;
-               length = ETH_ZLEN;
-       }
-
-       buf = pci_map_single(card->pdev, skb->data, length, PCI_DMA_TODEVICE);
+       buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
        if (pci_dma_mapping_error(buf)) {
                if (netif_msg_tx_err(card) && net_ratelimit())
                        pr_err("could not iommu-map packet (%p, %i). "
-                                 "Dropping packet\n", skb->data, length);
+                                 "Dropping packet\n", skb->data, skb->len);
                card->spider_stats.tx_iommu_map_error++;
                return -ENOMEM;
        }
@@ -672,7 +659,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
        card->tx_chain.head = descr->next;
 
        descr->buf_addr = buf;
-       descr->buf_size = length;
+       descr->buf_size = skb->len;
        descr->next_descr_addr = 0;
        descr->skb = skb;
        descr->data_status = 0;
@@ -698,7 +685,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
        return 0;
 }
 
-static void
+static int
 spider_net_set_low_watermark(struct spider_net_card *card)
 {
        unsigned long flags;
@@ -718,8 +705,8 @@ spider_net_set_low_watermark(struct spider_net_card *card)
        }
 
        /* If TX queue is short, don't even bother with interrupts */
-       if (cnt < card->tx_desc/4)
-               return;
+       if (cnt < card->num_tx_desc/4)
+               return cnt;
 
        /* Set low-watermark 3/4th's of the way into the queue. */
        descr = card->tx_chain.tail;
@@ -735,6 +722,7 @@ spider_net_set_low_watermark(struct spider_net_card *card)
                     card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG;
        card->low_watermark = descr;
        spin_unlock_irqrestore(&card->tx_chain.lock, flags);
+       return cnt;
 }
 
 /**
@@ -806,8 +794,8 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
 
                /* unmap the skb */
                if (skb) {
-                       int len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
-                       pci_unmap_single(card->pdev, buf_addr, len, PCI_DMA_TODEVICE);
+                       pci_unmap_single(card->pdev, buf_addr, skb->len,
+                                       PCI_DMA_TODEVICE);
                        dev_kfree_skb(skb);
                }
        }
@@ -819,8 +807,12 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
  * @card: card structure
  * @descr: descriptor address to enable TX processing at
  *
- * spider_net_kick_tx_dma writes the current tx chain head as start address
- * of the tx descriptor chain and enables the transmission DMA engine
+ * This routine will start the transmit DMA running if
+ * it is not already running. This routine ned only be
+ * called when queueing a new packet to an empty tx queue.
+ * Writes the current tx chain head as start address
+ * of the tx descriptor chain and enables the transmission
+ * DMA engine.
  */
 static inline void
 spider_net_kick_tx_dma(struct spider_net_card *card)
@@ -860,6 +852,7 @@ out:
 static int
 spider_net_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
+       int cnt;
        struct spider_net_card *card = netdev_priv(netdev);
        struct spider_net_descr_chain *chain = &card->tx_chain;
 
@@ -873,8 +866,9 @@ spider_net_xmit(struct sk_buff *skb, struct net_device *netdev)
                return NETDEV_TX_BUSY;
        }
 
-       spider_net_set_low_watermark(card);
-       spider_net_kick_tx_dma(card);
+       cnt = spider_net_set_low_watermark(card);
+       if (cnt < 5)
+               spider_net_kick_tx_dma(card);
        return NETDEV_TX_OK;
 }
 
@@ -1639,7 +1633,7 @@ spider_net_enable_card(struct spider_net_card *card)
                             SPIDER_NET_INT2_MASK_VALUE);
 
        spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
-                            SPIDER_NET_GDTBSTA | SPIDER_NET_GDTDCEIDIS);
+                            SPIDER_NET_GDTBSTA);
 }
 
 /**
@@ -1655,21 +1649,26 @@ int
 spider_net_open(struct net_device *netdev)
 {
        struct spider_net_card *card = netdev_priv(netdev);
-       int result;
+       struct spider_net_descr *descr;
+       int i, result;
 
        result = -ENOMEM;
        if (spider_net_init_chain(card, &card->tx_chain, card->descr,
-                       PCI_DMA_TODEVICE, card->tx_desc))
+                                 card->num_tx_desc))
                goto alloc_tx_failed;
 
        card->low_watermark = NULL;
 
        /* rx_chain is after tx_chain, so offset is descr + tx_count */
        if (spider_net_init_chain(card, &card->rx_chain,
-                       card->descr + card->tx_desc,
-                       PCI_DMA_FROMDEVICE, card->rx_desc))
+                                 card->descr + card->num_tx_desc,
+                                 card->num_rx_desc))
                goto alloc_rx_failed;
 
+       descr = card->rx_chain.head;
+       for (i=0; i < card->num_rx_desc; i++, descr++)
+               descr->next_descr_addr = descr->next->bus_addr;
+
        /* allocate rx skbs */
        if (spider_net_alloc_rx_skbs(card))
                goto alloc_skbs_failed;
@@ -2053,8 +2052,8 @@ spider_net_setup_netdev(struct spider_net_card *card)
 
        card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT;
 
-       card->tx_desc = tx_descriptors;
-       card->rx_desc = rx_descriptors;
+       card->num_tx_desc = tx_descriptors;
+       card->num_rx_desc = rx_descriptors;
 
        spider_net_setup_netdev_ops(netdev);