17956Sxiuyan.wang@Sun.COM /*
27956Sxiuyan.wang@Sun.COM * CDDL HEADER START
37956Sxiuyan.wang@Sun.COM *
47956Sxiuyan.wang@Sun.COM * The contents of this file are subject to the terms of the
57956Sxiuyan.wang@Sun.COM * Common Development and Distribution License (the "License").
67956Sxiuyan.wang@Sun.COM * You may not use this file except in compliance with the License.
77956Sxiuyan.wang@Sun.COM *
87956Sxiuyan.wang@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97956Sxiuyan.wang@Sun.COM * or http://www.opensolaris.org/os/licensing.
107956Sxiuyan.wang@Sun.COM * See the License for the specific language governing permissions
117956Sxiuyan.wang@Sun.COM * and limitations under the License.
127956Sxiuyan.wang@Sun.COM *
137956Sxiuyan.wang@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147956Sxiuyan.wang@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157956Sxiuyan.wang@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167956Sxiuyan.wang@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177956Sxiuyan.wang@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187956Sxiuyan.wang@Sun.COM *
197956Sxiuyan.wang@Sun.COM * CDDL HEADER END
207956Sxiuyan.wang@Sun.COM */
21*8687SJing.Xiong@Sun.COM
227956Sxiuyan.wang@Sun.COM /*
237956Sxiuyan.wang@Sun.COM * Copyright 2008 NetXen, Inc. All rights reserved.
247956Sxiuyan.wang@Sun.COM * Use is subject to license terms.
257956Sxiuyan.wang@Sun.COM */
26*8687SJing.Xiong@Sun.COM
277956Sxiuyan.wang@Sun.COM #include <sys/types.h>
287956Sxiuyan.wang@Sun.COM #include <sys/conf.h>
297956Sxiuyan.wang@Sun.COM #include <sys/debug.h>
307956Sxiuyan.wang@Sun.COM #include <sys/stropts.h>
317956Sxiuyan.wang@Sun.COM #include <sys/stream.h>
327956Sxiuyan.wang@Sun.COM #include <sys/strlog.h>
337956Sxiuyan.wang@Sun.COM #include <sys/kmem.h>
347956Sxiuyan.wang@Sun.COM #include <sys/stat.h>
357956Sxiuyan.wang@Sun.COM #include <sys/kstat.h>
367956Sxiuyan.wang@Sun.COM #include <sys/vtrace.h>
377956Sxiuyan.wang@Sun.COM #include <sys/dlpi.h>
387956Sxiuyan.wang@Sun.COM #include <sys/strsun.h>
397956Sxiuyan.wang@Sun.COM #include <sys/ethernet.h>
407956Sxiuyan.wang@Sun.COM #include <sys/modctl.h>
417956Sxiuyan.wang@Sun.COM #include <sys/errno.h>
427956Sxiuyan.wang@Sun.COM #include <sys/dditypes.h>
437956Sxiuyan.wang@Sun.COM #include <sys/ddi.h>
447956Sxiuyan.wang@Sun.COM #include <sys/sunddi.h>
457956Sxiuyan.wang@Sun.COM #include <sys/sysmacros.h>
467956Sxiuyan.wang@Sun.COM #include <sys/pci.h>
477956Sxiuyan.wang@Sun.COM
487956Sxiuyan.wang@Sun.COM #include "unm_nic_hw.h"
497956Sxiuyan.wang@Sun.COM #include "unm_nic.h"
507956Sxiuyan.wang@Sun.COM #include "nic_phan_reg.h"
517956Sxiuyan.wang@Sun.COM #include "nic_cmn.h"
527956Sxiuyan.wang@Sun.COM
537956Sxiuyan.wang@Sun.COM typedef unsigned int nx_rcode_t;
547956Sxiuyan.wang@Sun.COM
557956Sxiuyan.wang@Sun.COM #include "nx_errorcode.h"
567956Sxiuyan.wang@Sun.COM #include "nxhal_nic_interface.h"
577956Sxiuyan.wang@Sun.COM
587956Sxiuyan.wang@Sun.COM #define NXHAL_VERSION 1
597956Sxiuyan.wang@Sun.COM
607956Sxiuyan.wang@Sun.COM #define NX_OS_CRB_RETRY_COUNT 4000
617956Sxiuyan.wang@Sun.COM
627956Sxiuyan.wang@Sun.COM #define NX_CDRP_CLEAR 0x00000000
637956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_BIT 0x80000000
647956Sxiuyan.wang@Sun.COM
657956Sxiuyan.wang@Sun.COM /*
667956Sxiuyan.wang@Sun.COM * All responses must have the NX_CDRP_CMD_BIT cleared
677956Sxiuyan.wang@Sun.COM * in the crb NX_CDRP_CRB_OFFSET.
687956Sxiuyan.wang@Sun.COM */
697956Sxiuyan.wang@Sun.COM #define NX_CDRP_FORM_RSP(rsp) (rsp)
707956Sxiuyan.wang@Sun.COM #define NX_CDRP_IS_RSP(rsp) (((rsp) & NX_CDRP_CMD_BIT) == 0)
717956Sxiuyan.wang@Sun.COM
727956Sxiuyan.wang@Sun.COM #define NX_CDRP_RSP_OK 0x00000001
737956Sxiuyan.wang@Sun.COM #define NX_CDRP_RSP_FAIL 0x00000002
747956Sxiuyan.wang@Sun.COM #define NX_CDRP_RSP_TIMEOUT 0x00000003
757956Sxiuyan.wang@Sun.COM
767956Sxiuyan.wang@Sun.COM /*
777956Sxiuyan.wang@Sun.COM * All commands must have the NX_CDRP_CMD_BIT set in
787956Sxiuyan.wang@Sun.COM * the crb NX_CDRP_CRB_OFFSET.
797956Sxiuyan.wang@Sun.COM */
807956Sxiuyan.wang@Sun.COM #define NX_CDRP_FORM_CMD(cmd) (NX_CDRP_CMD_BIT | (cmd))
817956Sxiuyan.wang@Sun.COM #define NX_CDRP_IS_CMD(cmd) (((cmd) & NX_CDRP_CMD_BIT) != 0)
827956Sxiuyan.wang@Sun.COM
837956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_SUBMIT_CAPABILITIES 0x00000001
847956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_READ_MAX_RDS_PER_CTX 0x00000002
857956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_READ_MAX_SDS_PER_CTX 0x00000003
867956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_READ_MAX_RULES_PER_CTX 0x00000004
877956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_READ_MAX_RX_CTX 0x00000005
887956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_READ_MAX_TX_CTX 0x00000006
897956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_CREATE_RX_CTX 0x00000007
907956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_DESTROY_RX_CTX 0x00000008
917956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_CREATE_TX_CTX 0x00000009
927956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_DESTROY_TX_CTX 0x0000000a
937956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_SETUP_STATISTICS 0x0000000e
947956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_GET_STATISTICS 0x0000000f
957956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_DELETE_STATISTICS 0x00000010
967956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_SET_MTU 0x00000012
977956Sxiuyan.wang@Sun.COM #define NX_CDRP_CMD_MAX 0x00000013
987956Sxiuyan.wang@Sun.COM
997956Sxiuyan.wang@Sun.COM #define NX_DESTROY_CTX_RESET 0
1007956Sxiuyan.wang@Sun.COM #define NX_DESTROY_CTX_D3_RESET 1
1017956Sxiuyan.wang@Sun.COM #define NX_DESTROY_CTX_MAX 2
1027956Sxiuyan.wang@Sun.COM
1037956Sxiuyan.wang@Sun.COM /*
1047956Sxiuyan.wang@Sun.COM * Context state
1057956Sxiuyan.wang@Sun.COM */
1067956Sxiuyan.wang@Sun.COM #define NX_HOST_CTX_STATE_FREED 0
1077956Sxiuyan.wang@Sun.COM #define NX_HOST_CTX_STATE_ALLOCATED 1
1087956Sxiuyan.wang@Sun.COM #define NX_HOST_CTX_STATE_ACTIVE 2
1097956Sxiuyan.wang@Sun.COM #define NX_HOST_CTX_STATE_DISABLED 3
1107956Sxiuyan.wang@Sun.COM #define NX_HOST_CTX_STATE_QUIESCED 4
1117956Sxiuyan.wang@Sun.COM #define NX_HOST_CTX_STATE_MAX 5
1127956Sxiuyan.wang@Sun.COM
1137956Sxiuyan.wang@Sun.COM static int
netxen_api_lock(struct unm_adapter_s * adapter)1147956Sxiuyan.wang@Sun.COM netxen_api_lock(struct unm_adapter_s *adapter)
1157956Sxiuyan.wang@Sun.COM {
1167956Sxiuyan.wang@Sun.COM u32 done = 0, timeout = 0;
1177956Sxiuyan.wang@Sun.COM
1187956Sxiuyan.wang@Sun.COM for (;;) {
1197956Sxiuyan.wang@Sun.COM /* Acquire PCIE HW semaphore5 */
1207956Sxiuyan.wang@Sun.COM unm_nic_read_w0(adapter,
1217956Sxiuyan.wang@Sun.COM UNM_PCIE_REG(PCIE_SEM5_LOCK), &done);
1227956Sxiuyan.wang@Sun.COM
1237956Sxiuyan.wang@Sun.COM if (done == 1)
1247956Sxiuyan.wang@Sun.COM break;
1257956Sxiuyan.wang@Sun.COM
1267956Sxiuyan.wang@Sun.COM if (++timeout >= NX_OS_CRB_RETRY_COUNT) {
1277956Sxiuyan.wang@Sun.COM cmn_err(CE_WARN, "%s: lock timeout.\n", __func__);
1287956Sxiuyan.wang@Sun.COM return (-1);
1297956Sxiuyan.wang@Sun.COM }
1307956Sxiuyan.wang@Sun.COM
1317956Sxiuyan.wang@Sun.COM drv_usecwait(1000);
1327956Sxiuyan.wang@Sun.COM }
1337956Sxiuyan.wang@Sun.COM
1347956Sxiuyan.wang@Sun.COM #if 0
1357956Sxiuyan.wang@Sun.COM unm_nic_reg_write(adapter, NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER);
1367956Sxiuyan.wang@Sun.COM #endif
1377956Sxiuyan.wang@Sun.COM return (0);
1387956Sxiuyan.wang@Sun.COM }
1397956Sxiuyan.wang@Sun.COM
1407956Sxiuyan.wang@Sun.COM static void
netxen_api_unlock(struct unm_adapter_s * adapter)1417956Sxiuyan.wang@Sun.COM netxen_api_unlock(struct unm_adapter_s *adapter)
1427956Sxiuyan.wang@Sun.COM {
1437956Sxiuyan.wang@Sun.COM u32 val;
1447956Sxiuyan.wang@Sun.COM
1457956Sxiuyan.wang@Sun.COM /* Release PCIE HW semaphore5 */
1467956Sxiuyan.wang@Sun.COM unm_nic_read_w0(adapter,
1477956Sxiuyan.wang@Sun.COM UNM_PCIE_REG(PCIE_SEM5_UNLOCK), &val);
1487956Sxiuyan.wang@Sun.COM }
1497956Sxiuyan.wang@Sun.COM
1507956Sxiuyan.wang@Sun.COM static u32
netxen_poll_rsp(struct unm_adapter_s * adapter)1517956Sxiuyan.wang@Sun.COM netxen_poll_rsp(struct unm_adapter_s *adapter)
1527956Sxiuyan.wang@Sun.COM {
1537956Sxiuyan.wang@Sun.COM u32 raw_rsp, rsp = NX_CDRP_RSP_OK;
1547956Sxiuyan.wang@Sun.COM int timeout = 0;
1557956Sxiuyan.wang@Sun.COM
1567956Sxiuyan.wang@Sun.COM do {
1577956Sxiuyan.wang@Sun.COM /* give atleast 1ms for firmware to respond */
1587956Sxiuyan.wang@Sun.COM drv_usecwait(1000);
1597956Sxiuyan.wang@Sun.COM
1607956Sxiuyan.wang@Sun.COM if (++timeout > NX_OS_CRB_RETRY_COUNT)
1617956Sxiuyan.wang@Sun.COM return (NX_CDRP_RSP_TIMEOUT);
1627956Sxiuyan.wang@Sun.COM
1637956Sxiuyan.wang@Sun.COM adapter->unm_nic_hw_read_wx(adapter, NX_CDRP_CRB_OFFSET,
1647956Sxiuyan.wang@Sun.COM &raw_rsp, 4);
1657956Sxiuyan.wang@Sun.COM
1667956Sxiuyan.wang@Sun.COM rsp = LE_TO_HOST_32(raw_rsp);
1677956Sxiuyan.wang@Sun.COM } while (!NX_CDRP_IS_RSP(rsp));
1687956Sxiuyan.wang@Sun.COM
1697956Sxiuyan.wang@Sun.COM return (rsp);
1707956Sxiuyan.wang@Sun.COM }
1717956Sxiuyan.wang@Sun.COM
1727956Sxiuyan.wang@Sun.COM static u32
netxen_issue_cmd(struct unm_adapter_s * adapter,u32 pci_fn,u32 version,u32 arg1,u32 arg2,u32 arg3,u32 cmd)1737956Sxiuyan.wang@Sun.COM netxen_issue_cmd(struct unm_adapter_s *adapter,
1747956Sxiuyan.wang@Sun.COM u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd)
1757956Sxiuyan.wang@Sun.COM {
1767956Sxiuyan.wang@Sun.COM u32 rsp;
1777956Sxiuyan.wang@Sun.COM u32 signature = 0;
1787956Sxiuyan.wang@Sun.COM u32 rcode = NX_RCODE_SUCCESS;
1797956Sxiuyan.wang@Sun.COM
1807956Sxiuyan.wang@Sun.COM signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version);
1817956Sxiuyan.wang@Sun.COM
1827956Sxiuyan.wang@Sun.COM /* Acquire semaphore before accessing CRB */
1837956Sxiuyan.wang@Sun.COM if (netxen_api_lock(adapter))
1847956Sxiuyan.wang@Sun.COM return (NX_RCODE_TIMEOUT);
1857956Sxiuyan.wang@Sun.COM
1867956Sxiuyan.wang@Sun.COM unm_nic_reg_write(adapter, NX_SIGN_CRB_OFFSET,
1877956Sxiuyan.wang@Sun.COM HOST_TO_LE_32(signature));
1887956Sxiuyan.wang@Sun.COM
1897956Sxiuyan.wang@Sun.COM unm_nic_reg_write(adapter, NX_ARG1_CRB_OFFSET,
1907956Sxiuyan.wang@Sun.COM HOST_TO_LE_32(arg1));
1917956Sxiuyan.wang@Sun.COM
1927956Sxiuyan.wang@Sun.COM unm_nic_reg_write(adapter, NX_ARG2_CRB_OFFSET,
1937956Sxiuyan.wang@Sun.COM HOST_TO_LE_32(arg2));
1947956Sxiuyan.wang@Sun.COM
1957956Sxiuyan.wang@Sun.COM unm_nic_reg_write(adapter, NX_ARG3_CRB_OFFSET,
1967956Sxiuyan.wang@Sun.COM HOST_TO_LE_32(arg3));
1977956Sxiuyan.wang@Sun.COM
1987956Sxiuyan.wang@Sun.COM unm_nic_reg_write(adapter, NX_CDRP_CRB_OFFSET,
1997956Sxiuyan.wang@Sun.COM HOST_TO_LE_32(NX_CDRP_FORM_CMD(cmd)));
2007956Sxiuyan.wang@Sun.COM
2017956Sxiuyan.wang@Sun.COM rsp = netxen_poll_rsp(adapter);
2027956Sxiuyan.wang@Sun.COM
2037956Sxiuyan.wang@Sun.COM if (rsp == NX_CDRP_RSP_TIMEOUT) {
2047956Sxiuyan.wang@Sun.COM cmn_err(CE_WARN, "%s: card response timeout.\n",
2057956Sxiuyan.wang@Sun.COM unm_nic_driver_name);
2067956Sxiuyan.wang@Sun.COM
2077956Sxiuyan.wang@Sun.COM rcode = NX_RCODE_TIMEOUT;
2087956Sxiuyan.wang@Sun.COM } else if (rsp == NX_CDRP_RSP_FAIL) {
2097956Sxiuyan.wang@Sun.COM adapter->unm_nic_hw_read_wx(adapter, NX_ARG1_CRB_OFFSET,
2107956Sxiuyan.wang@Sun.COM &rcode, 4);
2117956Sxiuyan.wang@Sun.COM rcode = LE_TO_HOST_32(rcode);
2127956Sxiuyan.wang@Sun.COM
2137956Sxiuyan.wang@Sun.COM cmn_err(CE_WARN, "%s: failed card response code:0x%x\n",
2147956Sxiuyan.wang@Sun.COM unm_nic_driver_name, rcode);
2157956Sxiuyan.wang@Sun.COM }
2167956Sxiuyan.wang@Sun.COM
2177956Sxiuyan.wang@Sun.COM /* Release semaphore */
2187956Sxiuyan.wang@Sun.COM netxen_api_unlock(adapter);
2197956Sxiuyan.wang@Sun.COM
2207956Sxiuyan.wang@Sun.COM return (rcode);
2217956Sxiuyan.wang@Sun.COM }
2227956Sxiuyan.wang@Sun.COM
2237956Sxiuyan.wang@Sun.COM int
nx_fw_cmd_set_mtu(struct unm_adapter_s * adapter,int mtu)2247956Sxiuyan.wang@Sun.COM nx_fw_cmd_set_mtu(struct unm_adapter_s *adapter, int mtu)
2257956Sxiuyan.wang@Sun.COM {
2267956Sxiuyan.wang@Sun.COM u32 rcode = NX_RCODE_SUCCESS;
2277956Sxiuyan.wang@Sun.COM struct unm_recv_context_s *recv_ctx = &adapter->recv_ctx[0];
2287956Sxiuyan.wang@Sun.COM
2297956Sxiuyan.wang@Sun.COM if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
2307956Sxiuyan.wang@Sun.COM rcode = netxen_issue_cmd(adapter,
2317956Sxiuyan.wang@Sun.COM adapter->ahw.pci_func,
2327956Sxiuyan.wang@Sun.COM NXHAL_VERSION,
2337956Sxiuyan.wang@Sun.COM recv_ctx->context_id,
2347956Sxiuyan.wang@Sun.COM mtu,
2357956Sxiuyan.wang@Sun.COM 0,
2367956Sxiuyan.wang@Sun.COM NX_CDRP_CMD_SET_MTU);
2377956Sxiuyan.wang@Sun.COM
2387956Sxiuyan.wang@Sun.COM if (rcode != NX_RCODE_SUCCESS)
2397956Sxiuyan.wang@Sun.COM return (-EIO);
2407956Sxiuyan.wang@Sun.COM
2417956Sxiuyan.wang@Sun.COM return (0);
2427956Sxiuyan.wang@Sun.COM }
2437956Sxiuyan.wang@Sun.COM
2447956Sxiuyan.wang@Sun.COM static int
nx_fw_cmd_create_rx_ctx(struct unm_adapter_s * adapter)2457956Sxiuyan.wang@Sun.COM nx_fw_cmd_create_rx_ctx(struct unm_adapter_s *adapter)
2467956Sxiuyan.wang@Sun.COM {
2477956Sxiuyan.wang@Sun.COM unm_recv_context_t *recv_ctx = &adapter->recv_ctx[0];
2487956Sxiuyan.wang@Sun.COM nx_hostrq_rx_ctx_t *prq;
2497956Sxiuyan.wang@Sun.COM nx_cardrsp_rx_ctx_t *prsp;
2507956Sxiuyan.wang@Sun.COM nx_hostrq_rds_ring_t *prq_rds;
2517956Sxiuyan.wang@Sun.COM nx_hostrq_sds_ring_t *prq_sds;
2527956Sxiuyan.wang@Sun.COM nx_cardrsp_rds_ring_t *prsp_rds;
2537956Sxiuyan.wang@Sun.COM nx_cardrsp_sds_ring_t *prsp_sds;
2547956Sxiuyan.wang@Sun.COM unm_rcv_desc_ctx_t *rcv_desc;
2557956Sxiuyan.wang@Sun.COM ddi_dma_cookie_t cookie;
2567956Sxiuyan.wang@Sun.COM ddi_dma_handle_t rqdhdl, rsdhdl;
2577956Sxiuyan.wang@Sun.COM ddi_acc_handle_t rqahdl, rsahdl;
2587956Sxiuyan.wang@Sun.COM uint64_t hostrq_phys_addr, cardrsp_phys_addr;
2597956Sxiuyan.wang@Sun.COM u64 phys_addr;
2607956Sxiuyan.wang@Sun.COM u32 cap, reg;
2617956Sxiuyan.wang@Sun.COM size_t rq_size, rsp_size;
2627956Sxiuyan.wang@Sun.COM void *addr;
2637956Sxiuyan.wang@Sun.COM int i, nrds_rings, nsds_rings, err;
2647956Sxiuyan.wang@Sun.COM
2657956Sxiuyan.wang@Sun.COM /* only one sds ring for now */
2667956Sxiuyan.wang@Sun.COM nrds_rings = adapter->max_rds_rings;
2677956Sxiuyan.wang@Sun.COM nsds_rings = 1;
2687956Sxiuyan.wang@Sun.COM
2697956Sxiuyan.wang@Sun.COM rq_size =
2707956Sxiuyan.wang@Sun.COM SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings);
2717956Sxiuyan.wang@Sun.COM rsp_size =
2727956Sxiuyan.wang@Sun.COM SIZEOF_CARDRSP_RX(nx_cardrsp_rx_ctx_t, nrds_rings, nsds_rings);
2737956Sxiuyan.wang@Sun.COM
2747956Sxiuyan.wang@Sun.COM if (unm_pci_alloc_consistent(adapter, rq_size, (caddr_t *)&addr,
2757956Sxiuyan.wang@Sun.COM &cookie, &rqdhdl, &rqahdl) != DDI_SUCCESS)
2767956Sxiuyan.wang@Sun.COM return (-ENOMEM);
2777956Sxiuyan.wang@Sun.COM hostrq_phys_addr = cookie.dmac_laddress;
2787956Sxiuyan.wang@Sun.COM prq = (nx_hostrq_rx_ctx_t *)addr;
2797956Sxiuyan.wang@Sun.COM
2807956Sxiuyan.wang@Sun.COM if (unm_pci_alloc_consistent(adapter, rsp_size, (caddr_t *)&addr,
2817956Sxiuyan.wang@Sun.COM &cookie, &rsdhdl, &rsahdl) != DDI_SUCCESS) {
2827956Sxiuyan.wang@Sun.COM err = -ENOMEM;
2837956Sxiuyan.wang@Sun.COM goto out_free_rq;
2847956Sxiuyan.wang@Sun.COM }
2857956Sxiuyan.wang@Sun.COM cardrsp_phys_addr = cookie.dmac_laddress;
2867956Sxiuyan.wang@Sun.COM prsp = (nx_cardrsp_rx_ctx_t *)addr;
2877956Sxiuyan.wang@Sun.COM
2887956Sxiuyan.wang@Sun.COM prq->host_rsp_dma_addr = HOST_TO_LE_64(cardrsp_phys_addr);
2897956Sxiuyan.wang@Sun.COM
2907956Sxiuyan.wang@Sun.COM cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN);
2917956Sxiuyan.wang@Sun.COM cap |= (NX_CAP0_JUMBO_CONTIGUOUS);
2927956Sxiuyan.wang@Sun.COM
2937956Sxiuyan.wang@Sun.COM prq->capabilities[0] = HOST_TO_LE_32(cap);
2947956Sxiuyan.wang@Sun.COM prq->host_int_crb_mode =
2957956Sxiuyan.wang@Sun.COM HOST_TO_LE_32(NX_HOST_INT_CRB_MODE_SHARED);
2967956Sxiuyan.wang@Sun.COM prq->host_rds_crb_mode =
2977956Sxiuyan.wang@Sun.COM HOST_TO_LE_32(NX_HOST_RDS_CRB_MODE_UNIQUE);
2987956Sxiuyan.wang@Sun.COM
2997956Sxiuyan.wang@Sun.COM prq->num_rds_rings = HOST_TO_LE_16(nrds_rings);
3007956Sxiuyan.wang@Sun.COM prq->num_sds_rings = HOST_TO_LE_16(nsds_rings);
3017956Sxiuyan.wang@Sun.COM prq->rds_ring_offset = 0;
3027956Sxiuyan.wang@Sun.COM prq->sds_ring_offset = prq->rds_ring_offset +
3037956Sxiuyan.wang@Sun.COM (sizeof (nx_hostrq_rds_ring_t) * nrds_rings);
3047956Sxiuyan.wang@Sun.COM
305*8687SJing.Xiong@Sun.COM prq_rds = (nx_hostrq_rds_ring_t *)(uintptr_t)((char *)prq +
306*8687SJing.Xiong@Sun.COM sizeof (*prq) + prq->rds_ring_offset);
3077956Sxiuyan.wang@Sun.COM
3087956Sxiuyan.wang@Sun.COM for (i = 0; i < nrds_rings; i++) {
3097956Sxiuyan.wang@Sun.COM rcv_desc = &recv_ctx->rcv_desc[i];
3107956Sxiuyan.wang@Sun.COM
3117956Sxiuyan.wang@Sun.COM prq_rds[i].host_phys_addr = HOST_TO_LE_64(rcv_desc->phys_addr);
3127956Sxiuyan.wang@Sun.COM prq_rds[i].ring_size = HOST_TO_LE_32(rcv_desc->MaxRxDescCount);
3137956Sxiuyan.wang@Sun.COM prq_rds[i].ring_kind = HOST_TO_LE_32(i);
3147956Sxiuyan.wang@Sun.COM prq_rds[i].buff_size = HOST_TO_LE_64(rcv_desc->dma_size);
3157956Sxiuyan.wang@Sun.COM }
3167956Sxiuyan.wang@Sun.COM
317*8687SJing.Xiong@Sun.COM prq_sds = (nx_hostrq_sds_ring_t *)(uintptr_t)((char *)prq +
318*8687SJing.Xiong@Sun.COM sizeof (*prq) + prq->sds_ring_offset);
3197956Sxiuyan.wang@Sun.COM
3207956Sxiuyan.wang@Sun.COM prq_sds[0].host_phys_addr =
3217956Sxiuyan.wang@Sun.COM HOST_TO_LE_64(recv_ctx->rcvStatusDesc_physAddr);
3227956Sxiuyan.wang@Sun.COM prq_sds[0].ring_size = HOST_TO_LE_32(adapter->MaxRxDescCount);
3237956Sxiuyan.wang@Sun.COM /* only one msix vector for now */
3247956Sxiuyan.wang@Sun.COM prq_sds[0].msi_index = HOST_TO_LE_32(0);
3257956Sxiuyan.wang@Sun.COM
3267956Sxiuyan.wang@Sun.COM /* now byteswap offsets */
3277956Sxiuyan.wang@Sun.COM prq->rds_ring_offset = HOST_TO_LE_32(prq->rds_ring_offset);
3287956Sxiuyan.wang@Sun.COM prq->sds_ring_offset = HOST_TO_LE_32(prq->sds_ring_offset);
3297956Sxiuyan.wang@Sun.COM
3307956Sxiuyan.wang@Sun.COM phys_addr = hostrq_phys_addr;
3317956Sxiuyan.wang@Sun.COM err = netxen_issue_cmd(adapter,
3327956Sxiuyan.wang@Sun.COM adapter->ahw.pci_func,
3337956Sxiuyan.wang@Sun.COM NXHAL_VERSION,
3347956Sxiuyan.wang@Sun.COM (u32)(phys_addr >> 32),
3357956Sxiuyan.wang@Sun.COM (u32)(phys_addr & 0xffffffff),
3367956Sxiuyan.wang@Sun.COM rq_size,
3377956Sxiuyan.wang@Sun.COM NX_CDRP_CMD_CREATE_RX_CTX);
3387956Sxiuyan.wang@Sun.COM if (err) {
3397956Sxiuyan.wang@Sun.COM cmn_err(CE_WARN, "Failed to create rx ctx in firmware%d\n",
3407956Sxiuyan.wang@Sun.COM err);
3417956Sxiuyan.wang@Sun.COM goto out_free_rsp;
3427956Sxiuyan.wang@Sun.COM }
3437956Sxiuyan.wang@Sun.COM
3447956Sxiuyan.wang@Sun.COM
345*8687SJing.Xiong@Sun.COM prsp_rds = (nx_cardrsp_rds_ring_t *)(uintptr_t)((char *)prsp +
346*8687SJing.Xiong@Sun.COM sizeof (*prsp) + prsp->rds_ring_offset);
3477956Sxiuyan.wang@Sun.COM
3487956Sxiuyan.wang@Sun.COM for (i = 0; i < LE_TO_HOST_32(prsp->num_rds_rings); i++) {
3497956Sxiuyan.wang@Sun.COM rcv_desc = &recv_ctx->rcv_desc[i];
3507956Sxiuyan.wang@Sun.COM
3517956Sxiuyan.wang@Sun.COM reg = LE_TO_HOST_32(prsp_rds[i].host_producer_crb);
3527956Sxiuyan.wang@Sun.COM rcv_desc->host_rx_producer = UNM_NIC_REG(reg - 0x200);
3537956Sxiuyan.wang@Sun.COM }
3547956Sxiuyan.wang@Sun.COM
355*8687SJing.Xiong@Sun.COM prsp_sds = (nx_cardrsp_sds_ring_t *)(uintptr_t)((char *)prsp +
356*8687SJing.Xiong@Sun.COM sizeof (*prsp) + prsp->sds_ring_offset);
3577956Sxiuyan.wang@Sun.COM reg = LE_TO_HOST_32(prsp_sds[0].host_consumer_crb);
3587956Sxiuyan.wang@Sun.COM recv_ctx->host_sds_consumer = UNM_NIC_REG(reg - 0x200);
3597956Sxiuyan.wang@Sun.COM
3607956Sxiuyan.wang@Sun.COM reg = LE_TO_HOST_32(prsp_sds[0].interrupt_crb);
3617956Sxiuyan.wang@Sun.COM adapter->interrupt_crb = UNM_NIC_REG(reg - 0x200);
3627956Sxiuyan.wang@Sun.COM
3637956Sxiuyan.wang@Sun.COM recv_ctx->state = LE_TO_HOST_32(prsp->host_ctx_state);
3647956Sxiuyan.wang@Sun.COM recv_ctx->context_id = LE_TO_HOST_16(prsp->context_id);
3657956Sxiuyan.wang@Sun.COM recv_ctx->virt_port = LE_TO_HOST_16(prsp->virt_port);
3667956Sxiuyan.wang@Sun.COM
3677956Sxiuyan.wang@Sun.COM out_free_rsp:
3687956Sxiuyan.wang@Sun.COM unm_pci_free_consistent(&rsdhdl, &rsahdl);
3697956Sxiuyan.wang@Sun.COM out_free_rq:
3707956Sxiuyan.wang@Sun.COM unm_pci_free_consistent(&rqdhdl, &rqahdl);
3717956Sxiuyan.wang@Sun.COM return (err);
3727956Sxiuyan.wang@Sun.COM }
3737956Sxiuyan.wang@Sun.COM
3747956Sxiuyan.wang@Sun.COM static void
nx_fw_cmd_destroy_rx_ctx(struct unm_adapter_s * adapter)3757956Sxiuyan.wang@Sun.COM nx_fw_cmd_destroy_rx_ctx(struct unm_adapter_s *adapter)
3767956Sxiuyan.wang@Sun.COM {
3777956Sxiuyan.wang@Sun.COM struct unm_recv_context_s *recv_ctx = &adapter->recv_ctx[0];
3787956Sxiuyan.wang@Sun.COM
3797956Sxiuyan.wang@Sun.COM if (netxen_issue_cmd(adapter,
3807956Sxiuyan.wang@Sun.COM adapter->ahw.pci_func,
3817956Sxiuyan.wang@Sun.COM NXHAL_VERSION,
3827956Sxiuyan.wang@Sun.COM recv_ctx->context_id,
3837956Sxiuyan.wang@Sun.COM NX_DESTROY_CTX_RESET,
3847956Sxiuyan.wang@Sun.COM 0,
3857956Sxiuyan.wang@Sun.COM NX_CDRP_CMD_DESTROY_RX_CTX)) {
3867956Sxiuyan.wang@Sun.COM
3877956Sxiuyan.wang@Sun.COM cmn_err(CE_WARN, "%s: Failed to destroy rx ctx in firmware\n",
3887956Sxiuyan.wang@Sun.COM unm_nic_driver_name);
3897956Sxiuyan.wang@Sun.COM }
3907956Sxiuyan.wang@Sun.COM }
3917956Sxiuyan.wang@Sun.COM
3927956Sxiuyan.wang@Sun.COM static int
nx_fw_cmd_create_tx_ctx(struct unm_adapter_s * adapter)3937956Sxiuyan.wang@Sun.COM nx_fw_cmd_create_tx_ctx(struct unm_adapter_s *adapter)
3947956Sxiuyan.wang@Sun.COM {
3957956Sxiuyan.wang@Sun.COM nx_hostrq_tx_ctx_t *prq;
3967956Sxiuyan.wang@Sun.COM nx_hostrq_cds_ring_t *prq_cds;
3977956Sxiuyan.wang@Sun.COM nx_cardrsp_tx_ctx_t *prsp;
3987956Sxiuyan.wang@Sun.COM ddi_dma_cookie_t cookie;
3997956Sxiuyan.wang@Sun.COM ddi_dma_handle_t rqdhdl, rsdhdl;
4007956Sxiuyan.wang@Sun.COM ddi_acc_handle_t rqahdl, rsahdl;
4017956Sxiuyan.wang@Sun.COM void *rq_addr, *rsp_addr;
4027956Sxiuyan.wang@Sun.COM size_t rq_size, rsp_size;
4037956Sxiuyan.wang@Sun.COM u32 temp;
4047956Sxiuyan.wang@Sun.COM int err = 0;
4057956Sxiuyan.wang@Sun.COM u64 offset, phys_addr;
4067956Sxiuyan.wang@Sun.COM uint64_t rq_phys_addr, rsp_phys_addr;
4077956Sxiuyan.wang@Sun.COM
4087956Sxiuyan.wang@Sun.COM rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
4097956Sxiuyan.wang@Sun.COM if (unm_pci_alloc_consistent(adapter, rq_size, (caddr_t *)&rq_addr,
4107956Sxiuyan.wang@Sun.COM &cookie, &rqdhdl, &rqahdl) != DDI_SUCCESS)
4117956Sxiuyan.wang@Sun.COM return (-ENOMEM);
4127956Sxiuyan.wang@Sun.COM rq_phys_addr = cookie.dmac_laddress;
4137956Sxiuyan.wang@Sun.COM
4147956Sxiuyan.wang@Sun.COM rsp_size = SIZEOF_CARDRSP_TX(nx_cardrsp_tx_ctx_t);
4157956Sxiuyan.wang@Sun.COM if (unm_pci_alloc_consistent(adapter, rsp_size, (caddr_t *)&rsp_addr,
4167956Sxiuyan.wang@Sun.COM &cookie, &rsdhdl, &rsahdl) != DDI_SUCCESS) {
4177956Sxiuyan.wang@Sun.COM err = -ENOMEM;
4187956Sxiuyan.wang@Sun.COM goto out_free_rq;
4197956Sxiuyan.wang@Sun.COM }
4207956Sxiuyan.wang@Sun.COM rsp_phys_addr = cookie.dmac_laddress;
4217956Sxiuyan.wang@Sun.COM
4227956Sxiuyan.wang@Sun.COM (void) memset(rq_addr, 0, rq_size);
4237956Sxiuyan.wang@Sun.COM prq = (nx_hostrq_tx_ctx_t *)rq_addr;
4247956Sxiuyan.wang@Sun.COM
4257956Sxiuyan.wang@Sun.COM (void) memset(rsp_addr, 0, rsp_size);
4267956Sxiuyan.wang@Sun.COM prsp = (nx_cardrsp_tx_ctx_t *)rsp_addr;
4277956Sxiuyan.wang@Sun.COM
4287956Sxiuyan.wang@Sun.COM prq->host_rsp_dma_addr = HOST_TO_LE_64(rsp_phys_addr);
4297956Sxiuyan.wang@Sun.COM
4307956Sxiuyan.wang@Sun.COM temp = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN);
4317956Sxiuyan.wang@Sun.COM prq->capabilities[0] = HOST_TO_LE_32(temp);
4327956Sxiuyan.wang@Sun.COM
4337956Sxiuyan.wang@Sun.COM prq->host_int_crb_mode =
4347956Sxiuyan.wang@Sun.COM HOST_TO_LE_32(NX_HOST_INT_CRB_MODE_SHARED);
4357956Sxiuyan.wang@Sun.COM
4367956Sxiuyan.wang@Sun.COM prq->interrupt_ctl = 0;
4377956Sxiuyan.wang@Sun.COM prq->msi_index = 0;
4387956Sxiuyan.wang@Sun.COM
4397956Sxiuyan.wang@Sun.COM prq->dummy_dma_addr = HOST_TO_LE_64(adapter->dummy_dma.phys_addr);
4407956Sxiuyan.wang@Sun.COM
4417956Sxiuyan.wang@Sun.COM offset = adapter->ctxDesc_physAddr + sizeof (RingContext);
4427956Sxiuyan.wang@Sun.COM prq->cmd_cons_dma_addr = HOST_TO_LE_64(offset);
4437956Sxiuyan.wang@Sun.COM
4447956Sxiuyan.wang@Sun.COM prq_cds = &prq->cds_ring;
4457956Sxiuyan.wang@Sun.COM
4467956Sxiuyan.wang@Sun.COM prq_cds->host_phys_addr =
4477956Sxiuyan.wang@Sun.COM HOST_TO_LE_64(adapter->ahw.cmdDesc_physAddr);
4487956Sxiuyan.wang@Sun.COM
4497956Sxiuyan.wang@Sun.COM prq_cds->ring_size = HOST_TO_LE_32(adapter->MaxTxDescCount);
4507956Sxiuyan.wang@Sun.COM
4517956Sxiuyan.wang@Sun.COM phys_addr = rq_phys_addr;
4527956Sxiuyan.wang@Sun.COM err = netxen_issue_cmd(adapter,
4537956Sxiuyan.wang@Sun.COM adapter->ahw.pci_func,
4547956Sxiuyan.wang@Sun.COM NXHAL_VERSION,
4557956Sxiuyan.wang@Sun.COM (u32)(phys_addr >> 32),
4567956Sxiuyan.wang@Sun.COM ((u32)phys_addr & 0xffffffff),
4577956Sxiuyan.wang@Sun.COM rq_size,
4587956Sxiuyan.wang@Sun.COM NX_CDRP_CMD_CREATE_TX_CTX);
4597956Sxiuyan.wang@Sun.COM
4607956Sxiuyan.wang@Sun.COM if (err == NX_RCODE_SUCCESS) {
4617956Sxiuyan.wang@Sun.COM temp = LE_TO_HOST_32(prsp->cds_ring.host_producer_crb);
4627956Sxiuyan.wang@Sun.COM adapter->crb_addr_cmd_producer =
4637956Sxiuyan.wang@Sun.COM UNM_NIC_REG(temp - 0x200);
4647956Sxiuyan.wang@Sun.COM #if 0
4657956Sxiuyan.wang@Sun.COM adapter->tx_state =
4667956Sxiuyan.wang@Sun.COM LE_TO_HOST_32(prsp->host_ctx_state);
4677956Sxiuyan.wang@Sun.COM #endif
4687956Sxiuyan.wang@Sun.COM adapter->tx_context_id =
4697956Sxiuyan.wang@Sun.COM LE_TO_HOST_16(prsp->context_id);
4707956Sxiuyan.wang@Sun.COM } else {
4717956Sxiuyan.wang@Sun.COM cmn_err(CE_WARN, "Failed to create tx ctx in firmware%d\n",
4727956Sxiuyan.wang@Sun.COM err);
4737956Sxiuyan.wang@Sun.COM err = -EIO;
4747956Sxiuyan.wang@Sun.COM }
4757956Sxiuyan.wang@Sun.COM
4767956Sxiuyan.wang@Sun.COM unm_pci_free_consistent(&rsdhdl, &rsahdl);
4777956Sxiuyan.wang@Sun.COM
4787956Sxiuyan.wang@Sun.COM out_free_rq:
4797956Sxiuyan.wang@Sun.COM unm_pci_free_consistent(&rqdhdl, &rqahdl);
4807956Sxiuyan.wang@Sun.COM
4817956Sxiuyan.wang@Sun.COM return (err);
4827956Sxiuyan.wang@Sun.COM }
4837956Sxiuyan.wang@Sun.COM
4847956Sxiuyan.wang@Sun.COM static void
nx_fw_cmd_destroy_tx_ctx(struct unm_adapter_s * adapter)4857956Sxiuyan.wang@Sun.COM nx_fw_cmd_destroy_tx_ctx(struct unm_adapter_s *adapter)
4867956Sxiuyan.wang@Sun.COM {
4877956Sxiuyan.wang@Sun.COM if (netxen_issue_cmd(adapter,
4887956Sxiuyan.wang@Sun.COM adapter->ahw.pci_func,
4897956Sxiuyan.wang@Sun.COM NXHAL_VERSION,
4907956Sxiuyan.wang@Sun.COM adapter->tx_context_id,
4917956Sxiuyan.wang@Sun.COM NX_DESTROY_CTX_RESET,
4927956Sxiuyan.wang@Sun.COM 0,
4937956Sxiuyan.wang@Sun.COM NX_CDRP_CMD_DESTROY_TX_CTX)) {
4947956Sxiuyan.wang@Sun.COM
4957956Sxiuyan.wang@Sun.COM cmn_err(CE_WARN, "%s: Failed to destroy tx ctx in firmware\n",
4967956Sxiuyan.wang@Sun.COM unm_nic_driver_name);
4977956Sxiuyan.wang@Sun.COM }
4987956Sxiuyan.wang@Sun.COM }
4997956Sxiuyan.wang@Sun.COM
5007956Sxiuyan.wang@Sun.COM static u64 ctx_addr_sig_regs[][3] = {
5017956Sxiuyan.wang@Sun.COM {UNM_NIC_REG(0x188), UNM_NIC_REG(0x18c), UNM_NIC_REG(0x1c0)},
5027956Sxiuyan.wang@Sun.COM {UNM_NIC_REG(0x190), UNM_NIC_REG(0x194), UNM_NIC_REG(0x1c4)},
5037956Sxiuyan.wang@Sun.COM {UNM_NIC_REG(0x198), UNM_NIC_REG(0x19c), UNM_NIC_REG(0x1c8)},
5047956Sxiuyan.wang@Sun.COM {UNM_NIC_REG(0x1a0), UNM_NIC_REG(0x1a4), UNM_NIC_REG(0x1cc)}
5057956Sxiuyan.wang@Sun.COM };
5067956Sxiuyan.wang@Sun.COM
5077956Sxiuyan.wang@Sun.COM #define CRB_CTX_ADDR_REG_LO(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][0])
5087956Sxiuyan.wang@Sun.COM #define CRB_CTX_ADDR_REG_HI(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][2])
5097956Sxiuyan.wang@Sun.COM #define CRB_CTX_SIGNATURE_REG(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][1])
5107956Sxiuyan.wang@Sun.COM
5117956Sxiuyan.wang@Sun.COM struct netxen_recv_crb {
5127956Sxiuyan.wang@Sun.COM u32 crb_rcv_producer[NUM_RCV_DESC_RINGS];
5137956Sxiuyan.wang@Sun.COM u32 crb_sts_consumer;
5147956Sxiuyan.wang@Sun.COM };
5157956Sxiuyan.wang@Sun.COM
5167956Sxiuyan.wang@Sun.COM static struct netxen_recv_crb recv_crb_registers[] = {
5177956Sxiuyan.wang@Sun.COM /* Instance 0 */
5187956Sxiuyan.wang@Sun.COM {
5197956Sxiuyan.wang@Sun.COM /* crb_rcv_producer: */
5207956Sxiuyan.wang@Sun.COM {
5217956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x100),
5227956Sxiuyan.wang@Sun.COM /* Jumbo frames */
5237956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x110),
5247956Sxiuyan.wang@Sun.COM /* LRO */
5257956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x120)
5267956Sxiuyan.wang@Sun.COM },
5277956Sxiuyan.wang@Sun.COM /* crb_sts_consumer: */
5287956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x138),
5297956Sxiuyan.wang@Sun.COM },
5307956Sxiuyan.wang@Sun.COM /* Instance 1 */
5317956Sxiuyan.wang@Sun.COM {
5327956Sxiuyan.wang@Sun.COM /* crb_rcv_producer: */
5337956Sxiuyan.wang@Sun.COM {
5347956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x144),
5357956Sxiuyan.wang@Sun.COM /* Jumbo frames */
5367956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x154),
5377956Sxiuyan.wang@Sun.COM /* LRO */
5387956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x164)
5397956Sxiuyan.wang@Sun.COM },
5407956Sxiuyan.wang@Sun.COM /* crb_sts_consumer: */
5417956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x17c),
5427956Sxiuyan.wang@Sun.COM },
5437956Sxiuyan.wang@Sun.COM /* Instance 2 */
5447956Sxiuyan.wang@Sun.COM {
5457956Sxiuyan.wang@Sun.COM /* crb_rcv_producer: */
5467956Sxiuyan.wang@Sun.COM {
5477956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x1d8),
5487956Sxiuyan.wang@Sun.COM /* Jumbo frames */
5497956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x1f8),
5507956Sxiuyan.wang@Sun.COM /* LRO */
5517956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x208)
5527956Sxiuyan.wang@Sun.COM },
5537956Sxiuyan.wang@Sun.COM /* crb_sts_consumer: */
5547956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x220),
5557956Sxiuyan.wang@Sun.COM },
5567956Sxiuyan.wang@Sun.COM /* Instance 3 */
5577956Sxiuyan.wang@Sun.COM {
5587956Sxiuyan.wang@Sun.COM /* crb_rcv_producer: */
5597956Sxiuyan.wang@Sun.COM {
5607956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x22c),
5617956Sxiuyan.wang@Sun.COM /* Jumbo frames */
5627956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x23c),
5637956Sxiuyan.wang@Sun.COM /* LRO */
5647956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x24c)
5657956Sxiuyan.wang@Sun.COM },
5667956Sxiuyan.wang@Sun.COM /* crb_sts_consumer: */
5677956Sxiuyan.wang@Sun.COM UNM_NIC_REG(0x264),
5687956Sxiuyan.wang@Sun.COM },
5697956Sxiuyan.wang@Sun.COM };
5707956Sxiuyan.wang@Sun.COM
5717956Sxiuyan.wang@Sun.COM static uint32_t sw_int_mask[4] = {
5727956Sxiuyan.wang@Sun.COM CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1,
5737956Sxiuyan.wang@Sun.COM CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3
5747956Sxiuyan.wang@Sun.COM };
5757956Sxiuyan.wang@Sun.COM
5767956Sxiuyan.wang@Sun.COM static int
netxen_init_old_ctx(struct unm_adapter_s * adapter)5777956Sxiuyan.wang@Sun.COM netxen_init_old_ctx(struct unm_adapter_s *adapter)
5787956Sxiuyan.wang@Sun.COM {
5797956Sxiuyan.wang@Sun.COM hardware_context *hw = &adapter->ahw;
5807956Sxiuyan.wang@Sun.COM struct unm_recv_context_s *recv_ctx;
5817956Sxiuyan.wang@Sun.COM unm_rcv_desc_ctx_t *rcv_desc;
5827956Sxiuyan.wang@Sun.COM int ctx, ring, func_id = adapter->portnum;
5837956Sxiuyan.wang@Sun.COM unsigned int temp;
5847956Sxiuyan.wang@Sun.COM
5857956Sxiuyan.wang@Sun.COM adapter->ctxDesc->CmdRingAddrLo = hw->cmdDesc_physAddr & 0xffffffffUL;
5867956Sxiuyan.wang@Sun.COM adapter->ctxDesc->CmdRingAddrHi = ((U64)hw->cmdDesc_physAddr >> 32);
5877956Sxiuyan.wang@Sun.COM adapter->ctxDesc->CmdRingSize = adapter->MaxTxDescCount;
5887956Sxiuyan.wang@Sun.COM
5897956Sxiuyan.wang@Sun.COM for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
5907956Sxiuyan.wang@Sun.COM recv_ctx = &adapter->recv_ctx[ctx];
5917956Sxiuyan.wang@Sun.COM
5927956Sxiuyan.wang@Sun.COM for (ring = 0; ring < adapter->max_rds_rings; ring++) {
5937956Sxiuyan.wang@Sun.COM rcv_desc = &recv_ctx->rcv_desc[ring];
5947956Sxiuyan.wang@Sun.COM
5957956Sxiuyan.wang@Sun.COM adapter->ctxDesc->RcvContext[ring].RcvRingAddrLo =
5967956Sxiuyan.wang@Sun.COM rcv_desc->phys_addr & 0xffffffffUL;
5977956Sxiuyan.wang@Sun.COM adapter->ctxDesc->RcvContext[ring].RcvRingAddrHi =
5987956Sxiuyan.wang@Sun.COM ((U64)rcv_desc->phys_addr>>32);
5997956Sxiuyan.wang@Sun.COM adapter->ctxDesc->RcvContext[ring].RcvRingSize =
6007956Sxiuyan.wang@Sun.COM rcv_desc->MaxRxDescCount;
6017956Sxiuyan.wang@Sun.COM
6027956Sxiuyan.wang@Sun.COM rcv_desc->host_rx_producer =
6037956Sxiuyan.wang@Sun.COM recv_crb_registers[adapter->portnum].
6047956Sxiuyan.wang@Sun.COM crb_rcv_producer[ring];
6057956Sxiuyan.wang@Sun.COM }
6067956Sxiuyan.wang@Sun.COM
6077956Sxiuyan.wang@Sun.COM adapter->ctxDesc->StsRingAddrLo =
6087956Sxiuyan.wang@Sun.COM recv_ctx->rcvStatusDesc_physAddr & 0xffffffff;
6097956Sxiuyan.wang@Sun.COM adapter->ctxDesc->StsRingAddrHi =
6107956Sxiuyan.wang@Sun.COM recv_ctx->rcvStatusDesc_physAddr >> 32;
6117956Sxiuyan.wang@Sun.COM adapter->ctxDesc->StsRingSize = adapter->MaxRxDescCount;
6127956Sxiuyan.wang@Sun.COM
6137956Sxiuyan.wang@Sun.COM recv_ctx->host_sds_consumer =
6147956Sxiuyan.wang@Sun.COM recv_crb_registers[adapter->portnum].crb_sts_consumer;
6157956Sxiuyan.wang@Sun.COM }
6167956Sxiuyan.wang@Sun.COM
6177956Sxiuyan.wang@Sun.COM adapter->interrupt_crb = sw_int_mask[adapter->portnum];
6187956Sxiuyan.wang@Sun.COM
6197956Sxiuyan.wang@Sun.COM temp = lower32(adapter->ctxDesc_physAddr);
6207956Sxiuyan.wang@Sun.COM adapter->unm_nic_hw_write_wx(adapter, CRB_CTX_ADDR_REG_LO(func_id),
6217956Sxiuyan.wang@Sun.COM &temp, 4);
6227956Sxiuyan.wang@Sun.COM temp = upper32(adapter->ctxDesc_physAddr);
6237956Sxiuyan.wang@Sun.COM adapter->unm_nic_hw_write_wx(adapter, CRB_CTX_ADDR_REG_HI(func_id),
6247956Sxiuyan.wang@Sun.COM &temp, 4);
6257956Sxiuyan.wang@Sun.COM temp = UNM_CTX_SIGNATURE | func_id;
6267956Sxiuyan.wang@Sun.COM adapter->unm_nic_hw_write_wx(adapter, CRB_CTX_SIGNATURE_REG(func_id),
6277956Sxiuyan.wang@Sun.COM &temp, 4);
6287956Sxiuyan.wang@Sun.COM
6297956Sxiuyan.wang@Sun.COM return (0);
6307956Sxiuyan.wang@Sun.COM }
6317956Sxiuyan.wang@Sun.COM
6327956Sxiuyan.wang@Sun.COM void
netxen_destroy_rxtx(struct unm_adapter_s * adapter)6337956Sxiuyan.wang@Sun.COM netxen_destroy_rxtx(struct unm_adapter_s *adapter)
6347956Sxiuyan.wang@Sun.COM {
6357956Sxiuyan.wang@Sun.COM if (adapter->fw_major >= 4) {
6367956Sxiuyan.wang@Sun.COM nx_fw_cmd_destroy_tx_ctx(adapter);
6377956Sxiuyan.wang@Sun.COM nx_fw_cmd_destroy_rx_ctx(adapter);
6387956Sxiuyan.wang@Sun.COM }
6397956Sxiuyan.wang@Sun.COM }
6407956Sxiuyan.wang@Sun.COM
6417956Sxiuyan.wang@Sun.COM int
netxen_create_rxtx(struct unm_adapter_s * adapter)6427956Sxiuyan.wang@Sun.COM netxen_create_rxtx(struct unm_adapter_s *adapter)
6437956Sxiuyan.wang@Sun.COM {
6447956Sxiuyan.wang@Sun.COM int err;
6457956Sxiuyan.wang@Sun.COM
6467956Sxiuyan.wang@Sun.COM if (adapter->fw_major >= 4) {
6477956Sxiuyan.wang@Sun.COM err = nx_fw_cmd_create_rx_ctx(adapter);
6487956Sxiuyan.wang@Sun.COM if (err)
6497956Sxiuyan.wang@Sun.COM return (err);
6507956Sxiuyan.wang@Sun.COM err = nx_fw_cmd_create_tx_ctx(adapter);
6517956Sxiuyan.wang@Sun.COM if (err)
6527956Sxiuyan.wang@Sun.COM nx_fw_cmd_destroy_rx_ctx(adapter);
6537956Sxiuyan.wang@Sun.COM return (err);
6547956Sxiuyan.wang@Sun.COM } else {
6557956Sxiuyan.wang@Sun.COM return (netxen_init_old_ctx(adapter));
6567956Sxiuyan.wang@Sun.COM }
6577956Sxiuyan.wang@Sun.COM }
658