diff options
Diffstat (limited to 'drivers/scsi/bfa/bfa_port.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_port.c | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c index 8bb6d75f9160..f382a475a09d 100644 --- a/drivers/scsi/bfa/bfa_port.c +++ b/drivers/scsi/bfa/bfa_port.c | |||
@@ -480,3 +480,368 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, | |||
480 | 480 | ||
481 | bfa_trc(port, 0); | 481 | bfa_trc(port, 0); |
482 | } | 482 | } |
483 | |||
484 | /* | ||
485 | * CEE module specific definitions | ||
486 | */ | ||
487 | |||
488 | /* | ||
489 | * bfa_cee_get_attr_isr() | ||
490 | * | ||
491 | * @brief CEE ISR for get-attributes responses from f/w | ||
492 | * | ||
493 | * @param[in] cee - Pointer to the CEE module | ||
494 | * status - Return status from the f/w | ||
495 | * | ||
496 | * @return void | ||
497 | */ | ||
498 | static void | ||
499 | bfa_cee_get_attr_isr(struct bfa_cee_s *cee, bfa_status_t status) | ||
500 | { | ||
501 | struct bfa_cee_lldp_cfg_s *lldp_cfg = &cee->attr->lldp_remote; | ||
502 | |||
503 | cee->get_attr_status = status; | ||
504 | bfa_trc(cee, 0); | ||
505 | if (status == BFA_STATUS_OK) { | ||
506 | bfa_trc(cee, 0); | ||
507 | memcpy(cee->attr, cee->attr_dma.kva, | ||
508 | sizeof(struct bfa_cee_attr_s)); | ||
509 | lldp_cfg->time_to_live = be16_to_cpu(lldp_cfg->time_to_live); | ||
510 | lldp_cfg->enabled_system_cap = | ||
511 | be16_to_cpu(lldp_cfg->enabled_system_cap); | ||
512 | } | ||
513 | cee->get_attr_pending = BFA_FALSE; | ||
514 | if (cee->cbfn.get_attr_cbfn) { | ||
515 | bfa_trc(cee, 0); | ||
516 | cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status); | ||
517 | } | ||
518 | } | ||
519 | |||
520 | /* | ||
521 | * bfa_cee_get_stats_isr() | ||
522 | * | ||
523 | * @brief CEE ISR for get-stats responses from f/w | ||
524 | * | ||
525 | * @param[in] cee - Pointer to the CEE module | ||
526 | * status - Return status from the f/w | ||
527 | * | ||
528 | * @return void | ||
529 | */ | ||
530 | static void | ||
531 | bfa_cee_get_stats_isr(struct bfa_cee_s *cee, bfa_status_t status) | ||
532 | { | ||
533 | u32 *buffer; | ||
534 | int i; | ||
535 | |||
536 | cee->get_stats_status = status; | ||
537 | bfa_trc(cee, 0); | ||
538 | if (status == BFA_STATUS_OK) { | ||
539 | bfa_trc(cee, 0); | ||
540 | memcpy(cee->stats, cee->stats_dma.kva, | ||
541 | sizeof(struct bfa_cee_stats_s)); | ||
542 | /* swap the cee stats */ | ||
543 | buffer = (u32 *)cee->stats; | ||
544 | for (i = 0; i < (sizeof(struct bfa_cee_stats_s) / | ||
545 | sizeof(u32)); i++) | ||
546 | buffer[i] = cpu_to_be32(buffer[i]); | ||
547 | } | ||
548 | cee->get_stats_pending = BFA_FALSE; | ||
549 | bfa_trc(cee, 0); | ||
550 | if (cee->cbfn.get_stats_cbfn) { | ||
551 | bfa_trc(cee, 0); | ||
552 | cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status); | ||
553 | } | ||
554 | } | ||
555 | |||
556 | /* | ||
557 | * bfa_cee_reset_stats_isr() | ||
558 | * | ||
559 | * @brief CEE ISR for reset-stats responses from f/w | ||
560 | * | ||
561 | * @param[in] cee - Pointer to the CEE module | ||
562 | * status - Return status from the f/w | ||
563 | * | ||
564 | * @return void | ||
565 | */ | ||
566 | static void | ||
567 | bfa_cee_reset_stats_isr(struct bfa_cee_s *cee, bfa_status_t status) | ||
568 | { | ||
569 | cee->reset_stats_status = status; | ||
570 | cee->reset_stats_pending = BFA_FALSE; | ||
571 | if (cee->cbfn.reset_stats_cbfn) | ||
572 | cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status); | ||
573 | } | ||
574 | |||
575 | /* | ||
576 | * bfa_cee_meminfo() | ||
577 | * | ||
578 | * @brief Returns the size of the DMA memory needed by CEE module | ||
579 | * | ||
580 | * @param[in] void | ||
581 | * | ||
582 | * @return Size of DMA region | ||
583 | */ | ||
584 | u32 | ||
585 | bfa_cee_meminfo(void) | ||
586 | { | ||
587 | return BFA_ROUNDUP(sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ) + | ||
588 | BFA_ROUNDUP(sizeof(struct bfa_cee_stats_s), BFA_DMA_ALIGN_SZ); | ||
589 | } | ||
590 | |||
591 | /* | ||
592 | * bfa_cee_mem_claim() | ||
593 | * | ||
594 | * @brief Initialized CEE DMA Memory | ||
595 | * | ||
596 | * @param[in] cee CEE module pointer | ||
597 | * dma_kva Kernel Virtual Address of CEE DMA Memory | ||
598 | * dma_pa Physical Address of CEE DMA Memory | ||
599 | * | ||
600 | * @return void | ||
601 | */ | ||
602 | void | ||
603 | bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva, u64 dma_pa) | ||
604 | { | ||
605 | cee->attr_dma.kva = dma_kva; | ||
606 | cee->attr_dma.pa = dma_pa; | ||
607 | cee->stats_dma.kva = dma_kva + BFA_ROUNDUP( | ||
608 | sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ); | ||
609 | cee->stats_dma.pa = dma_pa + BFA_ROUNDUP( | ||
610 | sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ); | ||
611 | cee->attr = (struct bfa_cee_attr_s *) dma_kva; | ||
612 | cee->stats = (struct bfa_cee_stats_s *) (dma_kva + BFA_ROUNDUP( | ||
613 | sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ)); | ||
614 | } | ||
615 | |||
616 | /* | ||
617 | * bfa_cee_get_attr() | ||
618 | * | ||
619 | * @brief | ||
620 | * Send the request to the f/w to fetch CEE attributes. | ||
621 | * | ||
622 | * @param[in] Pointer to the CEE module data structure. | ||
623 | * | ||
624 | * @return Status | ||
625 | */ | ||
626 | |||
627 | bfa_status_t | ||
628 | bfa_cee_get_attr(struct bfa_cee_s *cee, struct bfa_cee_attr_s *attr, | ||
629 | bfa_cee_get_attr_cbfn_t cbfn, void *cbarg) | ||
630 | { | ||
631 | struct bfi_cee_get_req_s *cmd; | ||
632 | |||
633 | WARN_ON((cee == NULL) || (cee->ioc == NULL)); | ||
634 | bfa_trc(cee, 0); | ||
635 | if (!bfa_ioc_is_operational(cee->ioc)) { | ||
636 | bfa_trc(cee, 0); | ||
637 | return BFA_STATUS_IOC_FAILURE; | ||
638 | } | ||
639 | if (cee->get_attr_pending == BFA_TRUE) { | ||
640 | bfa_trc(cee, 0); | ||
641 | return BFA_STATUS_DEVBUSY; | ||
642 | } | ||
643 | cee->get_attr_pending = BFA_TRUE; | ||
644 | cmd = (struct bfi_cee_get_req_s *) cee->get_cfg_mb.msg; | ||
645 | cee->attr = attr; | ||
646 | cee->cbfn.get_attr_cbfn = cbfn; | ||
647 | cee->cbfn.get_attr_cbarg = cbarg; | ||
648 | bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ, | ||
649 | bfa_ioc_portid(cee->ioc)); | ||
650 | bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa); | ||
651 | bfa_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb); | ||
652 | |||
653 | return BFA_STATUS_OK; | ||
654 | } | ||
655 | |||
656 | /* | ||
657 | * bfa_cee_get_stats() | ||
658 | * | ||
659 | * @brief | ||
660 | * Send the request to the f/w to fetch CEE statistics. | ||
661 | * | ||
662 | * @param[in] Pointer to the CEE module data structure. | ||
663 | * | ||
664 | * @return Status | ||
665 | */ | ||
666 | |||
667 | bfa_status_t | ||
668 | bfa_cee_get_stats(struct bfa_cee_s *cee, struct bfa_cee_stats_s *stats, | ||
669 | bfa_cee_get_stats_cbfn_t cbfn, void *cbarg) | ||
670 | { | ||
671 | struct bfi_cee_get_req_s *cmd; | ||
672 | |||
673 | WARN_ON((cee == NULL) || (cee->ioc == NULL)); | ||
674 | |||
675 | if (!bfa_ioc_is_operational(cee->ioc)) { | ||
676 | bfa_trc(cee, 0); | ||
677 | return BFA_STATUS_IOC_FAILURE; | ||
678 | } | ||
679 | if (cee->get_stats_pending == BFA_TRUE) { | ||
680 | bfa_trc(cee, 0); | ||
681 | return BFA_STATUS_DEVBUSY; | ||
682 | } | ||
683 | cee->get_stats_pending = BFA_TRUE; | ||
684 | cmd = (struct bfi_cee_get_req_s *) cee->get_stats_mb.msg; | ||
685 | cee->stats = stats; | ||
686 | cee->cbfn.get_stats_cbfn = cbfn; | ||
687 | cee->cbfn.get_stats_cbarg = cbarg; | ||
688 | bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_STATS_REQ, | ||
689 | bfa_ioc_portid(cee->ioc)); | ||
690 | bfa_dma_be_addr_set(cmd->dma_addr, cee->stats_dma.pa); | ||
691 | bfa_ioc_mbox_queue(cee->ioc, &cee->get_stats_mb); | ||
692 | |||
693 | return BFA_STATUS_OK; | ||
694 | } | ||
695 | |||
696 | /* | ||
697 | * bfa_cee_reset_stats() | ||
698 | * | ||
699 | * @brief Clears CEE Stats in the f/w. | ||
700 | * | ||
701 | * @param[in] Pointer to the CEE module data structure. | ||
702 | * | ||
703 | * @return Status | ||
704 | */ | ||
705 | |||
706 | bfa_status_t | ||
707 | bfa_cee_reset_stats(struct bfa_cee_s *cee, | ||
708 | bfa_cee_reset_stats_cbfn_t cbfn, void *cbarg) | ||
709 | { | ||
710 | struct bfi_cee_reset_stats_s *cmd; | ||
711 | |||
712 | WARN_ON((cee == NULL) || (cee->ioc == NULL)); | ||
713 | if (!bfa_ioc_is_operational(cee->ioc)) { | ||
714 | bfa_trc(cee, 0); | ||
715 | return BFA_STATUS_IOC_FAILURE; | ||
716 | } | ||
717 | if (cee->reset_stats_pending == BFA_TRUE) { | ||
718 | bfa_trc(cee, 0); | ||
719 | return BFA_STATUS_DEVBUSY; | ||
720 | } | ||
721 | cee->reset_stats_pending = BFA_TRUE; | ||
722 | cmd = (struct bfi_cee_reset_stats_s *) cee->reset_stats_mb.msg; | ||
723 | cee->cbfn.reset_stats_cbfn = cbfn; | ||
724 | cee->cbfn.reset_stats_cbarg = cbarg; | ||
725 | bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_RESET_STATS, | ||
726 | bfa_ioc_portid(cee->ioc)); | ||
727 | bfa_ioc_mbox_queue(cee->ioc, &cee->reset_stats_mb); | ||
728 | |||
729 | return BFA_STATUS_OK; | ||
730 | } | ||
731 | |||
732 | /* | ||
733 | * bfa_cee_isrs() | ||
734 | * | ||
735 | * @brief Handles Mail-box interrupts for CEE module. | ||
736 | * | ||
737 | * @param[in] Pointer to the CEE module data structure. | ||
738 | * | ||
739 | * @return void | ||
740 | */ | ||
741 | |||
742 | void | ||
743 | bfa_cee_isr(void *cbarg, struct bfi_mbmsg_s *m) | ||
744 | { | ||
745 | union bfi_cee_i2h_msg_u *msg; | ||
746 | struct bfi_cee_get_rsp_s *get_rsp; | ||
747 | struct bfa_cee_s *cee = (struct bfa_cee_s *) cbarg; | ||
748 | msg = (union bfi_cee_i2h_msg_u *) m; | ||
749 | get_rsp = (struct bfi_cee_get_rsp_s *) m; | ||
750 | bfa_trc(cee, msg->mh.msg_id); | ||
751 | switch (msg->mh.msg_id) { | ||
752 | case BFI_CEE_I2H_GET_CFG_RSP: | ||
753 | bfa_trc(cee, get_rsp->cmd_status); | ||
754 | bfa_cee_get_attr_isr(cee, get_rsp->cmd_status); | ||
755 | break; | ||
756 | case BFI_CEE_I2H_GET_STATS_RSP: | ||
757 | bfa_cee_get_stats_isr(cee, get_rsp->cmd_status); | ||
758 | break; | ||
759 | case BFI_CEE_I2H_RESET_STATS_RSP: | ||
760 | bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status); | ||
761 | break; | ||
762 | default: | ||
763 | WARN_ON(1); | ||
764 | } | ||
765 | } | ||
766 | |||
767 | /* | ||
768 | * bfa_cee_notify() | ||
769 | * | ||
770 | * @brief CEE module IOC event handler. | ||
771 | * | ||
772 | * @param[in] Pointer to the CEE module data structure. | ||
773 | * @param[in] IOC event type | ||
774 | * | ||
775 | * @return void | ||
776 | */ | ||
777 | |||
778 | void | ||
779 | bfa_cee_notify(void *arg, enum bfa_ioc_event_e event) | ||
780 | { | ||
781 | struct bfa_cee_s *cee = (struct bfa_cee_s *) arg; | ||
782 | |||
783 | bfa_trc(cee, event); | ||
784 | |||
785 | switch (event) { | ||
786 | case BFA_IOC_E_DISABLED: | ||
787 | case BFA_IOC_E_FAILED: | ||
788 | if (cee->get_attr_pending == BFA_TRUE) { | ||
789 | cee->get_attr_status = BFA_STATUS_FAILED; | ||
790 | cee->get_attr_pending = BFA_FALSE; | ||
791 | if (cee->cbfn.get_attr_cbfn) { | ||
792 | cee->cbfn.get_attr_cbfn( | ||
793 | cee->cbfn.get_attr_cbarg, | ||
794 | BFA_STATUS_FAILED); | ||
795 | } | ||
796 | } | ||
797 | if (cee->get_stats_pending == BFA_TRUE) { | ||
798 | cee->get_stats_status = BFA_STATUS_FAILED; | ||
799 | cee->get_stats_pending = BFA_FALSE; | ||
800 | if (cee->cbfn.get_stats_cbfn) { | ||
801 | cee->cbfn.get_stats_cbfn( | ||
802 | cee->cbfn.get_stats_cbarg, | ||
803 | BFA_STATUS_FAILED); | ||
804 | } | ||
805 | } | ||
806 | if (cee->reset_stats_pending == BFA_TRUE) { | ||
807 | cee->reset_stats_status = BFA_STATUS_FAILED; | ||
808 | cee->reset_stats_pending = BFA_FALSE; | ||
809 | if (cee->cbfn.reset_stats_cbfn) { | ||
810 | cee->cbfn.reset_stats_cbfn( | ||
811 | cee->cbfn.reset_stats_cbarg, | ||
812 | BFA_STATUS_FAILED); | ||
813 | } | ||
814 | } | ||
815 | break; | ||
816 | |||
817 | default: | ||
818 | break; | ||
819 | } | ||
820 | } | ||
821 | |||
822 | /* | ||
823 | * bfa_cee_attach() | ||
824 | * | ||
825 | * @brief CEE module-attach API | ||
826 | * | ||
827 | * @param[in] cee - Pointer to the CEE module data structure | ||
828 | * ioc - Pointer to the ioc module data structure | ||
829 | * dev - Pointer to the device driver module data structure | ||
830 | * The device driver specific mbox ISR functions have | ||
831 | * this pointer as one of the parameters. | ||
832 | * | ||
833 | * @return void | ||
834 | */ | ||
835 | void | ||
836 | bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc, | ||
837 | void *dev) | ||
838 | { | ||
839 | WARN_ON(cee == NULL); | ||
840 | cee->dev = dev; | ||
841 | cee->ioc = ioc; | ||
842 | |||
843 | bfa_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee); | ||
844 | bfa_q_qe_init(&cee->ioc_notify); | ||
845 | bfa_ioc_notify_init(&cee->ioc_notify, bfa_cee_notify, cee); | ||
846 | list_add_tail(&cee->ioc_notify.qe, &cee->ioc->notify_q); | ||
847 | } | ||