|
@@ -70,6 +70,8 @@ enum bfa_fcport_sm_event {
|
|
|
BFA_FCPORT_SM_DPORTENABLE = 10, /* enable dport */
|
|
|
BFA_FCPORT_SM_DPORTDISABLE = 11,/* disable dport */
|
|
|
BFA_FCPORT_SM_FAA_MISCONFIG = 12, /* FAA misconfiguratin */
|
|
|
+ BFA_FCPORT_SM_DDPORTENABLE = 13, /* enable ddport */
|
|
|
+ BFA_FCPORT_SM_DDPORTDISABLE = 14, /* disable ddport */
|
|
|
};
|
|
|
|
|
|
/*
|
|
@@ -202,6 +204,8 @@ static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
|
|
|
enum bfa_fcport_sm_event event);
|
|
|
static void bfa_fcport_sm_dport(struct bfa_fcport_s *fcport,
|
|
|
enum bfa_fcport_sm_event event);
|
|
|
+static void bfa_fcport_sm_ddport(struct bfa_fcport_s *fcport,
|
|
|
+ enum bfa_fcport_sm_event event);
|
|
|
static void bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport,
|
|
|
enum bfa_fcport_sm_event event);
|
|
|
|
|
@@ -234,6 +238,7 @@ static struct bfa_sm_table_s hal_port_sm_table[] = {
|
|
|
{BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN},
|
|
|
{BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN},
|
|
|
{BFA_SM(bfa_fcport_sm_dport), BFA_PORT_ST_DPORT},
|
|
|
+ {BFA_SM(bfa_fcport_sm_ddport), BFA_PORT_ST_DDPORT},
|
|
|
{BFA_SM(bfa_fcport_sm_faa_misconfig), BFA_PORT_ST_FAA_MISCONFIG},
|
|
|
};
|
|
|
|
|
@@ -1276,7 +1281,6 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
|
|
|
|
|
|
switch (event) {
|
|
|
case BFA_LPS_SM_FWRSP:
|
|
|
- case BFA_LPS_SM_OFFLINE:
|
|
|
if (lps->status == BFA_STATUS_OK) {
|
|
|
bfa_sm_set_state(lps, bfa_lps_sm_online);
|
|
|
if (lps->fdisc)
|
|
@@ -1305,6 +1309,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
|
|
|
bfa_lps_login_comp(lps);
|
|
|
break;
|
|
|
|
|
|
+ case BFA_LPS_SM_OFFLINE:
|
|
|
case BFA_LPS_SM_DELETE:
|
|
|
bfa_sm_set_state(lps, bfa_lps_sm_init);
|
|
|
break;
|
|
@@ -1614,7 +1619,6 @@ bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp)
|
|
|
lps->lp_mac = rsp->lp_mac;
|
|
|
lps->brcd_switch = rsp->brcd_switch;
|
|
|
lps->fcf_mac = rsp->fcf_mac;
|
|
|
- lps->pr_bbscn = rsp->bb_scn;
|
|
|
|
|
|
break;
|
|
|
|
|
@@ -1744,7 +1748,6 @@ bfa_lps_send_login(struct bfa_lps_s *lps)
|
|
|
m->nwwn = lps->nwwn;
|
|
|
m->fdisc = lps->fdisc;
|
|
|
m->auth_en = lps->auth_en;
|
|
|
- m->bb_scn = lps->bb_scn;
|
|
|
|
|
|
bfa_reqq_produce(lps->bfa, lps->reqq, m->mh);
|
|
|
list_del(&lps->qe);
|
|
@@ -1940,7 +1943,7 @@ bfa_lps_delete(struct bfa_lps_s *lps)
|
|
|
*/
|
|
|
void
|
|
|
bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz,
|
|
|
- wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en, uint8_t bb_scn)
|
|
|
+ wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en)
|
|
|
{
|
|
|
lps->uarg = uarg;
|
|
|
lps->alpa = alpa;
|
|
@@ -1949,7 +1952,6 @@ bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz,
|
|
|
lps->nwwn = nwwn;
|
|
|
lps->fdisc = BFA_FALSE;
|
|
|
lps->auth_en = auth_en;
|
|
|
- lps->bb_scn = bb_scn;
|
|
|
bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
|
|
|
}
|
|
|
|
|
@@ -2649,6 +2651,10 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
|
|
|
bfa_sm_set_state(fcport, bfa_fcport_sm_dport);
|
|
|
break;
|
|
|
|
|
|
+ case BFA_FCPORT_SM_DDPORTENABLE:
|
|
|
+ bfa_sm_set_state(fcport, bfa_fcport_sm_ddport);
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
bfa_sm_fault(fcport->bfa, event);
|
|
|
}
|
|
@@ -2761,6 +2767,40 @@ bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+bfa_fcport_sm_ddport(struct bfa_fcport_s *fcport,
|
|
|
+ enum bfa_fcport_sm_event event)
|
|
|
+{
|
|
|
+ bfa_trc(fcport->bfa, event);
|
|
|
+
|
|
|
+ switch (event) {
|
|
|
+ case BFA_FCPORT_SM_DISABLE:
|
|
|
+ case BFA_FCPORT_SM_DDPORTDISABLE:
|
|
|
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFA_FCPORT_SM_DPORTENABLE:
|
|
|
+ case BFA_FCPORT_SM_DPORTDISABLE:
|
|
|
+ case BFA_FCPORT_SM_ENABLE:
|
|
|
+ case BFA_FCPORT_SM_START:
|
|
|
+ /**
|
|
|
+ * Ignore event for a port that is ddport
|
|
|
+ */
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFA_FCPORT_SM_STOP:
|
|
|
+ bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFA_FCPORT_SM_HWFAIL:
|
|
|
+ bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ bfa_sm_fault(fcport->bfa, event);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport,
|
|
|
enum bfa_fcport_sm_event event)
|
|
@@ -3082,6 +3122,8 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
|
|
|
port_cfg->qos_bw.med = BFA_QOS_BW_MED;
|
|
|
port_cfg->qos_bw.low = BFA_QOS_BW_LOW;
|
|
|
|
|
|
+ fcport->fec_state = BFA_FEC_OFFLINE;
|
|
|
+
|
|
|
INIT_LIST_HEAD(&fcport->stats_pending_q);
|
|
|
INIT_LIST_HEAD(&fcport->statsclr_pending_q);
|
|
|
|
|
@@ -3158,6 +3200,11 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
|
|
|
fcport->qos_attr = pevent->link_state.qos_attr;
|
|
|
fcport->qos_vc_attr = pevent->link_state.attr.vc_fcf.qos_vc_attr;
|
|
|
|
|
|
+ if (fcport->cfg.bb_cr_enabled)
|
|
|
+ fcport->bbcr_attr = pevent->link_state.attr.bbcr_attr;
|
|
|
+
|
|
|
+ fcport->fec_state = pevent->link_state.fec_state;
|
|
|
+
|
|
|
/*
|
|
|
* update trunk state if applicable
|
|
|
*/
|
|
@@ -3177,7 +3224,7 @@ bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport)
|
|
|
{
|
|
|
fcport->speed = BFA_PORT_SPEED_UNKNOWN;
|
|
|
fcport->topology = BFA_PORT_TOPOLOGY_NONE;
|
|
|
- fcport->bbsc_op_state = BFA_FALSE;
|
|
|
+ fcport->fec_state = BFA_FEC_OFFLINE;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -3629,6 +3676,11 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
|
|
|
fcport->qos_attr.qos_bw_op =
|
|
|
i2hmsg.penable_rsp->port_cfg.qos_bw;
|
|
|
|
|
|
+ if (fcport->cfg.bb_cr_enabled)
|
|
|
+ fcport->bbcr_attr.state = BFA_BBCR_OFFLINE;
|
|
|
+ else
|
|
|
+ fcport->bbcr_attr.state = BFA_BBCR_DISABLED;
|
|
|
+
|
|
|
bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
|
|
|
}
|
|
|
break;
|
|
@@ -3639,6 +3691,11 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
|
|
|
break;
|
|
|
|
|
|
case BFI_FCPORT_I2H_EVENT:
|
|
|
+ if (fcport->cfg.bb_cr_enabled)
|
|
|
+ fcport->bbcr_attr.state = BFA_BBCR_OFFLINE;
|
|
|
+ else
|
|
|
+ fcport->bbcr_attr.state = BFA_BBCR_DISABLED;
|
|
|
+
|
|
|
if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP)
|
|
|
bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP);
|
|
|
else {
|
|
@@ -3846,6 +3903,8 @@ bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology)
|
|
|
return BFA_STATUS_LOOP_UNSUPP_MEZZ;
|
|
|
if (bfa_fcport_is_dport(bfa) != BFA_FALSE)
|
|
|
return BFA_STATUS_DPORT_ERR;
|
|
|
+ if (bfa_fcport_is_ddport(bfa) != BFA_FALSE)
|
|
|
+ return BFA_STATUS_DPORT_ERR;
|
|
|
break;
|
|
|
|
|
|
case BFA_PORT_TOPOLOGY_AUTO:
|
|
@@ -3964,14 +4023,11 @@ bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
|
|
|
}
|
|
|
|
|
|
void
|
|
|
-bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn)
|
|
|
+bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
|
|
|
{
|
|
|
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
|
|
|
|
|
|
fcport->cfg.tx_bbcredit = (u8)tx_bbcredit;
|
|
|
- fcport->cfg.bb_scn = bb_scn;
|
|
|
- if (bb_scn)
|
|
|
- fcport->bbsc_op_state = BFA_TRUE;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -4021,7 +4077,8 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
|
|
|
attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
|
|
|
attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
|
|
|
attr->port_state = bfa_sm_to_state(hal_port_sm_table, fcport->sm);
|
|
|
- attr->bbsc_op_status = fcport->bbsc_op_state;
|
|
|
+
|
|
|
+ attr->fec_state = fcport->fec_state;
|
|
|
|
|
|
/* PBC Disabled State */
|
|
|
if (bfa_fcport_is_pbcdisabled(bfa))
|
|
@@ -4115,6 +4172,15 @@ bfa_fcport_is_dport(struct bfa_s *bfa)
|
|
|
BFA_PORT_ST_DPORT);
|
|
|
}
|
|
|
|
|
|
+bfa_boolean_t
|
|
|
+bfa_fcport_is_ddport(struct bfa_s *bfa)
|
|
|
+{
|
|
|
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
|
|
|
+
|
|
|
+ return (bfa_sm_to_state(hal_port_sm_table, fcport->sm) ==
|
|
|
+ BFA_PORT_ST_DDPORT);
|
|
|
+}
|
|
|
+
|
|
|
bfa_status_t
|
|
|
bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw)
|
|
|
{
|
|
@@ -4217,6 +4283,77 @@ bfa_fcport_is_trunk_enabled(struct bfa_s *bfa)
|
|
|
return fcport->cfg.trunked;
|
|
|
}
|
|
|
|
|
|
+bfa_status_t
|
|
|
+bfa_fcport_cfg_bbcr(struct bfa_s *bfa, bfa_boolean_t on_off, u8 bb_scn)
|
|
|
+{
|
|
|
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
|
|
|
+
|
|
|
+ bfa_trc(bfa, on_off);
|
|
|
+
|
|
|
+ if (bfa_ioc_get_type(&fcport->bfa->ioc) != BFA_IOC_TYPE_FC)
|
|
|
+ return BFA_STATUS_BBCR_FC_ONLY;
|
|
|
+
|
|
|
+ if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type) &&
|
|
|
+ (bfa->ioc.attr->card_type != BFA_MFG_TYPE_CHINOOK))
|
|
|
+ return BFA_STATUS_CMD_NOTSUPP_MEZZ;
|
|
|
+
|
|
|
+ if (on_off) {
|
|
|
+ if (fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP)
|
|
|
+ return BFA_STATUS_TOPOLOGY_LOOP;
|
|
|
+
|
|
|
+ if (fcport->cfg.qos_enabled)
|
|
|
+ return BFA_STATUS_ERROR_QOS_ENABLED;
|
|
|
+
|
|
|
+ if (fcport->cfg.trunked)
|
|
|
+ return BFA_STATUS_TRUNK_ENABLED;
|
|
|
+
|
|
|
+ if ((fcport->cfg.speed != BFA_PORT_SPEED_AUTO) &&
|
|
|
+ (fcport->cfg.speed < bfa_ioc_speed_sup(&bfa->ioc)))
|
|
|
+ return BFA_STATUS_ERR_BBCR_SPEED_UNSUPPORT;
|
|
|
+
|
|
|
+ if (bfa_ioc_speed_sup(&bfa->ioc) < BFA_PORT_SPEED_8GBPS)
|
|
|
+ return BFA_STATUS_FEATURE_NOT_SUPPORTED;
|
|
|
+
|
|
|
+ if (fcport->cfg.bb_cr_enabled) {
|
|
|
+ if (bb_scn != fcport->cfg.bb_scn)
|
|
|
+ return BFA_STATUS_BBCR_CFG_NO_CHANGE;
|
|
|
+ else
|
|
|
+ return BFA_STATUS_NO_CHANGE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((bb_scn == 0) || (bb_scn > BFA_BB_SCN_MAX))
|
|
|
+ bb_scn = BFA_BB_SCN_DEF;
|
|
|
+
|
|
|
+ fcport->cfg.bb_cr_enabled = on_off;
|
|
|
+ fcport->cfg.bb_scn = bb_scn;
|
|
|
+ } else {
|
|
|
+ if (!fcport->cfg.bb_cr_enabled)
|
|
|
+ return BFA_STATUS_NO_CHANGE;
|
|
|
+
|
|
|
+ fcport->cfg.bb_cr_enabled = on_off;
|
|
|
+ fcport->cfg.bb_scn = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return BFA_STATUS_OK;
|
|
|
+}
|
|
|
+
|
|
|
+bfa_status_t
|
|
|
+bfa_fcport_get_bbcr_attr(struct bfa_s *bfa,
|
|
|
+ struct bfa_bbcr_attr_s *bbcr_attr)
|
|
|
+{
|
|
|
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
|
|
|
+
|
|
|
+ if (bfa_ioc_get_type(&fcport->bfa->ioc) != BFA_IOC_TYPE_FC)
|
|
|
+ return BFA_STATUS_BBCR_FC_ONLY;
|
|
|
+
|
|
|
+ if (fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP)
|
|
|
+ return BFA_STATUS_TOPOLOGY_LOOP;
|
|
|
+
|
|
|
+ *bbcr_attr = fcport->bbcr_attr;
|
|
|
+
|
|
|
+ return BFA_STATUS_OK;
|
|
|
+}
|
|
|
+
|
|
|
void
|
|
|
bfa_fcport_dportenable(struct bfa_s *bfa)
|
|
|
{
|
|
@@ -4237,6 +4374,24 @@ bfa_fcport_dportdisable(struct bfa_s *bfa)
|
|
|
bfa_port_set_dportenabled(&bfa->modules.port, BFA_FALSE);
|
|
|
}
|
|
|
|
|
|
+void
|
|
|
+bfa_fcport_ddportenable(struct bfa_s *bfa)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Assume caller check for port is in disable state
|
|
|
+ */
|
|
|
+ bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DDPORTENABLE);
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+bfa_fcport_ddportdisable(struct bfa_s *bfa)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Assume caller check for port is in disable state
|
|
|
+ */
|
|
|
+ bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DDPORTDISABLE);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Rport State machine functions
|
|
|
*/
|
|
@@ -5622,6 +5777,14 @@ bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw)
|
|
|
* Dport forward declaration
|
|
|
*/
|
|
|
|
|
|
+enum bfa_dport_test_state_e {
|
|
|
+ BFA_DPORT_ST_DISABLED = 0, /*!< dport is disabled */
|
|
|
+ BFA_DPORT_ST_INP = 1, /*!< test in progress */
|
|
|
+ BFA_DPORT_ST_COMP = 2, /*!< test complete successfully */
|
|
|
+ BFA_DPORT_ST_NO_SFP = 3, /*!< sfp is not present */
|
|
|
+ BFA_DPORT_ST_NOTSTART = 4, /*!< test not start dport is enabled */
|
|
|
+};
|
|
|
+
|
|
|
/*
|
|
|
* BFA DPORT state machine events
|
|
|
*/
|
|
@@ -5631,6 +5794,9 @@ enum bfa_dport_sm_event {
|
|
|
BFA_DPORT_SM_FWRSP = 3, /* fw enable/disable rsp */
|
|
|
BFA_DPORT_SM_QRESUME = 4, /* CQ space available */
|
|
|
BFA_DPORT_SM_HWFAIL = 5, /* IOC h/w failure */
|
|
|
+ BFA_DPORT_SM_START = 6, /* re-start dport test */
|
|
|
+ BFA_DPORT_SM_REQFAIL = 7, /* request failure */
|
|
|
+ BFA_DPORT_SM_SCN = 8, /* state change notify frm fw */
|
|
|
};
|
|
|
|
|
|
static void bfa_dport_sm_disabled(struct bfa_dport_s *dport,
|
|
@@ -5645,9 +5811,19 @@ static void bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport,
|
|
|
enum bfa_dport_sm_event event);
|
|
|
static void bfa_dport_sm_disabling(struct bfa_dport_s *dport,
|
|
|
enum bfa_dport_sm_event event);
|
|
|
+static void bfa_dport_sm_starting_qwait(struct bfa_dport_s *dport,
|
|
|
+ enum bfa_dport_sm_event event);
|
|
|
+static void bfa_dport_sm_starting(struct bfa_dport_s *dport,
|
|
|
+ enum bfa_dport_sm_event event);
|
|
|
+static void bfa_dport_sm_dynamic_disabling(struct bfa_dport_s *dport,
|
|
|
+ enum bfa_dport_sm_event event);
|
|
|
+static void bfa_dport_sm_dynamic_disabling_qwait(struct bfa_dport_s *dport,
|
|
|
+ enum bfa_dport_sm_event event);
|
|
|
static void bfa_dport_qresume(void *cbarg);
|
|
|
static void bfa_dport_req_comp(struct bfa_dport_s *dport,
|
|
|
- bfi_diag_dport_rsp_t *msg);
|
|
|
+ struct bfi_diag_dport_rsp_s *msg);
|
|
|
+static void bfa_dport_scn(struct bfa_dport_s *dport,
|
|
|
+ struct bfi_diag_dport_scn_s *msg);
|
|
|
|
|
|
/*
|
|
|
* BFA fcdiag module
|
|
@@ -5689,6 +5865,8 @@ bfa_fcdiag_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
|
|
|
bfa_reqq_winit(&dport->reqq_wait, bfa_dport_qresume, dport);
|
|
|
dport->cbfn = NULL;
|
|
|
dport->cbarg = NULL;
|
|
|
+ dport->test_state = BFA_DPORT_ST_DISABLED;
|
|
|
+ memset(&dport->result, 0, sizeof(struct bfa_diag_dport_result_s));
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -5891,7 +6069,12 @@ bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg)
|
|
|
bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg);
|
|
|
break;
|
|
|
case BFI_DIAG_I2H_DPORT:
|
|
|
- bfa_dport_req_comp(&fcdiag->dport, (bfi_diag_dport_rsp_t *)msg);
|
|
|
+ bfa_dport_req_comp(&fcdiag->dport,
|
|
|
+ (struct bfi_diag_dport_rsp_s *)msg);
|
|
|
+ break;
|
|
|
+ case BFI_DIAG_I2H_DPORT_SCN:
|
|
|
+ bfa_dport_scn(&fcdiag->dport,
|
|
|
+ (struct bfi_diag_dport_scn_s *)msg);
|
|
|
break;
|
|
|
default:
|
|
|
bfa_trc(fcdiag, msg->mhdr.msg_id);
|
|
@@ -5986,7 +6169,11 @@ bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode,
|
|
|
return BFA_STATUS_UNSUPP_SPEED;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+ /* check to see if fcport is dport */
|
|
|
+ if (bfa_fcport_is_dport(bfa)) {
|
|
|
+ bfa_trc(fcdiag, fcdiag->lb.lock);
|
|
|
+ return BFA_STATUS_DPORT_ENABLED;
|
|
|
+ }
|
|
|
/* check to see if there is another destructive diag cmd running */
|
|
|
if (fcdiag->lb.lock) {
|
|
|
bfa_trc(fcdiag, fcdiag->lb.lock);
|
|
@@ -6090,6 +6277,15 @@ bfa_fcdiag_lb_is_running(struct bfa_s *bfa)
|
|
|
/*
|
|
|
* D-port
|
|
|
*/
|
|
|
+#define bfa_dport_result_start(__dport, __mode) do { \
|
|
|
+ (__dport)->result.start_time = bfa_get_log_time(); \
|
|
|
+ (__dport)->result.status = DPORT_TEST_ST_INPRG; \
|
|
|
+ (__dport)->result.mode = (__mode); \
|
|
|
+ (__dport)->result.rp_pwwn = (__dport)->rp_pwwn; \
|
|
|
+ (__dport)->result.rp_nwwn = (__dport)->rp_nwwn; \
|
|
|
+ (__dport)->result.lpcnt = (__dport)->lpcnt; \
|
|
|
+} while (0)
|
|
|
+
|
|
|
static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport,
|
|
|
enum bfi_dport_req req);
|
|
|
static void
|
|
@@ -6124,6 +6320,18 @@ bfa_dport_sm_disabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
|
|
|
/* ignore */
|
|
|
break;
|
|
|
|
|
|
+ case BFA_DPORT_SM_SCN:
|
|
|
+ if (dport->i2hmsg.scn.state == BFI_DPORT_SCN_DDPORT_ENABLE) {
|
|
|
+ bfa_fcport_ddportenable(dport->bfa);
|
|
|
+ dport->dynamic = BFA_TRUE;
|
|
|
+ dport->test_state = BFA_DPORT_ST_NOTSTART;
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_enabled);
|
|
|
+ } else {
|
|
|
+ bfa_trc(dport->bfa, dport->i2hmsg.scn.state);
|
|
|
+ WARN_ON(1);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
bfa_sm_fault(dport->bfa, event);
|
|
|
}
|
|
@@ -6159,9 +6367,23 @@ bfa_dport_sm_enabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
|
|
|
|
|
|
switch (event) {
|
|
|
case BFA_DPORT_SM_FWRSP:
|
|
|
+ memset(&dport->result, 0,
|
|
|
+ sizeof(struct bfa_diag_dport_result_s));
|
|
|
+ if (dport->i2hmsg.rsp.status == BFA_STATUS_DPORT_INV_SFP) {
|
|
|
+ dport->test_state = BFA_DPORT_ST_NO_SFP;
|
|
|
+ } else {
|
|
|
+ dport->test_state = BFA_DPORT_ST_INP;
|
|
|
+ bfa_dport_result_start(dport, BFA_DPORT_OPMODE_AUTO);
|
|
|
+ }
|
|
|
bfa_sm_set_state(dport, bfa_dport_sm_enabled);
|
|
|
break;
|
|
|
|
|
|
+ case BFA_DPORT_SM_REQFAIL:
|
|
|
+ dport->test_state = BFA_DPORT_ST_DISABLED;
|
|
|
+ bfa_fcport_dportdisable(dport->bfa);
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
|
|
|
+ break;
|
|
|
+
|
|
|
case BFA_DPORT_SM_HWFAIL:
|
|
|
bfa_sm_set_state(dport, bfa_dport_sm_disabled);
|
|
|
bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED);
|
|
@@ -6178,8 +6400,11 @@ bfa_dport_sm_enabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
|
|
|
bfa_trc(dport->bfa, event);
|
|
|
|
|
|
switch (event) {
|
|
|
- case BFA_DPORT_SM_ENABLE:
|
|
|
- /* Already enabled */
|
|
|
+ case BFA_DPORT_SM_START:
|
|
|
+ if (bfa_dport_send_req(dport, BFI_DPORT_START))
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_starting);
|
|
|
+ else
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_starting_qwait);
|
|
|
break;
|
|
|
|
|
|
case BFA_DPORT_SM_DISABLE:
|
|
@@ -6194,6 +6419,48 @@ bfa_dport_sm_enabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
|
|
|
bfa_sm_set_state(dport, bfa_dport_sm_disabled);
|
|
|
break;
|
|
|
|
|
|
+ case BFA_DPORT_SM_SCN:
|
|
|
+ switch (dport->i2hmsg.scn.state) {
|
|
|
+ case BFI_DPORT_SCN_TESTCOMP:
|
|
|
+ dport->test_state = BFA_DPORT_ST_COMP;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFI_DPORT_SCN_TESTSTART:
|
|
|
+ dport->test_state = BFA_DPORT_ST_INP;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFI_DPORT_SCN_TESTSKIP:
|
|
|
+ case BFI_DPORT_SCN_SUBTESTSTART:
|
|
|
+ /* no state change */
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFI_DPORT_SCN_SFP_REMOVED:
|
|
|
+ dport->test_state = BFA_DPORT_ST_NO_SFP;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFI_DPORT_SCN_DDPORT_DISABLE:
|
|
|
+ bfa_fcport_ddportdisable(dport->bfa);
|
|
|
+
|
|
|
+ if (bfa_dport_send_req(dport, BFI_DPORT_DYN_DISABLE))
|
|
|
+ bfa_sm_set_state(dport,
|
|
|
+ bfa_dport_sm_dynamic_disabling);
|
|
|
+ else
|
|
|
+ bfa_sm_set_state(dport,
|
|
|
+ bfa_dport_sm_dynamic_disabling_qwait);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFI_DPORT_SCN_FCPORT_DISABLE:
|
|
|
+ bfa_fcport_ddportdisable(dport->bfa);
|
|
|
+
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
|
|
|
+ dport->dynamic = BFA_FALSE;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ bfa_trc(dport->bfa, dport->i2hmsg.scn.state);
|
|
|
+ bfa_sm_fault(dport->bfa, event);
|
|
|
+ }
|
|
|
+ break;
|
|
|
default:
|
|
|
bfa_sm_fault(dport->bfa, event);
|
|
|
}
|
|
@@ -6217,6 +6484,10 @@ bfa_dport_sm_disabling_qwait(struct bfa_dport_s *dport,
|
|
|
bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK);
|
|
|
break;
|
|
|
|
|
|
+ case BFA_DPORT_SM_SCN:
|
|
|
+ /* ignore */
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
bfa_sm_fault(dport->bfa, event);
|
|
|
}
|
|
@@ -6229,7 +6500,98 @@ bfa_dport_sm_disabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
|
|
|
|
|
|
switch (event) {
|
|
|
case BFA_DPORT_SM_FWRSP:
|
|
|
+ dport->test_state = BFA_DPORT_ST_DISABLED;
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFA_DPORT_SM_HWFAIL:
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
|
|
|
+ bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFA_DPORT_SM_SCN:
|
|
|
+ /* no state change */
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ bfa_sm_fault(dport->bfa, event);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+bfa_dport_sm_starting_qwait(struct bfa_dport_s *dport,
|
|
|
+ enum bfa_dport_sm_event event)
|
|
|
+{
|
|
|
+ bfa_trc(dport->bfa, event);
|
|
|
+
|
|
|
+ switch (event) {
|
|
|
+ case BFA_DPORT_SM_QRESUME:
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_starting);
|
|
|
+ bfa_dport_send_req(dport, BFI_DPORT_START);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFA_DPORT_SM_HWFAIL:
|
|
|
+ bfa_reqq_wcancel(&dport->reqq_wait);
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
|
|
|
+ bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ bfa_sm_fault(dport->bfa, event);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+bfa_dport_sm_starting(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
|
|
|
+{
|
|
|
+ bfa_trc(dport->bfa, event);
|
|
|
+
|
|
|
+ switch (event) {
|
|
|
+ case BFA_DPORT_SM_FWRSP:
|
|
|
+ memset(&dport->result, 0,
|
|
|
+ sizeof(struct bfa_diag_dport_result_s));
|
|
|
+ if (dport->i2hmsg.rsp.status == BFA_STATUS_DPORT_INV_SFP) {
|
|
|
+ dport->test_state = BFA_DPORT_ST_NO_SFP;
|
|
|
+ } else {
|
|
|
+ dport->test_state = BFA_DPORT_ST_INP;
|
|
|
+ bfa_dport_result_start(dport, BFA_DPORT_OPMODE_MANU);
|
|
|
+ }
|
|
|
+ /* fall thru */
|
|
|
+
|
|
|
+ case BFA_DPORT_SM_REQFAIL:
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_enabled);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFA_DPORT_SM_HWFAIL:
|
|
|
bfa_sm_set_state(dport, bfa_dport_sm_disabled);
|
|
|
+ bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ bfa_sm_fault(dport->bfa, event);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+bfa_dport_sm_dynamic_disabling(struct bfa_dport_s *dport,
|
|
|
+ enum bfa_dport_sm_event event)
|
|
|
+{
|
|
|
+ bfa_trc(dport->bfa, event);
|
|
|
+
|
|
|
+ switch (event) {
|
|
|
+ case BFA_DPORT_SM_SCN:
|
|
|
+ switch (dport->i2hmsg.scn.state) {
|
|
|
+ case BFI_DPORT_SCN_DDPORT_DISABLED:
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
|
|
|
+ dport->dynamic = BFA_FALSE;
|
|
|
+ bfa_fcport_enable(dport->bfa);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ bfa_trc(dport->bfa, dport->i2hmsg.scn.state);
|
|
|
+ bfa_sm_fault(dport->bfa, event);
|
|
|
+
|
|
|
+ }
|
|
|
break;
|
|
|
|
|
|
case BFA_DPORT_SM_HWFAIL:
|
|
@@ -6242,18 +6604,38 @@ bfa_dport_sm_disabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+bfa_dport_sm_dynamic_disabling_qwait(struct bfa_dport_s *dport,
|
|
|
+ enum bfa_dport_sm_event event)
|
|
|
+{
|
|
|
+ bfa_trc(dport->bfa, event);
|
|
|
+
|
|
|
+ switch (event) {
|
|
|
+ case BFA_DPORT_SM_QRESUME:
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_dynamic_disabling);
|
|
|
+ bfa_dport_send_req(dport, BFI_DPORT_DYN_DISABLE);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFA_DPORT_SM_HWFAIL:
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
|
|
|
+ bfa_reqq_wcancel(&dport->reqq_wait);
|
|
|
+ bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFA_DPORT_SM_SCN:
|
|
|
+ /* ignore */
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ bfa_sm_fault(dport->bfa, event);
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
static bfa_boolean_t
|
|
|
bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req)
|
|
|
{
|
|
|
struct bfi_diag_dport_req_s *m;
|
|
|
|
|
|
- /*
|
|
|
- * Increment message tag before queue check, so that responses to old
|
|
|
- * requests are discarded.
|
|
|
- */
|
|
|
- dport->msgtag++;
|
|
|
-
|
|
|
/*
|
|
|
* check for room in queue to send request now
|
|
|
*/
|
|
@@ -6266,7 +6648,10 @@ bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req)
|
|
|
bfi_h2i_set(m->mh, BFI_MC_DIAG, BFI_DIAG_H2I_DPORT,
|
|
|
bfa_fn_lpu(dport->bfa));
|
|
|
m->req = req;
|
|
|
- m->msgtag = dport->msgtag;
|
|
|
+ if ((req == BFI_DPORT_ENABLE) || (req == BFI_DPORT_START)) {
|
|
|
+ m->lpcnt = cpu_to_be32(dport->lpcnt);
|
|
|
+ m->payload = cpu_to_be32(dport->payload);
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
* queue I/O message to firmware
|
|
@@ -6285,19 +6670,131 @@ bfa_dport_qresume(void *cbarg)
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-bfa_dport_req_comp(struct bfa_dport_s *dport, bfi_diag_dport_rsp_t *msg)
|
|
|
+bfa_dport_req_comp(struct bfa_dport_s *dport, struct bfi_diag_dport_rsp_s *msg)
|
|
|
{
|
|
|
- bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP);
|
|
|
+ msg->status = cpu_to_be32(msg->status);
|
|
|
+ dport->i2hmsg.rsp.status = msg->status;
|
|
|
+ dport->rp_pwwn = msg->pwwn;
|
|
|
+ dport->rp_nwwn = msg->nwwn;
|
|
|
+
|
|
|
+ if ((msg->status == BFA_STATUS_OK) ||
|
|
|
+ (msg->status == BFA_STATUS_DPORT_NO_SFP)) {
|
|
|
+ bfa_trc(dport->bfa, msg->status);
|
|
|
+ bfa_trc(dport->bfa, dport->rp_pwwn);
|
|
|
+ bfa_trc(dport->bfa, dport->rp_nwwn);
|
|
|
+ bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP);
|
|
|
+
|
|
|
+ } else {
|
|
|
+ bfa_trc(dport->bfa, msg->status);
|
|
|
+ bfa_sm_send_event(dport, BFA_DPORT_SM_REQFAIL);
|
|
|
+ }
|
|
|
bfa_cb_fcdiag_dport(dport, msg->status);
|
|
|
}
|
|
|
|
|
|
+static bfa_boolean_t
|
|
|
+bfa_dport_is_sending_req(struct bfa_dport_s *dport)
|
|
|
+{
|
|
|
+ if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) ||
|
|
|
+ bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) ||
|
|
|
+ bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) ||
|
|
|
+ bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait) ||
|
|
|
+ bfa_sm_cmp_state(dport, bfa_dport_sm_starting) ||
|
|
|
+ bfa_sm_cmp_state(dport, bfa_dport_sm_starting_qwait)) {
|
|
|
+ return BFA_TRUE;
|
|
|
+ } else {
|
|
|
+ return BFA_FALSE;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+bfa_dport_scn(struct bfa_dport_s *dport, struct bfi_diag_dport_scn_s *msg)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ uint8_t subtesttype;
|
|
|
+
|
|
|
+ bfa_trc(dport->bfa, msg->state);
|
|
|
+ dport->i2hmsg.scn.state = msg->state;
|
|
|
+
|
|
|
+ switch (dport->i2hmsg.scn.state) {
|
|
|
+ case BFI_DPORT_SCN_TESTCOMP:
|
|
|
+ dport->result.end_time = bfa_get_log_time();
|
|
|
+ bfa_trc(dport->bfa, dport->result.end_time);
|
|
|
+
|
|
|
+ dport->result.status = msg->info.testcomp.status;
|
|
|
+ bfa_trc(dport->bfa, dport->result.status);
|
|
|
+
|
|
|
+ dport->result.roundtrip_latency =
|
|
|
+ cpu_to_be32(msg->info.testcomp.latency);
|
|
|
+ dport->result.est_cable_distance =
|
|
|
+ cpu_to_be32(msg->info.testcomp.distance);
|
|
|
+ dport->result.buffer_required =
|
|
|
+ be16_to_cpu(msg->info.testcomp.numbuffer);
|
|
|
+
|
|
|
+ dport->result.frmsz = be16_to_cpu(msg->info.testcomp.frm_sz);
|
|
|
+ dport->result.speed = msg->info.testcomp.speed;
|
|
|
+
|
|
|
+ bfa_trc(dport->bfa, dport->result.roundtrip_latency);
|
|
|
+ bfa_trc(dport->bfa, dport->result.est_cable_distance);
|
|
|
+ bfa_trc(dport->bfa, dport->result.buffer_required);
|
|
|
+ bfa_trc(dport->bfa, dport->result.frmsz);
|
|
|
+ bfa_trc(dport->bfa, dport->result.speed);
|
|
|
+
|
|
|
+ for (i = DPORT_TEST_ELOOP; i < DPORT_TEST_MAX; i++) {
|
|
|
+ dport->result.subtest[i].status =
|
|
|
+ msg->info.testcomp.subtest_status[i];
|
|
|
+ bfa_trc(dport->bfa, dport->result.subtest[i].status);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFI_DPORT_SCN_TESTSKIP:
|
|
|
+ case BFI_DPORT_SCN_DDPORT_ENABLE:
|
|
|
+ memset(&dport->result, 0,
|
|
|
+ sizeof(struct bfa_diag_dport_result_s));
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFI_DPORT_SCN_TESTSTART:
|
|
|
+ memset(&dport->result, 0,
|
|
|
+ sizeof(struct bfa_diag_dport_result_s));
|
|
|
+ dport->rp_pwwn = msg->info.teststart.pwwn;
|
|
|
+ dport->rp_nwwn = msg->info.teststart.nwwn;
|
|
|
+ dport->lpcnt = cpu_to_be32(msg->info.teststart.numfrm);
|
|
|
+ bfa_dport_result_start(dport, BFA_DPORT_OPMODE_AUTO);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFI_DPORT_SCN_SUBTESTSTART:
|
|
|
+ subtesttype = msg->info.teststart.type;
|
|
|
+ dport->result.subtest[subtesttype].start_time =
|
|
|
+ bfa_get_log_time();
|
|
|
+ dport->result.subtest[subtesttype].status =
|
|
|
+ DPORT_TEST_ST_INPRG;
|
|
|
+
|
|
|
+ bfa_trc(dport->bfa, subtesttype);
|
|
|
+ bfa_trc(dport->bfa,
|
|
|
+ dport->result.subtest[subtesttype].start_time);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFI_DPORT_SCN_SFP_REMOVED:
|
|
|
+ case BFI_DPORT_SCN_DDPORT_DISABLED:
|
|
|
+ case BFI_DPORT_SCN_DDPORT_DISABLE:
|
|
|
+ case BFI_DPORT_SCN_FCPORT_DISABLE:
|
|
|
+ dport->result.status = DPORT_TEST_ST_IDLE;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ bfa_sm_fault(dport->bfa, msg->state);
|
|
|
+ }
|
|
|
+
|
|
|
+ bfa_sm_send_event(dport, BFA_DPORT_SM_SCN);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Dport enable
|
|
|
*
|
|
|
* @param[in] *bfa - bfa data struct
|
|
|
*/
|
|
|
bfa_status_t
|
|
|
-bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
|
|
|
+bfa_dport_enable(struct bfa_s *bfa, u32 lpcnt, u32 pat,
|
|
|
+ bfa_cb_diag_t cbfn, void *cbarg)
|
|
|
{
|
|
|
struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
|
|
|
struct bfa_dport_s *dport = &fcdiag->dport;
|
|
@@ -6310,6 +6807,14 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
|
|
|
return BFA_STATUS_CMD_NOTSUPP_MEZZ;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Dport is supported in CT2 or above
|
|
|
+ */
|
|
|
+ if (!(bfa_asic_id_ct2(dport->bfa->ioc.pcidev.device_id))) {
|
|
|
+ bfa_trc(dport->bfa, dport->bfa->ioc.pcidev.device_id);
|
|
|
+ return BFA_STATUS_FEATURE_NOT_SUPPORTED;
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* Check to see if IOC is down
|
|
|
*/
|
|
@@ -6347,6 +6852,14 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
|
|
|
return BFA_STATUS_ERROR_TRUNK_ENABLED;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Check if diag loopback is running
|
|
|
+ */
|
|
|
+ if (bfa_fcdiag_lb_is_running(bfa)) {
|
|
|
+ bfa_trc(dport->bfa, 0);
|
|
|
+ return BFA_STATUS_DIAG_BUSY;
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* Check to see if port is disable or in dport state
|
|
|
*/
|
|
@@ -6356,15 +6869,17 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
|
|
|
return BFA_STATUS_PORT_NOT_DISABLED;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Check if dport is in dynamic mode
|
|
|
+ */
|
|
|
+ if (dport->dynamic)
|
|
|
+ return BFA_STATUS_DDPORT_ERR;
|
|
|
+
|
|
|
/*
|
|
|
* Check if dport is busy
|
|
|
*/
|
|
|
- if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) ||
|
|
|
- bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) ||
|
|
|
- bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) ||
|
|
|
- bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) {
|
|
|
+ if (bfa_dport_is_sending_req(dport))
|
|
|
return BFA_STATUS_DEVBUSY;
|
|
|
- }
|
|
|
|
|
|
/*
|
|
|
* Check if dport is already enabled
|
|
@@ -6374,6 +6889,10 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
|
|
|
return BFA_STATUS_DPORT_ENABLED;
|
|
|
}
|
|
|
|
|
|
+ bfa_trc(dport->bfa, lpcnt);
|
|
|
+ bfa_trc(dport->bfa, pat);
|
|
|
+ dport->lpcnt = (lpcnt) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT;
|
|
|
+ dport->payload = (pat) ? pat : LB_PATTERN_DEFAULT;
|
|
|
dport->cbfn = cbfn;
|
|
|
dport->cbarg = cbarg;
|
|
|
|
|
@@ -6401,6 +6920,13 @@ bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
|
|
|
return BFA_STATUS_PBC;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Check if dport is in dynamic mode
|
|
|
+ */
|
|
|
+ if (dport->dynamic) {
|
|
|
+ return BFA_STATUS_DDPORT_ERR;
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* Check to see if port is disable or in dport state
|
|
|
*/
|
|
@@ -6413,10 +6939,7 @@ bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
|
|
|
/*
|
|
|
* Check if dport is busy
|
|
|
*/
|
|
|
- if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) ||
|
|
|
- bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) ||
|
|
|
- bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) ||
|
|
|
- bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait))
|
|
|
+ if (bfa_dport_is_sending_req(dport))
|
|
|
return BFA_STATUS_DEVBUSY;
|
|
|
|
|
|
/*
|
|
@@ -6435,30 +6958,105 @@ bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * Get D-port state
|
|
|
+ * Dport start -- restart dport test
|
|
|
*
|
|
|
- * @param[in] *bfa - bfa data struct
|
|
|
+ * @param[in] *bfa - bfa data struct
|
|
|
*/
|
|
|
+bfa_status_t
|
|
|
+bfa_dport_start(struct bfa_s *bfa, u32 lpcnt, u32 pat,
|
|
|
+ bfa_cb_diag_t cbfn, void *cbarg)
|
|
|
+{
|
|
|
+ struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
|
|
|
+ struct bfa_dport_s *dport = &fcdiag->dport;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check to see if IOC is down
|
|
|
+ */
|
|
|
+ if (!bfa_iocfc_is_operational(bfa))
|
|
|
+ return BFA_STATUS_IOC_NON_OP;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if dport is in dynamic mode
|
|
|
+ */
|
|
|
+ if (dport->dynamic)
|
|
|
+ return BFA_STATUS_DDPORT_ERR;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if dport is busy
|
|
|
+ */
|
|
|
+ if (bfa_dport_is_sending_req(dport))
|
|
|
+ return BFA_STATUS_DEVBUSY;
|
|
|
|
|
|
+ /*
|
|
|
+ * Check if dport is in enabled state.
|
|
|
+ * Test can only be restart when previous test has completed
|
|
|
+ */
|
|
|
+ if (!bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) {
|
|
|
+ bfa_trc(dport->bfa, 0);
|
|
|
+ return BFA_STATUS_DPORT_DISABLED;
|
|
|
+
|
|
|
+ } else {
|
|
|
+ if (dport->test_state == BFA_DPORT_ST_NO_SFP)
|
|
|
+ return BFA_STATUS_DPORT_INV_SFP;
|
|
|
+
|
|
|
+ if (dport->test_state == BFA_DPORT_ST_INP)
|
|
|
+ return BFA_STATUS_DEVBUSY;
|
|
|
+
|
|
|
+ WARN_ON(dport->test_state != BFA_DPORT_ST_COMP);
|
|
|
+ }
|
|
|
+
|
|
|
+ bfa_trc(dport->bfa, lpcnt);
|
|
|
+ bfa_trc(dport->bfa, pat);
|
|
|
+
|
|
|
+ dport->lpcnt = (lpcnt) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT;
|
|
|
+ dport->payload = (pat) ? pat : LB_PATTERN_DEFAULT;
|
|
|
+
|
|
|
+ dport->cbfn = cbfn;
|
|
|
+ dport->cbarg = cbarg;
|
|
|
+
|
|
|
+ bfa_sm_send_event(dport, BFA_DPORT_SM_START);
|
|
|
+ return BFA_STATUS_OK;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Dport show -- return dport test result
|
|
|
+ *
|
|
|
+ * @param[in] *bfa - bfa data struct
|
|
|
+ */
|
|
|
bfa_status_t
|
|
|
-bfa_dport_get_state(struct bfa_s *bfa, enum bfa_dport_state *state)
|
|
|
+bfa_dport_show(struct bfa_s *bfa, struct bfa_diag_dport_result_s *result)
|
|
|
{
|
|
|
struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
|
|
|
struct bfa_dport_s *dport = &fcdiag->dport;
|
|
|
|
|
|
- if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled))
|
|
|
- *state = BFA_DPORT_ST_ENABLED;
|
|
|
- else if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) ||
|
|
|
- bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait))
|
|
|
- *state = BFA_DPORT_ST_ENABLING;
|
|
|
- else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled))
|
|
|
- *state = BFA_DPORT_ST_DISABLED;
|
|
|
- else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) ||
|
|
|
- bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait))
|
|
|
- *state = BFA_DPORT_ST_DISABLING;
|
|
|
- else {
|
|
|
- bfa_trc(dport->bfa, BFA_STATUS_EINVAL);
|
|
|
- return BFA_STATUS_EINVAL;
|
|
|
+ /*
|
|
|
+ * Check to see if IOC is down
|
|
|
+ */
|
|
|
+ if (!bfa_iocfc_is_operational(bfa))
|
|
|
+ return BFA_STATUS_IOC_NON_OP;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if dport is busy
|
|
|
+ */
|
|
|
+ if (bfa_dport_is_sending_req(dport))
|
|
|
+ return BFA_STATUS_DEVBUSY;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if dport is in enabled state.
|
|
|
+ */
|
|
|
+ if (!bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) {
|
|
|
+ bfa_trc(dport->bfa, 0);
|
|
|
+ return BFA_STATUS_DPORT_DISABLED;
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if there is SFP
|
|
|
+ */
|
|
|
+ if (dport->test_state == BFA_DPORT_ST_NO_SFP)
|
|
|
+ return BFA_STATUS_DPORT_INV_SFP;
|
|
|
+
|
|
|
+ memcpy(result, &dport->result, sizeof(struct bfa_diag_dport_result_s));
|
|
|
+
|
|
|
return BFA_STATUS_OK;
|
|
|
}
|