<html><body>
<p>My unix mail is down. Here is the new update one.  I need to resend this one when my unix mail back.<br>
<br>
Signed-off-by: Shirley Ma <xma@us.ibm.com><br>
---<br>
<br>
 drivers/infiniband/ulp/ipoib/ipoib.h           |   13 +++++++++++++<br>
 drivers/infiniband/ulp/ipoib/ipoib_main.c      |   19 ++++++++++++++-----<br>
 drivers/infiniband/ulp/ipoib/ipoib_multicast.c |    3 +--<br>
 drivers/infiniband/ulp/ipoib/ipoib_verbs.c     |   14 ++++++++++++--<br>
 4 files changed, 40 insertions(+), 9 deletions(-)<br>
<br>
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h<br>
index d1d3ca2..004a80b 100644<br>
--- a/drivers/infiniband/ulp/ipoib/ipoib.h<br>
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h<br>
@@ -61,6 +61,10 @@ enum {<br>
 <br>
        IPOIB_ENCAP_LEN           = 4,<br>
 <br>
+       IPOIB_MAX_IB_MTU          = 4096,<br>
+       IPOIB_UD_MAX_RX_SG        = ALIGN(IPOIB_MAX_IB_MTU + IB_GRH_BYTES + 4,<br>
+                                         PAGE_SIZE) / PAGE_SIZE,  /* padding to align IP header */<br>
+<br>
        IPOIB_CM_MTU              = 0x10000 - 0x10, /* padding to align header to 16 */<br>
        IPOIB_CM_BUF_SIZE         = IPOIB_CM_MTU  + IPOIB_ENCAP_LEN,<br>
        IPOIB_CM_HEAD_SIZE        = IPOIB_CM_BUF_SIZE % PAGE_SIZE,<br>
@@ -319,6 +323,9 @@ struct ipoib_dev_priv {<br>
        struct dentry *mcg_dentry;<br>
        struct dentry *path_dentry;<br>
 #endif<br>
+       int max_ib_mtu;<br>
+       struct ib_sge rx_sge[IPOIB_UD_MAX_RX_SG];<br>
+       struct ib_recv_wr rx_wr;<br>
 };<br>
 <br>
 struct ipoib_ah {<br>
@@ -359,6 +366,12 @@ struct ipoib_neigh {<br>
        struct list_head    list;<br>
 };<br>
 <br>
+#define IPOIB_UD_MTU(ib_mtu)           (ib_mtu - IPOIB_ENCAP_LEN)<br>
+/* padding to align IP header */ <br>
+#define IPOIB_UD_BUF_SIZE(ib_mtu)      (ib_mtu + IB_GRH_BYTES + 4) <br>
+#define IPOIB_UD_HEAD_SIZE(ib_mtu)     (IPOIB_UD_BUF_SIZE(ib_mtu)) % PAGE_SIZE<br>
+#define IPOIB_UD_RX_SG(ib_mtu)         ALIGN(IPOIB_UD_BUF_SIZE(ib_mtu), PAGE_SIZE) / PAGE_SIZE<br>
+<br>
 /*<br>
  * We stash a pointer to our private neighbour information after our<br>
  * hardware address in neigh->ha.  The ALIGN() expression here makes<br>
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c<br>
index a082466..242591f 100644<br>
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c<br>
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c<br>
@@ -194,7 +194,7 @@ static int ipoib_change_mtu(struct net_device *dev, int new_mtu)<br>
                return 0;<br>
        }<br>
 <br>
-       if (new_mtu > IPOIB_PACKET_SIZE - IPOIB_ENCAP_LEN)<br>
+       if (new_mtu > IPOIB_UD_MTU(priv->max_ib_mtu))<br>
                return -EINVAL;<br>
 <br>
        priv->admin_mtu = new_mtu;<br>
@@ -968,10 +968,6 @@ static void ipoib_setup(struct net_device *dev)<br>
        dev->tx_queue_len     = ipoib_sendq_size * 2;<br>
        dev->features                 = NETIF_F_VLAN_CHALLENGED | NETIF_F_LLTX;<br>
 <br>
-       /* MTU will be reset when mcast join happens */<br>
-       dev->mtu              = IPOIB_PACKET_SIZE - IPOIB_ENCAP_LEN;<br>
-       priv->mcast_mtu               = priv->admin_mtu = dev->mtu;<br>
-<br>
        memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN);<br>
 <br>
        netif_carrier_off(dev);<br>
@@ -1103,6 +1099,7 @@ static struct net_device *ipoib_add_port(const char *format,<br>
                                         struct ib_device *hca, u8 port)<br>
 {<br>
        struct ipoib_dev_priv *priv;<br>
+       struct ib_port_attr attr;<br>
        int result = -ENOMEM;<br>
 <br>
        priv = ipoib_intf_alloc(format);<br>
@@ -1111,6 +1108,18 @@ static struct net_device *ipoib_add_port(const char *format,<br>
 <br>
        SET_NETDEV_DEV(priv->dev, hca->dma_device);<br>
 <br>
+       if (!ib_query_port(hca, port, &attr))<br>
+               priv->max_ib_mtu = ib_mtu_enum_to_int(attr.max_mtu);<br>
+       else {<br>
+               printk(KERN_WARNING "%s: ib_query_port %d failed\n",<br>
+                      hca->name, port);<br>
+               goto device_init_failed;<br>
+       }<br>
+<br>
+       /* MTU will be reset when mcast join happens */<br>
+       priv->dev->mtu  = IPOIB_UD_MTU(priv->max_ib_mtu);<br>
+       priv->mcast_mtu  = priv->admin_mtu = priv->dev->mtu;<br>
+<br>
        result = ib_query_pkey(hca, port, 0, &priv->pkey);<br>
        if (result) {<br>
                printk(KERN_WARNING "%s: ib_query_pkey port %d failed (ret = %d)\n",<br>
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c<br>
index 2628339..630b429 100644<br>
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c<br>
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c<br>
@@ -567,8 +567,7 @@ void ipoib_mcast_join_task(struct work_struct *work)<br>
                return;<br>
        }<br>
 <br>
-       priv->mcast_mtu = ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu) -<br>
-               IPOIB_ENCAP_LEN;<br>
+       priv->mcast_mtu = IPOIB_UD_MTU(ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu));<br>
 <br>
        if (!ipoib_cm_admin_enabled(dev))<br>
                dev->mtu = min(priv->mcast_mtu, priv->admin_mtu);<br>
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c<br>
index 433e99a..7e2d4d6 100644<br>
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c<br>
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c<br>
@@ -150,13 +150,13 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)<br>
                        .max_send_wr  = ipoib_sendq_size,<br>
                        .max_recv_wr  = ipoib_recvq_size,<br>
                        .max_send_sge = 1,<br>
-                       .max_recv_sge = 1<br>
+                       .max_recv_sge = IPOIB_UD_RX_SG(priv->max_ib_mtu) <br>
                },<br>
                .sq_sig_type = IB_SIGNAL_ALL_WR,<br>
                .qp_type     = IB_QPT_UD<br>
        };<br>
 <br>
