]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/pasemi_mac.c
ixgb: endianness
[linux-2.6-omap-h63xx.git] / drivers / net / pasemi_mac.c
index 46d5c0eef784656eab24f054f8d0081d8121e6b5..4d87cd65626f8c2954450f0f8b46c97fbd94b4c8 100644 (file)
 #define RX_DESC_INFO(mac, num) ((mac)->rx->desc_info[(num) & (RX_RING_SIZE-1)])
 #define RX_BUFF(mac, num)      ((mac)->rx->buffers[(num) & (RX_RING_SIZE-1)])
 
+#define RING_USED(ring)                (((ring)->next_to_fill - (ring)->next_to_clean) \
+                                & ((ring)->size - 1))
+#define RING_AVAIL(ring)       ((ring->size) - RING_USED(ring))
+
 #define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
 
 MODULE_LICENSE("GPL");
@@ -174,6 +178,7 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev)
 
        spin_lock_init(&ring->lock);
 
+       ring->size = RX_RING_SIZE;
        ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
                                  RX_RING_SIZE, GFP_KERNEL);
 
@@ -253,6 +258,7 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev)
 
        spin_lock_init(&ring->lock);
 
+       ring->size = TX_RING_SIZE;
        ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
                                  TX_RING_SIZE, GFP_KERNEL);
        if (!ring->desc_info)
@@ -281,7 +287,7 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev)
                           PAS_DMA_TXCHAN_CFG_UP |
                           PAS_DMA_TXCHAN_CFG_WT(2));
 
-       ring->next_to_use = 0;
+       ring->next_to_fill = 0;
        ring->next_to_clean = 0;
 
        snprintf(ring->irq_name, sizeof(ring->irq_name),
@@ -376,9 +382,7 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev)
        int start = mac->rx->next_to_fill;
        unsigned int limit, count;
 
-       limit = (mac->rx->next_to_clean + RX_RING_SIZE -
-                mac->rx->next_to_fill) & (RX_RING_SIZE - 1);
-
+       limit = RING_AVAIL(mac->rx);
        /* Check to see if we're doing first-time setup */
        if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0))
                limit = RX_RING_SIZE;
@@ -471,6 +475,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
                rmb();
 
                dp = &RX_DESC(mac, n);
+               prefetchw(dp);
                macrx = dp->macrx;
 
                if (!(macrx & XCT_MACRX_O))
@@ -492,8 +497,10 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
                        if (info->dma == dma)
                                break;
                }
+               prefetchw(info);
 
                skb = info->skb;
+               prefetchw(skb);
                info->dma = 0;
 
                pci_unmap_single(mac->dma_pdev, dma, skb->len,
@@ -506,9 +513,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
                            netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN);
                        if (new_skb) {
                                skb_reserve(new_skb, NET_IP_ALIGN);
-                               memcpy(new_skb->data - NET_IP_ALIGN,
-                                       skb->data - NET_IP_ALIGN,
-                                       len + NET_IP_ALIGN);
+                               memcpy(new_skb->data, skb->data, len);
                                /* save the skb in buffer_info as good */
                                skb = new_skb;
                        }
@@ -518,18 +523,17 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 
                skb_put(skb, len);
 
-               skb->protocol = eth_type_trans(skb, mac->netdev);
-
-               if ((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
-                       skb->ip_summed = CHECKSUM_COMPLETE;
+               if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
+                       skb->ip_summed = CHECKSUM_UNNECESSARY;
                        skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
                                           XCT_MACRX_CSUM_S;
                } else
                        skb->ip_summed = CHECKSUM_NONE;
 
-               mac->stats.rx_bytes += len;
-               mac->stats.rx_packets++;
+               mac->netdev->stats.rx_bytes += len;
+               mac->netdev->stats.rx_packets++;
 
+               skb->protocol = eth_type_trans(skb, mac->netdev);
                netif_receive_skb(skb);
 
                dp->ptr = 0;
@@ -551,37 +555,56 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
        int i;
        struct pasemi_mac_buffer *info;
        struct pas_dma_xct_descr *dp;
-       int start, count;
+       unsigned int start, count, limit;
+       unsigned int total_count;
        int flags;
+       struct sk_buff *skbs[32];
+       dma_addr_t dmas[32];
 
+       total_count = 0;
+restart:
        spin_lock_irqsave(&mac->tx->lock, flags);
 
        start = mac->tx->next_to_clean;
+       limit = min(mac->tx->next_to_fill, start+32);
+
        count = 0;
 
-       for (i = start; i < mac->tx->next_to_use; i++) {
+       for (i = start; i < limit; i++) {
                dp = &TX_DESC(mac, i);
-               if (!dp || (dp->mactx & XCT_MACTX_O))
-                       break;
 
-               count++;
+               if (unlikely(dp->mactx & XCT_MACTX_O))
+                       /* Not yet transmitted */
+                       break;
 
                info = &TX_DESC_INFO(mac, i);
-
-               pci_unmap_single(mac->dma_pdev, info->dma,
-                                info->skb->len, PCI_DMA_TODEVICE);
-               dev_kfree_skb_irq(info->skb);
+               skbs[count] = info->skb;
+               dmas[count] = info->dma;
 
                info->skb = NULL;
                info->dma = 0;
                dp->mactx = 0;
                dp->ptr = 0;
+
+               count++;
        }
        mac->tx->next_to_clean += count;
        spin_unlock_irqrestore(&mac->tx->lock, flags);
        netif_wake_queue(mac->netdev);
 
-       return count;
+       for (i = 0; i < count; i++) {
+               pci_unmap_single(mac->dma_pdev, dmas[i],
+                                skbs[i]->len, PCI_DMA_TODEVICE);
+               dev_kfree_skb_irq(skbs[i]);
+       }
+
+       total_count += count;
+
+       /* If the batch was full, try to clean more */
+       if (count == 32)
+               goto restart;
+
+       return total_count;
 }
 
 
@@ -777,7 +800,7 @@ static int pasemi_mac_open(struct net_device *dev)
                           PAS_IOB_DMA_RXCH_CFG_CNTTH(0));
 
        write_iob_reg(mac, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
-                          PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
+                          PAS_IOB_DMA_TXCH_CFG_CNTTH(128));
 
        /* Clear out any residual packet count state from firmware */
        pasemi_mac_restart_rx_intr(mac);
