diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-06-24 23:28:37 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-29 18:27:20 -0400 |
commit | 3350d98d6d072fc4ac3622e61dc3dc351ef01dc5 (patch) | |
tree | 44aa4df294c2bea6ff7cf84b6bbe340737fe4331 /drivers/scsi/bfa | |
parent | 3d7fc66dcd8d510aaa46ab9b914b632bc149b05c (diff) |
[SCSI] bfa: Added support to query PHY.
- Added PHY sub-module.
- Implemented interface to obtain stats and to
read/update the fw from the PHY module.
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.c | 14 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_defs.h | 37 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc.c | 521 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc.h | 54 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_modules.h | 1 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_port.c | 1 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.c | 116 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.h | 26 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi.h | 97 |
9 files changed, 867 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index e688ff72166d..c38e589105a5 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c | |||
@@ -154,6 +154,16 @@ bfa_com_diag_attach(struct bfa_s *bfa) | |||
154 | bfa_diag_memclaim(diag, diag_dma->kva_curp, diag_dma->dma_curp); | 154 | bfa_diag_memclaim(diag, diag_dma->kva_curp, diag_dma->dma_curp); |
155 | } | 155 | } |
156 | 156 | ||
157 | static void | ||
158 | bfa_com_phy_attach(struct bfa_s *bfa, bfa_boolean_t mincfg) | ||
159 | { | ||
160 | struct bfa_phy_s *phy = BFA_PHY(bfa); | ||
161 | struct bfa_mem_dma_s *phy_dma = BFA_MEM_PHY_DMA(bfa); | ||
162 | |||
163 | bfa_phy_attach(phy, &bfa->ioc, bfa, bfa->trcmod, mincfg); | ||
164 | bfa_phy_memclaim(phy, phy_dma->kva_curp, phy_dma->dma_curp, mincfg); | ||
165 | } | ||
166 | |||
157 | /* | 167 | /* |
158 | * BFA IOC FC related definitions | 168 | * BFA IOC FC related definitions |
159 | */ | 169 | */ |
@@ -1395,6 +1405,7 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, | |||
1395 | struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa); | 1405 | struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa); |
1396 | struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa); | 1406 | struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa); |
1397 | struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa); | 1407 | struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa); |
1408 | struct bfa_mem_dma_s *phy_dma = BFA_MEM_PHY_DMA(bfa); | ||
1398 | 1409 | ||
1399 | WARN_ON((cfg == NULL) || (meminfo == NULL)); | 1410 | WARN_ON((cfg == NULL) || (meminfo == NULL)); |
1400 | 1411 | ||
@@ -1417,6 +1428,8 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, | |||
1417 | bfa_mem_dma_setup(meminfo, flash_dma, | 1428 | bfa_mem_dma_setup(meminfo, flash_dma, |
1418 | bfa_flash_meminfo(cfg->drvcfg.min_cfg)); | 1429 | bfa_flash_meminfo(cfg->drvcfg.min_cfg)); |
1419 | bfa_mem_dma_setup(meminfo, diag_dma, bfa_diag_meminfo()); | 1430 | bfa_mem_dma_setup(meminfo, diag_dma, bfa_diag_meminfo()); |
1431 | bfa_mem_dma_setup(meminfo, phy_dma, | ||
1432 | bfa_phy_meminfo(cfg->drvcfg.min_cfg)); | ||
1420 | } | 1433 | } |
1421 | 1434 | ||
1422 | /* | 1435 | /* |
@@ -1488,6 +1501,7 @@ bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
1488 | bfa_com_sfp_attach(bfa); | 1501 | bfa_com_sfp_attach(bfa); |
1489 | bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg); | 1502 | bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg); |
1490 | bfa_com_diag_attach(bfa); | 1503 | bfa_com_diag_attach(bfa); |
1504 | bfa_com_phy_attach(bfa, cfg->drvcfg.min_cfg); | ||
1491 | } | 1505 | } |
1492 | 1506 | ||
1493 | /* | 1507 | /* |
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index ddf13d74e4b0..ed8d31b0188b 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h | |||
@@ -170,6 +170,7 @@ enum bfa_status { | |||
170 | BFA_STATUS_TRUNK_DISABLED = 165, /* Trunking is disabled on | 170 | BFA_STATUS_TRUNK_DISABLED = 165, /* Trunking is disabled on |
171 | * the adapter */ | 171 | * the adapter */ |
172 | BFA_STATUS_IOPROFILE_OFF = 175, /* IO profile OFF */ | 172 | BFA_STATUS_IOPROFILE_OFF = 175, /* IO profile OFF */ |
173 | BFA_STATUS_PHY_NOT_PRESENT = 183, /* PHY module not present */ | ||
173 | BFA_STATUS_FEATURE_NOT_SUPPORTED = 192, /* Feature not supported */ | 174 | BFA_STATUS_FEATURE_NOT_SUPPORTED = 192, /* Feature not supported */ |
174 | BFA_STATUS_FAA_ENABLED = 197, /* FAA is already enabled */ | 175 | BFA_STATUS_FAA_ENABLED = 197, /* FAA is already enabled */ |
175 | BFA_STATUS_FAA_DISABLED = 198, /* FAA is already disabled */ | 176 | BFA_STATUS_FAA_DISABLED = 198, /* FAA is already disabled */ |
@@ -939,6 +940,42 @@ struct bfa_diag_loopback_s { | |||
939 | u8 rsvd[2]; | 940 | u8 rsvd[2]; |
940 | }; | 941 | }; |
941 | 942 | ||
943 | /* | ||
944 | * PHY module specific | ||
945 | */ | ||
946 | enum bfa_phy_status_e { | ||
947 | BFA_PHY_STATUS_GOOD = 0, /* phy is good */ | ||
948 | BFA_PHY_STATUS_NOT_PRESENT = 1, /* phy does not exist */ | ||
949 | BFA_PHY_STATUS_BAD = 2, /* phy is bad */ | ||
950 | }; | ||
951 | |||
952 | /* | ||
953 | * phy attributes for phy query | ||
954 | */ | ||
955 | struct bfa_phy_attr_s { | ||
956 | u32 status; /* phy present/absent status */ | ||
957 | u32 length; /* firmware length */ | ||
958 | u32 fw_ver; /* firmware version */ | ||
959 | u32 an_status; /* AN status */ | ||
960 | u32 pma_pmd_status; /* PMA/PMD link status */ | ||
961 | u32 pma_pmd_signal; /* PMA/PMD signal detect */ | ||
962 | u32 pcs_status; /* PCS link status */ | ||
963 | }; | ||
964 | |||
965 | /* | ||
966 | * phy stats | ||
967 | */ | ||
968 | struct bfa_phy_stats_s { | ||
969 | u32 status; /* phy stats status */ | ||
970 | u32 link_breaks; /* Num of link breaks after linkup */ | ||
971 | u32 pma_pmd_fault; /* NPMA/PMD fault */ | ||
972 | u32 pcs_fault; /* PCS fault */ | ||
973 | u32 speed_neg; /* Num of speed negotiation */ | ||
974 | u32 tx_eq_training; /* Num of TX EQ training */ | ||
975 | u32 tx_eq_timeout; /* Num of TX EQ timeout */ | ||
976 | u32 crc_error; /* Num of CRC errors */ | ||
977 | }; | ||
978 | |||
942 | #pragma pack() | 979 | #pragma pack() |
943 | 980 | ||
944 | #endif /* __BFA_DEFS_H__ */ | 981 | #endif /* __BFA_DEFS_H__ */ |
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 31467780b619..d6c2bf3865d2 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c | |||
@@ -2159,6 +2159,7 @@ void | |||
2159 | bfa_ioc_detach(struct bfa_ioc_s *ioc) | 2159 | bfa_ioc_detach(struct bfa_ioc_s *ioc) |
2160 | { | 2160 | { |
2161 | bfa_fsm_send_event(ioc, IOC_E_DETACH); | 2161 | bfa_fsm_send_event(ioc, IOC_E_DETACH); |
2162 | INIT_LIST_HEAD(&ioc->notify_q); | ||
2162 | } | 2163 | } |
2163 | 2164 | ||
2164 | /* | 2165 | /* |
@@ -3120,6 +3121,7 @@ bfa_ablk_attach(struct bfa_ablk_s *ablk, struct bfa_ioc_s *ioc) | |||
3120 | ablk->ioc = ioc; | 3121 | ablk->ioc = ioc; |
3121 | 3122 | ||
3122 | bfa_ioc_mbox_regisr(ablk->ioc, BFI_MC_ABLK, bfa_ablk_isr, ablk); | 3123 | bfa_ioc_mbox_regisr(ablk->ioc, BFI_MC_ABLK, bfa_ablk_isr, ablk); |
3124 | bfa_q_qe_init(&ablk->ioc_notify); | ||
3123 | bfa_ioc_notify_init(&ablk->ioc_notify, bfa_ablk_notify, ablk); | 3125 | bfa_ioc_notify_init(&ablk->ioc_notify, bfa_ablk_notify, ablk); |
3124 | list_add_tail(&ablk->ioc_notify.qe, &ablk->ioc->notify_q); | 3126 | list_add_tail(&ablk->ioc_notify.qe, &ablk->ioc->notify_q); |
3125 | } | 3127 | } |
@@ -4895,3 +4897,522 @@ bfa_diag_memclaim(struct bfa_diag_s *diag, u8 *dm_kva, u64 dm_pa) | |||
4895 | diag->fwping.dbuf_pa = dm_pa; | 4897 | diag->fwping.dbuf_pa = dm_pa; |
4896 | memset(diag->fwping.dbuf_kva, 0, BFI_DIAG_DMA_BUF_SZ); | 4898 | memset(diag->fwping.dbuf_kva, 0, BFI_DIAG_DMA_BUF_SZ); |
4897 | } | 4899 | } |
4900 | |||
4901 | /* | ||
4902 | * PHY module specific | ||
4903 | */ | ||
4904 | #define BFA_PHY_DMA_BUF_SZ 0x02000 /* 8k dma buffer */ | ||
4905 | #define BFA_PHY_LOCK_STATUS 0x018878 /* phy semaphore status reg */ | ||
4906 | |||
4907 | static void | ||
4908 | bfa_phy_ntoh32(u32 *obuf, u32 *ibuf, int sz) | ||
4909 | { | ||
4910 | int i, m = sz >> 2; | ||
4911 | |||
4912 | for (i = 0; i < m; i++) | ||
4913 | obuf[i] = be32_to_cpu(ibuf[i]); | ||
4914 | } | ||
4915 | |||
4916 | static bfa_boolean_t | ||
4917 | bfa_phy_present(struct bfa_phy_s *phy) | ||
4918 | { | ||
4919 | return (phy->ioc->attr->card_type == BFA_MFG_TYPE_LIGHTNING); | ||
4920 | } | ||
4921 | |||
4922 | static void | ||
4923 | bfa_phy_notify(void *cbarg, enum bfa_ioc_event_e event) | ||
4924 | { | ||
4925 | struct bfa_phy_s *phy = cbarg; | ||
4926 | |||
4927 | bfa_trc(phy, event); | ||
4928 | |||
4929 | switch (event) { | ||
4930 | case BFA_IOC_E_DISABLED: | ||
4931 | case BFA_IOC_E_FAILED: | ||
4932 | if (phy->op_busy) { | ||
4933 | phy->status = BFA_STATUS_IOC_FAILURE; | ||
4934 | phy->cbfn(phy->cbarg, phy->status); | ||
4935 | phy->op_busy = 0; | ||
4936 | } | ||
4937 | break; | ||
4938 | |||
4939 | default: | ||
4940 | break; | ||
4941 | } | ||
4942 | } | ||
4943 | |||
4944 | /* | ||
4945 | * Send phy attribute query request. | ||
4946 | * | ||
4947 | * @param[in] cbarg - callback argument | ||
4948 | */ | ||
4949 | static void | ||
4950 | bfa_phy_query_send(void *cbarg) | ||
4951 | { | ||
4952 | struct bfa_phy_s *phy = cbarg; | ||
4953 | struct bfi_phy_query_req_s *msg = | ||
4954 | (struct bfi_phy_query_req_s *) phy->mb.msg; | ||
4955 | |||
4956 | msg->instance = phy->instance; | ||
4957 | bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_QUERY_REQ, | ||
4958 | bfa_ioc_portid(phy->ioc)); | ||
4959 | bfa_alen_set(&msg->alen, sizeof(struct bfa_phy_attr_s), phy->dbuf_pa); | ||
4960 | bfa_ioc_mbox_queue(phy->ioc, &phy->mb); | ||
4961 | } | ||
4962 | |||
4963 | /* | ||
4964 | * Send phy write request. | ||
4965 | * | ||
4966 | * @param[in] cbarg - callback argument | ||
4967 | */ | ||
4968 | static void | ||
4969 | bfa_phy_write_send(void *cbarg) | ||
4970 | { | ||
4971 | struct bfa_phy_s *phy = cbarg; | ||
4972 | struct bfi_phy_write_req_s *msg = | ||
4973 | (struct bfi_phy_write_req_s *) phy->mb.msg; | ||
4974 | u32 len; | ||
4975 | u16 *buf, *dbuf; | ||
4976 | int i, sz; | ||
4977 | |||
4978 | msg->instance = phy->instance; | ||
4979 | msg->offset = cpu_to_be32(phy->addr_off + phy->offset); | ||
4980 | len = (phy->residue < BFA_PHY_DMA_BUF_SZ) ? | ||
4981 | phy->residue : BFA_PHY_DMA_BUF_SZ; | ||
4982 | msg->length = cpu_to_be32(len); | ||
4983 | |||
4984 | /* indicate if it's the last msg of the whole write operation */ | ||
4985 | msg->last = (len == phy->residue) ? 1 : 0; | ||
4986 | |||
4987 | bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_WRITE_REQ, | ||
4988 | bfa_ioc_portid(phy->ioc)); | ||
4989 | bfa_alen_set(&msg->alen, len, phy->dbuf_pa); | ||
4990 | |||
4991 | buf = (u16 *) (phy->ubuf + phy->offset); | ||
4992 | dbuf = (u16 *)phy->dbuf_kva; | ||
4993 | sz = len >> 1; | ||
4994 | for (i = 0; i < sz; i++) | ||
4995 | buf[i] = cpu_to_be16(dbuf[i]); | ||
4996 | |||
4997 | bfa_ioc_mbox_queue(phy->ioc, &phy->mb); | ||
4998 | |||
4999 | phy->residue -= len; | ||
5000 | phy->offset += len; | ||
5001 | } | ||
5002 | |||
5003 | /* | ||
5004 | * Send phy read request. | ||
5005 | * | ||
5006 | * @param[in] cbarg - callback argument | ||
5007 | */ | ||
5008 | static void | ||
5009 | bfa_phy_read_send(void *cbarg) | ||
5010 | { | ||
5011 | struct bfa_phy_s *phy = cbarg; | ||
5012 | struct bfi_phy_read_req_s *msg = | ||
5013 | (struct bfi_phy_read_req_s *) phy->mb.msg; | ||
5014 | u32 len; | ||
5015 | |||
5016 | msg->instance = phy->instance; | ||
5017 | msg->offset = cpu_to_be32(phy->addr_off + phy->offset); | ||
5018 | len = (phy->residue < BFA_PHY_DMA_BUF_SZ) ? | ||
5019 | phy->residue : BFA_PHY_DMA_BUF_SZ; | ||
5020 | msg->length = cpu_to_be32(len); | ||
5021 | bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_READ_REQ, | ||
5022 | bfa_ioc_portid(phy->ioc)); | ||
5023 | bfa_alen_set(&msg->alen, len, phy->dbuf_pa); | ||
5024 | bfa_ioc_mbox_queue(phy->ioc, &phy->mb); | ||
5025 | } | ||
5026 | |||
5027 | /* | ||
5028 | * Send phy stats request. | ||
5029 | * | ||
5030 | * @param[in] cbarg - callback argument | ||
5031 | */ | ||
5032 | static void | ||
5033 | bfa_phy_stats_send(void *cbarg) | ||
5034 | { | ||
5035 | struct bfa_phy_s *phy = cbarg; | ||
5036 | struct bfi_phy_stats_req_s *msg = | ||
5037 | (struct bfi_phy_stats_req_s *) phy->mb.msg; | ||
5038 | |||
5039 | msg->instance = phy->instance; | ||
5040 | bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_STATS_REQ, | ||
5041 | bfa_ioc_portid(phy->ioc)); | ||
5042 | bfa_alen_set(&msg->alen, sizeof(struct bfa_phy_stats_s), phy->dbuf_pa); | ||
5043 | bfa_ioc_mbox_queue(phy->ioc, &phy->mb); | ||
5044 | } | ||
5045 | |||
5046 | /* | ||
5047 | * Flash memory info API. | ||
5048 | * | ||
5049 | * @param[in] mincfg - minimal cfg variable | ||
5050 | */ | ||
5051 | u32 | ||
5052 | bfa_phy_meminfo(bfa_boolean_t mincfg) | ||
5053 | { | ||
5054 | /* min driver doesn't need phy */ | ||
5055 | if (mincfg) | ||
5056 | return 0; | ||
5057 | |||
5058 | return BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
5059 | } | ||
5060 | |||
5061 | /* | ||
5062 | * Flash attach API. | ||
5063 | * | ||
5064 | * @param[in] phy - phy structure | ||
5065 | * @param[in] ioc - ioc structure | ||
5066 | * @param[in] dev - device structure | ||
5067 | * @param[in] trcmod - trace module | ||
5068 | * @param[in] logmod - log module | ||
5069 | */ | ||
5070 | void | ||
5071 | bfa_phy_attach(struct bfa_phy_s *phy, struct bfa_ioc_s *ioc, void *dev, | ||
5072 | struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg) | ||
5073 | { | ||
5074 | phy->ioc = ioc; | ||
5075 | phy->trcmod = trcmod; | ||
5076 | phy->cbfn = NULL; | ||
5077 | phy->cbarg = NULL; | ||
5078 | phy->op_busy = 0; | ||
5079 | |||
5080 | bfa_ioc_mbox_regisr(phy->ioc, BFI_MC_PHY, bfa_phy_intr, phy); | ||
5081 | bfa_q_qe_init(&phy->ioc_notify); | ||
5082 | bfa_ioc_notify_init(&phy->ioc_notify, bfa_phy_notify, phy); | ||
5083 | list_add_tail(&phy->ioc_notify.qe, &phy->ioc->notify_q); | ||
5084 | |||
5085 | /* min driver doesn't need phy */ | ||
5086 | if (mincfg) { | ||
5087 | phy->dbuf_kva = NULL; | ||
5088 | phy->dbuf_pa = 0; | ||
5089 | } | ||
5090 | } | ||
5091 | |||
5092 | /* | ||
5093 | * Claim memory for phy | ||
5094 | * | ||
5095 | * @param[in] phy - phy structure | ||
5096 | * @param[in] dm_kva - pointer to virtual memory address | ||
5097 | * @param[in] dm_pa - physical memory address | ||
5098 | * @param[in] mincfg - minimal cfg variable | ||
5099 | */ | ||
5100 | void | ||
5101 | bfa_phy_memclaim(struct bfa_phy_s *phy, u8 *dm_kva, u64 dm_pa, | ||
5102 | bfa_boolean_t mincfg) | ||
5103 | { | ||
5104 | if (mincfg) | ||
5105 | return; | ||
5106 | |||
5107 | phy->dbuf_kva = dm_kva; | ||
5108 | phy->dbuf_pa = dm_pa; | ||
5109 | memset(phy->dbuf_kva, 0, BFA_PHY_DMA_BUF_SZ); | ||
5110 | dm_kva += BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
5111 | dm_pa += BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
5112 | } | ||
5113 | |||
5114 | bfa_boolean_t | ||
5115 | bfa_phy_busy(struct bfa_ioc_s *ioc) | ||
5116 | { | ||
5117 | void __iomem *rb; | ||
5118 | |||
5119 | rb = bfa_ioc_bar0(ioc); | ||
5120 | return readl(rb + BFA_PHY_LOCK_STATUS); | ||
5121 | } | ||
5122 | |||
5123 | /* | ||
5124 | * Get phy attribute. | ||
5125 | * | ||
5126 | * @param[in] phy - phy structure | ||
5127 | * @param[in] attr - phy attribute structure | ||
5128 | * @param[in] cbfn - callback function | ||
5129 | * @param[in] cbarg - callback argument | ||
5130 | * | ||
5131 | * Return status. | ||
5132 | */ | ||
5133 | bfa_status_t | ||
5134 | bfa_phy_get_attr(struct bfa_phy_s *phy, u8 instance, | ||
5135 | struct bfa_phy_attr_s *attr, bfa_cb_phy_t cbfn, void *cbarg) | ||
5136 | { | ||
5137 | bfa_trc(phy, BFI_PHY_H2I_QUERY_REQ); | ||
5138 | bfa_trc(phy, instance); | ||
5139 | |||
5140 | if (!bfa_phy_present(phy)) | ||
5141 | return BFA_STATUS_PHY_NOT_PRESENT; | ||
5142 | |||
5143 | if (!bfa_ioc_is_operational(phy->ioc)) | ||
5144 | return BFA_STATUS_IOC_NON_OP; | ||
5145 | |||
5146 | if (phy->op_busy || bfa_phy_busy(phy->ioc)) { | ||
5147 | bfa_trc(phy, phy->op_busy); | ||
5148 | return BFA_STATUS_DEVBUSY; | ||
5149 | } | ||
5150 | |||
5151 | phy->op_busy = 1; | ||
5152 | phy->cbfn = cbfn; | ||
5153 | phy->cbarg = cbarg; | ||
5154 | phy->instance = instance; | ||
5155 | phy->ubuf = (uint8_t *) attr; | ||
5156 | bfa_phy_query_send(phy); | ||
5157 | |||
5158 | return BFA_STATUS_OK; | ||
5159 | } | ||
5160 | |||
5161 | /* | ||
5162 | * Get phy stats. | ||
5163 | * | ||
5164 | * @param[in] phy - phy structure | ||
5165 | * @param[in] instance - phy image instance | ||
5166 | * @param[in] stats - pointer to phy stats | ||
5167 | * @param[in] cbfn - callback function | ||
5168 | * @param[in] cbarg - callback argument | ||
5169 | * | ||
5170 | * Return status. | ||
5171 | */ | ||
5172 | bfa_status_t | ||
5173 | bfa_phy_get_stats(struct bfa_phy_s *phy, u8 instance, | ||
5174 | struct bfa_phy_stats_s *stats, | ||
5175 | bfa_cb_phy_t cbfn, void *cbarg) | ||
5176 | { | ||
5177 | bfa_trc(phy, BFI_PHY_H2I_STATS_REQ); | ||
5178 | bfa_trc(phy, instance); | ||
5179 | |||
5180 | if (!bfa_phy_present(phy)) | ||
5181 | return BFA_STATUS_PHY_NOT_PRESENT; | ||
5182 | |||
5183 | if (!bfa_ioc_is_operational(phy->ioc)) | ||
5184 | return BFA_STATUS_IOC_NON_OP; | ||
5185 | |||
5186 | if (phy->op_busy || bfa_phy_busy(phy->ioc)) { | ||
5187 | bfa_trc(phy, phy->op_busy); | ||
5188 | return BFA_STATUS_DEVBUSY; | ||
5189 | } | ||
5190 | |||
5191 | phy->op_busy = 1; | ||
5192 | phy->cbfn = cbfn; | ||
5193 | phy->cbarg = cbarg; | ||
5194 | phy->instance = instance; | ||
5195 | phy->ubuf = (u8 *) stats; | ||
5196 | bfa_phy_stats_send(phy); | ||
5197 | |||
5198 | return BFA_STATUS_OK; | ||
5199 | } | ||
5200 | |||
5201 | /* | ||
5202 | * Update phy image. | ||
5203 | * | ||
5204 | * @param[in] phy - phy structure | ||
5205 | * @param[in] instance - phy image instance | ||
5206 | * @param[in] buf - update data buffer | ||
5207 | * @param[in] len - data buffer length | ||
5208 | * @param[in] offset - offset relative to starting address | ||
5209 | * @param[in] cbfn - callback function | ||
5210 | * @param[in] cbarg - callback argument | ||
5211 | * | ||
5212 | * Return status. | ||
5213 | */ | ||
5214 | bfa_status_t | ||
5215 | bfa_phy_update(struct bfa_phy_s *phy, u8 instance, | ||
5216 | void *buf, u32 len, u32 offset, | ||
5217 | bfa_cb_phy_t cbfn, void *cbarg) | ||
5218 | { | ||
5219 | bfa_trc(phy, BFI_PHY_H2I_WRITE_REQ); | ||
5220 | bfa_trc(phy, instance); | ||
5221 | bfa_trc(phy, len); | ||
5222 | bfa_trc(phy, offset); | ||
5223 | |||
5224 | if (!bfa_phy_present(phy)) | ||
5225 | return BFA_STATUS_PHY_NOT_PRESENT; | ||
5226 | |||
5227 | if (!bfa_ioc_is_operational(phy->ioc)) | ||
5228 | return BFA_STATUS_IOC_NON_OP; | ||
5229 | |||
5230 | /* 'len' must be in word (4-byte) boundary */ | ||
5231 | if (!len || (len & 0x03)) | ||
5232 | return BFA_STATUS_FAILED; | ||
5233 | |||
5234 | if (phy->op_busy || bfa_phy_busy(phy->ioc)) { | ||
5235 | bfa_trc(phy, phy->op_busy); | ||
5236 | return BFA_STATUS_DEVBUSY; | ||
5237 | } | ||
5238 | |||
5239 | phy->op_busy = 1; | ||
5240 | phy->cbfn = cbfn; | ||
5241 | phy->cbarg = cbarg; | ||
5242 | phy->instance = instance; | ||
5243 | phy->residue = len; | ||
5244 | phy->offset = 0; | ||
5245 | phy->addr_off = offset; | ||
5246 | phy->ubuf = buf; | ||
5247 | |||
5248 | bfa_phy_write_send(phy); | ||
5249 | return BFA_STATUS_OK; | ||
5250 | } | ||
5251 | |||
5252 | /* | ||
5253 | * Read phy image. | ||
5254 | * | ||
5255 | * @param[in] phy - phy structure | ||
5256 | * @param[in] instance - phy image instance | ||
5257 | * @param[in] buf - read data buffer | ||
5258 | * @param[in] len - data buffer length | ||
5259 | * @param[in] offset - offset relative to starting address | ||
5260 | * @param[in] cbfn - callback function | ||
5261 | * @param[in] cbarg - callback argument | ||
5262 | * | ||
5263 | * Return status. | ||
5264 | */ | ||
5265 | bfa_status_t | ||
5266 | bfa_phy_read(struct bfa_phy_s *phy, u8 instance, | ||
5267 | void *buf, u32 len, u32 offset, | ||
5268 | bfa_cb_phy_t cbfn, void *cbarg) | ||
5269 | { | ||
5270 | bfa_trc(phy, BFI_PHY_H2I_READ_REQ); | ||
5271 | bfa_trc(phy, instance); | ||
5272 | bfa_trc(phy, len); | ||
5273 | bfa_trc(phy, offset); | ||
5274 | |||
5275 | if (!bfa_phy_present(phy)) | ||
5276 | return BFA_STATUS_PHY_NOT_PRESENT; | ||
5277 | |||
5278 | if (!bfa_ioc_is_operational(phy->ioc)) | ||
5279 | return BFA_STATUS_IOC_NON_OP; | ||
5280 | |||
5281 | /* 'len' must be in word (4-byte) boundary */ | ||
5282 | if (!len || (len & 0x03)) | ||
5283 | return BFA_STATUS_FAILED; | ||
5284 | |||
5285 | if (phy->op_busy || bfa_phy_busy(phy->ioc)) { | ||
5286 | bfa_trc(phy, phy->op_busy); | ||
5287 | return BFA_STATUS_DEVBUSY; | ||
5288 | } | ||
5289 | |||
5290 | phy->op_busy = 1; | ||
5291 | phy->cbfn = cbfn; | ||
5292 | phy->cbarg = cbarg; | ||
5293 | phy->instance = instance; | ||
5294 | phy->residue = len; | ||
5295 | phy->offset = 0; | ||
5296 | phy->addr_off = offset; | ||
5297 | phy->ubuf = buf; | ||
5298 | bfa_phy_read_send(phy); | ||
5299 | |||
5300 | return BFA_STATUS_OK; | ||
5301 | } | ||
5302 | |||
5303 | /* | ||
5304 | * Process phy response messages upon receiving interrupts. | ||
5305 | * | ||
5306 | * @param[in] phyarg - phy structure | ||
5307 | * @param[in] msg - message structure | ||
5308 | */ | ||
5309 | void | ||
5310 | bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg) | ||
5311 | { | ||
5312 | struct bfa_phy_s *phy = phyarg; | ||
5313 | u32 status; | ||
5314 | |||
5315 | union { | ||
5316 | struct bfi_phy_query_rsp_s *query; | ||
5317 | struct bfi_phy_stats_rsp_s *stats; | ||
5318 | struct bfi_phy_write_rsp_s *write; | ||
5319 | struct bfi_phy_read_rsp_s *read; | ||
5320 | struct bfi_mbmsg_s *msg; | ||
5321 | } m; | ||
5322 | |||
5323 | m.msg = msg; | ||
5324 | bfa_trc(phy, msg->mh.msg_id); | ||
5325 | |||
5326 | if (!phy->op_busy) { | ||
5327 | /* receiving response after ioc failure */ | ||
5328 | bfa_trc(phy, 0x9999); | ||
5329 | return; | ||
5330 | } | ||
5331 | |||
5332 | switch (msg->mh.msg_id) { | ||
5333 | case BFI_PHY_I2H_QUERY_RSP: | ||
5334 | status = be32_to_cpu(m.query->status); | ||
5335 | bfa_trc(phy, status); | ||
5336 | |||
5337 | if (status == BFA_STATUS_OK) { | ||
5338 | struct bfa_phy_attr_s *attr = | ||
5339 | (struct bfa_phy_attr_s *) phy->ubuf; | ||
5340 | bfa_phy_ntoh32((u32 *)attr, (u32 *)phy->dbuf_kva, | ||
5341 | sizeof(struct bfa_phy_attr_s)); | ||
5342 | bfa_trc(phy, attr->status); | ||
5343 | bfa_trc(phy, attr->length); | ||
5344 | } | ||
5345 | |||
5346 | phy->status = status; | ||
5347 | phy->op_busy = 0; | ||
5348 | if (phy->cbfn) | ||
5349 | phy->cbfn(phy->cbarg, phy->status); | ||
5350 | break; | ||
5351 | case BFI_PHY_I2H_STATS_RSP: | ||
5352 | status = be32_to_cpu(m.stats->status); | ||
5353 | bfa_trc(phy, status); | ||
5354 | |||
5355 | if (status == BFA_STATUS_OK) { | ||
5356 | struct bfa_phy_stats_s *stats = | ||
5357 | (struct bfa_phy_stats_s *) phy->ubuf; | ||
5358 | bfa_phy_ntoh32((u32 *)stats, (u32 *)phy->dbuf_kva, | ||
5359 | sizeof(struct bfa_phy_stats_s)); | ||
5360 | bfa_trc(phy, stats->status); | ||
5361 | } | ||
5362 | |||
5363 | phy->status = status; | ||
5364 | phy->op_busy = 0; | ||
5365 | if (phy->cbfn) | ||
5366 | phy->cbfn(phy->cbarg, phy->status); | ||
5367 | break; | ||
5368 | case BFI_PHY_I2H_WRITE_RSP: | ||
5369 | status = be32_to_cpu(m.write->status); | ||
5370 | bfa_trc(phy, status); | ||
5371 | |||
5372 | if (status != BFA_STATUS_OK || phy->residue == 0) { | ||
5373 | phy->status = status; | ||
5374 | phy->op_busy = 0; | ||
5375 | if (phy->cbfn) | ||
5376 | phy->cbfn(phy->cbarg, phy->status); | ||
5377 | } else { | ||
5378 | bfa_trc(phy, phy->offset); | ||
5379 | bfa_phy_write_send(phy); | ||
5380 | } | ||
5381 | break; | ||
5382 | case BFI_PHY_I2H_READ_RSP: | ||
5383 | status = be32_to_cpu(m.read->status); | ||
5384 | bfa_trc(phy, status); | ||
5385 | |||
5386 | if (status != BFA_STATUS_OK) { | ||
5387 | phy->status = status; | ||
5388 | phy->op_busy = 0; | ||
5389 | if (phy->cbfn) | ||
5390 | phy->cbfn(phy->cbarg, phy->status); | ||
5391 | } else { | ||
5392 | u32 len = be32_to_cpu(m.read->length); | ||
5393 | u16 *buf = (u16 *)(phy->ubuf + phy->offset); | ||
5394 | u16 *dbuf = (u16 *)phy->dbuf_kva; | ||
5395 | int i, sz = len >> 1; | ||
5396 | |||
5397 | bfa_trc(phy, phy->offset); | ||
5398 | bfa_trc(phy, len); | ||
5399 | |||
5400 | for (i = 0; i < sz; i++) | ||
5401 | buf[i] = be16_to_cpu(dbuf[i]); | ||
5402 | |||
5403 | phy->residue -= len; | ||
5404 | phy->offset += len; | ||
5405 | |||
5406 | if (phy->residue == 0) { | ||
5407 | phy->status = status; | ||
5408 | phy->op_busy = 0; | ||
5409 | if (phy->cbfn) | ||
5410 | phy->cbfn(phy->cbarg, phy->status); | ||
5411 | } else | ||
5412 | bfa_phy_read_send(phy); | ||
5413 | } | ||
5414 | break; | ||
5415 | default: | ||
5416 | WARN_ON(1); | ||
5417 | } | ||
5418 | } | ||
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index 5bcab540ea60..c5ecd2edc95d 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h | |||
@@ -632,6 +632,60 @@ bfa_status_t bfa_diag_beacon_port(struct bfa_diag_s *diag, | |||
632 | bfa_boolean_t beacon, bfa_boolean_t link_e2e_beacon, | 632 | bfa_boolean_t beacon, bfa_boolean_t link_e2e_beacon, |
633 | u32 sec); | 633 | u32 sec); |
634 | 634 | ||
635 | /* | ||
636 | * PHY module specific | ||
637 | */ | ||
638 | typedef void (*bfa_cb_phy_t) (void *cbarg, bfa_status_t status); | ||
639 | |||
640 | struct bfa_phy_s { | ||
641 | struct bfa_ioc_s *ioc; /* back pointer to ioc */ | ||
642 | struct bfa_trc_mod_s *trcmod; /* trace module */ | ||
643 | u8 instance; /* port instance */ | ||
644 | u8 op_busy; /* operation busy flag */ | ||
645 | u8 rsv[2]; | ||
646 | u32 residue; /* residual length */ | ||
647 | u32 offset; /* offset */ | ||
648 | bfa_status_t status; /* status */ | ||
649 | u8 *dbuf_kva; /* dma buf virtual address */ | ||
650 | u64 dbuf_pa; /* dma buf physical address */ | ||
651 | struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ | ||
652 | bfa_cb_phy_t cbfn; /* user callback function */ | ||
653 | void *cbarg; /* user callback arg */ | ||
654 | u8 *ubuf; /* user supplied buffer */ | ||
655 | struct bfa_cb_qe_s hcb_qe; /* comp: BFA callback qelem */ | ||
656 | u32 addr_off; /* phy address offset */ | ||
657 | struct bfa_mbox_cmd_s mb; /* mailbox */ | ||
658 | struct bfa_ioc_notify_s ioc_notify; /* ioc event notify */ | ||
659 | struct bfa_mem_dma_s phy_dma; | ||
660 | }; | ||
661 | |||
662 | #define BFA_PHY(__bfa) (&(__bfa)->modules.phy) | ||
663 | #define BFA_MEM_PHY_DMA(__bfa) (&(BFA_PHY(__bfa)->phy_dma)) | ||
664 | |||
665 | bfa_boolean_t bfa_phy_busy(struct bfa_ioc_s *ioc); | ||
666 | bfa_status_t bfa_phy_get_attr(struct bfa_phy_s *phy, u8 instance, | ||
667 | struct bfa_phy_attr_s *attr, | ||
668 | bfa_cb_phy_t cbfn, void *cbarg); | ||
669 | bfa_status_t bfa_phy_get_stats(struct bfa_phy_s *phy, u8 instance, | ||
670 | struct bfa_phy_stats_s *stats, | ||
671 | bfa_cb_phy_t cbfn, void *cbarg); | ||
672 | bfa_status_t bfa_phy_update(struct bfa_phy_s *phy, u8 instance, | ||
673 | void *buf, u32 len, u32 offset, | ||
674 | bfa_cb_phy_t cbfn, void *cbarg); | ||
675 | bfa_status_t bfa_phy_read(struct bfa_phy_s *phy, u8 instance, | ||
676 | void *buf, u32 len, u32 offset, | ||
677 | bfa_cb_phy_t cbfn, void *cbarg); | ||
678 | |||
679 | u32 bfa_phy_meminfo(bfa_boolean_t mincfg); | ||
680 | void bfa_phy_attach(struct bfa_phy_s *phy, struct bfa_ioc_s *ioc, | ||
681 | void *dev, struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg); | ||
682 | void bfa_phy_memclaim(struct bfa_phy_s *phy, | ||
683 | u8 *dm_kva, u64 dm_pa, bfa_boolean_t mincfg); | ||
684 | void bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg); | ||
685 | |||
686 | /* | ||
687 | * IOC specfic macros | ||
688 | */ | ||
635 | #define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) | 689 | #define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) |
636 | #define bfa_ioc_devid(__ioc) ((__ioc)->pcidev.device_id) | 690 | #define bfa_ioc_devid(__ioc) ((__ioc)->pcidev.device_id) |
637 | #define bfa_ioc_bar0(__ioc) ((__ioc)->pcidev.pci_bar_kva) | 691 | #define bfa_ioc_bar0(__ioc) ((__ioc)->pcidev.pci_bar_kva) |
diff --git a/drivers/scsi/bfa/bfa_modules.h b/drivers/scsi/bfa/bfa_modules.h index c6b2fe7ed960..1c6efd40a673 100644 --- a/drivers/scsi/bfa/bfa_modules.h +++ b/drivers/scsi/bfa/bfa_modules.h | |||
@@ -43,6 +43,7 @@ struct bfa_modules_s { | |||
43 | struct bfa_sfp_s sfp; /* SFP module */ | 43 | struct bfa_sfp_s sfp; /* SFP module */ |
44 | struct bfa_flash_s flash; /* flash module */ | 44 | struct bfa_flash_s flash; /* flash module */ |
45 | struct bfa_diag_s diag_mod; /* diagnostics module */ | 45 | struct bfa_diag_s diag_mod; /* diagnostics module */ |
46 | struct bfa_phy_s phy; /* phy module */ | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | /* | 49 | /* |
diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c index f382a475a09d..95e4ad8759ac 100644 --- a/drivers/scsi/bfa/bfa_port.c +++ b/drivers/scsi/bfa/bfa_port.c | |||
@@ -469,6 +469,7 @@ bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, | |||
469 | port->pbc_disabled = BFA_FALSE; | 469 | port->pbc_disabled = BFA_FALSE; |
470 | 470 | ||
471 | bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port); | 471 | bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port); |
472 | bfa_q_qe_init(&port->ioc_notify); | ||
472 | bfa_ioc_notify_init(&port->ioc_notify, bfa_port_notify, port); | 473 | bfa_ioc_notify_init(&port->ioc_notify, bfa_port_notify, port); |
473 | list_add_tail(&port->ioc_notify.qe, &port->ioc->notify_q); | 474 | list_add_tail(&port->ioc_notify.qe, &port->ioc->notify_q); |
474 | 475 | ||
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index a60270287064..552bb250a210 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c | |||
@@ -1393,6 +1393,110 @@ bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd) | |||
1393 | return 0; | 1393 | return 0; |
1394 | } | 1394 | } |
1395 | 1395 | ||
1396 | int | ||
1397 | bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd) | ||
1398 | { | ||
1399 | struct bfa_bsg_phy_attr_s *iocmd = | ||
1400 | (struct bfa_bsg_phy_attr_s *)cmd; | ||
1401 | struct bfad_hal_comp fcomp; | ||
1402 | unsigned long flags; | ||
1403 | |||
1404 | init_completion(&fcomp.comp); | ||
1405 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1406 | iocmd->status = bfa_phy_get_attr(BFA_PHY(&bfad->bfa), iocmd->instance, | ||
1407 | &iocmd->attr, bfad_hcb_comp, &fcomp); | ||
1408 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1409 | if (iocmd->status != BFA_STATUS_OK) | ||
1410 | goto out; | ||
1411 | wait_for_completion(&fcomp.comp); | ||
1412 | iocmd->status = fcomp.status; | ||
1413 | out: | ||
1414 | return 0; | ||
1415 | } | ||
1416 | |||
1417 | int | ||
1418 | bfad_iocmd_phy_get_stats(struct bfad_s *bfad, void *cmd) | ||
1419 | { | ||
1420 | struct bfa_bsg_phy_stats_s *iocmd = | ||
1421 | (struct bfa_bsg_phy_stats_s *)cmd; | ||
1422 | struct bfad_hal_comp fcomp; | ||
1423 | unsigned long flags; | ||
1424 | |||
1425 | init_completion(&fcomp.comp); | ||
1426 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1427 | iocmd->status = bfa_phy_get_stats(BFA_PHY(&bfad->bfa), iocmd->instance, | ||
1428 | &iocmd->stats, bfad_hcb_comp, &fcomp); | ||
1429 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1430 | if (iocmd->status != BFA_STATUS_OK) | ||
1431 | goto out; | ||
1432 | wait_for_completion(&fcomp.comp); | ||
1433 | iocmd->status = fcomp.status; | ||
1434 | out: | ||
1435 | return 0; | ||
1436 | } | ||
1437 | |||
1438 | int | ||
1439 | bfad_iocmd_phy_read(struct bfad_s *bfad, void *cmd, unsigned int payload_len) | ||
1440 | { | ||
1441 | struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd; | ||
1442 | struct bfad_hal_comp fcomp; | ||
1443 | void *iocmd_bufptr; | ||
1444 | unsigned long flags; | ||
1445 | |||
1446 | if (bfad_chk_iocmd_sz(payload_len, | ||
1447 | sizeof(struct bfa_bsg_phy_s), | ||
1448 | iocmd->bufsz) != BFA_STATUS_OK) { | ||
1449 | iocmd->status = BFA_STATUS_VERSION_FAIL; | ||
1450 | return 0; | ||
1451 | } | ||
1452 | |||
1453 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_phy_s); | ||
1454 | init_completion(&fcomp.comp); | ||
1455 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1456 | iocmd->status = bfa_phy_read(BFA_PHY(&bfad->bfa), | ||
1457 | iocmd->instance, iocmd_bufptr, iocmd->bufsz, | ||
1458 | 0, bfad_hcb_comp, &fcomp); | ||
1459 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1460 | if (iocmd->status != BFA_STATUS_OK) | ||
1461 | goto out; | ||
1462 | wait_for_completion(&fcomp.comp); | ||
1463 | iocmd->status = fcomp.status; | ||
1464 | if (iocmd->status != BFA_STATUS_OK) | ||
1465 | goto out; | ||
1466 | out: | ||
1467 | return 0; | ||
1468 | } | ||
1469 | |||
1470 | int | ||
1471 | bfad_iocmd_phy_update(struct bfad_s *bfad, void *cmd, unsigned int payload_len) | ||
1472 | { | ||
1473 | struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd; | ||
1474 | void *iocmd_bufptr; | ||
1475 | struct bfad_hal_comp fcomp; | ||
1476 | unsigned long flags; | ||
1477 | |||
1478 | if (bfad_chk_iocmd_sz(payload_len, | ||
1479 | sizeof(struct bfa_bsg_phy_s), | ||
1480 | iocmd->bufsz) != BFA_STATUS_OK) { | ||
1481 | iocmd->status = BFA_STATUS_VERSION_FAIL; | ||
1482 | return 0; | ||
1483 | } | ||
1484 | |||
1485 | iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_phy_s); | ||
1486 | init_completion(&fcomp.comp); | ||
1487 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1488 | iocmd->status = bfa_phy_update(BFA_PHY(&bfad->bfa), | ||
1489 | iocmd->instance, iocmd_bufptr, iocmd->bufsz, | ||
1490 | 0, bfad_hcb_comp, &fcomp); | ||
1491 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1492 | if (iocmd->status != BFA_STATUS_OK) | ||
1493 | goto out; | ||
1494 | wait_for_completion(&fcomp.comp); | ||
1495 | iocmd->status = fcomp.status; | ||
1496 | out: | ||
1497 | return 0; | ||
1498 | } | ||
1499 | |||
1396 | static int | 1500 | static int |
1397 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | 1501 | bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, |
1398 | unsigned int payload_len) | 1502 | unsigned int payload_len) |
@@ -1566,6 +1670,18 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | |||
1566 | case IOCMD_DIAG_LB_STAT: | 1670 | case IOCMD_DIAG_LB_STAT: |
1567 | rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); | 1671 | rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); |
1568 | break; | 1672 | break; |
1673 | case IOCMD_PHY_GET_ATTR: | ||
1674 | rc = bfad_iocmd_phy_get_attr(bfad, iocmd); | ||
1675 | break; | ||
1676 | case IOCMD_PHY_GET_STATS: | ||
1677 | rc = bfad_iocmd_phy_get_stats(bfad, iocmd); | ||
1678 | break; | ||
1679 | case IOCMD_PHY_UPDATE_FW: | ||
1680 | rc = bfad_iocmd_phy_update(bfad, iocmd, payload_len); | ||
1681 | break; | ||
1682 | case IOCMD_PHY_READ_FW: | ||
1683 | rc = bfad_iocmd_phy_read(bfad, iocmd, payload_len); | ||
1684 | break; | ||
1569 | default: | 1685 | default: |
1570 | rc = EINVAL; | 1686 | rc = EINVAL; |
1571 | break; | 1687 | break; |
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index 89942773febe..5d89c1dd977a 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h | |||
@@ -80,6 +80,10 @@ enum { | |||
80 | IOCMD_DIAG_LED, | 80 | IOCMD_DIAG_LED, |
81 | IOCMD_DIAG_BEACON_LPORT, | 81 | IOCMD_DIAG_BEACON_LPORT, |
82 | IOCMD_DIAG_LB_STAT, | 82 | IOCMD_DIAG_LB_STAT, |
83 | IOCMD_PHY_GET_ATTR, | ||
84 | IOCMD_PHY_GET_STATS, | ||
85 | IOCMD_PHY_UPDATE_FW, | ||
86 | IOCMD_PHY_READ_FW, | ||
83 | }; | 87 | }; |
84 | 88 | ||
85 | struct bfa_bsg_gen_s { | 89 | struct bfa_bsg_gen_s { |
@@ -440,6 +444,28 @@ struct bfa_bsg_diag_lb_stat_s { | |||
440 | u16 rsvd; | 444 | u16 rsvd; |
441 | }; | 445 | }; |
442 | 446 | ||
447 | struct bfa_bsg_phy_attr_s { | ||
448 | bfa_status_t status; | ||
449 | u16 bfad_num; | ||
450 | u16 instance; | ||
451 | struct bfa_phy_attr_s attr; | ||
452 | }; | ||
453 | |||
454 | struct bfa_bsg_phy_s { | ||
455 | bfa_status_t status; | ||
456 | u16 bfad_num; | ||
457 | u16 instance; | ||
458 | u64 bufsz; | ||
459 | u64 buf_ptr; | ||
460 | }; | ||
461 | |||
462 | struct bfa_bsg_phy_stats_s { | ||
463 | bfa_status_t status; | ||
464 | u16 bfad_num; | ||
465 | u16 instance; | ||
466 | struct bfa_phy_stats_s stats; | ||
467 | }; | ||
468 | |||
443 | struct bfa_bsg_fcpt_s { | 469 | struct bfa_bsg_fcpt_s { |
444 | bfa_status_t status; | 470 | bfa_status_t status; |
445 | u16 vf_id; | 471 | u16 vf_id; |
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index efa41b64bb32..1e258d5f8aec 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h | |||
@@ -209,6 +209,7 @@ enum bfi_mclass { | |||
209 | BFI_MC_TSKIM = 18, /* Initiator Task management */ | 209 | BFI_MC_TSKIM = 18, /* Initiator Task management */ |
210 | BFI_MC_PORT = 21, /* Physical port */ | 210 | BFI_MC_PORT = 21, /* Physical port */ |
211 | BFI_MC_SFP = 22, /* SFP module */ | 211 | BFI_MC_SFP = 22, /* SFP module */ |
212 | BFI_MC_PHY = 25, /* External PHY message class */ | ||
212 | BFI_MC_MAX = 32 | 213 | BFI_MC_MAX = 32 |
213 | }; | 214 | }; |
214 | 215 | ||
@@ -1030,6 +1031,102 @@ struct bfi_diag_qtest_req_s { | |||
1030 | }; | 1031 | }; |
1031 | #define bfi_diag_qtest_rsp_t struct bfi_diag_qtest_req_s | 1032 | #define bfi_diag_qtest_rsp_t struct bfi_diag_qtest_req_s |
1032 | 1033 | ||
1034 | /* | ||
1035 | * PHY module specific | ||
1036 | */ | ||
1037 | enum bfi_phy_h2i_msgs_e { | ||
1038 | BFI_PHY_H2I_QUERY_REQ = 1, | ||
1039 | BFI_PHY_H2I_STATS_REQ = 2, | ||
1040 | BFI_PHY_H2I_WRITE_REQ = 3, | ||
1041 | BFI_PHY_H2I_READ_REQ = 4, | ||
1042 | }; | ||
1043 | |||
1044 | enum bfi_phy_i2h_msgs_e { | ||
1045 | BFI_PHY_I2H_QUERY_RSP = BFA_I2HM(1), | ||
1046 | BFI_PHY_I2H_STATS_RSP = BFA_I2HM(2), | ||
1047 | BFI_PHY_I2H_WRITE_RSP = BFA_I2HM(3), | ||
1048 | BFI_PHY_I2H_READ_RSP = BFA_I2HM(4), | ||
1049 | }; | ||
1050 | |||
1051 | /* | ||
1052 | * External PHY query request | ||
1053 | */ | ||
1054 | struct bfi_phy_query_req_s { | ||
1055 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
1056 | u8 instance; | ||
1057 | u8 rsv[3]; | ||
1058 | struct bfi_alen_s alen; | ||
1059 | }; | ||
1060 | |||
1061 | /* | ||
1062 | * External PHY stats request | ||
1063 | */ | ||
1064 | struct bfi_phy_stats_req_s { | ||
1065 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
1066 | u8 instance; | ||
1067 | u8 rsv[3]; | ||
1068 | struct bfi_alen_s alen; | ||
1069 | }; | ||
1070 | |||
1071 | /* | ||
1072 | * External PHY write request | ||
1073 | */ | ||
1074 | struct bfi_phy_write_req_s { | ||
1075 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
1076 | u8 instance; | ||
1077 | u8 last; | ||
1078 | u8 rsv[2]; | ||
1079 | u32 offset; | ||
1080 | u32 length; | ||
1081 | struct bfi_alen_s alen; | ||
1082 | }; | ||
1083 | |||
1084 | /* | ||
1085 | * External PHY read request | ||
1086 | */ | ||
1087 | struct bfi_phy_read_req_s { | ||
1088 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
1089 | u8 instance; | ||
1090 | u8 rsv[3]; | ||
1091 | u32 offset; | ||
1092 | u32 length; | ||
1093 | struct bfi_alen_s alen; | ||
1094 | }; | ||
1095 | |||
1096 | /* | ||
1097 | * External PHY query response | ||
1098 | */ | ||
1099 | struct bfi_phy_query_rsp_s { | ||
1100 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
1101 | u32 status; | ||
1102 | }; | ||
1103 | |||
1104 | /* | ||
1105 | * External PHY stats response | ||
1106 | */ | ||
1107 | struct bfi_phy_stats_rsp_s { | ||
1108 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
1109 | u32 status; | ||
1110 | }; | ||
1111 | |||
1112 | /* | ||
1113 | * External PHY read response | ||
1114 | */ | ||
1115 | struct bfi_phy_read_rsp_s { | ||
1116 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
1117 | u32 status; | ||
1118 | u32 length; | ||
1119 | }; | ||
1120 | |||
1121 | /* | ||
1122 | * External PHY write response | ||
1123 | */ | ||
1124 | struct bfi_phy_write_rsp_s { | ||
1125 | struct bfi_mhdr_s mh; /* Common msg header */ | ||
1126 | u32 status; | ||
1127 | u32 length; | ||
1128 | }; | ||
1129 | |||
1033 | #pragma pack() | 1130 | #pragma pack() |
1034 | 1131 | ||
1035 | #endif /* __BFI_H__ */ | 1132 | #endif /* __BFI_H__ */ |