root/drivers/scsi/bfa/bfa_fcs_rport.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bfa_fcs_rport_sm_uninit
  2. bfa_fcs_rport_sm_plogi_sending
  3. bfa_fcs_rport_sm_plogiacc_sending
  4. bfa_fcs_rport_sm_plogi_retry
  5. bfa_fcs_rport_sm_plogi
  6. bfa_fcs_rport_sm_fc4_fcs_online
  7. bfa_fcs_rport_sm_hal_online
  8. bfa_fcs_rport_sm_online
  9. bfa_fcs_rport_sm_nsquery_sending
  10. bfa_fcs_rport_sm_nsquery
  11. bfa_fcs_rport_sm_adisc_online_sending
  12. bfa_fcs_rport_sm_adisc_online
  13. bfa_fcs_rport_sm_adisc_offline_sending
  14. bfa_fcs_rport_sm_adisc_offline
  15. bfa_fcs_rport_sm_fc4_logorcv
  16. bfa_fcs_rport_sm_fc4_logosend
  17. bfa_fcs_rport_sm_fc4_offline
  18. bfa_fcs_rport_sm_hcb_offline
  19. bfa_fcs_rport_sm_hcb_logorcv
  20. bfa_fcs_rport_sm_hcb_logosend
  21. bfa_fcs_rport_sm_logo_sending
  22. bfa_fcs_rport_sm_offline
  23. bfa_fcs_rport_sm_nsdisc_sending
  24. bfa_fcs_rport_sm_nsdisc_retry
  25. bfa_fcs_rport_sm_nsdisc_sent
  26. bfa_fcs_rport_sm_fc4_off_delete
  27. bfa_fcs_rport_sm_delete_pending
  28. bfa_fcs_rport_send_plogi
  29. bfa_fcs_rport_plogi_response
  30. bfa_fcs_rport_send_plogiacc
  31. bfa_fcs_rport_send_adisc
  32. bfa_fcs_rport_adisc_response
  33. bfa_fcs_rport_send_nsdisc
  34. bfa_fcs_rport_gidpn_response
  35. bfa_fcs_rport_gpnid_response
  36. bfa_fcs_rport_send_logo
  37. bfa_fcs_rport_send_logo_acc
  38. bfa_fcs_rport_timeout
  39. bfa_fcs_rport_process_prli
  40. bfa_fcs_rport_process_rpsc
  41. bfa_fcs_rport_process_adisc
  42. bfa_fcs_rport_hal_online
  43. bfa_fcs_rport_hal_offline
  44. bfa_fcs_rport_alloc
  45. bfa_fcs_rport_free
  46. bfa_fcs_rport_aen_post
  47. bfa_fcs_rport_fcs_online_action
  48. bfa_fcs_rport_hal_online_action
  49. bfa_fcs_rport_fcs_offline_action
  50. bfa_fcs_rport_hal_offline_action
  51. bfa_fcs_rport_update
  52. bfa_fcs_rport_process_logo
  53. bfa_fcs_rport_create
  54. bfa_fcs_rport_create_by_wwn
  55. bfa_fcs_rport_start
  56. bfa_fcs_rport_plogi_create
  57. bfa_fcs_rport_plogi
  58. bfa_fcs_rport_scn
  59. bfa_cb_rport_online
  60. bfa_cb_rport_offline
  61. bfa_cb_rport_qos_scn_flowid
  62. bfa_cb_rport_scn_online
  63. bfa_cb_rport_scn_no_dev
  64. bfa_cb_rport_scn_offline
  65. bfa_cb_rport_qos_scn_prio
  66. bfa_fcs_rport_uf_recv
  67. bfa_fcs_rport_send_prlo_acc
  68. bfa_fcs_rport_send_ls_rjt
  69. bfa_fcs_rport_get_state
  70. bfa_fcs_rport_set_del_timeout
  71. bfa_fcs_rport_prlo
  72. bfa_fcs_rport_set_max_logins
  73. bfa_fcs_rport_get_attr
  74. bfa_fcs_rport_lookup
  75. bfa_fcs_rport_lookup_by_nwwn
  76. bfa_fcs_rpf_sm_uninit
  77. bfa_fcs_rpf_sm_rpsc_sending
  78. bfa_fcs_rpf_sm_rpsc
  79. bfa_fcs_rpf_sm_rpsc_retry
  80. bfa_fcs_rpf_sm_online
  81. bfa_fcs_rpf_sm_offline
  82. bfa_fcs_rpf_init
  83. bfa_fcs_rpf_rport_online
  84. bfa_fcs_rpf_rport_offline
  85. bfa_fcs_rpf_timeout
  86. bfa_fcs_rpf_send_rpsc2
  87. bfa_fcs_rpf_rpsc2_response

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
   4  * Copyright (c) 2014- QLogic Corporation.
   5  * All rights reserved
   6  * www.qlogic.com
   7  *
   8  * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
   9  */
  10 
  11 /*
  12  *  rport.c Remote port implementation.
  13  */
  14 
  15 #include "bfad_drv.h"
  16 #include "bfad_im.h"
  17 #include "bfa_fcs.h"
  18 #include "bfa_fcbuild.h"
  19 
  20 BFA_TRC_FILE(FCS, RPORT);
  21 
  22 static u32
  23 bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000;
  24          /* In millisecs */
  25 /*
  26  * bfa_fcs_rport_max_logins is max count of bfa_fcs_rports
  27  * whereas DEF_CFG_NUM_RPORTS is max count of bfa_rports
  28  */
  29 static u32 bfa_fcs_rport_max_logins = BFA_FCS_MAX_RPORT_LOGINS;
  30 
  31 /*
  32  * forward declarations
  33  */
  34 static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc(
  35                 struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid);
  36 static void     bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport);
  37 static void     bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport);
  38 static void     bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport);
  39 static void     bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport);
  40 static void     bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport);
  41 static void     bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport);
  42 static void     bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport,
  43                                         struct fc_logi_s *plogi);
  44 static void     bfa_fcs_rport_timeout(void *arg);
  45 static void     bfa_fcs_rport_send_plogi(void *rport_cbarg,
  46                                          struct bfa_fcxp_s *fcxp_alloced);
  47 static void     bfa_fcs_rport_send_plogiacc(void *rport_cbarg,
  48                                         struct bfa_fcxp_s *fcxp_alloced);
  49 static void     bfa_fcs_rport_plogi_response(void *fcsarg,
  50                                 struct bfa_fcxp_s *fcxp, void *cbarg,
  51                                 bfa_status_t req_status, u32 rsp_len,
  52                                 u32 resid_len, struct fchs_s *rsp_fchs);
  53 static void     bfa_fcs_rport_send_adisc(void *rport_cbarg,
  54                                          struct bfa_fcxp_s *fcxp_alloced);
  55 static void     bfa_fcs_rport_adisc_response(void *fcsarg,
  56                                 struct bfa_fcxp_s *fcxp, void *cbarg,
  57                                 bfa_status_t req_status, u32 rsp_len,
  58                                 u32 resid_len, struct fchs_s *rsp_fchs);
  59 static void     bfa_fcs_rport_send_nsdisc(void *rport_cbarg,
  60                                          struct bfa_fcxp_s *fcxp_alloced);
  61 static void     bfa_fcs_rport_gidpn_response(void *fcsarg,
  62                                 struct bfa_fcxp_s *fcxp, void *cbarg,
  63                                 bfa_status_t req_status, u32 rsp_len,
  64                                 u32 resid_len, struct fchs_s *rsp_fchs);
  65 static void     bfa_fcs_rport_gpnid_response(void *fcsarg,
  66                                 struct bfa_fcxp_s *fcxp, void *cbarg,
  67                                 bfa_status_t req_status, u32 rsp_len,
  68                                 u32 resid_len, struct fchs_s *rsp_fchs);
  69 static void     bfa_fcs_rport_send_logo(void *rport_cbarg,
  70                                         struct bfa_fcxp_s *fcxp_alloced);
  71 static void     bfa_fcs_rport_send_logo_acc(void *rport_cbarg);
  72 static void     bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
  73                                         struct fchs_s *rx_fchs, u16 len);
  74 static void     bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
  75                                 struct fchs_s *rx_fchs, u8 reason_code,
  76                                           u8 reason_code_expl);
  77 static void     bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
  78                                 struct fchs_s *rx_fchs, u16 len);
  79 static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
  80 static void     bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport);
  81 
  82 static void     bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
  83                                         enum rport_event event);
  84 static void     bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
  85                                                 enum rport_event event);
  86 static void     bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
  87                                                   enum rport_event event);
  88 static void     bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
  89                                                 enum rport_event event);
  90 static void     bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport,
  91                                         enum rport_event event);
  92 static void     bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
  93                                         enum rport_event event);
  94 static void     bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
  95                                                 enum rport_event event);
  96 static void     bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport,
  97                                         enum rport_event event);
  98 static void     bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
  99                                                  enum rport_event event);
 100 static void     bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
 101                                          enum rport_event event);
 102 static void     bfa_fcs_rport_sm_adisc_online_sending(
 103                         struct bfa_fcs_rport_s *rport, enum rport_event event);
 104 static void     bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
 105                                         enum rport_event event);
 106 static void     bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s
 107                                         *rport, enum rport_event event);
 108 static void     bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
 109                                         enum rport_event event);
 110 static void     bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
 111                                                 enum rport_event event);
 112 static void     bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
 113                                                 enum rport_event event);
 114 static void     bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
 115                                                 enum rport_event event);
 116 static void     bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
 117                                                 enum rport_event event);
 118 static void     bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
 119                                                 enum rport_event event);
 120 static void     bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
 121                                                 enum rport_event event);
 122 static void     bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
 123                                                 enum rport_event event);
 124 static void     bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport,
 125                                          enum rport_event event);
 126 static void     bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
 127                                                 enum rport_event event);
 128 static void     bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
 129                                                 enum rport_event event);
 130 static void     bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
 131                                                 enum rport_event event);
 132 static void     bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
 133                                                 enum rport_event event);
 134 static void     bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport,
 135                                                 enum rport_event event);
 136 static void     bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport,
 137                                                 enum rport_event event);
 138 
 139 static struct bfa_sm_table_s rport_sm_table[] = {
 140         {BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT},
 141         {BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI},
 142         {BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE},
 143         {BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY},
 144         {BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI},
 145         {BFA_SM(bfa_fcs_rport_sm_fc4_fcs_online), BFA_RPORT_ONLINE},
 146         {BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE},
 147         {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
 148         {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
 149         {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
 150         {BFA_SM(bfa_fcs_rport_sm_adisc_online_sending), BFA_RPORT_ADISC},
 151         {BFA_SM(bfa_fcs_rport_sm_adisc_online), BFA_RPORT_ADISC},
 152         {BFA_SM(bfa_fcs_rport_sm_adisc_offline_sending), BFA_RPORT_ADISC},
 153         {BFA_SM(bfa_fcs_rport_sm_adisc_offline), BFA_RPORT_ADISC},
 154         {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
 155         {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
 156         {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
 157         {BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE},
 158         {BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV},
 159         {BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO},
 160         {BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO},
 161         {BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE},
 162         {BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC},
 163         {BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC},
 164         {BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC},
 165 };
 166 
 167 /*
 168  *              Beginning state.
 169  */
 170 static void
 171 bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
 172 {
 173         bfa_trc(rport->fcs, rport->pwwn);
 174         bfa_trc(rport->fcs, rport->pid);
 175         bfa_trc(rport->fcs, event);
 176 
 177         switch (event) {
 178         case RPSM_EVENT_PLOGI_SEND:
 179                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
 180                 rport->plogi_retries = 0;
 181                 bfa_fcs_rport_send_plogi(rport, NULL);
 182                 break;
 183 
 184         case RPSM_EVENT_PLOGI_RCVD:
 185                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
 186                 bfa_fcs_rport_send_plogiacc(rport, NULL);
 187                 break;
 188 
 189         case RPSM_EVENT_PLOGI_COMP:
 190                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
 191                 bfa_fcs_rport_hal_online(rport);
 192                 break;
 193 
 194         case RPSM_EVENT_ADDRESS_CHANGE:
 195         case RPSM_EVENT_ADDRESS_DISC:
 196                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
 197                 rport->ns_retries = 0;
 198                 bfa_fcs_rport_send_nsdisc(rport, NULL);
 199                 break;
 200         default:
 201                 bfa_sm_fault(rport->fcs, event);
 202         }
 203 }
 204 
 205 /*
 206  *              PLOGI is being sent.
 207  */
 208 static void
 209 bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
 210          enum rport_event event)
 211 {
 212         bfa_trc(rport->fcs, rport->pwwn);
 213         bfa_trc(rport->fcs, rport->pid);
 214         bfa_trc(rport->fcs, event);
 215 
 216         switch (event) {
 217         case RPSM_EVENT_FCXP_SENT:
 218                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi);
 219                 break;
 220 
 221         case RPSM_EVENT_DELETE:
 222                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
 223                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 224                 bfa_fcs_rport_free(rport);
 225                 break;
 226 
 227         case RPSM_EVENT_PLOGI_RCVD:
 228                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
 229                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 230                 bfa_fcs_rport_send_plogiacc(rport, NULL);
 231                 break;
 232 
 233         case RPSM_EVENT_SCN_OFFLINE:
 234                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
 235                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 236                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
 237                                 bfa_fcs_rport_timeout, rport,
 238                                 bfa_fcs_rport_del_timeout);
 239                 break;
 240         case RPSM_EVENT_ADDRESS_CHANGE:
 241         case RPSM_EVENT_FAB_SCN:
 242                 /* query the NS */
 243                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 244                 WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
 245                                         BFA_PORT_TOPOLOGY_LOOP));
 246                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
 247                 rport->ns_retries = 0;
 248                 bfa_fcs_rport_send_nsdisc(rport, NULL);
 249                 break;
 250 
 251         case RPSM_EVENT_LOGO_IMP:
 252                 rport->pid = 0;
 253                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
 254                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 255                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
 256                                 bfa_fcs_rport_timeout, rport,
 257                                 bfa_fcs_rport_del_timeout);
 258                 break;
 259 
 260 
 261         default:
 262                 bfa_sm_fault(rport->fcs, event);
 263         }
 264 }
 265 
 266 /*
 267  *              PLOGI is being sent.
 268  */
 269 static void
 270 bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
 271          enum rport_event event)
 272 {
 273         bfa_trc(rport->fcs, rport->pwwn);
 274         bfa_trc(rport->fcs, rport->pid);
 275         bfa_trc(rport->fcs, event);
 276 
 277         switch (event) {
 278         case RPSM_EVENT_FCXP_SENT:
 279                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
 280                 bfa_fcs_rport_fcs_online_action(rport);
 281                 break;
 282 
 283         case RPSM_EVENT_DELETE:
 284                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
 285                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 286                 bfa_fcs_rport_free(rport);
 287                 break;
 288 
 289         case RPSM_EVENT_PLOGI_RCVD:
 290         case RPSM_EVENT_PLOGI_COMP:
 291         case RPSM_EVENT_FAB_SCN:
 292                 /*
 293                  * Ignore, SCN is possibly online notification.
 294                  */
 295                 break;
 296 
 297         case RPSM_EVENT_SCN_OFFLINE:
 298                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
 299                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 300                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
 301                                 bfa_fcs_rport_timeout, rport,
 302                                 bfa_fcs_rport_del_timeout);
 303                 break;
 304 
 305         case RPSM_EVENT_ADDRESS_CHANGE:
 306                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 307                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
 308                 rport->ns_retries = 0;
 309                 bfa_fcs_rport_send_nsdisc(rport, NULL);
 310                 break;
 311 
 312         case RPSM_EVENT_LOGO_IMP:
 313                 rport->pid = 0;
 314                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
 315                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 316                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
 317                                 bfa_fcs_rport_timeout, rport,
 318                                 bfa_fcs_rport_del_timeout);
 319                 break;
 320 
 321         case RPSM_EVENT_HCB_OFFLINE:
 322                 /*
 323                  * Ignore BFA callback, on a PLOGI receive we call bfa offline.
 324                  */
 325                 break;
 326 
 327         default:
 328                 bfa_sm_fault(rport->fcs, event);
 329         }
 330 }
 331 
 332 /*
 333  *              PLOGI is sent.
 334  */
 335 static void
 336 bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
 337                         enum rport_event event)
 338 {
 339         bfa_trc(rport->fcs, rport->pwwn);
 340         bfa_trc(rport->fcs, rport->pid);
 341         bfa_trc(rport->fcs, event);
 342 
 343         switch (event) {
 344         case RPSM_EVENT_TIMEOUT:
 345                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
 346                 bfa_fcs_rport_send_plogi(rport, NULL);
 347                 break;
 348 
 349         case RPSM_EVENT_DELETE:
 350                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
 351                 bfa_timer_stop(&rport->timer);
 352                 bfa_fcs_rport_free(rport);
 353                 break;
 354 
 355         case RPSM_EVENT_PRLO_RCVD:
 356         case RPSM_EVENT_LOGO_RCVD:
 357                 break;
 358 
 359         case RPSM_EVENT_PLOGI_RCVD:
 360                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
 361                 bfa_timer_stop(&rport->timer);
 362                 bfa_fcs_rport_send_plogiacc(rport, NULL);
 363                 break;
 364 
 365         case RPSM_EVENT_SCN_OFFLINE:
 366                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
 367                 bfa_timer_stop(&rport->timer);
 368                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
 369                                 bfa_fcs_rport_timeout, rport,
 370                                 bfa_fcs_rport_del_timeout);
 371                 break;
 372 
 373         case RPSM_EVENT_ADDRESS_CHANGE:
 374         case RPSM_EVENT_FAB_SCN:
 375                 bfa_timer_stop(&rport->timer);
 376                 WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
 377                                         BFA_PORT_TOPOLOGY_LOOP));
 378                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
 379                 rport->ns_retries = 0;
 380                 bfa_fcs_rport_send_nsdisc(rport, NULL);
 381                 break;
 382 
 383         case RPSM_EVENT_LOGO_IMP:
 384                 rport->pid = 0;
 385                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
 386                 bfa_timer_stop(&rport->timer);
 387                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
 388                                 bfa_fcs_rport_timeout, rport,
 389                                 bfa_fcs_rport_del_timeout);
 390                 break;
 391 
 392         case RPSM_EVENT_PLOGI_COMP:
 393                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
 394                 bfa_timer_stop(&rport->timer);
 395                 bfa_fcs_rport_fcs_online_action(rport);
 396                 break;
 397 
 398         default:
 399                 bfa_sm_fault(rport->fcs, event);
 400         }
 401 }
 402 
 403 /*
 404  *              PLOGI is sent.
 405  */
 406 static void
 407 bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
 408 {
 409         bfa_trc(rport->fcs, rport->pwwn);
 410         bfa_trc(rport->fcs, rport->pid);
 411         bfa_trc(rport->fcs, event);
 412 
 413         switch (event) {
 414         case RPSM_EVENT_ACCEPTED:
 415                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
 416                 rport->plogi_retries = 0;
 417                 bfa_fcs_rport_fcs_online_action(rport);
 418                 break;
 419 
 420         case RPSM_EVENT_LOGO_RCVD:
 421                 bfa_fcs_rport_send_logo_acc(rport);
 422                 /* fall through */
 423         case RPSM_EVENT_PRLO_RCVD:
 424                 if (rport->prlo == BFA_TRUE)
 425                         bfa_fcs_rport_send_prlo_acc(rport);
 426 
 427                 bfa_fcxp_discard(rport->fcxp);
 428                 /* fall through */
 429         case RPSM_EVENT_FAILED:
 430                 if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) {
 431                         rport->plogi_retries++;
 432                         bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
 433                         bfa_timer_start(rport->fcs->bfa, &rport->timer,
 434                                         bfa_fcs_rport_timeout, rport,
 435                                         BFA_FCS_RETRY_TIMEOUT);
 436                 } else {
 437                         bfa_stats(rport->port, rport_del_max_plogi_retry);
 438                         rport->old_pid = rport->pid;
 439                         rport->pid = 0;
 440                         bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
 441                         bfa_timer_start(rport->fcs->bfa, &rport->timer,
 442                                         bfa_fcs_rport_timeout, rport,
 443                                         bfa_fcs_rport_del_timeout);
 444                 }
 445                 break;
 446 
 447         case RPSM_EVENT_SCN_ONLINE:
 448                 break;
 449 
 450         case RPSM_EVENT_SCN_OFFLINE:
 451                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
 452                 bfa_fcxp_discard(rport->fcxp);
 453                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
 454                                 bfa_fcs_rport_timeout, rport,
 455                                 bfa_fcs_rport_del_timeout);
 456                 break;
 457 
 458         case RPSM_EVENT_PLOGI_RETRY:
 459                 rport->plogi_retries = 0;
 460                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
 461                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
 462                                 bfa_fcs_rport_timeout, rport,
 463                                 (FC_RA_TOV * 1000));
 464                 break;
 465 
 466         case RPSM_EVENT_LOGO_IMP:
 467                 rport->pid = 0;
 468                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
 469                 bfa_fcxp_discard(rport->fcxp);
 470                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
 471                                 bfa_fcs_rport_timeout, rport,
 472                                 bfa_fcs_rport_del_timeout);
 473                 break;
 474 
 475         case RPSM_EVENT_ADDRESS_CHANGE:
 476         case RPSM_EVENT_FAB_SCN:
 477                 bfa_fcxp_discard(rport->fcxp);
 478                 WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
 479                                         BFA_PORT_TOPOLOGY_LOOP));
 480                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
 481                 rport->ns_retries = 0;
 482                 bfa_fcs_rport_send_nsdisc(rport, NULL);
 483                 break;
 484 
 485         case RPSM_EVENT_PLOGI_RCVD:
 486                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
 487                 bfa_fcxp_discard(rport->fcxp);
 488                 bfa_fcs_rport_send_plogiacc(rport, NULL);
 489                 break;
 490 
 491         case RPSM_EVENT_DELETE:
 492                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
 493                 bfa_fcxp_discard(rport->fcxp);
 494                 bfa_fcs_rport_free(rport);
 495                 break;
 496 
 497         case RPSM_EVENT_PLOGI_COMP:
 498                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
 499                 bfa_fcxp_discard(rport->fcxp);
 500                 bfa_fcs_rport_fcs_online_action(rport);
 501                 break;
 502 
 503         default:
 504                 bfa_sm_fault(rport->fcs, event);
 505         }
 506 }
 507 
 508 /*
 509  * PLOGI is done. Await bfa_fcs_itnim to ascertain the scsi function
 510  */
 511 static void
 512 bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
 513                                 enum rport_event event)
 514 {
 515         bfa_trc(rport->fcs, rport->pwwn);
 516         bfa_trc(rport->fcs, rport->pid);
 517         bfa_trc(rport->fcs, event);
 518 
 519         switch (event) {
 520         case RPSM_EVENT_FC4_FCS_ONLINE:
 521                 if (rport->scsi_function == BFA_RPORT_INITIATOR) {
 522                         if (!BFA_FCS_PID_IS_WKA(rport->pid))
 523                                 bfa_fcs_rpf_rport_online(rport);
 524                         bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
 525                         break;
 526                 }
 527 
 528                 if (!rport->bfa_rport)
 529                         rport->bfa_rport =
 530                                 bfa_rport_create(rport->fcs->bfa, rport);
 531 
 532                 if (rport->bfa_rport) {
 533                         bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
 534                         bfa_fcs_rport_hal_online(rport);
 535                 } else {
 536                         bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
 537                         bfa_fcs_rport_fcs_offline_action(rport);
 538                 }
 539                 break;
 540 
 541         case RPSM_EVENT_PLOGI_RCVD:
 542                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
 543                 rport->plogi_pending = BFA_TRUE;
 544                 bfa_fcs_rport_fcs_offline_action(rport);
 545                 break;
 546 
 547         case RPSM_EVENT_PLOGI_COMP:
 548         case RPSM_EVENT_LOGO_IMP:
 549         case RPSM_EVENT_ADDRESS_CHANGE:
 550         case RPSM_EVENT_FAB_SCN:
 551         case RPSM_EVENT_SCN_OFFLINE:
 552                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
 553                 bfa_fcs_rport_fcs_offline_action(rport);
 554                 break;
 555 
 556         case RPSM_EVENT_LOGO_RCVD:
 557         case RPSM_EVENT_PRLO_RCVD:
 558                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
 559                 bfa_fcs_rport_fcs_offline_action(rport);
 560                 break;
 561 
 562         case RPSM_EVENT_DELETE:
 563                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
 564                 bfa_fcs_rport_fcs_offline_action(rport);
 565                 break;
 566 
 567         default:
 568                 bfa_sm_fault(rport->fcs, event);
 569                 break;
 570         }
 571 }
 572 
 573 /*
 574  *              PLOGI is complete. Awaiting BFA rport online callback. FC-4s
 575  *              are offline.
 576  */
 577 static void
 578 bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
 579                         enum rport_event event)
 580 {
 581         bfa_trc(rport->fcs, rport->pwwn);
 582         bfa_trc(rport->fcs, rport->pid);
 583         bfa_trc(rport->fcs, event);
 584 
 585         switch (event) {
 586         case RPSM_EVENT_HCB_ONLINE:
 587                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
 588                 bfa_fcs_rport_hal_online_action(rport);
 589                 break;
 590 
 591         case RPSM_EVENT_PLOGI_COMP:
 592                 break;
 593 
 594         case RPSM_EVENT_PRLO_RCVD:
 595         case RPSM_EVENT_LOGO_RCVD:
 596                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
 597                 bfa_fcs_rport_fcs_offline_action(rport);
 598                 break;
 599 
 600         case RPSM_EVENT_FAB_SCN:
 601         case RPSM_EVENT_LOGO_IMP:
 602         case RPSM_EVENT_ADDRESS_CHANGE:
 603         case RPSM_EVENT_SCN_OFFLINE:
 604                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
 605                 bfa_fcs_rport_fcs_offline_action(rport);
 606                 break;
 607 
 608         case RPSM_EVENT_PLOGI_RCVD:
 609                 rport->plogi_pending = BFA_TRUE;
 610                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
 611                 bfa_fcs_rport_fcs_offline_action(rport);
 612                 break;
 613 
 614         case RPSM_EVENT_DELETE:
 615                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
 616                 bfa_fcs_rport_fcs_offline_action(rport);
 617                 break;
 618 
 619         default:
 620                 bfa_sm_fault(rport->fcs, event);
 621         }
 622 }
 623 
 624 /*
 625  *              Rport is ONLINE. FC-4s active.
 626  */
 627 static void
 628 bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
 629 {
 630         bfa_trc(rport->fcs, rport->pwwn);
 631         bfa_trc(rport->fcs, rport->pid);
 632         bfa_trc(rport->fcs, event);
 633 
 634         switch (event) {
 635         case RPSM_EVENT_FAB_SCN:
 636                 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
 637                         bfa_sm_set_state(rport,
 638                                          bfa_fcs_rport_sm_nsquery_sending);
 639                         rport->ns_retries = 0;
 640                         bfa_fcs_rport_send_nsdisc(rport, NULL);
 641                 } else {
 642                         bfa_sm_set_state(rport,
 643                                 bfa_fcs_rport_sm_adisc_online_sending);
 644                         bfa_fcs_rport_send_adisc(rport, NULL);
 645                 }
 646                 break;
 647 
 648         case RPSM_EVENT_PLOGI_RCVD:
 649         case RPSM_EVENT_LOGO_IMP:
 650         case RPSM_EVENT_ADDRESS_CHANGE:
 651         case RPSM_EVENT_SCN_OFFLINE:
 652                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
 653                 bfa_fcs_rport_hal_offline_action(rport);
 654                 break;
 655 
 656         case RPSM_EVENT_DELETE:
 657                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
 658                 bfa_fcs_rport_hal_offline_action(rport);
 659                 break;
 660 
 661         case RPSM_EVENT_LOGO_RCVD:
 662         case RPSM_EVENT_PRLO_RCVD:
 663                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
 664                 bfa_fcs_rport_hal_offline_action(rport);
 665                 break;
 666 
 667         case RPSM_EVENT_SCN_ONLINE:
 668         case RPSM_EVENT_PLOGI_COMP:
 669                 break;
 670 
 671         default:
 672                 bfa_sm_fault(rport->fcs, event);
 673         }
 674 }
 675 
 676 /*
 677  *              An SCN event is received in ONLINE state. NS query is being sent
 678  *              prior to ADISC authentication with rport. FC-4s are paused.
 679  */
 680 static void
 681 bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
 682          enum rport_event event)
 683 {
 684         bfa_trc(rport->fcs, rport->pwwn);
 685         bfa_trc(rport->fcs, rport->pid);
 686         bfa_trc(rport->fcs, event);
 687 
 688         switch (event) {
 689         case RPSM_EVENT_FCXP_SENT:
 690                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery);
 691                 break;
 692 
 693         case RPSM_EVENT_DELETE:
 694                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
 695                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 696                 bfa_fcs_rport_hal_offline_action(rport);
 697                 break;
 698 
 699         case RPSM_EVENT_FAB_SCN:
 700                 /*
 701                  * ignore SCN, wait for response to query itself
 702                  */
 703                 break;
 704 
 705         case RPSM_EVENT_LOGO_RCVD:
 706         case RPSM_EVENT_PRLO_RCVD:
 707                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
 708                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 709                 bfa_fcs_rport_hal_offline_action(rport);
 710                 break;
 711 
 712         case RPSM_EVENT_LOGO_IMP:
 713         case RPSM_EVENT_PLOGI_RCVD:
 714         case RPSM_EVENT_ADDRESS_CHANGE:
 715         case RPSM_EVENT_PLOGI_COMP:
 716                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
 717                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 718                 bfa_fcs_rport_hal_offline_action(rport);
 719                 break;
 720 
 721         default:
 722                 bfa_sm_fault(rport->fcs, event);
 723         }
 724 }
 725 
 726 /*
 727  *      An SCN event is received in ONLINE state. NS query is sent to rport.
 728  *      FC-4s are paused.
 729  */
 730 static void
 731 bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
 732 {
 733         bfa_trc(rport->fcs, rport->pwwn);
 734         bfa_trc(rport->fcs, rport->pid);
 735         bfa_trc(rport->fcs, event);
 736 
 737         switch (event) {
 738         case RPSM_EVENT_ACCEPTED:
 739                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online_sending);
 740                 bfa_fcs_rport_send_adisc(rport, NULL);
 741                 break;
 742 
 743         case RPSM_EVENT_FAILED:
 744                 rport->ns_retries++;
 745                 if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
 746                         bfa_sm_set_state(rport,
 747                                          bfa_fcs_rport_sm_nsquery_sending);
 748                         bfa_fcs_rport_send_nsdisc(rport, NULL);
 749                 } else {
 750                         bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
 751                         bfa_fcs_rport_hal_offline_action(rport);
 752                 }
 753                 break;
 754 
 755         case RPSM_EVENT_DELETE:
 756                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
 757                 bfa_fcxp_discard(rport->fcxp);
 758                 bfa_fcs_rport_hal_offline_action(rport);
 759                 break;
 760 
 761         case RPSM_EVENT_FAB_SCN:
 762                 break;
 763 
 764         case RPSM_EVENT_LOGO_RCVD:
 765         case RPSM_EVENT_PRLO_RCVD:
 766                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
 767                 bfa_fcxp_discard(rport->fcxp);
 768                 bfa_fcs_rport_hal_offline_action(rport);
 769                 break;
 770 
 771         case RPSM_EVENT_PLOGI_COMP:
 772         case RPSM_EVENT_ADDRESS_CHANGE:
 773         case RPSM_EVENT_PLOGI_RCVD:
 774         case RPSM_EVENT_LOGO_IMP:
 775                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
 776                 bfa_fcxp_discard(rport->fcxp);
 777                 bfa_fcs_rport_hal_offline_action(rport);
 778                 break;
 779 
 780         default:
 781                 bfa_sm_fault(rport->fcs, event);
 782         }
 783 }
 784 
 785 /*
 786  *      An SCN event is received in ONLINE state. ADISC is being sent for
 787  *      authenticating with rport. FC-4s are paused.
 788  */
 789 static void
 790 bfa_fcs_rport_sm_adisc_online_sending(struct bfa_fcs_rport_s *rport,
 791          enum rport_event event)
 792 {
 793         bfa_trc(rport->fcs, rport->pwwn);
 794         bfa_trc(rport->fcs, rport->pid);
 795         bfa_trc(rport->fcs, event);
 796 
 797         switch (event) {
 798         case RPSM_EVENT_FCXP_SENT:
 799                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online);
 800                 break;
 801 
 802         case RPSM_EVENT_DELETE:
 803                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
 804                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 805                 bfa_fcs_rport_hal_offline_action(rport);
 806                 break;
 807 
 808         case RPSM_EVENT_LOGO_IMP:
 809         case RPSM_EVENT_ADDRESS_CHANGE:
 810                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
 811                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 812                 bfa_fcs_rport_hal_offline_action(rport);
 813                 break;
 814 
 815         case RPSM_EVENT_LOGO_RCVD:
 816         case RPSM_EVENT_PRLO_RCVD:
 817                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
 818                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 819                 bfa_fcs_rport_hal_offline_action(rport);
 820                 break;
 821 
 822         case RPSM_EVENT_FAB_SCN:
 823                 break;
 824 
 825         case RPSM_EVENT_PLOGI_RCVD:
 826                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
 827                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 828                 bfa_fcs_rport_hal_offline_action(rport);
 829                 break;
 830 
 831         default:
 832                 bfa_sm_fault(rport->fcs, event);
 833         }
 834 }
 835 
 836 /*
 837  *              An SCN event is received in ONLINE state. ADISC is to rport.
 838  *              FC-4s are paused.
 839  */
 840 static void
 841 bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
 842                                 enum rport_event event)
 843 {
 844         bfa_trc(rport->fcs, rport->pwwn);
 845         bfa_trc(rport->fcs, rport->pid);
 846         bfa_trc(rport->fcs, event);
 847 
 848         switch (event) {
 849         case RPSM_EVENT_ACCEPTED:
 850                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
 851                 break;
 852 
 853         case RPSM_EVENT_PLOGI_RCVD:
 854                 /*
 855                  * Too complex to cleanup FC-4 & rport and then acc to PLOGI.
 856                  * At least go offline when a PLOGI is received.
 857                  */
 858                 bfa_fcxp_discard(rport->fcxp);
 859                 /* fall through */
 860 
 861         case RPSM_EVENT_FAILED:
 862         case RPSM_EVENT_ADDRESS_CHANGE:
 863                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
 864                 bfa_fcs_rport_hal_offline_action(rport);
 865                 break;
 866 
 867         case RPSM_EVENT_DELETE:
 868                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
 869                 bfa_fcxp_discard(rport->fcxp);
 870                 bfa_fcs_rport_hal_offline_action(rport);
 871                 break;
 872 
 873         case RPSM_EVENT_FAB_SCN:
 874                 /*
 875                  * already processing RSCN
 876                  */
 877                 break;
 878 
 879         case RPSM_EVENT_LOGO_IMP:
 880                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
 881                 bfa_fcxp_discard(rport->fcxp);
 882                 bfa_fcs_rport_hal_offline_action(rport);
 883                 break;
 884 
 885         case RPSM_EVENT_LOGO_RCVD:
 886         case RPSM_EVENT_PRLO_RCVD:
 887                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
 888                 bfa_fcxp_discard(rport->fcxp);
 889                 bfa_fcs_rport_hal_offline_action(rport);
 890                 break;
 891 
 892         default:
 893                 bfa_sm_fault(rport->fcs, event);
 894         }
 895 }
 896 
 897 /*
 898  * ADISC is being sent for authenticating with rport
 899  * Already did offline actions.
 900  */
 901 static void
 902 bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s *rport,
 903         enum rport_event event)
 904 {
 905         bfa_trc(rport->fcs, rport->pwwn);
 906         bfa_trc(rport->fcs, rport->pid);
 907         bfa_trc(rport->fcs, event);
 908 
 909         switch (event) {
 910         case RPSM_EVENT_FCXP_SENT:
 911                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_offline);
 912                 break;
 913 
 914         case RPSM_EVENT_DELETE:
 915         case RPSM_EVENT_SCN_OFFLINE:
 916         case RPSM_EVENT_LOGO_IMP:
 917         case RPSM_EVENT_LOGO_RCVD:
 918         case RPSM_EVENT_PRLO_RCVD:
 919                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
 920                 bfa_fcxp_walloc_cancel(rport->fcs->bfa,
 921                         &rport->fcxp_wqe);
 922                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
 923                         bfa_fcs_rport_timeout, rport,
 924                         bfa_fcs_rport_del_timeout);
 925                 break;
 926 
 927         case RPSM_EVENT_PLOGI_RCVD:
 928                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
 929                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
 930                 bfa_fcs_rport_send_plogiacc(rport, NULL);
 931                 break;
 932 
 933         default:
 934                 bfa_sm_fault(rport->fcs, event);
 935         }
 936 }
 937 
 938 /*
 939  * ADISC to rport
 940  * Already did offline actions
 941  */
 942 static void
 943 bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
 944                         enum rport_event event)
 945 {
 946         bfa_trc(rport->fcs, rport->pwwn);
 947         bfa_trc(rport->fcs, rport->pid);
 948         bfa_trc(rport->fcs, event);
 949 
 950         switch (event) {
 951         case RPSM_EVENT_ACCEPTED:
 952                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
 953                 bfa_fcs_rport_hal_online(rport);
 954                 break;
 955 
 956         case RPSM_EVENT_PLOGI_RCVD:
 957                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
 958                 bfa_fcxp_discard(rport->fcxp);
 959                 bfa_fcs_rport_send_plogiacc(rport, NULL);
 960                 break;
 961 
 962         case RPSM_EVENT_FAILED:
 963                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
 964                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
 965                         bfa_fcs_rport_timeout, rport,
 966                         bfa_fcs_rport_del_timeout);
 967                 break;
 968 
 969         case RPSM_EVENT_DELETE:
 970         case RPSM_EVENT_SCN_OFFLINE:
 971         case RPSM_EVENT_LOGO_IMP:
 972         case RPSM_EVENT_LOGO_RCVD:
 973         case RPSM_EVENT_PRLO_RCVD:
 974                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
 975                 bfa_fcxp_discard(rport->fcxp);
 976                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
 977                         bfa_fcs_rport_timeout, rport,
 978                         bfa_fcs_rport_del_timeout);
 979                 break;
 980 
 981         default:
 982                 bfa_sm_fault(rport->fcs, event);
 983         }
 984 }
 985 
 986 /*
 987  * Rport has sent LOGO. Awaiting FC-4 offline completion callback.
 988  */
 989 static void
 990 bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
 991                         enum rport_event event)
 992 {
 993         bfa_trc(rport->fcs, rport->pwwn);
 994         bfa_trc(rport->fcs, rport->pid);
 995         bfa_trc(rport->fcs, event);
 996 
 997         switch (event) {
 998         case RPSM_EVENT_FC4_OFFLINE:
 999                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
1000                 bfa_fcs_rport_hal_offline(rport);
1001                 break;
1002 
1003         case RPSM_EVENT_DELETE:
1004                 if (rport->pid && (rport->prlo == BFA_TRUE))
1005                         bfa_fcs_rport_send_prlo_acc(rport);
1006                 if (rport->pid && (rport->prlo == BFA_FALSE))
1007                         bfa_fcs_rport_send_logo_acc(rport);
1008 
1009                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
1010                 break;
1011 
1012         case RPSM_EVENT_SCN_ONLINE:
1013         case RPSM_EVENT_SCN_OFFLINE:
1014         case RPSM_EVENT_HCB_ONLINE:
1015         case RPSM_EVENT_LOGO_RCVD:
1016         case RPSM_EVENT_PRLO_RCVD:
1017         case RPSM_EVENT_ADDRESS_CHANGE:
1018                 break;
1019 
1020         default:
1021                 bfa_sm_fault(rport->fcs, event);
1022         }
1023 }
1024 
1025 /*
1026  *              LOGO needs to be sent to rport. Awaiting FC-4 offline completion
1027  *              callback.
1028  */
1029 static void
1030 bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
1031          enum rport_event event)
1032 {
1033         bfa_trc(rport->fcs, rport->pwwn);
1034         bfa_trc(rport->fcs, rport->pid);
1035         bfa_trc(rport->fcs, event);
1036 
1037         switch (event) {
1038         case RPSM_EVENT_FC4_OFFLINE:
1039                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
1040                 bfa_fcs_rport_hal_offline(rport);
1041                 break;
1042 
1043         case RPSM_EVENT_LOGO_RCVD:
1044                 bfa_fcs_rport_send_logo_acc(rport);
1045                 /* fall through */
1046         case RPSM_EVENT_PRLO_RCVD:
1047                 if (rport->prlo == BFA_TRUE)
1048                         bfa_fcs_rport_send_prlo_acc(rport);
1049                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
1050                 break;
1051 
1052         case RPSM_EVENT_HCB_ONLINE:
1053         case RPSM_EVENT_DELETE:
1054                 /* Rport is being deleted */
1055                 break;
1056 
1057         default:
1058                 bfa_sm_fault(rport->fcs, event);
1059         }
1060 }
1061 
1062 /*
1063  *      Rport is going offline. Awaiting FC-4 offline completion callback.
1064  */
1065 static void
1066 bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
1067                         enum rport_event event)
1068 {
1069         bfa_trc(rport->fcs, rport->pwwn);
1070         bfa_trc(rport->fcs, rport->pid);
1071         bfa_trc(rport->fcs, event);
1072 
1073         switch (event) {
1074         case RPSM_EVENT_FC4_OFFLINE:
1075                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
1076                 bfa_fcs_rport_hal_offline(rport);
1077                 break;
1078 
1079         case RPSM_EVENT_SCN_ONLINE:
1080                 break;
1081         case RPSM_EVENT_LOGO_RCVD:
1082                 /*
1083                  * Rport is going offline. Just ack the logo
1084                  */
1085                 bfa_fcs_rport_send_logo_acc(rport);
1086                 break;
1087 
1088         case RPSM_EVENT_PRLO_RCVD:
1089                 bfa_fcs_rport_send_prlo_acc(rport);
1090                 break;
1091 
1092         case RPSM_EVENT_SCN_OFFLINE:
1093         case RPSM_EVENT_HCB_ONLINE:
1094         case RPSM_EVENT_FAB_SCN:
1095         case RPSM_EVENT_LOGO_IMP:
1096         case RPSM_EVENT_ADDRESS_CHANGE:
1097                 /*
1098                  * rport is already going offline.
1099                  * SCN - ignore and wait till transitioning to offline state
1100                  */
1101                 break;
1102 
1103         case RPSM_EVENT_DELETE:
1104                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
1105                 break;
1106 
1107         default:
1108                 bfa_sm_fault(rport->fcs, event);
1109         }
1110 }
1111 
1112 /*
1113  *              Rport is offline. FC-4s are offline. Awaiting BFA rport offline
1114  *              callback.
1115  */
1116 static void
1117 bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
1118                                 enum rport_event event)
1119 {
1120         bfa_trc(rport->fcs, rport->pwwn);
1121         bfa_trc(rport->fcs, rport->pid);
1122         bfa_trc(rport->fcs, event);
1123 
1124         switch (event) {
1125         case RPSM_EVENT_HCB_OFFLINE:
1126                 if (bfa_fcs_lport_is_online(rport->port) &&
1127                     (rport->plogi_pending)) {
1128                         rport->plogi_pending = BFA_FALSE;
1129                         bfa_sm_set_state(rport,
1130                                 bfa_fcs_rport_sm_plogiacc_sending);
1131                         bfa_fcs_rport_send_plogiacc(rport, NULL);
1132                         break;
1133                 }
1134                 /* fall through */
1135 
1136         case RPSM_EVENT_ADDRESS_CHANGE:
1137                 if (!bfa_fcs_lport_is_online(rport->port)) {
1138                         rport->pid = 0;
1139                         bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1140                         bfa_timer_start(rport->fcs->bfa, &rport->timer,
1141                                         bfa_fcs_rport_timeout, rport,
1142                                         bfa_fcs_rport_del_timeout);
1143                         break;
1144                 }
1145                 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
1146                         bfa_sm_set_state(rport,
1147                                 bfa_fcs_rport_sm_nsdisc_sending);
1148                         rport->ns_retries = 0;
1149                         bfa_fcs_rport_send_nsdisc(rport, NULL);
1150                 } else if (bfa_fcport_get_topology(rport->port->fcs->bfa) ==
1151                                         BFA_PORT_TOPOLOGY_LOOP) {
1152                         if (rport->scn_online) {
1153                                 bfa_sm_set_state(rport,
1154                                         bfa_fcs_rport_sm_adisc_offline_sending);
1155                                 bfa_fcs_rport_send_adisc(rport, NULL);
1156                         } else {
1157                                 bfa_sm_set_state(rport,
1158                                         bfa_fcs_rport_sm_offline);
1159                                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1160                                         bfa_fcs_rport_timeout, rport,
1161                                         bfa_fcs_rport_del_timeout);
1162                         }
1163                 } else {
1164                         bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1165                         rport->plogi_retries = 0;
1166                         bfa_fcs_rport_send_plogi(rport, NULL);
1167                 }
1168                 break;
1169 
1170         case RPSM_EVENT_DELETE:
1171                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1172                 bfa_fcs_rport_free(rport);
1173                 break;
1174 
1175         case RPSM_EVENT_SCN_ONLINE:
1176         case RPSM_EVENT_SCN_OFFLINE:
1177         case RPSM_EVENT_FAB_SCN:
1178         case RPSM_EVENT_LOGO_RCVD:
1179         case RPSM_EVENT_PRLO_RCVD:
1180         case RPSM_EVENT_PLOGI_RCVD:
1181         case RPSM_EVENT_LOGO_IMP:
1182                 /*
1183                  * Ignore, already offline.
1184                  */
1185                 break;
1186 
1187         default:
1188                 bfa_sm_fault(rport->fcs, event);
1189         }
1190 }
1191 
1192 /*
1193  *              Rport is offline. FC-4s are offline. Awaiting BFA rport offline
1194  *              callback to send LOGO accept.
1195  */
1196 static void
1197 bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
1198                         enum rport_event event)
1199 {
1200         bfa_trc(rport->fcs, rport->pwwn);
1201         bfa_trc(rport->fcs, rport->pid);
1202         bfa_trc(rport->fcs, event);
1203 
1204         switch (event) {
1205         case RPSM_EVENT_HCB_OFFLINE:
1206         case RPSM_EVENT_ADDRESS_CHANGE:
1207                 if (rport->pid && (rport->prlo == BFA_TRUE))
1208                         bfa_fcs_rport_send_prlo_acc(rport);
1209                 if (rport->pid && (rport->prlo == BFA_FALSE))
1210                         bfa_fcs_rport_send_logo_acc(rport);
1211                 /*
1212                  * If the lport is online and if the rport is not a well
1213                  * known address port,
1214                  * we try to re-discover the r-port.
1215                  */
1216                 if (bfa_fcs_lport_is_online(rport->port) &&
1217                         (!BFA_FCS_PID_IS_WKA(rport->pid))) {
1218                         if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
1219                                 bfa_sm_set_state(rport,
1220                                         bfa_fcs_rport_sm_nsdisc_sending);
1221                                 rport->ns_retries = 0;
1222                                 bfa_fcs_rport_send_nsdisc(rport, NULL);
1223                         } else {
1224                                 /* For N2N  Direct Attach, try to re-login */
1225                                 bfa_sm_set_state(rport,
1226                                         bfa_fcs_rport_sm_plogi_sending);
1227                                 rport->plogi_retries = 0;
1228                                 bfa_fcs_rport_send_plogi(rport, NULL);
1229                         }
1230                 } else {
1231                         /*
1232                          * if it is not a well known address, reset the
1233                          * pid to 0.
1234                          */
1235                         if (!BFA_FCS_PID_IS_WKA(rport->pid))
1236                                 rport->pid = 0;
1237                         bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1238                         bfa_timer_start(rport->fcs->bfa, &rport->timer,
1239                                         bfa_fcs_rport_timeout, rport,
1240                                         bfa_fcs_rport_del_timeout);
1241                 }
1242                 break;
1243 
1244         case RPSM_EVENT_DELETE:
1245                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
1246                 if (rport->pid && (rport->prlo == BFA_TRUE))
1247                         bfa_fcs_rport_send_prlo_acc(rport);
1248                 if (rport->pid && (rport->prlo == BFA_FALSE))
1249                         bfa_fcs_rport_send_logo_acc(rport);
1250                 break;
1251 
1252         case RPSM_EVENT_LOGO_IMP:
1253                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
1254                 break;
1255 
1256         case RPSM_EVENT_SCN_ONLINE:
1257         case RPSM_EVENT_SCN_OFFLINE:
1258         case RPSM_EVENT_LOGO_RCVD:
1259         case RPSM_EVENT_PRLO_RCVD:
1260                 /*
1261                  * Ignore - already processing a LOGO.
1262                  */
1263                 break;
1264 
1265         default:
1266                 bfa_sm_fault(rport->fcs, event);
1267         }
1268 }
1269 
1270 /*
1271  *              Rport is being deleted. FC-4s are offline.
1272  *  Awaiting BFA rport offline
1273  *              callback to send LOGO.
1274  */
1275 static void
1276 bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
1277                  enum rport_event event)
1278 {
1279         bfa_trc(rport->fcs, rport->pwwn);
1280         bfa_trc(rport->fcs, rport->pid);
1281         bfa_trc(rport->fcs, event);
1282 
1283         switch (event) {
1284         case RPSM_EVENT_HCB_OFFLINE:
1285                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending);
1286                 bfa_fcs_rport_send_logo(rport, NULL);
1287                 break;
1288 
1289         case RPSM_EVENT_LOGO_RCVD:
1290                 bfa_fcs_rport_send_logo_acc(rport);
1291                 /* fall through */
1292         case RPSM_EVENT_PRLO_RCVD:
1293                 if (rport->prlo == BFA_TRUE)
1294                         bfa_fcs_rport_send_prlo_acc(rport);
1295 
1296                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
1297                 break;
1298 
1299         case RPSM_EVENT_SCN_ONLINE:
1300         case RPSM_EVENT_SCN_OFFLINE:
1301         case RPSM_EVENT_ADDRESS_CHANGE:
1302                 break;
1303 
1304         default:
1305                 bfa_sm_fault(rport->fcs, event);
1306         }
1307 }
1308 
1309 /*
1310  *              Rport is being deleted. FC-4s are offline. LOGO is being sent.
1311  */
1312 static void
1313 bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
1314          enum rport_event event)
1315 {
1316         bfa_trc(rport->fcs, rport->pwwn);
1317         bfa_trc(rport->fcs, rport->pid);
1318         bfa_trc(rport->fcs, event);
1319 
1320         switch (event) {
1321         case RPSM_EVENT_FCXP_SENT:
1322                 /* Once LOGO is sent, we donot wait for the response */
1323                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1324                 bfa_fcs_rport_free(rport);
1325                 break;
1326 
1327         case RPSM_EVENT_SCN_ONLINE:
1328         case RPSM_EVENT_SCN_OFFLINE:
1329         case RPSM_EVENT_FAB_SCN:
1330         case RPSM_EVENT_ADDRESS_CHANGE:
1331                 break;
1332 
1333         case RPSM_EVENT_LOGO_RCVD:
1334                 bfa_fcs_rport_send_logo_acc(rport);
1335                 /* fall through */
1336         case RPSM_EVENT_PRLO_RCVD:
1337                 if (rport->prlo == BFA_TRUE)
1338                         bfa_fcs_rport_send_prlo_acc(rport);
1339 
1340                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1341                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1342                 bfa_fcs_rport_free(rport);
1343                 break;
1344 
1345         default:
1346                 bfa_sm_fault(rport->fcs, event);
1347         }
1348 }
1349 
1350 /*
1351  *              Rport is offline. FC-4s are offline. BFA rport is offline.
1352  *              Timer active to delete stale rport.
1353  */
1354 static void
1355 bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
1356 {
1357         bfa_trc(rport->fcs, rport->pwwn);
1358         bfa_trc(rport->fcs, rport->pid);
1359         bfa_trc(rport->fcs, event);
1360 
1361         switch (event) {
1362         case RPSM_EVENT_TIMEOUT:
1363                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1364                 bfa_fcs_rport_free(rport);
1365                 break;
1366 
1367         case RPSM_EVENT_FAB_SCN:
1368         case RPSM_EVENT_ADDRESS_CHANGE:
1369                 bfa_timer_stop(&rport->timer);
1370                 WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
1371                                         BFA_PORT_TOPOLOGY_LOOP));
1372                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1373                 rport->ns_retries = 0;
1374                 bfa_fcs_rport_send_nsdisc(rport, NULL);
1375                 break;
1376 
1377         case RPSM_EVENT_DELETE:
1378                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1379                 bfa_timer_stop(&rport->timer);
1380                 bfa_fcs_rport_free(rport);
1381                 break;
1382 
1383         case RPSM_EVENT_PLOGI_RCVD:
1384                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1385                 bfa_timer_stop(&rport->timer);
1386                 bfa_fcs_rport_send_plogiacc(rport, NULL);
1387                 break;
1388 
1389         case RPSM_EVENT_LOGO_RCVD:
1390         case RPSM_EVENT_PRLO_RCVD:
1391         case RPSM_EVENT_LOGO_IMP:
1392         case RPSM_EVENT_SCN_OFFLINE:
1393                 break;
1394 
1395         case RPSM_EVENT_PLOGI_COMP:
1396                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1397                 bfa_timer_stop(&rport->timer);
1398                 bfa_fcs_rport_fcs_online_action(rport);
1399                 break;
1400 
1401         case RPSM_EVENT_SCN_ONLINE:
1402                 bfa_timer_stop(&rport->timer);
1403                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1404                 bfa_fcs_rport_send_plogi(rport, NULL);
1405                 break;
1406 
1407         case RPSM_EVENT_PLOGI_SEND:
1408                 bfa_timer_stop(&rport->timer);
1409                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1410                 rport->plogi_retries = 0;
1411                 bfa_fcs_rport_send_plogi(rport, NULL);
1412                 break;
1413 
1414         default:
1415                 bfa_sm_fault(rport->fcs, event);
1416         }
1417 }
1418 
1419 /*
1420  *      Rport address has changed. Nameserver discovery request is being sent.
1421  */
1422 static void
1423 bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
1424          enum rport_event event)
1425 {
1426         bfa_trc(rport->fcs, rport->pwwn);
1427         bfa_trc(rport->fcs, rport->pid);
1428         bfa_trc(rport->fcs, event);
1429 
1430         switch (event) {
1431         case RPSM_EVENT_FCXP_SENT:
1432                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sent);
1433                 break;
1434 
1435         case RPSM_EVENT_DELETE:
1436                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1437                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1438                 bfa_fcs_rport_free(rport);
1439                 break;
1440 
1441         case RPSM_EVENT_PLOGI_RCVD:
1442                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1443                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1444                 bfa_fcs_rport_send_plogiacc(rport, NULL);
1445                 break;
1446 
1447         case RPSM_EVENT_FAB_SCN:
1448         case RPSM_EVENT_LOGO_RCVD:
1449         case RPSM_EVENT_PRLO_RCVD:
1450         case RPSM_EVENT_PLOGI_SEND:
1451                 break;
1452 
1453         case RPSM_EVENT_ADDRESS_CHANGE:
1454                 rport->ns_retries = 0; /* reset the retry count */
1455                 break;
1456 
1457         case RPSM_EVENT_LOGO_IMP:
1458                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1459                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1460                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1461                                 bfa_fcs_rport_timeout, rport,
1462                                 bfa_fcs_rport_del_timeout);
1463                 break;
1464 
1465         case RPSM_EVENT_PLOGI_COMP:
1466                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1467                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1468                 bfa_fcs_rport_fcs_online_action(rport);
1469                 break;
1470 
1471         default:
1472                 bfa_sm_fault(rport->fcs, event);
1473         }
1474 }
1475 
1476 /*
1477  *              Nameserver discovery failed. Waiting for timeout to retry.
1478  */
1479 static void
1480 bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
1481          enum rport_event event)
1482 {
1483         bfa_trc(rport->fcs, rport->pwwn);
1484         bfa_trc(rport->fcs, rport->pid);
1485         bfa_trc(rport->fcs, event);
1486 
1487         switch (event) {
1488         case RPSM_EVENT_TIMEOUT:
1489                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1490                 bfa_fcs_rport_send_nsdisc(rport, NULL);
1491                 break;
1492 
1493         case RPSM_EVENT_FAB_SCN:
1494         case RPSM_EVENT_ADDRESS_CHANGE:
1495                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1496                 bfa_timer_stop(&rport->timer);
1497                 rport->ns_retries = 0;
1498                 bfa_fcs_rport_send_nsdisc(rport, NULL);
1499                 break;
1500 
1501         case RPSM_EVENT_DELETE:
1502                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1503                 bfa_timer_stop(&rport->timer);
1504                 bfa_fcs_rport_free(rport);
1505                 break;
1506 
1507         case RPSM_EVENT_PLOGI_RCVD:
1508                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1509                 bfa_timer_stop(&rport->timer);
1510                 bfa_fcs_rport_send_plogiacc(rport, NULL);
1511                 break;
1512 
1513         case RPSM_EVENT_LOGO_IMP:
1514                 rport->pid = 0;
1515                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1516                 bfa_timer_stop(&rport->timer);
1517                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1518                                 bfa_fcs_rport_timeout, rport,
1519                                 bfa_fcs_rport_del_timeout);
1520                 break;
1521 
1522         case RPSM_EVENT_LOGO_RCVD:
1523                 bfa_fcs_rport_send_logo_acc(rport);
1524                 break;
1525         case RPSM_EVENT_PRLO_RCVD:
1526                 bfa_fcs_rport_send_prlo_acc(rport);
1527                 break;
1528 
1529         case RPSM_EVENT_PLOGI_COMP:
1530                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1531                 bfa_timer_stop(&rport->timer);
1532                 bfa_fcs_rport_fcs_online_action(rport);
1533                 break;
1534 
1535         default:
1536                 bfa_sm_fault(rport->fcs, event);
1537         }
1538 }
1539 
1540 /*
1541  *              Rport address has changed. Nameserver discovery request is sent.
1542  */
1543 static void
1544 bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
1545                         enum rport_event event)
1546 {
1547         bfa_trc(rport->fcs, rport->pwwn);
1548         bfa_trc(rport->fcs, rport->pid);
1549         bfa_trc(rport->fcs, event);
1550 
1551         switch (event) {
1552         case RPSM_EVENT_ACCEPTED:
1553         case RPSM_EVENT_ADDRESS_CHANGE:
1554                 if (rport->pid) {
1555                         bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1556                         bfa_fcs_rport_send_plogi(rport, NULL);
1557                 } else {
1558                         bfa_sm_set_state(rport,
1559                                  bfa_fcs_rport_sm_nsdisc_sending);
1560                         rport->ns_retries = 0;
1561                         bfa_fcs_rport_send_nsdisc(rport, NULL);
1562                 }
1563                 break;
1564 
1565         case RPSM_EVENT_FAILED:
1566                 rport->ns_retries++;
1567                 if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
1568                         bfa_sm_set_state(rport,
1569                                  bfa_fcs_rport_sm_nsdisc_sending);
1570                         bfa_fcs_rport_send_nsdisc(rport, NULL);
1571                 } else {
1572                         rport->old_pid = rport->pid;
1573                         rport->pid = 0;
1574                         bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1575                         bfa_timer_start(rport->fcs->bfa, &rport->timer,
1576                                         bfa_fcs_rport_timeout, rport,
1577                                         bfa_fcs_rport_del_timeout);
1578                 };
1579                 break;
1580 
1581         case RPSM_EVENT_DELETE:
1582                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1583                 bfa_fcxp_discard(rport->fcxp);
1584                 bfa_fcs_rport_free(rport);
1585                 break;
1586 
1587         case RPSM_EVENT_PLOGI_RCVD:
1588                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1589                 bfa_fcxp_discard(rport->fcxp);
1590                 bfa_fcs_rport_send_plogiacc(rport, NULL);
1591                 break;
1592 
1593         case RPSM_EVENT_LOGO_IMP:
1594                 rport->pid = 0;
1595                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1596                 bfa_fcxp_discard(rport->fcxp);
1597                 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1598                                 bfa_fcs_rport_timeout, rport,
1599                                 bfa_fcs_rport_del_timeout);
1600                 break;
1601 
1602 
1603         case RPSM_EVENT_PRLO_RCVD:
1604                 bfa_fcs_rport_send_prlo_acc(rport);
1605                 break;
1606         case RPSM_EVENT_FAB_SCN:
1607                 /*
1608                  * ignore, wait for NS query response
1609                  */
1610                 break;
1611 
1612         case RPSM_EVENT_LOGO_RCVD:
1613                 /*
1614                  * Not logged-in yet. Accept LOGO.
1615                  */
1616                 bfa_fcs_rport_send_logo_acc(rport);
1617                 break;
1618 
1619         case RPSM_EVENT_PLOGI_COMP:
1620                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1621                 bfa_fcxp_discard(rport->fcxp);
1622                 bfa_fcs_rport_fcs_online_action(rport);
1623                 break;
1624 
1625         default:
1626                 bfa_sm_fault(rport->fcs, event);
1627         }
1628 }
1629 
1630 /*
1631  * Rport needs to be deleted
1632  * waiting for ITNIM clean up to finish
1633  */
1634 static void
1635 bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport,
1636                                 enum rport_event event)
1637 {
1638         bfa_trc(rport->fcs, rport->pwwn);
1639         bfa_trc(rport->fcs, rport->pid);
1640         bfa_trc(rport->fcs, event);
1641 
1642         switch (event) {
1643         case RPSM_EVENT_FC4_OFFLINE:
1644                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
1645                 bfa_fcs_rport_hal_offline(rport);
1646                 break;
1647 
1648         case RPSM_EVENT_DELETE:
1649         case RPSM_EVENT_PLOGI_RCVD:
1650                 /* Ignore these events */
1651                 break;
1652 
1653         default:
1654                 bfa_sm_fault(rport->fcs, event);
1655                 break;
1656         }
1657 }
1658 
1659 /*
1660  * RPort needs to be deleted
1661  * waiting for BFA/FW to finish current processing
1662  */
1663 static void
1664 bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport,
1665                                 enum rport_event event)
1666 {
1667         bfa_trc(rport->fcs, rport->pwwn);
1668         bfa_trc(rport->fcs, rport->pid);
1669         bfa_trc(rport->fcs, event);
1670 
1671         switch (event) {
1672         case RPSM_EVENT_HCB_OFFLINE:
1673                 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1674                 bfa_fcs_rport_free(rport);
1675                 break;
1676 
1677         case RPSM_EVENT_DELETE:
1678         case RPSM_EVENT_LOGO_IMP:
1679         case RPSM_EVENT_PLOGI_RCVD:
1680                 /* Ignore these events */
1681                 break;
1682 
1683         default:
1684                 bfa_sm_fault(rport->fcs, event);
1685         }
1686 }
1687 
1688 /*
1689  *  fcs_rport_private FCS RPORT provate functions
1690  */
1691 
1692 static void
1693 bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1694 {
1695         struct bfa_fcs_rport_s *rport = rport_cbarg;
1696         struct bfa_fcs_lport_s *port = rport->port;
1697         struct fchs_s   fchs;
1698         int             len;
1699         struct bfa_fcxp_s *fcxp;
1700 
1701         bfa_trc(rport->fcs, rport->pwwn);
1702 
1703         fcxp = fcxp_alloced ? fcxp_alloced :
1704                bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1705         if (!fcxp) {
1706                 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1707                                 bfa_fcs_rport_send_plogi, rport, BFA_TRUE);
1708                 return;
1709         }
1710         rport->fcxp = fcxp;
1711 
1712         len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1713                                 bfa_fcs_lport_get_fcid(port), 0,
1714                                 port->port_cfg.pwwn, port->port_cfg.nwwn,
1715                                 bfa_fcport_get_maxfrsize(port->fcs->bfa),
1716                                 bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
1717 
1718         bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1719                         FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
1720                         (void *)rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1721 
1722         rport->stats.plogis++;
1723         bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1724 }
1725 
1726 static void
1727 bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1728                                 bfa_status_t req_status, u32 rsp_len,
1729                                 u32 resid_len, struct fchs_s *rsp_fchs)
1730 {
1731         struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1732         struct fc_logi_s        *plogi_rsp;
1733         struct fc_ls_rjt_s      *ls_rjt;
1734         struct bfa_fcs_rport_s *twin;
1735         struct list_head        *qe;
1736 
1737         bfa_trc(rport->fcs, rport->pwwn);
1738 
1739         /*
1740          * Sanity Checks
1741          */
1742         if (req_status != BFA_STATUS_OK) {
1743                 bfa_trc(rport->fcs, req_status);
1744                 rport->stats.plogi_failed++;
1745                 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1746                 return;
1747         }
1748 
1749         plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp);
1750 
1751         /*
1752          * Check for failure first.
1753          */
1754         if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) {
1755                 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
1756 
1757                 bfa_trc(rport->fcs, ls_rjt->reason_code);
1758                 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1759 
1760                 if ((ls_rjt->reason_code == FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD) &&
1761                  (ls_rjt->reason_code_expl == FC_LS_RJT_EXP_INSUFF_RES)) {
1762                         rport->stats.rjt_insuff_res++;
1763                         bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RETRY);
1764                         return;
1765                 }
1766 
1767                 rport->stats.plogi_rejects++;
1768                 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1769                 return;
1770         }
1771 
1772         /*
1773          * PLOGI is complete. Make sure this device is not one of the known
1774          * device with a new FC port address.
1775          */
1776         list_for_each(qe, &rport->port->rport_q) {
1777                 twin = (struct bfa_fcs_rport_s *) qe;
1778                 if (twin == rport)
1779                         continue;
1780                 if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) {
1781                         bfa_trc(rport->fcs, twin->pid);
1782                         bfa_trc(rport->fcs, rport->pid);
1783 
1784                         /* Update plogi stats in twin */
1785                         twin->stats.plogis  += rport->stats.plogis;
1786                         twin->stats.plogi_rejects  +=
1787                                  rport->stats.plogi_rejects;
1788                         twin->stats.plogi_timeouts  +=
1789                                  rport->stats.plogi_timeouts;
1790                         twin->stats.plogi_failed +=
1791                                  rport->stats.plogi_failed;
1792                         twin->stats.plogi_rcvd    += rport->stats.plogi_rcvd;
1793                         twin->stats.plogi_accs++;
1794 
1795                         bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
1796 
1797                         bfa_fcs_rport_update(twin, plogi_rsp);
1798                         twin->pid = rsp_fchs->s_id;
1799                         bfa_sm_send_event(twin, RPSM_EVENT_PLOGI_COMP);
1800                         return;
1801                 }
1802         }
1803 
1804         /*
1805          * Normal login path -- no evil twins.
1806          */
1807         rport->stats.plogi_accs++;
1808         bfa_fcs_rport_update(rport, plogi_rsp);
1809         bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1810 }
1811 
1812 static void
1813 bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1814 {
1815         struct bfa_fcs_rport_s *rport = rport_cbarg;
1816         struct bfa_fcs_lport_s *port = rport->port;
1817         struct fchs_s           fchs;
1818         int             len;
1819         struct bfa_fcxp_s *fcxp;
1820 
1821         bfa_trc(rport->fcs, rport->pwwn);
1822         bfa_trc(rport->fcs, rport->reply_oxid);
1823 
1824         fcxp = fcxp_alloced ? fcxp_alloced :
1825                bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
1826         if (!fcxp) {
1827                 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1828                                 bfa_fcs_rport_send_plogiacc, rport, BFA_FALSE);
1829                 return;
1830         }
1831         rport->fcxp = fcxp;
1832 
1833         len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1834                                  rport->pid, bfa_fcs_lport_get_fcid(port),
1835                                  rport->reply_oxid, port->port_cfg.pwwn,
1836                                  port->port_cfg.nwwn,
1837                                  bfa_fcport_get_maxfrsize(port->fcs->bfa),
1838                                  bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
1839 
1840         bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1841                         FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1842 
1843         bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1844 }
1845 
1846 static void
1847 bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1848 {
1849         struct bfa_fcs_rport_s *rport = rport_cbarg;
1850         struct bfa_fcs_lport_s *port = rport->port;
1851         struct fchs_s           fchs;
1852         int             len;
1853         struct bfa_fcxp_s *fcxp;
1854 
1855         bfa_trc(rport->fcs, rport->pwwn);
1856 
1857         fcxp = fcxp_alloced ? fcxp_alloced :
1858                bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1859         if (!fcxp) {
1860                 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1861                                 bfa_fcs_rport_send_adisc, rport, BFA_TRUE);
1862                 return;
1863         }
1864         rport->fcxp = fcxp;
1865 
1866         len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1867                                 bfa_fcs_lport_get_fcid(port), 0,
1868                                 port->port_cfg.pwwn, port->port_cfg.nwwn);
1869 
1870         bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1871                         FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response,
1872                         rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1873 
1874         rport->stats.adisc_sent++;
1875         bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1876 }
1877 
1878 static void
1879 bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1880                                 bfa_status_t req_status, u32 rsp_len,
1881                                 u32 resid_len, struct fchs_s *rsp_fchs)
1882 {
1883         struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1884         void            *pld = bfa_fcxp_get_rspbuf(fcxp);
1885         struct fc_ls_rjt_s      *ls_rjt;
1886 
1887         if (req_status != BFA_STATUS_OK) {
1888                 bfa_trc(rport->fcs, req_status);
1889                 rport->stats.adisc_failed++;
1890                 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1891                 return;
1892         }
1893 
1894         if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn,
1895                                 rport->nwwn)  == FC_PARSE_OK) {
1896                 rport->stats.adisc_accs++;
1897                 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1898                 return;
1899         }
1900 
1901         rport->stats.adisc_rejects++;
1902         ls_rjt = pld;
1903         bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code);
1904         bfa_trc(rport->fcs, ls_rjt->reason_code);
1905         bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1906         bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1907 }
1908 
1909 static void
1910 bfa_fcs_rport_send_nsdisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1911 {
1912         struct bfa_fcs_rport_s *rport = rport_cbarg;
1913         struct bfa_fcs_lport_s *port = rport->port;
1914         struct fchs_s   fchs;
1915         struct bfa_fcxp_s *fcxp;
1916         int             len;
1917         bfa_cb_fcxp_send_t cbfn;
1918 
1919         bfa_trc(rport->fcs, rport->pid);
1920 
1921         fcxp = fcxp_alloced ? fcxp_alloced :
1922                bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1923         if (!fcxp) {
1924                 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1925                                 bfa_fcs_rport_send_nsdisc, rport, BFA_TRUE);
1926                 return;
1927         }
1928         rport->fcxp = fcxp;
1929 
1930         if (rport->pwwn) {
1931                 len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1932                                 bfa_fcs_lport_get_fcid(port), 0, rport->pwwn);
1933                 cbfn = bfa_fcs_rport_gidpn_response;
1934         } else {
1935                 len = fc_gpnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1936                                 bfa_fcs_lport_get_fcid(port), 0, rport->pid);
1937                 cbfn = bfa_fcs_rport_gpnid_response;
1938         }
1939 
1940         bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1941                         FC_CLASS_3, len, &fchs, cbfn,
1942                         (void *)rport, FC_MAX_PDUSZ, FC_FCCT_TOV);
1943 
1944         bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1945 }
1946 
1947 static void
1948 bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1949                                 bfa_status_t req_status, u32 rsp_len,
1950                                 u32 resid_len, struct fchs_s *rsp_fchs)
1951 {
1952         struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1953         struct ct_hdr_s *cthdr;
1954         struct fcgs_gidpn_resp_s        *gidpn_rsp;
1955         struct bfa_fcs_rport_s  *twin;
1956         struct list_head        *qe;
1957 
1958         bfa_trc(rport->fcs, rport->pwwn);
1959 
1960         cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1961         cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1962 
1963         if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1964                 /* Check if the pid is the same as before. */
1965                 gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1);
1966 
1967                 if (gidpn_rsp->dap == rport->pid) {
1968                         /* Device is online  */
1969                         bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1970                 } else {
1971                         /*
1972                          * Device's PID has changed. We need to cleanup
1973                          * and re-login. If there is another device with
1974                          * the the newly discovered pid, send an scn notice
1975                          * so that its new pid can be discovered.
1976                          */
1977                         list_for_each(qe, &rport->port->rport_q) {
1978                                 twin = (struct bfa_fcs_rport_s *) qe;
1979                                 if (twin == rport)
1980                                         continue;
1981                                 if (gidpn_rsp->dap == twin->pid) {
1982                                         bfa_trc(rport->fcs, twin->pid);
1983                                         bfa_trc(rport->fcs, rport->pid);
1984 
1985                                         twin->pid = 0;
1986                                         bfa_sm_send_event(twin,
1987                                          RPSM_EVENT_ADDRESS_CHANGE);
1988                                 }
1989                         }
1990                         rport->pid = gidpn_rsp->dap;
1991                         bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_CHANGE);
1992                 }
1993                 return;
1994         }
1995 
1996         /*
1997          * Reject Response
1998          */
1999         switch (cthdr->reason_code) {
2000         case CT_RSN_LOGICAL_BUSY:
2001                 /*
2002                  * Need to retry
2003                  */
2004                 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
2005                 break;
2006 
2007         case CT_RSN_UNABLE_TO_PERF:
2008                 /*
2009                  * device doesn't exist : Start timer to cleanup this later.
2010                  */
2011                 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
2012                 break;
2013 
2014         default:
2015                 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
2016                 break;
2017         }
2018 }
2019 
2020 static void
2021 bfa_fcs_rport_gpnid_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
2022                                 bfa_status_t req_status, u32 rsp_len,
2023                                 u32 resid_len, struct fchs_s *rsp_fchs)
2024 {
2025         struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2026         struct ct_hdr_s *cthdr;
2027 
2028         bfa_trc(rport->fcs, rport->pwwn);
2029 
2030         cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2031         cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2032 
2033         if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2034                 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
2035                 return;
2036         }
2037 
2038         /*
2039          * Reject Response
2040          */
2041         switch (cthdr->reason_code) {
2042         case CT_RSN_LOGICAL_BUSY:
2043                 /*
2044                  * Need to retry
2045                  */
2046                 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
2047                 break;
2048 
2049         case CT_RSN_UNABLE_TO_PERF:
2050                 /*
2051                  * device doesn't exist : Start timer to cleanup this later.
2052                  */
2053                 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
2054                 break;
2055 
2056         default:
2057                 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
2058                 break;
2059         }
2060 }
2061 
2062 /*
2063  *      Called to send a logout to the rport.
2064  */
2065 static void
2066 bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2067 {
2068         struct bfa_fcs_rport_s *rport = rport_cbarg;
2069         struct bfa_fcs_lport_s *port;
2070         struct fchs_s   fchs;
2071         struct bfa_fcxp_s *fcxp;
2072         u16     len;
2073 
2074         bfa_trc(rport->fcs, rport->pid);
2075 
2076         port = rport->port;
2077 
2078         fcxp = fcxp_alloced ? fcxp_alloced :
2079                bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2080         if (!fcxp) {
2081                 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
2082                                 bfa_fcs_rport_send_logo, rport, BFA_FALSE);
2083                 return;
2084         }
2085         rport->fcxp = fcxp;
2086 
2087         len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
2088                                 bfa_fcs_lport_get_fcid(port), 0,
2089                                 bfa_fcs_lport_get_pwwn(port));
2090 
2091         bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2092                         FC_CLASS_3, len, &fchs, NULL,
2093                         rport, FC_MAX_PDUSZ, FC_ELS_TOV);
2094 
2095         rport->stats.logos++;
2096         bfa_fcxp_discard(rport->fcxp);
2097         bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
2098 }
2099 
2100 /*
2101  *      Send ACC for a LOGO received.
2102  */
2103 static void
2104 bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
2105 {
2106         struct bfa_fcs_rport_s *rport = rport_cbarg;
2107         struct bfa_fcs_lport_s *port;
2108         struct fchs_s   fchs;
2109         struct bfa_fcxp_s *fcxp;
2110         u16     len;
2111 
2112         bfa_trc(rport->fcs, rport->pid);
2113 
2114         port = rport->port;
2115 
2116         fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2117         if (!fcxp)
2118                 return;
2119 
2120         rport->stats.logo_rcvd++;
2121         len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2122                                 rport->pid, bfa_fcs_lport_get_fcid(port),
2123                                 rport->reply_oxid);
2124 
2125         bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2126                         FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2127 }
2128 
2129 /*
2130  *      brief
2131  *      This routine will be called by bfa_timer on timer timeouts.
2132  *
2133  *      param[in]       rport                   - pointer to bfa_fcs_lport_ns_t.
2134  *      param[out]      rport_status    - pointer to return vport status in
2135  *
2136  *      return
2137  *              void
2138  *
2139  *      Special Considerations:
2140  *
2141  *      note
2142  */
2143 static void
2144 bfa_fcs_rport_timeout(void *arg)
2145 {
2146         struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) arg;
2147 
2148         rport->stats.plogi_timeouts++;
2149         bfa_stats(rport->port, rport_plogi_timeouts);
2150         bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
2151 }
2152 
2153 static void
2154 bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
2155                         struct fchs_s *rx_fchs, u16 len)
2156 {
2157         struct bfa_fcxp_s *fcxp;
2158         struct fchs_s   fchs;
2159         struct bfa_fcs_lport_s *port = rport->port;
2160         struct fc_prli_s        *prli;
2161 
2162         bfa_trc(port->fcs, rx_fchs->s_id);
2163         bfa_trc(port->fcs, rx_fchs->d_id);
2164 
2165         rport->stats.prli_rcvd++;
2166 
2167         /*
2168          * We are in Initiator Mode
2169          */
2170         prli = (struct fc_prli_s *) (rx_fchs + 1);
2171 
2172         if (prli->parampage.servparams.target) {
2173                 /*
2174                  * PRLI from a target ?
2175                  * Send the Acc.
2176                  * PRLI sent by us will be used to transition the IT nexus,
2177                  * once the response is received from the target.
2178                  */
2179                 bfa_trc(port->fcs, rx_fchs->s_id);
2180                 rport->scsi_function = BFA_RPORT_TARGET;
2181         } else {
2182                 bfa_trc(rport->fcs, prli->parampage.type);
2183                 rport->scsi_function = BFA_RPORT_INITIATOR;
2184                 bfa_fcs_itnim_is_initiator(rport->itnim);
2185         }
2186 
2187         fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2188         if (!fcxp)
2189                 return;
2190 
2191         len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2192                                 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2193                                 rx_fchs->ox_id, port->port_cfg.roles);
2194 
2195         bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2196                         FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2197 }
2198 
2199 static void
2200 bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
2201                         struct fchs_s *rx_fchs, u16 len)
2202 {
2203         struct bfa_fcxp_s *fcxp;
2204         struct fchs_s   fchs;
2205         struct bfa_fcs_lport_s *port = rport->port;
2206         struct fc_rpsc_speed_info_s speeds;
2207         struct bfa_port_attr_s pport_attr;
2208 
2209         bfa_trc(port->fcs, rx_fchs->s_id);
2210         bfa_trc(port->fcs, rx_fchs->d_id);
2211 
2212         rport->stats.rpsc_rcvd++;
2213         speeds.port_speed_cap =
2214                 RPSC_SPEED_CAP_1G | RPSC_SPEED_CAP_2G | RPSC_SPEED_CAP_4G |
2215                 RPSC_SPEED_CAP_8G;
2216 
2217         /*
2218          * get curent speed from pport attributes from BFA
2219          */
2220         bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
2221 
2222         speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
2223 
2224         fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2225         if (!fcxp)
2226                 return;
2227 
2228         len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2229                                 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2230                                 rx_fchs->ox_id, &speeds);
2231 
2232         bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2233                         FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2234 }
2235 
2236 static void
2237 bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
2238                         struct fchs_s *rx_fchs, u16 len)
2239 {
2240         struct bfa_fcxp_s *fcxp;
2241         struct fchs_s   fchs;
2242         struct bfa_fcs_lport_s *port = rport->port;
2243         struct fc_adisc_s       *adisc;
2244 
2245         bfa_trc(port->fcs, rx_fchs->s_id);
2246         bfa_trc(port->fcs, rx_fchs->d_id);
2247 
2248         rport->stats.adisc_rcvd++;
2249 
2250         adisc = (struct fc_adisc_s *) (rx_fchs + 1);
2251 
2252         /*
2253          * Accept if the itnim for this rport is online.
2254          * Else reject the ADISC.
2255          */
2256         if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) {
2257 
2258                 fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2259                 if (!fcxp)
2260                         return;
2261 
2262                 len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2263                          rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2264                          rx_fchs->ox_id, port->port_cfg.pwwn,
2265                          port->port_cfg.nwwn);
2266 
2267                 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
2268                                 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
2269                                 FC_MAX_PDUSZ, 0);
2270         } else {
2271                 rport->stats.adisc_rejected++;
2272                 bfa_fcs_rport_send_ls_rjt(rport, rx_fchs,
2273                                           FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD,
2274                                           FC_LS_RJT_EXP_LOGIN_REQUIRED);
2275         }
2276 }
2277 
2278 static void
2279 bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport)
2280 {
2281         struct bfa_fcs_lport_s *port = rport->port;
2282         struct bfa_rport_info_s rport_info;
2283 
2284         rport_info.pid = rport->pid;
2285         rport_info.local_pid = port->pid;
2286         rport_info.lp_tag = port->lp_tag;
2287         rport_info.vf_id = port->fabric->vf_id;
2288         rport_info.vf_en = port->fabric->is_vf;
2289         rport_info.fc_class = rport->fc_cos;
2290         rport_info.cisc = rport->cisc;
2291         rport_info.max_frmsz = rport->maxfrsize;
2292         bfa_rport_online(rport->bfa_rport, &rport_info);
2293 }
2294 
2295 static void
2296 bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport)
2297 {
2298         if (rport->bfa_rport)
2299                 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
2300         else
2301                 bfa_cb_rport_offline(rport);
2302 }
2303 
2304 static struct bfa_fcs_rport_s *
2305 bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
2306 {
2307         struct bfa_fcs_s        *fcs = port->fcs;
2308         struct bfa_fcs_rport_s *rport;
2309         struct bfad_rport_s     *rport_drv;
2310 
2311         /*
2312          * allocate rport
2313          */
2314         if (fcs->num_rport_logins >= bfa_fcs_rport_max_logins) {
2315                 bfa_trc(fcs, rpid);
2316                 return NULL;
2317         }
2318 
2319         if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv)
2320                 != BFA_STATUS_OK) {
2321                 bfa_trc(fcs, rpid);
2322                 return NULL;
2323         }
2324 
2325         /*
2326          * Initialize r-port
2327          */
2328         rport->port = port;
2329         rport->fcs = fcs;
2330         rport->rp_drv = rport_drv;
2331         rport->pid = rpid;
2332         rport->pwwn = pwwn;
2333         rport->old_pid = 0;
2334 
2335         rport->bfa_rport = NULL;
2336 
2337         /*
2338          * allocate FC-4s
2339          */
2340         WARN_ON(!bfa_fcs_lport_is_initiator(port));
2341 
2342         if (bfa_fcs_lport_is_initiator(port)) {
2343                 rport->itnim = bfa_fcs_itnim_create(rport);
2344                 if (!rport->itnim) {
2345                         bfa_trc(fcs, rpid);
2346                         kfree(rport_drv);
2347                         return NULL;
2348                 }
2349         }
2350 
2351         bfa_fcs_lport_add_rport(port, rport);
2352         fcs->num_rport_logins++;
2353 
2354         bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
2355 
2356         /* Initialize the Rport Features(RPF) Sub Module  */
2357         if (!BFA_FCS_PID_IS_WKA(rport->pid))
2358                 bfa_fcs_rpf_init(rport);
2359 
2360         return rport;
2361 }
2362 
2363 
2364 static void
2365 bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
2366 {
2367         struct bfa_fcs_lport_s *port = rport->port;
2368         struct bfa_fcs_s *fcs = port->fcs;
2369 
2370         /*
2371          * - delete FC-4s
2372          * - delete BFA rport
2373          * - remove from queue of rports
2374          */
2375         rport->plogi_pending = BFA_FALSE;
2376 
2377         if (bfa_fcs_lport_is_initiator(port)) {
2378                 bfa_fcs_itnim_delete(rport->itnim);
2379                 if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid))
2380                         bfa_fcs_rpf_rport_offline(rport);
2381         }
2382 
2383         if (rport->bfa_rport) {
2384                 bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE);
2385                 rport->bfa_rport = NULL;
2386         }
2387 
2388         bfa_fcs_lport_del_rport(port, rport);
2389         fcs->num_rport_logins--;
2390         kfree(rport->rp_drv);
2391 }
2392 
2393 static void
2394 bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
2395                         enum bfa_rport_aen_event event,
2396                         struct bfa_rport_aen_data_s *data)
2397 {
2398         struct bfa_fcs_lport_s *port = rport->port;
2399         struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2400         struct bfa_aen_entry_s  *aen_entry;
2401 
2402         bfad_get_aen_entry(bfad, aen_entry);
2403         if (!aen_entry)
2404                 return;
2405 
2406         if (event == BFA_RPORT_AEN_QOS_PRIO)
2407                 aen_entry->aen_data.rport.priv.qos = data->priv.qos;
2408         else if (event == BFA_RPORT_AEN_QOS_FLOWID)
2409                 aen_entry->aen_data.rport.priv.qos = data->priv.qos;
2410 
2411         aen_entry->aen_data.rport.vf_id = rport->port->fabric->vf_id;
2412         aen_entry->aen_data.rport.ppwwn = bfa_fcs_lport_get_pwwn(
2413                                         bfa_fcs_get_base_port(rport->fcs));
2414         aen_entry->aen_data.rport.lpwwn = bfa_fcs_lport_get_pwwn(rport->port);
2415         aen_entry->aen_data.rport.rpwwn = rport->pwwn;
2416 
2417         /* Send the AEN notification */
2418         bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq,
2419                                   BFA_AEN_CAT_RPORT, event);
2420 }
2421 
2422 static void
2423 bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport)
2424 {
2425         if ((!rport->pid) || (!rport->pwwn)) {
2426                 bfa_trc(rport->fcs, rport->pid);
2427                 bfa_sm_fault(rport->fcs, rport->pid);
2428         }
2429 
2430         bfa_sm_send_event(rport->itnim, BFA_FCS_ITNIM_SM_FCS_ONLINE);
2431 }
2432 
2433 static void
2434 bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport)
2435 {
2436         struct bfa_fcs_lport_s *port = rport->port;
2437         struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2438         char    lpwwn_buf[BFA_STRING_32];
2439         char    rpwwn_buf[BFA_STRING_32];
2440 
2441         rport->stats.onlines++;
2442 
2443         if ((!rport->pid) || (!rport->pwwn)) {
2444                 bfa_trc(rport->fcs, rport->pid);
2445                 bfa_sm_fault(rport->fcs, rport->pid);
2446         }
2447 
2448         if (bfa_fcs_lport_is_initiator(port)) {
2449                 bfa_fcs_itnim_brp_online(rport->itnim);
2450                 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2451                         bfa_fcs_rpf_rport_online(rport);
2452         };
2453 
2454         wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2455         wwn2str(rpwwn_buf, rport->pwwn);
2456         if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
2457                 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2458                 "Remote port (WWN = %s) online for logical port (WWN = %s)\n",
2459                 rpwwn_buf, lpwwn_buf);
2460                 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL);
2461         }
2462 }
2463 
2464 static void
2465 bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport)
2466 {
2467         if (!BFA_FCS_PID_IS_WKA(rport->pid))
2468                 bfa_fcs_rpf_rport_offline(rport);
2469 
2470         bfa_fcs_itnim_rport_offline(rport->itnim);
2471 }
2472 
2473 static void
2474 bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport)
2475 {
2476         struct bfa_fcs_lport_s *port = rport->port;
2477         struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2478         char    lpwwn_buf[BFA_STRING_32];
2479         char    rpwwn_buf[BFA_STRING_32];
2480 
2481         if (!rport->bfa_rport) {
2482                 bfa_fcs_rport_fcs_offline_action(rport);
2483                 return;
2484         }
2485 
2486         rport->stats.offlines++;
2487 
2488         wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2489         wwn2str(rpwwn_buf, rport->pwwn);
2490         if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
2491                 if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) {
2492                         BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2493                                 "Remote port (WWN = %s) connectivity lost for "
2494                                 "logical port (WWN = %s)\n",
2495                                 rpwwn_buf, lpwwn_buf);
2496                         bfa_fcs_rport_aen_post(rport,
2497                                 BFA_RPORT_AEN_DISCONNECT, NULL);
2498                 } else {
2499                         BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2500                                 "Remote port (WWN = %s) offlined by "
2501                                 "logical port (WWN = %s)\n",
2502                                 rpwwn_buf, lpwwn_buf);
2503                         bfa_fcs_rport_aen_post(rport,
2504                                 BFA_RPORT_AEN_OFFLINE, NULL);
2505                 }
2506         }
2507 
2508         if (bfa_fcs_lport_is_initiator(port)) {
2509                 bfa_fcs_itnim_rport_offline(rport->itnim);
2510                 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2511                         bfa_fcs_rpf_rport_offline(rport);
2512         }
2513 }
2514 
2515 /*
2516  * Update rport parameters from PLOGI or PLOGI accept.
2517  */
2518 static void
2519 bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
2520 {
2521         bfa_fcs_lport_t *port = rport->port;
2522 
2523         /*
2524          * - port name
2525          * - node name
2526          */
2527         rport->pwwn = plogi->port_name;
2528         rport->nwwn = plogi->node_name;
2529 
2530         /*
2531          * - class of service
2532          */
2533         rport->fc_cos = 0;
2534         if (plogi->class3.class_valid)
2535                 rport->fc_cos = FC_CLASS_3;
2536 
2537         if (plogi->class2.class_valid)
2538                 rport->fc_cos |= FC_CLASS_2;
2539 
2540         /*
2541          * - CISC
2542          * - MAX receive frame size
2543          */
2544         rport->cisc = plogi->csp.cisc;
2545         if (be16_to_cpu(plogi->class3.rxsz) < be16_to_cpu(plogi->csp.rxsz))
2546                 rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz);
2547         else
2548                 rport->maxfrsize = be16_to_cpu(plogi->csp.rxsz);
2549 
2550         bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2551         bfa_trc(port->fcs, port->fabric->bb_credit);
2552         /*
2553          * Direct Attach P2P mode :
2554          * This is to handle a bug (233476) in IBM targets in Direct Attach
2555          *  Mode. Basically, in FLOGI Accept the target would have
2556          * erroneously set the BB Credit to the value used in the FLOGI
2557          * sent by the HBA. It uses the correct value (its own BB credit)
2558          * in PLOGI.
2559          */
2560         if ((!bfa_fcs_fabric_is_switched(port->fabric))  &&
2561                 (be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) {
2562 
2563                 bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2564                 bfa_trc(port->fcs, port->fabric->bb_credit);
2565 
2566                 port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred);
2567                 bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
2568                                           port->fabric->bb_credit);
2569         }
2570 
2571 }
2572 
2573 /*
2574  *      Called to handle LOGO received from an existing remote port.
2575  */
2576 static void
2577 bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
2578 {
2579         rport->reply_oxid = fchs->ox_id;
2580         bfa_trc(rport->fcs, rport->reply_oxid);
2581 
2582         rport->prlo = BFA_FALSE;
2583         rport->stats.logo_rcvd++;
2584         bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD);
2585 }
2586 
2587 
2588 
2589 /*
2590  *  fcs_rport_public FCS rport public interfaces
2591  */
2592 
2593 /*
2594  *      Called by bport/vport to create a remote port instance for a discovered
2595  *      remote device.
2596  *
2597  * @param[in] port      - base port or vport
2598  * @param[in] rpid      - remote port ID
2599  *
2600  * @return None
2601  */
2602 struct bfa_fcs_rport_s *
2603 bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid)
2604 {
2605         struct bfa_fcs_rport_s *rport;
2606 
2607         bfa_trc(port->fcs, rpid);
2608         rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid);
2609         if (!rport)
2610                 return NULL;
2611 
2612         bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
2613         return rport;
2614 }
2615 
2616 /*
2617  * Called to create a rport for which only the wwn is known.
2618  *
2619  * @param[in] port      - base port
2620  * @param[in] rpwwn     - remote port wwn
2621  *
2622  * @return None
2623  */
2624 struct bfa_fcs_rport_s *
2625 bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
2626 {
2627         struct bfa_fcs_rport_s *rport;
2628         bfa_trc(port->fcs, rpwwn);
2629         rport = bfa_fcs_rport_alloc(port, rpwwn, 0);
2630         if (!rport)
2631                 return NULL;
2632 
2633         bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC);
2634         return rport;
2635 }
2636 /*
2637  * Called by bport in private loop topology to indicate that a
2638  * rport has been discovered and plogi has been completed.
2639  *
2640  * @param[in] port      - base port or vport
2641  * @param[in] rpid      - remote port ID
2642  */
2643 void
2644 bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2645          struct fc_logi_s *plogi)
2646 {
2647         struct bfa_fcs_rport_s *rport;
2648 
2649         rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id);
2650         if (!rport)
2651                 return;
2652 
2653         bfa_fcs_rport_update(rport, plogi);
2654 
2655         bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP);
2656 }
2657 
2658 /*
2659  *      Called by bport/vport to handle PLOGI received from a new remote port.
2660  *      If an existing rport does a plogi, it will be handled separately.
2661  */
2662 void
2663 bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2664                                 struct fc_logi_s *plogi)
2665 {
2666         struct bfa_fcs_rport_s *rport;
2667 
2668         rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id);
2669         if (!rport)
2670                 return;
2671 
2672         bfa_fcs_rport_update(rport, plogi);
2673 
2674         rport->reply_oxid = fchs->ox_id;
2675         bfa_trc(rport->fcs, rport->reply_oxid);
2676 
2677         rport->stats.plogi_rcvd++;
2678         bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2679 }
2680 
2681 /*
2682  *      Called by bport/vport to handle PLOGI received from an existing
2683  *       remote port.
2684  */
2685 void
2686 bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2687                         struct fc_logi_s *plogi)
2688 {
2689         /*
2690          * @todo Handle P2P and initiator-initiator.
2691          */
2692 
2693         bfa_fcs_rport_update(rport, plogi);
2694 
2695         rport->reply_oxid = rx_fchs->ox_id;
2696         bfa_trc(rport->fcs, rport->reply_oxid);
2697 
2698         rport->pid = rx_fchs->s_id;
2699         bfa_trc(rport->fcs, rport->pid);
2700 
2701         rport->stats.plogi_rcvd++;
2702         bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2703 }
2704 
2705 
2706 /*
2707  *      Called by bport/vport to notify SCN for the remote port
2708  */
2709 void
2710 bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
2711 {
2712         rport->stats.rscns++;
2713         bfa_sm_send_event(rport, RPSM_EVENT_FAB_SCN);
2714 }
2715 
2716 /*
2717  *      brief
2718  *      This routine BFA callback for bfa_rport_online() call.
2719  *
2720  *      param[in]       cb_arg  -  rport struct.
2721  *
2722  *      return
2723  *              void
2724  *
2725  *      Special Considerations:
2726  *
2727  *      note
2728  */
2729 void
2730 bfa_cb_rport_online(void *cbarg)
2731 {
2732 
2733         struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2734 
2735         bfa_trc(rport->fcs, rport->pwwn);
2736         bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE);
2737 }
2738 
2739 /*
2740  *      brief
2741  *      This routine BFA callback for bfa_rport_offline() call.
2742  *
2743  *      param[in]       rport   -
2744  *
2745  *      return
2746  *              void
2747  *
2748  *      Special Considerations:
2749  *
2750  *      note
2751  */
2752 void
2753 bfa_cb_rport_offline(void *cbarg)
2754 {
2755         struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2756 
2757         bfa_trc(rport->fcs, rport->pwwn);
2758         bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE);
2759 }
2760 
2761 /*
2762  *      brief
2763  *      This routine is a static BFA callback when there is a QoS flow_id
2764  *      change notification
2765  *
2766  *      param[in]       rport   -
2767  *
2768  *      return
2769  *              void
2770  *
2771  *      Special Considerations:
2772  *
2773  *      note
2774  */
2775 void
2776 bfa_cb_rport_qos_scn_flowid(void *cbarg,
2777                 struct bfa_rport_qos_attr_s old_qos_attr,
2778                 struct bfa_rport_qos_attr_s new_qos_attr)
2779 {
2780         struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2781         struct bfa_rport_aen_data_s aen_data;
2782 
2783         bfa_trc(rport->fcs, rport->pwwn);
2784         aen_data.priv.qos = new_qos_attr;
2785         bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data);
2786 }
2787 
2788 void
2789 bfa_cb_rport_scn_online(struct bfa_s *bfa)
2790 {
2791         struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
2792         struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
2793         struct bfa_fcs_rport_s *rp;
2794         struct list_head *qe;
2795 
2796         list_for_each(qe, &port->rport_q) {
2797                 rp = (struct bfa_fcs_rport_s *) qe;
2798                 bfa_sm_send_event(rp, RPSM_EVENT_SCN_ONLINE);
2799                 rp->scn_online = BFA_TRUE;
2800         }
2801 
2802         if (bfa_fcs_lport_is_online(port))
2803                 bfa_fcs_lport_lip_scn_online(port);
2804 }
2805 
2806 void
2807 bfa_cb_rport_scn_no_dev(void *rport)
2808 {
2809         struct bfa_fcs_rport_s *rp = rport;
2810 
2811         bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE);
2812         rp->scn_online = BFA_FALSE;
2813 }
2814 
2815 void
2816 bfa_cb_rport_scn_offline(struct bfa_s *bfa)
2817 {
2818         struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
2819         struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
2820         struct bfa_fcs_rport_s *rp;
2821         struct list_head *qe;
2822 
2823         list_for_each(qe, &port->rport_q) {
2824                 rp = (struct bfa_fcs_rport_s *) qe;
2825                 bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE);
2826                 rp->scn_online = BFA_FALSE;
2827         }
2828 }
2829 
2830 /*
2831  *      brief
2832  *      This routine is a static BFA callback when there is a QoS priority
2833  *      change notification
2834  *
2835  *      param[in]       rport   -
2836  *
2837  *      return
2838  *              void
2839  *
2840  *      Special Considerations:
2841  *
2842  *      note
2843  */
2844 void
2845 bfa_cb_rport_qos_scn_prio(void *cbarg,
2846                 struct bfa_rport_qos_attr_s old_qos_attr,
2847                 struct bfa_rport_qos_attr_s new_qos_attr)
2848 {
2849         struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2850         struct bfa_rport_aen_data_s aen_data;
2851 
2852         bfa_trc(rport->fcs, rport->pwwn);
2853         aen_data.priv.qos = new_qos_attr;
2854         bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data);
2855 }
2856 
2857 /*
2858  *              Called to process any unsolicted frames from this remote port
2859  */
2860 void
2861 bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport,
2862                         struct fchs_s *fchs, u16 len)
2863 {
2864         struct bfa_fcs_lport_s *port = rport->port;
2865         struct fc_els_cmd_s     *els_cmd;
2866 
2867         bfa_trc(rport->fcs, fchs->s_id);
2868         bfa_trc(rport->fcs, fchs->d_id);
2869         bfa_trc(rport->fcs, fchs->type);
2870 
2871         if (fchs->type != FC_TYPE_ELS)
2872                 return;
2873 
2874         els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
2875 
2876         bfa_trc(rport->fcs, els_cmd->els_code);
2877 
2878         switch (els_cmd->els_code) {
2879         case FC_ELS_LOGO:
2880                 bfa_stats(port, plogi_rcvd);
2881                 bfa_fcs_rport_process_logo(rport, fchs);
2882                 break;
2883 
2884         case FC_ELS_ADISC:
2885                 bfa_stats(port, adisc_rcvd);
2886                 bfa_fcs_rport_process_adisc(rport, fchs, len);
2887                 break;
2888 
2889         case FC_ELS_PRLO:
2890                 bfa_stats(port, prlo_rcvd);
2891                 if (bfa_fcs_lport_is_initiator(port))
2892                         bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len);
2893                 break;
2894 
2895         case FC_ELS_PRLI:
2896                 bfa_stats(port, prli_rcvd);
2897                 bfa_fcs_rport_process_prli(rport, fchs, len);
2898                 break;
2899 
2900         case FC_ELS_RPSC:
2901                 bfa_stats(port, rpsc_rcvd);
2902                 bfa_fcs_rport_process_rpsc(rport, fchs, len);
2903                 break;
2904 
2905         default:
2906                 bfa_stats(port, un_handled_els_rcvd);
2907                 bfa_fcs_rport_send_ls_rjt(rport, fchs,
2908                                           FC_LS_RJT_RSN_CMD_NOT_SUPP,
2909                                           FC_LS_RJT_EXP_NO_ADDL_INFO);
2910                 break;
2911         }
2912 }
2913 
2914 /* send best case  acc to prlo */
2915 static void
2916 bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport)
2917 {
2918         struct bfa_fcs_lport_s *port = rport->port;
2919         struct fchs_s   fchs;
2920         struct bfa_fcxp_s *fcxp;
2921         int             len;
2922 
2923         bfa_trc(rport->fcs, rport->pid);
2924 
2925         fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2926         if (!fcxp)
2927                 return;
2928         len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2929                         rport->pid, bfa_fcs_lport_get_fcid(port),
2930                         rport->reply_oxid, 0);
2931 
2932         bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id,
2933                 port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs,
2934                 NULL, NULL, FC_MAX_PDUSZ, 0);
2935 }
2936 
2937 /*
2938  * Send a LS reject
2939  */
2940 static void
2941 bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2942                           u8 reason_code, u8 reason_code_expl)
2943 {
2944         struct bfa_fcs_lport_s *port = rport->port;
2945         struct fchs_s   fchs;
2946         struct bfa_fcxp_s *fcxp;
2947         int             len;
2948 
2949         bfa_trc(rport->fcs, rx_fchs->s_id);
2950 
2951         fcxp = bfa_fcs_fcxp_alloc(rport->fcs, BFA_FALSE);
2952         if (!fcxp)
2953                 return;
2954 
2955         len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2956                                 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2957                                 rx_fchs->ox_id, reason_code, reason_code_expl);
2958 
2959         bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
2960                         BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
2961                         FC_MAX_PDUSZ, 0);
2962 }
2963 
2964 /*
2965  * Return state of rport.
2966  */
2967 int
2968 bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport)
2969 {
2970         return bfa_sm_to_state(rport_sm_table, rport->sm);
2971 }
2972 
2973 
2974 /*
2975  *      brief
2976  *               Called by the Driver to set rport delete/ageout timeout
2977  *
2978  *      param[in]               rport timeout value in seconds.
2979  *
2980  *      return None
2981  */
2982 void
2983 bfa_fcs_rport_set_del_timeout(u8 rport_tmo)
2984 {
2985         /* convert to Millisecs */
2986         if (rport_tmo > 0)
2987                 bfa_fcs_rport_del_timeout = rport_tmo * 1000;
2988 }
2989 void
2990 bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id)
2991 {
2992         bfa_trc(rport->fcs, rport->pid);
2993 
2994         rport->prlo = BFA_TRUE;
2995         rport->reply_oxid = ox_id;
2996         bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD);
2997 }
2998 
2999 /*
3000  * Called by BFAD to set the max limit on number of bfa_fcs_rport allocation
3001  * which limits number of concurrent logins to remote ports
3002  */
3003 void
3004 bfa_fcs_rport_set_max_logins(u32 max_logins)
3005 {
3006         if (max_logins > 0)
3007                 bfa_fcs_rport_max_logins = max_logins;
3008 }
3009 
3010 void
3011 bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
3012                 struct bfa_rport_attr_s *rport_attr)
3013 {
3014         struct bfa_rport_qos_attr_s qos_attr;
3015         struct bfa_fcs_lport_s *port = rport->port;
3016         bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed;
3017         struct bfa_port_attr_s port_attr;
3018 
3019         bfa_fcport_get_attr(rport->fcs->bfa, &port_attr);
3020 
3021         memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
3022         memset(&qos_attr, 0, sizeof(struct bfa_rport_qos_attr_s));
3023 
3024         rport_attr->pid = rport->pid;
3025         rport_attr->pwwn = rport->pwwn;
3026         rport_attr->nwwn = rport->nwwn;
3027         rport_attr->cos_supported = rport->fc_cos;
3028         rport_attr->df_sz = rport->maxfrsize;
3029         rport_attr->state = bfa_fcs_rport_get_state(rport);
3030         rport_attr->fc_cos = rport->fc_cos;
3031         rport_attr->cisc = rport->cisc;
3032         rport_attr->scsi_function = rport->scsi_function;
3033         rport_attr->curr_speed  = rport->rpf.rpsc_speed;
3034         rport_attr->assigned_speed  = rport->rpf.assigned_speed;
3035 
3036         if (rport->bfa_rport) {
3037                 qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority;
3038                 qos_attr.qos_flow_id =
3039                         cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id);
3040         }
3041         rport_attr->qos_attr = qos_attr;
3042 
3043         rport_attr->trl_enforced = BFA_FALSE;
3044         if (bfa_fcport_is_ratelim(port->fcs->bfa) &&
3045             (rport->scsi_function == BFA_RPORT_TARGET)) {
3046                 if (rport_speed == BFA_PORT_SPEED_UNKNOWN)
3047                         rport_speed =
3048                                 bfa_fcport_get_ratelim_speed(rport->fcs->bfa);
3049 
3050                 if ((bfa_fcs_lport_get_rport_max_speed(port) !=
3051                     BFA_PORT_SPEED_UNKNOWN) && (rport_speed < port_attr.speed))
3052                         rport_attr->trl_enforced = BFA_TRUE;
3053         }
3054 }
3055 
3056 /*
3057  * Remote port implementation.
3058  */
3059 
3060 /*
3061  *  fcs_rport_api FCS rport API.
3062  */
3063 
3064 struct bfa_fcs_rport_s *
3065 bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
3066 {
3067         struct bfa_fcs_rport_s *rport;
3068 
3069         rport = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
3070         if (rport == NULL) {
3071                 /*
3072                  * TBD Error handling
3073                  */
3074         }
3075 
3076         return rport;
3077 }
3078 
3079 struct bfa_fcs_rport_s *
3080 bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn)
3081 {
3082         struct bfa_fcs_rport_s *rport;
3083 
3084         rport = bfa_fcs_lport_get_rport_by_nwwn(port, rnwwn);
3085         if (rport == NULL) {
3086                 /*
3087                  * TBD Error handling
3088                  */
3089         }
3090 
3091         return rport;
3092 }
3093 
3094 /*
3095  * Remote port features (RPF) implementation.
3096  */
3097 
3098 #define BFA_FCS_RPF_RETRIES     (3)
3099 #define BFA_FCS_RPF_RETRY_TIMEOUT  (1000) /* 1 sec (In millisecs) */
3100 
3101 static void     bfa_fcs_rpf_send_rpsc2(void *rport_cbarg,
3102                                 struct bfa_fcxp_s *fcxp_alloced);
3103 static void     bfa_fcs_rpf_rpsc2_response(void *fcsarg,
3104                         struct bfa_fcxp_s *fcxp,
3105                         void *cbarg,
3106                         bfa_status_t req_status,
3107                         u32 rsp_len,
3108                         u32 resid_len,
3109                         struct fchs_s *rsp_fchs);
3110 
3111 static void     bfa_fcs_rpf_timeout(void *arg);
3112 
3113 /*
3114  *  fcs_rport_ftrs_sm FCS rport state machine events
3115  */
3116 
3117 enum rpf_event {
3118         RPFSM_EVENT_RPORT_OFFLINE  = 1, /* Rport offline                */
3119         RPFSM_EVENT_RPORT_ONLINE   = 2, /* Rport online                 */
3120         RPFSM_EVENT_FCXP_SENT      = 3, /* Frame from has been sent     */
3121         RPFSM_EVENT_TIMEOUT        = 4, /* Rport SM timeout event       */
3122         RPFSM_EVENT_RPSC_COMP      = 5,
3123         RPFSM_EVENT_RPSC_FAIL      = 6,
3124         RPFSM_EVENT_RPSC_ERROR     = 7,
3125 };
3126 
3127 static void     bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf,
3128                                         enum rpf_event event);
3129 static void     bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf,
3130                                        enum rpf_event event);
3131 static void     bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf,
3132                                        enum rpf_event event);
3133 static void     bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf,
3134                                         enum rpf_event event);
3135 static void     bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf,
3136                                         enum rpf_event event);
3137 static void     bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf,
3138                                         enum rpf_event event);
3139 
3140 static void
3141 bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3142 {
3143         struct bfa_fcs_rport_s *rport = rpf->rport;
3144         struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric;
3145 
3146         bfa_trc(rport->fcs, rport->pwwn);
3147         bfa_trc(rport->fcs, rport->pid);
3148         bfa_trc(rport->fcs, event);
3149 
3150         switch (event) {
3151         case RPFSM_EVENT_RPORT_ONLINE:
3152                 /* Send RPSC2 to a Brocade fabric only. */
3153                 if ((!BFA_FCS_PID_IS_WKA(rport->pid)) &&
3154                         ((rport->port->fabric->lps->brcd_switch) ||
3155                         (bfa_fcs_fabric_get_switch_oui(fabric) ==
3156                                                 BFA_FCS_BRCD_SWITCH_OUI))) {
3157                         bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3158                         rpf->rpsc_retries = 0;
3159                         bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3160                 }
3161                 break;
3162 
3163         case RPFSM_EVENT_RPORT_OFFLINE:
3164                 break;
3165 
3166         default:
3167                 bfa_sm_fault(rport->fcs, event);
3168         }
3169 }
3170 
3171 static void
3172 bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3173 {
3174         struct bfa_fcs_rport_s *rport = rpf->rport;
3175 
3176         bfa_trc(rport->fcs, event);
3177 
3178         switch (event) {
3179         case RPFSM_EVENT_FCXP_SENT:
3180                 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc);
3181                 break;
3182 
3183         case RPFSM_EVENT_RPORT_OFFLINE:
3184                 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3185                 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe);
3186                 rpf->rpsc_retries = 0;
3187                 break;
3188 
3189         default:
3190                 bfa_sm_fault(rport->fcs, event);
3191         }
3192 }
3193 
3194 static void
3195 bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3196 {
3197         struct bfa_fcs_rport_s *rport = rpf->rport;
3198 
3199         bfa_trc(rport->fcs, rport->pid);
3200         bfa_trc(rport->fcs, event);
3201 
3202         switch (event) {
3203         case RPFSM_EVENT_RPSC_COMP:
3204                 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3205                 /* Update speed info in f/w via BFA */
3206                 if (rpf->rpsc_speed != BFA_PORT_SPEED_UNKNOWN)
3207                         bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed);
3208                 else if (rpf->assigned_speed != BFA_PORT_SPEED_UNKNOWN)
3209                         bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed);
3210                 break;
3211 
3212         case RPFSM_EVENT_RPSC_FAIL:
3213                 /* RPSC not supported by rport */
3214                 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3215                 break;
3216 
3217         case RPFSM_EVENT_RPSC_ERROR:
3218                 /* need to retry...delayed a bit. */
3219                 if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) {
3220                         bfa_timer_start(rport->fcs->bfa, &rpf->timer,
3221                                     bfa_fcs_rpf_timeout, rpf,
3222                                     BFA_FCS_RPF_RETRY_TIMEOUT);
3223                         bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry);
3224                 } else {
3225                         bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3226                 }
3227                 break;
3228 
3229         case RPFSM_EVENT_RPORT_OFFLINE:
3230                 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3231                 bfa_fcxp_discard(rpf->fcxp);
3232                 rpf->rpsc_retries = 0;
3233                 break;
3234 
3235         default:
3236                 bfa_sm_fault(rport->fcs, event);
3237         }
3238 }
3239 
3240 static void
3241 bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3242 {
3243         struct bfa_fcs_rport_s *rport = rpf->rport;
3244 
3245         bfa_trc(rport->fcs, rport->pid);
3246         bfa_trc(rport->fcs, event);
3247 
3248         switch (event) {
3249         case RPFSM_EVENT_TIMEOUT:
3250                 /* re-send the RPSC */
3251                 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3252                 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3253                 break;
3254 
3255         case RPFSM_EVENT_RPORT_OFFLINE:
3256                 bfa_timer_stop(&rpf->timer);
3257                 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3258                 rpf->rpsc_retries = 0;
3259                 break;
3260 
3261         default:
3262                 bfa_sm_fault(rport->fcs, event);
3263         }
3264 }
3265 
3266 static void
3267 bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3268 {
3269         struct bfa_fcs_rport_s *rport = rpf->rport;
3270 
3271         bfa_trc(rport->fcs, rport->pwwn);
3272         bfa_trc(rport->fcs, rport->pid);
3273         bfa_trc(rport->fcs, event);
3274 
3275         switch (event) {
3276         case RPFSM_EVENT_RPORT_OFFLINE:
3277                 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3278                 rpf->rpsc_retries = 0;
3279                 break;
3280 
3281         default:
3282                 bfa_sm_fault(rport->fcs, event);
3283         }
3284 }
3285 
3286 static void
3287 bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3288 {
3289         struct bfa_fcs_rport_s *rport = rpf->rport;
3290 
3291         bfa_trc(rport->fcs, rport->pwwn);
3292         bfa_trc(rport->fcs, rport->pid);
3293         bfa_trc(rport->fcs, event);
3294 
3295         switch (event) {
3296         case RPFSM_EVENT_RPORT_ONLINE:
3297                 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3298                 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3299                 break;
3300 
3301         case RPFSM_EVENT_RPORT_OFFLINE:
3302                 break;
3303 
3304         default:
3305                 bfa_sm_fault(rport->fcs, event);
3306         }
3307 }
3308 /*
3309  * Called when Rport is created.
3310  */
3311 void
3312 bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport)
3313 {
3314         struct bfa_fcs_rpf_s *rpf = &rport->rpf;
3315 
3316         bfa_trc(rport->fcs, rport->pid);
3317         rpf->rport = rport;
3318 
3319         bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit);
3320 }
3321 
3322 /*
3323  * Called when Rport becomes online
3324  */
3325 void
3326 bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport)
3327 {
3328         bfa_trc(rport->fcs, rport->pid);
3329 
3330         if (__fcs_min_cfg(rport->port->fcs))
3331                 return;
3332 
3333         if (bfa_fcs_fabric_is_switched(rport->port->fabric))
3334                 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE);
3335 }
3336 
3337 /*
3338  * Called when Rport becomes offline
3339  */
3340 void
3341 bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport)
3342 {
3343         bfa_trc(rport->fcs, rport->pid);
3344 
3345         if (__fcs_min_cfg(rport->port->fcs))
3346                 return;
3347 
3348         rport->rpf.rpsc_speed = 0;
3349         bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE);
3350 }
3351 
3352 static void
3353 bfa_fcs_rpf_timeout(void *arg)
3354 {
3355         struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg;
3356         struct bfa_fcs_rport_s *rport = rpf->rport;
3357 
3358         bfa_trc(rport->fcs, rport->pid);
3359         bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT);
3360 }
3361 
3362 static void
3363 bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3364 {
3365         struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg;
3366         struct bfa_fcs_rport_s *rport = rpf->rport;
3367         struct bfa_fcs_lport_s *port = rport->port;
3368         struct fchs_s   fchs;
3369         int             len;
3370         struct bfa_fcxp_s *fcxp;
3371 
3372         bfa_trc(rport->fcs, rport->pwwn);
3373 
3374         fcxp = fcxp_alloced ? fcxp_alloced :
3375                bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3376         if (!fcxp) {
3377                 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe,
3378                                 bfa_fcs_rpf_send_rpsc2, rpf, BFA_TRUE);
3379                 return;
3380         }
3381         rpf->fcxp = fcxp;
3382 
3383         len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
3384                             bfa_fcs_lport_get_fcid(port), &rport->pid, 1);
3385 
3386         bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3387                           FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response,
3388                           rpf, FC_MAX_PDUSZ, FC_ELS_TOV);
3389         rport->stats.rpsc_sent++;
3390         bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT);
3391 
3392 }
3393 
3394 static void
3395 bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
3396                             bfa_status_t req_status, u32 rsp_len,
3397                             u32 resid_len, struct fchs_s *rsp_fchs)
3398 {
3399         struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg;
3400         struct bfa_fcs_rport_s *rport = rpf->rport;
3401         struct fc_ls_rjt_s *ls_rjt;
3402         struct fc_rpsc2_acc_s *rpsc2_acc;
3403         u16     num_ents;
3404 
3405         bfa_trc(rport->fcs, req_status);
3406 
3407         if (req_status != BFA_STATUS_OK) {
3408                 bfa_trc(rport->fcs, req_status);
3409                 if (req_status == BFA_STATUS_ETIMER)
3410                         rport->stats.rpsc_failed++;
3411                 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3412                 return;
3413         }
3414 
3415         rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp);
3416         if (rpsc2_acc->els_cmd == FC_ELS_ACC) {
3417                 rport->stats.rpsc_accs++;
3418                 num_ents = be16_to_cpu(rpsc2_acc->num_pids);
3419                 bfa_trc(rport->fcs, num_ents);
3420                 if (num_ents > 0) {
3421                         WARN_ON(be32_to_cpu(rpsc2_acc->port_info[0].pid) !=
3422                                                 bfa_ntoh3b(rport->pid));
3423                         bfa_trc(rport->fcs,
3424                                 be32_to_cpu(rpsc2_acc->port_info[0].pid));
3425                         bfa_trc(rport->fcs,
3426                                 be16_to_cpu(rpsc2_acc->port_info[0].speed));
3427                         bfa_trc(rport->fcs,
3428                                 be16_to_cpu(rpsc2_acc->port_info[0].index));
3429                         bfa_trc(rport->fcs,
3430                                 rpsc2_acc->port_info[0].type);
3431 
3432                         if (rpsc2_acc->port_info[0].speed == 0) {
3433                                 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3434                                 return;
3435                         }
3436 
3437                         rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed(
3438                                 be16_to_cpu(rpsc2_acc->port_info[0].speed));
3439 
3440                         bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP);
3441                 }
3442         } else {
3443                 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3444                 bfa_trc(rport->fcs, ls_rjt->reason_code);
3445                 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
3446                 rport->stats.rpsc_rejects++;
3447                 if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP)
3448                         bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL);
3449                 else
3450                         bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3451         }
3452 }

/* [<][>][^][v][top][bottom][index][help] */