IB/mad: Create a generic helper for DR SMP Recv processing

IB and OPA SMPs share the same processing algorithm but have different header
formats and permissive LID detection.

Add a helper function which is generic to processing DR SMP Recv messages which
can be used by both IB and OPA SMP code.

Use this function in the current IB function smi_handle_dr_smp_recv.

Signed-off-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
Ira Weiny 2015-06-06 14:38:26 -04:00 committed by Doug Ledford
parent 92f1505604
commit 86f0e67a21
1 changed files with 89 additions and 76 deletions

View File

@ -136,6 +136,88 @@ enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp,
smp->dr_slid == IB_LID_PERMISSIVE); smp->dr_slid == IB_LID_PERMISSIVE);
} }
static enum smi_action __smi_handle_dr_smp_recv(u8 node_type, int port_num,
int phys_port_cnt,
u8 *hop_ptr, u8 hop_cnt,
const u8 *initial_path,
u8 *return_path,
u8 direction,
bool dr_dlid_is_permissive,
bool dr_slid_is_permissive)
{
/* See section 14.2.2.2, Vol 1 IB spec */
/* C14-6 -- valid hop_cnt values are from 0 to 63 */
if (hop_cnt >= IB_SMP_MAX_PATH_HOPS)
return IB_SMI_DISCARD;
if (!direction) {
/* C14-9:1 -- sender should have incremented hop_ptr */
if (hop_cnt && *hop_ptr == 0)
return IB_SMI_DISCARD;
/* C14-9:2 -- intermediate hop */
if (*hop_ptr && *hop_ptr < hop_cnt) {
if (node_type != RDMA_NODE_IB_SWITCH)
return IB_SMI_DISCARD;
return_path[*hop_ptr] = port_num;
/* hop_ptr updated when sending */
return (initial_path[*hop_ptr+1] <= phys_port_cnt ?
IB_SMI_HANDLE : IB_SMI_DISCARD);
}
/* C14-9:3 -- We're at the end of the DR segment of path */
if (*hop_ptr == hop_cnt) {
if (hop_cnt)
return_path[*hop_ptr] = port_num;
/* hop_ptr updated when sending */
return (node_type == RDMA_NODE_IB_SWITCH ||
dr_dlid_is_permissive ?
IB_SMI_HANDLE : IB_SMI_DISCARD);
}
/* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
/* C14-9:5 -- fail unreasonable hop pointer */
return (*hop_ptr == hop_cnt + 1 ? IB_SMI_HANDLE : IB_SMI_DISCARD);
} else {
/* C14-13:1 */
if (hop_cnt && *hop_ptr == hop_cnt + 1) {
(*hop_ptr)--;
return (return_path[*hop_ptr] ==
port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD);
}
/* C14-13:2 */
if (2 <= *hop_ptr && *hop_ptr <= hop_cnt) {
if (node_type != RDMA_NODE_IB_SWITCH)
return IB_SMI_DISCARD;
/* hop_ptr updated when sending */
return (return_path[*hop_ptr-1] <= phys_port_cnt ?
IB_SMI_HANDLE : IB_SMI_DISCARD);
}
/* C14-13:3 -- We're at the end of the DR segment of path */
if (*hop_ptr == 1) {
if (dr_slid_is_permissive) {
/* giving SMP to SM - update hop_ptr */
(*hop_ptr)--;
return IB_SMI_HANDLE;
}
/* hop_ptr updated when sending */
return (node_type == RDMA_NODE_IB_SWITCH ?
IB_SMI_HANDLE : IB_SMI_DISCARD);
}
/* C14-13:4 -- hop_ptr = 0 -> give to SM */
/* C14-13:5 -- Check for unreasonable hop pointer */
return (*hop_ptr == 0 ? IB_SMI_HANDLE : IB_SMI_DISCARD);
}
}
/* /*
* Adjust information for a received SMP * Adjust information for a received SMP
* Return IB_SMI_DISCARD if the SMP should be dropped * Return IB_SMI_DISCARD if the SMP should be dropped
@ -143,82 +225,13 @@ enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp,
enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type, enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type,
int port_num, int phys_port_cnt) int port_num, int phys_port_cnt)
{ {
u8 hop_ptr, hop_cnt; return __smi_handle_dr_smp_recv(node_type, port_num, phys_port_cnt,
&smp->hop_ptr, smp->hop_cnt,
hop_ptr = smp->hop_ptr; smp->initial_path,
hop_cnt = smp->hop_cnt; smp->return_path,
ib_get_smp_direction(smp),
/* See section 14.2.2.2, Vol 1 IB spec */ smp->dr_dlid == IB_LID_PERMISSIVE,
/* C14-6 -- valid hop_cnt values are from 0 to 63 */ smp->dr_slid == IB_LID_PERMISSIVE);
if (hop_cnt >= IB_SMP_MAX_PATH_HOPS)
return IB_SMI_DISCARD;
if (!ib_get_smp_direction(smp)) {
/* C14-9:1 -- sender should have incremented hop_ptr */
if (hop_cnt && hop_ptr == 0)
return IB_SMI_DISCARD;
/* C14-9:2 -- intermediate hop */
if (hop_ptr && hop_ptr < hop_cnt) {
if (node_type != RDMA_NODE_IB_SWITCH)
return IB_SMI_DISCARD;
smp->return_path[hop_ptr] = port_num;
/* smp->hop_ptr updated when sending */
return (smp->initial_path[hop_ptr+1] <= phys_port_cnt ?
IB_SMI_HANDLE : IB_SMI_DISCARD);
}
/* C14-9:3 -- We're at the end of the DR segment of path */
if (hop_ptr == hop_cnt) {
if (hop_cnt)
smp->return_path[hop_ptr] = port_num;
/* smp->hop_ptr updated when sending */
return (node_type == RDMA_NODE_IB_SWITCH ||
smp->dr_dlid == IB_LID_PERMISSIVE ?
IB_SMI_HANDLE : IB_SMI_DISCARD);
}
/* C14-9:4 -- hop_ptr = hop_cnt + 1 -> give to SMA/SM */
/* C14-9:5 -- fail unreasonable hop pointer */
return (hop_ptr == hop_cnt + 1 ? IB_SMI_HANDLE : IB_SMI_DISCARD);
} else {
/* C14-13:1 */
if (hop_cnt && hop_ptr == hop_cnt + 1) {
smp->hop_ptr--;
return (smp->return_path[smp->hop_ptr] ==
port_num ? IB_SMI_HANDLE : IB_SMI_DISCARD);
}
/* C14-13:2 */
if (2 <= hop_ptr && hop_ptr <= hop_cnt) {
if (node_type != RDMA_NODE_IB_SWITCH)
return IB_SMI_DISCARD;
/* smp->hop_ptr updated when sending */
return (smp->return_path[hop_ptr-1] <= phys_port_cnt ?
IB_SMI_HANDLE : IB_SMI_DISCARD);
}
/* C14-13:3 -- We're at the end of the DR segment of path */
if (hop_ptr == 1) {
if (smp->dr_slid == IB_LID_PERMISSIVE) {
/* giving SMP to SM - update hop_ptr */
smp->hop_ptr--;
return IB_SMI_HANDLE;
}
/* smp->hop_ptr updated when sending */
return (node_type == RDMA_NODE_IB_SWITCH ?
IB_SMI_HANDLE : IB_SMI_DISCARD);
}
/* C14-13:4 -- hop_ptr = 0 -> give to SM */
/* C14-13:5 -- Check for unreasonable hop pointer */
return (hop_ptr == 0 ? IB_SMI_HANDLE : IB_SMI_DISCARD);
}
} }
enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp) enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp)