aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2011-06-24 23:25:36 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-06-29 18:21:23 -0400
commit148d61039c625f3f7e2d0a6ad1efe17f83153e65 (patch)
tree00ae7ce1b9096b35ecb37a1bb9de86edef58f0b5 /drivers/scsi/bfa
parent601380669baa2ba6427b821a14e5c91afb580dfc (diff)
[SCSI] bfa: Added support for CEE info and stats query.
- Added CEE sub-module. - Added support to collect stats/cee module info using BSG interface. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa')
-rw-r--r--drivers/scsi/bfa/bfa_core.c14
-rw-r--r--drivers/scsi/bfa/bfa_defs_svc.h73
-rw-r--r--drivers/scsi/bfa/bfa_modules.h1
-rw-r--r--drivers/scsi/bfa/bfa_port.c365
-rw-r--r--drivers/scsi/bfa/bfa_port.h54
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c96
-rw-r--r--drivers/scsi/bfa/bfad_bsg.h21
-rw-r--r--drivers/scsi/bfa/bfi.h59
8 files changed, 683 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
index 21343c26721d..ec9872484711 100644
--- a/drivers/scsi/bfa/bfa_core.c
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -111,6 +111,17 @@ bfa_com_ablk_attach(struct bfa_s *bfa)
111 bfa_ablk_memclaim(ablk, ablk_dma->kva_curp, ablk_dma->dma_curp); 111 bfa_ablk_memclaim(ablk, ablk_dma->kva_curp, ablk_dma->dma_curp);
112} 112}
113 113
114static void
115bfa_com_cee_attach(struct bfa_s *bfa)
116{
117 struct bfa_cee_s *cee = &bfa->modules.cee;
118 struct bfa_mem_dma_s *cee_dma = BFA_MEM_CEE_DMA(bfa);
119
120 cee->trcmod = bfa->trcmod;
121 bfa_cee_attach(cee, &bfa->ioc, bfa);
122 bfa_cee_mem_claim(cee, cee_dma->kva_curp, cee_dma->dma_curp);
123}
124
114/* 125/*
115 * BFA IOC FC related definitions 126 * BFA IOC FC related definitions
116 */ 127 */
@@ -1348,6 +1359,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
1348 int i; 1359 int i;
1349 struct bfa_mem_dma_s *port_dma = BFA_MEM_PORT_DMA(bfa); 1360 struct bfa_mem_dma_s *port_dma = BFA_MEM_PORT_DMA(bfa);
1350 struct bfa_mem_dma_s *ablk_dma = BFA_MEM_ABLK_DMA(bfa); 1361 struct bfa_mem_dma_s *ablk_dma = BFA_MEM_ABLK_DMA(bfa);
1362 struct bfa_mem_dma_s *cee_dma = BFA_MEM_CEE_DMA(bfa);
1351 1363
1352 WARN_ON((cfg == NULL) || (meminfo == NULL)); 1364 WARN_ON((cfg == NULL) || (meminfo == NULL));
1353 1365
@@ -1365,6 +1377,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
1365 /* dma info setup */ 1377 /* dma info setup */
1366 bfa_mem_dma_setup(meminfo, port_dma, bfa_port_meminfo()); 1378 bfa_mem_dma_setup(meminfo, port_dma, bfa_port_meminfo());
1367 bfa_mem_dma_setup(meminfo, ablk_dma, bfa_ablk_meminfo()); 1379 bfa_mem_dma_setup(meminfo, ablk_dma, bfa_ablk_meminfo());
1380 bfa_mem_dma_setup(meminfo, cee_dma, bfa_cee_meminfo());
1368} 1381}
1369 1382
1370/* 1383/*
@@ -1432,6 +1445,7 @@ bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
1432 1445
1433 bfa_com_port_attach(bfa); 1446 bfa_com_port_attach(bfa);
1434 bfa_com_ablk_attach(bfa); 1447 bfa_com_ablk_attach(bfa);
1448 bfa_com_cee_attach(bfa);
1435} 1449}
1436 1450
1437/* 1451/*
diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h
index 95a17ef631f0..4b6529c7a531 100644
--- a/drivers/scsi/bfa/bfa_defs_svc.h
+++ b/drivers/scsi/bfa/bfa_defs_svc.h
@@ -1142,4 +1142,77 @@ struct bfa_port_cfg_mode_s {
1142 enum bfa_mode_s mode; 1142 enum bfa_mode_s mode;
1143}; 1143};
1144 1144
1145#pragma pack(1)
1146
1147#define BFA_CEE_LLDP_MAX_STRING_LEN (128)
1148#define BFA_CEE_DCBX_MAX_PRIORITY (8)
1149#define BFA_CEE_DCBX_MAX_PGID (8)
1150
1151struct bfa_cee_lldp_str_s {
1152 u8 sub_type;
1153 u8 len;
1154 u8 rsvd[2];
1155 u8 value[BFA_CEE_LLDP_MAX_STRING_LEN];
1156};
1157
1158struct bfa_cee_lldp_cfg_s {
1159 struct bfa_cee_lldp_str_s chassis_id;
1160 struct bfa_cee_lldp_str_s port_id;
1161 struct bfa_cee_lldp_str_s port_desc;
1162 struct bfa_cee_lldp_str_s sys_name;
1163 struct bfa_cee_lldp_str_s sys_desc;
1164 struct bfa_cee_lldp_str_s mgmt_addr;
1165 u16 time_to_live;
1166 u16 enabled_system_cap;
1167};
1168
1169/* CEE/DCBX parameters */
1170struct bfa_cee_dcbx_cfg_s {
1171 u8 pgid[BFA_CEE_DCBX_MAX_PRIORITY];
1172 u8 pg_percentage[BFA_CEE_DCBX_MAX_PGID];
1173 u8 pfc_primap; /* bitmap of priorties with PFC enabled */
1174 u8 fcoe_primap; /* bitmap of priorities used for FcoE traffic */
1175 u8 iscsi_primap; /* bitmap of priorities used for iSCSI traffic */
1176 u8 dcbx_version; /* operating version:CEE or preCEE */
1177 u8 lls_fcoe; /* FCoE Logical Link Status */
1178 u8 lls_lan; /* LAN Logical Link Status */
1179 u8 rsvd[2];
1180};
1181
1182/* CEE Query */
1183struct bfa_cee_attr_s {
1184 u8 cee_status;
1185 u8 error_reason;
1186 struct bfa_cee_lldp_cfg_s lldp_remote;
1187 struct bfa_cee_dcbx_cfg_s dcbx_remote;
1188 mac_t src_mac;
1189 u8 link_speed;
1190 u8 nw_priority;
1191 u8 filler[2];
1192};
1193
1194/* LLDP/DCBX/CEE Statistics */
1195struct bfa_cee_stats_s {
1196 u32 lldp_tx_frames; /* LLDP Tx Frames */
1197 u32 lldp_rx_frames; /* LLDP Rx Frames */
1198 u32 lldp_rx_frames_invalid; /* LLDP Rx Frames invalid */
1199 u32 lldp_rx_frames_new; /* LLDP Rx Frames new */
1200 u32 lldp_tlvs_unrecognized; /* LLDP Rx unrecog. TLVs */
1201 u32 lldp_rx_shutdown_tlvs; /* LLDP Rx shutdown TLVs */
1202 u32 lldp_info_aged_out; /* LLDP remote info aged */
1203 u32 dcbx_phylink_ups; /* DCBX phy link ups */
1204 u32 dcbx_phylink_downs; /* DCBX phy link downs */
1205 u32 dcbx_rx_tlvs; /* DCBX Rx TLVs */
1206 u32 dcbx_rx_tlvs_invalid; /* DCBX Rx TLVs invalid */
1207 u32 dcbx_control_tlv_error; /* DCBX control TLV errors */
1208 u32 dcbx_feature_tlv_error; /* DCBX feature TLV errors */
1209 u32 dcbx_cee_cfg_new; /* DCBX new CEE cfg rcvd */
1210 u32 cee_status_down; /* DCB status down */
1211 u32 cee_status_up; /* DCB status up */
1212 u32 cee_hw_cfg_changed; /* DCB hw cfg changed */
1213 u32 cee_rx_invalid_cfg; /* DCB invalid cfg */
1214};
1215
1216#pragma pack()
1217
1145#endif /* __BFA_DEFS_SVC_H__ */ 1218#endif /* __BFA_DEFS_SVC_H__ */
diff --git a/drivers/scsi/bfa/bfa_modules.h b/drivers/scsi/bfa/bfa_modules.h
index e27fde8c6f2f..239aba711226 100644
--- a/drivers/scsi/bfa/bfa_modules.h
+++ b/drivers/scsi/bfa/bfa_modules.h
@@ -38,6 +38,7 @@ struct bfa_modules_s {
38 struct bfa_sgpg_mod_s sgpg_mod; /* SG page module */ 38 struct bfa_sgpg_mod_s sgpg_mod; /* SG page module */
39 struct bfa_port_s port; /* Physical port module */ 39 struct bfa_port_s port; /* Physical port module */
40 struct bfa_ablk_s ablk; /* ASIC block config module */ 40 struct bfa_ablk_s ablk; /* ASIC block config module */
41 struct bfa_cee_s cee; /* CEE Module */
41}; 42};
42 43
43/* 44/*
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 */
498static void
499bfa_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 */
530static void
531bfa_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 */
566static void
567bfa_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 */
584u32
585bfa_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 */
602void
603bfa_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
627bfa_status_t
628bfa_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
667bfa_status_t
668bfa_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
706bfa_status_t
707bfa_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
742void
743bfa_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
778void
779bfa_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 */
835void
836bfa_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}
diff --git a/drivers/scsi/bfa/bfa_port.h b/drivers/scsi/bfa/bfa_port.h
index b8bdc54aaeb4..947f897328d6 100644
--- a/drivers/scsi/bfa/bfa_port.h
+++ b/drivers/scsi/bfa/bfa_port.h
@@ -66,4 +66,58 @@ bfa_status_t bfa_port_disable(struct bfa_port_s *port,
66u32 bfa_port_meminfo(void); 66u32 bfa_port_meminfo(void);
67void bfa_port_mem_claim(struct bfa_port_s *port, 67void bfa_port_mem_claim(struct bfa_port_s *port,
68 u8 *dma_kva, u64 dma_pa); 68 u8 *dma_kva, u64 dma_pa);
69
70/*
71 * CEE declaration
72 */
73typedef void (*bfa_cee_get_attr_cbfn_t) (void *dev, bfa_status_t status);
74typedef void (*bfa_cee_get_stats_cbfn_t) (void *dev, bfa_status_t status);
75typedef void (*bfa_cee_reset_stats_cbfn_t) (void *dev, bfa_status_t status);
76
77struct bfa_cee_cbfn_s {
78 bfa_cee_get_attr_cbfn_t get_attr_cbfn;
79 void *get_attr_cbarg;
80 bfa_cee_get_stats_cbfn_t get_stats_cbfn;
81 void *get_stats_cbarg;
82 bfa_cee_reset_stats_cbfn_t reset_stats_cbfn;
83 void *reset_stats_cbarg;
84};
85
86struct bfa_cee_s {
87 void *dev;
88 bfa_boolean_t get_attr_pending;
89 bfa_boolean_t get_stats_pending;
90 bfa_boolean_t reset_stats_pending;
91 bfa_status_t get_attr_status;
92 bfa_status_t get_stats_status;
93 bfa_status_t reset_stats_status;
94 struct bfa_cee_cbfn_s cbfn;
95 struct bfa_ioc_notify_s ioc_notify;
96 struct bfa_trc_mod_s *trcmod;
97 struct bfa_cee_attr_s *attr;
98 struct bfa_cee_stats_s *stats;
99 struct bfa_dma_s attr_dma;
100 struct bfa_dma_s stats_dma;
101 struct bfa_ioc_s *ioc;
102 struct bfa_mbox_cmd_s get_cfg_mb;
103 struct bfa_mbox_cmd_s get_stats_mb;
104 struct bfa_mbox_cmd_s reset_stats_mb;
105 struct bfa_mem_dma_s cee_dma;
106};
107
108#define BFA_MEM_CEE_DMA(__bfa) (&((__bfa)->modules.cee.cee_dma))
109
110u32 bfa_cee_meminfo(void);
111void bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva, u64 dma_pa);
112void bfa_cee_attach(struct bfa_cee_s *cee,
113 struct bfa_ioc_s *ioc, void *dev);
114bfa_status_t bfa_cee_get_attr(struct bfa_cee_s *cee,
115 struct bfa_cee_attr_s *attr,
116 bfa_cee_get_attr_cbfn_t cbfn, void *cbarg);
117bfa_status_t bfa_cee_get_stats(struct bfa_cee_s *cee,
118 struct bfa_cee_stats_s *stats,
119 bfa_cee_get_stats_cbfn_t cbfn, void *cbarg);
120bfa_status_t bfa_cee_reset_stats(struct bfa_cee_s *cee,
121 bfa_cee_reset_stats_cbfn_t cbfn, void *cbarg);
122
69#endif /* __BFA_PORT_H__ */ 123#endif /* __BFA_PORT_H__ */
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 5ae591b062b3..fcfe0ae7fd31 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -979,6 +979,93 @@ out:
979 return 0; 979 return 0;
980} 980}
981 981
982int
983bfad_iocmd_cee_attr(struct bfad_s *bfad, void *cmd, unsigned int payload_len)
984{
985 struct bfa_bsg_cee_attr_s *iocmd =
986 (struct bfa_bsg_cee_attr_s *)cmd;
987 void *iocmd_bufptr;
988 struct bfad_hal_comp cee_comp;
989 unsigned long flags;
990
991 if (bfad_chk_iocmd_sz(payload_len,
992 sizeof(struct bfa_bsg_cee_attr_s),
993 sizeof(struct bfa_cee_attr_s)) != BFA_STATUS_OK) {
994 iocmd->status = BFA_STATUS_VERSION_FAIL;
995 return 0;
996 }
997
998 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_cee_attr_s);
999
1000 cee_comp.status = 0;
1001 init_completion(&cee_comp.comp);
1002 mutex_lock(&bfad_mutex);
1003 spin_lock_irqsave(&bfad->bfad_lock, flags);
1004 iocmd->status = bfa_cee_get_attr(&bfad->bfa.modules.cee, iocmd_bufptr,
1005 bfad_hcb_comp, &cee_comp);
1006 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1007 if (iocmd->status != BFA_STATUS_OK) {
1008 mutex_unlock(&bfad_mutex);
1009 bfa_trc(bfad, 0x5555);
1010 goto out;
1011 }
1012 wait_for_completion(&cee_comp.comp);
1013 mutex_unlock(&bfad_mutex);
1014out:
1015 return 0;
1016}
1017
1018int
1019bfad_iocmd_cee_get_stats(struct bfad_s *bfad, void *cmd,
1020 unsigned int payload_len)
1021{
1022 struct bfa_bsg_cee_stats_s *iocmd =
1023 (struct bfa_bsg_cee_stats_s *)cmd;
1024 void *iocmd_bufptr;
1025 struct bfad_hal_comp cee_comp;
1026 unsigned long flags;
1027
1028 if (bfad_chk_iocmd_sz(payload_len,
1029 sizeof(struct bfa_bsg_cee_stats_s),
1030 sizeof(struct bfa_cee_stats_s)) != BFA_STATUS_OK) {
1031 iocmd->status = BFA_STATUS_VERSION_FAIL;
1032 return 0;
1033 }
1034
1035 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_cee_stats_s);
1036
1037 cee_comp.status = 0;
1038 init_completion(&cee_comp.comp);
1039 mutex_lock(&bfad_mutex);
1040 spin_lock_irqsave(&bfad->bfad_lock, flags);
1041 iocmd->status = bfa_cee_get_stats(&bfad->bfa.modules.cee, iocmd_bufptr,
1042 bfad_hcb_comp, &cee_comp);
1043 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1044 if (iocmd->status != BFA_STATUS_OK) {
1045 mutex_unlock(&bfad_mutex);
1046 bfa_trc(bfad, 0x5555);
1047 goto out;
1048 }
1049 wait_for_completion(&cee_comp.comp);
1050 mutex_unlock(&bfad_mutex);
1051out:
1052 return 0;
1053}
1054
1055int
1056bfad_iocmd_cee_reset_stats(struct bfad_s *bfad, void *cmd)
1057{
1058 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
1059 unsigned long flags;
1060
1061 spin_lock_irqsave(&bfad->bfad_lock, flags);
1062 iocmd->status = bfa_cee_reset_stats(&bfad->bfa.modules.cee, NULL, NULL);
1063 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1064 if (iocmd->status != BFA_STATUS_OK)
1065 bfa_trc(bfad, 0x5555);
1066 return 0;
1067}
1068
982static int 1069static int
983bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, 1070bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
984 unsigned int payload_len) 1071 unsigned int payload_len)
@@ -1098,6 +1185,15 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
1098 case IOCMD_FAA_QUERY: 1185 case IOCMD_FAA_QUERY:
1099 rc = bfad_iocmd_faa_query(bfad, iocmd); 1186 rc = bfad_iocmd_faa_query(bfad, iocmd);
1100 break; 1187 break;
1188 case IOCMD_CEE_GET_ATTR:
1189 rc = bfad_iocmd_cee_attr(bfad, iocmd, payload_len);
1190 break;
1191 case IOCMD_CEE_GET_STATS:
1192 rc = bfad_iocmd_cee_get_stats(bfad, iocmd, payload_len);
1193 break;
1194 case IOCMD_CEE_RESET_STATS:
1195 rc = bfad_iocmd_cee_reset_stats(bfad, iocmd);
1196 break;
1101 default: 1197 default:
1102 rc = EINVAL; 1198 rc = EINVAL;
1103 break; 1199 break;
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h
index 0abb2d2036a3..5b4599ad8fb9 100644
--- a/drivers/scsi/bfa/bfad_bsg.h
+++ b/drivers/scsi/bfa/bfad_bsg.h
@@ -62,6 +62,9 @@ enum {
62 IOCMD_FAA_ENABLE, 62 IOCMD_FAA_ENABLE,
63 IOCMD_FAA_DISABLE, 63 IOCMD_FAA_DISABLE,
64 IOCMD_FAA_QUERY, 64 IOCMD_FAA_QUERY,
65 IOCMD_CEE_GET_ATTR,
66 IOCMD_CEE_GET_STATS,
67 IOCMD_CEE_RESET_STATS,
65}; 68};
66 69
67struct bfa_bsg_gen_s { 70struct bfa_bsg_gen_s {
@@ -299,6 +302,24 @@ struct bfa_bsg_faa_attr_s {
299 struct bfa_faa_attr_s faa_attr; 302 struct bfa_faa_attr_s faa_attr;
300}; 303};
301 304
305struct bfa_bsg_cee_attr_s {
306 bfa_status_t status;
307 u16 bfad_num;
308 u16 rsvd;
309 u32 buf_size;
310 u32 rsvd1;
311 u64 buf_ptr;
312};
313
314struct bfa_bsg_cee_stats_s {
315 bfa_status_t status;
316 u16 bfad_num;
317 u16 rsvd;
318 u32 buf_size;
319 u32 rsvd1;
320 u64 buf_ptr;
321};
322
302struct bfa_bsg_fcpt_s { 323struct bfa_bsg_fcpt_s {
303 bfa_status_t status; 324 bfa_status_t status;
304 u16 vf_id; 325 u16 vf_id;
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h
index d36c81b88f69..037b377668c2 100644
--- a/drivers/scsi/bfa/bfi.h
+++ b/drivers/scsi/bfa/bfi.h
@@ -190,6 +190,7 @@ enum bfi_pcifn_class {
190 */ 190 */
191enum bfi_mclass { 191enum bfi_mclass {
192 BFI_MC_IOC = 1, /* IO Controller (IOC) */ 192 BFI_MC_IOC = 1, /* IO Controller (IOC) */
193 BFI_MC_CEE = 4, /* CEE */
193 BFI_MC_FCPORT = 5, /* FC port */ 194 BFI_MC_FCPORT = 5, /* FC port */
194 BFI_MC_IOCFC = 6, /* FC - IO Controller (IOC) */ 195 BFI_MC_IOCFC = 6, /* FC - IO Controller (IOC) */
195 BFI_MC_ABLK = 7, /* ASIC block configuration */ 196 BFI_MC_ABLK = 7, /* ASIC block configuration */
@@ -706,6 +707,64 @@ struct bfi_ablk_i2h_rsp_s {
706 u8 port_mode; 707 u8 port_mode;
707}; 708};
708 709
710
711/*
712 * CEE module specific messages
713 */
714
715/* Mailbox commands from host to firmware */
716enum bfi_cee_h2i_msgs_e {
717 BFI_CEE_H2I_GET_CFG_REQ = 1,
718 BFI_CEE_H2I_RESET_STATS = 2,
719 BFI_CEE_H2I_GET_STATS_REQ = 3,
720};
721
722enum bfi_cee_i2h_msgs_e {
723 BFI_CEE_I2H_GET_CFG_RSP = BFA_I2HM(1),
724 BFI_CEE_I2H_RESET_STATS_RSP = BFA_I2HM(2),
725 BFI_CEE_I2H_GET_STATS_RSP = BFA_I2HM(3),
726};
727
728/*
729 * H2I command structure for resetting the stats
730 */
731struct bfi_cee_reset_stats_s {
732 struct bfi_mhdr_s mh;
733};
734
735/*
736 * Get configuration command from host
737 */
738struct bfi_cee_get_req_s {
739 struct bfi_mhdr_s mh;
740 union bfi_addr_u dma_addr;
741};
742
743/*
744 * Reply message from firmware
745 */
746struct bfi_cee_get_rsp_s {
747 struct bfi_mhdr_s mh;
748 u8 cmd_status;
749 u8 rsvd[3];
750};
751
752/*
753 * Reply message from firmware
754 */
755struct bfi_cee_stats_rsp_s {
756 struct bfi_mhdr_s mh;
757 u8 cmd_status;
758 u8 rsvd[3];
759};
760
761/* Mailbox message structures from firmware to host */
762union bfi_cee_i2h_msg_u {
763 struct bfi_mhdr_s mh;
764 struct bfi_cee_get_rsp_s get_rsp;
765 struct bfi_cee_stats_rsp_s stats_rsp;
766};
767
709#pragma pack() 768#pragma pack()
710 769
711#endif /* __BFI_H__ */ 770#endif /* __BFI_H__ */