diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-12 21:57:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-12 21:57:01 -0400 |
commit | 6a5a3d6a4adde0c66f3be29bbd7c0d6ffb7e1a40 (patch) | |
tree | ae416ffa4458df755f984a05d65ee1c3e220c40b /drivers/scsi/bfa/bfa_svc.c | |
parent | 8bbbfa70549bd84f29ff331d0ac051897ccbbd72 (diff) | |
parent | 5c1b10ab7f93d24f29b5630286e323d1c5802d5c (diff) |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull misc SCSI updates from James Bottomley:
"This is an assorted set of stragglers into the merge window with
driver updates for megaraid_sas, lpfc, bfi and mvumi. It also
includes some fairly major fixes for virtio-scsi (scatterlist init),
scsi_debug (off by one error), storvsc (use after free) and qla2xxx
(potential deadlock).
Signed-off-by: James Bottomley <JBottomley@Parallels.com>"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (49 commits)
[SCSI] storvsc: Account for in-transit packets in the RESET path
[SCSI] qla2xxx: fix potential deadlock on ha->hardware_lock
[SCSI] scsi_debug: Fix off-by-one bug when unmapping region
[SCSI] Shorten the path length of scsi_cmd_to_driver()
[SCSI] virtio-scsi: support online resizing of disks
[SCSI] virtio-scsi: fix LUNs greater than 255
[SCSI] virtio-scsi: initialize scatterlist structure
[SCSI] megaraid_sas: Version, Changelog, Copyright update
[SCSI] megaraid_sas: Remove duplicate code
[SCSI] megaraid_sas: Add SystemPD FastPath support
[SCSI] megaraid_sas: Add array boundary check for SystemPD
[SCSI] megaraid_sas: Load io_request DataLength in bytes
[SCSI] megaraid_sas: Add module param for configurable MSI-X vector count
[SCSI] megaraid_sas: Remove un-needed completion_lock spinlock calls
[SCSI] lpfc 8.3.35: Update lpfc version for 8.3.35 driver release
[SCSI] lpfc 8.3.35: Fixed not reporting logical link speed to SCSI midlayer when QoS not on
[SCSI] lpfc 8.3.35: Fix error with fabric service parameters causing performance issues
[SCSI] lpfc 8.3.35: Fixed SCSI host create showing wrong link speed on SLI3 HBA ports
[SCSI] lpfc 8.3.35: Fixed not checking solicition in progress bit when verifying FCF record for use
[SCSI] lpfc 8.3.35: Fixed messages for misconfigured port errors
...
Diffstat (limited to 'drivers/scsi/bfa/bfa_svc.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_svc.c | 732 |
1 files changed, 715 insertions, 17 deletions
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index b2538d60db34..299c1c889b33 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c | |||
@@ -67,6 +67,9 @@ enum bfa_fcport_sm_event { | |||
67 | BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */ | 67 | BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */ |
68 | BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */ | 68 | BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */ |
69 | BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */ | 69 | BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */ |
70 | BFA_FCPORT_SM_DPORTENABLE = 10, /* enable dport */ | ||
71 | BFA_FCPORT_SM_DPORTDISABLE = 11,/* disable dport */ | ||
72 | BFA_FCPORT_SM_FAA_MISCONFIG = 12, /* FAA misconfiguratin */ | ||
70 | }; | 73 | }; |
71 | 74 | ||
72 | /* | 75 | /* |
@@ -197,6 +200,10 @@ static void bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, | |||
197 | enum bfa_fcport_sm_event event); | 200 | enum bfa_fcport_sm_event event); |
198 | static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, | 201 | static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, |
199 | enum bfa_fcport_sm_event event); | 202 | enum bfa_fcport_sm_event event); |
203 | static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, | ||
204 | enum bfa_fcport_sm_event event); | ||
205 | static void bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport, | ||
206 | enum bfa_fcport_sm_event event); | ||
200 | 207 | ||
201 | static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, | 208 | static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, |
202 | enum bfa_fcport_ln_sm_event event); | 209 | enum bfa_fcport_ln_sm_event event); |
@@ -226,6 +233,8 @@ static struct bfa_sm_table_s hal_port_sm_table[] = { | |||
226 | {BFA_SM(bfa_fcport_sm_stopped), BFA_PORT_ST_STOPPED}, | 233 | {BFA_SM(bfa_fcport_sm_stopped), BFA_PORT_ST_STOPPED}, |
227 | {BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN}, | 234 | {BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN}, |
228 | {BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN}, | 235 | {BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN}, |
236 | {BFA_SM(bfa_fcport_sm_dport), BFA_PORT_ST_DPORT}, | ||
237 | {BFA_SM(bfa_fcport_sm_faa_misconfig), BFA_PORT_ST_FAA_MISCONFIG}, | ||
229 | }; | 238 | }; |
230 | 239 | ||
231 | 240 | ||
@@ -1244,6 +1253,12 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
1244 | * Just ignore | 1253 | * Just ignore |
1245 | */ | 1254 | */ |
1246 | break; | 1255 | break; |
1256 | case BFA_LPS_SM_SET_N2N_PID: | ||
1257 | /* | ||
1258 | * When topology is set to loop, bfa_lps_set_n2n_pid() sends | ||
1259 | * this event. Ignore this event. | ||
1260 | */ | ||
1261 | break; | ||
1247 | 1262 | ||
1248 | default: | 1263 | default: |
1249 | bfa_sm_fault(lps->bfa, event); | 1264 | bfa_sm_fault(lps->bfa, event); |
@@ -1261,6 +1276,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
1261 | 1276 | ||
1262 | switch (event) { | 1277 | switch (event) { |
1263 | case BFA_LPS_SM_FWRSP: | 1278 | case BFA_LPS_SM_FWRSP: |
1279 | case BFA_LPS_SM_OFFLINE: | ||
1264 | if (lps->status == BFA_STATUS_OK) { | 1280 | if (lps->status == BFA_STATUS_OK) { |
1265 | bfa_sm_set_state(lps, bfa_lps_sm_online); | 1281 | bfa_sm_set_state(lps, bfa_lps_sm_online); |
1266 | if (lps->fdisc) | 1282 | if (lps->fdisc) |
@@ -1289,7 +1305,6 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
1289 | bfa_lps_login_comp(lps); | 1305 | bfa_lps_login_comp(lps); |
1290 | break; | 1306 | break; |
1291 | 1307 | ||
1292 | case BFA_LPS_SM_OFFLINE: | ||
1293 | case BFA_LPS_SM_DELETE: | 1308 | case BFA_LPS_SM_DELETE: |
1294 | bfa_sm_set_state(lps, bfa_lps_sm_init); | 1309 | bfa_sm_set_state(lps, bfa_lps_sm_init); |
1295 | break; | 1310 | break; |
@@ -2169,6 +2184,12 @@ bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, | |||
2169 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); | 2184 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); |
2170 | break; | 2185 | break; |
2171 | 2186 | ||
2187 | case BFA_FCPORT_SM_FAA_MISCONFIG: | ||
2188 | bfa_fcport_reset_linkinfo(fcport); | ||
2189 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); | ||
2190 | bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); | ||
2191 | break; | ||
2192 | |||
2172 | default: | 2193 | default: |
2173 | bfa_sm_fault(fcport->bfa, event); | 2194 | bfa_sm_fault(fcport->bfa, event); |
2174 | } | 2195 | } |
@@ -2225,6 +2246,12 @@ bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, | |||
2225 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); | 2246 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); |
2226 | break; | 2247 | break; |
2227 | 2248 | ||
2249 | case BFA_FCPORT_SM_FAA_MISCONFIG: | ||
2250 | bfa_fcport_reset_linkinfo(fcport); | ||
2251 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); | ||
2252 | bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); | ||
2253 | break; | ||
2254 | |||
2228 | default: | 2255 | default: |
2229 | bfa_sm_fault(fcport->bfa, event); | 2256 | bfa_sm_fault(fcport->bfa, event); |
2230 | } | 2257 | } |
@@ -2250,11 +2277,11 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, | |||
2250 | if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { | 2277 | if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { |
2251 | 2278 | ||
2252 | bfa_trc(fcport->bfa, | 2279 | bfa_trc(fcport->bfa, |
2253 | pevent->link_state.vc_fcf.fcf.fipenabled); | 2280 | pevent->link_state.attr.vc_fcf.fcf.fipenabled); |
2254 | bfa_trc(fcport->bfa, | 2281 | bfa_trc(fcport->bfa, |
2255 | pevent->link_state.vc_fcf.fcf.fipfailed); | 2282 | pevent->link_state.attr.vc_fcf.fcf.fipfailed); |
2256 | 2283 | ||
2257 | if (pevent->link_state.vc_fcf.fcf.fipfailed) | 2284 | if (pevent->link_state.attr.vc_fcf.fcf.fipfailed) |
2258 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, | 2285 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
2259 | BFA_PL_EID_FIP_FCF_DISC, 0, | 2286 | BFA_PL_EID_FIP_FCF_DISC, 0, |
2260 | "FIP FCF Discovery Failed"); | 2287 | "FIP FCF Discovery Failed"); |
@@ -2311,6 +2338,12 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, | |||
2311 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); | 2338 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); |
2312 | break; | 2339 | break; |
2313 | 2340 | ||
2341 | case BFA_FCPORT_SM_FAA_MISCONFIG: | ||
2342 | bfa_fcport_reset_linkinfo(fcport); | ||
2343 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); | ||
2344 | bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); | ||
2345 | break; | ||
2346 | |||
2314 | default: | 2347 | default: |
2315 | bfa_sm_fault(fcport->bfa, event); | 2348 | bfa_sm_fault(fcport->bfa, event); |
2316 | } | 2349 | } |
@@ -2404,6 +2437,12 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, | |||
2404 | } | 2437 | } |
2405 | break; | 2438 | break; |
2406 | 2439 | ||
2440 | case BFA_FCPORT_SM_FAA_MISCONFIG: | ||
2441 | bfa_fcport_reset_linkinfo(fcport); | ||
2442 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); | ||
2443 | bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); | ||
2444 | break; | ||
2445 | |||
2407 | default: | 2446 | default: |
2408 | bfa_sm_fault(fcport->bfa, event); | 2447 | bfa_sm_fault(fcport->bfa, event); |
2409 | } | 2448 | } |
@@ -2449,6 +2488,12 @@ bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport, | |||
2449 | bfa_reqq_wcancel(&fcport->reqq_wait); | 2488 | bfa_reqq_wcancel(&fcport->reqq_wait); |
2450 | break; | 2489 | break; |
2451 | 2490 | ||
2491 | case BFA_FCPORT_SM_FAA_MISCONFIG: | ||
2492 | bfa_fcport_reset_linkinfo(fcport); | ||
2493 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); | ||
2494 | bfa_sm_set_state(fcport, bfa_fcport_sm_faa_misconfig); | ||
2495 | break; | ||
2496 | |||
2452 | default: | 2497 | default: |
2453 | bfa_sm_fault(fcport->bfa, event); | 2498 | bfa_sm_fault(fcport->bfa, event); |
2454 | } | 2499 | } |
@@ -2600,6 +2645,10 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, | |||
2600 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); | 2645 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); |
2601 | break; | 2646 | break; |
2602 | 2647 | ||
2648 | case BFA_FCPORT_SM_DPORTENABLE: | ||
2649 | bfa_sm_set_state(fcport, bfa_fcport_sm_dport); | ||
2650 | break; | ||
2651 | |||
2603 | default: | 2652 | default: |
2604 | bfa_sm_fault(fcport->bfa, event); | 2653 | bfa_sm_fault(fcport->bfa, event); |
2605 | } | 2654 | } |
@@ -2680,6 +2729,81 @@ bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, | |||
2680 | } | 2729 | } |
2681 | } | 2730 | } |
2682 | 2731 | ||
2732 | static void | ||
2733 | bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event) | ||
2734 | { | ||
2735 | bfa_trc(fcport->bfa, event); | ||
2736 | |||
2737 | switch (event) { | ||
2738 | case BFA_FCPORT_SM_DPORTENABLE: | ||
2739 | case BFA_FCPORT_SM_DISABLE: | ||
2740 | case BFA_FCPORT_SM_ENABLE: | ||
2741 | case BFA_FCPORT_SM_START: | ||
2742 | /* | ||
2743 | * Ignore event for a port that is dport | ||
2744 | */ | ||
2745 | break; | ||
2746 | |||
2747 | case BFA_FCPORT_SM_STOP: | ||
2748 | bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); | ||
2749 | break; | ||
2750 | |||
2751 | case BFA_FCPORT_SM_HWFAIL: | ||
2752 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); | ||
2753 | break; | ||
2754 | |||
2755 | case BFA_FCPORT_SM_DPORTDISABLE: | ||
2756 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); | ||
2757 | break; | ||
2758 | |||
2759 | default: | ||
2760 | bfa_sm_fault(fcport->bfa, event); | ||
2761 | } | ||
2762 | } | ||
2763 | |||
2764 | static void | ||
2765 | bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport, | ||
2766 | enum bfa_fcport_sm_event event) | ||
2767 | { | ||
2768 | bfa_trc(fcport->bfa, event); | ||
2769 | |||
2770 | switch (event) { | ||
2771 | case BFA_FCPORT_SM_DPORTENABLE: | ||
2772 | case BFA_FCPORT_SM_ENABLE: | ||
2773 | case BFA_FCPORT_SM_START: | ||
2774 | /* | ||
2775 | * Ignore event for a port as there is FAA misconfig | ||
2776 | */ | ||
2777 | break; | ||
2778 | |||
2779 | case BFA_FCPORT_SM_DISABLE: | ||
2780 | if (bfa_fcport_send_disable(fcport)) | ||
2781 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); | ||
2782 | else | ||
2783 | bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait); | ||
2784 | |||
2785 | bfa_fcport_reset_linkinfo(fcport); | ||
2786 | bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); | ||
2787 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, | ||
2788 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); | ||
2789 | bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); | ||
2790 | break; | ||
2791 | |||
2792 | case BFA_FCPORT_SM_STOP: | ||
2793 | bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); | ||
2794 | break; | ||
2795 | |||
2796 | case BFA_FCPORT_SM_HWFAIL: | ||
2797 | bfa_fcport_reset_linkinfo(fcport); | ||
2798 | bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); | ||
2799 | bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); | ||
2800 | break; | ||
2801 | |||
2802 | default: | ||
2803 | bfa_sm_fault(fcport->bfa, event); | ||
2804 | } | ||
2805 | } | ||
2806 | |||
2683 | /* | 2807 | /* |
2684 | * Link state is down | 2808 | * Link state is down |
2685 | */ | 2809 | */ |
@@ -2943,6 +3067,7 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
2943 | */ | 3067 | */ |
2944 | do_gettimeofday(&tv); | 3068 | do_gettimeofday(&tv); |
2945 | fcport->stats_reset_time = tv.tv_sec; | 3069 | fcport->stats_reset_time = tv.tv_sec; |
3070 | fcport->stats_dma_ready = BFA_FALSE; | ||
2946 | 3071 | ||
2947 | /* | 3072 | /* |
2948 | * initialize and set default configuration | 3073 | * initialize and set default configuration |
@@ -2953,6 +3078,9 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
2953 | port_cfg->maxfrsize = 0; | 3078 | port_cfg->maxfrsize = 0; |
2954 | 3079 | ||
2955 | port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS; | 3080 | port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS; |
3081 | port_cfg->qos_bw.high = BFA_QOS_BW_HIGH; | ||
3082 | port_cfg->qos_bw.med = BFA_QOS_BW_MED; | ||
3083 | port_cfg->qos_bw.low = BFA_QOS_BW_LOW; | ||
2956 | 3084 | ||
2957 | INIT_LIST_HEAD(&fcport->stats_pending_q); | 3085 | INIT_LIST_HEAD(&fcport->stats_pending_q); |
2958 | INIT_LIST_HEAD(&fcport->statsclr_pending_q); | 3086 | INIT_LIST_HEAD(&fcport->statsclr_pending_q); |
@@ -2996,6 +3124,21 @@ bfa_fcport_iocdisable(struct bfa_s *bfa) | |||
2996 | bfa_trunk_iocdisable(bfa); | 3124 | bfa_trunk_iocdisable(bfa); |
2997 | } | 3125 | } |
2998 | 3126 | ||
3127 | /* | ||
3128 | * Update loop info in fcport for SCN online | ||
3129 | */ | ||
3130 | static void | ||
3131 | bfa_fcport_update_loop_info(struct bfa_fcport_s *fcport, | ||
3132 | struct bfa_fcport_loop_info_s *loop_info) | ||
3133 | { | ||
3134 | fcport->myalpa = loop_info->myalpa; | ||
3135 | fcport->alpabm_valid = | ||
3136 | loop_info->alpabm_val; | ||
3137 | memcpy(fcport->alpabm.alpa_bm, | ||
3138 | loop_info->alpabm.alpa_bm, | ||
3139 | sizeof(struct fc_alpabm_s)); | ||
3140 | } | ||
3141 | |||
2999 | static void | 3142 | static void |
3000 | bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) | 3143 | bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) |
3001 | { | 3144 | { |
@@ -3005,12 +3148,15 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) | |||
3005 | fcport->speed = pevent->link_state.speed; | 3148 | fcport->speed = pevent->link_state.speed; |
3006 | fcport->topology = pevent->link_state.topology; | 3149 | fcport->topology = pevent->link_state.topology; |
3007 | 3150 | ||
3008 | if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) | 3151 | if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP) { |
3009 | fcport->myalpa = 0; | 3152 | bfa_fcport_update_loop_info(fcport, |
3153 | &pevent->link_state.attr.loop_info); | ||
3154 | return; | ||
3155 | } | ||
3010 | 3156 | ||
3011 | /* QoS Details */ | 3157 | /* QoS Details */ |
3012 | fcport->qos_attr = pevent->link_state.qos_attr; | 3158 | fcport->qos_attr = pevent->link_state.qos_attr; |
3013 | fcport->qos_vc_attr = pevent->link_state.vc_fcf.qos_vc_attr; | 3159 | fcport->qos_vc_attr = pevent->link_state.attr.vc_fcf.qos_vc_attr; |
3014 | 3160 | ||
3015 | /* | 3161 | /* |
3016 | * update trunk state if applicable | 3162 | * update trunk state if applicable |
@@ -3019,7 +3165,8 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) | |||
3019 | trunk->attr.state = BFA_TRUNK_DISABLED; | 3165 | trunk->attr.state = BFA_TRUNK_DISABLED; |
3020 | 3166 | ||
3021 | /* update FCoE specific */ | 3167 | /* update FCoE specific */ |
3022 | fcport->fcoe_vlan = be16_to_cpu(pevent->link_state.vc_fcf.fcf.vlan); | 3168 | fcport->fcoe_vlan = |
3169 | be16_to_cpu(pevent->link_state.attr.vc_fcf.fcf.vlan); | ||
3023 | 3170 | ||
3024 | bfa_trc(fcport->bfa, fcport->speed); | 3171 | bfa_trc(fcport->bfa, fcport->speed); |
3025 | bfa_trc(fcport->bfa, fcport->topology); | 3172 | bfa_trc(fcport->bfa, fcport->topology); |
@@ -3453,6 +3600,7 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) | |||
3453 | case BFI_FCPORT_I2H_ENABLE_RSP: | 3600 | case BFI_FCPORT_I2H_ENABLE_RSP: |
3454 | if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) { | 3601 | if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) { |
3455 | 3602 | ||
3603 | fcport->stats_dma_ready = BFA_TRUE; | ||
3456 | if (fcport->use_flash_cfg) { | 3604 | if (fcport->use_flash_cfg) { |
3457 | fcport->cfg = i2hmsg.penable_rsp->port_cfg; | 3605 | fcport->cfg = i2hmsg.penable_rsp->port_cfg; |
3458 | fcport->cfg.maxfrsize = | 3606 | fcport->cfg.maxfrsize = |
@@ -3468,6 +3616,8 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) | |||
3468 | else | 3616 | else |
3469 | fcport->trunk.attr.state = | 3617 | fcport->trunk.attr.state = |
3470 | BFA_TRUNK_DISABLED; | 3618 | BFA_TRUNK_DISABLED; |
3619 | fcport->qos_attr.qos_bw = | ||
3620 | i2hmsg.penable_rsp->port_cfg.qos_bw; | ||
3471 | fcport->use_flash_cfg = BFA_FALSE; | 3621 | fcport->use_flash_cfg = BFA_FALSE; |
3472 | } | 3622 | } |
3473 | 3623 | ||
@@ -3476,6 +3626,9 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) | |||
3476 | else | 3626 | else |
3477 | fcport->qos_attr.state = BFA_QOS_DISABLED; | 3627 | fcport->qos_attr.state = BFA_QOS_DISABLED; |
3478 | 3628 | ||
3629 | fcport->qos_attr.qos_bw_op = | ||
3630 | i2hmsg.penable_rsp->port_cfg.qos_bw; | ||
3631 | |||
3479 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); | 3632 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); |
3480 | } | 3633 | } |
3481 | break; | 3634 | break; |
@@ -3488,8 +3641,17 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) | |||
3488 | case BFI_FCPORT_I2H_EVENT: | 3641 | case BFI_FCPORT_I2H_EVENT: |
3489 | if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP) | 3642 | if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP) |
3490 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP); | 3643 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP); |
3491 | else | 3644 | else { |
3492 | bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN); | 3645 | if (i2hmsg.event->link_state.linkstate_rsn == |
3646 | BFA_PORT_LINKSTATE_RSN_FAA_MISCONFIG) | ||
3647 | bfa_sm_send_event(fcport, | ||
3648 | BFA_FCPORT_SM_FAA_MISCONFIG); | ||
3649 | else | ||
3650 | bfa_sm_send_event(fcport, | ||
3651 | BFA_FCPORT_SM_LINKDOWN); | ||
3652 | } | ||
3653 | fcport->qos_attr.qos_bw_op = | ||
3654 | i2hmsg.event->link_state.qos_attr.qos_bw_op; | ||
3493 | break; | 3655 | break; |
3494 | 3656 | ||
3495 | case BFI_FCPORT_I2H_TRUNK_SCN: | 3657 | case BFI_FCPORT_I2H_TRUNK_SCN: |
@@ -3609,6 +3771,9 @@ bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed) | |||
3609 | 3771 | ||
3610 | if (fcport->cfg.trunked == BFA_TRUE) | 3772 | if (fcport->cfg.trunked == BFA_TRUE) |
3611 | return BFA_STATUS_TRUNK_ENABLED; | 3773 | return BFA_STATUS_TRUNK_ENABLED; |
3774 | if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && | ||
3775 | (speed == BFA_PORT_SPEED_16GBPS)) | ||
3776 | return BFA_STATUS_UNSUPP_SPEED; | ||
3612 | if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) { | 3777 | if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) { |
3613 | bfa_trc(bfa, fcport->speed_sup); | 3778 | bfa_trc(bfa, fcport->speed_sup); |
3614 | return BFA_STATUS_UNSUPP_SPEED; | 3779 | return BFA_STATUS_UNSUPP_SPEED; |
@@ -3663,7 +3828,26 @@ bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology) | |||
3663 | 3828 | ||
3664 | switch (topology) { | 3829 | switch (topology) { |
3665 | case BFA_PORT_TOPOLOGY_P2P: | 3830 | case BFA_PORT_TOPOLOGY_P2P: |
3831 | break; | ||
3832 | |||
3666 | case BFA_PORT_TOPOLOGY_LOOP: | 3833 | case BFA_PORT_TOPOLOGY_LOOP: |
3834 | if ((bfa_fcport_is_qos_enabled(bfa) != BFA_FALSE) || | ||
3835 | (fcport->qos_attr.state != BFA_QOS_DISABLED)) | ||
3836 | return BFA_STATUS_ERROR_QOS_ENABLED; | ||
3837 | if (fcport->cfg.ratelimit != BFA_FALSE) | ||
3838 | return BFA_STATUS_ERROR_TRL_ENABLED; | ||
3839 | if ((bfa_fcport_is_trunk_enabled(bfa) != BFA_FALSE) || | ||
3840 | (fcport->trunk.attr.state != BFA_TRUNK_DISABLED)) | ||
3841 | return BFA_STATUS_ERROR_TRUNK_ENABLED; | ||
3842 | if ((bfa_fcport_get_speed(bfa) == BFA_PORT_SPEED_16GBPS) || | ||
3843 | (fcport->cfg.speed == BFA_PORT_SPEED_16GBPS)) | ||
3844 | return BFA_STATUS_UNSUPP_SPEED; | ||
3845 | if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) | ||
3846 | return BFA_STATUS_LOOP_UNSUPP_MEZZ; | ||
3847 | if (bfa_fcport_is_dport(bfa) != BFA_FALSE) | ||
3848 | return BFA_STATUS_DPORT_ERR; | ||
3849 | break; | ||
3850 | |||
3667 | case BFA_PORT_TOPOLOGY_AUTO: | 3851 | case BFA_PORT_TOPOLOGY_AUTO: |
3668 | break; | 3852 | break; |
3669 | 3853 | ||
@@ -3686,6 +3870,17 @@ bfa_fcport_get_topology(struct bfa_s *bfa) | |||
3686 | return fcport->topology; | 3870 | return fcport->topology; |
3687 | } | 3871 | } |
3688 | 3872 | ||
3873 | /** | ||
3874 | * Get config topology. | ||
3875 | */ | ||
3876 | enum bfa_port_topology | ||
3877 | bfa_fcport_get_cfg_topology(struct bfa_s *bfa) | ||
3878 | { | ||
3879 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | ||
3880 | |||
3881 | return fcport->cfg.topology; | ||
3882 | } | ||
3883 | |||
3689 | bfa_status_t | 3884 | bfa_status_t |
3690 | bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) | 3885 | bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) |
3691 | { | 3886 | { |
@@ -3761,9 +3956,11 @@ bfa_fcport_get_maxfrsize(struct bfa_s *bfa) | |||
3761 | u8 | 3956 | u8 |
3762 | bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) | 3957 | bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) |
3763 | { | 3958 | { |
3764 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | 3959 | if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP) |
3960 | return (BFA_FCPORT_MOD(bfa))->cfg.rx_bbcredit; | ||
3765 | 3961 | ||
3766 | return fcport->cfg.rx_bbcredit; | 3962 | else |
3963 | return 0; | ||
3767 | } | 3964 | } |
3768 | 3965 | ||
3769 | void | 3966 | void |
@@ -3850,8 +4047,9 @@ bfa_fcport_get_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb) | |||
3850 | { | 4047 | { |
3851 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | 4048 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
3852 | 4049 | ||
3853 | if (bfa_ioc_is_disabled(&bfa->ioc)) | 4050 | if (!bfa_iocfc_is_operational(bfa) || |
3854 | return BFA_STATUS_IOC_DISABLED; | 4051 | !fcport->stats_dma_ready) |
4052 | return BFA_STATUS_IOC_NON_OP; | ||
3855 | 4053 | ||
3856 | if (!list_empty(&fcport->statsclr_pending_q)) | 4054 | if (!list_empty(&fcport->statsclr_pending_q)) |
3857 | return BFA_STATUS_DEVBUSY; | 4055 | return BFA_STATUS_DEVBUSY; |
@@ -3876,6 +4074,10 @@ bfa_fcport_clear_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb) | |||
3876 | { | 4074 | { |
3877 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | 4075 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
3878 | 4076 | ||
4077 | if (!bfa_iocfc_is_operational(bfa) || | ||
4078 | !fcport->stats_dma_ready) | ||
4079 | return BFA_STATUS_IOC_NON_OP; | ||
4080 | |||
3879 | if (!list_empty(&fcport->stats_pending_q)) | 4081 | if (!list_empty(&fcport->stats_pending_q)) |
3880 | return BFA_STATUS_DEVBUSY; | 4082 | return BFA_STATUS_DEVBUSY; |
3881 | 4083 | ||
@@ -3905,6 +4107,40 @@ bfa_fcport_is_disabled(struct bfa_s *bfa) | |||
3905 | } | 4107 | } |
3906 | 4108 | ||
3907 | bfa_boolean_t | 4109 | bfa_boolean_t |
4110 | bfa_fcport_is_dport(struct bfa_s *bfa) | ||
4111 | { | ||
4112 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | ||
4113 | |||
4114 | return (bfa_sm_to_state(hal_port_sm_table, fcport->sm) == | ||
4115 | BFA_PORT_ST_DPORT); | ||
4116 | } | ||
4117 | |||
4118 | bfa_status_t | ||
4119 | bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw) | ||
4120 | { | ||
4121 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | ||
4122 | enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa); | ||
4123 | |||
4124 | bfa_trc(bfa, ioc_type); | ||
4125 | |||
4126 | if ((qos_bw->high == 0) || (qos_bw->med == 0) || (qos_bw->low == 0)) | ||
4127 | return BFA_STATUS_QOS_BW_INVALID; | ||
4128 | |||
4129 | if ((qos_bw->high + qos_bw->med + qos_bw->low) != 100) | ||
4130 | return BFA_STATUS_QOS_BW_INVALID; | ||
4131 | |||
4132 | if ((qos_bw->med > qos_bw->high) || (qos_bw->low > qos_bw->med) || | ||
4133 | (qos_bw->low > qos_bw->high)) | ||
4134 | return BFA_STATUS_QOS_BW_INVALID; | ||
4135 | |||
4136 | if ((ioc_type == BFA_IOC_TYPE_FC) && | ||
4137 | (fcport->cfg.topology != BFA_PORT_TOPOLOGY_LOOP)) | ||
4138 | fcport->cfg.qos_bw = *qos_bw; | ||
4139 | |||
4140 | return BFA_STATUS_OK; | ||
4141 | } | ||
4142 | |||
4143 | bfa_boolean_t | ||
3908 | bfa_fcport_is_ratelim(struct bfa_s *bfa) | 4144 | bfa_fcport_is_ratelim(struct bfa_s *bfa) |
3909 | { | 4145 | { |
3910 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); | 4146 | struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); |
@@ -3981,6 +4217,26 @@ bfa_fcport_is_trunk_enabled(struct bfa_s *bfa) | |||
3981 | return fcport->cfg.trunked; | 4217 | return fcport->cfg.trunked; |
3982 | } | 4218 | } |
3983 | 4219 | ||
4220 | void | ||
4221 | bfa_fcport_dportenable(struct bfa_s *bfa) | ||
4222 | { | ||
4223 | /* | ||
4224 | * Assume caller check for port is in disable state | ||
4225 | */ | ||
4226 | bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DPORTENABLE); | ||
4227 | bfa_port_set_dportenabled(&bfa->modules.port, BFA_TRUE); | ||
4228 | } | ||
4229 | |||
4230 | void | ||
4231 | bfa_fcport_dportdisable(struct bfa_s *bfa) | ||
4232 | { | ||
4233 | /* | ||
4234 | * Assume caller check for port is in disable state | ||
4235 | */ | ||
4236 | bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DPORTDISABLE); | ||
4237 | bfa_port_set_dportenabled(&bfa->modules.port, BFA_FALSE); | ||
4238 | } | ||
4239 | |||
3984 | /* | 4240 | /* |
3985 | * Rport State machine functions | 4241 | * Rport State machine functions |
3986 | */ | 4242 | */ |
@@ -4707,6 +4963,21 @@ bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m) | |||
4707 | bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN); | 4963 | bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN); |
4708 | break; | 4964 | break; |
4709 | 4965 | ||
4966 | case BFI_RPORT_I2H_LIP_SCN_ONLINE: | ||
4967 | bfa_fcport_update_loop_info(BFA_FCPORT_MOD(bfa), | ||
4968 | &msg.lip_scn->loop_info); | ||
4969 | bfa_cb_rport_scn_online(bfa); | ||
4970 | break; | ||
4971 | |||
4972 | case BFI_RPORT_I2H_LIP_SCN_OFFLINE: | ||
4973 | bfa_cb_rport_scn_offline(bfa); | ||
4974 | break; | ||
4975 | |||
4976 | case BFI_RPORT_I2H_NO_DEV: | ||
4977 | rp = BFA_RPORT_FROM_TAG(bfa, msg.lip_scn->bfa_handle); | ||
4978 | bfa_cb_rport_scn_no_dev(rp->rport_drv); | ||
4979 | break; | ||
4980 | |||
4710 | default: | 4981 | default: |
4711 | bfa_trc(bfa, m->mhdr.msg_id); | 4982 | bfa_trc(bfa, m->mhdr.msg_id); |
4712 | WARN_ON(1); | 4983 | WARN_ON(1); |
@@ -5348,6 +5619,37 @@ bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw) | |||
5348 | } | 5619 | } |
5349 | 5620 | ||
5350 | /* | 5621 | /* |
5622 | * Dport forward declaration | ||
5623 | */ | ||
5624 | |||
5625 | /* | ||
5626 | * BFA DPORT state machine events | ||
5627 | */ | ||
5628 | enum bfa_dport_sm_event { | ||
5629 | BFA_DPORT_SM_ENABLE = 1, /* dport enable event */ | ||
5630 | BFA_DPORT_SM_DISABLE = 2, /* dport disable event */ | ||
5631 | BFA_DPORT_SM_FWRSP = 3, /* fw enable/disable rsp */ | ||
5632 | BFA_DPORT_SM_QRESUME = 4, /* CQ space available */ | ||
5633 | BFA_DPORT_SM_HWFAIL = 5, /* IOC h/w failure */ | ||
5634 | }; | ||
5635 | |||
5636 | static void bfa_dport_sm_disabled(struct bfa_dport_s *dport, | ||
5637 | enum bfa_dport_sm_event event); | ||
5638 | static void bfa_dport_sm_enabling_qwait(struct bfa_dport_s *dport, | ||
5639 | enum bfa_dport_sm_event event); | ||
5640 | static void bfa_dport_sm_enabling(struct bfa_dport_s *dport, | ||
5641 | enum bfa_dport_sm_event event); | ||
5642 | static void bfa_dport_sm_enabled(struct bfa_dport_s *dport, | ||
5643 | enum bfa_dport_sm_event event); | ||
5644 | static void bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport, | ||
5645 | enum bfa_dport_sm_event event); | ||
5646 | static void bfa_dport_sm_disabling(struct bfa_dport_s *dport, | ||
5647 | enum bfa_dport_sm_event event); | ||
5648 | static void bfa_dport_qresume(void *cbarg); | ||
5649 | static void bfa_dport_req_comp(struct bfa_dport_s *dport, | ||
5650 | bfi_diag_dport_rsp_t *msg); | ||
5651 | |||
5652 | /* | ||
5351 | * BFA fcdiag module | 5653 | * BFA fcdiag module |
5352 | */ | 5654 | */ |
5353 | #define BFA_DIAG_QTEST_TOV 1000 /* msec */ | 5655 | #define BFA_DIAG_QTEST_TOV 1000 /* msec */ |
@@ -5377,15 +5679,24 @@ bfa_fcdiag_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, | |||
5377 | struct bfa_pcidev_s *pcidev) | 5679 | struct bfa_pcidev_s *pcidev) |
5378 | { | 5680 | { |
5379 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | 5681 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); |
5682 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
5683 | |||
5380 | fcdiag->bfa = bfa; | 5684 | fcdiag->bfa = bfa; |
5381 | fcdiag->trcmod = bfa->trcmod; | 5685 | fcdiag->trcmod = bfa->trcmod; |
5382 | /* The common DIAG attach bfa_diag_attach() will do all memory claim */ | 5686 | /* The common DIAG attach bfa_diag_attach() will do all memory claim */ |
5687 | dport->bfa = bfa; | ||
5688 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
5689 | bfa_reqq_winit(&dport->reqq_wait, bfa_dport_qresume, dport); | ||
5690 | dport->cbfn = NULL; | ||
5691 | dport->cbarg = NULL; | ||
5383 | } | 5692 | } |
5384 | 5693 | ||
5385 | static void | 5694 | static void |
5386 | bfa_fcdiag_iocdisable(struct bfa_s *bfa) | 5695 | bfa_fcdiag_iocdisable(struct bfa_s *bfa) |
5387 | { | 5696 | { |
5388 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | 5697 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); |
5698 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
5699 | |||
5389 | bfa_trc(fcdiag, fcdiag->lb.lock); | 5700 | bfa_trc(fcdiag, fcdiag->lb.lock); |
5390 | if (fcdiag->lb.lock) { | 5701 | if (fcdiag->lb.lock) { |
5391 | fcdiag->lb.status = BFA_STATUS_IOC_FAILURE; | 5702 | fcdiag->lb.status = BFA_STATUS_IOC_FAILURE; |
@@ -5393,6 +5704,8 @@ bfa_fcdiag_iocdisable(struct bfa_s *bfa) | |||
5393 | fcdiag->lb.lock = 0; | 5704 | fcdiag->lb.lock = 0; |
5394 | bfa_fcdiag_set_busy_status(fcdiag); | 5705 | bfa_fcdiag_set_busy_status(fcdiag); |
5395 | } | 5706 | } |
5707 | |||
5708 | bfa_sm_send_event(dport, BFA_DPORT_SM_HWFAIL); | ||
5396 | } | 5709 | } |
5397 | 5710 | ||
5398 | static void | 5711 | static void |
@@ -5577,6 +5890,9 @@ bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg) | |||
5577 | case BFI_DIAG_I2H_QTEST: | 5890 | case BFI_DIAG_I2H_QTEST: |
5578 | bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg); | 5891 | bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg); |
5579 | break; | 5892 | break; |
5893 | case BFI_DIAG_I2H_DPORT: | ||
5894 | bfa_dport_req_comp(&fcdiag->dport, (bfi_diag_dport_rsp_t *)msg); | ||
5895 | break; | ||
5580 | default: | 5896 | default: |
5581 | bfa_trc(fcdiag, msg->mhdr.msg_id); | 5897 | bfa_trc(fcdiag, msg->mhdr.msg_id); |
5582 | WARN_ON(1); | 5898 | WARN_ON(1); |
@@ -5646,12 +5962,18 @@ bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode, | |||
5646 | } | 5962 | } |
5647 | } | 5963 | } |
5648 | 5964 | ||
5965 | /* | ||
5966 | * For CT2, 1G is not supported | ||
5967 | */ | ||
5968 | if ((speed == BFA_PORT_SPEED_1GBPS) && | ||
5969 | (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) { | ||
5970 | bfa_trc(fcdiag, speed); | ||
5971 | return BFA_STATUS_UNSUPP_SPEED; | ||
5972 | } | ||
5973 | |||
5649 | /* For Mezz card, port speed entered needs to be checked */ | 5974 | /* For Mezz card, port speed entered needs to be checked */ |
5650 | if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) { | 5975 | if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) { |
5651 | if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) { | 5976 | if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) { |
5652 | if ((speed == BFA_PORT_SPEED_1GBPS) && | ||
5653 | (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) | ||
5654 | return BFA_STATUS_UNSUPP_SPEED; | ||
5655 | if (!(speed == BFA_PORT_SPEED_1GBPS || | 5977 | if (!(speed == BFA_PORT_SPEED_1GBPS || |
5656 | speed == BFA_PORT_SPEED_2GBPS || | 5978 | speed == BFA_PORT_SPEED_2GBPS || |
5657 | speed == BFA_PORT_SPEED_4GBPS || | 5979 | speed == BFA_PORT_SPEED_4GBPS || |
@@ -5764,3 +6086,379 @@ bfa_fcdiag_lb_is_running(struct bfa_s *bfa) | |||
5764 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | 6086 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); |
5765 | return fcdiag->lb.lock ? BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK; | 6087 | return fcdiag->lb.lock ? BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK; |
5766 | } | 6088 | } |
6089 | |||
6090 | /* | ||
6091 | * D-port | ||
6092 | */ | ||
6093 | static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport, | ||
6094 | enum bfi_dport_req req); | ||
6095 | static void | ||
6096 | bfa_cb_fcdiag_dport(struct bfa_dport_s *dport, bfa_status_t bfa_status) | ||
6097 | { | ||
6098 | if (dport->cbfn != NULL) { | ||
6099 | dport->cbfn(dport->cbarg, bfa_status); | ||
6100 | dport->cbfn = NULL; | ||
6101 | dport->cbarg = NULL; | ||
6102 | } | ||
6103 | } | ||
6104 | |||
6105 | static void | ||
6106 | bfa_dport_sm_disabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) | ||
6107 | { | ||
6108 | bfa_trc(dport->bfa, event); | ||
6109 | |||
6110 | switch (event) { | ||
6111 | case BFA_DPORT_SM_ENABLE: | ||
6112 | bfa_fcport_dportenable(dport->bfa); | ||
6113 | if (bfa_dport_send_req(dport, BFI_DPORT_ENABLE)) | ||
6114 | bfa_sm_set_state(dport, bfa_dport_sm_enabling); | ||
6115 | else | ||
6116 | bfa_sm_set_state(dport, bfa_dport_sm_enabling_qwait); | ||
6117 | break; | ||
6118 | |||
6119 | case BFA_DPORT_SM_DISABLE: | ||
6120 | /* Already disabled */ | ||
6121 | break; | ||
6122 | |||
6123 | case BFA_DPORT_SM_HWFAIL: | ||
6124 | /* ignore */ | ||
6125 | break; | ||
6126 | |||
6127 | default: | ||
6128 | bfa_sm_fault(dport->bfa, event); | ||
6129 | } | ||
6130 | } | ||
6131 | |||
6132 | static void | ||
6133 | bfa_dport_sm_enabling_qwait(struct bfa_dport_s *dport, | ||
6134 | enum bfa_dport_sm_event event) | ||
6135 | { | ||
6136 | bfa_trc(dport->bfa, event); | ||
6137 | |||
6138 | switch (event) { | ||
6139 | case BFA_DPORT_SM_QRESUME: | ||
6140 | bfa_sm_set_state(dport, bfa_dport_sm_enabling); | ||
6141 | bfa_dport_send_req(dport, BFI_DPORT_ENABLE); | ||
6142 | break; | ||
6143 | |||
6144 | case BFA_DPORT_SM_HWFAIL: | ||
6145 | bfa_reqq_wcancel(&dport->reqq_wait); | ||
6146 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
6147 | bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); | ||
6148 | break; | ||
6149 | |||
6150 | default: | ||
6151 | bfa_sm_fault(dport->bfa, event); | ||
6152 | } | ||
6153 | } | ||
6154 | |||
6155 | static void | ||
6156 | bfa_dport_sm_enabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) | ||
6157 | { | ||
6158 | bfa_trc(dport->bfa, event); | ||
6159 | |||
6160 | switch (event) { | ||
6161 | case BFA_DPORT_SM_FWRSP: | ||
6162 | bfa_sm_set_state(dport, bfa_dport_sm_enabled); | ||
6163 | break; | ||
6164 | |||
6165 | case BFA_DPORT_SM_HWFAIL: | ||
6166 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
6167 | bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); | ||
6168 | break; | ||
6169 | |||
6170 | default: | ||
6171 | bfa_sm_fault(dport->bfa, event); | ||
6172 | } | ||
6173 | } | ||
6174 | |||
6175 | static void | ||
6176 | bfa_dport_sm_enabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) | ||
6177 | { | ||
6178 | bfa_trc(dport->bfa, event); | ||
6179 | |||
6180 | switch (event) { | ||
6181 | case BFA_DPORT_SM_ENABLE: | ||
6182 | /* Already enabled */ | ||
6183 | break; | ||
6184 | |||
6185 | case BFA_DPORT_SM_DISABLE: | ||
6186 | bfa_fcport_dportdisable(dport->bfa); | ||
6187 | if (bfa_dport_send_req(dport, BFI_DPORT_DISABLE)) | ||
6188 | bfa_sm_set_state(dport, bfa_dport_sm_disabling); | ||
6189 | else | ||
6190 | bfa_sm_set_state(dport, bfa_dport_sm_disabling_qwait); | ||
6191 | break; | ||
6192 | |||
6193 | case BFA_DPORT_SM_HWFAIL: | ||
6194 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
6195 | break; | ||
6196 | |||
6197 | default: | ||
6198 | bfa_sm_fault(dport->bfa, event); | ||
6199 | } | ||
6200 | } | ||
6201 | |||
6202 | static void | ||
6203 | bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport, | ||
6204 | enum bfa_dport_sm_event event) | ||
6205 | { | ||
6206 | bfa_trc(dport->bfa, event); | ||
6207 | |||
6208 | switch (event) { | ||
6209 | case BFA_DPORT_SM_QRESUME: | ||
6210 | bfa_sm_set_state(dport, bfa_dport_sm_disabling); | ||
6211 | bfa_dport_send_req(dport, BFI_DPORT_DISABLE); | ||
6212 | break; | ||
6213 | |||
6214 | case BFA_DPORT_SM_HWFAIL: | ||
6215 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
6216 | bfa_reqq_wcancel(&dport->reqq_wait); | ||
6217 | bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); | ||
6218 | break; | ||
6219 | |||
6220 | default: | ||
6221 | bfa_sm_fault(dport->bfa, event); | ||
6222 | } | ||
6223 | } | ||
6224 | |||
6225 | static void | ||
6226 | bfa_dport_sm_disabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) | ||
6227 | { | ||
6228 | bfa_trc(dport->bfa, event); | ||
6229 | |||
6230 | switch (event) { | ||
6231 | case BFA_DPORT_SM_FWRSP: | ||
6232 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
6233 | break; | ||
6234 | |||
6235 | case BFA_DPORT_SM_HWFAIL: | ||
6236 | bfa_sm_set_state(dport, bfa_dport_sm_disabled); | ||
6237 | bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); | ||
6238 | break; | ||
6239 | |||
6240 | default: | ||
6241 | bfa_sm_fault(dport->bfa, event); | ||
6242 | } | ||
6243 | } | ||
6244 | |||
6245 | |||
6246 | static bfa_boolean_t | ||
6247 | bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req) | ||
6248 | { | ||
6249 | struct bfi_diag_dport_req_s *m; | ||
6250 | |||
6251 | /* | ||
6252 | * Increment message tag before queue check, so that responses to old | ||
6253 | * requests are discarded. | ||
6254 | */ | ||
6255 | dport->msgtag++; | ||
6256 | |||
6257 | /* | ||
6258 | * check for room in queue to send request now | ||
6259 | */ | ||
6260 | m = bfa_reqq_next(dport->bfa, BFA_REQQ_DIAG); | ||
6261 | if (!m) { | ||
6262 | bfa_reqq_wait(dport->bfa, BFA_REQQ_PORT, &dport->reqq_wait); | ||
6263 | return BFA_FALSE; | ||
6264 | } | ||
6265 | |||
6266 | bfi_h2i_set(m->mh, BFI_MC_DIAG, BFI_DIAG_H2I_DPORT, | ||
6267 | bfa_fn_lpu(dport->bfa)); | ||
6268 | m->req = req; | ||
6269 | m->msgtag = dport->msgtag; | ||
6270 | |||
6271 | /* | ||
6272 | * queue I/O message to firmware | ||
6273 | */ | ||
6274 | bfa_reqq_produce(dport->bfa, BFA_REQQ_DIAG, m->mh); | ||
6275 | |||
6276 | return BFA_TRUE; | ||
6277 | } | ||
6278 | |||
6279 | static void | ||
6280 | bfa_dport_qresume(void *cbarg) | ||
6281 | { | ||
6282 | struct bfa_dport_s *dport = cbarg; | ||
6283 | |||
6284 | bfa_sm_send_event(dport, BFA_DPORT_SM_QRESUME); | ||
6285 | } | ||
6286 | |||
6287 | static void | ||
6288 | bfa_dport_req_comp(struct bfa_dport_s *dport, bfi_diag_dport_rsp_t *msg) | ||
6289 | { | ||
6290 | bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP); | ||
6291 | bfa_cb_fcdiag_dport(dport, msg->status); | ||
6292 | } | ||
6293 | |||
6294 | /* | ||
6295 | * Dport enable | ||
6296 | * | ||
6297 | * @param[in] *bfa - bfa data struct | ||
6298 | */ | ||
6299 | bfa_status_t | ||
6300 | bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) | ||
6301 | { | ||
6302 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
6303 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
6304 | |||
6305 | /* | ||
6306 | * Dport is not support in MEZZ card | ||
6307 | */ | ||
6308 | if (bfa_mfg_is_mezz(dport->bfa->ioc.attr->card_type)) { | ||
6309 | bfa_trc(dport->bfa, BFA_STATUS_PBC); | ||
6310 | return BFA_STATUS_CMD_NOTSUPP_MEZZ; | ||
6311 | } | ||
6312 | |||
6313 | /* | ||
6314 | * Check to see if IOC is down | ||
6315 | */ | ||
6316 | if (!bfa_iocfc_is_operational(bfa)) | ||
6317 | return BFA_STATUS_IOC_NON_OP; | ||
6318 | |||
6319 | /* if port is PBC disabled, return error */ | ||
6320 | if (bfa_fcport_is_pbcdisabled(bfa)) { | ||
6321 | bfa_trc(dport->bfa, BFA_STATUS_PBC); | ||
6322 | return BFA_STATUS_PBC; | ||
6323 | } | ||
6324 | |||
6325 | /* | ||
6326 | * Check if port mode is FC port | ||
6327 | */ | ||
6328 | if (bfa_ioc_get_type(&bfa->ioc) != BFA_IOC_TYPE_FC) { | ||
6329 | bfa_trc(dport->bfa, bfa_ioc_get_type(&bfa->ioc)); | ||
6330 | return BFA_STATUS_CMD_NOTSUPP_CNA; | ||
6331 | } | ||
6332 | |||
6333 | /* | ||
6334 | * Check if port is in LOOP mode | ||
6335 | */ | ||
6336 | if ((bfa_fcport_get_cfg_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) || | ||
6337 | (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)) { | ||
6338 | bfa_trc(dport->bfa, 0); | ||
6339 | return BFA_STATUS_TOPOLOGY_LOOP; | ||
6340 | } | ||
6341 | |||
6342 | /* | ||
6343 | * Check if port is TRUNK mode | ||
6344 | */ | ||
6345 | if (bfa_fcport_is_trunk_enabled(bfa)) { | ||
6346 | bfa_trc(dport->bfa, 0); | ||
6347 | return BFA_STATUS_ERROR_TRUNK_ENABLED; | ||
6348 | } | ||
6349 | |||
6350 | /* | ||
6351 | * Check to see if port is disable or in dport state | ||
6352 | */ | ||
6353 | if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && | ||
6354 | (bfa_fcport_is_dport(bfa) == BFA_FALSE)) { | ||
6355 | bfa_trc(dport->bfa, 0); | ||
6356 | return BFA_STATUS_PORT_NOT_DISABLED; | ||
6357 | } | ||
6358 | |||
6359 | /* | ||
6360 | * Check if dport is busy | ||
6361 | */ | ||
6362 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || | ||
6363 | bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) || | ||
6364 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || | ||
6365 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) { | ||
6366 | return BFA_STATUS_DEVBUSY; | ||
6367 | } | ||
6368 | |||
6369 | /* | ||
6370 | * Check if dport is already enabled | ||
6371 | */ | ||
6372 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) { | ||
6373 | bfa_trc(dport->bfa, 0); | ||
6374 | return BFA_STATUS_DPORT_ENABLED; | ||
6375 | } | ||
6376 | |||
6377 | dport->cbfn = cbfn; | ||
6378 | dport->cbarg = cbarg; | ||
6379 | |||
6380 | bfa_sm_send_event(dport, BFA_DPORT_SM_ENABLE); | ||
6381 | return BFA_STATUS_OK; | ||
6382 | } | ||
6383 | |||
6384 | /* | ||
6385 | * Dport disable | ||
6386 | * | ||
6387 | * @param[in] *bfa - bfa data struct | ||
6388 | */ | ||
6389 | bfa_status_t | ||
6390 | bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) | ||
6391 | { | ||
6392 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
6393 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
6394 | |||
6395 | if (bfa_ioc_is_disabled(&bfa->ioc)) | ||
6396 | return BFA_STATUS_IOC_DISABLED; | ||
6397 | |||
6398 | /* if port is PBC disabled, return error */ | ||
6399 | if (bfa_fcport_is_pbcdisabled(bfa)) { | ||
6400 | bfa_trc(dport->bfa, BFA_STATUS_PBC); | ||
6401 | return BFA_STATUS_PBC; | ||
6402 | } | ||
6403 | |||
6404 | /* | ||
6405 | * Check to see if port is disable or in dport state | ||
6406 | */ | ||
6407 | if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && | ||
6408 | (bfa_fcport_is_dport(bfa) == BFA_FALSE)) { | ||
6409 | bfa_trc(dport->bfa, 0); | ||
6410 | return BFA_STATUS_PORT_NOT_DISABLED; | ||
6411 | } | ||
6412 | |||
6413 | /* | ||
6414 | * Check if dport is busy | ||
6415 | */ | ||
6416 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || | ||
6417 | bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) || | ||
6418 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || | ||
6419 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) | ||
6420 | return BFA_STATUS_DEVBUSY; | ||
6421 | |||
6422 | /* | ||
6423 | * Check if dport is already disabled | ||
6424 | */ | ||
6425 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled)) { | ||
6426 | bfa_trc(dport->bfa, 0); | ||
6427 | return BFA_STATUS_DPORT_DISABLED; | ||
6428 | } | ||
6429 | |||
6430 | dport->cbfn = cbfn; | ||
6431 | dport->cbarg = cbarg; | ||
6432 | |||
6433 | bfa_sm_send_event(dport, BFA_DPORT_SM_DISABLE); | ||
6434 | return BFA_STATUS_OK; | ||
6435 | } | ||
6436 | |||
6437 | /* | ||
6438 | * Get D-port state | ||
6439 | * | ||
6440 | * @param[in] *bfa - bfa data struct | ||
6441 | */ | ||
6442 | |||
6443 | bfa_status_t | ||
6444 | bfa_dport_get_state(struct bfa_s *bfa, enum bfa_dport_state *state) | ||
6445 | { | ||
6446 | struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); | ||
6447 | struct bfa_dport_s *dport = &fcdiag->dport; | ||
6448 | |||
6449 | if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) | ||
6450 | *state = BFA_DPORT_ST_ENABLED; | ||
6451 | else if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || | ||
6452 | bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait)) | ||
6453 | *state = BFA_DPORT_ST_ENABLING; | ||
6454 | else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled)) | ||
6455 | *state = BFA_DPORT_ST_DISABLED; | ||
6456 | else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || | ||
6457 | bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) | ||
6458 | *state = BFA_DPORT_ST_DISABLING; | ||
6459 | else { | ||
6460 | bfa_trc(dport->bfa, BFA_STATUS_EINVAL); | ||
6461 | return BFA_STATUS_EINVAL; | ||
6462 | } | ||
6463 | return BFA_STATUS_OK; | ||
6464 | } | ||