<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>