From: Roland Dreier Add parameters to process_mad device method to support full Mellanox firmware capabilities (pass sufficient information for baseboard management trap generation, etc). Signed-off-by: Michael S. Tsirkin Signed-off-by: Roland Dreier Signed-off-by: Andrew Morton --- 25-akpm/drivers/infiniband/core/mad.c | 44 +++++++++++++++--------- 25-akpm/drivers/infiniband/core/sysfs.c | 4 +- 25-akpm/drivers/infiniband/hw/mthca/mthca_dev.h | 3 + 25-akpm/drivers/infiniband/hw/mthca/mthca_mad.c | 4 +- 25-akpm/drivers/infiniband/include/ib_verbs.h | 8 +++- 5 files changed, 42 insertions(+), 21 deletions(-) diff -puN drivers/infiniband/core/mad.c~infiniband-core-add-more-parameters-to-process_mad drivers/infiniband/core/mad.c --- 25/drivers/infiniband/core/mad.c~infiniband-core-add-more-parameters-to-process_mad Wed Jan 12 16:31:56 2005 +++ 25-akpm/drivers/infiniband/core/mad.c Wed Jan 12 16:31:56 2005 @@ -617,6 +617,23 @@ static void snoop_recv(struct ib_mad_qp_ spin_unlock_irqrestore(&qp_info->snoop_lock, flags); } +static void build_smp_wc(u64 wr_id, u16 slid, u16 pkey_index, u8 port_num, + struct ib_wc *wc) +{ + memset(wc, 0, sizeof *wc); + wc->wr_id = wr_id; + wc->status = IB_WC_SUCCESS; + wc->opcode = IB_WC_RECV; + wc->pkey_index = pkey_index; + wc->byte_len = sizeof(struct ib_mad) + sizeof(struct ib_grh); + wc->src_qp = IB_QP0; + wc->qp_num = IB_QP0; + wc->slid = slid; + wc->sl = 0; + wc->dlid_path_bits = 0; + wc->port_num = port_num; +} + /* * Return 0 if SMP is to be sent * Return 1 if SMP was consumed locally (whether or not solicited) @@ -634,6 +651,7 @@ static int handle_outgoing_smp(struct ib struct ib_mad_agent_private *recv_mad_agent = NULL; struct ib_device *device = mad_agent_priv->agent.device; u8 port_num = mad_agent_priv->agent.port_num; + struct ib_wc mad_wc; if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) { ret = -EINVAL; @@ -664,7 +682,12 @@ static int handle_outgoing_smp(struct ib kfree(local); goto out; } - ret = device->process_mad(device, 0, port_num, smp->dr_slid, + + build_smp_wc(send_wr->wr_id, smp->dr_slid, send_wr->wr.ud.pkey_index, + send_wr->wr.ud.port_num, &mad_wc); + + /* No GRH for DR SMP */ + ret = device->process_mad(device, 0, port_num, &mad_wc, NULL, (struct ib_mad *)smp, (struct ib_mad *)&mad_priv->mad); switch (ret) @@ -1621,7 +1644,7 @@ local: ret = port_priv->device->process_mad(port_priv->device, 0, port_priv->port_num, - wc->slid, + wc, &recv->grh, &recv->mad.mad, &response->mad.mad); if (ret & IB_MAD_RESULT_SUCCESS) { @@ -2049,19 +2072,10 @@ static void local_completions(void *data * Defined behavior is to complete response * before request */ - wc.wr_id = local->wr_id; - wc.status = IB_WC_SUCCESS; - wc.opcode = IB_WC_RECV; - wc.vendor_err = 0; - wc.byte_len = sizeof(struct ib_mad) + - sizeof(struct ib_grh); - wc.src_qp = IB_QP0; - wc.wc_flags = 0; /* No GRH */ - wc.pkey_index = 0; - wc.slid = IB_LID_PERMISSIVE; - wc.sl = 0; - wc.dlid_path_bits = 0; - wc.qp_num = IB_QP0; + build_smp_wc(local->wr_id, IB_LID_PERMISSIVE, + 0 /* pkey index */, + recv_mad_agent->agent.port_num, &wc); + local->mad_priv->header.recv_wc.wc = &wc; local->mad_priv->header.recv_wc.mad_len = sizeof(struct ib_mad); diff -puN drivers/infiniband/core/sysfs.c~infiniband-core-add-more-parameters-to-process_mad drivers/infiniband/core/sysfs.c --- 25/drivers/infiniband/core/sysfs.c~infiniband-core-add-more-parameters-to-process_mad Wed Jan 12 16:31:56 2005 +++ 25-akpm/drivers/infiniband/core/sysfs.c Wed Jan 12 16:31:56 2005 @@ -315,8 +315,8 @@ static ssize_t show_pma_counter(struct i in_mad->data[41] = p->port_num; /* PortSelect field */ - if ((p->ibdev->process_mad(p->ibdev, IB_MAD_IGNORE_MKEY, p->port_num, 0xffff, - in_mad, out_mad) & + if ((p->ibdev->process_mad(p->ibdev, IB_MAD_IGNORE_MKEY, + p->port_num, NULL, NULL, in_mad, out_mad) & (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) != (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) { ret = -EINVAL; diff -puN drivers/infiniband/hw/mthca/mthca_dev.h~infiniband-core-add-more-parameters-to-process_mad drivers/infiniband/hw/mthca/mthca_dev.h --- 25/drivers/infiniband/hw/mthca/mthca_dev.h~infiniband-core-add-more-parameters-to-process_mad Wed Jan 12 16:31:56 2005 +++ 25-akpm/drivers/infiniband/hw/mthca/mthca_dev.h Wed Jan 12 16:31:56 2005 @@ -381,7 +381,8 @@ int mthca_multicast_detach(struct ib_qp int mthca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, - u16 slid, + struct ib_wc *in_wc, + struct ib_grh *in_grh, struct ib_mad *in_mad, struct ib_mad *out_mad); int mthca_create_agents(struct mthca_dev *dev); diff -puN drivers/infiniband/hw/mthca/mthca_mad.c~infiniband-core-add-more-parameters-to-process_mad drivers/infiniband/hw/mthca/mthca_mad.c --- 25/drivers/infiniband/hw/mthca/mthca_mad.c~infiniband-core-add-more-parameters-to-process_mad Wed Jan 12 16:31:56 2005 +++ 25-akpm/drivers/infiniband/hw/mthca/mthca_mad.c Wed Jan 12 16:31:56 2005 @@ -185,12 +185,14 @@ static void forward_trap(struct mthca_de int mthca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, - u16 slid, + struct ib_wc *in_wc, + struct ib_grh *in_grh, struct ib_mad *in_mad, struct ib_mad *out_mad) { int err; u8 status; + u16 slid = in_wc ? in_wc->slid : IB_LID_PERMISSIVE; /* Forward locally generated traps to the SM */ if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP && diff -puN drivers/infiniband/include/ib_verbs.h~infiniband-core-add-more-parameters-to-process_mad drivers/infiniband/include/ib_verbs.h --- 25/drivers/infiniband/include/ib_verbs.h~infiniband-core-add-more-parameters-to-process_mad Wed Jan 12 16:31:56 2005 +++ 25-akpm/drivers/infiniband/include/ib_verbs.h Wed Jan 12 16:31:56 2005 @@ -684,9 +684,12 @@ struct ib_fmr { }; struct ib_mad; +struct ib_grh; enum ib_process_mad_flags { - IB_MAD_IGNORE_MKEY = 1 + IB_MAD_IGNORE_MKEY = 1, + IB_MAD_IGNORE_BKEY = 2, + IB_MAD_IGNORE_ALL = IB_MAD_IGNORE_MKEY | IB_MAD_IGNORE_BKEY }; enum ib_mad_result { @@ -812,7 +815,8 @@ struct ib_device { int (*process_mad)(struct ib_device *device, int process_mad_flags, u8 port_num, - u16 source_lid, + struct ib_wc *in_wc, + struct ib_grh *in_grh, struct ib_mad *in_mad, struct ib_mad *out_mad); _