diff options
Diffstat (limited to 'drivers/scsi/bfa/bfa_ioc.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc.c | 494 |
1 files changed, 475 insertions, 19 deletions
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 75ca8752b9f4..0116c1032e25 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c | |||
@@ -731,8 +731,7 @@ bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf) | |||
731 | /* | 731 | /* |
732 | * Unlock the hw semaphore. Should be here only once per boot. | 732 | * Unlock the hw semaphore. Should be here only once per boot. |
733 | */ | 733 | */ |
734 | readl(iocpf->ioc->ioc_regs.ioc_sem_reg); | 734 | bfa_ioc_ownership_reset(iocpf->ioc); |
735 | writel(1, iocpf->ioc->ioc_regs.ioc_sem_reg); | ||
736 | 735 | ||
737 | /* | 736 | /* |
738 | * unlock init semaphore. | 737 | * unlock init semaphore. |
@@ -1751,6 +1750,7 @@ bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc) | |||
1751 | attr->card_type = be32_to_cpu(attr->card_type); | 1750 | attr->card_type = be32_to_cpu(attr->card_type); |
1752 | attr->maxfrsize = be16_to_cpu(attr->maxfrsize); | 1751 | attr->maxfrsize = be16_to_cpu(attr->maxfrsize); |
1753 | ioc->fcmode = (attr->port_mode == BFI_PORT_MODE_FC); | 1752 | ioc->fcmode = (attr->port_mode == BFI_PORT_MODE_FC); |
1753 | attr->mfg_year = be16_to_cpu(attr->mfg_year); | ||
1754 | 1754 | ||
1755 | bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); | 1755 | bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); |
1756 | } | 1756 | } |
@@ -2497,6 +2497,9 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, | |||
2497 | ad_attr->cna_capable = bfa_ioc_is_cna(ioc); | 2497 | ad_attr->cna_capable = bfa_ioc_is_cna(ioc); |
2498 | ad_attr->trunk_capable = (ad_attr->nports > 1) && | 2498 | ad_attr->trunk_capable = (ad_attr->nports > 1) && |
2499 | !bfa_ioc_is_cna(ioc) && !ad_attr->is_mezz; | 2499 | !bfa_ioc_is_cna(ioc) && !ad_attr->is_mezz; |
2500 | ad_attr->mfg_day = ioc_attr->mfg_day; | ||
2501 | ad_attr->mfg_month = ioc_attr->mfg_month; | ||
2502 | ad_attr->mfg_year = ioc_attr->mfg_year; | ||
2500 | } | 2503 | } |
2501 | 2504 | ||
2502 | enum bfa_ioc_type_e | 2505 | enum bfa_ioc_type_e |
@@ -2923,7 +2926,7 @@ bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc) | |||
2923 | return; | 2926 | return; |
2924 | } | 2927 | } |
2925 | 2928 | ||
2926 | if (ioc->iocpf.poll_time >= BFA_IOC_TOV) | 2929 | if (ioc->iocpf.poll_time >= (3 * BFA_IOC_TOV)) |
2927 | bfa_iocpf_timeout(ioc); | 2930 | bfa_iocpf_timeout(ioc); |
2928 | else { | 2931 | else { |
2929 | ioc->iocpf.poll_time += BFA_IOC_POLL_TOV; | 2932 | ioc->iocpf.poll_time += BFA_IOC_POLL_TOV; |
@@ -3016,7 +3019,6 @@ bfa_ablk_config_swap(struct bfa_ablk_cfg_s *cfg) | |||
3016 | struct bfa_ablk_cfg_inst_s *cfg_inst; | 3019 | struct bfa_ablk_cfg_inst_s *cfg_inst; |
3017 | int i, j; | 3020 | int i, j; |
3018 | u16 be16; | 3021 | u16 be16; |
3019 | u32 be32; | ||
3020 | 3022 | ||
3021 | for (i = 0; i < BFA_ABLK_MAX; i++) { | 3023 | for (i = 0; i < BFA_ABLK_MAX; i++) { |
3022 | cfg_inst = &cfg->inst[i]; | 3024 | cfg_inst = &cfg->inst[i]; |
@@ -3027,8 +3029,10 @@ bfa_ablk_config_swap(struct bfa_ablk_cfg_s *cfg) | |||
3027 | cfg_inst->pf_cfg[j].num_qpairs = be16_to_cpu(be16); | 3029 | cfg_inst->pf_cfg[j].num_qpairs = be16_to_cpu(be16); |
3028 | be16 = cfg_inst->pf_cfg[j].num_vectors; | 3030 | be16 = cfg_inst->pf_cfg[j].num_vectors; |
3029 | cfg_inst->pf_cfg[j].num_vectors = be16_to_cpu(be16); | 3031 | cfg_inst->pf_cfg[j].num_vectors = be16_to_cpu(be16); |
3030 | be32 = cfg_inst->pf_cfg[j].bw; | 3032 | be16 = cfg_inst->pf_cfg[j].bw_min; |
3031 | cfg_inst->pf_cfg[j].bw = be16_to_cpu(be32); | 3033 | cfg_inst->pf_cfg[j].bw_min = be16_to_cpu(be16); |
3034 | be16 = cfg_inst->pf_cfg[j].bw_max; | ||
3035 | cfg_inst->pf_cfg[j].bw_max = be16_to_cpu(be16); | ||
3032 | } | 3036 | } |
3033 | } | 3037 | } |
3034 | } | 3038 | } |
@@ -3170,7 +3174,8 @@ bfa_ablk_query(struct bfa_ablk_s *ablk, struct bfa_ablk_cfg_s *ablk_cfg, | |||
3170 | 3174 | ||
3171 | bfa_status_t | 3175 | bfa_status_t |
3172 | bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn, | 3176 | bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn, |
3173 | u8 port, enum bfi_pcifn_class personality, int bw, | 3177 | u8 port, enum bfi_pcifn_class personality, |
3178 | u16 bw_min, u16 bw_max, | ||
3174 | bfa_ablk_cbfn_t cbfn, void *cbarg) | 3179 | bfa_ablk_cbfn_t cbfn, void *cbarg) |
3175 | { | 3180 | { |
3176 | struct bfi_ablk_h2i_pf_req_s *m; | 3181 | struct bfi_ablk_h2i_pf_req_s *m; |
@@ -3194,7 +3199,8 @@ bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn, | |||
3194 | bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_CREATE, | 3199 | bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_CREATE, |
3195 | bfa_ioc_portid(ablk->ioc)); | 3200 | bfa_ioc_portid(ablk->ioc)); |
3196 | m->pers = cpu_to_be16((u16)personality); | 3201 | m->pers = cpu_to_be16((u16)personality); |
3197 | m->bw = cpu_to_be32(bw); | 3202 | m->bw_min = cpu_to_be16(bw_min); |
3203 | m->bw_max = cpu_to_be16(bw_max); | ||
3198 | m->port = port; | 3204 | m->port = port; |
3199 | bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); | 3205 | bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); |
3200 | 3206 | ||
@@ -3294,8 +3300,8 @@ bfa_ablk_port_config(struct bfa_ablk_s *ablk, int port, enum bfa_mode_s mode, | |||
3294 | } | 3300 | } |
3295 | 3301 | ||
3296 | bfa_status_t | 3302 | bfa_status_t |
3297 | bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, int bw, | 3303 | bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, u16 bw_min, |
3298 | bfa_ablk_cbfn_t cbfn, void *cbarg) | 3304 | u16 bw_max, bfa_ablk_cbfn_t cbfn, void *cbarg) |
3299 | { | 3305 | { |
3300 | struct bfi_ablk_h2i_pf_req_s *m; | 3306 | struct bfi_ablk_h2i_pf_req_s *m; |
3301 | 3307 | ||
@@ -3317,7 +3323,8 @@ bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, int bw, | |||
3317 | bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_UPDATE, | 3323 | bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_UPDATE, |
3318 | bfa_ioc_portid(ablk->ioc)); | 3324 | bfa_ioc_portid(ablk->ioc)); |
3319 | m->pcifn = (u8)pcifn; | 3325 | m->pcifn = (u8)pcifn; |
3320 | m->bw = cpu_to_be32(bw); | 3326 | m->bw_min = cpu_to_be16(bw_min); |
3327 | m->bw_max = cpu_to_be16(bw_max); | ||
3321 | bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); | 3328 | bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb); |
3322 | 3329 | ||
3323 | return BFA_STATUS_OK; | 3330 | return BFA_STATUS_OK; |
@@ -4680,22 +4687,25 @@ diag_tempsensor_comp(struct bfa_diag_s *diag, bfi_diag_ts_rsp_t *rsp) | |||
4680 | diag->tsensor.temp->temp = be16_to_cpu(rsp->temp); | 4687 | diag->tsensor.temp->temp = be16_to_cpu(rsp->temp); |
4681 | diag->tsensor.temp->ts_junc = rsp->ts_junc; | 4688 | diag->tsensor.temp->ts_junc = rsp->ts_junc; |
4682 | diag->tsensor.temp->ts_brd = rsp->ts_brd; | 4689 | diag->tsensor.temp->ts_brd = rsp->ts_brd; |
4683 | diag->tsensor.temp->status = BFA_STATUS_OK; | ||
4684 | 4690 | ||
4685 | if (rsp->ts_brd) { | 4691 | if (rsp->ts_brd) { |
4692 | /* tsensor.temp->status is brd_temp status */ | ||
4693 | diag->tsensor.temp->status = rsp->status; | ||
4686 | if (rsp->status == BFA_STATUS_OK) { | 4694 | if (rsp->status == BFA_STATUS_OK) { |
4687 | diag->tsensor.temp->brd_temp = | 4695 | diag->tsensor.temp->brd_temp = |
4688 | be16_to_cpu(rsp->brd_temp); | 4696 | be16_to_cpu(rsp->brd_temp); |
4689 | } else { | 4697 | } else |
4690 | bfa_trc(diag, rsp->status); | ||
4691 | diag->tsensor.temp->brd_temp = 0; | 4698 | diag->tsensor.temp->brd_temp = 0; |
4692 | diag->tsensor.temp->status = BFA_STATUS_DEVBUSY; | ||
4693 | } | ||
4694 | } | 4699 | } |
4700 | |||
4701 | bfa_trc(diag, rsp->status); | ||
4695 | bfa_trc(diag, rsp->ts_junc); | 4702 | bfa_trc(diag, rsp->ts_junc); |
4696 | bfa_trc(diag, rsp->temp); | 4703 | bfa_trc(diag, rsp->temp); |
4697 | bfa_trc(diag, rsp->ts_brd); | 4704 | bfa_trc(diag, rsp->ts_brd); |
4698 | bfa_trc(diag, rsp->brd_temp); | 4705 | bfa_trc(diag, rsp->brd_temp); |
4706 | |||
4707 | /* tsensor status is always good bcos we always have junction temp */ | ||
4708 | diag->tsensor.status = BFA_STATUS_OK; | ||
4699 | diag->tsensor.cbfn(diag->tsensor.cbarg, diag->tsensor.status); | 4709 | diag->tsensor.cbfn(diag->tsensor.cbarg, diag->tsensor.status); |
4700 | diag->tsensor.lock = 0; | 4710 | diag->tsensor.lock = 0; |
4701 | } | 4711 | } |
@@ -4924,6 +4934,7 @@ bfa_diag_tsensor_query(struct bfa_diag_s *diag, | |||
4924 | diag->tsensor.temp = result; | 4934 | diag->tsensor.temp = result; |
4925 | diag->tsensor.cbfn = cbfn; | 4935 | diag->tsensor.cbfn = cbfn; |
4926 | diag->tsensor.cbarg = cbarg; | 4936 | diag->tsensor.cbarg = cbarg; |
4937 | diag->tsensor.status = BFA_STATUS_OK; | ||
4927 | 4938 | ||
4928 | /* Send msg to fw */ | 4939 | /* Send msg to fw */ |
4929 | diag_tempsensor_send(diag); | 4940 | diag_tempsensor_send(diag); |
@@ -5615,7 +5626,7 @@ bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event) | |||
5615 | } | 5626 | } |
5616 | bfa_sm_set_state(dconf, bfa_dconf_sm_flash_read); | 5627 | bfa_sm_set_state(dconf, bfa_dconf_sm_flash_read); |
5617 | bfa_timer_start(dconf->bfa, &dconf->timer, | 5628 | bfa_timer_start(dconf->bfa, &dconf->timer, |
5618 | bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); | 5629 | bfa_dconf_timer, dconf, 2 * BFA_DCONF_UPDATE_TOV); |
5619 | bfa_status = bfa_flash_read_part(BFA_FLASH(dconf->bfa), | 5630 | bfa_status = bfa_flash_read_part(BFA_FLASH(dconf->bfa), |
5620 | BFA_FLASH_PART_DRV, dconf->instance, | 5631 | BFA_FLASH_PART_DRV, dconf->instance, |
5621 | dconf->dconf, | 5632 | dconf->dconf, |
@@ -5655,7 +5666,7 @@ bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf, | |||
5655 | break; | 5666 | break; |
5656 | case BFA_DCONF_SM_TIMEOUT: | 5667 | case BFA_DCONF_SM_TIMEOUT: |
5657 | bfa_sm_set_state(dconf, bfa_dconf_sm_ready); | 5668 | bfa_sm_set_state(dconf, bfa_dconf_sm_ready); |
5658 | bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_IOC_FAILED); | 5669 | bfa_ioc_suspend(&dconf->bfa->ioc); |
5659 | break; | 5670 | break; |
5660 | case BFA_DCONF_SM_EXIT: | 5671 | case BFA_DCONF_SM_EXIT: |
5661 | bfa_timer_stop(&dconf->timer); | 5672 | bfa_timer_stop(&dconf->timer); |
@@ -5853,7 +5864,6 @@ bfa_dconf_init_cb(void *arg, bfa_status_t status) | |||
5853 | struct bfa_s *bfa = arg; | 5864 | struct bfa_s *bfa = arg; |
5854 | struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); | 5865 | struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); |
5855 | 5866 | ||
5856 | bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP); | ||
5857 | if (status == BFA_STATUS_OK) { | 5867 | if (status == BFA_STATUS_OK) { |
5858 | bfa_dconf_read_data_valid(bfa) = BFA_TRUE; | 5868 | bfa_dconf_read_data_valid(bfa) = BFA_TRUE; |
5859 | if (dconf->dconf->hdr.signature != BFI_DCONF_SIGNATURE) | 5869 | if (dconf->dconf->hdr.signature != BFI_DCONF_SIGNATURE) |
@@ -5861,6 +5871,7 @@ bfa_dconf_init_cb(void *arg, bfa_status_t status) | |||
5861 | if (dconf->dconf->hdr.version != BFI_DCONF_VERSION) | 5871 | if (dconf->dconf->hdr.version != BFI_DCONF_VERSION) |
5862 | dconf->dconf->hdr.version = BFI_DCONF_VERSION; | 5872 | dconf->dconf->hdr.version = BFI_DCONF_VERSION; |
5863 | } | 5873 | } |
5874 | bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP); | ||
5864 | bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DCONF_DONE); | 5875 | bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DCONF_DONE); |
5865 | } | 5876 | } |
5866 | 5877 | ||
@@ -5945,3 +5956,448 @@ bfa_dconf_modexit(struct bfa_s *bfa) | |||
5945 | struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); | 5956 | struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); |
5946 | bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT); | 5957 | bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT); |
5947 | } | 5958 | } |
5959 | |||
5960 | /* | ||
5961 | * FRU specific functions | ||
5962 | */ | ||
5963 | |||
5964 | #define BFA_FRU_DMA_BUF_SZ 0x02000 /* 8k dma buffer */ | ||
5965 | #define BFA_FRU_CHINOOK_MAX_SIZE 0x10000 | ||
5966 | #define BFA_FRU_LIGHTNING_MAX_SIZE 0x200 | ||
5967 | |||
5968 | static void | ||
5969 | bfa_fru_notify(void *cbarg, enum bfa_ioc_event_e event) | ||
5970 | { | ||
5971 | struct bfa_fru_s *fru = cbarg; | ||
5972 | |||
5973 | bfa_trc(fru, event); | ||
5974 | |||
5975 | switch (event) { | ||
5976 | case BFA_IOC_E_DISABLED: | ||
5977 | case BFA_IOC_E_FAILED: | ||
5978 | if (fru->op_busy) { | ||
5979 | fru->status = BFA_STATUS_IOC_FAILURE; | ||
5980 | fru->cbfn(fru->cbarg, fru->status); | ||
5981 | fru->op_busy = 0; | ||
5982 | } | ||
5983 | break; | ||
5984 | |||
5985 | default: | ||
5986 | break; | ||
5987 | } | ||
5988 | } | ||
5989 | |||
5990 | /* | ||
5991 | * Send fru write request. | ||
5992 | * | ||
5993 | * @param[in] cbarg - callback argument | ||
5994 | */ | ||
5995 | static void | ||
5996 | bfa_fru_write_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type) | ||
5997 | { | ||
5998 | struct bfa_fru_s *fru = cbarg; | ||
5999 | struct bfi_fru_write_req_s *msg = | ||
6000 | (struct bfi_fru_write_req_s *) fru->mb.msg; | ||
6001 | u32 len; | ||
6002 | |||
6003 | msg->offset = cpu_to_be32(fru->addr_off + fru->offset); | ||
6004 | len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ? | ||
6005 | fru->residue : BFA_FRU_DMA_BUF_SZ; | ||
6006 | msg->length = cpu_to_be32(len); | ||
6007 | |||
6008 | /* | ||
6009 | * indicate if it's the last msg of the whole write operation | ||
6010 | */ | ||
6011 | msg->last = (len == fru->residue) ? 1 : 0; | ||
6012 | |||
6013 | bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc)); | ||
6014 | bfa_alen_set(&msg->alen, len, fru->dbuf_pa); | ||
6015 | |||
6016 | memcpy(fru->dbuf_kva, fru->ubuf + fru->offset, len); | ||
6017 | bfa_ioc_mbox_queue(fru->ioc, &fru->mb); | ||
6018 | |||
6019 | fru->residue -= len; | ||
6020 | fru->offset += len; | ||
6021 | } | ||
6022 | |||
6023 | /* | ||
6024 | * Send fru read request. | ||
6025 | * | ||
6026 | * @param[in] cbarg - callback argument | ||
6027 | */ | ||
6028 | static void | ||
6029 | bfa_fru_read_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type) | ||
6030 | { | ||
6031 | struct bfa_fru_s *fru = cbarg; | ||
6032 | struct bfi_fru_read_req_s *msg = | ||
6033 | (struct bfi_fru_read_req_s *) fru->mb.msg; | ||
6034 | u32 len; | ||
6035 | |||
6036 | msg->offset = cpu_to_be32(fru->addr_off + fru->offset); | ||
6037 | len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ? | ||
6038 | fru->residue : BFA_FRU_DMA_BUF_SZ; | ||
6039 | msg->length = cpu_to_be32(len); | ||
6040 | bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc)); | ||
6041 | bfa_alen_set(&msg->alen, len, fru->dbuf_pa); | ||
6042 | bfa_ioc_mbox_queue(fru->ioc, &fru->mb); | ||
6043 | } | ||
6044 | |||
6045 | /* | ||
6046 | * Flash memory info API. | ||
6047 | * | ||
6048 | * @param[in] mincfg - minimal cfg variable | ||
6049 | */ | ||
6050 | u32 | ||
6051 | bfa_fru_meminfo(bfa_boolean_t mincfg) | ||
6052 | { | ||
6053 | /* min driver doesn't need fru */ | ||
6054 | if (mincfg) | ||
6055 | return 0; | ||
6056 | |||
6057 | return BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
6058 | } | ||
6059 | |||
6060 | /* | ||
6061 | * Flash attach API. | ||
6062 | * | ||
6063 | * @param[in] fru - fru structure | ||
6064 | * @param[in] ioc - ioc structure | ||
6065 | * @param[in] dev - device structure | ||
6066 | * @param[in] trcmod - trace module | ||
6067 | * @param[in] logmod - log module | ||
6068 | */ | ||
6069 | void | ||
6070 | bfa_fru_attach(struct bfa_fru_s *fru, struct bfa_ioc_s *ioc, void *dev, | ||
6071 | struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg) | ||
6072 | { | ||
6073 | fru->ioc = ioc; | ||
6074 | fru->trcmod = trcmod; | ||
6075 | fru->cbfn = NULL; | ||
6076 | fru->cbarg = NULL; | ||
6077 | fru->op_busy = 0; | ||
6078 | |||
6079 | bfa_ioc_mbox_regisr(fru->ioc, BFI_MC_FRU, bfa_fru_intr, fru); | ||
6080 | bfa_q_qe_init(&fru->ioc_notify); | ||
6081 | bfa_ioc_notify_init(&fru->ioc_notify, bfa_fru_notify, fru); | ||
6082 | list_add_tail(&fru->ioc_notify.qe, &fru->ioc->notify_q); | ||
6083 | |||
6084 | /* min driver doesn't need fru */ | ||
6085 | if (mincfg) { | ||
6086 | fru->dbuf_kva = NULL; | ||
6087 | fru->dbuf_pa = 0; | ||
6088 | } | ||
6089 | } | ||
6090 | |||
6091 | /* | ||
6092 | * Claim memory for fru | ||
6093 | * | ||
6094 | * @param[in] fru - fru structure | ||
6095 | * @param[in] dm_kva - pointer to virtual memory address | ||
6096 | * @param[in] dm_pa - frusical memory address | ||
6097 | * @param[in] mincfg - minimal cfg variable | ||
6098 | */ | ||
6099 | void | ||
6100 | bfa_fru_memclaim(struct bfa_fru_s *fru, u8 *dm_kva, u64 dm_pa, | ||
6101 | bfa_boolean_t mincfg) | ||
6102 | { | ||
6103 | if (mincfg) | ||
6104 | return; | ||
6105 | |||
6106 | fru->dbuf_kva = dm_kva; | ||
6107 | fru->dbuf_pa = dm_pa; | ||
6108 | memset(fru->dbuf_kva, 0, BFA_FRU_DMA_BUF_SZ); | ||
6109 | dm_kva += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
6110 | dm_pa += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
6111 | } | ||
6112 | |||
6113 | /* | ||
6114 | * Update fru vpd image. | ||
6115 | * | ||
6116 | * @param[in] fru - fru structure | ||
6117 | * @param[in] buf - update data buffer | ||
6118 | * @param[in] len - data buffer length | ||
6119 | * @param[in] offset - offset relative to starting address | ||
6120 | * @param[in] cbfn - callback function | ||
6121 | * @param[in] cbarg - callback argument | ||
6122 | * | ||
6123 | * Return status. | ||
6124 | */ | ||
6125 | bfa_status_t | ||
6126 | bfa_fruvpd_update(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, | ||
6127 | bfa_cb_fru_t cbfn, void *cbarg) | ||
6128 | { | ||
6129 | bfa_trc(fru, BFI_FRUVPD_H2I_WRITE_REQ); | ||
6130 | bfa_trc(fru, len); | ||
6131 | bfa_trc(fru, offset); | ||
6132 | |||
6133 | if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) | ||
6134 | return BFA_STATUS_FRU_NOT_PRESENT; | ||
6135 | |||
6136 | if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK) | ||
6137 | return BFA_STATUS_CMD_NOTSUPP; | ||
6138 | |||
6139 | if (!bfa_ioc_is_operational(fru->ioc)) | ||
6140 | return BFA_STATUS_IOC_NON_OP; | ||
6141 | |||
6142 | if (fru->op_busy) { | ||
6143 | bfa_trc(fru, fru->op_busy); | ||
6144 | return BFA_STATUS_DEVBUSY; | ||
6145 | } | ||
6146 | |||
6147 | fru->op_busy = 1; | ||
6148 | |||
6149 | fru->cbfn = cbfn; | ||
6150 | fru->cbarg = cbarg; | ||
6151 | fru->residue = len; | ||
6152 | fru->offset = 0; | ||
6153 | fru->addr_off = offset; | ||
6154 | fru->ubuf = buf; | ||
6155 | |||
6156 | bfa_fru_write_send(fru, BFI_FRUVPD_H2I_WRITE_REQ); | ||
6157 | |||
6158 | return BFA_STATUS_OK; | ||
6159 | } | ||
6160 | |||
6161 | /* | ||
6162 | * Read fru vpd image. | ||
6163 | * | ||
6164 | * @param[in] fru - fru structure | ||
6165 | * @param[in] buf - read data buffer | ||
6166 | * @param[in] len - data buffer length | ||
6167 | * @param[in] offset - offset relative to starting address | ||
6168 | * @param[in] cbfn - callback function | ||
6169 | * @param[in] cbarg - callback argument | ||
6170 | * | ||
6171 | * Return status. | ||
6172 | */ | ||
6173 | bfa_status_t | ||
6174 | bfa_fruvpd_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, | ||
6175 | bfa_cb_fru_t cbfn, void *cbarg) | ||
6176 | { | ||
6177 | bfa_trc(fru, BFI_FRUVPD_H2I_READ_REQ); | ||
6178 | bfa_trc(fru, len); | ||
6179 | bfa_trc(fru, offset); | ||
6180 | |||
6181 | if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) | ||
6182 | return BFA_STATUS_FRU_NOT_PRESENT; | ||
6183 | |||
6184 | if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK) | ||
6185 | return BFA_STATUS_CMD_NOTSUPP; | ||
6186 | |||
6187 | if (!bfa_ioc_is_operational(fru->ioc)) | ||
6188 | return BFA_STATUS_IOC_NON_OP; | ||
6189 | |||
6190 | if (fru->op_busy) { | ||
6191 | bfa_trc(fru, fru->op_busy); | ||
6192 | return BFA_STATUS_DEVBUSY; | ||
6193 | } | ||
6194 | |||
6195 | fru->op_busy = 1; | ||
6196 | |||
6197 | fru->cbfn = cbfn; | ||
6198 | fru->cbarg = cbarg; | ||
6199 | fru->residue = len; | ||
6200 | fru->offset = 0; | ||
6201 | fru->addr_off = offset; | ||
6202 | fru->ubuf = buf; | ||
6203 | bfa_fru_read_send(fru, BFI_FRUVPD_H2I_READ_REQ); | ||
6204 | |||
6205 | return BFA_STATUS_OK; | ||
6206 | } | ||
6207 | |||
6208 | /* | ||
6209 | * Get maximum size fru vpd image. | ||
6210 | * | ||
6211 | * @param[in] fru - fru structure | ||
6212 | * @param[out] size - maximum size of fru vpd data | ||
6213 | * | ||
6214 | * Return status. | ||
6215 | */ | ||
6216 | bfa_status_t | ||
6217 | bfa_fruvpd_get_max_size(struct bfa_fru_s *fru, u32 *max_size) | ||
6218 | { | ||
6219 | if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) | ||
6220 | return BFA_STATUS_FRU_NOT_PRESENT; | ||
6221 | |||
6222 | if (!bfa_ioc_is_operational(fru->ioc)) | ||
6223 | return BFA_STATUS_IOC_NON_OP; | ||
6224 | |||
6225 | if (fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK) | ||
6226 | *max_size = BFA_FRU_CHINOOK_MAX_SIZE; | ||
6227 | else | ||
6228 | return BFA_STATUS_CMD_NOTSUPP; | ||
6229 | return BFA_STATUS_OK; | ||
6230 | } | ||
6231 | /* | ||
6232 | * tfru write. | ||
6233 | * | ||
6234 | * @param[in] fru - fru structure | ||
6235 | * @param[in] buf - update data buffer | ||
6236 | * @param[in] len - data buffer length | ||
6237 | * @param[in] offset - offset relative to starting address | ||
6238 | * @param[in] cbfn - callback function | ||
6239 | * @param[in] cbarg - callback argument | ||
6240 | * | ||
6241 | * Return status. | ||
6242 | */ | ||
6243 | bfa_status_t | ||
6244 | bfa_tfru_write(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, | ||
6245 | bfa_cb_fru_t cbfn, void *cbarg) | ||
6246 | { | ||
6247 | bfa_trc(fru, BFI_TFRU_H2I_WRITE_REQ); | ||
6248 | bfa_trc(fru, len); | ||
6249 | bfa_trc(fru, offset); | ||
6250 | bfa_trc(fru, *((u8 *) buf)); | ||
6251 | |||
6252 | if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) | ||
6253 | return BFA_STATUS_FRU_NOT_PRESENT; | ||
6254 | |||
6255 | if (!bfa_ioc_is_operational(fru->ioc)) | ||
6256 | return BFA_STATUS_IOC_NON_OP; | ||
6257 | |||
6258 | if (fru->op_busy) { | ||
6259 | bfa_trc(fru, fru->op_busy); | ||
6260 | return BFA_STATUS_DEVBUSY; | ||
6261 | } | ||
6262 | |||
6263 | fru->op_busy = 1; | ||
6264 | |||
6265 | fru->cbfn = cbfn; | ||
6266 | fru->cbarg = cbarg; | ||
6267 | fru->residue = len; | ||
6268 | fru->offset = 0; | ||
6269 | fru->addr_off = offset; | ||
6270 | fru->ubuf = buf; | ||
6271 | |||
6272 | bfa_fru_write_send(fru, BFI_TFRU_H2I_WRITE_REQ); | ||
6273 | |||
6274 | return BFA_STATUS_OK; | ||
6275 | } | ||
6276 | |||
6277 | /* | ||
6278 | * tfru read. | ||
6279 | * | ||
6280 | * @param[in] fru - fru structure | ||
6281 | * @param[in] buf - read data buffer | ||
6282 | * @param[in] len - data buffer length | ||
6283 | * @param[in] offset - offset relative to starting address | ||
6284 | * @param[in] cbfn - callback function | ||
6285 | * @param[in] cbarg - callback argument | ||
6286 | * | ||
6287 | * Return status. | ||
6288 | */ | ||
6289 | bfa_status_t | ||
6290 | bfa_tfru_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset, | ||
6291 | bfa_cb_fru_t cbfn, void *cbarg) | ||
6292 | { | ||
6293 | bfa_trc(fru, BFI_TFRU_H2I_READ_REQ); | ||
6294 | bfa_trc(fru, len); | ||
6295 | bfa_trc(fru, offset); | ||
6296 | |||
6297 | if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2) | ||
6298 | return BFA_STATUS_FRU_NOT_PRESENT; | ||
6299 | |||
6300 | if (!bfa_ioc_is_operational(fru->ioc)) | ||
6301 | return BFA_STATUS_IOC_NON_OP; | ||
6302 | |||
6303 | if (fru->op_busy) { | ||
6304 | bfa_trc(fru, fru->op_busy); | ||
6305 | return BFA_STATUS_DEVBUSY; | ||
6306 | } | ||
6307 | |||
6308 | fru->op_busy = 1; | ||
6309 | |||
6310 | fru->cbfn = cbfn; | ||
6311 | fru->cbarg = cbarg; | ||
6312 | fru->residue = len; | ||
6313 | fru->offset = 0; | ||
6314 | fru->addr_off = offset; | ||
6315 | fru->ubuf = buf; | ||
6316 | bfa_fru_read_send(fru, BFI_TFRU_H2I_READ_REQ); | ||
6317 | |||
6318 | return BFA_STATUS_OK; | ||
6319 | } | ||
6320 | |||
6321 | /* | ||
6322 | * Process fru response messages upon receiving interrupts. | ||
6323 | * | ||
6324 | * @param[in] fruarg - fru structure | ||
6325 | * @param[in] msg - message structure | ||
6326 | */ | ||
6327 | void | ||
6328 | bfa_fru_intr(void *fruarg, struct bfi_mbmsg_s *msg) | ||
6329 | { | ||
6330 | struct bfa_fru_s *fru = fruarg; | ||
6331 | struct bfi_fru_rsp_s *rsp = (struct bfi_fru_rsp_s *)msg; | ||
6332 | u32 status; | ||
6333 | |||
6334 | bfa_trc(fru, msg->mh.msg_id); | ||
6335 | |||
6336 | if (!fru->op_busy) { | ||
6337 | /* | ||
6338 | * receiving response after ioc failure | ||
6339 | */ | ||
6340 | bfa_trc(fru, 0x9999); | ||
6341 | return; | ||
6342 | } | ||
6343 | |||
6344 | switch (msg->mh.msg_id) { | ||
6345 | case BFI_FRUVPD_I2H_WRITE_RSP: | ||
6346 | case BFI_TFRU_I2H_WRITE_RSP: | ||
6347 | status = be32_to_cpu(rsp->status); | ||
6348 | bfa_trc(fru, status); | ||
6349 | |||
6350 | if (status != BFA_STATUS_OK || fru->residue == 0) { | ||
6351 | fru->status = status; | ||
6352 | fru->op_busy = 0; | ||
6353 | if (fru->cbfn) | ||
6354 | fru->cbfn(fru->cbarg, fru->status); | ||
6355 | } else { | ||
6356 | bfa_trc(fru, fru->offset); | ||
6357 | if (msg->mh.msg_id == BFI_FRUVPD_I2H_WRITE_RSP) | ||
6358 | bfa_fru_write_send(fru, | ||
6359 | BFI_FRUVPD_H2I_WRITE_REQ); | ||
6360 | else | ||
6361 | bfa_fru_write_send(fru, | ||
6362 | BFI_TFRU_H2I_WRITE_REQ); | ||
6363 | } | ||
6364 | break; | ||
6365 | case BFI_FRUVPD_I2H_READ_RSP: | ||
6366 | case BFI_TFRU_I2H_READ_RSP: | ||
6367 | status = be32_to_cpu(rsp->status); | ||
6368 | bfa_trc(fru, status); | ||
6369 | |||
6370 | if (status != BFA_STATUS_OK) { | ||
6371 | fru->status = status; | ||
6372 | fru->op_busy = 0; | ||
6373 | if (fru->cbfn) | ||
6374 | fru->cbfn(fru->cbarg, fru->status); | ||
6375 | } else { | ||
6376 | u32 len = be32_to_cpu(rsp->length); | ||
6377 | |||
6378 | bfa_trc(fru, fru->offset); | ||
6379 | bfa_trc(fru, len); | ||
6380 | |||
6381 | memcpy(fru->ubuf + fru->offset, fru->dbuf_kva, len); | ||
6382 | fru->residue -= len; | ||
6383 | fru->offset += len; | ||
6384 | |||
6385 | if (fru->residue == 0) { | ||
6386 | fru->status = status; | ||
6387 | fru->op_busy = 0; | ||
6388 | if (fru->cbfn) | ||
6389 | fru->cbfn(fru->cbarg, fru->status); | ||
6390 | } else { | ||
6391 | if (msg->mh.msg_id == BFI_FRUVPD_I2H_READ_RSP) | ||
6392 | bfa_fru_read_send(fru, | ||
6393 | BFI_FRUVPD_H2I_READ_REQ); | ||
6394 | else | ||
6395 | bfa_fru_read_send(fru, | ||
6396 | BFI_TFRU_H2I_READ_REQ); | ||
6397 | } | ||
6398 | } | ||
6399 | break; | ||
6400 | default: | ||
6401 | WARN_ON(1); | ||
6402 | } | ||
6403 | } | ||