Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Vijaya Mohan Guvva and committed by
James Bottomley
1a898a79 4e1e0d8d

+784 -92
+68 -11
drivers/scsi/bfa/bfa_defs.h
··· 199 199 BFA_STATUS_DPORT_DISABLED = 236, /* D-port mode is already disabled */ 200 200 BFA_STATUS_CMD_NOTSUPP_MEZZ = 239, /* Cmd not supported for MEZZ card */ 201 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 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 211 BFA_STATUS_ERR_BBCR_SPEED_UNSUPPORT = 258, /*!< BB credit recovery is 204 212 * supported at max port speed alone */ 205 213 BFA_STATUS_ERROR_BBCR_ENABLED = 259, /*!< BB credit recovery 206 214 * is enabled */ 207 215 BFA_STATUS_INVALID_BBSCN = 260, /*!< Invalid BBSCN value. 208 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 222 BFA_STATUS_BBCR_CFG_NO_CHANGE = 265, /*!< BBCR is operational. 210 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 230 BFA_STATUS_MAX_VAL /* Unknown error code */ 212 231 }; 213 232 #define bfa_status_t enum bfa_status ··· 543 524 wwn_t pwwn; 544 525 u16 ioc_type; 545 526 mac_t mac; 546 - }; 547 - 548 - /* 549 - * D-port states 550 - * 551 - */ 552 - enum bfa_dport_state { 553 - BFA_DPORT_ST_DISABLED = 0, /* D-port is Disabled */ 554 - BFA_DPORT_ST_DISABLING = 1, /* D-port is Disabling */ 555 - BFA_DPORT_ST_ENABLING = 2, /* D-port is Enabling */ 556 - BFA_DPORT_ST_ENABLED = 3, /* D-port is Enabled */ 557 527 }; 558 528 559 529 /* ··· 1144 1136 #define LB_PATTERN_DEFAULT 0xB5B5B5B5 1145 1137 #define QTEST_CNT_DEFAULT 10 1146 1138 #define QTEST_PAT_DEFAULT LB_PATTERN_DEFAULT 1139 + #define DPORT_ENABLE_LOOPCNT_DEFAULT (1024 * 1024) 1147 1140 1148 1141 struct bfa_diag_memtest_s { 1149 1142 u8 algo; ··· 1171 1162 u32 badfrmnum; /* mis-match fram number */ 1172 1163 u8 status; /* loopback test result */ 1173 1164 u8 rsvd[3]; 1165 + }; 1166 + 1167 + enum bfa_diag_dport_test_status { 1168 + DPORT_TEST_ST_IDLE = 0, /* the test has not started yet. */ 1169 + DPORT_TEST_ST_FINAL = 1, /* the test done successfully */ 1170 + DPORT_TEST_ST_SKIP = 2, /* the test skipped */ 1171 + DPORT_TEST_ST_FAIL = 3, /* the test failed */ 1172 + DPORT_TEST_ST_INPRG = 4, /* the testing is in progress */ 1173 + DPORT_TEST_ST_RESPONDER = 5, /* test triggered from remote port */ 1174 + DPORT_TEST_ST_STOPPED = 6, /* the test stopped by user. */ 1175 + DPORT_TEST_ST_MAX 1176 + }; 1177 + 1178 + enum bfa_diag_dport_test_type { 1179 + DPORT_TEST_ELOOP = 0, 1180 + DPORT_TEST_OLOOP = 1, 1181 + DPORT_TEST_ROLOOP = 2, 1182 + DPORT_TEST_LINK = 3, 1183 + DPORT_TEST_MAX 1184 + }; 1185 + 1186 + enum bfa_diag_dport_test_opmode { 1187 + BFA_DPORT_OPMODE_AUTO = 0, 1188 + BFA_DPORT_OPMODE_MANU = 1, 1189 + }; 1190 + 1191 + struct bfa_diag_dport_subtest_result_s { 1192 + u8 status; /* bfa_diag_dport_test_status */ 1193 + u8 rsvd[7]; /* 64bit align */ 1194 + u64 start_time; /* timestamp */ 1195 + }; 1196 + 1197 + struct bfa_diag_dport_result_s { 1198 + wwn_t rp_pwwn; /* switch port wwn */ 1199 + wwn_t rp_nwwn; /* switch node wwn */ 1200 + u64 start_time; /* user/sw start time */ 1201 + u64 end_time; /* timestamp */ 1202 + u8 status; /* bfa_diag_dport_test_status */ 1203 + u8 mode; /* bfa_diag_dport_test_opmode */ 1204 + u8 rsvd; /* 64bit align */ 1205 + u8 speed; /* link speed for buf_reqd */ 1206 + u16 buffer_required; 1207 + u16 frmsz; /* frame size for buf_reqd */ 1208 + u32 lpcnt; /* Frame count */ 1209 + u32 pat; /* Pattern */ 1210 + u32 roundtrip_latency; /* in nano sec */ 1211 + u32 est_cable_distance; /* in meter */ 1212 + struct bfa_diag_dport_subtest_result_s subtest[DPORT_TEST_MAX]; 1174 1213 }; 1175 1214 1176 1215 struct bfa_diag_ledtest_s {
+1
drivers/scsi/bfa/bfa_defs_svc.h
··· 761 761 BFA_PORT_ST_TOGGLING_QWAIT = 14, 762 762 BFA_PORT_ST_FAA_MISCONFIG = 15, 763 763 BFA_PORT_ST_DPORT = 16, 764 + BFA_PORT_ST_DDPORT = 17, 764 765 BFA_PORT_ST_MAX_STATE, 765 766 }; 766 767
+556 -41
drivers/scsi/bfa/bfa_svc.c
··· 70 70 BFA_FCPORT_SM_DPORTENABLE = 10, /* enable dport */ 71 71 BFA_FCPORT_SM_DPORTDISABLE = 11,/* disable dport */ 72 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 /* ··· 204 202 enum bfa_fcport_sm_event event); 205 203 static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, 206 204 enum bfa_fcport_sm_event event); 205 + static void bfa_fcport_sm_ddport(struct bfa_fcport_s *fcport, 206 + enum bfa_fcport_sm_event event); 207 207 static void bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport, 208 208 enum bfa_fcport_sm_event event); 209 209 ··· 238 234 {BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN}, 239 235 {BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN}, 240 236 {BFA_SM(bfa_fcport_sm_dport), BFA_PORT_ST_DPORT}, 237 + {BFA_SM(bfa_fcport_sm_ddport), BFA_PORT_ST_DDPORT}, 241 238 {BFA_SM(bfa_fcport_sm_faa_misconfig), BFA_PORT_ST_FAA_MISCONFIG}, 242 239 }; 243 240 ··· 2651 2646 bfa_sm_set_state(fcport, bfa_fcport_sm_dport); 2652 2647 break; 2653 2648 2649 + case BFA_FCPORT_SM_DDPORTENABLE: 2650 + bfa_sm_set_state(fcport, bfa_fcport_sm_ddport); 2651 + break; 2652 + 2654 2653 default: 2655 2654 bfa_sm_fault(fcport->bfa, event); 2656 2655 } ··· 2760 2751 2761 2752 case BFA_FCPORT_SM_DPORTDISABLE: 2762 2753 bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2754 + break; 2755 + 2756 + default: 2757 + bfa_sm_fault(fcport->bfa, event); 2758 + } 2759 + } 2760 + 2761 + static void 2762 + bfa_fcport_sm_ddport(struct bfa_fcport_s *fcport, 2763 + enum bfa_fcport_sm_event event) 2764 + { 2765 + bfa_trc(fcport->bfa, event); 2766 + 2767 + switch (event) { 2768 + case BFA_FCPORT_SM_DISABLE: 2769 + case BFA_FCPORT_SM_DDPORTDISABLE: 2770 + bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); 2771 + break; 2772 + 2773 + case BFA_FCPORT_SM_DPORTENABLE: 2774 + case BFA_FCPORT_SM_DPORTDISABLE: 2775 + case BFA_FCPORT_SM_ENABLE: 2776 + case BFA_FCPORT_SM_START: 2777 + /** 2778 + * Ignore event for a port that is ddport 2779 + */ 2780 + break; 2781 + 2782 + case BFA_FCPORT_SM_STOP: 2783 + bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); 2784 + break; 2785 + 2786 + case BFA_FCPORT_SM_HWFAIL: 2787 + bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); 2763 2788 break; 2764 2789 2765 2790 default: ··· 3903 3860 return BFA_STATUS_LOOP_UNSUPP_MEZZ; 3904 3861 if (bfa_fcport_is_dport(bfa) != BFA_FALSE) 3905 3862 return BFA_STATUS_DPORT_ERR; 3863 + if (bfa_fcport_is_ddport(bfa) != BFA_FALSE) 3864 + return BFA_STATUS_DPORT_ERR; 3906 3865 break; 3907 3866 3908 3867 case BFA_PORT_TOPOLOGY_AUTO: ··· 4172 4127 BFA_PORT_ST_DPORT); 4173 4128 } 4174 4129 4130 + bfa_boolean_t 4131 + bfa_fcport_is_ddport(struct bfa_s *bfa) 4132 + { 4133 + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); 4134 + 4135 + return (bfa_sm_to_state(hal_port_sm_table, fcport->sm) == 4136 + BFA_PORT_ST_DDPORT); 4137 + } 4138 + 4175 4139 bfa_status_t 4176 4140 bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw) 4177 4141 { ··· 4372 4318 */ 4373 4319 bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DPORTDISABLE); 4374 4320 bfa_port_set_dportenabled(&bfa->modules.port, BFA_FALSE); 4321 + } 4322 + 4323 + void 4324 + bfa_fcport_ddportenable(struct bfa_s *bfa) 4325 + { 4326 + /* 4327 + * Assume caller check for port is in disable state 4328 + */ 4329 + bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DDPORTENABLE); 4330 + } 4331 + 4332 + void 4333 + bfa_fcport_ddportdisable(struct bfa_s *bfa) 4334 + { 4335 + /* 4336 + * Assume caller check for port is in disable state 4337 + */ 4338 + bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DDPORTDISABLE); 4375 4339 } 4376 4340 4377 4341 /* ··· 5777 5705 * Dport forward declaration 5778 5706 */ 5779 5707 5708 + enum bfa_dport_test_state_e { 5709 + BFA_DPORT_ST_DISABLED = 0, /*!< dport is disabled */ 5710 + BFA_DPORT_ST_INP = 1, /*!< test in progress */ 5711 + BFA_DPORT_ST_COMP = 2, /*!< test complete successfully */ 5712 + BFA_DPORT_ST_NO_SFP = 3, /*!< sfp is not present */ 5713 + BFA_DPORT_ST_NOTSTART = 4, /*!< test not start dport is enabled */ 5714 + }; 5715 + 5780 5716 /* 5781 5717 * BFA DPORT state machine events 5782 5718 */ ··· 5794 5714 BFA_DPORT_SM_FWRSP = 3, /* fw enable/disable rsp */ 5795 5715 BFA_DPORT_SM_QRESUME = 4, /* CQ space available */ 5796 5716 BFA_DPORT_SM_HWFAIL = 5, /* IOC h/w failure */ 5717 + BFA_DPORT_SM_START = 6, /* re-start dport test */ 5718 + BFA_DPORT_SM_REQFAIL = 7, /* request failure */ 5719 + BFA_DPORT_SM_SCN = 8, /* state change notify frm fw */ 5797 5720 }; 5798 5721 5799 5722 static void bfa_dport_sm_disabled(struct bfa_dport_s *dport, ··· 5811 5728 enum bfa_dport_sm_event event); 5812 5729 static void bfa_dport_sm_disabling(struct bfa_dport_s *dport, 5813 5730 enum bfa_dport_sm_event event); 5731 + static void bfa_dport_sm_starting_qwait(struct bfa_dport_s *dport, 5732 + enum bfa_dport_sm_event event); 5733 + static void bfa_dport_sm_starting(struct bfa_dport_s *dport, 5734 + enum bfa_dport_sm_event event); 5735 + static void bfa_dport_sm_dynamic_disabling(struct bfa_dport_s *dport, 5736 + enum bfa_dport_sm_event event); 5737 + static void bfa_dport_sm_dynamic_disabling_qwait(struct bfa_dport_s *dport, 5738 + enum bfa_dport_sm_event event); 5814 5739 static void bfa_dport_qresume(void *cbarg); 5815 5740 static void bfa_dport_req_comp(struct bfa_dport_s *dport, 5816 - bfi_diag_dport_rsp_t *msg); 5741 + struct bfi_diag_dport_rsp_s *msg); 5742 + static void bfa_dport_scn(struct bfa_dport_s *dport, 5743 + struct bfi_diag_dport_scn_s *msg); 5817 5744 5818 5745 /* 5819 5746 * BFA fcdiag module ··· 5865 5772 bfa_reqq_winit(&dport->reqq_wait, bfa_dport_qresume, dport); 5866 5773 dport->cbfn = NULL; 5867 5774 dport->cbarg = NULL; 5775 + dport->test_state = BFA_DPORT_ST_DISABLED; 5776 + memset(&dport->result, 0, sizeof(struct bfa_diag_dport_result_s)); 5868 5777 } 5869 5778 5870 5779 static void ··· 6069 5974 bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg); 6070 5975 break; 6071 5976 case BFI_DIAG_I2H_DPORT: 6072 - bfa_dport_req_comp(&fcdiag->dport, (bfi_diag_dport_rsp_t *)msg); 5977 + bfa_dport_req_comp(&fcdiag->dport, 5978 + (struct bfi_diag_dport_rsp_s *)msg); 5979 + break; 5980 + case BFI_DIAG_I2H_DPORT_SCN: 5981 + bfa_dport_scn(&fcdiag->dport, 5982 + (struct bfi_diag_dport_scn_s *)msg); 6073 5983 break; 6074 5984 default: 6075 5985 bfa_trc(fcdiag, msg->mhdr.msg_id); ··· 6169 6069 return BFA_STATUS_UNSUPP_SPEED; 6170 6070 } 6171 6071 } 6172 - 6072 + /* check to see if fcport is dport */ 6073 + if (bfa_fcport_is_dport(bfa)) { 6074 + bfa_trc(fcdiag, fcdiag->lb.lock); 6075 + return BFA_STATUS_DPORT_ENABLED; 6076 + } 6173 6077 /* check to see if there is another destructive diag cmd running */ 6174 6078 if (fcdiag->lb.lock) { 6175 6079 bfa_trc(fcdiag, fcdiag->lb.lock); ··· 6277 6173 /* 6278 6174 * D-port 6279 6175 */ 6176 + #define bfa_dport_result_start(__dport, __mode) do { \ 6177 + (__dport)->result.start_time = bfa_get_log_time(); \ 6178 + (__dport)->result.status = DPORT_TEST_ST_INPRG; \ 6179 + (__dport)->result.mode = (__mode); \ 6180 + (__dport)->result.rp_pwwn = (__dport)->rp_pwwn; \ 6181 + (__dport)->result.rp_nwwn = (__dport)->rp_nwwn; \ 6182 + (__dport)->result.lpcnt = (__dport)->lpcnt; \ 6183 + } while (0) 6184 + 6280 6185 static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport, 6281 6186 enum bfi_dport_req req); 6282 6187 static void ··· 6318 6205 6319 6206 case BFA_DPORT_SM_HWFAIL: 6320 6207 /* ignore */ 6208 + break; 6209 + 6210 + case BFA_DPORT_SM_SCN: 6211 + if (dport->i2hmsg.scn.state == BFI_DPORT_SCN_DDPORT_ENABLE) { 6212 + bfa_fcport_ddportenable(dport->bfa); 6213 + dport->dynamic = BFA_TRUE; 6214 + dport->test_state = BFA_DPORT_ST_NOTSTART; 6215 + bfa_sm_set_state(dport, bfa_dport_sm_enabled); 6216 + } else { 6217 + bfa_trc(dport->bfa, dport->i2hmsg.scn.state); 6218 + WARN_ON(1); 6219 + } 6321 6220 break; 6322 6221 6323 6222 default: ··· 6367 6242 6368 6243 switch (event) { 6369 6244 case BFA_DPORT_SM_FWRSP: 6245 + memset(&dport->result, 0, 6246 + sizeof(struct bfa_diag_dport_result_s)); 6247 + if (dport->i2hmsg.rsp.status == BFA_STATUS_DPORT_INV_SFP) { 6248 + dport->test_state = BFA_DPORT_ST_NO_SFP; 6249 + } else { 6250 + dport->test_state = BFA_DPORT_ST_INP; 6251 + bfa_dport_result_start(dport, BFA_DPORT_OPMODE_AUTO); 6252 + } 6370 6253 bfa_sm_set_state(dport, bfa_dport_sm_enabled); 6254 + break; 6255 + 6256 + case BFA_DPORT_SM_REQFAIL: 6257 + dport->test_state = BFA_DPORT_ST_DISABLED; 6258 + bfa_fcport_dportdisable(dport->bfa); 6259 + bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6371 6260 break; 6372 6261 6373 6262 case BFA_DPORT_SM_HWFAIL: ··· 6400 6261 bfa_trc(dport->bfa, event); 6401 6262 6402 6263 switch (event) { 6403 - case BFA_DPORT_SM_ENABLE: 6404 - /* Already enabled */ 6264 + case BFA_DPORT_SM_START: 6265 + if (bfa_dport_send_req(dport, BFI_DPORT_START)) 6266 + bfa_sm_set_state(dport, bfa_dport_sm_starting); 6267 + else 6268 + bfa_sm_set_state(dport, bfa_dport_sm_starting_qwait); 6405 6269 break; 6406 6270 6407 6271 case BFA_DPORT_SM_DISABLE: ··· 6419 6277 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6420 6278 break; 6421 6279 6280 + case BFA_DPORT_SM_SCN: 6281 + switch (dport->i2hmsg.scn.state) { 6282 + case BFI_DPORT_SCN_TESTCOMP: 6283 + dport->test_state = BFA_DPORT_ST_COMP; 6284 + break; 6285 + 6286 + case BFI_DPORT_SCN_TESTSTART: 6287 + dport->test_state = BFA_DPORT_ST_INP; 6288 + break; 6289 + 6290 + case BFI_DPORT_SCN_TESTSKIP: 6291 + case BFI_DPORT_SCN_SUBTESTSTART: 6292 + /* no state change */ 6293 + break; 6294 + 6295 + case BFI_DPORT_SCN_SFP_REMOVED: 6296 + dport->test_state = BFA_DPORT_ST_NO_SFP; 6297 + break; 6298 + 6299 + case BFI_DPORT_SCN_DDPORT_DISABLE: 6300 + bfa_fcport_ddportdisable(dport->bfa); 6301 + 6302 + if (bfa_dport_send_req(dport, BFI_DPORT_DYN_DISABLE)) 6303 + bfa_sm_set_state(dport, 6304 + bfa_dport_sm_dynamic_disabling); 6305 + else 6306 + bfa_sm_set_state(dport, 6307 + bfa_dport_sm_dynamic_disabling_qwait); 6308 + break; 6309 + 6310 + case BFI_DPORT_SCN_FCPORT_DISABLE: 6311 + bfa_fcport_ddportdisable(dport->bfa); 6312 + 6313 + bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6314 + dport->dynamic = BFA_FALSE; 6315 + break; 6316 + 6317 + default: 6318 + bfa_trc(dport->bfa, dport->i2hmsg.scn.state); 6319 + bfa_sm_fault(dport->bfa, event); 6320 + } 6321 + break; 6422 6322 default: 6423 6323 bfa_sm_fault(dport->bfa, event); 6424 6324 } ··· 6484 6300 bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); 6485 6301 break; 6486 6302 6303 + case BFA_DPORT_SM_SCN: 6304 + /* ignore */ 6305 + break; 6306 + 6487 6307 default: 6488 6308 bfa_sm_fault(dport->bfa, event); 6489 6309 } ··· 6500 6312 6501 6313 switch (event) { 6502 6314 case BFA_DPORT_SM_FWRSP: 6315 + dport->test_state = BFA_DPORT_ST_DISABLED; 6503 6316 bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6317 + break; 6318 + 6319 + case BFA_DPORT_SM_HWFAIL: 6320 + bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6321 + bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); 6322 + break; 6323 + 6324 + case BFA_DPORT_SM_SCN: 6325 + /* no state change */ 6326 + break; 6327 + 6328 + default: 6329 + bfa_sm_fault(dport->bfa, event); 6330 + } 6331 + } 6332 + 6333 + static void 6334 + bfa_dport_sm_starting_qwait(struct bfa_dport_s *dport, 6335 + enum bfa_dport_sm_event event) 6336 + { 6337 + bfa_trc(dport->bfa, event); 6338 + 6339 + switch (event) { 6340 + case BFA_DPORT_SM_QRESUME: 6341 + bfa_sm_set_state(dport, bfa_dport_sm_starting); 6342 + bfa_dport_send_req(dport, BFI_DPORT_START); 6343 + break; 6344 + 6345 + case BFA_DPORT_SM_HWFAIL: 6346 + bfa_reqq_wcancel(&dport->reqq_wait); 6347 + bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6348 + bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); 6349 + break; 6350 + 6351 + default: 6352 + bfa_sm_fault(dport->bfa, event); 6353 + } 6354 + } 6355 + 6356 + static void 6357 + bfa_dport_sm_starting(struct bfa_dport_s *dport, enum bfa_dport_sm_event event) 6358 + { 6359 + bfa_trc(dport->bfa, event); 6360 + 6361 + switch (event) { 6362 + case BFA_DPORT_SM_FWRSP: 6363 + memset(&dport->result, 0, 6364 + sizeof(struct bfa_diag_dport_result_s)); 6365 + if (dport->i2hmsg.rsp.status == BFA_STATUS_DPORT_INV_SFP) { 6366 + dport->test_state = BFA_DPORT_ST_NO_SFP; 6367 + } else { 6368 + dport->test_state = BFA_DPORT_ST_INP; 6369 + bfa_dport_result_start(dport, BFA_DPORT_OPMODE_MANU); 6370 + } 6371 + /* fall thru */ 6372 + 6373 + case BFA_DPORT_SM_REQFAIL: 6374 + bfa_sm_set_state(dport, bfa_dport_sm_enabled); 6375 + break; 6376 + 6377 + case BFA_DPORT_SM_HWFAIL: 6378 + bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6379 + bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED); 6380 + break; 6381 + 6382 + default: 6383 + bfa_sm_fault(dport->bfa, event); 6384 + } 6385 + } 6386 + 6387 + static void 6388 + bfa_dport_sm_dynamic_disabling(struct bfa_dport_s *dport, 6389 + enum bfa_dport_sm_event event) 6390 + { 6391 + bfa_trc(dport->bfa, event); 6392 + 6393 + switch (event) { 6394 + case BFA_DPORT_SM_SCN: 6395 + switch (dport->i2hmsg.scn.state) { 6396 + case BFI_DPORT_SCN_DDPORT_DISABLED: 6397 + bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6398 + dport->dynamic = BFA_FALSE; 6399 + bfa_fcport_enable(dport->bfa); 6400 + break; 6401 + 6402 + default: 6403 + bfa_trc(dport->bfa, dport->i2hmsg.scn.state); 6404 + bfa_sm_fault(dport->bfa, event); 6405 + 6406 + } 6504 6407 break; 6505 6408 6506 6409 case BFA_DPORT_SM_HWFAIL: ··· 6604 6325 } 6605 6326 } 6606 6327 6328 + static void 6329 + bfa_dport_sm_dynamic_disabling_qwait(struct bfa_dport_s *dport, 6330 + enum bfa_dport_sm_event event) 6331 + { 6332 + bfa_trc(dport->bfa, event); 6333 + 6334 + switch (event) { 6335 + case BFA_DPORT_SM_QRESUME: 6336 + bfa_sm_set_state(dport, bfa_dport_sm_dynamic_disabling); 6337 + bfa_dport_send_req(dport, BFI_DPORT_DYN_DISABLE); 6338 + break; 6339 + 6340 + case BFA_DPORT_SM_HWFAIL: 6341 + bfa_sm_set_state(dport, bfa_dport_sm_disabled); 6342 + bfa_reqq_wcancel(&dport->reqq_wait); 6343 + bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK); 6344 + break; 6345 + 6346 + case BFA_DPORT_SM_SCN: 6347 + /* ignore */ 6348 + break; 6349 + 6350 + default: 6351 + bfa_sm_fault(dport->bfa, event); 6352 + } 6353 + } 6607 6354 6608 6355 static bfa_boolean_t 6609 6356 bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req) 6610 6357 { 6611 6358 struct bfi_diag_dport_req_s *m; 6612 - 6613 - /* 6614 - * Increment message tag before queue check, so that responses to old 6615 - * requests are discarded. 6616 - */ 6617 - dport->msgtag++; 6618 6359 6619 6360 /* 6620 6361 * check for room in queue to send request now ··· 6648 6349 bfi_h2i_set(m->mh, BFI_MC_DIAG, BFI_DIAG_H2I_DPORT, 6649 6350 bfa_fn_lpu(dport->bfa)); 6650 6351 m->req = req; 6651 - m->msgtag = dport->msgtag; 6352 + if ((req == BFI_DPORT_ENABLE) || (req == BFI_DPORT_START)) { 6353 + m->lpcnt = cpu_to_be32(dport->lpcnt); 6354 + m->payload = cpu_to_be32(dport->payload); 6355 + } 6652 6356 6653 6357 /* 6654 6358 * queue I/O message to firmware ··· 6670 6368 } 6671 6369 6672 6370 static void 6673 - bfa_dport_req_comp(struct bfa_dport_s *dport, bfi_diag_dport_rsp_t *msg) 6371 + bfa_dport_req_comp(struct bfa_dport_s *dport, struct bfi_diag_dport_rsp_s *msg) 6674 6372 { 6675 - bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP); 6373 + msg->status = cpu_to_be32(msg->status); 6374 + dport->i2hmsg.rsp.status = msg->status; 6375 + dport->rp_pwwn = msg->pwwn; 6376 + dport->rp_nwwn = msg->nwwn; 6377 + 6378 + if ((msg->status == BFA_STATUS_OK) || 6379 + (msg->status == BFA_STATUS_DPORT_NO_SFP)) { 6380 + bfa_trc(dport->bfa, msg->status); 6381 + bfa_trc(dport->bfa, dport->rp_pwwn); 6382 + bfa_trc(dport->bfa, dport->rp_nwwn); 6383 + bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP); 6384 + 6385 + } else { 6386 + bfa_trc(dport->bfa, msg->status); 6387 + bfa_sm_send_event(dport, BFA_DPORT_SM_REQFAIL); 6388 + } 6676 6389 bfa_cb_fcdiag_dport(dport, msg->status); 6390 + } 6391 + 6392 + static bfa_boolean_t 6393 + bfa_dport_is_sending_req(struct bfa_dport_s *dport) 6394 + { 6395 + if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || 6396 + bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) || 6397 + bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || 6398 + bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait) || 6399 + bfa_sm_cmp_state(dport, bfa_dport_sm_starting) || 6400 + bfa_sm_cmp_state(dport, bfa_dport_sm_starting_qwait)) { 6401 + return BFA_TRUE; 6402 + } else { 6403 + return BFA_FALSE; 6404 + } 6405 + } 6406 + 6407 + static void 6408 + bfa_dport_scn(struct bfa_dport_s *dport, struct bfi_diag_dport_scn_s *msg) 6409 + { 6410 + int i; 6411 + uint8_t subtesttype; 6412 + 6413 + bfa_trc(dport->bfa, msg->state); 6414 + dport->i2hmsg.scn.state = msg->state; 6415 + 6416 + switch (dport->i2hmsg.scn.state) { 6417 + case BFI_DPORT_SCN_TESTCOMP: 6418 + dport->result.end_time = bfa_get_log_time(); 6419 + bfa_trc(dport->bfa, dport->result.end_time); 6420 + 6421 + dport->result.status = msg->info.testcomp.status; 6422 + bfa_trc(dport->bfa, dport->result.status); 6423 + 6424 + dport->result.roundtrip_latency = 6425 + cpu_to_be32(msg->info.testcomp.latency); 6426 + dport->result.est_cable_distance = 6427 + cpu_to_be32(msg->info.testcomp.distance); 6428 + dport->result.buffer_required = 6429 + be16_to_cpu(msg->info.testcomp.numbuffer); 6430 + 6431 + dport->result.frmsz = be16_to_cpu(msg->info.testcomp.frm_sz); 6432 + dport->result.speed = msg->info.testcomp.speed; 6433 + 6434 + bfa_trc(dport->bfa, dport->result.roundtrip_latency); 6435 + bfa_trc(dport->bfa, dport->result.est_cable_distance); 6436 + bfa_trc(dport->bfa, dport->result.buffer_required); 6437 + bfa_trc(dport->bfa, dport->result.frmsz); 6438 + bfa_trc(dport->bfa, dport->result.speed); 6439 + 6440 + for (i = DPORT_TEST_ELOOP; i < DPORT_TEST_MAX; i++) { 6441 + dport->result.subtest[i].status = 6442 + msg->info.testcomp.subtest_status[i]; 6443 + bfa_trc(dport->bfa, dport->result.subtest[i].status); 6444 + } 6445 + break; 6446 + 6447 + case BFI_DPORT_SCN_TESTSKIP: 6448 + case BFI_DPORT_SCN_DDPORT_ENABLE: 6449 + memset(&dport->result, 0, 6450 + sizeof(struct bfa_diag_dport_result_s)); 6451 + break; 6452 + 6453 + case BFI_DPORT_SCN_TESTSTART: 6454 + memset(&dport->result, 0, 6455 + sizeof(struct bfa_diag_dport_result_s)); 6456 + dport->rp_pwwn = msg->info.teststart.pwwn; 6457 + dport->rp_nwwn = msg->info.teststart.nwwn; 6458 + dport->lpcnt = cpu_to_be32(msg->info.teststart.numfrm); 6459 + bfa_dport_result_start(dport, BFA_DPORT_OPMODE_AUTO); 6460 + break; 6461 + 6462 + case BFI_DPORT_SCN_SUBTESTSTART: 6463 + subtesttype = msg->info.teststart.type; 6464 + dport->result.subtest[subtesttype].start_time = 6465 + bfa_get_log_time(); 6466 + dport->result.subtest[subtesttype].status = 6467 + DPORT_TEST_ST_INPRG; 6468 + 6469 + bfa_trc(dport->bfa, subtesttype); 6470 + bfa_trc(dport->bfa, 6471 + dport->result.subtest[subtesttype].start_time); 6472 + break; 6473 + 6474 + case BFI_DPORT_SCN_SFP_REMOVED: 6475 + case BFI_DPORT_SCN_DDPORT_DISABLED: 6476 + case BFI_DPORT_SCN_DDPORT_DISABLE: 6477 + case BFI_DPORT_SCN_FCPORT_DISABLE: 6478 + dport->result.status = DPORT_TEST_ST_IDLE; 6479 + break; 6480 + 6481 + default: 6482 + bfa_sm_fault(dport->bfa, msg->state); 6483 + } 6484 + 6485 + bfa_sm_send_event(dport, BFA_DPORT_SM_SCN); 6677 6486 } 6678 6487 6679 6488 /* ··· 6793 6380 * @param[in] *bfa - bfa data struct 6794 6381 */ 6795 6382 bfa_status_t 6796 - bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg) 6383 + bfa_dport_enable(struct bfa_s *bfa, u32 lpcnt, u32 pat, 6384 + bfa_cb_diag_t cbfn, void *cbarg) 6797 6385 { 6798 6386 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 6799 6387 struct bfa_dport_s *dport = &fcdiag->dport; ··· 6805 6391 if (bfa_mfg_is_mezz(dport->bfa->ioc.attr->card_type)) { 6806 6392 bfa_trc(dport->bfa, BFA_STATUS_PBC); 6807 6393 return BFA_STATUS_CMD_NOTSUPP_MEZZ; 6394 + } 6395 + 6396 + /* 6397 + * Dport is supported in CT2 or above 6398 + */ 6399 + if (!(bfa_asic_id_ct2(dport->bfa->ioc.pcidev.device_id))) { 6400 + bfa_trc(dport->bfa, dport->bfa->ioc.pcidev.device_id); 6401 + return BFA_STATUS_FEATURE_NOT_SUPPORTED; 6808 6402 } 6809 6403 6810 6404 /* ··· 6853 6431 } 6854 6432 6855 6433 /* 6434 + * Check if diag loopback is running 6435 + */ 6436 + if (bfa_fcdiag_lb_is_running(bfa)) { 6437 + bfa_trc(dport->bfa, 0); 6438 + return BFA_STATUS_DIAG_BUSY; 6439 + } 6440 + 6441 + /* 6856 6442 * Check to see if port is disable or in dport state 6857 6443 */ 6858 6444 if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && ··· 6870 6440 } 6871 6441 6872 6442 /* 6443 + * Check if dport is in dynamic mode 6444 + */ 6445 + if (dport->dynamic) 6446 + return BFA_STATUS_DDPORT_ERR; 6447 + 6448 + /* 6873 6449 * Check if dport is busy 6874 6450 */ 6875 - if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || 6876 - bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) || 6877 - bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || 6878 - bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) { 6451 + if (bfa_dport_is_sending_req(dport)) 6879 6452 return BFA_STATUS_DEVBUSY; 6880 - } 6881 6453 6882 6454 /* 6883 6455 * Check if dport is already enabled ··· 6889 6457 return BFA_STATUS_DPORT_ENABLED; 6890 6458 } 6891 6459 6460 + bfa_trc(dport->bfa, lpcnt); 6461 + bfa_trc(dport->bfa, pat); 6462 + dport->lpcnt = (lpcnt) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT; 6463 + dport->payload = (pat) ? pat : LB_PATTERN_DEFAULT; 6892 6464 dport->cbfn = cbfn; 6893 6465 dport->cbarg = cbarg; 6894 6466 ··· 6921 6485 } 6922 6486 6923 6487 /* 6488 + * Check if dport is in dynamic mode 6489 + */ 6490 + if (dport->dynamic) { 6491 + return BFA_STATUS_DDPORT_ERR; 6492 + } 6493 + 6494 + /* 6924 6495 * Check to see if port is disable or in dport state 6925 6496 */ 6926 6497 if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) && ··· 6939 6496 /* 6940 6497 * Check if dport is busy 6941 6498 */ 6942 - if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || 6943 - bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) || 6944 - bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || 6945 - bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) 6499 + if (bfa_dport_is_sending_req(dport)) 6946 6500 return BFA_STATUS_DEVBUSY; 6947 6501 6948 6502 /* ··· 6958 6518 } 6959 6519 6960 6520 /* 6961 - * Get D-port state 6521 + * Dport start -- restart dport test 6962 6522 * 6963 - * @param[in] *bfa - bfa data struct 6523 + * @param[in] *bfa - bfa data struct 6964 6524 */ 6965 - 6966 6525 bfa_status_t 6967 - bfa_dport_get_state(struct bfa_s *bfa, enum bfa_dport_state *state) 6526 + bfa_dport_start(struct bfa_s *bfa, u32 lpcnt, u32 pat, 6527 + bfa_cb_diag_t cbfn, void *cbarg) 6968 6528 { 6969 6529 struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 6970 6530 struct bfa_dport_s *dport = &fcdiag->dport; 6971 6531 6972 - if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) 6973 - *state = BFA_DPORT_ST_ENABLED; 6974 - else if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) || 6975 - bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait)) 6976 - *state = BFA_DPORT_ST_ENABLING; 6977 - else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled)) 6978 - *state = BFA_DPORT_ST_DISABLED; 6979 - else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) || 6980 - bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) 6981 - *state = BFA_DPORT_ST_DISABLING; 6982 - else { 6983 - bfa_trc(dport->bfa, BFA_STATUS_EINVAL); 6984 - return BFA_STATUS_EINVAL; 6532 + /* 6533 + * Check to see if IOC is down 6534 + */ 6535 + if (!bfa_iocfc_is_operational(bfa)) 6536 + return BFA_STATUS_IOC_NON_OP; 6537 + 6538 + /* 6539 + * Check if dport is in dynamic mode 6540 + */ 6541 + if (dport->dynamic) 6542 + return BFA_STATUS_DDPORT_ERR; 6543 + 6544 + /* 6545 + * Check if dport is busy 6546 + */ 6547 + if (bfa_dport_is_sending_req(dport)) 6548 + return BFA_STATUS_DEVBUSY; 6549 + 6550 + /* 6551 + * Check if dport is in enabled state. 6552 + * Test can only be restart when previous test has completed 6553 + */ 6554 + if (!bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) { 6555 + bfa_trc(dport->bfa, 0); 6556 + return BFA_STATUS_DPORT_DISABLED; 6557 + 6558 + } else { 6559 + if (dport->test_state == BFA_DPORT_ST_NO_SFP) 6560 + return BFA_STATUS_DPORT_INV_SFP; 6561 + 6562 + if (dport->test_state == BFA_DPORT_ST_INP) 6563 + return BFA_STATUS_DEVBUSY; 6564 + 6565 + WARN_ON(dport->test_state != BFA_DPORT_ST_COMP); 6985 6566 } 6567 + 6568 + bfa_trc(dport->bfa, lpcnt); 6569 + bfa_trc(dport->bfa, pat); 6570 + 6571 + dport->lpcnt = (lpcnt) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT; 6572 + dport->payload = (pat) ? pat : LB_PATTERN_DEFAULT; 6573 + 6574 + dport->cbfn = cbfn; 6575 + dport->cbarg = cbarg; 6576 + 6577 + bfa_sm_send_event(dport, BFA_DPORT_SM_START); 6578 + return BFA_STATUS_OK; 6579 + } 6580 + 6581 + /* 6582 + * Dport show -- return dport test result 6583 + * 6584 + * @param[in] *bfa - bfa data struct 6585 + */ 6586 + bfa_status_t 6587 + bfa_dport_show(struct bfa_s *bfa, struct bfa_diag_dport_result_s *result) 6588 + { 6589 + struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa); 6590 + struct bfa_dport_s *dport = &fcdiag->dport; 6591 + 6592 + /* 6593 + * Check to see if IOC is down 6594 + */ 6595 + if (!bfa_iocfc_is_operational(bfa)) 6596 + return BFA_STATUS_IOC_NON_OP; 6597 + 6598 + /* 6599 + * Check if dport is busy 6600 + */ 6601 + if (bfa_dport_is_sending_req(dport)) 6602 + return BFA_STATUS_DEVBUSY; 6603 + 6604 + /* 6605 + * Check if dport is in enabled state. 6606 + */ 6607 + if (!bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) { 6608 + bfa_trc(dport->bfa, 0); 6609 + return BFA_STATUS_DPORT_DISABLED; 6610 + 6611 + } 6612 + 6613 + /* 6614 + * Check if there is SFP 6615 + */ 6616 + if (dport->test_state == BFA_DPORT_ST_NO_SFP) 6617 + return BFA_STATUS_DPORT_INV_SFP; 6618 + 6619 + memcpy(result, &dport->result, sizeof(struct bfa_diag_dport_result_s)); 6620 + 6986 6621 return BFA_STATUS_OK; 6987 6622 }
+16 -5
drivers/scsi/bfa/bfa_svc.h
··· 551 551 enum bfa_port_linkstate event), void *event_cbarg); 552 552 bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa); 553 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 555 bfa_status_t bfa_fcport_set_qos_bw(struct bfa_s *bfa, 555 556 struct bfa_qos_bw_s *qos_bw); 556 557 enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa); ··· 716 715 struct bfa_dport_s { 717 716 struct bfa_s *bfa; /* Back pointer to BFA */ 718 717 bfa_sm_t sm; /* finite state machine */ 719 - u32 msgtag; /* firmware msg tag for reply */ 720 718 struct bfa_reqq_wait_s reqq_wait; 721 719 bfa_cb_diag_t cbfn; 722 720 void *cbarg; 721 + union bfi_diag_dport_msg_u i2hmsg; 722 + u8 test_state; /* enum dport_test_state */ 723 + u8 dynamic; /* boolean_t */ 724 + u8 rsvd[2]; 725 + u32 lpcnt; 726 + u32 payload; /* user defined payload pattern */ 727 + wwn_t rp_pwwn; 728 + wwn_t rp_nwwn; 729 + struct bfa_diag_dport_result_s result; 723 730 }; 724 731 725 732 struct bfa_fcdiag_s { ··· 751 742 u32 queue, struct bfa_diag_qtest_result_s *result, 752 743 bfa_cb_diag_t cbfn, void *cbarg); 753 744 bfa_status_t bfa_fcdiag_lb_is_running(struct bfa_s *bfa); 754 - bfa_status_t bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, 755 - void *cbarg); 745 + bfa_status_t bfa_dport_enable(struct bfa_s *bfa, u32 lpcnt, u32 pat, 746 + bfa_cb_diag_t cbfn, void *cbarg); 756 747 bfa_status_t bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, 757 748 void *cbarg); 758 - bfa_status_t bfa_dport_get_state(struct bfa_s *bfa, 759 - enum bfa_dport_state *state); 749 + bfa_status_t bfa_dport_start(struct bfa_s *bfa, u32 lpcnt, u32 pat, 750 + bfa_cb_diag_t cbfn, void *cbarg); 751 + bfa_status_t bfa_dport_show(struct bfa_s *bfa, 752 + struct bfa_diag_dport_result_s *result); 760 753 761 754 #endif /* __BFA_SVC_H__ */
+63 -22
drivers/scsi/bfa/bfad_bsg.c
··· 1785 1785 } 1786 1786 1787 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 + { 1790 + struct bfa_bsg_dport_enable_s *iocmd = 1791 + (struct bfa_bsg_dport_enable_s *)pcmd; 1792 + unsigned long flags; 1793 + struct bfad_hal_comp fcomp; 1794 + 1795 + init_completion(&fcomp.comp); 1796 + spin_lock_irqsave(&bfad->bfad_lock, flags); 1797 + iocmd->status = bfa_dport_enable(&bfad->bfa, iocmd->lpcnt, 1798 + iocmd->pat, bfad_hcb_comp, &fcomp); 1799 + spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1800 + if (iocmd->status != BFA_STATUS_OK) 1801 + bfa_trc(bfad, iocmd->status); 1802 + else { 1803 + wait_for_completion(&fcomp.comp); 1804 + iocmd->status = fcomp.status; 1805 + } 1806 + return 0; 1807 + } 1808 + 1809 + int 1810 + bfad_iocmd_diag_dport_disable(struct bfad_s *bfad, void *pcmd) 1789 1811 { 1790 1812 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; 1791 1813 unsigned long flags; ··· 1815 1793 1816 1794 init_completion(&fcomp.comp); 1817 1795 spin_lock_irqsave(&bfad->bfad_lock, flags); 1818 - if (cmd == IOCMD_DIAG_DPORT_ENABLE) 1819 - iocmd->status = bfa_dport_enable(&bfad->bfa, 1820 - bfad_hcb_comp, &fcomp); 1821 - else if (cmd == IOCMD_DIAG_DPORT_DISABLE) 1822 - iocmd->status = bfa_dport_disable(&bfad->bfa, 1823 - bfad_hcb_comp, &fcomp); 1824 - else { 1825 - bfa_trc(bfad, 0); 1826 - spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1827 - return -EINVAL; 1828 - } 1796 + iocmd->status = bfa_dport_disable(&bfad->bfa, bfad_hcb_comp, &fcomp); 1829 1797 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1830 - 1831 1798 if (iocmd->status != BFA_STATUS_OK) 1832 1799 bfa_trc(bfad, iocmd->status); 1833 1800 else { 1801 + wait_for_completion(&fcomp.comp); 1802 + iocmd->status = fcomp.status; 1803 + } 1804 + return 0; 1805 + } 1806 + 1807 + int 1808 + bfad_iocmd_diag_dport_start(struct bfad_s *bfad, void *pcmd) 1809 + { 1810 + struct bfa_bsg_dport_enable_s *iocmd = 1811 + (struct bfa_bsg_dport_enable_s *)pcmd; 1812 + unsigned long flags; 1813 + struct bfad_hal_comp fcomp; 1814 + 1815 + init_completion(&fcomp.comp); 1816 + spin_lock_irqsave(&bfad->bfad_lock, flags); 1817 + iocmd->status = bfa_dport_start(&bfad->bfa, iocmd->lpcnt, 1818 + iocmd->pat, bfad_hcb_comp, 1819 + &fcomp); 1820 + spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1821 + 1822 + if (iocmd->status != BFA_STATUS_OK) { 1823 + bfa_trc(bfad, iocmd->status); 1824 + } else { 1834 1825 wait_for_completion(&fcomp.comp); 1835 1826 iocmd->status = fcomp.status; 1836 1827 } ··· 1852 1817 } 1853 1818 1854 1819 int 1855 - bfad_iocmd_diag_dport_get_state(struct bfad_s *bfad, void *pcmd) 1820 + bfad_iocmd_diag_dport_show(struct bfad_s *bfad, void *pcmd) 1856 1821 { 1857 - struct bfa_bsg_diag_dport_get_state_s *iocmd = 1858 - (struct bfa_bsg_diag_dport_get_state_s *)pcmd; 1859 - unsigned long flags; 1822 + struct bfa_bsg_diag_dport_show_s *iocmd = 1823 + (struct bfa_bsg_diag_dport_show_s *)pcmd; 1824 + unsigned long flags; 1860 1825 1861 1826 spin_lock_irqsave(&bfad->bfad_lock, flags); 1862 - iocmd->status = bfa_dport_get_state(&bfad->bfa, &iocmd->state); 1827 + iocmd->status = bfa_dport_show(&bfad->bfa, &iocmd->result); 1863 1828 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1864 1829 1865 1830 return 0; 1866 1831 } 1832 + 1867 1833 1868 1834 int 1869 1835 bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd) ··· 2970 2934 rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); 2971 2935 break; 2972 2936 case IOCMD_DIAG_DPORT_ENABLE: 2973 - case IOCMD_DIAG_DPORT_DISABLE: 2974 - rc = bfad_iocmd_diag_cfg_dport(bfad, cmd, iocmd); 2937 + rc = bfad_iocmd_diag_dport_enable(bfad, iocmd); 2975 2938 break; 2976 - case IOCMD_DIAG_DPORT_GET_STATE: 2977 - rc = bfad_iocmd_diag_dport_get_state(bfad, iocmd); 2939 + case IOCMD_DIAG_DPORT_DISABLE: 2940 + rc = bfad_iocmd_diag_dport_disable(bfad, iocmd); 2941 + break; 2942 + case IOCMD_DIAG_DPORT_SHOW: 2943 + rc = bfad_iocmd_diag_dport_show(bfad, iocmd); 2944 + break; 2945 + case IOCMD_DIAG_DPORT_START: 2946 + rc = bfad_iocmd_diag_dport_start(bfad, iocmd); 2978 2947 break; 2979 2948 case IOCMD_PHY_GET_ATTR: 2980 2949 rc = bfad_iocmd_phy_get_attr(bfad, iocmd);
+17 -8
drivers/scsi/bfa/bfad_bsg.h
··· 144 144 IOCMD_FCPIM_LUNMASK_DELETE, 145 145 IOCMD_DIAG_DPORT_ENABLE, 146 146 IOCMD_DIAG_DPORT_DISABLE, 147 - IOCMD_DIAG_DPORT_GET_STATE, 148 147 IOCMD_QOS_SET_BW, 149 148 IOCMD_FCPIM_THROTTLE_QUERY, 150 149 IOCMD_FCPIM_THROTTLE_SET, ··· 152 153 IOCMD_FRUVPD_READ, 153 154 IOCMD_FRUVPD_UPDATE, 154 155 IOCMD_FRUVPD_GET_MAX_SIZE, 156 + IOCMD_DIAG_DPORT_SHOW, 157 + IOCMD_DIAG_DPORT_START, 155 158 }; 156 159 157 160 struct bfa_bsg_gen_s { ··· 594 593 struct bfa_diag_loopback_result_s result; 595 594 }; 596 595 596 + struct bfa_bsg_diag_dport_show_s { 597 + bfa_status_t status; 598 + u16 bfad_num; 599 + u16 rsvd; 600 + struct bfa_diag_dport_result_s result; 601 + }; 602 + 603 + struct bfa_bsg_dport_enable_s { 604 + bfa_status_t status; 605 + u16 bfad_num; 606 + u16 rsvd; 607 + u16 lpcnt; 608 + u16 pat; 609 + }; 610 + 597 611 struct bfa_bsg_diag_fwping_s { 598 612 bfa_status_t status; 599 613 u16 bfad_num; ··· 654 638 bfa_status_t status; 655 639 u16 bfad_num; 656 640 u16 rsvd; 657 - }; 658 - 659 - struct bfa_bsg_diag_dport_get_state_s { 660 - bfa_status_t status; 661 - u16 bfad_num; 662 - u16 rsvd; 663 - enum bfa_dport_state state; 664 641 }; 665 642 666 643 struct bfa_bsg_phy_attr_s {
+63 -5
drivers/scsi/bfa/bfi.h
··· 973 973 BFI_DIAG_I2H_LEDTEST = BFA_I2HM(BFI_DIAG_H2I_LEDTEST), 974 974 BFI_DIAG_I2H_QTEST = BFA_I2HM(BFI_DIAG_H2I_QTEST), 975 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 979 #define BFI_DIAG_MAX_SGES 2 ··· 1065 1064 enum bfi_dport_req { 1066 1065 BFI_DPORT_DISABLE = 0, /* disable dport request */ 1067 1066 BFI_DPORT_ENABLE = 1, /* enable dport request */ 1067 + BFI_DPORT_START = 2, /* start dport request */ 1068 + BFI_DPORT_SHOW = 3, /* show dport request */ 1069 + BFI_DPORT_DYN_DISABLE = 4, /* disable dynamic dport request */ 1070 + }; 1071 + 1072 + enum bfi_dport_scn { 1073 + BFI_DPORT_SCN_TESTSTART = 1, 1074 + BFI_DPORT_SCN_TESTCOMP = 2, 1075 + BFI_DPORT_SCN_SFP_REMOVED = 3, 1076 + BFI_DPORT_SCN_DDPORT_ENABLE = 4, 1077 + BFI_DPORT_SCN_DDPORT_DISABLE = 5, 1078 + BFI_DPORT_SCN_FCPORT_DISABLE = 6, 1079 + BFI_DPORT_SCN_SUBTESTSTART = 7, 1080 + BFI_DPORT_SCN_TESTSKIP = 8, 1081 + BFI_DPORT_SCN_DDPORT_DISABLED = 9, 1068 1082 }; 1069 1083 1070 1084 struct bfi_diag_dport_req_s { 1071 1085 struct bfi_mhdr_s mh; /* 4 bytes */ 1072 - u8 req; /* request 1: enable 0: disable */ 1073 - u8 status; /* reply status */ 1074 - u8 rsvd[2]; 1075 - u32 msgtag; /* msgtag for reply */ 1086 + u8 req; /* request 1: enable 0: disable */ 1087 + u8 rsvd[3]; 1088 + u32 lpcnt; 1089 + u32 payload; 1076 1090 }; 1077 - #define bfi_diag_dport_rsp_t struct bfi_diag_dport_req_s 1091 + 1092 + struct bfi_diag_dport_rsp_s { 1093 + struct bfi_mhdr_s mh; /* header 4 bytes */ 1094 + bfa_status_t status; /* reply status */ 1095 + wwn_t pwwn; /* switch port wwn. 8 bytes */ 1096 + wwn_t nwwn; /* switch node wwn. 8 bytes */ 1097 + }; 1098 + 1099 + struct bfi_diag_dport_scn_teststart_s { 1100 + wwn_t pwwn; /* switch port wwn. 8 bytes */ 1101 + wwn_t nwwn; /* switch node wwn. 8 bytes */ 1102 + u8 type; /* bfa_diag_dport_test_type_e */ 1103 + u8 rsvd[3]; 1104 + u32 numfrm; /* from switch uint in 1M */ 1105 + }; 1106 + 1107 + struct bfi_diag_dport_scn_testcomp_s { 1108 + u8 status; /* bfa_diag_dport_test_status_e */ 1109 + u8 speed; /* bfa_port_speed_t */ 1110 + u16 numbuffer; /* from switch */ 1111 + u8 subtest_status[DPORT_TEST_MAX]; /* 4 bytes */ 1112 + u32 latency; /* from switch */ 1113 + u32 distance; /* from swtich unit in meters */ 1114 + /* Buffers required to saturate the link */ 1115 + u16 frm_sz; /* from switch for buf_reqd */ 1116 + u8 rsvd[2]; 1117 + }; 1118 + 1119 + struct bfi_diag_dport_scn_s { /* max size == RDS_RMESZ */ 1120 + struct bfi_mhdr_s mh; /* header 4 bytes */ 1121 + u8 state; /* new state */ 1122 + u8 rsvd[3]; 1123 + union { 1124 + struct bfi_diag_dport_scn_teststart_s teststart; 1125 + struct bfi_diag_dport_scn_testcomp_s testcomp; 1126 + } info; 1127 + }; 1128 + 1129 + union bfi_diag_dport_msg_u { 1130 + struct bfi_diag_dport_req_s req; 1131 + struct bfi_diag_dport_rsp_s rsp; 1132 + struct bfi_diag_dport_scn_s scn; 1133 + }; 1078 1134 1079 1135 /* 1080 1136 * PHY module specific