From af289e803fdf2fcd19cf4a57c3c896dba146c756 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Wed, 3 Oct 2007 13:03:54 -0500 Subject: 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 Signed-off-by: Jeff Garzik --- drivers/net/pasemi_mac.c | 50 +++++++++++++++++++++++++++++++++++------------- drivers/net/pasemi_mac.h | 8 ++++++-- 2 files changed, 43 insertions(+), 15 deletions(-) (limited to 'drivers') 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 #include +#include #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) & \ -- cgit v1.2.3-55-g7522