/*
 * Linux network driver for Brocade Converged Network Adapter.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License (GPL) Version 2 as
 * published by the Free Software Foundation
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
  */
/*
 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
 * All rights reserved
 * www.brocade.com
 */
#include "bna.h"
#include "bfa_sm.h"
#include "bfi.h"

/**
 * IB
 */
#define bna_ib_find_free_ibidx(_mask, _pos)\
do {\
	(_pos) = 0;\
	while (((_pos) < (BFI_IBIDX_MAX_SEGSIZE)) &&\
		((1 << (_pos)) & (_mask)))\
		(_pos)++;\
} while (0)

#define bna_ib_count_ibidx(_mask, _count)\
do {\
	int pos = 0;\
	(_count) = 0;\
	while (pos < (BFI_IBIDX_MAX_SEGSIZE)) {\
		if ((1 << pos) & (_mask))\
			(_count) = pos + 1;\
		pos++;\
	} \
} while (0)

#define bna_ib_select_segpool(_count, _q_idx)\
do {\
	int i;\
	(_q_idx) = -1;\
	for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {\
		if ((_count <= ibidx_pool[i].pool_entry_size)) {\
			(_q_idx) = i;\
			break;\
		} \
	} \
} while (0)

struct bna_ibidx_pool {
	int	pool_size;
	int	pool_entry_size;
};
init_ibidx_pool(ibidx_pool);

static struct bna_intr *
bna_intr_get(struct bna_ib_mod *ib_mod, enum bna_intr_type intr_type,
		int vector)
{
	struct bna_intr *intr;
	struct list_head *qe;

	list_for_each(qe, &ib_mod->intr_active_q) {
		intr = (struct bna_intr *)qe;

		if ((intr->intr_type == intr_type) &&
			(intr->vector == vector)) {
			intr->ref_count++;
			return intr;
		}
	}

	if (list_empty(&ib_mod->intr_free_q))
		return NULL;

	bfa_q_deq(&ib_mod->intr_free_q, &intr);
	bfa_q_qe_init(&intr->qe);

	intr->ref_count = 1;
	intr->intr_type = intr_type;
	intr->vector = vector;

	list_add_tail(&intr->qe, &ib_mod->intr_active_q);

	return intr;
}

static void
bna_intr_put(struct bna_ib_mod *ib_mod,
		struct bna_intr *intr)
{
	intr->ref_count--;

	if (intr->ref_count == 0) {
		intr->ib = NULL;
		list_del(&intr->qe);
		bfa_q_qe_init(&intr->qe);
		list_add_tail(&intr->qe, &ib_mod->intr_free_q);
	}
}

void
bna_ib_mod_init(struct bna_ib_mod *ib_mod, struct bna *bna,
		struct bna_res_info *res_info)
{
	int i;
	int j;
	int count;
	u8 offset;
	struct bna_doorbell_qset *qset;
	unsigned long off;

	ib_mod->bna = bna;

	ib_mod->ib = (struct bna_ib *)
		res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.mdl[0].kva;
	ib_mod->intr = (struct bna_intr *)
		res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.mdl[0].kva;
	ib_mod->idx_seg = (struct bna_ibidx_seg *)
		res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.mdl[0].kva;

	INIT_LIST_HEAD(&ib_mod->ib_free_q);
	INIT_LIST_HEAD(&ib_mod->intr_free_q);
	INIT_LIST_HEAD(&ib_mod->intr_active_q);

	for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++)
		INIT_LIST_HEAD(&ib_mod->ibidx_seg_pool[i]);

	for (i = 0; i < BFI_MAX_IB; i++) {
		ib_mod->ib[i].ib_id = i;

		ib_mod->ib[i].ib_seg_host_addr_kva =
		res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].kva;
		ib_mod->ib[i].ib_seg_host_addr.lsb =
		res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.lsb;
		ib_mod->ib[i].ib_seg_host_addr.msb =
		res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.msb;

		qset = (struct bna_doorbell_qset *)0;
		off = (unsigned long)(&qset[i >> 1].ib0[(i & 0x1)
					* (0x20 >> 2)]);
		ib_mod->ib[i].door_bell.doorbell_addr = off +
			BNA_GET_DOORBELL_BASE_ADDR(bna->pcidev.pci_bar_kva);

		bfa_q_qe_init(&ib_mod->ib[i].qe);
		list_add_tail(&ib_mod->ib[i].qe, &ib_mod->ib_free_q);

		bfa_q_qe_init(&ib_mod->intr[i].qe);
		list_add_tail(&ib_mod->intr[i].qe, &ib_mod->intr_free_q);
	}

	count = 0;
	offset = 0;
	for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {
		for (j = 0; j < ibidx_pool[i].pool_size; j++) {
			bfa_q_qe_init(&ib_mod->idx_seg[count]);
			ib_mod->idx_seg[count].ib_seg_size =
					ibidx_pool[i].pool_entry_size;
			ib_mod->idx_seg[count].ib_idx_tbl_offset = offset;
			list_add_tail(&ib_mod->idx_seg[count].qe,
				&ib_mod->ibidx_seg_pool[i]);
			count++;
			offset += ibidx_pool[i].pool_entry_size;
		}
	}
}

void
bna_ib_mod_uninit(struct bna_ib_mod *ib_mod)
{
	int i;
	int j;
	struct list_head *qe;

	i = 0;
	list_for_each(qe, &ib_mod->ib_free_q)
		i++;

	i = 0;
	list_for_each(qe, &ib_mod->intr_free_q)
		i++;

	for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {
		j = 0;
		list_for_each(qe, &ib_mod->ibidx_seg_pool[i])
			j++;
	}

	ib_mod->bna = NULL;
}

static struct bna_ib *
bna_ib_get(struct bna_ib_mod *ib_mod,
		enum bna_intr_type intr_type,
		int vector)
{
	struct bna_ib *ib;
	struct bna_intr *intr;

	if (intr_type == BNA_INTR_T_INTX)
		vector = (1 << vector);

	intr = bna_intr_get(ib_mod, intr_type, vector);
	if (intr == NULL)
		return NULL;

	if (intr->ib) {
		if (intr->ib->ref_count == BFI_IBIDX_MAX_SEGSIZE) {
			bna_intr_put(ib_mod, intr);
			return NULL;
		}
		intr->ib->ref_count++;
		return intr->ib;
	}

	if (list_empty(&ib_mod->ib_free_q)) {
		bna_intr_put(ib_mod, intr);
		return NULL;
	}

	bfa_q_deq(&ib_mod->ib_free_q, &ib);
	bfa_q_qe_init(&ib->qe);

	ib->ref_count = 1;
	ib->start_count = 0;
	ib->idx_mask = 0;

	ib->intr = intr;
	ib->idx_seg = NULL;
	intr->ib = ib;

	ib->bna = ib_mod->bna;

	return ib;
}

static void
bna_ib_put(struct bna_ib_mod *ib_mod, struct bna_ib *ib)
{
	bna_intr_put(ib_mod, ib->intr);

	ib->ref_count--;

	if (ib->ref_count == 0) {
		ib->intr = NULL;
		ib->bna = NULL;
		list_add_tail(&ib->qe, &ib_mod->ib_free_q);
	}
}

/* Returns index offset - starting from 0 */
static int
bna_ib_reserve_idx(struct bna_ib *ib)
{
	struct bna_ib_mod *ib_mod = &ib->bna->ib_mod;
	struct bna_ibidx_seg *idx_seg;
	int idx;
	int num_idx;
	int q_idx;

	/* Find the first free index position */
	bna_ib_find_free_ibidx(ib->idx_mask, idx);
	if (idx == BFI_IBIDX_MAX_SEGSIZE)
		return -1;

	/*
	 * Calculate the total number of indexes held by this IB,
	 * including the index newly reserved above.
	 */
	bna_ib_count_ibidx((ib->idx_mask | (1 << idx)), num_idx);

	/* See if there is a free space in the index segment held by this IB */
	if (ib->idx_seg && (num_idx <= ib->idx_seg->ib_seg_size)) {
		ib->idx_mask |= (1 << idx);
		return idx;
	}

	if (ib->start_count)
		return -1;

	/* Allocate a new segment */
	bna_ib_select_segpool(num_idx, q_idx);
	while (1) {
		if (q_idx == BFI_IBIDX_TOTAL_POOLS)
			return -1;
		if (!list_empty(&ib_mod->ibidx_seg_pool[q_idx]))
			break;
		q_idx++;
	}
	bfa_q_deq(&ib_mod->ibidx_seg_pool[q_idx], &idx_seg);
	bfa_q_qe_init(&idx_seg->qe);

	/* Free the old segment */
	if (ib->idx_seg) {
		bna_ib_select_segpool(ib->idx_seg->ib_seg_size, q_idx);
		list_add_tail(&ib->idx_seg->qe, &ib_mod->ibidx_seg_pool[q_idx]);
	}

	ib->idx_seg = idx_seg;

	ib->idx_mask |= (1 << idx);

	return idx;
}

static void
bna_ib_release_idx(struct bna_ib *ib, int idx)
{
	struct bna_ib_mod *ib_mod = &ib->bna->ib_mod;
	struct bna_ibidx_seg *idx_seg;
	int num_idx;
	int cur_q_idx;
	int new_q_idx;

	ib->idx_mask &= ~(1 << idx);

	if (ib->start_count)
		return;

	bna_ib_count_ibidx(ib->idx_mask, num_idx);

	/*
	 * Free the segment, if there are no more indexes in the segment
	 * held by this IB
	 */
	if (!num_idx) {
		bna_ib_select_segpool(ib->idx_seg->ib_seg_size, cur_q_idx);
		list_add_tail(&ib->idx_seg->qe,
			&ib_mod->ibidx_seg_pool[cur_q_idx]);
		ib->idx_seg = NULL;
		return;
	}

	/* See if we can move to a smaller segment */
	bna_ib_select_segpool(num_idx, new_q_idx);
	bna_ib_select_segpool(ib->idx_seg->ib_seg_size, cur_q_idx);
	while (new_q_idx < cur_q_idx) {
		if (!list_empty(&ib_mod->ibidx_seg_pool[new_q_idx]))
			break;
		new_q_idx++;
	}
	if (new_q_idx < cur_q_idx) {
		/* Select the new smaller segment */
		bfa_q_deq(&ib_mod->ibidx_seg_pool[new_q_idx], &idx_seg);
		bfa_q_qe_init(&idx_seg->qe);
		/* Free the old segment */
		list_add_tail(&ib->idx_seg->qe,
			&ib_mod->ibidx_seg_pool[cur_q_idx]);
		ib->idx_seg = idx_seg;
	}
}

static int
bna_ib_config(struct bna_ib *ib, struct bna_ib_config *ib_config)
{
	if (ib->start_count)
		return -1;

	ib->ib_config.coalescing_timeo = ib_config->coalescing_timeo;
	ib->ib_config.interpkt_timeo = ib_config->interpkt_timeo;
	ib->ib_config.interpkt_count = ib_config->interpkt_count;
	ib->ib_config.ctrl_flags = ib_config->ctrl_flags;

	ib->ib_config.ctrl_flags |= BFI_IB_CF_MASTER_ENABLE;
	if (ib->intr->intr_type == BNA_INTR_T_MSIX)
		ib->ib_config.ctrl_flags |= BFI_IB_CF_MSIX_MODE;

	return 0;
}

static void
bna_ib_start(struct bna_ib *ib)
{
	struct bna_ib_blk_mem ib_cfg;
	struct bna_ib_blk_mem *ib_mem;
	u32 pg_num;
	u32 intx_mask;
	int i;
	void __iomem *base_addr;
	unsigned long off;

	ib->start_count++;

	if (ib->start_count > 1)
		return;

	ib_cfg.host_addr_lo = (u32)(ib->ib_seg_host_addr.lsb);
	ib_cfg.host_addr_hi = (u32)(ib->ib_seg_host_addr.msb);

	ib_cfg.clsc_n_ctrl_n_msix = (((u32)
				     ib->ib_config.coalescing_timeo << 16) |
				((u32)ib->ib_config.ctrl_flags << 8) |
				(ib->intr->vector));
	ib_cfg.ipkt_n_ent_n_idxof =
				((u32)
				 (ib->ib_config.interpkt_timeo & 0xf) << 16) |
				((u32)ib->idx_seg->ib_seg_size << 8) |
				(ib->idx_seg->ib_idx_tbl_offset);
	ib_cfg.ipkt_cnt_cfg_n_unacked = ((u32)
					 ib->ib_config.interpkt_count << 24);

	pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + ib->bna->port_num,
				HQM_IB_RAM_BASE_OFFSET);
	writel(pg_num, ib->bna->regs.page_addr);

	base_addr = BNA_GET_MEM_BASE_ADDR(ib->bna->pcidev.pci_bar_kva,
					HQM_IB_RAM_BASE_OFFSET);

	ib_mem = (struct bna_ib_blk_mem *)0;
	off = (unsigned long)&ib_mem[ib->ib_id].host_addr_lo;
	writel(htonl(ib_cfg.host_addr_lo), base_addr + off);

	off = (unsigned long)&ib_mem[ib->ib_id].host_addr_hi;
	writel(htonl(ib_cfg.host_addr_hi), base_addr + off);

	off = (unsigned long)&ib_mem[ib->ib_id].clsc_n_ctrl_n_msix;
	writel(ib_cfg.clsc_n_ctrl_n_msix, base_addr + off);

	off = (unsigned long)&ib_mem[ib->ib_id].ipkt_n_ent_n_idxof;
	writel(ib_cfg.ipkt_n_ent_n_idxof, base_addr + off);

	off = (unsigned long)&ib_mem[ib->ib_id].ipkt_cnt_cfg_n_unacked;
	writel(ib_cfg.ipkt_cnt_cfg_n_unacked, base_addr + off);

	ib->door_bell.doorbell_ack = BNA_DOORBELL_IB_INT_ACK(
				(u32)ib->ib_config.coalescing_timeo, 0);

	pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + ib->bna->port_num,
				HQM_INDX_TBL_RAM_BASE_OFFSET);
	writel(pg_num, ib->bna->regs.page_addr);

	base_addr = BNA_GET_MEM_BASE_ADDR(ib->bna->pcidev.pci_bar_kva,
					HQM_INDX_TBL_RAM_BASE_OFFSET);
	for (i = 0; i < ib->idx_seg->ib_seg_size; i++) {
		off = (unsigned long)
		((ib->idx_seg->ib_idx_tbl_offset + i) * BFI_IBIDX_SIZE);
		writel(0, base_addr + off);
	}

	if (ib->intr->intr_type == BNA_INTR_T_INTX) {
		bna_intx_disable(ib->bna, intx_mask);
		intx_mask &= ~(ib->intr->vector);
		bna_intx_enable(ib->bna, intx_mask);
	}
}

static void
bna_ib_stop(struct bna_ib *ib)
{
	u32 intx_mask;

	ib->start_count--;

	if (ib->start_count == 0) {
		writel(BNA_DOORBELL_IB_INT_DISABLE,
				ib->door_bell.doorbell_addr);
		if (ib->intr->intr_type == BNA_INTR_T_INTX) {
			bna_intx_disable(ib->bna, intx_mask);
			intx_mask |= (ib->intr->vector);
			bna_intx_enable(ib->bna, intx_mask);
		}
	}
}

static void
bna_ib_fail(struct bna_ib *ib)
{
	ib->start_count = 0;
}

/**
 * RXF
 */
static void rxf_enable(struct bna_rxf *rxf);
static void rxf_disable(struct bna_rxf *rxf);
static void __rxf_config_set(struct bna_rxf *rxf);
static void __rxf_rit_set(struct bna_rxf *rxf);
static void __bna_rxf_stat_clr(struct bna_rxf *rxf);
static int rxf_process_packet_filter(struct bna_rxf *rxf);
static int rxf_clear_packet_filter(struct bna_rxf *rxf);
static void rxf_reset_packet_filter(struct bna_rxf *rxf);
static void rxf_cb_enabled(void *arg, int status);
static void rxf_cb_disabled(void *arg, int status);
static void bna_rxf_cb_stats_cleared(void *arg, int status);
static void __rxf_enable(struct bna_rxf *rxf);
static void __rxf_disable(struct bna_rxf *rxf);

bfa_fsm_state_decl(bna_rxf, stopped, struct bna_rxf,
			enum bna_rxf_event);
bfa_fsm_state_decl(bna_rxf, start_wait, struct bna_rxf,
			enum bna_rxf_event);
bfa_fsm_state_decl(bna_rxf, cam_fltr_mod_wait, struct bna_rxf,
			enum bna_rxf_event);
bfa_fsm_state_decl(bna_rxf, started, struct bna_rxf,
			enum bna_rxf_event);
bfa_fsm_state_decl(bna_rxf, cam_fltr_clr_wait, struct bna_rxf,
			enum bna_rxf_event);
bfa_fsm_state_decl(bna_rxf, stop_wait, struct bna_rxf,
			enum bna_rxf_event);
bfa_fsm_state_decl(bna_rxf, pause_wait, struct bna_rxf,
			enum bna_rxf_event);
bfa_fsm_state_decl(bna_rxf, resume_wait, struct bna_rxf,
			enum bna_rxf_event);
bfa_fsm_state_decl(bna_rxf, stat_clr_wait, struct bna_rxf,
			enum bna_rxf_event);

