1 /* 2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. 3 * All rights reserved 4 * www.brocade.com 5 * 6 * Linux driver for Brocade Fibre Channel Host Bus Adapter. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License (GPL) Version 2 as 10 * published by the Free Software Foundation 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 */ 17 18 /* 19 * bfa_cs.h BFA common services 20 */ 21 22 #ifndef __BFA_CS_H__ 23 #define __BFA_CS_H__ 24 25 #include "bfa_os_inc.h" 26 27 /* 28 * BFA TRC 29 */ 30 31 #ifndef BFA_TRC_MAX 32 #define BFA_TRC_MAX (4 * 1024) 33 #endif 34 35 #ifndef BFA_TRC_TS 36 #define BFA_TRC_TS(_trcm) ((_trcm)->ticks++) 37 #endif 38 39 struct bfa_trc_s { 40 #ifdef __BIGENDIAN 41 u16 fileno; 42 u16 line; 43 #else 44 u16 line; 45 u16 fileno; 46 #endif 47 u32 timestamp; 48 union { 49 struct { 50 u32 rsvd; 51 u32 u32; 52 } u32; 53 u64 u64; 54 } data; 55 }; 56 57 struct bfa_trc_mod_s { 58 u32 head; 59 u32 tail; 60 u32 ntrc; 61 u32 stopped; 62 u32 ticks; 63 u32 rsvd[3]; 64 struct bfa_trc_s trc[BFA_TRC_MAX]; 65 }; 66 67 enum { 68 BFA_TRC_HAL = 1, /* BFA modules */ 69 BFA_TRC_FCS = 2, /* BFA FCS modules */ 70 BFA_TRC_LDRV = 3, /* Linux driver modules */ 71 BFA_TRC_CNA = 4, /* Common modules */ 72 }; 73 #define BFA_TRC_MOD_SH 10 74 #define BFA_TRC_MOD(__mod) ((BFA_TRC_ ## __mod) << BFA_TRC_MOD_SH) 75 76 /* 77 * Define a new tracing file (module). Module should match one defined above. 78 */ 79 #define BFA_TRC_FILE(__mod, __submod) \ 80 static int __trc_fileno = ((BFA_TRC_ ## __mod ## _ ## __submod) | \ 81 BFA_TRC_MOD(__mod)) 82 83 84 #define bfa_trc32(_trcp, _data) \ 85 __bfa_trc((_trcp)->trcmod, __trc_fileno, __LINE__, (u32)_data) 86 #define bfa_trc(_trcp, _data) \ 87 __bfa_trc((_trcp)->trcmod, __trc_fileno, __LINE__, (u64)_data) 88 89 static inline void 90 bfa_trc_init(struct bfa_trc_mod_s *trcm) 91 { 92 trcm->head = trcm->tail = trcm->stopped = 0; 93 trcm->ntrc = BFA_TRC_MAX; 94 } 95 96 static inline void 97 bfa_trc_stop(struct bfa_trc_mod_s *trcm) 98 { 99 trcm->stopped = 1; 100 } 101 102 #ifdef FWTRC 103 extern void dc_flush(void *data); 104 #else 105 #define dc_flush(data) 106 #endif 107 108 109 static inline void 110 __bfa_trc(struct bfa_trc_mod_s *trcm, int fileno, int line, u64 data) 111 { 112 int tail = trcm->tail; 113 struct bfa_trc_s *trc = &trcm->trc[tail]; 114 115 if (trcm->stopped) 116 return; 117 118 trc->fileno = (u16) fileno; 119 trc->line = (u16) line; 120 trc->data.u64 = data; 121 trc->timestamp = BFA_TRC_TS(trcm); 122 dc_flush(trc); 123 124 trcm->tail = (trcm->tail + 1) & (BFA_TRC_MAX - 1); 125 if (trcm->tail == trcm->head) 126 trcm->head = (trcm->head + 1) & (BFA_TRC_MAX - 1); 127 dc_flush(trcm); 128 } 129 130 131 static inline void 132 __bfa_trc32(struct bfa_trc_mod_s *trcm, int fileno, int line, u32 data) 133 { 134 int tail = trcm->tail; 135 struct bfa_trc_s *trc = &trcm->trc[tail]; 136 137 if (trcm->stopped) 138 return; 139 140 trc->fileno = (u16) fileno; 141 trc->line = (u16) line; 142 trc->data.u32.u32 = data; 143 trc->timestamp = BFA_TRC_TS(trcm); 144 dc_flush(trc); 145 146 trcm->tail = (trcm->tail + 1) & (BFA_TRC_MAX - 1); 147 if (trcm->tail == trcm->head) 148 trcm->head = (trcm->head + 1) & (BFA_TRC_MAX - 1); 149 dc_flush(trcm); 150 } 151 152 #ifndef BFA_PERF_BUILD 153 #define bfa_trc_fp(_trcp, _data) bfa_trc(_trcp, _data) 154 #else 155 #define bfa_trc_fp(_trcp, _data) 156 #endif 157 158 /* 159 * @ BFA LOG interfaces 160 */ 161 #define bfa_assert(__cond) do { \ 162 if (!(__cond)) { \ 163 printk(KERN_ERR "assert(%s) failed at %s:%d\\n", \ 164 #__cond, __FILE__, __LINE__); \ 165 } \ 166 } while (0) 167 168 #define bfa_sm_fault(__mod, __event) do { \ 169 bfa_trc(__mod, (((u32)0xDEAD << 16) | __event)); \ 170 printk(KERN_ERR "Assertion failure: %s:%d: %d", \ 171 __FILE__, __LINE__, (__event)); \ 172 } while (0) 173 174 #ifndef BFA_PERF_BUILD 175 #define bfa_assert_fp(__cond) bfa_assert(__cond) 176 #else 177 #define bfa_assert_fp(__cond) 178 #endif 179 180 /* BFA queue definitions */ 181 #define bfa_q_first(_q) ((void *)(((struct list_head *) (_q))->next)) 182 #define bfa_q_next(_qe) (((struct list_head *) (_qe))->next) 183 #define bfa_q_prev(_qe) (((struct list_head *) (_qe))->prev) 184 185 /* 186 * bfa_q_qe_init - to initialize a queue element 187 */ 188 #define bfa_q_qe_init(_qe) { \ 189 bfa_q_next(_qe) = (struct list_head *) NULL; \ 190 bfa_q_prev(_qe) = (struct list_head *) NULL; \ 191 } 192 193 /* 194 * bfa_q_deq - dequeue an element from head of the queue 195 */ 196 #define bfa_q_deq(_q, _qe) { \ 197 if (!list_empty(_q)) { \ 198 (*((struct list_head **) (_qe))) = bfa_q_next(_q); \ 199 bfa_q_prev(bfa_q_next(*((struct list_head **) _qe))) = \ 200 (struct list_head *) (_q); \ 201 bfa_q_next(_q) = bfa_q_next(*((struct list_head **) _qe));\ 202 BFA_Q_DBG_INIT(*((struct list_head **) _qe)); \ 203 } else { \ 204 *((struct list_head **) (_qe)) = (struct list_head *) NULL;\ 205 } \ 206 } 207 208 /* 209 * bfa_q_deq_tail - dequeue an element from tail of the queue 210 */ 211 #define bfa_q_deq_tail(_q, _qe) { \ 212 if (!list_empty(_q)) { \ 213 *((struct list_head **) (_qe)) = bfa_q_prev(_q); \ 214 bfa_q_next(bfa_q_prev(*((struct list_head **) _qe))) = \ 215 (struct list_head *) (_q); \ 216 bfa_q_prev(_q) = bfa_q_prev(*(struct list_head **) _qe);\ 217 BFA_Q_DBG_INIT(*((struct list_head **) _qe)); \ 218 } else { \ 219 *((struct list_head **) (_qe)) = (struct list_head *) NULL;\ 220 } \ 221 } 222 223 static inline int 224 bfa_q_is_on_q_func(struct list_head *q, struct list_head *qe) 225 { 226 struct list_head *tqe; 227 228 tqe = bfa_q_next(q); 229 while (tqe != q) { 230 if (tqe == qe) 231 return 1; 232 tqe = bfa_q_next(tqe); 233 if (tqe == NULL) 234 break; 235 } 236 return 0; 237 } 238 239 /* 240 * #ifdef BFA_DEBUG (Using bfa_assert to check for debug_build is not 241 * consistent across modules) 242 */ 243 #ifndef BFA_PERF_BUILD 244 #define BFA_Q_DBG_INIT(_qe) bfa_q_qe_init(_qe) 245 #else 246 #define BFA_Q_DBG_INIT(_qe) 247 #endif 248 249 #define bfa_q_is_on_q(_q, _qe) \ 250 bfa_q_is_on_q_func(_q, (struct list_head *)(_qe)) 251 252 /* 253 * @ BFA state machine interfaces 254 */ 255 256 typedef void (*bfa_sm_t)(void *sm, int event); 257 258 /* 259 * oc - object class eg. bfa_ioc 260 * st - state, eg. reset 261 * otype - object type, eg. struct bfa_ioc_s 262 * etype - object type, eg. enum ioc_event 263 */ 264 #define bfa_sm_state_decl(oc, st, otype, etype) \ 265 static void oc ## _sm_ ## st(otype * fsm, etype event) 266 267 #define bfa_sm_set_state(_sm, _state) ((_sm)->sm = (bfa_sm_t)(_state)) 268 #define bfa_sm_send_event(_sm, _event) ((_sm)->sm((_sm), (_event))) 269 #define bfa_sm_get_state(_sm) ((_sm)->sm) 270 #define bfa_sm_cmp_state(_sm, _state) ((_sm)->sm == (bfa_sm_t)(_state)) 271 272 /* 273 * For converting from state machine function to state encoding. 274 */ 275 struct bfa_sm_table_s { 276 bfa_sm_t sm; /* state machine function */ 277 int state; /* state machine encoding */ 278 char *name; /* state name for display */ 279 }; 280 #define BFA_SM(_sm) ((bfa_sm_t)(_sm)) 281 282 /* 283 * State machine with entry actions. 284 */ 285 typedef void (*bfa_fsm_t)(void *fsm, int event); 286 287 /* 288 * oc - object class eg. bfa_ioc 289 * st - state, eg. reset 290 * otype - object type, eg. struct bfa_ioc_s 291 * etype - object type, eg. enum ioc_event 292 */ 293 #define bfa_fsm_state_decl(oc, st, otype, etype) \ 294 static void oc ## _sm_ ## st(otype * fsm, etype event); \ 295 static void oc ## _sm_ ## st ## _entry(otype * fsm) 296 297 #define bfa_fsm_set_state(_fsm, _state) do { \ 298 (_fsm)->fsm = (bfa_fsm_t)(_state); \ 299 _state ## _entry(_fsm); \ 300 } while (0) 301 302 #define bfa_fsm_send_event(_fsm, _event) ((_fsm)->fsm((_fsm), (_event))) 303 #define bfa_fsm_get_state(_fsm) ((_fsm)->fsm) 304 #define bfa_fsm_cmp_state(_fsm, _state) \ 305 ((_fsm)->fsm == (bfa_fsm_t)(_state)) 306 307 static inline int 308 bfa_sm_to_state(struct bfa_sm_table_s *smt, bfa_sm_t sm) 309 { 310 int i = 0; 311 312 while (smt[i].sm && smt[i].sm != sm) 313 i++; 314 return smt[i].state; 315 } 316 317 /* 318 * @ Generic wait counter. 319 */ 320 321 typedef void (*bfa_wc_resume_t) (void *cbarg); 322 323 struct bfa_wc_s { 324 bfa_wc_resume_t wc_resume; 325 void *wc_cbarg; 326 int wc_count; 327 }; 328 329 static inline void 330 bfa_wc_up(struct bfa_wc_s *wc) 331 { 332 wc->wc_count++; 333 } 334 335 static inline void 336 bfa_wc_down(struct bfa_wc_s *wc) 337 { 338 wc->wc_count--; 339 if (wc->wc_count == 0) 340 wc->wc_resume(wc->wc_cbarg); 341 } 342 343 /* 344 * Initialize a waiting counter. 345 */ 346 static inline void 347 bfa_wc_init(struct bfa_wc_s *wc, bfa_wc_resume_t wc_resume, void *wc_cbarg) 348 { 349 wc->wc_resume = wc_resume; 350 wc->wc_cbarg = wc_cbarg; 351 wc->wc_count = 0; 352 bfa_wc_up(wc); 353 } 354 355 /* 356 * Wait for counter to reach zero 357 */ 358 static inline void 359 bfa_wc_wait(struct bfa_wc_s *wc) 360 { 361 bfa_wc_down(wc); 362 } 363 364 #endif /* __BFA_CS_H__ */ 365