162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Linux network driver for QLogic BR-series Converged Network Adapter.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci/*
662306a36Sopenharmony_ci * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
762306a36Sopenharmony_ci * Copyright (c) 2014-2015 QLogic Corporation
862306a36Sopenharmony_ci * All rights reserved
962306a36Sopenharmony_ci * www.qlogic.com
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci#include "bna.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cistatic inline int
1462306a36Sopenharmony_ciethport_can_be_up(struct bna_ethport *ethport)
1562306a36Sopenharmony_ci{
1662306a36Sopenharmony_ci	int ready = 0;
1762306a36Sopenharmony_ci	if (ethport->bna->enet.type == BNA_ENET_T_REGULAR)
1862306a36Sopenharmony_ci		ready = ((ethport->flags & BNA_ETHPORT_F_ADMIN_UP) &&
1962306a36Sopenharmony_ci			 (ethport->flags & BNA_ETHPORT_F_RX_STARTED) &&
2062306a36Sopenharmony_ci			 (ethport->flags & BNA_ETHPORT_F_PORT_ENABLED));
2162306a36Sopenharmony_ci	else
2262306a36Sopenharmony_ci		ready = ((ethport->flags & BNA_ETHPORT_F_ADMIN_UP) &&
2362306a36Sopenharmony_ci			 (ethport->flags & BNA_ETHPORT_F_RX_STARTED) &&
2462306a36Sopenharmony_ci			 !(ethport->flags & BNA_ETHPORT_F_PORT_ENABLED));
2562306a36Sopenharmony_ci	return ready;
2662306a36Sopenharmony_ci}
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#define ethport_is_up ethport_can_be_up
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cienum bna_ethport_event {
3162306a36Sopenharmony_ci	ETHPORT_E_START			= 1,
3262306a36Sopenharmony_ci	ETHPORT_E_STOP			= 2,
3362306a36Sopenharmony_ci	ETHPORT_E_FAIL			= 3,
3462306a36Sopenharmony_ci	ETHPORT_E_UP			= 4,
3562306a36Sopenharmony_ci	ETHPORT_E_DOWN			= 5,
3662306a36Sopenharmony_ci	ETHPORT_E_FWRESP_UP_OK		= 6,
3762306a36Sopenharmony_ci	ETHPORT_E_FWRESP_DOWN		= 7,
3862306a36Sopenharmony_ci	ETHPORT_E_FWRESP_UP_FAIL	= 8,
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cienum bna_enet_event {
4262306a36Sopenharmony_ci	ENET_E_START			= 1,
4362306a36Sopenharmony_ci	ENET_E_STOP			= 2,
4462306a36Sopenharmony_ci	ENET_E_FAIL			= 3,
4562306a36Sopenharmony_ci	ENET_E_PAUSE_CFG		= 4,
4662306a36Sopenharmony_ci	ENET_E_MTU_CFG			= 5,
4762306a36Sopenharmony_ci	ENET_E_FWRESP_PAUSE		= 6,
4862306a36Sopenharmony_ci	ENET_E_CHLD_STOPPED		= 7,
4962306a36Sopenharmony_ci};
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cienum bna_ioceth_event {
5262306a36Sopenharmony_ci	IOCETH_E_ENABLE			= 1,
5362306a36Sopenharmony_ci	IOCETH_E_DISABLE		= 2,
5462306a36Sopenharmony_ci	IOCETH_E_IOC_RESET		= 3,
5562306a36Sopenharmony_ci	IOCETH_E_IOC_FAILED		= 4,
5662306a36Sopenharmony_ci	IOCETH_E_IOC_READY		= 5,
5762306a36Sopenharmony_ci	IOCETH_E_ENET_ATTR_RESP		= 6,
5862306a36Sopenharmony_ci	IOCETH_E_ENET_STOPPED		= 7,
5962306a36Sopenharmony_ci	IOCETH_E_IOC_DISABLED		= 8,
6062306a36Sopenharmony_ci};
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci#define bna_stats_copy(_name, _type)					\
6362306a36Sopenharmony_cido {									\
6462306a36Sopenharmony_ci	count = sizeof(struct bfi_enet_stats_ ## _type) / sizeof(u64);	\
6562306a36Sopenharmony_ci	stats_src = (u64 *)&bna->stats.hw_stats_kva->_name ## _stats;	\
6662306a36Sopenharmony_ci	stats_dst = (u64 *)&bna->stats.hw_stats._name ## _stats;	\
6762306a36Sopenharmony_ci	for (i = 0; i < count; i++)					\
6862306a36Sopenharmony_ci		stats_dst[i] = be64_to_cpu(stats_src[i]);		\
6962306a36Sopenharmony_ci} while (0)								\
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci/*
7262306a36Sopenharmony_ci * FW response handlers
7362306a36Sopenharmony_ci */
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistatic void
7662306a36Sopenharmony_cibna_bfi_ethport_enable_aen(struct bna_ethport *ethport,
7762306a36Sopenharmony_ci				struct bfi_msgq_mhdr *msghdr)
7862306a36Sopenharmony_ci{
7962306a36Sopenharmony_ci	ethport->flags |= BNA_ETHPORT_F_PORT_ENABLED;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	if (ethport_can_be_up(ethport))
8262306a36Sopenharmony_ci		bfa_fsm_send_event(ethport, ETHPORT_E_UP);
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cistatic void
8662306a36Sopenharmony_cibna_bfi_ethport_disable_aen(struct bna_ethport *ethport,
8762306a36Sopenharmony_ci				struct bfi_msgq_mhdr *msghdr)
8862306a36Sopenharmony_ci{
8962306a36Sopenharmony_ci	int ethport_up = ethport_is_up(ethport);
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	ethport->flags &= ~BNA_ETHPORT_F_PORT_ENABLED;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	if (ethport_up)
9462306a36Sopenharmony_ci		bfa_fsm_send_event(ethport, ETHPORT_E_DOWN);
9562306a36Sopenharmony_ci}
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cistatic void
9862306a36Sopenharmony_cibna_bfi_ethport_admin_rsp(struct bna_ethport *ethport,
9962306a36Sopenharmony_ci				struct bfi_msgq_mhdr *msghdr)
10062306a36Sopenharmony_ci{
10162306a36Sopenharmony_ci	struct bfi_enet_enable_req *admin_req =
10262306a36Sopenharmony_ci		&ethport->bfi_enet_cmd.admin_req;
10362306a36Sopenharmony_ci	struct bfi_enet_rsp *rsp =
10462306a36Sopenharmony_ci		container_of(msghdr, struct bfi_enet_rsp, mh);
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	switch (admin_req->enable) {
10762306a36Sopenharmony_ci	case BNA_STATUS_T_ENABLED:
10862306a36Sopenharmony_ci		if (rsp->error == BFI_ENET_CMD_OK)
10962306a36Sopenharmony_ci			bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_OK);
11062306a36Sopenharmony_ci		else {
11162306a36Sopenharmony_ci			ethport->flags &= ~BNA_ETHPORT_F_PORT_ENABLED;
11262306a36Sopenharmony_ci			bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_FAIL);
11362306a36Sopenharmony_ci		}
11462306a36Sopenharmony_ci		break;
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci	case BNA_STATUS_T_DISABLED:
11762306a36Sopenharmony_ci		bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_DOWN);
11862306a36Sopenharmony_ci		ethport->link_status = BNA_LINK_DOWN;
11962306a36Sopenharmony_ci		ethport->link_cbfn(ethport->bna->bnad, BNA_LINK_DOWN);
12062306a36Sopenharmony_ci		break;
12162306a36Sopenharmony_ci	}
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_cistatic void
12562306a36Sopenharmony_cibna_bfi_ethport_lpbk_rsp(struct bna_ethport *ethport,
12662306a36Sopenharmony_ci				struct bfi_msgq_mhdr *msghdr)
12762306a36Sopenharmony_ci{
12862306a36Sopenharmony_ci	struct bfi_enet_diag_lb_req *diag_lb_req =
12962306a36Sopenharmony_ci		&ethport->bfi_enet_cmd.lpbk_req;
13062306a36Sopenharmony_ci	struct bfi_enet_rsp *rsp =
13162306a36Sopenharmony_ci		container_of(msghdr, struct bfi_enet_rsp, mh);
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci	switch (diag_lb_req->enable) {
13462306a36Sopenharmony_ci	case BNA_STATUS_T_ENABLED:
13562306a36Sopenharmony_ci		if (rsp->error == BFI_ENET_CMD_OK)
13662306a36Sopenharmony_ci			bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_OK);
13762306a36Sopenharmony_ci		else {
13862306a36Sopenharmony_ci			ethport->flags &= ~BNA_ETHPORT_F_ADMIN_UP;
13962306a36Sopenharmony_ci			bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_FAIL);
14062306a36Sopenharmony_ci		}
14162306a36Sopenharmony_ci		break;
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	case BNA_STATUS_T_DISABLED:
14462306a36Sopenharmony_ci		bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_DOWN);
14562306a36Sopenharmony_ci		break;
14662306a36Sopenharmony_ci	}
14762306a36Sopenharmony_ci}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_cistatic void
15062306a36Sopenharmony_cibna_bfi_pause_set_rsp(struct bna_enet *enet, struct bfi_msgq_mhdr *msghdr)
15162306a36Sopenharmony_ci{
15262306a36Sopenharmony_ci	bfa_fsm_send_event(enet, ENET_E_FWRESP_PAUSE);
15362306a36Sopenharmony_ci}
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_cistatic void
15662306a36Sopenharmony_cibna_bfi_attr_get_rsp(struct bna_ioceth *ioceth,
15762306a36Sopenharmony_ci			struct bfi_msgq_mhdr *msghdr)
15862306a36Sopenharmony_ci{
15962306a36Sopenharmony_ci	struct bfi_enet_attr_rsp *rsp =
16062306a36Sopenharmony_ci		container_of(msghdr, struct bfi_enet_attr_rsp, mh);
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci	/**
16362306a36Sopenharmony_ci	 * Store only if not set earlier, since BNAD can override the HW
16462306a36Sopenharmony_ci	 * attributes
16562306a36Sopenharmony_ci	 */
16662306a36Sopenharmony_ci	if (!ioceth->attr.fw_query_complete) {
16762306a36Sopenharmony_ci		ioceth->attr.num_txq = ntohl(rsp->max_cfg);
16862306a36Sopenharmony_ci		ioceth->attr.num_rxp = ntohl(rsp->max_cfg);
16962306a36Sopenharmony_ci		ioceth->attr.num_ucmac = ntohl(rsp->max_ucmac);
17062306a36Sopenharmony_ci		ioceth->attr.num_mcmac = BFI_ENET_MAX_MCAM;
17162306a36Sopenharmony_ci		ioceth->attr.max_rit_size = ntohl(rsp->rit_size);
17262306a36Sopenharmony_ci		ioceth->attr.fw_query_complete = true;
17362306a36Sopenharmony_ci	}
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	bfa_fsm_send_event(ioceth, IOCETH_E_ENET_ATTR_RESP);
17662306a36Sopenharmony_ci}
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_cistatic void
17962306a36Sopenharmony_cibna_bfi_stats_get_rsp(struct bna *bna, struct bfi_msgq_mhdr *msghdr)
18062306a36Sopenharmony_ci{
18162306a36Sopenharmony_ci	struct bfi_enet_stats_req *stats_req = &bna->stats_mod.stats_get;
18262306a36Sopenharmony_ci	u64 *stats_src;
18362306a36Sopenharmony_ci	u64 *stats_dst;
18462306a36Sopenharmony_ci	u32 tx_enet_mask = ntohl(stats_req->tx_enet_mask);
18562306a36Sopenharmony_ci	u32 rx_enet_mask = ntohl(stats_req->rx_enet_mask);
18662306a36Sopenharmony_ci	int count;
18762306a36Sopenharmony_ci	int i;
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	bna_stats_copy(mac, mac);
19062306a36Sopenharmony_ci	bna_stats_copy(bpc, bpc);
19162306a36Sopenharmony_ci	bna_stats_copy(rad, rad);
19262306a36Sopenharmony_ci	bna_stats_copy(rlb, rad);
19362306a36Sopenharmony_ci	bna_stats_copy(fc_rx, fc_rx);
19462306a36Sopenharmony_ci	bna_stats_copy(fc_tx, fc_tx);
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	stats_src = (u64 *)&(bna->stats.hw_stats_kva->rxf_stats[0]);
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	/* Copy Rxf stats to SW area, scatter them while copying */
19962306a36Sopenharmony_ci	for (i = 0; i < BFI_ENET_CFG_MAX; i++) {
20062306a36Sopenharmony_ci		stats_dst = (u64 *)&(bna->stats.hw_stats.rxf_stats[i]);
20162306a36Sopenharmony_ci		memset(stats_dst, 0, sizeof(struct bfi_enet_stats_rxf));
20262306a36Sopenharmony_ci		if (rx_enet_mask & BIT(i)) {
20362306a36Sopenharmony_ci			int k;
20462306a36Sopenharmony_ci			count = sizeof(struct bfi_enet_stats_rxf) /
20562306a36Sopenharmony_ci				sizeof(u64);
20662306a36Sopenharmony_ci			for (k = 0; k < count; k++) {
20762306a36Sopenharmony_ci				stats_dst[k] = be64_to_cpu(*stats_src);
20862306a36Sopenharmony_ci				stats_src++;
20962306a36Sopenharmony_ci			}
21062306a36Sopenharmony_ci		}
21162306a36Sopenharmony_ci	}
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	/* Copy Txf stats to SW area, scatter them while copying */
21462306a36Sopenharmony_ci	for (i = 0; i < BFI_ENET_CFG_MAX; i++) {
21562306a36Sopenharmony_ci		stats_dst = (u64 *)&(bna->stats.hw_stats.txf_stats[i]);
21662306a36Sopenharmony_ci		memset(stats_dst, 0, sizeof(struct bfi_enet_stats_txf));
21762306a36Sopenharmony_ci		if (tx_enet_mask & BIT(i)) {
21862306a36Sopenharmony_ci			int k;
21962306a36Sopenharmony_ci			count = sizeof(struct bfi_enet_stats_txf) /
22062306a36Sopenharmony_ci				sizeof(u64);
22162306a36Sopenharmony_ci			for (k = 0; k < count; k++) {
22262306a36Sopenharmony_ci				stats_dst[k] = be64_to_cpu(*stats_src);
22362306a36Sopenharmony_ci				stats_src++;
22462306a36Sopenharmony_ci			}
22562306a36Sopenharmony_ci		}
22662306a36Sopenharmony_ci	}
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	bna->stats_mod.stats_get_busy = false;
22962306a36Sopenharmony_ci	bnad_cb_stats_get(bna->bnad, BNA_CB_SUCCESS, &bna->stats);
23062306a36Sopenharmony_ci}
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_cistatic void
23362306a36Sopenharmony_cibna_bfi_ethport_linkup_aen(struct bna_ethport *ethport,
23462306a36Sopenharmony_ci			struct bfi_msgq_mhdr *msghdr)
23562306a36Sopenharmony_ci{
23662306a36Sopenharmony_ci	ethport->link_status = BNA_LINK_UP;
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	/* Dispatch events */
23962306a36Sopenharmony_ci	ethport->link_cbfn(ethport->bna->bnad, ethport->link_status);
24062306a36Sopenharmony_ci}
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_cistatic void
24362306a36Sopenharmony_cibna_bfi_ethport_linkdown_aen(struct bna_ethport *ethport,
24462306a36Sopenharmony_ci				struct bfi_msgq_mhdr *msghdr)
24562306a36Sopenharmony_ci{
24662306a36Sopenharmony_ci	ethport->link_status = BNA_LINK_DOWN;
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	/* Dispatch events */
24962306a36Sopenharmony_ci	ethport->link_cbfn(ethport->bna->bnad, BNA_LINK_DOWN);
25062306a36Sopenharmony_ci}
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_cistatic void
25362306a36Sopenharmony_cibna_err_handler(struct bna *bna, u32 intr_status)
25462306a36Sopenharmony_ci{
25562306a36Sopenharmony_ci	if (BNA_IS_HALT_INTR(bna, intr_status))
25662306a36Sopenharmony_ci		bna_halt_clear(bna);
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci	bfa_nw_ioc_error_isr(&bna->ioceth.ioc);
25962306a36Sopenharmony_ci}
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_civoid
26262306a36Sopenharmony_cibna_mbox_handler(struct bna *bna, u32 intr_status)
26362306a36Sopenharmony_ci{
26462306a36Sopenharmony_ci	if (BNA_IS_ERR_INTR(bna, intr_status)) {
26562306a36Sopenharmony_ci		bna_err_handler(bna, intr_status);
26662306a36Sopenharmony_ci		return;
26762306a36Sopenharmony_ci	}
26862306a36Sopenharmony_ci	if (BNA_IS_MBOX_INTR(bna, intr_status))
26962306a36Sopenharmony_ci		bfa_nw_ioc_mbox_isr(&bna->ioceth.ioc);
27062306a36Sopenharmony_ci}
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_cistatic void
27362306a36Sopenharmony_cibna_msgq_rsp_handler(void *arg, struct bfi_msgq_mhdr *msghdr)
27462306a36Sopenharmony_ci{
27562306a36Sopenharmony_ci	struct bna *bna = (struct bna *)arg;
27662306a36Sopenharmony_ci	struct bna_tx *tx;
27762306a36Sopenharmony_ci	struct bna_rx *rx;
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	switch (msghdr->msg_id) {
28062306a36Sopenharmony_ci	case BFI_ENET_I2H_RX_CFG_SET_RSP:
28162306a36Sopenharmony_ci		bna_rx_from_rid(bna, msghdr->enet_id, rx);
28262306a36Sopenharmony_ci		if (rx)
28362306a36Sopenharmony_ci			bna_bfi_rx_enet_start_rsp(rx, msghdr);
28462306a36Sopenharmony_ci		break;
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	case BFI_ENET_I2H_RX_CFG_CLR_RSP:
28762306a36Sopenharmony_ci		bna_rx_from_rid(bna, msghdr->enet_id, rx);
28862306a36Sopenharmony_ci		if (rx)
28962306a36Sopenharmony_ci			bna_bfi_rx_enet_stop_rsp(rx, msghdr);
29062306a36Sopenharmony_ci		break;
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci	case BFI_ENET_I2H_RIT_CFG_RSP:
29362306a36Sopenharmony_ci	case BFI_ENET_I2H_RSS_CFG_RSP:
29462306a36Sopenharmony_ci	case BFI_ENET_I2H_RSS_ENABLE_RSP:
29562306a36Sopenharmony_ci	case BFI_ENET_I2H_RX_PROMISCUOUS_RSP:
29662306a36Sopenharmony_ci	case BFI_ENET_I2H_RX_DEFAULT_RSP:
29762306a36Sopenharmony_ci	case BFI_ENET_I2H_MAC_UCAST_CLR_RSP:
29862306a36Sopenharmony_ci	case BFI_ENET_I2H_MAC_UCAST_ADD_RSP:
29962306a36Sopenharmony_ci	case BFI_ENET_I2H_MAC_UCAST_DEL_RSP:
30062306a36Sopenharmony_ci	case BFI_ENET_I2H_MAC_MCAST_DEL_RSP:
30162306a36Sopenharmony_ci	case BFI_ENET_I2H_MAC_MCAST_FILTER_RSP:
30262306a36Sopenharmony_ci	case BFI_ENET_I2H_RX_VLAN_SET_RSP:
30362306a36Sopenharmony_ci	case BFI_ENET_I2H_RX_VLAN_STRIP_ENABLE_RSP:
30462306a36Sopenharmony_ci		bna_rx_from_rid(bna, msghdr->enet_id, rx);
30562306a36Sopenharmony_ci		if (rx)
30662306a36Sopenharmony_ci			bna_bfi_rxf_cfg_rsp(&rx->rxf, msghdr);
30762306a36Sopenharmony_ci		break;
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	case BFI_ENET_I2H_MAC_UCAST_SET_RSP:
31062306a36Sopenharmony_ci		bna_rx_from_rid(bna, msghdr->enet_id, rx);
31162306a36Sopenharmony_ci		if (rx)
31262306a36Sopenharmony_ci			bna_bfi_rxf_ucast_set_rsp(&rx->rxf, msghdr);
31362306a36Sopenharmony_ci		break;
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	case BFI_ENET_I2H_MAC_MCAST_ADD_RSP:
31662306a36Sopenharmony_ci		bna_rx_from_rid(bna, msghdr->enet_id, rx);
31762306a36Sopenharmony_ci		if (rx)
31862306a36Sopenharmony_ci			bna_bfi_rxf_mcast_add_rsp(&rx->rxf, msghdr);
31962306a36Sopenharmony_ci		break;
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	case BFI_ENET_I2H_TX_CFG_SET_RSP:
32262306a36Sopenharmony_ci		bna_tx_from_rid(bna, msghdr->enet_id, tx);
32362306a36Sopenharmony_ci		if (tx)
32462306a36Sopenharmony_ci			bna_bfi_tx_enet_start_rsp(tx, msghdr);
32562306a36Sopenharmony_ci		break;
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	case BFI_ENET_I2H_TX_CFG_CLR_RSP:
32862306a36Sopenharmony_ci		bna_tx_from_rid(bna, msghdr->enet_id, tx);
32962306a36Sopenharmony_ci		if (tx)
33062306a36Sopenharmony_ci			bna_bfi_tx_enet_stop_rsp(tx, msghdr);
33162306a36Sopenharmony_ci		break;
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	case BFI_ENET_I2H_PORT_ADMIN_RSP:
33462306a36Sopenharmony_ci		bna_bfi_ethport_admin_rsp(&bna->ethport, msghdr);
33562306a36Sopenharmony_ci		break;
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	case BFI_ENET_I2H_DIAG_LOOPBACK_RSP:
33862306a36Sopenharmony_ci		bna_bfi_ethport_lpbk_rsp(&bna->ethport, msghdr);
33962306a36Sopenharmony_ci		break;
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci	case BFI_ENET_I2H_SET_PAUSE_RSP:
34262306a36Sopenharmony_ci		bna_bfi_pause_set_rsp(&bna->enet, msghdr);
34362306a36Sopenharmony_ci		break;
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci	case BFI_ENET_I2H_GET_ATTR_RSP:
34662306a36Sopenharmony_ci		bna_bfi_attr_get_rsp(&bna->ioceth, msghdr);
34762306a36Sopenharmony_ci		break;
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	case BFI_ENET_I2H_STATS_GET_RSP:
35062306a36Sopenharmony_ci		bna_bfi_stats_get_rsp(bna, msghdr);
35162306a36Sopenharmony_ci		break;
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci	case BFI_ENET_I2H_STATS_CLR_RSP:
35462306a36Sopenharmony_ci		/* No-op */
35562306a36Sopenharmony_ci		break;
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci	case BFI_ENET_I2H_LINK_UP_AEN:
35862306a36Sopenharmony_ci		bna_bfi_ethport_linkup_aen(&bna->ethport, msghdr);
35962306a36Sopenharmony_ci		break;
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	case BFI_ENET_I2H_LINK_DOWN_AEN:
36262306a36Sopenharmony_ci		bna_bfi_ethport_linkdown_aen(&bna->ethport, msghdr);
36362306a36Sopenharmony_ci		break;
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	case BFI_ENET_I2H_PORT_ENABLE_AEN:
36662306a36Sopenharmony_ci		bna_bfi_ethport_enable_aen(&bna->ethport, msghdr);
36762306a36Sopenharmony_ci		break;
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	case BFI_ENET_I2H_PORT_DISABLE_AEN:
37062306a36Sopenharmony_ci		bna_bfi_ethport_disable_aen(&bna->ethport, msghdr);
37162306a36Sopenharmony_ci		break;
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	case BFI_ENET_I2H_BW_UPDATE_AEN:
37462306a36Sopenharmony_ci		bna_bfi_bw_update_aen(&bna->tx_mod);
37562306a36Sopenharmony_ci		break;
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci	default:
37862306a36Sopenharmony_ci		break;
37962306a36Sopenharmony_ci	}
38062306a36Sopenharmony_ci}
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci/* ETHPORT */
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci#define call_ethport_stop_cbfn(_ethport)				\
38562306a36Sopenharmony_cido {									\
38662306a36Sopenharmony_ci	if ((_ethport)->stop_cbfn) {					\
38762306a36Sopenharmony_ci		void (*cbfn)(struct bna_enet *);			\
38862306a36Sopenharmony_ci		cbfn = (_ethport)->stop_cbfn;				\
38962306a36Sopenharmony_ci		(_ethport)->stop_cbfn = NULL;				\
39062306a36Sopenharmony_ci		cbfn(&(_ethport)->bna->enet);				\
39162306a36Sopenharmony_ci	}								\
39262306a36Sopenharmony_ci} while (0)
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci#define call_ethport_adminup_cbfn(ethport, status)			\
39562306a36Sopenharmony_cido {									\
39662306a36Sopenharmony_ci	if ((ethport)->adminup_cbfn) {					\
39762306a36Sopenharmony_ci		void (*cbfn)(struct bnad *, enum bna_cb_status);	\
39862306a36Sopenharmony_ci		cbfn = (ethport)->adminup_cbfn;				\
39962306a36Sopenharmony_ci		(ethport)->adminup_cbfn = NULL;				\
40062306a36Sopenharmony_ci		cbfn((ethport)->bna->bnad, status);			\
40162306a36Sopenharmony_ci	}								\
40262306a36Sopenharmony_ci} while (0)
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_cistatic void
40562306a36Sopenharmony_cibna_bfi_ethport_admin_up(struct bna_ethport *ethport)
40662306a36Sopenharmony_ci{
40762306a36Sopenharmony_ci	struct bfi_enet_enable_req *admin_up_req =
40862306a36Sopenharmony_ci		&ethport->bfi_enet_cmd.admin_req;
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci	bfi_msgq_mhdr_set(admin_up_req->mh, BFI_MC_ENET,
41162306a36Sopenharmony_ci		BFI_ENET_H2I_PORT_ADMIN_UP_REQ, 0, 0);
41262306a36Sopenharmony_ci	admin_up_req->mh.num_entries = htons(
41362306a36Sopenharmony_ci		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
41462306a36Sopenharmony_ci	admin_up_req->enable = BNA_STATUS_T_ENABLED;
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	bfa_msgq_cmd_set(&ethport->msgq_cmd, NULL, NULL,
41762306a36Sopenharmony_ci		sizeof(struct bfi_enet_enable_req), &admin_up_req->mh);
41862306a36Sopenharmony_ci	bfa_msgq_cmd_post(&ethport->bna->msgq, &ethport->msgq_cmd);
41962306a36Sopenharmony_ci}
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_cistatic void
42262306a36Sopenharmony_cibna_bfi_ethport_admin_down(struct bna_ethport *ethport)
42362306a36Sopenharmony_ci{
42462306a36Sopenharmony_ci	struct bfi_enet_enable_req *admin_down_req =
42562306a36Sopenharmony_ci		&ethport->bfi_enet_cmd.admin_req;
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ci	bfi_msgq_mhdr_set(admin_down_req->mh, BFI_MC_ENET,
42862306a36Sopenharmony_ci		BFI_ENET_H2I_PORT_ADMIN_UP_REQ, 0, 0);
42962306a36Sopenharmony_ci	admin_down_req->mh.num_entries = htons(
43062306a36Sopenharmony_ci		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
43162306a36Sopenharmony_ci	admin_down_req->enable = BNA_STATUS_T_DISABLED;
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci	bfa_msgq_cmd_set(&ethport->msgq_cmd, NULL, NULL,
43462306a36Sopenharmony_ci		sizeof(struct bfi_enet_enable_req), &admin_down_req->mh);
43562306a36Sopenharmony_ci	bfa_msgq_cmd_post(&ethport->bna->msgq, &ethport->msgq_cmd);
43662306a36Sopenharmony_ci}
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_cistatic void
43962306a36Sopenharmony_cibna_bfi_ethport_lpbk_up(struct bna_ethport *ethport)
44062306a36Sopenharmony_ci{
44162306a36Sopenharmony_ci	struct bfi_enet_diag_lb_req *lpbk_up_req =
44262306a36Sopenharmony_ci		&ethport->bfi_enet_cmd.lpbk_req;
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci	bfi_msgq_mhdr_set(lpbk_up_req->mh, BFI_MC_ENET,
44562306a36Sopenharmony_ci		BFI_ENET_H2I_DIAG_LOOPBACK_REQ, 0, 0);
44662306a36Sopenharmony_ci	lpbk_up_req->mh.num_entries = htons(
44762306a36Sopenharmony_ci		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_diag_lb_req)));
44862306a36Sopenharmony_ci	lpbk_up_req->mode = (ethport->bna->enet.type ==
44962306a36Sopenharmony_ci				BNA_ENET_T_LOOPBACK_INTERNAL) ?
45062306a36Sopenharmony_ci				BFI_ENET_DIAG_LB_OPMODE_EXT :
45162306a36Sopenharmony_ci				BFI_ENET_DIAG_LB_OPMODE_CBL;
45262306a36Sopenharmony_ci	lpbk_up_req->enable = BNA_STATUS_T_ENABLED;
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci	bfa_msgq_cmd_set(&ethport->msgq_cmd, NULL, NULL,
45562306a36Sopenharmony_ci		sizeof(struct bfi_enet_diag_lb_req), &lpbk_up_req->mh);
45662306a36Sopenharmony_ci	bfa_msgq_cmd_post(&ethport->bna->msgq, &ethport->msgq_cmd);
45762306a36Sopenharmony_ci}
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_cistatic void
46062306a36Sopenharmony_cibna_bfi_ethport_lpbk_down(struct bna_ethport *ethport)
46162306a36Sopenharmony_ci{
46262306a36Sopenharmony_ci	struct bfi_enet_diag_lb_req *lpbk_down_req =
46362306a36Sopenharmony_ci		&ethport->bfi_enet_cmd.lpbk_req;
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci	bfi_msgq_mhdr_set(lpbk_down_req->mh, BFI_MC_ENET,
46662306a36Sopenharmony_ci		BFI_ENET_H2I_DIAG_LOOPBACK_REQ, 0, 0);
46762306a36Sopenharmony_ci	lpbk_down_req->mh.num_entries = htons(
46862306a36Sopenharmony_ci		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_diag_lb_req)));
46962306a36Sopenharmony_ci	lpbk_down_req->enable = BNA_STATUS_T_DISABLED;
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_ci	bfa_msgq_cmd_set(&ethport->msgq_cmd, NULL, NULL,
47262306a36Sopenharmony_ci		sizeof(struct bfi_enet_diag_lb_req), &lpbk_down_req->mh);
47362306a36Sopenharmony_ci	bfa_msgq_cmd_post(&ethport->bna->msgq, &ethport->msgq_cmd);
47462306a36Sopenharmony_ci}
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_cistatic void
47762306a36Sopenharmony_cibna_bfi_ethport_up(struct bna_ethport *ethport)
47862306a36Sopenharmony_ci{
47962306a36Sopenharmony_ci	if (ethport->bna->enet.type == BNA_ENET_T_REGULAR)
48062306a36Sopenharmony_ci		bna_bfi_ethport_admin_up(ethport);
48162306a36Sopenharmony_ci	else
48262306a36Sopenharmony_ci		bna_bfi_ethport_lpbk_up(ethport);
48362306a36Sopenharmony_ci}
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_cistatic void
48662306a36Sopenharmony_cibna_bfi_ethport_down(struct bna_ethport *ethport)
48762306a36Sopenharmony_ci{
48862306a36Sopenharmony_ci	if (ethport->bna->enet.type == BNA_ENET_T_REGULAR)
48962306a36Sopenharmony_ci		bna_bfi_ethport_admin_down(ethport);
49062306a36Sopenharmony_ci	else
49162306a36Sopenharmony_ci		bna_bfi_ethport_lpbk_down(ethport);
49262306a36Sopenharmony_ci}
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_cibfa_fsm_state_decl(bna_ethport, stopped, struct bna_ethport,
49562306a36Sopenharmony_ci			enum bna_ethport_event);
49662306a36Sopenharmony_cibfa_fsm_state_decl(bna_ethport, down, struct bna_ethport,
49762306a36Sopenharmony_ci			enum bna_ethport_event);
49862306a36Sopenharmony_cibfa_fsm_state_decl(bna_ethport, up_resp_wait, struct bna_ethport,
49962306a36Sopenharmony_ci			enum bna_ethport_event);
50062306a36Sopenharmony_cibfa_fsm_state_decl(bna_ethport, down_resp_wait, struct bna_ethport,
50162306a36Sopenharmony_ci			enum bna_ethport_event);
50262306a36Sopenharmony_cibfa_fsm_state_decl(bna_ethport, up, struct bna_ethport,
50362306a36Sopenharmony_ci			enum bna_ethport_event);
50462306a36Sopenharmony_cibfa_fsm_state_decl(bna_ethport, last_resp_wait, struct bna_ethport,
50562306a36Sopenharmony_ci			enum bna_ethport_event);
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_cistatic void
50862306a36Sopenharmony_cibna_ethport_sm_stopped_entry(struct bna_ethport *ethport)
50962306a36Sopenharmony_ci{
51062306a36Sopenharmony_ci	call_ethport_stop_cbfn(ethport);
51162306a36Sopenharmony_ci}
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_cistatic void
51462306a36Sopenharmony_cibna_ethport_sm_stopped(struct bna_ethport *ethport,
51562306a36Sopenharmony_ci			enum bna_ethport_event event)
51662306a36Sopenharmony_ci{
51762306a36Sopenharmony_ci	switch (event) {
51862306a36Sopenharmony_ci	case ETHPORT_E_START:
51962306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_down);
52062306a36Sopenharmony_ci		break;
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci	case ETHPORT_E_STOP:
52362306a36Sopenharmony_ci		call_ethport_stop_cbfn(ethport);
52462306a36Sopenharmony_ci		break;
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci	case ETHPORT_E_FAIL:
52762306a36Sopenharmony_ci		/* No-op */
52862306a36Sopenharmony_ci		break;
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	case ETHPORT_E_DOWN:
53162306a36Sopenharmony_ci		/* This event is received due to Rx objects failing */
53262306a36Sopenharmony_ci		/* No-op */
53362306a36Sopenharmony_ci		break;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	default:
53662306a36Sopenharmony_ci		bfa_sm_fault(event);
53762306a36Sopenharmony_ci	}
53862306a36Sopenharmony_ci}
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_cistatic void
54162306a36Sopenharmony_cibna_ethport_sm_down_entry(struct bna_ethport *ethport)
54262306a36Sopenharmony_ci{
54362306a36Sopenharmony_ci}
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_cistatic void
54662306a36Sopenharmony_cibna_ethport_sm_down(struct bna_ethport *ethport,
54762306a36Sopenharmony_ci			enum bna_ethport_event event)
54862306a36Sopenharmony_ci{
54962306a36Sopenharmony_ci	switch (event) {
55062306a36Sopenharmony_ci	case ETHPORT_E_STOP:
55162306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
55262306a36Sopenharmony_ci		break;
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ci	case ETHPORT_E_FAIL:
55562306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
55662306a36Sopenharmony_ci		break;
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci	case ETHPORT_E_UP:
55962306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_up_resp_wait);
56062306a36Sopenharmony_ci		bna_bfi_ethport_up(ethport);
56162306a36Sopenharmony_ci		break;
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ci	default:
56462306a36Sopenharmony_ci		bfa_sm_fault(event);
56562306a36Sopenharmony_ci	}
56662306a36Sopenharmony_ci}
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_cistatic void
56962306a36Sopenharmony_cibna_ethport_sm_up_resp_wait_entry(struct bna_ethport *ethport)
57062306a36Sopenharmony_ci{
57162306a36Sopenharmony_ci}
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_cistatic void
57462306a36Sopenharmony_cibna_ethport_sm_up_resp_wait(struct bna_ethport *ethport,
57562306a36Sopenharmony_ci			enum bna_ethport_event event)
57662306a36Sopenharmony_ci{
57762306a36Sopenharmony_ci	switch (event) {
57862306a36Sopenharmony_ci	case ETHPORT_E_STOP:
57962306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_last_resp_wait);
58062306a36Sopenharmony_ci		break;
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci	case ETHPORT_E_FAIL:
58362306a36Sopenharmony_ci		call_ethport_adminup_cbfn(ethport, BNA_CB_FAIL);
58462306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
58562306a36Sopenharmony_ci		break;
58662306a36Sopenharmony_ci
58762306a36Sopenharmony_ci	case ETHPORT_E_DOWN:
58862306a36Sopenharmony_ci		call_ethport_adminup_cbfn(ethport, BNA_CB_INTERRUPT);
58962306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_down_resp_wait);
59062306a36Sopenharmony_ci		break;
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	case ETHPORT_E_FWRESP_UP_OK:
59362306a36Sopenharmony_ci		call_ethport_adminup_cbfn(ethport, BNA_CB_SUCCESS);
59462306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_up);
59562306a36Sopenharmony_ci		break;
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci	case ETHPORT_E_FWRESP_UP_FAIL:
59862306a36Sopenharmony_ci		call_ethport_adminup_cbfn(ethport, BNA_CB_FAIL);
59962306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_down);
60062306a36Sopenharmony_ci		break;
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ci	case ETHPORT_E_FWRESP_DOWN:
60362306a36Sopenharmony_ci		/* down_resp_wait -> up_resp_wait transition on ETHPORT_E_UP */
60462306a36Sopenharmony_ci		bna_bfi_ethport_up(ethport);
60562306a36Sopenharmony_ci		break;
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci	default:
60862306a36Sopenharmony_ci		bfa_sm_fault(event);
60962306a36Sopenharmony_ci	}
61062306a36Sopenharmony_ci}
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_cistatic void
61362306a36Sopenharmony_cibna_ethport_sm_down_resp_wait_entry(struct bna_ethport *ethport)
61462306a36Sopenharmony_ci{
61562306a36Sopenharmony_ci	/**
61662306a36Sopenharmony_ci	 * NOTE: Do not call bna_bfi_ethport_down() here. That will over step
61762306a36Sopenharmony_ci	 * mbox due to up_resp_wait -> down_resp_wait transition on event
61862306a36Sopenharmony_ci	 * ETHPORT_E_DOWN
61962306a36Sopenharmony_ci	 */
62062306a36Sopenharmony_ci}
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_cistatic void
62362306a36Sopenharmony_cibna_ethport_sm_down_resp_wait(struct bna_ethport *ethport,
62462306a36Sopenharmony_ci			enum bna_ethport_event event)
62562306a36Sopenharmony_ci{
62662306a36Sopenharmony_ci	switch (event) {
62762306a36Sopenharmony_ci	case ETHPORT_E_STOP:
62862306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_last_resp_wait);
62962306a36Sopenharmony_ci		break;
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci	case ETHPORT_E_FAIL:
63262306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
63362306a36Sopenharmony_ci		break;
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_ci	case ETHPORT_E_UP:
63662306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_up_resp_wait);
63762306a36Sopenharmony_ci		break;
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci	case ETHPORT_E_FWRESP_UP_OK:
64062306a36Sopenharmony_ci		/* up_resp_wait->down_resp_wait transition on ETHPORT_E_DOWN */
64162306a36Sopenharmony_ci		bna_bfi_ethport_down(ethport);
64262306a36Sopenharmony_ci		break;
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_ci	case ETHPORT_E_FWRESP_UP_FAIL:
64562306a36Sopenharmony_ci	case ETHPORT_E_FWRESP_DOWN:
64662306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_down);
64762306a36Sopenharmony_ci		break;
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci	default:
65062306a36Sopenharmony_ci		bfa_sm_fault(event);
65162306a36Sopenharmony_ci	}
65262306a36Sopenharmony_ci}
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_cistatic void
65562306a36Sopenharmony_cibna_ethport_sm_up_entry(struct bna_ethport *ethport)
65662306a36Sopenharmony_ci{
65762306a36Sopenharmony_ci}
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_cistatic void
66062306a36Sopenharmony_cibna_ethport_sm_up(struct bna_ethport *ethport,
66162306a36Sopenharmony_ci			enum bna_ethport_event event)
66262306a36Sopenharmony_ci{
66362306a36Sopenharmony_ci	switch (event) {
66462306a36Sopenharmony_ci	case ETHPORT_E_STOP:
66562306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_last_resp_wait);
66662306a36Sopenharmony_ci		bna_bfi_ethport_down(ethport);
66762306a36Sopenharmony_ci		break;
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_ci	case ETHPORT_E_FAIL:
67062306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
67162306a36Sopenharmony_ci		break;
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_ci	case ETHPORT_E_DOWN:
67462306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_down_resp_wait);
67562306a36Sopenharmony_ci		bna_bfi_ethport_down(ethport);
67662306a36Sopenharmony_ci		break;
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci	default:
67962306a36Sopenharmony_ci		bfa_sm_fault(event);
68062306a36Sopenharmony_ci	}
68162306a36Sopenharmony_ci}
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_cistatic void
68462306a36Sopenharmony_cibna_ethport_sm_last_resp_wait_entry(struct bna_ethport *ethport)
68562306a36Sopenharmony_ci{
68662306a36Sopenharmony_ci}
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_cistatic void
68962306a36Sopenharmony_cibna_ethport_sm_last_resp_wait(struct bna_ethport *ethport,
69062306a36Sopenharmony_ci			enum bna_ethport_event event)
69162306a36Sopenharmony_ci{
69262306a36Sopenharmony_ci	switch (event) {
69362306a36Sopenharmony_ci	case ETHPORT_E_FAIL:
69462306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
69562306a36Sopenharmony_ci		break;
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci	case ETHPORT_E_DOWN:
69862306a36Sopenharmony_ci		/**
69962306a36Sopenharmony_ci		 * This event is received due to Rx objects stopping in
70062306a36Sopenharmony_ci		 * parallel to ethport
70162306a36Sopenharmony_ci		 */
70262306a36Sopenharmony_ci		/* No-op */
70362306a36Sopenharmony_ci		break;
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_ci	case ETHPORT_E_FWRESP_UP_OK:
70662306a36Sopenharmony_ci		/* up_resp_wait->last_resp_wait transition on ETHPORT_T_STOP */
70762306a36Sopenharmony_ci		bna_bfi_ethport_down(ethport);
70862306a36Sopenharmony_ci		break;
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci	case ETHPORT_E_FWRESP_UP_FAIL:
71162306a36Sopenharmony_ci	case ETHPORT_E_FWRESP_DOWN:
71262306a36Sopenharmony_ci		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
71362306a36Sopenharmony_ci		break;
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ci	default:
71662306a36Sopenharmony_ci		bfa_sm_fault(event);
71762306a36Sopenharmony_ci	}
71862306a36Sopenharmony_ci}
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_cistatic void
72162306a36Sopenharmony_cibna_ethport_init(struct bna_ethport *ethport, struct bna *bna)
72262306a36Sopenharmony_ci{
72362306a36Sopenharmony_ci	ethport->flags |= (BNA_ETHPORT_F_ADMIN_UP | BNA_ETHPORT_F_PORT_ENABLED);
72462306a36Sopenharmony_ci	ethport->bna = bna;
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_ci	ethport->link_status = BNA_LINK_DOWN;
72762306a36Sopenharmony_ci	ethport->link_cbfn = bnad_cb_ethport_link_status;
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_ci	ethport->rx_started_count = 0;
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci	ethport->stop_cbfn = NULL;
73262306a36Sopenharmony_ci	ethport->adminup_cbfn = NULL;
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci	bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
73562306a36Sopenharmony_ci}
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_cistatic void
73862306a36Sopenharmony_cibna_ethport_uninit(struct bna_ethport *ethport)
73962306a36Sopenharmony_ci{
74062306a36Sopenharmony_ci	ethport->flags &= ~BNA_ETHPORT_F_ADMIN_UP;
74162306a36Sopenharmony_ci	ethport->flags &= ~BNA_ETHPORT_F_PORT_ENABLED;
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ci	ethport->bna = NULL;
74462306a36Sopenharmony_ci}
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_cistatic void
74762306a36Sopenharmony_cibna_ethport_start(struct bna_ethport *ethport)
74862306a36Sopenharmony_ci{
74962306a36Sopenharmony_ci	bfa_fsm_send_event(ethport, ETHPORT_E_START);
75062306a36Sopenharmony_ci}
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_cistatic void
75362306a36Sopenharmony_cibna_enet_cb_ethport_stopped(struct bna_enet *enet)
75462306a36Sopenharmony_ci{
75562306a36Sopenharmony_ci	bfa_wc_down(&enet->chld_stop_wc);
75662306a36Sopenharmony_ci}
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_cistatic void
75962306a36Sopenharmony_cibna_ethport_stop(struct bna_ethport *ethport)
76062306a36Sopenharmony_ci{
76162306a36Sopenharmony_ci	ethport->stop_cbfn = bna_enet_cb_ethport_stopped;
76262306a36Sopenharmony_ci	bfa_fsm_send_event(ethport, ETHPORT_E_STOP);
76362306a36Sopenharmony_ci}
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_cistatic void
76662306a36Sopenharmony_cibna_ethport_fail(struct bna_ethport *ethport)
76762306a36Sopenharmony_ci{
76862306a36Sopenharmony_ci	/* Reset the physical port status to enabled */
76962306a36Sopenharmony_ci	ethport->flags |= BNA_ETHPORT_F_PORT_ENABLED;
77062306a36Sopenharmony_ci
77162306a36Sopenharmony_ci	if (ethport->link_status != BNA_LINK_DOWN) {
77262306a36Sopenharmony_ci		ethport->link_status = BNA_LINK_DOWN;
77362306a36Sopenharmony_ci		ethport->link_cbfn(ethport->bna->bnad, BNA_LINK_DOWN);
77462306a36Sopenharmony_ci	}
77562306a36Sopenharmony_ci	bfa_fsm_send_event(ethport, ETHPORT_E_FAIL);
77662306a36Sopenharmony_ci}
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_ci/* Should be called only when ethport is disabled */
77962306a36Sopenharmony_civoid
78062306a36Sopenharmony_cibna_ethport_cb_rx_started(struct bna_ethport *ethport)
78162306a36Sopenharmony_ci{
78262306a36Sopenharmony_ci	ethport->rx_started_count++;
78362306a36Sopenharmony_ci
78462306a36Sopenharmony_ci	if (ethport->rx_started_count == 1) {
78562306a36Sopenharmony_ci		ethport->flags |= BNA_ETHPORT_F_RX_STARTED;
78662306a36Sopenharmony_ci
78762306a36Sopenharmony_ci		if (ethport_can_be_up(ethport))
78862306a36Sopenharmony_ci			bfa_fsm_send_event(ethport, ETHPORT_E_UP);
78962306a36Sopenharmony_ci	}
79062306a36Sopenharmony_ci}
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_civoid
79362306a36Sopenharmony_cibna_ethport_cb_rx_stopped(struct bna_ethport *ethport)
79462306a36Sopenharmony_ci{
79562306a36Sopenharmony_ci	int ethport_up = ethport_is_up(ethport);
79662306a36Sopenharmony_ci
79762306a36Sopenharmony_ci	ethport->rx_started_count--;
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci	if (ethport->rx_started_count == 0) {
80062306a36Sopenharmony_ci		ethport->flags &= ~BNA_ETHPORT_F_RX_STARTED;
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci		if (ethport_up)
80362306a36Sopenharmony_ci			bfa_fsm_send_event(ethport, ETHPORT_E_DOWN);
80462306a36Sopenharmony_ci	}
80562306a36Sopenharmony_ci}
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_ci/* ENET */
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ci#define bna_enet_chld_start(enet)					\
81062306a36Sopenharmony_cido {									\
81162306a36Sopenharmony_ci	enum bna_tx_type tx_type =					\
81262306a36Sopenharmony_ci		((enet)->type == BNA_ENET_T_REGULAR) ?			\
81362306a36Sopenharmony_ci		BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;			\
81462306a36Sopenharmony_ci	enum bna_rx_type rx_type =					\
81562306a36Sopenharmony_ci		((enet)->type == BNA_ENET_T_REGULAR) ?			\
81662306a36Sopenharmony_ci		BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;			\
81762306a36Sopenharmony_ci	bna_ethport_start(&(enet)->bna->ethport);			\
81862306a36Sopenharmony_ci	bna_tx_mod_start(&(enet)->bna->tx_mod, tx_type);		\
81962306a36Sopenharmony_ci	bna_rx_mod_start(&(enet)->bna->rx_mod, rx_type);		\
82062306a36Sopenharmony_ci} while (0)
82162306a36Sopenharmony_ci
82262306a36Sopenharmony_ci#define bna_enet_chld_stop(enet)					\
82362306a36Sopenharmony_cido {									\
82462306a36Sopenharmony_ci	enum bna_tx_type tx_type =					\
82562306a36Sopenharmony_ci		((enet)->type == BNA_ENET_T_REGULAR) ?			\
82662306a36Sopenharmony_ci		BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;			\
82762306a36Sopenharmony_ci	enum bna_rx_type rx_type =					\
82862306a36Sopenharmony_ci		((enet)->type == BNA_ENET_T_REGULAR) ?			\
82962306a36Sopenharmony_ci		BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;			\
83062306a36Sopenharmony_ci	bfa_wc_init(&(enet)->chld_stop_wc, bna_enet_cb_chld_stopped, (enet));\
83162306a36Sopenharmony_ci	bfa_wc_up(&(enet)->chld_stop_wc);				\
83262306a36Sopenharmony_ci	bna_ethport_stop(&(enet)->bna->ethport);			\
83362306a36Sopenharmony_ci	bfa_wc_up(&(enet)->chld_stop_wc);				\
83462306a36Sopenharmony_ci	bna_tx_mod_stop(&(enet)->bna->tx_mod, tx_type);			\
83562306a36Sopenharmony_ci	bfa_wc_up(&(enet)->chld_stop_wc);				\
83662306a36Sopenharmony_ci	bna_rx_mod_stop(&(enet)->bna->rx_mod, rx_type);			\
83762306a36Sopenharmony_ci	bfa_wc_wait(&(enet)->chld_stop_wc);				\
83862306a36Sopenharmony_ci} while (0)
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_ci#define bna_enet_chld_fail(enet)					\
84162306a36Sopenharmony_cido {									\
84262306a36Sopenharmony_ci	bna_ethport_fail(&(enet)->bna->ethport);			\
84362306a36Sopenharmony_ci	bna_tx_mod_fail(&(enet)->bna->tx_mod);				\
84462306a36Sopenharmony_ci	bna_rx_mod_fail(&(enet)->bna->rx_mod);				\
84562306a36Sopenharmony_ci} while (0)
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci#define bna_enet_rx_start(enet)						\
84862306a36Sopenharmony_cido {									\
84962306a36Sopenharmony_ci	enum bna_rx_type rx_type =					\
85062306a36Sopenharmony_ci		((enet)->type == BNA_ENET_T_REGULAR) ?			\
85162306a36Sopenharmony_ci		BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;			\
85262306a36Sopenharmony_ci	bna_rx_mod_start(&(enet)->bna->rx_mod, rx_type);		\
85362306a36Sopenharmony_ci} while (0)
85462306a36Sopenharmony_ci
85562306a36Sopenharmony_ci#define bna_enet_rx_stop(enet)						\
85662306a36Sopenharmony_cido {									\
85762306a36Sopenharmony_ci	enum bna_rx_type rx_type =					\
85862306a36Sopenharmony_ci		((enet)->type == BNA_ENET_T_REGULAR) ?			\
85962306a36Sopenharmony_ci		BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;			\
86062306a36Sopenharmony_ci	bfa_wc_init(&(enet)->chld_stop_wc, bna_enet_cb_chld_stopped, (enet));\
86162306a36Sopenharmony_ci	bfa_wc_up(&(enet)->chld_stop_wc);				\
86262306a36Sopenharmony_ci	bna_rx_mod_stop(&(enet)->bna->rx_mod, rx_type);			\
86362306a36Sopenharmony_ci	bfa_wc_wait(&(enet)->chld_stop_wc);				\
86462306a36Sopenharmony_ci} while (0)
86562306a36Sopenharmony_ci
86662306a36Sopenharmony_ci#define call_enet_stop_cbfn(enet)					\
86762306a36Sopenharmony_cido {									\
86862306a36Sopenharmony_ci	if ((enet)->stop_cbfn) {					\
86962306a36Sopenharmony_ci		void (*cbfn)(void *);					\
87062306a36Sopenharmony_ci		void *cbarg;						\
87162306a36Sopenharmony_ci		cbfn = (enet)->stop_cbfn;				\
87262306a36Sopenharmony_ci		cbarg = (enet)->stop_cbarg;				\
87362306a36Sopenharmony_ci		(enet)->stop_cbfn = NULL;				\
87462306a36Sopenharmony_ci		(enet)->stop_cbarg = NULL;				\
87562306a36Sopenharmony_ci		cbfn(cbarg);						\
87662306a36Sopenharmony_ci	}								\
87762306a36Sopenharmony_ci} while (0)
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_ci#define call_enet_mtu_cbfn(enet)					\
88062306a36Sopenharmony_cido {									\
88162306a36Sopenharmony_ci	if ((enet)->mtu_cbfn) {						\
88262306a36Sopenharmony_ci		void (*cbfn)(struct bnad *);				\
88362306a36Sopenharmony_ci		cbfn = (enet)->mtu_cbfn;				\
88462306a36Sopenharmony_ci		(enet)->mtu_cbfn = NULL;				\
88562306a36Sopenharmony_ci		cbfn((enet)->bna->bnad);				\
88662306a36Sopenharmony_ci	}								\
88762306a36Sopenharmony_ci} while (0)
88862306a36Sopenharmony_ci
88962306a36Sopenharmony_cistatic void bna_enet_cb_chld_stopped(void *arg);
89062306a36Sopenharmony_cistatic void bna_bfi_pause_set(struct bna_enet *enet);
89162306a36Sopenharmony_ci
89262306a36Sopenharmony_cibfa_fsm_state_decl(bna_enet, stopped, struct bna_enet,
89362306a36Sopenharmony_ci			enum bna_enet_event);
89462306a36Sopenharmony_cibfa_fsm_state_decl(bna_enet, pause_init_wait, struct bna_enet,
89562306a36Sopenharmony_ci			enum bna_enet_event);
89662306a36Sopenharmony_cibfa_fsm_state_decl(bna_enet, last_resp_wait, struct bna_enet,
89762306a36Sopenharmony_ci			enum bna_enet_event);
89862306a36Sopenharmony_cibfa_fsm_state_decl(bna_enet, started, struct bna_enet,
89962306a36Sopenharmony_ci			enum bna_enet_event);
90062306a36Sopenharmony_cibfa_fsm_state_decl(bna_enet, cfg_wait, struct bna_enet,
90162306a36Sopenharmony_ci			enum bna_enet_event);
90262306a36Sopenharmony_cibfa_fsm_state_decl(bna_enet, cfg_stop_wait, struct bna_enet,
90362306a36Sopenharmony_ci			enum bna_enet_event);
90462306a36Sopenharmony_cibfa_fsm_state_decl(bna_enet, chld_stop_wait, struct bna_enet,
90562306a36Sopenharmony_ci			enum bna_enet_event);
90662306a36Sopenharmony_ci
90762306a36Sopenharmony_cistatic void
90862306a36Sopenharmony_cibna_enet_sm_stopped_entry(struct bna_enet *enet)
90962306a36Sopenharmony_ci{
91062306a36Sopenharmony_ci	call_enet_mtu_cbfn(enet);
91162306a36Sopenharmony_ci	call_enet_stop_cbfn(enet);
91262306a36Sopenharmony_ci}
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_cistatic void
91562306a36Sopenharmony_cibna_enet_sm_stopped(struct bna_enet *enet, enum bna_enet_event event)
91662306a36Sopenharmony_ci{
91762306a36Sopenharmony_ci	switch (event) {
91862306a36Sopenharmony_ci	case ENET_E_START:
91962306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_pause_init_wait);
92062306a36Sopenharmony_ci		break;
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_ci	case ENET_E_STOP:
92362306a36Sopenharmony_ci		call_enet_stop_cbfn(enet);
92462306a36Sopenharmony_ci		break;
92562306a36Sopenharmony_ci
92662306a36Sopenharmony_ci	case ENET_E_FAIL:
92762306a36Sopenharmony_ci		/* No-op */
92862306a36Sopenharmony_ci		break;
92962306a36Sopenharmony_ci
93062306a36Sopenharmony_ci	case ENET_E_PAUSE_CFG:
93162306a36Sopenharmony_ci		break;
93262306a36Sopenharmony_ci
93362306a36Sopenharmony_ci	case ENET_E_MTU_CFG:
93462306a36Sopenharmony_ci		call_enet_mtu_cbfn(enet);
93562306a36Sopenharmony_ci		break;
93662306a36Sopenharmony_ci
93762306a36Sopenharmony_ci	case ENET_E_CHLD_STOPPED:
93862306a36Sopenharmony_ci		/**
93962306a36Sopenharmony_ci		 * This event is received due to Ethport, Tx and Rx objects
94062306a36Sopenharmony_ci		 * failing
94162306a36Sopenharmony_ci		 */
94262306a36Sopenharmony_ci		/* No-op */
94362306a36Sopenharmony_ci		break;
94462306a36Sopenharmony_ci
94562306a36Sopenharmony_ci	default:
94662306a36Sopenharmony_ci		bfa_sm_fault(event);
94762306a36Sopenharmony_ci	}
94862306a36Sopenharmony_ci}
94962306a36Sopenharmony_ci
95062306a36Sopenharmony_cistatic void
95162306a36Sopenharmony_cibna_enet_sm_pause_init_wait_entry(struct bna_enet *enet)
95262306a36Sopenharmony_ci{
95362306a36Sopenharmony_ci	bna_bfi_pause_set(enet);
95462306a36Sopenharmony_ci}
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_cistatic void
95762306a36Sopenharmony_cibna_enet_sm_pause_init_wait(struct bna_enet *enet,
95862306a36Sopenharmony_ci				enum bna_enet_event event)
95962306a36Sopenharmony_ci{
96062306a36Sopenharmony_ci	switch (event) {
96162306a36Sopenharmony_ci	case ENET_E_STOP:
96262306a36Sopenharmony_ci		enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
96362306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_last_resp_wait);
96462306a36Sopenharmony_ci		break;
96562306a36Sopenharmony_ci
96662306a36Sopenharmony_ci	case ENET_E_FAIL:
96762306a36Sopenharmony_ci		enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
96862306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
96962306a36Sopenharmony_ci		break;
97062306a36Sopenharmony_ci
97162306a36Sopenharmony_ci	case ENET_E_PAUSE_CFG:
97262306a36Sopenharmony_ci		enet->flags |= BNA_ENET_F_PAUSE_CHANGED;
97362306a36Sopenharmony_ci		break;
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_ci	case ENET_E_MTU_CFG:
97662306a36Sopenharmony_ci		/* No-op */
97762306a36Sopenharmony_ci		break;
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci	case ENET_E_FWRESP_PAUSE:
98062306a36Sopenharmony_ci		if (enet->flags & BNA_ENET_F_PAUSE_CHANGED) {
98162306a36Sopenharmony_ci			enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
98262306a36Sopenharmony_ci			bna_bfi_pause_set(enet);
98362306a36Sopenharmony_ci		} else {
98462306a36Sopenharmony_ci			bfa_fsm_set_state(enet, bna_enet_sm_started);
98562306a36Sopenharmony_ci			bna_enet_chld_start(enet);
98662306a36Sopenharmony_ci		}
98762306a36Sopenharmony_ci		break;
98862306a36Sopenharmony_ci
98962306a36Sopenharmony_ci	default:
99062306a36Sopenharmony_ci		bfa_sm_fault(event);
99162306a36Sopenharmony_ci	}
99262306a36Sopenharmony_ci}
99362306a36Sopenharmony_ci
99462306a36Sopenharmony_cistatic void
99562306a36Sopenharmony_cibna_enet_sm_last_resp_wait_entry(struct bna_enet *enet)
99662306a36Sopenharmony_ci{
99762306a36Sopenharmony_ci	enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
99862306a36Sopenharmony_ci}
99962306a36Sopenharmony_ci
100062306a36Sopenharmony_cistatic void
100162306a36Sopenharmony_cibna_enet_sm_last_resp_wait(struct bna_enet *enet,
100262306a36Sopenharmony_ci				enum bna_enet_event event)
100362306a36Sopenharmony_ci{
100462306a36Sopenharmony_ci	switch (event) {
100562306a36Sopenharmony_ci	case ENET_E_FAIL:
100662306a36Sopenharmony_ci	case ENET_E_FWRESP_PAUSE:
100762306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
100862306a36Sopenharmony_ci		break;
100962306a36Sopenharmony_ci
101062306a36Sopenharmony_ci	default:
101162306a36Sopenharmony_ci		bfa_sm_fault(event);
101262306a36Sopenharmony_ci	}
101362306a36Sopenharmony_ci}
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_cistatic void
101662306a36Sopenharmony_cibna_enet_sm_started_entry(struct bna_enet *enet)
101762306a36Sopenharmony_ci{
101862306a36Sopenharmony_ci	/**
101962306a36Sopenharmony_ci	 * NOTE: Do not call bna_enet_chld_start() here, since it will be
102062306a36Sopenharmony_ci	 * inadvertently called during cfg_wait->started transition as well
102162306a36Sopenharmony_ci	 */
102262306a36Sopenharmony_ci	call_enet_mtu_cbfn(enet);
102362306a36Sopenharmony_ci}
102462306a36Sopenharmony_ci
102562306a36Sopenharmony_cistatic void
102662306a36Sopenharmony_cibna_enet_sm_started(struct bna_enet *enet,
102762306a36Sopenharmony_ci			enum bna_enet_event event)
102862306a36Sopenharmony_ci{
102962306a36Sopenharmony_ci	switch (event) {
103062306a36Sopenharmony_ci	case ENET_E_STOP:
103162306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_chld_stop_wait);
103262306a36Sopenharmony_ci		break;
103362306a36Sopenharmony_ci
103462306a36Sopenharmony_ci	case ENET_E_FAIL:
103562306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
103662306a36Sopenharmony_ci		bna_enet_chld_fail(enet);
103762306a36Sopenharmony_ci		break;
103862306a36Sopenharmony_ci
103962306a36Sopenharmony_ci	case ENET_E_PAUSE_CFG:
104062306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_cfg_wait);
104162306a36Sopenharmony_ci		bna_bfi_pause_set(enet);
104262306a36Sopenharmony_ci		break;
104362306a36Sopenharmony_ci
104462306a36Sopenharmony_ci	case ENET_E_MTU_CFG:
104562306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_cfg_wait);
104662306a36Sopenharmony_ci		bna_enet_rx_stop(enet);
104762306a36Sopenharmony_ci		break;
104862306a36Sopenharmony_ci
104962306a36Sopenharmony_ci	default:
105062306a36Sopenharmony_ci		bfa_sm_fault(event);
105162306a36Sopenharmony_ci	}
105262306a36Sopenharmony_ci}
105362306a36Sopenharmony_ci
105462306a36Sopenharmony_cistatic void
105562306a36Sopenharmony_cibna_enet_sm_cfg_wait_entry(struct bna_enet *enet)
105662306a36Sopenharmony_ci{
105762306a36Sopenharmony_ci}
105862306a36Sopenharmony_ci
105962306a36Sopenharmony_cistatic void
106062306a36Sopenharmony_cibna_enet_sm_cfg_wait(struct bna_enet *enet,
106162306a36Sopenharmony_ci			enum bna_enet_event event)
106262306a36Sopenharmony_ci{
106362306a36Sopenharmony_ci	switch (event) {
106462306a36Sopenharmony_ci	case ENET_E_STOP:
106562306a36Sopenharmony_ci		enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
106662306a36Sopenharmony_ci		enet->flags &= ~BNA_ENET_F_MTU_CHANGED;
106762306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_cfg_stop_wait);
106862306a36Sopenharmony_ci		break;
106962306a36Sopenharmony_ci
107062306a36Sopenharmony_ci	case ENET_E_FAIL:
107162306a36Sopenharmony_ci		enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
107262306a36Sopenharmony_ci		enet->flags &= ~BNA_ENET_F_MTU_CHANGED;
107362306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
107462306a36Sopenharmony_ci		bna_enet_chld_fail(enet);
107562306a36Sopenharmony_ci		break;
107662306a36Sopenharmony_ci
107762306a36Sopenharmony_ci	case ENET_E_PAUSE_CFG:
107862306a36Sopenharmony_ci		enet->flags |= BNA_ENET_F_PAUSE_CHANGED;
107962306a36Sopenharmony_ci		break;
108062306a36Sopenharmony_ci
108162306a36Sopenharmony_ci	case ENET_E_MTU_CFG:
108262306a36Sopenharmony_ci		enet->flags |= BNA_ENET_F_MTU_CHANGED;
108362306a36Sopenharmony_ci		break;
108462306a36Sopenharmony_ci
108562306a36Sopenharmony_ci	case ENET_E_CHLD_STOPPED:
108662306a36Sopenharmony_ci		bna_enet_rx_start(enet);
108762306a36Sopenharmony_ci		fallthrough;
108862306a36Sopenharmony_ci	case ENET_E_FWRESP_PAUSE:
108962306a36Sopenharmony_ci		if (enet->flags & BNA_ENET_F_PAUSE_CHANGED) {
109062306a36Sopenharmony_ci			enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
109162306a36Sopenharmony_ci			bna_bfi_pause_set(enet);
109262306a36Sopenharmony_ci		} else if (enet->flags & BNA_ENET_F_MTU_CHANGED) {
109362306a36Sopenharmony_ci			enet->flags &= ~BNA_ENET_F_MTU_CHANGED;
109462306a36Sopenharmony_ci			bna_enet_rx_stop(enet);
109562306a36Sopenharmony_ci		} else {
109662306a36Sopenharmony_ci			bfa_fsm_set_state(enet, bna_enet_sm_started);
109762306a36Sopenharmony_ci		}
109862306a36Sopenharmony_ci		break;
109962306a36Sopenharmony_ci
110062306a36Sopenharmony_ci	default:
110162306a36Sopenharmony_ci		bfa_sm_fault(event);
110262306a36Sopenharmony_ci	}
110362306a36Sopenharmony_ci}
110462306a36Sopenharmony_ci
110562306a36Sopenharmony_cistatic void
110662306a36Sopenharmony_cibna_enet_sm_cfg_stop_wait_entry(struct bna_enet *enet)
110762306a36Sopenharmony_ci{
110862306a36Sopenharmony_ci	enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
110962306a36Sopenharmony_ci	enet->flags &= ~BNA_ENET_F_MTU_CHANGED;
111062306a36Sopenharmony_ci}
111162306a36Sopenharmony_ci
111262306a36Sopenharmony_cistatic void
111362306a36Sopenharmony_cibna_enet_sm_cfg_stop_wait(struct bna_enet *enet,
111462306a36Sopenharmony_ci				enum bna_enet_event event)
111562306a36Sopenharmony_ci{
111662306a36Sopenharmony_ci	switch (event) {
111762306a36Sopenharmony_ci	case ENET_E_FAIL:
111862306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
111962306a36Sopenharmony_ci		bna_enet_chld_fail(enet);
112062306a36Sopenharmony_ci		break;
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_ci	case ENET_E_FWRESP_PAUSE:
112362306a36Sopenharmony_ci	case ENET_E_CHLD_STOPPED:
112462306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_chld_stop_wait);
112562306a36Sopenharmony_ci		break;
112662306a36Sopenharmony_ci
112762306a36Sopenharmony_ci	default:
112862306a36Sopenharmony_ci		bfa_sm_fault(event);
112962306a36Sopenharmony_ci	}
113062306a36Sopenharmony_ci}
113162306a36Sopenharmony_ci
113262306a36Sopenharmony_cistatic void
113362306a36Sopenharmony_cibna_enet_sm_chld_stop_wait_entry(struct bna_enet *enet)
113462306a36Sopenharmony_ci{
113562306a36Sopenharmony_ci	bna_enet_chld_stop(enet);
113662306a36Sopenharmony_ci}
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_cistatic void
113962306a36Sopenharmony_cibna_enet_sm_chld_stop_wait(struct bna_enet *enet,
114062306a36Sopenharmony_ci				enum bna_enet_event event)
114162306a36Sopenharmony_ci{
114262306a36Sopenharmony_ci	switch (event) {
114362306a36Sopenharmony_ci	case ENET_E_FAIL:
114462306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
114562306a36Sopenharmony_ci		bna_enet_chld_fail(enet);
114662306a36Sopenharmony_ci		break;
114762306a36Sopenharmony_ci
114862306a36Sopenharmony_ci	case ENET_E_CHLD_STOPPED:
114962306a36Sopenharmony_ci		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
115062306a36Sopenharmony_ci		break;
115162306a36Sopenharmony_ci
115262306a36Sopenharmony_ci	default:
115362306a36Sopenharmony_ci		bfa_sm_fault(event);
115462306a36Sopenharmony_ci	}
115562306a36Sopenharmony_ci}
115662306a36Sopenharmony_ci
115762306a36Sopenharmony_cistatic void
115862306a36Sopenharmony_cibna_bfi_pause_set(struct bna_enet *enet)
115962306a36Sopenharmony_ci{
116062306a36Sopenharmony_ci	struct bfi_enet_set_pause_req *pause_req = &enet->pause_req;
116162306a36Sopenharmony_ci
116262306a36Sopenharmony_ci	bfi_msgq_mhdr_set(pause_req->mh, BFI_MC_ENET,
116362306a36Sopenharmony_ci		BFI_ENET_H2I_SET_PAUSE_REQ, 0, 0);
116462306a36Sopenharmony_ci	pause_req->mh.num_entries = htons(
116562306a36Sopenharmony_ci	bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_set_pause_req)));
116662306a36Sopenharmony_ci	pause_req->tx_pause = enet->pause_config.tx_pause;
116762306a36Sopenharmony_ci	pause_req->rx_pause = enet->pause_config.rx_pause;
116862306a36Sopenharmony_ci
116962306a36Sopenharmony_ci	bfa_msgq_cmd_set(&enet->msgq_cmd, NULL, NULL,
117062306a36Sopenharmony_ci		sizeof(struct bfi_enet_set_pause_req), &pause_req->mh);
117162306a36Sopenharmony_ci	bfa_msgq_cmd_post(&enet->bna->msgq, &enet->msgq_cmd);
117262306a36Sopenharmony_ci}
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_cistatic void
117562306a36Sopenharmony_cibna_enet_cb_chld_stopped(void *arg)
117662306a36Sopenharmony_ci{
117762306a36Sopenharmony_ci	struct bna_enet *enet = (struct bna_enet *)arg;
117862306a36Sopenharmony_ci
117962306a36Sopenharmony_ci	bfa_fsm_send_event(enet, ENET_E_CHLD_STOPPED);
118062306a36Sopenharmony_ci}
118162306a36Sopenharmony_ci
118262306a36Sopenharmony_cistatic void
118362306a36Sopenharmony_cibna_enet_init(struct bna_enet *enet, struct bna *bna)
118462306a36Sopenharmony_ci{
118562306a36Sopenharmony_ci	enet->bna = bna;
118662306a36Sopenharmony_ci	enet->flags = 0;
118762306a36Sopenharmony_ci	enet->mtu = 0;
118862306a36Sopenharmony_ci	enet->type = BNA_ENET_T_REGULAR;
118962306a36Sopenharmony_ci
119062306a36Sopenharmony_ci	enet->stop_cbfn = NULL;
119162306a36Sopenharmony_ci	enet->stop_cbarg = NULL;
119262306a36Sopenharmony_ci
119362306a36Sopenharmony_ci	enet->mtu_cbfn = NULL;
119462306a36Sopenharmony_ci
119562306a36Sopenharmony_ci	bfa_fsm_set_state(enet, bna_enet_sm_stopped);
119662306a36Sopenharmony_ci}
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_cistatic void
119962306a36Sopenharmony_cibna_enet_uninit(struct bna_enet *enet)
120062306a36Sopenharmony_ci{
120162306a36Sopenharmony_ci	enet->flags = 0;
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_ci	enet->bna = NULL;
120462306a36Sopenharmony_ci}
120562306a36Sopenharmony_ci
120662306a36Sopenharmony_cistatic void
120762306a36Sopenharmony_cibna_enet_start(struct bna_enet *enet)
120862306a36Sopenharmony_ci{
120962306a36Sopenharmony_ci	enet->flags |= BNA_ENET_F_IOCETH_READY;
121062306a36Sopenharmony_ci	if (enet->flags & BNA_ENET_F_ENABLED)
121162306a36Sopenharmony_ci		bfa_fsm_send_event(enet, ENET_E_START);
121262306a36Sopenharmony_ci}
121362306a36Sopenharmony_ci
121462306a36Sopenharmony_cistatic void
121562306a36Sopenharmony_cibna_ioceth_cb_enet_stopped(void *arg)
121662306a36Sopenharmony_ci{
121762306a36Sopenharmony_ci	struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
121862306a36Sopenharmony_ci
121962306a36Sopenharmony_ci	bfa_fsm_send_event(ioceth, IOCETH_E_ENET_STOPPED);
122062306a36Sopenharmony_ci}
122162306a36Sopenharmony_ci
122262306a36Sopenharmony_cistatic void
122362306a36Sopenharmony_cibna_enet_stop(struct bna_enet *enet)
122462306a36Sopenharmony_ci{
122562306a36Sopenharmony_ci	enet->stop_cbfn = bna_ioceth_cb_enet_stopped;
122662306a36Sopenharmony_ci	enet->stop_cbarg = &enet->bna->ioceth;
122762306a36Sopenharmony_ci
122862306a36Sopenharmony_ci	enet->flags &= ~BNA_ENET_F_IOCETH_READY;
122962306a36Sopenharmony_ci	bfa_fsm_send_event(enet, ENET_E_STOP);
123062306a36Sopenharmony_ci}
123162306a36Sopenharmony_ci
123262306a36Sopenharmony_cistatic void
123362306a36Sopenharmony_cibna_enet_fail(struct bna_enet *enet)
123462306a36Sopenharmony_ci{
123562306a36Sopenharmony_ci	enet->flags &= ~BNA_ENET_F_IOCETH_READY;
123662306a36Sopenharmony_ci	bfa_fsm_send_event(enet, ENET_E_FAIL);
123762306a36Sopenharmony_ci}
123862306a36Sopenharmony_ci
123962306a36Sopenharmony_civoid
124062306a36Sopenharmony_cibna_enet_cb_tx_stopped(struct bna_enet *enet)
124162306a36Sopenharmony_ci{
124262306a36Sopenharmony_ci	bfa_wc_down(&enet->chld_stop_wc);
124362306a36Sopenharmony_ci}
124462306a36Sopenharmony_ci
124562306a36Sopenharmony_civoid
124662306a36Sopenharmony_cibna_enet_cb_rx_stopped(struct bna_enet *enet)
124762306a36Sopenharmony_ci{
124862306a36Sopenharmony_ci	bfa_wc_down(&enet->chld_stop_wc);
124962306a36Sopenharmony_ci}
125062306a36Sopenharmony_ci
125162306a36Sopenharmony_ciint
125262306a36Sopenharmony_cibna_enet_mtu_get(struct bna_enet *enet)
125362306a36Sopenharmony_ci{
125462306a36Sopenharmony_ci	return enet->mtu;
125562306a36Sopenharmony_ci}
125662306a36Sopenharmony_ci
125762306a36Sopenharmony_civoid
125862306a36Sopenharmony_cibna_enet_enable(struct bna_enet *enet)
125962306a36Sopenharmony_ci{
126062306a36Sopenharmony_ci	if (enet->fsm != bna_enet_sm_stopped)
126162306a36Sopenharmony_ci		return;
126262306a36Sopenharmony_ci
126362306a36Sopenharmony_ci	enet->flags |= BNA_ENET_F_ENABLED;
126462306a36Sopenharmony_ci
126562306a36Sopenharmony_ci	if (enet->flags & BNA_ENET_F_IOCETH_READY)
126662306a36Sopenharmony_ci		bfa_fsm_send_event(enet, ENET_E_START);
126762306a36Sopenharmony_ci}
126862306a36Sopenharmony_ci
126962306a36Sopenharmony_civoid
127062306a36Sopenharmony_cibna_enet_disable(struct bna_enet *enet, enum bna_cleanup_type type,
127162306a36Sopenharmony_ci		 void (*cbfn)(void *))
127262306a36Sopenharmony_ci{
127362306a36Sopenharmony_ci	if (type == BNA_SOFT_CLEANUP) {
127462306a36Sopenharmony_ci		(*cbfn)(enet->bna->bnad);
127562306a36Sopenharmony_ci		return;
127662306a36Sopenharmony_ci	}
127762306a36Sopenharmony_ci
127862306a36Sopenharmony_ci	enet->stop_cbfn = cbfn;
127962306a36Sopenharmony_ci	enet->stop_cbarg = enet->bna->bnad;
128062306a36Sopenharmony_ci
128162306a36Sopenharmony_ci	enet->flags &= ~BNA_ENET_F_ENABLED;
128262306a36Sopenharmony_ci
128362306a36Sopenharmony_ci	bfa_fsm_send_event(enet, ENET_E_STOP);
128462306a36Sopenharmony_ci}
128562306a36Sopenharmony_ci
128662306a36Sopenharmony_civoid
128762306a36Sopenharmony_cibna_enet_pause_config(struct bna_enet *enet,
128862306a36Sopenharmony_ci		      struct bna_pause_config *pause_config)
128962306a36Sopenharmony_ci{
129062306a36Sopenharmony_ci	enet->pause_config = *pause_config;
129162306a36Sopenharmony_ci
129262306a36Sopenharmony_ci	bfa_fsm_send_event(enet, ENET_E_PAUSE_CFG);
129362306a36Sopenharmony_ci}
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_civoid
129662306a36Sopenharmony_cibna_enet_mtu_set(struct bna_enet *enet, int mtu,
129762306a36Sopenharmony_ci		 void (*cbfn)(struct bnad *))
129862306a36Sopenharmony_ci{
129962306a36Sopenharmony_ci	enet->mtu = mtu;
130062306a36Sopenharmony_ci
130162306a36Sopenharmony_ci	enet->mtu_cbfn = cbfn;
130262306a36Sopenharmony_ci
130362306a36Sopenharmony_ci	bfa_fsm_send_event(enet, ENET_E_MTU_CFG);
130462306a36Sopenharmony_ci}
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_civoid
130762306a36Sopenharmony_cibna_enet_perm_mac_get(struct bna_enet *enet, u8 *mac)
130862306a36Sopenharmony_ci{
130962306a36Sopenharmony_ci	bfa_nw_ioc_get_mac(&enet->bna->ioceth.ioc, mac);
131062306a36Sopenharmony_ci}
131162306a36Sopenharmony_ci
131262306a36Sopenharmony_ci/* IOCETH */
131362306a36Sopenharmony_ci
131462306a36Sopenharmony_ci#define enable_mbox_intr(_ioceth)					\
131562306a36Sopenharmony_cido {									\
131662306a36Sopenharmony_ci	u32 intr_status;						\
131762306a36Sopenharmony_ci	bna_intr_status_get((_ioceth)->bna, intr_status);		\
131862306a36Sopenharmony_ci	bnad_cb_mbox_intr_enable((_ioceth)->bna->bnad);			\
131962306a36Sopenharmony_ci	bna_mbox_intr_enable((_ioceth)->bna);				\
132062306a36Sopenharmony_ci} while (0)
132162306a36Sopenharmony_ci
132262306a36Sopenharmony_ci#define disable_mbox_intr(_ioceth)					\
132362306a36Sopenharmony_cido {									\
132462306a36Sopenharmony_ci	bna_mbox_intr_disable((_ioceth)->bna);				\
132562306a36Sopenharmony_ci	bnad_cb_mbox_intr_disable((_ioceth)->bna->bnad);		\
132662306a36Sopenharmony_ci} while (0)
132762306a36Sopenharmony_ci
132862306a36Sopenharmony_ci#define call_ioceth_stop_cbfn(_ioceth)					\
132962306a36Sopenharmony_cido {									\
133062306a36Sopenharmony_ci	if ((_ioceth)->stop_cbfn) {					\
133162306a36Sopenharmony_ci		void (*cbfn)(struct bnad *);				\
133262306a36Sopenharmony_ci		struct bnad *cbarg;					\
133362306a36Sopenharmony_ci		cbfn = (_ioceth)->stop_cbfn;				\
133462306a36Sopenharmony_ci		cbarg = (_ioceth)->stop_cbarg;				\
133562306a36Sopenharmony_ci		(_ioceth)->stop_cbfn = NULL;				\
133662306a36Sopenharmony_ci		(_ioceth)->stop_cbarg = NULL;				\
133762306a36Sopenharmony_ci		cbfn(cbarg);						\
133862306a36Sopenharmony_ci	}								\
133962306a36Sopenharmony_ci} while (0)
134062306a36Sopenharmony_ci
134162306a36Sopenharmony_ci#define bna_stats_mod_uninit(_stats_mod)				\
134262306a36Sopenharmony_cido {									\
134362306a36Sopenharmony_ci} while (0)
134462306a36Sopenharmony_ci
134562306a36Sopenharmony_ci#define bna_stats_mod_start(_stats_mod)					\
134662306a36Sopenharmony_cido {									\
134762306a36Sopenharmony_ci	(_stats_mod)->ioc_ready = true;					\
134862306a36Sopenharmony_ci} while (0)
134962306a36Sopenharmony_ci
135062306a36Sopenharmony_ci#define bna_stats_mod_stop(_stats_mod)					\
135162306a36Sopenharmony_cido {									\
135262306a36Sopenharmony_ci	(_stats_mod)->ioc_ready = false;				\
135362306a36Sopenharmony_ci} while (0)
135462306a36Sopenharmony_ci
135562306a36Sopenharmony_ci#define bna_stats_mod_fail(_stats_mod)					\
135662306a36Sopenharmony_cido {									\
135762306a36Sopenharmony_ci	(_stats_mod)->ioc_ready = false;				\
135862306a36Sopenharmony_ci	(_stats_mod)->stats_get_busy = false;				\
135962306a36Sopenharmony_ci	(_stats_mod)->stats_clr_busy = false;				\
136062306a36Sopenharmony_ci} while (0)
136162306a36Sopenharmony_ci
136262306a36Sopenharmony_cistatic void bna_bfi_attr_get(struct bna_ioceth *ioceth);
136362306a36Sopenharmony_ci
136462306a36Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, stopped, struct bna_ioceth,
136562306a36Sopenharmony_ci			enum bna_ioceth_event);
136662306a36Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, ioc_ready_wait, struct bna_ioceth,
136762306a36Sopenharmony_ci			enum bna_ioceth_event);
136862306a36Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, enet_attr_wait, struct bna_ioceth,
136962306a36Sopenharmony_ci			enum bna_ioceth_event);
137062306a36Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, ready, struct bna_ioceth,
137162306a36Sopenharmony_ci			enum bna_ioceth_event);
137262306a36Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, last_resp_wait, struct bna_ioceth,
137362306a36Sopenharmony_ci			enum bna_ioceth_event);
137462306a36Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, enet_stop_wait, struct bna_ioceth,
137562306a36Sopenharmony_ci			enum bna_ioceth_event);
137662306a36Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, ioc_disable_wait, struct bna_ioceth,
137762306a36Sopenharmony_ci			enum bna_ioceth_event);
137862306a36Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, failed, struct bna_ioceth,
137962306a36Sopenharmony_ci			enum bna_ioceth_event);
138062306a36Sopenharmony_ci
138162306a36Sopenharmony_cistatic void
138262306a36Sopenharmony_cibna_ioceth_sm_stopped_entry(struct bna_ioceth *ioceth)
138362306a36Sopenharmony_ci{
138462306a36Sopenharmony_ci	call_ioceth_stop_cbfn(ioceth);
138562306a36Sopenharmony_ci}
138662306a36Sopenharmony_ci
138762306a36Sopenharmony_cistatic void
138862306a36Sopenharmony_cibna_ioceth_sm_stopped(struct bna_ioceth *ioceth,
138962306a36Sopenharmony_ci			enum bna_ioceth_event event)
139062306a36Sopenharmony_ci{
139162306a36Sopenharmony_ci	switch (event) {
139262306a36Sopenharmony_ci	case IOCETH_E_ENABLE:
139362306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_ready_wait);
139462306a36Sopenharmony_ci		bfa_nw_ioc_enable(&ioceth->ioc);
139562306a36Sopenharmony_ci		break;
139662306a36Sopenharmony_ci
139762306a36Sopenharmony_ci	case IOCETH_E_DISABLE:
139862306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_stopped);
139962306a36Sopenharmony_ci		break;
140062306a36Sopenharmony_ci
140162306a36Sopenharmony_ci	case IOCETH_E_IOC_RESET:
140262306a36Sopenharmony_ci		enable_mbox_intr(ioceth);
140362306a36Sopenharmony_ci		break;
140462306a36Sopenharmony_ci
140562306a36Sopenharmony_ci	case IOCETH_E_IOC_FAILED:
140662306a36Sopenharmony_ci		disable_mbox_intr(ioceth);
140762306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed);
140862306a36Sopenharmony_ci		break;
140962306a36Sopenharmony_ci
141062306a36Sopenharmony_ci	default:
141162306a36Sopenharmony_ci		bfa_sm_fault(event);
141262306a36Sopenharmony_ci	}
141362306a36Sopenharmony_ci}
141462306a36Sopenharmony_ci
141562306a36Sopenharmony_cistatic void
141662306a36Sopenharmony_cibna_ioceth_sm_ioc_ready_wait_entry(struct bna_ioceth *ioceth)
141762306a36Sopenharmony_ci{
141862306a36Sopenharmony_ci	/**
141962306a36Sopenharmony_ci	 * Do not call bfa_nw_ioc_enable() here. It must be called in the
142062306a36Sopenharmony_ci	 * previous state due to failed -> ioc_ready_wait transition.
142162306a36Sopenharmony_ci	 */
142262306a36Sopenharmony_ci}
142362306a36Sopenharmony_ci
142462306a36Sopenharmony_cistatic void
142562306a36Sopenharmony_cibna_ioceth_sm_ioc_ready_wait(struct bna_ioceth *ioceth,
142662306a36Sopenharmony_ci				enum bna_ioceth_event event)
142762306a36Sopenharmony_ci{
142862306a36Sopenharmony_ci	switch (event) {
142962306a36Sopenharmony_ci	case IOCETH_E_DISABLE:
143062306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
143162306a36Sopenharmony_ci		bfa_nw_ioc_disable(&ioceth->ioc);
143262306a36Sopenharmony_ci		break;
143362306a36Sopenharmony_ci
143462306a36Sopenharmony_ci	case IOCETH_E_IOC_RESET:
143562306a36Sopenharmony_ci		enable_mbox_intr(ioceth);
143662306a36Sopenharmony_ci		break;
143762306a36Sopenharmony_ci
143862306a36Sopenharmony_ci	case IOCETH_E_IOC_FAILED:
143962306a36Sopenharmony_ci		disable_mbox_intr(ioceth);
144062306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed);
144162306a36Sopenharmony_ci		break;
144262306a36Sopenharmony_ci
144362306a36Sopenharmony_ci	case IOCETH_E_IOC_READY:
144462306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_enet_attr_wait);
144562306a36Sopenharmony_ci		break;
144662306a36Sopenharmony_ci
144762306a36Sopenharmony_ci	default:
144862306a36Sopenharmony_ci		bfa_sm_fault(event);
144962306a36Sopenharmony_ci	}
145062306a36Sopenharmony_ci}
145162306a36Sopenharmony_ci
145262306a36Sopenharmony_cistatic void
145362306a36Sopenharmony_cibna_ioceth_sm_enet_attr_wait_entry(struct bna_ioceth *ioceth)
145462306a36Sopenharmony_ci{
145562306a36Sopenharmony_ci	bna_bfi_attr_get(ioceth);
145662306a36Sopenharmony_ci}
145762306a36Sopenharmony_ci
145862306a36Sopenharmony_cistatic void
145962306a36Sopenharmony_cibna_ioceth_sm_enet_attr_wait(struct bna_ioceth *ioceth,
146062306a36Sopenharmony_ci				enum bna_ioceth_event event)
146162306a36Sopenharmony_ci{
146262306a36Sopenharmony_ci	switch (event) {
146362306a36Sopenharmony_ci	case IOCETH_E_DISABLE:
146462306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_last_resp_wait);
146562306a36Sopenharmony_ci		break;
146662306a36Sopenharmony_ci
146762306a36Sopenharmony_ci	case IOCETH_E_IOC_FAILED:
146862306a36Sopenharmony_ci		disable_mbox_intr(ioceth);
146962306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed);
147062306a36Sopenharmony_ci		break;
147162306a36Sopenharmony_ci
147262306a36Sopenharmony_ci	case IOCETH_E_ENET_ATTR_RESP:
147362306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ready);
147462306a36Sopenharmony_ci		break;
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_ci	default:
147762306a36Sopenharmony_ci		bfa_sm_fault(event);
147862306a36Sopenharmony_ci	}
147962306a36Sopenharmony_ci}
148062306a36Sopenharmony_ci
148162306a36Sopenharmony_cistatic void
148262306a36Sopenharmony_cibna_ioceth_sm_ready_entry(struct bna_ioceth *ioceth)
148362306a36Sopenharmony_ci{
148462306a36Sopenharmony_ci	bna_enet_start(&ioceth->bna->enet);
148562306a36Sopenharmony_ci	bna_stats_mod_start(&ioceth->bna->stats_mod);
148662306a36Sopenharmony_ci	bnad_cb_ioceth_ready(ioceth->bna->bnad);
148762306a36Sopenharmony_ci}
148862306a36Sopenharmony_ci
148962306a36Sopenharmony_cistatic void
149062306a36Sopenharmony_cibna_ioceth_sm_ready(struct bna_ioceth *ioceth, enum bna_ioceth_event event)
149162306a36Sopenharmony_ci{
149262306a36Sopenharmony_ci	switch (event) {
149362306a36Sopenharmony_ci	case IOCETH_E_DISABLE:
149462306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_enet_stop_wait);
149562306a36Sopenharmony_ci		break;
149662306a36Sopenharmony_ci
149762306a36Sopenharmony_ci	case IOCETH_E_IOC_FAILED:
149862306a36Sopenharmony_ci		disable_mbox_intr(ioceth);
149962306a36Sopenharmony_ci		bna_enet_fail(&ioceth->bna->enet);
150062306a36Sopenharmony_ci		bna_stats_mod_fail(&ioceth->bna->stats_mod);
150162306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed);
150262306a36Sopenharmony_ci		break;
150362306a36Sopenharmony_ci
150462306a36Sopenharmony_ci	default:
150562306a36Sopenharmony_ci		bfa_sm_fault(event);
150662306a36Sopenharmony_ci	}
150762306a36Sopenharmony_ci}
150862306a36Sopenharmony_ci
150962306a36Sopenharmony_cistatic void
151062306a36Sopenharmony_cibna_ioceth_sm_last_resp_wait_entry(struct bna_ioceth *ioceth)
151162306a36Sopenharmony_ci{
151262306a36Sopenharmony_ci}
151362306a36Sopenharmony_ci
151462306a36Sopenharmony_cistatic void
151562306a36Sopenharmony_cibna_ioceth_sm_last_resp_wait(struct bna_ioceth *ioceth,
151662306a36Sopenharmony_ci				enum bna_ioceth_event event)
151762306a36Sopenharmony_ci{
151862306a36Sopenharmony_ci	switch (event) {
151962306a36Sopenharmony_ci	case IOCETH_E_IOC_FAILED:
152062306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
152162306a36Sopenharmony_ci		disable_mbox_intr(ioceth);
152262306a36Sopenharmony_ci		bfa_nw_ioc_disable(&ioceth->ioc);
152362306a36Sopenharmony_ci		break;
152462306a36Sopenharmony_ci
152562306a36Sopenharmony_ci	case IOCETH_E_ENET_ATTR_RESP:
152662306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
152762306a36Sopenharmony_ci		bfa_nw_ioc_disable(&ioceth->ioc);
152862306a36Sopenharmony_ci		break;
152962306a36Sopenharmony_ci
153062306a36Sopenharmony_ci	default:
153162306a36Sopenharmony_ci		bfa_sm_fault(event);
153262306a36Sopenharmony_ci	}
153362306a36Sopenharmony_ci}
153462306a36Sopenharmony_ci
153562306a36Sopenharmony_cistatic void
153662306a36Sopenharmony_cibna_ioceth_sm_enet_stop_wait_entry(struct bna_ioceth *ioceth)
153762306a36Sopenharmony_ci{
153862306a36Sopenharmony_ci	bna_stats_mod_stop(&ioceth->bna->stats_mod);
153962306a36Sopenharmony_ci	bna_enet_stop(&ioceth->bna->enet);
154062306a36Sopenharmony_ci}
154162306a36Sopenharmony_ci
154262306a36Sopenharmony_cistatic void
154362306a36Sopenharmony_cibna_ioceth_sm_enet_stop_wait(struct bna_ioceth *ioceth,
154462306a36Sopenharmony_ci				enum bna_ioceth_event event)
154562306a36Sopenharmony_ci{
154662306a36Sopenharmony_ci	switch (event) {
154762306a36Sopenharmony_ci	case IOCETH_E_IOC_FAILED:
154862306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
154962306a36Sopenharmony_ci		disable_mbox_intr(ioceth);
155062306a36Sopenharmony_ci		bna_enet_fail(&ioceth->bna->enet);
155162306a36Sopenharmony_ci		bna_stats_mod_fail(&ioceth->bna->stats_mod);
155262306a36Sopenharmony_ci		bfa_nw_ioc_disable(&ioceth->ioc);
155362306a36Sopenharmony_ci		break;
155462306a36Sopenharmony_ci
155562306a36Sopenharmony_ci	case IOCETH_E_ENET_STOPPED:
155662306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
155762306a36Sopenharmony_ci		bfa_nw_ioc_disable(&ioceth->ioc);
155862306a36Sopenharmony_ci		break;
155962306a36Sopenharmony_ci
156062306a36Sopenharmony_ci	default:
156162306a36Sopenharmony_ci		bfa_sm_fault(event);
156262306a36Sopenharmony_ci	}
156362306a36Sopenharmony_ci}
156462306a36Sopenharmony_ci
156562306a36Sopenharmony_cistatic void
156662306a36Sopenharmony_cibna_ioceth_sm_ioc_disable_wait_entry(struct bna_ioceth *ioceth)
156762306a36Sopenharmony_ci{
156862306a36Sopenharmony_ci}
156962306a36Sopenharmony_ci
157062306a36Sopenharmony_cistatic void
157162306a36Sopenharmony_cibna_ioceth_sm_ioc_disable_wait(struct bna_ioceth *ioceth,
157262306a36Sopenharmony_ci				enum bna_ioceth_event event)
157362306a36Sopenharmony_ci{
157462306a36Sopenharmony_ci	switch (event) {
157562306a36Sopenharmony_ci	case IOCETH_E_IOC_DISABLED:
157662306a36Sopenharmony_ci		disable_mbox_intr(ioceth);
157762306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_stopped);
157862306a36Sopenharmony_ci		break;
157962306a36Sopenharmony_ci
158062306a36Sopenharmony_ci	case IOCETH_E_ENET_STOPPED:
158162306a36Sopenharmony_ci		/* This event is received due to enet failing */
158262306a36Sopenharmony_ci		/* No-op */
158362306a36Sopenharmony_ci		break;
158462306a36Sopenharmony_ci
158562306a36Sopenharmony_ci	default:
158662306a36Sopenharmony_ci		bfa_sm_fault(event);
158762306a36Sopenharmony_ci	}
158862306a36Sopenharmony_ci}
158962306a36Sopenharmony_ci
159062306a36Sopenharmony_cistatic void
159162306a36Sopenharmony_cibna_ioceth_sm_failed_entry(struct bna_ioceth *ioceth)
159262306a36Sopenharmony_ci{
159362306a36Sopenharmony_ci	bnad_cb_ioceth_failed(ioceth->bna->bnad);
159462306a36Sopenharmony_ci}
159562306a36Sopenharmony_ci
159662306a36Sopenharmony_cistatic void
159762306a36Sopenharmony_cibna_ioceth_sm_failed(struct bna_ioceth *ioceth,
159862306a36Sopenharmony_ci			enum bna_ioceth_event event)
159962306a36Sopenharmony_ci{
160062306a36Sopenharmony_ci	switch (event) {
160162306a36Sopenharmony_ci	case IOCETH_E_DISABLE:
160262306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
160362306a36Sopenharmony_ci		bfa_nw_ioc_disable(&ioceth->ioc);
160462306a36Sopenharmony_ci		break;
160562306a36Sopenharmony_ci
160662306a36Sopenharmony_ci	case IOCETH_E_IOC_RESET:
160762306a36Sopenharmony_ci		enable_mbox_intr(ioceth);
160862306a36Sopenharmony_ci		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_ready_wait);
160962306a36Sopenharmony_ci		break;
161062306a36Sopenharmony_ci
161162306a36Sopenharmony_ci	case IOCETH_E_IOC_FAILED:
161262306a36Sopenharmony_ci		break;
161362306a36Sopenharmony_ci
161462306a36Sopenharmony_ci	default:
161562306a36Sopenharmony_ci		bfa_sm_fault(event);
161662306a36Sopenharmony_ci	}
161762306a36Sopenharmony_ci}
161862306a36Sopenharmony_ci
161962306a36Sopenharmony_cistatic void
162062306a36Sopenharmony_cibna_bfi_attr_get(struct bna_ioceth *ioceth)
162162306a36Sopenharmony_ci{
162262306a36Sopenharmony_ci	struct bfi_enet_attr_req *attr_req = &ioceth->attr_req;
162362306a36Sopenharmony_ci
162462306a36Sopenharmony_ci	bfi_msgq_mhdr_set(attr_req->mh, BFI_MC_ENET,
162562306a36Sopenharmony_ci		BFI_ENET_H2I_GET_ATTR_REQ, 0, 0);
162662306a36Sopenharmony_ci	attr_req->mh.num_entries = htons(
162762306a36Sopenharmony_ci	bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_attr_req)));
162862306a36Sopenharmony_ci	bfa_msgq_cmd_set(&ioceth->msgq_cmd, NULL, NULL,
162962306a36Sopenharmony_ci		sizeof(struct bfi_enet_attr_req), &attr_req->mh);
163062306a36Sopenharmony_ci	bfa_msgq_cmd_post(&ioceth->bna->msgq, &ioceth->msgq_cmd);
163162306a36Sopenharmony_ci}
163262306a36Sopenharmony_ci
163362306a36Sopenharmony_ci/* IOC callback functions */
163462306a36Sopenharmony_ci
163562306a36Sopenharmony_cistatic void
163662306a36Sopenharmony_cibna_cb_ioceth_enable(void *arg, enum bfa_status error)
163762306a36Sopenharmony_ci{
163862306a36Sopenharmony_ci	struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
163962306a36Sopenharmony_ci
164062306a36Sopenharmony_ci	if (error)
164162306a36Sopenharmony_ci		bfa_fsm_send_event(ioceth, IOCETH_E_IOC_FAILED);
164262306a36Sopenharmony_ci	else
164362306a36Sopenharmony_ci		bfa_fsm_send_event(ioceth, IOCETH_E_IOC_READY);
164462306a36Sopenharmony_ci}
164562306a36Sopenharmony_ci
164662306a36Sopenharmony_cistatic void
164762306a36Sopenharmony_cibna_cb_ioceth_disable(void *arg)
164862306a36Sopenharmony_ci{
164962306a36Sopenharmony_ci	struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
165062306a36Sopenharmony_ci
165162306a36Sopenharmony_ci	bfa_fsm_send_event(ioceth, IOCETH_E_IOC_DISABLED);
165262306a36Sopenharmony_ci}
165362306a36Sopenharmony_ci
165462306a36Sopenharmony_cistatic void
165562306a36Sopenharmony_cibna_cb_ioceth_hbfail(void *arg)
165662306a36Sopenharmony_ci{
165762306a36Sopenharmony_ci	struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
165862306a36Sopenharmony_ci
165962306a36Sopenharmony_ci	bfa_fsm_send_event(ioceth, IOCETH_E_IOC_FAILED);
166062306a36Sopenharmony_ci}
166162306a36Sopenharmony_ci
166262306a36Sopenharmony_cistatic void
166362306a36Sopenharmony_cibna_cb_ioceth_reset(void *arg)
166462306a36Sopenharmony_ci{
166562306a36Sopenharmony_ci	struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
166662306a36Sopenharmony_ci
166762306a36Sopenharmony_ci	bfa_fsm_send_event(ioceth, IOCETH_E_IOC_RESET);
166862306a36Sopenharmony_ci}
166962306a36Sopenharmony_ci
167062306a36Sopenharmony_cistatic struct bfa_ioc_cbfn bna_ioceth_cbfn = {
167162306a36Sopenharmony_ci	.enable_cbfn = bna_cb_ioceth_enable,
167262306a36Sopenharmony_ci	.disable_cbfn = bna_cb_ioceth_disable,
167362306a36Sopenharmony_ci	.hbfail_cbfn = bna_cb_ioceth_hbfail,
167462306a36Sopenharmony_ci	.reset_cbfn = bna_cb_ioceth_reset
167562306a36Sopenharmony_ci};
167662306a36Sopenharmony_ci
167762306a36Sopenharmony_cistatic void bna_attr_init(struct bna_ioceth *ioceth)
167862306a36Sopenharmony_ci{
167962306a36Sopenharmony_ci	ioceth->attr.num_txq = BFI_ENET_DEF_TXQ;
168062306a36Sopenharmony_ci	ioceth->attr.num_rxp = BFI_ENET_DEF_RXP;
168162306a36Sopenharmony_ci	ioceth->attr.num_ucmac = BFI_ENET_DEF_UCAM;
168262306a36Sopenharmony_ci	ioceth->attr.num_mcmac = BFI_ENET_MAX_MCAM;
168362306a36Sopenharmony_ci	ioceth->attr.max_rit_size = BFI_ENET_DEF_RITSZ;
168462306a36Sopenharmony_ci	ioceth->attr.fw_query_complete = false;
168562306a36Sopenharmony_ci}
168662306a36Sopenharmony_ci
168762306a36Sopenharmony_cistatic void
168862306a36Sopenharmony_cibna_ioceth_init(struct bna_ioceth *ioceth, struct bna *bna,
168962306a36Sopenharmony_ci		struct bna_res_info *res_info)
169062306a36Sopenharmony_ci{
169162306a36Sopenharmony_ci	u64 dma;
169262306a36Sopenharmony_ci	u8 *kva;
169362306a36Sopenharmony_ci
169462306a36Sopenharmony_ci	ioceth->bna = bna;
169562306a36Sopenharmony_ci
169662306a36Sopenharmony_ci	/**
169762306a36Sopenharmony_ci	 * Attach IOC and claim:
169862306a36Sopenharmony_ci	 *	1. DMA memory for IOC attributes
169962306a36Sopenharmony_ci	 *	2. Kernel memory for FW trace
170062306a36Sopenharmony_ci	 */
170162306a36Sopenharmony_ci	bfa_nw_ioc_attach(&ioceth->ioc, ioceth, &bna_ioceth_cbfn);
170262306a36Sopenharmony_ci	bfa_nw_ioc_pci_init(&ioceth->ioc, &bna->pcidev, BFI_PCIFN_CLASS_ETH);
170362306a36Sopenharmony_ci
170462306a36Sopenharmony_ci	BNA_GET_DMA_ADDR(
170562306a36Sopenharmony_ci		&res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].dma, dma);
170662306a36Sopenharmony_ci	kva = res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].kva;
170762306a36Sopenharmony_ci	bfa_nw_ioc_mem_claim(&ioceth->ioc, kva, dma);
170862306a36Sopenharmony_ci
170962306a36Sopenharmony_ci	kva = res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mdl[0].kva;
171062306a36Sopenharmony_ci	bfa_nw_ioc_debug_memclaim(&ioceth->ioc, kva);
171162306a36Sopenharmony_ci
171262306a36Sopenharmony_ci	/**
171362306a36Sopenharmony_ci	 * Attach common modules (Diag, SFP, CEE, Port) and claim respective
171462306a36Sopenharmony_ci	 * DMA memory.
171562306a36Sopenharmony_ci	 */
171662306a36Sopenharmony_ci	BNA_GET_DMA_ADDR(
171762306a36Sopenharmony_ci		&res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].dma, dma);
171862306a36Sopenharmony_ci	kva = res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].kva;
171962306a36Sopenharmony_ci	bfa_nw_cee_attach(&bna->cee, &ioceth->ioc, bna);
172062306a36Sopenharmony_ci	bfa_nw_cee_mem_claim(&bna->cee, kva, dma);
172162306a36Sopenharmony_ci	kva += bfa_nw_cee_meminfo();
172262306a36Sopenharmony_ci	dma += bfa_nw_cee_meminfo();
172362306a36Sopenharmony_ci
172462306a36Sopenharmony_ci	bfa_nw_flash_attach(&bna->flash, &ioceth->ioc, bna);
172562306a36Sopenharmony_ci	bfa_nw_flash_memclaim(&bna->flash, kva, dma);
172662306a36Sopenharmony_ci	kva += bfa_nw_flash_meminfo();
172762306a36Sopenharmony_ci	dma += bfa_nw_flash_meminfo();
172862306a36Sopenharmony_ci
172962306a36Sopenharmony_ci	bfa_msgq_attach(&bna->msgq, &ioceth->ioc);
173062306a36Sopenharmony_ci	bfa_msgq_memclaim(&bna->msgq, kva, dma);
173162306a36Sopenharmony_ci	bfa_msgq_regisr(&bna->msgq, BFI_MC_ENET, bna_msgq_rsp_handler, bna);
173262306a36Sopenharmony_ci	kva += bfa_msgq_meminfo();
173362306a36Sopenharmony_ci	dma += bfa_msgq_meminfo();
173462306a36Sopenharmony_ci
173562306a36Sopenharmony_ci	ioceth->stop_cbfn = NULL;
173662306a36Sopenharmony_ci	ioceth->stop_cbarg = NULL;
173762306a36Sopenharmony_ci
173862306a36Sopenharmony_ci	bna_attr_init(ioceth);
173962306a36Sopenharmony_ci
174062306a36Sopenharmony_ci	bfa_fsm_set_state(ioceth, bna_ioceth_sm_stopped);
174162306a36Sopenharmony_ci}
174262306a36Sopenharmony_ci
174362306a36Sopenharmony_cistatic void
174462306a36Sopenharmony_cibna_ioceth_uninit(struct bna_ioceth *ioceth)
174562306a36Sopenharmony_ci{
174662306a36Sopenharmony_ci	bfa_nw_ioc_detach(&ioceth->ioc);
174762306a36Sopenharmony_ci
174862306a36Sopenharmony_ci	ioceth->bna = NULL;
174962306a36Sopenharmony_ci}
175062306a36Sopenharmony_ci
175162306a36Sopenharmony_civoid
175262306a36Sopenharmony_cibna_ioceth_enable(struct bna_ioceth *ioceth)
175362306a36Sopenharmony_ci{
175462306a36Sopenharmony_ci	if (ioceth->fsm == bna_ioceth_sm_ready) {
175562306a36Sopenharmony_ci		bnad_cb_ioceth_ready(ioceth->bna->bnad);
175662306a36Sopenharmony_ci		return;
175762306a36Sopenharmony_ci	}
175862306a36Sopenharmony_ci
175962306a36Sopenharmony_ci	if (ioceth->fsm == bna_ioceth_sm_stopped)
176062306a36Sopenharmony_ci		bfa_fsm_send_event(ioceth, IOCETH_E_ENABLE);
176162306a36Sopenharmony_ci}
176262306a36Sopenharmony_ci
176362306a36Sopenharmony_civoid
176462306a36Sopenharmony_cibna_ioceth_disable(struct bna_ioceth *ioceth, enum bna_cleanup_type type)
176562306a36Sopenharmony_ci{
176662306a36Sopenharmony_ci	if (type == BNA_SOFT_CLEANUP) {
176762306a36Sopenharmony_ci		bnad_cb_ioceth_disabled(ioceth->bna->bnad);
176862306a36Sopenharmony_ci		return;
176962306a36Sopenharmony_ci	}
177062306a36Sopenharmony_ci
177162306a36Sopenharmony_ci	ioceth->stop_cbfn = bnad_cb_ioceth_disabled;
177262306a36Sopenharmony_ci	ioceth->stop_cbarg = ioceth->bna->bnad;
177362306a36Sopenharmony_ci
177462306a36Sopenharmony_ci	bfa_fsm_send_event(ioceth, IOCETH_E_DISABLE);
177562306a36Sopenharmony_ci}
177662306a36Sopenharmony_ci
177762306a36Sopenharmony_cistatic void
177862306a36Sopenharmony_cibna_ucam_mod_init(struct bna_ucam_mod *ucam_mod, struct bna *bna,
177962306a36Sopenharmony_ci		  struct bna_res_info *res_info)
178062306a36Sopenharmony_ci{
178162306a36Sopenharmony_ci	int i;
178262306a36Sopenharmony_ci
178362306a36Sopenharmony_ci	ucam_mod->ucmac = (struct bna_mac *)
178462306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mdl[0].kva;
178562306a36Sopenharmony_ci
178662306a36Sopenharmony_ci	INIT_LIST_HEAD(&ucam_mod->free_q);
178762306a36Sopenharmony_ci	for (i = 0; i < bna->ioceth.attr.num_ucmac; i++)
178862306a36Sopenharmony_ci		list_add_tail(&ucam_mod->ucmac[i].qe, &ucam_mod->free_q);
178962306a36Sopenharmony_ci
179062306a36Sopenharmony_ci	/* A separate queue to allow synchronous setting of a list of MACs */
179162306a36Sopenharmony_ci	INIT_LIST_HEAD(&ucam_mod->del_q);
179262306a36Sopenharmony_ci	for (; i < (bna->ioceth.attr.num_ucmac * 2); i++)
179362306a36Sopenharmony_ci		list_add_tail(&ucam_mod->ucmac[i].qe, &ucam_mod->del_q);
179462306a36Sopenharmony_ci
179562306a36Sopenharmony_ci	ucam_mod->bna = bna;
179662306a36Sopenharmony_ci}
179762306a36Sopenharmony_ci
179862306a36Sopenharmony_cistatic void
179962306a36Sopenharmony_cibna_ucam_mod_uninit(struct bna_ucam_mod *ucam_mod)
180062306a36Sopenharmony_ci{
180162306a36Sopenharmony_ci	ucam_mod->bna = NULL;
180262306a36Sopenharmony_ci}
180362306a36Sopenharmony_ci
180462306a36Sopenharmony_cistatic void
180562306a36Sopenharmony_cibna_mcam_mod_init(struct bna_mcam_mod *mcam_mod, struct bna *bna,
180662306a36Sopenharmony_ci		  struct bna_res_info *res_info)
180762306a36Sopenharmony_ci{
180862306a36Sopenharmony_ci	int i;
180962306a36Sopenharmony_ci
181062306a36Sopenharmony_ci	mcam_mod->mcmac = (struct bna_mac *)
181162306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mdl[0].kva;
181262306a36Sopenharmony_ci
181362306a36Sopenharmony_ci	INIT_LIST_HEAD(&mcam_mod->free_q);
181462306a36Sopenharmony_ci	for (i = 0; i < bna->ioceth.attr.num_mcmac; i++)
181562306a36Sopenharmony_ci		list_add_tail(&mcam_mod->mcmac[i].qe, &mcam_mod->free_q);
181662306a36Sopenharmony_ci
181762306a36Sopenharmony_ci	mcam_mod->mchandle = (struct bna_mcam_handle *)
181862306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.mdl[0].kva;
181962306a36Sopenharmony_ci
182062306a36Sopenharmony_ci	INIT_LIST_HEAD(&mcam_mod->free_handle_q);
182162306a36Sopenharmony_ci	for (i = 0; i < bna->ioceth.attr.num_mcmac; i++)
182262306a36Sopenharmony_ci		list_add_tail(&mcam_mod->mchandle[i].qe,
182362306a36Sopenharmony_ci			      &mcam_mod->free_handle_q);
182462306a36Sopenharmony_ci
182562306a36Sopenharmony_ci	/* A separate queue to allow synchronous setting of a list of MACs */
182662306a36Sopenharmony_ci	INIT_LIST_HEAD(&mcam_mod->del_q);
182762306a36Sopenharmony_ci	for (; i < (bna->ioceth.attr.num_mcmac * 2); i++)
182862306a36Sopenharmony_ci		list_add_tail(&mcam_mod->mcmac[i].qe, &mcam_mod->del_q);
182962306a36Sopenharmony_ci
183062306a36Sopenharmony_ci	mcam_mod->bna = bna;
183162306a36Sopenharmony_ci}
183262306a36Sopenharmony_ci
183362306a36Sopenharmony_cistatic void
183462306a36Sopenharmony_cibna_mcam_mod_uninit(struct bna_mcam_mod *mcam_mod)
183562306a36Sopenharmony_ci{
183662306a36Sopenharmony_ci	mcam_mod->bna = NULL;
183762306a36Sopenharmony_ci}
183862306a36Sopenharmony_ci
183962306a36Sopenharmony_cistatic void
184062306a36Sopenharmony_cibna_bfi_stats_get(struct bna *bna)
184162306a36Sopenharmony_ci{
184262306a36Sopenharmony_ci	struct bfi_enet_stats_req *stats_req = &bna->stats_mod.stats_get;
184362306a36Sopenharmony_ci
184462306a36Sopenharmony_ci	bna->stats_mod.stats_get_busy = true;
184562306a36Sopenharmony_ci
184662306a36Sopenharmony_ci	bfi_msgq_mhdr_set(stats_req->mh, BFI_MC_ENET,
184762306a36Sopenharmony_ci		BFI_ENET_H2I_STATS_GET_REQ, 0, 0);
184862306a36Sopenharmony_ci	stats_req->mh.num_entries = htons(
184962306a36Sopenharmony_ci		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_stats_req)));
185062306a36Sopenharmony_ci	stats_req->stats_mask = htons(BFI_ENET_STATS_ALL);
185162306a36Sopenharmony_ci	stats_req->tx_enet_mask = htonl(bna->tx_mod.rid_mask);
185262306a36Sopenharmony_ci	stats_req->rx_enet_mask = htonl(bna->rx_mod.rid_mask);
185362306a36Sopenharmony_ci	stats_req->host_buffer.a32.addr_hi = bna->stats.hw_stats_dma.msb;
185462306a36Sopenharmony_ci	stats_req->host_buffer.a32.addr_lo = bna->stats.hw_stats_dma.lsb;
185562306a36Sopenharmony_ci
185662306a36Sopenharmony_ci	bfa_msgq_cmd_set(&bna->stats_mod.stats_get_cmd, NULL, NULL,
185762306a36Sopenharmony_ci		sizeof(struct bfi_enet_stats_req), &stats_req->mh);
185862306a36Sopenharmony_ci	bfa_msgq_cmd_post(&bna->msgq, &bna->stats_mod.stats_get_cmd);
185962306a36Sopenharmony_ci}
186062306a36Sopenharmony_ci
186162306a36Sopenharmony_civoid
186262306a36Sopenharmony_cibna_res_req(struct bna_res_info *res_info)
186362306a36Sopenharmony_ci{
186462306a36Sopenharmony_ci	/* DMA memory for COMMON_MODULE */
186562306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_COM].res_type = BNA_RES_T_MEM;
186662306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
186762306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_COM].res_u.mem_info.num = 1;
186862306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_COM].res_u.mem_info.len = ALIGN(
186962306a36Sopenharmony_ci				(bfa_nw_cee_meminfo() +
187062306a36Sopenharmony_ci				 bfa_nw_flash_meminfo() +
187162306a36Sopenharmony_ci				 bfa_msgq_meminfo()), PAGE_SIZE);
187262306a36Sopenharmony_ci
187362306a36Sopenharmony_ci	/* DMA memory for retrieving IOC attributes */
187462306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_ATTR].res_type = BNA_RES_T_MEM;
187562306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
187662306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.num = 1;
187762306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.len =
187862306a36Sopenharmony_ci				ALIGN(bfa_nw_ioc_meminfo(), PAGE_SIZE);
187962306a36Sopenharmony_ci
188062306a36Sopenharmony_ci	/* Virtual memory for retreiving fw_trc */
188162306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_FWTRC].res_type = BNA_RES_T_MEM;
188262306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mem_type = BNA_MEM_T_KVA;
188362306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.num = 1;
188462306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.len = BNA_DBG_FWTRC_LEN;
188562306a36Sopenharmony_ci
188662306a36Sopenharmony_ci	/* DMA memory for retreiving stats */
188762306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_STATS].res_type = BNA_RES_T_MEM;
188862306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
188962306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.num = 1;
189062306a36Sopenharmony_ci	res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.len =
189162306a36Sopenharmony_ci				ALIGN(sizeof(struct bfi_enet_stats),
189262306a36Sopenharmony_ci					PAGE_SIZE);
189362306a36Sopenharmony_ci}
189462306a36Sopenharmony_ci
189562306a36Sopenharmony_civoid
189662306a36Sopenharmony_cibna_mod_res_req(struct bna *bna, struct bna_res_info *res_info)
189762306a36Sopenharmony_ci{
189862306a36Sopenharmony_ci	struct bna_attr *attr = &bna->ioceth.attr;
189962306a36Sopenharmony_ci
190062306a36Sopenharmony_ci	/* Virtual memory for Tx objects - stored by Tx module */
190162306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_type = BNA_RES_T_MEM;
190262306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.mem_type =
190362306a36Sopenharmony_ci		BNA_MEM_T_KVA;
190462306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.num = 1;
190562306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.len =
190662306a36Sopenharmony_ci		attr->num_txq * sizeof(struct bna_tx);
190762306a36Sopenharmony_ci
190862306a36Sopenharmony_ci	/* Virtual memory for TxQ - stored by Tx module */
190962306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_type = BNA_RES_T_MEM;
191062306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mem_type =
191162306a36Sopenharmony_ci		BNA_MEM_T_KVA;
191262306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.num = 1;
191362306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.len =
191462306a36Sopenharmony_ci		attr->num_txq * sizeof(struct bna_txq);
191562306a36Sopenharmony_ci
191662306a36Sopenharmony_ci	/* Virtual memory for Rx objects - stored by Rx module */
191762306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_type = BNA_RES_T_MEM;
191862306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.mem_type =
191962306a36Sopenharmony_ci		BNA_MEM_T_KVA;
192062306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.num = 1;
192162306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.len =
192262306a36Sopenharmony_ci		attr->num_rxp * sizeof(struct bna_rx);
192362306a36Sopenharmony_ci
192462306a36Sopenharmony_ci	/* Virtual memory for RxPath - stored by Rx module */
192562306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_type = BNA_RES_T_MEM;
192662306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mem_type =
192762306a36Sopenharmony_ci		BNA_MEM_T_KVA;
192862306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.num = 1;
192962306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.len =
193062306a36Sopenharmony_ci		attr->num_rxp * sizeof(struct bna_rxp);
193162306a36Sopenharmony_ci
193262306a36Sopenharmony_ci	/* Virtual memory for RxQ - stored by Rx module */
193362306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_type = BNA_RES_T_MEM;
193462306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mem_type =
193562306a36Sopenharmony_ci		BNA_MEM_T_KVA;
193662306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.num = 1;
193762306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.len =
193862306a36Sopenharmony_ci		(attr->num_rxp * 2) * sizeof(struct bna_rxq);
193962306a36Sopenharmony_ci
194062306a36Sopenharmony_ci	/* Virtual memory for Unicast MAC address - stored by ucam module */
194162306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_type = BNA_RES_T_MEM;
194262306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mem_type =
194362306a36Sopenharmony_ci		BNA_MEM_T_KVA;
194462306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.num = 1;
194562306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.len =
194662306a36Sopenharmony_ci		(attr->num_ucmac * 2) * sizeof(struct bna_mac);
194762306a36Sopenharmony_ci
194862306a36Sopenharmony_ci	/* Virtual memory for Multicast MAC address - stored by mcam module */
194962306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_type = BNA_RES_T_MEM;
195062306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mem_type =
195162306a36Sopenharmony_ci		BNA_MEM_T_KVA;
195262306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.num = 1;
195362306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.len =
195462306a36Sopenharmony_ci		(attr->num_mcmac * 2) * sizeof(struct bna_mac);
195562306a36Sopenharmony_ci
195662306a36Sopenharmony_ci	/* Virtual memory for Multicast handle - stored by mcam module */
195762306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_type = BNA_RES_T_MEM;
195862306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.mem_type =
195962306a36Sopenharmony_ci		BNA_MEM_T_KVA;
196062306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.num = 1;
196162306a36Sopenharmony_ci	res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.len =
196262306a36Sopenharmony_ci		attr->num_mcmac * sizeof(struct bna_mcam_handle);
196362306a36Sopenharmony_ci}
196462306a36Sopenharmony_ci
196562306a36Sopenharmony_civoid
196662306a36Sopenharmony_cibna_init(struct bna *bna, struct bnad *bnad,
196762306a36Sopenharmony_ci		struct bfa_pcidev *pcidev, struct bna_res_info *res_info)
196862306a36Sopenharmony_ci{
196962306a36Sopenharmony_ci	bna->bnad = bnad;
197062306a36Sopenharmony_ci	bna->pcidev = *pcidev;
197162306a36Sopenharmony_ci
197262306a36Sopenharmony_ci	bna->stats.hw_stats_kva = (struct bfi_enet_stats *)
197362306a36Sopenharmony_ci		res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].kva;
197462306a36Sopenharmony_ci	bna->stats.hw_stats_dma.msb =
197562306a36Sopenharmony_ci		res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.msb;
197662306a36Sopenharmony_ci	bna->stats.hw_stats_dma.lsb =
197762306a36Sopenharmony_ci		res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.lsb;
197862306a36Sopenharmony_ci
197962306a36Sopenharmony_ci	bna_reg_addr_init(bna, &bna->pcidev);
198062306a36Sopenharmony_ci
198162306a36Sopenharmony_ci	/* Also initializes diag, cee, sfp, phy_port, msgq */
198262306a36Sopenharmony_ci	bna_ioceth_init(&bna->ioceth, bna, res_info);
198362306a36Sopenharmony_ci
198462306a36Sopenharmony_ci	bna_enet_init(&bna->enet, bna);
198562306a36Sopenharmony_ci	bna_ethport_init(&bna->ethport, bna);
198662306a36Sopenharmony_ci}
198762306a36Sopenharmony_ci
198862306a36Sopenharmony_civoid
198962306a36Sopenharmony_cibna_mod_init(struct bna *bna, struct bna_res_info *res_info)
199062306a36Sopenharmony_ci{
199162306a36Sopenharmony_ci	bna_tx_mod_init(&bna->tx_mod, bna, res_info);
199262306a36Sopenharmony_ci
199362306a36Sopenharmony_ci	bna_rx_mod_init(&bna->rx_mod, bna, res_info);
199462306a36Sopenharmony_ci
199562306a36Sopenharmony_ci	bna_ucam_mod_init(&bna->ucam_mod, bna, res_info);
199662306a36Sopenharmony_ci
199762306a36Sopenharmony_ci	bna_mcam_mod_init(&bna->mcam_mod, bna, res_info);
199862306a36Sopenharmony_ci
199962306a36Sopenharmony_ci	bna->default_mode_rid = BFI_INVALID_RID;
200062306a36Sopenharmony_ci	bna->promisc_rid = BFI_INVALID_RID;
200162306a36Sopenharmony_ci
200262306a36Sopenharmony_ci	bna->mod_flags |= BNA_MOD_F_INIT_DONE;
200362306a36Sopenharmony_ci}
200462306a36Sopenharmony_ci
200562306a36Sopenharmony_civoid
200662306a36Sopenharmony_cibna_uninit(struct bna *bna)
200762306a36Sopenharmony_ci{
200862306a36Sopenharmony_ci	if (bna->mod_flags & BNA_MOD_F_INIT_DONE) {
200962306a36Sopenharmony_ci		bna_mcam_mod_uninit(&bna->mcam_mod);
201062306a36Sopenharmony_ci		bna_ucam_mod_uninit(&bna->ucam_mod);
201162306a36Sopenharmony_ci		bna_rx_mod_uninit(&bna->rx_mod);
201262306a36Sopenharmony_ci		bna_tx_mod_uninit(&bna->tx_mod);
201362306a36Sopenharmony_ci		bna->mod_flags &= ~BNA_MOD_F_INIT_DONE;
201462306a36Sopenharmony_ci	}
201562306a36Sopenharmony_ci
201662306a36Sopenharmony_ci	bna_stats_mod_uninit(&bna->stats_mod);
201762306a36Sopenharmony_ci	bna_ethport_uninit(&bna->ethport);
201862306a36Sopenharmony_ci	bna_enet_uninit(&bna->enet);
201962306a36Sopenharmony_ci
202062306a36Sopenharmony_ci	bna_ioceth_uninit(&bna->ioceth);
202162306a36Sopenharmony_ci
202262306a36Sopenharmony_ci	bna->bnad = NULL;
202362306a36Sopenharmony_ci}
202462306a36Sopenharmony_ci
202562306a36Sopenharmony_ciint
202662306a36Sopenharmony_cibna_num_txq_set(struct bna *bna, int num_txq)
202762306a36Sopenharmony_ci{
202862306a36Sopenharmony_ci	if (bna->ioceth.attr.fw_query_complete &&
202962306a36Sopenharmony_ci		(num_txq <= bna->ioceth.attr.num_txq)) {
203062306a36Sopenharmony_ci		bna->ioceth.attr.num_txq = num_txq;
203162306a36Sopenharmony_ci		return BNA_CB_SUCCESS;
203262306a36Sopenharmony_ci	}
203362306a36Sopenharmony_ci
203462306a36Sopenharmony_ci	return BNA_CB_FAIL;
203562306a36Sopenharmony_ci}
203662306a36Sopenharmony_ci
203762306a36Sopenharmony_ciint
203862306a36Sopenharmony_cibna_num_rxp_set(struct bna *bna, int num_rxp)
203962306a36Sopenharmony_ci{
204062306a36Sopenharmony_ci	if (bna->ioceth.attr.fw_query_complete &&
204162306a36Sopenharmony_ci		(num_rxp <= bna->ioceth.attr.num_rxp)) {
204262306a36Sopenharmony_ci		bna->ioceth.attr.num_rxp = num_rxp;
204362306a36Sopenharmony_ci		return BNA_CB_SUCCESS;
204462306a36Sopenharmony_ci	}
204562306a36Sopenharmony_ci
204662306a36Sopenharmony_ci	return BNA_CB_FAIL;
204762306a36Sopenharmony_ci}
204862306a36Sopenharmony_ci
204962306a36Sopenharmony_cistruct bna_mac *
205062306a36Sopenharmony_cibna_cam_mod_mac_get(struct list_head *head)
205162306a36Sopenharmony_ci{
205262306a36Sopenharmony_ci	struct bna_mac *mac;
205362306a36Sopenharmony_ci
205462306a36Sopenharmony_ci	mac = list_first_entry_or_null(head, struct bna_mac, qe);
205562306a36Sopenharmony_ci	if (mac)
205662306a36Sopenharmony_ci		list_del(&mac->qe);
205762306a36Sopenharmony_ci
205862306a36Sopenharmony_ci	return mac;
205962306a36Sopenharmony_ci}
206062306a36Sopenharmony_ci
206162306a36Sopenharmony_cistruct bna_mcam_handle *
206262306a36Sopenharmony_cibna_mcam_mod_handle_get(struct bna_mcam_mod *mcam_mod)
206362306a36Sopenharmony_ci{
206462306a36Sopenharmony_ci	struct bna_mcam_handle *handle;
206562306a36Sopenharmony_ci
206662306a36Sopenharmony_ci	handle = list_first_entry_or_null(&mcam_mod->free_handle_q,
206762306a36Sopenharmony_ci					  struct bna_mcam_handle, qe);
206862306a36Sopenharmony_ci	if (handle)
206962306a36Sopenharmony_ci		list_del(&handle->qe);
207062306a36Sopenharmony_ci
207162306a36Sopenharmony_ci	return handle;
207262306a36Sopenharmony_ci}
207362306a36Sopenharmony_ci
207462306a36Sopenharmony_civoid
207562306a36Sopenharmony_cibna_mcam_mod_handle_put(struct bna_mcam_mod *mcam_mod,
207662306a36Sopenharmony_ci			struct bna_mcam_handle *handle)
207762306a36Sopenharmony_ci{
207862306a36Sopenharmony_ci	list_add_tail(&handle->qe, &mcam_mod->free_handle_q);
207962306a36Sopenharmony_ci}
208062306a36Sopenharmony_ci
208162306a36Sopenharmony_civoid
208262306a36Sopenharmony_cibna_hw_stats_get(struct bna *bna)
208362306a36Sopenharmony_ci{
208462306a36Sopenharmony_ci	if (!bna->stats_mod.ioc_ready) {
208562306a36Sopenharmony_ci		bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats);
208662306a36Sopenharmony_ci		return;
208762306a36Sopenharmony_ci	}
208862306a36Sopenharmony_ci	if (bna->stats_mod.stats_get_busy) {
208962306a36Sopenharmony_ci		bnad_cb_stats_get(bna->bnad, BNA_CB_BUSY, &bna->stats);
209062306a36Sopenharmony_ci		return;
209162306a36Sopenharmony_ci	}
209262306a36Sopenharmony_ci
209362306a36Sopenharmony_ci	bna_bfi_stats_get(bna);
209462306a36Sopenharmony_ci}
2095