1/*
2 * Copyright (c) 2004 Topspin Communications.  All rights reserved.
3 * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
4 * Copyright (c) 2006 Intel Corporation.  All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses.  You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 *     Redistribution and use in source and binary forms, with or
13 *     without modification, are permitted provided that the following
14 *     conditions are met:
15 *
16 *      - Redistributions of source code must retain the above
17 *        copyright notice, this list of conditions and the following
18 *        disclaimer.
19 *
20 *      - Redistributions in binary form must reproduce the above
21 *        copyright notice, this list of conditions and the following
22 *        disclaimer in the documentation and/or other materials
23 *        provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 */
34
35#include <linux/module.h>
36#include <linux/err.h>
37#include <linux/random.h>
38#include <linux/spinlock.h>
39#include <linux/slab.h>
40#include <linux/dma-mapping.h>
41#include <linux/kref.h>
42#include <linux/idr.h>
43#include <linux/workqueue.h>
44
45#include <rdma/ib_pack.h>
46#include <rdma/ib_cache.h>
47#include "sa.h"
48
49MODULE_AUTHOR("Roland Dreier");
50MODULE_DESCRIPTION("InfiniBand subnet administration query support");
51MODULE_LICENSE("Dual BSD/GPL");
52
53struct ib_sa_sm_ah {
54	struct ib_ah        *ah;
55	struct kref          ref;
56	u16		     pkey_index;
57	u8		     src_path_mask;
58};
59
60struct ib_sa_port {
61	struct ib_mad_agent *agent;
62	struct ib_mad_agent *notice_agent;
63	struct ib_sa_sm_ah  *sm_ah;
64	struct work_struct   update_task;
65	spinlock_t           ah_lock;
66	u8                   port_num;
67	struct ib_device    *device;
68};
69
70struct ib_sa_device {
71	int                     start_port, end_port;
72	struct ib_event_handler event_handler;
73	struct ib_sa_port port[0];
74};
75
76struct ib_sa_query {
77	void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *);
78	void (*release)(struct ib_sa_query *);
79	struct ib_sa_client    *client;
80	struct ib_sa_port      *port;
81	struct ib_mad_send_buf *mad_buf;
82	struct ib_sa_sm_ah     *sm_ah;
83	int			id;
84};
85
86struct ib_sa_service_query {
87	void (*callback)(int, struct ib_sa_service_rec *, void *);
88	void *context;
89	struct ib_sa_query sa_query;
90};
91
92struct ib_sa_path_query {
93	void (*callback)(int, struct ib_sa_path_rec *, void *);
94	void *context;
95	struct ib_sa_query sa_query;
96};
97
98struct ib_sa_mcmember_query {
99	void (*callback)(int, struct ib_sa_mcmember_rec *, void *);
100	void *context;
101	struct ib_sa_query sa_query;
102};
103
104struct ib_sa_inform_query {
105	void (*callback)(int, struct ib_sa_inform *, void *);
106	void *context;
107	struct ib_sa_query sa_query;
108};
109
110static void ib_sa_add_one(struct ib_device *device);
111static void ib_sa_remove_one(struct ib_device *device);
112
113static struct ib_client sa_client = {
114	.name   = "sa",
115	.add    = ib_sa_add_one,
116	.remove = ib_sa_remove_one
117};
118
119static spinlock_t idr_lock;
120static DEFINE_IDR(query_idr);
121
122static spinlock_t tid_lock;
123static u32 tid;
124
125#define PATH_REC_FIELD(field) \
126	.struct_offset_bytes = offsetof(struct ib_sa_path_rec, field),		\
127	.struct_size_bytes   = sizeof ((struct ib_sa_path_rec *) 0)->field,	\
128	.field_name          = "sa_path_rec:" #field
129
130static const struct ib_field path_rec_table[] = {
131	{ PATH_REC_FIELD(service_id),
132	  .offset_words = 0,
133	  .offset_bits  = 0,
134	  .size_bits    = 64 },
135	{ PATH_REC_FIELD(dgid),
136	  .offset_words = 2,
137	  .offset_bits  = 0,
138	  .size_bits    = 128 },
139	{ PATH_REC_FIELD(sgid),
140	  .offset_words = 6,
141	  .offset_bits  = 0,
142	  .size_bits    = 128 },
143	{ PATH_REC_FIELD(dlid),
144	  .offset_words = 10,
145	  .offset_bits  = 0,
146	  .size_bits    = 16 },
147	{ PATH_REC_FIELD(slid),
148	  .offset_words = 10,
149	  .offset_bits  = 16,
150	  .size_bits    = 16 },
151	{ PATH_REC_FIELD(raw_traffic),
152	  .offset_words = 11,
153	  .offset_bits  = 0,
154	  .size_bits    = 1 },
155	{ RESERVED,
156	  .offset_words = 11,
157	  .offset_bits  = 1,
158	  .size_bits    = 3 },
159	{ PATH_REC_FIELD(flow_label),
160	  .offset_words = 11,
161	  .offset_bits  = 4,
162	  .size_bits    = 20 },
163	{ PATH_REC_FIELD(hop_limit),
164	  .offset_words = 11,
165	  .offset_bits  = 24,
166	  .size_bits    = 8 },
167	{ PATH_REC_FIELD(traffic_class),
168	  .offset_words = 12,
169	  .offset_bits  = 0,
170	  .size_bits    = 8 },
171	{ PATH_REC_FIELD(reversible),
172	  .offset_words = 12,
173	  .offset_bits  = 8,
174	  .size_bits    = 1 },
175	{ PATH_REC_FIELD(numb_path),
176	  .offset_words = 12,
177	  .offset_bits  = 9,
178	  .size_bits    = 7 },
179	{ PATH_REC_FIELD(pkey),
180	  .offset_words = 12,
181	  .offset_bits  = 16,
182	  .size_bits    = 16 },
183	{ PATH_REC_FIELD(qos_class),
184	  .offset_words = 13,
185	  .offset_bits  = 0,
186	  .size_bits    = 12 },
187	{ PATH_REC_FIELD(sl),
188	  .offset_words = 13,
189	  .offset_bits  = 12,
190	  .size_bits    = 4 },
191	{ PATH_REC_FIELD(mtu_selector),
192	  .offset_words = 13,
193	  .offset_bits  = 16,
194	  .size_bits    = 2 },
195	{ PATH_REC_FIELD(mtu),
196	  .offset_words = 13,
197	  .offset_bits  = 18,
198	  .size_bits    = 6 },
199	{ PATH_REC_FIELD(rate_selector),
200	  .offset_words = 13,
201	  .offset_bits  = 24,
202	  .size_bits    = 2 },
203	{ PATH_REC_FIELD(rate),
204	  .offset_words = 13,
205	  .offset_bits  = 26,
206	  .size_bits    = 6 },
207	{ PATH_REC_FIELD(packet_life_time_selector),
208	  .offset_words = 14,
209	  .offset_bits  = 0,
210	  .size_bits    = 2 },
211	{ PATH_REC_FIELD(packet_life_time),
212	  .offset_words = 14,
213	  .offset_bits  = 2,
214	  .size_bits    = 6 },
215	{ PATH_REC_FIELD(preference),
216	  .offset_words = 14,
217	  .offset_bits  = 8,
218	  .size_bits    = 8 },
219	{ RESERVED,
220	  .offset_words = 14,
221	  .offset_bits  = 16,
222	  .size_bits    = 48 },
223};
224
225#define MCMEMBER_REC_FIELD(field) \
226	.struct_offset_bytes = offsetof(struct ib_sa_mcmember_rec, field),	\
227	.struct_size_bytes   = sizeof ((struct ib_sa_mcmember_rec *) 0)->field,	\
228	.field_name          = "sa_mcmember_rec:" #field
229
230static const struct ib_field mcmember_rec_table[] = {
231	{ MCMEMBER_REC_FIELD(mgid),
232	  .offset_words = 0,
233	  .offset_bits  = 0,
234	  .size_bits    = 128 },
235	{ MCMEMBER_REC_FIELD(port_gid),
236	  .offset_words = 4,
237	  .offset_bits  = 0,
238	  .size_bits    = 128 },
239	{ MCMEMBER_REC_FIELD(qkey),
240	  .offset_words = 8,
241	  .offset_bits  = 0,
242	  .size_bits    = 32 },
243	{ MCMEMBER_REC_FIELD(mlid),
244	  .offset_words = 9,
245	  .offset_bits  = 0,
246	  .size_bits    = 16 },
247	{ MCMEMBER_REC_FIELD(mtu_selector),
248	  .offset_words = 9,
249	  .offset_bits  = 16,
250	  .size_bits    = 2 },
251	{ MCMEMBER_REC_FIELD(mtu),
252	  .offset_words = 9,
253	  .offset_bits  = 18,
254	  .size_bits    = 6 },
255	{ MCMEMBER_REC_FIELD(traffic_class),
256	  .offset_words = 9,
257	  .offset_bits  = 24,
258	  .size_bits    = 8 },
259	{ MCMEMBER_REC_FIELD(pkey),
260	  .offset_words = 10,
261	  .offset_bits  = 0,
262	  .size_bits    = 16 },
263	{ MCMEMBER_REC_FIELD(rate_selector),
264	  .offset_words = 10,
265	  .offset_bits  = 16,
266	  .size_bits    = 2 },
267	{ MCMEMBER_REC_FIELD(rate),
268	  .offset_words = 10,
269	  .offset_bits  = 18,
270	  .size_bits    = 6 },
271	{ MCMEMBER_REC_FIELD(packet_life_time_selector),
272	  .offset_words = 10,
273	  .offset_bits  = 24,
274	  .size_bits    = 2 },
275	{ MCMEMBER_REC_FIELD(packet_life_time),
276	  .offset_words = 10,
277	  .offset_bits  = 26,
278	  .size_bits    = 6 },
279	{ MCMEMBER_REC_FIELD(sl),
280	  .offset_words = 11,
281	  .offset_bits  = 0,
282	  .size_bits    = 4 },
283	{ MCMEMBER_REC_FIELD(flow_label),
284	  .offset_words = 11,
285	  .offset_bits  = 4,
286	  .size_bits    = 20 },
287	{ MCMEMBER_REC_FIELD(hop_limit),
288	  .offset_words = 11,
289	  .offset_bits  = 24,
290	  .size_bits    = 8 },
291	{ MCMEMBER_REC_FIELD(scope),
292	  .offset_words = 12,
293	  .offset_bits  = 0,
294	  .size_bits    = 4 },
295	{ MCMEMBER_REC_FIELD(join_state),
296	  .offset_words = 12,
297	  .offset_bits  = 4,
298	  .size_bits    = 4 },
299	{ MCMEMBER_REC_FIELD(proxy_join),
300	  .offset_words = 12,
301	  .offset_bits  = 8,
302	  .size_bits    = 1 },
303	{ RESERVED,
304	  .offset_words = 12,
305	  .offset_bits  = 9,
306	  .size_bits    = 23 },
307};
308
309#define SERVICE_REC_FIELD(field) \
310	.struct_offset_bytes = offsetof(struct ib_sa_service_rec, field),	\
311	.struct_size_bytes   = sizeof ((struct ib_sa_service_rec *) 0)->field,	\
312	.field_name          = "sa_service_rec:" #field
313
314static const struct ib_field service_rec_table[] = {
315	{ SERVICE_REC_FIELD(id),
316	  .offset_words = 0,
317	  .offset_bits  = 0,
318	  .size_bits    = 64 },
319	{ SERVICE_REC_FIELD(gid),
320	  .offset_words = 2,
321	  .offset_bits  = 0,
322	  .size_bits    = 128 },
323	{ SERVICE_REC_FIELD(pkey),
324	  .offset_words = 6,
325	  .offset_bits  = 0,
326	  .size_bits    = 16 },
327	{ SERVICE_REC_FIELD(lease),
328	  .offset_words = 7,
329	  .offset_bits  = 0,
330	  .size_bits    = 32 },
331	{ SERVICE_REC_FIELD(key),
332	  .offset_words = 8,
333	  .offset_bits  = 0,
334	  .size_bits    = 128 },
335	{ SERVICE_REC_FIELD(name),
336	  .offset_words = 12,
337	  .offset_bits  = 0,
338	  .size_bits    = 64*8 },
339	{ SERVICE_REC_FIELD(data8),
340	  .offset_words = 28,
341	  .offset_bits  = 0,
342	  .size_bits    = 16*8 },
343	{ SERVICE_REC_FIELD(data16),
344	  .offset_words = 32,
345	  .offset_bits  = 0,
346	  .size_bits    = 8*16 },
347	{ SERVICE_REC_FIELD(data32),
348	  .offset_words = 36,
349	  .offset_bits  = 0,
350	  .size_bits    = 4*32 },
351	{ SERVICE_REC_FIELD(data64),
352	  .offset_words = 40,
353	  .offset_bits  = 0,
354	  .size_bits    = 2*64 },
355};
356
357#define INFORM_FIELD(field) \
358	.struct_offset_bytes = offsetof(struct ib_sa_inform, field), \
359	.struct_size_bytes   = sizeof ((struct ib_sa_inform *) 0)->field, \
360	.field_name          = "sa_inform:" #field
361
362static const struct ib_field inform_table[] = {
363	{ INFORM_FIELD(gid),
364	  .offset_words = 0,
365	  .offset_bits  = 0,
366	  .size_bits    = 128 },
367	{ INFORM_FIELD(lid_range_begin),
368	  .offset_words = 4,
369	  .offset_bits  = 0,
370	  .size_bits    = 16 },
371	{ INFORM_FIELD(lid_range_end),
372	  .offset_words = 4,
373	  .offset_bits  = 16,
374	  .size_bits    = 16 },
375	{ RESERVED,
376	  .offset_words = 5,
377	  .offset_bits  = 0,
378	  .size_bits    = 16 },
379	{ INFORM_FIELD(is_generic),
380	  .offset_words = 5,
381	  .offset_bits  = 16,
382	  .size_bits    = 8 },
383	{ INFORM_FIELD(subscribe),
384	  .offset_words = 5,
385	  .offset_bits  = 24,
386	  .size_bits    = 8 },
387	{ INFORM_FIELD(type),
388	  .offset_words = 6,
389	  .offset_bits  = 0,
390	  .size_bits    = 16 },
391	{ INFORM_FIELD(trap.generic.trap_num),
392	  .offset_words = 6,
393	  .offset_bits  = 16,
394	  .size_bits    = 16 },
395	{ INFORM_FIELD(trap.generic.qpn),
396	  .offset_words = 7,
397	  .offset_bits  = 0,
398	  .size_bits    = 24 },
399	{ RESERVED,
400	  .offset_words = 7,
401	  .offset_bits  = 24,
402	  .size_bits    = 3 },
403	{ INFORM_FIELD(trap.generic.resp_time),
404	  .offset_words = 7,
405	  .offset_bits  = 27,
406	  .size_bits    = 5 },
407	{ RESERVED,
408	  .offset_words = 8,
409	  .offset_bits  = 0,
410	  .size_bits    = 8 },
411	{ INFORM_FIELD(trap.generic.producer_type),
412	  .offset_words = 8,
413	  .offset_bits  = 8,
414	  .size_bits    = 24 },
415};
416
417#define NOTICE_FIELD(field) \
418	.struct_offset_bytes = offsetof(struct ib_sa_notice, field), \
419	.struct_size_bytes   = sizeof ((struct ib_sa_notice *) 0)->field, \
420	.field_name          = "sa_notice:" #field
421
422static const struct ib_field notice_table[] = {
423	{ NOTICE_FIELD(is_generic),
424	  .offset_words = 0,
425	  .offset_bits  = 0,
426	  .size_bits    = 1 },
427	{ NOTICE_FIELD(type),
428	  .offset_words = 0,
429	  .offset_bits  = 1,
430	  .size_bits    = 7 },
431	{ NOTICE_FIELD(trap.generic.producer_type),
432	  .offset_words = 0,
433	  .offset_bits  = 8,
434	  .size_bits    = 24 },
435	{ NOTICE_FIELD(trap.generic.trap_num),
436	  .offset_words = 1,
437	  .offset_bits  = 0,
438	  .size_bits    = 16 },
439	{ NOTICE_FIELD(issuer_lid),
440	  .offset_words = 1,
441	  .offset_bits  = 16,
442	  .size_bits    = 16 },
443	{ NOTICE_FIELD(notice_toggle),
444	  .offset_words = 2,
445	  .offset_bits  = 0,
446	  .size_bits    = 1 },
447	{ NOTICE_FIELD(notice_count),
448	  .offset_words = 2,
449	  .offset_bits  = 1,
450	  .size_bits    = 15 },
451	{ NOTICE_FIELD(data_details),
452	  .offset_words = 2,
453	  .offset_bits  = 16,
454	  .size_bits    = 432 },
455	{ NOTICE_FIELD(issuer_gid),
456	  .offset_words = 16,
457	  .offset_bits  = 0,
458	  .size_bits    = 128 },
459};
460
461int ib_sa_check_selector(ib_sa_comp_mask comp_mask,
462			 ib_sa_comp_mask selector_mask,
463			 ib_sa_comp_mask value_mask,
464			 u8 selector, u8 src_value, u8 dst_value)
465{
466	int err;
467
468	if (!(comp_mask & selector_mask) || !(comp_mask & value_mask))
469		return 0;
470
471	switch (selector) {
472	case IB_SA_GT:
473		err = (src_value <= dst_value);
474		break;
475	case IB_SA_LT:
476		err = (src_value >= dst_value);
477		break;
478	case IB_SA_EQ:
479		err = (src_value != dst_value);
480		break;
481	default:
482		err = 0;
483		break;
484	}
485
486	return err;
487}
488
489int ib_sa_pack_attr(void *dst, void *src, int attr_id)
490{
491	switch (attr_id) {
492	case IB_SA_ATTR_PATH_REC:
493		ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), src, dst);
494		break;
495	default:
496		return -EINVAL;
497	}
498	return 0;
499}
500
501int ib_sa_unpack_attr(void *dst, void *src, int attr_id)
502{
503	switch (attr_id) {
504	case IB_SA_ATTR_PATH_REC:
505		ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), src, dst);
506		break;
507	default:
508		return -EINVAL;
509	}
510	return 0;
511}
512
513static void free_sm_ah(struct kref *kref)
514{
515	struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
516
517	ib_destroy_ah(sm_ah->ah);
518	kfree(sm_ah);
519}
520
521static void update_sm_ah(struct work_struct *work)
522{
523	struct ib_sa_port *port =
524		container_of(work, struct ib_sa_port, update_task);
525	struct ib_sa_sm_ah *new_ah;
526	struct ib_port_attr port_attr;
527	struct ib_ah_attr   ah_attr;
528
529	if (ib_query_port(port->agent->device, port->port_num, &port_attr)) {
530		printk(KERN_WARNING "Couldn't query port\n");
531		return;
532	}
533
534	new_ah = kmalloc(sizeof *new_ah, GFP_KERNEL);
535	if (!new_ah) {
536		printk(KERN_WARNING "Couldn't allocate new SM AH\n");
537		return;
538	}
539
540	kref_init(&new_ah->ref);
541	new_ah->src_path_mask = (1 << port_attr.lmc) - 1;
542
543	new_ah->pkey_index = 0;
544	if (ib_find_pkey(port->agent->device, port->port_num,
545			 IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index))
546		printk(KERN_ERR "Couldn't find index for default PKey\n");
547
548	memset(&ah_attr, 0, sizeof ah_attr);
549	ah_attr.dlid     = port_attr.sm_lid;
550	ah_attr.sl       = port_attr.sm_sl;
551	ah_attr.port_num = port->port_num;
552
553	new_ah->ah = ib_create_ah(port->agent->qp->pd, &ah_attr);
554	if (IS_ERR(new_ah->ah)) {
555		printk(KERN_WARNING "Couldn't create new SM AH\n");
556		kfree(new_ah);
557		return;
558	}
559
560	spin_lock_irq(&port->ah_lock);
561	if (port->sm_ah)
562		kref_put(&port->sm_ah->ref, free_sm_ah);
563	port->sm_ah = new_ah;
564	spin_unlock_irq(&port->ah_lock);
565
566}
567
568static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event)
569{
570	if (event->event == IB_EVENT_PORT_ERR    ||
571	    event->event == IB_EVENT_PORT_ACTIVE ||
572	    event->event == IB_EVENT_LID_CHANGE  ||
573	    event->event == IB_EVENT_PKEY_CHANGE ||
574	    event->event == IB_EVENT_SM_CHANGE   ||
575	    event->event == IB_EVENT_CLIENT_REREGISTER) {
576		unsigned long flags;
577		struct ib_sa_device *sa_dev =
578			container_of(handler, typeof(*sa_dev), event_handler);
579		struct ib_sa_port *port =
580			&sa_dev->port[event->element.port_num - sa_dev->start_port];
581
582		if (rdma_port_get_link_layer(handler->device, port->port_num) != IB_LINK_LAYER_INFINIBAND)
583			return;
584
585		spin_lock_irqsave(&port->ah_lock, flags);
586		if (port->sm_ah)
587			kref_put(&port->sm_ah->ref, free_sm_ah);
588		port->sm_ah = NULL;
589		spin_unlock_irqrestore(&port->ah_lock, flags);
590
591		schedule_work(&sa_dev->port[event->element.port_num -
592					    sa_dev->start_port].update_task);
593	}
594}
595
596void ib_sa_register_client(struct ib_sa_client *client)
597{
598	atomic_set(&client->users, 1);
599	init_completion(&client->comp);
600}
601EXPORT_SYMBOL(ib_sa_register_client);
602
603void ib_sa_unregister_client(struct ib_sa_client *client)
604{
605	ib_sa_client_put(client);
606	wait_for_completion(&client->comp);
607}
608EXPORT_SYMBOL(ib_sa_unregister_client);
609
610/**
611 * ib_sa_cancel_query - try to cancel an SA query
612 * @id:ID of query to cancel
613 * @query:query pointer to cancel
614 *
615 * Try to cancel an SA query.  If the id and query don't match up or
616 * the query has already completed, nothing is done.  Otherwise the
617 * query is canceled and will complete with a status of -EINTR.
618 */
619void ib_sa_cancel_query(int id, struct ib_sa_query *query)
620{
621	unsigned long flags;
622	struct ib_mad_agent *agent;
623	struct ib_mad_send_buf *mad_buf;
624
625	spin_lock_irqsave(&idr_lock, flags);
626	if (idr_find(&query_idr, id) != query) {
627		spin_unlock_irqrestore(&idr_lock, flags);
628		return;
629	}
630	agent = query->port->agent;
631	mad_buf = query->mad_buf;
632	spin_unlock_irqrestore(&idr_lock, flags);
633
634	ib_cancel_mad(agent, mad_buf);
635}
636EXPORT_SYMBOL(ib_sa_cancel_query);
637
638static u8 get_src_path_mask(struct ib_device *device, u8 port_num)
639{
640	struct ib_sa_device *sa_dev;
641	struct ib_sa_port   *port;
642	unsigned long flags;
643	u8 src_path_mask;
644
645	sa_dev = ib_get_client_data(device, &sa_client);
646	if (!sa_dev)
647		return 0x7f;
648
649	port  = &sa_dev->port[port_num - sa_dev->start_port];
650	spin_lock_irqsave(&port->ah_lock, flags);
651	src_path_mask = port->sm_ah ? port->sm_ah->src_path_mask : 0x7f;
652	spin_unlock_irqrestore(&port->ah_lock, flags);
653
654	return src_path_mask;
655}
656
657int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
658			 struct ib_sa_path_rec *rec, struct ib_ah_attr *ah_attr)
659{
660	int ret;
661	u16 gid_index;
662	int force_grh;
663
664	memset(ah_attr, 0, sizeof *ah_attr);
665	ah_attr->dlid = be16_to_cpu(rec->dlid);
666	ah_attr->sl = rec->sl;
667	ah_attr->src_path_bits = be16_to_cpu(rec->slid) &
668				 get_src_path_mask(device, port_num);
669	ah_attr->port_num = port_num;
670	ah_attr->static_rate = rec->rate;
671
672	force_grh = rdma_port_get_link_layer(device, port_num) == IB_LINK_LAYER_ETHERNET;
673
674	if (rec->hop_limit > 1 || force_grh) {
675		ah_attr->ah_flags = IB_AH_GRH;
676		ah_attr->grh.dgid = rec->dgid;
677
678		ret = ib_find_cached_gid(device, &rec->sgid, &port_num,
679					 &gid_index);
680		if (ret)
681			return ret;
682
683		ah_attr->grh.sgid_index    = gid_index;
684		ah_attr->grh.flow_label    = be32_to_cpu(rec->flow_label);
685		ah_attr->grh.hop_limit     = rec->hop_limit;
686		ah_attr->grh.traffic_class = rec->traffic_class;
687	}
688	return 0;
689}
690EXPORT_SYMBOL(ib_init_ah_from_path);
691
692static int alloc_mad(struct ib_sa_query *query, gfp_t gfp_mask)
693{
694	unsigned long flags;
695
696	spin_lock_irqsave(&query->port->ah_lock, flags);
697	if (!query->port->sm_ah) {
698		spin_unlock_irqrestore(&query->port->ah_lock, flags);
699		return -EAGAIN;
700	}
701	kref_get(&query->port->sm_ah->ref);
702	query->sm_ah = query->port->sm_ah;
703	spin_unlock_irqrestore(&query->port->ah_lock, flags);
704
705	query->mad_buf = ib_create_send_mad(query->port->agent, 1,
706					    query->sm_ah->pkey_index,
707					    0, IB_MGMT_SA_HDR, IB_MGMT_SA_DATA,
708					    gfp_mask);
709	if (IS_ERR(query->mad_buf)) {
710		kref_put(&query->sm_ah->ref, free_sm_ah);
711		return -ENOMEM;
712	}
713
714	query->mad_buf->ah = query->sm_ah->ah;
715
716	return 0;
717}
718
719static void free_mad(struct ib_sa_query *query)
720{
721	ib_free_send_mad(query->mad_buf);
722	kref_put(&query->sm_ah->ref, free_sm_ah);
723}
724
725static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent)
726{
727	unsigned long flags;
728
729	memset(mad, 0, sizeof *mad);
730
731	mad->mad_hdr.base_version  = IB_MGMT_BASE_VERSION;
732	mad->mad_hdr.mgmt_class    = IB_MGMT_CLASS_SUBN_ADM;
733	mad->mad_hdr.class_version = IB_SA_CLASS_VERSION;
734
735	spin_lock_irqsave(&tid_lock, flags);
736	mad->mad_hdr.tid           =
737		cpu_to_be64(((u64) agent->hi_tid) << 32 | tid++);
738	spin_unlock_irqrestore(&tid_lock, flags);
739}
740
741static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
742{
743	unsigned long flags;
744	int ret, id;
745
746retry:
747	if (!idr_pre_get(&query_idr, gfp_mask))
748		return -ENOMEM;
749	spin_lock_irqsave(&idr_lock, flags);
750	ret = idr_get_new(&query_idr, query, &id);
751	spin_unlock_irqrestore(&idr_lock, flags);
752	if (ret == -EAGAIN)
753		goto retry;
754	if (ret)
755		return ret;
756
757	query->mad_buf->timeout_ms  = timeout_ms;
758	query->mad_buf->context[0] = query;
759	query->id = id;
760
761	ret = ib_post_send_mad(query->mad_buf, NULL);
762	if (ret) {
763		spin_lock_irqsave(&idr_lock, flags);
764		idr_remove(&query_idr, id);
765		spin_unlock_irqrestore(&idr_lock, flags);
766	}
767
768	/*
769	 * It's not safe to dereference query any more, because the
770	 * send may already have completed and freed the query in
771	 * another context.
772	 */
773	return ret ? ret : id;
774}
775
776void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec)
777{
778	ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), attribute, rec);
779}
780EXPORT_SYMBOL(ib_sa_unpack_path);
781
782static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
783				    int status,
784				    struct ib_sa_mad *mad)
785{
786	struct ib_sa_path_query *query =
787		container_of(sa_query, struct ib_sa_path_query, sa_query);
788
789	if (mad) {
790		struct ib_sa_path_rec rec;
791
792		ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table),
793			  mad->data, &rec);
794		query->callback(status, &rec, query->context);
795	} else
796		query->callback(status, NULL, query->context);
797}
798
799static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
800{
801	kfree(container_of(sa_query, struct ib_sa_path_query, sa_query));
802}
803
804int ib_sa_path_rec_query(struct ib_sa_client *client,
805			 struct ib_device *device, u8 port_num,
806			 struct ib_sa_path_rec *rec,
807			 ib_sa_comp_mask comp_mask,
808			 int timeout_ms, gfp_t gfp_mask,
809			 void (*callback)(int status,
810					  struct ib_sa_path_rec *resp,
811					  void *context),
812			 void *context,
813			 struct ib_sa_query **sa_query)
814{
815	struct ib_sa_path_query *query;
816	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
817	struct ib_sa_port   *port;
818	struct ib_mad_agent *agent;
819	struct ib_sa_mad *mad;
820	int ret;
821
822	if (!sa_dev)
823		return -ENODEV;
824
825	port  = &sa_dev->port[port_num - sa_dev->start_port];
826	agent = port->agent;
827
828	query = kmalloc(sizeof *query, gfp_mask);
829	if (!query)
830		return -ENOMEM;
831
832	query->sa_query.port     = port;
833	ret = alloc_mad(&query->sa_query, gfp_mask);
834	if (ret)
835		goto err1;
836
837	ib_sa_client_get(client);
838	query->sa_query.client = client;
839	query->callback        = callback;
840	query->context         = context;
841
842	mad = query->sa_query.mad_buf->mad;
843	init_mad(mad, agent);
844
845	query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL;
846	query->sa_query.release  = ib_sa_path_rec_release;
847	mad->mad_hdr.method	 = IB_MGMT_METHOD_GET;
848	mad->mad_hdr.attr_id	 = cpu_to_be16(IB_SA_ATTR_PATH_REC);
849	mad->sa_hdr.comp_mask	 = comp_mask;
850
851	ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), rec, mad->data);
852
853	*sa_query = &query->sa_query;
854
855	ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
856	if (ret < 0)
857		goto err2;
858
859	return ret;
860
861err2:
862	*sa_query = NULL;
863	ib_sa_client_put(query->sa_query.client);
864	free_mad(&query->sa_query);
865
866err1:
867	kfree(query);
868	return ret;
869}
870
871static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query,
872				    int status,
873				    struct ib_sa_mad *mad)
874{
875	struct ib_sa_service_query *query =
876		container_of(sa_query, struct ib_sa_service_query, sa_query);
877
878	if (mad) {
879		struct ib_sa_service_rec rec;
880
881		ib_unpack(service_rec_table, ARRAY_SIZE(service_rec_table),
882			  mad->data, &rec);
883		query->callback(status, &rec, query->context);
884	} else
885		query->callback(status, NULL, query->context);
886}
887
888static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
889{
890	kfree(container_of(sa_query, struct ib_sa_service_query, sa_query));
891}
892
893/**
894 * ib_sa_service_rec_query - Start Service Record operation
895 * @client:SA client
896 * @device:device to send request on
897 * @port_num: port number to send request on
898 * @method:SA method - should be get, set, or delete
899 * @rec:Service Record to send in request
900 * @comp_mask:component mask to send in request
901 * @timeout_ms:time to wait for response
902 * @gfp_mask:GFP mask to use for internal allocations
903 * @callback:function called when request completes, times out or is
904 * canceled
905 * @context:opaque user context passed to callback
906 * @sa_query:request context, used to cancel request
907 *
908 * Send a Service Record set/get/delete to the SA to register,
909 * unregister or query a service record.
910 * The callback function will be called when the request completes (or
911 * fails); status is 0 for a successful response, -EINTR if the query
912 * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
913 * occurred sending the query.  The resp parameter of the callback is
914 * only valid if status is 0.
915 *
916 * If the return value of ib_sa_service_rec_query() is negative, it is an
917 * error code.  Otherwise it is a request ID that can be used to cancel
918 * the query.
919 */
920int ib_sa_service_rec_query(struct ib_sa_client *client,
921			    struct ib_device *device, u8 port_num, u8 method,
922			    struct ib_sa_service_rec *rec,
923			    ib_sa_comp_mask comp_mask,
924			    int timeout_ms, gfp_t gfp_mask,
925			    void (*callback)(int status,
926					     struct ib_sa_service_rec *resp,
927					     void *context),
928			    void *context,
929			    struct ib_sa_query **sa_query)
930{
931	struct ib_sa_service_query *query;
932	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
933	struct ib_sa_port   *port;
934	struct ib_mad_agent *agent;
935	struct ib_sa_mad *mad;
936	int ret;
937
938	if (!sa_dev)
939		return -ENODEV;
940
941	port  = &sa_dev->port[port_num - sa_dev->start_port];
942	agent = port->agent;
943
944	if (method != IB_MGMT_METHOD_GET &&
945	    method != IB_MGMT_METHOD_SET &&
946	    method != IB_SA_METHOD_DELETE)
947		return -EINVAL;
948
949	query = kmalloc(sizeof *query, gfp_mask);
950	if (!query)
951		return -ENOMEM;
952
953	query->sa_query.port     = port;
954	ret = alloc_mad(&query->sa_query, gfp_mask);
955	if (ret)
956		goto err1;
957
958	ib_sa_client_get(client);
959	query->sa_query.client = client;
960	query->callback        = callback;
961	query->context         = context;
962
963	mad = query->sa_query.mad_buf->mad;
964	init_mad(mad, agent);
965
966	query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL;
967	query->sa_query.release  = ib_sa_service_rec_release;
968	mad->mad_hdr.method	 = method;
969	mad->mad_hdr.attr_id	 = cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
970	mad->sa_hdr.comp_mask	 = comp_mask;
971
972	ib_pack(service_rec_table, ARRAY_SIZE(service_rec_table),
973		rec, mad->data);
974
975	*sa_query = &query->sa_query;
976
977	ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
978	if (ret < 0)
979		goto err2;
980
981	return ret;
982
983err2:
984	*sa_query = NULL;
985	ib_sa_client_put(query->sa_query.client);
986	free_mad(&query->sa_query);
987
988err1:
989	kfree(query);
990	return ret;
991}
992EXPORT_SYMBOL(ib_sa_service_rec_query);
993
994static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query,
995					int status,
996					struct ib_sa_mad *mad)
997{
998	struct ib_sa_mcmember_query *query =
999		container_of(sa_query, struct ib_sa_mcmember_query, sa_query);
1000
1001	if (mad) {
1002		struct ib_sa_mcmember_rec rec;
1003
1004		ib_unpack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
1005			  mad->data, &rec);
1006		query->callback(status, &rec, query->context);
1007	} else
1008		query->callback(status, NULL, query->context);
1009}
1010
1011static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query)
1012{
1013	kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query));
1014}
1015
1016int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
1017			     struct ib_device *device, u8 port_num,
1018			     u8 method,
1019			     struct ib_sa_mcmember_rec *rec,
1020			     ib_sa_comp_mask comp_mask,
1021			     int timeout_ms, gfp_t gfp_mask,
1022			     void (*callback)(int status,
1023					      struct ib_sa_mcmember_rec *resp,
1024					      void *context),
1025			     void *context,
1026			     struct ib_sa_query **sa_query)
1027{
1028	struct ib_sa_mcmember_query *query;
1029	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
1030	struct ib_sa_port   *port;
1031	struct ib_mad_agent *agent;
1032	struct ib_sa_mad *mad;
1033	int ret;
1034
1035	if (!sa_dev)
1036		return -ENODEV;
1037
1038	port  = &sa_dev->port[port_num - sa_dev->start_port];
1039	agent = port->agent;
1040
1041	query = kmalloc(sizeof *query, gfp_mask);
1042	if (!query)
1043		return -ENOMEM;
1044
1045	query->sa_query.port     = port;
1046	ret = alloc_mad(&query->sa_query, gfp_mask);
1047	if (ret)
1048		goto err1;
1049
1050	ib_sa_client_get(client);
1051	query->sa_query.client = client;
1052	query->callback        = callback;
1053	query->context         = context;
1054
1055	mad = query->sa_query.mad_buf->mad;
1056	init_mad(mad, agent);
1057
1058	query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL;
1059	query->sa_query.release  = ib_sa_mcmember_rec_release;
1060	mad->mad_hdr.method	 = method;
1061	mad->mad_hdr.attr_id	 = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC);
1062	mad->sa_hdr.comp_mask	 = comp_mask;
1063
1064	ib_pack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
1065		rec, mad->data);
1066
1067	*sa_query = &query->sa_query;
1068
1069	ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
1070	if (ret < 0)
1071		goto err2;
1072
1073	return ret;
1074
1075err2:
1076	*sa_query = NULL;
1077	ib_sa_client_put(query->sa_query.client);
1078	free_mad(&query->sa_query);
1079
1080err1:
1081	kfree(query);
1082	return ret;
1083}
1084
1085static void ib_sa_inform_callback(struct ib_sa_query *sa_query,
1086				  int status,
1087				  struct ib_sa_mad *mad)
1088{
1089	struct ib_sa_inform_query *query =
1090		container_of(sa_query, struct ib_sa_inform_query, sa_query);
1091
1092	if (mad) {
1093		struct ib_sa_inform rec;
1094
1095		ib_unpack(inform_table, ARRAY_SIZE(inform_table),
1096			  mad->data, &rec);
1097		query->callback(status, &rec, query->context);
1098	} else
1099		query->callback(status, NULL, query->context);
1100}
1101
1102static void ib_sa_inform_release(struct ib_sa_query *sa_query)
1103{
1104	kfree(container_of(sa_query, struct ib_sa_inform_query, sa_query));
1105}
1106
1107int ib_sa_guid_info_rec_query(struct ib_sa_client *client,
1108			      struct ib_device *device, u8 port_num,
1109			      struct ib_sa_guidinfo_rec *rec,
1110			      ib_sa_comp_mask comp_mask, u8 method,
1111			      int timeout_ms, gfp_t gfp_mask,
1112			      void (*callback)(int status,
1113					       struct ib_sa_guidinfo_rec *resp,
1114					       void *context),
1115			      void *context,
1116			      struct ib_sa_query **sa_query)
1117{
1118	// stub function -
1119        // called originally from mad.c under mlx4_ib_init_sriov()
1120        // which calls mlx4_ib_init_alias_guid_service() in alias_GUID.c
1121        // which goes down to this function
1122
1123        printk("ERROR: function should be called only in SRIOV flow!!!");
1124
1125	return 0;
1126}
1127
1128/**
1129 * ib_sa_informinfo_query - Start an InformInfo registration.
1130 * @client:SA client
1131 * @device:device to send query on
1132 * @port_num: port number to send query on
1133 * @rec:Inform record to send in query
1134 * @timeout_ms:time to wait for response
1135 * @gfp_mask:GFP mask to use for internal allocations
1136 * @callback:function called when notice handler registration completes,
1137 * times out or is canceled
1138 * @context:opaque user context passed to callback
1139 * @sa_query:query context, used to cancel query
1140 *
1141 * This function sends inform info to register with SA to receive
1142 * in-service notice.
1143 * The callback function will be called when the query completes (or
1144 * fails); status is 0 for a successful response, -EINTR if the query
1145 * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
1146 * occurred sending the query.  The resp parameter of the callback is
1147 * only valid if status is 0.
1148 *
1149 * If the return value of ib_sa_inform_query() is negative, it is an
1150 * error code.  Otherwise it is a query ID that can be used to cancel
1151 * the query.
1152 */
1153int ib_sa_informinfo_query(struct ib_sa_client *client,
1154			   struct ib_device *device, u8 port_num,
1155			   struct ib_sa_inform *rec,
1156			   int timeout_ms, gfp_t gfp_mask,
1157			   void (*callback)(int status,
1158					   struct ib_sa_inform *resp,
1159					   void *context),
1160			   void *context,
1161			   struct ib_sa_query **sa_query)
1162{
1163	struct ib_sa_inform_query *query;
1164	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
1165	struct ib_sa_port   *port;
1166	struct ib_mad_agent *agent;
1167	struct ib_sa_mad *mad;
1168	int ret;
1169
1170	if (!sa_dev)
1171		return -ENODEV;
1172
1173	port  = &sa_dev->port[port_num - sa_dev->start_port];
1174	agent = port->agent;
1175
1176	query = kmalloc(sizeof *query, gfp_mask);
1177	if (!query)
1178		return -ENOMEM;
1179
1180	query->sa_query.port     = port;
1181	ret = alloc_mad(&query->sa_query, gfp_mask);
1182	if (ret)
1183		goto err1;
1184
1185	ib_sa_client_get(client);
1186	query->sa_query.client = client;
1187	query->callback = callback;
1188	query->context  = context;
1189
1190	mad = query->sa_query.mad_buf->mad;
1191	init_mad(mad, agent);
1192
1193	query->sa_query.callback = callback ? ib_sa_inform_callback : NULL;
1194	query->sa_query.release  = ib_sa_inform_release;
1195	query->sa_query.port     = port;
1196	mad->mad_hdr.method	 = IB_MGMT_METHOD_SET;
1197	mad->mad_hdr.attr_id	 = cpu_to_be16(IB_SA_ATTR_INFORM_INFO);
1198
1199	ib_pack(inform_table, ARRAY_SIZE(inform_table), rec, mad->data);
1200
1201	*sa_query = &query->sa_query;
1202	ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
1203	if (ret < 0)
1204		goto err2;
1205
1206	return ret;
1207
1208err2:
1209	*sa_query = NULL;
1210	ib_sa_client_put(query->sa_query.client);
1211	free_mad(&query->sa_query);
1212err1:
1213	kfree(query);
1214	return ret;
1215}
1216
1217static void ib_sa_notice_resp(struct ib_sa_port *port,
1218			      struct ib_mad_recv_wc *mad_recv_wc)
1219{
1220	struct ib_mad_send_buf *mad_buf;
1221	struct ib_sa_mad *mad;
1222	int ret;
1223	unsigned long flags;
1224
1225	mad_buf = ib_create_send_mad(port->notice_agent, 1, 0, 0,
1226				     IB_MGMT_SA_HDR, IB_MGMT_SA_DATA,
1227				     GFP_KERNEL);
1228	if (IS_ERR(mad_buf))
1229		return;
1230
1231	mad = mad_buf->mad;
1232	memcpy(mad, mad_recv_wc->recv_buf.mad, sizeof *mad);
1233	mad->mad_hdr.method = IB_MGMT_METHOD_REPORT_RESP;
1234
1235	spin_lock_irqsave(&port->ah_lock, flags);
1236	if (!port->sm_ah) {
1237		spin_unlock_irqrestore(&port->ah_lock, flags);
1238		ib_free_send_mad(mad_buf);
1239		return;
1240	}
1241	kref_get(&port->sm_ah->ref);
1242	mad_buf->context[0] = &port->sm_ah->ref;
1243	mad_buf->ah = port->sm_ah->ah;
1244	spin_unlock_irqrestore(&port->ah_lock, flags);
1245
1246	ret = ib_post_send_mad(mad_buf, NULL);
1247	if (ret)
1248		goto err;
1249
1250	return;
1251err:
1252	kref_put(mad_buf->context[0], free_sm_ah);
1253	ib_free_send_mad(mad_buf);
1254}
1255
1256static void send_handler(struct ib_mad_agent *agent,
1257			 struct ib_mad_send_wc *mad_send_wc)
1258{
1259	struct ib_sa_query *query = mad_send_wc->send_buf->context[0];
1260	unsigned long flags;
1261
1262	if (query->callback)
1263		switch (mad_send_wc->status) {
1264		case IB_WC_SUCCESS:
1265			/* No callback -- already got recv */
1266			break;
1267		case IB_WC_RESP_TIMEOUT_ERR:
1268			query->callback(query, -ETIMEDOUT, NULL);
1269			break;
1270		case IB_WC_WR_FLUSH_ERR:
1271			query->callback(query, -EINTR, NULL);
1272			break;
1273		default:
1274			query->callback(query, -EIO, NULL);
1275			break;
1276		}
1277
1278	spin_lock_irqsave(&idr_lock, flags);
1279	idr_remove(&query_idr, query->id);
1280	spin_unlock_irqrestore(&idr_lock, flags);
1281
1282	free_mad(query);
1283	ib_sa_client_put(query->client);
1284	query->release(query);
1285}
1286
1287static void recv_handler(struct ib_mad_agent *mad_agent,
1288			 struct ib_mad_recv_wc *mad_recv_wc)
1289{
1290	struct ib_sa_query *query;
1291	struct ib_mad_send_buf *mad_buf;
1292
1293	mad_buf = (void *) (unsigned long) mad_recv_wc->wc->wr_id;
1294	query = mad_buf->context[0];
1295
1296	if (query->callback) {
1297		if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
1298			query->callback(query,
1299					mad_recv_wc->recv_buf.mad->mad_hdr.status ?
1300					-EINVAL : 0,
1301					(struct ib_sa_mad *) mad_recv_wc->recv_buf.mad);
1302		else
1303			query->callback(query, -EIO, NULL);
1304	}
1305
1306	ib_free_recv_mad(mad_recv_wc);
1307}
1308
1309static void notice_resp_handler(struct ib_mad_agent *agent,
1310				struct ib_mad_send_wc *mad_send_wc)
1311{
1312	kref_put(mad_send_wc->send_buf->context[0], free_sm_ah);
1313	ib_free_send_mad(mad_send_wc->send_buf);
1314}
1315
1316static void notice_handler(struct ib_mad_agent *mad_agent,
1317			   struct ib_mad_recv_wc *mad_recv_wc)
1318{
1319	struct ib_sa_port *port;
1320	struct ib_sa_mad *mad;
1321	struct ib_sa_notice notice;
1322
1323	port = mad_agent->context;
1324	mad = (struct ib_sa_mad *) mad_recv_wc->recv_buf.mad;
1325	ib_unpack(notice_table, ARRAY_SIZE(notice_table), mad->data, &notice);
1326
1327	if (!notice_dispatch(port->device, port->port_num, &notice))
1328		ib_sa_notice_resp(port, mad_recv_wc);
1329	ib_free_recv_mad(mad_recv_wc);
1330}
1331
1332static void ib_sa_add_one(struct ib_device *device)
1333{
1334	struct ib_sa_device *sa_dev;
1335	struct ib_mad_reg_req reg_req = {
1336		.mgmt_class = IB_MGMT_CLASS_SUBN_ADM,
1337		.mgmt_class_version = 2
1338	};
1339	int s, e, i;
1340
1341	if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
1342		return;
1343
1344	if (device->node_type == RDMA_NODE_IB_SWITCH)
1345		s = e = 0;
1346	else {
1347		s = 1;
1348		e = device->phys_port_cnt;
1349	}
1350
1351	sa_dev = kzalloc(sizeof *sa_dev +
1352			 (e - s + 1) * sizeof (struct ib_sa_port),
1353			 GFP_KERNEL);
1354	if (!sa_dev)
1355		return;
1356
1357	sa_dev->start_port = s;
1358	sa_dev->end_port   = e;
1359
1360	for (i = 0; i <= e - s; ++i) {
1361		spin_lock_init(&sa_dev->port[i].ah_lock);
1362		if (rdma_port_get_link_layer(device, i + 1) != IB_LINK_LAYER_INFINIBAND)
1363			continue;
1364
1365		sa_dev->port[i].sm_ah    = NULL;
1366		sa_dev->port[i].port_num = i + s;
1367
1368		sa_dev->port[i].agent =
1369			ib_register_mad_agent(device, i + s, IB_QPT_GSI,
1370					      NULL, 0, send_handler,
1371					      recv_handler, sa_dev);
1372		if (IS_ERR(sa_dev->port[i].agent))
1373			goto err;
1374
1375		sa_dev->port[i].device = device;
1376		set_bit(IB_MGMT_METHOD_REPORT, reg_req.method_mask);
1377		sa_dev->port[i].notice_agent =
1378			ib_register_mad_agent(device, i + s, IB_QPT_GSI,
1379					      &reg_req, 0, notice_resp_handler,
1380					      notice_handler, &sa_dev->port[i]);
1381
1382		if (IS_ERR(sa_dev->port[i].notice_agent))
1383			goto err;
1384
1385		INIT_WORK(&sa_dev->port[i].update_task, update_sm_ah);
1386	}
1387
1388	ib_set_client_data(device, &sa_client, sa_dev);
1389
1390	/*
1391	 * We register our event handler after everything is set up,
1392	 * and then update our cached info after the event handler is
1393	 * registered to avoid any problems if a port changes state
1394	 * during our initialization.
1395	 */
1396
1397	INIT_IB_EVENT_HANDLER(&sa_dev->event_handler, device, ib_sa_event);
1398	if (ib_register_event_handler(&sa_dev->event_handler))
1399		goto err;
1400
1401	for (i = 0; i <= e - s; ++i)
1402		if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND)
1403			update_sm_ah(&sa_dev->port[i].update_task);
1404
1405	return;
1406
1407err:
1408	while (--i >= 0)
1409		if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND) {
1410			if (!IS_ERR(sa_dev->port[i].notice_agent))
1411				ib_unregister_mad_agent(sa_dev->port[i].notice_agent);
1412			if (!IS_ERR(sa_dev->port[i].agent))
1413				ib_unregister_mad_agent(sa_dev->port[i].agent);
1414		}
1415
1416	kfree(sa_dev);
1417
1418	return;
1419}
1420
1421static void ib_sa_remove_one(struct ib_device *device)
1422{
1423	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
1424	int i;
1425
1426	if (!sa_dev)
1427		return;
1428
1429	ib_unregister_event_handler(&sa_dev->event_handler);
1430
1431	flush_scheduled_work();
1432
1433	for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) {
1434		if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND) {
1435			ib_unregister_mad_agent(sa_dev->port[i].notice_agent);
1436			ib_unregister_mad_agent(sa_dev->port[i].agent);
1437			if (sa_dev->port[i].sm_ah)
1438				kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah);
1439		}
1440
1441	}
1442
1443	kfree(sa_dev);
1444}
1445
1446static int __init ib_sa_init(void)
1447{
1448	int ret;
1449
1450	spin_lock_init(&idr_lock);
1451	spin_lock_init(&tid_lock);
1452
1453	get_random_bytes(&tid, sizeof tid);
1454
1455	ret = ib_register_client(&sa_client);
1456	if (ret) {
1457		printk(KERN_ERR "Couldn't register ib_sa client\n");
1458		goto err1;
1459	}
1460
1461	ret = mcast_init();
1462	if (ret) {
1463		printk(KERN_ERR "Couldn't initialize multicast handling\n");
1464		goto err2;
1465	}
1466
1467	ret = notice_init();
1468	if (ret) {
1469		printk(KERN_ERR "Couldn't initialize notice handling\n");
1470		goto err3;
1471	}
1472
1473	ret = sa_db_init();
1474	if (ret) {
1475		printk(KERN_ERR "Couldn't initialize local SA\n");
1476		goto err4;
1477	}
1478
1479	return 0;
1480err4:
1481	notice_cleanup();
1482err3:
1483	mcast_cleanup();
1484err2:
1485	ib_unregister_client(&sa_client);
1486err1:
1487	return ret;
1488}
1489
1490static void __exit ib_sa_cleanup(void)
1491{
1492	sa_db_cleanup();
1493	mcast_cleanup();
1494	notice_cleanup();
1495	ib_unregister_client(&sa_client);
1496	idr_destroy(&query_idr);
1497}
1498
1499module_init_order(ib_sa_init, SI_ORDER_SECOND);
1500module_exit(ib_sa_cleanup);
1501