aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa/bfa_svc.c
diff options
context:
space:
mode:
authorVijaya Mohan Guvva <vmohan@brocade.com>2013-05-13 05:33:21 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-06-26 14:44:20 -0400
commit1a898a794d5913c899a329c5dec39d28e6065672 (patch)
treebf5ec13403df005157a3ac053dcf82c8044cd1b7 /drivers/scsi/bfa/bfa_svc.c
parent4e1e0d8d71810fb5e4c294299ab35c30a746353d (diff)
[SCSI] bfa: Add dynamic diagnostic port support
D-Port is a new port type created with the intention of running link level diagnostic tests like loopback, traffic test. In static D-port mode, user configures the port to D-port mode and starts the test, but in dynamic D-port, once the Brocade switch port is configured to D-port, it will reject the regular FLOGI from HBA with reason that it is in D-port mode. So based on the reason code HBA port will turn itself into D-port and start diagnostic test. Signed-off-by: Sudarsana Reddy Kalluru <skalluru@brocade.com> Signed-off-by: Vijaya Mohan Guvva <vmohan@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfa_svc.c')
-rw-r--r--drivers/scsi/bfa/bfa_svc.c595
1 files changed, 555 insertions, 40 deletions
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c
index 1baa9b348c59..6c41e57fd752 100644
--- a/drivers/scsi/bfa/bfa_svc.c
+++ b/drivers/scsi/bfa/bfa_svc.c
@@ -70,6 +70,8 @@ enum bfa_fcport_sm_event {
70 BFA_FCPORT_SM_DPORTENABLE = 10, /* enable dport */ 70 BFA_FCPORT_SM_DPORTENABLE = 10, /* enable dport */
71 BFA_FCPORT_SM_DPORTDISABLE = 11,/* disable dport */ 71 BFA_FCPORT_SM_DPORTDISABLE = 11,/* disable dport */
72 BFA_FCPORT_SM_FAA_MISCONFIG = 12, /* FAA misconfiguratin */ 72 BFA_FCPORT_SM_FAA_MISCONFIG = 12, /* FAA misconfiguratin */
73 BFA_FCPORT_SM_DDPORTENABLE = 13, /* enable ddport */
74 BFA_FCPORT_SM_DDPORTDISABLE = 14, /* disable ddport */
73}; 75};
74 76
75/* 77/*
@@ -202,6 +204,8 @@ static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
202 enum bfa_fcport_sm_event event); 204 enum bfa_fcport_sm_event event);
203static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, 205static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport,
204 enum bfa_fcport_sm_event event); 206 enum bfa_fcport_sm_event event);
207static void bfa_fcport_sm_ddport(struct bfa_fcport_s *fcport,
208 enum bfa_fcport_sm_event event);
205static void bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport, 209static void bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport,
206 enum bfa_fcport_sm_event event); 210 enum bfa_fcport_sm_event event);
207 211
@@ -234,6 +238,7 @@ static struct bfa_sm_table_s hal_port_sm_table[] = {
234 {BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN}, 238 {BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN},
235 {BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN}, 239 {BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN},
236 {BFA_SM(bfa_fcport_sm_dport), BFA_PORT_ST_DPORT}, 240 {BFA_SM(bfa_fcport_sm_dport), BFA_PORT_ST_DPORT},
241 {BFA_SM(bfa_fcport_sm_ddport), BFA_PORT_ST_DDPORT},
237 {BFA_SM(bfa_fcport_sm_faa_misconfig), BFA_PORT_ST_FAA_MISCONFIG}, 242 {BFA_SM(bfa_fcport_sm_faa_misconfig), BFA_PORT_ST_FAA_MISCONFIG},
238}; 243};
239 244
@@ -2646,6 +2651,10 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
2646 bfa_sm_set_state(fcport, bfa_fcport_sm_dport); 2651 bfa_sm_set_state(fcport, bfa_fcport_sm_dport);
2647 break; 2652 break;
2648 2653
2654 case BFA_FCPORT_SM_DDPORTENABLE:
2655 bfa_sm_set_state(fcport, bfa_fcport_sm_ddport);
2656 break;
2657
2649 default: 2658 default:
2650 bfa_sm_fault(fcport->bfa, event); 2659 bfa_sm_fault(fcport->bfa, event);
2651 } 2660 }
@@ -2759,6 +2768,40 @@ bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event)
2759} 2768}
2760 2769
2761static void 2770static void
2771bfa_fcport_sm_ddport(struct bfa_fcport_s *fcport,
2772 enum bfa_fcport_sm_event event)
2773{
2774 bfa_trc(fcport->bfa, event);
2775
2776 switch (event) {
2777 case BFA_FCPORT_SM_DISABLE:
2778 case BFA_FCPORT_SM_DDPORTDISABLE:
2779 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
2780 break;
2781
2782 case BFA_FCPORT_SM_DPORTENABLE:
2783 case BFA_FCPORT_SM_DPORTDISABLE:
2784 case BFA_FCPORT_SM_ENABLE:
2785 case BFA_FCPORT_SM_START:
2786 /**
2787 * Ignore event for a port that is ddport
2788 */
2789 break;
2790
2791 case BFA_FCPORT_SM_STOP:
2792 bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2793 break;
2794
2795 case BFA_FCPORT_SM_HWFAIL:
2796 bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
2797 break;
2798
2799 default:
2800 bfa_sm_fault(fcport->bfa, event);
2801 }
2802}
2803
2804static void
2762bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport, 2805bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport,
2763 enum bfa_fcport_sm_event event) 2806 enum bfa_fcport_sm_event event)
2764{ 2807{
@@ -3860,6 +3903,8 @@ bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology)
3860 return BFA_STATUS_LOOP_UNSUPP_MEZZ; 3903 return BFA_STATUS_LOOP_UNSUPP_MEZZ;
3861 if (bfa_fcport_is_dport(bfa) != BFA_FALSE) 3904 if (bfa_fcport_is_dport(bfa) != BFA_FALSE)
3862 return BFA_STATUS_DPORT_ERR; 3905 return BFA_STATUS_DPORT_ERR;
3906 if (bfa_fcport_is_ddport(bfa) != BFA_FALSE)
3907 return BFA_STATUS_DPORT_ERR;
3863 break; 3908 break;
3864 3909
3865 case BFA_PORT_TOPOLOGY_AUTO: 3910 case BFA_PORT_TOPOLOGY_AUTO:
@@ -4127,6 +4172,15 @@ bfa_fcport_is_dport(struct bfa_s *bfa)
4127 BFA_PORT_ST_DPORT); 4172 BFA_PORT_ST_DPORT);
4128} 4173}
4129 4174
4175bfa_boolean_t
4176bfa_fcport_is_ddport(struct bfa_s *bfa)
4177{
4178 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
4179
4180 return (bfa_sm_to_state(hal_port_sm_table, fcport->sm) ==
4181 BFA_PORT_ST_DDPORT);
4182}
4183
4130bfa_status_t 4184bfa_status_t
4131bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw) 4185bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw)
4132{ 4186{
@@ -4320,6 +4374,24 @@ bfa_fcport_dportdisable(struct bfa_s *bfa)
4320 bfa_port_set_dportenabled(&bfa->modules.port, BFA_FALSE); 4374 bfa_port_set_dportenabled(&bfa->modules.port, BFA_FALSE);
4321} 4375}
4322 4376
4377void
4378bfa_fcport_ddportenable(struct bfa_s *bfa)
4379{
4380 /*
4381 * Assume caller check for port is in disable state
4382 */
4383 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DDPORTENABLE);
4384}
4385
4386void
4387bfa_fcport_ddportdisable(struct bfa_s *bfa)
4388{
4389 /*
4390 * Assume caller check for port is in disable state
4391 */
4392 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DDPORTDISABLE);
4393}
4394
4323/* 4395/*
4324 * Rport State machine functions 4396 * Rport State machine functions
4325 */ 4397 */
@@ -5705,6 +5777,14 @@ bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw)
5705 * Dport forward declaration 5777 * Dport forward declaration
5706 */ 5778 */
5707 5779
5780enum bfa_dport_test_state_e {
5781 BFA_DPORT_ST_DISABLED = 0, /*!< dport is disabled */
5782 BFA_DPORT_ST_INP = 1, /*!< test in progress */
5783 BFA_DPORT_ST_COMP = 2, /*!< test complete successfully */
5784 BFA_DPORT_ST_NO_SFP = 3, /*!< sfp is not present */
5785 BFA_DPORT_ST_NOTSTART = 4, /*!< test not start dport is enabled */
5786};
5787
5708/* 5788/*
5709 * BFA DPORT state machine events 5789 * BFA DPORT state machine events
5710 */ 5790 */
@@ -5714,6 +5794,9 @@ enum bfa_dport_sm_event {
5714 BFA_DPORT_SM_FWRSP = 3, /* fw enable/disable rsp */ 5794 BFA_DPORT_SM_FWRSP = 3, /* fw enable/disable rsp */
5715 BFA_DPORT_SM_QRESUME = 4, /* CQ space available */ 5795 BFA_DPORT_SM_QRESUME = 4, /* CQ space available */
5716 BFA_DPORT_SM_HWFAIL = 5, /* IOC h/w failure */ 5796 BFA_DPORT_SM_HWFAIL = 5, /* IOC h/w failure */
5797 BFA_DPORT_SM_START = 6, /* re-start dport test */
5798 BFA_DPORT_SM_REQFAIL = 7, /* request failure */
5799 BFA_DPORT_SM_SCN = 8, /* state change notify frm fw */
5717}; 5800};
5718 5801
5719static void bfa_dport_sm_disabled(struct bfa_dport_s *dport, 5802static void bfa_dport_sm_disabled(struct bfa_dport_s *dport,
@@ -5728,9 +5811,19 @@ static void bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport,
5728 enum bfa_dport_sm_event event); 5811 enum bfa_dport_sm_event event);
5729static void bfa_dport_sm_disabling(struct bfa_dport_s *dport, 5812static void bfa_dport_sm_disabling(struct bfa_dport_s *dport,
5730 enum bfa_dport_sm_event event); 5813 enum bfa_dport_sm_event event);
5814static void bfa_dport_sm_starting_qwait(struct bfa_dport_s *dport,
5815 enum bfa_dport_sm_event event);
5816static void bfa_dport_sm_starting(struct bfa_dport_s *dport,
5817 enum bfa_dport_sm_event event);
5818static void bfa_dport_sm_dynamic_disabling(struct bfa_dport_s *dport,
5819 enum bfa_dport_sm_event event);
5820static void bfa_dport_sm_dynamic_disabling_qwait(struct bfa_dport_s *dport,
5821 enum bfa_dport_sm_event event);
5731static void bfa_dport_qresume(void *cbarg); 5822static void bfa_dport_qresume(void *cbarg);
5732static void bfa_dport_req_comp(struct bfa_dport_s *dport, 5823static void bfa_dport_req_comp(struct bfa_dport_s *dport,
5733 bfi_diag_dport_rsp_t *msg); 5824 struct bfi_diag_dport_rsp_s *msg);
5825static void bfa_dport_scn(struct bfa_dport_s *dport,
5826 struct bfi_diag_dport_scn_s *msg);
5734 5827
5735/* 5828/*
5736 * BFA fcdiag module 5829 * BFA fcdiag module
@@ -5772,6 +5865,8 @@ bfa_fcdiag_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
5772 bfa_reqq_winit(&dport->reqq_wait, bfa_dport_qresume, dport); 5865 bfa_reqq_winit(&dport->reqq_wait, bfa_dport_qresume, dport);
5773 dport->cbfn = NULL; 5866 dport->cbfn = NULL;
5774 dport->cbarg = NULL; 5867 dport->cbarg = NULL;
5868 dport->test_state = BFA_DPORT_ST_DISABLED;
5869 memset(&dport->result, 0, sizeof(struct bfa_diag_dport_result_s));
5775} 5870}
5776 5871
5777static void 5872static void
@@ -5974,7 +6069,12 @@ bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg)
5974 bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg); 6069 bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg);
5975 break; 6070 break;
5976 case BFI_DIAG_I2H_DPORT: 6071 case BFI_DIAG_I2H_DPORT:
5977 bfa_dport_req_comp(&fcdiag->dport, (bfi_diag_dport_rsp_t *)msg); 6072 bfa_dport_req_comp(&fcdiag->dport,
6073 (struct bfi_diag_dport_rsp_s *)msg);
6074 break;
6075 case BFI_DIAG_I2H_DPORT_SCN:
6076 bfa_dport_scn(&fcdiag->dport,
6077 (struct bfi_diag_dport_scn_s *)msg);
5978 break; 6078 break;
5979 default: 6079 default:
5980 bfa_trc(fcdiag, msg->mhdr.msg_id); 6080 bfa_trc(fcdiag, msg->mhdr.msg_id);
@@ -6069,7 +6169,11 @@ bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode,
6069 return BFA_STATUS_UNSUPP_SPEED; 6169 return BFA_STATUS_UNSUPP_SPEED;
6070 } 6170 }
6071 } 6171 }
6072 6172 /* check to see if fcport is dport */
6173 if (bfa_fcport_is_dport(bfa)) {
6174 bfa_trc(fcdiag, fcdiag->lb.lock);
6175 return BFA_STATUS_DPORT_ENABLED;
6176 }
6073 /* check to see if there is another destructive diag cmd running */ 6177 /* check to see if there is another destructive diag cmd running */
6074 if (fcdiag->lb.lock) { 6178 if (fcdiag->lb.lock) {
6075 bfa_trc(fcdiag, fcdiag->lb.lock); 6179 bfa_trc(fcdiag, fcdiag->lb.lock);
@@ -6173,6 +6277,15 @@ bfa_fcdiag_lb_is_running(struct bfa_s *bfa)
6173/* 6277/*
6174 * D-port 6278 * D-port
6175 */ 6279 */
6280#define bfa_dport_result_start(__dport, __mode) do { \
6281 (__dport)->result.start_time = bfa_get_log_time(); \
6282 (__dport)->result.status = DPORT_TEST_ST_INPRG; \
6283 (__dport)->result.mode = (__mode); \
6284 (__dport)->result.rp_pwwn = (__dport)->rp_pwwn; \
6285 (__dport)->result.rp_nwwn = (__dport)->rp_nwwn; \
6286 (__dport)->result.lpcnt = (__dport)->lpcnt; \
6287} while (0)
6288
6176static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport, 6289static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport,
6177 enum bfi_dport_req req); 6290 enum bfi_dport_req req);
6178static void 6291static void
@@ -6207,6 +6320,18 @@ bfa_dport_sm_disabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
6207 /* ignore */ 6320 /* ignore */
6208 break; 6321 break;
6209 6322
6323 case BFA_DPORT_SM_SCN:
6324 if (dport->i2hmsg.scn.state == BFI_DPORT_SCN_DDPORT_ENABLE) {
6325 bfa_fcport_ddportenable(dport->bfa);
6326 dport->dynamic = BFA_TRUE;
6327 dport->test_state = BFA_DPORT_ST_NOTSTART;
6328 bfa_sm_set_state(dport, bfa_dport_sm_enabled);
6329 } else {
6330 bfa_trc(dport->bfa, dport->i2hmsg.scn.state);
6331 WARN_ON(1);
6332 }
6333 break;
6334
6210 default: 6335 default:
6211 bfa_sm_fault(dport->bfa, event); 6336 bfa_sm_fault(dport->bfa, event);
6212 } 6337 }
@@ -6242,9 +6367,23 @@ bfa_dport_sm_enabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
6242 6367
6243 switch (event) { 6368 switch (event) {
6244 case BFA_DPORT_SM_FWRSP: 6369 case BFA_DPORT_SM_FWRSP:
6370 memset(&dport->result, 0,
6371 sizeof(struct bfa_diag_dport_result_s));
6372 if (dport->i2hmsg.rsp.status == BFA_STATUS_DPORT_INV_SFP) {
6373 dport->test_state = BFA_DPORT_ST_NO_SFP;
6374 } else {
6375 dport->test_state = BFA_DPORT_ST_INP;
6376 bfa_dport_result_start(dport, BFA_DPORT_OPMODE_AUTO);
6377 }
6245 bfa_sm_set_state(dport, bfa_dport_sm_enabled); 6378 bfa_sm_set_state(dport, bfa_dport_sm_enabled);
6246 break; 6379 break;
6247 6380
6381 case BFA_DPORT_SM_REQFAIL:
6382 dport->test_state = BFA_DPORT_ST_DISABLED;
6383 bfa_fcport_dportdisable(dport->bfa);
6384 bfa_sm_set_state(dport, bfa_dport_sm_disabled);
6385 break;
6386
6248 case BFA_DPORT_SM_HWFAIL: 6387 case BFA_DPORT_SM_HWFAIL:
6249 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6388 bfa_sm_set_state(dport, bfa_dport_sm_disabled);
6250 bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); 6389 bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED);
@@ -6261,8 +6400,11 @@ bfa_dport_sm_enabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
6261 bfa_trc(dport->bfa, event); 6400 bfa_trc(dport->bfa, event);
6262 6401
6263 switch (event) { 6402 switch (event) {
6264 case BFA_DPORT_SM_ENABLE: 6403 case BFA_DPORT_SM_START:
6265 /* Already enabled */ 6404 if (bfa_dport_send_req(dport, BFI_DPORT_START))
6405 bfa_sm_set_state(dport, bfa_dport_sm_starting);
6406 else
6407 bfa_sm_set_state(dport, bfa_dport_sm_starting_qwait);
6266 break; 6408 break;
6267 6409
6268 case BFA_DPORT_SM_DISABLE: 6410 case BFA_DPORT_SM_DISABLE:
@@ -6277,6 +6419,48 @@ bfa_dport_sm_enabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
6277 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6419 bfa_sm_set_state(dport, bfa_dport_sm_disabled);
6278 break; 6420 break;
6279 6421
6422 case BFA_DPORT_SM_SCN:
6423 switch (dport->i2hmsg.scn.state) {
6424 case BFI_DPORT_SCN_TESTCOMP:
6425 dport->test_state = BFA_DPORT_ST_COMP;
6426 break;
6427
6428 case BFI_DPORT_SCN_TESTSTART:
6429 dport->test_state = BFA_DPORT_ST_INP;
6430 break;
6431
6432 case BFI_DPORT_SCN_TESTSKIP:
6433 case BFI_DPORT_SCN_SUBTESTSTART:
6434 /* no state change */
6435 break;
6436
6437 case BFI_DPORT_SCN_SFP_REMOVED:
6438 dport->test_state = BFA_DPORT_ST_NO_SFP;
6439 break;
6440
6441 case BFI_DPORT_SCN_DDPORT_DISABLE:
6442 bfa_fcport_ddportdisable(dport->bfa);
6443
6444 if (bfa_dport_send_req(dport, BFI_DPORT_DYN_DISABLE))
6445 bfa_sm_set_state(dport,
6446 bfa_dport_sm_dynamic_disabling);
6447 else
6448 bfa_sm_set_state(dport,
6449 bfa_dport_sm_dynamic_disabling_qwait);
6450 break;
6451
6452 case BFI_DPORT_SCN_FCPORT_DISABLE:
6453 bfa_fcport_ddportdisable(dport->bfa);
6454
6455 bfa_sm_set_state(dport, bfa_dport_sm_disabled);
6456 dport->dynamic = BFA_FALSE;
6457 break;
6458
6459 default:
6460 bfa_trc(dport->bfa, dport->i2hmsg.scn.state);
6461 bfa_sm_fault(dport->bfa, event);
6462 }
6463 break;
6280 default: 6464 default:
6281 bfa_sm_fault(dport->bfa, event); 6465 bfa_sm_fault(dport->bfa, event);
6282 } 6466 }
@@ -6300,6 +6484,10 @@ bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport,
6300 bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); 6484 bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK);
6301 break; 6485 break;
6302 6486
6487 case BFA_DPORT_SM_SCN:
6488 /* ignore */
6489 break;
6490
6303 default: 6491 default:
6304 bfa_sm_fault(dport->bfa, event); 6492 bfa_sm_fault(dport->bfa, event);
6305 } 6493 }
@@ -6312,7 +6500,98 @@ bfa_dport_sm_disabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
6312 6500
6313 switch (event) { 6501 switch (event) {
6314 case BFA_DPORT_SM_FWRSP: 6502 case BFA_DPORT_SM_FWRSP:
6503 dport->test_state = BFA_DPORT_ST_DISABLED;
6504 bfa_sm_set_state(dport, bfa_dport_sm_disabled);
6505 break;
6506
6507 case BFA_DPORT_SM_HWFAIL:
6315 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6508 bfa_sm_set_state(dport, bfa_dport_sm_disabled);
6509 bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK);
6510 break;
6511
6512 case BFA_DPORT_SM_SCN:
6513 /* no state change */
6514 break;
6515
6516 default:
6517 bfa_sm_fault(dport->bfa, event);
6518 }
6519}
6520
6521static void
6522bfa_dport_sm_starting_qwait(struct bfa_dport_s *dport,
6523 enum bfa_dport_sm_event event)
6524{
6525 bfa_trc(dport->bfa, event);
6526
6527 switch (event) {
6528 case BFA_DPORT_SM_QRESUME:
6529 bfa_sm_set_state(dport, bfa_dport_sm_starting);
6530 bfa_dport_send_req(dport, BFI_DPORT_START);
6531 break;
6532
6533 case BFA_DPORT_SM_HWFAIL:
6534 bfa_reqq_wcancel(&dport->reqq_wait);
6535 bfa_sm_set_state(dport, bfa_dport_sm_disabled);
6536 bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED);
6537 break;
6538
6539 default:
6540 bfa_sm_fault(dport->bfa, event);
6541 }
6542}
6543
6544static void
6545bfa_dport_sm_starting(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
6546{
6547 bfa_trc(dport->bfa, event);
6548
6549 switch (event) {
6550 case BFA_DPORT_SM_FWRSP:
6551 memset(&dport->result, 0,
6552 sizeof(struct bfa_diag_dport_result_s));
6553 if (dport->i2hmsg.rsp.status == BFA_STATUS_DPORT_INV_SFP) {
6554 dport->test_state = BFA_DPORT_ST_NO_SFP;
6555 } else {
6556 dport->test_state = BFA_DPORT_ST_INP;
6557 bfa_dport_result_start(dport, BFA_DPORT_OPMODE_MANU);
6558 }
6559 /* fall thru */
6560
6561 case BFA_DPORT_SM_REQFAIL:
6562 bfa_sm_set_state(dport, bfa_dport_sm_enabled);
6563 break;
6564
6565 case BFA_DPORT_SM_HWFAIL:
6566 bfa_sm_set_state(dport, bfa_dport_sm_disabled);
6567 bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED);
6568 break;
6569
6570 default:
6571 bfa_sm_fault(dport->bfa, event);
6572 }
6573}
6574
6575static void
6576bfa_dport_sm_dynamic_disabling(struct bfa_dport_s *dport,
6577 enum bfa_dport_sm_event event)
6578{
6579 bfa_trc(dport->bfa, event);
6580
6581 switch (event) {
6582 case BFA_DPORT_SM_SCN:
6583 switch (dport->i2hmsg.scn.state) {
6584 case BFI_DPORT_SCN_DDPORT_DISABLED:
6585 bfa_sm_set_state(dport, bfa_dport_sm_disabled);
6586 dport->dynamic = BFA_FALSE;
6587 bfa_fcport_enable(dport->bfa);
6588 break;
6589
6590 default:
6591 bfa_trc(dport->bfa, dport->i2hmsg.scn.state);
6592 bfa_sm_fault(dport->bfa, event);
6593
6594 }
6316 break; 6595 break;
6317 6596
6318 case BFA_DPORT_SM_HWFAIL: 6597 case BFA_DPORT_SM_HWFAIL:
@@ -6325,6 +6604,32 @@ bfa_dport_sm_disabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
6325 } 6604 }
6326} 6605}
6327 6606
6607static void
6608bfa_dport_sm_dynamic_disabling_qwait(struct bfa_dport_s *dport,
6609 enum bfa_dport_sm_event event)
6610{
6611 bfa_trc(dport->bfa, event);
6612
6613 switch (event) {
6614 case BFA_DPORT_SM_QRESUME:
6615 bfa_sm_set_state(dport, bfa_dport_sm_dynamic_disabling);
6616 bfa_dport_send_req(dport, BFI_DPORT_DYN_DISABLE);
6617 break;
6618
6619 case BFA_DPORT_SM_HWFAIL:
6620 bfa_sm_set_state(dport, bfa_dport_sm_disabled);
6621 bfa_reqq_wcancel(&dport->reqq_wait);
6622 bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK);
6623 break;
6624
6625 case BFA_DPORT_SM_SCN:
6626 /* ignore */
6627 break;
6628
6629 default:
6630 bfa_sm_fault(dport->bfa, event);
6631 }
6632}
6328 6633
6329static bfa_boolean_t 6634static bfa_boolean_t
6330bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req) 6635bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req)
@@ -6332,12 +6637,6 @@ bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req)
6332 struct bfi_diag_dport_req_s *m; 6637 struct bfi_diag_dport_req_s *m;
6333 6638
6334 /* 6639 /*
6335 * Increment message tag before queue check, so that responses to old
6336 * requests are discarded.
6337 */
6338 dport->msgtag++;
6339
6340 /*
6341 * check for room in queue to send request now 6640 * check for room in queue to send request now
6342 */ 6641 */
6343 m = bfa_reqq_next(dport->bfa, BFA_REQQ_DIAG); 6642 m = bfa_reqq_next(dport->bfa, BFA_REQQ_DIAG);
@@ -6349,7 +6648,10 @@ bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req)
6349 bfi_h2i_set(m->mh, BFI_MC_DIAG, BFI_DIAG_H2I_DPORT, 6648 bfi_h2i_set(m->mh, BFI_MC_DIAG, BFI_DIAG_H2I_DPORT,
6350 bfa_fn_lpu(dport->bfa)); 6649 bfa_fn_lpu(dport->bfa));
6351 m->req = req; 6650 m->req = req;
6352 m->msgtag = dport->msgtag; 6651 if ((req == BFI_DPORT_ENABLE) || (req == BFI_DPORT_START)) {
6652 m->lpcnt = cpu_to_be32(dport->lpcnt);
6653 m->payload = cpu_to_be32(dport->payload);
6654 }
6353 6655
6354 /* 6656 /*
6355 * queue I/O message to firmware 6657 * queue I/O message to firmware
@@ -6368,19 +6670,131 @@ bfa_dport_qresume(void *cbarg)
6368} 6670}
6369 6671
6370static void 6672static void
6371bfa_dport_req_comp(struct bfa_dport_s *dport, bfi_diag_dport_rsp_t *msg) 6673bfa_dport_req_comp(struct bfa_dport_s *dport, struct bfi_diag_dport_rsp_s *msg)
6372{ 6674{
6373 bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP); 6675 msg->status = cpu_to_be32(msg->status);
6676 dport->i2hmsg.rsp.status = msg->status;
6677 dport->rp_pwwn = msg->pwwn;
6678 dport->rp_nwwn = msg->nwwn;
6679
6680 if ((msg->status == BFA_STATUS_OK) ||
6681 (msg->status == BFA_STATUS_DPORT_NO_SFP)) {
6682 bfa_trc(dport->bfa, msg->status);
6683 bfa_trc(dport->bfa, dport->rp_pwwn);
6684 bfa_trc(dport->bfa, dport->rp_nwwn);
6685 bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP);
6686
6687 } else {
6688 bfa_trc(dport->bfa, msg->status);
6689 bfa_sm_send_event(dport, BFA_DPORT_SM_REQFAIL);
6690 }
6374 bfa_cb_fcdiag_dport(dport, msg->status); 6691 bfa_cb_fcdiag_dport(dport, msg->status);
6375} 6692}
6376 6693
6694static bfa_boolean_t
6695bfa_dport_is_sending_req(struct bfa_dport_s *dport)
6696{
6697 if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) ||
6698 bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) ||
6699 bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) ||
6700 bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait) ||
6701 bfa_sm_cmp_state(dport, bfa_dport_sm_starting) ||
6702 bfa_sm_cmp_state(dport, bfa_dport_sm_starting_qwait)) {
6703 return BFA_TRUE;
6704 } else {
6705 return BFA_FALSE;
6706 }
6707}
6708
6709static void
6710bfa_dport_scn(struct bfa_dport_s *dport, struct bfi_diag_dport_scn_s *msg)
6711{
6712 int i;
6713 uint8_t subtesttype;
6714
6715 bfa_trc(dport->bfa, msg->state);
6716 dport->i2hmsg.scn.state = msg->state;
6717
6718 switch (dport->i2hmsg.scn.state) {
6719 case BFI_DPORT_SCN_TESTCOMP:
6720 dport->result.end_time = bfa_get_log_time();
6721 bfa_trc(dport->bfa, dport->result.end_time);
6722
6723 dport->result.status = msg->info.testcomp.status;
6724 bfa_trc(dport->bfa, dport->result.status);
6725
6726 dport->result.roundtrip_latency =
6727 cpu_to_be32(msg->info.testcomp.latency);
6728 dport->result.est_cable_distance =
6729 cpu_to_be32(msg->info.testcomp.distance);
6730 dport->result.buffer_required =
6731 be16_to_cpu(msg->info.testcomp.numbuffer);
6732
6733 dport->result.frmsz = be16_to_cpu(msg->info.testcomp.frm_sz);
6734 dport->result.speed = msg->info.testcomp.speed;
6735
6736 bfa_trc(dport->bfa, dport->result.roundtrip_latency);
6737 bfa_trc(dport->bfa, dport->result.est_cable_distance);
6738 bfa_trc(dport->bfa, dport->result.buffer_required);
6739 bfa_trc(dport->bfa, dport->result.frmsz);
6740 bfa_trc(dport->bfa, dport->result.speed);
6741
6742 for (i = DPORT_TEST_ELOOP; i < DPORT_TEST_MAX; i++) {
6743 dport->result.subtest[i].status =
6744 msg->info.testcomp.subtest_status[i];
6745 bfa_trc(dport->bfa, dport->result.subtest[i].status);
6746 }
6747 break;
6748
6749 case BFI_DPORT_SCN_TESTSKIP:
6750 case BFI_DPORT_SCN_DDPORT_ENABLE:
6751 memset(&dport->result, 0,
6752 sizeof(struct bfa_diag_dport_result_s));
6753 break;
6754
6755 case BFI_DPORT_SCN_TESTSTART:
6756 memset(&dport->result, 0,
6757 sizeof(struct bfa_diag_dport_result_s));
6758 dport->rp_pwwn = msg->info.teststart.pwwn;
6759 dport->rp_nwwn = msg->info.teststart.nwwn;
6760 dport->lpcnt = cpu_to_be32(msg->info.teststart.numfrm);
6761 bfa_dport_result_start(dport, BFA_DPORT_OPMODE_AUTO);
6762 break;
6763
6764 case BFI_DPORT_SCN_SUBTESTSTART:
6765 subtesttype = msg->info.teststart.type;
6766 dport->result.subtest[subtesttype].start_time =
6767 bfa_get_log_time();
6768 dport->result.subtest[subtesttype].status =
6769 DPORT_TEST_ST_INPRG;
6770
6771 bfa_trc(dport->bfa, subtesttype);
6772 bfa_trc(dport->bfa,
6773 dport->result.subtest[subtesttype].start_time);
6774 break;
6775
6776 case BFI_DPORT_SCN_SFP_REMOVED:
6777 case BFI_DPORT_SCN_DDPORT_DISABLED:
6778 case BFI_DPORT_SCN_DDPORT_DISABLE:
6779 case BFI_DPORT_SCN_FCPORT_DISABLE:
6780 dport->result.status = DPORT_TEST_ST_IDLE;
6781 break;
6782
6783 default:
6784 bfa_sm_fault(dport->bfa, msg->state);
6785 }
6786
6787 bfa_sm_send_event(dport, BFA_DPORT_SM_SCN);
6788}
6789
6377/* 6790/*
6378 * Dport enable 6791 * Dport enable
6379 * 6792 *
6380 * @param[in] *bfa - bfa data struct 6793 * @param[in] *bfa - bfa data struct
6381 */ 6794 */
6382bfa_status_t 6795bfa_status_t
6383bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) 6796bfa_dport_enable(struct bfa_s *bfa, u32 lpcnt, u32 pat,
6797 bfa_cb_diag_t cbfn, void *cbarg)
6384{ 6798{
6385 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 6799 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
6386 struct bfa_dport_s *dport = &fcdiag->dport; 6800 struct bfa_dport_s *dport = &fcdiag->dport;
@@ -6394,6 +6808,14 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
6394 } 6808 }
6395 6809
6396 /* 6810 /*
6811 * Dport is supported in CT2 or above
6812 */
6813 if (!(bfa_asic_id_ct2(dport->bfa->ioc.pcidev.device_id))) {
6814 bfa_trc(dport->bfa, dport->bfa->ioc.pcidev.device_id);
6815 return BFA_STATUS_FEATURE_NOT_SUPPORTED;
6816 }
6817
6818 /*
6397 * Check to see if IOC is down 6819 * Check to see if IOC is down
6398 */ 6820 */
6399 if (!bfa_iocfc_is_operational(bfa)) 6821 if (!bfa_iocfc_is_operational(bfa))
@@ -6431,6 +6853,14 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
6431 } 6853 }
6432 6854
6433 /* 6855 /*
6856 * Check if diag loopback is running
6857 */
6858 if (bfa_fcdiag_lb_is_running(bfa)) {
6859 bfa_trc(dport->bfa, 0);
6860 return BFA_STATUS_DIAG_BUSY;
6861 }
6862
6863 /*
6434 * Check to see if port is disable or in dport state 6864 * Check to see if port is disable or in dport state
6435 */ 6865 */
6436 if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && 6866 if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) &&
@@ -6440,14 +6870,16 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
6440 } 6870 }
6441 6871
6442 /* 6872 /*
6873 * Check if dport is in dynamic mode
6874 */
6875 if (dport->dynamic)
6876 return BFA_STATUS_DDPORT_ERR;
6877
6878 /*
6443 * Check if dport is busy 6879 * Check if dport is busy
6444 */ 6880 */
6445 if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || 6881 if (bfa_dport_is_sending_req(dport))
6446 bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) ||
6447 bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) ||
6448 bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) {
6449 return BFA_STATUS_DEVBUSY; 6882 return BFA_STATUS_DEVBUSY;
6450 }
6451 6883
6452 /* 6884 /*
6453 * Check if dport is already enabled 6885 * Check if dport is already enabled
@@ -6457,6 +6889,10 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
6457 return BFA_STATUS_DPORT_ENABLED; 6889 return BFA_STATUS_DPORT_ENABLED;
6458 } 6890 }
6459 6891
6892 bfa_trc(dport->bfa, lpcnt);
6893 bfa_trc(dport->bfa, pat);
6894 dport->lpcnt = (lpcnt) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT;
6895 dport->payload = (pat) ? pat : LB_PATTERN_DEFAULT;
6460 dport->cbfn = cbfn; 6896 dport->cbfn = cbfn;
6461 dport->cbarg = cbarg; 6897 dport->cbarg = cbarg;
6462 6898
@@ -6485,6 +6921,13 @@ bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
6485 } 6921 }
6486 6922
6487 /* 6923 /*
6924 * Check if dport is in dynamic mode
6925 */
6926 if (dport->dynamic) {
6927 return BFA_STATUS_DDPORT_ERR;
6928 }
6929
6930 /*
6488 * Check to see if port is disable or in dport state 6931 * Check to see if port is disable or in dport state
6489 */ 6932 */
6490 if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && 6933 if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) &&
@@ -6496,10 +6939,7 @@ bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
6496 /* 6939 /*
6497 * Check if dport is busy 6940 * Check if dport is busy
6498 */ 6941 */
6499 if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || 6942 if (bfa_dport_is_sending_req(dport))
6500 bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) ||
6501 bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) ||
6502 bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait))
6503 return BFA_STATUS_DEVBUSY; 6943 return BFA_STATUS_DEVBUSY;
6504 6944
6505 /* 6945 /*
@@ -6518,30 +6958,105 @@ bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
6518} 6958}
6519 6959
6520/* 6960/*
6521 * Get D-port state 6961 * Dport start -- restart dport test
6522 * 6962 *
6523 * @param[in] *bfa - bfa data struct 6963 * @param[in] *bfa - bfa data struct
6524 */ 6964 */
6965bfa_status_t
6966bfa_dport_start(struct bfa_s *bfa, u32 lpcnt, u32 pat,
6967 bfa_cb_diag_t cbfn, void *cbarg)
6968{
6969 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
6970 struct bfa_dport_s *dport = &fcdiag->dport;
6525 6971
6972 /*
6973 * Check to see if IOC is down
6974 */
6975 if (!bfa_iocfc_is_operational(bfa))
6976 return BFA_STATUS_IOC_NON_OP;
6977
6978 /*
6979 * Check if dport is in dynamic mode
6980 */
6981 if (dport->dynamic)
6982 return BFA_STATUS_DDPORT_ERR;
6983
6984 /*
6985 * Check if dport is busy
6986 */
6987 if (bfa_dport_is_sending_req(dport))
6988 return BFA_STATUS_DEVBUSY;
6989
6990 /*
6991 * Check if dport is in enabled state.
6992 * Test can only be restart when previous test has completed
6993 */
6994 if (!bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) {
6995 bfa_trc(dport->bfa, 0);
6996 return BFA_STATUS_DPORT_DISABLED;
6997
6998 } else {
6999 if (dport->test_state == BFA_DPORT_ST_NO_SFP)
7000 return BFA_STATUS_DPORT_INV_SFP;
7001
7002 if (dport->test_state == BFA_DPORT_ST_INP)
7003 return BFA_STATUS_DEVBUSY;
7004
7005 WARN_ON(dport->test_state != BFA_DPORT_ST_COMP);
7006 }
7007
7008 bfa_trc(dport->bfa, lpcnt);
7009 bfa_trc(dport->bfa, pat);
7010
7011 dport->lpcnt = (lpcnt) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT;
7012 dport->payload = (pat) ? pat : LB_PATTERN_DEFAULT;
7013
7014 dport->cbfn = cbfn;
7015 dport->cbarg = cbarg;
7016
7017 bfa_sm_send_event(dport, BFA_DPORT_SM_START);
7018 return BFA_STATUS_OK;
7019}
7020
7021/*
7022 * Dport show -- return dport test result
7023 *
7024 * @param[in] *bfa - bfa data struct
7025 */
6526bfa_status_t 7026bfa_status_t
6527bfa_dport_get_state(struct bfa_s *bfa, enum bfa_dport_state *state) 7027bfa_dport_show(struct bfa_s *bfa, struct bfa_diag_dport_result_s *result)
6528{ 7028{
6529 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 7029 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
6530 struct bfa_dport_s *dport = &fcdiag->dport; 7030 struct bfa_dport_s *dport = &fcdiag->dport;
6531 7031
6532 if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) 7032 /*
6533 *state = BFA_DPORT_ST_ENABLED; 7033 * Check to see if IOC is down
6534 else if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || 7034 */
6535 bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait)) 7035 if (!bfa_iocfc_is_operational(bfa))
6536 *state = BFA_DPORT_ST_ENABLING; 7036 return BFA_STATUS_IOC_NON_OP;
6537 else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled)) 7037
6538 *state = BFA_DPORT_ST_DISABLED; 7038 /*
6539 else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || 7039 * Check if dport is busy
6540 bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) 7040 */
6541 *state = BFA_DPORT_ST_DISABLING; 7041 if (bfa_dport_is_sending_req(dport))
6542 else { 7042 return BFA_STATUS_DEVBUSY;
6543 bfa_trc(dport->bfa, BFA_STATUS_EINVAL); 7043
6544 return BFA_STATUS_EINVAL; 7044 /*
7045 * Check if dport is in enabled state.
7046 */
7047 if (!bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) {
7048 bfa_trc(dport->bfa, 0);
7049 return BFA_STATUS_DPORT_DISABLED;
7050
6545 } 7051 }
7052
7053 /*
7054 * Check if there is SFP
7055 */
7056 if (dport->test_state == BFA_DPORT_ST_NO_SFP)
7057 return BFA_STATUS_DPORT_INV_SFP;
7058
7059 memcpy(result, &dport->result, sizeof(struct bfa_diag_dport_result_s));
7060
6546 return BFA_STATUS_OK; 7061 return BFA_STATUS_OK;
6547} 7062}