Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd5a92e9 authored by Rasesh Mody's avatar Rasesh Mody Committed by David S. Miller
Browse files

bna: IOC Event Notification Enhancement



Change details:
 - Replace IOC HB failure event notification with a more generic mechanism
   that is capable of sending enble, disable, and failed events to registered
   modules. As a result, cee  module event handling callback bfa_cee_hbfail()
   is replaced with bfa_cee_notify() so that it can receive and handle
   different events from IOC.

Signed-off-by: default avatarRasesh Mody <rmody@brocade.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0120b99c
Loading
Loading
Loading
Loading
+39 −26
Original line number Diff line number Diff line
@@ -223,26 +223,31 @@ bfa_cee_isr(void *cbarg, struct bfi_mbmsg *m)
}

/**
 * bfa_cee_hbfail()
 * bfa_cee_notify()
 *
 * @brief CEE module heart-beat failure handler.
 * @brief CEE module IOC event handler.
 *
 * @param[in] Pointer to the CEE module data structure.
 * @param[in] IOC event type
 *
 * @return void
 */

static void
bfa_cee_hbfail(void *arg)
bfa_cee_notify(void *arg, enum bfa_ioc_event event)
{
	struct bfa_cee *cee;
	cee = arg;
	cee = (struct bfa_cee *) arg;

	switch (event) {
	case BFA_IOC_E_DISABLED:
	case BFA_IOC_E_FAILED:
		if (cee->get_attr_pending == true) {
			cee->get_attr_status = BFA_STATUS_FAILED;
			cee->get_attr_pending  = false;
			if (cee->cbfn.get_attr_cbfn) {
			cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg,
				cee->cbfn.get_attr_cbfn(
					cee->cbfn.get_attr_cbarg,
					BFA_STATUS_FAILED);
			}
		}
@@ -250,7 +255,8 @@ bfa_cee_hbfail(void *arg)
			cee->get_stats_status = BFA_STATUS_FAILED;
			cee->get_stats_pending  = false;
			if (cee->cbfn.get_stats_cbfn) {
			cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg,
				cee->cbfn.get_stats_cbfn(
					cee->cbfn.get_stats_cbarg,
					BFA_STATUS_FAILED);
			}
		}
@@ -258,10 +264,16 @@ bfa_cee_hbfail(void *arg)
			cee->reset_stats_status = BFA_STATUS_FAILED;
			cee->reset_stats_pending  = false;
			if (cee->cbfn.reset_stats_cbfn) {
			cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg,
				cee->cbfn.reset_stats_cbfn(
					cee->cbfn.reset_stats_cbarg,
					BFA_STATUS_FAILED);
			}
		}
		break;

	default:
		break;
	}
}

/**
@@ -286,6 +298,7 @@ bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc,
	cee->ioc = ioc;

	bfa_nw_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
	bfa_ioc_hbfail_init(&cee->hbfail, bfa_cee_hbfail, cee);
	bfa_nw_ioc_hbfail_register(cee->ioc, &cee->hbfail);
	bfa_q_qe_init(&cee->ioc_notify);
	bfa_ioc_notify_init(&cee->ioc_notify, bfa_cee_notify, cee);
	bfa_nw_ioc_notify_register(cee->ioc, &cee->ioc_notify);
}
+1 −2
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@
typedef void (*bfa_cee_get_attr_cbfn_t) (void *dev, enum bfa_status status);
typedef void (*bfa_cee_get_stats_cbfn_t) (void *dev, enum bfa_status status);
typedef void (*bfa_cee_reset_stats_cbfn_t) (void *dev, enum bfa_status status);
typedef void (*bfa_cee_hbfail_cbfn_t) (void *dev, enum bfa_status status);

struct bfa_cee_cbfn {
	bfa_cee_get_attr_cbfn_t    get_attr_cbfn;
@@ -45,7 +44,7 @@ struct bfa_cee {
	enum bfa_status get_stats_status;
	enum bfa_status reset_stats_status;
	struct bfa_cee_cbfn cbfn;
	struct bfa_ioc_hbfail_notify hbfail;
	struct bfa_ioc_notify ioc_notify;
	struct bfa_cee_attr *attr;
	struct bfa_cee_stats *stats;
	struct bfa_dma attr_dma;
+33 −21
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ static void bfa_ioc_mbox_poll(struct bfa_ioc *ioc);
static void bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc);
static void bfa_ioc_recover(struct bfa_ioc *ioc);
static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc);
static void bfa_ioc_event_notify(struct bfa_ioc *, enum bfa_ioc_event);
static void bfa_ioc_disable_comp(struct bfa_ioc *ioc);
static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc);
static void bfa_ioc_fail_notify(struct bfa_ioc *ioc);
@@ -1123,21 +1124,26 @@ bfa_iocpf_sm_fail(struct bfa_iocpf *iocpf, enum iocpf_event event)
 * BFA IOC private functions
 */

/**
 * Notify common modules registered for notification.
 */
