xref: /titanic_41/usr/src/uts/common/io/ntxn/unm_gem.c (revision c10c16dec587a0662068f6e2991c29ed3a9db943)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 NetXen, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*
26  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
27  * Use is subject to license terms.
28  */
29 #include <sys/types.h>
30 #include <sys/conf.h>
31 #include <sys/debug.h>
32 #include <sys/stropts.h>
33 #include <sys/stream.h>
34 #include <sys/strlog.h>
35 #include <sys/kmem.h>
36 #include <sys/stat.h>
37 #include <sys/kstat.h>
38 #include <sys/vtrace.h>
39 #include <sys/dlpi.h>
40 #include <sys/strsun.h>
41 #include <sys/ethernet.h>
42 #include <sys/modctl.h>
43 #include <sys/errno.h>
44 #include <sys/dditypes.h>
45 #include <sys/ddi.h>
46 #include <sys/sunddi.h>
47 #include <sys/sysmacros.h>
48 #include <sys/pci.h>
49 #include <sys/ddi_intr.h>
50 
51 #include "unm_nic.h"
52 #include "unm_nic_hw.h"
53 #include "unm_brdcfg.h"
54 #include "nic_cmn.h"
55 #include "nic_phan_reg.h"
56 #include "unm_nic_ioctl.h"
57 #include "nx_hw_pci_regs.h"
58 
59 char ident[] = "Netxen nic driver v" UNM_NIC_VERSIONID;
60 char unm_nic_driver_name[] = "ntxn";
61 int verbmsg = 0;
62 
63 static char txbcopythreshold_propname[] = "tx_bcopy_threshold";
64 static char rxbcopythreshold_propname[] = "rx_bcopy_threshold";
65 static char rxringsize_propname[] = "rx_ring_size";
66 static char jumborxringsize_propname[] = "jumbo_rx_ring_size";
67 static char txringsize_propname[] = "tx_ring_size";
68 static char defaultmtu_propname[] = "default_mtu";
69 static char dmesg_propname[] = "verbose_driver";
70 
71 #define	STRUCT_COPY(a, b)	bcopy(&(b), &(a), sizeof (a))
72 
73 extern int unm_register_mac(unm_adapter *adapter);
74 extern void unm_fini_kstats(unm_adapter* adapter);
75 extern void unm_nic_remove(unm_adapter *adapter);
76 extern int unm_nic_suspend(unm_adapter *);
77 extern uint_t unm_intr(caddr_t, caddr_t);
78 
79 /* Data access requirements. */
80 static struct ddi_device_acc_attr unm_dev_attr = {
81 	DDI_DEVICE_ATTR_V0,
82 	DDI_STRUCTURE_LE_ACC,
83 	DDI_STRICTORDER_ACC
84 };
85 
86 static struct ddi_device_acc_attr unm_buf_attr = {
87 	DDI_DEVICE_ATTR_V0,
88 	DDI_NEVERSWAP_ACC,
89 	DDI_STRICTORDER_ACC
90 };
91 
92 static ddi_dma_attr_t unm_dma_attr_desc = {
93 	DMA_ATTR_V0,		/* dma_attr_version */
94 	0,			/* dma_attr_addr_lo */
95 	0xffffffffull,		/* dma_attr_addr_hi */
96 	0x000fffffull,		/* dma_attr_count_max */
97 	4096,			/* dma_attr_align */
98 	0x000fffffull,		/* dma_attr_burstsizes */
99 	4,			/* dma_attr_minxfer */
100 	0x003fffffull,		/* dma_attr_maxxfer */
101 	0xffffffffull,		/* dma_attr_seg */
102 	1,			/* dma_attr_sgllen */
103 	1,			/* dma_attr_granular */
104 	0			/* dma_attr_flags */
105 };
106 
107 static ddi_dma_attr_t unm_dma_attr_rxbuf = {
108 	DMA_ATTR_V0,		/* dma_attr_version */
109 	0,			/* dma_attr_addr_lo */
110 	0x7ffffffffULL,		/* dma_attr_addr_hi */
111 	0xffffull,		/* dma_attr_count_max */
112 	4096,			/* dma_attr_align */
113 	0xfff8ull,		/* dma_attr_burstsizes */
114 	1,			/* dma_attr_minxfer */
115 	0xffffffffull,		/* dma_attr_maxxfer */
116 	0xffffull,		/* dma_attr_seg */
117 	1,			/* dma_attr_sgllen */
118 	1,			/* dma_attr_granular */
119 	0			/* dma_attr_flags */
120 };
121 
122 static ddi_dma_attr_t unm_dma_attr_cmddesc = {
123 	DMA_ATTR_V0,		/* dma_attr_version */
124 	0,			/* dma_attr_addr_lo */
125 	0x7ffffffffULL,		/* dma_attr_addr_hi */
126 	0xffffull,		/* dma_attr_count_max */
127 	1,			/* dma_attr_align */
128 	0xfff8ull,		/* dma_attr_burstsizes */
129 	1,			/* dma_attr_minxfer */
130 	0xffff0ull,		/* dma_attr_maxxfer */
131 	0xffffull,		/* dma_attr_seg */
132 	16,			/* dma_attr_sgllen */
133 	1,			/* dma_attr_granular */
134 	0			/* dma_attr_flags */
135 };
136 
137 static struct nx_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
138 
139 static int
140 check_hw_init(struct unm_adapter_s *adapter)
141 {
142 	u32	val;
143 	int	ret = 0;
144 
145 	adapter->unm_nic_hw_read_wx(adapter, UNM_CAM_RAM(0x1fc), &val, 4);
146 	if (val == 0x55555555) {
147 		/* This is the first boot after power up */
148 		adapter->unm_nic_hw_read_wx(adapter, UNM_ROMUSB_GLB_SW_RESET,
149 		    &val, 4);
150 		if (val != 0x80000f)
151 			ret = -1;
152 
153 		if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
154 			/* Start P2 boot loader */
155 			adapter->unm_nic_pci_write_normalize(adapter,
156 			    UNM_CAM_RAM(0x1fc), UNM_BDINFO_MAGIC);
157 			adapter->unm_nic_pci_write_normalize(adapter,
158 			    UNM_ROMUSB_GLB_PEGTUNE_DONE, 1);
159 		}
160 	}
161 	return (ret);
162 }
163 
164 
165 static int
166 unm_get_flash_block(unm_adapter *adapter, int base, int size, uint32_t *buf)
167 {
168 	int i, addr;
169 	uint32_t *ptr32;
170 
171 	addr  = base;
172 	ptr32 = buf;
173 	for (i = 0; i < size / sizeof (uint32_t); i++) {
174 		if (rom_fast_read(adapter, addr, (int *)ptr32) == -1)
175 			return (-1);
176 		ptr32++;
177 		addr += sizeof (uint32_t);
178 	}
179 	if ((char *)buf + size > (char *)ptr32) {
180 		int local;
181 
182 		if (rom_fast_read(adapter, addr, &local) == -1)
183 			return (-1);
184 		(void) memcpy(ptr32, &local,
185 		    (uintptr_t)((char *)buf + size) - (uintptr_t)(char *)ptr32);
186 	}
187 
188 	return (0);
189 }
190 
191 
192 static int
193 get_flash_mac_addr(struct unm_adapter_s *adapter, u64 mac[])
194 {
195 	uint32_t *pmac = (uint32_t *)&mac[0];
196 
197 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
198 		uint32_t temp, crbaddr;
199 		uint16_t *pmac16 = (uint16_t *)pmac;
200 
201 		// FOR P3, read from CAM RAM
202 
203 		int pci_func = adapter->ahw.pci_func;
204 		pmac16 += (4 * pci_func);
205 		crbaddr = CRB_MAC_BLOCK_START + (4 * ((pci_func/2) * 3)) +
206 		    (4 * (pci_func & 1));
207 
208 		adapter->unm_nic_hw_read_wx(adapter, crbaddr, &temp, 4);
209 		if (pci_func & 1) {
210 			*pmac16++ = (temp >> 16);
211 			adapter->unm_nic_hw_read_wx(adapter, crbaddr+4,
212 			    &temp, 4);
213 			*pmac16++ = (temp & 0xffff);
214 			*pmac16++ = (temp >> 16);
215 			*pmac16 = 0;
216 		} else {
217 			*pmac16++ = (temp & 0xffff);
218 			*pmac16++ = (temp >> 16);
219 			adapter->unm_nic_hw_read_wx(adapter, crbaddr+4,
220 			    &temp, 4);
221 			*pmac16++ = (temp & 0xffff);
222 			*pmac16 = 0;
223 		}
224 		return (0);
225 	}
226 
227 
228 	if (unm_get_flash_block(adapter, USER_START +
229 	    offsetof(unm_user_info_t, mac_addr), FLASH_NUM_PORTS * sizeof (U64),
230 	    pmac) == -1)
231 		return (-1);
232 
233 	if (*mac == ~0ULL) {
234 		if (unm_get_flash_block(adapter, USER_START_OLD +
235 		    offsetof(unm_old_user_info_t, mac_addr),
236 		    FLASH_NUM_PORTS * sizeof (U64), pmac) == -1)
237 			return (-1);
238 
239 		if (*mac == ~0ULL)
240 			return (-1);
241 	}
242 
243 	return (0);
244 }
245 
246 static int
247 unm_initialize_dummy_dma(unm_adapter *adapter)
248 {
249 	uint32_t		hi, lo, temp;
250 	ddi_dma_cookie_t	cookie;
251 
252 	if (unm_pci_alloc_consistent(adapter, UNM_HOST_DUMMY_DMA_SIZE,
253 	    (caddr_t *)&adapter->dummy_dma.addr, &cookie,
254 	    &adapter->dummy_dma.dma_handle,
255 	    &adapter->dummy_dma.acc_handle) != DDI_SUCCESS) {
256 		cmn_err(CE_WARN, "%s%d: Unable to alloc dummy dma buf\n",
257 		    adapter->name, adapter->instance);
258 		return (DDI_ENOMEM);
259 	}
260 
261 	adapter->dummy_dma.phys_addr = cookie.dmac_laddress;
262 
263 	hi = (adapter->dummy_dma.phys_addr >> 32) & 0xffffffff;
264 	lo = adapter->dummy_dma.phys_addr & 0xffffffff;
265 
266 	UNM_READ_LOCK(&adapter->adapter_lock);
267 	adapter->unm_nic_hw_write_wx(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI,
268 	    &hi, 4);
269 	adapter->unm_nic_hw_write_wx(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO,
270 	    &lo, 4);
271 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
272 		temp = DUMMY_BUF_INIT;
273 		adapter->unm_nic_hw_write_wx(adapter, CRB_HOST_DUMMY_BUF,
274 		    &temp, 4);
275 	}
276 	UNM_READ_UNLOCK(&adapter->adapter_lock);
277 
278 	return (DDI_SUCCESS);
279 }
280 
281 void
282 unm_free_dummy_dma(unm_adapter *adapter)
283 {
284 	if (adapter->dummy_dma.addr) {
285 		unm_pci_free_consistent(&adapter->dummy_dma.dma_handle,
286 		    &adapter->dummy_dma.acc_handle);
287 		adapter->dummy_dma.addr = NULL;
288 	}
289 }
290 
291 static int
292 unm_pci_cfg_init(unm_adapter *adapter)
293 {
294 	hardware_context *hwcontext;
295 	ddi_acc_handle_t pci_cfg_hdl;
296 	int *reg_options;
297 	dev_info_t *dip;
298 	uint_t noptions;
299 	int ret;
300 	uint16_t vendor_id, pci_cmd_word;
301 	uint8_t	base_class, sub_class, prog_class;
302 	uint32_t pexsizes;
303 	struct nx_legacy_intr_set *legacy_intrp;
304 
305 	hwcontext = &adapter->ahw;
306 	pci_cfg_hdl = adapter->pci_cfg_handle;
307 	dip = adapter->dip;
308 
309 	vendor_id = pci_config_get16(pci_cfg_hdl, PCI_CONF_VENID);
310 
311 	if (vendor_id != 0x4040) {
312 		cmn_err(CE_WARN, "%s%d: vendor id %x not 0x4040\n",
313 		    adapter->name, adapter->instance, vendor_id);
314 		return (DDI_FAILURE);
315 	}
316 
317 	ret = ddi_prop_lookup_int_array(DDI_DEV_T_ANY,
318 	    dip, 0, "reg", &reg_options, &noptions);
319 	if (ret != DDI_PROP_SUCCESS) {
320 		cmn_err(CE_WARN, "%s%d: Could not determine reg property\n",
321 		    adapter->name, adapter->instance);
322 		return (DDI_FAILURE);
323 	}
324 
325 	hwcontext->pci_func = (reg_options[0] >> 8) & 0x7;
326 	ddi_prop_free(reg_options);
327 
328 	base_class = pci_config_get8(pci_cfg_hdl, PCI_CONF_BASCLASS);
329 	sub_class = pci_config_get8(pci_cfg_hdl, PCI_CONF_SUBCLASS);
330 	prog_class = pci_config_get8(pci_cfg_hdl, PCI_CONF_PROGCLASS);
331 
332 	/*
333 	 * Need this check so that MEZZ card mgmt interface ntxn0 could fail
334 	 * attach & return and proceed to next interfaces ntxn1 and ntxn2
335 	 */
336 	if ((base_class != 0x02) || (sub_class != 0) || (prog_class != 0)) {
337 		cmn_err(CE_WARN, "%s%d: Base/sub/prog class problem %d/%d/%d\n",
338 		    adapter->name, adapter->instance, base_class, sub_class,
339 		    prog_class);
340 		return (DDI_FAILURE);
341 	}
342 
343 	hwcontext->revision_id = pci_config_get8(pci_cfg_hdl, PCI_CONF_REVID);
344 
345 	/*
346 	 * Refuse to work with dubious P3 cards.
347 	 */
348 	if ((hwcontext->revision_id >= NX_P3_A0) &&
349 	    (hwcontext->revision_id < NX_P3_B1)) {
350 		cmn_err(CE_WARN, "%s%d: NetXen chip revs between 0x%x-0x%x "
351 		    "is unsupported\n", adapter->name, adapter->instance,
352 		    NX_P3_A0, NX_P3_B0);
353 		return (DDI_FAILURE);
354 	}
355 
356 	/*
357 	 * Save error reporting settings; clear [19:16] error status bits.
358 	 * Set max read request [14:12] to 0 for 128 bytes. Set max payload
359 	 * size[7:5] to 0 for for 128 bytes.
360 	 */
361 	if (NX_IS_REVISION_P2(hwcontext->revision_id)) {
362 		pexsizes = pci_config_get32(pci_cfg_hdl, 0xd8);
363 		pexsizes &= 7;
364 		pexsizes |= 0xF0000;
365 		pci_config_put32(pci_cfg_hdl, 0xd8, pexsizes);
366 	}
367 
368 	pci_cmd_word = pci_config_get16(pci_cfg_hdl, PCI_CONF_COMM);
369 	pci_cmd_word |= (PCI_COMM_INTX_DISABLE | PCI_COMM_SERR_ENABLE);
370 	pci_config_put16(pci_cfg_hdl, PCI_CONF_COMM, pci_cmd_word);
371 
372 	if (hwcontext->revision_id >= NX_P3_B0)
373 		legacy_intrp = &legacy_intr[hwcontext->pci_func];
374 	else
375 		legacy_intrp = &legacy_intr[0];
376 
377 	adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit;
378 	adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg;
379 	adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg;
380 	adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg;
381 
382 	return (DDI_SUCCESS);
383 }
384 
385 static void
386 unm_free_tx_dmahdl(unm_adapter *adapter)
387 {
388 	int i;
389 	unm_dmah_node_t	 *nodep;
390 
391 	mutex_enter(&adapter->tx_lock);
392 	nodep = &adapter->tx_dma_hdls[0];
393 
394 	for (i = 0; i < adapter->MaxTxDescCount + EXTRA_HANDLES; i++) {
395 		if (nodep->dmahdl != NULL) {
396 			ddi_dma_free_handle(&nodep->dmahdl);
397 			nodep->dmahdl = NULL;
398 		}
399 		nodep->next = NULL;
400 		nodep++;
401 	}
402 
403 	adapter->dmahdl_pool = NULL;
404 	adapter->freehdls = 0;
405 	mutex_exit(&adapter->tx_lock);
406 }
407 
408 static int
409 unm_alloc_tx_dmahdl(unm_adapter *adapter)
410 {
411 	int		i;
412 	unm_dmah_node_t	*nodep = &adapter->tx_dma_hdls[0];
413 
414 	mutex_enter(&adapter->tx_lock);
415 	for (i = 0; i < adapter->MaxTxDescCount + EXTRA_HANDLES; i++) {
416 		if (ddi_dma_alloc_handle(adapter->dip, &unm_dma_attr_cmddesc,
417 		    DDI_DMA_DONTWAIT, NULL, &nodep->dmahdl) != DDI_SUCCESS) {
418 			mutex_exit(&adapter->tx_lock);
419 			goto alloc_hdl_fail;
420 		}
421 
422 		if (i > 0)
423 			nodep->next = nodep - 1;
424 		nodep++;
425 	}
426 
427 	adapter->dmahdl_pool = nodep - 1;
428 	adapter->freehdls = i;
429 	mutex_exit(&adapter->tx_lock);
430 
431 	return (DDI_SUCCESS);
432 
433 alloc_hdl_fail:
434 	unm_free_tx_dmahdl(adapter);
435 	cmn_err(CE_WARN, "%s%d: Failed transmit ring dma handle allocation\n",
436 	    adapter->name, adapter->instance);
437 	return (DDI_FAILURE);
438 }
439 
440 static void
441 unm_free_dma_mem(dma_area_t *dma_p)
442 {
443 	if (dma_p->dma_hdl != NULL) {
444 		if (dma_p->ncookies) {
445 			(void) ddi_dma_unbind_handle(dma_p->dma_hdl);
446 			dma_p->ncookies = 0;
447 		}
448 	}
449 	if (dma_p->acc_hdl != NULL) {
450 		ddi_dma_mem_free(&dma_p->acc_hdl);
451 		dma_p->acc_hdl = NULL;
452 	}
453 	if (dma_p->dma_hdl != NULL) {
454 		ddi_dma_free_handle(&dma_p->dma_hdl);
455 		dma_p->dma_hdl = NULL;
456 	}
457 }
458 
459 static int
460 unm_alloc_dma_mem(unm_adapter *adapter, int size, uint_t dma_flag,
461 	ddi_dma_attr_t *dma_attr_p, dma_area_t *dma_p)
462 {
463 	int ret;
464 	caddr_t vaddr;
465 	size_t actual_size;
466 	ddi_dma_cookie_t	cookie;
467 
468 	ret = ddi_dma_alloc_handle(adapter->dip,
469 	    dma_attr_p, DDI_DMA_DONTWAIT,
470 	    NULL, &dma_p->dma_hdl);
471 	if (ret != DDI_SUCCESS) {
472 		cmn_err(CE_WARN, "%s%d: Failed ddi_dma_alloc_handle\n",
473 		    adapter->name, adapter->instance);
474 		goto dma_mem_fail;
475 	}
476 
477 	ret = ddi_dma_mem_alloc(dma_p->dma_hdl,
478 	    size, &adapter->gc_attr_desc,
479 	    dma_flag & (DDI_DMA_STREAMING | DDI_DMA_CONSISTENT),
480 	    DDI_DMA_DONTWAIT, NULL, &vaddr, &actual_size,
481 	    &dma_p->acc_hdl);
482 	if (ret != DDI_SUCCESS) {
483 		cmn_err(CE_WARN, "%s%d: ddi_dma_mem_alloc() failed\n",
484 		    adapter->name, adapter->instance);
485 		goto dma_mem_fail;
486 	}
487 
488 	if (actual_size < size) {
489 		cmn_err(CE_WARN, "%s%d: ddi_dma_mem_alloc() allocated small\n",
490 		    adapter->name, adapter->instance);
491 		goto dma_mem_fail;
492 	}
493 
494 	ret = ddi_dma_addr_bind_handle(dma_p->dma_hdl,
495 	    NULL, vaddr, size, dma_flag, DDI_DMA_DONTWAIT,
496 	    NULL, &cookie, &dma_p->ncookies);
497 	if (ret != DDI_DMA_MAPPED || dma_p->ncookies != 1) {
498 		cmn_err(CE_WARN, "%s%d: ddi_dma_addr_bind_handle() failed, "
499 		    "%d, %d\n", adapter->name, adapter->instance, ret,
500 		    dma_p->ncookies);
501 		goto dma_mem_fail;
502 	}
503 
504 	dma_p->dma_addr = cookie.dmac_laddress;
505 	dma_p->vaddr = vaddr;
506 	(void) memset(vaddr, 0, size);
507 
508 	return (DDI_SUCCESS);
509 
510 dma_mem_fail:
511 	unm_free_dma_mem(dma_p);
512 	return (DDI_FAILURE);
513 }
514 
515 static void
516 unm_free_tx_buffers(unm_adapter *adapter)
517 {
518 	int i;
519 	dma_area_t *dma_p;
520 	struct unm_cmd_buffer *cmd_buf;
521 	unm_dmah_node_t	 *nodep;
522 
523 	cmd_buf = &adapter->cmd_buf_arr[0];
524 
525 	for (i = 0; i < adapter->MaxTxDescCount; i++) {
526 		dma_p = &cmd_buf->dma_area;
527 		unm_free_dma_mem(dma_p);
528 		nodep = cmd_buf->head;
529 		while (nodep != NULL) {
530 			(void) ddi_dma_unbind_handle(nodep->dmahdl);
531 			nodep = nodep->next;
532 		}
533 		if (cmd_buf->msg != NULL)
534 			freemsg(cmd_buf->msg);
535 		cmd_buf++;
536 	}
537 	adapter->freecmds = 0;
538 }
539 
540 static int
541 unm_alloc_tx_buffers(unm_adapter *adapter)
542 {
543 	int i, ret, size, allocated = 0;
544 	dma_area_t *dma_p;
545 	struct unm_cmd_buffer *cmd_buf;
546 
547 	cmd_buf = &adapter->cmd_buf_arr[0];
548 	size = adapter->maxmtu;
549 
550 	for (i = 0; i < adapter->MaxTxDescCount; i++) {
551 		dma_p = &cmd_buf->dma_area;
552 		ret = unm_alloc_dma_mem(adapter, size,
553 		    DDI_DMA_WRITE | DDI_DMA_STREAMING,
554 		    &unm_dma_attr_rxbuf, dma_p);
555 		if (ret != DDI_SUCCESS)
556 			goto alloc_tx_buffer_fail;
557 
558 		allocated++;
559 		cmd_buf++;
560 	}
561 	adapter->freecmds = adapter->MaxTxDescCount;
562 	return (DDI_SUCCESS);
563 
564 alloc_tx_buffer_fail:
565 
566 	cmd_buf = &adapter->cmd_buf_arr[0];
567 	for (i = 0; i < allocated; i++) {
568 		dma_p = &cmd_buf->dma_area;
569 		unm_free_dma_mem(dma_p);
570 		cmd_buf++;
571 	}
572 	cmn_err(CE_WARN, "%s%d: Failed transmit ring memory allocation\n",
573 	    adapter->name, adapter->instance);
574 	return (DDI_FAILURE);
575 }
576 
577 /*
578  * Called by freemsg() to "free" the resource.
579  */
580 static void
581 unm_rx_buffer_recycle(char *arg)
582 {
583 	unm_rx_buffer_t *rx_buffer = (unm_rx_buffer_t *)(uintptr_t)arg;
584 	unm_adapter *adapter = rx_buffer->adapter;
585 	unm_rcv_desc_ctx_t *rcv_desc = rx_buffer->rcv_desc;
586 
587 	rx_buffer->mp = desballoc(rx_buffer->dma_info.vaddr,
588 	    rcv_desc->dma_size, 0, &rx_buffer->rx_recycle);
589 
590 	if (rx_buffer->mp == NULL)
591 		adapter->stats.desballocfailed++;
592 
593 	mutex_enter(rcv_desc->recycle_lock);
594 	rx_buffer->next = rcv_desc->recycle_list;
595 	rcv_desc->recycle_list = rx_buffer;
596 	rcv_desc->rx_buf_recycle++;
597 	mutex_exit(rcv_desc->recycle_lock);
598 }
599 
600 static void
601 unm_destroy_rx_ring(unm_rcv_desc_ctx_t *rcv_desc)
602 {
603 	uint32_t i, total_buf;
604 	unm_rx_buffer_t *buf_pool;
605 
606 	total_buf = rcv_desc->rx_buf_total;
607 	buf_pool = rcv_desc->rx_buf_pool;
608 	for (i = 0; i < total_buf; i++) {
609 		if (buf_pool->mp != NULL)
610 			freemsg(buf_pool->mp);
611 		unm_free_dma_mem(&buf_pool->dma_info);
612 		buf_pool++;
613 	}
614 
615 	kmem_free(rcv_desc->rx_buf_pool, sizeof (unm_rx_buffer_t) * total_buf);
616 	rcv_desc->rx_buf_pool = NULL;
617 	rcv_desc->pool_list = NULL;
618 	rcv_desc->recycle_list = NULL;
619 	rcv_desc->rx_buf_free = 0;
620 
621 	mutex_destroy(rcv_desc->pool_lock);
622 	mutex_destroy(rcv_desc->recycle_lock);
623 }
624 
625 static int
626 unm_create_rx_ring(unm_adapter *adapter, unm_rcv_desc_ctx_t *rcv_desc)
627 {
628 	int		i, ret, allocate = 0, sreoff;
629 	uint32_t	total_buf;
630 	dma_area_t	*dma_info;
631 	unm_rx_buffer_t	*rx_buffer;
632 
633 	sreoff = adapter->ahw.cut_through ? 0 : IP_ALIGNMENT_BYTES;
634 
635 	/* temporarily set the total rx buffers two times of MaxRxDescCount */
636 	total_buf = rcv_desc->rx_buf_total = rcv_desc->MaxRxDescCount * 2;
637 
638 	rcv_desc->rx_buf_pool = kmem_zalloc(sizeof (unm_rx_buffer_t) *
639 	    total_buf, KM_SLEEP);
640 	rx_buffer = rcv_desc->rx_buf_pool;
641 	for (i = 0; i < total_buf; i++) {
642 		dma_info = &rx_buffer->dma_info;
643 		ret = unm_alloc_dma_mem(adapter, rcv_desc->buf_size,
644 		    DDI_DMA_READ | DDI_DMA_STREAMING,
645 		    &unm_dma_attr_rxbuf, dma_info);
646 		if (ret != DDI_SUCCESS)
647 			goto alloc_mem_failed;
648 		else {
649 			allocate++;
650 			dma_info->vaddr = (void *) ((char *)dma_info->vaddr +
651 			    sreoff);
652 			dma_info->dma_addr += sreoff;
653 			rx_buffer->rx_recycle.free_func =
654 			    unm_rx_buffer_recycle;
655 			rx_buffer->rx_recycle.free_arg = (caddr_t)rx_buffer;
656 			rx_buffer->next = NULL;
657 			rx_buffer->mp = desballoc(dma_info->vaddr,
658 			    rcv_desc->dma_size, 0, &rx_buffer->rx_recycle);
659 			if (rx_buffer->mp == NULL)
660 				adapter->stats.desballocfailed++;
661 			rx_buffer->rcv_desc = rcv_desc;
662 			rx_buffer->adapter = adapter;
663 			rx_buffer++;
664 		}
665 	}
666 
667 	for (i = 0; i < (total_buf - 1); i++) {
668 		rcv_desc->rx_buf_pool[i].next = &rcv_desc->rx_buf_pool[i + 1];
669 	}
670 
671 	rcv_desc->pool_list = rcv_desc->rx_buf_pool;
672 	rcv_desc->recycle_list = NULL;
673 	rcv_desc->rx_buf_free = total_buf;
674 
675 	mutex_init(rcv_desc->pool_lock, NULL,
676 	    MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri)));
677 	mutex_init(rcv_desc->recycle_lock, NULL,
678 	    MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri)));
679 
680 	return (DDI_SUCCESS);
681 
682 alloc_mem_failed:
683 	rx_buffer = rcv_desc->rx_buf_pool;
684 	for (i = 0; i < allocate; i++, rx_buffer++) {
685 		dma_info = &rx_buffer->dma_info;
686 		if (rx_buffer->mp != NULL)
687 			freemsg(rx_buffer->mp);
688 		unm_free_dma_mem(dma_info);
689 	}
690 
691 	kmem_free(rcv_desc->rx_buf_pool, sizeof (unm_rx_buffer_t) * total_buf);
692 	rcv_desc->rx_buf_pool = NULL;
693 
694 	cmn_err(CE_WARN, "%s%d: Failed receive ring resource allocation\n",
695 	    adapter->name, adapter->instance);
696 	return (DDI_FAILURE);
697 }
698 
699 static void
700 unm_check_options(unm_adapter *adapter)
701 {
702 	int			i, ring, tx_desc, rx_desc, rx_jdesc, maxrx;
703 	unm_recv_context_t	*recv_ctx;
704 	unm_rcv_desc_ctx_t	*rcv_desc;
705 	uint8_t			revid = adapter->ahw.revision_id;
706 	dev_info_t		*dip = adapter->dip;
707 
708 	/*
709 	 * Reduce number of regular rcv desc to half on x86.
710 	 */
711 	maxrx = MAX_RCV_DESCRIPTORS;
712 #if !defined(_LP64)
713 	maxrx /= 2;
714 #endif /* !_LP64 */
715 
716 	verbmsg = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
717 	    dmesg_propname, 0);
718 
719 	adapter->tx_bcopy_threshold = ddi_prop_get_int(DDI_DEV_T_ANY,
720 	    dip, DDI_PROP_DONTPASS, txbcopythreshold_propname,
721 	    UNM_TX_BCOPY_THRESHOLD);
722 	adapter->rx_bcopy_threshold = ddi_prop_get_int(DDI_DEV_T_ANY,
723 	    dip, DDI_PROP_DONTPASS, rxbcopythreshold_propname,
724 	    UNM_RX_BCOPY_THRESHOLD);
725 
726 	tx_desc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
727 	    txringsize_propname, MAX_CMD_DESCRIPTORS_HOST);
728 	if (tx_desc >= 256 && tx_desc <= MAX_CMD_DESCRIPTORS &&
729 	    !(tx_desc & (tx_desc - 1))) {
730 		adapter->MaxTxDescCount = tx_desc;
731 	} else {
732 		cmn_err(CE_WARN, "%s%d: TxRingSize defaulting to %d, since "
733 		    ".conf value is not 2 power aligned in range 256 - %d\n",
734 		    adapter->name, adapter->instance, MAX_CMD_DESCRIPTORS_HOST,
735 		    MAX_CMD_DESCRIPTORS);
736 		adapter->MaxTxDescCount = MAX_CMD_DESCRIPTORS_HOST;
737 	}
738 
739 	rx_desc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
740 	    rxringsize_propname, maxrx);
741 	if (rx_desc >= NX_MIN_DRIVER_RDS_SIZE &&
742 	    rx_desc <= NX_MAX_SUPPORTED_RDS_SIZE &&
743 	    !(rx_desc & (rx_desc - 1))) {
744 		adapter->MaxRxDescCount = rx_desc;
745 	} else {
746 		cmn_err(CE_WARN, "%s%d: RxRingSize defaulting to %d, since "
747 		    ".conf value is not 2 power aligned in range %d - %d\n",
748 		    adapter->name, adapter->instance, MAX_RCV_DESCRIPTORS,
749 		    NX_MIN_DRIVER_RDS_SIZE, NX_MAX_SUPPORTED_RDS_SIZE);
750 		adapter->MaxRxDescCount = MAX_RCV_DESCRIPTORS;
751 	}
752 
753 	rx_jdesc = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
754 	    jumborxringsize_propname, MAX_JUMBO_RCV_DESCRIPTORS);
755 	if (rx_jdesc >= NX_MIN_DRIVER_RDS_SIZE &&
756 	    rx_jdesc <= NX_MAX_SUPPORTED_JUMBO_RDS_SIZE &&
757 	    !(rx_jdesc & (rx_jdesc - 1))) {
758 		adapter->MaxJumboRxDescCount = rx_jdesc;
759 	} else {
760 		cmn_err(CE_WARN, "%s%d: JumboRingSize defaulting to %d, since "
761 		    ".conf value is not 2 power aligned in range %d - %d\n",
762 		    adapter->name, adapter->instance, MAX_JUMBO_RCV_DESCRIPTORS,
763 		    NX_MIN_DRIVER_RDS_SIZE, NX_MAX_SUPPORTED_JUMBO_RDS_SIZE);
764 		adapter->MaxJumboRxDescCount = MAX_JUMBO_RCV_DESCRIPTORS;
765 	}
766 
767 	/*
768 	 * Solaris does not use LRO, but older firmware needs to have a
769 	 * couple of descriptors for initialization.
770 	 */
771 	adapter->MaxLroRxDescCount = (adapter->fw_major < 4) ? 2 : 0;
772 
773 	adapter->mtu = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
774 	    DDI_PROP_DONTPASS, defaultmtu_propname, MTU_SIZE);
775 
776 	if (adapter->mtu < MTU_SIZE) {
777 		cmn_err(CE_WARN, "Raising mtu to %d\n", MTU_SIZE);
778 		adapter->mtu = MTU_SIZE;
779 	}
780 	adapter->maxmtu = NX_IS_REVISION_P2(revid) ? P2_MAX_MTU : P3_MAX_MTU;
781 	if (adapter->mtu > adapter->maxmtu) {
782 		cmn_err(CE_WARN, "Lowering mtu to %d\n", adapter->maxmtu);
783 		adapter->mtu = adapter->maxmtu;
784 	}
785 
786 	adapter->maxmtu = adapter->mtu + NX_MAX_ETHERHDR;
787 
788 	/*
789 	 * If we are not expecting to receive jumbo frames, save memory and
790 	 * do not allocate.
791 	 */
792 	if (adapter->mtu <= MTU_SIZE)
793 		adapter->MaxJumboRxDescCount = NX_MIN_DRIVER_RDS_SIZE;
794 
795 	for (i = 0; i < MAX_RCV_CTX; ++i) {
796 		recv_ctx = &adapter->recv_ctx[i];
797 
798 		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
799 			rcv_desc = &recv_ctx->rcv_desc[ring];
800 
801 			switch (RCV_DESC_TYPE(ring)) {
802 			case RCV_DESC_NORMAL:
803 				rcv_desc->MaxRxDescCount =
804 				    adapter->MaxRxDescCount;
805 				if (adapter->ahw.cut_through) {
806 					rcv_desc->dma_size =
807 					    NX_CT_DEFAULT_RX_BUF_LEN;
808 					rcv_desc->buf_size = rcv_desc->dma_size;
809 				} else {
810 					rcv_desc->dma_size =
811 					    NX_RX_NORMAL_BUF_MAX_LEN;
812 					rcv_desc->buf_size =
813 					    rcv_desc->dma_size +
814 					    IP_ALIGNMENT_BYTES;
815 				}
816 				break;
817 
818 			case RCV_DESC_JUMBO:
819 				rcv_desc->MaxRxDescCount =
820 				    adapter->MaxJumboRxDescCount;
821 				if (adapter->ahw.cut_through) {
822 					rcv_desc->dma_size =
823 					    rcv_desc->buf_size =
824 					    NX_P3_RX_JUMBO_BUF_MAX_LEN;
825 				} else {
826 					if (NX_IS_REVISION_P2(revid))
827 						rcv_desc->dma_size =
828 						    NX_P2_RX_JUMBO_BUF_MAX_LEN;
829 					else
830 						rcv_desc->dma_size =
831 						    NX_P3_RX_JUMBO_BUF_MAX_LEN;
832 					rcv_desc->buf_size =
833 					    rcv_desc->dma_size +
834 					    IP_ALIGNMENT_BYTES;
835 				}
836 				break;
837 
838 			case RCV_RING_LRO:
839 				rcv_desc->MaxRxDescCount =
840 				    adapter->MaxLroRxDescCount;
841 				rcv_desc->buf_size = MAX_RX_LRO_BUFFER_LENGTH;
842 				rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN;
843 				break;
844 			default:
845 				break;
846 			}
847 		}
848 	}
849 }
850 
851 static void
852 vector128M(unm_adapter *aptr)
853 {
854 	aptr->unm_nic_pci_change_crbwindow = &unm_nic_pci_change_crbwindow_128M;
855 	aptr->unm_crb_writelit_adapter = &unm_crb_writelit_adapter_128M;
856 	aptr->unm_nic_hw_write_wx = &unm_nic_hw_write_wx_128M;
857 	aptr->unm_nic_hw_read_wx = &unm_nic_hw_read_wx_128M;
858 	aptr->unm_nic_hw_write_ioctl = &unm_nic_hw_write_ioctl_128M;
859 	aptr->unm_nic_hw_read_ioctl = &unm_nic_hw_read_ioctl_128M;
860 	aptr->unm_nic_pci_mem_write = &unm_nic_pci_mem_write_128M;
861 	aptr->unm_nic_pci_mem_read = &unm_nic_pci_mem_read_128M;
862 	aptr->unm_nic_pci_write_immediate = &unm_nic_pci_write_immediate_128M;
863 	aptr->unm_nic_pci_read_immediate = &unm_nic_pci_read_immediate_128M;
864 	aptr->unm_nic_pci_write_normalize = &unm_nic_pci_write_normalize_128M;
865 	aptr->unm_nic_pci_read_normalize = &unm_nic_pci_read_normalize_128M;
866 	aptr->unm_nic_pci_set_window = &unm_nic_pci_set_window_128M;
867 	aptr->unm_nic_clear_statistics = &unm_nic_clear_statistics_128M;
868 	aptr->unm_nic_fill_statistics = &unm_nic_fill_statistics_128M;
869 }
870 
871 static void
872 vector2M(unm_adapter *aptr)
873 {
874 	aptr->unm_nic_pci_change_crbwindow = &unm_nic_pci_change_crbwindow_2M;
875 	aptr->unm_crb_writelit_adapter = &unm_crb_writelit_adapter_2M;
876 	aptr->unm_nic_hw_write_wx = &unm_nic_hw_write_wx_2M;
877 	aptr->unm_nic_hw_read_wx = &unm_nic_hw_read_wx_2M;
878 	aptr->unm_nic_hw_write_ioctl = &unm_nic_hw_write_wx_2M;
879 	aptr->unm_nic_hw_read_ioctl = &unm_nic_hw_read_wx_2M;
880 	aptr->unm_nic_pci_mem_write = &unm_nic_pci_mem_write_2M;
881 	aptr->unm_nic_pci_mem_read = &unm_nic_pci_mem_read_2M;
882 	aptr->unm_nic_pci_write_immediate = &unm_nic_pci_write_immediate_2M;
883 	aptr->unm_nic_pci_read_immediate = &unm_nic_pci_read_immediate_2M;
884 	aptr->unm_nic_pci_write_normalize = &unm_nic_pci_write_normalize_2M;
885 	aptr->unm_nic_pci_read_normalize = &unm_nic_pci_read_normalize_2M;
886 	aptr->unm_nic_pci_set_window = &unm_nic_pci_set_window_2M;
887 	aptr->unm_nic_clear_statistics = &unm_nic_clear_statistics_2M;
888 	aptr->unm_nic_fill_statistics = &unm_nic_fill_statistics_2M;
889 }
890 
891 static int
892 unm_pci_map_setup(unm_adapter *adapter)
893 {
894 	int ret;
895 	caddr_t reg_base, db_base;
896 	caddr_t mem_ptr0, mem_ptr1 = NULL, mem_ptr2 = NULL;
897 	unsigned long pci_len0;
898 	unsigned long first_page_group_start, first_page_group_end;
899 
900 	off_t regsize, dbsize = UNM_DB_MAPSIZE_BYTES;
901 	dev_info_t *dip = adapter->dip;
902 
903 	adapter->ahw.qdr_sn_window = adapter->ahw.ddr_mn_window = -1;
904 
905 	/* map register space */
906 
907 	ret = ddi_dev_regsize(dip, 1, &regsize);
908 	if (ret != DDI_SUCCESS) {
909 		cmn_err(CE_WARN, "%s%d: failed to read reg size for bar0\n",
910 		    adapter->name, adapter->instance);
911 		return (DDI_FAILURE);
912 	}
913 
914 	ret = ddi_regs_map_setup(dip, 1, &reg_base, 0,
915 	    regsize, &unm_dev_attr, &adapter->regs_handle);
916 	if (ret != DDI_SUCCESS) {
917 		cmn_err(CE_WARN, "%s%d: failed to map registers\n",
918 		    adapter->name, adapter->instance);
919 		return (DDI_FAILURE);
920 	}
921 
922 	mem_ptr0 = reg_base;
923 
924 	if (regsize == UNM_PCI_128MB_SIZE) {
925 		pci_len0 = FIRST_PAGE_GROUP_SIZE;
926 		mem_ptr1 = mem_ptr0 + SECOND_PAGE_GROUP_START;
927 		mem_ptr2 = mem_ptr0 + THIRD_PAGE_GROUP_START;
928 		first_page_group_start = FIRST_PAGE_GROUP_START;
929 		first_page_group_end   = FIRST_PAGE_GROUP_END;
930 		vector128M(adapter);
931 	} else if (regsize == UNM_PCI_32MB_SIZE) {
932 		pci_len0 = 0;
933 		mem_ptr1 = mem_ptr0;
934 		mem_ptr2 = mem_ptr0 +
935 		    (THIRD_PAGE_GROUP_START - SECOND_PAGE_GROUP_START);
936 		first_page_group_start = 0;
937 		first_page_group_end   = 0;
938 		vector128M(adapter);
939 	} else if (regsize == UNM_PCI_2MB_SIZE) {
940 		pci_len0 = UNM_PCI_2MB_SIZE;
941 		first_page_group_start = 0;
942 		first_page_group_end = 0;
943 		adapter->ahw.ddr_mn_window = adapter->ahw.qdr_sn_window = 0;
944 		adapter->ahw.mn_win_crb = 0x100000 + PCIX_MN_WINDOW +
945 		    (adapter->ahw.pci_func * 0x20);
946 		if (adapter->ahw.pci_func < 4)
947 			adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW +
948 			    (adapter->ahw.pci_func * 0x20);
949 		else
950 			adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW +
951 			    0xA0 + ((adapter->ahw.pci_func - 4) * 0x10);
952 		vector2M(adapter);
953 	} else {
954 		cmn_err(CE_WARN, "%s%d: invalid pci regs map size %ld\n",
955 		    adapter->name, adapter->instance, regsize);
956 		ddi_regs_map_free(&adapter->regs_handle);
957 		return (DDI_FAILURE);
958 	}
959 
960 	adapter->ahw.pci_base0  = (unsigned long)mem_ptr0;
961 	adapter->ahw.pci_len0   = pci_len0;
962 	adapter->ahw.pci_base1  = (unsigned long)mem_ptr1;
963 	adapter->ahw.pci_len1   = SECOND_PAGE_GROUP_SIZE;
964 	adapter->ahw.pci_base2  = (unsigned long)mem_ptr2;
965 	adapter->ahw.pci_len2   = THIRD_PAGE_GROUP_SIZE;
966 	adapter->ahw.crb_base   =
967 	    PCI_OFFSET_SECOND_RANGE(adapter, UNM_PCI_CRBSPACE);
968 
969 	adapter->ahw.first_page_group_start = first_page_group_start;
970 	adapter->ahw.first_page_group_end   = first_page_group_end;
971 
972 	/* map doorbell */
973 
974 	ret = ddi_regs_map_setup(dip, 2, &db_base, 0,
975 	    dbsize, &unm_dev_attr, &adapter->db_handle);
976 	if (ret != DDI_SUCCESS) {
977 		cmn_err(CE_WARN, "%s%d: failed to map doorbell\n",
978 		    adapter->name, adapter->instance);
979 		ddi_regs_map_free(&adapter->regs_handle);
980 		return (DDI_FAILURE);
981 	}
982 
983 	adapter->ahw.db_base   = (unsigned long)db_base;
984 	adapter->ahw.db_len    = dbsize;
985 
986 	return (DDI_SUCCESS);
987 }
988 
989 static int
990 unm_initialize_intr(unm_adapter *adapter)
991 {
992 
993 	int		ret;
994 	int		type, count, avail, actual;
995 
996 	ret = ddi_intr_get_supported_types(adapter->dip, &type);
997 	if (ret != DDI_SUCCESS) {
998 		cmn_err(CE_WARN, "%s%d: ddi_intr_get_supported_types() "
999 		    "failed\n", adapter->name, adapter->instance);
1000 		return (DDI_FAILURE);
1001 	}
1002 
1003 	type = DDI_INTR_TYPE_MSI;
1004 	ret = ddi_intr_get_nintrs(adapter->dip, type, &count);
1005 	if ((ret == DDI_SUCCESS) && (count > 0))
1006 		goto found_msi;
1007 
1008 	type = DDI_INTR_TYPE_FIXED;
1009 	ret = ddi_intr_get_nintrs(adapter->dip, type, &count);
1010 	if ((ret != DDI_SUCCESS) || (count == 0)) {
1011 		cmn_err(CE_WARN,
1012 		    "ddi_intr_get_nintrs() failure ret=%d\n", ret);
1013 		return (DDI_FAILURE);
1014 	}
1015 
1016 found_msi:
1017 	adapter->intr_type = type;
1018 	adapter->flags &= ~(UNM_NIC_MSI_ENABLED | UNM_NIC_MSIX_ENABLED);
1019 	if (type == DDI_INTR_TYPE_MSI)
1020 		adapter->flags |= UNM_NIC_MSI_ENABLED;
1021 
1022 	/* Get number of available interrupts */
1023 	ret = ddi_intr_get_navail(adapter->dip, type, &avail);
1024 	if ((ret != DDI_SUCCESS) || (avail == 0)) {
1025 		cmn_err(CE_WARN, "ddi_intr_get_navail() failure, ret=%d\n",
1026 		    ret);
1027 		return (DDI_FAILURE);
1028 	}
1029 
1030 	ret = ddi_intr_alloc(adapter->dip, &adapter->intr_handle,
1031 	    type, 0, 1, &actual, DDI_INTR_ALLOC_NORMAL);
1032 	if ((ret != DDI_SUCCESS) || (actual == 0)) {
1033 		cmn_err(CE_WARN, "ddi_intr_alloc() failure: %d\n", ret);
1034 		return (DDI_FAILURE);
1035 	}
1036 
1037 	ret = ddi_intr_get_pri(adapter->intr_handle, &adapter->intr_pri);
1038 	if (ret != DDI_SUCCESS) {
1039 		cmn_err(CE_WARN, "ddi_intr_get_pri() failure: %d\n", ret);
1040 	}
1041 
1042 	/* Call ddi_intr_add_handler() */
1043 	ret = ddi_intr_add_handler(adapter->intr_handle, unm_intr,
1044 	    (caddr_t)adapter, NULL);
1045 	if (ret != DDI_SUCCESS) {
1046 		cmn_err(CE_WARN, "%s%d: ddi_intr_add_handler() failure\n",
1047 		    adapter->name, adapter->instance);
1048 		(void) ddi_intr_free(adapter->intr_handle);
1049 		return (DDI_FAILURE);
1050 	}
1051 
1052 	/* Add softintr if required */
1053 
1054 	return (DDI_SUCCESS);
1055 
1056 }
1057 
1058 void
1059 unm_destroy_intr(unm_adapter *adapter)
1060 {
1061 	/* disable interrupt */
1062 	if (adapter->intr_type == DDI_INTR_TYPE_MSI)
1063 		(void) ddi_intr_block_disable(&adapter->intr_handle, 1);
1064 	else
1065 		(void) ddi_intr_disable(adapter->intr_handle);
1066 
1067 	(void) ddi_intr_remove_handler(adapter->intr_handle);
1068 	(void) ddi_intr_free(adapter->intr_handle);
1069 
1070 	/* Remove the software intr handler */
1071 }
1072 
1073 static void
1074 netxen_set_port_mode(unm_adapter *adapter)
1075 {
1076 	static int	wol_port_mode = UNM_PORT_MODE_AUTO_NEG_1G;
1077 	static int	port_mode = UNM_PORT_MODE_AUTO_NEG;
1078 	int		btype = adapter->ahw.boardcfg.board_type, data = 0;
1079 
1080 	if (btype == UNM_BRDTYPE_P3_HMEZ || btype == UNM_BRDTYPE_P3_XG_LOM) {
1081 		data = port_mode;	/* set to port_mode normally */
1082 		if ((port_mode != UNM_PORT_MODE_802_3_AP) &&
1083 		    (port_mode != UNM_PORT_MODE_XG) &&
1084 		    (port_mode != UNM_PORT_MODE_AUTO_NEG_1G) &&
1085 		    (port_mode != UNM_PORT_MODE_AUTO_NEG_XG))
1086 			data = UNM_PORT_MODE_AUTO_NEG;
1087 
1088 		adapter->unm_nic_hw_write_wx(adapter, UNM_PORT_MODE_ADDR,
1089 		    &data, 4);
1090 
1091 		if ((wol_port_mode != UNM_PORT_MODE_802_3_AP) &&
1092 		    (wol_port_mode != UNM_PORT_MODE_XG) &&
1093 		    (wol_port_mode != UNM_PORT_MODE_AUTO_NEG_1G) &&
1094 		    (wol_port_mode != UNM_PORT_MODE_AUTO_NEG_XG))
1095 			wol_port_mode = UNM_PORT_MODE_AUTO_NEG;
1096 
1097 		adapter->unm_nic_hw_write_wx(adapter, UNM_WOL_PORT_MODE,
1098 		    &wol_port_mode, 4);
1099 	}
1100 }
1101 
1102 static void
1103 netxen_pcie_strap_init(unm_adapter *adapter)
1104 {
1105 	ddi_acc_handle_t	pcihdl = adapter->pci_cfg_handle;
1106 	u32			chicken, control, c8c9value = 0xF1000;
1107 
1108 	adapter->unm_nic_hw_read_wx(adapter, UNM_PCIE_REG(PCIE_CHICKEN3),
1109 	    &chicken, 4);
1110 
1111 	chicken &= 0xFCFFFFFF;		/* clear chicken3 25:24 */
1112 	control = pci_config_get32(pcihdl, 0xD0);
1113 	if ((control & 0x000F0000) != 0x00020000)	/* is it gen1? */
1114 		chicken |= 0x01000000;
1115 	adapter->unm_nic_hw_write_wx(adapter, UNM_PCIE_REG(PCIE_CHICKEN3),
1116 	    &chicken, 4);
1117 	control = pci_config_get32(pcihdl, 0xC8);
1118 	control = pci_config_get32(pcihdl, 0xC8);
1119 	pci_config_put32(pcihdl, 0xC8, c8c9value);
1120 }
1121 
1122 static int
1123 netxen_read_mac_addr(unm_adapter *adapter)
1124 {
1125 	u64		mac_addr[8 + 1];
1126 	unsigned char	*p;
1127 	int		i;
1128 
1129 	if (get_flash_mac_addr(adapter, mac_addr) != 0)
1130 		return (-1);
1131 
1132 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
1133 		p = (unsigned char *)&mac_addr[adapter->ahw.pci_func];
1134 	else
1135 		p = (unsigned char *)&mac_addr[adapter->portnum];
1136 
1137 	for (i = 0; i < 6; i++)
1138 		adapter->mac_addr[i] = p[5 - i];
1139 
1140 	if (unm_nic_macaddr_set(adapter, adapter->mac_addr) != 0)
1141 		return (-1);
1142 
1143 	return (0);
1144 }
1145 
1146 static int
1147 unmattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1148 {
1149 	unm_adapter			*adapter;
1150 	int				i, first_driver = 0;
1151 	int				ret, temp;
1152 
1153 	switch (cmd) {
1154 	case DDI_ATTACH:
1155 		break;
1156 	case DDI_RESUME:
1157 	case DDI_PM_RESUME:
1158 	default:
1159 		return (DDI_FAILURE);
1160 	}
1161 
1162 	adapter = kmem_zalloc(sizeof (unm_adapter), KM_SLEEP);
1163 	adapter->dip = dip;
1164 	ddi_set_driver_private(dip, adapter);
1165 	adapter->instance = ddi_get_instance(dip);
1166 
1167 	adapter->name = ddi_driver_name(dip);
1168 
1169 	ret = pci_config_setup(dip, &adapter->pci_cfg_handle);
1170 	if (ret != DDI_SUCCESS) {
1171 		cmn_err(CE_WARN, "%s%d: pci_config_setup failed\n",
1172 		    adapter->name, adapter->instance);
1173 		goto attach_setup_err;
1174 	}
1175 
1176 	ret = unm_pci_cfg_init(adapter);
1177 	if (ret != DDI_SUCCESS)
1178 		goto attach_err;
1179 
1180 	ret = unm_pci_map_setup(adapter);
1181 	if (ret != DDI_SUCCESS)
1182 		goto attach_err;
1183 
1184 	if (unm_initialize_intr(adapter) != DDI_SUCCESS)
1185 		goto attach_unmap_regs;
1186 
1187 	rw_init(&adapter->adapter_lock, NULL,
1188 	    RW_DRIVER, DDI_INTR_PRI(adapter->intr_pri));
1189 	mutex_init(&adapter->tx_lock, NULL,
1190 	    MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri)));
1191 	mutex_init(&adapter->lock, NULL,
1192 	    MUTEX_DRIVER, (DDI_INTR_PRI(adapter->intr_pri)));
1193 
1194 	adapter->portnum = (int8_t)adapter->ahw.pci_func;
1195 
1196 	/*
1197 	 * Set the CRB window to invalid. If any register in window 0 is
1198 	 * accessed it should set window to 0 and then reset it to 1.
1199 	 */
1200 	adapter->curr_window = 255;
1201 
1202 	adapter->fw_major = adapter->unm_nic_pci_read_normalize(adapter,
1203 	    UNM_FW_VERSION_MAJOR);
1204 
1205 	if (adapter->fw_major < 4)
1206 		adapter->max_rds_rings = 3;
1207 	else
1208 		adapter->max_rds_rings = 2;
1209 
1210 	STRUCT_COPY(adapter->gc_dma_attr_desc, unm_dma_attr_desc);
1211 	STRUCT_COPY(adapter->gc_attr_desc, unm_buf_attr);
1212 
1213 	ret = unm_nic_get_board_info(adapter);
1214 	if (ret != DDI_SUCCESS) {
1215 		cmn_err(CE_WARN, "%s%d: error reading board config\n",
1216 		    adapter->name, adapter->instance);
1217 		goto attach_destroy_intr;
1218 	}
1219 
1220 	/* Mezz cards have PCI function 0, 2, 3 enabled */
1221 	switch (adapter->ahw.boardcfg.board_type) {
1222 	case UNM_BRDTYPE_P2_SB31_10G_IMEZ:
1223 	case UNM_BRDTYPE_P2_SB31_10G_HMEZ:
1224 		if (adapter->ahw.pci_func >= 2) {
1225 			adapter->portnum = adapter->ahw.pci_func - 2;
1226 		}
1227 	default:
1228 		break;
1229 	}
1230 
1231 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
1232 		temp = UNM_CRB_READ_VAL_ADAPTER(UNM_MIU_MN_CONTROL, adapter);
1233 		adapter->ahw.cut_through = NX_IS_SYSTEM_CUT_THROUGH(temp);
1234 		if (adapter->ahw.pci_func == 0)
1235 			first_driver = 1;
1236 	} else {
1237 		if (adapter->portnum == 0)
1238 			first_driver = 1;
1239 	}
1240 
1241 	unm_check_options(adapter);
1242 
1243 	if (first_driver) {
1244 		int first_boot = adapter->unm_nic_pci_read_normalize(adapter,
1245 		    UNM_CAM_RAM(0x1fc));
1246 
1247 		if (check_hw_init(adapter) != 0) {
1248 			cmn_err(CE_WARN, "%s%d: Error in HW init sequence\n",
1249 			    adapter->name, adapter->instance);
1250 			goto attach_destroy_intr;
1251 		}
1252 
1253 		if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
1254 			netxen_set_port_mode(adapter);
1255 
1256 		if (first_boot != 0x55555555) {
1257 			temp = 0;
1258 			adapter->unm_nic_hw_write_wx(adapter, CRB_CMDPEG_STATE,
1259 			    &temp, 4);
1260 			if (pinit_from_rom(adapter, 0) != 0)
1261 				goto attach_destroy_intr;
1262 
1263 			drv_usecwait(500);
1264 
1265 			ret = load_from_flash(adapter);
1266 			if (ret != DDI_SUCCESS)
1267 				goto attach_destroy_intr;
1268 		}
1269 
1270 		if (ret = unm_initialize_dummy_dma(adapter))
1271 			goto attach_destroy_intr;
1272 
1273 		/*
1274 		 * Tell the hardware our version number.
1275 		 */
1276 		i = (_UNM_NIC_MAJOR << 16) |
1277 		    ((_UNM_NIC_MINOR << 8)) | (_UNM_NIC_SUBVERSION);
1278 		adapter->unm_nic_hw_write_wx(adapter, CRB_DRIVER_VERSION,
1279 		    &i, 4);
1280 
1281 		/* Unlock the HW, prompting the boot sequence */
1282 		if ((first_boot == 0x55555555) &&
1283 		    (NX_IS_REVISION_P2(adapter->ahw.revision_id)))
1284 			adapter->unm_nic_pci_write_normalize(adapter,
1285 			    UNM_ROMUSB_GLB_PEGTUNE_DONE, 1);
1286 
1287 		/* Handshake with the card before we register the devices. */
1288 		if (phantom_init(adapter, 0) != DDI_SUCCESS)
1289 			goto attach_destroy_intr;
1290 	}
1291 
1292 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
1293 		netxen_pcie_strap_init(adapter);
1294 
1295 	/*
1296 	 * See if the firmware gave us a virtual-physical port mapping.
1297 	 */
1298 	adapter->physical_port = adapter->portnum;
1299 	i = adapter->unm_nic_pci_read_normalize(adapter,
1300 	    CRB_V2P(adapter->portnum));
1301 	if (i != 0x55555555)
1302 		adapter->physical_port = (uint16_t)i;
1303 
1304 	adapter->ahw.linkup = 0;
1305 
1306 	if (receive_peg_ready(adapter)) {
1307 		ret = -EIO;
1308 		goto free_dummy_dma;
1309 	}
1310 
1311 	if (netxen_read_mac_addr(adapter))
1312 		cmn_err(CE_WARN, "%s%d: Failed to read MAC addr\n",
1313 		    adapter->name, adapter->instance);
1314 
1315 	unm_nic_flash_print(adapter);
1316 
1317 	if (verbmsg != 0) {
1318 		switch (adapter->ahw.board_type) {
1319 		case UNM_NIC_GBE:
1320 			cmn_err(CE_NOTE, "%s: QUAD GbE port %d initialized\n",
1321 			    unm_nic_driver_name, adapter->portnum);
1322 			break;
1323 
1324 		case UNM_NIC_XGBE:
1325 			cmn_err(CE_NOTE, "%s: XGbE port %d initialized\n",
1326 			    unm_nic_driver_name, adapter->portnum);
1327 			break;
1328 		}
1329 	}
1330 
1331 	ret = unm_register_mac(adapter);
1332 	if (ret != DDI_SUCCESS) {
1333 		cmn_err(CE_NOTE, "%s%d: Mac registration error\n",
1334 		    adapter->name, adapter->instance);
1335 		goto free_dummy_dma;
1336 	}
1337 
1338 	return (DDI_SUCCESS);
1339 
1340 free_dummy_dma:
1341 	if (first_driver)
1342 		unm_free_dummy_dma(adapter);
1343 attach_destroy_intr:
1344 	unm_destroy_intr(adapter);
1345 attach_unmap_regs:
1346 	ddi_regs_map_free(&(adapter->regs_handle));
1347 	ddi_regs_map_free(&(adapter->db_handle));
1348 attach_err:
1349 	pci_config_teardown(&adapter->pci_cfg_handle);
1350 attach_setup_err:
1351 	kmem_free(adapter, sizeof (unm_adapter));
1352 	return (ret);
1353 }
1354 
1355 static int
1356 unmdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1357 {
1358 	unm_adapter  *adapter = (unm_adapter *)ddi_get_driver_private(dip);
1359 
1360 	if (adapter == NULL)
1361 	return (DDI_FAILURE);
1362 
1363 	switch (cmd) {
1364 	case DDI_DETACH:
1365 		unm_fini_kstats(adapter);
1366 		adapter->kstats[0] = NULL;
1367 
1368 		if (adapter->pci_cfg_handle != NULL)
1369 			pci_config_teardown(&adapter->pci_cfg_handle);
1370 
1371 		unm_nd_cleanup(adapter);
1372 		unm_nic_remove(adapter);
1373 		return (DDI_SUCCESS);
1374 
1375 	case DDI_SUSPEND:
1376 		return (unm_nic_suspend(adapter));
1377 
1378 	default:
1379 		break;
1380 	}
1381 
1382 	return (DDI_FAILURE);
1383 }
1384 
1385 int
1386 create_rxtx_rings(unm_adapter *adapter)
1387 {
1388 	unm_recv_context_t	*recv_ctx;
1389 	unm_rcv_desc_ctx_t	*rcv_desc;
1390 	int			i, ring;
1391 
1392 	adapter->cmd_buf_arr = (struct unm_cmd_buffer *)kmem_zalloc(
1393 	    sizeof (struct unm_cmd_buffer) * adapter->MaxTxDescCount,
1394 	    KM_SLEEP);
1395 
1396 	for (i = 0; i < MAX_RCV_CTX; ++i) {
1397 		recv_ctx = &adapter->recv_ctx[i];
1398 
1399 		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1400 			rcv_desc = &recv_ctx->rcv_desc[ring];
1401 			if (unm_create_rx_ring(adapter, rcv_desc) !=
1402 			    DDI_SUCCESS)
1403 				goto attach_free_cmdbufs;
1404 		}
1405 	}
1406 
1407 	if (unm_alloc_tx_dmahdl(adapter) != DDI_SUCCESS)
1408 		goto attach_free_cmdbufs;
1409 
1410 	if (unm_alloc_tx_buffers(adapter) != DDI_SUCCESS)
1411 		goto attach_free_tx_dmahdl;
1412 
1413 	return (DDI_SUCCESS);
1414 
1415 attach_free_tx_buffers:
1416 	unm_free_tx_buffers(adapter);
1417 attach_free_tx_dmahdl:
1418 	unm_free_tx_dmahdl(adapter);
1419 attach_free_cmdbufs:
1420 	kmem_free(adapter->cmd_buf_arr, sizeof (struct unm_cmd_buffer) *
1421 	    adapter->MaxTxDescCount);
1422 	for (i = 0; i < MAX_RCV_CTX; ++i) {
1423 		recv_ctx = &adapter->recv_ctx[i];
1424 
1425 		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1426 			rcv_desc = &recv_ctx->rcv_desc[ring];
1427 			if (rcv_desc->rx_buf_pool != NULL)
1428 				unm_destroy_rx_ring(rcv_desc);
1429 		}
1430 	}
1431 	return (DDI_FAILURE);
1432 }
1433 
1434 void
1435 destroy_rxtx_rings(unm_adapter *adapter)
1436 {
1437 	unm_recv_context_t	*recv_ctx;
1438 	unm_rcv_desc_ctx_t	*rcv_desc;
1439 	int			ctx, ring;
1440 
1441 	unm_free_tx_buffers(adapter);
1442 	unm_free_tx_dmahdl(adapter);
1443 
1444 	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
1445 		recv_ctx = &adapter->recv_ctx[ctx];
1446 		for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1447 			rcv_desc = &recv_ctx->rcv_desc[ring];
1448 			if (rcv_desc->rx_buf_pool != NULL)
1449 				unm_destroy_rx_ring(rcv_desc);
1450 		}
1451 	}
1452 
1453 	if (adapter->cmd_buf_arr != NULL)
1454 		kmem_free(adapter->cmd_buf_arr,
1455 		    sizeof (struct unm_cmd_buffer) * adapter->MaxTxDescCount);
1456 }
1457 
1458 #ifdef SOLARIS11
1459 DDI_DEFINE_STREAM_OPS(unm_ops, nulldev, nulldev, unmattach, unmdetach,
1460 	nodev, NULL, D_MP, NULL, NULL);
1461 #else
1462 DDI_DEFINE_STREAM_OPS(unm_ops, nulldev, nulldev, unmattach, unmdetach,
1463 	nodev, NULL, D_MP, NULL);
1464 #endif
1465 
1466 static struct modldrv modldrv = {
1467 	&mod_driverops,	/* Type of module.  This one is a driver */
1468 	ident,
1469 	&unm_ops,	/* driver ops */
1470 };
1471 
1472 static struct modlinkage modlinkage = {
1473 	MODREV_1,
1474 	(&modldrv),
1475 	NULL
1476 };
1477 
1478 
1479 int
1480 _init(void)
1481 {
1482 	int ret;
1483 
1484 	unm_ops.devo_cb_ops->cb_str = NULL;
1485 	mac_init_ops(&unm_ops, "ntxn");
1486 
1487 	ret = mod_install(&modlinkage);
1488 	if (ret != DDI_SUCCESS) {
1489 		mac_fini_ops(&unm_ops);
1490 		cmn_err(CE_WARN, "ntxn: mod_install failed\n");
1491 	}
1492 
1493 	return (ret);
1494 }
1495 
1496 
1497 int
1498 _fini(void)
1499 {
1500 	int ret;
1501 
1502 	ret = mod_remove(&modlinkage);
1503 	if (ret == DDI_SUCCESS)
1504 		mac_fini_ops(&unm_ops);
1505 	return (ret);
1506 }
1507 
1508 int
1509 _info(struct modinfo *modinfop)
1510 {
1511 	return (mod_info(&modlinkage, modinfop));
1512 }
1513