diff options
author | Olof Johansson <olof@lixom.net> | 2007-10-03 14:03:54 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:54:30 -0400 |
commit | af289e803fdf2fcd19cf4a57c3c896dba146c756 (patch) | |
tree | 038fe6e9a32ed958450bf0bd33227a3c23342ae8 /drivers/net/pasemi_mac.c | |
parent | 9ddf7774b9d760dc3fa4d5ae7d7fd92d4c02150b (diff) |
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/net/pasemi_mac.c')
-rw-r--r-- | drivers/net/pasemi_mac.c | 50 |
1 files changed, 37 insertions, 13 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 @@ | |||
34 | #include <net/checksum.h> | 34 | #include <net/checksum.h> |
35 | 35 | ||
36 | #include <asm/irq.h> | 36 | #include <asm/irq.h> |
37 | #include <asm/firmware.h> | ||
37 | 38 | ||
38 | #include "pasemi_mac.h" | 39 | #include "pasemi_mac.h" |
39 | 40 | ||
@@ -89,6 +90,15 @@ MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value"); | |||
89 | 90 | ||
90 | static struct pasdma_status *dma_status; | 91 | static struct pasdma_status *dma_status; |
91 | 92 | ||
93 | static int translation_enabled(void) | ||
94 | { | ||
95 | #if defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE) | ||
96 | return 1; | ||
97 | #else | ||
98 | return firmware_has_feature(FW_FEATURE_LPAR); | ||
99 | #endif | ||
100 | } | ||
101 | |||
92 | static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg, | 102 | static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg, |
93 | unsigned int val) | 103 | unsigned int val) |
94 | { | 104 | { |
@@ -193,6 +203,7 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev) | |||
193 | struct pasemi_mac_rxring *ring; | 203 | struct pasemi_mac_rxring *ring; |
194 | struct pasemi_mac *mac = netdev_priv(dev); | 204 | struct pasemi_mac *mac = netdev_priv(dev); |
195 | int chan_id = mac->dma_rxch; | 205 | int chan_id = mac->dma_rxch; |
206 | unsigned int cfg; | ||
196 | 207 | ||
197 | ring = kzalloc(sizeof(*ring), GFP_KERNEL); | 208 | ring = kzalloc(sizeof(*ring), GFP_KERNEL); |
198 | 209 | ||
@@ -232,20 +243,28 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev) | |||
232 | PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) | | 243 | PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) | |
233 | PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 3)); | 244 | PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 3)); |
234 | 245 | ||
235 | write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id), | 246 | cfg = PAS_DMA_RXCHAN_CFG_HBU(2); |
236 | PAS_DMA_RXCHAN_CFG_HBU(2)); | 247 | |
248 | if (translation_enabled()) | ||
249 | cfg |= PAS_DMA_RXCHAN_CFG_CTR; | ||
250 | |||
251 | write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id), cfg); | ||
237 | 252 | ||
238 | write_dma_reg(mac, PAS_DMA_RXINT_BASEL(mac->dma_if), | 253 | write_dma_reg(mac, PAS_DMA_RXINT_BASEL(mac->dma_if), |
239 | PAS_DMA_RXINT_BASEL_BRBL(__pa(ring->buffers))); | 254 | PAS_DMA_RXINT_BASEL_BRBL(ring->buf_dma)); |
240 | 255 | ||
241 | write_dma_reg(mac, PAS_DMA_RXINT_BASEU(mac->dma_if), | 256 | write_dma_reg(mac, PAS_DMA_RXINT_BASEU(mac->dma_if), |
242 | PAS_DMA_RXINT_BASEU_BRBH(__pa(ring->buffers) >> 32) | | 257 | PAS_DMA_RXINT_BASEU_BRBH(ring->buf_dma >> 32) | |
243 | PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3)); | 258 | PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3)); |
244 | 259 | ||
245 | write_dma_reg(mac, PAS_DMA_RXINT_CFG(mac->dma_if), | 260 | cfg = PAS_DMA_RXINT_CFG_DHL(3) | PAS_DMA_RXINT_CFG_L2 | |
246 | PAS_DMA_RXINT_CFG_DHL(3) | PAS_DMA_RXINT_CFG_L2 | | 261 | PAS_DMA_RXINT_CFG_LW | PAS_DMA_RXINT_CFG_RBP | |
247 | PAS_DMA_RXINT_CFG_LW | PAS_DMA_RXINT_CFG_RBP | | 262 | PAS_DMA_RXINT_CFG_HEN; |
248 | PAS_DMA_RXINT_CFG_HEN); | 263 | |
264 | if (translation_enabled()) | ||
265 | cfg |= PAS_DMA_RXINT_CFG_ITRR | PAS_DMA_RXINT_CFG_ITR; | ||
266 | |||
267 | write_dma_reg(mac, PAS_DMA_RXINT_CFG(mac->dma_if), cfg); | ||
249 | 268 | ||
250 | ring->next_to_fill = 0; | 269 | ring->next_to_fill = 0; |
251 | ring->next_to_clean = 0; | 270 | ring->next_to_clean = 0; |
@@ -275,6 +294,7 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev) | |||
275 | u32 val; | 294 | u32 val; |
276 | int chan_id = mac->dma_txch; | 295 | int chan_id = mac->dma_txch; |
277 | struct pasemi_mac_txring *ring; | 296 | struct pasemi_mac_txring *ring; |
297 | unsigned int cfg; | ||
278 | 298 | ||
279 | ring = kzalloc(sizeof(*ring), GFP_KERNEL); | 299 | ring = kzalloc(sizeof(*ring), GFP_KERNEL); |
280 | if (!ring) | 300 | if (!ring) |
@@ -304,11 +324,15 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev) | |||
304 | 324 | ||
305 | write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(chan_id), val); | 325 | write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(chan_id), val); |
306 | 326 | ||
307 | write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id), | 327 | cfg = PAS_DMA_TXCHAN_CFG_TY_IFACE | |
308 | PAS_DMA_TXCHAN_CFG_TY_IFACE | | 328 | PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) | |
309 | PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) | | 329 | PAS_DMA_TXCHAN_CFG_UP | |
310 | PAS_DMA_TXCHAN_CFG_UP | | 330 | PAS_DMA_TXCHAN_CFG_WT(2); |
311 | PAS_DMA_TXCHAN_CFG_WT(2)); | 331 | |
332 | if (translation_enabled()) | ||
333 | cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR; | ||
334 | |||
335 | write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id), cfg); | ||
312 | 336 | ||
313 | ring->next_to_fill = 0; | 337 | ring->next_to_fill = 0; |
314 | ring->next_to_clean = 0; | 338 | ring->next_to_clean = 0; |