@@ -950,7 +973,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
        struct pasemi_mac_txring *txring;
        struct pasemi_mac_buffer *info;
        struct pas_dma_xct_descr *dp;
-       u64 dflags;
+       u64 dflags, mactx, ptr;
        dma_addr_t map;
        int flags;
 
@@ -978,18 +1001,20 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
        if (dma_mapping_error(map))
                return NETDEV_TX_BUSY;
 
+       mactx = dflags | XCT_MACTX_LLEN(skb->len);
+       ptr   = XCT_PTR_LEN(skb->len) | XCT_PTR_ADDR(map);
+
        txring = mac->tx;
 
        spin_lock_irqsave(&txring->lock, flags);
 
-       if (txring->next_to_clean - txring->next_to_use == TX_RING_SIZE) {
+       if (RING_AVAIL(txring) <= 1) {
                spin_unlock_irqrestore(&txring->lock, flags);
                pasemi_mac_clean_tx(mac);
                pasemi_mac_restart_tx_intr(mac);
                spin_lock_irqsave(&txring->lock, flags);
 
-               if (txring->next_to_clean - txring->next_to_use ==
-                   TX_RING_SIZE) {
+               if (RING_AVAIL(txring) <= 1) {
                        /* Still no room -- stop the queue and wait for tx
                         * intr when there's room.
                         */
@@ -998,18 +1023,17 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
                }
        }
 
+       dp = &TX_DESC(mac, txring->next_to_fill);
+       info = &TX_DESC_INFO(mac, txring->next_to_fill);
 
-       dp = &TX_DESC(mac, txring->next_to_use);
-       info = &TX_DESC_INFO(mac, txring->next_to_use);
-
-       dp->mactx = dflags | XCT_MACTX_LLEN(skb->len);
-       dp->ptr   = XCT_PTR_LEN(skb->len) | XCT_PTR_ADDR(map);
+       dp->mactx = mactx;
+       dp->ptr   = ptr;
        info->dma = map;
        info->skb = skb;
 
-       txring->next_to_use++;
-       mac->stats.tx_packets++;
-       mac->stats.tx_bytes += skb->len;
+       txring->next_to_fill++;
+       dev->stats.tx_packets++;
+       dev->stats.tx_bytes += skb->len;
 
        spin_unlock_irqrestore(&txring->lock, flags);
 
@@ -1023,14 +1047,6 @@ out_err:
        return NETDEV_TX_BUSY;
 }
 
-static struct net_device_stats *pasemi_mac_get_stats(struct net_device *dev)
-{
-       struct pasemi_mac *mac = netdev_priv(dev);
-
-       return &mac->stats;
-}
-
-
 static void pasemi_mac_set_rx_mode(struct net_device *dev)
 {
        struct pasemi_mac *mac = netdev_priv(dev);
@@ -1054,6 +1070,7 @@ static int pasemi_mac_poll(struct napi_struct *napi, int budget)
        struct net_device *dev = mac->netdev;
        int pkts;
 
+       pasemi_mac_clean_tx(mac);
        pkts = pasemi_mac_clean_rx(mac, budget);
        if (pkts < budget) {
                /* all done, no more packets present */
@@ -1138,6 +1155,7 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        struct net_device *dev;
        struct pasemi_mac *mac;
        int err;
+       DECLARE_MAC_BUF(mac_buf);
 
        err = pci_enable_device(pdev);
        if (err)
@@ -1151,7 +1169,6 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto out_disable_device;
        }
 
-       SET_MODULE_OWNER(dev);
        pci_set_drvdata(pdev, dev);
        SET_NETDEV_DEV(dev, &pdev->dev);
 
@@ -1162,7 +1179,7 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64);
 
-       dev->features = NETIF_F_HW_CSUM;
+       dev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX;
 
        /* These should come out of the device tree eventually */
        mac->dma_txch = index;
@@ -1199,7 +1216,6 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->open = pasemi_mac_open;
        dev->stop = pasemi_mac_close;
        dev->hard_start_xmit = pasemi_mac_start_tx;
-       dev->get_stats = pasemi_mac_get_stats;
        dev->set_multicast_list = pasemi_mac_set_rx_mode;
 
        err = pasemi_mac_map_regs(mac);
@@ -1222,11 +1238,10 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto out;
        } else
                printk(KERN_INFO "%s: PA Semi %s: intf %d, txch %d, rxch %d, "
-                      "hw addr %02x:%02x:%02x:%02x:%02x:%02x\n",
+                      "hw addr %s\n",
                       dev->name, mac->type == MAC_TYPE_GMAC ? "GMAC" : "XAUI",
                       mac->dma_if, mac->dma_txch, mac->dma_rxch,
-                      dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-                      dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+                      print_mac(mac_buf, dev->dev_addr));
 
        return err;