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