static struct bfa_sm_table rxf_sm_table[] = {
	{BFA_SM(bna_rxf_sm_stopped), BNA_RXF_STOPPED},
	{BFA_SM(bna_rxf_sm_start_wait), BNA_RXF_START_WAIT},
	{BFA_SM(bna_rxf_sm_cam_fltr_mod_wait), BNA_RXF_CAM_FLTR_MOD_WAIT},
	{BFA_SM(bna_rxf_sm_started), BNA_RXF_STARTED},
	{BFA_SM(bna_rxf_sm_cam_fltr_clr_wait), BNA_RXF_CAM_FLTR_CLR_WAIT},
	{BFA_SM(bna_rxf_sm_stop_wait), BNA_RXF_STOP_WAIT},
	{BFA_SM(bna_rxf_sm_pause_wait), BNA_RXF_PAUSE_WAIT},
	{BFA_SM(bna_rxf_sm_resume_wait), BNA_RXF_RESUME_WAIT},
	{BFA_SM(bna_rxf_sm_stat_clr_wait), BNA_RXF_STAT_CLR_WAIT}
};

static void
bna_rxf_sm_stopped_entry(struct bna_rxf *rxf)
{
	call_rxf_stop_cbfn(rxf, BNA_CB_SUCCESS);
}

static void
bna_rxf_sm_stopped(struct bna_rxf *rxf, enum bna_rxf_event event)
{
	switch (event) {
	case RXF_E_START:
		bfa_fsm_set_state(rxf, bna_rxf_sm_start_wait);
		break;

	case RXF_E_STOP:
		bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
		break;

	case RXF_E_FAIL:
		/* No-op */
		break;

	case RXF_E_CAM_FLTR_MOD:
		call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
		break;

	case RXF_E_STARTED:
	case RXF_E_STOPPED:
	case RXF_E_CAM_FLTR_RESP:
		/**
		 * These events are received due to flushing of mbox
		 * when device fails
		 */
		/* No-op */
		break;

	case RXF_E_PAUSE:
		rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED;
		call_rxf_pause_cbfn(rxf, BNA_CB_SUCCESS);
		break;

	case RXF_E_RESUME:
		rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING;
		call_rxf_resume_cbfn(rxf, BNA_CB_SUCCESS);
		break;

	default:
		bfa_sm_fault(rxf->rx->bna, event);
	}
}

static void
bna_rxf_sm_start_wait_entry(struct bna_rxf *rxf)
{
	__rxf_config_set(rxf);
	__rxf_rit_set(rxf);
	rxf_enable(rxf);
}

static void
bna_rxf_sm_start_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
{
	switch (event) {
	case RXF_E_STOP:
		/**
		 * STOP is originated from bnad. When this happens,
		 * it can not be waiting for filter update
		 */
		call_rxf_start_cbfn(rxf, BNA_CB_INTERRUPT);
		bfa_fsm_set_state(rxf, bna_rxf_sm_stop_wait);
		break;

	case RXF_E_FAIL:
		call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
		call_rxf_start_cbfn(rxf, BNA_CB_FAIL);
		bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
		break;

	case RXF_E_CAM_FLTR_MOD:
		/* No-op */
		break;

	case RXF_E_STARTED:
		/**
		 * Force rxf_process_filter() to go through initial
		 * config
		 */
		if ((rxf->ucast_active_mac != NULL) &&
			(rxf->ucast_pending_set == 0))
			rxf->ucast_pending_set = 1;

		if (rxf->rss_status == BNA_STATUS_T_ENABLED)
			rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING;

		rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;

		bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_mod_wait);
		break;

	case RXF_E_PAUSE:
	case RXF_E_RESUME:
		rxf->rxf_flags |= BNA_RXF_FL_OPERSTATE_CHANGED;
		break;

	default:
		bfa_sm_fault(rxf->rx->bna, event);
	}
}

static void
bna_rxf_sm_cam_fltr_mod_wait_entry(struct bna_rxf *rxf)
{
	if (!rxf_process_packet_filter(rxf)) {
		/* No more pending CAM entries to update */
		bfa_fsm_set_state(rxf, bna_rxf_sm_started);
	}
}

static void
bna_rxf_sm_cam_fltr_mod_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
{
	switch (event) {
	case RXF_E_STOP:
		/**
		 * STOP is originated from bnad. When this happens,
		 * it can not be waiting for filter update
		 */
		call_rxf_start_cbfn(rxf, BNA_CB_INTERRUPT);
		bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_clr_wait);
		break;

	case RXF_E_FAIL:
		rxf_reset_packet_filter(rxf);
		call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
		call_rxf_start_cbfn(rxf, BNA_CB_FAIL);
		bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
		break;

	case RXF_E_CAM_FLTR_MOD:
		/* No-op */
		break;

	case RXF_E_CAM_FLTR_RESP:
		if (!rxf_process_packet_filter(rxf)) {
			/* No more pending CAM entries to update */
			call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS);
			bfa_fsm_set_state(rxf, bna_rxf_sm_started);
		}
		break;

	case RXF_E_PAUSE:
	case RXF_E_RESUME:
		rxf->rxf_flags |= BNA_RXF_FL_OPERSTATE_CHANGED;
		break;

	default:
		bfa_sm_fault(rxf->rx->bna, event);
	}
}

static void
bna_rxf_sm_started_entry(struct bna_rxf *rxf)
{
	call_rxf_start_cbfn(rxf, BNA_CB_SUCCESS);

	if (rxf->rxf_flags & BNA_RXF_FL_OPERSTATE_CHANGED) {
		if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED)
			bfa_fsm_send_event(rxf, RXF_E_PAUSE);
		else
			bfa_fsm_send_event(rxf, RXF_E_RESUME);
	}

}

static void
bna_rxf_sm_started(struct bna_rxf *rxf, enum bna_rxf_event event)
{
	switch (event) {
	case RXF_E_STOP:
		bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_clr_wait);
		/* Hack to get FSM start clearing CAM entries */
		bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_RESP);
		break;

	case RXF_E_FAIL:
		rxf_reset_packet_filter(rxf);
		bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
		break;

	case RXF_E_CAM_FLTR_MOD:
		bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_mod_wait);
		break;

	case RXF_E_PAUSE:
		bfa_fsm_set_state(rxf, bna_rxf_sm_pause_wait);
		break;

	case RXF_E_RESUME:
		bfa_fsm_set_state(rxf, bna_rxf_sm_resume_wait);
		break;

	default:
		bfa_sm_fault(rxf->rx->bna, event);
	}
}

static void
bna_rxf_sm_cam_fltr_clr_wait_entry(struct bna_rxf *rxf)
{
	/**
	 *  Note: Do not add rxf_clear_packet_filter here.
	 * It will overstep mbox when this transition happens:
	 * 	cam_fltr_mod_wait -> cam_fltr_clr_wait on RXF_E_STOP event
	 */
}

static void
bna_rxf_sm_cam_fltr_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
{
	switch (event) {
	case RXF_E_FAIL:
		/**
		 * FSM was in the process of stopping, initiated by
		 * bnad. When this happens, no one can be waiting for
		 * start or filter update
		 */
		rxf_reset_packet_filter(rxf);
		bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
		break;

	case RXF_E_CAM_FLTR_RESP:
		if (!rxf_clear_packet_filter(rxf)) {
			/* No more pending CAM entries to clear */
			bfa_fsm_set_state(rxf, bna_rxf_sm_stop_wait);
			rxf_disable(rxf);
		}
		break;

	default:
		bfa_sm_fault(rxf->rx->bna, event);
	}
}

static void
bna_rxf_sm_stop_wait_entry(struct bna_rxf *rxf)
{
	/**
	 * NOTE: Do not add  rxf_disable here.
	 * It will overstep mbox when this transition happens:
	 * 	start_wait -> stop_wait on RXF_E_STOP event
	 */
}

static void
bna_rxf_sm_stop_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
{
	switch (event) {
	case RXF_E_FAIL:
		/**
		 * FSM was in the process of stopping, initiated by
		 * bnad. When this happens, no one can be waiting for
		 * start or filter update
		 */
		bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
		break;

	case RXF_E_STARTED:
		/**
		 * This event is received due to abrupt transition from
		 * bna_rxf_sm_start_wait state on receiving
		 * RXF_E_STOP event
		 */
		rxf_disable(rxf);
		break;

	case RXF_E_STOPPED:
		/**
		 * FSM was in the process of stopping, initiated by
		 * bnad. When this happens, no one can be waiting for
		 * start or filter update
		 */
		bfa_fsm_set_state(rxf, bna_rxf_sm_stat_clr_wait);
		break;

	case RXF_E_PAUSE:
		rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED;
		break;

	case RXF_E_RESUME:
		rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING;
		break;

	default:
		bfa_sm_fault(rxf->rx->bna, event);
	}
}

static void
bna_rxf_sm_pause_wait_entry(struct bna_rxf *rxf)
{
	rxf->rxf_flags &=
		~(BNA_RXF_FL_OPERSTATE_CHANGED | BNA_RXF_FL_RXF_ENABLED);
	__rxf_disable(rxf);
}

static void
bna_rxf_sm_pause_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
{
	switch (event) {
	case RXF_E_FAIL:
		/**
		 * FSM was in the process of disabling rxf, initiated by
		 * bnad.
		 */
		call_rxf_pause_cbfn(rxf, BNA_CB_FAIL);
		bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
		break;

	case RXF_E_STOPPED:
		rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED;
		call_rxf_pause_cbfn(rxf, BNA_CB_SUCCESS);
		bfa_fsm_set_state(rxf, bna_rxf_sm_started);
		break;

	/*
	 * Since PAUSE/RESUME can only be sent by bnad, we don't expect
	 * any other event during these states
	 */
	default:
		bfa_sm_fault(rxf->rx->bna, event);
	}
}

static void
bna_rxf_sm_resume_wait_entry(struct bna_rxf *rxf)
{
	rxf->rxf_flags &= ~(BNA_RXF_FL_OPERSTATE_CHANGED);
	rxf->rxf_flags |= BNA_RXF_FL_RXF_ENABLED;
	__rxf_enable(rxf);
}

static void
bna_rxf_sm_resume_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
{
	switch (event) {
	case RXF_E_FAIL:
		/**
		 * FSM was in the process of disabling rxf, initiated by
		 * bnad.
		 */
		call_rxf_resume_cbfn(rxf, BNA_CB_FAIL);
		bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
		break;

	case RXF_E_STARTED:
		rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING;
		call_rxf_resume_cbfn(rxf, BNA_CB_SUCCESS);
		bfa_fsm_set_state(rxf, bna_rxf_sm_started);
		break;

	/*
	 * Since PAUSE/RESUME can only be sent by bnad, we don't expect
	 * any other event during these states
	 */
	default:
		bfa_sm_fault(rxf->rx->bna, event);
	}
}

static void
bna_rxf_sm_stat_clr_wait_entry(struct bna_rxf *rxf)
{
	__bna_rxf_stat_clr(rxf);
}

static void
bna_rxf_sm_stat_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
{
	switch (event) {
	case RXF_E_FAIL:
	case RXF_E_STAT_CLEARED:
		bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
		break;

	default:
		bfa_sm_fault(rxf->rx->bna, event);
	}
}

static void
__rxf_enable(struct bna_rxf *rxf)
{
	struct bfi_ll_rxf_multi_req ll_req;
	u32 bm[2] = {0, 0};

	if (rxf->rxf_id < 32)
		bm[0] = 1 << rxf->rxf_id;
	else
		bm[1] = 1 << (rxf->rxf_id - 32);

	bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RX_REQ, 0);
	ll_req.rxf_id_mask[0] = htonl(bm[0]);
	ll_req.rxf_id_mask[1] = htonl(bm[1]);
	ll_req.enable = 1;

	bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req),
			rxf_cb_enabled, rxf);

	bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
}

static void
__rxf_disable(struct bna_rxf *rxf)
{
	struct bfi_ll_rxf_multi_req ll_req;
	u32 bm[2] = {0, 0};

	if (rxf->rxf_id < 32)
		bm[0] = 1 << rxf->rxf_id;
	else
		bm[1] = 1 << (rxf->rxf_id - 32);

	bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RX_REQ, 0);
	ll_req.rxf_id_mask[0] = htonl(bm[0]);
	ll_req.rxf_id_mask[1] = htonl(bm[1]);
	ll_req.enable = 0;

	bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req),
			rxf_cb_disabled, rxf);

	bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
}

static void
__rxf_config_set(struct bna_rxf *rxf)
{
	u32 i;
	struct bna_rss_mem *rss_mem;
	struct bna_rx_fndb_ram *rx_fndb_ram;
	struct bna *bna = rxf->rx->bna;
	void __iomem *base_addr;
	unsigned long off;

	base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
			RSS_TABLE_BASE_OFFSET);

	rss_mem = (struct bna_rss_mem *)0;

	/* Configure RSS if required */
	if (rxf->ctrl_flags & BNA_RXF_CF_RSS_ENABLE) {
		/* configure RSS Table */
		writel(BNA_GET_PAGE_NUM(RAD0_MEM_BLK_BASE_PG_NUM +
			bna->port_num, RSS_TABLE_BASE_OFFSET),
					bna->regs.page_addr);

		/* temporarily disable RSS, while hash value is written */
		off = (unsigned long)&rss_mem[0].type_n_hash;
		writel(0, base_addr + off);

		for (i = 0; i < BFI_RSS_HASH_KEY_LEN; i++) {
			off = (unsigned long)
			&rss_mem[0].hash_key[(BFI_RSS_HASH_KEY_LEN - 1) - i];
			writel(htonl(rxf->rss_cfg.toeplitz_hash_key[i]),
			base_addr + off);
		}

		off = (unsigned long)&rss_mem[0].type_n_hash;
		writel(rxf->rss_cfg.hash_type | rxf->rss_cfg.hash_mask,
			base_addr + off);
	}

	/* Configure RxF */
	writel(BNA_GET_PAGE_NUM(
		LUT0_MEM_BLK_BASE_PG_NUM + (bna->port_num * 2),
		RX_FNDB_RAM_BASE_OFFSET),
		bna->regs.page_addr);

	base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
		RX_FNDB_RAM_BASE_OFFSET);

	rx_fndb_ram = (struct bna_rx_fndb_ram *)0;

	/* We always use RSS table 0 */
	off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].rss_prop;
	writel(rxf->ctrl_flags & BNA_RXF_CF_RSS_ENABLE,
		base_addr + off);

	/* small large buffer enable/disable */
	off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].size_routing_props;
	writel((rxf->ctrl_flags & BNA_RXF_CF_SM_LG_RXQ) | 0x80,
		base_addr + off);

	/* RIT offset,  HDS forced offset, multicast RxQ Id */
	off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].rit_hds_mcastq;
	writel((rxf->rit_segment->rit_offset << 16) |
		(rxf->forced_offset << 8) |
		(rxf->hds_cfg.hdr_type & BNA_HDS_FORCED) | rxf->mcast_rxq_id,
		base_addr + off);

	/*
	 * default vlan tag, default function enable, strip vlan bytes,
	 * HDS type, header size
	 */

	off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].control_flags;
	 writel(((u32)rxf->default_vlan_tag << 16) |
		(rxf->ctrl_flags &
			(BNA_RXF_CF_DEFAULT_VLAN |
			BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE |
			BNA_RXF_CF_VLAN_STRIP)) |
		(rxf->hds_cfg.hdr_type & ~BNA_HDS_FORCED) |
		rxf->hds_cfg.header_size,
		base_addr + off);
}

void
__rxf_vlan_filter_set(struct bna_rxf *rxf, enum bna_status status)
{
	struct bna *bna = rxf->rx->bna;
	int i;

	writel(BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM +
			(bna->port_num * 2), VLAN_RAM_BASE_OFFSET),
			bna->regs.page_addr);

	if (status == BNA_STATUS_T_ENABLED) {
		/* enable VLAN filtering on this function */
		for (i = 0; i <= BFI_MAX_VLAN / 32; i++) {
			writel(rxf->vlan_filter_table[i],
					BNA_GET_VLAN_MEM_ENTRY_ADDR
					(bna->pcidev.pci_bar_kva, rxf->rxf_id,
						i * 32));
		}
	} else {
		/* disable VLAN filtering on this function */
		for (i = 0; i <= BFI_MAX_VLAN / 32; i++) {
			writel(0xffffffff,
					BNA_GET_VLAN_MEM_ENTRY_ADDR
					(bna->pcidev.pci_bar_kva, rxf->rxf_id,
						i * 32));
		}
	}
}

static void
__rxf_rit_set(struct bna_rxf *rxf)
{
	struct bna *bna = rxf->rx->bna;
	struct bna_rit_mem *rit_mem;
	int i;
	void __iomem *base_addr;
	unsigned long off;

	base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
			FUNCTION_TO_RXQ_TRANSLATE);

	rit_mem = (struct bna_rit_mem *)0;

	writel(BNA_GET_PAGE_NUM(RXA0_MEM_BLK_BASE_PG_NUM + bna->port_num,
		FUNCTION_TO_RXQ_TRANSLATE),
		bna->regs.page_addr);

	for (i = 0; i < rxf->rit_segment->rit_size; i++) {
		off = (unsigned long)&rit_mem[i + rxf->rit_segment->rit_offset];
		writel(rxf->rit_segment->rit[i].large_rxq_id << 6 |
			rxf->rit_segment->rit[i].small_rxq_id,
			base_addr + off);
	}
}

static void
__bna_rxf_stat_clr(struct bna_rxf *rxf)
{
	struct bfi_ll_stats_req ll_req;
	u32 bm[2] = {0, 0};

	if (rxf->rxf_id < 32)
		bm[0] = 1 << rxf->rxf_id;
	else
		bm[1] = 1 << (rxf->rxf_id - 32);

	bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0);
	ll_req.stats_mask = 0;
	ll_req.txf_id_mask[0] = 0;
	ll_req.txf_id_mask[1] =	0;

	ll_req.rxf_id_mask[0] = htonl(bm[0]);
	ll_req.rxf_id_mask[1] = htonl(bm[1]);

	bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req),
			bna_rxf_cb_stats_cleared, rxf);
	bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
}

