summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2007-10-03 20:03:54 +0200
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-11 01:54:30 +0200
commitaf289e803fdf2fcd19cf4a57c3c896dba146c756 (patch)
tree038fe6e9a32ed958450bf0bd33227a3c23342ae8 /drivers
parentdrivers/net/qla3xxx: trim trailing whitespace (diff)
downloadlinux-af289e803fdf2fcd19cf4a57c3c896dba146c756.tar.xz
linux-af289e803fdf2fcd19cf4a57c3c896dba146c756.zip
pasemi_mac: enable iommu support
pasemi_mac: enable iommu support Enable IOMMU support for pasemi_mac, but avoid using it on non-partitioned systems for performance reasons. The user can override this by selecting the PPC_PASEMI_IOMMU_DMA_FORCE configuration option. Signed-off-by: Olof Johansson <olof@lixom.net> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/pasemi_mac.c50
-rw-r--r--drivers/net/pasemi_mac.h8
2 files changed, 43 insertions, 15 deletions
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 31ad2b9093a7..9f9a421c99b3 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -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;
diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h
index 1a120408cf3f..60368df72634 100644
--- a/drivers/net/pasemi_mac.h
+++ b/drivers/net/pasemi_mac.h
@@ -212,6 +212,7 @@ enum {
#define PAS_DMA_RXINT_CFG_DHL_S 24
#define PAS_DMA_RXINT_CFG_DHL(x) (((x) << PAS_DMA_RXINT_CFG_DHL_S) & \
PAS_DMA_RXINT_CFG_DHL_M)
+#define PAS_DMA_RXINT_CFG_ITR 0x00400000
#define PAS_DMA_RXINT_CFG_LW 0x00200000
#define PAS_DMA_RXINT_CFG_L2 0x00100000
#define PAS_DMA_RXINT_CFG_HEN 0x00080000
@@ -258,9 +259,11 @@ enum {
#define PAS_DMA_TXCHAN_CFG_WT_S 6
#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
PAS_DMA_TXCHAN_CFG_WT_M)
-#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */
-#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */
+#define PAS_DMA_TXCHAN_CFG_TRD 0x00010000 /* translate data */
+#define PAS_DMA_TXCHAN_CFG_TRR 0x00008000 /* translate rings */
#define PAS_DMA_TXCHAN_CFG_UP 0x00004000 /* update tx descr when sent */
+#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */
+#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */
#define PAS_DMA_TXCHAN_INCR(c) (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
#define PAS_DMA_TXCHAN_BASEL(c) (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
#define PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0
@@ -294,6 +297,7 @@ enum {
#define PAS_DMA_RXCHAN_CCMDSTA_FD 0x00001000
#define PAS_DMA_RXCHAN_CCMDSTA_DT 0x00000800
#define PAS_DMA_RXCHAN_CFG(c) (0x804+(c)*_PAS_DMA_RXCHAN_STRIDE)
+#define PAS_DMA_RXCHAN_CFG_CTR 0x00000400
#define PAS_DMA_RXCHAN_CFG_HBU_M 0x00000380
#define PAS_DMA_RXCHAN_CFG_HBU_S 7
#define PAS_DMA_RXCHAN_CFG_HBU(x) (((x) << PAS_DMA_RXCHAN_CFG_HBU_S) & \