316 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.4 * Copyright (c) 2014- QLogic Corporation.5 * All rights reserved6 * www.qlogic.com7 *8 * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.9 */10 11/*12 * bfa_cs.h BFA common services13 */14 15#ifndef __BFA_CS_H__16#define __BFA_CS_H__17 18#include "bfad_drv.h"19 20/*21 * BFA TRC22 */23 24#ifndef BFA_TRC_MAX25#define BFA_TRC_MAX (4 * 1024)26#endif27 28#define BFA_TRC_TS(_trcm) \29 ({ \30 struct timespec64 ts; \31 \32 ktime_get_ts64(&ts); \33 (ts.tv_sec*1000000+ts.tv_nsec / 1000); \34 })35 36#ifndef BFA_TRC_TS37#define BFA_TRC_TS(_trcm) ((_trcm)->ticks++)38#endif39 40struct bfa_trc_s {41#ifdef __BIG_ENDIAN42 u16 fileno;43 u16 line;44#else45 u16 line;46 u16 fileno;47#endif48 u32 timestamp;49 union {50 struct {51 u32 rsvd;52 u32 u32;53 } u32;54 u64 u64;55 } data;56};57 58struct bfa_trc_mod_s {59 u32 head;60 u32 tail;61 u32 ntrc;62 u32 stopped;63 u32 ticks;64 u32 rsvd[3];65 struct bfa_trc_s trc[BFA_TRC_MAX];66};67 68enum {69 BFA_TRC_HAL = 1, /* BFA modules */70 BFA_TRC_FCS = 2, /* BFA FCS modules */71 BFA_TRC_LDRV = 3, /* Linux driver modules */72 BFA_TRC_CNA = 4, /* Common modules */73};74#define BFA_TRC_MOD_SH 1075#define BFA_TRC_MOD(__mod) ((BFA_TRC_ ## __mod) << BFA_TRC_MOD_SH)76 77/*78 * Define a new tracing file (module). Module should match one defined above.79 */80#define BFA_TRC_FILE(__mod, __submod) \81 static int __trc_fileno = ((BFA_TRC_ ## __mod ## _ ## __submod) | \82 BFA_TRC_MOD(__mod))83 84 85#define bfa_trc32(_trcp, _data) \86 __bfa_trc((_trcp)->trcmod, __trc_fileno, __LINE__, (u32)_data)87#define bfa_trc(_trcp, _data) \88 __bfa_trc((_trcp)->trcmod, __trc_fileno, __LINE__, (u64)_data)89 90static inline void91bfa_trc_init(struct bfa_trc_mod_s *trcm)92{93 trcm->head = trcm->tail = trcm->stopped = 0;94 trcm->ntrc = BFA_TRC_MAX;95}96 97static inline void98bfa_trc_stop(struct bfa_trc_mod_s *trcm)99{100 trcm->stopped = 1;101}102 103void104__bfa_trc(struct bfa_trc_mod_s *trcm, int fileno, int line, u64 data);105 106void107__bfa_trc32(struct bfa_trc_mod_s *trcm, int fileno, int line, u32 data);108 109#define bfa_sm_fault(__mod, __event) do { \110 bfa_trc(__mod, (((u32)0xDEAD << 16) | __event)); \111 printk(KERN_ERR "Assertion failure: %s:%d: %d", \112 __FILE__, __LINE__, (__event)); \113} while (0)114 115/* BFA queue definitions */116#define bfa_q_first(_q) ((void *)(((struct list_head *) (_q))->next))117#define bfa_q_next(_qe) (((struct list_head *) (_qe))->next)118#define bfa_q_prev(_qe) (((struct list_head *) (_qe))->prev)119 120/*121 * bfa_q_qe_init - to initialize a queue element122 */123#define bfa_q_qe_init(_qe) { \124 bfa_q_next(_qe) = (struct list_head *) NULL; \125 bfa_q_prev(_qe) = (struct list_head *) NULL; \126}127 128/*129 * bfa_q_deq - dequeue an element from head of the queue130 */131#define bfa_q_deq(_q, _qe) do { \132 if (!list_empty(_q)) { \133 (*((struct list_head **) (_qe))) = bfa_q_next(_q); \134 bfa_q_prev(bfa_q_next(*((struct list_head **) _qe))) = \135 (struct list_head *) (_q); \136 bfa_q_next(_q) = bfa_q_next(*((struct list_head **) _qe));\137 } else { \138 *((struct list_head **) (_qe)) = (struct list_head *) NULL;\139 } \140} while (0)141 142/*143 * bfa_q_deq_tail - dequeue an element from tail of the queue144 */145#define bfa_q_deq_tail(_q, _qe) { \146 if (!list_empty(_q)) { \147 *((struct list_head **) (_qe)) = bfa_q_prev(_q); \148 bfa_q_next(bfa_q_prev(*((struct list_head **) _qe))) = \149 (struct list_head *) (_q); \150 bfa_q_prev(_q) = bfa_q_prev(*(struct list_head **) _qe);\151 } else { \152 *((struct list_head **) (_qe)) = (struct list_head *) NULL;\153 } \154}155 156static inline int157bfa_q_is_on_q_func(struct list_head *q, struct list_head *qe)158{159 struct list_head *tqe;160 161 tqe = bfa_q_next(q);162 while (tqe != q) {163 if (tqe == qe)164 return 1;165 tqe = bfa_q_next(tqe);166 if (tqe == NULL)167 break;168 }169 return 0;170}171 172#define bfa_q_is_on_q(_q, _qe) \173 bfa_q_is_on_q_func(_q, (struct list_head *)(_qe))174 175/*176 * @ BFA state machine interfaces177 */178 179typedef void (*bfa_sm_t)(void *sm, int event);180 181/*182 * oc - object class eg. bfa_ioc183 * st - state, eg. reset184 * otype - object type, eg. struct bfa_ioc_s185 * etype - object type, eg. enum ioc_event186 */187#define bfa_sm_state_decl(oc, st, otype, etype) \188 static void oc ## _sm_ ## st(otype * fsm, etype event)189 190#define bfa_sm_set_state(_sm, _state) ((_sm)->sm = (_state))191#define bfa_sm_send_event(_sm, _event) ((_sm)->sm((_sm), (_event)))192#define bfa_sm_get_state(_sm) ((_sm)->sm)193#define bfa_sm_cmp_state(_sm, _state) ((_sm)->sm == (_state))194 195/*196 * For converting from state machine function to state encoding.197 */198struct bfa_sm_table_s {199 bfa_sm_t sm; /* state machine function */200 int state; /* state machine encoding */201 char *name; /* state name for display */202};203#define BFA_SM(_sm) (_sm)204 205/*206 * State machine with entry actions.207 */208typedef void (*bfa_fsm_t)(void *fsm, int event);209 210/*211 * oc - object class eg. bfa_ioc212 * st - state, eg. reset213 * otype - object type, eg. struct bfa_ioc_s214 * etype - object type, eg. enum ioc_event215 */216#define bfa_fsm_state_decl(oc, st, otype, etype) \217 static void oc ## _sm_ ## st(otype * fsm, etype event); \218 static void oc ## _sm_ ## st ## _entry(otype * fsm)219 220#define bfa_fsm_set_state(_fsm, _state) do { \221 (_fsm)->fsm = (_state); \222 _state ## _entry(_fsm); \223} while (0)224 225#define bfa_fsm_send_event(_fsm, _event) ((_fsm)->fsm((_fsm), (_event)))226#define bfa_fsm_get_state(_fsm) ((_fsm)->fsm)227#define bfa_fsm_cmp_state(_fsm, _state) ((_fsm)->fsm == (_state))228 229/*230 * @ Generic wait counter.231 */232 233typedef void (*bfa_wc_resume_t) (void *cbarg);234 235struct bfa_wc_s {236 bfa_wc_resume_t wc_resume;237 void *wc_cbarg;238 int wc_count;239};240 241static inline void242bfa_wc_up(struct bfa_wc_s *wc)243{244 wc->wc_count++;245}246 247static inline void248bfa_wc_down(struct bfa_wc_s *wc)249{250 wc->wc_count--;251 if (wc->wc_count == 0)252 wc->wc_resume(wc->wc_cbarg);253}254 255/*256 * Initialize a waiting counter.257 */258static inline void259bfa_wc_init(struct bfa_wc_s *wc, bfa_wc_resume_t wc_resume, void *wc_cbarg)260{261 wc->wc_resume = wc_resume;262 wc->wc_cbarg = wc_cbarg;263 wc->wc_count = 0;264 bfa_wc_up(wc);265}266 267/*268 * Wait for counter to reach zero269 */270static inline void271bfa_wc_wait(struct bfa_wc_s *wc)272{273 bfa_wc_down(wc);274}275 276static inline void277wwn2str(char *wwn_str, u64 wwn)278{279 union {280 u64 wwn;281 u8 byte[8];282 } w;283 284 w.wwn = wwn;285 sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", w.byte[0],286 w.byte[1], w.byte[2], w.byte[3], w.byte[4], w.byte[5],287 w.byte[6], w.byte[7]);288}289 290static inline void291fcid2str(char *fcid_str, u32 fcid)292{293 union {294 u32 fcid;295 u8 byte[4];296 } f;297 298 f.fcid = fcid;299 sprintf(fcid_str, "%02x:%02x:%02x", f.byte[1], f.byte[2], f.byte[3]);300}301 302#define bfa_swap_3b(_x) \303 ((((_x) & 0xff) << 16) | \304 ((_x) & 0x00ff00) | \305 (((_x) & 0xff0000) >> 16))306 307#ifndef __BIG_ENDIAN308#define bfa_hton3b(_x) bfa_swap_3b(_x)309#else310#define bfa_hton3b(_x) (_x)311#endif312 313#define bfa_ntoh3b(_x) bfa_hton3b(_x)314 315#endif /* __BFA_CS_H__ */316