static void
rxf_enable(struct bna_rxf *rxf)
{
	if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED)
		bfa_fsm_send_event(rxf, RXF_E_STARTED);
	else {
		rxf->rxf_flags |= BNA_RXF_FL_RXF_ENABLED;
		__rxf_enable(rxf);
	}
}

static void
rxf_cb_enabled(void *arg, int status)
{
	struct bna_rxf *rxf = (struct bna_rxf *)arg;

	bfa_q_qe_init(&rxf->mbox_qe.qe);
	bfa_fsm_send_event(rxf, RXF_E_STARTED);
}

static void
rxf_disable(struct bna_rxf *rxf)
{
	if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED)
		bfa_fsm_send_event(rxf, RXF_E_STOPPED);
	else
		rxf->rxf_flags &= ~BNA_RXF_FL_RXF_ENABLED;
		__rxf_disable(rxf);
}

static void
rxf_cb_disabled(void *arg, int status)
{
	struct bna_rxf *rxf = (struct bna_rxf *)arg;

	bfa_q_qe_init(&rxf->mbox_qe.qe);
	bfa_fsm_send_event(rxf, RXF_E_STOPPED);
}

void
rxf_cb_cam_fltr_mbox_cmd(void *arg, int status)
{
	struct bna_rxf *rxf = (struct bna_rxf *)arg;

	bfa_q_qe_init(&rxf->mbox_qe.qe);

	bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_RESP);
}

static void
bna_rxf_cb_stats_cleared(void *arg, int status)
{
	struct bna_rxf *rxf = (struct bna_rxf *)arg;

	bfa_q_qe_init(&rxf->mbox_qe.qe);
	bfa_fsm_send_event(rxf, RXF_E_STAT_CLEARED);
}

void
rxf_cam_mbox_cmd(struct bna_rxf *rxf, u8 cmd,
		const struct bna_mac *mac_addr)
{
	struct bfi_ll_mac_addr_req req;

	bfi_h2i_set(req.mh, BFI_MC_LL, cmd, 0);

	req.rxf_id = rxf->rxf_id;
	memcpy(&req.mac_addr, (void *)&mac_addr->addr, ETH_ALEN);

	bna_mbox_qe_fill(&rxf->mbox_qe, &req, sizeof(req),
				rxf_cb_cam_fltr_mbox_cmd, rxf);

	bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe);
}

static int
rxf_process_packet_filter_mcast(struct bna_rxf *rxf)
{
	struct bna_mac *mac = NULL;
	struct list_head *qe;

	/* Add multicast entries */
	if (!list_empty(&rxf->mcast_pending_add_q)) {
		bfa_q_deq(&rxf->mcast_pending_add_q, &qe);
		bfa_q_qe_init(qe);
		mac = (struct bna_mac *)qe;
		rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_ADD_REQ, mac);
		list_add_tail(&mac->qe, &rxf->mcast_active_q);
		return 1;
	}

	/* Delete multicast entries previousely added */
	if (!list_empty(&rxf->mcast_pending_del_q)) {
		bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
		bfa_q_qe_init(qe);
		mac = (struct bna_mac *)qe;
		rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac);
		bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
		return 1;
	}

	return 0;
}

static int
rxf_process_packet_filter_vlan(struct bna_rxf *rxf)
{
	/* Apply the VLAN filter */
	if (rxf->rxf_flags & BNA_RXF_FL_VLAN_CONFIG_PENDING) {
		rxf->rxf_flags &= ~BNA_RXF_FL_VLAN_CONFIG_PENDING;
		if (!(rxf->rxmode_active & BNA_RXMODE_PROMISC) &&
			!(rxf->rxmode_active & BNA_RXMODE_DEFAULT))
			__rxf_vlan_filter_set(rxf, rxf->vlan_filter_status);
	}

	/* Apply RSS configuration */
	if (rxf->rxf_flags & BNA_RXF_FL_RSS_CONFIG_PENDING) {
		rxf->rxf_flags &= ~BNA_RXF_FL_RSS_CONFIG_PENDING;
		if (rxf->rss_status == BNA_STATUS_T_DISABLED) {
			/* RSS is being disabled */
			rxf->ctrl_flags &= ~BNA_RXF_CF_RSS_ENABLE;
			__rxf_rit_set(rxf);
			__rxf_config_set(rxf);
		} else {
			/* RSS is being enabled or reconfigured */
			rxf->ctrl_flags |= BNA_RXF_CF_RSS_ENABLE;
			__rxf_rit_set(rxf);
			__rxf_config_set(rxf);
		}
	}

	return 0;
}

/**
 * Processes pending ucast, mcast entry addition/deletion and issues mailbox
 * command. Also processes pending filter configuration - promiscuous mode,
 * default mode, allmutli mode and issues mailbox command or directly applies
 * to h/w
 */
static int
rxf_process_packet_filter(struct bna_rxf *rxf)
{
	/* Set the default MAC first */
	if (rxf->ucast_pending_set > 0) {
		rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_SET_REQ,
				rxf->ucast_active_mac);
		rxf->ucast_pending_set--;
		return 1;
	}

	if (rxf_process_packet_filter_ucast(rxf))
		return 1;

	if (rxf_process_packet_filter_mcast(rxf))
		return 1;

	if (rxf_process_packet_filter_promisc(rxf))
		return 1;

	if (rxf_process_packet_filter_default(rxf))
		return 1;

	if (rxf_process_packet_filter_allmulti(rxf))
		return 1;

	if (rxf_process_packet_filter_vlan(rxf))
		return 1;

	return 0;
}

static int
rxf_clear_packet_filter_mcast(struct bna_rxf *rxf)
{
	struct bna_mac *mac = NULL;
	struct list_head *qe;

	/* 3. delete pending mcast entries */
	if (!list_empty(&rxf->mcast_pending_del_q)) {
		bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
		bfa_q_qe_init(qe);
		mac = (struct bna_mac *)qe;
		rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac);
		bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
		return 1;
	}

	/* 4. clear active mcast entries; move them to pending_add_q */
	if (!list_empty(&rxf->mcast_active_q)) {
		bfa_q_deq(&rxf->mcast_active_q, &qe);
		bfa_q_qe_init(qe);
		mac = (struct bna_mac *)qe;
		rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac);
		list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
		return 1;
	}

	return 0;
}

/**
 * In the rxf stop path, processes pending ucast/mcast delete queue and issues
 * the mailbox command. Moves the active ucast/mcast entries to pending add q,
 * so that they are added to CAM again in the rxf start path. Moves the current
 * filter settings - promiscuous, default, allmutli - to pending filter
 * configuration
 */
static int
rxf_clear_packet_filter(struct bna_rxf *rxf)
{
	if (rxf_clear_packet_filter_ucast(rxf))
		return 1;

	if (rxf_clear_packet_filter_mcast(rxf))
		return 1;

	/* 5. clear active default MAC in the CAM */
	if (rxf->ucast_pending_set > 0)
		rxf->ucast_pending_set = 0;

	if (rxf_clear_packet_filter_promisc(rxf))
		return 1;

	if (rxf_clear_packet_filter_default(rxf))
		return 1;

	if (rxf_clear_packet_filter_allmulti(rxf))
		return 1;

	return 0;
}

static void
rxf_reset_packet_filter_mcast(struct bna_rxf *rxf)
{
	struct list_head *qe;
	struct bna_mac *mac;

	/* 3. Move active mcast entries to pending_add_q */
	while (!list_empty(&rxf->mcast_active_q)) {
		bfa_q_deq(&rxf->mcast_active_q, &qe);
		bfa_q_qe_init(qe);
		list_add_tail(qe, &rxf->mcast_pending_add_q);
	}

	/* 4. Throw away delete pending mcast entries */
	while (!list_empty(&rxf->mcast_pending_del_q)) {
		bfa_q_deq(&rxf->mcast_pending_del_q, &qe);
		bfa_q_qe_init(qe);
		mac = (struct bna_mac *)qe;
		bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
	}
}

/**
 * In the rxf fail path, throws away the ucast/mcast entries pending for
 * deletion, moves all active ucast/mcast entries to pending queue so that
 * they are added back to CAM in the rxf start path. Also moves the current
 * filter configuration to pending filter configuration.
 */
static void
rxf_reset_packet_filter(struct bna_rxf *rxf)
{
	rxf_reset_packet_filter_ucast(rxf);

	rxf_reset_packet_filter_mcast(rxf);

	/* 5. Turn off ucast set flag */
	rxf->ucast_pending_set = 0;

	rxf_reset_packet_filter_promisc(rxf);

	rxf_reset_packet_filter_default(rxf);

	rxf_reset_packet_filter_allmulti(rxf);
}

static void
bna_rxf_init(struct bna_rxf *rxf,
		struct bna_rx *rx,
		struct bna_rx_config *q_config)
{
	struct list_head *qe;
	struct bna_rxp *rxp;

	/* rxf_id is initialized during rx_mod init */
	rxf->rx = rx;

	INIT_LIST_HEAD(&rxf->ucast_pending_add_q);
	INIT_LIST_HEAD(&rxf->ucast_pending_del_q);
	rxf->ucast_pending_set = 0;
	INIT_LIST_HEAD(&rxf->ucast_active_q);
	rxf->ucast_active_mac = NULL;

	INIT_LIST_HEAD(&rxf->mcast_pending_add_q);
	INIT_LIST_HEAD(&rxf->mcast_pending_del_q);
	INIT_LIST_HEAD(&rxf->mcast_active_q);

	bfa_q_qe_init(&rxf->mbox_qe.qe);

	if (q_config->vlan_strip_status == BNA_STATUS_T_ENABLED)
		rxf->ctrl_flags |= BNA_RXF_CF_VLAN_STRIP;

	rxf->rxf_oper_state = (q_config->paused) ?
		BNA_RXF_OPER_STATE_PAUSED : BNA_RXF_OPER_STATE_RUNNING;

	bna_rxf_adv_init(rxf, rx, q_config);

	rxf->rit_segment = bna_rit_mod_seg_get(&rxf->rx->bna->rit_mod,
					q_config->num_paths);

	list_for_each(qe, &rx->rxp_q) {
		rxp = (struct bna_rxp *)qe;
		if (q_config->rxp_type == BNA_RXP_SINGLE)
			rxf->mcast_rxq_id = rxp->rxq.single.only->rxq_id;
		else
			rxf->mcast_rxq_id = rxp->rxq.slr.large->rxq_id;
		break;
	}

	rxf->vlan_filter_status = BNA_STATUS_T_DISABLED;
	memset(rxf->vlan_filter_table, 0,
			(sizeof(u32) * ((BFI_MAX_VLAN + 1) / 32)));

	bfa_fsm_set_state(rxf, bna_rxf_sm_stopped);
}

static void
bna_rxf_uninit(struct bna_rxf *rxf)
{
	struct bna_mac *mac;

	bna_rit_mod_seg_put(&rxf->rx->bna->rit_mod, rxf->rit_segment);
	rxf->rit_segment = NULL;

	rxf->ucast_pending_set = 0;

	while (!list_empty(&rxf->ucast_pending_add_q)) {
		bfa_q_deq(&rxf->ucast_pending_add_q, &mac);
		bfa_q_qe_init(&mac->qe);
		bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac);
	}

	if (rxf->ucast_active_mac) {
		bfa_q_qe_init(&rxf->ucast_active_mac->qe);
		bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod,
			rxf->ucast_active_mac);
		rxf->ucast_active_mac = NULL;
	}

	while (!list_empty(&rxf->mcast_pending_add_q)) {
		bfa_q_deq(&rxf->mcast_pending_add_q, &mac);
		bfa_q_qe_init(&mac->qe);
		bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
	}

	rxf->rx = NULL;
}

static void
bna_rx_cb_rxf_started(struct bna_rx *rx, enum bna_cb_status status)
{
	bfa_fsm_send_event(rx, RX_E_RXF_STARTED);
	if (rx->rxf.rxf_id < 32)
		rx->bna->rx_mod.rxf_bmap[0] |= ((u32)1 << rx->rxf.rxf_id);
	else
		rx->bna->rx_mod.rxf_bmap[1] |= ((u32)
				1 << (rx->rxf.rxf_id - 32));
}

static void
bna_rxf_start(struct bna_rxf *rxf)
{
	rxf->start_cbfn = bna_rx_cb_rxf_started;
	rxf->start_cbarg = rxf->rx;
	rxf->rxf_flags &= ~BNA_RXF_FL_FAILED;
	bfa_fsm_send_event(rxf, RXF_E_START);
}

static void
bna_rx_cb_rxf_stopped(struct bna_rx *rx, enum bna_cb_status status)
{
	bfa_fsm_send_event(rx, RX_E_RXF_STOPPED);
	if (rx->rxf.rxf_id < 32)
		rx->bna->rx_mod.rxf_bmap[0] &= ~(u32)1 << rx->rxf.rxf_id;
	else
		rx->bna->rx_mod.rxf_bmap[1] &= ~(u32)
				1 << (rx->rxf.rxf_id - 32);
}

static void
bna_rxf_stop(struct bna_rxf *rxf)
{
	rxf->stop_cbfn = bna_rx_cb_rxf_stopped;
	rxf->stop_cbarg = rxf->rx;
	bfa_fsm_send_event(rxf, RXF_E_STOP);
}

static void
bna_rxf_fail(struct bna_rxf *rxf)
{
	rxf->rxf_flags |= BNA_RXF_FL_FAILED;
	bfa_fsm_send_event(rxf, RXF_E_FAIL);
}

int
bna_rxf_state_get(struct bna_rxf *rxf)
{
	return bfa_sm_to_state(rxf_sm_table, rxf->fsm);
}

enum bna_cb_status
bna_rx_ucast_set(struct bna_rx *rx, u8 *ucmac,
		 void (*cbfn)(struct bnad *, struct bna_rx *,
			      enum bna_cb_status))
{
	struct bna_rxf *rxf = &rx->rxf;

	if (rxf->ucast_active_mac == NULL) {
		rxf->ucast_active_mac =
				bna_ucam_mod_mac_get(&rxf->rx->bna->ucam_mod);
		if (rxf->ucast_active_mac == NULL)
			return BNA_CB_UCAST_CAM_FULL;
		bfa_q_qe_init(&rxf->ucast_active_mac->qe);
	}

	memcpy(rxf->ucast_active_mac->addr, ucmac, ETH_ALEN);
	rxf->ucast_pending_set++;
	rxf->cam_fltr_cbfn = cbfn;
	rxf->cam_fltr_cbarg = rx->bna->bnad;

	bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);

	return BNA_CB_SUCCESS;
}

enum bna_cb_status
bna_rx_mcast_add(struct bna_rx *rx, u8 *addr,
		 void (*cbfn)(struct bnad *, struct bna_rx *,
			      enum bna_cb_status))
{
	struct bna_rxf *rxf = &rx->rxf;
	struct list_head	*qe;
	struct bna_mac *mac;

	/* Check if already added */
	list_for_each(qe, &rxf->mcast_active_q) {
		mac = (struct bna_mac *)qe;
		if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
			if (cbfn)
				(*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
			return BNA_CB_SUCCESS;
		}
	}

	/* Check if pending addition */
	list_for_each(qe, &rxf->mcast_pending_add_q) {
		mac = (struct bna_mac *)qe;
		if (BNA_MAC_IS_EQUAL(mac->addr, addr)) {
			if (cbfn)
				(*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
			return BNA_CB_SUCCESS;
		}
	}

	mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod);
	if (mac == NULL)
		return BNA_CB_MCAST_LIST_FULL;
	bfa_q_qe_init(&mac->qe);
	memcpy(mac->addr, addr, ETH_ALEN);
	list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);

	rxf->cam_fltr_cbfn = cbfn;
	rxf->cam_fltr_cbarg = rx->bna->bnad;

	bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);

	return BNA_CB_SUCCESS;
}

enum bna_cb_status
bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mclist,
		     void (*cbfn)(struct bnad *, struct bna_rx *,
				  enum bna_cb_status))
{
	struct bna_rxf *rxf = &rx->rxf;
	struct list_head list_head;
	struct list_head *qe;
	u8 *mcaddr;
	struct bna_mac *mac;
	struct bna_mac *mac1;
	int skip;
	int delete;
	int need_hw_config = 0;
	int i;

	/* Allocate nodes */
	INIT_LIST_HEAD(&list_head);
	for (i = 0, mcaddr = mclist; i < count; i++) {
		mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod);
		if (mac == NULL)
			goto err_return;
		bfa_q_qe_init(&mac->qe);
		memcpy(mac->addr, mcaddr, ETH_ALEN);
		list_add_tail(&mac->qe, &list_head);

