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

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
...@@ -223,44 +223,56 @@ bfa_cee_isr(void *cbarg, struct bfi_mbmsg *m) ...@@ -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 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 * @return void
*/ */
static void static void
bfa_cee_hbfail(void *arg) bfa_cee_notify(void *arg, enum bfa_ioc_event event)
{ {
struct bfa_cee *cee; struct bfa_cee *cee;
cee = arg; cee = (struct bfa_cee *) arg;
if (cee->get_attr_pending == true) { switch (event) {
cee->get_attr_status = BFA_STATUS_FAILED; case BFA_IOC_E_DISABLED:
cee->get_attr_pending = false; case BFA_IOC_E_FAILED:
if (cee->cbfn.get_attr_cbfn) { if (cee->get_attr_pending == true) {
cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, cee->get_attr_status = BFA_STATUS_FAILED;
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) {
if (cee->get_stats_pending == true) { cee->get_stats_status = BFA_STATUS_FAILED;
cee->get_stats_status = BFA_STATUS_FAILED; cee->get_stats_pending = false;
cee->get_stats_pending = false; if (cee->cbfn.get_stats_cbfn) {
if (cee->cbfn.get_stats_cbfn) { cee->cbfn.get_stats_cbfn(
cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, cee->cbfn.get_stats_cbarg,
BFA_STATUS_FAILED); BFA_STATUS_FAILED);
}
} }
} if (cee->reset_stats_pending == true) {
if (cee->reset_stats_pending == true) { cee->reset_stats_status = BFA_STATUS_FAILED;
cee->reset_stats_status = BFA_STATUS_FAILED; cee->reset_stats_pending = false;
cee->reset_stats_pending = false; if (cee->cbfn.reset_stats_cbfn) {
if (cee->cbfn.reset_stats_cbfn) { cee->cbfn.reset_stats_cbfn(
cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, cee->cbfn.reset_stats_cbarg,
BFA_STATUS_FAILED); BFA_STATUS_FAILED);
}
} }
break;
default:
break;
} }
} }
...@@ -286,6 +298,7 @@ bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc, ...@@ -286,6 +298,7 @@ bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc,
cee->ioc = ioc; cee->ioc = ioc;
bfa_nw_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee); 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_q_qe_init(&cee->ioc_notify);
bfa_nw_ioc_hbfail_register(cee->ioc, &cee->hbfail); 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 @@ ...@@ -25,7 +25,6 @@
typedef void (*bfa_cee_get_attr_cbfn_t) (void *dev, enum bfa_status status); 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_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_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 { struct bfa_cee_cbfn {
bfa_cee_get_attr_cbfn_t get_attr_cbfn; bfa_cee_get_attr_cbfn_t get_attr_cbfn;
...@@ -45,7 +44,7 @@ struct bfa_cee { ...@@ -45,7 +44,7 @@ struct bfa_cee {
enum bfa_status get_stats_status; enum bfa_status get_stats_status;
enum bfa_status reset_stats_status; enum bfa_status reset_stats_status;
struct bfa_cee_cbfn cbfn; 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_attr *attr;
struct bfa_cee_stats *stats; struct bfa_cee_stats *stats;
struct bfa_dma attr_dma; struct bfa_dma attr_dma;
......
...@@ -71,6 +71,7 @@ static void bfa_ioc_mbox_poll(struct bfa_ioc *ioc); ...@@ -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_mbox_hbfail(struct bfa_ioc *ioc);
static void bfa_ioc_recover(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_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_disable_comp(struct bfa_ioc *ioc);
static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc); static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc);
static void bfa_ioc_fail_notify(struct bfa_ioc *ioc); static void bfa_ioc_fail_notify(struct bfa_ioc *ioc);
...@@ -1123,23 +1124,28 @@ bfa_iocpf_sm_fail(struct bfa_iocpf *iocpf, enum iocpf_event event) ...@@ -1123,23 +1124,28 @@ bfa_iocpf_sm_fail(struct bfa_iocpf *iocpf, enum iocpf_event event)
* BFA IOC private functions * BFA IOC private functions
*/ */
/**
* Notify common modules registered for notification.
*/
static void 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 list_head *qe;
struct bfa_ioc_hbfail_notify *notify;
ioc->cbfn->disable_cbfn(ioc->bfa); list_for_each(qe, &ioc->notify_q) {
notify = (struct bfa_ioc_notify *)qe;
/** notify->cbfn(notify->cbarg, event);
* 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);
} }
} }
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 bool
bfa_nw_ioc_sem_get(void __iomem *sem_reg) bfa_nw_ioc_sem_get(void __iomem *sem_reg)
{ {
...@@ -1650,17 +1656,11 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc) ...@@ -1650,17 +1656,11 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc)
static void static void
bfa_ioc_fail_notify(struct bfa_ioc *ioc) 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. * Notify driver and common modules registered for notification.
*/ */
ioc->cbfn->hbfail_cbfn(ioc->bfa); ioc->cbfn->hbfail_cbfn(ioc->bfa);
list_for_each(qe, &ioc->hb_notify_q) { bfa_ioc_event_notify(ioc, BFA_IOC_E_FAILED);
notify = (struct bfa_ioc_hbfail_notify *) qe;
notify->cbfn(notify->cbarg);
}
} }
static void static void
...@@ -1839,7 +1839,7 @@ bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn) ...@@ -1839,7 +1839,7 @@ bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn)
ioc->iocpf.ioc = ioc; ioc->iocpf.ioc = ioc;
bfa_ioc_mbox_attach(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_set_state(ioc, bfa_ioc_sm_uninit);
bfa_fsm_send_event(ioc, IOC_E_RESET); 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) ...@@ -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 * mailbox is free -- queue command to firmware
*/ */
bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
return;
} }
/** /**
...@@ -2004,15 +2006,25 @@ bfa_nw_ioc_error_isr(struct bfa_ioc *ioc) ...@@ -2004,15 +2006,25 @@ bfa_nw_ioc_error_isr(struct bfa_ioc *ioc)
bfa_fsm_send_event(ioc, IOC_E_HWERROR); 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 * Add to IOC heartbeat failure notification queue. To be used by common
* modules such as cee, port, diag. * modules such as cee, port, diag.
*/ */
void void
bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc, bfa_nw_ioc_notify_register(struct bfa_ioc *ioc,
struct bfa_ioc_hbfail_notify *notify) 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" #define BFA_MFG_NAME "Brocade"
......
...@@ -97,9 +97,12 @@ struct bfa_ioc_regs { ...@@ -97,9 +97,12 @@ struct bfa_ioc_regs {
/** /**
* IOC Mailbox structures * IOC Mailbox structures
*/ */
typedef void (*bfa_mbox_cmd_cbfn_t)(void *cbarg);
struct bfa_mbox_cmd { struct bfa_mbox_cmd {
struct list_head qe; 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 { ...@@ -129,6 +132,23 @@ struct bfa_ioc_cbfn {
bfa_ioc_reset_cbfn_t reset_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. * Heartbeat failure notification queue element.
*/ */
...@@ -141,7 +161,7 @@ struct bfa_ioc_hbfail_notify { ...@@ -141,7 +161,7 @@ struct bfa_ioc_hbfail_notify {
/** /**
* Initialize a heartbeat failure notification structure * 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)->cbfn = (__cbfn); \
(__notify)->cbarg = (__cbarg); \ (__notify)->cbarg = (__cbarg); \
} while (0) } while (0)
...@@ -162,7 +182,7 @@ struct bfa_ioc { ...@@ -162,7 +182,7 @@ struct bfa_ioc {
struct timer_list sem_timer; struct timer_list sem_timer;
struct timer_list hb_timer; struct timer_list hb_timer;
u32 hb_count; u32 hb_count;
struct list_head hb_notify_q; struct list_head notify_q;
void *dbg_fwsave; void *dbg_fwsave;
int dbg_fwsave_len; int dbg_fwsave_len;
bool dbg_fwsave_once; bool dbg_fwsave_once;
...@@ -263,9 +283,10 @@ void bfa_nw_ioc_enable(struct bfa_ioc *ioc); ...@@ -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_disable(struct bfa_ioc *ioc);
void bfa_nw_ioc_error_isr(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_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr);
void bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc, void bfa_nw_ioc_notify_register(struct bfa_ioc *ioc,
struct bfa_ioc_hbfail_notify *notify); struct bfa_ioc_notify *notify);
bool bfa_nw_ioc_sem_get(void __iomem *sem_reg); bool bfa_nw_ioc_sem_get(void __iomem *sem_reg);
void bfa_nw_ioc_sem_release(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); void bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment