diff options
author | Vijaya Mohan Guvva <vmohan@brocade.com> | 2013-05-13 05:33:21 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-06-26 14:44:20 -0400 |
commit | 1a898a794d5913c899a329c5dec39d28e6065672 (patch) | |
tree | bf5ec13403df005157a3ac053dcf82c8044cd1b7 /drivers/scsi | |
parent | 4e1e0d8d71810fb5e4c294299ab35c30a746353d (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')
-rw-r--r-- | drivers/scsi/bfa/bfa_defs.h | 79 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_defs_svc.h | 1 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_svc.c | 595 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfa_svc.h | 21 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.c | 81 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfad_bsg.h | 25 | ||||
-rw-r--r-- | drivers/scsi/bfa/bfi.h | 68 |
7 files changed, 781 insertions, 89 deletions
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h index bdd1bae971ef..d65a9b4a6f65 100644 --- a/drivers/scsi/bfa/bfa_defs.h +++ b/drivers/scsi/bfa/bfa_defs.h | |||
@@ -199,15 +199,34 @@ enum bfa_status { | |||
199 | BFA_STATUS_DPORT_DISABLED = 236, /* D-port mode is already disabled */ | 199 | BFA_STATUS_DPORT_DISABLED = 236, /* D-port mode is already disabled */ |
200 | BFA_STATUS_CMD_NOTSUPP_MEZZ = 239, /* Cmd not supported for MEZZ card */ | 200 | BFA_STATUS_CMD_NOTSUPP_MEZZ = 239, /* Cmd not supported for MEZZ card */ |
201 | BFA_STATUS_FRU_NOT_PRESENT = 240, /* fru module not present */ | 201 | BFA_STATUS_FRU_NOT_PRESENT = 240, /* fru module not present */ |
202 | BFA_STATUS_DPORT_NO_SFP = 243, /* SFP is not present.\n D-port will be | ||
203 | * enabled but it will be operational | ||
204 | * only after inserting a valid SFP. */ | ||
202 | BFA_STATUS_DPORT_ERR = 245, /* D-port mode is enabled */ | 205 | BFA_STATUS_DPORT_ERR = 245, /* D-port mode is enabled */ |
206 | BFA_STATUS_DPORT_ENOSYS = 254, /* Switch has no D_Port functionality */ | ||
207 | BFA_STATUS_DPORT_CANT_PERF = 255, /* Switch port is not D_Port capable | ||
208 | * or D_Port is disabled */ | ||
209 | BFA_STATUS_DPORT_LOGICALERR = 256, /* Switch D_Port fail */ | ||
210 | BFA_STATUS_DPORT_SWBUSY = 257, /* Switch port busy */ | ||
203 | BFA_STATUS_ERR_BBCR_SPEED_UNSUPPORT = 258, /*!< BB credit recovery is | 211 | BFA_STATUS_ERR_BBCR_SPEED_UNSUPPORT = 258, /*!< BB credit recovery is |
204 | * supported at max port speed alone */ | 212 | * supported at max port speed alone */ |
205 | BFA_STATUS_ERROR_BBCR_ENABLED = 259, /*!< BB credit recovery | 213 | BFA_STATUS_ERROR_BBCR_ENABLED = 259, /*!< BB credit recovery |
206 | * is enabled */ | 214 | * is enabled */ |
207 | BFA_STATUS_INVALID_BBSCN = 260, /*!< Invalid BBSCN value. | 215 | BFA_STATUS_INVALID_BBSCN = 260, /*!< Invalid BBSCN value. |
208 | * Valid range is [1-15] */ | 216 | * Valid range is [1-15] */ |
217 | BFA_STATUS_DDPORT_ERR = 261, /* Dynamic D_Port mode is active.\n To | ||
218 | * exit dynamic mode, disable D_Port on | ||
219 | * the remote port */ | ||
220 | BFA_STATUS_DPORT_SFPWRAP_ERR = 262, /* Clear e/o_wrap fail, check or | ||
221 | * replace SFP */ | ||
209 | BFA_STATUS_BBCR_CFG_NO_CHANGE = 265, /*!< BBCR is operational. | 222 | BFA_STATUS_BBCR_CFG_NO_CHANGE = 265, /*!< BBCR is operational. |
210 | * Disable BBCR and try this operation again. */ | 223 | * Disable BBCR and try this operation again. */ |
224 | BFA_STATUS_DPORT_SW_NOTREADY = 268, /* Remote port is not ready to | ||
225 | * start dport test. Check remote | ||
226 | * port status. */ | ||
227 | BFA_STATUS_DPORT_INV_SFP = 271, /* Invalid SFP for D-PORT mode. */ | ||
228 | BFA_STATUS_DPORT_CMD_NOTSUPP = 273, /* Dport is not supported by | ||
229 | * remote port */ | ||
211 | BFA_STATUS_MAX_VAL /* Unknown error code */ | 230 | BFA_STATUS_MAX_VAL /* Unknown error code */ |
212 | }; | 231 | }; |
213 | #define bfa_status_t enum bfa_status | 232 | #define bfa_status_t enum bfa_status |
@@ -527,17 +546,6 @@ struct bfa_ioc_aen_data_s { | |||
527 | }; | 546 | }; |
528 | 547 | ||
529 | /* | 548 | /* |
530 | * D-port states | ||
531 | * | ||
532 | */ | ||
533 | enum bfa_dport_state { | ||
534 | BFA_DPORT_ST_DISABLED = 0, /* D-port is Disabled */ | ||
535 | BFA_DPORT_ST_DISABLING = 1, /* D-port is Disabling */ | ||
536 | BFA_DPORT_ST_ENABLING = 2, /* D-port is Enabling */ | ||
537 | BFA_DPORT_ST_ENABLED = 3, /* D-port is Enabled */ | ||
538 | }; | ||
539 | |||
540 | /* | ||
541 | * ---------------------- mfg definitions ------------ | 549 | * ---------------------- mfg definitions ------------ |
542 | */ | 550 | */ |
543 | 551 | ||
@@ -1136,6 +1144,7 @@ struct bfa_flash_attr_s { | |||
1136 | #define LB_PATTERN_DEFAULT 0xB5B5B5B5 | 1144 | #define LB_PATTERN_DEFAULT 0xB5B5B5B5 |
1137 | #define QTEST_CNT_DEFAULT 10 | 1145 | #define QTEST_CNT_DEFAULT 10 |
1138 | #define QTEST_PAT_DEFAULT LB_PATTERN_DEFAULT | 1146 | #define QTEST_PAT_DEFAULT LB_PATTERN_DEFAULT |
1147 | #define DPORT_ENABLE_LOOPCNT_DEFAULT (1024 * 1024) | ||
1139 | 1148 | ||
1140 | struct bfa_diag_memtest_s { | 1149 | struct bfa_diag_memtest_s { |
1141 | u8 algo; | 1150 | u8 algo; |
@@ -1164,6 +1173,54 @@ struct bfa_diag_loopback_result_s { | |||
1164 | u8 rsvd[3]; | 1173 | u8 rsvd[3]; |
1165 | }; | 1174 | }; |
1166 | 1175 | ||
1176 | enum bfa_diag_dport_test_status { | ||
1177 | DPORT_TEST_ST_IDLE = 0, /* the test has not started yet. */ | ||
1178 | DPORT_TEST_ST_FINAL = 1, /* the test done successfully */ | ||
1179 | DPORT_TEST_ST_SKIP = 2, /* the test skipped */ | ||
1180 | DPORT_TEST_ST_FAIL = 3, /* the test failed */ | ||
1181 | DPORT_TEST_ST_INPRG = 4, /* the testing is in progress */ | ||
1182 | DPORT_TEST_ST_RESPONDER = 5, /* test triggered from remote port */ | ||
1183 | DPORT_TEST_ST_STOPPED = 6, /* the test stopped by user. */ | ||
1184 | DPORT_TEST_ST_MAX | ||
1185 | }; | ||
1186 | |||
1187 | enum bfa_diag_dport_test_type { | ||
1188 | DPORT_TEST_ELOOP = 0, | ||
1189 | DPORT_TEST_OLOOP = 1, | ||
1190 | DPORT_TEST_ROLOOP = 2, | ||
1191 | DPORT_TEST_LINK = 3, | ||
1192 | DPORT_TEST_MAX | ||
1193 | }; | ||
1194 | |||
1195 | enum bfa_diag_dport_test_opmode { | ||
1196 | BFA_DPORT_OPMODE_AUTO = 0, | ||
1197 | BFA_DPORT_OPMODE_MANU = 1, | ||
1198 | }; | ||
1199 | |||
1200 | struct bfa_diag_dport_subtest_result_s { | ||
1201 | u8 status; /* bfa_diag_dport_test_status */ | ||
1202 | u8 rsvd[7]; /* 64bit align */ | ||
1203 | u64 start_time; /* timestamp */ | ||
1204 | }; | ||
1205 | |||
1206 | struct bfa_diag_dport_result_s { | ||
1207 | wwn_t rp_pwwn; /* switch port wwn */ | ||
1208 | wwn_t rp_nwwn; /* switch node wwn */ | ||
1209 | u64 start_time; /* user/sw start time */ | ||
1210 | u64 end_time; /* timestamp */ | ||
1211 | u8 status; /* bfa_diag_dport_test_status */ | ||
1212 | u8 mode; /* bfa_diag_dport_test_opmode */ | ||
1213 | u8 rsvd; /* 64bit align */ | ||
1214 | u8 speed; /* link speed for buf_reqd */ | ||
1215 | u16 buffer_required; | ||
1216 | u16 frmsz; /* frame size for buf_reqd */ | ||
1217 | u32 lpcnt; /* Frame count */ | ||
1218 | u32 pat; /* Pattern */ | ||
1219 | u32 roundtrip_latency; /* in nano sec */ | ||
1220 | u32 est_cable_distance; /* in meter */ | ||
1221 | struct bfa_diag_dport_subtest_result_s subtest[DPORT_TEST_MAX]; | ||
1222 | }; | ||
1223 | |||
1167 | struct bfa_diag_ledtest_s { | 1224 | struct bfa_diag_ledtest_s { |
1168 | u32 cmd; /* bfa_led_op_t */ | 1225 | u32 cmd; /* bfa_led_op_t */ |
1169 | u32 color; /* bfa_led_color_t */ | 1226 | u32 color; /* bfa_led_color_t */ |
diff --git a/drivers/scsi/bfa/bfa_defs_svc.h b/drivers/scsi/bfa/bfa_defs_svc.h index 0880d86c3542..2f20ba5f57b6 100644 --- a/drivers/scsi/bfa/bfa_defs_svc.h +++ b/drivers/scsi/bfa/bfa_defs_svc.h | |||
@@ -761,6 +761,7 @@ enum bfa_port_states { | |||
761 | BFA_PORT_ST_TOGGLING_QWAIT = 14, | 761 | BFA_PORT_ST_TOGGLING_QWAIT = 14, |
762 | BFA_PORT_ST_FAA_MISCONFIG = 15, | 762 | BFA_PORT_ST_FAA_MISCONFIG = 15, |
763 | BFA_PORT_ST_DPORT = 16, | 763 | BFA_PORT_ST_DPORT = 16, |
764 | BFA_PORT_ST_DDPORT = 17, | ||
764 | BFA_PORT_ST_MAX_STATE, | 765 | BFA_PORT_ST_MAX_STATE, |
765 | }; | 766 | }; |
766 | 767 | ||
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); |
203 | static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, | 205 | static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, |
204 | enum bfa_fcport_sm_event event); | 206 | enum bfa_fcport_sm_event event); |
207 | static void bfa_fcport_sm_ddport(struct bfa_fcport_s *fcport, | ||
208 | enum bfa_fcport_sm_event event); | ||
205 | static void bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport, | 209 | static 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 | ||
2761 | static void | 2770 | static void |
2771 | bfa_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 | |||
2804 | static void | ||
2762 | bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport, | 2805 | bfa_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 | ||
4175 | bfa_boolean_t | ||
4176 | bfa_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 | |||
4130 | bfa_status_t | 4184 | bfa_status_t |
4131 | bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw) | 4185 | bfa_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 | ||
4377 | void | ||
4378 | bfa_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 | |||
4386 | void | ||
4387 | bfa_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 | ||
5780 | enum 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 | ||
5719 | static void bfa_dport_sm_disabled(struct bfa_dport_s *dport, | 5802 | static 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); |
5729 | static void bfa_dport_sm_disabling(struct bfa_dport_s *dport, | 5812 | static void bfa_dport_sm_disabling(struct bfa_dport_s *dport, |
5730 | enum bfa_dport_sm_event event); | 5813 | enum bfa_dport_sm_event event); |
5814 | static void bfa_dport_sm_starting_qwait(struct bfa_dport_s *dport, | ||
5815 | enum bfa_dport_sm_event event); | ||
5816 | static void bfa_dport_sm_starting(struct bfa_dport_s *dport, | ||
5817 | enum bfa_dport_sm_event event); | ||
5818 | static void bfa_dport_sm_dynamic_disabling(struct bfa_dport_s *dport, | ||
5819 | enum bfa_dport_sm_event event); | ||
5820 | static void bfa_dport_sm_dynamic_disabling_qwait(struct bfa_dport_s *dport, | ||
5821 | enum bfa_dport_sm_event event); | ||
5731 | static void bfa_dport_qresume(void *cbarg); | 5822 | static void bfa_dport_qresume(void *cbarg); |
5732 | static void bfa_dport_req_comp(struct bfa_dport_s *dport, | 5823 | static 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); |
5825 | static 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 | ||
5777 | static void | 5872 | static 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 | |||
6176 | static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport, | 6289 | static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport, |
6177 | enum bfi_dport_req req); | 6290 | enum bfi_dport_req req); |
6178 | static void | 6291 | static 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 | |||
6521 | static void | ||
6522 | bfa_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 | |||
6544 | static void | ||
6545 | bfa_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 | |||
6575 | static void | ||
6576 | bfa_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 | ||
6607 | static void | ||
6608 | bfa_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 | ||
6329 | static bfa_boolean_t | 6634 | static bfa_boolean_t |
6330 | bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req) | 6635 | bfa_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 | ||
6370 | static void | 6672 | static void |
6371 | bfa_dport_req_comp(struct bfa_dport_s *dport, bfi_diag_dport_rsp_t *msg) | 6673 | bfa_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 | ||
6694 | static bfa_boolean_t | ||
6695 | bfa_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 | |||
6709 | static void | ||
6710 | bfa_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 | */ |
6382 | bfa_status_t | 6795 | bfa_status_t |
6383 | bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) | 6796 | bfa_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 | */ |
6965 | bfa_status_t | ||
6966 | bfa_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 | */ | ||
6526 | bfa_status_t | 7026 | bfa_status_t |
6527 | bfa_dport_get_state(struct bfa_s *bfa, enum bfa_dport_state *state) | 7027 | bfa_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 | } |
diff --git a/drivers/scsi/bfa/bfa_svc.h b/drivers/scsi/bfa/bfa_svc.h index 5af64de152b6..ef07365991e7 100644 --- a/drivers/scsi/bfa/bfa_svc.h +++ b/drivers/scsi/bfa/bfa_svc.h | |||
@@ -551,6 +551,7 @@ void bfa_fcport_event_register(struct bfa_s *bfa, | |||
551 | enum bfa_port_linkstate event), void *event_cbarg); | 551 | enum bfa_port_linkstate event), void *event_cbarg); |
552 | bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa); | 552 | bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa); |
553 | bfa_boolean_t bfa_fcport_is_dport(struct bfa_s *bfa); | 553 | bfa_boolean_t bfa_fcport_is_dport(struct bfa_s *bfa); |
554 | bfa_boolean_t bfa_fcport_is_ddport(struct bfa_s *bfa); | ||
554 | bfa_status_t bfa_fcport_set_qos_bw(struct bfa_s *bfa, | 555 | bfa_status_t bfa_fcport_set_qos_bw(struct bfa_s *bfa, |
555 | struct bfa_qos_bw_s *qos_bw); | 556 | struct bfa_qos_bw_s *qos_bw); |
556 | enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa); | 557 | enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa); |
@@ -715,10 +716,18 @@ struct bfa_fcdiag_lb_s { | |||
715 | struct bfa_dport_s { | 716 | struct bfa_dport_s { |
716 | struct bfa_s *bfa; /* Back pointer to BFA */ | 717 | struct bfa_s *bfa; /* Back pointer to BFA */ |
717 | bfa_sm_t sm; /* finite state machine */ | 718 | bfa_sm_t sm; /* finite state machine */ |
718 | u32 msgtag; /* firmware msg tag for reply */ | ||
719 | struct bfa_reqq_wait_s reqq_wait; | 719 | struct bfa_reqq_wait_s reqq_wait; |
720 | bfa_cb_diag_t cbfn; | 720 | bfa_cb_diag_t cbfn; |
721 | void *cbarg; | 721 | void *cbarg; |
722 | union bfi_diag_dport_msg_u i2hmsg; | ||
723 | u8 test_state; /* enum dport_test_state */ | ||
724 | u8 dynamic; /* boolean_t */ | ||
725 | u8 rsvd[2]; | ||
726 | u32 lpcnt; | ||
727 | u32 payload; /* user defined payload pattern */ | ||
728 | wwn_t rp_pwwn; | ||
729 | wwn_t rp_nwwn; | ||
730 | struct bfa_diag_dport_result_s result; | ||
722 | }; | 731 | }; |
723 | 732 | ||
724 | struct bfa_fcdiag_s { | 733 | struct bfa_fcdiag_s { |
@@ -742,11 +751,13 @@ bfa_status_t bfa_fcdiag_queuetest(struct bfa_s *bfa, u32 ignore, | |||
742 | u32 queue, struct bfa_diag_qtest_result_s *result, | 751 | u32 queue, struct bfa_diag_qtest_result_s *result, |
743 | bfa_cb_diag_t cbfn, void *cbarg); | 752 | bfa_cb_diag_t cbfn, void *cbarg); |
744 | bfa_status_t bfa_fcdiag_lb_is_running(struct bfa_s *bfa); | 753 | bfa_status_t bfa_fcdiag_lb_is_running(struct bfa_s *bfa); |
745 | bfa_status_t bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, | 754 | bfa_status_t bfa_dport_enable(struct bfa_s *bfa, u32 lpcnt, u32 pat, |
746 | void *cbarg); | 755 | bfa_cb_diag_t cbfn, void *cbarg); |
747 | bfa_status_t bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, | 756 | bfa_status_t bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, |
748 | void *cbarg); | 757 | void *cbarg); |
749 | bfa_status_t bfa_dport_get_state(struct bfa_s *bfa, | 758 | bfa_status_t bfa_dport_start(struct bfa_s *bfa, u32 lpcnt, u32 pat, |
750 | enum bfa_dport_state *state); | 759 | bfa_cb_diag_t cbfn, void *cbarg); |
760 | bfa_status_t bfa_dport_show(struct bfa_s *bfa, | ||
761 | struct bfa_diag_dport_result_s *result); | ||
751 | 762 | ||
752 | #endif /* __BFA_SVC_H__ */ | 763 | #endif /* __BFA_SVC_H__ */ |
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index bda1500e1a20..f31acfa3f113 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c | |||
@@ -1785,51 +1785,87 @@ bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd) | |||
1785 | } | 1785 | } |
1786 | 1786 | ||
1787 | int | 1787 | int |
1788 | bfad_iocmd_diag_cfg_dport(struct bfad_s *bfad, unsigned int cmd, void *pcmd) | 1788 | bfad_iocmd_diag_dport_enable(struct bfad_s *bfad, void *pcmd) |
1789 | { | 1789 | { |
1790 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; | 1790 | struct bfa_bsg_dport_enable_s *iocmd = |
1791 | (struct bfa_bsg_dport_enable_s *)pcmd; | ||
1791 | unsigned long flags; | 1792 | unsigned long flags; |
1792 | struct bfad_hal_comp fcomp; | 1793 | struct bfad_hal_comp fcomp; |
1793 | 1794 | ||
1794 | init_completion(&fcomp.comp); | 1795 | init_completion(&fcomp.comp); |
1795 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 1796 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1796 | if (cmd == IOCMD_DIAG_DPORT_ENABLE) | 1797 | iocmd->status = bfa_dport_enable(&bfad->bfa, iocmd->lpcnt, |
1797 | iocmd->status = bfa_dport_enable(&bfad->bfa, | 1798 | iocmd->pat, bfad_hcb_comp, &fcomp); |
1798 | bfad_hcb_comp, &fcomp); | 1799 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
1799 | else if (cmd == IOCMD_DIAG_DPORT_DISABLE) | 1800 | if (iocmd->status != BFA_STATUS_OK) |
1800 | iocmd->status = bfa_dport_disable(&bfad->bfa, | 1801 | bfa_trc(bfad, iocmd->status); |
1801 | bfad_hcb_comp, &fcomp); | ||
1802 | else { | 1802 | else { |
1803 | bfa_trc(bfad, 0); | 1803 | wait_for_completion(&fcomp.comp); |
1804 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 1804 | iocmd->status = fcomp.status; |
1805 | return -EINVAL; | ||
1806 | } | 1805 | } |
1807 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 1806 | return 0; |
1807 | } | ||
1808 | 1808 | ||
1809 | int | ||
1810 | bfad_iocmd_diag_dport_disable(struct bfad_s *bfad, void *pcmd) | ||
1811 | { | ||
1812 | struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; | ||
1813 | unsigned long flags; | ||
1814 | struct bfad_hal_comp fcomp; | ||
1815 | |||
1816 | init_completion(&fcomp.comp); | ||
1817 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1818 | iocmd->status = bfa_dport_disable(&bfad->bfa, bfad_hcb_comp, &fcomp); | ||
1819 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1809 | if (iocmd->status != BFA_STATUS_OK) | 1820 | if (iocmd->status != BFA_STATUS_OK) |
1810 | bfa_trc(bfad, iocmd->status); | 1821 | bfa_trc(bfad, iocmd->status); |
1811 | else { | 1822 | else { |
1812 | wait_for_completion(&fcomp.comp); | 1823 | wait_for_completion(&fcomp.comp); |
1813 | iocmd->status = fcomp.status; | 1824 | iocmd->status = fcomp.status; |
1814 | } | 1825 | } |
1826 | return 0; | ||
1827 | } | ||
1828 | |||
1829 | int | ||
1830 | bfad_iocmd_diag_dport_start(struct bfad_s *bfad, void *pcmd) | ||
1831 | { | ||
1832 | struct bfa_bsg_dport_enable_s *iocmd = | ||
1833 | (struct bfa_bsg_dport_enable_s *)pcmd; | ||
1834 | unsigned long flags; | ||
1835 | struct bfad_hal_comp fcomp; | ||
1836 | |||
1837 | init_completion(&fcomp.comp); | ||
1838 | spin_lock_irqsave(&bfad->bfad_lock, flags); | ||
1839 | iocmd->status = bfa_dport_start(&bfad->bfa, iocmd->lpcnt, | ||
1840 | iocmd->pat, bfad_hcb_comp, | ||
1841 | &fcomp); | ||
1842 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | ||
1843 | |||
1844 | if (iocmd->status != BFA_STATUS_OK) { | ||
1845 | bfa_trc(bfad, iocmd->status); | ||
1846 | } else { | ||
1847 | wait_for_completion(&fcomp.comp); | ||
1848 | iocmd->status = fcomp.status; | ||
1849 | } | ||
1815 | 1850 | ||
1816 | return 0; | 1851 | return 0; |
1817 | } | 1852 | } |
1818 | 1853 | ||
1819 | int | 1854 | int |
1820 | bfad_iocmd_diag_dport_get_state(struct bfad_s *bfad, void *pcmd) | 1855 | bfad_iocmd_diag_dport_show(struct bfad_s *bfad, void *pcmd) |
1821 | { | 1856 | { |
1822 | struct bfa_bsg_diag_dport_get_state_s *iocmd = | 1857 | struct bfa_bsg_diag_dport_show_s *iocmd = |
1823 | (struct bfa_bsg_diag_dport_get_state_s *)pcmd; | 1858 | (struct bfa_bsg_diag_dport_show_s *)pcmd; |
1824 | unsigned long flags; | 1859 | unsigned long flags; |
1825 | 1860 | ||
1826 | spin_lock_irqsave(&bfad->bfad_lock, flags); | 1861 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1827 | iocmd->status = bfa_dport_get_state(&bfad->bfa, &iocmd->state); | 1862 | iocmd->status = bfa_dport_show(&bfad->bfa, &iocmd->result); |
1828 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 1863 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
1829 | 1864 | ||
1830 | return 0; | 1865 | return 0; |
1831 | } | 1866 | } |
1832 | 1867 | ||
1868 | |||
1833 | int | 1869 | int |
1834 | bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd) | 1870 | bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd) |
1835 | { | 1871 | { |
@@ -2934,11 +2970,16 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, | |||
2934 | rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); | 2970 | rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); |
2935 | break; | 2971 | break; |
2936 | case IOCMD_DIAG_DPORT_ENABLE: | 2972 | case IOCMD_DIAG_DPORT_ENABLE: |
2973 | rc = bfad_iocmd_diag_dport_enable(bfad, iocmd); | ||
2974 | break; | ||
2937 | case IOCMD_DIAG_DPORT_DISABLE: | 2975 | case IOCMD_DIAG_DPORT_DISABLE: |
2938 | rc = bfad_iocmd_diag_cfg_dport(bfad, cmd, iocmd); | 2976 | rc = bfad_iocmd_diag_dport_disable(bfad, iocmd); |
2977 | break; | ||
2978 | case IOCMD_DIAG_DPORT_SHOW: | ||
2979 | rc = bfad_iocmd_diag_dport_show(bfad, iocmd); | ||
2939 | break; | 2980 | break; |
2940 | case IOCMD_DIAG_DPORT_GET_STATE: | 2981 | case IOCMD_DIAG_DPORT_START: |
2941 | rc = bfad_iocmd_diag_dport_get_state(bfad, iocmd); | 2982 | rc = bfad_iocmd_diag_dport_start(bfad, iocmd); |
2942 | break; | 2983 | break; |
2943 | case IOCMD_PHY_GET_ATTR: | 2984 | case IOCMD_PHY_GET_ATTR: |
2944 | rc = bfad_iocmd_phy_get_attr(bfad, iocmd); | 2985 | rc = bfad_iocmd_phy_get_attr(bfad, iocmd); |
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h index 612463b60061..3ef321cd7e20 100644 --- a/drivers/scsi/bfa/bfad_bsg.h +++ b/drivers/scsi/bfa/bfad_bsg.h | |||
@@ -144,7 +144,6 @@ enum { | |||
144 | IOCMD_FCPIM_LUNMASK_DELETE, | 144 | IOCMD_FCPIM_LUNMASK_DELETE, |
145 | IOCMD_DIAG_DPORT_ENABLE, | 145 | IOCMD_DIAG_DPORT_ENABLE, |
146 | IOCMD_DIAG_DPORT_DISABLE, | 146 | IOCMD_DIAG_DPORT_DISABLE, |
147 | IOCMD_DIAG_DPORT_GET_STATE, | ||
148 | IOCMD_QOS_SET_BW, | 147 | IOCMD_QOS_SET_BW, |
149 | IOCMD_FCPIM_THROTTLE_QUERY, | 148 | IOCMD_FCPIM_THROTTLE_QUERY, |
150 | IOCMD_FCPIM_THROTTLE_SET, | 149 | IOCMD_FCPIM_THROTTLE_SET, |
@@ -153,6 +152,8 @@ enum { | |||
153 | IOCMD_FRUVPD_READ, | 152 | IOCMD_FRUVPD_READ, |
154 | IOCMD_FRUVPD_UPDATE, | 153 | IOCMD_FRUVPD_UPDATE, |
155 | IOCMD_FRUVPD_GET_MAX_SIZE, | 154 | IOCMD_FRUVPD_GET_MAX_SIZE, |
155 | IOCMD_DIAG_DPORT_SHOW, | ||
156 | IOCMD_DIAG_DPORT_START, | ||
156 | }; | 157 | }; |
157 | 158 | ||
158 | struct bfa_bsg_gen_s { | 159 | struct bfa_bsg_gen_s { |
@@ -593,6 +594,21 @@ struct bfa_bsg_diag_loopback_s { | |||
593 | struct bfa_diag_loopback_result_s result; | 594 | struct bfa_diag_loopback_result_s result; |
594 | }; | 595 | }; |
595 | 596 | ||
597 | struct bfa_bsg_diag_dport_show_s { | ||
598 | bfa_status_t status; | ||
599 | u16 bfad_num; | ||
600 | u16 rsvd; | ||
601 | struct bfa_diag_dport_result_s result; | ||
602 | }; | ||
603 | |||
604 | struct bfa_bsg_dport_enable_s { | ||
605 | bfa_status_t status; | ||
606 | u16 bfad_num; | ||
607 | u16 rsvd; | ||
608 | u16 lpcnt; | ||
609 | u16 pat; | ||
610 | }; | ||
611 | |||
596 | struct bfa_bsg_diag_fwping_s { | 612 | struct bfa_bsg_diag_fwping_s { |
597 | bfa_status_t status; | 613 | bfa_status_t status; |
598 | u16 bfad_num; | 614 | u16 bfad_num; |
@@ -640,13 +656,6 @@ struct bfa_bsg_diag_lb_stat_s { | |||
640 | u16 rsvd; | 656 | u16 rsvd; |
641 | }; | 657 | }; |
642 | 658 | ||
643 | struct bfa_bsg_diag_dport_get_state_s { | ||
644 | bfa_status_t status; | ||
645 | u16 bfad_num; | ||
646 | u16 rsvd; | ||
647 | enum bfa_dport_state state; | ||
648 | }; | ||
649 | |||
650 | struct bfa_bsg_phy_attr_s { | 659 | struct bfa_bsg_phy_attr_s { |
651 | bfa_status_t status; | 660 | bfa_status_t status; |
652 | u16 bfad_num; | 661 | u16 bfad_num; |
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h index 57b146bca18c..e70e0832eafd 100644 --- a/drivers/scsi/bfa/bfi.h +++ b/drivers/scsi/bfa/bfi.h | |||
@@ -973,6 +973,7 @@ enum bfi_diag_i2h { | |||
973 | BFI_DIAG_I2H_LEDTEST = BFA_I2HM(BFI_DIAG_H2I_LEDTEST), | 973 | BFI_DIAG_I2H_LEDTEST = BFA_I2HM(BFI_DIAG_H2I_LEDTEST), |
974 | BFI_DIAG_I2H_QTEST = BFA_I2HM(BFI_DIAG_H2I_QTEST), | 974 | BFI_DIAG_I2H_QTEST = BFA_I2HM(BFI_DIAG_H2I_QTEST), |
975 | BFI_DIAG_I2H_DPORT = BFA_I2HM(BFI_DIAG_H2I_DPORT), | 975 | BFI_DIAG_I2H_DPORT = BFA_I2HM(BFI_DIAG_H2I_DPORT), |
976 | BFI_DIAG_I2H_DPORT_SCN = BFA_I2HM(8), | ||
976 | }; | 977 | }; |
977 | 978 | ||
978 | #define BFI_DIAG_MAX_SGES 2 | 979 | #define BFI_DIAG_MAX_SGES 2 |
@@ -1064,16 +1065,73 @@ struct bfi_diag_qtest_req_s { | |||
1064 | enum bfi_dport_req { | 1065 | enum bfi_dport_req { |
1065 | BFI_DPORT_DISABLE = 0, /* disable dport request */ | 1066 | BFI_DPORT_DISABLE = 0, /* disable dport request */ |
1066 | BFI_DPORT_ENABLE = 1, /* enable dport request */ | 1067 | BFI_DPORT_ENABLE = 1, /* enable dport request */ |
1068 | BFI_DPORT_START = 2, /* start dport request */ | ||
1069 | BFI_DPORT_SHOW = 3, /* show dport request */ | ||
1070 | BFI_DPORT_DYN_DISABLE = 4, /* disable dynamic dport request */ | ||
1071 | }; | ||
1072 | |||
1073 | enum bfi_dport_scn { | ||
1074 | BFI_DPORT_SCN_TESTSTART = 1, | ||
1075 | BFI_DPORT_SCN_TESTCOMP = 2, | ||
1076 | BFI_DPORT_SCN_SFP_REMOVED = 3, | ||
1077 | BFI_DPORT_SCN_DDPORT_ENABLE = 4, | ||
1078 | BFI_DPORT_SCN_DDPORT_DISABLE = 5, | ||
1079 | BFI_DPORT_SCN_FCPORT_DISABLE = 6, | ||
1080 | BFI_DPORT_SCN_SUBTESTSTART = 7, | ||
1081 | BFI_DPORT_SCN_TESTSKIP = 8, | ||
1082 | BFI_DPORT_SCN_DDPORT_DISABLED = 9, | ||
1067 | }; | 1083 | }; |
1068 | 1084 | ||
1069 | struct bfi_diag_dport_req_s { | 1085 | struct bfi_diag_dport_req_s { |
1070 | struct bfi_mhdr_s mh; /* 4 bytes */ | 1086 | struct bfi_mhdr_s mh; /* 4 bytes */ |
1071 | u8 req; /* request 1: enable 0: disable */ | 1087 | u8 req; /* request 1: enable 0: disable */ |
1072 | u8 status; /* reply status */ | 1088 | u8 rsvd[3]; |
1073 | u8 rsvd[2]; | 1089 | u32 lpcnt; |
1074 | u32 msgtag; /* msgtag for reply */ | 1090 | u32 payload; |
1091 | }; | ||
1092 | |||
1093 | struct bfi_diag_dport_rsp_s { | ||
1094 | struct bfi_mhdr_s mh; /* header 4 bytes */ | ||
1095 | bfa_status_t status; /* reply status */ | ||
1096 | wwn_t pwwn; /* switch port wwn. 8 bytes */ | ||
1097 | wwn_t nwwn; /* switch node wwn. 8 bytes */ | ||
1098 | }; | ||
1099 | |||
1100 | struct bfi_diag_dport_scn_teststart_s { | ||
1101 | wwn_t pwwn; /* switch port wwn. 8 bytes */ | ||
1102 | wwn_t nwwn; /* switch node wwn. 8 bytes */ | ||
1103 | u8 type; /* bfa_diag_dport_test_type_e */ | ||
1104 | u8 rsvd[3]; | ||
1105 | u32 numfrm; /* from switch uint in 1M */ | ||
1106 | }; | ||
1107 | |||
1108 | struct bfi_diag_dport_scn_testcomp_s { | ||
1109 | u8 status; /* bfa_diag_dport_test_status_e */ | ||
1110 | u8 speed; /* bfa_port_speed_t */ | ||
1111 | u16 numbuffer; /* from switch */ | ||
1112 | u8 subtest_status[DPORT_TEST_MAX]; /* 4 bytes */ | ||
1113 | u32 latency; /* from switch */ | ||
1114 | u32 distance; /* from swtich unit in meters */ | ||
1115 | /* Buffers required to saturate the link */ | ||
1116 | u16 frm_sz; /* from switch for buf_reqd */ | ||
1117 | u8 rsvd[2]; | ||
1118 | }; | ||
1119 | |||
1120 | struct bfi_diag_dport_scn_s { /* max size == RDS_RMESZ */ | ||
1121 | struct bfi_mhdr_s mh; /* header 4 bytes */ | ||
1122 | u8 state; /* new state */ | ||
1123 | u8 rsvd[3]; | ||
1124 | union { | ||
1125 | struct bfi_diag_dport_scn_teststart_s teststart; | ||
1126 | struct bfi_diag_dport_scn_testcomp_s testcomp; | ||
1127 | } info; | ||
1128 | }; | ||
1129 | |||
1130 | union bfi_diag_dport_msg_u { | ||
1131 | struct bfi_diag_dport_req_s req; | ||
1132 | struct bfi_diag_dport_rsp_s rsp; | ||
1133 | struct bfi_diag_dport_scn_s scn; | ||
1075 | }; | 1134 | }; |
1076 | #define bfi_diag_dport_rsp_t struct bfi_diag_dport_req_s | ||
1077 | 1135 | ||
1078 | /* | 1136 | /* |
1079 | * PHY module specific | 1137 | * PHY module specific |