		mcaddr += ETH_ALEN;
	}

	/* Schedule for addition */
	while (!list_empty(&list_head)) {
		bfa_q_deq(&list_head, &qe);
		mac = (struct bna_mac *)qe;
		bfa_q_qe_init(&mac->qe);

		skip = 0;

		/* Skip if already added */
		list_for_each(qe, &rxf->mcast_active_q) {
			mac1 = (struct bna_mac *)qe;
			if (BNA_MAC_IS_EQUAL(mac1->addr, mac->addr)) {
				bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod,
							mac);
				skip = 1;
				break;
			}
		}

		if (skip)
			continue;

		/* Skip if pending addition */
		list_for_each(qe, &rxf->mcast_pending_add_q) {
			mac1 = (struct bna_mac *)qe;
			if (BNA_MAC_IS_EQUAL(mac1->addr, mac->addr)) {
				bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod,
							mac);
				skip = 1;
				break;
			}
		}

		if (skip)
			continue;

		need_hw_config = 1;
		list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
	}

	/**
	 * Delete the entries that are in the pending_add_q but not
	 * in the new list
	 */
	while (!list_empty(&rxf->mcast_pending_add_q)) {
		bfa_q_deq(&rxf->mcast_pending_add_q, &qe);
		mac = (struct bna_mac *)qe;
		bfa_q_qe_init(&mac->qe);
		for (i = 0, mcaddr = mclist, delete = 1; i < count; i++) {
			if (BNA_MAC_IS_EQUAL(mcaddr, mac->addr)) {
				delete = 0;
				break;
			}
			mcaddr += ETH_ALEN;
		}
		if (delete)
			bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
		else
			list_add_tail(&mac->qe, &list_head);
	}
	while (!list_empty(&list_head)) {
		bfa_q_deq(&list_head, &qe);
		mac = (struct bna_mac *)qe;
		bfa_q_qe_init(&mac->qe);
		list_add_tail(&mac->qe, &rxf->mcast_pending_add_q);
	}

	/**
	 * Schedule entries for deletion that are in the active_q but not
	 * in the new list
	 */
	while (!list_empty(&rxf->mcast_active_q)) {
		bfa_q_deq(&rxf->mcast_active_q, &qe);
		mac = (struct bna_mac *)qe;
		bfa_q_qe_init(&mac->qe);
		for (i = 0, mcaddr = mclist, delete = 1; i < count; i++) {
			if (BNA_MAC_IS_EQUAL(mcaddr, mac->addr)) {
				delete = 0;
				break;
			}
			mcaddr += ETH_ALEN;
		}
		if (delete) {
			list_add_tail(&mac->qe, &rxf->mcast_pending_del_q);
			need_hw_config = 1;
		} else {
			list_add_tail(&mac->qe, &list_head);
		}
	}
	while (!list_empty(&list_head)) {
		bfa_q_deq(&list_head, &qe);
		mac = (struct bna_mac *)qe;
		bfa_q_qe_init(&mac->qe);
		list_add_tail(&mac->qe, &rxf->mcast_active_q);
	}

	if (need_hw_config) {
		rxf->cam_fltr_cbfn = cbfn;
		rxf->cam_fltr_cbarg = rx->bna->bnad;
		bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
	} else if (cbfn)
		(*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);

	return BNA_CB_SUCCESS;

err_return:
	while (!list_empty(&list_head)) {
		bfa_q_deq(&list_head, &qe);
		mac = (struct bna_mac *)qe;
		bfa_q_qe_init(&mac->qe);
		bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac);
	}

	return BNA_CB_MCAST_LIST_FULL;
}

void
bna_rx_vlan_add(struct bna_rx *rx, int vlan_id)
{
	struct bna_rxf *rxf = &rx->rxf;
	int index = (vlan_id >> 5);
	int bit = (1 << (vlan_id & 0x1F));

	rxf->vlan_filter_table[index] |= bit;
	if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) {
		rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
		bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
	}
}

void
bna_rx_vlan_del(struct bna_rx *rx, int vlan_id)
{
	struct bna_rxf *rxf = &rx->rxf;
	int index = (vlan_id >> 5);
	int bit = (1 << (vlan_id & 0x1F));

	rxf->vlan_filter_table[index] &= ~bit;
	if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) {
		rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING;
		bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD);
	}
}

/**
 * RX
 */
#define	RXQ_RCB_INIT(q, rxp, qdepth, bna, _id, unmapq_mem)	do {	\
	struct bna_doorbell_qset *_qset;				\
	unsigned long off;						\
	(q)->rcb->producer_index = (q)->rcb->consumer_index = 0;	\
	(q)->rcb->q_depth = (qdepth);					\
	(q)->rcb->unmap_q = unmapq_mem;					\
	(q)->rcb->rxq = (q);						\
	(q)->rcb->cq = &(rxp)->cq;					\
	(q)->rcb->bnad = (bna)->bnad;					\
	_qset = (struct bna_doorbell_qset *)0;			\
	off = (unsigned long)&_qset[(q)->rxq_id].rxq[0];		\
	(q)->rcb->q_dbell = off +					\
		BNA_GET_DOORBELL_BASE_ADDR((bna)->pcidev.pci_bar_kva);	\
	(q)->rcb->id = _id;						\
} while (0)

#define	BNA_GET_RXQS(qcfg)	(((qcfg)->rxp_type == BNA_RXP_SINGLE) ?	\
	(qcfg)->num_paths : ((qcfg)->num_paths * 2))

#define	SIZE_TO_PAGES(size)	(((size) >> PAGE_SHIFT) + ((((size) &\
	(PAGE_SIZE - 1)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))

#define	call_rx_stop_callback(rx, status)				\
	if ((rx)->stop_cbfn) {						\
		(*(rx)->stop_cbfn)((rx)->stop_cbarg, rx, (status));	\
		(rx)->stop_cbfn = NULL;					\
		(rx)->stop_cbarg = NULL;				\
	}

/*
 * Since rx_enable is synchronous callback, there is no start_cbfn required.
 * Instead, we'll call bnad_rx_post(rxp) so that bnad can post the buffers
 * for each rxpath.
 */

#define	call_rx_disable_cbfn(rx, status)				\
		if ((rx)->disable_cbfn)	{				\
			(*(rx)->disable_cbfn)((rx)->disable_cbarg,	\
					status);			\
			(rx)->disable_cbfn = NULL;			\
			(rx)->disable_cbarg = NULL;			\
		}							\

#define	rxqs_reqd(type, num_rxqs)					\
	(((type) == BNA_RXP_SINGLE) ? (num_rxqs) : ((num_rxqs) * 2))

#define rx_ib_fail(rx)						\
do {								\
	struct bna_rxp *rxp;					\
	struct list_head *qe;						\
	list_for_each(qe, &(rx)->rxp_q) {				\
		rxp = (struct bna_rxp *)qe;			\
		bna_ib_fail(rxp->cq.ib);			\
	}							\
} while (0)

static void __bna_multi_rxq_stop(struct bna_rxp *, u32 *);
static void __bna_rxq_start(struct bna_rxq *rxq);
static void __bna_cq_start(struct bna_cq *cq);
static void bna_rit_create(struct bna_rx *rx);
static void bna_rx_cb_multi_rxq_stopped(void *arg, int status);
static void bna_rx_cb_rxq_stopped_all(void *arg);

bfa_fsm_state_decl(bna_rx, stopped,
	struct bna_rx, enum bna_rx_event);
bfa_fsm_state_decl(bna_rx, rxf_start_wait,
	struct bna_rx, enum bna_rx_event);
bfa_fsm_state_decl(bna_rx, started,
	struct bna_rx, enum bna_rx_event);
bfa_fsm_state_decl(bna_rx, rxf_stop_wait,
	struct bna_rx, enum bna_rx_event);
bfa_fsm_state_decl(bna_rx, rxq_stop_wait,
	struct bna_rx, enum bna_rx_event);

static const struct bfa_sm_table rx_sm_table[] = {
	{BFA_SM(bna_rx_sm_stopped), BNA_RX_STOPPED},
	{BFA_SM(bna_rx_sm_rxf_start_wait), BNA_RX_RXF_START_WAIT},
	{BFA_SM(bna_rx_sm_started), BNA_RX_STARTED},
	{BFA_SM(bna_rx_sm_rxf_stop_wait), BNA_RX_RXF_STOP_WAIT},
	{BFA_SM(bna_rx_sm_rxq_stop_wait), BNA_RX_RXQ_STOP_WAIT},
};

static void bna_rx_sm_stopped_entry(struct bna_rx *rx)
{
	struct bna_rxp *rxp;
	struct list_head *qe_rxp;

	list_for_each(qe_rxp, &rx->rxp_q) {
		rxp = (struct bna_rxp *)qe_rxp;
		rx->rx_cleanup_cbfn(rx->bna->bnad, rxp->cq.ccb);
	}

	call_rx_stop_callback(rx, BNA_CB_SUCCESS);
}

static void bna_rx_sm_stopped(struct bna_rx *rx,
				enum bna_rx_event event)
{
	switch (event) {
	case RX_E_START:
		bfa_fsm_set_state(rx, bna_rx_sm_rxf_start_wait);
		break;
	case RX_E_STOP:
		call_rx_stop_callback(rx, BNA_CB_SUCCESS);
		break;
	case RX_E_FAIL:
		/* no-op */
		break;
	default:
		bfa_sm_fault(rx->bna, event);
		break;
	}

}

static void bna_rx_sm_rxf_start_wait_entry(struct bna_rx *rx)
{
	struct bna_rxp *rxp;
	struct list_head *qe_rxp;
	struct bna_rxq *q0 = NULL, *q1 = NULL;

	/* Setup the RIT */
	bna_rit_create(rx);

	list_for_each(qe_rxp, &rx->rxp_q) {
		rxp = (struct bna_rxp *)qe_rxp;
		bna_ib_start(rxp->cq.ib);
		GET_RXQS(rxp, q0, q1);
		q0->buffer_size = bna_port_mtu_get(&rx->bna->port);
		__bna_rxq_start(q0);
		rx->rx_post_cbfn(rx->bna->bnad, q0->rcb);
		if (q1)  {
			__bna_rxq_start(q1);
			rx->rx_post_cbfn(rx->bna->bnad, q1->rcb);
		}
		__bna_cq_start(&rxp->cq);
	}

	bna_rxf_start(&rx->rxf);
}

static void bna_rx_sm_rxf_start_wait(struct bna_rx *rx,
				enum bna_rx_event event)
{
	switch (event) {
	case RX_E_STOP:
		bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
		break;
	case RX_E_FAIL:
		bfa_fsm_set_state(rx, bna_rx_sm_stopped);
		rx_ib_fail(rx);
		bna_rxf_fail(&rx->rxf);
		break;
	case RX_E_RXF_STARTED:
		bfa_fsm_set_state(rx, bna_rx_sm_started);
		break;
	default:
		bfa_sm_fault(rx->bna, event);
		break;
	}
}

void
bna_rx_sm_started_entry(struct bna_rx *rx)
{
	struct bna_rxp *rxp;
	struct list_head *qe_rxp;

	/* Start IB */
	list_for_each(qe_rxp, &rx->rxp_q) {
		rxp = (struct bna_rxp *)qe_rxp;
		bna_ib_ack(&rxp->cq.ib->door_bell, 0);
	}

	bna_llport_admin_up(&rx->bna->port.llport);
}

void
bna_rx_sm_started(struct bna_rx *rx, enum bna_rx_event event)
{
	switch (event) {
	case RX_E_FAIL:
		bna_llport_admin_down(&rx->bna->port.llport);
		bfa_fsm_set_state(rx, bna_rx_sm_stopped);
		rx_ib_fail(rx);
		bna_rxf_fail(&rx->rxf);
		break;
	case RX_E_STOP:
		bna_llport_admin_down(&rx->bna->port.llport);
		bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
		break;
	default:
		bfa_sm_fault(rx->bna, event);
		break;
	}
}

void
bna_rx_sm_rxf_stop_wait_entry(struct bna_rx *rx)
{
	bna_rxf_stop(&rx->rxf);
}

void
bna_rx_sm_rxf_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
{
	switch (event) {
	case RX_E_RXF_STOPPED:
		bfa_fsm_set_state(rx, bna_rx_sm_rxq_stop_wait);
		break;
	case RX_E_RXF_STARTED:
		/**
		 * RxF was in the process of starting up when
		 * RXF_E_STOP was issued. Ignore this event
		 */
		break;
	case RX_E_FAIL:
		bfa_fsm_set_state(rx, bna_rx_sm_stopped);
		rx_ib_fail(rx);
		bna_rxf_fail(&rx->rxf);
		break;
	default:
		bfa_sm_fault(rx->bna, event);
		break;
	}

}

void
bna_rx_sm_rxq_stop_wait_entry(struct bna_rx *rx)
{
	struct bna_rxp *rxp = NULL;
	struct bna_rxq *q0 = NULL;
	struct bna_rxq *q1 = NULL;
	struct list_head	*qe;
	u32 rxq_mask[2] = {0, 0};

	/* Only one call to multi-rxq-stop for all RXPs in this RX */
	bfa_wc_up(&rx->rxq_stop_wc);
	list_for_each(qe, &rx->rxp_q) {
		rxp = (struct bna_rxp *)qe;
		GET_RXQS(rxp, q0, q1);
		if (q0->rxq_id < 32)
			rxq_mask[0] |= ((u32)1 << q0->rxq_id);
		else
			rxq_mask[1] |= ((u32)1 << (q0->rxq_id - 32));
		if (q1) {
			if (q1->rxq_id < 32)
				rxq_mask[0] |= ((u32)1 << q1->rxq_id);
			else
				rxq_mask[1] |= ((u32)
						1 << (q1->rxq_id - 32));
		}
	}

	__bna_multi_rxq_stop(rxp, rxq_mask);
}

void
bna_rx_sm_rxq_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
{
	struct bna_rxp *rxp = NULL;
	struct list_head	*qe;

	switch (event) {
	case RX_E_RXQ_STOPPED:
		list_for_each(qe, &rx->rxp_q) {
			rxp = (struct bna_rxp *)qe;
			bna_ib_stop(rxp->cq.ib);
		}
		/* Fall through */
	case RX_E_FAIL:
		bfa_fsm_set_state(rx, bna_rx_sm_stopped);
		break;
	default:
		bfa_sm_fault(rx->bna, event);
		break;
	}
}

void
__bna_multi_rxq_stop(struct bna_rxp *rxp, u32 * rxq_id_mask)
{
	struct bfi_ll_q_stop_req ll_req;

	bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RXQ_STOP_REQ, 0);
	ll_req.q_id_mask[0] = htonl(rxq_id_mask[0]);
	ll_req.q_id_mask[1] = htonl(rxq_id_mask[1]);
	bna_mbox_qe_fill(&rxp->mbox_qe, &ll_req, sizeof(ll_req),
		bna_rx_cb_multi_rxq_stopped, rxp);
	bna_mbox_send(rxp->rx->bna, &rxp->mbox_qe);
}

void
__bna_rxq_start(struct bna_rxq *rxq)
{
	struct bna_rxtx_q_mem *q_mem;
	struct bna_rxq_mem rxq_cfg, *rxq_mem;
	struct bna_dma_addr cur_q_addr;
	/* struct bna_doorbell_qset *qset; */
	struct bna_qpt *qpt;
	u32 pg_num;
	struct bna *bna = rxq->rx->bna;
	void __iomem *base_addr;
	unsigned long off;

	qpt = &rxq->qpt;
	cur_q_addr = *((struct bna_dma_addr *)(qpt->kv_qpt_ptr));

	rxq_cfg.pg_tbl_addr_lo = qpt->hw_qpt_ptr.lsb;
	rxq_cfg.pg_tbl_addr_hi = qpt->hw_qpt_ptr.msb;
	rxq_cfg.cur_q_entry_lo = cur_q_addr.lsb;
	rxq_cfg.cur_q_entry_hi = cur_q_addr.msb;

	rxq_cfg.pg_cnt_n_prd_ptr = ((u32)qpt->page_count << 16) | 0x0;
	rxq_cfg.entry_n_pg_size = ((u32)(BFI_RXQ_WI_SIZE >> 2) << 16) |
		(qpt->page_size >> 2);
	rxq_cfg.sg_n_cq_n_cns_ptr =
		((u32)(rxq->rxp->cq.cq_id & 0xff) << 16) | 0x0;
	rxq_cfg.buf_sz_n_q_state = ((u32)rxq->buffer_size << 16) |
		BNA_Q_IDLE_STATE;
	rxq_cfg.next_qid = 0x0 | (0x3 << 8);

	/* Write the page number register */
	pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + bna->port_num,
			HQM_RXTX_Q_RAM_BASE_OFFSET);
	writel(pg_num, bna->regs.page_addr);

	/* Write to h/w */
	base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
					HQM_RXTX_Q_RAM_BASE_OFFSET);

	q_mem = (struct bna_rxtx_q_mem *)0;
	rxq_mem = &q_mem[rxq->rxq_id].rxq;

	off = (unsigned long)&rxq_mem->pg_tbl_addr_lo;
	writel(htonl(rxq_cfg.pg_tbl_addr_lo), base_addr + off);

	off = (unsigned long)&rxq_mem->pg_tbl_addr_hi;
	writel(htonl(rxq_cfg.pg_tbl_addr_hi), base_addr + off);

	off = (unsigned long)&rxq_mem->cur_q_entry_lo;
	writel(htonl(rxq_cfg.cur_q_entry_lo), base_addr + off);

	off = (unsigned long)&rxq_mem->cur_q_entry_hi;
	writel(htonl(rxq_cfg.cur_q_entry_hi), base_addr + off);

	off = (unsigned long)&rxq_mem->pg_cnt_n_prd_ptr;
	writel(rxq_cfg.pg_cnt_n_prd_ptr, base_addr + off);

	off = (unsigned long)&rxq_mem->entry_n_pg_size;
	writel(rxq_cfg.entry_n_pg_size, base_addr + off);

	off = (unsigned long)&rxq_mem->sg_n_cq_n_cns_ptr;
	writel(rxq_cfg.sg_n_cq_n_cns_ptr, base_addr + off);

	off = (unsigned long)&rxq_mem->buf_sz_n_q_state;
	writel(rxq_cfg.buf_sz_n_q_state, base_addr + off);

	off = (unsigned long)&rxq_mem->next_qid;
	writel(rxq_cfg.next_qid, base_addr + off);

	rxq->rcb->producer_index = 0;
	rxq->rcb->consumer_index = 0;
}

void
__bna_cq_start(struct bna_cq *cq)
{
	struct bna_cq_mem cq_cfg, *cq_mem;
	const struct bna_qpt *qpt;
	struct bna_dma_addr cur_q_addr;
	u32 pg_num;
	struct bna *bna = cq->rx->bna;
	void __iomem *base_addr;
	unsigned long off;

	qpt = &cq->qpt;
	cur_q_addr = *((struct bna_dma_addr *)(qpt->kv_qpt_ptr));

	/*
	 * Fill out structure, to be subsequently written
	 * to hardware
	 */
	cq_cfg.pg_tbl_addr_lo = qpt->hw_qpt_ptr.lsb;
	cq_cfg.pg_tbl_addr_hi = qpt->hw_qpt_ptr.msb;
	cq_cfg.cur_q_entry_lo = cur_q_addr.lsb;
	cq_cfg.cur_q_entry_hi = cur_q_addr.msb;

	cq_cfg.pg_cnt_n_prd_ptr = (qpt->page_count << 16) | 0x0;
	cq_cfg.entry_n_pg_size =
		((u32)(BFI_CQ_WI_SIZE >> 2) << 16) | (qpt->page_size >> 2);
	cq_cfg.int_blk_n_cns_ptr = ((((u32)cq->ib_seg_offset) << 24) |
			((u32)(cq->ib->ib_id & 0xff)  << 16) | 0x0);
	cq_cfg.q_state = BNA_Q_IDLE_STATE;

	/* Write the page number register */
	pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + bna->port_num,
				  HQM_CQ_RAM_BASE_OFFSET);

	writel(pg_num, bna->regs.page_addr);

	/* H/W write */
	base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva,
					HQM_CQ_RAM_BASE_OFFSET);

	cq_mem = (struct bna_cq_mem *)0;

	off = (unsigned long)&cq_mem[cq->cq_id].pg_tbl_addr_lo;
	writel(htonl(cq_cfg.pg_tbl_addr_lo), base_addr + off);

	off = (unsigned long)&cq_mem[cq->cq_id].pg_tbl_addr_hi;
	writel(htonl(cq_cfg.pg_tbl_addr_hi), base_addr + off);

	off = (unsigned long)&cq_mem[cq->cq_id].cur_q_entry_lo;
	writel(htonl(cq_cfg.cur_q_entry_lo), base_addr + off);

	off = (unsigned long)&cq_mem[cq->cq_id].cur_q_entry_hi;
	writel(htonl(cq_cfg.cur_q_entry_hi), base_addr + off);

	off = (unsigned long)&cq_mem[cq->cq_id].pg_cnt_n_prd_ptr;
	writel(cq_cfg.pg_cnt_n_prd_ptr, base_addr + off);

	off = (unsigned long)&cq_mem[cq->cq_id].entry_n_pg_size;
	writel(cq_cfg.entry_n_pg_size, base_addr + off);

	off = (unsigned long)&cq_mem[cq->cq_id].int_blk_n_cns_ptr;
	writel(cq_cfg.int_blk_n_cns_ptr, base_addr + off);

	off = (unsigned long)&cq_mem[cq->cq_id].q_state;
	writel(cq_cfg.q_state, base_addr + off);

	cq->ccb->producer_index = 0;
	*(cq->ccb->hw_producer_index) = 0;
}

void
bna_rit_create(struct bna_rx *rx)
{
	struct list_head	*qe_rxp;
	struct bna *bna;
	struct bna_rxp *rxp;
	struct bna_rxq *q0 = NULL;
	struct bna_rxq *q1 = NULL;
	int offset;

	bna = rx->bna;

	offset = 0;
	list_for_each(qe_rxp, &rx->rxp_q) {
		rxp = (struct bna_rxp *)qe_rxp;
		GET_RXQS(rxp, q0, q1);
		rx->rxf.rit_segment->rit[offset].large_rxq_id = q0->rxq_id;
		rx->rxf.rit_segment->rit[offset].small_rxq_id =
						(q1 ? q1->rxq_id : 0);
		offset++;
	}
}

static int
_rx_can_satisfy(struct bna_rx_mod *rx_mod,
		struct bna_rx_config *rx_cfg)
{
	if ((rx_mod->rx_free_count == 0) ||
		(rx_mod->rxp_free_count == 0) ||
		(rx_mod->rxq_free_count == 0))
		return 0;

	if (rx_cfg->rxp_type == BNA_RXP_SINGLE) {
		if ((rx_mod->rxp_free_count < rx_cfg->num_paths) ||
			(rx_mod->rxq_free_count < rx_cfg->num_paths))
				return 0;
	} else {
		if ((rx_mod->rxp_free_count < rx_cfg->num_paths) ||
			(rx_mod->rxq_free_count < (2 * rx_cfg->num_paths)))
			return 0;
	}

	if (!bna_rit_mod_can_satisfy(&rx_mod->bna->rit_mod, rx_cfg->num_paths))
		return 0;

	return 1;
}

static struct bna_rxq *
_get_free_rxq(struct bna_rx_mod *rx_mod)
{
	struct bna_rxq *rxq = NULL;
	struct list_head	*qe = NULL;

	bfa_q_deq(&rx_mod->rxq_free_q, &qe);
	if (qe) {
		rx_mod->rxq_free_count--;
		rxq = (struct bna_rxq *)qe;
	}
	return rxq;
}

static void
_put_free_rxq(struct bna_rx_mod *rx_mod, struct bna_rxq *rxq)
{
	bfa_q_qe_init(&rxq->qe);
	list_add_tail(&rxq->qe, &rx_mod->rxq_free_q);
	rx_mod->rxq_free_count++;
}

static struct bna_rxp *
_get_free_rxp(struct bna_rx_mod *rx_mod)
{
	struct list_head	*qe = NULL;
	struct bna_rxp *rxp = NULL;

	bfa_q_deq(&rx_mod->rxp_free_q, &qe);
	if (qe) {
		rx_mod->rxp_free_count--;

		rxp = (struct bna_rxp *)qe;
	}

	return rxp;
}

static void
_put_free_rxp(struct bna_rx_mod *rx_mod, struct bna_rxp *rxp)
{
	bfa_q_qe_init(&rxp->qe);
	list_add_tail(&rxp->qe, &rx_mod->rxp_free_q);
	rx_mod->rxp_free_count++;
}

static struct bna_rx *
_get_free_rx(struct bna_rx_mod *rx_mod)
{
	struct list_head	*qe = NULL;
	struct bna_rx *rx = NULL;

	bfa_q_deq(&rx_mod->rx_free_q, &qe);
	if (qe) {
		rx_mod->rx_free_count--;

		rx = (struct bna_rx *)qe;
		bfa_q_qe_init(qe);
		list_add_tail(&rx->qe, &rx_mod->rx_active_q);
	}

	return rx;
}

static void
_put_free_rx(struct bna_rx_mod *rx_mod, struct bna_rx *rx)
{
	bfa_q_qe_init(&rx->qe);
	list_add_tail(&rx->qe, &rx_mod->rx_free_q);
	rx_mod->rx_free_count++;
}

static void
_rx_init(struct bna_rx *rx, struct bna *bna)
{
	rx->bna = bna;
	rx->rx_flags = 0;

	INIT_LIST_HEAD(&rx->rxp_q);

	rx->rxq_stop_wc.wc_resume = bna_rx_cb_rxq_stopped_all;
	rx->rxq_stop_wc.wc_cbarg = rx;
	rx->rxq_stop_wc.wc_count = 0;

	rx->stop_cbfn = NULL;
	rx->stop_cbarg = NULL;
}

static void
_rxp_add_rxqs(struct bna_rxp *rxp,
		struct bna_rxq *q0,
		struct bna_rxq *q1)
{
	switch (rxp->type) {
	case BNA_RXP_SINGLE:
		rxp->rxq.single.only = q0;
		rxp->rxq.single.reserved = NULL;
		break;
	case BNA_RXP_SLR:
		rxp->rxq.slr.large = q0;
		rxp->rxq.slr.small = q1;
		break;
	case BNA_RXP_HDS:
		rxp->rxq.hds.data = q0;
		rxp->rxq.hds.hdr = q1;
		break;
	default:
		break;
	}
}

