netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
@ 2007-05-02  1:13 Michael Chan
  2007-05-02  7:06 ` Jeff Garzik
  0 siblings, 1 reply; 17+ messages in thread
From: Michael Chan @ 2007-05-02  1:13 UTC (permalink / raw)
  To: davem, netdev

[BNX2]: Add 40-bit DMA workaround for 5708.

The internal PCIE-to-PCIX bridge of the 5708 has the same 40-bit DMA
limitation as some of the tg3 chips.  Use the same workaround used in
tg3.  On 64-bit systems without IOMMU, linearize the SKB if any
address is > 40-bit.

Signed-off-by: Michael Chan <mchan@broadcom.com>

diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 6d05397..dba4088 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -4495,6 +4495,93 @@ bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid)
 }
 #endif
 
+/* Test for DMA addresses > 40-bit.
+ * Only 64-bit systems without IOMMU require DMA address checking.
+ */
+static inline int bnx2_40bit_overflow_test(struct bnx2 *bp, dma_addr_t mapping,
+					   int len)
+{
+#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
+	if (CHIP_NUM(bp) == CHIP_NUM_5708)
+		return (((u64) mapping + len) > DMA_40BIT_MASK);
+	return 0;
+#else
+	return 0;
+#endif
+}
+
+#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
+/* Workaround 40-bit hardware DMA bugs. */
+static int bnx2_dma_hwbug_workaround(struct bnx2 *bp, struct sk_buff **skb,
+				     u16 *last_plus_one, u32 base_flags,
+				     u32 mss)
+{
+	struct sk_buff *new_skb = skb_copy(*skb, GFP_ATOMIC);
+	dma_addr_t new_addr = 0;
+	int i, ret = 0;
+	u16 hw_prod = *last_plus_one;
+	u16 start, hw_start, prod;
+
+	prod = TX_RING_IDX(hw_prod);
+	start = prod - 1 - skb_shinfo(*skb)->nr_frags;
+	hw_start = hw_prod - 1 - skb_shinfo(*skb)->nr_frags;
+	start &= MAX_TX_DESC_CNT;
+	if (start > prod) {
+		start--;
+		hw_start--;
+	}
+
+	if (!new_skb) {
+		ret = -1;
+	} else {
+		struct tx_bd *txbd;
+
+		/* New SKB is guaranteed to be linear. */
+		new_addr = pci_map_single(bp->pdev, new_skb->data, new_skb->len,
+					  PCI_DMA_TODEVICE);
+		txbd = &bp->tx_desc_ring[start];
+
+		txbd->tx_bd_haddr_hi = (u64) new_addr >> 32;
+		txbd->tx_bd_haddr_lo = (u64) new_addr & 0xffffffff;
+		txbd->tx_bd_mss_nbytes = new_skb->len | (mss << 16);
+		txbd->tx_bd_vlan_tag_flags = base_flags | TX_BD_FLAGS_START |
+					     TX_BD_FLAGS_END;
+
+		*last_plus_one = NEXT_TX_BD(hw_start);
+	}
+
+	/* Now clean up the sw ring entries. */
+	i = 0;
+	while (start != prod) {
+		int len;
+
+		if (i == 0)
+			len = skb_headlen(*skb);
+		else
+			len = skb_shinfo(*skb)->frags[i-1].size;
+
+		pci_unmap_single(bp->pdev,
+				 pci_unmap_addr(&tp->tx_buf_ring[start],
+					 	mapping),
+				 len, PCI_DMA_TODEVICE);
+		if (i == 0) {
+			bp->tx_buf_ring[start].skb = new_skb;
+			pci_unmap_addr_set(&bp->tx_buf_ring[start], mapping,
+					   new_addr);
+		}
+		hw_start = NEXT_TX_BD(hw_start);
+		start = TX_RING_IDX(hw_start);
+		i++;
+	}
+
+	dev_kfree_skb(*skb);
+
+	*skb = new_skb;
+
+	return ret;
+}
+#endif
+
 /* Called with netif_tx_lock.
  * bnx2_tx_int() runs without netif_tx_lock unless it needs to call
  * netif_wake_queue().
@@ -4508,7 +4595,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct sw_bd *tx_buf;
 	u32 len, vlan_tag_flags, last_frag, mss;
 	u16 prod, ring_prod;
-	int i;
+	int i, would_hit_hwbug = 0;
 
 	if (unlikely(bnx2_tx_avail(bp) < (skb_shinfo(skb)->nr_frags + 1))) {
 		netif_stop_queue(dev);
@@ -4598,10 +4685,25 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		txbd->tx_bd_mss_nbytes = len | (mss << 16);
 		txbd->tx_bd_vlan_tag_flags = vlan_tag_flags;
 
+		if (bnx2_40bit_overflow_test(bp, mapping, len))
+			would_hit_hwbug = 1;
 	}
 	txbd->tx_bd_vlan_tag_flags |= TX_BD_FLAGS_END;
 
 	prod = NEXT_TX_BD(prod);
+
+#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
+	if (unlikely(would_hit_hwbug)) {
+		/* If the workaround fails due to memory/mapping
+		 * failure, silently drop this packet.
+		 */
+		if (bnx2_dma_hwbug_workaround(bp, &skb, &prod,
+					      vlan_tag_flags, mss))
+			return NETDEV_TX_OK;
+
+	}
+#endif
+
 	bp->tx_prod_bseq += skb->len;
 
 	REG_WR16(bp, bp->tx_bidx_addr, prod);
@@ -5711,6 +5813,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 	unsigned long mem_len;
 	int rc;
 	u32 reg;
+	u64 dma_mask, persist_dma_mask;
 
 	SET_MODULE_OWNER(dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
@@ -5749,21 +5852,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 		goto err_out_release;
 	}
 
-	if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
-		bp->flags |= USING_DAC_FLAG;
-		if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
-			dev_err(&pdev->dev,
-				"pci_set_consistent_dma_mask failed, aborting.\n");
-			rc = -EIO;
-			goto err_out_release;
-		}
-	}
-	else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) {
-		dev_err(&pdev->dev, "System does not support DMA, aborting.\n");
-		rc = -EIO;
-		goto err_out_release;
-	}
-
 	bp->dev = dev;
 	bp->pdev = pdev;
 
@@ -5805,6 +5893,33 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 		}
 	}
 
+	/* 5708 cannot support DMA addresses > 40-bit.
+	 * On 64-bit systems with IOMMU, use 40-bit dma_mask.
+	 * On 64-bit systems without IOMMU, use 64-bit dma_mask and
+	 * do DMA address check in bnx2_start_xmit().
+	 */
+	if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+		persist_dma_mask = dma_mask = DMA_40BIT_MASK;
+#ifdef CONFIG_HIGHMEM
+		dma_mask = DMA_64BIT_MASK;
+#endif
+	} else
+		persist_dma_mask = dma_mask = DMA_64BIT_MASK;
+
+	/* Configure DMA attributes. */
+	if (pci_set_dma_mask(pdev, dma_mask) == 0) {
+		dev->features |= NETIF_F_HIGHDMA;
+		rc = pci_set_consistent_dma_mask(pdev, persist_dma_mask);
+		if (rc) {
+			dev_err(&pdev->dev,
+				"pci_set_consistent_dma_mask failed, aborting.\n");
+			goto err_out_unmap;
+		}
+	} else if ((rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
+		dev_err(&pdev->dev, "System does not support DMA, aborting.\n");
+		goto err_out_unmap;
+	}
+
 	/* Get bus information. */
 	reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS);
 	if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {
@@ -6114,8 +6229,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	printk("\n");
 
 	dev->features |= NETIF_F_SG;
-	if (bp->flags & USING_DAC_FLAG)
-		dev->features |= NETIF_F_HIGHDMA;
 	dev->features |= NETIF_F_IP_CSUM;
 #ifdef BCM_VLAN
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 878eee5..8e7b29a 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -6433,7 +6433,6 @@ struct bnx2 {
 #define PCI_32BIT_FLAG			2
 #define ONE_TDMA_FLAG			4	/* no longer used */
 #define NO_WOL_FLAG			8
-#define USING_DAC_FLAG			0x10
 #define USING_MSI_FLAG			0x20
 #define ASF_ENABLE_FLAG			0x40
 



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02  1:13 [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708 Michael Chan
@ 2007-05-02  7:06 ` Jeff Garzik
  2007-05-02  7:12   ` David Miller
  0 siblings, 1 reply; 17+ messages in thread
From: Jeff Garzik @ 2007-05-02  7:06 UTC (permalink / raw)
  To: Michael Chan; +Cc: davem, netdev

Michael Chan wrote:
> [BNX2]: Add 40-bit DMA workaround for 5708.
> 
> The internal PCIE-to-PCIX bridge of the 5708 has the same 40-bit DMA
> limitation as some of the tg3 chips.  Use the same workaround used in
> tg3.  On 64-bit systems without IOMMU, linearize the SKB if any
> address is > 40-bit.
> 
> Signed-off-by: Michael Chan <mchan@broadcom.com>
> 
> diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
> index 6d05397..dba4088 100644
> --- a/drivers/net/bnx2.c
> +++ b/drivers/net/bnx2.c
> @@ -4495,6 +4495,93 @@ bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid)
>  }
>  #endif
>  
> +/* Test for DMA addresses > 40-bit.
> + * Only 64-bit systems without IOMMU require DMA address checking.
> + */
> +static inline int bnx2_40bit_overflow_test(struct bnx2 *bp, dma_addr_t mapping,
> +					   int len)
> +{
> +#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
> +	if (CHIP_NUM(bp) == CHIP_NUM_5708)
> +		return (((u64) mapping + len) > DMA_40BIT_MASK);

If the mapping is at a very high address, adding len might overflow, yes?



> +#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
> +	if (unlikely(would_hit_hwbug)) {
> +		/* If the workaround fails due to memory/mapping
> +		 * failure, silently drop this packet.
> +		 */
> +		if (bnx2_dma_hwbug_workaround(bp, &skb, &prod,
> +					      vlan_tag_flags, mss))
> +			return NETDEV_TX_OK;
> +
> +	}
> +#endif

You need to at least account for the drop, in packets-dropped stat.

/Completely/ silent intentional packet drops are something to be 
avoided.  The user should be given /some/ indication of what is going on.

Second, CONFIG_HIGHMEM is a bad test for IOMMU presence.  I don't think 
you /can/ test for IOMMU presence.  Maybe DaveM knows a way that I do not?



> +	/* 5708 cannot support DMA addresses > 40-bit.
> +	 * On 64-bit systems with IOMMU, use 40-bit dma_mask.
> +	 * On 64-bit systems without IOMMU, use 64-bit dma_mask and
> +	 * do DMA address check in bnx2_start_xmit().
> +	 */
> +	if (CHIP_NUM(bp) == CHIP_NUM_5708) {
> +		persist_dma_mask = dma_mask = DMA_40BIT_MASK;
> +#ifdef CONFIG_HIGHMEM
> +		dma_mask = DMA_64BIT_MASK;
> +#endif
> +	} else
> +		persist_dma_mask = dma_mask = DMA_64BIT_MASK;
> +
> +	/* Configure DMA attributes. */
> +	if (pci_set_dma_mask(pdev, dma_mask) == 0) {
> +		dev->features |= NETIF_F_HIGHDMA;
> +		rc = pci_set_consistent_dma_mask(pdev, persist_dma_mask);
> +		if (rc) {
> +			dev_err(&pdev->dev,
> +				"pci_set_consistent_dma_mask failed, aborting.\n");
> +			goto err_out_unmap;
> +		}
> +	} else if ((rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
> +		dev_err(&pdev->dev, "System does not support DMA, aborting.\n");
> +		goto err_out_unmap;
> +	}
> +

Ditto.  CONFIG_HIGHMEM is not an effective test.

NAK.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02  7:06 ` Jeff Garzik
@ 2007-05-02  7:12   ` David Miller
  2007-05-02 15:23     ` Michael Chan
  0 siblings, 1 reply; 17+ messages in thread
