This patch defines some parameters and creates a couple of APIs and  for UD RX 
S/G to be used later.

Signed-off-by: Shirley Ma <[EMAIL PROTECTED]>
---

 drivers/infiniband/ulp/ipoib/ipoib.h |   48 ++++++++++++++++++++++++++++++++++
 1 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h 
b/drivers/infiniband/ulp/ipoib/ipoib.h
index f9b7caa..73a8fe5 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -61,6 +61,10 @@ enum {
 
        IPOIB_ENCAP_LEN           = 4,
 
+       IPOIB_UD_MAX_PAYLOAD      = 4096,
+       IPOIB_UD_HEAD_SIZE        = IB_GRH_BYTES + IPOIB_ENCAP_LEN,
+       IPOIB_UD_RX_SG            = (IPOIB_UD_MAX_PAYLOAD + IB_GRH_BYTES) / 
PAGE_SIZE,
+
        IPOIB_CM_MTU              = 0x10000 - 0x10, /* padding to align header 
to 16 */
        IPOIB_CM_BUF_SIZE         = IPOIB_CM_MTU  + IPOIB_ENCAP_LEN,
        IPOIB_CM_HEAD_SIZE        = IPOIB_CM_BUF_SIZE % PAGE_SIZE,
@@ -141,6 +145,11 @@ struct ipoib_rx_buf {
        u64             mapping;
 };
 
+struct ipoib_ud_rx_buf {
+       struct sk_buff *skb;
+       u64             mapping[IPOIB_UD_RX_SG];
+};
+
 struct ipoib_tx_buf {
        struct sk_buff *skb;
        u64             mapping[MAX_SKB_FRAGS + 1];
@@ -289,6 +298,7 @@ struct ipoib_dev_priv {
 
        unsigned int admin_mtu;
        unsigned int mcast_mtu;
+       unsigned int max_ib_mtu;
 
        struct ipoib_rx_buf *rx_ring;
 
@@ -359,6 +369,44 @@ struct ipoib_neigh {
        struct list_head    list;
 };
 
+#define IPOIB_UD_MTU(ib_mtu)           (ib_mtu - IPOIB_ENCAP_LEN)
+#define IPOIB_UD_BUF_SIZE(ib_mtu)      (ib_mtu + IB_GRH_BYTES)
+
+static inline int ipoib_ud_need_sg(unsigned int ib_mtu)
+{
+       return (IPOIB_UD_BUF_SIZE(ib_mtu) > PAGE_SIZE) ? 1 : 0;
+}
+
+static inline void ipoib_ud_dma_unmap_rx(struct ipoib_dev_priv *priv,
+                                        u64 mapping[IPOIB_UD_RX_SG])
+{
+       if (ipoib_ud_need_sg(priv->max_ib_mtu)) {
+               ib_dma_unmap_single(priv->ca, mapping[0], IPOIB_UD_HEAD_SIZE, 
DMA_FROM_DEVICE);
+               ib_dma_unmap_page(priv->ca, mapping[1], PAGE_SIZE, 
DMA_FROM_DEVICE);
+       } else
+               ib_dma_unmap_single(priv->ca, mapping[0], 
IPOIB_UD_BUF_SIZE(priv->max_ib_mtu), DMA_FROM_DEVICE);
+}
+
+static inline void ipoib_ud_skb_put_frags(struct ipoib_dev_priv *priv,
+                                         struct sk_buff *skb,
+                                         unsigned int length)
+{
+       if (ipoib_ud_need_sg(priv->max_ib_mtu)) {
+               skb_frag_t *frag = &skb_shinfo(skb)->frags[0];
+               /*
+                * There is only two buffers needed for max_payload = 4K,
+                * first buf size is IPOIB_UD_HEAD_SIZE
+                */
+               skb->tail += IPOIB_UD_HEAD_SIZE;
+               frag->size = length - IPOIB_UD_HEAD_SIZE;
+               skb->data_len += frag->size;
+               skb->truesize += frag->size;
+               skb->len += length;
+       } else
+               skb_put(skb, length);
+
+}
+
 /*
  * We stash a pointer to our private neighbour information after our
  * hardware address in neigh->ha.  The ALIGN() expression here makes


_______________________________________________
ewg mailing list
ewg@lists.openfabrics.org
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ewg

Reply via email to