static void
_rxq_qpt_init(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)
{
	int	i;

	rxq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
	rxq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
	rxq->qpt.kv_qpt_ptr = qpt_mem->kva;
	rxq->qpt.page_count = page_count;
	rxq->qpt.page_size = page_size;

	rxq->rcb->sw_qpt = (void **) swqpt_mem->kva;

	for (i = 0; i < rxq->qpt.page_count; i++) {
		rxq->rcb->sw_qpt[i] = page_mem[i].kva;
		((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].lsb =
			page_mem[i].dma.lsb;
		((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].msb =
			page_mem[i].dma.msb;

	}
}

static void
_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)
{
	int	i;

	rxp->cq.qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
	rxp->cq.qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
	rxp->cq.qpt.kv_qpt_ptr = qpt_mem->kva;
	rxp->cq.qpt.page_count = page_count;
	rxp->cq.qpt.page_size = page_size;

	rxp->cq.ccb->sw_qpt = (void **) swqpt_mem->kva;

	for (i = 0; i < rxp->cq.qpt.page_count; i++) {
		rxp->cq.ccb->sw_qpt[i] = page_mem[i].kva;

		((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].lsb =
			page_mem[i].dma.lsb;
		((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].msb =
			page_mem[i].dma.msb;

	}
}

static void
_rx_add_rxp(struct bna_rx *rx, struct bna_rxp *rxp)
{
	list_add_tail(&rxp->qe, &rx->rxp_q);
}

static void
_init_rxmod_queues(struct bna_rx_mod *rx_mod)
{
	INIT_LIST_HEAD(&rx_mod->rx_free_q);
	INIT_LIST_HEAD(&rx_mod->rxq_free_q);
	INIT_LIST_HEAD(&rx_mod->rxp_free_q);
	INIT_LIST_HEAD(&rx_mod->rx_active_q);

	rx_mod->rx_free_count = 0;
	rx_mod->rxq_free_count = 0;
	rx_mod->rxp_free_count = 0;
}

static void
_rx_ctor(struct bna_rx *rx, int id)
{
	bfa_q_qe_init(&rx->qe);
	INIT_LIST_HEAD(&rx->rxp_q);
	rx->bna = NULL;

	rx->rxf.rxf_id = id;

	/* FIXME: mbox_qe ctor()?? */
	bfa_q_qe_init(&rx->mbox_qe.qe);

	rx->stop_cbfn = NULL;
	rx->stop_cbarg = NULL;
}

void
bna_rx_cb_multi_rxq_stopped(void *arg, int status)
{
	struct bna_rxp *rxp = (struct bna_rxp *)arg;

	bfa_wc_down(&rxp->rx->rxq_stop_wc);
}

void
bna_rx_cb_rxq_stopped_all(void *arg)
{
	struct bna_rx *rx = (struct bna_rx *)arg;

	bfa_fsm_send_event(rx, RX_E_RXQ_STOPPED);
}

static void
bna_rx_mod_cb_rx_stopped(void *arg, struct bna_rx *rx,
			 enum bna_cb_status status)
{
	struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg;

	bfa_wc_down(&rx_mod->rx_stop_wc);
}

static void
bna_rx_mod_cb_rx_stopped_all(void *arg)
{
	struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg;

	if (rx_mod->stop_cbfn)
		rx_mod->stop_cbfn(&rx_mod->bna->port, BNA_CB_SUCCESS);
	rx_mod->stop_cbfn = NULL;
}

static void
bna_rx_start(struct bna_rx *rx)
{
	rx->rx_flags |= BNA_RX_F_PORT_ENABLED;
	if (rx->rx_flags & BNA_RX_F_ENABLE)
		bfa_fsm_send_event(rx, RX_E_START);
}

static void
bna_rx_stop(struct bna_rx *rx)
{
	rx->rx_flags &= ~BNA_RX_F_PORT_ENABLED;
	if (rx->fsm == (bfa_fsm_t) bna_rx_sm_stopped)
		bna_rx_mod_cb_rx_stopped(&rx->bna->rx_mod, rx, BNA_CB_SUCCESS);
	else {
		rx->stop_cbfn = bna_rx_mod_cb_rx_stopped;
		rx->stop_cbarg = &rx->bna->rx_mod;
		bfa_fsm_send_event(rx, RX_E_STOP);
	}
}

static void
bna_rx_fail(struct bna_rx *rx)
{
	/* Indicate port is not enabled, and failed */
	rx->rx_flags &= ~BNA_RX_F_PORT_ENABLED;
	rx->rx_flags |= BNA_RX_F_PORT_FAILED;
	bfa_fsm_send_event(rx, RX_E_FAIL);
}

void
bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
{
	struct bna_rx *rx;
	struct list_head *qe;

	rx_mod->flags |= BNA_RX_MOD_F_PORT_STARTED;
	if (type == BNA_RX_T_LOOPBACK)
		rx_mod->flags |= BNA_RX_MOD_F_PORT_LOOPBACK;

	list_for_each(qe, &rx_mod->rx_active_q) {
		rx = (struct bna_rx *)qe;
		if (rx->type == type)
			bna_rx_start(rx);
	}
}

void
bna_rx_mod_stop(struct bna_rx_mod *rx_mod, enum bna_rx_type type)
{
	struct bna_rx *rx;
	struct list_head *qe;

	rx_mod->flags &= ~BNA_RX_MOD_F_PORT_STARTED;
	rx_mod->flags &= ~BNA_RX_MOD_F_PORT_LOOPBACK;

	rx_mod->stop_cbfn = bna_port_cb_rx_stopped;

	/**
	 * Before calling bna_rx_stop(), increment rx_stop_wc as many times
	 * as we are going to call bna_rx_stop
	 */
	list_for_each(qe, &rx_mod->rx_active_q) {
		rx = (struct bna_rx *)qe;
		if (rx->type == type)
			bfa_wc_up(&rx_mod->rx_stop_wc);
	}

	if (rx_mod->rx_stop_wc.wc_count == 0) {
		rx_mod->stop_cbfn(&rx_mod->bna->port, BNA_CB_SUCCESS);
		rx_mod->stop_cbfn = NULL;
		return;
	}

	list_for_each(qe, &rx_mod->rx_active_q) {
		rx = (struct bna_rx *)qe;
		if (rx->type == type)
			bna_rx_stop(rx);
	}
}

void
bna_rx_mod_fail(struct bna_rx_mod *rx_mod)
{
	struct bna_rx *rx;
	struct list_head *qe;

	rx_mod->flags &= ~BNA_RX_MOD_F_PORT_STARTED;
	rx_mod->flags &= ~BNA_RX_MOD_F_PORT_LOOPBACK;

	list_for_each(qe, &rx_mod->rx_active_q) {
		rx = (struct bna_rx *)qe;
		bna_rx_fail(rx);
	}
}

void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna,
			struct bna_res_info *res_info)
{
	int	index;
	struct bna_rx *rx_ptr;
	struct bna_rxp *rxp_ptr;
	struct bna_rxq *rxq_ptr;

	rx_mod->bna = bna;
	rx_mod->flags = 0;

	rx_mod->rx = (struct bna_rx *)
		res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.mdl[0].kva;
	rx_mod->rxp = (struct bna_rxp *)
		res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mdl[0].kva;
	rx_mod->rxq = (struct bna_rxq *)
		res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mdl[0].kva;

	/* Initialize the queues */
	_init_rxmod_queues(rx_mod);

	/* Build RX queues */
	for (index = 0; index < BFI_MAX_RXQ; index++) {
		rx_ptr = &rx_mod->rx[index];
		_rx_ctor(rx_ptr, index);
		list_add_tail(&rx_ptr->qe, &rx_mod->rx_free_q);
		rx_mod->rx_free_count++;
	}

	/* build RX-path queue */
	for (index = 0; index < BFI_MAX_RXQ; index++) {
		rxp_ptr = &rx_mod->rxp[index];
		rxp_ptr->cq.cq_id = index;
		bfa_q_qe_init(&rxp_ptr->qe);
		list_add_tail(&rxp_ptr->qe, &rx_mod->rxp_free_q);
		rx_mod->rxp_free_count++;
	}

	/* build RXQ queue */
	for (index = 0; index < BFI_MAX_RXQ; index++) {
		rxq_ptr = &rx_mod->rxq[index];
		rxq_ptr->rxq_id = index;

		bfa_q_qe_init(&rxq_ptr->qe);
		list_add_tail(&rxq_ptr->qe, &rx_mod->rxq_free_q);
		rx_mod->rxq_free_count++;
	}

	rx_mod->rx_stop_wc.wc_resume = bna_rx_mod_cb_rx_stopped_all;
	rx_mod->rx_stop_wc.wc_cbarg = rx_mod;
	rx_mod->rx_stop_wc.wc_count = 0;
}

void
bna_rx_mod_uninit(struct bna_rx_mod *rx_mod)
{
	struct list_head		*qe;
	int i;

	i = 0;
	list_for_each(qe, &rx_mod->rx_free_q)
		i++;

	i = 0;
	list_for_each(qe, &rx_mod->rxp_free_q)
		i++;

	i = 0;
	list_for_each(qe, &rx_mod->rxq_free_q)
		i++;

	rx_mod->bna = NULL;
}

int
bna_rx_state_get(struct bna_rx *rx)
{
	return bfa_sm_to_state(rx_sm_table, rx->fsm);
}

void
bna_rx_res_req(struct bna_rx_config *q_cfg, struct bna_res_info *res_info)
{
	u32 cq_size, hq_size, dq_size;
	u32 cpage_count, hpage_count, dpage_count;
	struct bna_mem_info *mem_info;
	u32 cq_depth;
	u32 hq_depth;
	u32 dq_depth;

	dq_depth = q_cfg->q_depth;
	hq_depth = ((q_cfg->rxp_type == BNA_RXP_SINGLE) ? 0 : q_cfg->q_depth);
	cq_depth = dq_depth + hq_depth;

	BNA_TO_POWER_OF_2_HIGH(cq_depth);
	cq_size = cq_depth * BFI_CQ_WI_SIZE;
	cq_size = ALIGN(cq_size, PAGE_SIZE);
	cpage_count = SIZE_TO_PAGES(cq_size);

	BNA_TO_POWER_OF_2_HIGH(dq_depth);
	dq_size = dq_depth * BFI_RXQ_WI_SIZE;
	dq_size = ALIGN(dq_size, PAGE_SIZE);
	dpage_count = SIZE_TO_PAGES(dq_size);

	if (BNA_RXP_SINGLE != q_cfg->rxp_type) {
		BNA_TO_POWER_OF_2_HIGH(hq_depth);
		hq_size = hq_depth * BFI_RXQ_WI_SIZE;
		hq_size = ALIGN(hq_size, PAGE_SIZE);
		hpage_count = SIZE_TO_PAGES(hq_size);
	} else {
		hpage_count = 0;
	}

	/* CCB structures */
	res_info[BNA_RX_RES_MEM_T_CCB].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_KVA;
	mem_info->len = sizeof(struct bna_ccb);
	mem_info->num = q_cfg->num_paths;

	/* RCB structures */
	res_info[BNA_RX_RES_MEM_T_RCB].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_KVA;
	mem_info->len = sizeof(struct bna_rcb);
	mem_info->num = BNA_GET_RXQS(q_cfg);

	/* Completion QPT */
	res_info[BNA_RX_RES_MEM_T_CQPT].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_DMA;
	mem_info->len = cpage_count * sizeof(struct bna_dma_addr);
	mem_info->num = q_cfg->num_paths;

	/* Completion s/w QPT */
	res_info[BNA_RX_RES_MEM_T_CSWQPT].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_KVA;
	mem_info->len = cpage_count * sizeof(void *);
	mem_info->num = q_cfg->num_paths;

	/* Completion QPT pages */
	res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_DMA;
	mem_info->len = PAGE_SIZE;
	mem_info->num = cpage_count * q_cfg->num_paths;

	/* Data QPTs */
	res_info[BNA_RX_RES_MEM_T_DQPT].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_DMA;
	mem_info->len = dpage_count * sizeof(struct bna_dma_addr);
	mem_info->num = q_cfg->num_paths;

	/* Data s/w QPTs */
	res_info[BNA_RX_RES_MEM_T_DSWQPT].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_KVA;
	mem_info->len = dpage_count * sizeof(void *);
	mem_info->num = q_cfg->num_paths;

	/* Data QPT pages */
	res_info[BNA_RX_RES_MEM_T_DPAGE].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_DMA;
	mem_info->len = PAGE_SIZE;
	mem_info->num = dpage_count * q_cfg->num_paths;

	/* Hdr QPTs */
	res_info[BNA_RX_RES_MEM_T_HQPT].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_DMA;
	mem_info->len = hpage_count * sizeof(struct bna_dma_addr);
	mem_info->num = (hpage_count ? q_cfg->num_paths : 0);

	/* Hdr s/w QPTs */
	res_info[BNA_RX_RES_MEM_T_HSWQPT].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_KVA;
	mem_info->len = hpage_count * sizeof(void *);
	mem_info->num = (hpage_count ? q_cfg->num_paths : 0);

	/* Hdr QPT pages */
	res_info[BNA_RX_RES_MEM_T_HPAGE].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_DMA;
	mem_info->len = (hpage_count ? PAGE_SIZE : 0);
	mem_info->num = (hpage_count ? (hpage_count * q_cfg->num_paths) : 0);

	/* RX Interrupts */
	res_info[BNA_RX_RES_T_INTR].res_type = BNA_RES_T_INTR;
	res_info[BNA_RX_RES_T_INTR].res_u.intr_info.intr_type = BNA_INTR_T_MSIX;
	res_info[BNA_RX_RES_T_INTR].res_u.intr_info.num = q_cfg->num_paths;
}

struct bna_rx *
bna_rx_create(struct bna *bna, struct bnad *bnad,
		struct bna_rx_config *rx_cfg,
		struct bna_rx_event_cbfn *rx_cbfn,
		struct bna_res_info *res_info,
		void *priv)
{
	struct bna_rx_mod *rx_mod = &bna->rx_mod;
	struct bna_rx *rx;
	struct bna_rxp *rxp;
	struct bna_rxq *q0;
	struct bna_rxq *q1;
	struct bna_intr_info *intr_info;
	u32 page_count;
	struct bna_mem_descr *ccb_mem;
	struct bna_mem_descr *rcb_mem;
	struct bna_mem_descr *unmapq_mem;
	struct bna_mem_descr *cqpt_mem;
	struct bna_mem_descr *cswqpt_mem;
	struct bna_mem_descr *cpage_mem;
	struct bna_mem_descr *hqpt_mem;	/* Header/Small Q qpt */
	struct bna_mem_descr *dqpt_mem;	/* Data/Large Q qpt */
	struct bna_mem_descr *hsqpt_mem;	/* s/w qpt for hdr */
	struct bna_mem_descr *dsqpt_mem;	/* s/w qpt for data */
	struct bna_mem_descr *hpage_mem;	/* hdr page mem */
	struct bna_mem_descr *dpage_mem;	/* data page mem */
	int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0, ret;
	int dpage_count, hpage_count, rcb_idx;
	struct bna_ib_config ibcfg;
	/* Fail if we don't have enough RXPs, RXQs */
	if (!_rx_can_satisfy(rx_mod, rx_cfg))
		return NULL;

	/* Initialize resource pointers */
	intr_info = &res_info[BNA_RX_RES_T_INTR].res_u.intr_info;
	ccb_mem = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info.mdl[0];
	rcb_mem = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info.mdl[0];
	unmapq_mem = &res_info[BNA_RX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[0];
	cqpt_mem = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info.mdl[0];
	cswqpt_mem = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info.mdl[0];
	cpage_mem = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.mdl[0];
	hqpt_mem = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info.mdl[0];
	dqpt_mem = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info.mdl[0];
	hsqpt_mem = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info.mdl[0];
	dsqpt_mem = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info.mdl[0];
	hpage_mem = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.mdl[0];
	dpage_mem = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.mdl[0];

	/* Compute q depth & page count */
	page_count = res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.num /
			rx_cfg->num_paths;

	dpage_count = res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.num /
			rx_cfg->num_paths;

	hpage_count = res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.num /
			rx_cfg->num_paths;
	/* Get RX pointer */
	rx = _get_free_rx(rx_mod);
	_rx_init(rx, bna);
	rx->priv = priv;
	rx->type = rx_cfg->rx_type;

	rx->rcb_setup_cbfn = rx_cbfn->rcb_setup_cbfn;
	rx->rcb_destroy_cbfn = rx_cbfn->rcb_destroy_cbfn;
	rx->ccb_setup_cbfn = rx_cbfn->ccb_setup_cbfn;
	rx->ccb_destroy_cbfn = rx_cbfn->ccb_destroy_cbfn;
	/* Following callbacks are mandatory */
	rx->rx_cleanup_cbfn = rx_cbfn->rx_cleanup_cbfn;
	rx->rx_post_cbfn = rx_cbfn->rx_post_cbfn;

	if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_PORT_STARTED) {
		switch (rx->type) {
		case BNA_RX_T_REGULAR:
			if (!(rx->bna->rx_mod.flags &
				BNA_RX_MOD_F_PORT_LOOPBACK))
				rx->rx_flags |= BNA_RX_F_PORT_ENABLED;
			break;
		case BNA_RX_T_LOOPBACK:
			if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_PORT_LOOPBACK)
				rx->rx_flags |= BNA_RX_F_PORT_ENABLED;
			break;
		}
	}

	for (i = 0, rcb_idx = 0; i < rx_cfg->num_paths; i++) {
		rxp = _get_free_rxp(rx_mod);
		rxp->type = rx_cfg->rxp_type;
		rxp->rx = rx;
		rxp->cq.rx = rx;

		/* Get required RXQs, and queue them to rx-path */
		q0 = _get_free_rxq(rx_mod);
		if (BNA_RXP_SINGLE == rx_cfg->rxp_type)
			q1 = NULL;
		else
			q1 = _get_free_rxq(rx_mod);

		/* Initialize IB */
		if (1 == intr_info->num) {
			rxp->cq.ib = bna_ib_get(&bna->ib_mod,
					intr_info->intr_type,
					intr_info->idl[0].vector);
			rxp->vector = intr_info->idl[0].vector;
		} else {
			rxp->cq.ib = bna_ib_get(&bna->ib_mod,
					intr_info->intr_type,
					intr_info->idl[i].vector);

			/* Map the MSI-x vector used for this RXP */
			rxp->vector = intr_info->idl[i].vector;
		}

		rxp->cq.ib_seg_offset = bna_ib_reserve_idx(rxp->cq.ib);

		ibcfg.coalescing_timeo = BFI_RX_COALESCING_TIMEO;
		ibcfg.interpkt_count = BFI_RX_INTERPKT_COUNT;
		ibcfg.interpkt_timeo = BFI_RX_INTERPKT_TIMEO;
		ibcfg.ctrl_flags = BFI_IB_CF_INT_ENABLE;

		ret = bna_ib_config(rxp->cq.ib, &ibcfg);

		/* Link rxqs to rxp */
		_rxp_add_rxqs(rxp, q0, q1);

		/* Link rxp to rx */
		_rx_add_rxp(rx, rxp);

		q0->rx = rx;
		q0->rxp = rxp;

		/* Initialize RCB for the large / data q */
		q0->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva;
		RXQ_RCB_INIT(q0, rxp, rx_cfg->q_depth, bna, 0,
			(void *)unmapq_mem[rcb_idx].kva);
		rcb_idx++;
		(q0)->rx_packets = (q0)->rx_bytes = 0;
		(q0)->rx_packets_with_error = (q0)->rxbuf_alloc_failed = 0;

		/* Initialize RXQs */
		_rxq_qpt_init(q0, rxp, dpage_count, PAGE_SIZE,
			&dqpt_mem[i], &dsqpt_mem[i], &dpage_mem[dpage_idx]);
		q0->rcb->page_idx = dpage_idx;
		q0->rcb->page_count = dpage_count;
		dpage_idx += dpage_count;

		/* Call bnad to complete rcb setup */
		if (rx->rcb_setup_cbfn)
			rx->rcb_setup_cbfn(bnad, q0->rcb);

		if (q1) {
			q1->rx = rx;
			q1->rxp = rxp;

			q1->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva;
			RXQ_RCB_INIT(q1, rxp, rx_cfg->q_depth, bna, 1,
				(void *)unmapq_mem[rcb_idx].kva);
			rcb_idx++;
			(q1)->buffer_size = (rx_cfg)->small_buff_size;
			(q1)->rx_packets = (q1)->rx_bytes = 0;
			(q1)->rx_packets_with_error =
				(q1)->rxbuf_alloc_failed = 0;

			_rxq_qpt_init(q1, rxp, hpage_count, PAGE_SIZE,
				&hqpt_mem[i], &hsqpt_mem[i],
				&hpage_mem[hpage_idx]);
			q1->rcb->page_idx = hpage_idx;
			q1->rcb->page_count = hpage_count;
			hpage_idx += hpage_count;

			/* Call bnad to complete rcb setup */
			if (rx->rcb_setup_cbfn)
				rx->rcb_setup_cbfn(bnad, q1->rcb);
		}
		/* Setup RXP::CQ */
		rxp->cq.ccb = (struct bna_ccb *) ccb_mem[i].kva;
		_rxp_cqpt_setup(rxp, page_count, PAGE_SIZE,
			&cqpt_mem[i], &cswqpt_mem[i], &cpage_mem[cpage_idx]);
		rxp->cq.ccb->page_idx = cpage_idx;
		rxp->cq.ccb->page_count = page_count;
		cpage_idx += page_count;

		rxp->cq.ccb->pkt_rate.small_pkt_cnt = 0;
		rxp->cq.ccb->pkt_rate.large_pkt_cnt = 0;

		rxp->cq.ccb->producer_index = 0;
		rxp->cq.ccb->q_depth =	rx_cfg->q_depth +
					((rx_cfg->rxp_type == BNA_RXP_SINGLE) ?
					0 : rx_cfg->q_depth);
		rxp->cq.ccb->i_dbell = &rxp->cq.ib->door_bell;
		rxp->cq.ccb->rcb[0] = q0->rcb;
		if (q1)
			rxp->cq.ccb->rcb[1] = q1->rcb;
		rxp->cq.ccb->cq = &rxp->cq;
		rxp->cq.ccb->bnad = bna->bnad;
		rxp->cq.ccb->hw_producer_index =
			((volatile u32 *)rxp->cq.ib->ib_seg_host_addr_kva +
				      (rxp->cq.ib_seg_offset * BFI_IBIDX_SIZE));
		*(rxp->cq.ccb->hw_producer_index) = 0;
		rxp->cq.ccb->intr_type = intr_info->intr_type;
		rxp->cq.ccb->intr_vector = (intr_info->num == 1) ?
						intr_info->idl[0].vector :
						intr_info->idl[i].vector;
		rxp->cq.ccb->rx_coalescing_timeo =
					rxp->cq.ib->ib_config.coalescing_timeo;
		rxp->cq.ccb->id = i;

		/* Call bnad to complete CCB setup */
		if (rx->ccb_setup_cbfn)
			rx->ccb_setup_cbfn(bnad, rxp->cq.ccb);

	} /* for each rx-path */

	bna_rxf_init(&rx->rxf, rx, rx_cfg);

	bfa_fsm_set_state(rx, bna_rx_sm_stopped);

	return rx;
}

void
bna_rx_destroy(struct bna_rx *rx)
{
	struct bna_rx_mod *rx_mod = &rx->bna->rx_mod;
	struct bna_ib_mod *ib_mod = &rx->bna->ib_mod;
	struct bna_rxq *q0 = NULL;
	struct bna_rxq *q1 = NULL;
	struct bna_rxp *rxp;
	struct list_head *qe;

	bna_rxf_uninit(&rx->rxf);

	while (!list_empty(&rx->rxp_q)) {
		bfa_q_deq(&rx->rxp_q, &rxp);
		GET_RXQS(rxp, q0, q1);
		/* Callback to bnad for destroying RCB */
		if (rx->rcb_destroy_cbfn)
			rx->rcb_destroy_cbfn(rx->bna->bnad, q0->rcb);
		q0->rcb = NULL;
		q0->rxp = NULL;
		q0->rx = NULL;
		_put_free_rxq(rx_mod, q0);
		if (q1) {
			/* Callback to bnad for destroying RCB */
			if (rx->rcb_destroy_cbfn)
				rx->rcb_destroy_cbfn(rx->bna->bnad, q1->rcb);
			q1->rcb = NULL;
			q1->rxp = NULL;
			q1->rx = NULL;
			_put_free_rxq(rx_mod, q1);
		}
		rxp->rxq.slr.large = NULL;
		rxp->rxq.slr.small = NULL;
		if (rxp->cq.ib) {
			if (rxp->cq.ib_seg_offset != 0xff)
				bna_ib_release_idx(rxp->cq.ib,
						rxp->cq.ib_seg_offset);
			bna_ib_put(ib_mod, rxp->cq.ib);
			rxp->cq.ib = NULL;
		}
		/* Callback to bnad for destroying CCB */
		if (rx->ccb_destroy_cbfn)
			rx->ccb_destroy_cbfn(rx->bna->bnad, rxp->cq.ccb);
		rxp->cq.ccb = NULL;
		rxp->rx = NULL;
		_put_free_rxp(rx_mod, rxp);
	}

	list_for_each(qe, &rx_mod->rx_active_q) {
		if (qe == &rx->qe) {
			list_del(&rx->qe);
			bfa_q_qe_init(&rx->qe);
			break;
		}
	}

	rx->bna = NULL;
	rx->priv = NULL;
	_put_free_rx(rx_mod, rx);
}

void
bna_rx_enable(struct bna_rx *rx)
{
	if (rx->fsm != (bfa_sm_t)bna_rx_sm_stopped)
		return;

	rx->rx_flags |= BNA_RX_F_ENABLE;
	if (rx->rx_flags & BNA_RX_F_PORT_ENABLED)
		bfa_fsm_send_event(rx, RX_E_START);
}

void
bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type,
		void (*cbfn)(void *, struct bna_rx *,
				enum bna_cb_status))
{
	if (type == BNA_SOFT_CLEANUP) {
		/* h/w should not be accessed. Treat we're stopped */
		(*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS);
	} else {
		rx->stop_cbfn = cbfn;
		rx->stop_cbarg = rx->bna->bnad;

		rx->rx_flags &= ~BNA_RX_F_ENABLE;

		bfa_fsm_send_event(rx, RX_E_STOP);
	}
}

/**
 * TX
 */
#define call_tx_stop_cbfn(tx, status)\
do {\
	if ((tx)->stop_cbfn)\
		(tx)->stop_cbfn((tx)->stop_cbarg, (tx), status);\
	(tx)->stop_cbfn = NULL;\
	(tx)->stop_cbarg = NULL;\
} while (0)

#define call_tx_prio_change_cbfn(tx, status)\
do {\
	if ((tx)->prio_change_cbfn)\
		(tx)->prio_change_cbfn((tx)->bna->bnad, (tx), status);\
	(tx)->prio_change_cbfn = NULL;\
} while (0)

static void bna_tx_mod_cb_tx_stopped(void *tx_mod, struct bna_tx *tx,
					enum bna_cb_status status);