static void
bfa_ioc_disable_comp(struct bfa_ioc *ioc)
bfa_ioc_event_notify(struct bfa_ioc *ioc, enum bfa_ioc_event event)
{
	struct bfa_ioc_notify *notify;
	struct list_head			*qe;
	struct bfa_ioc_hbfail_notify *notify;

	ioc->cbfn->disable_cbfn(ioc->bfa);

	/**
	 * Notify common modules registered for notification.
	 */
	list_for_each(qe, &ioc->hb_notify_q) {
		notify = (struct bfa_ioc_hbfail_notify *) qe;
		notify->cbfn(notify->cbarg);
	list_for_each(qe, &ioc->notify_q) {
		notify = (struct bfa_ioc_notify *)qe;
		notify->cbfn(notify->cbarg, event);
	}
}

static void
bfa_ioc_disable_comp(struct bfa_ioc *ioc)
{
	ioc->cbfn->disable_cbfn(ioc->bfa);
	bfa_ioc_event_notify(ioc, BFA_IOC_E_DISABLED);
}

bool
@@ -1650,17 +1656,11 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc)
static void
bfa_ioc_fail_notify(struct bfa_ioc *ioc)
{
	struct list_head		*qe;
	struct bfa_ioc_hbfail_notify	*notify;

	/**
	 * Notify driver and common modules registered for notification.
	 */
	ioc->cbfn->hbfail_cbfn(ioc->bfa);
	list_for_each(qe, &ioc->hb_notify_q) {
		notify = (struct bfa_ioc_hbfail_notify *) qe;
		notify->cbfn(notify->cbarg);
	}
	bfa_ioc_event_notify(ioc, BFA_IOC_E_FAILED);
}

static void
@@ -1839,7 +1839,7 @@ bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn)
	ioc->iocpf.ioc  = ioc;

	bfa_ioc_mbox_attach(ioc);
	INIT_LIST_HEAD(&ioc->hb_notify_q);
	INIT_LIST_HEAD(&ioc->notify_q);

	bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
	bfa_fsm_send_event(ioc, IOC_E_RESET);
@@ -1969,6 +1969,8 @@ bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd)
	 * mailbox is free -- queue command to firmware
	 */
	bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));

	return;
}

/**
@@ -2004,15 +2006,25 @@ bfa_nw_ioc_error_isr(struct bfa_ioc *ioc)
	bfa_fsm_send_event(ioc, IOC_E_HWERROR);
}

/**
 * return true if IOC is disabled
 */
bool
bfa_nw_ioc_is_disabled(struct bfa_ioc *ioc)
{
	return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) ||
		bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
}

/**
 * Add to IOC heartbeat failure notification queue. To be used by common
 * modules such as cee, port, diag.
 */
void
bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc,
			struct bfa_ioc_hbfail_notify *notify)
bfa_nw_ioc_notify_register(struct bfa_ioc *ioc,
			struct bfa_ioc_notify *notify)
{
	list_add_tail(&notify->qe, &ioc->hb_notify_q);
	list_add_tail(&notify->qe, &ioc->notify_q);
}

#define BFA_MFG_NAME "Brocade"
+26 −5
Original line number Diff line number Diff line
@@ -97,8 +97,11 @@ struct bfa_ioc_regs {
/**
 * IOC Mailbox structures
 */
typedef void (*bfa_mbox_cmd_cbfn_t)(void *cbarg);
struct bfa_mbox_cmd {
	struct list_head	qe;
	bfa_mbox_cmd_cbfn_t     cbfn;
	void		    *cbarg;
	u32     msg[BFI_IOC_MSGSZ];
};

@@ -129,6 +132,23 @@ struct bfa_ioc_cbfn {
	bfa_ioc_reset_cbfn_t	reset_cbfn;
};

/**
 * IOC event notification mechanism.
 */
enum bfa_ioc_event {
	BFA_IOC_E_ENABLED	= 1,
	BFA_IOC_E_DISABLED	= 2,
	BFA_IOC_E_FAILED	= 3,
};

typedef void (*bfa_ioc_notify_cbfn_t)(void *, enum bfa_ioc_event);

struct bfa_ioc_notify {
	struct list_head	qe;
	bfa_ioc_notify_cbfn_t	cbfn;
	void			*cbarg;
};

/**
 * Heartbeat failure notification queue element.
 */
@@ -141,7 +161,7 @@ struct bfa_ioc_hbfail_notify {
/**
 * Initialize a heartbeat failure notification structure
 */
#define bfa_ioc_hbfail_init(__notify, __cbfn, __cbarg) do {	\
#define bfa_ioc_notify_init(__notify, __cbfn, __cbarg) do {	\
	(__notify)->cbfn = (__cbfn);				\
	(__notify)->cbarg = (__cbarg);				\
} while (0)
@@ -162,7 +182,7 @@ struct bfa_ioc {
	struct timer_list	sem_timer;
	struct timer_list	hb_timer;
	u32			hb_count;
	struct list_head	hb_notify_q;
	struct list_head	notify_q;
	void			*dbg_fwsave;
	int			dbg_fwsave_len;
	bool			dbg_fwsave_once;
@@ -263,9 +283,10 @@ void bfa_nw_ioc_enable(struct bfa_ioc *ioc);
void bfa_nw_ioc_disable(struct bfa_ioc *ioc);

void bfa_nw_ioc_error_isr(struct bfa_ioc *ioc);
bool bfa_nw_ioc_is_disabled(struct bfa_ioc *ioc);
void bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr);
void bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc,
	struct bfa_ioc_hbfail_notify *notify);
void bfa_nw_ioc_notify_register(struct bfa_ioc *ioc,
	struct bfa_ioc_notify *notify);
bool bfa_nw_ioc_sem_get(void __iomem *sem_reg);
void bfa_nw_ioc_sem_release(void __iomem *sem_reg);
void bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc);