Commit 727792da authored by Steve Welch's avatar Steve Welch Committed by Roland Dreier

IB/mad: Enable loopback of DR SMP responses from userspace

The local loopback of an outgoing DR SMP response is limited to those
that originate at the driver specific SMA implementation during the
driver specific process_mad() function.  This patch enables a
returning DR SMP originating in userspace (or elsewhere) to be
delivered to the local managment stack.  In this specific case the
driver process_mad() function does not consume or process the MAD, so
a reponse mad has not be created and the original MAD must manually be
copied to the MAD buffer that is to be handed off to the local agent.
Signed-off-by: default avatarSteve Welch <swelch@systemfabricworks.com>
Acked-by: default avatarHal Rosenstock <hal@xsigo.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent f9b40353
...@@ -701,7 +701,8 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, ...@@ -701,7 +701,8 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
} }
/* Check to post send on QP or process locally */ /* Check to post send on QP or process locally */
if (smi_check_local_smp(smp, device) == IB_SMI_DISCARD) if (smi_check_local_smp(smp, device) == IB_SMI_DISCARD &&
smi_check_local_returning_smp(smp, device) == IB_SMI_DISCARD)
goto out; goto out;
local = kmalloc(sizeof *local, GFP_ATOMIC); local = kmalloc(sizeof *local, GFP_ATOMIC);
...@@ -752,8 +753,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, ...@@ -752,8 +753,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
port_priv = ib_get_mad_port(mad_agent_priv->agent.device, port_priv = ib_get_mad_port(mad_agent_priv->agent.device,
mad_agent_priv->agent.port_num); mad_agent_priv->agent.port_num);
if (port_priv) { if (port_priv) {
mad_priv->mad.mad.mad_hdr.tid = memcpy(&mad_priv->mad.mad, smp, sizeof(struct ib_mad));
((struct ib_mad *)smp)->mad_hdr.tid;
recv_mad_agent = find_mad_agent(port_priv, recv_mad_agent = find_mad_agent(port_priv,
&mad_priv->mad.mad); &mad_priv->mad.mad);
} }
......
...@@ -59,7 +59,8 @@ extern enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp, ...@@ -59,7 +59,8 @@ extern enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp,
u8 node_type, int port_num); u8 node_type, int port_num);
/* /*
* Return 1 if the SMP should be handled by the local SMA/SM via process_mad * Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM
* via process_mad
*/ */
static inline enum smi_action smi_check_local_smp(struct ib_smp *smp, static inline enum smi_action smi_check_local_smp(struct ib_smp *smp,
struct ib_device *device) struct ib_device *device)
...@@ -71,4 +72,19 @@ static inline enum smi_action smi_check_local_smp(struct ib_smp *smp, ...@@ -71,4 +72,19 @@ static inline enum smi_action smi_check_local_smp(struct ib_smp *smp,
(smp->hop_ptr == smp->hop_cnt + 1)) ? (smp->hop_ptr == smp->hop_cnt + 1)) ?
IB_SMI_HANDLE : IB_SMI_DISCARD); IB_SMI_HANDLE : IB_SMI_DISCARD);
} }
/*
* Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM
* via process_mad
*/
static inline enum smi_action smi_check_local_returning_smp(struct ib_smp *smp,
struct ib_device *device)
{
/* C14-13:3 -- We're at the end of the DR segment of path */
/* C14-13:4 -- Hop Pointer == 0 -> give to SM */
return ((device->process_mad &&
ib_get_smp_direction(smp) &&
!smp->hop_ptr) ? IB_SMI_HANDLE : IB_SMI_DISCARD);
}
#endif /* __SMI_H_ */ #endif /* __SMI_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment