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
pe_intr(ch_t * sa)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
pe_init(void * xsa)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
link_start(ch_t * sa,struct pe_port_t * p)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
pe_stop(ch_t * sa)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
pe_start(ch_t * sa,mblk_t * mp,uint32_t flg)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
pe_set_mac(ch_t * sa,unsigned char * ac_enaddr)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 *
pe_get_mac(ch_t * sa)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
pe_set_promiscuous(ch_t * sa,int flag)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
pe_set_mc(ch_t * sa,uint8_t * ep,int flg)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
pe_get_stats(ch_t * sa,uint64_t * speed,uint32_t * intrcnt,uint32_t * norcvbuf,uint32_t * oerrors,uint32_t * ierrors,uint32_t * underrun,uint32_t * overrun,uint32_t * framing,uint32_t * crc,uint32_t * carrier,uint32_t * collisions,uint32_t * xcollisions,uint32_t * late,uint32_t * defer,uint32_t * xerrs,uint32_t * rerrs,uint32_t * toolong,uint32_t * runt,ulong_t * multixmt,ulong_t * multircv,ulong_t * brdcstxmt,ulong_t * brdcstrcv)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
pe_attach(ch_t * chp)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
ch_set_config_data(ch_t * chp)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 *
pe_sa_init(ch_t * sa)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
pe_small_rbuf_pool_init(ch_t * sa)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
pe_big_rbuf_pool_init(ch_t * sa)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 *
ch_alloc_small_esbbuf(ch_t * sa,uint32_t i)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 *
ch_alloc_big_esbbuf(ch_t * sa,uint32_t i)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
pe_rbuf_pool_free(ch_t * sa)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
ch_small_rbuf_recycle(ch_esb_t * rbp)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
ch_big_rbuf_recycle(ch_esb_t * rbp)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 *
ch_get_small_rbuf(ch_t * sa)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 *
ch_get_big_rbuf(ch_t * sa)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
pe_detach(ch_t * sa)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
pe_free_driver_resources(ch_t * sa)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
ext_intr_task(ch_t * adapter)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
t1_os_elmer0_ext_intr(ch_t * adapter)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 *
t1_get_next_mcaddr(struct t1_rx_mode * rmp)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
pe_dma_handle_init(ch_t * chp,int cnt)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
update_mtu_tab(ch_t * adapter)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
pe_change_mtu(ch_t * chp)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
pe_make_fake_arp(ch_t * chp,unsigned char * arpp)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
pe_free_fake_arp(void * arp)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
pe_get_ip(unsigned char * arpp)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
t1_os_link_changed(ch_t * obj,int port_id,int link_status,int speed,int duplex,int fc)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