BFA_TRC_FILE(HAL, PPORT);
BFA_MODULE(pport);
-#define bfa_pport_callback(__pport, __event) do { \
- if ((__pport)->bfa->fcs) { \
- (__pport)->event_cbfn((__pport)->event_cbarg, (__event)); \
- } else { \
- (__pport)->hcb_event = (__event); \
- bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe, \
- __bfa_cb_port_event, (__pport)); \
- } \
-} while (0)
-
/*
* The port is considered disabled if corresponding physical port or IOC are
* disabled explicitly
static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete);
static void bfa_port_stats_timeout(void *cbarg);
static void bfa_port_stats_clr_timeout(void *cbarg);
-
+static void bfa_pport_callback(struct bfa_pport_s *pport,
+ enum bfa_pport_linkstate event);
+static void bfa_pport_queue_cb(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_linkstate event);
/**
* bfa_pport_private
*/
BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */
};
+/**
+ * BFA port link notification state machine events
+ */
+
+enum bfa_pport_ln_sm_event {
+ BFA_PPORT_LN_SM_LINKUP = 1, /* linkup event */
+ BFA_PPORT_LN_SM_LINKDOWN = 2, /* linkdown event */
+ BFA_PPORT_LN_SM_NOTIFICATION = 3 /* done notification */
+};
+
static void bfa_pport_sm_uninit(struct bfa_pport_s *pport,
enum bfa_pport_sm_event event);
static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport,
enum bfa_pport_sm_event event);
+static void bfa_pport_ln_sm_dn(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event);
+static void bfa_pport_ln_sm_dn_nf(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event);
+static void bfa_pport_ln_sm_dn_up_nf(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event);
+static void bfa_pport_ln_sm_up(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event);
+static void bfa_pport_ln_sm_up_nf(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event);
+static void bfa_pport_ln_sm_up_dn_nf(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event);
+static void bfa_pport_ln_sm_up_dn_up_nf(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event);
+
static struct bfa_sm_table_s hal_pport_sm_table[] = {
{BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT},
{BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
}
}
+/**
+ * Link state is down
+ */
+static void
+bfa_pport_ln_sm_dn(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event)
+{
+ bfa_trc(ln->pport->bfa, event);
+
+ switch (event) {
+ case BFA_PPORT_LN_SM_LINKUP:
+ bfa_sm_set_state(ln, bfa_pport_ln_sm_up_nf);
+ bfa_pport_queue_cb(ln, BFA_PPORT_LINKUP);
+ break;
+
+ default:
+ bfa_sm_fault(ln->pport->bfa, event);
+ }
+}
+
+/**
+ * Link state is waiting for down notification
+ */
+static void
+bfa_pport_ln_sm_dn_nf(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event)
+{
+ bfa_trc(ln->pport->bfa, event);
+
+ switch (event) {
+ case BFA_PPORT_LN_SM_LINKUP:
+ bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_up_nf);
+ break;
+
+ case BFA_PPORT_LN_SM_NOTIFICATION:
+ bfa_sm_set_state(ln, bfa_pport_ln_sm_dn);
+ break;
+
+ default:
+ bfa_sm_fault(ln->pport->bfa, event);
+ }
+}
+
+/**
+ * Link state is waiting for down notification and there is a pending up
+ */
+static void
+bfa_pport_ln_sm_dn_up_nf(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event)
+{
+ bfa_trc(ln->pport->bfa, event);
+
+ switch (event) {
+ case BFA_PPORT_LN_SM_LINKDOWN:
+ bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf);
+ break;
+
+ case BFA_PPORT_LN_SM_NOTIFICATION:
+ bfa_sm_set_state(ln, bfa_pport_ln_sm_up_nf);
+ bfa_pport_queue_cb(ln, BFA_PPORT_LINKUP);
+ break;
+
+ default:
+ bfa_sm_fault(ln->pport->bfa, event);
+ }
+}
+
+/**
+ * Link state is up
+ */
+static void
+bfa_pport_ln_sm_up(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event)
+{
+ bfa_trc(ln->pport->bfa, event);
+
+ switch (event) {
+ case BFA_PPORT_LN_SM_LINKDOWN:
+ bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf);
+ bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+ break;
+
+ default:
+ bfa_sm_fault(ln->pport->bfa, event);
+ }
+}
+
+/**
+ * Link state is waiting for up notification
+ */
+static void
+bfa_pport_ln_sm_up_nf(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event)
+{
+ bfa_trc(ln->pport->bfa, event);
+
+ switch (event) {
+ case BFA_PPORT_LN_SM_LINKDOWN:
+ bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_nf);
+ break;
+
+ case BFA_PPORT_LN_SM_NOTIFICATION:
+ bfa_sm_set_state(ln, bfa_pport_ln_sm_up);
+ break;
+
+ default:
+ bfa_sm_fault(ln->pport->bfa, event);
+ }
+}
+
+/**
+ * Link state is waiting for up notification and there is a pending down
+ */
+static void
+bfa_pport_ln_sm_up_dn_nf(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event)
+{
+ bfa_trc(ln->pport->bfa, event);
+ switch (event) {
+ case BFA_PPORT_LN_SM_LINKUP:
+ bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_up_nf);
+ break;
+
+ case BFA_PPORT_LN_SM_NOTIFICATION:
+ bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf);
+ bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+ break;
+
+ default:
+ bfa_sm_fault(ln->pport->bfa, event);
+ }
+}
+
+/**
+ * Link state is waiting for up notification and there are pending down and up
+ */
+static void
+bfa_pport_ln_sm_up_dn_up_nf(struct bfa_pport_ln_s *ln,
+ enum bfa_pport_ln_sm_event event)
+{
+ bfa_trc(ln->pport->bfa, event);
+
+ switch (event) {
+ case BFA_PPORT_LN_SM_LINKDOWN:
+ bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_nf);
+ break;
+
+ case BFA_PPORT_LN_SM_NOTIFICATION:
+ bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_up_nf);
+ bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN);
+ break;
+
+ default:
+ bfa_sm_fault(ln->pport->bfa, event);
+ }
+}
/**
* bfa_pport_private
static void
__bfa_cb_port_event(void *cbarg, bfa_boolean_t complete)
{
- struct bfa_pport_s *pport = cbarg;
+ struct bfa_pport_ln_s *ln = cbarg;
if (complete)
- pport->event_cbfn(pport->event_cbarg, pport->hcb_event);
+ ln->pport->event_cbfn(ln->pport->event_cbarg, ln->ln_event);
+ else
+ bfa_sm_send_event(ln, BFA_PPORT_LN_SM_NOTIFICATION);
}
#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \
{
struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
struct bfa_pport_cfg_s *port_cfg = &pport->cfg;
+ struct bfa_pport_ln_s *ln = &pport->ln;
bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s));
pport->bfa = bfa;
+ ln->pport = pport;
bfa_pport_mem_claim(pport, meminfo);
bfa_sm_set_state(pport, bfa_pport_sm_uninit);
+ bfa_sm_set_state(ln, bfa_pport_ln_sm_dn);
/**
* initialize and set default configuration
bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats_clr, port);
}
+static void
+bfa_pport_callback(struct bfa_pport_s *pport, enum bfa_pport_linkstate event)
+{
+ if (pport->bfa->fcs) {
+ pport->event_cbfn(pport->event_cbarg, event);
+ return;
+ }
+
+ switch (event) {
+ case BFA_PPORT_LINKUP:
+ bfa_sm_send_event(&pport->ln, BFA_PPORT_LN_SM_LINKUP);
+ break;
+ case BFA_PPORT_LINKDOWN:
+ bfa_sm_send_event(&pport->ln, BFA_PPORT_LN_SM_LINKDOWN);
+ break;
+ default:
+ bfa_assert(0);
+ }
+}
+
+static void
+bfa_pport_queue_cb(struct bfa_pport_ln_s *ln, enum bfa_pport_linkstate event)
+{
+ ln->ln_event = event;
+ bfa_cb_queue(ln->pport->bfa, &ln->ln_qe, __bfa_cb_port_event, ln);
+}
+
static void
__bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete)
{