1*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
2*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * CDDL HEADER START
3*9a5557fdSlucy wang - Sun Microsystems - Beijing China  *
4*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * The contents of this file are subject to the terms of the
5*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * Common Development and Distribution License (the "License").
6*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * You may not use this file except in compliance with the License.
7*9a5557fdSlucy wang - Sun Microsystems - Beijing China  *
8*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * or http://www.opensolaris.org/os/licensing.
10*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * See the License for the specific language governing permissions
11*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * and limitations under the License.
12*9a5557fdSlucy wang - Sun Microsystems - Beijing China  *
13*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * When distributing Covered Code, include this CDDL HEADER in each
14*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * If applicable, add the following below this CDDL HEADER, with the
16*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * fields enclosed by brackets "[]" replaced with your own identifying
17*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * information: Portions Copyright [yyyy] [name of copyright owner]
18*9a5557fdSlucy wang - Sun Microsystems - Beijing China  *
19*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * CDDL HEADER END
20*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
21*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
22*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * Copyright 2008 NetXen, Inc.  All rights reserved.
23*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * Use is subject to license terms.
24*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
25*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
26*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
27*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * Use is subject to license terms.
28*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
29*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/types.h>
30*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/conf.h>
31*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/debug.h>
32*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/stropts.h>
33*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/stream.h>
34*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/strlog.h>
35*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/kmem.h>
36*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/stat.h>
37*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/kstat.h>
38*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/vtrace.h>
39*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/dlpi.h>
40*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/strsun.h>
41*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/ethernet.h>
42*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/modctl.h>
43*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/errno.h>
44*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/dditypes.h>
45*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/ddi.h>
46*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/sunddi.h>
47*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/sysmacros.h>
48*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/pci.h>
49*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
50*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/gld.h>
51*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <netinet/in.h>
52*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <inet/ip.h>
53*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <inet/tcp.h>
54*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
55*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/rwlock.h>
56*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/mutex.h>
57*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/pattr.h>
58*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/strsubr.h>
59*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include <sys/ddi_impldefs.h>
60*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include<sys/task.h>
61*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
62*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include "unm_nic_hw.h"
63*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include "unm_nic.h"
64*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
65*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include "nic_phan_reg.h"
66*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include "unm_nic_ioctl.h"
67*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include "nic_cmn.h"
68*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include "unm_version.h"
69*9a5557fdSlucy wang - Sun Microsystems - Beijing China #include "unm_brdcfg.h"
70*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
71*9a5557fdSlucy wang - Sun Microsystems - Beijing China #if defined(lint)
72*9a5557fdSlucy wang - Sun Microsystems - Beijing China #undef MBLKL
73*9a5557fdSlucy wang - Sun Microsystems - Beijing China #define	MBLKL(_mp_)	((uintptr_t)(_mp_)->b_wptr - (uintptr_t)(_mp_)->b_rptr)
74*9a5557fdSlucy wang - Sun Microsystems - Beijing China #endif /* lint */
75*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
76*9a5557fdSlucy wang - Sun Microsystems - Beijing China #undef UNM_LOOPBACK
77*9a5557fdSlucy wang - Sun Microsystems - Beijing China #undef SINGLE_DMA_BUF
78*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
79*9a5557fdSlucy wang - Sun Microsystems - Beijing China #define	UNM_ADAPTER_UP_MAGIC	777
80*9a5557fdSlucy wang - Sun Microsystems - Beijing China #define	VLAN_TAGSZ		0x4
81*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
82*9a5557fdSlucy wang - Sun Microsystems - Beijing China #define	index2rxbuf(_rdp_, _idx_)	((_rdp_)->rx_buf_pool + (_idx_))
83*9a5557fdSlucy wang - Sun Microsystems - Beijing China #define	rxbuf2index(_rdp_, _bufp_)	((_bufp_) - (_rdp_)->rx_buf_pool)
84*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
85*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
86*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * Receive ISR processes NX_RX_MAXBUFS incoming packets at most, then posts
87*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * as many buffers as packets processed. This loop repeats as required to
88*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * process all incoming packets delivered in a single interrupt. Higher
89*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * value of NX_RX_MAXBUFS improves performance by posting rx buffers less
90*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * frequently, but at the cost of not posting quickly enough when card is
91*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * running out of rx buffers.
92*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
93*9a5557fdSlucy wang - Sun Microsystems - Beijing China #define	NX_RX_THRESHOLD		32
94*9a5557fdSlucy wang - Sun Microsystems - Beijing China #define	NX_RX_MAXBUFS		128
95*9a5557fdSlucy wang - Sun Microsystems - Beijing China #define	NX_MAX_TXCOMPS		256
96*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
97*9a5557fdSlucy wang - Sun Microsystems - Beijing China extern void unm_free_tx_buffers(unm_adapter *adapter);
98*9a5557fdSlucy wang - Sun Microsystems - Beijing China extern void unm_free_tx_dmahdl(unm_adapter *adapter);
99*9a5557fdSlucy wang - Sun Microsystems - Beijing China extern void unm_destroy_rx_ring(unm_rcv_desc_ctx_t *rcv_desc);
100*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
101*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void unm_post_rx_buffers_nodb(struct unm_adapter_s *adapter,
102*9a5557fdSlucy wang - Sun Microsystems - Beijing China     uint32_t ringid);
103*9a5557fdSlucy wang - Sun Microsystems - Beijing China static mblk_t *unm_process_rcv(unm_adapter *adapter, statusDesc_t *desc);
104*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int unm_process_rcv_ring(unm_adapter *, int);
105*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int unm_process_cmd_ring(struct unm_adapter_s *adapter);
106*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
107*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int unm_nic_do_ioctl(unm_adapter *adapter, queue_t *q, mblk_t *mp);
108*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void unm_nic_ioctl(struct unm_adapter_s *adapter, int cmd, queue_t *q,
109*9a5557fdSlucy wang - Sun Microsystems - Beijing China     mblk_t *mp);
110*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
111*9a5557fdSlucy wang - Sun Microsystems - Beijing China /* GLDv3 interface functions */
112*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int ntxn_m_start(void *);
113*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void ntxn_m_stop(void *);
114*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int ntxn_m_multicst(void *, boolean_t, const uint8_t *);
115*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int ntxn_m_promisc(void *, boolean_t);
116*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int ntxn_m_stat(void *arg, uint_t stat, uint64_t *val);
117*9a5557fdSlucy wang - Sun Microsystems - Beijing China static mblk_t *ntxn_m_tx(void *, mblk_t *);
118*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void ntxn_m_ioctl(void *arg, queue_t *wq, mblk_t *mp);
119*9a5557fdSlucy wang - Sun Microsystems - Beijing China static boolean_t ntxn_m_getcapab(void *arg, mac_capab_t cap, void *cap_data);
120*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
121*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
122*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * Allocates DMA handle, virtual memory and binds them
123*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * returns size of actual memory binded and the physical address.
124*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
125*9a5557fdSlucy wang - Sun Microsystems - Beijing China int
126*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_pci_alloc_consistent(unm_adapter *adapter,
127*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		int size, caddr_t *address, ddi_dma_cookie_t *cookie,
128*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		ddi_dma_handle_t *dma_handle, ddi_acc_handle_t *handlep)
129*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
130*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int			err;
131*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t		ncookies;
132*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	size_t			ring_len;
133*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint_t			dma_flags = DDI_DMA_RDWR | DDI_DMA_CONSISTENT;
134*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
135*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	*dma_handle = NULL;
136*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
137*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (size <= 0)
138*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_ENOMEM);
139*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
140*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	err = ddi_dma_alloc_handle(adapter->dip,
141*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &adapter->gc_dma_attr_desc,
142*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    DDI_DMA_DONTWAIT, NULL, dma_handle);
143*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (err != DDI_SUCCESS) {
144*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "!%s: %s: ddi_dma_alloc_handle FAILED:"
145*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    " %d", unm_nic_driver_name, __func__, err);
146*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_ENOMEM);
147*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
148*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
149*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	err = ddi_dma_mem_alloc(*dma_handle,
150*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    size, &adapter->gc_attr_desc,
151*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    dma_flags & (DDI_DMA_STREAMING | DDI_DMA_CONSISTENT),
152*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    DDI_DMA_DONTWAIT, NULL, address, &ring_len,
153*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    handlep);
154*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (err != DDI_SUCCESS) {
155*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "!%s: %s: ddi_dma_mem_alloc failed:"
156*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    "ret %d, request size: %d",
157*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    unm_nic_driver_name, __func__, err, size);
158*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		ddi_dma_free_handle(dma_handle);
159*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_ENOMEM);
160*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
161*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
162*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ring_len < size) {
163*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s: %s: could not allocate required "
164*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    "memory :%d\n", unm_nic_driver_name,
165*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    __func__, err);
166*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		ddi_dma_mem_free(handlep);
167*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		ddi_dma_free_handle(dma_handle);
168*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
169*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
170*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
171*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) memset(*address, 0, size);
172*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
173*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (((err = ddi_dma_addr_bind_handle(*dma_handle,
174*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    NULL, *address, ring_len,
175*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    dma_flags,
176*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    DDI_DMA_DONTWAIT, NULL,
177*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    cookie, &ncookies)) != DDI_DMA_MAPPED) ||
178*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    (ncookies != 1)) {
179*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN,
180*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    "!%s: %s: ddi_dma_addr_bind_handle FAILED: %d",
181*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    unm_nic_driver_name, __func__, err);
182*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		ddi_dma_mem_free(handlep);
183*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		ddi_dma_free_handle(dma_handle);
184*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
185*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
186*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
187*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
188*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
189*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
190*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
191*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * Unbinds the memory, frees the DMA handle and at the end, frees the memory
192*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
193*9a5557fdSlucy wang - Sun Microsystems - Beijing China void
194*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_pci_free_consistent(ddi_dma_handle_t *dma_handle,
195*9a5557fdSlucy wang - Sun Microsystems - Beijing China     ddi_acc_handle_t *acc_handle)
196*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
197*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int err;
198*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
199*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	err = ddi_dma_unbind_handle(*dma_handle);
200*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (err != DDI_SUCCESS) {
201*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s: Error unbinding memory\n", __func__);
202*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return;
203*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
204*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
205*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_dma_mem_free(acc_handle);
206*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_dma_free_handle(dma_handle);
207*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
208*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
209*9a5557fdSlucy wang - Sun Microsystems - Beijing China static uint32_t msi_tgt_status[] = {
210*9a5557fdSlucy wang - Sun Microsystems - Beijing China     ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1,
211*9a5557fdSlucy wang - Sun Microsystems - Beijing China     ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3,
212*9a5557fdSlucy wang - Sun Microsystems - Beijing China     ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5,
213*9a5557fdSlucy wang - Sun Microsystems - Beijing China     ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7
214*9a5557fdSlucy wang - Sun Microsystems - Beijing China };
215*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
216*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
217*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_disable_int(unm_adapter *adapter)
218*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
219*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	__uint32_t	temp = 0;
220*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
221*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->unm_nic_hw_write_wx(adapter, adapter->interrupt_crb,
222*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &temp, 4);
223*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
224*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
225*9a5557fdSlucy wang - Sun Microsystems - Beijing China static inline int
226*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_clear_int(unm_adapter *adapter)
227*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
228*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t	mask, temp, our_int, status;
229*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
230*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_LOCK(&adapter->adapter_lock);
231*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
232*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* check whether it's our interrupt */
233*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (!UNM_IS_MSI_FAMILY(adapter)) {
234*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
235*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* Legacy Interrupt case */
236*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_pci_read_immediate(adapter, ISR_INT_VECTOR,
237*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &status);
238*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
239*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (!(status & adapter->legacy_intr.int_vec_bit)) {
240*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			UNM_READ_UNLOCK(&adapter->adapter_lock);
241*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			return (-1);
242*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
243*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
244*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (adapter->ahw.revision_id >= NX_P3_B1) {
245*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->unm_nic_pci_read_immediate(adapter,
246*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    ISR_INT_STATE_REG, &temp);
247*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			if (!ISR_IS_LEGACY_INTR_TRIGGERED(temp)) {
248*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				UNM_READ_UNLOCK(&adapter->adapter_lock);
249*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				return (-1);
250*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			}
251*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		} else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
252*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			our_int = adapter->unm_nic_pci_read_normalize(adapter,
253*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    CRB_INT_VECTOR);
254*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
255*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			/* FIXME: Assumes pci_func is same as ctx */
256*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			if ((our_int & (0x80 << adapter->portnum)) == 0) {
257*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				if (our_int != 0) {
258*9a5557fdSlucy wang - Sun Microsystems - Beijing China 					/* not our interrupt */
259*9a5557fdSlucy wang - Sun Microsystems - Beijing China 					UNM_READ_UNLOCK(&adapter->adapter_lock);
260*9a5557fdSlucy wang - Sun Microsystems - Beijing China 					return (-1);
261*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				}
262*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			}
263*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			temp = our_int & ~((u32)(0x80 << adapter->portnum));
264*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->unm_nic_pci_write_normalize(adapter,
265*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    CRB_INT_VECTOR, temp);
266*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
267*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
268*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (adapter->fw_major < 4)
269*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			unm_nic_disable_int(adapter);
270*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
271*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* claim interrupt */
272*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		temp = 0xffffffff;
273*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_pci_write_immediate(adapter,
274*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->legacy_intr.tgt_status_reg, &temp);
275*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
276*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_pci_read_immediate(adapter, ISR_INT_VECTOR,
277*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &mask);
278*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
279*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/*
280*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * Read again to make sure the legacy interrupt message got
281*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * flushed out
282*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 */
283*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_pci_read_immediate(adapter, ISR_INT_VECTOR,
284*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &mask);
285*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else if (adapter->flags & UNM_NIC_MSI_ENABLED) {
286*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* clear interrupt */
287*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		temp = 0xffffffff;
288*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_pci_write_immediate(adapter,
289*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    msi_tgt_status[adapter->ahw.pci_func], &temp);
290*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
291*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
292*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_UNLOCK(&adapter->adapter_lock);
293*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
294*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (0);
295*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
296*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
297*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
298*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_enable_int(unm_adapter *adapter)
299*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
300*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	u32	temp = 1;
301*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
302*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->unm_nic_hw_write_wx(adapter, adapter->interrupt_crb,
303*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &temp, 4);
304*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
305*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (!UNM_IS_MSI_FAMILY(adapter)) {
306*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		u32	mask = 0xfbff;
307*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
308*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_pci_write_immediate(adapter,
309*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->legacy_intr.tgt_mask_reg, &mask);
310*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
311*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
312*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
313*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
314*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_free_hw_resources(unm_adapter *adapter)
315*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
316*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_recv_context_t *recv_ctx;
317*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rcv_desc_ctx_t *rcv_desc;
318*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int ctx, ring;
319*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
320*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->context_alloced == 1) {
321*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		netxen_destroy_rxtx(adapter);
322*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->context_alloced = 0;
323*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
324*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
325*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->ctxDesc != NULL) {
326*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_pci_free_consistent(&adapter->ctxDesc_dma_handle,
327*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &adapter->ctxDesc_acc_handle);
328*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->ctxDesc = NULL;
329*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
330*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
331*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->ahw.cmdDescHead != NULL) {
332*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_pci_free_consistent(&adapter->ahw.cmd_desc_dma_handle,
333*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &adapter->ahw.cmd_desc_acc_handle);
334*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->ahw.cmdDesc_physAddr = NULL;
335*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->ahw.cmdDescHead = NULL;
336*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
337*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
338*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
339*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		recv_ctx = &adapter->recv_ctx[ctx];
340*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
341*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rcv_desc = &recv_ctx->rcv_desc[ring];
342*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
343*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			if (rcv_desc->desc_head != NULL) {
344*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				unm_pci_free_consistent(
345*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				    &rcv_desc->rx_desc_dma_handle,
346*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				    &rcv_desc->rx_desc_acc_handle);
347*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				rcv_desc->desc_head = NULL;
348*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				rcv_desc->phys_addr = NULL;
349*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			}
350*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
351*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
352*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (recv_ctx->rcvStatusDescHead != NULL) {
353*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			unm_pci_free_consistent(
354*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    &recv_ctx->status_desc_dma_handle,
355*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    &recv_ctx->status_desc_acc_handle);
356*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			recv_ctx->rcvStatusDesc_physAddr = NULL;
357*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			recv_ctx->rcvStatusDescHead = NULL;
358*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
359*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
360*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
361*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
362*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
363*9a5557fdSlucy wang - Sun Microsystems - Beijing China cleanup_adapter(struct unm_adapter_s *adapter)
364*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
365*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->cmd_buf_arr != NULL)
366*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		kmem_free(adapter->cmd_buf_arr,
367*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    sizeof (struct unm_cmd_buffer) * adapter->MaxTxDescCount);
368*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
369*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_regs_map_free(&(adapter->regs_handle));
370*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_regs_map_free(&(adapter->db_handle));
371*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	kmem_free(adapter, sizeof (unm_adapter));
372*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
373*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
374*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
375*9a5557fdSlucy wang - Sun Microsystems - Beijing China void
376*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_remove(unm_adapter *adapter)
377*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
378*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_recv_context_t *recv_ctx;
379*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rcv_desc_ctx_t	*rcv_desc;
380*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int ctx, ring;
381*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
382*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	mac_link_update(adapter->mach, LINK_STATE_DOWN);
383*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_stop_port(adapter);
384*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
385*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->interrupt_crb) {
386*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_READ_LOCK(&adapter->adapter_lock);
387*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_nic_disable_int(adapter);
388*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_READ_UNLOCK(&adapter->adapter_lock);
389*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
390*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) untimeout(adapter->watchdog_timer);
391*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
392*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_free_hw_resources(adapter);
393*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_free_tx_buffers(adapter);
394*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_free_tx_dmahdl(adapter);
395*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
396*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
397*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		recv_ctx = &adapter->recv_ctx[ctx];
398*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
399*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rcv_desc = &recv_ctx->rcv_desc[ring];
400*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			if (rcv_desc->rx_buf_pool != NULL)
401*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				unm_destroy_rx_ring(rcv_desc);
402*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
403*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
404*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
405*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->portnum == 0)
406*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_free_dummy_dma(adapter);
407*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
408*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_destroy_intr(adapter);
409*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
410*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_set_driver_private(adapter->dip, NULL);
411*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	cleanup_adapter(adapter);
412*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
413*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
414*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
415*9a5557fdSlucy wang - Sun Microsystems - Beijing China init_firmware(unm_adapter *adapter)
416*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
417*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t state = 0, loops = 0, tempout;
418*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
419*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* Window 1 call */
420*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_LOCK(&adapter->adapter_lock);
421*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	state = adapter->unm_nic_pci_read_normalize(adapter, CRB_CMDPEG_STATE);
422*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_UNLOCK(&adapter->adapter_lock);
423*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
424*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (state == PHAN_INITIALIZE_ACK)
425*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (0);
426*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
427*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	while (state != PHAN_INITIALIZE_COMPLETE && loops < 200000) {
428*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		drv_usecwait(100);
429*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* Window 1 call */
430*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_READ_LOCK(&adapter->adapter_lock);
431*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		state = adapter->unm_nic_pci_read_normalize(adapter,
432*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    CRB_CMDPEG_STATE);
433*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_READ_UNLOCK(&adapter->adapter_lock);
434*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		loops++;
435*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
436*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
437*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (loops >= 200000) {
438*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: CmdPeg init incomplete:%x\n",
439*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance, state);
440*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (-EIO);
441*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
442*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
443*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* Window 1 call */
444*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_LOCK(&adapter->adapter_lock);
445*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	tempout = INTR_SCHEME_PERPORT;
446*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->unm_nic_hw_write_wx(adapter, CRB_NIC_CAPABILITIES_HOST,
447*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &tempout, 4);
448*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	tempout = MSI_MODE_MULTIFUNC;
449*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->unm_nic_hw_write_wx(adapter, CRB_NIC_MSI_MODE_HOST,
450*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &tempout, 4);
451*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	tempout = MPORT_MULTI_FUNCTION_MODE;
452*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->unm_nic_hw_write_wx(adapter, CRB_MPORT_MODE, &tempout, 4);
453*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	tempout = PHAN_INITIALIZE_ACK;
454*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->unm_nic_hw_write_wx(adapter, CRB_CMDPEG_STATE, &tempout, 4);
455*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_UNLOCK(&adapter->adapter_lock);
456*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
457*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (0);
458*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
459*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
460*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
461*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * Utility to synchronize with receive peg.
462*9a5557fdSlucy wang - Sun Microsystems - Beijing China  *  Returns   0 on sucess
463*9a5557fdSlucy wang - Sun Microsystems - Beijing China  *         -EIO on error
464*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
465*9a5557fdSlucy wang - Sun Microsystems - Beijing China int
466*9a5557fdSlucy wang - Sun Microsystems - Beijing China receive_peg_ready(struct unm_adapter_s *adapter)
467*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
468*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t state = 0;
469*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int loops = 0, err = 0;
470*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
471*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* Window 1 call */
472*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_LOCK(&adapter->adapter_lock);
473*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	state = adapter->unm_nic_pci_read_normalize(adapter, CRB_RCVPEG_STATE);
474*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_UNLOCK(&adapter->adapter_lock);
475*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
476*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	while ((state != PHAN_PEG_RCV_INITIALIZED) && (loops < 20000)) {
477*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		drv_usecwait(100);
478*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* Window 1 call */
479*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
480*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_READ_LOCK(&adapter->adapter_lock);
481*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		state = adapter->unm_nic_pci_read_normalize(adapter,
482*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    CRB_RCVPEG_STATE);
483*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_READ_UNLOCK(&adapter->adapter_lock);
484*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
485*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		loops++;
486*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
487*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
488*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (loops >= 20000) {
489*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "Receive Peg initialization incomplete 0x%x\n",
490*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    state);
491*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		err = -EIO;
492*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
493*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
494*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (err);
495*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
496*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
497*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
498*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * check if the firmware has been downloaded and ready to run  and
499*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * setup the address for the descriptors in the adapter
500*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
501*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
502*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_hw_resources(unm_adapter *adapter)
503*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
504*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hardware_context	*hw = &adapter->ahw;
505*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	void			*addr;
506*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int			err;
507*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int			ctx, ring;
508*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_recv_context_t	*recv_ctx;
509*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rcv_desc_ctx_t	*rcv_desc;
510*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_dma_cookie_t	cookie;
511*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int			size;
512*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
513*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (err = receive_peg_ready(adapter))
514*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (err);
515*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
516*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	size = (sizeof (RingContext) + sizeof (uint32_t));
517*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
518*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	err = unm_pci_alloc_consistent(adapter,
519*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    size, (caddr_t *)&addr, &cookie,
520*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &adapter->ctxDesc_dma_handle,
521*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &adapter->ctxDesc_acc_handle);
522*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (err != DDI_SUCCESS) {
523*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "Failed to allocate HW context\n");
524*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (err);
525*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
526*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
527*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ctxDesc_physAddr = cookie.dmac_laddress;
528*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
529*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) memset(addr, 0, sizeof (RingContext));
530*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
531*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ctxDesc = (RingContext *) addr;
532*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ctxDesc->CtxId = adapter->portnum;
533*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->ctxDesc->CMD_CONSUMER_OFFSET =
534*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    adapter->ctxDesc_physAddr + sizeof (RingContext);
535*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->cmdConsumer =
536*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    (uint32_t *)(uintptr_t)(((char *)addr) + sizeof (RingContext));
537*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
538*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ASSERT(!((unsigned long)adapter->ctxDesc_physAddr & 0x3f));
539*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
540*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
541*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * Allocate command descriptor ring.
542*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
543*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	size = (sizeof (cmdDescType0_t) * adapter->MaxTxDescCount);
544*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	err = unm_pci_alloc_consistent(adapter,
545*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    size, (caddr_t *)&addr, &cookie,
546*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &hw->cmd_desc_dma_handle,
547*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &hw->cmd_desc_acc_handle);
548*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (err != DDI_SUCCESS) {
549*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "Failed to allocate cmd desc ring\n");
550*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (err);
551*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
552*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
553*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hw->cmdDesc_physAddr = cookie.dmac_laddress;
554*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hw->cmdDescHead = (cmdDescType0_t *)addr;
555*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
556*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
557*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		recv_ctx = &adapter->recv_ctx[ctx];
558*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
559*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		size = (sizeof (statusDesc_t)* adapter->MaxRxDescCount);
560*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		err = unm_pci_alloc_consistent(adapter,
561*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    size, (caddr_t *)&addr,
562*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &recv_ctx->status_desc_dma_cookie,
563*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &recv_ctx->status_desc_dma_handle,
564*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &recv_ctx->status_desc_acc_handle);
565*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (err != DDI_SUCCESS) {
566*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			cmn_err(CE_WARN, "Failed to allocate sts desc ring\n");
567*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto free_cmd_desc;
568*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
569*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
570*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) memset(addr, 0, size);
571*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		recv_ctx->rcvStatusDesc_physAddr =
572*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    recv_ctx->status_desc_dma_cookie.dmac_laddress;
573*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		recv_ctx->rcvStatusDescHead = (statusDesc_t *)addr;
574*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
575*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* rds rings */
576*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
577*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rcv_desc = &recv_ctx->rcv_desc[ring];
578*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
579*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			size = (sizeof (rcvDesc_t) * adapter->MaxRxDescCount);
580*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			err = unm_pci_alloc_consistent(adapter,
581*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    size, (caddr_t *)&addr,
582*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    &rcv_desc->rx_desc_dma_cookie,
583*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    &rcv_desc->rx_desc_dma_handle,
584*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    &rcv_desc->rx_desc_acc_handle);
585*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			if (err != DDI_SUCCESS) {
586*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				cmn_err(CE_WARN, "Failed to allocate "
587*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				    "rx desc ring %d\n", ring);
588*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				goto free_status_desc;
589*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			}
590*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
591*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rcv_desc->phys_addr =
592*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    rcv_desc->rx_desc_dma_cookie.dmac_laddress;
593*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rcv_desc->desc_head = (rcvDesc_t *)addr;
594*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
595*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
596*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
597*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (err = netxen_create_rxtx(adapter))
598*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto free_statusrx_desc;
599*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->context_alloced = 1;
600*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
601*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
602*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
603*9a5557fdSlucy wang - Sun Microsystems - Beijing China free_statusrx_desc:
604*9a5557fdSlucy wang - Sun Microsystems - Beijing China free_status_desc:
605*9a5557fdSlucy wang - Sun Microsystems - Beijing China free_cmd_desc:
606*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_free_hw_resources(adapter);
607*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
608*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (err);
609*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
610*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
611*9a5557fdSlucy wang - Sun Microsystems - Beijing China void unm_desc_dma_sync(ddi_dma_handle_t handle, uint_t start, uint_t count,
612*9a5557fdSlucy wang - Sun Microsystems - Beijing China     uint_t range, uint_t unit_size, uint_t direction)
613*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
614*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((start + count) < range) {
615*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(handle, start * unit_size,
616*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    count * unit_size, direction);
617*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
618*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(handle, start * unit_size, 0, direction);
619*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) ddi_dma_sync(handle, 0,
620*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (start + count - range) * unit_size, DDI_DMA_SYNC_FORCPU);
621*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
622*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
623*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
624*9a5557fdSlucy wang - Sun Microsystems - Beijing China static uint32_t crb_cmd_producer[4] = { CRB_CMD_PRODUCER_OFFSET,
625*9a5557fdSlucy wang - Sun Microsystems - Beijing China     CRB_CMD_PRODUCER_OFFSET_1, CRB_CMD_PRODUCER_OFFSET_2,
626*9a5557fdSlucy wang - Sun Microsystems - Beijing China     CRB_CMD_PRODUCER_OFFSET_3 };
627*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
628*9a5557fdSlucy wang - Sun Microsystems - Beijing China static uint32_t crb_cmd_consumer[4] = { CRB_CMD_CONSUMER_OFFSET,
629*9a5557fdSlucy wang - Sun Microsystems - Beijing China     CRB_CMD_CONSUMER_OFFSET_1, CRB_CMD_CONSUMER_OFFSET_2,
630*9a5557fdSlucy wang - Sun Microsystems - Beijing China     CRB_CMD_CONSUMER_OFFSET_3 };
631*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
632*9a5557fdSlucy wang - Sun Microsystems - Beijing China void
633*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_update_cmd_producer(struct unm_adapter_s *adapter,
634*9a5557fdSlucy wang - Sun Microsystems - Beijing China     uint32_t crb_producer)
635*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
636*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int data = crb_producer;
637*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
638*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->crb_addr_cmd_producer) {
639*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_READ_LOCK(&adapter->adapter_lock);
640*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_hw_write_wx(adapter,
641*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->crb_addr_cmd_producer, &data, 4);
642*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_READ_UNLOCK(&adapter->adapter_lock);
643*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
644*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
645*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
646*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
647*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_update_cmd_consumer(struct unm_adapter_s *adapter,
648*9a5557fdSlucy wang - Sun Microsystems - Beijing China     uint32_t crb_producer)
649*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
650*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int data = crb_producer;
651*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
652*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->crb_addr_cmd_consumer)
653*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_hw_write_wx(adapter,
654*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->crb_addr_cmd_consumer, &data, 4);
655*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
656*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
657*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
658*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * Looks for type of packet and sets opcode accordingly
659*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * so that checksum offload can be used.
660*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
661*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
662*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_tx_csum(cmdDescType0_t *desc, mblk_t *mp, pktinfo_t *pktinfo)
663*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
664*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (pktinfo->mac_hlen == sizeof (struct ether_vlan_header))
665*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		desc->u1.s1.flags = FLAGS_VLAN_TAGGED;
666*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
667*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (pktinfo->etype == htons(ETHERTYPE_IP)) {
668*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		uint32_t	start, flags;
669*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
670*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		hcksum_retrieve(mp, NULL, NULL, &start, NULL, NULL, NULL,
671*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &flags);
672*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if ((flags & (HCK_FULLCKSUM | HCK_IPV4_HDRCKSUM)) == 0)
673*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			return;
674*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
675*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/*
676*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * For TCP/UDP, ask hardware to do both IP header and
677*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * full checksum, even if stack has already done one or
678*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * the other. Hardware will always get it correct even
679*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * if stack has already done it.
680*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 */
681*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		switch (pktinfo->l4_proto) {
682*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			case IPPROTO_TCP:
683*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				desc->u1.s1.opcode = TX_TCP_PKT;
684*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				break;
685*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			case IPPROTO_UDP:
686*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				desc->u1.s1.opcode = TX_UDP_PKT;
687*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				break;
688*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			default:
689*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				/* Must be here with HCK_IPV4_HDRCKSUM */
690*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				desc->u1.s1.opcode = TX_IP_PKT;
691*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				return;
692*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
693*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
694*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		desc->u1.s1.ipHdrOffset = pktinfo->mac_hlen;
695*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		desc->u1.s1.tcpHdrOffset = pktinfo->mac_hlen + pktinfo->ip_hlen;
696*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
697*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
698*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
699*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
700*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * For IP/UDP/TCP checksum offload, this checks for MAC+IP header in one
701*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * contiguous block ending at 8 byte aligned address as required by hardware.
702*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * Caller assumes pktinfo->total_len will be updated by this function and
703*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * if pktinfo->etype is set to 0, it will need to linearize the mblk and
704*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * invoke unm_update_pkt_info() to determine ethertype, IP header len and
705*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * protocol.
706*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
707*9a5557fdSlucy wang - Sun Microsystems - Beijing China static boolean_t
708*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_get_pkt_info(mblk_t *mp, pktinfo_t *pktinfo)
709*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
710*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	mblk_t		*bp;
711*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ushort_t	type;
712*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
713*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) memset(pktinfo, 0, sizeof (pktinfo_t));
714*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
715*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (bp = mp; bp != NULL; bp = bp->b_cont) {
716*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (MBLKL(bp) == 0)
717*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			continue;
718*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		pktinfo->mblk_no++;
719*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		pktinfo->total_len += MBLKL(bp);
720*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
721*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
722*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (MBLKL(mp) < (sizeof (struct ether_header) + sizeof (ipha_t)))
723*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (B_FALSE);
724*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
725*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
726*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * We just need non 1 byte aligned address, since ether_type is
727*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * ushort.
728*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
729*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((uintptr_t)mp->b_rptr & 1)
730*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (B_FALSE);
731*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
732*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	type = ((struct ether_header *)(uintptr_t)mp->b_rptr)->ether_type;
733*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (type == htons(ETHERTYPE_VLAN)) {
734*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (MBLKL(mp) < (sizeof (struct ether_vlan_header) +
735*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    sizeof (ipha_t)))
736*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			return (B_FALSE);
737*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		type = ((struct ether_vlan_header *) \
738*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (uintptr_t)mp->b_rptr)->ether_type;
739*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		pktinfo->mac_hlen = sizeof (struct ether_vlan_header);
740*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
741*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		pktinfo->mac_hlen = sizeof (struct ether_header);
742*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
743*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	pktinfo->etype = type;
744*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
745*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (pktinfo->etype == htons(ETHERTYPE_IP)) {
746*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		uchar_t *ip_off = mp->b_rptr + pktinfo->mac_hlen;
747*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
748*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		pktinfo->ip_hlen = IPH_HDR_LENGTH((uintptr_t)ip_off);
749*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		pktinfo->l4_proto =
750*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    ((ipha_t *)(uintptr_t)ip_off)->ipha_protocol;
751*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
752*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* IP header not aligned to quadward boundary? */
753*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if ((unsigned long)(ip_off + pktinfo->ip_hlen) % 8 != 0)
754*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			return (B_FALSE);
755*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
756*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
757*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (B_TRUE);
758*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
759*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
760*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
761*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_update_pkt_info(char *ptr, pktinfo_t *pktinfo)
762*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
763*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ushort_t	type;
764*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
765*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	type = ((struct ether_header *)(uintptr_t)ptr)->ether_type;
766*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (type == htons(ETHERTYPE_VLAN)) {
767*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		type = ((struct ether_vlan_header *)(uintptr_t)ptr)->ether_type;
768*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		pktinfo->mac_hlen = sizeof (struct ether_vlan_header);
769*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
770*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		pktinfo->mac_hlen = sizeof (struct ether_header);
771*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
772*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	pktinfo->etype = type;
773*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
774*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (pktinfo->etype == htons(ETHERTYPE_IP)) {
775*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		char *ipp = ptr + pktinfo->mac_hlen;
776*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
777*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		pktinfo->ip_hlen = IPH_HDR_LENGTH((uintptr_t)ipp);
778*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		pktinfo->l4_proto = ((ipha_t *)(uintptr_t)ipp)->ipha_protocol;
779*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
780*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
781*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
782*9a5557fdSlucy wang - Sun Microsystems - Beijing China static boolean_t
783*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_send_copy(struct unm_adapter_s *adapter, mblk_t *mp, pktinfo_t *pktinfo)
784*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
785*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hardware_context *hw;
786*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	u32				producer = 0;
787*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	cmdDescType0_t			*hwdesc;
788*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct unm_cmd_buffer		*pbuf = NULL;
789*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	u32				mblen;
790*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int				no_of_desc = 1;
791*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int				MaxTxDescCount;
792*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	mblk_t				*bp;
793*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	char				*txb;
794*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
795*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hw = &adapter->ahw;
796*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	MaxTxDescCount = adapter->MaxTxDescCount;
797*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
798*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_SPIN_LOCK(&adapter->tx_lock);
799*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	membar_enter();
800*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
801*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (find_diff_among(adapter->cmdProducer, adapter->lastCmdConsumer,
802*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    MaxTxDescCount) <= 2) {
803*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->stats.outofcmddesc++;
804*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->resched_needed = 1;
805*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		membar_exit();
806*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_SPIN_UNLOCK(&adapter->tx_lock);
807*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (B_FALSE);
808*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
809*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->freecmds -= no_of_desc;
810*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
811*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	producer = adapter->cmdProducer;
812*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
813*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->cmdProducer = get_index_range(adapter->cmdProducer,
814*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    MaxTxDescCount, no_of_desc);
815*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
816*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc = &hw->cmdDescHead[producer];
817*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) memset(hwdesc, 0, sizeof (cmdDescType0_t));
818*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	pbuf = &adapter->cmd_buf_arr[producer];
819*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
820*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	pbuf->msg = NULL;
821*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	pbuf->head = NULL;
822*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	pbuf->tail = NULL;
823*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
824*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	txb = pbuf->dma_area.vaddr;
825*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
826*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (bp = mp; bp != NULL; bp = bp->b_cont) {
827*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if ((mblen = MBLKL(bp)) == 0)
828*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			continue;
829*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		bcopy(bp->b_rptr, txb, mblen);
830*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		txb += mblen;
831*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
832*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
833*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
834*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * Determine metadata if not previously done due to fragmented mblk.
835*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
836*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (pktinfo->etype == 0)
837*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_update_pkt_info(pbuf->dma_area.vaddr, pktinfo);
838*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
839*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(pbuf->dma_area.dma_hdl,
840*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    0, pktinfo->total_len, DDI_DMA_SYNC_FORDEV);
841*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
842*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* hwdesc->u1.s1.tcpHdrOffset = 0; */
843*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* hwdesc->mss = 0; */
844*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc->u1.s1.opcode = TX_ETHER_PKT;
845*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc->u3.s1.port = adapter->portnum;
846*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc->u3.s1.ctx_id = adapter->portnum;
847*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
848*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc->u6.s1.buffer1Length = pktinfo->total_len;
849*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc->u5.AddrBuffer1 = pbuf->dma_area.dma_addr;
850*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc->u1.s1.numOfBuffers = 1;
851*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc->u1.s1.totalLength = pktinfo->total_len;
852*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
853*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_tx_csum(hwdesc, mp, pktinfo);
854*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
855*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_desc_dma_sync(hw->cmd_desc_dma_handle,
856*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    producer,
857*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    no_of_desc,
858*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    MaxTxDescCount,
859*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    sizeof (cmdDescType0_t),
860*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    DDI_DMA_SYNC_FORDEV);
861*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
862*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hw->cmdProducer = adapter->cmdProducer;
863*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_update_cmd_producer(adapter, adapter->cmdProducer);
864*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
865*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->stats.txbytes += pktinfo->total_len;
866*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->stats.xmitfinished++;
867*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->stats.txcopyed++;
868*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_SPIN_UNLOCK(&adapter->tx_lock);
869*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
870*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	freemsg(mp);
871*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (B_TRUE);
872*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
873*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
874*9a5557fdSlucy wang - Sun Microsystems - Beijing China /* Should be called with adapter->tx_lock held. */
875*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
876*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_return_dma_handle(unm_adapter *adapter, unm_dmah_node_t *head,
877*9a5557fdSlucy wang - Sun Microsystems - Beijing China     unm_dmah_node_t *tail, uint32_t num)
878*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
879*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ASSERT(tail != NULL);
880*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	tail->next = adapter->dmahdl_pool;
881*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->dmahdl_pool = head;
882*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->freehdls += num;
883*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
884*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
885*9a5557fdSlucy wang - Sun Microsystems - Beijing China static unm_dmah_node_t *
886*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_reserve_dma_handle(unm_adapter* adapter)
887*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
888*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_dmah_node_t *dmah = NULL;
889*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
890*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	dmah = adapter->dmahdl_pool;
891*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (dmah != NULL) {
892*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->dmahdl_pool = dmah->next;
893*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		dmah->next = NULL;
894*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->freehdls--;
895*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		membar_exit();
896*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
897*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
898*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (dmah);
899*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
900*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
901*9a5557fdSlucy wang - Sun Microsystems - Beijing China static boolean_t
902*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_send_mapped(struct unm_adapter_s *adapter, mblk_t *mp, pktinfo_t *pktinfo)
903*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
904*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hardware_context		*hw;
905*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	u32				producer = 0;
906*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	u32				saved_producer = 0;
907*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	cmdDescType0_t			*hwdesc;
908*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct unm_cmd_buffer		*pbuf = NULL;
909*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int				no_of_desc;
910*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int				k;
911*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int				MaxTxDescCount;
912*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	mblk_t				*bp;
913*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
914*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_dmah_node_t *dmah, *head = NULL, *tail = NULL, *hdlp;
915*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_dma_cookie_t cookie[MAX_COOKIES_PER_CMD + 1];
916*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int ret, i;
917*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t hdl_reserved = 0;
918*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t mblen;
919*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t ncookies, index = 0, total_cookies = 0;
920*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
921*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	MaxTxDescCount = adapter->MaxTxDescCount;
922*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
923*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_SPIN_LOCK(&adapter->tx_lock);
924*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
925*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* bind all the mblks of the packet first */
926*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (bp = mp; bp != NULL; bp = bp->b_cont) {
927*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		mblen = MBLKL(bp);
928*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (mblen == 0)
929*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			continue;
930*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
931*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		dmah = unm_reserve_dma_handle(adapter);
932*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (dmah == NULL) {
933*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->stats.outoftxdmahdl++;
934*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto err_map;
935*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
936*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
937*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		ret = ddi_dma_addr_bind_handle(dmah->dmahdl,
938*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    NULL, (caddr_t)bp->b_rptr, mblen,
939*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    DDI_DMA_STREAMING | DDI_DMA_WRITE,
940*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    DDI_DMA_DONTWAIT, NULL, &cookie[index], &ncookies);
941*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
942*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (ret != DDI_DMA_MAPPED)
943*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto err_map;
944*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
945*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (tail == NULL) {
946*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			head = tail = dmah;
947*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		} else {
948*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			tail->next = dmah;
949*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			tail = dmah;
950*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
951*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		hdl_reserved++;
952*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
953*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		total_cookies += ncookies;
954*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (total_cookies > MAX_COOKIES_PER_CMD) {
955*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			dmah = NULL;
956*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto err_map;
957*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
958*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
959*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (index == 0) {
960*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			size_t	hsize = cookie[0].dmac_size;
961*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
962*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			/*
963*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			 * For TCP/UDP packets with checksum offload,
964*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			 * MAC/IP headers need to be contiguous. Otherwise,
965*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			 * there must be at least 16 bytes in the first
966*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			 * descriptor.
967*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			 */
968*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			if ((pktinfo->l4_proto == IPPROTO_TCP) ||
969*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    (pktinfo->l4_proto == IPPROTO_UDP)) {
970*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				if (hsize < (pktinfo->mac_hlen +
971*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				    pktinfo->ip_hlen)) {
972*9a5557fdSlucy wang - Sun Microsystems - Beijing China 					dmah = NULL;
973*9a5557fdSlucy wang - Sun Microsystems - Beijing China 					goto err_map;
974*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				}
975*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			} else {
976*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				if (hsize < 16) {
977*9a5557fdSlucy wang - Sun Microsystems - Beijing China 					dmah = NULL;
978*9a5557fdSlucy wang - Sun Microsystems - Beijing China 					goto err_map;
979*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				}
980*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			}
981*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
982*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
983*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		index++;
984*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		ncookies--;
985*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		for (i = 0; i < ncookies; i++, index++)
986*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			ddi_dma_nextcookie(dmah->dmahdl, &cookie[index]);
987*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
988*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
989*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	dmah = NULL;
990*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hw = &adapter->ahw;
991*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	no_of_desc = (total_cookies + 3) >> 2;
992*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
993*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	membar_enter();
994*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (find_diff_among(adapter->cmdProducer, adapter->lastCmdConsumer,
995*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    MaxTxDescCount) < no_of_desc+2) {
996*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/*
997*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * If we are going to be trying the copy path, no point
998*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * scheduling an upcall when Tx resources are freed.
999*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 */
1000*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (pktinfo->total_len > adapter->maxmtu) {
1001*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->stats.outofcmddesc++;
1002*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->resched_needed = 1;
1003*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1004*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		membar_exit();
1005*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto err_alloc_desc;
1006*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1007*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->freecmds -= no_of_desc;
1008*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1009*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* Copy the descriptors into the hardware    */
1010*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	producer = adapter->cmdProducer;
1011*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	saved_producer = producer;
1012*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc = &hw->cmdDescHead[producer];
1013*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) memset(hwdesc, 0, sizeof (cmdDescType0_t));
1014*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	pbuf = &adapter->cmd_buf_arr[producer];
1015*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1016*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	pbuf->msg = mp;
1017*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	pbuf->head = head;
1018*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	pbuf->tail = tail;
1019*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1020*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc->u1.s1.numOfBuffers = total_cookies;
1021*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc->u1.s1.opcode = TX_ETHER_PKT;
1022*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc->u3.s1.port = adapter->portnum;
1023*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* hwdesc->u1.s1.tcpHdrOffset = 0; */
1024*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* hwdesc->mss = 0; */
1025*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc->u3.s1.ctx_id = adapter->portnum;
1026*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hwdesc->u1.s1.totalLength = pktinfo->total_len;
1027*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_tx_csum(hwdesc, mp, pktinfo);
1028*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1029*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (i = k = 0; i < total_cookies; i++) {
1030*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (k == 4) {
1031*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			/* Move to the next descriptor */
1032*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			k = 0;
1033*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			producer = get_next_index(producer, MaxTxDescCount);
1034*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			hwdesc = &hw->cmdDescHead[producer];
1035*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			(void) memset(hwdesc, 0, sizeof (cmdDescType0_t));
1036*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1037*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1038*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		switch (k) {
1039*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case 0:
1040*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			hwdesc->u6.s1.buffer1Length = cookie[i].dmac_size;
1041*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			hwdesc->u5.AddrBuffer1 = cookie[i].dmac_laddress;
1042*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
1043*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case 1:
1044*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			hwdesc->u6.s1.buffer2Length = cookie[i].dmac_size;
1045*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			hwdesc->u2.AddrBuffer2 = cookie[i].dmac_laddress;
1046*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
1047*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case 2:
1048*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			hwdesc->u6.s1.buffer3Length = cookie[i].dmac_size;
1049*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			hwdesc->u4.AddrBuffer3 = cookie[i].dmac_laddress;
1050*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
1051*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case 3:
1052*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			hwdesc->u6.s1.buffer4Length = cookie[i].dmac_size;
1053*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			hwdesc->u7.AddrBuffer4 = cookie[i].dmac_laddress;
1054*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
1055*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1056*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		k++;
1057*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1058*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1059*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_desc_dma_sync(hw->cmd_desc_dma_handle, saved_producer, no_of_desc,
1060*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    MaxTxDescCount, sizeof (cmdDescType0_t), DDI_DMA_SYNC_FORDEV);
1061*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1062*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->cmdProducer = get_next_index(producer, MaxTxDescCount);
1063*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hw->cmdProducer = adapter->cmdProducer;
1064*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_update_cmd_producer(adapter, adapter->cmdProducer);
1065*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1066*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->stats.txbytes += pktinfo->total_len;
1067*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->stats.xmitfinished++;
1068*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->stats.txmapped++;
1069*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_SPIN_UNLOCK(&adapter->tx_lock);
1070*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (B_TRUE);
1071*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1072*9a5557fdSlucy wang - Sun Microsystems - Beijing China err_alloc_desc:
1073*9a5557fdSlucy wang - Sun Microsystems - Beijing China err_map:
1074*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1075*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	hdlp = head;
1076*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	while (hdlp != NULL) {
1077*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) ddi_dma_unbind_handle(hdlp->dmahdl);
1078*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		hdlp = hdlp->next;
1079*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1080*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1081*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
1082*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * add the reserved but bind failed one to the list to be returned
1083*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
1084*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (dmah != NULL) {
1085*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (tail == NULL)
1086*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			head = tail = dmah;
1087*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		else {
1088*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			tail->next = dmah;
1089*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			tail = dmah;
1090*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1091*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		hdl_reserved++;
1092*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1093*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1094*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (head != NULL)
1095*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_return_dma_handle(adapter, head, tail, hdl_reserved);
1096*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1097*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_SPIN_UNLOCK(&adapter->tx_lock);
1098*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (B_FALSE);
1099*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1100*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1101*9a5557fdSlucy wang - Sun Microsystems - Beijing China static boolean_t
1102*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_xmit_frame(unm_adapter *adapter, mblk_t *mp)
1103*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1104*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	pktinfo_t	pktinfo;
1105*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	boolean_t	status = B_FALSE, send_mapped;
1106*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1107*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->stats.xmitcalled++;
1108*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1109*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	send_mapped = unm_get_pkt_info(mp, &pktinfo);
1110*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1111*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (pktinfo.total_len <= adapter->tx_bcopy_threshold ||
1112*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    pktinfo.mblk_no >= MAX_BUFFERS_PER_CMD)
1113*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		send_mapped = B_FALSE;
1114*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1115*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (send_mapped == B_TRUE)
1116*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		status = unm_send_mapped(adapter, mp, &pktinfo);
1117*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1118*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (status != B_TRUE) {
1119*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (pktinfo.total_len <= adapter->maxmtu)
1120*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			return (unm_send_copy(adapter, mp, &pktinfo));
1121*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1122*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* message too large */
1123*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		freemsg(mp);
1124*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->stats.txdropped++;
1125*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		status = B_TRUE;
1126*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1127*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1128*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (status);
1129*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1130*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1131*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
1132*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_check_temp(struct unm_adapter_s *adapter)
1133*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1134*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t temp, temp_state, temp_val;
1135*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int rv = 0;
1136*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1137*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((adapter->ahw.revision_id == NX_P3_A2) ||
1138*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    (adapter->ahw.revision_id == NX_P3_A0))
1139*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (0);
1140*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1141*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	temp = adapter->unm_nic_pci_read_normalize(adapter, CRB_TEMP_STATE);
1142*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1143*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	temp_state = nx_get_temp_state(temp);
1144*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	temp_val = nx_get_temp_val(temp);
1145*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1146*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (temp_state == NX_TEMP_PANIC) {
1147*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s: Device temperature %d C exceeds "
1148*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    "maximum allowed, device has been shut down\n",
1149*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    unm_nic_driver_name, temp_val);
1150*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		rv = 1;
1151*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else if (temp_state == NX_TEMP_WARN) {
1152*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (adapter->temp == NX_TEMP_NORMAL) {
1153*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s: Device temperature %d C exceeds"
1154*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    "operating range. Immediate action needed.\n",
1155*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    unm_nic_driver_name, temp_val);
1156*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1157*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
1158*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (adapter->temp == NX_TEMP_WARN) {
1159*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			cmn_err(CE_WARN, "%s: Device temperature is now %d "
1160*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    "degrees C in normal range.\n",
1161*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    unm_nic_driver_name, temp_val);
1162*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1163*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1164*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1165*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->temp = temp_state;
1166*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (rv);
1167*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1168*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1169*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
1170*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_watchdog(unsigned long v)
1171*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1172*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_adapter *adapter = (unm_adapter *)v;
1173*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1174*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((adapter->portnum == 0) && unm_nic_check_temp(adapter)) {
1175*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/*
1176*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * We return without turning on the netdev queue as there
1177*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * was an overheated device
1178*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 */
1179*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return;
1180*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1181*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1182*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_handle_phy_intr(adapter);
1183*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1184*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
1185*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * This function schedules a call for itself.
1186*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
1187*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->watchdog_timer = timeout((void (*)(void *))&unm_watchdog,
1188*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    (void *)adapter, 2 * drv_usectohz(1000000));
1189*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1190*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1191*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1192*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void unm_nic_clear_stats(unm_adapter *adapter)
1193*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1194*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) memset(&adapter->stats, 0, sizeof (adapter->stats));
1195*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1196*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1197*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
1198*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_poll(unm_adapter *adapter)
1199*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1200*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int	work_done, tx_complete;
1201*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1202*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->stats.polled++;
1203*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1204*9a5557fdSlucy wang - Sun Microsystems - Beijing China loop:
1205*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	tx_complete = unm_process_cmd_ring(adapter);
1206*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	work_done = unm_process_rcv_ring(adapter, NX_RX_MAXBUFS);
1207*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((!tx_complete) || (!(work_done < NX_RX_MAXBUFS)))
1208*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto loop;
1209*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1210*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_LOCK(&adapter->adapter_lock);
1211*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_enable_int(adapter);
1212*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_UNLOCK(&adapter->adapter_lock);
1213*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1214*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1215*9a5557fdSlucy wang - Sun Microsystems - Beijing China /* ARGSUSED */
1216*9a5557fdSlucy wang - Sun Microsystems - Beijing China uint_t
1217*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_intr(caddr_t data, caddr_t arg)
1218*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1219*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_adapter	*adapter = (unm_adapter *)(uintptr_t)data;
1220*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1221*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (unm_nic_clear_int(adapter))
1222*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_INTR_UNCLAIMED);
1223*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1224*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_poll(adapter);
1225*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_INTR_CLAIMED);
1226*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1227*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1228*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
1229*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * This is invoked from receive isr. Due to the single threaded nature
1230*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * of the invocation, pool_lock acquisition is not neccesary to protect
1231*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * pool_list.
1232*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
1233*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
1234*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_free_rx_buffer(unm_rcv_desc_ctx_t *rcv_desc, unm_rx_buffer_t *rx_buffer)
1235*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1236*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* mutex_enter(rcv_desc->pool_lock); */
1237*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	rx_buffer->next = rcv_desc->pool_list;
1238*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->pool_list = rx_buffer;
1239*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->rx_buf_free++;
1240*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* mutex_exit(rcv_desc->pool_lock); */
1241*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1242*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1243*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
1244*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * unm_process_rcv() send the received packet to the protocol stack.
1245*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
1246*9a5557fdSlucy wang - Sun Microsystems - Beijing China static mblk_t *
1247*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_process_rcv(unm_adapter *adapter, statusDesc_t *desc)
1248*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1249*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_recv_context_t	*recv_ctx = &(adapter->recv_ctx[0]);
1250*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rx_buffer_t		*rx_buffer;
1251*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	mblk_t *mp;
1252*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	u32			desc_ctx = desc->u1.s1.type;
1253*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rcv_desc_ctx_t	*rcv_desc = &recv_ctx->rcv_desc[desc_ctx];
1254*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	u32			pkt_length = desc->u1.s1.totalLength;
1255*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int			poff = desc->u1.s1.pkt_offset;
1256*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int			index, cksum_flags, docopy;
1257*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int			index_lo = desc->u1.s1.referenceHandle_lo;
1258*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	char			*vaddr;
1259*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1260*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	index = ((desc->u1.s1.referenceHandle_hi << 4) | index_lo);
1261*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1262*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	rx_buffer = index2rxbuf(rcv_desc, index);
1263*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1264*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (rx_buffer == NULL) {
1265*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "\r\nNULL rx_buffer idx=%d", index);
1266*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (NULL);
1267*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1268*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	vaddr = (char *)rx_buffer->dma_info.vaddr;
1269*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (vaddr == NULL) {
1270*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "\r\nNULL vaddr");
1271*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (NULL);
1272*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1273*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->rx_desc_handled++;
1274*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->rx_buf_card--;
1275*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1276*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(rx_buffer->dma_info.dma_hdl, 0,
1277*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    pkt_length + poff + (adapter->ahw.cut_through ? 0 :
1278*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    IP_ALIGNMENT_BYTES), DDI_DMA_SYNC_FORCPU);
1279*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1280*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
1281*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * Copy packet into new allocated message buffer, if pkt_length
1282*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * is below copy threshold.
1283*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
1284*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	docopy = (pkt_length <= adapter->rx_bcopy_threshold) ? 1 : 0;
1285*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1286*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
1287*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * If card is running out of rx buffers, then attempt to allocate
1288*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * new mblk so we can feed this rx buffer back to card (we
1289*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * _could_ look at what's pending on free and recycle lists).
1290*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
1291*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (rcv_desc->rx_buf_card < NX_RX_THRESHOLD) {
1292*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		docopy = 1;
1293*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->stats.rxbufshort++;
1294*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1295*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1296*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (docopy == 1) {
1297*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if ((mp = allocb(pkt_length + IP_ALIGNMENT_BYTES, 0)) == NULL) {
1298*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->stats.allocbfailed++;
1299*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto freebuf;
1300*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1301*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1302*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		mp->b_rptr += IP_ALIGNMENT_BYTES;
1303*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		vaddr += poff;
1304*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		bcopy(vaddr, mp->b_rptr, pkt_length);
1305*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->stats.rxcopyed++;
1306*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_free_rx_buffer(rcv_desc, rx_buffer);
1307*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
1308*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		mp = (mblk_t *)rx_buffer->mp;
1309*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (mp == NULL) {
1310*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			mp = desballoc(rx_buffer->dma_info.vaddr,
1311*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    rcv_desc->dma_size, 0, &rx_buffer->rx_recycle);
1312*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			if (mp == NULL) {
1313*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				adapter->stats.desballocfailed++;
1314*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				goto freebuf;
1315*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			}
1316*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rx_buffer->mp = mp;
1317*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1318*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		mp->b_rptr += poff;
1319*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->stats.rxmapped++;
1320*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1321*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1322*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	mp->b_wptr = (uchar_t *)((unsigned long)mp->b_rptr + pkt_length);
1323*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1324*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (desc->u1.s1.status == STATUS_CKSUM_OK) {
1325*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->stats.csummed++;
1326*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cksum_flags =
1327*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    HCK_FULLCKSUM_OK | HCK_IPV4_HDRCKSUM | HCK_FULLCKSUM;
1328*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
1329*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cksum_flags = 0;
1330*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1331*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) hcksum_assoc(mp, NULL, NULL, 0, 0, 0, 0, cksum_flags, 0);
1332*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1333*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->stats.no_rcv++;
1334*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->stats.rxbytes += pkt_length;
1335*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->stats.uphappy++;
1336*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1337*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (mp);
1338*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1339*9a5557fdSlucy wang - Sun Microsystems - Beijing China freebuf:
1340*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_free_rx_buffer(rcv_desc, rx_buffer);
1341*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (NULL);
1342*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1343*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1344*9a5557fdSlucy wang - Sun Microsystems - Beijing China /* Process Receive status ring */
1345*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
1346*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_process_rcv_ring(unm_adapter *adapter, int max)
1347*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1348*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_recv_context_t	*recv_ctx = &(adapter->recv_ctx[0]);
1349*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	statusDesc_t		*desc_head = recv_ctx->rcvStatusDescHead;
1350*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	statusDesc_t		*desc = NULL;
1351*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t		consumer, start;
1352*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int			count = 0, ring;
1353*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	mblk_t *mp;
1354*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1355*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	start = consumer = recv_ctx->statusRxConsumer;
1356*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1357*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_desc_dma_sync(recv_ctx->status_desc_dma_handle, start, max,
1358*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    adapter->MaxRxDescCount, sizeof (statusDesc_t),
1359*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    DDI_DMA_SYNC_FORCPU);
1360*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1361*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	while (count < max) {
1362*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		desc = &desc_head[consumer];
1363*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (!(desc->u1.s1.owner & STATUS_OWNER_HOST))
1364*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
1365*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1366*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		mp = unm_process_rcv(adapter, desc);
1367*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		desc->u1.s1.owner = STATUS_OWNER_PHANTOM;
1368*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1369*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		consumer = (consumer + 1) % adapter->MaxRxDescCount;
1370*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		count++;
1371*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (mp != NULL)
1372*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			mac_rx(adapter->mach, NULL, mp);
1373*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1374*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1375*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1376*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (recv_ctx->rcv_desc[ring].rx_desc_handled > 0)
1377*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			unm_post_rx_buffers_nodb(adapter, ring);
1378*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1379*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1380*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (count) {
1381*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_desc_dma_sync(recv_ctx->status_desc_dma_handle, start,
1382*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    count, adapter->MaxRxDescCount, sizeof (statusDesc_t),
1383*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORDEV);
1384*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1385*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* update the consumer index in phantom */
1386*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		recv_ctx->statusRxConsumer = consumer;
1387*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1388*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_READ_LOCK(&adapter->adapter_lock);
1389*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_hw_write_wx(adapter,
1390*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    recv_ctx->host_sds_consumer, &consumer, 4);
1391*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_READ_UNLOCK(&adapter->adapter_lock);
1392*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1393*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1394*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (count);
1395*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1396*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1397*9a5557fdSlucy wang - Sun Microsystems - Beijing China /* Process Command status ring */
1398*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
1399*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_process_cmd_ring(struct unm_adapter_s *adapter)
1400*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1401*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	u32			last_consumer;
1402*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	u32			consumer;
1403*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int			count = 0;
1404*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct unm_cmd_buffer	*buffer;
1405*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int			done;
1406*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_dmah_node_t *dmah, *head = NULL, *tail = NULL;
1407*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	uint32_t	free_hdls = 0;
1408*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1409*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(adapter->ctxDesc_dma_handle, sizeof (RingContext),
1410*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    sizeof (uint32_t), DDI_DMA_SYNC_FORCPU);
1411*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1412*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	last_consumer = adapter->lastCmdConsumer;
1413*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	consumer = *(adapter->cmdConsumer);
1414*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1415*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	while (last_consumer != consumer) {
1416*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		buffer = &adapter->cmd_buf_arr[last_consumer];
1417*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (buffer->head != NULL) {
1418*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			dmah = buffer->head;
1419*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			while (dmah != NULL) {
1420*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				(void) ddi_dma_unbind_handle(dmah->dmahdl);
1421*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				dmah = dmah->next;
1422*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				free_hdls++;
1423*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			}
1424*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1425*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			if (head == NULL) {
1426*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				head = buffer->head;
1427*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				tail = buffer->tail;
1428*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			} else {
1429*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				tail->next = buffer->head;
1430*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				tail = buffer->tail;
1431*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			}
1432*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1433*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			buffer->head = NULL;
1434*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			buffer->tail = NULL;
1435*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1436*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			if (buffer->msg != NULL) {
1437*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				freemsg(buffer->msg);
1438*9a5557fdSlucy wang - Sun Microsystems - Beijing China 				buffer->msg = NULL;
1439*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			}
1440*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1441*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1442*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		last_consumer = get_next_index(last_consumer,
1443*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->MaxTxDescCount);
1444*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (++count > NX_MAX_TXCOMPS)
1445*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
1446*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1447*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1448*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (count) {
1449*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		int	doresched;
1450*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1451*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_SPIN_LOCK(&adapter->tx_lock);
1452*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->lastCmdConsumer = last_consumer;
1453*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->freecmds += count;
1454*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		membar_exit();
1455*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1456*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		doresched = adapter->resched_needed;
1457*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (doresched)
1458*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->resched_needed = 0;
1459*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1460*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (head != NULL)
1461*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			unm_return_dma_handle(adapter, head, tail, free_hdls);
1462*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1463*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_SPIN_UNLOCK(&adapter->tx_lock);
1464*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1465*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (doresched)
1466*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			mac_tx_update(adapter->mach);
1467*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1468*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1469*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) ddi_dma_sync(adapter->ctxDesc_dma_handle, sizeof (RingContext),
1470*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    sizeof (uint32_t), DDI_DMA_SYNC_FORCPU);
1471*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1472*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	consumer = *(adapter->cmdConsumer);
1473*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	done = (adapter->lastCmdConsumer == consumer);
1474*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1475*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (done);
1476*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1477*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1478*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
1479*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * This is invoked from receive isr, and at initialization time when no
1480*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * rx buffers have been posted to card. Due to the single threaded nature
1481*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * of the invocation, pool_lock acquisition is not neccesary to protect
1482*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * pool_list.
1483*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
1484*9a5557fdSlucy wang - Sun Microsystems - Beijing China static unm_rx_buffer_t *
1485*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_reserve_rx_buffer(unm_rcv_desc_ctx_t *rcv_desc)
1486*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1487*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rx_buffer_t *rx_buffer = NULL;
1488*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1489*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* mutex_enter(rcv_desc->pool_lock); */
1490*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (rcv_desc->rx_buf_free) {
1491*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		rx_buffer = rcv_desc->pool_list;
1492*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		rcv_desc->pool_list = rx_buffer->next;
1493*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		rx_buffer->next = NULL;
1494*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		rcv_desc->rx_buf_free--;
1495*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
1496*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		mutex_enter(rcv_desc->recycle_lock);
1497*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1498*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (rcv_desc->rx_buf_recycle) {
1499*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rcv_desc->pool_list = rcv_desc->recycle_list;
1500*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rcv_desc->recycle_list = NULL;
1501*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rcv_desc->rx_buf_free += rcv_desc->rx_buf_recycle;
1502*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rcv_desc->rx_buf_recycle = 0;
1503*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1504*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rx_buffer = rcv_desc->pool_list;
1505*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rcv_desc->pool_list = rx_buffer->next;
1506*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rx_buffer->next = NULL;
1507*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			rcv_desc->rx_buf_free--;
1508*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1509*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1510*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		mutex_exit(rcv_desc->recycle_lock);
1511*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1512*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1513*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* mutex_exit(rcv_desc->pool_lock); */
1514*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (rx_buffer);
1515*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1516*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1517*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
1518*9a5557fdSlucy wang - Sun Microsystems - Beijing China post_rx_doorbell(struct unm_adapter_s *adapter, uint32_t ringid, int count)
1519*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1520*9a5557fdSlucy wang - Sun Microsystems - Beijing China #define	UNM_RCV_PEG_DB_ID	2
1521*9a5557fdSlucy wang - Sun Microsystems - Beijing China #define	UNM_RCV_PRODUCER_OFFSET	0
1522*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ctx_msg msg = {0};
1523*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1524*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
1525*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * Write a doorbell msg to tell phanmon of change in
1526*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * receive ring producer
1527*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
1528*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	msg.PegId = UNM_RCV_PEG_DB_ID;
1529*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	msg.privId = 1;
1530*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	msg.Count = count;
1531*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	msg.CtxId = adapter->portnum;
1532*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	msg.Opcode = UNM_RCV_PRODUCER(ringid);
1533*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	dbwritel(*((__uint32_t *)&msg),
1534*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    (void *)(DB_NORMALIZE(adapter, UNM_RCV_PRODUCER_OFFSET)));
1535*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1536*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1537*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
1538*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_post_rx_buffers(struct unm_adapter_s *adapter, uint32_t ringid)
1539*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1540*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_recv_context_t	*recv_ctx = &(adapter->recv_ctx[0]);
1541*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rcv_desc_ctx_t	*rcv_desc = &recv_ctx->rcv_desc[ringid];
1542*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rx_buffer_t		*rx_buffer;
1543*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcvDesc_t		*pdesc;
1544*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int			count;
1545*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1546*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (count = 0; count < rcv_desc->MaxRxDescCount; count++) {
1547*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		rx_buffer = unm_reserve_rx_buffer(rcv_desc);
1548*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (rx_buffer != NULL) {
1549*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			pdesc = &rcv_desc->desc_head[count];
1550*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			pdesc->referenceHandle = rxbuf2index(rcv_desc,
1551*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    rx_buffer);
1552*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			pdesc->flags = ringid;
1553*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			pdesc->bufferLength = rcv_desc->dma_size;
1554*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			pdesc->AddrBuffer = rx_buffer->dma_info.dma_addr;
1555*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1556*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		else
1557*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			return (DDI_FAILURE);
1558*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1559*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1560*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->producer = count % rcv_desc->MaxRxDescCount;
1561*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	count--;
1562*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_desc_dma_sync(rcv_desc->rx_desc_dma_handle,
1563*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    0,		/* start */
1564*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    count,	/* count */
1565*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    count,	/* range */
1566*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    sizeof (rcvDesc_t),	/* unit_size */
1567*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    DDI_DMA_SYNC_FORDEV);	/* direction */
1568*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1569*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcv_desc->rx_buf_card = rcv_desc->MaxRxDescCount;
1570*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_LOCK(&adapter->adapter_lock);
1571*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->unm_nic_hw_write_wx(adapter, rcv_desc->host_rx_producer,
1572*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &count, 4);
1573*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->fw_major < 4)
1574*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		post_rx_doorbell(adapter, ringid, count);
1575*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_UNLOCK(&adapter->adapter_lock);
1576*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1577*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
1578*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1579*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1580*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
1581*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_post_rx_buffers_nodb(struct unm_adapter_s *adapter,
1582*9a5557fdSlucy wang - Sun Microsystems - Beijing China     uint32_t ringid)
1583*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1584*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_recv_context_t	*recv_ctx = &(adapter->recv_ctx[0]);
1585*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_rcv_desc_ctx_t	*rcv_desc = &recv_ctx->rcv_desc[ringid];
1586*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct unm_rx_buffer	*rx_buffer;
1587*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	rcvDesc_t		*pdesc;
1588*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int 			count, producer = rcv_desc->producer;
1589*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int 			last_producer = producer;
1590*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1591*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (count = 0; count < rcv_desc->rx_desc_handled; count++) {
1592*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		rx_buffer = unm_reserve_rx_buffer(rcv_desc);
1593*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (rx_buffer != NULL) {
1594*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			pdesc = &rcv_desc->desc_head[producer];
1595*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			pdesc->referenceHandle = rxbuf2index(rcv_desc,
1596*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    rx_buffer);
1597*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			pdesc->flags = ringid;
1598*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			pdesc->bufferLength = rcv_desc->dma_size;
1599*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			pdesc->AddrBuffer = rx_buffer->dma_info.dma_addr;
1600*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		} else {
1601*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->stats.outofrxbuf++;
1602*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
1603*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1604*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		producer = get_next_index(producer, rcv_desc->MaxRxDescCount);
1605*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1606*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1607*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* if we did allocate buffers, then write the count to Phantom */
1608*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (count) {
1609*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* Sync rx ring, considering case for wrap around */
1610*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_desc_dma_sync(rcv_desc->rx_desc_dma_handle, last_producer,
1611*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    count, rcv_desc->MaxRxDescCount, sizeof (rcvDesc_t),
1612*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    DDI_DMA_SYNC_FORDEV);
1613*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1614*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		rcv_desc->producer = producer;
1615*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		rcv_desc->rx_desc_handled -= count;
1616*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		rcv_desc->rx_buf_card += count;
1617*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1618*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		producer = (producer - 1) % rcv_desc->MaxRxDescCount;
1619*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_READ_LOCK(&adapter->adapter_lock);
1620*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->unm_nic_hw_write_wx(adapter,
1621*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    rcv_desc->host_rx_producer, &producer, 4);
1622*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_READ_UNLOCK(&adapter->adapter_lock);
1623*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1624*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1625*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1626*9a5557fdSlucy wang - Sun Microsystems - Beijing China int
1627*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_fill_statistics_128M(struct unm_adapter_s *adapter,
1628*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    struct unm_statistics *unm_stats)
1629*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1630*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	void *addr;
1631*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->ahw.board_type == UNM_NIC_XGBE) {
1632*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_WRITE_LOCK(&adapter->adapter_lock);
1633*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
1634*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1635*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* LINTED: E_FALSE_LOGICAL_EXPR */
1636*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_TX_BYTE_CNT,
1637*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->tx_bytes));
1638*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* LINTED: E_FALSE_LOGICAL_EXPR */
1639*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_TX_FRAME_CNT,
1640*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->tx_packets));
1641*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* LINTED: E_FALSE_LOGICAL_EXPR */
1642*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_RX_BYTE_CNT,
1643*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->rx_bytes));
1644*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* LINTED: E_FALSE_LOGICAL_EXPR */
1645*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_RX_FRAME_CNT,
1646*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->rx_packets));
1647*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* LINTED: E_FALSE_LOGICAL_EXPR */
1648*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_AGGR_ERROR_CNT,
1649*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->rx_errors));
1650*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* LINTED: E_FALSE_LOGICAL_EXPR */
1651*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_CRC_ERROR_CNT,
1652*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->rx_CRC_errors));
1653*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* LINTED: E_FALSE_LOGICAL_EXPR */
1654*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_OVERSIZE_FRAME_ERR,
1655*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->rx_long_length_error));
1656*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* LINTED: E_FALSE_LOGICAL_EXPR */
1657*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_NIC_LOCKED_READ_REG(UNM_NIU_XGE_UNDERSIZE_FRAME_ERR,
1658*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->rx_short_length_error));
1659*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1660*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/*
1661*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * For reading rx_MAC_error bit different procedure
1662*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_TEST_MUX_CTL, 0x15);
1663*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * UNM_NIC_LOCKED_READ_REG((UNM_CRB_NIU + 0xC0), &temp);
1664*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * unm_stats->rx_MAC_errors = temp & 0xff;
1665*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 */
1666*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1667*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
1668*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_WRITE_UNLOCK(&adapter->adapter_lock);
1669*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
1670*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_SPIN_LOCK_ISR(&adapter->tx_lock);
1671*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->tx_bytes = adapter->stats.txbytes;
1672*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->tx_packets = adapter->stats.xmitedframes +
1673*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->stats.xmitfinished;
1674*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_bytes = adapter->stats.rxbytes;
1675*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_packets = adapter->stats.no_rcv;
1676*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_errors = adapter->stats.rcvdbadmsg;
1677*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->tx_errors = adapter->stats.nocmddescriptor;
1678*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_short_length_error = adapter->stats.uplcong;
1679*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_long_length_error = adapter->stats.uphcong;
1680*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_CRC_errors = 0;
1681*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_MAC_errors = 0;
1682*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_SPIN_UNLOCK_ISR(&adapter->tx_lock);
1683*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1684*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (0);
1685*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1686*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1687*9a5557fdSlucy wang - Sun Microsystems - Beijing China int
1688*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_fill_statistics_2M(struct unm_adapter_s *adapter,
1689*9a5557fdSlucy wang - Sun Microsystems - Beijing China     struct unm_statistics *unm_stats)
1690*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1691*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->ahw.board_type == UNM_NIC_XGBE) {
1692*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) unm_nic_hw_read_wx_2M(adapter, UNM_NIU_XGE_TX_BYTE_CNT,
1693*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->tx_bytes), 4);
1694*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) unm_nic_hw_read_wx_2M(adapter, UNM_NIU_XGE_TX_FRAME_CNT,
1695*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->tx_packets), 4);
1696*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) unm_nic_hw_read_wx_2M(adapter, UNM_NIU_XGE_RX_BYTE_CNT,
1697*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->rx_bytes), 4);
1698*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) unm_nic_hw_read_wx_2M(adapter, UNM_NIU_XGE_RX_FRAME_CNT,
1699*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->rx_packets), 4);
1700*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) unm_nic_hw_read_wx_2M(adapter,
1701*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    UNM_NIU_XGE_AGGR_ERROR_CNT, &(unm_stats->rx_errors), 4);
1702*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) unm_nic_hw_read_wx_2M(adapter, UNM_NIU_XGE_CRC_ERROR_CNT,
1703*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->rx_CRC_errors), 4);
1704*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) unm_nic_hw_read_wx_2M(adapter,
1705*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    UNM_NIU_XGE_OVERSIZE_FRAME_ERR,
1706*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->rx_long_length_error), 4);
1707*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) unm_nic_hw_read_wx_2M(adapter,
1708*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    UNM_NIU_XGE_UNDERSIZE_FRAME_ERR,
1709*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &(unm_stats->rx_short_length_error), 4);
1710*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
1711*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_SPIN_LOCK_ISR(&adapter->tx_lock);
1712*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->tx_bytes = adapter->stats.txbytes;
1713*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->tx_packets = adapter->stats.xmitedframes +
1714*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->stats.xmitfinished;
1715*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_bytes = adapter->stats.rxbytes;
1716*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_packets = adapter->stats.no_rcv;
1717*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_errors = adapter->stats.rcvdbadmsg;
1718*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->tx_errors = adapter->stats.nocmddescriptor;
1719*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_short_length_error = adapter->stats.uplcong;
1720*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_long_length_error = adapter->stats.uphcong;
1721*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_CRC_errors = 0;
1722*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_stats->rx_MAC_errors = 0;
1723*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_SPIN_UNLOCK_ISR(&adapter->tx_lock);
1724*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1725*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (0);
1726*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1727*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1728*9a5557fdSlucy wang - Sun Microsystems - Beijing China int
1729*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_clear_statistics_128M(struct unm_adapter_s *adapter)
1730*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1731*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	void *addr;
1732*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int data = 0;
1733*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1734*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_WRITE_LOCK(&adapter->adapter_lock);
1735*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_pci_change_crbwindow_128M(adapter, 0);
1736*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1737*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* LINTED: E_FALSE_LOGICAL_EXPR */
1738*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_TX_BYTE_CNT, &data);
1739*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* LINTED: E_FALSE_LOGICAL_EXPR */
1740*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_TX_FRAME_CNT, &data);
1741*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* LINTED: E_FALSE_LOGICAL_EXPR */
1742*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_RX_BYTE_CNT, &data);
1743*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* LINTED: E_FALSE_LOGICAL_EXPR */
1744*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_RX_FRAME_CNT, &data);
1745*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* LINTED: E_FALSE_LOGICAL_EXPR */
1746*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_AGGR_ERROR_CNT, &data);
1747*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* LINTED: E_FALSE_LOGICAL_EXPR */
1748*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_CRC_ERROR_CNT, &data);
1749*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* LINTED: E_FALSE_LOGICAL_EXPR */
1750*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_OVERSIZE_FRAME_ERR, &data);
1751*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* LINTED: E_FALSE_LOGICAL_EXPR */
1752*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_NIC_LOCKED_WRITE_REG(UNM_NIU_XGE_UNDERSIZE_FRAME_ERR, &data);
1753*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1754*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_pci_change_crbwindow_128M(adapter, 1);
1755*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_WRITE_UNLOCK(&adapter->adapter_lock);
1756*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_clear_stats(adapter);
1757*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (0);
1758*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1759*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1760*9a5557fdSlucy wang - Sun Microsystems - Beijing China int
1761*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_clear_statistics_2M(struct unm_adapter_s *adapter)
1762*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1763*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int data = 0;
1764*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1765*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_TX_BYTE_CNT,
1766*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &data, 4);
1767*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_TX_FRAME_CNT,
1768*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &data, 4);
1769*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_RX_BYTE_CNT,
1770*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &data, 4);
1771*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_RX_FRAME_CNT,
1772*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &data, 4);
1773*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_AGGR_ERROR_CNT,
1774*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &data, 4);
1775*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_CRC_ERROR_CNT,
1776*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &data, 4);
1777*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_OVERSIZE_FRAME_ERR,
1778*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &data, 4);
1779*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) unm_nic_hw_write_wx_2M(adapter, UNM_NIU_XGE_UNDERSIZE_FRAME_ERR,
1780*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    &data, 4);
1781*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_clear_stats(adapter);
1782*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (0);
1783*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1784*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1785*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
1786*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * unm_nic_ioctl ()    We provide the tcl/phanmon support
1787*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * through these ioctls.
1788*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
1789*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
1790*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_ioctl(struct unm_adapter_s *adapter, int cmd, queue_t *q, mblk_t *mp)
1791*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1792*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	void *ptr;
1793*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1794*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	switch (cmd) {
1795*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case UNM_NIC_CMD:
1796*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) unm_nic_do_ioctl(adapter, q, mp);
1797*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
1798*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1799*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case UNM_NIC_NAME:
1800*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		ptr = (void *) mp->b_cont->b_rptr;
1801*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1802*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/*
1803*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * Phanmon checks for "UNM-UNM" string
1804*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * Replace the hardcoded value with appropriate macro
1805*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 */
1806*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		DPRINTF(-1, (CE_CONT, "UNM_NIC_NAME ioctl executed %d %d\n",
1807*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    cmd, __LINE__));
1808*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) memcpy(ptr, "UNM-UNM", 10);
1809*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		miocack(q, mp, 10, 0);
1810*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
1811*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1812*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	default:
1813*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "Netxen ioctl cmd %x not supported\n", cmd);
1814*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1815*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		miocnak(q, mp, 0, EINVAL);
1816*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
1817*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1818*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1819*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1820*9a5557fdSlucy wang - Sun Microsystems - Beijing China int
1821*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_resume(unm_adapter *adapter)
1822*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1823*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1824*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->watchdog_timer = timeout((void (*)(void *))&unm_watchdog,
1825*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    (void *) adapter, 50000);
1826*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1827*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->intr_type == DDI_INTR_TYPE_MSI)
1828*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) ddi_intr_block_enable(&adapter->intr_handle, 1);
1829*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	else
1830*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) ddi_intr_enable(adapter->intr_handle);
1831*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_LOCK(&adapter->adapter_lock);
1832*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_enable_int(adapter);
1833*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_UNLOCK(&adapter->adapter_lock);
1834*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1835*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	mac_link_update(adapter->mach, LINK_STATE_UP);
1836*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1837*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
1838*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1839*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1840*9a5557fdSlucy wang - Sun Microsystems - Beijing China int
1841*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_suspend(unm_adapter *adapter)
1842*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1843*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	mac_link_update(adapter->mach, LINK_STATE_DOWN);
1844*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1845*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) untimeout(adapter->watchdog_timer);
1846*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1847*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_LOCK(&adapter->adapter_lock);
1848*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_disable_int(adapter);
1849*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_READ_UNLOCK(&adapter->adapter_lock);
1850*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->intr_type == DDI_INTR_TYPE_MSI)
1851*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) ddi_intr_block_disable(&adapter->intr_handle, 1);
1852*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	else
1853*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) ddi_intr_disable(adapter->intr_handle);
1854*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1855*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
1856*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
1857*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1858*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
1859*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_do_ioctl(unm_adapter *adapter, queue_t *wq, mblk_t *mp)
1860*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
1861*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_ioctl_data_t		data;
1862*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct unm_nic_ioctl_data	*up_data;
1863*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ddi_acc_handle_t		conf_handle;
1864*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int				retval = 0;
1865*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unsigned int			efuse_chip_id;
1866*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	char				*ptr1;
1867*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	short				*ptr2;
1868*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int				*ptr4;
1869*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1870*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	up_data = (struct unm_nic_ioctl_data *)(mp->b_cont->b_rptr);
1871*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(void) memcpy(&data, (void **)(uintptr_t)(mp->b_cont->b_rptr),
1872*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    sizeof (data));
1873*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1874*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* Shouldn't access beyond legal limits of  "char u[64];" member */
1875*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (data.size > sizeof (data.uabc)) {
1876*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/* evil user tried to crash the kernel */
1877*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "bad size: %d\n", data.size);
1878*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		retval = GLD_BADARG;
1879*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto error_out;
1880*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
1881*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1882*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	switch (data.cmd) {
1883*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case unm_nic_cmd_pci_read:
1884*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1885*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if ((retval = adapter->unm_nic_hw_read_ioctl(adapter,
1886*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    data.off, up_data, data.size))) {
1887*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			DPRINTF(-1, (CE_WARN, "%s(%d) unm_nic_hw_read_wx "
1888*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    "returned %d\n", __FUNCTION__, __LINE__, retval));
1889*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1890*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			retval = data.rv;
1891*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto error_out;
1892*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1893*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1894*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		data.rv = 0;
1895*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
1896*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1897*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case unm_nic_cmd_pci_write:
1898*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if ((data.rv = adapter->unm_nic_hw_write_ioctl(adapter,
1899*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    data.off, &(data.uabc), data.size))) {
1900*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			DPRINTF(-1, (CE_WARN, "%s(%d) unm_nic_hw_write_wx "
1901*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    "returned %d\n", __FUNCTION__,
1902*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    __LINE__, data.rv));
1903*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			retval = data.rv;
1904*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto error_out;
1905*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1906*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		data.size = 0;
1907*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
1908*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1909*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case unm_nic_cmd_pci_mem_read:
1910*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if ((data.rv = adapter->unm_nic_pci_mem_read(adapter,
1911*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    data.off, up_data, data.size))) {
1912*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			DPRINTF(-1, (CE_WARN, "%s(%d) unm_nic_pci_mem_read "
1913*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    "returned %d\n", __FUNCTION__,
1914*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    __LINE__, data.rv));
1915*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			retval = data.rv;
1916*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto error_out;
1917*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1918*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		data.rv = 0;
1919*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
1920*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1921*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case unm_nic_cmd_pci_mem_write:
1922*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if ((data.rv = adapter->unm_nic_pci_mem_write(adapter,
1923*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    data.off, &(data.uabc), data.size))) {
1924*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			DPRINTF(-1, (CE_WARN,
1925*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    "%s(%d) unm_nic_cmd_pci_mem_write "
1926*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    "returned %d\n",
1927*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    __FUNCTION__, __LINE__, data.rv));
1928*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			retval = data.rv;
1929*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto error_out;
1930*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1931*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1932*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		data.size = 0;
1933*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		data.rv = 0;
1934*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
1935*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1936*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case unm_nic_cmd_pci_config_read:
1937*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1938*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (adapter->pci_cfg_handle != NULL) {
1939*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			conf_handle = adapter->pci_cfg_handle;
1940*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1941*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		} else if ((retval = pci_config_setup(adapter->dip,
1942*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &conf_handle)) != DDI_SUCCESS) {
1943*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			DPRINTF(-1, (CE_WARN, "!%s: pci_config_setup failed"
1944*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    " error:%d\n", unm_nic_driver_name, retval));
1945*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto error_out;
1946*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1947*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		} else
1948*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->pci_cfg_handle = conf_handle;
1949*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1950*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		switch (data.size) {
1951*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case 1:
1952*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			ptr1 = (char *)up_data;
1953*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			*ptr1 = (char)pci_config_get8(conf_handle, data.off);
1954*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
1955*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case 2:
1956*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			ptr2 = (short *)up_data;
1957*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			*ptr2 = (short)pci_config_get16(conf_handle, data.off);
1958*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
1959*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case 4:
1960*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			ptr4 = (int *)up_data;
1961*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			*ptr4 = (int)pci_config_get32(conf_handle, data.off);
1962*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
1963*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1964*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1965*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
1966*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1967*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case unm_nic_cmd_pci_config_write:
1968*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1969*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (adapter->pci_cfg_handle != NULL) {
1970*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			conf_handle = adapter->pci_cfg_handle;
1971*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		} else if ((retval = pci_config_setup(adapter->dip,
1972*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    &conf_handle)) != DDI_SUCCESS) {
1973*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			DPRINTF(-1, (CE_WARN, "!%s: pci_config_setup failed"
1974*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    " error:%d\n", unm_nic_driver_name, retval));
1975*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			goto error_out;
1976*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		} else {
1977*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->pci_cfg_handle = conf_handle;
1978*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1979*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1980*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		switch (data.size) {
1981*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case 1:
1982*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			pci_config_put8(conf_handle,
1983*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    data.off, *(char *)&(data.uabc));
1984*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
1985*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case 2:
1986*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			pci_config_put16(conf_handle,
1987*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    data.off, *(short *)(uintptr_t)&(data.uabc));
1988*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
1989*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case 4:
1990*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			pci_config_put32(conf_handle,
1991*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    data.off, *(u32 *)(uintptr_t)&(data.uabc));
1992*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
1993*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
1994*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		data.size = 0;
1995*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
1996*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
1997*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case unm_nic_cmd_get_stats:
1998*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		data.rv = adapter->unm_nic_fill_statistics(adapter,
1999*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    (struct unm_statistics *)up_data);
2000*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		data.size = sizeof (struct unm_statistics);
2001*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2002*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2003*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2004*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case unm_nic_cmd_clear_stats:
2005*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		data.rv = adapter->unm_nic_clear_statistics(adapter);
2006*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2007*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2008*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case unm_nic_cmd_get_version:
2009*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) memcpy(up_data, UNM_NIC_VERSIONID,
2010*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    sizeof (UNM_NIC_VERSIONID));
2011*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		data.size = sizeof (UNM_NIC_VERSIONID);
2012*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2013*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2014*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2015*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case unm_nic_cmd_get_phy_type:
2016*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "unm_nic_cmd_get_phy_type unimplemented\n");
2017*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2018*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2019*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case unm_nic_cmd_efuse_chip_id:
2020*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		efuse_chip_id = adapter->unm_nic_pci_read_normalize(adapter,
2021*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    UNM_EFUSE_CHIP_ID);
2022*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) memcpy(up_data, &efuse_chip_id, sizeof (unsigned long));
2023*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		data.rv = 0;
2024*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2025*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2026*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	default:
2027*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: bad command %d\n", adapter->name,
2028*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->instance, data.cmd);
2029*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		data.rv = GLD_NOTSUPPORTED;
2030*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		data.size = 0;
2031*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		goto error_out;
2032*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2033*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2034*9a5557fdSlucy wang - Sun Microsystems - Beijing China work_done:
2035*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	miocack(wq, mp, data.size, data.rv);
2036*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
2037*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2038*9a5557fdSlucy wang - Sun Microsystems - Beijing China error_out:
2039*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	cmn_err(CE_WARN, "%s(%d) ioctl error\n", __FUNCTION__, data.cmd);
2040*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	miocnak(wq, mp, 0, EINVAL);
2041*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (retval);
2042*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2043*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2044*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
2045*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * Local datatype for defining tables of (Offset, Name) pairs
2046*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
2047*9a5557fdSlucy wang - Sun Microsystems - Beijing China typedef struct {
2048*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	offset_t	index;
2049*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	char		*name;
2050*9a5557fdSlucy wang - Sun Microsystems - Beijing China } unm_ksindex_t;
2051*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2052*9a5557fdSlucy wang - Sun Microsystems - Beijing China static const unm_ksindex_t unm_kstat[] = {
2053*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 0,		"freehdls"		},
2054*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 1,		"freecmds"		},
2055*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 2,		"tx_bcopy_threshold"	},
2056*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 3,		"rx_bcopy_threshold"	},
2057*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 4,		"xmitcalled"		},
2058*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 5,		"xmitedframes"		},
2059*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 6,		"xmitfinished"		},
2060*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 7,		"txbytes"		},
2061*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 8,		"txcopyed"		},
2062*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 9,		"txmapped"		},
2063*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 10,		"outoftxdmahdl"		},
2064*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 11,		"outofcmddesc"		},
2065*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 12,		"txdropped"		},
2066*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 13,		"polled"		},
2067*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 14,		"uphappy"		},
2068*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 15,		"updropped"		},
2069*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 16,		"csummed"		},
2070*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 17,		"no_rcv"		},
2071*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 18,		"rxbytes"		},
2072*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 19,		"rxcopyed"		},
2073*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 20,		"rxmapped"		},
2074*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 21,		"desballocfailed"	},
2075*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 22,		"outofrxbuf"		},
2076*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 23,		"promiscmode"		},
2077*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 24,		"rxbufshort"		},
2078*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ 25,		"allocbfailed"		},
2079*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	{ -1,		NULL			}
2080*9a5557fdSlucy wang - Sun Microsystems - Beijing China };
2081*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2082*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
2083*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_kstat_update(kstat_t *ksp, int flag)
2084*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2085*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_adapter *adapter;
2086*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	kstat_named_t *knp;
2087*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2088*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (flag != KSTAT_READ)
2089*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (EACCES);
2090*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2091*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter = ksp->ks_private;
2092*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	knp = ksp->ks_data;
2093*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2094*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui32 = adapter->freehdls;
2095*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->freecmds;
2096*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->tx_bcopy_threshold;
2097*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->rx_bcopy_threshold;
2098*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2099*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.xmitcalled;
2100*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.xmitedframes;
2101*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.xmitfinished;
2102*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.txbytes;
2103*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.txcopyed;
2104*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.txmapped;
2105*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.outoftxdmahdl;
2106*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.outofcmddesc;
2107*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.txdropped;
2108*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.polled;
2109*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.uphappy;
2110*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.updropped;
2111*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.csummed;
2112*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.no_rcv;
2113*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.rxbytes;
2114*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.rxcopyed;
2115*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.rxmapped;
2116*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.desballocfailed;
2117*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.outofrxbuf;
2118*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.promiscmode;
2119*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.rxbufshort;
2120*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	(knp++)->value.ui64 = adapter->stats.allocbfailed;
2121*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2122*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (0);
2123*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2124*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2125*9a5557fdSlucy wang - Sun Microsystems - Beijing China static kstat_t *
2126*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_setup_named_kstat(unm_adapter *adapter, int instance, char *name,
2127*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	const unm_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int))
2128*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2129*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	kstat_t *ksp;
2130*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	kstat_named_t *knp;
2131*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	char *np;
2132*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int type;
2133*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int count = 0;
2134*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2135*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	size /= sizeof (unm_ksindex_t);
2136*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ksp = kstat_create(unm_nic_driver_name, instance, name, "net",
2137*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    KSTAT_TYPE_NAMED, size-1, KSTAT_FLAG_PERSISTENT);
2138*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ksp == NULL)
2139*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (NULL);
2140*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2141*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ksp->ks_private = adapter;
2142*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ksp->ks_update = update;
2143*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) {
2144*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		count++;
2145*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		switch (*np) {
2146*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		default:
2147*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			type = KSTAT_DATA_UINT64;
2148*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
2149*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case '%':
2150*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			np += 1;
2151*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			type = KSTAT_DATA_UINT32;
2152*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
2153*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case '$':
2154*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			np += 1;
2155*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			type = KSTAT_DATA_STRING;
2156*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
2157*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case '&':
2158*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			np += 1;
2159*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			type = KSTAT_DATA_CHAR;
2160*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
2161*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
2162*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		kstat_named_init(knp, np, type);
2163*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2164*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	kstat_install(ksp);
2165*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2166*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (ksp);
2167*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2168*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2169*9a5557fdSlucy wang - Sun Microsystems - Beijing China void
2170*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_init_kstats(unm_adapter* adapter, int instance)
2171*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2172*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->kstats[0] = unm_setup_named_kstat(adapter,
2173*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    instance, "kstatinfo", unm_kstat,
2174*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    sizeof (unm_kstat), unm_kstat_update);
2175*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2176*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2177*9a5557fdSlucy wang - Sun Microsystems - Beijing China void
2178*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_fini_kstats(unm_adapter* adapter)
2179*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2180*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2181*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->kstats[0] != NULL) {
2182*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			kstat_delete(adapter->kstats[0]);
2183*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			adapter->kstats[0] = NULL;
2184*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
2185*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2186*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2187*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
2188*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_nic_set_pauseparam(unm_adapter *adapter, unm_pauseparam_t *pause)
2189*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2190*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int ret = 0;
2191*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2192*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->ahw.board_type == UNM_NIC_GBE) {
2193*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (unm_niu_gbe_set_rx_flow_ctl(adapter, pause->rx_pause))
2194*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			ret = -EIO;
2195*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2196*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (unm_niu_gbe_set_tx_flow_ctl(adapter, pause->tx_pause))
2197*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			ret = -EIO;
2198*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2199*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else if (adapter->ahw.board_type == UNM_NIC_XGBE) {
2200*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (unm_niu_xg_set_tx_flow_ctl(adapter, pause->tx_pause))
2201*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			ret =  -EIO;
2202*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else
2203*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		ret = -EIO;
2204*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2205*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (ret);
2206*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2207*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2208*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
2209*9a5557fdSlucy wang - Sun Microsystems - Beijing China  *
2210*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * GLD/MAC interfaces
2211*9a5557fdSlucy wang - Sun Microsystems - Beijing China  *
2212*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
2213*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2214*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
2215*9a5557fdSlucy wang - Sun Microsystems - Beijing China ntxn_m_start(void *arg)
2216*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2217*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_adapter	*adapter = arg;
2218*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int		ring;
2219*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2220*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_SPIN_LOCK(&adapter->lock);
2221*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->is_up == UNM_ADAPTER_UP_MAGIC) {
2222*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_SPIN_UNLOCK(&adapter->lock);
2223*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_SUCCESS);
2224*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2225*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2226*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (init_firmware(adapter) != DDI_SUCCESS) {
2227*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_SPIN_UNLOCK(&adapter->lock);
2228*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: Failed to init firmware\n",
2229*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
2230*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
2231*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2232*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2233*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_clear_stats(adapter);
2234*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2235*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (unm_nic_hw_resources(adapter) != 0) {
2236*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_SPIN_UNLOCK(&adapter->lock);
2237*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: Error setting hw resources\n",
2238*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
2239*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
2240*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2241*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2242*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->fw_major < 4) {
2243*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->crb_addr_cmd_producer =
2244*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    crb_cmd_producer[adapter->portnum];
2245*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->crb_addr_cmd_consumer =
2246*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    crb_cmd_consumer[adapter->portnum];
2247*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_nic_update_cmd_producer(adapter, 0);
2248*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_nic_update_cmd_consumer(adapter, 0);
2249*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2250*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2251*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
2252*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (unm_post_rx_buffers(adapter, ring) != DDI_SUCCESS) {
2253*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			/* TODO: clean up */
2254*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			UNM_SPIN_UNLOCK(&adapter->lock);
2255*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			return (DDI_FAILURE);
2256*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
2257*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2258*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2259*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (unm_nic_macaddr_set(adapter, adapter->mac_addr) != 0) {
2260*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_SPIN_UNLOCK(&adapter->lock);
2261*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: Could not set mac address\n",
2262*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
2263*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
2264*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2265*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2266*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (unm_nic_init_port(adapter) != 0) {
2267*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_SPIN_UNLOCK(&adapter->lock);
2268*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: Could not initialize port\n",
2269*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
2270*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
2271*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2272*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2273*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_set_link_parameters(adapter);
2274*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2275*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
2276*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * P2 and P3 should be handled similarly.
2277*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
2278*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
2279*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (unm_nic_set_promisc_mode(adapter) != 0) {
2280*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			UNM_SPIN_UNLOCK(&adapter->lock);
2281*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			cmn_err(CE_WARN, "%s%d: Could not set promisc mode\n",
2282*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    adapter->name, adapter->instance);
2283*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			return (DDI_FAILURE);
2284*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
2285*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
2286*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		nx_p3_nic_set_multi(adapter);
2287*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2288*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->stats.promiscmode = 1;
2289*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2290*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (unm_nic_set_mtu(adapter, adapter->mtu) != 0) {
2291*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		UNM_SPIN_UNLOCK(&adapter->lock);
2292*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "%s%d: Could not set mtu\n",
2293*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->name, adapter->instance);
2294*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
2295*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2296*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2297*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->watchdog_timer = timeout((void (*)(void *))&unm_watchdog,
2298*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    (void *)adapter, 0);
2299*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2300*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->is_up = UNM_ADAPTER_UP_MAGIC;
2301*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2302*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (adapter->intr_type == DDI_INTR_TYPE_MSI)
2303*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) ddi_intr_block_enable(&adapter->intr_handle, 1);
2304*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	else
2305*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		(void) ddi_intr_enable(adapter->intr_handle);
2306*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_nic_enable_int(adapter);
2307*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2308*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	UNM_SPIN_UNLOCK(&adapter->lock);
2309*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (GLD_SUCCESS);
2310*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2311*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2312*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2313*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*
2314*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * This code is kept here for reference so as to
2315*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * see if something different is required to be done
2316*9a5557fdSlucy wang - Sun Microsystems - Beijing China  * in GLDV3. This will be deleted later.
2317*9a5557fdSlucy wang - Sun Microsystems - Beijing China  */
2318*9a5557fdSlucy wang - Sun Microsystems - Beijing China /* ARGSUSED */
2319*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
2320*9a5557fdSlucy wang - Sun Microsystems - Beijing China ntxn_m_stop(void *arg)
2321*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2322*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2323*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2324*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*ARGSUSED*/
2325*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
2326*9a5557fdSlucy wang - Sun Microsystems - Beijing China ntxn_m_multicst(void *arg, boolean_t add, const uint8_t *ep)
2327*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2328*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/*
2329*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * When we correctly implement this, invoke nx_p3_nic_set_multi()
2330*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 * or nx_p2_nic_set_multi() here.
2331*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	 */
2332*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (GLD_SUCCESS);
2333*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2334*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2335*9a5557fdSlucy wang - Sun Microsystems - Beijing China /*ARGSUSED*/
2336*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
2337*9a5557fdSlucy wang - Sun Microsystems - Beijing China ntxn_m_promisc(void *arg, boolean_t on)
2338*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2339*9a5557fdSlucy wang - Sun Microsystems - Beijing China #if 0
2340*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int err = 0;
2341*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct unm_adapter_s *adapter = arg;
2342*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2343*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	err = on ? unm_nic_set_promisc_mode(adapter) :
2344*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	    unm_nic_unset_promisc_mode(adapter);
2345*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2346*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (err)
2347*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (GLD_FAILURE);
2348*9a5557fdSlucy wang - Sun Microsystems - Beijing China #endif
2349*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2350*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (GLD_SUCCESS);
2351*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2352*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2353*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
2354*9a5557fdSlucy wang - Sun Microsystems - Beijing China ntxn_m_stat(void *arg, uint_t stat, uint64_t *val)
2355*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2356*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct unm_adapter_s		*adapter = arg;
2357*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct unm_adapter_stats	*portstat = &adapter->stats;
2358*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2359*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	switch (stat) {
2360*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_STAT_IFSPEED:
2361*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (adapter->ahw.board_type == UNM_NIC_XGBE) {
2362*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			/* 10 Gigs */
2363*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			*val = 10000000000ULL;
2364*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		} else {
2365*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			/* 1 Gig */
2366*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			*val = 1000000000;
2367*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
2368*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2369*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2370*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_STAT_MULTIRCV:
2371*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		*val = 0;
2372*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2373*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2374*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_STAT_BRDCSTRCV:
2375*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_STAT_BRDCSTXMT:
2376*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		*val = 0;
2377*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2378*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2379*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_STAT_NORCVBUF:
2380*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		*val = portstat->updropped;
2381*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2382*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2383*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_STAT_NOXMTBUF:
2384*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		*val = portstat->txdropped;
2385*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2386*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2387*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_STAT_RBYTES:
2388*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		*val = portstat->rxbytes;
2389*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2390*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2391*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_STAT_OBYTES:
2392*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		*val = portstat->txbytes;
2393*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2394*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2395*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_STAT_OPACKETS:
2396*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		*val = portstat->xmitedframes;
2397*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2398*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2399*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_STAT_IPACKETS:
2400*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		*val = portstat->uphappy;
2401*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2402*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2403*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_STAT_OERRORS:
2404*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		*val = portstat->xmitcalled - portstat->xmitedframes;
2405*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2406*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2407*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case ETHER_STAT_LINK_DUPLEX:
2408*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		*val = LINK_DUPLEX_FULL;
2409*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2410*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2411*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	default:
2412*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		/*
2413*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 * Shouldn't reach here...
2414*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		 */
2415*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		*val = 0;
2416*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		DPRINTF(0, (CE_WARN, ": unrecognized parameter = %d, value "
2417*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    "returned 1\n", stat));
2418*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2419*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2420*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2421*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (0);
2422*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2423*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2424*9a5557fdSlucy wang - Sun Microsystems - Beijing China static int
2425*9a5557fdSlucy wang - Sun Microsystems - Beijing China ntxn_m_unicst(void *arg, const uint8_t *mac)
2426*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2427*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct unm_adapter_s *adapter = arg;
2428*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2429*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	DPRINTF(-1, (CE_CONT, "%s: called\n", __func__));
2430*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2431*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (unm_nic_macaddr_set(adapter, (uint8_t *)mac))
2432*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (EAGAIN);
2433*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	bcopy(mac, adapter->mac_addr, ETHERADDRL);
2434*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2435*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (0);
2436*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2437*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2438*9a5557fdSlucy wang - Sun Microsystems - Beijing China static mblk_t *
2439*9a5557fdSlucy wang - Sun Microsystems - Beijing China ntxn_m_tx(void *arg, mblk_t *mp)
2440*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2441*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_adapter *adapter = arg;
2442*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	mblk_t *next;
2443*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2444*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	while (mp != NULL) {
2445*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		next = mp->b_next;
2446*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		mp->b_next = NULL;
2447*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2448*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		if (unm_nic_xmit_frame(adapter, mp) != B_TRUE) {
2449*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			mp->b_next = next;
2450*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
2451*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
2452*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		mp = next;
2453*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		adapter->stats.xmitedframes++;
2454*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2455*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2456*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (mp);
2457*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2458*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2459*9a5557fdSlucy wang - Sun Microsystems - Beijing China static void
2460*9a5557fdSlucy wang - Sun Microsystems - Beijing China ntxn_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
2461*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2462*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int		cmd;
2463*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct iocblk   *iocp = (struct iocblk *)(uintptr_t)mp->b_rptr;
2464*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	struct unm_adapter_s *adapter = (struct unm_adapter_s *)arg;
2465*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	enum ioc_reply status = IOC_DONE;
2466*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2467*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	iocp->ioc_error = 0;
2468*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	cmd = iocp->ioc_cmd;
2469*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2470*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (cmd == ND_GET || cmd == ND_SET) {
2471*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		status = unm_nd_ioctl(adapter, wq, mp, iocp);
2472*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		switch (status) {
2473*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		default:
2474*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case IOC_INVAL:
2475*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			miocnak(wq, mp, 0, iocp->ioc_error == 0 ?
2476*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    EINVAL : iocp->ioc_error);
2477*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
2478*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2479*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case IOC_DONE:
2480*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
2481*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2482*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case IOC_RESTART_ACK:
2483*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case IOC_ACK:
2484*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			miocack(wq, mp, 0, 0);
2485*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
2486*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2487*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case IOC_RESTART_REPLY:
2488*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		case IOC_REPLY:
2489*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			mp->b_datap->db_type = iocp->ioc_error == 0 ?
2490*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    M_IOCACK : M_IOCNAK;
2491*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			qreply(wq, mp);
2492*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			break;
2493*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
2494*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else if (cmd <= UNM_NIC_NAME && cmd >= UNM_CMD_START) {
2495*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		unm_nic_ioctl(adapter, cmd, wq, mp);
2496*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return;
2497*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	} else {
2498*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		miocnak(wq, mp, 0, EINVAL);
2499*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return;
2500*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2501*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2502*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2503*9a5557fdSlucy wang - Sun Microsystems - Beijing China /* ARGSUSED */
2504*9a5557fdSlucy wang - Sun Microsystems - Beijing China static boolean_t
2505*9a5557fdSlucy wang - Sun Microsystems - Beijing China ntxn_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
2506*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2507*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	switch (cap) {
2508*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_CAPAB_HCKSUM:
2509*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		{
2510*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			uint32_t *txflags = cap_data;
2511*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2512*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			*txflags = (HCKSUM_ENABLE |
2513*9a5557fdSlucy wang - Sun Microsystems - Beijing China 			    HCKSUM_INET_FULL_V4 | HCKSUM_IPHDRCKSUM);
2514*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		}
2515*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		break;
2516*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2517*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_CAPAB_POLL:
2518*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	case MAC_CAPAB_MULTIADDRESS:
2519*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	default:
2520*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (B_FALSE);
2521*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2522*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2523*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (B_TRUE);
2524*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2525*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2526*9a5557fdSlucy wang - Sun Microsystems - Beijing China #define	NETXEN_M_CALLBACK_FLAGS	(MC_IOCTL | MC_GETCAPAB)
2527*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2528*9a5557fdSlucy wang - Sun Microsystems - Beijing China static mac_callbacks_t ntxn_m_callbacks = {
2529*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	NETXEN_M_CALLBACK_FLAGS,
2530*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ntxn_m_stat,
2531*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ntxn_m_start,
2532*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ntxn_m_stop,
2533*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ntxn_m_promisc,
2534*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ntxn_m_multicst,
2535*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ntxn_m_unicst,
2536*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ntxn_m_tx,
2537*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	NULL,			/* mc_resources */
2538*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ntxn_m_ioctl,
2539*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ntxn_m_getcapab,
2540*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	NULL,			/* mc_open */
2541*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	NULL,			/* mc_close */
2542*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	NULL,			/* mc_setprop */
2543*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	NULL			/* mc_getprop */
2544*9a5557fdSlucy wang - Sun Microsystems - Beijing China };
2545*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2546*9a5557fdSlucy wang - Sun Microsystems - Beijing China int
2547*9a5557fdSlucy wang - Sun Microsystems - Beijing China unm_register_mac(unm_adapter *adapter)
2548*9a5557fdSlucy wang - Sun Microsystems - Beijing China {
2549*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	int ret;
2550*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	mac_register_t *macp;
2551*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_pauseparam_t pause;
2552*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2553*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	dev_info_t *dip = adapter->dip;
2554*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2555*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
2556*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "Memory not available\n");
2557*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
2558*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2559*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2560*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
2561*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	macp->m_driver = adapter;
2562*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	macp->m_dip = dip;
2563*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	macp->m_instance = adapter->instance;
2564*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	macp->m_src_addr = adapter->mac_addr;
2565*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	macp->m_callbacks = &ntxn_m_callbacks;
2566*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	macp->m_min_sdu = 0;
2567*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	macp->m_max_sdu = adapter->mtu;
2568*9a5557fdSlucy wang - Sun Microsystems - Beijing China #ifdef SOLARIS11
2569*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	macp->m_margin = VLAN_TAGSZ;
2570*9a5557fdSlucy wang - Sun Microsystems - Beijing China #endif /* SOLARIS11 */
2571*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2572*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	ret = mac_register(macp, &adapter->mach);
2573*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	mac_free(macp);
2574*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (ret != 0) {
2575*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "mac_register failed for port %d\n",
2576*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    adapter->portnum);
2577*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
2578*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2579*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2580*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	unm_init_kstats(adapter, adapter->instance);
2581*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2582*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	/* Register NDD-tweakable parameters */
2583*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (unm_nd_init(adapter)) {
2584*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "unm_nd_init() failed");
2585*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		return (DDI_FAILURE);
2586*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2587*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2588*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	pause.rx_pause = adapter->nd_params[PARAM_ADV_PAUSE_CAP].ndp_val;
2589*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	pause.tx_pause = adapter->nd_params[PARAM_ADV_ASYM_PAUSE_CAP].ndp_val;
2590*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2591*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	if (unm_nic_set_pauseparam(adapter, &pause)) {
2592*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		cmn_err(CE_WARN, "\nBad Pause settings RX %d, Tx %d",
2593*9a5557fdSlucy wang - Sun Microsystems - Beijing China 		    pause.rx_pause, pause.tx_pause);
2594*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	}
2595*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->nd_params[PARAM_PAUSE_CAP].ndp_val = pause.rx_pause;
2596*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	adapter->nd_params[PARAM_ASYM_PAUSE_CAP].ndp_val = pause.tx_pause;
2597*9a5557fdSlucy wang - Sun Microsystems - Beijing China 
2598*9a5557fdSlucy wang - Sun Microsystems - Beijing China 	return (DDI_SUCCESS);
2599*9a5557fdSlucy wang - Sun Microsystems - Beijing China }
2600