From 86f0e67a21508b3e6020d53ef92a73081ed7eae1 Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Sat, 6 Jun 2015 14:38:26 -0400 Subject: [PATCH] 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 Signed-off-by: Doug Ledford --- drivers/infiniband/core/smi.c | 165 ++++++++++++++++++---------------- 1 file changed, 89 insertions(+), 76 deletions(-) diff --git a/drivers/infiniband/core/smi.c b/drivers/infiniband/core/smi.c index b6dedc0918fe..eb39146adb80 100644 --- a/drivers/infiniband/core/smi.c +++ b/drivers/infiniband/core/smi.c @@ -136,6 +136,88 @@ enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp, 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 * 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, int port_num, int phys_port_cnt) { - u8 hop_ptr, hop_cnt; - - hop_ptr = smp->hop_ptr; - hop_cnt = smp->hop_cnt; - - /* 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 (!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); - } + return __smi_handle_dr_smp_recv(node_type, port_num, phys_port_cnt, + &smp->hop_ptr, smp->hop_cnt, + smp->initial_path, + smp->return_path, + ib_get_smp_direction(smp), + smp->dr_dlid == IB_LID_PERMISSIVE, + smp->dr_slid == IB_LID_PERMISSIVE); } enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp)