bfa_ioc.c (79107B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Linux network driver for QLogic BR-series Converged Network Adapter. 4 */ 5/* 6 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. 7 * Copyright (c) 2014-2015 QLogic Corporation 8 * All rights reserved 9 * www.qlogic.com 10 */ 11 12#include "bfa_ioc.h" 13#include "bfi_reg.h" 14#include "bfa_defs.h" 15 16/* IOC local definitions */ 17 18/* Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details. */ 19 20#define bfa_ioc_firmware_lock(__ioc) \ 21 ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc)) 22#define bfa_ioc_firmware_unlock(__ioc) \ 23 ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc)) 24#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc)) 25#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc)) 26#define bfa_ioc_notify_fail(__ioc) \ 27 ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc)) 28#define bfa_ioc_sync_start(__ioc) \ 29 ((__ioc)->ioc_hwif->ioc_sync_start(__ioc)) 30#define bfa_ioc_sync_join(__ioc) \ 31 ((__ioc)->ioc_hwif->ioc_sync_join(__ioc)) 32#define bfa_ioc_sync_leave(__ioc) \ 33 ((__ioc)->ioc_hwif->ioc_sync_leave(__ioc)) 34#define bfa_ioc_sync_ack(__ioc) \ 35 ((__ioc)->ioc_hwif->ioc_sync_ack(__ioc)) 36#define bfa_ioc_sync_complete(__ioc) \ 37 ((__ioc)->ioc_hwif->ioc_sync_complete(__ioc)) 38#define bfa_ioc_set_cur_ioc_fwstate(__ioc, __fwstate) \ 39 ((__ioc)->ioc_hwif->ioc_set_fwstate(__ioc, __fwstate)) 40#define bfa_ioc_get_cur_ioc_fwstate(__ioc) \ 41 ((__ioc)->ioc_hwif->ioc_get_fwstate(__ioc)) 42#define bfa_ioc_set_alt_ioc_fwstate(__ioc, __fwstate) \ 43 ((__ioc)->ioc_hwif->ioc_set_alt_fwstate(__ioc, __fwstate)) 44 45static bool bfa_nw_auto_recover = true; 46 47/* 48 * forward declarations 49 */ 50static void bfa_ioc_hw_sem_init(struct bfa_ioc *ioc); 51static void bfa_ioc_hw_sem_get(struct bfa_ioc *ioc); 52static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc); 53static void bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force); 54static void bfa_ioc_poll_fwinit(struct bfa_ioc *ioc); 55static void bfa_ioc_send_enable(struct bfa_ioc *ioc); 56static void bfa_ioc_send_disable(struct bfa_ioc *ioc); 57static void bfa_ioc_send_getattr(struct bfa_ioc *ioc); 58static void bfa_ioc_hb_monitor(struct bfa_ioc *ioc); 59static void bfa_ioc_hb_stop(struct bfa_ioc *ioc); 60static void bfa_ioc_reset(struct bfa_ioc *ioc, bool force); 61static void bfa_ioc_mbox_poll(struct bfa_ioc *ioc); 62static void bfa_ioc_mbox_flush(struct bfa_ioc *ioc); 63static void bfa_ioc_recover(struct bfa_ioc *ioc); 64static void bfa_ioc_event_notify(struct bfa_ioc *, enum bfa_ioc_event); 65static void bfa_ioc_disable_comp(struct bfa_ioc *ioc); 66static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc); 67static void bfa_nw_ioc_debug_save_ftrc(struct bfa_ioc *ioc); 68static void bfa_ioc_fail_notify(struct bfa_ioc *ioc); 69static void bfa_ioc_pf_enabled(struct bfa_ioc *ioc); 70static void bfa_ioc_pf_disabled(struct bfa_ioc *ioc); 71static void bfa_ioc_pf_failed(struct bfa_ioc *ioc); 72static void bfa_ioc_pf_hwfailed(struct bfa_ioc *ioc); 73static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc); 74static enum bfa_status bfa_ioc_boot(struct bfa_ioc *ioc, 75 enum bfi_fwboot_type boot_type, u32 boot_param); 76static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr); 77static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, 78 char *serial_num); 79static void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, 80 char *fw_ver); 81static void bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, 82 char *chip_rev); 83static void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, 84 char *optrom_ver); 85static void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, 86 char *manufacturer); 87static void bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model); 88static u64 bfa_ioc_get_pwwn(struct bfa_ioc *ioc); 89 90/* IOC state machine definitions/declarations */ 91enum ioc_event { 92 IOC_E_RESET = 1, /*!< IOC reset request */ 93 IOC_E_ENABLE = 2, /*!< IOC enable request */ 94 IOC_E_DISABLE = 3, /*!< IOC disable request */ 95 IOC_E_DETACH = 4, /*!< driver detach cleanup */ 96 IOC_E_ENABLED = 5, /*!< f/w enabled */ 97 IOC_E_FWRSP_GETATTR = 6, /*!< IOC get attribute response */ 98 IOC_E_DISABLED = 7, /*!< f/w disabled */ 99 IOC_E_PFFAILED = 8, /*!< failure notice by iocpf sm */ 100 IOC_E_HBFAIL = 9, /*!< heartbeat failure */ 101 IOC_E_HWERROR = 10, /*!< hardware error interrupt */ 102 IOC_E_TIMEOUT = 11, /*!< timeout */ 103 IOC_E_HWFAILED = 12, /*!< PCI mapping failure notice */ 104}; 105 106bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc, enum ioc_event); 107bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc, enum ioc_event); 108bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc, enum ioc_event); 109bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc, enum ioc_event); 110bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc, enum ioc_event); 111bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc, enum ioc_event); 112bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc, enum ioc_event); 113bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc, enum ioc_event); 114bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc, enum ioc_event); 115bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc, enum ioc_event); 116 117static struct bfa_sm_table ioc_sm_table[] = { 118 {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT}, 119 {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET}, 120 {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING}, 121 {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR}, 122 {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL}, 123 {BFA_SM(bfa_ioc_sm_fail_retry), BFA_IOC_INITFAIL}, 124 {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL}, 125 {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, 126 {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, 127 {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL}, 128}; 129 130/* 131 * Forward declareations for iocpf state machine 132 */ 133static void bfa_iocpf_enable(struct bfa_ioc *ioc); 134static void bfa_iocpf_disable(struct bfa_ioc *ioc); 135static void bfa_iocpf_fail(struct bfa_ioc *ioc); 136static void bfa_iocpf_initfail(struct bfa_ioc *ioc); 137static void bfa_iocpf_getattrfail(struct bfa_ioc *ioc); 138static void bfa_iocpf_stop(struct bfa_ioc *ioc); 139 140/* IOCPF state machine events */ 141enum iocpf_event { 142 IOCPF_E_ENABLE = 1, /*!< IOCPF enable request */ 143 IOCPF_E_DISABLE = 2, /*!< IOCPF disable request */ 144 IOCPF_E_STOP = 3, /*!< stop on driver detach */ 145 IOCPF_E_FWREADY = 4, /*!< f/w initialization done */ 146 IOCPF_E_FWRSP_ENABLE = 5, /*!< enable f/w response */ 147 IOCPF_E_FWRSP_DISABLE = 6, /*!< disable f/w response */ 148 IOCPF_E_FAIL = 7, /*!< failure notice by ioc sm */ 149 IOCPF_E_INITFAIL = 8, /*!< init fail notice by ioc sm */ 150 IOCPF_E_GETATTRFAIL = 9, /*!< init fail notice by ioc sm */ 151 IOCPF_E_SEMLOCKED = 10, /*!< h/w semaphore is locked */ 152 IOCPF_E_TIMEOUT = 11, /*!< f/w response timeout */ 153 IOCPF_E_SEM_ERROR = 12, /*!< h/w sem mapping error */ 154}; 155 156/* IOCPF states */ 157enum bfa_iocpf_state { 158 BFA_IOCPF_RESET = 1, /*!< IOC is in reset state */ 159 BFA_IOCPF_SEMWAIT = 2, /*!< Waiting for IOC h/w semaphore */ 160 BFA_IOCPF_HWINIT = 3, /*!< IOC h/w is being initialized */ 161 BFA_IOCPF_READY = 4, /*!< IOCPF is initialized */ 162 BFA_IOCPF_INITFAIL = 5, /*!< IOCPF failed */ 163 BFA_IOCPF_FAIL = 6, /*!< IOCPF failed */ 164 BFA_IOCPF_DISABLING = 7, /*!< IOCPF is being disabled */ 165 BFA_IOCPF_DISABLED = 8, /*!< IOCPF is disabled */ 166 BFA_IOCPF_FWMISMATCH = 9, /*!< IOC f/w different from drivers */ 167}; 168 169bfa_fsm_state_decl(bfa_iocpf, reset, struct bfa_iocpf, enum iocpf_event); 170bfa_fsm_state_decl(bfa_iocpf, fwcheck, struct bfa_iocpf, enum iocpf_event); 171bfa_fsm_state_decl(bfa_iocpf, mismatch, struct bfa_iocpf, enum iocpf_event); 172bfa_fsm_state_decl(bfa_iocpf, semwait, struct bfa_iocpf, enum iocpf_event); 173bfa_fsm_state_decl(bfa_iocpf, hwinit, struct bfa_iocpf, enum iocpf_event); 174bfa_fsm_state_decl(bfa_iocpf, enabling, struct bfa_iocpf, enum iocpf_event); 175bfa_fsm_state_decl(bfa_iocpf, ready, struct bfa_iocpf, enum iocpf_event); 176bfa_fsm_state_decl(bfa_iocpf, initfail_sync, struct bfa_iocpf, 177 enum iocpf_event); 178bfa_fsm_state_decl(bfa_iocpf, initfail, struct bfa_iocpf, enum iocpf_event); 179bfa_fsm_state_decl(bfa_iocpf, fail_sync, struct bfa_iocpf, enum iocpf_event); 180bfa_fsm_state_decl(bfa_iocpf, fail, struct bfa_iocpf, enum iocpf_event); 181bfa_fsm_state_decl(bfa_iocpf, disabling, struct bfa_iocpf, enum iocpf_event); 182bfa_fsm_state_decl(bfa_iocpf, disabling_sync, struct bfa_iocpf, 183 enum iocpf_event); 184bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf, enum iocpf_event); 185 186static struct bfa_sm_table iocpf_sm_table[] = { 187 {BFA_SM(bfa_iocpf_sm_reset), BFA_IOCPF_RESET}, 188 {BFA_SM(bfa_iocpf_sm_fwcheck), BFA_IOCPF_FWMISMATCH}, 189 {BFA_SM(bfa_iocpf_sm_mismatch), BFA_IOCPF_FWMISMATCH}, 190 {BFA_SM(bfa_iocpf_sm_semwait), BFA_IOCPF_SEMWAIT}, 191 {BFA_SM(bfa_iocpf_sm_hwinit), BFA_IOCPF_HWINIT}, 192 {BFA_SM(bfa_iocpf_sm_enabling), BFA_IOCPF_HWINIT}, 193 {BFA_SM(bfa_iocpf_sm_ready), BFA_IOCPF_READY}, 194 {BFA_SM(bfa_iocpf_sm_initfail_sync), BFA_IOCPF_INITFAIL}, 195 {BFA_SM(bfa_iocpf_sm_initfail), BFA_IOCPF_INITFAIL}, 196 {BFA_SM(bfa_iocpf_sm_fail_sync), BFA_IOCPF_FAIL}, 197 {BFA_SM(bfa_iocpf_sm_fail), BFA_IOCPF_FAIL}, 198 {BFA_SM(bfa_iocpf_sm_disabling), BFA_IOCPF_DISABLING}, 199 {BFA_SM(bfa_iocpf_sm_disabling_sync), BFA_IOCPF_DISABLING}, 200 {BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED}, 201}; 202 203/* IOC State Machine */ 204 205/* Beginning state. IOC uninit state. */ 206static void 207bfa_ioc_sm_uninit_entry(struct bfa_ioc *ioc) 208{ 209} 210 211/* IOC is in uninit state. */ 212static void 213bfa_ioc_sm_uninit(struct bfa_ioc *ioc, enum ioc_event event) 214{ 215 switch (event) { 216 case IOC_E_RESET: 217 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); 218 break; 219 220 default: 221 bfa_sm_fault(event); 222 } 223} 224 225/* Reset entry actions -- initialize state machine */ 226static void 227bfa_ioc_sm_reset_entry(struct bfa_ioc *ioc) 228{ 229 bfa_fsm_set_state(&ioc->iocpf, bfa_iocpf_sm_reset); 230} 231 232/* IOC is in reset state. */ 233static void 234bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event) 235{ 236 switch (event) { 237 case IOC_E_ENABLE: 238 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); 239 break; 240 241 case IOC_E_DISABLE: 242 bfa_ioc_disable_comp(ioc); 243 break; 244 245 case IOC_E_DETACH: 246 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 247 break; 248 249 default: 250 bfa_sm_fault(event); 251 } 252} 253 254static void 255bfa_ioc_sm_enabling_entry(struct bfa_ioc *ioc) 256{ 257 bfa_iocpf_enable(ioc); 258} 259 260/* Host IOC function is being enabled, awaiting response from firmware. 261 * Semaphore is acquired. 262 */ 263static void 264bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event) 265{ 266 switch (event) { 267 case IOC_E_ENABLED: 268 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); 269 break; 270 271 case IOC_E_PFFAILED: 272 fallthrough; 273 case IOC_E_HWERROR: 274 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 275 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 276 if (event != IOC_E_PFFAILED) 277 bfa_iocpf_initfail(ioc); 278 break; 279 280 case IOC_E_HWFAILED: 281 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 282 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail); 283 break; 284 285 case IOC_E_DISABLE: 286 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 287 break; 288 289 case IOC_E_DETACH: 290 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 291 bfa_iocpf_stop(ioc); 292 break; 293 294 case IOC_E_ENABLE: 295 break; 296 297 default: 298 bfa_sm_fault(event); 299 } 300} 301 302/* Semaphore should be acquired for version check. */ 303static void 304bfa_ioc_sm_getattr_entry(struct bfa_ioc *ioc) 305{ 306 mod_timer(&ioc->ioc_timer, jiffies + 307 msecs_to_jiffies(BFA_IOC_TOV)); 308 bfa_ioc_send_getattr(ioc); 309} 310 311/* IOC configuration in progress. Timer is active. */ 312static void 313bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event) 314{ 315 switch (event) { 316 case IOC_E_FWRSP_GETATTR: 317 del_timer(&ioc->ioc_timer); 318 bfa_fsm_set_state(ioc, bfa_ioc_sm_op); 319 break; 320 321 case IOC_E_PFFAILED: 322 case IOC_E_HWERROR: 323 del_timer(&ioc->ioc_timer); 324 fallthrough; 325 case IOC_E_TIMEOUT: 326 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 327 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 328 if (event != IOC_E_PFFAILED) 329 bfa_iocpf_getattrfail(ioc); 330 break; 331 332 case IOC_E_DISABLE: 333 del_timer(&ioc->ioc_timer); 334 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 335 break; 336 337 case IOC_E_ENABLE: 338 break; 339 340 default: 341 bfa_sm_fault(event); 342 } 343} 344 345static void 346bfa_ioc_sm_op_entry(struct bfa_ioc *ioc) 347{ 348 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); 349 bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED); 350 bfa_ioc_hb_monitor(ioc); 351} 352 353static void 354bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event) 355{ 356 switch (event) { 357 case IOC_E_ENABLE: 358 break; 359 360 case IOC_E_DISABLE: 361 bfa_ioc_hb_stop(ioc); 362 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 363 break; 364 365 case IOC_E_PFFAILED: 366 case IOC_E_HWERROR: 367 bfa_ioc_hb_stop(ioc); 368 fallthrough; 369 370 case IOC_E_HBFAIL: 371 if (ioc->iocpf.auto_recover) 372 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); 373 else 374 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 375 376 bfa_ioc_fail_notify(ioc); 377 378 if (event != IOC_E_PFFAILED) 379 bfa_iocpf_fail(ioc); 380 break; 381 382 default: 383 bfa_sm_fault(event); 384 } 385} 386 387static void 388bfa_ioc_sm_disabling_entry(struct bfa_ioc *ioc) 389{ 390 bfa_iocpf_disable(ioc); 391} 392 393/* IOC is being disabled */ 394static void 395bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event) 396{ 397 switch (event) { 398 case IOC_E_DISABLED: 399 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); 400 break; 401 402 case IOC_E_HWERROR: 403 /* 404 * No state change. Will move to disabled state 405 * after iocpf sm completes failure processing and 406 * moves to disabled state. 407 */ 408 bfa_iocpf_fail(ioc); 409 break; 410 411 case IOC_E_HWFAILED: 412 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail); 413 bfa_ioc_disable_comp(ioc); 414 break; 415 416 default: 417 bfa_sm_fault(event); 418 } 419} 420 421/* IOC disable completion entry. */ 422static void 423bfa_ioc_sm_disabled_entry(struct bfa_ioc *ioc) 424{ 425 bfa_ioc_disable_comp(ioc); 426} 427 428static void 429bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event) 430{ 431 switch (event) { 432 case IOC_E_ENABLE: 433 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); 434 break; 435 436 case IOC_E_DISABLE: 437 ioc->cbfn->disable_cbfn(ioc->bfa); 438 break; 439 440 case IOC_E_DETACH: 441 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 442 bfa_iocpf_stop(ioc); 443 break; 444 445 default: 446 bfa_sm_fault(event); 447 } 448} 449 450static void 451bfa_ioc_sm_fail_retry_entry(struct bfa_ioc *ioc) 452{ 453} 454 455/* Hardware initialization retry. */ 456static void 457bfa_ioc_sm_fail_retry(struct bfa_ioc *ioc, enum ioc_event event) 458{ 459 switch (event) { 460 case IOC_E_ENABLED: 461 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); 462 break; 463 464 case IOC_E_PFFAILED: 465 case IOC_E_HWERROR: 466 /** 467 * Initialization retry failed. 468 */ 469 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 470 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 471 if (event != IOC_E_PFFAILED) 472 bfa_iocpf_initfail(ioc); 473 break; 474 475 case IOC_E_HWFAILED: 476 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 477 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail); 478 break; 479 480 case IOC_E_ENABLE: 481 break; 482 483 case IOC_E_DISABLE: 484 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 485 break; 486 487 case IOC_E_DETACH: 488 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 489 bfa_iocpf_stop(ioc); 490 break; 491 492 default: 493 bfa_sm_fault(event); 494 } 495} 496 497static void 498bfa_ioc_sm_fail_entry(struct bfa_ioc *ioc) 499{ 500} 501 502/* IOC failure. */ 503static void 504bfa_ioc_sm_fail(struct bfa_ioc *ioc, enum ioc_event event) 505{ 506 switch (event) { 507 case IOC_E_ENABLE: 508 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 509 break; 510 511 case IOC_E_DISABLE: 512 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 513 break; 514 515 case IOC_E_DETACH: 516 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 517 bfa_iocpf_stop(ioc); 518 break; 519 520 case IOC_E_HWERROR: 521 /* HB failure notification, ignore. */ 522 break; 523 524 default: 525 bfa_sm_fault(event); 526 } 527} 528 529static void 530bfa_ioc_sm_hwfail_entry(struct bfa_ioc *ioc) 531{ 532} 533 534/* IOC failure. */ 535static void 536bfa_ioc_sm_hwfail(struct bfa_ioc *ioc, enum ioc_event event) 537{ 538 switch (event) { 539 540 case IOC_E_ENABLE: 541 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 542 break; 543 544 case IOC_E_DISABLE: 545 ioc->cbfn->disable_cbfn(ioc->bfa); 546 break; 547 548 case IOC_E_DETACH: 549 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 550 break; 551 552 default: 553 bfa_sm_fault(event); 554 } 555} 556 557/* IOCPF State Machine */ 558 559/* Reset entry actions -- initialize state machine */ 560static void 561bfa_iocpf_sm_reset_entry(struct bfa_iocpf *iocpf) 562{ 563 iocpf->fw_mismatch_notified = false; 564 iocpf->auto_recover = bfa_nw_auto_recover; 565} 566 567/* Beginning state. IOC is in reset state. */ 568static void 569bfa_iocpf_sm_reset(struct bfa_iocpf *iocpf, enum iocpf_event event) 570{ 571 switch (event) { 572 case IOCPF_E_ENABLE: 573 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck); 574 break; 575 576 case IOCPF_E_STOP: 577 break; 578 579 default: 580 bfa_sm_fault(event); 581 } 582} 583 584/* Semaphore should be acquired for version check. */ 585static void 586bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf *iocpf) 587{ 588 bfa_ioc_hw_sem_init(iocpf->ioc); 589 bfa_ioc_hw_sem_get(iocpf->ioc); 590} 591 592/* Awaiting h/w semaphore to continue with version check. */ 593static void 594bfa_iocpf_sm_fwcheck(struct bfa_iocpf *iocpf, enum iocpf_event event) 595{ 596 struct bfa_ioc *ioc = iocpf->ioc; 597 598 switch (event) { 599 case IOCPF_E_SEMLOCKED: 600 if (bfa_ioc_firmware_lock(ioc)) { 601 if (bfa_ioc_sync_start(ioc)) { 602 bfa_ioc_sync_join(ioc); 603 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 604 } else { 605 bfa_ioc_firmware_unlock(ioc); 606 bfa_nw_ioc_hw_sem_release(ioc); 607 mod_timer(&ioc->sem_timer, jiffies + 608 msecs_to_jiffies(BFA_IOC_HWSEM_TOV)); 609 } 610 } else { 611 bfa_nw_ioc_hw_sem_release(ioc); 612 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_mismatch); 613 } 614 break; 615 616 case IOCPF_E_SEM_ERROR: 617 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 618 bfa_ioc_pf_hwfailed(ioc); 619 break; 620 621 case IOCPF_E_DISABLE: 622 bfa_ioc_hw_sem_get_cancel(ioc); 623 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 624 bfa_ioc_pf_disabled(ioc); 625 break; 626 627 case IOCPF_E_STOP: 628 bfa_ioc_hw_sem_get_cancel(ioc); 629 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 630 break; 631 632 default: 633 bfa_sm_fault(event); 634 } 635} 636 637/* Notify enable completion callback */ 638static void 639bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf *iocpf) 640{ 641 /* Call only the first time sm enters fwmismatch state. */ 642 if (!iocpf->fw_mismatch_notified) 643 bfa_ioc_pf_fwmismatch(iocpf->ioc); 644 645 iocpf->fw_mismatch_notified = true; 646 mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies + 647 msecs_to_jiffies(BFA_IOC_TOV)); 648} 649 650/* Awaiting firmware version match. */ 651static void 652bfa_iocpf_sm_mismatch(struct bfa_iocpf *iocpf, enum iocpf_event event) 653{ 654 struct bfa_ioc *ioc = iocpf->ioc; 655 656 switch (event) { 657 case IOCPF_E_TIMEOUT: 658 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck); 659 break; 660 661 case IOCPF_E_DISABLE: 662 del_timer(&ioc->iocpf_timer); 663 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 664 bfa_ioc_pf_disabled(ioc); 665 break; 666 667 case IOCPF_E_STOP: 668 del_timer(&ioc->iocpf_timer); 669 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 670 break; 671 672 default: 673 bfa_sm_fault(event); 674 } 675} 676 677/* Request for semaphore. */ 678static void 679bfa_iocpf_sm_semwait_entry(struct bfa_iocpf *iocpf) 680{ 681 bfa_ioc_hw_sem_get(iocpf->ioc); 682} 683 684/* Awaiting semaphore for h/w initialzation. */ 685static void 686bfa_iocpf_sm_semwait(struct bfa_iocpf *iocpf, enum iocpf_event event) 687{ 688 struct bfa_ioc *ioc = iocpf->ioc; 689 690 switch (event) { 691 case IOCPF_E_SEMLOCKED: 692 if (bfa_ioc_sync_complete(ioc)) { 693 bfa_ioc_sync_join(ioc); 694 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 695 } else { 696 bfa_nw_ioc_hw_sem_release(ioc); 697 mod_timer(&ioc->sem_timer, jiffies + 698 msecs_to_jiffies(BFA_IOC_HWSEM_TOV)); 699 } 700 break; 701 702 case IOCPF_E_SEM_ERROR: 703 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 704 bfa_ioc_pf_hwfailed(ioc); 705 break; 706 707 case IOCPF_E_DISABLE: 708 bfa_ioc_hw_sem_get_cancel(ioc); 709 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 710 break; 711 712 default: 713 bfa_sm_fault(event); 714 } 715} 716 717static void 718bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf *iocpf) 719{ 720 iocpf->poll_time = 0; 721 bfa_ioc_reset(iocpf->ioc, false); 722} 723 724/* Hardware is being initialized. Interrupts are enabled. 725 * Holding hardware semaphore lock. 726 */ 727static void 728bfa_iocpf_sm_hwinit(struct bfa_iocpf *iocpf, enum iocpf_event event) 729{ 730 struct bfa_ioc *ioc = iocpf->ioc; 731 732 switch (event) { 733 case IOCPF_E_FWREADY: 734 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling); 735 break; 736 737 case IOCPF_E_TIMEOUT: 738 bfa_nw_ioc_hw_sem_release(ioc); 739 bfa_ioc_pf_failed(ioc); 740 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 741 break; 742 743 case IOCPF_E_DISABLE: 744 del_timer(&ioc->iocpf_timer); 745 bfa_ioc_sync_leave(ioc); 746 bfa_nw_ioc_hw_sem_release(ioc); 747 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 748 break; 749 750 default: 751 bfa_sm_fault(event); 752 } 753} 754 755static void 756bfa_iocpf_sm_enabling_entry(struct bfa_iocpf *iocpf) 757{ 758 mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies + 759 msecs_to_jiffies(BFA_IOC_TOV)); 760 /** 761 * Enable Interrupts before sending fw IOC ENABLE cmd. 762 */ 763 iocpf->ioc->cbfn->reset_cbfn(iocpf->ioc->bfa); 764 bfa_ioc_send_enable(iocpf->ioc); 765} 766 767/* Host IOC function is being enabled, awaiting response from firmware. 768 * Semaphore is acquired. 769 */ 770static void 771bfa_iocpf_sm_enabling(struct bfa_iocpf *iocpf, enum iocpf_event event) 772{ 773 struct bfa_ioc *ioc = iocpf->ioc; 774 775 switch (event) { 776 case IOCPF_E_FWRSP_ENABLE: 777 del_timer(&ioc->iocpf_timer); 778 bfa_nw_ioc_hw_sem_release(ioc); 779 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready); 780 break; 781 782 case IOCPF_E_INITFAIL: 783 del_timer(&ioc->iocpf_timer); 784 fallthrough; 785 786 case IOCPF_E_TIMEOUT: 787 bfa_nw_ioc_hw_sem_release(ioc); 788 if (event == IOCPF_E_TIMEOUT) 789 bfa_ioc_pf_failed(ioc); 790 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 791 break; 792 793 case IOCPF_E_DISABLE: 794 del_timer(&ioc->iocpf_timer); 795 bfa_nw_ioc_hw_sem_release(ioc); 796 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling); 797 break; 798 799 default: 800 bfa_sm_fault(event); 801 } 802} 803 804static void 805bfa_iocpf_sm_ready_entry(struct bfa_iocpf *iocpf) 806{ 807 bfa_ioc_pf_enabled(iocpf->ioc); 808} 809 810static void 811bfa_iocpf_sm_ready(struct bfa_iocpf *iocpf, enum iocpf_event event) 812{ 813 switch (event) { 814 case IOCPF_E_DISABLE: 815 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling); 816 break; 817 818 case IOCPF_E_GETATTRFAIL: 819 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 820 break; 821 822 case IOCPF_E_FAIL: 823 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync); 824 break; 825 826 default: 827 bfa_sm_fault(event); 828 } 829} 830 831static void 832bfa_iocpf_sm_disabling_entry(struct bfa_iocpf *iocpf) 833{ 834 mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies + 835 msecs_to_jiffies(BFA_IOC_TOV)); 836 bfa_ioc_send_disable(iocpf->ioc); 837} 838 839/* IOC is being disabled */ 840static void 841bfa_iocpf_sm_disabling(struct bfa_iocpf *iocpf, enum iocpf_event event) 842{ 843 struct bfa_ioc *ioc = iocpf->ioc; 844 845 switch (event) { 846 case IOCPF_E_FWRSP_DISABLE: 847 del_timer(&ioc->iocpf_timer); 848 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 849 break; 850 851 case IOCPF_E_FAIL: 852 del_timer(&ioc->iocpf_timer); 853 fallthrough; 854 855 case IOCPF_E_TIMEOUT: 856 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL); 857 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 858 break; 859 860 case IOCPF_E_FWRSP_ENABLE: 861 break; 862 863 default: 864 bfa_sm_fault(event); 865 } 866} 867 868static void 869bfa_iocpf_sm_disabling_sync_entry(struct bfa_iocpf *iocpf) 870{ 871 bfa_ioc_hw_sem_get(iocpf->ioc); 872} 873 874/* IOC hb ack request is being removed. */ 875static void 876bfa_iocpf_sm_disabling_sync(struct bfa_iocpf *iocpf, enum iocpf_event event) 877{ 878 struct bfa_ioc *ioc = iocpf->ioc; 879 880 switch (event) { 881 case IOCPF_E_SEMLOCKED: 882 bfa_ioc_sync_leave(ioc); 883 bfa_nw_ioc_hw_sem_release(ioc); 884 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 885 break; 886 887 case IOCPF_E_SEM_ERROR: 888 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 889 bfa_ioc_pf_hwfailed(ioc); 890 break; 891 892 case IOCPF_E_FAIL: 893 break; 894 895 default: 896 bfa_sm_fault(event); 897 } 898} 899 900/* IOC disable completion entry. */ 901static void 902bfa_iocpf_sm_disabled_entry(struct bfa_iocpf *iocpf) 903{ 904 bfa_ioc_mbox_flush(iocpf->ioc); 905 bfa_ioc_pf_disabled(iocpf->ioc); 906} 907 908static void 909bfa_iocpf_sm_disabled(struct bfa_iocpf *iocpf, enum iocpf_event event) 910{ 911 struct bfa_ioc *ioc = iocpf->ioc; 912 913 switch (event) { 914 case IOCPF_E_ENABLE: 915 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); 916 break; 917 918 case IOCPF_E_STOP: 919 bfa_ioc_firmware_unlock(ioc); 920 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 921 break; 922 923 default: 924 bfa_sm_fault(event); 925 } 926} 927 928static void 929bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf *iocpf) 930{ 931 bfa_nw_ioc_debug_save_ftrc(iocpf->ioc); 932 bfa_ioc_hw_sem_get(iocpf->ioc); 933} 934 935/* Hardware initialization failed. */ 936static void 937bfa_iocpf_sm_initfail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event) 938{ 939 struct bfa_ioc *ioc = iocpf->ioc; 940 941 switch (event) { 942 case IOCPF_E_SEMLOCKED: 943 bfa_ioc_notify_fail(ioc); 944 bfa_ioc_sync_leave(ioc); 945 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL); 946 bfa_nw_ioc_hw_sem_release(ioc); 947 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); 948 break; 949 950 case IOCPF_E_SEM_ERROR: 951 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 952 bfa_ioc_pf_hwfailed(ioc); 953 break; 954 955 case IOCPF_E_DISABLE: 956 bfa_ioc_hw_sem_get_cancel(ioc); 957 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 958 break; 959 960 case IOCPF_E_STOP: 961 bfa_ioc_hw_sem_get_cancel(ioc); 962 bfa_ioc_firmware_unlock(ioc); 963 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 964 break; 965 966 case IOCPF_E_FAIL: 967 break; 968 969 default: 970 bfa_sm_fault(event); 971 } 972} 973 974static void 975bfa_iocpf_sm_initfail_entry(struct bfa_iocpf *iocpf) 976{ 977} 978 979/* Hardware initialization failed. */ 980static void 981bfa_iocpf_sm_initfail(struct bfa_iocpf *iocpf, enum iocpf_event event) 982{ 983 struct bfa_ioc *ioc = iocpf->ioc; 984 985 switch (event) { 986 case IOCPF_E_DISABLE: 987 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 988 break; 989 990 case IOCPF_E_STOP: 991 bfa_ioc_firmware_unlock(ioc); 992 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 993 break; 994 995 default: 996 bfa_sm_fault(event); 997 } 998} 999 1000static void 1001bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf *iocpf) 1002{ 1003 /** 1004 * Mark IOC as failed in hardware and stop firmware. 1005 */ 1006 bfa_ioc_lpu_stop(iocpf->ioc); 1007 1008 /** 1009 * Flush any queued up mailbox requests. 1010 */ 1011 bfa_ioc_mbox_flush(iocpf->ioc); 1012 bfa_ioc_hw_sem_get(iocpf->ioc); 1013} 1014 1015/* IOC is in failed state. */ 1016static void 1017bfa_iocpf_sm_fail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event) 1018{ 1019 struct bfa_ioc *ioc = iocpf->ioc; 1020 1021 switch (event) { 1022 case IOCPF_E_SEMLOCKED: 1023 bfa_ioc_sync_ack(ioc); 1024 bfa_ioc_notify_fail(ioc); 1025 if (!iocpf->auto_recover) { 1026 bfa_ioc_sync_leave(ioc); 1027 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL); 1028 bfa_nw_ioc_hw_sem_release(ioc); 1029 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 1030 } else { 1031 if (bfa_ioc_sync_complete(ioc)) 1032 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 1033 else { 1034 bfa_nw_ioc_hw_sem_release(ioc); 1035 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); 1036 } 1037 } 1038 break; 1039 1040 case IOCPF_E_SEM_ERROR: 1041 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 1042 bfa_ioc_pf_hwfailed(ioc); 1043 break; 1044 1045 case IOCPF_E_DISABLE: 1046 bfa_ioc_hw_sem_get_cancel(ioc); 1047 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 1048 break; 1049 1050 case IOCPF_E_FAIL: 1051 break; 1052 1053 default: 1054 bfa_sm_fault(event); 1055 } 1056} 1057 1058static void 1059bfa_iocpf_sm_fail_entry(struct bfa_iocpf *iocpf) 1060{ 1061} 1062 1063/* IOC is in failed state. */ 1064static void 1065bfa_iocpf_sm_fail(struct bfa_iocpf *iocpf, enum iocpf_event event) 1066{ 1067 switch (event) { 1068 case IOCPF_E_DISABLE: 1069 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 1070 break; 1071 1072 default: 1073 bfa_sm_fault(event); 1074 } 1075} 1076 1077/* BFA IOC private functions */ 1078 1079/* Notify common modules registered for notification. */ 1080static void 1081bfa_ioc_event_notify(struct bfa_ioc *ioc, enum bfa_ioc_event event) 1082{ 1083 struct bfa_ioc_notify *notify; 1084 1085 list_for_each_entry(notify, &ioc->notify_q, qe) 1086 notify->cbfn(notify->cbarg, event); 1087} 1088 1089static void 1090bfa_ioc_disable_comp(struct bfa_ioc *ioc) 1091{ 1092 ioc->cbfn->disable_cbfn(ioc->bfa); 1093 bfa_ioc_event_notify(ioc, BFA_IOC_E_DISABLED); 1094} 1095 1096bool 1097bfa_nw_ioc_sem_get(void __iomem *sem_reg) 1098{ 1099 u32 r32; 1100 int cnt = 0; 1101#define BFA_SEM_SPINCNT 3000 1102 1103 r32 = readl(sem_reg); 1104 1105 while ((r32 & 1) && (cnt < BFA_SEM_SPINCNT)) { 1106 cnt++; 1107 udelay(2); 1108 r32 = readl(sem_reg); 1109 } 1110 1111 if (!(r32 & 1)) 1112 return true; 1113 1114 return false; 1115} 1116 1117void 1118bfa_nw_ioc_sem_release(void __iomem *sem_reg) 1119{ 1120 readl(sem_reg); 1121 writel(1, sem_reg); 1122} 1123 1124/* Clear fwver hdr */ 1125static void 1126bfa_ioc_fwver_clear(struct bfa_ioc *ioc) 1127{ 1128 u32 pgnum, loff = 0; 1129 int i; 1130 1131 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff); 1132 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1133 1134 for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32)); i++) { 1135 writel(0, ioc->ioc_regs.smem_page_start + loff); 1136 loff += sizeof(u32); 1137 } 1138} 1139 1140 1141static void 1142bfa_ioc_hw_sem_init(struct bfa_ioc *ioc) 1143{ 1144 struct bfi_ioc_image_hdr fwhdr; 1145 u32 fwstate, r32; 1146 1147 /* Spin on init semaphore to serialize. */ 1148 r32 = readl(ioc->ioc_regs.ioc_init_sem_reg); 1149 while (r32 & 0x1) { 1150 udelay(20); 1151 r32 = readl(ioc->ioc_regs.ioc_init_sem_reg); 1152 } 1153 1154 fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc); 1155 if (fwstate == BFI_IOC_UNINIT) { 1156 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 1157 return; 1158 } 1159 1160 bfa_nw_ioc_fwver_get(ioc, &fwhdr); 1161 1162 if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) { 1163 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 1164 return; 1165 } 1166 1167 bfa_ioc_fwver_clear(ioc); 1168 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_UNINIT); 1169 bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_UNINIT); 1170 1171 /* 1172 * Try to lock and then unlock the semaphore. 1173 */ 1174 readl(ioc->ioc_regs.ioc_sem_reg); 1175 writel(1, ioc->ioc_regs.ioc_sem_reg); 1176 1177 /* Unlock init semaphore */ 1178 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 1179} 1180 1181static void 1182bfa_ioc_hw_sem_get(struct bfa_ioc *ioc) 1183{ 1184 u32 r32; 1185 1186 /** 1187 * First read to the semaphore register will return 0, subsequent reads 1188 * will return 1. Semaphore is released by writing 1 to the register 1189 */ 1190 r32 = readl(ioc->ioc_regs.ioc_sem_reg); 1191 if (r32 == ~0) { 1192 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEM_ERROR); 1193 return; 1194 } 1195 if (!(r32 & 1)) { 1196 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED); 1197 return; 1198 } 1199 1200 mod_timer(&ioc->sem_timer, jiffies + 1201 msecs_to_jiffies(BFA_IOC_HWSEM_TOV)); 1202} 1203 1204void 1205bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc) 1206{ 1207 writel(1, ioc->ioc_regs.ioc_sem_reg); 1208} 1209 1210static void 1211bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc) 1212{ 1213 del_timer(&ioc->sem_timer); 1214} 1215 1216/* Initialize LPU local memory (aka secondary memory / SRAM) */ 1217static void 1218bfa_ioc_lmem_init(struct bfa_ioc *ioc) 1219{ 1220 u32 pss_ctl; 1221 int i; 1222#define PSS_LMEM_INIT_TIME 10000 1223 1224 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1225 pss_ctl &= ~__PSS_LMEM_RESET; 1226 pss_ctl |= __PSS_LMEM_INIT_EN; 1227 1228 /* 1229 * i2c workaround 12.5khz clock 1230 */ 1231 pss_ctl |= __PSS_I2C_CLK_DIV(3UL); 1232 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1233 1234 /** 1235 * wait for memory initialization to be complete 1236 */ 1237 i = 0; 1238 do { 1239 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1240 i++; 1241 } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME)); 1242 1243 /** 1244 * If memory initialization is not successful, IOC timeout will catch 1245 * such failures. 1246 */ 1247 BUG_ON(!(pss_ctl & __PSS_LMEM_INIT_DONE)); 1248 1249 pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN); 1250 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1251} 1252 1253static void 1254bfa_ioc_lpu_start(struct bfa_ioc *ioc) 1255{ 1256 u32 pss_ctl; 1257 1258 /** 1259 * Take processor out of reset. 1260 */ 1261 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1262 pss_ctl &= ~__PSS_LPU0_RESET; 1263 1264 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1265} 1266 1267static void 1268bfa_ioc_lpu_stop(struct bfa_ioc *ioc) 1269{ 1270 u32 pss_ctl; 1271 1272 /** 1273 * Put processors in reset. 1274 */ 1275 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1276 pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET); 1277 1278 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1279} 1280 1281/* Get driver and firmware versions. */ 1282void 1283bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) 1284{ 1285 u32 pgnum; 1286 u32 loff = 0; 1287 int i; 1288 u32 *fwsig = (u32 *) fwhdr; 1289 1290 pgnum = bfa_ioc_smem_pgnum(ioc, loff); 1291 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1292 1293 for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32)); 1294 i++) { 1295 fwsig[i] = 1296 swab32(readl(loff + ioc->ioc_regs.smem_page_start)); 1297 loff += sizeof(u32); 1298 } 1299} 1300 1301static bool 1302bfa_ioc_fwver_md5_check(struct bfi_ioc_image_hdr *fwhdr_1, 1303 struct bfi_ioc_image_hdr *fwhdr_2) 1304{ 1305 int i; 1306 1307 for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) { 1308 if (fwhdr_1->md5sum[i] != fwhdr_2->md5sum[i]) 1309 return false; 1310 } 1311 1312 return true; 1313} 1314 1315/* Returns TRUE if major minor and maintenance are same. 1316 * If patch version are same, check for MD5 Checksum to be same. 1317 */ 1318static bool 1319bfa_ioc_fw_ver_compatible(struct bfi_ioc_image_hdr *drv_fwhdr, 1320 struct bfi_ioc_image_hdr *fwhdr_to_cmp) 1321{ 1322 if (drv_fwhdr->signature != fwhdr_to_cmp->signature) 1323 return false; 1324 if (drv_fwhdr->fwver.major != fwhdr_to_cmp->fwver.major) 1325 return false; 1326 if (drv_fwhdr->fwver.minor != fwhdr_to_cmp->fwver.minor) 1327 return false; 1328 if (drv_fwhdr->fwver.maint != fwhdr_to_cmp->fwver.maint) 1329 return false; 1330 if (drv_fwhdr->fwver.patch == fwhdr_to_cmp->fwver.patch && 1331 drv_fwhdr->fwver.phase == fwhdr_to_cmp->fwver.phase && 1332 drv_fwhdr->fwver.build == fwhdr_to_cmp->fwver.build) 1333 return bfa_ioc_fwver_md5_check(drv_fwhdr, fwhdr_to_cmp); 1334 1335 return true; 1336} 1337 1338static bool 1339bfa_ioc_flash_fwver_valid(struct bfi_ioc_image_hdr *flash_fwhdr) 1340{ 1341 if (flash_fwhdr->fwver.major == 0 || flash_fwhdr->fwver.major == 0xFF) 1342 return false; 1343 1344 return true; 1345} 1346 1347static bool 1348fwhdr_is_ga(struct bfi_ioc_image_hdr *fwhdr) 1349{ 1350 if (fwhdr->fwver.phase == 0 && 1351 fwhdr->fwver.build == 0) 1352 return false; 1353 1354 return true; 1355} 1356 1357/* Returns TRUE if both are compatible and patch of fwhdr_to_cmp is better. */ 1358static enum bfi_ioc_img_ver_cmp 1359bfa_ioc_fw_ver_patch_cmp(struct bfi_ioc_image_hdr *base_fwhdr, 1360 struct bfi_ioc_image_hdr *fwhdr_to_cmp) 1361{ 1362 if (!bfa_ioc_fw_ver_compatible(base_fwhdr, fwhdr_to_cmp)) 1363 return BFI_IOC_IMG_VER_INCOMP; 1364 1365 if (fwhdr_to_cmp->fwver.patch > base_fwhdr->fwver.patch) 1366 return BFI_IOC_IMG_VER_BETTER; 1367 else if (fwhdr_to_cmp->fwver.patch < base_fwhdr->fwver.patch) 1368 return BFI_IOC_IMG_VER_OLD; 1369 1370 /* GA takes priority over internal builds of the same patch stream. 1371 * At this point major minor maint and patch numbers are same. 1372 */ 1373 if (fwhdr_is_ga(base_fwhdr)) 1374 if (fwhdr_is_ga(fwhdr_to_cmp)) 1375 return BFI_IOC_IMG_VER_SAME; 1376 else 1377 return BFI_IOC_IMG_VER_OLD; 1378 else 1379 if (fwhdr_is_ga(fwhdr_to_cmp)) 1380 return BFI_IOC_IMG_VER_BETTER; 1381 1382 if (fwhdr_to_cmp->fwver.phase > base_fwhdr->fwver.phase) 1383 return BFI_IOC_IMG_VER_BETTER; 1384 else if (fwhdr_to_cmp->fwver.phase < base_fwhdr->fwver.phase) 1385 return BFI_IOC_IMG_VER_OLD; 1386 1387 if (fwhdr_to_cmp->fwver.build > base_fwhdr->fwver.build) 1388 return BFI_IOC_IMG_VER_BETTER; 1389 else if (fwhdr_to_cmp->fwver.build < base_fwhdr->fwver.build) 1390 return BFI_IOC_IMG_VER_OLD; 1391 1392 /* All Version Numbers are equal. 1393 * Md5 check to be done as a part of compatibility check. 1394 */ 1395 return BFI_IOC_IMG_VER_SAME; 1396} 1397 1398/* register definitions */ 1399#define FLI_CMD_REG 0x0001d000 1400#define FLI_WRDATA_REG 0x0001d00c 1401#define FLI_RDDATA_REG 0x0001d010 1402#define FLI_ADDR_REG 0x0001d004 1403#define FLI_DEV_STATUS_REG 0x0001d014 1404 1405#define BFA_FLASH_FIFO_SIZE 128 /* fifo size */ 1406#define BFA_FLASH_CHECK_MAX 10000 /* max # of status check */ 1407#define BFA_FLASH_BLOCKING_OP_MAX 1000000 /* max # of blocking op check */ 1408#define BFA_FLASH_WIP_MASK 0x01 /* write in progress bit mask */ 1409 1410#define NFC_STATE_RUNNING 0x20000001 1411#define NFC_STATE_PAUSED 0x00004560 1412#define NFC_VER_VALID 0x147 1413 1414enum bfa_flash_cmd { 1415 BFA_FLASH_FAST_READ = 0x0b, /* fast read */ 1416 BFA_FLASH_WRITE_ENABLE = 0x06, /* write enable */ 1417 BFA_FLASH_SECTOR_ERASE = 0xd8, /* sector erase */ 1418 BFA_FLASH_WRITE = 0x02, /* write */ 1419 BFA_FLASH_READ_STATUS = 0x05, /* read status */ 1420}; 1421 1422/* hardware error definition */ 1423enum bfa_flash_err { 1424 BFA_FLASH_NOT_PRESENT = -1, /*!< flash not present */ 1425 BFA_FLASH_UNINIT = -2, /*!< flash not initialized */ 1426 BFA_FLASH_BAD = -3, /*!< flash bad */ 1427 BFA_FLASH_BUSY = -4, /*!< flash busy */ 1428 BFA_FLASH_ERR_CMD_ACT = -5, /*!< command active never cleared */ 1429 BFA_FLASH_ERR_FIFO_CNT = -6, /*!< fifo count never cleared */ 1430 BFA_FLASH_ERR_WIP = -7, /*!< write-in-progress never cleared */ 1431 BFA_FLASH_ERR_TIMEOUT = -8, /*!< fli timeout */ 1432 BFA_FLASH_ERR_LEN = -9, /*!< invalid length */ 1433}; 1434 1435/* flash command register data structure */ 1436union bfa_flash_cmd_reg { 1437 struct { 1438#ifdef __BIG_ENDIAN 1439 u32 act:1; 1440 u32 rsv:1; 1441 u32 write_cnt:9; 1442 u32 read_cnt:9; 1443 u32 addr_cnt:4; 1444 u32 cmd:8; 1445#else 1446 u32 cmd:8; 1447 u32 addr_cnt:4; 1448 u32 read_cnt:9; 1449 u32 write_cnt:9; 1450 u32 rsv:1; 1451 u32 act:1; 1452#endif 1453 } r; 1454 u32 i; 1455}; 1456 1457/* flash device status register data structure */ 1458union bfa_flash_dev_status_reg { 1459 struct { 1460#ifdef __BIG_ENDIAN 1461 u32 rsv:21; 1462 u32 fifo_cnt:6; 1463 u32 busy:1; 1464 u32 init_status:1; 1465 u32 present:1; 1466 u32 bad:1; 1467 u32 good:1; 1468#else 1469 u32 good:1; 1470 u32 bad:1; 1471 u32 present:1; 1472 u32 init_status:1; 1473 u32 busy:1; 1474 u32 fifo_cnt:6; 1475 u32 rsv:21; 1476#endif 1477 } r; 1478 u32 i; 1479}; 1480 1481/* flash address register data structure */ 1482union bfa_flash_addr_reg { 1483 struct { 1484#ifdef __BIG_ENDIAN 1485 u32 addr:24; 1486 u32 dummy:8; 1487#else 1488 u32 dummy:8; 1489 u32 addr:24; 1490#endif 1491 } r; 1492 u32 i; 1493}; 1494 1495/* Flash raw private functions */ 1496static void 1497bfa_flash_set_cmd(void __iomem *pci_bar, u8 wr_cnt, 1498 u8 rd_cnt, u8 ad_cnt, u8 op) 1499{ 1500 union bfa_flash_cmd_reg cmd; 1501 1502 cmd.i = 0; 1503 cmd.r.act = 1; 1504 cmd.r.write_cnt = wr_cnt; 1505 cmd.r.read_cnt = rd_cnt; 1506 cmd.r.addr_cnt = ad_cnt; 1507 cmd.r.cmd = op; 1508 writel(cmd.i, (pci_bar + FLI_CMD_REG)); 1509} 1510 1511static void 1512bfa_flash_set_addr(void __iomem *pci_bar, u32 address) 1513{ 1514 union bfa_flash_addr_reg addr; 1515 1516 addr.r.addr = address & 0x00ffffff; 1517 addr.r.dummy = 0; 1518 writel(addr.i, (pci_bar + FLI_ADDR_REG)); 1519} 1520 1521static int 1522bfa_flash_cmd_act_check(void __iomem *pci_bar) 1523{ 1524 union bfa_flash_cmd_reg cmd; 1525 1526 cmd.i = readl(pci_bar + FLI_CMD_REG); 1527 1528 if (cmd.r.act) 1529 return BFA_FLASH_ERR_CMD_ACT; 1530 1531 return 0; 1532} 1533 1534/* Flush FLI data fifo. */ 1535static int 1536bfa_flash_fifo_flush(void __iomem *pci_bar) 1537{ 1538 u32 i; 1539 union bfa_flash_dev_status_reg dev_status; 1540 1541 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG); 1542 1543 if (!dev_status.r.fifo_cnt) 1544 return 0; 1545 1546 /* fifo counter in terms of words */ 1547 for (i = 0; i < dev_status.r.fifo_cnt; i++) 1548 readl(pci_bar + FLI_RDDATA_REG); 1549 1550 /* Check the device status. It may take some time. */ 1551 for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) { 1552 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG); 1553 if (!dev_status.r.fifo_cnt) 1554 break; 1555 } 1556 1557 if (dev_status.r.fifo_cnt) 1558 return BFA_FLASH_ERR_FIFO_CNT; 1559 1560 return 0; 1561} 1562 1563/* Read flash status. */ 1564static int 1565bfa_flash_status_read(void __iomem *pci_bar) 1566{ 1567 union bfa_flash_dev_status_reg dev_status; 1568 int status; 1569 u32 ret_status; 1570 int i; 1571 1572 status = bfa_flash_fifo_flush(pci_bar); 1573 if (status < 0) 1574 return status; 1575 1576 bfa_flash_set_cmd(pci_bar, 0, 4, 0, BFA_FLASH_READ_STATUS); 1577 1578 for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) { 1579 status = bfa_flash_cmd_act_check(pci_bar); 1580 if (!status) 1581 break; 1582 } 1583 1584 if (status) 1585 return status; 1586 1587 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG); 1588 if (!dev_status.r.fifo_cnt) 1589 return BFA_FLASH_BUSY; 1590 1591 ret_status = readl(pci_bar + FLI_RDDATA_REG); 1592 ret_status >>= 24; 1593 1594 status = bfa_flash_fifo_flush(pci_bar); 1595 if (status < 0) 1596 return status; 1597 1598 return ret_status; 1599} 1600 1601/* Start flash read operation. */ 1602static int 1603bfa_flash_read_start(void __iomem *pci_bar, u32 offset, u32 len, 1604 char *buf) 1605{ 1606 int status; 1607 1608 /* len must be mutiple of 4 and not exceeding fifo size */ 1609 if (len == 0 || len > BFA_FLASH_FIFO_SIZE || (len & 0x03) != 0) 1610 return BFA_FLASH_ERR_LEN; 1611 1612 /* check status */ 1613 status = bfa_flash_status_read(pci_bar); 1614 if (status == BFA_FLASH_BUSY) 1615 status = bfa_flash_status_read(pci_bar); 1616 1617 if (status < 0) 1618 return status; 1619 1620 /* check if write-in-progress bit is cleared */ 1621 if (status & BFA_FLASH_WIP_MASK) 1622 return BFA_FLASH_ERR_WIP; 1623 1624 bfa_flash_set_addr(pci_bar, offset); 1625 1626 bfa_flash_set_cmd(pci_bar, 0, (u8)len, 4, BFA_FLASH_FAST_READ); 1627 1628 return 0; 1629} 1630 1631/* Check flash read operation. */ 1632static u32 1633bfa_flash_read_check(void __iomem *pci_bar) 1634{ 1635 if (bfa_flash_cmd_act_check(pci_bar)) 1636 return 1; 1637 1638 return 0; 1639} 1640 1641/* End flash read operation. */ 1642static void 1643bfa_flash_read_end(void __iomem *pci_bar, u32 len, char *buf) 1644{ 1645 u32 i; 1646 1647 /* read data fifo up to 32 words */ 1648 for (i = 0; i < len; i += 4) { 1649 u32 w = readl(pci_bar + FLI_RDDATA_REG); 1650 *((u32 *)(buf + i)) = swab32(w); 1651 } 1652 1653 bfa_flash_fifo_flush(pci_bar); 1654} 1655 1656/* Perform flash raw read. */ 1657 1658#define FLASH_BLOCKING_OP_MAX 500 1659#define FLASH_SEM_LOCK_REG 0x18820 1660 1661static int 1662bfa_raw_sem_get(void __iomem *bar) 1663{ 1664 int locked; 1665 1666 locked = readl(bar + FLASH_SEM_LOCK_REG); 1667 1668 return !locked; 1669} 1670 1671static enum bfa_status 1672bfa_flash_sem_get(void __iomem *bar) 1673{ 1674 u32 n = FLASH_BLOCKING_OP_MAX; 1675 1676 while (!bfa_raw_sem_get(bar)) { 1677 if (--n <= 0) 1678 return BFA_STATUS_BADFLASH; 1679 mdelay(10); 1680 } 1681 return BFA_STATUS_OK; 1682} 1683 1684static void 1685bfa_flash_sem_put(void __iomem *bar) 1686{ 1687 writel(0, (bar + FLASH_SEM_LOCK_REG)); 1688} 1689 1690static enum bfa_status 1691bfa_flash_raw_read(void __iomem *pci_bar, u32 offset, char *buf, 1692 u32 len) 1693{ 1694 u32 n; 1695 int status; 1696 u32 off, l, s, residue, fifo_sz; 1697 1698 residue = len; 1699 off = 0; 1700 fifo_sz = BFA_FLASH_FIFO_SIZE; 1701 status = bfa_flash_sem_get(pci_bar); 1702 if (status != BFA_STATUS_OK) 1703 return status; 1704 1705 while (residue) { 1706 s = offset + off; 1707 n = s / fifo_sz; 1708 l = (n + 1) * fifo_sz - s; 1709 if (l > residue) 1710 l = residue; 1711 1712 status = bfa_flash_read_start(pci_bar, offset + off, l, 1713 &buf[off]); 1714 if (status < 0) { 1715 bfa_flash_sem_put(pci_bar); 1716 return BFA_STATUS_FAILED; 1717 } 1718 1719 n = BFA_FLASH_BLOCKING_OP_MAX; 1720 while (bfa_flash_read_check(pci_bar)) { 1721 if (--n <= 0) { 1722 bfa_flash_sem_put(pci_bar); 1723 return BFA_STATUS_FAILED; 1724 } 1725 } 1726 1727 bfa_flash_read_end(pci_bar, l, &buf[off]); 1728 1729 residue -= l; 1730 off += l; 1731 } 1732 bfa_flash_sem_put(pci_bar); 1733 1734 return BFA_STATUS_OK; 1735} 1736 1737#define BFA_FLASH_PART_FWIMG_ADDR 0x100000 /* fw image address */ 1738 1739static enum bfa_status 1740bfa_nw_ioc_flash_img_get_chnk(struct bfa_ioc *ioc, u32 off, 1741 u32 *fwimg) 1742{ 1743 return bfa_flash_raw_read(ioc->pcidev.pci_bar_kva, 1744 BFA_FLASH_PART_FWIMG_ADDR + (off * sizeof(u32)), 1745 (char *)fwimg, BFI_FLASH_CHUNK_SZ); 1746} 1747 1748static enum bfi_ioc_img_ver_cmp 1749bfa_ioc_flash_fwver_cmp(struct bfa_ioc *ioc, 1750 struct bfi_ioc_image_hdr *base_fwhdr) 1751{ 1752 struct bfi_ioc_image_hdr *flash_fwhdr; 1753 enum bfa_status status; 1754 u32 fwimg[BFI_FLASH_CHUNK_SZ_WORDS]; 1755 1756 status = bfa_nw_ioc_flash_img_get_chnk(ioc, 0, fwimg); 1757 if (status != BFA_STATUS_OK) 1758 return BFI_IOC_IMG_VER_INCOMP; 1759 1760 flash_fwhdr = (struct bfi_ioc_image_hdr *)fwimg; 1761 if (bfa_ioc_flash_fwver_valid(flash_fwhdr)) 1762 return bfa_ioc_fw_ver_patch_cmp(base_fwhdr, flash_fwhdr); 1763 else 1764 return BFI_IOC_IMG_VER_INCOMP; 1765} 1766 1767/* 1768 * Returns TRUE if driver is willing to work with current smem f/w version. 1769 */ 1770bool 1771bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) 1772{ 1773 struct bfi_ioc_image_hdr *drv_fwhdr; 1774 enum bfi_ioc_img_ver_cmp smem_flash_cmp, drv_smem_cmp; 1775 1776 drv_fwhdr = (struct bfi_ioc_image_hdr *) 1777 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0); 1778 1779 /* If smem is incompatible or old, driver should not work with it. */ 1780 drv_smem_cmp = bfa_ioc_fw_ver_patch_cmp(drv_fwhdr, fwhdr); 1781 if (drv_smem_cmp == BFI_IOC_IMG_VER_INCOMP || 1782 drv_smem_cmp == BFI_IOC_IMG_VER_OLD) { 1783 return false; 1784 } 1785 1786 /* IF Flash has a better F/W than smem do not work with smem. 1787 * If smem f/w == flash f/w, as smem f/w not old | incmp, work with it. 1788 * If Flash is old or incomp work with smem iff smem f/w == drv f/w. 1789 */ 1790 smem_flash_cmp = bfa_ioc_flash_fwver_cmp(ioc, fwhdr); 1791 1792 if (smem_flash_cmp == BFI_IOC_IMG_VER_BETTER) 1793 return false; 1794 else if (smem_flash_cmp == BFI_IOC_IMG_VER_SAME) 1795 return true; 1796 else 1797 return (drv_smem_cmp == BFI_IOC_IMG_VER_SAME) ? 1798 true : false; 1799} 1800 1801/* Return true if current running version is valid. Firmware signature and 1802 * execution context (driver/bios) must match. 1803 */ 1804static bool 1805bfa_ioc_fwver_valid(struct bfa_ioc *ioc, u32 boot_env) 1806{ 1807 struct bfi_ioc_image_hdr fwhdr; 1808 1809 bfa_nw_ioc_fwver_get(ioc, &fwhdr); 1810 if (swab32(fwhdr.bootenv) != boot_env) 1811 return false; 1812 1813 return bfa_nw_ioc_fwver_cmp(ioc, &fwhdr); 1814} 1815 1816/* Conditionally flush any pending message from firmware at start. */ 1817static void 1818bfa_ioc_msgflush(struct bfa_ioc *ioc) 1819{ 1820 u32 r32; 1821 1822 r32 = readl(ioc->ioc_regs.lpu_mbox_cmd); 1823 if (r32) 1824 writel(1, ioc->ioc_regs.lpu_mbox_cmd); 1825} 1826 1827static void 1828bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force) 1829{ 1830 enum bfi_ioc_state ioc_fwstate; 1831 bool fwvalid; 1832 u32 boot_env; 1833 1834 ioc_fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc); 1835 1836 if (force) 1837 ioc_fwstate = BFI_IOC_UNINIT; 1838 1839 boot_env = BFI_FWBOOT_ENV_OS; 1840 1841 /** 1842 * check if firmware is valid 1843 */ 1844 fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ? 1845 false : bfa_ioc_fwver_valid(ioc, boot_env); 1846 1847 if (!fwvalid) { 1848 if (bfa_ioc_boot(ioc, BFI_FWBOOT_TYPE_NORMAL, boot_env) == 1849 BFA_STATUS_OK) 1850 bfa_ioc_poll_fwinit(ioc); 1851 1852 return; 1853 } 1854 1855 /** 1856 * If hardware initialization is in progress (initialized by other IOC), 1857 * just wait for an initialization completion interrupt. 1858 */ 1859 if (ioc_fwstate == BFI_IOC_INITING) { 1860 bfa_ioc_poll_fwinit(ioc); 1861 return; 1862 } 1863 1864 /** 1865 * If IOC function is disabled and firmware version is same, 1866 * just re-enable IOC. 1867 */ 1868 if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) { 1869 /** 1870 * When using MSI-X any pending firmware ready event should 1871 * be flushed. Otherwise MSI-X interrupts are not delivered. 1872 */ 1873 bfa_ioc_msgflush(ioc); 1874 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY); 1875 return; 1876 } 1877 1878 /** 1879 * Initialize the h/w for any other states. 1880 */ 1881 if (bfa_ioc_boot(ioc, BFI_FWBOOT_TYPE_NORMAL, boot_env) == 1882 BFA_STATUS_OK) 1883 bfa_ioc_poll_fwinit(ioc); 1884} 1885 1886void 1887bfa_nw_ioc_timeout(struct bfa_ioc *ioc) 1888{ 1889 bfa_fsm_send_event(ioc, IOC_E_TIMEOUT); 1890} 1891 1892static void 1893bfa_ioc_mbox_send(struct bfa_ioc *ioc, void *ioc_msg, int len) 1894{ 1895 u32 *msgp = (u32 *) ioc_msg; 1896 u32 i; 1897 1898 BUG_ON(!(len <= BFI_IOC_MSGLEN_MAX)); 1899 1900 /* 1901 * first write msg to mailbox registers 1902 */ 1903 for (i = 0; i < len / sizeof(u32); i++) 1904 writel(cpu_to_le32(msgp[i]), 1905 ioc->ioc_regs.hfn_mbox + i * sizeof(u32)); 1906 1907 for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++) 1908 writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32)); 1909 1910 /* 1911 * write 1 to mailbox CMD to trigger LPU event 1912 */ 1913 writel(1, ioc->ioc_regs.hfn_mbox_cmd); 1914 (void) readl(ioc->ioc_regs.hfn_mbox_cmd); 1915} 1916 1917static void 1918bfa_ioc_send_enable(struct bfa_ioc *ioc) 1919{ 1920 struct bfi_ioc_ctrl_req enable_req; 1921 1922 bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ, 1923 bfa_ioc_portid(ioc)); 1924 enable_req.clscode = htons(ioc->clscode); 1925 enable_req.rsvd = htons(0); 1926 /* overflow in 2106 */ 1927 enable_req.tv_sec = ntohl(ktime_get_real_seconds()); 1928 bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req)); 1929} 1930 1931static void 1932bfa_ioc_send_disable(struct bfa_ioc *ioc) 1933{ 1934 struct bfi_ioc_ctrl_req disable_req; 1935 1936 bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ, 1937 bfa_ioc_portid(ioc)); 1938 disable_req.clscode = htons(ioc->clscode); 1939 disable_req.rsvd = htons(0); 1940 /* overflow in 2106 */ 1941 disable_req.tv_sec = ntohl(ktime_get_real_seconds()); 1942 bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req)); 1943} 1944 1945static void 1946bfa_ioc_send_getattr(struct bfa_ioc *ioc) 1947{ 1948 struct bfi_ioc_getattr_req attr_req; 1949 1950 bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ, 1951 bfa_ioc_portid(ioc)); 1952 bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa); 1953 bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req)); 1954} 1955 1956void 1957bfa_nw_ioc_hb_check(struct bfa_ioc *ioc) 1958{ 1959 u32 hb_count; 1960 1961 hb_count = readl(ioc->ioc_regs.heartbeat); 1962 if (ioc->hb_count == hb_count) { 1963 bfa_ioc_recover(ioc); 1964 return; 1965 } else { 1966 ioc->hb_count = hb_count; 1967 } 1968 1969 bfa_ioc_mbox_poll(ioc); 1970 mod_timer(&ioc->hb_timer, jiffies + 1971 msecs_to_jiffies(BFA_IOC_HB_TOV)); 1972} 1973 1974static void 1975bfa_ioc_hb_monitor(struct bfa_ioc *ioc) 1976{ 1977 ioc->hb_count = readl(ioc->ioc_regs.heartbeat); 1978 mod_timer(&ioc->hb_timer, jiffies + 1979 msecs_to_jiffies(BFA_IOC_HB_TOV)); 1980} 1981 1982static void 1983bfa_ioc_hb_stop(struct bfa_ioc *ioc) 1984{ 1985 del_timer(&ioc->hb_timer); 1986} 1987 1988/* Initiate a full firmware download. */ 1989static enum bfa_status 1990bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type, 1991 u32 boot_env) 1992{ 1993 u32 *fwimg; 1994 u32 pgnum; 1995 u32 loff = 0; 1996 u32 chunkno = 0; 1997 u32 i; 1998 u32 asicmode; 1999 u32 fwimg_size; 2000 u32 fwimg_buf[BFI_FLASH_CHUNK_SZ_WORDS]; 2001 enum bfa_status status; 2002 2003 if (boot_env == BFI_FWBOOT_ENV_OS && 2004 boot_type == BFI_FWBOOT_TYPE_FLASH) { 2005 fwimg_size = BFI_FLASH_IMAGE_SZ/sizeof(u32); 2006 2007 status = bfa_nw_ioc_flash_img_get_chnk(ioc, 2008 BFA_IOC_FLASH_CHUNK_ADDR(chunkno), fwimg_buf); 2009 if (status != BFA_STATUS_OK) 2010 return status; 2011 2012 fwimg = fwimg_buf; 2013 } else { 2014 fwimg_size = bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)); 2015 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 2016 BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); 2017 } 2018 2019 pgnum = bfa_ioc_smem_pgnum(ioc, loff); 2020 2021 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 2022 2023 for (i = 0; i < fwimg_size; i++) { 2024 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) { 2025 chunkno = BFA_IOC_FLASH_CHUNK_NO(i); 2026 if (boot_env == BFI_FWBOOT_ENV_OS && 2027 boot_type == BFI_FWBOOT_TYPE_FLASH) { 2028 status = bfa_nw_ioc_flash_img_get_chnk(ioc, 2029 BFA_IOC_FLASH_CHUNK_ADDR(chunkno), 2030 fwimg_buf); 2031 if (status != BFA_STATUS_OK) 2032 return status; 2033 2034 fwimg = fwimg_buf; 2035 } else { 2036 fwimg = bfa_cb_image_get_chunk( 2037 bfa_ioc_asic_gen(ioc), 2038 BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); 2039 } 2040 } 2041 2042 /** 2043 * write smem 2044 */ 2045 writel(swab32(fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]), 2046 ioc->ioc_regs.smem_page_start + loff); 2047 2048 loff += sizeof(u32); 2049 2050 /** 2051 * handle page offset wrap around 2052 */ 2053 loff = PSS_SMEM_PGOFF(loff); 2054 if (loff == 0) { 2055 pgnum++; 2056 writel(pgnum, 2057 ioc->ioc_regs.host_page_num_fn); 2058 } 2059 } 2060 2061 writel(bfa_ioc_smem_pgnum(ioc, 0), 2062 ioc->ioc_regs.host_page_num_fn); 2063 2064 /* 2065 * Set boot type, env and device mode at the end. 2066 */ 2067 if (boot_env == BFI_FWBOOT_ENV_OS && 2068 boot_type == BFI_FWBOOT_TYPE_FLASH) { 2069 boot_type = BFI_FWBOOT_TYPE_NORMAL; 2070 } 2071 asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode, 2072 ioc->port0_mode, ioc->port1_mode); 2073 writel(asicmode, ((ioc->ioc_regs.smem_page_start) 2074 + BFI_FWBOOT_DEVMODE_OFF)); 2075 writel(boot_type, ((ioc->ioc_regs.smem_page_start) 2076 + (BFI_FWBOOT_TYPE_OFF))); 2077 writel(boot_env, ((ioc->ioc_regs.smem_page_start) 2078 + (BFI_FWBOOT_ENV_OFF))); 2079 return BFA_STATUS_OK; 2080} 2081 2082static void 2083bfa_ioc_reset(struct bfa_ioc *ioc, bool force) 2084{ 2085 bfa_ioc_hwinit(ioc, force); 2086} 2087 2088/* BFA ioc enable reply by firmware */ 2089static void 2090bfa_ioc_enable_reply(struct bfa_ioc *ioc, enum bfa_mode port_mode, 2091 u8 cap_bm) 2092{ 2093 struct bfa_iocpf *iocpf = &ioc->iocpf; 2094 2095 ioc->port_mode = ioc->port_mode_cfg = port_mode; 2096 ioc->ad_cap_bm = cap_bm; 2097 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE); 2098} 2099 2100/* Update BFA configuration from firmware configuration. */ 2101static void 2102bfa_ioc_getattr_reply(struct bfa_ioc *ioc) 2103{ 2104 struct bfi_ioc_attr *attr = ioc->attr; 2105 2106 attr->adapter_prop = ntohl(attr->adapter_prop); 2107 attr->card_type = ntohl(attr->card_type); 2108 attr->maxfrsize = ntohs(attr->maxfrsize); 2109 2110 bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); 2111} 2112 2113/* Attach time initialization of mbox logic. */ 2114static void 2115bfa_ioc_mbox_attach(struct bfa_ioc *ioc) 2116{ 2117 struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; 2118 int mc; 2119 2120 INIT_LIST_HEAD(&mod->cmd_q); 2121 for (mc = 0; mc < BFI_MC_MAX; mc++) { 2122 mod->mbhdlr[mc].cbfn = NULL; 2123 mod->mbhdlr[mc].cbarg = ioc->bfa; 2124 } 2125} 2126 2127/* Mbox poll timer -- restarts any pending mailbox requests. */ 2128static void 2129bfa_ioc_mbox_poll(struct bfa_ioc *ioc) 2130{ 2131 struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; 2132 struct bfa_mbox_cmd *cmd; 2133 bfa_mbox_cmd_cbfn_t cbfn; 2134 void *cbarg; 2135 u32 stat; 2136 2137 /** 2138 * If no command pending, do nothing 2139 */ 2140 if (list_empty(&mod->cmd_q)) 2141 return; 2142 2143 /** 2144 * If previous command is not yet fetched by firmware, do nothing 2145 */ 2146 stat = readl(ioc->ioc_regs.hfn_mbox_cmd); 2147 if (stat) 2148 return; 2149 2150 /** 2151 * Enqueue command to firmware. 2152 */ 2153 cmd = list_first_entry(&mod->cmd_q, struct bfa_mbox_cmd, qe); 2154 list_del(&cmd->qe); 2155 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); 2156 2157 /** 2158 * Give a callback to the client, indicating that the command is sent 2159 */ 2160 if (cmd->cbfn) { 2161 cbfn = cmd->cbfn; 2162 cbarg = cmd->cbarg; 2163 cmd->cbfn = NULL; 2164 cbfn(cbarg); 2165 } 2166} 2167 2168/* Cleanup any pending requests. */ 2169static void 2170bfa_ioc_mbox_flush(struct bfa_ioc *ioc) 2171{ 2172 struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; 2173 struct bfa_mbox_cmd *cmd; 2174 2175 while (!list_empty(&mod->cmd_q)) { 2176 cmd = list_first_entry(&mod->cmd_q, struct bfa_mbox_cmd, qe); 2177 list_del(&cmd->qe); 2178 } 2179} 2180 2181/** 2182 * bfa_nw_ioc_smem_read - Read data from SMEM to host through PCI memmap 2183 * 2184 * @ioc: memory for IOC 2185 * @tbuf: app memory to store data from smem 2186 * @soff: smem offset 2187 * @sz: size of smem in bytes 2188 */ 2189static int 2190bfa_nw_ioc_smem_read(struct bfa_ioc *ioc, void *tbuf, u32 soff, u32 sz) 2191{ 2192 u32 pgnum, loff, r32; 2193 int i, len; 2194 u32 *buf = tbuf; 2195 2196 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff); 2197 loff = PSS_SMEM_PGOFF(soff); 2198 2199 /* 2200 * Hold semaphore to serialize pll init and fwtrc. 2201 */ 2202 if (!bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) 2203 return 1; 2204 2205 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 2206 2207 len = sz/sizeof(u32); 2208 for (i = 0; i < len; i++) { 2209 r32 = swab32(readl(loff + ioc->ioc_regs.smem_page_start)); 2210 buf[i] = be32_to_cpu(r32); 2211 loff += sizeof(u32); 2212 2213 /** 2214 * handle page offset wrap around 2215 */ 2216 loff = PSS_SMEM_PGOFF(loff); 2217 if (loff == 0) { 2218 pgnum++; 2219 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 2220 } 2221 } 2222 2223 writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0), 2224 ioc->ioc_regs.host_page_num_fn); 2225 2226 /* 2227 * release semaphore 2228 */ 2229 readl(ioc->ioc_regs.ioc_init_sem_reg); 2230 writel(1, ioc->ioc_regs.ioc_init_sem_reg); 2231 return 0; 2232} 2233 2234/* Retrieve saved firmware trace from a prior IOC failure. */ 2235int 2236bfa_nw_ioc_debug_fwtrc(struct bfa_ioc *ioc, void *trcdata, int *trclen) 2237{ 2238 u32 loff = BFI_IOC_TRC_OFF + BNA_DBG_FWTRC_LEN * ioc->port_id; 2239 int tlen, status = 0; 2240 2241 tlen = *trclen; 2242 if (tlen > BNA_DBG_FWTRC_LEN) 2243 tlen = BNA_DBG_FWTRC_LEN; 2244 2245 status = bfa_nw_ioc_smem_read(ioc, trcdata, loff, tlen); 2246 *trclen = tlen; 2247 return status; 2248} 2249 2250/* Save firmware trace if configured. */ 2251static void 2252bfa_nw_ioc_debug_save_ftrc(struct bfa_ioc *ioc) 2253{ 2254 int tlen; 2255 2256 if (ioc->dbg_fwsave_once) { 2257 ioc->dbg_fwsave_once = false; 2258 if (ioc->dbg_fwsave_len) { 2259 tlen = ioc->dbg_fwsave_len; 2260 bfa_nw_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen); 2261 } 2262 } 2263} 2264 2265/* Retrieve saved firmware trace from a prior IOC failure. */ 2266int 2267bfa_nw_ioc_debug_fwsave(struct bfa_ioc *ioc, void *trcdata, int *trclen) 2268{ 2269 int tlen; 2270 2271 if (ioc->dbg_fwsave_len == 0) 2272 return BFA_STATUS_ENOFSAVE; 2273 2274 tlen = *trclen; 2275 if (tlen > ioc->dbg_fwsave_len) 2276 tlen = ioc->dbg_fwsave_len; 2277 2278 memcpy(trcdata, ioc->dbg_fwsave, tlen); 2279 *trclen = tlen; 2280 return BFA_STATUS_OK; 2281} 2282 2283static void 2284bfa_ioc_fail_notify(struct bfa_ioc *ioc) 2285{ 2286 /** 2287 * Notify driver and common modules registered for notification. 2288 */ 2289 ioc->cbfn->hbfail_cbfn(ioc->bfa); 2290 bfa_ioc_event_notify(ioc, BFA_IOC_E_FAILED); 2291 bfa_nw_ioc_debug_save_ftrc(ioc); 2292} 2293 2294/* IOCPF to IOC interface */ 2295static void 2296bfa_ioc_pf_enabled(struct bfa_ioc *ioc) 2297{ 2298 bfa_fsm_send_event(ioc, IOC_E_ENABLED); 2299} 2300 2301static void 2302bfa_ioc_pf_disabled(struct bfa_ioc *ioc) 2303{ 2304 bfa_fsm_send_event(ioc, IOC_E_DISABLED); 2305} 2306 2307static void 2308bfa_ioc_pf_failed(struct bfa_ioc *ioc) 2309{ 2310 bfa_fsm_send_event(ioc, IOC_E_PFFAILED); 2311} 2312 2313static void 2314bfa_ioc_pf_hwfailed(struct bfa_ioc *ioc) 2315{ 2316 bfa_fsm_send_event(ioc, IOC_E_HWFAILED); 2317} 2318 2319static void 2320bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc) 2321{ 2322 /** 2323 * Provide enable completion callback and AEN notification. 2324 */ 2325 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 2326} 2327 2328/* IOC public */ 2329static enum bfa_status 2330bfa_ioc_pll_init(struct bfa_ioc *ioc) 2331{ 2332 /* 2333 * Hold semaphore so that nobody can access the chip during init. 2334 */ 2335 bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); 2336 2337 bfa_ioc_pll_init_asic(ioc); 2338 2339 ioc->pllinit = true; 2340 2341 /* Initialize LMEM */ 2342 bfa_ioc_lmem_init(ioc); 2343 2344 /* 2345 * release semaphore. 2346 */ 2347 bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); 2348 2349 return BFA_STATUS_OK; 2350} 2351 2352/* Interface used by diag module to do firmware boot with memory test 2353 * as the entry vector. 2354 */ 2355static enum bfa_status 2356bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type, 2357 u32 boot_env) 2358{ 2359 struct bfi_ioc_image_hdr *drv_fwhdr; 2360 enum bfa_status status; 2361 bfa_ioc_stats(ioc, ioc_boots); 2362 2363 if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK) 2364 return BFA_STATUS_FAILED; 2365 if (boot_env == BFI_FWBOOT_ENV_OS && 2366 boot_type == BFI_FWBOOT_TYPE_NORMAL) { 2367 drv_fwhdr = (struct bfi_ioc_image_hdr *) 2368 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0); 2369 /* Work with Flash iff flash f/w is better than driver f/w. 2370 * Otherwise push drivers firmware. 2371 */ 2372 if (bfa_ioc_flash_fwver_cmp(ioc, drv_fwhdr) == 2373 BFI_IOC_IMG_VER_BETTER) 2374 boot_type = BFI_FWBOOT_TYPE_FLASH; 2375 } 2376 2377 /** 2378 * Initialize IOC state of all functions on a chip reset. 2379 */ 2380 if (boot_type == BFI_FWBOOT_TYPE_MEMTEST) { 2381 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_MEMTEST); 2382 bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_MEMTEST); 2383 } else { 2384 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_INITING); 2385 bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_INITING); 2386 } 2387 2388 bfa_ioc_msgflush(ioc); 2389 status = bfa_ioc_download_fw(ioc, boot_type, boot_env); 2390 if (status == BFA_STATUS_OK) 2391 bfa_ioc_lpu_start(ioc); 2392 else 2393 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT); 2394 2395 return status; 2396} 2397 2398/* Enable/disable IOC failure auto recovery. */ 2399void 2400bfa_nw_ioc_auto_recover(bool auto_recover) 2401{ 2402 bfa_nw_auto_recover = auto_recover; 2403} 2404 2405static bool 2406bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg) 2407{ 2408 u32 *msgp = mbmsg; 2409 u32 r32; 2410 int i; 2411 2412 r32 = readl(ioc->ioc_regs.lpu_mbox_cmd); 2413 if ((r32 & 1) == 0) 2414 return false; 2415 2416 /** 2417 * read the MBOX msg 2418 */ 2419 for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32)); 2420 i++) { 2421 r32 = readl(ioc->ioc_regs.lpu_mbox + 2422 i * sizeof(u32)); 2423 msgp[i] = htonl(r32); 2424 } 2425 2426 /** 2427 * turn off mailbox interrupt by clearing mailbox status 2428 */ 2429 writel(1, ioc->ioc_regs.lpu_mbox_cmd); 2430 readl(ioc->ioc_regs.lpu_mbox_cmd); 2431 2432 return true; 2433} 2434 2435static void 2436bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m) 2437{ 2438 union bfi_ioc_i2h_msg_u *msg; 2439 struct bfa_iocpf *iocpf = &ioc->iocpf; 2440 2441 msg = (union bfi_ioc_i2h_msg_u *) m; 2442 2443 bfa_ioc_stats(ioc, ioc_isrs); 2444 2445 switch (msg->mh.msg_id) { 2446 case BFI_IOC_I2H_HBEAT: 2447 break; 2448 2449 case BFI_IOC_I2H_ENABLE_REPLY: 2450 bfa_ioc_enable_reply(ioc, 2451 (enum bfa_mode)msg->fw_event.port_mode, 2452 msg->fw_event.cap_bm); 2453 break; 2454 2455 case BFI_IOC_I2H_DISABLE_REPLY: 2456 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_DISABLE); 2457 break; 2458 2459 case BFI_IOC_I2H_GETATTR_REPLY: 2460 bfa_ioc_getattr_reply(ioc); 2461 break; 2462 2463 default: 2464 BUG_ON(1); 2465 } 2466} 2467 2468/** 2469 * bfa_nw_ioc_attach - IOC attach time initialization and setup. 2470 * 2471 * @ioc: memory for IOC 2472 * @bfa: driver instance structure 2473 * @cbfn: callback function 2474 */ 2475void 2476bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn) 2477{ 2478 ioc->bfa = bfa; 2479 ioc->cbfn = cbfn; 2480 ioc->fcmode = false; 2481 ioc->pllinit = false; 2482 ioc->dbg_fwsave_once = true; 2483 ioc->iocpf.ioc = ioc; 2484 2485 bfa_ioc_mbox_attach(ioc); 2486 INIT_LIST_HEAD(&ioc->notify_q); 2487 2488 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 2489 bfa_fsm_send_event(ioc, IOC_E_RESET); 2490} 2491 2492/* Driver detach time IOC cleanup. */ 2493void 2494bfa_nw_ioc_detach(struct bfa_ioc *ioc) 2495{ 2496 bfa_fsm_send_event(ioc, IOC_E_DETACH); 2497 2498 /* Done with detach, empty the notify_q. */ 2499 INIT_LIST_HEAD(&ioc->notify_q); 2500} 2501 2502/** 2503 * bfa_nw_ioc_pci_init - Setup IOC PCI properties. 2504 * 2505 * @ioc: memory for IOC 2506 * @pcidev: PCI device information for this IOC 2507 * @clscode: class code 2508 */ 2509void 2510bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev, 2511 enum bfi_pcifn_class clscode) 2512{ 2513 ioc->clscode = clscode; 2514 ioc->pcidev = *pcidev; 2515 2516 /** 2517 * Initialize IOC and device personality 2518 */ 2519 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_FC; 2520 ioc->asic_mode = BFI_ASIC_MODE_FC; 2521 2522 switch (pcidev->device_id) { 2523 case PCI_DEVICE_ID_BROCADE_CT: 2524 ioc->asic_gen = BFI_ASIC_GEN_CT; 2525 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH; 2526 ioc->asic_mode = BFI_ASIC_MODE_ETH; 2527 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_CNA; 2528 ioc->ad_cap_bm = BFA_CM_CNA; 2529 break; 2530 2531 case BFA_PCI_DEVICE_ID_CT2: 2532 ioc->asic_gen = BFI_ASIC_GEN_CT2; 2533 if (clscode == BFI_PCIFN_CLASS_FC && 2534 pcidev->ssid == BFA_PCI_CT2_SSID_FC) { 2535 ioc->asic_mode = BFI_ASIC_MODE_FC16; 2536 ioc->fcmode = true; 2537 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA; 2538 ioc->ad_cap_bm = BFA_CM_HBA; 2539 } else { 2540 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH; 2541 ioc->asic_mode = BFI_ASIC_MODE_ETH; 2542 if (pcidev->ssid == BFA_PCI_CT2_SSID_FCoE) { 2543 ioc->port_mode = 2544 ioc->port_mode_cfg = BFA_MODE_CNA; 2545 ioc->ad_cap_bm = BFA_CM_CNA; 2546 } else { 2547 ioc->port_mode = 2548 ioc->port_mode_cfg = BFA_MODE_NIC; 2549 ioc->ad_cap_bm = BFA_CM_NIC; 2550 } 2551 } 2552 break; 2553 2554 default: 2555 BUG_ON(1); 2556 } 2557 2558 /** 2559 * Set asic specific interfaces. 2560 */ 2561 if (ioc->asic_gen == BFI_ASIC_GEN_CT) 2562 bfa_nw_ioc_set_ct_hwif(ioc); 2563 else { 2564 WARN_ON(ioc->asic_gen != BFI_ASIC_GEN_CT2); 2565 bfa_nw_ioc_set_ct2_hwif(ioc); 2566 bfa_nw_ioc_ct2_poweron(ioc); 2567 } 2568 2569 bfa_ioc_map_port(ioc); 2570 bfa_ioc_reg_init(ioc); 2571} 2572 2573/** 2574 * bfa_nw_ioc_mem_claim - Initialize IOC dma memory 2575 * 2576 * @ioc: memory for IOC 2577 * @dm_kva: kernel virtual address of IOC dma memory 2578 * @dm_pa: physical address of IOC dma memory 2579 */ 2580void 2581bfa_nw_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa) 2582{ 2583 /** 2584 * dma memory for firmware attribute 2585 */ 2586 ioc->attr_dma.kva = dm_kva; 2587 ioc->attr_dma.pa = dm_pa; 2588 ioc->attr = (struct bfi_ioc_attr *) dm_kva; 2589} 2590 2591/* Return size of dma memory required. */ 2592u32 2593bfa_nw_ioc_meminfo(void) 2594{ 2595 return roundup(sizeof(struct bfi_ioc_attr), BFA_DMA_ALIGN_SZ); 2596} 2597 2598void 2599bfa_nw_ioc_enable(struct bfa_ioc *ioc) 2600{ 2601 bfa_ioc_stats(ioc, ioc_enables); 2602 ioc->dbg_fwsave_once = true; 2603 2604 bfa_fsm_send_event(ioc, IOC_E_ENABLE); 2605} 2606 2607void 2608bfa_nw_ioc_disable(struct bfa_ioc *ioc) 2609{ 2610 bfa_ioc_stats(ioc, ioc_disables); 2611 bfa_fsm_send_event(ioc, IOC_E_DISABLE); 2612} 2613 2614/* Initialize memory for saving firmware trace. */ 2615void 2616bfa_nw_ioc_debug_memclaim(struct bfa_ioc *ioc, void *dbg_fwsave) 2617{ 2618 ioc->dbg_fwsave = dbg_fwsave; 2619 ioc->dbg_fwsave_len = ioc->iocpf.auto_recover ? BNA_DBG_FWTRC_LEN : 0; 2620} 2621 2622static u32 2623bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr) 2624{ 2625 return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr); 2626} 2627 2628/* Register mailbox message handler function, to be called by common modules */ 2629void 2630bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc, 2631 bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg) 2632{ 2633 struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; 2634 2635 mod->mbhdlr[mc].cbfn = cbfn; 2636 mod->mbhdlr[mc].cbarg = cbarg; 2637} 2638 2639/** 2640 * bfa_nw_ioc_mbox_queue - Queue a mailbox command request to firmware. 2641 * 2642 * @ioc: IOC instance 2643 * @cmd: Mailbox command 2644 * @cbfn: callback function 2645 * @cbarg: arguments to callback 2646 * 2647 * Waits if mailbox is busy. Responsibility of caller to serialize 2648 */ 2649bool 2650bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd, 2651 bfa_mbox_cmd_cbfn_t cbfn, void *cbarg) 2652{ 2653 struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; 2654 u32 stat; 2655 2656 cmd->cbfn = cbfn; 2657 cmd->cbarg = cbarg; 2658 2659 /** 2660 * If a previous command is pending, queue new command 2661 */ 2662 if (!list_empty(&mod->cmd_q)) { 2663 list_add_tail(&cmd->qe, &mod->cmd_q); 2664 return true; 2665 } 2666 2667 /** 2668 * If mailbox is busy, queue command for poll timer 2669 */ 2670 stat = readl(ioc->ioc_regs.hfn_mbox_cmd); 2671 if (stat) { 2672 list_add_tail(&cmd->qe, &mod->cmd_q); 2673 return true; 2674 } 2675 2676 /** 2677 * mailbox is free -- queue command to firmware 2678 */ 2679 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); 2680 2681 return false; 2682} 2683 2684/* Handle mailbox interrupts */ 2685void 2686bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc) 2687{ 2688 struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; 2689 struct bfi_mbmsg m; 2690 int mc; 2691 2692 if (bfa_ioc_msgget(ioc, &m)) { 2693 /** 2694 * Treat IOC message class as special. 2695 */ 2696 mc = m.mh.msg_class; 2697 if (mc == BFI_MC_IOC) { 2698 bfa_ioc_isr(ioc, &m); 2699 return; 2700 } 2701 2702 if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL)) 2703 return; 2704 2705 mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m); 2706 } 2707 2708 bfa_ioc_lpu_read_stat(ioc); 2709 2710 /** 2711 * Try to send pending mailbox commands 2712 */ 2713 bfa_ioc_mbox_poll(ioc); 2714} 2715 2716void 2717bfa_nw_ioc_error_isr(struct bfa_ioc *ioc) 2718{ 2719 bfa_ioc_stats(ioc, ioc_hbfails); 2720 bfa_ioc_stats_hb_count(ioc, ioc->hb_count); 2721 bfa_fsm_send_event(ioc, IOC_E_HWERROR); 2722} 2723 2724/* return true if IOC is disabled */ 2725bool 2726bfa_nw_ioc_is_disabled(struct bfa_ioc *ioc) 2727{ 2728 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) || 2729 bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled); 2730} 2731 2732/* return true if IOC is operational */ 2733bool 2734bfa_nw_ioc_is_operational(struct bfa_ioc *ioc) 2735{ 2736 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op); 2737} 2738 2739/* Add to IOC heartbeat failure notification queue. To be used by common 2740 * modules such as cee, port, diag. 2741 */ 2742void 2743bfa_nw_ioc_notify_register(struct bfa_ioc *ioc, 2744 struct bfa_ioc_notify *notify) 2745{ 2746 list_add_tail(¬ify->qe, &ioc->notify_q); 2747} 2748 2749#define BFA_MFG_NAME "QLogic" 2750static void 2751bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc, 2752 struct bfa_adapter_attr *ad_attr) 2753{ 2754 struct bfi_ioc_attr *ioc_attr; 2755 2756 ioc_attr = ioc->attr; 2757 2758 bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num); 2759 bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver); 2760 bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver); 2761 bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer); 2762 memcpy(&ad_attr->vpd, &ioc_attr->vpd, 2763 sizeof(struct bfa_mfg_vpd)); 2764 2765 ad_attr->nports = bfa_ioc_get_nports(ioc); 2766 ad_attr->max_speed = bfa_ioc_speed_sup(ioc); 2767 2768 bfa_ioc_get_adapter_model(ioc, ad_attr->model); 2769 /* For now, model descr uses same model string */ 2770 bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr); 2771 2772 ad_attr->card_type = ioc_attr->card_type; 2773 ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type); 2774 2775 if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop)) 2776 ad_attr->prototype = 1; 2777 else 2778 ad_attr->prototype = 0; 2779 2780 ad_attr->pwwn = bfa_ioc_get_pwwn(ioc); 2781 bfa_nw_ioc_get_mac(ioc, ad_attr->mac); 2782 2783 ad_attr->pcie_gen = ioc_attr->pcie_gen; 2784 ad_attr->pcie_lanes = ioc_attr->pcie_lanes; 2785 ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig; 2786 ad_attr->asic_rev = ioc_attr->asic_rev; 2787 2788 bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver); 2789} 2790 2791static enum bfa_ioc_type 2792bfa_ioc_get_type(struct bfa_ioc *ioc) 2793{ 2794 if (ioc->clscode == BFI_PCIFN_CLASS_ETH) 2795 return BFA_IOC_TYPE_LL; 2796 2797 BUG_ON(!(ioc->clscode == BFI_PCIFN_CLASS_FC)); 2798 2799 return (ioc->attr->port_mode == BFI_PORT_MODE_FC) 2800 ? BFA_IOC_TYPE_FC : BFA_IOC_TYPE_FCoE; 2801} 2802 2803static void 2804bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, char *serial_num) 2805{ 2806 memcpy(serial_num, 2807 (void *)ioc->attr->brcd_serialnum, 2808 BFA_ADAPTER_SERIAL_NUM_LEN); 2809} 2810 2811static void 2812bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, char *fw_ver) 2813{ 2814 memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN); 2815} 2816 2817static void 2818bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, char *chip_rev) 2819{ 2820 BUG_ON(!(chip_rev)); 2821 2822 memset(chip_rev, 0, BFA_IOC_CHIP_REV_LEN); 2823 2824 chip_rev[0] = 'R'; 2825 chip_rev[1] = 'e'; 2826 chip_rev[2] = 'v'; 2827 chip_rev[3] = '-'; 2828 chip_rev[4] = ioc->attr->asic_rev; 2829 chip_rev[5] = '\0'; 2830} 2831 2832static void 2833bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver) 2834{ 2835 memcpy(optrom_ver, ioc->attr->optrom_version, 2836 BFA_VERSION_LEN); 2837} 2838 2839static void 2840bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, char *manufacturer) 2841{ 2842 strncpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); 2843} 2844 2845static void 2846bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model) 2847{ 2848 struct bfi_ioc_attr *ioc_attr; 2849 2850 BUG_ON(!(model)); 2851 memset(model, 0, BFA_ADAPTER_MODEL_NAME_LEN); 2852 2853 ioc_attr = ioc->attr; 2854 2855 snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u", 2856 BFA_MFG_NAME, ioc_attr->card_type); 2857} 2858 2859static enum bfa_ioc_state 2860bfa_ioc_get_state(struct bfa_ioc *ioc) 2861{ 2862 enum bfa_iocpf_state iocpf_st; 2863 enum bfa_ioc_state ioc_st = bfa_sm_to_state(ioc_sm_table, ioc->fsm); 2864 2865 if (ioc_st == BFA_IOC_ENABLING || 2866 ioc_st == BFA_IOC_FAIL || ioc_st == BFA_IOC_INITFAIL) { 2867 2868 iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm); 2869 2870 switch (iocpf_st) { 2871 case BFA_IOCPF_SEMWAIT: 2872 ioc_st = BFA_IOC_SEMWAIT; 2873 break; 2874 2875 case BFA_IOCPF_HWINIT: 2876 ioc_st = BFA_IOC_HWINIT; 2877 break; 2878 2879 case BFA_IOCPF_FWMISMATCH: 2880 ioc_st = BFA_IOC_FWMISMATCH; 2881 break; 2882 2883 case BFA_IOCPF_FAIL: 2884 ioc_st = BFA_IOC_FAIL; 2885 break; 2886 2887 case BFA_IOCPF_INITFAIL: 2888 ioc_st = BFA_IOC_INITFAIL; 2889 break; 2890 2891 default: 2892 break; 2893 } 2894 } 2895 return ioc_st; 2896} 2897 2898void 2899bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr) 2900{ 2901 memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr)); 2902 2903 ioc_attr->state = bfa_ioc_get_state(ioc); 2904 ioc_attr->port_id = bfa_ioc_portid(ioc); 2905 ioc_attr->port_mode = ioc->port_mode; 2906 2907 ioc_attr->port_mode_cfg = ioc->port_mode_cfg; 2908 ioc_attr->cap_bm = ioc->ad_cap_bm; 2909 2910 ioc_attr->ioc_type = bfa_ioc_get_type(ioc); 2911 2912 bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr); 2913 2914 ioc_attr->pci_attr.device_id = bfa_ioc_devid(ioc); 2915 ioc_attr->pci_attr.pcifn = bfa_ioc_pcifn(ioc); 2916 ioc_attr->def_fn = bfa_ioc_is_default(ioc); 2917 bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev); 2918} 2919 2920/* WWN public */ 2921static u64 2922bfa_ioc_get_pwwn(struct bfa_ioc *ioc) 2923{ 2924 return ioc->attr->pwwn; 2925} 2926 2927void 2928bfa_nw_ioc_get_mac(struct bfa_ioc *ioc, u8 *mac) 2929{ 2930 ether_addr_copy(mac, ioc->attr->mac); 2931} 2932 2933/* Firmware failure detected. Start recovery actions. */ 2934static void 2935bfa_ioc_recover(struct bfa_ioc *ioc) 2936{ 2937 pr_crit("Heart Beat of IOC has failed\n"); 2938 bfa_ioc_stats(ioc, ioc_hbfails); 2939 bfa_ioc_stats_hb_count(ioc, ioc->hb_count); 2940 bfa_fsm_send_event(ioc, IOC_E_HBFAIL); 2941} 2942 2943/* BFA IOC PF private functions */ 2944 2945static void 2946bfa_iocpf_enable(struct bfa_ioc *ioc) 2947{ 2948 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE); 2949} 2950 2951static void 2952bfa_iocpf_disable(struct bfa_ioc *ioc) 2953{ 2954 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE); 2955} 2956 2957static void 2958bfa_iocpf_fail(struct bfa_ioc *ioc) 2959{ 2960 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL); 2961} 2962 2963static void 2964bfa_iocpf_initfail(struct bfa_ioc *ioc) 2965{ 2966 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); 2967} 2968 2969static void 2970bfa_iocpf_getattrfail(struct bfa_ioc *ioc) 2971{ 2972 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL); 2973} 2974 2975static void 2976bfa_iocpf_stop(struct bfa_ioc *ioc) 2977{ 2978 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP); 2979} 2980 2981void 2982bfa_nw_iocpf_timeout(struct bfa_ioc *ioc) 2983{ 2984 enum bfa_iocpf_state iocpf_st; 2985 2986 iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm); 2987 2988 if (iocpf_st == BFA_IOCPF_HWINIT) 2989 bfa_ioc_poll_fwinit(ioc); 2990 else 2991 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT); 2992} 2993 2994void 2995bfa_nw_iocpf_sem_timeout(struct bfa_ioc *ioc) 2996{ 2997 bfa_ioc_hw_sem_get(ioc); 2998} 2999 3000static void 3001bfa_ioc_poll_fwinit(struct bfa_ioc *ioc) 3002{ 3003 u32 fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc); 3004 3005 if (fwstate == BFI_IOC_DISABLED) { 3006 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY); 3007 return; 3008 } 3009 3010 if (ioc->iocpf.poll_time >= BFA_IOC_TOV) { 3011 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT); 3012 } else { 3013 ioc->iocpf.poll_time += BFA_IOC_POLL_TOV; 3014 mod_timer(&ioc->iocpf_timer, jiffies + 3015 msecs_to_jiffies(BFA_IOC_POLL_TOV)); 3016 } 3017} 3018 3019/* 3020 * Flash module specific 3021 */ 3022 3023/* 3024 * FLASH DMA buffer should be big enough to hold both MFG block and 3025 * asic block(64k) at the same time and also should be 2k aligned to 3026 * avoid write segement to cross sector boundary. 3027 */ 3028#define BFA_FLASH_SEG_SZ 2048 3029#define BFA_FLASH_DMA_BUF_SZ \ 3030 roundup(0x010000 + sizeof(struct bfa_mfg_block), BFA_FLASH_SEG_SZ) 3031 3032static void 3033bfa_flash_cb(struct bfa_flash *flash) 3034{ 3035 flash->op_busy = 0; 3036 if (flash->cbfn) 3037 flash->cbfn(flash->cbarg, flash->status); 3038} 3039 3040static void 3041bfa_flash_notify(void *cbarg, enum bfa_ioc_event event) 3042{ 3043 struct bfa_flash *flash = cbarg; 3044 3045 switch (event) { 3046 case BFA_IOC_E_DISABLED: 3047 case BFA_IOC_E_FAILED: 3048 if (flash->op_busy) { 3049 flash->status = BFA_STATUS_IOC_FAILURE; 3050 flash->cbfn(flash->cbarg, flash->status); 3051 flash->op_busy = 0; 3052 } 3053 break; 3054 default: 3055 break; 3056 } 3057} 3058 3059/* 3060 * Send flash write request. 3061 */ 3062static void 3063bfa_flash_write_send(struct bfa_flash *flash) 3064{ 3065 struct bfi_flash_write_req *msg = 3066 (struct bfi_flash_write_req *) flash->mb.msg; 3067 u32 len; 3068 3069 msg->type = be32_to_cpu(flash->type); 3070 msg->instance = flash->instance; 3071 msg->offset = be32_to_cpu(flash->addr_off + flash->offset); 3072 len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ? 3073 flash->residue : BFA_FLASH_DMA_BUF_SZ; 3074 msg->length = be32_to_cpu(len); 3075 3076 /* indicate if it's the last msg of the whole write operation */ 3077 msg->last = (len == flash->residue) ? 1 : 0; 3078 3079 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_WRITE_REQ, 3080 bfa_ioc_portid(flash->ioc)); 3081 bfa_alen_set(&msg->alen, len, flash->dbuf_pa); 3082 memcpy(flash->dbuf_kva, flash->ubuf + flash->offset, len); 3083 bfa_nw_ioc_mbox_queue(flash->ioc, &flash->mb, NULL, NULL); 3084 3085 flash->residue -= len; 3086 flash->offset += len; 3087} 3088 3089/** 3090 * bfa_flash_read_send - Send flash read request. 3091 * 3092 * @cbarg: callback argument 3093 */ 3094static void 3095bfa_flash_read_send(void *cbarg) 3096{ 3097 struct bfa_flash *flash = cbarg; 3098 struct bfi_flash_read_req *msg = 3099 (struct bfi_flash_read_req *) flash->mb.msg; 3100 u32 len; 3101 3102 msg->type = be32_to_cpu(flash->type); 3103 msg->instance = flash->instance; 3104 msg->offset = be32_to_cpu(flash->addr_off + flash->offset); 3105 len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ? 3106 flash->residue : BFA_FLASH_DMA_BUF_SZ; 3107 msg->length = be32_to_cpu(len); 3108 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_READ_REQ, 3109 bfa_ioc_portid(flash->ioc)); 3110 bfa_alen_set(&msg->alen, len, flash->dbuf_pa); 3111 bfa_nw_ioc_mbox_queue(flash->ioc, &flash->mb, NULL, NULL); 3112} 3113 3114/** 3115 * bfa_flash_intr - Process flash response messages upon receiving interrupts. 3116 * 3117 * @flasharg: flash structure 3118 * @msg: message structure 3119 */ 3120static void 3121bfa_flash_intr(void *flasharg, struct bfi_mbmsg *msg) 3122{ 3123 struct bfa_flash *flash = flasharg; 3124 u32 status; 3125 3126 union { 3127 struct bfi_flash_query_rsp *query; 3128 struct bfi_flash_write_rsp *write; 3129 struct bfi_flash_read_rsp *read; 3130 struct bfi_mbmsg *msg; 3131 } m; 3132 3133 m.msg = msg; 3134 3135 /* receiving response after ioc failure */ 3136 if (!flash->op_busy && msg->mh.msg_id != BFI_FLASH_I2H_EVENT) 3137 return; 3138 3139 switch (msg->mh.msg_id) { 3140 case BFI_FLASH_I2H_QUERY_RSP: 3141 status = be32_to_cpu(m.query->status); 3142 if (status == BFA_STATUS_OK) { 3143 u32 i; 3144 struct bfa_flash_attr *attr, *f; 3145 3146 attr = (struct bfa_flash_attr *) flash->ubuf; 3147 f = (struct bfa_flash_attr *) flash->dbuf_kva; 3148 attr->status = be32_to_cpu(f->status); 3149 attr->npart = be32_to_cpu(f->npart); 3150 for (i = 0; i < attr->npart; i++) { 3151 attr->part[i].part_type = 3152 be32_to_cpu(f->part[i].part_type); 3153 attr->part[i].part_instance = 3154 be32_to_cpu(f->part[i].part_instance); 3155 attr->part[i].part_off = 3156 be32_to_cpu(f->part[i].part_off); 3157 attr->part[i].part_size = 3158 be32_to_cpu(f->part[i].part_size); 3159 attr->part[i].part_len = 3160 be32_to_cpu(f->part[i].part_len); 3161 attr->part[i].part_status = 3162 be32_to_cpu(f->part[i].part_status); 3163 } 3164 } 3165 flash->status = status; 3166 bfa_flash_cb(flash); 3167 break; 3168 case BFI_FLASH_I2H_WRITE_RSP: 3169 status = be32_to_cpu(m.write->status); 3170 if (status != BFA_STATUS_OK || flash->residue == 0) { 3171 flash->status = status; 3172 bfa_flash_cb(flash); 3173 } else 3174 bfa_flash_write_send(flash); 3175 break; 3176 case BFI_FLASH_I2H_READ_RSP: 3177 status = be32_to_cpu(m.read->status); 3178 if (status != BFA_STATUS_OK) { 3179 flash->status = status; 3180 bfa_flash_cb(flash); 3181 } else { 3182 u32 len = be32_to_cpu(m.read->length); 3183 memcpy(flash->ubuf + flash->offset, 3184 flash->dbuf_kva, len); 3185 flash->residue -= len; 3186 flash->offset += len; 3187 if (flash->residue == 0) { 3188 flash->status = status; 3189 bfa_flash_cb(flash); 3190 } else 3191 bfa_flash_read_send(flash); 3192 } 3193 break; 3194 case BFI_FLASH_I2H_BOOT_VER_RSP: 3195 case BFI_FLASH_I2H_EVENT: 3196 break; 3197 default: 3198 WARN_ON(1); 3199 } 3200} 3201 3202/* 3203 * Flash memory info API. 3204 */ 3205u32 3206bfa_nw_flash_meminfo(void) 3207{ 3208 return roundup(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 3209} 3210 3211/** 3212 * bfa_nw_flash_attach - Flash attach API. 3213 * 3214 * @flash: flash structure 3215 * @ioc: ioc structure 3216 * @dev: device structure 3217 */ 3218void 3219bfa_nw_flash_attach(struct bfa_flash *flash, struct bfa_ioc *ioc, void *dev) 3220{ 3221 flash->ioc = ioc; 3222 flash->cbfn = NULL; 3223 flash->cbarg = NULL; 3224 flash->op_busy = 0; 3225 3226 bfa_nw_ioc_mbox_regisr(flash->ioc, BFI_MC_FLASH, bfa_flash_intr, flash); 3227 bfa_ioc_notify_init(&flash->ioc_notify, bfa_flash_notify, flash); 3228 list_add_tail(&flash->ioc_notify.qe, &flash->ioc->notify_q); 3229} 3230 3231/** 3232 * bfa_nw_flash_memclaim - Claim memory for flash 3233 * 3234 * @flash: flash structure 3235 * @dm_kva: pointer to virtual memory address 3236 * @dm_pa: physical memory address 3237 */ 3238void 3239bfa_nw_flash_memclaim(struct bfa_flash *flash, u8 *dm_kva, u64 dm_pa) 3240{ 3241 flash->dbuf_kva = dm_kva; 3242 flash->dbuf_pa = dm_pa; 3243 memset(flash->dbuf_kva, 0, BFA_FLASH_DMA_BUF_SZ); 3244 dm_kva += roundup(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 3245 dm_pa += roundup(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); 3246} 3247 3248/** 3249 * bfa_nw_flash_get_attr - Get flash attribute. 3250 * 3251 * @flash: flash structure 3252 * @attr: flash attribute structure 3253 * @cbfn: callback function 3254 * @cbarg: callback argument 3255 * 3256 * Return status. 3257 */ 3258enum bfa_status 3259bfa_nw_flash_get_attr(struct bfa_flash *flash, struct bfa_flash_attr *attr, 3260 bfa_cb_flash cbfn, void *cbarg) 3261{ 3262 struct bfi_flash_query_req *msg = 3263 (struct bfi_flash_query_req *) flash->mb.msg; 3264 3265 if (!bfa_nw_ioc_is_operational(flash->ioc)) 3266 return BFA_STATUS_IOC_NON_OP; 3267 3268 if (flash->op_busy) 3269 return BFA_STATUS_DEVBUSY; 3270 3271 flash->op_busy = 1; 3272 flash->cbfn = cbfn; 3273 flash->cbarg = cbarg; 3274 flash->ubuf = (u8 *) attr; 3275 3276 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_QUERY_REQ, 3277 bfa_ioc_portid(flash->ioc)); 3278 bfa_alen_set(&msg->alen, sizeof(struct bfa_flash_attr), flash->dbuf_pa); 3279 bfa_nw_ioc_mbox_queue(flash->ioc, &flash->mb, NULL, NULL); 3280 3281 return BFA_STATUS_OK; 3282} 3283 3284/** 3285 * bfa_nw_flash_update_part - Update flash partition. 3286 * 3287 * @flash: flash structure 3288 * @type: flash partition type 3289 * @instance: flash partition instance 3290 * @buf: update data buffer 3291 * @len: data buffer length 3292 * @offset: offset relative to the partition starting address 3293 * @cbfn: callback function 3294 * @cbarg: callback argument 3295 * 3296 * Return status. 3297 */ 3298enum bfa_status 3299bfa_nw_flash_update_part(struct bfa_flash *flash, u32 type, u8 instance, 3300 void *buf, u32 len, u32 offset, 3301 bfa_cb_flash cbfn, void *cbarg) 3302{ 3303 if (!bfa_nw_ioc_is_operational(flash->ioc)) 3304 return BFA_STATUS_IOC_NON_OP; 3305 3306 /* 3307 * 'len' must be in word (4-byte) boundary 3308 */ 3309 if (!len || (len & 0x03)) 3310 return BFA_STATUS_FLASH_BAD_LEN; 3311 3312 if (type == BFA_FLASH_PART_MFG) 3313 return BFA_STATUS_EINVAL; 3314 3315 if (flash->op_busy) 3316 return BFA_STATUS_DEVBUSY; 3317 3318 flash->op_busy = 1; 3319 flash->cbfn = cbfn; 3320 flash->cbarg = cbarg; 3321 flash->type = type; 3322 flash->instance = instance; 3323 flash->residue = len; 3324 flash->offset = 0; 3325 flash->addr_off = offset; 3326 flash->ubuf = buf; 3327 3328 bfa_flash_write_send(flash); 3329 3330 return BFA_STATUS_OK; 3331} 3332 3333/** 3334 * bfa_nw_flash_read_part - Read flash partition. 3335 * 3336 * @flash: flash structure 3337 * @type: flash partition type 3338 * @instance: flash partition instance 3339 * @buf: read data buffer 3340 * @len: data buffer length 3341 * @offset: offset relative to the partition starting address 3342 * @cbfn: callback function 3343 * @cbarg: callback argument 3344 * 3345 * Return status. 3346 */ 3347enum bfa_status 3348bfa_nw_flash_read_part(struct bfa_flash *flash, u32 type, u8 instance, 3349 void *buf, u32 len, u32 offset, 3350 bfa_cb_flash cbfn, void *cbarg) 3351{ 3352 if (!bfa_nw_ioc_is_operational(flash->ioc)) 3353 return BFA_STATUS_IOC_NON_OP; 3354 3355 /* 3356 * 'len' must be in word (4-byte) boundary 3357 */ 3358 if (!len || (len & 0x03)) 3359 return BFA_STATUS_FLASH_BAD_LEN; 3360 3361 if (flash->op_busy) 3362 return BFA_STATUS_DEVBUSY; 3363 3364 flash->op_busy = 1; 3365 flash->cbfn = cbfn; 3366 flash->cbarg = cbarg; 3367 flash->type = type; 3368 flash->instance = instance; 3369 flash->residue = len; 3370 flash->offset = 0; 3371 flash->addr_off = offset; 3372 flash->ubuf = buf; 3373 3374 bfa_flash_read_send(flash); 3375 3376 return BFA_STATUS_OK; 3377}