static void bna_tx_cb_txq_stopped(void *arg, int status);
static void bna_tx_cb_stats_cleared(void *arg, int status);
static void __bna_tx_stop(struct bna_tx *tx);
static void __bna_tx_start(struct bna_tx *tx);
static void __bna_txf_stat_clr(struct bna_tx *tx);

enum bna_tx_event {
	TX_E_START			= 1,
	TX_E_STOP			= 2,
	TX_E_FAIL			= 3,
	TX_E_TXQ_STOPPED		= 4,
	TX_E_PRIO_CHANGE		= 5,
	TX_E_STAT_CLEARED		= 6,
};

enum bna_tx_state {
	BNA_TX_STOPPED			= 1,
	BNA_TX_STARTED			= 2,
	BNA_TX_TXQ_STOP_WAIT		= 3,
	BNA_TX_PRIO_STOP_WAIT		= 4,
	BNA_TX_STAT_CLR_WAIT		= 5,
};

bfa_fsm_state_decl(bna_tx, stopped, struct bna_tx,
			enum bna_tx_event);
bfa_fsm_state_decl(bna_tx, started, struct bna_tx,
			enum bna_tx_event);
bfa_fsm_state_decl(bna_tx, txq_stop_wait, struct bna_tx,
			enum bna_tx_event);
bfa_fsm_state_decl(bna_tx, prio_stop_wait, struct bna_tx,
			enum bna_tx_event);
bfa_fsm_state_decl(bna_tx, stat_clr_wait, struct bna_tx,
			enum bna_tx_event);

static struct bfa_sm_table tx_sm_table[] = {
	{BFA_SM(bna_tx_sm_stopped), BNA_TX_STOPPED},
	{BFA_SM(bna_tx_sm_started), BNA_TX_STARTED},
	{BFA_SM(bna_tx_sm_txq_stop_wait), BNA_TX_TXQ_STOP_WAIT},
	{BFA_SM(bna_tx_sm_prio_stop_wait), BNA_TX_PRIO_STOP_WAIT},
	{BFA_SM(bna_tx_sm_stat_clr_wait), BNA_TX_STAT_CLR_WAIT},
};

static void
bna_tx_sm_stopped_entry(struct bna_tx *tx)
{
	struct bna_txq *txq;
	struct list_head		 *qe;

	list_for_each(qe, &tx->txq_q) {
		txq = (struct bna_txq *)qe;
		(tx->tx_cleanup_cbfn)(tx->bna->bnad, txq->tcb);
	}

	call_tx_stop_cbfn(tx, BNA_CB_SUCCESS);
}

static void
bna_tx_sm_stopped(struct bna_tx *tx, enum bna_tx_event event)
{
	switch (event) {
	case TX_E_START:
		bfa_fsm_set_state(tx, bna_tx_sm_started);
		break;

	case TX_E_STOP:
		bfa_fsm_set_state(tx, bna_tx_sm_stopped);
		break;

	case TX_E_FAIL:
		/* No-op */
		break;

	case TX_E_PRIO_CHANGE:
		call_tx_prio_change_cbfn(tx, BNA_CB_SUCCESS);
		break;

	case TX_E_TXQ_STOPPED:
		/**
		 * This event is received due to flushing of mbox when
		 * device fails
		 */
		/* No-op */
		break;

	default:
		bfa_sm_fault(tx->bna, event);
	}
}

static void
bna_tx_sm_started_entry(struct bna_tx *tx)
{
	struct bna_txq *txq;
	struct list_head		 *qe;

	__bna_tx_start(tx);

	/* Start IB */
	list_for_each(qe, &tx->txq_q) {
		txq = (struct bna_txq *)qe;
		bna_ib_ack(&txq->ib->door_bell, 0);
	}
}

static void
bna_tx_sm_started(struct bna_tx *tx, enum bna_tx_event event)
{
	struct bna_txq *txq;
	struct list_head		 *qe;

	switch (event) {
	case TX_E_STOP:
		bfa_fsm_set_state(tx, bna_tx_sm_txq_stop_wait);
		__bna_tx_stop(tx);
		break;

	case TX_E_FAIL:
		list_for_each(qe, &tx->txq_q) {
			txq = (struct bna_txq *)qe;
			bna_ib_fail(txq->ib);
			(tx->tx_stall_cbfn)(tx->bna->bnad, txq->tcb);
		}
		bfa_fsm_set_state(tx, bna_tx_sm_stopped);
		break;

	case TX_E_PRIO_CHANGE:
		bfa_fsm_set_state(tx, bna_tx_sm_prio_stop_wait);
		break;

	default:
		bfa_sm_fault(tx->bna, event);
	}
}

static void
bna_tx_sm_txq_stop_wait_entry(struct bna_tx *tx)
{
}

static void
bna_tx_sm_txq_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
{
	struct bna_txq *txq;
	struct list_head		 *qe;

	switch (event) {
	case TX_E_FAIL:
		bfa_fsm_set_state(tx, bna_tx_sm_stopped);
		break;

	case TX_E_TXQ_STOPPED:
		list_for_each(qe, &tx->txq_q) {
			txq = (struct bna_txq *)qe;
			bna_ib_stop(txq->ib);
		}
		bfa_fsm_set_state(tx, bna_tx_sm_stat_clr_wait);
		break;

	case TX_E_PRIO_CHANGE:
		/* No-op */
		break;

	default:
		bfa_sm_fault(tx->bna, event);
	}
}

static void
bna_tx_sm_prio_stop_wait_entry(struct bna_tx *tx)
{
	__bna_tx_stop(tx);
}

static void
bna_tx_sm_prio_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
{
	struct bna_txq *txq;
	struct list_head		 *qe;

	switch (event) {
	case TX_E_STOP:
		bfa_fsm_set_state(tx, bna_tx_sm_txq_stop_wait);
		break;

	case TX_E_FAIL:
		call_tx_prio_change_cbfn(tx, BNA_CB_FAIL);
		bfa_fsm_set_state(tx, bna_tx_sm_stopped);
		break;

	case TX_E_TXQ_STOPPED:
		list_for_each(qe, &tx->txq_q) {
			txq = (struct bna_txq *)qe;
			bna_ib_stop(txq->ib);
			(tx->tx_cleanup_cbfn)(tx->bna->bnad, txq->tcb);
		}
		call_tx_prio_change_cbfn(tx, BNA_CB_SUCCESS);
		bfa_fsm_set_state(tx, bna_tx_sm_started);
		break;

	case TX_E_PRIO_CHANGE:
		/* No-op */
		break;

	default:
		bfa_sm_fault(tx->bna, event);
	}
}

static void
bna_tx_sm_stat_clr_wait_entry(struct bna_tx *tx)
{
	__bna_txf_stat_clr(tx);
}

static void
bna_tx_sm_stat_clr_wait(struct bna_tx *tx, enum bna_tx_event event)
{
	switch (event) {
	case TX_E_FAIL:
	case TX_E_STAT_CLEARED:
		bfa_fsm_set_state(tx, bna_tx_sm_stopped);
		break;

	default:
		bfa_sm_fault(tx->bna, event);
	}
}

static void
__bna_txq_start(struct bna_tx *tx, struct bna_txq *txq)
{
	struct bna_rxtx_q_mem *q_mem;
	struct bna_txq_mem txq_cfg;
	struct bna_txq_mem *txq_mem;
	struct bna_dma_addr cur_q_addr;
	u32 pg_num;
	void __iomem *base_addr;
	unsigned long off;

	/* Fill out structure, to be subsequently written to hardware */
	txq_cfg.pg_tbl_addr_lo = txq->qpt.hw_qpt_ptr.lsb;
	txq_cfg.pg_tbl_addr_hi = txq->qpt.hw_qpt_ptr.msb;
	cur_q_addr = *((struct bna_dma_addr *)(txq->qpt.kv_qpt_ptr));
	txq_cfg.cur_q_entry_lo = cur_q_addr.lsb;
	txq_cfg.cur_q_entry_hi = cur_q_addr.msb;

	txq_cfg.pg_cnt_n_prd_ptr = (txq->qpt.page_count << 16) | 0x0;

	txq_cfg.entry_n_pg_size = ((u32)(BFI_TXQ_WI_SIZE >> 2) << 16) |
			(txq->qpt.page_size >> 2);
	txq_cfg.int_blk_n_cns_ptr = ((((u32)txq->ib_seg_offset) << 24) |
			((u32)(txq->ib->ib_id & 0xff) << 16) | 0x0);

	txq_cfg.cns_ptr2_n_q_state = BNA_Q_IDLE_STATE;
	txq_cfg.nxt_qid_n_fid_n_pri = (((tx->txf.txf_id & 0x3f) << 3) |
			(txq->priority & 0x3));
	txq_cfg.wvc_n_cquota_n_rquota =
			((((u32)BFI_TX_MAX_WRR_QUOTA & 0xfff) << 12) |
			(BFI_TX_MAX_WRR_QUOTA & 0xfff));

	/* Setup the page and write to H/W */

	pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + tx->bna->port_num,
			HQM_RXTX_Q_RAM_BASE_OFFSET);
	writel(pg_num, tx->bna->regs.page_addr);

	base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva,
					HQM_RXTX_Q_RAM_BASE_OFFSET);
	q_mem = (struct bna_rxtx_q_mem *)0;
	txq_mem = &q_mem[txq->txq_id].txq;

	/*
	 * The following 4 lines, is a hack b'cos the H/W needs to read
	 * these DMA addresses as little endian
	 */

	off = (unsigned long)&txq_mem->pg_tbl_addr_lo;
	writel(htonl(txq_cfg.pg_tbl_addr_lo), base_addr + off);

	off = (unsigned long)&txq_mem->pg_tbl_addr_hi;
	writel(htonl(txq_cfg.pg_tbl_addr_hi), base_addr + off);

	off = (unsigned long)&txq_mem->cur_q_entry_lo;
	writel(htonl(txq_cfg.cur_q_entry_lo), base_addr + off);

	off = (unsigned long)&txq_mem->cur_q_entry_hi;
	writel(htonl(txq_cfg.cur_q_entry_hi), base_addr + off);

	off = (unsigned long)&txq_mem->pg_cnt_n_prd_ptr;
	writel(txq_cfg.pg_cnt_n_prd_ptr, base_addr + off);

	off = (unsigned long)&txq_mem->entry_n_pg_size;
	writel(txq_cfg.entry_n_pg_size, base_addr + off);

	off = (unsigned long)&txq_mem->int_blk_n_cns_ptr;
	writel(txq_cfg.int_blk_n_cns_ptr, base_addr + off);

	off = (unsigned long)&txq_mem->cns_ptr2_n_q_state;
	writel(txq_cfg.cns_ptr2_n_q_state, base_addr + off);

	off = (unsigned long)&txq_mem->nxt_qid_n_fid_n_pri;
	writel(txq_cfg.nxt_qid_n_fid_n_pri, base_addr + off);

	off = (unsigned long)&txq_mem->wvc_n_cquota_n_rquota;
	writel(txq_cfg.wvc_n_cquota_n_rquota, base_addr + off);

	txq->tcb->producer_index = 0;
	txq->tcb->consumer_index = 0;
	*(txq->tcb->hw_consumer_index) = 0;

}

static void
__bna_txq_stop(struct bna_tx *tx, struct bna_txq *txq)
{
	struct bfi_ll_q_stop_req ll_req;
	u32 bit_mask[2] = {0, 0};
	if (txq->txq_id < 32)
		bit_mask[0] = (u32)1 << txq->txq_id;
	else
		bit_mask[1] = (u32)1 << (txq->txq_id - 32);

	memset(&ll_req, 0, sizeof(ll_req));
	ll_req.mh.msg_class = BFI_MC_LL;
	ll_req.mh.msg_id = BFI_LL_H2I_TXQ_STOP_REQ;
	ll_req.mh.mtag.h2i.lpu_id = 0;
	ll_req.q_id_mask[0] = htonl(bit_mask[0]);
	ll_req.q_id_mask[1] = htonl(bit_mask[1]);

	bna_mbox_qe_fill(&tx->mbox_qe, &ll_req, sizeof(ll_req),
			bna_tx_cb_txq_stopped, tx);

	bna_mbox_send(tx->bna, &tx->mbox_qe);
}

static void
__bna_txf_start(struct bna_tx *tx)
{
	struct bna_tx_fndb_ram *tx_fndb;
	struct bna_txf *txf = &tx->txf;
	void __iomem *base_addr;
	unsigned long off;

	writel(BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM +
			(tx->bna->port_num * 2), TX_FNDB_RAM_BASE_OFFSET),
			tx->bna->regs.page_addr);

	base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva,
					TX_FNDB_RAM_BASE_OFFSET);

	tx_fndb = (struct bna_tx_fndb_ram *)0;
	off = (unsigned long)&tx_fndb[txf->txf_id].vlan_n_ctrl_flags;

	writel(((u32)txf->vlan << 16) | txf->ctrl_flags,
			base_addr + off);

	if (tx->txf.txf_id < 32)
		tx->bna->tx_mod.txf_bmap[0] |= ((u32)1 << tx->txf.txf_id);
	else
		tx->bna->tx_mod.txf_bmap[1] |= ((u32)
						 1 << (tx->txf.txf_id - 32));
}

static void
__bna_txf_stop(struct bna_tx *tx)
{
	struct bna_tx_fndb_ram *tx_fndb;
	u32 page_num;
	u32 ctl_flags;
	struct bna_txf *txf = &tx->txf;
	void __iomem *base_addr;
	unsigned long off;

	/* retrieve the running txf_flags & turn off enable bit */
	page_num = BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM +
			(tx->bna->port_num * 2), TX_FNDB_RAM_BASE_OFFSET);
	writel(page_num, tx->bna->regs.page_addr);

	base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva,
					TX_FNDB_RAM_BASE_OFFSET);
	tx_fndb = (struct bna_tx_fndb_ram *)0;
	off = (unsigned long)&tx_fndb[txf->txf_id].vlan_n_ctrl_flags;

	ctl_flags = readl(base_addr + off);
	ctl_flags &= ~BFI_TXF_CF_ENABLE;

	writel(ctl_flags, base_addr + off);

	if (tx->txf.txf_id < 32)
		tx->bna->tx_mod.txf_bmap[0] &= ~((u32)1 << tx->txf.txf_id);
	else
		tx->bna->tx_mod.txf_bmap[0] &= ~((u32)
						 1 << (tx->txf.txf_id - 32));
}

static void
__bna_txf_stat_clr(struct bna_tx *tx)
{
	struct bfi_ll_stats_req ll_req;
	u32 txf_bmap[2] = {0, 0};
	if (tx->txf.txf_id < 32)
		txf_bmap[0] = ((u32)1 << tx->txf.txf_id);
	else
		txf_bmap[1] = ((u32)1 << (tx->txf.txf_id - 32));
	bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0);
	ll_req.stats_mask = 0;
	ll_req.rxf_id_mask[0] = 0;
	ll_req.rxf_id_mask[1] =	0;
	ll_req.txf_id_mask[0] =	htonl(txf_bmap[0]);
	ll_req.txf_id_mask[1] =	htonl(txf_bmap[1]);

	bna_mbox_qe_fill(&tx->mbox_qe, &ll_req, sizeof(ll_req),
			bna_tx_cb_stats_cleared, tx);
	bna_mbox_send(tx->bna, &tx->mbox_qe);
}

static void
__bna_tx_start(struct bna_tx *tx)
{
	struct bna_txq *txq;
	struct list_head		 *qe;

	list_for_each(qe, &tx->txq_q) {
		txq = (struct bna_txq *)qe;
		bna_ib_start(txq->ib);
		__bna_txq_start(tx, txq);
	}

	__bna_txf_start(tx);

	list_for_each(qe, &tx->txq_q) {
		txq = (struct bna_txq *)qe;
		txq->tcb->priority = txq->priority;
		(tx->tx_resume_cbfn)(tx->bna->bnad, txq->tcb);
	}
}

