]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/pasemi_mac.c
[AF_UNIX]: Convert socks to unix_socks in scan_inflight, not in callbacks
[linux-2.6-omap-h63xx.git] / drivers / net / pasemi_mac.c
index 31ad2b9093a7cf017d4e699798ac11e1f9164685..09b4fde8d924978d05a63d8e57b834dea02ecea9 100644 (file)
@@ -34,6 +34,7 @@
 #include <net/checksum.h>
 
 #include <asm/irq.h>
+#include <asm/firmware.h>
 
 #include "pasemi_mac.h"
 
@@ -89,6 +90,15 @@ MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value");
 
 static struct pasdma_status *dma_status;
 
+static int translation_enabled(void)
+{
+#if defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE)
+       return 1;
+#else
+       return firmware_has_feature(FW_FEATURE_LPAR);
+#endif
+}
+
 static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg,
                          unsigned int val)
 {
@@ -193,6 +203,7 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev)
        struct pasemi_mac_rxring *ring;
        struct pasemi_mac *mac = netdev_priv(dev);
        int chan_id = mac->dma_rxch;
+       unsigned int cfg;
 
        ring = kzalloc(sizeof(*ring), GFP_KERNEL);
 
@@ -232,20 +243,28 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev)
                           PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) |
                           PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 3));
 
-       write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id),
-                          PAS_DMA_RXCHAN_CFG_HBU(2));
+       cfg = PAS_DMA_RXCHAN_CFG_HBU(2);
+
+       if (translation_enabled())
+               cfg |= PAS_DMA_RXCHAN_CFG_CTR;
+
+       write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id), cfg);
 
        write_dma_reg(mac, PAS_DMA_RXINT_BASEL(mac->dma_if),
-                          PAS_DMA_RXINT_BASEL_BRBL(__pa(ring->buffers)));
+                          PAS_DMA_RXINT_BASEL_BRBL(ring->buf_dma));
 
        write_dma_reg(mac, PAS_DMA_RXINT_BASEU(mac->dma_if),
-                          PAS_DMA_RXINT_BASEU_BRBH(__pa(ring->buffers) >> 32) |
+                          PAS_DMA_RXINT_BASEU_BRBH(ring->buf_dma >> 32) |
                           PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3));
 
-       write_dma_reg(mac, PAS_DMA_RXINT_CFG(mac->dma_if),
-                     PAS_DMA_RXINT_CFG_DHL(3) | PAS_DMA_RXINT_CFG_L2 |
-                     PAS_DMA_RXINT_CFG_LW | PAS_DMA_RXINT_CFG_RBP |
-                     PAS_DMA_RXINT_CFG_HEN);
+       cfg = PAS_DMA_RXINT_CFG_DHL(3) | PAS_DMA_RXINT_CFG_L2 |
+             PAS_DMA_RXINT_CFG_LW | PAS_DMA_RXINT_CFG_RBP |
+             PAS_DMA_RXINT_CFG_HEN;
+
+       if (translation_enabled())
+               cfg |= PAS_DMA_RXINT_CFG_ITRR | PAS_DMA_RXINT_CFG_ITR;
+
+       write_dma_reg(mac, PAS_DMA_RXINT_CFG(mac->dma_if), cfg);
 
        ring->next_to_fill = 0;
        ring->next_to_clean = 0;
@@ -275,6 +294,7 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev)
        u32 val;
        int chan_id = mac->dma_txch;
        struct pasemi_mac_txring *ring;
+       unsigned int cfg;
 
        ring = kzalloc(sizeof(*ring), GFP_KERNEL);
        if (!ring)
@@ -304,11 +324,15 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev)
 
        write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(chan_id), val);
 
-       write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id),
-                          PAS_DMA_TXCHAN_CFG_TY_IFACE |
-                          PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) |
-                          PAS_DMA_TXCHAN_CFG_UP |
-                          PAS_DMA_TXCHAN_CFG_WT(2));
+       cfg = PAS_DMA_TXCHAN_CFG_TY_IFACE |
+             PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) |
+             PAS_DMA_TXCHAN_CFG_UP |
+             PAS_DMA_TXCHAN_CFG_WT(2);
+
+       if (translation_enabled())
+               cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR;
+
+       write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id), cfg);
 
        ring->next_to_fill = 0;
        ring->next_to_clean = 0;
@@ -526,7 +550,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 
        n = mac->rx->next_to_clean;
 
-       prefetch(RX_RING(mac, n));
+       prefetch(&RX_RING(mac, n));
 
        for (count = 0; count < limit; count++) {
                macrx = RX_RING(mac, n);
@@ -556,6 +580,16 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 
                len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
 
+               pci_unmap_single(mac->dma_pdev, dma, len, PCI_DMA_FROMDEVICE);
+
+               if (macrx & XCT_MACRX_CRC) {
+                       /* CRC error flagged */
+                       mac->netdev->stats.rx_errors++;
+                       mac->netdev->stats.rx_crc_errors++;
+                       dev_kfree_skb_irq(skb);
+                       goto next;
+               }
+
                if (len < 256) {
                        struct sk_buff *new_skb;
 
@@ -571,11 +605,10 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
                } else
                        info->skb = NULL;
 
-               pci_unmap_single(mac->dma_pdev, dma, len, PCI_DMA_FROMDEVICE);
-
                info->dma = 0;
 
-               skb_put(skb, len);
+               /* Don't include CRC */
+               skb_put(skb, len-4);
 
                if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -590,6 +623,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
                skb->protocol = eth_type_trans(skb, mac->netdev);
                netif_receive_skb(skb);
 
+next:
                RX_RING(mac, n) = 0;
                RX_RING(mac, n+1) = 0;
 
@@ -1102,7 +1136,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
        unsigned long flags;
        int i, nfrags;
 
-       dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_SS | XCT_MACTX_CRC_PAD;
+       dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD;
 
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
                const unsigned char *nh = skb_network_header(skb);