linux/drivers/scsi/bfa/bfa_fcpim.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
   3 * All rights reserved
   4 * www.brocade.com
   5 *
   6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
   7 *
   8 * This program is free software; you can redistribute it and/or modify it
   9 * under the terms of the GNU General Public License (GPL) Version 2 as
  10 * published by the Free Software Foundation
  11 *
  12 * This program is distributed in the hope that it will be useful, but
  13 * WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15 * General Public License for more details.
  16 */
  17
  18#include "bfad_drv.h"
  19#include "bfa_modules.h"
  20
  21BFA_TRC_FILE(HAL, FCPIM);
  22
  23/*
  24 *  BFA ITNIM Related definitions
  25 */
  26static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
  27static void bfa_ioim_lm_init(struct bfa_s *bfa);
  28
  29#define BFA_ITNIM_FROM_TAG(_fcpim, _tag)                                \
  30        (((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1))))
  31
  32#define bfa_fcpim_additn(__itnim)                                       \
  33        list_add_tail(&(__itnim)->qe, &(__itnim)->fcpim->itnim_q)
  34#define bfa_fcpim_delitn(__itnim)       do {                            \
  35        WARN_ON(!bfa_q_is_on_q(&(__itnim)->fcpim->itnim_q, __itnim));   \
  36        bfa_itnim_update_del_itn_stats(__itnim);      \
  37        list_del(&(__itnim)->qe);      \
  38        WARN_ON(!list_empty(&(__itnim)->io_q));                         \
  39        WARN_ON(!list_empty(&(__itnim)->io_cleanup_q));                 \
  40        WARN_ON(!list_empty(&(__itnim)->pending_q));                    \
  41} while (0)
  42
  43#define bfa_itnim_online_cb(__itnim) do {                               \
  44        if ((__itnim)->bfa->fcs)                                        \
  45                bfa_cb_itnim_online((__itnim)->ditn);      \
  46        else {                                                          \
  47                bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe,        \
  48                __bfa_cb_itnim_online, (__itnim));      \
  49        }                                                               \
  50} while (0)
  51
  52#define bfa_itnim_offline_cb(__itnim) do {                              \
  53        if ((__itnim)->bfa->fcs)                                        \
  54                bfa_cb_itnim_offline((__itnim)->ditn);      \
  55        else {                                                          \
  56                bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe,        \
  57                __bfa_cb_itnim_offline, (__itnim));      \
  58        }                                                               \
  59} while (0)
  60
  61#define bfa_itnim_sler_cb(__itnim) do {                                 \
  62        if ((__itnim)->bfa->fcs)                                        \
  63                bfa_cb_itnim_sler((__itnim)->ditn);      \
  64        else {                                                          \
  65                bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe,        \
  66                __bfa_cb_itnim_sler, (__itnim));      \
  67        }                                                               \
  68} while (0)
  69
  70enum bfa_ioim_lm_ua_status {
  71        BFA_IOIM_LM_UA_RESET = 0,
  72        BFA_IOIM_LM_UA_SET = 1,
  73};
  74
  75/*
  76 *  itnim state machine event
  77 */
  78enum bfa_itnim_event {
  79        BFA_ITNIM_SM_CREATE = 1,        /*  itnim is created */
  80        BFA_ITNIM_SM_ONLINE = 2,        /*  itnim is online */
  81        BFA_ITNIM_SM_OFFLINE = 3,       /*  itnim is offline */
  82        BFA_ITNIM_SM_FWRSP = 4,         /*  firmware response */
  83        BFA_ITNIM_SM_DELETE = 5,        /*  deleting an existing itnim */
  84        BFA_ITNIM_SM_CLEANUP = 6,       /*  IO cleanup completion */
  85        BFA_ITNIM_SM_SLER = 7,          /*  second level error recovery */
  86        BFA_ITNIM_SM_HWFAIL = 8,        /*  IOC h/w failure event */
  87        BFA_ITNIM_SM_QRESUME = 9,       /*  queue space available */
  88};
  89
  90/*
  91 *  BFA IOIM related definitions
  92 */
  93#define bfa_ioim_move_to_comp_q(__ioim) do {                            \
  94        list_del(&(__ioim)->qe);                                        \
  95        list_add_tail(&(__ioim)->qe, &(__ioim)->fcpim->ioim_comp_q);    \
  96} while (0)
  97
  98
  99#define bfa_ioim_cb_profile_comp(__fcpim, __ioim) do {                  \
 100        if ((__fcpim)->profile_comp)                                    \
 101                (__fcpim)->profile_comp(__ioim);                        \
 102} while (0)
 103
 104#define bfa_ioim_cb_profile_start(__fcpim, __ioim) do {                 \
 105        if ((__fcpim)->profile_start)                                   \
 106                (__fcpim)->profile_start(__ioim);                       \
 107} while (0)
 108
 109/*
 110 * IO state machine events
 111 */
 112enum bfa_ioim_event {
 113        BFA_IOIM_SM_START       = 1,    /*  io start request from host */
 114        BFA_IOIM_SM_COMP_GOOD   = 2,    /*  io good comp, resource free */
 115        BFA_IOIM_SM_COMP        = 3,    /*  io comp, resource is free */
 116        BFA_IOIM_SM_COMP_UTAG   = 4,    /*  io comp, resource is free */
 117        BFA_IOIM_SM_DONE        = 5,    /*  io comp, resource not free */
 118        BFA_IOIM_SM_FREE        = 6,    /*  io resource is freed */
 119        BFA_IOIM_SM_ABORT       = 7,    /*  abort request from scsi stack */
 120        BFA_IOIM_SM_ABORT_COMP  = 8,    /*  abort from f/w */
 121        BFA_IOIM_SM_ABORT_DONE  = 9,    /*  abort completion from f/w */
 122        BFA_IOIM_SM_QRESUME     = 10,   /*  CQ space available to queue IO */
 123        BFA_IOIM_SM_SGALLOCED   = 11,   /*  SG page allocation successful */
 124        BFA_IOIM_SM_SQRETRY     = 12,   /*  sequence recovery retry */
 125        BFA_IOIM_SM_HCB         = 13,   /*  bfa callback complete */
 126        BFA_IOIM_SM_CLEANUP     = 14,   /*  IO cleanup from itnim */
 127        BFA_IOIM_SM_TMSTART     = 15,   /*  IO cleanup from tskim */
 128        BFA_IOIM_SM_TMDONE      = 16,   /*  IO cleanup from tskim */
 129        BFA_IOIM_SM_HWFAIL      = 17,   /*  IOC h/w failure event */
 130        BFA_IOIM_SM_IOTOV       = 18,   /*  ITN offline TOV */
 131};
 132
 133
 134/*
 135 *  BFA TSKIM related definitions
 136 */
 137
 138/*
 139 * task management completion handling
 140 */
 141#define bfa_tskim_qcomp(__tskim, __cbfn) do {                           \
 142        bfa_cb_queue((__tskim)->bfa, &(__tskim)->hcb_qe, __cbfn, (__tskim));\
 143        bfa_tskim_notify_comp(__tskim);      \
 144} while (0)
 145
 146#define bfa_tskim_notify_comp(__tskim) do {                             \
 147        if ((__tskim)->notify)                                          \
 148                bfa_itnim_tskdone((__tskim)->itnim);      \
 149} while (0)
 150
 151
 152enum bfa_tskim_event {
 153        BFA_TSKIM_SM_START      = 1,    /*  TM command start            */
 154        BFA_TSKIM_SM_DONE       = 2,    /*  TM completion               */
 155        BFA_TSKIM_SM_QRESUME    = 3,    /*  resume after qfull          */
 156        BFA_TSKIM_SM_HWFAIL     = 5,    /*  IOC h/w failure event       */
 157        BFA_TSKIM_SM_HCB        = 6,    /*  BFA callback completion     */
 158        BFA_TSKIM_SM_IOS_DONE   = 7,    /*  IO and sub TM completions   */
 159        BFA_TSKIM_SM_CLEANUP    = 8,    /*  TM cleanup on ITN offline   */
 160        BFA_TSKIM_SM_CLEANUP_DONE = 9,  /*  TM abort completion */
 161        BFA_TSKIM_SM_UTAG       = 10,   /*  TM completion unknown tag  */
 162};
 163
 164/*
 165 * forward declaration for BFA ITNIM functions
 166 */
 167static void     bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim);
 168static bfa_boolean_t bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim);
 169static bfa_boolean_t bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim);
 170static void     bfa_itnim_cleanp_comp(void *itnim_cbarg);
 171static void     bfa_itnim_cleanup(struct bfa_itnim_s *itnim);
 172static void     __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete);
 173static void     __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete);
 174static void     __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete);
 175static void     bfa_itnim_iotov_online(struct bfa_itnim_s *itnim);
 176static void     bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim);
 177static void     bfa_itnim_iotov(void *itnim_arg);
 178static void     bfa_itnim_iotov_start(struct bfa_itnim_s *itnim);
 179static void     bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim);
 180static void     bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim);
 181
 182/*
 183 * forward declaration of ITNIM state machine
 184 */
 185static void     bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim,
 186                                        enum bfa_itnim_event event);
 187static void     bfa_itnim_sm_created(struct bfa_itnim_s *itnim,
 188                                        enum bfa_itnim_event event);
 189static void     bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim,
 190                                        enum bfa_itnim_event event);
 191static void     bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
 192                                        enum bfa_itnim_event event);
 193static void     bfa_itnim_sm_online(struct bfa_itnim_s *itnim,
 194                                        enum bfa_itnim_event event);
 195static void     bfa_itnim_sm_sler(struct bfa_itnim_s *itnim,
 196                                        enum bfa_itnim_event event);
 197static void     bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
 198                                        enum bfa_itnim_event event);
 199static void     bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
 200                                        enum bfa_itnim_event event);
 201static void     bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim,
 202                                        enum bfa_itnim_event event);
 203static void     bfa_itnim_sm_offline(struct bfa_itnim_s *itnim,
 204                                        enum bfa_itnim_event event);
 205static void     bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
 206                                        enum bfa_itnim_event event);
 207static void     bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim,
 208                                        enum bfa_itnim_event event);
 209static void     bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
 210                                        enum bfa_itnim_event event);
 211static void     bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
 212                                        enum bfa_itnim_event event);
 213static void     bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
 214                                        enum bfa_itnim_event event);
 215
 216/*
 217 * forward declaration for BFA IOIM functions
 218 */
 219static bfa_boolean_t    bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim);
 220static bfa_boolean_t    bfa_ioim_sgpg_alloc(struct bfa_ioim_s *ioim);
 221static bfa_boolean_t    bfa_ioim_send_abort(struct bfa_ioim_s *ioim);
 222static void             bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim);
 223static void __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete);
 224static void __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete);
 225static void __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete);
 226static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete);
 227static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete);
 228static bfa_boolean_t    bfa_ioim_is_abortable(struct bfa_ioim_s *ioim);
 229
 230/*
 231 * forward declaration of BFA IO state machine
 232 */
 233static void     bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim,
 234                                        enum bfa_ioim_event event);
 235static void     bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim,
 236                                        enum bfa_ioim_event event);
 237static void     bfa_ioim_sm_active(struct bfa_ioim_s *ioim,
 238                                        enum bfa_ioim_event event);
 239static void     bfa_ioim_sm_abort(struct bfa_ioim_s *ioim,
 240                                        enum bfa_ioim_event event);
 241static void     bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim,
 242                                        enum bfa_ioim_event event);
 243static void     bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim,
 244                                        enum bfa_ioim_event event);
 245static void     bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim,
 246                                        enum bfa_ioim_event event);
 247static void     bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim,
 248                                        enum bfa_ioim_event event);
 249static void     bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim,
 250                                        enum bfa_ioim_event event);
 251static void     bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim,
 252                                        enum bfa_ioim_event event);
 253static void     bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim,
 254                                        enum bfa_ioim_event event);
 255static void     bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim,
 256                                        enum bfa_ioim_event event);
 257/*
 258 * forward declaration for BFA TSKIM functions
 259 */
 260static void     __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete);
 261static void     __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete);
 262static bfa_boolean_t bfa_tskim_match_scope(struct bfa_tskim_s *tskim,
 263                                        struct scsi_lun lun);
 264static void     bfa_tskim_gather_ios(struct bfa_tskim_s *tskim);
 265static void     bfa_tskim_cleanp_comp(void *tskim_cbarg);
 266static void     bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim);
 267static bfa_boolean_t bfa_tskim_send(struct bfa_tskim_s *tskim);
 268static bfa_boolean_t bfa_tskim_send_abort(struct bfa_tskim_s *tskim);
 269static void     bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim);
 270
 271/*
 272 * forward declaration of BFA TSKIM state machine
 273 */
 274static void     bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim,
 275                                        enum bfa_tskim_event event);
 276static void     bfa_tskim_sm_active(struct bfa_tskim_s *tskim,
 277                                        enum bfa_tskim_event event);
 278static void     bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim,
 279                                        enum bfa_tskim_event event);
 280static void     bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim,
 281                                        enum bfa_tskim_event event);
 282static void     bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim,
 283                                        enum bfa_tskim_event event);
 284static void     bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
 285                                        enum bfa_tskim_event event);
 286static void     bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim,
 287                                        enum bfa_tskim_event event);
 288/*
 289 *  BFA FCP Initiator Mode module
 290 */
 291
 292/*
 293 * Compute and return memory needed by FCP(im) module.
 294 */
 295static void
 296bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len)
 297{
 298        bfa_itnim_meminfo(cfg, km_len);
 299
 300        /*
 301         * IO memory
 302         */
 303        *km_len += cfg->fwcfg.num_ioim_reqs *
 304          (sizeof(struct bfa_ioim_s) + sizeof(struct bfa_ioim_sp_s));
 305
 306        /*
 307         * task management command memory
 308         */
 309        if (cfg->fwcfg.num_tskim_reqs < BFA_TSKIM_MIN)
 310                cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN;
 311        *km_len += cfg->fwcfg.num_tskim_reqs * sizeof(struct bfa_tskim_s);
 312}
 313
 314
 315static void
 316bfa_fcpim_attach(struct bfa_fcp_mod_s *fcp, void *bfad,
 317                struct bfa_iocfc_cfg_s *cfg, struct bfa_pcidev_s *pcidev)
 318{
 319        struct bfa_fcpim_s *fcpim = &fcp->fcpim;
 320        struct bfa_s *bfa = fcp->bfa;
 321
 322        bfa_trc(bfa, cfg->drvcfg.path_tov);
 323        bfa_trc(bfa, cfg->fwcfg.num_rports);
 324        bfa_trc(bfa, cfg->fwcfg.num_ioim_reqs);
 325        bfa_trc(bfa, cfg->fwcfg.num_tskim_reqs);
 326
 327        fcpim->fcp              = fcp;
 328        fcpim->bfa              = bfa;
 329        fcpim->num_itnims       = cfg->fwcfg.num_rports;
 330        fcpim->num_tskim_reqs = cfg->fwcfg.num_tskim_reqs;
 331        fcpim->path_tov         = cfg->drvcfg.path_tov;
 332        fcpim->delay_comp       = cfg->drvcfg.delay_comp;
 333        fcpim->profile_comp = NULL;
 334        fcpim->profile_start = NULL;
 335
 336        bfa_itnim_attach(fcpim);
 337        bfa_tskim_attach(fcpim);
 338        bfa_ioim_attach(fcpim);
 339}
 340
 341static void
 342bfa_fcpim_iocdisable(struct bfa_fcp_mod_s *fcp)
 343{
 344        struct bfa_fcpim_s *fcpim = &fcp->fcpim;
 345        struct bfa_itnim_s *itnim;
 346        struct list_head *qe, *qen;
 347
 348        /* Enqueue unused ioim resources to free_q */
 349        list_splice_tail_init(&fcpim->tskim_unused_q, &fcpim->tskim_free_q);
 350
 351        list_for_each_safe(qe, qen, &fcpim->itnim_q) {
 352                itnim = (struct bfa_itnim_s *) qe;
 353                bfa_itnim_iocdisable(itnim);
 354        }
 355}
 356
 357void
 358bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov)
 359{
 360        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
 361
 362        fcpim->path_tov = path_tov * 1000;
 363        if (fcpim->path_tov > BFA_FCPIM_PATHTOV_MAX)
 364                fcpim->path_tov = BFA_FCPIM_PATHTOV_MAX;
 365}
 366
 367u16
 368bfa_fcpim_path_tov_get(struct bfa_s *bfa)
 369{
 370        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
 371
 372        return fcpim->path_tov / 1000;
 373}
 374
 375#define bfa_fcpim_add_iostats(__l, __r, __stats)        \
 376        (__l->__stats += __r->__stats)
 377
 378void
 379bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *lstats,
 380                struct bfa_itnim_iostats_s *rstats)
 381{
 382        bfa_fcpim_add_iostats(lstats, rstats, total_ios);
 383        bfa_fcpim_add_iostats(lstats, rstats, qresumes);
 384        bfa_fcpim_add_iostats(lstats, rstats, no_iotags);
 385        bfa_fcpim_add_iostats(lstats, rstats, io_aborts);
 386        bfa_fcpim_add_iostats(lstats, rstats, no_tskims);
 387        bfa_fcpim_add_iostats(lstats, rstats, iocomp_ok);
 388        bfa_fcpim_add_iostats(lstats, rstats, iocomp_underrun);
 389        bfa_fcpim_add_iostats(lstats, rstats, iocomp_overrun);
 390        bfa_fcpim_add_iostats(lstats, rstats, iocomp_aborted);
 391        bfa_fcpim_add_iostats(lstats, rstats, iocomp_timedout);
 392        bfa_fcpim_add_iostats(lstats, rstats, iocom_nexus_abort);
 393        bfa_fcpim_add_iostats(lstats, rstats, iocom_proto_err);
 394        bfa_fcpim_add_iostats(lstats, rstats, iocom_dif_err);
 395        bfa_fcpim_add_iostats(lstats, rstats, iocom_sqer_needed);
 396        bfa_fcpim_add_iostats(lstats, rstats, iocom_res_free);
 397        bfa_fcpim_add_iostats(lstats, rstats, iocom_hostabrts);
 398        bfa_fcpim_add_iostats(lstats, rstats, iocom_utags);
 399        bfa_fcpim_add_iostats(lstats, rstats, io_cleanups);
 400        bfa_fcpim_add_iostats(lstats, rstats, io_tmaborts);
 401        bfa_fcpim_add_iostats(lstats, rstats, onlines);
 402        bfa_fcpim_add_iostats(lstats, rstats, offlines);
 403        bfa_fcpim_add_iostats(lstats, rstats, creates);
 404        bfa_fcpim_add_iostats(lstats, rstats, deletes);
 405        bfa_fcpim_add_iostats(lstats, rstats, create_comps);
 406        bfa_fcpim_add_iostats(lstats, rstats, delete_comps);
 407        bfa_fcpim_add_iostats(lstats, rstats, sler_events);
 408        bfa_fcpim_add_iostats(lstats, rstats, fw_create);
 409        bfa_fcpim_add_iostats(lstats, rstats, fw_delete);
 410        bfa_fcpim_add_iostats(lstats, rstats, ioc_disabled);
 411        bfa_fcpim_add_iostats(lstats, rstats, cleanup_comps);
 412        bfa_fcpim_add_iostats(lstats, rstats, tm_cmnds);
 413        bfa_fcpim_add_iostats(lstats, rstats, tm_fw_rsps);
 414        bfa_fcpim_add_iostats(lstats, rstats, tm_success);
 415        bfa_fcpim_add_iostats(lstats, rstats, tm_failures);
 416        bfa_fcpim_add_iostats(lstats, rstats, tm_io_comps);
 417        bfa_fcpim_add_iostats(lstats, rstats, tm_qresumes);
 418        bfa_fcpim_add_iostats(lstats, rstats, tm_iocdowns);
 419        bfa_fcpim_add_iostats(lstats, rstats, tm_cleanups);
 420        bfa_fcpim_add_iostats(lstats, rstats, tm_cleanup_comps);
 421        bfa_fcpim_add_iostats(lstats, rstats, io_comps);
 422        bfa_fcpim_add_iostats(lstats, rstats, input_reqs);
 423        bfa_fcpim_add_iostats(lstats, rstats, output_reqs);
 424        bfa_fcpim_add_iostats(lstats, rstats, rd_throughput);
 425        bfa_fcpim_add_iostats(lstats, rstats, wr_throughput);
 426}
 427
 428bfa_status_t
 429bfa_fcpim_port_iostats(struct bfa_s *bfa,
 430                struct bfa_itnim_iostats_s *stats, u8 lp_tag)
 431{
 432        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
 433        struct list_head *qe, *qen;
 434        struct bfa_itnim_s *itnim;
 435
 436        /* accumulate IO stats from itnim */
 437        memset(stats, 0, sizeof(struct bfa_itnim_iostats_s));
 438        list_for_each_safe(qe, qen, &fcpim->itnim_q) {
 439                itnim = (struct bfa_itnim_s *) qe;
 440                if (itnim->rport->rport_info.lp_tag != lp_tag)
 441                        continue;
 442                bfa_fcpim_add_stats(stats, &(itnim->stats));
 443        }
 444        return BFA_STATUS_OK;
 445}
 446
 447void
 448bfa_ioim_profile_comp(struct bfa_ioim_s *ioim)
 449{
 450        struct bfa_itnim_latency_s *io_lat =
 451                        &(ioim->itnim->ioprofile.io_latency);
 452        u32 val, idx;
 453
 454        val = (u32)(jiffies - ioim->start_time);
 455        idx = bfa_ioim_get_index(scsi_bufflen((struct scsi_cmnd *)ioim->dio));
 456        bfa_itnim_ioprofile_update(ioim->itnim, idx);
 457
 458        io_lat->count[idx]++;
 459        io_lat->min[idx] = (io_lat->min[idx] < val) ? io_lat->min[idx] : val;
 460        io_lat->max[idx] = (io_lat->max[idx] > val) ? io_lat->max[idx] : val;
 461        io_lat->avg[idx] += val;
 462}
 463
 464void
 465bfa_ioim_profile_start(struct bfa_ioim_s *ioim)
 466{
 467        ioim->start_time = jiffies;
 468}
 469
 470bfa_status_t
 471bfa_fcpim_profile_on(struct bfa_s *bfa, u32 time)
 472{
 473        struct bfa_itnim_s *itnim;
 474        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
 475        struct list_head *qe, *qen;
 476
 477        /* accumulate IO stats from itnim */
 478        list_for_each_safe(qe, qen, &fcpim->itnim_q) {
 479                itnim = (struct bfa_itnim_s *) qe;
 480                bfa_itnim_clear_stats(itnim);
 481        }
 482        fcpim->io_profile = BFA_TRUE;
 483        fcpim->io_profile_start_time = time;
 484        fcpim->profile_comp = bfa_ioim_profile_comp;
 485        fcpim->profile_start = bfa_ioim_profile_start;
 486        return BFA_STATUS_OK;
 487}
 488
 489bfa_status_t
 490bfa_fcpim_profile_off(struct bfa_s *bfa)
 491{
 492        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
 493        fcpim->io_profile = BFA_FALSE;
 494        fcpim->io_profile_start_time = 0;
 495        fcpim->profile_comp = NULL;
 496        fcpim->profile_start = NULL;
 497        return BFA_STATUS_OK;
 498}
 499
 500u16
 501bfa_fcpim_qdepth_get(struct bfa_s *bfa)
 502{
 503        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
 504
 505        return fcpim->q_depth;
 506}
 507
 508/*
 509 *  BFA ITNIM module state machine functions
 510 */
 511
 512/*
 513 * Beginning/unallocated state - no events expected.
 514 */
 515static void
 516bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 517{
 518        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 519        bfa_trc(itnim->bfa, event);
 520
 521        switch (event) {
 522        case BFA_ITNIM_SM_CREATE:
 523                bfa_sm_set_state(itnim, bfa_itnim_sm_created);
 524                itnim->is_online = BFA_FALSE;
 525                bfa_fcpim_additn(itnim);
 526                break;
 527
 528        default:
 529                bfa_sm_fault(itnim->bfa, event);
 530        }
 531}
 532
 533/*
 534 * Beginning state, only online event expected.
 535 */
 536static void
 537bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 538{
 539        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 540        bfa_trc(itnim->bfa, event);
 541
 542        switch (event) {
 543        case BFA_ITNIM_SM_ONLINE:
 544                if (bfa_itnim_send_fwcreate(itnim))
 545                        bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
 546                else
 547                        bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
 548                break;
 549
 550        case BFA_ITNIM_SM_DELETE:
 551                bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 552                bfa_fcpim_delitn(itnim);
 553                break;
 554
 555        case BFA_ITNIM_SM_HWFAIL:
 556                bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 557                break;
 558
 559        default:
 560                bfa_sm_fault(itnim->bfa, event);
 561        }
 562}
 563
 564/*
 565 *      Waiting for itnim create response from firmware.
 566 */
 567static void
 568bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 569{
 570        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 571        bfa_trc(itnim->bfa, event);
 572
 573        switch (event) {
 574        case BFA_ITNIM_SM_FWRSP:
 575                bfa_sm_set_state(itnim, bfa_itnim_sm_online);
 576                itnim->is_online = BFA_TRUE;
 577                bfa_itnim_iotov_online(itnim);
 578                bfa_itnim_online_cb(itnim);
 579                break;
 580
 581        case BFA_ITNIM_SM_DELETE:
 582                bfa_sm_set_state(itnim, bfa_itnim_sm_delete_pending);
 583                break;
 584
 585        case BFA_ITNIM_SM_OFFLINE:
 586                if (bfa_itnim_send_fwdelete(itnim))
 587                        bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
 588                else
 589                        bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull);
 590                break;
 591
 592        case BFA_ITNIM_SM_HWFAIL:
 593                bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 594                break;
 595
 596        default:
 597                bfa_sm_fault(itnim->bfa, event);
 598        }
 599}
 600
 601static void
 602bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
 603                        enum bfa_itnim_event event)
 604{
 605        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 606        bfa_trc(itnim->bfa, event);
 607
 608        switch (event) {
 609        case BFA_ITNIM_SM_QRESUME:
 610                bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
 611                bfa_itnim_send_fwcreate(itnim);
 612                break;
 613
 614        case BFA_ITNIM_SM_DELETE:
 615                bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 616                bfa_reqq_wcancel(&itnim->reqq_wait);
 617                bfa_fcpim_delitn(itnim);
 618                break;
 619
 620        case BFA_ITNIM_SM_OFFLINE:
 621                bfa_sm_set_state(itnim, bfa_itnim_sm_offline);
 622                bfa_reqq_wcancel(&itnim->reqq_wait);
 623                bfa_itnim_offline_cb(itnim);
 624                break;
 625
 626        case BFA_ITNIM_SM_HWFAIL:
 627                bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 628                bfa_reqq_wcancel(&itnim->reqq_wait);
 629                break;
 630
 631        default:
 632                bfa_sm_fault(itnim->bfa, event);
 633        }
 634}
 635
 636/*
 637 * Waiting for itnim create response from firmware, a delete is pending.
 638 */
 639static void
 640bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
 641                                enum bfa_itnim_event event)
 642{
 643        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 644        bfa_trc(itnim->bfa, event);
 645
 646        switch (event) {
 647        case BFA_ITNIM_SM_FWRSP:
 648                if (bfa_itnim_send_fwdelete(itnim))
 649                        bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
 650                else
 651                        bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
 652                break;
 653
 654        case BFA_ITNIM_SM_HWFAIL:
 655                bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 656                bfa_fcpim_delitn(itnim);
 657                break;
 658
 659        default:
 660                bfa_sm_fault(itnim->bfa, event);
 661        }
 662}
 663
 664/*
 665 * Online state - normal parking state.
 666 */
 667static void
 668bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 669{
 670        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 671        bfa_trc(itnim->bfa, event);
 672
 673        switch (event) {
 674        case BFA_ITNIM_SM_OFFLINE:
 675                bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline);
 676                itnim->is_online = BFA_FALSE;
 677                bfa_itnim_iotov_start(itnim);
 678                bfa_itnim_cleanup(itnim);
 679                break;
 680
 681        case BFA_ITNIM_SM_DELETE:
 682                bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
 683                itnim->is_online = BFA_FALSE;
 684                bfa_itnim_cleanup(itnim);
 685                break;
 686
 687        case BFA_ITNIM_SM_SLER:
 688                bfa_sm_set_state(itnim, bfa_itnim_sm_sler);
 689                itnim->is_online = BFA_FALSE;
 690                bfa_itnim_iotov_start(itnim);
 691                bfa_itnim_sler_cb(itnim);
 692                break;
 693
 694        case BFA_ITNIM_SM_HWFAIL:
 695                bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 696                itnim->is_online = BFA_FALSE;
 697                bfa_itnim_iotov_start(itnim);
 698                bfa_itnim_iocdisable_cleanup(itnim);
 699                break;
 700
 701        default:
 702                bfa_sm_fault(itnim->bfa, event);
 703        }
 704}
 705
 706/*
 707 * Second level error recovery need.
 708 */
 709static void
 710bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 711{
 712        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 713        bfa_trc(itnim->bfa, event);
 714
 715        switch (event) {
 716        case BFA_ITNIM_SM_OFFLINE:
 717                bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline);
 718                bfa_itnim_cleanup(itnim);
 719                break;
 720
 721        case BFA_ITNIM_SM_DELETE:
 722                bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
 723                bfa_itnim_cleanup(itnim);
 724                bfa_itnim_iotov_delete(itnim);
 725                break;
 726
 727        case BFA_ITNIM_SM_HWFAIL:
 728                bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 729                bfa_itnim_iocdisable_cleanup(itnim);
 730                break;
 731
 732        default:
 733                bfa_sm_fault(itnim->bfa, event);
 734        }
 735}
 736
 737/*
 738 * Going offline. Waiting for active IO cleanup.
 739 */
 740static void
 741bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
 742                                 enum bfa_itnim_event event)
 743{
 744        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 745        bfa_trc(itnim->bfa, event);
 746
 747        switch (event) {
 748        case BFA_ITNIM_SM_CLEANUP:
 749                if (bfa_itnim_send_fwdelete(itnim))
 750                        bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
 751                else
 752                        bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull);
 753                break;
 754
 755        case BFA_ITNIM_SM_DELETE:
 756                bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
 757                bfa_itnim_iotov_delete(itnim);
 758                break;
 759
 760        case BFA_ITNIM_SM_HWFAIL:
 761                bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 762                bfa_itnim_iocdisable_cleanup(itnim);
 763                bfa_itnim_offline_cb(itnim);
 764                break;
 765
 766        case BFA_ITNIM_SM_SLER:
 767                break;
 768
 769        default:
 770                bfa_sm_fault(itnim->bfa, event);
 771        }
 772}
 773
 774/*
 775 * Deleting itnim. Waiting for active IO cleanup.
 776 */
 777static void
 778bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
 779                                enum bfa_itnim_event event)
 780{
 781        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 782        bfa_trc(itnim->bfa, event);
 783
 784        switch (event) {
 785        case BFA_ITNIM_SM_CLEANUP:
 786                if (bfa_itnim_send_fwdelete(itnim))
 787                        bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
 788                else
 789                        bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
 790                break;
 791
 792        case BFA_ITNIM_SM_HWFAIL:
 793                bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 794                bfa_itnim_iocdisable_cleanup(itnim);
 795                break;
 796
 797        default:
 798                bfa_sm_fault(itnim->bfa, event);
 799        }
 800}
 801
 802/*
 803 * Rport offline. Fimrware itnim is being deleted - awaiting f/w response.
 804 */
 805static void
 806bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 807{
 808        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 809        bfa_trc(itnim->bfa, event);
 810
 811        switch (event) {
 812        case BFA_ITNIM_SM_FWRSP:
 813                bfa_sm_set_state(itnim, bfa_itnim_sm_offline);
 814                bfa_itnim_offline_cb(itnim);
 815                break;
 816
 817        case BFA_ITNIM_SM_DELETE:
 818                bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
 819                break;
 820
 821        case BFA_ITNIM_SM_HWFAIL:
 822                bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 823                bfa_itnim_offline_cb(itnim);
 824                break;
 825
 826        default:
 827                bfa_sm_fault(itnim->bfa, event);
 828        }
 829}
 830
 831static void
 832bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
 833                        enum bfa_itnim_event event)
 834{
 835        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 836        bfa_trc(itnim->bfa, event);
 837
 838        switch (event) {
 839        case BFA_ITNIM_SM_QRESUME:
 840                bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
 841                bfa_itnim_send_fwdelete(itnim);
 842                break;
 843
 844        case BFA_ITNIM_SM_DELETE:
 845                bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
 846                break;
 847
 848        case BFA_ITNIM_SM_HWFAIL:
 849                bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 850                bfa_reqq_wcancel(&itnim->reqq_wait);
 851                bfa_itnim_offline_cb(itnim);
 852                break;
 853
 854        default:
 855                bfa_sm_fault(itnim->bfa, event);
 856        }
 857}
 858
 859/*
 860 * Offline state.
 861 */
 862static void
 863bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 864{
 865        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 866        bfa_trc(itnim->bfa, event);
 867
 868        switch (event) {
 869        case BFA_ITNIM_SM_DELETE:
 870                bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 871                bfa_itnim_iotov_delete(itnim);
 872                bfa_fcpim_delitn(itnim);
 873                break;
 874
 875        case BFA_ITNIM_SM_ONLINE:
 876                if (bfa_itnim_send_fwcreate(itnim))
 877                        bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
 878                else
 879                        bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
 880                break;
 881
 882        case BFA_ITNIM_SM_HWFAIL:
 883                bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 884                break;
 885
 886        default:
 887                bfa_sm_fault(itnim->bfa, event);
 888        }
 889}
 890
 891static void
 892bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
 893                                enum bfa_itnim_event event)
 894{
 895        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 896        bfa_trc(itnim->bfa, event);
 897
 898        switch (event) {
 899        case BFA_ITNIM_SM_DELETE:
 900                bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 901                bfa_itnim_iotov_delete(itnim);
 902                bfa_fcpim_delitn(itnim);
 903                break;
 904
 905        case BFA_ITNIM_SM_OFFLINE:
 906                bfa_itnim_offline_cb(itnim);
 907                break;
 908
 909        case BFA_ITNIM_SM_ONLINE:
 910                if (bfa_itnim_send_fwcreate(itnim))
 911                        bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
 912                else
 913                        bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
 914                break;
 915
 916        case BFA_ITNIM_SM_HWFAIL:
 917                break;
 918
 919        default:
 920                bfa_sm_fault(itnim->bfa, event);
 921        }
 922}
 923
 924/*
 925 * Itnim is deleted, waiting for firmware response to delete.
 926 */
 927static void
 928bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 929{
 930        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 931        bfa_trc(itnim->bfa, event);
 932
 933        switch (event) {
 934        case BFA_ITNIM_SM_FWRSP:
 935        case BFA_ITNIM_SM_HWFAIL:
 936                bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 937                bfa_fcpim_delitn(itnim);
 938                break;
 939
 940        default:
 941                bfa_sm_fault(itnim->bfa, event);
 942        }
 943}
 944
 945static void
 946bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
 947                enum bfa_itnim_event event)
 948{
 949        bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 950        bfa_trc(itnim->bfa, event);
 951
 952        switch (event) {
 953        case BFA_ITNIM_SM_QRESUME:
 954                bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
 955                bfa_itnim_send_fwdelete(itnim);
 956                break;
 957
 958        case BFA_ITNIM_SM_HWFAIL:
 959                bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 960                bfa_reqq_wcancel(&itnim->reqq_wait);
 961                bfa_fcpim_delitn(itnim);
 962                break;
 963
 964        default:
 965                bfa_sm_fault(itnim->bfa, event);
 966        }
 967}
 968
 969/*
 970 * Initiate cleanup of all IOs on an IOC failure.
 971 */
 972static void
 973bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim)
 974{
 975        struct bfa_tskim_s *tskim;
 976        struct bfa_ioim_s *ioim;
 977        struct list_head        *qe, *qen;
 978
 979        list_for_each_safe(qe, qen, &itnim->tsk_q) {
 980                tskim = (struct bfa_tskim_s *) qe;
 981                bfa_tskim_iocdisable(tskim);
 982        }
 983
 984        list_for_each_safe(qe, qen, &itnim->io_q) {
 985                ioim = (struct bfa_ioim_s *) qe;
 986                bfa_ioim_iocdisable(ioim);
 987        }
 988
 989        /*
 990         * For IO request in pending queue, we pretend an early timeout.
 991         */
 992        list_for_each_safe(qe, qen, &itnim->pending_q) {
 993                ioim = (struct bfa_ioim_s *) qe;
 994                bfa_ioim_tov(ioim);
 995        }
 996
 997        list_for_each_safe(qe, qen, &itnim->io_cleanup_q) {
 998                ioim = (struct bfa_ioim_s *) qe;
 999                bfa_ioim_iocdisable(ioim);
1000        }
1001}
1002
1003/*
1004 * IO cleanup completion
1005 */
1006static void
1007bfa_itnim_cleanp_comp(void *itnim_cbarg)
1008{
1009        struct bfa_itnim_s *itnim = itnim_cbarg;
1010
1011        bfa_stats(itnim, cleanup_comps);
1012        bfa_sm_send_event(itnim, BFA_ITNIM_SM_CLEANUP);
1013}
1014
1015/*
1016 * Initiate cleanup of all IOs.
1017 */
1018static void
1019bfa_itnim_cleanup(struct bfa_itnim_s *itnim)
1020{
1021        struct bfa_ioim_s  *ioim;
1022        struct bfa_tskim_s *tskim;
1023        struct list_head        *qe, *qen;
1024
1025        bfa_wc_init(&itnim->wc, bfa_itnim_cleanp_comp, itnim);
1026
1027        list_for_each_safe(qe, qen, &itnim->io_q) {
1028                ioim = (struct bfa_ioim_s *) qe;
1029
1030                /*
1031                 * Move IO to a cleanup queue from active queue so that a later
1032                 * TM will not pickup this IO.
1033                 */
1034                list_del(&ioim->qe);
1035                list_add_tail(&ioim->qe, &itnim->io_cleanup_q);
1036
1037                bfa_wc_up(&itnim->wc);
1038                bfa_ioim_cleanup(ioim);
1039        }
1040
1041        list_for_each_safe(qe, qen, &itnim->tsk_q) {
1042                tskim = (struct bfa_tskim_s *) qe;
1043                bfa_wc_up(&itnim->wc);
1044                bfa_tskim_cleanup(tskim);
1045        }
1046
1047        bfa_wc_wait(&itnim->wc);
1048}
1049
1050static void
1051__bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete)
1052{
1053        struct bfa_itnim_s *itnim = cbarg;
1054
1055        if (complete)
1056                bfa_cb_itnim_online(itnim->ditn);
1057}
1058
1059static void
1060__bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete)
1061{
1062        struct bfa_itnim_s *itnim = cbarg;
1063
1064        if (complete)
1065                bfa_cb_itnim_offline(itnim->ditn);
1066}
1067
1068static void
1069__bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete)
1070{
1071        struct bfa_itnim_s *itnim = cbarg;
1072
1073        if (complete)
1074                bfa_cb_itnim_sler(itnim->ditn);
1075}
1076
1077/*
1078 * Call to resume any I/O requests waiting for room in request queue.
1079 */
1080static void
1081bfa_itnim_qresume(void *cbarg)
1082{
1083        struct bfa_itnim_s *itnim = cbarg;
1084
1085        bfa_sm_send_event(itnim, BFA_ITNIM_SM_QRESUME);
1086}
1087
1088/*
1089 *  bfa_itnim_public
1090 */
1091
1092void
1093bfa_itnim_iodone(struct bfa_itnim_s *itnim)
1094{
1095        bfa_wc_down(&itnim->wc);
1096}
1097
1098void
1099bfa_itnim_tskdone(struct bfa_itnim_s *itnim)
1100{
1101        bfa_wc_down(&itnim->wc);
1102}
1103
1104void
1105bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len)
1106{
1107        /*
1108         * ITN memory
1109         */
1110        *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_itnim_s);
1111}
1112
1113void
1114bfa_itnim_attach(struct bfa_fcpim_s *fcpim)
1115{
1116        struct bfa_s    *bfa = fcpim->bfa;
1117        struct bfa_fcp_mod_s    *fcp = fcpim->fcp;
1118        struct bfa_itnim_s *itnim;
1119        int     i, j;
1120
1121        INIT_LIST_HEAD(&fcpim->itnim_q);
1122
1123        itnim = (struct bfa_itnim_s *) bfa_mem_kva_curp(fcp);
1124        fcpim->itnim_arr = itnim;
1125
1126        for (i = 0; i < fcpim->num_itnims; i++, itnim++) {
1127                memset(itnim, 0, sizeof(struct bfa_itnim_s));
1128                itnim->bfa = bfa;
1129                itnim->fcpim = fcpim;
1130                itnim->reqq = BFA_REQQ_QOS_LO;
1131                itnim->rport = BFA_RPORT_FROM_TAG(bfa, i);
1132                itnim->iotov_active = BFA_FALSE;
1133                bfa_reqq_winit(&itnim->reqq_wait, bfa_itnim_qresume, itnim);
1134
1135                INIT_LIST_HEAD(&itnim->io_q);
1136                INIT_LIST_HEAD(&itnim->io_cleanup_q);
1137                INIT_LIST_HEAD(&itnim->pending_q);
1138                INIT_LIST_HEAD(&itnim->tsk_q);
1139                INIT_LIST_HEAD(&itnim->delay_comp_q);
1140                for (j = 0; j < BFA_IOBUCKET_MAX; j++)
1141                        itnim->ioprofile.io_latency.min[j] = ~0;
1142                bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
1143        }
1144
1145        bfa_mem_kva_curp(fcp) = (u8 *) itnim;
1146}
1147
1148void
1149bfa_itnim_iocdisable(struct bfa_itnim_s *itnim)
1150{
1151        bfa_stats(itnim, ioc_disabled);
1152        bfa_sm_send_event(itnim, BFA_ITNIM_SM_HWFAIL);
1153}
1154
1155static bfa_boolean_t
1156bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim)
1157{
1158        struct bfi_itn_create_req_s *m;
1159
1160        itnim->msg_no++;
1161
1162        /*
1163         * check for room in queue to send request now
1164         */
1165        m = bfa_reqq_next(itnim->bfa, itnim->reqq);
1166        if (!m) {
1167                bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait);
1168                return BFA_FALSE;
1169        }
1170
1171        bfi_h2i_set(m->mh, BFI_MC_ITN, BFI_ITN_H2I_CREATE_REQ,
1172                        bfa_fn_lpu(itnim->bfa));
1173        m->fw_handle = itnim->rport->fw_handle;
1174        m->class = FC_CLASS_3;
1175        m->seq_rec = itnim->seq_rec;
1176        m->msg_no = itnim->msg_no;
1177        bfa_stats(itnim, fw_create);
1178
1179        /*
1180         * queue I/O message to firmware
1181         */
1182        bfa_reqq_produce(itnim->bfa, itnim->reqq, m->mh);
1183        return BFA_TRUE;
1184}
1185
1186static bfa_boolean_t
1187bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim)
1188{
1189        struct bfi_itn_delete_req_s *m;
1190
1191        /*
1192         * check for room in queue to send request now
1193         */
1194        m = bfa_reqq_next(itnim->bfa, itnim->reqq);
1195        if (!m) {
1196                bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait);
1197                return BFA_FALSE;
1198        }
1199
1200        bfi_h2i_set(m->mh, BFI_MC_ITN, BFI_ITN_H2I_DELETE_REQ,
1201                        bfa_fn_lpu(itnim->bfa));
1202        m->fw_handle = itnim->rport->fw_handle;
1203        bfa_stats(itnim, fw_delete);
1204
1205        /*
1206         * queue I/O message to firmware
1207         */
1208        bfa_reqq_produce(itnim->bfa, itnim->reqq, m->mh);
1209        return BFA_TRUE;
1210}
1211
1212/*
1213 * Cleanup all pending failed inflight requests.
1214 */
1215static void
1216bfa_itnim_delayed_comp(struct bfa_itnim_s *itnim, bfa_boolean_t iotov)
1217{
1218        struct bfa_ioim_s *ioim;
1219        struct list_head *qe, *qen;
1220
1221        list_for_each_safe(qe, qen, &itnim->delay_comp_q) {
1222                ioim = (struct bfa_ioim_s *)qe;
1223                bfa_ioim_delayed_comp(ioim, iotov);
1224        }
1225}
1226
1227/*
1228 * Start all pending IO requests.
1229 */
1230static void
1231bfa_itnim_iotov_online(struct bfa_itnim_s *itnim)
1232{
1233        struct bfa_ioim_s *ioim;
1234
1235        bfa_itnim_iotov_stop(itnim);
1236
1237        /*
1238         * Abort all inflight IO requests in the queue
1239         */
1240        bfa_itnim_delayed_comp(itnim, BFA_FALSE);
1241
1242        /*
1243         * Start all pending IO requests.
1244         */
1245        while (!list_empty(&itnim->pending_q)) {
1246                bfa_q_deq(&itnim->pending_q, &ioim);
1247                list_add_tail(&ioim->qe, &itnim->io_q);
1248                bfa_ioim_start(ioim);
1249        }
1250}
1251
1252/*
1253 * Fail all pending IO requests
1254 */
1255static void
1256bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim)
1257{
1258        struct bfa_ioim_s *ioim;
1259
1260        /*
1261         * Fail all inflight IO requests in the queue
1262         */
1263        bfa_itnim_delayed_comp(itnim, BFA_TRUE);
1264
1265        /*
1266         * Fail any pending IO requests.
1267         */
1268        while (!list_empty(&itnim->pending_q)) {
1269                bfa_q_deq(&itnim->pending_q, &ioim);
1270                list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
1271                bfa_ioim_tov(ioim);
1272        }
1273}
1274
1275/*
1276 * IO TOV timer callback. Fail any pending IO requests.
1277 */
1278static void
1279bfa_itnim_iotov(void *itnim_arg)
1280{
1281        struct bfa_itnim_s *itnim = itnim_arg;
1282
1283        itnim->iotov_active = BFA_FALSE;
1284
1285        bfa_cb_itnim_tov_begin(itnim->ditn);
1286        bfa_itnim_iotov_cleanup(itnim);
1287        bfa_cb_itnim_tov(itnim->ditn);
1288}
1289
1290/*
1291 * Start IO TOV timer for failing back pending IO requests in offline state.
1292 */
1293static void
1294bfa_itnim_iotov_start(struct bfa_itnim_s *itnim)
1295{
1296        if (itnim->fcpim->path_tov > 0) {
1297
1298                itnim->iotov_active = BFA_TRUE;
1299                WARN_ON(!bfa_itnim_hold_io(itnim));
1300                bfa_timer_start(itnim->bfa, &itnim->timer,
1301                        bfa_itnim_iotov, itnim, itnim->fcpim->path_tov);
1302        }
1303}
1304
1305/*
1306 * Stop IO TOV timer.
1307 */
1308static void
1309bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim)
1310{
1311        if (itnim->iotov_active) {
1312                itnim->iotov_active = BFA_FALSE;
1313                bfa_timer_stop(&itnim->timer);
1314        }
1315}
1316
1317/*
1318 * Stop IO TOV timer.
1319 */
1320static void
1321bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim)
1322{
1323        bfa_boolean_t pathtov_active = BFA_FALSE;
1324
1325        if (itnim->iotov_active)
1326                pathtov_active = BFA_TRUE;
1327
1328        bfa_itnim_iotov_stop(itnim);
1329        if (pathtov_active)
1330                bfa_cb_itnim_tov_begin(itnim->ditn);
1331        bfa_itnim_iotov_cleanup(itnim);
1332        if (pathtov_active)
1333                bfa_cb_itnim_tov(itnim->ditn);
1334}
1335
1336static void
1337bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim)
1338{
1339        struct bfa_fcpim_s *fcpim = BFA_FCPIM(itnim->bfa);
1340        fcpim->del_itn_stats.del_itn_iocomp_aborted +=
1341                itnim->stats.iocomp_aborted;
1342        fcpim->del_itn_stats.del_itn_iocomp_timedout +=
1343                itnim->stats.iocomp_timedout;
1344        fcpim->del_itn_stats.del_itn_iocom_sqer_needed +=
1345                itnim->stats.iocom_sqer_needed;
1346        fcpim->del_itn_stats.del_itn_iocom_res_free +=
1347                itnim->stats.iocom_res_free;
1348        fcpim->del_itn_stats.del_itn_iocom_hostabrts +=
1349                itnim->stats.iocom_hostabrts;
1350        fcpim->del_itn_stats.del_itn_total_ios += itnim->stats.total_ios;
1351        fcpim->del_itn_stats.del_io_iocdowns += itnim->stats.io_iocdowns;
1352        fcpim->del_itn_stats.del_tm_iocdowns += itnim->stats.tm_iocdowns;
1353}
1354
1355/*
1356 * bfa_itnim_public
1357 */
1358
1359/*
1360 * Itnim interrupt processing.
1361 */
1362void
1363bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
1364{
1365        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
1366        union bfi_itn_i2h_msg_u msg;
1367        struct bfa_itnim_s *itnim;
1368
1369        bfa_trc(bfa, m->mhdr.msg_id);
1370
1371        msg.msg = m;
1372
1373        switch (m->mhdr.msg_id) {
1374        case BFI_ITN_I2H_CREATE_RSP:
1375                itnim = BFA_ITNIM_FROM_TAG(fcpim,
1376                                                msg.create_rsp->bfa_handle);
1377                WARN_ON(msg.create_rsp->status != BFA_STATUS_OK);
1378                bfa_stats(itnim, create_comps);
1379                bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
1380                break;
1381
1382        case BFI_ITN_I2H_DELETE_RSP:
1383                itnim = BFA_ITNIM_FROM_TAG(fcpim,
1384                                                msg.delete_rsp->bfa_handle);
1385                WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK);
1386                bfa_stats(itnim, delete_comps);
1387                bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
1388                break;
1389
1390        case BFI_ITN_I2H_SLER_EVENT:
1391                itnim = BFA_ITNIM_FROM_TAG(fcpim,
1392                                                msg.sler_event->bfa_handle);
1393                bfa_stats(itnim, sler_events);
1394                bfa_sm_send_event(itnim, BFA_ITNIM_SM_SLER);
1395                break;
1396
1397        default:
1398                bfa_trc(bfa, m->mhdr.msg_id);
1399                WARN_ON(1);
1400        }
1401}
1402
1403/*
1404 * bfa_itnim_api
1405 */
1406
1407struct bfa_itnim_s *
1408bfa_itnim_create(struct bfa_s *bfa, struct bfa_rport_s *rport, void *ditn)
1409{
1410        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
1411        struct bfa_itnim_s *itnim;
1412
1413        bfa_itn_create(bfa, rport, bfa_itnim_isr);
1414
1415        itnim = BFA_ITNIM_FROM_TAG(fcpim, rport->rport_tag);
1416        WARN_ON(itnim->rport != rport);
1417
1418        itnim->ditn = ditn;
1419
1420        bfa_stats(itnim, creates);
1421        bfa_sm_send_event(itnim, BFA_ITNIM_SM_CREATE);
1422
1423        return itnim;
1424}
1425
1426void
1427bfa_itnim_delete(struct bfa_itnim_s *itnim)
1428{
1429        bfa_stats(itnim, deletes);
1430        bfa_sm_send_event(itnim, BFA_ITNIM_SM_DELETE);
1431}
1432
1433void
1434bfa_itnim_online(struct bfa_itnim_s *itnim, bfa_boolean_t seq_rec)
1435{
1436        itnim->seq_rec = seq_rec;
1437        bfa_stats(itnim, onlines);
1438        bfa_sm_send_event(itnim, BFA_ITNIM_SM_ONLINE);
1439}
1440
1441void
1442bfa_itnim_offline(struct bfa_itnim_s *itnim)
1443{
1444        bfa_stats(itnim, offlines);
1445        bfa_sm_send_event(itnim, BFA_ITNIM_SM_OFFLINE);
1446}
1447
1448/*
1449 * Return true if itnim is considered offline for holding off IO request.
1450 * IO is not held if itnim is being deleted.
1451 */
1452bfa_boolean_t
1453bfa_itnim_hold_io(struct bfa_itnim_s *itnim)
1454{
1455        return itnim->fcpim->path_tov && itnim->iotov_active &&
1456                (bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwcreate) ||
1457                 bfa_sm_cmp_state(itnim, bfa_itnim_sm_sler) ||
1458                 bfa_sm_cmp_state(itnim, bfa_itnim_sm_cleanup_offline) ||
1459                 bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwdelete) ||
1460                 bfa_sm_cmp_state(itnim, bfa_itnim_sm_offline) ||
1461                 bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable));
1462}
1463
1464#define bfa_io_lat_clock_res_div        HZ
1465#define bfa_io_lat_clock_res_mul        1000
1466bfa_status_t
1467bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
1468                        struct bfa_itnim_ioprofile_s *ioprofile)
1469{
1470        struct bfa_fcpim_s *fcpim;
1471
1472        if (!itnim)
1473                return BFA_STATUS_NO_FCPIM_NEXUS;
1474
1475        fcpim = BFA_FCPIM(itnim->bfa);
1476
1477        if (!fcpim->io_profile)
1478                return BFA_STATUS_IOPROFILE_OFF;
1479
1480        itnim->ioprofile.index = BFA_IOBUCKET_MAX;
1481        itnim->ioprofile.io_profile_start_time =
1482                                bfa_io_profile_start_time(itnim->bfa);
1483        itnim->ioprofile.clock_res_mul = bfa_io_lat_clock_res_mul;
1484        itnim->ioprofile.clock_res_div = bfa_io_lat_clock_res_div;
1485        *ioprofile = itnim->ioprofile;
1486
1487        return BFA_STATUS_OK;
1488}
1489
1490void
1491bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
1492{
1493        int j;
1494
1495        if (!itnim)
1496                return;
1497
1498        memset(&itnim->stats, 0, sizeof(itnim->stats));
1499        memset(&itnim->ioprofile, 0, sizeof(itnim->ioprofile));
1500        for (j = 0; j < BFA_IOBUCKET_MAX; j++)
1501                itnim->ioprofile.io_latency.min[j] = ~0;
1502}
1503
1504/*
1505 *  BFA IO module state machine functions
1506 */
1507
1508/*
1509 * IO is not started (unallocated).
1510 */
1511static void
1512bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1513{
1514        switch (event) {
1515        case BFA_IOIM_SM_START:
1516                if (!bfa_itnim_is_online(ioim->itnim)) {
1517                        if (!bfa_itnim_hold_io(ioim->itnim)) {
1518                                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1519                                list_del(&ioim->qe);
1520                                list_add_tail(&ioim->qe,
1521                                        &ioim->fcpim->ioim_comp_q);
1522                                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1523                                                __bfa_cb_ioim_pathtov, ioim);
1524                        } else {
1525                                list_del(&ioim->qe);
1526                                list_add_tail(&ioim->qe,
1527                                        &ioim->itnim->pending_q);
1528                        }
1529                        break;
1530                }
1531
1532                if (ioim->nsges > BFI_SGE_INLINE) {
1533                        if (!bfa_ioim_sgpg_alloc(ioim)) {
1534                                bfa_sm_set_state(ioim, bfa_ioim_sm_sgalloc);
1535                                return;
1536                        }
1537                }
1538
1539                if (!bfa_ioim_send_ioreq(ioim)) {
1540                        bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
1541                        break;
1542                }
1543
1544                bfa_sm_set_state(ioim, bfa_ioim_sm_active);
1545                break;
1546
1547        case BFA_IOIM_SM_IOTOV:
1548                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1549                bfa_ioim_move_to_comp_q(ioim);
1550                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1551                                __bfa_cb_ioim_pathtov, ioim);
1552                break;
1553
1554        case BFA_IOIM_SM_ABORT:
1555                /*
1556                 * IO in pending queue can get abort requests. Complete abort
1557                 * requests immediately.
1558                 */
1559                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1560                WARN_ON(!bfa_q_is_on_q(&ioim->itnim->pending_q, ioim));
1561                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1562                        __bfa_cb_ioim_abort, ioim);
1563                break;
1564
1565        default:
1566                bfa_sm_fault(ioim->bfa, event);
1567        }
1568}
1569
1570/*
1571 * IO is waiting for SG pages.
1572 */
1573static void
1574bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1575{
1576        bfa_trc(ioim->bfa, ioim->iotag);
1577        bfa_trc(ioim->bfa, event);
1578
1579        switch (event) {
1580        case BFA_IOIM_SM_SGALLOCED:
1581                if (!bfa_ioim_send_ioreq(ioim)) {
1582                        bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
1583                        break;
1584                }
1585                bfa_sm_set_state(ioim, bfa_ioim_sm_active);
1586                break;
1587
1588        case BFA_IOIM_SM_CLEANUP:
1589                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1590                bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
1591                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1592                              ioim);
1593                bfa_ioim_notify_cleanup(ioim);
1594                break;
1595
1596        case BFA_IOIM_SM_ABORT:
1597                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1598                bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
1599                bfa_ioim_move_to_comp_q(ioim);
1600                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1601                              ioim);
1602                break;
1603
1604        case BFA_IOIM_SM_HWFAIL:
1605                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1606                bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
1607                bfa_ioim_move_to_comp_q(ioim);
1608                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1609                              ioim);
1610                break;
1611
1612        default:
1613                bfa_sm_fault(ioim->bfa, event);
1614        }
1615}
1616
1617/*
1618 * IO is active.
1619 */
1620static void
1621bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1622{
1623        switch (event) {
1624        case BFA_IOIM_SM_COMP_GOOD:
1625                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1626                bfa_ioim_move_to_comp_q(ioim);
1627                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1628                              __bfa_cb_ioim_good_comp, ioim);
1629                break;
1630
1631        case BFA_IOIM_SM_COMP:
1632                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1633                bfa_ioim_move_to_comp_q(ioim);
1634                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
1635                              ioim);
1636                break;
1637
1638        case BFA_IOIM_SM_DONE:
1639                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1640                bfa_ioim_move_to_comp_q(ioim);
1641                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
1642                              ioim);
1643                break;
1644
1645        case BFA_IOIM_SM_ABORT:
1646                ioim->iosp->abort_explicit = BFA_TRUE;
1647                ioim->io_cbfn = __bfa_cb_ioim_abort;
1648
1649                if (bfa_ioim_send_abort(ioim))
1650                        bfa_sm_set_state(ioim, bfa_ioim_sm_abort);
1651                else {
1652                        bfa_sm_set_state(ioim, bfa_ioim_sm_abort_qfull);
1653                        bfa_stats(ioim->itnim, qwait);
1654                        bfa_reqq_wait(ioim->bfa, ioim->reqq,
1655                                          &ioim->iosp->reqq_wait);
1656                }
1657                break;
1658
1659        case BFA_IOIM_SM_CLEANUP:
1660                ioim->iosp->abort_explicit = BFA_FALSE;
1661                ioim->io_cbfn = __bfa_cb_ioim_failed;
1662
1663                if (bfa_ioim_send_abort(ioim))
1664                        bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
1665                else {
1666                        bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
1667                        bfa_stats(ioim->itnim, qwait);
1668                        bfa_reqq_wait(ioim->bfa, ioim->reqq,
1669                                          &ioim->iosp->reqq_wait);
1670                }
1671                break;
1672
1673        case BFA_IOIM_SM_HWFAIL:
1674                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1675                bfa_ioim_move_to_comp_q(ioim);
1676                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1677                              ioim);
1678                break;
1679
1680        case BFA_IOIM_SM_SQRETRY:
1681                if (bfa_ioim_maxretry_reached(ioim)) {
1682                        /* max retry reached, free IO */
1683                        bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1684                        bfa_ioim_move_to_comp_q(ioim);
1685                        bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1686                                        __bfa_cb_ioim_failed, ioim);
1687                        break;
1688                }
1689                /* waiting for IO tag resource free */
1690                bfa_sm_set_state(ioim, bfa_ioim_sm_cmnd_retry);
1691                break;
1692
1693        default:
1694                bfa_sm_fault(ioim->bfa, event);
1695        }
1696}
1697
1698/*
1699 * IO is retried with new tag.
1700 */
1701static void
1702bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1703{
1704        switch (event) {
1705        case BFA_IOIM_SM_FREE:
1706                /* abts and rrq done. Now retry the IO with new tag */
1707                bfa_ioim_update_iotag(ioim);
1708                if (!bfa_ioim_send_ioreq(ioim)) {
1709                        bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
1710                        break;
1711                }
1712                bfa_sm_set_state(ioim, bfa_ioim_sm_active);
1713        break;
1714
1715        case BFA_IOIM_SM_CLEANUP:
1716                ioim->iosp->abort_explicit = BFA_FALSE;
1717                ioim->io_cbfn = __bfa_cb_ioim_failed;
1718
1719                if (bfa_ioim_send_abort(ioim))
1720                        bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
1721                else {
1722                        bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
1723                        bfa_stats(ioim->itnim, qwait);
1724                        bfa_reqq_wait(ioim->bfa, ioim->reqq,
1725                                          &ioim->iosp->reqq_wait);
1726                }
1727        break;
1728
1729        case BFA_IOIM_SM_HWFAIL:
1730                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1731                bfa_ioim_move_to_comp_q(ioim);
1732                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1733                         __bfa_cb_ioim_failed, ioim);
1734                break;
1735
1736        case BFA_IOIM_SM_ABORT:
1737                /* in this state IO abort is done.
1738                 * Waiting for IO tag resource free.
1739                 */
1740                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1741                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1742                              ioim);
1743                break;
1744
1745        default:
1746                bfa_sm_fault(ioim->bfa, event);
1747        }
1748}
1749
1750/*
1751 * IO is being aborted, waiting for completion from firmware.
1752 */
1753static void
1754bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1755{
1756        bfa_trc(ioim->bfa, ioim->iotag);
1757        bfa_trc(ioim->bfa, event);
1758
1759        switch (event) {
1760        case BFA_IOIM_SM_COMP_GOOD:
1761        case BFA_IOIM_SM_COMP:
1762        case BFA_IOIM_SM_DONE:
1763        case BFA_IOIM_SM_FREE:
1764                break;
1765
1766        case BFA_IOIM_SM_ABORT_DONE:
1767                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1768                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1769                              ioim);
1770                break;
1771
1772        case BFA_IOIM_SM_ABORT_COMP:
1773                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1774                bfa_ioim_move_to_comp_q(ioim);
1775                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1776                              ioim);
1777                break;
1778
1779        case BFA_IOIM_SM_COMP_UTAG:
1780                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1781                bfa_ioim_move_to_comp_q(ioim);
1782                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1783                              ioim);
1784                break;
1785
1786        case BFA_IOIM_SM_CLEANUP:
1787                WARN_ON(ioim->iosp->abort_explicit != BFA_TRUE);
1788                ioim->iosp->abort_explicit = BFA_FALSE;
1789
1790                if (bfa_ioim_send_abort(ioim))
1791                        bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
1792                else {
1793                        bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
1794                        bfa_stats(ioim->itnim, qwait);
1795                        bfa_reqq_wait(ioim->bfa, ioim->reqq,
1796                                          &ioim->iosp->reqq_wait);
1797                }
1798                break;
1799
1800        case BFA_IOIM_SM_HWFAIL:
1801                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1802                bfa_ioim_move_to_comp_q(ioim);
1803                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1804                              ioim);
1805                break;
1806
1807        default:
1808                bfa_sm_fault(ioim->bfa, event);
1809        }
1810}
1811
1812/*
1813 * IO is being cleaned up (implicit abort), waiting for completion from
1814 * firmware.
1815 */
1816static void
1817bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1818{
1819        bfa_trc(ioim->bfa, ioim->iotag);
1820        bfa_trc(ioim->bfa, event);
1821
1822        switch (event) {
1823        case BFA_IOIM_SM_COMP_GOOD:
1824        case BFA_IOIM_SM_COMP:
1825        case BFA_IOIM_SM_DONE:
1826        case BFA_IOIM_SM_FREE:
1827                break;
1828
1829        case BFA_IOIM_SM_ABORT:
1830                /*
1831                 * IO is already being aborted implicitly
1832                 */
1833                ioim->io_cbfn = __bfa_cb_ioim_abort;
1834                break;
1835
1836        case BFA_IOIM_SM_ABORT_DONE:
1837                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1838                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1839                bfa_ioim_notify_cleanup(ioim);
1840                break;
1841
1842        case BFA_IOIM_SM_ABORT_COMP:
1843                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1844                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1845                bfa_ioim_notify_cleanup(ioim);
1846                break;
1847
1848        case BFA_IOIM_SM_COMP_UTAG:
1849                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1850                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1851                bfa_ioim_notify_cleanup(ioim);
1852                break;
1853
1854        case BFA_IOIM_SM_HWFAIL:
1855                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1856                bfa_ioim_move_to_comp_q(ioim);
1857                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1858                              ioim);
1859                break;
1860
1861        case BFA_IOIM_SM_CLEANUP:
1862                /*
1863                 * IO can be in cleanup state already due to TM command.
1864                 * 2nd cleanup request comes from ITN offline event.
1865                 */
1866                break;
1867
1868        default:
1869                bfa_sm_fault(ioim->bfa, event);
1870        }
1871}
1872
1873/*
1874 * IO is waiting for room in request CQ
1875 */
1876static void
1877bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1878{
1879        bfa_trc(ioim->bfa, ioim->iotag);
1880        bfa_trc(ioim->bfa, event);
1881
1882        switch (event) {
1883        case BFA_IOIM_SM_QRESUME:
1884                bfa_sm_set_state(ioim, bfa_ioim_sm_active);
1885                bfa_ioim_send_ioreq(ioim);
1886                break;
1887
1888        case BFA_IOIM_SM_ABORT:
1889                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1890                bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1891                bfa_ioim_move_to_comp_q(ioim);
1892                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1893                              ioim);
1894                break;
1895
1896        case BFA_IOIM_SM_CLEANUP:
1897                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1898                bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1899                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1900                              ioim);
1901                bfa_ioim_notify_cleanup(ioim);
1902                break;
1903
1904        case BFA_IOIM_SM_HWFAIL:
1905                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1906                bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1907                bfa_ioim_move_to_comp_q(ioim);
1908                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1909                              ioim);
1910                break;
1911
1912        default:
1913                bfa_sm_fault(ioim->bfa, event);
1914        }
1915}
1916
1917/*
1918 * Active IO is being aborted, waiting for room in request CQ.
1919 */
1920static void
1921bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1922{
1923        bfa_trc(ioim->bfa, ioim->iotag);
1924        bfa_trc(ioim->bfa, event);
1925
1926        switch (event) {
1927        case BFA_IOIM_SM_QRESUME:
1928                bfa_sm_set_state(ioim, bfa_ioim_sm_abort);
1929                bfa_ioim_send_abort(ioim);
1930                break;
1931
1932        case BFA_IOIM_SM_CLEANUP:
1933                WARN_ON(ioim->iosp->abort_explicit != BFA_TRUE);
1934                ioim->iosp->abort_explicit = BFA_FALSE;
1935                bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
1936                break;
1937
1938        case BFA_IOIM_SM_COMP_GOOD:
1939        case BFA_IOIM_SM_COMP:
1940                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1941                bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1942                bfa_ioim_move_to_comp_q(ioim);
1943                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1944                              ioim);
1945                break;
1946
1947        case BFA_IOIM_SM_DONE:
1948                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1949                bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1950                bfa_ioim_move_to_comp_q(ioim);
1951                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1952                              ioim);
1953                break;
1954
1955        case BFA_IOIM_SM_HWFAIL:
1956                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1957                bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1958                bfa_ioim_move_to_comp_q(ioim);
1959                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1960                              ioim);
1961                break;
1962
1963        default:
1964                bfa_sm_fault(ioim->bfa, event);
1965        }
1966}
1967
1968/*
1969 * Active IO is being cleaned up, waiting for room in request CQ.
1970 */
1971static void
1972bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1973{
1974        bfa_trc(ioim->bfa, ioim->iotag);
1975        bfa_trc(ioim->bfa, event);
1976
1977        switch (event) {
1978        case BFA_IOIM_SM_QRESUME:
1979                bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
1980                bfa_ioim_send_abort(ioim);
1981                break;
1982
1983        case BFA_IOIM_SM_ABORT:
1984                /*
1985                 * IO is already being cleaned up implicitly
1986                 */
1987                ioim->io_cbfn = __bfa_cb_ioim_abort;
1988                break;
1989
1990        case BFA_IOIM_SM_COMP_GOOD:
1991        case BFA_IOIM_SM_COMP:
1992                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1993                bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
1994                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1995                bfa_ioim_notify_cleanup(ioim);
1996                break;
1997
1998        case BFA_IOIM_SM_DONE:
1999                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
2000                bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
2001                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
2002                bfa_ioim_notify_cleanup(ioim);
2003                break;
2004
2005        case BFA_IOIM_SM_HWFAIL:
2006                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2007                bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
2008                bfa_ioim_move_to_comp_q(ioim);
2009                bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
2010                              ioim);
2011                break;
2012
2013        default:
2014                bfa_sm_fault(ioim->bfa, event);
2015        }
2016}
2017
2018/*
2019 * IO bfa callback is pending.
2020 */
2021static void
2022bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
2023{
2024        switch (event) {
2025        case BFA_IOIM_SM_HCB:
2026                bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
2027                bfa_ioim_free(ioim);
2028                break;
2029
2030        case BFA_IOIM_SM_CLEANUP:
2031                bfa_ioim_notify_cleanup(ioim);
2032                break;
2033
2034        case BFA_IOIM_SM_HWFAIL:
2035                break;
2036
2037        default:
2038                bfa_sm_fault(ioim->bfa, event);
2039        }
2040}
2041
2042/*
2043 * IO bfa callback is pending. IO resource cannot be freed.
2044 */
2045static void
2046bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
2047{
2048        bfa_trc(ioim->bfa, ioim->iotag);
2049        bfa_trc(ioim->bfa, event);
2050
2051        switch (event) {
2052        case BFA_IOIM_SM_HCB:
2053                bfa_sm_set_state(ioim, bfa_ioim_sm_resfree);
2054                list_del(&ioim->qe);
2055                list_add_tail(&ioim->qe, &ioim->fcpim->ioim_resfree_q);
2056                break;
2057
2058        case BFA_IOIM_SM_FREE:
2059                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2060                break;
2061
2062        case BFA_IOIM_SM_CLEANUP:
2063                bfa_ioim_notify_cleanup(ioim);
2064                break;
2065
2066        case BFA_IOIM_SM_HWFAIL:
2067                bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2068                break;
2069
2070        default:
2071                bfa_sm_fault(ioim->bfa, event);
2072        }
2073}
2074
2075/*
2076 * IO is completed, waiting resource free from firmware.
2077 */
2078static void
2079bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
2080{
2081        bfa_trc(ioim->bfa, ioim->iotag);
2082        bfa_trc(ioim->bfa, event);
2083
2084        switch (event) {
2085        case BFA_IOIM_SM_FREE:
2086                bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
2087                bfa_ioim_free(ioim);
2088                break;
2089
2090        case BFA_IOIM_SM_CLEANUP:
2091                bfa_ioim_notify_cleanup(ioim);
2092                break;
2093
2094        case BFA_IOIM_SM_HWFAIL:
2095                break;
2096
2097        default:
2098                bfa_sm_fault(ioim->bfa, event);
2099        }
2100}
2101
2102/*
2103 * This is called from bfa_fcpim_start after the bfa_init() with flash read
2104 * is complete by driver. now invalidate the stale content of lun mask
2105 * like unit attention, rp tag and lp tag.
2106 */
2107static void
2108bfa_ioim_lm_init(struct bfa_s *bfa)
2109{
2110        struct bfa_lun_mask_s *lunm_list;
2111        int     i;
2112
2113        if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2114                return;
2115
2116        lunm_list = bfa_get_lun_mask_list(bfa);
2117        for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2118                lunm_list[i].ua = BFA_IOIM_LM_UA_RESET;
2119                lunm_list[i].lp_tag = BFA_LP_TAG_INVALID;
2120                lunm_list[i].rp_tag = BFA_RPORT_TAG_INVALID;
2121        }
2122}
2123
2124static void
2125__bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete)
2126{
2127        struct bfa_ioim_s *ioim = cbarg;
2128
2129        if (!complete) {
2130                bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2131                return;
2132        }
2133
2134        bfa_cb_ioim_good_comp(ioim->bfa->bfad, ioim->dio);
2135}
2136
2137static void
2138__bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete)
2139{
2140        struct bfa_ioim_s       *ioim = cbarg;
2141        struct bfi_ioim_rsp_s *m;
2142        u8      *snsinfo = NULL;
2143        u8      sns_len = 0;
2144        s32     residue = 0;
2145
2146        if (!complete) {
2147                bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2148                return;
2149        }
2150
2151        m = (struct bfi_ioim_rsp_s *) &ioim->iosp->comp_rspmsg;
2152        if (m->io_status == BFI_IOIM_STS_OK) {
2153                /*
2154                 * setup sense information, if present
2155                 */
2156                if ((m->scsi_status == SCSI_STATUS_CHECK_CONDITION) &&
2157                                        m->sns_len) {
2158                        sns_len = m->sns_len;
2159                        snsinfo = BFA_SNSINFO_FROM_TAG(ioim->fcpim->fcp,
2160                                                ioim->iotag);
2161                }
2162
2163                /*
2164                 * setup residue value correctly for normal completions
2165                 */
2166                if (m->resid_flags == FCP_RESID_UNDER) {
2167                        residue = be32_to_cpu(m->residue);
2168                        bfa_stats(ioim->itnim, iocomp_underrun);
2169                }
2170                if (m->resid_flags == FCP_RESID_OVER) {
2171                        residue = be32_to_cpu(m->residue);
2172                        residue = -residue;
2173                        bfa_stats(ioim->itnim, iocomp_overrun);
2174                }
2175        }
2176
2177        bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, m->io_status,
2178                          m->scsi_status, sns_len, snsinfo, residue);
2179}
2180
2181void
2182bfa_fcpim_lunmask_rp_update(struct bfa_s *bfa, wwn_t lp_wwn, wwn_t rp_wwn,
2183                        u16 rp_tag, u8 lp_tag)
2184{
2185        struct bfa_lun_mask_s *lun_list;
2186        u8      i;
2187
2188        if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2189                return;
2190
2191        lun_list = bfa_get_lun_mask_list(bfa);
2192        for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2193                if (lun_list[i].state == BFA_IOIM_LUN_MASK_ACTIVE) {
2194                        if ((lun_list[i].lp_wwn == lp_wwn) &&
2195                            (lun_list[i].rp_wwn == rp_wwn)) {
2196                                lun_list[i].rp_tag = rp_tag;
2197                                lun_list[i].lp_tag = lp_tag;
2198                        }
2199                }
2200        }
2201}
2202
2203/*
2204 * set UA for all active luns in LM DB
2205 */
2206static void
2207bfa_ioim_lm_set_ua(struct bfa_s *bfa)
2208{
2209        struct bfa_lun_mask_s   *lunm_list;
2210        int     i;
2211
2212        lunm_list = bfa_get_lun_mask_list(bfa);
2213        for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2214                if (lunm_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE)
2215                        continue;
2216                lunm_list[i].ua = BFA_IOIM_LM_UA_SET;
2217        }
2218}
2219
2220bfa_status_t
2221bfa_fcpim_lunmask_update(struct bfa_s *bfa, u32 update)
2222{
2223        struct bfa_lunmask_cfg_s        *lun_mask;
2224
2225        bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
2226        if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2227                return BFA_STATUS_FAILED;
2228
2229        if (bfa_get_lun_mask_status(bfa) == update)
2230                return BFA_STATUS_NO_CHANGE;
2231
2232        lun_mask = bfa_get_lun_mask(bfa);
2233        lun_mask->status = update;
2234
2235        if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_ENABLED)
2236                bfa_ioim_lm_set_ua(bfa);
2237
2238        return  bfa_dconf_update(bfa);
2239}
2240
2241bfa_status_t
2242bfa_fcpim_lunmask_clear(struct bfa_s *bfa)
2243{
2244        int i;
2245        struct bfa_lun_mask_s   *lunm_list;
2246
2247        bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
2248        if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2249                return BFA_STATUS_FAILED;
2250
2251        lunm_list = bfa_get_lun_mask_list(bfa);
2252        for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2253                if (lunm_list[i].state == BFA_IOIM_LUN_MASK_ACTIVE) {
2254                        if (lunm_list[i].rp_tag != BFA_RPORT_TAG_INVALID)
2255                                bfa_rport_unset_lunmask(bfa,
2256                                  BFA_RPORT_FROM_TAG(bfa, lunm_list[i].rp_tag));
2257                }
2258        }
2259
2260        memset(lunm_list, 0, sizeof(struct bfa_lun_mask_s) * MAX_LUN_MASK_CFG);
2261        return bfa_dconf_update(bfa);
2262}
2263
2264bfa_status_t
2265bfa_fcpim_lunmask_query(struct bfa_s *bfa, void *buf)
2266{
2267        struct bfa_lunmask_cfg_s *lun_mask;
2268
2269        bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
2270        if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2271                return BFA_STATUS_FAILED;
2272
2273        lun_mask = bfa_get_lun_mask(bfa);
2274        memcpy(buf, lun_mask, sizeof(struct bfa_lunmask_cfg_s));
2275        return BFA_STATUS_OK;
2276}
2277
2278bfa_status_t
2279bfa_fcpim_lunmask_add(struct bfa_s *bfa, u16 vf_id, wwn_t *pwwn,
2280                      wwn_t rpwwn, struct scsi_lun lun)
2281{
2282        struct bfa_lun_mask_s *lunm_list;
2283        struct bfa_rport_s *rp = NULL;
2284        int i, free_index = MAX_LUN_MASK_CFG + 1;
2285        struct bfa_fcs_lport_s *port = NULL;
2286        struct bfa_fcs_rport_s *rp_fcs;
2287
2288        bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
2289        if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2290                return BFA_STATUS_FAILED;
2291
2292        port = bfa_fcs_lookup_port(&((struct bfad_s *)bfa->bfad)->bfa_fcs,
2293                                   vf_id, *pwwn);
2294        if (port) {
2295                *pwwn = port->port_cfg.pwwn;
2296                rp_fcs = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
2297                if (rp_fcs)
2298                        rp = rp_fcs->bfa_rport;
2299        }
2300
2301        lunm_list = bfa_get_lun_mask_list(bfa);
2302        /* if entry exists */
2303        for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2304                if (lunm_list[i].state != BFA_IOIM_LUN_MASK_ACTIVE)
2305                        free_index = i;
2306                if ((lunm_list[i].lp_wwn == *pwwn) &&
2307                    (lunm_list[i].rp_wwn == rpwwn) &&
2308                    (scsilun_to_int((struct scsi_lun *)&lunm_list[i].lun) ==
2309                     scsilun_to_int((struct scsi_lun *)&lun)))
2310                        return  BFA_STATUS_ENTRY_EXISTS;
2311        }
2312
2313        if (free_index > MAX_LUN_MASK_CFG)
2314                return BFA_STATUS_MAX_ENTRY_REACHED;
2315
2316        if (rp) {
2317                lunm_list[free_index].lp_tag = bfa_lps_get_tag_from_pid(bfa,
2318                                                   rp->rport_info.local_pid);
2319                lunm_list[free_index].rp_tag = rp->rport_tag;
2320        } else {
2321                lunm_list[free_index].lp_tag = BFA_LP_TAG_INVALID;
2322                lunm_list[free_index].rp_tag = BFA_RPORT_TAG_INVALID;
2323        }
2324
2325        lunm_list[free_index].lp_wwn = *pwwn;
2326        lunm_list[free_index].rp_wwn = rpwwn;
2327        lunm_list[free_index].lun = lun;
2328        lunm_list[free_index].state = BFA_IOIM_LUN_MASK_ACTIVE;
2329
2330        /* set for all luns in this rp */
2331        for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2332                if ((lunm_list[i].lp_wwn == *pwwn) &&
2333                    (lunm_list[i].rp_wwn == rpwwn))
2334                        lunm_list[i].ua = BFA_IOIM_LM_UA_SET;
2335        }
2336
2337        return bfa_dconf_update(bfa);
2338}
2339
2340bfa_status_t
2341bfa_fcpim_lunmask_delete(struct bfa_s *bfa, u16 vf_id, wwn_t *pwwn,
2342                         wwn_t rpwwn, struct scsi_lun lun)
2343{
2344        struct bfa_lun_mask_s   *lunm_list;
2345        struct bfa_rport_s      *rp = NULL;
2346        struct bfa_fcs_lport_s *port = NULL;
2347        struct bfa_fcs_rport_s *rp_fcs;
2348        int     i;
2349
2350        /* in min cfg lunm_list could be NULL but  no commands should run. */
2351        if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_MINCFG)
2352                return BFA_STATUS_FAILED;
2353
2354        bfa_trc(bfa, bfa_get_lun_mask_status(bfa));
2355        bfa_trc(bfa, *pwwn);
2356        bfa_trc(bfa, rpwwn);
2357        bfa_trc(bfa, scsilun_to_int((struct scsi_lun *)&lun));
2358
2359        if (*pwwn == 0) {
2360                port = bfa_fcs_lookup_port(
2361                                &((struct bfad_s *)bfa->bfad)->bfa_fcs,
2362                                vf_id, *pwwn);
2363                if (port) {
2364                        *pwwn = port->port_cfg.pwwn;
2365                        rp_fcs = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
2366                        if (rp_fcs)
2367                                rp = rp_fcs->bfa_rport;
2368                }
2369        }
2370
2371        lunm_list = bfa_get_lun_mask_list(bfa);
2372        for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2373                if ((lunm_list[i].lp_wwn == *pwwn) &&
2374                    (lunm_list[i].rp_wwn == rpwwn) &&
2375                    (scsilun_to_int((struct scsi_lun *)&lunm_list[i].lun) ==
2376                     scsilun_to_int((struct scsi_lun *)&lun))) {
2377                        lunm_list[i].lp_wwn = 0;
2378                        lunm_list[i].rp_wwn = 0;
2379                        int_to_scsilun(0, &lunm_list[i].lun);
2380                        lunm_list[i].state = BFA_IOIM_LUN_MASK_INACTIVE;
2381                        if (lunm_list[i].rp_tag != BFA_RPORT_TAG_INVALID) {
2382                                lunm_list[i].rp_tag = BFA_RPORT_TAG_INVALID;
2383                                lunm_list[i].lp_tag = BFA_LP_TAG_INVALID;
2384                        }
2385                        return bfa_dconf_update(bfa);
2386                }
2387        }
2388
2389        /* set for all luns in this rp */
2390        for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
2391                if ((lunm_list[i].lp_wwn == *pwwn) &&
2392                    (lunm_list[i].rp_wwn == rpwwn))
2393                        lunm_list[i].ua = BFA_IOIM_LM_UA_SET;
2394        }
2395
2396        return BFA_STATUS_ENTRY_NOT_EXISTS;
2397}
2398
2399static void
2400__bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete)
2401{
2402        struct bfa_ioim_s *ioim = cbarg;
2403
2404        if (!complete) {
2405                bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2406                return;
2407        }
2408
2409        bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED,
2410                          0, 0, NULL, 0);
2411}
2412
2413static void
2414__bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete)
2415{
2416        struct bfa_ioim_s *ioim = cbarg;
2417
2418        bfa_stats(ioim->itnim, path_tov_expired);
2419        if (!complete) {
2420                bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2421                return;
2422        }
2423
2424        bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV,
2425                          0, 0, NULL, 0);
2426}
2427
2428static void
2429__bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete)
2430{
2431        struct bfa_ioim_s *ioim = cbarg;
2432
2433        if (!complete) {
2434                bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2435                return;
2436        }
2437
2438        bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio);
2439}
2440
2441static void
2442bfa_ioim_sgpg_alloced(void *cbarg)
2443{
2444        struct bfa_ioim_s *ioim = cbarg;
2445
2446        ioim->nsgpgs = BFA_SGPG_NPAGE(ioim->nsges);
2447        list_splice_tail_init(&ioim->iosp->sgpg_wqe.sgpg_q, &ioim->sgpg_q);
2448        ioim->sgpg = bfa_q_first(&ioim->sgpg_q);
2449        bfa_sm_send_event(ioim, BFA_IOIM_SM_SGALLOCED);
2450}
2451
2452/*
2453 * Send I/O request to firmware.
2454 */
2455static  bfa_boolean_t
2456bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
2457{
2458        struct bfa_itnim_s *itnim = ioim->itnim;
2459        struct bfi_ioim_req_s *m;
2460        static struct fcp_cmnd_s cmnd_z0 = { { { 0 } } };
2461        struct bfi_sge_s *sge, *sgpge;
2462        u32     pgdlen = 0;
2463        u32     fcp_dl;
2464        u64 addr;
2465        struct scatterlist *sg;
2466        struct bfa_sgpg_s *sgpg;
2467        struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio;
2468        u32 i, sge_id, pgcumsz;
2469        enum dma_data_direction dmadir;
2470
2471        /*
2472         * check for room in queue to send request now
2473         */
2474        m = bfa_reqq_next(ioim->bfa, ioim->reqq);
2475        if (!m) {
2476                bfa_stats(ioim->itnim, qwait);
2477                bfa_reqq_wait(ioim->bfa, ioim->reqq,
2478                                  &ioim->iosp->reqq_wait);
2479                return BFA_FALSE;
2480        }
2481
2482        /*
2483         * build i/o request message next
2484         */
2485        m->io_tag = cpu_to_be16(ioim->iotag);
2486        m->rport_hdl = ioim->itnim->rport->fw_handle;
2487        m->io_timeout = 0;
2488
2489        sge = &m->sges[0];
2490        sgpg = ioim->sgpg;
2491        sge_id = 0;
2492        sgpge = NULL;
2493        pgcumsz = 0;
2494        scsi_for_each_sg(cmnd, sg, ioim->nsges, i) {
2495                if (i == 0) {
2496                        /* build inline IO SG element */
2497                        addr = bfa_sgaddr_le(sg_dma_address(sg));
2498                        sge->sga = *(union bfi_addr_u *) &addr;
2499                        pgdlen = sg_dma_len(sg);
2500                        sge->sg_len = pgdlen;
2501                        sge->flags = (ioim->nsges > BFI_SGE_INLINE) ?
2502                                        BFI_SGE_DATA_CPL : BFI_SGE_DATA_LAST;
2503                        bfa_sge_to_be(sge);
2504                        sge++;
2505                } else {
2506                        if (sge_id == 0)
2507                                sgpge = sgpg->sgpg->sges;
2508
2509                        addr = bfa_sgaddr_le(sg_dma_address(sg));
2510                        sgpge->sga = *(union bfi_addr_u *) &addr;
2511                        sgpge->sg_len = sg_dma_len(sg);
2512                        pgcumsz += sgpge->sg_len;
2513
2514                        /* set flags */
2515                        if (i < (ioim->nsges - 1) &&
2516                                        sge_id < (BFI_SGPG_DATA_SGES - 1))
2517                                sgpge->flags = BFI_SGE_DATA;
2518                        else if (i < (ioim->nsges - 1))
2519                                sgpge->flags = BFI_SGE_DATA_CPL;
2520                        else
2521                                sgpge->flags = BFI_SGE_DATA_LAST;
2522
2523                        bfa_sge_to_le(sgpge);
2524
2525                        sgpge++;
2526                        if (i == (ioim->nsges - 1)) {
2527                                sgpge->flags = BFI_SGE_PGDLEN;
2528                                sgpge->sga.a32.addr_lo = 0;
2529                                sgpge->sga.a32.addr_hi = 0;
2530                                sgpge->sg_len = pgcumsz;
2531                                bfa_sge_to_le(sgpge);
2532                        } else if (++sge_id == BFI_SGPG_DATA_SGES) {
2533                                sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg);
2534                                sgpge->flags = BFI_SGE_LINK;
2535                                sgpge->sga = sgpg->sgpg_pa;
2536                                sgpge->sg_len = pgcumsz;
2537                                bfa_sge_to_le(sgpge);
2538                                sge_id = 0;
2539                                pgcumsz = 0;
2540                        }
2541                }
2542        }
2543
2544        if (ioim->nsges > BFI_SGE_INLINE) {
2545                sge->sga = ioim->sgpg->sgpg_pa;
2546        } else {
2547                sge->sga.a32.addr_lo = 0;
2548                sge->sga.a32.addr_hi = 0;
2549        }
2550        sge->sg_len = pgdlen;
2551        sge->flags = BFI_SGE_PGDLEN;
2552        bfa_sge_to_be(sge);
2553
2554        /*
2555         * set up I/O command parameters
2556         */
2557        m->cmnd = cmnd_z0;
2558        int_to_scsilun(cmnd->device->lun, &m->cmnd.lun);
2559        dmadir = cmnd->sc_data_direction;
2560        if (dmadir == DMA_TO_DEVICE)
2561                m->cmnd.iodir = FCP_IODIR_WRITE;
2562        else if (dmadir == DMA_FROM_DEVICE)
2563                m->cmnd.iodir = FCP_IODIR_READ;
2564        else
2565                m->cmnd.iodir = FCP_IODIR_NONE;
2566
2567        m->cmnd.cdb = *(struct scsi_cdb_s *) cmnd->cmnd;
2568        fcp_dl = scsi_bufflen(cmnd);
2569        m->cmnd.fcp_dl = cpu_to_be32(fcp_dl);
2570
2571        /*
2572         * set up I/O message header
2573         */
2574        switch (m->cmnd.iodir) {
2575        case FCP_IODIR_READ:
2576                bfi_h2i_set(m->mh, BFI_MC_IOIM_READ, 0, bfa_fn_lpu(ioim->bfa));
2577                bfa_stats(itnim, input_reqs);
2578                ioim->itnim->stats.rd_throughput += fcp_dl;
2579                break;
2580        case FCP_IODIR_WRITE:
2581                bfi_h2i_set(m->mh, BFI_MC_IOIM_WRITE, 0, bfa_fn_lpu(ioim->bfa));
2582                bfa_stats(itnim, output_reqs);
2583                ioim->itnim->stats.wr_throughput += fcp_dl;
2584                break;
2585        case FCP_IODIR_RW:
2586                bfa_stats(itnim, input_reqs);
2587                bfa_stats(itnim, output_reqs);
2588        default:
2589                bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_fn_lpu(ioim->bfa));
2590        }
2591        if (itnim->seq_rec ||
2592            (scsi_bufflen(cmnd) & (sizeof(u32) - 1)))
2593                bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_fn_lpu(ioim->bfa));
2594
2595        /*
2596         * queue I/O message to firmware
2597         */
2598        bfa_reqq_produce(ioim->bfa, ioim->reqq, m->mh);
2599        return BFA_TRUE;
2600}
2601
2602/*
2603 * Setup any additional SG pages needed.Inline SG element is setup
2604 * at queuing time.
2605 */
2606static bfa_boolean_t
2607bfa_ioim_sgpg_alloc(struct bfa_ioim_s *ioim)
2608{
2609        u16     nsgpgs;
2610
2611        WARN_ON(ioim->nsges <= BFI_SGE_INLINE);
2612
2613        /*
2614         * allocate SG pages needed
2615         */
2616        nsgpgs = BFA_SGPG_NPAGE(ioim->nsges);
2617        if (!nsgpgs)
2618                return BFA_TRUE;
2619
2620        if (bfa_sgpg_malloc(ioim->bfa, &ioim->sgpg_q, nsgpgs)
2621            != BFA_STATUS_OK) {
2622                bfa_sgpg_wait(ioim->bfa, &ioim->iosp->sgpg_wqe, nsgpgs);
2623                return BFA_FALSE;
2624        }
2625
2626        ioim->nsgpgs = nsgpgs;
2627        ioim->sgpg = bfa_q_first(&ioim->sgpg_q);
2628
2629        return BFA_TRUE;
2630}
2631
2632/*
2633 * Send I/O abort request to firmware.
2634 */
2635static  bfa_boolean_t
2636bfa_ioim_send_abort(struct bfa_ioim_s *ioim)
2637{
2638        struct bfi_ioim_abort_req_s *m;
2639        enum bfi_ioim_h2i       msgop;
2640
2641        /*
2642         * check for room in queue to send request now
2643         */
2644        m = bfa_reqq_next(ioim->bfa, ioim->reqq);
2645        if (!m)
2646                return BFA_FALSE;
2647
2648        /*
2649         * build i/o request message next
2650         */
2651        if (ioim->iosp->abort_explicit)
2652                msgop = BFI_IOIM_H2I_IOABORT_REQ;
2653        else
2654                msgop = BFI_IOIM_H2I_IOCLEANUP_REQ;
2655
2656        bfi_h2i_set(m->mh, BFI_MC_IOIM, msgop, bfa_fn_lpu(ioim->bfa));
2657        m->io_tag    = cpu_to_be16(ioim->iotag);
2658        m->abort_tag = ++ioim->abort_tag;
2659
2660        /*
2661         * queue I/O message to firmware
2662         */
2663        bfa_reqq_produce(ioim->bfa, ioim->reqq, m->mh);
2664        return BFA_TRUE;
2665}
2666
2667/*
2668 * Call to resume any I/O requests waiting for room in request queue.
2669 */
2670static void
2671bfa_ioim_qresume(void *cbarg)
2672{
2673        struct bfa_ioim_s *ioim = cbarg;
2674
2675        bfa_stats(ioim->itnim, qresumes);
2676        bfa_sm_send_event(ioim, BFA_IOIM_SM_QRESUME);
2677}
2678
2679
2680static void
2681bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim)
2682{
2683        /*
2684         * Move IO from itnim queue to fcpim global queue since itnim will be
2685         * freed.
2686         */
2687        list_del(&ioim->qe);
2688        list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
2689
2690        if (!ioim->iosp->tskim) {
2691                if (ioim->fcpim->delay_comp && ioim->itnim->iotov_active) {
2692                        bfa_cb_dequeue(&ioim->hcb_qe);
2693                        list_del(&ioim->qe);
2694                        list_add_tail(&ioim->qe, &ioim->itnim->delay_comp_q);
2695                }
2696                bfa_itnim_iodone(ioim->itnim);
2697        } else
2698                bfa_wc_down(&ioim->iosp->tskim->wc);
2699}
2700
2701static bfa_boolean_t
2702bfa_ioim_is_abortable(struct bfa_ioim_s *ioim)
2703{
2704        if ((bfa_sm_cmp_state(ioim, bfa_ioim_sm_uninit) &&
2705            (!bfa_q_is_on_q(&ioim->itnim->pending_q, ioim)))    ||
2706            (bfa_sm_cmp_state(ioim, bfa_ioim_sm_abort))         ||
2707            (bfa_sm_cmp_state(ioim, bfa_ioim_sm_abort_qfull))   ||
2708            (bfa_sm_cmp_state(ioim, bfa_ioim_sm_hcb))           ||
2709            (bfa_sm_cmp_state(ioim, bfa_ioim_sm_hcb_free))      ||
2710            (bfa_sm_cmp_state(ioim, bfa_ioim_sm_resfree)))
2711                return BFA_FALSE;
2712
2713        return BFA_TRUE;
2714}
2715
2716void
2717bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov)
2718{
2719        /*
2720         * If path tov timer expired, failback with PATHTOV status - these
2721         * IO requests are not normally retried by IO stack.
2722         *
2723         * Otherwise device cameback online and fail it with normal failed
2724         * status so that IO stack retries these failed IO requests.
2725         */
2726        if (iotov)
2727                ioim->io_cbfn = __bfa_cb_ioim_pathtov;
2728        else {
2729                ioim->io_cbfn = __bfa_cb_ioim_failed;
2730                bfa_stats(ioim->itnim, iocom_nexus_abort);
2731        }
2732        bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
2733
2734        /*
2735         * Move IO to fcpim global queue since itnim will be
2736         * freed.
2737         */
2738        list_del(&ioim->qe);
2739        list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
2740}
2741
2742
2743/*
2744 * Memory allocation and initialization.
2745 */
2746void
2747bfa_ioim_attach(struct bfa_fcpim_s *fcpim)
2748{
2749        struct bfa_ioim_s               *ioim;
2750        struct bfa_fcp_mod_s    *fcp = fcpim->fcp;
2751        struct bfa_ioim_sp_s    *iosp;
2752        u16             i;
2753
2754        /*
2755         * claim memory first
2756         */
2757        ioim = (struct bfa_ioim_s *) bfa_mem_kva_curp(fcp);
2758        fcpim->ioim_arr = ioim;
2759        bfa_mem_kva_curp(fcp) = (u8 *) (ioim + fcpim->fcp->num_ioim_reqs);
2760
2761        iosp = (struct bfa_ioim_sp_s *) bfa_mem_kva_curp(fcp);
2762        fcpim->ioim_sp_arr = iosp;
2763        bfa_mem_kva_curp(fcp) = (u8 *) (iosp + fcpim->fcp->num_ioim_reqs);
2764
2765        /*
2766         * Initialize ioim free queues
2767         */
2768        INIT_LIST_HEAD(&fcpim->ioim_resfree_q);
2769        INIT_LIST_HEAD(&fcpim->ioim_comp_q);
2770
2771        for (i = 0; i < fcpim->fcp->num_ioim_reqs;
2772             i++, ioim++, iosp++) {
2773                /*
2774                 * initialize IOIM
2775                 */
2776                memset(ioim, 0, sizeof(struct bfa_ioim_s));
2777                ioim->iotag   = i;
2778                ioim->bfa     = fcpim->bfa;
2779                ioim->fcpim   = fcpim;
2780                ioim->iosp    = iosp;
2781                INIT_LIST_HEAD(&ioim->sgpg_q);
2782                bfa_reqq_winit(&ioim->iosp->reqq_wait,
2783                                   bfa_ioim_qresume, ioim);
2784                bfa_sgpg_winit(&ioim->iosp->sgpg_wqe,
2785                                   bfa_ioim_sgpg_alloced, ioim);
2786                bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
2787        }
2788}
2789
2790void
2791bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2792{
2793        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
2794        struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m;
2795        struct bfa_ioim_s *ioim;
2796        u16     iotag;
2797        enum bfa_ioim_event evt = BFA_IOIM_SM_COMP;
2798
2799        iotag = be16_to_cpu(rsp->io_tag);
2800
2801        ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
2802        WARN_ON(ioim->iotag != iotag);
2803
2804        bfa_trc(ioim->bfa, ioim->iotag);
2805        bfa_trc(ioim->bfa, rsp->io_status);
2806        bfa_trc(ioim->bfa, rsp->reuse_io_tag);
2807
2808        if (bfa_sm_cmp_state(ioim, bfa_ioim_sm_active))
2809                ioim->iosp->comp_rspmsg = *m;
2810
2811        switch (rsp->io_status) {
2812        case BFI_IOIM_STS_OK:
2813                bfa_stats(ioim->itnim, iocomp_ok);
2814                if (rsp->reuse_io_tag == 0)
2815                        evt = BFA_IOIM_SM_DONE;
2816                else
2817                        evt = BFA_IOIM_SM_COMP;
2818                break;
2819
2820        case BFI_IOIM_STS_TIMEDOUT:
2821                bfa_stats(ioim->itnim, iocomp_timedout);
2822        case BFI_IOIM_STS_ABORTED:
2823                rsp->io_status = BFI_IOIM_STS_ABORTED;
2824                bfa_stats(ioim->itnim, iocomp_aborted);
2825                if (rsp->reuse_io_tag == 0)
2826                        evt = BFA_IOIM_SM_DONE;
2827                else
2828                        evt = BFA_IOIM_SM_COMP;
2829                break;
2830
2831        case BFI_IOIM_STS_PROTO_ERR:
2832                bfa_stats(ioim->itnim, iocom_proto_err);
2833                WARN_ON(!rsp->reuse_io_tag);
2834                evt = BFA_IOIM_SM_COMP;
2835                break;
2836
2837        case BFI_IOIM_STS_SQER_NEEDED:
2838                bfa_stats(ioim->itnim, iocom_sqer_needed);
2839                WARN_ON(rsp->reuse_io_tag != 0);
2840                evt = BFA_IOIM_SM_SQRETRY;
2841                break;
2842
2843        case BFI_IOIM_STS_RES_FREE:
2844                bfa_stats(ioim->itnim, iocom_res_free);
2845                evt = BFA_IOIM_SM_FREE;
2846                break;
2847
2848        case BFI_IOIM_STS_HOST_ABORTED:
2849                bfa_stats(ioim->itnim, iocom_hostabrts);
2850                if (rsp->abort_tag != ioim->abort_tag) {
2851                        bfa_trc(ioim->bfa, rsp->abort_tag);
2852                        bfa_trc(ioim->bfa, ioim->abort_tag);
2853                        return;
2854                }
2855
2856                if (rsp->reuse_io_tag)
2857                        evt = BFA_IOIM_SM_ABORT_COMP;
2858                else
2859                        evt = BFA_IOIM_SM_ABORT_DONE;
2860                break;
2861
2862        case BFI_IOIM_STS_UTAG:
2863                bfa_stats(ioim->itnim, iocom_utags);
2864                evt = BFA_IOIM_SM_COMP_UTAG;
2865                break;
2866
2867        default:
2868                WARN_ON(1);
2869        }
2870
2871        bfa_sm_send_event(ioim, evt);
2872}
2873
2874void
2875bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2876{
2877        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
2878        struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m;
2879        struct bfa_ioim_s *ioim;
2880        u16     iotag;
2881
2882        iotag = be16_to_cpu(rsp->io_tag);
2883
2884        ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
2885        WARN_ON(ioim->iotag != iotag);
2886
2887        bfa_ioim_cb_profile_comp(fcpim, ioim);
2888
2889        bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD);
2890}
2891
2892/*
2893 * Called by itnim to clean up IO while going offline.
2894 */
2895void
2896bfa_ioim_cleanup(struct bfa_ioim_s *ioim)
2897{
2898        bfa_trc(ioim->bfa, ioim->iotag);
2899        bfa_stats(ioim->itnim, io_cleanups);
2900
2901        ioim->iosp->tskim = NULL;
2902        bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP);
2903}
2904
2905void
2906bfa_ioim_cleanup_tm(struct bfa_ioim_s *ioim, struct bfa_tskim_s *tskim)
2907{
2908        bfa_trc(ioim->bfa, ioim->iotag);
2909        bfa_stats(ioim->itnim, io_tmaborts);
2910
2911        ioim->iosp->tskim = tskim;
2912        bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP);
2913}
2914
2915/*
2916 * IOC failure handling.
2917 */
2918void
2919bfa_ioim_iocdisable(struct bfa_ioim_s *ioim)
2920{
2921        bfa_trc(ioim->bfa, ioim->iotag);
2922        bfa_stats(ioim->itnim, io_iocdowns);
2923        bfa_sm_send_event(ioim, BFA_IOIM_SM_HWFAIL);
2924}
2925
2926/*
2927 * IO offline TOV popped. Fail the pending IO.
2928 */
2929void
2930bfa_ioim_tov(struct bfa_ioim_s *ioim)
2931{
2932        bfa_trc(ioim->bfa, ioim->iotag);
2933        bfa_sm_send_event(ioim, BFA_IOIM_SM_IOTOV);
2934}
2935
2936
2937/*
2938 * Allocate IOIM resource for initiator mode I/O request.
2939 */
2940struct bfa_ioim_s *
2941bfa_ioim_alloc(struct bfa_s *bfa, struct bfad_ioim_s *dio,
2942                struct bfa_itnim_s *itnim, u16 nsges)
2943{
2944        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
2945        struct bfa_ioim_s *ioim;
2946        struct bfa_iotag_s *iotag = NULL;
2947
2948        /*
2949         * alocate IOIM resource
2950         */
2951        bfa_q_deq(&fcpim->fcp->iotag_ioim_free_q, &iotag);
2952        if (!iotag) {
2953                bfa_stats(itnim, no_iotags);
2954                return NULL;
2955        }
2956
2957        ioim = BFA_IOIM_FROM_TAG(fcpim, iotag->tag);
2958
2959        ioim->dio = dio;
2960        ioim->itnim = itnim;
2961        ioim->nsges = nsges;
2962        ioim->nsgpgs = 0;
2963
2964        bfa_stats(itnim, total_ios);
2965        fcpim->ios_active++;
2966
2967        list_add_tail(&ioim->qe, &itnim->io_q);
2968
2969        return ioim;
2970}
2971
2972void
2973bfa_ioim_free(struct bfa_ioim_s *ioim)
2974{
2975        struct bfa_fcpim_s *fcpim = ioim->fcpim;
2976        struct bfa_iotag_s *iotag;
2977
2978        if (ioim->nsgpgs > 0)
2979                bfa_sgpg_mfree(ioim->bfa, &ioim->sgpg_q, ioim->nsgpgs);
2980
2981        bfa_stats(ioim->itnim, io_comps);
2982        fcpim->ios_active--;
2983
2984        ioim->iotag &= BFA_IOIM_IOTAG_MASK;
2985
2986        WARN_ON(!(ioim->iotag <
2987                (fcpim->fcp->num_ioim_reqs + fcpim->fcp->num_fwtio_reqs)));
2988        iotag = BFA_IOTAG_FROM_TAG(fcpim->fcp, ioim->iotag);
2989
2990        if (ioim->iotag < fcpim->fcp->num_ioim_reqs)
2991                list_add_tail(&iotag->qe, &fcpim->fcp->iotag_ioim_free_q);
2992        else
2993                list_add_tail(&iotag->qe, &fcpim->fcp->iotag_tio_free_q);
2994
2995        list_del(&ioim->qe);
2996}
2997
2998void
2999bfa_ioim_start(struct bfa_ioim_s *ioim)
3000{
3001        bfa_ioim_cb_profile_start(ioim->fcpim, ioim);
3002
3003        /*
3004         * Obtain the queue over which this request has to be issued
3005         */
3006        ioim->reqq = bfa_fcpim_ioredirect_enabled(ioim->bfa) ?
3007                        BFA_FALSE : bfa_itnim_get_reqq(ioim);
3008
3009        bfa_sm_send_event(ioim, BFA_IOIM_SM_START);
3010}
3011
3012/*
3013 * Driver I/O abort request.
3014 */
3015bfa_status_t
3016bfa_ioim_abort(struct bfa_ioim_s *ioim)
3017{
3018
3019        bfa_trc(ioim->bfa, ioim->iotag);
3020
3021        if (!bfa_ioim_is_abortable(ioim))
3022                return BFA_STATUS_FAILED;
3023
3024        bfa_stats(ioim->itnim, io_aborts);
3025        bfa_sm_send_event(ioim, BFA_IOIM_SM_ABORT);
3026
3027        return BFA_STATUS_OK;
3028}
3029
3030/*
3031 *  BFA TSKIM state machine functions
3032 */
3033
3034/*
3035 * Task management command beginning state.
3036 */
3037static void
3038bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3039{
3040        bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3041
3042        switch (event) {
3043        case BFA_TSKIM_SM_START:
3044                bfa_sm_set_state(tskim, bfa_tskim_sm_active);
3045                bfa_tskim_gather_ios(tskim);
3046
3047                /*
3048                 * If device is offline, do not send TM on wire. Just cleanup
3049                 * any pending IO requests and complete TM request.
3050                 */
3051                if (!bfa_itnim_is_online(tskim->itnim)) {
3052                        bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
3053                        tskim->tsk_status = BFI_TSKIM_STS_OK;
3054                        bfa_tskim_cleanup_ios(tskim);
3055                        return;
3056                }
3057
3058                if (!bfa_tskim_send(tskim)) {
3059                        bfa_sm_set_state(tskim, bfa_tskim_sm_qfull);
3060                        bfa_stats(tskim->itnim, tm_qwait);
3061                        bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq,
3062                                          &tskim->reqq_wait);
3063                }
3064                break;
3065
3066        default:
3067                bfa_sm_fault(tskim->bfa, event);
3068        }
3069}
3070
3071/*
3072 * TM command is active, awaiting completion from firmware to
3073 * cleanup IO requests in TM scope.
3074 */
3075static void
3076bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3077{
3078        bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3079
3080        switch (event) {
3081        case BFA_TSKIM_SM_DONE:
3082                bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
3083                bfa_tskim_cleanup_ios(tskim);
3084                break;
3085
3086        case BFA_TSKIM_SM_CLEANUP:
3087                bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup);
3088                if (!bfa_tskim_send_abort(tskim)) {
3089                        bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup_qfull);
3090                        bfa_stats(tskim->itnim, tm_qwait);
3091                        bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq,
3092                                &tskim->reqq_wait);
3093                }
3094                break;
3095
3096        case BFA_TSKIM_SM_HWFAIL:
3097                bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3098                bfa_tskim_iocdisable_ios(tskim);
3099                bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3100                break;
3101
3102        default:
3103                bfa_sm_fault(tskim->bfa, event);
3104        }
3105}
3106
3107/*
3108 * An active TM is being cleaned up since ITN is offline. Awaiting cleanup
3109 * completion event from firmware.
3110 */
3111static void
3112bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3113{
3114        bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3115
3116        switch (event) {
3117        case BFA_TSKIM_SM_DONE:
3118                /*
3119                 * Ignore and wait for ABORT completion from firmware.
3120                 */
3121                break;
3122
3123        case BFA_TSKIM_SM_UTAG:
3124        case BFA_TSKIM_SM_CLEANUP_DONE:
3125                bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
3126                bfa_tskim_cleanup_ios(tskim);
3127                break;
3128
3129        case BFA_TSKIM_SM_HWFAIL:
3130                bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3131                bfa_tskim_iocdisable_ios(tskim);
3132                bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3133                break;
3134
3135        default:
3136                bfa_sm_fault(tskim->bfa, event);
3137        }
3138}
3139
3140static void
3141bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3142{
3143        bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3144
3145        switch (event) {
3146        case BFA_TSKIM_SM_IOS_DONE:
3147                bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3148                bfa_tskim_qcomp(tskim, __bfa_cb_tskim_done);
3149                break;
3150
3151        case BFA_TSKIM_SM_CLEANUP:
3152                /*
3153                 * Ignore, TM command completed on wire.
3154                 * Notify TM conmpletion on IO cleanup completion.
3155                 */
3156                break;
3157
3158        case BFA_TSKIM_SM_HWFAIL:
3159                bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3160                bfa_tskim_iocdisable_ios(tskim);
3161                bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3162                break;
3163
3164        default:
3165                bfa_sm_fault(tskim->bfa, event);
3166        }
3167}
3168
3169/*
3170 * Task management command is waiting for room in request CQ
3171 */
3172static void
3173bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3174{
3175        bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3176
3177        switch (event) {
3178        case BFA_TSKIM_SM_QRESUME:
3179                bfa_sm_set_state(tskim, bfa_tskim_sm_active);
3180                bfa_tskim_send(tskim);
3181                break;
3182
3183        case BFA_TSKIM_SM_CLEANUP:
3184                /*
3185                 * No need to send TM on wire since ITN is offline.
3186                 */
3187                bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
3188                bfa_reqq_wcancel(&tskim->reqq_wait);
3189                bfa_tskim_cleanup_ios(tskim);
3190                break;
3191
3192        case BFA_TSKIM_SM_HWFAIL:
3193                bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3194                bfa_reqq_wcancel(&tskim->reqq_wait);
3195                bfa_tskim_iocdisable_ios(tskim);
3196                bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3197                break;
3198
3199        default:
3200                bfa_sm_fault(tskim->bfa, event);
3201        }
3202}
3203
3204/*
3205 * Task management command is active, awaiting for room in request CQ
3206 * to send clean up request.
3207 */
3208static void
3209bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
3210                enum bfa_tskim_event event)
3211{
3212        bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3213
3214        switch (event) {
3215        case BFA_TSKIM_SM_DONE:
3216                bfa_reqq_wcancel(&tskim->reqq_wait);
3217                /*
3218                 * Fall through !!!
3219                 */
3220        case BFA_TSKIM_SM_QRESUME:
3221                bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup);
3222                bfa_tskim_send_abort(tskim);
3223                break;
3224
3225        case BFA_TSKIM_SM_HWFAIL:
3226                bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3227                bfa_reqq_wcancel(&tskim->reqq_wait);
3228                bfa_tskim_iocdisable_ios(tskim);
3229                bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3230                break;
3231
3232        default:
3233                bfa_sm_fault(tskim->bfa, event);
3234        }
3235}
3236
3237/*
3238 * BFA callback is pending
3239 */
3240static void
3241bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3242{
3243        bfa_trc(tskim->bfa, tskim->tsk_tag << 16 | event);
3244
3245        switch (event) {
3246        case BFA_TSKIM_SM_HCB:
3247                bfa_sm_set_state(tskim, bfa_tskim_sm_uninit);
3248                bfa_tskim_free(tskim);
3249                break;
3250
3251        case BFA_TSKIM_SM_CLEANUP:
3252                bfa_tskim_notify_comp(tskim);
3253                break;
3254
3255        case BFA_TSKIM_SM_HWFAIL:
3256                break;
3257
3258        default:
3259                bfa_sm_fault(tskim->bfa, event);
3260        }
3261}
3262
3263static void
3264__bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete)
3265{
3266        struct bfa_tskim_s *tskim = cbarg;
3267
3268        if (!complete) {
3269                bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB);
3270                return;
3271        }
3272
3273        bfa_stats(tskim->itnim, tm_success);
3274        bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk, tskim->tsk_status);
3275}
3276
3277static void
3278__bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete)
3279{
3280        struct bfa_tskim_s *tskim = cbarg;
3281
3282        if (!complete) {
3283                bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB);
3284                return;
3285        }
3286
3287        bfa_stats(tskim->itnim, tm_failures);
3288        bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk,
3289                                BFI_TSKIM_STS_FAILED);
3290}
3291
3292static bfa_boolean_t
3293bfa_tskim_match_scope(struct bfa_tskim_s *tskim, struct scsi_lun lun)
3294{
3295        switch (tskim->tm_cmnd) {
3296        case FCP_TM_TARGET_RESET:
3297                return BFA_TRUE;
3298
3299        case FCP_TM_ABORT_TASK_SET:
3300        case FCP_TM_CLEAR_TASK_SET:
3301        case FCP_TM_LUN_RESET:
3302        case FCP_TM_CLEAR_ACA:
3303                return !memcmp(&tskim->lun, &lun, sizeof(lun));
3304
3305        default:
3306                WARN_ON(1);
3307        }
3308
3309        return BFA_FALSE;
3310}
3311
3312/*
3313 * Gather affected IO requests and task management commands.
3314 */
3315static void
3316bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
3317{
3318        struct bfa_itnim_s *itnim = tskim->itnim;
3319        struct bfa_ioim_s *ioim;
3320        struct list_head *qe, *qen;
3321        struct scsi_cmnd *cmnd;
3322        struct scsi_lun scsilun;
3323
3324        INIT_LIST_HEAD(&tskim->io_q);
3325
3326        /*
3327         * Gather any active IO requests first.
3328         */
3329        list_for_each_safe(qe, qen, &itnim->io_q) {
3330                ioim = (struct bfa_ioim_s *) qe;
3331                cmnd = (struct scsi_cmnd *) ioim->dio;
3332                int_to_scsilun(cmnd->device->lun, &scsilun);
3333                if (bfa_tskim_match_scope(tskim, scsilun)) {
3334                        list_del(&ioim->qe);
3335                        list_add_tail(&ioim->qe, &tskim->io_q);
3336                }
3337        }
3338
3339        /*
3340         * Failback any pending IO requests immediately.
3341         */
3342        list_for_each_safe(qe, qen, &itnim->pending_q) {
3343                ioim = (struct bfa_ioim_s *) qe;
3344                cmnd = (struct scsi_cmnd *) ioim->dio;
3345                int_to_scsilun(cmnd->device->lun, &scsilun);
3346                if (bfa_tskim_match_scope(tskim, scsilun)) {
3347                        list_del(&ioim->qe);
3348                        list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
3349                        bfa_ioim_tov(ioim);
3350                }
3351        }
3352}
3353
3354/*
3355 * IO cleanup completion
3356 */
3357static void
3358bfa_tskim_cleanp_comp(void *tskim_cbarg)
3359{
3360        struct bfa_tskim_s *tskim = tskim_cbarg;
3361
3362        bfa_stats(tskim->itnim, tm_io_comps);
3363        bfa_sm_send_event(tskim, BFA_TSKIM_SM_IOS_DONE);
3364}
3365
3366/*
3367 * Gather affected IO requests and task management commands.
3368 */
3369static void
3370bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim)
3371{
3372        struct bfa_ioim_s *ioim;
3373        struct list_head        *qe, *qen;
3374
3375        bfa_wc_init(&tskim->wc, bfa_tskim_cleanp_comp, tskim);
3376
3377        list_for_each_safe(qe, qen, &tskim->io_q) {
3378                ioim = (struct bfa_ioim_s *) qe;
3379                bfa_wc_up(&tskim->wc);
3380                bfa_ioim_cleanup_tm(ioim, tskim);
3381        }
3382
3383        bfa_wc_wait(&tskim->wc);
3384}
3385
3386/*
3387 * Send task management request to firmware.
3388 */
3389static bfa_boolean_t
3390bfa_tskim_send(struct bfa_tskim_s *tskim)
3391{
3392        struct bfa_itnim_s *itnim = tskim->itnim;
3393        struct bfi_tskim_req_s *m;
3394
3395        /*
3396         * check for room in queue to send request now
3397         */
3398        m = bfa_reqq_next(tskim->bfa, itnim->reqq);
3399        if (!m)
3400                return BFA_FALSE;
3401
3402        /*
3403         * build i/o request message next
3404         */
3405        bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_TM_REQ,
3406                        bfa_fn_lpu(tskim->bfa));
3407
3408        m->tsk_tag = cpu_to_be16(tskim->tsk_tag);
3409        m->itn_fhdl = tskim->itnim->rport->fw_handle;
3410        m->t_secs = tskim->tsecs;
3411        m->lun = tskim->lun;
3412        m->tm_flags = tskim->tm_cmnd;
3413
3414        /*
3415         * queue I/O message to firmware
3416         */
3417        bfa_reqq_produce(tskim->bfa, itnim->reqq, m->mh);
3418        return BFA_TRUE;
3419}
3420
3421/*
3422 * Send abort request to cleanup an active TM to firmware.
3423 */
3424static bfa_boolean_t
3425bfa_tskim_send_abort(struct bfa_tskim_s *tskim)
3426{
3427        struct bfa_itnim_s      *itnim = tskim->itnim;
3428        struct bfi_tskim_abortreq_s     *m;
3429
3430        /*
3431         * check for room in queue to send request now
3432         */
3433        m = bfa_reqq_next(tskim->bfa, itnim->reqq);
3434        if (!m)
3435                return BFA_FALSE;
3436
3437        /*
3438         * build i/o request message next
3439         */
3440        bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_ABORT_REQ,
3441                        bfa_fn_lpu(tskim->bfa));
3442
3443        m->tsk_tag  = cpu_to_be16(tskim->tsk_tag);
3444
3445        /*
3446         * queue I/O message to firmware
3447         */
3448        bfa_reqq_produce(tskim->bfa, itnim->reqq, m->mh);
3449        return BFA_TRUE;
3450}
3451
3452/*
3453 * Call to resume task management cmnd waiting for room in request queue.
3454 */
3455static void
3456bfa_tskim_qresume(void *cbarg)
3457{
3458        struct bfa_tskim_s *tskim = cbarg;
3459
3460        bfa_stats(tskim->itnim, tm_qresumes);
3461        bfa_sm_send_event(tskim, BFA_TSKIM_SM_QRESUME);
3462}
3463
3464/*
3465 * Cleanup IOs associated with a task mangement command on IOC failures.
3466 */
3467static void
3468bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim)
3469{
3470        struct bfa_ioim_s *ioim;
3471        struct list_head        *qe, *qen;
3472
3473        list_for_each_safe(qe, qen, &tskim->io_q) {
3474                ioim = (struct bfa_ioim_s *) qe;
3475                bfa_ioim_iocdisable(ioim);
3476        }
3477}
3478
3479/*
3480 * Notification on completions from related ioim.
3481 */
3482void
3483bfa_tskim_iodone(struct bfa_tskim_s *tskim)
3484{
3485        bfa_wc_down(&tskim->wc);
3486}
3487
3488/*
3489 * Handle IOC h/w failure notification from itnim.
3490 */
3491void
3492bfa_tskim_iocdisable(struct bfa_tskim_s *tskim)
3493{
3494        tskim->notify = BFA_FALSE;
3495        bfa_stats(tskim->itnim, tm_iocdowns);
3496        bfa_sm_send_event(tskim, BFA_TSKIM_SM_HWFAIL);
3497}
3498
3499/*
3500 * Cleanup TM command and associated IOs as part of ITNIM offline.
3501 */
3502void
3503bfa_tskim_cleanup(struct bfa_tskim_s *tskim)
3504{
3505        tskim->notify = BFA_TRUE;
3506        bfa_stats(tskim->itnim, tm_cleanups);
3507        bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP);
3508}
3509
3510/*
3511 * Memory allocation and initialization.
3512 */
3513void
3514bfa_tskim_attach(struct bfa_fcpim_s *fcpim)
3515{
3516        struct bfa_tskim_s *tskim;
3517        struct bfa_fcp_mod_s    *fcp = fcpim->fcp;
3518        u16     i;
3519
3520        INIT_LIST_HEAD(&fcpim->tskim_free_q);
3521        INIT_LIST_HEAD(&fcpim->tskim_unused_q);
3522
3523        tskim = (struct bfa_tskim_s *) bfa_mem_kva_curp(fcp);
3524        fcpim->tskim_arr = tskim;
3525
3526        for (i = 0; i < fcpim->num_tskim_reqs; i++, tskim++) {
3527                /*
3528                 * initialize TSKIM
3529                 */
3530                memset(tskim, 0, sizeof(struct bfa_tskim_s));
3531                tskim->tsk_tag = i;
3532                tskim->bfa      = fcpim->bfa;
3533                tskim->fcpim    = fcpim;
3534                tskim->notify  = BFA_FALSE;
3535                bfa_reqq_winit(&tskim->reqq_wait, bfa_tskim_qresume,
3536                                        tskim);
3537                bfa_sm_set_state(tskim, bfa_tskim_sm_uninit);
3538
3539                list_add_tail(&tskim->qe, &fcpim->tskim_free_q);
3540        }
3541
3542        bfa_mem_kva_curp(fcp) = (u8 *) tskim;
3543}
3544
3545void
3546bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
3547{
3548        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
3549        struct bfi_tskim_rsp_s *rsp = (struct bfi_tskim_rsp_s *) m;
3550        struct bfa_tskim_s *tskim;
3551        u16     tsk_tag = be16_to_cpu(rsp->tsk_tag);
3552
3553        tskim = BFA_TSKIM_FROM_TAG(fcpim, tsk_tag);
3554        WARN_ON(tskim->tsk_tag != tsk_tag);
3555
3556        tskim->tsk_status = rsp->tsk_status;
3557
3558        /*
3559         * Firmware sends BFI_TSKIM_STS_ABORTED status for abort
3560         * requests. All other statuses are for normal completions.
3561         */
3562        if (rsp->tsk_status == BFI_TSKIM_STS_ABORTED) {
3563                bfa_stats(tskim->itnim, tm_cleanup_comps);
3564                bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP_DONE);
3565        } else if (rsp->tsk_status == BFI_TSKIM_STS_UTAG) {
3566                bfa_sm_send_event(tskim, BFA_TSKIM_SM_UTAG);
3567        } else {
3568                bfa_stats(tskim->itnim, tm_fw_rsps);
3569                bfa_sm_send_event(tskim, BFA_TSKIM_SM_DONE);
3570        }
3571}
3572
3573
3574struct bfa_tskim_s *
3575bfa_tskim_alloc(struct bfa_s *bfa, struct bfad_tskim_s *dtsk)
3576{
3577        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
3578        struct bfa_tskim_s *tskim;
3579
3580        bfa_q_deq(&fcpim->tskim_free_q, &tskim);
3581
3582        if (tskim)
3583                tskim->dtsk = dtsk;
3584
3585        return tskim;
3586}
3587
3588void
3589bfa_tskim_free(struct bfa_tskim_s *tskim)
3590{
3591        WARN_ON(!bfa_q_is_on_q_func(&tskim->itnim->tsk_q, &tskim->qe));
3592        list_del(&tskim->qe);
3593        list_add_tail(&tskim->qe, &tskim->fcpim->tskim_free_q);
3594}
3595
3596/*
3597 * Start a task management command.
3598 *
3599 * @param[in]   tskim   BFA task management command instance
3600 * @param[in]   itnim   i-t nexus for the task management command
3601 * @param[in]   lun     lun, if applicable
3602 * @param[in]   tm_cmnd Task management command code.
3603 * @param[in]   t_secs  Timeout in seconds
3604 *
3605 * @return None.
3606 */
3607void
3608bfa_tskim_start(struct bfa_tskim_s *tskim, struct bfa_itnim_s *itnim,
3609                        struct scsi_lun lun,
3610                        enum fcp_tm_cmnd tm_cmnd, u8 tsecs)
3611{
3612        tskim->itnim    = itnim;
3613        tskim->lun      = lun;
3614        tskim->tm_cmnd = tm_cmnd;
3615        tskim->tsecs    = tsecs;
3616        tskim->notify  = BFA_FALSE;
3617        bfa_stats(itnim, tm_cmnds);
3618
3619        list_add_tail(&tskim->qe, &itnim->tsk_q);
3620        bfa_sm_send_event(tskim, BFA_TSKIM_SM_START);
3621}
3622
3623void
3624bfa_tskim_res_recfg(struct bfa_s *bfa, u16 num_tskim_fw)
3625{
3626        struct bfa_fcpim_s      *fcpim = BFA_FCPIM(bfa);
3627        struct list_head        *qe;
3628        int     i;
3629
3630        for (i = 0; i < (fcpim->num_tskim_reqs - num_tskim_fw); i++) {
3631                bfa_q_deq_tail(&fcpim->tskim_free_q, &qe);
3632                list_add_tail(qe, &fcpim->tskim_unused_q);
3633        }
3634}
3635
3636/* BFA FCP module - parent module for fcpim */
3637
3638BFA_MODULE(fcp);
3639
3640static void
3641bfa_fcp_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo,
3642                struct bfa_s *bfa)
3643{
3644        struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
3645        struct bfa_mem_kva_s *fcp_kva = BFA_MEM_FCP_KVA(bfa);
3646        struct bfa_mem_dma_s *seg_ptr;
3647        u16     nsegs, idx, per_seg_ios, num_io_req;
3648        u32     km_len = 0;
3649
3650        /*
3651         * ZERO for num_ioim_reqs and num_fwtio_reqs is allowed config value.
3652         * So if the values are non zero, adjust them appropriately.
3653         */
3654        if (cfg->fwcfg.num_ioim_reqs &&
3655            cfg->fwcfg.num_ioim_reqs < BFA_IOIM_MIN)
3656                cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN;
3657        else if (cfg->fwcfg.num_ioim_reqs > BFA_IOIM_MAX)
3658                cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MAX;
3659
3660        if (cfg->fwcfg.num_fwtio_reqs > BFA_FWTIO_MAX)
3661                cfg->fwcfg.num_fwtio_reqs = BFA_FWTIO_MAX;
3662
3663        num_io_req = (cfg->fwcfg.num_ioim_reqs + cfg->fwcfg.num_fwtio_reqs);
3664        if (num_io_req > BFA_IO_MAX) {
3665                if (cfg->fwcfg.num_ioim_reqs && cfg->fwcfg.num_fwtio_reqs) {
3666                        cfg->fwcfg.num_ioim_reqs = BFA_IO_MAX/2;
3667                        cfg->fwcfg.num_fwtio_reqs = BFA_IO_MAX/2;
3668                } else if (cfg->fwcfg.num_fwtio_reqs)
3669                        cfg->fwcfg.num_fwtio_reqs = BFA_FWTIO_MAX;
3670                else
3671                        cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MAX;
3672        }
3673
3674        bfa_fcpim_meminfo(cfg, &km_len);
3675
3676        num_io_req = (cfg->fwcfg.num_ioim_reqs + cfg->fwcfg.num_fwtio_reqs);
3677        km_len += num_io_req * sizeof(struct bfa_iotag_s);
3678        km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_itn_s);
3679
3680        /* dma memory */
3681        nsegs = BFI_MEM_DMA_NSEGS(num_io_req, BFI_IOIM_SNSLEN);
3682        per_seg_ios = BFI_MEM_NREQS_SEG(BFI_IOIM_SNSLEN);
3683
3684        bfa_mem_dma_seg_iter(fcp, seg_ptr, nsegs, idx) {
3685                if (num_io_req >= per_seg_ios) {
3686                        num_io_req -= per_seg_ios;
3687                        bfa_mem_dma_setup(minfo, seg_ptr,
3688                                per_seg_ios * BFI_IOIM_SNSLEN);
3689                } else
3690                        bfa_mem_dma_setup(minfo, seg_ptr,
3691                                num_io_req * BFI_IOIM_SNSLEN);
3692        }
3693
3694        /* kva memory */
3695        bfa_mem_kva_setup(minfo, fcp_kva, km_len);
3696}
3697
3698static void
3699bfa_fcp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
3700                struct bfa_pcidev_s *pcidev)
3701{
3702        struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
3703        struct bfa_mem_dma_s *seg_ptr;
3704        u16     idx, nsegs, num_io_req;
3705
3706        fcp->max_ioim_reqs = cfg->fwcfg.num_ioim_reqs;
3707        fcp->num_ioim_reqs = cfg->fwcfg.num_ioim_reqs;
3708        fcp->num_fwtio_reqs  = cfg->fwcfg.num_fwtio_reqs;
3709        fcp->num_itns   = cfg->fwcfg.num_rports;
3710        fcp->bfa = bfa;
3711
3712        /*
3713         * Setup the pool of snsbase addr's, that is passed to fw as
3714         * part of bfi_iocfc_cfg_s.
3715         */
3716        num_io_req = (cfg->fwcfg.num_ioim_reqs + cfg->fwcfg.num_fwtio_reqs);
3717        nsegs = BFI_MEM_DMA_NSEGS(num_io_req, BFI_IOIM_SNSLEN);
3718
3719        bfa_mem_dma_seg_iter(fcp, seg_ptr, nsegs, idx) {
3720
3721                if (!bfa_mem_dma_virt(seg_ptr))
3722                        break;
3723
3724                fcp->snsbase[idx].pa = bfa_mem_dma_phys(seg_ptr);
3725                fcp->snsbase[idx].kva = bfa_mem_dma_virt(seg_ptr);
3726                bfa_iocfc_set_snsbase(bfa, idx, fcp->snsbase[idx].pa);
3727        }
3728
3729        fcp->throttle_update_required = 1;
3730        bfa_fcpim_attach(fcp, bfad, cfg, pcidev);
3731
3732        bfa_iotag_attach(fcp);
3733
3734        fcp->itn_arr = (struct bfa_itn_s *) bfa_mem_kva_curp(fcp);
3735        bfa_mem_kva_curp(fcp) = (u8 *)fcp->itn_arr +
3736                        (fcp->num_itns * sizeof(struct bfa_itn_s));
3737        memset(fcp->itn_arr, 0,
3738                        (fcp->num_itns * sizeof(struct bfa_itn_s)));
3739}
3740
3741static void
3742bfa_fcp_detach(struct bfa_s *bfa)
3743{
3744}
3745
3746static void
3747bfa_fcp_start(struct bfa_s *bfa)
3748{
3749        struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
3750
3751        /*
3752         * bfa_init() with flash read is complete. now invalidate the stale
3753         * content of lun mask like unit attention, rp tag and lp tag.
3754         */
3755        bfa_ioim_lm_init(fcp->bfa);
3756}
3757
3758static void
3759bfa_fcp_stop(struct bfa_s *bfa)
3760{
3761}
3762
3763static void
3764bfa_fcp_iocdisable(struct bfa_s *bfa)
3765{
3766        struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
3767
3768        bfa_fcpim_iocdisable(fcp);
3769}
3770
3771void
3772bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw, u16 max_ioim_fw)
3773{
3774        struct bfa_fcp_mod_s    *mod = BFA_FCP_MOD(bfa);
3775        struct list_head        *qe;
3776        int     i;
3777
3778        /* Update io throttle value only once during driver load time */
3779        if (!mod->throttle_update_required)
3780                return;
3781
3782        for (i = 0; i < (mod->num_ioim_reqs - num_ioim_fw); i++) {
3783                bfa_q_deq_tail(&mod->iotag_ioim_free_q, &qe);
3784                list_add_tail(qe, &mod->iotag_unused_q);
3785        }
3786
3787        if (mod->num_ioim_reqs != num_ioim_fw) {
3788                bfa_trc(bfa, mod->num_ioim_reqs);
3789                bfa_trc(bfa, num_ioim_fw);
3790        }
3791
3792        mod->max_ioim_reqs = max_ioim_fw;
3793        mod->num_ioim_reqs = num_ioim_fw;
3794        mod->throttle_update_required = 0;
3795}
3796
3797void
3798bfa_itn_create(struct bfa_s *bfa, struct bfa_rport_s *rport,
3799                void (*isr)(struct bfa_s *bfa, struct bfi_msg_s *m))
3800{
3801        struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
3802        struct bfa_itn_s *itn;
3803
3804        itn =  BFA_ITN_FROM_TAG(fcp, rport->rport_tag);
3805        itn->isr = isr;
3806}
3807
3808/*
3809 * Itn interrupt processing.
3810 */
3811void
3812bfa_itn_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
3813{
3814        struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
3815        union bfi_itn_i2h_msg_u msg;
3816        struct bfa_itn_s *itn;
3817
3818        msg.msg = m;
3819        itn =  BFA_ITN_FROM_TAG(fcp, msg.create_rsp->bfa_handle);
3820
3821        if (itn->isr)
3822                itn->isr(bfa, m);
3823        else
3824                WARN_ON(1);
3825}
3826
3827void
3828bfa_iotag_attach(struct bfa_fcp_mod_s *fcp)
3829{
3830        struct bfa_iotag_s *iotag;
3831        u16     num_io_req, i;
3832
3833        iotag = (struct bfa_iotag_s *) bfa_mem_kva_curp(fcp);
3834        fcp->iotag_arr = iotag;
3835
3836        INIT_LIST_HEAD(&fcp->iotag_ioim_free_q);
3837        INIT_LIST_HEAD(&fcp->iotag_tio_free_q);
3838        INIT_LIST_HEAD(&fcp->iotag_unused_q);
3839
3840        num_io_req = fcp->num_ioim_reqs + fcp->num_fwtio_reqs;
3841        for (i = 0; i < num_io_req; i++, iotag++) {
3842                memset(iotag, 0, sizeof(struct bfa_iotag_s));
3843                iotag->tag = i;
3844                if (i < fcp->num_ioim_reqs)
3845                        list_add_tail(&iotag->qe, &fcp->iotag_ioim_free_q);
3846                else
3847                        list_add_tail(&iotag->qe, &fcp->iotag_tio_free_q);
3848        }
3849
3850        bfa_mem_kva_curp(fcp) = (u8 *) iotag;
3851}
3852
3853
3854/**
3855 * To send config req, first try to use throttle value from flash
3856 * If 0, then use driver parameter
3857 * We need to use min(flash_val, drv_val) because
3858 * memory allocation was done based on this cfg'd value
3859 */
3860u16
3861bfa_fcpim_get_throttle_cfg(struct bfa_s *bfa, u16 drv_cfg_param)
3862{
3863        u16 tmp;
3864        struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa);
3865
3866        /*
3867         * If throttle value from flash is already in effect after driver is
3868         * loaded then until next load, always return current value instead
3869         * of actual flash value
3870         */
3871        if (!fcp->throttle_update_required)
3872                return (u16)fcp->num_ioim_reqs;
3873
3874        tmp = bfa_dconf_read_data_valid(bfa) ? bfa_fcpim_read_throttle(bfa) : 0;
3875        if (!tmp || (tmp > drv_cfg_param))
3876                tmp = drv_cfg_param;
3877
3878        return tmp;
3879}
3880
3881bfa_status_t
3882bfa_fcpim_write_throttle(struct bfa_s *bfa, u16 value)
3883{
3884        if (!bfa_dconf_get_min_cfg(bfa)) {
3885                BFA_DCONF_MOD(bfa)->dconf->throttle_cfg.value = value;
3886                BFA_DCONF_MOD(bfa)->dconf->throttle_cfg.is_valid = 1;
3887                return BFA_STATUS_OK;
3888        }
3889
3890        return BFA_STATUS_FAILED;
3891}
3892
3893u16
3894bfa_fcpim_read_throttle(struct bfa_s *bfa)
3895{
3896        struct bfa_throttle_cfg_s *throttle_cfg =
3897                        &(BFA_DCONF_MOD(bfa)->dconf->throttle_cfg);
3898
3899        return ((!bfa_dconf_get_min_cfg(bfa)) ?
3900               ((throttle_cfg->is_valid == 1) ? (throttle_cfg->value) : 0) : 0);
3901}
3902
3903bfa_status_t
3904bfa_fcpim_throttle_set(struct bfa_s *bfa, u16 value)
3905{
3906        /* in min cfg no commands should run. */
3907        if ((bfa_dconf_get_min_cfg(bfa) == BFA_TRUE) ||
3908            (!bfa_dconf_read_data_valid(bfa)))
3909                return BFA_STATUS_FAILED;
3910
3911        bfa_fcpim_write_throttle(bfa, value);
3912
3913        return bfa_dconf_update(bfa);
3914}
3915
3916bfa_status_t
3917bfa_fcpim_throttle_get(struct bfa_s *bfa, void *buf)
3918{
3919        struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
3920        struct bfa_defs_fcpim_throttle_s throttle;
3921
3922        if ((bfa_dconf_get_min_cfg(bfa) == BFA_TRUE) ||
3923            (!bfa_dconf_read_data_valid(bfa)))
3924                return BFA_STATUS_FAILED;
3925
3926        memset(&throttle, 0, sizeof(struct bfa_defs_fcpim_throttle_s));
3927
3928        throttle.cur_value = (u16)(fcpim->fcp->num_ioim_reqs);
3929        throttle.cfg_value = bfa_fcpim_read_throttle(bfa);
3930        if (!throttle.cfg_value)
3931                throttle.cfg_value = throttle.cur_value;
3932        throttle.max_value = (u16)(fcpim->fcp->max_ioim_reqs);
3933        memcpy(buf, &throttle, sizeof(struct bfa_defs_fcpim_throttle_s));
3934
3935        return BFA_STATUS_OK;
3936}
3937