1 /* 2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. 3 * All rights reserved 4 * www.brocade.com 5 * 6 * Linux driver for Brocade Fibre Channel Host Bus Adapter. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License (GPL) Version 2 as 10 * published by the Free Software Foundation 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 */ 17 18 #include "bfad_drv.h" 19 #include "bfa_ioc.h" 20 #include "bfi_ctreg.h" 21 #include "bfa_defs.h" 22 #include "bfa_defs_svc.h" 23 24 BFA_TRC_FILE(CNA, IOC); 25 26 /* 27 * IOC local definitions 28 */ 29 #define BFA_IOC_TOV 3000 /* msecs */ 30 #define BFA_IOC_HWSEM_TOV 500 /* msecs */ 31 #define BFA_IOC_HB_TOV 500 /* msecs */ 32 #define BFA_IOC_HWINIT_MAX 5 33 #define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV 34 35 #define bfa_ioc_timer_start(__ioc) \ 36 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ 37 bfa_ioc_timeout, (__ioc), BFA_IOC_TOV) 38 #define bfa_ioc_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->ioc_timer) 39 40 #define bfa_hb_timer_start(__ioc) \ 41 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->hb_timer, \ 42 bfa_ioc_hb_check, (__ioc), BFA_IOC_HB_TOV) 43 #define bfa_hb_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->hb_timer) 44 45 #define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn)) 46 47 /* 48 * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details. 49 */ 50 51 #define bfa_ioc_firmware_lock(__ioc) \ 52 ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc)) 53 #define bfa_ioc_firmware_unlock(__ioc) \ 54 ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc)) 55 #define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc)) 56 #define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc)) 57 #define bfa_ioc_notify_fail(__ioc) \ 58 ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc)) 59 #define bfa_ioc_sync_start(__ioc) \ 60 ((__ioc)->ioc_hwif->ioc_sync_start(__ioc)) 61 #define bfa_ioc_sync_join(__ioc) \ 62 ((__ioc)->ioc_hwif->ioc_sync_join(__ioc)) 63 #define bfa_ioc_sync_leave(__ioc) \ 64 ((__ioc)->ioc_hwif->ioc_sync_leave(__ioc)) 65 #define bfa_ioc_sync_ack(__ioc) \ 66 ((__ioc)->ioc_hwif->ioc_sync_ack(__ioc)) 67 #define bfa_ioc_sync_complete(__ioc) \ 68 ((__ioc)->ioc_hwif->ioc_sync_complete(__ioc)) 69 70 #define bfa_ioc_mbox_cmd_pending(__ioc) \ 71 (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \ 72 readl((__ioc)->ioc_regs.hfn_mbox_cmd)) 73 74 bfa_boolean_t bfa_auto_recover = BFA_TRUE; 75 76 /* 77 * forward declarations 78 */ 79 static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc); 80 static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force); 81 static void bfa_ioc_timeout(void *ioc); 82 static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc); 83 static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc); 84 static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc); 85 static void bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc); 86 static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc); 87 static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc); 88 static void bfa_ioc_recover(struct bfa_ioc_s *ioc); 89 static void bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc); 90 static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc); 91 static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc); 92 static void bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc); 93 static void bfa_ioc_fail_notify(struct bfa_ioc_s *ioc); 94 static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc); 95 96 97 /* 98 * IOC state machine definitions/declarations 99 */ 100 enum ioc_event { 101 IOC_E_RESET = 1, /* IOC reset request */ 102 IOC_E_ENABLE = 2, /* IOC enable request */ 103 IOC_E_DISABLE = 3, /* IOC disable request */ 104 IOC_E_DETACH = 4, /* driver detach cleanup */ 105 IOC_E_ENABLED = 5, /* f/w enabled */ 106 IOC_E_FWRSP_GETATTR = 6, /* IOC get attribute response */ 107 IOC_E_DISABLED = 7, /* f/w disabled */ 108 IOC_E_INITFAILED = 8, /* failure notice by iocpf sm */ 109 IOC_E_PFFAILED = 9, /* failure notice by iocpf sm */ 110 IOC_E_HBFAIL = 10, /* heartbeat failure */ 111 IOC_E_HWERROR = 11, /* hardware error interrupt */ 112 IOC_E_TIMEOUT = 12, /* timeout */ 113 }; 114 115 bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event); 116 bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event); 117 bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event); 118 bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event); 119 bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event); 120 bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc_s, enum ioc_event); 121 bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event); 122 bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event); 123 bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event); 124 125 static struct bfa_sm_table_s ioc_sm_table[] = { 126 {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT}, 127 {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET}, 128 {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING}, 129 {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR}, 130 {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL}, 131 {BFA_SM(bfa_ioc_sm_fail_retry), BFA_IOC_INITFAIL}, 132 {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL}, 133 {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, 134 {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, 135 }; 136 137 /* 138 * IOCPF state machine definitions/declarations 139 */ 140 141 #define bfa_iocpf_timer_start(__ioc) \ 142 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ 143 bfa_iocpf_timeout, (__ioc), BFA_IOC_TOV) 144 #define bfa_iocpf_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->ioc_timer) 145 146 #define bfa_iocpf_recovery_timer_start(__ioc) \ 147 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ 148 bfa_iocpf_timeout, (__ioc), BFA_IOC_TOV_RECOVER) 149 150 #define bfa_sem_timer_start(__ioc) \ 151 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->sem_timer, \ 152 bfa_iocpf_sem_timeout, (__ioc), BFA_IOC_HWSEM_TOV) 153 #define bfa_sem_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->sem_timer) 154 155 /* 156 * Forward declareations for iocpf state machine 157 */ 158 static void bfa_iocpf_timeout(void *ioc_arg); 159 static void bfa_iocpf_sem_timeout(void *ioc_arg); 160 161 /* 162 * IOCPF state machine events 163 */ 164 enum iocpf_event { 165 IOCPF_E_ENABLE = 1, /* IOCPF enable request */ 166 IOCPF_E_DISABLE = 2, /* IOCPF disable request */ 167 IOCPF_E_STOP = 3, /* stop on driver detach */ 168 IOCPF_E_FWREADY = 4, /* f/w initialization done */ 169 IOCPF_E_FWRSP_ENABLE = 5, /* enable f/w response */ 170 IOCPF_E_FWRSP_DISABLE = 6, /* disable f/w response */ 171 IOCPF_E_FAIL = 7, /* failure notice by ioc sm */ 172 IOCPF_E_INITFAIL = 8, /* init fail notice by ioc sm */ 173 IOCPF_E_GETATTRFAIL = 9, /* init fail notice by ioc sm */ 174 IOCPF_E_SEMLOCKED = 10, /* h/w semaphore is locked */ 175 IOCPF_E_TIMEOUT = 11, /* f/w response timeout */ 176 }; 177 178 /* 179 * IOCPF states 180 */ 181 enum bfa_iocpf_state { 182 BFA_IOCPF_RESET = 1, /* IOC is in reset state */ 183 BFA_IOCPF_SEMWAIT = 2, /* Waiting for IOC h/w semaphore */ 184 BFA_IOCPF_HWINIT = 3, /* IOC h/w is being initialized */ 185 BFA_IOCPF_READY = 4, /* IOCPF is initialized */ 186 BFA_IOCPF_INITFAIL = 5, /* IOCPF failed */ 187 BFA_IOCPF_FAIL = 6, /* IOCPF failed */ 188 BFA_IOCPF_DISABLING = 7, /* IOCPF is being disabled */ 189 BFA_IOCPF_DISABLED = 8, /* IOCPF is disabled */ 190 BFA_IOCPF_FWMISMATCH = 9, /* IOC f/w different from drivers */ 191 }; 192 193 bfa_fsm_state_decl(bfa_iocpf, reset, struct bfa_iocpf_s, enum iocpf_event); 194 bfa_fsm_state_decl(bfa_iocpf, fwcheck, struct bfa_iocpf_s, enum iocpf_event); 195 bfa_fsm_state_decl(bfa_iocpf, mismatch, struct bfa_iocpf_s, enum iocpf_event); 196 bfa_fsm_state_decl(bfa_iocpf, semwait, struct bfa_iocpf_s, enum iocpf_event); 197 bfa_fsm_state_decl(bfa_iocpf, hwinit, struct bfa_iocpf_s, enum iocpf_event); 198 bfa_fsm_state_decl(bfa_iocpf, enabling, struct bfa_iocpf_s, enum iocpf_event); 199 bfa_fsm_state_decl(bfa_iocpf, ready, struct bfa_iocpf_s, enum iocpf_event); 200 bfa_fsm_state_decl(bfa_iocpf, initfail_sync, struct bfa_iocpf_s, 201 enum iocpf_event); 202 bfa_fsm_state_decl(bfa_iocpf, initfail, struct bfa_iocpf_s, enum iocpf_event); 203 bfa_fsm_state_decl(bfa_iocpf, fail_sync, struct bfa_iocpf_s, enum iocpf_event); 204 bfa_fsm_state_decl(bfa_iocpf, fail, struct bfa_iocpf_s, enum iocpf_event); 205 bfa_fsm_state_decl(bfa_iocpf, disabling, struct bfa_iocpf_s, enum iocpf_event); 206 bfa_fsm_state_decl(bfa_iocpf, disabling_sync, struct bfa_iocpf_s, 207 enum iocpf_event); 208 bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf_s, enum iocpf_event); 209 210 static struct bfa_sm_table_s iocpf_sm_table[] = { 211 {BFA_SM(bfa_iocpf_sm_reset), BFA_IOCPF_RESET}, 212 {BFA_SM(bfa_iocpf_sm_fwcheck), BFA_IOCPF_FWMISMATCH}, 213 {BFA_SM(bfa_iocpf_sm_mismatch), BFA_IOCPF_FWMISMATCH}, 214 {BFA_SM(bfa_iocpf_sm_semwait), BFA_IOCPF_SEMWAIT}, 215 {BFA_SM(bfa_iocpf_sm_hwinit), BFA_IOCPF_HWINIT}, 216 {BFA_SM(bfa_iocpf_sm_enabling), BFA_IOCPF_HWINIT}, 217 {BFA_SM(bfa_iocpf_sm_ready), BFA_IOCPF_READY}, 218 {BFA_SM(bfa_iocpf_sm_initfail_sync), BFA_IOCPF_INITFAIL}, 219 {BFA_SM(bfa_iocpf_sm_initfail), BFA_IOCPF_INITFAIL}, 220 {BFA_SM(bfa_iocpf_sm_fail_sync), BFA_IOCPF_FAIL}, 221 {BFA_SM(bfa_iocpf_sm_fail), BFA_IOCPF_FAIL}, 222 {BFA_SM(bfa_iocpf_sm_disabling), BFA_IOCPF_DISABLING}, 223 {BFA_SM(bfa_iocpf_sm_disabling_sync), BFA_IOCPF_DISABLING}, 224 {BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED}, 225 }; 226 227 /* 228 * IOC State Machine 229 */ 230 231 /* 232 * Beginning state. IOC uninit state. 233 */ 234 235 static void 236 bfa_ioc_sm_uninit_entry(struct bfa_ioc_s *ioc) 237 { 238 } 239 240 /* 241 * IOC is in uninit state. 242 */ 243 static void 244 bfa_ioc_sm_uninit(struct bfa_ioc_s *ioc, enum ioc_event event) 245 { 246 bfa_trc(ioc, event); 247 248 switch (event) { 249 case IOC_E_RESET: 250 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); 251 break; 252 253 default: 254 bfa_sm_fault(ioc, event); 255 } 256 } 257 /* 258 * Reset entry actions -- initialize state machine 259 */ 260 static void 261 bfa_ioc_sm_reset_entry(struct bfa_ioc_s *ioc) 262 { 263 bfa_fsm_set_state(&ioc->iocpf, bfa_iocpf_sm_reset); 264 } 265 266 /* 267 * IOC is in reset state. 268 */ 269 static void 270 bfa_ioc_sm_reset(struct bfa_ioc_s *ioc, enum ioc_event event) 271 { 272 bfa_trc(ioc, event); 273 274 switch (event) { 275 case IOC_E_ENABLE: 276 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); 277 break; 278 279 case IOC_E_DISABLE: 280 bfa_ioc_disable_comp(ioc); 281 break; 282 283 case IOC_E_DETACH: 284 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 285 break; 286 287 default: 288 bfa_sm_fault(ioc, event); 289 } 290 } 291 292 293 static void 294 bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc) 295 { 296 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE); 297 } 298 299 /* 300 * Host IOC function is being enabled, awaiting response from firmware. 301 * Semaphore is acquired. 302 */ 303 static void 304 bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event) 305 { 306 bfa_trc(ioc, event); 307 308 switch (event) { 309 case IOC_E_ENABLED: 310 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); 311 break; 312 313 case IOC_E_PFFAILED: 314 /* !!! fall through !!! */ 315 case IOC_E_HWERROR: 316 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 317 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); 318 if (event != IOC_E_PFFAILED) 319 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); 320 break; 321 322 case IOC_E_DISABLE: 323 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 324 break; 325 326 case IOC_E_DETACH: 327 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 328 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP); 329 break; 330 331 case IOC_E_ENABLE: 332 break; 333 334 default: 335 bfa_sm_fault(ioc, event); 336 } 337 } 338 339 340 static void 341 bfa_ioc_sm_getattr_entry(struct bfa_ioc_s *ioc) 342 { 343 bfa_ioc_timer_start(ioc); 344 bfa_ioc_send_getattr(ioc); 345 } 346 347 /* 348 * IOC configuration in progress. Timer is active. 349 */ 350 static void 351 bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event) 352 { 353 bfa_trc(ioc, event); 354 355 switch (event) { 356 case IOC_E_FWRSP_GETATTR: 357 bfa_ioc_timer_stop(ioc); 358 bfa_ioc_check_attr_wwns(ioc); 359 bfa_fsm_set_state(ioc, bfa_ioc_sm_op); 360 break; 361 362 break; 363 case IOC_E_PFFAILED: 364 case IOC_E_HWERROR: 365 bfa_ioc_timer_stop(ioc); 366 /* !!! fall through !!! */ 367 case IOC_E_TIMEOUT: 368 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 369 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); 370 if (event != IOC_E_PFFAILED) 371 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL); 372 break; 373 374 case IOC_E_DISABLE: 375 bfa_ioc_timer_stop(ioc); 376 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 377 break; 378 379 case IOC_E_ENABLE: 380 break; 381 382 default: 383 bfa_sm_fault(ioc, event); 384 } 385 } 386 387 388 static void 389 bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc) 390 { 391 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 392 393 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); 394 bfa_ioc_hb_monitor(ioc); 395 BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n"); 396 } 397 398 static void 399 bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event) 400 { 401 bfa_trc(ioc, event); 402 403 switch (event) { 404 case IOC_E_ENABLE: 405 break; 406 407 case IOC_E_DISABLE: 408 bfa_hb_timer_stop(ioc); 409 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 410 break; 411 412 case IOC_E_PFFAILED: 413 case IOC_E_HWERROR: 414 bfa_hb_timer_stop(ioc); 415 /* !!! fall through !!! */ 416 case IOC_E_HBFAIL: 417 bfa_ioc_fail_notify(ioc); 418 419 if (ioc->iocpf.auto_recover) 420 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); 421 else 422 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 423 424 if (event != IOC_E_PFFAILED) 425 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL); 426 break; 427 428 default: 429 bfa_sm_fault(ioc, event); 430 } 431 } 432 433 434 static void 435 bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc) 436 { 437 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 438 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE); 439 BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n"); 440 } 441 442 /* 443 * IOC is being disabled 444 */ 445 static void 446 bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event) 447 { 448 bfa_trc(ioc, event); 449 450 switch (event) { 451 case IOC_E_DISABLED: 452 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); 453 break; 454 455 case IOC_E_HWERROR: 456 /* 457 * No state change. Will move to disabled state 458 * after iocpf sm completes failure processing and 459 * moves to disabled state. 460 */ 461 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL); 462 break; 463 464 default: 465 bfa_sm_fault(ioc, event); 466 } 467 } 468 469 /* 470 * IOC disable completion entry. 471 */ 472 static void 473 bfa_ioc_sm_disabled_entry(struct bfa_ioc_s *ioc) 474 { 475 bfa_ioc_disable_comp(ioc); 476 } 477 478 static void 479 bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event) 480 { 481 bfa_trc(ioc, event); 482 483 switch (event) { 484 case IOC_E_ENABLE: 485 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); 486 break; 487 488 case IOC_E_DISABLE: 489 ioc->cbfn->disable_cbfn(ioc->bfa); 490 break; 491 492 case IOC_E_DETACH: 493 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 494 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP); 495 break; 496 497 default: 498 bfa_sm_fault(ioc, event); 499 } 500 } 501 502 503 static void 504 bfa_ioc_sm_fail_retry_entry(struct bfa_ioc_s *ioc) 505 { 506 bfa_trc(ioc, 0); 507 } 508 509 /* 510 * Hardware initialization retry. 511 */ 512 static void 513 bfa_ioc_sm_fail_retry(struct bfa_ioc_s *ioc, enum ioc_event event) 514 { 515 bfa_trc(ioc, event); 516 517 switch (event) { 518 case IOC_E_ENABLED: 519 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); 520 break; 521 522 case IOC_E_PFFAILED: 523 case IOC_E_HWERROR: 524 /* 525 * Initialization retry failed. 526 */ 527 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 528 if (event != IOC_E_PFFAILED) 529 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); 530 break; 531 532 case IOC_E_INITFAILED: 533 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 534 break; 535 536 case IOC_E_ENABLE: 537 break; 538 539 case IOC_E_DISABLE: 540 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 541 break; 542 543 case IOC_E_DETACH: 544 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 545 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP); 546 break; 547 548 default: 549 bfa_sm_fault(ioc, event); 550 } 551 } 552 553 554 static void 555 bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc) 556 { 557 bfa_trc(ioc, 0); 558 } 559 560 /* 561 * IOC failure. 562 */ 563 static void 564 bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event) 565 { 566 bfa_trc(ioc, event); 567 568 switch (event) { 569 570 case IOC_E_ENABLE: 571 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 572 break; 573 574 case IOC_E_DISABLE: 575 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 576 break; 577 578 case IOC_E_DETACH: 579 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 580 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP); 581 break; 582 583 case IOC_E_HWERROR: 584 /* 585 * HB failure notification, ignore. 586 */ 587 break; 588 default: 589 bfa_sm_fault(ioc, event); 590 } 591 } 592 593 /* 594 * IOCPF State Machine 595 */ 596 597 /* 598 * Reset entry actions -- initialize state machine 599 */ 600 static void 601 bfa_iocpf_sm_reset_entry(struct bfa_iocpf_s *iocpf) 602 { 603 iocpf->retry_count = 0; 604 iocpf->auto_recover = bfa_auto_recover; 605 } 606 607 /* 608 * Beginning state. IOC is in reset state. 609 */ 610 static void 611 bfa_iocpf_sm_reset(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 612 { 613 struct bfa_ioc_s *ioc = iocpf->ioc; 614 615 bfa_trc(ioc, event); 616 617 switch (event) { 618 case IOCPF_E_ENABLE: 619 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck); 620 break; 621 622 case IOCPF_E_STOP: 623 break; 624 625 default: 626 bfa_sm_fault(ioc, event); 627 } 628 } 629 630 /* 631 * Semaphore should be acquired for version check. 632 */ 633 static void 634 bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf) 635 { 636 bfa_ioc_hw_sem_get(iocpf->ioc); 637 } 638 639 /* 640 * Awaiting h/w semaphore to continue with version check. 641 */ 642 static void 643 bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 644 { 645 struct bfa_ioc_s *ioc = iocpf->ioc; 646 647 bfa_trc(ioc, event); 648 649 switch (event) { 650 case IOCPF_E_SEMLOCKED: 651 if (bfa_ioc_firmware_lock(ioc)) { 652 if (bfa_ioc_sync_start(ioc)) { 653 iocpf->retry_count = 0; 654 bfa_ioc_sync_join(ioc); 655 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 656 } else { 657 bfa_ioc_firmware_unlock(ioc); 658 writel(1, ioc->ioc_regs.ioc_sem_reg); 659 bfa_sem_timer_start(ioc); 660 } 661 } else { 662 writel(1, ioc->ioc_regs.ioc_sem_reg); 663 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_mismatch); 664 } 665 break; 666 667 case IOCPF_E_DISABLE: 668 bfa_sem_timer_stop(ioc); 669 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 670 bfa_fsm_send_event(ioc, IOC_E_DISABLED); 671 break; 672 673 case IOCPF_E_STOP: 674 bfa_sem_timer_stop(ioc); 675 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 676 break; 677 678 default: 679 bfa_sm_fault(ioc, event); 680 } 681 } 682 683 /* 684 * Notify enable completion callback. 685 */ 686 static void 687 bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf_s *iocpf) 688 { 689 /* 690 * Call only the first time sm enters fwmismatch state. 691 */ 692 if (iocpf->retry_count == 0) 693 bfa_ioc_pf_fwmismatch(iocpf->ioc); 694 695 iocpf->retry_count++; 696 bfa_iocpf_timer_start(iocpf->ioc); 697 } 698 699 /* 700 * Awaiting firmware version match. 701 */ 702 static void 703 bfa_iocpf_sm_mismatch(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 704 { 705 struct bfa_ioc_s *ioc = iocpf->ioc; 706 707 bfa_trc(ioc, event); 708 709 switch (event) { 710 case IOCPF_E_TIMEOUT: 711 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck); 712 break; 713 714 case IOCPF_E_DISABLE: 715 bfa_iocpf_timer_stop(ioc); 716 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 717 bfa_fsm_send_event(ioc, IOC_E_DISABLED); 718 break; 719 720 case IOCPF_E_STOP: 721 bfa_iocpf_timer_stop(ioc); 722 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 723 break; 724 725 default: 726 bfa_sm_fault(ioc, event); 727 } 728 } 729 730 /* 731 * Request for semaphore. 732 */ 733 static void 734 bfa_iocpf_sm_semwait_entry(struct bfa_iocpf_s *iocpf) 735 { 736 bfa_ioc_hw_sem_get(iocpf->ioc); 737 } 738 739 /* 740 * Awaiting semaphore for h/w initialzation. 741 */ 742 static void 743 bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 744 { 745 struct bfa_ioc_s *ioc = iocpf->ioc; 746 747 bfa_trc(ioc, event); 748 749 switch (event) { 750 case IOCPF_E_SEMLOCKED: 751 if (bfa_ioc_sync_complete(ioc)) { 752 bfa_ioc_sync_join(ioc); 753 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 754 } else { 755 writel(1, ioc->ioc_regs.ioc_sem_reg); 756 bfa_sem_timer_start(ioc); 757 } 758 break; 759 760 case IOCPF_E_DISABLE: 761 bfa_sem_timer_stop(ioc); 762 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 763 break; 764 765 default: 766 bfa_sm_fault(ioc, event); 767 } 768 } 769 770 static void 771 bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf_s *iocpf) 772 { 773 bfa_iocpf_timer_start(iocpf->ioc); 774 bfa_ioc_hwinit(iocpf->ioc, BFA_FALSE); 775 } 776 777 /* 778 * Hardware is being initialized. Interrupts are enabled. 779 * Holding hardware semaphore lock. 780 */ 781 static void 782 bfa_iocpf_sm_hwinit(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 783 { 784 struct bfa_ioc_s *ioc = iocpf->ioc; 785 786 bfa_trc(ioc, event); 787 788 switch (event) { 789 case IOCPF_E_FWREADY: 790 bfa_iocpf_timer_stop(ioc); 791 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling); 792 break; 793 794 case IOCPF_E_INITFAIL: 795 bfa_iocpf_timer_stop(ioc); 796 /* 797 * !!! fall through !!! 798 */ 799 800 case IOCPF_E_TIMEOUT: 801 writel(1, ioc->ioc_regs.ioc_sem_reg); 802 if (event == IOCPF_E_TIMEOUT) 803 bfa_fsm_send_event(ioc, IOC_E_PFFAILED); 804 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 805 break; 806 807 case IOCPF_E_DISABLE: 808 bfa_iocpf_timer_stop(ioc); 809 bfa_ioc_sync_leave(ioc); 810 writel(1, ioc->ioc_regs.ioc_sem_reg); 811 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 812 break; 813 814 default: 815 bfa_sm_fault(ioc, event); 816 } 817 } 818 819 static void 820 bfa_iocpf_sm_enabling_entry(struct bfa_iocpf_s *iocpf) 821 { 822 bfa_iocpf_timer_start(iocpf->ioc); 823 bfa_ioc_send_enable(iocpf->ioc); 824 } 825 826 /* 827 * Host IOC function is being enabled, awaiting response from firmware. 828 * Semaphore is acquired. 829 */ 830 static void 831 bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 832 { 833 struct bfa_ioc_s *ioc = iocpf->ioc; 834 835 bfa_trc(ioc, event); 836 837 switch (event) { 838 case IOCPF_E_FWRSP_ENABLE: 839 bfa_iocpf_timer_stop(ioc); 840 writel(1, ioc->ioc_regs.ioc_sem_reg); 841 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready); 842 break; 843 844 case IOCPF_E_INITFAIL: 845 bfa_iocpf_timer_stop(ioc); 846 /* 847 * !!! fall through !!! 848 */ 849 850 case IOCPF_E_TIMEOUT: 851 writel(1, ioc->ioc_regs.ioc_sem_reg); 852 if (event == IOCPF_E_TIMEOUT) 853 bfa_fsm_send_event(ioc, IOC_E_PFFAILED); 854 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 855 break; 856 857 case IOCPF_E_DISABLE: 858 bfa_iocpf_timer_stop(ioc); 859 writel(1, ioc->ioc_regs.ioc_sem_reg); 860 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling); 861 break; 862 863 case IOCPF_E_FWREADY: 864 bfa_ioc_send_enable(ioc); 865 break; 866 867 default: 868 bfa_sm_fault(ioc, event); 869 } 870 } 871 872 static void 873 bfa_iocpf_sm_ready_entry(struct bfa_iocpf_s *iocpf) 874 { 875 bfa_fsm_send_event(iocpf->ioc, IOC_E_ENABLED); 876 } 877 878 static void 879 bfa_iocpf_sm_ready(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 880 { 881 struct bfa_ioc_s *ioc = iocpf->ioc; 882 883 bfa_trc(ioc, event); 884 885 switch (event) { 886 case IOCPF_E_DISABLE: 887 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling); 888 break; 889 890 case IOCPF_E_GETATTRFAIL: 891 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 892 break; 893 894 case IOCPF_E_FAIL: 895 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync); 896 break; 897 898 case IOCPF_E_FWREADY: 899 if (bfa_ioc_is_operational(ioc)) { 900 bfa_fsm_send_event(ioc, IOC_E_PFFAILED); 901 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync); 902 } else { 903 bfa_fsm_send_event(ioc, IOC_E_PFFAILED); 904 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 905 } 906 break; 907 908 default: 909 bfa_sm_fault(ioc, event); 910 } 911 } 912 913 static void 914 bfa_iocpf_sm_disabling_entry(struct bfa_iocpf_s *iocpf) 915 { 916 bfa_iocpf_timer_start(iocpf->ioc); 917 bfa_ioc_send_disable(iocpf->ioc); 918 } 919 920 /* 921 * IOC is being disabled 922 */ 923 static void 924 bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 925 { 926 struct bfa_ioc_s *ioc = iocpf->ioc; 927 928 bfa_trc(ioc, event); 929 930 switch (event) { 931 case IOCPF_E_FWRSP_DISABLE: 932 case IOCPF_E_FWREADY: 933 bfa_iocpf_timer_stop(ioc); 934 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 935 break; 936 937 case IOCPF_E_FAIL: 938 bfa_iocpf_timer_stop(ioc); 939 /* 940 * !!! fall through !!! 941 */ 942 943 case IOCPF_E_TIMEOUT: 944 writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); 945 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 946 break; 947 948 case IOCPF_E_FWRSP_ENABLE: 949 break; 950 951 default: 952 bfa_sm_fault(ioc, event); 953 } 954 } 955 956 static void 957 bfa_iocpf_sm_disabling_sync_entry(struct bfa_iocpf_s *iocpf) 958 { 959 bfa_ioc_hw_sem_get(iocpf->ioc); 960 } 961 962 /* 963 * IOC hb ack request is being removed. 964 */ 965 static void 966 bfa_iocpf_sm_disabling_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 967 { 968 struct bfa_ioc_s *ioc = iocpf->ioc; 969 970 bfa_trc(ioc, event); 971 972 switch (event) { 973 case IOCPF_E_SEMLOCKED: 974 bfa_ioc_sync_leave(ioc); 975 writel(1, ioc->ioc_regs.ioc_sem_reg); 976 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 977 break; 978 979 case IOCPF_E_FAIL: 980 break; 981 982 default: 983 bfa_sm_fault(ioc, event); 984 } 985 } 986 987 /* 988 * IOC disable completion entry. 989 */ 990 static void 991 bfa_iocpf_sm_disabled_entry(struct bfa_iocpf_s *iocpf) 992 { 993 bfa_fsm_send_event(iocpf->ioc, IOC_E_DISABLED); 994 } 995 996 static void 997 bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 998 { 999 struct bfa_ioc_s *ioc = iocpf->ioc; 1000 1001 bfa_trc(ioc, event); 1002 1003 switch (event) { 1004 case IOCPF_E_ENABLE: 1005 iocpf->retry_count = 0; 1006 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); 1007 break; 1008 1009 case IOCPF_E_STOP: 1010 bfa_ioc_firmware_unlock(ioc); 1011 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 1012 break; 1013 1014 default: 1015 bfa_sm_fault(ioc, event); 1016 } 1017 } 1018 1019 static void 1020 bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf_s *iocpf) 1021 { 1022 bfa_ioc_hw_sem_get(iocpf->ioc); 1023 } 1024 1025 /* 1026 * Hardware initialization failed. 1027 */ 1028 static void 1029 bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 1030 { 1031 struct bfa_ioc_s *ioc = iocpf->ioc; 1032 1033 bfa_trc(ioc, event); 1034 1035 switch (event) { 1036 case IOCPF_E_SEMLOCKED: 1037 bfa_ioc_notify_fail(ioc); 1038 bfa_ioc_sync_ack(ioc); 1039 iocpf->retry_count++; 1040 if (iocpf->retry_count >= BFA_IOC_HWINIT_MAX) { 1041 bfa_ioc_sync_leave(ioc); 1042 writel(1, ioc->ioc_regs.ioc_sem_reg); 1043 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); 1044 } else { 1045 if (bfa_ioc_sync_complete(ioc)) 1046 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 1047 else { 1048 writel(1, ioc->ioc_regs.ioc_sem_reg); 1049 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); 1050 } 1051 } 1052 break; 1053 1054 case IOCPF_E_DISABLE: 1055 bfa_sem_timer_stop(ioc); 1056 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 1057 break; 1058 1059 case IOCPF_E_STOP: 1060 bfa_sem_timer_stop(ioc); 1061 bfa_ioc_firmware_unlock(ioc); 1062 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 1063 break; 1064 1065 case IOCPF_E_FAIL: 1066 break; 1067 1068 default: 1069 bfa_sm_fault(ioc, event); 1070 } 1071 } 1072 1073 static void 1074 bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf) 1075 { 1076 bfa_fsm_send_event(iocpf->ioc, IOC_E_INITFAILED); 1077 } 1078 1079 /* 1080 * Hardware initialization failed. 1081 */ 1082 static void 1083 bfa_iocpf_sm_initfail(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 1084 { 1085 struct bfa_ioc_s *ioc = iocpf->ioc; 1086 1087 bfa_trc(ioc, event); 1088 1089 switch (event) { 1090 case IOCPF_E_DISABLE: 1091 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 1092 break; 1093 1094 case IOCPF_E_STOP: 1095 bfa_ioc_firmware_unlock(ioc); 1096 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 1097 break; 1098 1099 default: 1100 bfa_sm_fault(ioc, event); 1101 } 1102 } 1103 1104 static void 1105 bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf_s *iocpf) 1106 { 1107 /* 1108 * Mark IOC as failed in hardware and stop firmware. 1109 */ 1110 bfa_ioc_lpu_stop(iocpf->ioc); 1111 1112 /* 1113 * Flush any queued up mailbox requests. 1114 */ 1115 bfa_ioc_mbox_hbfail(iocpf->ioc); 1116 1117 bfa_ioc_hw_sem_get(iocpf->ioc); 1118 } 1119 1120 static void 1121 bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 1122 { 1123 struct bfa_ioc_s *ioc = iocpf->ioc; 1124 1125 bfa_trc(ioc, event); 1126 1127 switch (event) { 1128 case IOCPF_E_SEMLOCKED: 1129 iocpf->retry_count = 0; 1130 bfa_ioc_sync_ack(ioc); 1131 bfa_ioc_notify_fail(ioc); 1132 if (!iocpf->auto_recover) { 1133 bfa_ioc_sync_leave(ioc); 1134 writel(1, ioc->ioc_regs.ioc_sem_reg); 1135 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 1136 } else { 1137 if (bfa_ioc_sync_complete(ioc)) 1138 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 1139 else { 1140 writel(1, ioc->ioc_regs.ioc_sem_reg); 1141 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); 1142 } 1143 } 1144 break; 1145 1146 case IOCPF_E_DISABLE: 1147 bfa_sem_timer_stop(ioc); 1148 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 1149 break; 1150 1151 case IOCPF_E_FAIL: 1152 break; 1153 1154 default: 1155 bfa_sm_fault(ioc, event); 1156 } 1157 } 1158 1159 static void 1160 bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf) 1161 { 1162 } 1163 1164 /* 1165 * IOC is in failed state. 1166 */ 1167 static void 1168 bfa_iocpf_sm_fail(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 1169 { 1170 struct bfa_ioc_s *ioc = iocpf->ioc; 1171 1172 bfa_trc(ioc, event); 1173 1174 switch (event) { 1175 case IOCPF_E_DISABLE: 1176 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 1177 break; 1178 1179 default: 1180 bfa_sm_fault(ioc, event); 1181 } 1182 } 1183 1184 /* 1185 * BFA IOC private functions 1186 */ 1187 1188 static void 1189 bfa_ioc_disable_comp(struct bfa_ioc_s *ioc) 1190 { 1191 struct list_head *qe; 1192 struct bfa_ioc_hbfail_notify_s *notify; 1193 1194 ioc->cbfn->disable_cbfn(ioc->bfa); 1195 1196 /* 1197 * Notify common modules registered for notification. 1198 */ 1199 list_for_each(qe, &ioc->hb_notify_q) { 1200 notify = (struct bfa_ioc_hbfail_notify_s *) qe; 1201 notify->cbfn(notify->cbarg); 1202 } 1203 } 1204 1205 bfa_boolean_t 1206 bfa_ioc_sem_get(void __iomem *sem_reg) 1207 { 1208 u32 r32; 1209 int cnt = 0; 1210 #define BFA_SEM_SPINCNT 3000 1211 1212 r32 = readl(sem_reg); 1213 1214 while (r32 && (cnt < BFA_SEM_SPINCNT)) { 1215 cnt++; 1216 udelay(2); 1217 r32 = readl(sem_reg); 1218 } 1219 1220 if (r32 == 0) 1221 return BFA_TRUE; 1222 1223 WARN_ON(cnt >= BFA_SEM_SPINCNT); 1224 return BFA_FALSE; 1225 } 1226 1227 static void 1228 bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc) 1229 { 1230 u32 r32; 1231 1232 /* 1233 * First read to the semaphore register will return 0, subsequent reads 1234 * will return 1. Semaphore is released by writing 1 to the register 1235 */ 1236 r32 = readl(ioc->ioc_regs.ioc_sem_reg); 1237 if (r32 == 0) { 1238 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED); 1239 return; 1240 } 1241 1242 bfa_sem_timer_start(ioc); 1243 } 1244 1245 /* 1246 * Initialize LPU local memory (aka secondary memory / SRAM) 1247 */ 1248 static void 1249 bfa_ioc_lmem_init(struct bfa_ioc_s *ioc) 1250 { 1251 u32 pss_ctl; 1252 int i; 1253 #define PSS_LMEM_INIT_TIME 10000 1254 1255 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1256 pss_ctl &= ~__PSS_LMEM_RESET; 1257 pss_ctl |= __PSS_LMEM_INIT_EN; 1258 1259 /* 1260 * i2c workaround 12.5khz clock 1261 */ 1262 pss_ctl |= __PSS_I2C_CLK_DIV(3UL); 1263 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1264 1265 /* 1266 * wait for memory initialization to be complete 1267 */ 1268 i = 0; 1269 do { 1270 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1271 i++; 1272 } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME)); 1273 1274 /* 1275 * If memory initialization is not successful, IOC timeout will catch 1276 * such failures. 1277 */ 1278 WARN_ON(!(pss_ctl & __PSS_LMEM_INIT_DONE)); 1279 bfa_trc(ioc, pss_ctl); 1280 1281 pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN); 1282 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1283 } 1284 1285 static void 1286 bfa_ioc_lpu_start(struct bfa_ioc_s *ioc) 1287 { 1288 u32 pss_ctl; 1289 1290 /* 1291 * Take processor out of reset. 1292 */ 1293 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1294 pss_ctl &= ~__PSS_LPU0_RESET; 1295 1296 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1297 } 1298 1299 static void 1300 bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc) 1301 { 1302 u32 pss_ctl; 1303 1304 /* 1305 * Put processors in reset. 1306 */ 1307 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1308 pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET); 1309 1310 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1311 } 1312 1313 /* 1314 * Get driver and firmware versions. 1315 */ 1316 void 1317 bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) 1318 { 1319 u32 pgnum, pgoff; 1320 u32 loff = 0; 1321 int i; 1322 u32 *fwsig = (u32 *) fwhdr; 1323 1324 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff); 1325 pgoff = PSS_SMEM_PGOFF(loff); 1326 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1327 1328 for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32)); 1329 i++) { 1330 fwsig[i] = 1331 bfa_mem_read(ioc->ioc_regs.smem_page_start, loff); 1332 loff += sizeof(u32); 1333 } 1334 } 1335 1336 /* 1337 * Returns TRUE if same. 1338 */ 1339 bfa_boolean_t 1340 bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) 1341 { 1342 struct bfi_ioc_image_hdr_s *drv_fwhdr; 1343 int i; 1344 1345 drv_fwhdr = (struct bfi_ioc_image_hdr_s *) 1346 bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0); 1347 1348 for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) { 1349 if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) { 1350 bfa_trc(ioc, i); 1351 bfa_trc(ioc, fwhdr->md5sum[i]); 1352 bfa_trc(ioc, drv_fwhdr->md5sum[i]); 1353 return BFA_FALSE; 1354 } 1355 } 1356 1357 bfa_trc(ioc, fwhdr->md5sum[0]); 1358 return BFA_TRUE; 1359 } 1360 1361 /* 1362 * Return true if current running version is valid. Firmware signature and 1363 * execution context (driver/bios) must match. 1364 */ 1365 static bfa_boolean_t 1366 bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env) 1367 { 1368 struct bfi_ioc_image_hdr_s fwhdr, *drv_fwhdr; 1369 1370 bfa_ioc_fwver_get(ioc, &fwhdr); 1371 drv_fwhdr = (struct bfi_ioc_image_hdr_s *) 1372 bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0); 1373 1374 if (fwhdr.signature != drv_fwhdr->signature) { 1375 bfa_trc(ioc, fwhdr.signature); 1376 bfa_trc(ioc, drv_fwhdr->signature); 1377 return BFA_FALSE; 1378 } 1379 1380 if (swab32(fwhdr.param) != boot_env) { 1381 bfa_trc(ioc, fwhdr.param); 1382 bfa_trc(ioc, boot_env); 1383 return BFA_FALSE; 1384 } 1385 1386 return bfa_ioc_fwver_cmp(ioc, &fwhdr); 1387 } 1388 1389 /* 1390 * Conditionally flush any pending message from firmware at start. 1391 */ 1392 static void 1393 bfa_ioc_msgflush(struct bfa_ioc_s *ioc) 1394 { 1395 u32 r32; 1396 1397 r32 = readl(ioc->ioc_regs.lpu_mbox_cmd); 1398 if (r32) 1399 writel(1, ioc->ioc_regs.lpu_mbox_cmd); 1400 } 1401 1402 static void 1403 bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force) 1404 { 1405 enum bfi_ioc_state ioc_fwstate; 1406 bfa_boolean_t fwvalid; 1407 u32 boot_type; 1408 u32 boot_env; 1409 1410 ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate); 1411 1412 if (force) 1413 ioc_fwstate = BFI_IOC_UNINIT; 1414 1415 bfa_trc(ioc, ioc_fwstate); 1416 1417 boot_type = BFI_BOOT_TYPE_NORMAL; 1418 boot_env = BFI_BOOT_LOADER_OS; 1419 1420 /* 1421 * check if firmware is valid 1422 */ 1423 fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ? 1424 BFA_FALSE : bfa_ioc_fwver_valid(ioc, boot_env); 1425 1426 if (!fwvalid) { 1427 bfa_ioc_boot(ioc, boot_type, boot_env); 1428 return; 1429 } 1430 1431 /* 1432 * If hardware initialization is in progress (initialized by other IOC), 1433 * just wait for an initialization completion interrupt. 1434 */ 1435 if (ioc_fwstate == BFI_IOC_INITING) { 1436 ioc->cbfn->reset_cbfn(ioc->bfa); 1437 return; 1438 } 1439 1440 /* 1441 * If IOC function is disabled and firmware version is same, 1442 * just re-enable IOC. 1443 * 1444 * If option rom, IOC must not be in operational state. With 1445 * convergence, IOC will be in operational state when 2nd driver 1446 * is loaded. 1447 */ 1448 if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) { 1449 1450 /* 1451 * When using MSI-X any pending firmware ready event should 1452 * be flushed. Otherwise MSI-X interrupts are not delivered. 1453 */ 1454 bfa_ioc_msgflush(ioc); 1455 ioc->cbfn->reset_cbfn(ioc->bfa); 1456 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY); 1457 return; 1458 } 1459 1460 /* 1461 * Initialize the h/w for any other states. 1462 */ 1463 bfa_ioc_boot(ioc, boot_type, boot_env); 1464 } 1465 1466 static void 1467 bfa_ioc_timeout(void *ioc_arg) 1468 { 1469 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg; 1470 1471 bfa_trc(ioc, 0); 1472 bfa_fsm_send_event(ioc, IOC_E_TIMEOUT); 1473 } 1474 1475 void 1476 bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len) 1477 { 1478 u32 *msgp = (u32 *) ioc_msg; 1479 u32 i; 1480 1481 bfa_trc(ioc, msgp[0]); 1482 bfa_trc(ioc, len); 1483 1484 WARN_ON(len > BFI_IOC_MSGLEN_MAX); 1485 1486 /* 1487 * first write msg to mailbox registers 1488 */ 1489 for (i = 0; i < len / sizeof(u32); i++) 1490 writel(cpu_to_le32(msgp[i]), 1491 ioc->ioc_regs.hfn_mbox + i * sizeof(u32)); 1492 1493 for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++) 1494 writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32)); 1495 1496 /* 1497 * write 1 to mailbox CMD to trigger LPU event 1498 */ 1499 writel(1, ioc->ioc_regs.hfn_mbox_cmd); 1500 (void) readl(ioc->ioc_regs.hfn_mbox_cmd); 1501 } 1502 1503 static void 1504 bfa_ioc_send_enable(struct bfa_ioc_s *ioc) 1505 { 1506 struct bfi_ioc_ctrl_req_s enable_req; 1507 struct timeval tv; 1508 1509 bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ, 1510 bfa_ioc_portid(ioc)); 1511 enable_req.ioc_class = ioc->ioc_mc; 1512 do_gettimeofday(&tv); 1513 enable_req.tv_sec = be32_to_cpu(tv.tv_sec); 1514 bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s)); 1515 } 1516 1517 static void 1518 bfa_ioc_send_disable(struct bfa_ioc_s *ioc) 1519 { 1520 struct bfi_ioc_ctrl_req_s disable_req; 1521 1522 bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ, 1523 bfa_ioc_portid(ioc)); 1524 bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req_s)); 1525 } 1526 1527 static void 1528 bfa_ioc_send_getattr(struct bfa_ioc_s *ioc) 1529 { 1530 struct bfi_ioc_getattr_req_s attr_req; 1531 1532 bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ, 1533 bfa_ioc_portid(ioc)); 1534 bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa); 1535 bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req)); 1536 } 1537 1538 static void 1539 bfa_ioc_hb_check(void *cbarg) 1540 { 1541 struct bfa_ioc_s *ioc = cbarg; 1542 u32 hb_count; 1543 1544 hb_count = readl(ioc->ioc_regs.heartbeat); 1545 if (ioc->hb_count == hb_count) { 1546 bfa_ioc_recover(ioc); 1547 return; 1548 } else { 1549 ioc->hb_count = hb_count; 1550 } 1551 1552 bfa_ioc_mbox_poll(ioc); 1553 bfa_hb_timer_start(ioc); 1554 } 1555 1556 static void 1557 bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc) 1558 { 1559 ioc->hb_count = readl(ioc->ioc_regs.heartbeat); 1560 bfa_hb_timer_start(ioc); 1561 } 1562 1563 /* 1564 * Initiate a full firmware download. 1565 */ 1566 static void 1567 bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, 1568 u32 boot_env) 1569 { 1570 u32 *fwimg; 1571 u32 pgnum, pgoff; 1572 u32 loff = 0; 1573 u32 chunkno = 0; 1574 u32 i; 1575 1576 /* 1577 * Initialize LMEM first before code download 1578 */ 1579 bfa_ioc_lmem_init(ioc); 1580 1581 bfa_trc(ioc, bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc))); 1582 fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno); 1583 1584 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff); 1585 pgoff = PSS_SMEM_PGOFF(loff); 1586 1587 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1588 1589 for (i = 0; i < bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)); i++) { 1590 1591 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) { 1592 chunkno = BFA_IOC_FLASH_CHUNK_NO(i); 1593 fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 1594 BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); 1595 } 1596 1597 /* 1598 * write smem 1599 */ 1600 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 1601 fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]); 1602 1603 loff += sizeof(u32); 1604 1605 /* 1606 * handle page offset wrap around 1607 */ 1608 loff = PSS_SMEM_PGOFF(loff); 1609 if (loff == 0) { 1610 pgnum++; 1611 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1612 } 1613 } 1614 1615 writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0), 1616 ioc->ioc_regs.host_page_num_fn); 1617 1618 /* 1619 * Set boot type and boot param at the end. 1620 */ 1621 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_TYPE_OFF, 1622 swab32(boot_type)); 1623 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_LOADER_OFF, 1624 swab32(boot_env)); 1625 } 1626 1627 1628 /* 1629 * Update BFA configuration from firmware configuration. 1630 */ 1631 static void 1632 bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc) 1633 { 1634 struct bfi_ioc_attr_s *attr = ioc->attr; 1635 1636 attr->adapter_prop = be32_to_cpu(attr->adapter_prop); 1637 attr->card_type = be32_to_cpu(attr->card_type); 1638 attr->maxfrsize = be16_to_cpu(attr->maxfrsize); 1639 1640 bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); 1641 } 1642 1643 /* 1644 * Attach time initialization of mbox logic. 1645 */ 1646 static void 1647 bfa_ioc_mbox_attach(struct bfa_ioc_s *ioc) 1648 { 1649 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 1650 int mc; 1651 1652 INIT_LIST_HEAD(&mod->cmd_q); 1653 for (mc = 0; mc < BFI_MC_MAX; mc++) { 1654 mod->mbhdlr[mc].cbfn = NULL; 1655 mod->mbhdlr[mc].cbarg = ioc->bfa; 1656 } 1657 } 1658 1659 /* 1660 * Mbox poll timer -- restarts any pending mailbox requests. 1661 */ 1662 static void 1663 bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc) 1664 { 1665 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 1666 struct bfa_mbox_cmd_s *cmd; 1667 u32 stat; 1668 1669 /* 1670 * If no command pending, do nothing 1671 */ 1672 if (list_empty(&mod->cmd_q)) 1673 return; 1674 1675 /* 1676 * If previous command is not yet fetched by firmware, do nothing 1677 */ 1678 stat = readl(ioc->ioc_regs.hfn_mbox_cmd); 1679 if (stat) 1680 return; 1681 1682 /* 1683 * Enqueue command to firmware. 1684 */ 1685 bfa_q_deq(&mod->cmd_q, &cmd); 1686 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); 1687 } 1688 1689 /* 1690 * Cleanup any pending requests. 1691 */ 1692 static void 1693 bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc) 1694 { 1695 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 1696 struct bfa_mbox_cmd_s *cmd; 1697 1698 while (!list_empty(&mod->cmd_q)) 1699 bfa_q_deq(&mod->cmd_q, &cmd); 1700 } 1701 1702 /* 1703 * Read data from SMEM to host through PCI memmap 1704 * 1705 * @param[in] ioc memory for IOC 1706 * @param[in] tbuf app memory to store data from smem 1707 * @param[in] soff smem offset 1708 * @param[in] sz size of smem in bytes 1709 */ 1710 static bfa_status_t 1711 bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz) 1712 { 1713 u32 pgnum, loff; 1714 __be32 r32; 1715 int i, len; 1716 u32 *buf = tbuf; 1717 1718 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff); 1719 loff = PSS_SMEM_PGOFF(soff); 1720 bfa_trc(ioc, pgnum); 1721 bfa_trc(ioc, loff); 1722 bfa_trc(ioc, sz); 1723 1724 /* 1725 * Hold semaphore to serialize pll init and fwtrc. 1726 */ 1727 if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) { 1728 bfa_trc(ioc, 0); 1729 return BFA_STATUS_FAILED; 1730 } 1731 1732 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1733 1734 len = sz/sizeof(u32); 1735 bfa_trc(ioc, len); 1736 for (i = 0; i < len; i++) { 1737 r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff); 1738 buf[i] = be32_to_cpu(r32); 1739 loff += sizeof(u32); 1740 1741 /* 1742 * handle page offset wrap around 1743 */ 1744 loff = PSS_SMEM_PGOFF(loff); 1745 if (loff == 0) { 1746 pgnum++; 1747 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1748 } 1749 } 1750 writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0), 1751 ioc->ioc_regs.host_page_num_fn); 1752 /* 1753 * release semaphore. 1754 */ 1755 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 1756 1757 bfa_trc(ioc, pgnum); 1758 return BFA_STATUS_OK; 1759 } 1760 1761 /* 1762 * Clear SMEM data from host through PCI memmap 1763 * 1764 * @param[in] ioc memory for IOC 1765 * @param[in] soff smem offset 1766 * @param[in] sz size of smem in bytes 1767 */ 1768 static bfa_status_t 1769 bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz) 1770 { 1771 int i, len; 1772 u32 pgnum, loff; 1773 1774 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff); 1775 loff = PSS_SMEM_PGOFF(soff); 1776 bfa_trc(ioc, pgnum); 1777 bfa_trc(ioc, loff); 1778 bfa_trc(ioc, sz); 1779 1780 /* 1781 * Hold semaphore to serialize pll init and fwtrc. 1782 */ 1783 if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) { 1784 bfa_trc(ioc, 0); 1785 return BFA_STATUS_FAILED; 1786 } 1787 1788 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1789 1790 len = sz/sizeof(u32); /* len in words */ 1791 bfa_trc(ioc, len); 1792 for (i = 0; i < len; i++) { 1793 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 0); 1794 loff += sizeof(u32); 1795 1796 /* 1797 * handle page offset wrap around 1798 */ 1799 loff = PSS_SMEM_PGOFF(loff); 1800 if (loff == 0) { 1801 pgnum++; 1802 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1803 } 1804 } 1805 writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0), 1806 ioc->ioc_regs.host_page_num_fn); 1807 1808 /* 1809 * release semaphore. 1810 */ 1811 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 1812 bfa_trc(ioc, pgnum); 1813 return BFA_STATUS_OK; 1814 } 1815 1816 static void 1817 bfa_ioc_fail_notify(struct bfa_ioc_s *ioc) 1818 { 1819 struct list_head *qe; 1820 struct bfa_ioc_hbfail_notify_s *notify; 1821 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 1822 1823 /* 1824 * Notify driver and common modules registered for notification. 1825 */ 1826 ioc->cbfn->hbfail_cbfn(ioc->bfa); 1827 list_for_each(qe, &ioc->hb_notify_q) { 1828 notify = (struct bfa_ioc_hbfail_notify_s *) qe; 1829 notify->cbfn(notify->cbarg); 1830 } 1831 1832 bfa_ioc_debug_save_ftrc(ioc); 1833 1834 BFA_LOG(KERN_CRIT, bfad, bfa_log_level, 1835 "Heart Beat of IOC has failed\n"); 1836 1837 } 1838 1839 static void 1840 bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc) 1841 { 1842 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 1843 /* 1844 * Provide enable completion callback. 1845 */ 1846 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 1847 BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 1848 "Running firmware version is incompatible " 1849 "with the driver version\n"); 1850 } 1851 1852 bfa_status_t 1853 bfa_ioc_pll_init(struct bfa_ioc_s *ioc) 1854 { 1855 1856 /* 1857 * Hold semaphore so that nobody can access the chip during init. 1858 */ 1859 bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); 1860 1861 bfa_ioc_pll_init_asic(ioc); 1862 1863 ioc->pllinit = BFA_TRUE; 1864 /* 1865 * release semaphore. 1866 */ 1867 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 1868 1869 return BFA_STATUS_OK; 1870 } 1871 1872 /* 1873 * Interface used by diag module to do firmware boot with memory test 1874 * as the entry vector. 1875 */ 1876 void 1877 bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env) 1878 { 1879 void __iomem *rb; 1880 1881 bfa_ioc_stats(ioc, ioc_boots); 1882 1883 if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK) 1884 return; 1885 1886 /* 1887 * Initialize IOC state of all functions on a chip reset. 1888 */ 1889 rb = ioc->pcidev.pci_bar_kva; 1890 if (boot_type == BFI_BOOT_TYPE_MEMTEST) { 1891 writel(BFI_IOC_MEMTEST, (rb + BFA_IOC0_STATE_REG)); 1892 writel(BFI_IOC_MEMTEST, (rb + BFA_IOC1_STATE_REG)); 1893 } else { 1894 writel(BFI_IOC_INITING, (rb + BFA_IOC0_STATE_REG)); 1895 writel(BFI_IOC_INITING, (rb + BFA_IOC1_STATE_REG)); 1896 } 1897 1898 bfa_ioc_msgflush(ioc); 1899 bfa_ioc_download_fw(ioc, boot_type, boot_env); 1900 1901 /* 1902 * Enable interrupts just before starting LPU 1903 */ 1904 ioc->cbfn->reset_cbfn(ioc->bfa); 1905 bfa_ioc_lpu_start(ioc); 1906 } 1907 1908 /* 1909 * Enable/disable IOC failure auto recovery. 1910 */ 1911 void 1912 bfa_ioc_auto_recover(bfa_boolean_t auto_recover) 1913 { 1914 bfa_auto_recover = auto_recover; 1915 } 1916 1917 1918 1919 bfa_boolean_t 1920 bfa_ioc_is_operational(struct bfa_ioc_s *ioc) 1921 { 1922 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op); 1923 } 1924 1925 bfa_boolean_t 1926 bfa_ioc_is_initialized(struct bfa_ioc_s *ioc) 1927 { 1928 u32 r32 = readl(ioc->ioc_regs.ioc_fwstate); 1929 1930 return ((r32 != BFI_IOC_UNINIT) && 1931 (r32 != BFI_IOC_INITING) && 1932 (r32 != BFI_IOC_MEMTEST)); 1933 } 1934 1935 void 1936 bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg) 1937 { 1938 __be32 *msgp = mbmsg; 1939 u32 r32; 1940 int i; 1941 1942 /* 1943 * read the MBOX msg 1944 */ 1945 for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32)); 1946 i++) { 1947 r32 = readl(ioc->ioc_regs.lpu_mbox + 1948 i * sizeof(u32)); 1949 msgp[i] = cpu_to_be32(r32); 1950 } 1951 1952 /* 1953 * turn off mailbox interrupt by clearing mailbox status 1954 */ 1955 writel(1, ioc->ioc_regs.lpu_mbox_cmd); 1956 readl(ioc->ioc_regs.lpu_mbox_cmd); 1957 } 1958 1959 void 1960 bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m) 1961 { 1962 union bfi_ioc_i2h_msg_u *msg; 1963 struct bfa_iocpf_s *iocpf = &ioc->iocpf; 1964 1965 msg = (union bfi_ioc_i2h_msg_u *) m; 1966 1967 bfa_ioc_stats(ioc, ioc_isrs); 1968 1969 switch (msg->mh.msg_id) { 1970 case BFI_IOC_I2H_HBEAT: 1971 break; 1972 1973 case BFI_IOC_I2H_READY_EVENT: 1974 bfa_fsm_send_event(iocpf, IOCPF_E_FWREADY); 1975 break; 1976 1977 case BFI_IOC_I2H_ENABLE_REPLY: 1978 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE); 1979 break; 1980 1981 case BFI_IOC_I2H_DISABLE_REPLY: 1982 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_DISABLE); 1983 break; 1984 1985 case BFI_IOC_I2H_GETATTR_REPLY: 1986 bfa_ioc_getattr_reply(ioc); 1987 break; 1988 1989 default: 1990 bfa_trc(ioc, msg->mh.msg_id); 1991 WARN_ON(1); 1992 } 1993 } 1994 1995 /* 1996 * IOC attach time initialization and setup. 1997 * 1998 * @param[in] ioc memory for IOC 1999 * @param[in] bfa driver instance structure 2000 */ 2001 void 2002 bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn, 2003 struct bfa_timer_mod_s *timer_mod) 2004 { 2005 ioc->bfa = bfa; 2006 ioc->cbfn = cbfn; 2007 ioc->timer_mod = timer_mod; 2008 ioc->fcmode = BFA_FALSE; 2009 ioc->pllinit = BFA_FALSE; 2010 ioc->dbg_fwsave_once = BFA_TRUE; 2011 ioc->iocpf.ioc = ioc; 2012 2013 bfa_ioc_mbox_attach(ioc); 2014 INIT_LIST_HEAD(&ioc->hb_notify_q); 2015 2016 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 2017 bfa_fsm_send_event(ioc, IOC_E_RESET); 2018 } 2019 2020 /* 2021 * Driver detach time IOC cleanup. 2022 */ 2023 void 2024 bfa_ioc_detach(struct bfa_ioc_s *ioc) 2025 { 2026 bfa_fsm_send_event(ioc, IOC_E_DETACH); 2027 } 2028 2029 /* 2030 * Setup IOC PCI properties. 2031 * 2032 * @param[in] pcidev PCI device information for this IOC 2033 */ 2034 void 2035 bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev, 2036 enum bfi_mclass mc) 2037 { 2038 ioc->ioc_mc = mc; 2039 ioc->pcidev = *pcidev; 2040 ioc->ctdev = bfa_asic_id_ct(ioc->pcidev.device_id); 2041 ioc->cna = ioc->ctdev && !ioc->fcmode; 2042 2043 /* 2044 * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c 2045 */ 2046 if (ioc->ctdev) 2047 bfa_ioc_set_ct_hwif(ioc); 2048 else 2049 bfa_ioc_set_cb_hwif(ioc); 2050 2051 bfa_ioc_map_port(ioc); 2052 bfa_ioc_reg_init(ioc); 2053 } 2054 2055 /* 2056 * Initialize IOC dma memory 2057 * 2058 * @param[in] dm_kva kernel virtual address of IOC dma memory 2059 * @param[in] dm_pa physical address of IOC dma memory 2060 */ 2061 void 2062 bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa) 2063 { 2064 /* 2065 * dma memory for firmware attribute 2066 */ 2067 ioc->attr_dma.kva = dm_kva; 2068 ioc->attr_dma.pa = dm_pa; 2069 ioc->attr = (struct bfi_ioc_attr_s *) dm_kva; 2070 } 2071 2072 void 2073 bfa_ioc_enable(struct bfa_ioc_s *ioc) 2074 { 2075 bfa_ioc_stats(ioc, ioc_enables); 2076 ioc->dbg_fwsave_once = BFA_TRUE; 2077 2078 bfa_fsm_send_event(ioc, IOC_E_ENABLE); 2079 } 2080 2081 void 2082 bfa_ioc_disable(struct bfa_ioc_s *ioc) 2083 { 2084 bfa_ioc_stats(ioc, ioc_disables); 2085 bfa_fsm_send_event(ioc, IOC_E_DISABLE); 2086 } 2087 2088 2089 /* 2090 * Initialize memory for saving firmware trace. Driver must initialize 2091 * trace memory before call bfa_ioc_enable(). 2092 */ 2093 void 2094 bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave) 2095 { 2096 ioc->dbg_fwsave = dbg_fwsave; 2097 ioc->dbg_fwsave_len = (ioc->iocpf.auto_recover) ? BFA_DBG_FWTRC_LEN : 0; 2098 } 2099 2100 /* 2101 * Register mailbox message handler functions 2102 * 2103 * @param[in] ioc IOC instance 2104 * @param[in] mcfuncs message class handler functions 2105 */ 2106 void 2107 bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs) 2108 { 2109 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2110 int mc; 2111 2112 for (mc = 0; mc < BFI_MC_MAX; mc++) 2113 mod->mbhdlr[mc].cbfn = mcfuncs[mc]; 2114 } 2115 2116 /* 2117 * Register mailbox message handler function, to be called by common modules 2118 */ 2119 void 2120 bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc, 2121 bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg) 2122 { 2123 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2124 2125 mod->mbhdlr[mc].cbfn = cbfn; 2126 mod->mbhdlr[mc].cbarg = cbarg; 2127 } 2128 2129 /* 2130 * Queue a mailbox command request to firmware. Waits if mailbox is busy. 2131 * Responsibility of caller to serialize 2132 * 2133 * @param[in] ioc IOC instance 2134 * @param[i] cmd Mailbox command 2135 */ 2136 void 2137 bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd) 2138 { 2139 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2140 u32 stat; 2141 2142 /* 2143 * If a previous command is pending, queue new command 2144 */ 2145 if (!list_empty(&mod->cmd_q)) { 2146 list_add_tail(&cmd->qe, &mod->cmd_q); 2147 return; 2148 } 2149 2150 /* 2151 * If mailbox is busy, queue command for poll timer 2152 */ 2153 stat = readl(ioc->ioc_regs.hfn_mbox_cmd); 2154 if (stat) { 2155 list_add_tail(&cmd->qe, &mod->cmd_q); 2156 return; 2157 } 2158 2159 /* 2160 * mailbox is free -- queue command to firmware 2161 */ 2162 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); 2163 } 2164 2165 /* 2166 * Handle mailbox interrupts 2167 */ 2168 void 2169 bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc) 2170 { 2171 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2172 struct bfi_mbmsg_s m; 2173 int mc; 2174 2175 bfa_ioc_msgget(ioc, &m); 2176 2177 /* 2178 * Treat IOC message class as special. 2179 */ 2180 mc = m.mh.msg_class; 2181 if (mc == BFI_MC_IOC) { 2182 bfa_ioc_isr(ioc, &m); 2183 return; 2184 } 2185 2186 if ((mc > BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL)) 2187 return; 2188 2189 mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m); 2190 } 2191 2192 void 2193 bfa_ioc_error_isr(struct bfa_ioc_s *ioc) 2194 { 2195 bfa_fsm_send_event(ioc, IOC_E_HWERROR); 2196 } 2197 2198 void 2199 bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc) 2200 { 2201 ioc->fcmode = BFA_TRUE; 2202 ioc->port_id = bfa_ioc_pcifn(ioc); 2203 } 2204 2205 /* 2206 * return true if IOC is disabled 2207 */ 2208 bfa_boolean_t 2209 bfa_ioc_is_disabled(struct bfa_ioc_s *ioc) 2210 { 2211 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) || 2212 bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled); 2213 } 2214 2215 /* 2216 * return true if IOC firmware is different. 2217 */ 2218 bfa_boolean_t 2219 bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc) 2220 { 2221 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset) || 2222 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_fwcheck) || 2223 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_mismatch); 2224 } 2225 2226 #define bfa_ioc_state_disabled(__sm) \ 2227 (((__sm) == BFI_IOC_UNINIT) || \ 2228 ((__sm) == BFI_IOC_INITING) || \ 2229 ((__sm) == BFI_IOC_HWINIT) || \ 2230 ((__sm) == BFI_IOC_DISABLED) || \ 2231 ((__sm) == BFI_IOC_FAIL) || \ 2232 ((__sm) == BFI_IOC_CFG_DISABLED)) 2233 2234 /* 2235 * Check if adapter is disabled -- both IOCs should be in a disabled 2236 * state. 2237 */ 2238 bfa_boolean_t 2239 bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc) 2240 { 2241 u32 ioc_state; 2242 void __iomem *rb = ioc->pcidev.pci_bar_kva; 2243 2244 if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled)) 2245 return BFA_FALSE; 2246 2247 ioc_state = readl(rb + BFA_IOC0_STATE_REG); 2248 if (!bfa_ioc_state_disabled(ioc_state)) 2249 return BFA_FALSE; 2250 2251 if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_FC_8G1P) { 2252 ioc_state = readl(rb + BFA_IOC1_STATE_REG); 2253 if (!bfa_ioc_state_disabled(ioc_state)) 2254 return BFA_FALSE; 2255 } 2256 2257 return BFA_TRUE; 2258 } 2259 2260 /* 2261 * Reset IOC fwstate registers. 2262 */ 2263 void 2264 bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc) 2265 { 2266 writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate); 2267 writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate); 2268 } 2269 2270 #define BFA_MFG_NAME "Brocade" 2271 void 2272 bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, 2273 struct bfa_adapter_attr_s *ad_attr) 2274 { 2275 struct bfi_ioc_attr_s *ioc_attr; 2276 2277 ioc_attr = ioc->attr; 2278 2279 bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num); 2280 bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver); 2281 bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver); 2282 bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer); 2283 memcpy(&ad_attr->vpd, &ioc_attr->vpd, 2284 sizeof(struct bfa_mfg_vpd_s)); 2285 2286 ad_attr->nports = bfa_ioc_get_nports(ioc); 2287 ad_attr->max_speed = bfa_ioc_speed_sup(ioc); 2288 2289 bfa_ioc_get_adapter_model(ioc, ad_attr->model); 2290 /* For now, model descr uses same model string */ 2291 bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr); 2292 2293 ad_attr->card_type = ioc_attr->card_type; 2294 ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type); 2295 2296 if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop)) 2297 ad_attr->prototype = 1; 2298 else 2299 ad_attr->prototype = 0; 2300 2301 ad_attr->pwwn = ioc->attr->pwwn; 2302 ad_attr->mac = bfa_ioc_get_mac(ioc); 2303 2304 ad_attr->pcie_gen = ioc_attr->pcie_gen; 2305 ad_attr->pcie_lanes = ioc_attr->pcie_lanes; 2306 ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig; 2307 ad_attr->asic_rev = ioc_attr->asic_rev; 2308 2309 bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver); 2310 2311 ad_attr->cna_capable = ioc->cna; 2312 ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna && 2313 !ad_attr->is_mezz; 2314 } 2315 2316 enum bfa_ioc_type_e 2317 bfa_ioc_get_type(struct bfa_ioc_s *ioc) 2318 { 2319 if (!ioc->ctdev || ioc->fcmode) 2320 return BFA_IOC_TYPE_FC; 2321 else if (ioc->ioc_mc == BFI_MC_IOCFC) 2322 return BFA_IOC_TYPE_FCoE; 2323 else if (ioc->ioc_mc == BFI_MC_LL) 2324 return BFA_IOC_TYPE_LL; 2325 else { 2326 WARN_ON(ioc->ioc_mc != BFI_MC_LL); 2327 return BFA_IOC_TYPE_LL; 2328 } 2329 } 2330 2331 void 2332 bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num) 2333 { 2334 memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN); 2335 memcpy((void *)serial_num, 2336 (void *)ioc->attr->brcd_serialnum, 2337 BFA_ADAPTER_SERIAL_NUM_LEN); 2338 } 2339 2340 void 2341 bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver) 2342 { 2343 memset((void *)fw_ver, 0, BFA_VERSION_LEN); 2344 memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN); 2345 } 2346 2347 void 2348 bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev) 2349 { 2350 WARN_ON(!chip_rev); 2351 2352 memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN); 2353 2354 chip_rev[0] = 'R'; 2355 chip_rev[1] = 'e'; 2356 chip_rev[2] = 'v'; 2357 chip_rev[3] = '-'; 2358 chip_rev[4] = ioc->attr->asic_rev; 2359 chip_rev[5] = '\0'; 2360 } 2361 2362 void 2363 bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver) 2364 { 2365 memset((void *)optrom_ver, 0, BFA_VERSION_LEN); 2366 memcpy(optrom_ver, ioc->attr->optrom_version, 2367 BFA_VERSION_LEN); 2368 } 2369 2370 void 2371 bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer) 2372 { 2373 memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN); 2374 memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); 2375 } 2376 2377 void 2378 bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model) 2379 { 2380 struct bfi_ioc_attr_s *ioc_attr; 2381 2382 WARN_ON(!model); 2383 memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN); 2384 2385 ioc_attr = ioc->attr; 2386 2387 /* 2388 * model name 2389 */ 2390 snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u", 2391 BFA_MFG_NAME, ioc_attr->card_type); 2392 } 2393 2394 enum bfa_ioc_state 2395 bfa_ioc_get_state(struct bfa_ioc_s *ioc) 2396 { 2397 enum bfa_iocpf_state iocpf_st; 2398 enum bfa_ioc_state ioc_st = bfa_sm_to_state(ioc_sm_table, ioc->fsm); 2399 2400 if (ioc_st == BFA_IOC_ENABLING || 2401 ioc_st == BFA_IOC_FAIL || ioc_st == BFA_IOC_INITFAIL) { 2402 2403 iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm); 2404 2405 switch (iocpf_st) { 2406 case BFA_IOCPF_SEMWAIT: 2407 ioc_st = BFA_IOC_SEMWAIT; 2408 break; 2409 2410 case BFA_IOCPF_HWINIT: 2411 ioc_st = BFA_IOC_HWINIT; 2412 break; 2413 2414 case BFA_IOCPF_FWMISMATCH: 2415 ioc_st = BFA_IOC_FWMISMATCH; 2416 break; 2417 2418 case BFA_IOCPF_FAIL: 2419 ioc_st = BFA_IOC_FAIL; 2420 break; 2421 2422 case BFA_IOCPF_INITFAIL: 2423 ioc_st = BFA_IOC_INITFAIL; 2424 break; 2425 2426 default: 2427 break; 2428 } 2429 } 2430 2431 return ioc_st; 2432 } 2433 2434 void 2435 bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) 2436 { 2437 memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s)); 2438 2439 ioc_attr->state = bfa_ioc_get_state(ioc); 2440 ioc_attr->port_id = ioc->port_id; 2441 2442 ioc_attr->ioc_type = bfa_ioc_get_type(ioc); 2443 2444 bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr); 2445 2446 ioc_attr->pci_attr.device_id = ioc->pcidev.device_id; 2447 ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func; 2448 bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev); 2449 } 2450 2451 mac_t 2452 bfa_ioc_get_mac(struct bfa_ioc_s *ioc) 2453 { 2454 /* 2455 * Check the IOC type and return the appropriate MAC 2456 */ 2457 if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE) 2458 return ioc->attr->fcoe_mac; 2459 else 2460 return ioc->attr->mac; 2461 } 2462 2463 mac_t 2464 bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc) 2465 { 2466 mac_t m; 2467 2468 m = ioc->attr->mfg_mac; 2469 if (bfa_mfg_is_old_wwn_mac_model(ioc->attr->card_type)) 2470 m.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc); 2471 else 2472 bfa_mfg_increment_wwn_mac(&(m.mac[MAC_ADDRLEN-3]), 2473 bfa_ioc_pcifn(ioc)); 2474 2475 return m; 2476 } 2477 2478 bfa_boolean_t 2479 bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc) 2480 { 2481 return ioc->fcmode || !bfa_asic_id_ct(ioc->pcidev.device_id); 2482 } 2483 2484 /* 2485 * Retrieve saved firmware trace from a prior IOC failure. 2486 */ 2487 bfa_status_t 2488 bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) 2489 { 2490 int tlen; 2491 2492 if (ioc->dbg_fwsave_len == 0) 2493 return BFA_STATUS_ENOFSAVE; 2494 2495 tlen = *trclen; 2496 if (tlen > ioc->dbg_fwsave_len) 2497 tlen = ioc->dbg_fwsave_len; 2498 2499 memcpy(trcdata, ioc->dbg_fwsave, tlen); 2500 *trclen = tlen; 2501 return BFA_STATUS_OK; 2502 } 2503 2504 2505 /* 2506 * Retrieve saved firmware trace from a prior IOC failure. 2507 */ 2508 bfa_status_t 2509 bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) 2510 { 2511 u32 loff = BFA_DBG_FWTRC_OFF(bfa_ioc_portid(ioc)); 2512 int tlen; 2513 bfa_status_t status; 2514 2515 bfa_trc(ioc, *trclen); 2516 2517 tlen = *trclen; 2518 if (tlen > BFA_DBG_FWTRC_LEN) 2519 tlen = BFA_DBG_FWTRC_LEN; 2520 2521 status = bfa_ioc_smem_read(ioc, trcdata, loff, tlen); 2522 *trclen = tlen; 2523 return status; 2524 } 2525 2526 static void 2527 bfa_ioc_send_fwsync(struct bfa_ioc_s *ioc) 2528 { 2529 struct bfa_mbox_cmd_s cmd; 2530 struct bfi_ioc_ctrl_req_s *req = (struct bfi_ioc_ctrl_req_s *) cmd.msg; 2531 2532 bfi_h2i_set(req->mh, BFI_MC_IOC, BFI_IOC_H2I_DBG_SYNC, 2533 bfa_ioc_portid(ioc)); 2534 req->ioc_class = ioc->ioc_mc; 2535 bfa_ioc_mbox_queue(ioc, &cmd); 2536 } 2537 2538 static void 2539 bfa_ioc_fwsync(struct bfa_ioc_s *ioc) 2540 { 2541 u32 fwsync_iter = 1000; 2542 2543 bfa_ioc_send_fwsync(ioc); 2544 2545 /* 2546 * After sending a fw sync mbox command wait for it to 2547 * take effect. We will not wait for a response because 2548 * 1. fw_sync mbox cmd doesn't have a response. 2549 * 2. Even if we implement that, interrupts might not 2550 * be enabled when we call this function. 2551 * So, just keep checking if any mbox cmd is pending, and 2552 * after waiting for a reasonable amount of time, go ahead. 2553 * It is possible that fw has crashed and the mbox command 2554 * is never acknowledged. 2555 */ 2556 while (bfa_ioc_mbox_cmd_pending(ioc) && fwsync_iter > 0) 2557 fwsync_iter--; 2558 } 2559 2560 /* 2561 * Dump firmware smem 2562 */ 2563 bfa_status_t 2564 bfa_ioc_debug_fwcore(struct bfa_ioc_s *ioc, void *buf, 2565 u32 *offset, int *buflen) 2566 { 2567 u32 loff; 2568 int dlen; 2569 bfa_status_t status; 2570 u32 smem_len = BFA_IOC_FW_SMEM_SIZE(ioc); 2571 2572 if (*offset >= smem_len) { 2573 *offset = *buflen = 0; 2574 return BFA_STATUS_EINVAL; 2575 } 2576 2577 loff = *offset; 2578 dlen = *buflen; 2579 2580 /* 2581 * First smem read, sync smem before proceeding 2582 * No need to sync before reading every chunk. 2583 */ 2584 if (loff == 0) 2585 bfa_ioc_fwsync(ioc); 2586 2587 if ((loff + dlen) >= smem_len) 2588 dlen = smem_len - loff; 2589 2590 status = bfa_ioc_smem_read(ioc, buf, loff, dlen); 2591 2592 if (status != BFA_STATUS_OK) { 2593 *offset = *buflen = 0; 2594 return status; 2595 } 2596 2597 *offset += dlen; 2598 2599 if (*offset >= smem_len) 2600 *offset = 0; 2601 2602 *buflen = dlen; 2603 2604 return status; 2605 } 2606 2607 /* 2608 * Firmware statistics 2609 */ 2610 bfa_status_t 2611 bfa_ioc_fw_stats_get(struct bfa_ioc_s *ioc, void *stats) 2612 { 2613 u32 loff = BFI_IOC_FWSTATS_OFF + \ 2614 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc)); 2615 int tlen; 2616 bfa_status_t status; 2617 2618 if (ioc->stats_busy) { 2619 bfa_trc(ioc, ioc->stats_busy); 2620 return BFA_STATUS_DEVBUSY; 2621 } 2622 ioc->stats_busy = BFA_TRUE; 2623 2624 tlen = sizeof(struct bfa_fw_stats_s); 2625 status = bfa_ioc_smem_read(ioc, stats, loff, tlen); 2626 2627 ioc->stats_busy = BFA_FALSE; 2628 return status; 2629 } 2630 2631 bfa_status_t 2632 bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc) 2633 { 2634 u32 loff = BFI_IOC_FWSTATS_OFF + \ 2635 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc)); 2636 int tlen; 2637 bfa_status_t status; 2638 2639 if (ioc->stats_busy) { 2640 bfa_trc(ioc, ioc->stats_busy); 2641 return BFA_STATUS_DEVBUSY; 2642 } 2643 ioc->stats_busy = BFA_TRUE; 2644 2645 tlen = sizeof(struct bfa_fw_stats_s); 2646 status = bfa_ioc_smem_clr(ioc, loff, tlen); 2647 2648 ioc->stats_busy = BFA_FALSE; 2649 return status; 2650 } 2651 2652 /* 2653 * Save firmware trace if configured. 2654 */ 2655 static void 2656 bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc) 2657 { 2658 int tlen; 2659 2660 if (ioc->dbg_fwsave_once) { 2661 ioc->dbg_fwsave_once = BFA_FALSE; 2662 if (ioc->dbg_fwsave_len) { 2663 tlen = ioc->dbg_fwsave_len; 2664 bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen); 2665 } 2666 } 2667 } 2668 2669 /* 2670 * Firmware failure detected. Start recovery actions. 2671 */ 2672 static void 2673 bfa_ioc_recover(struct bfa_ioc_s *ioc) 2674 { 2675 bfa_ioc_stats(ioc, ioc_hbfails); 2676 bfa_fsm_send_event(ioc, IOC_E_HBFAIL); 2677 } 2678 2679 static void 2680 bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc) 2681 { 2682 if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL) 2683 return; 2684 } 2685 2686 /* 2687 * BFA IOC PF private functions 2688 */ 2689 static void 2690 bfa_iocpf_timeout(void *ioc_arg) 2691 { 2692 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg; 2693 2694 bfa_trc(ioc, 0); 2695 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT); 2696 } 2697 2698 static void 2699 bfa_iocpf_sem_timeout(void *ioc_arg) 2700 { 2701 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg; 2702 2703 bfa_ioc_hw_sem_get(ioc); 2704 } 2705 2706 /* 2707 * bfa timer function 2708 */ 2709 void 2710 bfa_timer_beat(struct bfa_timer_mod_s *mod) 2711 { 2712 struct list_head *qh = &mod->timer_q; 2713 struct list_head *qe, *qe_next; 2714 struct bfa_timer_s *elem; 2715 struct list_head timedout_q; 2716 2717 INIT_LIST_HEAD(&timedout_q); 2718 2719 qe = bfa_q_next(qh); 2720 2721 while (qe != qh) { 2722 qe_next = bfa_q_next(qe); 2723 2724 elem = (struct bfa_timer_s *) qe; 2725 if (elem->timeout <= BFA_TIMER_FREQ) { 2726 elem->timeout = 0; 2727 list_del(&elem->qe); 2728 list_add_tail(&elem->qe, &timedout_q); 2729 } else { 2730 elem->timeout -= BFA_TIMER_FREQ; 2731 } 2732 2733 qe = qe_next; /* go to next elem */ 2734 } 2735 2736 /* 2737 * Pop all the timeout entries 2738 */ 2739 while (!list_empty(&timedout_q)) { 2740 bfa_q_deq(&timedout_q, &elem); 2741 elem->timercb(elem->arg); 2742 } 2743 } 2744 2745 /* 2746 * Should be called with lock protection 2747 */ 2748 void 2749 bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer, 2750 void (*timercb) (void *), void *arg, unsigned int timeout) 2751 { 2752 2753 WARN_ON(timercb == NULL); 2754 WARN_ON(bfa_q_is_on_q(&mod->timer_q, timer)); 2755 2756 timer->timeout = timeout; 2757 timer->timercb = timercb; 2758 timer->arg = arg; 2759 2760 list_add_tail(&timer->qe, &mod->timer_q); 2761 } 2762 2763 /* 2764 * Should be called with lock protection 2765 */ 2766 void 2767 bfa_timer_stop(struct bfa_timer_s *timer) 2768 { 2769 WARN_ON(list_empty(&timer->qe)); 2770 2771 list_del(&timer->qe); 2772 } 2773