162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Linux network driver for QLogic BR-series Converged Network Adapter.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci/*
662306a36Sopenharmony_ci * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
762306a36Sopenharmony_ci * Copyright (c) 2014-2015 QLogic Corporation
862306a36Sopenharmony_ci * All rights reserved
962306a36Sopenharmony_ci * www.qlogic.com
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci/* BFA common services */
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#ifndef __BFA_CS_H__
1562306a36Sopenharmony_ci#define __BFA_CS_H__
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include "cna.h"
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci/* BFA state machine interfaces */
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/* For converting from state machine function to state encoding. */
2262306a36Sopenharmony_ci#define BFA_SM_TABLE(n, s, e, t)				\
2362306a36Sopenharmony_cistruct s;							\
2462306a36Sopenharmony_cienum e;								\
2562306a36Sopenharmony_citypedef void (*t)(struct s *, enum e);				\
2662306a36Sopenharmony_ci								\
2762306a36Sopenharmony_cistruct n ## _sm_table_s {					\
2862306a36Sopenharmony_ci	t		sm;	/* state machine function */	\
2962306a36Sopenharmony_ci	int		state;	/* state machine encoding */	\
3062306a36Sopenharmony_ci	char		*name;	/* state name for display */	\
3162306a36Sopenharmony_ci};								\
3262306a36Sopenharmony_ci								\
3362306a36Sopenharmony_cistatic inline int						\
3462306a36Sopenharmony_cin ## _sm_to_state(struct n ## _sm_table_s *smt, t sm)		\
3562306a36Sopenharmony_ci{								\
3662306a36Sopenharmony_ci	int	i = 0;						\
3762306a36Sopenharmony_ci								\
3862306a36Sopenharmony_ci	while (smt[i].sm && smt[i].sm != sm)			\
3962306a36Sopenharmony_ci		i++;						\
4062306a36Sopenharmony_ci	return smt[i].state;					\
4162306a36Sopenharmony_ci}
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ciBFA_SM_TABLE(iocpf,	bfa_iocpf,	iocpf_event,	bfa_fsm_iocpf_t)
4462306a36Sopenharmony_ciBFA_SM_TABLE(ioc,	bfa_ioc,	ioc_event,	bfa_fsm_ioc_t)
4562306a36Sopenharmony_ciBFA_SM_TABLE(cmdq,	bfa_msgq_cmdq,	cmdq_event,	bfa_fsm_msgq_cmdq_t)
4662306a36Sopenharmony_ciBFA_SM_TABLE(rspq,	bfa_msgq_rspq,	rspq_event,	bfa_fsm_msgq_rspq_t)
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ciBFA_SM_TABLE(ioceth,	bna_ioceth,	bna_ioceth_event, bna_fsm_ioceth_t)
4962306a36Sopenharmony_ciBFA_SM_TABLE(enet,	bna_enet,	bna_enet_event, bna_fsm_enet_t)
5062306a36Sopenharmony_ciBFA_SM_TABLE(ethport,	bna_ethport,	bna_ethport_event, bna_fsm_ethport_t)
5162306a36Sopenharmony_ciBFA_SM_TABLE(tx,	bna_tx,		bna_tx_event,	bna_fsm_tx_t)
5262306a36Sopenharmony_ciBFA_SM_TABLE(rxf,	bna_rxf,	bna_rxf_event, bna_fsm_rxf_t)
5362306a36Sopenharmony_ciBFA_SM_TABLE(rx,	bna_rx,		bna_rx_event,	bna_fsm_rx_t)
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci#undef BFA_SM_TABLE
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci#define BFA_SM(_sm)	(_sm)
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci/* State machine with entry actions. */
6062306a36Sopenharmony_citypedef void (*bfa_fsm_t)(void *fsm, int event);
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci/* oc - object class eg. bfa_ioc
6362306a36Sopenharmony_ci * st - state, eg. reset
6462306a36Sopenharmony_ci * otype - object type, eg. struct bfa_ioc
6562306a36Sopenharmony_ci * etype - object type, eg. enum ioc_event
6662306a36Sopenharmony_ci */
6762306a36Sopenharmony_ci#define bfa_fsm_state_decl(oc, st, otype, etype)			\
6862306a36Sopenharmony_ci	static void oc ## _sm_ ## st(otype * fsm, etype event);		\
6962306a36Sopenharmony_ci	static void oc ## _sm_ ## st ## _entry(otype * fsm)
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci#define bfa_fsm_set_state(_fsm, _state) do {				\
7262306a36Sopenharmony_ci	(_fsm)->fsm = (_state);						\
7362306a36Sopenharmony_ci	_state ## _entry(_fsm);						\
7462306a36Sopenharmony_ci} while (0)
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#define bfa_fsm_send_event(_fsm, _event)	((_fsm)->fsm((_fsm), (_event)))
7762306a36Sopenharmony_ci#define bfa_fsm_cmp_state(_fsm, _state)		((_fsm)->fsm == (_state))
7862306a36Sopenharmony_ci/* Generic wait counter. */
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_citypedef void (*bfa_wc_resume_t) (void *cbarg);
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistruct bfa_wc {
8362306a36Sopenharmony_ci	bfa_wc_resume_t wc_resume;
8462306a36Sopenharmony_ci	void		*wc_cbarg;
8562306a36Sopenharmony_ci	int		wc_count;
8662306a36Sopenharmony_ci};
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_cistatic inline void
8962306a36Sopenharmony_cibfa_wc_up(struct bfa_wc *wc)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci	wc->wc_count++;
9262306a36Sopenharmony_ci}
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_cistatic inline void
9562306a36Sopenharmony_cibfa_wc_down(struct bfa_wc *wc)
9662306a36Sopenharmony_ci{
9762306a36Sopenharmony_ci	wc->wc_count--;
9862306a36Sopenharmony_ci	if (wc->wc_count == 0)
9962306a36Sopenharmony_ci		wc->wc_resume(wc->wc_cbarg);
10062306a36Sopenharmony_ci}
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci/* Initialize a waiting counter. */
10362306a36Sopenharmony_cistatic inline void
10462306a36Sopenharmony_cibfa_wc_init(struct bfa_wc *wc, bfa_wc_resume_t wc_resume, void *wc_cbarg)
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	wc->wc_resume = wc_resume;
10762306a36Sopenharmony_ci	wc->wc_cbarg = wc_cbarg;
10862306a36Sopenharmony_ci	wc->wc_count = 0;
10962306a36Sopenharmony_ci	bfa_wc_up(wc);
11062306a36Sopenharmony_ci}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci/* Wait for counter to reach zero */
11362306a36Sopenharmony_cistatic inline void
11462306a36Sopenharmony_cibfa_wc_wait(struct bfa_wc *wc)
11562306a36Sopenharmony_ci{
11662306a36Sopenharmony_ci	bfa_wc_down(wc);
11762306a36Sopenharmony_ci}
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#endif /* __BFA_CS_H__ */
120