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