Commit d37779f8 authored by Krishna Gudipati's avatar Krishna Gudipati Committed by James Bottomley

[SCSI] bfa: Introduce IOC event notification mechanism.

Introduced a generic event notification callback function that
receives IOC_ENABLED, IOC_DISABLED, IOC_FAILED events and notifies the
modules registered for these events.
Signed-off-by: default avatarKrishna Gudipati <kgudipat@brocade.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 85ce928d
...@@ -821,7 +821,7 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ...@@ -821,7 +821,7 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
if (pcidev->device_id == BFA_PCI_DEVICE_ID_CT_FC) if (pcidev->device_id == BFA_PCI_DEVICE_ID_CT_FC)
bfa_ioc_set_fcmode(&bfa->ioc); bfa_ioc_set_fcmode(&bfa->ioc);
bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC); bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_PCIFN_CLASS_FC);
bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs); bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev); bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
......
...@@ -87,6 +87,8 @@ static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc); ...@@ -87,6 +87,8 @@ static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc); static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
static void bfa_ioc_recover(struct bfa_ioc_s *ioc); static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
static void bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc); static void bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc);
static void bfa_ioc_event_notify(struct bfa_ioc_s *ioc ,
enum bfa_ioc_event_e event);
static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc); static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc); static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
static void bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc); static void bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc);
...@@ -391,6 +393,7 @@ bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc) ...@@ -391,6 +393,7 @@ bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED);
bfa_ioc_hb_monitor(ioc); bfa_ioc_hb_monitor(ioc);
BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n"); BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n");
} }
...@@ -1185,23 +1188,28 @@ bfa_iocpf_sm_fail(struct bfa_iocpf_s *iocpf, enum iocpf_event event) ...@@ -1185,23 +1188,28 @@ bfa_iocpf_sm_fail(struct bfa_iocpf_s *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_s *ioc) bfa_ioc_event_notify(struct bfa_ioc_s *ioc, enum bfa_ioc_event_e event)
{ {
struct list_head *qe; struct bfa_ioc_notify_s *notify;
struct bfa_ioc_hbfail_notify_s *notify; struct list_head *qe;
ioc->cbfn->disable_cbfn(ioc->bfa);
/* list_for_each(qe, &ioc->notify_q) {
* Notify common modules registered for notification. notify = (struct bfa_ioc_notify_s *)qe;
*/ notify->cbfn(notify->cbarg, event);
list_for_each(qe, &ioc->hb_notify_q) {
notify = (struct bfa_ioc_hbfail_notify_s *) qe;
notify->cbfn(notify->cbarg);
} }
} }
static void
bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
{
ioc->cbfn->disable_cbfn(ioc->bfa);
bfa_ioc_event_notify(ioc, BFA_IOC_E_DISABLED);
}
bfa_boolean_t bfa_boolean_t
bfa_ioc_sem_get(void __iomem *sem_reg) bfa_ioc_sem_get(void __iomem *sem_reg)
{ {
...@@ -1508,7 +1516,7 @@ bfa_ioc_send_enable(struct bfa_ioc_s *ioc) ...@@ -1508,7 +1516,7 @@ bfa_ioc_send_enable(struct bfa_ioc_s *ioc)
bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ, bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
bfa_ioc_portid(ioc)); bfa_ioc_portid(ioc));
enable_req.ioc_class = ioc->ioc_mc; enable_req.clscode = cpu_to_be16(ioc->clscode);
do_gettimeofday(&tv); do_gettimeofday(&tv);
enable_req.tv_sec = be32_to_cpu(tv.tv_sec); enable_req.tv_sec = be32_to_cpu(tv.tv_sec);
bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s)); bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s));
...@@ -1816,18 +1824,13 @@ bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz) ...@@ -1816,18 +1824,13 @@ bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
static void static void
bfa_ioc_fail_notify(struct bfa_ioc_s *ioc) bfa_ioc_fail_notify(struct bfa_ioc_s *ioc)
{ {
struct list_head *qe;
struct bfa_ioc_hbfail_notify_s *notify;
struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
/* /*
* 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_s *) qe;
notify->cbfn(notify->cbarg);
}
bfa_ioc_debug_save_ftrc(ioc); bfa_ioc_debug_save_ftrc(ioc);
...@@ -2011,7 +2014,7 @@ bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn, ...@@ -2011,7 +2014,7 @@ bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *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);
...@@ -2033,9 +2036,9 @@ bfa_ioc_detach(struct bfa_ioc_s *ioc) ...@@ -2033,9 +2036,9 @@ bfa_ioc_detach(struct bfa_ioc_s *ioc)
*/ */
void void
bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev, bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
enum bfi_mclass mc) enum bfi_pcifn_class clscode)
{ {
ioc->ioc_mc = mc; ioc->clscode = clscode;
ioc->pcidev = *pcidev; ioc->pcidev = *pcidev;
ioc->ctdev = bfa_asic_id_ct(ioc->pcidev.device_id); ioc->ctdev = bfa_asic_id_ct(ioc->pcidev.device_id);
ioc->cna = ioc->ctdev && !ioc->fcmode; ioc->cna = ioc->ctdev && !ioc->fcmode;
...@@ -2318,12 +2321,10 @@ bfa_ioc_get_type(struct bfa_ioc_s *ioc) ...@@ -2318,12 +2321,10 @@ bfa_ioc_get_type(struct bfa_ioc_s *ioc)
{ {
if (!ioc->ctdev || ioc->fcmode) if (!ioc->ctdev || ioc->fcmode)
return BFA_IOC_TYPE_FC; return BFA_IOC_TYPE_FC;
else if (ioc->ioc_mc == BFI_MC_IOCFC) else if (ioc->clscode == BFI_PCIFN_CLASS_FC)
return BFA_IOC_TYPE_FCoE; return BFA_IOC_TYPE_FCoE;
else if (ioc->ioc_mc == BFI_MC_LL)
return BFA_IOC_TYPE_LL;
else { else {
WARN_ON(ioc->ioc_mc != BFI_MC_LL); WARN_ON(ioc->clscode != BFI_PCIFN_CLASS_ETH);
return BFA_IOC_TYPE_LL; return BFA_IOC_TYPE_LL;
} }
} }
...@@ -2531,7 +2532,7 @@ bfa_ioc_send_fwsync(struct bfa_ioc_s *ioc) ...@@ -2531,7 +2532,7 @@ bfa_ioc_send_fwsync(struct bfa_ioc_s *ioc)
bfi_h2i_set(req->mh, BFI_MC_IOC, BFI_IOC_H2I_DBG_SYNC, bfi_h2i_set(req->mh, BFI_MC_IOC, BFI_IOC_H2I_DBG_SYNC,
bfa_ioc_portid(ioc)); bfa_ioc_portid(ioc));
req->ioc_class = ioc->ioc_mc; req->clscode = cpu_to_be16(ioc->clscode);
bfa_ioc_mbox_queue(ioc, &cmd); bfa_ioc_mbox_queue(ioc, &cmd);
} }
......
...@@ -197,18 +197,26 @@ struct bfa_ioc_cbfn_s { ...@@ -197,18 +197,26 @@ struct bfa_ioc_cbfn_s {
}; };
/* /*
* Heartbeat failure notification queue element. * IOC event notification mechanism.
*/ */
struct bfa_ioc_hbfail_notify_s { enum bfa_ioc_event_e {
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_e);
struct bfa_ioc_notify_s {
struct list_head qe; struct list_head qe;
bfa_ioc_hbfail_cbfn_t cbfn; bfa_ioc_notify_cbfn_t cbfn;
void *cbarg; void *cbarg;
}; };
/* /*
* Initialize a heartbeat failure notification structure * Initialize a IOC event 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)
...@@ -229,11 +237,11 @@ struct bfa_ioc_s { ...@@ -229,11 +237,11 @@ struct bfa_ioc_s {
struct bfa_timer_s sem_timer; struct bfa_timer_s sem_timer;
struct bfa_timer_s hb_timer; struct bfa_timer_s 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;
bfa_boolean_t dbg_fwsave_once; bfa_boolean_t dbg_fwsave_once;
enum bfi_mclass ioc_mc; enum bfi_pcifn_class clscode;
struct bfa_ioc_regs_s ioc_regs; struct bfa_ioc_regs_s ioc_regs;
struct bfa_trc_mod_s *trcmod; struct bfa_trc_mod_s *trcmod;
struct bfa_ioc_drv_stats_s stats; struct bfa_ioc_drv_stats_s stats;
...@@ -334,7 +342,7 @@ void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, ...@@ -334,7 +342,7 @@ void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa,
void bfa_ioc_auto_recover(bfa_boolean_t auto_recover); void bfa_ioc_auto_recover(bfa_boolean_t auto_recover);
void bfa_ioc_detach(struct bfa_ioc_s *ioc); void bfa_ioc_detach(struct bfa_ioc_s *ioc);
void bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev, void bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
enum bfi_mclass mc); enum bfi_pcifn_class clscode);
void bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa); void bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa);
void bfa_ioc_enable(struct bfa_ioc_s *ioc); void bfa_ioc_enable(struct bfa_ioc_s *ioc);
void bfa_ioc_disable(struct bfa_ioc_s *ioc); void bfa_ioc_disable(struct bfa_ioc_s *ioc);
......
...@@ -387,32 +387,43 @@ bfa_port_clear_stats(struct bfa_port_s *port, bfa_port_stats_cbfn_t cbfn, ...@@ -387,32 +387,43 @@ bfa_port_clear_stats(struct bfa_port_s *port, bfa_port_stats_cbfn_t cbfn,
} }
/* /*
* bfa_port_hbfail() * bfa_port_notify()
* *
* Port module IOC event handler
* *
* @param[in] Pointer to the Port module data structure. * @param[in] Pointer to the Port module data structure.
* @param[in] IOC event structure
* *
* @return void * @return void
*/ */
void void
bfa_port_hbfail(void *arg) bfa_port_notify(void *arg, enum bfa_ioc_event_e event)
{ {
struct bfa_port_s *port = (struct bfa_port_s *) arg; struct bfa_port_s *port = (struct bfa_port_s *) arg;
/* Fail any pending get_stats/clear_stats requests */ switch (event) {
if (port->stats_busy) { case BFA_IOC_E_DISABLED:
if (port->stats_cbfn) case BFA_IOC_E_FAILED:
port->stats_cbfn(port->stats_cbarg, BFA_STATUS_FAILED); /* Fail any pending get_stats/clear_stats requests */
port->stats_cbfn = NULL; if (port->stats_busy) {
port->stats_busy = BFA_FALSE; if (port->stats_cbfn)
} port->stats_cbfn(port->stats_cbarg,
BFA_STATUS_FAILED);
/* Clear any enable/disable is pending */ port->stats_cbfn = NULL;
if (port->endis_pending) { port->stats_busy = BFA_FALSE;
if (port->endis_cbfn) }
port->endis_cbfn(port->endis_cbarg, BFA_STATUS_FAILED);
port->endis_cbfn = NULL; /* Clear any enable/disable is pending */
port->endis_pending = BFA_FALSE; if (port->endis_pending) {
if (port->endis_cbfn)
port->endis_cbfn(port->endis_cbarg,
BFA_STATUS_FAILED);
port->endis_cbfn = NULL;
port->endis_pending = BFA_FALSE;
}
break;
default:
break;
} }
} }
...@@ -447,8 +458,8 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, ...@@ -447,8 +458,8 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
port->endis_cbfn = NULL; port->endis_cbfn = NULL;
bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port); bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port);
bfa_ioc_hbfail_init(&port->hbfail, bfa_port_hbfail, port); bfa_ioc_notify_init(&port->ioc_notify, bfa_port_notify, port);
list_add_tail(&port->hbfail.qe, &port->ioc->hb_notify_q); list_add_tail(&port->ioc_notify.qe, &port->ioc->notify_q);
/* /*
* initialize time stamp for stats reset * initialize time stamp for stats reset
......
...@@ -43,12 +43,12 @@ struct bfa_port_s { ...@@ -43,12 +43,12 @@ struct bfa_port_s {
bfa_port_endis_cbfn_t endis_cbfn; bfa_port_endis_cbfn_t endis_cbfn;
void *endis_cbarg; void *endis_cbarg;
bfa_status_t endis_status; bfa_status_t endis_status;
struct bfa_ioc_hbfail_notify_s hbfail; struct bfa_ioc_notify_s ioc_notify;
}; };
void bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, void bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
void *dev, struct bfa_trc_mod_s *trcmod); void *dev, struct bfa_trc_mod_s *trcmod);
void bfa_port_hbfail(void *arg); void bfa_port_notify(void *arg, enum bfa_ioc_event_e event);
bfa_status_t bfa_port_get_stats(struct bfa_port_s *port, bfa_status_t bfa_port_get_stats(struct bfa_port_s *port,
union bfa_port_stats_u *stats, union bfa_port_stats_u *stats,
......
...@@ -43,13 +43,15 @@ struct bfi_mhdr_s { ...@@ -43,13 +43,15 @@ struct bfi_mhdr_s {
u8 msg_id; /* msg opcode with in the class */ u8 msg_id; /* msg opcode with in the class */
union { union {
struct { struct {
u8 rsvd; u8 qid;
u8 lpu_id; /* msg destination */ u8 lpu_id; /* msg destination */
} h2i; } h2i;
u16 i2htok; /* token in msgs to host */ u16 i2htok; /* token in msgs to host */
} mtag; } mtag;
}; };
#define bfi_mhdr_2_qid(_mh) (_mh)->mtag.h2i.qid
#define bfi_h2i_set(_mh, _mc, _op, _lpuid) do { \ #define bfi_h2i_set(_mh, _mc, _op, _lpuid) do { \
(_mh).msg_class = (_mc); \ (_mh).msg_class = (_mc); \
(_mh).msg_id = (_op); \ (_mh).msg_id = (_op); \
...@@ -156,6 +158,14 @@ struct bfi_mbmsg_s { ...@@ -156,6 +158,14 @@ struct bfi_mbmsg_s {
u32 pl[BFI_MBMSG_SZ]; u32 pl[BFI_MBMSG_SZ];
}; };
/*
* Supported PCI function class codes (personality)
*/
enum bfi_pcifn_class {
BFI_PCIFN_CLASS_FC = 0x0c04,
BFI_PCIFN_CLASS_ETH = 0x0200,
};
/* /*
* Message Classes * Message Classes
*/ */
...@@ -353,8 +363,8 @@ enum { ...@@ -353,8 +363,8 @@ enum {
*/ */
struct bfi_ioc_ctrl_req_s { struct bfi_ioc_ctrl_req_s {
struct bfi_mhdr_s mh; struct bfi_mhdr_s mh;
u8 ioc_class; u16 clscode;
u8 rsvd[3]; u16 rsvd;
u32 tv_sec; u32 tv_sec;
}; };
#define bfi_ioc_enable_req_t struct bfi_ioc_ctrl_req_s; #define bfi_ioc_enable_req_t struct bfi_ioc_ctrl_req_s;
......
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