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 "bfad_im.h" 20 #include "bfa_ioc.h" 21 #include "bfi_reg.h" 22 #include "bfa_defs.h" 23 #include "bfa_defs_svc.h" 24 25 BFA_TRC_FILE(CNA, IOC); 26 27 /* 28 * IOC local definitions 29 */ 30 #define BFA_IOC_TOV 3000 /* msecs */ 31 #define BFA_IOC_HWSEM_TOV 500 /* msecs */ 32 #define BFA_IOC_HB_TOV 500 /* msecs */ 33 #define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV 34 #define BFA_IOC_POLL_TOV BFA_TIMER_FREQ 35 36 #define bfa_ioc_timer_start(__ioc) \ 37 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ 38 bfa_ioc_timeout, (__ioc), BFA_IOC_TOV) 39 #define bfa_ioc_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->ioc_timer) 40 41 #define bfa_hb_timer_start(__ioc) \ 42 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->hb_timer, \ 43 bfa_ioc_hb_check, (__ioc), BFA_IOC_HB_TOV) 44 #define bfa_hb_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->hb_timer) 45 46 #define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn)) 47 48 /* 49 * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details. 50 */ 51 52 #define bfa_ioc_firmware_lock(__ioc) \ 53 ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc)) 54 #define bfa_ioc_firmware_unlock(__ioc) \ 55 ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc)) 56 #define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc)) 57 #define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc)) 58 #define bfa_ioc_notify_fail(__ioc) \ 59 ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc)) 60 #define bfa_ioc_sync_start(__ioc) \ 61 ((__ioc)->ioc_hwif->ioc_sync_start(__ioc)) 62 #define bfa_ioc_sync_join(__ioc) \ 63 ((__ioc)->ioc_hwif->ioc_sync_join(__ioc)) 64 #define bfa_ioc_sync_leave(__ioc) \ 65 ((__ioc)->ioc_hwif->ioc_sync_leave(__ioc)) 66 #define bfa_ioc_sync_ack(__ioc) \ 67 ((__ioc)->ioc_hwif->ioc_sync_ack(__ioc)) 68 #define bfa_ioc_sync_complete(__ioc) \ 69 ((__ioc)->ioc_hwif->ioc_sync_complete(__ioc)) 70 71 #define bfa_ioc_mbox_cmd_pending(__ioc) \ 72 (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \ 73 readl((__ioc)->ioc_regs.hfn_mbox_cmd)) 74 75 bfa_boolean_t bfa_auto_recover = BFA_TRUE; 76 77 /* 78 * forward declarations 79 */ 80 static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc); 81 static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force); 82 static void bfa_ioc_timeout(void *ioc); 83 static void bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc); 84 static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc); 85 static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc); 86 static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc); 87 static void bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc); 88 static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc); 89 static void bfa_ioc_mbox_flush(struct bfa_ioc_s *ioc); 90 static void bfa_ioc_recover(struct bfa_ioc_s *ioc); 91 static void bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc); 92 static void bfa_ioc_event_notify(struct bfa_ioc_s *ioc , 93 enum bfa_ioc_event_e event); 94 static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc); 95 static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc); 96 static void bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc); 97 static void bfa_ioc_fail_notify(struct bfa_ioc_s *ioc); 98 static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc); 99 100 101 /* 102 * IOC state machine definitions/declarations 103 */ 104 enum ioc_event { 105 IOC_E_RESET = 1, /* IOC reset request */ 106 IOC_E_ENABLE = 2, /* IOC enable request */ 107 IOC_E_DISABLE = 3, /* IOC disable request */ 108 IOC_E_DETACH = 4, /* driver detach cleanup */ 109 IOC_E_ENABLED = 5, /* f/w enabled */ 110 IOC_E_FWRSP_GETATTR = 6, /* IOC get attribute response */ 111 IOC_E_DISABLED = 7, /* f/w disabled */ 112 IOC_E_PFFAILED = 8, /* failure notice by iocpf sm */ 113 IOC_E_HBFAIL = 9, /* heartbeat failure */ 114 IOC_E_HWERROR = 10, /* hardware error interrupt */ 115 IOC_E_TIMEOUT = 11, /* timeout */ 116 IOC_E_HWFAILED = 12, /* PCI mapping failure notice */ 117 IOC_E_FWRSP_ACQ_ADDR = 13, /* Acquiring address */ 118 }; 119 120 bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event); 121 bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event); 122 bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event); 123 bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event); 124 bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event); 125 bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc_s, enum ioc_event); 126 bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event); 127 bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event); 128 bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event); 129 bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc_s, enum ioc_event); 130 bfa_fsm_state_decl(bfa_ioc, acq_addr, struct bfa_ioc_s, enum ioc_event); 131 132 static struct bfa_sm_table_s ioc_sm_table[] = { 133 {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT}, 134 {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET}, 135 {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING}, 136 {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR}, 137 {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL}, 138 {BFA_SM(bfa_ioc_sm_fail_retry), BFA_IOC_INITFAIL}, 139 {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL}, 140 {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, 141 {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, 142 {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL}, 143 {BFA_SM(bfa_ioc_sm_acq_addr), BFA_IOC_ACQ_ADDR}, 144 }; 145 146 /* 147 * IOCPF state machine definitions/declarations 148 */ 149 150 #define bfa_iocpf_timer_start(__ioc) \ 151 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ 152 bfa_iocpf_timeout, (__ioc), BFA_IOC_TOV) 153 #define bfa_iocpf_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->ioc_timer) 154 155 #define bfa_iocpf_poll_timer_start(__ioc) \ 156 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ 157 bfa_iocpf_poll_timeout, (__ioc), BFA_IOC_POLL_TOV) 158 159 #define bfa_sem_timer_start(__ioc) \ 160 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->sem_timer, \ 161 bfa_iocpf_sem_timeout, (__ioc), BFA_IOC_HWSEM_TOV) 162 #define bfa_sem_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->sem_timer) 163 164 /* 165 * Forward declareations for iocpf state machine 166 */ 167 static void bfa_iocpf_timeout(void *ioc_arg); 168 static void bfa_iocpf_sem_timeout(void *ioc_arg); 169 static void bfa_iocpf_poll_timeout(void *ioc_arg); 170 171 /* 172 * IOCPF state machine events 173 */ 174 enum iocpf_event { 175 IOCPF_E_ENABLE = 1, /* IOCPF enable request */ 176 IOCPF_E_DISABLE = 2, /* IOCPF disable request */ 177 IOCPF_E_STOP = 3, /* stop on driver detach */ 178 IOCPF_E_FWREADY = 4, /* f/w initialization done */ 179 IOCPF_E_FWRSP_ENABLE = 5, /* enable f/w response */ 180 IOCPF_E_FWRSP_DISABLE = 6, /* disable f/w response */ 181 IOCPF_E_FAIL = 7, /* failure notice by ioc sm */ 182 IOCPF_E_INITFAIL = 8, /* init fail notice by ioc sm */ 183 IOCPF_E_GETATTRFAIL = 9, /* init fail notice by ioc sm */ 184 IOCPF_E_SEMLOCKED = 10, /* h/w semaphore is locked */ 185 IOCPF_E_TIMEOUT = 11, /* f/w response timeout */ 186 IOCPF_E_SEM_ERROR = 12, /* h/w sem mapping error */ 187 }; 188 189 /* 190 * IOCPF states 191 */ 192 enum bfa_iocpf_state { 193 BFA_IOCPF_RESET = 1, /* IOC is in reset state */ 194 BFA_IOCPF_SEMWAIT = 2, /* Waiting for IOC h/w semaphore */ 195 BFA_IOCPF_HWINIT = 3, /* IOC h/w is being initialized */ 196 BFA_IOCPF_READY = 4, /* IOCPF is initialized */ 197 BFA_IOCPF_INITFAIL = 5, /* IOCPF failed */ 198 BFA_IOCPF_FAIL = 6, /* IOCPF failed */ 199 BFA_IOCPF_DISABLING = 7, /* IOCPF is being disabled */ 200 BFA_IOCPF_DISABLED = 8, /* IOCPF is disabled */ 201 BFA_IOCPF_FWMISMATCH = 9, /* IOC f/w different from drivers */ 202 }; 203 204 bfa_fsm_state_decl(bfa_iocpf, reset, struct bfa_iocpf_s, enum iocpf_event); 205 bfa_fsm_state_decl(bfa_iocpf, fwcheck, struct bfa_iocpf_s, enum iocpf_event); 206 bfa_fsm_state_decl(bfa_iocpf, mismatch, struct bfa_iocpf_s, enum iocpf_event); 207 bfa_fsm_state_decl(bfa_iocpf, semwait, struct bfa_iocpf_s, enum iocpf_event); 208 bfa_fsm_state_decl(bfa_iocpf, hwinit, struct bfa_iocpf_s, enum iocpf_event); 209 bfa_fsm_state_decl(bfa_iocpf, enabling, struct bfa_iocpf_s, enum iocpf_event); 210 bfa_fsm_state_decl(bfa_iocpf, ready, struct bfa_iocpf_s, enum iocpf_event); 211 bfa_fsm_state_decl(bfa_iocpf, initfail_sync, struct bfa_iocpf_s, 212 enum iocpf_event); 213 bfa_fsm_state_decl(bfa_iocpf, initfail, struct bfa_iocpf_s, enum iocpf_event); 214 bfa_fsm_state_decl(bfa_iocpf, fail_sync, struct bfa_iocpf_s, enum iocpf_event); 215 bfa_fsm_state_decl(bfa_iocpf, fail, struct bfa_iocpf_s, enum iocpf_event); 216 bfa_fsm_state_decl(bfa_iocpf, disabling, struct bfa_iocpf_s, enum iocpf_event); 217 bfa_fsm_state_decl(bfa_iocpf, disabling_sync, struct bfa_iocpf_s, 218 enum iocpf_event); 219 bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf_s, enum iocpf_event); 220 221 static struct bfa_sm_table_s iocpf_sm_table[] = { 222 {BFA_SM(bfa_iocpf_sm_reset), BFA_IOCPF_RESET}, 223 {BFA_SM(bfa_iocpf_sm_fwcheck), BFA_IOCPF_FWMISMATCH}, 224 {BFA_SM(bfa_iocpf_sm_mismatch), BFA_IOCPF_FWMISMATCH}, 225 {BFA_SM(bfa_iocpf_sm_semwait), BFA_IOCPF_SEMWAIT}, 226 {BFA_SM(bfa_iocpf_sm_hwinit), BFA_IOCPF_HWINIT}, 227 {BFA_SM(bfa_iocpf_sm_enabling), BFA_IOCPF_HWINIT}, 228 {BFA_SM(bfa_iocpf_sm_ready), BFA_IOCPF_READY}, 229 {BFA_SM(bfa_iocpf_sm_initfail_sync), BFA_IOCPF_INITFAIL}, 230 {BFA_SM(bfa_iocpf_sm_initfail), BFA_IOCPF_INITFAIL}, 231 {BFA_SM(bfa_iocpf_sm_fail_sync), BFA_IOCPF_FAIL}, 232 {BFA_SM(bfa_iocpf_sm_fail), BFA_IOCPF_FAIL}, 233 {BFA_SM(bfa_iocpf_sm_disabling), BFA_IOCPF_DISABLING}, 234 {BFA_SM(bfa_iocpf_sm_disabling_sync), BFA_IOCPF_DISABLING}, 235 {BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED}, 236 }; 237 238 /* 239 * IOC State Machine 240 */ 241 242 /* 243 * Beginning state. IOC uninit state. 244 */ 245 246 static void 247 bfa_ioc_sm_uninit_entry(struct bfa_ioc_s *ioc) 248 { 249 } 250 251 /* 252 * IOC is in uninit state. 253 */ 254 static void 255 bfa_ioc_sm_uninit(struct bfa_ioc_s *ioc, enum ioc_event event) 256 { 257 bfa_trc(ioc, event); 258 259 switch (event) { 260 case IOC_E_RESET: 261 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); 262 break; 263 264 default: 265 bfa_sm_fault(ioc, event); 266 } 267 } 268 /* 269 * Reset entry actions -- initialize state machine 270 */ 271 static void 272 bfa_ioc_sm_reset_entry(struct bfa_ioc_s *ioc) 273 { 274 bfa_fsm_set_state(&ioc->iocpf, bfa_iocpf_sm_reset); 275 } 276 277 /* 278 * IOC is in reset state. 279 */ 280 static void 281 bfa_ioc_sm_reset(struct bfa_ioc_s *ioc, enum ioc_event event) 282 { 283 bfa_trc(ioc, event); 284 285 switch (event) { 286 case IOC_E_ENABLE: 287 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); 288 break; 289 290 case IOC_E_DISABLE: 291 bfa_ioc_disable_comp(ioc); 292 break; 293 294 case IOC_E_DETACH: 295 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 296 break; 297 298 default: 299 bfa_sm_fault(ioc, event); 300 } 301 } 302 303 304 static void 305 bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc) 306 { 307 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE); 308 } 309 310 /* 311 * Host IOC function is being enabled, awaiting response from firmware. 312 * Semaphore is acquired. 313 */ 314 static void 315 bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event) 316 { 317 bfa_trc(ioc, event); 318 319 switch (event) { 320 case IOC_E_ENABLED: 321 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); 322 break; 323 324 case IOC_E_PFFAILED: 325 /* !!! fall through !!! */ 326 case IOC_E_HWERROR: 327 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 328 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 329 if (event != IOC_E_PFFAILED) 330 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); 331 break; 332 333 case IOC_E_HWFAILED: 334 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 335 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail); 336 break; 337 338 case IOC_E_DISABLE: 339 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 340 break; 341 342 case IOC_E_DETACH: 343 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 344 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP); 345 break; 346 347 case IOC_E_ENABLE: 348 break; 349 350 default: 351 bfa_sm_fault(ioc, event); 352 } 353 } 354 355 356 static void 357 bfa_ioc_sm_getattr_entry(struct bfa_ioc_s *ioc) 358 { 359 bfa_ioc_timer_start(ioc); 360 bfa_ioc_send_getattr(ioc); 361 } 362 363 /* 364 * IOC configuration in progress. Timer is active. 365 */ 366 static void 367 bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event) 368 { 369 bfa_trc(ioc, event); 370 371 switch (event) { 372 case IOC_E_FWRSP_GETATTR: 373 bfa_ioc_timer_stop(ioc); 374 bfa_ioc_check_attr_wwns(ioc); 375 bfa_ioc_hb_monitor(ioc); 376 bfa_fsm_set_state(ioc, bfa_ioc_sm_op); 377 break; 378 379 case IOC_E_FWRSP_ACQ_ADDR: 380 bfa_ioc_timer_stop(ioc); 381 bfa_ioc_hb_monitor(ioc); 382 bfa_fsm_set_state(ioc, bfa_ioc_sm_acq_addr); 383 break; 384 385 case IOC_E_PFFAILED: 386 case IOC_E_HWERROR: 387 bfa_ioc_timer_stop(ioc); 388 /* !!! fall through !!! */ 389 case IOC_E_TIMEOUT: 390 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 391 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 392 if (event != IOC_E_PFFAILED) 393 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL); 394 break; 395 396 case IOC_E_DISABLE: 397 bfa_ioc_timer_stop(ioc); 398 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 399 break; 400 401 case IOC_E_ENABLE: 402 break; 403 404 default: 405 bfa_sm_fault(ioc, event); 406 } 407 } 408 409 /* 410 * Acquiring address from fabric (entry function) 411 */ 412 static void 413 bfa_ioc_sm_acq_addr_entry(struct bfa_ioc_s *ioc) 414 { 415 } 416 417 /* 418 * Acquiring address from the fabric 419 */ 420 static void 421 bfa_ioc_sm_acq_addr(struct bfa_ioc_s *ioc, enum ioc_event event) 422 { 423 bfa_trc(ioc, event); 424 425 switch (event) { 426 case IOC_E_FWRSP_GETATTR: 427 bfa_ioc_check_attr_wwns(ioc); 428 bfa_fsm_set_state(ioc, bfa_ioc_sm_op); 429 break; 430 431 case IOC_E_PFFAILED: 432 case IOC_E_HWERROR: 433 bfa_hb_timer_stop(ioc); 434 case IOC_E_HBFAIL: 435 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 436 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 437 if (event != IOC_E_PFFAILED) 438 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL); 439 break; 440 441 case IOC_E_DISABLE: 442 bfa_hb_timer_stop(ioc); 443 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 444 break; 445 446 case IOC_E_ENABLE: 447 break; 448 449 default: 450 bfa_sm_fault(ioc, event); 451 } 452 } 453 454 static void 455 bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc) 456 { 457 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 458 459 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); 460 bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED); 461 BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n"); 462 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_ENABLE); 463 } 464 465 static void 466 bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event) 467 { 468 bfa_trc(ioc, event); 469 470 switch (event) { 471 case IOC_E_ENABLE: 472 break; 473 474 case IOC_E_DISABLE: 475 bfa_hb_timer_stop(ioc); 476 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 477 break; 478 479 case IOC_E_PFFAILED: 480 case IOC_E_HWERROR: 481 bfa_hb_timer_stop(ioc); 482 /* !!! fall through !!! */ 483 case IOC_E_HBFAIL: 484 if (ioc->iocpf.auto_recover) 485 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); 486 else 487 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 488 489 bfa_ioc_fail_notify(ioc); 490 491 if (event != IOC_E_PFFAILED) 492 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL); 493 break; 494 495 default: 496 bfa_sm_fault(ioc, event); 497 } 498 } 499 500 501 static void 502 bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc) 503 { 504 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 505 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE); 506 BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n"); 507 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_DISABLE); 508 } 509 510 /* 511 * IOC is being disabled 512 */ 513 static void 514 bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event) 515 { 516 bfa_trc(ioc, event); 517 518 switch (event) { 519 case IOC_E_DISABLED: 520 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); 521 break; 522 523 case IOC_E_HWERROR: 524 /* 525 * No state change. Will move to disabled state 526 * after iocpf sm completes failure processing and 527 * moves to disabled state. 528 */ 529 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL); 530 break; 531 532 case IOC_E_HWFAILED: 533 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail); 534 bfa_ioc_disable_comp(ioc); 535 break; 536 537 default: 538 bfa_sm_fault(ioc, event); 539 } 540 } 541 542 /* 543 * IOC disable completion entry. 544 */ 545 static void 546 bfa_ioc_sm_disabled_entry(struct bfa_ioc_s *ioc) 547 { 548 bfa_ioc_disable_comp(ioc); 549 } 550 551 static void 552 bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event) 553 { 554 bfa_trc(ioc, event); 555 556 switch (event) { 557 case IOC_E_ENABLE: 558 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); 559 break; 560 561 case IOC_E_DISABLE: 562 ioc->cbfn->disable_cbfn(ioc->bfa); 563 break; 564 565 case IOC_E_DETACH: 566 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 567 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP); 568 break; 569 570 default: 571 bfa_sm_fault(ioc, event); 572 } 573 } 574 575 576 static void 577 bfa_ioc_sm_fail_retry_entry(struct bfa_ioc_s *ioc) 578 { 579 bfa_trc(ioc, 0); 580 } 581 582 /* 583 * Hardware initialization retry. 584 */ 585 static void 586 bfa_ioc_sm_fail_retry(struct bfa_ioc_s *ioc, enum ioc_event event) 587 { 588 bfa_trc(ioc, event); 589 590 switch (event) { 591 case IOC_E_ENABLED: 592 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); 593 break; 594 595 case IOC_E_PFFAILED: 596 case IOC_E_HWERROR: 597 /* 598 * Initialization retry failed. 599 */ 600 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 601 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 602 if (event != IOC_E_PFFAILED) 603 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); 604 break; 605 606 case IOC_E_HWFAILED: 607 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 608 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail); 609 break; 610 611 case IOC_E_ENABLE: 612 break; 613 614 case IOC_E_DISABLE: 615 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 616 break; 617 618 case IOC_E_DETACH: 619 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 620 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP); 621 break; 622 623 default: 624 bfa_sm_fault(ioc, event); 625 } 626 } 627 628 629 static void 630 bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc) 631 { 632 bfa_trc(ioc, 0); 633 } 634 635 /* 636 * IOC failure. 637 */ 638 static void 639 bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event) 640 { 641 bfa_trc(ioc, event); 642 643 switch (event) { 644 645 case IOC_E_ENABLE: 646 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 647 break; 648 649 case IOC_E_DISABLE: 650 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 651 break; 652 653 case IOC_E_DETACH: 654 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 655 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP); 656 break; 657 658 case IOC_E_HWERROR: 659 /* 660 * HB failure notification, ignore. 661 */ 662 break; 663 default: 664 bfa_sm_fault(ioc, event); 665 } 666 } 667 668 static void 669 bfa_ioc_sm_hwfail_entry(struct bfa_ioc_s *ioc) 670 { 671 bfa_trc(ioc, 0); 672 } 673 674 static void 675 bfa_ioc_sm_hwfail(struct bfa_ioc_s *ioc, enum ioc_event event) 676 { 677 bfa_trc(ioc, event); 678 679 switch (event) { 680 case IOC_E_ENABLE: 681 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 682 break; 683 684 case IOC_E_DISABLE: 685 ioc->cbfn->disable_cbfn(ioc->bfa); 686 break; 687 688 case IOC_E_DETACH: 689 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 690 break; 691 692 default: 693 bfa_sm_fault(ioc, event); 694 } 695 } 696 697 /* 698 * IOCPF State Machine 699 */ 700 701 /* 702 * Reset entry actions -- initialize state machine 703 */ 704 static void 705 bfa_iocpf_sm_reset_entry(struct bfa_iocpf_s *iocpf) 706 { 707 iocpf->fw_mismatch_notified = BFA_FALSE; 708 iocpf->auto_recover = bfa_auto_recover; 709 } 710 711 /* 712 * Beginning state. IOC is in reset state. 713 */ 714 static void 715 bfa_iocpf_sm_reset(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 716 { 717 struct bfa_ioc_s *ioc = iocpf->ioc; 718 719 bfa_trc(ioc, event); 720 721 switch (event) { 722 case IOCPF_E_ENABLE: 723 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck); 724 break; 725 726 case IOCPF_E_STOP: 727 break; 728 729 default: 730 bfa_sm_fault(ioc, event); 731 } 732 } 733 734 /* 735 * Semaphore should be acquired for version check. 736 */ 737 static void 738 bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf) 739 { 740 struct bfi_ioc_image_hdr_s fwhdr; 741 u32 fwstate = readl(iocpf->ioc->ioc_regs.ioc_fwstate); 742 743 /* h/w sem init */ 744 if (fwstate == BFI_IOC_UNINIT) 745 goto sem_get; 746 747 bfa_ioc_fwver_get(iocpf->ioc, &fwhdr); 748 749 if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) 750 goto sem_get; 751 752 bfa_trc(iocpf->ioc, fwstate); 753 bfa_trc(iocpf->ioc, fwhdr.exec); 754 writel(BFI_IOC_UNINIT, iocpf->ioc->ioc_regs.ioc_fwstate); 755 756 /* 757 * Try to lock and then unlock the semaphore. 758 */ 759 readl(iocpf->ioc->ioc_regs.ioc_sem_reg); 760 writel(1, iocpf->ioc->ioc_regs.ioc_sem_reg); 761 sem_get: 762 bfa_ioc_hw_sem_get(iocpf->ioc); 763 } 764 765 /* 766 * Awaiting h/w semaphore to continue with version check. 767 */ 768 static void 769 bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 770 { 771 struct bfa_ioc_s *ioc = iocpf->ioc; 772 773 bfa_trc(ioc, event); 774 775 switch (event) { 776 case IOCPF_E_SEMLOCKED: 777 if (bfa_ioc_firmware_lock(ioc)) { 778 if (bfa_ioc_sync_start(ioc)) { 779 bfa_ioc_sync_join(ioc); 780 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 781 } else { 782 bfa_ioc_firmware_unlock(ioc); 783 writel(1, ioc->ioc_regs.ioc_sem_reg); 784 bfa_sem_timer_start(ioc); 785 } 786 } else { 787 writel(1, ioc->ioc_regs.ioc_sem_reg); 788 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_mismatch); 789 } 790 break; 791 792 case IOCPF_E_SEM_ERROR: 793 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 794 bfa_fsm_send_event(ioc, IOC_E_HWFAILED); 795 break; 796 797 case IOCPF_E_DISABLE: 798 bfa_sem_timer_stop(ioc); 799 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 800 bfa_fsm_send_event(ioc, IOC_E_DISABLED); 801 break; 802 803 case IOCPF_E_STOP: 804 bfa_sem_timer_stop(ioc); 805 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 806 break; 807 808 default: 809 bfa_sm_fault(ioc, event); 810 } 811 } 812 813 /* 814 * Notify enable completion callback. 815 */ 816 static void 817 bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf_s *iocpf) 818 { 819 /* 820 * Call only the first time sm enters fwmismatch state. 821 */ 822 if (iocpf->fw_mismatch_notified == BFA_FALSE) 823 bfa_ioc_pf_fwmismatch(iocpf->ioc); 824 825 iocpf->fw_mismatch_notified = BFA_TRUE; 826 bfa_iocpf_timer_start(iocpf->ioc); 827 } 828 829 /* 830 * Awaiting firmware version match. 831 */ 832 static void 833 bfa_iocpf_sm_mismatch(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 834 { 835 struct bfa_ioc_s *ioc = iocpf->ioc; 836 837 bfa_trc(ioc, event); 838 839 switch (event) { 840 case IOCPF_E_TIMEOUT: 841 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck); 842 break; 843 844 case IOCPF_E_DISABLE: 845 bfa_iocpf_timer_stop(ioc); 846 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 847 bfa_fsm_send_event(ioc, IOC_E_DISABLED); 848 break; 849 850 case IOCPF_E_STOP: 851 bfa_iocpf_timer_stop(ioc); 852 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 853 break; 854 855 default: 856 bfa_sm_fault(ioc, event); 857 } 858 } 859 860 /* 861 * Request for semaphore. 862 */ 863 static void 864 bfa_iocpf_sm_semwait_entry(struct bfa_iocpf_s *iocpf) 865 { 866 bfa_ioc_hw_sem_get(iocpf->ioc); 867 } 868 869 /* 870 * Awaiting semaphore for h/w initialzation. 871 */ 872 static void 873 bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 874 { 875 struct bfa_ioc_s *ioc = iocpf->ioc; 876 877 bfa_trc(ioc, event); 878 879 switch (event) { 880 case IOCPF_E_SEMLOCKED: 881 if (bfa_ioc_sync_complete(ioc)) { 882 bfa_ioc_sync_join(ioc); 883 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 884 } else { 885 writel(1, ioc->ioc_regs.ioc_sem_reg); 886 bfa_sem_timer_start(ioc); 887 } 888 break; 889 890 case IOCPF_E_SEM_ERROR: 891 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 892 bfa_fsm_send_event(ioc, IOC_E_HWFAILED); 893 break; 894 895 case IOCPF_E_DISABLE: 896 bfa_sem_timer_stop(ioc); 897 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 898 break; 899 900 default: 901 bfa_sm_fault(ioc, event); 902 } 903 } 904 905 static void 906 bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf_s *iocpf) 907 { 908 iocpf->poll_time = 0; 909 bfa_ioc_hwinit(iocpf->ioc, BFA_FALSE); 910 } 911 912 /* 913 * Hardware is being initialized. Interrupts are enabled. 914 * Holding hardware semaphore lock. 915 */ 916 static void 917 bfa_iocpf_sm_hwinit(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 918 { 919 struct bfa_ioc_s *ioc = iocpf->ioc; 920 921 bfa_trc(ioc, event); 922 923 switch (event) { 924 case IOCPF_E_FWREADY: 925 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling); 926 break; 927 928 case IOCPF_E_TIMEOUT: 929 writel(1, ioc->ioc_regs.ioc_sem_reg); 930 bfa_fsm_send_event(ioc, IOC_E_PFFAILED); 931 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 932 break; 933 934 case IOCPF_E_DISABLE: 935 bfa_iocpf_timer_stop(ioc); 936 bfa_ioc_sync_leave(ioc); 937 writel(1, ioc->ioc_regs.ioc_sem_reg); 938 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 939 break; 940 941 default: 942 bfa_sm_fault(ioc, event); 943 } 944 } 945 946 static void 947 bfa_iocpf_sm_enabling_entry(struct bfa_iocpf_s *iocpf) 948 { 949 bfa_iocpf_timer_start(iocpf->ioc); 950 /* 951 * Enable Interrupts before sending fw IOC ENABLE cmd. 952 */ 953 iocpf->ioc->cbfn->reset_cbfn(iocpf->ioc->bfa); 954 bfa_ioc_send_enable(iocpf->ioc); 955 } 956 957 /* 958 * Host IOC function is being enabled, awaiting response from firmware. 959 * Semaphore is acquired. 960 */ 961 static void 962 bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 963 { 964 struct bfa_ioc_s *ioc = iocpf->ioc; 965 966 bfa_trc(ioc, event); 967 968 switch (event) { 969 case IOCPF_E_FWRSP_ENABLE: 970 bfa_iocpf_timer_stop(ioc); 971 writel(1, ioc->ioc_regs.ioc_sem_reg); 972 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready); 973 break; 974 975 case IOCPF_E_INITFAIL: 976 bfa_iocpf_timer_stop(ioc); 977 /* 978 * !!! fall through !!! 979 */ 980 981 case IOCPF_E_TIMEOUT: 982 writel(1, ioc->ioc_regs.ioc_sem_reg); 983 if (event == IOCPF_E_TIMEOUT) 984 bfa_fsm_send_event(ioc, IOC_E_PFFAILED); 985 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 986 break; 987 988 case IOCPF_E_DISABLE: 989 bfa_iocpf_timer_stop(ioc); 990 writel(1, ioc->ioc_regs.ioc_sem_reg); 991 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling); 992 break; 993 994 default: 995 bfa_sm_fault(ioc, event); 996 } 997 } 998 999 static void 1000 bfa_iocpf_sm_ready_entry(struct bfa_iocpf_s *iocpf) 1001 { 1002 bfa_fsm_send_event(iocpf->ioc, IOC_E_ENABLED); 1003 } 1004 1005 static void 1006 bfa_iocpf_sm_ready(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 1007 { 1008 struct bfa_ioc_s *ioc = iocpf->ioc; 1009 1010 bfa_trc(ioc, event); 1011 1012 switch (event) { 1013 case IOCPF_E_DISABLE: 1014 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling); 1015 break; 1016 1017 case IOCPF_E_GETATTRFAIL: 1018 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 1019 break; 1020 1021 case IOCPF_E_FAIL: 1022 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync); 1023 break; 1024 1025 default: 1026 bfa_sm_fault(ioc, event); 1027 } 1028 } 1029 1030 static void 1031 bfa_iocpf_sm_disabling_entry(struct bfa_iocpf_s *iocpf) 1032 { 1033 bfa_iocpf_timer_start(iocpf->ioc); 1034 bfa_ioc_send_disable(iocpf->ioc); 1035 } 1036 1037 /* 1038 * IOC is being disabled 1039 */ 1040 static void 1041 bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 1042 { 1043 struct bfa_ioc_s *ioc = iocpf->ioc; 1044 1045 bfa_trc(ioc, event); 1046 1047 switch (event) { 1048 case IOCPF_E_FWRSP_DISABLE: 1049 bfa_iocpf_timer_stop(ioc); 1050 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 1051 break; 1052 1053 case IOCPF_E_FAIL: 1054 bfa_iocpf_timer_stop(ioc); 1055 /* 1056 * !!! fall through !!! 1057 */ 1058 1059 case IOCPF_E_TIMEOUT: 1060 writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); 1061 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 1062 break; 1063 1064 case IOCPF_E_FWRSP_ENABLE: 1065 break; 1066 1067 default: 1068 bfa_sm_fault(ioc, event); 1069 } 1070 } 1071 1072 static void 1073 bfa_iocpf_sm_disabling_sync_entry(struct bfa_iocpf_s *iocpf) 1074 { 1075 bfa_ioc_hw_sem_get(iocpf->ioc); 1076 } 1077 1078 /* 1079 * IOC hb ack request is being removed. 1080 */ 1081 static void 1082 bfa_iocpf_sm_disabling_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 1083 { 1084 struct bfa_ioc_s *ioc = iocpf->ioc; 1085 1086 bfa_trc(ioc, event); 1087 1088 switch (event) { 1089 case IOCPF_E_SEMLOCKED: 1090 bfa_ioc_sync_leave(ioc); 1091 writel(1, ioc->ioc_regs.ioc_sem_reg); 1092 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 1093 break; 1094 1095 case IOCPF_E_SEM_ERROR: 1096 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 1097 bfa_fsm_send_event(ioc, IOC_E_HWFAILED); 1098 break; 1099 1100 case IOCPF_E_FAIL: 1101 break; 1102 1103 default: 1104 bfa_sm_fault(ioc, event); 1105 } 1106 } 1107 1108 /* 1109 * IOC disable completion entry. 1110 */ 1111 static void 1112 bfa_iocpf_sm_disabled_entry(struct bfa_iocpf_s *iocpf) 1113 { 1114 bfa_ioc_mbox_flush(iocpf->ioc); 1115 bfa_fsm_send_event(iocpf->ioc, IOC_E_DISABLED); 1116 } 1117 1118 static void 1119 bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 1120 { 1121 struct bfa_ioc_s *ioc = iocpf->ioc; 1122 1123 bfa_trc(ioc, event); 1124 1125 switch (event) { 1126 case IOCPF_E_ENABLE: 1127 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); 1128 break; 1129 1130 case IOCPF_E_STOP: 1131 bfa_ioc_firmware_unlock(ioc); 1132 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 1133 break; 1134 1135 default: 1136 bfa_sm_fault(ioc, event); 1137 } 1138 } 1139 1140 static void 1141 bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf_s *iocpf) 1142 { 1143 bfa_ioc_debug_save_ftrc(iocpf->ioc); 1144 bfa_ioc_hw_sem_get(iocpf->ioc); 1145 } 1146 1147 /* 1148 * Hardware initialization failed. 1149 */ 1150 static void 1151 bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 1152 { 1153 struct bfa_ioc_s *ioc = iocpf->ioc; 1154 1155 bfa_trc(ioc, event); 1156 1157 switch (event) { 1158 case IOCPF_E_SEMLOCKED: 1159 bfa_ioc_notify_fail(ioc); 1160 bfa_ioc_sync_leave(ioc); 1161 writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); 1162 writel(1, ioc->ioc_regs.ioc_sem_reg); 1163 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); 1164 break; 1165 1166 case IOCPF_E_SEM_ERROR: 1167 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 1168 bfa_fsm_send_event(ioc, IOC_E_HWFAILED); 1169 break; 1170 1171 case IOCPF_E_DISABLE: 1172 bfa_sem_timer_stop(ioc); 1173 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 1174 break; 1175 1176 case IOCPF_E_STOP: 1177 bfa_sem_timer_stop(ioc); 1178 bfa_ioc_firmware_unlock(ioc); 1179 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 1180 break; 1181 1182 case IOCPF_E_FAIL: 1183 break; 1184 1185 default: 1186 bfa_sm_fault(ioc, event); 1187 } 1188 } 1189 1190 static void 1191 bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf) 1192 { 1193 bfa_trc(iocpf->ioc, 0); 1194 } 1195 1196 /* 1197 * Hardware initialization failed. 1198 */ 1199 static void 1200 bfa_iocpf_sm_initfail(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 1201 { 1202 struct bfa_ioc_s *ioc = iocpf->ioc; 1203 1204 bfa_trc(ioc, event); 1205 1206 switch (event) { 1207 case IOCPF_E_DISABLE: 1208 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 1209 break; 1210 1211 case IOCPF_E_STOP: 1212 bfa_ioc_firmware_unlock(ioc); 1213 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 1214 break; 1215 1216 default: 1217 bfa_sm_fault(ioc, event); 1218 } 1219 } 1220 1221 static void 1222 bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf_s *iocpf) 1223 { 1224 /* 1225 * Mark IOC as failed in hardware and stop firmware. 1226 */ 1227 bfa_ioc_lpu_stop(iocpf->ioc); 1228 1229 /* 1230 * Flush any queued up mailbox requests. 1231 */ 1232 bfa_ioc_mbox_flush(iocpf->ioc); 1233 1234 bfa_ioc_hw_sem_get(iocpf->ioc); 1235 } 1236 1237 static void 1238 bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 1239 { 1240 struct bfa_ioc_s *ioc = iocpf->ioc; 1241 1242 bfa_trc(ioc, event); 1243 1244 switch (event) { 1245 case IOCPF_E_SEMLOCKED: 1246 bfa_ioc_sync_ack(ioc); 1247 bfa_ioc_notify_fail(ioc); 1248 if (!iocpf->auto_recover) { 1249 bfa_ioc_sync_leave(ioc); 1250 writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); 1251 writel(1, ioc->ioc_regs.ioc_sem_reg); 1252 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 1253 } else { 1254 if (bfa_ioc_sync_complete(ioc)) 1255 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 1256 else { 1257 writel(1, ioc->ioc_regs.ioc_sem_reg); 1258 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); 1259 } 1260 } 1261 break; 1262 1263 case IOCPF_E_SEM_ERROR: 1264 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 1265 bfa_fsm_send_event(ioc, IOC_E_HWFAILED); 1266 break; 1267 1268 case IOCPF_E_DISABLE: 1269 bfa_sem_timer_stop(ioc); 1270 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 1271 break; 1272 1273 case IOCPF_E_FAIL: 1274 break; 1275 1276 default: 1277 bfa_sm_fault(ioc, event); 1278 } 1279 } 1280 1281 static void 1282 bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf) 1283 { 1284 bfa_trc(iocpf->ioc, 0); 1285 } 1286 1287 /* 1288 * IOC is in failed state. 1289 */ 1290 static void 1291 bfa_iocpf_sm_fail(struct bfa_iocpf_s *iocpf, enum iocpf_event event) 1292 { 1293 struct bfa_ioc_s *ioc = iocpf->ioc; 1294 1295 bfa_trc(ioc, event); 1296 1297 switch (event) { 1298 case IOCPF_E_DISABLE: 1299 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 1300 break; 1301 1302 default: 1303 bfa_sm_fault(ioc, event); 1304 } 1305 } 1306 1307 /* 1308 * BFA IOC private functions 1309 */ 1310 1311 /* 1312 * Notify common modules registered for notification. 1313 */ 1314 static void 1315 bfa_ioc_event_notify(struct bfa_ioc_s *ioc, enum bfa_ioc_event_e event) 1316 { 1317 struct bfa_ioc_notify_s *notify; 1318 struct list_head *qe; 1319 1320 list_for_each(qe, &ioc->notify_q) { 1321 notify = (struct bfa_ioc_notify_s *)qe; 1322 notify->cbfn(notify->cbarg, event); 1323 } 1324 } 1325 1326 static void 1327 bfa_ioc_disable_comp(struct bfa_ioc_s *ioc) 1328 { 1329 ioc->cbfn->disable_cbfn(ioc->bfa); 1330 bfa_ioc_event_notify(ioc, BFA_IOC_E_DISABLED); 1331 } 1332 1333 bfa_boolean_t 1334 bfa_ioc_sem_get(void __iomem *sem_reg) 1335 { 1336 u32 r32; 1337 int cnt = 0; 1338 #define BFA_SEM_SPINCNT 3000 1339 1340 r32 = readl(sem_reg); 1341 1342 while ((r32 & 1) && (cnt < BFA_SEM_SPINCNT)) { 1343 cnt++; 1344 udelay(2); 1345 r32 = readl(sem_reg); 1346 } 1347 1348 if (!(r32 & 1)) 1349 return BFA_TRUE; 1350 1351 return BFA_FALSE; 1352 } 1353 1354 static void 1355 bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc) 1356 { 1357 u32 r32; 1358 1359 /* 1360 * First read to the semaphore register will return 0, subsequent reads 1361 * will return 1. Semaphore is released by writing 1 to the register 1362 */ 1363 r32 = readl(ioc->ioc_regs.ioc_sem_reg); 1364 if (r32 == ~0) { 1365 WARN_ON(r32 == ~0); 1366 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEM_ERROR); 1367 return; 1368 } 1369 if (!(r32 & 1)) { 1370 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED); 1371 return; 1372 } 1373 1374 bfa_sem_timer_start(ioc); 1375 } 1376 1377 /* 1378 * Initialize LPU local memory (aka secondary memory / SRAM) 1379 */ 1380 static void 1381 bfa_ioc_lmem_init(struct bfa_ioc_s *ioc) 1382 { 1383 u32 pss_ctl; 1384 int i; 1385 #define PSS_LMEM_INIT_TIME 10000 1386 1387 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1388 pss_ctl &= ~__PSS_LMEM_RESET; 1389 pss_ctl |= __PSS_LMEM_INIT_EN; 1390 1391 /* 1392 * i2c workaround 12.5khz clock 1393 */ 1394 pss_ctl |= __PSS_I2C_CLK_DIV(3UL); 1395 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1396 1397 /* 1398 * wait for memory initialization to be complete 1399 */ 1400 i = 0; 1401 do { 1402 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1403 i++; 1404 } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME)); 1405 1406 /* 1407 * If memory initialization is not successful, IOC timeout will catch 1408 * such failures. 1409 */ 1410 WARN_ON(!(pss_ctl & __PSS_LMEM_INIT_DONE)); 1411 bfa_trc(ioc, pss_ctl); 1412 1413 pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN); 1414 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1415 } 1416 1417 static void 1418 bfa_ioc_lpu_start(struct bfa_ioc_s *ioc) 1419 { 1420 u32 pss_ctl; 1421 1422 /* 1423 * Take processor out of reset. 1424 */ 1425 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1426 pss_ctl &= ~__PSS_LPU0_RESET; 1427 1428 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1429 } 1430 1431 static void 1432 bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc) 1433 { 1434 u32 pss_ctl; 1435 1436 /* 1437 * Put processors in reset. 1438 */ 1439 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1440 pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET); 1441 1442 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1443 } 1444 1445 /* 1446 * Get driver and firmware versions. 1447 */ 1448 void 1449 bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) 1450 { 1451 u32 pgnum, pgoff; 1452 u32 loff = 0; 1453 int i; 1454 u32 *fwsig = (u32 *) fwhdr; 1455 1456 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff); 1457 pgoff = PSS_SMEM_PGOFF(loff); 1458 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1459 1460 for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32)); 1461 i++) { 1462 fwsig[i] = 1463 bfa_mem_read(ioc->ioc_regs.smem_page_start, loff); 1464 loff += sizeof(u32); 1465 } 1466 } 1467 1468 /* 1469 * Returns TRUE if same. 1470 */ 1471 bfa_boolean_t 1472 bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) 1473 { 1474 struct bfi_ioc_image_hdr_s *drv_fwhdr; 1475 int i; 1476 1477 drv_fwhdr = (struct bfi_ioc_image_hdr_s *) 1478 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0); 1479 1480 for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) { 1481 if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) { 1482 bfa_trc(ioc, i); 1483 bfa_trc(ioc, fwhdr->md5sum[i]); 1484 bfa_trc(ioc, drv_fwhdr->md5sum[i]); 1485 return BFA_FALSE; 1486 } 1487 } 1488 1489 bfa_trc(ioc, fwhdr->md5sum[0]); 1490 return BFA_TRUE; 1491 } 1492 1493 /* 1494 * Return true if current running version is valid. Firmware signature and 1495 * execution context (driver/bios) must match. 1496 */ 1497 static bfa_boolean_t 1498 bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env) 1499 { 1500 struct bfi_ioc_image_hdr_s fwhdr, *drv_fwhdr; 1501 1502 bfa_ioc_fwver_get(ioc, &fwhdr); 1503 drv_fwhdr = (struct bfi_ioc_image_hdr_s *) 1504 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0); 1505 1506 if (fwhdr.signature != drv_fwhdr->signature) { 1507 bfa_trc(ioc, fwhdr.signature); 1508 bfa_trc(ioc, drv_fwhdr->signature); 1509 return BFA_FALSE; 1510 } 1511 1512 if (swab32(fwhdr.bootenv) != boot_env) { 1513 bfa_trc(ioc, fwhdr.bootenv); 1514 bfa_trc(ioc, boot_env); 1515 return BFA_FALSE; 1516 } 1517 1518 return bfa_ioc_fwver_cmp(ioc, &fwhdr); 1519 } 1520 1521 /* 1522 * Conditionally flush any pending message from firmware at start. 1523 */ 1524 static void 1525 bfa_ioc_msgflush(struct bfa_ioc_s *ioc) 1526 { 1527 u32 r32; 1528 1529 r32 = readl(ioc->ioc_regs.lpu_mbox_cmd); 1530 if (r32) 1531 writel(1, ioc->ioc_regs.lpu_mbox_cmd); 1532 } 1533 1534 static void 1535 bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force) 1536 { 1537 enum bfi_ioc_state ioc_fwstate; 1538 bfa_boolean_t fwvalid; 1539 u32 boot_type; 1540 u32 boot_env; 1541 1542 ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate); 1543 1544 if (force) 1545 ioc_fwstate = BFI_IOC_UNINIT; 1546 1547 bfa_trc(ioc, ioc_fwstate); 1548 1549 boot_type = BFI_FWBOOT_TYPE_NORMAL; 1550 boot_env = BFI_FWBOOT_ENV_OS; 1551 1552 /* 1553 * check if firmware is valid 1554 */ 1555 fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ? 1556 BFA_FALSE : bfa_ioc_fwver_valid(ioc, boot_env); 1557 1558 if (!fwvalid) { 1559 bfa_ioc_boot(ioc, boot_type, boot_env); 1560 bfa_ioc_poll_fwinit(ioc); 1561 return; 1562 } 1563 1564 /* 1565 * If hardware initialization is in progress (initialized by other IOC), 1566 * just wait for an initialization completion interrupt. 1567 */ 1568 if (ioc_fwstate == BFI_IOC_INITING) { 1569 bfa_ioc_poll_fwinit(ioc); 1570 return; 1571 } 1572 1573 /* 1574 * If IOC function is disabled and firmware version is same, 1575 * just re-enable IOC. 1576 * 1577 * If option rom, IOC must not be in operational state. With 1578 * convergence, IOC will be in operational state when 2nd driver 1579 * is loaded. 1580 */ 1581 if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) { 1582 1583 /* 1584 * When using MSI-X any pending firmware ready event should 1585 * be flushed. Otherwise MSI-X interrupts are not delivered. 1586 */ 1587 bfa_ioc_msgflush(ioc); 1588 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY); 1589 return; 1590 } 1591 1592 /* 1593 * Initialize the h/w for any other states. 1594 */ 1595 bfa_ioc_boot(ioc, boot_type, boot_env); 1596 bfa_ioc_poll_fwinit(ioc); 1597 } 1598 1599 static void 1600 bfa_ioc_timeout(void *ioc_arg) 1601 { 1602 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg; 1603 1604 bfa_trc(ioc, 0); 1605 bfa_fsm_send_event(ioc, IOC_E_TIMEOUT); 1606 } 1607 1608 void 1609 bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len) 1610 { 1611 u32 *msgp = (u32 *) ioc_msg; 1612 u32 i; 1613 1614 bfa_trc(ioc, msgp[0]); 1615 bfa_trc(ioc, len); 1616 1617 WARN_ON(len > BFI_IOC_MSGLEN_MAX); 1618 1619 /* 1620 * first write msg to mailbox registers 1621 */ 1622 for (i = 0; i < len / sizeof(u32); i++) 1623 writel(cpu_to_le32(msgp[i]), 1624 ioc->ioc_regs.hfn_mbox + i * sizeof(u32)); 1625 1626 for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++) 1627 writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32)); 1628 1629 /* 1630 * write 1 to mailbox CMD to trigger LPU event 1631 */ 1632 writel(1, ioc->ioc_regs.hfn_mbox_cmd); 1633 (void) readl(ioc->ioc_regs.hfn_mbox_cmd); 1634 } 1635 1636 static void 1637 bfa_ioc_send_enable(struct bfa_ioc_s *ioc) 1638 { 1639 struct bfi_ioc_ctrl_req_s enable_req; 1640 struct timeval tv; 1641 1642 bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ, 1643 bfa_ioc_portid(ioc)); 1644 enable_req.clscode = cpu_to_be16(ioc->clscode); 1645 do_gettimeofday(&tv); 1646 enable_req.tv_sec = be32_to_cpu(tv.tv_sec); 1647 bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s)); 1648 } 1649 1650 static void 1651 bfa_ioc_send_disable(struct bfa_ioc_s *ioc) 1652 { 1653 struct bfi_ioc_ctrl_req_s disable_req; 1654 1655 bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ, 1656 bfa_ioc_portid(ioc)); 1657 bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req_s)); 1658 } 1659 1660 static void 1661 bfa_ioc_send_getattr(struct bfa_ioc_s *ioc) 1662 { 1663 struct bfi_ioc_getattr_req_s attr_req; 1664 1665 bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ, 1666 bfa_ioc_portid(ioc)); 1667 bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa); 1668 bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req)); 1669 } 1670 1671 static void 1672 bfa_ioc_hb_check(void *cbarg) 1673 { 1674 struct bfa_ioc_s *ioc = cbarg; 1675 u32 hb_count; 1676 1677 hb_count = readl(ioc->ioc_regs.heartbeat); 1678 if (ioc->hb_count == hb_count) { 1679 bfa_ioc_recover(ioc); 1680 return; 1681 } else { 1682 ioc->hb_count = hb_count; 1683 } 1684 1685 bfa_ioc_mbox_poll(ioc); 1686 bfa_hb_timer_start(ioc); 1687 } 1688 1689 static void 1690 bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc) 1691 { 1692 ioc->hb_count = readl(ioc->ioc_regs.heartbeat); 1693 bfa_hb_timer_start(ioc); 1694 } 1695 1696 /* 1697 * Initiate a full firmware download. 1698 */ 1699 static void 1700 bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, 1701 u32 boot_env) 1702 { 1703 u32 *fwimg; 1704 u32 pgnum, pgoff; 1705 u32 loff = 0; 1706 u32 chunkno = 0; 1707 u32 i; 1708 u32 asicmode; 1709 1710 /* 1711 * Initialize LMEM first before code download 1712 */ 1713 bfa_ioc_lmem_init(ioc); 1714 1715 bfa_trc(ioc, bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc))); 1716 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno); 1717 1718 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff); 1719 pgoff = PSS_SMEM_PGOFF(loff); 1720 1721 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1722 1723 for (i = 0; i < bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)); i++) { 1724 1725 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) { 1726 chunkno = BFA_IOC_FLASH_CHUNK_NO(i); 1727 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 1728 BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); 1729 } 1730 1731 /* 1732 * write smem 1733 */ 1734 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 1735 fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]); 1736 1737 loff += sizeof(u32); 1738 1739 /* 1740 * handle page offset wrap around 1741 */ 1742 loff = PSS_SMEM_PGOFF(loff); 1743 if (loff == 0) { 1744 pgnum++; 1745 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1746 } 1747 } 1748 1749 writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0), 1750 ioc->ioc_regs.host_page_num_fn); 1751 1752 /* 1753 * Set boot type and device mode at the end. 1754 */ 1755 asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode, 1756 ioc->port0_mode, ioc->port1_mode); 1757 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_DEVMODE_OFF, 1758 swab32(asicmode)); 1759 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_TYPE_OFF, 1760 swab32(boot_type)); 1761 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_ENV_OFF, 1762 swab32(boot_env)); 1763 } 1764 1765 1766 /* 1767 * Update BFA configuration from firmware configuration. 1768 */ 1769 static void 1770 bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc) 1771 { 1772 struct bfi_ioc_attr_s *attr = ioc->attr; 1773 1774 attr->adapter_prop = be32_to_cpu(attr->adapter_prop); 1775 attr->card_type = be32_to_cpu(attr->card_type); 1776 attr->maxfrsize = be16_to_cpu(attr->maxfrsize); 1777 ioc->fcmode = (attr->port_mode == BFI_PORT_MODE_FC); 1778 1779 bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); 1780 } 1781 1782 /* 1783 * Attach time initialization of mbox logic. 1784 */ 1785 static void 1786 bfa_ioc_mbox_attach(struct bfa_ioc_s *ioc) 1787 { 1788 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 1789 int mc; 1790 1791 INIT_LIST_HEAD(&mod->cmd_q); 1792 for (mc = 0; mc < BFI_MC_MAX; mc++) { 1793 mod->mbhdlr[mc].cbfn = NULL; 1794 mod->mbhdlr[mc].cbarg = ioc->bfa; 1795 } 1796 } 1797 1798 /* 1799 * Mbox poll timer -- restarts any pending mailbox requests. 1800 */ 1801 static void 1802 bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc) 1803 { 1804 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 1805 struct bfa_mbox_cmd_s *cmd; 1806 u32 stat; 1807 1808 /* 1809 * If no command pending, do nothing 1810 */ 1811 if (list_empty(&mod->cmd_q)) 1812 return; 1813 1814 /* 1815 * If previous command is not yet fetched by firmware, do nothing 1816 */ 1817 stat = readl(ioc->ioc_regs.hfn_mbox_cmd); 1818 if (stat) 1819 return; 1820 1821 /* 1822 * Enqueue command to firmware. 1823 */ 1824 bfa_q_deq(&mod->cmd_q, &cmd); 1825 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); 1826 } 1827 1828 /* 1829 * Cleanup any pending requests. 1830 */ 1831 static void 1832 bfa_ioc_mbox_flush(struct bfa_ioc_s *ioc) 1833 { 1834 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 1835 struct bfa_mbox_cmd_s *cmd; 1836 1837 while (!list_empty(&mod->cmd_q)) 1838 bfa_q_deq(&mod->cmd_q, &cmd); 1839 } 1840 1841 /* 1842 * Read data from SMEM to host through PCI memmap 1843 * 1844 * @param[in] ioc memory for IOC 1845 * @param[in] tbuf app memory to store data from smem 1846 * @param[in] soff smem offset 1847 * @param[in] sz size of smem in bytes 1848 */ 1849 static bfa_status_t 1850 bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz) 1851 { 1852 u32 pgnum, loff; 1853 __be32 r32; 1854 int i, len; 1855 u32 *buf = tbuf; 1856 1857 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff); 1858 loff = PSS_SMEM_PGOFF(soff); 1859 bfa_trc(ioc, pgnum); 1860 bfa_trc(ioc, loff); 1861 bfa_trc(ioc, sz); 1862 1863 /* 1864 * Hold semaphore to serialize pll init and fwtrc. 1865 */ 1866 if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) { 1867 bfa_trc(ioc, 0); 1868 return BFA_STATUS_FAILED; 1869 } 1870 1871 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1872 1873 len = sz/sizeof(u32); 1874 bfa_trc(ioc, len); 1875 for (i = 0; i < len; i++) { 1876 r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff); 1877 buf[i] = be32_to_cpu(r32); 1878 loff += sizeof(u32); 1879 1880 /* 1881 * handle page offset wrap around 1882 */ 1883 loff = PSS_SMEM_PGOFF(loff); 1884 if (loff == 0) { 1885 pgnum++; 1886 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1887 } 1888 } 1889 writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0), 1890 ioc->ioc_regs.host_page_num_fn); 1891 /* 1892 * release semaphore. 1893 */ 1894 readl(ioc->ioc_regs.ioc_init_sem_reg); 1895 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 1896 1897 bfa_trc(ioc, pgnum); 1898 return BFA_STATUS_OK; 1899 } 1900 1901 /* 1902 * Clear SMEM data from host through PCI memmap 1903 * 1904 * @param[in] ioc memory for IOC 1905 * @param[in] soff smem offset 1906 * @param[in] sz size of smem in bytes 1907 */ 1908 static bfa_status_t 1909 bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz) 1910 { 1911 int i, len; 1912 u32 pgnum, loff; 1913 1914 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff); 1915 loff = PSS_SMEM_PGOFF(soff); 1916 bfa_trc(ioc, pgnum); 1917 bfa_trc(ioc, loff); 1918 bfa_trc(ioc, sz); 1919 1920 /* 1921 * Hold semaphore to serialize pll init and fwtrc. 1922 */ 1923 if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) { 1924 bfa_trc(ioc, 0); 1925 return BFA_STATUS_FAILED; 1926 } 1927 1928 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1929 1930 len = sz/sizeof(u32); /* len in words */ 1931 bfa_trc(ioc, len); 1932 for (i = 0; i < len; i++) { 1933 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 0); 1934 loff += sizeof(u32); 1935 1936 /* 1937 * handle page offset wrap around 1938 */ 1939 loff = PSS_SMEM_PGOFF(loff); 1940 if (loff == 0) { 1941 pgnum++; 1942 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1943 } 1944 } 1945 writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0), 1946 ioc->ioc_regs.host_page_num_fn); 1947 1948 /* 1949 * release semaphore. 1950 */ 1951 readl(ioc->ioc_regs.ioc_init_sem_reg); 1952 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 1953 bfa_trc(ioc, pgnum); 1954 return BFA_STATUS_OK; 1955 } 1956 1957 static void 1958 bfa_ioc_fail_notify(struct bfa_ioc_s *ioc) 1959 { 1960 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 1961 1962 /* 1963 * Notify driver and common modules registered for notification. 1964 */ 1965 ioc->cbfn->hbfail_cbfn(ioc->bfa); 1966 bfa_ioc_event_notify(ioc, BFA_IOC_E_FAILED); 1967 1968 bfa_ioc_debug_save_ftrc(ioc); 1969 1970 BFA_LOG(KERN_CRIT, bfad, bfa_log_level, 1971 "Heart Beat of IOC has failed\n"); 1972 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_HBFAIL); 1973 1974 } 1975 1976 static void 1977 bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc) 1978 { 1979 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 1980 /* 1981 * Provide enable completion callback. 1982 */ 1983 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 1984 BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 1985 "Running firmware version is incompatible " 1986 "with the driver version\n"); 1987 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_FWMISMATCH); 1988 } 1989 1990 bfa_status_t 1991 bfa_ioc_pll_init(struct bfa_ioc_s *ioc) 1992 { 1993 1994 /* 1995 * Hold semaphore so that nobody can access the chip during init. 1996 */ 1997 bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); 1998 1999 bfa_ioc_pll_init_asic(ioc); 2000 2001 ioc->pllinit = BFA_TRUE; 2002 /* 2003 * release semaphore. 2004 */ 2005 readl(ioc->ioc_regs.ioc_init_sem_reg); 2006 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 2007 2008 return BFA_STATUS_OK; 2009 } 2010 2011 /* 2012 * Interface used by diag module to do firmware boot with memory test 2013 * as the entry vector. 2014 */ 2015 void 2016 bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env) 2017 { 2018 bfa_ioc_stats(ioc, ioc_boots); 2019 2020 if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK) 2021 return; 2022 2023 /* 2024 * Initialize IOC state of all functions on a chip reset. 2025 */ 2026 if (boot_type == BFI_FWBOOT_TYPE_MEMTEST) { 2027 writel(BFI_IOC_MEMTEST, ioc->ioc_regs.ioc_fwstate); 2028 writel(BFI_IOC_MEMTEST, ioc->ioc_regs.alt_ioc_fwstate); 2029 } else { 2030 writel(BFI_IOC_INITING, ioc->ioc_regs.ioc_fwstate); 2031 writel(BFI_IOC_INITING, ioc->ioc_regs.alt_ioc_fwstate); 2032 } 2033 2034 bfa_ioc_msgflush(ioc); 2035 bfa_ioc_download_fw(ioc, boot_type, boot_env); 2036 bfa_ioc_lpu_start(ioc); 2037 } 2038 2039 /* 2040 * Enable/disable IOC failure auto recovery. 2041 */ 2042 void 2043 bfa_ioc_auto_recover(bfa_boolean_t auto_recover) 2044 { 2045 bfa_auto_recover = auto_recover; 2046 } 2047 2048 2049 2050 bfa_boolean_t 2051 bfa_ioc_is_operational(struct bfa_ioc_s *ioc) 2052 { 2053 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op); 2054 } 2055 2056 bfa_boolean_t 2057 bfa_ioc_is_initialized(struct bfa_ioc_s *ioc) 2058 { 2059 u32 r32 = readl(ioc->ioc_regs.ioc_fwstate); 2060 2061 return ((r32 != BFI_IOC_UNINIT) && 2062 (r32 != BFI_IOC_INITING) && 2063 (r32 != BFI_IOC_MEMTEST)); 2064 } 2065 2066 bfa_boolean_t 2067 bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg) 2068 { 2069 __be32 *msgp = mbmsg; 2070 u32 r32; 2071 int i; 2072 2073 r32 = readl(ioc->ioc_regs.lpu_mbox_cmd); 2074 if ((r32 & 1) == 0) 2075 return BFA_FALSE; 2076 2077 /* 2078 * read the MBOX msg 2079 */ 2080 for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32)); 2081 i++) { 2082 r32 = readl(ioc->ioc_regs.lpu_mbox + 2083 i * sizeof(u32)); 2084 msgp[i] = cpu_to_be32(r32); 2085 } 2086 2087 /* 2088 * turn off mailbox interrupt by clearing mailbox status 2089 */ 2090 writel(1, ioc->ioc_regs.lpu_mbox_cmd); 2091 readl(ioc->ioc_regs.lpu_mbox_cmd); 2092 2093 return BFA_TRUE; 2094 } 2095 2096 void 2097 bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m) 2098 { 2099 union bfi_ioc_i2h_msg_u *msg; 2100 struct bfa_iocpf_s *iocpf = &ioc->iocpf; 2101 2102 msg = (union bfi_ioc_i2h_msg_u *) m; 2103 2104 bfa_ioc_stats(ioc, ioc_isrs); 2105 2106 switch (msg->mh.msg_id) { 2107 case BFI_IOC_I2H_HBEAT: 2108 break; 2109 2110 case BFI_IOC_I2H_ENABLE_REPLY: 2111 ioc->port_mode = ioc->port_mode_cfg = 2112 (enum bfa_mode_s)msg->fw_event.port_mode; 2113 ioc->ad_cap_bm = msg->fw_event.cap_bm; 2114 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE); 2115 break; 2116 2117 case BFI_IOC_I2H_DISABLE_REPLY: 2118 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_DISABLE); 2119 break; 2120 2121 case BFI_IOC_I2H_GETATTR_REPLY: 2122 bfa_ioc_getattr_reply(ioc); 2123 break; 2124 2125 case BFI_IOC_I2H_ACQ_ADDR_REPLY: 2126 bfa_fsm_send_event(ioc, IOC_E_FWRSP_ACQ_ADDR); 2127 break; 2128 2129 default: 2130 bfa_trc(ioc, msg->mh.msg_id); 2131 WARN_ON(1); 2132 } 2133 } 2134 2135 /* 2136 * IOC attach time initialization and setup. 2137 * 2138 * @param[in] ioc memory for IOC 2139 * @param[in] bfa driver instance structure 2140 */ 2141 void 2142 bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn, 2143 struct bfa_timer_mod_s *timer_mod) 2144 { 2145 ioc->bfa = bfa; 2146 ioc->cbfn = cbfn; 2147 ioc->timer_mod = timer_mod; 2148 ioc->fcmode = BFA_FALSE; 2149 ioc->pllinit = BFA_FALSE; 2150 ioc->dbg_fwsave_once = BFA_TRUE; 2151 ioc->iocpf.ioc = ioc; 2152 2153 bfa_ioc_mbox_attach(ioc); 2154 INIT_LIST_HEAD(&ioc->notify_q); 2155 2156 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 2157 bfa_fsm_send_event(ioc, IOC_E_RESET); 2158 } 2159 2160 /* 2161 * Driver detach time IOC cleanup. 2162 */ 2163 void 2164 bfa_ioc_detach(struct bfa_ioc_s *ioc) 2165 { 2166 bfa_fsm_send_event(ioc, IOC_E_DETACH); 2167 INIT_LIST_HEAD(&ioc->notify_q); 2168 } 2169 2170 /* 2171 * Setup IOC PCI properties. 2172 * 2173 * @param[in] pcidev PCI device information for this IOC 2174 */ 2175 void 2176 bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev, 2177 enum bfi_pcifn_class clscode) 2178 { 2179 ioc->clscode = clscode; 2180 ioc->pcidev = *pcidev; 2181 2182 /* 2183 * Initialize IOC and device personality 2184 */ 2185 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_FC; 2186 ioc->asic_mode = BFI_ASIC_MODE_FC; 2187 2188 switch (pcidev->device_id) { 2189 case BFA_PCI_DEVICE_ID_FC_8G1P: 2190 case BFA_PCI_DEVICE_ID_FC_8G2P: 2191 ioc->asic_gen = BFI_ASIC_GEN_CB; 2192 ioc->fcmode = BFA_TRUE; 2193 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA; 2194 ioc->ad_cap_bm = BFA_CM_HBA; 2195 break; 2196 2197 case BFA_PCI_DEVICE_ID_CT: 2198 ioc->asic_gen = BFI_ASIC_GEN_CT; 2199 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH; 2200 ioc->asic_mode = BFI_ASIC_MODE_ETH; 2201 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_CNA; 2202 ioc->ad_cap_bm = BFA_CM_CNA; 2203 break; 2204 2205 case BFA_PCI_DEVICE_ID_CT_FC: 2206 ioc->asic_gen = BFI_ASIC_GEN_CT; 2207 ioc->fcmode = BFA_TRUE; 2208 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA; 2209 ioc->ad_cap_bm = BFA_CM_HBA; 2210 break; 2211 2212 case BFA_PCI_DEVICE_ID_CT2: 2213 ioc->asic_gen = BFI_ASIC_GEN_CT2; 2214 if (clscode == BFI_PCIFN_CLASS_FC && 2215 pcidev->ssid == BFA_PCI_CT2_SSID_FC) { 2216 ioc->asic_mode = BFI_ASIC_MODE_FC16; 2217 ioc->fcmode = BFA_TRUE; 2218 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA; 2219 ioc->ad_cap_bm = BFA_CM_HBA; 2220 } else { 2221 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH; 2222 ioc->asic_mode = BFI_ASIC_MODE_ETH; 2223 if (pcidev->ssid == BFA_PCI_CT2_SSID_FCoE) { 2224 ioc->port_mode = 2225 ioc->port_mode_cfg = BFA_MODE_CNA; 2226 ioc->ad_cap_bm = BFA_CM_CNA; 2227 } else { 2228 ioc->port_mode = 2229 ioc->port_mode_cfg = BFA_MODE_NIC; 2230 ioc->ad_cap_bm = BFA_CM_NIC; 2231 } 2232 } 2233 break; 2234 2235 default: 2236 WARN_ON(1); 2237 } 2238 2239 /* 2240 * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c 2241 */ 2242 if (ioc->asic_gen == BFI_ASIC_GEN_CB) 2243 bfa_ioc_set_cb_hwif(ioc); 2244 else if (ioc->asic_gen == BFI_ASIC_GEN_CT) 2245 bfa_ioc_set_ct_hwif(ioc); 2246 else { 2247 WARN_ON(ioc->asic_gen != BFI_ASIC_GEN_CT2); 2248 bfa_ioc_set_ct2_hwif(ioc); 2249 bfa_ioc_ct2_poweron(ioc); 2250 } 2251 2252 bfa_ioc_map_port(ioc); 2253 bfa_ioc_reg_init(ioc); 2254 } 2255 2256 /* 2257 * Initialize IOC dma memory 2258 * 2259 * @param[in] dm_kva kernel virtual address of IOC dma memory 2260 * @param[in] dm_pa physical address of IOC dma memory 2261 */ 2262 void 2263 bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa) 2264 { 2265 /* 2266 * dma memory for firmware attribute 2267 */ 2268 ioc->attr_dma.kva = dm_kva; 2269 ioc->attr_dma.pa = dm_pa; 2270 ioc->attr = (struct bfi_ioc_attr_s *) dm_kva; 2271 } 2272 2273 void 2274 bfa_ioc_enable(struct bfa_ioc_s *ioc) 2275 { 2276 bfa_ioc_stats(ioc, ioc_enables); 2277 ioc->dbg_fwsave_once = BFA_TRUE; 2278 2279 bfa_fsm_send_event(ioc, IOC_E_ENABLE); 2280 } 2281 2282 void 2283 bfa_ioc_disable(struct bfa_ioc_s *ioc) 2284 { 2285 bfa_ioc_stats(ioc, ioc_disables); 2286 bfa_fsm_send_event(ioc, IOC_E_DISABLE); 2287 } 2288 2289 2290 /* 2291 * Initialize memory for saving firmware trace. Driver must initialize 2292 * trace memory before call bfa_ioc_enable(). 2293 */ 2294 void 2295 bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave) 2296 { 2297 ioc->dbg_fwsave = dbg_fwsave; 2298 ioc->dbg_fwsave_len = (ioc->iocpf.auto_recover) ? BFA_DBG_FWTRC_LEN : 0; 2299 } 2300 2301 /* 2302 * Register mailbox message handler functions 2303 * 2304 * @param[in] ioc IOC instance 2305 * @param[in] mcfuncs message class handler functions 2306 */ 2307 void 2308 bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs) 2309 { 2310 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2311 int mc; 2312 2313 for (mc = 0; mc < BFI_MC_MAX; mc++) 2314 mod->mbhdlr[mc].cbfn = mcfuncs[mc]; 2315 } 2316 2317 /* 2318 * Register mailbox message handler function, to be called by common modules 2319 */ 2320 void 2321 bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc, 2322 bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg) 2323 { 2324 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2325 2326 mod->mbhdlr[mc].cbfn = cbfn; 2327 mod->mbhdlr[mc].cbarg = cbarg; 2328 } 2329 2330 /* 2331 * Queue a mailbox command request to firmware. Waits if mailbox is busy. 2332 * Responsibility of caller to serialize 2333 * 2334 * @param[in] ioc IOC instance 2335 * @param[i] cmd Mailbox command 2336 */ 2337 void 2338 bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd) 2339 { 2340 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2341 u32 stat; 2342 2343 /* 2344 * If a previous command is pending, queue new command 2345 */ 2346 if (!list_empty(&mod->cmd_q)) { 2347 list_add_tail(&cmd->qe, &mod->cmd_q); 2348 return; 2349 } 2350 2351 /* 2352 * If mailbox is busy, queue command for poll timer 2353 */ 2354 stat = readl(ioc->ioc_regs.hfn_mbox_cmd); 2355 if (stat) { 2356 list_add_tail(&cmd->qe, &mod->cmd_q); 2357 return; 2358 } 2359 2360 /* 2361 * mailbox is free -- queue command to firmware 2362 */ 2363 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); 2364 } 2365 2366 /* 2367 * Handle mailbox interrupts 2368 */ 2369 void 2370 bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc) 2371 { 2372 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2373 struct bfi_mbmsg_s m; 2374 int mc; 2375 2376 if (bfa_ioc_msgget(ioc, &m)) { 2377 /* 2378 * Treat IOC message class as special. 2379 */ 2380 mc = m.mh.msg_class; 2381 if (mc == BFI_MC_IOC) { 2382 bfa_ioc_isr(ioc, &m); 2383 return; 2384 } 2385 2386 if ((mc > BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL)) 2387 return; 2388 2389 mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m); 2390 } 2391 2392 bfa_ioc_lpu_read_stat(ioc); 2393 2394 /* 2395 * Try to send pending mailbox commands 2396 */ 2397 bfa_ioc_mbox_poll(ioc); 2398 } 2399 2400 void 2401 bfa_ioc_error_isr(struct bfa_ioc_s *ioc) 2402 { 2403 bfa_ioc_stats(ioc, ioc_hbfails); 2404 ioc->stats.hb_count = ioc->hb_count; 2405 bfa_fsm_send_event(ioc, IOC_E_HWERROR); 2406 } 2407 2408 /* 2409 * return true if IOC is disabled 2410 */ 2411 bfa_boolean_t 2412 bfa_ioc_is_disabled(struct bfa_ioc_s *ioc) 2413 { 2414 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) || 2415 bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled); 2416 } 2417 2418 /* 2419 * Return TRUE if IOC is in acquiring address state 2420 */ 2421 bfa_boolean_t 2422 bfa_ioc_is_acq_addr(struct bfa_ioc_s *ioc) 2423 { 2424 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_acq_addr); 2425 } 2426 2427 /* 2428 * return true if IOC firmware is different. 2429 */ 2430 bfa_boolean_t 2431 bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc) 2432 { 2433 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset) || 2434 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_fwcheck) || 2435 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_mismatch); 2436 } 2437 2438 #define bfa_ioc_state_disabled(__sm) \ 2439 (((__sm) == BFI_IOC_UNINIT) || \ 2440 ((__sm) == BFI_IOC_INITING) || \ 2441 ((__sm) == BFI_IOC_HWINIT) || \ 2442 ((__sm) == BFI_IOC_DISABLED) || \ 2443 ((__sm) == BFI_IOC_FAIL) || \ 2444 ((__sm) == BFI_IOC_CFG_DISABLED)) 2445 2446 /* 2447 * Check if adapter is disabled -- both IOCs should be in a disabled 2448 * state. 2449 */ 2450 bfa_boolean_t 2451 bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc) 2452 { 2453 u32 ioc_state; 2454 2455 if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled)) 2456 return BFA_FALSE; 2457 2458 ioc_state = readl(ioc->ioc_regs.ioc_fwstate); 2459 if (!bfa_ioc_state_disabled(ioc_state)) 2460 return BFA_FALSE; 2461 2462 if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_FC_8G1P) { 2463 ioc_state = readl(ioc->ioc_regs.alt_ioc_fwstate); 2464 if (!bfa_ioc_state_disabled(ioc_state)) 2465 return BFA_FALSE; 2466 } 2467 2468 return BFA_TRUE; 2469 } 2470 2471 /* 2472 * Reset IOC fwstate registers. 2473 */ 2474 void 2475 bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc) 2476 { 2477 writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate); 2478 writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate); 2479 } 2480 2481 #define BFA_MFG_NAME "Brocade" 2482 void 2483 bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, 2484 struct bfa_adapter_attr_s *ad_attr) 2485 { 2486 struct bfi_ioc_attr_s *ioc_attr; 2487 2488 ioc_attr = ioc->attr; 2489 2490 bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num); 2491 bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver); 2492 bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver); 2493 bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer); 2494 memcpy(&ad_attr->vpd, &ioc_attr->vpd, 2495 sizeof(struct bfa_mfg_vpd_s)); 2496 2497 ad_attr->nports = bfa_ioc_get_nports(ioc); 2498 ad_attr->max_speed = bfa_ioc_speed_sup(ioc); 2499 2500 bfa_ioc_get_adapter_model(ioc, ad_attr->model); 2501 /* For now, model descr uses same model string */ 2502 bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr); 2503 2504 ad_attr->card_type = ioc_attr->card_type; 2505 ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type); 2506 2507 if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop)) 2508 ad_attr->prototype = 1; 2509 else 2510 ad_attr->prototype = 0; 2511 2512 ad_attr->pwwn = ioc->attr->pwwn; 2513 ad_attr->mac = bfa_ioc_get_mac(ioc); 2514 2515 ad_attr->pcie_gen = ioc_attr->pcie_gen; 2516 ad_attr->pcie_lanes = ioc_attr->pcie_lanes; 2517 ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig; 2518 ad_attr->asic_rev = ioc_attr->asic_rev; 2519 2520 bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver); 2521 2522 ad_attr->cna_capable = bfa_ioc_is_cna(ioc); 2523 ad_attr->trunk_capable = (ad_attr->nports > 1) && 2524 !bfa_ioc_is_cna(ioc) && !ad_attr->is_mezz; 2525 } 2526 2527 enum bfa_ioc_type_e 2528 bfa_ioc_get_type(struct bfa_ioc_s *ioc) 2529 { 2530 if (ioc->clscode == BFI_PCIFN_CLASS_ETH) 2531 return BFA_IOC_TYPE_LL; 2532 2533 WARN_ON(ioc->clscode != BFI_PCIFN_CLASS_FC); 2534 2535 return (ioc->attr->port_mode == BFI_PORT_MODE_FC) 2536 ? BFA_IOC_TYPE_FC : BFA_IOC_TYPE_FCoE; 2537 } 2538 2539 void 2540 bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num) 2541 { 2542 memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN); 2543 memcpy((void *)serial_num, 2544 (void *)ioc->attr->brcd_serialnum, 2545 BFA_ADAPTER_SERIAL_NUM_LEN); 2546 } 2547 2548 void 2549 bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver) 2550 { 2551 memset((void *)fw_ver, 0, BFA_VERSION_LEN); 2552 memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN); 2553 } 2554 2555 void 2556 bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev) 2557 { 2558 WARN_ON(!chip_rev); 2559 2560 memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN); 2561 2562 chip_rev[0] = 'R'; 2563 chip_rev[1] = 'e'; 2564 chip_rev[2] = 'v'; 2565 chip_rev[3] = '-'; 2566 chip_rev[4] = ioc->attr->asic_rev; 2567 chip_rev[5] = '\0'; 2568 } 2569 2570 void 2571 bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver) 2572 { 2573 memset((void *)optrom_ver, 0, BFA_VERSION_LEN); 2574 memcpy(optrom_ver, ioc->attr->optrom_version, 2575 BFA_VERSION_LEN); 2576 } 2577 2578 void 2579 bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer) 2580 { 2581 memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN); 2582 memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); 2583 } 2584 2585 void 2586 bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model) 2587 { 2588 struct bfi_ioc_attr_s *ioc_attr; 2589 2590 WARN_ON(!model); 2591 memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN); 2592 2593 ioc_attr = ioc->attr; 2594 2595 snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u", 2596 BFA_MFG_NAME, ioc_attr->card_type); 2597 } 2598 2599 enum bfa_ioc_state 2600 bfa_ioc_get_state(struct bfa_ioc_s *ioc) 2601 { 2602 enum bfa_iocpf_state iocpf_st; 2603 enum bfa_ioc_state ioc_st = bfa_sm_to_state(ioc_sm_table, ioc->fsm); 2604 2605 if (ioc_st == BFA_IOC_ENABLING || 2606 ioc_st == BFA_IOC_FAIL || ioc_st == BFA_IOC_INITFAIL) { 2607 2608 iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm); 2609 2610 switch (iocpf_st) { 2611 case BFA_IOCPF_SEMWAIT: 2612 ioc_st = BFA_IOC_SEMWAIT; 2613 break; 2614 2615 case BFA_IOCPF_HWINIT: 2616 ioc_st = BFA_IOC_HWINIT; 2617 break; 2618 2619 case BFA_IOCPF_FWMISMATCH: 2620 ioc_st = BFA_IOC_FWMISMATCH; 2621 break; 2622 2623 case BFA_IOCPF_FAIL: 2624 ioc_st = BFA_IOC_FAIL; 2625 break; 2626 2627 case BFA_IOCPF_INITFAIL: 2628 ioc_st = BFA_IOC_INITFAIL; 2629 break; 2630 2631 default: 2632 break; 2633 } 2634 } 2635 2636 return ioc_st; 2637 } 2638 2639 void 2640 bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) 2641 { 2642 memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s)); 2643 2644 ioc_attr->state = bfa_ioc_get_state(ioc); 2645 ioc_attr->port_id = ioc->port_id; 2646 ioc_attr->port_mode = ioc->port_mode; 2647 ioc_attr->port_mode_cfg = ioc->port_mode_cfg; 2648 ioc_attr->cap_bm = ioc->ad_cap_bm; 2649 2650 ioc_attr->ioc_type = bfa_ioc_get_type(ioc); 2651 2652 bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr); 2653 2654 ioc_attr->pci_attr.device_id = ioc->pcidev.device_id; 2655 ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func; 2656 bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev); 2657 } 2658 2659 mac_t 2660 bfa_ioc_get_mac(struct bfa_ioc_s *ioc) 2661 { 2662 /* 2663 * Check the IOC type and return the appropriate MAC 2664 */ 2665 if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE) 2666 return ioc->attr->fcoe_mac; 2667 else 2668 return ioc->attr->mac; 2669 } 2670 2671 mac_t 2672 bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc) 2673 { 2674 mac_t m; 2675 2676 m = ioc->attr->mfg_mac; 2677 if (bfa_mfg_is_old_wwn_mac_model(ioc->attr->card_type)) 2678 m.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc); 2679 else 2680 bfa_mfg_increment_wwn_mac(&(m.mac[MAC_ADDRLEN-3]), 2681 bfa_ioc_pcifn(ioc)); 2682 2683 return m; 2684 } 2685 2686 /* 2687 * Send AEN notification 2688 */ 2689 void 2690 bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event) 2691 { 2692 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 2693 struct bfa_aen_entry_s *aen_entry; 2694 enum bfa_ioc_type_e ioc_type; 2695 2696 bfad_get_aen_entry(bfad, aen_entry); 2697 if (!aen_entry) 2698 return; 2699 2700 ioc_type = bfa_ioc_get_type(ioc); 2701 switch (ioc_type) { 2702 case BFA_IOC_TYPE_FC: 2703 aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn; 2704 break; 2705 case BFA_IOC_TYPE_FCoE: 2706 aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn; 2707 aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc); 2708 break; 2709 case BFA_IOC_TYPE_LL: 2710 aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc); 2711 break; 2712 default: 2713 WARN_ON(ioc_type != BFA_IOC_TYPE_FC); 2714 break; 2715 } 2716 2717 /* Send the AEN notification */ 2718 aen_entry->aen_data.ioc.ioc_type = ioc_type; 2719 bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq, 2720 BFA_AEN_CAT_IOC, event); 2721 } 2722 2723 /* 2724 * Retrieve saved firmware trace from a prior IOC failure. 2725 */ 2726 bfa_status_t 2727 bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) 2728 { 2729 int tlen; 2730 2731 if (ioc->dbg_fwsave_len == 0) 2732 return BFA_STATUS_ENOFSAVE; 2733 2734 tlen = *trclen; 2735 if (tlen > ioc->dbg_fwsave_len) 2736 tlen = ioc->dbg_fwsave_len; 2737 2738 memcpy(trcdata, ioc->dbg_fwsave, tlen); 2739 *trclen = tlen; 2740 return BFA_STATUS_OK; 2741 } 2742 2743 2744 /* 2745 * Retrieve saved firmware trace from a prior IOC failure. 2746 */ 2747 bfa_status_t 2748 bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) 2749 { 2750 u32 loff = BFA_DBG_FWTRC_OFF(bfa_ioc_portid(ioc)); 2751 int tlen; 2752 bfa_status_t status; 2753 2754 bfa_trc(ioc, *trclen); 2755 2756 tlen = *trclen; 2757 if (tlen > BFA_DBG_FWTRC_LEN) 2758 tlen = BFA_DBG_FWTRC_LEN; 2759 2760 status = bfa_ioc_smem_read(ioc, trcdata, loff, tlen); 2761 *trclen = tlen; 2762 return status; 2763 } 2764 2765 static void 2766 bfa_ioc_send_fwsync(struct bfa_ioc_s *ioc) 2767 { 2768 struct bfa_mbox_cmd_s cmd; 2769 struct bfi_ioc_ctrl_req_s *req = (struct bfi_ioc_ctrl_req_s *) cmd.msg; 2770 2771 bfi_h2i_set(req->mh, BFI_MC_IOC, BFI_IOC_H2I_DBG_SYNC, 2772 bfa_ioc_portid(ioc)); 2773 req->clscode = cpu_to_be16(ioc->clscode); 2774 bfa_ioc_mbox_queue(ioc, &cmd); 2775 } 2776 2777 static void 2778 bfa_ioc_fwsync(struct bfa_ioc_s *ioc) 2779 { 2780 u32 fwsync_iter = 1000; 2781 2782 bfa_ioc_send_fwsync(ioc); 2783 2784 /* 2785 * After sending a fw sync mbox command wait for it to 2786 * take effect. We will not wait for a response because 2787 * 1. fw_sync mbox cmd doesn't have a response. 2788 * 2. Even if we implement that, interrupts might not 2789 * be enabled when we call this function. 2790 * So, just keep checking if any mbox cmd is pending, and 2791 * after waiting for a reasonable amount of time, go ahead. 2792 * It is possible that fw has crashed and the mbox command 2793 * is never acknowledged. 2794 */ 2795 while (bfa_ioc_mbox_cmd_pending(ioc) && fwsync_iter > 0) 2796 fwsync_iter--; 2797 } 2798 2799 /* 2800 * Dump firmware smem 2801 */ 2802 bfa_status_t 2803 bfa_ioc_debug_fwcore(struct bfa_ioc_s *ioc, void *buf, 2804 u32 *offset, int *buflen) 2805 { 2806 u32 loff; 2807 int dlen; 2808 bfa_status_t status; 2809 u32 smem_len = BFA_IOC_FW_SMEM_SIZE(ioc); 2810 2811 if (*offset >= smem_len) { 2812 *offset = *buflen = 0; 2813 return BFA_STATUS_EINVAL; 2814 } 2815 2816 loff = *offset; 2817 dlen = *buflen; 2818 2819 /* 2820 * First smem read, sync smem before proceeding 2821 * No need to sync before reading every chunk. 2822 */ 2823 if (loff == 0) 2824 bfa_ioc_fwsync(ioc); 2825 2826 if ((loff + dlen) >= smem_len) 2827 dlen = smem_len - loff; 2828 2829 status = bfa_ioc_smem_read(ioc, buf, loff, dlen); 2830 2831 if (status != BFA_STATUS_OK) { 2832 *offset = *buflen = 0; 2833 return status; 2834 } 2835 2836 *offset += dlen; 2837 2838 if (*offset >= smem_len) 2839 *offset = 0; 2840 2841 *buflen = dlen; 2842 2843 return status; 2844 } 2845 2846 /* 2847 * Firmware statistics 2848 */ 2849 bfa_status_t 2850 bfa_ioc_fw_stats_get(struct bfa_ioc_s *ioc, void *stats) 2851 { 2852 u32 loff = BFI_IOC_FWSTATS_OFF + \ 2853 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc)); 2854 int tlen; 2855 bfa_status_t status; 2856 2857 if (ioc->stats_busy) { 2858 bfa_trc(ioc, ioc->stats_busy); 2859 return BFA_STATUS_DEVBUSY; 2860 } 2861 ioc->stats_busy = BFA_TRUE; 2862 2863 tlen = sizeof(struct bfa_fw_stats_s); 2864 status = bfa_ioc_smem_read(ioc, stats, loff, tlen); 2865 2866 ioc->stats_busy = BFA_FALSE; 2867 return status; 2868 } 2869 2870 bfa_status_t 2871 bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc) 2872 { 2873 u32 loff = BFI_IOC_FWSTATS_OFF + \ 2874 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc)); 2875 int tlen; 2876 bfa_status_t status; 2877 2878 if (ioc->stats_busy) { 2879 bfa_trc(ioc, ioc->stats_busy); 2880 return BFA_STATUS_DEVBUSY; 2881 } 2882 ioc->stats_busy = BFA_TRUE; 2883 2884 tlen = sizeof(struct bfa_fw_stats_s); 2885 status = bfa_ioc_smem_clr(ioc, loff, tlen); 2886 2887 ioc->stats_busy = BFA_FALSE; 2888 return status; 2889 } 2890 2891 /* 2892 * Save firmware trace if configured. 2893 */ 2894 static void 2895 bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc) 2896 { 2897 int tlen; 2898 2899 if (ioc->dbg_fwsave_once) { 2900 ioc->dbg_fwsave_once = BFA_FALSE; 2901 if (ioc->dbg_fwsave_len) { 2902 tlen = ioc->dbg_fwsave_len; 2903 bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen); 2904 } 2905 } 2906 } 2907 2908 /* 2909 * Firmware failure detected. Start recovery actions. 2910 */ 2911 static void 2912 bfa_ioc_recover(struct bfa_ioc_s *ioc) 2913 { 2914 bfa_ioc_stats(ioc, ioc_hbfails); 2915 ioc->stats.hb_count = ioc->hb_count; 2916 bfa_fsm_send_event(ioc, IOC_E_HBFAIL); 2917 } 2918 2919 static void 2920 bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc) 2921 { 2922 if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL) 2923 return; 2924 if (ioc->attr->nwwn == 0) 2925 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_INVALID_NWWN); 2926 if (ioc->attr->pwwn == 0) 2927 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_INVALID_PWWN); 2928 } 2929 2930 /* 2931 * BFA IOC PF private functions 2932 */ 2933 static void 2934 bfa_iocpf_timeout(void *ioc_arg) 2935 { 2936 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg; 2937 2938 bfa_trc(ioc, 0); 2939 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT); 2940 } 2941 2942 static void 2943 bfa_iocpf_sem_timeout(void *ioc_arg) 2944 { 2945 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg; 2946 2947 bfa_ioc_hw_sem_get(ioc); 2948 } 2949 2950 static void 2951 bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc) 2952 { 2953 u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate); 2954 2955 bfa_trc(ioc, fwstate); 2956 2957 if (fwstate == BFI_IOC_DISABLED) { 2958 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY); 2959 return; 2960 } 2961 2962 if (ioc->iocpf.poll_time >= BFA_IOC_TOV) 2963 bfa_iocpf_timeout(ioc); 2964 else { 2965 ioc->iocpf.poll_time += BFA_IOC_POLL_TOV; 2966 bfa_iocpf_poll_timer_start(ioc); 2967 } 2968 } 2969 2970 static void 2971 bfa_iocpf_poll_timeout(void *ioc_arg) 2972 { 2973 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg; 2974 2975 bfa_ioc_poll_fwinit(ioc); 2976 } 2977 2978 /* 2979 * bfa timer function 2980 */ 2981 void 2982 bfa_timer_beat(struct bfa_timer_mod_s *mod) 2983 { 2984 struct list_head *qh = &mod->timer_q; 2985 struct list_head *qe, *qe_next; 2986 struct bfa_timer_s *elem; 2987 struct list_head timedout_q; 2988 2989 INIT_LIST_HEAD(&timedout_q); 2990 2991 qe = bfa_q_next(qh); 2992 2993 while (qe != qh) { 2994 qe_next = bfa_q_next(qe); 2995 2996 elem = (struct bfa_timer_s *) qe; 2997 if (elem->timeout <= BFA_TIMER_FREQ) { 2998 elem->timeout = 0; 2999 list_del(&elem->qe); 3000 list_add_tail(&elem->qe, &timedout_q); 3001 } else { 3002 elem->timeout -= BFA_TIMER_FREQ; 3003 } 3004 3005 qe = qe_next; /* go to next elem */ 3006 } 3007 3008 /* 3009 * Pop all the timeout entries 3010 */ 3011 while (!list_empty(&timedout_q)) { 3012 bfa_q_deq(&timedout_q, &elem); 3013 elem->timercb(elem->arg); 3014 } 3015 } 3016 3017 /* 3018 * Should be called with lock protection 3019 */ 3020 void 3021 bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer, 3022 void (*timercb) (void *), void *arg, unsigned int timeout) 3023 { 3024 3025 WARN_ON(timercb == NULL); 3026 WARN_ON(bfa_q_is_on_q(&mod->timer_q, timer)); 3027 3028 timer->timeout = timeout; 3029 timer->timercb = timercb; 3030 timer->arg = arg; 3031 3032 list_add_tail(&timer->qe, &mod->timer_q); 3033 } 3034 3035 /* 3036 * Should be called with lock protection 3037 */ 3038 void 3039 bfa_timer_stop(struct bfa_timer_s *timer) 3040 { 3041 WARN_ON(list_empty(&timer->qe)); 3042 3043 list_del(&timer->qe); 3044 } 3045 3046 /* 3047 * ASIC block related 3048 */ 3049 static void 3050 bfa_ablk_config_swap(struct bfa_ablk_cfg_s *cfg) 3051 { 3052 struct bfa_ablk_cfg_inst_s *cfg_inst; 3053 int i, j; 3054 u16 be16; 3055 u32 be32; 3056 3057 for (i = 0; i < BFA_ABLK_MAX; i++) { 3058 cfg_inst = &cfg->inst[i]; 3059 for (j = 0; j < BFA_ABLK_MAX_PFS; j++) { 3060 be16 = cfg_inst->pf_cfg[j].pers; 3061 cfg_inst->pf_cfg[j].pers = be16_to_cpu(be16); 3062 be16 = cfg_inst->pf_cfg[j].num_qpairs; 3063 cfg_inst->pf_cfg[j].num_qpairs = be16_to_cpu(be16); 3064 be16 = cfg_inst->pf_cfg[j].num_vectors; 3065 cfg_inst->pf_cfg[j].num_vectors = be16_to_cpu(be16); 3066 be32 = cfg_inst->pf_cfg[j].bw; 3067 cfg_inst->pf_cfg[j].bw = be16_to_cpu(be32); 3068 } 3069 } 3070 } 3071 3072 static void 3073 bfa_ablk_isr(void *cbarg, struct bfi_mbmsg_s *msg) 3074 { 3075 struct bfa_ablk_s *ablk = (struct bfa_ablk_s *)cbarg; 3076 struct bfi_ablk_i2h_rsp_s *rsp = (struct bfi_ablk_i2h_rsp_s *)msg; 3077 bfa_ablk_cbfn_t cbfn; 3078 3079 WARN_ON(msg->mh.msg_class != BFI_MC_ABLK); 3080 bfa_trc(ablk->ioc, msg->mh.msg_id); 3081 3082 switch (msg->mh.msg_id) { 3083 case BFI_ABLK_I2H_QUERY: 3084 if (rsp->status == BFA_STATUS_OK) { 3085 memcpy(ablk->cfg, ablk->dma_addr.kva, 3086 sizeof(struct bfa_ablk_cfg_s)); 3087 bfa_ablk_config_swap(ablk->cfg); 3088 ablk->cfg = NULL; 3089 } 3090 break; 3091 3092 case BFI_ABLK_I2H_ADPT_CONFIG: 3093 case BFI_ABLK_I2H_PORT_CONFIG: 3094 /* update config port mode */ 3095 ablk->ioc->port_mode_cfg = rsp->port_mode; 3096 3097 case BFI_ABLK_I2H_PF_DELETE: 3098 case BFI_ABLK_I2H_PF_UPDATE: 3099 case BFI_ABLK_I2H_OPTROM_ENABLE: 3100 case BFI_ABLK_I2H_OPTROM_DISABLE: 3101 /* No-op */ 3102 break; 3103 3104 case BFI_ABLK_I2H_PF_CREATE: 3105 *(ablk->pcifn) = rsp->pcifn; 3106 ablk->pcifn = NULL; 3107 break; 3108 3109 default: 3110 WARN_ON(1); 3111 } 3112 3113 ablk->busy = BFA_FALSE; 3114 if (ablk->cbfn) { 3115 cbfn = ablk->cbfn; 3116 ablk->cbfn = NULL; 3117 cbfn(ablk->cbarg, rsp->status); 3118 } 3119 } 3120 3121 static void 3122 bfa_ablk_notify(void *cbarg, enum bfa_ioc_event_e event) 3123 { 3124 struct bfa_ablk_s *ablk = (struct bfa_ablk_s *)cbarg; 3125 3126 bfa_trc(ablk->ioc, event); 3127 3128 switch (event) { 3129 case BFA_IOC_E_ENABLED: 3130 WARN_ON(ablk->busy != BFA_FALSE); 3131 break; 3132 3133 case BFA_IOC_E_DISABLED: 3134 case BFA_IOC_E_FAILED: 3135 /* Fail any pending requests */ 3136 ablk->pcifn = NULL; 3137 if (ablk->busy) { 3138 if (ablk->cbfn) 3139 ablk->cbfn(ablk->cbarg, BFA_STATUS_FAILED); 3140 ablk->cbfn = NULL; 3141 ablk->busy = BFA_FALSE; 3142 } 3143 break; 3144 3145 default: 3146 WARN_ON(1); 3147 break; 3148 } 3149 } 3150 3151 u32 3152 bfa_ablk_meminfo(void) 3153 { 3154 return BFA_ROUNDUP(sizeof(struct bfa_ablk_cfg_s), BFA_DMA_ALIGN_SZ); 3155 } 3156 3157 void 3158 bfa_ablk_memclaim(struct bfa_ablk_s *ablk, u8 *dma_kva, u64 dma_pa) 3159 { 3160 ablk->dma_addr.kva = dma_kva; 3161 ablk->dma_addr.pa = dma_pa; 3162 } 3163 3164 void 3165 bfa_ablk_attach(struct bfa_ablk_s *ablk, struct bfa_ioc_s *ioc) 3166 { 3167 ablk->ioc = ioc; 3168 3169 bfa_ioc_mbox_regisr(ablk->ioc, BFI_MC_ABLK, bfa_ablk_isr, ablk); 3170 bfa_q_qe_init(&ablk->ioc_notify); 3171 bfa_ioc_notify_init(&ablk->ioc_notify, bfa_ablk_notify, ablk); 3172 list_add_tail(&ablk->ioc_notify.qe, &ablk->ioc->notify_q); 3173 } 3174 3175 bfa_status_t 3176 bfa_ablk_query(struct bfa_ablk_s *ablk, struct bfa_ablk_cfg_s *ablk_cfg, 3177 bfa_ablk_cbfn_t cbfn, void *cbarg) 3178 { 3179 struct bfi_ablk_h2i_query_s *m; 3180 3181 WARN_ON(!ablk_cfg); 3182 3183 if (!bfa_ioc_is_operational(ablk->ioc)) { 3184 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3185 return BFA_STATUS_IOC_FAILURE; 3186 } 3187 3188 if (ablk->busy) { 3189 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3190 return BFA_STATUS_DEVBUSY; 3191 } 3192 3193 ablk->cfg = ablk_cfg; 3194 ablk->cbfn = cbfn; 3195 ablk->cbarg = cbarg; 3196 ablk->busy = BFA_TRUE; 3197 3198 m = (struct bfi_ablk_h2i_query_s *)ablk->mb.msg; 3199 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_QUERY, 3200 bfa_ioc_portid(ablk->ioc)); 3201 bfa_dma_be_addr_set(m->addr, ablk->dma_addr.pa); 3202 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3203 3204 return BFA_STATUS_OK; 3205 } 3206 3207 bfa_status_t 3208 bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn, 3209 u8 port, enum bfi_pcifn_class personality, int bw, 3210 bfa_ablk_cbfn_t cbfn, void *cbarg) 3211 { 3212 struct bfi_ablk_h2i_pf_req_s *m; 3213 3214 if (!bfa_ioc_is_operational(ablk->ioc)) { 3215 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3216 return BFA_STATUS_IOC_FAILURE; 3217 } 3218 3219 if (ablk->busy) { 3220 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3221 return BFA_STATUS_DEVBUSY; 3222 } 3223 3224 ablk->pcifn = pcifn; 3225 ablk->cbfn = cbfn; 3226 ablk->cbarg = cbarg; 3227 ablk->busy = BFA_TRUE; 3228 3229 m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg; 3230 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_CREATE, 3231 bfa_ioc_portid(ablk->ioc)); 3232 m->pers = cpu_to_be16((u16)personality); 3233 m->bw = cpu_to_be32(bw); 3234 m->port = port; 3235 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3236 3237 return BFA_STATUS_OK; 3238 } 3239 3240 bfa_status_t 3241 bfa_ablk_pf_delete(struct bfa_ablk_s *ablk, int pcifn, 3242 bfa_ablk_cbfn_t cbfn, void *cbarg) 3243 { 3244 struct bfi_ablk_h2i_pf_req_s *m; 3245 3246 if (!bfa_ioc_is_operational(ablk->ioc)) { 3247 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3248 return BFA_STATUS_IOC_FAILURE; 3249 } 3250 3251 if (ablk->busy) { 3252 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3253 return BFA_STATUS_DEVBUSY; 3254 } 3255 3256 ablk->cbfn = cbfn; 3257 ablk->cbarg = cbarg; 3258 ablk->busy = BFA_TRUE; 3259 3260 m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg; 3261 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_DELETE, 3262 bfa_ioc_portid(ablk->ioc)); 3263 m->pcifn = (u8)pcifn; 3264 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3265 3266 return BFA_STATUS_OK; 3267 } 3268 3269 bfa_status_t 3270 bfa_ablk_adapter_config(struct bfa_ablk_s *ablk, enum bfa_mode_s mode, 3271 int max_pf, int max_vf, bfa_ablk_cbfn_t cbfn, void *cbarg) 3272 { 3273 struct bfi_ablk_h2i_cfg_req_s *m; 3274 3275 if (!bfa_ioc_is_operational(ablk->ioc)) { 3276 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3277 return BFA_STATUS_IOC_FAILURE; 3278 } 3279 3280 if (ablk->busy) { 3281 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3282 return BFA_STATUS_DEVBUSY; 3283 } 3284 3285 ablk->cbfn = cbfn; 3286 ablk->cbarg = cbarg; 3287 ablk->busy = BFA_TRUE; 3288 3289 m = (struct bfi_ablk_h2i_cfg_req_s *)ablk->mb.msg; 3290 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_ADPT_CONFIG, 3291 bfa_ioc_portid(ablk->ioc)); 3292 m->mode = (u8)mode; 3293 m->max_pf = (u8)max_pf; 3294 m->max_vf = (u8)max_vf; 3295 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3296 3297 return BFA_STATUS_OK; 3298 } 3299 3300 bfa_status_t 3301 bfa_ablk_port_config(struct bfa_ablk_s *ablk, int port, enum bfa_mode_s mode, 3302 int max_pf, int max_vf, bfa_ablk_cbfn_t cbfn, void *cbarg) 3303 { 3304 struct bfi_ablk_h2i_cfg_req_s *m; 3305 3306 if (!bfa_ioc_is_operational(ablk->ioc)) { 3307 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3308 return BFA_STATUS_IOC_FAILURE; 3309 } 3310 3311 if (ablk->busy) { 3312 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3313 return BFA_STATUS_DEVBUSY; 3314 } 3315 3316 ablk->cbfn = cbfn; 3317 ablk->cbarg = cbarg; 3318 ablk->busy = BFA_TRUE; 3319 3320 m = (struct bfi_ablk_h2i_cfg_req_s *)ablk->mb.msg; 3321 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PORT_CONFIG, 3322 bfa_ioc_portid(ablk->ioc)); 3323 m->port = (u8)port; 3324 m->mode = (u8)mode; 3325 m->max_pf = (u8)max_pf; 3326 m->max_vf = (u8)max_vf; 3327 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3328 3329 return BFA_STATUS_OK; 3330 } 3331 3332 bfa_status_t 3333 bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, int bw, 3334 bfa_ablk_cbfn_t cbfn, void *cbarg) 3335 { 3336 struct bfi_ablk_h2i_pf_req_s *m; 3337 3338 if (!bfa_ioc_is_operational(ablk->ioc)) { 3339 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3340 return BFA_STATUS_IOC_FAILURE; 3341 } 3342 3343 if (ablk->busy) { 3344 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3345 return BFA_STATUS_DEVBUSY; 3346 } 3347 3348 ablk->cbfn = cbfn; 3349 ablk->cbarg = cbarg; 3350 ablk->busy = BFA_TRUE; 3351 3352 m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg; 3353 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_UPDATE, 3354 bfa_ioc_portid(ablk->ioc)); 3355 m->pcifn = (u8)pcifn; 3356 m->bw = cpu_to_be32(bw); 3357 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3358 3359 return BFA_STATUS_OK; 3360 } 3361 3362 bfa_status_t 3363 bfa_ablk_optrom_en(struct bfa_ablk_s *ablk, bfa_ablk_cbfn_t cbfn, void *cbarg) 3364 { 3365 struct bfi_ablk_h2i_optrom_s *m; 3366 3367 if (!bfa_ioc_is_operational(ablk->ioc)) { 3368 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3369 return BFA_STATUS_IOC_FAILURE; 3370 } 3371 3372 if (ablk->busy) { 3373 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3374 return BFA_STATUS_DEVBUSY; 3375 } 3376 3377 ablk->cbfn = cbfn; 3378 ablk->cbarg = cbarg; 3379 ablk->busy = BFA_TRUE; 3380 3381 m = (struct bfi_ablk_h2i_optrom_s *)ablk->mb.msg; 3382 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_OPTROM_ENABLE, 3383 bfa_ioc_portid(ablk->ioc)); 3384 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3385 3386 return BFA_STATUS_OK; 3387 } 3388 3389 bfa_status_t 3390 bfa_ablk_optrom_dis(struct bfa_ablk_s *ablk, bfa_ablk_cbfn_t cbfn, void *cbarg) 3391 { 3392 struct bfi_ablk_h2i_optrom_s *m; 3393 3394 if (!bfa_ioc_is_operational(ablk->ioc)) { 3395 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3396 return BFA_STATUS_IOC_FAILURE; 3397 } 3398 3399 if (ablk->busy) { 3400 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3401 return BFA_STATUS_DEVBUSY; 3402 } 3403 3404 ablk->cbfn = cbfn; 3405 ablk->cbarg = cbarg; 3406 ablk->busy = BFA_TRUE; 3407 3408 m = (struct bfi_ablk_h2i_optrom_s *)ablk->mb.msg; 3409 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_OPTROM_DISABLE, 3410 bfa_ioc_portid(ablk->ioc)); 3411 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3412 3413 return BFA_STATUS_OK; 3414 } 3415 3416 /* 3417 * SFP module specific 3418 */ 3419 3420 /* forward declarations */ 3421 static void bfa_sfp_getdata_send(struct bfa_sfp_s *sfp); 3422 static void bfa_sfp_media_get(struct bfa_sfp_s *sfp); 3423 static bfa_status_t bfa_sfp_speed_valid(struct bfa_sfp_s *sfp, 3424 enum bfa_port_speed portspeed); 3425 3426 static void 3427 bfa_cb_sfp_show(struct bfa_sfp_s *sfp) 3428 { 3429 bfa_trc(sfp, sfp->lock); 3430 if (sfp->cbfn) 3431 sfp->cbfn(sfp->cbarg, sfp->status); 3432 sfp->lock = 0; 3433 sfp->cbfn = NULL; 3434 } 3435 3436 static void 3437 bfa_cb_sfp_state_query(struct bfa_sfp_s *sfp) 3438 { 3439 bfa_trc(sfp, sfp->portspeed); 3440 if (sfp->media) { 3441 bfa_sfp_media_get(sfp); 3442 if (sfp->state_query_cbfn) 3443 sfp->state_query_cbfn(sfp->state_query_cbarg, 3444 sfp->status); 3445 sfp->media = NULL; 3446 } 3447 3448 if (sfp->portspeed) { 3449 sfp->status = bfa_sfp_speed_valid(sfp, sfp->portspeed); 3450 if (sfp->state_query_cbfn) 3451 sfp->state_query_cbfn(sfp->state_query_cbarg, 3452 sfp->status); 3453 sfp->portspeed = BFA_PORT_SPEED_UNKNOWN; 3454 } 3455 3456 sfp->state_query_lock = 0; 3457 sfp->state_query_cbfn = NULL; 3458 } 3459 3460 /* 3461 * IOC event handler. 3462 */ 3463 static void 3464 bfa_sfp_notify(void *sfp_arg, enum bfa_ioc_event_e event) 3465 { 3466 struct bfa_sfp_s *sfp = sfp_arg; 3467 3468 bfa_trc(sfp, event); 3469 bfa_trc(sfp, sfp->lock); 3470 bfa_trc(sfp, sfp->state_query_lock); 3471 3472 switch (event) { 3473 case BFA_IOC_E_DISABLED: 3474 case BFA_IOC_E_FAILED: 3475 if (sfp->lock) { 3476 sfp->status = BFA_STATUS_IOC_FAILURE; 3477 bfa_cb_sfp_show(sfp); 3478 } 3479 3480 if (sfp->state_query_lock) { 3481 sfp->status = BFA_STATUS_IOC_FAILURE; 3482 bfa_cb_sfp_state_query(sfp); 3483 } 3484 break; 3485 3486 default: 3487 break; 3488 } 3489 } 3490 3491 /* 3492 * SFP's State Change Notification post to AEN 3493 */ 3494 static void 3495 bfa_sfp_scn_aen_post(struct bfa_sfp_s *sfp, struct bfi_sfp_scn_s *rsp) 3496 { 3497 struct bfad_s *bfad = (struct bfad_s *)sfp->ioc->bfa->bfad; 3498 struct bfa_aen_entry_s *aen_entry; 3499 enum bfa_port_aen_event aen_evt = 0; 3500 3501 bfa_trc(sfp, (((u64)rsp->pomlvl) << 16) | (((u64)rsp->sfpid) << 8) | 3502 ((u64)rsp->event)); 3503 3504 bfad_get_aen_entry(bfad, aen_entry); 3505 if (!aen_entry) 3506 return; 3507 3508 aen_entry->aen_data.port.ioc_type = bfa_ioc_get_type(sfp->ioc); 3509 aen_entry->aen_data.port.pwwn = sfp->ioc->attr->pwwn; 3510 aen_entry->aen_data.port.mac = bfa_ioc_get_mac(sfp->ioc); 3511 3512 switch (rsp->event) { 3513 case BFA_SFP_SCN_INSERTED: 3514 aen_evt = BFA_PORT_AEN_SFP_INSERT; 3515 break; 3516 case BFA_SFP_SCN_REMOVED: 3517 aen_evt = BFA_PORT_AEN_SFP_REMOVE; 3518 break; 3519 case BFA_SFP_SCN_FAILED: 3520 aen_evt = BFA_PORT_AEN_SFP_ACCESS_ERROR; 3521 break; 3522 case BFA_SFP_SCN_UNSUPPORT: 3523 aen_evt = BFA_PORT_AEN_SFP_UNSUPPORT; 3524 break; 3525 case BFA_SFP_SCN_POM: 3526 aen_evt = BFA_PORT_AEN_SFP_POM; 3527 aen_entry->aen_data.port.level = rsp->pomlvl; 3528 break; 3529 default: 3530 bfa_trc(sfp, rsp->event); 3531 WARN_ON(1); 3532 } 3533 3534 /* Send the AEN notification */ 3535 bfad_im_post_vendor_event(aen_entry, bfad, ++sfp->ioc->ioc_aen_seq, 3536 BFA_AEN_CAT_PORT, aen_evt); 3537 } 3538 3539 /* 3540 * SFP get data send 3541 */ 3542 static void 3543 bfa_sfp_getdata_send(struct bfa_sfp_s *sfp) 3544 { 3545 struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg; 3546 3547 bfa_trc(sfp, req->memtype); 3548 3549 /* build host command */ 3550 bfi_h2i_set(req->mh, BFI_MC_SFP, BFI_SFP_H2I_SHOW, 3551 bfa_ioc_portid(sfp->ioc)); 3552 3553 /* send mbox cmd */ 3554 bfa_ioc_mbox_queue(sfp->ioc, &sfp->mbcmd); 3555 } 3556 3557 /* 3558 * SFP is valid, read sfp data 3559 */ 3560 static void 3561 bfa_sfp_getdata(struct bfa_sfp_s *sfp, enum bfi_sfp_mem_e memtype) 3562 { 3563 struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg; 3564 3565 WARN_ON(sfp->lock != 0); 3566 bfa_trc(sfp, sfp->state); 3567 3568 sfp->lock = 1; 3569 sfp->memtype = memtype; 3570 req->memtype = memtype; 3571 3572 /* Setup SG list */ 3573 bfa_alen_set(&req->alen, sizeof(struct sfp_mem_s), sfp->dbuf_pa); 3574 3575 bfa_sfp_getdata_send(sfp); 3576 } 3577 3578 /* 3579 * SFP scn handler 3580 */ 3581 static void 3582 bfa_sfp_scn(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg) 3583 { 3584 struct bfi_sfp_scn_s *rsp = (struct bfi_sfp_scn_s *) msg; 3585 3586 switch (rsp->event) { 3587 case BFA_SFP_SCN_INSERTED: 3588 sfp->state = BFA_SFP_STATE_INSERTED; 3589 sfp->data_valid = 0; 3590 bfa_sfp_scn_aen_post(sfp, rsp); 3591 break; 3592 case BFA_SFP_SCN_REMOVED: 3593 sfp->state = BFA_SFP_STATE_REMOVED; 3594 sfp->data_valid = 0; 3595 bfa_sfp_scn_aen_post(sfp, rsp); 3596 break; 3597 case BFA_SFP_SCN_FAILED: 3598 sfp->state = BFA_SFP_STATE_FAILED; 3599 sfp->data_valid = 0; 3600 bfa_sfp_scn_aen_post(sfp, rsp); 3601 break; 3602 case BFA_SFP_SCN_UNSUPPORT: 3603 sfp->state = BFA_SFP_STATE_UNSUPPORT; 3604 bfa_sfp_scn_aen_post(sfp, rsp); 3605 if (!sfp->lock) 3606 bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL); 3607 break; 3608 case BFA_SFP_SCN_POM: 3609 bfa_sfp_scn_aen_post(sfp, rsp); 3610 break; 3611 case BFA_SFP_SCN_VALID: 3612 sfp->state = BFA_SFP_STATE_VALID; 3613 if (!sfp->lock) 3614 bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL); 3615 break; 3616 default: 3617 bfa_trc(sfp, rsp->event); 3618 WARN_ON(1); 3619 } 3620 } 3621 3622 /* 3623 * SFP show complete 3624 */ 3625 static void 3626 bfa_sfp_show_comp(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg) 3627 { 3628 struct bfi_sfp_rsp_s *rsp = (struct bfi_sfp_rsp_s *) msg; 3629 3630 if (!sfp->lock) { 3631 /* 3632 * receiving response after ioc failure 3633 */ 3634 bfa_trc(sfp, sfp->lock); 3635 return; 3636 } 3637 3638 bfa_trc(sfp, rsp->status); 3639 if (rsp->status == BFA_STATUS_OK) { 3640 sfp->data_valid = 1; 3641 if (sfp->state == BFA_SFP_STATE_VALID) 3642 sfp->status = BFA_STATUS_OK; 3643 else if (sfp->state == BFA_SFP_STATE_UNSUPPORT) 3644 sfp->status = BFA_STATUS_SFP_UNSUPP; 3645 else 3646 bfa_trc(sfp, sfp->state); 3647 } else { 3648 sfp->data_valid = 0; 3649 sfp->status = rsp->status; 3650 /* sfpshow shouldn't change sfp state */ 3651 } 3652 3653 bfa_trc(sfp, sfp->memtype); 3654 if (sfp->memtype == BFI_SFP_MEM_DIAGEXT) { 3655 bfa_trc(sfp, sfp->data_valid); 3656 if (sfp->data_valid) { 3657 u32 size = sizeof(struct sfp_mem_s); 3658 u8 *des = (u8 *) &(sfp->sfpmem->srlid_base); 3659 memcpy(des, sfp->dbuf_kva, size); 3660 } 3661 /* 3662 * Queue completion callback. 3663 */ 3664 bfa_cb_sfp_show(sfp); 3665 } else 3666 sfp->lock = 0; 3667 3668 bfa_trc(sfp, sfp->state_query_lock); 3669 if (sfp->state_query_lock) { 3670 sfp->state = rsp->state; 3671 /* Complete callback */ 3672 bfa_cb_sfp_state_query(sfp); 3673 } 3674 } 3675 3676 /* 3677 * SFP query fw sfp state 3678 */ 3679 static void 3680 bfa_sfp_state_query(struct bfa_sfp_s *sfp) 3681 { 3682 struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg; 3683 3684 /* Should not be doing query if not in _INIT state */ 3685 WARN_ON(sfp->state != BFA_SFP_STATE_INIT); 3686 WARN_ON(sfp->state_query_lock != 0); 3687 bfa_trc(sfp, sfp->state); 3688 3689 sfp->state_query_lock = 1; 3690 req->memtype = 0; 3691 3692 if (!sfp->lock) 3693 bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL); 3694 } 3695 3696 static void 3697 bfa_sfp_media_get(struct bfa_sfp_s *sfp) 3698 { 3699 enum bfa_defs_sfp_media_e *media = sfp->media; 3700 3701 *media = BFA_SFP_MEDIA_UNKNOWN; 3702 3703 if (sfp->state == BFA_SFP_STATE_UNSUPPORT) 3704 *media = BFA_SFP_MEDIA_UNSUPPORT; 3705 else if (sfp->state == BFA_SFP_STATE_VALID) { 3706 union sfp_xcvr_e10g_code_u e10g; 3707 struct sfp_mem_s *sfpmem = (struct sfp_mem_s *)sfp->dbuf_kva; 3708 u16 xmtr_tech = (sfpmem->srlid_base.xcvr[4] & 0x3) << 7 | 3709 (sfpmem->srlid_base.xcvr[5] >> 1); 3710 3711 e10g.b = sfpmem->srlid_base.xcvr[0]; 3712 bfa_trc(sfp, e10g.b); 3713 bfa_trc(sfp, xmtr_tech); 3714 /* check fc transmitter tech */ 3715 if ((xmtr_tech & SFP_XMTR_TECH_CU) || 3716 (xmtr_tech & SFP_XMTR_TECH_CP) || 3717 (xmtr_tech & SFP_XMTR_TECH_CA)) 3718 *media = BFA_SFP_MEDIA_CU; 3719 else if ((xmtr_tech & SFP_XMTR_TECH_EL_INTRA) || 3720 (xmtr_tech & SFP_XMTR_TECH_EL_INTER)) 3721 *media = BFA_SFP_MEDIA_EL; 3722 else if ((xmtr_tech & SFP_XMTR_TECH_LL) || 3723 (xmtr_tech & SFP_XMTR_TECH_LC)) 3724 *media = BFA_SFP_MEDIA_LW; 3725 else if ((xmtr_tech & SFP_XMTR_TECH_SL) || 3726 (xmtr_tech & SFP_XMTR_TECH_SN) || 3727 (xmtr_tech & SFP_XMTR_TECH_SA)) 3728 *media = BFA_SFP_MEDIA_SW; 3729 /* Check 10G Ethernet Compilance code */ 3730 else if (e10g.b & 0x10) 3731 *media = BFA_SFP_MEDIA_SW; 3732 else if (e10g.b & 0x60) 3733 *media = BFA_SFP_MEDIA_LW; 3734 else if (e10g.r.e10g_unall & 0x80) 3735 *media = BFA_SFP_MEDIA_UNKNOWN; 3736 else 3737 bfa_trc(sfp, 0); 3738 } else 3739 bfa_trc(sfp, sfp->state); 3740 } 3741 3742 static bfa_status_t 3743 bfa_sfp_speed_valid(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed) 3744 { 3745 struct sfp_mem_s *sfpmem = (struct sfp_mem_s *)sfp->dbuf_kva; 3746 struct sfp_xcvr_s *xcvr = (struct sfp_xcvr_s *) sfpmem->srlid_base.xcvr; 3747 union sfp_xcvr_fc3_code_u fc3 = xcvr->fc3; 3748 union sfp_xcvr_e10g_code_u e10g = xcvr->e10g; 3749 3750 if (portspeed == BFA_PORT_SPEED_10GBPS) { 3751 if (e10g.r.e10g_sr || e10g.r.e10g_lr) 3752 return BFA_STATUS_OK; 3753 else { 3754 bfa_trc(sfp, e10g.b); 3755 return BFA_STATUS_UNSUPP_SPEED; 3756 } 3757 } 3758 if (((portspeed & BFA_PORT_SPEED_16GBPS) && fc3.r.mb1600) || 3759 ((portspeed & BFA_PORT_SPEED_8GBPS) && fc3.r.mb800) || 3760 ((portspeed & BFA_PORT_SPEED_4GBPS) && fc3.r.mb400) || 3761 ((portspeed & BFA_PORT_SPEED_2GBPS) && fc3.r.mb200) || 3762 ((portspeed & BFA_PORT_SPEED_1GBPS) && fc3.r.mb100)) 3763 return BFA_STATUS_OK; 3764 else { 3765 bfa_trc(sfp, portspeed); 3766 bfa_trc(sfp, fc3.b); 3767 bfa_trc(sfp, e10g.b); 3768 return BFA_STATUS_UNSUPP_SPEED; 3769 } 3770 } 3771 3772 /* 3773 * SFP hmbox handler 3774 */ 3775 void 3776 bfa_sfp_intr(void *sfparg, struct bfi_mbmsg_s *msg) 3777 { 3778 struct bfa_sfp_s *sfp = sfparg; 3779 3780 switch (msg->mh.msg_id) { 3781 case BFI_SFP_I2H_SHOW: 3782 bfa_sfp_show_comp(sfp, msg); 3783 break; 3784 3785 case BFI_SFP_I2H_SCN: 3786 bfa_sfp_scn(sfp, msg); 3787 break; 3788 3789 default: 3790 bfa_trc(sfp, msg->mh.msg_id); 3791 WARN_ON(1); 3792 } 3793 } 3794 3795 /* 3796 * Return DMA memory needed by sfp module. 3797 */ 3798 u32 3799 bfa_sfp_meminfo(void) 3800 { 3801 return BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ); 3802 } 3803 3804 /* 3805 * Attach virtual and physical memory for SFP. 3806 */ 3807 void 3808 bfa_sfp_attach(struct bfa_sfp_s *sfp, struct bfa_ioc_s *ioc, void *dev, 3809 struct bfa_trc_mod_s *trcmod) 3810 { 3811 sfp->dev = dev; 3812 sfp->ioc = ioc; 3813 sfp->trcmod = trcmod; 3814 3815 sfp->cbfn = NULL; 3816 sfp->cbarg = NULL; 3817 sfp->sfpmem = NULL; 3818 sfp->lock = 0; 3819 sfp->data_valid = 0; 3820 sfp->state = BFA_SFP_STATE_INIT; 3821 sfp->state_query_lock = 0; 3822 sfp->state_query_cbfn = NULL; 3823 sfp->state_query_cbarg = NULL; 3824 sfp->media = NULL; 3825 sfp->portspeed = BFA_PORT_SPEED_UNKNOWN; 3826 sfp->is_elb = BFA_FALSE; 3827 3828 bfa_ioc_mbox_regisr(sfp->ioc, BFI_MC_SFP, bfa_sfp_intr, sfp); 3829 bfa_q_qe_init(&sfp->ioc_notify); 3830 bfa_ioc_notify_init(&sfp->ioc_notify, bfa_sfp_notify, sfp); 3831 list_add_tail(&sfp->ioc_notify.qe, &sfp->ioc->notify_q); 3832 } 3833 3834 /* 3835 * Claim Memory for SFP 3836 */ 3837 void 3838 bfa_sfp_memclaim(struct bfa_sfp_s *sfp, u8 *dm_kva, u64 dm_pa) 3839 { 3840 sfp->dbuf_kva = dm_kva; 3841 sfp->dbuf_pa = dm_pa; 3842 memset(sfp->dbuf_kva, 0, sizeof(struct sfp_mem_s)); 3843 3844 dm_kva += BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ); 3845 dm_pa += BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ); 3846 } 3847 3848 /* 3849 * Show SFP eeprom content 3850 * 3851 * @param[in] sfp - bfa sfp module 3852 * 3853 * @param[out] sfpmem - sfp eeprom data 3854 * 3855 */ 3856 bfa_status_t 3857 bfa_sfp_show(struct bfa_sfp_s *sfp, struct sfp_mem_s *sfpmem, 3858 bfa_cb_sfp_t cbfn, void *cbarg) 3859 { 3860 3861 if (!bfa_ioc_is_operational(sfp->ioc)) { 3862 bfa_trc(sfp, 0); 3863 return BFA_STATUS_IOC_NON_OP; 3864 } 3865 3866 if (sfp->lock) { 3867 bfa_trc(sfp, 0); 3868 return BFA_STATUS_DEVBUSY; 3869 } 3870 3871 sfp->cbfn = cbfn; 3872 sfp->cbarg = cbarg; 3873 sfp->sfpmem = sfpmem; 3874 3875 bfa_sfp_getdata(sfp, BFI_SFP_MEM_DIAGEXT); 3876 return BFA_STATUS_OK; 3877 } 3878 3879 /* 3880 * Return SFP Media type 3881 * 3882 * @param[in] sfp - bfa sfp module 3883 * 3884 * @param[out] media - port speed from user 3885 * 3886 */ 3887 bfa_status_t 3888 bfa_sfp_media(struct bfa_sfp_s *sfp, enum bfa_defs_sfp_media_e *media, 3889 bfa_cb_sfp_t cbfn, void *cbarg) 3890 { 3891 if (!bfa_ioc_is_operational(sfp->ioc)) { 3892 bfa_trc(sfp, 0); 3893 return BFA_STATUS_IOC_NON_OP; 3894 } 3895 3896 sfp->media = media; 3897 if (sfp->state == BFA_SFP_STATE_INIT) { 3898 if (sfp->state_query_lock) { 3899 bfa_trc(sfp, 0); 3900 return BFA_STATUS_DEVBUSY; 3901 } else { 3902 sfp->state_query_cbfn = cbfn; 3903 sfp->state_query_cbarg = cbarg; 3904 bfa_sfp_state_query(sfp); 3905 return BFA_STATUS_SFP_NOT_READY; 3906 } 3907 } 3908 3909 bfa_sfp_media_get(sfp); 3910 return BFA_STATUS_OK; 3911 } 3912 3913 /* 3914 * Check if user set port speed is allowed by the SFP 3915 * 3916 * @param[in] sfp - bfa sfp module 3917 * @param[in] portspeed - port speed from user 3918 * 3919 */ 3920 bfa_status_t 3921 bfa_sfp_speed(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed, 3922 bfa_cb_sfp_t cbfn, void *cbarg) 3923 { 3924 WARN_ON(portspeed == BFA_PORT_SPEED_UNKNOWN); 3925 3926 if (!bfa_ioc_is_operational(sfp->ioc)) 3927 return BFA_STATUS_IOC_NON_OP; 3928 3929 /* For Mezz card, all speed is allowed */ 3930 if (bfa_mfg_is_mezz(sfp->ioc->attr->card_type)) 3931 return BFA_STATUS_OK; 3932 3933 /* Check SFP state */ 3934 sfp->portspeed = portspeed; 3935 if (sfp->state == BFA_SFP_STATE_INIT) { 3936 if (sfp->state_query_lock) { 3937 bfa_trc(sfp, 0); 3938 return BFA_STATUS_DEVBUSY; 3939 } else { 3940 sfp->state_query_cbfn = cbfn; 3941 sfp->state_query_cbarg = cbarg; 3942 bfa_sfp_state_query(sfp); 3943 return BFA_STATUS_SFP_NOT_READY; 3944 } 3945 } 3946 3947 if (sfp->state == BFA_SFP_STATE_REMOVED || 3948 sfp->state == BFA_SFP_STATE_FAILED) { 3949 bfa_trc(sfp, sfp->state); 3950 return BFA_STATUS_NO_SFP_DEV; 3951 } 3952 3953 if (sfp->state == BFA_SFP_STATE_INSERTED) { 3954 bfa_trc(sfp, sfp->state); 3955 return BFA_STATUS_DEVBUSY; /* sfp is reading data */ 3956 } 3957 3958 /* For eloopback, all speed is allowed */ 3959 if (sfp->is_elb) 3960 return BFA_STATUS_OK; 3961 3962 return bfa_sfp_speed_valid(sfp, portspeed); 3963 } 3964 3965 /* 3966 * Flash module specific 3967 */ 3968 3969 /* 3970 * FLASH DMA buffer should be big enough to hold both MFG block and 3971 * asic block(64k) at the same time and also should be 2k aligned to 3972 * avoid write segement to cross sector boundary. 3973 */ 3974 #define BFA_FLASH_SEG_SZ 2048 3975 #define BFA_FLASH_DMA_BUF_SZ \ 3976 BFA_ROUNDUP(0x010000 + sizeof(struct bfa_mfg_block_s), BFA_FLASH_SEG_SZ) 3977 3978 static void 3979 bfa_flash_aen_audit_post(struct bfa_ioc_s *ioc, enum bfa_audit_aen_event event, 3980 int inst, int type) 3981 { 3982 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 3983 struct bfa_aen_entry_s *aen_entry; 3984 3985 bfad_get_aen_entry(bfad, aen_entry); 3986 if (!aen_entry) 3987 return; 3988 3989 aen_entry->aen_data.audit.pwwn = ioc->attr->pwwn; 3990 aen_entry->aen_data.audit.partition_inst = inst; 3991 aen_entry->aen_data.audit.partition_type = type; 3992 3993 /* Send the AEN notification */ 3994 bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq, 3995 BFA_AEN_CAT_AUDIT, event); 3996 } 3997 3998 static void 3999 bfa_flash_cb(struct bfa_flash_s *flash) 4000 { 4001 flash->op_busy = 0; 4002 if (flash->cbfn) 4003 flash->cbfn(flash->cbarg, flash->status); 4004 } 4005 4006 static void 4007 bfa_flash_notify(void *cbarg, enum bfa_ioc_event_e event) 4008 { 4009 struct bfa_flash_s *flash = cbarg; 4010 4011 bfa_trc(flash, event); 4012 switch (event) { 4013 case BFA_IOC_E_DISABLED: 4014 case BFA_IOC_E_FAILED: 4015 if (flash->op_busy) { 4016 flash->status = BFA_STATUS_IOC_FAILURE; 4017 flash->cbfn(flash->cbarg, flash->status); 4018 flash->op_busy = 0; 4019 } 4020 break; 4021 4022 default: 4023 break; 4024 } 4025 } 4026 4027 /* 4028 * Send flash attribute query request. 4029 * 4030 * @param[in] cbarg - callback argument 4031 */ 4032 static void 4033 bfa_flash_query_send(void *cbarg) 4034 { 4035 struct bfa_flash_s *flash = cbarg; 4036 struct bfi_flash_query_req_s *msg = 4037 (struct bfi_flash_query_req_s *) flash->mb.msg; 4038 4039 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_QUERY_REQ, 4040 bfa_ioc_portid(flash->ioc)); 4041 bfa_alen_set(&msg->alen, sizeof(struct bfa_flash_attr_s), 4042 flash->dbuf_pa); 4043 bfa_ioc_mbox_queue(flash->ioc, &flash->mb); 4044 } 4045 4046 /* 4047 * Send flash write request. 4048 * 4049 * @param[in] cbarg - callback argument 4050 */ 4051 static void 4052 bfa_flash_write_send(struct bfa_flash_s *flash) 4053 { 4054 struct bfi_flash_write_req_s *msg = 4055 (struct bfi_flash_write_req_s *) flash->mb.msg; 4056 u32 len; 4057 4058 msg->type = be32_to_cpu(flash->type); 4059 msg->instance = flash->instance; 4060 msg->offset = be32_to_cpu(flash->addr_off + flash->offset); 4061 len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ? 4062 flash->residue : BFA_FLASH_DMA_BUF_SZ; 4063 msg->length = be32_to_cpu(len); 4064 4065 /* indicate if it's the last msg of the whole write operation */ 4066 msg->last = (len == flash->residue) ? 1 : 0; 4067 4068 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_WRITE_REQ, 4069 bfa_ioc_portid(flash->ioc)); 4070 bfa_alen_set(&msg->alen, len, flash->dbuf_pa); 4071 memcpy(flash->dbuf_kva, flash->ubuf + flash->offset, len); 4072 bfa_ioc_mbox_queue(flash->ioc, &flash->mb); 4073 4074 flash->residue -= len; 4075 flash->offset += len; 4076 } 4077 4078 /* 4079 * Send flash read request. 4080 * 4081 * @param[in] cbarg - callback argument 4082 */ 4083 static void 4084 bfa_flash_read_send(void *cbarg) 4085 { 4086 struct bfa_flash_s *flash = cbarg; 4087 struct bfi_flash_read_req_s *msg = 4088 (struct bfi_flash_read_req_s *) flash->mb.msg; 4089 u32 len; 4090 4091 msg->type = be32_to_cpu(flash->type); 4092 msg->instance = flash->instance; 4093 msg->offset = be32_to_cpu(flash->addr_off + flash->offset); 4094 len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ? 4095 flash->residue : BFA_FLASH_DMA_BUF_SZ; 4096 msg->length = be32_to_cpu(len); 4097 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_READ_REQ, 4098 bfa_ioc_portid(flash->ioc)); 4099 bfa_alen_set(&msg->alen, len, flash->dbuf_pa); 4100 bfa_ioc_mbox_queue(flash->ioc, &flash->mb); 4101 } 4102 4103 /* 4104 * Send flash erase request. 4105 * 4106 * @param[in] cbarg - callback argument 4107 */ 4108 static void 4109 bfa_flash_erase_send(void *cbarg) 4110 { 4111 struct bfa_flash_s *flash = cbarg; 4112 struct bfi_flash_erase_req_s *msg = 4113 (struct bfi_flash_erase_req_s *) flash->mb.msg; 4114 4115 msg->type = be32_to_cpu(flash->type); 4116 msg->instance = flash->instance; 4117 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_ERASE_REQ, 4118 bfa_ioc_portid(flash->ioc)); 4119 bfa_ioc_mbox_queue(flash->ioc, &flash->mb); 4120 } 4121 4122 /* 4123 * Process flash response messages upon receiving interrupts. 4124 * 4125 * @param[in] flasharg - flash structure 4126 * @param[in] msg - message structure 4127 */ 4128 static void 4129 bfa_flash_intr(void *flasharg, struct bfi_mbmsg_s *msg) 4130 { 4131 struct bfa_flash_s *flash = flasharg; 4132 u32 status; 4133 4134 union { 4135 struct bfi_flash_query_rsp_s *query; 4136 struct bfi_flash_erase_rsp_s *erase; 4137 struct bfi_flash_write_rsp_s *write; 4138 struct bfi_flash_read_rsp_s *read; 4139 struct bfi_flash_event_s *event; 4140 struct bfi_mbmsg_s *msg; 4141 } m; 4142 4143 m.msg = msg; 4144 bfa_trc(flash, msg->mh.msg_id); 4145 4146 if (!flash->op_busy && msg->mh.msg_id != BFI_FLASH_I2H_EVENT) { 4147 /* receiving response after ioc failure */ 4148 bfa_trc(flash, 0x9999); 4149 return; 4150 } 4151 4152 switch (msg->mh.msg_id) { 4153 case BFI_FLASH_I2H_QUERY_RSP: 4154 status = be32_to_cpu(m.query->status); 4155 bfa_trc(flash, status); 4156 if (status == BFA_STATUS_OK) { 4157 u32 i; 4158 struct bfa_flash_attr_s *attr, *f; 4159 4160 attr = (struct bfa_flash_attr_s *) flash->ubuf; 4161 f = (struct bfa_flash_attr_s *) flash->dbuf_kva; 4162 attr->status = be32_to_cpu(f->status); 4163 attr->npart = be32_to_cpu(f->npart); 4164 bfa_trc(flash, attr->status); 4165 bfa_trc(flash, attr->npart); 4166 for (i = 0; i < attr->npart; i++) { 4167 attr->part[i].part_type = 4168 be32_to_cpu(f->part[i].part_type); 4169 attr->part[i].part_instance = 4170 be32_to_cpu(f->part[i].part_instance); 4171 attr->part[i].part_off = 4172 be32_to_cpu(f->part[i].part_off); 4173 attr->part[i].part_size = 4174 be32_to_cpu(f->part[i].part_size); 4175 attr->part[i].part_len = 4176 be32_to_cpu(f->part[i].part_len); 4177 attr->part[i].part_status = 4178 be32_to_cpu(f->part[i].part_status); 4179 } 4180 } 4181 flash->status = status; 4182 bfa_flash_cb(flash); 4183 break; 4184 case BFI_FLASH_I2H_ERASE_RSP: 4185 status = be32_to_cpu(m.erase->status); 4186 bfa_trc(flash, status); 4187 flash->status = status; 4188 bfa_flash_cb(flash); 4189 break; 4190 case BFI_FLASH_I2H_WRITE_RSP: 4191 status = be32_to_cpu(m.write->status); 4192 bfa_trc(flash, status); 4193 if (status != BFA_STATUS_OK || flash->residue == 0) { 4194 flash->status = status; 4195 bfa_flash_cb(flash); 4196 } else { 4197 bfa_trc(flash, flash->offset); 4198 bfa_flash_write_send(flash); 4199 } 4200 break; 4201 case BFI_FLASH_I2H_READ_RSP: 4202 status = be32_to_cpu(m.read->status); 4203 bfa_trc(flash, status); 4204 if (status != BFA_STATUS_OK) { 4205 flash->status = status; 4206 bfa_flash_cb(flash); 4207 } else { 4208 u32 len = be32_to_cpu(m.read->length); 4209 bfa_trc(flash, flash->offset); 4210 bfa_trc(flash, len); 4211 memcpy(flash->ubuf + flash->offset, 4212 flash->dbuf_kva, len); 4213 flash->residue -= len; 4214 flash->offset += len; 4215 if (flash->residue == 0) { 4216 flash->status = status; 4217 bfa_flash_cb(flash); 4218 } else 4219 bfa_flash_read_send(flash); 4220 } 4221 break; 4222 case BFI_FLASH_I2H_BOOT_VER_RSP: 4223 break; 4224 case BFI_FLASH_I2H_EVENT: 4225 status = be32_to_cpu(m.event->status); 4226 bfa_trc(flash, status); 4227 if (status == BFA_STATUS_BAD_FWCFG) 4228 bfa_ioc_aen_post(flash->ioc, BFA_IOC_AEN_FWCFG_ERROR); 4229 else if (status == BFA_STATUS_INVALID_VENDOR) { 4230 u32 param; 4231 param = be32_to_cpu(m.event->param); 4232 bfa_trc(flash, param); 4233 bfa_ioc_aen_post(flash->ioc, 4234 BFA_IOC_AEN_INVALID_VENDOR); 4235 } 4236 break; 4237 4238 default: 4239 WARN_ON(1); 4240 } 4241 } 4242 4243 /* 4244 * Flash memory info API. 4245 * 4246 * @param[in] mincfg - minimal cfg variable 4247 */ 4248 u32 4249 bfa_flash_meminfo(bfa_boolean_t mincfg) 4250 { 4251 /* min driver doesn't need flash */ 4252 if (mincfg) 4253 return 0; 4254 return BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 4255 } 4256 4257 /* 4258 * Flash attach API. 4259 * 4260 * @param[in] flash - flash structure 4261 * @param[in] ioc - ioc structure 4262 * @param[in] dev - device structure 4263 * @param[in] trcmod - trace module 4264 * @param[in] logmod - log module 4265 */ 4266 void 4267 bfa_flash_attach(struct bfa_flash_s *flash, struct bfa_ioc_s *ioc, void *dev, 4268 struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg) 4269 { 4270 flash->ioc = ioc; 4271 flash->trcmod = trcmod; 4272 flash->cbfn = NULL; 4273 flash->cbarg = NULL; 4274 flash->op_busy = 0; 4275 4276 bfa_ioc_mbox_regisr(flash->ioc, BFI_MC_FLASH, bfa_flash_intr, flash); 4277 bfa_q_qe_init(&flash->ioc_notify); 4278 bfa_ioc_notify_init(&flash->ioc_notify, bfa_flash_notify, flash); 4279 list_add_tail(&flash->ioc_notify.qe, &flash->ioc->notify_q); 4280 4281 /* min driver doesn't need flash */ 4282 if (mincfg) { 4283 flash->dbuf_kva = NULL; 4284 flash->dbuf_pa = 0; 4285 } 4286 } 4287 4288 /* 4289 * Claim memory for flash 4290 * 4291 * @param[in] flash - flash structure 4292 * @param[in] dm_kva - pointer to virtual memory address 4293 * @param[in] dm_pa - physical memory address 4294 * @param[in] mincfg - minimal cfg variable 4295 */ 4296 void 4297 bfa_flash_memclaim(struct bfa_flash_s *flash, u8 *dm_kva, u64 dm_pa, 4298 bfa_boolean_t mincfg) 4299 { 4300 if (mincfg) 4301 return; 4302 4303 flash->dbuf_kva = dm_kva; 4304 flash->dbuf_pa = dm_pa; 4305 memset(flash->dbuf_kva, 0, BFA_FLASH_DMA_BUF_SZ); 4306 dm_kva += BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 4307 dm_pa += BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 4308 } 4309 4310 /* 4311 * Get flash attribute. 4312 * 4313 * @param[in] flash - flash structure 4314 * @param[in] attr - flash attribute structure 4315 * @param[in] cbfn - callback function 4316 * @param[in] cbarg - callback argument 4317 * 4318 * Return status. 4319 */ 4320 bfa_status_t 4321 bfa_flash_get_attr(struct bfa_flash_s *flash, struct bfa_flash_attr_s *attr, 4322 bfa_cb_flash_t cbfn, void *cbarg) 4323 { 4324 bfa_trc(flash, BFI_FLASH_H2I_QUERY_REQ); 4325 4326 if (!bfa_ioc_is_operational(flash->ioc)) 4327 return BFA_STATUS_IOC_NON_OP; 4328 4329 if (flash->op_busy) { 4330 bfa_trc(flash, flash->op_busy); 4331 return BFA_STATUS_DEVBUSY; 4332 } 4333 4334 flash->op_busy = 1; 4335 flash->cbfn = cbfn; 4336 flash->cbarg = cbarg; 4337 flash->ubuf = (u8 *) attr; 4338 bfa_flash_query_send(flash); 4339 4340 return BFA_STATUS_OK; 4341 } 4342 4343 /* 4344 * Erase flash partition. 4345 * 4346 * @param[in] flash - flash structure 4347 * @param[in] type - flash partition type 4348 * @param[in] instance - flash partition instance 4349 * @param[in] cbfn - callback function 4350 * @param[in] cbarg - callback argument 4351 * 4352 * Return status. 4353 */ 4354 bfa_status_t 4355 bfa_flash_erase_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type, 4356 u8 instance, bfa_cb_flash_t cbfn, void *cbarg) 4357 { 4358 bfa_trc(flash, BFI_FLASH_H2I_ERASE_REQ); 4359 bfa_trc(flash, type); 4360 bfa_trc(flash, instance); 4361 4362 if (!bfa_ioc_is_operational(flash->ioc)) 4363 return BFA_STATUS_IOC_NON_OP; 4364 4365 if (flash->op_busy) { 4366 bfa_trc(flash, flash->op_busy); 4367 return BFA_STATUS_DEVBUSY; 4368 } 4369 4370 flash->op_busy = 1; 4371 flash->cbfn = cbfn; 4372 flash->cbarg = cbarg; 4373 flash->type = type; 4374 flash->instance = instance; 4375 4376 bfa_flash_erase_send(flash); 4377 bfa_flash_aen_audit_post(flash->ioc, BFA_AUDIT_AEN_FLASH_ERASE, 4378 instance, type); 4379 return BFA_STATUS_OK; 4380 } 4381 4382 /* 4383 * Update flash partition. 4384 * 4385 * @param[in] flash - flash structure 4386 * @param[in] type - flash partition type 4387 * @param[in] instance - flash partition instance 4388 * @param[in] buf - update data buffer 4389 * @param[in] len - data buffer length 4390 * @param[in] offset - offset relative to the partition starting address 4391 * @param[in] cbfn - callback function 4392 * @param[in] cbarg - callback argument 4393 * 4394 * Return status. 4395 */ 4396 bfa_status_t 4397 bfa_flash_update_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type, 4398 u8 instance, void *buf, u32 len, u32 offset, 4399 bfa_cb_flash_t cbfn, void *cbarg) 4400 { 4401 bfa_trc(flash, BFI_FLASH_H2I_WRITE_REQ); 4402 bfa_trc(flash, type); 4403 bfa_trc(flash, instance); 4404 bfa_trc(flash, len); 4405 bfa_trc(flash, offset); 4406 4407 if (!bfa_ioc_is_operational(flash->ioc)) 4408 return BFA_STATUS_IOC_NON_OP; 4409 4410 /* 4411 * 'len' must be in word (4-byte) boundary 4412 * 'offset' must be in sector (16kb) boundary 4413 */ 4414 if (!len || (len & 0x03) || (offset & 0x00003FFF)) 4415 return BFA_STATUS_FLASH_BAD_LEN; 4416 4417 if (type == BFA_FLASH_PART_MFG) 4418 return BFA_STATUS_EINVAL; 4419 4420 if (flash->op_busy) { 4421 bfa_trc(flash, flash->op_busy); 4422 return BFA_STATUS_DEVBUSY; 4423 } 4424 4425 flash->op_busy = 1; 4426 flash->cbfn = cbfn; 4427 flash->cbarg = cbarg; 4428 flash->type = type; 4429 flash->instance = instance; 4430 flash->residue = len; 4431 flash->offset = 0; 4432 flash->addr_off = offset; 4433 flash->ubuf = buf; 4434 4435 bfa_flash_write_send(flash); 4436 return BFA_STATUS_OK; 4437 } 4438 4439 /* 4440 * Read flash partition. 4441 * 4442 * @param[in] flash - flash structure 4443 * @param[in] type - flash partition type 4444 * @param[in] instance - flash partition instance 4445 * @param[in] buf - read data buffer 4446 * @param[in] len - data buffer length 4447 * @param[in] offset - offset relative to the partition starting address 4448 * @param[in] cbfn - callback function 4449 * @param[in] cbarg - callback argument 4450 * 4451 * Return status. 4452 */ 4453 bfa_status_t 4454 bfa_flash_read_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type, 4455 u8 instance, void *buf, u32 len, u32 offset, 4456 bfa_cb_flash_t cbfn, void *cbarg) 4457 { 4458 bfa_trc(flash, BFI_FLASH_H2I_READ_REQ); 4459 bfa_trc(flash, type); 4460 bfa_trc(flash, instance); 4461 bfa_trc(flash, len); 4462 bfa_trc(flash, offset); 4463 4464 if (!bfa_ioc_is_operational(flash->ioc)) 4465 return BFA_STATUS_IOC_NON_OP; 4466 4467 /* 4468 * 'len' must be in word (4-byte) boundary 4469 * 'offset' must be in sector (16kb) boundary 4470 */ 4471 if (!len || (len & 0x03) || (offset & 0x00003FFF)) 4472 return BFA_STATUS_FLASH_BAD_LEN; 4473 4474 if (flash->op_busy) { 4475 bfa_trc(flash, flash->op_busy); 4476 return BFA_STATUS_DEVBUSY; 4477 } 4478 4479 flash->op_busy = 1; 4480 flash->cbfn = cbfn; 4481 flash->cbarg = cbarg; 4482 flash->type = type; 4483 flash->instance = instance; 4484 flash->residue = len; 4485 flash->offset = 0; 4486 flash->addr_off = offset; 4487 flash->ubuf = buf; 4488 bfa_flash_read_send(flash); 4489 4490 return BFA_STATUS_OK; 4491 } 4492 4493 /* 4494 * DIAG module specific 4495 */ 4496 4497 #define BFA_DIAG_MEMTEST_TOV 50000 /* memtest timeout in msec */ 4498 #define BFA_DIAG_FWPING_TOV 1000 /* msec */ 4499 4500 /* IOC event handler */ 4501 static void 4502 bfa_diag_notify(void *diag_arg, enum bfa_ioc_event_e event) 4503 { 4504 struct bfa_diag_s *diag = diag_arg; 4505 4506 bfa_trc(diag, event); 4507 bfa_trc(diag, diag->block); 4508 bfa_trc(diag, diag->fwping.lock); 4509 bfa_trc(diag, diag->tsensor.lock); 4510 4511 switch (event) { 4512 case BFA_IOC_E_DISABLED: 4513 case BFA_IOC_E_FAILED: 4514 if (diag->fwping.lock) { 4515 diag->fwping.status = BFA_STATUS_IOC_FAILURE; 4516 diag->fwping.cbfn(diag->fwping.cbarg, 4517 diag->fwping.status); 4518 diag->fwping.lock = 0; 4519 } 4520 4521 if (diag->tsensor.lock) { 4522 diag->tsensor.status = BFA_STATUS_IOC_FAILURE; 4523 diag->tsensor.cbfn(diag->tsensor.cbarg, 4524 diag->tsensor.status); 4525 diag->tsensor.lock = 0; 4526 } 4527 4528 if (diag->block) { 4529 if (diag->timer_active) { 4530 bfa_timer_stop(&diag->timer); 4531 diag->timer_active = 0; 4532 } 4533 4534 diag->status = BFA_STATUS_IOC_FAILURE; 4535 diag->cbfn(diag->cbarg, diag->status); 4536 diag->block = 0; 4537 } 4538 break; 4539 4540 default: 4541 break; 4542 } 4543 } 4544 4545 static void 4546 bfa_diag_memtest_done(void *cbarg) 4547 { 4548 struct bfa_diag_s *diag = cbarg; 4549 struct bfa_ioc_s *ioc = diag->ioc; 4550 struct bfa_diag_memtest_result *res = diag->result; 4551 u32 loff = BFI_BOOT_MEMTEST_RES_ADDR; 4552 u32 pgnum, pgoff, i; 4553 4554 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff); 4555 pgoff = PSS_SMEM_PGOFF(loff); 4556 4557 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 4558 4559 for (i = 0; i < (sizeof(struct bfa_diag_memtest_result) / 4560 sizeof(u32)); i++) { 4561 /* read test result from smem */ 4562 *((u32 *) res + i) = 4563 bfa_mem_read(ioc->ioc_regs.smem_page_start, loff); 4564 loff += sizeof(u32); 4565 } 4566 4567 /* Reset IOC fwstates to BFI_IOC_UNINIT */ 4568 bfa_ioc_reset_fwstate(ioc); 4569 4570 res->status = swab32(res->status); 4571 bfa_trc(diag, res->status); 4572 4573 if (res->status == BFI_BOOT_MEMTEST_RES_SIG) 4574 diag->status = BFA_STATUS_OK; 4575 else { 4576 diag->status = BFA_STATUS_MEMTEST_FAILED; 4577 res->addr = swab32(res->addr); 4578 res->exp = swab32(res->exp); 4579 res->act = swab32(res->act); 4580 res->err_status = swab32(res->err_status); 4581 res->err_status1 = swab32(res->err_status1); 4582 res->err_addr = swab32(res->err_addr); 4583 bfa_trc(diag, res->addr); 4584 bfa_trc(diag, res->exp); 4585 bfa_trc(diag, res->act); 4586 bfa_trc(diag, res->err_status); 4587 bfa_trc(diag, res->err_status1); 4588 bfa_trc(diag, res->err_addr); 4589 } 4590 diag->timer_active = 0; 4591 diag->cbfn(diag->cbarg, diag->status); 4592 diag->block = 0; 4593 } 4594 4595 /* 4596 * Firmware ping 4597 */ 4598 4599 /* 4600 * Perform DMA test directly 4601 */ 4602 static void 4603 diag_fwping_send(struct bfa_diag_s *diag) 4604 { 4605 struct bfi_diag_fwping_req_s *fwping_req; 4606 u32 i; 4607 4608 bfa_trc(diag, diag->fwping.dbuf_pa); 4609 4610 /* fill DMA area with pattern */ 4611 for (i = 0; i < (BFI_DIAG_DMA_BUF_SZ >> 2); i++) 4612 *((u32 *)diag->fwping.dbuf_kva + i) = diag->fwping.data; 4613 4614 /* Fill mbox msg */ 4615 fwping_req = (struct bfi_diag_fwping_req_s *)diag->fwping.mbcmd.msg; 4616 4617 /* Setup SG list */ 4618 bfa_alen_set(&fwping_req->alen, BFI_DIAG_DMA_BUF_SZ, 4619 diag->fwping.dbuf_pa); 4620 /* Set up dma count */ 4621 fwping_req->count = cpu_to_be32(diag->fwping.count); 4622 /* Set up data pattern */ 4623 fwping_req->data = diag->fwping.data; 4624 4625 /* build host command */ 4626 bfi_h2i_set(fwping_req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_FWPING, 4627 bfa_ioc_portid(diag->ioc)); 4628 4629 /* send mbox cmd */ 4630 bfa_ioc_mbox_queue(diag->ioc, &diag->fwping.mbcmd); 4631 } 4632 4633 static void 4634 diag_fwping_comp(struct bfa_diag_s *diag, 4635 struct bfi_diag_fwping_rsp_s *diag_rsp) 4636 { 4637 u32 rsp_data = diag_rsp->data; 4638 u8 rsp_dma_status = diag_rsp->dma_status; 4639 4640 bfa_trc(diag, rsp_data); 4641 bfa_trc(diag, rsp_dma_status); 4642 4643 if (rsp_dma_status == BFA_STATUS_OK) { 4644 u32 i, pat; 4645 pat = (diag->fwping.count & 0x1) ? ~(diag->fwping.data) : 4646 diag->fwping.data; 4647 /* Check mbox data */ 4648 if (diag->fwping.data != rsp_data) { 4649 bfa_trc(diag, rsp_data); 4650 diag->fwping.result->dmastatus = 4651 BFA_STATUS_DATACORRUPTED; 4652 diag->fwping.status = BFA_STATUS_DATACORRUPTED; 4653 diag->fwping.cbfn(diag->fwping.cbarg, 4654 diag->fwping.status); 4655 diag->fwping.lock = 0; 4656 return; 4657 } 4658 /* Check dma pattern */ 4659 for (i = 0; i < (BFI_DIAG_DMA_BUF_SZ >> 2); i++) { 4660 if (*((u32 *)diag->fwping.dbuf_kva + i) != pat) { 4661 bfa_trc(diag, i); 4662 bfa_trc(diag, pat); 4663 bfa_trc(diag, 4664 *((u32 *)diag->fwping.dbuf_kva + i)); 4665 diag->fwping.result->dmastatus = 4666 BFA_STATUS_DATACORRUPTED; 4667 diag->fwping.status = BFA_STATUS_DATACORRUPTED; 4668 diag->fwping.cbfn(diag->fwping.cbarg, 4669 diag->fwping.status); 4670 diag->fwping.lock = 0; 4671 return; 4672 } 4673 } 4674 diag->fwping.result->dmastatus = BFA_STATUS_OK; 4675 diag->fwping.status = BFA_STATUS_OK; 4676 diag->fwping.cbfn(diag->fwping.cbarg, diag->fwping.status); 4677 diag->fwping.lock = 0; 4678 } else { 4679 diag->fwping.status = BFA_STATUS_HDMA_FAILED; 4680 diag->fwping.cbfn(diag->fwping.cbarg, diag->fwping.status); 4681 diag->fwping.lock = 0; 4682 } 4683 } 4684 4685 /* 4686 * Temperature Sensor 4687 */ 4688 4689 static void 4690 diag_tempsensor_send(struct bfa_diag_s *diag) 4691 { 4692 struct bfi_diag_ts_req_s *msg; 4693 4694 msg = (struct bfi_diag_ts_req_s *)diag->tsensor.mbcmd.msg; 4695 bfa_trc(diag, msg->temp); 4696 /* build host command */ 4697 bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_TEMPSENSOR, 4698 bfa_ioc_portid(diag->ioc)); 4699 /* send mbox cmd */ 4700 bfa_ioc_mbox_queue(diag->ioc, &diag->tsensor.mbcmd); 4701 } 4702 4703 static void 4704 diag_tempsensor_comp(struct bfa_diag_s *diag, bfi_diag_ts_rsp_t *rsp) 4705 { 4706 if (!diag->tsensor.lock) { 4707 /* receiving response after ioc failure */ 4708 bfa_trc(diag, diag->tsensor.lock); 4709 return; 4710 } 4711 4712 /* 4713 * ASIC junction tempsensor is a reg read operation 4714 * it will always return OK 4715 */ 4716 diag->tsensor.temp->temp = be16_to_cpu(rsp->temp); 4717 diag->tsensor.temp->ts_junc = rsp->ts_junc; 4718 diag->tsensor.temp->ts_brd = rsp->ts_brd; 4719 diag->tsensor.temp->status = BFA_STATUS_OK; 4720 4721 if (rsp->ts_brd) { 4722 if (rsp->status == BFA_STATUS_OK) { 4723 diag->tsensor.temp->brd_temp = 4724 be16_to_cpu(rsp->brd_temp); 4725 } else { 4726 bfa_trc(diag, rsp->status); 4727 diag->tsensor.temp->brd_temp = 0; 4728 diag->tsensor.temp->status = BFA_STATUS_DEVBUSY; 4729 } 4730 } 4731 bfa_trc(diag, rsp->ts_junc); 4732 bfa_trc(diag, rsp->temp); 4733 bfa_trc(diag, rsp->ts_brd); 4734 bfa_trc(diag, rsp->brd_temp); 4735 diag->tsensor.cbfn(diag->tsensor.cbarg, diag->tsensor.status); 4736 diag->tsensor.lock = 0; 4737 } 4738 4739 /* 4740 * LED Test command 4741 */ 4742 static void 4743 diag_ledtest_send(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest) 4744 { 4745 struct bfi_diag_ledtest_req_s *msg; 4746 4747 msg = (struct bfi_diag_ledtest_req_s *)diag->ledtest.mbcmd.msg; 4748 /* build host command */ 4749 bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_LEDTEST, 4750 bfa_ioc_portid(diag->ioc)); 4751 4752 /* 4753 * convert the freq from N blinks per 10 sec to 4754 * crossbow ontime value. We do it here because division is need 4755 */ 4756 if (ledtest->freq) 4757 ledtest->freq = 500 / ledtest->freq; 4758 4759 if (ledtest->freq == 0) 4760 ledtest->freq = 1; 4761 4762 bfa_trc(diag, ledtest->freq); 4763 /* mcpy(&ledtest_req->req, ledtest, sizeof(bfa_diag_ledtest_t)); */ 4764 msg->cmd = (u8) ledtest->cmd; 4765 msg->color = (u8) ledtest->color; 4766 msg->portid = bfa_ioc_portid(diag->ioc); 4767 msg->led = ledtest->led; 4768 msg->freq = cpu_to_be16(ledtest->freq); 4769 4770 /* send mbox cmd */ 4771 bfa_ioc_mbox_queue(diag->ioc, &diag->ledtest.mbcmd); 4772 } 4773 4774 static void 4775 diag_ledtest_comp(struct bfa_diag_s *diag, struct bfi_diag_ledtest_rsp_s * msg) 4776 { 4777 bfa_trc(diag, diag->ledtest.lock); 4778 diag->ledtest.lock = BFA_FALSE; 4779 /* no bfa_cb_queue is needed because driver is not waiting */ 4780 } 4781 4782 /* 4783 * Port beaconing 4784 */ 4785 static void 4786 diag_portbeacon_send(struct bfa_diag_s *diag, bfa_boolean_t beacon, u32 sec) 4787 { 4788 struct bfi_diag_portbeacon_req_s *msg; 4789 4790 msg = (struct bfi_diag_portbeacon_req_s *)diag->beacon.mbcmd.msg; 4791 /* build host command */ 4792 bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_PORTBEACON, 4793 bfa_ioc_portid(diag->ioc)); 4794 msg->beacon = beacon; 4795 msg->period = cpu_to_be32(sec); 4796 /* send mbox cmd */ 4797 bfa_ioc_mbox_queue(diag->ioc, &diag->beacon.mbcmd); 4798 } 4799 4800 static void 4801 diag_portbeacon_comp(struct bfa_diag_s *diag) 4802 { 4803 bfa_trc(diag, diag->beacon.state); 4804 diag->beacon.state = BFA_FALSE; 4805 if (diag->cbfn_beacon) 4806 diag->cbfn_beacon(diag->dev, BFA_FALSE, diag->beacon.link_e2e); 4807 } 4808 4809 /* 4810 * Diag hmbox handler 4811 */ 4812 void 4813 bfa_diag_intr(void *diagarg, struct bfi_mbmsg_s *msg) 4814 { 4815 struct bfa_diag_s *diag = diagarg; 4816 4817 switch (msg->mh.msg_id) { 4818 case BFI_DIAG_I2H_PORTBEACON: 4819 diag_portbeacon_comp(diag); 4820 break; 4821 case BFI_DIAG_I2H_FWPING: 4822 diag_fwping_comp(diag, (struct bfi_diag_fwping_rsp_s *) msg); 4823 break; 4824 case BFI_DIAG_I2H_TEMPSENSOR: 4825 diag_tempsensor_comp(diag, (bfi_diag_ts_rsp_t *) msg); 4826 break; 4827 case BFI_DIAG_I2H_LEDTEST: 4828 diag_ledtest_comp(diag, (struct bfi_diag_ledtest_rsp_s *) msg); 4829 break; 4830 default: 4831 bfa_trc(diag, msg->mh.msg_id); 4832 WARN_ON(1); 4833 } 4834 } 4835 4836 /* 4837 * Gen RAM Test 4838 * 4839 * @param[in] *diag - diag data struct 4840 * @param[in] *memtest - mem test params input from upper layer, 4841 * @param[in] pattern - mem test pattern 4842 * @param[in] *result - mem test result 4843 * @param[in] cbfn - mem test callback functioin 4844 * @param[in] cbarg - callback functioin arg 4845 * 4846 * @param[out] 4847 */ 4848 bfa_status_t 4849 bfa_diag_memtest(struct bfa_diag_s *diag, struct bfa_diag_memtest_s *memtest, 4850 u32 pattern, struct bfa_diag_memtest_result *result, 4851 bfa_cb_diag_t cbfn, void *cbarg) 4852 { 4853 bfa_trc(diag, pattern); 4854 4855 if (!bfa_ioc_adapter_is_disabled(diag->ioc)) 4856 return BFA_STATUS_ADAPTER_ENABLED; 4857 4858 /* check to see if there is another destructive diag cmd running */ 4859 if (diag->block) { 4860 bfa_trc(diag, diag->block); 4861 return BFA_STATUS_DEVBUSY; 4862 } else 4863 diag->block = 1; 4864 4865 diag->result = result; 4866 diag->cbfn = cbfn; 4867 diag->cbarg = cbarg; 4868 4869 /* download memtest code and take LPU0 out of reset */ 4870 bfa_ioc_boot(diag->ioc, BFI_FWBOOT_TYPE_MEMTEST, BFI_FWBOOT_ENV_OS); 4871 4872 bfa_timer_begin(diag->ioc->timer_mod, &diag->timer, 4873 bfa_diag_memtest_done, diag, BFA_DIAG_MEMTEST_TOV); 4874 diag->timer_active = 1; 4875 return BFA_STATUS_OK; 4876 } 4877 4878 /* 4879 * DIAG firmware ping command 4880 * 4881 * @param[in] *diag - diag data struct 4882 * @param[in] cnt - dma loop count for testing PCIE 4883 * @param[in] data - data pattern to pass in fw 4884 * @param[in] *result - pt to bfa_diag_fwping_result_t data struct 4885 * @param[in] cbfn - callback function 4886 * @param[in] *cbarg - callback functioin arg 4887 * 4888 * @param[out] 4889 */ 4890 bfa_status_t 4891 bfa_diag_fwping(struct bfa_diag_s *diag, u32 cnt, u32 data, 4892 struct bfa_diag_results_fwping *result, bfa_cb_diag_t cbfn, 4893 void *cbarg) 4894 { 4895 bfa_trc(diag, cnt); 4896 bfa_trc(diag, data); 4897 4898 if (!bfa_ioc_is_operational(diag->ioc)) 4899 return BFA_STATUS_IOC_NON_OP; 4900 4901 if (bfa_asic_id_ct2(bfa_ioc_devid((diag->ioc))) && 4902 ((diag->ioc)->clscode == BFI_PCIFN_CLASS_ETH)) 4903 return BFA_STATUS_CMD_NOTSUPP; 4904 4905 /* check to see if there is another destructive diag cmd running */ 4906 if (diag->block || diag->fwping.lock) { 4907 bfa_trc(diag, diag->block); 4908 bfa_trc(diag, diag->fwping.lock); 4909 return BFA_STATUS_DEVBUSY; 4910 } 4911 4912 /* Initialization */ 4913 diag->fwping.lock = 1; 4914 diag->fwping.cbfn = cbfn; 4915 diag->fwping.cbarg = cbarg; 4916 diag->fwping.result = result; 4917 diag->fwping.data = data; 4918 diag->fwping.count = cnt; 4919 4920 /* Init test results */ 4921 diag->fwping.result->data = 0; 4922 diag->fwping.result->status = BFA_STATUS_OK; 4923 4924 /* kick off the first ping */ 4925 diag_fwping_send(diag); 4926 return BFA_STATUS_OK; 4927 } 4928 4929 /* 4930 * Read Temperature Sensor 4931 * 4932 * @param[in] *diag - diag data struct 4933 * @param[in] *result - pt to bfa_diag_temp_t data struct 4934 * @param[in] cbfn - callback function 4935 * @param[in] *cbarg - callback functioin arg 4936 * 4937 * @param[out] 4938 */ 4939 bfa_status_t 4940 bfa_diag_tsensor_query(struct bfa_diag_s *diag, 4941 struct bfa_diag_results_tempsensor_s *result, 4942 bfa_cb_diag_t cbfn, void *cbarg) 4943 { 4944 /* check to see if there is a destructive diag cmd running */ 4945 if (diag->block || diag->tsensor.lock) { 4946 bfa_trc(diag, diag->block); 4947 bfa_trc(diag, diag->tsensor.lock); 4948 return BFA_STATUS_DEVBUSY; 4949 } 4950 4951 if (!bfa_ioc_is_operational(diag->ioc)) 4952 return BFA_STATUS_IOC_NON_OP; 4953 4954 /* Init diag mod params */ 4955 diag->tsensor.lock = 1; 4956 diag->tsensor.temp = result; 4957 diag->tsensor.cbfn = cbfn; 4958 diag->tsensor.cbarg = cbarg; 4959 4960 /* Send msg to fw */ 4961 diag_tempsensor_send(diag); 4962 4963 return BFA_STATUS_OK; 4964 } 4965 4966 /* 4967 * LED Test command 4968 * 4969 * @param[in] *diag - diag data struct 4970 * @param[in] *ledtest - pt to ledtest data structure 4971 * 4972 * @param[out] 4973 */ 4974 bfa_status_t 4975 bfa_diag_ledtest(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest) 4976 { 4977 bfa_trc(diag, ledtest->cmd); 4978 4979 if (!bfa_ioc_is_operational(diag->ioc)) 4980 return BFA_STATUS_IOC_NON_OP; 4981 4982 if (diag->beacon.state) 4983 return BFA_STATUS_BEACON_ON; 4984 4985 if (diag->ledtest.lock) 4986 return BFA_STATUS_LEDTEST_OP; 4987 4988 /* Send msg to fw */ 4989 diag->ledtest.lock = BFA_TRUE; 4990 diag_ledtest_send(diag, ledtest); 4991 4992 return BFA_STATUS_OK; 4993 } 4994 4995 /* 4996 * Port beaconing command 4997 * 4998 * @param[in] *diag - diag data struct 4999 * @param[in] beacon - port beaconing 1:ON 0:OFF 5000 * @param[in] link_e2e_beacon - link beaconing 1:ON 0:OFF 5001 * @param[in] sec - beaconing duration in seconds 5002 * 5003 * @param[out] 5004 */ 5005 bfa_status_t 5006 bfa_diag_beacon_port(struct bfa_diag_s *diag, bfa_boolean_t beacon, 5007 bfa_boolean_t link_e2e_beacon, uint32_t sec) 5008 { 5009 bfa_trc(diag, beacon); 5010 bfa_trc(diag, link_e2e_beacon); 5011 bfa_trc(diag, sec); 5012 5013 if (!bfa_ioc_is_operational(diag->ioc)) 5014 return BFA_STATUS_IOC_NON_OP; 5015 5016 if (diag->ledtest.lock) 5017 return BFA_STATUS_LEDTEST_OP; 5018 5019 if (diag->beacon.state && beacon) /* beacon alread on */ 5020 return BFA_STATUS_BEACON_ON; 5021 5022 diag->beacon.state = beacon; 5023 diag->beacon.link_e2e = link_e2e_beacon; 5024 if (diag->cbfn_beacon) 5025 diag->cbfn_beacon(diag->dev, beacon, link_e2e_beacon); 5026 5027 /* Send msg to fw */ 5028 diag_portbeacon_send(diag, beacon, sec); 5029 5030 return BFA_STATUS_OK; 5031 } 5032 5033 /* 5034 * Return DMA memory needed by diag module. 5035 */ 5036 u32 5037 bfa_diag_meminfo(void) 5038 { 5039 return BFA_ROUNDUP(BFI_DIAG_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 5040 } 5041 5042 /* 5043 * Attach virtual and physical memory for Diag. 5044 */ 5045 void 5046 bfa_diag_attach(struct bfa_diag_s *diag, struct bfa_ioc_s *ioc, void *dev, 5047 bfa_cb_diag_beacon_t cbfn_beacon, struct bfa_trc_mod_s *trcmod) 5048 { 5049 diag->dev = dev; 5050 diag->ioc = ioc; 5051 diag->trcmod = trcmod; 5052 5053 diag->block = 0; 5054 diag->cbfn = NULL; 5055 diag->cbarg = NULL; 5056 diag->result = NULL; 5057 diag->cbfn_beacon = cbfn_beacon; 5058 5059 bfa_ioc_mbox_regisr(diag->ioc, BFI_MC_DIAG, bfa_diag_intr, diag); 5060 bfa_q_qe_init(&diag->ioc_notify); 5061 bfa_ioc_notify_init(&diag->ioc_notify, bfa_diag_notify, diag); 5062 list_add_tail(&diag->ioc_notify.qe, &diag->ioc->notify_q); 5063 } 5064 5065 void 5066 bfa_diag_memclaim(struct bfa_diag_s *diag, u8 *dm_kva, u64 dm_pa) 5067 { 5068 diag->fwping.dbuf_kva = dm_kva; 5069 diag->fwping.dbuf_pa = dm_pa; 5070 memset(diag->fwping.dbuf_kva, 0, BFI_DIAG_DMA_BUF_SZ); 5071 } 5072 5073 /* 5074 * PHY module specific 5075 */ 5076 #define BFA_PHY_DMA_BUF_SZ 0x02000 /* 8k dma buffer */ 5077 #define BFA_PHY_LOCK_STATUS 0x018878 /* phy semaphore status reg */ 5078 5079 static void 5080 bfa_phy_ntoh32(u32 *obuf, u32 *ibuf, int sz) 5081 { 5082 int i, m = sz >> 2; 5083 5084 for (i = 0; i < m; i++) 5085 obuf[i] = be32_to_cpu(ibuf[i]); 5086 } 5087 5088 static bfa_boolean_t 5089 bfa_phy_present(struct bfa_phy_s *phy) 5090 { 5091 return (phy->ioc->attr->card_type == BFA_MFG_TYPE_LIGHTNING); 5092 } 5093 5094 static void 5095 bfa_phy_notify(void *cbarg, enum bfa_ioc_event_e event) 5096 { 5097 struct bfa_phy_s *phy = cbarg; 5098 5099 bfa_trc(phy, event); 5100 5101 switch (event) { 5102 case BFA_IOC_E_DISABLED: 5103 case BFA_IOC_E_FAILED: 5104 if (phy->op_busy) { 5105 phy->status = BFA_STATUS_IOC_FAILURE; 5106 phy->cbfn(phy->cbarg, phy->status); 5107 phy->op_busy = 0; 5108 } 5109 break; 5110 5111 default: 5112 break; 5113 } 5114 } 5115 5116 /* 5117 * Send phy attribute query request. 5118 * 5119 * @param[in] cbarg - callback argument 5120 */ 5121 static void 5122 bfa_phy_query_send(void *cbarg) 5123 { 5124 struct bfa_phy_s *phy = cbarg; 5125 struct bfi_phy_query_req_s *msg = 5126 (struct bfi_phy_query_req_s *) phy->mb.msg; 5127 5128 msg->instance = phy->instance; 5129 bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_QUERY_REQ, 5130 bfa_ioc_portid(phy->ioc)); 5131 bfa_alen_set(&msg->alen, sizeof(struct bfa_phy_attr_s), phy->dbuf_pa); 5132 bfa_ioc_mbox_queue(phy->ioc, &phy->mb); 5133 } 5134 5135 /* 5136 * Send phy write request. 5137 * 5138 * @param[in] cbarg - callback argument 5139 */ 5140 static void 5141 bfa_phy_write_send(void *cbarg) 5142 { 5143 struct bfa_phy_s *phy = cbarg; 5144 struct bfi_phy_write_req_s *msg = 5145 (struct bfi_phy_write_req_s *) phy->mb.msg; 5146 u32 len; 5147 u16 *buf, *dbuf; 5148 int i, sz; 5149 5150 msg->instance = phy->instance; 5151 msg->offset = cpu_to_be32(phy->addr_off + phy->offset); 5152 len = (phy->residue < BFA_PHY_DMA_BUF_SZ) ? 5153 phy->residue : BFA_PHY_DMA_BUF_SZ; 5154 msg->length = cpu_to_be32(len); 5155 5156 /* indicate if it's the last msg of the whole write operation */ 5157 msg->last = (len == phy->residue) ? 1 : 0; 5158 5159 bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_WRITE_REQ, 5160 bfa_ioc_portid(phy->ioc)); 5161 bfa_alen_set(&msg->alen, len, phy->dbuf_pa); 5162 5163 buf = (u16 *) (phy->ubuf + phy->offset); 5164 dbuf = (u16 *)phy->dbuf_kva; 5165 sz = len >> 1; 5166 for (i = 0; i < sz; i++) 5167 buf[i] = cpu_to_be16(dbuf[i]); 5168 5169 bfa_ioc_mbox_queue(phy->ioc, &phy->mb); 5170 5171 phy->residue -= len; 5172 phy->offset += len; 5173 } 5174 5175 /* 5176 * Send phy read request. 5177 * 5178 * @param[in] cbarg - callback argument 5179 */ 5180 static void 5181 bfa_phy_read_send(void *cbarg) 5182 { 5183 struct bfa_phy_s *phy = cbarg; 5184 struct bfi_phy_read_req_s *msg = 5185 (struct bfi_phy_read_req_s *) phy->mb.msg; 5186 u32 len; 5187 5188 msg->instance = phy->instance; 5189 msg->offset = cpu_to_be32(phy->addr_off + phy->offset); 5190 len = (phy->residue < BFA_PHY_DMA_BUF_SZ) ? 5191 phy->residue : BFA_PHY_DMA_BUF_SZ; 5192 msg->length = cpu_to_be32(len); 5193 bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_READ_REQ, 5194 bfa_ioc_portid(phy->ioc)); 5195 bfa_alen_set(&msg->alen, len, phy->dbuf_pa); 5196 bfa_ioc_mbox_queue(phy->ioc, &phy->mb); 5197 } 5198 5199 /* 5200 * Send phy stats request. 5201 * 5202 * @param[in] cbarg - callback argument 5203 */ 5204 static void 5205 bfa_phy_stats_send(void *cbarg) 5206 { 5207 struct bfa_phy_s *phy = cbarg; 5208 struct bfi_phy_stats_req_s *msg = 5209 (struct bfi_phy_stats_req_s *) phy->mb.msg; 5210 5211 msg->instance = phy->instance; 5212 bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_STATS_REQ, 5213 bfa_ioc_portid(phy->ioc)); 5214 bfa_alen_set(&msg->alen, sizeof(struct bfa_phy_stats_s), phy->dbuf_pa); 5215 bfa_ioc_mbox_queue(phy->ioc, &phy->mb); 5216 } 5217 5218 /* 5219 * Flash memory info API. 5220 * 5221 * @param[in] mincfg - minimal cfg variable 5222 */ 5223 u32 5224 bfa_phy_meminfo(bfa_boolean_t mincfg) 5225 { 5226 /* min driver doesn't need phy */ 5227 if (mincfg) 5228 return 0; 5229 5230 return BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 5231 } 5232 5233 /* 5234 * Flash attach API. 5235 * 5236 * @param[in] phy - phy structure 5237 * @param[in] ioc - ioc structure 5238 * @param[in] dev - device structure 5239 * @param[in] trcmod - trace module 5240 * @param[in] logmod - log module 5241 */ 5242 void 5243 bfa_phy_attach(struct bfa_phy_s *phy, struct bfa_ioc_s *ioc, void *dev, 5244 struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg) 5245 { 5246 phy->ioc = ioc; 5247 phy->trcmod = trcmod; 5248 phy->cbfn = NULL; 5249 phy->cbarg = NULL; 5250 phy->op_busy = 0; 5251 5252 bfa_ioc_mbox_regisr(phy->ioc, BFI_MC_PHY, bfa_phy_intr, phy); 5253 bfa_q_qe_init(&phy->ioc_notify); 5254 bfa_ioc_notify_init(&phy->ioc_notify, bfa_phy_notify, phy); 5255 list_add_tail(&phy->ioc_notify.qe, &phy->ioc->notify_q); 5256 5257 /* min driver doesn't need phy */ 5258 if (mincfg) { 5259 phy->dbuf_kva = NULL; 5260 phy->dbuf_pa = 0; 5261 } 5262 } 5263 5264 /* 5265 * Claim memory for phy 5266 * 5267 * @param[in] phy - phy structure 5268 * @param[in] dm_kva - pointer to virtual memory address 5269 * @param[in] dm_pa - physical memory address 5270 * @param[in] mincfg - minimal cfg variable 5271 */ 5272 void 5273 bfa_phy_memclaim(struct bfa_phy_s *phy, u8 *dm_kva, u64 dm_pa, 5274 bfa_boolean_t mincfg) 5275 { 5276 if (mincfg) 5277 return; 5278 5279 phy->dbuf_kva = dm_kva; 5280 phy->dbuf_pa = dm_pa; 5281 memset(phy->dbuf_kva, 0, BFA_PHY_DMA_BUF_SZ); 5282 dm_kva += BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 5283 dm_pa += BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 5284 } 5285 5286 bfa_boolean_t 5287 bfa_phy_busy(struct bfa_ioc_s *ioc) 5288 { 5289 void __iomem *rb; 5290 5291 rb = bfa_ioc_bar0(ioc); 5292 return readl(rb + BFA_PHY_LOCK_STATUS); 5293 } 5294 5295 /* 5296 * Get phy attribute. 5297 * 5298 * @param[in] phy - phy structure 5299 * @param[in] attr - phy attribute structure 5300 * @param[in] cbfn - callback function 5301 * @param[in] cbarg - callback argument 5302 * 5303 * Return status. 5304 */ 5305 bfa_status_t 5306 bfa_phy_get_attr(struct bfa_phy_s *phy, u8 instance, 5307 struct bfa_phy_attr_s *attr, bfa_cb_phy_t cbfn, void *cbarg) 5308 { 5309 bfa_trc(phy, BFI_PHY_H2I_QUERY_REQ); 5310 bfa_trc(phy, instance); 5311 5312 if (!bfa_phy_present(phy)) 5313 return BFA_STATUS_PHY_NOT_PRESENT; 5314 5315 if (!bfa_ioc_is_operational(phy->ioc)) 5316 return BFA_STATUS_IOC_NON_OP; 5317 5318 if (phy->op_busy || bfa_phy_busy(phy->ioc)) { 5319 bfa_trc(phy, phy->op_busy); 5320 return BFA_STATUS_DEVBUSY; 5321 } 5322 5323 phy->op_busy = 1; 5324 phy->cbfn = cbfn; 5325 phy->cbarg = cbarg; 5326 phy->instance = instance; 5327 phy->ubuf = (uint8_t *) attr; 5328 bfa_phy_query_send(phy); 5329 5330 return BFA_STATUS_OK; 5331 } 5332 5333 /* 5334 * Get phy stats. 5335 * 5336 * @param[in] phy - phy structure 5337 * @param[in] instance - phy image instance 5338 * @param[in] stats - pointer to phy stats 5339 * @param[in] cbfn - callback function 5340 * @param[in] cbarg - callback argument 5341 * 5342 * Return status. 5343 */ 5344 bfa_status_t 5345 bfa_phy_get_stats(struct bfa_phy_s *phy, u8 instance, 5346 struct bfa_phy_stats_s *stats, 5347 bfa_cb_phy_t cbfn, void *cbarg) 5348 { 5349 bfa_trc(phy, BFI_PHY_H2I_STATS_REQ); 5350 bfa_trc(phy, instance); 5351 5352 if (!bfa_phy_present(phy)) 5353 return BFA_STATUS_PHY_NOT_PRESENT; 5354 5355 if (!bfa_ioc_is_operational(phy->ioc)) 5356 return BFA_STATUS_IOC_NON_OP; 5357 5358 if (phy->op_busy || bfa_phy_busy(phy->ioc)) { 5359 bfa_trc(phy, phy->op_busy); 5360 return BFA_STATUS_DEVBUSY; 5361 } 5362 5363 phy->op_busy = 1; 5364 phy->cbfn = cbfn; 5365 phy->cbarg = cbarg; 5366 phy->instance = instance; 5367 phy->ubuf = (u8 *) stats; 5368 bfa_phy_stats_send(phy); 5369 5370 return BFA_STATUS_OK; 5371 } 5372 5373 /* 5374 * Update phy image. 5375 * 5376 * @param[in] phy - phy structure 5377 * @param[in] instance - phy image instance 5378 * @param[in] buf - update data buffer 5379 * @param[in] len - data buffer length 5380 * @param[in] offset - offset relative to starting address 5381 * @param[in] cbfn - callback function 5382 * @param[in] cbarg - callback argument 5383 * 5384 * Return status. 5385 */ 5386 bfa_status_t 5387 bfa_phy_update(struct bfa_phy_s *phy, u8 instance, 5388 void *buf, u32 len, u32 offset, 5389 bfa_cb_phy_t cbfn, void *cbarg) 5390 { 5391 bfa_trc(phy, BFI_PHY_H2I_WRITE_REQ); 5392 bfa_trc(phy, instance); 5393 bfa_trc(phy, len); 5394 bfa_trc(phy, offset); 5395 5396 if (!bfa_phy_present(phy)) 5397 return BFA_STATUS_PHY_NOT_PRESENT; 5398 5399 if (!bfa_ioc_is_operational(phy->ioc)) 5400 return BFA_STATUS_IOC_NON_OP; 5401 5402 /* 'len' must be in word (4-byte) boundary */ 5403 if (!len || (len & 0x03)) 5404 return BFA_STATUS_FAILED; 5405 5406 if (phy->op_busy || bfa_phy_busy(phy->ioc)) { 5407 bfa_trc(phy, phy->op_busy); 5408 return BFA_STATUS_DEVBUSY; 5409 } 5410 5411 phy->op_busy = 1; 5412 phy->cbfn = cbfn; 5413 phy->cbarg = cbarg; 5414 phy->instance = instance; 5415 phy->residue = len; 5416 phy->offset = 0; 5417 phy->addr_off = offset; 5418 phy->ubuf = buf; 5419 5420 bfa_phy_write_send(phy); 5421 return BFA_STATUS_OK; 5422 } 5423 5424 /* 5425 * Read phy image. 5426 * 5427 * @param[in] phy - phy structure 5428 * @param[in] instance - phy image instance 5429 * @param[in] buf - read data buffer 5430 * @param[in] len - data buffer length 5431 * @param[in] offset - offset relative to starting address 5432 * @param[in] cbfn - callback function 5433 * @param[in] cbarg - callback argument 5434 * 5435 * Return status. 5436 */ 5437 bfa_status_t 5438 bfa_phy_read(struct bfa_phy_s *phy, u8 instance, 5439 void *buf, u32 len, u32 offset, 5440 bfa_cb_phy_t cbfn, void *cbarg) 5441 { 5442 bfa_trc(phy, BFI_PHY_H2I_READ_REQ); 5443 bfa_trc(phy, instance); 5444 bfa_trc(phy, len); 5445 bfa_trc(phy, offset); 5446 5447 if (!bfa_phy_present(phy)) 5448 return BFA_STATUS_PHY_NOT_PRESENT; 5449 5450 if (!bfa_ioc_is_operational(phy->ioc)) 5451 return BFA_STATUS_IOC_NON_OP; 5452 5453 /* 'len' must be in word (4-byte) boundary */ 5454 if (!len || (len & 0x03)) 5455 return BFA_STATUS_FAILED; 5456 5457 if (phy->op_busy || bfa_phy_busy(phy->ioc)) { 5458 bfa_trc(phy, phy->op_busy); 5459 return BFA_STATUS_DEVBUSY; 5460 } 5461 5462 phy->op_busy = 1; 5463 phy->cbfn = cbfn; 5464 phy->cbarg = cbarg; 5465 phy->instance = instance; 5466 phy->residue = len; 5467 phy->offset = 0; 5468 phy->addr_off = offset; 5469 phy->ubuf = buf; 5470 bfa_phy_read_send(phy); 5471 5472 return BFA_STATUS_OK; 5473 } 5474 5475 /* 5476 * Process phy response messages upon receiving interrupts. 5477 * 5478 * @param[in] phyarg - phy structure 5479 * @param[in] msg - message structure 5480 */ 5481 void 5482 bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg) 5483 { 5484 struct bfa_phy_s *phy = phyarg; 5485 u32 status; 5486 5487 union { 5488 struct bfi_phy_query_rsp_s *query; 5489 struct bfi_phy_stats_rsp_s *stats; 5490 struct bfi_phy_write_rsp_s *write; 5491 struct bfi_phy_read_rsp_s *read; 5492 struct bfi_mbmsg_s *msg; 5493 } m; 5494 5495 m.msg = msg; 5496 bfa_trc(phy, msg->mh.msg_id); 5497 5498 if (!phy->op_busy) { 5499 /* receiving response after ioc failure */ 5500 bfa_trc(phy, 0x9999); 5501 return; 5502 } 5503 5504 switch (msg->mh.msg_id) { 5505 case BFI_PHY_I2H_QUERY_RSP: 5506 status = be32_to_cpu(m.query->status); 5507 bfa_trc(phy, status); 5508 5509 if (status == BFA_STATUS_OK) { 5510 struct bfa_phy_attr_s *attr = 5511 (struct bfa_phy_attr_s *) phy->ubuf; 5512 bfa_phy_ntoh32((u32 *)attr, (u32 *)phy->dbuf_kva, 5513 sizeof(struct bfa_phy_attr_s)); 5514 bfa_trc(phy, attr->status); 5515 bfa_trc(phy, attr->length); 5516 } 5517 5518 phy->status = status; 5519 phy->op_busy = 0; 5520 if (phy->cbfn) 5521 phy->cbfn(phy->cbarg, phy->status); 5522 break; 5523 case BFI_PHY_I2H_STATS_RSP: 5524 status = be32_to_cpu(m.stats->status); 5525 bfa_trc(phy, status); 5526 5527 if (status == BFA_STATUS_OK) { 5528 struct bfa_phy_stats_s *stats = 5529 (struct bfa_phy_stats_s *) phy->ubuf; 5530 bfa_phy_ntoh32((u32 *)stats, (u32 *)phy->dbuf_kva, 5531 sizeof(struct bfa_phy_stats_s)); 5532 bfa_trc(phy, stats->status); 5533 } 5534 5535 phy->status = status; 5536 phy->op_busy = 0; 5537 if (phy->cbfn) 5538 phy->cbfn(phy->cbarg, phy->status); 5539 break; 5540 case BFI_PHY_I2H_WRITE_RSP: 5541 status = be32_to_cpu(m.write->status); 5542 bfa_trc(phy, status); 5543 5544 if (status != BFA_STATUS_OK || phy->residue == 0) { 5545 phy->status = status; 5546 phy->op_busy = 0; 5547 if (phy->cbfn) 5548 phy->cbfn(phy->cbarg, phy->status); 5549 } else { 5550 bfa_trc(phy, phy->offset); 5551 bfa_phy_write_send(phy); 5552 } 5553 break; 5554 case BFI_PHY_I2H_READ_RSP: 5555 status = be32_to_cpu(m.read->status); 5556 bfa_trc(phy, status); 5557 5558 if (status != BFA_STATUS_OK) { 5559 phy->status = status; 5560 phy->op_busy = 0; 5561 if (phy->cbfn) 5562 phy->cbfn(phy->cbarg, phy->status); 5563 } else { 5564 u32 len = be32_to_cpu(m.read->length); 5565 u16 *buf = (u16 *)(phy->ubuf + phy->offset); 5566 u16 *dbuf = (u16 *)phy->dbuf_kva; 5567 int i, sz = len >> 1; 5568 5569 bfa_trc(phy, phy->offset); 5570 bfa_trc(phy, len); 5571 5572 for (i = 0; i < sz; i++) 5573 buf[i] = be16_to_cpu(dbuf[i]); 5574 5575 phy->residue -= len; 5576 phy->offset += len; 5577 5578 if (phy->residue == 0) { 5579 phy->status = status; 5580 phy->op_busy = 0; 5581 if (phy->cbfn) 5582 phy->cbfn(phy->cbarg, phy->status); 5583 } else 5584 bfa_phy_read_send(phy); 5585 } 5586 break; 5587 default: 5588 WARN_ON(1); 5589 } 5590 } 5591 5592 /* 5593 * DCONF module specific 5594 */ 5595 5596 BFA_MODULE(dconf); 5597 5598 /* 5599 * DCONF state machine events 5600 */ 5601 enum bfa_dconf_event { 5602 BFA_DCONF_SM_INIT = 1, /* dconf Init */ 5603 BFA_DCONF_SM_FLASH_COMP = 2, /* read/write to flash */ 5604 BFA_DCONF_SM_WR = 3, /* binding change, map */ 5605 BFA_DCONF_SM_TIMEOUT = 4, /* Start timer */ 5606 BFA_DCONF_SM_EXIT = 5, /* exit dconf module */ 5607 BFA_DCONF_SM_IOCDISABLE = 6, /* IOC disable event */ 5608 }; 5609 5610 /* forward declaration of DCONF state machine */ 5611 static void bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, 5612 enum bfa_dconf_event event); 5613 static void bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf, 5614 enum bfa_dconf_event event); 5615 static void bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf, 5616 enum bfa_dconf_event event); 5617 static void bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf, 5618 enum bfa_dconf_event event); 5619 static void bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf, 5620 enum bfa_dconf_event event); 5621 static void bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf, 5622 enum bfa_dconf_event event); 5623 static void bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf, 5624 enum bfa_dconf_event event); 5625 5626 static void bfa_dconf_cbfn(void *dconf, bfa_status_t status); 5627 static void bfa_dconf_timer(void *cbarg); 5628 static bfa_status_t bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf); 5629 static void bfa_dconf_init_cb(void *arg, bfa_status_t status); 5630 5631 /* 5632 * Begining state of dconf module. Waiting for an event to start. 5633 */ 5634 static void 5635 bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event) 5636 { 5637 bfa_status_t bfa_status; 5638 bfa_trc(dconf->bfa, event); 5639 5640 switch (event) { 5641 case BFA_DCONF_SM_INIT: 5642 if (dconf->min_cfg) { 5643 bfa_trc(dconf->bfa, dconf->min_cfg); 5644 return; 5645 } 5646 bfa_sm_set_state(dconf, bfa_dconf_sm_flash_read); 5647 dconf->flashdone = BFA_FALSE; 5648 bfa_trc(dconf->bfa, dconf->flashdone); 5649 bfa_status = bfa_flash_read_part(BFA_FLASH(dconf->bfa), 5650 BFA_FLASH_PART_DRV, dconf->instance, 5651 dconf->dconf, 5652 sizeof(struct bfa_dconf_s), 0, 5653 bfa_dconf_init_cb, dconf->bfa); 5654 if (bfa_status != BFA_STATUS_OK) { 5655 bfa_dconf_init_cb(dconf->bfa, BFA_STATUS_FAILED); 5656 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); 5657 return; 5658 } 5659 break; 5660 case BFA_DCONF_SM_EXIT: 5661 dconf->flashdone = BFA_TRUE; 5662 case BFA_DCONF_SM_IOCDISABLE: 5663 case BFA_DCONF_SM_WR: 5664 case BFA_DCONF_SM_FLASH_COMP: 5665 break; 5666 default: 5667 bfa_sm_fault(dconf->bfa, event); 5668 } 5669 } 5670 5671 /* 5672 * Read flash for dconf entries and make a call back to the driver once done. 5673 */ 5674 static void 5675 bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf, 5676 enum bfa_dconf_event event) 5677 { 5678 bfa_trc(dconf->bfa, event); 5679 5680 switch (event) { 5681 case BFA_DCONF_SM_FLASH_COMP: 5682 bfa_sm_set_state(dconf, bfa_dconf_sm_ready); 5683 break; 5684 case BFA_DCONF_SM_TIMEOUT: 5685 bfa_sm_set_state(dconf, bfa_dconf_sm_ready); 5686 break; 5687 case BFA_DCONF_SM_EXIT: 5688 dconf->flashdone = BFA_TRUE; 5689 bfa_trc(dconf->bfa, dconf->flashdone); 5690 case BFA_DCONF_SM_IOCDISABLE: 5691 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); 5692 break; 5693 default: 5694 bfa_sm_fault(dconf->bfa, event); 5695 } 5696 } 5697 5698 /* 5699 * DCONF Module is in ready state. Has completed the initialization. 5700 */ 5701 static void 5702 bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event) 5703 { 5704 bfa_trc(dconf->bfa, event); 5705 5706 switch (event) { 5707 case BFA_DCONF_SM_WR: 5708 bfa_timer_start(dconf->bfa, &dconf->timer, 5709 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); 5710 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty); 5711 break; 5712 case BFA_DCONF_SM_EXIT: 5713 dconf->flashdone = BFA_TRUE; 5714 bfa_trc(dconf->bfa, dconf->flashdone); 5715 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); 5716 break; 5717 case BFA_DCONF_SM_INIT: 5718 case BFA_DCONF_SM_IOCDISABLE: 5719 break; 5720 default: 5721 bfa_sm_fault(dconf->bfa, event); 5722 } 5723 } 5724 5725 /* 5726 * entries are dirty, write back to the flash. 5727 */ 5728 5729 static void 5730 bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event) 5731 { 5732 bfa_trc(dconf->bfa, event); 5733 5734 switch (event) { 5735 case BFA_DCONF_SM_TIMEOUT: 5736 bfa_sm_set_state(dconf, bfa_dconf_sm_sync); 5737 bfa_dconf_flash_write(dconf); 5738 break; 5739 case BFA_DCONF_SM_WR: 5740 bfa_timer_stop(&dconf->timer); 5741 bfa_timer_start(dconf->bfa, &dconf->timer, 5742 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); 5743 break; 5744 case BFA_DCONF_SM_EXIT: 5745 bfa_timer_stop(&dconf->timer); 5746 bfa_timer_start(dconf->bfa, &dconf->timer, 5747 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); 5748 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync); 5749 bfa_dconf_flash_write(dconf); 5750 break; 5751 case BFA_DCONF_SM_FLASH_COMP: 5752 break; 5753 case BFA_DCONF_SM_IOCDISABLE: 5754 bfa_timer_stop(&dconf->timer); 5755 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty); 5756 break; 5757 default: 5758 bfa_sm_fault(dconf->bfa, event); 5759 } 5760 } 5761 5762 /* 5763 * Sync the dconf entries to the flash. 5764 */ 5765 static void 5766 bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf, 5767 enum bfa_dconf_event event) 5768 { 5769 bfa_trc(dconf->bfa, event); 5770 5771 switch (event) { 5772 case BFA_DCONF_SM_IOCDISABLE: 5773 case BFA_DCONF_SM_FLASH_COMP: 5774 bfa_timer_stop(&dconf->timer); 5775 case BFA_DCONF_SM_TIMEOUT: 5776 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); 5777 dconf->flashdone = BFA_TRUE; 5778 bfa_trc(dconf->bfa, dconf->flashdone); 5779 bfa_ioc_disable(&dconf->bfa->ioc); 5780 break; 5781 default: 5782 bfa_sm_fault(dconf->bfa, event); 5783 } 5784 } 5785 5786 static void 5787 bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event) 5788 { 5789 bfa_trc(dconf->bfa, event); 5790 5791 switch (event) { 5792 case BFA_DCONF_SM_FLASH_COMP: 5793 bfa_sm_set_state(dconf, bfa_dconf_sm_ready); 5794 break; 5795 case BFA_DCONF_SM_WR: 5796 bfa_timer_start(dconf->bfa, &dconf->timer, 5797 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); 5798 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty); 5799 break; 5800 case BFA_DCONF_SM_EXIT: 5801 bfa_timer_start(dconf->bfa, &dconf->timer, 5802 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); 5803 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync); 5804 break; 5805 case BFA_DCONF_SM_IOCDISABLE: 5806 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty); 5807 break; 5808 default: 5809 bfa_sm_fault(dconf->bfa, event); 5810 } 5811 } 5812 5813 static void 5814 bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf, 5815 enum bfa_dconf_event event) 5816 { 5817 bfa_trc(dconf->bfa, event); 5818 5819 switch (event) { 5820 case BFA_DCONF_SM_INIT: 5821 bfa_timer_start(dconf->bfa, &dconf->timer, 5822 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); 5823 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty); 5824 break; 5825 case BFA_DCONF_SM_EXIT: 5826 dconf->flashdone = BFA_TRUE; 5827 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); 5828 break; 5829 case BFA_DCONF_SM_IOCDISABLE: 5830 break; 5831 default: 5832 bfa_sm_fault(dconf->bfa, event); 5833 } 5834 } 5835 5836 /* 5837 * Compute and return memory needed by DRV_CFG module. 5838 */ 5839 static void 5840 bfa_dconf_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, 5841 struct bfa_s *bfa) 5842 { 5843 struct bfa_mem_kva_s *dconf_kva = BFA_MEM_DCONF_KVA(bfa); 5844 5845 if (cfg->drvcfg.min_cfg) 5846 bfa_mem_kva_setup(meminfo, dconf_kva, 5847 sizeof(struct bfa_dconf_hdr_s)); 5848 else 5849 bfa_mem_kva_setup(meminfo, dconf_kva, 5850 sizeof(struct bfa_dconf_s)); 5851 } 5852 5853 static void 5854 bfa_dconf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 5855 struct bfa_pcidev_s *pcidev) 5856 { 5857 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); 5858 5859 dconf->bfad = bfad; 5860 dconf->bfa = bfa; 5861 dconf->instance = bfa->ioc.port_id; 5862 bfa_trc(bfa, dconf->instance); 5863 5864 dconf->dconf = (struct bfa_dconf_s *) bfa_mem_kva_curp(dconf); 5865 if (cfg->drvcfg.min_cfg) { 5866 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_hdr_s); 5867 dconf->min_cfg = BFA_TRUE; 5868 /* 5869 * Set the flashdone flag to TRUE explicitly as no flash 5870 * write will happen in min_cfg mode. 5871 */ 5872 dconf->flashdone = BFA_TRUE; 5873 } else { 5874 dconf->min_cfg = BFA_FALSE; 5875 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_s); 5876 } 5877 5878 bfa_dconf_read_data_valid(bfa) = BFA_FALSE; 5879 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); 5880 } 5881 5882 static void 5883 bfa_dconf_init_cb(void *arg, bfa_status_t status) 5884 { 5885 struct bfa_s *bfa = arg; 5886 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); 5887 5888 dconf->flashdone = BFA_TRUE; 5889 bfa_trc(bfa, dconf->flashdone); 5890 bfa_iocfc_cb_dconf_modinit(bfa, status); 5891 if (status == BFA_STATUS_OK) { 5892 bfa_dconf_read_data_valid(bfa) = BFA_TRUE; 5893 if (dconf->dconf->hdr.signature != BFI_DCONF_SIGNATURE) 5894 dconf->dconf->hdr.signature = BFI_DCONF_SIGNATURE; 5895 if (dconf->dconf->hdr.version != BFI_DCONF_VERSION) 5896 dconf->dconf->hdr.version = BFI_DCONF_VERSION; 5897 } 5898 bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP); 5899 } 5900 5901 void 5902 bfa_dconf_modinit(struct bfa_s *bfa) 5903 { 5904 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); 5905 bfa_sm_send_event(dconf, BFA_DCONF_SM_INIT); 5906 } 5907 static void 5908 bfa_dconf_start(struct bfa_s *bfa) 5909 { 5910 } 5911 5912 static void 5913 bfa_dconf_stop(struct bfa_s *bfa) 5914 { 5915 } 5916 5917 static void bfa_dconf_timer(void *cbarg) 5918 { 5919 struct bfa_dconf_mod_s *dconf = cbarg; 5920 bfa_sm_send_event(dconf, BFA_DCONF_SM_TIMEOUT); 5921 } 5922 static void 5923 bfa_dconf_iocdisable(struct bfa_s *bfa) 5924 { 5925 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); 5926 bfa_sm_send_event(dconf, BFA_DCONF_SM_IOCDISABLE); 5927 } 5928 5929 static void 5930 bfa_dconf_detach(struct bfa_s *bfa) 5931 { 5932 } 5933 5934 static bfa_status_t 5935 bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf) 5936 { 5937 bfa_status_t bfa_status; 5938 bfa_trc(dconf->bfa, 0); 5939 5940 bfa_status = bfa_flash_update_part(BFA_FLASH(dconf->bfa), 5941 BFA_FLASH_PART_DRV, dconf->instance, 5942 dconf->dconf, sizeof(struct bfa_dconf_s), 0, 5943 bfa_dconf_cbfn, dconf); 5944 if (bfa_status != BFA_STATUS_OK) 5945 WARN_ON(bfa_status); 5946 bfa_trc(dconf->bfa, bfa_status); 5947 5948 return bfa_status; 5949 } 5950 5951 bfa_status_t 5952 bfa_dconf_update(struct bfa_s *bfa) 5953 { 5954 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); 5955 bfa_trc(dconf->bfa, 0); 5956 if (bfa_sm_cmp_state(dconf, bfa_dconf_sm_iocdown_dirty)) 5957 return BFA_STATUS_FAILED; 5958 5959 if (dconf->min_cfg) { 5960 bfa_trc(dconf->bfa, dconf->min_cfg); 5961 return BFA_STATUS_FAILED; 5962 } 5963 5964 bfa_sm_send_event(dconf, BFA_DCONF_SM_WR); 5965 return BFA_STATUS_OK; 5966 } 5967 5968 static void 5969 bfa_dconf_cbfn(void *arg, bfa_status_t status) 5970 { 5971 struct bfa_dconf_mod_s *dconf = arg; 5972 WARN_ON(status); 5973 bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP); 5974 } 5975 5976 void 5977 bfa_dconf_modexit(struct bfa_s *bfa) 5978 { 5979 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); 5980 BFA_DCONF_MOD(bfa)->flashdone = BFA_FALSE; 5981 bfa_trc(bfa, BFA_DCONF_MOD(bfa)->flashdone); 5982 bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT); 5983 } 5984