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