aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa/bfa_core.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-31 16:31:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-31 16:31:23 -0400
commita75ee6ecd411a50bf4da927c2fdb2cb56246a2bd (patch)
treefcb06e1940152b115901fda68e7eea1cc1196ff3 /drivers/scsi/bfa/bfa_core.c
parentc9651e70ad0aa499814817cbf3cc1d0b806ed3a1 (diff)
parent699316948628dab9e813c415640fe5b9f65cd5e3 (diff)
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
Pull SCSI updates from James Bottomley: "This is primarily another round of driver updates (lpfc, bfa, fcoe, ipr) plus a new ufshcd driver. There shouldn't be anything controversial in here (The final deletion of scsi proc_ops which caused some build breakage has been held over until the next merge window to give us more time to stabilise it). I'm afraid, with me moving continents at exactly the wrong time, anything submitted after the merge window opened has been held over to the next merge window." * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (63 commits) [SCSI] ipr: Driver version 2.5.3 [SCSI] ipr: Increase alignment boundary of command blocks [SCSI] ipr: Increase max concurrent oustanding commands [SCSI] ipr: Remove unnecessary memory barriers [SCSI] ipr: Remove unnecessary interrupt clearing on new adapters [SCSI] ipr: Fix target id allocation re-use problem [SCSI] atp870u, mpt2sas, qla4xxx use pci_dev->revision [SCSI] fcoe: Drop the rtnl_mutex before calling fcoe_ctlr_link_up [SCSI] bfa: Update the driver version to 3.0.23.0 [SCSI] bfa: BSG and User interface fixes. [SCSI] bfa: Fix to avoid vport delete hang on request queue full scenario. [SCSI] bfa: Move service parameter programming logic into firmware. [SCSI] bfa: Revised Fabric Assigned Address(FAA) feature implementation. [SCSI] bfa: Flash controller IOC pll init fixes. [SCSI] bfa: Serialize the IOC hw semaphore unlock logic. [SCSI] bfa: Modify ISR to process pending completions [SCSI] bfa: Add fc host issue lip support [SCSI] mpt2sas: remove extraneous sas_log_info messages [SCSI] libfc: fcoe_transport_create fails in single-CPU environment [SCSI] fcoe: reduce contention for fcoe_rx_list lock [v2] ...
Diffstat (limited to 'drivers/scsi/bfa/bfa_core.c')
-rw-r--r--drivers/scsi/bfa/bfa_core.c693
1 files changed, 484 insertions, 209 deletions
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
index 4bd546bcc240..456e5762977d 100644
--- a/drivers/scsi/bfa/bfa_core.c
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -200,13 +200,431 @@ enum {
200#define DEF_CFG_NUM_SBOOT_LUNS 16 200#define DEF_CFG_NUM_SBOOT_LUNS 16
201 201
202/* 202/*
203 * IOCFC state machine definitions/declarations
204 */
205bfa_fsm_state_decl(bfa_iocfc, stopped, struct bfa_iocfc_s, enum iocfc_event);
206bfa_fsm_state_decl(bfa_iocfc, initing, struct bfa_iocfc_s, enum iocfc_event);
207bfa_fsm_state_decl(bfa_iocfc, dconf_read, struct bfa_iocfc_s, enum iocfc_event);
208bfa_fsm_state_decl(bfa_iocfc, init_cfg_wait,
209 struct bfa_iocfc_s, enum iocfc_event);
210bfa_fsm_state_decl(bfa_iocfc, init_cfg_done,
211 struct bfa_iocfc_s, enum iocfc_event);
212bfa_fsm_state_decl(bfa_iocfc, operational,
213 struct bfa_iocfc_s, enum iocfc_event);
214bfa_fsm_state_decl(bfa_iocfc, dconf_write,
215 struct bfa_iocfc_s, enum iocfc_event);
216bfa_fsm_state_decl(bfa_iocfc, stopping, struct bfa_iocfc_s, enum iocfc_event);
217bfa_fsm_state_decl(bfa_iocfc, enabling, struct bfa_iocfc_s, enum iocfc_event);
218bfa_fsm_state_decl(bfa_iocfc, cfg_wait, struct bfa_iocfc_s, enum iocfc_event);
219bfa_fsm_state_decl(bfa_iocfc, disabling, struct bfa_iocfc_s, enum iocfc_event);
220bfa_fsm_state_decl(bfa_iocfc, disabled, struct bfa_iocfc_s, enum iocfc_event);
221bfa_fsm_state_decl(bfa_iocfc, failed, struct bfa_iocfc_s, enum iocfc_event);
222bfa_fsm_state_decl(bfa_iocfc, init_failed,
223 struct bfa_iocfc_s, enum iocfc_event);
224
225/*
203 * forward declaration for IOC FC functions 226 * forward declaration for IOC FC functions
204 */ 227 */
228static void bfa_iocfc_start_submod(struct bfa_s *bfa);
229static void bfa_iocfc_disable_submod(struct bfa_s *bfa);
230static void bfa_iocfc_send_cfg(void *bfa_arg);
205static void bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status); 231static void bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status);
206static void bfa_iocfc_disable_cbfn(void *bfa_arg); 232static void bfa_iocfc_disable_cbfn(void *bfa_arg);
207static void bfa_iocfc_hbfail_cbfn(void *bfa_arg); 233static void bfa_iocfc_hbfail_cbfn(void *bfa_arg);
208static void bfa_iocfc_reset_cbfn(void *bfa_arg); 234static void bfa_iocfc_reset_cbfn(void *bfa_arg);
209static struct bfa_ioc_cbfn_s bfa_iocfc_cbfn; 235static struct bfa_ioc_cbfn_s bfa_iocfc_cbfn;
236static void bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete);
237static void bfa_iocfc_stop_cb(void *bfa_arg, bfa_boolean_t compl);
238static void bfa_iocfc_enable_cb(void *bfa_arg, bfa_boolean_t compl);
239static void bfa_iocfc_disable_cb(void *bfa_arg, bfa_boolean_t compl);
240
241static void
242bfa_iocfc_sm_stopped_entry(struct bfa_iocfc_s *iocfc)
243{
244}
245
246static void
247bfa_iocfc_sm_stopped(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
248{
249 bfa_trc(iocfc->bfa, event);
250
251 switch (event) {
252 case IOCFC_E_INIT:
253 case IOCFC_E_ENABLE:
254 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_initing);
255 break;
256 default:
257 bfa_sm_fault(iocfc->bfa, event);
258 break;
259 }
260}
261
262static void
263bfa_iocfc_sm_initing_entry(struct bfa_iocfc_s *iocfc)
264{
265 bfa_ioc_enable(&iocfc->bfa->ioc);
266}
267
268static void
269bfa_iocfc_sm_initing(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
270{
271 bfa_trc(iocfc->bfa, event);
272
273 switch (event) {
274 case IOCFC_E_IOC_ENABLED:
275 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_read);
276 break;
277 case IOCFC_E_IOC_FAILED:
278 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed);
279 break;
280 default:
281 bfa_sm_fault(iocfc->bfa, event);
282 break;
283 }
284}
285
286static void
287bfa_iocfc_sm_dconf_read_entry(struct bfa_iocfc_s *iocfc)
288{
289 bfa_dconf_modinit(iocfc->bfa);
290}
291
292static void
293bfa_iocfc_sm_dconf_read(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
294{
295 bfa_trc(iocfc->bfa, event);
296
297 switch (event) {
298 case IOCFC_E_DCONF_DONE:
299 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_cfg_wait);
300 break;
301 case IOCFC_E_IOC_FAILED:
302 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed);
303 break;
304 default:
305 bfa_sm_fault(iocfc->bfa, event);
306 break;
307 }
308}
309
310static void
311bfa_iocfc_sm_init_cfg_wait_entry(struct bfa_iocfc_s *iocfc)
312{
313 bfa_iocfc_send_cfg(iocfc->bfa);
314}
315
316static void
317bfa_iocfc_sm_init_cfg_wait(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
318{
319 bfa_trc(iocfc->bfa, event);
320
321 switch (event) {
322 case IOCFC_E_CFG_DONE:
323 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_cfg_done);
324 break;
325 case IOCFC_E_IOC_FAILED:
326 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed);
327 break;
328 default:
329 bfa_sm_fault(iocfc->bfa, event);
330 break;
331 }
332}
333
334static void
335bfa_iocfc_sm_init_cfg_done_entry(struct bfa_iocfc_s *iocfc)
336{
337 iocfc->bfa->iocfc.op_status = BFA_STATUS_OK;
338 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.init_hcb_qe,
339 bfa_iocfc_init_cb, iocfc->bfa);
340}
341
342static void
343bfa_iocfc_sm_init_cfg_done(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
344{
345 bfa_trc(iocfc->bfa, event);
346
347 switch (event) {
348 case IOCFC_E_START:
349 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_operational);
350 break;
351 case IOCFC_E_STOP:
352 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping);
353 break;
354 case IOCFC_E_DISABLE:
355 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);
356 break;
357 case IOCFC_E_IOC_FAILED:
358 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed);
359 break;
360 default:
361 bfa_sm_fault(iocfc->bfa, event);
362 break;
363 }
364}
365
366static void
367bfa_iocfc_sm_operational_entry(struct bfa_iocfc_s *iocfc)
368{
369 bfa_fcport_init(iocfc->bfa);
370 bfa_iocfc_start_submod(iocfc->bfa);
371}
372
373static void
374bfa_iocfc_sm_operational(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
375{
376 bfa_trc(iocfc->bfa, event);
377
378 switch (event) {
379 case IOCFC_E_STOP:
380 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write);
381 break;
382 case IOCFC_E_DISABLE:
383 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);
384 break;
385 case IOCFC_E_IOC_FAILED:
386 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed);
387 break;
388 default:
389 bfa_sm_fault(iocfc->bfa, event);
390 break;
391 }
392}
393
394static void
395bfa_iocfc_sm_dconf_write_entry(struct bfa_iocfc_s *iocfc)
396{
397 bfa_dconf_modexit(iocfc->bfa);
398}
399
400static void
401bfa_iocfc_sm_dconf_write(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
402{
403 bfa_trc(iocfc->bfa, event);
404
405 switch (event) {
406 case IOCFC_E_DCONF_DONE:
407 case IOCFC_E_IOC_FAILED:
408 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping);
409 break;
410 default:
411 bfa_sm_fault(iocfc->bfa, event);
412 break;
413 }
414}
415
416static void
417bfa_iocfc_sm_stopping_entry(struct bfa_iocfc_s *iocfc)
418{
419 bfa_ioc_disable(&iocfc->bfa->ioc);
420}
421
422static void
423bfa_iocfc_sm_stopping(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
424{
425 bfa_trc(iocfc->bfa, event);
426
427 switch (event) {
428 case IOCFC_E_IOC_DISABLED:
429 bfa_isr_disable(iocfc->bfa);
430 bfa_iocfc_disable_submod(iocfc->bfa);
431 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopped);
432 iocfc->bfa->iocfc.op_status = BFA_STATUS_OK;
433 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.stop_hcb_qe,
434 bfa_iocfc_stop_cb, iocfc->bfa);
435 break;
436 default:
437 bfa_sm_fault(iocfc->bfa, event);
438 break;
439 }
440}
441
442static void
443bfa_iocfc_sm_enabling_entry(struct bfa_iocfc_s *iocfc)
444{
445 bfa_ioc_enable(&iocfc->bfa->ioc);
446}
447
448static void
449bfa_iocfc_sm_enabling(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
450{
451 bfa_trc(iocfc->bfa, event);
452
453 switch (event) {
454 case IOCFC_E_IOC_ENABLED:
455 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_cfg_wait);
456 break;
457 case IOCFC_E_IOC_FAILED:
458 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed);
459
460 if (iocfc->bfa->iocfc.cb_reqd == BFA_FALSE)
461 break;
462
463 iocfc->bfa->iocfc.op_status = BFA_STATUS_FAILED;
464 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.en_hcb_qe,
465 bfa_iocfc_enable_cb, iocfc->bfa);
466 iocfc->bfa->iocfc.cb_reqd = BFA_FALSE;
467 break;
468 default:
469 bfa_sm_fault(iocfc->bfa, event);
470 break;
471 }
472}
473
474static void
475bfa_iocfc_sm_cfg_wait_entry(struct bfa_iocfc_s *iocfc)
476{
477 bfa_iocfc_send_cfg(iocfc->bfa);
478}
479
480static void
481bfa_iocfc_sm_cfg_wait(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
482{
483 bfa_trc(iocfc->bfa, event);
484
485 switch (event) {
486 case IOCFC_E_CFG_DONE:
487 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_operational);
488 if (iocfc->bfa->iocfc.cb_reqd == BFA_FALSE)
489 break;
490
491 iocfc->bfa->iocfc.op_status = BFA_STATUS_OK;
492 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.en_hcb_qe,
493 bfa_iocfc_enable_cb, iocfc->bfa);
494 iocfc->bfa->iocfc.cb_reqd = BFA_FALSE;
495 break;
496 case IOCFC_E_IOC_FAILED:
497 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed);
498 if (iocfc->bfa->iocfc.cb_reqd == BFA_FALSE)
499 break;
500
501 iocfc->bfa->iocfc.op_status = BFA_STATUS_FAILED;
502 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.en_hcb_qe,
503 bfa_iocfc_enable_cb, iocfc->bfa);
504 iocfc->bfa->iocfc.cb_reqd = BFA_FALSE;
505 break;
506 default:
507 bfa_sm_fault(iocfc->bfa, event);
508 break;
509 }
510}
511
512static void
513bfa_iocfc_sm_disabling_entry(struct bfa_iocfc_s *iocfc)
514{
515 bfa_ioc_disable(&iocfc->bfa->ioc);
516}
517
518static void
519bfa_iocfc_sm_disabling(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
520{
521 bfa_trc(iocfc->bfa, event);
522
523 switch (event) {
524 case IOCFC_E_IOC_DISABLED:
525 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabled);
526 break;
527 default:
528 bfa_sm_fault(iocfc->bfa, event);
529 break;
530 }
531}
532
533static void
534bfa_iocfc_sm_disabled_entry(struct bfa_iocfc_s *iocfc)
535{
536 bfa_isr_disable(iocfc->bfa);
537 bfa_iocfc_disable_submod(iocfc->bfa);
538 iocfc->bfa->iocfc.op_status = BFA_STATUS_OK;
539 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.dis_hcb_qe,
540 bfa_iocfc_disable_cb, iocfc->bfa);
541}
542
543static void
544bfa_iocfc_sm_disabled(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
545{
546 bfa_trc(iocfc->bfa, event);
547
548 switch (event) {
549 case IOCFC_E_STOP:
550 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write);
551 break;
552 case IOCFC_E_ENABLE:
553 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_enabling);
554 break;
555 default:
556 bfa_sm_fault(iocfc->bfa, event);
557 break;
558 }
559}
560
561static void
562bfa_iocfc_sm_failed_entry(struct bfa_iocfc_s *iocfc)
563{
564 bfa_isr_disable(iocfc->bfa);
565 bfa_iocfc_disable_submod(iocfc->bfa);
566}
567
568static void
569bfa_iocfc_sm_failed(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
570{
571 bfa_trc(iocfc->bfa, event);
572
573 switch (event) {
574 case IOCFC_E_STOP:
575 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write);
576 break;
577 case IOCFC_E_DISABLE:
578 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling);
579 break;
580 case IOCFC_E_IOC_ENABLED:
581 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_cfg_wait);
582 break;
583 case IOCFC_E_IOC_FAILED:
584 break;
585 default:
586 bfa_sm_fault(iocfc->bfa, event);
587 break;
588 }
589}
590
591static void
592bfa_iocfc_sm_init_failed_entry(struct bfa_iocfc_s *iocfc)
593{
594 bfa_isr_disable(iocfc->bfa);
595 iocfc->bfa->iocfc.op_status = BFA_STATUS_FAILED;
596 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.init_hcb_qe,
597 bfa_iocfc_init_cb, iocfc->bfa);
598}
599
600static void
601bfa_iocfc_sm_init_failed(struct bfa_iocfc_s *iocfc, enum iocfc_event event)
602{
603 bfa_trc(iocfc->bfa, event);
604
605 switch (event) {
606 case IOCFC_E_STOP:
607 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping);
608 break;
609 case IOCFC_E_DISABLE:
610 bfa_ioc_disable(&iocfc->bfa->ioc);
611 break;
612 case IOCFC_E_IOC_ENABLED:
613 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_read);
614 break;
615 case IOCFC_E_IOC_DISABLED:
616 bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopped);
617 iocfc->bfa->iocfc.op_status = BFA_STATUS_OK;
618 bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.dis_hcb_qe,
619 bfa_iocfc_disable_cb, iocfc->bfa);
620 break;
621 case IOCFC_E_IOC_FAILED:
622 break;
623 default:
624 bfa_sm_fault(iocfc->bfa, event);
625 break;
626 }
627}
210 628
211/* 629/*
212 * BFA Interrupt handling functions 630 * BFA Interrupt handling functions
@@ -231,16 +649,19 @@ bfa_reqq_resume(struct bfa_s *bfa, int qid)
231 } 649 }
232} 650}
233 651
234static inline void 652bfa_boolean_t
235bfa_isr_rspq(struct bfa_s *bfa, int qid) 653bfa_isr_rspq(struct bfa_s *bfa, int qid)
236{ 654{
237 struct bfi_msg_s *m; 655 struct bfi_msg_s *m;
238 u32 pi, ci; 656 u32 pi, ci;
239 struct list_head *waitq; 657 struct list_head *waitq;
658 bfa_boolean_t ret;
240 659
241 ci = bfa_rspq_ci(bfa, qid); 660 ci = bfa_rspq_ci(bfa, qid);
242 pi = bfa_rspq_pi(bfa, qid); 661 pi = bfa_rspq_pi(bfa, qid);
243 662
663 ret = (ci != pi);
664
244 while (ci != pi) { 665 while (ci != pi) {
245 m = bfa_rspq_elem(bfa, qid, ci); 666 m = bfa_rspq_elem(bfa, qid, ci);
246 WARN_ON(m->mhdr.msg_class >= BFI_MC_MAX); 667 WARN_ON(m->mhdr.msg_class >= BFI_MC_MAX);
@@ -260,6 +681,8 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid)
260 waitq = bfa_reqq(bfa, qid); 681 waitq = bfa_reqq(bfa, qid);
261 if (!list_empty(waitq)) 682 if (!list_empty(waitq))
262 bfa_reqq_resume(bfa, qid); 683 bfa_reqq_resume(bfa, qid);
684
685 return ret;
263} 686}
264 687
265static inline void 688static inline void
@@ -320,6 +743,7 @@ bfa_intx(struct bfa_s *bfa)
320{ 743{
321 u32 intr, qintr; 744 u32 intr, qintr;
322 int queue; 745 int queue;
746 bfa_boolean_t rspq_comp = BFA_FALSE;
323 747
324 intr = readl(bfa->iocfc.bfa_regs.intr_status); 748 intr = readl(bfa->iocfc.bfa_regs.intr_status);
325 749
@@ -332,11 +756,12 @@ bfa_intx(struct bfa_s *bfa)
332 */ 756 */
333 if (bfa->queue_process) { 757 if (bfa->queue_process) {
334 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++) 758 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
335 bfa_isr_rspq(bfa, queue); 759 if (bfa_isr_rspq(bfa, queue))
760 rspq_comp = BFA_TRUE;
336 } 761 }
337 762
338 if (!intr) 763 if (!intr)
339 return BFA_TRUE; 764 return (qintr | rspq_comp) ? BFA_TRUE : BFA_FALSE;
340 765
341 /* 766 /*
342 * CPE completion queue interrupt 767 * CPE completion queue interrupt
@@ -525,11 +950,9 @@ bfa_iocfc_send_cfg(void *bfa_arg)
525 * Enable interrupt coalescing if it is driver init path 950 * Enable interrupt coalescing if it is driver init path
526 * and not ioc disable/enable path. 951 * and not ioc disable/enable path.
527 */ 952 */
528 if (!iocfc->cfgdone) 953 if (bfa_fsm_cmp_state(iocfc, bfa_iocfc_sm_init_cfg_wait))
529 cfg_info->intr_attr.coalesce = BFA_TRUE; 954 cfg_info->intr_attr.coalesce = BFA_TRUE;
530 955
531 iocfc->cfgdone = BFA_FALSE;
532
533 /* 956 /*
534 * dma map IOC configuration itself 957 * dma map IOC configuration itself
535 */ 958 */
@@ -549,8 +972,6 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
549 972
550 bfa->bfad = bfad; 973 bfa->bfad = bfad;
551 iocfc->bfa = bfa; 974 iocfc->bfa = bfa;
552 iocfc->action = BFA_IOCFC_ACT_NONE;
553
554 iocfc->cfg = *cfg; 975 iocfc->cfg = *cfg;
555 976
556 /* 977 /*
@@ -683,6 +1104,8 @@ bfa_iocfc_start_submod(struct bfa_s *bfa)
683 1104
684 for (i = 0; hal_mods[i]; i++) 1105 for (i = 0; hal_mods[i]; i++)
685 hal_mods[i]->start(bfa); 1106 hal_mods[i]->start(bfa);
1107
1108 bfa->iocfc.submod_enabled = BFA_TRUE;
686} 1109}
687 1110
688/* 1111/*
@@ -693,8 +1116,13 @@ bfa_iocfc_disable_submod(struct bfa_s *bfa)
693{ 1116{
694 int i; 1117 int i;
695 1118
1119 if (bfa->iocfc.submod_enabled == BFA_FALSE)
1120 return;
1121
696 for (i = 0; hal_mods[i]; i++) 1122 for (i = 0; hal_mods[i]; i++)
697 hal_mods[i]->iocdisable(bfa); 1123 hal_mods[i]->iocdisable(bfa);
1124
1125 bfa->iocfc.submod_enabled = BFA_FALSE;
698} 1126}
699 1127
700static void 1128static void
@@ -702,15 +1130,8 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)
702{ 1130{
703 struct bfa_s *bfa = bfa_arg; 1131 struct bfa_s *bfa = bfa_arg;
704 1132
705 if (complete) { 1133 if (complete)
706 if (bfa->iocfc.cfgdone && BFA_DCONF_MOD(bfa)->flashdone) 1134 bfa_cb_init(bfa->bfad, bfa->iocfc.op_status);
707 bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
708 else
709 bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
710 } else {
711 if (bfa->iocfc.cfgdone)
712 bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
713 }
714} 1135}
715 1136
716static void 1137static void
@@ -721,8 +1142,6 @@ bfa_iocfc_stop_cb(void *bfa_arg, bfa_boolean_t compl)
721 1142
722 if (compl) 1143 if (compl)
723 complete(&bfad->comp); 1144 complete(&bfad->comp);
724 else
725 bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
726} 1145}
727 1146
728static void 1147static void
@@ -794,8 +1213,6 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
794 fwcfg->num_uf_bufs = be16_to_cpu(fwcfg->num_uf_bufs); 1213 fwcfg->num_uf_bufs = be16_to_cpu(fwcfg->num_uf_bufs);
795 fwcfg->num_rports = be16_to_cpu(fwcfg->num_rports); 1214 fwcfg->num_rports = be16_to_cpu(fwcfg->num_rports);
796 1215
797 iocfc->cfgdone = BFA_TRUE;
798
799 /* 1216 /*
800 * configure queue register offsets as learnt from firmware 1217 * configure queue register offsets as learnt from firmware
801 */ 1218 */
@@ -811,22 +1228,13 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
811 */ 1228 */
812 bfa_msix_queue_install(bfa); 1229 bfa_msix_queue_install(bfa);
813 1230
814 /* 1231 if (bfa->iocfc.cfgrsp->pbc_cfg.pbc_pwwn != 0) {
815 * Configuration is complete - initialize/start submodules 1232 bfa->ioc.attr->pwwn = bfa->iocfc.cfgrsp->pbc_cfg.pbc_pwwn;
816 */ 1233 bfa->ioc.attr->nwwn = bfa->iocfc.cfgrsp->pbc_cfg.pbc_nwwn;
817 bfa_fcport_init(bfa); 1234 bfa_fsm_send_event(iocfc, IOCFC_E_CFG_DONE);
818
819 if (iocfc->action == BFA_IOCFC_ACT_INIT) {
820 if (BFA_DCONF_MOD(bfa)->flashdone == BFA_TRUE)
821 bfa_cb_queue(bfa, &iocfc->init_hcb_qe,
822 bfa_iocfc_init_cb, bfa);
823 } else {
824 if (bfa->iocfc.action == BFA_IOCFC_ACT_ENABLE)
825 bfa_cb_queue(bfa, &bfa->iocfc.en_hcb_qe,
826 bfa_iocfc_enable_cb, bfa);
827 bfa_iocfc_start_submod(bfa);
828 } 1235 }
829} 1236}
1237
830void 1238void
831bfa_iocfc_reset_queues(struct bfa_s *bfa) 1239bfa_iocfc_reset_queues(struct bfa_s *bfa)
832{ 1240{
@@ -840,6 +1248,23 @@ bfa_iocfc_reset_queues(struct bfa_s *bfa)
840 } 1248 }
841} 1249}
842 1250
1251/*
1252 * Process FAA pwwn msg from fw.
1253 */
1254static void
1255bfa_iocfc_process_faa_addr(struct bfa_s *bfa, struct bfi_faa_addr_msg_s *msg)
1256{
1257 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
1258 struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
1259
1260 cfgrsp->pbc_cfg.pbc_pwwn = msg->pwwn;
1261 cfgrsp->pbc_cfg.pbc_nwwn = msg->nwwn;
1262
1263 bfa->ioc.attr->pwwn = msg->pwwn;
1264 bfa->ioc.attr->nwwn = msg->nwwn;
1265 bfa_fsm_send_event(iocfc, IOCFC_E_CFG_DONE);
1266}
1267
843/* Fabric Assigned Address specific functions */ 1268/* Fabric Assigned Address specific functions */
844 1269
845/* 1270/*
@@ -855,84 +1280,13 @@ bfa_faa_validate_request(struct bfa_s *bfa)
855 if ((ioc_type != BFA_IOC_TYPE_FC) || bfa_mfg_is_mezz(card_type)) 1280 if ((ioc_type != BFA_IOC_TYPE_FC) || bfa_mfg_is_mezz(card_type))
856 return BFA_STATUS_FEATURE_NOT_SUPPORTED; 1281 return BFA_STATUS_FEATURE_NOT_SUPPORTED;
857 } else { 1282 } else {
858 if (!bfa_ioc_is_acq_addr(&bfa->ioc)) 1283 return BFA_STATUS_IOC_NON_OP;
859 return BFA_STATUS_IOC_NON_OP;
860 } 1284 }
861 1285
862 return BFA_STATUS_OK; 1286 return BFA_STATUS_OK;
863} 1287}
864 1288
865bfa_status_t 1289bfa_status_t
866bfa_faa_enable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn, void *cbarg)
867{
868 struct bfi_faa_en_dis_s faa_enable_req;
869 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
870 bfa_status_t status;
871
872 iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
873 iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
874
875 status = bfa_faa_validate_request(bfa);
876 if (status != BFA_STATUS_OK)
877 return status;
878
879 if (iocfc->faa_args.busy == BFA_TRUE)
880 return BFA_STATUS_DEVBUSY;
881
882 if (iocfc->faa_args.faa_state == BFA_FAA_ENABLED)
883 return BFA_STATUS_FAA_ENABLED;
884
885 if (bfa_fcport_is_trunk_enabled(bfa))
886 return BFA_STATUS_ERROR_TRUNK_ENABLED;
887
888 bfa_fcport_cfg_faa(bfa, BFA_FAA_ENABLED);
889 iocfc->faa_args.busy = BFA_TRUE;
890
891 memset(&faa_enable_req, 0, sizeof(struct bfi_faa_en_dis_s));
892 bfi_h2i_set(faa_enable_req.mh, BFI_MC_IOCFC,
893 BFI_IOCFC_H2I_FAA_ENABLE_REQ, bfa_fn_lpu(bfa));
894
895 bfa_ioc_mbox_send(&bfa->ioc, &faa_enable_req,
896 sizeof(struct bfi_faa_en_dis_s));
897
898 return BFA_STATUS_OK;
899}
900
901bfa_status_t
902bfa_faa_disable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn,
903 void *cbarg)
904{
905 struct bfi_faa_en_dis_s faa_disable_req;
906 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
907 bfa_status_t status;
908
909 iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
910 iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
911
912 status = bfa_faa_validate_request(bfa);
913 if (status != BFA_STATUS_OK)
914 return status;
915
916 if (iocfc->faa_args.busy == BFA_TRUE)
917 return BFA_STATUS_DEVBUSY;
918
919 if (iocfc->faa_args.faa_state == BFA_FAA_DISABLED)
920 return BFA_STATUS_FAA_DISABLED;
921
922 bfa_fcport_cfg_faa(bfa, BFA_FAA_DISABLED);
923 iocfc->faa_args.busy = BFA_TRUE;
924
925 memset(&faa_disable_req, 0, sizeof(struct bfi_faa_en_dis_s));
926 bfi_h2i_set(faa_disable_req.mh, BFI_MC_IOCFC,
927 BFI_IOCFC_H2I_FAA_DISABLE_REQ, bfa_fn_lpu(bfa));
928
929 bfa_ioc_mbox_send(&bfa->ioc, &faa_disable_req,
930 sizeof(struct bfi_faa_en_dis_s));
931
932 return BFA_STATUS_OK;
933}
934
935bfa_status_t
936bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr, 1290bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr,
937 bfa_cb_iocfc_t cbfn, void *cbarg) 1291 bfa_cb_iocfc_t cbfn, void *cbarg)
938{ 1292{
@@ -963,38 +1317,6 @@ bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr,
963} 1317}
964 1318
965/* 1319/*
966 * FAA enable response
967 */
968static void
969bfa_faa_enable_reply(struct bfa_iocfc_s *iocfc,
970 struct bfi_faa_en_dis_rsp_s *rsp)
971{
972 void *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
973 bfa_status_t status = rsp->status;
974
975 WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
976
977 iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status);
978 iocfc->faa_args.busy = BFA_FALSE;
979}
980
981/*
982 * FAA disable response
983 */
984static void
985bfa_faa_disable_reply(struct bfa_iocfc_s *iocfc,
986 struct bfi_faa_en_dis_rsp_s *rsp)
987{
988 void *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
989 bfa_status_t status = rsp->status;
990
991 WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
992
993 iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status);
994 iocfc->faa_args.busy = BFA_FALSE;
995}
996
997/*
998 * FAA query response 1320 * FAA query response
999 */ 1321 */
1000static void 1322static void
@@ -1023,25 +1345,10 @@ bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)
1023{ 1345{
1024 struct bfa_s *bfa = bfa_arg; 1346 struct bfa_s *bfa = bfa_arg;
1025 1347
1026 if (status == BFA_STATUS_FAA_ACQ_ADDR) { 1348 if (status == BFA_STATUS_OK)
1027 bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe, 1349 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_ENABLED);
1028 bfa_iocfc_init_cb, bfa); 1350 else
1029 return; 1351 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_FAILED);
1030 }
1031
1032 if (status != BFA_STATUS_OK) {
1033 bfa_isr_disable(bfa);
1034 if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT)
1035 bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
1036 bfa_iocfc_init_cb, bfa);
1037 else if (bfa->iocfc.action == BFA_IOCFC_ACT_ENABLE)
1038 bfa_cb_queue(bfa, &bfa->iocfc.en_hcb_qe,
1039 bfa_iocfc_enable_cb, bfa);
1040 return;
1041 }
1042
1043 bfa_iocfc_send_cfg(bfa);
1044 bfa_dconf_modinit(bfa);
1045} 1352}
1046 1353
1047/* 1354/*
@@ -1052,17 +1359,7 @@ bfa_iocfc_disable_cbfn(void *bfa_arg)
1052{ 1359{
1053 struct bfa_s *bfa = bfa_arg; 1360 struct bfa_s *bfa = bfa_arg;
1054 1361
1055 bfa_isr_disable(bfa); 1362 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_DISABLED);
1056 bfa_iocfc_disable_submod(bfa);
1057
1058 if (bfa->iocfc.action == BFA_IOCFC_ACT_STOP)
1059 bfa_cb_queue(bfa, &bfa->iocfc.stop_hcb_qe, bfa_iocfc_stop_cb,
1060 bfa);
1061 else {
1062 WARN_ON(bfa->iocfc.action != BFA_IOCFC_ACT_DISABLE);
1063 bfa_cb_queue(bfa, &bfa->iocfc.dis_hcb_qe, bfa_iocfc_disable_cb,
1064 bfa);
1065 }
1066} 1363}
1067 1364
1068/* 1365/*
@@ -1074,13 +1371,7 @@ bfa_iocfc_hbfail_cbfn(void *bfa_arg)
1074 struct bfa_s *bfa = bfa_arg; 1371 struct bfa_s *bfa = bfa_arg;
1075 1372
1076 bfa->queue_process = BFA_FALSE; 1373 bfa->queue_process = BFA_FALSE;
1077 1374 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_FAILED);
1078 bfa_isr_disable(bfa);
1079 bfa_iocfc_disable_submod(bfa);
1080
1081 if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT)
1082 bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe, bfa_iocfc_init_cb,
1083 bfa);
1084} 1375}
1085 1376
1086/* 1377/*
@@ -1095,7 +1386,6 @@ bfa_iocfc_reset_cbfn(void *bfa_arg)
1095 bfa_isr_enable(bfa); 1386 bfa_isr_enable(bfa);
1096} 1387}
1097 1388
1098
1099/* 1389/*
1100 * Query IOC memory requirement information. 1390 * Query IOC memory requirement information.
1101 */ 1391 */
@@ -1171,6 +1461,12 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
1171 INIT_LIST_HEAD(&bfa->comp_q); 1461 INIT_LIST_HEAD(&bfa->comp_q);
1172 for (i = 0; i < BFI_IOC_MAX_CQS; i++) 1462 for (i = 0; i < BFI_IOC_MAX_CQS; i++)
1173 INIT_LIST_HEAD(&bfa->reqq_waitq[i]); 1463 INIT_LIST_HEAD(&bfa->reqq_waitq[i]);
1464
1465 bfa->iocfc.cb_reqd = BFA_FALSE;
1466 bfa->iocfc.op_status = BFA_STATUS_OK;
1467 bfa->iocfc.submod_enabled = BFA_FALSE;
1468
1469 bfa_fsm_set_state(&bfa->iocfc, bfa_iocfc_sm_stopped);
1174} 1470}
1175 1471
1176/* 1472/*
@@ -1179,8 +1475,7 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
1179void 1475void
1180bfa_iocfc_init(struct bfa_s *bfa) 1476bfa_iocfc_init(struct bfa_s *bfa)
1181{ 1477{
1182 bfa->iocfc.action = BFA_IOCFC_ACT_INIT; 1478 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_INIT);
1183 bfa_ioc_enable(&bfa->ioc);
1184} 1479}
1185 1480
1186/* 1481/*
@@ -1190,8 +1485,7 @@ bfa_iocfc_init(struct bfa_s *bfa)
1190void 1485void
1191bfa_iocfc_start(struct bfa_s *bfa) 1486bfa_iocfc_start(struct bfa_s *bfa)
1192{ 1487{
1193 if (bfa->iocfc.cfgdone) 1488 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_START);
1194 bfa_iocfc_start_submod(bfa);
1195} 1489}
1196 1490
1197/* 1491/*
@@ -1201,12 +1495,8 @@ bfa_iocfc_start(struct bfa_s *bfa)
1201void 1495void
1202bfa_iocfc_stop(struct bfa_s *bfa) 1496bfa_iocfc_stop(struct bfa_s *bfa)
1203{ 1497{
1204 bfa->iocfc.action = BFA_IOCFC_ACT_STOP;
1205
1206 bfa->queue_process = BFA_FALSE; 1498 bfa->queue_process = BFA_FALSE;
1207 bfa_dconf_modexit(bfa); 1499 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_STOP);
1208 if (BFA_DCONF_MOD(bfa)->flashdone == BFA_TRUE)
1209 bfa_ioc_disable(&bfa->ioc);
1210} 1500}
1211 1501
1212void 1502void
@@ -1226,13 +1516,9 @@ bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m)
1226 case BFI_IOCFC_I2H_UPDATEQ_RSP: 1516 case BFI_IOCFC_I2H_UPDATEQ_RSP:
1227 iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK); 1517 iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK);
1228 break; 1518 break;
1229 case BFI_IOCFC_I2H_FAA_ENABLE_RSP: 1519 case BFI_IOCFC_I2H_ADDR_MSG:
1230 bfa_faa_enable_reply(iocfc, 1520 bfa_iocfc_process_faa_addr(bfa,
1231 (struct bfi_faa_en_dis_rsp_s *)msg); 1521 (struct bfi_faa_addr_msg_s *)msg);
1232 break;
1233 case BFI_IOCFC_I2H_FAA_DISABLE_RSP:
1234 bfa_faa_disable_reply(iocfc,
1235 (struct bfi_faa_en_dis_rsp_s *)msg);
1236 break; 1522 break;
1237 case BFI_IOCFC_I2H_FAA_QUERY_RSP: 1523 case BFI_IOCFC_I2H_FAA_QUERY_RSP:
1238 bfa_faa_query_reply(iocfc, (bfi_faa_query_rsp_t *)msg); 1524 bfa_faa_query_reply(iocfc, (bfi_faa_query_rsp_t *)msg);
@@ -1306,8 +1592,8 @@ bfa_iocfc_enable(struct bfa_s *bfa)
1306{ 1592{
1307 bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0, 1593 bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,
1308 "IOC Enable"); 1594 "IOC Enable");
1309 bfa->iocfc.action = BFA_IOCFC_ACT_ENABLE; 1595 bfa->iocfc.cb_reqd = BFA_TRUE;
1310 bfa_ioc_enable(&bfa->ioc); 1596 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_ENABLE);
1311} 1597}
1312 1598
1313void 1599void
@@ -1315,17 +1601,16 @@ bfa_iocfc_disable(struct bfa_s *bfa)
1315{ 1601{
1316 bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0, 1602 bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,
1317 "IOC Disable"); 1603 "IOC Disable");
1318 bfa->iocfc.action = BFA_IOCFC_ACT_DISABLE;
1319 1604
1320 bfa->queue_process = BFA_FALSE; 1605 bfa->queue_process = BFA_FALSE;
1321 bfa_ioc_disable(&bfa->ioc); 1606 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DISABLE);
1322} 1607}
1323 1608
1324
1325bfa_boolean_t 1609bfa_boolean_t
1326bfa_iocfc_is_operational(struct bfa_s *bfa) 1610bfa_iocfc_is_operational(struct bfa_s *bfa)
1327{ 1611{
1328 return bfa_ioc_is_operational(&bfa->ioc) && bfa->iocfc.cfgdone; 1612 return bfa_ioc_is_operational(&bfa->ioc) &&
1613 bfa_fsm_cmp_state(&bfa->iocfc, bfa_iocfc_sm_operational);
1329} 1614}
1330 1615
1331/* 1616/*
@@ -1567,16 +1852,6 @@ bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q)
1567 } 1852 }
1568} 1853}
1569 1854
1570void
1571bfa_iocfc_cb_dconf_modinit(struct bfa_s *bfa, bfa_status_t status)
1572{
1573 if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT) {
1574 if (bfa->iocfc.cfgdone == BFA_TRUE)
1575 bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
1576 bfa_iocfc_init_cb, bfa);
1577 }
1578}
1579
1580/* 1855/*
1581 * Return the list of PCI vendor/device id lists supported by this 1856 * Return the list of PCI vendor/device id lists supported by this
1582 * BFA instance. 1857 * BFA instance.