xref: /linux/drivers/net/ethernet/brocade/bna/bna_tx_rx.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
152fa7bf9SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2f3bd5173SRasesh Mody /*
32732ba56SRasesh Mody  * Linux network driver for QLogic BR-series Converged Network Adapter.
4f3bd5173SRasesh Mody   */
5f3bd5173SRasesh Mody /*
62732ba56SRasesh Mody  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
72732ba56SRasesh Mody  * Copyright (c) 2014-2015 QLogic Corporation
8f3bd5173SRasesh Mody  * All rights reserved
92732ba56SRasesh Mody  * www.qlogic.com
10f3bd5173SRasesh Mody  */
11f3bd5173SRasesh Mody #include "bna.h"
12f3bd5173SRasesh Mody #include "bfi.h"
13f3bd5173SRasesh Mody 
141aa8b471SBen Hutchings /* IB */
15f3bd5173SRasesh Mody static void
bna_ib_coalescing_timeo_set(struct bna_ib * ib,u8 coalescing_timeo)16f3bd5173SRasesh Mody bna_ib_coalescing_timeo_set(struct bna_ib *ib, u8 coalescing_timeo)
17f3bd5173SRasesh Mody {
18f3bd5173SRasesh Mody 	ib->coalescing_timeo = coalescing_timeo;
19f3bd5173SRasesh Mody 	ib->door_bell.doorbell_ack = BNA_DOORBELL_IB_INT_ACK(
20f3bd5173SRasesh Mody 				(u32)ib->coalescing_timeo, 0);
21f3bd5173SRasesh Mody }
22f3bd5173SRasesh Mody 
231aa8b471SBen Hutchings /* RXF */
24f3bd5173SRasesh Mody 
25f3bd5173SRasesh Mody #define bna_rxf_vlan_cfg_soft_reset(rxf)				\
26f3bd5173SRasesh Mody do {									\
27f3bd5173SRasesh Mody 	(rxf)->vlan_pending_bitmask = (u8)BFI_VLAN_BMASK_ALL;		\
28f3bd5173SRasesh Mody 	(rxf)->vlan_strip_pending = true;				\
29f3bd5173SRasesh Mody } while (0)
30f3bd5173SRasesh Mody 
31f3bd5173SRasesh Mody #define bna_rxf_rss_cfg_soft_reset(rxf)					\
32f3bd5173SRasesh Mody do {									\
33f3bd5173SRasesh Mody 	if ((rxf)->rss_status == BNA_STATUS_T_ENABLED)			\
34f3bd5173SRasesh Mody 		(rxf)->rss_pending = (BNA_RSS_F_RIT_PENDING |		\
35f3bd5173SRasesh Mody 				BNA_RSS_F_CFG_PENDING |			\
36f3bd5173SRasesh Mody 				BNA_RSS_F_STATUS_PENDING);		\
37f3bd5173SRasesh Mody } while (0)
38f3bd5173SRasesh Mody 
39f3bd5173SRasesh Mody static int bna_rxf_cfg_apply(struct bna_rxf *rxf);
40f3bd5173SRasesh Mody static void bna_rxf_cfg_reset(struct bna_rxf *rxf);
41f3bd5173SRasesh Mody static int bna_rxf_ucast_cfg_apply(struct bna_rxf *rxf);
42f3bd5173SRasesh Mody static int bna_rxf_promisc_cfg_apply(struct bna_rxf *rxf);
43f3bd5173SRasesh Mody static int bna_rxf_allmulti_cfg_apply(struct bna_rxf *rxf);
44f3bd5173SRasesh Mody static int bna_rxf_vlan_strip_cfg_apply(struct bna_rxf *rxf);
45f3bd5173SRasesh Mody static int bna_rxf_ucast_cfg_reset(struct bna_rxf *rxf,
46f3bd5173SRasesh Mody 					enum bna_cleanup_type cleanup);
47f3bd5173SRasesh Mody static int bna_rxf_promisc_cfg_reset(struct bna_rxf *rxf,
48f3bd5173SRasesh Mody 					enum bna_cleanup_type cleanup);
49f3bd5173SRasesh Mody static int bna_rxf_allmulti_cfg_reset(struct bna_rxf *rxf,
50f3bd5173SRasesh Mody 					enum bna_cleanup_type cleanup);
51f3bd5173SRasesh Mody 
52f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_rxf, stopped, struct bna_rxf,
53f3bd5173SRasesh Mody 			enum bna_rxf_event);
54f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_rxf, cfg_wait, struct bna_rxf,
55f3bd5173SRasesh Mody 			enum bna_rxf_event);
56f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_rxf, started, struct bna_rxf,
57f3bd5173SRasesh Mody 			enum bna_rxf_event);
58f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_rxf, last_resp_wait, struct bna_rxf,
59f3bd5173SRasesh Mody 			enum bna_rxf_event);
60f3bd5173SRasesh Mody 
61f3bd5173SRasesh Mody static void
bna_rxf_sm_stopped_entry(struct bna_rxf * rxf)62f3bd5173SRasesh Mody bna_rxf_sm_stopped_entry(struct bna_rxf *rxf)
63f3bd5173SRasesh Mody {
64f3bd5173SRasesh Mody 	call_rxf_stop_cbfn(rxf);
65f3bd5173SRasesh Mody }
66f3bd5173SRasesh Mody 
67f3bd5173SRasesh Mody static void
bna_rxf_sm_stopped(struct bna_rxf * rxf,enum bna_rxf_event event)68f3bd5173SRasesh Mody bna_rxf_sm_stopped(struct bna_rxf *rxf, enum bna_rxf_event event)
69f3bd5173SRasesh Mody {
70f3bd5173SRasesh Mody 	switch (event) {
71f3bd5173SRasesh Mody 	case RXF_E_START:
72f3bd5173SRasesh Mody 		bfa_fsm_set_state(rxf, bna_rxf_sm_cfg_wait);
73f3bd5173SRasesh Mody 		break;
74f3bd5173SRasesh Mody 
75f3bd5173SRasesh Mody 	case RXF_E_STOP:
76f3bd5173SRasesh Mody 		call_rxf_stop_cbfn(rxf);
77f3bd5173SRasesh Mody 		break;
78f3bd5173SRasesh Mody 
79f3bd5173SRasesh Mody 	case RXF_E_FAIL:
80f3bd5173SRasesh Mody 		/* No-op */
81f3bd5173SRasesh Mody 		break;
82f3bd5173SRasesh Mody 
83f3bd5173SRasesh Mody 	case RXF_E_CONFIG:
84f3bd5173SRasesh Mody 		call_rxf_cam_fltr_cbfn(rxf);
85f3bd5173SRasesh Mody 		break;
86f3bd5173SRasesh Mody 
87f3bd5173SRasesh Mody 	default:
88f3bd5173SRasesh Mody 		bfa_sm_fault(event);
89f3bd5173SRasesh Mody 	}
90f3bd5173SRasesh Mody }
91f3bd5173SRasesh Mody 
92f3bd5173SRasesh Mody static void
bna_rxf_sm_cfg_wait_entry(struct bna_rxf * rxf)93f3bd5173SRasesh Mody bna_rxf_sm_cfg_wait_entry(struct bna_rxf *rxf)
94f3bd5173SRasesh Mody {
95f3bd5173SRasesh Mody 	if (!bna_rxf_cfg_apply(rxf)) {
96f3bd5173SRasesh Mody 		/* No more pending config updates */
97f3bd5173SRasesh Mody 		bfa_fsm_set_state(rxf, bna_rxf_sm_started);
98f3bd5173SRasesh Mody 	}
99f3bd5173SRasesh Mody }
100f3bd5173SRasesh Mody 
101f3bd5173SRasesh Mody static void
bna_rxf_sm_cfg_wait(struct bna_rxf * rxf,enum bna_rxf_event event)102f3bd5173SRasesh Mody bna_rxf_sm_cfg_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
103f3bd5173SRasesh Mody {
104f3bd5173SRasesh Mody 	switch (event) {
105f3bd5173SRasesh Mody 	case RXF_E_STOP:
106f3bd5173SRasesh Mody 		bfa_fsm_set_state(rxf, bna_rxf_sm_last_resp_wait);
107f3bd5173SRasesh Mody 		break;
108f3bd5173SRasesh Mody 
109f3bd5173SRasesh Mody 	case RXF_E_FAIL:
110f3bd5173SRasesh Mody 		bna_rxf_cfg_reset(rxf);
111f3bd5173SRasesh Mody 		call_rxf_start_cbfn(rxf);
112f3bd5173SRasesh Mody 		call_rxf_cam_fltr_cbfn(rxf);
113f3bd5173SRasesh Mody 		bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
114f3bd5173SRasesh Mody 		break;
115f3bd5173SRasesh Mody 
116f3bd5173SRasesh Mody 	case RXF_E_CONFIG:
117f3bd5173SRasesh Mody 		/* No-op */
118f3bd5173SRasesh Mody 		break;
119f3bd5173SRasesh Mody 
120f3bd5173SRasesh Mody 	case RXF_E_FW_RESP:
121f3bd5173SRasesh Mody 		if (!bna_rxf_cfg_apply(rxf)) {
122f3bd5173SRasesh Mody 			/* No more pending config updates */
123f3bd5173SRasesh Mody 			bfa_fsm_set_state(rxf, bna_rxf_sm_started);
124f3bd5173SRasesh Mody 		}
125f3bd5173SRasesh Mody 		break;
126f3bd5173SRasesh Mody 
127f3bd5173SRasesh Mody 	default:
128f3bd5173SRasesh Mody 		bfa_sm_fault(event);
129f3bd5173SRasesh Mody 	}
130f3bd5173SRasesh Mody }
131f3bd5173SRasesh Mody 
132f3bd5173SRasesh Mody static void
bna_rxf_sm_started_entry(struct bna_rxf * rxf)133f3bd5173SRasesh Mody bna_rxf_sm_started_entry(struct bna_rxf *rxf)
134f3bd5173SRasesh Mody {
135f3bd5173SRasesh Mody 	call_rxf_start_cbfn(rxf);
136f3bd5173SRasesh Mody 	call_rxf_cam_fltr_cbfn(rxf);
137f3bd5173SRasesh Mody }
138f3bd5173SRasesh Mody 
139f3bd5173SRasesh Mody static void
bna_rxf_sm_started(struct bna_rxf * rxf,enum bna_rxf_event event)140f3bd5173SRasesh Mody bna_rxf_sm_started(struct bna_rxf *rxf, enum bna_rxf_event event)
141f3bd5173SRasesh Mody {
142f3bd5173SRasesh Mody 	switch (event) {
143f3bd5173SRasesh Mody 	case RXF_E_STOP:
144f3bd5173SRasesh Mody 	case RXF_E_FAIL:
145f3bd5173SRasesh Mody 		bna_rxf_cfg_reset(rxf);
146f3bd5173SRasesh Mody 		bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
147f3bd5173SRasesh Mody 		break;
148f3bd5173SRasesh Mody 
149f3bd5173SRasesh Mody 	case RXF_E_CONFIG:
150f3bd5173SRasesh Mody 		bfa_fsm_set_state(rxf, bna_rxf_sm_cfg_wait);
151f3bd5173SRasesh Mody 		break;
152f3bd5173SRasesh Mody 
153f3bd5173SRasesh Mody 	default:
154f3bd5173SRasesh Mody 		bfa_sm_fault(event);
155f3bd5173SRasesh Mody 	}
156f3bd5173SRasesh Mody }
157f3bd5173SRasesh Mody 
158f3bd5173SRasesh Mody static void
bna_rxf_sm_last_resp_wait_entry(struct bna_rxf * rxf)159f3bd5173SRasesh Mody bna_rxf_sm_last_resp_wait_entry(struct bna_rxf *rxf)
160f3bd5173SRasesh Mody {
161f3bd5173SRasesh Mody }
162f3bd5173SRasesh Mody 
163f3bd5173SRasesh Mody static void
bna_rxf_sm_last_resp_wait(struct bna_rxf * rxf,enum bna_rxf_event event)164f3bd5173SRasesh Mody bna_rxf_sm_last_resp_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
165f3bd5173SRasesh Mody {
166f3bd5173SRasesh Mody 	switch (event) {
167f3bd5173SRasesh Mody 	case RXF_E_FAIL:
168f3bd5173SRasesh Mody 	case RXF_E_FW_RESP:
169f3bd5173SRasesh Mody 		bna_rxf_cfg_reset(rxf);
170f3bd5173SRasesh Mody 		bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
171f3bd5173SRasesh Mody 		break;
172f3bd5173SRasesh Mody 
173f3bd5173SRasesh Mody 	default:
174f3bd5173SRasesh Mody 		bfa_sm_fault(event);
175f3bd5173SRasesh Mody 	}
176f3bd5173SRasesh Mody }
177f3bd5173SRasesh Mody 
178f3bd5173SRasesh Mody static void
bna_bfi_ucast_req(struct bna_rxf * rxf,struct bna_mac * mac,enum bfi_enet_h2i_msgs req_type)179f3bd5173SRasesh Mody bna_bfi_ucast_req(struct bna_rxf *rxf, struct bna_mac *mac,
180f3bd5173SRasesh Mody 		enum bfi_enet_h2i_msgs req_type)
181f3bd5173SRasesh Mody {
182f3bd5173SRasesh Mody 	struct bfi_enet_ucast_req *req = &rxf->bfi_enet_cmd.ucast_req;
183f3bd5173SRasesh Mody 
184f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET, req_type, 0, rxf->rx->rid);
185f3bd5173SRasesh Mody 	req->mh.num_entries = htons(
186f3bd5173SRasesh Mody 	bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_ucast_req)));
187d6b30598SIvan Vecera 	ether_addr_copy(req->mac_addr, mac->addr);
188f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
189f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_ucast_req), &req->mh);
190f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
191f3bd5173SRasesh Mody }
192f3bd5173SRasesh Mody 
193f3bd5173SRasesh Mody static void
bna_bfi_mcast_add_req(struct bna_rxf * rxf,struct bna_mac * mac)194f3bd5173SRasesh Mody bna_bfi_mcast_add_req(struct bna_rxf *rxf, struct bna_mac *mac)
195f3bd5173SRasesh Mody {
196f3bd5173SRasesh Mody 	struct bfi_enet_mcast_add_req *req =
197f3bd5173SRasesh Mody 		&rxf->bfi_enet_cmd.mcast_add_req;
198f3bd5173SRasesh Mody 
199f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET, BFI_ENET_H2I_MAC_MCAST_ADD_REQ,
200f3bd5173SRasesh Mody 		0, rxf->rx->rid);
201f3bd5173SRasesh Mody 	req->mh.num_entries = htons(
202f3bd5173SRasesh Mody 	bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_mcast_add_req)));
203d6b30598SIvan Vecera 	ether_addr_copy(req->mac_addr, mac->addr);
204f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
205f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_mcast_add_req), &req->mh);
206f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
207f3bd5173SRasesh Mody }
208f3bd5173SRasesh Mody 
209f3bd5173SRasesh Mody static void
bna_bfi_mcast_del_req(struct bna_rxf * rxf,u16 handle)210f3bd5173SRasesh Mody bna_bfi_mcast_del_req(struct bna_rxf *rxf, u16 handle)
211f3bd5173SRasesh Mody {
212f3bd5173SRasesh Mody 	struct bfi_enet_mcast_del_req *req =
213f3bd5173SRasesh Mody 		&rxf->bfi_enet_cmd.mcast_del_req;
214f3bd5173SRasesh Mody 
215f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET, BFI_ENET_H2I_MAC_MCAST_DEL_REQ,
216f3bd5173SRasesh Mody 		0, rxf->rx->rid);
217f3bd5173SRasesh Mody 	req->mh.num_entries = htons(
218f3bd5173SRasesh Mody 	bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_mcast_del_req)));
219f3bd5173SRasesh Mody 	req->handle = htons(handle);
220f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
221f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_mcast_del_req), &req->mh);
222f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
223f3bd5173SRasesh Mody }
224f3bd5173SRasesh Mody 
225f3bd5173SRasesh Mody static void
bna_bfi_mcast_filter_req(struct bna_rxf * rxf,enum bna_status status)226f3bd5173SRasesh Mody bna_bfi_mcast_filter_req(struct bna_rxf *rxf, enum bna_status status)
227f3bd5173SRasesh Mody {
228f3bd5173SRasesh Mody 	struct bfi_enet_enable_req *req = &rxf->bfi_enet_cmd.req;
229f3bd5173SRasesh Mody 
230f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
231f3bd5173SRasesh Mody 		BFI_ENET_H2I_MAC_MCAST_FILTER_REQ, 0, rxf->rx->rid);
232f3bd5173SRasesh Mody 	req->mh.num_entries = htons(
233f3bd5173SRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
234f3bd5173SRasesh Mody 	req->enable = status;
235f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
236f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_enable_req), &req->mh);
237f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
238f3bd5173SRasesh Mody }
239f3bd5173SRasesh Mody 
240f3bd5173SRasesh Mody static void
bna_bfi_rx_promisc_req(struct bna_rxf * rxf,enum bna_status status)241f3bd5173SRasesh Mody bna_bfi_rx_promisc_req(struct bna_rxf *rxf, enum bna_status status)
242f3bd5173SRasesh Mody {
243f3bd5173SRasesh Mody 	struct bfi_enet_enable_req *req = &rxf->bfi_enet_cmd.req;
244f3bd5173SRasesh Mody 
245f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
246f3bd5173SRasesh Mody 		BFI_ENET_H2I_RX_PROMISCUOUS_REQ, 0, rxf->rx->rid);
247f3bd5173SRasesh Mody 	req->mh.num_entries = htons(
248f3bd5173SRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
249f3bd5173SRasesh Mody 	req->enable = status;
250f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
251f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_enable_req), &req->mh);
252f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
253f3bd5173SRasesh Mody }
254f3bd5173SRasesh Mody 
255f3bd5173SRasesh Mody static void
bna_bfi_rx_vlan_filter_set(struct bna_rxf * rxf,u8 block_idx)256f3bd5173SRasesh Mody bna_bfi_rx_vlan_filter_set(struct bna_rxf *rxf, u8 block_idx)
257f3bd5173SRasesh Mody {
258f3bd5173SRasesh Mody 	struct bfi_enet_rx_vlan_req *req = &rxf->bfi_enet_cmd.vlan_req;
259f3bd5173SRasesh Mody 	int i;
260f3bd5173SRasesh Mody 	int j;
261f3bd5173SRasesh Mody 
262f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
263f3bd5173SRasesh Mody 		BFI_ENET_H2I_RX_VLAN_SET_REQ, 0, rxf->rx->rid);
264f3bd5173SRasesh Mody 	req->mh.num_entries = htons(
265f3bd5173SRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_rx_vlan_req)));
266f3bd5173SRasesh Mody 	req->block_idx = block_idx;
267f3bd5173SRasesh Mody 	for (i = 0; i < (BFI_ENET_VLAN_BLOCK_SIZE / 32); i++) {
268f3bd5173SRasesh Mody 		j = (block_idx * (BFI_ENET_VLAN_BLOCK_SIZE / 32)) + i;
269f3bd5173SRasesh Mody 		if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED)
270f3bd5173SRasesh Mody 			req->bit_mask[i] =
271f3bd5173SRasesh Mody 				htonl(rxf->vlan_filter_table[j]);
272f3bd5173SRasesh Mody 		else
273f3bd5173SRasesh Mody 			req->bit_mask[i] = 0xFFFFFFFF;
274f3bd5173SRasesh Mody 	}
275f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
276f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_rx_vlan_req), &req->mh);
277f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
278f3bd5173SRasesh Mody }
279f3bd5173SRasesh Mody 
280f3bd5173SRasesh Mody static void
bna_bfi_vlan_strip_enable(struct bna_rxf * rxf)281f3bd5173SRasesh Mody bna_bfi_vlan_strip_enable(struct bna_rxf *rxf)
282f3bd5173SRasesh Mody {
283f3bd5173SRasesh Mody 	struct bfi_enet_enable_req *req = &rxf->bfi_enet_cmd.req;
284f3bd5173SRasesh Mody 
285f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
286f3bd5173SRasesh Mody 		BFI_ENET_H2I_RX_VLAN_STRIP_ENABLE_REQ, 0, rxf->rx->rid);
287f3bd5173SRasesh Mody 	req->mh.num_entries = htons(
288f3bd5173SRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
289f3bd5173SRasesh Mody 	req->enable = rxf->vlan_strip_status;
290f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
291f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_enable_req), &req->mh);
292f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
293f3bd5173SRasesh Mody }
294f3bd5173SRasesh Mody 
295f3bd5173SRasesh Mody static void
bna_bfi_rit_cfg(struct bna_rxf * rxf)296f3bd5173SRasesh Mody bna_bfi_rit_cfg(struct bna_rxf *rxf)
297f3bd5173SRasesh Mody {
298f3bd5173SRasesh Mody 	struct bfi_enet_rit_req *req = &rxf->bfi_enet_cmd.rit_req;
299f3bd5173SRasesh Mody 
300f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
301f3bd5173SRasesh Mody 		BFI_ENET_H2I_RIT_CFG_REQ, 0, rxf->rx->rid);
302f3bd5173SRasesh Mody 	req->mh.num_entries = htons(
303f3bd5173SRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_rit_req)));
304f3bd5173SRasesh Mody 	req->size = htons(rxf->rit_size);
305f3bd5173SRasesh Mody 	memcpy(&req->table[0], rxf->rit, rxf->rit_size);
306f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
307f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_rit_req), &req->mh);
308f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
309f3bd5173SRasesh Mody }
310f3bd5173SRasesh Mody 
311f3bd5173SRasesh Mody static void
bna_bfi_rss_cfg(struct bna_rxf * rxf)312f3bd5173SRasesh Mody bna_bfi_rss_cfg(struct bna_rxf *rxf)
313f3bd5173SRasesh Mody {
314f3bd5173SRasesh Mody 	struct bfi_enet_rss_cfg_req *req = &rxf->bfi_enet_cmd.rss_req;
315f3bd5173SRasesh Mody 	int i;
316f3bd5173SRasesh Mody 
317f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
318f3bd5173SRasesh Mody 		BFI_ENET_H2I_RSS_CFG_REQ, 0, rxf->rx->rid);
319f3bd5173SRasesh Mody 	req->mh.num_entries = htons(
320f3bd5173SRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_rss_cfg_req)));
321f3bd5173SRasesh Mody 	req->cfg.type = rxf->rss_cfg.hash_type;
322f3bd5173SRasesh Mody 	req->cfg.mask = rxf->rss_cfg.hash_mask;
323f3bd5173SRasesh Mody 	for (i = 0; i < BFI_ENET_RSS_KEY_LEN; i++)
324f3bd5173SRasesh Mody 		req->cfg.key[i] =
325f3bd5173SRasesh Mody 			htonl(rxf->rss_cfg.toeplitz_hash_key[i]);
326f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
327f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_rss_cfg_req), &req->mh);
328f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
329f3bd5173SRasesh Mody }
330f3bd5173SRasesh Mody 
331f3bd5173SRasesh Mody static void
bna_bfi_rss_enable(struct bna_rxf * rxf)332f3bd5173SRasesh Mody bna_bfi_rss_enable(struct bna_rxf *rxf)
333f3bd5173SRasesh Mody {
334f3bd5173SRasesh Mody 	struct bfi_enet_enable_req *req = &rxf->bfi_enet_cmd.req;
335f3bd5173SRasesh Mody 
336f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
337f3bd5173SRasesh Mody 		BFI_ENET_H2I_RSS_ENABLE_REQ, 0, rxf->rx->rid);
338f3bd5173SRasesh Mody 	req->mh.num_entries = htons(
339f3bd5173SRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req)));
340f3bd5173SRasesh Mody 	req->enable = rxf->rss_status;
341f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&rxf->msgq_cmd, NULL, NULL,
342f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_enable_req), &req->mh);
343f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&rxf->rx->bna->msgq, &rxf->msgq_cmd);
344f3bd5173SRasesh Mody }
345f3bd5173SRasesh Mody 
346f3bd5173SRasesh Mody /* This function gets the multicast MAC that has already been added to CAM */
347f3bd5173SRasesh Mody static struct bna_mac *
bna_rxf_mcmac_get(struct bna_rxf * rxf,const u8 * mac_addr)348558caad7SIvan Vecera bna_rxf_mcmac_get(struct bna_rxf *rxf, const u8 *mac_addr)
349f3bd5173SRasesh Mody {
350f3bd5173SRasesh Mody 	struct bna_mac *mac;
351f3bd5173SRasesh Mody 
35216712c53SIvan Vecera 	list_for_each_entry(mac, &rxf->mcast_active_q, qe)
353a1ac490dSIvan Vecera 		if (ether_addr_equal(mac->addr, mac_addr))
354f3bd5173SRasesh Mody 			return mac;
355f3bd5173SRasesh Mody 
35616712c53SIvan Vecera 	list_for_each_entry(mac, &rxf->mcast_pending_del_q, qe)
357a1ac490dSIvan Vecera 		if (ether_addr_equal(mac->addr, mac_addr))
358f3bd5173SRasesh Mody 			return mac;
359f3bd5173SRasesh Mody 
360f3bd5173SRasesh Mody 	return NULL;
361f3bd5173SRasesh Mody }
362f3bd5173SRasesh Mody 
363f3bd5173SRasesh Mody static struct bna_mcam_handle *
bna_rxf_mchandle_get(struct bna_rxf * rxf,int handle)364f3bd5173SRasesh Mody bna_rxf_mchandle_get(struct bna_rxf *rxf, int handle)
365f3bd5173SRasesh Mody {
366f3bd5173SRasesh Mody 	struct bna_mcam_handle *mchandle;
367f3bd5173SRasesh Mody 
36816712c53SIvan Vecera 	list_for_each_entry(mchandle, &rxf->mcast_handle_q, qe)
369f3bd5173SRasesh Mody 		if (mchandle->handle == handle)
370f3bd5173SRasesh Mody 			return mchandle;
371f3bd5173SRasesh Mody 
372f3bd5173SRasesh Mody 	return NULL;
373f3bd5173SRasesh Mody }
374f3bd5173SRasesh Mody 
375f3bd5173SRasesh Mody static void
bna_rxf_mchandle_attach(struct bna_rxf * rxf,u8 * mac_addr,int handle)376f3bd5173SRasesh Mody bna_rxf_mchandle_attach(struct bna_rxf *rxf, u8 *mac_addr, int handle)
377f3bd5173SRasesh Mody {
378f3bd5173SRasesh Mody 	struct bna_mac *mcmac;
379f3bd5173SRasesh Mody 	struct bna_mcam_handle *mchandle;
380f3bd5173SRasesh Mody 
381f3bd5173SRasesh Mody 	mcmac = bna_rxf_mcmac_get(rxf, mac_addr);
382f3bd5173SRasesh Mody 	mchandle = bna_rxf_mchandle_get(rxf, handle);
383f3bd5173SRasesh Mody 	if (mchandle == NULL) {
384f3bd5173SRasesh Mody 		mchandle = bna_mcam_mod_handle_get(&rxf->rx->bna->mcam_mod);
385f3bd5173SRasesh Mody 		mchandle->handle = handle;
386f3bd5173SRasesh Mody 		mchandle->refcnt = 0;
387f3bd5173SRasesh Mody 		list_add_tail(&mchandle->qe, &rxf->mcast_handle_q);
388f3bd5173SRasesh Mody 	}
389f3bd5173SRasesh Mody 	mchandle->refcnt++;
390f3bd5173SRasesh Mody 	mcmac->handle = mchandle;
391f3bd5173SRasesh Mody }
392f3bd5173SRasesh Mody 
393f3bd5173SRasesh Mody static int
bna_rxf_mcast_del(struct bna_rxf * rxf,struct bna_mac * mac,enum bna_cleanup_type cleanup)394f3bd5173SRasesh Mody bna_rxf_mcast_del(struct bna_rxf *rxf, struct bna_mac *mac,
395f3bd5173SRasesh Mody 		enum bna_cleanup_type cleanup)
396f3bd5173SRasesh Mody {
397f3bd5173SRasesh Mody 	struct bna_mcam_handle *mchandle;
398f3bd5173SRasesh Mody 	int ret = 0;
399f3bd5173SRasesh Mody 
400f3bd5173SRasesh Mody 	mchandle = mac->handle;
401f3bd5173SRasesh Mody 	if (mchandle == NULL)
402f3bd5173SRasesh Mody 		return ret;
403f3bd5173SRasesh Mody 
404f3bd5173SRasesh Mody 	mchandle->refcnt--;
405f3bd5173SRasesh Mody 	if (mchandle->refcnt == 0) {
406f3bd5173SRasesh Mody 		if (cleanup == BNA_HARD_CLEANUP) {
407f3bd5173SRasesh Mody 			bna_bfi_mcast_del_req(rxf, mchandle->handle);
408f3bd5173SRasesh Mody 			ret = 1;
409f3bd5173SRasesh Mody 		}
410f3bd5173SRasesh Mody 		list_del(&mchandle->qe);
411f3bd5173SRasesh Mody 		bna_mcam_mod_handle_put(&rxf->rx->bna->mcam_mod, mchandle);
412f3bd5173SRasesh Mody 	}
413f3bd5173SRasesh Mody 	mac->handle = NULL;
414f3bd5173SRasesh Mody 
415f3bd5173SRasesh Mody 	return ret;
416f3bd5173SRasesh Mody }
417f3bd5173SRasesh Mody 
418f3bd5173SRasesh Mody static int
bna_rxf_mcast_cfg_apply(struct bna_rxf * rxf)419f3bd5173SRasesh Mody bna_rxf_mcast_cfg_apply(struct bna_rxf *rxf)
420f3bd5173SRasesh Mody {
421f3bd5173SRasesh Mody 	struct bna_mac *mac = NULL;
422f3bd5173SRasesh Mody 	int ret;
423f3bd5173SRasesh Mody 
42420b298f5SRasesh Mody 	/* First delete multicast entries to maintain the count */
425f3bd5173SRasesh Mody 	while (!list_empty(&rxf->mcast_pending_del_q)) {
4262b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->mcast_pending_del_q,
4272b26fb95SIvan Vecera 				       struct bna_mac, qe);
428f3bd5173SRasesh Mody 		ret = bna_rxf_mcast_del(rxf, mac, BNA_HARD_CLEANUP);
4292b26fb95SIvan Vecera 		list_move_tail(&mac->qe, bna_mcam_mod_del_q(rxf->rx->bna));
430f3bd5173SRasesh Mody 		if (ret)
431f3bd5173SRasesh Mody 			return ret;
432f3bd5173SRasesh Mody 	}
433f3bd5173SRasesh Mody 
434f3bd5173SRasesh Mody 	/* Add multicast entries */
435f3bd5173SRasesh Mody 	if (!list_empty(&rxf->mcast_pending_add_q)) {
4362b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->mcast_pending_add_q,
4372b26fb95SIvan Vecera 				       struct bna_mac, qe);
4382b26fb95SIvan Vecera 		list_move_tail(&mac->qe, &rxf->mcast_active_q);
439f3bd5173SRasesh Mody 		bna_bfi_mcast_add_req(rxf, mac);
440f3bd5173SRasesh Mody 		return 1;
441f3bd5173SRasesh Mody 	}
442f3bd5173SRasesh Mody 
443f3bd5173SRasesh Mody 	return 0;
444f3bd5173SRasesh Mody }
445f3bd5173SRasesh Mody 
446f3bd5173SRasesh Mody static int
bna_rxf_vlan_cfg_apply(struct bna_rxf * rxf)447f3bd5173SRasesh Mody bna_rxf_vlan_cfg_apply(struct bna_rxf *rxf)
448f3bd5173SRasesh Mody {
449f3bd5173SRasesh Mody 	u8 vlan_pending_bitmask;
450f3bd5173SRasesh Mody 	int block_idx = 0;
451f3bd5173SRasesh Mody 
452f3bd5173SRasesh Mody 	if (rxf->vlan_pending_bitmask) {
453f3bd5173SRasesh Mody 		vlan_pending_bitmask = rxf->vlan_pending_bitmask;
454f3bd5173SRasesh Mody 		while (!(vlan_pending_bitmask & 0x1)) {
455f3bd5173SRasesh Mody 			block_idx++;
456f3bd5173SRasesh Mody 			vlan_pending_bitmask >>= 1;
457f3bd5173SRasesh Mody 		}
4581a50691aSIvan Vecera 		rxf->vlan_pending_bitmask &= ~BIT(block_idx);
459f3bd5173SRasesh Mody 		bna_bfi_rx_vlan_filter_set(rxf, block_idx);
460f3bd5173SRasesh Mody 		return 1;
461f3bd5173SRasesh Mody 	}
462f3bd5173SRasesh Mody 
463f3bd5173SRasesh Mody 	return 0;
464f3bd5173SRasesh Mody }
465f3bd5173SRasesh Mody 
466f3bd5173SRasesh Mody static int
bna_rxf_mcast_cfg_reset(struct bna_rxf * rxf,enum bna_cleanup_type cleanup)467f3bd5173SRasesh Mody bna_rxf_mcast_cfg_reset(struct bna_rxf *rxf, enum bna_cleanup_type cleanup)
468f3bd5173SRasesh Mody {
469f3bd5173SRasesh Mody 	struct bna_mac *mac;
470f3bd5173SRasesh Mody 	int ret;
471f3bd5173SRasesh Mody 
472f3bd5173SRasesh Mody 	/* Throw away delete pending mcast entries */
473f3bd5173SRasesh Mody 	while (!list_empty(&rxf->mcast_pending_del_q)) {
4742b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->mcast_pending_del_q,
4752b26fb95SIvan Vecera 				       struct bna_mac, qe);
476f3bd5173SRasesh Mody 		ret = bna_rxf_mcast_del(rxf, mac, cleanup);
4772b26fb95SIvan Vecera 		list_move_tail(&mac->qe, bna_mcam_mod_del_q(rxf->rx->bna));
478f3bd5173SRasesh Mody 		if (ret)
479f3bd5173SRasesh Mody 			return ret;
480f3bd5173SRasesh Mody 	}
481f3bd5173SRasesh Mody 
482f3bd5173SRasesh Mody 	/* Move active mcast entries to pending_add_q */
483f3bd5173SRasesh Mody 	while (!list_empty(&rxf->mcast_active_q)) {
4842b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->mcast_active_q,
4852b26fb95SIvan Vecera 				       struct bna_mac, qe);
4862b26fb95SIvan Vecera 		list_move_tail(&mac->qe, &rxf->mcast_pending_add_q);
487f3bd5173SRasesh Mody 		if (bna_rxf_mcast_del(rxf, mac, cleanup))
488f3bd5173SRasesh Mody 			return 1;
489f3bd5173SRasesh Mody 	}
490f3bd5173SRasesh Mody 
491f3bd5173SRasesh Mody 	return 0;
492f3bd5173SRasesh Mody }
493f3bd5173SRasesh Mody 
494f3bd5173SRasesh Mody static int
bna_rxf_rss_cfg_apply(struct bna_rxf * rxf)495f3bd5173SRasesh Mody bna_rxf_rss_cfg_apply(struct bna_rxf *rxf)
496f3bd5173SRasesh Mody {
497f3bd5173SRasesh Mody 	if (rxf->rss_pending) {
498f3bd5173SRasesh Mody 		if (rxf->rss_pending & BNA_RSS_F_RIT_PENDING) {
499f3bd5173SRasesh Mody 			rxf->rss_pending &= ~BNA_RSS_F_RIT_PENDING;
500f3bd5173SRasesh Mody 			bna_bfi_rit_cfg(rxf);
501f3bd5173SRasesh Mody 			return 1;
502f3bd5173SRasesh Mody 		}
503f3bd5173SRasesh Mody 
504f3bd5173SRasesh Mody 		if (rxf->rss_pending & BNA_RSS_F_CFG_PENDING) {
505f3bd5173SRasesh Mody 			rxf->rss_pending &= ~BNA_RSS_F_CFG_PENDING;
506f3bd5173SRasesh Mody 			bna_bfi_rss_cfg(rxf);
507f3bd5173SRasesh Mody 			return 1;
508f3bd5173SRasesh Mody 		}
509f3bd5173SRasesh Mody 
510f3bd5173SRasesh Mody 		if (rxf->rss_pending & BNA_RSS_F_STATUS_PENDING) {
511f3bd5173SRasesh Mody 			rxf->rss_pending &= ~BNA_RSS_F_STATUS_PENDING;
512f3bd5173SRasesh Mody 			bna_bfi_rss_enable(rxf);
513f3bd5173SRasesh Mody 			return 1;
514f3bd5173SRasesh Mody 		}
515f3bd5173SRasesh Mody 	}
516f3bd5173SRasesh Mody 
517f3bd5173SRasesh Mody 	return 0;
518f3bd5173SRasesh Mody }
519f3bd5173SRasesh Mody 
520f3bd5173SRasesh Mody static int
bna_rxf_cfg_apply(struct bna_rxf * rxf)521f3bd5173SRasesh Mody bna_rxf_cfg_apply(struct bna_rxf *rxf)
522f3bd5173SRasesh Mody {
523f3bd5173SRasesh Mody 	if (bna_rxf_ucast_cfg_apply(rxf))
524f3bd5173SRasesh Mody 		return 1;
525f3bd5173SRasesh Mody 
526f3bd5173SRasesh Mody 	if (bna_rxf_mcast_cfg_apply(rxf))
527f3bd5173SRasesh Mody 		return 1;
528f3bd5173SRasesh Mody 
529f3bd5173SRasesh Mody 	if (bna_rxf_promisc_cfg_apply(rxf))
530f3bd5173SRasesh Mody 		return 1;
531f3bd5173SRasesh Mody 
532f3bd5173SRasesh Mody 	if (bna_rxf_allmulti_cfg_apply(rxf))
533f3bd5173SRasesh Mody 		return 1;
534f3bd5173SRasesh Mody 
535f3bd5173SRasesh Mody 	if (bna_rxf_vlan_cfg_apply(rxf))
536f3bd5173SRasesh Mody 		return 1;
537f3bd5173SRasesh Mody 
538f3bd5173SRasesh Mody 	if (bna_rxf_vlan_strip_cfg_apply(rxf))
539f3bd5173SRasesh Mody 		return 1;
540f3bd5173SRasesh Mody 
541f3bd5173SRasesh Mody 	if (bna_rxf_rss_cfg_apply(rxf))
542f3bd5173SRasesh Mody 		return 1;
543f3bd5173SRasesh Mody 
544f3bd5173SRasesh Mody 	return 0;
545f3bd5173SRasesh Mody }
546f3bd5173SRasesh Mody 
547f3bd5173SRasesh Mody static void
bna_rxf_cfg_reset(struct bna_rxf * rxf)548f3bd5173SRasesh Mody bna_rxf_cfg_reset(struct bna_rxf *rxf)
549f3bd5173SRasesh Mody {
550f3bd5173SRasesh Mody 	bna_rxf_ucast_cfg_reset(rxf, BNA_SOFT_CLEANUP);
551f3bd5173SRasesh Mody 	bna_rxf_mcast_cfg_reset(rxf, BNA_SOFT_CLEANUP);
552f3bd5173SRasesh Mody 	bna_rxf_promisc_cfg_reset(rxf, BNA_SOFT_CLEANUP);
553f3bd5173SRasesh Mody 	bna_rxf_allmulti_cfg_reset(rxf, BNA_SOFT_CLEANUP);
554f3bd5173SRasesh Mody 	bna_rxf_vlan_cfg_soft_reset(rxf);
555f3bd5173SRasesh Mody 	bna_rxf_rss_cfg_soft_reset(rxf);
556f3bd5173SRasesh Mody }
557f3bd5173SRasesh Mody 
558f3bd5173SRasesh Mody static void
bna_rit_init(struct bna_rxf * rxf,int rit_size)559f3bd5173SRasesh Mody bna_rit_init(struct bna_rxf *rxf, int rit_size)
560f3bd5173SRasesh Mody {
561f3bd5173SRasesh Mody 	struct bna_rx *rx = rxf->rx;
562f3bd5173SRasesh Mody 	struct bna_rxp *rxp;
563f3bd5173SRasesh Mody 	int offset = 0;
564f3bd5173SRasesh Mody 
565f3bd5173SRasesh Mody 	rxf->rit_size = rit_size;
56616712c53SIvan Vecera 	list_for_each_entry(rxp, &rx->rxp_q, qe) {
567f3bd5173SRasesh Mody 		rxf->rit[offset] = rxp->cq.ccb->id;
568f3bd5173SRasesh Mody 		offset++;
569f3bd5173SRasesh Mody 	}
570f3bd5173SRasesh Mody }
571f3bd5173SRasesh Mody 
572f3bd5173SRasesh Mody void
bna_bfi_rxf_cfg_rsp(struct bna_rxf * rxf,struct bfi_msgq_mhdr * msghdr)573f3bd5173SRasesh Mody bna_bfi_rxf_cfg_rsp(struct bna_rxf *rxf, struct bfi_msgq_mhdr *msghdr)
574f3bd5173SRasesh Mody {
575f3bd5173SRasesh Mody 	bfa_fsm_send_event(rxf, RXF_E_FW_RESP);
576f3bd5173SRasesh Mody }
577f3bd5173SRasesh Mody 
578f3bd5173SRasesh Mody void
bna_bfi_rxf_ucast_set_rsp(struct bna_rxf * rxf,struct bfi_msgq_mhdr * msghdr)579f489a4baSRasesh Mody bna_bfi_rxf_ucast_set_rsp(struct bna_rxf *rxf,
580f489a4baSRasesh Mody 			struct bfi_msgq_mhdr *msghdr)
581f489a4baSRasesh Mody {
582f489a4baSRasesh Mody 	struct bfi_enet_rsp *rsp =
58317b6f244SFabian Frederick 		container_of(msghdr, struct bfi_enet_rsp, mh);
584f489a4baSRasesh Mody 
585f489a4baSRasesh Mody 	if (rsp->error) {
586f489a4baSRasesh Mody 		/* Clear ucast from cache */
587f489a4baSRasesh Mody 		rxf->ucast_active_set = 0;
588f489a4baSRasesh Mody 	}
589f489a4baSRasesh Mody 
590f489a4baSRasesh Mody 	bfa_fsm_send_event(rxf, RXF_E_FW_RESP);
591f489a4baSRasesh Mody }
592f489a4baSRasesh Mody 
593f489a4baSRasesh Mody void
bna_bfi_rxf_mcast_add_rsp(struct bna_rxf * rxf,struct bfi_msgq_mhdr * msghdr)594f3bd5173SRasesh Mody bna_bfi_rxf_mcast_add_rsp(struct bna_rxf *rxf,
595f3bd5173SRasesh Mody 			struct bfi_msgq_mhdr *msghdr)
596f3bd5173SRasesh Mody {
597f3bd5173SRasesh Mody 	struct bfi_enet_mcast_add_req *req =
598f3bd5173SRasesh Mody 		&rxf->bfi_enet_cmd.mcast_add_req;
599f3bd5173SRasesh Mody 	struct bfi_enet_mcast_add_rsp *rsp =
60017b6f244SFabian Frederick 		container_of(msghdr, struct bfi_enet_mcast_add_rsp, mh);
601f3bd5173SRasesh Mody 
602f3bd5173SRasesh Mody 	bna_rxf_mchandle_attach(rxf, (u8 *)&req->mac_addr,
603f3bd5173SRasesh Mody 		ntohs(rsp->handle));
604f3bd5173SRasesh Mody 	bfa_fsm_send_event(rxf, RXF_E_FW_RESP);
605f3bd5173SRasesh Mody }
606f3bd5173SRasesh Mody 
607f3bd5173SRasesh Mody static void
bna_rxf_init(struct bna_rxf * rxf,struct bna_rx * rx,struct bna_rx_config * q_config,struct bna_res_info * res_info)608f3bd5173SRasesh Mody bna_rxf_init(struct bna_rxf *rxf,
609f3bd5173SRasesh Mody 		struct bna_rx *rx,
610f3bd5173SRasesh Mody 		struct bna_rx_config *q_config,
611f3bd5173SRasesh Mody 		struct bna_res_info *res_info)
612f3bd5173SRasesh Mody {
613f3bd5173SRasesh Mody 	rxf->rx = rx;
614f3bd5173SRasesh Mody 
615f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&rxf->ucast_pending_add_q);
616f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&rxf->ucast_pending_del_q);
617f3bd5173SRasesh Mody 	rxf->ucast_pending_set = 0;
618f3bd5173SRasesh Mody 	rxf->ucast_active_set = 0;
619f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&rxf->ucast_active_q);
620f3bd5173SRasesh Mody 	rxf->ucast_pending_mac = NULL;
621f3bd5173SRasesh Mody 
622f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&rxf->mcast_pending_add_q);
623f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&rxf->mcast_pending_del_q);
624f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&rxf->mcast_active_q);
625f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&rxf->mcast_handle_q);
626f3bd5173SRasesh Mody 
627f3bd5173SRasesh Mody 	rxf->rit = (u8 *)
628f3bd5173SRasesh Mody 		res_info[BNA_RX_RES_MEM_T_RIT].res_u.mem_info.mdl[0].kva;
629f3bd5173SRasesh Mody 	bna_rit_init(rxf, q_config->num_paths);
630f3bd5173SRasesh Mody 
631f3bd5173SRasesh Mody 	rxf->rss_status = q_config->rss_status;
632f3bd5173SRasesh Mody 	if (rxf->rss_status == BNA_STATUS_T_ENABLED) {
633f3bd5173SRasesh Mody 		rxf->rss_cfg = q_config->rss_config;
634f3bd5173SRasesh Mody 		rxf->rss_pending |= BNA_RSS_F_CFG_PENDING;
635f3bd5173SRasesh Mody 		rxf->rss_pending |= BNA_RSS_F_RIT_PENDING;
636f3bd5173SRasesh Mody 		rxf->rss_pending |= BNA_RSS_F_STATUS_PENDING;
637f3bd5173SRasesh Mody 	}
638f3bd5173SRasesh Mody 
639f3bd5173SRasesh Mody 	rxf->vlan_filter_status = BNA_STATUS_T_DISABLED;
640f3bd5173SRasesh Mody 	memset(rxf->vlan_filter_table, 0,
641f3bd5173SRasesh Mody 			(sizeof(u32) * (BFI_ENET_VLAN_ID_MAX / 32)));
642f3bd5173SRasesh Mody 	rxf->vlan_filter_table[0] |= 1; /* for pure priority tagged frames */
643f3bd5173SRasesh Mody 	rxf->vlan_pending_bitmask = (u8)BFI_VLAN_BMASK_ALL;
644f3bd5173SRasesh Mody 
645f3bd5173SRasesh Mody 	rxf->vlan_strip_status = q_config->vlan_strip_status;
646f3bd5173SRasesh Mody 
647f3bd5173SRasesh Mody 	bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
648f3bd5173SRasesh Mody }
649f3bd5173SRasesh Mody 
650f3bd5173SRasesh Mody static void
bna_rxf_uninit(struct bna_rxf * rxf)651f3bd5173SRasesh Mody bna_rxf_uninit(struct bna_rxf *rxf)
652f3bd5173SRasesh Mody {
653f3bd5173SRasesh Mody 	struct bna_mac *mac;
654f3bd5173SRasesh Mody 
655f3bd5173SRasesh Mody 	rxf->ucast_pending_set = 0;
656f3bd5173SRasesh Mody 	rxf->ucast_active_set = 0;
657f3bd5173SRasesh Mody 
658f3bd5173SRasesh Mody 	while (!list_empty(&rxf->ucast_pending_add_q)) {
6592b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->ucast_pending_add_q,
6602b26fb95SIvan Vecera 				       struct bna_mac, qe);
6612b26fb95SIvan Vecera 		list_move_tail(&mac->qe, bna_ucam_mod_free_q(rxf->rx->bna));
662f3bd5173SRasesh Mody 	}
663f3bd5173SRasesh Mody 
664f3bd5173SRasesh Mody 	if (rxf->ucast_pending_mac) {
6652b26fb95SIvan Vecera 		list_add_tail(&rxf->ucast_pending_mac->qe,
6662b26fb95SIvan Vecera 			      bna_ucam_mod_free_q(rxf->rx->bna));
667f3bd5173SRasesh Mody 		rxf->ucast_pending_mac = NULL;
668f3bd5173SRasesh Mody 	}
669f3bd5173SRasesh Mody 
670f3bd5173SRasesh Mody 	while (!list_empty(&rxf->mcast_pending_add_q)) {
6712b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->mcast_pending_add_q,
6722b26fb95SIvan Vecera 				       struct bna_mac, qe);
6732b26fb95SIvan Vecera 		list_move_tail(&mac->qe, bna_mcam_mod_free_q(rxf->rx->bna));
674f3bd5173SRasesh Mody 	}
675f3bd5173SRasesh Mody 
676f3bd5173SRasesh Mody 	rxf->rxmode_pending = 0;
677f3bd5173SRasesh Mody 	rxf->rxmode_pending_bitmask = 0;
678f3bd5173SRasesh Mody 	if (rxf->rx->bna->promisc_rid == rxf->rx->rid)
679f3bd5173SRasesh Mody 		rxf->rx->bna->promisc_rid = BFI_INVALID_RID;
680f3bd5173SRasesh Mody 	if (rxf->rx->bna->default_mode_rid == rxf->rx->rid)
681f3bd5173SRasesh Mody 		rxf->rx->bna->default_mode_rid = BFI_INVALID_RID;
682f3bd5173SRasesh Mody 
683f3bd5173SRasesh Mody 	rxf->rss_pending = 0;
684f3bd5173SRasesh Mody 	rxf->vlan_strip_pending = false;
685f3bd5173SRasesh Mody 
686f3bd5173SRasesh Mody 	rxf->rx = NULL;
687f3bd5173SRasesh Mody }
688f3bd5173SRasesh Mody 
689f3bd5173SRasesh Mody static void
bna_rx_cb_rxf_started(struct bna_rx * rx)690f3bd5173SRasesh Mody bna_rx_cb_rxf_started(struct bna_rx *rx)
691f3bd5173SRasesh Mody {
692f3bd5173SRasesh Mody 	bfa_fsm_send_event(rx, RX_E_RXF_STARTED);
693f3bd5173SRasesh Mody }
694f3bd5173SRasesh Mody 
695f3bd5173SRasesh Mody static void
bna_rxf_start(struct bna_rxf * rxf)696f3bd5173SRasesh Mody bna_rxf_start(struct bna_rxf *rxf)
697f3bd5173SRasesh Mody {
698f3bd5173SRasesh Mody 	rxf->start_cbfn = bna_rx_cb_rxf_started;
699f3bd5173SRasesh Mody 	rxf->start_cbarg = rxf->rx;
700f3bd5173SRasesh Mody 	bfa_fsm_send_event(rxf, RXF_E_START);
701f3bd5173SRasesh Mody }
702f3bd5173SRasesh Mody 
703f3bd5173SRasesh Mody static void
bna_rx_cb_rxf_stopped(struct bna_rx * rx)704f3bd5173SRasesh Mody bna_rx_cb_rxf_stopped(struct bna_rx *rx)
705f3bd5173SRasesh Mody {
706f3bd5173SRasesh Mody 	bfa_fsm_send_event(rx, RX_E_RXF_STOPPED);
707f3bd5173SRasesh Mody }
708f3bd5173SRasesh Mody 
709f3bd5173SRasesh Mody static void
bna_rxf_stop(struct bna_rxf * rxf)710f3bd5173SRasesh Mody bna_rxf_stop(struct bna_rxf *rxf)
711f3bd5173SRasesh Mody {
712f3bd5173SRasesh Mody 	rxf->stop_cbfn = bna_rx_cb_rxf_stopped;
713f3bd5173SRasesh Mody 	rxf->stop_cbarg = rxf->rx;
714f3bd5173SRasesh Mody 	bfa_fsm_send_event(rxf, RXF_E_STOP);
715f3bd5173SRasesh Mody }
716f3bd5173SRasesh Mody 
717f3bd5173SRasesh Mody static void
bna_rxf_fail(struct bna_rxf * rxf)718f3bd5173SRasesh Mody bna_rxf_fail(struct bna_rxf *rxf)
719f3bd5173SRasesh Mody {
720f3bd5173SRasesh Mody 	bfa_fsm_send_event(rxf, RXF_E_FAIL);
721f3bd5173SRasesh Mody }
722f3bd5173SRasesh Mody 
723f3bd5173SRasesh Mody enum bna_cb_status
bna_rx_ucast_set(struct bna_rx * rx,const u8 * ucmac)724558caad7SIvan Vecera bna_rx_ucast_set(struct bna_rx *rx, const u8 *ucmac)
725f3bd5173SRasesh Mody {
726f3bd5173SRasesh Mody 	struct bna_rxf *rxf = &rx->rxf;
727f3bd5173SRasesh Mody 
728f3bd5173SRasesh Mody 	if (rxf->ucast_pending_mac == NULL) {
729f3bd5173SRasesh Mody 		rxf->ucast_pending_mac =
73020b298f5SRasesh Mody 			bna_cam_mod_mac_get(bna_ucam_mod_free_q(rxf->rx->bna));
731f3bd5173SRasesh Mody 		if (rxf->ucast_pending_mac == NULL)
732f3bd5173SRasesh Mody 			return BNA_CB_UCAST_CAM_FULL;
733f3bd5173SRasesh Mody 	}
734f3bd5173SRasesh Mody 
735e2f9ecfcSIvan Vecera 	ether_addr_copy(rxf->ucast_pending_mac->addr, ucmac);
736f3bd5173SRasesh Mody 	rxf->ucast_pending_set = 1;
7371f9883e0SIvan Vecera 	rxf->cam_fltr_cbfn = NULL;
738f3bd5173SRasesh Mody 	rxf->cam_fltr_cbarg = rx->bna->bnad;
739f3bd5173SRasesh Mody 
740f3bd5173SRasesh Mody 	bfa_fsm_send_event(rxf, RXF_E_CONFIG);
741f3bd5173SRasesh Mody 
742f3bd5173SRasesh Mody 	return BNA_CB_SUCCESS;
743f3bd5173SRasesh Mody }
744f3bd5173SRasesh Mody 
745f3bd5173SRasesh Mody enum bna_cb_status
bna_rx_mcast_add(struct bna_rx * rx,const u8 * addr,void (* cbfn)(struct bnad *,struct bna_rx *))746558caad7SIvan Vecera bna_rx_mcast_add(struct bna_rx *rx, const u8 *addr,
747f3bd5173SRasesh Mody 		 void (*cbfn)(struct bnad *, struct bna_rx *))
748f3bd5173SRasesh Mody {
749f3bd5173SRasesh Mody 	struct bna_rxf *rxf = &rx->rxf;
750f3bd5173SRasesh Mody 	struct bna_mac *mac;
751f3bd5173SRasesh Mody 
752f3bd5173SRasesh Mody 	/* Check if already added or pending addition */
753f3bd5173SRasesh Mody 	if (bna_mac_find(&rxf->mcast_active_q, addr) ||
754f3bd5173SRasesh Mody 		bna_mac_find(&rxf->mcast_pending_add_q, addr)) {
755f3bd5173SRasesh Mody 		if (cbfn)
756f3bd5173SRasesh Mody 			cbfn(rx->bna->bnad, rx);
757f3bd5173SRasesh Mody 		return BNA_CB_SUCCESS;
758f3bd5173SRasesh Mody 	}
759f3bd5173SRasesh Mody 
76020b298f5SRasesh Mody 	mac = bna_cam_mod_mac_get(bna_mcam_mod_free_q(rxf->rx->bna));
761f3bd5173SRasesh Mody 	if (mac == NULL)
762f3bd5173SRasesh Mody 		return BNA_CB_MCAST_LIST_FULL;
763e2f9ecfcSIvan Vecera 	ether_addr_copy(mac->addr, addr);
764f3bd5173SRasesh Mody 	list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
765f3bd5173SRasesh Mody 
766f3bd5173SRasesh Mody 	rxf->cam_fltr_cbfn = cbfn;
767f3bd5173SRasesh Mody 	rxf->cam_fltr_cbarg = rx->bna->bnad;
768f3bd5173SRasesh Mody 
769f3bd5173SRasesh Mody 	bfa_fsm_send_event(rxf, RXF_E_CONFIG);
770f3bd5173SRasesh Mody 
771f3bd5173SRasesh Mody 	return BNA_CB_SUCCESS;
772f3bd5173SRasesh Mody }
773f3bd5173SRasesh Mody 
774f3bd5173SRasesh Mody enum bna_cb_status
bna_rx_ucast_listset(struct bna_rx * rx,int count,const u8 * uclist)775558caad7SIvan Vecera bna_rx_ucast_listset(struct bna_rx *rx, int count, const u8 *uclist)
776fe1624cfSRasesh Mody {
777fe1624cfSRasesh Mody 	struct bna_ucam_mod *ucam_mod = &rx->bna->ucam_mod;
778fe1624cfSRasesh Mody 	struct bna_rxf *rxf = &rx->rxf;
779fe1624cfSRasesh Mody 	struct list_head list_head;
780558caad7SIvan Vecera 	const u8 *mcaddr;
781fe1624cfSRasesh Mody 	struct bna_mac *mac, *del_mac;
782fe1624cfSRasesh Mody 	int i;
783fe1624cfSRasesh Mody 
784fe1624cfSRasesh Mody 	/* Purge the pending_add_q */
785fe1624cfSRasesh Mody 	while (!list_empty(&rxf->ucast_pending_add_q)) {
7862b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->ucast_pending_add_q,
7872b26fb95SIvan Vecera 				       struct bna_mac, qe);
7882b26fb95SIvan Vecera 		list_move_tail(&mac->qe, &ucam_mod->free_q);
789fe1624cfSRasesh Mody 	}
790fe1624cfSRasesh Mody 
791fe1624cfSRasesh Mody 	/* Schedule active_q entries for deletion */
792fe1624cfSRasesh Mody 	while (!list_empty(&rxf->ucast_active_q)) {
7932b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->ucast_active_q,
7942b26fb95SIvan Vecera 				       struct bna_mac, qe);
795fe1624cfSRasesh Mody 		del_mac = bna_cam_mod_mac_get(&ucam_mod->del_q);
7962b26fb95SIvan Vecera 		ether_addr_copy(del_mac->addr, mac->addr);
7972b26fb95SIvan Vecera 		del_mac->handle = mac->handle;
798fe1624cfSRasesh Mody 		list_add_tail(&del_mac->qe, &rxf->ucast_pending_del_q);
7992b26fb95SIvan Vecera 		list_move_tail(&mac->qe, &ucam_mod->free_q);
800fe1624cfSRasesh Mody 	}
801fe1624cfSRasesh Mody 
802fe1624cfSRasesh Mody 	/* Allocate nodes */
803fe1624cfSRasesh Mody 	INIT_LIST_HEAD(&list_head);
804fe1624cfSRasesh Mody 	for (i = 0, mcaddr = uclist; i < count; i++) {
805fe1624cfSRasesh Mody 		mac = bna_cam_mod_mac_get(&ucam_mod->free_q);
806fe1624cfSRasesh Mody 		if (mac == NULL)
807fe1624cfSRasesh Mody 			goto err_return;
808e2f9ecfcSIvan Vecera 		ether_addr_copy(mac->addr, mcaddr);
809fe1624cfSRasesh Mody 		list_add_tail(&mac->qe, &list_head);
810fe1624cfSRasesh Mody 		mcaddr += ETH_ALEN;
811fe1624cfSRasesh Mody 	}
812fe1624cfSRasesh Mody 
813fe1624cfSRasesh Mody 	/* Add the new entries */
814fe1624cfSRasesh Mody 	while (!list_empty(&list_head)) {
8152b26fb95SIvan Vecera 		mac = list_first_entry(&list_head, struct bna_mac, qe);
8162b26fb95SIvan Vecera 		list_move_tail(&mac->qe, &rxf->ucast_pending_add_q);
817fe1624cfSRasesh Mody 	}
818fe1624cfSRasesh Mody 
819fe1624cfSRasesh Mody 	bfa_fsm_send_event(rxf, RXF_E_CONFIG);
820fe1624cfSRasesh Mody 
821fe1624cfSRasesh Mody 	return BNA_CB_SUCCESS;
822fe1624cfSRasesh Mody 
823fe1624cfSRasesh Mody err_return:
824fe1624cfSRasesh Mody 	while (!list_empty(&list_head)) {
8252b26fb95SIvan Vecera 		mac = list_first_entry(&list_head, struct bna_mac, qe);
8262b26fb95SIvan Vecera 		list_move_tail(&mac->qe, &ucam_mod->free_q);
827fe1624cfSRasesh Mody 	}
828fe1624cfSRasesh Mody 
829fe1624cfSRasesh Mody 	return BNA_CB_UCAST_CAM_FULL;
830fe1624cfSRasesh Mody }
831fe1624cfSRasesh Mody 
832fe1624cfSRasesh Mody enum bna_cb_status
bna_rx_mcast_listset(struct bna_rx * rx,int count,const u8 * mclist)833558caad7SIvan Vecera bna_rx_mcast_listset(struct bna_rx *rx, int count, const u8 *mclist)
834f3bd5173SRasesh Mody {
83520b298f5SRasesh Mody 	struct bna_mcam_mod *mcam_mod = &rx->bna->mcam_mod;
836f3bd5173SRasesh Mody 	struct bna_rxf *rxf = &rx->rxf;
837f3bd5173SRasesh Mody 	struct list_head list_head;
838558caad7SIvan Vecera 	const u8 *mcaddr;
83920b298f5SRasesh Mody 	struct bna_mac *mac, *del_mac;
840f3bd5173SRasesh Mody 	int i;
841f3bd5173SRasesh Mody 
842f3bd5173SRasesh Mody 	/* Purge the pending_add_q */
843f3bd5173SRasesh Mody 	while (!list_empty(&rxf->mcast_pending_add_q)) {
8442b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->mcast_pending_add_q,
8452b26fb95SIvan Vecera 				       struct bna_mac, qe);
8462b26fb95SIvan Vecera 		list_move_tail(&mac->qe, &mcam_mod->free_q);
847f3bd5173SRasesh Mody 	}
848f3bd5173SRasesh Mody 
849f3bd5173SRasesh Mody 	/* Schedule active_q entries for deletion */
850f3bd5173SRasesh Mody 	while (!list_empty(&rxf->mcast_active_q)) {
8512b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->mcast_active_q,
8522b26fb95SIvan Vecera 				       struct bna_mac, qe);
85320b298f5SRasesh Mody 		del_mac = bna_cam_mod_mac_get(&mcam_mod->del_q);
8542b26fb95SIvan Vecera 		ether_addr_copy(del_mac->addr, mac->addr);
8552b26fb95SIvan Vecera 		del_mac->handle = mac->handle;
85620b298f5SRasesh Mody 		list_add_tail(&del_mac->qe, &rxf->mcast_pending_del_q);
85720b298f5SRasesh Mody 		mac->handle = NULL;
8582b26fb95SIvan Vecera 		list_move_tail(&mac->qe, &mcam_mod->free_q);
85920b298f5SRasesh Mody 	}
86020b298f5SRasesh Mody 
86120b298f5SRasesh Mody 	/* Allocate nodes */
86220b298f5SRasesh Mody 	INIT_LIST_HEAD(&list_head);
86320b298f5SRasesh Mody 	for (i = 0, mcaddr = mclist; i < count; i++) {
86420b298f5SRasesh Mody 		mac = bna_cam_mod_mac_get(&mcam_mod->free_q);
86520b298f5SRasesh Mody 		if (mac == NULL)
86620b298f5SRasesh Mody 			goto err_return;
867e2f9ecfcSIvan Vecera 		ether_addr_copy(mac->addr, mcaddr);
86820b298f5SRasesh Mody 		list_add_tail(&mac->qe, &list_head);
86920b298f5SRasesh Mody 
87020b298f5SRasesh Mody 		mcaddr += ETH_ALEN;
871f3bd5173SRasesh Mody 	}
872f3bd5173SRasesh Mody 
873f3bd5173SRasesh Mody 	/* Add the new entries */
874f3bd5173SRasesh Mody 	while (!list_empty(&list_head)) {
8752b26fb95SIvan Vecera 		mac = list_first_entry(&list_head, struct bna_mac, qe);
8762b26fb95SIvan Vecera 		list_move_tail(&mac->qe, &rxf->mcast_pending_add_q);
877f3bd5173SRasesh Mody 	}
878f3bd5173SRasesh Mody 
879f3bd5173SRasesh Mody 	bfa_fsm_send_event(rxf, RXF_E_CONFIG);
880f3bd5173SRasesh Mody 
881f3bd5173SRasesh Mody 	return BNA_CB_SUCCESS;
882f3bd5173SRasesh Mody 
883f3bd5173SRasesh Mody err_return:
884f3bd5173SRasesh Mody 	while (!list_empty(&list_head)) {
8852b26fb95SIvan Vecera 		mac = list_first_entry(&list_head, struct bna_mac, qe);
8862b26fb95SIvan Vecera 		list_move_tail(&mac->qe, &mcam_mod->free_q);
887f3bd5173SRasesh Mody 	}
888f3bd5173SRasesh Mody 
889f3bd5173SRasesh Mody 	return BNA_CB_MCAST_LIST_FULL;
890f3bd5173SRasesh Mody }
891f3bd5173SRasesh Mody 
892f3bd5173SRasesh Mody void
bna_rx_mcast_delall(struct bna_rx * rx)8931f9883e0SIvan Vecera bna_rx_mcast_delall(struct bna_rx *rx)
894fe1624cfSRasesh Mody {
895fe1624cfSRasesh Mody 	struct bna_rxf *rxf = &rx->rxf;
896fe1624cfSRasesh Mody 	struct bna_mac *mac, *del_mac;
897fe1624cfSRasesh Mody 	int need_hw_config = 0;
898fe1624cfSRasesh Mody 
899fe1624cfSRasesh Mody 	/* Purge all entries from pending_add_q */
900fe1624cfSRasesh Mody 	while (!list_empty(&rxf->mcast_pending_add_q)) {
9012b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->mcast_pending_add_q,
9022b26fb95SIvan Vecera 				       struct bna_mac, qe);
9032b26fb95SIvan Vecera 		list_move_tail(&mac->qe, bna_mcam_mod_free_q(rxf->rx->bna));
904fe1624cfSRasesh Mody 	}
905fe1624cfSRasesh Mody 
906fe1624cfSRasesh Mody 	/* Schedule all entries in active_q for deletion */
907fe1624cfSRasesh Mody 	while (!list_empty(&rxf->mcast_active_q)) {
9082b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->mcast_active_q,
9092b26fb95SIvan Vecera 				       struct bna_mac, qe);
9102b26fb95SIvan Vecera 		list_del(&mac->qe);
911fe1624cfSRasesh Mody 		del_mac = bna_cam_mod_mac_get(bna_mcam_mod_del_q(rxf->rx->bna));
912fe1624cfSRasesh Mody 		memcpy(del_mac, mac, sizeof(*del_mac));
913fe1624cfSRasesh Mody 		list_add_tail(&del_mac->qe, &rxf->mcast_pending_del_q);
914fe1624cfSRasesh Mody 		mac->handle = NULL;
9152b26fb95SIvan Vecera 		list_add_tail(&mac->qe, bna_mcam_mod_free_q(rxf->rx->bna));
916fe1624cfSRasesh Mody 		need_hw_config = 1;
917fe1624cfSRasesh Mody 	}
918fe1624cfSRasesh Mody 
9191f9883e0SIvan Vecera 	if (need_hw_config)
920fe1624cfSRasesh Mody 		bfa_fsm_send_event(rxf, RXF_E_CONFIG);
921fe1624cfSRasesh Mody }
922fe1624cfSRasesh Mody 
923fe1624cfSRasesh Mody void
bna_rx_vlan_add(struct bna_rx * rx,int vlan_id)924f3bd5173SRasesh Mody bna_rx_vlan_add(struct bna_rx *rx, int vlan_id)
925f3bd5173SRasesh Mody {
926f3bd5173SRasesh Mody 	struct bna_rxf *rxf = &rx->rxf;
927f3bd5173SRasesh Mody 	int index = (vlan_id >> BFI_VLAN_WORD_SHIFT);
928ebb56d37SIvan Vecera 	int bit = BIT(vlan_id & BFI_VLAN_WORD_MASK);
929f3bd5173SRasesh Mody 	int group_id = (vlan_id >> BFI_VLAN_BLOCK_SHIFT);
930f3bd5173SRasesh Mody 
931f3bd5173SRasesh Mody 	rxf->vlan_filter_table[index] |= bit;
932f3bd5173SRasesh Mody 	if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) {
9331a50691aSIvan Vecera 		rxf->vlan_pending_bitmask |= BIT(group_id);
934f3bd5173SRasesh Mody 		bfa_fsm_send_event(rxf, RXF_E_CONFIG);
935f3bd5173SRasesh Mody 	}
936f3bd5173SRasesh Mody }
937f3bd5173SRasesh Mody 
938f3bd5173SRasesh Mody void
bna_rx_vlan_del(struct bna_rx * rx,int vlan_id)939f3bd5173SRasesh Mody bna_rx_vlan_del(struct bna_rx *rx, int vlan_id)
940f3bd5173SRasesh Mody {
941f3bd5173SRasesh Mody 	struct bna_rxf *rxf = &rx->rxf;
942f3bd5173SRasesh Mody 	int index = (vlan_id >> BFI_VLAN_WORD_SHIFT);
943ebb56d37SIvan Vecera 	int bit = BIT(vlan_id & BFI_VLAN_WORD_MASK);
944f3bd5173SRasesh Mody 	int group_id = (vlan_id >> BFI_VLAN_BLOCK_SHIFT);
945f3bd5173SRasesh Mody 
946f3bd5173SRasesh Mody 	rxf->vlan_filter_table[index] &= ~bit;
947f3bd5173SRasesh Mody 	if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) {
9481a50691aSIvan Vecera 		rxf->vlan_pending_bitmask |= BIT(group_id);
949f3bd5173SRasesh Mody 		bfa_fsm_send_event(rxf, RXF_E_CONFIG);
950f3bd5173SRasesh Mody 	}
951f3bd5173SRasesh Mody }
952f3bd5173SRasesh Mody 
953f3bd5173SRasesh Mody static int
bna_rxf_ucast_cfg_apply(struct bna_rxf * rxf)954f3bd5173SRasesh Mody bna_rxf_ucast_cfg_apply(struct bna_rxf *rxf)
955f3bd5173SRasesh Mody {
956f3bd5173SRasesh Mody 	struct bna_mac *mac = NULL;
957f3bd5173SRasesh Mody 
958f3bd5173SRasesh Mody 	/* Delete MAC addresses previousely added */
959f3bd5173SRasesh Mody 	if (!list_empty(&rxf->ucast_pending_del_q)) {
9602b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->ucast_pending_del_q,
9612b26fb95SIvan Vecera 				       struct bna_mac, qe);
962f3bd5173SRasesh Mody 		bna_bfi_ucast_req(rxf, mac, BFI_ENET_H2I_MAC_UCAST_DEL_REQ);
9632b26fb95SIvan Vecera 		list_move_tail(&mac->qe, bna_ucam_mod_del_q(rxf->rx->bna));
964f3bd5173SRasesh Mody 		return 1;
965f3bd5173SRasesh Mody 	}
966f3bd5173SRasesh Mody 
967f3bd5173SRasesh Mody 	/* Set default unicast MAC */
968f3bd5173SRasesh Mody 	if (rxf->ucast_pending_set) {
969f3bd5173SRasesh Mody 		rxf->ucast_pending_set = 0;
970e2f9ecfcSIvan Vecera 		ether_addr_copy(rxf->ucast_active_mac.addr,
971e2f9ecfcSIvan Vecera 				rxf->ucast_pending_mac->addr);
972f3bd5173SRasesh Mody 		rxf->ucast_active_set = 1;
973f3bd5173SRasesh Mody 		bna_bfi_ucast_req(rxf, &rxf->ucast_active_mac,
974f3bd5173SRasesh Mody 			BFI_ENET_H2I_MAC_UCAST_SET_REQ);
975f3bd5173SRasesh Mody 		return 1;
976f3bd5173SRasesh Mody 	}
977f3bd5173SRasesh Mody 
978f3bd5173SRasesh Mody 	/* Add additional MAC entries */
979f3bd5173SRasesh Mody 	if (!list_empty(&rxf->ucast_pending_add_q)) {
9802b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->ucast_pending_add_q,
9812b26fb95SIvan Vecera 				       struct bna_mac, qe);
982a7f4b988SIvan Vecera 		list_move_tail(&mac->qe, &rxf->ucast_active_q);
983f3bd5173SRasesh Mody 		bna_bfi_ucast_req(rxf, mac, BFI_ENET_H2I_MAC_UCAST_ADD_REQ);
984f3bd5173SRasesh Mody 		return 1;
985f3bd5173SRasesh Mody 	}
986f3bd5173SRasesh Mody 
987f3bd5173SRasesh Mody 	return 0;
988f3bd5173SRasesh Mody }
989f3bd5173SRasesh Mody 
990f3bd5173SRasesh Mody static int
bna_rxf_ucast_cfg_reset(struct bna_rxf * rxf,enum bna_cleanup_type cleanup)991f3bd5173SRasesh Mody bna_rxf_ucast_cfg_reset(struct bna_rxf *rxf, enum bna_cleanup_type cleanup)
992f3bd5173SRasesh Mody {
993f3bd5173SRasesh Mody 	struct bna_mac *mac;
994f3bd5173SRasesh Mody 
995f3bd5173SRasesh Mody 	/* Throw away delete pending ucast entries */
996f3bd5173SRasesh Mody 	while (!list_empty(&rxf->ucast_pending_del_q)) {
9972b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->ucast_pending_del_q,
9982b26fb95SIvan Vecera 				       struct bna_mac, qe);
999f3bd5173SRasesh Mody 		if (cleanup == BNA_SOFT_CLEANUP)
10002b26fb95SIvan Vecera 			list_move_tail(&mac->qe,
10012b26fb95SIvan Vecera 				       bna_ucam_mod_del_q(rxf->rx->bna));
1002f3bd5173SRasesh Mody 		else {
1003f3bd5173SRasesh Mody 			bna_bfi_ucast_req(rxf, mac,
1004f3bd5173SRasesh Mody 					  BFI_ENET_H2I_MAC_UCAST_DEL_REQ);
10052b26fb95SIvan Vecera 			list_move_tail(&mac->qe,
10062b26fb95SIvan Vecera 				       bna_ucam_mod_del_q(rxf->rx->bna));
1007f3bd5173SRasesh Mody 			return 1;
1008f3bd5173SRasesh Mody 		}
1009f3bd5173SRasesh Mody 	}
1010f3bd5173SRasesh Mody 
1011f3bd5173SRasesh Mody 	/* Move active ucast entries to pending_add_q */
1012f3bd5173SRasesh Mody 	while (!list_empty(&rxf->ucast_active_q)) {
10132b26fb95SIvan Vecera 		mac = list_first_entry(&rxf->ucast_active_q,
10142b26fb95SIvan Vecera 				       struct bna_mac, qe);
10152b26fb95SIvan Vecera 		list_move_tail(&mac->qe, &rxf->ucast_pending_add_q);
1016f3bd5173SRasesh Mody 		if (cleanup == BNA_HARD_CLEANUP) {
1017f3bd5173SRasesh Mody 			bna_bfi_ucast_req(rxf, mac,
1018f3bd5173SRasesh Mody 				BFI_ENET_H2I_MAC_UCAST_DEL_REQ);
1019f3bd5173SRasesh Mody 			return 1;
1020f3bd5173SRasesh Mody 		}
1021f3bd5173SRasesh Mody 	}
1022f3bd5173SRasesh Mody 
1023f3bd5173SRasesh Mody 	if (rxf->ucast_active_set) {
1024f3bd5173SRasesh Mody 		rxf->ucast_pending_set = 1;
1025f3bd5173SRasesh Mody 		rxf->ucast_active_set = 0;
1026f3bd5173SRasesh Mody 		if (cleanup == BNA_HARD_CLEANUP) {
1027f3bd5173SRasesh Mody 			bna_bfi_ucast_req(rxf, &rxf->ucast_active_mac,
1028f3bd5173SRasesh Mody 				BFI_ENET_H2I_MAC_UCAST_CLR_REQ);
1029f3bd5173SRasesh Mody 			return 1;
1030f3bd5173SRasesh Mody 		}
1031f3bd5173SRasesh Mody 	}
1032f3bd5173SRasesh Mody 
1033f3bd5173SRasesh Mody 	return 0;
1034f3bd5173SRasesh Mody }
1035f3bd5173SRasesh Mody 
1036f3bd5173SRasesh Mody static int
bna_rxf_promisc_cfg_apply(struct bna_rxf * rxf)1037f3bd5173SRasesh Mody bna_rxf_promisc_cfg_apply(struct bna_rxf *rxf)
1038f3bd5173SRasesh Mody {
1039f3bd5173SRasesh Mody 	struct bna *bna = rxf->rx->bna;
1040f3bd5173SRasesh Mody 
1041f3bd5173SRasesh Mody 	/* Enable/disable promiscuous mode */
1042f3bd5173SRasesh Mody 	if (is_promisc_enable(rxf->rxmode_pending,
1043f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask)) {
1044f3bd5173SRasesh Mody 		/* move promisc configuration from pending -> active */
1045f3bd5173SRasesh Mody 		promisc_inactive(rxf->rxmode_pending,
1046f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1047f3bd5173SRasesh Mody 		rxf->rxmode_active |= BNA_RXMODE_PROMISC;
1048f3bd5173SRasesh Mody 		bna_bfi_rx_promisc_req(rxf, BNA_STATUS_T_ENABLED);
1049f3bd5173SRasesh Mody 		return 1;
1050f3bd5173SRasesh Mody 	} else if (is_promisc_disable(rxf->rxmode_pending,
1051f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask)) {
1052f3bd5173SRasesh Mody 		/* move promisc configuration from pending -> active */
1053f3bd5173SRasesh Mody 		promisc_inactive(rxf->rxmode_pending,
1054f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1055f3bd5173SRasesh Mody 		rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
1056f3bd5173SRasesh Mody 		bna->promisc_rid = BFI_INVALID_RID;
1057f3bd5173SRasesh Mody 		bna_bfi_rx_promisc_req(rxf, BNA_STATUS_T_DISABLED);
1058f3bd5173SRasesh Mody 		return 1;
1059f3bd5173SRasesh Mody 	}
1060f3bd5173SRasesh Mody 
1061f3bd5173SRasesh Mody 	return 0;
1062f3bd5173SRasesh Mody }
1063f3bd5173SRasesh Mody 
1064f3bd5173SRasesh Mody static int
bna_rxf_promisc_cfg_reset(struct bna_rxf * rxf,enum bna_cleanup_type cleanup)1065f3bd5173SRasesh Mody bna_rxf_promisc_cfg_reset(struct bna_rxf *rxf, enum bna_cleanup_type cleanup)
1066f3bd5173SRasesh Mody {
1067f3bd5173SRasesh Mody 	struct bna *bna = rxf->rx->bna;
1068f3bd5173SRasesh Mody 
1069f3bd5173SRasesh Mody 	/* Clear pending promisc mode disable */
1070f3bd5173SRasesh Mody 	if (is_promisc_disable(rxf->rxmode_pending,
1071f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask)) {
1072f3bd5173SRasesh Mody 		promisc_inactive(rxf->rxmode_pending,
1073f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1074f3bd5173SRasesh Mody 		rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
1075f3bd5173SRasesh Mody 		bna->promisc_rid = BFI_INVALID_RID;
1076f3bd5173SRasesh Mody 		if (cleanup == BNA_HARD_CLEANUP) {
1077f3bd5173SRasesh Mody 			bna_bfi_rx_promisc_req(rxf, BNA_STATUS_T_DISABLED);
1078f3bd5173SRasesh Mody 			return 1;
1079f3bd5173SRasesh Mody 		}
1080f3bd5173SRasesh Mody 	}
1081f3bd5173SRasesh Mody 
1082f3bd5173SRasesh Mody 	/* Move promisc mode config from active -> pending */
1083f3bd5173SRasesh Mody 	if (rxf->rxmode_active & BNA_RXMODE_PROMISC) {
1084f3bd5173SRasesh Mody 		promisc_enable(rxf->rxmode_pending,
1085f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1086f3bd5173SRasesh Mody 		rxf->rxmode_active &= ~BNA_RXMODE_PROMISC;
1087f3bd5173SRasesh Mody 		if (cleanup == BNA_HARD_CLEANUP) {
1088f3bd5173SRasesh Mody 			bna_bfi_rx_promisc_req(rxf, BNA_STATUS_T_DISABLED);
1089f3bd5173SRasesh Mody 			return 1;
1090f3bd5173SRasesh Mody 		}
1091f3bd5173SRasesh Mody 	}
1092f3bd5173SRasesh Mody 
1093f3bd5173SRasesh Mody 	return 0;
1094f3bd5173SRasesh Mody }
1095f3bd5173SRasesh Mody 
1096f3bd5173SRasesh Mody static int
bna_rxf_allmulti_cfg_apply(struct bna_rxf * rxf)1097f3bd5173SRasesh Mody bna_rxf_allmulti_cfg_apply(struct bna_rxf *rxf)
1098f3bd5173SRasesh Mody {
1099f3bd5173SRasesh Mody 	/* Enable/disable allmulti mode */
1100f3bd5173SRasesh Mody 	if (is_allmulti_enable(rxf->rxmode_pending,
1101f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask)) {
1102f3bd5173SRasesh Mody 		/* move allmulti configuration from pending -> active */
1103f3bd5173SRasesh Mody 		allmulti_inactive(rxf->rxmode_pending,
1104f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1105f3bd5173SRasesh Mody 		rxf->rxmode_active |= BNA_RXMODE_ALLMULTI;
1106f3bd5173SRasesh Mody 		bna_bfi_mcast_filter_req(rxf, BNA_STATUS_T_DISABLED);
1107f3bd5173SRasesh Mody 		return 1;
1108f3bd5173SRasesh Mody 	} else if (is_allmulti_disable(rxf->rxmode_pending,
1109f3bd5173SRasesh Mody 					rxf->rxmode_pending_bitmask)) {
1110f3bd5173SRasesh Mody 		/* move allmulti configuration from pending -> active */
1111f3bd5173SRasesh Mody 		allmulti_inactive(rxf->rxmode_pending,
1112f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1113f3bd5173SRasesh Mody 		rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
1114f3bd5173SRasesh Mody 		bna_bfi_mcast_filter_req(rxf, BNA_STATUS_T_ENABLED);
1115f3bd5173SRasesh Mody 		return 1;
1116f3bd5173SRasesh Mody 	}
1117f3bd5173SRasesh Mody 
1118f3bd5173SRasesh Mody 	return 0;
1119f3bd5173SRasesh Mody }
1120f3bd5173SRasesh Mody 
1121f3bd5173SRasesh Mody static int
bna_rxf_allmulti_cfg_reset(struct bna_rxf * rxf,enum bna_cleanup_type cleanup)1122f3bd5173SRasesh Mody bna_rxf_allmulti_cfg_reset(struct bna_rxf *rxf, enum bna_cleanup_type cleanup)
1123f3bd5173SRasesh Mody {
1124f3bd5173SRasesh Mody 	/* Clear pending allmulti mode disable */
1125f3bd5173SRasesh Mody 	if (is_allmulti_disable(rxf->rxmode_pending,
1126f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask)) {
1127f3bd5173SRasesh Mody 		allmulti_inactive(rxf->rxmode_pending,
1128f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1129f3bd5173SRasesh Mody 		rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
1130f3bd5173SRasesh Mody 		if (cleanup == BNA_HARD_CLEANUP) {
1131f3bd5173SRasesh Mody 			bna_bfi_mcast_filter_req(rxf, BNA_STATUS_T_ENABLED);
1132f3bd5173SRasesh Mody 			return 1;
1133f3bd5173SRasesh Mody 		}
1134f3bd5173SRasesh Mody 	}
1135f3bd5173SRasesh Mody 
1136f3bd5173SRasesh Mody 	/* Move allmulti mode config from active -> pending */
1137f3bd5173SRasesh Mody 	if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) {
1138f3bd5173SRasesh Mody 		allmulti_enable(rxf->rxmode_pending,
1139f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1140f3bd5173SRasesh Mody 		rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI;
1141f3bd5173SRasesh Mody 		if (cleanup == BNA_HARD_CLEANUP) {
1142f3bd5173SRasesh Mody 			bna_bfi_mcast_filter_req(rxf, BNA_STATUS_T_ENABLED);
1143f3bd5173SRasesh Mody 			return 1;
1144f3bd5173SRasesh Mody 		}
1145f3bd5173SRasesh Mody 	}
1146f3bd5173SRasesh Mody 
1147f3bd5173SRasesh Mody 	return 0;
1148f3bd5173SRasesh Mody }
1149f3bd5173SRasesh Mody 
1150f3bd5173SRasesh Mody static int
bna_rxf_promisc_enable(struct bna_rxf * rxf)1151f3bd5173SRasesh Mody bna_rxf_promisc_enable(struct bna_rxf *rxf)
1152f3bd5173SRasesh Mody {
1153f3bd5173SRasesh Mody 	struct bna *bna = rxf->rx->bna;
1154f3bd5173SRasesh Mody 	int ret = 0;
1155f3bd5173SRasesh Mody 
1156f3bd5173SRasesh Mody 	if (is_promisc_enable(rxf->rxmode_pending,
1157f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask) ||
1158f3bd5173SRasesh Mody 		(rxf->rxmode_active & BNA_RXMODE_PROMISC)) {
1159f3bd5173SRasesh Mody 		/* Do nothing if pending enable or already enabled */
1160f3bd5173SRasesh Mody 	} else if (is_promisc_disable(rxf->rxmode_pending,
1161f3bd5173SRasesh Mody 					rxf->rxmode_pending_bitmask)) {
1162f3bd5173SRasesh Mody 		/* Turn off pending disable command */
1163f3bd5173SRasesh Mody 		promisc_inactive(rxf->rxmode_pending,
1164f3bd5173SRasesh Mody 			rxf->rxmode_pending_bitmask);
1165f3bd5173SRasesh Mody 	} else {
1166f3bd5173SRasesh Mody 		/* Schedule enable */
1167f3bd5173SRasesh Mody 		promisc_enable(rxf->rxmode_pending,
1168f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1169f3bd5173SRasesh Mody 		bna->promisc_rid = rxf->rx->rid;
1170f3bd5173SRasesh Mody 		ret = 1;
1171f3bd5173SRasesh Mody 	}
1172f3bd5173SRasesh Mody 
1173f3bd5173SRasesh Mody 	return ret;
1174f3bd5173SRasesh Mody }
1175f3bd5173SRasesh Mody 
1176f3bd5173SRasesh Mody static int
bna_rxf_promisc_disable(struct bna_rxf * rxf)1177f3bd5173SRasesh Mody bna_rxf_promisc_disable(struct bna_rxf *rxf)
1178f3bd5173SRasesh Mody {
1179f3bd5173SRasesh Mody 	struct bna *bna = rxf->rx->bna;
1180f3bd5173SRasesh Mody 	int ret = 0;
1181f3bd5173SRasesh Mody 
1182f3bd5173SRasesh Mody 	if (is_promisc_disable(rxf->rxmode_pending,
1183f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask) ||
1184f3bd5173SRasesh Mody 		(!(rxf->rxmode_active & BNA_RXMODE_PROMISC))) {
1185f3bd5173SRasesh Mody 		/* Do nothing if pending disable or already disabled */
1186f3bd5173SRasesh Mody 	} else if (is_promisc_enable(rxf->rxmode_pending,
1187f3bd5173SRasesh Mody 					rxf->rxmode_pending_bitmask)) {
1188f3bd5173SRasesh Mody 		/* Turn off pending enable command */
1189f3bd5173SRasesh Mody 		promisc_inactive(rxf->rxmode_pending,
1190f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1191f3bd5173SRasesh Mody 		bna->promisc_rid = BFI_INVALID_RID;
1192f3bd5173SRasesh Mody 	} else if (rxf->rxmode_active & BNA_RXMODE_PROMISC) {
1193f3bd5173SRasesh Mody 		/* Schedule disable */
1194f3bd5173SRasesh Mody 		promisc_disable(rxf->rxmode_pending,
1195f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1196f3bd5173SRasesh Mody 		ret = 1;
1197f3bd5173SRasesh Mody 	}
1198f3bd5173SRasesh Mody 
1199f3bd5173SRasesh Mody 	return ret;
1200f3bd5173SRasesh Mody }
1201f3bd5173SRasesh Mody 
1202f3bd5173SRasesh Mody static int
bna_rxf_allmulti_enable(struct bna_rxf * rxf)1203f3bd5173SRasesh Mody bna_rxf_allmulti_enable(struct bna_rxf *rxf)
1204f3bd5173SRasesh Mody {
1205f3bd5173SRasesh Mody 	int ret = 0;
1206f3bd5173SRasesh Mody 
1207f3bd5173SRasesh Mody 	if (is_allmulti_enable(rxf->rxmode_pending,
1208f3bd5173SRasesh Mody 			rxf->rxmode_pending_bitmask) ||
1209f3bd5173SRasesh Mody 			(rxf->rxmode_active & BNA_RXMODE_ALLMULTI)) {
1210f3bd5173SRasesh Mody 		/* Do nothing if pending enable or already enabled */
1211f3bd5173SRasesh Mody 	} else if (is_allmulti_disable(rxf->rxmode_pending,
1212f3bd5173SRasesh Mody 					rxf->rxmode_pending_bitmask)) {
1213f3bd5173SRasesh Mody 		/* Turn off pending disable command */
1214f3bd5173SRasesh Mody 		allmulti_inactive(rxf->rxmode_pending,
1215f3bd5173SRasesh Mody 			rxf->rxmode_pending_bitmask);
1216f3bd5173SRasesh Mody 	} else {
1217f3bd5173SRasesh Mody 		/* Schedule enable */
1218f3bd5173SRasesh Mody 		allmulti_enable(rxf->rxmode_pending,
1219f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1220f3bd5173SRasesh Mody 		ret = 1;
1221f3bd5173SRasesh Mody 	}
1222f3bd5173SRasesh Mody 
1223f3bd5173SRasesh Mody 	return ret;
1224f3bd5173SRasesh Mody }
1225f3bd5173SRasesh Mody 
1226f3bd5173SRasesh Mody static int
bna_rxf_allmulti_disable(struct bna_rxf * rxf)1227f3bd5173SRasesh Mody bna_rxf_allmulti_disable(struct bna_rxf *rxf)
1228f3bd5173SRasesh Mody {
1229f3bd5173SRasesh Mody 	int ret = 0;
1230f3bd5173SRasesh Mody 
1231f3bd5173SRasesh Mody 	if (is_allmulti_disable(rxf->rxmode_pending,
1232f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask) ||
1233f3bd5173SRasesh Mody 		(!(rxf->rxmode_active & BNA_RXMODE_ALLMULTI))) {
1234f3bd5173SRasesh Mody 		/* Do nothing if pending disable or already disabled */
1235f3bd5173SRasesh Mody 	} else if (is_allmulti_enable(rxf->rxmode_pending,
1236f3bd5173SRasesh Mody 					rxf->rxmode_pending_bitmask)) {
1237f3bd5173SRasesh Mody 		/* Turn off pending enable command */
1238f3bd5173SRasesh Mody 		allmulti_inactive(rxf->rxmode_pending,
1239f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1240f3bd5173SRasesh Mody 	} else if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) {
1241f3bd5173SRasesh Mody 		/* Schedule disable */
1242f3bd5173SRasesh Mody 		allmulti_disable(rxf->rxmode_pending,
1243f3bd5173SRasesh Mody 				rxf->rxmode_pending_bitmask);
1244f3bd5173SRasesh Mody 		ret = 1;
1245f3bd5173SRasesh Mody 	}
1246f3bd5173SRasesh Mody 
1247f3bd5173SRasesh Mody 	return ret;
1248f3bd5173SRasesh Mody }
1249f3bd5173SRasesh Mody 
1250f3bd5173SRasesh Mody static int
bna_rxf_vlan_strip_cfg_apply(struct bna_rxf * rxf)1251f3bd5173SRasesh Mody bna_rxf_vlan_strip_cfg_apply(struct bna_rxf *rxf)
1252f3bd5173SRasesh Mody {
1253f3bd5173SRasesh Mody 	if (rxf->vlan_strip_pending) {
1254f3bd5173SRasesh Mody 			rxf->vlan_strip_pending = false;
1255f3bd5173SRasesh Mody 			bna_bfi_vlan_strip_enable(rxf);
1256f3bd5173SRasesh Mody 			return 1;
1257f3bd5173SRasesh Mody 	}
1258f3bd5173SRasesh Mody 
1259f3bd5173SRasesh Mody 	return 0;
1260f3bd5173SRasesh Mody }
1261f3bd5173SRasesh Mody 
12621aa8b471SBen Hutchings /* RX */
1263f3bd5173SRasesh Mody 
1264f3bd5173SRasesh Mody #define	BNA_GET_RXQS(qcfg)	(((qcfg)->rxp_type == BNA_RXP_SINGLE) ?	\
1265f3bd5173SRasesh Mody 	(qcfg)->num_paths : ((qcfg)->num_paths * 2))
1266f3bd5173SRasesh Mody 
1267f3bd5173SRasesh Mody #define	SIZE_TO_PAGES(size)	(((size) >> PAGE_SHIFT) + ((((size) &\
1268f3bd5173SRasesh Mody 	(PAGE_SIZE - 1)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
1269f3bd5173SRasesh Mody 
1270f3bd5173SRasesh Mody #define	call_rx_stop_cbfn(rx)						\
1271f3bd5173SRasesh Mody do {								    \
1272f3bd5173SRasesh Mody 	if ((rx)->stop_cbfn) {						\
1273f3bd5173SRasesh Mody 		void (*cbfn)(void *, struct bna_rx *);	  \
1274f3bd5173SRasesh Mody 		void *cbarg;					    \
1275f3bd5173SRasesh Mody 		cbfn = (rx)->stop_cbfn;				 \
1276f3bd5173SRasesh Mody 		cbarg = (rx)->stop_cbarg;			       \
1277f3bd5173SRasesh Mody 		(rx)->stop_cbfn = NULL;					\
1278f3bd5173SRasesh Mody 		(rx)->stop_cbarg = NULL;				\
1279f3bd5173SRasesh Mody 		cbfn(cbarg, rx);					\
1280f3bd5173SRasesh Mody 	}							       \
1281f3bd5173SRasesh Mody } while (0)
1282f3bd5173SRasesh Mody 
12835bcf6ac0SRasesh Mody #define call_rx_stall_cbfn(rx)						\
12845bcf6ac0SRasesh Mody do {									\
12855bcf6ac0SRasesh Mody 	if ((rx)->rx_stall_cbfn)					\
12865bcf6ac0SRasesh Mody 		(rx)->rx_stall_cbfn((rx)->bna->bnad, (rx));		\
12875bcf6ac0SRasesh Mody } while (0)
12885bcf6ac0SRasesh Mody 
1289f3bd5173SRasesh Mody #define bfi_enet_datapath_q_init(bfi_q, bna_qpt)			\
1290f3bd5173SRasesh Mody do {									\
1291f3bd5173SRasesh Mody 	struct bna_dma_addr cur_q_addr =				\
1292f3bd5173SRasesh Mody 		*((struct bna_dma_addr *)((bna_qpt)->kv_qpt_ptr));	\
1293f3bd5173SRasesh Mody 	(bfi_q)->pg_tbl.a32.addr_lo = (bna_qpt)->hw_qpt_ptr.lsb;	\
1294f3bd5173SRasesh Mody 	(bfi_q)->pg_tbl.a32.addr_hi = (bna_qpt)->hw_qpt_ptr.msb;	\
1295f3bd5173SRasesh Mody 	(bfi_q)->first_entry.a32.addr_lo = cur_q_addr.lsb;		\
1296f3bd5173SRasesh Mody 	(bfi_q)->first_entry.a32.addr_hi = cur_q_addr.msb;		\
1297f3bd5173SRasesh Mody 	(bfi_q)->pages = htons((u16)(bna_qpt)->page_count);	\
1298f3bd5173SRasesh Mody 	(bfi_q)->page_sz = htons((u16)(bna_qpt)->page_size);\
1299f3bd5173SRasesh Mody } while (0)
1300f3bd5173SRasesh Mody 
1301f3bd5173SRasesh Mody static void bna_bfi_rx_enet_start(struct bna_rx *rx);
1302f3bd5173SRasesh Mody static void bna_rx_enet_stop(struct bna_rx *rx);
1303f3bd5173SRasesh Mody static void bna_rx_mod_cb_rx_stopped(void *arg, struct bna_rx *rx);
1304f3bd5173SRasesh Mody 
1305f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_rx, stopped,
1306f3bd5173SRasesh Mody 	struct bna_rx, enum bna_rx_event);
1307f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_rx, start_wait,
1308f3bd5173SRasesh Mody 	struct bna_rx, enum bna_rx_event);
1309215a64a2SRasesh Mody bfa_fsm_state_decl(bna_rx, start_stop_wait,
1310215a64a2SRasesh Mody 	struct bna_rx, enum bna_rx_event);
1311f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_rx, rxf_start_wait,
1312f3bd5173SRasesh Mody 	struct bna_rx, enum bna_rx_event);
1313f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_rx, started,
1314f3bd5173SRasesh Mody 	struct bna_rx, enum bna_rx_event);
1315f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_rx, rxf_stop_wait,
1316f3bd5173SRasesh Mody 	struct bna_rx, enum bna_rx_event);
1317f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_rx, stop_wait,
1318f3bd5173SRasesh Mody 	struct bna_rx, enum bna_rx_event);
1319f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_rx, cleanup_wait,
1320f3bd5173SRasesh Mody 	struct bna_rx, enum bna_rx_event);
1321f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_rx, failed,
1322f3bd5173SRasesh Mody 	struct bna_rx, enum bna_rx_event);
1323f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_rx, quiesce_wait,
1324f3bd5173SRasesh Mody 	struct bna_rx, enum bna_rx_event);
1325f3bd5173SRasesh Mody 
bna_rx_sm_stopped_entry(struct bna_rx * rx)1326f3bd5173SRasesh Mody static void bna_rx_sm_stopped_entry(struct bna_rx *rx)
1327f3bd5173SRasesh Mody {
1328f3bd5173SRasesh Mody 	call_rx_stop_cbfn(rx);
1329f3bd5173SRasesh Mody }
1330f3bd5173SRasesh Mody 
bna_rx_sm_stopped(struct bna_rx * rx,enum bna_rx_event event)1331f3bd5173SRasesh Mody static void bna_rx_sm_stopped(struct bna_rx *rx,
1332f3bd5173SRasesh Mody 				enum bna_rx_event event)
1333f3bd5173SRasesh Mody {
1334f3bd5173SRasesh Mody 	switch (event) {
1335f3bd5173SRasesh Mody 	case RX_E_START:
1336f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_start_wait);
1337f3bd5173SRasesh Mody 		break;
1338f3bd5173SRasesh Mody 
1339f3bd5173SRasesh Mody 	case RX_E_STOP:
1340f3bd5173SRasesh Mody 		call_rx_stop_cbfn(rx);
1341f3bd5173SRasesh Mody 		break;
1342f3bd5173SRasesh Mody 
1343f3bd5173SRasesh Mody 	case RX_E_FAIL:
1344f3bd5173SRasesh Mody 		/* no-op */
1345f3bd5173SRasesh Mody 		break;
1346f3bd5173SRasesh Mody 
1347f3bd5173SRasesh Mody 	default:
1348f3bd5173SRasesh Mody 		bfa_sm_fault(event);
1349f3bd5173SRasesh Mody 		break;
1350f3bd5173SRasesh Mody 	}
1351f3bd5173SRasesh Mody }
1352f3bd5173SRasesh Mody 
bna_rx_sm_start_wait_entry(struct bna_rx * rx)1353f3bd5173SRasesh Mody static void bna_rx_sm_start_wait_entry(struct bna_rx *rx)
1354f3bd5173SRasesh Mody {
1355f3bd5173SRasesh Mody 	bna_bfi_rx_enet_start(rx);
1356f3bd5173SRasesh Mody }
1357f3bd5173SRasesh Mody 
13587f4341feSJingoo Han static void
bna_rx_sm_stop_wait_entry(struct bna_rx * rx)1359f3bd5173SRasesh Mody bna_rx_sm_stop_wait_entry(struct bna_rx *rx)
1360f3bd5173SRasesh Mody {
1361f3bd5173SRasesh Mody }
1362f3bd5173SRasesh Mody 
1363f3bd5173SRasesh Mody static void
bna_rx_sm_stop_wait(struct bna_rx * rx,enum bna_rx_event event)1364f3bd5173SRasesh Mody bna_rx_sm_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
1365f3bd5173SRasesh Mody {
1366f3bd5173SRasesh Mody 	switch (event) {
1367f3bd5173SRasesh Mody 	case RX_E_FAIL:
1368f3bd5173SRasesh Mody 	case RX_E_STOPPED:
1369f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_cleanup_wait);
1370f3bd5173SRasesh Mody 		rx->rx_cleanup_cbfn(rx->bna->bnad, rx);
1371f3bd5173SRasesh Mody 		break;
1372f3bd5173SRasesh Mody 
1373f3bd5173SRasesh Mody 	case RX_E_STARTED:
1374f3bd5173SRasesh Mody 		bna_rx_enet_stop(rx);
1375f3bd5173SRasesh Mody 		break;
1376f3bd5173SRasesh Mody 
1377f3bd5173SRasesh Mody 	default:
1378f3bd5173SRasesh Mody 		bfa_sm_fault(event);
1379f3bd5173SRasesh Mody 		break;
1380f3bd5173SRasesh Mody 	}
1381f3bd5173SRasesh Mody }
1382f3bd5173SRasesh Mody 
bna_rx_sm_start_wait(struct bna_rx * rx,enum bna_rx_event event)1383f3bd5173SRasesh Mody static void bna_rx_sm_start_wait(struct bna_rx *rx,
1384f3bd5173SRasesh Mody 				enum bna_rx_event event)
1385f3bd5173SRasesh Mody {
1386f3bd5173SRasesh Mody 	switch (event) {
1387f3bd5173SRasesh Mody 	case RX_E_STOP:
1388215a64a2SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_start_stop_wait);
1389f3bd5173SRasesh Mody 		break;
1390f3bd5173SRasesh Mody 
1391f3bd5173SRasesh Mody 	case RX_E_FAIL:
1392f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_stopped);
1393f3bd5173SRasesh Mody 		break;
1394f3bd5173SRasesh Mody 
1395f3bd5173SRasesh Mody 	case RX_E_STARTED:
1396f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_rxf_start_wait);
1397f3bd5173SRasesh Mody 		break;
1398f3bd5173SRasesh Mody 
1399f3bd5173SRasesh Mody 	default:
1400f3bd5173SRasesh Mody 		bfa_sm_fault(event);
1401f3bd5173SRasesh Mody 		break;
1402f3bd5173SRasesh Mody 	}
1403f3bd5173SRasesh Mody }
1404f3bd5173SRasesh Mody 
bna_rx_sm_rxf_start_wait_entry(struct bna_rx * rx)1405f3bd5173SRasesh Mody static void bna_rx_sm_rxf_start_wait_entry(struct bna_rx *rx)
1406f3bd5173SRasesh Mody {
1407f3bd5173SRasesh Mody 	rx->rx_post_cbfn(rx->bna->bnad, rx);
1408f3bd5173SRasesh Mody 	bna_rxf_start(&rx->rxf);
1409f3bd5173SRasesh Mody }
1410f3bd5173SRasesh Mody 
14117f4341feSJingoo Han static void
bna_rx_sm_rxf_stop_wait_entry(struct bna_rx * rx)1412f3bd5173SRasesh Mody bna_rx_sm_rxf_stop_wait_entry(struct bna_rx *rx)
1413f3bd5173SRasesh Mody {
1414f3bd5173SRasesh Mody }
1415f3bd5173SRasesh Mody 
1416f3bd5173SRasesh Mody static void
bna_rx_sm_rxf_stop_wait(struct bna_rx * rx,enum bna_rx_event event)1417f3bd5173SRasesh Mody bna_rx_sm_rxf_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
1418f3bd5173SRasesh Mody {
1419f3bd5173SRasesh Mody 	switch (event) {
1420f3bd5173SRasesh Mody 	case RX_E_FAIL:
1421f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_cleanup_wait);
1422f3bd5173SRasesh Mody 		bna_rxf_fail(&rx->rxf);
14235bcf6ac0SRasesh Mody 		call_rx_stall_cbfn(rx);
1424f3bd5173SRasesh Mody 		rx->rx_cleanup_cbfn(rx->bna->bnad, rx);
1425f3bd5173SRasesh Mody 		break;
1426f3bd5173SRasesh Mody 
1427f3bd5173SRasesh Mody 	case RX_E_RXF_STARTED:
1428f3bd5173SRasesh Mody 		bna_rxf_stop(&rx->rxf);
1429f3bd5173SRasesh Mody 		break;
1430f3bd5173SRasesh Mody 
1431f3bd5173SRasesh Mody 	case RX_E_RXF_STOPPED:
1432f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_stop_wait);
14335bcf6ac0SRasesh Mody 		call_rx_stall_cbfn(rx);
1434f3bd5173SRasesh Mody 		bna_rx_enet_stop(rx);
1435f3bd5173SRasesh Mody 		break;
1436f3bd5173SRasesh Mody 
1437f3bd5173SRasesh Mody 	default:
1438f3bd5173SRasesh Mody 		bfa_sm_fault(event);
1439f3bd5173SRasesh Mody 		break;
1440f3bd5173SRasesh Mody 	}
1441f3bd5173SRasesh Mody 
1442f3bd5173SRasesh Mody }
1443f3bd5173SRasesh Mody 
1444215a64a2SRasesh Mody static void
bna_rx_sm_start_stop_wait_entry(struct bna_rx * rx)1445215a64a2SRasesh Mody bna_rx_sm_start_stop_wait_entry(struct bna_rx *rx)
1446215a64a2SRasesh Mody {
1447215a64a2SRasesh Mody }
1448215a64a2SRasesh Mody 
1449215a64a2SRasesh Mody static void
bna_rx_sm_start_stop_wait(struct bna_rx * rx,enum bna_rx_event event)1450215a64a2SRasesh Mody bna_rx_sm_start_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
1451215a64a2SRasesh Mody {
1452215a64a2SRasesh Mody 	switch (event) {
1453215a64a2SRasesh Mody 	case RX_E_FAIL:
1454215a64a2SRasesh Mody 	case RX_E_STOPPED:
1455215a64a2SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_stopped);
1456215a64a2SRasesh Mody 		break;
1457215a64a2SRasesh Mody 
1458215a64a2SRasesh Mody 	case RX_E_STARTED:
1459215a64a2SRasesh Mody 		bna_rx_enet_stop(rx);
1460215a64a2SRasesh Mody 		break;
1461215a64a2SRasesh Mody 
1462215a64a2SRasesh Mody 	default:
1463215a64a2SRasesh Mody 		bfa_sm_fault(event);
1464215a64a2SRasesh Mody 	}
1465215a64a2SRasesh Mody }
1466215a64a2SRasesh Mody 
14677f4341feSJingoo Han static void
bna_rx_sm_started_entry(struct bna_rx * rx)1468f3bd5173SRasesh Mody bna_rx_sm_started_entry(struct bna_rx *rx)
1469f3bd5173SRasesh Mody {
1470f3bd5173SRasesh Mody 	struct bna_rxp *rxp;
1471f3bd5173SRasesh Mody 	int is_regular = (rx->type == BNA_RX_T_REGULAR);
1472f3bd5173SRasesh Mody 
1473f3bd5173SRasesh Mody 	/* Start IB */
147416712c53SIvan Vecera 	list_for_each_entry(rxp, &rx->rxp_q, qe)
1475f3bd5173SRasesh Mody 		bna_ib_start(rx->bna, &rxp->cq.ib, is_regular);
1476f3bd5173SRasesh Mody 
1477f3bd5173SRasesh Mody 	bna_ethport_cb_rx_started(&rx->bna->ethport);
1478f3bd5173SRasesh Mody }
1479f3bd5173SRasesh Mody 
1480f3bd5173SRasesh Mody static void
bna_rx_sm_started(struct bna_rx * rx,enum bna_rx_event event)1481f3bd5173SRasesh Mody bna_rx_sm_started(struct bna_rx *rx, enum bna_rx_event event)
1482f3bd5173SRasesh Mody {
1483f3bd5173SRasesh Mody 	switch (event) {
1484f3bd5173SRasesh Mody 	case RX_E_STOP:
1485f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
1486f3bd5173SRasesh Mody 		bna_ethport_cb_rx_stopped(&rx->bna->ethport);
1487f3bd5173SRasesh Mody 		bna_rxf_stop(&rx->rxf);
1488f3bd5173SRasesh Mody 		break;
1489f3bd5173SRasesh Mody 
1490f3bd5173SRasesh Mody 	case RX_E_FAIL:
1491f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_failed);
1492f3bd5173SRasesh Mody 		bna_ethport_cb_rx_stopped(&rx->bna->ethport);
1493f3bd5173SRasesh Mody 		bna_rxf_fail(&rx->rxf);
14945bcf6ac0SRasesh Mody 		call_rx_stall_cbfn(rx);
1495f3bd5173SRasesh Mody 		rx->rx_cleanup_cbfn(rx->bna->bnad, rx);
1496f3bd5173SRasesh Mody 		break;
1497f3bd5173SRasesh Mody 
1498f3bd5173SRasesh Mody 	default:
1499f3bd5173SRasesh Mody 		bfa_sm_fault(event);
1500f3bd5173SRasesh Mody 		break;
1501f3bd5173SRasesh Mody 	}
1502f3bd5173SRasesh Mody }
1503f3bd5173SRasesh Mody 
bna_rx_sm_rxf_start_wait(struct bna_rx * rx,enum bna_rx_event event)1504f3bd5173SRasesh Mody static void bna_rx_sm_rxf_start_wait(struct bna_rx *rx,
1505f3bd5173SRasesh Mody 				enum bna_rx_event event)
1506f3bd5173SRasesh Mody {
1507f3bd5173SRasesh Mody 	switch (event) {
1508f3bd5173SRasesh Mody 	case RX_E_STOP:
1509f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
1510f3bd5173SRasesh Mody 		break;
1511f3bd5173SRasesh Mody 
1512f3bd5173SRasesh Mody 	case RX_E_FAIL:
1513f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_failed);
1514f3bd5173SRasesh Mody 		bna_rxf_fail(&rx->rxf);
15155bcf6ac0SRasesh Mody 		call_rx_stall_cbfn(rx);
1516f3bd5173SRasesh Mody 		rx->rx_cleanup_cbfn(rx->bna->bnad, rx);
1517f3bd5173SRasesh Mody 		break;
1518f3bd5173SRasesh Mody 
1519f3bd5173SRasesh Mody 	case RX_E_RXF_STARTED:
1520f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_started);
1521f3bd5173SRasesh Mody 		break;
1522f3bd5173SRasesh Mody 
1523f3bd5173SRasesh Mody 	default:
1524f3bd5173SRasesh Mody 		bfa_sm_fault(event);
1525f3bd5173SRasesh Mody 		break;
1526f3bd5173SRasesh Mody 	}
1527f3bd5173SRasesh Mody }
1528f3bd5173SRasesh Mody 
15297f4341feSJingoo Han static void
bna_rx_sm_cleanup_wait_entry(struct bna_rx * rx)1530f3bd5173SRasesh Mody bna_rx_sm_cleanup_wait_entry(struct bna_rx *rx)
1531f3bd5173SRasesh Mody {
1532f3bd5173SRasesh Mody }
1533f3bd5173SRasesh Mody 
15347f4341feSJingoo Han static void
bna_rx_sm_cleanup_wait(struct bna_rx * rx,enum bna_rx_event event)1535f3bd5173SRasesh Mody bna_rx_sm_cleanup_wait(struct bna_rx *rx, enum bna_rx_event event)
1536f3bd5173SRasesh Mody {
1537f3bd5173SRasesh Mody 	switch (event) {
1538f3bd5173SRasesh Mody 	case RX_E_FAIL:
1539f3bd5173SRasesh Mody 	case RX_E_RXF_STOPPED:
1540f3bd5173SRasesh Mody 		/* No-op */
1541f3bd5173SRasesh Mody 		break;
1542f3bd5173SRasesh Mody 
1543f3bd5173SRasesh Mody 	case RX_E_CLEANUP_DONE:
1544f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_stopped);
1545f3bd5173SRasesh Mody 		break;
1546f3bd5173SRasesh Mody 
1547f3bd5173SRasesh Mody 	default:
1548f3bd5173SRasesh Mody 		bfa_sm_fault(event);
1549f3bd5173SRasesh Mody 		break;
1550f3bd5173SRasesh Mody 	}
1551f3bd5173SRasesh Mody }
1552f3bd5173SRasesh Mody 
1553f3bd5173SRasesh Mody static void
bna_rx_sm_failed_entry(struct bna_rx * rx)1554f3bd5173SRasesh Mody bna_rx_sm_failed_entry(struct bna_rx *rx)
1555f3bd5173SRasesh Mody {
1556f3bd5173SRasesh Mody }
1557f3bd5173SRasesh Mody 
1558f3bd5173SRasesh Mody static void
bna_rx_sm_failed(struct bna_rx * rx,enum bna_rx_event event)1559f3bd5173SRasesh Mody bna_rx_sm_failed(struct bna_rx *rx, enum bna_rx_event event)
1560f3bd5173SRasesh Mody {
1561f3bd5173SRasesh Mody 	switch (event) {
1562f3bd5173SRasesh Mody 	case RX_E_START:
1563f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_quiesce_wait);
1564f3bd5173SRasesh Mody 		break;
1565f3bd5173SRasesh Mody 
1566f3bd5173SRasesh Mody 	case RX_E_STOP:
1567f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_cleanup_wait);
1568f3bd5173SRasesh Mody 		break;
1569f3bd5173SRasesh Mody 
1570f3bd5173SRasesh Mody 	case RX_E_FAIL:
1571f3bd5173SRasesh Mody 	case RX_E_RXF_STARTED:
1572f3bd5173SRasesh Mody 	case RX_E_RXF_STOPPED:
1573f3bd5173SRasesh Mody 		/* No-op */
1574f3bd5173SRasesh Mody 		break;
1575f3bd5173SRasesh Mody 
1576f3bd5173SRasesh Mody 	case RX_E_CLEANUP_DONE:
1577f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_stopped);
1578f3bd5173SRasesh Mody 		break;
1579f3bd5173SRasesh Mody 
1580f3bd5173SRasesh Mody 	default:
1581f3bd5173SRasesh Mody 		bfa_sm_fault(event);
1582f3bd5173SRasesh Mody 		break;
1583f3bd5173SRasesh Mody }	}
1584f3bd5173SRasesh Mody 
1585f3bd5173SRasesh Mody static void
bna_rx_sm_quiesce_wait_entry(struct bna_rx * rx)1586f3bd5173SRasesh Mody bna_rx_sm_quiesce_wait_entry(struct bna_rx *rx)
1587f3bd5173SRasesh Mody {
1588f3bd5173SRasesh Mody }
1589f3bd5173SRasesh Mody 
1590f3bd5173SRasesh Mody static void
bna_rx_sm_quiesce_wait(struct bna_rx * rx,enum bna_rx_event event)1591f3bd5173SRasesh Mody bna_rx_sm_quiesce_wait(struct bna_rx *rx, enum bna_rx_event event)
1592f3bd5173SRasesh Mody {
1593f3bd5173SRasesh Mody 	switch (event) {
1594f3bd5173SRasesh Mody 	case RX_E_STOP:
1595f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_cleanup_wait);
1596f3bd5173SRasesh Mody 		break;
1597f3bd5173SRasesh Mody 
1598f3bd5173SRasesh Mody 	case RX_E_FAIL:
1599f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_failed);
1600f3bd5173SRasesh Mody 		break;
1601f3bd5173SRasesh Mody 
1602f3bd5173SRasesh Mody 	case RX_E_CLEANUP_DONE:
1603f3bd5173SRasesh Mody 		bfa_fsm_set_state(rx, bna_rx_sm_start_wait);
1604f3bd5173SRasesh Mody 		break;
1605f3bd5173SRasesh Mody 
1606f3bd5173SRasesh Mody 	default:
1607f3bd5173SRasesh Mody 		bfa_sm_fault(event);
1608f3bd5173SRasesh Mody 		break;
1609f3bd5173SRasesh Mody 	}
1610f3bd5173SRasesh Mody }
1611f3bd5173SRasesh Mody 
1612f3bd5173SRasesh Mody static void
bna_bfi_rx_enet_start(struct bna_rx * rx)1613f3bd5173SRasesh Mody bna_bfi_rx_enet_start(struct bna_rx *rx)
1614f3bd5173SRasesh Mody {
1615f3bd5173SRasesh Mody 	struct bfi_enet_rx_cfg_req *cfg_req = &rx->bfi_enet_cmd.cfg_req;
1616f3bd5173SRasesh Mody 	struct bna_rxp *rxp = NULL;
1617f3bd5173SRasesh Mody 	struct bna_rxq *q0 = NULL, *q1 = NULL;
1618f3bd5173SRasesh Mody 	int i;
1619f3bd5173SRasesh Mody 
1620f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(cfg_req->mh, BFI_MC_ENET,
1621f3bd5173SRasesh Mody 		BFI_ENET_H2I_RX_CFG_SET_REQ, 0, rx->rid);
1622f3bd5173SRasesh Mody 	cfg_req->mh.num_entries = htons(
1623f3bd5173SRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_rx_cfg_req)));
1624f3bd5173SRasesh Mody 
1625e29aa339SRasesh Mody 	cfg_req->rx_cfg.frame_size = bna_enet_mtu_get(&rx->bna->enet);
1626f3bd5173SRasesh Mody 	cfg_req->num_queue_sets = rx->num_paths;
16272b26fb95SIvan Vecera 	for (i = 0; i < rx->num_paths; i++) {
16282b26fb95SIvan Vecera 		rxp = rxp ? list_next_entry(rxp, qe)
16292b26fb95SIvan Vecera 			: list_first_entry(&rx->rxp_q, struct bna_rxp, qe);
1630f3bd5173SRasesh Mody 		GET_RXQS(rxp, q0, q1);
1631f3bd5173SRasesh Mody 		switch (rxp->type) {
1632f3bd5173SRasesh Mody 		case BNA_RXP_SLR:
1633f3bd5173SRasesh Mody 		case BNA_RXP_HDS:
1634f3bd5173SRasesh Mody 			/* Small RxQ */
1635f3bd5173SRasesh Mody 			bfi_enet_datapath_q_init(&cfg_req->q_cfg[i].qs.q,
1636f3bd5173SRasesh Mody 						&q1->qpt);
1637f3bd5173SRasesh Mody 			cfg_req->q_cfg[i].qs.rx_buffer_size =
1638f3bd5173SRasesh Mody 				htons((u16)q1->buffer_size);
1639df561f66SGustavo A. R. Silva 			fallthrough;
1640f3bd5173SRasesh Mody 
1641f3bd5173SRasesh Mody 		case BNA_RXP_SINGLE:
1642f3bd5173SRasesh Mody 			/* Large/Single RxQ */
1643f3bd5173SRasesh Mody 			bfi_enet_datapath_q_init(&cfg_req->q_cfg[i].ql.q,
1644f3bd5173SRasesh Mody 						&q0->qpt);
1645e29aa339SRasesh Mody 			if (q0->multi_buffer)
1646e29aa339SRasesh Mody 				/* multi-buffer is enabled by allocating
1647e29aa339SRasesh Mody 				 * a new rx with new set of resources.
1648e29aa339SRasesh Mody 				 * q0->buffer_size should be initialized to
1649e29aa339SRasesh Mody 				 * fragment size.
1650e29aa339SRasesh Mody 				 */
1651e29aa339SRasesh Mody 				cfg_req->rx_cfg.multi_buffer =
1652e29aa339SRasesh Mody 					BNA_STATUS_T_ENABLED;
1653e29aa339SRasesh Mody 			else
1654f3bd5173SRasesh Mody 				q0->buffer_size =
1655f3bd5173SRasesh Mody 					bna_enet_mtu_get(&rx->bna->enet);
1656f3bd5173SRasesh Mody 			cfg_req->q_cfg[i].ql.rx_buffer_size =
1657f3bd5173SRasesh Mody 				htons((u16)q0->buffer_size);
1658f3bd5173SRasesh Mody 			break;
1659f3bd5173SRasesh Mody 
1660f3bd5173SRasesh Mody 		default:
1661f3bd5173SRasesh Mody 			BUG_ON(1);
1662f3bd5173SRasesh Mody 		}
1663f3bd5173SRasesh Mody 
1664f3bd5173SRasesh Mody 		bfi_enet_datapath_q_init(&cfg_req->q_cfg[i].cq.q,
1665f3bd5173SRasesh Mody 					&rxp->cq.qpt);
1666f3bd5173SRasesh Mody 
1667f3bd5173SRasesh Mody 		cfg_req->q_cfg[i].ib.index_addr.a32.addr_lo =
1668f3bd5173SRasesh Mody 			rxp->cq.ib.ib_seg_host_addr.lsb;
1669f3bd5173SRasesh Mody 		cfg_req->q_cfg[i].ib.index_addr.a32.addr_hi =
1670f3bd5173SRasesh Mody 			rxp->cq.ib.ib_seg_host_addr.msb;
1671f3bd5173SRasesh Mody 		cfg_req->q_cfg[i].ib.intr.msix_index =
1672f3bd5173SRasesh Mody 			htons((u16)rxp->cq.ib.intr_vector);
1673f3bd5173SRasesh Mody 	}
1674f3bd5173SRasesh Mody 
1675f3bd5173SRasesh Mody 	cfg_req->ib_cfg.int_pkt_dma = BNA_STATUS_T_DISABLED;
1676f3bd5173SRasesh Mody 	cfg_req->ib_cfg.int_enabled = BNA_STATUS_T_ENABLED;
1677f3bd5173SRasesh Mody 	cfg_req->ib_cfg.int_pkt_enabled = BNA_STATUS_T_DISABLED;
1678f3bd5173SRasesh Mody 	cfg_req->ib_cfg.continuous_coalescing = BNA_STATUS_T_DISABLED;
1679f3bd5173SRasesh Mody 	cfg_req->ib_cfg.msix = (rxp->cq.ib.intr_type == BNA_INTR_T_MSIX)
1680f3bd5173SRasesh Mody 				? BNA_STATUS_T_ENABLED :
1681f3bd5173SRasesh Mody 				BNA_STATUS_T_DISABLED;
1682f3bd5173SRasesh Mody 	cfg_req->ib_cfg.coalescing_timeout =
1683f3bd5173SRasesh Mody 			htonl((u32)rxp->cq.ib.coalescing_timeo);
1684f3bd5173SRasesh Mody 	cfg_req->ib_cfg.inter_pkt_timeout =
1685f3bd5173SRasesh Mody 			htonl((u32)rxp->cq.ib.interpkt_timeo);
1686f3bd5173SRasesh Mody 	cfg_req->ib_cfg.inter_pkt_count = (u8)rxp->cq.ib.interpkt_count;
1687f3bd5173SRasesh Mody 
1688f3bd5173SRasesh Mody 	switch (rxp->type) {
1689f3bd5173SRasesh Mody 	case BNA_RXP_SLR:
1690f3bd5173SRasesh Mody 		cfg_req->rx_cfg.rxq_type = BFI_ENET_RXQ_LARGE_SMALL;
1691f3bd5173SRasesh Mody 		break;
1692f3bd5173SRasesh Mody 
1693f3bd5173SRasesh Mody 	case BNA_RXP_HDS:
1694f3bd5173SRasesh Mody 		cfg_req->rx_cfg.rxq_type = BFI_ENET_RXQ_HDS;
1695f3bd5173SRasesh Mody 		cfg_req->rx_cfg.hds.type = rx->hds_cfg.hdr_type;
1696f3bd5173SRasesh Mody 		cfg_req->rx_cfg.hds.force_offset = rx->hds_cfg.forced_offset;
1697f3bd5173SRasesh Mody 		cfg_req->rx_cfg.hds.max_header_size = rx->hds_cfg.forced_offset;
1698f3bd5173SRasesh Mody 		break;
1699f3bd5173SRasesh Mody 
1700f3bd5173SRasesh Mody 	case BNA_RXP_SINGLE:
1701f3bd5173SRasesh Mody 		cfg_req->rx_cfg.rxq_type = BFI_ENET_RXQ_SINGLE;
1702f3bd5173SRasesh Mody 		break;
1703f3bd5173SRasesh Mody 
1704f3bd5173SRasesh Mody 	default:
1705f3bd5173SRasesh Mody 		BUG_ON(1);
1706f3bd5173SRasesh Mody 	}
1707f3bd5173SRasesh Mody 	cfg_req->rx_cfg.strip_vlan = rx->rxf.vlan_strip_status;
1708f3bd5173SRasesh Mody 
1709f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&rx->msgq_cmd, NULL, NULL,
1710f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_rx_cfg_req), &cfg_req->mh);
1711f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&rx->bna->msgq, &rx->msgq_cmd);
1712f3bd5173SRasesh Mody }
1713f3bd5173SRasesh Mody 
1714f3bd5173SRasesh Mody static void
bna_bfi_rx_enet_stop(struct bna_rx * rx)1715f3bd5173SRasesh Mody bna_bfi_rx_enet_stop(struct bna_rx *rx)
1716f3bd5173SRasesh Mody {
1717f3bd5173SRasesh Mody 	struct bfi_enet_req *req = &rx->bfi_enet_cmd.req;
1718f3bd5173SRasesh Mody 
1719f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
1720f3bd5173SRasesh Mody 		BFI_ENET_H2I_RX_CFG_CLR_REQ, 0, rx->rid);
1721f3bd5173SRasesh Mody 	req->mh.num_entries = htons(
1722f3bd5173SRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_req)));
1723f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&rx->msgq_cmd, NULL, NULL, sizeof(struct bfi_enet_req),
1724f3bd5173SRasesh Mody 		&req->mh);
1725f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&rx->bna->msgq, &rx->msgq_cmd);
1726f3bd5173SRasesh Mody }
1727f3bd5173SRasesh Mody 
1728f3bd5173SRasesh Mody static void
bna_rx_enet_stop(struct bna_rx * rx)1729f3bd5173SRasesh Mody bna_rx_enet_stop(struct bna_rx *rx)
1730f3bd5173SRasesh Mody {
1731f3bd5173SRasesh Mody 	struct bna_rxp *rxp;
1732f3bd5173SRasesh Mody 
1733f3bd5173SRasesh Mody 	/* Stop IB */
173416712c53SIvan Vecera 	list_for_each_entry(rxp, &rx->rxp_q, qe)
1735f3bd5173SRasesh Mody 		bna_ib_stop(rx->bna, &rxp->cq.ib);
1736f3bd5173SRasesh Mody 
1737f3bd5173SRasesh Mody 	bna_bfi_rx_enet_stop(rx);
1738f3bd5173SRasesh Mody }
1739f3bd5173SRasesh Mody 
1740f3bd5173SRasesh Mody static int
bna_rx_res_check(struct bna_rx_mod * rx_mod,struct bna_rx_config * rx_cfg)1741f3bd5173SRasesh Mody bna_rx_res_check(struct bna_rx_mod *rx_mod, struct bna_rx_config *rx_cfg)
1742f3bd5173SRasesh Mody {
1743f3bd5173SRasesh Mody 	if ((rx_mod->rx_free_count == 0) ||
1744f3bd5173SRasesh Mody 		(rx_mod->rxp_free_count == 0) ||
1745f3bd5173SRasesh Mody 		(rx_mod->rxq_free_count == 0))
1746f3bd5173SRasesh Mody 		return 0;
1747f3bd5173SRasesh Mody 
1748f3bd5173SRasesh Mody 	if (rx_cfg->rxp_type == BNA_RXP_SINGLE) {
1749f3bd5173SRasesh Mody 		if ((rx_mod->rxp_free_count < rx_cfg->num_paths) ||
1750f3bd5173SRasesh Mody 			(rx_mod->rxq_free_count < rx_cfg->num_paths))
1751f3bd5173SRasesh Mody 				return 0;
1752f3bd5173SRasesh Mody 	} else {
1753f3bd5173SRasesh Mody 		if ((rx_mod->rxp_free_count < rx_cfg->num_paths) ||
1754f3bd5173SRasesh Mody 			(rx_mod->rxq_free_count < (2 * rx_cfg->num_paths)))
1755f3bd5173SRasesh Mody 			return 0;
1756f3bd5173SRasesh Mody 	}
1757f3bd5173SRasesh Mody 
1758f3bd5173SRasesh Mody 	return 1;
1759f3bd5173SRasesh Mody }
1760f3bd5173SRasesh Mody 
1761f3bd5173SRasesh Mody static struct bna_rxq *
bna_rxq_get(struct bna_rx_mod * rx_mod)1762f3bd5173SRasesh Mody bna_rxq_get(struct bna_rx_mod *rx_mod)
1763f3bd5173SRasesh Mody {
1764f3bd5173SRasesh Mody 	struct bna_rxq *rxq = NULL;
1765f3bd5173SRasesh Mody 
17662b26fb95SIvan Vecera 	rxq = list_first_entry(&rx_mod->rxq_free_q, struct bna_rxq, qe);
17672b26fb95SIvan Vecera 	list_del(&rxq->qe);
1768f3bd5173SRasesh Mody 	rx_mod->rxq_free_count--;
1769f3bd5173SRasesh Mody 
1770f3bd5173SRasesh Mody 	return rxq;
1771f3bd5173SRasesh Mody }
1772f3bd5173SRasesh Mody 
1773f3bd5173SRasesh Mody static void
bna_rxq_put(struct bna_rx_mod * rx_mod,struct bna_rxq * rxq)1774f3bd5173SRasesh Mody bna_rxq_put(struct bna_rx_mod *rx_mod, struct bna_rxq *rxq)
1775f3bd5173SRasesh Mody {
1776f3bd5173SRasesh Mody 	list_add_tail(&rxq->qe, &rx_mod->rxq_free_q);
1777f3bd5173SRasesh Mody 	rx_mod->rxq_free_count++;
1778f3bd5173SRasesh Mody }
1779f3bd5173SRasesh Mody 
1780f3bd5173SRasesh Mody static struct bna_rxp *
bna_rxp_get(struct bna_rx_mod * rx_mod)1781f3bd5173SRasesh Mody bna_rxp_get(struct bna_rx_mod *rx_mod)
1782f3bd5173SRasesh Mody {
1783f3bd5173SRasesh Mody 	struct bna_rxp *rxp = NULL;
1784f3bd5173SRasesh Mody 
17852b26fb95SIvan Vecera 	rxp = list_first_entry(&rx_mod->rxp_free_q, struct bna_rxp, qe);
17862b26fb95SIvan Vecera 	list_del(&rxp->qe);
1787f3bd5173SRasesh Mody 	rx_mod->rxp_free_count--;
1788f3bd5173SRasesh Mody 
1789f3bd5173SRasesh Mody 	return rxp;
1790f3bd5173SRasesh Mody }
1791f3bd5173SRasesh Mody 
1792f3bd5173SRasesh Mody static void
bna_rxp_put(struct bna_rx_mod * rx_mod,struct bna_rxp * rxp)1793f3bd5173SRasesh Mody bna_rxp_put(struct bna_rx_mod *rx_mod, struct bna_rxp *rxp)
1794f3bd5173SRasesh Mody {
1795f3bd5173SRasesh Mody 	list_add_tail(&rxp->qe, &rx_mod->rxp_free_q);
1796f3bd5173SRasesh Mody 	rx_mod->rxp_free_count++;
1797f3bd5173SRasesh Mody }
1798f3bd5173SRasesh Mody 
1799f3bd5173SRasesh Mody static struct bna_rx *
bna_rx_get(struct bna_rx_mod * rx_mod,enum bna_rx_type type)1800f3bd5173SRasesh Mody bna_rx_get(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
1801f3bd5173SRasesh Mody {
1802f3bd5173SRasesh Mody 	struct bna_rx *rx = NULL;
1803f3bd5173SRasesh Mody 
18042b26fb95SIvan Vecera 	BUG_ON(list_empty(&rx_mod->rx_free_q));
18052b26fb95SIvan Vecera 	if (type == BNA_RX_T_REGULAR)
18062b26fb95SIvan Vecera 		rx = list_first_entry(&rx_mod->rx_free_q, struct bna_rx, qe);
18072b26fb95SIvan Vecera 	else
18082b26fb95SIvan Vecera 		rx = list_last_entry(&rx_mod->rx_free_q, struct bna_rx, qe);
1809f3bd5173SRasesh Mody 
1810f3bd5173SRasesh Mody 	rx_mod->rx_free_count--;
18112b26fb95SIvan Vecera 	list_move_tail(&rx->qe, &rx_mod->rx_active_q);
1812f3bd5173SRasesh Mody 	rx->type = type;
1813f3bd5173SRasesh Mody 
1814f3bd5173SRasesh Mody 	return rx;
1815f3bd5173SRasesh Mody }
1816f3bd5173SRasesh Mody 
1817f3bd5173SRasesh Mody static void
bna_rx_put(struct bna_rx_mod * rx_mod,struct bna_rx * rx)1818f3bd5173SRasesh Mody bna_rx_put(struct bna_rx_mod *rx_mod, struct bna_rx *rx)
1819f3bd5173SRasesh Mody {
1820f3bd5173SRasesh Mody 	struct list_head *qe;
1821f3bd5173SRasesh Mody 
18222b26fb95SIvan Vecera 	list_for_each_prev(qe, &rx_mod->rx_free_q)
1823f3bd5173SRasesh Mody 		if (((struct bna_rx *)qe)->rid < rx->rid)
1824f3bd5173SRasesh Mody 			break;
1825f3bd5173SRasesh Mody 
18262b26fb95SIvan Vecera 	list_add(&rx->qe, qe);
1827f3bd5173SRasesh Mody 	rx_mod->rx_free_count++;
1828f3bd5173SRasesh Mody }
1829f3bd5173SRasesh Mody 
1830f3bd5173SRasesh Mody static void
bna_rxp_add_rxqs(struct bna_rxp * rxp,struct bna_rxq * q0,struct bna_rxq * q1)1831f3bd5173SRasesh Mody bna_rxp_add_rxqs(struct bna_rxp *rxp, struct bna_rxq *q0,
1832f3bd5173SRasesh Mody 		struct bna_rxq *q1)
1833f3bd5173SRasesh Mody {
1834f3bd5173SRasesh Mody 	switch (rxp->type) {
1835f3bd5173SRasesh Mody 	case BNA_RXP_SINGLE:
1836f3bd5173SRasesh Mody 		rxp->rxq.single.only = q0;
1837f3bd5173SRasesh Mody 		rxp->rxq.single.reserved = NULL;
1838f3bd5173SRasesh Mody 		break;
1839f3bd5173SRasesh Mody 	case BNA_RXP_SLR:
1840f3bd5173SRasesh Mody 		rxp->rxq.slr.large = q0;
1841f3bd5173SRasesh Mody 		rxp->rxq.slr.small = q1;
1842f3bd5173SRasesh Mody 		break;
1843f3bd5173SRasesh Mody 	case BNA_RXP_HDS:
1844f3bd5173SRasesh Mody 		rxp->rxq.hds.data = q0;
1845f3bd5173SRasesh Mody 		rxp->rxq.hds.hdr = q1;
1846f3bd5173SRasesh Mody 		break;
1847f3bd5173SRasesh Mody 	default:
1848f3bd5173SRasesh Mody 		break;
1849f3bd5173SRasesh Mody 	}
1850f3bd5173SRasesh Mody }
1851f3bd5173SRasesh Mody 
1852f3bd5173SRasesh Mody static void
bna_rxq_qpt_setup(struct bna_rxq * rxq,struct bna_rxp * rxp,u32 page_count,u32 page_size,struct bna_mem_descr * qpt_mem,struct bna_mem_descr * swqpt_mem,struct bna_mem_descr * page_mem)1853f3bd5173SRasesh Mody bna_rxq_qpt_setup(struct bna_rxq *rxq,
1854f3bd5173SRasesh Mody 		struct bna_rxp *rxp,
1855f3bd5173SRasesh Mody 		u32 page_count,
1856f3bd5173SRasesh Mody 		u32 page_size,
1857f3bd5173SRasesh Mody 		struct bna_mem_descr *qpt_mem,
1858f3bd5173SRasesh Mody 		struct bna_mem_descr *swqpt_mem,
1859f3bd5173SRasesh Mody 		struct bna_mem_descr *page_mem)
1860f3bd5173SRasesh Mody {
18615216562aSRasesh Mody 	u8 *kva;
18625216562aSRasesh Mody 	u64 dma;
18635216562aSRasesh Mody 	struct bna_dma_addr bna_dma;
1864f3bd5173SRasesh Mody 	int	i;
1865f3bd5173SRasesh Mody 
1866f3bd5173SRasesh Mody 	rxq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
1867f3bd5173SRasesh Mody 	rxq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
1868f3bd5173SRasesh Mody 	rxq->qpt.kv_qpt_ptr = qpt_mem->kva;
1869f3bd5173SRasesh Mody 	rxq->qpt.page_count = page_count;
1870f3bd5173SRasesh Mody 	rxq->qpt.page_size = page_size;
1871f3bd5173SRasesh Mody 
1872f3bd5173SRasesh Mody 	rxq->rcb->sw_qpt = (void **) swqpt_mem->kva;
18735216562aSRasesh Mody 	rxq->rcb->sw_q = page_mem->kva;
18745216562aSRasesh Mody 
18755216562aSRasesh Mody 	kva = page_mem->kva;
18765216562aSRasesh Mody 	BNA_GET_DMA_ADDR(&page_mem->dma, dma);
1877f3bd5173SRasesh Mody 
1878f3bd5173SRasesh Mody 	for (i = 0; i < rxq->qpt.page_count; i++) {
18795216562aSRasesh Mody 		rxq->rcb->sw_qpt[i] = kva;
18805216562aSRasesh Mody 		kva += PAGE_SIZE;
18815216562aSRasesh Mody 
18825216562aSRasesh Mody 		BNA_SET_DMA_ADDR(dma, &bna_dma);
1883f3bd5173SRasesh Mody 		((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].lsb =
18845216562aSRasesh Mody 			bna_dma.lsb;
1885f3bd5173SRasesh Mody 		((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].msb =
18865216562aSRasesh Mody 			bna_dma.msb;
18875216562aSRasesh Mody 		dma += PAGE_SIZE;
1888f3bd5173SRasesh Mody 	}
1889f3bd5173SRasesh Mody }
1890f3bd5173SRasesh Mody 
1891f3bd5173SRasesh Mody static void
bna_rxp_cqpt_setup(struct bna_rxp * rxp,u32 page_count,u32 page_size,struct bna_mem_descr * qpt_mem,struct bna_mem_descr * swqpt_mem,struct bna_mem_descr * page_mem)1892f3bd5173SRasesh Mody bna_rxp_cqpt_setup(struct bna_rxp *rxp,
1893f3bd5173SRasesh Mody 		u32 page_count,
1894f3bd5173SRasesh Mody 		u32 page_size,
1895f3bd5173SRasesh Mody 		struct bna_mem_descr *qpt_mem,
1896f3bd5173SRasesh Mody 		struct bna_mem_descr *swqpt_mem,
1897f3bd5173SRasesh Mody 		struct bna_mem_descr *page_mem)
1898f3bd5173SRasesh Mody {
18995216562aSRasesh Mody 	u8 *kva;
19005216562aSRasesh Mody 	u64 dma;
19015216562aSRasesh Mody 	struct bna_dma_addr bna_dma;
1902f3bd5173SRasesh Mody 	int	i;
1903f3bd5173SRasesh Mody 
1904f3bd5173SRasesh Mody 	rxp->cq.qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
1905f3bd5173SRasesh Mody 	rxp->cq.qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
1906f3bd5173SRasesh Mody 	rxp->cq.qpt.kv_qpt_ptr = qpt_mem->kva;
1907f3bd5173SRasesh Mody 	rxp->cq.qpt.page_count = page_count;
1908f3bd5173SRasesh Mody 	rxp->cq.qpt.page_size = page_size;
1909f3bd5173SRasesh Mody 
1910f3bd5173SRasesh Mody 	rxp->cq.ccb->sw_qpt = (void **) swqpt_mem->kva;
19115216562aSRasesh Mody 	rxp->cq.ccb->sw_q = page_mem->kva;
19125216562aSRasesh Mody 
19135216562aSRasesh Mody 	kva = page_mem->kva;
19145216562aSRasesh Mody 	BNA_GET_DMA_ADDR(&page_mem->dma, dma);
1915f3bd5173SRasesh Mody 
1916f3bd5173SRasesh Mody 	for (i = 0; i < rxp->cq.qpt.page_count; i++) {
19175216562aSRasesh Mody 		rxp->cq.ccb->sw_qpt[i] = kva;
19185216562aSRasesh Mody 		kva += PAGE_SIZE;
1919f3bd5173SRasesh Mody 
19205216562aSRasesh Mody 		BNA_SET_DMA_ADDR(dma, &bna_dma);
1921f3bd5173SRasesh Mody 		((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].lsb =
19225216562aSRasesh Mody 			bna_dma.lsb;
1923f3bd5173SRasesh Mody 		((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].msb =
19245216562aSRasesh Mody 			bna_dma.msb;
19255216562aSRasesh Mody 		dma += PAGE_SIZE;
1926f3bd5173SRasesh Mody 	}
1927f3bd5173SRasesh Mody }
1928f3bd5173SRasesh Mody 
1929f3bd5173SRasesh Mody static void
bna_rx_mod_cb_rx_stopped(void * arg,struct bna_rx * rx)1930f3bd5173SRasesh Mody bna_rx_mod_cb_rx_stopped(void *arg, struct bna_rx *rx)
1931f3bd5173SRasesh Mody {
1932f3bd5173SRasesh Mody 	struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg;
1933f3bd5173SRasesh Mody 
1934f3bd5173SRasesh Mody 	bfa_wc_down(&rx_mod->rx_stop_wc);
1935f3bd5173SRasesh Mody }
1936f3bd5173SRasesh Mody 
1937f3bd5173SRasesh Mody static void
bna_rx_mod_cb_rx_stopped_all(void * arg)1938f3bd5173SRasesh Mody bna_rx_mod_cb_rx_stopped_all(void *arg)
1939f3bd5173SRasesh Mody {
1940f3bd5173SRasesh Mody 	struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg;
1941f3bd5173SRasesh Mody 
1942f3bd5173SRasesh Mody 	if (rx_mod->stop_cbfn)
1943f3bd5173SRasesh Mody 		rx_mod->stop_cbfn(&rx_mod->bna->enet);
1944f3bd5173SRasesh Mody 	rx_mod->stop_cbfn = NULL;
1945f3bd5173SRasesh Mody }
1946f3bd5173SRasesh Mody 
1947f3bd5173SRasesh Mody static void
bna_rx_start(struct bna_rx * rx)1948f3bd5173SRasesh Mody bna_rx_start(struct bna_rx *rx)
1949f3bd5173SRasesh Mody {
1950f3bd5173SRasesh Mody 	rx->rx_flags |= BNA_RX_F_ENET_STARTED;
1951f3bd5173SRasesh Mody 	if (rx->rx_flags & BNA_RX_F_ENABLED)
1952f3bd5173SRasesh Mody 		bfa_fsm_send_event(rx, RX_E_START);
1953f3bd5173SRasesh Mody }
1954f3bd5173SRasesh Mody 
1955f3bd5173SRasesh Mody static void
bna_rx_stop(struct bna_rx * rx)1956f3bd5173SRasesh Mody bna_rx_stop(struct bna_rx *rx)
1957f3bd5173SRasesh Mody {
1958f3bd5173SRasesh Mody 	rx->rx_flags &= ~BNA_RX_F_ENET_STARTED;
1959*8719a1c3SGustavo A. R. Silva 	if (rx->fsm == bna_rx_sm_stopped)
1960f3bd5173SRasesh Mody 		bna_rx_mod_cb_rx_stopped(&rx->bna->rx_mod, rx);
1961f3bd5173SRasesh Mody 	else {
1962f3bd5173SRasesh Mody 		rx->stop_cbfn = bna_rx_mod_cb_rx_stopped;
1963f3bd5173SRasesh Mody 		rx->stop_cbarg = &rx->bna->rx_mod;
1964f3bd5173SRasesh Mody 		bfa_fsm_send_event(rx, RX_E_STOP);
1965f3bd5173SRasesh Mody 	}
1966f3bd5173SRasesh Mody }
1967f3bd5173SRasesh Mody 
1968f3bd5173SRasesh Mody static void
bna_rx_fail(struct bna_rx * rx)1969f3bd5173SRasesh Mody bna_rx_fail(struct bna_rx *rx)
1970f3bd5173SRasesh Mody {
1971f3bd5173SRasesh Mody 	/* Indicate Enet is not enabled, and failed */
1972f3bd5173SRasesh Mody 	rx->rx_flags &= ~BNA_RX_F_ENET_STARTED;
1973f3bd5173SRasesh Mody 	bfa_fsm_send_event(rx, RX_E_FAIL);
1974f3bd5173SRasesh Mody }
1975f3bd5173SRasesh Mody 
1976f3bd5173SRasesh Mody void
bna_rx_mod_start(struct bna_rx_mod * rx_mod,enum bna_rx_type type)1977f3bd5173SRasesh Mody bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
1978f3bd5173SRasesh Mody {
1979f3bd5173SRasesh Mody 	struct bna_rx *rx;
1980f3bd5173SRasesh Mody 
1981f3bd5173SRasesh Mody 	rx_mod->flags |= BNA_RX_MOD_F_ENET_STARTED;
1982f3bd5173SRasesh Mody 	if (type == BNA_RX_T_LOOPBACK)
1983f3bd5173SRasesh Mody 		rx_mod->flags |= BNA_RX_MOD_F_ENET_LOOPBACK;
1984f3bd5173SRasesh Mody 
198516712c53SIvan Vecera 	list_for_each_entry(rx, &rx_mod->rx_active_q, qe)
1986f3bd5173SRasesh Mody 		if (rx->type == type)
1987f3bd5173SRasesh Mody 			bna_rx_start(rx);
1988f3bd5173SRasesh Mody }
1989f3bd5173SRasesh Mody 
1990f3bd5173SRasesh Mody void
bna_rx_mod_stop(struct bna_rx_mod * rx_mod,enum bna_rx_type type)1991f3bd5173SRasesh Mody bna_rx_mod_stop(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
1992f3bd5173SRasesh Mody {
1993f3bd5173SRasesh Mody 	struct bna_rx *rx;
1994f3bd5173SRasesh Mody 
1995f3bd5173SRasesh Mody 	rx_mod->flags &= ~BNA_RX_MOD_F_ENET_STARTED;
1996f3bd5173SRasesh Mody 	rx_mod->flags &= ~BNA_RX_MOD_F_ENET_LOOPBACK;
1997f3bd5173SRasesh Mody 
1998f3bd5173SRasesh Mody 	rx_mod->stop_cbfn = bna_enet_cb_rx_stopped;
1999f3bd5173SRasesh Mody 
2000f3bd5173SRasesh Mody 	bfa_wc_init(&rx_mod->rx_stop_wc, bna_rx_mod_cb_rx_stopped_all, rx_mod);
2001f3bd5173SRasesh Mody 
200216712c53SIvan Vecera 	list_for_each_entry(rx, &rx_mod->rx_active_q, qe)
2003f3bd5173SRasesh Mody 		if (rx->type == type) {
2004f3bd5173SRasesh Mody 			bfa_wc_up(&rx_mod->rx_stop_wc);
2005f3bd5173SRasesh Mody 			bna_rx_stop(rx);
2006f3bd5173SRasesh Mody 		}
2007f3bd5173SRasesh Mody 
2008f3bd5173SRasesh Mody 	bfa_wc_wait(&rx_mod->rx_stop_wc);
2009f3bd5173SRasesh Mody }
2010f3bd5173SRasesh Mody 
2011f3bd5173SRasesh Mody void
bna_rx_mod_fail(struct bna_rx_mod * rx_mod)2012f3bd5173SRasesh Mody bna_rx_mod_fail(struct bna_rx_mod *rx_mod)
2013f3bd5173SRasesh Mody {
2014f3bd5173SRasesh Mody 	struct bna_rx *rx;
2015f3bd5173SRasesh Mody 
2016f3bd5173SRasesh Mody 	rx_mod->flags &= ~BNA_RX_MOD_F_ENET_STARTED;
2017f3bd5173SRasesh Mody 	rx_mod->flags &= ~BNA_RX_MOD_F_ENET_LOOPBACK;
2018f3bd5173SRasesh Mody 
201916712c53SIvan Vecera 	list_for_each_entry(rx, &rx_mod->rx_active_q, qe)
2020f3bd5173SRasesh Mody 		bna_rx_fail(rx);
2021f3bd5173SRasesh Mody }
2022f3bd5173SRasesh Mody 
bna_rx_mod_init(struct bna_rx_mod * rx_mod,struct bna * bna,struct bna_res_info * res_info)2023f3bd5173SRasesh Mody void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna,
2024f3bd5173SRasesh Mody 			struct bna_res_info *res_info)
2025f3bd5173SRasesh Mody {
2026f3bd5173SRasesh Mody 	int	index;
2027f3bd5173SRasesh Mody 	struct bna_rx *rx_ptr;
2028f3bd5173SRasesh Mody 	struct bna_rxp *rxp_ptr;
2029f3bd5173SRasesh Mody 	struct bna_rxq *rxq_ptr;
2030f3bd5173SRasesh Mody 
2031f3bd5173SRasesh Mody 	rx_mod->bna = bna;
2032f3bd5173SRasesh Mody 	rx_mod->flags = 0;
2033f3bd5173SRasesh Mody 
2034f3bd5173SRasesh Mody 	rx_mod->rx = (struct bna_rx *)
2035f3bd5173SRasesh Mody 		res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.mdl[0].kva;
2036f3bd5173SRasesh Mody 	rx_mod->rxp = (struct bna_rxp *)
2037f3bd5173SRasesh Mody 		res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mdl[0].kva;
2038f3bd5173SRasesh Mody 	rx_mod->rxq = (struct bna_rxq *)
2039f3bd5173SRasesh Mody 		res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mdl[0].kva;
2040f3bd5173SRasesh Mody 
2041f3bd5173SRasesh Mody 	/* Initialize the queues */
2042f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&rx_mod->rx_free_q);
2043f3bd5173SRasesh Mody 	rx_mod->rx_free_count = 0;
2044f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&rx_mod->rxq_free_q);
2045f3bd5173SRasesh Mody 	rx_mod->rxq_free_count = 0;
2046f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&rx_mod->rxp_free_q);
2047f3bd5173SRasesh Mody 	rx_mod->rxp_free_count = 0;
2048f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&rx_mod->rx_active_q);
2049f3bd5173SRasesh Mody 
2050f3bd5173SRasesh Mody 	/* Build RX queues */
2051f3bd5173SRasesh Mody 	for (index = 0; index < bna->ioceth.attr.num_rxp; index++) {
2052f3bd5173SRasesh Mody 		rx_ptr = &rx_mod->rx[index];
2053f3bd5173SRasesh Mody 
2054f3bd5173SRasesh Mody 		INIT_LIST_HEAD(&rx_ptr->rxp_q);
2055f3bd5173SRasesh Mody 		rx_ptr->bna = NULL;
2056f3bd5173SRasesh Mody 		rx_ptr->rid = index;
2057f3bd5173SRasesh Mody 		rx_ptr->stop_cbfn = NULL;
2058f3bd5173SRasesh Mody 		rx_ptr->stop_cbarg = NULL;
2059f3bd5173SRasesh Mody 
2060f3bd5173SRasesh Mody 		list_add_tail(&rx_ptr->qe, &rx_mod->rx_free_q);
2061f3bd5173SRasesh Mody 		rx_mod->rx_free_count++;
2062f3bd5173SRasesh Mody 	}
2063f3bd5173SRasesh Mody 
2064f3bd5173SRasesh Mody 	/* build RX-path queue */
2065f3bd5173SRasesh Mody 	for (index = 0; index < bna->ioceth.attr.num_rxp; index++) {
2066f3bd5173SRasesh Mody 		rxp_ptr = &rx_mod->rxp[index];
2067f3bd5173SRasesh Mody 		list_add_tail(&rxp_ptr->qe, &rx_mod->rxp_free_q);
2068f3bd5173SRasesh Mody 		rx_mod->rxp_free_count++;
2069f3bd5173SRasesh Mody 	}
2070f3bd5173SRasesh Mody 
2071f3bd5173SRasesh Mody 	/* build RXQ queue */
2072f3bd5173SRasesh Mody 	for (index = 0; index < (bna->ioceth.attr.num_rxp * 2); index++) {
2073f3bd5173SRasesh Mody 		rxq_ptr = &rx_mod->rxq[index];
2074f3bd5173SRasesh Mody 		list_add_tail(&rxq_ptr->qe, &rx_mod->rxq_free_q);
2075f3bd5173SRasesh Mody 		rx_mod->rxq_free_count++;
2076f3bd5173SRasesh Mody 	}
2077f3bd5173SRasesh Mody }
2078f3bd5173SRasesh Mody 
2079f3bd5173SRasesh Mody void
bna_rx_mod_uninit(struct bna_rx_mod * rx_mod)2080f3bd5173SRasesh Mody bna_rx_mod_uninit(struct bna_rx_mod *rx_mod)
2081f3bd5173SRasesh Mody {
2082f3bd5173SRasesh Mody 	rx_mod->bna = NULL;
2083f3bd5173SRasesh Mody }
2084f3bd5173SRasesh Mody 
2085f3bd5173SRasesh Mody void
bna_bfi_rx_enet_start_rsp(struct bna_rx * rx,struct bfi_msgq_mhdr * msghdr)2086f3bd5173SRasesh Mody bna_bfi_rx_enet_start_rsp(struct bna_rx *rx, struct bfi_msgq_mhdr *msghdr)
2087f3bd5173SRasesh Mody {
2088f3bd5173SRasesh Mody 	struct bfi_enet_rx_cfg_rsp *cfg_rsp = &rx->bfi_enet_cmd.cfg_rsp;
2089f3bd5173SRasesh Mody 	struct bna_rxp *rxp = NULL;
2090f3bd5173SRasesh Mody 	struct bna_rxq *q0 = NULL, *q1 = NULL;
2091f3bd5173SRasesh Mody 	int i;
2092f3bd5173SRasesh Mody 
2093f3bd5173SRasesh Mody 	bfa_msgq_rsp_copy(&rx->bna->msgq, (u8 *)cfg_rsp,
2094f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_rx_cfg_rsp));
2095f3bd5173SRasesh Mody 
2096f3bd5173SRasesh Mody 	rx->hw_id = cfg_rsp->hw_id;
2097f3bd5173SRasesh Mody 
20982b26fb95SIvan Vecera 	for (i = 0, rxp = list_first_entry(&rx->rxp_q, struct bna_rxp, qe);
20992b26fb95SIvan Vecera 	     i < rx->num_paths; i++, rxp = list_next_entry(rxp, qe)) {
2100f3bd5173SRasesh Mody 		GET_RXQS(rxp, q0, q1);
2101f3bd5173SRasesh Mody 
2102f3bd5173SRasesh Mody 		/* Setup doorbells */
2103f3bd5173SRasesh Mody 		rxp->cq.ccb->i_dbell->doorbell_addr =
2104f3bd5173SRasesh Mody 			rx->bna->pcidev.pci_bar_kva
2105f3bd5173SRasesh Mody 			+ ntohl(cfg_rsp->q_handles[i].i_dbell);
2106f3bd5173SRasesh Mody 		rxp->hw_id = cfg_rsp->q_handles[i].hw_cqid;
2107f3bd5173SRasesh Mody 		q0->rcb->q_dbell =
2108f3bd5173SRasesh Mody 			rx->bna->pcidev.pci_bar_kva
2109f3bd5173SRasesh Mody 			+ ntohl(cfg_rsp->q_handles[i].ql_dbell);
2110f3bd5173SRasesh Mody 		q0->hw_id = cfg_rsp->q_handles[i].hw_lqid;
2111f3bd5173SRasesh Mody 		if (q1) {
2112f3bd5173SRasesh Mody 			q1->rcb->q_dbell =
2113f3bd5173SRasesh Mody 			rx->bna->pcidev.pci_bar_kva
2114f3bd5173SRasesh Mody 			+ ntohl(cfg_rsp->q_handles[i].qs_dbell);
2115f3bd5173SRasesh Mody 			q1->hw_id = cfg_rsp->q_handles[i].hw_sqid;
2116f3bd5173SRasesh Mody 		}
2117f3bd5173SRasesh Mody 
2118f3bd5173SRasesh Mody 		/* Initialize producer/consumer indexes */
2119f3bd5173SRasesh Mody 		(*rxp->cq.ccb->hw_producer_index) = 0;
2120f3bd5173SRasesh Mody 		rxp->cq.ccb->producer_index = 0;
2121f3bd5173SRasesh Mody 		q0->rcb->producer_index = q0->rcb->consumer_index = 0;
2122f3bd5173SRasesh Mody 		if (q1)
2123f3bd5173SRasesh Mody 			q1->rcb->producer_index = q1->rcb->consumer_index = 0;
2124f3bd5173SRasesh Mody 	}
2125f3bd5173SRasesh Mody 
2126f3bd5173SRasesh Mody 	bfa_fsm_send_event(rx, RX_E_STARTED);
2127f3bd5173SRasesh Mody }
2128f3bd5173SRasesh Mody 
2129f3bd5173SRasesh Mody void
bna_bfi_rx_enet_stop_rsp(struct bna_rx * rx,struct bfi_msgq_mhdr * msghdr)2130f3bd5173SRasesh Mody bna_bfi_rx_enet_stop_rsp(struct bna_rx *rx, struct bfi_msgq_mhdr *msghdr)
2131f3bd5173SRasesh Mody {
2132f3bd5173SRasesh Mody 	bfa_fsm_send_event(rx, RX_E_STOPPED);
2133f3bd5173SRasesh Mody }
2134f3bd5173SRasesh Mody 
2135f3bd5173SRasesh Mody void
bna_rx_res_req(struct bna_rx_config * q_cfg,struct bna_res_info * res_info)2136f3bd5173SRasesh Mody bna_rx_res_req(struct bna_rx_config *q_cfg, struct bna_res_info *res_info)
2137f3bd5173SRasesh Mody {
2138f3bd5173SRasesh Mody 	u32 cq_size, hq_size, dq_size;
2139f3bd5173SRasesh Mody 	u32 cpage_count, hpage_count, dpage_count;
2140f3bd5173SRasesh Mody 	struct bna_mem_info *mem_info;
2141f3bd5173SRasesh Mody 	u32 cq_depth;
2142f3bd5173SRasesh Mody 	u32 hq_depth;
2143f3bd5173SRasesh Mody 	u32 dq_depth;
2144f3bd5173SRasesh Mody 
2145e29aa339SRasesh Mody 	dq_depth = q_cfg->q0_depth;
2146e29aa339SRasesh Mody 	hq_depth = ((q_cfg->rxp_type == BNA_RXP_SINGLE) ? 0 : q_cfg->q1_depth);
2147a1ac490dSIvan Vecera 	cq_depth = roundup_pow_of_two(dq_depth + hq_depth);
2148f3bd5173SRasesh Mody 
2149f3bd5173SRasesh Mody 	cq_size = cq_depth * BFI_CQ_WI_SIZE;
2150f3bd5173SRasesh Mody 	cq_size = ALIGN(cq_size, PAGE_SIZE);
2151f3bd5173SRasesh Mody 	cpage_count = SIZE_TO_PAGES(cq_size);
2152f3bd5173SRasesh Mody 
2153a1ac490dSIvan Vecera 	dq_depth = roundup_pow_of_two(dq_depth);
2154f3bd5173SRasesh Mody 	dq_size = dq_depth * BFI_RXQ_WI_SIZE;
2155f3bd5173SRasesh Mody 	dq_size = ALIGN(dq_size, PAGE_SIZE);
2156f3bd5173SRasesh Mody 	dpage_count = SIZE_TO_PAGES(dq_size);
2157f3bd5173SRasesh Mody 
2158f3bd5173SRasesh Mody 	if (BNA_RXP_SINGLE != q_cfg->rxp_type) {
2159a1ac490dSIvan Vecera 		hq_depth = roundup_pow_of_two(hq_depth);
2160f3bd5173SRasesh Mody 		hq_size = hq_depth * BFI_RXQ_WI_SIZE;
2161f3bd5173SRasesh Mody 		hq_size = ALIGN(hq_size, PAGE_SIZE);
2162f3bd5173SRasesh Mody 		hpage_count = SIZE_TO_PAGES(hq_size);
2163f3bd5173SRasesh Mody 	} else
2164f3bd5173SRasesh Mody 		hpage_count = 0;
2165f3bd5173SRasesh Mody 
2166f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_MEM_T_CCB].res_type = BNA_RES_T_MEM;
2167f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info;
2168f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_KVA;
2169f3bd5173SRasesh Mody 	mem_info->len = sizeof(struct bna_ccb);
2170f3bd5173SRasesh Mody 	mem_info->num = q_cfg->num_paths;
2171f3bd5173SRasesh Mody 
2172f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_MEM_T_RCB].res_type = BNA_RES_T_MEM;
2173f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info;
2174f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_KVA;
2175f3bd5173SRasesh Mody 	mem_info->len = sizeof(struct bna_rcb);
2176f3bd5173SRasesh Mody 	mem_info->num = BNA_GET_RXQS(q_cfg);
2177f3bd5173SRasesh Mody 
2178f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_MEM_T_CQPT].res_type = BNA_RES_T_MEM;
2179f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info;
2180f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_DMA;
2181f3bd5173SRasesh Mody 	mem_info->len = cpage_count * sizeof(struct bna_dma_addr);
2182f3bd5173SRasesh Mody 	mem_info->num = q_cfg->num_paths;
2183f3bd5173SRasesh Mody 
2184f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_MEM_T_CSWQPT].res_type = BNA_RES_T_MEM;
2185f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info;
2186f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_KVA;
2187f3bd5173SRasesh Mody 	mem_info->len = cpage_count * sizeof(void *);
2188f3bd5173SRasesh Mody 	mem_info->num = q_cfg->num_paths;
2189f3bd5173SRasesh Mody 
2190f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_type = BNA_RES_T_MEM;
2191f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info;
2192f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_DMA;
21935216562aSRasesh Mody 	mem_info->len = PAGE_SIZE * cpage_count;
21945216562aSRasesh Mody 	mem_info->num = q_cfg->num_paths;
2195f3bd5173SRasesh Mody 
2196f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_MEM_T_DQPT].res_type = BNA_RES_T_MEM;
2197f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info;
2198f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_DMA;
2199f3bd5173SRasesh Mody 	mem_info->len = dpage_count * sizeof(struct bna_dma_addr);
2200f3bd5173SRasesh Mody 	mem_info->num = q_cfg->num_paths;
2201f3bd5173SRasesh Mody 
2202f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_MEM_T_DSWQPT].res_type = BNA_RES_T_MEM;
2203f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info;
2204f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_KVA;
2205f3bd5173SRasesh Mody 	mem_info->len = dpage_count * sizeof(void *);
2206f3bd5173SRasesh Mody 	mem_info->num = q_cfg->num_paths;
2207f3bd5173SRasesh Mody 
2208f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_MEM_T_DPAGE].res_type = BNA_RES_T_MEM;
2209f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info;
2210f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_DMA;
22115216562aSRasesh Mody 	mem_info->len = PAGE_SIZE * dpage_count;
22125216562aSRasesh Mody 	mem_info->num = q_cfg->num_paths;
2213f3bd5173SRasesh Mody 
2214f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_MEM_T_HQPT].res_type = BNA_RES_T_MEM;
2215f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info;
2216f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_DMA;
2217f3bd5173SRasesh Mody 	mem_info->len = hpage_count * sizeof(struct bna_dma_addr);
2218f3bd5173SRasesh Mody 	mem_info->num = (hpage_count ? q_cfg->num_paths : 0);
2219f3bd5173SRasesh Mody 
2220f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_MEM_T_HSWQPT].res_type = BNA_RES_T_MEM;
2221f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info;
2222f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_KVA;
2223f3bd5173SRasesh Mody 	mem_info->len = hpage_count * sizeof(void *);
2224f3bd5173SRasesh Mody 	mem_info->num = (hpage_count ? q_cfg->num_paths : 0);
2225f3bd5173SRasesh Mody 
2226f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_MEM_T_HPAGE].res_type = BNA_RES_T_MEM;
2227f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info;
2228f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_DMA;
22295216562aSRasesh Mody 	mem_info->len = PAGE_SIZE * hpage_count;
22305216562aSRasesh Mody 	mem_info->num = (hpage_count ? q_cfg->num_paths : 0);
2231f3bd5173SRasesh Mody 
2232f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM;
2233f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_RX_RES_MEM_T_IBIDX].res_u.mem_info;
2234f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_DMA;
2235f3bd5173SRasesh Mody 	mem_info->len = BFI_IBIDX_SIZE;
2236f3bd5173SRasesh Mody 	mem_info->num = q_cfg->num_paths;
2237f3bd5173SRasesh Mody 
2238f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_MEM_T_RIT].res_type = BNA_RES_T_MEM;
2239f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_RX_RES_MEM_T_RIT].res_u.mem_info;
2240f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_KVA;
2241f3bd5173SRasesh Mody 	mem_info->len = BFI_ENET_RSS_RIT_MAX;
2242f3bd5173SRasesh Mody 	mem_info->num = 1;
2243f3bd5173SRasesh Mody 
2244f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_T_INTR].res_type = BNA_RES_T_INTR;
2245f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_T_INTR].res_u.intr_info.intr_type = BNA_INTR_T_MSIX;
2246f3bd5173SRasesh Mody 	res_info[BNA_RX_RES_T_INTR].res_u.intr_info.num = q_cfg->num_paths;
2247f3bd5173SRasesh Mody }
2248f3bd5173SRasesh Mody 
2249f3bd5173SRasesh Mody struct bna_rx *
bna_rx_create(struct bna * bna,struct bnad * bnad,struct bna_rx_config * rx_cfg,const struct bna_rx_event_cbfn * rx_cbfn,struct bna_res_info * res_info,void * priv)2250f3bd5173SRasesh Mody bna_rx_create(struct bna *bna, struct bnad *bnad,
2251f3bd5173SRasesh Mody 		struct bna_rx_config *rx_cfg,
2252d91d25d5Sstephen hemminger 		const struct bna_rx_event_cbfn *rx_cbfn,
2253f3bd5173SRasesh Mody 		struct bna_res_info *res_info,
2254f3bd5173SRasesh Mody 		void *priv)
2255f3bd5173SRasesh Mody {
2256f3bd5173SRasesh Mody 	struct bna_rx_mod *rx_mod = &bna->rx_mod;
2257f3bd5173SRasesh Mody 	struct bna_rx *rx;
2258f3bd5173SRasesh Mody 	struct bna_rxp *rxp;
2259f3bd5173SRasesh Mody 	struct bna_rxq *q0;
2260f3bd5173SRasesh Mody 	struct bna_rxq *q1;
2261f3bd5173SRasesh Mody 	struct bna_intr_info *intr_info;
2262e29aa339SRasesh Mody 	struct bna_mem_descr *hqunmap_mem;
2263e29aa339SRasesh Mody 	struct bna_mem_descr *dqunmap_mem;
2264f3bd5173SRasesh Mody 	struct bna_mem_descr *ccb_mem;
2265f3bd5173SRasesh Mody 	struct bna_mem_descr *rcb_mem;
2266f3bd5173SRasesh Mody 	struct bna_mem_descr *cqpt_mem;
2267f3bd5173SRasesh Mody 	struct bna_mem_descr *cswqpt_mem;
2268f3bd5173SRasesh Mody 	struct bna_mem_descr *cpage_mem;
2269f3bd5173SRasesh Mody 	struct bna_mem_descr *hqpt_mem;
2270f3bd5173SRasesh Mody 	struct bna_mem_descr *dqpt_mem;
2271f3bd5173SRasesh Mody 	struct bna_mem_descr *hsqpt_mem;
2272f3bd5173SRasesh Mody 	struct bna_mem_descr *dsqpt_mem;
2273f3bd5173SRasesh Mody 	struct bna_mem_descr *hpage_mem;
2274f3bd5173SRasesh Mody 	struct bna_mem_descr *dpage_mem;
2275e29aa339SRasesh Mody 	u32 dpage_count, hpage_count;
2276e29aa339SRasesh Mody 	u32 hq_idx, dq_idx, rcb_idx;
2277e29aa339SRasesh Mody 	u32 cq_depth, i;
2278e29aa339SRasesh Mody 	u32 page_count;
2279f3bd5173SRasesh Mody 
2280f3bd5173SRasesh Mody 	if (!bna_rx_res_check(rx_mod, rx_cfg))
2281f3bd5173SRasesh Mody 		return NULL;
2282f3bd5173SRasesh Mody 
2283f3bd5173SRasesh Mody 	intr_info = &res_info[BNA_RX_RES_T_INTR].res_u.intr_info;
2284f3bd5173SRasesh Mody 	ccb_mem = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info.mdl[0];
2285f3bd5173SRasesh Mody 	rcb_mem = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info.mdl[0];
2286e29aa339SRasesh Mody 	dqunmap_mem = &res_info[BNA_RX_RES_MEM_T_UNMAPDQ].res_u.mem_info.mdl[0];
2287e29aa339SRasesh Mody 	hqunmap_mem = &res_info[BNA_RX_RES_MEM_T_UNMAPHQ].res_u.mem_info.mdl[0];
2288f3bd5173SRasesh Mody 	cqpt_mem = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info.mdl[0];
2289f3bd5173SRasesh Mody 	cswqpt_mem = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info.mdl[0];
2290f3bd5173SRasesh Mody 	cpage_mem = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.mdl[0];
2291f3bd5173SRasesh Mody 	hqpt_mem = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info.mdl[0];
2292f3bd5173SRasesh Mody 	dqpt_mem = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info.mdl[0];
2293f3bd5173SRasesh Mody 	hsqpt_mem = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info.mdl[0];
2294f3bd5173SRasesh Mody 	dsqpt_mem = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info.mdl[0];
2295f3bd5173SRasesh Mody 	hpage_mem = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.mdl[0];
2296f3bd5173SRasesh Mody 	dpage_mem = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.mdl[0];
2297f3bd5173SRasesh Mody 
22985216562aSRasesh Mody 	page_count = res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.len /
22995216562aSRasesh Mody 			PAGE_SIZE;
2300f3bd5173SRasesh Mody 
23015216562aSRasesh Mody 	dpage_count = res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.len /
23025216562aSRasesh Mody 			PAGE_SIZE;
2303f3bd5173SRasesh Mody 
23045216562aSRasesh Mody 	hpage_count = res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.len /
23055216562aSRasesh Mody 			PAGE_SIZE;
2306f3bd5173SRasesh Mody 
2307f3bd5173SRasesh Mody 	rx = bna_rx_get(rx_mod, rx_cfg->rx_type);
2308f3bd5173SRasesh Mody 	rx->bna = bna;
2309f3bd5173SRasesh Mody 	rx->rx_flags = 0;
2310f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&rx->rxp_q);
2311f3bd5173SRasesh Mody 	rx->stop_cbfn = NULL;
2312f3bd5173SRasesh Mody 	rx->stop_cbarg = NULL;
2313f3bd5173SRasesh Mody 	rx->priv = priv;
2314f3bd5173SRasesh Mody 
2315f3bd5173SRasesh Mody 	rx->rcb_setup_cbfn = rx_cbfn->rcb_setup_cbfn;
2316f3bd5173SRasesh Mody 	rx->rcb_destroy_cbfn = rx_cbfn->rcb_destroy_cbfn;
2317f3bd5173SRasesh Mody 	rx->ccb_setup_cbfn = rx_cbfn->ccb_setup_cbfn;
2318f3bd5173SRasesh Mody 	rx->ccb_destroy_cbfn = rx_cbfn->ccb_destroy_cbfn;
23195bcf6ac0SRasesh Mody 	rx->rx_stall_cbfn = rx_cbfn->rx_stall_cbfn;
2320f3bd5173SRasesh Mody 	/* Following callbacks are mandatory */
2321f3bd5173SRasesh Mody 	rx->rx_cleanup_cbfn = rx_cbfn->rx_cleanup_cbfn;
2322f3bd5173SRasesh Mody 	rx->rx_post_cbfn = rx_cbfn->rx_post_cbfn;
2323f3bd5173SRasesh Mody 
2324f3bd5173SRasesh Mody 	if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_ENET_STARTED) {
2325f3bd5173SRasesh Mody 		switch (rx->type) {
2326f3bd5173SRasesh Mody 		case BNA_RX_T_REGULAR:
2327f3bd5173SRasesh Mody 			if (!(rx->bna->rx_mod.flags &
2328f3bd5173SRasesh Mody 				BNA_RX_MOD_F_ENET_LOOPBACK))
2329f3bd5173SRasesh Mody 				rx->rx_flags |= BNA_RX_F_ENET_STARTED;
2330f3bd5173SRasesh Mody 			break;
2331f3bd5173SRasesh Mody 		case BNA_RX_T_LOOPBACK:
2332f3bd5173SRasesh Mody 			if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_ENET_LOOPBACK)
2333f3bd5173SRasesh Mody 				rx->rx_flags |= BNA_RX_F_ENET_STARTED;
2334f3bd5173SRasesh Mody 			break;
2335f3bd5173SRasesh Mody 		}
2336f3bd5173SRasesh Mody 	}
2337f3bd5173SRasesh Mody 
2338f3bd5173SRasesh Mody 	rx->num_paths = rx_cfg->num_paths;
2339e29aa339SRasesh Mody 	for (i = 0, hq_idx = 0, dq_idx = 0, rcb_idx = 0;
2340e29aa339SRasesh Mody 			i < rx->num_paths; i++) {
2341f3bd5173SRasesh Mody 		rxp = bna_rxp_get(rx_mod);
2342f3bd5173SRasesh Mody 		list_add_tail(&rxp->qe, &rx->rxp_q);
2343f3bd5173SRasesh Mody 		rxp->type = rx_cfg->rxp_type;
2344f3bd5173SRasesh Mody 		rxp->rx = rx;
2345f3bd5173SRasesh Mody 		rxp->cq.rx = rx;
2346f3bd5173SRasesh Mody 
2347f3bd5173SRasesh Mody 		q0 = bna_rxq_get(rx_mod);
2348f3bd5173SRasesh Mody 		if (BNA_RXP_SINGLE == rx_cfg->rxp_type)
2349f3bd5173SRasesh Mody 			q1 = NULL;
2350f3bd5173SRasesh Mody 		else
2351f3bd5173SRasesh Mody 			q1 = bna_rxq_get(rx_mod);
2352f3bd5173SRasesh Mody 
2353f3bd5173SRasesh Mody 		if (1 == intr_info->num)
2354f3bd5173SRasesh Mody 			rxp->vector = intr_info->idl[0].vector;
2355f3bd5173SRasesh Mody 		else
2356f3bd5173SRasesh Mody 			rxp->vector = intr_info->idl[i].vector;
2357f3bd5173SRasesh Mody 
2358f3bd5173SRasesh Mody 		/* Setup IB */
2359f3bd5173SRasesh Mody 
2360f3bd5173SRasesh Mody 		rxp->cq.ib.ib_seg_host_addr.lsb =
2361f3bd5173SRasesh Mody 		res_info[BNA_RX_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.lsb;
2362f3bd5173SRasesh Mody 		rxp->cq.ib.ib_seg_host_addr.msb =
2363f3bd5173SRasesh Mody 		res_info[BNA_RX_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.msb;
2364f3bd5173SRasesh Mody 		rxp->cq.ib.ib_seg_host_addr_kva =
2365f3bd5173SRasesh Mody 		res_info[BNA_RX_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].kva;
2366f3bd5173SRasesh Mody 		rxp->cq.ib.intr_type = intr_info->intr_type;
2367f3bd5173SRasesh Mody 		if (intr_info->intr_type == BNA_INTR_T_MSIX)
2368f3bd5173SRasesh Mody 			rxp->cq.ib.intr_vector = rxp->vector;
2369f3bd5173SRasesh Mody 		else
23701a50691aSIvan Vecera 			rxp->cq.ib.intr_vector = BIT(rxp->vector);
2371f3bd5173SRasesh Mody 		rxp->cq.ib.coalescing_timeo = rx_cfg->coalescing_timeo;
2372f3bd5173SRasesh Mody 		rxp->cq.ib.interpkt_count = BFI_RX_INTERPKT_COUNT;
2373f3bd5173SRasesh Mody 		rxp->cq.ib.interpkt_timeo = BFI_RX_INTERPKT_TIMEO;
2374f3bd5173SRasesh Mody 
2375f3bd5173SRasesh Mody 		bna_rxp_add_rxqs(rxp, q0, q1);
2376f3bd5173SRasesh Mody 
2377f3bd5173SRasesh Mody 		/* Setup large Q */
2378f3bd5173SRasesh Mody 
2379f3bd5173SRasesh Mody 		q0->rx = rx;
2380f3bd5173SRasesh Mody 		q0->rxp = rxp;
2381f3bd5173SRasesh Mody 
2382f3bd5173SRasesh Mody 		q0->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva;
2383e29aa339SRasesh Mody 		q0->rcb->unmap_q = (void *)dqunmap_mem[dq_idx].kva;
2384e29aa339SRasesh Mody 		rcb_idx++; dq_idx++;
2385e29aa339SRasesh Mody 		q0->rcb->q_depth = rx_cfg->q0_depth;
2386e29aa339SRasesh Mody 		q0->q_depth = rx_cfg->q0_depth;
2387e29aa339SRasesh Mody 		q0->multi_buffer = rx_cfg->q0_multi_buf;
2388e29aa339SRasesh Mody 		q0->buffer_size = rx_cfg->q0_buf_size;
2389e29aa339SRasesh Mody 		q0->num_vecs = rx_cfg->q0_num_vecs;
2390f3bd5173SRasesh Mody 		q0->rcb->rxq = q0;
2391f3bd5173SRasesh Mody 		q0->rcb->bnad = bna->bnad;
2392f3bd5173SRasesh Mody 		q0->rcb->id = 0;
2393f3bd5173SRasesh Mody 		q0->rx_packets = q0->rx_bytes = 0;
2394f3bd5173SRasesh Mody 		q0->rx_packets_with_error = q0->rxbuf_alloc_failed = 0;
2395ba5ca784SIvan Vecera 		q0->rxbuf_map_failed = 0;
2396f3bd5173SRasesh Mody 
2397f3bd5173SRasesh Mody 		bna_rxq_qpt_setup(q0, rxp, dpage_count, PAGE_SIZE,
23985216562aSRasesh Mody 			&dqpt_mem[i], &dsqpt_mem[i], &dpage_mem[i]);
2399f3bd5173SRasesh Mody 
2400f3bd5173SRasesh Mody 		if (rx->rcb_setup_cbfn)
2401f3bd5173SRasesh Mody 			rx->rcb_setup_cbfn(bnad, q0->rcb);
2402f3bd5173SRasesh Mody 
2403f3bd5173SRasesh Mody 		/* Setup small Q */
2404f3bd5173SRasesh Mody 
2405f3bd5173SRasesh Mody 		if (q1) {
2406f3bd5173SRasesh Mody 			q1->rx = rx;
2407f3bd5173SRasesh Mody 			q1->rxp = rxp;
2408f3bd5173SRasesh Mody 
2409f3bd5173SRasesh Mody 			q1->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva;
2410e29aa339SRasesh Mody 			q1->rcb->unmap_q = (void *)hqunmap_mem[hq_idx].kva;
2411e29aa339SRasesh Mody 			rcb_idx++; hq_idx++;
2412e29aa339SRasesh Mody 			q1->rcb->q_depth = rx_cfg->q1_depth;
2413e29aa339SRasesh Mody 			q1->q_depth = rx_cfg->q1_depth;
2414e29aa339SRasesh Mody 			q1->multi_buffer = BNA_STATUS_T_DISABLED;
2415e29aa339SRasesh Mody 			q1->num_vecs = 1;
2416f3bd5173SRasesh Mody 			q1->rcb->rxq = q1;
2417f3bd5173SRasesh Mody 			q1->rcb->bnad = bna->bnad;
2418f3bd5173SRasesh Mody 			q1->rcb->id = 1;
2419f3bd5173SRasesh Mody 			q1->buffer_size = (rx_cfg->rxp_type == BNA_RXP_HDS) ?
2420f3bd5173SRasesh Mody 					rx_cfg->hds_config.forced_offset
2421e29aa339SRasesh Mody 					: rx_cfg->q1_buf_size;
2422f3bd5173SRasesh Mody 			q1->rx_packets = q1->rx_bytes = 0;
2423f3bd5173SRasesh Mody 			q1->rx_packets_with_error = q1->rxbuf_alloc_failed = 0;
2424ba5ca784SIvan Vecera 			q1->rxbuf_map_failed = 0;
2425f3bd5173SRasesh Mody 
2426f3bd5173SRasesh Mody 			bna_rxq_qpt_setup(q1, rxp, hpage_count, PAGE_SIZE,
2427f3bd5173SRasesh Mody 				&hqpt_mem[i], &hsqpt_mem[i],
24285216562aSRasesh Mody 				&hpage_mem[i]);
2429f3bd5173SRasesh Mody 
2430f3bd5173SRasesh Mody 			if (rx->rcb_setup_cbfn)
2431f3bd5173SRasesh Mody 				rx->rcb_setup_cbfn(bnad, q1->rcb);
2432f3bd5173SRasesh Mody 		}
2433f3bd5173SRasesh Mody 
2434f3bd5173SRasesh Mody 		/* Setup CQ */
2435f3bd5173SRasesh Mody 
2436f3bd5173SRasesh Mody 		rxp->cq.ccb = (struct bna_ccb *) ccb_mem[i].kva;
2437e29aa339SRasesh Mody 		cq_depth = rx_cfg->q0_depth +
2438f3bd5173SRasesh Mody 			((rx_cfg->rxp_type == BNA_RXP_SINGLE) ?
2439e29aa339SRasesh Mody 			 0 : rx_cfg->q1_depth);
2440e29aa339SRasesh Mody 		/* if multi-buffer is enabled sum of q0_depth
2441e29aa339SRasesh Mody 		 * and q1_depth need not be a power of 2
2442e29aa339SRasesh Mody 		 */
2443a1ac490dSIvan Vecera 		cq_depth = roundup_pow_of_two(cq_depth);
2444e29aa339SRasesh Mody 		rxp->cq.ccb->q_depth = cq_depth;
2445f3bd5173SRasesh Mody 		rxp->cq.ccb->cq = &rxp->cq;
2446f3bd5173SRasesh Mody 		rxp->cq.ccb->rcb[0] = q0->rcb;
2447f3bd5173SRasesh Mody 		q0->rcb->ccb = rxp->cq.ccb;
2448f3bd5173SRasesh Mody 		if (q1) {
2449f3bd5173SRasesh Mody 			rxp->cq.ccb->rcb[1] = q1->rcb;
2450f3bd5173SRasesh Mody 			q1->rcb->ccb = rxp->cq.ccb;
2451f3bd5173SRasesh Mody 		}
2452f3bd5173SRasesh Mody 		rxp->cq.ccb->hw_producer_index =
2453f3bd5173SRasesh Mody 			(u32 *)rxp->cq.ib.ib_seg_host_addr_kva;
2454f3bd5173SRasesh Mody 		rxp->cq.ccb->i_dbell = &rxp->cq.ib.door_bell;
2455f3bd5173SRasesh Mody 		rxp->cq.ccb->intr_type = rxp->cq.ib.intr_type;
2456f3bd5173SRasesh Mody 		rxp->cq.ccb->intr_vector = rxp->cq.ib.intr_vector;
2457f3bd5173SRasesh Mody 		rxp->cq.ccb->rx_coalescing_timeo =
2458f3bd5173SRasesh Mody 			rxp->cq.ib.coalescing_timeo;
2459f3bd5173SRasesh Mody 		rxp->cq.ccb->pkt_rate.small_pkt_cnt = 0;
2460f3bd5173SRasesh Mody 		rxp->cq.ccb->pkt_rate.large_pkt_cnt = 0;
2461f3bd5173SRasesh Mody 		rxp->cq.ccb->bnad = bna->bnad;
2462f3bd5173SRasesh Mody 		rxp->cq.ccb->id = i;
2463f3bd5173SRasesh Mody 
2464f3bd5173SRasesh Mody 		bna_rxp_cqpt_setup(rxp, page_count, PAGE_SIZE,
24655216562aSRasesh Mody 			&cqpt_mem[i], &cswqpt_mem[i], &cpage_mem[i]);
2466f3bd5173SRasesh Mody 
2467f3bd5173SRasesh Mody 		if (rx->ccb_setup_cbfn)
2468f3bd5173SRasesh Mody 			rx->ccb_setup_cbfn(bnad, rxp->cq.ccb);
2469f3bd5173SRasesh Mody 	}
2470f3bd5173SRasesh Mody 
2471f3bd5173SRasesh Mody 	rx->hds_cfg = rx_cfg->hds_config;
2472f3bd5173SRasesh Mody 
2473f3bd5173SRasesh Mody 	bna_rxf_init(&rx->rxf, rx, rx_cfg, res_info);
2474f3bd5173SRasesh Mody 
2475f3bd5173SRasesh Mody 	bfa_fsm_set_state(rx, bna_rx_sm_stopped);
2476f3bd5173SRasesh Mody 
24771a50691aSIvan Vecera 	rx_mod->rid_mask |= BIT(rx->rid);
2478f3bd5173SRasesh Mody 
2479f3bd5173SRasesh Mody 	return rx;
2480f3bd5173SRasesh Mody }
2481f3bd5173SRasesh Mody 
2482f3bd5173SRasesh Mody void
bna_rx_destroy(struct bna_rx * rx)2483f3bd5173SRasesh Mody bna_rx_destroy(struct bna_rx *rx)
2484f3bd5173SRasesh Mody {
2485f3bd5173SRasesh Mody 	struct bna_rx_mod *rx_mod = &rx->bna->rx_mod;
2486f3bd5173SRasesh Mody 	struct bna_rxq *q0 = NULL;
2487f3bd5173SRasesh Mody 	struct bna_rxq *q1 = NULL;
2488f3bd5173SRasesh Mody 	struct bna_rxp *rxp;
2489f3bd5173SRasesh Mody 	struct list_head *qe;
2490f3bd5173SRasesh Mody 
2491f3bd5173SRasesh Mody 	bna_rxf_uninit(&rx->rxf);
2492f3bd5173SRasesh Mody 
2493f3bd5173SRasesh Mody 	while (!list_empty(&rx->rxp_q)) {
24942b26fb95SIvan Vecera 		rxp = list_first_entry(&rx->rxp_q, struct bna_rxp, qe);
24952b26fb95SIvan Vecera 		list_del(&rxp->qe);
2496f3bd5173SRasesh Mody 		GET_RXQS(rxp, q0, q1);
2497f3bd5173SRasesh Mody 		if (rx->rcb_destroy_cbfn)
2498f3bd5173SRasesh Mody 			rx->rcb_destroy_cbfn(rx->bna->bnad, q0->rcb);
2499f3bd5173SRasesh Mody 		q0->rcb = NULL;
2500f3bd5173SRasesh Mody 		q0->rxp = NULL;
2501f3bd5173SRasesh Mody 		q0->rx = NULL;
2502f3bd5173SRasesh Mody 		bna_rxq_put(rx_mod, q0);
2503f3bd5173SRasesh Mody 
2504f3bd5173SRasesh Mody 		if (q1) {
2505f3bd5173SRasesh Mody 			if (rx->rcb_destroy_cbfn)
2506f3bd5173SRasesh Mody 				rx->rcb_destroy_cbfn(rx->bna->bnad, q1->rcb);
2507f3bd5173SRasesh Mody 			q1->rcb = NULL;
2508f3bd5173SRasesh Mody 			q1->rxp = NULL;
2509f3bd5173SRasesh Mody 			q1->rx = NULL;
2510f3bd5173SRasesh Mody 			bna_rxq_put(rx_mod, q1);
2511f3bd5173SRasesh Mody 		}
2512f3bd5173SRasesh Mody 		rxp->rxq.slr.large = NULL;
2513f3bd5173SRasesh Mody 		rxp->rxq.slr.small = NULL;
2514f3bd5173SRasesh Mody 
2515f3bd5173SRasesh Mody 		if (rx->ccb_destroy_cbfn)
2516f3bd5173SRasesh Mody 			rx->ccb_destroy_cbfn(rx->bna->bnad, rxp->cq.ccb);
2517f3bd5173SRasesh Mody 		rxp->cq.ccb = NULL;
2518f3bd5173SRasesh Mody 		rxp->rx = NULL;
2519f3bd5173SRasesh Mody 		bna_rxp_put(rx_mod, rxp);
2520f3bd5173SRasesh Mody 	}
2521f3bd5173SRasesh Mody 
25222b26fb95SIvan Vecera 	list_for_each(qe, &rx_mod->rx_active_q)
2523f3bd5173SRasesh Mody 		if (qe == &rx->qe) {
2524f3bd5173SRasesh Mody 			list_del(&rx->qe);
2525f3bd5173SRasesh Mody 			break;
2526f3bd5173SRasesh Mody 		}
2527f3bd5173SRasesh Mody 
25281a50691aSIvan Vecera 	rx_mod->rid_mask &= ~BIT(rx->rid);
2529f3bd5173SRasesh Mody 
2530f3bd5173SRasesh Mody 	rx->bna = NULL;
2531f3bd5173SRasesh Mody 	rx->priv = NULL;
2532f3bd5173SRasesh Mody 	bna_rx_put(rx_mod, rx);
2533f3bd5173SRasesh Mody }
2534f3bd5173SRasesh Mody 
2535f3bd5173SRasesh Mody void
bna_rx_enable(struct bna_rx * rx)2536f3bd5173SRasesh Mody bna_rx_enable(struct bna_rx *rx)
2537f3bd5173SRasesh Mody {
2538*8719a1c3SGustavo A. R. Silva 	if (rx->fsm != bna_rx_sm_stopped)
2539f3bd5173SRasesh Mody 		return;
2540f3bd5173SRasesh Mody 
2541f3bd5173SRasesh Mody 	rx->rx_flags |= BNA_RX_F_ENABLED;
2542f3bd5173SRasesh Mody 	if (rx->rx_flags & BNA_RX_F_ENET_STARTED)
2543f3bd5173SRasesh Mody 		bfa_fsm_send_event(rx, RX_E_START);
2544f3bd5173SRasesh Mody }
2545f3bd5173SRasesh Mody 
2546f3bd5173SRasesh Mody void
bna_rx_disable(struct bna_rx * rx,enum bna_cleanup_type type,void (* cbfn)(void *,struct bna_rx *))2547f3bd5173SRasesh Mody bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type,
2548f3bd5173SRasesh Mody 		void (*cbfn)(void *, struct bna_rx *))
2549f3bd5173SRasesh Mody {
2550f3bd5173SRasesh Mody 	if (type == BNA_SOFT_CLEANUP) {
2551f3bd5173SRasesh Mody 		/* h/w should not be accessed. Treat we're stopped */
2552f3bd5173SRasesh Mody 		(*cbfn)(rx->bna->bnad, rx);
2553f3bd5173SRasesh Mody 	} else {
2554f3bd5173SRasesh Mody 		rx->stop_cbfn = cbfn;
2555f3bd5173SRasesh Mody 		rx->stop_cbarg = rx->bna->bnad;
2556f3bd5173SRasesh Mody 
2557f3bd5173SRasesh Mody 		rx->rx_flags &= ~BNA_RX_F_ENABLED;
2558f3bd5173SRasesh Mody 
2559f3bd5173SRasesh Mody 		bfa_fsm_send_event(rx, RX_E_STOP);
2560f3bd5173SRasesh Mody 	}
2561f3bd5173SRasesh Mody }
2562f3bd5173SRasesh Mody 
2563f3bd5173SRasesh Mody void
bna_rx_cleanup_complete(struct bna_rx * rx)2564f3bd5173SRasesh Mody bna_rx_cleanup_complete(struct bna_rx *rx)
2565f3bd5173SRasesh Mody {
2566f3bd5173SRasesh Mody 	bfa_fsm_send_event(rx, RX_E_CLEANUP_DONE);
2567f3bd5173SRasesh Mody }
2568f3bd5173SRasesh Mody 
2569fe1624cfSRasesh Mody void
bna_rx_vlan_strip_enable(struct bna_rx * rx)2570fe1624cfSRasesh Mody bna_rx_vlan_strip_enable(struct bna_rx *rx)
2571fe1624cfSRasesh Mody {
2572fe1624cfSRasesh Mody 	struct bna_rxf *rxf = &rx->rxf;
2573fe1624cfSRasesh Mody 
2574fe1624cfSRasesh Mody 	if (rxf->vlan_strip_status == BNA_STATUS_T_DISABLED) {
2575fe1624cfSRasesh Mody 		rxf->vlan_strip_status = BNA_STATUS_T_ENABLED;
2576fe1624cfSRasesh Mody 		rxf->vlan_strip_pending = true;
2577fe1624cfSRasesh Mody 		bfa_fsm_send_event(rxf, RXF_E_CONFIG);
2578fe1624cfSRasesh Mody 	}
2579fe1624cfSRasesh Mody }
2580fe1624cfSRasesh Mody 
2581fe1624cfSRasesh Mody void
bna_rx_vlan_strip_disable(struct bna_rx * rx)2582fe1624cfSRasesh Mody bna_rx_vlan_strip_disable(struct bna_rx *rx)
2583fe1624cfSRasesh Mody {
2584fe1624cfSRasesh Mody 	struct bna_rxf *rxf = &rx->rxf;
2585fe1624cfSRasesh Mody 
2586fe1624cfSRasesh Mody 	if (rxf->vlan_strip_status != BNA_STATUS_T_DISABLED) {
2587fe1624cfSRasesh Mody 		rxf->vlan_strip_status = BNA_STATUS_T_DISABLED;
2588fe1624cfSRasesh Mody 		rxf->vlan_strip_pending = true;
2589fe1624cfSRasesh Mody 		bfa_fsm_send_event(rxf, RXF_E_CONFIG);
2590fe1624cfSRasesh Mody 	}
2591fe1624cfSRasesh Mody }
2592fe1624cfSRasesh Mody 
2593f3bd5173SRasesh Mody enum bna_cb_status
bna_rx_mode_set(struct bna_rx * rx,enum bna_rxmode new_mode,enum bna_rxmode bitmask)2594f3bd5173SRasesh Mody bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode new_mode,
25951f9883e0SIvan Vecera 		enum bna_rxmode bitmask)
2596f3bd5173SRasesh Mody {
2597f3bd5173SRasesh Mody 	struct bna_rxf *rxf = &rx->rxf;
2598f3bd5173SRasesh Mody 	int need_hw_config = 0;
2599f3bd5173SRasesh Mody 
2600f3bd5173SRasesh Mody 	/* Error checks */
2601f3bd5173SRasesh Mody 
2602f3bd5173SRasesh Mody 	if (is_promisc_enable(new_mode, bitmask)) {
2603f3bd5173SRasesh Mody 		/* If promisc mode is already enabled elsewhere in the system */
2604f3bd5173SRasesh Mody 		if ((rx->bna->promisc_rid != BFI_INVALID_RID) &&
2605f3bd5173SRasesh Mody 			(rx->bna->promisc_rid != rxf->rx->rid))
2606f3bd5173SRasesh Mody 			goto err_return;
2607f3bd5173SRasesh Mody 
2608f3bd5173SRasesh Mody 		/* If default mode is already enabled in the system */
2609f3bd5173SRasesh Mody 		if (rx->bna->default_mode_rid != BFI_INVALID_RID)
2610f3bd5173SRasesh Mody 			goto err_return;
2611f3bd5173SRasesh Mody 
2612f3bd5173SRasesh Mody 		/* Trying to enable promiscuous and default mode together */
2613f3bd5173SRasesh Mody 		if (is_default_enable(new_mode, bitmask))
2614f3bd5173SRasesh Mody 			goto err_return;
2615f3bd5173SRasesh Mody 	}
2616f3bd5173SRasesh Mody 
2617f3bd5173SRasesh Mody 	if (is_default_enable(new_mode, bitmask)) {
2618f3bd5173SRasesh Mody 		/* If default mode is already enabled elsewhere in the system */
2619f3bd5173SRasesh Mody 		if ((rx->bna->default_mode_rid != BFI_INVALID_RID) &&
2620f3bd5173SRasesh Mody 			(rx->bna->default_mode_rid != rxf->rx->rid)) {
2621f3bd5173SRasesh Mody 				goto err_return;
2622f3bd5173SRasesh Mody 		}
2623f3bd5173SRasesh Mody 
2624f3bd5173SRasesh Mody 		/* If promiscuous mode is already enabled in the system */
2625f3bd5173SRasesh Mody 		if (rx->bna->promisc_rid != BFI_INVALID_RID)
2626f3bd5173SRasesh Mody 			goto err_return;
2627f3bd5173SRasesh Mody 	}
2628f3bd5173SRasesh Mody 
2629f3bd5173SRasesh Mody 	/* Process the commands */
2630f3bd5173SRasesh Mody 
2631f3bd5173SRasesh Mody 	if (is_promisc_enable(new_mode, bitmask)) {
2632f3bd5173SRasesh Mody 		if (bna_rxf_promisc_enable(rxf))
2633f3bd5173SRasesh Mody 			need_hw_config = 1;
2634f3bd5173SRasesh Mody 	} else if (is_promisc_disable(new_mode, bitmask)) {
2635f3bd5173SRasesh Mody 		if (bna_rxf_promisc_disable(rxf))
2636f3bd5173SRasesh Mody 			need_hw_config = 1;
2637f3bd5173SRasesh Mody 	}
2638f3bd5173SRasesh Mody 
2639f3bd5173SRasesh Mody 	if (is_allmulti_enable(new_mode, bitmask)) {
2640f3bd5173SRasesh Mody 		if (bna_rxf_allmulti_enable(rxf))
2641f3bd5173SRasesh Mody 			need_hw_config = 1;
2642f3bd5173SRasesh Mody 	} else if (is_allmulti_disable(new_mode, bitmask)) {
2643f3bd5173SRasesh Mody 		if (bna_rxf_allmulti_disable(rxf))
2644f3bd5173SRasesh Mody 			need_hw_config = 1;
2645f3bd5173SRasesh Mody 	}
2646f3bd5173SRasesh Mody 
2647f3bd5173SRasesh Mody 	/* Trigger h/w if needed */
2648f3bd5173SRasesh Mody 
2649f3bd5173SRasesh Mody 	if (need_hw_config) {
26501f9883e0SIvan Vecera 		rxf->cam_fltr_cbfn = NULL;
2651f3bd5173SRasesh Mody 		rxf->cam_fltr_cbarg = rx->bna->bnad;
2652f3bd5173SRasesh Mody 		bfa_fsm_send_event(rxf, RXF_E_CONFIG);
26531f9883e0SIvan Vecera 	}
2654f3bd5173SRasesh Mody 
2655f3bd5173SRasesh Mody 	return BNA_CB_SUCCESS;
2656f3bd5173SRasesh Mody 
2657f3bd5173SRasesh Mody err_return:
2658f3bd5173SRasesh Mody 	return BNA_CB_FAIL;
2659f3bd5173SRasesh Mody }
2660f3bd5173SRasesh Mody 
2661f3bd5173SRasesh Mody void
bna_rx_vlanfilter_enable(struct bna_rx * rx)2662f3bd5173SRasesh Mody bna_rx_vlanfilter_enable(struct bna_rx *rx)
2663f3bd5173SRasesh Mody {
2664f3bd5173SRasesh Mody 	struct bna_rxf *rxf = &rx->rxf;
2665f3bd5173SRasesh Mody 
2666f3bd5173SRasesh Mody 	if (rxf->vlan_filter_status == BNA_STATUS_T_DISABLED) {
2667f3bd5173SRasesh Mody 		rxf->vlan_filter_status = BNA_STATUS_T_ENABLED;
2668f3bd5173SRasesh Mody 		rxf->vlan_pending_bitmask = (u8)BFI_VLAN_BMASK_ALL;
2669f3bd5173SRasesh Mody 		bfa_fsm_send_event(rxf, RXF_E_CONFIG);
2670f3bd5173SRasesh Mody 	}
2671f3bd5173SRasesh Mody }
2672f3bd5173SRasesh Mody 
2673f3bd5173SRasesh Mody void
bna_rx_coalescing_timeo_set(struct bna_rx * rx,int coalescing_timeo)2674f3bd5173SRasesh Mody bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo)
2675f3bd5173SRasesh Mody {
2676f3bd5173SRasesh Mody 	struct bna_rxp *rxp;
2677f3bd5173SRasesh Mody 
267816712c53SIvan Vecera 	list_for_each_entry(rxp, &rx->rxp_q, qe) {
2679f3bd5173SRasesh Mody 		rxp->cq.ccb->rx_coalescing_timeo = coalescing_timeo;
2680f3bd5173SRasesh Mody 		bna_ib_coalescing_timeo_set(&rxp->cq.ib, coalescing_timeo);
2681f3bd5173SRasesh Mody 	}
2682f3bd5173SRasesh Mody }
2683f3bd5173SRasesh Mody 
2684f3bd5173SRasesh Mody void
bna_rx_dim_reconfig(struct bna * bna,const u32 vector[][BNA_BIAS_T_MAX])2685f3bd5173SRasesh Mody bna_rx_dim_reconfig(struct bna *bna, const u32 vector[][BNA_BIAS_T_MAX])
2686f3bd5173SRasesh Mody {
2687f3bd5173SRasesh Mody 	int i, j;
2688f3bd5173SRasesh Mody 
2689f3bd5173SRasesh Mody 	for (i = 0; i < BNA_LOAD_T_MAX; i++)
2690f3bd5173SRasesh Mody 		for (j = 0; j < BNA_BIAS_T_MAX; j++)
2691f3bd5173SRasesh Mody 			bna->rx_mod.dim_vector[i][j] = vector[i][j];
2692f3bd5173SRasesh Mody }
2693f3bd5173SRasesh Mody 
2694f3bd5173SRasesh Mody void
bna_rx_dim_update(struct bna_ccb * ccb)2695f3bd5173SRasesh Mody bna_rx_dim_update(struct bna_ccb *ccb)
2696f3bd5173SRasesh Mody {
2697f3bd5173SRasesh Mody 	struct bna *bna = ccb->cq->rx->bna;
2698f3bd5173SRasesh Mody 	u32 load, bias;
2699f3bd5173SRasesh Mody 	u32 pkt_rt, small_rt, large_rt;
2700f3bd5173SRasesh Mody 	u8 coalescing_timeo;
2701f3bd5173SRasesh Mody 
2702f3bd5173SRasesh Mody 	if ((ccb->pkt_rate.small_pkt_cnt == 0) &&
2703f3bd5173SRasesh Mody 		(ccb->pkt_rate.large_pkt_cnt == 0))
2704f3bd5173SRasesh Mody 		return;
2705f3bd5173SRasesh Mody 
2706f3bd5173SRasesh Mody 	/* Arrive at preconfigured coalescing timeo value based on pkt rate */
2707f3bd5173SRasesh Mody 
2708f3bd5173SRasesh Mody 	small_rt = ccb->pkt_rate.small_pkt_cnt;
2709f3bd5173SRasesh Mody 	large_rt = ccb->pkt_rate.large_pkt_cnt;
2710f3bd5173SRasesh Mody 
2711f3bd5173SRasesh Mody 	pkt_rt = small_rt + large_rt;
2712f3bd5173SRasesh Mody 
2713f3bd5173SRasesh Mody 	if (pkt_rt < BNA_PKT_RATE_10K)
2714f3bd5173SRasesh Mody 		load = BNA_LOAD_T_LOW_4;
2715f3bd5173SRasesh Mody 	else if (pkt_rt < BNA_PKT_RATE_20K)
2716f3bd5173SRasesh Mody 		load = BNA_LOAD_T_LOW_3;
2717f3bd5173SRasesh Mody 	else if (pkt_rt < BNA_PKT_RATE_30K)
2718f3bd5173SRasesh Mody 		load = BNA_LOAD_T_LOW_2;
2719f3bd5173SRasesh Mody 	else if (pkt_rt < BNA_PKT_RATE_40K)
2720f3bd5173SRasesh Mody 		load = BNA_LOAD_T_LOW_1;
2721f3bd5173SRasesh Mody 	else if (pkt_rt < BNA_PKT_RATE_50K)
2722f3bd5173SRasesh Mody 		load = BNA_LOAD_T_HIGH_1;
2723f3bd5173SRasesh Mody 	else if (pkt_rt < BNA_PKT_RATE_60K)
2724f3bd5173SRasesh Mody 		load = BNA_LOAD_T_HIGH_2;
2725f3bd5173SRasesh Mody 	else if (pkt_rt < BNA_PKT_RATE_80K)
2726f3bd5173SRasesh Mody 		load = BNA_LOAD_T_HIGH_3;
2727f3bd5173SRasesh Mody 	else
2728f3bd5173SRasesh Mody 		load = BNA_LOAD_T_HIGH_4;
2729f3bd5173SRasesh Mody 
2730f3bd5173SRasesh Mody 	if (small_rt > (large_rt << 1))
2731f3bd5173SRasesh Mody 		bias = 0;
2732f3bd5173SRasesh Mody 	else
2733f3bd5173SRasesh Mody 		bias = 1;
2734f3bd5173SRasesh Mody 
2735f3bd5173SRasesh Mody 	ccb->pkt_rate.small_pkt_cnt = 0;
2736f3bd5173SRasesh Mody 	ccb->pkt_rate.large_pkt_cnt = 0;
2737f3bd5173SRasesh Mody 
2738f3bd5173SRasesh Mody 	coalescing_timeo = bna->rx_mod.dim_vector[load][bias];
2739f3bd5173SRasesh Mody 	ccb->rx_coalescing_timeo = coalescing_timeo;
2740f3bd5173SRasesh Mody 
2741f3bd5173SRasesh Mody 	/* Set it to IB */
2742f3bd5173SRasesh Mody 	bna_ib_coalescing_timeo_set(&ccb->cq->ib, coalescing_timeo);
2743f3bd5173SRasesh Mody }
2744f3bd5173SRasesh Mody 
2745f3bd5173SRasesh Mody const u32 bna_napi_dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX] = {
2746f3bd5173SRasesh Mody 	{12, 12},
2747f3bd5173SRasesh Mody 	{6, 10},
2748f3bd5173SRasesh Mody 	{5, 10},
2749f3bd5173SRasesh Mody 	{4, 8},
2750f3bd5173SRasesh Mody 	{3, 6},
2751f3bd5173SRasesh Mody 	{3, 6},
2752f3bd5173SRasesh Mody 	{2, 4},
2753f3bd5173SRasesh Mody 	{1, 2},
2754f3bd5173SRasesh Mody };
2755f3bd5173SRasesh Mody 
27561aa8b471SBen Hutchings /* TX */
27571aa8b471SBen Hutchings 
2758f3bd5173SRasesh Mody #define call_tx_stop_cbfn(tx)						\
2759f3bd5173SRasesh Mody do {									\
2760f3bd5173SRasesh Mody 	if ((tx)->stop_cbfn) {						\
2761f3bd5173SRasesh Mody 		void (*cbfn)(void *, struct bna_tx *);		\
2762f3bd5173SRasesh Mody 		void *cbarg;						\
2763f3bd5173SRasesh Mody 		cbfn = (tx)->stop_cbfn;					\
2764f3bd5173SRasesh Mody 		cbarg = (tx)->stop_cbarg;				\
2765f3bd5173SRasesh Mody 		(tx)->stop_cbfn = NULL;					\
2766f3bd5173SRasesh Mody 		(tx)->stop_cbarg = NULL;				\
2767f3bd5173SRasesh Mody 		cbfn(cbarg, (tx));					\
2768f3bd5173SRasesh Mody 	}								\
2769f3bd5173SRasesh Mody } while (0)
2770f3bd5173SRasesh Mody 
2771f3bd5173SRasesh Mody static void bna_tx_mod_cb_tx_stopped(void *tx_mod, struct bna_tx *tx);
2772f3bd5173SRasesh Mody static void bna_bfi_tx_enet_start(struct bna_tx *tx);
2773f3bd5173SRasesh Mody static void bna_tx_enet_stop(struct bna_tx *tx);
2774f3bd5173SRasesh Mody 
2775f3bd5173SRasesh Mody enum bna_tx_event {
2776f3bd5173SRasesh Mody 	TX_E_START			= 1,
2777f3bd5173SRasesh Mody 	TX_E_STOP			= 2,
2778f3bd5173SRasesh Mody 	TX_E_FAIL			= 3,
2779f3bd5173SRasesh Mody 	TX_E_STARTED			= 4,
2780f3bd5173SRasesh Mody 	TX_E_STOPPED			= 5,
2781f3bd5173SRasesh Mody 	TX_E_CLEANUP_DONE		= 7,
2782f3bd5173SRasesh Mody 	TX_E_BW_UPDATE			= 8,
2783f3bd5173SRasesh Mody };
2784f3bd5173SRasesh Mody 
2785f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_tx, stopped, struct bna_tx, enum bna_tx_event);
2786f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_tx, start_wait, struct bna_tx, enum bna_tx_event);
2787f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_tx, started, struct bna_tx, enum bna_tx_event);
2788f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_tx, stop_wait, struct bna_tx, enum bna_tx_event);
2789f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_tx, cleanup_wait, struct bna_tx,
2790f3bd5173SRasesh Mody 			enum bna_tx_event);
2791f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_tx, prio_stop_wait, struct bna_tx,
2792f3bd5173SRasesh Mody 			enum bna_tx_event);
2793f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_tx, prio_cleanup_wait, struct bna_tx,
2794f3bd5173SRasesh Mody 			enum bna_tx_event);
2795f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_tx, failed, struct bna_tx, enum bna_tx_event);
2796f3bd5173SRasesh Mody bfa_fsm_state_decl(bna_tx, quiesce_wait, struct bna_tx,
2797f3bd5173SRasesh Mody 			enum bna_tx_event);
2798f3bd5173SRasesh Mody 
2799f3bd5173SRasesh Mody static void
bna_tx_sm_stopped_entry(struct bna_tx * tx)2800f3bd5173SRasesh Mody bna_tx_sm_stopped_entry(struct bna_tx *tx)
2801f3bd5173SRasesh Mody {
2802f3bd5173SRasesh Mody 	call_tx_stop_cbfn(tx);
2803f3bd5173SRasesh Mody }
2804f3bd5173SRasesh Mody 
2805f3bd5173SRasesh Mody static void
bna_tx_sm_stopped(struct bna_tx * tx,enum bna_tx_event event)2806f3bd5173SRasesh Mody bna_tx_sm_stopped(struct bna_tx *tx, enum bna_tx_event event)
2807f3bd5173SRasesh Mody {
2808f3bd5173SRasesh Mody 	switch (event) {
2809f3bd5173SRasesh Mody 	case TX_E_START:
2810f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_start_wait);
2811f3bd5173SRasesh Mody 		break;
2812f3bd5173SRasesh Mody 
2813f3bd5173SRasesh Mody 	case TX_E_STOP:
2814f3bd5173SRasesh Mody 		call_tx_stop_cbfn(tx);
2815f3bd5173SRasesh Mody 		break;
2816f3bd5173SRasesh Mody 
2817f3bd5173SRasesh Mody 	case TX_E_FAIL:
2818f3bd5173SRasesh Mody 		/* No-op */
2819f3bd5173SRasesh Mody 		break;
2820f3bd5173SRasesh Mody 
2821f3bd5173SRasesh Mody 	case TX_E_BW_UPDATE:
2822f3bd5173SRasesh Mody 		/* No-op */
2823f3bd5173SRasesh Mody 		break;
2824f3bd5173SRasesh Mody 
2825f3bd5173SRasesh Mody 	default:
2826f3bd5173SRasesh Mody 		bfa_sm_fault(event);
2827f3bd5173SRasesh Mody 	}
2828f3bd5173SRasesh Mody }
2829f3bd5173SRasesh Mody 
2830f3bd5173SRasesh Mody static void
bna_tx_sm_start_wait_entry(struct bna_tx * tx)2831f3bd5173SRasesh Mody bna_tx_sm_start_wait_entry(struct bna_tx *tx)
2832f3bd5173SRasesh Mody {
2833f3bd5173SRasesh Mody 	bna_bfi_tx_enet_start(tx);
2834f3bd5173SRasesh Mody }
2835f3bd5173SRasesh Mody 
2836f3bd5173SRasesh Mody static void
bna_tx_sm_start_wait(struct bna_tx * tx,enum bna_tx_event event)2837f3bd5173SRasesh Mody bna_tx_sm_start_wait(struct bna_tx *tx, enum bna_tx_event event)
2838f3bd5173SRasesh Mody {
2839f3bd5173SRasesh Mody 	switch (event) {
2840f3bd5173SRasesh Mody 	case TX_E_STOP:
28412a2d75c0SIvan Vecera 		tx->flags &= ~BNA_TX_F_BW_UPDATED;
2842f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_stop_wait);
2843f3bd5173SRasesh Mody 		break;
2844f3bd5173SRasesh Mody 
2845f3bd5173SRasesh Mody 	case TX_E_FAIL:
28462a2d75c0SIvan Vecera 		tx->flags &= ~BNA_TX_F_BW_UPDATED;
2847f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_stopped);
2848f3bd5173SRasesh Mody 		break;
2849f3bd5173SRasesh Mody 
2850f3bd5173SRasesh Mody 	case TX_E_STARTED:
28512a2d75c0SIvan Vecera 		if (tx->flags & BNA_TX_F_BW_UPDATED) {
28522a2d75c0SIvan Vecera 			tx->flags &= ~BNA_TX_F_BW_UPDATED;
2853f3bd5173SRasesh Mody 			bfa_fsm_set_state(tx, bna_tx_sm_prio_stop_wait);
2854f3bd5173SRasesh Mody 		} else
2855f3bd5173SRasesh Mody 			bfa_fsm_set_state(tx, bna_tx_sm_started);
2856f3bd5173SRasesh Mody 		break;
2857f3bd5173SRasesh Mody 
2858f3bd5173SRasesh Mody 	case TX_E_BW_UPDATE:
2859f3bd5173SRasesh Mody 		tx->flags |= BNA_TX_F_BW_UPDATED;
2860f3bd5173SRasesh Mody 		break;
2861f3bd5173SRasesh Mody 
2862f3bd5173SRasesh Mody 	default:
2863f3bd5173SRasesh Mody 		bfa_sm_fault(event);
2864f3bd5173SRasesh Mody 	}
2865f3bd5173SRasesh Mody }
2866f3bd5173SRasesh Mody 
2867f3bd5173SRasesh Mody static void
bna_tx_sm_started_entry(struct bna_tx * tx)2868f3bd5173SRasesh Mody bna_tx_sm_started_entry(struct bna_tx *tx)
2869f3bd5173SRasesh Mody {
2870f3bd5173SRasesh Mody 	struct bna_txq *txq;
2871f3bd5173SRasesh Mody 	int is_regular = (tx->type == BNA_TX_T_REGULAR);
2872f3bd5173SRasesh Mody 
287316712c53SIvan Vecera 	list_for_each_entry(txq, &tx->txq_q, qe) {
2874f3bd5173SRasesh Mody 		txq->tcb->priority = txq->priority;
2875f3bd5173SRasesh Mody 		/* Start IB */
2876f3bd5173SRasesh Mody 		bna_ib_start(tx->bna, &txq->ib, is_regular);
2877f3bd5173SRasesh Mody 	}
2878f3bd5173SRasesh Mody 	tx->tx_resume_cbfn(tx->bna->bnad, tx);
2879f3bd5173SRasesh Mody }
2880f3bd5173SRasesh Mody 
2881f3bd5173SRasesh Mody static void
bna_tx_sm_started(struct bna_tx * tx,enum bna_tx_event event)2882f3bd5173SRasesh Mody bna_tx_sm_started(struct bna_tx *tx, enum bna_tx_event event)
2883f3bd5173SRasesh Mody {
2884f3bd5173SRasesh Mody 	switch (event) {
2885f3bd5173SRasesh Mody 	case TX_E_STOP:
2886f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_stop_wait);
2887f3bd5173SRasesh Mody 		tx->tx_stall_cbfn(tx->bna->bnad, tx);
2888f3bd5173SRasesh Mody 		bna_tx_enet_stop(tx);
2889f3bd5173SRasesh Mody 		break;
2890f3bd5173SRasesh Mody 
2891f3bd5173SRasesh Mody 	case TX_E_FAIL:
2892f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_failed);
2893f3bd5173SRasesh Mody 		tx->tx_stall_cbfn(tx->bna->bnad, tx);
2894f3bd5173SRasesh Mody 		tx->tx_cleanup_cbfn(tx->bna->bnad, tx);
2895f3bd5173SRasesh Mody 		break;
2896f3bd5173SRasesh Mody 
2897f3bd5173SRasesh Mody 	case TX_E_BW_UPDATE:
2898f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_prio_stop_wait);
2899f3bd5173SRasesh Mody 		break;
2900f3bd5173SRasesh Mody 
2901f3bd5173SRasesh Mody 	default:
2902f3bd5173SRasesh Mody 		bfa_sm_fault(event);
2903f3bd5173SRasesh Mody 	}
2904f3bd5173SRasesh Mody }
2905f3bd5173SRasesh Mody 
2906f3bd5173SRasesh Mody static void
bna_tx_sm_stop_wait_entry(struct bna_tx * tx)2907f3bd5173SRasesh Mody bna_tx_sm_stop_wait_entry(struct bna_tx *tx)
2908f3bd5173SRasesh Mody {
2909f3bd5173SRasesh Mody }
2910f3bd5173SRasesh Mody 
2911f3bd5173SRasesh Mody static void
bna_tx_sm_stop_wait(struct bna_tx * tx,enum bna_tx_event event)2912f3bd5173SRasesh Mody bna_tx_sm_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
2913f3bd5173SRasesh Mody {
2914f3bd5173SRasesh Mody 	switch (event) {
2915f3bd5173SRasesh Mody 	case TX_E_FAIL:
2916f3bd5173SRasesh Mody 	case TX_E_STOPPED:
2917f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_cleanup_wait);
2918f3bd5173SRasesh Mody 		tx->tx_cleanup_cbfn(tx->bna->bnad, tx);
2919f3bd5173SRasesh Mody 		break;
2920f3bd5173SRasesh Mody 
2921f3bd5173SRasesh Mody 	case TX_E_STARTED:
2922f3bd5173SRasesh Mody 		/**
2923f3bd5173SRasesh Mody 		 * We are here due to start_wait -> stop_wait transition on
2924f3bd5173SRasesh Mody 		 * TX_E_STOP event
2925f3bd5173SRasesh Mody 		 */
2926f3bd5173SRasesh Mody 		bna_tx_enet_stop(tx);
2927f3bd5173SRasesh Mody 		break;
2928f3bd5173SRasesh Mody 
2929f3bd5173SRasesh Mody 	case TX_E_BW_UPDATE:
2930f3bd5173SRasesh Mody 		/* No-op */
2931f3bd5173SRasesh Mody 		break;
2932f3bd5173SRasesh Mody 
2933f3bd5173SRasesh Mody 	default:
2934f3bd5173SRasesh Mody 		bfa_sm_fault(event);
2935f3bd5173SRasesh Mody 	}
2936f3bd5173SRasesh Mody }
2937f3bd5173SRasesh Mody 
2938f3bd5173SRasesh Mody static void
bna_tx_sm_cleanup_wait_entry(struct bna_tx * tx)2939f3bd5173SRasesh Mody bna_tx_sm_cleanup_wait_entry(struct bna_tx *tx)
2940f3bd5173SRasesh Mody {
2941f3bd5173SRasesh Mody }
2942f3bd5173SRasesh Mody 
2943f3bd5173SRasesh Mody static void
bna_tx_sm_cleanup_wait(struct bna_tx * tx,enum bna_tx_event event)2944f3bd5173SRasesh Mody bna_tx_sm_cleanup_wait(struct bna_tx *tx, enum bna_tx_event event)
2945f3bd5173SRasesh Mody {
2946f3bd5173SRasesh Mody 	switch (event) {
2947f3bd5173SRasesh Mody 	case TX_E_FAIL:
2948f3bd5173SRasesh Mody 	case TX_E_BW_UPDATE:
2949f3bd5173SRasesh Mody 		/* No-op */
2950f3bd5173SRasesh Mody 		break;
2951f3bd5173SRasesh Mody 
2952f3bd5173SRasesh Mody 	case TX_E_CLEANUP_DONE:
2953f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_stopped);
2954f3bd5173SRasesh Mody 		break;
2955f3bd5173SRasesh Mody 
2956f3bd5173SRasesh Mody 	default:
2957f3bd5173SRasesh Mody 		bfa_sm_fault(event);
2958f3bd5173SRasesh Mody 	}
2959f3bd5173SRasesh Mody }
2960f3bd5173SRasesh Mody 
2961f3bd5173SRasesh Mody static void
bna_tx_sm_prio_stop_wait_entry(struct bna_tx * tx)2962f3bd5173SRasesh Mody bna_tx_sm_prio_stop_wait_entry(struct bna_tx *tx)
2963f3bd5173SRasesh Mody {
2964f3bd5173SRasesh Mody 	tx->tx_stall_cbfn(tx->bna->bnad, tx);
2965f3bd5173SRasesh Mody 	bna_tx_enet_stop(tx);
2966f3bd5173SRasesh Mody }
2967f3bd5173SRasesh Mody 
2968f3bd5173SRasesh Mody static void
bna_tx_sm_prio_stop_wait(struct bna_tx * tx,enum bna_tx_event event)2969f3bd5173SRasesh Mody bna_tx_sm_prio_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
2970f3bd5173SRasesh Mody {
2971f3bd5173SRasesh Mody 	switch (event) {
2972f3bd5173SRasesh Mody 	case TX_E_STOP:
2973f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_stop_wait);
2974f3bd5173SRasesh Mody 		break;
2975f3bd5173SRasesh Mody 
2976f3bd5173SRasesh Mody 	case TX_E_FAIL:
2977f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_failed);
2978f3bd5173SRasesh Mody 		tx->tx_cleanup_cbfn(tx->bna->bnad, tx);
2979f3bd5173SRasesh Mody 		break;
2980f3bd5173SRasesh Mody 
2981f3bd5173SRasesh Mody 	case TX_E_STOPPED:
2982f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_prio_cleanup_wait);
2983f3bd5173SRasesh Mody 		break;
2984f3bd5173SRasesh Mody 
2985f3bd5173SRasesh Mody 	case TX_E_BW_UPDATE:
2986f3bd5173SRasesh Mody 		/* No-op */
2987f3bd5173SRasesh Mody 		break;
2988f3bd5173SRasesh Mody 
2989f3bd5173SRasesh Mody 	default:
2990f3bd5173SRasesh Mody 		bfa_sm_fault(event);
2991f3bd5173SRasesh Mody 	}
2992f3bd5173SRasesh Mody }
2993f3bd5173SRasesh Mody 
2994f3bd5173SRasesh Mody static void
bna_tx_sm_prio_cleanup_wait_entry(struct bna_tx * tx)2995f3bd5173SRasesh Mody bna_tx_sm_prio_cleanup_wait_entry(struct bna_tx *tx)
2996f3bd5173SRasesh Mody {
2997f3bd5173SRasesh Mody 	tx->tx_cleanup_cbfn(tx->bna->bnad, tx);
2998f3bd5173SRasesh Mody }
2999f3bd5173SRasesh Mody 
3000f3bd5173SRasesh Mody static void
bna_tx_sm_prio_cleanup_wait(struct bna_tx * tx,enum bna_tx_event event)3001f3bd5173SRasesh Mody bna_tx_sm_prio_cleanup_wait(struct bna_tx *tx, enum bna_tx_event event)
3002f3bd5173SRasesh Mody {
3003f3bd5173SRasesh Mody 	switch (event) {
3004f3bd5173SRasesh Mody 	case TX_E_STOP:
3005f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_cleanup_wait);
3006f3bd5173SRasesh Mody 		break;
3007f3bd5173SRasesh Mody 
3008f3bd5173SRasesh Mody 	case TX_E_FAIL:
3009f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_failed);
3010f3bd5173SRasesh Mody 		break;
3011f3bd5173SRasesh Mody 
3012f3bd5173SRasesh Mody 	case TX_E_BW_UPDATE:
3013f3bd5173SRasesh Mody 		/* No-op */
3014f3bd5173SRasesh Mody 		break;
3015f3bd5173SRasesh Mody 
3016f3bd5173SRasesh Mody 	case TX_E_CLEANUP_DONE:
3017f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_start_wait);
3018f3bd5173SRasesh Mody 		break;
3019f3bd5173SRasesh Mody 
3020f3bd5173SRasesh Mody 	default:
3021f3bd5173SRasesh Mody 		bfa_sm_fault(event);
3022f3bd5173SRasesh Mody 	}
3023f3bd5173SRasesh Mody }
3024f3bd5173SRasesh Mody 
3025f3bd5173SRasesh Mody static void
bna_tx_sm_failed_entry(struct bna_tx * tx)3026f3bd5173SRasesh Mody bna_tx_sm_failed_entry(struct bna_tx *tx)
3027f3bd5173SRasesh Mody {
3028f3bd5173SRasesh Mody }
3029f3bd5173SRasesh Mody 
3030f3bd5173SRasesh Mody static void
bna_tx_sm_failed(struct bna_tx * tx,enum bna_tx_event event)3031f3bd5173SRasesh Mody bna_tx_sm_failed(struct bna_tx *tx, enum bna_tx_event event)
3032f3bd5173SRasesh Mody {
3033f3bd5173SRasesh Mody 	switch (event) {
3034f3bd5173SRasesh Mody 	case TX_E_START:
3035f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_quiesce_wait);
3036f3bd5173SRasesh Mody 		break;
3037f3bd5173SRasesh Mody 
3038f3bd5173SRasesh Mody 	case TX_E_STOP:
3039f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_cleanup_wait);
3040f3bd5173SRasesh Mody 		break;
3041f3bd5173SRasesh Mody 
3042f3bd5173SRasesh Mody 	case TX_E_FAIL:
3043f3bd5173SRasesh Mody 		/* No-op */
3044f3bd5173SRasesh Mody 		break;
3045f3bd5173SRasesh Mody 
3046f3bd5173SRasesh Mody 	case TX_E_CLEANUP_DONE:
3047f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_stopped);
3048f3bd5173SRasesh Mody 		break;
3049f3bd5173SRasesh Mody 
3050f3bd5173SRasesh Mody 	default:
3051f3bd5173SRasesh Mody 		bfa_sm_fault(event);
3052f3bd5173SRasesh Mody 	}
3053f3bd5173SRasesh Mody }
3054f3bd5173SRasesh Mody 
3055f3bd5173SRasesh Mody static void
bna_tx_sm_quiesce_wait_entry(struct bna_tx * tx)3056f3bd5173SRasesh Mody bna_tx_sm_quiesce_wait_entry(struct bna_tx *tx)
3057f3bd5173SRasesh Mody {
3058f3bd5173SRasesh Mody }
3059f3bd5173SRasesh Mody 
3060f3bd5173SRasesh Mody static void
bna_tx_sm_quiesce_wait(struct bna_tx * tx,enum bna_tx_event event)3061f3bd5173SRasesh Mody bna_tx_sm_quiesce_wait(struct bna_tx *tx, enum bna_tx_event event)
3062f3bd5173SRasesh Mody {
3063f3bd5173SRasesh Mody 	switch (event) {
3064f3bd5173SRasesh Mody 	case TX_E_STOP:
3065f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_cleanup_wait);
3066f3bd5173SRasesh Mody 		break;
3067f3bd5173SRasesh Mody 
3068f3bd5173SRasesh Mody 	case TX_E_FAIL:
3069f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_failed);
3070f3bd5173SRasesh Mody 		break;
3071f3bd5173SRasesh Mody 
3072f3bd5173SRasesh Mody 	case TX_E_CLEANUP_DONE:
3073f3bd5173SRasesh Mody 		bfa_fsm_set_state(tx, bna_tx_sm_start_wait);
3074f3bd5173SRasesh Mody 		break;
3075f3bd5173SRasesh Mody 
3076f3bd5173SRasesh Mody 	case TX_E_BW_UPDATE:
3077f3bd5173SRasesh Mody 		/* No-op */
3078f3bd5173SRasesh Mody 		break;
3079f3bd5173SRasesh Mody 
3080f3bd5173SRasesh Mody 	default:
3081f3bd5173SRasesh Mody 		bfa_sm_fault(event);
3082f3bd5173SRasesh Mody 	}
3083f3bd5173SRasesh Mody }
3084f3bd5173SRasesh Mody 
3085f3bd5173SRasesh Mody static void
bna_bfi_tx_enet_start(struct bna_tx * tx)3086f3bd5173SRasesh Mody bna_bfi_tx_enet_start(struct bna_tx *tx)
3087f3bd5173SRasesh Mody {
3088f3bd5173SRasesh Mody 	struct bfi_enet_tx_cfg_req *cfg_req = &tx->bfi_enet_cmd.cfg_req;
3089f3bd5173SRasesh Mody 	struct bna_txq *txq = NULL;
3090f3bd5173SRasesh Mody 	int i;
3091f3bd5173SRasesh Mody 
3092f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(cfg_req->mh, BFI_MC_ENET,
3093f3bd5173SRasesh Mody 		BFI_ENET_H2I_TX_CFG_SET_REQ, 0, tx->rid);
3094f3bd5173SRasesh Mody 	cfg_req->mh.num_entries = htons(
3095f3bd5173SRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_tx_cfg_req)));
3096f3bd5173SRasesh Mody 
3097f3bd5173SRasesh Mody 	cfg_req->num_queues = tx->num_txq;
30982b26fb95SIvan Vecera 	for (i = 0; i < tx->num_txq; i++) {
30992b26fb95SIvan Vecera 		txq = txq ? list_next_entry(txq, qe)
31002b26fb95SIvan Vecera 			: list_first_entry(&tx->txq_q, struct bna_txq, qe);
3101f3bd5173SRasesh Mody 		bfi_enet_datapath_q_init(&cfg_req->q_cfg[i].q.q, &txq->qpt);
3102f3bd5173SRasesh Mody 		cfg_req->q_cfg[i].q.priority = txq->priority;
3103f3bd5173SRasesh Mody 
3104f3bd5173SRasesh Mody 		cfg_req->q_cfg[i].ib.index_addr.a32.addr_lo =
3105f3bd5173SRasesh Mody 			txq->ib.ib_seg_host_addr.lsb;
3106f3bd5173SRasesh Mody 		cfg_req->q_cfg[i].ib.index_addr.a32.addr_hi =
3107f3bd5173SRasesh Mody 			txq->ib.ib_seg_host_addr.msb;
3108f3bd5173SRasesh Mody 		cfg_req->q_cfg[i].ib.intr.msix_index =
3109f3bd5173SRasesh Mody 			htons((u16)txq->ib.intr_vector);
3110f3bd5173SRasesh Mody 	}
3111f3bd5173SRasesh Mody 
3112f3bd5173SRasesh Mody 	cfg_req->ib_cfg.int_pkt_dma = BNA_STATUS_T_ENABLED;
3113f3bd5173SRasesh Mody 	cfg_req->ib_cfg.int_enabled = BNA_STATUS_T_ENABLED;
3114f3bd5173SRasesh Mody 	cfg_req->ib_cfg.int_pkt_enabled = BNA_STATUS_T_DISABLED;
3115f3bd5173SRasesh Mody 	cfg_req->ib_cfg.continuous_coalescing = BNA_STATUS_T_ENABLED;
3116f3bd5173SRasesh Mody 	cfg_req->ib_cfg.msix = (txq->ib.intr_type == BNA_INTR_T_MSIX)
3117f3bd5173SRasesh Mody 				? BNA_STATUS_T_ENABLED : BNA_STATUS_T_DISABLED;
3118f3bd5173SRasesh Mody 	cfg_req->ib_cfg.coalescing_timeout =
3119f3bd5173SRasesh Mody 			htonl((u32)txq->ib.coalescing_timeo);
3120f3bd5173SRasesh Mody 	cfg_req->ib_cfg.inter_pkt_timeout =
3121f3bd5173SRasesh Mody 			htonl((u32)txq->ib.interpkt_timeo);
3122f3bd5173SRasesh Mody 	cfg_req->ib_cfg.inter_pkt_count = (u8)txq->ib.interpkt_count;
3123f3bd5173SRasesh Mody 
3124f3bd5173SRasesh Mody 	cfg_req->tx_cfg.vlan_mode = BFI_ENET_TX_VLAN_WI;
3125f3bd5173SRasesh Mody 	cfg_req->tx_cfg.vlan_id = htons((u16)tx->txf_vlan_id);
31266654cf60SIvan Vecera 	cfg_req->tx_cfg.admit_tagged_frame = BNA_STATUS_T_ENABLED;
3127f3bd5173SRasesh Mody 	cfg_req->tx_cfg.apply_vlan_filter = BNA_STATUS_T_DISABLED;
3128f3bd5173SRasesh Mody 
3129f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&tx->msgq_cmd, NULL, NULL,
3130f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_tx_cfg_req), &cfg_req->mh);
3131f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&tx->bna->msgq, &tx->msgq_cmd);
3132f3bd5173SRasesh Mody }
3133f3bd5173SRasesh Mody 
3134f3bd5173SRasesh Mody static void
bna_bfi_tx_enet_stop(struct bna_tx * tx)3135f3bd5173SRasesh Mody bna_bfi_tx_enet_stop(struct bna_tx *tx)
3136f3bd5173SRasesh Mody {
3137f3bd5173SRasesh Mody 	struct bfi_enet_req *req = &tx->bfi_enet_cmd.req;
3138f3bd5173SRasesh Mody 
3139f3bd5173SRasesh Mody 	bfi_msgq_mhdr_set(req->mh, BFI_MC_ENET,
3140f3bd5173SRasesh Mody 		BFI_ENET_H2I_TX_CFG_CLR_REQ, 0, tx->rid);
3141f3bd5173SRasesh Mody 	req->mh.num_entries = htons(
3142f3bd5173SRasesh Mody 		bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_req)));
3143f3bd5173SRasesh Mody 	bfa_msgq_cmd_set(&tx->msgq_cmd, NULL, NULL, sizeof(struct bfi_enet_req),
3144f3bd5173SRasesh Mody 		&req->mh);
3145f3bd5173SRasesh Mody 	bfa_msgq_cmd_post(&tx->bna->msgq, &tx->msgq_cmd);
3146f3bd5173SRasesh Mody }
3147f3bd5173SRasesh Mody 
3148f3bd5173SRasesh Mody static void
bna_tx_enet_stop(struct bna_tx * tx)3149f3bd5173SRasesh Mody bna_tx_enet_stop(struct bna_tx *tx)
3150f3bd5173SRasesh Mody {
3151f3bd5173SRasesh Mody 	struct bna_txq *txq;
3152f3bd5173SRasesh Mody 
3153f3bd5173SRasesh Mody 	/* Stop IB */
315416712c53SIvan Vecera 	list_for_each_entry(txq, &tx->txq_q, qe)
3155f3bd5173SRasesh Mody 		bna_ib_stop(tx->bna, &txq->ib);
3156f3bd5173SRasesh Mody 
3157f3bd5173SRasesh Mody 	bna_bfi_tx_enet_stop(tx);
3158f3bd5173SRasesh Mody }
3159f3bd5173SRasesh Mody 
3160f3bd5173SRasesh Mody static void
bna_txq_qpt_setup(struct bna_txq * txq,int page_count,int page_size,struct bna_mem_descr * qpt_mem,struct bna_mem_descr * swqpt_mem,struct bna_mem_descr * page_mem)3161f3bd5173SRasesh Mody bna_txq_qpt_setup(struct bna_txq *txq, int page_count, int page_size,
3162f3bd5173SRasesh Mody 		struct bna_mem_descr *qpt_mem,
3163f3bd5173SRasesh Mody 		struct bna_mem_descr *swqpt_mem,
3164f3bd5173SRasesh Mody 		struct bna_mem_descr *page_mem)
3165f3bd5173SRasesh Mody {
31665216562aSRasesh Mody 	u8 *kva;
31675216562aSRasesh Mody 	u64 dma;
31685216562aSRasesh Mody 	struct bna_dma_addr bna_dma;
3169f3bd5173SRasesh Mody 	int i;
3170f3bd5173SRasesh Mody 
3171f3bd5173SRasesh Mody 	txq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
3172f3bd5173SRasesh Mody 	txq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
3173f3bd5173SRasesh Mody 	txq->qpt.kv_qpt_ptr = qpt_mem->kva;
3174f3bd5173SRasesh Mody 	txq->qpt.page_count = page_count;
3175f3bd5173SRasesh Mody 	txq->qpt.page_size = page_size;
3176f3bd5173SRasesh Mody 
3177f3bd5173SRasesh Mody 	txq->tcb->sw_qpt = (void **) swqpt_mem->kva;
31785216562aSRasesh Mody 	txq->tcb->sw_q = page_mem->kva;
31795216562aSRasesh Mody 
31805216562aSRasesh Mody 	kva = page_mem->kva;
31815216562aSRasesh Mody 	BNA_GET_DMA_ADDR(&page_mem->dma, dma);
3182f3bd5173SRasesh Mody 
3183f3bd5173SRasesh Mody 	for (i = 0; i < page_count; i++) {
31845216562aSRasesh Mody 		txq->tcb->sw_qpt[i] = kva;
31855216562aSRasesh Mody 		kva += PAGE_SIZE;
3186f3bd5173SRasesh Mody 
31875216562aSRasesh Mody 		BNA_SET_DMA_ADDR(dma, &bna_dma);
3188f3bd5173SRasesh Mody 		((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].lsb =
31895216562aSRasesh Mody 			bna_dma.lsb;
3190f3bd5173SRasesh Mody 		((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].msb =
31915216562aSRasesh Mody 			bna_dma.msb;
31925216562aSRasesh Mody 		dma += PAGE_SIZE;
3193f3bd5173SRasesh Mody 	}
3194f3bd5173SRasesh Mody }
3195f3bd5173SRasesh Mody 
3196f3bd5173SRasesh Mody static struct bna_tx *
bna_tx_get(struct bna_tx_mod * tx_mod,enum bna_tx_type type)3197f3bd5173SRasesh Mody bna_tx_get(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
3198f3bd5173SRasesh Mody {
3199f3bd5173SRasesh Mody 	struct bna_tx *tx = NULL;
3200f3bd5173SRasesh Mody 
3201f3bd5173SRasesh Mody 	if (list_empty(&tx_mod->tx_free_q))
3202f3bd5173SRasesh Mody 		return NULL;
32032b26fb95SIvan Vecera 	if (type == BNA_TX_T_REGULAR)
32042b26fb95SIvan Vecera 		tx = list_first_entry(&tx_mod->tx_free_q, struct bna_tx, qe);
32052b26fb95SIvan Vecera 	else
32062b26fb95SIvan Vecera 		tx = list_last_entry(&tx_mod->tx_free_q, struct bna_tx, qe);
32072b26fb95SIvan Vecera 	list_del(&tx->qe);
3208f3bd5173SRasesh Mody 	tx->type = type;
3209f3bd5173SRasesh Mody 
3210f3bd5173SRasesh Mody 	return tx;
3211f3bd5173SRasesh Mody }
3212f3bd5173SRasesh Mody 
3213f3bd5173SRasesh Mody static void
bna_tx_free(struct bna_tx * tx)3214f3bd5173SRasesh Mody bna_tx_free(struct bna_tx *tx)
3215f3bd5173SRasesh Mody {
3216f3bd5173SRasesh Mody 	struct bna_tx_mod *tx_mod = &tx->bna->tx_mod;
3217f3bd5173SRasesh Mody 	struct bna_txq *txq;
3218f3bd5173SRasesh Mody 	struct list_head *qe;
3219f3bd5173SRasesh Mody 
3220f3bd5173SRasesh Mody 	while (!list_empty(&tx->txq_q)) {
32212b26fb95SIvan Vecera 		txq = list_first_entry(&tx->txq_q, struct bna_txq, qe);
3222f3bd5173SRasesh Mody 		txq->tcb = NULL;
3223f3bd5173SRasesh Mody 		txq->tx = NULL;
32242b26fb95SIvan Vecera 		list_move_tail(&txq->qe, &tx_mod->txq_free_q);
3225f3bd5173SRasesh Mody 	}
3226f3bd5173SRasesh Mody 
3227f3bd5173SRasesh Mody 	list_for_each(qe, &tx_mod->tx_active_q) {
3228f3bd5173SRasesh Mody 		if (qe == &tx->qe) {
3229f3bd5173SRasesh Mody 			list_del(&tx->qe);
3230f3bd5173SRasesh Mody 			break;
3231f3bd5173SRasesh Mody 		}
3232f3bd5173SRasesh Mody 	}
3233f3bd5173SRasesh Mody 
3234f3bd5173SRasesh Mody 	tx->bna = NULL;
3235f3bd5173SRasesh Mody 	tx->priv = NULL;
3236f3bd5173SRasesh Mody 
32372b26fb95SIvan Vecera 	list_for_each_prev(qe, &tx_mod->tx_free_q)
3238f3bd5173SRasesh Mody 		if (((struct bna_tx *)qe)->rid < tx->rid)
3239f3bd5173SRasesh Mody 			break;
3240f3bd5173SRasesh Mody 
32412b26fb95SIvan Vecera 	list_add(&tx->qe, qe);
3242f3bd5173SRasesh Mody }
3243f3bd5173SRasesh Mody 
3244f3bd5173SRasesh Mody static void
bna_tx_start(struct bna_tx * tx)3245f3bd5173SRasesh Mody bna_tx_start(struct bna_tx *tx)
3246f3bd5173SRasesh Mody {
3247f3bd5173SRasesh Mody 	tx->flags |= BNA_TX_F_ENET_STARTED;
3248f3bd5173SRasesh Mody 	if (tx->flags & BNA_TX_F_ENABLED)
3249f3bd5173SRasesh Mody 		bfa_fsm_send_event(tx, TX_E_START);
3250f3bd5173SRasesh Mody }
3251f3bd5173SRasesh Mody 
3252f3bd5173SRasesh Mody static void
bna_tx_stop(struct bna_tx * tx)3253f3bd5173SRasesh Mody bna_tx_stop(struct bna_tx *tx)
3254f3bd5173SRasesh Mody {
3255f3bd5173SRasesh Mody 	tx->stop_cbfn = bna_tx_mod_cb_tx_stopped;
3256f3bd5173SRasesh Mody 	tx->stop_cbarg = &tx->bna->tx_mod;
3257f3bd5173SRasesh Mody 
3258f3bd5173SRasesh Mody 	tx->flags &= ~BNA_TX_F_ENET_STARTED;
3259f3bd5173SRasesh Mody 	bfa_fsm_send_event(tx, TX_E_STOP);
3260f3bd5173SRasesh Mody }
3261f3bd5173SRasesh Mody 
3262f3bd5173SRasesh Mody static void
bna_tx_fail(struct bna_tx * tx)3263f3bd5173SRasesh Mody bna_tx_fail(struct bna_tx *tx)
3264f3bd5173SRasesh Mody {
3265f3bd5173SRasesh Mody 	tx->flags &= ~BNA_TX_F_ENET_STARTED;
3266f3bd5173SRasesh Mody 	bfa_fsm_send_event(tx, TX_E_FAIL);
3267f3bd5173SRasesh Mody }
3268f3bd5173SRasesh Mody 
3269f3bd5173SRasesh Mody void
bna_bfi_tx_enet_start_rsp(struct bna_tx * tx,struct bfi_msgq_mhdr * msghdr)3270f3bd5173SRasesh Mody bna_bfi_tx_enet_start_rsp(struct bna_tx *tx, struct bfi_msgq_mhdr *msghdr)
3271f3bd5173SRasesh Mody {
3272f3bd5173SRasesh Mody 	struct bfi_enet_tx_cfg_rsp *cfg_rsp = &tx->bfi_enet_cmd.cfg_rsp;
3273f3bd5173SRasesh Mody 	struct bna_txq *txq = NULL;
3274f3bd5173SRasesh Mody 	int i;
3275f3bd5173SRasesh Mody 
3276f3bd5173SRasesh Mody 	bfa_msgq_rsp_copy(&tx->bna->msgq, (u8 *)cfg_rsp,
3277f3bd5173SRasesh Mody 		sizeof(struct bfi_enet_tx_cfg_rsp));
3278f3bd5173SRasesh Mody 
3279f3bd5173SRasesh Mody 	tx->hw_id = cfg_rsp->hw_id;
3280f3bd5173SRasesh Mody 
32812b26fb95SIvan Vecera 	for (i = 0, txq = list_first_entry(&tx->txq_q, struct bna_txq, qe);
32822b26fb95SIvan Vecera 	     i < tx->num_txq; i++, txq = list_next_entry(txq, qe)) {
3283f3bd5173SRasesh Mody 		/* Setup doorbells */
3284f3bd5173SRasesh Mody 		txq->tcb->i_dbell->doorbell_addr =
3285f3bd5173SRasesh Mody 			tx->bna->pcidev.pci_bar_kva
3286f3bd5173SRasesh Mody 			+ ntohl(cfg_rsp->q_handles[i].i_dbell);
3287f3bd5173SRasesh Mody 		txq->tcb->q_dbell =
3288f3bd5173SRasesh Mody 			tx->bna->pcidev.pci_bar_kva
3289f3bd5173SRasesh Mody 			+ ntohl(cfg_rsp->q_handles[i].q_dbell);
3290f3bd5173SRasesh Mody 		txq->hw_id = cfg_rsp->q_handles[i].hw_qid;
3291f3bd5173SRasesh Mody 
3292f3bd5173SRasesh Mody 		/* Initialize producer/consumer indexes */
3293f3bd5173SRasesh Mody 		(*txq->tcb->hw_consumer_index) = 0;
3294f3bd5173SRasesh Mody 		txq->tcb->producer_index = txq->tcb->consumer_index = 0;
3295f3bd5173SRasesh Mody 	}
3296f3bd5173SRasesh Mody 
3297f3bd5173SRasesh Mody 	bfa_fsm_send_event(tx, TX_E_STARTED);
3298f3bd5173SRasesh Mody }
3299f3bd5173SRasesh Mody 
3300f3bd5173SRasesh Mody void
bna_bfi_tx_enet_stop_rsp(struct bna_tx * tx,struct bfi_msgq_mhdr * msghdr)3301f3bd5173SRasesh Mody bna_bfi_tx_enet_stop_rsp(struct bna_tx *tx, struct bfi_msgq_mhdr *msghdr)
3302f3bd5173SRasesh Mody {
3303f3bd5173SRasesh Mody 	bfa_fsm_send_event(tx, TX_E_STOPPED);
3304f3bd5173SRasesh Mody }
3305f3bd5173SRasesh Mody 
3306f3bd5173SRasesh Mody void
bna_bfi_bw_update_aen(struct bna_tx_mod * tx_mod)3307f3bd5173SRasesh Mody bna_bfi_bw_update_aen(struct bna_tx_mod *tx_mod)
3308f3bd5173SRasesh Mody {
3309f3bd5173SRasesh Mody 	struct bna_tx *tx;
3310f3bd5173SRasesh Mody 
331116712c53SIvan Vecera 	list_for_each_entry(tx, &tx_mod->tx_active_q, qe)
3312f3bd5173SRasesh Mody 		bfa_fsm_send_event(tx, TX_E_BW_UPDATE);
3313f3bd5173SRasesh Mody }
3314f3bd5173SRasesh Mody 
3315f3bd5173SRasesh Mody void
bna_tx_res_req(int num_txq,int txq_depth,struct bna_res_info * res_info)3316f3bd5173SRasesh Mody bna_tx_res_req(int num_txq, int txq_depth, struct bna_res_info *res_info)
3317f3bd5173SRasesh Mody {
3318f3bd5173SRasesh Mody 	u32 q_size;
3319f3bd5173SRasesh Mody 	u32 page_count;
3320f3bd5173SRasesh Mody 	struct bna_mem_info *mem_info;
3321f3bd5173SRasesh Mody 
3322f3bd5173SRasesh Mody 	res_info[BNA_TX_RES_MEM_T_TCB].res_type = BNA_RES_T_MEM;
3323f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info;
3324f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_KVA;
3325f3bd5173SRasesh Mody 	mem_info->len = sizeof(struct bna_tcb);
3326f3bd5173SRasesh Mody 	mem_info->num = num_txq;
3327f3bd5173SRasesh Mody 
3328f3bd5173SRasesh Mody 	q_size = txq_depth * BFI_TXQ_WI_SIZE;
3329f3bd5173SRasesh Mody 	q_size = ALIGN(q_size, PAGE_SIZE);
3330f3bd5173SRasesh Mody 	page_count = q_size >> PAGE_SHIFT;
3331f3bd5173SRasesh Mody 
3332f3bd5173SRasesh Mody 	res_info[BNA_TX_RES_MEM_T_QPT].res_type = BNA_RES_T_MEM;
3333f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info;
3334f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_DMA;
3335f3bd5173SRasesh Mody 	mem_info->len = page_count * sizeof(struct bna_dma_addr);
3336f3bd5173SRasesh Mody 	mem_info->num = num_txq;
3337f3bd5173SRasesh Mody 
3338f3bd5173SRasesh Mody 	res_info[BNA_TX_RES_MEM_T_SWQPT].res_type = BNA_RES_T_MEM;
3339f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info;
3340f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_KVA;
3341f3bd5173SRasesh Mody 	mem_info->len = page_count * sizeof(void *);
3342f3bd5173SRasesh Mody 	mem_info->num = num_txq;
3343f3bd5173SRasesh Mody 
3344f3bd5173SRasesh Mody 	res_info[BNA_TX_RES_MEM_T_PAGE].res_type = BNA_RES_T_MEM;
3345f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info;
3346f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_DMA;
33475216562aSRasesh Mody 	mem_info->len = PAGE_SIZE * page_count;
33485216562aSRasesh Mody 	mem_info->num = num_txq;
3349f3bd5173SRasesh Mody 
3350f3bd5173SRasesh Mody 	res_info[BNA_TX_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM;
3351f3bd5173SRasesh Mody 	mem_info = &res_info[BNA_TX_RES_MEM_T_IBIDX].res_u.mem_info;
3352f3bd5173SRasesh Mody 	mem_info->mem_type = BNA_MEM_T_DMA;
3353f3bd5173SRasesh Mody 	mem_info->len = BFI_IBIDX_SIZE;
3354f3bd5173SRasesh Mody 	mem_info->num = num_txq;
3355f3bd5173SRasesh Mody 
3356f3bd5173SRasesh Mody 	res_info[BNA_TX_RES_INTR_T_TXCMPL].res_type = BNA_RES_T_INTR;
3357f3bd5173SRasesh Mody 	res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.intr_type =
3358f3bd5173SRasesh Mody 			BNA_INTR_T_MSIX;
3359f3bd5173SRasesh Mody 	res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.num = num_txq;
3360f3bd5173SRasesh Mody }
3361f3bd5173SRasesh Mody 
3362f3bd5173SRasesh Mody struct bna_tx *
bna_tx_create(struct bna * bna,struct bnad * bnad,struct bna_tx_config * tx_cfg,const struct bna_tx_event_cbfn * tx_cbfn,struct bna_res_info * res_info,void * priv)3363f3bd5173SRasesh Mody bna_tx_create(struct bna *bna, struct bnad *bnad,
3364f3bd5173SRasesh Mody 		struct bna_tx_config *tx_cfg,
3365d91d25d5Sstephen hemminger 		const struct bna_tx_event_cbfn *tx_cbfn,
3366f3bd5173SRasesh Mody 		struct bna_res_info *res_info, void *priv)
3367f3bd5173SRasesh Mody {
3368f3bd5173SRasesh Mody 	struct bna_intr_info *intr_info;
3369f3bd5173SRasesh Mody 	struct bna_tx_mod *tx_mod = &bna->tx_mod;
3370f3bd5173SRasesh Mody 	struct bna_tx *tx;
3371f3bd5173SRasesh Mody 	struct bna_txq *txq;
3372f3bd5173SRasesh Mody 	int page_count;
3373f3bd5173SRasesh Mody 	int i;
3374f3bd5173SRasesh Mody 
3375f3bd5173SRasesh Mody 	intr_info = &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info;
33765216562aSRasesh Mody 	page_count = (res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.len) /
33775216562aSRasesh Mody 					PAGE_SIZE;
3378f3bd5173SRasesh Mody 
3379f3bd5173SRasesh Mody 	/**
3380f3bd5173SRasesh Mody 	 * Get resources
3381f3bd5173SRasesh Mody 	 */
3382f3bd5173SRasesh Mody 
3383f3bd5173SRasesh Mody 	if ((intr_info->num != 1) && (intr_info->num != tx_cfg->num_txq))
3384f3bd5173SRasesh Mody 		return NULL;
3385f3bd5173SRasesh Mody 
3386f3bd5173SRasesh Mody 	/* Tx */
3387f3bd5173SRasesh Mody 
3388f3bd5173SRasesh Mody 	tx = bna_tx_get(tx_mod, tx_cfg->tx_type);
3389f3bd5173SRasesh Mody 	if (!tx)
3390f3bd5173SRasesh Mody 		return NULL;
3391f3bd5173SRasesh Mody 	tx->bna = bna;
3392f3bd5173SRasesh Mody 	tx->priv = priv;
3393f3bd5173SRasesh Mody 
3394f3bd5173SRasesh Mody 	/* TxQs */
3395f3bd5173SRasesh Mody 
3396f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&tx->txq_q);
3397f3bd5173SRasesh Mody 	for (i = 0; i < tx_cfg->num_txq; i++) {
3398f3bd5173SRasesh Mody 		if (list_empty(&tx_mod->txq_free_q))
3399f3bd5173SRasesh Mody 			goto err_return;
3400f3bd5173SRasesh Mody 
34012b26fb95SIvan Vecera 		txq = list_first_entry(&tx_mod->txq_free_q, struct bna_txq, qe);
34022b26fb95SIvan Vecera 		list_move_tail(&txq->qe, &tx->txq_q);
3403f3bd5173SRasesh Mody 		txq->tx = tx;
3404f3bd5173SRasesh Mody 	}
3405f3bd5173SRasesh Mody 
3406f3bd5173SRasesh Mody 	/*
3407f3bd5173SRasesh Mody 	 * Initialize
3408f3bd5173SRasesh Mody 	 */
3409f3bd5173SRasesh Mody 
3410f3bd5173SRasesh Mody 	/* Tx */
3411f3bd5173SRasesh Mody 
3412f3bd5173SRasesh Mody 	tx->tcb_setup_cbfn = tx_cbfn->tcb_setup_cbfn;
3413f3bd5173SRasesh Mody 	tx->tcb_destroy_cbfn = tx_cbfn->tcb_destroy_cbfn;
3414f3bd5173SRasesh Mody 	/* Following callbacks are mandatory */
3415f3bd5173SRasesh Mody 	tx->tx_stall_cbfn = tx_cbfn->tx_stall_cbfn;
3416f3bd5173SRasesh Mody 	tx->tx_resume_cbfn = tx_cbfn->tx_resume_cbfn;
3417f3bd5173SRasesh Mody 	tx->tx_cleanup_cbfn = tx_cbfn->tx_cleanup_cbfn;
3418f3bd5173SRasesh Mody 
3419f3bd5173SRasesh Mody 	list_add_tail(&tx->qe, &tx_mod->tx_active_q);
3420f3bd5173SRasesh Mody 
3421f3bd5173SRasesh Mody 	tx->num_txq = tx_cfg->num_txq;
3422f3bd5173SRasesh Mody 
3423f3bd5173SRasesh Mody 	tx->flags = 0;
3424f3bd5173SRasesh Mody 	if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_ENET_STARTED) {
3425f3bd5173SRasesh Mody 		switch (tx->type) {
3426f3bd5173SRasesh Mody 		case BNA_TX_T_REGULAR:
3427f3bd5173SRasesh Mody 			if (!(tx->bna->tx_mod.flags &
3428f3bd5173SRasesh Mody 				BNA_TX_MOD_F_ENET_LOOPBACK))
3429f3bd5173SRasesh Mody 				tx->flags |= BNA_TX_F_ENET_STARTED;
3430f3bd5173SRasesh Mody 			break;
3431f3bd5173SRasesh Mody 		case BNA_TX_T_LOOPBACK:
3432f3bd5173SRasesh Mody 			if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_ENET_LOOPBACK)
3433f3bd5173SRasesh Mody 				tx->flags |= BNA_TX_F_ENET_STARTED;
3434f3bd5173SRasesh Mody 			break;
3435f3bd5173SRasesh Mody 		}
3436f3bd5173SRasesh Mody 	}
3437f3bd5173SRasesh Mody 
3438f3bd5173SRasesh Mody 	/* TxQ */
3439f3bd5173SRasesh Mody 
3440f3bd5173SRasesh Mody 	i = 0;
344116712c53SIvan Vecera 	list_for_each_entry(txq, &tx->txq_q, qe) {
3442f3bd5173SRasesh Mody 		txq->tcb = (struct bna_tcb *)
3443f3bd5173SRasesh Mody 		res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info.mdl[i].kva;
3444f3bd5173SRasesh Mody 		txq->tx_packets = 0;
3445f3bd5173SRasesh Mody 		txq->tx_bytes = 0;
3446f3bd5173SRasesh Mody 
3447f3bd5173SRasesh Mody 		/* IB */
3448f3bd5173SRasesh Mody 		txq->ib.ib_seg_host_addr.lsb =
3449f3bd5173SRasesh Mody 		res_info[BNA_TX_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.lsb;
3450f3bd5173SRasesh Mody 		txq->ib.ib_seg_host_addr.msb =
3451f3bd5173SRasesh Mody 		res_info[BNA_TX_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.msb;
3452f3bd5173SRasesh Mody 		txq->ib.ib_seg_host_addr_kva =
3453f3bd5173SRasesh Mody 		res_info[BNA_TX_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].kva;
3454f3bd5173SRasesh Mody 		txq->ib.intr_type = intr_info->intr_type;
3455f3bd5173SRasesh Mody 		txq->ib.intr_vector = (intr_info->num == 1) ?
3456f3bd5173SRasesh Mody 					intr_info->idl[0].vector :
3457f3bd5173SRasesh Mody 					intr_info->idl[i].vector;
3458f3bd5173SRasesh Mody 		if (intr_info->intr_type == BNA_INTR_T_INTX)
34591a50691aSIvan Vecera 			txq->ib.intr_vector = BIT(txq->ib.intr_vector);
3460f3bd5173SRasesh Mody 		txq->ib.coalescing_timeo = tx_cfg->coalescing_timeo;
3461d3f92aecSRasesh Mody 		txq->ib.interpkt_timeo = BFI_TX_INTERPKT_TIMEO;
3462f3bd5173SRasesh Mody 		txq->ib.interpkt_count = BFI_TX_INTERPKT_COUNT;
3463f3bd5173SRasesh Mody 
3464f3bd5173SRasesh Mody 		/* TCB */
3465f3bd5173SRasesh Mody 
3466f3bd5173SRasesh Mody 		txq->tcb->q_depth = tx_cfg->txq_depth;
3467f3bd5173SRasesh Mody 		txq->tcb->unmap_q = (void *)
3468f3bd5173SRasesh Mody 		res_info[BNA_TX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[i].kva;
3469f3bd5173SRasesh Mody 		txq->tcb->hw_consumer_index =
3470f3bd5173SRasesh Mody 			(u32 *)txq->ib.ib_seg_host_addr_kva;
3471f3bd5173SRasesh Mody 		txq->tcb->i_dbell = &txq->ib.door_bell;
3472f3bd5173SRasesh Mody 		txq->tcb->intr_type = txq->ib.intr_type;
3473f3bd5173SRasesh Mody 		txq->tcb->intr_vector = txq->ib.intr_vector;
3474f3bd5173SRasesh Mody 		txq->tcb->txq = txq;
3475f3bd5173SRasesh Mody 		txq->tcb->bnad = bnad;
3476f3bd5173SRasesh Mody 		txq->tcb->id = i;
3477f3bd5173SRasesh Mody 
3478f3bd5173SRasesh Mody 		/* QPT, SWQPT, Pages */
34795216562aSRasesh Mody 		bna_txq_qpt_setup(txq, page_count, PAGE_SIZE,
3480f3bd5173SRasesh Mody 			&res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info.mdl[i],
3481f3bd5173SRasesh Mody 			&res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info.mdl[i],
3482f3bd5173SRasesh Mody 			&res_info[BNA_TX_RES_MEM_T_PAGE].
34835216562aSRasesh Mody 				  res_u.mem_info.mdl[i]);
3484f3bd5173SRasesh Mody 
3485f3bd5173SRasesh Mody 		/* Callback to bnad for setting up TCB */
3486f3bd5173SRasesh Mody 		if (tx->tcb_setup_cbfn)
3487f3bd5173SRasesh Mody 			(tx->tcb_setup_cbfn)(bna->bnad, txq->tcb);
3488f3bd5173SRasesh Mody 
3489f3bd5173SRasesh Mody 		if (tx_cfg->num_txq == BFI_TX_MAX_PRIO)
3490f3bd5173SRasesh Mody 			txq->priority = txq->tcb->id;
3491f3bd5173SRasesh Mody 		else
3492f3bd5173SRasesh Mody 			txq->priority = tx_mod->default_prio;
3493f3bd5173SRasesh Mody 
3494f3bd5173SRasesh Mody 		i++;
3495f3bd5173SRasesh Mody 	}
3496f3bd5173SRasesh Mody 
3497f3bd5173SRasesh Mody 	tx->txf_vlan_id = 0;
3498f3bd5173SRasesh Mody 
3499f3bd5173SRasesh Mody 	bfa_fsm_set_state(tx, bna_tx_sm_stopped);
3500f3bd5173SRasesh Mody 
35011a50691aSIvan Vecera 	tx_mod->rid_mask |= BIT(tx->rid);
3502f3bd5173SRasesh Mody 
3503f3bd5173SRasesh Mody 	return tx;
3504f3bd5173SRasesh Mody 
3505f3bd5173SRasesh Mody err_return:
3506f3bd5173SRasesh Mody 	bna_tx_free(tx);
3507f3bd5173SRasesh Mody 	return NULL;
3508f3bd5173SRasesh Mody }
3509f3bd5173SRasesh Mody 
3510f3bd5173SRasesh Mody void
bna_tx_destroy(struct bna_tx * tx)3511f3bd5173SRasesh Mody bna_tx_destroy(struct bna_tx *tx)
3512f3bd5173SRasesh Mody {
3513f3bd5173SRasesh Mody 	struct bna_txq *txq;
3514f3bd5173SRasesh Mody 
351516712c53SIvan Vecera 	list_for_each_entry(txq, &tx->txq_q, qe)
3516f3bd5173SRasesh Mody 		if (tx->tcb_destroy_cbfn)
3517f3bd5173SRasesh Mody 			(tx->tcb_destroy_cbfn)(tx->bna->bnad, txq->tcb);
3518f3bd5173SRasesh Mody 
35191a50691aSIvan Vecera 	tx->bna->tx_mod.rid_mask &= ~BIT(tx->rid);
3520f3bd5173SRasesh Mody 	bna_tx_free(tx);
3521f3bd5173SRasesh Mody }
3522f3bd5173SRasesh Mody 
3523f3bd5173SRasesh Mody void
bna_tx_enable(struct bna_tx * tx)3524f3bd5173SRasesh Mody bna_tx_enable(struct bna_tx *tx)
3525f3bd5173SRasesh Mody {
3526*8719a1c3SGustavo A. R. Silva 	if (tx->fsm != bna_tx_sm_stopped)
3527f3bd5173SRasesh Mody 		return;
3528f3bd5173SRasesh Mody 
3529f3bd5173SRasesh Mody 	tx->flags |= BNA_TX_F_ENABLED;
3530f3bd5173SRasesh Mody 
3531f3bd5173SRasesh Mody 	if (tx->flags & BNA_TX_F_ENET_STARTED)
3532f3bd5173SRasesh Mody 		bfa_fsm_send_event(tx, TX_E_START);
3533f3bd5173SRasesh Mody }
3534f3bd5173SRasesh Mody 
3535f3bd5173SRasesh Mody void
bna_tx_disable(struct bna_tx * tx,enum bna_cleanup_type type,void (* cbfn)(void *,struct bna_tx *))3536f3bd5173SRasesh Mody bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type,
3537f3bd5173SRasesh Mody 		void (*cbfn)(void *, struct bna_tx *))
3538f3bd5173SRasesh Mody {
3539f3bd5173SRasesh Mody 	if (type == BNA_SOFT_CLEANUP) {
3540f3bd5173SRasesh Mody 		(*cbfn)(tx->bna->bnad, tx);
3541f3bd5173SRasesh Mody 		return;
3542f3bd5173SRasesh Mody 	}
3543f3bd5173SRasesh Mody 
3544f3bd5173SRasesh Mody 	tx->stop_cbfn = cbfn;
3545f3bd5173SRasesh Mody 	tx->stop_cbarg = tx->bna->bnad;
3546f3bd5173SRasesh Mody 
3547f3bd5173SRasesh Mody 	tx->flags &= ~BNA_TX_F_ENABLED;
3548f3bd5173SRasesh Mody 
3549f3bd5173SRasesh Mody 	bfa_fsm_send_event(tx, TX_E_STOP);
3550f3bd5173SRasesh Mody }
3551f3bd5173SRasesh Mody 
3552f3bd5173SRasesh Mody void
bna_tx_cleanup_complete(struct bna_tx * tx)3553f3bd5173SRasesh Mody bna_tx_cleanup_complete(struct bna_tx *tx)
3554f3bd5173SRasesh Mody {
3555f3bd5173SRasesh Mody 	bfa_fsm_send_event(tx, TX_E_CLEANUP_DONE);
3556f3bd5173SRasesh Mody }
3557f3bd5173SRasesh Mody 
3558f3bd5173SRasesh Mody static void
bna_tx_mod_cb_tx_stopped(void * arg,struct bna_tx * tx)3559f3bd5173SRasesh Mody bna_tx_mod_cb_tx_stopped(void *arg, struct bna_tx *tx)
3560f3bd5173SRasesh Mody {
3561f3bd5173SRasesh Mody 	struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg;
3562f3bd5173SRasesh Mody 
3563f3bd5173SRasesh Mody 	bfa_wc_down(&tx_mod->tx_stop_wc);
3564f3bd5173SRasesh Mody }
3565f3bd5173SRasesh Mody 
3566f3bd5173SRasesh Mody static void
bna_tx_mod_cb_tx_stopped_all(void * arg)3567f3bd5173SRasesh Mody bna_tx_mod_cb_tx_stopped_all(void *arg)
3568f3bd5173SRasesh Mody {
3569f3bd5173SRasesh Mody 	struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg;
3570f3bd5173SRasesh Mody 
3571f3bd5173SRasesh Mody 	if (tx_mod->stop_cbfn)
3572f3bd5173SRasesh Mody 		tx_mod->stop_cbfn(&tx_mod->bna->enet);
3573f3bd5173SRasesh Mody 	tx_mod->stop_cbfn = NULL;
3574f3bd5173SRasesh Mody }
3575f3bd5173SRasesh Mody 
3576f3bd5173SRasesh Mody void
bna_tx_mod_init(struct bna_tx_mod * tx_mod,struct bna * bna,struct bna_res_info * res_info)3577f3bd5173SRasesh Mody bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna,
3578f3bd5173SRasesh Mody 		struct bna_res_info *res_info)
3579f3bd5173SRasesh Mody {
3580f3bd5173SRasesh Mody 	int i;
3581f3bd5173SRasesh Mody 
3582f3bd5173SRasesh Mody 	tx_mod->bna = bna;
3583f3bd5173SRasesh Mody 	tx_mod->flags = 0;
3584f3bd5173SRasesh Mody 
3585f3bd5173SRasesh Mody 	tx_mod->tx = (struct bna_tx *)
3586f3bd5173SRasesh Mody 		res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.mdl[0].kva;
3587f3bd5173SRasesh Mody 	tx_mod->txq = (struct bna_txq *)
3588f3bd5173SRasesh Mody 		res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mdl[0].kva;
3589f3bd5173SRasesh Mody 
3590f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&tx_mod->tx_free_q);
3591f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&tx_mod->tx_active_q);
3592f3bd5173SRasesh Mody 
3593f3bd5173SRasesh Mody 	INIT_LIST_HEAD(&tx_mod->txq_free_q);
3594f3bd5173SRasesh Mody 
3595f3bd5173SRasesh Mody 	for (i = 0; i < bna->ioceth.attr.num_txq; i++) {
3596f3bd5173SRasesh Mody 		tx_mod->tx[i].rid = i;
3597f3bd5173SRasesh Mody 		list_add_tail(&tx_mod->tx[i].qe, &tx_mod->tx_free_q);
3598f3bd5173SRasesh Mody 		list_add_tail(&tx_mod->txq[i].qe, &tx_mod->txq_free_q);
3599f3bd5173SRasesh Mody 	}
3600f3bd5173SRasesh Mody 
3601f3bd5173SRasesh Mody 	tx_mod->prio_map = BFI_TX_PRIO_MAP_ALL;
3602f3bd5173SRasesh Mody 	tx_mod->default_prio = 0;
3603f3bd5173SRasesh Mody 	tx_mod->iscsi_over_cee = BNA_STATUS_T_DISABLED;
3604f3bd5173SRasesh Mody 	tx_mod->iscsi_prio = -1;
3605f3bd5173SRasesh Mody }
3606f3bd5173SRasesh Mody 
3607f3bd5173SRasesh Mody void
bna_tx_mod_uninit(struct bna_tx_mod * tx_mod)3608f3bd5173SRasesh Mody bna_tx_mod_uninit(struct bna_tx_mod *tx_mod)
3609f3bd5173SRasesh Mody {
3610f3bd5173SRasesh Mody 	tx_mod->bna = NULL;
3611f3bd5173SRasesh Mody }
3612f3bd5173SRasesh Mody 
3613f3bd5173SRasesh Mody void
bna_tx_mod_start(struct bna_tx_mod * tx_mod,enum bna_tx_type type)3614f3bd5173SRasesh Mody bna_tx_mod_start(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
3615f3bd5173SRasesh Mody {
3616f3bd5173SRasesh Mody 	struct bna_tx *tx;
3617f3bd5173SRasesh Mody 
3618f3bd5173SRasesh Mody 	tx_mod->flags |= BNA_TX_MOD_F_ENET_STARTED;
3619f3bd5173SRasesh Mody 	if (type == BNA_TX_T_LOOPBACK)
3620f3bd5173SRasesh Mody 		tx_mod->flags |= BNA_TX_MOD_F_ENET_LOOPBACK;
3621f3bd5173SRasesh Mody 
362216712c53SIvan Vecera 	list_for_each_entry(tx, &tx_mod->tx_active_q, qe)
3623f3bd5173SRasesh Mody 		if (tx->type == type)
3624f3bd5173SRasesh Mody 			bna_tx_start(tx);
3625f3bd5173SRasesh Mody }
3626f3bd5173SRasesh Mody 
3627f3bd5173SRasesh Mody void
bna_tx_mod_stop(struct bna_tx_mod * tx_mod,enum bna_tx_type type)3628f3bd5173SRasesh Mody bna_tx_mod_stop(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
3629f3bd5173SRasesh Mody {
3630f3bd5173SRasesh Mody 	struct bna_tx *tx;
3631f3bd5173SRasesh Mody 
3632f3bd5173SRasesh Mody 	tx_mod->flags &= ~BNA_TX_MOD_F_ENET_STARTED;
3633f3bd5173SRasesh Mody 	tx_mod->flags &= ~BNA_TX_MOD_F_ENET_LOOPBACK;
3634f3bd5173SRasesh Mody 
3635f3bd5173SRasesh Mody 	tx_mod->stop_cbfn = bna_enet_cb_tx_stopped;
3636f3bd5173SRasesh Mody 
3637f3bd5173SRasesh Mody 	bfa_wc_init(&tx_mod->tx_stop_wc, bna_tx_mod_cb_tx_stopped_all, tx_mod);
3638f3bd5173SRasesh Mody 
363916712c53SIvan Vecera 	list_for_each_entry(tx, &tx_mod->tx_active_q, qe)
3640f3bd5173SRasesh Mody 		if (tx->type == type) {
3641f3bd5173SRasesh Mody 			bfa_wc_up(&tx_mod->tx_stop_wc);
3642f3bd5173SRasesh Mody 			bna_tx_stop(tx);
3643f3bd5173SRasesh Mody 		}
3644f3bd5173SRasesh Mody 
3645f3bd5173SRasesh Mody 	bfa_wc_wait(&tx_mod->tx_stop_wc);
3646f3bd5173SRasesh Mody }
3647f3bd5173SRasesh Mody 
3648f3bd5173SRasesh Mody void
bna_tx_mod_fail(struct bna_tx_mod * tx_mod)3649f3bd5173SRasesh Mody bna_tx_mod_fail(struct bna_tx_mod *tx_mod)
3650f3bd5173SRasesh Mody {
3651f3bd5173SRasesh Mody 	struct bna_tx *tx;
3652f3bd5173SRasesh Mody 
3653f3bd5173SRasesh Mody 	tx_mod->flags &= ~BNA_TX_MOD_F_ENET_STARTED;
3654f3bd5173SRasesh Mody 	tx_mod->flags &= ~BNA_TX_MOD_F_ENET_LOOPBACK;
3655f3bd5173SRasesh Mody 
365616712c53SIvan Vecera 	list_for_each_entry(tx, &tx_mod->tx_active_q, qe)
3657f3bd5173SRasesh Mody 		bna_tx_fail(tx);
3658f3bd5173SRasesh Mody }
3659f3bd5173SRasesh Mody 
3660f3bd5173SRasesh Mody void
bna_tx_coalescing_timeo_set(struct bna_tx * tx,int coalescing_timeo)3661f3bd5173SRasesh Mody bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo)
3662f3bd5173SRasesh Mody {
3663f3bd5173SRasesh Mody 	struct bna_txq *txq;
3664f3bd5173SRasesh Mody 
366516712c53SIvan Vecera 	list_for_each_entry(txq, &tx->txq_q, qe)
3666f3bd5173SRasesh Mody 		bna_ib_coalescing_timeo_set(&txq->ib, coalescing_timeo);
3667f3bd5173SRasesh Mody }
3668