[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