]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/scsi/bfa/bfa_svc.c
[SCSI] bfa: direct attach mode fix.
[karo-tx-linux.git] / drivers / scsi / bfa / bfa_svc.c
index c9192869c0fe0fa0bcca108477429450b207e174..b7df5534da857834edf300d282399603fcf24f89 100644 (file)
  * General Public License for more details.
  */
 
-#include "bfa_os_inc.h"
+#include "bfad_drv.h"
 #include "bfa_plog.h"
 #include "bfa_cs.h"
 #include "bfa_modules.h"
-#include "bfad_drv.h"
 
 BFA_TRC_FILE(HAL, FCXP);
 BFA_MODULE(fcxp);
@@ -53,7 +52,6 @@ BFA_MODULE(uf);
        ((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \
        (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
 
-
 /*
  * BFA port state machine events
  */
@@ -133,6 +131,7 @@ static void bfa_lps_reqq_resume(void *lps_arg);
 static void bfa_lps_free(struct bfa_lps_s *lps);
 static void bfa_lps_send_login(struct bfa_lps_s *lps);
 static void bfa_lps_send_logout(struct bfa_lps_s *lps);
+static void bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps);
 static void bfa_lps_login_comp(struct bfa_lps_s *lps);
 static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
 static void bfa_lps_cvl_event(struct bfa_lps_s *lps);
@@ -145,6 +144,8 @@ static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event);
 static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event
                                        event);
 static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event);
+static void bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps,
+                                       enum bfa_lps_event event);
 static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event);
 static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event
                                        event);
@@ -286,6 +287,18 @@ plkd_validate_logrec(struct bfa_plog_rec_s *pl_rec)
        return 0;
 }
 
+static u64
+bfa_get_log_time(void)
+{
+       u64 system_time = 0;
+       struct timeval tv;
+       do_gettimeofday(&tv);
+
+       /* We are interested in seconds only. */
+       system_time = tv.tv_sec;
+       return system_time;
+}
+
 static void
 bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec)
 {
@@ -306,7 +319,7 @@ bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec)
 
        memcpy(pl_recp, pl_rec, sizeof(struct bfa_plog_rec_s));
 
-       pl_recp->tv = bfa_os_get_log_time();
+       pl_recp->tv = bfa_get_log_time();
        BFA_PL_LOG_REC_INCR(plog->tail);
 
        if (plog->head == plog->tail)
@@ -905,10 +918,6 @@ bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
        bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP));
 }
 
-/*
- *  hal_fcxp_api BFA FCXP API
- */
-
 /*
  * Allocate an FCXP instance to send a response or to send a request
  * that has a response. Request/response buffers are allocated by caller.
@@ -1003,7 +1012,7 @@ bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
 }
 
 /*
- *             Free the BFA FCXP
+ * Free the BFA FCXP
  *
  * @param[in]  fcxp                    BFA fcxp pointer
  *
@@ -1150,12 +1159,6 @@ bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
        fcxp->send_cbfn = bfa_fcxp_null_comp;
 }
 
-
-
-/*
- *  hal_fcxp_public BFA FCXP public functions
- */
-
 void
 bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
 {
@@ -1254,6 +1257,12 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
                        else
                                bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
                                        BFA_PL_EID_LOGIN, 0, "FLOGI Accept");
+                       /* If N2N, send the assigned PID to FW */
+                       bfa_trc(lps->bfa, lps->fport);
+                       bfa_trc(lps->bfa, lps->lp_pid);
+
+                       if (!lps->fport && lps->lp_pid)
+                               bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID);
                } else {
                        bfa_sm_set_state(lps, bfa_lps_sm_init);
                        if (lps->fdisc)
@@ -1272,6 +1281,11 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
                bfa_sm_set_state(lps, bfa_lps_sm_init);
                break;
 
+       case BFA_LPS_SM_SET_N2N_PID:
+               bfa_trc(lps->bfa, lps->fport);
+               bfa_trc(lps->bfa, lps->lp_pid);
+               break;
+
        default:
                bfa_sm_fault(lps->bfa, event);
        }
@@ -1340,6 +1354,14 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
                        BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
                break;
 
+       case BFA_LPS_SM_SET_N2N_PID:
+               if (bfa_reqq_full(lps->bfa, lps->reqq)) {
+                       bfa_sm_set_state(lps, bfa_lps_sm_online_n2n_pid_wait);
+                       bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
+               } else
+                       bfa_lps_send_set_n2n_pid(lps);
+               break;
+
        case BFA_LPS_SM_OFFLINE:
        case BFA_LPS_SM_DELETE:
                bfa_sm_set_state(lps, bfa_lps_sm_init);