-       int ret, size;<br>
+       int ret, size, i;<br>
 <br>
        priv->pd = ib_alloc_pd(priv->ca);<br>
        if (IS_ERR(priv->pd)) {<br>
@@ -208,6 +208,16 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)<br>
        priv->tx_wr.num_sge  = 1;<br>
        priv->tx_wr.send_flags       = IB_SEND_SIGNALED;<br>
 <br>
+       priv->rx_sge[0].length = IPOIB_UD_HEAD_SIZE(priv->max_ib_mtu);<br>
+       priv->rx_sge[0].lkey = priv->mr->lkey;<br>
+       for (i = 1; i < IPOIB_UD_RX_SG(priv->max_ib_mtu); ++i) {<br>
+               priv->rx_sge[i].length = PAGE_SIZE;<br>
+               priv->rx_sge[i].lkey = priv->mr->lkey;<br>
+       }<br>
+       priv->rx_wr.num_sge = IPOIB_UD_RX_SG(priv->max_ib_mtu);<br>
+       priv->rx_wr.next = NULL;<br>
+       priv->rx_wr.sg_list = priv->rx_sge;<br>
+<br>
        return 0;<br>
 <br>
 out_free_cq:<br>
<br>
<i>(See attached file: ipoib-4kmtu-ud-set.patch)</i><br>
<br>
Thanks<br>
Shirley </body></html>