1219820Sjeff/*
2219820Sjeff * Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
3219820Sjeff * Copyright (c) 2004 Infinicon Corporation.  All rights reserved.
4219820Sjeff * Copyright (c) 2004 Intel Corporation.  All rights reserved.
5219820Sjeff * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
6219820Sjeff * Copyright (c) 2004-2006 Voltaire Corporation.  All rights reserved.
7219820Sjeff *
8219820Sjeff * This software is available to you under a choice of one of two
9219820Sjeff * licenses.  You may choose to be licensed under the terms of the GNU
10219820Sjeff * General Public License (GPL) Version 2, available from the file
11219820Sjeff * COPYING in the main directory of this source tree, or the
12219820Sjeff * OpenIB.org BSD license below:
13219820Sjeff *
14219820Sjeff *     Redistribution and use in source and binary forms, with or
15219820Sjeff *     without modification, are permitted provided that the following
16219820Sjeff *     conditions are met:
17219820Sjeff *
18219820Sjeff *      - Redistributions of source code must retain the above
19219820Sjeff *        copyright notice, this list of conditions and the following
20219820Sjeff *        disclaimer.
21219820Sjeff *
22219820Sjeff *      - Redistributions in binary form must reproduce the above
23219820Sjeff *        copyright notice, this list of conditions and the following
24219820Sjeff *        disclaimer in the documentation and/or other materials
25219820Sjeff *        provided with the distribution.
26219820Sjeff *
27219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34219820Sjeff * SOFTWARE.
35219820Sjeff */
36219820Sjeff
37219820Sjeff#if !defined(IB_MAD_H)
38219820Sjeff#define IB_MAD_H
39219820Sjeff
40219820Sjeff#include <linux/list.h>
41219820Sjeff
42219820Sjeff#include <rdma/ib_verbs.h>
43219820Sjeff
44219820Sjeff/* Management base version */
45219820Sjeff#define IB_MGMT_BASE_VERSION			1
46219820Sjeff
47219820Sjeff/* Management classes */
48219820Sjeff#define IB_MGMT_CLASS_SUBN_LID_ROUTED		0x01
49219820Sjeff#define IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE	0x81
50219820Sjeff#define IB_MGMT_CLASS_SUBN_ADM			0x03
51219820Sjeff#define IB_MGMT_CLASS_PERF_MGMT			0x04
52219820Sjeff#define IB_MGMT_CLASS_BM			0x05
53219820Sjeff#define IB_MGMT_CLASS_DEVICE_MGMT		0x06
54219820Sjeff#define IB_MGMT_CLASS_CM			0x07
55219820Sjeff#define IB_MGMT_CLASS_SNMP			0x08
56219820Sjeff#define IB_MGMT_CLASS_DEVICE_ADM		0x10
57219820Sjeff#define IB_MGMT_CLASS_BOOT_MGMT			0x11
58219820Sjeff#define IB_MGMT_CLASS_BIS			0x12
59219820Sjeff#define IB_MGMT_CLASS_CONG_MGMT			0x21
60219820Sjeff#define IB_MGMT_CLASS_VENDOR_RANGE2_START	0x30
61219820Sjeff#define IB_MGMT_CLASS_VENDOR_RANGE2_END		0x4F
62219820Sjeff
63219820Sjeff#define	IB_OPENIB_OUI				(0x001405)
64219820Sjeff
65219820Sjeff/* Management methods */
66219820Sjeff#define IB_MGMT_METHOD_GET			0x01
67219820Sjeff#define IB_MGMT_METHOD_SET			0x02
68219820Sjeff#define IB_MGMT_METHOD_GET_RESP			0x81
69219820Sjeff#define IB_MGMT_METHOD_SEND			0x03
70219820Sjeff#define IB_MGMT_METHOD_TRAP			0x05
71219820Sjeff#define IB_MGMT_METHOD_REPORT			0x06
72219820Sjeff#define IB_MGMT_METHOD_REPORT_RESP		0x86
73219820Sjeff#define IB_MGMT_METHOD_TRAP_REPRESS		0x07
74219820Sjeff
75219820Sjeff#define IB_MGMT_METHOD_RESP			0x80
76219820Sjeff#define IB_BM_ATTR_MOD_RESP			cpu_to_be32(1)
77219820Sjeff
78219820Sjeff#define IB_MGMT_MAX_METHODS			128
79219820Sjeff
80219820Sjeff/* RMPP information */
81219820Sjeff#define IB_MGMT_RMPP_VERSION			1
82219820Sjeff
83219820Sjeff#define IB_MGMT_RMPP_TYPE_DATA			1
84219820Sjeff#define IB_MGMT_RMPP_TYPE_ACK			2
85219820Sjeff#define IB_MGMT_RMPP_TYPE_STOP			3
86219820Sjeff#define IB_MGMT_RMPP_TYPE_ABORT			4
87219820Sjeff
88219820Sjeff#define IB_MGMT_RMPP_FLAG_ACTIVE		1
89219820Sjeff#define IB_MGMT_RMPP_FLAG_FIRST			(1<<1)
90219820Sjeff#define IB_MGMT_RMPP_FLAG_LAST			(1<<2)
91219820Sjeff
92219820Sjeff#define IB_MGMT_RMPP_NO_RESPTIME		0x1F
93219820Sjeff
94219820Sjeff#define	IB_MGMT_RMPP_STATUS_SUCCESS		0
95219820Sjeff#define	IB_MGMT_RMPP_STATUS_RESX		1
96219820Sjeff#define	IB_MGMT_RMPP_STATUS_ABORT_MIN		118
97219820Sjeff#define	IB_MGMT_RMPP_STATUS_T2L			118
98219820Sjeff#define	IB_MGMT_RMPP_STATUS_BAD_LEN		119
99219820Sjeff#define	IB_MGMT_RMPP_STATUS_BAD_SEG		120
100219820Sjeff#define	IB_MGMT_RMPP_STATUS_BADT		121
101219820Sjeff#define	IB_MGMT_RMPP_STATUS_W2S			122
102219820Sjeff#define	IB_MGMT_RMPP_STATUS_S2B			123
103219820Sjeff#define	IB_MGMT_RMPP_STATUS_BAD_STATUS		124
104219820Sjeff#define	IB_MGMT_RMPP_STATUS_UNV			125
105219820Sjeff#define	IB_MGMT_RMPP_STATUS_TMR			126
106219820Sjeff#define	IB_MGMT_RMPP_STATUS_UNSPEC		127
107219820Sjeff#define	IB_MGMT_RMPP_STATUS_ABORT_MAX		127
108219820Sjeff
109219820Sjeff#define IB_QP0		0
110219820Sjeff#define IB_QP1		cpu_to_be32(1)
111219820Sjeff#define IB_QP1_QKEY	0x80010000
112219820Sjeff#define IB_QP_SET_QKEY	0x80000000
113219820Sjeff
114219820Sjeff#define IB_DEFAULT_PKEY_PARTIAL 0x7FFF
115219820Sjeff#define IB_DEFAULT_PKEY_FULL	0xFFFF
116219820Sjeff
117219820Sjeffenum {
118219820Sjeff	IB_MGMT_MAD_HDR = 24,
119219820Sjeff	IB_MGMT_MAD_DATA = 232,
120219820Sjeff	IB_MGMT_RMPP_HDR = 36,
121219820Sjeff	IB_MGMT_RMPP_DATA = 220,
122219820Sjeff	IB_MGMT_VENDOR_HDR = 40,
123219820Sjeff	IB_MGMT_VENDOR_DATA = 216,
124219820Sjeff	IB_MGMT_SA_HDR = 56,
125219820Sjeff	IB_MGMT_SA_DATA = 200,
126219820Sjeff	IB_MGMT_DEVICE_HDR = 64,
127219820Sjeff	IB_MGMT_DEVICE_DATA = 192,
128219820Sjeff};
129219820Sjeff
130219820Sjeffstruct ib_mad_hdr {
131219820Sjeff	u8	base_version;
132219820Sjeff	u8	mgmt_class;
133219820Sjeff	u8	class_version;
134219820Sjeff	u8	method;
135219820Sjeff	__be16	status;
136219820Sjeff	__be16	class_specific;
137219820Sjeff	__be64	tid;
138219820Sjeff	__be16	attr_id;
139219820Sjeff	__be16	resv;
140219820Sjeff	__be32	attr_mod;
141219820Sjeff};
142219820Sjeff
143219820Sjeffstruct ib_rmpp_hdr {
144219820Sjeff	u8	rmpp_version;
145219820Sjeff	u8	rmpp_type;
146219820Sjeff	u8	rmpp_rtime_flags;
147219820Sjeff	u8	rmpp_status;
148219820Sjeff	__be32	seg_num;
149219820Sjeff	__be32	paylen_newwin;
150219820Sjeff};
151219820Sjeff
152219820Sjefftypedef u64 __bitwise ib_sa_comp_mask;
153219820Sjeff
154255932Salfred#define IB_SA_COMP_MASK(n) ((__force ib_sa_comp_mask) cpu_to_be64(1ull << (n)))
155219820Sjeff
156219820Sjeff/*
157219820Sjeff * ib_sa_hdr and ib_sa_mad structures must be packed because they have
158219820Sjeff * 64-bit fields that are only 32-bit aligned. 64-bit architectures will
159219820Sjeff * lay them out wrong otherwise.  (And unfortunately they are sent on
160219820Sjeff * the wire so we can't change the layout)
161219820Sjeff */
162219820Sjeffstruct ib_sa_hdr {
163219820Sjeff	__be64			sm_key;
164219820Sjeff	__be16			attr_offset;
165219820Sjeff	__be16			reserved;
166219820Sjeff	ib_sa_comp_mask		comp_mask;
167219820Sjeff} __attribute__ ((packed));
168219820Sjeff
169219820Sjeffstruct ib_mad {
170219820Sjeff	struct ib_mad_hdr	mad_hdr;
171219820Sjeff	u8			data[IB_MGMT_MAD_DATA];
172219820Sjeff};
173219820Sjeff
174219820Sjeffstruct ib_rmpp_mad {
175219820Sjeff	struct ib_mad_hdr	mad_hdr;
176219820Sjeff	struct ib_rmpp_hdr	rmpp_hdr;
177219820Sjeff	u8			data[IB_MGMT_RMPP_DATA];
178219820Sjeff};
179219820Sjeff
180219820Sjeffstruct ib_sa_mad {
181219820Sjeff	struct ib_mad_hdr	mad_hdr;
182219820Sjeff	struct ib_rmpp_hdr	rmpp_hdr;
183219820Sjeff	struct ib_sa_hdr	sa_hdr;
184219820Sjeff	u8			data[IB_MGMT_SA_DATA];
185219820Sjeff} __attribute__ ((packed));
186219820Sjeff
187219820Sjeffstruct ib_vendor_mad {
188219820Sjeff	struct ib_mad_hdr	mad_hdr;
189219820Sjeff	struct ib_rmpp_hdr	rmpp_hdr;
190219820Sjeff	u8			reserved;
191219820Sjeff	u8			oui[3];
192219820Sjeff	u8			data[IB_MGMT_VENDOR_DATA];
193219820Sjeff};
194219820Sjeff
195219820Sjeffstruct ib_class_port_info {
196219820Sjeff	u8			base_version;
197219820Sjeff	u8			class_version;
198219820Sjeff	__be16			capability_mask;
199219820Sjeff	u8			reserved[3];
200219820Sjeff	u8			resp_time_value;
201219820Sjeff	u8			redirect_gid[16];
202219820Sjeff	__be32			redirect_tcslfl;
203219820Sjeff	__be16			redirect_lid;
204219820Sjeff	__be16			redirect_pkey;
205219820Sjeff	__be32			redirect_qp;
206219820Sjeff	__be32			redirect_qkey;
207219820Sjeff	u8			trap_gid[16];
208219820Sjeff	__be32			trap_tcslfl;
209219820Sjeff	__be16			trap_lid;
210219820Sjeff	__be16			trap_pkey;
211219820Sjeff	__be32			trap_hlqp;
212219820Sjeff	__be32			trap_qkey;
213219820Sjeff};
214219820Sjeff
215219820Sjeff/**
216219820Sjeff * ib_mad_send_buf - MAD data buffer and work request for sends.
217219820Sjeff * @next: A pointer used to chain together MADs for posting.
218219820Sjeff * @mad: References an allocated MAD data buffer for MADs that do not have
219219820Sjeff *   RMPP active.  For MADs using RMPP, references the common and management
220219820Sjeff *   class specific headers.
221219820Sjeff * @mad_agent: MAD agent that allocated the buffer.
222219820Sjeff * @ah: The address handle to use when sending the MAD.
223219820Sjeff * @context: User-controlled context fields.
224219820Sjeff * @hdr_len: Indicates the size of the data header of the MAD.  This length
225219820Sjeff *   includes the common MAD, RMPP, and class specific headers.
226219820Sjeff * @data_len: Indicates the total size of user-transferred data.
227219820Sjeff * @seg_count: The number of RMPP segments allocated for this send.
228219820Sjeff * @seg_size: Size of each RMPP segment.
229219820Sjeff * @timeout_ms: Time to wait for a response.
230219820Sjeff * @retries: Number of times to retry a request for a response.  For MADs
231219820Sjeff *   using RMPP, this applies per window.  On completion, returns the number
232219820Sjeff *   of retries needed to complete the transfer.
233219820Sjeff *
234219820Sjeff * Users are responsible for initializing the MAD buffer itself, with the
235219820Sjeff * exception of any RMPP header.  Additional segment buffer space allocated
236219820Sjeff * beyond data_len is padding.
237219820Sjeff */
238219820Sjeffstruct ib_mad_send_buf {
239219820Sjeff	struct ib_mad_send_buf	*next;
240219820Sjeff	void			*mad;
241219820Sjeff	struct ib_mad_agent	*mad_agent;
242219820Sjeff	struct ib_ah		*ah;
243219820Sjeff	void			*context[2];
244219820Sjeff	int			hdr_len;
245219820Sjeff	int			data_len;
246219820Sjeff	int			seg_count;
247219820Sjeff	int			seg_size;
248219820Sjeff	int			timeout_ms;
249219820Sjeff	int			retries;
250219820Sjeff};
251219820Sjeff
252219820Sjeff/**
253219820Sjeff * ib_response_mad - Returns if the specified MAD has been generated in
254219820Sjeff *   response to a sent request or trap.
255219820Sjeff */
256219820Sjeffint ib_response_mad(struct ib_mad *mad);
257219820Sjeff
258219820Sjeff/**
259219820Sjeff * ib_get_rmpp_resptime - Returns the RMPP response time.
260219820Sjeff * @rmpp_hdr: An RMPP header.
261219820Sjeff */
262219820Sjeffstatic inline u8 ib_get_rmpp_resptime(struct ib_rmpp_hdr *rmpp_hdr)
263219820Sjeff{
264219820Sjeff	return rmpp_hdr->rmpp_rtime_flags >> 3;
265219820Sjeff}
266219820Sjeff
267219820Sjeff/**
268219820Sjeff * ib_get_rmpp_flags - Returns the RMPP flags.
269219820Sjeff * @rmpp_hdr: An RMPP header.
270219820Sjeff */
271219820Sjeffstatic inline u8 ib_get_rmpp_flags(struct ib_rmpp_hdr *rmpp_hdr)
272219820Sjeff{
273219820Sjeff	return rmpp_hdr->rmpp_rtime_flags & 0x7;
274219820Sjeff}
275219820Sjeff
276219820Sjeff/**
277219820Sjeff * ib_set_rmpp_resptime - Sets the response time in an RMPP header.
278219820Sjeff * @rmpp_hdr: An RMPP header.
279219820Sjeff * @rtime: The response time to set.
280219820Sjeff */
281219820Sjeffstatic inline void ib_set_rmpp_resptime(struct ib_rmpp_hdr *rmpp_hdr, u8 rtime)
282219820Sjeff{
283219820Sjeff	rmpp_hdr->rmpp_rtime_flags = ib_get_rmpp_flags(rmpp_hdr) | (rtime << 3);
284219820Sjeff}
285219820Sjeff
286219820Sjeff/**
287219820Sjeff * ib_set_rmpp_flags - Sets the flags in an RMPP header.
288219820Sjeff * @rmpp_hdr: An RMPP header.
289219820Sjeff * @flags: The flags to set.
290219820Sjeff */
291219820Sjeffstatic inline void ib_set_rmpp_flags(struct ib_rmpp_hdr *rmpp_hdr, u8 flags)
292219820Sjeff{
293219820Sjeff	rmpp_hdr->rmpp_rtime_flags = (rmpp_hdr->rmpp_rtime_flags & 0xF8) |
294219820Sjeff				     (flags & 0x7);
295219820Sjeff}
296219820Sjeff
297219820Sjeffstruct ib_mad_agent;
298219820Sjeffstruct ib_mad_send_wc;
299219820Sjeffstruct ib_mad_recv_wc;
300219820Sjeff
301219820Sjeff/**
302219820Sjeff * ib_mad_send_handler - callback handler for a sent MAD.
303219820Sjeff * @mad_agent: MAD agent that sent the MAD.
304219820Sjeff * @mad_send_wc: Send work completion information on the sent MAD.
305219820Sjeff */
306219820Sjefftypedef void (*ib_mad_send_handler)(struct ib_mad_agent *mad_agent,
307219820Sjeff				    struct ib_mad_send_wc *mad_send_wc);
308219820Sjeff
309219820Sjeff/**
310219820Sjeff * ib_mad_snoop_handler - Callback handler for snooping sent MADs.
311219820Sjeff * @mad_agent: MAD agent that snooped the MAD.
312219820Sjeff * @send_wr: Work request information on the sent MAD.
313219820Sjeff * @mad_send_wc: Work completion information on the sent MAD.  Valid
314219820Sjeff *   only for snooping that occurs on a send completion.
315219820Sjeff *
316219820Sjeff * Clients snooping MADs should not modify data referenced by the @send_wr
317219820Sjeff * or @mad_send_wc.
318219820Sjeff */
319219820Sjefftypedef void (*ib_mad_snoop_handler)(struct ib_mad_agent *mad_agent,
320219820Sjeff				     struct ib_mad_send_buf *send_buf,
321219820Sjeff				     struct ib_mad_send_wc *mad_send_wc);
322219820Sjeff
323219820Sjeff/**
324219820Sjeff * ib_mad_recv_handler - callback handler for a received MAD.
325219820Sjeff * @mad_agent: MAD agent requesting the received MAD.
326219820Sjeff * @mad_recv_wc: Received work completion information on the received MAD.
327219820Sjeff *
328219820Sjeff * MADs received in response to a send request operation will be handed to
329219820Sjeff * the user before the send operation completes.  All data buffers given
330219820Sjeff * to registered agents through this routine are owned by the receiving
331219820Sjeff * client, except for snooping agents.  Clients snooping MADs should not
332219820Sjeff * modify the data referenced by @mad_recv_wc.
333219820Sjeff */
334219820Sjefftypedef void (*ib_mad_recv_handler)(struct ib_mad_agent *mad_agent,
335219820Sjeff				    struct ib_mad_recv_wc *mad_recv_wc);
336219820Sjeff
337219820Sjeff/**
338219820Sjeff * ib_mad_agent - Used to track MAD registration with the access layer.
339219820Sjeff * @device: Reference to device registration is on.
340219820Sjeff * @qp: Reference to QP used for sending and receiving MADs.
341219820Sjeff * @mr: Memory region for system memory usable for DMA.
342219820Sjeff * @recv_handler: Callback handler for a received MAD.
343219820Sjeff * @send_handler: Callback handler for a sent MAD.
344219820Sjeff * @snoop_handler: Callback handler for snooped sent MADs.
345219820Sjeff * @context: User-specified context associated with this registration.
346219820Sjeff * @hi_tid: Access layer assigned transaction ID for this client.
347219820Sjeff *   Unsolicited MADs sent by this client will have the upper 32-bits
348219820Sjeff *   of their TID set to this value.
349219820Sjeff * @port_num: Port number on which QP is registered
350219820Sjeff * @rmpp_version: If set, indicates the RMPP version used by this agent.
351219820Sjeff */
352219820Sjeffstruct ib_mad_agent {
353219820Sjeff	struct ib_device	*device;
354219820Sjeff	struct ib_qp		*qp;
355219820Sjeff	struct ib_mr		*mr;
356219820Sjeff	ib_mad_recv_handler	recv_handler;
357219820Sjeff	ib_mad_send_handler	send_handler;
358219820Sjeff	ib_mad_snoop_handler	snoop_handler;
359219820Sjeff	void			*context;
360219820Sjeff	u32			hi_tid;
361219820Sjeff	u8			port_num;
362219820Sjeff	u8			rmpp_version;
363219820Sjeff};
364219820Sjeff
365219820Sjeff/**
366219820Sjeff * ib_mad_send_wc - MAD send completion information.
367219820Sjeff * @send_buf: Send MAD data buffer associated with the send MAD request.
368219820Sjeff * @status: Completion status.
369219820Sjeff * @vendor_err: Optional vendor error information returned with a failed
370219820Sjeff *   request.
371219820Sjeff */
372219820Sjeffstruct ib_mad_send_wc {
373219820Sjeff	struct ib_mad_send_buf	*send_buf;
374219820Sjeff	enum ib_wc_status	status;
375219820Sjeff	u32			vendor_err;
376219820Sjeff};
377219820Sjeff
378219820Sjeff/**
379219820Sjeff * ib_mad_recv_buf - received MAD buffer information.
380219820Sjeff * @list: Reference to next data buffer for a received RMPP MAD.
381219820Sjeff * @grh: References a data buffer containing the global route header.
382219820Sjeff *   The data refereced by this buffer is only valid if the GRH is
383219820Sjeff *   valid.
384219820Sjeff * @mad: References the start of the received MAD.
385219820Sjeff */
386219820Sjeffstruct ib_mad_recv_buf {
387219820Sjeff	struct list_head	list;
388219820Sjeff	struct ib_grh		*grh;
389219820Sjeff	struct ib_mad		*mad;
390219820Sjeff};
391219820Sjeff
392219820Sjeff/**
393219820Sjeff * ib_mad_recv_wc - received MAD information.
394219820Sjeff * @wc: Completion information for the received data.
395219820Sjeff * @recv_buf: Specifies the location of the received data buffer(s).
396219820Sjeff * @rmpp_list: Specifies a list of RMPP reassembled received MAD buffers.
397219820Sjeff * @mad_len: The length of the received MAD, without duplicated headers.
398219820Sjeff *
399219820Sjeff * For received response, the wr_id contains a pointer to the ib_mad_send_buf
400219820Sjeff *   for the corresponding send request.
401219820Sjeff */
402219820Sjeffstruct ib_mad_recv_wc {
403219820Sjeff	struct ib_wc		*wc;
404219820Sjeff	struct ib_mad_recv_buf	recv_buf;
405219820Sjeff	struct list_head	rmpp_list;
406219820Sjeff	int			mad_len;
407219820Sjeff};
408219820Sjeff
409219820Sjeff/**
410219820Sjeff * ib_mad_reg_req - MAD registration request
411219820Sjeff * @mgmt_class: Indicates which management class of MADs should be receive
412219820Sjeff *   by the caller.  This field is only required if the user wishes to
413219820Sjeff *   receive unsolicited MADs, otherwise it should be 0.
414219820Sjeff * @mgmt_class_version: Indicates which version of MADs for the given
415219820Sjeff *   management class to receive.
416219820Sjeff * @oui: Indicates IEEE OUI when mgmt_class is a vendor class
417219820Sjeff *   in the range from 0x30 to 0x4f. Otherwise not used.
418219820Sjeff * @method_mask: The caller will receive unsolicited MADs for any method
419219820Sjeff *   where @method_mask = 1.
420219820Sjeff */
421219820Sjeffstruct ib_mad_reg_req {
422219820Sjeff	u8	mgmt_class;
423219820Sjeff	u8	mgmt_class_version;
424219820Sjeff	u8	oui[3];
425219820Sjeff	DECLARE_BITMAP(method_mask, IB_MGMT_MAX_METHODS);
426219820Sjeff};
427219820Sjeff
428219820Sjeff/**
429219820Sjeff * ib_register_mad_agent - Register to send/receive MADs.
430219820Sjeff * @device: The device to register with.
431219820Sjeff * @port_num: The port on the specified device to use.
432219820Sjeff * @qp_type: Specifies which QP to access.  Must be either
433219820Sjeff *   IB_QPT_SMI or IB_QPT_GSI.
434219820Sjeff * @mad_reg_req: Specifies which unsolicited MADs should be received
435219820Sjeff *   by the caller.  This parameter may be NULL if the caller only
436219820Sjeff *   wishes to receive solicited responses.
437219820Sjeff * @rmpp_version: If set, indicates that the client will send
438219820Sjeff *   and receive MADs that contain the RMPP header for the given version.
439219820Sjeff *   If set to 0, indicates that RMPP is not used by this client.
440219820Sjeff * @send_handler: The completion callback routine invoked after a send
441219820Sjeff *   request has completed.
442219820Sjeff * @recv_handler: The completion callback routine invoked for a received
443219820Sjeff *   MAD.
444219820Sjeff * @context: User specified context associated with the registration.
445219820Sjeff */
446219820Sjeffstruct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
447219820Sjeff					   u8 port_num,
448219820Sjeff					   enum ib_qp_type qp_type,
449219820Sjeff					   struct ib_mad_reg_req *mad_reg_req,
450219820Sjeff					   u8 rmpp_version,
451219820Sjeff					   ib_mad_send_handler send_handler,
452219820Sjeff					   ib_mad_recv_handler recv_handler,
453219820Sjeff					   void *context);
454219820Sjeff
455219820Sjeffenum ib_mad_snoop_flags {
456219820Sjeff	/*IB_MAD_SNOOP_POSTED_SENDS	   = 1,*/
457219820Sjeff	/*IB_MAD_SNOOP_RMPP_SENDS	   = (1<<1),*/
458219820Sjeff	IB_MAD_SNOOP_SEND_COMPLETIONS	   = (1<<2),
459219820Sjeff	/*IB_MAD_SNOOP_RMPP_SEND_COMPLETIONS = (1<<3),*/
460219820Sjeff	IB_MAD_SNOOP_RECVS		   = (1<<4)
461219820Sjeff	/*IB_MAD_SNOOP_RMPP_RECVS	   = (1<<5),*/
462219820Sjeff	/*IB_MAD_SNOOP_REDIRECTED_QPS	   = (1<<6)*/
463219820Sjeff};
464219820Sjeff
465219820Sjeff/**
466219820Sjeff * ib_register_mad_snoop - Register to snoop sent and received MADs.
467219820Sjeff * @device: The device to register with.
468219820Sjeff * @port_num: The port on the specified device to use.
469219820Sjeff * @qp_type: Specifies which QP traffic to snoop.  Must be either
470219820Sjeff *   IB_QPT_SMI or IB_QPT_GSI.
471219820Sjeff * @mad_snoop_flags: Specifies information where snooping occurs.
472219820Sjeff * @send_handler: The callback routine invoked for a snooped send.
473219820Sjeff * @recv_handler: The callback routine invoked for a snooped receive.
474219820Sjeff * @context: User specified context associated with the registration.
475219820Sjeff */
476219820Sjeffstruct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device,
477219820Sjeff					   u8 port_num,
478219820Sjeff					   enum ib_qp_type qp_type,
479219820Sjeff					   int mad_snoop_flags,
480219820Sjeff					   ib_mad_snoop_handler snoop_handler,
481219820Sjeff					   ib_mad_recv_handler recv_handler,
482219820Sjeff					   void *context);
483219820Sjeff
484219820Sjeff/**
485219820Sjeff * ib_unregister_mad_agent - Unregisters a client from using MAD services.
486219820Sjeff * @mad_agent: Corresponding MAD registration request to deregister.
487219820Sjeff *
488219820Sjeff * After invoking this routine, MAD services are no longer usable by the
489219820Sjeff * client on the associated QP.
490219820Sjeff */
491219820Sjeffint ib_unregister_mad_agent(struct ib_mad_agent *mad_agent);
492219820Sjeff
493219820Sjeff/**
494219820Sjeff * ib_post_send_mad - Posts MAD(s) to the send queue of the QP associated
495219820Sjeff *   with the registered client.
496219820Sjeff * @send_buf: Specifies the information needed to send the MAD(s).
497219820Sjeff * @bad_send_buf: Specifies the MAD on which an error was encountered.  This
498219820Sjeff *   parameter is optional if only a single MAD is posted.
499219820Sjeff *
500219820Sjeff * Sent MADs are not guaranteed to complete in the order that they were posted.
501219820Sjeff *
502219820Sjeff * If the MAD requires RMPP, the data buffer should contain a single copy
503219820Sjeff * of the common MAD, RMPP, and class specific headers, followed by the class
504219820Sjeff * defined data.  If the class defined data would not divide evenly into
505219820Sjeff * RMPP segments, then space must be allocated at the end of the referenced
506219820Sjeff * buffer for any required padding.  To indicate the amount of class defined
507219820Sjeff * data being transferred, the paylen_newwin field in the RMPP header should
508219820Sjeff * be set to the size of the class specific header plus the amount of class
509219820Sjeff * defined data being transferred.  The paylen_newwin field should be
510219820Sjeff * specified in network-byte order.
511219820Sjeff */
512219820Sjeffint ib_post_send_mad(struct ib_mad_send_buf *send_buf,
513219820Sjeff		     struct ib_mad_send_buf **bad_send_buf);
514219820Sjeff
515219820Sjeff
516219820Sjeff/**
517219820Sjeff * ib_free_recv_mad - Returns data buffers used to receive a MAD.
518219820Sjeff * @mad_recv_wc: Work completion information for a received MAD.
519219820Sjeff *
520219820Sjeff * Clients receiving MADs through their ib_mad_recv_handler must call this
521219820Sjeff * routine to return the work completion buffers to the access layer.
522219820Sjeff */
523219820Sjeffvoid ib_free_recv_mad(struct ib_mad_recv_wc *mad_recv_wc);
524219820Sjeff
525219820Sjeff/**
526219820Sjeff * ib_cancel_mad - Cancels an outstanding send MAD operation.
527219820Sjeff * @mad_agent: Specifies the registration associated with sent MAD.
528219820Sjeff * @send_buf: Indicates the MAD to cancel.
529219820Sjeff *
530219820Sjeff * MADs will be returned to the user through the corresponding
531219820Sjeff * ib_mad_send_handler.
532219820Sjeff */
533219820Sjeffvoid ib_cancel_mad(struct ib_mad_agent *mad_agent,
534219820Sjeff		   struct ib_mad_send_buf *send_buf);
535219820Sjeff
536219820Sjeff/**
537219820Sjeff * ib_modify_mad - Modifies an outstanding send MAD operation.
538219820Sjeff * @mad_agent: Specifies the registration associated with sent MAD.
539219820Sjeff * @send_buf: Indicates the MAD to modify.
540219820Sjeff * @timeout_ms: New timeout value for sent MAD.
541219820Sjeff *
542219820Sjeff * This call will reset the timeout value for a sent MAD to the specified
543219820Sjeff * value.
544219820Sjeff */
545219820Sjeffint ib_modify_mad(struct ib_mad_agent *mad_agent,
546219820Sjeff		  struct ib_mad_send_buf *send_buf, u32 timeout_ms);
547219820Sjeff
548219820Sjeff/**
549219820Sjeff * ib_redirect_mad_qp - Registers a QP for MAD services.
550219820Sjeff * @qp: Reference to a QP that requires MAD services.
551219820Sjeff * @rmpp_version: If set, indicates that the client will send
552219820Sjeff *   and receive MADs that contain the RMPP header for the given version.
553219820Sjeff *   If set to 0, indicates that RMPP is not used by this client.
554219820Sjeff * @send_handler: The completion callback routine invoked after a send
555219820Sjeff *   request has completed.
556219820Sjeff * @recv_handler: The completion callback routine invoked for a received
557219820Sjeff *   MAD.
558219820Sjeff * @context: User specified context associated with the registration.
559219820Sjeff *
560219820Sjeff * Use of this call allows clients to use MAD services, such as RMPP,
561219820Sjeff * on user-owned QPs.  After calling this routine, users may send
562219820Sjeff * MADs on the specified QP by calling ib_mad_post_send.
563219820Sjeff */
564219820Sjeffstruct ib_mad_agent *ib_redirect_mad_qp(struct ib_qp *qp,
565219820Sjeff					u8 rmpp_version,
566219820Sjeff					ib_mad_send_handler send_handler,
567219820Sjeff					ib_mad_recv_handler recv_handler,
568219820Sjeff					void *context);
569219820Sjeff
570219820Sjeff/**
571219820Sjeff * ib_process_mad_wc - Processes a work completion associated with a
572219820Sjeff *   MAD sent or received on a redirected QP.
573219820Sjeff * @mad_agent: Specifies the registered MAD service using the redirected QP.
574219820Sjeff * @wc: References a work completion associated with a sent or received
575219820Sjeff *   MAD segment.
576219820Sjeff *
577219820Sjeff * This routine is used to complete or continue processing on a MAD request.
578219820Sjeff * If the work completion is associated with a send operation, calling
579219820Sjeff * this routine is required to continue an RMPP transfer or to wait for a
580219820Sjeff * corresponding response, if it is a request.  If the work completion is
581219820Sjeff * associated with a receive operation, calling this routine is required to
582219820Sjeff * process an inbound or outbound RMPP transfer, or to match a response MAD
583219820Sjeff * with its corresponding request.
584219820Sjeff */
585219820Sjeffint ib_process_mad_wc(struct ib_mad_agent *mad_agent,
586219820Sjeff		      struct ib_wc *wc);
587219820Sjeff
588219820Sjeff/**
589219820Sjeff * ib_create_send_mad - Allocate and initialize a data buffer and work request
590219820Sjeff *   for sending a MAD.
591219820Sjeff * @mad_agent: Specifies the registered MAD service to associate with the MAD.
592219820Sjeff * @remote_qpn: Specifies the QPN of the receiving node.
593219820Sjeff * @pkey_index: Specifies which PKey the MAD will be sent using.  This field
594219820Sjeff *   is valid only if the remote_qpn is QP 1.
595219820Sjeff * @rmpp_active: Indicates if the send will enable RMPP.
596219820Sjeff * @hdr_len: Indicates the size of the data header of the MAD.  This length
597219820Sjeff *   should include the common MAD header, RMPP header, plus any class
598219820Sjeff *   specific header.
599219820Sjeff * @data_len: Indicates the size of any user-transferred data.  The call will
600219820Sjeff *   automatically adjust the allocated buffer size to account for any
601219820Sjeff *   additional padding that may be necessary.
602219820Sjeff * @gfp_mask: GFP mask used for the memory allocation.
603219820Sjeff *
604219820Sjeff * This routine allocates a MAD for sending.  The returned MAD send buffer
605219820Sjeff * will reference a data buffer usable for sending a MAD, along
606219820Sjeff * with an initialized work request structure.  Users may modify the returned
607219820Sjeff * MAD data buffer before posting the send.
608219820Sjeff *
609219820Sjeff * The returned MAD header, class specific headers, and any padding will be
610219820Sjeff * cleared.  Users are responsible for initializing the common MAD header,
611219820Sjeff * any class specific header, and MAD data area.
612219820Sjeff * If @rmpp_active is set, the RMPP header will be initialized for sending.
613219820Sjeff */
614219820Sjeffstruct ib_mad_send_buf *ib_create_send_mad(struct ib_mad_agent *mad_agent,
615219820Sjeff					   u32 remote_qpn, u16 pkey_index,
616219820Sjeff					   int rmpp_active,
617219820Sjeff					   int hdr_len, int data_len,
618219820Sjeff					   gfp_t gfp_mask);
619219820Sjeff
620219820Sjeff/**
621219820Sjeff * ib_is_mad_class_rmpp - returns whether given management class
622219820Sjeff * supports RMPP.
623219820Sjeff * @mgmt_class: management class
624219820Sjeff *
625219820Sjeff * This routine returns whether the management class supports RMPP.
626219820Sjeff */
627219820Sjeffint ib_is_mad_class_rmpp(u8 mgmt_class);
628219820Sjeff
629219820Sjeff/**
630219820Sjeff * ib_get_mad_data_offset - returns the data offset for a given
631219820Sjeff * management class.
632219820Sjeff * @mgmt_class: management class
633219820Sjeff *
634219820Sjeff * This routine returns the data offset in the MAD for the management
635219820Sjeff * class requested.
636219820Sjeff */
637219820Sjeffint ib_get_mad_data_offset(u8 mgmt_class);
638219820Sjeff
639219820Sjeff/**
640219820Sjeff * ib_get_rmpp_segment - returns the data buffer for a given RMPP segment.
641219820Sjeff * @send_buf: Previously allocated send data buffer.
642219820Sjeff * @seg_num: number of segment to return
643219820Sjeff *
644219820Sjeff * This routine returns a pointer to the data buffer of an RMPP MAD.
645219820Sjeff * Users must provide synchronization to @send_buf around this call.
646219820Sjeff */
647219820Sjeffvoid *ib_get_rmpp_segment(struct ib_mad_send_buf *send_buf, int seg_num);
648219820Sjeff
649219820Sjeff/**
650219820Sjeff * ib_free_send_mad - Returns data buffers used to send a MAD.
651219820Sjeff * @send_buf: Previously allocated send data buffer.
652219820Sjeff */
653219820Sjeffvoid ib_free_send_mad(struct ib_mad_send_buf *send_buf);
654219820Sjeff
655219820Sjeff#endif /* IB_MAD_H */
656