[openib-general] [PATCH] agent: Add IB ping server agent
Hal Rosenstock
halr at voltaire.com
Thu Mar 17 06:10:51 PST 2005
agent: Add IB ping server agent (used with ibping diagnostic tool)
Signed-off-by: Shahar Frank <shaharf at voltaire.com>
Signed-off-by: Hal Rosenstock <halr at voltaire.com>
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);
More information about the general
mailing list