/*
 * Copyright (C) 2003 - 2008 NetXen, Inc.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA  02111-1307, USA.
 *
 * The full GNU General Public License is included in this distribution
 * in the file called LICENSE.
 *
 * Contact Information:
 *    info@netxen.com
 * NetXen,
 * 3965 Freedom Circle, Fourth floor,
 * Santa Clara, CA 95054
 *
 */

#include "netxen_nic_hw.h"
#include "netxen_nic.h"
#include "netxen_nic_phan_reg.h"

#define NXHAL_VERSION	1

static int
netxen_api_lock(struct netxen_adapter *adapter)
{
	u32 done = 0, timeout = 0;

	for (;;) {
		/* Acquire PCIE HW semaphore5 */
		netxen_nic_read_w0(adapter,
			NETXEN_PCIE_REG(PCIE_SEM5_LOCK), &done);

		if (done == 1)
			break;

		if (++timeout >= NX_OS_CRB_RETRY_COUNT) {
			printk(KERN_ERR "%s: lock timeout.\n", __func__);
			return -1;
		}

		msleep(1);
	}

#if 0
	netxen_nic_write_w1(adapter,
		NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER);
#endif
	return 0;
}

static int
netxen_api_unlock(struct netxen_adapter *adapter)
{
	u32 val;

	/* Release PCIE HW semaphore5 */
	netxen_nic_read_w0(adapter,
		NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK), &val);
	return 0;
}

static u32
netxen_poll_rsp(struct netxen_adapter *adapter)
{
	u32 raw_rsp, rsp = NX_CDRP_RSP_OK;
	int	timeout = 0;

	do {
		/* give atleast 1ms for firmware to respond */
		msleep(1);

		if (++timeout > NX_OS_CRB_RETRY_COUNT)
			return NX_CDRP_RSP_TIMEOUT;

		netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET,
				&raw_rsp);

		rsp = le32_to_cpu(raw_rsp);
	} while (!NX_CDRP_IS_RSP(rsp));

	return rsp;
}

static u32
netxen_issue_cmd(struct netxen_adapter *adapter,
	u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd)
{
	u32 rsp;
	u32 signature = 0;
	u32 rcode = NX_RCODE_SUCCESS;

	signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version);

	/* Acquire semaphore before accessing CRB */
	if (netxen_api_lock(adapter))
		return NX_RCODE_TIMEOUT;

	netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET,
			cpu_to_le32(signature));

	netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET,
			cpu_to_le32(arg1));

	netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET,
			cpu_to_le32(arg2));

	netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET,
			cpu_to_le32(arg3));

	netxen_nic_write_w1(adapter, NX_CDRP_CRB_OFFSET,
			cpu_to_le32(NX_CDRP_FORM_CMD(cmd)));

	rsp = netxen_poll_rsp(adapter);

	if (rsp == NX_CDRP_RSP_TIMEOUT) {
		printk(KERN_ERR "%s: card response timeout.\n",
				netxen_nic_driver_name);

		rcode = NX_RCODE_TIMEOUT;
	} else if (rsp == NX_CDRP_RSP_FAIL) {
		netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET, &rcode);
		rcode = le32_to_cpu(rcode);

		printk(KERN_ERR "%s: failed card response code:0x%x\n",
				netxen_nic_driver_name, rcode);
	}

	/* Release semaphore */
	netxen_api_unlock(adapter);

	return rcode;
}

int
nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu)
{
	u32 rcode = NX_RCODE_SUCCESS;
	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];

	if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
		rcode = netxen_issue_cmd(adapter,
				adapter->ahw.pci_func,
				NXHAL_VERSION,
				recv_ctx->context_id,
				mtu,
				0,
				NX_CDRP_CMD_SET_MTU);

	if (rcode != NX_RCODE_SUCCESS)
		return -EIO;

	return 0;
}

