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.
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:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
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.
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
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>
46 #include <rdma/ib_pack.h>
47 #include <rdma/ib_cache.h>
50 MODULE_AUTHOR("Roland Dreier");
51 MODULE_DESCRIPTION("InfiniBand subnet administration query support");
52 MODULE_LICENSE("Dual BSD/GPL");
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;
68 struct ib_device *device;
72 int start_port, end_port;
73 struct ib_event_handler event_handler;
74 struct ib_sa_port port[0];
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;
87 struct ib_sa_service_query {
88 void (*callback)(int, struct ib_sa_service_rec *, void *);
90 struct ib_sa_query sa_query;
93 struct ib_sa_path_query {
94 void (*callback)(int, struct ib_sa_path_rec *, void *);
96 struct ib_sa_query sa_query;
99 struct ib_sa_mcmember_query {
100 void (*callback)(int, struct ib_sa_mcmember_rec *, void *);
102 struct ib_sa_query sa_query;
105 struct ib_sa_inform_query {
106 void (*callback)(int, struct ib_sa_inform *, void *);
108 struct ib_sa_query sa_query;
111 static void ib_sa_add_one(struct ib_device *device);
112 static void ib_sa_remove_one(struct ib_device *device);
114 static struct ib_client sa_client = {
116 .add = ib_sa_add_one,
117 .remove = ib_sa_remove_one
120 static spinlock_t idr_lock;
121 static DEFINE_IDR(query_idr);
123 static spinlock_t tid_lock;
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
131 static const struct ib_field path_rec_table[] = {
132 { PATH_REC_FIELD(service_id),
136 { PATH_REC_FIELD(dgid),
140 { PATH_REC_FIELD(sgid),
144 { PATH_REC_FIELD(dlid),
148 { PATH_REC_FIELD(slid),
152 { PATH_REC_FIELD(raw_traffic),
160 { PATH_REC_FIELD(flow_label),
164 { PATH_REC_FIELD(hop_limit),
168 { PATH_REC_FIELD(traffic_class),
172 { PATH_REC_FIELD(reversible),
176 { PATH_REC_FIELD(numb_path),
180 { PATH_REC_FIELD(pkey),
184 { PATH_REC_FIELD(qos_class),
188 { PATH_REC_FIELD(sl),
192 { PATH_REC_FIELD(mtu_selector),
196 { PATH_REC_FIELD(mtu),
200 { PATH_REC_FIELD(rate_selector),
204 { PATH_REC_FIELD(rate),
208 { PATH_REC_FIELD(packet_life_time_selector),
212 { PATH_REC_FIELD(packet_life_time),
216 { PATH_REC_FIELD(preference),
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
231 static const struct ib_field mcmember_rec_table[] = {
232 { MCMEMBER_REC_FIELD(mgid),
236 { MCMEMBER_REC_FIELD(port_gid),
240 { MCMEMBER_REC_FIELD(qkey),
244 { MCMEMBER_REC_FIELD(mlid),
248 { MCMEMBER_REC_FIELD(mtu_selector),
252 { MCMEMBER_REC_FIELD(mtu),
256 { MCMEMBER_REC_FIELD(traffic_class),
260 { MCMEMBER_REC_FIELD(pkey),
264 { MCMEMBER_REC_FIELD(rate_selector),
268 { MCMEMBER_REC_FIELD(rate),
272 { MCMEMBER_REC_FIELD(packet_life_time_selector),
276 { MCMEMBER_REC_FIELD(packet_life_time),
280 { MCMEMBER_REC_FIELD(sl),
284 { MCMEMBER_REC_FIELD(flow_label),
288 { MCMEMBER_REC_FIELD(hop_limit),
292 { MCMEMBER_REC_FIELD(scope),
296 { MCMEMBER_REC_FIELD(join_state),
300 { MCMEMBER_REC_FIELD(proxy_join),
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
315 static const struct ib_field service_rec_table[] = {
316 { SERVICE_REC_FIELD(id),
320 { SERVICE_REC_FIELD(gid),
324 { SERVICE_REC_FIELD(pkey),
328 { SERVICE_REC_FIELD(lease),
332 { SERVICE_REC_FIELD(key),
336 { SERVICE_REC_FIELD(name),
340 { SERVICE_REC_FIELD(data8),
344 { SERVICE_REC_FIELD(data16),
348 { SERVICE_REC_FIELD(data32),
352 { SERVICE_REC_FIELD(data64),
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
363 static const struct ib_field inform_table[] = {
368 { INFORM_FIELD(lid_range_begin),
372 { INFORM_FIELD(lid_range_end),
380 { INFORM_FIELD(is_generic),
384 { INFORM_FIELD(subscribe),
388 { INFORM_FIELD(type),
392 { INFORM_FIELD(trap.generic.trap_num),
396 { INFORM_FIELD(trap.generic.qpn),
404 { INFORM_FIELD(trap.generic.resp_time),
412 { INFORM_FIELD(trap.generic.producer_type),
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
423 static const struct ib_field notice_table[] = {
424 { NOTICE_FIELD(is_generic),
428 { NOTICE_FIELD(type),
432 { NOTICE_FIELD(trap.generic.producer_type),
436 { NOTICE_FIELD(trap.generic.trap_num),
440 { NOTICE_FIELD(issuer_lid),
444 { NOTICE_FIELD(notice_toggle),
448 { NOTICE_FIELD(notice_count),
452 { NOTICE_FIELD(data_details),
456 { NOTICE_FIELD(issuer_gid),
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)
469 if (!(comp_mask & selector_mask) || !(comp_mask & value_mask))
474 err = (src_value <= dst_value);
477 err = (src_value >= dst_value);
480 err = (src_value != dst_value);
490 int ib_sa_pack_attr(void *dst, void *src, int attr_id)
493 case IB_SA_ATTR_PATH_REC:
494 ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), src, dst);
502 int ib_sa_unpack_attr(void *dst, void *src, int attr_id)
505 case IB_SA_ATTR_PATH_REC:
506 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), src, dst);
514 static void free_sm_ah(struct kref *kref)
516 struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
518 ib_destroy_ah(sm_ah->ah);
522 static void update_sm_ah(struct work_struct *work)
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;
530 if (ib_query_port(port->agent->device, port->port_num, &port_attr)) {
531 printk(KERN_WARNING "Couldn't query port\n");
535 new_ah = kmalloc(sizeof *new_ah, GFP_KERNEL);
537 printk(KERN_WARNING "Couldn't allocate new SM AH\n");
541 kref_init(&new_ah->ref);
542 new_ah->src_path_mask = (1 << port_attr.lmc) - 1;
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");
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;
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");
561 spin_lock_irq(&port->ah_lock);
563 kref_put(&port->sm_ah->ref, free_sm_ah);
564 port->sm_ah = new_ah;
565 spin_unlock_irq(&port->ah_lock);
569 static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event)
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) {
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];
583 if (rdma_port_get_link_layer(handler->device, port->port_num) != IB_LINK_LAYER_INFINIBAND)
586 spin_lock_irqsave(&port->ah_lock, flags);
588 kref_put(&port->sm_ah->ref, free_sm_ah);
590 spin_unlock_irqrestore(&port->ah_lock, flags);
592 schedule_work(&sa_dev->port[event->element.port_num -
593 sa_dev->start_port].update_task);
597 void ib_sa_register_client(struct ib_sa_client *client)
599 atomic_set(&client->users, 1);
600 init_completion(&client->comp);
602 EXPORT_SYMBOL(ib_sa_register_client);
604 void ib_sa_unregister_client(struct ib_sa_client *client)
606 ib_sa_client_put(client);
607 wait_for_completion(&client->comp);
609 EXPORT_SYMBOL(ib_sa_unregister_client);
612 * ib_sa_cancel_query - try to cancel an SA query
613 * @id:ID of query to cancel
614 * @query:query pointer to cancel
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.
620 void ib_sa_cancel_query(int id, struct ib_sa_query *query)
623 struct ib_mad_agent *agent;
624 struct ib_mad_send_buf *mad_buf;
626 spin_lock_irqsave(&idr_lock, flags);
627 if (idr_find(&query_idr, id) != query) {
628 spin_unlock_irqrestore(&idr_lock, flags);
631 agent = query->port->agent;
632 mad_buf = query->mad_buf;
633 spin_unlock_irqrestore(&idr_lock, flags);
635 ib_cancel_mad(agent, mad_buf);
637 EXPORT_SYMBOL(ib_sa_cancel_query);
639 static u8 get_src_path_mask(struct ib_device *device, u8 port_num)
641 struct ib_sa_device *sa_dev;
642 struct ib_sa_port *port;
646 sa_dev = ib_get_client_data(device, &sa_client);
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);
655 return src_path_mask;
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)
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;
673 force_grh = rdma_port_get_link_layer(device, port_num) == IB_LINK_LAYER_ETHERNET;
675 if (rec->hop_limit > 1 || force_grh) {
676 ah_attr->ah_flags = IB_AH_GRH;
677 ah_attr->grh.dgid = rec->dgid;
679 ret = ib_find_cached_gid(device, &rec->sgid, &port_num,
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;
691 EXPORT_SYMBOL(ib_init_ah_from_path);
693 static int alloc_mad(struct ib_sa_query *query, gfp_t gfp_mask)
697 spin_lock_irqsave(&query->port->ah_lock, flags);
698 if (!query->port->sm_ah) {
699 spin_unlock_irqrestore(&query->port->ah_lock, flags);
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);
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,
710 if (IS_ERR(query->mad_buf)) {
711 kref_put(&query->sm_ah->ref, free_sm_ah);
715 query->mad_buf->ah = query->sm_ah->ah;
720 static void free_mad(struct ib_sa_query *query)
722 ib_free_send_mad(query->mad_buf);
723 kref_put(&query->sm_ah->ref, free_sm_ah);
726 static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent)
730 memset(mad, 0, sizeof *mad);
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;
736 spin_lock_irqsave(&tid_lock, flags);
738 cpu_to_be64(((u64) agent->hi_tid) << 32 | tid++);
739 spin_unlock_irqrestore(&tid_lock, flags);
742 static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
748 if (!idr_pre_get(&query_idr, gfp_mask))
750 spin_lock_irqsave(&idr_lock, flags);
751 ret = idr_get_new(&query_idr, query, &id);
752 spin_unlock_irqrestore(&idr_lock, flags);
758 query->mad_buf->timeout_ms = timeout_ms;
759 query->mad_buf->context[0] = query;
762 ret = ib_post_send_mad(query->mad_buf, NULL);
764 spin_lock_irqsave(&idr_lock, flags);
765 idr_remove(&query_idr, id);
766 spin_unlock_irqrestore(&idr_lock, flags);
770 * It's not safe to dereference query any more, because the
771 * send may already have completed and freed the query in
774 return ret ? ret : id;
777 void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec)
779 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), attribute, rec);
781 EXPORT_SYMBOL(ib_sa_unpack_path);
783 static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
785 struct ib_sa_mad *mad)
787 struct ib_sa_path_query *query =
788 container_of(sa_query, struct ib_sa_path_query, sa_query);
791 struct ib_sa_path_rec rec;
793 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table),
795 query->callback(status, &rec, query->context);
797 query->callback(status, NULL, query->context);
800 static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
802 kfree(container_of(sa_query, struct ib_sa_path_query, sa_query));
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,
814 struct ib_sa_query **sa_query)
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;
826 port = &sa_dev->port[port_num - sa_dev->start_port];
829 query = kmalloc(sizeof *query, gfp_mask);
833 query->sa_query.port = port;
834 ret = alloc_mad(&query->sa_query, gfp_mask);
838 ib_sa_client_get(client);
839 query->sa_query.client = client;
840 query->callback = callback;
841 query->context = context;
843 mad = query->sa_query.mad_buf->mad;
844 init_mad(mad, agent);
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;
852 ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), rec, mad->data);
854 *sa_query = &query->sa_query;
856 ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
864 ib_sa_client_put(query->sa_query.client);
865 free_mad(&query->sa_query);
872 static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query,
874 struct ib_sa_mad *mad)
876 struct ib_sa_service_query *query =
877 container_of(sa_query, struct ib_sa_service_query, sa_query);
880 struct ib_sa_service_rec rec;
882 ib_unpack(service_rec_table, ARRAY_SIZE(service_rec_table),
884 query->callback(status, &rec, query->context);
886 query->callback(status, NULL, query->context);
889 static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
891 kfree(container_of(sa_query, struct ib_sa_service_query, sa_query));
895 * ib_sa_service_rec_query - Start Service Record operation
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
906 * @context:opaque user context passed to callback
907 * @sa_query:request context, used to cancel request
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.
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
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,
930 struct ib_sa_query **sa_query)
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;
942 port = &sa_dev->port[port_num - sa_dev->start_port];
945 if (method != IB_MGMT_METHOD_GET &&
946 method != IB_MGMT_METHOD_SET &&
947 method != IB_SA_METHOD_DELETE)
950 query = kmalloc(sizeof *query, gfp_mask);
954 query->sa_query.port = port;
955 ret = alloc_mad(&query->sa_query, gfp_mask);
959 ib_sa_client_get(client);
960 query->sa_query.client = client;
961 query->callback = callback;
962 query->context = context;
964 mad = query->sa_query.mad_buf->mad;
965 init_mad(mad, agent);
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;
973 ib_pack(service_rec_table, ARRAY_SIZE(service_rec_table),
976 *sa_query = &query->sa_query;
978 ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
986 ib_sa_client_put(query->sa_query.client);
987 free_mad(&query->sa_query);
993 EXPORT_SYMBOL(ib_sa_service_rec_query);
995 static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query,
997 struct ib_sa_mad *mad)
999 struct ib_sa_mcmember_query *query =
1000 container_of(sa_query, struct ib_sa_mcmember_query, sa_query);
1003 struct ib_sa_mcmember_rec rec;
1005 ib_unpack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
1007 query->callback(status, &rec, query->context);
1009 query->callback(status, NULL, query->context);
1012 static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query)
1014 kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query));
1017 int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
1018 struct ib_device *device, u8 port_num,
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,
1027 struct ib_sa_query **sa_query)
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;
1039 port = &sa_dev->port[port_num - sa_dev->start_port];
1040 agent = port->agent;
1042 query = kmalloc(sizeof *query, gfp_mask);
1046 query->sa_query.port = port;
1047 ret = alloc_mad(&query->sa_query, gfp_mask);
1051 ib_sa_client_get(client);
1052 query->sa_query.client = client;
1053 query->callback = callback;
1054 query->context = context;
1056 mad = query->sa_query.mad_buf->mad;
1057 init_mad(mad, agent);
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;
1065 ib_pack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
1068 *sa_query = &query->sa_query;
1070 ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
1078 ib_sa_client_put(query->sa_query.client);
1079 free_mad(&query->sa_query);
1086 static void ib_sa_inform_callback(struct ib_sa_query *sa_query,
1088 struct ib_sa_mad *mad)
1090 struct ib_sa_inform_query *query =
1091 container_of(sa_query, struct ib_sa_inform_query, sa_query);
1094 struct ib_sa_inform rec;
1096 ib_unpack(inform_table, ARRAY_SIZE(inform_table),
1098 query->callback(status, &rec, query->context);
1100 query->callback(status, NULL, query->context);
1103 static void ib_sa_inform_release(struct ib_sa_query *sa_query)
1105 kfree(container_of(sa_query, struct ib_sa_inform_query, sa_query));
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,
1117 struct ib_sa_query **sa_query)
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
1124 printk("ERROR: function should be called only in SRIOV flow!!!");
1130 * ib_sa_informinfo_query - Start an InformInfo registration.
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
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.
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
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,
1162 struct ib_sa_query **sa_query)
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;
1174 port = &sa_dev->port[port_num - sa_dev->start_port];
1175 agent = port->agent;
1177 query = kmalloc(sizeof *query, gfp_mask);
1181 query->sa_query.port = port;
1182 ret = alloc_mad(&query->sa_query, gfp_mask);
1186 ib_sa_client_get(client);
1187 query->sa_query.client = client;
1188 query->callback = callback;
1189 query->context = context;
1191 mad = query->sa_query.mad_buf->mad;
1192 init_mad(mad, agent);
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);
1200 ib_pack(inform_table, ARRAY_SIZE(inform_table), rec, mad->data);
1202 *sa_query = &query->sa_query;
1203 ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
1211 ib_sa_client_put(query->sa_query.client);
1212 free_mad(&query->sa_query);
1218 static void ib_sa_notice_resp(struct ib_sa_port *port,
1219 struct ib_mad_recv_wc *mad_recv_wc)
1221 struct ib_mad_send_buf *mad_buf;
1222 struct ib_sa_mad *mad;
1224 unsigned long flags;
1226 mad_buf = ib_create_send_mad(port->notice_agent, 1, 0, 0,
1227 IB_MGMT_SA_HDR, IB_MGMT_SA_DATA,
1229 if (IS_ERR(mad_buf))
1233 memcpy(mad, mad_recv_wc->recv_buf.mad, sizeof *mad);
1234 mad->mad_hdr.method = IB_MGMT_METHOD_REPORT_RESP;
1236 spin_lock_irqsave(&port->ah_lock, flags);
1238 spin_unlock_irqrestore(&port->ah_lock, flags);
1239 ib_free_send_mad(mad_buf);
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);
1247 ret = ib_post_send_mad(mad_buf, NULL);
1253 kref_put(mad_buf->context[0], free_sm_ah);
1254 ib_free_send_mad(mad_buf);
1257 static void send_handler(struct ib_mad_agent *agent,
1258 struct ib_mad_send_wc *mad_send_wc)
1260 struct ib_sa_query *query = mad_send_wc->send_buf->context[0];
1261 unsigned long flags;
1263 if (query->callback)
1264 switch (mad_send_wc->status) {
1266 /* No callback -- already got recv */
1268 case IB_WC_RESP_TIMEOUT_ERR:
1269 query->callback(query, -ETIMEDOUT, NULL);
1271 case IB_WC_WR_FLUSH_ERR:
1272 query->callback(query, -EINTR, NULL);
1275 query->callback(query, -EIO, NULL);
1279 spin_lock_irqsave(&idr_lock, flags);
1280 idr_remove(&query_idr, query->id);
1281 spin_unlock_irqrestore(&idr_lock, flags);
1284 ib_sa_client_put(query->client);
1285 query->release(query);
1288 static void recv_handler(struct ib_mad_agent *mad_agent,
1289 struct ib_mad_recv_wc *mad_recv_wc)
1291 struct ib_sa_query *query;
1292 struct ib_mad_send_buf *mad_buf;
1294 mad_buf = (void *) (unsigned long) mad_recv_wc->wc->wr_id;
1295 query = mad_buf->context[0];
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 ?
1302 (struct ib_sa_mad *) mad_recv_wc->recv_buf.mad);
1304 query->callback(query, -EIO, NULL);
1307 ib_free_recv_mad(mad_recv_wc);
1310 static void notice_resp_handler(struct ib_mad_agent *agent,
1311 struct ib_mad_send_wc *mad_send_wc)
1313 kref_put(mad_send_wc->send_buf->context[0], free_sm_ah);
1314 ib_free_send_mad(mad_send_wc->send_buf);
1317 static void notice_handler(struct ib_mad_agent *mad_agent,
1318 struct ib_mad_recv_wc *mad_recv_wc)
1320 struct ib_sa_port *port;
1321 struct ib_sa_mad *mad;
1322 struct ib_sa_notice notice;
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, ¬ice);
1328 if (!notice_dispatch(port->device, port->port_num, ¬ice))
1329 ib_sa_notice_resp(port, mad_recv_wc);
1330 ib_free_recv_mad(mad_recv_wc);
1333 static void ib_sa_add_one(struct ib_device *device)
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
1342 if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
1345 if (device->node_type == RDMA_NODE_IB_SWITCH)
1349 e = device->phys_port_cnt;
1352 sa_dev = kzalloc(sizeof *sa_dev +
1353 (e - s + 1) * sizeof (struct ib_sa_port),
1358 sa_dev->start_port = s;
1359 sa_dev->end_port = e;
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)
1366 sa_dev->port[i].sm_ah = NULL;
1367 sa_dev->port[i].port_num = i + s;
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))
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 ®_req, 0, notice_resp_handler,
1381 notice_handler, &sa_dev->port[i]);
1383 if (IS_ERR(sa_dev->port[i].notice_agent))
1386 INIT_WORK(&sa_dev->port[i].update_task, update_sm_ah);
1389 ib_set_client_data(device, &sa_client, sa_dev);
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.
1398 INIT_IB_EVENT_HANDLER(&sa_dev->event_handler, device, ib_sa_event);
1399 if (ib_register_event_handler(&sa_dev->event_handler))
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);
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);
1422 static void ib_sa_remove_one(struct ib_device *device)
1424 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
1430 ib_unregister_event_handler(&sa_dev->event_handler);
1432 flush_scheduled_work();
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);
1447 static int __init ib_sa_init(void)
1451 spin_lock_init(&idr_lock);
1452 spin_lock_init(&tid_lock);
1454 get_random_bytes(&tid, sizeof tid);
1456 ret = ib_register_client(&sa_client);
1458 printk(KERN_ERR "Couldn't register ib_sa client\n");
1464 printk(KERN_ERR "Couldn't initialize multicast handling\n");
1468 ret = notice_init();
1470 printk(KERN_ERR "Couldn't initialize notice handling\n");
1476 printk(KERN_ERR "Couldn't initialize local SA\n");
1486 ib_unregister_client(&sa_client);
1491 static void __exit ib_sa_cleanup(void)
1496 ib_unregister_client(&sa_client);
1497 idr_destroy(&query_idr);
1500 module_init_order(ib_sa_init, SI_ORDER_SECOND);
1501 module_exit(ib_sa_cleanup);