1 /* 2 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. 3 * Copyright (c) 2014- QLogic Corporation. 4 * All rights reserved 5 * www.qlogic.com 6 * 7 * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License (GPL) Version 2 as 11 * published by the Free Software Foundation 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 */ 18 19 #include "bfad_drv.h" 20 #include "bfad_im.h" 21 #include "bfa_plog.h" 22 #include "bfa_cs.h" 23 #include "bfa_modules.h" 24 25 BFA_TRC_FILE(HAL, FCXP); 26 27 /* 28 * LPS related definitions 29 */ 30 #define BFA_LPS_MIN_LPORTS (1) 31 #define BFA_LPS_MAX_LPORTS (256) 32 33 /* 34 * Maximum Vports supported per physical port or vf. 35 */ 36 #define BFA_LPS_MAX_VPORTS_SUPP_CB 255 37 #define BFA_LPS_MAX_VPORTS_SUPP_CT 190 38 39 40 /* 41 * FC PORT related definitions 42 */ 43 /* 44 * The port is considered disabled if corresponding physical port or IOC are 45 * disabled explicitly 46 */ 47 #define BFA_PORT_IS_DISABLED(bfa) \ 48 ((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \ 49 (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE)) 50 51 /* 52 * BFA port state machine events 53 */ 54 enum bfa_fcport_sm_event { 55 BFA_FCPORT_SM_START = 1, /* start port state machine */ 56 BFA_FCPORT_SM_STOP = 2, /* stop port state machine */ 57 BFA_FCPORT_SM_ENABLE = 3, /* enable port */ 58 BFA_FCPORT_SM_DISABLE = 4, /* disable port state machine */ 59 BFA_FCPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */ 60 BFA_FCPORT_SM_LINKUP = 6, /* firmware linkup event */ 61 BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */ 62 BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */ 63 BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */ 64 BFA_FCPORT_SM_DPORTENABLE = 10, /* enable dport */ 65 BFA_FCPORT_SM_DPORTDISABLE = 11,/* disable dport */ 66 BFA_FCPORT_SM_FAA_MISCONFIG = 12, /* FAA misconfiguratin */ 67 BFA_FCPORT_SM_DDPORTENABLE = 13, /* enable ddport */ 68 BFA_FCPORT_SM_DDPORTDISABLE = 14, /* disable ddport */ 69 }; 70 71 /* 72 * BFA port link notification state machine events 73 */ 74 75 enum bfa_fcport_ln_sm_event { 76 BFA_FCPORT_LN_SM_LINKUP = 1, /* linkup event */ 77 BFA_FCPORT_LN_SM_LINKDOWN = 2, /* linkdown event */ 78 BFA_FCPORT_LN_SM_NOTIFICATION = 3 /* done notification */ 79 }; 80 81 /* 82 * RPORT related definitions 83 */ 84 #define bfa_rport_offline_cb(__rp) do { \ 85 if ((__rp)->bfa->fcs) \ 86 bfa_cb_rport_offline((__rp)->rport_drv); \ 87 else { \ 88 bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \ 89 __bfa_cb_rport_offline, (__rp)); \ 90 } \ 91 } while (0) 92 93 #define bfa_rport_online_cb(__rp) do { \ 94 if ((__rp)->bfa->fcs) \ 95 bfa_cb_rport_online((__rp)->rport_drv); \ 96 else { \ 97 bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \ 98 __bfa_cb_rport_online, (__rp)); \ 99 } \ 100 } while (0) 101 102 /* 103 * forward declarations FCXP related functions 104 */ 105 static void __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete); 106 static void hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp, 107 struct bfi_fcxp_send_rsp_s *fcxp_rsp); 108 static void hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, 109 struct bfa_fcxp_s *fcxp, struct fchs_s *fchs); 110 static void bfa_fcxp_qresume(void *cbarg); 111 static void bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, 112 struct bfi_fcxp_send_req_s *send_req); 113 114 /* 115 * forward declarations for LPS functions 116 */ 117 static void bfa_lps_login_rsp(struct bfa_s *bfa, 118 struct bfi_lps_login_rsp_s *rsp); 119 static void bfa_lps_no_res(struct bfa_lps_s *first_lps, u8 count); 120 static void bfa_lps_logout_rsp(struct bfa_s *bfa, 121 struct bfi_lps_logout_rsp_s *rsp); 122 static void bfa_lps_reqq_resume(void *lps_arg); 123 static void bfa_lps_free(struct bfa_lps_s *lps); 124 static void bfa_lps_send_login(struct bfa_lps_s *lps); 125 static void bfa_lps_send_logout(struct bfa_lps_s *lps); 126 static void bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps); 127 static void bfa_lps_login_comp(struct bfa_lps_s *lps); 128 static void bfa_lps_logout_comp(struct bfa_lps_s *lps); 129 static void bfa_lps_cvl_event(struct bfa_lps_s *lps); 130 131 /* 132 * forward declaration for LPS state machine 133 */ 134 static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event); 135 static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event); 136 static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event 137 event); 138 static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event); 139 static void bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, 140 enum bfa_lps_event event); 141 static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event); 142 static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event 143 event); 144 145 /* 146 * forward declaration for FC Port functions 147 */ 148 static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport); 149 static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport); 150 static void bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport); 151 static void bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport); 152 static void bfa_fcport_set_wwns(struct bfa_fcport_s *fcport); 153 static void __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete); 154 static void bfa_fcport_scn(struct bfa_fcport_s *fcport, 155 enum bfa_port_linkstate event, bfa_boolean_t trunk); 156 static void bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, 157 enum bfa_port_linkstate event); 158 static void __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete); 159 static void bfa_fcport_stats_get_timeout(void *cbarg); 160 static void bfa_fcport_stats_clr_timeout(void *cbarg); 161 static void bfa_trunk_iocdisable(struct bfa_s *bfa); 162 163 /* 164 * forward declaration for FC PORT state machine 165 */ 166 static void bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport, 167 enum bfa_fcport_sm_event event); 168 static void bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, 169 enum bfa_fcport_sm_event event); 170 static void bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, 171 enum bfa_fcport_sm_event event); 172 static void bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, 173 enum bfa_fcport_sm_event event); 174 static void bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, 175 enum bfa_fcport_sm_event event); 176 static void bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport, 177 enum bfa_fcport_sm_event event); 178 static void bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport, 179 enum bfa_fcport_sm_event event); 180 static void bfa_fcport_sm_toggling_qwait(struct bfa_fcport_s *fcport, 181 enum bfa_fcport_sm_event event); 182 static void bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, 183 enum bfa_fcport_sm_event event); 184 static void bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport, 185 enum bfa_fcport_sm_event event); 186 static void bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, 187 enum bfa_fcport_sm_event event); 188 static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, 189 enum bfa_fcport_sm_event event); 190 static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, 191 enum bfa_fcport_sm_event event); 192 static void bfa_fcport_sm_ddport(struct bfa_fcport_s *fcport, 193 enum bfa_fcport_sm_event event); 194 static void bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport, 195 enum bfa_fcport_sm_event event); 196 197 static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, 198 enum bfa_fcport_ln_sm_event event); 199 static void bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln, 200 enum bfa_fcport_ln_sm_event event); 201 static void bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln, 202 enum bfa_fcport_ln_sm_event event); 203 static void bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln, 204 enum bfa_fcport_ln_sm_event event); 205 static void bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln, 206 enum bfa_fcport_ln_sm_event event); 207 static void bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln, 208 enum bfa_fcport_ln_sm_event event); 209 static void bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln, 210 enum bfa_fcport_ln_sm_event event); 211 212 static struct bfa_sm_table_s hal_port_sm_table[] = { 213 {BFA_SM(bfa_fcport_sm_uninit), BFA_PORT_ST_UNINIT}, 214 {BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PORT_ST_ENABLING_QWAIT}, 215 {BFA_SM(bfa_fcport_sm_enabling), BFA_PORT_ST_ENABLING}, 216 {BFA_SM(bfa_fcport_sm_linkdown), BFA_PORT_ST_LINKDOWN}, 217 {BFA_SM(bfa_fcport_sm_linkup), BFA_PORT_ST_LINKUP}, 218 {BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PORT_ST_DISABLING_QWAIT}, 219 {BFA_SM(bfa_fcport_sm_toggling_qwait), BFA_PORT_ST_TOGGLING_QWAIT}, 220 {BFA_SM(bfa_fcport_sm_disabling), BFA_PORT_ST_DISABLING}, 221 {BFA_SM(bfa_fcport_sm_disabled), BFA_PORT_ST_DISABLED}, 222 {BFA_SM(bfa_fcport_sm_stopped), BFA_PORT_ST_STOPPED}, 223 {BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN}, 224 {BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN}, 225 {BFA_SM(bfa_fcport_sm_dport), BFA_PORT_ST_DPORT}, 226 {BFA_SM(bfa_fcport_sm_ddport), BFA_PORT_ST_DDPORT}, 227 {BFA_SM(bfa_fcport_sm_faa_misconfig), BFA_PORT_ST_FAA_MISCONFIG}, 228 }; 229 230 231 /* 232 * forward declaration for RPORT related functions 233 */ 234 static struct bfa_rport_s *bfa_rport_alloc(struct bfa_rport_mod_s *rp_mod); 235 static void bfa_rport_free(struct bfa_rport_s *rport); 236 static bfa_boolean_t bfa_rport_send_fwcreate(struct bfa_rport_s *rp); 237 static bfa_boolean_t bfa_rport_send_fwdelete(struct bfa_rport_s *rp); 238 static bfa_boolean_t bfa_rport_send_fwspeed(struct bfa_rport_s *rp); 239 static void __bfa_cb_rport_online(void *cbarg, 240 bfa_boolean_t complete); 241 static void __bfa_cb_rport_offline(void *cbarg, 242 bfa_boolean_t complete); 243 244 /* 245 * forward declaration for RPORT state machine 246 */ 247 static void bfa_rport_sm_uninit(struct bfa_rport_s *rp, 248 enum bfa_rport_event event); 249 static void bfa_rport_sm_created(struct bfa_rport_s *rp, 250 enum bfa_rport_event event); 251 static void bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, 252 enum bfa_rport_event event); 253 static void bfa_rport_sm_online(struct bfa_rport_s *rp, 254 enum bfa_rport_event event); 255 static void bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, 256 enum bfa_rport_event event); 257 static void bfa_rport_sm_offline(struct bfa_rport_s *rp, 258 enum bfa_rport_event event); 259 static void bfa_rport_sm_deleting(struct bfa_rport_s *rp, 260 enum bfa_rport_event event); 261 static void bfa_rport_sm_offline_pending(struct bfa_rport_s *rp, 262 enum bfa_rport_event event); 263 static void bfa_rport_sm_delete_pending(struct bfa_rport_s *rp, 264 enum bfa_rport_event event); 265 static void bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, 266 enum bfa_rport_event event); 267 static void bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, 268 enum bfa_rport_event event); 269 static void bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, 270 enum bfa_rport_event event); 271 static void bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, 272 enum bfa_rport_event event); 273 274 /* 275 * PLOG related definitions 276 */ 277 static int 278 plkd_validate_logrec(struct bfa_plog_rec_s *pl_rec) 279 { 280 if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT) && 281 (pl_rec->log_type != BFA_PL_LOG_TYPE_STRING)) 282 return 1; 283 284 if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT) && 285 (pl_rec->log_num_ints > BFA_PL_INT_LOG_SZ)) 286 return 1; 287 288 return 0; 289 } 290 291 static void 292 bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec) 293 { 294 u16 tail; 295 struct bfa_plog_rec_s *pl_recp; 296 297 if (plog->plog_enabled == 0) 298 return; 299 300 if (plkd_validate_logrec(pl_rec)) { 301 WARN_ON(1); 302 return; 303 } 304 305 tail = plog->tail; 306 307 pl_recp = &(plog->plog_recs[tail]); 308 309 memcpy(pl_recp, pl_rec, sizeof(struct bfa_plog_rec_s)); 310 311 pl_recp->tv = ktime_get_real_seconds(); 312 BFA_PL_LOG_REC_INCR(plog->tail); 313 314 if (plog->head == plog->tail) 315 BFA_PL_LOG_REC_INCR(plog->head); 316 } 317 318 void 319 bfa_plog_init(struct bfa_plog_s *plog) 320 { 321 memset((char *)plog, 0, sizeof(struct bfa_plog_s)); 322 323 memcpy(plog->plog_sig, BFA_PL_SIG_STR, BFA_PL_SIG_LEN); 324 plog->head = plog->tail = 0; 325 plog->plog_enabled = 1; 326 } 327 328 void 329 bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid, 330 enum bfa_plog_eid event, 331 u16 misc, char *log_str) 332 { 333 struct bfa_plog_rec_s lp; 334 335 if (plog->plog_enabled) { 336 memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); 337 lp.mid = mid; 338 lp.eid = event; 339 lp.log_type = BFA_PL_LOG_TYPE_STRING; 340 lp.misc = misc; 341 strlcpy(lp.log_entry.string_log, log_str, 342 BFA_PL_STRING_LOG_SZ); 343 lp.log_entry.string_log[BFA_PL_STRING_LOG_SZ - 1] = '\0'; 344 bfa_plog_add(plog, &lp); 345 } 346 } 347 348 void 349 bfa_plog_intarr(struct bfa_plog_s *plog, enum bfa_plog_mid mid, 350 enum bfa_plog_eid event, 351 u16 misc, u32 *intarr, u32 num_ints) 352 { 353 struct bfa_plog_rec_s lp; 354 u32 i; 355 356 if (num_ints > BFA_PL_INT_LOG_SZ) 357 num_ints = BFA_PL_INT_LOG_SZ; 358 359 if (plog->plog_enabled) { 360 memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); 361 lp.mid = mid; 362 lp.eid = event; 363 lp.log_type = BFA_PL_LOG_TYPE_INT; 364 lp.misc = misc; 365 366 for (i = 0; i < num_ints; i++) 367 lp.log_entry.int_log[i] = intarr[i]; 368 369 lp.log_num_ints = (u8) num_ints; 370 371 bfa_plog_add(plog, &lp); 372 } 373 } 374 375 void 376 bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid, 377 enum bfa_plog_eid event, 378 u16 misc, struct fchs_s *fchdr) 379 { 380 struct bfa_plog_rec_s lp; 381 u32 *tmp_int = (u32 *) fchdr; 382 u32 ints[BFA_PL_INT_LOG_SZ]; 383 384 if (plog->plog_enabled) { 385 memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); 386 387 ints[0] = tmp_int[0]; 388 ints[1] = tmp_int[1]; 389 ints[2] = tmp_int[4]; 390 391 bfa_plog_intarr(plog, mid, event, misc, ints, 3); 392 } 393 } 394 395 void 396 bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid, 397 enum bfa_plog_eid event, u16 misc, struct fchs_s *fchdr, 398 u32 pld_w0) 399 { 400 struct bfa_plog_rec_s lp; 401 u32 *tmp_int = (u32 *) fchdr; 402 u32 ints[BFA_PL_INT_LOG_SZ]; 403 404 if (plog->plog_enabled) { 405 memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); 406 407 ints[0] = tmp_int[0]; 408 ints[1] = tmp_int[1]; 409 ints[2] = tmp_int[4]; 410 ints[3] = pld_w0; 411 412 bfa_plog_intarr(plog, mid, event, misc, ints, 4); 413 } 414 } 415 416 417 /* 418 * fcxp_pvt BFA FCXP private functions 419 */ 420 421 static void 422 claim_fcxps_mem(struct bfa_fcxp_mod_s *mod) 423 { 424 u16 i; 425 struct bfa_fcxp_s *fcxp; 426 427 fcxp = (struct bfa_fcxp_s *) bfa_mem_kva_curp(mod); 428 memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps); 429 430 INIT_LIST_HEAD(&mod->fcxp_req_free_q); 431 INIT_LIST_HEAD(&mod->fcxp_rsp_free_q); 432 INIT_LIST_HEAD(&mod->fcxp_active_q); 433 INIT_LIST_HEAD(&mod->fcxp_req_unused_q); 434 INIT_LIST_HEAD(&mod->fcxp_rsp_unused_q); 435 436 mod->fcxp_list = fcxp; 437 438 for (i = 0; i < mod->num_fcxps; i++) { 439 fcxp->fcxp_mod = mod; 440 fcxp->fcxp_tag = i; 441 442 if (i < (mod->num_fcxps / 2)) { 443 list_add_tail(&fcxp->qe, &mod->fcxp_req_free_q); 444 fcxp->req_rsp = BFA_TRUE; 445 } else { 446 list_add_tail(&fcxp->qe, &mod->fcxp_rsp_free_q); 447 fcxp->req_rsp = BFA_FALSE; 448 } 449 450 bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp); 451 fcxp->reqq_waiting = BFA_FALSE; 452 453 fcxp = fcxp + 1; 454 } 455 456 bfa_mem_kva_curp(mod) = (void *)fcxp; 457 } 458 459 void 460 bfa_fcxp_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 461 struct bfa_s *bfa) 462 { 463 struct bfa_fcxp_mod_s *fcxp_mod = BFA_FCXP_MOD(bfa); 464 struct bfa_mem_kva_s *fcxp_kva = BFA_MEM_FCXP_KVA(bfa); 465 struct bfa_mem_dma_s *seg_ptr; 466 u16 nsegs, idx, per_seg_fcxp; 467 u16 num_fcxps = cfg->fwcfg.num_fcxp_reqs; 468 u32 per_fcxp_sz; 469 470 if (num_fcxps == 0) 471 return; 472 473 if (cfg->drvcfg.min_cfg) 474 per_fcxp_sz = 2 * BFA_FCXP_MAX_IBUF_SZ; 475 else 476 per_fcxp_sz = BFA_FCXP_MAX_IBUF_SZ + BFA_FCXP_MAX_LBUF_SZ; 477 478 /* dma memory */ 479 nsegs = BFI_MEM_DMA_NSEGS(num_fcxps, per_fcxp_sz); 480 per_seg_fcxp = BFI_MEM_NREQS_SEG(per_fcxp_sz); 481 482 bfa_mem_dma_seg_iter(fcxp_mod, seg_ptr, nsegs, idx) { 483 if (num_fcxps >= per_seg_fcxp) { 484 num_fcxps -= per_seg_fcxp; 485 bfa_mem_dma_setup(minfo, seg_ptr, 486 per_seg_fcxp * per_fcxp_sz); 487 } else 488 bfa_mem_dma_setup(minfo, seg_ptr, 489 num_fcxps * per_fcxp_sz); 490 } 491 492 /* kva memory */ 493 bfa_mem_kva_setup(minfo, fcxp_kva, 494 cfg->fwcfg.num_fcxp_reqs * sizeof(struct bfa_fcxp_s)); 495 } 496 497 void 498 bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 499 struct bfa_pcidev_s *pcidev) 500 { 501 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 502 503 mod->bfa = bfa; 504 mod->num_fcxps = cfg->fwcfg.num_fcxp_reqs; 505 506 /* 507 * Initialize FCXP request and response payload sizes. 508 */ 509 mod->req_pld_sz = mod->rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ; 510 if (!cfg->drvcfg.min_cfg) 511 mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ; 512 513 INIT_LIST_HEAD(&mod->req_wait_q); 514 INIT_LIST_HEAD(&mod->rsp_wait_q); 515 516 claim_fcxps_mem(mod); 517 } 518 519 void 520 bfa_fcxp_iocdisable(struct bfa_s *bfa) 521 { 522 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 523 struct bfa_fcxp_s *fcxp; 524 struct list_head *qe, *qen; 525 526 /* Enqueue unused fcxp resources to free_q */ 527 list_splice_tail_init(&mod->fcxp_req_unused_q, &mod->fcxp_req_free_q); 528 list_splice_tail_init(&mod->fcxp_rsp_unused_q, &mod->fcxp_rsp_free_q); 529 530 list_for_each_safe(qe, qen, &mod->fcxp_active_q) { 531 fcxp = (struct bfa_fcxp_s *) qe; 532 if (fcxp->caller == NULL) { 533 fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, 534 BFA_STATUS_IOC_FAILURE, 0, 0, NULL); 535 bfa_fcxp_free(fcxp); 536 } else { 537 fcxp->rsp_status = BFA_STATUS_IOC_FAILURE; 538 bfa_cb_queue(bfa, &fcxp->hcb_qe, 539 __bfa_fcxp_send_cbfn, fcxp); 540 } 541 } 542 } 543 544 static struct bfa_fcxp_s * 545 bfa_fcxp_get(struct bfa_fcxp_mod_s *fm, bfa_boolean_t req) 546 { 547 struct bfa_fcxp_s *fcxp; 548 549 if (req) 550 bfa_q_deq(&fm->fcxp_req_free_q, &fcxp); 551 else 552 bfa_q_deq(&fm->fcxp_rsp_free_q, &fcxp); 553 554 if (fcxp) 555 list_add_tail(&fcxp->qe, &fm->fcxp_active_q); 556 557 return fcxp; 558 } 559 560 static void 561 bfa_fcxp_init_reqrsp(struct bfa_fcxp_s *fcxp, 562 struct bfa_s *bfa, 563 u8 *use_ibuf, 564 u32 *nr_sgles, 565 bfa_fcxp_get_sgaddr_t *r_sga_cbfn, 566 bfa_fcxp_get_sglen_t *r_sglen_cbfn, 567 struct list_head *r_sgpg_q, 568 int n_sgles, 569 bfa_fcxp_get_sgaddr_t sga_cbfn, 570 bfa_fcxp_get_sglen_t sglen_cbfn) 571 { 572 573 WARN_ON(bfa == NULL); 574 575 bfa_trc(bfa, fcxp->fcxp_tag); 576 577 if (n_sgles == 0) { 578 *use_ibuf = 1; 579 } else { 580 WARN_ON(*sga_cbfn == NULL); 581 WARN_ON(*sglen_cbfn == NULL); 582 583 *use_ibuf = 0; 584 *r_sga_cbfn = sga_cbfn; 585 *r_sglen_cbfn = sglen_cbfn; 586 587 *nr_sgles = n_sgles; 588 589 /* 590 * alloc required sgpgs 591 */ 592 if (n_sgles > BFI_SGE_INLINE) 593 WARN_ON(1); 594 } 595 596 } 597 598 static void 599 bfa_fcxp_init(struct bfa_fcxp_s *fcxp, 600 void *caller, struct bfa_s *bfa, int nreq_sgles, 601 int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 602 bfa_fcxp_get_sglen_t req_sglen_cbfn, 603 bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 604 bfa_fcxp_get_sglen_t rsp_sglen_cbfn) 605 { 606 607 WARN_ON(bfa == NULL); 608 609 bfa_trc(bfa, fcxp->fcxp_tag); 610 611 fcxp->caller = caller; 612 613 bfa_fcxp_init_reqrsp(fcxp, bfa, 614 &fcxp->use_ireqbuf, &fcxp->nreq_sgles, &fcxp->req_sga_cbfn, 615 &fcxp->req_sglen_cbfn, &fcxp->req_sgpg_q, 616 nreq_sgles, req_sga_cbfn, req_sglen_cbfn); 617 618 bfa_fcxp_init_reqrsp(fcxp, bfa, 619 &fcxp->use_irspbuf, &fcxp->nrsp_sgles, &fcxp->rsp_sga_cbfn, 620 &fcxp->rsp_sglen_cbfn, &fcxp->rsp_sgpg_q, 621 nrsp_sgles, rsp_sga_cbfn, rsp_sglen_cbfn); 622 623 } 624 625 static void 626 bfa_fcxp_put(struct bfa_fcxp_s *fcxp) 627 { 628 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 629 struct bfa_fcxp_wqe_s *wqe; 630 631 if (fcxp->req_rsp) 632 bfa_q_deq(&mod->req_wait_q, &wqe); 633 else 634 bfa_q_deq(&mod->rsp_wait_q, &wqe); 635 636 if (wqe) { 637 bfa_trc(mod->bfa, fcxp->fcxp_tag); 638 639 bfa_fcxp_init(fcxp, wqe->caller, wqe->bfa, wqe->nreq_sgles, 640 wqe->nrsp_sgles, wqe->req_sga_cbfn, 641 wqe->req_sglen_cbfn, wqe->rsp_sga_cbfn, 642 wqe->rsp_sglen_cbfn); 643 644 wqe->alloc_cbfn(wqe->alloc_cbarg, fcxp); 645 return; 646 } 647 648 WARN_ON(!bfa_q_is_on_q(&mod->fcxp_active_q, fcxp)); 649 list_del(&fcxp->qe); 650 651 if (fcxp->req_rsp) 652 list_add_tail(&fcxp->qe, &mod->fcxp_req_free_q); 653 else 654 list_add_tail(&fcxp->qe, &mod->fcxp_rsp_free_q); 655 } 656 657 static void 658 bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg, 659 bfa_status_t req_status, u32 rsp_len, 660 u32 resid_len, struct fchs_s *rsp_fchs) 661 { 662 /* discarded fcxp completion */ 663 } 664 665 static void 666 __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete) 667 { 668 struct bfa_fcxp_s *fcxp = cbarg; 669 670 if (complete) { 671 fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, 672 fcxp->rsp_status, fcxp->rsp_len, 673 fcxp->residue_len, &fcxp->rsp_fchs); 674 } else { 675 bfa_fcxp_free(fcxp); 676 } 677 } 678 679 static void 680 hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp) 681 { 682 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 683 struct bfa_fcxp_s *fcxp; 684 u16 fcxp_tag = be16_to_cpu(fcxp_rsp->fcxp_tag); 685 686 bfa_trc(bfa, fcxp_tag); 687 688 fcxp_rsp->rsp_len = be32_to_cpu(fcxp_rsp->rsp_len); 689 690 /* 691 * @todo f/w should not set residue to non-0 when everything 692 * is received. 693 */ 694 if (fcxp_rsp->req_status == BFA_STATUS_OK) 695 fcxp_rsp->residue_len = 0; 696 else 697 fcxp_rsp->residue_len = be32_to_cpu(fcxp_rsp->residue_len); 698 699 fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag); 700 701 WARN_ON(fcxp->send_cbfn == NULL); 702 703 hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp); 704 705 if (fcxp->send_cbfn != NULL) { 706 bfa_trc(mod->bfa, (NULL == fcxp->caller)); 707 if (fcxp->caller == NULL) { 708 fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, 709 fcxp_rsp->req_status, fcxp_rsp->rsp_len, 710 fcxp_rsp->residue_len, &fcxp_rsp->fchs); 711 /* 712 * fcxp automatically freed on return from the callback 713 */ 714 bfa_fcxp_free(fcxp); 715 } else { 716 fcxp->rsp_status = fcxp_rsp->req_status; 717 fcxp->rsp_len = fcxp_rsp->rsp_len; 718 fcxp->residue_len = fcxp_rsp->residue_len; 719 fcxp->rsp_fchs = fcxp_rsp->fchs; 720 721 bfa_cb_queue(bfa, &fcxp->hcb_qe, 722 __bfa_fcxp_send_cbfn, fcxp); 723 } 724 } else { 725 bfa_trc(bfa, (NULL == fcxp->send_cbfn)); 726 } 727 } 728 729 static void 730 hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp, 731 struct fchs_s *fchs) 732 { 733 /* 734 * TODO: TX ox_id 735 */ 736 if (reqlen > 0) { 737 if (fcxp->use_ireqbuf) { 738 u32 pld_w0 = 739 *((u32 *) BFA_FCXP_REQ_PLD(fcxp)); 740 741 bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP, 742 BFA_PL_EID_TX, 743 reqlen + sizeof(struct fchs_s), fchs, 744 pld_w0); 745 } else { 746 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, 747 BFA_PL_EID_TX, 748 reqlen + sizeof(struct fchs_s), 749 fchs); 750 } 751 } else { 752 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX, 753 reqlen + sizeof(struct fchs_s), fchs); 754 } 755 } 756 757 static void 758 hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp, 759 struct bfi_fcxp_send_rsp_s *fcxp_rsp) 760 { 761 if (fcxp_rsp->rsp_len > 0) { 762 if (fcxp->use_irspbuf) { 763 u32 pld_w0 = 764 *((u32 *) BFA_FCXP_RSP_PLD(fcxp)); 765 766 bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP, 767 BFA_PL_EID_RX, 768 (u16) fcxp_rsp->rsp_len, 769 &fcxp_rsp->fchs, pld_w0); 770 } else { 771 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, 772 BFA_PL_EID_RX, 773 (u16) fcxp_rsp->rsp_len, 774 &fcxp_rsp->fchs); 775 } 776 } else { 777 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_RX, 778 (u16) fcxp_rsp->rsp_len, &fcxp_rsp->fchs); 779 } 780 } 781 782 /* 783 * Handler to resume sending fcxp when space in available in cpe queue. 784 */ 785 static void 786 bfa_fcxp_qresume(void *cbarg) 787 { 788 struct bfa_fcxp_s *fcxp = cbarg; 789 struct bfa_s *bfa = fcxp->fcxp_mod->bfa; 790 struct bfi_fcxp_send_req_s *send_req; 791 792 fcxp->reqq_waiting = BFA_FALSE; 793 send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP); 794 bfa_fcxp_queue(fcxp, send_req); 795 } 796 797 /* 798 * Queue fcxp send request to foimrware. 799 */ 800 static void 801 bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req) 802 { 803 struct bfa_s *bfa = fcxp->fcxp_mod->bfa; 804 struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info; 805 struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info; 806 struct bfa_rport_s *rport = reqi->bfa_rport; 807 808 bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ, 809 bfa_fn_lpu(bfa)); 810 811 send_req->fcxp_tag = cpu_to_be16(fcxp->fcxp_tag); 812 if (rport) { 813 send_req->rport_fw_hndl = rport->fw_handle; 814 send_req->max_frmsz = cpu_to_be16(rport->rport_info.max_frmsz); 815 if (send_req->max_frmsz == 0) 816 send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ); 817 } else { 818 send_req->rport_fw_hndl = 0; 819 send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ); 820 } 821 822 send_req->vf_id = cpu_to_be16(reqi->vf_id); 823 send_req->lp_fwtag = bfa_lps_get_fwtag(bfa, reqi->lp_tag); 824 send_req->class = reqi->class; 825 send_req->rsp_timeout = rspi->rsp_timeout; 826 send_req->cts = reqi->cts; 827 send_req->fchs = reqi->fchs; 828 829 send_req->req_len = cpu_to_be32(reqi->req_tot_len); 830 send_req->rsp_maxlen = cpu_to_be32(rspi->rsp_maxlen); 831 832 /* 833 * setup req sgles 834 */ 835 if (fcxp->use_ireqbuf == 1) { 836 bfa_alen_set(&send_req->req_alen, reqi->req_tot_len, 837 BFA_FCXP_REQ_PLD_PA(fcxp)); 838 } else { 839 if (fcxp->nreq_sgles > 0) { 840 WARN_ON(fcxp->nreq_sgles != 1); 841 bfa_alen_set(&send_req->req_alen, reqi->req_tot_len, 842 fcxp->req_sga_cbfn(fcxp->caller, 0)); 843 } else { 844 WARN_ON(reqi->req_tot_len != 0); 845 bfa_alen_set(&send_req->rsp_alen, 0, 0); 846 } 847 } 848 849 /* 850 * setup rsp sgles 851 */ 852 if (fcxp->use_irspbuf == 1) { 853 WARN_ON(rspi->rsp_maxlen > BFA_FCXP_MAX_LBUF_SZ); 854 855 bfa_alen_set(&send_req->rsp_alen, rspi->rsp_maxlen, 856 BFA_FCXP_RSP_PLD_PA(fcxp)); 857 } else { 858 if (fcxp->nrsp_sgles > 0) { 859 WARN_ON(fcxp->nrsp_sgles != 1); 860 bfa_alen_set(&send_req->rsp_alen, rspi->rsp_maxlen, 861 fcxp->rsp_sga_cbfn(fcxp->caller, 0)); 862 863 } else { 864 WARN_ON(rspi->rsp_maxlen != 0); 865 bfa_alen_set(&send_req->rsp_alen, 0, 0); 866 } 867 } 868 869 hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs); 870 871 bfa_reqq_produce(bfa, BFA_REQQ_FCXP, send_req->mh); 872 873 bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP)); 874 bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP)); 875 } 876 877 /* 878 * Allocate an FCXP instance to send a response or to send a request 879 * that has a response. Request/response buffers are allocated by caller. 880 * 881 * @param[in] bfa BFA bfa instance 882 * @param[in] nreq_sgles Number of SG elements required for request 883 * buffer. 0, if fcxp internal buffers are used. 884 * Use bfa_fcxp_get_reqbuf() to get the 885 * internal req buffer. 886 * @param[in] req_sgles SG elements describing request buffer. Will be 887 * copied in by BFA and hence can be freed on 888 * return from this function. 889 * @param[in] get_req_sga function ptr to be called to get a request SG 890 * Address (given the sge index). 891 * @param[in] get_req_sglen function ptr to be called to get a request SG 892 * len (given the sge index). 893 * @param[in] get_rsp_sga function ptr to be called to get a response SG 894 * Address (given the sge index). 895 * @param[in] get_rsp_sglen function ptr to be called to get a response SG 896 * len (given the sge index). 897 * @param[in] req Allocated FCXP is used to send req or rsp? 898 * request - BFA_TRUE, response - BFA_FALSE 899 * 900 * @return FCXP instance. NULL on failure. 901 */ 902 struct bfa_fcxp_s * 903 bfa_fcxp_req_rsp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles, 904 int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 905 bfa_fcxp_get_sglen_t req_sglen_cbfn, 906 bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 907 bfa_fcxp_get_sglen_t rsp_sglen_cbfn, bfa_boolean_t req) 908 { 909 struct bfa_fcxp_s *fcxp = NULL; 910 911 WARN_ON(bfa == NULL); 912 913 fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa), req); 914 if (fcxp == NULL) 915 return NULL; 916 917 bfa_trc(bfa, fcxp->fcxp_tag); 918 919 bfa_fcxp_init(fcxp, caller, bfa, nreq_sgles, nrsp_sgles, req_sga_cbfn, 920 req_sglen_cbfn, rsp_sga_cbfn, rsp_sglen_cbfn); 921 922 return fcxp; 923 } 924 925 /* 926 * Get the internal request buffer pointer 927 * 928 * @param[in] fcxp BFA fcxp pointer 929 * 930 * @return pointer to the internal request buffer 931 */ 932 void * 933 bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp) 934 { 935 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 936 void *reqbuf; 937 938 WARN_ON(fcxp->use_ireqbuf != 1); 939 reqbuf = bfa_mem_get_dmabuf_kva(mod, fcxp->fcxp_tag, 940 mod->req_pld_sz + mod->rsp_pld_sz); 941 return reqbuf; 942 } 943 944 u32 945 bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp) 946 { 947 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 948 949 return mod->req_pld_sz; 950 } 951 952 /* 953 * Get the internal response buffer pointer 954 * 955 * @param[in] fcxp BFA fcxp pointer 956 * 957 * @return pointer to the internal request buffer 958 */ 959 void * 960 bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp) 961 { 962 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 963 void *fcxp_buf; 964 965 WARN_ON(fcxp->use_irspbuf != 1); 966 967 fcxp_buf = bfa_mem_get_dmabuf_kva(mod, fcxp->fcxp_tag, 968 mod->req_pld_sz + mod->rsp_pld_sz); 969 970 /* fcxp_buf = req_buf + rsp_buf :- add req_buf_sz to get to rsp_buf */ 971 return ((u8 *) fcxp_buf) + mod->req_pld_sz; 972 } 973 974 /* 975 * Free the BFA FCXP 976 * 977 * @param[in] fcxp BFA fcxp pointer 978 * 979 * @return void 980 */ 981 void 982 bfa_fcxp_free(struct bfa_fcxp_s *fcxp) 983 { 984 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; 985 986 WARN_ON(fcxp == NULL); 987 bfa_trc(mod->bfa, fcxp->fcxp_tag); 988 bfa_fcxp_put(fcxp); 989 } 990 991 /* 992 * Send a FCXP request 993 * 994 * @param[in] fcxp BFA fcxp pointer 995 * @param[in] rport BFA rport pointer. Could be left NULL for WKA rports 996 * @param[in] vf_id virtual Fabric ID 997 * @param[in] lp_tag lport tag 998 * @param[in] cts use Continuous sequence 999 * @param[in] cos fc Class of Service 1000 * @param[in] reqlen request length, does not include FCHS length 1001 * @param[in] fchs fc Header Pointer. The header content will be copied 1002 * in by BFA. 1003 * 1004 * @param[in] cbfn call back function to be called on receiving 1005 * the response 1006 * @param[in] cbarg arg for cbfn 1007 * @param[in] rsp_timeout 1008 * response timeout 1009 * 1010 * @return bfa_status_t 1011 */ 1012 void 1013 bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport, 1014 u16 vf_id, u8 lp_tag, bfa_boolean_t cts, enum fc_cos cos, 1015 u32 reqlen, struct fchs_s *fchs, bfa_cb_fcxp_send_t cbfn, 1016 void *cbarg, u32 rsp_maxlen, u8 rsp_timeout) 1017 { 1018 struct bfa_s *bfa = fcxp->fcxp_mod->bfa; 1019 struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info; 1020 struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info; 1021 struct bfi_fcxp_send_req_s *send_req; 1022 1023 bfa_trc(bfa, fcxp->fcxp_tag); 1024 1025 /* 1026 * setup request/response info 1027 */ 1028 reqi->bfa_rport = rport; 1029 reqi->vf_id = vf_id; 1030 reqi->lp_tag = lp_tag; 1031 reqi->class = cos; 1032 rspi->rsp_timeout = rsp_timeout; 1033 reqi->cts = cts; 1034 reqi->fchs = *fchs; 1035 reqi->req_tot_len = reqlen; 1036 rspi->rsp_maxlen = rsp_maxlen; 1037 fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp; 1038 fcxp->send_cbarg = cbarg; 1039 1040 /* 1041 * If no room in CPE queue, wait for space in request queue 1042 */ 1043 send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP); 1044 if (!send_req) { 1045 bfa_trc(bfa, fcxp->fcxp_tag); 1046 fcxp->reqq_waiting = BFA_TRUE; 1047 bfa_reqq_wait(bfa, BFA_REQQ_FCXP, &fcxp->reqq_wqe); 1048 return; 1049 } 1050 1051 bfa_fcxp_queue(fcxp, send_req); 1052 } 1053 1054 /* 1055 * Abort a BFA FCXP 1056 * 1057 * @param[in] fcxp BFA fcxp pointer 1058 * 1059 * @return void 1060 */ 1061 bfa_status_t 1062 bfa_fcxp_abort(struct bfa_fcxp_s *fcxp) 1063 { 1064 bfa_trc(fcxp->fcxp_mod->bfa, fcxp->fcxp_tag); 1065 WARN_ON(1); 1066 return BFA_STATUS_OK; 1067 } 1068 1069 void 1070 bfa_fcxp_req_rsp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe, 1071 bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg, 1072 void *caller, int nreq_sgles, 1073 int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, 1074 bfa_fcxp_get_sglen_t req_sglen_cbfn, 1075 bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, 1076 bfa_fcxp_get_sglen_t rsp_sglen_cbfn, bfa_boolean_t req) 1077 { 1078 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1079 1080 if (req) 1081 WARN_ON(!list_empty(&mod->fcxp_req_free_q)); 1082 else 1083 WARN_ON(!list_empty(&mod->fcxp_rsp_free_q)); 1084 1085 wqe->alloc_cbfn = alloc_cbfn; 1086 wqe->alloc_cbarg = alloc_cbarg; 1087 wqe->caller = caller; 1088 wqe->bfa = bfa; 1089 wqe->nreq_sgles = nreq_sgles; 1090 wqe->nrsp_sgles = nrsp_sgles; 1091 wqe->req_sga_cbfn = req_sga_cbfn; 1092 wqe->req_sglen_cbfn = req_sglen_cbfn; 1093 wqe->rsp_sga_cbfn = rsp_sga_cbfn; 1094 wqe->rsp_sglen_cbfn = rsp_sglen_cbfn; 1095 1096 if (req) 1097 list_add_tail(&wqe->qe, &mod->req_wait_q); 1098 else 1099 list_add_tail(&wqe->qe, &mod->rsp_wait_q); 1100 } 1101 1102 void 1103 bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe) 1104 { 1105 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1106 1107 WARN_ON(!bfa_q_is_on_q(&mod->req_wait_q, wqe) || 1108 !bfa_q_is_on_q(&mod->rsp_wait_q, wqe)); 1109 list_del(&wqe->qe); 1110 } 1111 1112 void 1113 bfa_fcxp_discard(struct bfa_fcxp_s *fcxp) 1114 { 1115 /* 1116 * If waiting for room in request queue, cancel reqq wait 1117 * and free fcxp. 1118 */ 1119 if (fcxp->reqq_waiting) { 1120 fcxp->reqq_waiting = BFA_FALSE; 1121 bfa_reqq_wcancel(&fcxp->reqq_wqe); 1122 bfa_fcxp_free(fcxp); 1123 return; 1124 } 1125 1126 fcxp->send_cbfn = bfa_fcxp_null_comp; 1127 } 1128 1129 void 1130 bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 1131 { 1132 switch (msg->mhdr.msg_id) { 1133 case BFI_FCXP_I2H_SEND_RSP: 1134 hal_fcxp_send_comp(bfa, (struct bfi_fcxp_send_rsp_s *) msg); 1135 break; 1136 1137 default: 1138 bfa_trc(bfa, msg->mhdr.msg_id); 1139 WARN_ON(1); 1140 } 1141 } 1142 1143 u32 1144 bfa_fcxp_get_maxrsp(struct bfa_s *bfa) 1145 { 1146 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1147 1148 return mod->rsp_pld_sz; 1149 } 1150 1151 void 1152 bfa_fcxp_res_recfg(struct bfa_s *bfa, u16 num_fcxp_fw) 1153 { 1154 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); 1155 struct list_head *qe; 1156 int i; 1157 1158 for (i = 0; i < (mod->num_fcxps - num_fcxp_fw); i++) { 1159 if (i < ((mod->num_fcxps - num_fcxp_fw) / 2)) { 1160 bfa_q_deq_tail(&mod->fcxp_req_free_q, &qe); 1161 list_add_tail(qe, &mod->fcxp_req_unused_q); 1162 } else { 1163 bfa_q_deq_tail(&mod->fcxp_rsp_free_q, &qe); 1164 list_add_tail(qe, &mod->fcxp_rsp_unused_q); 1165 } 1166 } 1167 } 1168 1169 /* 1170 * BFA LPS state machine functions 1171 */ 1172 1173 /* 1174 * Init state -- no login 1175 */ 1176 static void 1177 bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) 1178 { 1179 bfa_trc(lps->bfa, lps->bfa_tag); 1180 bfa_trc(lps->bfa, event); 1181 1182 switch (event) { 1183 case BFA_LPS_SM_LOGIN: 1184 if (bfa_reqq_full(lps->bfa, lps->reqq)) { 1185 bfa_sm_set_state(lps, bfa_lps_sm_loginwait); 1186 bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 1187 } else { 1188 bfa_sm_set_state(lps, bfa_lps_sm_login); 1189 bfa_lps_send_login(lps); 1190 } 1191 1192 if (lps->fdisc) 1193 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1194 BFA_PL_EID_LOGIN, 0, "FDISC Request"); 1195 else 1196 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1197 BFA_PL_EID_LOGIN, 0, "FLOGI Request"); 1198 break; 1199 1200 case BFA_LPS_SM_LOGOUT: 1201 bfa_lps_logout_comp(lps); 1202 break; 1203 1204 case BFA_LPS_SM_DELETE: 1205 bfa_lps_free(lps); 1206 break; 1207 1208 case BFA_LPS_SM_RX_CVL: 1209 case BFA_LPS_SM_OFFLINE: 1210 break; 1211 1212 case BFA_LPS_SM_FWRSP: 1213 /* 1214 * Could happen when fabric detects loopback and discards 1215 * the lps request. Fw will eventually sent out the timeout 1216 * Just ignore 1217 */ 1218 break; 1219 case BFA_LPS_SM_SET_N2N_PID: 1220 /* 1221 * When topology is set to loop, bfa_lps_set_n2n_pid() sends 1222 * this event. Ignore this event. 1223 */ 1224 break; 1225 1226 default: 1227 bfa_sm_fault(lps->bfa, event); 1228 } 1229 } 1230 1231 /* 1232 * login is in progress -- awaiting response from firmware 1233 */ 1234 static void 1235 bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) 1236 { 1237 bfa_trc(lps->bfa, lps->bfa_tag); 1238 bfa_trc(lps->bfa, event); 1239 1240 switch (event) { 1241 case BFA_LPS_SM_FWRSP: 1242 if (lps->status == BFA_STATUS_OK) { 1243 bfa_sm_set_state(lps, bfa_lps_sm_online); 1244 if (lps->fdisc) 1245 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1246 BFA_PL_EID_LOGIN, 0, "FDISC Accept"); 1247 else 1248 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1249 BFA_PL_EID_LOGIN, 0, "FLOGI Accept"); 1250 /* If N2N, send the assigned PID to FW */ 1251 bfa_trc(lps->bfa, lps->fport); 1252 bfa_trc(lps->bfa, lps->lp_pid); 1253 1254 if (!lps->fport && lps->lp_pid) 1255 bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID); 1256 } else { 1257 bfa_sm_set_state(lps, bfa_lps_sm_init); 1258 if (lps->fdisc) 1259 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1260 BFA_PL_EID_LOGIN, 0, 1261 "FDISC Fail (RJT or timeout)"); 1262 else 1263 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1264 BFA_PL_EID_LOGIN, 0, 1265 "FLOGI Fail (RJT or timeout)"); 1266 } 1267 bfa_lps_login_comp(lps); 1268 break; 1269 1270 case BFA_LPS_SM_OFFLINE: 1271 case BFA_LPS_SM_DELETE: 1272 bfa_sm_set_state(lps, bfa_lps_sm_init); 1273 break; 1274 1275 case BFA_LPS_SM_SET_N2N_PID: 1276 bfa_trc(lps->bfa, lps->fport); 1277 bfa_trc(lps->bfa, lps->lp_pid); 1278 break; 1279 1280 default: 1281 bfa_sm_fault(lps->bfa, event); 1282 } 1283 } 1284 1285 /* 1286 * login pending - awaiting space in request queue 1287 */ 1288 static void 1289 bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event) 1290 { 1291 bfa_trc(lps->bfa, lps->bfa_tag); 1292 bfa_trc(lps->bfa, event); 1293 1294 switch (event) { 1295 case BFA_LPS_SM_RESUME: 1296 bfa_sm_set_state(lps, bfa_lps_sm_login); 1297 bfa_lps_send_login(lps); 1298 break; 1299 1300 case BFA_LPS_SM_OFFLINE: 1301 case BFA_LPS_SM_DELETE: 1302 bfa_sm_set_state(lps, bfa_lps_sm_init); 1303 bfa_reqq_wcancel(&lps->wqe); 1304 break; 1305 1306 case BFA_LPS_SM_RX_CVL: 1307 /* 1308 * Login was not even sent out; so when getting out 1309 * of this state, it will appear like a login retry 1310 * after Clear virtual link 1311 */ 1312 break; 1313 1314 default: 1315 bfa_sm_fault(lps->bfa, event); 1316 } 1317 } 1318 1319 /* 1320 * login complete 1321 */ 1322 static void 1323 bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) 1324 { 1325 bfa_trc(lps->bfa, lps->bfa_tag); 1326 bfa_trc(lps->bfa, event); 1327 1328 switch (event) { 1329 case BFA_LPS_SM_LOGOUT: 1330 if (bfa_reqq_full(lps->bfa, lps->reqq)) { 1331 bfa_sm_set_state(lps, bfa_lps_sm_logowait); 1332 bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 1333 } else { 1334 bfa_sm_set_state(lps, bfa_lps_sm_logout); 1335 bfa_lps_send_logout(lps); 1336 } 1337 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1338 BFA_PL_EID_LOGO, 0, "Logout"); 1339 break; 1340 1341 case BFA_LPS_SM_RX_CVL: 1342 bfa_sm_set_state(lps, bfa_lps_sm_init); 1343 1344 /* Let the vport module know about this event */ 1345 bfa_lps_cvl_event(lps); 1346 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1347 BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); 1348 break; 1349 1350 case BFA_LPS_SM_SET_N2N_PID: 1351 if (bfa_reqq_full(lps->bfa, lps->reqq)) { 1352 bfa_sm_set_state(lps, bfa_lps_sm_online_n2n_pid_wait); 1353 bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); 1354 } else 1355 bfa_lps_send_set_n2n_pid(lps); 1356 break; 1357 1358 case BFA_LPS_SM_OFFLINE: 1359 case BFA_LPS_SM_DELETE: 1360 bfa_sm_set_state(lps, bfa_lps_sm_init); 1361 break; 1362 1363 default: 1364 bfa_sm_fault(lps->bfa, event); 1365 } 1366 } 1367 1368 /* 1369 * login complete 1370 */ 1371 static void 1372 bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, enum bfa_lps_event event) 1373 { 1374 bfa_trc(lps->bfa, lps->bfa_tag); 1375 bfa_trc(lps->bfa, event); 1376 1377 switch (event) { 1378 case BFA_LPS_SM_RESUME: 1379 bfa_sm_set_state(lps, bfa_lps_sm_online); 1380 bfa_lps_send_set_n2n_pid(lps); 1381 break; 1382 1383 case BFA_LPS_SM_LOGOUT: 1384 bfa_sm_set_state(lps, bfa_lps_sm_logowait); 1385 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1386 BFA_PL_EID_LOGO, 0, "Logout"); 1387 break; 1388 1389 case BFA_LPS_SM_RX_CVL: 1390 bfa_sm_set_state(lps, bfa_lps_sm_init); 1391 bfa_reqq_wcancel(&lps->wqe); 1392 1393 /* Let the vport module know about this event */ 1394 bfa_lps_cvl_event(lps); 1395 bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, 1396 BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); 1397 break; 1398 1399 case BFA_LPS_SM_OFFLINE: 1400 case BFA_LPS_SM_DELETE: 1401 bfa_sm_set_state(lps, bfa_lps_sm_init); 1402 bfa_reqq_wcancel(&lps->wqe); 1403 break; 1404 1405 default: 1406 bfa_sm_fault(lps->bfa, event); 1407 } 1408 } 1409 1410 /* 1411 * logout in progress - awaiting firmware response 1412 */ 1413 static void 1414 bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event) 1415 { 1416 bfa_trc(lps->bfa, lps->bfa_tag); 1417 bfa_trc(lps->bfa, event); 1418 1419 switch (event) { 1420 case BFA_LPS_SM_FWRSP: 1421 case BFA_LPS_SM_OFFLINE: 1422 bfa_sm_set_state(lps, bfa_lps_sm_init); 1423 bfa_lps_logout_comp(lps); 1424 break; 1425 1426 case BFA_LPS_SM_DELETE: 1427 bfa_sm_set_state(lps, bfa_lps_sm_init); 1428 break; 1429 1430 default: 1431 bfa_sm_fault(lps->bfa, event); 1432 } 1433 } 1434 1435 /* 1436 * logout pending -- awaiting space in request queue 1437 */ 1438 static void 1439 bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event) 1440 { 1441 bfa_trc(lps->bfa, lps->bfa_tag); 1442 bfa_trc(lps->bfa, event); 1443 1444 switch (event) { 1445 case BFA_LPS_SM_RESUME: 1446 bfa_sm_set_state(lps, bfa_lps_sm_logout); 1447 bfa_lps_send_logout(lps); 1448 break; 1449 1450 case BFA_LPS_SM_OFFLINE: 1451 case BFA_LPS_SM_DELETE: 1452 bfa_sm_set_state(lps, bfa_lps_sm_init); 1453 bfa_reqq_wcancel(&lps->wqe); 1454 break; 1455 1456 default: 1457 bfa_sm_fault(lps->bfa, event); 1458 } 1459 } 1460 1461 1462 1463 /* 1464 * lps_pvt BFA LPS private functions 1465 */ 1466 1467 /* 1468 * return memory requirement 1469 */ 1470 void 1471 bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 1472 struct bfa_s *bfa) 1473 { 1474 struct bfa_mem_kva_s *lps_kva = BFA_MEM_LPS_KVA(bfa); 1475 1476 if (cfg->drvcfg.min_cfg) 1477 bfa_mem_kva_setup(minfo, lps_kva, 1478 sizeof(struct bfa_lps_s) * BFA_LPS_MIN_LPORTS); 1479 else 1480 bfa_mem_kva_setup(minfo, lps_kva, 1481 sizeof(struct bfa_lps_s) * BFA_LPS_MAX_LPORTS); 1482 } 1483 1484 /* 1485 * bfa module attach at initialization time 1486 */ 1487 void 1488 bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 1489 struct bfa_pcidev_s *pcidev) 1490 { 1491 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1492 struct bfa_lps_s *lps; 1493 int i; 1494 1495 mod->num_lps = BFA_LPS_MAX_LPORTS; 1496 if (cfg->drvcfg.min_cfg) 1497 mod->num_lps = BFA_LPS_MIN_LPORTS; 1498 else 1499 mod->num_lps = BFA_LPS_MAX_LPORTS; 1500 mod->lps_arr = lps = (struct bfa_lps_s *) bfa_mem_kva_curp(mod); 1501 1502 bfa_mem_kva_curp(mod) += mod->num_lps * sizeof(struct bfa_lps_s); 1503 1504 INIT_LIST_HEAD(&mod->lps_free_q); 1505 INIT_LIST_HEAD(&mod->lps_active_q); 1506 INIT_LIST_HEAD(&mod->lps_login_q); 1507 1508 for (i = 0; i < mod->num_lps; i++, lps++) { 1509 lps->bfa = bfa; 1510 lps->bfa_tag = (u8) i; 1511 lps->reqq = BFA_REQQ_LPS; 1512 bfa_reqq_winit(&lps->wqe, bfa_lps_reqq_resume, lps); 1513 list_add_tail(&lps->qe, &mod->lps_free_q); 1514 } 1515 } 1516 1517 /* 1518 * IOC in disabled state -- consider all lps offline 1519 */ 1520 void 1521 bfa_lps_iocdisable(struct bfa_s *bfa) 1522 { 1523 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1524 struct bfa_lps_s *lps; 1525 struct list_head *qe, *qen; 1526 1527 list_for_each_safe(qe, qen, &mod->lps_active_q) { 1528 lps = (struct bfa_lps_s *) qe; 1529 bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE); 1530 } 1531 list_for_each_safe(qe, qen, &mod->lps_login_q) { 1532 lps = (struct bfa_lps_s *) qe; 1533 bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE); 1534 } 1535 list_splice_tail_init(&mod->lps_login_q, &mod->lps_active_q); 1536 } 1537 1538 /* 1539 * Firmware login response 1540 */ 1541 static void 1542 bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp) 1543 { 1544 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1545 struct bfa_lps_s *lps; 1546 1547 WARN_ON(rsp->bfa_tag >= mod->num_lps); 1548 lps = BFA_LPS_FROM_TAG(mod, rsp->bfa_tag); 1549 1550 lps->status = rsp->status; 1551 switch (rsp->status) { 1552 case BFA_STATUS_OK: 1553 lps->fw_tag = rsp->fw_tag; 1554 lps->fport = rsp->f_port; 1555 if (lps->fport) 1556 lps->lp_pid = rsp->lp_pid; 1557 lps->npiv_en = rsp->npiv_en; 1558 lps->pr_bbcred = be16_to_cpu(rsp->bb_credit); 1559 lps->pr_pwwn = rsp->port_name; 1560 lps->pr_nwwn = rsp->node_name; 1561 lps->auth_req = rsp->auth_req; 1562 lps->lp_mac = rsp->lp_mac; 1563 lps->brcd_switch = rsp->brcd_switch; 1564 lps->fcf_mac = rsp->fcf_mac; 1565 1566 break; 1567 1568 case BFA_STATUS_FABRIC_RJT: 1569 lps->lsrjt_rsn = rsp->lsrjt_rsn; 1570 lps->lsrjt_expl = rsp->lsrjt_expl; 1571 1572 break; 1573 1574 case BFA_STATUS_EPROTOCOL: 1575 lps->ext_status = rsp->ext_status; 1576 1577 break; 1578 1579 case BFA_STATUS_VPORT_MAX: 1580 if (rsp->ext_status) 1581 bfa_lps_no_res(lps, rsp->ext_status); 1582 break; 1583 1584 default: 1585 /* Nothing to do with other status */ 1586 break; 1587 } 1588 1589 list_del(&lps->qe); 1590 list_add_tail(&lps->qe, &mod->lps_active_q); 1591 bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); 1592 } 1593 1594 static void 1595 bfa_lps_no_res(struct bfa_lps_s *first_lps, u8 count) 1596 { 1597 struct bfa_s *bfa = first_lps->bfa; 1598 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1599 struct list_head *qe, *qe_next; 1600 struct bfa_lps_s *lps; 1601 1602 bfa_trc(bfa, count); 1603 1604 qe = bfa_q_next(first_lps); 1605 1606 while (count && qe) { 1607 qe_next = bfa_q_next(qe); 1608 lps = (struct bfa_lps_s *)qe; 1609 bfa_trc(bfa, lps->bfa_tag); 1610 lps->status = first_lps->status; 1611 list_del(&lps->qe); 1612 list_add_tail(&lps->qe, &mod->lps_active_q); 1613 bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); 1614 qe = qe_next; 1615 count--; 1616 } 1617 } 1618 1619 /* 1620 * Firmware logout response 1621 */ 1622 static void 1623 bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp) 1624 { 1625 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1626 struct bfa_lps_s *lps; 1627 1628 WARN_ON(rsp->bfa_tag >= mod->num_lps); 1629 lps = BFA_LPS_FROM_TAG(mod, rsp->bfa_tag); 1630 1631 bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); 1632 } 1633 1634 /* 1635 * Firmware received a Clear virtual link request (for FCoE) 1636 */ 1637 static void 1638 bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl) 1639 { 1640 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1641 struct bfa_lps_s *lps; 1642 1643 lps = BFA_LPS_FROM_TAG(mod, cvl->bfa_tag); 1644 1645 bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL); 1646 } 1647 1648 /* 1649 * Space is available in request queue, resume queueing request to firmware. 1650 */ 1651 static void 1652 bfa_lps_reqq_resume(void *lps_arg) 1653 { 1654 struct bfa_lps_s *lps = lps_arg; 1655 1656 bfa_sm_send_event(lps, BFA_LPS_SM_RESUME); 1657 } 1658 1659 /* 1660 * lps is freed -- triggered by vport delete 1661 */ 1662 static void 1663 bfa_lps_free(struct bfa_lps_s *lps) 1664 { 1665 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(lps->bfa); 1666 1667 lps->lp_pid = 0; 1668 list_del(&lps->qe); 1669 list_add_tail(&lps->qe, &mod->lps_free_q); 1670 } 1671 1672 /* 1673 * send login request to firmware 1674 */ 1675 static void 1676 bfa_lps_send_login(struct bfa_lps_s *lps) 1677 { 1678 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(lps->bfa); 1679 struct bfi_lps_login_req_s *m; 1680 1681 m = bfa_reqq_next(lps->bfa, lps->reqq); 1682 WARN_ON(!m); 1683 1684 bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGIN_REQ, 1685 bfa_fn_lpu(lps->bfa)); 1686 1687 m->bfa_tag = lps->bfa_tag; 1688 m->alpa = lps->alpa; 1689 m->pdu_size = cpu_to_be16(lps->pdusz); 1690 m->pwwn = lps->pwwn; 1691 m->nwwn = lps->nwwn; 1692 m->fdisc = lps->fdisc; 1693 m->auth_en = lps->auth_en; 1694 1695 bfa_reqq_produce(lps->bfa, lps->reqq, m->mh); 1696 list_del(&lps->qe); 1697 list_add_tail(&lps->qe, &mod->lps_login_q); 1698 } 1699 1700 /* 1701 * send logout request to firmware 1702 */ 1703 static void 1704 bfa_lps_send_logout(struct bfa_lps_s *lps) 1705 { 1706 struct bfi_lps_logout_req_s *m; 1707 1708 m = bfa_reqq_next(lps->bfa, lps->reqq); 1709 WARN_ON(!m); 1710 1711 bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGOUT_REQ, 1712 bfa_fn_lpu(lps->bfa)); 1713 1714 m->fw_tag = lps->fw_tag; 1715 m->port_name = lps->pwwn; 1716 bfa_reqq_produce(lps->bfa, lps->reqq, m->mh); 1717 } 1718 1719 /* 1720 * send n2n pid set request to firmware 1721 */ 1722 static void 1723 bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps) 1724 { 1725 struct bfi_lps_n2n_pid_req_s *m; 1726 1727 m = bfa_reqq_next(lps->bfa, lps->reqq); 1728 WARN_ON(!m); 1729 1730 bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_N2N_PID_REQ, 1731 bfa_fn_lpu(lps->bfa)); 1732 1733 m->fw_tag = lps->fw_tag; 1734 m->lp_pid = lps->lp_pid; 1735 bfa_reqq_produce(lps->bfa, lps->reqq, m->mh); 1736 } 1737 1738 /* 1739 * Indirect login completion handler for non-fcs 1740 */ 1741 static void 1742 bfa_lps_login_comp_cb(void *arg, bfa_boolean_t complete) 1743 { 1744 struct bfa_lps_s *lps = arg; 1745 1746 if (!complete) 1747 return; 1748 1749 if (lps->fdisc) 1750 bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status); 1751 else 1752 bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status); 1753 } 1754 1755 /* 1756 * Login completion handler -- direct call for fcs, queue for others 1757 */ 1758 static void 1759 bfa_lps_login_comp(struct bfa_lps_s *lps) 1760 { 1761 if (!lps->bfa->fcs) { 1762 bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_login_comp_cb, 1763 lps); 1764 return; 1765 } 1766 1767 if (lps->fdisc) 1768 bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status); 1769 else 1770 bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status); 1771 } 1772 1773 /* 1774 * Indirect logout completion handler for non-fcs 1775 */ 1776 static void 1777 bfa_lps_logout_comp_cb(void *arg, bfa_boolean_t complete) 1778 { 1779 struct bfa_lps_s *lps = arg; 1780 1781 if (!complete) 1782 return; 1783 1784 if (lps->fdisc) 1785 bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg); 1786 else 1787 bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg); 1788 } 1789 1790 /* 1791 * Logout completion handler -- direct call for fcs, queue for others 1792 */ 1793 static void 1794 bfa_lps_logout_comp(struct bfa_lps_s *lps) 1795 { 1796 if (!lps->bfa->fcs) { 1797 bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_logout_comp_cb, 1798 lps); 1799 return; 1800 } 1801 if (lps->fdisc) 1802 bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg); 1803 } 1804 1805 /* 1806 * Clear virtual link completion handler for non-fcs 1807 */ 1808 static void 1809 bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete) 1810 { 1811 struct bfa_lps_s *lps = arg; 1812 1813 if (!complete) 1814 return; 1815 1816 /* Clear virtual link to base port will result in link down */ 1817 if (lps->fdisc) 1818 bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); 1819 } 1820 1821 /* 1822 * Received Clear virtual link event --direct call for fcs, 1823 * queue for others 1824 */ 1825 static void 1826 bfa_lps_cvl_event(struct bfa_lps_s *lps) 1827 { 1828 if (!lps->bfa->fcs) { 1829 bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb, 1830 lps); 1831 return; 1832 } 1833 1834 /* Clear virtual link to base port will result in link down */ 1835 if (lps->fdisc) 1836 bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); 1837 } 1838 1839 1840 1841 /* 1842 * lps_public BFA LPS public functions 1843 */ 1844 1845 u32 1846 bfa_lps_get_max_vport(struct bfa_s *bfa) 1847 { 1848 if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) 1849 return BFA_LPS_MAX_VPORTS_SUPP_CT; 1850 else 1851 return BFA_LPS_MAX_VPORTS_SUPP_CB; 1852 } 1853 1854 /* 1855 * Allocate a lport srvice tag. 1856 */ 1857 struct bfa_lps_s * 1858 bfa_lps_alloc(struct bfa_s *bfa) 1859 { 1860 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1861 struct bfa_lps_s *lps = NULL; 1862 1863 bfa_q_deq(&mod->lps_free_q, &lps); 1864 1865 if (lps == NULL) 1866 return NULL; 1867 1868 list_add_tail(&lps->qe, &mod->lps_active_q); 1869 1870 bfa_sm_set_state(lps, bfa_lps_sm_init); 1871 return lps; 1872 } 1873 1874 /* 1875 * Free lport service tag. This can be called anytime after an alloc. 1876 * No need to wait for any pending login/logout completions. 1877 */ 1878 void 1879 bfa_lps_delete(struct bfa_lps_s *lps) 1880 { 1881 bfa_sm_send_event(lps, BFA_LPS_SM_DELETE); 1882 } 1883 1884 /* 1885 * Initiate a lport login. 1886 */ 1887 void 1888 bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz, 1889 wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en) 1890 { 1891 lps->uarg = uarg; 1892 lps->alpa = alpa; 1893 lps->pdusz = pdusz; 1894 lps->pwwn = pwwn; 1895 lps->nwwn = nwwn; 1896 lps->fdisc = BFA_FALSE; 1897 lps->auth_en = auth_en; 1898 bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN); 1899 } 1900 1901 /* 1902 * Initiate a lport fdisc login. 1903 */ 1904 void 1905 bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn, 1906 wwn_t nwwn) 1907 { 1908 lps->uarg = uarg; 1909 lps->alpa = 0; 1910 lps->pdusz = pdusz; 1911 lps->pwwn = pwwn; 1912 lps->nwwn = nwwn; 1913 lps->fdisc = BFA_TRUE; 1914 lps->auth_en = BFA_FALSE; 1915 bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN); 1916 } 1917 1918 1919 /* 1920 * Initiate a lport FDSIC logout. 1921 */ 1922 void 1923 bfa_lps_fdisclogo(struct bfa_lps_s *lps) 1924 { 1925 bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT); 1926 } 1927 1928 u8 1929 bfa_lps_get_fwtag(struct bfa_s *bfa, u8 lp_tag) 1930 { 1931 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1932 1933 return BFA_LPS_FROM_TAG(mod, lp_tag)->fw_tag; 1934 } 1935 1936 /* 1937 * Return lport services tag given the pid 1938 */ 1939 u8 1940 bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid) 1941 { 1942 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1943 struct bfa_lps_s *lps; 1944 int i; 1945 1946 for (i = 0, lps = mod->lps_arr; i < mod->num_lps; i++, lps++) { 1947 if (lps->lp_pid == pid) 1948 return lps->bfa_tag; 1949 } 1950 1951 /* Return base port tag anyway */ 1952 return 0; 1953 } 1954 1955 1956 /* 1957 * return port id assigned to the base lport 1958 */ 1959 u32 1960 bfa_lps_get_base_pid(struct bfa_s *bfa) 1961 { 1962 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); 1963 1964 return BFA_LPS_FROM_TAG(mod, 0)->lp_pid; 1965 } 1966 1967 /* 1968 * Set PID in case of n2n (which is assigned during PLOGI) 1969 */ 1970 void 1971 bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, uint32_t n2n_pid) 1972 { 1973 bfa_trc(lps->bfa, lps->bfa_tag); 1974 bfa_trc(lps->bfa, n2n_pid); 1975 1976 lps->lp_pid = n2n_pid; 1977 bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID); 1978 } 1979 1980 /* 1981 * LPS firmware message class handler. 1982 */ 1983 void 1984 bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 1985 { 1986 union bfi_lps_i2h_msg_u msg; 1987 1988 bfa_trc(bfa, m->mhdr.msg_id); 1989 msg.msg = m; 1990 1991 switch (m->mhdr.msg_id) { 1992 case BFI_LPS_I2H_LOGIN_RSP: 1993 bfa_lps_login_rsp(bfa, msg.login_rsp); 1994 break; 1995 1996 case BFI_LPS_I2H_LOGOUT_RSP: 1997 bfa_lps_logout_rsp(bfa, msg.logout_rsp); 1998 break; 1999 2000 case BFI_LPS_I2H_CVL_EVENT: 2001 bfa_lps_rx_cvl_event(bfa, msg.cvl_event); 2002 break; 2003 2004 default: 2005 bfa_trc(bfa, m->mhdr.msg_id); 2006 WARN_ON(1); 2007 } 2008 } 2009 2010 static void 2011 bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event) 2012 { 2013 struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2014 struct bfa_aen_entry_s *aen_entry; 2015 2016 bfad_get_aen_entry(bfad, aen_entry); 2017 if (!aen_entry) 2018 return; 2019 2020 aen_entry->aen_data.port.ioc_type = bfa_get_type(fcport->bfa); 2021 aen_entry->aen_data.port.pwwn = fcport->pwwn; 2022 2023 /* Send the AEN notification */ 2024 bfad_im_post_vendor_event(aen_entry, bfad, ++fcport->bfa->bfa_aen_seq, 2025 BFA_AEN_CAT_PORT, event); 2026 } 2027 2028 /* 2029 * FC PORT state machine functions 2030 */ 2031 static void 2032 bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport, 2033 enum bfa_fcport_sm_event event) 2034 { 2035 bfa_trc(fcport->bfa, event); 2036 2037 switch (event) { 2038 case BFA_FCPORT_SM_START: 2039 /* 2040 * Start event after IOC is configured and BFA is started. 2041 */ 2042 fcport->use_flash_cfg = BFA_TRUE; 2043 2044 if (bfa_fcport_send_enable(fcport)) { 2045 bfa_trc(fcport->bfa, BFA_TRUE); 2046 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2047 } else { 2048 bfa_trc(fcport->bfa, BFA_FALSE); 2049 bfa_sm_set_state(fcport, 2050 bfa_fcport_sm_enabling_qwait); 2051 } 2052 break; 2053 2054 case BFA_FCPORT_SM_ENABLE: 2055 /* 2056 * Port is persistently configured to be in enabled state. Do 2057 * not change state. Port enabling is done when START event is 2058 * received. 2059 */ 2060 break; 2061 2062 case BFA_FCPORT_SM_DISABLE: 2063 /* 2064 * If a port is persistently configured to be disabled, the 2065 * first event will a port disable request. 2066 */ 2067 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2068 break; 2069 2070 case BFA_FCPORT_SM_HWFAIL: 2071 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2072 break; 2073 2074 default: 2075 bfa_sm_fault(fcport->bfa, event); 2076 } 2077 } 2078 2079 static void 2080 bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, 2081 enum bfa_fcport_sm_event event) 2082 { 2083 char pwwn_buf[BFA_STRING_32]; 2084 struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2085 bfa_trc(fcport->bfa, event); 2086 2087 switch (event) { 2088 case BFA_FCPORT_SM_QRESUME: 2089 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2090 bfa_fcport_send_enable(fcport); 2091 break; 2092 2093 case BFA_FCPORT_SM_STOP: 2094 bfa_reqq_wcancel(&fcport->reqq_wait); 2095 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2096 break; 2097 2098 case BFA_FCPORT_SM_ENABLE: 2099 /* 2100 * Already enable is in progress. 2101 */ 2102 break; 2103 2104 case BFA_FCPORT_SM_DISABLE: 2105 /* 2106 * Just send disable request to firmware when room becomes 2107 * available in request queue. 2108 */ 2109 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2110 bfa_reqq_wcancel(&fcport->reqq_wait); 2111 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2112 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2113 wwn2str(pwwn_buf, fcport->pwwn); 2114 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2115 "Base port disabled: WWN = %s\n", pwwn_buf); 2116 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); 2117 break; 2118 2119 case BFA_FCPORT_SM_LINKUP: 2120 case BFA_FCPORT_SM_LINKDOWN: 2121 /* 2122 * Possible to get link events when doing back-to-back 2123 * enable/disables. 2124 */ 2125 break; 2126 2127 case BFA_FCPORT_SM_HWFAIL: 2128 bfa_reqq_wcancel(&fcport->reqq_wait); 2129 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2130 break; 2131 2132 case BFA_FCPORT_SM_FAA_MISCONFIG: 2133 bfa_fcport_reset_linkinfo(fcport); 2134 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 2135 bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); 2136 break; 2137 2138 default: 2139 bfa_sm_fault(fcport->bfa, event); 2140 } 2141 } 2142 2143 static void 2144 bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, 2145 enum bfa_fcport_sm_event event) 2146 { 2147 char pwwn_buf[BFA_STRING_32]; 2148 struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2149 bfa_trc(fcport->bfa, event); 2150 2151 switch (event) { 2152 case BFA_FCPORT_SM_FWRSP: 2153 case BFA_FCPORT_SM_LINKDOWN: 2154 bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown); 2155 break; 2156 2157 case BFA_FCPORT_SM_LINKUP: 2158 bfa_fcport_update_linkinfo(fcport); 2159 bfa_sm_set_state(fcport, bfa_fcport_sm_linkup); 2160 2161 WARN_ON(!fcport->event_cbfn); 2162 bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE); 2163 break; 2164 2165 case BFA_FCPORT_SM_ENABLE: 2166 /* 2167 * Already being enabled. 2168 */ 2169 break; 2170 2171 case BFA_FCPORT_SM_DISABLE: 2172 if (bfa_fcport_send_disable(fcport)) 2173 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2174 else 2175 bfa_sm_set_state(fcport, 2176 bfa_fcport_sm_disabling_qwait); 2177 2178 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2179 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2180 wwn2str(pwwn_buf, fcport->pwwn); 2181 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2182 "Base port disabled: WWN = %s\n", pwwn_buf); 2183 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); 2184 break; 2185 2186 case BFA_FCPORT_SM_STOP: 2187 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2188 break; 2189 2190 case BFA_FCPORT_SM_HWFAIL: 2191 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2192 break; 2193 2194 case BFA_FCPORT_SM_FAA_MISCONFIG: 2195 bfa_fcport_reset_linkinfo(fcport); 2196 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 2197 bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); 2198 break; 2199 2200 default: 2201 bfa_sm_fault(fcport->bfa, event); 2202 } 2203 } 2204 2205 static void 2206 bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, 2207 enum bfa_fcport_sm_event event) 2208 { 2209 struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event; 2210 char pwwn_buf[BFA_STRING_32]; 2211 struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2212 2213 bfa_trc(fcport->bfa, event); 2214 2215 switch (event) { 2216 case BFA_FCPORT_SM_LINKUP: 2217 bfa_fcport_update_linkinfo(fcport); 2218 bfa_sm_set_state(fcport, bfa_fcport_sm_linkup); 2219 WARN_ON(!fcport->event_cbfn); 2220 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2221 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup"); 2222 if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { 2223 2224 bfa_trc(fcport->bfa, 2225 pevent->link_state.attr.vc_fcf.fcf.fipenabled); 2226 bfa_trc(fcport->bfa, 2227 pevent->link_state.attr.vc_fcf.fcf.fipfailed); 2228 2229 if (pevent->link_state.attr.vc_fcf.fcf.fipfailed) 2230 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2231 BFA_PL_EID_FIP_FCF_DISC, 0, 2232 "FIP FCF Discovery Failed"); 2233 else 2234 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2235 BFA_PL_EID_FIP_FCF_DISC, 0, 2236 "FIP FCF Discovered"); 2237 } 2238 2239 bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE); 2240 wwn2str(pwwn_buf, fcport->pwwn); 2241 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2242 "Base port online: WWN = %s\n", pwwn_buf); 2243 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE); 2244 2245 /* If QoS is enabled and it is not online, send AEN */ 2246 if (fcport->cfg.qos_enabled && 2247 fcport->qos_attr.state != BFA_QOS_ONLINE) 2248 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG); 2249 break; 2250 2251 case BFA_FCPORT_SM_LINKDOWN: 2252 /* 2253 * Possible to get link down event. 2254 */ 2255 break; 2256 2257 case BFA_FCPORT_SM_ENABLE: 2258 /* 2259 * Already enabled. 2260 */ 2261 break; 2262 2263 case BFA_FCPORT_SM_DISABLE: 2264 if (bfa_fcport_send_disable(fcport)) 2265 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2266 else 2267 bfa_sm_set_state(fcport, 2268 bfa_fcport_sm_disabling_qwait); 2269 2270 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2271 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2272 wwn2str(pwwn_buf, fcport->pwwn); 2273 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2274 "Base port disabled: WWN = %s\n", pwwn_buf); 2275 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); 2276 break; 2277 2278 case BFA_FCPORT_SM_STOP: 2279 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2280 break; 2281 2282 case BFA_FCPORT_SM_HWFAIL: 2283 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2284 break; 2285 2286 case BFA_FCPORT_SM_FAA_MISCONFIG: 2287 bfa_fcport_reset_linkinfo(fcport); 2288 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 2289 bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); 2290 break; 2291 2292 default: 2293 bfa_sm_fault(fcport->bfa, event); 2294 } 2295 } 2296 2297 static void 2298 bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, 2299 enum bfa_fcport_sm_event event) 2300 { 2301 char pwwn_buf[BFA_STRING_32]; 2302 struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2303 2304 bfa_trc(fcport->bfa, event); 2305 2306 switch (event) { 2307 case BFA_FCPORT_SM_ENABLE: 2308 /* 2309 * Already enabled. 2310 */ 2311 break; 2312 2313 case BFA_FCPORT_SM_DISABLE: 2314 if (bfa_fcport_send_disable(fcport)) 2315 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2316 else 2317 bfa_sm_set_state(fcport, 2318 bfa_fcport_sm_disabling_qwait); 2319 2320 bfa_fcport_reset_linkinfo(fcport); 2321 bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2322 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2323 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2324 wwn2str(pwwn_buf, fcport->pwwn); 2325 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2326 "Base port offline: WWN = %s\n", pwwn_buf); 2327 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); 2328 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2329 "Base port disabled: WWN = %s\n", pwwn_buf); 2330 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); 2331 break; 2332 2333 case BFA_FCPORT_SM_LINKDOWN: 2334 bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown); 2335 bfa_fcport_reset_linkinfo(fcport); 2336 bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2337 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2338 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown"); 2339 wwn2str(pwwn_buf, fcport->pwwn); 2340 if (BFA_PORT_IS_DISABLED(fcport->bfa)) { 2341 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2342 "Base port offline: WWN = %s\n", pwwn_buf); 2343 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); 2344 } else { 2345 BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2346 "Base port (WWN = %s) " 2347 "lost fabric connectivity\n", pwwn_buf); 2348 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 2349 } 2350 break; 2351 2352 case BFA_FCPORT_SM_STOP: 2353 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2354 bfa_fcport_reset_linkinfo(fcport); 2355 wwn2str(pwwn_buf, fcport->pwwn); 2356 if (BFA_PORT_IS_DISABLED(fcport->bfa)) { 2357 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2358 "Base port offline: WWN = %s\n", pwwn_buf); 2359 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); 2360 } else { 2361 BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2362 "Base port (WWN = %s) " 2363 "lost fabric connectivity\n", pwwn_buf); 2364 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 2365 } 2366 break; 2367 2368 case BFA_FCPORT_SM_HWFAIL: 2369 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2370 bfa_fcport_reset_linkinfo(fcport); 2371 bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2372 wwn2str(pwwn_buf, fcport->pwwn); 2373 if (BFA_PORT_IS_DISABLED(fcport->bfa)) { 2374 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2375 "Base port offline: WWN = %s\n", pwwn_buf); 2376 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); 2377 } else { 2378 BFA_LOG(KERN_ERR, bfad, bfa_log_level, 2379 "Base port (WWN = %s) " 2380 "lost fabric connectivity\n", pwwn_buf); 2381 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 2382 } 2383 break; 2384 2385 case BFA_FCPORT_SM_FAA_MISCONFIG: 2386 bfa_fcport_reset_linkinfo(fcport); 2387 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 2388 bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); 2389 break; 2390 2391 default: 2392 bfa_sm_fault(fcport->bfa, event); 2393 } 2394 } 2395 2396 static void 2397 bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport, 2398 enum bfa_fcport_sm_event event) 2399 { 2400 bfa_trc(fcport->bfa, event); 2401 2402 switch (event) { 2403 case BFA_FCPORT_SM_QRESUME: 2404 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2405 bfa_fcport_send_disable(fcport); 2406 break; 2407 2408 case BFA_FCPORT_SM_STOP: 2409 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2410 bfa_reqq_wcancel(&fcport->reqq_wait); 2411 break; 2412 2413 case BFA_FCPORT_SM_ENABLE: 2414 bfa_sm_set_state(fcport, bfa_fcport_sm_toggling_qwait); 2415 break; 2416 2417 case BFA_FCPORT_SM_DISABLE: 2418 /* 2419 * Already being disabled. 2420 */ 2421 break; 2422 2423 case BFA_FCPORT_SM_LINKUP: 2424 case BFA_FCPORT_SM_LINKDOWN: 2425 /* 2426 * Possible to get link events when doing back-to-back 2427 * enable/disables. 2428 */ 2429 break; 2430 2431 case BFA_FCPORT_SM_HWFAIL: 2432 bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2433 bfa_reqq_wcancel(&fcport->reqq_wait); 2434 break; 2435 2436 case BFA_FCPORT_SM_FAA_MISCONFIG: 2437 bfa_fcport_reset_linkinfo(fcport); 2438 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); 2439 bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); 2440 break; 2441 2442 default: 2443 bfa_sm_fault(fcport->bfa, event); 2444 } 2445 } 2446 2447 static void 2448 bfa_fcport_sm_toggling_qwait(struct bfa_fcport_s *fcport, 2449 enum bfa_fcport_sm_event event) 2450 { 2451 bfa_trc(fcport->bfa, event); 2452 2453 switch (event) { 2454 case BFA_FCPORT_SM_QRESUME: 2455 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2456 bfa_fcport_send_disable(fcport); 2457 if (bfa_fcport_send_enable(fcport)) 2458 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2459 else 2460 bfa_sm_set_state(fcport, 2461 bfa_fcport_sm_enabling_qwait); 2462 break; 2463 2464 case BFA_FCPORT_SM_STOP: 2465 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2466 bfa_reqq_wcancel(&fcport->reqq_wait); 2467 break; 2468 2469 case BFA_FCPORT_SM_ENABLE: 2470 break; 2471 2472 case BFA_FCPORT_SM_DISABLE: 2473 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait); 2474 break; 2475 2476 case BFA_FCPORT_SM_LINKUP: 2477 case BFA_FCPORT_SM_LINKDOWN: 2478 /* 2479 * Possible to get link events when doing back-to-back 2480 * enable/disables. 2481 */ 2482 break; 2483 2484 case BFA_FCPORT_SM_HWFAIL: 2485 bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2486 bfa_reqq_wcancel(&fcport->reqq_wait); 2487 break; 2488 2489 default: 2490 bfa_sm_fault(fcport->bfa, event); 2491 } 2492 } 2493 2494 static void 2495 bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport, 2496 enum bfa_fcport_sm_event event) 2497 { 2498 char pwwn_buf[BFA_STRING_32]; 2499 struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2500 bfa_trc(fcport->bfa, event); 2501 2502 switch (event) { 2503 case BFA_FCPORT_SM_FWRSP: 2504 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2505 break; 2506 2507 case BFA_FCPORT_SM_DISABLE: 2508 /* 2509 * Already being disabled. 2510 */ 2511 break; 2512 2513 case BFA_FCPORT_SM_ENABLE: 2514 if (bfa_fcport_send_enable(fcport)) 2515 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2516 else 2517 bfa_sm_set_state(fcport, 2518 bfa_fcport_sm_enabling_qwait); 2519 2520 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2521 BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); 2522 wwn2str(pwwn_buf, fcport->pwwn); 2523 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2524 "Base port enabled: WWN = %s\n", pwwn_buf); 2525 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE); 2526 break; 2527 2528 case BFA_FCPORT_SM_STOP: 2529 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2530 break; 2531 2532 case BFA_FCPORT_SM_LINKUP: 2533 case BFA_FCPORT_SM_LINKDOWN: 2534 /* 2535 * Possible to get link events when doing back-to-back 2536 * enable/disables. 2537 */ 2538 break; 2539 2540 case BFA_FCPORT_SM_HWFAIL: 2541 bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2542 break; 2543 2544 default: 2545 bfa_sm_fault(fcport->bfa, event); 2546 } 2547 } 2548 2549 static void 2550 bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, 2551 enum bfa_fcport_sm_event event) 2552 { 2553 char pwwn_buf[BFA_STRING_32]; 2554 struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad; 2555 bfa_trc(fcport->bfa, event); 2556 2557 switch (event) { 2558 case BFA_FCPORT_SM_START: 2559 /* 2560 * Ignore start event for a port that is disabled. 2561 */ 2562 break; 2563 2564 case BFA_FCPORT_SM_STOP: 2565 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2566 break; 2567 2568 case BFA_FCPORT_SM_ENABLE: 2569 if (bfa_fcport_send_enable(fcport)) 2570 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2571 else 2572 bfa_sm_set_state(fcport, 2573 bfa_fcport_sm_enabling_qwait); 2574 2575 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2576 BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); 2577 wwn2str(pwwn_buf, fcport->pwwn); 2578 BFA_LOG(KERN_INFO, bfad, bfa_log_level, 2579 "Base port enabled: WWN = %s\n", pwwn_buf); 2580 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE); 2581 break; 2582 2583 case BFA_FCPORT_SM_DISABLE: 2584 /* 2585 * Already disabled. 2586 */ 2587 break; 2588 2589 case BFA_FCPORT_SM_HWFAIL: 2590 bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2591 break; 2592 2593 case BFA_FCPORT_SM_DPORTENABLE: 2594 bfa_sm_set_state(fcport, bfa_fcport_sm_dport); 2595 break; 2596 2597 case BFA_FCPORT_SM_DDPORTENABLE: 2598 bfa_sm_set_state(fcport, bfa_fcport_sm_ddport); 2599 break; 2600 2601 default: 2602 bfa_sm_fault(fcport->bfa, event); 2603 } 2604 } 2605 2606 static void 2607 bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport, 2608 enum bfa_fcport_sm_event event) 2609 { 2610 bfa_trc(fcport->bfa, event); 2611 2612 switch (event) { 2613 case BFA_FCPORT_SM_START: 2614 if (bfa_fcport_send_enable(fcport)) 2615 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2616 else 2617 bfa_sm_set_state(fcport, 2618 bfa_fcport_sm_enabling_qwait); 2619 break; 2620 2621 default: 2622 /* 2623 * Ignore all other events. 2624 */ 2625 ; 2626 } 2627 } 2628 2629 /* 2630 * Port is enabled. IOC is down/failed. 2631 */ 2632 static void 2633 bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, 2634 enum bfa_fcport_sm_event event) 2635 { 2636 bfa_trc(fcport->bfa, event); 2637 2638 switch (event) { 2639 case BFA_FCPORT_SM_START: 2640 if (bfa_fcport_send_enable(fcport)) 2641 bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); 2642 else 2643 bfa_sm_set_state(fcport, 2644 bfa_fcport_sm_enabling_qwait); 2645 break; 2646 2647 default: 2648 /* 2649 * Ignore all events. 2650 */ 2651 ; 2652 } 2653 } 2654 2655 /* 2656 * Port is disabled. IOC is down/failed. 2657 */ 2658 static void 2659 bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, 2660 enum bfa_fcport_sm_event event) 2661 { 2662 bfa_trc(fcport->bfa, event); 2663 2664 switch (event) { 2665 case BFA_FCPORT_SM_START: 2666 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2667 break; 2668 2669 case BFA_FCPORT_SM_ENABLE: 2670 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2671 break; 2672 2673 default: 2674 /* 2675 * Ignore all events. 2676 */ 2677 ; 2678 } 2679 } 2680 2681 static void 2682 bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event) 2683 { 2684 bfa_trc(fcport->bfa, event); 2685 2686 switch (event) { 2687 case BFA_FCPORT_SM_DPORTENABLE: 2688 case BFA_FCPORT_SM_DISABLE: 2689 case BFA_FCPORT_SM_ENABLE: 2690 case BFA_FCPORT_SM_START: 2691 /* 2692 * Ignore event for a port that is dport 2693 */ 2694 break; 2695 2696 case BFA_FCPORT_SM_STOP: 2697 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2698 break; 2699 2700 case BFA_FCPORT_SM_HWFAIL: 2701 bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2702 break; 2703 2704 case BFA_FCPORT_SM_DPORTDISABLE: 2705 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2706 break; 2707 2708 default: 2709 bfa_sm_fault(fcport->bfa, event); 2710 } 2711 } 2712 2713 static void 2714 bfa_fcport_sm_ddport(struct bfa_fcport_s *fcport, 2715 enum bfa_fcport_sm_event event) 2716 { 2717 bfa_trc(fcport->bfa, event); 2718 2719 switch (event) { 2720 case BFA_FCPORT_SM_DISABLE: 2721 case BFA_FCPORT_SM_DDPORTDISABLE: 2722 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2723 break; 2724 2725 case BFA_FCPORT_SM_DPORTENABLE: 2726 case BFA_FCPORT_SM_DPORTDISABLE: 2727 case BFA_FCPORT_SM_ENABLE: 2728 case BFA_FCPORT_SM_START: 2729 /** 2730 * Ignore event for a port that is ddport 2731 */ 2732 break; 2733 2734 case BFA_FCPORT_SM_STOP: 2735 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2736 break; 2737 2738 case BFA_FCPORT_SM_HWFAIL: 2739 bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2740 break; 2741 2742 default: 2743 bfa_sm_fault(fcport->bfa, event); 2744 } 2745 } 2746 2747 static void 2748 bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport, 2749 enum bfa_fcport_sm_event event) 2750 { 2751 bfa_trc(fcport->bfa, event); 2752 2753 switch (event) { 2754 case BFA_FCPORT_SM_DPORTENABLE: 2755 case BFA_FCPORT_SM_ENABLE: 2756 case BFA_FCPORT_SM_START: 2757 /* 2758 * Ignore event for a port as there is FAA misconfig 2759 */ 2760 break; 2761 2762 case BFA_FCPORT_SM_DISABLE: 2763 if (bfa_fcport_send_disable(fcport)) 2764 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); 2765 else 2766 bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait); 2767 2768 bfa_fcport_reset_linkinfo(fcport); 2769 bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2770 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 2771 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); 2772 bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); 2773 break; 2774 2775 case BFA_FCPORT_SM_STOP: 2776 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2777 break; 2778 2779 case BFA_FCPORT_SM_HWFAIL: 2780 bfa_fcport_reset_linkinfo(fcport); 2781 bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); 2782 bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); 2783 break; 2784 2785 default: 2786 bfa_sm_fault(fcport->bfa, event); 2787 } 2788 } 2789 2790 /* 2791 * Link state is down 2792 */ 2793 static void 2794 bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, 2795 enum bfa_fcport_ln_sm_event event) 2796 { 2797 bfa_trc(ln->fcport->bfa, event); 2798 2799 switch (event) { 2800 case BFA_FCPORT_LN_SM_LINKUP: 2801 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf); 2802 bfa_fcport_queue_cb(ln, BFA_PORT_LINKUP); 2803 break; 2804 2805 default: 2806 bfa_sm_fault(ln->fcport->bfa, event); 2807 } 2808 } 2809 2810 /* 2811 * Link state is waiting for down notification 2812 */ 2813 static void 2814 bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln, 2815 enum bfa_fcport_ln_sm_event event) 2816 { 2817 bfa_trc(ln->fcport->bfa, event); 2818 2819 switch (event) { 2820 case BFA_FCPORT_LN_SM_LINKUP: 2821 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf); 2822 break; 2823 2824 case BFA_FCPORT_LN_SM_NOTIFICATION: 2825 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn); 2826 break; 2827 2828 default: 2829 bfa_sm_fault(ln->fcport->bfa, event); 2830 } 2831 } 2832 2833 /* 2834 * Link state is waiting for down notification and there is a pending up 2835 */ 2836 static void 2837 bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln, 2838 enum bfa_fcport_ln_sm_event event) 2839 { 2840 bfa_trc(ln->fcport->bfa, event); 2841 2842 switch (event) { 2843 case BFA_FCPORT_LN_SM_LINKDOWN: 2844 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); 2845 break; 2846 2847 case BFA_FCPORT_LN_SM_NOTIFICATION: 2848 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf); 2849 bfa_fcport_queue_cb(ln, BFA_PORT_LINKUP); 2850 break; 2851 2852 default: 2853 bfa_sm_fault(ln->fcport->bfa, event); 2854 } 2855 } 2856 2857 /* 2858 * Link state is up 2859 */ 2860 static void 2861 bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln, 2862 enum bfa_fcport_ln_sm_event event) 2863 { 2864 bfa_trc(ln->fcport->bfa, event); 2865 2866 switch (event) { 2867 case BFA_FCPORT_LN_SM_LINKDOWN: 2868 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); 2869 bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN); 2870 break; 2871 2872 default: 2873 bfa_sm_fault(ln->fcport->bfa, event); 2874 } 2875 } 2876 2877 /* 2878 * Link state is waiting for up notification 2879 */ 2880 static void 2881 bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln, 2882 enum bfa_fcport_ln_sm_event event) 2883 { 2884 bfa_trc(ln->fcport->bfa, event); 2885 2886 switch (event) { 2887 case BFA_FCPORT_LN_SM_LINKDOWN: 2888 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf); 2889 break; 2890 2891 case BFA_FCPORT_LN_SM_NOTIFICATION: 2892 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up); 2893 break; 2894 2895 default: 2896 bfa_sm_fault(ln->fcport->bfa, event); 2897 } 2898 } 2899 2900 /* 2901 * Link state is waiting for up notification and there is a pending down 2902 */ 2903 static void 2904 bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln, 2905 enum bfa_fcport_ln_sm_event event) 2906 { 2907 bfa_trc(ln->fcport->bfa, event); 2908 2909 switch (event) { 2910 case BFA_FCPORT_LN_SM_LINKUP: 2911 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf); 2912 break; 2913 2914 case BFA_FCPORT_LN_SM_NOTIFICATION: 2915 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); 2916 bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN); 2917 break; 2918 2919 default: 2920 bfa_sm_fault(ln->fcport->bfa, event); 2921 } 2922 } 2923 2924 /* 2925 * Link state is waiting for up notification and there are pending down and up 2926 */ 2927 static void 2928 bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln, 2929 enum bfa_fcport_ln_sm_event event) 2930 { 2931 bfa_trc(ln->fcport->bfa, event); 2932 2933 switch (event) { 2934 case BFA_FCPORT_LN_SM_LINKDOWN: 2935 bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf); 2936 break; 2937 2938 case BFA_FCPORT_LN_SM_NOTIFICATION: 2939 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf); 2940 bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN); 2941 break; 2942 2943 default: 2944 bfa_sm_fault(ln->fcport->bfa, event); 2945 } 2946 } 2947 2948 static void 2949 __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete) 2950 { 2951 struct bfa_fcport_ln_s *ln = cbarg; 2952 2953 if (complete) 2954 ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event); 2955 else 2956 bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION); 2957 } 2958 2959 /* 2960 * Send SCN notification to upper layers. 2961 * trunk - false if caller is fcport to ignore fcport event in trunked mode 2962 */ 2963 static void 2964 bfa_fcport_scn(struct bfa_fcport_s *fcport, enum bfa_port_linkstate event, 2965 bfa_boolean_t trunk) 2966 { 2967 if (fcport->cfg.trunked && !trunk) 2968 return; 2969 2970 switch (event) { 2971 case BFA_PORT_LINKUP: 2972 bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP); 2973 break; 2974 case BFA_PORT_LINKDOWN: 2975 bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN); 2976 break; 2977 default: 2978 WARN_ON(1); 2979 } 2980 } 2981 2982 static void 2983 bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_port_linkstate event) 2984 { 2985 struct bfa_fcport_s *fcport = ln->fcport; 2986 2987 if (fcport->bfa->fcs) { 2988 fcport->event_cbfn(fcport->event_cbarg, event); 2989 bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION); 2990 } else { 2991 ln->ln_event = event; 2992 bfa_cb_queue(fcport->bfa, &ln->ln_qe, 2993 __bfa_cb_fcport_event, ln); 2994 } 2995 } 2996 2997 #define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \ 2998 BFA_CACHELINE_SZ)) 2999 3000 void 3001 bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 3002 struct bfa_s *bfa) 3003 { 3004 struct bfa_mem_dma_s *fcport_dma = BFA_MEM_FCPORT_DMA(bfa); 3005 3006 bfa_mem_dma_setup(minfo, fcport_dma, FCPORT_STATS_DMA_SZ); 3007 } 3008 3009 static void 3010 bfa_fcport_qresume(void *cbarg) 3011 { 3012 struct bfa_fcport_s *fcport = cbarg; 3013 3014 bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME); 3015 } 3016 3017 static void 3018 bfa_fcport_mem_claim(struct bfa_fcport_s *fcport) 3019 { 3020 struct bfa_mem_dma_s *fcport_dma = &fcport->fcport_dma; 3021 3022 fcport->stats_kva = bfa_mem_dma_virt(fcport_dma); 3023 fcport->stats_pa = bfa_mem_dma_phys(fcport_dma); 3024 fcport->stats = (union bfa_fcport_stats_u *) 3025 bfa_mem_dma_virt(fcport_dma); 3026 } 3027 3028 /* 3029 * Memory initialization. 3030 */ 3031 void 3032 bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 3033 struct bfa_pcidev_s *pcidev) 3034 { 3035 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3036 struct bfa_port_cfg_s *port_cfg = &fcport->cfg; 3037 struct bfa_fcport_ln_s *ln = &fcport->ln; 3038 3039 fcport->bfa = bfa; 3040 ln->fcport = fcport; 3041 3042 bfa_fcport_mem_claim(fcport); 3043 3044 bfa_sm_set_state(fcport, bfa_fcport_sm_uninit); 3045 bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn); 3046 3047 /* 3048 * initialize time stamp for stats reset 3049 */ 3050 fcport->stats_reset_time = ktime_get_seconds(); 3051 fcport->stats_dma_ready = BFA_FALSE; 3052 3053 /* 3054 * initialize and set default configuration 3055 */ 3056 port_cfg->topology = BFA_PORT_TOPOLOGY_P2P; 3057 port_cfg->speed = BFA_PORT_SPEED_AUTO; 3058 port_cfg->trunked = BFA_FALSE; 3059 port_cfg->maxfrsize = 0; 3060 3061 port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS; 3062 port_cfg->qos_bw.high = BFA_QOS_BW_HIGH; 3063 port_cfg->qos_bw.med = BFA_QOS_BW_MED; 3064 port_cfg->qos_bw.low = BFA_QOS_BW_LOW; 3065 3066 fcport->fec_state = BFA_FEC_OFFLINE; 3067 3068 INIT_LIST_HEAD(&fcport->stats_pending_q); 3069 INIT_LIST_HEAD(&fcport->statsclr_pending_q); 3070 3071 bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport); 3072 } 3073 3074 void 3075 bfa_fcport_start(struct bfa_s *bfa) 3076 { 3077 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START); 3078 } 3079 3080 /* 3081 * Called when IOC failure is detected. 3082 */ 3083 void 3084 bfa_fcport_iocdisable(struct bfa_s *bfa) 3085 { 3086 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3087 3088 bfa_sm_send_event(fcport, BFA_FCPORT_SM_HWFAIL); 3089 bfa_trunk_iocdisable(bfa); 3090 } 3091 3092 /* 3093 * Update loop info in fcport for SCN online 3094 */ 3095 static void 3096 bfa_fcport_update_loop_info(struct bfa_fcport_s *fcport, 3097 struct bfa_fcport_loop_info_s *loop_info) 3098 { 3099 fcport->myalpa = loop_info->myalpa; 3100 fcport->alpabm_valid = 3101 loop_info->alpabm_val; 3102 memcpy(fcport->alpabm.alpa_bm, 3103 loop_info->alpabm.alpa_bm, 3104 sizeof(struct fc_alpabm_s)); 3105 } 3106 3107 static void 3108 bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) 3109 { 3110 struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event; 3111 struct bfa_fcport_trunk_s *trunk = &fcport->trunk; 3112 3113 fcport->speed = pevent->link_state.speed; 3114 fcport->topology = pevent->link_state.topology; 3115 3116 if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) { 3117 bfa_fcport_update_loop_info(fcport, 3118 &pevent->link_state.attr.loop_info); 3119 return; 3120 } 3121 3122 /* QoS Details */ 3123 fcport->qos_attr = pevent->link_state.qos_attr; 3124 fcport->qos_vc_attr = pevent->link_state.attr.vc_fcf.qos_vc_attr; 3125 3126 if (fcport->cfg.bb_cr_enabled) 3127 fcport->bbcr_attr = pevent->link_state.attr.bbcr_attr; 3128 3129 fcport->fec_state = pevent->link_state.fec_state; 3130 3131 /* 3132 * update trunk state if applicable 3133 */ 3134 if (!fcport->cfg.trunked) 3135 trunk->attr.state = BFA_TRUNK_DISABLED; 3136 3137 /* update FCoE specific */ 3138 fcport->fcoe_vlan = 3139 be16_to_cpu(pevent->link_state.attr.vc_fcf.fcf.vlan); 3140 3141 bfa_trc(fcport->bfa, fcport->speed); 3142 bfa_trc(fcport->bfa, fcport->topology); 3143 } 3144 3145 static void 3146 bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport) 3147 { 3148 fcport->speed = BFA_PORT_SPEED_UNKNOWN; 3149 fcport->topology = BFA_PORT_TOPOLOGY_NONE; 3150 fcport->fec_state = BFA_FEC_OFFLINE; 3151 } 3152 3153 /* 3154 * Send port enable message to firmware. 3155 */ 3156 static bfa_boolean_t 3157 bfa_fcport_send_enable(struct bfa_fcport_s *fcport) 3158 { 3159 struct bfi_fcport_enable_req_s *m; 3160 3161 /* 3162 * Increment message tag before queue check, so that responses to old 3163 * requests are discarded. 3164 */ 3165 fcport->msgtag++; 3166 3167 /* 3168 * check for room in queue to send request now 3169 */ 3170 m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3171 if (!m) { 3172 bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3173 &fcport->reqq_wait); 3174 return BFA_FALSE; 3175 } 3176 3177 bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ, 3178 bfa_fn_lpu(fcport->bfa)); 3179 m->nwwn = fcport->nwwn; 3180 m->pwwn = fcport->pwwn; 3181 m->port_cfg = fcport->cfg; 3182 m->msgtag = fcport->msgtag; 3183 m->port_cfg.maxfrsize = cpu_to_be16(fcport->cfg.maxfrsize); 3184 m->use_flash_cfg = fcport->use_flash_cfg; 3185 bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa); 3186 bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo); 3187 bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi); 3188 3189 /* 3190 * queue I/O message to firmware 3191 */ 3192 bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, m->mh); 3193 return BFA_TRUE; 3194 } 3195 3196 /* 3197 * Send port disable message to firmware. 3198 */ 3199 static bfa_boolean_t 3200 bfa_fcport_send_disable(struct bfa_fcport_s *fcport) 3201 { 3202 struct bfi_fcport_req_s *m; 3203 3204 /* 3205 * Increment message tag before queue check, so that responses to old 3206 * requests are discarded. 3207 */ 3208 fcport->msgtag++; 3209 3210 /* 3211 * check for room in queue to send request now 3212 */ 3213 m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3214 if (!m) { 3215 bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3216 &fcport->reqq_wait); 3217 return BFA_FALSE; 3218 } 3219 3220 bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ, 3221 bfa_fn_lpu(fcport->bfa)); 3222 m->msgtag = fcport->msgtag; 3223 3224 /* 3225 * queue I/O message to firmware 3226 */ 3227 bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, m->mh); 3228 3229 return BFA_TRUE; 3230 } 3231 3232 static void 3233 bfa_fcport_set_wwns(struct bfa_fcport_s *fcport) 3234 { 3235 fcport->pwwn = fcport->bfa->ioc.attr->pwwn; 3236 fcport->nwwn = fcport->bfa->ioc.attr->nwwn; 3237 3238 bfa_trc(fcport->bfa, fcport->pwwn); 3239 bfa_trc(fcport->bfa, fcport->nwwn); 3240 } 3241 3242 static void 3243 bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d, 3244 struct bfa_qos_stats_s *s) 3245 { 3246 u32 *dip = (u32 *) d; 3247 __be32 *sip = (__be32 *) s; 3248 int i; 3249 3250 /* Now swap the 32 bit fields */ 3251 for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i) 3252 dip[i] = be32_to_cpu(sip[i]); 3253 } 3254 3255 static void 3256 bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d, 3257 struct bfa_fcoe_stats_s *s) 3258 { 3259 u32 *dip = (u32 *) d; 3260 __be32 *sip = (__be32 *) s; 3261 int i; 3262 3263 for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32)); 3264 i = i + 2) { 3265 #ifdef __BIG_ENDIAN 3266 dip[i] = be32_to_cpu(sip[i]); 3267 dip[i + 1] = be32_to_cpu(sip[i + 1]); 3268 #else 3269 dip[i] = be32_to_cpu(sip[i + 1]); 3270 dip[i + 1] = be32_to_cpu(sip[i]); 3271 #endif 3272 } 3273 } 3274 3275 static void 3276 __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete) 3277 { 3278 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg; 3279 struct bfa_cb_pending_q_s *cb; 3280 struct list_head *qe, *qen; 3281 union bfa_fcport_stats_u *ret; 3282 3283 if (complete) { 3284 time64_t time = ktime_get_seconds(); 3285 3286 list_for_each_safe(qe, qen, &fcport->stats_pending_q) { 3287 bfa_q_deq(&fcport->stats_pending_q, &qe); 3288 cb = (struct bfa_cb_pending_q_s *)qe; 3289 if (fcport->stats_status == BFA_STATUS_OK) { 3290 ret = (union bfa_fcport_stats_u *)cb->data; 3291 /* Swap FC QoS or FCoE stats */ 3292 if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) 3293 bfa_fcport_qos_stats_swap(&ret->fcqos, 3294 &fcport->stats->fcqos); 3295 else { 3296 bfa_fcport_fcoe_stats_swap(&ret->fcoe, 3297 &fcport->stats->fcoe); 3298 ret->fcoe.secs_reset = 3299 time - fcport->stats_reset_time; 3300 } 3301 } 3302 bfa_cb_queue_status(fcport->bfa, &cb->hcb_qe, 3303 fcport->stats_status); 3304 } 3305 fcport->stats_status = BFA_STATUS_OK; 3306 } else { 3307 INIT_LIST_HEAD(&fcport->stats_pending_q); 3308 fcport->stats_status = BFA_STATUS_OK; 3309 } 3310 } 3311 3312 static void 3313 bfa_fcport_stats_get_timeout(void *cbarg) 3314 { 3315 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3316 3317 bfa_trc(fcport->bfa, fcport->stats_qfull); 3318 3319 if (fcport->stats_qfull) { 3320 bfa_reqq_wcancel(&fcport->stats_reqq_wait); 3321 fcport->stats_qfull = BFA_FALSE; 3322 } 3323 3324 fcport->stats_status = BFA_STATUS_ETIMER; 3325 __bfa_cb_fcport_stats_get(fcport, BFA_TRUE); 3326 } 3327 3328 static void 3329 bfa_fcport_send_stats_get(void *cbarg) 3330 { 3331 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3332 struct bfi_fcport_req_s *msg; 3333 3334 msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3335 3336 if (!msg) { 3337 fcport->stats_qfull = BFA_TRUE; 3338 bfa_reqq_winit(&fcport->stats_reqq_wait, 3339 bfa_fcport_send_stats_get, fcport); 3340 bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3341 &fcport->stats_reqq_wait); 3342 return; 3343 } 3344 fcport->stats_qfull = BFA_FALSE; 3345 3346 memset(msg, 0, sizeof(struct bfi_fcport_req_s)); 3347 bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ, 3348 bfa_fn_lpu(fcport->bfa)); 3349 bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, msg->mh); 3350 } 3351 3352 static void 3353 __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete) 3354 { 3355 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3356 struct bfa_cb_pending_q_s *cb; 3357 struct list_head *qe, *qen; 3358 3359 if (complete) { 3360 /* 3361 * re-initialize time stamp for stats reset 3362 */ 3363 fcport->stats_reset_time = ktime_get_seconds(); 3364 list_for_each_safe(qe, qen, &fcport->statsclr_pending_q) { 3365 bfa_q_deq(&fcport->statsclr_pending_q, &qe); 3366 cb = (struct bfa_cb_pending_q_s *)qe; 3367 bfa_cb_queue_status(fcport->bfa, &cb->hcb_qe, 3368 fcport->stats_status); 3369 } 3370 fcport->stats_status = BFA_STATUS_OK; 3371 } else { 3372 INIT_LIST_HEAD(&fcport->statsclr_pending_q); 3373 fcport->stats_status = BFA_STATUS_OK; 3374 } 3375 } 3376 3377 static void 3378 bfa_fcport_stats_clr_timeout(void *cbarg) 3379 { 3380 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3381 3382 bfa_trc(fcport->bfa, fcport->stats_qfull); 3383 3384 if (fcport->stats_qfull) { 3385 bfa_reqq_wcancel(&fcport->stats_reqq_wait); 3386 fcport->stats_qfull = BFA_FALSE; 3387 } 3388 3389 fcport->stats_status = BFA_STATUS_ETIMER; 3390 __bfa_cb_fcport_stats_clr(fcport, BFA_TRUE); 3391 } 3392 3393 static void 3394 bfa_fcport_send_stats_clear(void *cbarg) 3395 { 3396 struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; 3397 struct bfi_fcport_req_s *msg; 3398 3399 msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); 3400 3401 if (!msg) { 3402 fcport->stats_qfull = BFA_TRUE; 3403 bfa_reqq_winit(&fcport->stats_reqq_wait, 3404 bfa_fcport_send_stats_clear, fcport); 3405 bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, 3406 &fcport->stats_reqq_wait); 3407 return; 3408 } 3409 fcport->stats_qfull = BFA_FALSE; 3410 3411 memset(msg, 0, sizeof(struct bfi_fcport_req_s)); 3412 bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ, 3413 bfa_fn_lpu(fcport->bfa)); 3414 bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, msg->mh); 3415 } 3416 3417 /* 3418 * Handle trunk SCN event from firmware. 3419 */ 3420 static void 3421 bfa_trunk_scn(struct bfa_fcport_s *fcport, struct bfi_fcport_trunk_scn_s *scn) 3422 { 3423 struct bfa_fcport_trunk_s *trunk = &fcport->trunk; 3424 struct bfi_fcport_trunk_link_s *tlink; 3425 struct bfa_trunk_link_attr_s *lattr; 3426 enum bfa_trunk_state state_prev; 3427 int i; 3428 int link_bm = 0; 3429 3430 bfa_trc(fcport->bfa, fcport->cfg.trunked); 3431 WARN_ON(scn->trunk_state != BFA_TRUNK_ONLINE && 3432 scn->trunk_state != BFA_TRUNK_OFFLINE); 3433 3434 bfa_trc(fcport->bfa, trunk->attr.state); 3435 bfa_trc(fcport->bfa, scn->trunk_state); 3436 bfa_trc(fcport->bfa, scn->trunk_speed); 3437 3438 /* 3439 * Save off new state for trunk attribute query 3440 */ 3441 state_prev = trunk->attr.state; 3442 if (fcport->cfg.trunked && (trunk->attr.state != BFA_TRUNK_DISABLED)) 3443 trunk->attr.state = scn->trunk_state; 3444 trunk->attr.speed = scn->trunk_speed; 3445 for (i = 0; i < BFA_TRUNK_MAX_PORTS; i++) { 3446 lattr = &trunk->attr.link_attr[i]; 3447 tlink = &scn->tlink[i]; 3448 3449 lattr->link_state = tlink->state; 3450 lattr->trunk_wwn = tlink->trunk_wwn; 3451 lattr->fctl = tlink->fctl; 3452 lattr->speed = tlink->speed; 3453 lattr->deskew = be32_to_cpu(tlink->deskew); 3454 3455 if (tlink->state == BFA_TRUNK_LINK_STATE_UP) { 3456 fcport->speed = tlink->speed; 3457 fcport->topology = BFA_PORT_TOPOLOGY_P2P; 3458 link_bm |= 1 << i; 3459 } 3460 3461 bfa_trc(fcport->bfa, lattr->link_state); 3462 bfa_trc(fcport->bfa, lattr->trunk_wwn); 3463 bfa_trc(fcport->bfa, lattr->fctl); 3464 bfa_trc(fcport->bfa, lattr->speed); 3465 bfa_trc(fcport->bfa, lattr->deskew); 3466 } 3467 3468 switch (link_bm) { 3469 case 3: 3470 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3471 BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(0,1)"); 3472 break; 3473 case 2: 3474 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3475 BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(-,1)"); 3476 break; 3477 case 1: 3478 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3479 BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(0,-)"); 3480 break; 3481 default: 3482 bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, 3483 BFA_PL_EID_TRUNK_SCN, 0, "Trunk down"); 3484 } 3485 3486 /* 3487 * Notify upper layers if trunk state changed. 3488 */ 3489 if ((state_prev != trunk->attr.state) || 3490 (scn->trunk_state == BFA_TRUNK_OFFLINE)) { 3491 bfa_fcport_scn(fcport, (scn->trunk_state == BFA_TRUNK_ONLINE) ? 3492 BFA_PORT_LINKUP : BFA_PORT_LINKDOWN, BFA_TRUE); 3493 } 3494 } 3495 3496 static void 3497 bfa_trunk_iocdisable(struct bfa_s *bfa) 3498 { 3499 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3500 int i = 0; 3501 3502 /* 3503 * In trunked mode, notify upper layers that link is down 3504 */ 3505 if (fcport->cfg.trunked) { 3506 if (fcport->trunk.attr.state == BFA_TRUNK_ONLINE) 3507 bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_TRUE); 3508 3509 fcport->trunk.attr.state = BFA_TRUNK_OFFLINE; 3510 fcport->trunk.attr.speed = BFA_PORT_SPEED_UNKNOWN; 3511 for (i = 0; i < BFA_TRUNK_MAX_PORTS; i++) { 3512 fcport->trunk.attr.link_attr[i].trunk_wwn = 0; 3513 fcport->trunk.attr.link_attr[i].fctl = 3514 BFA_TRUNK_LINK_FCTL_NORMAL; 3515 fcport->trunk.attr.link_attr[i].link_state = 3516 BFA_TRUNK_LINK_STATE_DN_LINKDN; 3517 fcport->trunk.attr.link_attr[i].speed = 3518 BFA_PORT_SPEED_UNKNOWN; 3519 fcport->trunk.attr.link_attr[i].deskew = 0; 3520 } 3521 } 3522 } 3523 3524 /* 3525 * Called to initialize port attributes 3526 */ 3527 void 3528 bfa_fcport_init(struct bfa_s *bfa) 3529 { 3530 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3531 3532 /* 3533 * Initialize port attributes from IOC hardware data. 3534 */ 3535 bfa_fcport_set_wwns(fcport); 3536 if (fcport->cfg.maxfrsize == 0) 3537 fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc); 3538 fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc); 3539 fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc); 3540 3541 if (bfa_fcport_is_pbcdisabled(bfa)) 3542 bfa->modules.port.pbc_disabled = BFA_TRUE; 3543 3544 WARN_ON(!fcport->cfg.maxfrsize); 3545 WARN_ON(!fcport->cfg.rx_bbcredit); 3546 WARN_ON(!fcport->speed_sup); 3547 } 3548 3549 /* 3550 * Firmware message handler. 3551 */ 3552 void 3553 bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 3554 { 3555 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3556 union bfi_fcport_i2h_msg_u i2hmsg; 3557 3558 i2hmsg.msg = msg; 3559 fcport->event_arg.i2hmsg = i2hmsg; 3560 3561 bfa_trc(bfa, msg->mhdr.msg_id); 3562 bfa_trc(bfa, bfa_sm_to_state(hal_port_sm_table, fcport->sm)); 3563 3564 switch (msg->mhdr.msg_id) { 3565 case BFI_FCPORT_I2H_ENABLE_RSP: 3566 if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) { 3567 3568 fcport->stats_dma_ready = BFA_TRUE; 3569 if (fcport->use_flash_cfg) { 3570 fcport->cfg = i2hmsg.penable_rsp->port_cfg; 3571 fcport->cfg.maxfrsize = 3572 cpu_to_be16(fcport->cfg.maxfrsize); 3573 fcport->cfg.path_tov = 3574 cpu_to_be16(fcport->cfg.path_tov); 3575 fcport->cfg.q_depth = 3576 cpu_to_be16(fcport->cfg.q_depth); 3577 3578 if (fcport->cfg.trunked) 3579 fcport->trunk.attr.state = 3580 BFA_TRUNK_OFFLINE; 3581 else 3582 fcport->trunk.attr.state = 3583 BFA_TRUNK_DISABLED; 3584 fcport->qos_attr.qos_bw = 3585 i2hmsg.penable_rsp->port_cfg.qos_bw; 3586 fcport->use_flash_cfg = BFA_FALSE; 3587 } 3588 3589 if (fcport->cfg.qos_enabled) 3590 fcport->qos_attr.state = BFA_QOS_OFFLINE; 3591 else 3592 fcport->qos_attr.state = BFA_QOS_DISABLED; 3593 3594 fcport->qos_attr.qos_bw_op = 3595 i2hmsg.penable_rsp->port_cfg.qos_bw; 3596 3597 if (fcport->cfg.bb_cr_enabled) 3598 fcport->bbcr_attr.state = BFA_BBCR_OFFLINE; 3599 else 3600 fcport->bbcr_attr.state = BFA_BBCR_DISABLED; 3601 3602 bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); 3603 } 3604 break; 3605 3606 case BFI_FCPORT_I2H_DISABLE_RSP: 3607 if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) 3608 bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); 3609 break; 3610 3611 case BFI_FCPORT_I2H_EVENT: 3612 if (fcport->cfg.bb_cr_enabled) 3613 fcport->bbcr_attr.state = BFA_BBCR_OFFLINE; 3614 else 3615 fcport->bbcr_attr.state = BFA_BBCR_DISABLED; 3616 3617 if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP) 3618 bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP); 3619 else { 3620 if (i2hmsg.event->link_state.linkstate_rsn == 3621 BFA_PORT_LINKSTATE_RSN_FAA_MISCONFIG) 3622 bfa_sm_send_event(fcport, 3623 BFA_FCPORT_SM_FAA_MISCONFIG); 3624 else 3625 bfa_sm_send_event(fcport, 3626 BFA_FCPORT_SM_LINKDOWN); 3627 } 3628 fcport->qos_attr.qos_bw_op = 3629 i2hmsg.event->link_state.qos_attr.qos_bw_op; 3630 break; 3631 3632 case BFI_FCPORT_I2H_TRUNK_SCN: 3633 bfa_trunk_scn(fcport, i2hmsg.trunk_scn); 3634 break; 3635 3636 case BFI_FCPORT_I2H_STATS_GET_RSP: 3637 /* 3638 * check for timer pop before processing the rsp 3639 */ 3640 if (list_empty(&fcport->stats_pending_q) || 3641 (fcport->stats_status == BFA_STATUS_ETIMER)) 3642 break; 3643 3644 bfa_timer_stop(&fcport->timer); 3645 fcport->stats_status = i2hmsg.pstatsget_rsp->status; 3646 __bfa_cb_fcport_stats_get(fcport, BFA_TRUE); 3647 break; 3648 3649 case BFI_FCPORT_I2H_STATS_CLEAR_RSP: 3650 /* 3651 * check for timer pop before processing the rsp 3652 */ 3653 if (list_empty(&fcport->statsclr_pending_q) || 3654 (fcport->stats_status == BFA_STATUS_ETIMER)) 3655 break; 3656 3657 bfa_timer_stop(&fcport->timer); 3658 fcport->stats_status = BFA_STATUS_OK; 3659 __bfa_cb_fcport_stats_clr(fcport, BFA_TRUE); 3660 break; 3661 3662 case BFI_FCPORT_I2H_ENABLE_AEN: 3663 bfa_sm_send_event(fcport, BFA_FCPORT_SM_ENABLE); 3664 break; 3665 3666 case BFI_FCPORT_I2H_DISABLE_AEN: 3667 bfa_sm_send_event(fcport, BFA_FCPORT_SM_DISABLE); 3668 break; 3669 3670 default: 3671 WARN_ON(1); 3672 break; 3673 } 3674 } 3675 3676 /* 3677 * Registered callback for port events. 3678 */ 3679 void 3680 bfa_fcport_event_register(struct bfa_s *bfa, 3681 void (*cbfn) (void *cbarg, 3682 enum bfa_port_linkstate event), 3683 void *cbarg) 3684 { 3685 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3686 3687 fcport->event_cbfn = cbfn; 3688 fcport->event_cbarg = cbarg; 3689 } 3690 3691 bfa_status_t 3692 bfa_fcport_enable(struct bfa_s *bfa) 3693 { 3694 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3695 3696 if (bfa_fcport_is_pbcdisabled(bfa)) 3697 return BFA_STATUS_PBC; 3698 3699 if (bfa_ioc_is_disabled(&bfa->ioc)) 3700 return BFA_STATUS_IOC_DISABLED; 3701 3702 if (fcport->diag_busy) 3703 return BFA_STATUS_DIAG_BUSY; 3704 3705 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE); 3706 return BFA_STATUS_OK; 3707 } 3708 3709 bfa_status_t 3710 bfa_fcport_disable(struct bfa_s *bfa) 3711 { 3712 if (bfa_fcport_is_pbcdisabled(bfa)) 3713 return BFA_STATUS_PBC; 3714 3715 if (bfa_ioc_is_disabled(&bfa->ioc)) 3716 return BFA_STATUS_IOC_DISABLED; 3717 3718 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE); 3719 return BFA_STATUS_OK; 3720 } 3721 3722 /* If PBC is disabled on port, return error */ 3723 bfa_status_t 3724 bfa_fcport_is_pbcdisabled(struct bfa_s *bfa) 3725 { 3726 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3727 struct bfa_iocfc_s *iocfc = &bfa->iocfc; 3728 struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp; 3729 3730 if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) { 3731 bfa_trc(bfa, fcport->pwwn); 3732 return BFA_STATUS_PBC; 3733 } 3734 return BFA_STATUS_OK; 3735 } 3736 3737 /* 3738 * Configure port speed. 3739 */ 3740 bfa_status_t 3741 bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed) 3742 { 3743 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3744 3745 bfa_trc(bfa, speed); 3746 3747 if (fcport->cfg.trunked == BFA_TRUE) 3748 return BFA_STATUS_TRUNK_ENABLED; 3749 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 3750 (speed == BFA_PORT_SPEED_16GBPS)) 3751 return BFA_STATUS_UNSUPP_SPEED; 3752 if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) { 3753 bfa_trc(bfa, fcport->speed_sup); 3754 return BFA_STATUS_UNSUPP_SPEED; 3755 } 3756 3757 /* Port speed entered needs to be checked */ 3758 if (bfa_ioc_get_type(&fcport->bfa->ioc) == BFA_IOC_TYPE_FC) { 3759 /* For CT2, 1G is not supported */ 3760 if ((speed == BFA_PORT_SPEED_1GBPS) && 3761 (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) 3762 return BFA_STATUS_UNSUPP_SPEED; 3763 3764 /* Already checked for Auto Speed and Max Speed supp */ 3765 if (!(speed == BFA_PORT_SPEED_1GBPS || 3766 speed == BFA_PORT_SPEED_2GBPS || 3767 speed == BFA_PORT_SPEED_4GBPS || 3768 speed == BFA_PORT_SPEED_8GBPS || 3769 speed == BFA_PORT_SPEED_16GBPS || 3770 speed == BFA_PORT_SPEED_AUTO)) 3771 return BFA_STATUS_UNSUPP_SPEED; 3772 } else { 3773 if (speed != BFA_PORT_SPEED_10GBPS) 3774 return BFA_STATUS_UNSUPP_SPEED; 3775 } 3776 3777 fcport->cfg.speed = speed; 3778 3779 return BFA_STATUS_OK; 3780 } 3781 3782 /* 3783 * Get current speed. 3784 */ 3785 enum bfa_port_speed 3786 bfa_fcport_get_speed(struct bfa_s *bfa) 3787 { 3788 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3789 3790 return fcport->speed; 3791 } 3792 3793 /* 3794 * Configure port topology. 3795 */ 3796 bfa_status_t 3797 bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology) 3798 { 3799 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3800 3801 bfa_trc(bfa, topology); 3802 bfa_trc(bfa, fcport->cfg.topology); 3803 3804 switch (topology) { 3805 case BFA_PORT_TOPOLOGY_P2P: 3806 break; 3807 3808 case BFA_PORT_TOPOLOGY_LOOP: 3809 if ((bfa_fcport_is_qos_enabled(bfa) != BFA_FALSE) || 3810 (fcport->qos_attr.state != BFA_QOS_DISABLED)) 3811 return BFA_STATUS_ERROR_QOS_ENABLED; 3812 if (fcport->cfg.ratelimit != BFA_FALSE) 3813 return BFA_STATUS_ERROR_TRL_ENABLED; 3814 if ((bfa_fcport_is_trunk_enabled(bfa) != BFA_FALSE) || 3815 (fcport->trunk.attr.state != BFA_TRUNK_DISABLED)) 3816 return BFA_STATUS_ERROR_TRUNK_ENABLED; 3817 if ((bfa_fcport_get_speed(bfa) == BFA_PORT_SPEED_16GBPS) || 3818 (fcport->cfg.speed == BFA_PORT_SPEED_16GBPS)) 3819 return BFA_STATUS_UNSUPP_SPEED; 3820 if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) 3821 return BFA_STATUS_LOOP_UNSUPP_MEZZ; 3822 if (bfa_fcport_is_dport(bfa) != BFA_FALSE) 3823 return BFA_STATUS_DPORT_ERR; 3824 if (bfa_fcport_is_ddport(bfa) != BFA_FALSE) 3825 return BFA_STATUS_DPORT_ERR; 3826 break; 3827 3828 case BFA_PORT_TOPOLOGY_AUTO: 3829 break; 3830 3831 default: 3832 return BFA_STATUS_EINVAL; 3833 } 3834 3835 fcport->cfg.topology = topology; 3836 return BFA_STATUS_OK; 3837 } 3838 3839 /* 3840 * Get current topology. 3841 */ 3842 enum bfa_port_topology 3843 bfa_fcport_get_topology(struct bfa_s *bfa) 3844 { 3845 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3846 3847 return fcport->topology; 3848 } 3849 3850 /** 3851 * Get config topology. 3852 */ 3853 enum bfa_port_topology 3854 bfa_fcport_get_cfg_topology(struct bfa_s *bfa) 3855 { 3856 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3857 3858 return fcport->cfg.topology; 3859 } 3860 3861 bfa_status_t 3862 bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) 3863 { 3864 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3865 3866 bfa_trc(bfa, alpa); 3867 bfa_trc(bfa, fcport->cfg.cfg_hardalpa); 3868 bfa_trc(bfa, fcport->cfg.hardalpa); 3869 3870 fcport->cfg.cfg_hardalpa = BFA_TRUE; 3871 fcport->cfg.hardalpa = alpa; 3872 3873 return BFA_STATUS_OK; 3874 } 3875 3876 bfa_status_t 3877 bfa_fcport_clr_hardalpa(struct bfa_s *bfa) 3878 { 3879 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3880 3881 bfa_trc(bfa, fcport->cfg.cfg_hardalpa); 3882 bfa_trc(bfa, fcport->cfg.hardalpa); 3883 3884 fcport->cfg.cfg_hardalpa = BFA_FALSE; 3885 return BFA_STATUS_OK; 3886 } 3887 3888 bfa_boolean_t 3889 bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa) 3890 { 3891 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3892 3893 *alpa = fcport->cfg.hardalpa; 3894 return fcport->cfg.cfg_hardalpa; 3895 } 3896 3897 u8 3898 bfa_fcport_get_myalpa(struct bfa_s *bfa) 3899 { 3900 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3901 3902 return fcport->myalpa; 3903 } 3904 3905 bfa_status_t 3906 bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize) 3907 { 3908 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3909 3910 bfa_trc(bfa, maxfrsize); 3911 bfa_trc(bfa, fcport->cfg.maxfrsize); 3912 3913 /* with in range */ 3914 if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ)) 3915 return BFA_STATUS_INVLD_DFSZ; 3916 3917 /* power of 2, if not the max frame size of 2112 */ 3918 if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1))) 3919 return BFA_STATUS_INVLD_DFSZ; 3920 3921 fcport->cfg.maxfrsize = maxfrsize; 3922 return BFA_STATUS_OK; 3923 } 3924 3925 u16 3926 bfa_fcport_get_maxfrsize(struct bfa_s *bfa) 3927 { 3928 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3929 3930 return fcport->cfg.maxfrsize; 3931 } 3932 3933 u8 3934 bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) 3935 { 3936 if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP) 3937 return (BFA_FCPORT_MOD(bfa))->cfg.rx_bbcredit; 3938 3939 else 3940 return 0; 3941 } 3942 3943 void 3944 bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit) 3945 { 3946 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3947 3948 fcport->cfg.tx_bbcredit = (u8)tx_bbcredit; 3949 } 3950 3951 /* 3952 * Get port attributes. 3953 */ 3954 3955 wwn_t 3956 bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node) 3957 { 3958 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3959 if (node) 3960 return fcport->nwwn; 3961 else 3962 return fcport->pwwn; 3963 } 3964 3965 void 3966 bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr) 3967 { 3968 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 3969 3970 memset(attr, 0, sizeof(struct bfa_port_attr_s)); 3971 3972 attr->nwwn = fcport->nwwn; 3973 attr->pwwn = fcport->pwwn; 3974 3975 attr->factorypwwn = bfa->ioc.attr->mfg_pwwn; 3976 attr->factorynwwn = bfa->ioc.attr->mfg_nwwn; 3977 3978 memcpy(&attr->pport_cfg, &fcport->cfg, 3979 sizeof(struct bfa_port_cfg_s)); 3980 /* speed attributes */ 3981 attr->pport_cfg.speed = fcport->cfg.speed; 3982 attr->speed_supported = fcport->speed_sup; 3983 attr->speed = fcport->speed; 3984 attr->cos_supported = FC_CLASS_3; 3985 3986 /* topology attributes */ 3987 attr->pport_cfg.topology = fcport->cfg.topology; 3988 attr->topology = fcport->topology; 3989 attr->pport_cfg.trunked = fcport->cfg.trunked; 3990 3991 /* beacon attributes */ 3992 attr->beacon = fcport->beacon; 3993 attr->link_e2e_beacon = fcport->link_e2e_beacon; 3994 3995 attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); 3996 attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); 3997 attr->port_state = bfa_sm_to_state(hal_port_sm_table, fcport->sm); 3998 3999 attr->fec_state = fcport->fec_state; 4000 4001 /* PBC Disabled State */ 4002 if (bfa_fcport_is_pbcdisabled(bfa)) 4003 attr->port_state = BFA_PORT_ST_PREBOOT_DISABLED; 4004 else { 4005 if (bfa_ioc_is_disabled(&fcport->bfa->ioc)) 4006 attr->port_state = BFA_PORT_ST_IOCDIS; 4007 else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc)) 4008 attr->port_state = BFA_PORT_ST_FWMISMATCH; 4009 } 4010 4011 /* FCoE vlan */ 4012 attr->fcoe_vlan = fcport->fcoe_vlan; 4013 } 4014 4015 #define BFA_FCPORT_STATS_TOV 1000 4016 4017 /* 4018 * Fetch port statistics (FCQoS or FCoE). 4019 */ 4020 bfa_status_t 4021 bfa_fcport_get_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb) 4022 { 4023 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4024 4025 if (!bfa_iocfc_is_operational(bfa) || 4026 !fcport->stats_dma_ready) 4027 return BFA_STATUS_IOC_NON_OP; 4028 4029 if (!list_empty(&fcport->statsclr_pending_q)) 4030 return BFA_STATUS_DEVBUSY; 4031 4032 if (list_empty(&fcport->stats_pending_q)) { 4033 list_add_tail(&cb->hcb_qe.qe, &fcport->stats_pending_q); 4034 bfa_fcport_send_stats_get(fcport); 4035 bfa_timer_start(bfa, &fcport->timer, 4036 bfa_fcport_stats_get_timeout, 4037 fcport, BFA_FCPORT_STATS_TOV); 4038 } else 4039 list_add_tail(&cb->hcb_qe.qe, &fcport->stats_pending_q); 4040 4041 return BFA_STATUS_OK; 4042 } 4043 4044 /* 4045 * Reset port statistics (FCQoS or FCoE). 4046 */ 4047 bfa_status_t 4048 bfa_fcport_clear_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb) 4049 { 4050 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4051 4052 if (!bfa_iocfc_is_operational(bfa) || 4053 !fcport->stats_dma_ready) 4054 return BFA_STATUS_IOC_NON_OP; 4055 4056 if (!list_empty(&fcport->stats_pending_q)) 4057 return BFA_STATUS_DEVBUSY; 4058 4059 if (list_empty(&fcport->statsclr_pending_q)) { 4060 list_add_tail(&cb->hcb_qe.qe, &fcport->statsclr_pending_q); 4061 bfa_fcport_send_stats_clear(fcport); 4062 bfa_timer_start(bfa, &fcport->timer, 4063 bfa_fcport_stats_clr_timeout, 4064 fcport, BFA_FCPORT_STATS_TOV); 4065 } else 4066 list_add_tail(&cb->hcb_qe.qe, &fcport->statsclr_pending_q); 4067 4068 return BFA_STATUS_OK; 4069 } 4070 4071 /* 4072 * Fetch port attributes. 4073 */ 4074 bfa_boolean_t 4075 bfa_fcport_is_disabled(struct bfa_s *bfa) 4076 { 4077 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4078 4079 return bfa_sm_to_state(hal_port_sm_table, fcport->sm) == 4080 BFA_PORT_ST_DISABLED; 4081 4082 } 4083 4084 bfa_boolean_t 4085 bfa_fcport_is_dport(struct bfa_s *bfa) 4086 { 4087 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4088 4089 return (bfa_sm_to_state(hal_port_sm_table, fcport->sm) == 4090 BFA_PORT_ST_DPORT); 4091 } 4092 4093 bfa_boolean_t 4094 bfa_fcport_is_ddport(struct bfa_s *bfa) 4095 { 4096 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4097 4098 return (bfa_sm_to_state(hal_port_sm_table, fcport->sm) == 4099 BFA_PORT_ST_DDPORT); 4100 } 4101 4102 bfa_status_t 4103 bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw) 4104 { 4105 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4106 enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa); 4107 4108 bfa_trc(bfa, ioc_type); 4109 4110 if ((qos_bw->high == 0) || (qos_bw->med == 0) || (qos_bw->low == 0)) 4111 return BFA_STATUS_QOS_BW_INVALID; 4112 4113 if ((qos_bw->high + qos_bw->med + qos_bw->low) != 100) 4114 return BFA_STATUS_QOS_BW_INVALID; 4115 4116 if ((qos_bw->med > qos_bw->high) || (qos_bw->low > qos_bw->med) || 4117 (qos_bw->low > qos_bw->high)) 4118 return BFA_STATUS_QOS_BW_INVALID; 4119 4120 if ((ioc_type == BFA_IOC_TYPE_FC) && 4121 (fcport->cfg.topology != BFA_PORT_TOPOLOGY_LOOP)) 4122 fcport->cfg.qos_bw = *qos_bw; 4123 4124 return BFA_STATUS_OK; 4125 } 4126 4127 bfa_boolean_t 4128 bfa_fcport_is_ratelim(struct bfa_s *bfa) 4129 { 4130 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4131 4132 return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE; 4133 4134 } 4135 4136 /* 4137 * Enable/Disable FAA feature in port config 4138 */ 4139 void 4140 bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state) 4141 { 4142 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4143 4144 bfa_trc(bfa, state); 4145 fcport->cfg.faa_state = state; 4146 } 4147 4148 /* 4149 * Get default minimum ratelim speed 4150 */ 4151 enum bfa_port_speed 4152 bfa_fcport_get_ratelim_speed(struct bfa_s *bfa) 4153 { 4154 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4155 4156 bfa_trc(bfa, fcport->cfg.trl_def_speed); 4157 return fcport->cfg.trl_def_speed; 4158 4159 } 4160 4161 void 4162 bfa_fcport_beacon(void *dev, bfa_boolean_t beacon, 4163 bfa_boolean_t link_e2e_beacon) 4164 { 4165 struct bfa_s *bfa = dev; 4166 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4167 4168 bfa_trc(bfa, beacon); 4169 bfa_trc(bfa, link_e2e_beacon); 4170 bfa_trc(bfa, fcport->beacon); 4171 bfa_trc(bfa, fcport->link_e2e_beacon); 4172 4173 fcport->beacon = beacon; 4174 fcport->link_e2e_beacon = link_e2e_beacon; 4175 } 4176 4177 bfa_boolean_t 4178 bfa_fcport_is_linkup(struct bfa_s *bfa) 4179 { 4180 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4181 4182 return (!fcport->cfg.trunked && 4183 bfa_sm_cmp_state(fcport, bfa_fcport_sm_linkup)) || 4184 (fcport->cfg.trunked && 4185 fcport->trunk.attr.state == BFA_TRUNK_ONLINE); 4186 } 4187 4188 bfa_boolean_t 4189 bfa_fcport_is_qos_enabled(struct bfa_s *bfa) 4190 { 4191 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4192 4193 return fcport->cfg.qos_enabled; 4194 } 4195 4196 bfa_boolean_t 4197 bfa_fcport_is_trunk_enabled(struct bfa_s *bfa) 4198 { 4199 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4200 4201 return fcport->cfg.trunked; 4202 } 4203 4204 bfa_status_t 4205 bfa_fcport_cfg_bbcr(struct bfa_s *bfa, bfa_boolean_t on_off, u8 bb_scn) 4206 { 4207 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4208 4209 bfa_trc(bfa, on_off); 4210 4211 if (bfa_ioc_get_type(&fcport->bfa->ioc) != BFA_IOC_TYPE_FC) 4212 return BFA_STATUS_BBCR_FC_ONLY; 4213 4214 if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type) && 4215 (bfa->ioc.attr->card_type != BFA_MFG_TYPE_CHINOOK)) 4216 return BFA_STATUS_CMD_NOTSUPP_MEZZ; 4217 4218 if (on_off) { 4219 if (fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) 4220 return BFA_STATUS_TOPOLOGY_LOOP; 4221 4222 if (fcport->cfg.qos_enabled) 4223 return BFA_STATUS_ERROR_QOS_ENABLED; 4224 4225 if (fcport->cfg.trunked) 4226 return BFA_STATUS_TRUNK_ENABLED; 4227 4228 if ((fcport->cfg.speed != BFA_PORT_SPEED_AUTO) && 4229 (fcport->cfg.speed < bfa_ioc_speed_sup(&bfa->ioc))) 4230 return BFA_STATUS_ERR_BBCR_SPEED_UNSUPPORT; 4231 4232 if (bfa_ioc_speed_sup(&bfa->ioc) < BFA_PORT_SPEED_8GBPS) 4233 return BFA_STATUS_FEATURE_NOT_SUPPORTED; 4234 4235 if (fcport->cfg.bb_cr_enabled) { 4236 if (bb_scn != fcport->cfg.bb_scn) 4237 return BFA_STATUS_BBCR_CFG_NO_CHANGE; 4238 else 4239 return BFA_STATUS_NO_CHANGE; 4240 } 4241 4242 if ((bb_scn == 0) || (bb_scn > BFA_BB_SCN_MAX)) 4243 bb_scn = BFA_BB_SCN_DEF; 4244 4245 fcport->cfg.bb_cr_enabled = on_off; 4246 fcport->cfg.bb_scn = bb_scn; 4247 } else { 4248 if (!fcport->cfg.bb_cr_enabled) 4249 return BFA_STATUS_NO_CHANGE; 4250 4251 fcport->cfg.bb_cr_enabled = on_off; 4252 fcport->cfg.bb_scn = 0; 4253 } 4254 4255 return BFA_STATUS_OK; 4256 } 4257 4258 bfa_status_t 4259 bfa_fcport_get_bbcr_attr(struct bfa_s *bfa, 4260 struct bfa_bbcr_attr_s *bbcr_attr) 4261 { 4262 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4263 4264 if (bfa_ioc_get_type(&fcport->bfa->ioc) != BFA_IOC_TYPE_FC) 4265 return BFA_STATUS_BBCR_FC_ONLY; 4266 4267 if (fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) 4268 return BFA_STATUS_TOPOLOGY_LOOP; 4269 4270 *bbcr_attr = fcport->bbcr_attr; 4271 4272 return BFA_STATUS_OK; 4273 } 4274 4275 void 4276 bfa_fcport_dportenable(struct bfa_s *bfa) 4277 { 4278 /* 4279 * Assume caller check for port is in disable state 4280 */ 4281 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DPORTENABLE); 4282 bfa_port_set_dportenabled(&bfa->modules.port, BFA_TRUE); 4283 } 4284 4285 void 4286 bfa_fcport_dportdisable(struct bfa_s *bfa) 4287 { 4288 /* 4289 * Assume caller check for port is in disable state 4290 */ 4291 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DPORTDISABLE); 4292 bfa_port_set_dportenabled(&bfa->modules.port, BFA_FALSE); 4293 } 4294 4295 void 4296 bfa_fcport_ddportenable(struct bfa_s *bfa) 4297 { 4298 /* 4299 * Assume caller check for port is in disable state 4300 */ 4301 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DDPORTENABLE); 4302 } 4303 4304 void 4305 bfa_fcport_ddportdisable(struct bfa_s *bfa) 4306 { 4307 /* 4308 * Assume caller check for port is in disable state 4309 */ 4310 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DDPORTDISABLE); 4311 } 4312 4313 /* 4314 * Rport State machine functions 4315 */ 4316 /* 4317 * Beginning state, only online event expected. 4318 */ 4319 static void 4320 bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event) 4321 { 4322 bfa_trc(rp->bfa, rp->rport_tag); 4323 bfa_trc(rp->bfa, event); 4324 4325 switch (event) { 4326 case BFA_RPORT_SM_CREATE: 4327 bfa_stats(rp, sm_un_cr); 4328 bfa_sm_set_state(rp, bfa_rport_sm_created); 4329 break; 4330 4331 default: 4332 bfa_stats(rp, sm_un_unexp); 4333 bfa_sm_fault(rp->bfa, event); 4334 } 4335 } 4336 4337 static void 4338 bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event) 4339 { 4340 bfa_trc(rp->bfa, rp->rport_tag); 4341 bfa_trc(rp->bfa, event); 4342 4343 switch (event) { 4344 case BFA_RPORT_SM_ONLINE: 4345 bfa_stats(rp, sm_cr_on); 4346 if (bfa_rport_send_fwcreate(rp)) 4347 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 4348 else 4349 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); 4350 break; 4351 4352 case BFA_RPORT_SM_DELETE: 4353 bfa_stats(rp, sm_cr_del); 4354 bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4355 bfa_rport_free(rp); 4356 break; 4357 4358 case BFA_RPORT_SM_HWFAIL: 4359 bfa_stats(rp, sm_cr_hwf); 4360 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4361 break; 4362 4363 default: 4364 bfa_stats(rp, sm_cr_unexp); 4365 bfa_sm_fault(rp->bfa, event); 4366 } 4367 } 4368 4369 /* 4370 * Waiting for rport create response from firmware. 4371 */ 4372 static void 4373 bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event) 4374 { 4375 bfa_trc(rp->bfa, rp->rport_tag); 4376 bfa_trc(rp->bfa, event); 4377 4378 switch (event) { 4379 case BFA_RPORT_SM_FWRSP: 4380 bfa_stats(rp, sm_fwc_rsp); 4381 bfa_sm_set_state(rp, bfa_rport_sm_online); 4382 bfa_rport_online_cb(rp); 4383 break; 4384 4385 case BFA_RPORT_SM_DELETE: 4386 bfa_stats(rp, sm_fwc_del); 4387 bfa_sm_set_state(rp, bfa_rport_sm_delete_pending); 4388 break; 4389 4390 case BFA_RPORT_SM_OFFLINE: 4391 bfa_stats(rp, sm_fwc_off); 4392 bfa_sm_set_state(rp, bfa_rport_sm_offline_pending); 4393 break; 4394 4395 case BFA_RPORT_SM_HWFAIL: 4396 bfa_stats(rp, sm_fwc_hwf); 4397 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4398 break; 4399 4400 default: 4401 bfa_stats(rp, sm_fwc_unexp); 4402 bfa_sm_fault(rp->bfa, event); 4403 } 4404 } 4405 4406 /* 4407 * Request queue is full, awaiting queue resume to send create request. 4408 */ 4409 static void 4410 bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) 4411 { 4412 bfa_trc(rp->bfa, rp->rport_tag); 4413 bfa_trc(rp->bfa, event); 4414 4415 switch (event) { 4416 case BFA_RPORT_SM_QRESUME: 4417 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 4418 bfa_rport_send_fwcreate(rp); 4419 break; 4420 4421 case BFA_RPORT_SM_DELETE: 4422 bfa_stats(rp, sm_fwc_del); 4423 bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4424 bfa_reqq_wcancel(&rp->reqq_wait); 4425 bfa_rport_free(rp); 4426 break; 4427 4428 case BFA_RPORT_SM_OFFLINE: 4429 bfa_stats(rp, sm_fwc_off); 4430 bfa_sm_set_state(rp, bfa_rport_sm_offline); 4431 bfa_reqq_wcancel(&rp->reqq_wait); 4432 bfa_rport_offline_cb(rp); 4433 break; 4434 4435 case BFA_RPORT_SM_HWFAIL: 4436 bfa_stats(rp, sm_fwc_hwf); 4437 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4438 bfa_reqq_wcancel(&rp->reqq_wait); 4439 break; 4440 4441 default: 4442 bfa_stats(rp, sm_fwc_unexp); 4443 bfa_sm_fault(rp->bfa, event); 4444 } 4445 } 4446 4447 /* 4448 * Online state - normal parking state. 4449 */ 4450 static void 4451 bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event) 4452 { 4453 struct bfi_rport_qos_scn_s *qos_scn; 4454 4455 bfa_trc(rp->bfa, rp->rport_tag); 4456 bfa_trc(rp->bfa, event); 4457 4458 switch (event) { 4459 case BFA_RPORT_SM_OFFLINE: 4460 bfa_stats(rp, sm_on_off); 4461 if (bfa_rport_send_fwdelete(rp)) 4462 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); 4463 else 4464 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull); 4465 break; 4466 4467 case BFA_RPORT_SM_DELETE: 4468 bfa_stats(rp, sm_on_del); 4469 if (bfa_rport_send_fwdelete(rp)) 4470 bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4471 else 4472 bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); 4473 break; 4474 4475 case BFA_RPORT_SM_HWFAIL: 4476 bfa_stats(rp, sm_on_hwf); 4477 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4478 break; 4479 4480 case BFA_RPORT_SM_SET_SPEED: 4481 bfa_rport_send_fwspeed(rp); 4482 break; 4483 4484 case BFA_RPORT_SM_QOS_SCN: 4485 qos_scn = (struct bfi_rport_qos_scn_s *) rp->event_arg.fw_msg; 4486 rp->qos_attr = qos_scn->new_qos_attr; 4487 bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_flow_id); 4488 bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_flow_id); 4489 bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_priority); 4490 bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_priority); 4491 4492 qos_scn->old_qos_attr.qos_flow_id = 4493 be32_to_cpu(qos_scn->old_qos_attr.qos_flow_id); 4494 qos_scn->new_qos_attr.qos_flow_id = 4495 be32_to_cpu(qos_scn->new_qos_attr.qos_flow_id); 4496 4497 if (qos_scn->old_qos_attr.qos_flow_id != 4498 qos_scn->new_qos_attr.qos_flow_id) 4499 bfa_cb_rport_qos_scn_flowid(rp->rport_drv, 4500 qos_scn->old_qos_attr, 4501 qos_scn->new_qos_attr); 4502 if (qos_scn->old_qos_attr.qos_priority != 4503 qos_scn->new_qos_attr.qos_priority) 4504 bfa_cb_rport_qos_scn_prio(rp->rport_drv, 4505 qos_scn->old_qos_attr, 4506 qos_scn->new_qos_attr); 4507 break; 4508 4509 default: 4510 bfa_stats(rp, sm_on_unexp); 4511 bfa_sm_fault(rp->bfa, event); 4512 } 4513 } 4514 4515 /* 4516 * Firmware rport is being deleted - awaiting f/w response. 4517 */ 4518 static void 4519 bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event) 4520 { 4521 bfa_trc(rp->bfa, rp->rport_tag); 4522 bfa_trc(rp->bfa, event); 4523 4524 switch (event) { 4525 case BFA_RPORT_SM_FWRSP: 4526 bfa_stats(rp, sm_fwd_rsp); 4527 bfa_sm_set_state(rp, bfa_rport_sm_offline); 4528 bfa_rport_offline_cb(rp); 4529 break; 4530 4531 case BFA_RPORT_SM_DELETE: 4532 bfa_stats(rp, sm_fwd_del); 4533 bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4534 break; 4535 4536 case BFA_RPORT_SM_HWFAIL: 4537 bfa_stats(rp, sm_fwd_hwf); 4538 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4539 bfa_rport_offline_cb(rp); 4540 break; 4541 4542 default: 4543 bfa_stats(rp, sm_fwd_unexp); 4544 bfa_sm_fault(rp->bfa, event); 4545 } 4546 } 4547 4548 static void 4549 bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) 4550 { 4551 bfa_trc(rp->bfa, rp->rport_tag); 4552 bfa_trc(rp->bfa, event); 4553 4554 switch (event) { 4555 case BFA_RPORT_SM_QRESUME: 4556 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); 4557 bfa_rport_send_fwdelete(rp); 4558 break; 4559 4560 case BFA_RPORT_SM_DELETE: 4561 bfa_stats(rp, sm_fwd_del); 4562 bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); 4563 break; 4564 4565 case BFA_RPORT_SM_HWFAIL: 4566 bfa_stats(rp, sm_fwd_hwf); 4567 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4568 bfa_reqq_wcancel(&rp->reqq_wait); 4569 bfa_rport_offline_cb(rp); 4570 break; 4571 4572 default: 4573 bfa_stats(rp, sm_fwd_unexp); 4574 bfa_sm_fault(rp->bfa, event); 4575 } 4576 } 4577 4578 /* 4579 * Offline state. 4580 */ 4581 static void 4582 bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event) 4583 { 4584 bfa_trc(rp->bfa, rp->rport_tag); 4585 bfa_trc(rp->bfa, event); 4586 4587 switch (event) { 4588 case BFA_RPORT_SM_DELETE: 4589 bfa_stats(rp, sm_off_del); 4590 bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4591 bfa_rport_free(rp); 4592 break; 4593 4594 case BFA_RPORT_SM_ONLINE: 4595 bfa_stats(rp, sm_off_on); 4596 if (bfa_rport_send_fwcreate(rp)) 4597 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 4598 else 4599 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); 4600 break; 4601 4602 case BFA_RPORT_SM_HWFAIL: 4603 bfa_stats(rp, sm_off_hwf); 4604 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4605 break; 4606 4607 case BFA_RPORT_SM_OFFLINE: 4608 bfa_rport_offline_cb(rp); 4609 break; 4610 4611 default: 4612 bfa_stats(rp, sm_off_unexp); 4613 bfa_sm_fault(rp->bfa, event); 4614 } 4615 } 4616 4617 /* 4618 * Rport is deleted, waiting for firmware response to delete. 4619 */ 4620 static void 4621 bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event) 4622 { 4623 bfa_trc(rp->bfa, rp->rport_tag); 4624 bfa_trc(rp->bfa, event); 4625 4626 switch (event) { 4627 case BFA_RPORT_SM_FWRSP: 4628 bfa_stats(rp, sm_del_fwrsp); 4629 bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4630 bfa_rport_free(rp); 4631 break; 4632 4633 case BFA_RPORT_SM_HWFAIL: 4634 bfa_stats(rp, sm_del_hwf); 4635 bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4636 bfa_rport_free(rp); 4637 break; 4638 4639 default: 4640 bfa_sm_fault(rp->bfa, event); 4641 } 4642 } 4643 4644 static void 4645 bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) 4646 { 4647 bfa_trc(rp->bfa, rp->rport_tag); 4648 bfa_trc(rp->bfa, event); 4649 4650 switch (event) { 4651 case BFA_RPORT_SM_QRESUME: 4652 bfa_stats(rp, sm_del_fwrsp); 4653 bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4654 bfa_rport_send_fwdelete(rp); 4655 break; 4656 4657 case BFA_RPORT_SM_HWFAIL: 4658 bfa_stats(rp, sm_del_hwf); 4659 bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4660 bfa_reqq_wcancel(&rp->reqq_wait); 4661 bfa_rport_free(rp); 4662 break; 4663 4664 default: 4665 bfa_sm_fault(rp->bfa, event); 4666 } 4667 } 4668 4669 /* 4670 * Waiting for rport create response from firmware. A delete is pending. 4671 */ 4672 static void 4673 bfa_rport_sm_delete_pending(struct bfa_rport_s *rp, 4674 enum bfa_rport_event event) 4675 { 4676 bfa_trc(rp->bfa, rp->rport_tag); 4677 bfa_trc(rp->bfa, event); 4678 4679 switch (event) { 4680 case BFA_RPORT_SM_FWRSP: 4681 bfa_stats(rp, sm_delp_fwrsp); 4682 if (bfa_rport_send_fwdelete(rp)) 4683 bfa_sm_set_state(rp, bfa_rport_sm_deleting); 4684 else 4685 bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); 4686 break; 4687 4688 case BFA_RPORT_SM_HWFAIL: 4689 bfa_stats(rp, sm_delp_hwf); 4690 bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4691 bfa_rport_free(rp); 4692 break; 4693 4694 default: 4695 bfa_stats(rp, sm_delp_unexp); 4696 bfa_sm_fault(rp->bfa, event); 4697 } 4698 } 4699 4700 /* 4701 * Waiting for rport create response from firmware. Rport offline is pending. 4702 */ 4703 static void 4704 bfa_rport_sm_offline_pending(struct bfa_rport_s *rp, 4705 enum bfa_rport_event event) 4706 { 4707 bfa_trc(rp->bfa, rp->rport_tag); 4708 bfa_trc(rp->bfa, event); 4709 4710 switch (event) { 4711 case BFA_RPORT_SM_FWRSP: 4712 bfa_stats(rp, sm_offp_fwrsp); 4713 if (bfa_rport_send_fwdelete(rp)) 4714 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); 4715 else 4716 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull); 4717 break; 4718 4719 case BFA_RPORT_SM_DELETE: 4720 bfa_stats(rp, sm_offp_del); 4721 bfa_sm_set_state(rp, bfa_rport_sm_delete_pending); 4722 break; 4723 4724 case BFA_RPORT_SM_HWFAIL: 4725 bfa_stats(rp, sm_offp_hwf); 4726 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4727 bfa_rport_offline_cb(rp); 4728 break; 4729 4730 default: 4731 bfa_stats(rp, sm_offp_unexp); 4732 bfa_sm_fault(rp->bfa, event); 4733 } 4734 } 4735 4736 /* 4737 * IOC h/w failed. 4738 */ 4739 static void 4740 bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event) 4741 { 4742 bfa_trc(rp->bfa, rp->rport_tag); 4743 bfa_trc(rp->bfa, event); 4744 4745 switch (event) { 4746 case BFA_RPORT_SM_OFFLINE: 4747 bfa_stats(rp, sm_iocd_off); 4748 bfa_rport_offline_cb(rp); 4749 break; 4750 4751 case BFA_RPORT_SM_DELETE: 4752 bfa_stats(rp, sm_iocd_del); 4753 bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4754 bfa_rport_free(rp); 4755 break; 4756 4757 case BFA_RPORT_SM_ONLINE: 4758 bfa_stats(rp, sm_iocd_on); 4759 if (bfa_rport_send_fwcreate(rp)) 4760 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); 4761 else 4762 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); 4763 break; 4764 4765 case BFA_RPORT_SM_HWFAIL: 4766 break; 4767 4768 default: 4769 bfa_stats(rp, sm_iocd_unexp); 4770 bfa_sm_fault(rp->bfa, event); 4771 } 4772 } 4773 4774 4775 4776 /* 4777 * bfa_rport_private BFA rport private functions 4778 */ 4779 4780 static void 4781 __bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete) 4782 { 4783 struct bfa_rport_s *rp = cbarg; 4784 4785 if (complete) 4786 bfa_cb_rport_online(rp->rport_drv); 4787 } 4788 4789 static void 4790 __bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete) 4791 { 4792 struct bfa_rport_s *rp = cbarg; 4793 4794 if (complete) 4795 bfa_cb_rport_offline(rp->rport_drv); 4796 } 4797 4798 static void 4799 bfa_rport_qresume(void *cbarg) 4800 { 4801 struct bfa_rport_s *rp = cbarg; 4802 4803 bfa_sm_send_event(rp, BFA_RPORT_SM_QRESUME); 4804 } 4805 4806 void 4807 bfa_rport_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 4808 struct bfa_s *bfa) 4809 { 4810 struct bfa_mem_kva_s *rport_kva = BFA_MEM_RPORT_KVA(bfa); 4811 4812 if (cfg->fwcfg.num_rports < BFA_RPORT_MIN) 4813 cfg->fwcfg.num_rports = BFA_RPORT_MIN; 4814 4815 /* kva memory */ 4816 bfa_mem_kva_setup(minfo, rport_kva, 4817 cfg->fwcfg.num_rports * sizeof(struct bfa_rport_s)); 4818 } 4819 4820 void 4821 bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 4822 struct bfa_pcidev_s *pcidev) 4823 { 4824 struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa); 4825 struct bfa_rport_s *rp; 4826 u16 i; 4827 4828 INIT_LIST_HEAD(&mod->rp_free_q); 4829 INIT_LIST_HEAD(&mod->rp_active_q); 4830 INIT_LIST_HEAD(&mod->rp_unused_q); 4831 4832 rp = (struct bfa_rport_s *) bfa_mem_kva_curp(mod); 4833 mod->rps_list = rp; 4834 mod->num_rports = cfg->fwcfg.num_rports; 4835 4836 WARN_ON(!mod->num_rports || 4837 (mod->num_rports & (mod->num_rports - 1))); 4838 4839 for (i = 0; i < mod->num_rports; i++, rp++) { 4840 memset(rp, 0, sizeof(struct bfa_rport_s)); 4841 rp->bfa = bfa; 4842 rp->rport_tag = i; 4843 bfa_sm_set_state(rp, bfa_rport_sm_uninit); 4844 4845 /* 4846 * - is unused 4847 */ 4848 if (i) 4849 list_add_tail(&rp->qe, &mod->rp_free_q); 4850 4851 bfa_reqq_winit(&rp->reqq_wait, bfa_rport_qresume, rp); 4852 } 4853 4854 /* 4855 * consume memory 4856 */ 4857 bfa_mem_kva_curp(mod) = (u8 *) rp; 4858 } 4859 4860 void 4861 bfa_rport_iocdisable(struct bfa_s *bfa) 4862 { 4863 struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa); 4864 struct bfa_rport_s *rport; 4865 struct list_head *qe, *qen; 4866 4867 /* Enqueue unused rport resources to free_q */ 4868 list_splice_tail_init(&mod->rp_unused_q, &mod->rp_free_q); 4869 4870 list_for_each_safe(qe, qen, &mod->rp_active_q) { 4871 rport = (struct bfa_rport_s *) qe; 4872 bfa_sm_send_event(rport, BFA_RPORT_SM_HWFAIL); 4873 } 4874 } 4875 4876 static struct bfa_rport_s * 4877 bfa_rport_alloc(struct bfa_rport_mod_s *mod) 4878 { 4879 struct bfa_rport_s *rport; 4880 4881 bfa_q_deq(&mod->rp_free_q, &rport); 4882 if (rport) 4883 list_add_tail(&rport->qe, &mod->rp_active_q); 4884 4885 return rport; 4886 } 4887 4888 static void 4889 bfa_rport_free(struct bfa_rport_s *rport) 4890 { 4891 struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(rport->bfa); 4892 4893 WARN_ON(!bfa_q_is_on_q(&mod->rp_active_q, rport)); 4894 list_del(&rport->qe); 4895 list_add_tail(&rport->qe, &mod->rp_free_q); 4896 } 4897 4898 static bfa_boolean_t 4899 bfa_rport_send_fwcreate(struct bfa_rport_s *rp) 4900 { 4901 struct bfi_rport_create_req_s *m; 4902 4903 /* 4904 * check for room in queue to send request now 4905 */ 4906 m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); 4907 if (!m) { 4908 bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait); 4909 return BFA_FALSE; 4910 } 4911 4912 bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_CREATE_REQ, 4913 bfa_fn_lpu(rp->bfa)); 4914 m->bfa_handle = rp->rport_tag; 4915 m->max_frmsz = cpu_to_be16(rp->rport_info.max_frmsz); 4916 m->pid = rp->rport_info.pid; 4917 m->lp_fwtag = bfa_lps_get_fwtag(rp->bfa, (u8)rp->rport_info.lp_tag); 4918 m->local_pid = rp->rport_info.local_pid; 4919 m->fc_class = rp->rport_info.fc_class; 4920 m->vf_en = rp->rport_info.vf_en; 4921 m->vf_id = rp->rport_info.vf_id; 4922 m->cisc = rp->rport_info.cisc; 4923 4924 /* 4925 * queue I/O message to firmware 4926 */ 4927 bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh); 4928 return BFA_TRUE; 4929 } 4930 4931 static bfa_boolean_t 4932 bfa_rport_send_fwdelete(struct bfa_rport_s *rp) 4933 { 4934 struct bfi_rport_delete_req_s *m; 4935 4936 /* 4937 * check for room in queue to send request now 4938 */ 4939 m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); 4940 if (!m) { 4941 bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait); 4942 return BFA_FALSE; 4943 } 4944 4945 bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_DELETE_REQ, 4946 bfa_fn_lpu(rp->bfa)); 4947 m->fw_handle = rp->fw_handle; 4948 4949 /* 4950 * queue I/O message to firmware 4951 */ 4952 bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh); 4953 return BFA_TRUE; 4954 } 4955 4956 static bfa_boolean_t 4957 bfa_rport_send_fwspeed(struct bfa_rport_s *rp) 4958 { 4959 struct bfa_rport_speed_req_s *m; 4960 4961 /* 4962 * check for room in queue to send request now 4963 */ 4964 m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); 4965 if (!m) { 4966 bfa_trc(rp->bfa, rp->rport_info.speed); 4967 return BFA_FALSE; 4968 } 4969 4970 bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_SET_SPEED_REQ, 4971 bfa_fn_lpu(rp->bfa)); 4972 m->fw_handle = rp->fw_handle; 4973 m->speed = (u8)rp->rport_info.speed; 4974 4975 /* 4976 * queue I/O message to firmware 4977 */ 4978 bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh); 4979 return BFA_TRUE; 4980 } 4981 4982 4983 4984 /* 4985 * bfa_rport_public 4986 */ 4987 4988 /* 4989 * Rport interrupt processing. 4990 */ 4991 void 4992 bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 4993 { 4994 union bfi_rport_i2h_msg_u msg; 4995 struct bfa_rport_s *rp; 4996 4997 bfa_trc(bfa, m->mhdr.msg_id); 4998 4999 msg.msg = m; 5000 5001 switch (m->mhdr.msg_id) { 5002 case BFI_RPORT_I2H_CREATE_RSP: 5003 rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle); 5004 rp->fw_handle = msg.create_rsp->fw_handle; 5005 rp->qos_attr = msg.create_rsp->qos_attr; 5006 bfa_rport_set_lunmask(bfa, rp); 5007 WARN_ON(msg.create_rsp->status != BFA_STATUS_OK); 5008 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); 5009 break; 5010 5011 case BFI_RPORT_I2H_DELETE_RSP: 5012 rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle); 5013 WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK); 5014 bfa_rport_unset_lunmask(bfa, rp); 5015 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); 5016 break; 5017 5018 case BFI_RPORT_I2H_QOS_SCN: 5019 rp = BFA_RPORT_FROM_TAG(bfa, msg.qos_scn_evt->bfa_handle); 5020 rp->event_arg.fw_msg = msg.qos_scn_evt; 5021 bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN); 5022 break; 5023 5024 case BFI_RPORT_I2H_LIP_SCN_ONLINE: 5025 bfa_fcport_update_loop_info(BFA_FCPORT_MOD(bfa), 5026 &msg.lip_scn->loop_info); 5027 bfa_cb_rport_scn_online(bfa); 5028 break; 5029 5030 case BFI_RPORT_I2H_LIP_SCN_OFFLINE: 5031 bfa_cb_rport_scn_offline(bfa); 5032 break; 5033 5034 case BFI_RPORT_I2H_NO_DEV: 5035 rp = BFA_RPORT_FROM_TAG(bfa, msg.lip_scn->bfa_handle); 5036 bfa_cb_rport_scn_no_dev(rp->rport_drv); 5037 break; 5038 5039 default: 5040 bfa_trc(bfa, m->mhdr.msg_id); 5041 WARN_ON(1); 5042 } 5043 } 5044 5045 void 5046 bfa_rport_res_recfg(struct bfa_s *bfa, u16 num_rport_fw) 5047 { 5048 struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa); 5049 struct list_head *qe; 5050 int i; 5051 5052 for (i = 0; i < (mod->num_rports - num_rport_fw); i++) { 5053 bfa_q_deq_tail(&mod->rp_free_q, &qe); 5054 list_add_tail(qe, &mod->rp_unused_q); 5055 } 5056 } 5057 5058 /* 5059 * bfa_rport_api 5060 */ 5061 5062 struct bfa_rport_s * 5063 bfa_rport_create(struct bfa_s *bfa, void *rport_drv) 5064 { 5065 struct bfa_rport_s *rp; 5066 5067 rp = bfa_rport_alloc(BFA_RPORT_MOD(bfa)); 5068 5069 if (rp == NULL) 5070 return NULL; 5071 5072 rp->bfa = bfa; 5073 rp->rport_drv = rport_drv; 5074 memset(&rp->stats, 0, sizeof(rp->stats)); 5075 5076 WARN_ON(!bfa_sm_cmp_state(rp, bfa_rport_sm_uninit)); 5077 bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE); 5078 5079 return rp; 5080 } 5081 5082 void 5083 bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info) 5084 { 5085 WARN_ON(rport_info->max_frmsz == 0); 5086 5087 /* 5088 * Some JBODs are seen to be not setting PDU size correctly in PLOGI 5089 * responses. Default to minimum size. 5090 */ 5091 if (rport_info->max_frmsz == 0) { 5092 bfa_trc(rport->bfa, rport->rport_tag); 5093 rport_info->max_frmsz = FC_MIN_PDUSZ; 5094 } 5095 5096 rport->rport_info = *rport_info; 5097 bfa_sm_send_event(rport, BFA_RPORT_SM_ONLINE); 5098 } 5099 5100 void 5101 bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed) 5102 { 5103 WARN_ON(speed == 0); 5104 WARN_ON(speed == BFA_PORT_SPEED_AUTO); 5105 5106 if (rport) { 5107 rport->rport_info.speed = speed; 5108 bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED); 5109 } 5110 } 5111 5112 /* Set Rport LUN Mask */ 5113 void 5114 bfa_rport_set_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp) 5115 { 5116 struct bfa_lps_mod_s *lps_mod = BFA_LPS_MOD(bfa); 5117 wwn_t lp_wwn, rp_wwn; 5118 u8 lp_tag = (u8)rp->rport_info.lp_tag; 5119 5120 rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn; 5121 lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn; 5122 5123 BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask = 5124 rp->lun_mask = BFA_TRUE; 5125 bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn, rp->rport_tag, lp_tag); 5126 } 5127 5128 /* Unset Rport LUN mask */ 5129 void 5130 bfa_rport_unset_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp) 5131 { 5132 struct bfa_lps_mod_s *lps_mod = BFA_LPS_MOD(bfa); 5133 wwn_t lp_wwn, rp_wwn; 5134 5135 rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn; 5136 lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn; 5137 5138 BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask = 5139 rp->lun_mask = BFA_FALSE; 5140 bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn, 5141 BFA_RPORT_TAG_INVALID, BFA_LP_TAG_INVALID); 5142 } 5143 5144 /* 5145 * SGPG related functions 5146 */ 5147 5148 /* 5149 * Compute and return memory needed by FCP(im) module. 5150 */ 5151 void 5152 bfa_sgpg_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 5153 struct bfa_s *bfa) 5154 { 5155 struct bfa_sgpg_mod_s *sgpg_mod = BFA_SGPG_MOD(bfa); 5156 struct bfa_mem_kva_s *sgpg_kva = BFA_MEM_SGPG_KVA(bfa); 5157 struct bfa_mem_dma_s *seg_ptr; 5158 u16 nsegs, idx, per_seg_sgpg, num_sgpg; 5159 u32 sgpg_sz = sizeof(struct bfi_sgpg_s); 5160 5161 if (cfg->drvcfg.num_sgpgs < BFA_SGPG_MIN) 5162 cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN; 5163 else if (cfg->drvcfg.num_sgpgs > BFA_SGPG_MAX) 5164 cfg->drvcfg.num_sgpgs = BFA_SGPG_MAX; 5165 5166 num_sgpg = cfg->drvcfg.num_sgpgs; 5167 5168 nsegs = BFI_MEM_DMA_NSEGS(num_sgpg, sgpg_sz); 5169 per_seg_sgpg = BFI_MEM_NREQS_SEG(sgpg_sz); 5170 5171 bfa_mem_dma_seg_iter(sgpg_mod, seg_ptr, nsegs, idx) { 5172 if (num_sgpg >= per_seg_sgpg) { 5173 num_sgpg -= per_seg_sgpg; 5174 bfa_mem_dma_setup(minfo, seg_ptr, 5175 per_seg_sgpg * sgpg_sz); 5176 } else 5177 bfa_mem_dma_setup(minfo, seg_ptr, 5178 num_sgpg * sgpg_sz); 5179 } 5180 5181 /* kva memory */ 5182 bfa_mem_kva_setup(minfo, sgpg_kva, 5183 cfg->drvcfg.num_sgpgs * sizeof(struct bfa_sgpg_s)); 5184 } 5185 5186 void 5187 bfa_sgpg_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 5188 struct bfa_pcidev_s *pcidev) 5189 { 5190 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 5191 struct bfa_sgpg_s *hsgpg; 5192 struct bfi_sgpg_s *sgpg; 5193 u64 align_len; 5194 struct bfa_mem_dma_s *seg_ptr; 5195 u32 sgpg_sz = sizeof(struct bfi_sgpg_s); 5196 u16 i, idx, nsegs, per_seg_sgpg, num_sgpg; 5197 5198 union { 5199 u64 pa; 5200 union bfi_addr_u addr; 5201 } sgpg_pa, sgpg_pa_tmp; 5202 5203 INIT_LIST_HEAD(&mod->sgpg_q); 5204 INIT_LIST_HEAD(&mod->sgpg_wait_q); 5205 5206 bfa_trc(bfa, cfg->drvcfg.num_sgpgs); 5207 5208 mod->free_sgpgs = mod->num_sgpgs = cfg->drvcfg.num_sgpgs; 5209 5210 num_sgpg = cfg->drvcfg.num_sgpgs; 5211 nsegs = BFI_MEM_DMA_NSEGS(num_sgpg, sgpg_sz); 5212 5213 /* dma/kva mem claim */ 5214 hsgpg = (struct bfa_sgpg_s *) bfa_mem_kva_curp(mod); 5215 5216 bfa_mem_dma_seg_iter(mod, seg_ptr, nsegs, idx) { 5217 5218 if (!bfa_mem_dma_virt(seg_ptr)) 5219 break; 5220 5221 align_len = BFA_SGPG_ROUNDUP(bfa_mem_dma_phys(seg_ptr)) - 5222 bfa_mem_dma_phys(seg_ptr); 5223 5224 sgpg = (struct bfi_sgpg_s *) 5225 (((u8 *) bfa_mem_dma_virt(seg_ptr)) + align_len); 5226 sgpg_pa.pa = bfa_mem_dma_phys(seg_ptr) + align_len; 5227 WARN_ON(sgpg_pa.pa & (sgpg_sz - 1)); 5228 5229 per_seg_sgpg = (seg_ptr->mem_len - (u32)align_len) / sgpg_sz; 5230 5231 for (i = 0; num_sgpg > 0 && i < per_seg_sgpg; i++, num_sgpg--) { 5232 memset(hsgpg, 0, sizeof(*hsgpg)); 5233 memset(sgpg, 0, sizeof(*sgpg)); 5234 5235 hsgpg->sgpg = sgpg; 5236 sgpg_pa_tmp.pa = bfa_sgaddr_le(sgpg_pa.pa); 5237 hsgpg->sgpg_pa = sgpg_pa_tmp.addr; 5238 list_add_tail(&hsgpg->qe, &mod->sgpg_q); 5239 5240 sgpg++; 5241 hsgpg++; 5242 sgpg_pa.pa += sgpg_sz; 5243 } 5244 } 5245 5246 bfa_mem_kva_curp(mod) = (u8 *) hsgpg; 5247 } 5248 5249 bfa_status_t 5250 bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpgs) 5251 { 5252 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 5253 struct bfa_sgpg_s *hsgpg; 5254 int i; 5255 5256 if (mod->free_sgpgs < nsgpgs) 5257 return BFA_STATUS_ENOMEM; 5258 5259 for (i = 0; i < nsgpgs; i++) { 5260 bfa_q_deq(&mod->sgpg_q, &hsgpg); 5261 WARN_ON(!hsgpg); 5262 list_add_tail(&hsgpg->qe, sgpg_q); 5263 } 5264 5265 mod->free_sgpgs -= nsgpgs; 5266 return BFA_STATUS_OK; 5267 } 5268 5269 void 5270 bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpg) 5271 { 5272 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 5273 struct bfa_sgpg_wqe_s *wqe; 5274 5275 mod->free_sgpgs += nsgpg; 5276 WARN_ON(mod->free_sgpgs > mod->num_sgpgs); 5277 5278 list_splice_tail_init(sgpg_q, &mod->sgpg_q); 5279 5280 if (list_empty(&mod->sgpg_wait_q)) 5281 return; 5282 5283 /* 5284 * satisfy as many waiting requests as possible 5285 */ 5286 do { 5287 wqe = bfa_q_first(&mod->sgpg_wait_q); 5288 if (mod->free_sgpgs < wqe->nsgpg) 5289 nsgpg = mod->free_sgpgs; 5290 else 5291 nsgpg = wqe->nsgpg; 5292 bfa_sgpg_malloc(bfa, &wqe->sgpg_q, nsgpg); 5293 wqe->nsgpg -= nsgpg; 5294 if (wqe->nsgpg == 0) { 5295 list_del(&wqe->qe); 5296 wqe->cbfn(wqe->cbarg); 5297 } 5298 } while (mod->free_sgpgs && !list_empty(&mod->sgpg_wait_q)); 5299 } 5300 5301 void 5302 bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, int nsgpg) 5303 { 5304 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 5305 5306 WARN_ON(nsgpg <= 0); 5307 WARN_ON(nsgpg <= mod->free_sgpgs); 5308 5309 wqe->nsgpg_total = wqe->nsgpg = nsgpg; 5310 5311 /* 5312 * allocate any left to this one first 5313 */ 5314 if (mod->free_sgpgs) { 5315 /* 5316 * no one else is waiting for SGPG 5317 */ 5318 WARN_ON(!list_empty(&mod->sgpg_wait_q)); 5319 list_splice_tail_init(&mod->sgpg_q, &wqe->sgpg_q); 5320 wqe->nsgpg -= mod->free_sgpgs; 5321 mod->free_sgpgs = 0; 5322 } 5323 5324 list_add_tail(&wqe->qe, &mod->sgpg_wait_q); 5325 } 5326 5327 void 5328 bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe) 5329 { 5330 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); 5331 5332 WARN_ON(!bfa_q_is_on_q(&mod->sgpg_wait_q, wqe)); 5333 list_del(&wqe->qe); 5334 5335 if (wqe->nsgpg_total != wqe->nsgpg) 5336 bfa_sgpg_mfree(bfa, &wqe->sgpg_q, 5337 wqe->nsgpg_total - wqe->nsgpg); 5338 } 5339 5340 void 5341 bfa_sgpg_winit(struct bfa_sgpg_wqe_s *wqe, void (*cbfn) (void *cbarg), 5342 void *cbarg) 5343 { 5344 INIT_LIST_HEAD(&wqe->sgpg_q); 5345 wqe->cbfn = cbfn; 5346 wqe->cbarg = cbarg; 5347 } 5348 5349 /* 5350 * UF related functions 5351 */ 5352 /* 5353 ***************************************************************************** 5354 * Internal functions 5355 ***************************************************************************** 5356 */ 5357 static void 5358 __bfa_cb_uf_recv(void *cbarg, bfa_boolean_t complete) 5359 { 5360 struct bfa_uf_s *uf = cbarg; 5361 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(uf->bfa); 5362 5363 if (complete) 5364 ufm->ufrecv(ufm->cbarg, uf); 5365 } 5366 5367 static void 5368 claim_uf_post_msgs(struct bfa_uf_mod_s *ufm) 5369 { 5370 struct bfi_uf_buf_post_s *uf_bp_msg; 5371 u16 i; 5372 u16 buf_len; 5373 5374 ufm->uf_buf_posts = (struct bfi_uf_buf_post_s *) bfa_mem_kva_curp(ufm); 5375 uf_bp_msg = ufm->uf_buf_posts; 5376 5377 for (i = 0, uf_bp_msg = ufm->uf_buf_posts; i < ufm->num_ufs; 5378 i++, uf_bp_msg++) { 5379 memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s)); 5380 5381 uf_bp_msg->buf_tag = i; 5382 buf_len = sizeof(struct bfa_uf_buf_s); 5383 uf_bp_msg->buf_len = cpu_to_be16(buf_len); 5384 bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST, 5385 bfa_fn_lpu(ufm->bfa)); 5386 bfa_alen_set(&uf_bp_msg->alen, buf_len, ufm_pbs_pa(ufm, i)); 5387 } 5388 5389 /* 5390 * advance pointer beyond consumed memory 5391 */ 5392 bfa_mem_kva_curp(ufm) = (u8 *) uf_bp_msg; 5393 } 5394 5395 static void 5396 claim_ufs(struct bfa_uf_mod_s *ufm) 5397 { 5398 u16 i; 5399 struct bfa_uf_s *uf; 5400 5401 /* 5402 * Claim block of memory for UF list 5403 */ 5404 ufm->uf_list = (struct bfa_uf_s *) bfa_mem_kva_curp(ufm); 5405 5406 /* 5407 * Initialize UFs and queue it in UF free queue 5408 */ 5409 for (i = 0, uf = ufm->uf_list; i < ufm->num_ufs; i++, uf++) { 5410 memset(uf, 0, sizeof(struct bfa_uf_s)); 5411 uf->bfa = ufm->bfa; 5412 uf->uf_tag = i; 5413 uf->pb_len = BFA_PER_UF_DMA_SZ; 5414 uf->buf_kva = bfa_mem_get_dmabuf_kva(ufm, i, BFA_PER_UF_DMA_SZ); 5415 uf->buf_pa = ufm_pbs_pa(ufm, i); 5416 list_add_tail(&uf->qe, &ufm->uf_free_q); 5417 } 5418 5419 /* 5420 * advance memory pointer 5421 */ 5422 bfa_mem_kva_curp(ufm) = (u8 *) uf; 5423 } 5424 5425 static void 5426 uf_mem_claim(struct bfa_uf_mod_s *ufm) 5427 { 5428 claim_ufs(ufm); 5429 claim_uf_post_msgs(ufm); 5430 } 5431 5432 void 5433 bfa_uf_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 5434 struct bfa_s *bfa) 5435 { 5436 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5437 struct bfa_mem_kva_s *uf_kva = BFA_MEM_UF_KVA(bfa); 5438 u32 num_ufs = cfg->fwcfg.num_uf_bufs; 5439 struct bfa_mem_dma_s *seg_ptr; 5440 u16 nsegs, idx, per_seg_uf = 0; 5441 5442 nsegs = BFI_MEM_DMA_NSEGS(num_ufs, BFA_PER_UF_DMA_SZ); 5443 per_seg_uf = BFI_MEM_NREQS_SEG(BFA_PER_UF_DMA_SZ); 5444 5445 bfa_mem_dma_seg_iter(ufm, seg_ptr, nsegs, idx) { 5446 if (num_ufs >= per_seg_uf) { 5447 num_ufs -= per_seg_uf; 5448 bfa_mem_dma_setup(minfo, seg_ptr, 5449 per_seg_uf * BFA_PER_UF_DMA_SZ); 5450 } else 5451 bfa_mem_dma_setup(minfo, seg_ptr, 5452 num_ufs * BFA_PER_UF_DMA_SZ); 5453 } 5454 5455 /* kva memory */ 5456 bfa_mem_kva_setup(minfo, uf_kva, cfg->fwcfg.num_uf_bufs * 5457 (sizeof(struct bfa_uf_s) + sizeof(struct bfi_uf_buf_post_s))); 5458 } 5459 5460 void 5461 bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 5462 struct bfa_pcidev_s *pcidev) 5463 { 5464 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5465 5466 ufm->bfa = bfa; 5467 ufm->num_ufs = cfg->fwcfg.num_uf_bufs; 5468 INIT_LIST_HEAD(&ufm->uf_free_q); 5469 INIT_LIST_HEAD(&ufm->uf_posted_q); 5470 INIT_LIST_HEAD(&ufm->uf_unused_q); 5471 5472 uf_mem_claim(ufm); 5473 } 5474 5475 static struct bfa_uf_s * 5476 bfa_uf_get(struct bfa_uf_mod_s *uf_mod) 5477 { 5478 struct bfa_uf_s *uf; 5479 5480 bfa_q_deq(&uf_mod->uf_free_q, &uf); 5481 return uf; 5482 } 5483 5484 static void 5485 bfa_uf_put(struct bfa_uf_mod_s *uf_mod, struct bfa_uf_s *uf) 5486 { 5487 list_add_tail(&uf->qe, &uf_mod->uf_free_q); 5488 } 5489 5490 static bfa_status_t 5491 bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf) 5492 { 5493 struct bfi_uf_buf_post_s *uf_post_msg; 5494 5495 uf_post_msg = bfa_reqq_next(ufm->bfa, BFA_REQQ_FCXP); 5496 if (!uf_post_msg) 5497 return BFA_STATUS_FAILED; 5498 5499 memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag], 5500 sizeof(struct bfi_uf_buf_post_s)); 5501 bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP, uf_post_msg->mh); 5502 5503 bfa_trc(ufm->bfa, uf->uf_tag); 5504 5505 list_add_tail(&uf->qe, &ufm->uf_posted_q); 5506 return BFA_STATUS_OK; 5507 } 5508 5509 static void 5510 bfa_uf_post_all(struct bfa_uf_mod_s *uf_mod) 5511 { 5512 struct bfa_uf_s *uf; 5513 5514 while ((uf = bfa_uf_get(uf_mod)) != NULL) { 5515 if (bfa_uf_post(uf_mod, uf) != BFA_STATUS_OK) 5516 break; 5517 } 5518 } 5519 5520 static void 5521 uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m) 5522 { 5523 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5524 u16 uf_tag = m->buf_tag; 5525 struct bfa_uf_s *uf = &ufm->uf_list[uf_tag]; 5526 struct bfa_uf_buf_s *uf_buf; 5527 uint8_t *buf; 5528 struct fchs_s *fchs; 5529 5530 uf_buf = (struct bfa_uf_buf_s *) 5531 bfa_mem_get_dmabuf_kva(ufm, uf_tag, uf->pb_len); 5532 buf = &uf_buf->d[0]; 5533 5534 m->frm_len = be16_to_cpu(m->frm_len); 5535 m->xfr_len = be16_to_cpu(m->xfr_len); 5536 5537 fchs = (struct fchs_s *)uf_buf; 5538 5539 list_del(&uf->qe); /* dequeue from posted queue */ 5540 5541 uf->data_ptr = buf; 5542 uf->data_len = m->xfr_len; 5543 5544 WARN_ON(uf->data_len < sizeof(struct fchs_s)); 5545 5546 if (uf->data_len == sizeof(struct fchs_s)) { 5547 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_UF, BFA_PL_EID_RX, 5548 uf->data_len, (struct fchs_s *)buf); 5549 } else { 5550 u32 pld_w0 = *((u32 *) (buf + sizeof(struct fchs_s))); 5551 bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_UF, 5552 BFA_PL_EID_RX, uf->data_len, 5553 (struct fchs_s *)buf, pld_w0); 5554 } 5555 5556 if (bfa->fcs) 5557 __bfa_cb_uf_recv(uf, BFA_TRUE); 5558 else 5559 bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf); 5560 } 5561 5562 void 5563 bfa_uf_iocdisable(struct bfa_s *bfa) 5564 { 5565 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5566 struct bfa_uf_s *uf; 5567 struct list_head *qe, *qen; 5568 5569 /* Enqueue unused uf resources to free_q */ 5570 list_splice_tail_init(&ufm->uf_unused_q, &ufm->uf_free_q); 5571 5572 list_for_each_safe(qe, qen, &ufm->uf_posted_q) { 5573 uf = (struct bfa_uf_s *) qe; 5574 list_del(&uf->qe); 5575 bfa_uf_put(ufm, uf); 5576 } 5577 } 5578 5579 void 5580 bfa_uf_start(struct bfa_s *bfa) 5581 { 5582 bfa_uf_post_all(BFA_UF_MOD(bfa)); 5583 } 5584 5585 /* 5586 * Register handler for all unsolicted receive frames. 5587 * 5588 * @param[in] bfa BFA instance 5589 * @param[in] ufrecv receive handler function 5590 * @param[in] cbarg receive handler arg 5591 */ 5592 void 5593 bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, void *cbarg) 5594 { 5595 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); 5596 5597 ufm->ufrecv = ufrecv; 5598 ufm->cbarg = cbarg; 5599 } 5600 5601 /* 5602 * Free an unsolicited frame back to BFA. 5603 * 5604 * @param[in] uf unsolicited frame to be freed 5605 * 5606 * @return None 5607 */ 5608 void 5609 bfa_uf_free(struct bfa_uf_s *uf) 5610 { 5611 bfa_uf_put(BFA_UF_MOD(uf->bfa), uf); 5612 bfa_uf_post_all(BFA_UF_MOD(uf->bfa)); 5613 } 5614 5615 5616 5617 /* 5618 * uf_pub BFA uf module public functions 5619 */ 5620 void 5621 bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) 5622 { 5623 bfa_trc(bfa, msg->mhdr.msg_id); 5624 5625 switch (msg->mhdr.msg_id) { 5626 case BFI_UF_I2H_FRM_RCVD: 5627 uf_recv(bfa, (struct bfi_uf_frm_rcvd_s *) msg); 5628 break; 5629 5630 default: 5631 bfa_trc(bfa, msg->mhdr.msg_id); 5632 WARN_ON(1); 5633 } 5634 } 5635 5636 void 5637 bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw) 5638 { 5639 struct bfa_uf_mod_s *mod = BFA_UF_MOD(bfa); 5640 struct list_head *qe; 5641 int i; 5642 5643 for (i = 0; i < (mod->num_ufs - num_uf_fw); i++) { 5644 bfa_q_deq_tail(&mod->uf_free_q, &qe); 5645 list_add_tail(qe, &mod->uf_unused_q); 5646 } 5647 } 5648 5649 /* 5650 * Dport forward declaration 5651 */ 5652 5653 enum bfa_dport_test_state_e { 5654 BFA_DPORT_ST_DISABLED = 0, /*!< dport is disabled */ 5655 BFA_DPORT_ST_INP = 1, /*!< test in progress */ 5656 BFA_DPORT_ST_COMP = 2, /*!< test complete successfully */ 5657 BFA_DPORT_ST_NO_SFP = 3, /*!< sfp is not present */ 5658 BFA_DPORT_ST_NOTSTART = 4, /*!< test not start dport is enabled */ 5659 }; 5660 5661 /* 5662 * BFA DPORT state machine events 5663 */ 5664 enum bfa_dport_sm_event { 5665 BFA_DPORT_SM_ENABLE = 1, /* dport enable event */ 5666 BFA_DPORT_SM_DISABLE = 2, /* dport disable event */ 5667 BFA_DPORT_SM_FWRSP = 3, /* fw enable/disable rsp */ 5668 BFA_DPORT_SM_QRESUME = 4, /* CQ space available */ 5669 BFA_DPORT_SM_HWFAIL = 5, /* IOC h/w failure */ 5670 BFA_DPORT_SM_START = 6, /* re-start dport test */ 5671 BFA_DPORT_SM_REQFAIL = 7, /* request failure */ 5672 BFA_DPORT_SM_SCN = 8, /* state change notify frm fw */ 5673 }; 5674 5675 static void bfa_dport_sm_disabled(struct bfa_dport_s *dport, 5676 enum bfa_dport_sm_event event); 5677 static void bfa_dport_sm_enabling_qwait(struct bfa_dport_s *dport, 5678 enum bfa_dport_sm_event event); 5679 static void bfa_dport_sm_enabling(struct bfa_dport_s *dport, 5680 enum bfa_dport_sm_event event); 5681 static void bfa_dport_sm_enabled(struct bfa_dport_s *dport, 5682 enum bfa_dport_sm_event event); 5683 static void bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport, 5684 enum bfa_dport_sm_event event); 5685 static void bfa_dport_sm_disabling(struct bfa_dport_s *dport, 5686 enum bfa_dport_sm_event event); 5687 static void bfa_dport_sm_starting_qwait(struct bfa_dport_s *dport, 5688 enum bfa_dport_sm_event event); 5689 static void bfa_dport_sm_starting(struct bfa_dport_s *dport, 5690 enum bfa_dport_sm_event event); 5691 static void bfa_dport_sm_dynamic_disabling(struct bfa_dport_s *dport, 5692 enum bfa_dport_sm_event event); 5693 static void bfa_dport_sm_dynamic_disabling_qwait(struct bfa_dport_s *dport, 5694 enum bfa_dport_sm_event event); 5695 static void bfa_dport_qresume(void *cbarg); 5696 static void bfa_dport_req_comp(struct bfa_dport_s *dport, 5697 struct bfi_diag_dport_rsp_s *msg); 5698 static void bfa_dport_scn(struct bfa_dport_s *dport, 5699 struct bfi_diag_dport_scn_s *msg); 5700 5701 /* 5702 * BFA fcdiag module 5703 */ 5704 #define BFA_DIAG_QTEST_TOV 1000 /* msec */ 5705 5706 /* 5707 * Set port status to busy 5708 */ 5709 static void 5710 bfa_fcdiag_set_busy_status(struct bfa_fcdiag_s *fcdiag) 5711 { 5712 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(fcdiag->bfa); 5713 5714 if (fcdiag->lb.lock) 5715 fcport->diag_busy = BFA_TRUE; 5716 else 5717 fcport->diag_busy = BFA_FALSE; 5718 } 5719 5720 void 5721 bfa_fcdiag_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 5722 struct bfa_pcidev_s *pcidev) 5723 { 5724 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 5725 struct bfa_dport_s *dport = &fcdiag->dport; 5726 5727 fcdiag->bfa = bfa; 5728 fcdiag->trcmod = bfa->trcmod; 5729 /* The common DIAG attach bfa_diag_attach() will do all memory claim */ 5730 dport->bfa = bfa; 5731 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 5732 bfa_reqq_winit(&dport->reqq_wait, bfa_dport_qresume, dport); 5733 dport->cbfn = NULL; 5734 dport->cbarg = NULL; 5735 dport->test_state = BFA_DPORT_ST_DISABLED; 5736 memset(&dport->result, 0, sizeof(struct bfa_diag_dport_result_s)); 5737 } 5738 5739 void 5740 bfa_fcdiag_iocdisable(struct bfa_s *bfa) 5741 { 5742 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 5743 struct bfa_dport_s *dport = &fcdiag->dport; 5744 5745 bfa_trc(fcdiag, fcdiag->lb.lock); 5746 if (fcdiag->lb.lock) { 5747 fcdiag->lb.status = BFA_STATUS_IOC_FAILURE; 5748 fcdiag->lb.cbfn(fcdiag->lb.cbarg, fcdiag->lb.status); 5749 fcdiag->lb.lock = 0; 5750 bfa_fcdiag_set_busy_status(fcdiag); 5751 } 5752 5753 bfa_sm_send_event(dport, BFA_DPORT_SM_HWFAIL); 5754 } 5755 5756 static void 5757 bfa_fcdiag_queuetest_timeout(void *cbarg) 5758 { 5759 struct bfa_fcdiag_s *fcdiag = cbarg; 5760 struct bfa_diag_qtest_result_s *res = fcdiag->qtest.result; 5761 5762 bfa_trc(fcdiag, fcdiag->qtest.all); 5763 bfa_trc(fcdiag, fcdiag->qtest.count); 5764 5765 fcdiag->qtest.timer_active = 0; 5766 5767 res->status = BFA_STATUS_ETIMER; 5768 res->count = QTEST_CNT_DEFAULT - fcdiag->qtest.count; 5769 if (fcdiag->qtest.all) 5770 res->queue = fcdiag->qtest.all; 5771 5772 bfa_trc(fcdiag, BFA_STATUS_ETIMER); 5773 fcdiag->qtest.status = BFA_STATUS_ETIMER; 5774 fcdiag->qtest.cbfn(fcdiag->qtest.cbarg, fcdiag->qtest.status); 5775 fcdiag->qtest.lock = 0; 5776 } 5777 5778 static bfa_status_t 5779 bfa_fcdiag_queuetest_send(struct bfa_fcdiag_s *fcdiag) 5780 { 5781 u32 i; 5782 struct bfi_diag_qtest_req_s *req; 5783 5784 req = bfa_reqq_next(fcdiag->bfa, fcdiag->qtest.queue); 5785 if (!req) 5786 return BFA_STATUS_DEVBUSY; 5787 5788 /* build host command */ 5789 bfi_h2i_set(req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_QTEST, 5790 bfa_fn_lpu(fcdiag->bfa)); 5791 5792 for (i = 0; i < BFI_LMSG_PL_WSZ; i++) 5793 req->data[i] = QTEST_PAT_DEFAULT; 5794 5795 bfa_trc(fcdiag, fcdiag->qtest.queue); 5796 /* ring door bell */ 5797 bfa_reqq_produce(fcdiag->bfa, fcdiag->qtest.queue, req->mh); 5798 return BFA_STATUS_OK; 5799 } 5800 5801 static void 5802 bfa_fcdiag_queuetest_comp(struct bfa_fcdiag_s *fcdiag, 5803 bfi_diag_qtest_rsp_t *rsp) 5804 { 5805 struct bfa_diag_qtest_result_s *res = fcdiag->qtest.result; 5806 bfa_status_t status = BFA_STATUS_OK; 5807 int i; 5808 5809 /* Check timer, should still be active */ 5810 if (!fcdiag->qtest.timer_active) { 5811 bfa_trc(fcdiag, fcdiag->qtest.timer_active); 5812 return; 5813 } 5814 5815 /* update count */ 5816 fcdiag->qtest.count--; 5817 5818 /* Check result */ 5819 for (i = 0; i < BFI_LMSG_PL_WSZ; i++) { 5820 if (rsp->data[i] != ~(QTEST_PAT_DEFAULT)) { 5821 res->status = BFA_STATUS_DATACORRUPTED; 5822 break; 5823 } 5824 } 5825 5826 if (res->status == BFA_STATUS_OK) { 5827 if (fcdiag->qtest.count > 0) { 5828 status = bfa_fcdiag_queuetest_send(fcdiag); 5829 if (status == BFA_STATUS_OK) 5830 return; 5831 else 5832 res->status = status; 5833 } else if (fcdiag->qtest.all > 0 && 5834 fcdiag->qtest.queue < (BFI_IOC_MAX_CQS - 1)) { 5835 fcdiag->qtest.count = QTEST_CNT_DEFAULT; 5836 fcdiag->qtest.queue++; 5837 status = bfa_fcdiag_queuetest_send(fcdiag); 5838 if (status == BFA_STATUS_OK) 5839 return; 5840 else 5841 res->status = status; 5842 } 5843 } 5844 5845 /* Stop timer when we comp all queue */ 5846 if (fcdiag->qtest.timer_active) { 5847 bfa_timer_stop(&fcdiag->qtest.timer); 5848 fcdiag->qtest.timer_active = 0; 5849 } 5850 res->queue = fcdiag->qtest.queue; 5851 res->count = QTEST_CNT_DEFAULT - fcdiag->qtest.count; 5852 bfa_trc(fcdiag, res->count); 5853 bfa_trc(fcdiag, res->status); 5854 fcdiag->qtest.status = res->status; 5855 fcdiag->qtest.cbfn(fcdiag->qtest.cbarg, fcdiag->qtest.status); 5856 fcdiag->qtest.lock = 0; 5857 } 5858 5859 static void 5860 bfa_fcdiag_loopback_comp(struct bfa_fcdiag_s *fcdiag, 5861 struct bfi_diag_lb_rsp_s *rsp) 5862 { 5863 struct bfa_diag_loopback_result_s *res = fcdiag->lb.result; 5864 5865 res->numtxmfrm = be32_to_cpu(rsp->res.numtxmfrm); 5866 res->numosffrm = be32_to_cpu(rsp->res.numosffrm); 5867 res->numrcvfrm = be32_to_cpu(rsp->res.numrcvfrm); 5868 res->badfrminf = be32_to_cpu(rsp->res.badfrminf); 5869 res->badfrmnum = be32_to_cpu(rsp->res.badfrmnum); 5870 res->status = rsp->res.status; 5871 fcdiag->lb.status = rsp->res.status; 5872 bfa_trc(fcdiag, fcdiag->lb.status); 5873 fcdiag->lb.cbfn(fcdiag->lb.cbarg, fcdiag->lb.status); 5874 fcdiag->lb.lock = 0; 5875 bfa_fcdiag_set_busy_status(fcdiag); 5876 } 5877 5878 static bfa_status_t 5879 bfa_fcdiag_loopback_send(struct bfa_fcdiag_s *fcdiag, 5880 struct bfa_diag_loopback_s *loopback) 5881 { 5882 struct bfi_diag_lb_req_s *lb_req; 5883 5884 lb_req = bfa_reqq_next(fcdiag->bfa, BFA_REQQ_DIAG); 5885 if (!lb_req) 5886 return BFA_STATUS_DEVBUSY; 5887 5888 /* build host command */ 5889 bfi_h2i_set(lb_req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_LOOPBACK, 5890 bfa_fn_lpu(fcdiag->bfa)); 5891 5892 lb_req->lb_mode = loopback->lb_mode; 5893 lb_req->speed = loopback->speed; 5894 lb_req->loopcnt = loopback->loopcnt; 5895 lb_req->pattern = loopback->pattern; 5896 5897 /* ring door bell */ 5898 bfa_reqq_produce(fcdiag->bfa, BFA_REQQ_DIAG, lb_req->mh); 5899 5900 bfa_trc(fcdiag, loopback->lb_mode); 5901 bfa_trc(fcdiag, loopback->speed); 5902 bfa_trc(fcdiag, loopback->loopcnt); 5903 bfa_trc(fcdiag, loopback->pattern); 5904 return BFA_STATUS_OK; 5905 } 5906 5907 /* 5908 * cpe/rme intr handler 5909 */ 5910 void 5911 bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg) 5912 { 5913 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 5914 5915 switch (msg->mhdr.msg_id) { 5916 case BFI_DIAG_I2H_LOOPBACK: 5917 bfa_fcdiag_loopback_comp(fcdiag, 5918 (struct bfi_diag_lb_rsp_s *) msg); 5919 break; 5920 case BFI_DIAG_I2H_QTEST: 5921 bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg); 5922 break; 5923 case BFI_DIAG_I2H_DPORT: 5924 bfa_dport_req_comp(&fcdiag->dport, 5925 (struct bfi_diag_dport_rsp_s *)msg); 5926 break; 5927 case BFI_DIAG_I2H_DPORT_SCN: 5928 bfa_dport_scn(&fcdiag->dport, 5929 (struct bfi_diag_dport_scn_s *)msg); 5930 break; 5931 default: 5932 bfa_trc(fcdiag, msg->mhdr.msg_id); 5933 WARN_ON(1); 5934 } 5935 } 5936 5937 /* 5938 * Loopback test 5939 * 5940 * @param[in] *bfa - bfa data struct 5941 * @param[in] opmode - port operation mode 5942 * @param[in] speed - port speed 5943 * @param[in] lpcnt - loop count 5944 * @param[in] pat - pattern to build packet 5945 * @param[in] *result - pt to bfa_diag_loopback_result_t data struct 5946 * @param[in] cbfn - callback function 5947 * @param[in] cbarg - callback functioin arg 5948 * 5949 * @param[out] 5950 */ 5951 bfa_status_t 5952 bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode, 5953 enum bfa_port_speed speed, u32 lpcnt, u32 pat, 5954 struct bfa_diag_loopback_result_s *result, bfa_cb_diag_t cbfn, 5955 void *cbarg) 5956 { 5957 struct bfa_diag_loopback_s loopback; 5958 struct bfa_port_attr_s attr; 5959 bfa_status_t status; 5960 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 5961 5962 if (!bfa_iocfc_is_operational(bfa)) 5963 return BFA_STATUS_IOC_NON_OP; 5964 5965 /* if port is PBC disabled, return error */ 5966 if (bfa_fcport_is_pbcdisabled(bfa)) { 5967 bfa_trc(fcdiag, BFA_STATUS_PBC); 5968 return BFA_STATUS_PBC; 5969 } 5970 5971 if (bfa_fcport_is_disabled(bfa) == BFA_FALSE) { 5972 bfa_trc(fcdiag, opmode); 5973 return BFA_STATUS_PORT_NOT_DISABLED; 5974 } 5975 5976 /* 5977 * Check if input speed is supported by the port mode 5978 */ 5979 if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) { 5980 if (!(speed == BFA_PORT_SPEED_1GBPS || 5981 speed == BFA_PORT_SPEED_2GBPS || 5982 speed == BFA_PORT_SPEED_4GBPS || 5983 speed == BFA_PORT_SPEED_8GBPS || 5984 speed == BFA_PORT_SPEED_16GBPS || 5985 speed == BFA_PORT_SPEED_AUTO)) { 5986 bfa_trc(fcdiag, speed); 5987 return BFA_STATUS_UNSUPP_SPEED; 5988 } 5989 bfa_fcport_get_attr(bfa, &attr); 5990 bfa_trc(fcdiag, attr.speed_supported); 5991 if (speed > attr.speed_supported) 5992 return BFA_STATUS_UNSUPP_SPEED; 5993 } else { 5994 if (speed != BFA_PORT_SPEED_10GBPS) { 5995 bfa_trc(fcdiag, speed); 5996 return BFA_STATUS_UNSUPP_SPEED; 5997 } 5998 } 5999 6000 /* 6001 * For CT2, 1G is not supported 6002 */ 6003 if ((speed == BFA_PORT_SPEED_1GBPS) && 6004 (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) { 6005 bfa_trc(fcdiag, speed); 6006 return BFA_STATUS_UNSUPP_SPEED; 6007 } 6008 6009 /* For Mezz card, port speed entered needs to be checked */ 6010 if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) { 6011 if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) { 6012 if (!(speed == BFA_PORT_SPEED_1GBPS || 6013 speed == BFA_PORT_SPEED_2GBPS || 6014 speed == BFA_PORT_SPEED_4GBPS || 6015 speed == BFA_PORT_SPEED_8GBPS || 6016 speed == BFA_PORT_SPEED_16GBPS || 6017 speed == BFA_PORT_SPEED_AUTO)) 6018 return BFA_STATUS_UNSUPP_SPEED; 6019 } else { 6020 if (speed != BFA_PORT_SPEED_10GBPS) 6021 return BFA_STATUS_UNSUPP_SPEED; 6022 } 6023 } 6024 /* check to see if fcport is dport */ 6025 if (bfa_fcport_is_dport(bfa)) { 6026 bfa_trc(fcdiag, fcdiag->lb.lock); 6027 return BFA_STATUS_DPORT_ENABLED; 6028 } 6029 /* check to see if there is another destructive diag cmd running */ 6030 if (fcdiag->lb.lock) { 6031 bfa_trc(fcdiag, fcdiag->lb.lock); 6032 return BFA_STATUS_DEVBUSY; 6033 } 6034 6035 fcdiag->lb.lock = 1; 6036 loopback.lb_mode = opmode; 6037 loopback.speed = speed; 6038 loopback.loopcnt = lpcnt; 6039 loopback.pattern = pat; 6040 fcdiag->lb.result = result; 6041 fcdiag->lb.cbfn = cbfn; 6042 fcdiag->lb.cbarg = cbarg; 6043 memset(result, 0, sizeof(struct bfa_diag_loopback_result_s)); 6044 bfa_fcdiag_set_busy_status(fcdiag); 6045 6046 /* Send msg to fw */ 6047 status = bfa_fcdiag_loopback_send(fcdiag, &loopback); 6048 return status; 6049 } 6050 6051 /* 6052 * DIAG queue test command 6053 * 6054 * @param[in] *bfa - bfa data struct 6055 * @param[in] force - 1: don't do ioc op checking 6056 * @param[in] queue - queue no. to test 6057 * @param[in] *result - pt to bfa_diag_qtest_result_t data struct 6058 * @param[in] cbfn - callback function 6059 * @param[in] *cbarg - callback functioin arg 6060 * 6061 * @param[out] 6062 */ 6063 bfa_status_t 6064 bfa_fcdiag_queuetest(struct bfa_s *bfa, u32 force, u32 queue, 6065 struct bfa_diag_qtest_result_s *result, bfa_cb_diag_t cbfn, 6066 void *cbarg) 6067 { 6068 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 6069 bfa_status_t status; 6070 bfa_trc(fcdiag, force); 6071 bfa_trc(fcdiag, queue); 6072 6073 if (!force && !bfa_iocfc_is_operational(bfa)) 6074 return BFA_STATUS_IOC_NON_OP; 6075 6076 /* check to see if there is another destructive diag cmd running */ 6077 if (fcdiag->qtest.lock) { 6078 bfa_trc(fcdiag, fcdiag->qtest.lock); 6079 return BFA_STATUS_DEVBUSY; 6080 } 6081 6082 /* Initialization */ 6083 fcdiag->qtest.lock = 1; 6084 fcdiag->qtest.cbfn = cbfn; 6085 fcdiag->qtest.cbarg = cbarg; 6086 fcdiag->qtest.result = result; 6087 fcdiag->qtest.count = QTEST_CNT_DEFAULT; 6088 6089 /* Init test results */ 6090 fcdiag->qtest.result->status = BFA_STATUS_OK; 6091 fcdiag->qtest.result->count = 0; 6092 6093 /* send */ 6094 if (queue < BFI_IOC_MAX_CQS) { 6095 fcdiag->qtest.result->queue = (u8)queue; 6096 fcdiag->qtest.queue = (u8)queue; 6097 fcdiag->qtest.all = 0; 6098 } else { 6099 fcdiag->qtest.result->queue = 0; 6100 fcdiag->qtest.queue = 0; 6101 fcdiag->qtest.all = 1; 6102 } 6103 status = bfa_fcdiag_queuetest_send(fcdiag); 6104 6105 /* Start a timer */ 6106 if (status == BFA_STATUS_OK) { 6107 bfa_timer_start(bfa, &fcdiag->qtest.timer, 6108 bfa_fcdiag_queuetest_timeout, fcdiag, 6109 BFA_DIAG_QTEST_TOV); 6110 fcdiag->qtest.timer_active = 1; 6111 } 6112 return status; 6113 } 6114 6115 /* 6116 * DIAG PLB is running 6117 * 6118 * @param[in] *bfa - bfa data struct 6119 * 6120 * @param[out] 6121 */ 6122 bfa_status_t 6123 bfa_fcdiag_lb_is_running(struct bfa_s *bfa) 6124 { 6125 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 6126 return fcdiag->lb.lock ? BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK; 6127 } 6128 6129 /* 6130 * D-port 6131 */ 6132 #define bfa_dport_result_start(__dport, __mode) do { \ 6133 (__dport)->result.start_time = ktime_get_real_seconds(); \ 6134 (__dport)->result.status = DPORT_TEST_ST_INPRG; \ 6135 (__dport)->result.mode = (__mode); \ 6136 (__dport)->result.rp_pwwn = (__dport)->rp_pwwn; \ 6137 (__dport)->result.rp_nwwn = (__dport)->rp_nwwn; \ 6138 (__dport)->result.lpcnt = (__dport)->lpcnt; \ 6139 } while (0) 6140 6141 static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport, 6142 enum bfi_dport_req req); 6143 static void 6144 bfa_cb_fcdiag_dport(struct bfa_dport_s *dport, bfa_status_t bfa_status) 6145 { 6146 if (dport->cbfn != NULL) { 6147 dport->cbfn(dport->cbarg, bfa_status); 6148 dport->cbfn = NULL; 6149 dport->cbarg = NULL; 6150 } 6151 } 6152 6153 static void 6154 bfa_dport_sm_disabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) 6155 { 6156 bfa_trc(dport->bfa, event); 6157 6158 switch (event) { 6159 case BFA_DPORT_SM_ENABLE: 6160 bfa_fcport_dportenable(dport->bfa); 6161 if (bfa_dport_send_req(dport, BFI_DPORT_ENABLE)) 6162 bfa_sm_set_state(dport, bfa_dport_sm_enabling); 6163 else 6164 bfa_sm_set_state(dport, bfa_dport_sm_enabling_qwait); 6165 break; 6166 6167 case BFA_DPORT_SM_DISABLE: 6168 /* Already disabled */ 6169 break; 6170 6171 case BFA_DPORT_SM_HWFAIL: 6172 /* ignore */ 6173 break; 6174 6175 case BFA_DPORT_SM_SCN: 6176 if (dport->i2hmsg.scn.state == BFI_DPORT_SCN_DDPORT_ENABLE) { 6177 bfa_fcport_ddportenable(dport->bfa); 6178 dport->dynamic = BFA_TRUE; 6179 dport->test_state = BFA_DPORT_ST_NOTSTART; 6180 bfa_sm_set_state(dport, bfa_dport_sm_enabled); 6181 } else { 6182 bfa_trc(dport->bfa, dport->i2hmsg.scn.state); 6183 WARN_ON(1); 6184 } 6185 break; 6186 6187 default: 6188 bfa_sm_fault(dport->bfa, event); 6189 } 6190 } 6191 6192 static void 6193 bfa_dport_sm_enabling_qwait(struct bfa_dport_s *dport, 6194 enum bfa_dport_sm_event event) 6195 { 6196 bfa_trc(dport->bfa, event); 6197 6198 switch (event) { 6199 case BFA_DPORT_SM_QRESUME: 6200 bfa_sm_set_state(dport, bfa_dport_sm_enabling); 6201 bfa_dport_send_req(dport, BFI_DPORT_ENABLE); 6202 break; 6203 6204 case BFA_DPORT_SM_HWFAIL: 6205 bfa_reqq_wcancel(&dport->reqq_wait); 6206 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6207 bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); 6208 break; 6209 6210 default: 6211 bfa_sm_fault(dport->bfa, event); 6212 } 6213 } 6214 6215 static void 6216 bfa_dport_sm_enabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) 6217 { 6218 bfa_trc(dport->bfa, event); 6219 6220 switch (event) { 6221 case BFA_DPORT_SM_FWRSP: 6222 memset(&dport->result, 0, 6223 sizeof(struct bfa_diag_dport_result_s)); 6224 if (dport->i2hmsg.rsp.status == BFA_STATUS_DPORT_INV_SFP) { 6225 dport->test_state = BFA_DPORT_ST_NO_SFP; 6226 } else { 6227 dport->test_state = BFA_DPORT_ST_INP; 6228 bfa_dport_result_start(dport, BFA_DPORT_OPMODE_AUTO); 6229 } 6230 bfa_sm_set_state(dport, bfa_dport_sm_enabled); 6231 break; 6232 6233 case BFA_DPORT_SM_REQFAIL: 6234 dport->test_state = BFA_DPORT_ST_DISABLED; 6235 bfa_fcport_dportdisable(dport->bfa); 6236 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6237 break; 6238 6239 case BFA_DPORT_SM_HWFAIL: 6240 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6241 bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); 6242 break; 6243 6244 default: 6245 bfa_sm_fault(dport->bfa, event); 6246 } 6247 } 6248 6249 static void 6250 bfa_dport_sm_enabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) 6251 { 6252 bfa_trc(dport->bfa, event); 6253 6254 switch (event) { 6255 case BFA_DPORT_SM_START: 6256 if (bfa_dport_send_req(dport, BFI_DPORT_START)) 6257 bfa_sm_set_state(dport, bfa_dport_sm_starting); 6258 else 6259 bfa_sm_set_state(dport, bfa_dport_sm_starting_qwait); 6260 break; 6261 6262 case BFA_DPORT_SM_DISABLE: 6263 bfa_fcport_dportdisable(dport->bfa); 6264 if (bfa_dport_send_req(dport, BFI_DPORT_DISABLE)) 6265 bfa_sm_set_state(dport, bfa_dport_sm_disabling); 6266 else 6267 bfa_sm_set_state(dport, bfa_dport_sm_disabling_qwait); 6268 break; 6269 6270 case BFA_DPORT_SM_HWFAIL: 6271 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6272 break; 6273 6274 case BFA_DPORT_SM_SCN: 6275 switch (dport->i2hmsg.scn.state) { 6276 case BFI_DPORT_SCN_TESTCOMP: 6277 dport->test_state = BFA_DPORT_ST_COMP; 6278 break; 6279 6280 case BFI_DPORT_SCN_TESTSTART: 6281 dport->test_state = BFA_DPORT_ST_INP; 6282 break; 6283 6284 case BFI_DPORT_SCN_TESTSKIP: 6285 case BFI_DPORT_SCN_SUBTESTSTART: 6286 /* no state change */ 6287 break; 6288 6289 case BFI_DPORT_SCN_SFP_REMOVED: 6290 dport->test_state = BFA_DPORT_ST_NO_SFP; 6291 break; 6292 6293 case BFI_DPORT_SCN_DDPORT_DISABLE: 6294 bfa_fcport_ddportdisable(dport->bfa); 6295 6296 if (bfa_dport_send_req(dport, BFI_DPORT_DYN_DISABLE)) 6297 bfa_sm_set_state(dport, 6298 bfa_dport_sm_dynamic_disabling); 6299 else 6300 bfa_sm_set_state(dport, 6301 bfa_dport_sm_dynamic_disabling_qwait); 6302 break; 6303 6304 case BFI_DPORT_SCN_FCPORT_DISABLE: 6305 bfa_fcport_ddportdisable(dport->bfa); 6306 6307 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6308 dport->dynamic = BFA_FALSE; 6309 break; 6310 6311 default: 6312 bfa_trc(dport->bfa, dport->i2hmsg.scn.state); 6313 bfa_sm_fault(dport->bfa, event); 6314 } 6315 break; 6316 default: 6317 bfa_sm_fault(dport->bfa, event); 6318 } 6319 } 6320 6321 static void 6322 bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport, 6323 enum bfa_dport_sm_event event) 6324 { 6325 bfa_trc(dport->bfa, event); 6326 6327 switch (event) { 6328 case BFA_DPORT_SM_QRESUME: 6329 bfa_sm_set_state(dport, bfa_dport_sm_disabling); 6330 bfa_dport_send_req(dport, BFI_DPORT_DISABLE); 6331 break; 6332 6333 case BFA_DPORT_SM_HWFAIL: 6334 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6335 bfa_reqq_wcancel(&dport->reqq_wait); 6336 bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); 6337 break; 6338 6339 case BFA_DPORT_SM_SCN: 6340 /* ignore */ 6341 break; 6342 6343 default: 6344 bfa_sm_fault(dport->bfa, event); 6345 } 6346 } 6347 6348 static void 6349 bfa_dport_sm_disabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) 6350 { 6351 bfa_trc(dport->bfa, event); 6352 6353 switch (event) { 6354 case BFA_DPORT_SM_FWRSP: 6355 dport->test_state = BFA_DPORT_ST_DISABLED; 6356 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6357 break; 6358 6359 case BFA_DPORT_SM_HWFAIL: 6360 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6361 bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); 6362 break; 6363 6364 case BFA_DPORT_SM_SCN: 6365 /* no state change */ 6366 break; 6367 6368 default: 6369 bfa_sm_fault(dport->bfa, event); 6370 } 6371 } 6372 6373 static void 6374 bfa_dport_sm_starting_qwait(struct bfa_dport_s *dport, 6375 enum bfa_dport_sm_event event) 6376 { 6377 bfa_trc(dport->bfa, event); 6378 6379 switch (event) { 6380 case BFA_DPORT_SM_QRESUME: 6381 bfa_sm_set_state(dport, bfa_dport_sm_starting); 6382 bfa_dport_send_req(dport, BFI_DPORT_START); 6383 break; 6384 6385 case BFA_DPORT_SM_HWFAIL: 6386 bfa_reqq_wcancel(&dport->reqq_wait); 6387 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6388 bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); 6389 break; 6390 6391 default: 6392 bfa_sm_fault(dport->bfa, event); 6393 } 6394 } 6395 6396 static void 6397 bfa_dport_sm_starting(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) 6398 { 6399 bfa_trc(dport->bfa, event); 6400 6401 switch (event) { 6402 case BFA_DPORT_SM_FWRSP: 6403 memset(&dport->result, 0, 6404 sizeof(struct bfa_diag_dport_result_s)); 6405 if (dport->i2hmsg.rsp.status == BFA_STATUS_DPORT_INV_SFP) { 6406 dport->test_state = BFA_DPORT_ST_NO_SFP; 6407 } else { 6408 dport->test_state = BFA_DPORT_ST_INP; 6409 bfa_dport_result_start(dport, BFA_DPORT_OPMODE_MANU); 6410 } 6411 /* fall thru */ 6412 6413 case BFA_DPORT_SM_REQFAIL: 6414 bfa_sm_set_state(dport, bfa_dport_sm_enabled); 6415 break; 6416 6417 case BFA_DPORT_SM_HWFAIL: 6418 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6419 bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); 6420 break; 6421 6422 default: 6423 bfa_sm_fault(dport->bfa, event); 6424 } 6425 } 6426 6427 static void 6428 bfa_dport_sm_dynamic_disabling(struct bfa_dport_s *dport, 6429 enum bfa_dport_sm_event event) 6430 { 6431 bfa_trc(dport->bfa, event); 6432 6433 switch (event) { 6434 case BFA_DPORT_SM_SCN: 6435 switch (dport->i2hmsg.scn.state) { 6436 case BFI_DPORT_SCN_DDPORT_DISABLED: 6437 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6438 dport->dynamic = BFA_FALSE; 6439 bfa_fcport_enable(dport->bfa); 6440 break; 6441 6442 default: 6443 bfa_trc(dport->bfa, dport->i2hmsg.scn.state); 6444 bfa_sm_fault(dport->bfa, event); 6445 6446 } 6447 break; 6448 6449 case BFA_DPORT_SM_HWFAIL: 6450 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6451 bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); 6452 break; 6453 6454 default: 6455 bfa_sm_fault(dport->bfa, event); 6456 } 6457 } 6458 6459 static void 6460 bfa_dport_sm_dynamic_disabling_qwait(struct bfa_dport_s *dport, 6461 enum bfa_dport_sm_event event) 6462 { 6463 bfa_trc(dport->bfa, event); 6464 6465 switch (event) { 6466 case BFA_DPORT_SM_QRESUME: 6467 bfa_sm_set_state(dport, bfa_dport_sm_dynamic_disabling); 6468 bfa_dport_send_req(dport, BFI_DPORT_DYN_DISABLE); 6469 break; 6470 6471 case BFA_DPORT_SM_HWFAIL: 6472 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6473 bfa_reqq_wcancel(&dport->reqq_wait); 6474 bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); 6475 break; 6476 6477 case BFA_DPORT_SM_SCN: 6478 /* ignore */ 6479 break; 6480 6481 default: 6482 bfa_sm_fault(dport->bfa, event); 6483 } 6484 } 6485 6486 static bfa_boolean_t 6487 bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req) 6488 { 6489 struct bfi_diag_dport_req_s *m; 6490 6491 /* 6492 * check for room in queue to send request now 6493 */ 6494 m = bfa_reqq_next(dport->bfa, BFA_REQQ_DIAG); 6495 if (!m) { 6496 bfa_reqq_wait(dport->bfa, BFA_REQQ_PORT, &dport->reqq_wait); 6497 return BFA_FALSE; 6498 } 6499 6500 bfi_h2i_set(m->mh, BFI_MC_DIAG, BFI_DIAG_H2I_DPORT, 6501 bfa_fn_lpu(dport->bfa)); 6502 m->req = req; 6503 if ((req == BFI_DPORT_ENABLE) || (req == BFI_DPORT_START)) { 6504 m->lpcnt = cpu_to_be32(dport->lpcnt); 6505 m->payload = cpu_to_be32(dport->payload); 6506 } 6507 6508 /* 6509 * queue I/O message to firmware 6510 */ 6511 bfa_reqq_produce(dport->bfa, BFA_REQQ_DIAG, m->mh); 6512 6513 return BFA_TRUE; 6514 } 6515 6516 static void 6517 bfa_dport_qresume(void *cbarg) 6518 { 6519 struct bfa_dport_s *dport = cbarg; 6520 6521 bfa_sm_send_event(dport, BFA_DPORT_SM_QRESUME); 6522 } 6523 6524 static void 6525 bfa_dport_req_comp(struct bfa_dport_s *dport, struct bfi_diag_dport_rsp_s *msg) 6526 { 6527 msg->status = cpu_to_be32(msg->status); 6528 dport->i2hmsg.rsp.status = msg->status; 6529 dport->rp_pwwn = msg->pwwn; 6530 dport->rp_nwwn = msg->nwwn; 6531 6532 if ((msg->status == BFA_STATUS_OK) || 6533 (msg->status == BFA_STATUS_DPORT_NO_SFP)) { 6534 bfa_trc(dport->bfa, msg->status); 6535 bfa_trc(dport->bfa, dport->rp_pwwn); 6536 bfa_trc(dport->bfa, dport->rp_nwwn); 6537 bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP); 6538 6539 } else { 6540 bfa_trc(dport->bfa, msg->status); 6541 bfa_sm_send_event(dport, BFA_DPORT_SM_REQFAIL); 6542 } 6543 bfa_cb_fcdiag_dport(dport, msg->status); 6544 } 6545 6546 static bfa_boolean_t 6547 bfa_dport_is_sending_req(struct bfa_dport_s *dport) 6548 { 6549 if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || 6550 bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) || 6551 bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || 6552 bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait) || 6553 bfa_sm_cmp_state(dport, bfa_dport_sm_starting) || 6554 bfa_sm_cmp_state(dport, bfa_dport_sm_starting_qwait)) { 6555 return BFA_TRUE; 6556 } else { 6557 return BFA_FALSE; 6558 } 6559 } 6560 6561 static void 6562 bfa_dport_scn(struct bfa_dport_s *dport, struct bfi_diag_dport_scn_s *msg) 6563 { 6564 int i; 6565 uint8_t subtesttype; 6566 6567 bfa_trc(dport->bfa, msg->state); 6568 dport->i2hmsg.scn.state = msg->state; 6569 6570 switch (dport->i2hmsg.scn.state) { 6571 case BFI_DPORT_SCN_TESTCOMP: 6572 dport->result.end_time = ktime_get_real_seconds(); 6573 bfa_trc(dport->bfa, dport->result.end_time); 6574 6575 dport->result.status = msg->info.testcomp.status; 6576 bfa_trc(dport->bfa, dport->result.status); 6577 6578 dport->result.roundtrip_latency = 6579 cpu_to_be32(msg->info.testcomp.latency); 6580 dport->result.est_cable_distance = 6581 cpu_to_be32(msg->info.testcomp.distance); 6582 dport->result.buffer_required = 6583 be16_to_cpu(msg->info.testcomp.numbuffer); 6584 6585 dport->result.frmsz = be16_to_cpu(msg->info.testcomp.frm_sz); 6586 dport->result.speed = msg->info.testcomp.speed; 6587 6588 bfa_trc(dport->bfa, dport->result.roundtrip_latency); 6589 bfa_trc(dport->bfa, dport->result.est_cable_distance); 6590 bfa_trc(dport->bfa, dport->result.buffer_required); 6591 bfa_trc(dport->bfa, dport->result.frmsz); 6592 bfa_trc(dport->bfa, dport->result.speed); 6593 6594 for (i = DPORT_TEST_ELOOP; i < DPORT_TEST_MAX; i++) { 6595 dport->result.subtest[i].status = 6596 msg->info.testcomp.subtest_status[i]; 6597 bfa_trc(dport->bfa, dport->result.subtest[i].status); 6598 } 6599 break; 6600 6601 case BFI_DPORT_SCN_TESTSKIP: 6602 case BFI_DPORT_SCN_DDPORT_ENABLE: 6603 memset(&dport->result, 0, 6604 sizeof(struct bfa_diag_dport_result_s)); 6605 break; 6606 6607 case BFI_DPORT_SCN_TESTSTART: 6608 memset(&dport->result, 0, 6609 sizeof(struct bfa_diag_dport_result_s)); 6610 dport->rp_pwwn = msg->info.teststart.pwwn; 6611 dport->rp_nwwn = msg->info.teststart.nwwn; 6612 dport->lpcnt = cpu_to_be32(msg->info.teststart.numfrm); 6613 bfa_dport_result_start(dport, msg->info.teststart.mode); 6614 break; 6615 6616 case BFI_DPORT_SCN_SUBTESTSTART: 6617 subtesttype = msg->info.teststart.type; 6618 dport->result.subtest[subtesttype].start_time = 6619 ktime_get_real_seconds(); 6620 dport->result.subtest[subtesttype].status = 6621 DPORT_TEST_ST_INPRG; 6622 6623 bfa_trc(dport->bfa, subtesttype); 6624 bfa_trc(dport->bfa, 6625 dport->result.subtest[subtesttype].start_time); 6626 break; 6627 6628 case BFI_DPORT_SCN_SFP_REMOVED: 6629 case BFI_DPORT_SCN_DDPORT_DISABLED: 6630 case BFI_DPORT_SCN_DDPORT_DISABLE: 6631 case BFI_DPORT_SCN_FCPORT_DISABLE: 6632 dport->result.status = DPORT_TEST_ST_IDLE; 6633 break; 6634 6635 default: 6636 bfa_sm_fault(dport->bfa, msg->state); 6637 } 6638 6639 bfa_sm_send_event(dport, BFA_DPORT_SM_SCN); 6640 } 6641 6642 /* 6643 * Dport enable 6644 * 6645 * @param[in] *bfa - bfa data struct 6646 */ 6647 bfa_status_t 6648 bfa_dport_enable(struct bfa_s *bfa, u32 lpcnt, u32 pat, 6649 bfa_cb_diag_t cbfn, void *cbarg) 6650 { 6651 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 6652 struct bfa_dport_s *dport = &fcdiag->dport; 6653 6654 /* 6655 * Dport is not support in MEZZ card 6656 */ 6657 if (bfa_mfg_is_mezz(dport->bfa->ioc.attr->card_type)) { 6658 bfa_trc(dport->bfa, BFA_STATUS_PBC); 6659 return BFA_STATUS_CMD_NOTSUPP_MEZZ; 6660 } 6661 6662 /* 6663 * Dport is supported in CT2 or above 6664 */ 6665 if (!(bfa_asic_id_ct2(dport->bfa->ioc.pcidev.device_id))) { 6666 bfa_trc(dport->bfa, dport->bfa->ioc.pcidev.device_id); 6667 return BFA_STATUS_FEATURE_NOT_SUPPORTED; 6668 } 6669 6670 /* 6671 * Check to see if IOC is down 6672 */ 6673 if (!bfa_iocfc_is_operational(bfa)) 6674 return BFA_STATUS_IOC_NON_OP; 6675 6676 /* if port is PBC disabled, return error */ 6677 if (bfa_fcport_is_pbcdisabled(bfa)) { 6678 bfa_trc(dport->bfa, BFA_STATUS_PBC); 6679 return BFA_STATUS_PBC; 6680 } 6681 6682 /* 6683 * Check if port mode is FC port 6684 */ 6685 if (bfa_ioc_get_type(&bfa->ioc) != BFA_IOC_TYPE_FC) { 6686 bfa_trc(dport->bfa, bfa_ioc_get_type(&bfa->ioc)); 6687 return BFA_STATUS_CMD_NOTSUPP_CNA; 6688 } 6689 6690 /* 6691 * Check if port is in LOOP mode 6692 */ 6693 if ((bfa_fcport_get_cfg_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) || 6694 (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)) { 6695 bfa_trc(dport->bfa, 0); 6696 return BFA_STATUS_TOPOLOGY_LOOP; 6697 } 6698 6699 /* 6700 * Check if port is TRUNK mode 6701 */ 6702 if (bfa_fcport_is_trunk_enabled(bfa)) { 6703 bfa_trc(dport->bfa, 0); 6704 return BFA_STATUS_ERROR_TRUNK_ENABLED; 6705 } 6706 6707 /* 6708 * Check if diag loopback is running 6709 */ 6710 if (bfa_fcdiag_lb_is_running(bfa)) { 6711 bfa_trc(dport->bfa, 0); 6712 return BFA_STATUS_DIAG_BUSY; 6713 } 6714 6715 /* 6716 * Check to see if port is disable or in dport state 6717 */ 6718 if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && 6719 (bfa_fcport_is_dport(bfa) == BFA_FALSE)) { 6720 bfa_trc(dport->bfa, 0); 6721 return BFA_STATUS_PORT_NOT_DISABLED; 6722 } 6723 6724 /* 6725 * Check if dport is in dynamic mode 6726 */ 6727 if (dport->dynamic) 6728 return BFA_STATUS_DDPORT_ERR; 6729 6730 /* 6731 * Check if dport is busy 6732 */ 6733 if (bfa_dport_is_sending_req(dport)) 6734 return BFA_STATUS_DEVBUSY; 6735 6736 /* 6737 * Check if dport is already enabled 6738 */ 6739 if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) { 6740 bfa_trc(dport->bfa, 0); 6741 return BFA_STATUS_DPORT_ENABLED; 6742 } 6743 6744 bfa_trc(dport->bfa, lpcnt); 6745 bfa_trc(dport->bfa, pat); 6746 dport->lpcnt = (lpcnt) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT; 6747 dport->payload = (pat) ? pat : LB_PATTERN_DEFAULT; 6748 dport->cbfn = cbfn; 6749 dport->cbarg = cbarg; 6750 6751 bfa_sm_send_event(dport, BFA_DPORT_SM_ENABLE); 6752 return BFA_STATUS_OK; 6753 } 6754 6755 /* 6756 * Dport disable 6757 * 6758 * @param[in] *bfa - bfa data struct 6759 */ 6760 bfa_status_t 6761 bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) 6762 { 6763 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 6764 struct bfa_dport_s *dport = &fcdiag->dport; 6765 6766 if (bfa_ioc_is_disabled(&bfa->ioc)) 6767 return BFA_STATUS_IOC_DISABLED; 6768 6769 /* if port is PBC disabled, return error */ 6770 if (bfa_fcport_is_pbcdisabled(bfa)) { 6771 bfa_trc(dport->bfa, BFA_STATUS_PBC); 6772 return BFA_STATUS_PBC; 6773 } 6774 6775 /* 6776 * Check if dport is in dynamic mode 6777 */ 6778 if (dport->dynamic) { 6779 return BFA_STATUS_DDPORT_ERR; 6780 } 6781 6782 /* 6783 * Check to see if port is disable or in dport state 6784 */ 6785 if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && 6786 (bfa_fcport_is_dport(bfa) == BFA_FALSE)) { 6787 bfa_trc(dport->bfa, 0); 6788 return BFA_STATUS_PORT_NOT_DISABLED; 6789 } 6790 6791 /* 6792 * Check if dport is busy 6793 */ 6794 if (bfa_dport_is_sending_req(dport)) 6795 return BFA_STATUS_DEVBUSY; 6796 6797 /* 6798 * Check if dport is already disabled 6799 */ 6800 if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled)) { 6801 bfa_trc(dport->bfa, 0); 6802 return BFA_STATUS_DPORT_DISABLED; 6803 } 6804 6805 dport->cbfn = cbfn; 6806 dport->cbarg = cbarg; 6807 6808 bfa_sm_send_event(dport, BFA_DPORT_SM_DISABLE); 6809 return BFA_STATUS_OK; 6810 } 6811 6812 /* 6813 * Dport start -- restart dport test 6814 * 6815 * @param[in] *bfa - bfa data struct 6816 */ 6817 bfa_status_t 6818 bfa_dport_start(struct bfa_s *bfa, u32 lpcnt, u32 pat, 6819 bfa_cb_diag_t cbfn, void *cbarg) 6820 { 6821 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 6822 struct bfa_dport_s *dport = &fcdiag->dport; 6823 6824 /* 6825 * Check to see if IOC is down 6826 */ 6827 if (!bfa_iocfc_is_operational(bfa)) 6828 return BFA_STATUS_IOC_NON_OP; 6829 6830 /* 6831 * Check if dport is in dynamic mode 6832 */ 6833 if (dport->dynamic) 6834 return BFA_STATUS_DDPORT_ERR; 6835 6836 /* 6837 * Check if dport is busy 6838 */ 6839 if (bfa_dport_is_sending_req(dport)) 6840 return BFA_STATUS_DEVBUSY; 6841 6842 /* 6843 * Check if dport is in enabled state. 6844 * Test can only be restart when previous test has completed 6845 */ 6846 if (!bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) { 6847 bfa_trc(dport->bfa, 0); 6848 return BFA_STATUS_DPORT_DISABLED; 6849 6850 } else { 6851 if (dport->test_state == BFA_DPORT_ST_NO_SFP) 6852 return BFA_STATUS_DPORT_INV_SFP; 6853 6854 if (dport->test_state == BFA_DPORT_ST_INP) 6855 return BFA_STATUS_DEVBUSY; 6856 6857 WARN_ON(dport->test_state != BFA_DPORT_ST_COMP); 6858 } 6859 6860 bfa_trc(dport->bfa, lpcnt); 6861 bfa_trc(dport->bfa, pat); 6862 6863 dport->lpcnt = (lpcnt) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT; 6864 dport->payload = (pat) ? pat : LB_PATTERN_DEFAULT; 6865 6866 dport->cbfn = cbfn; 6867 dport->cbarg = cbarg; 6868 6869 bfa_sm_send_event(dport, BFA_DPORT_SM_START); 6870 return BFA_STATUS_OK; 6871 } 6872 6873 /* 6874 * Dport show -- return dport test result 6875 * 6876 * @param[in] *bfa - bfa data struct 6877 */ 6878 bfa_status_t 6879 bfa_dport_show(struct bfa_s *bfa, struct bfa_diag_dport_result_s *result) 6880 { 6881 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 6882 struct bfa_dport_s *dport = &fcdiag->dport; 6883 6884 /* 6885 * Check to see if IOC is down 6886 */ 6887 if (!bfa_iocfc_is_operational(bfa)) 6888 return BFA_STATUS_IOC_NON_OP; 6889 6890 /* 6891 * Check if dport is busy 6892 */ 6893 if (bfa_dport_is_sending_req(dport)) 6894 return BFA_STATUS_DEVBUSY; 6895 6896 /* 6897 * Check if dport is in enabled state. 6898 */ 6899 if (!bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) { 6900 bfa_trc(dport->bfa, 0); 6901 return BFA_STATUS_DPORT_DISABLED; 6902 6903 } 6904 6905 /* 6906 * Check if there is SFP 6907 */ 6908 if (dport->test_state == BFA_DPORT_ST_NO_SFP) 6909 return BFA_STATUS_DPORT_INV_SFP; 6910 6911 memcpy(result, &dport->result, sizeof(struct bfa_diag_dport_result_s)); 6912 6913 return BFA_STATUS_OK; 6914 } 6915