static int
nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
{
	void *addr;
	nx_hostrq_rx_ctx_t *prq;
	nx_cardrsp_rx_ctx_t *prsp;
	nx_hostrq_rds_ring_t *prq_rds;
	nx_hostrq_sds_ring_t *prq_sds;
	nx_cardrsp_rds_ring_t *prsp_rds;
	nx_cardrsp_sds_ring_t *prsp_sds;
	struct nx_host_rds_ring *rds_ring;

	dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
	u64 phys_addr;

	int i, nrds_rings, nsds_rings;
	size_t rq_size, rsp_size;
	u32 cap, reg;

	int err;

	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];

	/* only one sds ring for now */
	nrds_rings = adapter->max_rds_rings;
	nsds_rings = 1;

	rq_size =
		SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings);
	rsp_size =
		SIZEOF_CARDRSP_RX(nx_cardrsp_rx_ctx_t, nrds_rings, nsds_rings);

	addr = pci_alloc_consistent(adapter->pdev,
				rq_size, &hostrq_phys_addr);
	if (addr == NULL)
		return -ENOMEM;
	prq = (nx_hostrq_rx_ctx_t *)addr;

	addr = pci_alloc_consistent(adapter->pdev,
			rsp_size, &cardrsp_phys_addr);
	if (addr == NULL) {
		err = -ENOMEM;
		goto out_free_rq;
	}
	prsp = (nx_cardrsp_rx_ctx_t *)addr;

	prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr);

	cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN);
	cap |= (NX_CAP0_JUMBO_CONTIGUOUS | NX_CAP0_LRO_CONTIGUOUS);

	prq->capabilities[0] = cpu_to_le32(cap);
	prq->host_int_crb_mode =
		cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED);
	prq->host_rds_crb_mode =
		cpu_to_le32(NX_HOST_RDS_CRB_MODE_UNIQUE);

	prq->num_rds_rings = cpu_to_le16(nrds_rings);
	prq->num_sds_rings = cpu_to_le16(nsds_rings);
	prq->rds_ring_offset = 0;
	prq->sds_ring_offset = prq->rds_ring_offset +
		(sizeof(nx_hostrq_rds_ring_t) * nrds_rings);

	prq_rds = (nx_hostrq_rds_ring_t *)(prq->data + prq->rds_ring_offset);

	for (i = 0; i < nrds_rings; i++) {

		rds_ring = &recv_ctx->rds_rings[i];

		prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
		prq_rds[i].ring_size = cpu_to_le32(rds_ring->max_rx_desc_count);
		prq_rds[i].ring_kind = cpu_to_le32(i);
		prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size);
	}

	prq_sds = (nx_hostrq_sds_ring_t *)(prq->data + prq->sds_ring_offset);

	prq_sds[0].host_phys_addr =
		cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
	prq_sds[0].ring_size = cpu_to_le32(adapter->max_rx_desc_count);
	/* only one msix vector for now */
	prq_sds[0].msi_index = cpu_to_le32(0);

	/* now byteswap offsets */
	prq->rds_ring_offset = cpu_to_le32(prq->rds_ring_offset);
	prq->sds_ring_offset = cpu_to_le32(prq->sds_ring_offset);

	phys_addr = hostrq_phys_addr;
	err = netxen_issue_cmd(adapter,
			adapter->ahw.pci_func,
			NXHAL_VERSION,
			(u32)(phys_addr >> 32),
			(u32)(phys_addr & 0xffffffff),
			rq_size,
			NX_CDRP_CMD_CREATE_RX_CTX);
	if (err) {
		printk(KERN_WARNING
			"Failed to create rx ctx in firmware%d\n", err);
		goto out_free_rsp;
	}


	prsp_rds = ((nx_cardrsp_rds_ring_t *)
			 &prsp->data[prsp->rds_ring_offset]);

	for (i = 0; i < le32_to_cpu(prsp->num_rds_rings); i++) {
		rds_ring = &recv_ctx->rds_rings[i];

		reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
		rds_ring->crb_rcv_producer = NETXEN_NIC_REG(reg - 0x200);
	}

	prsp_sds = ((nx_cardrsp_sds_ring_t *)
			&prsp->data[prsp->sds_ring_offset]);
	reg = le32_to_cpu(prsp_sds[0].host_consumer_crb);
	recv_ctx->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);

	reg = le32_to_cpu(prsp_sds[0].interrupt_crb);
	adapter->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);

	recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
	recv_ctx->context_id = le16_to_cpu(prsp->context_id);
	recv_ctx->virt_port = le16_to_cpu(prsp->virt_port);

out_free_rsp:
	pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr);
out_free_rq:
	pci_free_consistent(adapter->pdev, rq_size, prq, hostrq_phys_addr);
	return err;
}

