[openib-general] [PATCH] [MAD] changes to ib_create_send_mad

Sean Hefty sean.hefty at intel.com
Wed May 4 17:05:06 PDT 2005


The following patch adds an rmpp_active parameter to
ib_create_send_mad, so it can properly format the RMPP header.
This patch also contains the fix to clear the MAD data buffer.
Additional comments were added regarding RMPP use.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>


Index: include/ib_mad.h
===================================================================
--- include/ib_mad.h	(revision 2256)
+++ include/ib_mad.h	(working copy)
@@ -440,6 +440,16 @@ int ib_unregister_mad_agent(struct ib_ma
  * @bad_send_wr: Specifies the MAD on which an error was encountered.
  *
  * Sent MADs are not guaranteed to complete in the order that they were posted.
+ *
+ * If the MAD requires RMPP, the data buffer should contain a single copy
+ * of the common MAD, RMPP, and class specific headers, followed by the class
+ * defined data.  If the class defined data would not divide evenly into
+ * RMPP segments, then space must be allocated at the end of the referenced
+ * buffer for any required padding.  To indicate the amount of class defined
+ * data being transferred, the paylen_newwin field in the RMPP header should
+ * be set to the size of the class specific header plus the amount of class
+ * defined data being transferred.  The paylen_newwin field should be
+ * specified in network-byte order.
  */
 int ib_post_send_mad(struct ib_mad_agent *mad_agent,
 		     struct ib_send_wr *send_wr,
@@ -452,7 +462,7 @@ int ib_post_send_mad(struct ib_mad_agent
  *   referenced buffer should be at least the size of the mad_len specified
  *   by @mad_recv_wc.
  *
- * This call copies a chain of received RMPP MADs into a single data buffer,
+ * This call copies a chain of received MAD segments into a single data buffer,
  * removing duplicated headers.
  */
 void ib_coalesce_recv_mad(struct ib_mad_recv_wc *mad_recv_wc, void *buf);
@@ -525,6 +535,7 @@ int ib_process_mad_wc(struct ib_mad_agen
  * @pkey_index: Specifies which PKey the MAD will be sent using.  This field
  *   is valid only if the remote_qpn is QP 1.
  * @ah: References the address handle used to transfer to the remote node.
+ * @rmpp_active: Indicates if the send will enable RMPP.
  * @hdr_len: Indicates the size of the data header of the MAD.  This length
  *   should include the common MAD header, RMPP header, plus any class
  *   specific header.
@@ -536,11 +547,16 @@ int ib_process_mad_wc(struct ib_mad_agen
  * This is a helper routine that may be used to allocate a MAD.  Users are
  * not required to allocate outbound MADs using this call.  The returned
  * MAD send buffer will reference a data buffer usable for sending a MAD, along
- * with an initialized work request structure.
+ * with an initialized work request structure.  Users may modify the returned
+ * MAD data buffer or work request before posting the send.
+ *
+ * The returned data buffer will be cleared.  Users are responsible for
+ * initializing the common MAD and any class specific headers.  If @rmpp_active
+ * is set, the RMPP header will be initialized for sending.
  */
 struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
 					    u32 remote_qpn, u16 pkey_index,
-					    struct ib_ah *ah,
+					    struct ib_ah *ah, int rmpp_active,
 					    int hdr_len, int data_len,
 					    int gfp_mask);
 
Index: core/mad.c
===================================================================
--- core/mad.c	(revision 2256)
+++ core/mad.c	(working copy)
@@ -780,7 +780,7 @@ static int get_buf_length(int hdr_len, i
 
 struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
 					    u32 remote_qpn, u16 pkey_index,
-					    struct ib_ah *ah,
+					    struct ib_ah *ah, int rmpp_active,
 					    int hdr_len, int data_len,
 					    int gfp_mask)
 {
@@ -793,12 +793,17 @@ struct ib_mad_send_buf * ib_create_send_
 				      struct ib_mad_agent_private, agent);
 	buf_size = get_buf_length(hdr_len, data_len);
 
+	if ((!mad_agent->rmpp_version &&
+	     (rmpp_active || buf_size > sizeof(struct ib_mad))) ||
+	    (!rmpp_active && buf_size > sizeof(struct ib_mad)))
+		return ERR_PTR(-EINVAL);
+
 	buf = kmalloc(sizeof *send_buf + buf_size, gfp_mask);
 	if (!buf)
 		return ERR_PTR(-ENOMEM);
+	memset(buf, 0, sizeof *send_buf + buf_size);
 
 	send_buf = buf + buf_size;
-	memset(send_buf, 0, sizeof *send_buf);
 	send_buf->mad = buf;
 
 	send_buf->sge.addr = dma_map_single(mad_agent->device->dma_device,
@@ -818,11 +823,15 @@ struct ib_mad_send_buf * ib_create_send_
 	send_buf->send_wr.wr.ud.remote_qkey = IB_QP_SET_QKEY;
 	send_buf->send_wr.wr.ud.pkey_index = pkey_index;
 
-	if (mad_agent->rmpp_version) {
+	if (rmpp_active) {
 		struct ib_rmpp_mad *rmpp_mad;
 		rmpp_mad = (struct ib_rmpp_mad *)send_buf->mad;
 		rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(hdr_len -
 			offsetof(struct ib_rmpp_mad, data) + data_len);
+		rmpp_mad->rmpp_hdr.rmpp_version = mad_agent->rmpp_version;
+		rmpp_mad->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_DATA;
+		ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr,
+				  IB_MGMT_RMPP_FLAG_ACTIVE);
 	}
 
 	send_buf->mad_agent = mad_agent;






More information about the general mailing list