bna: IOC Event Notification Enhancement
authorRasesh Mody <rmody@brocade.com>
Fri, 22 Jul 2011 08:07:42 +0000 (08:07 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sat, 23 Jul 2011 00:01:13 +0000 (17:01 -0700)
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>
drivers/net/bna/bfa_cee.c
drivers/net/bna/bfa_cee.h
drivers/net/bna/bfa_ioc.c
drivers/net/bna/bfa_ioc.h

index dcfbf08bcf433b342d041cb60fa4b7fae50e249c..39e5ab9fde5981429e58ecccc5dce636fdde3953 100644 (file)
@@ -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);
 }
index 20543d15b64f5f49facb00f8114030130d634519..58d54e98d595d72d7b7b99379d1cfeb3ba9d6b37 100644 (file)
@@ -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;
index 04bfb29bdc933ed638af3fbfe0c1fa0b4c6c5ea3..c52ef6347dc65c2bf4944d988030139b33d76697 100644 (file)
@@ -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,23 +1124,28 @@ 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
 bfa_nw_ioc_sem_get(void __iomem *sem_reg)
 {
@@ -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"
index 8473c00b94278001caeb65f30358cad1dc3e4018..c6cf218d9f816f750823949408a3d5106fb54f16 100644 (file)
@@ -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);