[openib-general] [PATCH] [MAD] API changes and updates to support RMPP
Sean Hefty
mshefty at ichips.intel.com
Mon Mar 14 16:22:58 PST 2005
This patch updates the MAD API to help provide support for the RMPP
implementation and clients. Notable changes:
* A valid memory region (MR) is returned as part of the mad_agent
registration process. The agent, CM, and SA query modules were
updated to use the returned MR.
* A list_head structure was added to ib_mad_recv_wc to make walking
the list of received MAD buffers easier. As part of this change, a
bug was fixed where freed memory could have been accessed in
ib_free_recv_mad() if RMPP were enabled. This change is unlikely
to affect existing clients.
Please respond with any comments. The received RMPP support code* is
currently dependent on these changes.
Signed-off-by: Sean Hefty <sean.hefty at intel.com>
*not included, some assembly required...
Index: core/agent.c
===================================================================
--- core/agent.c (revision 1964)
+++ core/agent.c (working copy)
@@ -135,7 +135,7 @@ static int agent_mad_send(struct ib_mad_
sizeof(mad_priv->mad),
DMA_TO_DEVICE);
gather_list.length = sizeof(mad_priv->mad);
- gather_list.lkey = (*port_priv->mr).lkey;
+ gather_list.lkey = mad_agent->mr->lkey;
send_wr.next = NULL;
send_wr.opcode = IB_WR_SEND;
@@ -324,22 +324,12 @@ int ib_agent_port_open(struct ib_device
goto error3;
}
- port_priv->mr = ib_get_dma_mr(port_priv->smp_agent->qp->pd,
- IB_ACCESS_LOCAL_WRITE);
- if (IS_ERR(port_priv->mr)) {
- printk(KERN_ERR SPFX "Couldn't get DMA MR\n");
- ret = PTR_ERR(port_priv->mr);
- goto error4;
- }
-
spin_lock_irqsave(&ib_agent_port_list_lock, flags);
list_add_tail(&port_priv->port_list, &ib_agent_port_list);
spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
return 0;
-error4:
- ib_unregister_mad_agent(port_priv->perf_mgmt_agent);
error3:
ib_unregister_mad_agent(port_priv->smp_agent);
error2:
@@ -363,8 +353,6 @@ int ib_agent_port_close(struct ib_device
list_del(&port_priv->port_list);
spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
- ib_dereg_mr(port_priv->mr);
-
ib_unregister_mad_agent(port_priv->perf_mgmt_agent);
ib_unregister_mad_agent(port_priv->smp_agent);
kfree(port_priv);
Index: core/cm.c
===================================================================
--- core/cm.c (revision 1977)
+++ core/cm.c (working copy)
@@ -75,7 +75,6 @@ static struct ib_cm {
struct cm_port {
struct cm_device *cm_dev;
struct ib_mad_agent *mad_agent;
- struct ib_mr *mr;
u8 port_num;
};
@@ -191,7 +190,7 @@ static int cm_alloc_msg(struct cm_id_pri
DMA_TO_DEVICE);
pci_unmap_addr_set(m, mapping, m->sge.addr);
m->sge.length = sizeof m->mad;
- m->sge.lkey = cm_id_priv->av.port->mr->lkey;
+ m->sge.lkey = cm_id_priv->av.port->mad_agent->mr->lkey;
m->send_wr.wr_id = (unsigned long) m;
m->send_wr.sg_list = &m->sge;
@@ -2970,14 +2969,9 @@ static void cm_add_one(struct ib_device
if (IS_ERR(port->mad_agent))
goto error2;
- port->mr = ib_get_dma_mr(port->mad_agent->qp->pd,
- IB_ACCESS_LOCAL_WRITE);
- if (IS_ERR(port->mr))
- goto error3;
-
ret = ib_modify_port(device, i, 0, &port_modify);
if (ret)
- goto error4;
+ goto error3;
}
ib_set_client_data(device, &cm_client, cm_dev);
@@ -2986,15 +2980,13 @@ static void cm_add_one(struct ib_device
write_unlock_irqrestore(&cm.device_lock, flags);
return;
-error4:
- ib_dereg_mr(port->mr);
error3:
ib_unregister_mad_agent(port->mad_agent);
error2:
port_modify.set_port_cap_mask = 0;
port_modify.clr_port_cap_mask = IB_PORT_CM_SUP;
while (--i) {
- port = &cm_dev->port[i];
+ port = &cm_dev->port[i-1];
ib_modify_port(device, port->port_num, 0, &port_modify);
ib_unregister_mad_agent(port->mad_agent);
}
@@ -3022,7 +3014,6 @@ static void cm_remove_one(struct ib_devi
for (i = 1; i <= device->phys_port_cnt; i++) {
port = &cm_dev->port[i-1];
- ib_dereg_mr(port->mr);
ib_modify_port(device, port->port_num, 0, &port_modify);
ib_unregister_mad_agent(port->mad_agent);
}
Index: core/mad.c
===================================================================
--- core/mad.c (revision 1980)
+++ core/mad.c (working copy)
@@ -35,8 +35,6 @@
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
-#include <ib_mad.h>
-
#include "mad_priv.h"
#include "smi.h"
#include "agent.h"
@@ -264,22 +262,29 @@ struct ib_mad_agent *ib_register_mad_age
ret = ERR_PTR(-ENOMEM);
goto error1;
}
+ memset(mad_agent_priv, 0, sizeof *mad_agent_priv);
+
+ mad_agent_priv->agent.mr = ib_get_dma_mr(port_priv->qp_info[qpn].qp->pd,
+ IB_ACCESS_LOCAL_WRITE);
+ if (IS_ERR(mad_agent_priv->agent.mr)) {
+ ret = ERR_PTR(-ENOMEM);
+ goto error2;
+ }
if (mad_reg_req) {
reg_req = kmalloc(sizeof *reg_req, GFP_KERNEL);
if (!reg_req) {
ret = ERR_PTR(-ENOMEM);
- goto error2;
+ goto error3;
}
/* Make a copy of the MAD registration request */
memcpy(reg_req, mad_reg_req, sizeof *reg_req);
}
/* Now, fill in the various structures */
- memset(mad_agent_priv, 0, sizeof *mad_agent_priv);
mad_agent_priv->qp_info = &port_priv->qp_info[qpn];
mad_agent_priv->reg_req = reg_req;
- mad_agent_priv->rmpp_version = rmpp_version;
+ mad_agent_priv->agent.rmpp_version = rmpp_version;
mad_agent_priv->agent.device = device;
mad_agent_priv->agent.recv_handler = recv_handler;
mad_agent_priv->agent.send_handler = send_handler;
@@ -304,7 +309,7 @@ struct ib_mad_agent *ib_register_mad_age
if (method) {
if (method_in_use(&method,
mad_reg_req))
- goto error3;
+ goto error4;
}
}
ret2 = add_nonoui_reg_req(mad_reg_req, mad_agent_priv,
@@ -320,14 +325,14 @@ struct ib_mad_agent *ib_register_mad_age
if (is_vendor_method_in_use(
vendor_class,
mad_reg_req))
- goto error3;
+ goto error4;
}
}
ret2 = add_oui_reg_req(mad_reg_req, mad_agent_priv);
}
if (ret2) {
ret = ERR_PTR(ret2);
- goto error3;
+ goto error4;
}
}
@@ -349,11 +354,13 @@ struct ib_mad_agent *ib_register_mad_age
return &mad_agent_priv->agent;
-error3:
+error4:
spin_unlock_irqrestore(&port_priv->reg_lock, flags);
kfree(reg_req);
-error2:
+error3:
kfree(mad_agent_priv);
+error2:
+ ib_dereg_mr(mad_agent_priv->agent.mr);
error1:
return ret;
}
@@ -490,18 +497,16 @@ static void unregister_mad_agent(struct
* MADs, preventing us from queuing additional work
*/
cancel_mads(mad_agent_priv);
-
port_priv = mad_agent_priv->qp_info->port_priv;
-
cancel_delayed_work(&mad_agent_priv->timed_work);
- flush_workqueue(port_priv->wq);
spin_lock_irqsave(&port_priv->reg_lock, flags);
remove_mad_reg_req(mad_agent_priv);
list_del(&mad_agent_priv->agent_list);
spin_unlock_irqrestore(&port_priv->reg_lock, flags);
- /* XXX: Cleanup pending RMPP receives for this agent */
+ flush_workqueue(port_priv->wq);
+ /* ib_cancel_rmpp_recvs(mad_agent_priv); */
atomic_dec(&mad_agent_priv->refcount);
wait_event(mad_agent_priv->wait,
@@ -509,6 +514,7 @@ static void unregister_mad_agent(struct
if (mad_agent_priv->reg_req)
kfree(mad_agent_priv->reg_req);
+ ib_dereg_mr(mad_agent_priv->agent.mr);
kfree(mad_agent_priv);
}
@@ -757,7 +763,7 @@ static int handle_outgoing_dr_smp(struct
list_add_tail(&local->completion_list, &mad_agent_priv->local_list);
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
queue_work(mad_agent_priv->qp_info->port_priv->wq,
- &mad_agent_priv->local_work);
+ &mad_agent_priv->local_work);
ret = 1;
out:
return ret;
@@ -919,31 +925,33 @@ EXPORT_SYMBOL(ib_post_send_mad);
*/
void ib_free_recv_mad(struct ib_mad_recv_wc *mad_recv_wc)
{
- struct ib_mad_recv_buf *entry;
+ struct ib_mad_recv_buf *mad_recv_buf, *temp_recv_buf;
struct ib_mad_private_header *mad_priv_hdr;
struct ib_mad_private *priv;
+ struct list_head free_list;
- mad_priv_hdr = container_of(mad_recv_wc,
- struct ib_mad_private_header,
- recv_wc);
- priv = container_of(mad_priv_hdr, struct ib_mad_private, header);
-
- /*
- * Walk receive buffer list associated with this WC
- * No need to remove them from list of receive buffers
- */
- list_for_each_entry(entry, &mad_recv_wc->recv_buf.list, list) {
- /* Free previous receive buffer */
- kmem_cache_free(ib_mad_cache, priv);
+ if (mad_recv_wc->mad_len <= sizeof(struct ib_mad)) {
mad_priv_hdr = container_of(mad_recv_wc,
struct ib_mad_private_header,
recv_wc);
priv = container_of(mad_priv_hdr, struct ib_mad_private,
header);
- }
+ kmem_cache_free(ib_mad_cache, priv);
+ } else {
+ INIT_LIST_HEAD(&free_list);
+ list_splice_init(&mad_recv_wc->rmpp_list, &free_list);
- /* Free last buffer */
- kmem_cache_free(ib_mad_cache, priv);
+ list_for_each_entry_safe(mad_recv_buf, temp_recv_buf,
+ &free_list, list) {
+ mad_priv_hdr = container_of(mad_recv_wc,
+ struct ib_mad_private_header,
+ recv_wc);
+ priv = container_of(mad_priv_hdr,
+ struct ib_mad_private,
+ header);
+ kmem_cache_free(ib_mad_cache, priv);
+ }
+ }
}
EXPORT_SYMBOL(ib_free_recv_mad);
@@ -1486,16 +1494,19 @@ out:
return valid;
}
-/*
- * Return start of fully reassembled MAD, or NULL, if MAD isn't assembled yet
- */
-static struct ib_mad_private *
-reassemble_recv(struct ib_mad_agent_private *mad_agent_priv,
- struct ib_mad_private *recv)
-{
- /* Until we have RMPP, all receives are reassembled!... */
- INIT_LIST_HEAD(&recv->header.recv_wc.recv_buf.list);
- return recv;
+static struct ib_mad_recv_wc *
+process_recv(struct ib_mad_agent_private *mad_agent_priv,
+ struct ib_mad_recv_wc *mad_recv_wc)
+{
+ INIT_LIST_HEAD(&mad_recv_wc->rmpp_list);
+ list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
+
+ /*
+ if (mad_agent_priv->agent.rmpp_version)
+ return ib_process_rmpp_recv(mad_agent_priv, mad_recv_wc);
+ else
+ */
+ return mad_recv_wc;
}
static struct ib_mad_send_wr_private*
@@ -1526,16 +1537,17 @@ find_send_req(struct ib_mad_agent_privat
}
static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
- struct ib_mad_private *recv,
+ struct ib_mad_recv_wc *mad_recv_wc,
int solicited)
{
struct ib_mad_send_wr_private *mad_send_wr;
struct ib_mad_send_wc mad_send_wc;
unsigned long flags;
+ u64 tid;
- /* Fully reassemble receive before processing */
- recv = reassemble_recv(mad_agent_priv, recv);
- if (!recv) {
+ /* Process the receive before giving it to the user. */
+ mad_recv_wc = process_recv(mad_agent_priv, mad_recv_wc);
+ if (!mad_recv_wc) {
if (atomic_dec_and_test(&mad_agent_priv->refcount))
wake_up(&mad_agent_priv->wait);
return;
@@ -1543,12 +1555,12 @@ static void ib_mad_complete_recv(struct
/* Complete corresponding request */
if (solicited) {
+ tid = mad_recv_wc->recv_buf.mad->mad_hdr.tid;
spin_lock_irqsave(&mad_agent_priv->lock, flags);
- mad_send_wr = find_send_req(mad_agent_priv,
- recv->mad.mad.mad_hdr.tid);
+ mad_send_wr = find_send_req(mad_agent_priv, tid);
if (!mad_send_wr) {
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
- ib_free_recv_mad(&recv->header.recv_wc);
+ ib_free_recv_mad(mad_recv_wc);
if (atomic_dec_and_test(&mad_agent_priv->refcount))
wake_up(&mad_agent_priv->wait);
return;
@@ -1558,10 +1570,9 @@ static void ib_mad_complete_recv(struct
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
/* Defined behavior is to complete response before request */
- recv->header.recv_wc.wc->wr_id = mad_send_wr->wr_id;
- mad_agent_priv->agent.recv_handler(
- &mad_agent_priv->agent,
- &recv->header.recv_wc);
+ mad_recv_wc->wc->wr_id = mad_send_wr->wr_id;
+ mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
+ mad_recv_wc);
atomic_dec(&mad_agent_priv->refcount);
mad_send_wc.status = IB_WC_SUCCESS;
@@ -1569,9 +1580,8 @@ static void ib_mad_complete_recv(struct
mad_send_wc.wr_id = mad_send_wr->wr_id;
ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc);
} else {
- mad_agent_priv->agent.recv_handler(
- &mad_agent_priv->agent,
- &recv->header.recv_wc);
+ mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
+ mad_recv_wc);
if (atomic_dec_and_test(&mad_agent_priv->refcount))
wake_up(&mad_agent_priv->wait);
}
@@ -1675,7 +1685,8 @@ local:
solicited = solicited_mad(&recv->mad.mad);
mad_agent = find_mad_agent(port_priv, &recv->mad.mad, solicited);
if (mad_agent) {
- ib_mad_complete_recv(mad_agent, recv, solicited);
+ ib_mad_complete_recv(mad_agent, &recv->header.recv_wc,
+ solicited);
/*
* recv is freed up in error cases in ib_mad_complete_recv
* or via recv_handler in ib_mad_complete_recv()
@@ -1757,10 +1768,18 @@ static void ib_mad_complete_send_wr(stru
{
struct ib_mad_agent_private *mad_agent_priv;
unsigned long flags;
+ enum ib_mad_result ret;
mad_agent_priv = container_of(mad_send_wr->agent,
struct ib_mad_agent_private, agent);
+ /*
+ if (mad_agent_priv->agent.rmpp_version)
+ ret = process_rmpp_send_wc(mad_send_wr, mad_send_wc);
+ else
+ */
+ ret = IB_MAD_RESULT_SUCCESS;
+
spin_lock_irqsave(&mad_agent_priv->lock, flags);
if (mad_send_wc->status != IB_WC_SUCCESS &&
mad_send_wr->status == IB_WC_SUCCESS) {
@@ -1784,8 +1803,9 @@ static void ib_mad_complete_send_wr(stru
if (mad_send_wr->status != IB_WC_SUCCESS )
mad_send_wc->status = mad_send_wr->status;
- mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
- mad_send_wc);
+ if (ret == IB_MAD_RESULT_SUCCESS)
+ mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
+ mad_send_wc);
/* Release reference on agent taken when sending */
if (atomic_dec_and_test(&mad_agent_priv->refcount))
@@ -2034,8 +2054,7 @@ void cancel_sends(void *data)
&mad_send_wc);
kfree(mad_send_wr);
- if (atomic_dec_and_test(&mad_agent_priv->refcount))
- wake_up(&mad_agent_priv->wait);
+ atomic_dec(&mad_agent_priv->refcount);
spin_lock_irqsave(&mad_agent_priv->lock, flags);
}
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
Index: core/agent_priv.h
===================================================================
--- core/agent_priv.h (revision 1964)
+++ core/agent_priv.h (working copy)
@@ -57,7 +57,6 @@ struct ib_agent_port_private {
int port_num;
struct ib_mad_agent *smp_agent; /* SM class */
struct ib_mad_agent *perf_mgmt_agent; /* PerfMgmt class */
- struct ib_mr *mr;
};
#endif /* __IB_AGENT_PRIV_H__ */
Index: core/mad_priv.h
===================================================================
--- core/mad_priv.h (revision 1980)
+++ core/mad_priv.h (working copy)
@@ -101,7 +101,6 @@ struct ib_mad_agent_private {
atomic_t refcount;
wait_queue_head_t wait;
- u8 rmpp_version;
};
struct ib_mad_snoop_private {
Index: core/sa_query.c
===================================================================
--- core/sa_query.c (revision 1964)
+++ core/sa_query.c (working copy)
@@ -77,7 +77,6 @@ struct ib_sa_sm_ah {
struct ib_sa_port {
struct ib_mad_agent *agent;
- struct ib_mr *mr;
struct ib_sa_sm_ah *sm_ah;
struct work_struct update_task;
spinlock_t ah_lock;
@@ -492,7 +491,7 @@ retry:
sizeof (struct ib_sa_mad),
DMA_TO_DEVICE);
gather_list.length = sizeof (struct ib_sa_mad);
- gather_list.lkey = port->mr->lkey;
+ gather_list.lkey = port->agent->mr->lkey;
pci_unmap_addr_set(query, mapping, gather_list.addr);
ret = ib_post_send_mad(port->agent, &wr, &bad_wr);
@@ -771,7 +770,6 @@ static void ib_sa_add_one(struct ib_devi
sa_dev->end_port = e;
for (i = 0; i <= e - s; ++i) {
- sa_dev->port[i].mr = NULL;
sa_dev->port[i].sm_ah = NULL;
sa_dev->port[i].port_num = i + s;
spin_lock_init(&sa_dev->port[i].ah_lock);
@@ -783,13 +781,6 @@ static void ib_sa_add_one(struct ib_devi
if (IS_ERR(sa_dev->port[i].agent))
goto err;
- sa_dev->port[i].mr = ib_get_dma_mr(sa_dev->port[i].agent->qp->pd,
- IB_ACCESS_LOCAL_WRITE);
- if (IS_ERR(sa_dev->port[i].mr)) {
- ib_unregister_mad_agent(sa_dev->port[i].agent);
- goto err;
- }
-
INIT_WORK(&sa_dev->port[i].update_task,
update_sm_ah, &sa_dev->port[i]);
}
@@ -813,10 +804,8 @@ static void ib_sa_add_one(struct ib_devi
return;
err:
- while (--i >= 0) {
- ib_dereg_mr(sa_dev->port[i].mr);
+ while (--i >= 0)
ib_unregister_mad_agent(sa_dev->port[i].agent);
- }
kfree(sa_dev);
Index: include/ib_mad.h
===================================================================
--- include/ib_mad.h (revision 1964)
+++ include/ib_mad.h (working copy)
@@ -70,9 +70,37 @@
#define IB_MGMT_MAX_METHODS 128
+/* RMPP information */
+#define IB_MGMT_RMPP_VERSION 1
+
+#define IB_MGMT_RMPP_TYPE_DATA 1
+#define IB_MGMT_RMPP_TYPE_ACK 2
+#define IB_MGMT_RMPP_TYPE_STOP 3
+#define IB_MGMT_RMPP_TYPE_ABORT 4
+
+#define IB_MGMT_RMPP_FLAG_ACTIVE 1
+#define IB_MGMT_RMPP_FLAG_FIRST (1<<1)
+#define IB_MGMT_RMPP_FLAG_LAST (1<<2)
+
+#define IB_MGMT_RMPP_NO_RESPTIME 0x1F
+
+#define IB_MGMT_RMPP_STATUS_SUCCESS 0
+#define IB_MGMT_RMPP_STATUS_RESX 1
+#define IB_MGMT_RMPP_STATUS_T2L 118
+#define IB_MGMT_RMPP_STATUS_BAD_LEN 119
+#define IB_MGMT_RMPP_STATUS_BAD_SEG 120
+#define IB_MGMT_RMPP_STATUS_BADT 121
+#define IB_MGMT_RMPP_STATUS_W2S 122
+#define IB_MGMT_RMPP_STATUS_S2B 123
+#define IB_MGMT_RMPP_STATUS_BAD_STATUS 124
+#define IB_MGMT_RMPP_STATUS_UNV 125
+#define IB_MGMT_RMPP_STATUS_TMR 126
+#define IB_MGMT_RMPP_STATUS_UNSPEC 127
+
#define IB_QP0 0
#define IB_QP1 __constant_htonl(1)
#define IB_QP1_QKEY 0x80010000
+#define IB_QP_SET_QKEY 0x80000000
struct ib_grh {
u32 version_tclass_flow;
@@ -124,6 +152,45 @@ struct ib_vendor_mad {
u8 data[216];
} __attribute__ ((packed));
+/**
+ * ib_get_rmpp_resptime - Returns the RMPP response time.
+ * @rmpp_hdr: An RMPP header.
+ */
+static inline u8 ib_get_rmpp_resptime(struct ib_rmpp_hdr *rmpp_hdr)
+{
+ return rmpp_hdr->rmpp_rtime_flags >> 3;
+}
+
+/**
+ * ib_get_rmpp_flags - Returns the RMPP flags.
+ * @rmpp_hdr: An RMPP header.
+ */
+static inline u8 ib_get_rmpp_flags(struct ib_rmpp_hdr *rmpp_hdr)
+{
+ return rmpp_hdr->rmpp_rtime_flags & 0x7;
+}
+
+/**
+ * ib_set_rmpp_resptime - Sets the response time in an RMPP header.
+ * @rmpp_hdr: An RMPP header.
+ * @rtime: The response time to set.
+ */
+static inline void ib_set_rmpp_resptime(struct ib_rmpp_hdr *rmpp_hdr, u8 rtime)
+{
+ rmpp_hdr->rmpp_rtime_flags = ib_get_rmpp_flags(rmpp_hdr) | (rtime << 3);
+}
+
+/**
+ * ib_set_rmpp_flags - Sets the flags in an RMPP header.
+ * @rmpp_hdr: An RMPP header.
+ * @flags: The flags to set.
+ */
+static inline void ib_set_rmpp_flags(struct ib_rmpp_hdr *rmpp_hdr, u8 flags)
+{
+ rmpp_hdr->rmpp_rtime_flags = (rmpp_hdr->rmpp_rtime_flags & 0xF1) |
+ (flags & 0x7);
+}
+
struct ib_mad_agent;
struct ib_mad_send_wc;
struct ib_mad_recv_wc;
@@ -168,6 +235,7 @@ typedef void (*ib_mad_recv_handler)(stru
* ib_mad_agent - Used to track MAD registration with the access layer.
* @device: Reference to device registration is on.
* @qp: Reference to QP used for sending and receiving MADs.
+ * @mr: Memory region for system memory usable for DMA.
* @recv_handler: Callback handler for a received MAD.
* @send_handler: Callback handler for a sent MAD.
* @snoop_handler: Callback handler for snooped sent MADs.
@@ -176,16 +244,19 @@ typedef void (*ib_mad_recv_handler)(stru
* Unsolicited MADs sent by this client will have the upper 32-bits
* of their TID set to this value.
* @port_num: Port number on which QP is registered
+ * @rmpp_version: If set, indicates the RMPP version used by this agent.
*/
struct ib_mad_agent {
struct ib_device *device;
struct ib_qp *qp;
+ struct ib_mr *mr;
ib_mad_recv_handler recv_handler;
ib_mad_send_handler send_handler;
ib_mad_snoop_handler snoop_handler;
void *context;
u32 hi_tid;
u8 port_num;
+ u8 rmpp_version;
};
/**
@@ -219,6 +290,7 @@ struct ib_mad_recv_buf {
* ib_mad_recv_wc - received MAD information.
* @wc: Completion information for the received data.
* @recv_buf: Specifies the location of the received data buffer(s).
+ * @rmpp_list: Specifies a list of RMPP reassembled received MAD buffers.
* @mad_len: The length of the received MAD, without duplicated headers.
*
* For received response, the wr_id field of the wc is set to the wr_id
@@ -227,6 +299,7 @@ struct ib_mad_recv_buf {
struct ib_mad_recv_wc {
struct ib_wc *wc;
struct ib_mad_recv_buf recv_buf;
+ struct list_head rmpp_list;
int mad_len;
};
More information about the general
mailing list