@@ -1350,6 +1372,48 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
        }
 }
 
+/**
+ * login complete
+ */
+static void
+bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, enum bfa_lps_event event)
+{
+       bfa_trc(lps->bfa, lps->lp_tag);
+       bfa_trc(lps->bfa, event);
+
+       switch (event) {
+       case BFA_LPS_SM_RESUME:
+               bfa_sm_set_state(lps, bfa_lps_sm_online);
+               bfa_lps_send_set_n2n_pid(lps);
+               break;
+
+       case BFA_LPS_SM_LOGOUT:
+               bfa_sm_set_state(lps, bfa_lps_sm_logowait);
+               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                       BFA_PL_EID_LOGO, 0, "Logout");
+               break;
+
+       case BFA_LPS_SM_RX_CVL:
+               bfa_sm_set_state(lps, bfa_lps_sm_init);
+               bfa_reqq_wcancel(&lps->wqe);
+
+               /* Let the vport module know about this event */
+               bfa_lps_cvl_event(lps);
+               bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
+                       BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
+               break;
+
+       case BFA_LPS_SM_OFFLINE:
+       case BFA_LPS_SM_DELETE:
+               bfa_sm_set_state(lps, bfa_lps_sm_init);
+               bfa_reqq_wcancel(&lps->wqe);
+               break;
+
+       default:
+               bfa_sm_fault(lps->bfa, event);
+       }
+}
+
 /*
  * logout in progress - awaiting firmware response
  */
@@ -1498,8 +1562,9 @@ bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp)
        switch (rsp->status) {
        case BFA_STATUS_OK:
                lps->fport      = rsp->f_port;
+               if (lps->fport)
+                       lps->lp_pid = rsp->lp_pid;
                lps->npiv_en    = rsp->npiv_en;
-               lps->lp_pid     = rsp->lp_pid;
                lps->pr_bbcred  = be16_to_cpu(rsp->bb_credit);
                lps->pr_pwwn    = rsp->port_name;
                lps->pr_nwwn    = rsp->node_name;
@@ -1626,6 +1691,25 @@ bfa_lps_send_logout(struct bfa_lps_s *lps)
        bfa_reqq_produce(lps->bfa, lps->reqq);
 }
 
+/**
+ * send n2n pid set request to firmware
+ */
+static void
+bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps)
+{
+       struct bfi_lps_n2n_pid_req_s *m;
+
+       m = bfa_reqq_next(lps->bfa, lps->reqq);
+       bfa_assert(m);
+
+       bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_N2N_PID_REQ,
+               bfa_lpuid(lps->bfa));
+
+       m->lp_tag = lps->lp_tag;
+       m->lp_pid = lps->lp_pid;
+       bfa_reqq_produce(lps->bfa, lps->reqq);
+}
+
 /*
  * Indirect login completion handler for non-fcs
  */
@@ -1846,6 +1930,19 @@ bfa_lps_get_base_pid(struct bfa_s *bfa)
        return BFA_LPS_FROM_TAG(mod, 0)->lp_pid;
 }
 
+/**
+ * Set PID in case of n2n (which is assigned during PLOGI)
+ */
+void
+bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, uint32_t n2n_pid)
+{
+       bfa_trc(lps->bfa, lps->lp_tag);
+       bfa_trc(lps->bfa, n2n_pid);
+
+       lps->lp_pid = n2n_pid;
+       bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID);
+}
+
 /*
  * LPS firmware message class handler.
  */
@@ -1890,6 +1987,8 @@ bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
                /*
                 * Start event after IOC is configured and BFA is started.
                 */
+               fcport->use_flash_cfg = BFA_TRUE;
+
                if (bfa_fcport_send_enable(fcport)) {
                        bfa_trc(fcport->bfa, BFA_TRUE);
                        bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
@@ -2625,12 +2724,6 @@ bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
        }
 }
 