From: David Miller @ 2007-05-02  7:12 UTC (permalink / raw)
  To: jeff; +Cc: mchan, netdev

From: Jeff Garzik <jeff@garzik.org>
Date: Wed, 02 May 2007 03:06:43 -0400

> Second, CONFIG_HIGHMEM is a bad test for IOMMU presence.  I don't
> think you /can/ test for IOMMU presence.  Maybe DaveM knows a way
> that I do not?

You really can't.

We have platforms that are both IOMMU and non-IOMMU for the same
configuration, it isn't known until run-time.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02  7:12   ` David Miller
@ 2007-05-02 15:23     ` Michael Chan
  2007-05-02 15:28       ` Christoph Hellwig
                         ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: Michael Chan @ 2007-05-02 15:23 UTC (permalink / raw)
  To: David Miller, jeff; +Cc: netdev

David Miller wrote:

> From: Jeff Garzik <jeff@garzik.org>
> Date: Wed, 02 May 2007 03:06:43 -0400
> 
> > Second, CONFIG_HIGHMEM is a bad test for IOMMU presence.  I don't
> > think you /can/ test for IOMMU presence.  Maybe DaveM knows a way
> > that I do not?
> 
> You really can't.
> 
> We have platforms that are both IOMMU and non-IOMMU for the same
> configuration, it isn't known until run-time.
> 
> 
A non-IOMMU system using 64-bit dma_addr_t will always set
CONFIG_HIGHMEM, right?


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02 15:23     ` Michael Chan
@ 2007-05-02 15:28       ` Christoph Hellwig
  2007-05-02 15:29       ` Jeff Garzik
  2007-05-02 19:40       ` David Miller
  2 siblings, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2007-05-02 15:28 UTC (permalink / raw)
  To: Michael Chan; +Cc: David Miller, jeff, netdev

