aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa/bfa_ioc.c
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2011-06-24 23:22:28 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-06-29 17:56:05 -0400
commit1a4d8e1bd81c018f7b8c7622066d5cfead59b38a (patch)
tree52ec78c60131cf3d861929e1f90d84e8acd0a429 /drivers/scsi/bfa/bfa_ioc.c
parentea9582d721a0d711fb046a25f5e94dcbbc5be410 (diff)
[SCSI] bfa: Enable ASIC block configuration and query.
- Added ASIC block configuration APIs: - to create/delete/update the physical functions - to do adapter/port mode configuration - to query the current ASIC block configuration. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfa_ioc.c')
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c402
1 files changed, 399 insertions, 3 deletions
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index b9413c2e67ff..2c575f5dea04 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -1945,6 +1945,9 @@ bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
1945 break; 1945 break;
1946 1946
1947 case BFI_IOC_I2H_ENABLE_REPLY: 1947 case BFI_IOC_I2H_ENABLE_REPLY:
1948 ioc->port_mode = ioc->port_mode_cfg =
1949 (enum bfa_mode_s)msg->fw_event.port_mode;
1950 ioc->ad_cap_bm = msg->fw_event.cap_bm;
1948 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE); 1951 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE);
1949 break; 1952 break;
1950 1953
@@ -2018,25 +2021,46 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
2018 case BFA_PCI_DEVICE_ID_FC_8G1P: 2021 case BFA_PCI_DEVICE_ID_FC_8G1P:
2019 case BFA_PCI_DEVICE_ID_FC_8G2P: 2022 case BFA_PCI_DEVICE_ID_FC_8G2P:
2020 ioc->asic_gen = BFI_ASIC_GEN_CB; 2023 ioc->asic_gen = BFI_ASIC_GEN_CB;
2024 ioc->fcmode = BFA_TRUE;
2025 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
2026 ioc->ad_cap_bm = BFA_CM_HBA;
2021 break; 2027 break;
2022 2028
2023 case BFA_PCI_DEVICE_ID_CT: 2029 case BFA_PCI_DEVICE_ID_CT:
2024 ioc->asic_gen = BFI_ASIC_GEN_CT; 2030 ioc->asic_gen = BFI_ASIC_GEN_CT;
2025 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH; 2031 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
2026 ioc->asic_mode = BFI_ASIC_MODE_ETH; 2032 ioc->asic_mode = BFI_ASIC_MODE_ETH;
2033 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_CNA;
2034 ioc->ad_cap_bm = BFA_CM_CNA;
2027 break; 2035 break;
2028 2036
2029 case BFA_PCI_DEVICE_ID_CT_FC: 2037 case BFA_PCI_DEVICE_ID_CT_FC:
2030 ioc->asic_gen = BFI_ASIC_GEN_CT; 2038 ioc->asic_gen = BFI_ASIC_GEN_CT;
2039 ioc->fcmode = BFA_TRUE;
2040 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
2041 ioc->ad_cap_bm = BFA_CM_HBA;
2031 break; 2042 break;
2032 2043
2033 case BFA_PCI_DEVICE_ID_CT2: 2044 case BFA_PCI_DEVICE_ID_CT2:
2034 ioc->asic_gen = BFI_ASIC_GEN_CT2; 2045 ioc->asic_gen = BFI_ASIC_GEN_CT2;
2035 if (clscode == BFI_PCIFN_CLASS_FC) 2046 if (clscode == BFI_PCIFN_CLASS_FC &&
2047 pcidev->ssid == BFA_PCI_CT2_SSID_FC) {
2036 ioc->asic_mode = BFI_ASIC_MODE_FC16; 2048 ioc->asic_mode = BFI_ASIC_MODE_FC16;
2037 else { 2049 ioc->fcmode = BFA_TRUE;
2050 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
2051 ioc->ad_cap_bm = BFA_CM_HBA;
2052 } else {
2038 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH; 2053 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
2039 ioc->asic_mode = BFI_ASIC_MODE_ETH; 2054 ioc->asic_mode = BFI_ASIC_MODE_ETH;
2055 if (pcidev->ssid == BFA_PCI_CT2_SSID_FCoE) {
2056 ioc->port_mode =
2057 ioc->port_mode_cfg = BFA_MODE_CNA;
2058 ioc->ad_cap_bm = BFA_CM_CNA;
2059 } else {
2060 ioc->port_mode =
2061 ioc->port_mode_cfg = BFA_MODE_NIC;
2062 ioc->ad_cap_bm = BFA_CM_NIC;
2063 }
2040 } 2064 }
2041 break; 2065 break;
2042 2066
@@ -2477,6 +2501,9 @@ bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
2477 2501
2478 ioc_attr->state = bfa_ioc_get_state(ioc); 2502 ioc_attr->state = bfa_ioc_get_state(ioc);
2479 ioc_attr->port_id = ioc->port_id; 2503 ioc_attr->port_id = ioc->port_id;
2504 ioc_attr->port_mode = ioc->port_mode;
2505 ioc_attr->port_mode_cfg = ioc->port_mode_cfg;
2506 ioc_attr->cap_bm = ioc->ad_cap_bm;
2480 2507
2481 ioc_attr->ioc_type = bfa_ioc_get_type(ioc); 2508 ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
2482 2509
@@ -2837,3 +2864,372 @@ bfa_timer_stop(struct bfa_timer_s *timer)
2837 2864
2838 list_del(&timer->qe); 2865 list_del(&timer->qe);
2839} 2866}
2867
2868/*
2869 * ASIC block related
2870 */
2871static void
2872bfa_ablk_config_swap(struct bfa_ablk_cfg_s *cfg)
2873{
2874 struct bfa_ablk_cfg_inst_s *cfg_inst;
2875 int i, j;
2876 u16 be16;
2877 u32 be32;
2878
2879 for (i = 0; i < BFA_ABLK_MAX; i++) {
2880 cfg_inst = &cfg->inst[i];
2881 for (j = 0; j < BFA_ABLK_MAX_PFS; j++) {
2882 be16 = cfg_inst->pf_cfg[j].pers;
2883 cfg_inst->pf_cfg[j].pers = be16_to_cpu(be16);
2884 be16 = cfg_inst->pf_cfg[j].num_qpairs;
2885 cfg_inst->pf_cfg[j].num_qpairs = be16_to_cpu(be16);
2886 be16 = cfg_inst->pf_cfg[j].num_vectors;
2887 cfg_inst->pf_cfg[j].num_vectors = be16_to_cpu(be16);
2888 be32 = cfg_inst->pf_cfg[j].bw;
2889 cfg_inst->pf_cfg[j].bw = be16_to_cpu(be32);
2890 }
2891 }
2892}
2893
2894static void
2895bfa_ablk_isr(void *cbarg, struct bfi_mbmsg_s *msg)
2896{
2897 struct bfa_ablk_s *ablk = (struct bfa_ablk_s *)cbarg;
2898 struct bfi_ablk_i2h_rsp_s *rsp = (struct bfi_ablk_i2h_rsp_s *)msg;
2899 bfa_ablk_cbfn_t cbfn;
2900
2901 WARN_ON(msg->mh.msg_class != BFI_MC_ABLK);
2902 bfa_trc(ablk->ioc, msg->mh.msg_id);
2903
2904 switch (msg->mh.msg_id) {
2905 case BFI_ABLK_I2H_QUERY:
2906 if (rsp->status == BFA_STATUS_OK) {
2907 memcpy(ablk->cfg, ablk->dma_addr.kva,
2908 sizeof(struct bfa_ablk_cfg_s));
2909 bfa_ablk_config_swap(ablk->cfg);
2910 ablk->cfg = NULL;
2911 }
2912 break;
2913
2914 case BFI_ABLK_I2H_ADPT_CONFIG:
2915 case BFI_ABLK_I2H_PORT_CONFIG:
2916 /* update config port mode */
2917 ablk->ioc->port_mode_cfg = rsp->port_mode;
2918
2919 case BFI_ABLK_I2H_PF_DELETE:
2920 case BFI_ABLK_I2H_PF_UPDATE:
2921 case BFI_ABLK_I2H_OPTROM_ENABLE:
2922 case BFI_ABLK_I2H_OPTROM_DISABLE:
2923 /* No-op */
2924 break;
2925
2926 case BFI_ABLK_I2H_PF_CREATE:
2927 *(ablk->pcifn) = rsp->pcifn;
2928 ablk->pcifn = NULL;
2929 break;
2930
2931 default:
2932 WARN_ON(1);
2933 }
2934
2935 ablk->busy = BFA_FALSE;
2936 if (ablk->cbfn) {
2937 cbfn = ablk->cbfn;
2938 ablk->cbfn = NULL;
2939 cbfn(ablk->cbarg, rsp->status);
2940 }
2941}
2942
2943static void
2944bfa_ablk_notify(void *cbarg, enum bfa_ioc_event_e event)
2945{
2946 struct bfa_ablk_s *ablk = (struct bfa_ablk_s *)cbarg;
2947
2948 bfa_trc(ablk->ioc, event);
2949
2950 switch (event) {
2951 case BFA_IOC_E_ENABLED:
2952 WARN_ON(ablk->busy != BFA_FALSE);
2953 break;
2954
2955 case BFA_IOC_E_DISABLED:
2956 case BFA_IOC_E_FAILED:
2957 /* Fail any pending requests */
2958 ablk->pcifn = NULL;
2959 if (ablk->busy) {
2960 if (ablk->cbfn)
2961 ablk->cbfn(ablk->cbarg, BFA_STATUS_FAILED);
2962 ablk->cbfn = NULL;
2963 ablk->busy = BFA_FALSE;
2964 }
2965 break;
2966
2967 default:
2968 WARN_ON(1);
2969 break;
2970 }
2971}
2972
2973u32
2974bfa_ablk_meminfo(void)
2975{
2976 return BFA_ROUNDUP(sizeof(struct bfa_ablk_cfg_s), BFA_DMA_ALIGN_SZ);
2977}
2978
2979void
2980bfa_ablk_memclaim(struct bfa_ablk_s *ablk, u8 *dma_kva, u64 dma_pa)
2981{
2982 ablk->dma_addr.kva = dma_kva;
2983 ablk->dma_addr.pa = dma_pa;
2984}
2985
2986void
2987bfa_ablk_attach(struct bfa_ablk_s *ablk, struct bfa_ioc_s *ioc)
2988{
2989 ablk->ioc = ioc;
2990
2991 bfa_ioc_mbox_regisr(ablk->ioc, BFI_MC_ABLK, bfa_ablk_isr, ablk);
2992 bfa_ioc_notify_init(&ablk->ioc_notify, bfa_ablk_notify, ablk);
2993 list_add_tail(&ablk->ioc_notify.qe, &ablk->ioc->notify_q);
2994}
2995
2996bfa_status_t
2997bfa_ablk_query(struct bfa_ablk_s *ablk, struct bfa_ablk_cfg_s *ablk_cfg,
2998 bfa_ablk_cbfn_t cbfn, void *cbarg)
2999{
3000 struct bfi_ablk_h2i_query_s *m;
3001
3002 WARN_ON(!ablk_cfg);
3003
3004 if (!bfa_ioc_is_operational(ablk->ioc)) {
3005 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3006 return BFA_STATUS_IOC_FAILURE;
3007 }
3008
3009 if (ablk->busy) {
3010 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3011 return BFA_STATUS_DEVBUSY;
3012 }
3013
3014 ablk->cfg = ablk_cfg;
3015 ablk->cbfn = cbfn;
3016 ablk->cbarg = cbarg;
3017 ablk->busy = BFA_TRUE;
3018
3019 m = (struct bfi_ablk_h2i_query_s *)ablk->mb.msg;
3020 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_QUERY,
3021 bfa_ioc_portid(ablk->ioc));
3022 bfa_dma_be_addr_set(m->addr, ablk->dma_addr.pa);
3023 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3024
3025 return BFA_STATUS_OK;
3026}
3027
3028bfa_status_t
3029bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn,
3030 u8 port, enum bfi_pcifn_class personality, int bw,
3031 bfa_ablk_cbfn_t cbfn, void *cbarg)
3032{
3033 struct bfi_ablk_h2i_pf_req_s *m;
3034
3035 if (!bfa_ioc_is_operational(ablk->ioc)) {
3036 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3037 return BFA_STATUS_IOC_FAILURE;
3038 }
3039
3040 if (ablk->busy) {
3041 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3042 return BFA_STATUS_DEVBUSY;
3043 }
3044
3045 ablk->pcifn = pcifn;
3046 ablk->cbfn = cbfn;
3047 ablk->cbarg = cbarg;
3048 ablk->busy = BFA_TRUE;
3049
3050 m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg;
3051 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_CREATE,
3052 bfa_ioc_portid(ablk->ioc));
3053 m->pers = cpu_to_be16((u16)personality);
3054 m->bw = cpu_to_be32(bw);
3055 m->port = port;
3056 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3057
3058 return BFA_STATUS_OK;
3059}
3060
3061bfa_status_t
3062bfa_ablk_pf_delete(struct bfa_ablk_s *ablk, int pcifn,
3063 bfa_ablk_cbfn_t cbfn, void *cbarg)
3064{
3065 struct bfi_ablk_h2i_pf_req_s *m;
3066
3067 if (!bfa_ioc_is_operational(ablk->ioc)) {
3068 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3069 return BFA_STATUS_IOC_FAILURE;
3070 }
3071
3072 if (ablk->busy) {
3073 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3074 return BFA_STATUS_DEVBUSY;
3075 }
3076
3077 ablk->cbfn = cbfn;
3078 ablk->cbarg = cbarg;
3079 ablk->busy = BFA_TRUE;
3080
3081 m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg;
3082 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_DELETE,
3083 bfa_ioc_portid(ablk->ioc));
3084 m->pcifn = (u8)pcifn;
3085 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3086
3087 return BFA_STATUS_OK;
3088}
3089
3090bfa_status_t
3091bfa_ablk_adapter_config(struct bfa_ablk_s *ablk, enum bfa_mode_s mode,
3092 int max_pf, int max_vf, bfa_ablk_cbfn_t cbfn, void *cbarg)
3093{
3094 struct bfi_ablk_h2i_cfg_req_s *m;
3095
3096 if (!bfa_ioc_is_operational(ablk->ioc)) {
3097 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3098 return BFA_STATUS_IOC_FAILURE;
3099 }
3100
3101 if (ablk->busy) {
3102 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3103 return BFA_STATUS_DEVBUSY;
3104 }
3105
3106 ablk->cbfn = cbfn;
3107 ablk->cbarg = cbarg;
3108 ablk->busy = BFA_TRUE;
3109
3110 m = (struct bfi_ablk_h2i_cfg_req_s *)ablk->mb.msg;
3111 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_ADPT_CONFIG,
3112 bfa_ioc_portid(ablk->ioc));
3113 m->mode = (u8)mode;
3114 m->max_pf = (u8)max_pf;
3115 m->max_vf = (u8)max_vf;
3116 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3117
3118 return BFA_STATUS_OK;
3119}
3120
3121bfa_status_t
3122bfa_ablk_port_config(struct bfa_ablk_s *ablk, int port, enum bfa_mode_s mode,
3123 int max_pf, int max_vf, bfa_ablk_cbfn_t cbfn, void *cbarg)
3124{
3125 struct bfi_ablk_h2i_cfg_req_s *m;
3126
3127 if (!bfa_ioc_is_operational(ablk->ioc)) {
3128 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3129 return BFA_STATUS_IOC_FAILURE;
3130 }
3131
3132 if (ablk->busy) {
3133 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3134 return BFA_STATUS_DEVBUSY;
3135 }
3136
3137 ablk->cbfn = cbfn;
3138 ablk->cbarg = cbarg;
3139 ablk->busy = BFA_TRUE;
3140
3141 m = (struct bfi_ablk_h2i_cfg_req_s *)ablk->mb.msg;
3142 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PORT_CONFIG,
3143 bfa_ioc_portid(ablk->ioc));
3144 m->port = (u8)port;
3145 m->mode = (u8)mode;
3146 m->max_pf = (u8)max_pf;
3147 m->max_vf = (u8)max_vf;
3148 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3149
3150 return BFA_STATUS_OK;
3151}
3152
3153bfa_status_t
3154bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, int bw,
3155 bfa_ablk_cbfn_t cbfn, void *cbarg)
3156{
3157 struct bfi_ablk_h2i_pf_req_s *m;
3158
3159 if (!bfa_ioc_is_operational(ablk->ioc)) {
3160 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3161 return BFA_STATUS_IOC_FAILURE;
3162 }
3163
3164 if (ablk->busy) {
3165 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3166 return BFA_STATUS_DEVBUSY;
3167 }
3168
3169 ablk->cbfn = cbfn;
3170 ablk->cbarg = cbarg;
3171 ablk->busy = BFA_TRUE;
3172
3173 m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg;
3174 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_UPDATE,
3175 bfa_ioc_portid(ablk->ioc));
3176 m->pcifn = (u8)pcifn;
3177 m->bw = cpu_to_be32(bw);
3178 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3179
3180 return BFA_STATUS_OK;
3181}
3182
3183bfa_status_t
3184bfa_ablk_optrom_en(struct bfa_ablk_s *ablk, bfa_ablk_cbfn_t cbfn, void *cbarg)
3185{
3186 struct bfi_ablk_h2i_optrom_s *m;
3187
3188 if (!bfa_ioc_is_operational(ablk->ioc)) {
3189 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3190 return BFA_STATUS_IOC_FAILURE;
3191 }
3192
3193 if (ablk->busy) {
3194 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3195 return BFA_STATUS_DEVBUSY;
3196 }
3197
3198 ablk->cbfn = cbfn;
3199 ablk->cbarg = cbarg;
3200 ablk->busy = BFA_TRUE;
3201
3202 m = (struct bfi_ablk_h2i_optrom_s *)ablk->mb.msg;
3203 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_OPTROM_ENABLE,
3204 bfa_ioc_portid(ablk->ioc));
3205 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3206
3207 return BFA_STATUS_OK;
3208}
3209
3210bfa_status_t
3211bfa_ablk_optrom_dis(struct bfa_ablk_s *ablk, bfa_ablk_cbfn_t cbfn, void *cbarg)
3212{
3213 struct bfi_ablk_h2i_optrom_s *m;
3214
3215 if (!bfa_ioc_is_operational(ablk->ioc)) {
3216 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3217 return BFA_STATUS_IOC_FAILURE;
3218 }
3219
3220 if (ablk->busy) {
3221 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3222 return BFA_STATUS_DEVBUSY;
3223 }
3224
3225 ablk->cbfn = cbfn;
3226 ablk->cbarg = cbarg;
3227 ablk->busy = BFA_TRUE;
3228
3229 m = (struct bfi_ablk_h2i_optrom_s *)ablk->mb.msg;
3230 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_OPTROM_DISABLE,
3231 bfa_ioc_portid(ablk->ioc));
3232 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3233
3234 return BFA_STATUS_OK;
3235}