|
@@ -67,6 +67,8 @@ enum bfa_fcport_sm_event {
|
|
|
BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */
|
|
|
BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */
|
|
|
BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */
|
|
|
+ BFA_FCPORT_SM_DPORTENABLE = 10, /* enable dport */
|
|
|
+ BFA_FCPORT_SM_DPORTDISABLE = 11,/* disable dport */
|
|
|
};
|
|
|
|
|
|
/*
|
|
@@ -197,6 +199,8 @@ static void bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
|
|
|
enum bfa_fcport_sm_event event);
|
|
|
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_ln_sm_dn(struct bfa_fcport_ln_s *ln,
|
|
|
enum bfa_fcport_ln_sm_event event);
|
|
@@ -226,6 +230,7 @@ static struct bfa_sm_table_s hal_port_sm_table[] = {
|
|
|
{BFA_SM(bfa_fcport_sm_stopped), BFA_PORT_ST_STOPPED},
|
|
|
{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},
|
|
|
};
|
|
|
|
|
|
|
|
@@ -2606,6 +2611,10 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
|
|
|
bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
|
|
|
break;
|
|
|
|
|
|
+ case BFA_FCPORT_SM_DPORTENABLE:
|
|
|
+ bfa_sm_set_state(fcport, bfa_fcport_sm_dport);
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
bfa_sm_fault(fcport->bfa, event);
|
|
|
}
|
|
@@ -2686,6 +2695,38 @@ bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+bfa_fcport_sm_dport(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event)
|
|
|
+{
|
|
|
+ bfa_trc(fcport->bfa, event);
|
|
|
+
|
|
|
+ switch (event) {
|
|
|
+ case BFA_FCPORT_SM_DPORTENABLE:
|
|
|
+ case BFA_FCPORT_SM_DISABLE:
|
|
|
+ case BFA_FCPORT_SM_ENABLE:
|
|
|
+ case BFA_FCPORT_SM_START:
|
|
|
+ /*
|
|
|
+ * Ignore event for a port that is dport
|
|
|
+ */
|
|
|
+ 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;
|
|
|
+
|
|
|
+ case BFA_FCPORT_SM_DPORTDISABLE:
|
|
|
+ bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ bfa_sm_fault(fcport->bfa, event);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Link state is down
|
|
|
*/
|
|
@@ -3707,6 +3748,8 @@ bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology)
|
|
|
return BFA_STATUS_UNSUPP_SPEED;
|
|
|
if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type))
|
|
|
return BFA_STATUS_LOOP_UNSUPP_MEZZ;
|
|
|
+ if (bfa_fcport_is_dport(bfa) != BFA_FALSE)
|
|
|
+ return BFA_STATUS_DPORT_ERR;
|
|
|
break;
|
|
|
|
|
|
case BFA_PORT_TOPOLOGY_AUTO:
|
|
@@ -3962,6 +4005,15 @@ bfa_fcport_is_disabled(struct bfa_s *bfa)
|
|
|
|
|
|
}
|
|
|
|
|
|
+bfa_boolean_t
|
|
|
+bfa_fcport_is_dport(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_DPORT);
|
|
|
+}
|
|
|
+
|
|
|
bfa_boolean_t
|
|
|
bfa_fcport_is_ratelim(struct bfa_s *bfa)
|
|
|
{
|
|
@@ -4039,6 +4091,26 @@ bfa_fcport_is_trunk_enabled(struct bfa_s *bfa)
|
|
|
return fcport->cfg.trunked;
|
|
|
}
|
|
|
|
|
|
+void
|
|
|
+bfa_fcport_dportenable(struct bfa_s *bfa)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Assume caller check for port is in disable state
|
|
|
+ */
|
|
|
+ bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DPORTENABLE);
|
|
|
+ bfa_port_set_dportenabled(&bfa->modules.port, BFA_TRUE);
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+bfa_fcport_dportdisable(struct bfa_s *bfa)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Assume caller check for port is in disable state
|
|
|
+ */
|
|
|
+ bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DPORTDISABLE);
|
|
|
+ bfa_port_set_dportenabled(&bfa->modules.port, BFA_FALSE);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Rport State machine functions
|
|
|
*/
|
|
@@ -5420,6 +5492,37 @@ bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Dport forward declaration
|
|
|
+ */
|
|
|
+
|
|
|
+/*
|
|
|
+ * BFA DPORT state machine events
|
|
|
+ */
|
|
|
+enum bfa_dport_sm_event {
|
|
|
+ BFA_DPORT_SM_ENABLE = 1, /* dport enable event */
|
|
|
+ BFA_DPORT_SM_DISABLE = 2, /* dport disable 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 */
|
|
|
+};
|
|
|
+
|
|
|
+static void bfa_dport_sm_disabled(struct bfa_dport_s *dport,
|
|
|
+ enum bfa_dport_sm_event event);
|
|
|
+static void bfa_dport_sm_enabling_qwait(struct bfa_dport_s *dport,
|
|
|
+ enum bfa_dport_sm_event event);
|
|
|
+static void bfa_dport_sm_enabling(struct bfa_dport_s *dport,
|
|
|
+ enum bfa_dport_sm_event event);
|
|
|
+static void bfa_dport_sm_enabled(struct bfa_dport_s *dport,
|
|
|
+ enum bfa_dport_sm_event event);
|
|
|
+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_qresume(void *cbarg);
|
|
|
+static void bfa_dport_req_comp(struct bfa_dport_s *dport,
|
|
|
+ bfi_diag_dport_rsp_t *msg);
|
|
|
+
|
|
|
/*
|
|
|
* BFA fcdiag module
|
|
|
*/
|
|
@@ -5450,15 +5553,24 @@ bfa_fcdiag_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
|
|
|
struct bfa_pcidev_s *pcidev)
|
|
|
{
|
|
|
struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
|
|
|
+ struct bfa_dport_s *dport = &fcdiag->dport;
|
|
|
+
|
|
|
fcdiag->bfa = bfa;
|
|
|
fcdiag->trcmod = bfa->trcmod;
|
|
|
/* The common DIAG attach bfa_diag_attach() will do all memory claim */
|
|
|
+ dport->bfa = bfa;
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
|
|
|
+ bfa_reqq_winit(&dport->reqq_wait, bfa_dport_qresume, dport);
|
|
|
+ dport->cbfn = NULL;
|
|
|
+ dport->cbarg = NULL;
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
bfa_fcdiag_iocdisable(struct bfa_s *bfa)
|
|
|
{
|
|
|
struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
|
|
|
+ struct bfa_dport_s *dport = &fcdiag->dport;
|
|
|
+
|
|
|
bfa_trc(fcdiag, fcdiag->lb.lock);
|
|
|
if (fcdiag->lb.lock) {
|
|
|
fcdiag->lb.status = BFA_STATUS_IOC_FAILURE;
|
|
@@ -5466,6 +5578,8 @@ bfa_fcdiag_iocdisable(struct bfa_s *bfa)
|
|
|
fcdiag->lb.lock = 0;
|
|
|
bfa_fcdiag_set_busy_status(fcdiag);
|
|
|
}
|
|
|
+
|
|
|
+ bfa_sm_send_event(dport, BFA_DPORT_SM_HWFAIL);
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -5650,6 +5764,9 @@ bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg)
|
|
|
case BFI_DIAG_I2H_QTEST:
|
|
|
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);
|
|
|
+ break;
|
|
|
default:
|
|
|
bfa_trc(fcdiag, msg->mhdr.msg_id);
|
|
|
WARN_ON(1);
|
|
@@ -5719,12 +5836,18 @@ bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * For CT2, 1G is not supported
|
|
|
+ */
|
|
|
+ if ((speed == BFA_PORT_SPEED_1GBPS) &&
|
|
|
+ (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) {
|
|
|
+ bfa_trc(fcdiag, speed);
|
|
|
+ return BFA_STATUS_UNSUPP_SPEED;
|
|
|
+ }
|
|
|
+
|
|
|
/* For Mezz card, port speed entered needs to be checked */
|
|
|
if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) {
|
|
|
if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) {
|
|
|
- if ((speed == BFA_PORT_SPEED_1GBPS) &&
|
|
|
- (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)))
|
|
|
- return BFA_STATUS_UNSUPP_SPEED;
|
|
|
if (!(speed == BFA_PORT_SPEED_1GBPS ||
|
|
|
speed == BFA_PORT_SPEED_2GBPS ||
|
|
|
speed == BFA_PORT_SPEED_4GBPS ||
|
|
@@ -5837,3 +5960,379 @@ bfa_fcdiag_lb_is_running(struct bfa_s *bfa)
|
|
|
struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
|
|
|
return fcdiag->lb.lock ? BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK;
|
|
|
}
|
|
|
+
|
|
|
+/*
|
|
|
+ * D-port
|
|
|
+ */
|
|
|
+static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport,
|
|
|
+ enum bfi_dport_req req);
|
|
|
+static void
|
|
|
+bfa_cb_fcdiag_dport(struct bfa_dport_s *dport, bfa_status_t bfa_status)
|
|
|
+{
|
|
|
+ if (dport->cbfn != NULL) {
|
|
|
+ dport->cbfn(dport->cbarg, bfa_status);
|
|
|
+ dport->cbfn = NULL;
|
|
|
+ dport->cbarg = NULL;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+bfa_dport_sm_disabled(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
|
|
|
+{
|
|
|
+ bfa_trc(dport->bfa, event);
|
|
|
+
|
|
|
+ switch (event) {
|
|
|
+ case BFA_DPORT_SM_ENABLE:
|
|
|
+ bfa_fcport_dportenable(dport->bfa);
|
|
|
+ if (bfa_dport_send_req(dport, BFI_DPORT_ENABLE))
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_enabling);
|
|
|
+ else
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_enabling_qwait);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFA_DPORT_SM_DISABLE:
|
|
|
+ /* Already disabled */
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFA_DPORT_SM_HWFAIL:
|
|
|
+ /* ignore */
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ bfa_sm_fault(dport->bfa, event);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+bfa_dport_sm_enabling_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_enabling);
|
|
|
+ bfa_dport_send_req(dport, BFI_DPORT_ENABLE);
|
|
|
+ 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_enabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
|
|
|
+{
|
|
|
+ bfa_trc(dport->bfa, event);
|
|
|
+
|
|
|
+ switch (event) {
|
|
|
+ case BFA_DPORT_SM_FWRSP:
|
|
|
+ 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_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 */
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFA_DPORT_SM_DISABLE:
|
|
|
+ bfa_fcport_dportdisable(dport->bfa);
|
|
|
+ if (bfa_dport_send_req(dport, BFI_DPORT_DISABLE))
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_disabling);
|
|
|
+ else
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_disabling_qwait);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case BFA_DPORT_SM_HWFAIL:
|
|
|
+ bfa_sm_set_state(dport, bfa_dport_sm_disabled);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ bfa_sm_fault(dport->bfa, event);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+bfa_dport_sm_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_disabling);
|
|
|
+ bfa_dport_send_req(dport, BFI_DPORT_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;
|
|
|
+
|
|
|
+ default:
|
|
|
+ bfa_sm_fault(dport->bfa, event);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+bfa_dport_sm_disabling(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
|
|
|
+{
|
|
|
+ bfa_trc(dport->bfa, event);
|
|
|
+
|
|
|
+ switch (event) {
|
|
|
+ case BFA_DPORT_SM_FWRSP:
|
|
|
+ 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;
|
|
|
+
|
|
|
+ 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
|
|
|
+ */
|
|
|
+ m = bfa_reqq_next(dport->bfa, BFA_REQQ_DIAG);
|
|
|
+ if (!m) {
|
|
|
+ bfa_reqq_wait(dport->bfa, BFA_REQQ_PORT, &dport->reqq_wait);
|
|
|
+ return BFA_FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ bfi_h2i_set(m->mh, BFI_MC_DIAG, BFI_DIAG_H2I_DPORT,
|
|
|
+ bfa_fn_lpu(dport->bfa));
|
|
|
+ m->req = req;
|
|
|
+ m->msgtag = dport->msgtag;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * queue I/O message to firmware
|
|
|
+ */
|
|
|
+ bfa_reqq_produce(dport->bfa, BFA_REQQ_DIAG, m->mh);
|
|
|
+
|
|
|
+ return BFA_TRUE;
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+bfa_dport_qresume(void *cbarg)
|
|
|
+{
|
|
|
+ struct bfa_dport_s *dport = cbarg;
|
|
|
+
|
|
|
+ bfa_sm_send_event(dport, BFA_DPORT_SM_QRESUME);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+bfa_dport_req_comp(struct bfa_dport_s *dport, bfi_diag_dport_rsp_t *msg)
|
|
|
+{
|
|
|
+ bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP);
|
|
|
+ bfa_cb_fcdiag_dport(dport, msg->status);
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * 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)
|
|
|
+{
|
|
|
+ struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
|
|
|
+ struct bfa_dport_s *dport = &fcdiag->dport;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Dport is not support in MEZZ card
|
|
|
+ */
|
|
|
+ if (bfa_mfg_is_mezz(dport->bfa->ioc.attr->card_type)) {
|
|
|
+ bfa_trc(dport->bfa, BFA_STATUS_PBC);
|
|
|
+ return BFA_STATUS_CMD_NOTSUPP_MEZZ;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check to see if IOC is down
|
|
|
+ */
|
|
|
+ if (!bfa_iocfc_is_operational(bfa))
|
|
|
+ return BFA_STATUS_IOC_NON_OP;
|
|
|
+
|
|
|
+ /* if port is PBC disabled, return error */
|
|
|
+ if (bfa_fcport_is_pbcdisabled(bfa)) {
|
|
|
+ bfa_trc(dport->bfa, BFA_STATUS_PBC);
|
|
|
+ return BFA_STATUS_PBC;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if port mode is FC port
|
|
|
+ */
|
|
|
+ if (bfa_ioc_get_type(&bfa->ioc) != BFA_IOC_TYPE_FC) {
|
|
|
+ bfa_trc(dport->bfa, bfa_ioc_get_type(&bfa->ioc));
|
|
|
+ return BFA_STATUS_CMD_NOTSUPP_CNA;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if port is in LOOP mode
|
|
|
+ */
|
|
|
+ if ((bfa_fcport_get_cfg_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) ||
|
|
|
+ (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)) {
|
|
|
+ bfa_trc(dport->bfa, 0);
|
|
|
+ return BFA_STATUS_TOPOLOGY_LOOP;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if port is TRUNK mode
|
|
|
+ */
|
|
|
+ if (bfa_fcport_is_trunk_enabled(bfa)) {
|
|
|
+ bfa_trc(dport->bfa, 0);
|
|
|
+ return BFA_STATUS_ERROR_TRUNK_ENABLED;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check to see if port is disable or in dport state
|
|
|
+ */
|
|
|
+ if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) &&
|
|
|
+ (bfa_fcport_is_dport(bfa) == BFA_FALSE)) {
|
|
|
+ bfa_trc(dport->bfa, 0);
|
|
|
+ return BFA_STATUS_PORT_NOT_DISABLED;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 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)) {
|
|
|
+ return BFA_STATUS_DEVBUSY;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if dport is already enabled
|
|
|
+ */
|
|
|
+ if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) {
|
|
|
+ bfa_trc(dport->bfa, 0);
|
|
|
+ return BFA_STATUS_DPORT_ENABLED;
|
|
|
+ }
|
|
|
+
|
|
|
+ dport->cbfn = cbfn;
|
|
|
+ dport->cbarg = cbarg;
|
|
|
+
|
|
|
+ bfa_sm_send_event(dport, BFA_DPORT_SM_ENABLE);
|
|
|
+ return BFA_STATUS_OK;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Dport disable
|
|
|
+ *
|
|
|
+ * @param[in] *bfa - bfa data struct
|
|
|
+ */
|
|
|
+bfa_status_t
|
|
|
+bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
|
|
|
+{
|
|
|
+ struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
|
|
|
+ struct bfa_dport_s *dport = &fcdiag->dport;
|
|
|
+
|
|
|
+ if (bfa_ioc_is_disabled(&bfa->ioc))
|
|
|
+ return BFA_STATUS_IOC_DISABLED;
|
|
|
+
|
|
|
+ /* if port is PBC disabled, return error */
|
|
|
+ if (bfa_fcport_is_pbcdisabled(bfa)) {
|
|
|
+ bfa_trc(dport->bfa, BFA_STATUS_PBC);
|
|
|
+ return BFA_STATUS_PBC;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check to see if port is disable or in dport state
|
|
|
+ */
|
|
|
+ if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) &&
|
|
|
+ (bfa_fcport_is_dport(bfa) == BFA_FALSE)) {
|
|
|
+ bfa_trc(dport->bfa, 0);
|
|
|
+ return BFA_STATUS_PORT_NOT_DISABLED;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 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))
|
|
|
+ return BFA_STATUS_DEVBUSY;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check if dport is already disabled
|
|
|
+ */
|
|
|
+ if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled)) {
|
|
|
+ bfa_trc(dport->bfa, 0);
|
|
|
+ return BFA_STATUS_DPORT_DISABLED;
|
|
|
+ }
|
|
|
+
|
|
|
+ dport->cbfn = cbfn;
|
|
|
+ dport->cbarg = cbarg;
|
|
|
+
|
|
|
+ bfa_sm_send_event(dport, BFA_DPORT_SM_DISABLE);
|
|
|
+ return BFA_STATUS_OK;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Get D-port state
|
|
|
+ *
|
|
|
+ * @param[in] *bfa - bfa data struct
|
|
|
+ */
|
|
|
+
|
|
|
+bfa_status_t
|
|
|
+bfa_dport_get_state(struct bfa_s *bfa, enum bfa_dport_state *state)
|
|
|
+{
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ return BFA_STATUS_OK;
|
|
|
+}
|