152fa7bf9SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
245979c1eSRasesh Mody /*
32732ba56SRasesh Mody  * Linux network driver for QLogic BR-series Converged Network Adapter.
445979c1eSRasesh Mody  */
545979c1eSRasesh Mody /*
62732ba56SRasesh Mody  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
72732ba56SRasesh Mody  * Copyright (c) 2014-2015 QLogic Corporation
845979c1eSRasesh Mody  * All rights reserved
92732ba56SRasesh Mody  * www.qlogic.com
1045979c1eSRasesh Mody  */
1145979c1eSRasesh Mody #include "bna.h"
1245979c1eSRasesh Mody 
1345979c1eSRasesh Mody static inline int
ethport_can_be_up(struct bna_ethport * ethport)1445979c1eSRasesh Mody ethport_can_be_up(struct bna_ethport *ethport)
1545979c1eSRasesh Mody {
1645979c1eSRasesh Mody 	int ready = 0;
1745979c1eSRasesh Mody 	if (ethport->bna->enet.type == BNA_ENET_T_REGULAR)
1845979c1eSRasesh Mody 		ready = ((ethport->flags & BNA_ETHPORT_F_ADMIN_UP) &&
1945979c1eSRasesh Mody 			 (ethport->flags & BNA_ETHPORT_F_RX_STARTED) &&
2045979c1eSRasesh Mody 			 (ethport->flags & BNA_ETHPORT_F_PORT_ENABLED));
2145979c1eSRasesh Mody 	else
2245979c1eSRasesh Mody 		ready = ((ethport->flags & BNA_ETHPORT_F_ADMIN_UP) &&
2345979c1eSRasesh Mody 			 (ethport->flags & BNA_ETHPORT_F_RX_STARTED) &&
2445979c1eSRasesh Mody 			 !(ethport->flags & BNA_ETHPORT_F_PORT_ENABLED));
2545979c1eSRasesh Mody 	return ready;
2645979c1eSRasesh Mody }
2745979c1eSRasesh Mody 
2845979c1eSRasesh Mody #define ethport_is_up ethport_can_be_up
2945979c1eSRasesh Mody 
3045979c1eSRasesh Mody enum bna_ethport_event {
3145979c1eSRasesh Mody 	ETHPORT_E_START			= 1,
3245979c1eSRasesh Mody 	ETHPORT_E_STOP			= 2,
3345979c1eSRasesh Mody 	ETHPORT_E_FAIL			= 3,
3445979c1eSRasesh Mody 	ETHPORT_E_UP			= 4,
3545979c1eSRasesh Mody 	ETHPORT_E_DOWN			= 5,
3645979c1eSRasesh Mody 	ETHPORT_E_FWRESP_UP_OK		= 6,
3745979c1eSRasesh Mody 	ETHPORT_E_FWRESP_DOWN		= 7,
3845979c1eSRasesh Mody 	ETHPORT_E_FWRESP_UP_FAIL	= 8,
3945979c1eSRasesh Mody };
4045979c1eSRasesh Mody 
4145979c1eSRasesh Mody enum bna_enet_event {
4245979c1eSRasesh Mody 	ENET_E_START			= 1,
4345979c1eSRasesh Mody 	ENET_E_STOP			= 2,
4445979c1eSRasesh Mody 	ENET_E_FAIL			= 3,
4545979c1eSRasesh Mody 	ENET_E_PAUSE_CFG		= 4,
4645979c1eSRasesh Mody 	ENET_E_MTU_CFG			= 5,
4745979c1eSRasesh Mody 	ENET_E_FWRESP_PAUSE		= 6,
4845979c1eSRasesh Mody 	ENET_E_CHLD_STOPPED		= 7,
4945979c1eSRasesh Mody };
5045979c1eSRasesh Mody 
5145979c1eSRasesh Mody enum bna_ioceth_event {
5245979c1eSRasesh Mody 	IOCETH_E_ENABLE			= 1,
5345979c1eSRasesh Mody 	IOCETH_E_DISABLE		= 2,
5445979c1eSRasesh Mody 	IOCETH_E_IOC_RESET		= 3,
5545979c1eSRasesh Mody 	IOCETH_E_IOC_FAILED		= 4,
5645979c1eSRasesh Mody 	IOCETH_E_IOC_READY		= 5,
5745979c1eSRasesh Mody 	IOCETH_E_ENET_ATTR_RESP		= 6,
5845979c1eSRasesh Mody 	IOCETH_E_ENET_STOPPED		= 7,
5945979c1eSRasesh Mody 	IOCETH_E_IOC_DISABLED		= 8,
6045979c1eSRasesh Mody };
6145979c1eSRasesh Mody 
6245979c1eSRasesh Mody #define bna_stats_copy(_name, _type)					\
6345979c1eSRasesh Mody do {									\
6445979c1eSRasesh Mody 	count = sizeof(struct bfi_enet_stats_ ## _type) / sizeof(u64);	\
6545979c1eSRasesh Mody 	stats_src = (u64 *)&bna->stats.hw_stats_kva->_name ## _stats;	\
6645979c1eSRasesh Mody 	stats_dst = (u64 *)&bna->stats.hw_stats._name ## _stats;	\
6745979c1eSRasesh Mody 	for (i = 0; i < count; i++)					\
6845979c1eSRasesh Mody 		stats_dst[i] = be64_to_cpu(stats_src[i]);		\
6945979c1eSRasesh Mody } while (0)								\
7045979c1eSRasesh Mody 
7145979c1eSRasesh Mody /*
7245979c1eSRasesh Mody  * FW response handlers
7345979c1eSRasesh Mody  */
7445979c1eSRasesh Mody 
7545979c1eSRasesh Mody static void
bna_bfi_ethport_enable_aen(struct bna_ethport * ethport,struct bfi_msgq_mhdr * msghdr)7645979c1eSRasesh Mody bna_bfi_ethport_enable_aen(struct bna_ethport *ethport,
7745979c1eSRasesh Mody 				struct bfi_msgq_mhdr *msghdr)
7845979c1eSRasesh Mody {
7945979c1eSRasesh Mody 	ethport->flags |= BNA_ETHPORT_F_PORT_ENABLED;
8045979c1eSRasesh Mody 
8145979c1eSRasesh Mody 	if (ethport_can_be_up(ethport))
8245979c1eSRasesh Mody 		bfa_fsm_send_event(ethport, ETHPORT_E_UP);
8345979c1eSRasesh Mody }
8445979c1eSRasesh Mody 
8545979c1eSRasesh Mody static void
bna_bfi_ethport_disable_aen(struct bna_ethport * ethport,struct bfi_msgq_mhdr * msghdr)8645979c1eSRasesh Mody bna_bfi_ethport_disable_aen(struct bna_ethport *ethport,
8745979c1eSRasesh Mody 				struct bfi_msgq_mhdr *msghdr)
8845979c1eSRasesh Mody {
8945979c1eSRasesh Mody 	int ethport_up = ethport_is_up(ethport);
9045979c1eSRasesh Mody 
9145979c1eSRasesh Mody 	ethport->flags &= ~BNA_ETHPORT_F_PORT_ENABLED;
9245979c1eSRasesh Mody 
9345979c1eSRasesh Mody 	if (ethport_up)
9445979c1eSRasesh Mody 		bfa_fsm_send_event(ethport, ETHPORT_E_DOWN);
9545979c1eSRasesh Mody }
9645979c1eSRasesh Mody 
9745979c1eSRasesh Mody static void
bna_bfi_ethport_admin_rsp(struct bna_ethport * ethport,struct bfi_msgq_mhdr * msghdr)9845979c1eSRasesh Mody bna_bfi_ethport_admin_rsp(struct bna_ethport *ethport,
9945979c1eSRasesh Mody 				struct bfi_msgq_mhdr *msghdr)
10045979c1eSRasesh Mody {
10145979c1eSRasesh Mody 	struct bfi_enet_enable_req *admin_req =
10245979c1eSRasesh Mody 		&ethport->bfi_enet_cmd.admin_req;
10317b6f244SFabian Frederick 	struct bfi_enet_rsp *rsp =
10417b6f244SFabian Frederick 		container_of(msghdr, struct bfi_enet_rsp, mh);
10545979c1eSRasesh Mody 
10645979c1eSRasesh Mody 	switch (admin_req->enable) {
10745979c1eSRasesh Mody 	case BNA_STATUS_T_ENABLED:
10845979c1eSRasesh Mody 		if (rsp->error == BFI_ENET_CMD_OK)
10945979c1eSRasesh Mody 			bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_OK);
11045979c1eSRasesh Mody 		else {
11145979c1eSRasesh Mody 			ethport->flags &= ~BNA_ETHPORT_F_PORT_ENABLED;
11245979c1eSRasesh Mody 			bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_FAIL);
11345979c1eSRasesh Mody 		}
11445979c1eSRasesh Mody 		break;
11545979c1eSRasesh Mody 
11645979c1eSRasesh Mody 	case BNA_STATUS_T_DISABLED:
11745979c1eSRasesh Mody 		bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_DOWN);
11845979c1eSRasesh Mody 		ethport->link_status = BNA_LINK_DOWN;
11945979c1eSRasesh Mody 		ethport->link_cbfn(ethport->bna->bnad, BNA_LINK_DOWN);
12045979c1eSRasesh Mody 		break;
12145979c1eSRasesh Mody 	}
12245979c1eSRasesh Mody }
12345979c1eSRasesh Mody 
12445979c1eSRasesh Mody static void
bna_bfi_ethport_lpbk_rsp(struct bna_ethport * ethport,struct bfi_msgq_mhdr * msghdr)12545979c1eSRasesh Mody bna_bfi_ethport_lpbk_rsp(struct bna_ethport *ethport,
12645979c1eSRasesh Mody 				struct bfi_msgq_mhdr *msghdr)
12745979c1eSRasesh Mody {
12845979c1eSRasesh Mody 	struct bfi_enet_diag_lb_req *diag_lb_req =
12945979c1eSRasesh Mody 		&ethport->bfi_enet_cmd.lpbk_req;
13017b6f244SFabian Frederick 	struct bfi_enet_rsp *rsp =
13117b6f244SFabian Frederick 		container_of(msghdr, struct bfi_enet_rsp, mh);
13245979c1eSRasesh Mody 
13345979c1eSRasesh Mody 	switch (diag_lb_req->enable) {
13445979c1eSRasesh Mody 	case BNA_STATUS_T_ENABLED:
13545979c1eSRasesh Mody 		if (rsp->error == BFI_ENET_CMD_OK)
13645979c1eSRasesh Mody 			bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_OK);
13745979c1eSRasesh Mody 		else {
13845979c1eSRasesh Mody 			ethport->flags &= ~BNA_ETHPORT_F_ADMIN_UP;
13945979c1eSRasesh Mody 			bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_FAIL);
14045979c1eSRasesh Mody 		}
14145979c1eSRasesh Mody 		break;
14245979c1eSRasesh Mody 
14345979c1eSRasesh Mody 	case BNA_STATUS_T_DISABLED:
14445979c1eSRasesh Mody 		bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_DOWN);
14545979c1eSRasesh Mody 		break;
14645979c1eSRasesh Mody 	}
14745979c1eSRasesh Mody }
14845979c1eSRasesh Mody 
14945979c1eSRasesh Mody static void
bna_bfi_pause_set_rsp(struct bna_enet * enet,struct bfi_msgq_mhdr * msghdr)15045979c1eSRasesh Mody bna_bfi_pause_set_rsp(struct bna_enet *enet, struct bfi_msgq_mhdr *msghdr)
15145979c1eSRasesh Mody {
15245979c1eSRasesh Mody 	bfa_fsm_send_event(enet, ENET_E_FWRESP_PAUSE);
15345979c1eSRasesh Mody }
15445979c1eSRasesh Mody 
15545979c1eSRasesh Mody static void
bna_bfi_attr_get_rsp(struct bna_ioceth * ioceth,struct bfi_msgq_mhdr * msghdr)15645979c1eSRasesh Mody bna_bfi_attr_get_rsp(struct bna_ioceth *ioceth,
15745979c1eSRasesh Mody 			struct bfi_msgq_mhdr *msghdr)
15845979c1eSRasesh Mody {
15917b6f244SFabian Frederick 	struct bfi_enet_attr_rsp *rsp =
16017b6f244SFabian Frederick 		container_of(msghdr, struct bfi_enet_attr_rsp, mh);
16145979c1eSRasesh Mody 
16245979c1eSRasesh Mody 	/**
16345979c1eSRasesh Mody 	 * Store only if not set earlier, since BNAD can override the HW
16445979c1eSRasesh Mody 	 * attributes
16545979c1eSRasesh Mody 	 */
166761fab37SRasesh Mody 	if (!ioceth->attr.fw_query_complete) {
16745979c1eSRasesh Mody 		ioceth->attr.num_txq = ntohl(rsp->max_cfg);
16845979c1eSRasesh Mody 		ioceth->attr.num_rxp = ntohl(rsp->max_cfg);
16945979c1eSRasesh Mody 		ioceth->attr.num_ucmac = ntohl(rsp->max_ucmac);
17045979c1eSRasesh Mody 		ioceth->attr.num_mcmac = BFI_ENET_MAX_MCAM;
17145979c1eSRasesh Mody 		ioceth->attr.max_rit_size = ntohl(rsp->rit_size);
172761fab37SRasesh Mody 		ioceth->attr.fw_query_complete = true;
173761fab37SRasesh Mody 	}
17445979c1eSRasesh Mody 
17545979c1eSRasesh Mody 	bfa_fsm_send_event(ioceth, IOCETH_E_ENET_ATTR_RESP);
17645979c1eSRasesh Mody }
17745979c1eSRasesh Mody 
17845979c1eSRasesh Mody static void
bna_bfi_stats_get_rsp(struct bna * bna,struct bfi_msgq_mhdr * msghdr)17945979c1eSRasesh Mody bna_bfi_stats_get_rsp(struct bna *bna, struct bfi_msgq_mhdr *msghdr)
18045979c1eSRasesh Mody {
18145979c1eSRasesh Mody 	struct bfi_enet_stats_req *stats_req = &bna->stats_mod.stats_get;
18245979c1eSRasesh Mody 	u64 *stats_src;
18345979c1eSRasesh Mody 	u64 *stats_dst;
18445979c1eSRasesh Mody 	u32 tx_enet_mask = ntohl(stats_req->tx_enet_mask);
18545979c1eSRasesh Mody 	u32 rx_enet_mask = ntohl(stats_req->rx_enet_mask);
18645979c1eSRasesh Mody 	int count;
18745979c1eSRasesh Mody 	int i;
18845979c1eSRasesh Mody 
18945979c1eSRasesh Mody 	bna_stats_copy(mac, mac);
19045979c1eSRasesh Mody 	bna_stats_copy(bpc, bpc);
19145979c1eSRasesh Mody 	bna_stats_copy(rad, rad);
19245979c1eSRasesh Mody 	bna_stats_copy(rlb, rad);
19345979c1eSRasesh Mody 	bna_stats_copy(fc_rx, fc_rx);
19445979c1eSRasesh Mody 	bna_stats_copy(fc_tx, fc_tx);
19545979c1eSRasesh Mody 
19645979c1eSRasesh Mody 	stats_src = (u64 *)&(bna->stats.hw_stats_kva->rxf_stats[0]);
19745979c1eSRasesh Mody 
19845979c1eSRasesh Mody 	/* Copy Rxf stats to SW area, scatter them while copying */
19945979c1eSRasesh Mody 	for (i = 0; i < BFI_ENET_CFG_MAX; i++) {
20045979c1eSRasesh Mody 		stats_dst = (u64 *)&(bna->stats.hw_stats.rxf_stats[i]);
20145979c1eSRasesh Mody 		memset(stats_dst, 0, sizeof(struct bfi_enet_stats_rxf));
2028e8942b1SIvan Vecera 		if (rx_enet_mask & BIT(i)) {
20345979c1eSRasesh Mody 			int k;
20445979c1eSRasesh Mody 			count = sizeof(struct bfi_enet_stats_rxf) /
20545979c1eSRasesh Mody 				sizeof(u64);
20645979c1eSRasesh Mody 			for (k = 0; k < count; k++) {
20745979c1eSRasesh Mody 				stats_dst[k] = be64_to_cpu(*stats_src);
20845979c1eSRasesh Mody 				stats_src++;
20945979c1eSRasesh Mody 			}
21045979c1eSRasesh Mody 		}
21145979c1eSRasesh Mody 	}
21245979c1eSRasesh Mody 
21345979c1eSRasesh Mody 	/* Copy Txf stats to SW area, scatter them while copying */
21445979c1eSRasesh Mody 	for (i = 0; i < BFI_ENET_CFG_MAX; i++) {
21545979c1eSRasesh Mody 		stats_dst = (u64 *)&(bna->stats.hw_stats.txf_stats[i]);
21645979c1eSRasesh Mody 		memset(stats_dst, 0, sizeof(struct bfi_enet_stats_txf));
2178e8942b1SIvan Vecera 		if (tx_enet_mask & BIT(i)) {
21845979c1eSRasesh Mody 			int k;
21945979c1eSRasesh Mody 			count = sizeof(struct bfi_enet_stats_txf) /
22045979c1eSRasesh Mody 				sizeof(u64);
22145979c1eSRasesh Mody 			for (k = 0; k < count; k++) {
22245979c1eSRasesh Mody 				stats_dst[k] = be64_to_cpu(*stats_src);
22345979c1eSRasesh Mody 				stats_src++;
22445979c1eSRasesh Mody 			}
22545979c1eSRasesh Mody 		}
22645979c1eSRasesh Mody 	}
22745979c1eSRasesh Mody 
22845979c1eSRasesh Mody 	bna->stats_mod.stats_get_busy = false;
22945979c1eSRasesh Mody 	bnad_cb_stats_get(bna->bnad, BNA_CB_SUCCESS, &bna->stats);
23045979c1eSRasesh Mody }
23145979c1eSRasesh Mody 
23245979c1eSRasesh Mody static void
bna_bfi_ethport_linkup_aen(struct bna_ethport * ethport,struct bfi_msgq_mhdr * msghdr)23345979c1eSRasesh Mody bna_bfi_ethport_linkup_aen(struct bna_ethport *ethport,
23445979c1eSRasesh Mody 			struct bfi_msgq_mhdr *msghdr)
23545979c1eSRasesh Mody {
23645979c1eSRasesh Mody 	ethport->link_status = BNA_LINK_UP;
23745979c1eSRasesh Mody 
23845979c1eSRasesh Mody 	/* Dispatch events */
23945979c1eSRasesh Mody 	ethport->link_cbfn(ethport->bna->bnad, ethport->link_status);
24045979c1eSRasesh Mody }
24145979c1eSRasesh Mody 
24245979c1eSRasesh Mody static void
bna_bfi_ethport_linkdown_aen(struct bna_ethport * ethport,struct bfi_msgq_mhdr * msghdr)24345979c1eSRasesh Mody bna_bfi_ethport_linkdown_aen(struct bna_ethport *ethport,
24445979c1eSRasesh Mody 				struct bfi_msgq_mhdr *msghdr)
24545979c1eSRasesh Mody {
24645979c1eSRasesh Mody 	ethport->link_status = BNA_LINK_DOWN;
24745979c1eSRasesh Mody 
24845979c1eSRasesh Mody 	/* Dispatch events */
24945979c1eSRasesh Mody 	ethport->link_cbfn(ethport->bna->bnad, BNA_LINK_DOWN);
25045979c1eSRasesh Mody }
25145979c1eSRasesh Mody 
25245979c1eSRasesh Mody static void
bna_err_handler(struct bna * bna,u32 intr_status)25345979c1eSRasesh Mody bna_err_handler(struct bna *bna, u32 intr_status)
25445979c1eSRasesh Mody {
25545979c1eSRasesh Mody 	if (BNA_IS_HALT_INTR(bna, intr_status))
25645979c1eSRasesh Mody 		bna_halt_clear(bna);
25745979c1eSRasesh Mody 
25845979c1eSRasesh Mody 	bfa_nw_ioc_error_isr(&bna->ioceth.ioc);
25945979c1eSRasesh Mody }
26045979c1eSRasesh Mody 
26145979c1eSRasesh Mody void
bna_mbox_handler(struct bna * bna,u32 intr_status)26245979c1eSRasesh Mody bna_mbox_handler(struct bna *bna, u32 intr_status)
26345979c1eSRasesh Mody {
26445979c1eSRasesh Mody 	if (BNA_IS_ERR_INTR(bna, intr_status)) {
26545979c1eSRasesh Mody 		bna_err_handler(bna, intr_status);
26645979c1eSRasesh Mody 		return;
26745979c1eSRasesh Mody 	}
26845979c1eSRasesh Mody 	if (BNA_IS_MBOX_INTR(bna, intr_status))
26945979c1eSRasesh Mody 		bfa_nw_ioc_mbox_isr(&bna->ioceth.ioc);
27045979c1eSRasesh Mody }
27145979c1eSRasesh Mody 
27245979c1eSRasesh Mody static void
bna_msgq_rsp_handler(void * arg,struct bfi_msgq_mhdr * msghdr)27345979c1eSRasesh Mody bna_msgq_rsp_handler(void *arg, struct bfi_msgq_mhdr *msghdr)
27445979c1eSRasesh Mody {
27545979c1eSRasesh Mody 	struct bna *bna = (struct bna *)arg;
27645979c1eSRasesh Mody 	struct bna_tx *tx;
27745979c1eSRasesh Mody 	struct bna_rx *rx;
27845979c1eSRasesh Mody 
27945979c1eSRasesh Mody 	switch (msghdr->msg_id) {
28045979c1eSRasesh Mody 	case BFI_ENET_I2H_RX_CFG_SET_RSP:
28145979c1eSRasesh Mody 		bna_rx_from_rid(bna, msghdr->enet_id, rx);
28245979c1eSRasesh Mody 		if (rx)
28345979c1eSRasesh Mody 			bna_bfi_rx_enet_start_rsp(rx, msghdr);
28445979c1eSRasesh Mody 		break;
28545979c1eSRasesh Mody 
28645979c1eSRasesh Mody 	case BFI_ENET_I2H_RX_CFG_CLR_RSP:
28745979c1eSRasesh Mody 		bna_rx_from_rid(bna, msghdr->enet_id, rx);
28845979c1eSRasesh Mody 		if (rx)
28945979c1eSRasesh Mody 			bna_bfi_rx_enet_stop_rsp(rx, msghdr);
29045979c1eSRasesh Mody 		break;
29145979c1eSRasesh Mody 
29245979c1eSRasesh Mody 	case BFI_ENET_I2H_RIT_CFG_RSP:
29345979c1eSRasesh Mody 	case BFI_ENET_I2H_RSS_CFG_RSP:
29445979c1eSRasesh Mody 	case BFI_ENET_I2H_RSS_ENABLE_RSP:
29545979c1eSRasesh Mody 	case BFI_ENET_I2H_RX_PROMISCUOUS_RSP:
29645979c1eSRasesh Mody 	case BFI_ENET_I2H_RX_DEFAULT_RSP:
29745979c1eSRasesh Mody 	case BFI_ENET_I2H_MAC_UCAST_CLR_RSP:
29845979c1eSRasesh Mody 	case BFI_ENET_I2H_MAC_UCAST_ADD_RSP:
29945979c1eSRasesh Mody 	case BFI_ENET_I2H_MAC_UCAST_DEL_RSP:
30045979c1eSRasesh Mody 	case BFI_ENET_I2H_MAC_MCAST_DEL_RSP:
30145979c1eSRasesh Mody 	case BFI_ENET_I2H_MAC_MCAST_FILTER_RSP:
30245979c1eSRasesh Mody 	case BFI_ENET_I2H_RX_VLAN_SET_RSP:
30345979c1eSRasesh Mody 	case BFI_ENET_I2H_RX_VLAN_STRIP_ENABLE_RSP:
30445979c1eSRasesh Mody 		bna_rx_from_rid(bna, msghdr->enet_id, rx);
30545979c1eSRasesh Mody 		if (rx)
30645979c1eSRasesh Mody 			bna_bfi_rxf_cfg_rsp(&rx->rxf, msghdr);
30745979c1eSRasesh Mody 		break;
30845979c1eSRasesh Mody 
309f489a4baSRasesh Mody 	case BFI_ENET_I2H_MAC_UCAST_SET_RSP:
310f489a4baSRasesh Mody 		bna_rx_from_rid(bna, msghdr->enet_id, rx);
311f489a4baSRasesh Mody 		if (rx)
312f489a4baSRasesh Mody 			bna_bfi_rxf_ucast_set_rsp(&rx->rxf, msghdr);
313f489a4baSRasesh Mody 		break;
314f489a4baSRasesh Mody 
31545979c1eSRasesh Mody 	case BFI_ENET_I2H_MAC_MCAST_ADD_RSP:
31645979c1eSRasesh Mody 		bna_rx_from_rid(bna, msghdr->enet_id, rx);
31745979c1eSRasesh Mody 		if (rx)
31845979c1eSRasesh Mody 			bna_bfi_rxf_mcast_add_rsp(&rx->rxf, msghdr);
31945979c1eSRasesh Mody 		break;
32045979c1eSRasesh Mody 
32145979c1eSRasesh Mody 	case BFI_ENET_I2H_TX_CFG_SET_RSP:
32245979c1eSRasesh Mody 		bna_tx_from_rid(bna, msghdr->enet_id, tx);
32345979c1eSRasesh Mody 		if (tx)
32445979c1eSRasesh Mody 			bna_bfi_tx_enet_start_rsp(tx, msghdr);
32545979c1eSRasesh Mody 		break;
32645979c1eSRasesh Mody 
32745979c1eSRasesh Mody 	case BFI_ENET_I2H_TX_CFG_CLR_RSP:
32845979c1eSRasesh Mody 		bna_tx_from_rid(bna, msghdr->enet_id, tx);
32945979c1eSRasesh Mody 		if (tx)
33045979c1eSRasesh Mody 			bna_bfi_tx_enet_stop_rsp(tx, msghdr);
33145979c1eSRasesh Mody 		break;
33245979c1eSRasesh Mody 
33345979c1eSRasesh Mody 	case BFI_ENET_I2H_PORT_ADMIN_RSP:
33445979c1eSRasesh Mody 		bna_bfi_ethport_admin_rsp(&bna->ethport, msghdr);
33545979c1eSRasesh Mody 		break;
33645979c1eSRasesh Mody 
33745979c1eSRasesh Mody 	case BFI_ENET_I2H_DIAG_LOOPBACK_RSP:
33845979c1eSRasesh Mody 		bna_bfi_ethport_lpbk_rsp(&bna->ethport, msghdr);
33945979c1eSRasesh Mody 		break;
34045979c1eSRasesh Mody 
34145979c1eSRasesh Mody 	case BFI_ENET_I2H_SET_PAUSE_RSP:
34245979c1eSRasesh Mody 		bna_bfi_pause_set_rsp(&bna->enet, msghdr);
34345979c1eSRasesh Mody 		break;
34445979c1eSRasesh Mody 
34545979c1eSRasesh Mody 	case BFI_ENET_I2H_GET_ATTR_RSP:
34645979c1eSRasesh Mody 		bna_bfi_attr_get_rsp(&bna->ioceth, msghdr);
34745979c1eSRasesh Mody 		break;
34845979c1eSRasesh Mody 
34945979c1eSRasesh Mody 	case BFI_ENET_I2H_STATS_GET_RSP:
35045979c1eSRasesh Mody 		bna_bfi_stats_get_rsp(bna, msghdr);
35145979c1eSRasesh Mody 		break;
35245979c1eSRasesh Mody 
35345979c1eSRasesh Mody 	case BFI_ENET_I2H_STATS_CLR_RSP:
35445979c1eSRasesh Mody 		/* No-op */
35545979c1eSRasesh Mody 		break;
35645979c1eSRasesh Mody 
35745979c1eSRasesh Mody 	case BFI_ENET_I2H_LINK_UP_AEN:
35845979c1eSRasesh Mody 		bna_bfi_ethport_linkup_aen(&bna->ethport, msghdr);
35945979c1eSRasesh Mody 		break;
36045979c1eSRasesh Mody 
36145979c1eSRasesh Mody 	case BFI_ENET_I2H_LINK_DOWN_AEN:
36245979c1eSRasesh Mody 		bna_bfi_ethport_linkdown_aen(&bna->ethport, msghdr);
36345979c1eSRasesh Mody 		break;
36445979c1eSRasesh Mody 
36545979c1eSRasesh Mody 	case BFI_ENET_I2H_PORT_ENABLE_AEN:
36645979c1eSRasesh Mody 		bna_bfi_ethport_enable_aen(&bna->ethport, msghdr);
36745979c1eSRasesh Mody 		break;
36845979c1eSRasesh Mody 
36945979c1eSRasesh Mody 	case BFI_ENET_I2H_PORT_DISABLE_AEN:
37045979c1eSRasesh Mody 		bna_bfi_ethport_disable_aen(&bna->ethport, msghdr);
37145979c1eSRasesh Mody 		break;
37245979c1eSRasesh Mody 
37345979c1eSRasesh Mody 	case BFI_ENET_I2H_BW_UPDATE_AEN:
37445979c1eSRasesh Mody 		bna_bfi_bw_update_aen(&bna->tx_mod);
37545979c1eSRasesh Mody 		break;
37645979c1eSRasesh Mody 
37745979c1eSRasesh Mody 	default:
37845979c1eSRasesh Mody 		break;
37945979c1eSRasesh Mody 	}
38045979c1eSRasesh Mody }
38145979c1eSRasesh Mody 
3821aa8b471SBen Hutchings /* ETHPORT */
3831aa8b471SBen Hutchings 
38445979c1eSRasesh Mody #define call_ethport_stop_cbfn(_ethport)				\
38545979c1eSRasesh Mody do {									\
38645979c1eSRasesh Mody 	if ((_ethport)->stop_cbfn) {					\
38745979c1eSRasesh Mody 		void (*cbfn)(struct bna_enet *);			\
38845979c1eSRasesh Mody 		cbfn = (_ethport)->stop_cbfn;				\
38945979c1eSRasesh Mody 		(_ethport)->stop_cbfn = NULL;				\
39045979c1eSRasesh Mody 		cbfn(&(_ethport)->bna->enet);				\
39145979c1eSRasesh Mody 	}								\
39245979c1eSRasesh Mody } while (0)
39345979c1eSRasesh Mody 
39445979c1eSRasesh Mody #define call_ethport_adminup_cbfn(ethport, status)			\
39545979c1eSRasesh Mody do {									\
39645979c1eSRasesh Mody 	if ((ethport)->adminup_cbfn) {					\
39745979c1eSRasesh Mody 		void (*cbfn)(struct bnad *, enum bna_cb_status);	\
39845979c1eSRasesh Mody 		cbfn = (ethport)->adminup_cbfn;				\
39945979c1eSRasesh Mody 		(ethport)->adminup_cbfn = NULL;				\
40045979c1eSRasesh Mody 		cbfn((ethport)->bna->bnad, status);			\
40145979c1eSRasesh Mody 	}								\
40245979c1eSRasesh Mody } while (0)
40345979c1eSRasesh Mody 
40445979c1eSRasesh Mody static void
bna_bfi_ethport_admin_up(struct bna_ethport * ethport)40545979c1eSRasesh Mody bna_bfi_ethport_admin_up(struct bna_ethport *ethport)
40645979c1eSRasesh Mody {
40745979c1eSRasesh Mody 	struct bfi_enet_enable_req *admin_up_req =
40845979c1eSRasesh Mody 		&ethport->bfi_enet_cmd.admin_req;
40945979c1eSRasesh Mody 
41045979c1eSRasesh Mody 	bfi_msgq_mhdr_set(admin_up_req->mh, BFI_MC_ENET,
41145979c1eSRasesh Mody 		BFI_ENET_H2I_PORT_ADMIN_UP_REQ, 0, 0);
41245979c1eSRasesh Mody 	admin_up_req->mh.num_entries = htons(
41345979c1eSRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
41445979c1eSRasesh Mody 	admin_up_req->enable = BNA_STATUS_T_ENABLED;
41545979c1eSRasesh Mody 
41645979c1eSRasesh Mody 	bfa_msgq_cmd_set(&ethport->msgq_cmd, NULL, NULL,
41745979c1eSRasesh Mody 		sizeof(struct bfi_enet_enable_req), &admin_up_req->mh);
41845979c1eSRasesh Mody 	bfa_msgq_cmd_post(&ethport->bna->msgq, &ethport->msgq_cmd);
41945979c1eSRasesh Mody }
42045979c1eSRasesh Mody 
42145979c1eSRasesh Mody static void
bna_bfi_ethport_admin_down(struct bna_ethport * ethport)42245979c1eSRasesh Mody bna_bfi_ethport_admin_down(struct bna_ethport *ethport)
42345979c1eSRasesh Mody {
42445979c1eSRasesh Mody 	struct bfi_enet_enable_req *admin_down_req =
42545979c1eSRasesh Mody 		&ethport->bfi_enet_cmd.admin_req;
42645979c1eSRasesh Mody 
42745979c1eSRasesh Mody 	bfi_msgq_mhdr_set(admin_down_req->mh, BFI_MC_ENET,
42845979c1eSRasesh Mody 		BFI_ENET_H2I_PORT_ADMIN_UP_REQ, 0, 0);
42945979c1eSRasesh Mody 	admin_down_req->mh.num_entries = htons(
43045979c1eSRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
43145979c1eSRasesh Mody 	admin_down_req->enable = BNA_STATUS_T_DISABLED;
43245979c1eSRasesh Mody 
43345979c1eSRasesh Mody 	bfa_msgq_cmd_set(&ethport->msgq_cmd, NULL, NULL,
43445979c1eSRasesh Mody 		sizeof(struct bfi_enet_enable_req), &admin_down_req->mh);
43545979c1eSRasesh Mody 	bfa_msgq_cmd_post(&ethport->bna->msgq, &ethport->msgq_cmd);
43645979c1eSRasesh Mody }
43745979c1eSRasesh Mody 
43845979c1eSRasesh Mody static void
bna_bfi_ethport_lpbk_up(struct bna_ethport * ethport)43945979c1eSRasesh Mody bna_bfi_ethport_lpbk_up(struct bna_ethport *ethport)
44045979c1eSRasesh Mody {
44145979c1eSRasesh Mody 	struct bfi_enet_diag_lb_req *lpbk_up_req =
44245979c1eSRasesh Mody 		&ethport->bfi_enet_cmd.lpbk_req;
44345979c1eSRasesh Mody 
44445979c1eSRasesh Mody 	bfi_msgq_mhdr_set(lpbk_up_req->mh, BFI_MC_ENET,
44545979c1eSRasesh Mody 		BFI_ENET_H2I_DIAG_LOOPBACK_REQ, 0, 0);
44645979c1eSRasesh Mody 	lpbk_up_req->mh.num_entries = htons(
44745979c1eSRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_diag_lb_req)));
44845979c1eSRasesh Mody 	lpbk_up_req->mode = (ethport->bna->enet.type ==
44945979c1eSRasesh Mody 				BNA_ENET_T_LOOPBACK_INTERNAL) ?
45045979c1eSRasesh Mody 				BFI_ENET_DIAG_LB_OPMODE_EXT :
45145979c1eSRasesh Mody 				BFI_ENET_DIAG_LB_OPMODE_CBL;
45245979c1eSRasesh Mody 	lpbk_up_req->enable = BNA_STATUS_T_ENABLED;
45345979c1eSRasesh Mody 
45445979c1eSRasesh Mody 	bfa_msgq_cmd_set(&ethport->msgq_cmd, NULL, NULL,
45545979c1eSRasesh Mody 		sizeof(struct bfi_enet_diag_lb_req), &lpbk_up_req->mh);
45645979c1eSRasesh Mody 	bfa_msgq_cmd_post(&ethport->bna->msgq, &ethport->msgq_cmd);
45745979c1eSRasesh Mody }
45845979c1eSRasesh Mody 
45945979c1eSRasesh Mody static void
bna_bfi_ethport_lpbk_down(struct bna_ethport * ethport)46045979c1eSRasesh Mody bna_bfi_ethport_lpbk_down(struct bna_ethport *ethport)
46145979c1eSRasesh Mody {
46245979c1eSRasesh Mody 	struct bfi_enet_diag_lb_req *lpbk_down_req =
46345979c1eSRasesh Mody 		&ethport->bfi_enet_cmd.lpbk_req;
46445979c1eSRasesh Mody 
46545979c1eSRasesh Mody 	bfi_msgq_mhdr_set(lpbk_down_req->mh, BFI_MC_ENET,
46645979c1eSRasesh Mody 		BFI_ENET_H2I_DIAG_LOOPBACK_REQ, 0, 0);
46745979c1eSRasesh Mody 	lpbk_down_req->mh.num_entries = htons(
46845979c1eSRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_diag_lb_req)));
46945979c1eSRasesh Mody 	lpbk_down_req->enable = BNA_STATUS_T_DISABLED;
47045979c1eSRasesh Mody 
47145979c1eSRasesh Mody 	bfa_msgq_cmd_set(&ethport->msgq_cmd, NULL, NULL,
47245979c1eSRasesh Mody 		sizeof(struct bfi_enet_diag_lb_req), &lpbk_down_req->mh);
47345979c1eSRasesh Mody 	bfa_msgq_cmd_post(&ethport->bna->msgq, &ethport->msgq_cmd);
47445979c1eSRasesh Mody }
47545979c1eSRasesh Mody 
47645979c1eSRasesh Mody static void
bna_bfi_ethport_up(struct bna_ethport * ethport)47745979c1eSRasesh Mody bna_bfi_ethport_up(struct bna_ethport *ethport)
47845979c1eSRasesh Mody {
47945979c1eSRasesh Mody 	if (ethport->bna->enet.type == BNA_ENET_T_REGULAR)
48045979c1eSRasesh Mody 		bna_bfi_ethport_admin_up(ethport);
48145979c1eSRasesh Mody 	else
48245979c1eSRasesh Mody 		bna_bfi_ethport_lpbk_up(ethport);
48345979c1eSRasesh Mody }
48445979c1eSRasesh Mody 
48545979c1eSRasesh Mody static void
bna_bfi_ethport_down(struct bna_ethport * ethport)48645979c1eSRasesh Mody bna_bfi_ethport_down(struct bna_ethport *ethport)
48745979c1eSRasesh Mody {
48845979c1eSRasesh Mody 	if (ethport->bna->enet.type == BNA_ENET_T_REGULAR)
48945979c1eSRasesh Mody 		bna_bfi_ethport_admin_down(ethport);
49045979c1eSRasesh Mody 	else
49145979c1eSRasesh Mody 		bna_bfi_ethport_lpbk_down(ethport);
49245979c1eSRasesh Mody }
49345979c1eSRasesh Mody 
49445979c1eSRasesh Mody bfa_fsm_state_decl(bna_ethport, stopped, struct bna_ethport,
49545979c1eSRasesh Mody 			enum bna_ethport_event);
49645979c1eSRasesh Mody bfa_fsm_state_decl(bna_ethport, down, struct bna_ethport,
49745979c1eSRasesh Mody 			enum bna_ethport_event);
49845979c1eSRasesh Mody bfa_fsm_state_decl(bna_ethport, up_resp_wait, struct bna_ethport,
49945979c1eSRasesh Mody 			enum bna_ethport_event);
50045979c1eSRasesh Mody bfa_fsm_state_decl(bna_ethport, down_resp_wait, struct bna_ethport,
50145979c1eSRasesh Mody 			enum bna_ethport_event);
50245979c1eSRasesh Mody bfa_fsm_state_decl(bna_ethport, up, struct bna_ethport,
50345979c1eSRasesh Mody 			enum bna_ethport_event);
50445979c1eSRasesh Mody bfa_fsm_state_decl(bna_ethport, last_resp_wait, struct bna_ethport,
50545979c1eSRasesh Mody 			enum bna_ethport_event);
50645979c1eSRasesh Mody 
50745979c1eSRasesh Mody static void
bna_ethport_sm_stopped_entry(struct bna_ethport * ethport)50845979c1eSRasesh Mody bna_ethport_sm_stopped_entry(struct bna_ethport *ethport)
50945979c1eSRasesh Mody {
51045979c1eSRasesh Mody 	call_ethport_stop_cbfn(ethport);
51145979c1eSRasesh Mody }
51245979c1eSRasesh Mody 
51345979c1eSRasesh Mody static void
bna_ethport_sm_stopped(struct bna_ethport * ethport,enum bna_ethport_event event)51445979c1eSRasesh Mody bna_ethport_sm_stopped(struct bna_ethport *ethport,
51545979c1eSRasesh Mody 			enum bna_ethport_event event)
51645979c1eSRasesh Mody {
51745979c1eSRasesh Mody 	switch (event) {
51845979c1eSRasesh Mody 	case ETHPORT_E_START:
51945979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_down);
52045979c1eSRasesh Mody 		break;
52145979c1eSRasesh Mody 
52245979c1eSRasesh Mody 	case ETHPORT_E_STOP:
52345979c1eSRasesh Mody 		call_ethport_stop_cbfn(ethport);
52445979c1eSRasesh Mody 		break;
52545979c1eSRasesh Mody 
52645979c1eSRasesh Mody 	case ETHPORT_E_FAIL:
52745979c1eSRasesh Mody 		/* No-op */
52845979c1eSRasesh Mody 		break;
52945979c1eSRasesh Mody 
53045979c1eSRasesh Mody 	case ETHPORT_E_DOWN:
53145979c1eSRasesh Mody 		/* This event is received due to Rx objects failing */
53245979c1eSRasesh Mody 		/* No-op */
53345979c1eSRasesh Mody 		break;
53445979c1eSRasesh Mody 
53545979c1eSRasesh Mody 	default:
53645979c1eSRasesh Mody 		bfa_sm_fault(event);
53745979c1eSRasesh Mody 	}
53845979c1eSRasesh Mody }
53945979c1eSRasesh Mody 
54045979c1eSRasesh Mody static void
bna_ethport_sm_down_entry(struct bna_ethport * ethport)54145979c1eSRasesh Mody bna_ethport_sm_down_entry(struct bna_ethport *ethport)
54245979c1eSRasesh Mody {
54345979c1eSRasesh Mody }
54445979c1eSRasesh Mody 
54545979c1eSRasesh Mody static void
bna_ethport_sm_down(struct bna_ethport * ethport,enum bna_ethport_event event)54645979c1eSRasesh Mody bna_ethport_sm_down(struct bna_ethport *ethport,
54745979c1eSRasesh Mody 			enum bna_ethport_event event)
54845979c1eSRasesh Mody {
54945979c1eSRasesh Mody 	switch (event) {
55045979c1eSRasesh Mody 	case ETHPORT_E_STOP:
55145979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
55245979c1eSRasesh Mody 		break;
55345979c1eSRasesh Mody 
55445979c1eSRasesh Mody 	case ETHPORT_E_FAIL:
55545979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
55645979c1eSRasesh Mody 		break;
55745979c1eSRasesh Mody 
55845979c1eSRasesh Mody 	case ETHPORT_E_UP:
55945979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_up_resp_wait);
56045979c1eSRasesh Mody 		bna_bfi_ethport_up(ethport);
56145979c1eSRasesh Mody 		break;
56245979c1eSRasesh Mody 
56345979c1eSRasesh Mody 	default:
56445979c1eSRasesh Mody 		bfa_sm_fault(event);
56545979c1eSRasesh Mody 	}
56645979c1eSRasesh Mody }
56745979c1eSRasesh Mody 
56845979c1eSRasesh Mody static void
bna_ethport_sm_up_resp_wait_entry(struct bna_ethport * ethport)56945979c1eSRasesh Mody bna_ethport_sm_up_resp_wait_entry(struct bna_ethport *ethport)
57045979c1eSRasesh Mody {
57145979c1eSRasesh Mody }
57245979c1eSRasesh Mody 
57345979c1eSRasesh Mody static void
bna_ethport_sm_up_resp_wait(struct bna_ethport * ethport,enum bna_ethport_event event)57445979c1eSRasesh Mody bna_ethport_sm_up_resp_wait(struct bna_ethport *ethport,
57545979c1eSRasesh Mody 			enum bna_ethport_event event)
57645979c1eSRasesh Mody {
57745979c1eSRasesh Mody 	switch (event) {
57845979c1eSRasesh Mody 	case ETHPORT_E_STOP:
57945979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_last_resp_wait);
58045979c1eSRasesh Mody 		break;
58145979c1eSRasesh Mody 
58245979c1eSRasesh Mody 	case ETHPORT_E_FAIL:
58345979c1eSRasesh Mody 		call_ethport_adminup_cbfn(ethport, BNA_CB_FAIL);
58445979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
58545979c1eSRasesh Mody 		break;
58645979c1eSRasesh Mody 
58745979c1eSRasesh Mody 	case ETHPORT_E_DOWN:
58845979c1eSRasesh Mody 		call_ethport_adminup_cbfn(ethport, BNA_CB_INTERRUPT);
58945979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_down_resp_wait);
59045979c1eSRasesh Mody 		break;
59145979c1eSRasesh Mody 
59245979c1eSRasesh Mody 	case ETHPORT_E_FWRESP_UP_OK:
59345979c1eSRasesh Mody 		call_ethport_adminup_cbfn(ethport, BNA_CB_SUCCESS);
59445979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_up);
59545979c1eSRasesh Mody 		break;
59645979c1eSRasesh Mody 
59745979c1eSRasesh Mody 	case ETHPORT_E_FWRESP_UP_FAIL:
59845979c1eSRasesh Mody 		call_ethport_adminup_cbfn(ethport, BNA_CB_FAIL);
59945979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_down);
60045979c1eSRasesh Mody 		break;
60145979c1eSRasesh Mody 
60245979c1eSRasesh Mody 	case ETHPORT_E_FWRESP_DOWN:
60345979c1eSRasesh Mody 		/* down_resp_wait -> up_resp_wait transition on ETHPORT_E_UP */
60445979c1eSRasesh Mody 		bna_bfi_ethport_up(ethport);
60545979c1eSRasesh Mody 		break;
60645979c1eSRasesh Mody 
60745979c1eSRasesh Mody 	default:
60845979c1eSRasesh Mody 		bfa_sm_fault(event);
60945979c1eSRasesh Mody 	}
61045979c1eSRasesh Mody }
61145979c1eSRasesh Mody 
61245979c1eSRasesh Mody static void
bna_ethport_sm_down_resp_wait_entry(struct bna_ethport * ethport)61345979c1eSRasesh Mody bna_ethport_sm_down_resp_wait_entry(struct bna_ethport *ethport)
61445979c1eSRasesh Mody {
61545979c1eSRasesh Mody 	/**
61645979c1eSRasesh Mody 	 * NOTE: Do not call bna_bfi_ethport_down() here. That will over step
61745979c1eSRasesh Mody 	 * mbox due to up_resp_wait -> down_resp_wait transition on event
61845979c1eSRasesh Mody 	 * ETHPORT_E_DOWN
61945979c1eSRasesh Mody 	 */
62045979c1eSRasesh Mody }
62145979c1eSRasesh Mody 
62245979c1eSRasesh Mody static void
bna_ethport_sm_down_resp_wait(struct bna_ethport * ethport,enum bna_ethport_event event)62345979c1eSRasesh Mody bna_ethport_sm_down_resp_wait(struct bna_ethport *ethport,
62445979c1eSRasesh Mody 			enum bna_ethport_event event)
62545979c1eSRasesh Mody {
62645979c1eSRasesh Mody 	switch (event) {
62745979c1eSRasesh Mody 	case ETHPORT_E_STOP:
62845979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_last_resp_wait);
62945979c1eSRasesh Mody 		break;
63045979c1eSRasesh Mody 
63145979c1eSRasesh Mody 	case ETHPORT_E_FAIL:
63245979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
63345979c1eSRasesh Mody 		break;
63445979c1eSRasesh Mody 
63545979c1eSRasesh Mody 	case ETHPORT_E_UP:
63645979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_up_resp_wait);
63745979c1eSRasesh Mody 		break;
63845979c1eSRasesh Mody 
63945979c1eSRasesh Mody 	case ETHPORT_E_FWRESP_UP_OK:
64045979c1eSRasesh Mody 		/* up_resp_wait->down_resp_wait transition on ETHPORT_E_DOWN */
64145979c1eSRasesh Mody 		bna_bfi_ethport_down(ethport);
64245979c1eSRasesh Mody 		break;
64345979c1eSRasesh Mody 
64445979c1eSRasesh Mody 	case ETHPORT_E_FWRESP_UP_FAIL:
64545979c1eSRasesh Mody 	case ETHPORT_E_FWRESP_DOWN:
64645979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_down);
64745979c1eSRasesh Mody 		break;
64845979c1eSRasesh Mody 
64945979c1eSRasesh Mody 	default:
65045979c1eSRasesh Mody 		bfa_sm_fault(event);
65145979c1eSRasesh Mody 	}
65245979c1eSRasesh Mody }
65345979c1eSRasesh Mody 
65445979c1eSRasesh Mody static void
bna_ethport_sm_up_entry(struct bna_ethport * ethport)65545979c1eSRasesh Mody bna_ethport_sm_up_entry(struct bna_ethport *ethport)
65645979c1eSRasesh Mody {
65745979c1eSRasesh Mody }
65845979c1eSRasesh Mody 
65945979c1eSRasesh Mody static void
bna_ethport_sm_up(struct bna_ethport * ethport,enum bna_ethport_event event)66045979c1eSRasesh Mody bna_ethport_sm_up(struct bna_ethport *ethport,
66145979c1eSRasesh Mody 			enum bna_ethport_event event)
66245979c1eSRasesh Mody {
66345979c1eSRasesh Mody 	switch (event) {
66445979c1eSRasesh Mody 	case ETHPORT_E_STOP:
66545979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_last_resp_wait);
66645979c1eSRasesh Mody 		bna_bfi_ethport_down(ethport);
66745979c1eSRasesh Mody 		break;
66845979c1eSRasesh Mody 
66945979c1eSRasesh Mody 	case ETHPORT_E_FAIL:
67045979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
67145979c1eSRasesh Mody 		break;
67245979c1eSRasesh Mody 
67345979c1eSRasesh Mody 	case ETHPORT_E_DOWN:
67445979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_down_resp_wait);
67545979c1eSRasesh Mody 		bna_bfi_ethport_down(ethport);
67645979c1eSRasesh Mody 		break;
67745979c1eSRasesh Mody 
67845979c1eSRasesh Mody 	default:
67945979c1eSRasesh Mody 		bfa_sm_fault(event);
68045979c1eSRasesh Mody 	}
68145979c1eSRasesh Mody }
68245979c1eSRasesh Mody 
68345979c1eSRasesh Mody static void
bna_ethport_sm_last_resp_wait_entry(struct bna_ethport * ethport)68445979c1eSRasesh Mody bna_ethport_sm_last_resp_wait_entry(struct bna_ethport *ethport)
68545979c1eSRasesh Mody {
68645979c1eSRasesh Mody }
68745979c1eSRasesh Mody 
68845979c1eSRasesh Mody static void
bna_ethport_sm_last_resp_wait(struct bna_ethport * ethport,enum bna_ethport_event event)68945979c1eSRasesh Mody bna_ethport_sm_last_resp_wait(struct bna_ethport *ethport,
69045979c1eSRasesh Mody 			enum bna_ethport_event event)
69145979c1eSRasesh Mody {
69245979c1eSRasesh Mody 	switch (event) {
69345979c1eSRasesh Mody 	case ETHPORT_E_FAIL:
69445979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
69545979c1eSRasesh Mody 		break;
69645979c1eSRasesh Mody 
69745979c1eSRasesh Mody 	case ETHPORT_E_DOWN:
69845979c1eSRasesh Mody 		/**
69945979c1eSRasesh Mody 		 * This event is received due to Rx objects stopping in
70045979c1eSRasesh Mody 		 * parallel to ethport
70145979c1eSRasesh Mody 		 */
70245979c1eSRasesh Mody 		/* No-op */
70345979c1eSRasesh Mody 		break;
70445979c1eSRasesh Mody 
70545979c1eSRasesh Mody 	case ETHPORT_E_FWRESP_UP_OK:
70645979c1eSRasesh Mody 		/* up_resp_wait->last_resp_wait transition on ETHPORT_T_STOP */
70745979c1eSRasesh Mody 		bna_bfi_ethport_down(ethport);
70845979c1eSRasesh Mody 		break;
70945979c1eSRasesh Mody 
71045979c1eSRasesh Mody 	case ETHPORT_E_FWRESP_UP_FAIL:
71145979c1eSRasesh Mody 	case ETHPORT_E_FWRESP_DOWN:
71245979c1eSRasesh Mody 		bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
71345979c1eSRasesh Mody 		break;
71445979c1eSRasesh Mody 
71545979c1eSRasesh Mody 	default:
71645979c1eSRasesh Mody 		bfa_sm_fault(event);
71745979c1eSRasesh Mody 	}
71845979c1eSRasesh Mody }
71945979c1eSRasesh Mody 
72045979c1eSRasesh Mody static void
bna_ethport_init(struct bna_ethport * ethport,struct bna * bna)72145979c1eSRasesh Mody bna_ethport_init(struct bna_ethport *ethport, struct bna *bna)
72245979c1eSRasesh Mody {
72345979c1eSRasesh Mody 	ethport->flags |= (BNA_ETHPORT_F_ADMIN_UP | BNA_ETHPORT_F_PORT_ENABLED);
72445979c1eSRasesh Mody 	ethport->bna = bna;
72545979c1eSRasesh Mody 
72645979c1eSRasesh Mody 	ethport->link_status = BNA_LINK_DOWN;
72745979c1eSRasesh Mody 	ethport->link_cbfn = bnad_cb_ethport_link_status;
72845979c1eSRasesh Mody 
72945979c1eSRasesh Mody 	ethport->rx_started_count = 0;
73045979c1eSRasesh Mody 
73145979c1eSRasesh Mody 	ethport->stop_cbfn = NULL;
73245979c1eSRasesh Mody 	ethport->adminup_cbfn = NULL;
73345979c1eSRasesh Mody 
73445979c1eSRasesh Mody 	bfa_fsm_set_state(ethport, bna_ethport_sm_stopped);
73545979c1eSRasesh Mody }
73645979c1eSRasesh Mody 
73745979c1eSRasesh Mody static void
bna_ethport_uninit(struct bna_ethport * ethport)73845979c1eSRasesh Mody bna_ethport_uninit(struct bna_ethport *ethport)
73945979c1eSRasesh Mody {
74045979c1eSRasesh Mody 	ethport->flags &= ~BNA_ETHPORT_F_ADMIN_UP;
74145979c1eSRasesh Mody 	ethport->flags &= ~BNA_ETHPORT_F_PORT_ENABLED;
74245979c1eSRasesh Mody 
74345979c1eSRasesh Mody 	ethport->bna = NULL;
74445979c1eSRasesh Mody }
74545979c1eSRasesh Mody 
74645979c1eSRasesh Mody static void
bna_ethport_start(struct bna_ethport * ethport)74745979c1eSRasesh Mody bna_ethport_start(struct bna_ethport *ethport)
74845979c1eSRasesh Mody {
74945979c1eSRasesh Mody 	bfa_fsm_send_event(ethport, ETHPORT_E_START);
75045979c1eSRasesh Mody }
75145979c1eSRasesh Mody 
75245979c1eSRasesh Mody static void
bna_enet_cb_ethport_stopped(struct bna_enet * enet)75345979c1eSRasesh Mody bna_enet_cb_ethport_stopped(struct bna_enet *enet)
75445979c1eSRasesh Mody {
75545979c1eSRasesh Mody 	bfa_wc_down(&enet->chld_stop_wc);
75645979c1eSRasesh Mody }
75745979c1eSRasesh Mody 
75845979c1eSRasesh Mody static void
bna_ethport_stop(struct bna_ethport * ethport)75945979c1eSRasesh Mody bna_ethport_stop(struct bna_ethport *ethport)
76045979c1eSRasesh Mody {
76145979c1eSRasesh Mody 	ethport->stop_cbfn = bna_enet_cb_ethport_stopped;
76245979c1eSRasesh Mody 	bfa_fsm_send_event(ethport, ETHPORT_E_STOP);
76345979c1eSRasesh Mody }
76445979c1eSRasesh Mody 
76545979c1eSRasesh Mody static void
bna_ethport_fail(struct bna_ethport * ethport)76645979c1eSRasesh Mody bna_ethport_fail(struct bna_ethport *ethport)
76745979c1eSRasesh Mody {
76845979c1eSRasesh Mody 	/* Reset the physical port status to enabled */
76945979c1eSRasesh Mody 	ethport->flags |= BNA_ETHPORT_F_PORT_ENABLED;
77045979c1eSRasesh Mody 
77145979c1eSRasesh Mody 	if (ethport->link_status != BNA_LINK_DOWN) {
77245979c1eSRasesh Mody 		ethport->link_status = BNA_LINK_DOWN;
77345979c1eSRasesh Mody 		ethport->link_cbfn(ethport->bna->bnad, BNA_LINK_DOWN);
77445979c1eSRasesh Mody 	}
77545979c1eSRasesh Mody 	bfa_fsm_send_event(ethport, ETHPORT_E_FAIL);
77645979c1eSRasesh Mody }
77745979c1eSRasesh Mody 
77845979c1eSRasesh Mody /* Should be called only when ethport is disabled */
77945979c1eSRasesh Mody void
bna_ethport_cb_rx_started(struct bna_ethport * ethport)78045979c1eSRasesh Mody bna_ethport_cb_rx_started(struct bna_ethport *ethport)
78145979c1eSRasesh Mody {
78245979c1eSRasesh Mody 	ethport->rx_started_count++;
78345979c1eSRasesh Mody 
78445979c1eSRasesh Mody 	if (ethport->rx_started_count == 1) {
78545979c1eSRasesh Mody 		ethport->flags |= BNA_ETHPORT_F_RX_STARTED;
78645979c1eSRasesh Mody 
78745979c1eSRasesh Mody 		if (ethport_can_be_up(ethport))
78845979c1eSRasesh Mody 			bfa_fsm_send_event(ethport, ETHPORT_E_UP);
78945979c1eSRasesh Mody 	}
79045979c1eSRasesh Mody }
79145979c1eSRasesh Mody 
79245979c1eSRasesh Mody void
bna_ethport_cb_rx_stopped(struct bna_ethport * ethport)79345979c1eSRasesh Mody bna_ethport_cb_rx_stopped(struct bna_ethport *ethport)
79445979c1eSRasesh Mody {
79545979c1eSRasesh Mody 	int ethport_up = ethport_is_up(ethport);
79645979c1eSRasesh Mody 
79745979c1eSRasesh Mody 	ethport->rx_started_count--;
79845979c1eSRasesh Mody 
79945979c1eSRasesh Mody 	if (ethport->rx_started_count == 0) {
80045979c1eSRasesh Mody 		ethport->flags &= ~BNA_ETHPORT_F_RX_STARTED;
80145979c1eSRasesh Mody 
80245979c1eSRasesh Mody 		if (ethport_up)
80345979c1eSRasesh Mody 			bfa_fsm_send_event(ethport, ETHPORT_E_DOWN);
80445979c1eSRasesh Mody 	}
80545979c1eSRasesh Mody }
80645979c1eSRasesh Mody 
8071aa8b471SBen Hutchings /* ENET */
8081aa8b471SBen Hutchings 
80945979c1eSRasesh Mody #define bna_enet_chld_start(enet)					\
81045979c1eSRasesh Mody do {									\
81145979c1eSRasesh Mody 	enum bna_tx_type tx_type =					\
81245979c1eSRasesh Mody 		((enet)->type == BNA_ENET_T_REGULAR) ?			\
81345979c1eSRasesh Mody 		BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;			\
81445979c1eSRasesh Mody 	enum bna_rx_type rx_type =					\
81545979c1eSRasesh Mody 		((enet)->type == BNA_ENET_T_REGULAR) ?			\
81645979c1eSRasesh Mody 		BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;			\
81745979c1eSRasesh Mody 	bna_ethport_start(&(enet)->bna->ethport);			\
81845979c1eSRasesh Mody 	bna_tx_mod_start(&(enet)->bna->tx_mod, tx_type);		\
81945979c1eSRasesh Mody 	bna_rx_mod_start(&(enet)->bna->rx_mod, rx_type);		\
82045979c1eSRasesh Mody } while (0)
82145979c1eSRasesh Mody 
82245979c1eSRasesh Mody #define bna_enet_chld_stop(enet)					\
82345979c1eSRasesh Mody do {									\
82445979c1eSRasesh Mody 	enum bna_tx_type tx_type =					\
82545979c1eSRasesh Mody 		((enet)->type == BNA_ENET_T_REGULAR) ?			\
82645979c1eSRasesh Mody 		BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;			\
82745979c1eSRasesh Mody 	enum bna_rx_type rx_type =					\
82845979c1eSRasesh Mody 		((enet)->type == BNA_ENET_T_REGULAR) ?			\
82945979c1eSRasesh Mody 		BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;			\
83045979c1eSRasesh Mody 	bfa_wc_init(&(enet)->chld_stop_wc, bna_enet_cb_chld_stopped, (enet));\
83145979c1eSRasesh Mody 	bfa_wc_up(&(enet)->chld_stop_wc);				\
83245979c1eSRasesh Mody 	bna_ethport_stop(&(enet)->bna->ethport);			\
83345979c1eSRasesh Mody 	bfa_wc_up(&(enet)->chld_stop_wc);				\
83445979c1eSRasesh Mody 	bna_tx_mod_stop(&(enet)->bna->tx_mod, tx_type);			\
83545979c1eSRasesh Mody 	bfa_wc_up(&(enet)->chld_stop_wc);				\
83645979c1eSRasesh Mody 	bna_rx_mod_stop(&(enet)->bna->rx_mod, rx_type);			\
83745979c1eSRasesh Mody 	bfa_wc_wait(&(enet)->chld_stop_wc);				\
83845979c1eSRasesh Mody } while (0)
83945979c1eSRasesh Mody 
84045979c1eSRasesh Mody #define bna_enet_chld_fail(enet)					\
84145979c1eSRasesh Mody do {									\
84245979c1eSRasesh Mody 	bna_ethport_fail(&(enet)->bna->ethport);			\
84345979c1eSRasesh Mody 	bna_tx_mod_fail(&(enet)->bna->tx_mod);				\
84445979c1eSRasesh Mody 	bna_rx_mod_fail(&(enet)->bna->rx_mod);				\
84545979c1eSRasesh Mody } while (0)
84645979c1eSRasesh Mody 
84745979c1eSRasesh Mody #define bna_enet_rx_start(enet)						\
84845979c1eSRasesh Mody do {									\
84945979c1eSRasesh Mody 	enum bna_rx_type rx_type =					\
85045979c1eSRasesh Mody 		((enet)->type == BNA_ENET_T_REGULAR) ?			\
85145979c1eSRasesh Mody 		BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;			\
85245979c1eSRasesh Mody 	bna_rx_mod_start(&(enet)->bna->rx_mod, rx_type);		\
85345979c1eSRasesh Mody } while (0)
85445979c1eSRasesh Mody 
85545979c1eSRasesh Mody #define bna_enet_rx_stop(enet)						\
85645979c1eSRasesh Mody do {									\
85745979c1eSRasesh Mody 	enum bna_rx_type rx_type =					\
85845979c1eSRasesh Mody 		((enet)->type == BNA_ENET_T_REGULAR) ?			\
85945979c1eSRasesh Mody 		BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;			\
86045979c1eSRasesh Mody 	bfa_wc_init(&(enet)->chld_stop_wc, bna_enet_cb_chld_stopped, (enet));\
86145979c1eSRasesh Mody 	bfa_wc_up(&(enet)->chld_stop_wc);				\
86245979c1eSRasesh Mody 	bna_rx_mod_stop(&(enet)->bna->rx_mod, rx_type);			\
86345979c1eSRasesh Mody 	bfa_wc_wait(&(enet)->chld_stop_wc);				\
86445979c1eSRasesh Mody } while (0)
86545979c1eSRasesh Mody 
86645979c1eSRasesh Mody #define call_enet_stop_cbfn(enet)					\
86745979c1eSRasesh Mody do {									\
86845979c1eSRasesh Mody 	if ((enet)->stop_cbfn) {					\
86945979c1eSRasesh Mody 		void (*cbfn)(void *);					\
87045979c1eSRasesh Mody 		void *cbarg;						\
87145979c1eSRasesh Mody 		cbfn = (enet)->stop_cbfn;				\
87245979c1eSRasesh Mody 		cbarg = (enet)->stop_cbarg;				\
87345979c1eSRasesh Mody 		(enet)->stop_cbfn = NULL;				\
87445979c1eSRasesh Mody 		(enet)->stop_cbarg = NULL;				\
87545979c1eSRasesh Mody 		cbfn(cbarg);						\
87645979c1eSRasesh Mody 	}								\
87745979c1eSRasesh Mody } while (0)
87845979c1eSRasesh Mody 
87945979c1eSRasesh Mody #define call_enet_mtu_cbfn(enet)					\
88045979c1eSRasesh Mody do {									\
88145979c1eSRasesh Mody 	if ((enet)->mtu_cbfn) {						\
88245979c1eSRasesh Mody 		void (*cbfn)(struct bnad *);				\
88345979c1eSRasesh Mody 		cbfn = (enet)->mtu_cbfn;				\
88445979c1eSRasesh Mody 		(enet)->mtu_cbfn = NULL;				\
88545979c1eSRasesh Mody 		cbfn((enet)->bna->bnad);				\
88645979c1eSRasesh Mody 	}								\
88745979c1eSRasesh Mody } while (0)
88845979c1eSRasesh Mody 
88945979c1eSRasesh Mody static void bna_enet_cb_chld_stopped(void *arg);
89045979c1eSRasesh Mody static void bna_bfi_pause_set(struct bna_enet *enet);
89145979c1eSRasesh Mody 
89245979c1eSRasesh Mody bfa_fsm_state_decl(bna_enet, stopped, struct bna_enet,
89345979c1eSRasesh Mody 			enum bna_enet_event);
89445979c1eSRasesh Mody bfa_fsm_state_decl(bna_enet, pause_init_wait, struct bna_enet,
89545979c1eSRasesh Mody 			enum bna_enet_event);
89645979c1eSRasesh Mody bfa_fsm_state_decl(bna_enet, last_resp_wait, struct bna_enet,
89745979c1eSRasesh Mody 			enum bna_enet_event);
89845979c1eSRasesh Mody bfa_fsm_state_decl(bna_enet, started, struct bna_enet,
89945979c1eSRasesh Mody 			enum bna_enet_event);
90045979c1eSRasesh Mody bfa_fsm_state_decl(bna_enet, cfg_wait, struct bna_enet,
90145979c1eSRasesh Mody 			enum bna_enet_event);
90245979c1eSRasesh Mody bfa_fsm_state_decl(bna_enet, cfg_stop_wait, struct bna_enet,
90345979c1eSRasesh Mody 			enum bna_enet_event);
90445979c1eSRasesh Mody bfa_fsm_state_decl(bna_enet, chld_stop_wait, struct bna_enet,
90545979c1eSRasesh Mody 			enum bna_enet_event);
90645979c1eSRasesh Mody 
90745979c1eSRasesh Mody static void
bna_enet_sm_stopped_entry(struct bna_enet * enet)90845979c1eSRasesh Mody bna_enet_sm_stopped_entry(struct bna_enet *enet)
90945979c1eSRasesh Mody {
91045979c1eSRasesh Mody 	call_enet_mtu_cbfn(enet);
91145979c1eSRasesh Mody 	call_enet_stop_cbfn(enet);
91245979c1eSRasesh Mody }
91345979c1eSRasesh Mody 
91445979c1eSRasesh Mody static void
bna_enet_sm_stopped(struct bna_enet * enet,enum bna_enet_event event)91545979c1eSRasesh Mody bna_enet_sm_stopped(struct bna_enet *enet, enum bna_enet_event event)
91645979c1eSRasesh Mody {
91745979c1eSRasesh Mody 	switch (event) {
91845979c1eSRasesh Mody 	case ENET_E_START:
91945979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_pause_init_wait);
92045979c1eSRasesh Mody 		break;
92145979c1eSRasesh Mody 
92245979c1eSRasesh Mody 	case ENET_E_STOP:
92345979c1eSRasesh Mody 		call_enet_stop_cbfn(enet);
92445979c1eSRasesh Mody 		break;
92545979c1eSRasesh Mody 
92645979c1eSRasesh Mody 	case ENET_E_FAIL:
92745979c1eSRasesh Mody 		/* No-op */
92845979c1eSRasesh Mody 		break;
92945979c1eSRasesh Mody 
93045979c1eSRasesh Mody 	case ENET_E_PAUSE_CFG:
93145979c1eSRasesh Mody 		break;
93245979c1eSRasesh Mody 
93345979c1eSRasesh Mody 	case ENET_E_MTU_CFG:
93445979c1eSRasesh Mody 		call_enet_mtu_cbfn(enet);
93545979c1eSRasesh Mody 		break;
93645979c1eSRasesh Mody 
93745979c1eSRasesh Mody 	case ENET_E_CHLD_STOPPED:
93845979c1eSRasesh Mody 		/**
93945979c1eSRasesh Mody 		 * This event is received due to Ethport, Tx and Rx objects
94045979c1eSRasesh Mody 		 * failing
94145979c1eSRasesh Mody 		 */
94245979c1eSRasesh Mody 		/* No-op */
94345979c1eSRasesh Mody 		break;
94445979c1eSRasesh Mody 
94545979c1eSRasesh Mody 	default:
94645979c1eSRasesh Mody 		bfa_sm_fault(event);
94745979c1eSRasesh Mody 	}
94845979c1eSRasesh Mody }
94945979c1eSRasesh Mody 
95045979c1eSRasesh Mody static void
bna_enet_sm_pause_init_wait_entry(struct bna_enet * enet)95145979c1eSRasesh Mody bna_enet_sm_pause_init_wait_entry(struct bna_enet *enet)
95245979c1eSRasesh Mody {
95345979c1eSRasesh Mody 	bna_bfi_pause_set(enet);
95445979c1eSRasesh Mody }
95545979c1eSRasesh Mody 
95645979c1eSRasesh Mody static void
bna_enet_sm_pause_init_wait(struct bna_enet * enet,enum bna_enet_event event)95745979c1eSRasesh Mody bna_enet_sm_pause_init_wait(struct bna_enet *enet,
95845979c1eSRasesh Mody 				enum bna_enet_event event)
95945979c1eSRasesh Mody {
96045979c1eSRasesh Mody 	switch (event) {
96145979c1eSRasesh Mody 	case ENET_E_STOP:
96245979c1eSRasesh Mody 		enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
96345979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_last_resp_wait);
96445979c1eSRasesh Mody 		break;
96545979c1eSRasesh Mody 
96645979c1eSRasesh Mody 	case ENET_E_FAIL:
96745979c1eSRasesh Mody 		enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
96845979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
96945979c1eSRasesh Mody 		break;
97045979c1eSRasesh Mody 
97145979c1eSRasesh Mody 	case ENET_E_PAUSE_CFG:
97245979c1eSRasesh Mody 		enet->flags |= BNA_ENET_F_PAUSE_CHANGED;
97345979c1eSRasesh Mody 		break;
97445979c1eSRasesh Mody 
97545979c1eSRasesh Mody 	case ENET_E_MTU_CFG:
97645979c1eSRasesh Mody 		/* No-op */
97745979c1eSRasesh Mody 		break;
97845979c1eSRasesh Mody 
97945979c1eSRasesh Mody 	case ENET_E_FWRESP_PAUSE:
98045979c1eSRasesh Mody 		if (enet->flags & BNA_ENET_F_PAUSE_CHANGED) {
98145979c1eSRasesh Mody 			enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
98245979c1eSRasesh Mody 			bna_bfi_pause_set(enet);
98345979c1eSRasesh Mody 		} else {
98445979c1eSRasesh Mody 			bfa_fsm_set_state(enet, bna_enet_sm_started);
98545979c1eSRasesh Mody 			bna_enet_chld_start(enet);
98645979c1eSRasesh Mody 		}
98745979c1eSRasesh Mody 		break;
98845979c1eSRasesh Mody 
98945979c1eSRasesh Mody 	default:
99045979c1eSRasesh Mody 		bfa_sm_fault(event);
99145979c1eSRasesh Mody 	}
99245979c1eSRasesh Mody }
99345979c1eSRasesh Mody 
99445979c1eSRasesh Mody static void
bna_enet_sm_last_resp_wait_entry(struct bna_enet * enet)99545979c1eSRasesh Mody bna_enet_sm_last_resp_wait_entry(struct bna_enet *enet)
99645979c1eSRasesh Mody {
99745979c1eSRasesh Mody 	enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
99845979c1eSRasesh Mody }
99945979c1eSRasesh Mody 
100045979c1eSRasesh Mody static void
bna_enet_sm_last_resp_wait(struct bna_enet * enet,enum bna_enet_event event)100145979c1eSRasesh Mody bna_enet_sm_last_resp_wait(struct bna_enet *enet,
100245979c1eSRasesh Mody 				enum bna_enet_event event)
100345979c1eSRasesh Mody {
100445979c1eSRasesh Mody 	switch (event) {
100545979c1eSRasesh Mody 	case ENET_E_FAIL:
100645979c1eSRasesh Mody 	case ENET_E_FWRESP_PAUSE:
100745979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
100845979c1eSRasesh Mody 		break;
100945979c1eSRasesh Mody 
101045979c1eSRasesh Mody 	default:
101145979c1eSRasesh Mody 		bfa_sm_fault(event);
101245979c1eSRasesh Mody 	}
101345979c1eSRasesh Mody }
101445979c1eSRasesh Mody 
101545979c1eSRasesh Mody static void
bna_enet_sm_started_entry(struct bna_enet * enet)101645979c1eSRasesh Mody bna_enet_sm_started_entry(struct bna_enet *enet)
101745979c1eSRasesh Mody {
101845979c1eSRasesh Mody 	/**
101945979c1eSRasesh Mody 	 * NOTE: Do not call bna_enet_chld_start() here, since it will be
102045979c1eSRasesh Mody 	 * inadvertently called during cfg_wait->started transition as well
102145979c1eSRasesh Mody 	 */
102245979c1eSRasesh Mody 	call_enet_mtu_cbfn(enet);
102345979c1eSRasesh Mody }
102445979c1eSRasesh Mody 
102545979c1eSRasesh Mody static void
bna_enet_sm_started(struct bna_enet * enet,enum bna_enet_event event)102645979c1eSRasesh Mody bna_enet_sm_started(struct bna_enet *enet,
102745979c1eSRasesh Mody 			enum bna_enet_event event)
102845979c1eSRasesh Mody {
102945979c1eSRasesh Mody 	switch (event) {
103045979c1eSRasesh Mody 	case ENET_E_STOP:
103145979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_chld_stop_wait);
103245979c1eSRasesh Mody 		break;
103345979c1eSRasesh Mody 
103445979c1eSRasesh Mody 	case ENET_E_FAIL:
103545979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
103645979c1eSRasesh Mody 		bna_enet_chld_fail(enet);
103745979c1eSRasesh Mody 		break;
103845979c1eSRasesh Mody 
103945979c1eSRasesh Mody 	case ENET_E_PAUSE_CFG:
104045979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_cfg_wait);
104145979c1eSRasesh Mody 		bna_bfi_pause_set(enet);
104245979c1eSRasesh Mody 		break;
104345979c1eSRasesh Mody 
104445979c1eSRasesh Mody 	case ENET_E_MTU_CFG:
104545979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_cfg_wait);
104645979c1eSRasesh Mody 		bna_enet_rx_stop(enet);
104745979c1eSRasesh Mody 		break;
104845979c1eSRasesh Mody 
104945979c1eSRasesh Mody 	default:
105045979c1eSRasesh Mody 		bfa_sm_fault(event);
105145979c1eSRasesh Mody 	}
105245979c1eSRasesh Mody }
105345979c1eSRasesh Mody 
105445979c1eSRasesh Mody static void
bna_enet_sm_cfg_wait_entry(struct bna_enet * enet)105545979c1eSRasesh Mody bna_enet_sm_cfg_wait_entry(struct bna_enet *enet)
105645979c1eSRasesh Mody {
105745979c1eSRasesh Mody }
105845979c1eSRasesh Mody 
105945979c1eSRasesh Mody static void
bna_enet_sm_cfg_wait(struct bna_enet * enet,enum bna_enet_event event)106045979c1eSRasesh Mody bna_enet_sm_cfg_wait(struct bna_enet *enet,
106145979c1eSRasesh Mody 			enum bna_enet_event event)
106245979c1eSRasesh Mody {
106345979c1eSRasesh Mody 	switch (event) {
106445979c1eSRasesh Mody 	case ENET_E_STOP:
106545979c1eSRasesh Mody 		enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
106645979c1eSRasesh Mody 		enet->flags &= ~BNA_ENET_F_MTU_CHANGED;
106745979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_cfg_stop_wait);
106845979c1eSRasesh Mody 		break;
106945979c1eSRasesh Mody 
107045979c1eSRasesh Mody 	case ENET_E_FAIL:
107145979c1eSRasesh Mody 		enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
107245979c1eSRasesh Mody 		enet->flags &= ~BNA_ENET_F_MTU_CHANGED;
107345979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
107445979c1eSRasesh Mody 		bna_enet_chld_fail(enet);
107545979c1eSRasesh Mody 		break;
107645979c1eSRasesh Mody 
107745979c1eSRasesh Mody 	case ENET_E_PAUSE_CFG:
107845979c1eSRasesh Mody 		enet->flags |= BNA_ENET_F_PAUSE_CHANGED;
107945979c1eSRasesh Mody 		break;
108045979c1eSRasesh Mody 
108145979c1eSRasesh Mody 	case ENET_E_MTU_CFG:
108245979c1eSRasesh Mody 		enet->flags |= BNA_ENET_F_MTU_CHANGED;
108345979c1eSRasesh Mody 		break;
108445979c1eSRasesh Mody 
108545979c1eSRasesh Mody 	case ENET_E_CHLD_STOPPED:
108645979c1eSRasesh Mody 		bna_enet_rx_start(enet);
1087df561f66SGustavo A. R. Silva 		fallthrough;
108845979c1eSRasesh Mody 	case ENET_E_FWRESP_PAUSE:
108945979c1eSRasesh Mody 		if (enet->flags & BNA_ENET_F_PAUSE_CHANGED) {
109045979c1eSRasesh Mody 			enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
109145979c1eSRasesh Mody 			bna_bfi_pause_set(enet);
109245979c1eSRasesh Mody 		} else if (enet->flags & BNA_ENET_F_MTU_CHANGED) {
109345979c1eSRasesh Mody 			enet->flags &= ~BNA_ENET_F_MTU_CHANGED;
109445979c1eSRasesh Mody 			bna_enet_rx_stop(enet);
109545979c1eSRasesh Mody 		} else {
109645979c1eSRasesh Mody 			bfa_fsm_set_state(enet, bna_enet_sm_started);
109745979c1eSRasesh Mody 		}
109845979c1eSRasesh Mody 		break;
109945979c1eSRasesh Mody 
110045979c1eSRasesh Mody 	default:
110145979c1eSRasesh Mody 		bfa_sm_fault(event);
110245979c1eSRasesh Mody 	}
110345979c1eSRasesh Mody }
110445979c1eSRasesh Mody 
110545979c1eSRasesh Mody static void
bna_enet_sm_cfg_stop_wait_entry(struct bna_enet * enet)110645979c1eSRasesh Mody bna_enet_sm_cfg_stop_wait_entry(struct bna_enet *enet)
110745979c1eSRasesh Mody {
110845979c1eSRasesh Mody 	enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED;
110945979c1eSRasesh Mody 	enet->flags &= ~BNA_ENET_F_MTU_CHANGED;
111045979c1eSRasesh Mody }
111145979c1eSRasesh Mody 
111245979c1eSRasesh Mody static void
bna_enet_sm_cfg_stop_wait(struct bna_enet * enet,enum bna_enet_event event)111345979c1eSRasesh Mody bna_enet_sm_cfg_stop_wait(struct bna_enet *enet,
111445979c1eSRasesh Mody 				enum bna_enet_event event)
111545979c1eSRasesh Mody {
111645979c1eSRasesh Mody 	switch (event) {
111745979c1eSRasesh Mody 	case ENET_E_FAIL:
111845979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
111945979c1eSRasesh Mody 		bna_enet_chld_fail(enet);
112045979c1eSRasesh Mody 		break;
112145979c1eSRasesh Mody 
112245979c1eSRasesh Mody 	case ENET_E_FWRESP_PAUSE:
112345979c1eSRasesh Mody 	case ENET_E_CHLD_STOPPED:
112445979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_chld_stop_wait);
112545979c1eSRasesh Mody 		break;
112645979c1eSRasesh Mody 
112745979c1eSRasesh Mody 	default:
112845979c1eSRasesh Mody 		bfa_sm_fault(event);
112945979c1eSRasesh Mody 	}
113045979c1eSRasesh Mody }
113145979c1eSRasesh Mody 
113245979c1eSRasesh Mody static void
bna_enet_sm_chld_stop_wait_entry(struct bna_enet * enet)113345979c1eSRasesh Mody bna_enet_sm_chld_stop_wait_entry(struct bna_enet *enet)
113445979c1eSRasesh Mody {
113545979c1eSRasesh Mody 	bna_enet_chld_stop(enet);
113645979c1eSRasesh Mody }
113745979c1eSRasesh Mody 
113845979c1eSRasesh Mody static void
bna_enet_sm_chld_stop_wait(struct bna_enet * enet,enum bna_enet_event event)113945979c1eSRasesh Mody bna_enet_sm_chld_stop_wait(struct bna_enet *enet,
114045979c1eSRasesh Mody 				enum bna_enet_event event)
114145979c1eSRasesh Mody {
114245979c1eSRasesh Mody 	switch (event) {
114345979c1eSRasesh Mody 	case ENET_E_FAIL:
114445979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
114545979c1eSRasesh Mody 		bna_enet_chld_fail(enet);
114645979c1eSRasesh Mody 		break;
114745979c1eSRasesh Mody 
114845979c1eSRasesh Mody 	case ENET_E_CHLD_STOPPED:
114945979c1eSRasesh Mody 		bfa_fsm_set_state(enet, bna_enet_sm_stopped);
115045979c1eSRasesh Mody 		break;
115145979c1eSRasesh Mody 
115245979c1eSRasesh Mody 	default:
115345979c1eSRasesh Mody 		bfa_sm_fault(event);
115445979c1eSRasesh Mody 	}
115545979c1eSRasesh Mody }
115645979c1eSRasesh Mody 
115745979c1eSRasesh Mody static void
bna_bfi_pause_set(struct bna_enet * enet)115845979c1eSRasesh Mody bna_bfi_pause_set(struct bna_enet *enet)
115945979c1eSRasesh Mody {
116045979c1eSRasesh Mody 	struct bfi_enet_set_pause_req *pause_req = &enet->pause_req;
116145979c1eSRasesh Mody 
116245979c1eSRasesh Mody 	bfi_msgq_mhdr_set(pause_req->mh, BFI_MC_ENET,
116345979c1eSRasesh Mody 		BFI_ENET_H2I_SET_PAUSE_REQ, 0, 0);
116445979c1eSRasesh Mody 	pause_req->mh.num_entries = htons(
116545979c1eSRasesh Mody 	bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_set_pause_req)));
116645979c1eSRasesh Mody 	pause_req->tx_pause = enet->pause_config.tx_pause;
116745979c1eSRasesh Mody 	pause_req->rx_pause = enet->pause_config.rx_pause;
116845979c1eSRasesh Mody 
116945979c1eSRasesh Mody 	bfa_msgq_cmd_set(&enet->msgq_cmd, NULL, NULL,
117045979c1eSRasesh Mody 		sizeof(struct bfi_enet_set_pause_req), &pause_req->mh);
117145979c1eSRasesh Mody 	bfa_msgq_cmd_post(&enet->bna->msgq, &enet->msgq_cmd);
117245979c1eSRasesh Mody }
117345979c1eSRasesh Mody 
117445979c1eSRasesh Mody static void
bna_enet_cb_chld_stopped(void * arg)117545979c1eSRasesh Mody bna_enet_cb_chld_stopped(void *arg)
117645979c1eSRasesh Mody {
117745979c1eSRasesh Mody 	struct bna_enet *enet = (struct bna_enet *)arg;
117845979c1eSRasesh Mody 
117945979c1eSRasesh Mody 	bfa_fsm_send_event(enet, ENET_E_CHLD_STOPPED);
118045979c1eSRasesh Mody }
118145979c1eSRasesh Mody 
118245979c1eSRasesh Mody static void
bna_enet_init(struct bna_enet * enet,struct bna * bna)118345979c1eSRasesh Mody bna_enet_init(struct bna_enet *enet, struct bna *bna)
118445979c1eSRasesh Mody {
118545979c1eSRasesh Mody 	enet->bna = bna;
118645979c1eSRasesh Mody 	enet->flags = 0;
118745979c1eSRasesh Mody 	enet->mtu = 0;
118845979c1eSRasesh Mody 	enet->type = BNA_ENET_T_REGULAR;
118945979c1eSRasesh Mody 
119045979c1eSRasesh Mody 	enet->stop_cbfn = NULL;
119145979c1eSRasesh Mody 	enet->stop_cbarg = NULL;
119245979c1eSRasesh Mody 
119345979c1eSRasesh Mody 	enet->mtu_cbfn = NULL;
119445979c1eSRasesh Mody 
119545979c1eSRasesh Mody 	bfa_fsm_set_state(enet, bna_enet_sm_stopped);
119645979c1eSRasesh Mody }
119745979c1eSRasesh Mody 
119845979c1eSRasesh Mody static void
bna_enet_uninit(struct bna_enet * enet)119945979c1eSRasesh Mody bna_enet_uninit(struct bna_enet *enet)
120045979c1eSRasesh Mody {
120145979c1eSRasesh Mody 	enet->flags = 0;
120245979c1eSRasesh Mody 
120345979c1eSRasesh Mody 	enet->bna = NULL;
120445979c1eSRasesh Mody }
120545979c1eSRasesh Mody 
120645979c1eSRasesh Mody static void
bna_enet_start(struct bna_enet * enet)120745979c1eSRasesh Mody bna_enet_start(struct bna_enet *enet)
120845979c1eSRasesh Mody {
120945979c1eSRasesh Mody 	enet->flags |= BNA_ENET_F_IOCETH_READY;
121045979c1eSRasesh Mody 	if (enet->flags & BNA_ENET_F_ENABLED)
121145979c1eSRasesh Mody 		bfa_fsm_send_event(enet, ENET_E_START);
121245979c1eSRasesh Mody }
121345979c1eSRasesh Mody 
121445979c1eSRasesh Mody static void
bna_ioceth_cb_enet_stopped(void * arg)121545979c1eSRasesh Mody bna_ioceth_cb_enet_stopped(void *arg)
121645979c1eSRasesh Mody {
121745979c1eSRasesh Mody 	struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
121845979c1eSRasesh Mody 
121945979c1eSRasesh Mody 	bfa_fsm_send_event(ioceth, IOCETH_E_ENET_STOPPED);
122045979c1eSRasesh Mody }
122145979c1eSRasesh Mody 
122245979c1eSRasesh Mody static void
bna_enet_stop(struct bna_enet * enet)122345979c1eSRasesh Mody bna_enet_stop(struct bna_enet *enet)
122445979c1eSRasesh Mody {
122545979c1eSRasesh Mody 	enet->stop_cbfn = bna_ioceth_cb_enet_stopped;
122645979c1eSRasesh Mody 	enet->stop_cbarg = &enet->bna->ioceth;
122745979c1eSRasesh Mody 
122845979c1eSRasesh Mody 	enet->flags &= ~BNA_ENET_F_IOCETH_READY;
122945979c1eSRasesh Mody 	bfa_fsm_send_event(enet, ENET_E_STOP);
123045979c1eSRasesh Mody }
123145979c1eSRasesh Mody 
123245979c1eSRasesh Mody static void
bna_enet_fail(struct bna_enet * enet)123345979c1eSRasesh Mody bna_enet_fail(struct bna_enet *enet)
123445979c1eSRasesh Mody {
123545979c1eSRasesh Mody 	enet->flags &= ~BNA_ENET_F_IOCETH_READY;
123645979c1eSRasesh Mody 	bfa_fsm_send_event(enet, ENET_E_FAIL);
123745979c1eSRasesh Mody }
123845979c1eSRasesh Mody 
123945979c1eSRasesh Mody void
bna_enet_cb_tx_stopped(struct bna_enet * enet)124045979c1eSRasesh Mody bna_enet_cb_tx_stopped(struct bna_enet *enet)
124145979c1eSRasesh Mody {
124245979c1eSRasesh Mody 	bfa_wc_down(&enet->chld_stop_wc);
124345979c1eSRasesh Mody }
124445979c1eSRasesh Mody 
124545979c1eSRasesh Mody void
bna_enet_cb_rx_stopped(struct bna_enet * enet)124645979c1eSRasesh Mody bna_enet_cb_rx_stopped(struct bna_enet *enet)
124745979c1eSRasesh Mody {
124845979c1eSRasesh Mody 	bfa_wc_down(&enet->chld_stop_wc);
124945979c1eSRasesh Mody }
125045979c1eSRasesh Mody 
125145979c1eSRasesh Mody int
bna_enet_mtu_get(struct bna_enet * enet)125245979c1eSRasesh Mody bna_enet_mtu_get(struct bna_enet *enet)
125345979c1eSRasesh Mody {
125445979c1eSRasesh Mody 	return enet->mtu;
125545979c1eSRasesh Mody }
125645979c1eSRasesh Mody 
125745979c1eSRasesh Mody void
bna_enet_enable(struct bna_enet * enet)125845979c1eSRasesh Mody bna_enet_enable(struct bna_enet *enet)
125945979c1eSRasesh Mody {
1260*8719a1c3SGustavo A. R. Silva 	if (enet->fsm != bna_enet_sm_stopped)
126145979c1eSRasesh Mody 		return;
126245979c1eSRasesh Mody 
126345979c1eSRasesh Mody 	enet->flags |= BNA_ENET_F_ENABLED;
126445979c1eSRasesh Mody 
126545979c1eSRasesh Mody 	if (enet->flags & BNA_ENET_F_IOCETH_READY)
126645979c1eSRasesh Mody 		bfa_fsm_send_event(enet, ENET_E_START);
126745979c1eSRasesh Mody }
126845979c1eSRasesh Mody 
126945979c1eSRasesh Mody void
bna_enet_disable(struct bna_enet * enet,enum bna_cleanup_type type,void (* cbfn)(void *))127045979c1eSRasesh Mody bna_enet_disable(struct bna_enet *enet, enum bna_cleanup_type type,
127145979c1eSRasesh Mody 		 void (*cbfn)(void *))
127245979c1eSRasesh Mody {
127345979c1eSRasesh Mody 	if (type == BNA_SOFT_CLEANUP) {
127445979c1eSRasesh Mody 		(*cbfn)(enet->bna->bnad);
127545979c1eSRasesh Mody 		return;
127645979c1eSRasesh Mody 	}
127745979c1eSRasesh Mody 
127845979c1eSRasesh Mody 	enet->stop_cbfn = cbfn;
127945979c1eSRasesh Mody 	enet->stop_cbarg = enet->bna->bnad;
128045979c1eSRasesh Mody 
128145979c1eSRasesh Mody 	enet->flags &= ~BNA_ENET_F_ENABLED;
128245979c1eSRasesh Mody 
128345979c1eSRasesh Mody 	bfa_fsm_send_event(enet, ENET_E_STOP);
128445979c1eSRasesh Mody }
128545979c1eSRasesh Mody 
128645979c1eSRasesh Mody void
bna_enet_pause_config(struct bna_enet * enet,struct bna_pause_config * pause_config)128745979c1eSRasesh Mody bna_enet_pause_config(struct bna_enet *enet,
12881f9883e0SIvan Vecera 		      struct bna_pause_config *pause_config)
128945979c1eSRasesh Mody {
129045979c1eSRasesh Mody 	enet->pause_config = *pause_config;
129145979c1eSRasesh Mody 
129245979c1eSRasesh Mody 	bfa_fsm_send_event(enet, ENET_E_PAUSE_CFG);
129345979c1eSRasesh Mody }
129445979c1eSRasesh Mody 
129545979c1eSRasesh Mody void
bna_enet_mtu_set(struct bna_enet * enet,int mtu,void (* cbfn)(struct bnad *))129645979c1eSRasesh Mody bna_enet_mtu_set(struct bna_enet *enet, int mtu,
129745979c1eSRasesh Mody 		 void (*cbfn)(struct bnad *))
129845979c1eSRasesh Mody {
129945979c1eSRasesh Mody 	enet->mtu = mtu;
130045979c1eSRasesh Mody 
130145979c1eSRasesh Mody 	enet->mtu_cbfn = cbfn;
130245979c1eSRasesh Mody 
130345979c1eSRasesh Mody 	bfa_fsm_send_event(enet, ENET_E_MTU_CFG);
130445979c1eSRasesh Mody }
130545979c1eSRasesh Mody 
130645979c1eSRasesh Mody void
bna_enet_perm_mac_get(struct bna_enet * enet,u8 * mac)1307d6b30598SIvan Vecera bna_enet_perm_mac_get(struct bna_enet *enet, u8 *mac)
130845979c1eSRasesh Mody {
1309d6b30598SIvan Vecera 	bfa_nw_ioc_get_mac(&enet->bna->ioceth.ioc, mac);
131045979c1eSRasesh Mody }
131145979c1eSRasesh Mody 
13121aa8b471SBen Hutchings /* IOCETH */
13131aa8b471SBen Hutchings 
131445979c1eSRasesh Mody #define enable_mbox_intr(_ioceth)					\
131545979c1eSRasesh Mody do {									\
131645979c1eSRasesh Mody 	u32 intr_status;						\
131745979c1eSRasesh Mody 	bna_intr_status_get((_ioceth)->bna, intr_status);		\
131845979c1eSRasesh Mody 	bnad_cb_mbox_intr_enable((_ioceth)->bna->bnad);			\
131945979c1eSRasesh Mody 	bna_mbox_intr_enable((_ioceth)->bna);				\
132045979c1eSRasesh Mody } while (0)
132145979c1eSRasesh Mody 
132245979c1eSRasesh Mody #define disable_mbox_intr(_ioceth)					\
132345979c1eSRasesh Mody do {									\
132445979c1eSRasesh Mody 	bna_mbox_intr_disable((_ioceth)->bna);				\
132545979c1eSRasesh Mody 	bnad_cb_mbox_intr_disable((_ioceth)->bna->bnad);		\
132645979c1eSRasesh Mody } while (0)
132745979c1eSRasesh Mody 
132845979c1eSRasesh Mody #define call_ioceth_stop_cbfn(_ioceth)					\
132945979c1eSRasesh Mody do {									\
133045979c1eSRasesh Mody 	if ((_ioceth)->stop_cbfn) {					\
133145979c1eSRasesh Mody 		void (*cbfn)(struct bnad *);				\
133245979c1eSRasesh Mody 		struct bnad *cbarg;					\
133345979c1eSRasesh Mody 		cbfn = (_ioceth)->stop_cbfn;				\
133445979c1eSRasesh Mody 		cbarg = (_ioceth)->stop_cbarg;				\
133545979c1eSRasesh Mody 		(_ioceth)->stop_cbfn = NULL;				\
133645979c1eSRasesh Mody 		(_ioceth)->stop_cbarg = NULL;				\
133745979c1eSRasesh Mody 		cbfn(cbarg);						\
133845979c1eSRasesh Mody 	}								\
133945979c1eSRasesh Mody } while (0)
134045979c1eSRasesh Mody 
134145979c1eSRasesh Mody #define bna_stats_mod_uninit(_stats_mod)				\
134245979c1eSRasesh Mody do {									\
134345979c1eSRasesh Mody } while (0)
134445979c1eSRasesh Mody 
134545979c1eSRasesh Mody #define bna_stats_mod_start(_stats_mod)					\
134645979c1eSRasesh Mody do {									\
134745979c1eSRasesh Mody 	(_stats_mod)->ioc_ready = true;					\
134845979c1eSRasesh Mody } while (0)
134945979c1eSRasesh Mody 
135045979c1eSRasesh Mody #define bna_stats_mod_stop(_stats_mod)					\
135145979c1eSRasesh Mody do {									\
135245979c1eSRasesh Mody 	(_stats_mod)->ioc_ready = false;				\
135345979c1eSRasesh Mody } while (0)
135445979c1eSRasesh Mody 
135545979c1eSRasesh Mody #define bna_stats_mod_fail(_stats_mod)					\
135645979c1eSRasesh Mody do {									\
135745979c1eSRasesh Mody 	(_stats_mod)->ioc_ready = false;				\
135845979c1eSRasesh Mody 	(_stats_mod)->stats_get_busy = false;				\
135945979c1eSRasesh Mody 	(_stats_mod)->stats_clr_busy = false;				\
136045979c1eSRasesh Mody } while (0)
136145979c1eSRasesh Mody 
136245979c1eSRasesh Mody static void bna_bfi_attr_get(struct bna_ioceth *ioceth);
136345979c1eSRasesh Mody 
136445979c1eSRasesh Mody bfa_fsm_state_decl(bna_ioceth, stopped, struct bna_ioceth,
136545979c1eSRasesh Mody 			enum bna_ioceth_event);
136645979c1eSRasesh Mody bfa_fsm_state_decl(bna_ioceth, ioc_ready_wait, struct bna_ioceth,
136745979c1eSRasesh Mody 			enum bna_ioceth_event);
136845979c1eSRasesh Mody bfa_fsm_state_decl(bna_ioceth, enet_attr_wait, struct bna_ioceth,
136945979c1eSRasesh Mody 			enum bna_ioceth_event);
137045979c1eSRasesh Mody bfa_fsm_state_decl(bna_ioceth, ready, struct bna_ioceth,
137145979c1eSRasesh Mody 			enum bna_ioceth_event);
137245979c1eSRasesh Mody bfa_fsm_state_decl(bna_ioceth, last_resp_wait, struct bna_ioceth,
137345979c1eSRasesh Mody 			enum bna_ioceth_event);
137445979c1eSRasesh Mody bfa_fsm_state_decl(bna_ioceth, enet_stop_wait, struct bna_ioceth,
137545979c1eSRasesh Mody 			enum bna_ioceth_event);
137645979c1eSRasesh Mody bfa_fsm_state_decl(bna_ioceth, ioc_disable_wait, struct bna_ioceth,
137745979c1eSRasesh Mody 			enum bna_ioceth_event);
137845979c1eSRasesh Mody bfa_fsm_state_decl(bna_ioceth, failed, struct bna_ioceth,
137945979c1eSRasesh Mody 			enum bna_ioceth_event);
138045979c1eSRasesh Mody 
138145979c1eSRasesh Mody static void
bna_ioceth_sm_stopped_entry(struct bna_ioceth * ioceth)138245979c1eSRasesh Mody bna_ioceth_sm_stopped_entry(struct bna_ioceth *ioceth)
138345979c1eSRasesh Mody {
138445979c1eSRasesh Mody 	call_ioceth_stop_cbfn(ioceth);
138545979c1eSRasesh Mody }
138645979c1eSRasesh Mody 
138745979c1eSRasesh Mody static void
bna_ioceth_sm_stopped(struct bna_ioceth * ioceth,enum bna_ioceth_event event)138845979c1eSRasesh Mody bna_ioceth_sm_stopped(struct bna_ioceth *ioceth,
138945979c1eSRasesh Mody 			enum bna_ioceth_event event)
139045979c1eSRasesh Mody {
139145979c1eSRasesh Mody 	switch (event) {
139245979c1eSRasesh Mody 	case IOCETH_E_ENABLE:
139345979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_ready_wait);
139445979c1eSRasesh Mody 		bfa_nw_ioc_enable(&ioceth->ioc);
139545979c1eSRasesh Mody 		break;
139645979c1eSRasesh Mody 
139745979c1eSRasesh Mody 	case IOCETH_E_DISABLE:
139845979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_stopped);
139945979c1eSRasesh Mody 		break;
140045979c1eSRasesh Mody 
140145979c1eSRasesh Mody 	case IOCETH_E_IOC_RESET:
140245979c1eSRasesh Mody 		enable_mbox_intr(ioceth);
140345979c1eSRasesh Mody 		break;
140445979c1eSRasesh Mody 
140545979c1eSRasesh Mody 	case IOCETH_E_IOC_FAILED:
140645979c1eSRasesh Mody 		disable_mbox_intr(ioceth);
140745979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed);
140845979c1eSRasesh Mody 		break;
140945979c1eSRasesh Mody 
141045979c1eSRasesh Mody 	default:
141145979c1eSRasesh Mody 		bfa_sm_fault(event);
141245979c1eSRasesh Mody 	}
141345979c1eSRasesh Mody }
141445979c1eSRasesh Mody 
141545979c1eSRasesh Mody static void
bna_ioceth_sm_ioc_ready_wait_entry(struct bna_ioceth * ioceth)141645979c1eSRasesh Mody bna_ioceth_sm_ioc_ready_wait_entry(struct bna_ioceth *ioceth)
141745979c1eSRasesh Mody {
141845979c1eSRasesh Mody 	/**
141945979c1eSRasesh Mody 	 * Do not call bfa_nw_ioc_enable() here. It must be called in the
142045979c1eSRasesh Mody 	 * previous state due to failed -> ioc_ready_wait transition.
142145979c1eSRasesh Mody 	 */
142245979c1eSRasesh Mody }
142345979c1eSRasesh Mody 
142445979c1eSRasesh Mody static void
bna_ioceth_sm_ioc_ready_wait(struct bna_ioceth * ioceth,enum bna_ioceth_event event)142545979c1eSRasesh Mody bna_ioceth_sm_ioc_ready_wait(struct bna_ioceth *ioceth,
142645979c1eSRasesh Mody 				enum bna_ioceth_event event)
142745979c1eSRasesh Mody {
142845979c1eSRasesh Mody 	switch (event) {
142945979c1eSRasesh Mody 	case IOCETH_E_DISABLE:
143045979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
143145979c1eSRasesh Mody 		bfa_nw_ioc_disable(&ioceth->ioc);
143245979c1eSRasesh Mody 		break;
143345979c1eSRasesh Mody 
143445979c1eSRasesh Mody 	case IOCETH_E_IOC_RESET:
143545979c1eSRasesh Mody 		enable_mbox_intr(ioceth);
143645979c1eSRasesh Mody 		break;
143745979c1eSRasesh Mody 
143845979c1eSRasesh Mody 	case IOCETH_E_IOC_FAILED:
143945979c1eSRasesh Mody 		disable_mbox_intr(ioceth);
144045979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed);
144145979c1eSRasesh Mody 		break;
144245979c1eSRasesh Mody 
144345979c1eSRasesh Mody 	case IOCETH_E_IOC_READY:
144445979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_enet_attr_wait);
144545979c1eSRasesh Mody 		break;
144645979c1eSRasesh Mody 
144745979c1eSRasesh Mody 	default:
144845979c1eSRasesh Mody 		bfa_sm_fault(event);
144945979c1eSRasesh Mody 	}
145045979c1eSRasesh Mody }
145145979c1eSRasesh Mody 
145245979c1eSRasesh Mody static void
bna_ioceth_sm_enet_attr_wait_entry(struct bna_ioceth * ioceth)145345979c1eSRasesh Mody bna_ioceth_sm_enet_attr_wait_entry(struct bna_ioceth *ioceth)
145445979c1eSRasesh Mody {
145545979c1eSRasesh Mody 	bna_bfi_attr_get(ioceth);
145645979c1eSRasesh Mody }
145745979c1eSRasesh Mody 
145845979c1eSRasesh Mody static void
bna_ioceth_sm_enet_attr_wait(struct bna_ioceth * ioceth,enum bna_ioceth_event event)145945979c1eSRasesh Mody bna_ioceth_sm_enet_attr_wait(struct bna_ioceth *ioceth,
146045979c1eSRasesh Mody 				enum bna_ioceth_event event)
146145979c1eSRasesh Mody {
146245979c1eSRasesh Mody 	switch (event) {
146345979c1eSRasesh Mody 	case IOCETH_E_DISABLE:
146445979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_last_resp_wait);
146545979c1eSRasesh Mody 		break;
146645979c1eSRasesh Mody 
146745979c1eSRasesh Mody 	case IOCETH_E_IOC_FAILED:
146845979c1eSRasesh Mody 		disable_mbox_intr(ioceth);
146945979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed);
147045979c1eSRasesh Mody 		break;
147145979c1eSRasesh Mody 
147245979c1eSRasesh Mody 	case IOCETH_E_ENET_ATTR_RESP:
147345979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ready);
147445979c1eSRasesh Mody 		break;
147545979c1eSRasesh Mody 
147645979c1eSRasesh Mody 	default:
147745979c1eSRasesh Mody 		bfa_sm_fault(event);
147845979c1eSRasesh Mody 	}
147945979c1eSRasesh Mody }
148045979c1eSRasesh Mody 
148145979c1eSRasesh Mody static void
bna_ioceth_sm_ready_entry(struct bna_ioceth * ioceth)148245979c1eSRasesh Mody bna_ioceth_sm_ready_entry(struct bna_ioceth *ioceth)
148345979c1eSRasesh Mody {
148445979c1eSRasesh Mody 	bna_enet_start(&ioceth->bna->enet);
148545979c1eSRasesh Mody 	bna_stats_mod_start(&ioceth->bna->stats_mod);
148645979c1eSRasesh Mody 	bnad_cb_ioceth_ready(ioceth->bna->bnad);
148745979c1eSRasesh Mody }
148845979c1eSRasesh Mody 
148945979c1eSRasesh Mody static void
bna_ioceth_sm_ready(struct bna_ioceth * ioceth,enum bna_ioceth_event event)149045979c1eSRasesh Mody bna_ioceth_sm_ready(struct bna_ioceth *ioceth, enum bna_ioceth_event event)
149145979c1eSRasesh Mody {
149245979c1eSRasesh Mody 	switch (event) {
149345979c1eSRasesh Mody 	case IOCETH_E_DISABLE:
149445979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_enet_stop_wait);
149545979c1eSRasesh Mody 		break;
149645979c1eSRasesh Mody 
149745979c1eSRasesh Mody 	case IOCETH_E_IOC_FAILED:
149845979c1eSRasesh Mody 		disable_mbox_intr(ioceth);
149945979c1eSRasesh Mody 		bna_enet_fail(&ioceth->bna->enet);
150045979c1eSRasesh Mody 		bna_stats_mod_fail(&ioceth->bna->stats_mod);
150145979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed);
150245979c1eSRasesh Mody 		break;
150345979c1eSRasesh Mody 
150445979c1eSRasesh Mody 	default:
150545979c1eSRasesh Mody 		bfa_sm_fault(event);
150645979c1eSRasesh Mody 	}
150745979c1eSRasesh Mody }
150845979c1eSRasesh Mody 
150945979c1eSRasesh Mody static void
bna_ioceth_sm_last_resp_wait_entry(struct bna_ioceth * ioceth)151045979c1eSRasesh Mody bna_ioceth_sm_last_resp_wait_entry(struct bna_ioceth *ioceth)
151145979c1eSRasesh Mody {
151245979c1eSRasesh Mody }
151345979c1eSRasesh Mody 
151445979c1eSRasesh Mody static void
bna_ioceth_sm_last_resp_wait(struct bna_ioceth * ioceth,enum bna_ioceth_event event)151545979c1eSRasesh Mody bna_ioceth_sm_last_resp_wait(struct bna_ioceth *ioceth,
151645979c1eSRasesh Mody 				enum bna_ioceth_event event)
151745979c1eSRasesh Mody {
151845979c1eSRasesh Mody 	switch (event) {
151945979c1eSRasesh Mody 	case IOCETH_E_IOC_FAILED:
152045979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
152145979c1eSRasesh Mody 		disable_mbox_intr(ioceth);
152245979c1eSRasesh Mody 		bfa_nw_ioc_disable(&ioceth->ioc);
152345979c1eSRasesh Mody 		break;
152445979c1eSRasesh Mody 
152545979c1eSRasesh Mody 	case IOCETH_E_ENET_ATTR_RESP:
152645979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
152745979c1eSRasesh Mody 		bfa_nw_ioc_disable(&ioceth->ioc);
152845979c1eSRasesh Mody 		break;
152945979c1eSRasesh Mody 
153045979c1eSRasesh Mody 	default:
153145979c1eSRasesh Mody 		bfa_sm_fault(event);
153245979c1eSRasesh Mody 	}
153345979c1eSRasesh Mody }
153445979c1eSRasesh Mody 
153545979c1eSRasesh Mody static void
bna_ioceth_sm_enet_stop_wait_entry(struct bna_ioceth * ioceth)153645979c1eSRasesh Mody bna_ioceth_sm_enet_stop_wait_entry(struct bna_ioceth *ioceth)
153745979c1eSRasesh Mody {
153845979c1eSRasesh Mody 	bna_stats_mod_stop(&ioceth->bna->stats_mod);
153945979c1eSRasesh Mody 	bna_enet_stop(&ioceth->bna->enet);
154045979c1eSRasesh Mody }
154145979c1eSRasesh Mody 
154245979c1eSRasesh Mody static void
bna_ioceth_sm_enet_stop_wait(struct bna_ioceth * ioceth,enum bna_ioceth_event event)154345979c1eSRasesh Mody bna_ioceth_sm_enet_stop_wait(struct bna_ioceth *ioceth,
154445979c1eSRasesh Mody 				enum bna_ioceth_event event)
154545979c1eSRasesh Mody {
154645979c1eSRasesh Mody 	switch (event) {
154745979c1eSRasesh Mody 	case IOCETH_E_IOC_FAILED:
154845979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
154945979c1eSRasesh Mody 		disable_mbox_intr(ioceth);
155045979c1eSRasesh Mody 		bna_enet_fail(&ioceth->bna->enet);
155145979c1eSRasesh Mody 		bna_stats_mod_fail(&ioceth->bna->stats_mod);
155245979c1eSRasesh Mody 		bfa_nw_ioc_disable(&ioceth->ioc);
155345979c1eSRasesh Mody 		break;
155445979c1eSRasesh Mody 
155545979c1eSRasesh Mody 	case IOCETH_E_ENET_STOPPED:
155645979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
155745979c1eSRasesh Mody 		bfa_nw_ioc_disable(&ioceth->ioc);
155845979c1eSRasesh Mody 		break;
155945979c1eSRasesh Mody 
156045979c1eSRasesh Mody 	default:
156145979c1eSRasesh Mody 		bfa_sm_fault(event);
156245979c1eSRasesh Mody 	}
156345979c1eSRasesh Mody }
156445979c1eSRasesh Mody 
156545979c1eSRasesh Mody static void
bna_ioceth_sm_ioc_disable_wait_entry(struct bna_ioceth * ioceth)156645979c1eSRasesh Mody bna_ioceth_sm_ioc_disable_wait_entry(struct bna_ioceth *ioceth)
156745979c1eSRasesh Mody {
156845979c1eSRasesh Mody }
156945979c1eSRasesh Mody 
157045979c1eSRasesh Mody static void
bna_ioceth_sm_ioc_disable_wait(struct bna_ioceth * ioceth,enum bna_ioceth_event event)157145979c1eSRasesh Mody bna_ioceth_sm_ioc_disable_wait(struct bna_ioceth *ioceth,
157245979c1eSRasesh Mody 				enum bna_ioceth_event event)
157345979c1eSRasesh Mody {
157445979c1eSRasesh Mody 	switch (event) {
157545979c1eSRasesh Mody 	case IOCETH_E_IOC_DISABLED:
157645979c1eSRasesh Mody 		disable_mbox_intr(ioceth);
157745979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_stopped);
157845979c1eSRasesh Mody 		break;
157945979c1eSRasesh Mody 
158045979c1eSRasesh Mody 	case IOCETH_E_ENET_STOPPED:
158145979c1eSRasesh Mody 		/* This event is received due to enet failing */
158245979c1eSRasesh Mody 		/* No-op */
158345979c1eSRasesh Mody 		break;
158445979c1eSRasesh Mody 
158545979c1eSRasesh Mody 	default:
158645979c1eSRasesh Mody 		bfa_sm_fault(event);
158745979c1eSRasesh Mody 	}
158845979c1eSRasesh Mody }
158945979c1eSRasesh Mody 
159045979c1eSRasesh Mody static void
bna_ioceth_sm_failed_entry(struct bna_ioceth * ioceth)159145979c1eSRasesh Mody bna_ioceth_sm_failed_entry(struct bna_ioceth *ioceth)
159245979c1eSRasesh Mody {
159345979c1eSRasesh Mody 	bnad_cb_ioceth_failed(ioceth->bna->bnad);
159445979c1eSRasesh Mody }
159545979c1eSRasesh Mody 
159645979c1eSRasesh Mody static void
bna_ioceth_sm_failed(struct bna_ioceth * ioceth,enum bna_ioceth_event event)159745979c1eSRasesh Mody bna_ioceth_sm_failed(struct bna_ioceth *ioceth,
159845979c1eSRasesh Mody 			enum bna_ioceth_event event)
159945979c1eSRasesh Mody {
160045979c1eSRasesh Mody 	switch (event) {
160145979c1eSRasesh Mody 	case IOCETH_E_DISABLE:
160245979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait);
160345979c1eSRasesh Mody 		bfa_nw_ioc_disable(&ioceth->ioc);
160445979c1eSRasesh Mody 		break;
160545979c1eSRasesh Mody 
160645979c1eSRasesh Mody 	case IOCETH_E_IOC_RESET:
160745979c1eSRasesh Mody 		enable_mbox_intr(ioceth);
160845979c1eSRasesh Mody 		bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_ready_wait);
160945979c1eSRasesh Mody 		break;
161045979c1eSRasesh Mody 
161145979c1eSRasesh Mody 	case IOCETH_E_IOC_FAILED:
161245979c1eSRasesh Mody 		break;
161345979c1eSRasesh Mody 
161445979c1eSRasesh Mody 	default:
161545979c1eSRasesh Mody 		bfa_sm_fault(event);
161645979c1eSRasesh Mody 	}
161745979c1eSRasesh Mody }
161845979c1eSRasesh Mody 
161945979c1eSRasesh Mody static void
bna_bfi_attr_get(struct bna_ioceth * ioceth)162045979c1eSRasesh Mody bna_bfi_attr_get(struct bna_ioceth *ioceth)
162145979c1eSRasesh Mody {
162245979c1eSRasesh Mody 	struct bfi_enet_attr_req *attr_req = &ioceth->attr_req;
162345979c1eSRasesh Mody 
162445979c1eSRasesh Mody 	bfi_msgq_mhdr_set(attr_req->mh, BFI_MC_ENET,
162545979c1eSRasesh Mody 		BFI_ENET_H2I_GET_ATTR_REQ, 0, 0);
162645979c1eSRasesh Mody 	attr_req->mh.num_entries = htons(
162745979c1eSRasesh Mody 	bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_attr_req)));
162845979c1eSRasesh Mody 	bfa_msgq_cmd_set(&ioceth->msgq_cmd, NULL, NULL,
162945979c1eSRasesh Mody 		sizeof(struct bfi_enet_attr_req), &attr_req->mh);
163045979c1eSRasesh Mody 	bfa_msgq_cmd_post(&ioceth->bna->msgq, &ioceth->msgq_cmd);
163145979c1eSRasesh Mody }
163245979c1eSRasesh Mody 
163345979c1eSRasesh Mody /* IOC callback functions */
163445979c1eSRasesh Mody 
163545979c1eSRasesh Mody static void
bna_cb_ioceth_enable(void * arg,enum bfa_status error)163645979c1eSRasesh Mody bna_cb_ioceth_enable(void *arg, enum bfa_status error)
163745979c1eSRasesh Mody {
163845979c1eSRasesh Mody 	struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
163945979c1eSRasesh Mody 
164045979c1eSRasesh Mody 	if (error)
164145979c1eSRasesh Mody 		bfa_fsm_send_event(ioceth, IOCETH_E_IOC_FAILED);
164245979c1eSRasesh Mody 	else
164345979c1eSRasesh Mody 		bfa_fsm_send_event(ioceth, IOCETH_E_IOC_READY);
164445979c1eSRasesh Mody }
164545979c1eSRasesh Mody 
164645979c1eSRasesh Mody static void
bna_cb_ioceth_disable(void * arg)164745979c1eSRasesh Mody bna_cb_ioceth_disable(void *arg)
164845979c1eSRasesh Mody {
164945979c1eSRasesh Mody 	struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
165045979c1eSRasesh Mody 
165145979c1eSRasesh Mody 	bfa_fsm_send_event(ioceth, IOCETH_E_IOC_DISABLED);
165245979c1eSRasesh Mody }
165345979c1eSRasesh Mody 
165445979c1eSRasesh Mody static void
bna_cb_ioceth_hbfail(void * arg)165545979c1eSRasesh Mody bna_cb_ioceth_hbfail(void *arg)
165645979c1eSRasesh Mody {
165745979c1eSRasesh Mody 	struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
165845979c1eSRasesh Mody 
165945979c1eSRasesh Mody 	bfa_fsm_send_event(ioceth, IOCETH_E_IOC_FAILED);
166045979c1eSRasesh Mody }
166145979c1eSRasesh Mody 
166245979c1eSRasesh Mody static void
bna_cb_ioceth_reset(void * arg)166345979c1eSRasesh Mody bna_cb_ioceth_reset(void *arg)
166445979c1eSRasesh Mody {
166545979c1eSRasesh Mody 	struct bna_ioceth *ioceth = (struct bna_ioceth *)arg;
166645979c1eSRasesh Mody 
166745979c1eSRasesh Mody 	bfa_fsm_send_event(ioceth, IOCETH_E_IOC_RESET);
166845979c1eSRasesh Mody }
166945979c1eSRasesh Mody 
167045979c1eSRasesh Mody static struct bfa_ioc_cbfn bna_ioceth_cbfn = {
16719751362aSKees Cook 	.enable_cbfn = bna_cb_ioceth_enable,
16729751362aSKees Cook 	.disable_cbfn = bna_cb_ioceth_disable,
16739751362aSKees Cook 	.hbfail_cbfn = bna_cb_ioceth_hbfail,
16749751362aSKees Cook 	.reset_cbfn = bna_cb_ioceth_reset
167545979c1eSRasesh Mody };
167645979c1eSRasesh Mody 
bna_attr_init(struct bna_ioceth * ioceth)1677761fab37SRasesh Mody static void bna_attr_init(struct bna_ioceth *ioceth)
1678761fab37SRasesh Mody {
1679761fab37SRasesh Mody 	ioceth->attr.num_txq = BFI_ENET_DEF_TXQ;
1680761fab37SRasesh Mody 	ioceth->attr.num_rxp = BFI_ENET_DEF_RXP;
1681761fab37SRasesh Mody 	ioceth->attr.num_ucmac = BFI_ENET_DEF_UCAM;
1682761fab37SRasesh Mody 	ioceth->attr.num_mcmac = BFI_ENET_MAX_MCAM;
1683761fab37SRasesh Mody 	ioceth->attr.max_rit_size = BFI_ENET_DEF_RITSZ;
1684761fab37SRasesh Mody 	ioceth->attr.fw_query_complete = false;
1685761fab37SRasesh Mody }
1686761fab37SRasesh Mody 
168745979c1eSRasesh Mody static void
bna_ioceth_init(struct bna_ioceth * ioceth,struct bna * bna,struct bna_res_info * res_info)168845979c1eSRasesh Mody bna_ioceth_init(struct bna_ioceth *ioceth, struct bna *bna,
168945979c1eSRasesh Mody 		struct bna_res_info *res_info)
169045979c1eSRasesh Mody {
169145979c1eSRasesh Mody 	u64 dma;
169245979c1eSRasesh Mody 	u8 *kva;
169345979c1eSRasesh Mody 
169445979c1eSRasesh Mody 	ioceth->bna = bna;
169545979c1eSRasesh Mody 
169645979c1eSRasesh Mody 	/**
169745979c1eSRasesh Mody 	 * Attach IOC and claim:
169845979c1eSRasesh Mody 	 *	1. DMA memory for IOC attributes
169945979c1eSRasesh Mody 	 *	2. Kernel memory for FW trace
170045979c1eSRasesh Mody 	 */
170145979c1eSRasesh Mody 	bfa_nw_ioc_attach(&ioceth->ioc, ioceth, &bna_ioceth_cbfn);
170245979c1eSRasesh Mody 	bfa_nw_ioc_pci_init(&ioceth->ioc, &bna->pcidev, BFI_PCIFN_CLASS_ETH);
170345979c1eSRasesh Mody 
170445979c1eSRasesh Mody 	BNA_GET_DMA_ADDR(
170545979c1eSRasesh Mody 		&res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].dma, dma);
170645979c1eSRasesh Mody 	kva = res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].kva;
170745979c1eSRasesh Mody 	bfa_nw_ioc_mem_claim(&ioceth->ioc, kva, dma);
170845979c1eSRasesh Mody 
170945979c1eSRasesh Mody 	kva = res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mdl[0].kva;
17107afc5dbdSKrishna Gudipati 	bfa_nw_ioc_debug_memclaim(&ioceth->ioc, kva);
171145979c1eSRasesh Mody 
171245979c1eSRasesh Mody 	/**
171345979c1eSRasesh Mody 	 * Attach common modules (Diag, SFP, CEE, Port) and claim respective
171445979c1eSRasesh Mody 	 * DMA memory.
171545979c1eSRasesh Mody 	 */
171645979c1eSRasesh Mody 	BNA_GET_DMA_ADDR(
171745979c1eSRasesh Mody 		&res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].dma, dma);
171845979c1eSRasesh Mody 	kva = res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].kva;
171945979c1eSRasesh Mody 	bfa_nw_cee_attach(&bna->cee, &ioceth->ioc, bna);
172045979c1eSRasesh Mody 	bfa_nw_cee_mem_claim(&bna->cee, kva, dma);
172145979c1eSRasesh Mody 	kva += bfa_nw_cee_meminfo();
172245979c1eSRasesh Mody 	dma += bfa_nw_cee_meminfo();
172345979c1eSRasesh Mody 
172472a9730bSKrishna Gudipati 	bfa_nw_flash_attach(&bna->flash, &ioceth->ioc, bna);
172572a9730bSKrishna Gudipati 	bfa_nw_flash_memclaim(&bna->flash, kva, dma);
172672a9730bSKrishna Gudipati 	kva += bfa_nw_flash_meminfo();
172772a9730bSKrishna Gudipati 	dma += bfa_nw_flash_meminfo();
172872a9730bSKrishna Gudipati 
172945979c1eSRasesh Mody 	bfa_msgq_attach(&bna->msgq, &ioceth->ioc);
173045979c1eSRasesh Mody 	bfa_msgq_memclaim(&bna->msgq, kva, dma);
173145979c1eSRasesh Mody 	bfa_msgq_regisr(&bna->msgq, BFI_MC_ENET, bna_msgq_rsp_handler, bna);
173245979c1eSRasesh Mody 	kva += bfa_msgq_meminfo();
173345979c1eSRasesh Mody 	dma += bfa_msgq_meminfo();
173445979c1eSRasesh Mody 
173545979c1eSRasesh Mody 	ioceth->stop_cbfn = NULL;
173645979c1eSRasesh Mody 	ioceth->stop_cbarg = NULL;
173745979c1eSRasesh Mody 
1738761fab37SRasesh Mody 	bna_attr_init(ioceth);
1739761fab37SRasesh Mody 
174045979c1eSRasesh Mody 	bfa_fsm_set_state(ioceth, bna_ioceth_sm_stopped);
174145979c1eSRasesh Mody }
174245979c1eSRasesh Mody 
174345979c1eSRasesh Mody static void
bna_ioceth_uninit(struct bna_ioceth * ioceth)174445979c1eSRasesh Mody bna_ioceth_uninit(struct bna_ioceth *ioceth)
174545979c1eSRasesh Mody {
174645979c1eSRasesh Mody 	bfa_nw_ioc_detach(&ioceth->ioc);
174745979c1eSRasesh Mody 
174845979c1eSRasesh Mody 	ioceth->bna = NULL;
174945979c1eSRasesh Mody }
175045979c1eSRasesh Mody 
175145979c1eSRasesh Mody void
bna_ioceth_enable(struct bna_ioceth * ioceth)175245979c1eSRasesh Mody bna_ioceth_enable(struct bna_ioceth *ioceth)
175345979c1eSRasesh Mody {
1754*8719a1c3SGustavo A. R. Silva 	if (ioceth->fsm == bna_ioceth_sm_ready) {
175545979c1eSRasesh Mody 		bnad_cb_ioceth_ready(ioceth->bna->bnad);
175645979c1eSRasesh Mody 		return;
175745979c1eSRasesh Mody 	}
175845979c1eSRasesh Mody 
1759*8719a1c3SGustavo A. R. Silva 	if (ioceth->fsm == bna_ioceth_sm_stopped)
176045979c1eSRasesh Mody 		bfa_fsm_send_event(ioceth, IOCETH_E_ENABLE);
176145979c1eSRasesh Mody }
176245979c1eSRasesh Mody 
176345979c1eSRasesh Mody void
bna_ioceth_disable(struct bna_ioceth * ioceth,enum bna_cleanup_type type)176445979c1eSRasesh Mody bna_ioceth_disable(struct bna_ioceth *ioceth, enum bna_cleanup_type type)
176545979c1eSRasesh Mody {
176645979c1eSRasesh Mody 	if (type == BNA_SOFT_CLEANUP) {
176745979c1eSRasesh Mody 		bnad_cb_ioceth_disabled(ioceth->bna->bnad);
176845979c1eSRasesh Mody 		return;
176945979c1eSRasesh Mody 	}
177045979c1eSRasesh Mody 
177145979c1eSRasesh Mody 	ioceth->stop_cbfn = bnad_cb_ioceth_disabled;
177245979c1eSRasesh Mody 	ioceth->stop_cbarg = ioceth->bna->bnad;
177345979c1eSRasesh Mody 
177445979c1eSRasesh Mody 	bfa_fsm_send_event(ioceth, IOCETH_E_DISABLE);
177545979c1eSRasesh Mody }
177645979c1eSRasesh Mody 
177745979c1eSRasesh Mody static void
bna_ucam_mod_init(struct bna_ucam_mod * ucam_mod,struct bna * bna,struct bna_res_info * res_info)177845979c1eSRasesh Mody bna_ucam_mod_init(struct bna_ucam_mod *ucam_mod, struct bna *bna,
177945979c1eSRasesh Mody 		  struct bna_res_info *res_info)
178045979c1eSRasesh Mody {
178145979c1eSRasesh Mody 	int i;
178245979c1eSRasesh Mody 
178345979c1eSRasesh Mody 	ucam_mod->ucmac = (struct bna_mac *)
178445979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mdl[0].kva;
178545979c1eSRasesh Mody 
178645979c1eSRasesh Mody 	INIT_LIST_HEAD(&ucam_mod->free_q);
17872b26fb95SIvan Vecera 	for (i = 0; i < bna->ioceth.attr.num_ucmac; i++)
178845979c1eSRasesh Mody 		list_add_tail(&ucam_mod->ucmac[i].qe, &ucam_mod->free_q);
178945979c1eSRasesh Mody 
179020b298f5SRasesh Mody 	/* A separate queue to allow synchronous setting of a list of MACs */
179120b298f5SRasesh Mody 	INIT_LIST_HEAD(&ucam_mod->del_q);
179283b4768eSNathan Chancellor 	for (; i < (bna->ioceth.attr.num_ucmac * 2); i++)
179320b298f5SRasesh Mody 		list_add_tail(&ucam_mod->ucmac[i].qe, &ucam_mod->del_q);
179420b298f5SRasesh Mody 
179545979c1eSRasesh Mody 	ucam_mod->bna = bna;
179645979c1eSRasesh Mody }
179745979c1eSRasesh Mody 
179845979c1eSRasesh Mody static void
bna_ucam_mod_uninit(struct bna_ucam_mod * ucam_mod)179945979c1eSRasesh Mody bna_ucam_mod_uninit(struct bna_ucam_mod *ucam_mod)
180045979c1eSRasesh Mody {
180145979c1eSRasesh Mody 	ucam_mod->bna = NULL;
180245979c1eSRasesh Mody }
180345979c1eSRasesh Mody 
180445979c1eSRasesh Mody static void
bna_mcam_mod_init(struct bna_mcam_mod * mcam_mod,struct bna * bna,struct bna_res_info * res_info)180545979c1eSRasesh Mody bna_mcam_mod_init(struct bna_mcam_mod *mcam_mod, struct bna *bna,
180645979c1eSRasesh Mody 		  struct bna_res_info *res_info)
180745979c1eSRasesh Mody {
180845979c1eSRasesh Mody 	int i;
180945979c1eSRasesh Mody 
181045979c1eSRasesh Mody 	mcam_mod->mcmac = (struct bna_mac *)
181145979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mdl[0].kva;
181245979c1eSRasesh Mody 
181345979c1eSRasesh Mody 	INIT_LIST_HEAD(&mcam_mod->free_q);
18142b26fb95SIvan Vecera 	for (i = 0; i < bna->ioceth.attr.num_mcmac; i++)
181545979c1eSRasesh Mody 		list_add_tail(&mcam_mod->mcmac[i].qe, &mcam_mod->free_q);
181645979c1eSRasesh Mody 
181745979c1eSRasesh Mody 	mcam_mod->mchandle = (struct bna_mcam_handle *)
181845979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.mdl[0].kva;
181945979c1eSRasesh Mody 
182045979c1eSRasesh Mody 	INIT_LIST_HEAD(&mcam_mod->free_handle_q);
18212b26fb95SIvan Vecera 	for (i = 0; i < bna->ioceth.attr.num_mcmac; i++)
182245979c1eSRasesh Mody 		list_add_tail(&mcam_mod->mchandle[i].qe,
182345979c1eSRasesh Mody 			      &mcam_mod->free_handle_q);
182445979c1eSRasesh Mody 
182520b298f5SRasesh Mody 	/* A separate queue to allow synchronous setting of a list of MACs */
182620b298f5SRasesh Mody 	INIT_LIST_HEAD(&mcam_mod->del_q);
182783b4768eSNathan Chancellor 	for (; i < (bna->ioceth.attr.num_mcmac * 2); i++)
182820b298f5SRasesh Mody 		list_add_tail(&mcam_mod->mcmac[i].qe, &mcam_mod->del_q);
182920b298f5SRasesh Mody 
183045979c1eSRasesh Mody 	mcam_mod->bna = bna;
183145979c1eSRasesh Mody }
183245979c1eSRasesh Mody 
183345979c1eSRasesh Mody static void
bna_mcam_mod_uninit(struct bna_mcam_mod * mcam_mod)183445979c1eSRasesh Mody bna_mcam_mod_uninit(struct bna_mcam_mod *mcam_mod)
183545979c1eSRasesh Mody {
183645979c1eSRasesh Mody 	mcam_mod->bna = NULL;
183745979c1eSRasesh Mody }
183845979c1eSRasesh Mody 
183945979c1eSRasesh Mody static void
bna_bfi_stats_get(struct bna * bna)184045979c1eSRasesh Mody bna_bfi_stats_get(struct bna *bna)
184145979c1eSRasesh Mody {
184245979c1eSRasesh Mody 	struct bfi_enet_stats_req *stats_req = &bna->stats_mod.stats_get;
184345979c1eSRasesh Mody 
184445979c1eSRasesh Mody 	bna->stats_mod.stats_get_busy = true;
184545979c1eSRasesh Mody 
184645979c1eSRasesh Mody 	bfi_msgq_mhdr_set(stats_req->mh, BFI_MC_ENET,
184745979c1eSRasesh Mody 		BFI_ENET_H2I_STATS_GET_REQ, 0, 0);
184845979c1eSRasesh Mody 	stats_req->mh.num_entries = htons(
184945979c1eSRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_stats_req)));
185045979c1eSRasesh Mody 	stats_req->stats_mask = htons(BFI_ENET_STATS_ALL);
185145979c1eSRasesh Mody 	stats_req->tx_enet_mask = htonl(bna->tx_mod.rid_mask);
185245979c1eSRasesh Mody 	stats_req->rx_enet_mask = htonl(bna->rx_mod.rid_mask);
185345979c1eSRasesh Mody 	stats_req->host_buffer.a32.addr_hi = bna->stats.hw_stats_dma.msb;
185445979c1eSRasesh Mody 	stats_req->host_buffer.a32.addr_lo = bna->stats.hw_stats_dma.lsb;
185545979c1eSRasesh Mody 
185645979c1eSRasesh Mody 	bfa_msgq_cmd_set(&bna->stats_mod.stats_get_cmd, NULL, NULL,
185745979c1eSRasesh Mody 		sizeof(struct bfi_enet_stats_req), &stats_req->mh);
185845979c1eSRasesh Mody 	bfa_msgq_cmd_post(&bna->msgq, &bna->stats_mod.stats_get_cmd);
185945979c1eSRasesh Mody }
186045979c1eSRasesh Mody 
186145979c1eSRasesh Mody void
bna_res_req(struct bna_res_info * res_info)186245979c1eSRasesh Mody bna_res_req(struct bna_res_info *res_info)
186345979c1eSRasesh Mody {
186445979c1eSRasesh Mody 	/* DMA memory for COMMON_MODULE */
186545979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_COM].res_type = BNA_RES_T_MEM;
186645979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
186745979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_COM].res_u.mem_info.num = 1;
186845979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_COM].res_u.mem_info.len = ALIGN(
186945979c1eSRasesh Mody 				(bfa_nw_cee_meminfo() +
187072a9730bSKrishna Gudipati 				 bfa_nw_flash_meminfo() +
187145979c1eSRasesh Mody 				 bfa_msgq_meminfo()), PAGE_SIZE);
187245979c1eSRasesh Mody 
187345979c1eSRasesh Mody 	/* DMA memory for retrieving IOC attributes */
187445979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_ATTR].res_type = BNA_RES_T_MEM;
187545979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
187645979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.num = 1;
187745979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.len =
187845979c1eSRasesh Mody 				ALIGN(bfa_nw_ioc_meminfo(), PAGE_SIZE);
187945979c1eSRasesh Mody 
188045979c1eSRasesh Mody 	/* Virtual memory for retreiving fw_trc */
188145979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_FWTRC].res_type = BNA_RES_T_MEM;
188245979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mem_type = BNA_MEM_T_KVA;
18837afc5dbdSKrishna Gudipati 	res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.num = 1;
18847afc5dbdSKrishna Gudipati 	res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.len = BNA_DBG_FWTRC_LEN;
188545979c1eSRasesh Mody 
188645979c1eSRasesh Mody 	/* DMA memory for retreiving stats */
188745979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_STATS].res_type = BNA_RES_T_MEM;
188845979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mem_type = BNA_MEM_T_DMA;
188945979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.num = 1;
189045979c1eSRasesh Mody 	res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.len =
189145979c1eSRasesh Mody 				ALIGN(sizeof(struct bfi_enet_stats),
189245979c1eSRasesh Mody 					PAGE_SIZE);
189345979c1eSRasesh Mody }
189445979c1eSRasesh Mody 
189545979c1eSRasesh Mody void
bna_mod_res_req(struct bna * bna,struct bna_res_info * res_info)189645979c1eSRasesh Mody bna_mod_res_req(struct bna *bna, struct bna_res_info *res_info)
189745979c1eSRasesh Mody {
189845979c1eSRasesh Mody 	struct bna_attr *attr = &bna->ioceth.attr;
189945979c1eSRasesh Mody 
190045979c1eSRasesh Mody 	/* Virtual memory for Tx objects - stored by Tx module */
190145979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_type = BNA_RES_T_MEM;
190245979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.mem_type =
190345979c1eSRasesh Mody 		BNA_MEM_T_KVA;
190445979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.num = 1;
190545979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.len =
190645979c1eSRasesh Mody 		attr->num_txq * sizeof(struct bna_tx);
190745979c1eSRasesh Mody 
190845979c1eSRasesh Mody 	/* Virtual memory for TxQ - stored by Tx module */
190945979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_type = BNA_RES_T_MEM;
191045979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mem_type =
191145979c1eSRasesh Mody 		BNA_MEM_T_KVA;
191245979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.num = 1;
191345979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.len =
191445979c1eSRasesh Mody 		attr->num_txq * sizeof(struct bna_txq);
191545979c1eSRasesh Mody 
191645979c1eSRasesh Mody 	/* Virtual memory for Rx objects - stored by Rx module */
191745979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_type = BNA_RES_T_MEM;
191845979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.mem_type =
191945979c1eSRasesh Mody 		BNA_MEM_T_KVA;
192045979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.num = 1;
192145979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.len =
192245979c1eSRasesh Mody 		attr->num_rxp * sizeof(struct bna_rx);
192345979c1eSRasesh Mody 
192445979c1eSRasesh Mody 	/* Virtual memory for RxPath - stored by Rx module */
192545979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_type = BNA_RES_T_MEM;
192645979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mem_type =
192745979c1eSRasesh Mody 		BNA_MEM_T_KVA;
192845979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.num = 1;
192945979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.len =
193045979c1eSRasesh Mody 		attr->num_rxp * sizeof(struct bna_rxp);
193145979c1eSRasesh Mody 
193245979c1eSRasesh Mody 	/* Virtual memory for RxQ - stored by Rx module */
193345979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_type = BNA_RES_T_MEM;
193445979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mem_type =
193545979c1eSRasesh Mody 		BNA_MEM_T_KVA;
193645979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.num = 1;
193745979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.len =
193845979c1eSRasesh Mody 		(attr->num_rxp * 2) * sizeof(struct bna_rxq);
193945979c1eSRasesh Mody 
194045979c1eSRasesh Mody 	/* Virtual memory for Unicast MAC address - stored by ucam module */
194145979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_type = BNA_RES_T_MEM;
194245979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mem_type =
194345979c1eSRasesh Mody 		BNA_MEM_T_KVA;
194445979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.num = 1;
194545979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.len =
194620b298f5SRasesh Mody 		(attr->num_ucmac * 2) * sizeof(struct bna_mac);
194745979c1eSRasesh Mody 
194845979c1eSRasesh Mody 	/* Virtual memory for Multicast MAC address - stored by mcam module */
194945979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_type = BNA_RES_T_MEM;
195045979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mem_type =
195145979c1eSRasesh Mody 		BNA_MEM_T_KVA;
195245979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.num = 1;
195345979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.len =
195420b298f5SRasesh Mody 		(attr->num_mcmac * 2) * sizeof(struct bna_mac);
195545979c1eSRasesh Mody 
195645979c1eSRasesh Mody 	/* Virtual memory for Multicast handle - stored by mcam module */
195745979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_type = BNA_RES_T_MEM;
195845979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.mem_type =
195945979c1eSRasesh Mody 		BNA_MEM_T_KVA;
196045979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.num = 1;
196145979c1eSRasesh Mody 	res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.len =
196245979c1eSRasesh Mody 		attr->num_mcmac * sizeof(struct bna_mcam_handle);
196345979c1eSRasesh Mody }
196445979c1eSRasesh Mody 
196545979c1eSRasesh Mody void
bna_init(struct bna * bna,struct bnad * bnad,struct bfa_pcidev * pcidev,struct bna_res_info * res_info)196645979c1eSRasesh Mody bna_init(struct bna *bna, struct bnad *bnad,
196745979c1eSRasesh Mody 		struct bfa_pcidev *pcidev, struct bna_res_info *res_info)
196845979c1eSRasesh Mody {
196945979c1eSRasesh Mody 	bna->bnad = bnad;
197045979c1eSRasesh Mody 	bna->pcidev = *pcidev;
197145979c1eSRasesh Mody 
197245979c1eSRasesh Mody 	bna->stats.hw_stats_kva = (struct bfi_enet_stats *)
197345979c1eSRasesh Mody 		res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].kva;
197445979c1eSRasesh Mody 	bna->stats.hw_stats_dma.msb =
197545979c1eSRasesh Mody 		res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.msb;
197645979c1eSRasesh Mody 	bna->stats.hw_stats_dma.lsb =
197745979c1eSRasesh Mody 		res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.lsb;
197845979c1eSRasesh Mody 
197945979c1eSRasesh Mody 	bna_reg_addr_init(bna, &bna->pcidev);
198045979c1eSRasesh Mody 
198145979c1eSRasesh Mody 	/* Also initializes diag, cee, sfp, phy_port, msgq */
198245979c1eSRasesh Mody 	bna_ioceth_init(&bna->ioceth, bna, res_info);
198345979c1eSRasesh Mody 
198445979c1eSRasesh Mody 	bna_enet_init(&bna->enet, bna);
198545979c1eSRasesh Mody 	bna_ethport_init(&bna->ethport, bna);
198645979c1eSRasesh Mody }
198745979c1eSRasesh Mody 
198845979c1eSRasesh Mody void
bna_mod_init(struct bna * bna,struct bna_res_info * res_info)198945979c1eSRasesh Mody bna_mod_init(struct bna *bna, struct bna_res_info *res_info)
199045979c1eSRasesh Mody {
199145979c1eSRasesh Mody 	bna_tx_mod_init(&bna->tx_mod, bna, res_info);
199245979c1eSRasesh Mody 
199345979c1eSRasesh Mody 	bna_rx_mod_init(&bna->rx_mod, bna, res_info);
199445979c1eSRasesh Mody 
199545979c1eSRasesh Mody 	bna_ucam_mod_init(&bna->ucam_mod, bna, res_info);
199645979c1eSRasesh Mody 
199745979c1eSRasesh Mody 	bna_mcam_mod_init(&bna->mcam_mod, bna, res_info);
199845979c1eSRasesh Mody 
199945979c1eSRasesh Mody 	bna->default_mode_rid = BFI_INVALID_RID;
200045979c1eSRasesh Mody 	bna->promisc_rid = BFI_INVALID_RID;
200145979c1eSRasesh Mody 
200245979c1eSRasesh Mody 	bna->mod_flags |= BNA_MOD_F_INIT_DONE;
200345979c1eSRasesh Mody }
200445979c1eSRasesh Mody 
200545979c1eSRasesh Mody void
bna_uninit(struct bna * bna)200645979c1eSRasesh Mody bna_uninit(struct bna *bna)
200745979c1eSRasesh Mody {
200845979c1eSRasesh Mody 	if (bna->mod_flags & BNA_MOD_F_INIT_DONE) {
200945979c1eSRasesh Mody 		bna_mcam_mod_uninit(&bna->mcam_mod);
201045979c1eSRasesh Mody 		bna_ucam_mod_uninit(&bna->ucam_mod);
201145979c1eSRasesh Mody 		bna_rx_mod_uninit(&bna->rx_mod);
201245979c1eSRasesh Mody 		bna_tx_mod_uninit(&bna->tx_mod);
201345979c1eSRasesh Mody 		bna->mod_flags &= ~BNA_MOD_F_INIT_DONE;
201445979c1eSRasesh Mody 	}
201545979c1eSRasesh Mody 
201645979c1eSRasesh Mody 	bna_stats_mod_uninit(&bna->stats_mod);
201745979c1eSRasesh Mody 	bna_ethport_uninit(&bna->ethport);
201845979c1eSRasesh Mody 	bna_enet_uninit(&bna->enet);
201945979c1eSRasesh Mody 
202045979c1eSRasesh Mody 	bna_ioceth_uninit(&bna->ioceth);
202145979c1eSRasesh Mody 
202245979c1eSRasesh Mody 	bna->bnad = NULL;
202345979c1eSRasesh Mody }
202445979c1eSRasesh Mody 
202545979c1eSRasesh Mody int
bna_num_txq_set(struct bna * bna,int num_txq)202645979c1eSRasesh Mody bna_num_txq_set(struct bna *bna, int num_txq)
202745979c1eSRasesh Mody {
2028761fab37SRasesh Mody 	if (bna->ioceth.attr.fw_query_complete &&
2029761fab37SRasesh Mody 		(num_txq <= bna->ioceth.attr.num_txq)) {
203045979c1eSRasesh Mody 		bna->ioceth.attr.num_txq = num_txq;
203145979c1eSRasesh Mody 		return BNA_CB_SUCCESS;
203245979c1eSRasesh Mody 	}
203345979c1eSRasesh Mody 
203445979c1eSRasesh Mody 	return BNA_CB_FAIL;
203545979c1eSRasesh Mody }
203645979c1eSRasesh Mody 
203745979c1eSRasesh Mody int
bna_num_rxp_set(struct bna * bna,int num_rxp)203845979c1eSRasesh Mody bna_num_rxp_set(struct bna *bna, int num_rxp)
203945979c1eSRasesh Mody {
2040761fab37SRasesh Mody 	if (bna->ioceth.attr.fw_query_complete &&
2041761fab37SRasesh Mody 		(num_rxp <= bna->ioceth.attr.num_rxp)) {
204245979c1eSRasesh Mody 		bna->ioceth.attr.num_rxp = num_rxp;
204345979c1eSRasesh Mody 		return BNA_CB_SUCCESS;
204445979c1eSRasesh Mody 	}
204545979c1eSRasesh Mody 
204645979c1eSRasesh Mody 	return BNA_CB_FAIL;
204745979c1eSRasesh Mody }
204845979c1eSRasesh Mody 
204945979c1eSRasesh Mody struct bna_mac *
bna_cam_mod_mac_get(struct list_head * head)205020b298f5SRasesh Mody bna_cam_mod_mac_get(struct list_head *head)
205145979c1eSRasesh Mody {
20522b26fb95SIvan Vecera 	struct bna_mac *mac;
205345979c1eSRasesh Mody 
20542b26fb95SIvan Vecera 	mac = list_first_entry_or_null(head, struct bna_mac, qe);
20552b26fb95SIvan Vecera 	if (mac)
20562b26fb95SIvan Vecera 		list_del(&mac->qe);
205745979c1eSRasesh Mody 
20582b26fb95SIvan Vecera 	return mac;
205945979c1eSRasesh Mody }
206045979c1eSRasesh Mody 
206145979c1eSRasesh Mody struct bna_mcam_handle *
bna_mcam_mod_handle_get(struct bna_mcam_mod * mcam_mod)206245979c1eSRasesh Mody bna_mcam_mod_handle_get(struct bna_mcam_mod *mcam_mod)
206345979c1eSRasesh Mody {
20642b26fb95SIvan Vecera 	struct bna_mcam_handle *handle;
206545979c1eSRasesh Mody 
20662b26fb95SIvan Vecera 	handle = list_first_entry_or_null(&mcam_mod->free_handle_q,
20672b26fb95SIvan Vecera 					  struct bna_mcam_handle, qe);
20682b26fb95SIvan Vecera 	if (handle)
20692b26fb95SIvan Vecera 		list_del(&handle->qe);
207045979c1eSRasesh Mody 
20712b26fb95SIvan Vecera 	return handle;
207245979c1eSRasesh Mody }
207345979c1eSRasesh Mody 
207445979c1eSRasesh Mody void
bna_mcam_mod_handle_put(struct bna_mcam_mod * mcam_mod,struct bna_mcam_handle * handle)207545979c1eSRasesh Mody bna_mcam_mod_handle_put(struct bna_mcam_mod *mcam_mod,
207645979c1eSRasesh Mody 			struct bna_mcam_handle *handle)
207745979c1eSRasesh Mody {
207845979c1eSRasesh Mody 	list_add_tail(&handle->qe, &mcam_mod->free_handle_q);
207945979c1eSRasesh Mody }
208045979c1eSRasesh Mody 
208145979c1eSRasesh Mody void
bna_hw_stats_get(struct bna * bna)208245979c1eSRasesh Mody bna_hw_stats_get(struct bna *bna)
208345979c1eSRasesh Mody {
208445979c1eSRasesh Mody 	if (!bna->stats_mod.ioc_ready) {
208545979c1eSRasesh Mody 		bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats);
208645979c1eSRasesh Mody 		return;
208745979c1eSRasesh Mody 	}
208845979c1eSRasesh Mody 	if (bna->stats_mod.stats_get_busy) {
208945979c1eSRasesh Mody 		bnad_cb_stats_get(bna->bnad, BNA_CB_BUSY, &bna->stats);
209045979c1eSRasesh Mody 		return;
209145979c1eSRasesh Mody 	}
209245979c1eSRasesh Mody 
209345979c1eSRasesh Mody 	bna_bfi_stats_get(bna);
209445979c1eSRasesh Mody }
2095