static void
nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter)
{
	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];

	if (netxen_issue_cmd(adapter,
			adapter->ahw.pci_func,
			NXHAL_VERSION,
			recv_ctx->context_id,
			NX_DESTROY_CTX_RESET,
			0,
			NX_CDRP_CMD_DESTROY_RX_CTX)) {

		printk(KERN_WARNING
			"%s: Failed to destroy rx ctx in firmware\n",
			netxen_nic_driver_name);
	}
}

static int
nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
{
	nx_hostrq_tx_ctx_t	*prq;
	nx_hostrq_cds_ring_t	*prq_cds;
	nx_cardrsp_tx_ctx_t	*prsp;
	void	*rq_addr, *rsp_addr;
	size_t	rq_size, rsp_size;
	u32	temp;
	int	err = 0;
	u64	offset, phys_addr;
	dma_addr_t	rq_phys_addr, rsp_phys_addr;

	rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
	rq_addr = pci_alloc_consistent(adapter->pdev,
		rq_size, &rq_phys_addr);
	if (!rq_addr)
		return -ENOMEM;

	rsp_size = SIZEOF_CARDRSP_TX(nx_cardrsp_tx_ctx_t);
	rsp_addr = pci_alloc_consistent(adapter->pdev,
		rsp_size, &rsp_phys_addr);
	if (!rsp_addr) {
		err = -ENOMEM;
		goto out_free_rq;
	}

	memset(rq_addr, 0, rq_size);
	prq = (nx_hostrq_tx_ctx_t *)rq_addr;

	memset(rsp_addr, 0, rsp_size);
	prsp = (nx_cardrsp_tx_ctx_t *)rsp_addr;

	prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr);

	temp = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN | NX_CAP0_LSO);
	prq->capabilities[0] = cpu_to_le32(temp);

	prq->host_int_crb_mode =
		cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED);

	prq->interrupt_ctl = 0;
	prq->msi_index = 0;

	prq->dummy_dma_addr = cpu_to_le64(adapter->dummy_dma.phys_addr);

	offset = adapter->ctx_desc_phys_addr+sizeof(struct netxen_ring_ctx);
	prq->cmd_cons_dma_addr = cpu_to_le64(offset);

	prq_cds = &prq->cds_ring;

	prq_cds->host_phys_addr =
		cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);

	prq_cds->ring_size = cpu_to_le32(adapter->max_tx_desc_count);

	phys_addr = rq_phys_addr;
	err = netxen_issue_cmd(adapter,
			adapter->ahw.pci_func,
			NXHAL_VERSION,
			(u32)(phys_addr >> 32),
			((u32)phys_addr & 0xffffffff),
			rq_size,
			NX_CDRP_CMD_CREATE_TX_CTX);

	if (err == NX_RCODE_SUCCESS) {
		temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
		adapter->crb_addr_cmd_producer =
			NETXEN_NIC_REG(temp - 0x200);
#if 0
		adapter->tx_state =
			le32_to_cpu(prsp->host_ctx_state);
#endif
		adapter->tx_context_id =
			le16_to_cpu(prsp->context_id);
	} else {
		printk(KERN_WARNING
			"Failed to create tx ctx in firmware%d\n", err);
		err = -EIO;
	}

	pci_free_consistent(adapter->pdev, rsp_size, rsp_addr, rsp_phys_addr);

out_free_rq:
	pci_free_consistent(adapter->pdev, rq_size, rq_addr, rq_phys_addr);

	return err;
}

static void
nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter)
{
	if (netxen_issue_cmd(adapter,
			adapter->ahw.pci_func,
			NXHAL_VERSION,
			adapter->tx_context_id,
			NX_DESTROY_CTX_RESET,
			0,
			NX_CDRP_CMD_DESTROY_TX_CTX)) {

		printk(KERN_WARNING
			"%s: Failed to destroy tx ctx in firmware\n",
			netxen_nic_driver_name);
	}
}

static u64 ctx_addr_sig_regs[][3] = {
	{NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)},
	{NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)},
	{NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)},
	{NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)}
};

#define CRB_CTX_ADDR_REG_LO(FUNC_ID)	(ctx_addr_sig_regs[FUNC_ID][0])
#define CRB_CTX_ADDR_REG_HI(FUNC_ID)	(ctx_addr_sig_regs[FUNC_ID][2])
#define CRB_CTX_SIGNATURE_REG(FUNC_ID)	(ctx_addr_sig_regs[FUNC_ID][1])

#define lower32(x)	((u32)((x) & 0xffffffff))
#define upper32(x)	((u32)(((u64)(x) >> 32) & 0xffffffff))

