agent: Add IB ping server agent (used with ibping diagnostic tool) Signed-off-by: Shahar Frank <[EMAIL PROTECTED]> Signed-off-by: Hal Rosenstock <[EMAIL PROTECTED]>
Index: include/ib_mad.h =================================================================== --- include/ib_mad.h (revision 2012) +++ include/ib_mad.h (working copy) @@ -56,6 +56,10 @@ #define IB_MGMT_CLASS_VENDOR_RANGE2_START 0x30 #define IB_MGMT_CLASS_VENDOR_RANGE2_END 0x4F +#define IB_MGMT_CLASS_OPENIB_PING (IB_MGMT_CLASS_VENDOR_RANGE2_START+2) + +#define IB_OPENIB_OUI (0x001405) + /* Management methods */ #define IB_MGMT_METHOD_GET 0x01 #define IB_MGMT_METHOD_SET 0x02 Index: core/agent_priv.h =================================================================== --- core/agent_priv.h (revision 2012) +++ core/agent_priv.h (working copy) @@ -57,6 +57,7 @@ int port_num; struct ib_mad_agent *smp_agent; /* SM class */ struct ib_mad_agent *perf_mgmt_agent; /* PerfMgmt class */ + struct ib_mad_agent *pingd_agent; /* OpenIB Ping class */ }; #endif /* __IB_AGENT_PRIV_H__ */ Index: core/agent.c =================================================================== --- core/agent.c (revision 2012) +++ core/agent.c (working copy) @@ -37,7 +37,7 @@ */ #include <linux/dma-mapping.h> - +#include <linux/utsname.h> #include <asm/bug.h> #include <ib_smi.h> @@ -70,7 +70,8 @@ } else { list_for_each_entry(entry, &ib_agent_port_list, port_list) { if ((entry->smp_agent == mad_agent) || - (entry->perf_mgmt_agent == mad_agent)) + (entry->perf_mgmt_agent == mad_agent) || + (entry->pingd_agent == mad_agent)) return entry; } } @@ -151,7 +152,8 @@ ah_attr.sl = wc->sl; ah_attr.static_rate = 0; ah_attr.ah_flags = 0; /* No GRH */ - if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT) { + if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT || + mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_OPENIB_PING) { if (wc->wc_flags & IB_WC_GRH) { ah_attr.ah_flags = IB_AH_GRH; /* Should sgid be looked up ? */ @@ -175,7 +177,8 @@ } send_wr.wr.ud.ah = agent_send_wr->ah; - if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT) { + if (mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT || + mad_priv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_OPENIB_PING) { send_wr.wr.ud.pkey_index = wc->pkey_index; send_wr.wr.ud.remote_qkey = IB_QP1_QKEY; } else { /* for SMPs */ @@ -233,6 +236,9 @@ case IB_MGMT_CLASS_PERF_MGMT: mad_agent = port_priv->perf_mgmt_agent; break; + case IB_MGMT_CLASS_OPENIB_PING: + mad_agent = port_priv->pingd_agent; + break; default: return 1; } @@ -240,6 +246,42 @@ return agent_mad_send(mad_agent, port_priv, mad, grh, wc); } +static void pingd_recv_handler(struct ib_mad_agent *mad_agent, + struct ib_mad_recv_wc *mad_recv_wc) +{ + struct ib_agent_port_private *port_priv; + struct ib_vendor_mad *vend; + struct ib_mad_private *recv = container_of(mad_recv_wc, + struct ib_mad_private, + header.recv_wc); + + /* Find matching MAD agent */ + port_priv = ib_get_agent_port(NULL, 0, mad_agent); + if (!port_priv) { + kmem_cache_free(ib_mad_cache, recv); + printk(KERN_ERR SPFX "pingd_recv_handler: no matching MAD " + "agent %p\n", mad_agent); + return; + } + + vend = (struct ib_vendor_mad *)mad_recv_wc->recv_buf.mad; + + vend->mad_hdr.method |= IB_MGMT_METHOD_RESP; + vend->mad_hdr.status = 0; + if (!system_utsname.domainname[0]) + strncpy(vend->data, system_utsname.nodename, sizeof vend->data); + else + snprintf(vend->data, sizeof vend->data, "%s.%s", + system_utsname.nodename, system_utsname.domainname); + + /* Send response */ + if (agent_mad_send(mad_agent, port_priv, recv, + mad_recv_wc->recv_buf.grh, mad_recv_wc->wc)) { + kmem_cache_free(ib_mad_cache, recv); + printk(KERN_ERR SPFX "pingd_recv_handler: reply failed\n"); + } +} + static void agent_send_handler(struct ib_mad_agent *mad_agent, struct ib_mad_send_wc *mad_send_wc) { @@ -278,6 +320,7 @@ { int ret; struct ib_agent_port_private *port_priv; + struct ib_mad_reg_req pingd_reg_req; unsigned long flags; /* First, check if port already open for SMI */ @@ -324,12 +367,33 @@ goto error3; } + pingd_reg_req.mgmt_class = IB_MGMT_CLASS_OPENIB_PING; + pingd_reg_req.mgmt_class_version = 1; + pingd_reg_req.oui[0] = (IB_OPENIB_OUI >> 16) & 0xff; + pingd_reg_req.oui[1] = (IB_OPENIB_OUI >> 8) & 0xff; + pingd_reg_req.oui[2] = IB_OPENIB_OUI & 0xff; + set_bit(IB_MGMT_METHOD_GET, pingd_reg_req.method_mask); + + /* Obtain server MAD agent for OpenIB Ping class (GSI QP) */ + port_priv->pingd_agent = ib_register_mad_agent(device, port_num, + IB_QPT_GSI, + &pingd_reg_req, 0, + &agent_send_handler, + &pingd_recv_handler, + NULL); + if (IS_ERR(port_priv->pingd_agent)) { + ret = PTR_ERR(port_priv->pingd_agent); + goto error4; + } + spin_lock_irqsave(&ib_agent_port_list_lock, flags); list_add_tail(&port_priv->port_list, &ib_agent_port_list); spin_unlock_irqrestore(&ib_agent_port_list_lock, flags); return 0; +error4: + ib_unregister_mad_agent(port_priv->perf_mgmt_agent); error3: ib_unregister_mad_agent(port_priv->smp_agent); error2: @@ -353,6 +417,7 @@ list_del(&port_priv->port_list); spin_unlock_irqrestore(&ib_agent_port_list_lock, flags); + ib_unregister_mad_agent(port_priv->pingd_agent); ib_unregister_mad_agent(port_priv->perf_mgmt_agent); ib_unregister_mad_agent(port_priv->smp_agent); kfree(port_priv); _______________________________________________ openib-general mailing list openib-general@openib.org http://openib.org/mailman/listinfo/openib-general To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general