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