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 struct timeval tv; 1813 1814 bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ, 1815 bfa_ioc_portid(ioc)); 1816 enable_req.clscode = cpu_to_be16(ioc->clscode); 1817 do_gettimeofday(&tv); 1818 enable_req.tv_sec = be32_to_cpu(tv.tv_sec); 1819 bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s)); 1820 } 1821 1822 static void 1823 bfa_ioc_send_disable(struct bfa_ioc_s *ioc) 1824 { 1825 struct bfi_ioc_ctrl_req_s disable_req; 1826 1827 bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ, 1828 bfa_ioc_portid(ioc)); 1829 bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req_s)); 1830 } 1831 1832 static void 1833 bfa_ioc_send_getattr(struct bfa_ioc_s *ioc) 1834 { 1835 struct bfi_ioc_getattr_req_s attr_req; 1836 1837 bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ, 1838 bfa_ioc_portid(ioc)); 1839 bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa); 1840 bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req)); 1841 } 1842 1843 static void 1844 bfa_ioc_hb_check(void *cbarg) 1845 { 1846 struct bfa_ioc_s *ioc = cbarg; 1847 u32 hb_count; 1848 1849 hb_count = readl(ioc->ioc_regs.heartbeat); 1850 if (ioc->hb_count == hb_count) { 1851 bfa_ioc_recover(ioc); 1852 return; 1853 } else { 1854 ioc->hb_count = hb_count; 1855 } 1856 1857 bfa_ioc_mbox_poll(ioc); 1858 bfa_hb_timer_start(ioc); 1859 } 1860 1861 static void 1862 bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc) 1863 { 1864 ioc->hb_count = readl(ioc->ioc_regs.heartbeat); 1865 bfa_hb_timer_start(ioc); 1866 } 1867 1868 /* 1869 * Initiate a full firmware download. 1870 */ 1871 static bfa_status_t 1872 bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, 1873 u32 boot_env) 1874 { 1875 u32 *fwimg; 1876 u32 pgnum, pgoff; 1877 u32 loff = 0; 1878 u32 chunkno = 0; 1879 u32 i; 1880 u32 asicmode; 1881 u32 fwimg_size; 1882 u32 fwimg_buf[BFI_FLASH_CHUNK_SZ_WORDS]; 1883 bfa_status_t status; 1884 1885 if (boot_env == BFI_FWBOOT_ENV_OS && 1886 boot_type == BFI_FWBOOT_TYPE_FLASH) { 1887 fwimg_size = BFI_FLASH_IMAGE_SZ/sizeof(u32); 1888 1889 status = bfa_ioc_flash_img_get_chnk(ioc, 1890 BFA_IOC_FLASH_CHUNK_ADDR(chunkno), fwimg_buf); 1891 if (status != BFA_STATUS_OK) 1892 return status; 1893 1894 fwimg = fwimg_buf; 1895 } else { 1896 fwimg_size = bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)); 1897 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 1898 BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); 1899 } 1900 1901 bfa_trc(ioc, fwimg_size); 1902 1903 1904 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff); 1905 pgoff = PSS_SMEM_PGOFF(loff); 1906 1907 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1908 1909 for (i = 0; i < fwimg_size; i++) { 1910 1911 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) { 1912 chunkno = BFA_IOC_FLASH_CHUNK_NO(i); 1913 1914 if (boot_env == BFI_FWBOOT_ENV_OS && 1915 boot_type == BFI_FWBOOT_TYPE_FLASH) { 1916 status = bfa_ioc_flash_img_get_chnk(ioc, 1917 BFA_IOC_FLASH_CHUNK_ADDR(chunkno), 1918 fwimg_buf); 1919 if (status != BFA_STATUS_OK) 1920 return status; 1921 1922 fwimg = fwimg_buf; 1923 } else { 1924 fwimg = bfa_cb_image_get_chunk( 1925 bfa_ioc_asic_gen(ioc), 1926 BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); 1927 } 1928 } 1929 1930 /* 1931 * write smem 1932 */ 1933 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 1934 fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]); 1935 1936 loff += sizeof(u32); 1937 1938 /* 1939 * handle page offset wrap around 1940 */ 1941 loff = PSS_SMEM_PGOFF(loff); 1942 if (loff == 0) { 1943 pgnum++; 1944 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1945 } 1946 } 1947 1948 writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0), 1949 ioc->ioc_regs.host_page_num_fn); 1950 1951 /* 1952 * Set boot type, env and device mode at the end. 1953 */ 1954 if (boot_env == BFI_FWBOOT_ENV_OS && 1955 boot_type == BFI_FWBOOT_TYPE_FLASH) { 1956 boot_type = BFI_FWBOOT_TYPE_NORMAL; 1957 } 1958 asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode, 1959 ioc->port0_mode, ioc->port1_mode); 1960 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_DEVMODE_OFF, 1961 swab32(asicmode)); 1962 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_TYPE_OFF, 1963 swab32(boot_type)); 1964 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_ENV_OFF, 1965 swab32(boot_env)); 1966 return BFA_STATUS_OK; 1967 } 1968 1969 1970 /* 1971 * Update BFA configuration from firmware configuration. 1972 */ 1973 static void 1974 bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc) 1975 { 1976 struct bfi_ioc_attr_s *attr = ioc->attr; 1977 1978 attr->adapter_prop = be32_to_cpu(attr->adapter_prop); 1979 attr->card_type = be32_to_cpu(attr->card_type); 1980 attr->maxfrsize = be16_to_cpu(attr->maxfrsize); 1981 ioc->fcmode = (attr->port_mode == BFI_PORT_MODE_FC); 1982 attr->mfg_year = be16_to_cpu(attr->mfg_year); 1983 1984 bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); 1985 } 1986 1987 /* 1988 * Attach time initialization of mbox logic. 1989 */ 1990 static void 1991 bfa_ioc_mbox_attach(struct bfa_ioc_s *ioc) 1992 { 1993 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 1994 int mc; 1995 1996 INIT_LIST_HEAD(&mod->cmd_q); 1997 for (mc = 0; mc < BFI_MC_MAX; mc++) { 1998 mod->mbhdlr[mc].cbfn = NULL; 1999 mod->mbhdlr[mc].cbarg = ioc->bfa; 2000 } 2001 } 2002 2003 /* 2004 * Mbox poll timer -- restarts any pending mailbox requests. 2005 */ 2006 static void 2007 bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc) 2008 { 2009 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2010 struct bfa_mbox_cmd_s *cmd; 2011 u32 stat; 2012 2013 /* 2014 * If no command pending, do nothing 2015 */ 2016 if (list_empty(&mod->cmd_q)) 2017 return; 2018 2019 /* 2020 * If previous command is not yet fetched by firmware, do nothing 2021 */ 2022 stat = readl(ioc->ioc_regs.hfn_mbox_cmd); 2023 if (stat) 2024 return; 2025 2026 /* 2027 * Enqueue command to firmware. 2028 */ 2029 bfa_q_deq(&mod->cmd_q, &cmd); 2030 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); 2031 } 2032 2033 /* 2034 * Cleanup any pending requests. 2035 */ 2036 static void 2037 bfa_ioc_mbox_flush(struct bfa_ioc_s *ioc) 2038 { 2039 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2040 struct bfa_mbox_cmd_s *cmd; 2041 2042 while (!list_empty(&mod->cmd_q)) 2043 bfa_q_deq(&mod->cmd_q, &cmd); 2044 } 2045 2046 /* 2047 * Read data from SMEM to host through PCI memmap 2048 * 2049 * @param[in] ioc memory for IOC 2050 * @param[in] tbuf app memory to store data from smem 2051 * @param[in] soff smem offset 2052 * @param[in] sz size of smem in bytes 2053 */ 2054 static bfa_status_t 2055 bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz) 2056 { 2057 u32 pgnum, loff; 2058 __be32 r32; 2059 int i, len; 2060 u32 *buf = tbuf; 2061 2062 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff); 2063 loff = PSS_SMEM_PGOFF(soff); 2064 bfa_trc(ioc, pgnum); 2065 bfa_trc(ioc, loff); 2066 bfa_trc(ioc, sz); 2067 2068 /* 2069 * Hold semaphore to serialize pll init and fwtrc. 2070 */ 2071 if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) { 2072 bfa_trc(ioc, 0); 2073 return BFA_STATUS_FAILED; 2074 } 2075 2076 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 2077 2078 len = sz/sizeof(u32); 2079 bfa_trc(ioc, len); 2080 for (i = 0; i < len; i++) { 2081 r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff); 2082 buf[i] = swab32(r32); 2083 loff += sizeof(u32); 2084 2085 /* 2086 * handle page offset wrap around 2087 */ 2088 loff = PSS_SMEM_PGOFF(loff); 2089 if (loff == 0) { 2090 pgnum++; 2091 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 2092 } 2093 } 2094 writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0), 2095 ioc->ioc_regs.host_page_num_fn); 2096 /* 2097 * release semaphore. 2098 */ 2099 readl(ioc->ioc_regs.ioc_init_sem_reg); 2100 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 2101 2102 bfa_trc(ioc, pgnum); 2103 return BFA_STATUS_OK; 2104 } 2105 2106 /* 2107 * Clear SMEM data from host through PCI memmap 2108 * 2109 * @param[in] ioc memory for IOC 2110 * @param[in] soff smem offset 2111 * @param[in] sz size of smem in bytes 2112 */ 2113 static bfa_status_t 2114 bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz) 2115 { 2116 int i, len; 2117 u32 pgnum, loff; 2118 2119 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff); 2120 loff = PSS_SMEM_PGOFF(soff); 2121 bfa_trc(ioc, pgnum); 2122 bfa_trc(ioc, loff); 2123 bfa_trc(ioc, sz); 2124 2125 /* 2126 * Hold semaphore to serialize pll init and fwtrc. 2127 */ 2128 if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) { 2129 bfa_trc(ioc, 0); 2130 return BFA_STATUS_FAILED; 2131 } 2132 2133 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 2134 2135 len = sz/sizeof(u32); /* len in words */ 2136 bfa_trc(ioc, len); 2137 for (i = 0; i < len; i++) { 2138 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 0); 2139 loff += sizeof(u32); 2140 2141 /* 2142 * handle page offset wrap around 2143 */ 2144 loff = PSS_SMEM_PGOFF(loff); 2145 if (loff == 0) { 2146 pgnum++; 2147 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 2148 } 2149 } 2150 writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0), 2151 ioc->ioc_regs.host_page_num_fn); 2152 2153 /* 2154 * release semaphore. 2155 */ 2156 readl(ioc->ioc_regs.ioc_init_sem_reg); 2157 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 2158 bfa_trc(ioc, pgnum); 2159 return BFA_STATUS_OK; 2160 } 2161 2162 static void 2163 bfa_ioc_fail_notify(struct bfa_ioc_s *ioc) 2164 { 2165 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 2166 2167 /* 2168 * Notify driver and common modules registered for notification. 2169 */ 2170 ioc->cbfn->hbfail_cbfn(ioc->bfa); 2171 bfa_ioc_event_notify(ioc, BFA_IOC_E_FAILED); 2172 2173 bfa_ioc_debug_save_ftrc(ioc); 2174 2175 BFA_LOG(KERN_CRIT, bfad, bfa_log_level, 2176 "Heart Beat of IOC has failed\n"); 2177 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_HBFAIL); 2178 2179 } 2180 2181 static void 2182 bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc) 2183 { 2184 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 2185 /* 2186 * Provide enable completion callback. 2187 */ 2188 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 2189 BFA_LOG(KERN_WARNING, bfad, bfa_log_level, 2190 "Running firmware version is incompatible " 2191 "with the driver version\n"); 2192 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_FWMISMATCH); 2193 } 2194 2195 bfa_status_t 2196 bfa_ioc_pll_init(struct bfa_ioc_s *ioc) 2197 { 2198 2199 /* 2200 * Hold semaphore so that nobody can access the chip during init. 2201 */ 2202 bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); 2203 2204 bfa_ioc_pll_init_asic(ioc); 2205 2206 ioc->pllinit = BFA_TRUE; 2207 2208 /* 2209 * Initialize LMEM 2210 */ 2211 bfa_ioc_lmem_init(ioc); 2212 2213 /* 2214 * release semaphore. 2215 */ 2216 readl(ioc->ioc_regs.ioc_init_sem_reg); 2217 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 2218 2219 return BFA_STATUS_OK; 2220 } 2221 2222 /* 2223 * Interface used by diag module to do firmware boot with memory test 2224 * as the entry vector. 2225 */ 2226 bfa_status_t 2227 bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env) 2228 { 2229 struct bfi_ioc_image_hdr_s *drv_fwhdr; 2230 bfa_status_t status; 2231 bfa_ioc_stats(ioc, ioc_boots); 2232 2233 if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK) 2234 return BFA_STATUS_FAILED; 2235 2236 if (boot_env == BFI_FWBOOT_ENV_OS && 2237 boot_type == BFI_FWBOOT_TYPE_NORMAL) { 2238 2239 drv_fwhdr = (struct bfi_ioc_image_hdr_s *) 2240 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0); 2241 2242 /* 2243 * Work with Flash iff flash f/w is better than driver f/w. 2244 * Otherwise push drivers firmware. 2245 */ 2246 if (bfa_ioc_flash_fwver_cmp(ioc, drv_fwhdr) == 2247 BFI_IOC_IMG_VER_BETTER) 2248 boot_type = BFI_FWBOOT_TYPE_FLASH; 2249 } 2250 2251 /* 2252 * Initialize IOC state of all functions on a chip reset. 2253 */ 2254 if (boot_type == BFI_FWBOOT_TYPE_MEMTEST) { 2255 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_MEMTEST); 2256 bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_MEMTEST); 2257 } else { 2258 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_INITING); 2259 bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_INITING); 2260 } 2261 2262 bfa_ioc_msgflush(ioc); 2263 status = bfa_ioc_download_fw(ioc, boot_type, boot_env); 2264 if (status == BFA_STATUS_OK) 2265 bfa_ioc_lpu_start(ioc); 2266 else { 2267 WARN_ON(boot_type == BFI_FWBOOT_TYPE_MEMTEST); 2268 bfa_iocpf_timeout(ioc); 2269 } 2270 return status; 2271 } 2272 2273 /* 2274 * Enable/disable IOC failure auto recovery. 2275 */ 2276 void 2277 bfa_ioc_auto_recover(bfa_boolean_t auto_recover) 2278 { 2279 bfa_auto_recover = auto_recover; 2280 } 2281 2282 2283 2284 bfa_boolean_t 2285 bfa_ioc_is_operational(struct bfa_ioc_s *ioc) 2286 { 2287 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op); 2288 } 2289 2290 bfa_boolean_t 2291 bfa_ioc_is_initialized(struct bfa_ioc_s *ioc) 2292 { 2293 u32 r32 = bfa_ioc_get_cur_ioc_fwstate(ioc); 2294 2295 return ((r32 != BFI_IOC_UNINIT) && 2296 (r32 != BFI_IOC_INITING) && 2297 (r32 != BFI_IOC_MEMTEST)); 2298 } 2299 2300 bfa_boolean_t 2301 bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg) 2302 { 2303 __be32 *msgp = mbmsg; 2304 u32 r32; 2305 int i; 2306 2307 r32 = readl(ioc->ioc_regs.lpu_mbox_cmd); 2308 if ((r32 & 1) == 0) 2309 return BFA_FALSE; 2310 2311 /* 2312 * read the MBOX msg 2313 */ 2314 for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32)); 2315 i++) { 2316 r32 = readl(ioc->ioc_regs.lpu_mbox + 2317 i * sizeof(u32)); 2318 msgp[i] = cpu_to_be32(r32); 2319 } 2320 2321 /* 2322 * turn off mailbox interrupt by clearing mailbox status 2323 */ 2324 writel(1, ioc->ioc_regs.lpu_mbox_cmd); 2325 readl(ioc->ioc_regs.lpu_mbox_cmd); 2326 2327 return BFA_TRUE; 2328 } 2329 2330 void 2331 bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m) 2332 { 2333 union bfi_ioc_i2h_msg_u *msg; 2334 struct bfa_iocpf_s *iocpf = &ioc->iocpf; 2335 2336 msg = (union bfi_ioc_i2h_msg_u *) m; 2337 2338 bfa_ioc_stats(ioc, ioc_isrs); 2339 2340 switch (msg->mh.msg_id) { 2341 case BFI_IOC_I2H_HBEAT: 2342 break; 2343 2344 case BFI_IOC_I2H_ENABLE_REPLY: 2345 ioc->port_mode = ioc->port_mode_cfg = 2346 (enum bfa_mode_s)msg->fw_event.port_mode; 2347 ioc->ad_cap_bm = msg->fw_event.cap_bm; 2348 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE); 2349 break; 2350 2351 case BFI_IOC_I2H_DISABLE_REPLY: 2352 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_DISABLE); 2353 break; 2354 2355 case BFI_IOC_I2H_GETATTR_REPLY: 2356 bfa_ioc_getattr_reply(ioc); 2357 break; 2358 2359 default: 2360 bfa_trc(ioc, msg->mh.msg_id); 2361 WARN_ON(1); 2362 } 2363 } 2364 2365 /* 2366 * IOC attach time initialization and setup. 2367 * 2368 * @param[in] ioc memory for IOC 2369 * @param[in] bfa driver instance structure 2370 */ 2371 void 2372 bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn, 2373 struct bfa_timer_mod_s *timer_mod) 2374 { 2375 ioc->bfa = bfa; 2376 ioc->cbfn = cbfn; 2377 ioc->timer_mod = timer_mod; 2378 ioc->fcmode = BFA_FALSE; 2379 ioc->pllinit = BFA_FALSE; 2380 ioc->dbg_fwsave_once = BFA_TRUE; 2381 ioc->iocpf.ioc = ioc; 2382 2383 bfa_ioc_mbox_attach(ioc); 2384 INIT_LIST_HEAD(&ioc->notify_q); 2385 2386 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 2387 bfa_fsm_send_event(ioc, IOC_E_RESET); 2388 } 2389 2390 /* 2391 * Driver detach time IOC cleanup. 2392 */ 2393 void 2394 bfa_ioc_detach(struct bfa_ioc_s *ioc) 2395 { 2396 bfa_fsm_send_event(ioc, IOC_E_DETACH); 2397 INIT_LIST_HEAD(&ioc->notify_q); 2398 } 2399 2400 /* 2401 * Setup IOC PCI properties. 2402 * 2403 * @param[in] pcidev PCI device information for this IOC 2404 */ 2405 void 2406 bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev, 2407 enum bfi_pcifn_class clscode) 2408 { 2409 ioc->clscode = clscode; 2410 ioc->pcidev = *pcidev; 2411 2412 /* 2413 * Initialize IOC and device personality 2414 */ 2415 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_FC; 2416 ioc->asic_mode = BFI_ASIC_MODE_FC; 2417 2418 switch (pcidev->device_id) { 2419 case BFA_PCI_DEVICE_ID_FC_8G1P: 2420 case BFA_PCI_DEVICE_ID_FC_8G2P: 2421 ioc->asic_gen = BFI_ASIC_GEN_CB; 2422 ioc->fcmode = BFA_TRUE; 2423 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA; 2424 ioc->ad_cap_bm = BFA_CM_HBA; 2425 break; 2426 2427 case BFA_PCI_DEVICE_ID_CT: 2428 ioc->asic_gen = BFI_ASIC_GEN_CT; 2429 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH; 2430 ioc->asic_mode = BFI_ASIC_MODE_ETH; 2431 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_CNA; 2432 ioc->ad_cap_bm = BFA_CM_CNA; 2433 break; 2434 2435 case BFA_PCI_DEVICE_ID_CT_FC: 2436 ioc->asic_gen = BFI_ASIC_GEN_CT; 2437 ioc->fcmode = BFA_TRUE; 2438 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA; 2439 ioc->ad_cap_bm = BFA_CM_HBA; 2440 break; 2441 2442 case BFA_PCI_DEVICE_ID_CT2: 2443 case BFA_PCI_DEVICE_ID_CT2_QUAD: 2444 ioc->asic_gen = BFI_ASIC_GEN_CT2; 2445 if (clscode == BFI_PCIFN_CLASS_FC && 2446 pcidev->ssid == BFA_PCI_CT2_SSID_FC) { 2447 ioc->asic_mode = BFI_ASIC_MODE_FC16; 2448 ioc->fcmode = BFA_TRUE; 2449 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA; 2450 ioc->ad_cap_bm = BFA_CM_HBA; 2451 } else { 2452 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH; 2453 ioc->asic_mode = BFI_ASIC_MODE_ETH; 2454 if (pcidev->ssid == BFA_PCI_CT2_SSID_FCoE) { 2455 ioc->port_mode = 2456 ioc->port_mode_cfg = BFA_MODE_CNA; 2457 ioc->ad_cap_bm = BFA_CM_CNA; 2458 } else { 2459 ioc->port_mode = 2460 ioc->port_mode_cfg = BFA_MODE_NIC; 2461 ioc->ad_cap_bm = BFA_CM_NIC; 2462 } 2463 } 2464 break; 2465 2466 default: 2467 WARN_ON(1); 2468 } 2469 2470 /* 2471 * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c 2472 */ 2473 if (ioc->asic_gen == BFI_ASIC_GEN_CB) 2474 bfa_ioc_set_cb_hwif(ioc); 2475 else if (ioc->asic_gen == BFI_ASIC_GEN_CT) 2476 bfa_ioc_set_ct_hwif(ioc); 2477 else { 2478 WARN_ON(ioc->asic_gen != BFI_ASIC_GEN_CT2); 2479 bfa_ioc_set_ct2_hwif(ioc); 2480 bfa_ioc_ct2_poweron(ioc); 2481 } 2482 2483 bfa_ioc_map_port(ioc); 2484 bfa_ioc_reg_init(ioc); 2485 } 2486 2487 /* 2488 * Initialize IOC dma memory 2489 * 2490 * @param[in] dm_kva kernel virtual address of IOC dma memory 2491 * @param[in] dm_pa physical address of IOC dma memory 2492 */ 2493 void 2494 bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa) 2495 { 2496 /* 2497 * dma memory for firmware attribute 2498 */ 2499 ioc->attr_dma.kva = dm_kva; 2500 ioc->attr_dma.pa = dm_pa; 2501 ioc->attr = (struct bfi_ioc_attr_s *) dm_kva; 2502 } 2503 2504 void 2505 bfa_ioc_enable(struct bfa_ioc_s *ioc) 2506 { 2507 bfa_ioc_stats(ioc, ioc_enables); 2508 ioc->dbg_fwsave_once = BFA_TRUE; 2509 2510 bfa_fsm_send_event(ioc, IOC_E_ENABLE); 2511 } 2512 2513 void 2514 bfa_ioc_disable(struct bfa_ioc_s *ioc) 2515 { 2516 bfa_ioc_stats(ioc, ioc_disables); 2517 bfa_fsm_send_event(ioc, IOC_E_DISABLE); 2518 } 2519 2520 void 2521 bfa_ioc_suspend(struct bfa_ioc_s *ioc) 2522 { 2523 ioc->dbg_fwsave_once = BFA_TRUE; 2524 bfa_fsm_send_event(ioc, IOC_E_HWERROR); 2525 } 2526 2527 /* 2528 * Initialize memory for saving firmware trace. Driver must initialize 2529 * trace memory before call bfa_ioc_enable(). 2530 */ 2531 void 2532 bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave) 2533 { 2534 ioc->dbg_fwsave = dbg_fwsave; 2535 ioc->dbg_fwsave_len = BFA_DBG_FWTRC_LEN; 2536 } 2537 2538 /* 2539 * Register mailbox message handler functions 2540 * 2541 * @param[in] ioc IOC instance 2542 * @param[in] mcfuncs message class handler functions 2543 */ 2544 void 2545 bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs) 2546 { 2547 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2548 int mc; 2549 2550 for (mc = 0; mc < BFI_MC_MAX; mc++) 2551 mod->mbhdlr[mc].cbfn = mcfuncs[mc]; 2552 } 2553 2554 /* 2555 * Register mailbox message handler function, to be called by common modules 2556 */ 2557 void 2558 bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc, 2559 bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg) 2560 { 2561 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2562 2563 mod->mbhdlr[mc].cbfn = cbfn; 2564 mod->mbhdlr[mc].cbarg = cbarg; 2565 } 2566 2567 /* 2568 * Queue a mailbox command request to firmware. Waits if mailbox is busy. 2569 * Responsibility of caller to serialize 2570 * 2571 * @param[in] ioc IOC instance 2572 * @param[i] cmd Mailbox command 2573 */ 2574 void 2575 bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd) 2576 { 2577 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2578 u32 stat; 2579 2580 /* 2581 * If a previous command is pending, queue new command 2582 */ 2583 if (!list_empty(&mod->cmd_q)) { 2584 list_add_tail(&cmd->qe, &mod->cmd_q); 2585 return; 2586 } 2587 2588 /* 2589 * If mailbox is busy, queue command for poll timer 2590 */ 2591 stat = readl(ioc->ioc_regs.hfn_mbox_cmd); 2592 if (stat) { 2593 list_add_tail(&cmd->qe, &mod->cmd_q); 2594 return; 2595 } 2596 2597 /* 2598 * mailbox is free -- queue command to firmware 2599 */ 2600 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); 2601 } 2602 2603 /* 2604 * Handle mailbox interrupts 2605 */ 2606 void 2607 bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc) 2608 { 2609 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; 2610 struct bfi_mbmsg_s m; 2611 int mc; 2612 2613 if (bfa_ioc_msgget(ioc, &m)) { 2614 /* 2615 * Treat IOC message class as special. 2616 */ 2617 mc = m.mh.msg_class; 2618 if (mc == BFI_MC_IOC) { 2619 bfa_ioc_isr(ioc, &m); 2620 return; 2621 } 2622 2623 if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL)) 2624 return; 2625 2626 mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m); 2627 } 2628 2629 bfa_ioc_lpu_read_stat(ioc); 2630 2631 /* 2632 * Try to send pending mailbox commands 2633 */ 2634 bfa_ioc_mbox_poll(ioc); 2635 } 2636 2637 void 2638 bfa_ioc_error_isr(struct bfa_ioc_s *ioc) 2639 { 2640 bfa_ioc_stats(ioc, ioc_hbfails); 2641 ioc->stats.hb_count = ioc->hb_count; 2642 bfa_fsm_send_event(ioc, IOC_E_HWERROR); 2643 } 2644 2645 /* 2646 * return true if IOC is disabled 2647 */ 2648 bfa_boolean_t 2649 bfa_ioc_is_disabled(struct bfa_ioc_s *ioc) 2650 { 2651 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) || 2652 bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled); 2653 } 2654 2655 /* 2656 * return true if IOC firmware is different. 2657 */ 2658 bfa_boolean_t 2659 bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc) 2660 { 2661 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset) || 2662 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_fwcheck) || 2663 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_mismatch); 2664 } 2665 2666 /* 2667 * Check if adapter is disabled -- both IOCs should be in a disabled 2668 * state. 2669 */ 2670 bfa_boolean_t 2671 bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc) 2672 { 2673 u32 ioc_state; 2674 2675 if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled)) 2676 return BFA_FALSE; 2677 2678 ioc_state = bfa_ioc_get_cur_ioc_fwstate(ioc); 2679 if (!bfa_ioc_state_disabled(ioc_state)) 2680 return BFA_FALSE; 2681 2682 if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_FC_8G1P) { 2683 ioc_state = bfa_ioc_get_cur_ioc_fwstate(ioc); 2684 if (!bfa_ioc_state_disabled(ioc_state)) 2685 return BFA_FALSE; 2686 } 2687 2688 return BFA_TRUE; 2689 } 2690 2691 /* 2692 * Reset IOC fwstate registers. 2693 */ 2694 void 2695 bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc) 2696 { 2697 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_UNINIT); 2698 bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_UNINIT); 2699 } 2700 2701 #define BFA_MFG_NAME "QLogic" 2702 void 2703 bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, 2704 struct bfa_adapter_attr_s *ad_attr) 2705 { 2706 struct bfi_ioc_attr_s *ioc_attr; 2707 2708 ioc_attr = ioc->attr; 2709 2710 bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num); 2711 bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver); 2712 bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver); 2713 bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer); 2714 memcpy(&ad_attr->vpd, &ioc_attr->vpd, 2715 sizeof(struct bfa_mfg_vpd_s)); 2716 2717 ad_attr->nports = bfa_ioc_get_nports(ioc); 2718 ad_attr->max_speed = bfa_ioc_speed_sup(ioc); 2719 2720 bfa_ioc_get_adapter_model(ioc, ad_attr->model); 2721 /* For now, model descr uses same model string */ 2722 bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr); 2723 2724 ad_attr->card_type = ioc_attr->card_type; 2725 ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type); 2726 2727 if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop)) 2728 ad_attr->prototype = 1; 2729 else 2730 ad_attr->prototype = 0; 2731 2732 ad_attr->pwwn = ioc->attr->pwwn; 2733 ad_attr->mac = bfa_ioc_get_mac(ioc); 2734 2735 ad_attr->pcie_gen = ioc_attr->pcie_gen; 2736 ad_attr->pcie_lanes = ioc_attr->pcie_lanes; 2737 ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig; 2738 ad_attr->asic_rev = ioc_attr->asic_rev; 2739 2740 bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver); 2741 2742 ad_attr->cna_capable = bfa_ioc_is_cna(ioc); 2743 ad_attr->trunk_capable = (ad_attr->nports > 1) && 2744 !bfa_ioc_is_cna(ioc) && !ad_attr->is_mezz; 2745 ad_attr->mfg_day = ioc_attr->mfg_day; 2746 ad_attr->mfg_month = ioc_attr->mfg_month; 2747 ad_attr->mfg_year = ioc_attr->mfg_year; 2748 memcpy(ad_attr->uuid, ioc_attr->uuid, BFA_ADAPTER_UUID_LEN); 2749 } 2750 2751 enum bfa_ioc_type_e 2752 bfa_ioc_get_type(struct bfa_ioc_s *ioc) 2753 { 2754 if (ioc->clscode == BFI_PCIFN_CLASS_ETH) 2755 return BFA_IOC_TYPE_LL; 2756 2757 WARN_ON(ioc->clscode != BFI_PCIFN_CLASS_FC); 2758 2759 return (ioc->attr->port_mode == BFI_PORT_MODE_FC) 2760 ? BFA_IOC_TYPE_FC : BFA_IOC_TYPE_FCoE; 2761 } 2762 2763 void 2764 bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num) 2765 { 2766 memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN); 2767 memcpy((void *)serial_num, 2768 (void *)ioc->attr->brcd_serialnum, 2769 BFA_ADAPTER_SERIAL_NUM_LEN); 2770 } 2771 2772 void 2773 bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver) 2774 { 2775 memset((void *)fw_ver, 0, BFA_VERSION_LEN); 2776 memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN); 2777 } 2778 2779 void 2780 bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev) 2781 { 2782 WARN_ON(!chip_rev); 2783 2784 memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN); 2785 2786 chip_rev[0] = 'R'; 2787 chip_rev[1] = 'e'; 2788 chip_rev[2] = 'v'; 2789 chip_rev[3] = '-'; 2790 chip_rev[4] = ioc->attr->asic_rev; 2791 chip_rev[5] = '\0'; 2792 } 2793 2794 void 2795 bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver) 2796 { 2797 memset((void *)optrom_ver, 0, BFA_VERSION_LEN); 2798 memcpy(optrom_ver, ioc->attr->optrom_version, 2799 BFA_VERSION_LEN); 2800 } 2801 2802 void 2803 bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer) 2804 { 2805 memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN); 2806 strncpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); 2807 } 2808 2809 void 2810 bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model) 2811 { 2812 struct bfi_ioc_attr_s *ioc_attr; 2813 u8 nports = bfa_ioc_get_nports(ioc); 2814 2815 WARN_ON(!model); 2816 memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN); 2817 2818 ioc_attr = ioc->attr; 2819 2820 if (bfa_asic_id_ct2(ioc->pcidev.device_id) && 2821 (!bfa_mfg_is_mezz(ioc_attr->card_type))) 2822 snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u-%u%s", 2823 BFA_MFG_NAME, ioc_attr->card_type, nports, "p"); 2824 else 2825 snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u", 2826 BFA_MFG_NAME, ioc_attr->card_type); 2827 } 2828 2829 enum bfa_ioc_state 2830 bfa_ioc_get_state(struct bfa_ioc_s *ioc) 2831 { 2832 enum bfa_iocpf_state iocpf_st; 2833 enum bfa_ioc_state ioc_st = bfa_sm_to_state(ioc_sm_table, ioc->fsm); 2834 2835 if (ioc_st == BFA_IOC_ENABLING || 2836 ioc_st == BFA_IOC_FAIL || ioc_st == BFA_IOC_INITFAIL) { 2837 2838 iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm); 2839 2840 switch (iocpf_st) { 2841 case BFA_IOCPF_SEMWAIT: 2842 ioc_st = BFA_IOC_SEMWAIT; 2843 break; 2844 2845 case BFA_IOCPF_HWINIT: 2846 ioc_st = BFA_IOC_HWINIT; 2847 break; 2848 2849 case BFA_IOCPF_FWMISMATCH: 2850 ioc_st = BFA_IOC_FWMISMATCH; 2851 break; 2852 2853 case BFA_IOCPF_FAIL: 2854 ioc_st = BFA_IOC_FAIL; 2855 break; 2856 2857 case BFA_IOCPF_INITFAIL: 2858 ioc_st = BFA_IOC_INITFAIL; 2859 break; 2860 2861 default: 2862 break; 2863 } 2864 } 2865 2866 return ioc_st; 2867 } 2868 2869 void 2870 bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) 2871 { 2872 memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s)); 2873 2874 ioc_attr->state = bfa_ioc_get_state(ioc); 2875 ioc_attr->port_id = bfa_ioc_portid(ioc); 2876 ioc_attr->port_mode = ioc->port_mode; 2877 ioc_attr->port_mode_cfg = ioc->port_mode_cfg; 2878 ioc_attr->cap_bm = ioc->ad_cap_bm; 2879 2880 ioc_attr->ioc_type = bfa_ioc_get_type(ioc); 2881 2882 bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr); 2883 2884 ioc_attr->pci_attr.device_id = bfa_ioc_devid(ioc); 2885 ioc_attr->pci_attr.pcifn = bfa_ioc_pcifn(ioc); 2886 ioc_attr->def_fn = (bfa_ioc_pcifn(ioc) == bfa_ioc_portid(ioc)); 2887 bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev); 2888 } 2889 2890 mac_t 2891 bfa_ioc_get_mac(struct bfa_ioc_s *ioc) 2892 { 2893 /* 2894 * Check the IOC type and return the appropriate MAC 2895 */ 2896 if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE) 2897 return ioc->attr->fcoe_mac; 2898 else 2899 return ioc->attr->mac; 2900 } 2901 2902 mac_t 2903 bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc) 2904 { 2905 mac_t m; 2906 2907 m = ioc->attr->mfg_mac; 2908 if (bfa_mfg_is_old_wwn_mac_model(ioc->attr->card_type)) 2909 m.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc); 2910 else 2911 bfa_mfg_increment_wwn_mac(&(m.mac[MAC_ADDRLEN-3]), 2912 bfa_ioc_pcifn(ioc)); 2913 2914 return m; 2915 } 2916 2917 /* 2918 * Send AEN notification 2919 */ 2920 void 2921 bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event) 2922 { 2923 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 2924 struct bfa_aen_entry_s *aen_entry; 2925 enum bfa_ioc_type_e ioc_type; 2926 2927 bfad_get_aen_entry(bfad, aen_entry); 2928 if (!aen_entry) 2929 return; 2930 2931 ioc_type = bfa_ioc_get_type(ioc); 2932 switch (ioc_type) { 2933 case BFA_IOC_TYPE_FC: 2934 aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn; 2935 break; 2936 case BFA_IOC_TYPE_FCoE: 2937 aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn; 2938 aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc); 2939 break; 2940 case BFA_IOC_TYPE_LL: 2941 aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc); 2942 break; 2943 default: 2944 WARN_ON(ioc_type != BFA_IOC_TYPE_FC); 2945 break; 2946 } 2947 2948 /* Send the AEN notification */ 2949 aen_entry->aen_data.ioc.ioc_type = ioc_type; 2950 bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq, 2951 BFA_AEN_CAT_IOC, event); 2952 } 2953 2954 /* 2955 * Retrieve saved firmware trace from a prior IOC failure. 2956 */ 2957 bfa_status_t 2958 bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) 2959 { 2960 int tlen; 2961 2962 if (ioc->dbg_fwsave_len == 0) 2963 return BFA_STATUS_ENOFSAVE; 2964 2965 tlen = *trclen; 2966 if (tlen > ioc->dbg_fwsave_len) 2967 tlen = ioc->dbg_fwsave_len; 2968 2969 memcpy(trcdata, ioc->dbg_fwsave, tlen); 2970 *trclen = tlen; 2971 return BFA_STATUS_OK; 2972 } 2973 2974 2975 /* 2976 * Retrieve saved firmware trace from a prior IOC failure. 2977 */ 2978 bfa_status_t 2979 bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) 2980 { 2981 u32 loff = BFA_DBG_FWTRC_OFF(bfa_ioc_portid(ioc)); 2982 int tlen; 2983 bfa_status_t status; 2984 2985 bfa_trc(ioc, *trclen); 2986 2987 tlen = *trclen; 2988 if (tlen > BFA_DBG_FWTRC_LEN) 2989 tlen = BFA_DBG_FWTRC_LEN; 2990 2991 status = bfa_ioc_smem_read(ioc, trcdata, loff, tlen); 2992 *trclen = tlen; 2993 return status; 2994 } 2995 2996 static void 2997 bfa_ioc_send_fwsync(struct bfa_ioc_s *ioc) 2998 { 2999 struct bfa_mbox_cmd_s cmd; 3000 struct bfi_ioc_ctrl_req_s *req = (struct bfi_ioc_ctrl_req_s *) cmd.msg; 3001 3002 bfi_h2i_set(req->mh, BFI_MC_IOC, BFI_IOC_H2I_DBG_SYNC, 3003 bfa_ioc_portid(ioc)); 3004 req->clscode = cpu_to_be16(ioc->clscode); 3005 bfa_ioc_mbox_queue(ioc, &cmd); 3006 } 3007 3008 static void 3009 bfa_ioc_fwsync(struct bfa_ioc_s *ioc) 3010 { 3011 u32 fwsync_iter = 1000; 3012 3013 bfa_ioc_send_fwsync(ioc); 3014 3015 /* 3016 * After sending a fw sync mbox command wait for it to 3017 * take effect. We will not wait for a response because 3018 * 1. fw_sync mbox cmd doesn't have a response. 3019 * 2. Even if we implement that, interrupts might not 3020 * be enabled when we call this function. 3021 * So, just keep checking if any mbox cmd is pending, and 3022 * after waiting for a reasonable amount of time, go ahead. 3023 * It is possible that fw has crashed and the mbox command 3024 * is never acknowledged. 3025 */ 3026 while (bfa_ioc_mbox_cmd_pending(ioc) && fwsync_iter > 0) 3027 fwsync_iter--; 3028 } 3029 3030 /* 3031 * Dump firmware smem 3032 */ 3033 bfa_status_t 3034 bfa_ioc_debug_fwcore(struct bfa_ioc_s *ioc, void *buf, 3035 u32 *offset, int *buflen) 3036 { 3037 u32 loff; 3038 int dlen; 3039 bfa_status_t status; 3040 u32 smem_len = BFA_IOC_FW_SMEM_SIZE(ioc); 3041 3042 if (*offset >= smem_len) { 3043 *offset = *buflen = 0; 3044 return BFA_STATUS_EINVAL; 3045 } 3046 3047 loff = *offset; 3048 dlen = *buflen; 3049 3050 /* 3051 * First smem read, sync smem before proceeding 3052 * No need to sync before reading every chunk. 3053 */ 3054 if (loff == 0) 3055 bfa_ioc_fwsync(ioc); 3056 3057 if ((loff + dlen) >= smem_len) 3058 dlen = smem_len - loff; 3059 3060 status = bfa_ioc_smem_read(ioc, buf, loff, dlen); 3061 3062 if (status != BFA_STATUS_OK) { 3063 *offset = *buflen = 0; 3064 return status; 3065 } 3066 3067 *offset += dlen; 3068 3069 if (*offset >= smem_len) 3070 *offset = 0; 3071 3072 *buflen = dlen; 3073 3074 return status; 3075 } 3076 3077 /* 3078 * Firmware statistics 3079 */ 3080 bfa_status_t 3081 bfa_ioc_fw_stats_get(struct bfa_ioc_s *ioc, void *stats) 3082 { 3083 u32 loff = BFI_IOC_FWSTATS_OFF + \ 3084 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc)); 3085 int tlen; 3086 bfa_status_t status; 3087 3088 if (ioc->stats_busy) { 3089 bfa_trc(ioc, ioc->stats_busy); 3090 return BFA_STATUS_DEVBUSY; 3091 } 3092 ioc->stats_busy = BFA_TRUE; 3093 3094 tlen = sizeof(struct bfa_fw_stats_s); 3095 status = bfa_ioc_smem_read(ioc, stats, loff, tlen); 3096 3097 ioc->stats_busy = BFA_FALSE; 3098 return status; 3099 } 3100 3101 bfa_status_t 3102 bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc) 3103 { 3104 u32 loff = BFI_IOC_FWSTATS_OFF + \ 3105 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc)); 3106 int tlen; 3107 bfa_status_t status; 3108 3109 if (ioc->stats_busy) { 3110 bfa_trc(ioc, ioc->stats_busy); 3111 return BFA_STATUS_DEVBUSY; 3112 } 3113 ioc->stats_busy = BFA_TRUE; 3114 3115 tlen = sizeof(struct bfa_fw_stats_s); 3116 status = bfa_ioc_smem_clr(ioc, loff, tlen); 3117 3118 ioc->stats_busy = BFA_FALSE; 3119 return status; 3120 } 3121 3122 /* 3123 * Save firmware trace if configured. 3124 */ 3125 void 3126 bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc) 3127 { 3128 int tlen; 3129 3130 if (ioc->dbg_fwsave_once) { 3131 ioc->dbg_fwsave_once = BFA_FALSE; 3132 if (ioc->dbg_fwsave_len) { 3133 tlen = ioc->dbg_fwsave_len; 3134 bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen); 3135 } 3136 } 3137 } 3138 3139 /* 3140 * Firmware failure detected. Start recovery actions. 3141 */ 3142 static void 3143 bfa_ioc_recover(struct bfa_ioc_s *ioc) 3144 { 3145 bfa_ioc_stats(ioc, ioc_hbfails); 3146 ioc->stats.hb_count = ioc->hb_count; 3147 bfa_fsm_send_event(ioc, IOC_E_HBFAIL); 3148 } 3149 3150 /* 3151 * BFA IOC PF private functions 3152 */ 3153 static void 3154 bfa_iocpf_timeout(void *ioc_arg) 3155 { 3156 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg; 3157 3158 bfa_trc(ioc, 0); 3159 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT); 3160 } 3161 3162 static void 3163 bfa_iocpf_sem_timeout(void *ioc_arg) 3164 { 3165 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg; 3166 3167 bfa_ioc_hw_sem_get(ioc); 3168 } 3169 3170 static void 3171 bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc) 3172 { 3173 u32 fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc); 3174 3175 bfa_trc(ioc, fwstate); 3176 3177 if (fwstate == BFI_IOC_DISABLED) { 3178 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY); 3179 return; 3180 } 3181 3182 if (ioc->iocpf.poll_time >= (3 * BFA_IOC_TOV)) 3183 bfa_iocpf_timeout(ioc); 3184 else { 3185 ioc->iocpf.poll_time += BFA_IOC_POLL_TOV; 3186 bfa_iocpf_poll_timer_start(ioc); 3187 } 3188 } 3189 3190 static void 3191 bfa_iocpf_poll_timeout(void *ioc_arg) 3192 { 3193 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg; 3194 3195 bfa_ioc_poll_fwinit(ioc); 3196 } 3197 3198 /* 3199 * bfa timer function 3200 */ 3201 void 3202 bfa_timer_beat(struct bfa_timer_mod_s *mod) 3203 { 3204 struct list_head *qh = &mod->timer_q; 3205 struct list_head *qe, *qe_next; 3206 struct bfa_timer_s *elem; 3207 struct list_head timedout_q; 3208 3209 INIT_LIST_HEAD(&timedout_q); 3210 3211 qe = bfa_q_next(qh); 3212 3213 while (qe != qh) { 3214 qe_next = bfa_q_next(qe); 3215 3216 elem = (struct bfa_timer_s *) qe; 3217 if (elem->timeout <= BFA_TIMER_FREQ) { 3218 elem->timeout = 0; 3219 list_del(&elem->qe); 3220 list_add_tail(&elem->qe, &timedout_q); 3221 } else { 3222 elem->timeout -= BFA_TIMER_FREQ; 3223 } 3224 3225 qe = qe_next; /* go to next elem */ 3226 } 3227 3228 /* 3229 * Pop all the timeout entries 3230 */ 3231 while (!list_empty(&timedout_q)) { 3232 bfa_q_deq(&timedout_q, &elem); 3233 elem->timercb(elem->arg); 3234 } 3235 } 3236 3237 /* 3238 * Should be called with lock protection 3239 */ 3240 void 3241 bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer, 3242 void (*timercb) (void *), void *arg, unsigned int timeout) 3243 { 3244 3245 WARN_ON(timercb == NULL); 3246 WARN_ON(bfa_q_is_on_q(&mod->timer_q, timer)); 3247 3248 timer->timeout = timeout; 3249 timer->timercb = timercb; 3250 timer->arg = arg; 3251 3252 list_add_tail(&timer->qe, &mod->timer_q); 3253 } 3254 3255 /* 3256 * Should be called with lock protection 3257 */ 3258 void 3259 bfa_timer_stop(struct bfa_timer_s *timer) 3260 { 3261 WARN_ON(list_empty(&timer->qe)); 3262 3263 list_del(&timer->qe); 3264 } 3265 3266 /* 3267 * ASIC block related 3268 */ 3269 static void 3270 bfa_ablk_config_swap(struct bfa_ablk_cfg_s *cfg) 3271 { 3272 struct bfa_ablk_cfg_inst_s *cfg_inst; 3273 int i, j; 3274 u16 be16; 3275 3276 for (i = 0; i < BFA_ABLK_MAX; i++) { 3277 cfg_inst = &cfg->inst[i]; 3278 for (j = 0; j < BFA_ABLK_MAX_PFS; j++) { 3279 be16 = cfg_inst->pf_cfg[j].pers; 3280 cfg_inst->pf_cfg[j].pers = be16_to_cpu(be16); 3281 be16 = cfg_inst->pf_cfg[j].num_qpairs; 3282 cfg_inst->pf_cfg[j].num_qpairs = be16_to_cpu(be16); 3283 be16 = cfg_inst->pf_cfg[j].num_vectors; 3284 cfg_inst->pf_cfg[j].num_vectors = be16_to_cpu(be16); 3285 be16 = cfg_inst->pf_cfg[j].bw_min; 3286 cfg_inst->pf_cfg[j].bw_min = be16_to_cpu(be16); 3287 be16 = cfg_inst->pf_cfg[j].bw_max; 3288 cfg_inst->pf_cfg[j].bw_max = be16_to_cpu(be16); 3289 } 3290 } 3291 } 3292 3293 static void 3294 bfa_ablk_isr(void *cbarg, struct bfi_mbmsg_s *msg) 3295 { 3296 struct bfa_ablk_s *ablk = (struct bfa_ablk_s *)cbarg; 3297 struct bfi_ablk_i2h_rsp_s *rsp = (struct bfi_ablk_i2h_rsp_s *)msg; 3298 bfa_ablk_cbfn_t cbfn; 3299 3300 WARN_ON(msg->mh.msg_class != BFI_MC_ABLK); 3301 bfa_trc(ablk->ioc, msg->mh.msg_id); 3302 3303 switch (msg->mh.msg_id) { 3304 case BFI_ABLK_I2H_QUERY: 3305 if (rsp->status == BFA_STATUS_OK) { 3306 memcpy(ablk->cfg, ablk->dma_addr.kva, 3307 sizeof(struct bfa_ablk_cfg_s)); 3308 bfa_ablk_config_swap(ablk->cfg); 3309 ablk->cfg = NULL; 3310 } 3311 break; 3312 3313 case BFI_ABLK_I2H_ADPT_CONFIG: 3314 case BFI_ABLK_I2H_PORT_CONFIG: 3315 /* update config port mode */ 3316 ablk->ioc->port_mode_cfg = rsp->port_mode; 3317 3318 case BFI_ABLK_I2H_PF_DELETE: 3319 case BFI_ABLK_I2H_PF_UPDATE: 3320 case BFI_ABLK_I2H_OPTROM_ENABLE: 3321 case BFI_ABLK_I2H_OPTROM_DISABLE: 3322 /* No-op */ 3323 break; 3324 3325 case BFI_ABLK_I2H_PF_CREATE: 3326 *(ablk->pcifn) = rsp->pcifn; 3327 ablk->pcifn = NULL; 3328 break; 3329 3330 default: 3331 WARN_ON(1); 3332 } 3333 3334 ablk->busy = BFA_FALSE; 3335 if (ablk->cbfn) { 3336 cbfn = ablk->cbfn; 3337 ablk->cbfn = NULL; 3338 cbfn(ablk->cbarg, rsp->status); 3339 } 3340 } 3341 3342 static void 3343 bfa_ablk_notify(void *cbarg, enum bfa_ioc_event_e event) 3344 { 3345 struct bfa_ablk_s *ablk = (struct bfa_ablk_s *)cbarg; 3346 3347 bfa_trc(ablk->ioc, event); 3348 3349 switch (event) { 3350 case BFA_IOC_E_ENABLED: 3351 WARN_ON(ablk->busy != BFA_FALSE); 3352 break; 3353 3354 case BFA_IOC_E_DISABLED: 3355 case BFA_IOC_E_FAILED: 3356 /* Fail any pending requests */ 3357 ablk->pcifn = NULL; 3358 if (ablk->busy) { 3359 if (ablk->cbfn) 3360 ablk->cbfn(ablk->cbarg, BFA_STATUS_FAILED); 3361 ablk->cbfn = NULL; 3362 ablk->busy = BFA_FALSE; 3363 } 3364 break; 3365 3366 default: 3367 WARN_ON(1); 3368 break; 3369 } 3370 } 3371 3372 u32 3373 bfa_ablk_meminfo(void) 3374 { 3375 return BFA_ROUNDUP(sizeof(struct bfa_ablk_cfg_s), BFA_DMA_ALIGN_SZ); 3376 } 3377 3378 void 3379 bfa_ablk_memclaim(struct bfa_ablk_s *ablk, u8 *dma_kva, u64 dma_pa) 3380 { 3381 ablk->dma_addr.kva = dma_kva; 3382 ablk->dma_addr.pa = dma_pa; 3383 } 3384 3385 void 3386 bfa_ablk_attach(struct bfa_ablk_s *ablk, struct bfa_ioc_s *ioc) 3387 { 3388 ablk->ioc = ioc; 3389 3390 bfa_ioc_mbox_regisr(ablk->ioc, BFI_MC_ABLK, bfa_ablk_isr, ablk); 3391 bfa_q_qe_init(&ablk->ioc_notify); 3392 bfa_ioc_notify_init(&ablk->ioc_notify, bfa_ablk_notify, ablk); 3393 list_add_tail(&ablk->ioc_notify.qe, &ablk->ioc->notify_q); 3394 } 3395 3396 bfa_status_t 3397 bfa_ablk_query(struct bfa_ablk_s *ablk, struct bfa_ablk_cfg_s *ablk_cfg, 3398 bfa_ablk_cbfn_t cbfn, void *cbarg) 3399 { 3400 struct bfi_ablk_h2i_query_s *m; 3401 3402 WARN_ON(!ablk_cfg); 3403 3404 if (!bfa_ioc_is_operational(ablk->ioc)) { 3405 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3406 return BFA_STATUS_IOC_FAILURE; 3407 } 3408 3409 if (ablk->busy) { 3410 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3411 return BFA_STATUS_DEVBUSY; 3412 } 3413 3414 ablk->cfg = ablk_cfg; 3415 ablk->cbfn = cbfn; 3416 ablk->cbarg = cbarg; 3417 ablk->busy = BFA_TRUE; 3418 3419 m = (struct bfi_ablk_h2i_query_s *)ablk->mb.msg; 3420 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_QUERY, 3421 bfa_ioc_portid(ablk->ioc)); 3422 bfa_dma_be_addr_set(m->addr, ablk->dma_addr.pa); 3423 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3424 3425 return BFA_STATUS_OK; 3426 } 3427 3428 bfa_status_t 3429 bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn, 3430 u8 port, enum bfi_pcifn_class personality, 3431 u16 bw_min, u16 bw_max, 3432 bfa_ablk_cbfn_t cbfn, void *cbarg) 3433 { 3434 struct bfi_ablk_h2i_pf_req_s *m; 3435 3436 if (!bfa_ioc_is_operational(ablk->ioc)) { 3437 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3438 return BFA_STATUS_IOC_FAILURE; 3439 } 3440 3441 if (ablk->busy) { 3442 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3443 return BFA_STATUS_DEVBUSY; 3444 } 3445 3446 ablk->pcifn = pcifn; 3447 ablk->cbfn = cbfn; 3448 ablk->cbarg = cbarg; 3449 ablk->busy = BFA_TRUE; 3450 3451 m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg; 3452 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_CREATE, 3453 bfa_ioc_portid(ablk->ioc)); 3454 m->pers = cpu_to_be16((u16)personality); 3455 m->bw_min = cpu_to_be16(bw_min); 3456 m->bw_max = cpu_to_be16(bw_max); 3457 m->port = port; 3458 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3459 3460 return BFA_STATUS_OK; 3461 } 3462 3463 bfa_status_t 3464 bfa_ablk_pf_delete(struct bfa_ablk_s *ablk, int pcifn, 3465 bfa_ablk_cbfn_t cbfn, void *cbarg) 3466 { 3467 struct bfi_ablk_h2i_pf_req_s *m; 3468 3469 if (!bfa_ioc_is_operational(ablk->ioc)) { 3470 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3471 return BFA_STATUS_IOC_FAILURE; 3472 } 3473 3474 if (ablk->busy) { 3475 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3476 return BFA_STATUS_DEVBUSY; 3477 } 3478 3479 ablk->cbfn = cbfn; 3480 ablk->cbarg = cbarg; 3481 ablk->busy = BFA_TRUE; 3482 3483 m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg; 3484 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_DELETE, 3485 bfa_ioc_portid(ablk->ioc)); 3486 m->pcifn = (u8)pcifn; 3487 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3488 3489 return BFA_STATUS_OK; 3490 } 3491 3492 bfa_status_t 3493 bfa_ablk_adapter_config(struct bfa_ablk_s *ablk, enum bfa_mode_s mode, 3494 int max_pf, int max_vf, bfa_ablk_cbfn_t cbfn, void *cbarg) 3495 { 3496 struct bfi_ablk_h2i_cfg_req_s *m; 3497 3498 if (!bfa_ioc_is_operational(ablk->ioc)) { 3499 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3500 return BFA_STATUS_IOC_FAILURE; 3501 } 3502 3503 if (ablk->busy) { 3504 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3505 return BFA_STATUS_DEVBUSY; 3506 } 3507 3508 ablk->cbfn = cbfn; 3509 ablk->cbarg = cbarg; 3510 ablk->busy = BFA_TRUE; 3511 3512 m = (struct bfi_ablk_h2i_cfg_req_s *)ablk->mb.msg; 3513 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_ADPT_CONFIG, 3514 bfa_ioc_portid(ablk->ioc)); 3515 m->mode = (u8)mode; 3516 m->max_pf = (u8)max_pf; 3517 m->max_vf = (u8)max_vf; 3518 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3519 3520 return BFA_STATUS_OK; 3521 } 3522 3523 bfa_status_t 3524 bfa_ablk_port_config(struct bfa_ablk_s *ablk, int port, enum bfa_mode_s mode, 3525 int max_pf, int max_vf, bfa_ablk_cbfn_t cbfn, void *cbarg) 3526 { 3527 struct bfi_ablk_h2i_cfg_req_s *m; 3528 3529 if (!bfa_ioc_is_operational(ablk->ioc)) { 3530 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3531 return BFA_STATUS_IOC_FAILURE; 3532 } 3533 3534 if (ablk->busy) { 3535 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3536 return BFA_STATUS_DEVBUSY; 3537 } 3538 3539 ablk->cbfn = cbfn; 3540 ablk->cbarg = cbarg; 3541 ablk->busy = BFA_TRUE; 3542 3543 m = (struct bfi_ablk_h2i_cfg_req_s *)ablk->mb.msg; 3544 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PORT_CONFIG, 3545 bfa_ioc_portid(ablk->ioc)); 3546 m->port = (u8)port; 3547 m->mode = (u8)mode; 3548 m->max_pf = (u8)max_pf; 3549 m->max_vf = (u8)max_vf; 3550 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3551 3552 return BFA_STATUS_OK; 3553 } 3554 3555 bfa_status_t 3556 bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, u16 bw_min, 3557 u16 bw_max, bfa_ablk_cbfn_t cbfn, void *cbarg) 3558 { 3559 struct bfi_ablk_h2i_pf_req_s *m; 3560 3561 if (!bfa_ioc_is_operational(ablk->ioc)) { 3562 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3563 return BFA_STATUS_IOC_FAILURE; 3564 } 3565 3566 if (ablk->busy) { 3567 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3568 return BFA_STATUS_DEVBUSY; 3569 } 3570 3571 ablk->cbfn = cbfn; 3572 ablk->cbarg = cbarg; 3573 ablk->busy = BFA_TRUE; 3574 3575 m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg; 3576 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_UPDATE, 3577 bfa_ioc_portid(ablk->ioc)); 3578 m->pcifn = (u8)pcifn; 3579 m->bw_min = cpu_to_be16(bw_min); 3580 m->bw_max = cpu_to_be16(bw_max); 3581 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3582 3583 return BFA_STATUS_OK; 3584 } 3585 3586 bfa_status_t 3587 bfa_ablk_optrom_en(struct bfa_ablk_s *ablk, bfa_ablk_cbfn_t cbfn, void *cbarg) 3588 { 3589 struct bfi_ablk_h2i_optrom_s *m; 3590 3591 if (!bfa_ioc_is_operational(ablk->ioc)) { 3592 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3593 return BFA_STATUS_IOC_FAILURE; 3594 } 3595 3596 if (ablk->busy) { 3597 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3598 return BFA_STATUS_DEVBUSY; 3599 } 3600 3601 ablk->cbfn = cbfn; 3602 ablk->cbarg = cbarg; 3603 ablk->busy = BFA_TRUE; 3604 3605 m = (struct bfi_ablk_h2i_optrom_s *)ablk->mb.msg; 3606 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_OPTROM_ENABLE, 3607 bfa_ioc_portid(ablk->ioc)); 3608 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3609 3610 return BFA_STATUS_OK; 3611 } 3612 3613 bfa_status_t 3614 bfa_ablk_optrom_dis(struct bfa_ablk_s *ablk, bfa_ablk_cbfn_t cbfn, void *cbarg) 3615 { 3616 struct bfi_ablk_h2i_optrom_s *m; 3617 3618 if (!bfa_ioc_is_operational(ablk->ioc)) { 3619 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE); 3620 return BFA_STATUS_IOC_FAILURE; 3621 } 3622 3623 if (ablk->busy) { 3624 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY); 3625 return BFA_STATUS_DEVBUSY; 3626 } 3627 3628 ablk->cbfn = cbfn; 3629 ablk->cbarg = cbarg; 3630 ablk->busy = BFA_TRUE; 3631 3632 m = (struct bfi_ablk_h2i_optrom_s *)ablk->mb.msg; 3633 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_OPTROM_DISABLE, 3634 bfa_ioc_portid(ablk->ioc)); 3635 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); 3636 3637 return BFA_STATUS_OK; 3638 } 3639 3640 /* 3641 * SFP module specific 3642 */ 3643 3644 /* forward declarations */ 3645 static void bfa_sfp_getdata_send(struct bfa_sfp_s *sfp); 3646 static void bfa_sfp_media_get(struct bfa_sfp_s *sfp); 3647 static bfa_status_t bfa_sfp_speed_valid(struct bfa_sfp_s *sfp, 3648 enum bfa_port_speed portspeed); 3649 3650 static void 3651 bfa_cb_sfp_show(struct bfa_sfp_s *sfp) 3652 { 3653 bfa_trc(sfp, sfp->lock); 3654 if (sfp->cbfn) 3655 sfp->cbfn(sfp->cbarg, sfp->status); 3656 sfp->lock = 0; 3657 sfp->cbfn = NULL; 3658 } 3659 3660 static void 3661 bfa_cb_sfp_state_query(struct bfa_sfp_s *sfp) 3662 { 3663 bfa_trc(sfp, sfp->portspeed); 3664 if (sfp->media) { 3665 bfa_sfp_media_get(sfp); 3666 if (sfp->state_query_cbfn) 3667 sfp->state_query_cbfn(sfp->state_query_cbarg, 3668 sfp->status); 3669 sfp->media = NULL; 3670 } 3671 3672 if (sfp->portspeed) { 3673 sfp->status = bfa_sfp_speed_valid(sfp, sfp->portspeed); 3674 if (sfp->state_query_cbfn) 3675 sfp->state_query_cbfn(sfp->state_query_cbarg, 3676 sfp->status); 3677 sfp->portspeed = BFA_PORT_SPEED_UNKNOWN; 3678 } 3679 3680 sfp->state_query_lock = 0; 3681 sfp->state_query_cbfn = NULL; 3682 } 3683 3684 /* 3685 * IOC event handler. 3686 */ 3687 static void 3688 bfa_sfp_notify(void *sfp_arg, enum bfa_ioc_event_e event) 3689 { 3690 struct bfa_sfp_s *sfp = sfp_arg; 3691 3692 bfa_trc(sfp, event); 3693 bfa_trc(sfp, sfp->lock); 3694 bfa_trc(sfp, sfp->state_query_lock); 3695 3696 switch (event) { 3697 case BFA_IOC_E_DISABLED: 3698 case BFA_IOC_E_FAILED: 3699 if (sfp->lock) { 3700 sfp->status = BFA_STATUS_IOC_FAILURE; 3701 bfa_cb_sfp_show(sfp); 3702 } 3703 3704 if (sfp->state_query_lock) { 3705 sfp->status = BFA_STATUS_IOC_FAILURE; 3706 bfa_cb_sfp_state_query(sfp); 3707 } 3708 break; 3709 3710 default: 3711 break; 3712 } 3713 } 3714 3715 /* 3716 * SFP's State Change Notification post to AEN 3717 */ 3718 static void 3719 bfa_sfp_scn_aen_post(struct bfa_sfp_s *sfp, struct bfi_sfp_scn_s *rsp) 3720 { 3721 struct bfad_s *bfad = (struct bfad_s *)sfp->ioc->bfa->bfad; 3722 struct bfa_aen_entry_s *aen_entry; 3723 enum bfa_port_aen_event aen_evt = 0; 3724 3725 bfa_trc(sfp, (((u64)rsp->pomlvl) << 16) | (((u64)rsp->sfpid) << 8) | 3726 ((u64)rsp->event)); 3727 3728 bfad_get_aen_entry(bfad, aen_entry); 3729 if (!aen_entry) 3730 return; 3731 3732 aen_entry->aen_data.port.ioc_type = bfa_ioc_get_type(sfp->ioc); 3733 aen_entry->aen_data.port.pwwn = sfp->ioc->attr->pwwn; 3734 aen_entry->aen_data.port.mac = bfa_ioc_get_mac(sfp->ioc); 3735 3736 switch (rsp->event) { 3737 case BFA_SFP_SCN_INSERTED: 3738 aen_evt = BFA_PORT_AEN_SFP_INSERT; 3739 break; 3740 case BFA_SFP_SCN_REMOVED: 3741 aen_evt = BFA_PORT_AEN_SFP_REMOVE; 3742 break; 3743 case BFA_SFP_SCN_FAILED: 3744 aen_evt = BFA_PORT_AEN_SFP_ACCESS_ERROR; 3745 break; 3746 case BFA_SFP_SCN_UNSUPPORT: 3747 aen_evt = BFA_PORT_AEN_SFP_UNSUPPORT; 3748 break; 3749 case BFA_SFP_SCN_POM: 3750 aen_evt = BFA_PORT_AEN_SFP_POM; 3751 aen_entry->aen_data.port.level = rsp->pomlvl; 3752 break; 3753 default: 3754 bfa_trc(sfp, rsp->event); 3755 WARN_ON(1); 3756 } 3757 3758 /* Send the AEN notification */ 3759 bfad_im_post_vendor_event(aen_entry, bfad, ++sfp->ioc->ioc_aen_seq, 3760 BFA_AEN_CAT_PORT, aen_evt); 3761 } 3762 3763 /* 3764 * SFP get data send 3765 */ 3766 static void 3767 bfa_sfp_getdata_send(struct bfa_sfp_s *sfp) 3768 { 3769 struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg; 3770 3771 bfa_trc(sfp, req->memtype); 3772 3773 /* build host command */ 3774 bfi_h2i_set(req->mh, BFI_MC_SFP, BFI_SFP_H2I_SHOW, 3775 bfa_ioc_portid(sfp->ioc)); 3776 3777 /* send mbox cmd */ 3778 bfa_ioc_mbox_queue(sfp->ioc, &sfp->mbcmd); 3779 } 3780 3781 /* 3782 * SFP is valid, read sfp data 3783 */ 3784 static void 3785 bfa_sfp_getdata(struct bfa_sfp_s *sfp, enum bfi_sfp_mem_e memtype) 3786 { 3787 struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg; 3788 3789 WARN_ON(sfp->lock != 0); 3790 bfa_trc(sfp, sfp->state); 3791 3792 sfp->lock = 1; 3793 sfp->memtype = memtype; 3794 req->memtype = memtype; 3795 3796 /* Setup SG list */ 3797 bfa_alen_set(&req->alen, sizeof(struct sfp_mem_s), sfp->dbuf_pa); 3798 3799 bfa_sfp_getdata_send(sfp); 3800 } 3801 3802 /* 3803 * SFP scn handler 3804 */ 3805 static void 3806 bfa_sfp_scn(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg) 3807 { 3808 struct bfi_sfp_scn_s *rsp = (struct bfi_sfp_scn_s *) msg; 3809 3810 switch (rsp->event) { 3811 case BFA_SFP_SCN_INSERTED: 3812 sfp->state = BFA_SFP_STATE_INSERTED; 3813 sfp->data_valid = 0; 3814 bfa_sfp_scn_aen_post(sfp, rsp); 3815 break; 3816 case BFA_SFP_SCN_REMOVED: 3817 sfp->state = BFA_SFP_STATE_REMOVED; 3818 sfp->data_valid = 0; 3819 bfa_sfp_scn_aen_post(sfp, rsp); 3820 break; 3821 case BFA_SFP_SCN_FAILED: 3822 sfp->state = BFA_SFP_STATE_FAILED; 3823 sfp->data_valid = 0; 3824 bfa_sfp_scn_aen_post(sfp, rsp); 3825 break; 3826 case BFA_SFP_SCN_UNSUPPORT: 3827 sfp->state = BFA_SFP_STATE_UNSUPPORT; 3828 bfa_sfp_scn_aen_post(sfp, rsp); 3829 if (!sfp->lock) 3830 bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL); 3831 break; 3832 case BFA_SFP_SCN_POM: 3833 bfa_sfp_scn_aen_post(sfp, rsp); 3834 break; 3835 case BFA_SFP_SCN_VALID: 3836 sfp->state = BFA_SFP_STATE_VALID; 3837 if (!sfp->lock) 3838 bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL); 3839 break; 3840 default: 3841 bfa_trc(sfp, rsp->event); 3842 WARN_ON(1); 3843 } 3844 } 3845 3846 /* 3847 * SFP show complete 3848 */ 3849 static void 3850 bfa_sfp_show_comp(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg) 3851 { 3852 struct bfi_sfp_rsp_s *rsp = (struct bfi_sfp_rsp_s *) msg; 3853 3854 if (!sfp->lock) { 3855 /* 3856 * receiving response after ioc failure 3857 */ 3858 bfa_trc(sfp, sfp->lock); 3859 return; 3860 } 3861 3862 bfa_trc(sfp, rsp->status); 3863 if (rsp->status == BFA_STATUS_OK) { 3864 sfp->data_valid = 1; 3865 if (sfp->state == BFA_SFP_STATE_VALID) 3866 sfp->status = BFA_STATUS_OK; 3867 else if (sfp->state == BFA_SFP_STATE_UNSUPPORT) 3868 sfp->status = BFA_STATUS_SFP_UNSUPP; 3869 else 3870 bfa_trc(sfp, sfp->state); 3871 } else { 3872 sfp->data_valid = 0; 3873 sfp->status = rsp->status; 3874 /* sfpshow shouldn't change sfp state */ 3875 } 3876 3877 bfa_trc(sfp, sfp->memtype); 3878 if (sfp->memtype == BFI_SFP_MEM_DIAGEXT) { 3879 bfa_trc(sfp, sfp->data_valid); 3880 if (sfp->data_valid) { 3881 u32 size = sizeof(struct sfp_mem_s); 3882 u8 *des = (u8 *)(sfp->sfpmem); 3883 memcpy(des, sfp->dbuf_kva, size); 3884 } 3885 /* 3886 * Queue completion callback. 3887 */ 3888 bfa_cb_sfp_show(sfp); 3889 } else 3890 sfp->lock = 0; 3891 3892 bfa_trc(sfp, sfp->state_query_lock); 3893 if (sfp->state_query_lock) { 3894 sfp->state = rsp->state; 3895 /* Complete callback */ 3896 bfa_cb_sfp_state_query(sfp); 3897 } 3898 } 3899 3900 /* 3901 * SFP query fw sfp state 3902 */ 3903 static void 3904 bfa_sfp_state_query(struct bfa_sfp_s *sfp) 3905 { 3906 struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg; 3907 3908 /* Should not be doing query if not in _INIT state */ 3909 WARN_ON(sfp->state != BFA_SFP_STATE_INIT); 3910 WARN_ON(sfp->state_query_lock != 0); 3911 bfa_trc(sfp, sfp->state); 3912 3913 sfp->state_query_lock = 1; 3914 req->memtype = 0; 3915 3916 if (!sfp->lock) 3917 bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL); 3918 } 3919 3920 static void 3921 bfa_sfp_media_get(struct bfa_sfp_s *sfp) 3922 { 3923 enum bfa_defs_sfp_media_e *media = sfp->media; 3924 3925 *media = BFA_SFP_MEDIA_UNKNOWN; 3926 3927 if (sfp->state == BFA_SFP_STATE_UNSUPPORT) 3928 *media = BFA_SFP_MEDIA_UNSUPPORT; 3929 else if (sfp->state == BFA_SFP_STATE_VALID) { 3930 union sfp_xcvr_e10g_code_u e10g; 3931 struct sfp_mem_s *sfpmem = (struct sfp_mem_s *)sfp->dbuf_kva; 3932 u16 xmtr_tech = (sfpmem->srlid_base.xcvr[4] & 0x3) << 7 | 3933 (sfpmem->srlid_base.xcvr[5] >> 1); 3934 3935 e10g.b = sfpmem->srlid_base.xcvr[0]; 3936 bfa_trc(sfp, e10g.b); 3937 bfa_trc(sfp, xmtr_tech); 3938 /* check fc transmitter tech */ 3939 if ((xmtr_tech & SFP_XMTR_TECH_CU) || 3940 (xmtr_tech & SFP_XMTR_TECH_CP) || 3941 (xmtr_tech & SFP_XMTR_TECH_CA)) 3942 *media = BFA_SFP_MEDIA_CU; 3943 else if ((xmtr_tech & SFP_XMTR_TECH_EL_INTRA) || 3944 (xmtr_tech & SFP_XMTR_TECH_EL_INTER)) 3945 *media = BFA_SFP_MEDIA_EL; 3946 else if ((xmtr_tech & SFP_XMTR_TECH_LL) || 3947 (xmtr_tech & SFP_XMTR_TECH_LC)) 3948 *media = BFA_SFP_MEDIA_LW; 3949 else if ((xmtr_tech & SFP_XMTR_TECH_SL) || 3950 (xmtr_tech & SFP_XMTR_TECH_SN) || 3951 (xmtr_tech & SFP_XMTR_TECH_SA)) 3952 *media = BFA_SFP_MEDIA_SW; 3953 /* Check 10G Ethernet Compilance code */ 3954 else if (e10g.r.e10g_sr) 3955 *media = BFA_SFP_MEDIA_SW; 3956 else if (e10g.r.e10g_lrm && e10g.r.e10g_lr) 3957 *media = BFA_SFP_MEDIA_LW; 3958 else if (e10g.r.e10g_unall) 3959 *media = BFA_SFP_MEDIA_UNKNOWN; 3960 else 3961 bfa_trc(sfp, 0); 3962 } else 3963 bfa_trc(sfp, sfp->state); 3964 } 3965 3966 static bfa_status_t 3967 bfa_sfp_speed_valid(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed) 3968 { 3969 struct sfp_mem_s *sfpmem = (struct sfp_mem_s *)sfp->dbuf_kva; 3970 struct sfp_xcvr_s *xcvr = (struct sfp_xcvr_s *) sfpmem->srlid_base.xcvr; 3971 union sfp_xcvr_fc3_code_u fc3 = xcvr->fc3; 3972 union sfp_xcvr_e10g_code_u e10g = xcvr->e10g; 3973 3974 if (portspeed == BFA_PORT_SPEED_10GBPS) { 3975 if (e10g.r.e10g_sr || e10g.r.e10g_lr) 3976 return BFA_STATUS_OK; 3977 else { 3978 bfa_trc(sfp, e10g.b); 3979 return BFA_STATUS_UNSUPP_SPEED; 3980 } 3981 } 3982 if (((portspeed & BFA_PORT_SPEED_16GBPS) && fc3.r.mb1600) || 3983 ((portspeed & BFA_PORT_SPEED_8GBPS) && fc3.r.mb800) || 3984 ((portspeed & BFA_PORT_SPEED_4GBPS) && fc3.r.mb400) || 3985 ((portspeed & BFA_PORT_SPEED_2GBPS) && fc3.r.mb200) || 3986 ((portspeed & BFA_PORT_SPEED_1GBPS) && fc3.r.mb100)) 3987 return BFA_STATUS_OK; 3988 else { 3989 bfa_trc(sfp, portspeed); 3990 bfa_trc(sfp, fc3.b); 3991 bfa_trc(sfp, e10g.b); 3992 return BFA_STATUS_UNSUPP_SPEED; 3993 } 3994 } 3995 3996 /* 3997 * SFP hmbox handler 3998 */ 3999 void 4000 bfa_sfp_intr(void *sfparg, struct bfi_mbmsg_s *msg) 4001 { 4002 struct bfa_sfp_s *sfp = sfparg; 4003 4004 switch (msg->mh.msg_id) { 4005 case BFI_SFP_I2H_SHOW: 4006 bfa_sfp_show_comp(sfp, msg); 4007 break; 4008 4009 case BFI_SFP_I2H_SCN: 4010 bfa_sfp_scn(sfp, msg); 4011 break; 4012 4013 default: 4014 bfa_trc(sfp, msg->mh.msg_id); 4015 WARN_ON(1); 4016 } 4017 } 4018 4019 /* 4020 * Return DMA memory needed by sfp module. 4021 */ 4022 u32 4023 bfa_sfp_meminfo(void) 4024 { 4025 return BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ); 4026 } 4027 4028 /* 4029 * Attach virtual and physical memory for SFP. 4030 */ 4031 void 4032 bfa_sfp_attach(struct bfa_sfp_s *sfp, struct bfa_ioc_s *ioc, void *dev, 4033 struct bfa_trc_mod_s *trcmod) 4034 { 4035 sfp->dev = dev; 4036 sfp->ioc = ioc; 4037 sfp->trcmod = trcmod; 4038 4039 sfp->cbfn = NULL; 4040 sfp->cbarg = NULL; 4041 sfp->sfpmem = NULL; 4042 sfp->lock = 0; 4043 sfp->data_valid = 0; 4044 sfp->state = BFA_SFP_STATE_INIT; 4045 sfp->state_query_lock = 0; 4046 sfp->state_query_cbfn = NULL; 4047 sfp->state_query_cbarg = NULL; 4048 sfp->media = NULL; 4049 sfp->portspeed = BFA_PORT_SPEED_UNKNOWN; 4050 sfp->is_elb = BFA_FALSE; 4051 4052 bfa_ioc_mbox_regisr(sfp->ioc, BFI_MC_SFP, bfa_sfp_intr, sfp); 4053 bfa_q_qe_init(&sfp->ioc_notify); 4054 bfa_ioc_notify_init(&sfp->ioc_notify, bfa_sfp_notify, sfp); 4055 list_add_tail(&sfp->ioc_notify.qe, &sfp->ioc->notify_q); 4056 } 4057 4058 /* 4059 * Claim Memory for SFP 4060 */ 4061 void 4062 bfa_sfp_memclaim(struct bfa_sfp_s *sfp, u8 *dm_kva, u64 dm_pa) 4063 { 4064 sfp->dbuf_kva = dm_kva; 4065 sfp->dbuf_pa = dm_pa; 4066 memset(sfp->dbuf_kva, 0, sizeof(struct sfp_mem_s)); 4067 4068 dm_kva += BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ); 4069 dm_pa += BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ); 4070 } 4071 4072 /* 4073 * Show SFP eeprom content 4074 * 4075 * @param[in] sfp - bfa sfp module 4076 * 4077 * @param[out] sfpmem - sfp eeprom data 4078 * 4079 */ 4080 bfa_status_t 4081 bfa_sfp_show(struct bfa_sfp_s *sfp, struct sfp_mem_s *sfpmem, 4082 bfa_cb_sfp_t cbfn, void *cbarg) 4083 { 4084 4085 if (!bfa_ioc_is_operational(sfp->ioc)) { 4086 bfa_trc(sfp, 0); 4087 return BFA_STATUS_IOC_NON_OP; 4088 } 4089 4090 if (sfp->lock) { 4091 bfa_trc(sfp, 0); 4092 return BFA_STATUS_DEVBUSY; 4093 } 4094 4095 sfp->cbfn = cbfn; 4096 sfp->cbarg = cbarg; 4097 sfp->sfpmem = sfpmem; 4098 4099 bfa_sfp_getdata(sfp, BFI_SFP_MEM_DIAGEXT); 4100 return BFA_STATUS_OK; 4101 } 4102 4103 /* 4104 * Return SFP Media type 4105 * 4106 * @param[in] sfp - bfa sfp module 4107 * 4108 * @param[out] media - port speed from user 4109 * 4110 */ 4111 bfa_status_t 4112 bfa_sfp_media(struct bfa_sfp_s *sfp, enum bfa_defs_sfp_media_e *media, 4113 bfa_cb_sfp_t cbfn, void *cbarg) 4114 { 4115 if (!bfa_ioc_is_operational(sfp->ioc)) { 4116 bfa_trc(sfp, 0); 4117 return BFA_STATUS_IOC_NON_OP; 4118 } 4119 4120 sfp->media = media; 4121 if (sfp->state == BFA_SFP_STATE_INIT) { 4122 if (sfp->state_query_lock) { 4123 bfa_trc(sfp, 0); 4124 return BFA_STATUS_DEVBUSY; 4125 } else { 4126 sfp->state_query_cbfn = cbfn; 4127 sfp->state_query_cbarg = cbarg; 4128 bfa_sfp_state_query(sfp); 4129 return BFA_STATUS_SFP_NOT_READY; 4130 } 4131 } 4132 4133 bfa_sfp_media_get(sfp); 4134 return BFA_STATUS_OK; 4135 } 4136 4137 /* 4138 * Check if user set port speed is allowed by the SFP 4139 * 4140 * @param[in] sfp - bfa sfp module 4141 * @param[in] portspeed - port speed from user 4142 * 4143 */ 4144 bfa_status_t 4145 bfa_sfp_speed(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed, 4146 bfa_cb_sfp_t cbfn, void *cbarg) 4147 { 4148 WARN_ON(portspeed == BFA_PORT_SPEED_UNKNOWN); 4149 4150 if (!bfa_ioc_is_operational(sfp->ioc)) 4151 return BFA_STATUS_IOC_NON_OP; 4152 4153 /* For Mezz card, all speed is allowed */ 4154 if (bfa_mfg_is_mezz(sfp->ioc->attr->card_type)) 4155 return BFA_STATUS_OK; 4156 4157 /* Check SFP state */ 4158 sfp->portspeed = portspeed; 4159 if (sfp->state == BFA_SFP_STATE_INIT) { 4160 if (sfp->state_query_lock) { 4161 bfa_trc(sfp, 0); 4162 return BFA_STATUS_DEVBUSY; 4163 } else { 4164 sfp->state_query_cbfn = cbfn; 4165 sfp->state_query_cbarg = cbarg; 4166 bfa_sfp_state_query(sfp); 4167 return BFA_STATUS_SFP_NOT_READY; 4168 } 4169 } 4170 4171 if (sfp->state == BFA_SFP_STATE_REMOVED || 4172 sfp->state == BFA_SFP_STATE_FAILED) { 4173 bfa_trc(sfp, sfp->state); 4174 return BFA_STATUS_NO_SFP_DEV; 4175 } 4176 4177 if (sfp->state == BFA_SFP_STATE_INSERTED) { 4178 bfa_trc(sfp, sfp->state); 4179 return BFA_STATUS_DEVBUSY; /* sfp is reading data */ 4180 } 4181 4182 /* For eloopback, all speed is allowed */ 4183 if (sfp->is_elb) 4184 return BFA_STATUS_OK; 4185 4186 return bfa_sfp_speed_valid(sfp, portspeed); 4187 } 4188 4189 /* 4190 * Flash module specific 4191 */ 4192 4193 /* 4194 * FLASH DMA buffer should be big enough to hold both MFG block and 4195 * asic block(64k) at the same time and also should be 2k aligned to 4196 * avoid write segement to cross sector boundary. 4197 */ 4198 #define BFA_FLASH_SEG_SZ 2048 4199 #define BFA_FLASH_DMA_BUF_SZ \ 4200 BFA_ROUNDUP(0x010000 + sizeof(struct bfa_mfg_block_s), BFA_FLASH_SEG_SZ) 4201 4202 static void 4203 bfa_flash_aen_audit_post(struct bfa_ioc_s *ioc, enum bfa_audit_aen_event event, 4204 int inst, int type) 4205 { 4206 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 4207 struct bfa_aen_entry_s *aen_entry; 4208 4209 bfad_get_aen_entry(bfad, aen_entry); 4210 if (!aen_entry) 4211 return; 4212 4213 aen_entry->aen_data.audit.pwwn = ioc->attr->pwwn; 4214 aen_entry->aen_data.audit.partition_inst = inst; 4215 aen_entry->aen_data.audit.partition_type = type; 4216 4217 /* Send the AEN notification */ 4218 bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq, 4219 BFA_AEN_CAT_AUDIT, event); 4220 } 4221 4222 static void 4223 bfa_flash_cb(struct bfa_flash_s *flash) 4224 { 4225 flash->op_busy = 0; 4226 if (flash->cbfn) 4227 flash->cbfn(flash->cbarg, flash->status); 4228 } 4229 4230 static void 4231 bfa_flash_notify(void *cbarg, enum bfa_ioc_event_e event) 4232 { 4233 struct bfa_flash_s *flash = cbarg; 4234 4235 bfa_trc(flash, event); 4236 switch (event) { 4237 case BFA_IOC_E_DISABLED: 4238 case BFA_IOC_E_FAILED: 4239 if (flash->op_busy) { 4240 flash->status = BFA_STATUS_IOC_FAILURE; 4241 flash->cbfn(flash->cbarg, flash->status); 4242 flash->op_busy = 0; 4243 } 4244 break; 4245 4246 default: 4247 break; 4248 } 4249 } 4250 4251 /* 4252 * Send flash attribute query request. 4253 * 4254 * @param[in] cbarg - callback argument 4255 */ 4256 static void 4257 bfa_flash_query_send(void *cbarg) 4258 { 4259 struct bfa_flash_s *flash = cbarg; 4260 struct bfi_flash_query_req_s *msg = 4261 (struct bfi_flash_query_req_s *) flash->mb.msg; 4262 4263 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_QUERY_REQ, 4264 bfa_ioc_portid(flash->ioc)); 4265 bfa_alen_set(&msg->alen, sizeof(struct bfa_flash_attr_s), 4266 flash->dbuf_pa); 4267 bfa_ioc_mbox_queue(flash->ioc, &flash->mb); 4268 } 4269 4270 /* 4271 * Send flash write request. 4272 * 4273 * @param[in] cbarg - callback argument 4274 */ 4275 static void 4276 bfa_flash_write_send(struct bfa_flash_s *flash) 4277 { 4278 struct bfi_flash_write_req_s *msg = 4279 (struct bfi_flash_write_req_s *) flash->mb.msg; 4280 u32 len; 4281 4282 msg->type = be32_to_cpu(flash->type); 4283 msg->instance = flash->instance; 4284 msg->offset = be32_to_cpu(flash->addr_off + flash->offset); 4285 len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ? 4286 flash->residue : BFA_FLASH_DMA_BUF_SZ; 4287 msg->length = be32_to_cpu(len); 4288 4289 /* indicate if it's the last msg of the whole write operation */ 4290 msg->last = (len == flash->residue) ? 1 : 0; 4291 4292 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_WRITE_REQ, 4293 bfa_ioc_portid(flash->ioc)); 4294 bfa_alen_set(&msg->alen, len, flash->dbuf_pa); 4295 memcpy(flash->dbuf_kva, flash->ubuf + flash->offset, len); 4296 bfa_ioc_mbox_queue(flash->ioc, &flash->mb); 4297 4298 flash->residue -= len; 4299 flash->offset += len; 4300 } 4301 4302 /* 4303 * Send flash read request. 4304 * 4305 * @param[in] cbarg - callback argument 4306 */ 4307 static void 4308 bfa_flash_read_send(void *cbarg) 4309 { 4310 struct bfa_flash_s *flash = cbarg; 4311 struct bfi_flash_read_req_s *msg = 4312 (struct bfi_flash_read_req_s *) flash->mb.msg; 4313 u32 len; 4314 4315 msg->type = be32_to_cpu(flash->type); 4316 msg->instance = flash->instance; 4317 msg->offset = be32_to_cpu(flash->addr_off + flash->offset); 4318 len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ? 4319 flash->residue : BFA_FLASH_DMA_BUF_SZ; 4320 msg->length = be32_to_cpu(len); 4321 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_READ_REQ, 4322 bfa_ioc_portid(flash->ioc)); 4323 bfa_alen_set(&msg->alen, len, flash->dbuf_pa); 4324 bfa_ioc_mbox_queue(flash->ioc, &flash->mb); 4325 } 4326 4327 /* 4328 * Send flash erase request. 4329 * 4330 * @param[in] cbarg - callback argument 4331 */ 4332 static void 4333 bfa_flash_erase_send(void *cbarg) 4334 { 4335 struct bfa_flash_s *flash = cbarg; 4336 struct bfi_flash_erase_req_s *msg = 4337 (struct bfi_flash_erase_req_s *) flash->mb.msg; 4338 4339 msg->type = be32_to_cpu(flash->type); 4340 msg->instance = flash->instance; 4341 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_ERASE_REQ, 4342 bfa_ioc_portid(flash->ioc)); 4343 bfa_ioc_mbox_queue(flash->ioc, &flash->mb); 4344 } 4345 4346 /* 4347 * Process flash response messages upon receiving interrupts. 4348 * 4349 * @param[in] flasharg - flash structure 4350 * @param[in] msg - message structure 4351 */ 4352 static void 4353 bfa_flash_intr(void *flasharg, struct bfi_mbmsg_s *msg) 4354 { 4355 struct bfa_flash_s *flash = flasharg; 4356 u32 status; 4357 4358 union { 4359 struct bfi_flash_query_rsp_s *query; 4360 struct bfi_flash_erase_rsp_s *erase; 4361 struct bfi_flash_write_rsp_s *write; 4362 struct bfi_flash_read_rsp_s *read; 4363 struct bfi_flash_event_s *event; 4364 struct bfi_mbmsg_s *msg; 4365 } m; 4366 4367 m.msg = msg; 4368 bfa_trc(flash, msg->mh.msg_id); 4369 4370 if (!flash->op_busy && msg->mh.msg_id != BFI_FLASH_I2H_EVENT) { 4371 /* receiving response after ioc failure */ 4372 bfa_trc(flash, 0x9999); 4373 return; 4374 } 4375 4376 switch (msg->mh.msg_id) { 4377 case BFI_FLASH_I2H_QUERY_RSP: 4378 status = be32_to_cpu(m.query->status); 4379 bfa_trc(flash, status); 4380 if (status == BFA_STATUS_OK) { 4381 u32 i; 4382 struct bfa_flash_attr_s *attr, *f; 4383 4384 attr = (struct bfa_flash_attr_s *) flash->ubuf; 4385 f = (struct bfa_flash_attr_s *) flash->dbuf_kva; 4386 attr->status = be32_to_cpu(f->status); 4387 attr->npart = be32_to_cpu(f->npart); 4388 bfa_trc(flash, attr->status); 4389 bfa_trc(flash, attr->npart); 4390 for (i = 0; i < attr->npart; i++) { 4391 attr->part[i].part_type = 4392 be32_to_cpu(f->part[i].part_type); 4393 attr->part[i].part_instance = 4394 be32_to_cpu(f->part[i].part_instance); 4395 attr->part[i].part_off = 4396 be32_to_cpu(f->part[i].part_off); 4397 attr->part[i].part_size = 4398 be32_to_cpu(f->part[i].part_size); 4399 attr->part[i].part_len = 4400 be32_to_cpu(f->part[i].part_len); 4401 attr->part[i].part_status = 4402 be32_to_cpu(f->part[i].part_status); 4403 } 4404 } 4405 flash->status = status; 4406 bfa_flash_cb(flash); 4407 break; 4408 case BFI_FLASH_I2H_ERASE_RSP: 4409 status = be32_to_cpu(m.erase->status); 4410 bfa_trc(flash, status); 4411 flash->status = status; 4412 bfa_flash_cb(flash); 4413 break; 4414 case BFI_FLASH_I2H_WRITE_RSP: 4415 status = be32_to_cpu(m.write->status); 4416 bfa_trc(flash, status); 4417 if (status != BFA_STATUS_OK || flash->residue == 0) { 4418 flash->status = status; 4419 bfa_flash_cb(flash); 4420 } else { 4421 bfa_trc(flash, flash->offset); 4422 bfa_flash_write_send(flash); 4423 } 4424 break; 4425 case BFI_FLASH_I2H_READ_RSP: 4426 status = be32_to_cpu(m.read->status); 4427 bfa_trc(flash, status); 4428 if (status != BFA_STATUS_OK) { 4429 flash->status = status; 4430 bfa_flash_cb(flash); 4431 } else { 4432 u32 len = be32_to_cpu(m.read->length); 4433 bfa_trc(flash, flash->offset); 4434 bfa_trc(flash, len); 4435 memcpy(flash->ubuf + flash->offset, 4436 flash->dbuf_kva, len); 4437 flash->residue -= len; 4438 flash->offset += len; 4439 if (flash->residue == 0) { 4440 flash->status = status; 4441 bfa_flash_cb(flash); 4442 } else 4443 bfa_flash_read_send(flash); 4444 } 4445 break; 4446 case BFI_FLASH_I2H_BOOT_VER_RSP: 4447 break; 4448 case BFI_FLASH_I2H_EVENT: 4449 status = be32_to_cpu(m.event->status); 4450 bfa_trc(flash, status); 4451 if (status == BFA_STATUS_BAD_FWCFG) 4452 bfa_ioc_aen_post(flash->ioc, BFA_IOC_AEN_FWCFG_ERROR); 4453 else if (status == BFA_STATUS_INVALID_VENDOR) { 4454 u32 param; 4455 param = be32_to_cpu(m.event->param); 4456 bfa_trc(flash, param); 4457 bfa_ioc_aen_post(flash->ioc, 4458 BFA_IOC_AEN_INVALID_VENDOR); 4459 } 4460 break; 4461 4462 default: 4463 WARN_ON(1); 4464 } 4465 } 4466 4467 /* 4468 * Flash memory info API. 4469 * 4470 * @param[in] mincfg - minimal cfg variable 4471 */ 4472 u32 4473 bfa_flash_meminfo(bfa_boolean_t mincfg) 4474 { 4475 /* min driver doesn't need flash */ 4476 if (mincfg) 4477 return 0; 4478 return BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 4479 } 4480 4481 /* 4482 * Flash attach API. 4483 * 4484 * @param[in] flash - flash structure 4485 * @param[in] ioc - ioc structure 4486 * @param[in] dev - device structure 4487 * @param[in] trcmod - trace module 4488 * @param[in] logmod - log module 4489 */ 4490 void 4491 bfa_flash_attach(struct bfa_flash_s *flash, struct bfa_ioc_s *ioc, void *dev, 4492 struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg) 4493 { 4494 flash->ioc = ioc; 4495 flash->trcmod = trcmod; 4496 flash->cbfn = NULL; 4497 flash->cbarg = NULL; 4498 flash->op_busy = 0; 4499 4500 bfa_ioc_mbox_regisr(flash->ioc, BFI_MC_FLASH, bfa_flash_intr, flash); 4501 bfa_q_qe_init(&flash->ioc_notify); 4502 bfa_ioc_notify_init(&flash->ioc_notify, bfa_flash_notify, flash); 4503 list_add_tail(&flash->ioc_notify.qe, &flash->ioc->notify_q); 4504 4505 /* min driver doesn't need flash */ 4506 if (mincfg) { 4507 flash->dbuf_kva = NULL; 4508 flash->dbuf_pa = 0; 4509 } 4510 } 4511 4512 /* 4513 * Claim memory for flash 4514 * 4515 * @param[in] flash - flash structure 4516 * @param[in] dm_kva - pointer to virtual memory address 4517 * @param[in] dm_pa - physical memory address 4518 * @param[in] mincfg - minimal cfg variable 4519 */ 4520 void 4521 bfa_flash_memclaim(struct bfa_flash_s *flash, u8 *dm_kva, u64 dm_pa, 4522 bfa_boolean_t mincfg) 4523 { 4524 if (mincfg) 4525 return; 4526 4527 flash->dbuf_kva = dm_kva; 4528 flash->dbuf_pa = dm_pa; 4529 memset(flash->dbuf_kva, 0, BFA_FLASH_DMA_BUF_SZ); 4530 dm_kva += BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 4531 dm_pa += BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 4532 } 4533 4534 /* 4535 * Get flash attribute. 4536 * 4537 * @param[in] flash - flash structure 4538 * @param[in] attr - flash attribute structure 4539 * @param[in] cbfn - callback function 4540 * @param[in] cbarg - callback argument 4541 * 4542 * Return status. 4543 */ 4544 bfa_status_t 4545 bfa_flash_get_attr(struct bfa_flash_s *flash, struct bfa_flash_attr_s *attr, 4546 bfa_cb_flash_t cbfn, void *cbarg) 4547 { 4548 bfa_trc(flash, BFI_FLASH_H2I_QUERY_REQ); 4549 4550 if (!bfa_ioc_is_operational(flash->ioc)) 4551 return BFA_STATUS_IOC_NON_OP; 4552 4553 if (flash->op_busy) { 4554 bfa_trc(flash, flash->op_busy); 4555 return BFA_STATUS_DEVBUSY; 4556 } 4557 4558 flash->op_busy = 1; 4559 flash->cbfn = cbfn; 4560 flash->cbarg = cbarg; 4561 flash->ubuf = (u8 *) attr; 4562 bfa_flash_query_send(flash); 4563 4564 return BFA_STATUS_OK; 4565 } 4566 4567 /* 4568 * Erase flash partition. 4569 * 4570 * @param[in] flash - flash structure 4571 * @param[in] type - flash partition type 4572 * @param[in] instance - flash partition instance 4573 * @param[in] cbfn - callback function 4574 * @param[in] cbarg - callback argument 4575 * 4576 * Return status. 4577 */ 4578 bfa_status_t 4579 bfa_flash_erase_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type, 4580 u8 instance, bfa_cb_flash_t cbfn, void *cbarg) 4581 { 4582 bfa_trc(flash, BFI_FLASH_H2I_ERASE_REQ); 4583 bfa_trc(flash, type); 4584 bfa_trc(flash, instance); 4585 4586 if (!bfa_ioc_is_operational(flash->ioc)) 4587 return BFA_STATUS_IOC_NON_OP; 4588 4589 if (flash->op_busy) { 4590 bfa_trc(flash, flash->op_busy); 4591 return BFA_STATUS_DEVBUSY; 4592 } 4593 4594 flash->op_busy = 1; 4595 flash->cbfn = cbfn; 4596 flash->cbarg = cbarg; 4597 flash->type = type; 4598 flash->instance = instance; 4599 4600 bfa_flash_erase_send(flash); 4601 bfa_flash_aen_audit_post(flash->ioc, BFA_AUDIT_AEN_FLASH_ERASE, 4602 instance, type); 4603 return BFA_STATUS_OK; 4604 } 4605 4606 /* 4607 * Update flash partition. 4608 * 4609 * @param[in] flash - flash structure 4610 * @param[in] type - flash partition type 4611 * @param[in] instance - flash partition instance 4612 * @param[in] buf - update data buffer 4613 * @param[in] len - data buffer length 4614 * @param[in] offset - offset relative to the partition starting address 4615 * @param[in] cbfn - callback function 4616 * @param[in] cbarg - callback argument 4617 * 4618 * Return status. 4619 */ 4620 bfa_status_t 4621 bfa_flash_update_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type, 4622 u8 instance, void *buf, u32 len, u32 offset, 4623 bfa_cb_flash_t cbfn, void *cbarg) 4624 { 4625 bfa_trc(flash, BFI_FLASH_H2I_WRITE_REQ); 4626 bfa_trc(flash, type); 4627 bfa_trc(flash, instance); 4628 bfa_trc(flash, len); 4629 bfa_trc(flash, offset); 4630 4631 if (!bfa_ioc_is_operational(flash->ioc)) 4632 return BFA_STATUS_IOC_NON_OP; 4633 4634 /* 4635 * 'len' must be in word (4-byte) boundary 4636 * 'offset' must be in sector (16kb) boundary 4637 */ 4638 if (!len || (len & 0x03) || (offset & 0x00003FFF)) 4639 return BFA_STATUS_FLASH_BAD_LEN; 4640 4641 if (type == BFA_FLASH_PART_MFG) 4642 return BFA_STATUS_EINVAL; 4643 4644 if (flash->op_busy) { 4645 bfa_trc(flash, flash->op_busy); 4646 return BFA_STATUS_DEVBUSY; 4647 } 4648 4649 flash->op_busy = 1; 4650 flash->cbfn = cbfn; 4651 flash->cbarg = cbarg; 4652 flash->type = type; 4653 flash->instance = instance; 4654 flash->residue = len; 4655 flash->offset = 0; 4656 flash->addr_off = offset; 4657 flash->ubuf = buf; 4658 4659 bfa_flash_write_send(flash); 4660 return BFA_STATUS_OK; 4661 } 4662 4663 /* 4664 * Read flash partition. 4665 * 4666 * @param[in] flash - flash structure 4667 * @param[in] type - flash partition type 4668 * @param[in] instance - flash partition instance 4669 * @param[in] buf - read data buffer 4670 * @param[in] len - data buffer length 4671 * @param[in] offset - offset relative to the partition starting address 4672 * @param[in] cbfn - callback function 4673 * @param[in] cbarg - callback argument 4674 * 4675 * Return status. 4676 */ 4677 bfa_status_t 4678 bfa_flash_read_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type, 4679 u8 instance, void *buf, u32 len, u32 offset, 4680 bfa_cb_flash_t cbfn, void *cbarg) 4681 { 4682 bfa_trc(flash, BFI_FLASH_H2I_READ_REQ); 4683 bfa_trc(flash, type); 4684 bfa_trc(flash, instance); 4685 bfa_trc(flash, len); 4686 bfa_trc(flash, offset); 4687 4688 if (!bfa_ioc_is_operational(flash->ioc)) 4689 return BFA_STATUS_IOC_NON_OP; 4690 4691 /* 4692 * 'len' must be in word (4-byte) boundary 4693 * 'offset' must be in sector (16kb) boundary 4694 */ 4695 if (!len || (len & 0x03) || (offset & 0x00003FFF)) 4696 return BFA_STATUS_FLASH_BAD_LEN; 4697 4698 if (flash->op_busy) { 4699 bfa_trc(flash, flash->op_busy); 4700 return BFA_STATUS_DEVBUSY; 4701 } 4702 4703 flash->op_busy = 1; 4704 flash->cbfn = cbfn; 4705 flash->cbarg = cbarg; 4706 flash->type = type; 4707 flash->instance = instance; 4708 flash->residue = len; 4709 flash->offset = 0; 4710 flash->addr_off = offset; 4711 flash->ubuf = buf; 4712 bfa_flash_read_send(flash); 4713 4714 return BFA_STATUS_OK; 4715 } 4716 4717 /* 4718 * DIAG module specific 4719 */ 4720 4721 #define BFA_DIAG_MEMTEST_TOV 50000 /* memtest timeout in msec */ 4722 #define CT2_BFA_DIAG_MEMTEST_TOV (9*30*1000) /* 4.5 min */ 4723 4724 /* IOC event handler */ 4725 static void 4726 bfa_diag_notify(void *diag_arg, enum bfa_ioc_event_e event) 4727 { 4728 struct bfa_diag_s *diag = diag_arg; 4729 4730 bfa_trc(diag, event); 4731 bfa_trc(diag, diag->block); 4732 bfa_trc(diag, diag->fwping.lock); 4733 bfa_trc(diag, diag->tsensor.lock); 4734 4735 switch (event) { 4736 case BFA_IOC_E_DISABLED: 4737 case BFA_IOC_E_FAILED: 4738 if (diag->fwping.lock) { 4739 diag->fwping.status = BFA_STATUS_IOC_FAILURE; 4740 diag->fwping.cbfn(diag->fwping.cbarg, 4741 diag->fwping.status); 4742 diag->fwping.lock = 0; 4743 } 4744 4745 if (diag->tsensor.lock) { 4746 diag->tsensor.status = BFA_STATUS_IOC_FAILURE; 4747 diag->tsensor.cbfn(diag->tsensor.cbarg, 4748 diag->tsensor.status); 4749 diag->tsensor.lock = 0; 4750 } 4751 4752 if (diag->block) { 4753 if (diag->timer_active) { 4754 bfa_timer_stop(&diag->timer); 4755 diag->timer_active = 0; 4756 } 4757 4758 diag->status = BFA_STATUS_IOC_FAILURE; 4759 diag->cbfn(diag->cbarg, diag->status); 4760 diag->block = 0; 4761 } 4762 break; 4763 4764 default: 4765 break; 4766 } 4767 } 4768 4769 static void 4770 bfa_diag_memtest_done(void *cbarg) 4771 { 4772 struct bfa_diag_s *diag = cbarg; 4773 struct bfa_ioc_s *ioc = diag->ioc; 4774 struct bfa_diag_memtest_result *res = diag->result; 4775 u32 loff = BFI_BOOT_MEMTEST_RES_ADDR; 4776 u32 pgnum, pgoff, i; 4777 4778 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff); 4779 pgoff = PSS_SMEM_PGOFF(loff); 4780 4781 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 4782 4783 for (i = 0; i < (sizeof(struct bfa_diag_memtest_result) / 4784 sizeof(u32)); i++) { 4785 /* read test result from smem */ 4786 *((u32 *) res + i) = 4787 bfa_mem_read(ioc->ioc_regs.smem_page_start, loff); 4788 loff += sizeof(u32); 4789 } 4790 4791 /* Reset IOC fwstates to BFI_IOC_UNINIT */ 4792 bfa_ioc_reset_fwstate(ioc); 4793 4794 res->status = swab32(res->status); 4795 bfa_trc(diag, res->status); 4796 4797 if (res->status == BFI_BOOT_MEMTEST_RES_SIG) 4798 diag->status = BFA_STATUS_OK; 4799 else { 4800 diag->status = BFA_STATUS_MEMTEST_FAILED; 4801 res->addr = swab32(res->addr); 4802 res->exp = swab32(res->exp); 4803 res->act = swab32(res->act); 4804 res->err_status = swab32(res->err_status); 4805 res->err_status1 = swab32(res->err_status1); 4806 res->err_addr = swab32(res->err_addr); 4807 bfa_trc(diag, res->addr); 4808 bfa_trc(diag, res->exp); 4809 bfa_trc(diag, res->act); 4810 bfa_trc(diag, res->err_status); 4811 bfa_trc(diag, res->err_status1); 4812 bfa_trc(diag, res->err_addr); 4813 } 4814 diag->timer_active = 0; 4815 diag->cbfn(diag->cbarg, diag->status); 4816 diag->block = 0; 4817 } 4818 4819 /* 4820 * Firmware ping 4821 */ 4822 4823 /* 4824 * Perform DMA test directly 4825 */ 4826 static void 4827 diag_fwping_send(struct bfa_diag_s *diag) 4828 { 4829 struct bfi_diag_fwping_req_s *fwping_req; 4830 u32 i; 4831 4832 bfa_trc(diag, diag->fwping.dbuf_pa); 4833 4834 /* fill DMA area with pattern */ 4835 for (i = 0; i < (BFI_DIAG_DMA_BUF_SZ >> 2); i++) 4836 *((u32 *)diag->fwping.dbuf_kva + i) = diag->fwping.data; 4837 4838 /* Fill mbox msg */ 4839 fwping_req = (struct bfi_diag_fwping_req_s *)diag->fwping.mbcmd.msg; 4840 4841 /* Setup SG list */ 4842 bfa_alen_set(&fwping_req->alen, BFI_DIAG_DMA_BUF_SZ, 4843 diag->fwping.dbuf_pa); 4844 /* Set up dma count */ 4845 fwping_req->count = cpu_to_be32(diag->fwping.count); 4846 /* Set up data pattern */ 4847 fwping_req->data = diag->fwping.data; 4848 4849 /* build host command */ 4850 bfi_h2i_set(fwping_req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_FWPING, 4851 bfa_ioc_portid(diag->ioc)); 4852 4853 /* send mbox cmd */ 4854 bfa_ioc_mbox_queue(diag->ioc, &diag->fwping.mbcmd); 4855 } 4856 4857 static void 4858 diag_fwping_comp(struct bfa_diag_s *diag, 4859 struct bfi_diag_fwping_rsp_s *diag_rsp) 4860 { 4861 u32 rsp_data = diag_rsp->data; 4862 u8 rsp_dma_status = diag_rsp->dma_status; 4863 4864 bfa_trc(diag, rsp_data); 4865 bfa_trc(diag, rsp_dma_status); 4866 4867 if (rsp_dma_status == BFA_STATUS_OK) { 4868 u32 i, pat; 4869 pat = (diag->fwping.count & 0x1) ? ~(diag->fwping.data) : 4870 diag->fwping.data; 4871 /* Check mbox data */ 4872 if (diag->fwping.data != rsp_data) { 4873 bfa_trc(diag, rsp_data); 4874 diag->fwping.result->dmastatus = 4875 BFA_STATUS_DATACORRUPTED; 4876 diag->fwping.status = BFA_STATUS_DATACORRUPTED; 4877 diag->fwping.cbfn(diag->fwping.cbarg, 4878 diag->fwping.status); 4879 diag->fwping.lock = 0; 4880 return; 4881 } 4882 /* Check dma pattern */ 4883 for (i = 0; i < (BFI_DIAG_DMA_BUF_SZ >> 2); i++) { 4884 if (*((u32 *)diag->fwping.dbuf_kva + i) != pat) { 4885 bfa_trc(diag, i); 4886 bfa_trc(diag, pat); 4887 bfa_trc(diag, 4888 *((u32 *)diag->fwping.dbuf_kva + i)); 4889 diag->fwping.result->dmastatus = 4890 BFA_STATUS_DATACORRUPTED; 4891 diag->fwping.status = BFA_STATUS_DATACORRUPTED; 4892 diag->fwping.cbfn(diag->fwping.cbarg, 4893 diag->fwping.status); 4894 diag->fwping.lock = 0; 4895 return; 4896 } 4897 } 4898 diag->fwping.result->dmastatus = BFA_STATUS_OK; 4899 diag->fwping.status = BFA_STATUS_OK; 4900 diag->fwping.cbfn(diag->fwping.cbarg, diag->fwping.status); 4901 diag->fwping.lock = 0; 4902 } else { 4903 diag->fwping.status = BFA_STATUS_HDMA_FAILED; 4904 diag->fwping.cbfn(diag->fwping.cbarg, diag->fwping.status); 4905 diag->fwping.lock = 0; 4906 } 4907 } 4908 4909 /* 4910 * Temperature Sensor 4911 */ 4912 4913 static void 4914 diag_tempsensor_send(struct bfa_diag_s *diag) 4915 { 4916 struct bfi_diag_ts_req_s *msg; 4917 4918 msg = (struct bfi_diag_ts_req_s *)diag->tsensor.mbcmd.msg; 4919 bfa_trc(diag, msg->temp); 4920 /* build host command */ 4921 bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_TEMPSENSOR, 4922 bfa_ioc_portid(diag->ioc)); 4923 /* send mbox cmd */ 4924 bfa_ioc_mbox_queue(diag->ioc, &diag->tsensor.mbcmd); 4925 } 4926 4927 static void 4928 diag_tempsensor_comp(struct bfa_diag_s *diag, bfi_diag_ts_rsp_t *rsp) 4929 { 4930 if (!diag->tsensor.lock) { 4931 /* receiving response after ioc failure */ 4932 bfa_trc(diag, diag->tsensor.lock); 4933 return; 4934 } 4935 4936 /* 4937 * ASIC junction tempsensor is a reg read operation 4938 * it will always return OK 4939 */ 4940 diag->tsensor.temp->temp = be16_to_cpu(rsp->temp); 4941 diag->tsensor.temp->ts_junc = rsp->ts_junc; 4942 diag->tsensor.temp->ts_brd = rsp->ts_brd; 4943 4944 if (rsp->ts_brd) { 4945 /* tsensor.temp->status is brd_temp status */ 4946 diag->tsensor.temp->status = rsp->status; 4947 if (rsp->status == BFA_STATUS_OK) { 4948 diag->tsensor.temp->brd_temp = 4949 be16_to_cpu(rsp->brd_temp); 4950 } else 4951 diag->tsensor.temp->brd_temp = 0; 4952 } 4953 4954 bfa_trc(diag, rsp->status); 4955 bfa_trc(diag, rsp->ts_junc); 4956 bfa_trc(diag, rsp->temp); 4957 bfa_trc(diag, rsp->ts_brd); 4958 bfa_trc(diag, rsp->brd_temp); 4959 4960 /* tsensor status is always good bcos we always have junction temp */ 4961 diag->tsensor.status = BFA_STATUS_OK; 4962 diag->tsensor.cbfn(diag->tsensor.cbarg, diag->tsensor.status); 4963 diag->tsensor.lock = 0; 4964 } 4965 4966 /* 4967 * LED Test command 4968 */ 4969 static void 4970 diag_ledtest_send(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest) 4971 { 4972 struct bfi_diag_ledtest_req_s *msg; 4973 4974 msg = (struct bfi_diag_ledtest_req_s *)diag->ledtest.mbcmd.msg; 4975 /* build host command */ 4976 bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_LEDTEST, 4977 bfa_ioc_portid(diag->ioc)); 4978 4979 /* 4980 * convert the freq from N blinks per 10 sec to 4981 * crossbow ontime value. We do it here because division is need 4982 */ 4983 if (ledtest->freq) 4984 ledtest->freq = 500 / ledtest->freq; 4985 4986 if (ledtest->freq == 0) 4987 ledtest->freq = 1; 4988 4989 bfa_trc(diag, ledtest->freq); 4990 /* mcpy(&ledtest_req->req, ledtest, sizeof(bfa_diag_ledtest_t)); */ 4991 msg->cmd = (u8) ledtest->cmd; 4992 msg->color = (u8) ledtest->color; 4993 msg->portid = bfa_ioc_portid(diag->ioc); 4994 msg->led = ledtest->led; 4995 msg->freq = cpu_to_be16(ledtest->freq); 4996 4997 /* send mbox cmd */ 4998 bfa_ioc_mbox_queue(diag->ioc, &diag->ledtest.mbcmd); 4999 } 5000 5001 static void 5002 diag_ledtest_comp(struct bfa_diag_s *diag, struct bfi_diag_ledtest_rsp_s *msg) 5003 { 5004 bfa_trc(diag, diag->ledtest.lock); 5005 diag->ledtest.lock = BFA_FALSE; 5006 /* no bfa_cb_queue is needed because driver is not waiting */ 5007 } 5008 5009 /* 5010 * Port beaconing 5011 */ 5012 static void 5013 diag_portbeacon_send(struct bfa_diag_s *diag, bfa_boolean_t beacon, u32 sec) 5014 { 5015 struct bfi_diag_portbeacon_req_s *msg; 5016 5017 msg = (struct bfi_diag_portbeacon_req_s *)diag->beacon.mbcmd.msg; 5018 /* build host command */ 5019 bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_PORTBEACON, 5020 bfa_ioc_portid(diag->ioc)); 5021 msg->beacon = beacon; 5022 msg->period = cpu_to_be32(sec); 5023 /* send mbox cmd */ 5024 bfa_ioc_mbox_queue(diag->ioc, &diag->beacon.mbcmd); 5025 } 5026 5027 static void 5028 diag_portbeacon_comp(struct bfa_diag_s *diag) 5029 { 5030 bfa_trc(diag, diag->beacon.state); 5031 diag->beacon.state = BFA_FALSE; 5032 if (diag->cbfn_beacon) 5033 diag->cbfn_beacon(diag->dev, BFA_FALSE, diag->beacon.link_e2e); 5034 } 5035 5036 /* 5037 * Diag hmbox handler 5038 */ 5039 void 5040 bfa_diag_intr(void *diagarg, struct bfi_mbmsg_s *msg) 5041 { 5042 struct bfa_diag_s *diag = diagarg; 5043 5044 switch (msg->mh.msg_id) { 5045 case BFI_DIAG_I2H_PORTBEACON: 5046 diag_portbeacon_comp(diag); 5047 break; 5048 case BFI_DIAG_I2H_FWPING: 5049 diag_fwping_comp(diag, (struct bfi_diag_fwping_rsp_s *) msg); 5050 break; 5051 case BFI_DIAG_I2H_TEMPSENSOR: 5052 diag_tempsensor_comp(diag, (bfi_diag_ts_rsp_t *) msg); 5053 break; 5054 case BFI_DIAG_I2H_LEDTEST: 5055 diag_ledtest_comp(diag, (struct bfi_diag_ledtest_rsp_s *) msg); 5056 break; 5057 default: 5058 bfa_trc(diag, msg->mh.msg_id); 5059 WARN_ON(1); 5060 } 5061 } 5062 5063 /* 5064 * Gen RAM Test 5065 * 5066 * @param[in] *diag - diag data struct 5067 * @param[in] *memtest - mem test params input from upper layer, 5068 * @param[in] pattern - mem test pattern 5069 * @param[in] *result - mem test result 5070 * @param[in] cbfn - mem test callback functioin 5071 * @param[in] cbarg - callback functioin arg 5072 * 5073 * @param[out] 5074 */ 5075 bfa_status_t 5076 bfa_diag_memtest(struct bfa_diag_s *diag, struct bfa_diag_memtest_s *memtest, 5077 u32 pattern, struct bfa_diag_memtest_result *result, 5078 bfa_cb_diag_t cbfn, void *cbarg) 5079 { 5080 u32 memtest_tov; 5081 5082 bfa_trc(diag, pattern); 5083 5084 if (!bfa_ioc_adapter_is_disabled(diag->ioc)) 5085 return BFA_STATUS_ADAPTER_ENABLED; 5086 5087 /* check to see if there is another destructive diag cmd running */ 5088 if (diag->block) { 5089 bfa_trc(diag, diag->block); 5090 return BFA_STATUS_DEVBUSY; 5091 } else 5092 diag->block = 1; 5093 5094 diag->result = result; 5095 diag->cbfn = cbfn; 5096 diag->cbarg = cbarg; 5097 5098 /* download memtest code and take LPU0 out of reset */ 5099 bfa_ioc_boot(diag->ioc, BFI_FWBOOT_TYPE_MEMTEST, BFI_FWBOOT_ENV_OS); 5100 5101 memtest_tov = (bfa_ioc_asic_gen(diag->ioc) == BFI_ASIC_GEN_CT2) ? 5102 CT2_BFA_DIAG_MEMTEST_TOV : BFA_DIAG_MEMTEST_TOV; 5103 bfa_timer_begin(diag->ioc->timer_mod, &diag->timer, 5104 bfa_diag_memtest_done, diag, memtest_tov); 5105 diag->timer_active = 1; 5106 return BFA_STATUS_OK; 5107 } 5108 5109 /* 5110 * DIAG firmware ping command 5111 * 5112 * @param[in] *diag - diag data struct 5113 * @param[in] cnt - dma loop count for testing PCIE 5114 * @param[in] data - data pattern to pass in fw 5115 * @param[in] *result - pt to bfa_diag_fwping_result_t data struct 5116 * @param[in] cbfn - callback function 5117 * @param[in] *cbarg - callback functioin arg 5118 * 5119 * @param[out] 5120 */ 5121 bfa_status_t 5122 bfa_diag_fwping(struct bfa_diag_s *diag, u32 cnt, u32 data, 5123 struct bfa_diag_results_fwping *result, bfa_cb_diag_t cbfn, 5124 void *cbarg) 5125 { 5126 bfa_trc(diag, cnt); 5127 bfa_trc(diag, data); 5128 5129 if (!bfa_ioc_is_operational(diag->ioc)) 5130 return BFA_STATUS_IOC_NON_OP; 5131 5132 if (bfa_asic_id_ct2(bfa_ioc_devid((diag->ioc))) && 5133 ((diag->ioc)->clscode == BFI_PCIFN_CLASS_ETH)) 5134 return BFA_STATUS_CMD_NOTSUPP; 5135 5136 /* check to see if there is another destructive diag cmd running */ 5137 if (diag->block || diag->fwping.lock) { 5138 bfa_trc(diag, diag->block); 5139 bfa_trc(diag, diag->fwping.lock); 5140 return BFA_STATUS_DEVBUSY; 5141 } 5142 5143 /* Initialization */ 5144 diag->fwping.lock = 1; 5145 diag->fwping.cbfn = cbfn; 5146 diag->fwping.cbarg = cbarg; 5147 diag->fwping.result = result; 5148 diag->fwping.data = data; 5149 diag->fwping.count = cnt; 5150 5151 /* Init test results */ 5152 diag->fwping.result->data = 0; 5153 diag->fwping.result->status = BFA_STATUS_OK; 5154 5155 /* kick off the first ping */ 5156 diag_fwping_send(diag); 5157 return BFA_STATUS_OK; 5158 } 5159 5160 /* 5161 * Read Temperature Sensor 5162 * 5163 * @param[in] *diag - diag data struct 5164 * @param[in] *result - pt to bfa_diag_temp_t data struct 5165 * @param[in] cbfn - callback function 5166 * @param[in] *cbarg - callback functioin arg 5167 * 5168 * @param[out] 5169 */ 5170 bfa_status_t 5171 bfa_diag_tsensor_query(struct bfa_diag_s *diag, 5172 struct bfa_diag_results_tempsensor_s *result, 5173 bfa_cb_diag_t cbfn, void *cbarg) 5174 { 5175 /* check to see if there is a destructive diag cmd running */ 5176 if (diag->block || diag->tsensor.lock) { 5177 bfa_trc(diag, diag->block); 5178 bfa_trc(diag, diag->tsensor.lock); 5179 return BFA_STATUS_DEVBUSY; 5180 } 5181 5182 if (!bfa_ioc_is_operational(diag->ioc)) 5183 return BFA_STATUS_IOC_NON_OP; 5184 5185 /* Init diag mod params */ 5186 diag->tsensor.lock = 1; 5187 diag->tsensor.temp = result; 5188 diag->tsensor.cbfn = cbfn; 5189 diag->tsensor.cbarg = cbarg; 5190 diag->tsensor.status = BFA_STATUS_OK; 5191 5192 /* Send msg to fw */ 5193 diag_tempsensor_send(diag); 5194 5195 return BFA_STATUS_OK; 5196 } 5197 5198 /* 5199 * LED Test command 5200 * 5201 * @param[in] *diag - diag data struct 5202 * @param[in] *ledtest - pt to ledtest data structure 5203 * 5204 * @param[out] 5205 */ 5206 bfa_status_t 5207 bfa_diag_ledtest(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest) 5208 { 5209 bfa_trc(diag, ledtest->cmd); 5210 5211 if (!bfa_ioc_is_operational(diag->ioc)) 5212 return BFA_STATUS_IOC_NON_OP; 5213 5214 if (diag->beacon.state) 5215 return BFA_STATUS_BEACON_ON; 5216 5217 if (diag->ledtest.lock) 5218 return BFA_STATUS_LEDTEST_OP; 5219 5220 /* Send msg to fw */ 5221 diag->ledtest.lock = BFA_TRUE; 5222 diag_ledtest_send(diag, ledtest); 5223 5224 return BFA_STATUS_OK; 5225 } 5226 5227 /* 5228 * Port beaconing command 5229 * 5230 * @param[in] *diag - diag data struct 5231 * @param[in] beacon - port beaconing 1:ON 0:OFF 5232 * @param[in] link_e2e_beacon - link beaconing 1:ON 0:OFF 5233 * @param[in] sec - beaconing duration in seconds 5234 * 5235 * @param[out] 5236 */ 5237 bfa_status_t 5238 bfa_diag_beacon_port(struct bfa_diag_s *diag, bfa_boolean_t beacon, 5239 bfa_boolean_t link_e2e_beacon, uint32_t sec) 5240 { 5241 bfa_trc(diag, beacon); 5242 bfa_trc(diag, link_e2e_beacon); 5243 bfa_trc(diag, sec); 5244 5245 if (!bfa_ioc_is_operational(diag->ioc)) 5246 return BFA_STATUS_IOC_NON_OP; 5247 5248 if (diag->ledtest.lock) 5249 return BFA_STATUS_LEDTEST_OP; 5250 5251 if (diag->beacon.state && beacon) /* beacon alread on */ 5252 return BFA_STATUS_BEACON_ON; 5253 5254 diag->beacon.state = beacon; 5255 diag->beacon.link_e2e = link_e2e_beacon; 5256 if (diag->cbfn_beacon) 5257 diag->cbfn_beacon(diag->dev, beacon, link_e2e_beacon); 5258 5259 /* Send msg to fw */ 5260 diag_portbeacon_send(diag, beacon, sec); 5261 5262 return BFA_STATUS_OK; 5263 } 5264 5265 /* 5266 * Return DMA memory needed by diag module. 5267 */ 5268 u32 5269 bfa_diag_meminfo(void) 5270 { 5271 return BFA_ROUNDUP(BFI_DIAG_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 5272 } 5273 5274 /* 5275 * Attach virtual and physical memory for Diag. 5276 */ 5277 void 5278 bfa_diag_attach(struct bfa_diag_s *diag, struct bfa_ioc_s *ioc, void *dev, 5279 bfa_cb_diag_beacon_t cbfn_beacon, struct bfa_trc_mod_s *trcmod) 5280 { 5281 diag->dev = dev; 5282 diag->ioc = ioc; 5283 diag->trcmod = trcmod; 5284 5285 diag->block = 0; 5286 diag->cbfn = NULL; 5287 diag->cbarg = NULL; 5288 diag->result = NULL; 5289 diag->cbfn_beacon = cbfn_beacon; 5290 5291 bfa_ioc_mbox_regisr(diag->ioc, BFI_MC_DIAG, bfa_diag_intr, diag); 5292 bfa_q_qe_init(&diag->ioc_notify); 5293 bfa_ioc_notify_init(&diag->ioc_notify, bfa_diag_notify, diag); 5294 list_add_tail(&diag->ioc_notify.qe, &diag->ioc->notify_q); 5295 } 5296 5297 void 5298 bfa_diag_memclaim(struct bfa_diag_s *diag, u8 *dm_kva, u64 dm_pa) 5299 { 5300 diag->fwping.dbuf_kva = dm_kva; 5301 diag->fwping.dbuf_pa = dm_pa; 5302 memset(diag->fwping.dbuf_kva, 0, BFI_DIAG_DMA_BUF_SZ); 5303 } 5304 5305 /* 5306 * PHY module specific 5307 */ 5308 #define BFA_PHY_DMA_BUF_SZ 0x02000 /* 8k dma buffer */ 5309 #define BFA_PHY_LOCK_STATUS 0x018878 /* phy semaphore status reg */ 5310 5311 static void 5312 bfa_phy_ntoh32(u32 *obuf, u32 *ibuf, int sz) 5313 { 5314 int i, m = sz >> 2; 5315 5316 for (i = 0; i < m; i++) 5317 obuf[i] = be32_to_cpu(ibuf[i]); 5318 } 5319 5320 static bfa_boolean_t 5321 bfa_phy_present(struct bfa_phy_s *phy) 5322 { 5323 return (phy->ioc->attr->card_type == BFA_MFG_TYPE_LIGHTNING); 5324 } 5325 5326 static void 5327 bfa_phy_notify(void *cbarg, enum bfa_ioc_event_e event) 5328 { 5329 struct bfa_phy_s *phy = cbarg; 5330 5331 bfa_trc(phy, event); 5332 5333 switch (event) { 5334 case BFA_IOC_E_DISABLED: 5335 case BFA_IOC_E_FAILED: 5336 if (phy->op_busy) { 5337 phy->status = BFA_STATUS_IOC_FAILURE; 5338 phy->cbfn(phy->cbarg, phy->status); 5339 phy->op_busy = 0; 5340 } 5341 break; 5342 5343 default: 5344 break; 5345 } 5346 } 5347 5348 /* 5349 * Send phy attribute query request. 5350 * 5351 * @param[in] cbarg - callback argument 5352 */ 5353 static void 5354 bfa_phy_query_send(void *cbarg) 5355 { 5356 struct bfa_phy_s *phy = cbarg; 5357 struct bfi_phy_query_req_s *msg = 5358 (struct bfi_phy_query_req_s *) phy->mb.msg; 5359 5360 msg->instance = phy->instance; 5361 bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_QUERY_REQ, 5362 bfa_ioc_portid(phy->ioc)); 5363 bfa_alen_set(&msg->alen, sizeof(struct bfa_phy_attr_s), phy->dbuf_pa); 5364 bfa_ioc_mbox_queue(phy->ioc, &phy->mb); 5365 } 5366 5367 /* 5368 * Send phy write request. 5369 * 5370 * @param[in] cbarg - callback argument 5371 */ 5372 static void 5373 bfa_phy_write_send(void *cbarg) 5374 { 5375 struct bfa_phy_s *phy = cbarg; 5376 struct bfi_phy_write_req_s *msg = 5377 (struct bfi_phy_write_req_s *) phy->mb.msg; 5378 u32 len; 5379 u16 *buf, *dbuf; 5380 int i, sz; 5381 5382 msg->instance = phy->instance; 5383 msg->offset = cpu_to_be32(phy->addr_off + phy->offset); 5384 len = (phy->residue < BFA_PHY_DMA_BUF_SZ) ? 5385 phy->residue : BFA_PHY_DMA_BUF_SZ; 5386 msg->length = cpu_to_be32(len); 5387 5388 /* indicate if it's the last msg of the whole write operation */ 5389 msg->last = (len == phy->residue) ? 1 : 0; 5390 5391 bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_WRITE_REQ, 5392 bfa_ioc_portid(phy->ioc)); 5393 bfa_alen_set(&msg->alen, len, phy->dbuf_pa); 5394 5395 buf = (u16 *) (phy->ubuf + phy->offset); 5396 dbuf = (u16 *)phy->dbuf_kva; 5397 sz = len >> 1; 5398 for (i = 0; i < sz; i++) 5399 buf[i] = cpu_to_be16(dbuf[i]); 5400 5401 bfa_ioc_mbox_queue(phy->ioc, &phy->mb); 5402 5403 phy->residue -= len; 5404 phy->offset += len; 5405 } 5406 5407 /* 5408 * Send phy read request. 5409 * 5410 * @param[in] cbarg - callback argument 5411 */ 5412 static void 5413 bfa_phy_read_send(void *cbarg) 5414 { 5415 struct bfa_phy_s *phy = cbarg; 5416 struct bfi_phy_read_req_s *msg = 5417 (struct bfi_phy_read_req_s *) phy->mb.msg; 5418 u32 len; 5419 5420 msg->instance = phy->instance; 5421 msg->offset = cpu_to_be32(phy->addr_off + phy->offset); 5422 len = (phy->residue < BFA_PHY_DMA_BUF_SZ) ? 5423 phy->residue : BFA_PHY_DMA_BUF_SZ; 5424 msg->length = cpu_to_be32(len); 5425 bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_READ_REQ, 5426 bfa_ioc_portid(phy->ioc)); 5427 bfa_alen_set(&msg->alen, len, phy->dbuf_pa); 5428 bfa_ioc_mbox_queue(phy->ioc, &phy->mb); 5429 } 5430 5431 /* 5432 * Send phy stats request. 5433 * 5434 * @param[in] cbarg - callback argument 5435 */ 5436 static void 5437 bfa_phy_stats_send(void *cbarg) 5438 { 5439 struct bfa_phy_s *phy = cbarg; 5440 struct bfi_phy_stats_req_s *msg = 5441 (struct bfi_phy_stats_req_s *) phy->mb.msg; 5442 5443 msg->instance = phy->instance; 5444 bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_STATS_REQ, 5445 bfa_ioc_portid(phy->ioc)); 5446 bfa_alen_set(&msg->alen, sizeof(struct bfa_phy_stats_s), phy->dbuf_pa); 5447 bfa_ioc_mbox_queue(phy->ioc, &phy->mb); 5448 } 5449 5450 /* 5451 * Flash memory info API. 5452 * 5453 * @param[in] mincfg - minimal cfg variable 5454 */ 5455 u32 5456 bfa_phy_meminfo(bfa_boolean_t mincfg) 5457 { 5458 /* min driver doesn't need phy */ 5459 if (mincfg) 5460 return 0; 5461 5462 return BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 5463 } 5464 5465 /* 5466 * Flash attach API. 5467 * 5468 * @param[in] phy - phy structure 5469 * @param[in] ioc - ioc structure 5470 * @param[in] dev - device structure 5471 * @param[in] trcmod - trace module 5472 * @param[in] logmod - log module 5473 */ 5474 void 5475 bfa_phy_attach(struct bfa_phy_s *phy, struct bfa_ioc_s *ioc, void *dev, 5476 struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg) 5477 { 5478 phy->ioc = ioc; 5479 phy->trcmod = trcmod; 5480 phy->cbfn = NULL; 5481 phy->cbarg = NULL; 5482 phy->op_busy = 0; 5483 5484 bfa_ioc_mbox_regisr(phy->ioc, BFI_MC_PHY, bfa_phy_intr, phy); 5485 bfa_q_qe_init(&phy->ioc_notify); 5486 bfa_ioc_notify_init(&phy->ioc_notify, bfa_phy_notify, phy); 5487 list_add_tail(&phy->ioc_notify.qe, &phy->ioc->notify_q); 5488 5489 /* min driver doesn't need phy */ 5490 if (mincfg) { 5491 phy->dbuf_kva = NULL; 5492 phy->dbuf_pa = 0; 5493 } 5494 } 5495 5496 /* 5497 * Claim memory for phy 5498 * 5499 * @param[in] phy - phy structure 5500 * @param[in] dm_kva - pointer to virtual memory address 5501 * @param[in] dm_pa - physical memory address 5502 * @param[in] mincfg - minimal cfg variable 5503 */ 5504 void 5505 bfa_phy_memclaim(struct bfa_phy_s *phy, u8 *dm_kva, u64 dm_pa, 5506 bfa_boolean_t mincfg) 5507 { 5508 if (mincfg) 5509 return; 5510 5511 phy->dbuf_kva = dm_kva; 5512 phy->dbuf_pa = dm_pa; 5513 memset(phy->dbuf_kva, 0, BFA_PHY_DMA_BUF_SZ); 5514 dm_kva += BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 5515 dm_pa += BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 5516 } 5517 5518 bfa_boolean_t 5519 bfa_phy_busy(struct bfa_ioc_s *ioc) 5520 { 5521 void __iomem *rb; 5522 5523 rb = bfa_ioc_bar0(ioc); 5524 return readl(rb + BFA_PHY_LOCK_STATUS); 5525 } 5526 5527 /* 5528 * Get phy attribute. 5529 * 5530 * @param[in] phy - phy structure 5531 * @param[in] attr - phy attribute structure 5532 * @param[in] cbfn - callback function 5533 * @param[in] cbarg - callback argument 5534 * 5535 * Return status. 5536 */ 5537 bfa_status_t 5538 bfa_phy_get_attr(struct bfa_phy_s *phy, u8 instance, 5539 struct bfa_phy_attr_s *attr, bfa_cb_phy_t cbfn, void *cbarg) 5540 { 5541 bfa_trc(phy, BFI_PHY_H2I_QUERY_REQ); 5542 bfa_trc(phy, instance); 5543 5544 if (!bfa_phy_present(phy)) 5545 return BFA_STATUS_PHY_NOT_PRESENT; 5546 5547 if (!bfa_ioc_is_operational(phy->ioc)) 5548 return BFA_STATUS_IOC_NON_OP; 5549 5550 if (phy->op_busy || bfa_phy_busy(phy->ioc)) { 5551 bfa_trc(phy, phy->op_busy); 5552 return BFA_STATUS_DEVBUSY; 5553 } 5554 5555 phy->op_busy = 1; 5556 phy->cbfn = cbfn; 5557 phy->cbarg = cbarg; 5558 phy->instance = instance; 5559 phy->ubuf = (uint8_t *) attr; 5560 bfa_phy_query_send(phy); 5561 5562 return BFA_STATUS_OK; 5563 } 5564 5565 /* 5566 * Get phy stats. 5567 * 5568 * @param[in] phy - phy structure 5569 * @param[in] instance - phy image instance 5570 * @param[in] stats - pointer to phy stats 5571 * @param[in] cbfn - callback function 5572 * @param[in] cbarg - callback argument 5573 * 5574 * Return status. 5575 */ 5576 bfa_status_t 5577 bfa_phy_get_stats(struct bfa_phy_s *phy, u8 instance, 5578 struct bfa_phy_stats_s *stats, 5579 bfa_cb_phy_t cbfn, void *cbarg) 5580 { 5581 bfa_trc(phy, BFI_PHY_H2I_STATS_REQ); 5582 bfa_trc(phy, instance); 5583 5584 if (!bfa_phy_present(phy)) 5585 return BFA_STATUS_PHY_NOT_PRESENT; 5586 5587 if (!bfa_ioc_is_operational(phy->ioc)) 5588 return BFA_STATUS_IOC_NON_OP; 5589 5590 if (phy->op_busy || bfa_phy_busy(phy->ioc)) { 5591 bfa_trc(phy, phy->op_busy); 5592 return BFA_STATUS_DEVBUSY; 5593 } 5594 5595 phy->op_busy = 1; 5596 phy->cbfn = cbfn; 5597 phy->cbarg = cbarg; 5598 phy->instance = instance; 5599 phy->ubuf = (u8 *) stats; 5600 bfa_phy_stats_send(phy); 5601 5602 return BFA_STATUS_OK; 5603 } 5604 5605 /* 5606 * Update phy image. 5607 * 5608 * @param[in] phy - phy structure 5609 * @param[in] instance - phy image instance 5610 * @param[in] buf - update data buffer 5611 * @param[in] len - data buffer length 5612 * @param[in] offset - offset relative to starting address 5613 * @param[in] cbfn - callback function 5614 * @param[in] cbarg - callback argument 5615 * 5616 * Return status. 5617 */ 5618 bfa_status_t 5619 bfa_phy_update(struct bfa_phy_s *phy, u8 instance, 5620 void *buf, u32 len, u32 offset, 5621 bfa_cb_phy_t cbfn, void *cbarg) 5622 { 5623 bfa_trc(phy, BFI_PHY_H2I_WRITE_REQ); 5624 bfa_trc(phy, instance); 5625 bfa_trc(phy, len); 5626 bfa_trc(phy, offset); 5627 5628 if (!bfa_phy_present(phy)) 5629 return BFA_STATUS_PHY_NOT_PRESENT; 5630 5631 if (!bfa_ioc_is_operational(phy->ioc)) 5632 return BFA_STATUS_IOC_NON_OP; 5633 5634 /* 'len' must be in word (4-byte) boundary */ 5635 if (!len || (len & 0x03)) 5636 return BFA_STATUS_FAILED; 5637 5638 if (phy->op_busy || bfa_phy_busy(phy->ioc)) { 5639 bfa_trc(phy, phy->op_busy); 5640 return BFA_STATUS_DEVBUSY; 5641 } 5642 5643 phy->op_busy = 1; 5644 phy->cbfn = cbfn; 5645 phy->cbarg = cbarg; 5646 phy->instance = instance; 5647 phy->residue = len; 5648 phy->offset = 0; 5649 phy->addr_off = offset; 5650 phy->ubuf = buf; 5651 5652 bfa_phy_write_send(phy); 5653 return BFA_STATUS_OK; 5654 } 5655 5656 /* 5657 * Read phy image. 5658 * 5659 * @param[in] phy - phy structure 5660 * @param[in] instance - phy image instance 5661 * @param[in] buf - read data buffer 5662 * @param[in] len - data buffer length 5663 * @param[in] offset - offset relative to starting address 5664 * @param[in] cbfn - callback function 5665 * @param[in] cbarg - callback argument 5666 * 5667 * Return status. 5668 */ 5669 bfa_status_t 5670 bfa_phy_read(struct bfa_phy_s *phy, u8 instance, 5671 void *buf, u32 len, u32 offset, 5672 bfa_cb_phy_t cbfn, void *cbarg) 5673 { 5674 bfa_trc(phy, BFI_PHY_H2I_READ_REQ); 5675 bfa_trc(phy, instance); 5676 bfa_trc(phy, len); 5677 bfa_trc(phy, offset); 5678 5679 if (!bfa_phy_present(phy)) 5680 return BFA_STATUS_PHY_NOT_PRESENT; 5681 5682 if (!bfa_ioc_is_operational(phy->ioc)) 5683 return BFA_STATUS_IOC_NON_OP; 5684 5685 /* 'len' must be in word (4-byte) boundary */ 5686 if (!len || (len & 0x03)) 5687 return BFA_STATUS_FAILED; 5688 5689 if (phy->op_busy || bfa_phy_busy(phy->ioc)) { 5690 bfa_trc(phy, phy->op_busy); 5691 return BFA_STATUS_DEVBUSY; 5692 } 5693 5694 phy->op_busy = 1; 5695 phy->cbfn = cbfn; 5696 phy->cbarg = cbarg; 5697 phy->instance = instance; 5698 phy->residue = len; 5699 phy->offset = 0; 5700 phy->addr_off = offset; 5701 phy->ubuf = buf; 5702 bfa_phy_read_send(phy); 5703 5704 return BFA_STATUS_OK; 5705 } 5706 5707 /* 5708 * Process phy response messages upon receiving interrupts. 5709 * 5710 * @param[in] phyarg - phy structure 5711 * @param[in] msg - message structure 5712 */ 5713 void 5714 bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg) 5715 { 5716 struct bfa_phy_s *phy = phyarg; 5717 u32 status; 5718 5719 union { 5720 struct bfi_phy_query_rsp_s *query; 5721 struct bfi_phy_stats_rsp_s *stats; 5722 struct bfi_phy_write_rsp_s *write; 5723 struct bfi_phy_read_rsp_s *read; 5724 struct bfi_mbmsg_s *msg; 5725 } m; 5726 5727 m.msg = msg; 5728 bfa_trc(phy, msg->mh.msg_id); 5729 5730 if (!phy->op_busy) { 5731 /* receiving response after ioc failure */ 5732 bfa_trc(phy, 0x9999); 5733 return; 5734 } 5735 5736 switch (msg->mh.msg_id) { 5737 case BFI_PHY_I2H_QUERY_RSP: 5738 status = be32_to_cpu(m.query->status); 5739 bfa_trc(phy, status); 5740 5741 if (status == BFA_STATUS_OK) { 5742 struct bfa_phy_attr_s *attr = 5743 (struct bfa_phy_attr_s *) phy->ubuf; 5744 bfa_phy_ntoh32((u32 *)attr, (u32 *)phy->dbuf_kva, 5745 sizeof(struct bfa_phy_attr_s)); 5746 bfa_trc(phy, attr->status); 5747 bfa_trc(phy, attr->length); 5748 } 5749 5750 phy->status = status; 5751 phy->op_busy = 0; 5752 if (phy->cbfn) 5753 phy->cbfn(phy->cbarg, phy->status); 5754 break; 5755 case BFI_PHY_I2H_STATS_RSP: 5756 status = be32_to_cpu(m.stats->status); 5757 bfa_trc(phy, status); 5758 5759 if (status == BFA_STATUS_OK) { 5760 struct bfa_phy_stats_s *stats = 5761 (struct bfa_phy_stats_s *) phy->ubuf; 5762 bfa_phy_ntoh32((u32 *)stats, (u32 *)phy->dbuf_kva, 5763 sizeof(struct bfa_phy_stats_s)); 5764 bfa_trc(phy, stats->status); 5765 } 5766 5767 phy->status = status; 5768 phy->op_busy = 0; 5769 if (phy->cbfn) 5770 phy->cbfn(phy->cbarg, phy->status); 5771 break; 5772 case BFI_PHY_I2H_WRITE_RSP: 5773 status = be32_to_cpu(m.write->status); 5774 bfa_trc(phy, status); 5775 5776 if (status != BFA_STATUS_OK || phy->residue == 0) { 5777 phy->status = status; 5778 phy->op_busy = 0; 5779 if (phy->cbfn) 5780 phy->cbfn(phy->cbarg, phy->status); 5781 } else { 5782 bfa_trc(phy, phy->offset); 5783 bfa_phy_write_send(phy); 5784 } 5785 break; 5786 case BFI_PHY_I2H_READ_RSP: 5787 status = be32_to_cpu(m.read->status); 5788 bfa_trc(phy, status); 5789 5790 if (status != BFA_STATUS_OK) { 5791 phy->status = status; 5792 phy->op_busy = 0; 5793 if (phy->cbfn) 5794 phy->cbfn(phy->cbarg, phy->status); 5795 } else { 5796 u32 len = be32_to_cpu(m.read->length); 5797 u16 *buf = (u16 *)(phy->ubuf + phy->offset); 5798 u16 *dbuf = (u16 *)phy->dbuf_kva; 5799 int i, sz = len >> 1; 5800 5801 bfa_trc(phy, phy->offset); 5802 bfa_trc(phy, len); 5803 5804 for (i = 0; i < sz; i++) 5805 buf[i] = be16_to_cpu(dbuf[i]); 5806 5807 phy->residue -= len; 5808 phy->offset += len; 5809 5810 if (phy->residue == 0) { 5811 phy->status = status; 5812 phy->op_busy = 0; 5813 if (phy->cbfn) 5814 phy->cbfn(phy->cbarg, phy->status); 5815 } else 5816 bfa_phy_read_send(phy); 5817 } 5818 break; 5819 default: 5820 WARN_ON(1); 5821 } 5822 } 5823 5824 /* 5825 * DCONF module specific 5826 */ 5827 5828 BFA_MODULE(dconf); 5829 5830 /* 5831 * DCONF state machine events 5832 */ 5833 enum bfa_dconf_event { 5834 BFA_DCONF_SM_INIT = 1, /* dconf Init */ 5835 BFA_DCONF_SM_FLASH_COMP = 2, /* read/write to flash */ 5836 BFA_DCONF_SM_WR = 3, /* binding change, map */ 5837 BFA_DCONF_SM_TIMEOUT = 4, /* Start timer */ 5838 BFA_DCONF_SM_EXIT = 5, /* exit dconf module */ 5839 BFA_DCONF_SM_IOCDISABLE = 6, /* IOC disable event */ 5840 }; 5841 5842 /* forward declaration of DCONF state machine */ 5843 static void bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, 5844 enum bfa_dconf_event event); 5845 static void bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf, 5846 enum bfa_dconf_event event); 5847 static void bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf, 5848 enum bfa_dconf_event event); 5849 static void bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf, 5850 enum bfa_dconf_event event); 5851 static void bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf, 5852 enum bfa_dconf_event event); 5853 static void bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf, 5854 enum bfa_dconf_event event); 5855 static void bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf, 5856 enum bfa_dconf_event event); 5857 5858 static void bfa_dconf_cbfn(void *dconf, bfa_status_t status); 5859 static void bfa_dconf_timer(void *cbarg); 5860 static bfa_status_t bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf); 5861 static void bfa_dconf_init_cb(void *arg, bfa_status_t status); 5862 5863 /* 5864 * Beginning state of dconf module. Waiting for an event to start. 5865 */ 5866 static void 5867 bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event) 5868 { 5869 bfa_status_t bfa_status; 5870 bfa_trc(dconf->bfa, event); 5871 5872 switch (event) { 5873 case BFA_DCONF_SM_INIT: 5874 if (dconf->min_cfg) { 5875 bfa_trc(dconf->bfa, dconf->min_cfg); 5876 bfa_fsm_send_event(&dconf->bfa->iocfc, 5877 IOCFC_E_DCONF_DONE); 5878 return; 5879 } 5880 bfa_sm_set_state(dconf, bfa_dconf_sm_flash_read); 5881 bfa_timer_start(dconf->bfa, &dconf->timer, 5882 bfa_dconf_timer, dconf, 2 * BFA_DCONF_UPDATE_TOV); 5883 bfa_status = bfa_flash_read_part(BFA_FLASH(dconf->bfa), 5884 BFA_FLASH_PART_DRV, dconf->instance, 5885 dconf->dconf, 5886 sizeof(struct bfa_dconf_s), 0, 5887 bfa_dconf_init_cb, dconf->bfa); 5888 if (bfa_status != BFA_STATUS_OK) { 5889 bfa_timer_stop(&dconf->timer); 5890 bfa_dconf_init_cb(dconf->bfa, BFA_STATUS_FAILED); 5891 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); 5892 return; 5893 } 5894 break; 5895 case BFA_DCONF_SM_EXIT: 5896 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE); 5897 case BFA_DCONF_SM_IOCDISABLE: 5898 case BFA_DCONF_SM_WR: 5899 case BFA_DCONF_SM_FLASH_COMP: 5900 break; 5901 default: 5902 bfa_sm_fault(dconf->bfa, event); 5903 } 5904 } 5905 5906 /* 5907 * Read flash for dconf entries and make a call back to the driver once done. 5908 */ 5909 static void 5910 bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf, 5911 enum bfa_dconf_event event) 5912 { 5913 bfa_trc(dconf->bfa, event); 5914 5915 switch (event) { 5916 case BFA_DCONF_SM_FLASH_COMP: 5917 bfa_timer_stop(&dconf->timer); 5918 bfa_sm_set_state(dconf, bfa_dconf_sm_ready); 5919 break; 5920 case BFA_DCONF_SM_TIMEOUT: 5921 bfa_sm_set_state(dconf, bfa_dconf_sm_ready); 5922 bfa_ioc_suspend(&dconf->bfa->ioc); 5923 break; 5924 case BFA_DCONF_SM_EXIT: 5925 bfa_timer_stop(&dconf->timer); 5926 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); 5927 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE); 5928 break; 5929 case BFA_DCONF_SM_IOCDISABLE: 5930 bfa_timer_stop(&dconf->timer); 5931 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); 5932 break; 5933 default: 5934 bfa_sm_fault(dconf->bfa, event); 5935 } 5936 } 5937 5938 /* 5939 * DCONF Module is in ready state. Has completed the initialization. 5940 */ 5941 static void 5942 bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event) 5943 { 5944 bfa_trc(dconf->bfa, event); 5945 5946 switch (event) { 5947 case BFA_DCONF_SM_WR: 5948 bfa_timer_start(dconf->bfa, &dconf->timer, 5949 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); 5950 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty); 5951 break; 5952 case BFA_DCONF_SM_EXIT: 5953 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); 5954 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE); 5955 break; 5956 case BFA_DCONF_SM_INIT: 5957 case BFA_DCONF_SM_IOCDISABLE: 5958 break; 5959 default: 5960 bfa_sm_fault(dconf->bfa, event); 5961 } 5962 } 5963 5964 /* 5965 * entries are dirty, write back to the flash. 5966 */ 5967 5968 static void 5969 bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event) 5970 { 5971 bfa_trc(dconf->bfa, event); 5972 5973 switch (event) { 5974 case BFA_DCONF_SM_TIMEOUT: 5975 bfa_sm_set_state(dconf, bfa_dconf_sm_sync); 5976 bfa_dconf_flash_write(dconf); 5977 break; 5978 case BFA_DCONF_SM_WR: 5979 bfa_timer_stop(&dconf->timer); 5980 bfa_timer_start(dconf->bfa, &dconf->timer, 5981 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); 5982 break; 5983 case BFA_DCONF_SM_EXIT: 5984 bfa_timer_stop(&dconf->timer); 5985 bfa_timer_start(dconf->bfa, &dconf->timer, 5986 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); 5987 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync); 5988 bfa_dconf_flash_write(dconf); 5989 break; 5990 case BFA_DCONF_SM_FLASH_COMP: 5991 break; 5992 case BFA_DCONF_SM_IOCDISABLE: 5993 bfa_timer_stop(&dconf->timer); 5994 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty); 5995 break; 5996 default: 5997 bfa_sm_fault(dconf->bfa, event); 5998 } 5999 } 6000 6001 /* 6002 * Sync the dconf entries to the flash. 6003 */ 6004 static void 6005 bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf, 6006 enum bfa_dconf_event event) 6007 { 6008 bfa_trc(dconf->bfa, event); 6009 6010 switch (event) { 6011 case BFA_DCONF_SM_IOCDISABLE: 6012 case BFA_DCONF_SM_FLASH_COMP: 6013 bfa_timer_stop(&dconf->timer); 6014 case BFA_DCONF_SM_TIMEOUT: 6015 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); 6016 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE); 6017 break; 6018 default: 6019 bfa_sm_fault(dconf->bfa, event); 6020 } 6021 } 6022 6023 static void 6024 bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event) 6025 { 6026 bfa_trc(dconf->bfa, event); 6027 6028 switch (event) { 6029 case BFA_DCONF_SM_FLASH_COMP: 6030 bfa_sm_set_state(dconf, bfa_dconf_sm_ready); 6031 break; 6032 case BFA_DCONF_SM_WR: 6033 bfa_timer_start(dconf->bfa, &dconf->timer, 6034 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); 6035 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty); 6036 break; 6037 case BFA_DCONF_SM_EXIT: 6038 bfa_timer_start(dconf->bfa, &dconf->timer, 6039 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); 6040 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync); 6041 break; 6042 case BFA_DCONF_SM_IOCDISABLE: 6043 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty); 6044 break; 6045 default: 6046 bfa_sm_fault(dconf->bfa, event); 6047 } 6048 } 6049 6050 static void 6051 bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf, 6052 enum bfa_dconf_event event) 6053 { 6054 bfa_trc(dconf->bfa, event); 6055 6056 switch (event) { 6057 case BFA_DCONF_SM_INIT: 6058 bfa_timer_start(dconf->bfa, &dconf->timer, 6059 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); 6060 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty); 6061 break; 6062 case BFA_DCONF_SM_EXIT: 6063 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); 6064 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE); 6065 break; 6066 case BFA_DCONF_SM_IOCDISABLE: 6067 break; 6068 default: 6069 bfa_sm_fault(dconf->bfa, event); 6070 } 6071 } 6072 6073 /* 6074 * Compute and return memory needed by DRV_CFG module. 6075 */ 6076 static void 6077 bfa_dconf_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, 6078 struct bfa_s *bfa) 6079 { 6080 struct bfa_mem_kva_s *dconf_kva = BFA_MEM_DCONF_KVA(bfa); 6081 6082 if (cfg->drvcfg.min_cfg) 6083 bfa_mem_kva_setup(meminfo, dconf_kva, 6084 sizeof(struct bfa_dconf_hdr_s)); 6085 else 6086 bfa_mem_kva_setup(meminfo, dconf_kva, 6087 sizeof(struct bfa_dconf_s)); 6088 } 6089 6090 static void 6091 bfa_dconf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 6092 struct bfa_pcidev_s *pcidev) 6093 { 6094 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); 6095 6096 dconf->bfad = bfad; 6097 dconf->bfa = bfa; 6098 dconf->instance = bfa->ioc.port_id; 6099 bfa_trc(bfa, dconf->instance); 6100 6101 dconf->dconf = (struct bfa_dconf_s *) bfa_mem_kva_curp(dconf); 6102 if (cfg->drvcfg.min_cfg) { 6103 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_hdr_s); 6104 dconf->min_cfg = BFA_TRUE; 6105 } else { 6106 dconf->min_cfg = BFA_FALSE; 6107 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_s); 6108 } 6109 6110 bfa_dconf_read_data_valid(bfa) = BFA_FALSE; 6111 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); 6112 } 6113 6114 static void 6115 bfa_dconf_init_cb(void *arg, bfa_status_t status) 6116 { 6117 struct bfa_s *bfa = arg; 6118 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); 6119 6120 if (status == BFA_STATUS_OK) { 6121 bfa_dconf_read_data_valid(bfa) = BFA_TRUE; 6122 if (dconf->dconf->hdr.signature != BFI_DCONF_SIGNATURE) 6123 dconf->dconf->hdr.signature = BFI_DCONF_SIGNATURE; 6124 if (dconf->dconf->hdr.version != BFI_DCONF_VERSION) 6125 dconf->dconf->hdr.version = BFI_DCONF_VERSION; 6126 } 6127 bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP); 6128 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DCONF_DONE); 6129 } 6130 6131 void 6132 bfa_dconf_modinit(struct bfa_s *bfa) 6133 { 6134 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); 6135 bfa_sm_send_event(dconf, BFA_DCONF_SM_INIT); 6136 } 6137 static void 6138 bfa_dconf_start(struct bfa_s *bfa) 6139 { 6140 } 6141 6142 static void 6143 bfa_dconf_stop(struct bfa_s *bfa) 6144 { 6145 } 6146 6147 static void bfa_dconf_timer(void *cbarg) 6148 { 6149 struct bfa_dconf_mod_s *dconf = cbarg; 6150 bfa_sm_send_event(dconf, BFA_DCONF_SM_TIMEOUT); 6151 } 6152 static void 6153 bfa_dconf_iocdisable(struct bfa_s *bfa) 6154 { 6155 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); 6156 bfa_sm_send_event(dconf, BFA_DCONF_SM_IOCDISABLE); 6157 } 6158 6159 static void 6160 bfa_dconf_detach(struct bfa_s *bfa) 6161 { 6162 } 6163 6164 static bfa_status_t 6165 bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf) 6166 { 6167 bfa_status_t bfa_status; 6168 bfa_trc(dconf->bfa, 0); 6169 6170 bfa_status = bfa_flash_update_part(BFA_FLASH(dconf->bfa), 6171 BFA_FLASH_PART_DRV, dconf->instance, 6172 dconf->dconf, sizeof(struct bfa_dconf_s), 0, 6173 bfa_dconf_cbfn, dconf); 6174 if (bfa_status != BFA_STATUS_OK) 6175 WARN_ON(bfa_status); 6176 bfa_trc(dconf->bfa, bfa_status); 6177 6178 return bfa_status; 6179 } 6180 6181 bfa_status_t 6182 bfa_dconf_update(struct bfa_s *bfa) 6183 { 6184 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); 6185 bfa_trc(dconf->bfa, 0); 6186 if (bfa_sm_cmp_state(dconf, bfa_dconf_sm_iocdown_dirty)) 6187 return BFA_STATUS_FAILED; 6188 6189 if (dconf->min_cfg) { 6190 bfa_trc(dconf->bfa, dconf->min_cfg); 6191 return BFA_STATUS_FAILED; 6192 } 6193 6194 bfa_sm_send_event(dconf, BFA_DCONF_SM_WR); 6195 return BFA_STATUS_OK; 6196 } 6197 6198 static void 6199 bfa_dconf_cbfn(void *arg, bfa_status_t status) 6200 { 6201 struct bfa_dconf_mod_s *dconf = arg; 6202 WARN_ON(status); 6203 bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP); 6204 } 6205 6206 void 6207 bfa_dconf_modexit(struct bfa_s *bfa) 6208 { 6209 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); 6210 bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT); 6211 } 6212 6213 /* 6214 * FRU specific functions 6215 */ 6216 6217 #define BFA_FRU_DMA_BUF_SZ 0x02000 /* 8k dma buffer */ 6218 #define BFA_FRU_CHINOOK_MAX_SIZE 0x10000 6219 #define BFA_FRU_LIGHTNING_MAX_SIZE 0x200 6220 6221 static void 6222 bfa_fru_notify(void *cbarg, enum bfa_ioc_event_e event) 6223 { 6224 struct bfa_fru_s *fru = cbarg; 6225 6226 bfa_trc(fru, event); 6227 6228 switch (event) { 6229 case BFA_IOC_E_DISABLED: 6230 case BFA_IOC_E_FAILED: 6231 if (fru->op_busy) { 6232 fru->status = BFA_STATUS_IOC_FAILURE; 6233 fru->cbfn(fru->cbarg, fru->status); 6234 fru->op_busy = 0; 6235 } 6236 break; 6237 6238 default: 6239 break; 6240 } 6241 } 6242 6243 /* 6244 * Send fru write request. 6245 * 6246 * @param[in] cbarg - callback argument 6247 */ 6248 static void 6249 bfa_fru_write_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type) 6250 { 6251 struct bfa_fru_s *fru = cbarg; 6252 struct bfi_fru_write_req_s *msg = 6253 (struct bfi_fru_write_req_s *) fru->mb.msg; 6254 u32 len; 6255 6256 msg->offset = cpu_to_be32(fru->addr_off + fru->offset); 6257 len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ? 6258 fru->residue : BFA_FRU_DMA_BUF_SZ; 6259 msg->length = cpu_to_be32(len); 6260 6261 /* 6262 * indicate if it's the last msg of the whole write operation 6263 */ 6264 msg->last = (len == fru->residue) ? 1 : 0; 6265 6266 msg->trfr_cmpl = (len == fru->residue) ? fru->trfr_cmpl : 0; 6267 bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc)); 6268 bfa_alen_set(&msg->alen, len, fru->dbuf_pa); 6269 6270 memcpy(fru->dbuf_kva, fru->ubuf + fru->offset, len); 6271 bfa_ioc_mbox_queue(fru->ioc, &fru->mb); 6272 6273 fru->residue -= len; 6274 fru->offset += len; 6275 } 6276 6277 /* 6278 * Send fru read request. 6279 * 6280 * @param[in] cbarg - callback argument 6281 */ 6282 static void 6283 bfa_fru_read_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type) 6284 { 6285 struct bfa_fru_s *fru = cbarg; 6286 struct bfi_fru_read_req_s *msg = 6287 (struct bfi_fru_read_req_s *) fru->mb.msg; 6288 u32 len; 6289 6290 msg->offset = cpu_to_be32(fru->addr_off + fru->offset); 6291 len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ? 6292 fru->residue : BFA_FRU_DMA_BUF_SZ; 6293 msg->length = cpu_to_be32(len); 6294 bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc)); 6295 bfa_alen_set(&msg->alen, len, fru->dbuf_pa); 6296 bfa_ioc_mbox_queue(fru->ioc, &fru->mb); 6297 } 6298 6299 /* 6300 * Flash memory info API. 6301 * 6302 * @param[in] mincfg - minimal cfg variable 6303 */ 6304 u32 6305 bfa_fru_meminfo(bfa_boolean_t mincfg) 6306 { 6307 /* min driver doesn't need fru */ 6308 if (mincfg) 6309 return 0; 6310 6311 return BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 6312 } 6313 6314 /* 6315 * Flash attach API. 6316 * 6317 * @param[in] fru - fru structure 6318 * @param[in] ioc - ioc structure 6319 * @param[in] dev - device structure 6320 * @param[in] trcmod - trace module 6321 * @param[in] logmod - log module 6322 */ 6323 void 6324 bfa_fru_attach(struct bfa_fru_s *fru, struct bfa_ioc_s *ioc, void *dev, 6325 struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg) 6326 { 6327 fru->ioc = ioc; 6328 fru->trcmod = trcmod; 6329 fru->cbfn = NULL; 6330 fru->cbarg = NULL; 6331 fru->op_busy = 0; 6332 6333 bfa_ioc_mbox_regisr(fru->ioc, BFI_MC_FRU, bfa_fru_intr, fru); 6334 bfa_q_qe_init(&fru->ioc_notify); 6335 bfa_ioc_notify_init(&fru->ioc_notify, bfa_fru_notify, fru); 6336 list_add_tail(&fru->ioc_notify.qe, &fru->ioc->notify_q); 6337 6338 /* min driver doesn't need fru */ 6339 if (mincfg) { 6340 fru->dbuf_kva = NULL; 6341 fru->dbuf_pa = 0; 6342 } 6343 } 6344 6345 /* 6346 * Claim memory for fru 6347 * 6348 * @param[in] fru - fru structure 6349 * @param[in] dm_kva - pointer to virtual memory address 6350 * @param[in] dm_pa - frusical memory address 6351 * @param[in] mincfg - minimal cfg variable 6352 */ 6353 void 6354 bfa_fru_memclaim(struct bfa_fru_s *fru, u8 *dm_kva, u64 dm_pa, 6355 bfa_boolean_t mincfg) 6356 { 6357 if (mincfg) 6358 return; 6359 6360 fru->dbuf_kva = dm_kva; 6361 fru->dbuf_pa = dm_pa; 6362 memset(fru->dbuf_kva, 0, BFA_FRU_DMA_BUF_SZ); 6363 dm_kva += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 6364 dm_pa += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 6365 } 6366 6367 /* 6368 * Update fru vpd image. 6369 * 6370 * @param[in] fru - fru structure 6371 * @param[in] buf - update data buffer 6372 * @param[in] len - data buffer length 6373 * @param[in] offset - offset relative to starting address 6374 * @param[in] cbfn - callback function 6375 * @param[in] cbarg - callback argument 6376 * 6377 * Return status. 6378 */ 6379 bfa_status_t 6380 bfa_fruvpd_update(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, 6381 bfa_cb_fru_t cbfn, void *cbarg, u8 trfr_cmpl) 6382 { 6383 bfa_trc(fru, BFI_FRUVPD_H2I_WRITE_REQ); 6384 bfa_trc(fru, len); 6385 bfa_trc(fru, offset); 6386 6387 if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2 && 6388 fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2) 6389 return BFA_STATUS_FRU_NOT_PRESENT; 6390 6391 if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK) 6392 return BFA_STATUS_CMD_NOTSUPP; 6393 6394 if (!bfa_ioc_is_operational(fru->ioc)) 6395 return BFA_STATUS_IOC_NON_OP; 6396 6397 if (fru->op_busy) { 6398 bfa_trc(fru, fru->op_busy); 6399 return BFA_STATUS_DEVBUSY; 6400 } 6401 6402 fru->op_busy = 1; 6403 6404 fru->cbfn = cbfn; 6405 fru->cbarg = cbarg; 6406 fru->residue = len; 6407 fru->offset = 0; 6408 fru->addr_off = offset; 6409 fru->ubuf = buf; 6410 fru->trfr_cmpl = trfr_cmpl; 6411 6412 bfa_fru_write_send(fru, BFI_FRUVPD_H2I_WRITE_REQ); 6413 6414 return BFA_STATUS_OK; 6415 } 6416 6417 /* 6418 * Read fru vpd image. 6419 * 6420 * @param[in] fru - fru structure 6421 * @param[in] buf - read data buffer 6422 * @param[in] len - data buffer length 6423 * @param[in] offset - offset relative to starting address 6424 * @param[in] cbfn - callback function 6425 * @param[in] cbarg - callback argument 6426 * 6427 * Return status. 6428 */ 6429 bfa_status_t 6430 bfa_fruvpd_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, 6431 bfa_cb_fru_t cbfn, void *cbarg) 6432 { 6433 bfa_trc(fru, BFI_FRUVPD_H2I_READ_REQ); 6434 bfa_trc(fru, len); 6435 bfa_trc(fru, offset); 6436 6437 if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) 6438 return BFA_STATUS_FRU_NOT_PRESENT; 6439 6440 if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK && 6441 fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2) 6442 return BFA_STATUS_CMD_NOTSUPP; 6443 6444 if (!bfa_ioc_is_operational(fru->ioc)) 6445 return BFA_STATUS_IOC_NON_OP; 6446 6447 if (fru->op_busy) { 6448 bfa_trc(fru, fru->op_busy); 6449 return BFA_STATUS_DEVBUSY; 6450 } 6451 6452 fru->op_busy = 1; 6453 6454 fru->cbfn = cbfn; 6455 fru->cbarg = cbarg; 6456 fru->residue = len; 6457 fru->offset = 0; 6458 fru->addr_off = offset; 6459 fru->ubuf = buf; 6460 bfa_fru_read_send(fru, BFI_FRUVPD_H2I_READ_REQ); 6461 6462 return BFA_STATUS_OK; 6463 } 6464 6465 /* 6466 * Get maximum size fru vpd image. 6467 * 6468 * @param[in] fru - fru structure 6469 * @param[out] size - maximum size of fru vpd data 6470 * 6471 * Return status. 6472 */ 6473 bfa_status_t 6474 bfa_fruvpd_get_max_size(struct bfa_fru_s *fru, u32 *max_size) 6475 { 6476 if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) 6477 return BFA_STATUS_FRU_NOT_PRESENT; 6478 6479 if (!bfa_ioc_is_operational(fru->ioc)) 6480 return BFA_STATUS_IOC_NON_OP; 6481 6482 if (fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK || 6483 fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK2) 6484 *max_size = BFA_FRU_CHINOOK_MAX_SIZE; 6485 else 6486 return BFA_STATUS_CMD_NOTSUPP; 6487 return BFA_STATUS_OK; 6488 } 6489 /* 6490 * tfru write. 6491 * 6492 * @param[in] fru - fru structure 6493 * @param[in] buf - update data buffer 6494 * @param[in] len - data buffer length 6495 * @param[in] offset - offset relative to starting address 6496 * @param[in] cbfn - callback function 6497 * @param[in] cbarg - callback argument 6498 * 6499 * Return status. 6500 */ 6501 bfa_status_t 6502 bfa_tfru_write(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, 6503 bfa_cb_fru_t cbfn, void *cbarg) 6504 { 6505 bfa_trc(fru, BFI_TFRU_H2I_WRITE_REQ); 6506 bfa_trc(fru, len); 6507 bfa_trc(fru, offset); 6508 bfa_trc(fru, *((u8 *) buf)); 6509 6510 if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) 6511 return BFA_STATUS_FRU_NOT_PRESENT; 6512 6513 if (!bfa_ioc_is_operational(fru->ioc)) 6514 return BFA_STATUS_IOC_NON_OP; 6515 6516 if (fru->op_busy) { 6517 bfa_trc(fru, fru->op_busy); 6518 return BFA_STATUS_DEVBUSY; 6519 } 6520 6521 fru->op_busy = 1; 6522 6523 fru->cbfn = cbfn; 6524 fru->cbarg = cbarg; 6525 fru->residue = len; 6526 fru->offset = 0; 6527 fru->addr_off = offset; 6528 fru->ubuf = buf; 6529 6530 bfa_fru_write_send(fru, BFI_TFRU_H2I_WRITE_REQ); 6531 6532 return BFA_STATUS_OK; 6533 } 6534 6535 /* 6536 * tfru read. 6537 * 6538 * @param[in] fru - fru structure 6539 * @param[in] buf - read data buffer 6540 * @param[in] len - data buffer length 6541 * @param[in] offset - offset relative to starting address 6542 * @param[in] cbfn - callback function 6543 * @param[in] cbarg - callback argument 6544 * 6545 * Return status. 6546 */ 6547 bfa_status_t 6548 bfa_tfru_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, 6549 bfa_cb_fru_t cbfn, void *cbarg) 6550 { 6551 bfa_trc(fru, BFI_TFRU_H2I_READ_REQ); 6552 bfa_trc(fru, len); 6553 bfa_trc(fru, offset); 6554 6555 if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) 6556 return BFA_STATUS_FRU_NOT_PRESENT; 6557 6558 if (!bfa_ioc_is_operational(fru->ioc)) 6559 return BFA_STATUS_IOC_NON_OP; 6560 6561 if (fru->op_busy) { 6562 bfa_trc(fru, fru->op_busy); 6563 return BFA_STATUS_DEVBUSY; 6564 } 6565 6566 fru->op_busy = 1; 6567 6568 fru->cbfn = cbfn; 6569 fru->cbarg = cbarg; 6570 fru->residue = len; 6571 fru->offset = 0; 6572 fru->addr_off = offset; 6573 fru->ubuf = buf; 6574 bfa_fru_read_send(fru, BFI_TFRU_H2I_READ_REQ); 6575 6576 return BFA_STATUS_OK; 6577 } 6578 6579 /* 6580 * Process fru response messages upon receiving interrupts. 6581 * 6582 * @param[in] fruarg - fru structure 6583 * @param[in] msg - message structure 6584 */ 6585 void 6586 bfa_fru_intr(void *fruarg, struct bfi_mbmsg_s *msg) 6587 { 6588 struct bfa_fru_s *fru = fruarg; 6589 struct bfi_fru_rsp_s *rsp = (struct bfi_fru_rsp_s *)msg; 6590 u32 status; 6591 6592 bfa_trc(fru, msg->mh.msg_id); 6593 6594 if (!fru->op_busy) { 6595 /* 6596 * receiving response after ioc failure 6597 */ 6598 bfa_trc(fru, 0x9999); 6599 return; 6600 } 6601 6602 switch (msg->mh.msg_id) { 6603 case BFI_FRUVPD_I2H_WRITE_RSP: 6604 case BFI_TFRU_I2H_WRITE_RSP: 6605 status = be32_to_cpu(rsp->status); 6606 bfa_trc(fru, status); 6607 6608 if (status != BFA_STATUS_OK || fru->residue == 0) { 6609 fru->status = status; 6610 fru->op_busy = 0; 6611 if (fru->cbfn) 6612 fru->cbfn(fru->cbarg, fru->status); 6613 } else { 6614 bfa_trc(fru, fru->offset); 6615 if (msg->mh.msg_id == BFI_FRUVPD_I2H_WRITE_RSP) 6616 bfa_fru_write_send(fru, 6617 BFI_FRUVPD_H2I_WRITE_REQ); 6618 else 6619 bfa_fru_write_send(fru, 6620 BFI_TFRU_H2I_WRITE_REQ); 6621 } 6622 break; 6623 case BFI_FRUVPD_I2H_READ_RSP: 6624 case BFI_TFRU_I2H_READ_RSP: 6625 status = be32_to_cpu(rsp->status); 6626 bfa_trc(fru, status); 6627 6628 if (status != BFA_STATUS_OK) { 6629 fru->status = status; 6630 fru->op_busy = 0; 6631 if (fru->cbfn) 6632 fru->cbfn(fru->cbarg, fru->status); 6633 } else { 6634 u32 len = be32_to_cpu(rsp->length); 6635 6636 bfa_trc(fru, fru->offset); 6637 bfa_trc(fru, len); 6638 6639 memcpy(fru->ubuf + fru->offset, fru->dbuf_kva, len); 6640 fru->residue -= len; 6641 fru->offset += len; 6642 6643 if (fru->residue == 0) { 6644 fru->status = status; 6645 fru->op_busy = 0; 6646 if (fru->cbfn) 6647 fru->cbfn(fru->cbarg, fru->status); 6648 } else { 6649 if (msg->mh.msg_id == BFI_FRUVPD_I2H_READ_RSP) 6650 bfa_fru_read_send(fru, 6651 BFI_FRUVPD_H2I_READ_REQ); 6652 else 6653 bfa_fru_read_send(fru, 6654 BFI_TFRU_H2I_READ_REQ); 6655 } 6656 } 6657 break; 6658 default: 6659 WARN_ON(1); 6660 } 6661 } 6662 6663 /* 6664 * register definitions 6665 */ 6666 #define FLI_CMD_REG 0x0001d000 6667 #define FLI_RDDATA_REG 0x0001d010 6668 #define FLI_ADDR_REG 0x0001d004 6669 #define FLI_DEV_STATUS_REG 0x0001d014 6670 6671 #define BFA_FLASH_FIFO_SIZE 128 /* fifo size */ 6672 #define BFA_FLASH_CHECK_MAX 10000 /* max # of status check */ 6673 #define BFA_FLASH_BLOCKING_OP_MAX 1000000 /* max # of blocking op check */ 6674 #define BFA_FLASH_WIP_MASK 0x01 /* write in progress bit mask */ 6675 6676 enum bfa_flash_cmd { 6677 BFA_FLASH_FAST_READ = 0x0b, /* fast read */ 6678 BFA_FLASH_READ_STATUS = 0x05, /* read status */ 6679 }; 6680 6681 /** 6682 * @brief hardware error definition 6683 */ 6684 enum bfa_flash_err { 6685 BFA_FLASH_NOT_PRESENT = -1, /*!< flash not present */ 6686 BFA_FLASH_UNINIT = -2, /*!< flash not initialized */ 6687 BFA_FLASH_BAD = -3, /*!< flash bad */ 6688 BFA_FLASH_BUSY = -4, /*!< flash busy */ 6689 BFA_FLASH_ERR_CMD_ACT = -5, /*!< command active never cleared */ 6690 BFA_FLASH_ERR_FIFO_CNT = -6, /*!< fifo count never cleared */ 6691 BFA_FLASH_ERR_WIP = -7, /*!< write-in-progress never cleared */ 6692 BFA_FLASH_ERR_TIMEOUT = -8, /*!< fli timeout */ 6693 BFA_FLASH_ERR_LEN = -9, /*!< invalid length */ 6694 }; 6695 6696 /** 6697 * @brief flash command register data structure 6698 */ 6699 union bfa_flash_cmd_reg_u { 6700 struct { 6701 #ifdef __BIG_ENDIAN 6702 u32 act:1; 6703 u32 rsv:1; 6704 u32 write_cnt:9; 6705 u32 read_cnt:9; 6706 u32 addr_cnt:4; 6707 u32 cmd:8; 6708 #else 6709 u32 cmd:8; 6710 u32 addr_cnt:4; 6711 u32 read_cnt:9; 6712 u32 write_cnt:9; 6713 u32 rsv:1; 6714 u32 act:1; 6715 #endif 6716 } r; 6717 u32 i; 6718 }; 6719 6720 /** 6721 * @brief flash device status register data structure 6722 */ 6723 union bfa_flash_dev_status_reg_u { 6724 struct { 6725 #ifdef __BIG_ENDIAN 6726 u32 rsv:21; 6727 u32 fifo_cnt:6; 6728 u32 busy:1; 6729 u32 init_status:1; 6730 u32 present:1; 6731 u32 bad:1; 6732 u32 good:1; 6733 #else 6734 u32 good:1; 6735 u32 bad:1; 6736 u32 present:1; 6737 u32 init_status:1; 6738 u32 busy:1; 6739 u32 fifo_cnt:6; 6740 u32 rsv:21; 6741 #endif 6742 } r; 6743 u32 i; 6744 }; 6745 6746 /** 6747 * @brief flash address register data structure 6748 */ 6749 union bfa_flash_addr_reg_u { 6750 struct { 6751 #ifdef __BIG_ENDIAN 6752 u32 addr:24; 6753 u32 dummy:8; 6754 #else 6755 u32 dummy:8; 6756 u32 addr:24; 6757 #endif 6758 } r; 6759 u32 i; 6760 }; 6761 6762 /** 6763 * dg flash_raw_private Flash raw private functions 6764 */ 6765 static void 6766 bfa_flash_set_cmd(void __iomem *pci_bar, u8 wr_cnt, 6767 u8 rd_cnt, u8 ad_cnt, u8 op) 6768 { 6769 union bfa_flash_cmd_reg_u cmd; 6770 6771 cmd.i = 0; 6772 cmd.r.act = 1; 6773 cmd.r.write_cnt = wr_cnt; 6774 cmd.r.read_cnt = rd_cnt; 6775 cmd.r.addr_cnt = ad_cnt; 6776 cmd.r.cmd = op; 6777 writel(cmd.i, (pci_bar + FLI_CMD_REG)); 6778 } 6779 6780 static void 6781 bfa_flash_set_addr(void __iomem *pci_bar, u32 address) 6782 { 6783 union bfa_flash_addr_reg_u addr; 6784 6785 addr.r.addr = address & 0x00ffffff; 6786 addr.r.dummy = 0; 6787 writel(addr.i, (pci_bar + FLI_ADDR_REG)); 6788 } 6789 6790 static int 6791 bfa_flash_cmd_act_check(void __iomem *pci_bar) 6792 { 6793 union bfa_flash_cmd_reg_u cmd; 6794 6795 cmd.i = readl(pci_bar + FLI_CMD_REG); 6796 6797 if (cmd.r.act) 6798 return BFA_FLASH_ERR_CMD_ACT; 6799 6800 return 0; 6801 } 6802 6803 /** 6804 * @brief 6805 * Flush FLI data fifo. 6806 * 6807 * @param[in] pci_bar - pci bar address 6808 * @param[in] dev_status - device status 6809 * 6810 * Return 0 on success, negative error number on error. 6811 */ 6812 static u32 6813 bfa_flash_fifo_flush(void __iomem *pci_bar) 6814 { 6815 u32 i; 6816 u32 t; 6817 union bfa_flash_dev_status_reg_u dev_status; 6818 6819 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG); 6820 6821 if (!dev_status.r.fifo_cnt) 6822 return 0; 6823 6824 /* fifo counter in terms of words */ 6825 for (i = 0; i < dev_status.r.fifo_cnt; i++) 6826 t = readl(pci_bar + FLI_RDDATA_REG); 6827 6828 /* 6829 * Check the device status. It may take some time. 6830 */ 6831 for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) { 6832 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG); 6833 if (!dev_status.r.fifo_cnt) 6834 break; 6835 } 6836 6837 if (dev_status.r.fifo_cnt) 6838 return BFA_FLASH_ERR_FIFO_CNT; 6839 6840 return 0; 6841 } 6842 6843 /** 6844 * @brief 6845 * Read flash status. 6846 * 6847 * @param[in] pci_bar - pci bar address 6848 * 6849 * Return 0 on success, negative error number on error. 6850 */ 6851 static u32 6852 bfa_flash_status_read(void __iomem *pci_bar) 6853 { 6854 union bfa_flash_dev_status_reg_u dev_status; 6855 int status; 6856 u32 ret_status; 6857 int i; 6858 6859 status = bfa_flash_fifo_flush(pci_bar); 6860 if (status < 0) 6861 return status; 6862 6863 bfa_flash_set_cmd(pci_bar, 0, 4, 0, BFA_FLASH_READ_STATUS); 6864 6865 for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) { 6866 status = bfa_flash_cmd_act_check(pci_bar); 6867 if (!status) 6868 break; 6869 } 6870 6871 if (status) 6872 return status; 6873 6874 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG); 6875 if (!dev_status.r.fifo_cnt) 6876 return BFA_FLASH_BUSY; 6877 6878 ret_status = readl(pci_bar + FLI_RDDATA_REG); 6879 ret_status >>= 24; 6880 6881 status = bfa_flash_fifo_flush(pci_bar); 6882 if (status < 0) 6883 return status; 6884 6885 return ret_status; 6886 } 6887 6888 /** 6889 * @brief 6890 * Start flash read operation. 6891 * 6892 * @param[in] pci_bar - pci bar address 6893 * @param[in] offset - flash address offset 6894 * @param[in] len - read data length 6895 * @param[in] buf - read data buffer 6896 * 6897 * Return 0 on success, negative error number on error. 6898 */ 6899 static u32 6900 bfa_flash_read_start(void __iomem *pci_bar, u32 offset, u32 len, 6901 char *buf) 6902 { 6903 int status; 6904 6905 /* 6906 * len must be mutiple of 4 and not exceeding fifo size 6907 */ 6908 if (len == 0 || len > BFA_FLASH_FIFO_SIZE || (len & 0x03) != 0) 6909 return BFA_FLASH_ERR_LEN; 6910 6911 /* 6912 * check status 6913 */ 6914 status = bfa_flash_status_read(pci_bar); 6915 if (status == BFA_FLASH_BUSY) 6916 status = bfa_flash_status_read(pci_bar); 6917 6918 if (status < 0) 6919 return status; 6920 6921 /* 6922 * check if write-in-progress bit is cleared 6923 */ 6924 if (status & BFA_FLASH_WIP_MASK) 6925 return BFA_FLASH_ERR_WIP; 6926 6927 bfa_flash_set_addr(pci_bar, offset); 6928 6929 bfa_flash_set_cmd(pci_bar, 0, (u8)len, 4, BFA_FLASH_FAST_READ); 6930 6931 return 0; 6932 } 6933 6934 /** 6935 * @brief 6936 * Check flash read operation. 6937 * 6938 * @param[in] pci_bar - pci bar address 6939 * 6940 * Return flash device status, 1 if busy, 0 if not. 6941 */ 6942 static u32 6943 bfa_flash_read_check(void __iomem *pci_bar) 6944 { 6945 if (bfa_flash_cmd_act_check(pci_bar)) 6946 return 1; 6947 6948 return 0; 6949 } 6950 /** 6951 * @brief 6952 * End flash read operation. 6953 * 6954 * @param[in] pci_bar - pci bar address 6955 * @param[in] len - read data length 6956 * @param[in] buf - read data buffer 6957 * 6958 */ 6959 static void 6960 bfa_flash_read_end(void __iomem *pci_bar, u32 len, char *buf) 6961 { 6962 6963 u32 i; 6964 6965 /* 6966 * read data fifo up to 32 words 6967 */ 6968 for (i = 0; i < len; i += 4) { 6969 u32 w = readl(pci_bar + FLI_RDDATA_REG); 6970 *((u32 *) (buf + i)) = swab32(w); 6971 } 6972 6973 bfa_flash_fifo_flush(pci_bar); 6974 } 6975 6976 /** 6977 * @brief 6978 * Perform flash raw read. 6979 * 6980 * @param[in] pci_bar - pci bar address 6981 * @param[in] offset - flash partition address offset 6982 * @param[in] buf - read data buffer 6983 * @param[in] len - read data length 6984 * 6985 * Return status. 6986 */ 6987 6988 6989 #define FLASH_BLOCKING_OP_MAX 500 6990 #define FLASH_SEM_LOCK_REG 0x18820 6991 6992 static int 6993 bfa_raw_sem_get(void __iomem *bar) 6994 { 6995 int locked; 6996 6997 locked = readl((bar + FLASH_SEM_LOCK_REG)); 6998 return !locked; 6999 7000 } 7001 7002 bfa_status_t 7003 bfa_flash_sem_get(void __iomem *bar) 7004 { 7005 u32 n = FLASH_BLOCKING_OP_MAX; 7006 7007 while (!bfa_raw_sem_get(bar)) { 7008 if (--n <= 0) 7009 return BFA_STATUS_BADFLASH; 7010 mdelay(10); 7011 } 7012 return BFA_STATUS_OK; 7013 } 7014 7015 void 7016 bfa_flash_sem_put(void __iomem *bar) 7017 { 7018 writel(0, (bar + FLASH_SEM_LOCK_REG)); 7019 } 7020 7021 bfa_status_t 7022 bfa_flash_raw_read(void __iomem *pci_bar, u32 offset, char *buf, 7023 u32 len) 7024 { 7025 u32 n; 7026 int status; 7027 u32 off, l, s, residue, fifo_sz; 7028 7029 residue = len; 7030 off = 0; 7031 fifo_sz = BFA_FLASH_FIFO_SIZE; 7032 status = bfa_flash_sem_get(pci_bar); 7033 if (status != BFA_STATUS_OK) 7034 return status; 7035 7036 while (residue) { 7037 s = offset + off; 7038 n = s / fifo_sz; 7039 l = (n + 1) * fifo_sz - s; 7040 if (l > residue) 7041 l = residue; 7042 7043 status = bfa_flash_read_start(pci_bar, offset + off, l, 7044 &buf[off]); 7045 if (status < 0) { 7046 bfa_flash_sem_put(pci_bar); 7047 return BFA_STATUS_FAILED; 7048 } 7049 7050 n = BFA_FLASH_BLOCKING_OP_MAX; 7051 while (bfa_flash_read_check(pci_bar)) { 7052 if (--n <= 0) { 7053 bfa_flash_sem_put(pci_bar); 7054 return BFA_STATUS_FAILED; 7055 } 7056 } 7057 7058 bfa_flash_read_end(pci_bar, l, &buf[off]); 7059 7060 residue -= l; 7061 off += l; 7062 } 7063 bfa_flash_sem_put(pci_bar); 7064 7065 return BFA_STATUS_OK; 7066 } 7067