Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.0-rc7 2285 lines 50 kB view raw
1/* 2 * Linux network driver for Brocade Converged Network Adapter. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License (GPL) Version 2 as 6 * published by the Free Software Foundation 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License for more details. 12 */ 13/* 14 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. 15 * All rights reserved 16 * www.brocade.com 17 */ 18 19#include "bfa_ioc.h" 20#include "cna.h" 21#include "bfi.h" 22#include "bfi_ctreg.h" 23#include "bfa_defs.h" 24 25/** 26 * IOC local definitions 27 */ 28 29/** 30 * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details. 31 */ 32 33#define bfa_ioc_firmware_lock(__ioc) \ 34 ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc)) 35#define bfa_ioc_firmware_unlock(__ioc) \ 36 ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc)) 37#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc)) 38#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc)) 39#define bfa_ioc_notify_fail(__ioc) \ 40 ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc)) 41#define bfa_ioc_sync_start(__ioc) \ 42 ((__ioc)->ioc_hwif->ioc_sync_start(__ioc)) 43#define bfa_ioc_sync_join(__ioc) \ 44 ((__ioc)->ioc_hwif->ioc_sync_join(__ioc)) 45#define bfa_ioc_sync_leave(__ioc) \ 46 ((__ioc)->ioc_hwif->ioc_sync_leave(__ioc)) 47#define bfa_ioc_sync_ack(__ioc) \ 48 ((__ioc)->ioc_hwif->ioc_sync_ack(__ioc)) 49#define bfa_ioc_sync_complete(__ioc) \ 50 ((__ioc)->ioc_hwif->ioc_sync_complete(__ioc)) 51 52#define bfa_ioc_mbox_cmd_pending(__ioc) \ 53 (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \ 54 readl((__ioc)->ioc_regs.hfn_mbox_cmd)) 55 56static bool bfa_nw_auto_recover = true; 57 58/* 59 * forward declarations 60 */ 61static void bfa_ioc_hw_sem_get(struct bfa_ioc *ioc); 62static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc); 63static void bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force); 64static void bfa_ioc_send_enable(struct bfa_ioc *ioc); 65static void bfa_ioc_send_disable(struct bfa_ioc *ioc); 66static void bfa_ioc_send_getattr(struct bfa_ioc *ioc); 67static void bfa_ioc_hb_monitor(struct bfa_ioc *ioc); 68static void bfa_ioc_hb_stop(struct bfa_ioc *ioc); 69static void bfa_ioc_reset(struct bfa_ioc *ioc, bool force); 70static void bfa_ioc_mbox_poll(struct bfa_ioc *ioc); 71static void bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc); 72static void bfa_ioc_recover(struct bfa_ioc *ioc); 73static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc); 74static void bfa_ioc_disable_comp(struct bfa_ioc *ioc); 75static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc); 76static void bfa_ioc_fail_notify(struct bfa_ioc *ioc); 77static void bfa_ioc_pf_enabled(struct bfa_ioc *ioc); 78static void bfa_ioc_pf_disabled(struct bfa_ioc *ioc); 79static void bfa_ioc_pf_initfailed(struct bfa_ioc *ioc); 80static void bfa_ioc_pf_failed(struct bfa_ioc *ioc); 81static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc); 82static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, 83 u32 boot_param); 84static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr); 85static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, 86 char *serial_num); 87static void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, 88 char *fw_ver); 89static void bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, 90 char *chip_rev); 91static void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, 92 char *optrom_ver); 93static void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, 94 char *manufacturer); 95static void bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model); 96static u64 bfa_ioc_get_pwwn(struct bfa_ioc *ioc); 97 98/** 99 * IOC state machine definitions/declarations 100 */ 101enum ioc_event { 102 IOC_E_RESET = 1, /*!< IOC reset request */ 103 IOC_E_ENABLE = 2, /*!< IOC enable request */ 104 IOC_E_DISABLE = 3, /*!< IOC disable request */ 105 IOC_E_DETACH = 4, /*!< driver detach cleanup */ 106 IOC_E_ENABLED = 5, /*!< f/w enabled */ 107 IOC_E_FWRSP_GETATTR = 6, /*!< IOC get attribute response */ 108 IOC_E_DISABLED = 7, /*!< f/w disabled */ 109 IOC_E_INITFAILED = 8, /*!< failure notice by iocpf sm */ 110 IOC_E_PFAILED = 9, /*!< failure notice by iocpf sm */ 111 IOC_E_HBFAIL = 10, /*!< heartbeat failure */ 112 IOC_E_HWERROR = 11, /*!< hardware error interrupt */ 113 IOC_E_TIMEOUT = 12, /*!< timeout */ 114}; 115 116bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc, enum ioc_event); 117bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc, enum ioc_event); 118bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc, enum ioc_event); 119bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc, enum ioc_event); 120bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc, enum ioc_event); 121bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc, enum ioc_event); 122bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc, enum ioc_event); 123bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc, enum ioc_event); 124bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc, enum ioc_event); 125 126static struct bfa_sm_table ioc_sm_table[] = { 127 {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT}, 128 {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET}, 129 {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING}, 130 {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR}, 131 {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL}, 132 {BFA_SM(bfa_ioc_sm_fail_retry), BFA_IOC_INITFAIL}, 133 {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL}, 134 {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, 135 {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, 136}; 137 138/** 139 * IOCPF state machine definitions/declarations 140 */ 141 142/* 143 * Forward declareations for iocpf state machine 144 */ 145static void bfa_iocpf_enable(struct bfa_ioc *ioc); 146static void bfa_iocpf_disable(struct bfa_ioc *ioc); 147static void bfa_iocpf_fail(struct bfa_ioc *ioc); 148static void bfa_iocpf_initfail(struct bfa_ioc *ioc); 149static void bfa_iocpf_getattrfail(struct bfa_ioc *ioc); 150static void bfa_iocpf_stop(struct bfa_ioc *ioc); 151 152/** 153 * IOCPF state machine events 154 */ 155enum iocpf_event { 156 IOCPF_E_ENABLE = 1, /*!< IOCPF enable request */ 157 IOCPF_E_DISABLE = 2, /*!< IOCPF disable request */ 158 IOCPF_E_STOP = 3, /*!< stop on driver detach */ 159 IOCPF_E_FWREADY = 4, /*!< f/w initialization done */ 160 IOCPF_E_FWRSP_ENABLE = 5, /*!< enable f/w response */ 161 IOCPF_E_FWRSP_DISABLE = 6, /*!< disable f/w response */ 162 IOCPF_E_FAIL = 7, /*!< failure notice by ioc sm */ 163 IOCPF_E_INITFAIL = 8, /*!< init fail notice by ioc sm */ 164 IOCPF_E_GETATTRFAIL = 9, /*!< init fail notice by ioc sm */ 165 IOCPF_E_SEMLOCKED = 10, /*!< h/w semaphore is locked */ 166 IOCPF_E_TIMEOUT = 11, /*!< f/w response timeout */ 167}; 168 169/** 170 * IOCPF states 171 */ 172enum bfa_iocpf_state { 173 BFA_IOCPF_RESET = 1, /*!< IOC is in reset state */ 174 BFA_IOCPF_SEMWAIT = 2, /*!< Waiting for IOC h/w semaphore */ 175 BFA_IOCPF_HWINIT = 3, /*!< IOC h/w is being initialized */ 176 BFA_IOCPF_READY = 4, /*!< IOCPF is initialized */ 177 BFA_IOCPF_INITFAIL = 5, /*!< IOCPF failed */ 178 BFA_IOCPF_FAIL = 6, /*!< IOCPF failed */ 179 BFA_IOCPF_DISABLING = 7, /*!< IOCPF is being disabled */ 180 BFA_IOCPF_DISABLED = 8, /*!< IOCPF is disabled */ 181 BFA_IOCPF_FWMISMATCH = 9, /*!< IOC f/w different from drivers */ 182}; 183 184bfa_fsm_state_decl(bfa_iocpf, reset, struct bfa_iocpf, enum iocpf_event); 185bfa_fsm_state_decl(bfa_iocpf, fwcheck, struct bfa_iocpf, enum iocpf_event); 186bfa_fsm_state_decl(bfa_iocpf, mismatch, struct bfa_iocpf, enum iocpf_event); 187bfa_fsm_state_decl(bfa_iocpf, semwait, struct bfa_iocpf, enum iocpf_event); 188bfa_fsm_state_decl(bfa_iocpf, hwinit, struct bfa_iocpf, enum iocpf_event); 189bfa_fsm_state_decl(bfa_iocpf, enabling, struct bfa_iocpf, enum iocpf_event); 190bfa_fsm_state_decl(bfa_iocpf, ready, struct bfa_iocpf, enum iocpf_event); 191bfa_fsm_state_decl(bfa_iocpf, initfail_sync, struct bfa_iocpf, 192 enum iocpf_event); 193bfa_fsm_state_decl(bfa_iocpf, initfail, struct bfa_iocpf, enum iocpf_event); 194bfa_fsm_state_decl(bfa_iocpf, fail_sync, struct bfa_iocpf, enum iocpf_event); 195bfa_fsm_state_decl(bfa_iocpf, fail, struct bfa_iocpf, enum iocpf_event); 196bfa_fsm_state_decl(bfa_iocpf, disabling, struct bfa_iocpf, enum iocpf_event); 197bfa_fsm_state_decl(bfa_iocpf, disabling_sync, struct bfa_iocpf, 198 enum iocpf_event); 199bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf, enum iocpf_event); 200 201static struct bfa_sm_table iocpf_sm_table[] = { 202 {BFA_SM(bfa_iocpf_sm_reset), BFA_IOCPF_RESET}, 203 {BFA_SM(bfa_iocpf_sm_fwcheck), BFA_IOCPF_FWMISMATCH}, 204 {BFA_SM(bfa_iocpf_sm_mismatch), BFA_IOCPF_FWMISMATCH}, 205 {BFA_SM(bfa_iocpf_sm_semwait), BFA_IOCPF_SEMWAIT}, 206 {BFA_SM(bfa_iocpf_sm_hwinit), BFA_IOCPF_HWINIT}, 207 {BFA_SM(bfa_iocpf_sm_enabling), BFA_IOCPF_HWINIT}, 208 {BFA_SM(bfa_iocpf_sm_ready), BFA_IOCPF_READY}, 209 {BFA_SM(bfa_iocpf_sm_initfail_sync), BFA_IOCPF_INITFAIL}, 210 {BFA_SM(bfa_iocpf_sm_initfail), BFA_IOCPF_INITFAIL}, 211 {BFA_SM(bfa_iocpf_sm_fail_sync), BFA_IOCPF_FAIL}, 212 {BFA_SM(bfa_iocpf_sm_fail), BFA_IOCPF_FAIL}, 213 {BFA_SM(bfa_iocpf_sm_disabling), BFA_IOCPF_DISABLING}, 214 {BFA_SM(bfa_iocpf_sm_disabling_sync), BFA_IOCPF_DISABLING}, 215 {BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED}, 216}; 217 218/** 219 * IOC State Machine 220 */ 221 222/** 223 * Beginning state. IOC uninit state. 224 */ 225static void 226bfa_ioc_sm_uninit_entry(struct bfa_ioc *ioc) 227{ 228} 229 230/** 231 * IOC is in uninit state. 232 */ 233static void 234bfa_ioc_sm_uninit(struct bfa_ioc *ioc, enum ioc_event event) 235{ 236 switch (event) { 237 case IOC_E_RESET: 238 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); 239 break; 240 241 default: 242 bfa_sm_fault(ioc, event); 243 } 244} 245 246/** 247 * Reset entry actions -- initialize state machine 248 */ 249static void 250bfa_ioc_sm_reset_entry(struct bfa_ioc *ioc) 251{ 252 bfa_fsm_set_state(&ioc->iocpf, bfa_iocpf_sm_reset); 253} 254 255/** 256 * IOC is in reset state. 257 */ 258static void 259bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event) 260{ 261 switch (event) { 262 case IOC_E_ENABLE: 263 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); 264 break; 265 266 case IOC_E_DISABLE: 267 bfa_ioc_disable_comp(ioc); 268 break; 269 270 case IOC_E_DETACH: 271 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 272 break; 273 274 default: 275 bfa_sm_fault(ioc, event); 276 } 277} 278 279static void 280bfa_ioc_sm_enabling_entry(struct bfa_ioc *ioc) 281{ 282 bfa_iocpf_enable(ioc); 283} 284 285/** 286 * Host IOC function is being enabled, awaiting response from firmware. 287 * Semaphore is acquired. 288 */ 289static void 290bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event) 291{ 292 switch (event) { 293 case IOC_E_ENABLED: 294 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); 295 break; 296 297 case IOC_E_PFAILED: 298 /* !!! fall through !!! */ 299 case IOC_E_HWERROR: 300 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 301 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); 302 if (event != IOC_E_PFAILED) 303 bfa_iocpf_initfail(ioc); 304 break; 305 306 case IOC_E_DISABLE: 307 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 308 break; 309 310 case IOC_E_DETACH: 311 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 312 bfa_iocpf_stop(ioc); 313 break; 314 315 case IOC_E_ENABLE: 316 break; 317 318 default: 319 bfa_sm_fault(ioc, event); 320 } 321} 322 323/** 324 * Semaphore should be acquired for version check. 325 */ 326static void 327bfa_ioc_sm_getattr_entry(struct bfa_ioc *ioc) 328{ 329 mod_timer(&ioc->ioc_timer, jiffies + 330 msecs_to_jiffies(BFA_IOC_TOV)); 331 bfa_ioc_send_getattr(ioc); 332} 333 334/** 335 * IOC configuration in progress. Timer is active. 336 */ 337static void 338bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event) 339{ 340 switch (event) { 341 case IOC_E_FWRSP_GETATTR: 342 del_timer(&ioc->ioc_timer); 343 bfa_ioc_check_attr_wwns(ioc); 344 bfa_fsm_set_state(ioc, bfa_ioc_sm_op); 345 break; 346 347 case IOC_E_PFAILED: 348 case IOC_E_HWERROR: 349 del_timer(&ioc->ioc_timer); 350 /* fall through */ 351 case IOC_E_TIMEOUT: 352 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 353 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); 354 if (event != IOC_E_PFAILED) 355 bfa_iocpf_getattrfail(ioc); 356 break; 357 358 case IOC_E_DISABLE: 359 del_timer(&ioc->ioc_timer); 360 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 361 break; 362 363 case IOC_E_ENABLE: 364 break; 365 366 default: 367 bfa_sm_fault(ioc, event); 368 } 369} 370 371static void 372bfa_ioc_sm_op_entry(struct bfa_ioc *ioc) 373{ 374 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); 375 bfa_ioc_hb_monitor(ioc); 376} 377 378static void 379bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event) 380{ 381 switch (event) { 382 case IOC_E_ENABLE: 383 break; 384 385 case IOC_E_DISABLE: 386 bfa_ioc_hb_stop(ioc); 387 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 388 break; 389 390 case IOC_E_PFAILED: 391 case IOC_E_HWERROR: 392 bfa_ioc_hb_stop(ioc); 393 /* !!! fall through !!! */ 394 case IOC_E_HBFAIL: 395 bfa_ioc_fail_notify(ioc); 396 if (ioc->iocpf.auto_recover) 397 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry); 398 else 399 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 400 401 if (event != IOC_E_PFAILED) 402 bfa_iocpf_fail(ioc); 403 break; 404 405 default: 406 bfa_sm_fault(ioc, event); 407 } 408} 409 410static void 411bfa_ioc_sm_disabling_entry(struct bfa_ioc *ioc) 412{ 413 bfa_iocpf_disable(ioc); 414} 415 416/** 417 * IOC is being desabled 418 */ 419static void 420bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event) 421{ 422 switch (event) { 423 case IOC_E_DISABLED: 424 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); 425 break; 426 427 case IOC_E_HWERROR: 428 /* 429 * No state change. Will move to disabled state 430 * after iocpf sm completes failure processing and 431 * moves to disabled state. 432 */ 433 bfa_iocpf_fail(ioc); 434 break; 435 436 default: 437 bfa_sm_fault(ioc, event); 438 } 439} 440 441/** 442 * IOC desable completion entry. 443 */ 444static void 445bfa_ioc_sm_disabled_entry(struct bfa_ioc *ioc) 446{ 447 bfa_ioc_disable_comp(ioc); 448} 449 450static void 451bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event) 452{ 453 switch (event) { 454 case IOC_E_ENABLE: 455 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); 456 break; 457 458 case IOC_E_DISABLE: 459 ioc->cbfn->disable_cbfn(ioc->bfa); 460 break; 461 462 case IOC_E_DETACH: 463 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 464 bfa_iocpf_stop(ioc); 465 break; 466 467 default: 468 bfa_sm_fault(ioc, event); 469 } 470} 471 472static void 473bfa_ioc_sm_fail_retry_entry(struct bfa_ioc *ioc) 474{ 475} 476 477/** 478 * Hardware initialization retry. 479 */ 480static void 481bfa_ioc_sm_fail_retry(struct bfa_ioc *ioc, enum ioc_event event) 482{ 483 switch (event) { 484 case IOC_E_ENABLED: 485 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); 486 break; 487 488 case IOC_E_PFAILED: 489 case IOC_E_HWERROR: 490 /** 491 * Initialization retry failed. 492 */ 493 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 494 if (event != IOC_E_PFAILED) 495 bfa_iocpf_initfail(ioc); 496 break; 497 498 case IOC_E_INITFAILED: 499 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 500 break; 501 502 case IOC_E_ENABLE: 503 break; 504 505 case IOC_E_DISABLE: 506 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 507 break; 508 509 case IOC_E_DETACH: 510 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 511 bfa_iocpf_stop(ioc); 512 break; 513 514 default: 515 bfa_sm_fault(ioc, event); 516 } 517} 518 519static void 520bfa_ioc_sm_fail_entry(struct bfa_ioc *ioc) 521{ 522} 523 524/** 525 * IOC failure. 526 */ 527static void 528bfa_ioc_sm_fail(struct bfa_ioc *ioc, enum ioc_event event) 529{ 530 switch (event) { 531 case IOC_E_ENABLE: 532 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 533 break; 534 535 case IOC_E_DISABLE: 536 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 537 break; 538 539 case IOC_E_DETACH: 540 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 541 bfa_iocpf_stop(ioc); 542 break; 543 544 case IOC_E_HWERROR: 545 /* HB failure notification, ignore. */ 546 break; 547 548 default: 549 bfa_sm_fault(ioc, event); 550 } 551} 552 553/** 554 * IOCPF State Machine 555 */ 556 557/** 558 * Reset entry actions -- initialize state machine 559 */ 560static void 561bfa_iocpf_sm_reset_entry(struct bfa_iocpf *iocpf) 562{ 563 iocpf->retry_count = 0; 564 iocpf->auto_recover = bfa_nw_auto_recover; 565} 566 567/** 568 * Beginning state. IOC is in reset state. 569 */ 570static void 571bfa_iocpf_sm_reset(struct bfa_iocpf *iocpf, enum iocpf_event event) 572{ 573 switch (event) { 574 case IOCPF_E_ENABLE: 575 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck); 576 break; 577 578 case IOCPF_E_STOP: 579 break; 580 581 default: 582 bfa_sm_fault(iocpf->ioc, event); 583 } 584} 585 586/** 587 * Semaphore should be acquired for version check. 588 */ 589static void 590bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf *iocpf) 591{ 592 bfa_ioc_hw_sem_get(iocpf->ioc); 593} 594 595/** 596 * Awaiting h/w semaphore to continue with version check. 597 */ 598static void 599bfa_iocpf_sm_fwcheck(struct bfa_iocpf *iocpf, enum iocpf_event event) 600{ 601 struct bfa_ioc *ioc = iocpf->ioc; 602 603 switch (event) { 604 case IOCPF_E_SEMLOCKED: 605 if (bfa_ioc_firmware_lock(ioc)) { 606 if (bfa_ioc_sync_start(ioc)) { 607 iocpf->retry_count = 0; 608 bfa_ioc_sync_join(ioc); 609 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 610 } else { 611 bfa_ioc_firmware_unlock(ioc); 612 bfa_nw_ioc_hw_sem_release(ioc); 613 mod_timer(&ioc->sem_timer, jiffies + 614 msecs_to_jiffies(BFA_IOC_HWSEM_TOV)); 615 } 616 } else { 617 bfa_nw_ioc_hw_sem_release(ioc); 618 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_mismatch); 619 } 620 break; 621 622 case IOCPF_E_DISABLE: 623 bfa_ioc_hw_sem_get_cancel(ioc); 624 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 625 bfa_ioc_pf_disabled(ioc); 626 break; 627 628 case IOCPF_E_STOP: 629 bfa_ioc_hw_sem_get_cancel(ioc); 630 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 631 break; 632 633 default: 634 bfa_sm_fault(ioc, event); 635 } 636} 637 638/** 639 * Notify enable completion callback 640 */ 641static void 642bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf *iocpf) 643{ 644 /* Call only the first time sm enters fwmismatch state. */ 645 if (iocpf->retry_count == 0) 646 bfa_ioc_pf_fwmismatch(iocpf->ioc); 647 648 iocpf->retry_count++; 649 mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies + 650 msecs_to_jiffies(BFA_IOC_TOV)); 651} 652 653/** 654 * Awaiting firmware version match. 655 */ 656static void 657bfa_iocpf_sm_mismatch(struct bfa_iocpf *iocpf, enum iocpf_event event) 658{ 659 struct bfa_ioc *ioc = iocpf->ioc; 660 661 switch (event) { 662 case IOCPF_E_TIMEOUT: 663 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck); 664 break; 665 666 case IOCPF_E_DISABLE: 667 del_timer(&ioc->iocpf_timer); 668 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 669 bfa_ioc_pf_disabled(ioc); 670 break; 671 672 case IOCPF_E_STOP: 673 del_timer(&ioc->iocpf_timer); 674 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 675 break; 676 677 default: 678 bfa_sm_fault(ioc, event); 679 } 680} 681 682/** 683 * Request for semaphore. 684 */ 685static void 686bfa_iocpf_sm_semwait_entry(struct bfa_iocpf *iocpf) 687{ 688 bfa_ioc_hw_sem_get(iocpf->ioc); 689} 690 691/** 692 * Awaiting semaphore for h/w initialzation. 693 */ 694static void 695bfa_iocpf_sm_semwait(struct bfa_iocpf *iocpf, enum iocpf_event event) 696{ 697 struct bfa_ioc *ioc = iocpf->ioc; 698 699 switch (event) { 700 case IOCPF_E_SEMLOCKED: 701 if (bfa_ioc_sync_complete(ioc)) { 702 bfa_ioc_sync_join(ioc); 703 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 704 } else { 705 bfa_nw_ioc_hw_sem_release(ioc); 706 mod_timer(&ioc->sem_timer, jiffies + 707 msecs_to_jiffies(BFA_IOC_HWSEM_TOV)); 708 } 709 break; 710 711 case IOCPF_E_DISABLE: 712 bfa_ioc_hw_sem_get_cancel(ioc); 713 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 714 break; 715 716 default: 717 bfa_sm_fault(ioc, event); 718 } 719} 720 721static void 722bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf *iocpf) 723{ 724 mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies + 725 msecs_to_jiffies(BFA_IOC_TOV)); 726 bfa_ioc_reset(iocpf->ioc, 0); 727} 728 729/** 730 * Hardware is being initialized. Interrupts are enabled. 731 * Holding hardware semaphore lock. 732 */ 733static void 734bfa_iocpf_sm_hwinit(struct bfa_iocpf *iocpf, enum iocpf_event event) 735{ 736 struct bfa_ioc *ioc = iocpf->ioc; 737 738 switch (event) { 739 case IOCPF_E_FWREADY: 740 del_timer(&ioc->iocpf_timer); 741 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling); 742 break; 743 744 case IOCPF_E_INITFAIL: 745 del_timer(&ioc->iocpf_timer); 746 /* 747 * !!! fall through !!! 748 */ 749 750 case IOCPF_E_TIMEOUT: 751 bfa_nw_ioc_hw_sem_release(ioc); 752 if (event == IOCPF_E_TIMEOUT) 753 bfa_ioc_pf_failed(ioc); 754 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 755 break; 756 757 case IOCPF_E_DISABLE: 758 del_timer(&ioc->iocpf_timer); 759 bfa_ioc_sync_leave(ioc); 760 bfa_nw_ioc_hw_sem_release(ioc); 761 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 762 break; 763 764 default: 765 bfa_sm_fault(ioc, event); 766 } 767} 768 769static void 770bfa_iocpf_sm_enabling_entry(struct bfa_iocpf *iocpf) 771{ 772 mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies + 773 msecs_to_jiffies(BFA_IOC_TOV)); 774 bfa_ioc_send_enable(iocpf->ioc); 775} 776 777/** 778 * Host IOC function is being enabled, awaiting response from firmware. 779 * Semaphore is acquired. 780 */ 781static void 782bfa_iocpf_sm_enabling(struct bfa_iocpf *iocpf, enum iocpf_event event) 783{ 784 struct bfa_ioc *ioc = iocpf->ioc; 785 786 switch (event) { 787 case IOCPF_E_FWRSP_ENABLE: 788 del_timer(&ioc->iocpf_timer); 789 bfa_nw_ioc_hw_sem_release(ioc); 790 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready); 791 break; 792 793 case IOCPF_E_INITFAIL: 794 del_timer(&ioc->iocpf_timer); 795 /* 796 * !!! fall through !!! 797 */ 798 case IOCPF_E_TIMEOUT: 799 bfa_nw_ioc_hw_sem_release(ioc); 800 if (event == IOCPF_E_TIMEOUT) 801 bfa_ioc_pf_failed(ioc); 802 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 803 break; 804 805 case IOCPF_E_DISABLE: 806 del_timer(&ioc->iocpf_timer); 807 bfa_nw_ioc_hw_sem_release(ioc); 808 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling); 809 break; 810 811 case IOCPF_E_FWREADY: 812 bfa_ioc_send_enable(ioc); 813 break; 814 815 default: 816 bfa_sm_fault(ioc, event); 817 } 818} 819 820static bool 821bfa_nw_ioc_is_operational(struct bfa_ioc *ioc) 822{ 823 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op); 824} 825 826static void 827bfa_iocpf_sm_ready_entry(struct bfa_iocpf *iocpf) 828{ 829 bfa_ioc_pf_enabled(iocpf->ioc); 830} 831 832static void 833bfa_iocpf_sm_ready(struct bfa_iocpf *iocpf, enum iocpf_event event) 834{ 835 struct bfa_ioc *ioc = iocpf->ioc; 836 837 switch (event) { 838 case IOCPF_E_DISABLE: 839 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling); 840 break; 841 842 case IOCPF_E_GETATTRFAIL: 843 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 844 break; 845 846 case IOCPF_E_FAIL: 847 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync); 848 break; 849 850 case IOCPF_E_FWREADY: 851 bfa_ioc_pf_failed(ioc); 852 if (bfa_nw_ioc_is_operational(ioc)) 853 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync); 854 else 855 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync); 856 break; 857 858 default: 859 bfa_sm_fault(ioc, event); 860 } 861} 862 863static void 864bfa_iocpf_sm_disabling_entry(struct bfa_iocpf *iocpf) 865{ 866 mod_timer(&(iocpf->ioc)->iocpf_timer, jiffies + 867 msecs_to_jiffies(BFA_IOC_TOV)); 868 bfa_ioc_send_disable(iocpf->ioc); 869} 870 871/** 872 * IOC is being disabled 873 */ 874static void 875bfa_iocpf_sm_disabling(struct bfa_iocpf *iocpf, enum iocpf_event event) 876{ 877 struct bfa_ioc *ioc = iocpf->ioc; 878 879 switch (event) { 880 case IOCPF_E_FWRSP_DISABLE: 881 case IOCPF_E_FWREADY: 882 del_timer(&ioc->iocpf_timer); 883 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 884 break; 885 886 case IOCPF_E_FAIL: 887 del_timer(&ioc->iocpf_timer); 888 /* 889 * !!! fall through !!! 890 */ 891 892 case IOCPF_E_TIMEOUT: 893 writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); 894 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 895 break; 896 897 case IOCPF_E_FWRSP_ENABLE: 898 break; 899 900 default: 901 bfa_sm_fault(ioc, event); 902 } 903} 904 905static void 906bfa_iocpf_sm_disabling_sync_entry(struct bfa_iocpf *iocpf) 907{ 908 bfa_ioc_hw_sem_get(iocpf->ioc); 909} 910 911/** 912 * IOC hb ack request is being removed. 913 */ 914static void 915bfa_iocpf_sm_disabling_sync(struct bfa_iocpf *iocpf, enum iocpf_event event) 916{ 917 struct bfa_ioc *ioc = iocpf->ioc; 918 919 switch (event) { 920 case IOCPF_E_SEMLOCKED: 921 bfa_ioc_sync_leave(ioc); 922 bfa_nw_ioc_hw_sem_release(ioc); 923 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 924 break; 925 926 case IOCPF_E_FAIL: 927 break; 928 929 default: 930 bfa_sm_fault(ioc, event); 931 } 932} 933 934/** 935 * IOC disable completion entry. 936 */ 937static void 938bfa_iocpf_sm_disabled_entry(struct bfa_iocpf *iocpf) 939{ 940 bfa_ioc_pf_disabled(iocpf->ioc); 941} 942 943static void 944bfa_iocpf_sm_disabled(struct bfa_iocpf *iocpf, enum iocpf_event event) 945{ 946 struct bfa_ioc *ioc = iocpf->ioc; 947 948 switch (event) { 949 case IOCPF_E_ENABLE: 950 iocpf->retry_count = 0; 951 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); 952 break; 953 954 case IOCPF_E_STOP: 955 bfa_ioc_firmware_unlock(ioc); 956 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 957 break; 958 959 default: 960 bfa_sm_fault(ioc, event); 961 } 962} 963 964static void 965bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf *iocpf) 966{ 967 bfa_ioc_hw_sem_get(iocpf->ioc); 968} 969 970/** 971 * Hardware initialization failed. 972 */ 973static void 974bfa_iocpf_sm_initfail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event) 975{ 976 struct bfa_ioc *ioc = iocpf->ioc; 977 978 switch (event) { 979 case IOCPF_E_SEMLOCKED: 980 bfa_ioc_notify_fail(ioc); 981 bfa_ioc_sync_ack(ioc); 982 iocpf->retry_count++; 983 if (iocpf->retry_count >= BFA_IOC_HWINIT_MAX) { 984 bfa_ioc_sync_leave(ioc); 985 bfa_nw_ioc_hw_sem_release(ioc); 986 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); 987 } else { 988 if (bfa_ioc_sync_complete(ioc)) 989 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 990 else { 991 bfa_nw_ioc_hw_sem_release(ioc); 992 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); 993 } 994 } 995 break; 996 997 case IOCPF_E_DISABLE: 998 bfa_ioc_hw_sem_get_cancel(ioc); 999 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 1000 break; 1001 1002 case IOCPF_E_STOP: 1003 bfa_ioc_hw_sem_get_cancel(ioc); 1004 bfa_ioc_firmware_unlock(ioc); 1005 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 1006 break; 1007 1008 case IOCPF_E_FAIL: 1009 break; 1010 1011 default: 1012 bfa_sm_fault(ioc, event); 1013 } 1014} 1015 1016static void 1017bfa_iocpf_sm_initfail_entry(struct bfa_iocpf *iocpf) 1018{ 1019 bfa_ioc_pf_initfailed(iocpf->ioc); 1020} 1021 1022/** 1023 * Hardware initialization failed. 1024 */ 1025static void 1026bfa_iocpf_sm_initfail(struct bfa_iocpf *iocpf, enum iocpf_event event) 1027{ 1028 struct bfa_ioc *ioc = iocpf->ioc; 1029 1030 switch (event) { 1031 case IOCPF_E_DISABLE: 1032 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 1033 break; 1034 1035 case IOCPF_E_STOP: 1036 bfa_ioc_firmware_unlock(ioc); 1037 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset); 1038 break; 1039 1040 default: 1041 bfa_sm_fault(ioc, event); 1042 } 1043} 1044 1045static void 1046bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf *iocpf) 1047{ 1048 /** 1049 * Mark IOC as failed in hardware and stop firmware. 1050 */ 1051 bfa_ioc_lpu_stop(iocpf->ioc); 1052 1053 /** 1054 * Flush any queued up mailbox requests. 1055 */ 1056 bfa_ioc_mbox_hbfail(iocpf->ioc); 1057 bfa_ioc_hw_sem_get(iocpf->ioc); 1058} 1059 1060/** 1061 * IOC is in failed state. 1062 */ 1063static void 1064bfa_iocpf_sm_fail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event) 1065{ 1066 struct bfa_ioc *ioc = iocpf->ioc; 1067 1068 switch (event) { 1069 case IOCPF_E_SEMLOCKED: 1070 iocpf->retry_count = 0; 1071 bfa_ioc_sync_ack(ioc); 1072 bfa_ioc_notify_fail(ioc); 1073 if (!iocpf->auto_recover) { 1074 bfa_ioc_sync_leave(ioc); 1075 bfa_nw_ioc_hw_sem_release(ioc); 1076 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail); 1077 } else { 1078 if (bfa_ioc_sync_complete(ioc)) 1079 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); 1080 else { 1081 bfa_nw_ioc_hw_sem_release(ioc); 1082 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait); 1083 } 1084 } 1085 break; 1086 1087 case IOCPF_E_DISABLE: 1088 bfa_ioc_hw_sem_get_cancel(ioc); 1089 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync); 1090 break; 1091 1092 case IOCPF_E_FAIL: 1093 break; 1094 1095 default: 1096 bfa_sm_fault(ioc, event); 1097 } 1098} 1099 1100static void 1101bfa_iocpf_sm_fail_entry(struct bfa_iocpf *iocpf) 1102{ 1103} 1104 1105/** 1106 * @brief 1107 * IOC is in failed state. 1108 */ 1109static void 1110bfa_iocpf_sm_fail(struct bfa_iocpf *iocpf, enum iocpf_event event) 1111{ 1112 switch (event) { 1113 case IOCPF_E_DISABLE: 1114 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled); 1115 break; 1116 1117 default: 1118 bfa_sm_fault(iocpf->ioc, event); 1119 } 1120} 1121 1122/** 1123 * BFA IOC private functions 1124 */ 1125 1126static void 1127bfa_ioc_disable_comp(struct bfa_ioc *ioc) 1128{ 1129 struct list_head *qe; 1130 struct bfa_ioc_hbfail_notify *notify; 1131 1132 ioc->cbfn->disable_cbfn(ioc->bfa); 1133 1134 /** 1135 * Notify common modules registered for notification. 1136 */ 1137 list_for_each(qe, &ioc->hb_notify_q) { 1138 notify = (struct bfa_ioc_hbfail_notify *) qe; 1139 notify->cbfn(notify->cbarg); 1140 } 1141} 1142 1143bool 1144bfa_nw_ioc_sem_get(void __iomem *sem_reg) 1145{ 1146 u32 r32; 1147 int cnt = 0; 1148#define BFA_SEM_SPINCNT 3000 1149 1150 r32 = readl(sem_reg); 1151 1152 while (r32 && (cnt < BFA_SEM_SPINCNT)) { 1153 cnt++; 1154 udelay(2); 1155 r32 = readl(sem_reg); 1156 } 1157 1158 if (r32 == 0) 1159 return true; 1160 1161 BUG_ON(!(cnt < BFA_SEM_SPINCNT)); 1162 return false; 1163} 1164 1165void 1166bfa_nw_ioc_sem_release(void __iomem *sem_reg) 1167{ 1168 writel(1, sem_reg); 1169} 1170 1171static void 1172bfa_ioc_hw_sem_get(struct bfa_ioc *ioc) 1173{ 1174 u32 r32; 1175 1176 /** 1177 * First read to the semaphore register will return 0, subsequent reads 1178 * will return 1. Semaphore is released by writing 1 to the register 1179 */ 1180 r32 = readl(ioc->ioc_regs.ioc_sem_reg); 1181 if (r32 == 0) { 1182 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED); 1183 return; 1184 } 1185 1186 mod_timer(&ioc->sem_timer, jiffies + 1187 msecs_to_jiffies(BFA_IOC_HWSEM_TOV)); 1188} 1189 1190void 1191bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc) 1192{ 1193 writel(1, ioc->ioc_regs.ioc_sem_reg); 1194} 1195 1196static void 1197bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc) 1198{ 1199 del_timer(&ioc->sem_timer); 1200} 1201 1202/** 1203 * @brief 1204 * Initialize LPU local memory (aka secondary memory / SRAM) 1205 */ 1206static void 1207bfa_ioc_lmem_init(struct bfa_ioc *ioc) 1208{ 1209 u32 pss_ctl; 1210 int i; 1211#define PSS_LMEM_INIT_TIME 10000 1212 1213 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1214 pss_ctl &= ~__PSS_LMEM_RESET; 1215 pss_ctl |= __PSS_LMEM_INIT_EN; 1216 1217 /* 1218 * i2c workaround 12.5khz clock 1219 */ 1220 pss_ctl |= __PSS_I2C_CLK_DIV(3UL); 1221 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1222 1223 /** 1224 * wait for memory initialization to be complete 1225 */ 1226 i = 0; 1227 do { 1228 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1229 i++; 1230 } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME)); 1231 1232 /** 1233 * If memory initialization is not successful, IOC timeout will catch 1234 * such failures. 1235 */ 1236 BUG_ON(!(pss_ctl & __PSS_LMEM_INIT_DONE)); 1237 1238 pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN); 1239 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1240} 1241 1242static void 1243bfa_ioc_lpu_start(struct bfa_ioc *ioc) 1244{ 1245 u32 pss_ctl; 1246 1247 /** 1248 * Take processor out of reset. 1249 */ 1250 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1251 pss_ctl &= ~__PSS_LPU0_RESET; 1252 1253 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1254} 1255 1256static void 1257bfa_ioc_lpu_stop(struct bfa_ioc *ioc) 1258{ 1259 u32 pss_ctl; 1260 1261 /** 1262 * Put processors in reset. 1263 */ 1264 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); 1265 pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET); 1266 1267 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); 1268} 1269 1270/** 1271 * Get driver and firmware versions. 1272 */ 1273void 1274bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) 1275{ 1276 u32 pgnum; 1277 u32 loff = 0; 1278 int i; 1279 u32 *fwsig = (u32 *) fwhdr; 1280 1281 pgnum = bfa_ioc_smem_pgnum(ioc, loff); 1282 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1283 1284 for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32)); 1285 i++) { 1286 fwsig[i] = 1287 swab32(readl((loff) + (ioc->ioc_regs.smem_page_start))); 1288 loff += sizeof(u32); 1289 } 1290} 1291 1292/** 1293 * Returns TRUE if same. 1294 */ 1295bool 1296bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) 1297{ 1298 struct bfi_ioc_image_hdr *drv_fwhdr; 1299 int i; 1300 1301 drv_fwhdr = (struct bfi_ioc_image_hdr *) 1302 bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0); 1303 1304 for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) { 1305 if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) 1306 return false; 1307 } 1308 1309 return true; 1310} 1311 1312/** 1313 * Return true if current running version is valid. Firmware signature and 1314 * execution context (driver/bios) must match. 1315 */ 1316static bool 1317bfa_ioc_fwver_valid(struct bfa_ioc *ioc, u32 boot_env) 1318{ 1319 struct bfi_ioc_image_hdr fwhdr, *drv_fwhdr; 1320 1321 bfa_nw_ioc_fwver_get(ioc, &fwhdr); 1322 drv_fwhdr = (struct bfi_ioc_image_hdr *) 1323 bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0); 1324 1325 if (fwhdr.signature != drv_fwhdr->signature) 1326 return false; 1327 1328 if (swab32(fwhdr.param) != boot_env) 1329 return false; 1330 1331 return bfa_nw_ioc_fwver_cmp(ioc, &fwhdr); 1332} 1333 1334/** 1335 * Conditionally flush any pending message from firmware at start. 1336 */ 1337static void 1338bfa_ioc_msgflush(struct bfa_ioc *ioc) 1339{ 1340 u32 r32; 1341 1342 r32 = readl(ioc->ioc_regs.lpu_mbox_cmd); 1343 if (r32) 1344 writel(1, ioc->ioc_regs.lpu_mbox_cmd); 1345} 1346 1347/** 1348 * @img ioc_init_logic.jpg 1349 */ 1350static void 1351bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force) 1352{ 1353 enum bfi_ioc_state ioc_fwstate; 1354 bool fwvalid; 1355 u32 boot_env; 1356 1357 ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate); 1358 1359 boot_env = BFI_BOOT_LOADER_OS; 1360 1361 if (force) 1362 ioc_fwstate = BFI_IOC_UNINIT; 1363 1364 /** 1365 * check if firmware is valid 1366 */ 1367 fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ? 1368 false : bfa_ioc_fwver_valid(ioc, boot_env); 1369 1370 if (!fwvalid) { 1371 bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, boot_env); 1372 return; 1373 } 1374 1375 /** 1376 * If hardware initialization is in progress (initialized by other IOC), 1377 * just wait for an initialization completion interrupt. 1378 */ 1379 if (ioc_fwstate == BFI_IOC_INITING) { 1380 ioc->cbfn->reset_cbfn(ioc->bfa); 1381 return; 1382 } 1383 1384 /** 1385 * If IOC function is disabled and firmware version is same, 1386 * just re-enable IOC. 1387 */ 1388 if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) { 1389 /** 1390 * When using MSI-X any pending firmware ready event should 1391 * be flushed. Otherwise MSI-X interrupts are not delivered. 1392 */ 1393 bfa_ioc_msgflush(ioc); 1394 ioc->cbfn->reset_cbfn(ioc->bfa); 1395 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY); 1396 return; 1397 } 1398 1399 /** 1400 * Initialize the h/w for any other states. 1401 */ 1402 bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, boot_env); 1403} 1404 1405void 1406bfa_nw_ioc_timeout(void *ioc_arg) 1407{ 1408 struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg; 1409 1410 bfa_fsm_send_event(ioc, IOC_E_TIMEOUT); 1411} 1412 1413static void 1414bfa_ioc_mbox_send(struct bfa_ioc *ioc, void *ioc_msg, int len) 1415{ 1416 u32 *msgp = (u32 *) ioc_msg; 1417 u32 i; 1418 1419 BUG_ON(!(len <= BFI_IOC_MSGLEN_MAX)); 1420 1421 /* 1422 * first write msg to mailbox registers 1423 */ 1424 for (i = 0; i < len / sizeof(u32); i++) 1425 writel(cpu_to_le32(msgp[i]), 1426 ioc->ioc_regs.hfn_mbox + i * sizeof(u32)); 1427 1428 for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++) 1429 writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32)); 1430 1431 /* 1432 * write 1 to mailbox CMD to trigger LPU event 1433 */ 1434 writel(1, ioc->ioc_regs.hfn_mbox_cmd); 1435 (void) readl(ioc->ioc_regs.hfn_mbox_cmd); 1436} 1437 1438static void 1439bfa_ioc_send_enable(struct bfa_ioc *ioc) 1440{ 1441 struct bfi_ioc_ctrl_req enable_req; 1442 struct timeval tv; 1443 1444 bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ, 1445 bfa_ioc_portid(ioc)); 1446 enable_req.ioc_class = ioc->ioc_mc; 1447 do_gettimeofday(&tv); 1448 enable_req.tv_sec = ntohl(tv.tv_sec); 1449 bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req)); 1450} 1451 1452static void 1453bfa_ioc_send_disable(struct bfa_ioc *ioc) 1454{ 1455 struct bfi_ioc_ctrl_req disable_req; 1456 1457 bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ, 1458 bfa_ioc_portid(ioc)); 1459 bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req)); 1460} 1461 1462static void 1463bfa_ioc_send_getattr(struct bfa_ioc *ioc) 1464{ 1465 struct bfi_ioc_getattr_req attr_req; 1466 1467 bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ, 1468 bfa_ioc_portid(ioc)); 1469 bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa); 1470 bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req)); 1471} 1472 1473void 1474bfa_nw_ioc_hb_check(void *cbarg) 1475{ 1476 struct bfa_ioc *ioc = cbarg; 1477 u32 hb_count; 1478 1479 hb_count = readl(ioc->ioc_regs.heartbeat); 1480 if (ioc->hb_count == hb_count) { 1481 bfa_ioc_recover(ioc); 1482 return; 1483 } else { 1484 ioc->hb_count = hb_count; 1485 } 1486 1487 bfa_ioc_mbox_poll(ioc); 1488 mod_timer(&ioc->hb_timer, jiffies + 1489 msecs_to_jiffies(BFA_IOC_HB_TOV)); 1490} 1491 1492static void 1493bfa_ioc_hb_monitor(struct bfa_ioc *ioc) 1494{ 1495 ioc->hb_count = readl(ioc->ioc_regs.heartbeat); 1496 mod_timer(&ioc->hb_timer, jiffies + 1497 msecs_to_jiffies(BFA_IOC_HB_TOV)); 1498} 1499 1500static void 1501bfa_ioc_hb_stop(struct bfa_ioc *ioc) 1502{ 1503 del_timer(&ioc->hb_timer); 1504} 1505 1506/** 1507 * @brief 1508 * Initiate a full firmware download. 1509 */ 1510static void 1511bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type, 1512 u32 boot_env) 1513{ 1514 u32 *fwimg; 1515 u32 pgnum; 1516 u32 loff = 0; 1517 u32 chunkno = 0; 1518 u32 i; 1519 1520 /** 1521 * Initialize LMEM first before code download 1522 */ 1523 bfa_ioc_lmem_init(ioc); 1524 1525 fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno); 1526 1527 pgnum = bfa_ioc_smem_pgnum(ioc, loff); 1528 1529 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1530 1531 for (i = 0; i < bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)); i++) { 1532 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) { 1533 chunkno = BFA_IOC_FLASH_CHUNK_NO(i); 1534 fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 1535 BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); 1536 } 1537 1538 /** 1539 * write smem 1540 */ 1541 writel((swab32(fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)])), 1542 ((ioc->ioc_regs.smem_page_start) + (loff))); 1543 1544 loff += sizeof(u32); 1545 1546 /** 1547 * handle page offset wrap around 1548 */ 1549 loff = PSS_SMEM_PGOFF(loff); 1550 if (loff == 0) { 1551 pgnum++; 1552 writel(pgnum, 1553 ioc->ioc_regs.host_page_num_fn); 1554 } 1555 } 1556 1557 writel(bfa_ioc_smem_pgnum(ioc, 0), 1558 ioc->ioc_regs.host_page_num_fn); 1559 1560 /* 1561 * Set boot type and boot param at the end. 1562 */ 1563 writel(boot_type, ((ioc->ioc_regs.smem_page_start) 1564 + (BFI_BOOT_TYPE_OFF))); 1565 writel(boot_env, ((ioc->ioc_regs.smem_page_start) 1566 + (BFI_BOOT_LOADER_OFF))); 1567} 1568 1569static void 1570bfa_ioc_reset(struct bfa_ioc *ioc, bool force) 1571{ 1572 bfa_ioc_hwinit(ioc, force); 1573} 1574 1575/** 1576 * @brief 1577 * Update BFA configuration from firmware configuration. 1578 */ 1579static void 1580bfa_ioc_getattr_reply(struct bfa_ioc *ioc) 1581{ 1582 struct bfi_ioc_attr *attr = ioc->attr; 1583 1584 attr->adapter_prop = ntohl(attr->adapter_prop); 1585 attr->card_type = ntohl(attr->card_type); 1586 attr->maxfrsize = ntohs(attr->maxfrsize); 1587 1588 bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); 1589} 1590 1591/** 1592 * Attach time initialization of mbox logic. 1593 */ 1594static void 1595bfa_ioc_mbox_attach(struct bfa_ioc *ioc) 1596{ 1597 struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; 1598 int mc; 1599 1600 INIT_LIST_HEAD(&mod->cmd_q); 1601 for (mc = 0; mc < BFI_MC_MAX; mc++) { 1602 mod->mbhdlr[mc].cbfn = NULL; 1603 mod->mbhdlr[mc].cbarg = ioc->bfa; 1604 } 1605} 1606 1607/** 1608 * Mbox poll timer -- restarts any pending mailbox requests. 1609 */ 1610static void 1611bfa_ioc_mbox_poll(struct bfa_ioc *ioc) 1612{ 1613 struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; 1614 struct bfa_mbox_cmd *cmd; 1615 u32 stat; 1616 1617 /** 1618 * If no command pending, do nothing 1619 */ 1620 if (list_empty(&mod->cmd_q)) 1621 return; 1622 1623 /** 1624 * If previous command is not yet fetched by firmware, do nothing 1625 */ 1626 stat = readl(ioc->ioc_regs.hfn_mbox_cmd); 1627 if (stat) 1628 return; 1629 1630 /** 1631 * Enqueue command to firmware. 1632 */ 1633 bfa_q_deq(&mod->cmd_q, &cmd); 1634 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); 1635} 1636 1637/** 1638 * Cleanup any pending requests. 1639 */ 1640static void 1641bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc) 1642{ 1643 struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; 1644 struct bfa_mbox_cmd *cmd; 1645 1646 while (!list_empty(&mod->cmd_q)) 1647 bfa_q_deq(&mod->cmd_q, &cmd); 1648} 1649 1650static void 1651bfa_ioc_fail_notify(struct bfa_ioc *ioc) 1652{ 1653 struct list_head *qe; 1654 struct bfa_ioc_hbfail_notify *notify; 1655 1656 /** 1657 * Notify driver and common modules registered for notification. 1658 */ 1659 ioc->cbfn->hbfail_cbfn(ioc->bfa); 1660 list_for_each(qe, &ioc->hb_notify_q) { 1661 notify = (struct bfa_ioc_hbfail_notify *) qe; 1662 notify->cbfn(notify->cbarg); 1663 } 1664} 1665 1666static void 1667bfa_ioc_pf_enabled(struct bfa_ioc *ioc) 1668{ 1669 bfa_fsm_send_event(ioc, IOC_E_ENABLED); 1670} 1671 1672static void 1673bfa_ioc_pf_disabled(struct bfa_ioc *ioc) 1674{ 1675 bfa_fsm_send_event(ioc, IOC_E_DISABLED); 1676} 1677 1678static void 1679bfa_ioc_pf_initfailed(struct bfa_ioc *ioc) 1680{ 1681 bfa_fsm_send_event(ioc, IOC_E_INITFAILED); 1682} 1683 1684static void 1685bfa_ioc_pf_failed(struct bfa_ioc *ioc) 1686{ 1687 bfa_fsm_send_event(ioc, IOC_E_PFAILED); 1688} 1689 1690static void 1691bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc) 1692{ 1693 /** 1694 * Provide enable completion callback and AEN notification. 1695 */ 1696 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 1697} 1698 1699/** 1700 * IOC public 1701 */ 1702static enum bfa_status 1703bfa_ioc_pll_init(struct bfa_ioc *ioc) 1704{ 1705 /* 1706 * Hold semaphore so that nobody can access the chip during init. 1707 */ 1708 bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); 1709 1710 bfa_ioc_pll_init_asic(ioc); 1711 1712 ioc->pllinit = true; 1713 /* 1714 * release semaphore. 1715 */ 1716 bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); 1717 1718 return BFA_STATUS_OK; 1719} 1720 1721/** 1722 * Interface used by diag module to do firmware boot with memory test 1723 * as the entry vector. 1724 */ 1725static void 1726bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_env) 1727{ 1728 void __iomem *rb; 1729 1730 bfa_ioc_stats(ioc, ioc_boots); 1731 1732 if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK) 1733 return; 1734 1735 /** 1736 * Initialize IOC state of all functions on a chip reset. 1737 */ 1738 rb = ioc->pcidev.pci_bar_kva; 1739 if (boot_type == BFI_BOOT_TYPE_MEMTEST) { 1740 writel(BFI_IOC_MEMTEST, (rb + BFA_IOC0_STATE_REG)); 1741 writel(BFI_IOC_MEMTEST, (rb + BFA_IOC1_STATE_REG)); 1742 } else { 1743 writel(BFI_IOC_INITING, (rb + BFA_IOC0_STATE_REG)); 1744 writel(BFI_IOC_INITING, (rb + BFA_IOC1_STATE_REG)); 1745 } 1746 1747 bfa_ioc_msgflush(ioc); 1748 bfa_ioc_download_fw(ioc, boot_type, boot_env); 1749 1750 /** 1751 * Enable interrupts just before starting LPU 1752 */ 1753 ioc->cbfn->reset_cbfn(ioc->bfa); 1754 bfa_ioc_lpu_start(ioc); 1755} 1756 1757/** 1758 * Enable/disable IOC failure auto recovery. 1759 */ 1760void 1761bfa_nw_ioc_auto_recover(bool auto_recover) 1762{ 1763 bfa_nw_auto_recover = auto_recover; 1764} 1765 1766static void 1767bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg) 1768{ 1769 u32 *msgp = mbmsg; 1770 u32 r32; 1771 int i; 1772 1773 /** 1774 * read the MBOX msg 1775 */ 1776 for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32)); 1777 i++) { 1778 r32 = readl(ioc->ioc_regs.lpu_mbox + 1779 i * sizeof(u32)); 1780 msgp[i] = htonl(r32); 1781 } 1782 1783 /** 1784 * turn off mailbox interrupt by clearing mailbox status 1785 */ 1786 writel(1, ioc->ioc_regs.lpu_mbox_cmd); 1787 readl(ioc->ioc_regs.lpu_mbox_cmd); 1788} 1789 1790static void 1791bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m) 1792{ 1793 union bfi_ioc_i2h_msg_u *msg; 1794 struct bfa_iocpf *iocpf = &ioc->iocpf; 1795 1796 msg = (union bfi_ioc_i2h_msg_u *) m; 1797 1798 bfa_ioc_stats(ioc, ioc_isrs); 1799 1800 switch (msg->mh.msg_id) { 1801 case BFI_IOC_I2H_HBEAT: 1802 break; 1803 1804 case BFI_IOC_I2H_READY_EVENT: 1805 bfa_fsm_send_event(iocpf, IOCPF_E_FWREADY); 1806 break; 1807 1808 case BFI_IOC_I2H_ENABLE_REPLY: 1809 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE); 1810 break; 1811 1812 case BFI_IOC_I2H_DISABLE_REPLY: 1813 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_DISABLE); 1814 break; 1815 1816 case BFI_IOC_I2H_GETATTR_REPLY: 1817 bfa_ioc_getattr_reply(ioc); 1818 break; 1819 1820 default: 1821 BUG_ON(1); 1822 } 1823} 1824 1825/** 1826 * IOC attach time initialization and setup. 1827 * 1828 * @param[in] ioc memory for IOC 1829 * @param[in] bfa driver instance structure 1830 */ 1831void 1832bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn) 1833{ 1834 ioc->bfa = bfa; 1835 ioc->cbfn = cbfn; 1836 ioc->fcmode = false; 1837 ioc->pllinit = false; 1838 ioc->dbg_fwsave_once = true; 1839 ioc->iocpf.ioc = ioc; 1840 1841 bfa_ioc_mbox_attach(ioc); 1842 INIT_LIST_HEAD(&ioc->hb_notify_q); 1843 1844 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit); 1845 bfa_fsm_send_event(ioc, IOC_E_RESET); 1846} 1847 1848/** 1849 * Driver detach time IOC cleanup. 1850 */ 1851void 1852bfa_nw_ioc_detach(struct bfa_ioc *ioc) 1853{ 1854 bfa_fsm_send_event(ioc, IOC_E_DETACH); 1855} 1856 1857/** 1858 * Setup IOC PCI properties. 1859 * 1860 * @param[in] pcidev PCI device information for this IOC 1861 */ 1862void 1863bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev, 1864 enum bfi_mclass mc) 1865{ 1866 ioc->ioc_mc = mc; 1867 ioc->pcidev = *pcidev; 1868 ioc->ctdev = bfa_asic_id_ct(ioc->pcidev.device_id); 1869 ioc->cna = ioc->ctdev && !ioc->fcmode; 1870 1871 bfa_nw_ioc_set_ct_hwif(ioc); 1872 1873 bfa_ioc_map_port(ioc); 1874 bfa_ioc_reg_init(ioc); 1875} 1876 1877/** 1878 * Initialize IOC dma memory 1879 * 1880 * @param[in] dm_kva kernel virtual address of IOC dma memory 1881 * @param[in] dm_pa physical address of IOC dma memory 1882 */ 1883void 1884bfa_nw_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa) 1885{ 1886 /** 1887 * dma memory for firmware attribute 1888 */ 1889 ioc->attr_dma.kva = dm_kva; 1890 ioc->attr_dma.pa = dm_pa; 1891 ioc->attr = (struct bfi_ioc_attr *) dm_kva; 1892} 1893 1894/** 1895 * Return size of dma memory required. 1896 */ 1897u32 1898bfa_nw_ioc_meminfo(void) 1899{ 1900 return roundup(sizeof(struct bfi_ioc_attr), BFA_DMA_ALIGN_SZ); 1901} 1902 1903void 1904bfa_nw_ioc_enable(struct bfa_ioc *ioc) 1905{ 1906 bfa_ioc_stats(ioc, ioc_enables); 1907 ioc->dbg_fwsave_once = true; 1908 1909 bfa_fsm_send_event(ioc, IOC_E_ENABLE); 1910} 1911 1912void 1913bfa_nw_ioc_disable(struct bfa_ioc *ioc) 1914{ 1915 bfa_ioc_stats(ioc, ioc_disables); 1916 bfa_fsm_send_event(ioc, IOC_E_DISABLE); 1917} 1918 1919static u32 1920bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr) 1921{ 1922 return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr); 1923} 1924 1925/** 1926 * Register mailbox message handler function, to be called by common modules 1927 */ 1928void 1929bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc, 1930 bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg) 1931{ 1932 struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; 1933 1934 mod->mbhdlr[mc].cbfn = cbfn; 1935 mod->mbhdlr[mc].cbarg = cbarg; 1936} 1937 1938/** 1939 * Queue a mailbox command request to firmware. Waits if mailbox is busy. 1940 * Responsibility of caller to serialize 1941 * 1942 * @param[in] ioc IOC instance 1943 * @param[i] cmd Mailbox command 1944 */ 1945void 1946bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd) 1947{ 1948 struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; 1949 u32 stat; 1950 1951 /** 1952 * If a previous command is pending, queue new command 1953 */ 1954 if (!list_empty(&mod->cmd_q)) { 1955 list_add_tail(&cmd->qe, &mod->cmd_q); 1956 return; 1957 } 1958 1959 /** 1960 * If mailbox is busy, queue command for poll timer 1961 */ 1962 stat = readl(ioc->ioc_regs.hfn_mbox_cmd); 1963 if (stat) { 1964 list_add_tail(&cmd->qe, &mod->cmd_q); 1965 return; 1966 } 1967 1968 /** 1969 * mailbox is free -- queue command to firmware 1970 */ 1971 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); 1972} 1973 1974/** 1975 * Handle mailbox interrupts 1976 */ 1977void 1978bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc) 1979{ 1980 struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; 1981 struct bfi_mbmsg m; 1982 int mc; 1983 1984 bfa_ioc_msgget(ioc, &m); 1985 1986 /** 1987 * Treat IOC message class as special. 1988 */ 1989 mc = m.mh.msg_class; 1990 if (mc == BFI_MC_IOC) { 1991 bfa_ioc_isr(ioc, &m); 1992 return; 1993 } 1994 1995 if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL)) 1996 return; 1997 1998 mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m); 1999} 2000 2001void 2002bfa_nw_ioc_error_isr(struct bfa_ioc *ioc) 2003{ 2004 bfa_fsm_send_event(ioc, IOC_E_HWERROR); 2005} 2006 2007/** 2008 * Add to IOC heartbeat failure notification queue. To be used by common 2009 * modules such as cee, port, diag. 2010 */ 2011void 2012bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc, 2013 struct bfa_ioc_hbfail_notify *notify) 2014{ 2015 list_add_tail(&notify->qe, &ioc->hb_notify_q); 2016} 2017 2018#define BFA_MFG_NAME "Brocade" 2019static void 2020bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc, 2021 struct bfa_adapter_attr *ad_attr) 2022{ 2023 struct bfi_ioc_attr *ioc_attr; 2024 2025 ioc_attr = ioc->attr; 2026 2027 bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num); 2028 bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver); 2029 bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver); 2030 bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer); 2031 memcpy(&ad_attr->vpd, &ioc_attr->vpd, 2032 sizeof(struct bfa_mfg_vpd)); 2033 2034 ad_attr->nports = bfa_ioc_get_nports(ioc); 2035 ad_attr->max_speed = bfa_ioc_speed_sup(ioc); 2036 2037 bfa_ioc_get_adapter_model(ioc, ad_attr->model); 2038 /* For now, model descr uses same model string */ 2039 bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr); 2040 2041 ad_attr->card_type = ioc_attr->card_type; 2042 ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type); 2043 2044 if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop)) 2045 ad_attr->prototype = 1; 2046 else 2047 ad_attr->prototype = 0; 2048 2049 ad_attr->pwwn = bfa_ioc_get_pwwn(ioc); 2050 ad_attr->mac = bfa_nw_ioc_get_mac(ioc); 2051 2052 ad_attr->pcie_gen = ioc_attr->pcie_gen; 2053 ad_attr->pcie_lanes = ioc_attr->pcie_lanes; 2054 ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig; 2055 ad_attr->asic_rev = ioc_attr->asic_rev; 2056 2057 bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver); 2058 2059 ad_attr->cna_capable = ioc->cna; 2060 ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna; 2061} 2062 2063static enum bfa_ioc_type 2064bfa_ioc_get_type(struct bfa_ioc *ioc) 2065{ 2066 if (!ioc->ctdev || ioc->fcmode) 2067 return BFA_IOC_TYPE_FC; 2068 else if (ioc->ioc_mc == BFI_MC_IOCFC) 2069 return BFA_IOC_TYPE_FCoE; 2070 else if (ioc->ioc_mc == BFI_MC_LL) 2071 return BFA_IOC_TYPE_LL; 2072 else { 2073 BUG_ON(!(ioc->ioc_mc == BFI_MC_LL)); 2074 return BFA_IOC_TYPE_LL; 2075 } 2076} 2077 2078static void 2079bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, char *serial_num) 2080{ 2081 memset(serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN); 2082 memcpy(serial_num, 2083 (void *)ioc->attr->brcd_serialnum, 2084 BFA_ADAPTER_SERIAL_NUM_LEN); 2085} 2086 2087static void 2088bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, char *fw_ver) 2089{ 2090 memset(fw_ver, 0, BFA_VERSION_LEN); 2091 memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN); 2092} 2093 2094static void 2095bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, char *chip_rev) 2096{ 2097 BUG_ON(!(chip_rev)); 2098 2099 memset(chip_rev, 0, BFA_IOC_CHIP_REV_LEN); 2100 2101 chip_rev[0] = 'R'; 2102 chip_rev[1] = 'e'; 2103 chip_rev[2] = 'v'; 2104 chip_rev[3] = '-'; 2105 chip_rev[4] = ioc->attr->asic_rev; 2106 chip_rev[5] = '\0'; 2107} 2108 2109static void 2110bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver) 2111{ 2112 memset(optrom_ver, 0, BFA_VERSION_LEN); 2113 memcpy(optrom_ver, ioc->attr->optrom_version, 2114 BFA_VERSION_LEN); 2115} 2116 2117static void 2118bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, char *manufacturer) 2119{ 2120 memset(manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN); 2121 memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); 2122} 2123 2124static void 2125bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model) 2126{ 2127 struct bfi_ioc_attr *ioc_attr; 2128 2129 BUG_ON(!(model)); 2130 memset(model, 0, BFA_ADAPTER_MODEL_NAME_LEN); 2131 2132 ioc_attr = ioc->attr; 2133 2134 /** 2135 * model name 2136 */ 2137 snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u", 2138 BFA_MFG_NAME, ioc_attr->card_type); 2139} 2140 2141static enum bfa_ioc_state 2142bfa_ioc_get_state(struct bfa_ioc *ioc) 2143{ 2144 enum bfa_iocpf_state iocpf_st; 2145 enum bfa_ioc_state ioc_st = bfa_sm_to_state(ioc_sm_table, ioc->fsm); 2146 2147 if (ioc_st == BFA_IOC_ENABLING || 2148 ioc_st == BFA_IOC_FAIL || ioc_st == BFA_IOC_INITFAIL) { 2149 2150 iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm); 2151 2152 switch (iocpf_st) { 2153 case BFA_IOCPF_SEMWAIT: 2154 ioc_st = BFA_IOC_SEMWAIT; 2155 break; 2156 2157 case BFA_IOCPF_HWINIT: 2158 ioc_st = BFA_IOC_HWINIT; 2159 break; 2160 2161 case BFA_IOCPF_FWMISMATCH: 2162 ioc_st = BFA_IOC_FWMISMATCH; 2163 break; 2164 2165 case BFA_IOCPF_FAIL: 2166 ioc_st = BFA_IOC_FAIL; 2167 break; 2168 2169 case BFA_IOCPF_INITFAIL: 2170 ioc_st = BFA_IOC_INITFAIL; 2171 break; 2172 2173 default: 2174 break; 2175 } 2176 } 2177 return ioc_st; 2178} 2179 2180void 2181bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr) 2182{ 2183 memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr)); 2184 2185 ioc_attr->state = bfa_ioc_get_state(ioc); 2186 ioc_attr->port_id = ioc->port_id; 2187 2188 ioc_attr->ioc_type = bfa_ioc_get_type(ioc); 2189 2190 bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr); 2191 2192 ioc_attr->pci_attr.device_id = ioc->pcidev.device_id; 2193 ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func; 2194 bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev); 2195} 2196 2197/** 2198 * WWN public 2199 */ 2200static u64 2201bfa_ioc_get_pwwn(struct bfa_ioc *ioc) 2202{ 2203 return ioc->attr->pwwn; 2204} 2205 2206mac_t 2207bfa_nw_ioc_get_mac(struct bfa_ioc *ioc) 2208{ 2209 return ioc->attr->mac; 2210} 2211 2212/** 2213 * Firmware failure detected. Start recovery actions. 2214 */ 2215static void 2216bfa_ioc_recover(struct bfa_ioc *ioc) 2217{ 2218 pr_crit("Heart Beat of IOC has failed\n"); 2219 bfa_ioc_stats(ioc, ioc_hbfails); 2220 bfa_fsm_send_event(ioc, IOC_E_HBFAIL); 2221} 2222 2223static void 2224bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc) 2225{ 2226 if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL) 2227 return; 2228} 2229 2230/** 2231 * @dg hal_iocpf_pvt BFA IOC PF private functions 2232 * @{ 2233 */ 2234 2235static void 2236bfa_iocpf_enable(struct bfa_ioc *ioc) 2237{ 2238 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE); 2239} 2240 2241static void 2242bfa_iocpf_disable(struct bfa_ioc *ioc) 2243{ 2244 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE); 2245} 2246 2247static void 2248bfa_iocpf_fail(struct bfa_ioc *ioc) 2249{ 2250 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL); 2251} 2252 2253static void 2254bfa_iocpf_initfail(struct bfa_ioc *ioc) 2255{ 2256 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); 2257} 2258 2259static void 2260bfa_iocpf_getattrfail(struct bfa_ioc *ioc) 2261{ 2262 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL); 2263} 2264 2265static void 2266bfa_iocpf_stop(struct bfa_ioc *ioc) 2267{ 2268 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP); 2269} 2270 2271void 2272bfa_nw_iocpf_timeout(void *ioc_arg) 2273{ 2274 struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg; 2275 2276 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT); 2277} 2278 2279void 2280bfa_nw_iocpf_sem_timeout(void *ioc_arg) 2281{ 2282 struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg; 2283 2284 bfa_ioc_hw_sem_get(ioc); 2285}