1/* 2 3 * Copyright (c) 2004, 2005 Mellanox Technologies Ltd. All rights reserved. 4 * Copyright (c) 2004, 2005 Infinicon Corporation. All rights reserved. 5 * Copyright (c) 2004, 2005 Intel Corporation. All rights reserved. 6 * Copyright (c) 2004, 2005 Topspin Corporation. All rights reserved. 7 * Copyright (c) 2004-2007 Voltaire Corporation. All rights reserved. 8 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 9 * 10 * This software is available to you under a choice of one of two 11 * licenses. You may choose to be licensed under the terms of the GNU 12 * General Public License (GPL) Version 2, available from the file 13 * COPYING in the main directory of this source tree, or the 14 * OpenIB.org BSD license below: 15 * 16 * Redistribution and use in source and binary forms, with or 17 * without modification, are permitted provided that the following 18 * conditions are met: 19 * 20 * - Redistributions of source code must retain the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer. 23 * 24 * - Redistributions in binary form must reproduce the above 25 * copyright notice, this list of conditions and the following 26 * disclaimer in the documentation and/or other materials 27 * provided with the distribution. 28 * 29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 30 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 31 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 32 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 33 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 34 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 35 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 36 * SOFTWARE. 37 * 38 */ 39 40// #include <linux/slab.h> 41// #include <linux/string.h> 42 43#include <linux/gfp.h> 44 45#include "agent.h" 46/* 47 #include "smi.h" 48 */ 49#include "mad_priv.h" 50 51#define SPFX "ib_agent: " 52 53struct ib_agent_port_private { 54 struct list_head port_list; 55 struct ib_mad_agent *agent[2]; 56}; 57/* 58 static DEFINE_SPINLOCK(ib_agent_port_list_lock); 59 */ 60static MLX4_LIST_HEAD( ib_agent_port_list); 61 62static struct ib_agent_port_private * 63__ib_get_agent_port(struct ib_device *device, int port_num) { 64 struct ib_agent_port_private *entry; 65 66 list_for_each_entry(entry, &ib_agent_port_list, port_list) 67 { 68 if (entry->agent[1]->device == device 69 && entry->agent[1]->port_num == port_num) 70 return entry; 71 } 72 return NULL; 73} 74 75static struct ib_agent_port_private * 76ib_get_agent_port(struct ib_device *device, int port_num) { 77 struct ib_agent_port_private *entry; 78 /*unsigned long flags;*/ 79 80 /*spin_lock_irqsave(&ib_agent_port_list_lock, flags);*/ 81 entry = __ib_get_agent_port(device, port_num); 82 /*spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);*/ 83 return entry; 84} 85 86void agent_send_response(struct ib_mad *mad, struct ib_grh *grh, 87 struct ib_wc *wc, struct ib_device *device, int port_num, int qpn) { 88 struct ib_agent_port_private *port_priv; 89 struct ib_mad_agent *agent; 90 struct ib_mad_send_buf *send_buf; 91 struct ib_ah *ah; 92 struct ib_mad_send_wr_private *mad_send_wr; 93 94 if (device->node_type == RDMA_NODE_IB_SWITCH) 95 port_priv = ib_get_agent_port(device, 0); 96 else 97 port_priv = ib_get_agent_port(device, port_num); 98 99 if (!port_priv) { 100 printf("Unable to find port agent\n"); 101 return; 102 } 103 104 agent = port_priv->agent[qpn]; 105 ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num); 106 if (IS_ERR(ah)) { 107 printf("ib_create_ah_from_wc error %ld\n", PTR_ERR(ah)); 108 return; 109 } 110 111 send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0, 112 IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, GFP_KERNEL); 113 if (IS_ERR(send_buf)) { 114 printf("ib_create_send_mad error\n"); 115 goto err1; 116 } 117 118 memcpy(send_buf->mad, mad, sizeof *mad); 119 send_buf->ah = ah; 120 121 if (device->node_type == RDMA_NODE_IB_SWITCH) { 122 mad_send_wr = container_of(send_buf, struct ib_mad_send_wr_private, 123 send_buf); 124 mad_send_wr->send_wr.wr.ud.port_num = port_num; 125 } 126 127 if (ib_post_send_mad(send_buf, NULL)) { 128 printf("ib_post_send_mad error\n"); 129 goto err2; 130 } 131 return; 132 133 /*TODO: cleanup*/ 134 err2: /*ib_free_send_mad(send_buf);*/ 135 err1: /*ib_destroy_ah(ah);*/ 136 return; 137} 138 139static void agent_send_handler(struct ib_mad_agent *mad_agent, 140 struct ib_mad_send_wc *mad_send_wc) { 141 ib_destroy_ah(mad_send_wc->send_buf->ah); 142 ib_free_send_mad(mad_send_wc->send_buf); 143} 144 145int ib_agent_port_open(struct ib_device *device, int port_num) { 146 struct ib_agent_port_private *port_priv; 147 /*unsigned long flags;*/ 148 int ret; 149 150 /*Create new device info*/ 151 port_priv = calloc(1, sizeof *port_priv); 152 if (!port_priv) { 153 printf("No memory for ib_agent_port_private\n"); 154 ret = -ENOMEM; 155 goto error1; 156 } 157 158 if (rdma_port_get_link_layer(device, port_num) 159 == IB_LINK_LAYER_INFINIBAND) { 160 /*Obtain send only MAD agent for SMI QP*/ 161 port_priv->agent[0] = ib_register_mad_agent(device, port_num, 162 IB_QPT_SMI, 163 NULL, 0, &agent_send_handler, 164 NULL, NULL); 165 if (IS_ERR(port_priv->agent[0])) { 166 ret = PTR_ERR(port_priv->agent[0]); 167 goto error2; 168 } 169 } 170 171 /*Obtain send only MAD agent for GSI QP*/ 172 port_priv->agent[1] = ib_register_mad_agent(device, port_num, IB_QPT_GSI, 173 NULL, 0, &agent_send_handler, 174 NULL, NULL); 175 if (IS_ERR(port_priv->agent[1])) { 176 ret = PTR_ERR(port_priv->agent[1]); 177 goto error3; 178 } 179 180 /*spin_lock_irqsave(&ib_agent_port_list_lock, flags);*/ 181 list_add_tail(&port_priv->port_list, &ib_agent_port_list); 182 /*spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);*/ 183 184 return 0; 185 186 /*TODO: cleanup*/ 187 error3: /*if (port_priv->agent[0]) 188 ib_unregister_mad_agent(port_priv->agent[0]);*/ 189 error2: free(port_priv); 190 error1: return ret; 191} 192/* 193 int ib_agent_port_close(struct ib_device *device, int port_num) 194 { 195 struct ib_agent_port_private *port_priv; 196 unsigned long flags; 197 198 spin_lock_irqsave(&ib_agent_port_list_lock, flags); 199 port_priv = __ib_get_agent_port(device, port_num); 200 if (port_priv == NULL) { 201 spin_unlock_irqrestore(&ib_agent_port_list_lock, flags); 202 printf( "Port %d not found\n", port_num); 203 return -ENODEV; 204 } 205 list_del(&port_priv->port_list); 206 spin_unlock_irqrestore(&ib_agent_port_list_lock, flags); 207 208 ib_unregister_mad_agent(port_priv->agent[1]); 209 if (port_priv->agent[0]) 210 ib_unregister_mad_agent(port_priv->agent[0]); 211 212 kfree(port_priv); 213 return 0; 214 } 215 */ 216