forked from Minki/linux
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: Rasesh Mody <rmody@brocade.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
0120b99c8d
commit
bd5a92e9a0
@ -223,44 +223,56 @@ 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;
|
||||
|
||||
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,
|
||||
BFA_STATUS_FAILED);
|
||||
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,
|
||||
BFA_STATUS_FAILED);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cee->get_stats_pending == true) {
|
||||
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,
|
||||
BFA_STATUS_FAILED);
|
||||
if (cee->get_stats_pending == true) {
|
||||
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,
|
||||
BFA_STATUS_FAILED);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cee->reset_stats_pending == true) {
|
||||
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,
|
||||
BFA_STATUS_FAILED);
|
||||
if (cee->reset_stats_pending == true) {
|
||||
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,
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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_event_notify(struct bfa_ioc *ioc, enum bfa_ioc_event event)
|
||||
{
|
||||
struct bfa_ioc_notify *notify;
|
||||
struct list_head *qe;
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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(¬ify->qe, &ioc->hb_notify_q);
|
||||
list_add_tail(¬ify->qe, &ioc->notify_q);
|
||||
}
|
||||
|
||||
#define BFA_MFG_NAME "Brocade"
|
||||
|
@ -97,9 +97,12 @@ struct bfa_ioc_regs {
|
||||
/**
|
||||
* IOC Mailbox structures
|
||||
*/
|
||||
typedef void (*bfa_mbox_cmd_cbfn_t)(void *cbarg);
|
||||
struct bfa_mbox_cmd {
|
||||
struct list_head qe;
|
||||
u32 msg[BFI_IOC_MSGSZ];
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user