aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/mad.c
diff options
context:
space:
mode:
authorHal Rosenstock <halr@voltaire.com>2007-05-14 17:21:52 -0400
committerRoland Dreier <rolandd@cisco.com>2007-07-09 19:17:32 -0400
commit1bae4dbf9576e563da23927e4078fffbbce67a75 (patch)
tree3728d91be2f42c1a4a73e41c92857769738d1b83 /drivers/infiniband/core/mad.c
parent71780f59e127bb281a9302d430495ca9586c14e7 (diff)
IB/mad: Enhance SMI for switch support
Extend the SMI with switch (intermediate hop) support. Care has been taken to ensure that the CA (and router) code paths are changed as little as possible. Signed-off-by: Suresh Shelvapille <suri@baymicrosystems.com> Signed-off-by: Hal Rosenstock <halr@voltaire.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/core/mad.c')
-rw-r--r--drivers/infiniband/core/mad.c50
1 files changed, 41 insertions, 9 deletions
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 85ccf13b8041..6b8faca02f8a 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -675,10 +675,16 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
675 struct ib_mad_port_private *port_priv; 675 struct ib_mad_port_private *port_priv;
676 struct ib_mad_agent_private *recv_mad_agent = NULL; 676 struct ib_mad_agent_private *recv_mad_agent = NULL;
677 struct ib_device *device = mad_agent_priv->agent.device; 677 struct ib_device *device = mad_agent_priv->agent.device;
678 u8 port_num = mad_agent_priv->agent.port_num; 678 u8 port_num;
679 struct ib_wc mad_wc; 679 struct ib_wc mad_wc;
680 struct ib_send_wr *send_wr = &mad_send_wr->send_wr; 680 struct ib_send_wr *send_wr = &mad_send_wr->send_wr;
681 681
682 if (device->node_type == RDMA_NODE_IB_SWITCH &&
683 smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
684 port_num = send_wr->wr.ud.port_num;
685 else
686 port_num = mad_agent_priv->agent.port_num;
687
682 /* 688 /*
683 * Directed route handling starts if the initial LID routed part of 689 * Directed route handling starts if the initial LID routed part of
684 * a request or the ending LID routed part of a response is empty. 690 * a request or the ending LID routed part of a response is empty.
@@ -1839,6 +1845,7 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
1839 struct ib_mad_private *recv, *response; 1845 struct ib_mad_private *recv, *response;
1840 struct ib_mad_list_head *mad_list; 1846 struct ib_mad_list_head *mad_list;
1841 struct ib_mad_agent_private *mad_agent; 1847 struct ib_mad_agent_private *mad_agent;
1848 int port_num;
1842 1849
1843 response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); 1850 response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
1844 if (!response) 1851 if (!response)
@@ -1872,25 +1879,50 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
1872 if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num)) 1879 if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num))
1873 goto out; 1880 goto out;
1874 1881
1882 if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH)
1883 port_num = wc->port_num;
1884 else
1885 port_num = port_priv->port_num;
1886
1875 if (recv->mad.mad.mad_hdr.mgmt_class == 1887 if (recv->mad.mad.mad_hdr.mgmt_class ==
1876 IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) { 1888 IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
1889 enum smi_forward_action retsmi;
1890
1877 if (smi_handle_dr_smp_recv(&recv->mad.smp, 1891 if (smi_handle_dr_smp_recv(&recv->mad.smp,
1878 port_priv->device->node_type, 1892 port_priv->device->node_type,
1879 port_priv->port_num, 1893 port_num,
1880 port_priv->device->phys_port_cnt) == 1894 port_priv->device->phys_port_cnt) ==
1881 IB_SMI_DISCARD) 1895 IB_SMI_DISCARD)
1882 goto out; 1896 goto out;
1883 1897
1884 if (smi_check_forward_dr_smp(&recv->mad.smp) == IB_SMI_LOCAL) 1898 retsmi = smi_check_forward_dr_smp(&recv->mad.smp);
1899 if (retsmi == IB_SMI_LOCAL)
1885 goto local; 1900 goto local;
1886 1901
1887 if (smi_handle_dr_smp_send(&recv->mad.smp, 1902 if (retsmi == IB_SMI_SEND) { /* don't forward */
1888 port_priv->device->node_type, 1903 if (smi_handle_dr_smp_send(&recv->mad.smp,
1889 port_priv->port_num) == IB_SMI_DISCARD) 1904 port_priv->device->node_type,
1890 goto out; 1905 port_num) == IB_SMI_DISCARD)
1906 goto out;
1907
1908 if (smi_check_local_smp(&recv->mad.smp, port_priv->device) == IB_SMI_DISCARD)
1909 goto out;
1910 } else if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH) {
1911 /* forward case for switches */
1912 memcpy(response, recv, sizeof(*response));
1913 response->header.recv_wc.wc = &response->header.wc;
1914 response->header.recv_wc.recv_buf.mad = &response->mad.mad;
1915 response->header.recv_wc.recv_buf.grh = &response->grh;
1916
1917 if (!agent_send_response(&response->mad.mad,
1918 &response->grh, wc,
1919 port_priv->device,
1920 smi_get_fwd_port(&recv->mad.smp),
1921 qp_info->qp->qp_num))
1922 response = NULL;
1891 1923
1892 if (smi_check_local_smp(&recv->mad.smp, port_priv->device) == IB_SMI_DISCARD)
1893 goto out; 1924 goto out;
1925 }
1894 } 1926 }
1895 1927
1896local: 1928local:
@@ -1919,7 +1951,7 @@ local:
1919 agent_send_response(&response->mad.mad, 1951 agent_send_response(&response->mad.mad,
1920 &recv->grh, wc, 1952 &recv->grh, wc,
1921 port_priv->device, 1953 port_priv->device,
1922 port_priv->port_num, 1954 port_num,
1923 qp_info->qp->qp_num); 1955 qp_info->qp->qp_num);
1924 goto out; 1956 goto out;
1925 } 1957 }