On Wed, May 02, 2007 at 08:23:40AM -0700, Michael Chan wrote:
> A non-IOMMU system using 64-bit dma_addr_t will always set
> CONFIG_HIGHMEM, right?

No. 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02 15:23     ` Michael Chan
  2007-05-02 15:28       ` Christoph Hellwig
@ 2007-05-02 15:29       ` Jeff Garzik
  2007-05-02 18:23         ` Michael Chan
  2007-05-02 19:40       ` David Miller
  2 siblings, 1 reply; 17+ messages in thread
From: Jeff Garzik @ 2007-05-02 15:29 UTC (permalink / raw)
  To: Michael Chan; +Cc: David Miller, netdev

Michael Chan wrote:
> A non-IOMMU system using 64-bit dma_addr_t will always set
> CONFIG_HIGHMEM, right?

No.

	Jeff




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02 15:29       ` Jeff Garzik
@ 2007-05-02 18:23         ` Michael Chan
  2007-05-02 18:24           ` Jeff Garzik
  0 siblings, 1 reply; 17+ messages in thread
From: Michael Chan @ 2007-05-02 18:23 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: David Miller, netdev

On Wed, 2007-05-02 at 11:29 -0400, Jeff Garzik wrote:
> Michael Chan wrote:
> > A non-IOMMU system using 64-bit dma_addr_t will always set
> > CONFIG_HIGHMEM, right?
> 
> No.
> 
May be I misunderstood the code in illegal_highdma() in net/core/dev.c
where it is checking to see if it needs to linearize the SKB when the
device does not support 64-bit DMA.  I'm using similar assumptions for
the 40-bit address check in the patch.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02 18:23         ` Michael Chan
@ 2007-05-02 18:24           ` Jeff Garzik
  2007-05-02 20:02             ` Michael Chan
  0 siblings, 1 reply; 17+ messages in thread
From: Jeff Garzik @ 2007-05-02 18:24 UTC (permalink / raw)
  To: Michael Chan; +Cc: David Miller, netdev

Michael Chan wrote:
> On Wed, 2007-05-02 at 11:29 -0400, Jeff Garzik wrote:
>> Michael Chan wrote:
>>> A non-IOMMU system using 64-bit dma_addr_t will always set
>>> CONFIG_HIGHMEM, right?
>> No.
>>
> May be I misunderstood the code in illegal_highdma() in net/core/dev.c
> where it is checking to see if it needs to linearize the SKB when the
> device does not support 64-bit DMA.  I'm using similar assumptions for
> the 40-bit address check in the patch.

That function is just checking for highmem pages, no more, no less.

Your question quoted far above presumes that no 64-bit systems exist 
lacking IOMMUs, which is not the case.  64-bit platforms with a 64-bit 
dma_addr_t will /not/ set CONFIG_HIGHMEM, regardless of IOMMU presence.

Probably you want to base your actions on some combination of

* CONFIG_64BIT
* sizeof(dma_addr_t)
* pci_set_dma_mask() for >32 bit platforms

Regards,

	Jeff




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02 15:23     ` Michael Chan
  2007-05-02 15:28       ` Christoph Hellwig
  2007-05-02 15:29       ` Jeff Garzik
@ 2007-05-02 19:40       ` David Miller
  2007-05-02 21:27         ` Michael Chan
  2 siblings, 1 reply; 17+ messages in thread
From: David Miller @ 2007-05-02 19:40 UTC (permalink / raw)
  To: mchan; +Cc: jeff, netdev

From: "Michael Chan" <mchan@broadcom.com>
Date: Wed, 2 May 2007 08:23:40 -0700

> A non-IOMMU system using 64-bit dma_addr_t will always set
> CONFIG_HIGHMEM, right?

Nope, IA-64 is at least one example.

IA-64 has both IOMMU and non-IOMMU configurations, and
never sets HIGHMEM.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02 18:24           ` Jeff Garzik
@ 2007-05-02 20:02             ` Michael Chan
  2007-05-02 20:30               ` Jeff Garzik
  2007-05-02 22:48               ` Christoph Hellwig
  0 siblings, 2 replies; 17+ messages in thread
From: Michael Chan @ 2007-05-02 20:02 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: David Miller, netdev

On Wed, 2007-05-02 at 14:24 -0400, Jeff Garzik wrote:
> Michael Chan wrote:
> > On Wed, 2007-05-02 at 11:29 -0400, Jeff Garzik wrote:
> >> Michael Chan wrote:
> >>> A non-IOMMU system using 64-bit dma_addr_t will always set
> >>> CONFIG_HIGHMEM, right?
> >> No.
> >>
> > May be I misunderstood the code in illegal_highdma() in net/core/dev.c
> > where it is checking to see if it needs to linearize the SKB when the
> > device does not support 64-bit DMA.  I'm using similar assumptions for
> > the 40-bit address check in the patch.
> 
> That function is just checking for highmem pages, no more, no less.
> 

Let's say I have a 32-bit card that cannot do dual address cycle on a
64-bit dma_addr_t system without IOMMU.  If CONFIG_HIGHMEM is not set,
wouldn't the device get > 32-bit DMA addresses that it cannot handle?

> Your question quoted far above presumes that no 64-bit systems exist 
> lacking IOMMUs, which is not the case.  64-bit platforms with a 64-bit 
> dma_addr_t will /not/ set CONFIG_HIGHMEM, regardless of IOMMU presence.

I know that there are 64-bit systems without IOMMUs.  That's why we need
the workaround code.  Otherwise we can always just set the DMA mask to
40-bit and let the IOMMU handle the translation.  I'm trying to come up
with the right conditions to determine whether the address checking is
needed or not.  These systems without IOMMU must support 32-bit only
cards, right?  How do they do that if they are not using CONFIG_HIGHMEM?

> 
> Probably you want to base your actions on some combination of
> 
> * CONFIG_64BIT
> * sizeof(dma_addr_t)
> * pci_set_dma_mask() for >32 bit platforms
> 

Sure I can use these if CONFIG_HIGHMEM is not right.




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02 20:02             ` Michael Chan
@ 2007-05-02 20:30               ` Jeff Garzik
  2007-05-02 22:48               ` Christoph Hellwig
  1 sibling, 0 replies; 17+ messages in thread
From: Jeff Garzik @ 2007-05-02 20:30 UTC (permalink / raw)
  To: Michael Chan; +Cc: David Miller, netdev

Michael Chan wrote:
> If CONFIG_HIGHMEM is not set,
> wouldn't the device get > 32-bit DMA addresses that it cannot handle?

No -- presuming your PCI device's DMA mask is set correctly.


> I know that there are 64-bit systems without IOMMUs.  That's why we need
[...]
> needed or not.  These systems without IOMMU must support 32-bit only
> cards, right?  How do they do that if they are not using CONFIG_HIGHMEM?

pci_set_dma_mask()

	Jeff



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02 19:40       ` David Miller
@ 2007-05-02 21:27         ` Michael Chan
  2007-05-02 21:45           ` David Miller
  0 siblings, 1 reply; 17+ messages in thread
