1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  *  Copyright (c) 2002-2005 Neterion, Inc.
24  *  All right Reserved.
25  *
26  *  FileName :    xgehal-driver.h
27  *
28  *  Description:  HAL driver object functionality
29  *
30  *  Created:      14 May 2004
31  */
32 
33 #ifndef XGE_HAL_DRIVER_H
34 #define XGE_HAL_DRIVER_H
35 
36 #include "xge-os-pal.h"
37 #include "xge-list.h"
38 #include "xge-queue.h"
39 #include "xgehal-types.h"
40 #include "xgehal-config.h"
41 #include "xgehal-event.h"
42 
43 /* maximum number of events consumed in a syncle poll() cycle */
44 #define XGE_HAL_DRIVER_QUEUE_CONSUME_MAX	5
45 
46 
47 /**
48  * function xge_uld_sched_timer_cb_f - Per-device periodic timer
49  * callback.
50  * @devh: HAL device handle.
51  * @userdata: Per-device user data (a.k.a. context) specified via
52  * xge_hal_device_initialize().
53  *
54  * Periodic or one-shot timer callback. If specified (that is, not NULL)
55  * HAL invokes this callback periodically. The call is performed in the
56  * interrupt context, or more exactly, in the context of HAL's ISR
57  * xge_hal_device_continue_irq().
58  *
59  * See also: xge_hal_device_initialize{}
60  */
61 typedef void (*xge_uld_sched_timer_cb_f)(xge_hal_device_h devh, void *userdata);
62 
63 /**
64  * function xge_uld_link_up_f - Link-Up callback provided by upper-layer
65  * driver.
66  * @userdata: Opaque context set by the ULD via
67  * xge_hal_device_private_set()
68  * (typically - at HAL device iinitialization time).
69  *
70  * Link-up notification callback provided by the ULD.
71  * This is one of the per-driver callbacks, see xge_hal_uld_cbs_t{}.
72  *
73  * See also: xge_hal_uld_cbs_t{}, xge_uld_link_down_f{},
74  * xge_hal_driver_initialize(), xge_hal_device_private_set().
75  */
76 typedef void (*xge_uld_link_up_f) (void *userdata);
77 
78 /**
79  * function xge_uld_link_down_f - Link-Down callback provided by
80  * upper-layer driver.
81  * @userdata: Opaque context set by the ULD via
82  * xge_hal_device_private_set()
83  * (typically - at HAL device iinitialization time).
84  *
85  * Link-Down notification callback provided by the upper-layer driver.
86  * This is one of the per-driver callbacks, see xge_hal_uld_cbs_t{}.
87  *
88  * See also: xge_hal_uld_cbs_t{}, xge_uld_link_up_f{},
89  * xge_hal_driver_initialize(), xge_hal_device_private_set().
90  */
91 typedef void (*xge_uld_link_down_f) (void *userdata);
92 
93 /**
94  * function xge_uld_crit_err_f - Critical Error notification callback.
95  * @userdata: Opaque context set by the ULD via
96  * xge_hal_device_private_set()
97  * (typically - at HAL device iinitialization time).
98  * @type: Enumerated hw error, e.g.: double ECC.
99  * @serr_data: Xframe status.
100  * @ext_data: Extended data. The contents depends on the @type.
101  *
102  * Link-Down notification callback provided by the upper-layer driver.
103  * This is one of the per-driver callbacks, see xge_hal_uld_cbs_t{}.
104  *
105  * See also: xge_hal_uld_cbs_t{}, xge_hal_event_e{},
106  * xge_hal_device_private_set(), xge_hal_driver_initialize().
107  */
108 typedef void (*xge_uld_crit_err_f) (void *userdata, xge_hal_event_e type,
109 		u64 ext_data);
110 
111 /**
112  * function xge_uld_event_queued_f - Event-enqueued notification
113  * callback.
114  * @devh: HAL device handle.
115  * @event_type: HAL- or ULD-defined event type. Note that HAL
116  *              events are enumerated by xge_hal_event_e{}.
117  *
118  * "Event-was-enqueued" notification callback provided by the upper-layer
119  * driver. The callback is invoked (if defined, i.e., not NULL in the
120  * xge_hal_uld_cbs_t{} structure) each time immediately after an event
121  * is enqueued.
122  *
123  * See also: xge_hal_uld_cbs_t{}, xge_hal_device_private_set(),
124  * xge_hal_driver_initialize().
125  */
126 typedef void (*xge_uld_event_queued_f) (xge_hal_device_h devh, int event_type);
127 
128 /**
129  * function xge_uld_event_f - ULD event callback.
130  * @item: ULD-defined event, item of the xge_queue_t.
131  *
132  * ULD event callback.
133  * Upper-layer driver can use HAL queue to serialize certain slow-path
134  * events. HAL periodically polls the queue as part of the
135  * xge_hal_device_poll() processing. When/if HAL discovers in the queue
136  * an unkown event type it simply invokes the event callback
137  * (which must be non-NULL and supplied by the ULD in this case).
138  *
139  * See also: xge_hal_uld_cbs_t{}, xge_hal_device_poll(), xge_queue_t{},
140  * xge_hal_driver_initialize(), xge_queue_item_t{}.
141  */
142 typedef void (*xge_uld_event_f) (xge_queue_item_t *item);
143 
144 /**
145  * function xge_uld_before_device_poll_f - ULD "before-poll" callback.
146  * @devh: HAL device handle.
147  *
148  * HAL invokes the callback from inside its xge_hal_device_poll()
149  * implementation %prior to accessing the @devh device. This allows ULD to
150  * perform per-device locking and/or context mapping, if required..
151  * The interface is currently used by AIX driver only.
152  * To avoid using/implementing the callback set the corresponding field
153  * in the xge_hal_uld_cbs_t{} structure to NULL.
154  *
155  * Returns: 0 on success, non-zero on failure.
156  *
157  * See also: xge_hal_driver_initialize(), xge_hal_uld_cbs_t{},
158  * xge_hal_device_poll().
159  */
160 typedef int (*xge_uld_before_device_poll_f) (xge_hal_device_h devh);
161 
162 /**
163  * function xge_uld_after_device_poll_f - ULD "after-poll" callback.
164  * @devh: HAL device handle.
165  *
166  * Unless NULL is specified,
167  * HAL invokes the callback from inside its xge_hal_device_poll()
168  * implementation immediately %after it has completed polling the @devh
169  * device. This allows ULD to undo the affects of
170  * xge_uld_before_device_poll_f{}.
171  * The interface is currently used by AIX driver only.
172  *
173  * See also: xge_hal_driver_initialize(), xge_hal_uld_cbs_t{},
174  * xge_hal_device_poll().
175  */
176 typedef void (*xge_uld_after_device_poll_f) (xge_hal_device_h devh);
177 
178 /**
179  * struct xge_hal_uld_cbs_t - Upper-layer driver "slow-path" callbacks.
180  * @link_up: See xge_uld_link_up_f{}.
181  * @link_down: See xge_uld_link_down_f{}.
182  * @crit_err: See xge_uld_crit_err_f{}.
183  * @event: See xge_uld_event_f{}.
184  * @event_queued: See xge_uld_event_queued_f{}.
185  * @before_device_poll: See xge_uld_before_device_poll_f{}.
186  * @after_device_poll: See xge_uld_after_device_poll_f{}.
187  * @sched_timer: See xge_uld_sched_timer_cb_f{}.
188  *
189  * Upper layer driver slow-path (per-driver) callbacks.
190  * Implemented by ULD and provided to HAL via
191  * xge_hal_driver_initialize().
192  * Note that these callbacks are not mandatory: HAL will not invoke
193  * a callback if NULL is specified.
194  *
195  * Note that in addition to those, there are curently 2 per-channel callbacks
196  * (completion and abort) specified at channel open time
197  * via xge_hal_channel_open().
198  *
199  * See also: xge_hal_driver_initialize().
200  */
201 typedef struct xge_hal_uld_cbs_t {
202 	xge_uld_link_up_f		link_up;
203 	xge_uld_link_down_f		link_down;
204 	xge_uld_crit_err_f		crit_err;
205 	xge_uld_event_f			event;
206 	xge_uld_event_queued_f		event_queued;
207 	xge_uld_before_device_poll_f    before_device_poll;
208 	xge_uld_after_device_poll_f	after_device_poll;
209 	xge_uld_sched_timer_cb_f	sched_timer;
210 } xge_hal_uld_cbs_t;
211 
212 /**
213  * struct xge_hal_driver_t - Represents HAL object.
214  * @config: HAL configuration.
215  * @devices: List of all PCI-enumerated Xframe devices in the system.
216  * A single xge_hal_driver_t instance contains zero or more
217  * Xframe devices.
218  * @devices_lock: Lock to protect %devices when inserting/removing.
219  * @is_initialized: True if HAL is initialized; false otherwise.
220  * @uld_callbacks: Upper-layer driver callbacks. See xge_hal_uld_cbs_t{}.
221  * @debug_module_mask: 32bit mask that defines which components of the
222  * driver are to be traced. The trace-able components are:
223  *	XGE_COMPONENT_HAL_CONFIG		0x1
224  *	XGE_COMPONENT_HAL_FIFO			0x2
225  *	XGE_COMPONENT_HAL_RING			0x4
226  *	XGE_COMPONENT_HAL_CHANNEL		0x8
227  *	XGE_COMPONENT_HAL_DEVICE		0x10
228  *	XGE_COMPONENT_HAL_MM			0x20
229  *	XGE_COMPONENT_HAL_QUEUE			0x40
230  *	XGE_COMPONENT_HAL_STATS			0x100
231  *	XGE_COMPONENT_OSDEP			0x1000
232  *	XGE_COMPONENT_LL			0x2000
233  *	XGE_COMPONENT_TOE			0x4000
234  *	XGE_COMPONENT_RDMA			0x8000
235  *	XGE_COMPONENT_ALL			0xffffffff
236  * The @debug_module_mask allows to switch off and on tracing at runtime.
237  * In addition, the traces for the same trace-able components can be
238  * compiled out, based on the same mask provided via Makefile.
239  * @debug_level: See xge_debug_level_e{}.
240  *
241  * HAL (driver) object. There is a single instance of this structure per HAL.
242  */
243 typedef struct xge_hal_driver_t {
244 	xge_hal_driver_config_t		config;
245 	int                             is_initialized;
246 	xge_hal_uld_cbs_t               uld_callbacks;
247 	u32				debug_module_mask;
248 	int				debug_level;
249 } xge_hal_driver_t;
250 
251 extern xge_hal_driver_t *g_xge_hal_driver;
252 
253 static inline int
254 xge_hal_driver_is_initialized(void) {
255         return g_xge_hal_driver->is_initialized;
256 }
257 
258 static inline int
259 xge_hal_driver_debug_module_mask(void)
260 {
261 	return g_xge_hal_driver->debug_module_mask;
262 }
263 
264 static inline void
265 xge_hal_driver_debug_module_mask_set(u32 new_mask)
266 {
267 #if (defined(XGE_DEBUG_TRACE_MASK) && XGE_DEBUG_TRACE_MASK > 0) || \
268     (defined(XGE_DEBUG_ERR_MASK) && XGE_DEBUG_ERR_MASK > 0)
269 	g_xge_hal_driver->debug_module_mask = new_mask;
270 	g_module_mask = &g_xge_hal_driver->debug_module_mask;
271 #endif
272 }
273 
274 static inline int
275 xge_hal_driver_debug_level(void) { return g_xge_hal_driver->debug_level; }
276 
277 static inline void
278 xge_hal_driver_debug_level_set(int new_level)
279 {
280 #if (defined(XGE_DEBUG_TRACE_MASK) && XGE_DEBUG_TRACE_MASK > 0) || \
281     (defined(XGE_DEBUG_ERR_MASK) && XGE_DEBUG_ERR_MASK > 0)
282 	g_xge_hal_driver->debug_level = new_level;
283 	g_level = &g_xge_hal_driver->debug_level;
284 #endif
285 }
286 
287 static inline void
288 xge_hal_driver_module_mask_set(int new_mask) {
289 	g_xge_hal_driver->debug_module_mask = new_mask; }
290 
291 xge_hal_status_e xge_hal_driver_initialize(xge_hal_driver_config_t *config,
292 		xge_hal_uld_cbs_t *uld_callbacks);
293 
294 void xge_hal_driver_terminate(void);
295 
296 #ifdef XGE_TRACE_INTO_CIRCULAR_ARR
297 static inline void
298 xge_hal_driver_tracebuf_timestamp(int on)
299 {
300 	g_xge_os_tracebuf->timestamp = on;
301 }
302 
303 void xge_hal_driver_tracebuf_dump(void);
304 #else
305 #define xge_hal_driver_tracebuf_timestamp(a)
306 #define xge_hal_driver_tracebuf_dump()
307 #endif
308 
309 
310 #endif /* XGE_HAL_DRIVER_H */
311