static struct netxen_recv_crb recv_crb_registers[] = {
	/* Instance 0 */
	{
		/* crb_rcv_producer: */
		{
			NETXEN_NIC_REG(0x100),
			/* Jumbo frames */
			NETXEN_NIC_REG(0x110),
			/* LRO */
			NETXEN_NIC_REG(0x120)
		},
		/* crb_sts_consumer: */
		NETXEN_NIC_REG(0x138),
	},
	/* Instance 1 */
	{
		/* crb_rcv_producer: */
		{
			NETXEN_NIC_REG(0x144),
			/* Jumbo frames */
			NETXEN_NIC_REG(0x154),
			/* LRO */
			NETXEN_NIC_REG(0x164)
		},
		/* crb_sts_consumer: */
		NETXEN_NIC_REG(0x17c),
	},
	/* Instance 2 */
	{
		/* crb_rcv_producer: */
		{
			NETXEN_NIC_REG(0x1d8),
			/* Jumbo frames */
			NETXEN_NIC_REG(0x1f8),
			/* LRO */
			NETXEN_NIC_REG(0x208)
		},
		/* crb_sts_consumer: */
		NETXEN_NIC_REG(0x220),
	},
	/* Instance 3 */
	{
		/* crb_rcv_producer: */
		{
			NETXEN_NIC_REG(0x22c),
			/* Jumbo frames */
			NETXEN_NIC_REG(0x23c),
			/* LRO */
			NETXEN_NIC_REG(0x24c)
		},
		/* crb_sts_consumer: */
		NETXEN_NIC_REG(0x264),
	},
};

static int
netxen_init_old_ctx(struct netxen_adapter *adapter)
{
	struct netxen_recv_context *recv_ctx;
	struct nx_host_rds_ring *rds_ring;
	int ctx, ring;
	int func_id = adapter->portnum;

	adapter->ctx_desc->cmd_ring_addr =
		cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
	adapter->ctx_desc->cmd_ring_size =
		cpu_to_le32(adapter->max_tx_desc_count);

	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
		recv_ctx = &adapter->recv_ctx[ctx];

		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
			rds_ring = &recv_ctx->rds_rings[ring];

			adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
				cpu_to_le64(rds_ring->phys_addr);
			adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
				cpu_to_le32(rds_ring->max_rx_desc_count);
		}
		adapter->ctx_desc->sts_ring_addr =
			cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
		adapter->ctx_desc->sts_ring_size =
			cpu_to_le32(adapter->max_rx_desc_count);
	}

	adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id),
			lower32(adapter->ctx_desc_phys_addr));
	adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_HI(func_id),
			upper32(adapter->ctx_desc_phys_addr));
	adapter->pci_write_normalize(adapter, CRB_CTX_SIGNATURE_REG(func_id),
			NETXEN_CTX_SIGNATURE | func_id);
	return 0;
}

static uint32_t sw_int_mask[4] = {
	CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1,
	CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3
};