From: Michael Chan @ 2007-05-02 21:27 UTC (permalink / raw)
  To: David Miller; +Cc: jeff, netdev

On Wed, 2007-05-02 at 12:40 -0700, David Miller wrote:
> From: "Michael Chan" <mchan@broadcom.com>
> Date: Wed, 2 May 2007 08:23:40 -0700
> 
> > A non-IOMMU system using 64-bit dma_addr_t will always set
> > CONFIG_HIGHMEM, right?
> 
> Nope, IA-64 is at least one example.
> 
> IA-64 has both IOMMU and non-IOMMU configurations, and
> never sets HIGHMEM.
> 

I see.  So IA64 always uses the SWIOTLB when it doesn't have IOMMU then?

I'm a bit confused.  Is it enough to just set the DMA mask to 40-bit and
forget about all this checking?  I thought that wasn't enough.  A tx
packet can be anywhere in 64-bit memory.  When it gets to the driver,
pci_map will not do any translation even if DMA mask is set to 40-bit if
it doesn't have IOMMU.  Is that right?


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02 21:27         ` Michael Chan
@ 2007-05-02 21:45           ` David Miller
  2007-05-02 23:28             ` Michael Chan
  0 siblings, 1 reply; 17+ messages in thread
From: David Miller @ 2007-05-02 21:45 UTC (permalink / raw)
  To: mchan; +Cc: jeff, netdev

From: "Michael Chan" <mchan@broadcom.com>
Date: Wed, 02 May 2007 14:27:49 -0700

> I see.  So IA64 always uses the SWIOTLB when it doesn't have IOMMU then?
> 
> I'm a bit confused.  Is it enough to just set the DMA mask to 40-bit and
> forget about all this checking?  I thought that wasn't enough.  A tx
> packet can be anywhere in 64-bit memory.  When it gets to the driver,
> pci_map will not do any translation even if DMA mask is set to 40-bit if
> it doesn't have IOMMU.  Is that right?

If the buffer doesn't meet the DMA mask specification, it should do
bounce buffering.

Have a look at lib/swiotlb.c, that is exactly what it appears to
be doing.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02 23:28             ` Michael Chan
@ 2007-05-02 22:48               ` David Miller
  0 siblings, 0 replies; 17+ messages in thread
From: David Miller @ 2007-05-02 22:48 UTC (permalink / raw)
  To: mchan; +Cc: jeff, netdev

From: "Michael Chan" <mchan@broadcom.com>
Date: Wed, 02 May 2007 16:28:22 -0700

> Is it correct to assume that all 64-bit systems using 64-bit
> dma_addr_t will either have real IOMMUs or will use SWIOTLB?  If
> this is true, we can just set the DMA mask to what is supported by
> the hardware and let pci_map_xxx() handle all necessary translations
> or bounce buffering.

This should work.

Especailly since every platform has to support 32-bit DMA masks, the
worst possible case is that the 40-bit DMA mask set fails, and you
have to fall back to 32-bit.

But since every driver has that fallback logic, it should be totally
transparent.

We might want to formalize that at some point to save driver code.
Ie. we'd have an interface that takes a prioritized array of DMA
masks the driver wants to use, and you get back the index that was
selected or an error if none of them could be accomodated.

It's just a tangental future cleanup idea, since we're discussing
this.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02 20:02             ` Michael Chan
  2007-05-02 20:30               ` Jeff Garzik
@ 2007-05-02 22:48               ` Christoph Hellwig
  2007-05-02 22:50                 ` David Miller
  1 sibling, 1 reply; 17+ messages in thread
From: Christoph Hellwig @ 2007-05-02 22:48 UTC (permalink / raw)
  To: Michael Chan; +Cc: Jeff Garzik, David Miller, netdev

On Wed, May 02, 2007 at 01:02:41PM -0700, Michael Chan wrote:
> Let's say I have a 32-bit card that cannot do dual address cycle on a
> 64-bit dma_addr_t system without IOMMU.  If CONFIG_HIGHMEM is not set,
> wouldn't the device get > 32-bit DMA addresses that it cannot handle?

It needs to set it's dma mask to 32bits and the upper layers (net, block)
will do the bouncing for it.  


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02 22:48               ` Christoph Hellwig
@ 2007-05-02 22:50                 ` David Miller
  0 siblings, 0 replies; 17+ messages in thread
From: David Miller @ 2007-05-02 22:50 UTC (permalink / raw)
  To: hch; +Cc: mchan, jeff, netdev

From: Christoph Hellwig <hch@infradead.org>
Date: Wed, 2 May 2007 23:48:58 +0100

> On Wed, May 02, 2007 at 01:02:41PM -0700, Michael Chan wrote:
> > Let's say I have a 32-bit card that cannot do dual address cycle on a
> > 64-bit dma_addr_t system without IOMMU.  If CONFIG_HIGHMEM is not set,
> > wouldn't the device get > 32-bit DMA addresses that it cannot handle?
> 
> It needs to set it's dma mask to 32bits and the upper layers (net, block)
> will do the bouncing for it.  

Not the case for networking, we rely upon the DMA API to take
care of things, which it does.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708.
  2007-05-02 21:45           ` David Miller
