Home | History | Annotate | Download | only in ntxn
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2008 NetXen, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #include <sys/types.h>
     28 #include <sys/conf.h>
     29 #include <sys/debug.h>
     30 #include <sys/stropts.h>
     31 #include <sys/stream.h>
     32 #include <sys/strlog.h>
     33 #include <sys/kmem.h>
     34 #include <sys/stat.h>
     35 #include <sys/kstat.h>
     36 #include <sys/vtrace.h>
     37 #include <sys/dlpi.h>
     38 #include <sys/strsun.h>
     39 #include <sys/ethernet.h>
     40 #include <sys/modctl.h>
     41 #include <sys/errno.h>
     42 #include <sys/dditypes.h>
     43 #include <sys/ddi.h>
     44 #include <sys/sunddi.h>
     45 #include <sys/sysmacros.h>
     46 #include <sys/pci.h>
     47 
     48 #include "unm_nic_hw.h"
     49 #include "unm_nic.h"
     50 #include "nic_phan_reg.h"
     51 #include "nic_cmn.h"
     52 
     53 typedef unsigned int nx_rcode_t;
     54 
     55 #include "nx_errorcode.h"
     56 #include "nxhal_nic_interface.h"
     57 
     58 #define	NXHAL_VERSION	1
     59 
     60 #define	NX_OS_CRB_RETRY_COUNT	4000
     61 
     62 #define	NX_CDRP_CLEAR		0x00000000
     63 #define	NX_CDRP_CMD_BIT		0x80000000
     64 
     65 /*
     66  * All responses must have the NX_CDRP_CMD_BIT cleared
     67  * in the crb NX_CDRP_CRB_OFFSET.
     68  */
     69 #define	NX_CDRP_FORM_RSP(rsp)	(rsp)
     70 #define	NX_CDRP_IS_RSP(rsp)	(((rsp) & NX_CDRP_CMD_BIT) == 0)
     71 
     72 #define	NX_CDRP_RSP_OK		0x00000001
     73 #define	NX_CDRP_RSP_FAIL	0x00000002
     74 #define	NX_CDRP_RSP_TIMEOUT	0x00000003
     75 
     76 /*
     77  * All commands must have the NX_CDRP_CMD_BIT set in
     78  * the crb NX_CDRP_CRB_OFFSET.
     79  */
     80 #define	NX_CDRP_FORM_CMD(cmd)	(NX_CDRP_CMD_BIT | (cmd))
     81 #define	NX_CDRP_IS_CMD(cmd)	(((cmd) & NX_CDRP_CMD_BIT) != 0)
     82 
     83 #define	NX_CDRP_CMD_SUBMIT_CAPABILITIES		0x00000001
     84 #define	NX_CDRP_CMD_READ_MAX_RDS_PER_CTX    0x00000002
     85 #define	NX_CDRP_CMD_READ_MAX_SDS_PER_CTX    0x00000003
     86 #define	NX_CDRP_CMD_READ_MAX_RULES_PER_CTX  0x00000004
     87 #define	NX_CDRP_CMD_READ_MAX_RX_CTX			0x00000005
     88 #define	NX_CDRP_CMD_READ_MAX_TX_CTX			0x00000006
     89 #define	NX_CDRP_CMD_CREATE_RX_CTX			0x00000007
     90 #define	NX_CDRP_CMD_DESTROY_RX_CTX			0x00000008
     91 #define	NX_CDRP_CMD_CREATE_TX_CTX			0x00000009
     92 #define	NX_CDRP_CMD_DESTROY_TX_CTX			0x0000000a
     93 #define	NX_CDRP_CMD_SETUP_STATISTICS		0x0000000e
     94 #define	NX_CDRP_CMD_GET_STATISTICS			0x0000000f
     95 #define	NX_CDRP_CMD_DELETE_STATISTICS		0x00000010
     96 #define	NX_CDRP_CMD_SET_MTU					0x00000012
     97 #define	NX_CDRP_CMD_MAX						0x00000013
     98 
     99 #define	NX_DESTROY_CTX_RESET		0
    100 #define	NX_DESTROY_CTX_D3_RESET		1
    101 #define	NX_DESTROY_CTX_MAX		2
    102 
    103 /*
    104  * Context state
    105  */
    106 #define	NX_HOST_CTX_STATE_FREED		0
    107 #define	NX_HOST_CTX_STATE_ALLOCATED	1
    108 #define	NX_HOST_CTX_STATE_ACTIVE	2
    109 #define	NX_HOST_CTX_STATE_DISABLED	3
    110 #define	NX_HOST_CTX_STATE_QUIESCED	4
    111 #define	NX_HOST_CTX_STATE_MAX		5
    112 
    113 static int
    114 netxen_api_lock(struct unm_adapter_s *adapter)
    115 {
    116 	u32 done = 0, timeout = 0;
    117 
    118 	for (;;) {
    119 		/* Acquire PCIE HW semaphore5 */
    120 		unm_nic_read_w0(adapter,
    121 		    UNM_PCIE_REG(PCIE_SEM5_LOCK), &done);
    122 
    123 		if (done == 1)
    124 			break;
    125 
    126 		if (++timeout >= NX_OS_CRB_RETRY_COUNT) {
    127 			cmn_err(CE_WARN, "%s: lock timeout.\n", __func__);
    128 			return (-1);
    129 		}
    130 
    131 		drv_usecwait(1000);
    132 	}
    133 
    134 #if 0
    135 	unm_nic_reg_write(adapter, NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER);
    136 #endif
    137 	return (0);
    138 }
    139 
    140 static void
    141 netxen_api_unlock(struct unm_adapter_s *adapter)
    142 {
    143 	u32 val;
    144 
    145 	/* Release PCIE HW semaphore5 */
    146 	unm_nic_read_w0(adapter,
    147 	    UNM_PCIE_REG(PCIE_SEM5_UNLOCK), &val);
    148 }
    149 
    150 static u32
    151 netxen_poll_rsp(struct unm_adapter_s *adapter)
    152 {
    153 	u32 raw_rsp, rsp = NX_CDRP_RSP_OK;
    154 	int	timeout = 0;
    155 
    156 	do {
    157 		/* give atleast 1ms for firmware to respond */
    158 		drv_usecwait(1000);
    159 
    160 		if (++timeout > NX_OS_CRB_RETRY_COUNT)
    161 			return (NX_CDRP_RSP_TIMEOUT);
    162 
    163 		adapter->unm_nic_hw_read_wx(adapter, NX_CDRP_CRB_OFFSET,
    164 		    &raw_rsp, 4);
    165 
    166 		rsp = LE_TO_HOST_32(raw_rsp);
    167 	} while (!NX_CDRP_IS_RSP(rsp));
    168 
    169 	return (rsp);
    170 }
    171 
    172 static u32
    173 netxen_issue_cmd(struct unm_adapter_s *adapter,
    174 	u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd)
    175 {
    176 	u32 rsp;
    177 	u32 signature = 0;
    178 	u32 rcode = NX_RCODE_SUCCESS;
    179 
    180 	signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version);
    181 
    182 	/* Acquire semaphore before accessing CRB */
    183 	if (netxen_api_lock(adapter))
    184 		return (NX_RCODE_TIMEOUT);
    185 
    186 	unm_nic_reg_write(adapter, NX_SIGN_CRB_OFFSET,
    187 	    HOST_TO_LE_32(signature));
    188 
    189 	unm_nic_reg_write(adapter, NX_ARG1_CRB_OFFSET,
    190 	    HOST_TO_LE_32(arg1));
    191 
    192 	unm_nic_reg_write(adapter, NX_ARG2_CRB_OFFSET,
    193 	    HOST_TO_LE_32(arg2));
    194 
    195 	unm_nic_reg_write(adapter, NX_ARG3_CRB_OFFSET,
    196 	    HOST_TO_LE_32(arg3));
    197 
    198 	unm_nic_reg_write(adapter, NX_CDRP_CRB_OFFSET,
    199 	    HOST_TO_LE_32(NX_CDRP_FORM_CMD(cmd)));
    200 
    201 	rsp = netxen_poll_rsp(adapter);
    202 
    203 	if (rsp == NX_CDRP_RSP_TIMEOUT) {
    204 		cmn_err(CE_WARN, "%s: card response timeout.\n",
    205 		    unm_nic_driver_name);
    206 
    207 		rcode = NX_RCODE_TIMEOUT;
    208 	} else if (rsp == NX_CDRP_RSP_FAIL) {
    209 		adapter->unm_nic_hw_read_wx(adapter, NX_ARG1_CRB_OFFSET,
    210 		    &rcode, 4);
    211 		rcode = LE_TO_HOST_32(rcode);
    212 
    213 		cmn_err(CE_WARN, "%s: failed card response code:0x%x\n",
    214 		    unm_nic_driver_name, rcode);
    215 	}
    216 
    217 	/* Release semaphore */
    218 	netxen_api_unlock(adapter);
    219 
    220 	return (rcode);
    221 }
    222 
    223 int
    224 nx_fw_cmd_set_mtu(struct unm_adapter_s *adapter, int mtu)
    225 {
    226 	u32 rcode = NX_RCODE_SUCCESS;
    227 	struct unm_recv_context_s *recv_ctx = &adapter->recv_ctx[0];
    228 
    229 	if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
    230 		rcode = netxen_issue_cmd(adapter,
    231 		    adapter->ahw.pci_func,
    232 		    NXHAL_VERSION,
    233 		    recv_ctx->context_id,
    234 		    mtu,
    235 		    0,
    236 		    NX_CDRP_CMD_SET_MTU);
    237 
    238 	if (rcode != NX_RCODE_SUCCESS)
    239 		return (-EIO);
    240 
    241 	return (0);
    242 }
    243 
    244 static int
    245 nx_fw_cmd_create_rx_ctx(struct unm_adapter_s *adapter)
    246 {
    247 	unm_recv_context_t	*recv_ctx = &adapter->recv_ctx[0];
    248 	nx_hostrq_rx_ctx_t	*prq;
    249 	nx_cardrsp_rx_ctx_t	*prsp;
    250 	nx_hostrq_rds_ring_t	*prq_rds;
    251 	nx_hostrq_sds_ring_t	*prq_sds;
    252 	nx_cardrsp_rds_ring_t	*prsp_rds;
    253 	nx_cardrsp_sds_ring_t	*prsp_sds;
    254 	unm_rcv_desc_ctx_t	*rcv_desc;
    255 	ddi_dma_cookie_t	cookie;
    256 	ddi_dma_handle_t	rqdhdl, rsdhdl;
    257 	ddi_acc_handle_t	rqahdl, rsahdl;
    258 	uint64_t		hostrq_phys_addr, cardrsp_phys_addr;
    259 	u64			phys_addr;
    260 	u32			cap, reg;
    261 	size_t			rq_size, rsp_size;
    262 	void			*addr;
    263 	int			i, nrds_rings, nsds_rings, err;
    264 
    265 	/* only one sds ring for now */
    266 	nrds_rings = adapter->max_rds_rings;
    267 	nsds_rings = 1;
    268 
    269 	rq_size =
    270 	    SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings);
    271 	rsp_size =
    272 	    SIZEOF_CARDRSP_RX(nx_cardrsp_rx_ctx_t, nrds_rings, nsds_rings);
    273 
    274 	if (unm_pci_alloc_consistent(adapter, rq_size, (caddr_t *)&addr,
    275 	    &cookie, &rqdhdl, &rqahdl) != DDI_SUCCESS)
    276 		return (-ENOMEM);
    277 	hostrq_phys_addr = cookie.dmac_laddress;
    278 	prq = (nx_hostrq_rx_ctx_t *)addr;
    279 
    280 	if (unm_pci_alloc_consistent(adapter, rsp_size, (caddr_t *)&addr,
    281 	    &cookie, &rsdhdl, &rsahdl) != DDI_SUCCESS) {
    282 		err = -ENOMEM;
    283 		goto out_free_rq;
    284 	}
    285 	cardrsp_phys_addr = cookie.dmac_laddress;
    286 	prsp = (nx_cardrsp_rx_ctx_t *)addr;
    287 
    288 	prq->host_rsp_dma_addr = HOST_TO_LE_64(cardrsp_phys_addr);
    289 
    290 	cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN);
    291 	cap |= (NX_CAP0_JUMBO_CONTIGUOUS);
    292 
    293 	prq->capabilities[0] = HOST_TO_LE_32(cap);
    294 	prq->host_int_crb_mode =
    295 	    HOST_TO_LE_32(NX_HOST_INT_CRB_MODE_SHARED);
    296 	prq->host_rds_crb_mode =
    297 	    HOST_TO_LE_32(NX_HOST_RDS_CRB_MODE_UNIQUE);
    298 
    299 	prq->num_rds_rings = HOST_TO_LE_16(nrds_rings);
    300 	prq->num_sds_rings = HOST_TO_LE_16(nsds_rings);
    301 	prq->rds_ring_offset = 0;
    302 	prq->sds_ring_offset = prq->rds_ring_offset +
    303 	    (sizeof (nx_hostrq_rds_ring_t) * nrds_rings);
    304 
    305 	prq_rds = (nx_hostrq_rds_ring_t *)(uintptr_t)((char *)prq +
    306 	    sizeof (*prq) + prq->rds_ring_offset);
    307 
    308 	for (i = 0; i < nrds_rings; i++) {
    309 		rcv_desc = &recv_ctx->rcv_desc[i];
    310 
    311 		prq_rds[i].host_phys_addr = HOST_TO_LE_64(rcv_desc->phys_addr);
    312 		prq_rds[i].ring_size = HOST_TO_LE_32(rcv_desc->MaxRxDescCount);
    313 		prq_rds[i].ring_kind = HOST_TO_LE_32(i);
    314 		prq_rds[i].buff_size = HOST_TO_LE_64(rcv_desc->dma_size);
    315 	}
    316 
    317 	prq_sds = (nx_hostrq_sds_ring_t *)(uintptr_t)((char *)prq +
    318 	    sizeof (*prq) + prq->sds_ring_offset);
    319 
    320 	prq_sds[0].host_phys_addr =
    321 	    HOST_TO_LE_64(recv_ctx->rcvStatusDesc_physAddr);
    322 	prq_sds[0].ring_size = HOST_TO_LE_32(adapter->MaxRxDescCount);
    323 	/* only one msix vector for now */
    324 	prq_sds[0].msi_index = HOST_TO_LE_32(0);
    325 
    326 	/* now byteswap offsets */
    327 	prq->rds_ring_offset = HOST_TO_LE_32(prq->rds_ring_offset);
    328 	prq->sds_ring_offset = HOST_TO_LE_32(prq->sds_ring_offset);
    329 
    330 	phys_addr = hostrq_phys_addr;
    331 	err = netxen_issue_cmd(adapter,
    332 	    adapter->ahw.pci_func,
    333 	    NXHAL_VERSION,
    334 	    (u32)(phys_addr >> 32),
    335 	    (u32)(phys_addr & 0xffffffff),
    336 	    rq_size,
    337 	    NX_CDRP_CMD_CREATE_RX_CTX);
    338 	if (err) {
    339 		cmn_err(CE_WARN, "Failed to create rx ctx in firmware%d\n",
    340 		    err);
    341 		goto out_free_rsp;
    342 	}
    343 
    344 
    345 	prsp_rds = (nx_cardrsp_rds_ring_t *)(uintptr_t)((char *)prsp +
    346 	    sizeof (*prsp) + prsp->rds_ring_offset);
    347 
    348 	for (i = 0; i < LE_TO_HOST_32(prsp->num_rds_rings); i++) {
    349 		rcv_desc = &recv_ctx->rcv_desc[i];
    350 
    351 		reg = LE_TO_HOST_32(prsp_rds[i].host_producer_crb);
    352 		rcv_desc->host_rx_producer = UNM_NIC_REG(reg - 0x200);
    353 	}
    354 
    355 	prsp_sds = (nx_cardrsp_sds_ring_t *)(uintptr_t)((char *)prsp +
    356 	    sizeof (*prsp) + prsp->sds_ring_offset);
    357 	reg = LE_TO_HOST_32(prsp_sds[0].host_consumer_crb);
    358 	recv_ctx->host_sds_consumer = UNM_NIC_REG(reg - 0x200);
    359 
    360 	reg = LE_TO_HOST_32(prsp_sds[0].interrupt_crb);
    361 	adapter->interrupt_crb = UNM_NIC_REG(reg - 0x200);
    362 
    363 	recv_ctx->state = LE_TO_HOST_32(prsp->host_ctx_state);
    364 	recv_ctx->context_id = LE_TO_HOST_16(prsp->context_id);
    365 	recv_ctx->virt_port = LE_TO_HOST_16(prsp->virt_port);
    366 
    367 out_free_rsp:
    368 	unm_pci_free_consistent(&rsdhdl, &rsahdl);
    369 out_free_rq:
    370 	unm_pci_free_consistent(&rqdhdl, &rqahdl);
    371 	return (err);
    372 }
    373 
    374 static void
    375 nx_fw_cmd_destroy_rx_ctx(struct unm_adapter_s *adapter)
    376 {
    377 	struct unm_recv_context_s *recv_ctx = &adapter->recv_ctx[0];
    378 
    379 	if (netxen_issue_cmd(adapter,
    380 	    adapter->ahw.pci_func,
    381 	    NXHAL_VERSION,
    382 	    recv_ctx->context_id,
    383 	    NX_DESTROY_CTX_RESET,
    384 	    0,
    385 	    NX_CDRP_CMD_DESTROY_RX_CTX)) {
    386 
    387 		cmn_err(CE_WARN, "%s: Failed to destroy rx ctx in firmware\n",
    388 		    unm_nic_driver_name);
    389 	}
    390 }
    391 
    392 static int
    393 nx_fw_cmd_create_tx_ctx(struct unm_adapter_s *adapter)
    394 {
    395 	nx_hostrq_tx_ctx_t	*prq;
    396 	nx_hostrq_cds_ring_t	*prq_cds;
    397 	nx_cardrsp_tx_ctx_t	*prsp;
    398 	ddi_dma_cookie_t	cookie;
    399 	ddi_dma_handle_t	rqdhdl, rsdhdl;
    400 	ddi_acc_handle_t	rqahdl, rsahdl;
    401 	void			*rq_addr, *rsp_addr;
    402 	size_t			rq_size, rsp_size;
    403 	u32			temp;
    404 	int			err = 0;
    405 	u64			offset, phys_addr;
    406 	uint64_t		rq_phys_addr, rsp_phys_addr;
    407 
    408 	rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
    409 	if (unm_pci_alloc_consistent(adapter, rq_size, (caddr_t *)&rq_addr,
    410 	    &cookie, &rqdhdl, &rqahdl) != DDI_SUCCESS)
    411 		return (-ENOMEM);
    412 	rq_phys_addr = cookie.dmac_laddress;
    413 
    414 	rsp_size = SIZEOF_CARDRSP_TX(nx_cardrsp_tx_ctx_t);
    415 	if (unm_pci_alloc_consistent(adapter, rsp_size, (caddr_t *)&rsp_addr,
    416 	    &cookie, &rsdhdl, &rsahdl) != DDI_SUCCESS) {
    417 		err = -ENOMEM;
    418 		goto out_free_rq;
    419 	}
    420 	rsp_phys_addr = cookie.dmac_laddress;
    421 
    422 	(void) memset(rq_addr, 0, rq_size);
    423 	prq = (nx_hostrq_tx_ctx_t *)rq_addr;
    424 
    425 	(void) memset(rsp_addr, 0, rsp_size);
    426 	prsp = (nx_cardrsp_tx_ctx_t *)rsp_addr;
    427 
    428 	prq->host_rsp_dma_addr = HOST_TO_LE_64(rsp_phys_addr);
    429 
    430 	temp = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN);
    431 	prq->capabilities[0] = HOST_TO_LE_32(temp);
    432 
    433 	prq->host_int_crb_mode =
    434 	    HOST_TO_LE_32(NX_HOST_INT_CRB_MODE_SHARED);
    435 
    436 	prq->interrupt_ctl = 0;
    437 	prq->msi_index = 0;
    438 
    439 	prq->dummy_dma_addr = HOST_TO_LE_64(adapter->dummy_dma.phys_addr);
    440 
    441 	offset = adapter->ctxDesc_physAddr + sizeof (RingContext);
    442 	prq->cmd_cons_dma_addr = HOST_TO_LE_64(offset);
    443 
    444 	prq_cds = &prq->cds_ring;
    445 
    446 	prq_cds->host_phys_addr =
    447 	    HOST_TO_LE_64(adapter->ahw.cmdDesc_physAddr);
    448 
    449 	prq_cds->ring_size = HOST_TO_LE_32(adapter->MaxTxDescCount);
    450 
    451 	phys_addr = rq_phys_addr;
    452 	err = netxen_issue_cmd(adapter,
    453 	    adapter->ahw.pci_func,
    454 	    NXHAL_VERSION,
    455 	    (u32)(phys_addr >> 32),
    456 	    ((u32)phys_addr & 0xffffffff),
    457 	    rq_size,
    458 	    NX_CDRP_CMD_CREATE_TX_CTX);
    459 
    460 	if (err == NX_RCODE_SUCCESS) {
    461 		temp = LE_TO_HOST_32(prsp->cds_ring.host_producer_crb);
    462 		adapter->crb_addr_cmd_producer =
    463 		    UNM_NIC_REG(temp - 0x200);
    464 #if 0
    465 		adapter->tx_state =
    466 		    LE_TO_HOST_32(prsp->host_ctx_state);
    467 #endif
    468 		adapter->tx_context_id =
    469 		    LE_TO_HOST_16(prsp->context_id);
    470 	} else {
    471 		cmn_err(CE_WARN, "Failed to create tx ctx in firmware%d\n",
    472 		    err);
    473 		err = -EIO;
    474 	}
    475 
    476 	unm_pci_free_consistent(&rsdhdl, &rsahdl);
    477 
    478 out_free_rq:
    479 	unm_pci_free_consistent(&rqdhdl, &rqahdl);
    480 
    481 	return (err);
    482 }
    483 
    484 static void
    485 nx_fw_cmd_destroy_tx_ctx(struct unm_adapter_s *adapter)
    486 {
    487 	if (netxen_issue_cmd(adapter,
    488 	    adapter->ahw.pci_func,
    489 	    NXHAL_VERSION,
    490 	    adapter->tx_context_id,
    491 	    NX_DESTROY_CTX_RESET,
    492 	    0,
    493 	    NX_CDRP_CMD_DESTROY_TX_CTX)) {
    494 
    495 		cmn_err(CE_WARN, "%s: Failed to destroy tx ctx in firmware\n",
    496 		    unm_nic_driver_name);
    497 	}
    498 }
    499 
    500 static u64 ctx_addr_sig_regs[][3] = {
    501 	{UNM_NIC_REG(0x188), UNM_NIC_REG(0x18c), UNM_NIC_REG(0x1c0)},
    502 	{UNM_NIC_REG(0x190), UNM_NIC_REG(0x194), UNM_NIC_REG(0x1c4)},
    503 	{UNM_NIC_REG(0x198), UNM_NIC_REG(0x19c), UNM_NIC_REG(0x1c8)},
    504 	{UNM_NIC_REG(0x1a0), UNM_NIC_REG(0x1a4), UNM_NIC_REG(0x1cc)}
    505 };
    506 
    507 #define	CRB_CTX_ADDR_REG_LO(FUNC_ID)	(ctx_addr_sig_regs[FUNC_ID][0])
    508 #define	CRB_CTX_ADDR_REG_HI(FUNC_ID)	(ctx_addr_sig_regs[FUNC_ID][2])
    509 #define	CRB_CTX_SIGNATURE_REG(FUNC_ID)	(ctx_addr_sig_regs[FUNC_ID][1])
    510 
    511 struct netxen_recv_crb {
    512 	u32	crb_rcv_producer[NUM_RCV_DESC_RINGS];
    513 	u32	crb_sts_consumer;
    514 };
    515 
    516 static struct netxen_recv_crb recv_crb_registers[] = {
    517 	/* Instance 0 */
    518 	{
    519 		/* crb_rcv_producer: */
    520 		{
    521 			UNM_NIC_REG(0x100),
    522 			/* Jumbo frames */
    523 			UNM_NIC_REG(0x110),
    524 			/* LRO */
    525 			UNM_NIC_REG(0x120)
    526 		},
    527 		/* crb_sts_consumer: */
    528 		UNM_NIC_REG(0x138),
    529 	},
    530 	/* Instance 1 */
    531 	{
    532 		/* crb_rcv_producer: */
    533 		{
    534 			UNM_NIC_REG(0x144),
    535 			/* Jumbo frames */
    536 			UNM_NIC_REG(0x154),
    537 			/* LRO */
    538 			UNM_NIC_REG(0x164)
    539 		},
    540 		/* crb_sts_consumer: */
    541 		UNM_NIC_REG(0x17c),
    542 	},
    543 	/* Instance 2 */
    544 	{
    545 		/* crb_rcv_producer: */
    546 		{
    547 			UNM_NIC_REG(0x1d8),
    548 			/* Jumbo frames */
    549 			UNM_NIC_REG(0x1f8),
    550 			/* LRO */
    551 			UNM_NIC_REG(0x208)
    552 		},
    553 		/* crb_sts_consumer: */
    554 		UNM_NIC_REG(0x220),
    555 	},
    556 	/* Instance 3 */
    557 	{
    558 		/* crb_rcv_producer: */
    559 		{
    560 			UNM_NIC_REG(0x22c),
    561 			/* Jumbo frames */
    562 			UNM_NIC_REG(0x23c),
    563 			/* LRO */
    564 			UNM_NIC_REG(0x24c)
    565 		},
    566 		/* crb_sts_consumer: */
    567 		UNM_NIC_REG(0x264),
    568 	},
    569 };
    570 
    571 static uint32_t sw_int_mask[4] = {
    572 	CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1,
    573 	CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3
    574 };
    575 
    576 static int
    577 netxen_init_old_ctx(struct unm_adapter_s *adapter)
    578 {
    579 	hardware_context		*hw = &adapter->ahw;
    580 	struct unm_recv_context_s	*recv_ctx;
    581 	unm_rcv_desc_ctx_t		*rcv_desc;
    582 	int				ctx, ring, func_id = adapter->portnum;
    583 	unsigned int			temp;
    584 
    585 	adapter->ctxDesc->CmdRingAddrLo = hw->cmdDesc_physAddr & 0xffffffffUL;
    586 	adapter->ctxDesc->CmdRingAddrHi = ((U64)hw->cmdDesc_physAddr >> 32);
    587 	adapter->ctxDesc->CmdRingSize = adapter->MaxTxDescCount;
    588 
    589 	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
    590 		recv_ctx = &adapter->recv_ctx[ctx];
    591 
    592 		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
    593 			rcv_desc = &recv_ctx->rcv_desc[ring];
    594 
    595 			adapter->ctxDesc->RcvContext[ring].RcvRingAddrLo =
    596 			    rcv_desc->phys_addr & 0xffffffffUL;
    597 			adapter->ctxDesc->RcvContext[ring].RcvRingAddrHi =
    598 			    ((U64)rcv_desc->phys_addr>>32);
    599 			adapter->ctxDesc->RcvContext[ring].RcvRingSize =
    600 			    rcv_desc->MaxRxDescCount;
    601 
    602 			rcv_desc->host_rx_producer =
    603 			    recv_crb_registers[adapter->portnum].
    604 			    crb_rcv_producer[ring];
    605 		}
    606 
    607 		adapter->ctxDesc->StsRingAddrLo =
    608 		    recv_ctx->rcvStatusDesc_physAddr & 0xffffffff;
    609 		adapter->ctxDesc->StsRingAddrHi =
    610 		    recv_ctx->rcvStatusDesc_physAddr >> 32;
    611 		adapter->ctxDesc->StsRingSize = adapter->MaxRxDescCount;
    612 
    613 		recv_ctx->host_sds_consumer =
    614 		    recv_crb_registers[adapter->portnum].crb_sts_consumer;
    615 	}
    616 
    617 	adapter->interrupt_crb = sw_int_mask[adapter->portnum];
    618 
    619 	temp = lower32(adapter->ctxDesc_physAddr);
    620 	adapter->unm_nic_hw_write_wx(adapter, CRB_CTX_ADDR_REG_LO(func_id),
    621 	    &temp, 4);
    622 	temp = upper32(adapter->ctxDesc_physAddr);
    623 	adapter->unm_nic_hw_write_wx(adapter, CRB_CTX_ADDR_REG_HI(func_id),
    624 	    &temp, 4);
    625 	temp = UNM_CTX_SIGNATURE | func_id;
    626 	adapter->unm_nic_hw_write_wx(adapter, CRB_CTX_SIGNATURE_REG(func_id),
    627 	    &temp, 4);
    628 
    629 	return (0);
    630 }
    631 
    632 void
    633 netxen_destroy_rxtx(struct unm_adapter_s *adapter)
    634 {
    635 	if (adapter->fw_major >= 4) {
    636 		nx_fw_cmd_destroy_tx_ctx(adapter);
    637 		nx_fw_cmd_destroy_rx_ctx(adapter);
    638 	}
    639 }
    640 
    641 int
    642 netxen_create_rxtx(struct unm_adapter_s *adapter)
    643 {
    644 	int	err;
    645 
    646 	if (adapter->fw_major >= 4) {
    647 		err = nx_fw_cmd_create_rx_ctx(adapter);
    648 		if (err)
    649 			return (err);
    650 		err = nx_fw_cmd_create_tx_ctx(adapter);
    651 		if (err)
    652 			nx_fw_cmd_destroy_rx_ctx(adapter);
    653 		return (err);
    654 	} else {
    655 		return (netxen_init_old_ctx(adapter));
    656 	}
    657 }
    658