int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
{
	struct netxen_hardware_context *hw = &adapter->ahw;
	u32 state = 0;
	void *addr;
	int err = 0;
	int ctx, ring;
	struct netxen_recv_context *recv_ctx;
	struct nx_host_rds_ring *rds_ring;

	err = netxen_receive_peg_ready(adapter);
	if (err) {
		printk(KERN_ERR "Rcv Peg initialization not complete:%x.\n",
				state);
		return err;
	}

	addr = pci_alloc_consistent(adapter->pdev,
			sizeof(struct netxen_ring_ctx) + sizeof(uint32_t),
			&adapter->ctx_desc_phys_addr);

	if (addr == NULL) {
		DPRINTK(ERR, "failed to allocate hw context\n");
		return -ENOMEM;
	}
	memset(addr, 0, sizeof(struct netxen_ring_ctx));
	adapter->ctx_desc = (struct netxen_ring_ctx *)addr;
	adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum);
	adapter->ctx_desc->cmd_consumer_offset =
		cpu_to_le64(adapter->ctx_desc_phys_addr +
			sizeof(struct netxen_ring_ctx));
	adapter->cmd_consumer =
		(__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx));

	/* cmd desc ring */
	addr = pci_alloc_consistent(adapter->pdev,
			sizeof(struct cmd_desc_type0) *
			adapter->max_tx_desc_count,
			&hw->cmd_desc_phys_addr);

	if (addr == NULL) {
		printk(KERN_ERR "%s failed to allocate tx desc ring\n",
				netxen_nic_driver_name);
		return -ENOMEM;
	}

	hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;

	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
		recv_ctx = &adapter->recv_ctx[ctx];

		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
			/* rx desc ring */
			rds_ring = &recv_ctx->rds_rings[ring];
			addr = pci_alloc_consistent(adapter->pdev,
					RCV_DESC_RINGSIZE,
					&rds_ring->phys_addr);
			if (addr == NULL) {
				printk(KERN_ERR "%s failed to allocate rx "
					"desc ring[%d]\n",
					netxen_nic_driver_name, ring);
				err = -ENOMEM;
				goto err_out_free;
			}
			rds_ring->desc_head = (struct rcv_desc *)addr;

			if (adapter->fw_major < 4)
				rds_ring->crb_rcv_producer =
					recv_crb_registers[adapter->portnum].
					crb_rcv_producer[ring];
		}

		/* status desc ring */
		addr = pci_alloc_consistent(adapter->pdev,
				STATUS_DESC_RINGSIZE,
				&recv_ctx->rcv_status_desc_phys_addr);
		if (addr == NULL) {
			printk(KERN_ERR "%s failed to allocate sts desc ring\n",
					netxen_nic_driver_name);
			err = -ENOMEM;
			goto err_out_free;
		}
		recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;

		if (adapter->fw_major < 4)
			recv_ctx->crb_sts_consumer =
				recv_crb_registers[adapter->portnum].
				crb_sts_consumer;
	}

	if (adapter->fw_major >= 4) {
		adapter->intr_scheme = INTR_SCHEME_PERPORT;
		adapter->msi_mode = MSI_MODE_MULTIFUNC;

		err = nx_fw_cmd_create_rx_ctx(adapter);
		if (err)
			goto err_out_free;
		err = nx_fw_cmd_create_tx_ctx(adapter);
		if (err)
			goto err_out_free;
	} else {

		adapter->intr_scheme = adapter->pci_read_normalize(adapter,
				CRB_NIC_CAPABILITIES_FW);
		adapter->msi_mode = adapter->pci_read_normalize(adapter,
				CRB_NIC_MSI_MODE_FW);
		adapter->crb_intr_mask = sw_int_mask[adapter->portnum];

		err = netxen_init_old_ctx(adapter);
		if (err) {
			netxen_free_hw_resources(adapter);
			return err;
		}

	}

	return 0;

err_out_free:
	netxen_free_hw_resources(adapter);
	return err;
}

void netxen_free_hw_resources(struct netxen_adapter *adapter)
{
	struct netxen_recv_context *recv_ctx;
	struct nx_host_rds_ring *rds_ring;
	int ctx, ring;

	if (adapter->fw_major >= 4) {
		nx_fw_cmd_destroy_tx_ctx(adapter);
		nx_fw_cmd_destroy_rx_ctx(adapter);
	}

	if (adapter->ctx_desc != NULL) {
		pci_free_consistent(adapter->pdev,
				sizeof(struct netxen_ring_ctx) +
				sizeof(uint32_t),
				adapter->ctx_desc,
				adapter->ctx_desc_phys_addr);
		adapter->ctx_desc = NULL;
	}

	if (adapter->ahw.cmd_desc_head != NULL) {
		pci_free_consistent(adapter->pdev,
				sizeof(struct cmd_desc_type0) *
				adapter->max_tx_desc_count,
				adapter->ahw.cmd_desc_head,
				adapter->ahw.cmd_desc_phys_addr);
		adapter->ahw.cmd_desc_head = NULL;
	}

	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
		recv_ctx = &adapter->recv_ctx[ctx];
		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
			rds_ring = &recv_ctx->rds_rings[ring];

			if (rds_ring->desc_head != NULL) {
				pci_free_consistent(adapter->pdev,
						RCV_DESC_RINGSIZE,
						rds_ring->desc_head,
						rds_ring->phys_addr);
				rds_ring->desc_head = NULL;
			}
		}

		if (recv_ctx->rcv_status_desc_head != NULL) {
			pci_free_consistent(adapter->pdev,
					STATUS_DESC_RINGSIZE,
					recv_ctx->rcv_status_desc_head,
					recv_ctx->rcv_status_desc_phys_addr);
			recv_ctx->rcv_status_desc_head = NULL;
		}
	}
}

