IN const ib_mad_t* const p_mad_hdr,\r
IN const boolean_t are_we_sender )\r
{\r
- ib_rmpp_mad_t *p_rmpp_mad;\r
boolean_t is_orig;\r
\r
AL_ENTER( AL_DBG_MAD_SVC );\r
return FALSE;\r
}\r
\r
- /*\r
- * Determine originator for a sent MAD. Received MADs are just the\r
- * opposite.\r
- */\r
-\r
- /* Non-DATA RMPP MADs are handled differently. */\r
- p_rmpp_mad = (ib_rmpp_mad_t*)p_mad_hdr;\r
- if( (p_mad_hdr->mgmt_class == IB_MCLASS_SUBN_ADM) &&\r
- ( ib_rmpp_is_flag_set( p_rmpp_mad, IB_RMPP_FLAG_ACTIVE ) &&\r
- (p_rmpp_mad->rmpp_type != IB_RMPP_TYPE_DATA) ) )\r
- {\r
- /*\r
- * We need to distinguish between ACKs sent after receiving\r
- * a request, versus ACKs sent after receiving a response. ACKs\r
- * to a request are from the responder. ACKs to a response are\r
- * from the originator.\r
-\r
- * Note that we assume STOP and ABORT packets are initiated by\r
- * receivers. If both senders and receivers can\r
- * initiate STOP and ABORT MADs, then we can't distinguish which\r
- * transaction is associated with the MAD. The TID for a\r
- * send and receive can be the same.\r
- */\r
- is_orig = !ib_mad_is_response( p_mad_hdr );\r
- }\r
+ if (are_we_sender)\r
+ is_orig = !ib_mad_is_response(p_mad_hdr);\r
else\r
- {\r
- /*\r
- * See if the MAD is being sent in response to a previous MAD. If\r
- * it is, then we're NOT the originator. Note that trap repress\r
- * MADs are responses, even though the response bit isn't set.\r
- */\r
- is_orig = !( ib_mad_is_response( p_mad_hdr ) ||\r
- (p_mad_hdr->method == IB_MAD_METHOD_TRAP_REPRESS) );\r
- }\r
-\r
- /* If we're the receiver, toggle the result. */\r
- if( !are_we_sender )\r
- is_orig = !is_orig;\r
+ is_orig = ib_mad_is_response(p_mad_hdr);\r
\r
AL_EXIT( AL_DBG_MAD_SVC );\r
return is_orig;\r
return FALSE;\r
}\r
}\r
+ if (ib_class_is_vendor_specific_high(p_mad_element->p_mad_buf->mgmt_class) &&\r
+ ib_rmpp_is_flag_set((ib_rmpp_mad_t *) p_mad_element->p_mad_buf,\r
+ IB_RMPP_FLAG_ACTIVE))\r
+ {\r
+ *p_rmpp_version = DEFAULT_RMPP_VERSION;\r
+ return TRUE;\r
+ }\r
\r
/* The RMPP is not active. */\r
return FALSE;\r
}\r
\r
/*\r
- * See if the MAD was sent in response to a previously sent MAD. Note\r
- * that trap repress messages are responses, even though the response\r
- * bit isn't set.\r
+ * See if the MAD was sent in response to a previously sent MAD.\r
*/\r
- if( ib_mad_is_response( p_mad_hdr ) ||\r
- (p_mad_hdr->method == IB_MAD_METHOD_TRAP_REPRESS) )\r
+ if( ib_mad_is_response( p_mad_hdr ) )\r
{\r
/* Process the received response. */\r
__process_recv_resp( h_mad_svc, p_mad_element );\r
switch( mad_svc_type )\r
{\r
case IB_MAD_SVC_DEFAULT:\r
- /* Only subnet management receives require RMPP. */\r
- return( (p_rmpp_mad->common_hdr.mgmt_class == IB_MCLASS_SUBN_ADM) &&\r
- ib_rmpp_is_flag_set( p_rmpp_mad, IB_RMPP_FLAG_ACTIVE ) );\r
+ return (p_rmpp_mad->common_hdr.mgmt_class == IB_MCLASS_SUBN_ADM ||\r
+ ib_class_is_vendor_specific_high(p_rmpp_mad->common_hdr.mgmt_class)) &&\r
+ ib_rmpp_is_flag_set(p_rmpp_mad, IB_RMPP_FLAG_ACTIVE);\r
\r
case IB_MAD_SVC_RMPP:\r
return( ib_rmpp_is_flag_set( p_rmpp_mad, IB_RMPP_FLAG_ACTIVE ) );\r
{\r
case IB_MAD_SVC_DEFAULT:\r
/* Internal sends are non-RMPP data MADs. */\r
- return( (p_rmpp_mad->common_hdr.mgmt_class == IB_MCLASS_SUBN_ADM) &&\r
- (p_rmpp_mad->rmpp_type &&\r
- (p_rmpp_mad->rmpp_type != IB_RMPP_TYPE_DATA) ) );\r
+ return ((p_rmpp_mad->common_hdr.mgmt_class == IB_MCLASS_SUBN_ADM ||\r
+ ib_class_is_vendor_specific_high(p_rmpp_mad->common_hdr.mgmt_class)) &&\r
+ (p_rmpp_mad->rmpp_type && p_rmpp_mad->rmpp_type != IB_RMPP_TYPE_DATA));\r
\r
case IB_MAD_SVC_RMPP:\r
/* The RMPP header is present. Check its type. */\r
IN spl_qp_svc_t* p_spl_qp_svc,\r
IN ib_mad_element_t* p_mad_element );\r
\r
-mad_route_t\r
+static mad_route_t\r
route_recv_smp(\r
IN ib_mad_element_t* p_mad_element );\r
\r
-mad_route_t\r
+static mad_route_t\r
route_recv_smp_attr(\r
IN ib_mad_element_t* p_mad_element );\r
\r
route_recv_dm_mad(\r
IN ib_mad_element_t* p_mad_element );\r
\r
-mad_route_t\r
-route_recv_gmp(\r
+static mad_route_t\r
+route_recv_bm(\r
IN ib_mad_element_t* p_mad_element );\r
\r
-mad_route_t\r
-route_recv_gmp_attr(\r
+static mad_route_t\r
+route_recv_perf(\r
IN ib_mad_element_t* p_mad_element );\r
\r
ib_api_status_t\r
ib_mad_t* p_mad;\r
ib_smp_t* p_smp;\r
al_mad_send_t* p_mad_send;\r
+ ib_mad_element_t* p_send_mad;\r
ib_mad_element_t* p_mad_response = NULL;\r
ib_mad_t* p_mad_response_buf;\r
ib_api_status_t status = IB_SUCCESS;\r
return status;\r
}\r
p_mad_response_buf = p_mad_response->p_mad_buf;\r
+ /* Copy MAD to dispatch locally in case CA doesn't handle it. */\r
+ *p_mad_response_buf = *p_mad;\r
}\r
else\r
{\r
\r
\r
/* Construct the receive MAD element. */\r
- p_mad_response->status = IB_WCS_SUCCESS;\r
- p_mad_response->remote_qp = p_mad_wr->send_wr.dgrm.ud.remote_qp;\r
- p_mad_response->remote_lid = p_spl_qp_svc->base_lid;\r
+ p_send_mad = p_mad_send->p_send_mad;\r
+ p_mad_response->status = IB_WCS_SUCCESS;\r
+ p_mad_response->grh_valid = p_send_mad->grh_valid;\r
+ if( p_mad_response->grh_valid )\r
+ *p_mad_response->p_grh = *p_send_mad->p_grh;\r
+ p_mad_response->path_bits = p_send_mad->path_bits;\r
+ p_mad_response->pkey_index = p_send_mad->pkey_index;\r
+ p_mad_response->remote_lid = p_send_mad->remote_lid;\r
+ p_mad_response->remote_qkey = p_send_mad->remote_qkey;\r
+ p_mad_response->remote_qp = p_send_mad->remote_qp;\r
+ p_mad_response->remote_sl = p_send_mad->remote_sl;\r
if( p_mad_wr->send_wr.send_opt & IB_RECV_OPT_IMMEDIATE )\r
{\r
p_mad_response->immediate_data = p_mad_wr->send_wr.immediate_data;\r
* the send. This guarantees that the send request cannot time out.\r
*/\r
status = mad_disp_recv_done( p_spl_qp_svc->h_mad_disp, p_mad_response );\r
+ if( status != IB_SUCCESS )\r
+ ib_put_mad( p_mad_response );\r
}\r
\r
__complete_send_mad( p_spl_qp_svc->h_mad_disp, p_mad_wr,IB_WCS_SUCCESS);\r
break;\r
\r
case IB_MCLASS_PERF:\r
- /* Process the received GMP. */\r
- switch( p_mad_element->p_mad_buf->method )\r
- {\r
- case IB_MAD_METHOD_GET:\r
- case IB_MAD_METHOD_SET:\r
- route = ROUTE_LOCAL;\r
- break;\r
- default:\r
- break;\r
- }\r
+ route = route_recv_perf( p_mad_element );\r
break;\r
\r
case IB_MCLASS_BM:\r
- route = route_recv_gmp( p_mad_element );\r
+ route = route_recv_bm( p_mad_element );\r
break;\r
\r
- case IB_MCLASS_SUBN_ADM:\r
- case IB_MCLASS_DEV_MGMT:\r
- case IB_MCLASS_COMM_MGMT:\r
- case IB_MCLASS_SNMP:\r
+ case IB_MLX_VENDOR_CLASS1:\r
+ case IB_MLX_VENDOR_CLASS2:\r
+ route = ROUTE_LOCAL;\r
break;\r
\r
default:\r
- /* Route vendor specific MADs to the HCA provider. */\r
- if( ib_class_is_vendor_specific(\r
- p_mad_element->p_mad_buf->mgmt_class ) )\r
- {\r
- route = route_recv_gmp( p_mad_element );\r
- }\r
break;\r
}\r
}\r
/*\r
* Route a received SMP.\r
*/\r
-mad_route_t\r
+static mad_route_t\r
route_recv_smp(\r
IN ib_mad_element_t* p_mad_element )\r
{\r
/*\r
* Route received SMP attributes.\r
*/\r
-mad_route_t\r
+static mad_route_t\r
route_recv_smp_attr(\r
IN ib_mad_element_t* p_mad_element )\r
{\r
}\r
\r
\r
-/*\r
- * Route a received GMP.\r
- */\r
-mad_route_t\r
-route_recv_gmp(\r
+static mad_route_t\r
+route_recv_bm(\r
IN ib_mad_element_t* p_mad_element )\r
{\r
- mad_route_t route;\r
-\r
- AL_ENTER( AL_DBG_SMI );\r
-\r
- CL_ASSERT( p_mad_element );\r
-\r
- /* Process the received GMP. */\r
switch( p_mad_element->p_mad_buf->method )\r
{\r
case IB_MAD_METHOD_GET:\r
case IB_MAD_METHOD_SET:\r
- /* Route vendor specific MADs to the HCA provider. */\r
- if( ib_class_is_vendor_specific(\r
- p_mad_element->p_mad_buf->mgmt_class ) )\r
- {\r
- route = ROUTE_LOCAL;\r
- }\r
- else\r
- {\r
- route = route_recv_gmp_attr( p_mad_element );\r
- }\r
+ if( p_mad_element->p_mad_buf->attr_id == IB_MAD_ATTR_CLASS_PORT_INFO )\r
+ return ROUTE_LOCAL;\r
break;\r
-\r
default:\r
- route = ROUTE_DISPATCHER;\r
break;\r
}\r
-\r
- AL_EXIT( AL_DBG_SMI );\r
- return route;\r
+ return ROUTE_DISPATCHER;\r
}\r
\r
-\r
-\r
-/*\r
- * Route received GMP attributes.\r
- */\r
-mad_route_t\r
-route_recv_gmp_attr(\r
+static mad_route_t\r
+route_recv_perf(\r
IN ib_mad_element_t* p_mad_element )\r
{\r
- mad_route_t route;\r
-\r
- AL_ENTER( AL_DBG_SMI );\r
-\r
- CL_ASSERT( p_mad_element );\r
-\r
- /* Process the received GMP attributes. */\r
- if( p_mad_element->p_mad_buf->attr_id == IB_MAD_ATTR_CLASS_PORT_INFO )\r
- route = ROUTE_LOCAL;\r
- else\r
- route = ROUTE_DISPATCHER;\r
-\r
- AL_EXIT( AL_DBG_SMI );\r
- return route;\r
+ switch( p_mad_element->p_mad_buf->method )\r
+ {\r
+ case IB_MAD_METHOD_GET:\r
+ case IB_MAD_METHOD_SET:\r
+ return ROUTE_LOCAL;\r
+ default:\r
+ break;\r
+ }\r
+ return ROUTE_DISPATCHER;\r
}\r
\r
-\r
-\r
/*\r
* Forward a locally generated Subnet Management trap.\r
*/\r
* We need to get a response from the local HCA to this MAD only if this\r
* MAD is not itself a response.\r
*/\r
- p_mad_request->resp_expected = !( ib_mad_is_response( p_mad_hdr ) ||\r
- ( p_mad_hdr->method == IB_MAD_METHOD_TRAP_REPRESS ) );\r
+ p_mad_request->resp_expected = !ib_mad_is_response( p_mad_hdr );\r
p_mad_request->timeout_ms = LOCAL_MAD_TIMEOUT;\r
p_mad_request->send_opt = IB_SEND_OPT_LOCAL;\r
\r
next = mad->p_next;\r
mad->p_next = NULL;\r
\r
- if (mad->send_context1 == pRegistration) {\r
+ if (mad->context1 == pRegistration) {\r
pRegistration->pDevice->IbInterface.put_mad(mad);\r
} else {\r
WmInsertMad(pProvider, mad);\r
WmProviderUnlockRemove(pProvider);\r
}\r
\r
-static NTSTATUS WmCopyRead(WM_PROVIDER *pProvider, WM_IO_MAD *pIoMad,\r
- ib_mad_element_t *pMad, size_t *pLen)\r
+static NTSTATUS WmCopyMad(WM_IO_MAD *pIoMad, ib_mad_element_t *pMad, size_t *pLen)\r
{\r
- WM_REGISTRATION *reg;\r
-\r
- reg = (WM_REGISTRATION *) pMad->send_context1;\r
- pIoMad->Id = reg->Id;\r
-\r
+ pIoMad->Id = ((WM_REGISTRATION *) pMad->context1)->Id;\r
pIoMad->Status = pMad->status;\r
pIoMad->Timeout = pMad->timeout_ms;\r
pIoMad->Retries = pMad->retry_cnt;\r
}\r
\r
len = outlen;\r
- status = WmCopyRead(pProvider, wmad, pProvider->MadHead, &len);\r
+ status = WmCopyMad(wmad, pProvider->MadHead, &len);\r
if (status == STATUS_SUCCESS) {\r
- reg = (WM_REGISTRATION *) pProvider->MadHead->send_context1;\r
+ reg = (WM_REGISTRATION *) pProvider->MadHead->context1;\r
reg->pDevice->IbInterface.put_mad(WmRemoveMad(pProvider));\r
}\r
WdfObjectReleaseLock(pProvider->ReadQueue);\r
return STATUS_NO_MEMORY;\r
}\r
\r
- mad->context1 = pRegistration;\r
RtlCopyMemory(mad->p_mad_buf, pIoMad + 1, size);\r
mad->remote_qp = pIoMad->Address.Qpn;\r
mad->remote_qkey = pIoMad->Address.Qkey;\r
mad->remote_sl = pIoMad->Address.ServiceLevel;\r
mad->pkey_index = pIoMad->Address.PkeyIndex;\r
mad->path_bits = pIoMad->Address.PathBits;\r
- mad->p_mad_buf->trans_id &= 0xFFFFFFFF00000000;\r
+ if (!ib_mad_is_response(mad->p_mad_buf)) {\r
+ mad->p_mad_buf->trans_id &= 0xFFFFFFFF00000000;\r
+ }\r
\r
ib_status = pifc->send_mad(pRegistration->hService, mad, NULL);\r
if (ib_status != IB_SUCCESS) {\r
void WmReceiveHandler(ib_mad_svc_handle_t hService, void *Context,\r
ib_mad_element_t *pMad)\r
{\r
- WM_REGISTRATION *reg;\r
- WM_PROVIDER *prov = Context;\r
+ WM_REGISTRATION *reg = Context;\r
+ WM_PROVIDER *prov;\r
WDFREQUEST request;\r
NTSTATUS status;\r
WM_IO_MAD *wmad;\r
size_t len = 0;\r
\r
UNREFERENCED_PARAMETER(hService);\r
- reg = (WM_REGISTRATION *) pMad->send_context1;\r
+ prov = reg->pProvider;\r
+ pMad->context1 = reg;\r
\r
WdfObjectAcquireLock(prov->ReadQueue);\r
if (reg->hService == NULL) {\r
goto complete;\r
}\r
\r
- status = WmCopyRead(prov, wmad, pMad, &len);\r
+ status = WmCopyMad(wmad, pMad, &len);\r
if (status == STATUS_SUCCESS) {\r
- reg = (WM_REGISTRATION *) pMad->send_context1;\r
reg->pDevice->IbInterface.put_mad(pMad);\r
} else {\r
WmInsertMad(prov, pMad);\r
ib_mad_element_t *pMad)\r
{\r
if (pMad->status == IB_SUCCESS) {\r
- ((WM_REGISTRATION *) pMad->context1)->pDevice->IbInterface.put_mad(pMad);\r
+ ((WM_REGISTRATION *) Context)->pDevice->IbInterface.put_mad(pMad);\r
} else {\r
- pMad->send_context1 = (void*) pMad->context1;\r
WmReceiveHandler(hService, Context, pMad);\r
}\r
}\r
goto err4;\r
}\r
\r
- svc.mad_svc_context = pRegistration->pProvider;\r
+ svc.mad_svc_context = pRegistration;\r
svc.pfn_mad_send_cb = WmSendHandler;\r
svc.pfn_mad_recv_cb = WmReceiveHandler;\r
svc.support_unsol = WmConvertMethods(&svc, pAttributes);\r
#endif
-enum {
- MLX4_IB_VENDOR_CLASS1 = 0x9,
- MLX4_IB_VENDOR_CLASS2 = 0xa
-};
-
int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int ignore_mkey, int ignore_bkey,
int port, ib_wc_t *in_wc, struct ib_grh *in_grh,
void *in_mad, void *response_mad)
IB_SMP_ATTR_VENDOR_MASK))
return IB_MAD_RESULT_SUCCESS;
} else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT ||
- in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS1 ||
- in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS2) {
+ in_mad->mad_hdr.mgmt_class == IB_MLX_VENDOR_CLASS1 ||
+ in_mad->mad_hdr.mgmt_class == IB_MLX_VENDOR_CLASS2) {
if (in_mad->mad_hdr.method != IB_MGMT_METHOD_GET &&
in_mad->mad_hdr.method != IB_MGMT_METHOD_SET)
return IB_MAD_RESULT_SUCCESS;
#endif\r
#include "mthca_cmd.h"\r
\r
-enum {\r
- MTHCA_VENDOR_CLASS1 = 0x9,\r
- MTHCA_VENDOR_CLASS2 = 0xa\r
-};\r
-\r
struct mthca_trap_mad {\r
struct scatterlist sg;\r
};\r
} \r
else {\r
if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT ||\r
- in_mad->mad_hdr.mgmt_class == MTHCA_VENDOR_CLASS1 ||\r
- in_mad->mad_hdr.mgmt_class == MTHCA_VENDOR_CLASS2) {\r
+ in_mad->mad_hdr.mgmt_class == IB_MLX_VENDOR_CLASS1 ||\r
+ in_mad->mad_hdr.mgmt_class == IB_MLX_VENDOR_CLASS2) {\r
\r
if (in_mad->mad_hdr.method != IB_MGMT_METHOD_GET &&\r
in_mad->mad_hdr.method != IB_MGMT_METHOD_SET) {\r
#define IB_MCLASS_VENDOR_LOW_RANGE_MAX 0x0f\r
/**********/\r
\r
+#define IB_MLX_VENDOR_CLASS1 0x9\r
+#define IB_MLX_VENDOR_CLASS2 0xA\r
+\r
/****d* IBA Base: Constants/IB_MCLASS_DEV_ADM\r
* NAME\r
* IB_MCLASS_DEV_ADM\r
IN const ib_mad_t* const p_mad )\r
{\r
CL_ASSERT( p_mad );\r
- return( (p_mad->method & IB_MAD_METHOD_RESP_MASK) ==\r
- IB_MAD_METHOD_RESP_MASK );\r
+ return ((p_mad->method & IB_MAD_METHOD_RESP_MASK) ||\r
+ (p_mad->method == IB_MAD_METHOD_TRAP_REPRESS));\r
}\r
/*\r
* PARAMETERS\r