@ 2007-05-02 23:28             ` Michael Chan
  2007-05-02 22:48               ` David Miller
  0 siblings, 1 reply; 17+ messages in thread
From: Michael Chan @ 2007-05-02 23:28 UTC (permalink / raw)
  To: David Miller; +Cc: jeff, netdev

On Wed, 2007-05-02 at 14:45 -0700, David Miller wrote:
> From: "Michael Chan" <mchan@broadcom.com>
> Date: Wed, 02 May 2007 14:27:49 -0700
> 
> > I see.  So IA64 always uses the SWIOTLB when it doesn't have IOMMU then?
> > 
> > I'm a bit confused.  Is it enough to just set the DMA mask to 40-bit and
> > forget about all this checking?  I thought that wasn't enough.  A tx
> > packet can be anywhere in 64-bit memory.  When it gets to the driver,
> > pci_map will not do any translation even if DMA mask is set to 40-bit if
> > it doesn't have IOMMU.  Is that right?
> 
> If the buffer doesn't meet the DMA mask specification, it should do
> bounce buffering.
> 
> Have a look at lib/swiotlb.c, that is exactly what it appears to
> be doing.
> 

OK.  Is it correct to assume that all 64-bit systems using 64-bit
dma_addr_t will either have real IOMMUs or will use SWIOTLB?  If this is
true, we can just set the DMA mask to what is supported by the hardware
and let pci_map_xxx() handle all necessary translations or bounce
buffering.


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2007-05-02 22:50 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-02  1:13 [PATCH 3/20][BNX2]: Add 40-bit DMA workaround for 5708 Michael Chan
2007-05-02  7:06 ` Jeff Garzik
2007-05-02  7:12   ` David Miller
2007-05-02 15:23     ` Michael Chan
2007-05-02 15:28       ` Christoph Hellwig
2007-05-02 15:29       ` Jeff Garzik
2007-05-02 18:23         ` Michael Chan
2007-05-02 18:24           ` Jeff Garzik
2007-05-02 20:02             ` Michael Chan
2007-05-02 20:30               ` Jeff Garzik
2007-05-02 22:48               ` Christoph Hellwig
2007-05-02 22:50                 ` David Miller
2007-05-02 19:40       ` David Miller
2007-05-02 21:27         ` Michael Chan
2007-05-02 21:45           ` David Miller
2007-05-02 23:28             ` Michael Chan
2007-05-02 22:48               ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).