xref: /illumos-gate/usr/src/uts/common/io/chxge/pe.c (revision e214b19eaa16fec1fa60a97227778103f598336f)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * This file is part of the Chelsio T1 Ethernet driver.
29  *
30  * Copyright (C) 2003-2005 Chelsio Communications.  All rights reserved.
31  */
32 
33 /*
34  * Solaris Multithreaded STREAMS Chelsio PCI Ethernet Driver.
35  * Interface code
36  */
37 
38 #include <sys/types.h>
39 #include <sys/systm.h>
40 #include <sys/cmn_err.h>
41 #include <sys/ddi.h>
42 #include <sys/sunddi.h>
43 #include <sys/byteorder.h>
44 #include <sys/atomic.h>
45 #include <sys/ethernet.h>
46 #if PE_PROFILING_ENABLED
47 #include <sys/time.h>
48 #endif
49 #include <sys/gld.h>
50 #include "ostypes.h"
51 #include "common.h"
52 #include "oschtoe.h"
53 #ifdef CONFIG_CHELSIO_T1_1G
54 #include "fpga_defs.h"
55 #endif
56 #include "regs.h"
57 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
58 #include "mc3.h"
59 #include "mc4.h"
60 #endif
61 #include "sge.h"
62 #include "tp.h"
63 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
64 #include "ulp.h"
65 #endif
66 #include "espi.h"
67 #include "elmer0.h"
68 #include "gmac.h"
69 #include "cphy.h"
70 #include "suni1x10gexp_regs.h"
71 #include "ch.h"
72 
73 #define	MLEN(mp) ((mp)->b_wptr - (mp)->b_rptr)
74 
75 extern uint32_t buffers_in_use[];
76 extern kmutex_t in_use_l;
77 extern uint32_t in_use_index;
78 
79 static void link_start(ch_t *sa, struct pe_port_t *pp);
80 static ch_esb_t *ch_alloc_small_esbbuf(ch_t *sa, uint32_t i);
81 static ch_esb_t *ch_alloc_big_esbbuf(ch_t *sa, uint32_t i);
82 void ch_big_rbuf_recycle(ch_esb_t *rbp);
83 void ch_small_rbuf_recycle(ch_esb_t *rbp);
84 static const struct board_info *pe_sa_init(ch_t *sa);
85 static int ch_set_config_data(ch_t *chp);
86 void pe_rbuf_pool_free(ch_t *chp);
87 static void pe_free_driver_resources(ch_t *sa);
88 static void update_mtu_tab(ch_t *adapter);
89 static int pe_change_mtu(ch_t *chp);
90 
91 /*
92  * CPL5 Defines (from netinet/cpl5_commands.h)
93  */
94 #define	FLITSTOBYTES	8
95 
96 #define	CPL_FORMAT_0_SIZE 8
97 #define	CPL_FORMAT_1_SIZE 16
98 #define	CPL_FORMAT_2_SIZE 24
99 #define	CPL_FORMAT_3_SIZE 32
100 #define	CPL_FORMAT_4_SIZE 40
101 #define	CPL_FORMAT_5_SIZE 48
102 
103 #define	TID_MASK 0xffffff
104 
105 #define	PE_LINK_SPEED_AUTONEG	5
106 
107 static int pe_small_rbuf_pool_init(ch_t *sa);
108 static int pe_big_rbuf_pool_init(ch_t *sa);
109 static int pe_make_fake_arp(ch_t *chp, unsigned char *arpp);
110 static uint32_t pe_get_ip(unsigned char *arpp);
111 
112 /*
113  * May be set in /etc/system to 0 to use default latency timer for 10G.
114  * See PCI register 0xc definition.
115  */
116 int enable_latency_timer = 1;
117 
118 /*
119  * May be set in /etc/system to 0 to disable hardware checksum for
120  * TCP and UDP.
121  */
122 int enable_checksum_offload = 1;
123 
124 /*
125  * Multiplier for freelist pool.
126  */
127 int fl_sz_multiplier = 6;
128 
129 uint_t
130 pe_intr(ch_t *sa)
131 {
132 	mutex_enter(&sa->ch_intr);
133 
134 	if (sge_data_in(sa->sge)) {
135 		sa->isr_intr++;
136 		mutex_exit(&sa->ch_intr);
137 		return (DDI_INTR_CLAIMED);
138 	}
139 
140 	mutex_exit(&sa->ch_intr);
141 
142 	return (DDI_INTR_UNCLAIMED);
143 }
144 
145 /*
146  * Each setup struct will call this function to
147  * initialize.
148  */
149 void
150 pe_init(void* xsa)
151 {
152 	ch_t *sa = NULL;
153 	int i = 0;
154 
155 	sa = (ch_t *)xsa;
156 
157 	/*
158 	 * Need to count the number of times this routine is called
159 	 * because we only want the resources to be allocated once.
160 	 * The 7500 has four ports and so this routine can be called
161 	 * once for each port.
162 	 */
163 	if (sa->init_counter == 0) {
164 		for_each_port(sa, i) {
165 
166 			/*
167 			 * We only want to initialize the line if it is down.
168 			 */
169 			if (sa->port[i].line_up == 0) {
170 				link_start(sa, &sa->port[i]);
171 				sa->port[i].line_up = 1;
172 			}
173 		}
174 
175 		(void) t1_init_hw_modules(sa);
176 
177 		/*
178 		 * Enable/Disable checksum offloading.
179 		 */
180 		if (sa->ch_config.cksum_enabled) {
181 			if (sa->config_data.offload_ip_cksum) {
182 				/* Notify that HW will do the checksum. */
183 				t1_tp_set_ip_checksum_offload(sa->tp, 1);
184 			}
185 
186 			if (sa->config_data.offload_tcp_cksum) {
187 				/* Notify that HW will do the checksum. */
188 				t1_tp_set_tcp_checksum_offload(sa->tp, 1);
189 			}
190 
191 			if (sa->config_data.offload_udp_cksum) {
192 				/* Notify that HW will do the checksum. */
193 				t1_tp_set_udp_checksum_offload(sa->tp, 1);
194 			}
195 		}
196 
197 		sa->ch_flags |= PEINITDONE;
198 
199 		sa->init_counter++;
200 	}
201 
202 	/*
203 	 * Enable interrupts after starting the SGE so
204 	 * that the SGE is ready to handle interrupts.
205 	 */
206 	(void) sge_start(sa->sge);
207 	t1_interrupts_enable(sa);
208 
209 	/*
210 	 * set mtu (either 1500 or bigger)
211 	 */
212 	(void) pe_change_mtu(sa);
213 #ifdef HOST_PAUSE
214 	/*
215 	 * get the configured value of the MAC.
216 	 */
217 	(void) t1_tpi_read(sa, SUNI1x10GEXP_REG_TXXG_CONFIG_1 << 2,
218 	    &sa->txxg_cfg1);
219 #endif
220 }
221 
222 /* ARGSUSED */
223 static void
224 link_start(ch_t *sa, struct pe_port_t *p)
225 {
226 	struct cmac *mac = p->mac;
227 
228 	mac->ops->reset(mac);
229 	if (mac->ops->macaddress_set)
230 		mac->ops->macaddress_set(mac, p->enaddr);
231 	(void) t1_link_start(p->phy, mac, &p->link_config);
232 	mac->ops->enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
233 }
234 
235 /*
236  * turn off interrupts...
237  */
238 void
239 pe_stop(ch_t *sa)
240 {
241 	t1_interrupts_disable(sa);
242 	(void) sge_stop(sa->sge);
243 
244 	/*
245 	 * we can still be running an interrupt thread in sge_data_in().
246 	 * If we are, we'll block on the ch_intr lock
247 	 */
248 	mutex_enter(&sa->ch_intr);
249 	mutex_exit(&sa->ch_intr);
250 }
251 
252 /*
253  * output mblk to SGE level and out to the wire.
254  */
255 
256 int
257 pe_start(ch_t *sa, mblk_t *mp, uint32_t flg)
258 {
259 	mblk_t *m0 = mp;
260 	cmdQ_ce_t cm[16];
261 	cmdQ_ce_t *cmp;
262 	cmdQ_ce_t *hmp = &cm[0]; /* head of cm table (may be kmem_alloed) */
263 	int cm_flg = 0;		/* flag (1 - if kmem-alloced) */
264 	int nseg = 0;		/* number cmdQ_ce entries created */
265 	int mseg = 16;		/* maximum entries in hmp arrary */
266 	int freeme = 0;		/* we have an mblk to free in case of error */
267 	uint32_t ch_bind_dma_handle(ch_t *, int, caddr_t, cmdQ_ce_t *,
268 	    uint32_t);
269 #if defined(__sparc)
270 	uint32_t ch_bind_dvma_handle(ch_t *, int, caddr_t, cmdQ_ce_t *,
271 	    uint32_t);
272 #endif
273 	int rv;			/* return value on error */
274 
275 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
276 	if (flg & CH_OFFLOAD) {
277 		hmp->ce_pa = ((tbuf_t *)mp)->tb_pa;
278 		hmp->ce_dh = NULL;
279 		hmp->ce_flg = DH_TOE;
280 		hmp->ce_len = ((tbuf_t *)mp)->tb_len;
281 		hmp->ce_mp = mp;
282 
283 		/* make sure data is flushed to physical memory */
284 		(void) ddi_dma_sync((ddi_dma_handle_t)((tbuf_t *)mp)->tb_dh,
285 		    (off_t)0, hmp->ce_len, DDI_DMA_SYNC_FORDEV);
286 
287 		if (sge_data_out(sa->sge, 0, mp, hmp, 1, flg) == 0) {
288 			return (0);
289 		}
290 
291 		/*
292 		 * set a flag so we'll restart upper layer when
293 		 * resources become available.
294 		 */
295 		sa->ch_blked = 1;
296 		return (1);
297 	}
298 #endif	/* CONFIG_CHELSIO_T1_OFFLOAD */
299 
300 	/* writes from toe will always have CPL header in place */
301 	if (flg & CH_NO_CPL) {
302 		struct cpl_tx_pkt *cpl;
303 
304 		/* PR2928 & PR3309 */
305 		if (sa->ch_ip == 0) {
306 			ushort_t ethertype = ntohs(*(short *)&mp->b_rptr[12]);
307 			if (ethertype == ETHERTYPE_ARP) {
308 				if (is_T2(sa)) {
309 					/*
310 					 * We assume here that the arp will be
311 					 * contained in one mblk.
312 					 */
313 					if (pe_make_fake_arp(sa, mp->b_rptr)) {
314 						freemsg(mp);
315 						sa->oerr++;
316 						return (0);
317 					}
318 				} else {
319 					sa->ch_ip = pe_get_ip(mp->b_rptr);
320 				}
321 			}
322 		}
323 
324 		/*
325 		 * if space in front of packet big enough for CPL
326 		 * header, then use it. We'll allocate an mblk
327 		 * otherwise.
328 		 */
329 		if ((mp->b_rptr - mp->b_datap->db_base) >= SZ_CPL_TX_PKT) {
330 
331 			mp->b_rptr -= SZ_CPL_TX_PKT;
332 
333 		} else {
334 
335 #ifdef SUN_KSTATS
336 			sa->sge->intr_cnt.tx_need_cpl_space++;
337 #endif
338 			m0 = allocb(SZ_CPL_TX_PKT, BPRI_HI);
339 			if (m0 == NULL) {
340 				freemsg(mp);
341 				sa->oerr++;
342 				return (0);
343 			}
344 
345 			m0->b_wptr = m0->b_rptr + SZ_CPL_TX_PKT;
346 			m0->b_cont = mp;
347 			freeme = 1;
348 
349 			mp = m0;
350 		}
351 
352 		/* fill in cpl header */
353 		cpl = (struct cpl_tx_pkt *)mp->b_rptr;
354 		cpl->opcode = CPL_TX_PKT;
355 		cpl->iff = 0;		/* XXX port 0 needs fixing with NEMO */
356 		cpl->ip_csum_dis = 1;	/* no IP header cksum */
357 		cpl->l4_csum_dis =
358 		    flg & CH_NO_HWCKSUM;	/* CH_NO_HWCKSUM == 1 */
359 		cpl->vlan_valid = 0;		/* no vlan */
360 	}
361 
362 	if (m0->b_cont) {
363 
364 #ifdef SUN_KSTATS
365 			sa->sge->intr_cnt.tx_multi_mblks++;
366 #endif
367 
368 		while (mp) {
369 			int lseg;	/* added by ch_bind_dma_handle() */
370 			int len;
371 
372 			len = MLEN(mp);
373 			/* skip mlks with no data */
374 			if (len == 0) {
375 				mp = mp->b_cont;
376 				continue;
377 			}
378 
379 			/*
380 			 * if we've run out of space on stack, then we
381 			 * allocate a temporary buffer to hold the
382 			 * information. This will kill the the performance,
383 			 * but since it shouldn't really occur, we can live
384 			 * with it. Since jumbo frames may map multiple
385 			 * descriptors, we reallocate the hmp[] array before
386 			 * we reach the end.
387 			 */
388 			if (nseg >= (mseg-4)) {
389 				cmdQ_ce_t *buf;
390 				int j;
391 
392 				buf = kmem_alloc(sizeof (cmdQ_ce_t) * 2 * mseg,
393 				    KM_SLEEP);
394 
395 				for (j = 0; j < nseg; j++)
396 					buf[j] = hmp[j];
397 
398 				if (cm_flg) {
399 					kmem_free(hmp,
400 					    mseg * sizeof (cmdQ_ce_t));
401 				} else
402 					cm_flg = 1;
403 
404 				hmp = buf;
405 				mseg = 2*mseg;
406 
407 				/*
408 				 * We've used up ch table on stack
409 				 */
410 			}
411 
412 #if defined(__sparc)
413 			if (sa->ch_config.enable_dvma) {
414 				lseg = ch_bind_dvma_handle(sa, len,
415 				    (void *)mp->b_rptr,
416 				    &hmp[nseg], mseg - nseg);
417 				if (lseg == 0) {
418 					sa->sge->intr_cnt.tx_no_dvma1++;
419 					if ((lseg = ch_bind_dma_handle(sa, len,
420 					    (void *)mp->b_rptr,
421 					    &hmp[nseg],
422 					    mseg - nseg)) == 0) {
423 						sa->sge->intr_cnt.tx_no_dma1++;
424 
425 						/*
426 						 * ran out of space. Gonna bale
427 						 */
428 						rv = 0;
429 
430 						/*
431 						 * we may have processed
432 						 * previous mblks and have
433 						 * descriptors. If so, we need
434 						 * to free the meta struct
435 						 * entries before freeing
436 						 * the mblk.
437 						 */
438 						if (nseg)
439 							goto error;
440 						goto error1;
441 					}
442 				}
443 			} else {
444 				lseg = ch_bind_dma_handle(sa, len,
445 				    (void *)mp->b_rptr, &hmp[nseg],
446 				    mseg - nseg);
447 				if (lseg == 0) {
448 					sa->sge->intr_cnt.tx_no_dma1++;
449 
450 					/*
451 					 * ran out of space. Gona bale
452 					 */
453 					rv = 0;
454 
455 					/*
456 					 * we may have processed previous
457 					 * mblks and have descriptors. If so,
458 					 * we need to free the meta struct
459 					 * entries before freeing the mblk.
460 					 */
461 					if (nseg)
462 						goto error;
463 					goto error1;
464 				}
465 			}
466 #else	/* defined(__sparc) */
467 			lseg = ch_bind_dma_handle(sa, len,
468 			    (void *)mp->b_rptr, &hmp[nseg],
469 			    mseg - nseg);
470 			if (lseg == 0) {
471 				sa->sge->intr_cnt.tx_no_dma1++;
472 
473 				/*
474 				 * ran out of space. Gona bale
475 				 */
476 				rv = 0;
477 
478 				/*
479 				 * we may have processed previous mblks and
480 				 * have descriptors. If so, we need to free
481 				 * the meta struct entries before freeing
482 				 * the mblk.
483 				 */
484 				if (nseg)
485 					goto error;
486 				goto error1;
487 			}
488 #endif	/* defined(__sparc) */
489 			nseg += lseg;
490 			mp = mp->b_cont;
491 		}
492 
493 		/*
494 		 * SHOULD NEVER OCCUR, BUT...
495 		 * no data if nseg 0 or
496 		 * nseg 1 and a CPL mblk (CPL mblk only with offload mode)
497 		 * and no data
498 		 */
499 		if ((nseg == 0) || (freeme && (nseg == 1))) {
500 			rv = 0;
501 			goto error1;
502 		}
503 
504 	} else {
505 		int len;
506 
507 		/* we assume that we always have data with one packet */
508 		len = MLEN(mp);
509 
510 #if defined(__sparc)
511 		if (sa->ch_config.enable_dvma) {
512 			nseg = ch_bind_dvma_handle(sa, len,
513 			    (void *)mp->b_rptr,
514 			    &hmp[0], 16);
515 			if (nseg == 0) {
516 				sa->sge->intr_cnt.tx_no_dvma2++;
517 				nseg = ch_bind_dma_handle(sa, len,
518 				    (void *)mp->b_rptr,
519 				    &hmp[0], 16);
520 				if (nseg == 0) {
521 					sa->sge->intr_cnt.tx_no_dma2++;
522 
523 					/*
524 					 * ran out of space. Gona bale
525 					 */
526 					rv = 0;
527 					goto error1;
528 				}
529 			}
530 		} else {
531 			nseg = ch_bind_dma_handle(sa, len,
532 			    (void *)mp->b_rptr, &hmp[0], 16);
533 			if (nseg == 0) {
534 				sa->sge->intr_cnt.tx_no_dma2++;
535 
536 				/*
537 				 * ran out of space. Gona bale
538 				 */
539 				rv = 0;
540 				goto error1;
541 			}
542 		}
543 #else	/* defined(__sparc) */
544 		nseg = ch_bind_dma_handle(sa, len,
545 		    (void *)mp->b_rptr, &hmp[0], 16);
546 		if (nseg == 0) {
547 			sa->sge->intr_cnt.tx_no_dma2++;
548 
549 			/*
550 			 * ran out of space. Gona bale
551 			 */
552 			rv = 0;
553 			goto error1;
554 		}
555 #endif	/* defined(__sparc) */
556 
557 		/*
558 		 * dummy arp message to handle PR3309 & PR2928
559 		 */
560 		if (flg & CH_ARP)
561 			hmp->ce_flg |= DH_ARP;
562 	}
563 
564 	if (sge_data_out(sa->sge, 0, m0, hmp, nseg, flg) == 0) {
565 		if (cm_flg)
566 			kmem_free(hmp, mseg * sizeof (cmdQ_ce_t));
567 		return (0);
568 	}
569 
570 	/*
571 	 * set a flag so we'll restart upper layer when
572 	 * resources become available.
573 	 */
574 	if ((flg & CH_ARP) == 0)
575 		sa->ch_blked = 1;
576 	rv = 1;
577 
578 error:
579 	/*
580 	 * unmap the physical addresses allocated earlier.
581 	 */
582 	cmp = hmp;
583 	for (--nseg; nseg >= 0; nseg--) {
584 		if (cmp->ce_dh) {
585 			if (cmp->ce_flg == DH_DMA)
586 				ch_unbind_dma_handle(sa, cmp->ce_dh);
587 #if defined(__sparc)
588 			else
589 				ch_unbind_dvma_handle(sa, cmp->ce_dh);
590 #endif
591 		}
592 		cmp++;
593 	}
594 
595 error1:
596 
597 	/* free the temporary array */
598 	if (cm_flg)
599 		kmem_free(hmp, mseg * sizeof (cmdQ_ce_t));
600 
601 	/*
602 	 * if we've allocated an mblk above, then we need to free it
603 	 * before returning. This is safe since we haven't done anything to
604 	 * the original message. The caller, gld, will still have a pointer
605 	 * to the original mblk.
606 	 */
607 	if (rv == 1) {
608 		if (freeme) {
609 			/* we had to allocate an mblk. Free it. */
610 			freeb(m0);
611 		} else {
612 			/* adjust the mblk back to original start */
613 			if (flg & CH_NO_CPL)
614 				m0->b_rptr += SZ_CPL_TX_PKT;
615 		}
616 	} else {
617 		freemsg(m0);
618 		sa->oerr++;
619 	}
620 
621 	return (rv);
622 }
623 
624 /* KLUDGE ALERT. HARD WIRED TO PORT ZERO */
625 void
626 pe_set_mac(ch_t *sa, unsigned char *ac_enaddr)
627 {
628 	sa->port[0].mac->ops->macaddress_set(sa->port[0].mac, ac_enaddr);
629 }
630 
631 /* KLUDGE ALERT. HARD WIRED TO PORT ZERO */
632 unsigned char *
633 pe_get_mac(ch_t *sa)
634 {
635 	return (sa->port[0].enaddr);
636 }
637 
638 /* KLUDGE ALERT. HARD WIRED TO ONE PORT */
639 void
640 pe_set_promiscuous(ch_t *sa, int flag)
641 {
642 	struct cmac *mac = sa->port[0].mac;
643 	struct t1_rx_mode rm;
644 
645 	switch (flag) {
646 	case 0:		/* turn off promiscuous mode */
647 		sa->ch_flags &= ~(PEPROMISC|PEALLMULTI);
648 		break;
649 
650 	case 1:		/* turn on promiscuous mode */
651 		sa->ch_flags |= PEPROMISC;
652 		break;
653 
654 	case 2:		/* turn on multicast reception */
655 		sa->ch_flags |= PEALLMULTI;
656 		break;
657 	}
658 
659 	mutex_enter(&sa->ch_mc_lck);
660 	rm.chp = sa;
661 	rm.mc = sa->ch_mc;
662 
663 	mac->ops->set_rx_mode(mac, &rm);
664 	mutex_exit(&sa->ch_mc_lck);
665 }
666 
667 int
668 pe_set_mc(ch_t *sa, uint8_t *ep, int flg)
669 {
670 	struct cmac *mac = sa->port[0].mac;
671 	struct t1_rx_mode rm;
672 
673 	if (flg == GLD_MULTI_ENABLE) {
674 		ch_mc_t *mcp;
675 
676 		mcp = (ch_mc_t *)kmem_zalloc(sizeof (struct ch_mc),
677 		    KM_NOSLEEP);
678 		if (mcp == NULL)
679 			return (GLD_NORESOURCES);
680 
681 		bcopy(ep, &mcp->cmc_mca, 6);
682 
683 		mutex_enter(&sa->ch_mc_lck);
684 		mcp->cmc_next = sa->ch_mc;
685 		sa->ch_mc = mcp;
686 		sa->ch_mc_cnt++;
687 		mutex_exit(&sa->ch_mc_lck);
688 
689 	} else if (flg == GLD_MULTI_DISABLE) {
690 		ch_mc_t **p = &sa->ch_mc;
691 		ch_mc_t *q = NULL;
692 
693 		mutex_enter(&sa->ch_mc_lck);
694 		p = &sa->ch_mc;
695 		while (*p) {
696 			if (bcmp(ep, (*p)->cmc_mca, 6) == 0) {
697 				q = *p;
698 				*p = (*p)->cmc_next;
699 				kmem_free(q, sizeof (*q));
700 				sa->ch_mc_cnt--;
701 				break;
702 			}
703 
704 			p = &(*p)->cmc_next;
705 		}
706 		mutex_exit(&sa->ch_mc_lck);
707 
708 		if (q == NULL)
709 			return (GLD_BADARG);
710 	} else
711 		return (GLD_BADARG);
712 
713 	mutex_enter(&sa->ch_mc_lck);
714 	rm.chp = sa;
715 	rm.mc = sa->ch_mc;
716 
717 	mac->ops->set_rx_mode(mac, &rm);
718 	mutex_exit(&sa->ch_mc_lck);
719 
720 	return (GLD_SUCCESS);
721 }
722 
723 /*
724  * return: speed       - bandwidth of interface
725  * return: intrcnt     - # interrupts
726  * return: norcvbuf    - # recedived packets dropped by driver
727  * return: oerrors     - # bad send packets
728  * return: ierrors     - # bad receive packets
729  * return: underrun    - # bad underrun xmit packets
730  * return: overrun     - # bad overrun recv packets
731  * return: framing     - # bad aligned recv packets
732  * return: crc         - # bad FCS (crc) recv packets
733  * return: carrier     - times carrier was lost
734  * return: collisions  - # xmit collisions
735  * return: xcollisions - # xmit pkts dropped due to collisions
736  * return: late        - # late xmit collisions
737  * return: defer       - # deferred xmit packets
738  * return: xerrs       - # xmit dropped packets
739  * return: rerrs       - # recv dropped packets
740  * return: toolong     - # recv pkts too long
741  * return: runt        - # recv runt pkts
742  * return: multixmt    - # multicast pkts xmitted
743  * return: multircv    - # multicast pkts recved
744  * return: brdcstxmt   - # broadcast pkts xmitted
745  * return: brdcstrcv   - # broadcast pkts rcv
746  */
747 
748 int
749 pe_get_stats(ch_t *sa, uint64_t *speed, uint32_t *intrcnt, uint32_t *norcvbuf,
750     uint32_t *oerrors, uint32_t *ierrors, uint32_t *underrun,
751     uint32_t *overrun, uint32_t *framing, uint32_t *crc,
752     uint32_t *carrier, uint32_t *collisions, uint32_t *xcollisions,
753     uint32_t *late, uint32_t *defer, uint32_t *xerrs, uint32_t *rerrs,
754     uint32_t *toolong, uint32_t *runt, ulong_t  *multixmt, ulong_t  *multircv,
755     ulong_t  *brdcstxmt, ulong_t  *brdcstrcv)
756 {
757 	struct pe_port_t *pt;
758 	int line_speed;
759 	int line_duplex;
760 	int line_is_active;
761 	uint64_t v;
762 	const struct cmac_statistics *sp;
763 
764 	pt = &(sa->port[0]);
765 	(void) pt->phy->ops->get_link_status(pt->phy,
766 	    &line_is_active, &line_speed, &line_duplex, NULL);
767 
768 	switch (line_speed) {
769 	case SPEED_10:
770 		*speed = 10000000;
771 		break;
772 	case SPEED_100:
773 		*speed = 100000000;
774 		break;
775 	case SPEED_1000:
776 		*speed = 1000000000;
777 		break;
778 	case SPEED_10000:
779 		/*
780 		 * kludge to get 10,000,000,000 constant (and keep
781 		 * compiler happy).
782 		 */
783 		v = 10000000;
784 		v *= 1000;
785 		*speed = v;
786 		break;
787 	default:
788 		goto error;
789 	}
790 
791 	*intrcnt = sa->isr_intr;
792 	*norcvbuf = sa->norcvbuf;
793 
794 	sp = sa->port[0].mac->ops->statistics_update(sa->port[0].mac,
795 	    MAC_STATS_UPDATE_FULL);
796 
797 	*ierrors = sp->RxOctetsBad;
798 
799 	/*
800 	 * not sure this is correct. # aborted at driver level +
801 	 * # at hardware level
802 	 */
803 	*oerrors = sa->oerr + sp->TxFramesAbortedDueToXSCollisions +
804 	    sp->TxUnderrun + sp->TxLengthErrors +
805 	    sp->TxInternalMACXmitError +
806 	    sp->TxFramesWithExcessiveDeferral +
807 	    sp->TxFCSErrors;
808 
809 	*underrun = sp->TxUnderrun;
810 	*overrun = sp->RxFrameTooLongErrors;
811 	*framing = sp->RxAlignErrors;
812 	*crc = sp->RxFCSErrors;
813 	*carrier = 0;		/* need to find this */
814 	*collisions = sp->TxTotalCollisions;
815 	*xcollisions = sp->TxFramesAbortedDueToXSCollisions;
816 	*late = sp->TxLateCollisions;
817 	*defer = sp->TxFramesWithDeferredXmissions;
818 	*xerrs = sp->TxUnderrun + sp->TxLengthErrors +
819 	    sp->TxInternalMACXmitError + sp->TxFCSErrors;
820 	*rerrs = sp->RxSymbolErrors + sp->RxSequenceErrors + sp->RxRuntErrors +
821 	    sp->RxJabberErrors + sp->RxInternalMACRcvError +
822 	    sp->RxInRangeLengthErrors + sp->RxOutOfRangeLengthField;
823 	*toolong = sp->RxFrameTooLongErrors;
824 	*runt = sp->RxRuntErrors;
825 
826 	*multixmt = sp->TxMulticastFramesOK;
827 	*multircv = sp->RxMulticastFramesOK;
828 	*brdcstxmt = sp->TxBroadcastFramesOK;
829 	*brdcstrcv = sp->RxBroadcastFramesOK;
830 
831 	return (0);
832 
833 error:
834 	*speed = 0;
835 	*intrcnt = 0;
836 	*norcvbuf = 0;
837 	*norcvbuf = 0;
838 	*oerrors = 0;
839 	*ierrors = 0;
840 	*underrun = 0;
841 	*overrun = 0;
842 	*framing = 0;
843 	*crc = 0;
844 	*carrier = 0;
845 	*collisions = 0;
846 	*xcollisions = 0;
847 	*late = 0;
848 	*defer = 0;
849 	*xerrs = 0;
850 	*rerrs = 0;
851 	*toolong = 0;
852 	*runt = 0;
853 	*multixmt = 0;
854 	*multircv = 0;
855 	*brdcstxmt = 0;
856 	*brdcstrcv = 0;
857 
858 	return (1);
859 }
860 
861 uint32_t ch_gtm = 0;		/* Default: Global Tunnel Mode off */
862 uint32_t ch_global_config = 0x07000000;	/* Default: errors, warnings, status */
863 uint32_t ch_is_asic = 0;	/* Default: non-ASIC */
864 uint32_t ch_link_speed = PE_LINK_SPEED_AUTONEG;	/* Default: auto-negoiate */
865 uint32_t ch_num_of_ports = 1;	/* Default: 1 port */
866 uint32_t ch_tp_reset_cm = 1;	/* Default: reset CM memory map */
867 uint32_t ch_phy_tx_fifo = 0;	/* Default: 0 phy tx fifo depth */
868 uint32_t ch_phy_rx_fifo = 0;	/* Default: 0 phy rx fifo depth */
869 uint32_t ch_phy_force_master = 1;	/* Default: link always master mode */
870 uint32_t ch_mc5_rtbl_size = 2048;	/* Default: TCAM routing table size */
871 uint32_t ch_mc5_dbsvr_size = 128;	/* Default: TCAM server size */
872 uint32_t ch_mc5_parity = 1;	/* Default: parity error checking */
873 uint32_t ch_mc5_issue_syn = 0;	/* Default: Allow transaction overlap */
874 uint32_t ch_packet_tracing = 0;		/* Default: no packet tracing */
875 uint32_t ch_server_region_len =
876 	DEFAULT_SERVER_REGION_LEN;
877 uint32_t ch_rt_region_len =
878 	DEFAULT_RT_REGION_LEN;
879 uint32_t ch_offload_ip_cksum = 0;	/* Default: no checksum offloading */
880 uint32_t ch_offload_udp_cksum = 1;	/* Default: offload UDP ckecksum */
881 uint32_t ch_offload_tcp_cksum = 1;	/* Default: offload TCP checksum */
882 uint32_t ch_sge_cmdq_threshold = 0;	/* Default: threshold 0 */
883 uint32_t ch_sge_flq_threshold = 0;	/* Default: SGE flq threshold */
884 uint32_t ch_sge_cmdq0_cnt =	/* Default: cmd queue 0 size */
885 	SGE_CMDQ0_CNT;
886 uint32_t ch_sge_cmdq1_cnt =	/* Default: cmd queue 1 size */
887 	SGE_CMDQ0_CNT;
888 uint32_t ch_sge_flq0_cnt =	/* Default: free list queue-0 length */
889 	SGE_FLQ0_CNT;
890 uint32_t ch_sge_flq1_cnt =	/* Default: free list queue-1 length */
891 	SGE_FLQ0_CNT;
892 uint32_t ch_sge_respq_cnt =	/* Default: reqsponse queue size */
893 	SGE_RESPQ_CNT;
894 uint32_t ch_stats = 1;		/* Default: Automatic Update MAC stats */
895 uint32_t ch_tx_delay_us = 0;	/* Default: No Msec delay to Tx pkts */
896 int32_t ch_chip = -1;		/* Default: use hardware lookup tbl */
897 uint32_t ch_exit_early = 0;	/* Default: complete initialization */
898 uint32_t ch_rb_num_of_entries = 1000; /* Default: number ring buffer entries */
899 uint32_t ch_rb_size_of_entries = 64;	/* Default: ring buffer entry size */
900 uint32_t ch_rb_flag = 1;	/* Default: ring buffer flag */
901 uint32_t ch_type;
902 uint64_t ch_cat_opt0 = 0;
903 uint64_t ch_cat_opt1 = 0;
904 uint32_t ch_timer_delay = 0;	/* Default: use value from board entry */
905 
906 int
907 pe_attach(ch_t *chp)
908 {
909 	int return_val = 1;
910 	const struct board_info *bi;
911 	uint32_t pcix_cmd;
912 
913 	(void) ch_set_config_data(chp);
914 
915 	bi = pe_sa_init(chp);
916 	if (bi == 0)
917 		return (1);
918 
919 	if (t1_init_sw_modules(chp, bi) < 0)
920 		return (1);
921 
922 	if (pe_small_rbuf_pool_init(chp) == 0)
923 		return (1);
924 
925 	if (pe_big_rbuf_pool_init(chp) == 0)
926 		return (1);
927 
928 	/*
929 	 * We gain significaint performance improvements when we
930 	 * increase the PCI's maximum memory read byte count to
931 	 * 2K(HW doesn't support 4K at this time) and set the PCI's
932 	 * maximum outstanding split transactions to 4. We want to do
933 	 * this for 10G. Done by software utility.
934 	 */
935 
936 	if (board_info(chp)->caps & SUPPORTED_10000baseT_Full) {
937 		(void) t1_os_pci_read_config_4(chp, A_PCICFG_PCIX_CMD,
938 		    &pcix_cmd);
939 		/*
940 		 * if the burstsize is set, then use it instead of default
941 		 */
942 		if (chp->ch_config.burstsize_set) {
943 			pcix_cmd &= ~0xc0000;
944 			pcix_cmd |= (chp->ch_config.burstsize << 18);
945 		}
946 		/*
947 		 * if the split transaction count is set, then use it.
948 		 */
949 		if (chp->ch_config.transaction_cnt_set) {
950 			pcix_cmd &= ~ 0x700000;
951 			pcix_cmd |= (chp->ch_config.transaction_cnt << 20);
952 		}
953 
954 		/*
955 		 * set ralaxed ordering flag as configured in chxge.conf
956 		 */
957 		pcix_cmd |= (chp->ch_config.relaxed_ordering << 17);
958 
959 		(void) t1_os_pci_write_config_4(chp, A_PCICFG_PCIX_CMD,
960 		    pcix_cmd);
961 	}
962 
963 	/*
964 	 * set the latency time to F8 for 10G cards.
965 	 * Done by software utiltiy.
966 	 */
967 	if (enable_latency_timer) {
968 		if (board_info(chp)->caps & SUPPORTED_10000baseT_Full) {
969 			(void) t1_os_pci_write_config_4(chp, 0xc, 0xf800);
970 		}
971 	}
972 
973 	/*
974 	 * update mtu table (regs: 0x404 - 0x420) with bigger values than
975 	 * default.
976 	 */
977 	update_mtu_tab(chp);
978 
979 	/*
980 	 * Clear all interrupts now.  Don't enable
981 	 * them until later.
982 	 */
983 	t1_interrupts_clear(chp);
984 
985 	/*
986 	 * Function succeeded.
987 	 */
988 	return_val = 0;
989 
990 	return (return_val);
991 }
992 
993 /*
994  * DESC: Read variables set in /boot/loader.conf and save
995  *       them internally. These internal values are then
996  *       used to make decisions at run-time on behavior thus
997  *       allowing a certain level of customization.
998  * OUT:  p_config - pointer to config structure that
999  *                  contains all of the new values.
1000  * RTN:  0 - Success;
1001  */
1002 static int
1003 ch_set_config_data(ch_t *chp)
1004 {
1005 	pe_config_data_t *p_config = (pe_config_data_t *)&chp->config_data;
1006 
1007 	bzero(p_config, sizeof (pe_config_data_t));
1008 
1009 	/*
1010 	 * Global Tunnel Mode configuration
1011 	 */
1012 	p_config->gtm = ch_gtm;
1013 
1014 	p_config->global_config = ch_global_config;
1015 
1016 	if (p_config->gtm)
1017 		p_config->global_config |= CFGMD_TUNNEL;
1018 
1019 	p_config->tp_reset_cm = ch_tp_reset_cm;
1020 	p_config->is_asic = ch_is_asic;
1021 
1022 	/*
1023 	 * MC5 configuration.
1024 	 */
1025 	p_config->mc5_rtbl_size = ch_mc5_rtbl_size;
1026 	p_config->mc5_dbsvr_size = ch_mc5_dbsvr_size;
1027 	p_config->mc5_parity = ch_mc5_parity;
1028 	p_config->mc5_issue_syn = ch_mc5_issue_syn;
1029 
1030 	p_config->offload_ip_cksum = ch_offload_ip_cksum;
1031 	p_config->offload_udp_cksum = ch_offload_udp_cksum;
1032 	p_config->offload_tcp_cksum = ch_offload_tcp_cksum;
1033 
1034 	p_config->packet_tracing = ch_packet_tracing;
1035 
1036 	p_config->server_region_len = ch_server_region_len;
1037 	p_config->rt_region_len = ch_rt_region_len;
1038 
1039 	/*
1040 	 * Link configuration.
1041 	 *
1042 	 * 5-auto-neg 2-1000Gbps; 1-100Gbps; 0-10Gbps
1043 	 */
1044 	p_config->link_speed = ch_link_speed;
1045 	p_config->num_of_ports = ch_num_of_ports;
1046 
1047 	/*
1048 	 * Catp options
1049 	 */
1050 	p_config->cat_opt0 = ch_cat_opt0;
1051 	p_config->cat_opt1 = ch_cat_opt1;
1052 
1053 	/*
1054 	 * SGE configuration.
1055 	 */
1056 	p_config->sge_cmdq0_cnt = ch_sge_cmdq0_cnt;
1057 	p_config->sge_cmdq1_cnt = ch_sge_cmdq1_cnt;
1058 	p_config->sge_flq0_cnt = ch_sge_flq0_cnt;
1059 	p_config->sge_flq1_cnt = ch_sge_flq1_cnt;
1060 	p_config->sge_respq_cnt = ch_sge_respq_cnt;
1061 
1062 	p_config->phy_rx_fifo = ch_phy_rx_fifo;
1063 	p_config->phy_tx_fifo = ch_phy_tx_fifo;
1064 
1065 	p_config->sge_cmdq_threshold = ch_sge_cmdq_threshold;
1066 
1067 	p_config->sge_flq_threshold = ch_sge_flq_threshold;
1068 
1069 	p_config->phy_force_master = ch_phy_force_master;
1070 
1071 	p_config->rb_num_of_entries = ch_rb_num_of_entries;
1072 
1073 	p_config->rb_size_of_entries = ch_rb_size_of_entries;
1074 
1075 	p_config->rb_flag = ch_rb_flag;
1076 
1077 	p_config->exit_early = ch_exit_early;
1078 
1079 	p_config->chip = ch_chip;
1080 
1081 	p_config->stats = ch_stats;
1082 
1083 	p_config->tx_delay_us = ch_tx_delay_us;
1084 
1085 	return (0);
1086 }
1087 
1088 static const struct board_info *
1089 pe_sa_init(ch_t *sa)
1090 {
1091 	uint16_t device_id;
1092 	uint16_t device_subid;
1093 	const struct board_info *bi;
1094 
1095 	sa->config = sa->config_data.global_config;
1096 	device_id = pci_config_get16(sa->ch_hpci, 2);
1097 	device_subid = pci_config_get16(sa->ch_hpci, 0x2e);
1098 
1099 	bi = t1_get_board_info_from_ids(device_id, device_subid);
1100 	if (bi == NULL) {
1101 		cmn_err(CE_NOTE,
1102 		    "The adapter with device_id %d %d is not supported.\n",
1103 		    device_id, device_subid);
1104 		return (NULL);
1105 	}
1106 
1107 	if (t1_get_board_rev(sa, bi, &sa->params)) {
1108 		cmn_err(CE_NOTE, "unknown device_id %d %d\n",
1109 		    device_id, device_subid);
1110 		return ((const struct board_info *)NULL);
1111 	}
1112 
1113 	return (bi);
1114 }
1115 
1116 /*
1117  * allocate pool of small receive buffers (with vaddr & paddr) and
1118  * receiver buffer control structure (ch_esb_t *rbp).
1119  * XXX we should allow better tuning of the # of preallocated
1120  * free buffers against the # of freelist entries.
1121  */
1122 static int
1123 pe_small_rbuf_pool_init(ch_t *sa)
1124 {
1125 	int i;
1126 	ch_esb_t *rbp;
1127 	extern uint32_t sge_flq0_cnt;
1128 	extern uint32_t sge_flq1_cnt;
1129 	int size;
1130 	uint32_t j;
1131 
1132 	if (is_T2(sa))
1133 		size = sge_flq1_cnt * fl_sz_multiplier;
1134 	else
1135 		size = sge_flq0_cnt * fl_sz_multiplier;
1136 
1137 	mutex_init(&sa->ch_small_esbl, NULL, MUTEX_DRIVER, sa->ch_icookp);
1138 
1139 	mutex_enter(&in_use_l);
1140 	j = in_use_index++;
1141 	if (in_use_index >= SZ_INUSE)
1142 		in_use_index = 0;
1143 	mutex_exit(&in_use_l);
1144 
1145 	sa->ch_small_owner = NULL;
1146 	sa->ch_sm_index = j;
1147 	sa->ch_small_esb_free = NULL;
1148 	for (i = 0; i < size; i++) {
1149 		rbp = ch_alloc_small_esbbuf(sa, j);
1150 		if (rbp == NULL)
1151 			goto error;
1152 		/*
1153 		 * add entry to free list
1154 		 */
1155 		rbp->cs_next = sa->ch_small_esb_free;
1156 		sa->ch_small_esb_free = rbp;
1157 
1158 		/*
1159 		 * add entry to owned list
1160 		 */
1161 		rbp->cs_owner = sa->ch_small_owner;
1162 		sa->ch_small_owner = rbp;
1163 	}
1164 	return (1);
1165 
1166 error:
1167 	sa->ch_small_owner = NULL;
1168 
1169 	/* free whatever we've already allocated */
1170 	pe_rbuf_pool_free(sa);
1171 
1172 	return (0);
1173 }
1174 
1175 /*
1176  * allocate pool of receive buffers (with vaddr & paddr) and
1177  * receiver buffer control structure (ch_esb_t *rbp).
1178  * XXX we should allow better tuning of the # of preallocated
1179  * free buffers against the # of freelist entries.
1180  */
1181 static int
1182 pe_big_rbuf_pool_init(ch_t *sa)
1183 {
1184 	int i;
1185 	ch_esb_t *rbp;
1186 	extern uint32_t sge_flq0_cnt;
1187 	extern uint32_t sge_flq1_cnt;
1188 	int size;
1189 	uint32_t j;
1190 
1191 	if (is_T2(sa))
1192 		size = sge_flq0_cnt * fl_sz_multiplier;
1193 	else
1194 		size = sge_flq1_cnt * fl_sz_multiplier;
1195 
1196 	mutex_init(&sa->ch_big_esbl, NULL, MUTEX_DRIVER, sa->ch_icookp);
1197 
1198 	mutex_enter(&in_use_l);
1199 	j = in_use_index++;
1200 	if (in_use_index >= SZ_INUSE)
1201 		in_use_index = 0;
1202 	mutex_exit(&in_use_l);
1203 
1204 	sa->ch_big_owner = NULL;
1205 	sa->ch_big_index = j;
1206 	sa->ch_big_esb_free = NULL;
1207 	for (i = 0; i < size; i++) {
1208 		rbp = ch_alloc_big_esbbuf(sa, j);
1209 		if (rbp == NULL)
1210 			goto error;
1211 		rbp->cs_next = sa->ch_big_esb_free;
1212 		sa->ch_big_esb_free = rbp;
1213 
1214 		/*
1215 		 * add entry to owned list
1216 		 */
1217 		rbp->cs_owner = sa->ch_big_owner;
1218 		sa->ch_big_owner = rbp;
1219 	}
1220 	return (1);
1221 
1222 error:
1223 	sa->ch_big_owner = NULL;
1224 
1225 	/* free whatever we've already allocated */
1226 	pe_rbuf_pool_free(sa);
1227 
1228 	return (0);
1229 }
1230 
1231 /*
1232  * allocate receive buffer structure and dma mapped buffer (SGE_SM_BUF_SZ bytes)
1233  * note that we will DMA at a 2 byte offset for Solaris when checksum offload
1234  * is enabled.
1235  */
1236 static ch_esb_t *
1237 ch_alloc_small_esbbuf(ch_t *sa, uint32_t i)
1238 {
1239 	ch_esb_t *rbp;
1240 
1241 	rbp = (ch_esb_t *)kmem_zalloc(sizeof (ch_esb_t), KM_SLEEP);
1242 	if (rbp == NULL) {
1243 		return ((ch_esb_t *)0);
1244 	}
1245 
1246 #if BYTE_ORDER == BIG_ENDIAN
1247 	rbp->cs_buf = (caddr_t)ch_alloc_dma_mem(sa, 1, DMA_STREAM|DMA_SMALN,
1248 	    SGE_SM_BUF_SZ(sa), &rbp->cs_pa, &rbp->cs_dh, &rbp->cs_ah);
1249 #else
1250 	rbp->cs_buf = (caddr_t)ch_alloc_dma_mem(sa, 0, DMA_STREAM|DMA_SMALN,
1251 	    SGE_SM_BUF_SZ(sa), &rbp->cs_pa, &rbp->cs_dh, &rbp->cs_ah);
1252 #endif
1253 
1254 	if (rbp->cs_buf == NULL) {
1255 		kmem_free(rbp, sizeof (ch_esb_t));
1256 		return ((ch_esb_t *)0);
1257 	}
1258 
1259 	rbp->cs_sa = sa;
1260 	rbp->cs_index = i;
1261 
1262 	rbp->cs_frtn.free_func = (void (*)())&ch_small_rbuf_recycle;
1263 	rbp->cs_frtn.free_arg  = (caddr_t)rbp;
1264 
1265 	return (rbp);
1266 }
1267 
1268 /*
1269  * allocate receive buffer structure and dma mapped buffer (SGE_BG_BUF_SZ bytes)
1270  * note that we will DMA at a 2 byte offset for Solaris when checksum offload
1271  * is enabled.
1272  */
1273 static ch_esb_t *
1274 ch_alloc_big_esbbuf(ch_t *sa, uint32_t i)
1275 {
1276 	ch_esb_t *rbp;
1277 
1278 	rbp = (ch_esb_t *)kmem_zalloc(sizeof (ch_esb_t), KM_SLEEP);
1279 	if (rbp == NULL) {
1280 		return ((ch_esb_t *)0);
1281 	}
1282 
1283 #if BYTE_ORDER == BIG_ENDIAN
1284 	rbp->cs_buf = (caddr_t)ch_alloc_dma_mem(sa, 1, DMA_STREAM|DMA_BGALN,
1285 	    SGE_BG_BUF_SZ(sa), &rbp->cs_pa, &rbp->cs_dh, &rbp->cs_ah);
1286 #else
1287 	rbp->cs_buf = (caddr_t)ch_alloc_dma_mem(sa, 0, DMA_STREAM|DMA_BGALN,
1288 	    SGE_BG_BUF_SZ(sa), &rbp->cs_pa, &rbp->cs_dh, &rbp->cs_ah);
1289 #endif
1290 
1291 	if (rbp->cs_buf == NULL) {
1292 		kmem_free(rbp, sizeof (ch_esb_t));
1293 		return ((ch_esb_t *)0);
1294 	}
1295 
1296 	rbp->cs_sa = sa;
1297 	rbp->cs_index = i;
1298 
1299 	rbp->cs_frtn.free_func = (void (*)())&ch_big_rbuf_recycle;
1300 	rbp->cs_frtn.free_arg  = (caddr_t)rbp;
1301 
1302 	return (rbp);
1303 }
1304 
1305 /*
1306  * free entries on the receive buffer list.
1307  */
1308 void
1309 pe_rbuf_pool_free(ch_t *sa)
1310 {
1311 	ch_esb_t *rbp;
1312 
1313 	mutex_enter(&sa->ch_small_esbl);
1314 
1315 	/*
1316 	 * Now set-up the rest to commit suicide.
1317 	 */
1318 	while (sa->ch_small_owner) {
1319 		rbp = sa->ch_small_owner;
1320 		sa->ch_small_owner = rbp->cs_owner;
1321 		rbp->cs_owner = NULL;
1322 		rbp->cs_flag = 1;
1323 	}
1324 
1325 	while ((rbp = sa->ch_small_esb_free) != NULL) {
1326 		/* advance head ptr to next entry */
1327 		sa->ch_small_esb_free = rbp->cs_next;
1328 		/* free private buffer allocated in ch_alloc_esbbuf() */
1329 		ch_free_dma_mem(rbp->cs_dh, rbp->cs_ah);
1330 		/* free descripter buffer */
1331 		kmem_free(rbp, sizeof (ch_esb_t));
1332 	}
1333 
1334 	mutex_exit(&sa->ch_small_esbl);
1335 
1336 	/* destroy ch_esbl lock */
1337 	mutex_destroy(&sa->ch_small_esbl);
1338 
1339 
1340 	mutex_enter(&sa->ch_big_esbl);
1341 
1342 	/*
1343 	 * Now set-up the rest to commit suicide.
1344 	 */
1345 	while (sa->ch_big_owner) {
1346 		rbp = sa->ch_big_owner;
1347 		sa->ch_big_owner = rbp->cs_owner;
1348 		rbp->cs_owner = NULL;
1349 		rbp->cs_flag = 1;
1350 	}
1351 
1352 	while ((rbp = sa->ch_big_esb_free) != NULL) {
1353 		/* advance head ptr to next entry */
1354 		sa->ch_big_esb_free = rbp->cs_next;
1355 		/* free private buffer allocated in ch_alloc_esbbuf() */
1356 		ch_free_dma_mem(rbp->cs_dh, rbp->cs_ah);
1357 		/* free descripter buffer */
1358 		kmem_free(rbp, sizeof (ch_esb_t));
1359 	}
1360 
1361 	mutex_exit(&sa->ch_big_esbl);
1362 
1363 	/* destroy ch_esbl lock */
1364 	mutex_destroy(&sa->ch_big_esbl);
1365 }
1366 
1367 void
1368 ch_small_rbuf_recycle(ch_esb_t *rbp)
1369 {
1370 	ch_t *sa = rbp->cs_sa;
1371 
1372 	if (rbp->cs_flag) {
1373 		uint32_t i;
1374 		/*
1375 		 * free private buffer allocated in ch_alloc_esbbuf()
1376 		 */
1377 		ch_free_dma_mem(rbp->cs_dh, rbp->cs_ah);
1378 
1379 		i = rbp->cs_index;
1380 
1381 		/*
1382 		 * free descripter buffer
1383 		 */
1384 		kmem_free(rbp, sizeof (ch_esb_t));
1385 
1386 		/*
1387 		 * decrement count of receive buffers freed by callback
1388 		 * We decrement here so anyone trying to do fini will
1389 		 * only remove the driver once the counts go to 0.
1390 		 */
1391 		atomic_dec_32(&buffers_in_use[i]);
1392 
1393 		return;
1394 	}
1395 
1396 	mutex_enter(&sa->ch_small_esbl);
1397 	rbp->cs_next = sa->ch_small_esb_free;
1398 	sa->ch_small_esb_free = rbp;
1399 	mutex_exit(&sa->ch_small_esbl);
1400 
1401 	/*
1402 	 * decrement count of receive buffers freed by callback
1403 	 */
1404 	atomic_dec_32(&buffers_in_use[rbp->cs_index]);
1405 }
1406 
1407 /*
1408  * callback function from freeb() when esballoced mblk freed.
1409  */
1410 void
1411 ch_big_rbuf_recycle(ch_esb_t *rbp)
1412 {
1413 	ch_t *sa = rbp->cs_sa;
1414 
1415 	if (rbp->cs_flag) {
1416 		uint32_t i;
1417 		/*
1418 		 * free private buffer allocated in ch_alloc_esbbuf()
1419 		 */
1420 		ch_free_dma_mem(rbp->cs_dh, rbp->cs_ah);
1421 
1422 		i = rbp->cs_index;
1423 
1424 		/*
1425 		 * free descripter buffer
1426 		 */
1427 		kmem_free(rbp, sizeof (ch_esb_t));
1428 
1429 		/*
1430 		 * decrement count of receive buffers freed by callback
1431 		 * We decrement here so anyone trying to do fini will
1432 		 * only remove the driver once the counts go to 0.
1433 		 */
1434 		atomic_dec_32(&buffers_in_use[i]);
1435 
1436 		return;
1437 	}
1438 
1439 	mutex_enter(&sa->ch_big_esbl);
1440 	rbp->cs_next = sa->ch_big_esb_free;
1441 	sa->ch_big_esb_free = rbp;
1442 	mutex_exit(&sa->ch_big_esbl);
1443 
1444 	/*
1445 	 * decrement count of receive buffers freed by callback
1446 	 */
1447 	atomic_dec_32(&buffers_in_use[rbp->cs_index]);
1448 }
1449 
1450 /*
1451  * get a pre-allocated, pre-mapped receive buffer from free list.
1452  * (used sge.c)
1453  */
1454 ch_esb_t *
1455 ch_get_small_rbuf(ch_t *sa)
1456 {
1457 	ch_esb_t *rbp;
1458 
1459 	mutex_enter(&sa->ch_small_esbl);
1460 	rbp = sa->ch_small_esb_free;
1461 	if (rbp) {
1462 		sa->ch_small_esb_free = rbp->cs_next;
1463 	}
1464 	mutex_exit(&sa->ch_small_esbl);
1465 
1466 	return (rbp);
1467 }
1468 
1469 /*
1470  * get a pre-allocated, pre-mapped receive buffer from free list.
1471  * (used sge.c)
1472  */
1473 
1474 ch_esb_t *
1475 ch_get_big_rbuf(ch_t *sa)
1476 {
1477 	ch_esb_t *rbp;
1478 
1479 	mutex_enter(&sa->ch_big_esbl);
1480 	rbp = sa->ch_big_esb_free;
1481 	if (rbp) {
1482 		sa->ch_big_esb_free = rbp->cs_next;
1483 	}
1484 	mutex_exit(&sa->ch_big_esbl);
1485 
1486 	return (rbp);
1487 }
1488 
1489 void
1490 pe_detach(ch_t *sa)
1491 {
1492 	(void) sge_stop(sa->sge);
1493 
1494 	pe_free_driver_resources(sa);
1495 }
1496 
1497 static void
1498 pe_free_driver_resources(ch_t *sa)
1499 {
1500 	if (sa) {
1501 		t1_free_sw_modules(sa);
1502 
1503 		/* free pool of receive buffers */
1504 		pe_rbuf_pool_free(sa);
1505 	}
1506 }
1507 
1508 /*
1509  * Processes elmer0 external interrupts in process context.
1510  */
1511 static void
1512 ext_intr_task(ch_t *adapter)
1513 {
1514 	u32 enable;
1515 
1516 	(void) elmer0_ext_intr_handler(adapter);
1517 
1518 	/* Now reenable external interrupts */
1519 	t1_write_reg_4(adapter, A_PL_CAUSE, F_PL_INTR_EXT);
1520 	enable = t1_read_reg_4(adapter, A_PL_ENABLE);
1521 	t1_write_reg_4(adapter, A_PL_ENABLE, enable | F_PL_INTR_EXT);
1522 	adapter->slow_intr_mask |= F_PL_INTR_EXT;
1523 }
1524 
1525 /*
1526  * Interrupt-context handler for elmer0 external interrupts.
1527  */
1528 void
1529 t1_os_elmer0_ext_intr(ch_t *adapter)
1530 {
1531 	u32 enable = t1_read_reg_4(adapter, A_PL_ENABLE);
1532 
1533 	adapter->slow_intr_mask &= ~F_PL_INTR_EXT;
1534 	t1_write_reg_4(adapter, A_PL_ENABLE, enable & ~F_PL_INTR_EXT);
1535 #ifdef NOTYET
1536 	schedule_work(&adapter->ext_intr_handler_task);
1537 #else
1538 	ext_intr_task(adapter);
1539 #endif
1540 }
1541 
1542 uint8_t *
1543 t1_get_next_mcaddr(struct t1_rx_mode *rmp)
1544 {
1545 	uint8_t *addr = 0;
1546 	if (rmp->mc) {
1547 		addr = rmp->mc->cmc_mca;
1548 		rmp->mc = rmp->mc->cmc_next;
1549 	}
1550 	return (addr);
1551 }
1552 
1553 void
1554 pe_dma_handle_init(ch_t *chp, int cnt)
1555 {
1556 	free_dh_t *dhe;
1557 #if defined(__sparc)
1558 	int tcnt = cnt/2;
1559 
1560 	for (; cnt; cnt--) {
1561 		dhe = ch_get_dvma_handle(chp);
1562 		if (dhe == NULL)
1563 			break;
1564 		mutex_enter(&chp->ch_dh_lck);
1565 		dhe->dhe_next = chp->ch_vdh;
1566 		chp->ch_vdh = dhe;
1567 		mutex_exit(&chp->ch_dh_lck);
1568 	}
1569 
1570 	cnt += tcnt;
1571 #endif
1572 	while (cnt--) {
1573 		dhe = ch_get_dma_handle(chp);
1574 		if (dhe == NULL)
1575 			return;
1576 		mutex_enter(&chp->ch_dh_lck);
1577 		dhe->dhe_next = chp->ch_dh;
1578 		chp->ch_dh = dhe;
1579 		mutex_exit(&chp->ch_dh_lck);
1580 	}
1581 }
1582 
1583 /*
1584  * Write new values to the MTU table.  Caller must validate that the new MTUs
1585  * are in ascending order. params.mtus[] is initialized by init_mtus()
1586  * called in t1_init_sw_modules().
1587  */
1588 #define	MTUREG(idx) (A_TP_MTU_REG0 + (idx) * 4)
1589 
1590 static void
1591 update_mtu_tab(ch_t *adapter)
1592 {
1593 	int i;
1594 
1595 	for (i = 0; i < NMTUS; ++i) {
1596 		int mtu = (unsigned int)adapter->params.mtus[i];
1597 
1598 		t1_write_reg_4(adapter, MTUREG(i), mtu);
1599 	}
1600 }
1601 
1602 static int
1603 pe_change_mtu(ch_t *chp)
1604 {
1605 	struct cmac *mac = chp->port[0].mac;
1606 	int ret;
1607 
1608 	if (!mac->ops->set_mtu) {
1609 		return (EOPNOTSUPP);
1610 	}
1611 	if (chp->ch_mtu < 68) {
1612 		return (EINVAL);
1613 	}
1614 	if (ret = mac->ops->set_mtu(mac, chp->ch_mtu)) {
1615 		return (ret);
1616 	}
1617 
1618 	return (0);
1619 }
1620 
1621 typedef struct fake_arp {
1622 	char fa_dst[6];		/* ethernet header */
1623 	char fa_src[6];		/* ethernet header */
1624 	ushort_t fa_typ;		/* ethernet header */
1625 
1626 	ushort_t fa_hrd;		/* arp */
1627 	ushort_t fa_pro;
1628 	char fa_hln;
1629 	char fa_pln;
1630 	ushort_t fa_op;
1631 	char fa_src_mac[6];
1632 	uint_t fa_src_ip;
1633 	char fa_dst_mac[6];
1634 	char fa_dst_ip[4];
1635 } fake_arp_t;
1636 
1637 /*
1638  * PR2928 & PR3309
1639  * construct packet in mblk and attach it to sge structure.
1640  */
1641 static int
1642 pe_make_fake_arp(ch_t *chp, unsigned char *arpp)
1643 {
1644 	pesge *sge = chp->sge;
1645 	mblk_t *bp;
1646 	fake_arp_t *fap;
1647 	static char buf[6] = {0, 7, 0x43, 0, 0, 0};
1648 	struct cpl_tx_pkt *cpl;
1649 
1650 	bp = allocb(sizeof (struct fake_arp) + SZ_CPL_TX_PKT, BPRI_HI);
1651 	if (bp == NULL) {
1652 		return (1);
1653 	}
1654 	bzero(bp->b_rptr, sizeof (struct fake_arp) + SZ_CPL_TX_PKT);
1655 
1656 	/* fill in cpl header */
1657 	cpl = (struct cpl_tx_pkt *)bp->b_rptr;
1658 	cpl->opcode = CPL_TX_PKT;
1659 	cpl->iff = 0;			/* XXX port 0 needs fixing with NEMO */
1660 	cpl->ip_csum_dis = 1;		/* no IP header cksum */
1661 	cpl->l4_csum_dis = 1;		/* no tcp/udp cksum */
1662 	cpl->vlan_valid = 0;		/* no vlan */
1663 
1664 	fap = (fake_arp_t *)&bp->b_rptr[SZ_CPL_TX_PKT];
1665 
1666 	bcopy(arpp, fap, sizeof (*fap));	/* copy first arp to mblk */
1667 
1668 	bcopy(buf, fap->fa_dst, 6);		/* overwrite dst mac */
1669 	chp->ch_ip = fap->fa_src_ip;		/* not used yet */
1670 	bcopy(buf, fap->fa_dst_mac, 6);		/* overwrite dst mac */
1671 
1672 	bp->b_wptr = bp->b_rptr + sizeof (struct fake_arp)+SZ_CPL_TX_PKT;
1673 
1674 	sge_add_fake_arp(sge, (void *)bp);
1675 
1676 	return (0);
1677 }
1678 
1679 /*
1680  * PR2928 & PR3309
1681  * free the fake arp's mblk on sge structure.
1682  */
1683 void
1684 pe_free_fake_arp(void *arp)
1685 {
1686 	mblk_t *bp = (mblk_t *)(arp);
1687 
1688 	freemsg(bp);
1689 }
1690 
1691 /*
1692  * extract ip address of nic from first outgoing arp.
1693  */
1694 static uint32_t
1695 pe_get_ip(unsigned char *arpp)
1696 {
1697 	fake_arp_t fap;
1698 
1699 	/*
1700 	 * first copy packet to buffer so we know
1701 	 * it will be properly aligned.
1702 	 */
1703 	bcopy(arpp, &fap, sizeof (fap));	/* copy first arp to buffer */
1704 	return (fap.fa_src_ip);
1705 }
1706 
1707 /* ARGSUSED */
1708 void
1709 t1_os_link_changed(ch_t *obj, int port_id, int link_status,
1710     int speed, int duplex, int fc)
1711 {
1712 	gld_mac_info_t *macinfo = obj->ch_macp;
1713 	if (link_status) {
1714 		gld_linkstate(macinfo, GLD_LINKSTATE_UP);
1715 		/*
1716 		 * Link states should be reported to user
1717 		 * whenever it changes
1718 		 */
1719 		cmn_err(CE_NOTE, "%s: link is up", adapter_name(obj));
1720 	} else {
1721 		gld_linkstate(macinfo, GLD_LINKSTATE_DOWN);
1722 		/*
1723 		 * Link states should be reported to user
1724 		 * whenever it changes
1725 		 */
1726 		cmn_err(CE_NOTE, "%s: link is down", adapter_name(obj));
1727 	}
1728 }
1729