aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa/bfa_svc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-12 21:57:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-12 21:57:01 -0400
commit6a5a3d6a4adde0c66f3be29bbd7c0d6ffb7e1a40 (patch)
treeae416ffa4458df755f984a05d65ee1c3e220c40b /drivers/scsi/bfa/bfa_svc.c
parent8bbbfa70549bd84f29ff331d0ac051897ccbbd72 (diff)
parent5c1b10ab7f93d24f29b5630286e323d1c5802d5c (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.c732
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);
198static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, 201static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
199 enum bfa_fcport_sm_event event); 202 enum bfa_fcport_sm_event event);
203static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport,
204 enum bfa_fcport_sm_event event);
205static void bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport,
206 enum bfa_fcport_sm_event event);
200 207
201static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, 208static 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
2732static void
2733bfa_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
2764static void
2765bfa_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 */
3130static void
3131bfa_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
2999static void 3142static void
3000bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) 3143bfa_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 */
3876enum bfa_port_topology
3877bfa_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
3689bfa_status_t 3884bfa_status_t
3690bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) 3885bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
3691{ 3886{
@@ -3761,9 +3956,11 @@ bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
3761u8 3956u8
3762bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) 3957bfa_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
3769void 3966void
@@ -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
3907bfa_boolean_t 4109bfa_boolean_t
4110bfa_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
4118bfa_status_t
4119bfa_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
4143bfa_boolean_t
3908bfa_fcport_is_ratelim(struct bfa_s *bfa) 4144bfa_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
4220void
4221bfa_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
4230void
4231bfa_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 */
5628enum 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
5636static void bfa_dport_sm_disabled(struct bfa_dport_s *dport,
5637 enum bfa_dport_sm_event event);
5638static void bfa_dport_sm_enabling_qwait(struct bfa_dport_s *dport,
5639 enum bfa_dport_sm_event event);
5640static void bfa_dport_sm_enabling(struct bfa_dport_s *dport,
5641 enum bfa_dport_sm_event event);
5642static void bfa_dport_sm_enabled(struct bfa_dport_s *dport,
5643 enum bfa_dport_sm_event event);
5644static void bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport,
5645 enum bfa_dport_sm_event event);
5646static void bfa_dport_sm_disabling(struct bfa_dport_s *dport,
5647 enum bfa_dport_sm_event event);
5648static void bfa_dport_qresume(void *cbarg);
5649static 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
5385static void 5694static void
5386bfa_fcdiag_iocdisable(struct bfa_s *bfa) 5695bfa_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
5398static void 5711static 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 */
6093static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport,
6094 enum bfi_dport_req req);
6095static void
6096bfa_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
6105static void
6106bfa_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
6132static void
6133bfa_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
6155static void
6156bfa_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
6175static void
6176bfa_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
6202static void
6203bfa_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
6225static void
6226bfa_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
6246static bfa_boolean_t
6247bfa_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
6279static void
6280bfa_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
6287static void
6288bfa_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 */
6299bfa_status_t
6300bfa_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 */
6389bfa_status_t
6390bfa_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
6443bfa_status_t
6444bfa_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}