]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/ofed/drivers/infiniband/core/sa_query.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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/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
49 MODULE_AUTHOR("Roland Dreier");
50 MODULE_DESCRIPTION("InfiniBand subnet administration query support");
51 MODULE_LICENSE("Dual BSD/GPL");
52
53 struct ib_sa_sm_ah {
54         struct ib_ah        *ah;
55         struct kref          ref;
56         u16                  pkey_index;
57         u8                   src_path_mask;
58 };
59
60 struct 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
70 struct 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
76 struct 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
86 struct 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
92 struct 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
98 struct 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
104 struct 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
110 static void ib_sa_add_one(struct ib_device *device);
111 static void ib_sa_remove_one(struct ib_device *device);
112
113 static struct ib_client sa_client = {
114         .name   = "sa",
115         .add    = ib_sa_add_one,
116         .remove = ib_sa_remove_one
117 };
118
119 static spinlock_t idr_lock;
120 static DEFINE_IDR(query_idr);
121
122 static spinlock_t tid_lock;
123 static 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
130 static 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
230 static 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
314 static 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
362 static 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
422 static 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
461 int 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
489 int 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
501 int 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
513 static 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
521 static 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
568 static 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
596 void ib_sa_register_client(struct ib_sa_client *client)
597 {
598         atomic_set(&client->users, 1);
599         init_completion(&client->comp);
600 }
601 EXPORT_SYMBOL(ib_sa_register_client);
602
603 void ib_sa_unregister_client(struct ib_sa_client *client)
604 {
605         ib_sa_client_put(client);
606         wait_for_completion(&client->comp);
607 }
608 EXPORT_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  */
619 void 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 }
636 EXPORT_SYMBOL(ib_sa_cancel_query);
637
638 static 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
657 int 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 }
690 EXPORT_SYMBOL(ib_init_ah_from_path);
691
692 static 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
719 static 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
725 static 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
741 static 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
746 retry:
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
776 void 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 }
780 EXPORT_SYMBOL(ib_sa_unpack_path);
781
782 static 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
799 static 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
804 int 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
861 err2:
862         *sa_query = NULL;
863         ib_sa_client_put(query->sa_query.client);
864         free_mad(&query->sa_query);
865
866 err1:
867         kfree(query);
868         return ret;
869 }
870
871 static 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
888 static 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  */
920 int 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
983 err2:
984         *sa_query = NULL;
985         ib_sa_client_put(query->sa_query.client);
986         free_mad(&query->sa_query);
987
988 err1:
989         kfree(query);
990         return ret;
991 }
992 EXPORT_SYMBOL(ib_sa_service_rec_query);
993
994 static 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
1011 static 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
1016 int 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
1075 err2:
1076         *sa_query = NULL;
1077         ib_sa_client_put(query->sa_query.client);
1078         free_mad(&query->sa_query);
1079
1080 err1:
1081         kfree(query);
1082         return ret;
1083 }
1084
1085 static 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
1102 static 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
1107 int 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  */
1153 int 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
1208 err2:
1209         *sa_query = NULL;
1210         ib_sa_client_put(query->sa_query.client);
1211         free_mad(&query->sa_query);
1212 err1:
1213         kfree(query);
1214         return ret;
1215 }
1216
1217 static 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;
1251 err:
1252         kref_put(mad_buf->context[0], free_sm_ah);
1253         ib_free_send_mad(mad_buf);
1254 }
1255
1256 static 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
1287 static 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
1309 static 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
1316 static 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
1332 static 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
1407 err:
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
1421 static 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
1446 static 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;
1480 err4:
1481         notice_cleanup();
1482 err3:
1483         mcast_cleanup();
1484 err2:
1485         ib_unregister_client(&sa_client);
1486 err1:
1487         return ret;
1488 }
1489
1490 static 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
1499 module_init_order(ib_sa_init, SI_ORDER_SECOND);
1500 module_exit(ib_sa_cleanup);