static void
__bna_tx_stop(struct bna_tx *tx)
{
	struct bna_txq *txq;
	struct list_head		 *qe;

	list_for_each(qe, &tx->txq_q) {
		txq = (struct bna_txq *)qe;
		(tx->tx_stall_cbfn)(tx->bna->bnad, txq->tcb);
	}

	__bna_txf_stop(tx);

	list_for_each(qe, &tx->txq_q) {
		txq = (struct bna_txq *)qe;
		bfa_wc_up(&tx->txq_stop_wc);
	}

	list_for_each(qe, &tx->txq_q) {
		txq = (struct bna_txq *)qe;
		__bna_txq_stop(tx, txq);
	}
}

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)
{
	int i;

	txq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb;
	txq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb;
	txq->qpt.kv_qpt_ptr = qpt_mem->kva;
	txq->qpt.page_count = page_count;
	txq->qpt.page_size = page_size;

	txq->tcb->sw_qpt = (void **) swqpt_mem->kva;

	for (i = 0; i < page_count; i++) {
		txq->tcb->sw_qpt[i] = page_mem[i].kva;

		((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].lsb =
			page_mem[i].dma.lsb;
		((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].msb =
			page_mem[i].dma.msb;

	}
}

static void
bna_tx_free(struct bna_tx *tx)
{
	struct bna_tx_mod *tx_mod = &tx->bna->tx_mod;
	struct bna_txq *txq;
	struct bna_ib_mod *ib_mod = &tx->bna->ib_mod;
	struct list_head *qe;

	while (!list_empty(&tx->txq_q)) {
		bfa_q_deq(&tx->txq_q, &txq);
		bfa_q_qe_init(&txq->qe);
		if (txq->ib) {
			if (txq->ib_seg_offset != -1)
				bna_ib_release_idx(txq->ib,
						txq->ib_seg_offset);
			bna_ib_put(ib_mod, txq->ib);
			txq->ib = NULL;
		}
		txq->tcb = NULL;
		txq->tx = NULL;
		list_add_tail(&txq->qe, &tx_mod->txq_free_q);
	}

	list_for_each(qe, &tx_mod->tx_active_q) {
		if (qe == &tx->qe) {
			list_del(&tx->qe);
			bfa_q_qe_init(&tx->qe);
			break;
		}
	}

	tx->bna = NULL;
	tx->priv = NULL;
	list_add_tail(&tx->qe, &tx_mod->tx_free_q);
}

static void
bna_tx_cb_txq_stopped(void *arg, int status)
{
	struct bna_tx *tx = (struct bna_tx *)arg;

	bfa_q_qe_init(&tx->mbox_qe.qe);
	bfa_wc_down(&tx->txq_stop_wc);
}

static void
bna_tx_cb_txq_stopped_all(void *arg)
{
	struct bna_tx *tx = (struct bna_tx *)arg;

	bfa_fsm_send_event(tx, TX_E_TXQ_STOPPED);
}

static void
bna_tx_cb_stats_cleared(void *arg, int status)
{
	struct bna_tx *tx = (struct bna_tx *)arg;

	bfa_q_qe_init(&tx->mbox_qe.qe);

	bfa_fsm_send_event(tx, TX_E_STAT_CLEARED);
}

static void
bna_tx_start(struct bna_tx *tx)
{
	tx->flags |= BNA_TX_F_PORT_STARTED;
	if (tx->flags & BNA_TX_F_ENABLED)
		bfa_fsm_send_event(tx, TX_E_START);
}

static void
bna_tx_stop(struct bna_tx *tx)
{
	tx->stop_cbfn = bna_tx_mod_cb_tx_stopped;
	tx->stop_cbarg = &tx->bna->tx_mod;

	tx->flags &= ~BNA_TX_F_PORT_STARTED;
	bfa_fsm_send_event(tx, TX_E_STOP);
}

static void
bna_tx_fail(struct bna_tx *tx)
{
	tx->flags &= ~BNA_TX_F_PORT_STARTED;
	bfa_fsm_send_event(tx, TX_E_FAIL);
}

static void
bna_tx_prio_changed(struct bna_tx *tx, int prio)
{
	struct bna_txq *txq;
	struct list_head		 *qe;

	list_for_each(qe, &tx->txq_q) {
		txq = (struct bna_txq *)qe;
		txq->priority = prio;
	}

	bfa_fsm_send_event(tx, TX_E_PRIO_CHANGE);
}

static void
bna_tx_cee_link_status(struct bna_tx *tx, int cee_link)
{
	if (cee_link)
		tx->flags |= BNA_TX_F_PRIO_LOCK;
	else
		tx->flags &= ~BNA_TX_F_PRIO_LOCK;
}

static void
bna_tx_mod_cb_tx_stopped(void *arg, struct bna_tx *tx,
			enum bna_cb_status status)
{
	struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg;

	bfa_wc_down(&tx_mod->tx_stop_wc);
}

static void
bna_tx_mod_cb_tx_stopped_all(void *arg)
{
	struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg;

	if (tx_mod->stop_cbfn)
		tx_mod->stop_cbfn(&tx_mod->bna->port, BNA_CB_SUCCESS);
	tx_mod->stop_cbfn = NULL;
}

void
bna_tx_res_req(int num_txq, int txq_depth, struct bna_res_info *res_info)
{
	u32 q_size;
	u32 page_count;
	struct bna_mem_info *mem_info;

	res_info[BNA_TX_RES_MEM_T_TCB].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_KVA;
	mem_info->len = sizeof(struct bna_tcb);
	mem_info->num = num_txq;

	q_size = txq_depth * BFI_TXQ_WI_SIZE;
	q_size = ALIGN(q_size, PAGE_SIZE);
	page_count = q_size >> PAGE_SHIFT;

	res_info[BNA_TX_RES_MEM_T_QPT].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_DMA;
	mem_info->len = page_count * sizeof(struct bna_dma_addr);
	mem_info->num = num_txq;

	res_info[BNA_TX_RES_MEM_T_SWQPT].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_KVA;
	mem_info->len = page_count * sizeof(void *);
	mem_info->num = num_txq;

	res_info[BNA_TX_RES_MEM_T_PAGE].res_type = BNA_RES_T_MEM;
	mem_info = &res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info;
	mem_info->mem_type = BNA_MEM_T_DMA;
	mem_info->len = PAGE_SIZE;
	mem_info->num = num_txq * page_count;

	res_info[BNA_TX_RES_INTR_T_TXCMPL].res_type = BNA_RES_T_INTR;
	res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.intr_type =
			BNA_INTR_T_MSIX;
	res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.num = num_txq;
}

struct bna_tx *
bna_tx_create(struct bna *bna, struct bnad *bnad,
		struct bna_tx_config *tx_cfg,
		struct bna_tx_event_cbfn *tx_cbfn,
		struct bna_res_info *res_info, void *priv)
{
	struct bna_intr_info *intr_info;
	struct bna_tx_mod *tx_mod = &bna->tx_mod;
	struct bna_tx *tx;
	struct bna_txq *txq;
	struct list_head *qe;
	struct bna_ib_mod *ib_mod = &bna->ib_mod;
	struct bna_doorbell_qset *qset;
	struct bna_ib_config ib_config;
	int page_count;
	int page_size;
	int page_idx;
	int i;
	unsigned long off;

	intr_info = &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info;
	page_count = (res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.num) /
			tx_cfg->num_txq;
	page_size = res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.len;

	/**
	 * Get resources
	 */

	if ((intr_info->num != 1) && (intr_info->num != tx_cfg->num_txq))
		return NULL;

	/* Tx */

	if (list_empty(&tx_mod->tx_free_q))
		return NULL;
	bfa_q_deq(&tx_mod->tx_free_q, &tx);
	bfa_q_qe_init(&tx->qe);

	/* TxQs */

	INIT_LIST_HEAD(&tx->txq_q);
	for (i = 0; i < tx_cfg->num_txq; i++) {
		if (list_empty(&tx_mod->txq_free_q))
			goto err_return;

		bfa_q_deq(&tx_mod->txq_free_q, &txq);
		bfa_q_qe_init(&txq->qe);
		list_add_tail(&txq->qe, &tx->txq_q);
		txq->ib = NULL;
		txq->ib_seg_offset = -1;
		txq->tx = tx;
	}

	/* IBs */
	i = 0;
	list_for_each(qe, &tx->txq_q) {
		txq = (struct bna_txq *)qe;

		if (intr_info->num == 1)
			txq->ib = bna_ib_get(ib_mod, intr_info->intr_type,
						intr_info->idl[0].vector);
		else
			txq->ib = bna_ib_get(ib_mod, intr_info->intr_type,
						intr_info->idl[i].vector);

		if (txq->ib == NULL)
			goto err_return;

		txq->ib_seg_offset = bna_ib_reserve_idx(txq->ib);
		if (txq->ib_seg_offset == -1)
			goto err_return;

		i++;
	}

	/*
	 * Initialize
	 */

	/* Tx */

	tx->tcb_setup_cbfn = tx_cbfn->tcb_setup_cbfn;
	tx->tcb_destroy_cbfn = tx_cbfn->tcb_destroy_cbfn;
	/* Following callbacks are mandatory */
	tx->tx_stall_cbfn = tx_cbfn->tx_stall_cbfn;
	tx->tx_resume_cbfn = tx_cbfn->tx_resume_cbfn;
	tx->tx_cleanup_cbfn = tx_cbfn->tx_cleanup_cbfn;

	list_add_tail(&tx->qe, &tx_mod->tx_active_q);
	tx->bna = bna;
	tx->priv = priv;
	tx->txq_stop_wc.wc_resume = bna_tx_cb_txq_stopped_all;
	tx->txq_stop_wc.wc_cbarg = tx;
	tx->txq_stop_wc.wc_count = 0;

	tx->type = tx_cfg->tx_type;

	tx->flags = 0;
	if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_PORT_STARTED) {
		switch (tx->type) {
		case BNA_TX_T_REGULAR:
			if (!(tx->bna->tx_mod.flags &
				BNA_TX_MOD_F_PORT_LOOPBACK))
				tx->flags |= BNA_TX_F_PORT_STARTED;
			break;
		case BNA_TX_T_LOOPBACK:
			if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_PORT_LOOPBACK)
				tx->flags |= BNA_TX_F_PORT_STARTED;
			break;
		}
	}
	if (tx->bna->tx_mod.cee_link)
		tx->flags |= BNA_TX_F_PRIO_LOCK;

	/* TxQ */

	i = 0;
	page_idx = 0;
	list_for_each(qe, &tx->txq_q) {
		txq = (struct bna_txq *)qe;
		txq->priority = tx_mod->priority;
		txq->tcb = (struct bna_tcb *)
		  res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info.mdl[i].kva;
		txq->tx_packets = 0;
		txq->tx_bytes = 0;

		/* IB */

		ib_config.coalescing_timeo = BFI_TX_COALESCING_TIMEO;
		ib_config.interpkt_timeo = 0; /* Not used */
		ib_config.interpkt_count = BFI_TX_INTERPKT_COUNT;
		ib_config.ctrl_flags = (BFI_IB_CF_INTER_PKT_DMA |
					BFI_IB_CF_INT_ENABLE |
					BFI_IB_CF_COALESCING_MODE);
		bna_ib_config(txq->ib, &ib_config);

		/* TCB */

		txq->tcb->producer_index = 0;
		txq->tcb->consumer_index = 0;
		txq->tcb->hw_consumer_index = (volatile u32 *)
			((volatile u8 *)txq->ib->ib_seg_host_addr_kva +
			 (txq->ib_seg_offset * BFI_IBIDX_SIZE));
		*(txq->tcb->hw_consumer_index) = 0;
		txq->tcb->q_depth = tx_cfg->txq_depth;
		txq->tcb->unmap_q = (void *)
		res_info[BNA_TX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[i].kva;
		qset = (struct bna_doorbell_qset *)0;
		off = (unsigned long)&qset[txq->txq_id].txq[0];
		txq->tcb->q_dbell = off +
			BNA_GET_DOORBELL_BASE_ADDR(bna->pcidev.pci_bar_kva);
		txq->tcb->i_dbell = &txq->ib->door_bell;
		txq->tcb->intr_type = intr_info->intr_type;
		txq->tcb->intr_vector = (intr_info->num == 1) ?
					intr_info->idl[0].vector :
					intr_info->idl[i].vector;
		txq->tcb->txq = txq;
		txq->tcb->bnad = bnad;
		txq->tcb->id = i;

		/* QPT, SWQPT, Pages */
		bna_txq_qpt_setup(txq, page_count, page_size,
			&res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info.mdl[i],
			&res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info.mdl[i],
			&res_info[BNA_TX_RES_MEM_T_PAGE].
				  res_u.mem_info.mdl[page_idx]);
		txq->tcb->page_idx = page_idx;
		txq->tcb->page_count = page_count;
		page_idx += page_count;

		/* Callback to bnad for setting up TCB */
		if (tx->tcb_setup_cbfn)
			(tx->tcb_setup_cbfn)(bna->bnad, txq->tcb);

		i++;
	}

	/* TxF */

	tx->txf.ctrl_flags = BFI_TXF_CF_ENABLE | BFI_TXF_CF_VLAN_WI_BASED;
	tx->txf.vlan = 0;

	/* Mbox element */
	bfa_q_qe_init(&tx->mbox_qe.qe);

	bfa_fsm_set_state(tx, bna_tx_sm_stopped);

	return tx;

err_return:
	bna_tx_free(tx);
	return NULL;
}

void
bna_tx_destroy(struct bna_tx *tx)
{
	/* Callback to bnad for destroying TCB */
	if (tx->tcb_destroy_cbfn) {
		struct bna_txq *txq;
		struct list_head *qe;

		list_for_each(qe, &tx->txq_q) {
			txq = (struct bna_txq *)qe;
			(tx->tcb_destroy_cbfn)(tx->bna->bnad, txq->tcb);
		}
	}

	bna_tx_free(tx);
}

void
bna_tx_enable(struct bna_tx *tx)
{
	if (tx->fsm != (bfa_sm_t)bna_tx_sm_stopped)
		return;

	tx->flags |= BNA_TX_F_ENABLED;

	if (tx->flags & BNA_TX_F_PORT_STARTED)
		bfa_fsm_send_event(tx, TX_E_START);
}

void
bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type,
		void (*cbfn)(void *, struct bna_tx *, enum bna_cb_status))
{
	if (type == BNA_SOFT_CLEANUP) {
		(*cbfn)(tx->bna->bnad, tx, BNA_CB_SUCCESS);
		return;
	}

	tx->stop_cbfn = cbfn;
	tx->stop_cbarg = tx->bna->bnad;

	tx->flags &= ~BNA_TX_F_ENABLED;

	bfa_fsm_send_event(tx, TX_E_STOP);
}

int
bna_tx_state_get(struct bna_tx *tx)
{
	return bfa_sm_to_state(tx_sm_table, tx->fsm);
}

void
bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna,
		struct bna_res_info *res_info)
{
	int i;

	tx_mod->bna = bna;
	tx_mod->flags = 0;

	tx_mod->tx = (struct bna_tx *)
		res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.mdl[0].kva;
	tx_mod->txq = (struct bna_txq *)
		res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mdl[0].kva;

	INIT_LIST_HEAD(&tx_mod->tx_free_q);
	INIT_LIST_HEAD(&tx_mod->tx_active_q);

	INIT_LIST_HEAD(&tx_mod->txq_free_q);

	for (i = 0; i < BFI_MAX_TXQ; i++) {
		tx_mod->tx[i].txf.txf_id = i;
		bfa_q_qe_init(&tx_mod->tx[i].qe);
		list_add_tail(&tx_mod->tx[i].qe, &tx_mod->tx_free_q);

		tx_mod->txq[i].txq_id = i;
		bfa_q_qe_init(&tx_mod->txq[i].qe);
		list_add_tail(&tx_mod->txq[i].qe, &tx_mod->txq_free_q);
	}

	tx_mod->tx_stop_wc.wc_resume = bna_tx_mod_cb_tx_stopped_all;
	tx_mod->tx_stop_wc.wc_cbarg = tx_mod;
	tx_mod->tx_stop_wc.wc_count = 0;
}

void
bna_tx_mod_uninit(struct bna_tx_mod *tx_mod)
{
	struct list_head		*qe;
	int i;

	i = 0;
	list_for_each(qe, &tx_mod->tx_free_q)
		i++;

	i = 0;
	list_for_each(qe, &tx_mod->txq_free_q)
		i++;

	tx_mod->bna = NULL;
}

void
bna_tx_mod_start(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
{
	struct bna_tx *tx;
	struct list_head		*qe;

	tx_mod->flags |= BNA_TX_MOD_F_PORT_STARTED;
	if (type == BNA_TX_T_LOOPBACK)
		tx_mod->flags |= BNA_TX_MOD_F_PORT_LOOPBACK;

	list_for_each(qe, &tx_mod->tx_active_q) {
		tx = (struct bna_tx *)qe;
		if (tx->type == type)
			bna_tx_start(tx);
	}
}

void
bna_tx_mod_stop(struct bna_tx_mod *tx_mod, enum bna_tx_type type)
{
	struct bna_tx *tx;
	struct list_head		*qe;

	tx_mod->flags &= ~BNA_TX_MOD_F_PORT_STARTED;
	tx_mod->flags &= ~BNA_TX_MOD_F_PORT_LOOPBACK;

	tx_mod->stop_cbfn = bna_port_cb_tx_stopped;

	/**
	 * Before calling bna_tx_stop(), increment tx_stop_wc as many times
	 * as we are going to call bna_tx_stop
	 */
	list_for_each(qe, &tx_mod->tx_active_q) {
		tx = (struct bna_tx *)qe;
		if (tx->type == type)
			bfa_wc_up(&tx_mod->tx_stop_wc);
	}

	if (tx_mod->tx_stop_wc.wc_count == 0) {
		tx_mod->stop_cbfn(&tx_mod->bna->port, BNA_CB_SUCCESS);
		tx_mod->stop_cbfn = NULL;
		return;
	}

	list_for_each(qe, &tx_mod->tx_active_q) {
		tx = (struct bna_tx *)qe;
		if (tx->type == type)
			bna_tx_stop(tx);
	}
}

void
bna_tx_mod_fail(struct bna_tx_mod *tx_mod)
{
	struct bna_tx *tx;
	struct list_head		*qe;

	tx_mod->flags &= ~BNA_TX_MOD_F_PORT_STARTED;
	tx_mod->flags &= ~BNA_TX_MOD_F_PORT_LOOPBACK;

	list_for_each(qe, &tx_mod->tx_active_q) {
		tx = (struct bna_tx *)qe;
		bna_tx_fail(tx);
	}
}

void
bna_tx_mod_prio_changed(struct bna_tx_mod *tx_mod, int prio)
{
	struct bna_tx *tx;
	struct list_head		*qe;

	if (prio != tx_mod->priority) {
		tx_mod->priority = prio;

		list_for_each(qe, &tx_mod->tx_active_q) {
			tx = (struct bna_tx *)qe;
			bna_tx_prio_changed(tx, prio);
		}
	}
}

void
bna_tx_mod_cee_link_status(struct bna_tx_mod *tx_mod, int cee_link)
{
	struct bna_tx *tx;
	struct list_head		*qe;

	tx_mod->cee_link = cee_link;

	list_for_each(qe, &tx_mod->tx_active_q) {
		tx = (struct bna_tx *)qe;
		bna_tx_cee_link_status(tx, cee_link);
	}
}