-
-
-/*
- *  hal_port_private
- */
-
 static void
 __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
 {
@@ -2728,7 +2821,7 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
        struct bfa_port_cfg_s *port_cfg = &fcport->cfg;
        struct bfa_fcport_ln_s *ln = &fcport->ln;
-       struct bfa_timeval_s tv;
+       struct timeval tv;
 
        memset(fcport, 0, sizeof(struct bfa_fcport_s));
        fcport->bfa = bfa;
@@ -2742,7 +2835,7 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
        /*
         * initialize time stamp for stats reset
         */
-       bfa_os_gettimeofday(&tv);
+       do_gettimeofday(&tv);
        fcport->stats_reset_time = tv.tv_sec;
 
        /*
@@ -2861,6 +2954,7 @@ bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
        m->port_cfg = fcport->cfg;
        m->msgtag = fcport->msgtag;
        m->port_cfg.maxfrsize = cpu_to_be16(fcport->cfg.maxfrsize);
+        m->use_flash_cfg = fcport->use_flash_cfg;
        bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa);
        bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo);
        bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi);
@@ -2967,7 +3061,7 @@ bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
 
        for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
             i = i + 2) {
-#ifdef __BIGENDIAN
+#ifdef __BIG_ENDIAN
                dip[i] = be32_to_cpu(sip[i]);
                dip[i + 1] = be32_to_cpu(sip[i + 1]);
 #else
@@ -2984,7 +3078,7 @@ __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
 
        if (complete) {
                if (fcport->stats_status == BFA_STATUS_OK) {
-                       struct bfa_timeval_s tv;
+                       struct timeval tv;
 
                        /* Swap FC QoS or FCoE stats */
                        if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
@@ -2996,7 +3090,7 @@ __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
                                        &fcport->stats_ret->fcoe,
                                        &fcport->stats->fcoe);
 
-                               bfa_os_gettimeofday(&tv);
+                               do_gettimeofday(&tv);
                                fcport->stats_ret->fcoe.secs_reset =
                                        tv.tv_sec - fcport->stats_reset_time;
                        }
@@ -3055,12 +3149,12 @@ __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
        struct bfa_fcport_s *fcport = cbarg;
 
        if (complete) {
-               struct bfa_timeval_s tv;
+               struct timeval tv;
 
                /*
                 * re-initialize time stamp for stats reset
                 */
-               bfa_os_gettimeofday(&tv);
+               do_gettimeofday(&tv);
                fcport->stats_reset_time = tv.tv_sec;
 
                fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
@@ -3218,12 +3312,6 @@ bfa_trunk_iocdisable(struct bfa_s *bfa)
        }
 }
 
-
-
-/*
- *  hal_port_public
- */
-
 /*
  * Called to initialize port attributes
  */
@@ -3263,8 +3351,28 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
 
        switch (msg->mhdr.msg_id) {
        case BFI_FCPORT_I2H_ENABLE_RSP:
-               if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
+               if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) {
+
+                       if (fcport->use_flash_cfg) {
+                               fcport->cfg = i2hmsg.penable_rsp->port_cfg;
+                               fcport->cfg.maxfrsize =
+                                       cpu_to_be16(fcport->cfg.maxfrsize);
+                               fcport->cfg.path_tov =
+                                       cpu_to_be16(fcport->cfg.path_tov);
+                               fcport->cfg.q_depth =
+                                       cpu_to_be16(fcport->cfg.q_depth);
+
+                               if (fcport->cfg.trunked)
+                                       fcport->trunk.attr.state =
+                                               BFA_TRUNK_OFFLINE;
+                               else
+                                       fcport->trunk.attr.state =
+                                               BFA_TRUNK_DISABLED;
+                               fcport->use_flash_cfg = BFA_FALSE;
+                       }
+
                        bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
+               }
                break;
 
        case BFI_FCPORT_I2H_DISABLE_RSP:
@@ -3325,12 +3433,6 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
        }
 }
 
-
-
-/*
- *  hal_port_api
- */
-
 /*
  * Registered callback for port events.
  */
@@ -3663,7 +3765,6 @@ bfa_fcport_is_ratelim(struct bfa_s *bfa)
 
 }
 
-
 /*
  * Get default minimum ratelim speed
  */
@@ -4562,12 +4663,6 @@ bfa_sgpg_iocdisable(struct bfa_s *bfa)
 {
 }
 
-
-
-/*
- *  hal_sgpg_public BFA SGPG public functions
- */
-
 bfa_status_t
 bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpgs)
 {
@@ -4930,10 +5025,6 @@ bfa_uf_start(struct bfa_s *bfa)
        bfa_uf_post_all(BFA_UF_MOD(bfa));
 }
 
-/*
- *  hal_uf_api
- */
-
 /*
  * Register handler for all unsolicted recieve frames.
  *