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.
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.
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]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/types.h>
28 #include <sys/stream.h>
29 #include <sys/strsun.h>
31 #include <sys/modctl.h>
32 #include <sys/ethernet.h>
33 #include <sys/debug.h>
36 #include <sys/miiregs.h>
37 #include <sys/sysmacros.h>
38 #include <sys/dditypes.h>
40 #include <sys/sunddi.h>
41 #include <sys/byteorder.h>
44 #include <sys/stream.h>
47 #include "atge_l1_reg.h"
48 #include "atge_cmn_reg.h"
50 static ddi_dma_attr_t atge_l1_dma_attr_tx_desc
= {
51 DMA_ATTR_V0
, /* dma_attr_version */
52 0, /* dma_attr_addr_lo */
53 0x0000ffffffffull
, /* dma_attr_addr_hi */
54 0x0000ffffffffull
, /* dma_attr_count_max */
55 L1_TX_RING_ALIGN
, /* dma_attr_align */
56 0x0000fffc, /* dma_attr_burstsizes */
57 1, /* dma_attr_minxfer */
58 0x0000ffffffffull
, /* dma_attr_maxxfer */
59 0x0000ffffffffull
, /* dma_attr_seg */
60 1, /* dma_attr_sgllen */
61 1, /* dma_attr_granular */
62 0 /* dma_attr_flags */
65 static ddi_dma_attr_t atge_l1_dma_attr_rx_desc
= {
66 DMA_ATTR_V0
, /* dma_attr_version */
67 0, /* dma_attr_addr_lo */
68 0x0000ffffffffull
, /* dma_attr_addr_hi */
69 0x0000ffffffffull
, /* dma_attr_count_max */
70 L1_RX_RING_ALIGN
, /* dma_attr_align */
71 0x0000fffc, /* dma_attr_burstsizes */
72 1, /* dma_attr_minxfer */
73 0x0000ffffffffull
, /* dma_attr_maxxfer */
74 0x0000ffffffffull
, /* dma_attr_seg */
75 1, /* dma_attr_sgllen */
76 1, /* dma_attr_granular */
77 0 /* dma_attr_flags */
80 static ddi_dma_attr_t atge_l1_dma_attr_cmb
= {
81 DMA_ATTR_V0
, /* dma_attr_version */
82 0, /* dma_attr_addr_lo */
83 0x0000ffffffffull
, /* dma_attr_addr_hi */
84 0x0000ffffffffull
, /* dma_attr_count_max */
85 L1_CMB_ALIGN
, /* dma_attr_align */
86 0x0000fffc, /* dma_attr_burstsizes */
87 1, /* dma_attr_minxfer */
88 0x0000ffffffffull
, /* dma_attr_maxxfer */
89 0x0000ffffffffull
, /* dma_attr_seg */
90 1, /* dma_attr_sgllen */
91 1, /* dma_attr_granular */
92 0 /* dma_attr_flags */
95 static ddi_dma_attr_t atge_l1_dma_attr_smb
= {
96 DMA_ATTR_V0
, /* dma_attr_version */
97 0, /* dma_attr_addr_lo */
98 0x0000ffffffffull
, /* dma_attr_addr_hi */
99 0x0000ffffffffull
, /* dma_attr_count_max */
100 L1_SMB_ALIGN
, /* dma_attr_align */
101 0x0000fffc, /* dma_attr_burstsizes */
102 1, /* dma_attr_minxfer */
103 0x0000ffffffffull
, /* dma_attr_maxxfer */
104 0x0000ffffffffull
, /* dma_attr_seg */
105 1, /* dma_attr_sgllen */
106 1, /* dma_attr_granular */
107 0 /* dma_attr_flags */
110 static ddi_dma_attr_t atge_l1_dma_attr_rr
= {
111 DMA_ATTR_V0
, /* dma_attr_version */
112 0, /* dma_attr_addr_lo */
113 0x0000ffffffffull
, /* dma_attr_addr_hi */
114 0x0000ffffffffull
, /* dma_attr_count_max */
115 L1_RR_RING_ALIGN
, /* dma_attr_align */
116 0x0000fffc, /* dma_attr_burstsizes */
117 1, /* dma_attr_minxfer */
118 0x0000ffffffffull
, /* dma_attr_maxxfer */
119 0x0000ffffffffull
, /* dma_attr_seg */
120 1, /* dma_attr_sgllen */
121 1, /* dma_attr_granular */
122 0 /* dma_attr_flags */
126 atge_l1_alloc_dma(atge_t
*atgep
)
132 l1
= kmem_zalloc(sizeof (atge_l1_data_t
), KM_SLEEP
);
133 atgep
->atge_private_data
= l1
;
136 * Allocate TX ring descriptor.
138 atgep
->atge_tx_buf_len
= atgep
->atge_mtu
+
139 sizeof (struct ether_header
) + VLAN_TAGSZ
+ ETHERFCSL
;
140 atgep
->atge_tx_ring
= kmem_alloc(sizeof (atge_ring_t
), KM_SLEEP
);
141 atgep
->atge_tx_ring
->r_atge
= atgep
;
142 atgep
->atge_tx_ring
->r_desc_ring
= NULL
;
143 dma
= atge_alloc_a_dma_blk(atgep
, &atge_l1_dma_attr_tx_desc
,
144 ATGE_TX_RING_SZ
, DDI_DMA_RDWR
);
146 atge_error(atgep
->atge_dip
, "DMA allocation failed for TX"
148 return (DDI_FAILURE
);
150 atgep
->atge_tx_ring
->r_desc_ring
= dma
;
153 * Allocate DMA buffers for TX ring.
155 err
= atge_alloc_buffers(atgep
->atge_tx_ring
, ATGE_TX_RING_CNT
,
156 atgep
->atge_tx_buf_len
, DDI_DMA_WRITE
);
157 if (err
!= DDI_SUCCESS
) {
158 atge_error(atgep
->atge_dip
, "DMA allocation failed for"
166 atgep
->atge_rx_buf_len
= atgep
->atge_mtu
+
167 sizeof (struct ether_header
) + VLAN_TAGSZ
+ ETHERFCSL
;
168 l1
->atge_rx_ring
= kmem_alloc(sizeof (atge_ring_t
), KM_SLEEP
);
169 l1
->atge_rx_ring
->r_atge
= atgep
;
170 l1
->atge_rx_ring
->r_desc_ring
= NULL
;
171 dma
= atge_alloc_a_dma_blk(atgep
, &atge_l1_dma_attr_rx_desc
,
172 L1_RX_RING_SZ
, DDI_DMA_RDWR
);
174 atge_error(atgep
->atge_dip
, "DMA allocation failed"
176 return (DDI_FAILURE
);
178 l1
->atge_rx_ring
->r_desc_ring
= dma
;
181 * Allocate DMA buffers for RX ring.
183 err
= atge_alloc_buffers(l1
->atge_rx_ring
, L1_RX_RING_CNT
,
184 atgep
->atge_rx_buf_len
, DDI_DMA_WRITE
);
185 if (err
!= DDI_SUCCESS
) {
186 atge_error(atgep
->atge_dip
, "DMA allocation failed for"
192 * Allocate CMB used for fetching interrupt status data.
194 ATGE_DB(("%s: %s() L1_CMB_BLOCK_SZ : %x", atgep
->atge_name
,
195 __func__
, L1_CMB_BLOCK_SZ
));
197 dma
= atge_alloc_a_dma_blk(atgep
, &atge_l1_dma_attr_cmb
,
198 L1_CMB_BLOCK_SZ
, DDI_DMA_RDWR
);
199 l1
->atge_l1_cmb
= dma
;
201 atge_error(atgep
->atge_dip
, "DMA allocation failed for CMB");
202 return (DDI_FAILURE
);
206 * RR ring (Return Ring for RX and TX).
208 ATGE_DB(("%s: %s() L1_RR_RING_SZ : %x", atgep
->atge_name
,
209 __func__
, L1_RR_RING_SZ
));
211 dma
= atge_alloc_a_dma_blk(atgep
, &atge_l1_dma_attr_rr
,
212 L1_RR_RING_SZ
, DDI_DMA_RDWR
);
213 l1
->atge_l1_rr
= dma
;
215 atge_error(atgep
->atge_dip
, "DMA allocation failed"
217 return (DDI_FAILURE
);
221 * SMB for statistics.
223 ATGE_DB(("%s: %s() L1_SMB_BLOCK_SZ : %x", atgep
->atge_name
,
224 __func__
, L1_SMB_BLOCK_SZ
));
226 dma
= atge_alloc_a_dma_blk(atgep
, &atge_l1_dma_attr_smb
,
227 L1_SMB_BLOCK_SZ
, DDI_DMA_RDWR
);
228 l1
->atge_l1_smb
= dma
;
230 atge_error(atgep
->atge_dip
, "DMA allocation failed for SMB");
231 return (DDI_FAILURE
);
234 atgep
->atge_hw_stats
= kmem_zalloc(sizeof (atge_l1_smb_t
), KM_SLEEP
);
236 return (DDI_SUCCESS
);
240 atge_l1_free_dma(atge_t
*atgep
)
244 l1
= atgep
->atge_private_data
;
249 if (atgep
->atge_tx_ring
!= NULL
) {
250 atge_free_buffers(atgep
->atge_tx_ring
, ATGE_TX_RING_CNT
);
252 if (atgep
->atge_tx_ring
->r_desc_ring
!= NULL
) {
253 atge_free_a_dma_blk(atgep
->atge_tx_ring
->r_desc_ring
);
256 kmem_free(atgep
->atge_tx_ring
, sizeof (atge_ring_t
));
257 atgep
->atge_tx_ring
= NULL
;
260 if (l1
&& l1
->atge_l1_cmb
!= NULL
) {
261 atge_free_a_dma_blk(l1
->atge_l1_cmb
);
262 l1
->atge_l1_cmb
= NULL
;
265 if (l1
&& l1
->atge_l1_rr
!= NULL
) {
266 atge_free_a_dma_blk(l1
->atge_l1_rr
);
267 l1
->atge_l1_rr
= NULL
;
270 if (l1
&& l1
->atge_l1_smb
!= NULL
) {
271 atge_free_a_dma_blk(l1
->atge_l1_smb
);
272 l1
->atge_l1_smb
= NULL
;
278 if (l1
&& l1
->atge_rx_ring
!= NULL
) {
279 atge_free_buffers(l1
->atge_rx_ring
, L1_RX_RING_CNT
);
281 if (l1
->atge_rx_ring
->r_desc_ring
!= NULL
) {
282 atge_free_a_dma_blk(l1
->atge_rx_ring
->r_desc_ring
);
285 kmem_free(l1
->atge_rx_ring
, sizeof (atge_ring_t
));
286 l1
->atge_rx_ring
= NULL
;
290 * Free the memory allocated for gathering hw stats.
292 if (atgep
->atge_hw_stats
!= NULL
) {
293 kmem_free(atgep
->atge_hw_stats
, sizeof (atge_l1_smb_t
));
294 atgep
->atge_hw_stats
= NULL
;
299 atge_l1_init_rx_ring(atge_t
*atgep
)
306 l1
= atgep
->atge_private_data
;
307 l1
->atge_rx_ring
->r_consumer
= L1_RX_RING_CNT
- 1;
308 dma
= l1
->atge_rx_ring
->r_desc_ring
;
309 bzero(dma
->addr
, L1_RX_RING_SZ
);
311 for (i
= 0; i
< L1_RX_RING_CNT
; i
++) {
312 rx
= (l1_rx_desc_t
*)(dma
->addr
+ (i
* sizeof (l1_rx_desc_t
)));
314 ATGE_PUT64(dma
, &rx
->addr
,
315 l1
->atge_rx_ring
->r_buf_tbl
[i
]->cookie
.dmac_laddress
);
316 ATGE_PUT32(dma
, &rx
->len
,
317 (l1
->atge_rx_ring
->r_buf_tbl
[i
]->len
& L1_RD_LEN_MASK
) <<
321 DMA_SYNC(dma
, 0, L1_RX_RING_SZ
, DDI_DMA_SYNC_FORDEV
);
325 atge_l1_init_tx_ring(atge_t
*atgep
)
327 atgep
->atge_tx_ring
->r_producer
= 0;
328 atgep
->atge_tx_ring
->r_consumer
= 0;
329 atgep
->atge_tx_ring
->r_avail_desc
= ATGE_TX_RING_CNT
;
331 bzero(atgep
->atge_tx_ring
->r_desc_ring
->addr
, ATGE_TX_RING_SZ
);
332 DMA_SYNC(atgep
->atge_tx_ring
->r_desc_ring
, 0, ATGE_TX_RING_SZ
,
333 DDI_DMA_SYNC_FORDEV
);
337 atge_l1_init_rr_ring(atge_t
*atgep
)
342 l1
= atgep
->atge_private_data
;
343 l1
->atge_l1_rr_consumers
= 0;
345 dma
= l1
->atge_l1_rr
;
346 bzero(dma
->addr
, L1_RR_RING_SZ
);
347 DMA_SYNC(dma
, 0, L1_RR_RING_SZ
, DDI_DMA_SYNC_FORDEV
);
351 atge_l1_init_smb(atge_t
*atgep
)
356 l1
= atgep
->atge_private_data
;
357 dma
= l1
->atge_l1_smb
;
358 bzero(dma
->addr
, L1_SMB_BLOCK_SZ
);
359 DMA_SYNC(dma
, 0, L1_SMB_BLOCK_SZ
, DDI_DMA_SYNC_FORDEV
);
363 atge_l1_init_cmb(atge_t
*atgep
)
368 l1
= atgep
->atge_private_data
;
369 dma
= l1
->atge_l1_cmb
;
370 bzero(dma
->addr
, L1_CMB_BLOCK_SZ
);
371 DMA_SYNC(dma
, 0, L1_CMB_BLOCK_SZ
, DDI_DMA_SYNC_FORDEV
);
375 atge_l1_sync_mbox(atge_t
*atgep
)
379 l1
= atgep
->atge_private_data
;
381 mutex_enter(&atgep
->atge_mbox_lock
);
382 OUTL(atgep
, ATGE_MBOX
,
383 ((l1
->atge_rx_ring
->r_consumer
<< MBOX_RD_PROD_IDX_SHIFT
) &
384 MBOX_RD_PROD_IDX_MASK
) |
385 ((l1
->atge_l1_rr_consumers
<<
386 MBOX_RRD_CONS_IDX_SHIFT
) & MBOX_RRD_CONS_IDX_MASK
) |
387 ((atgep
->atge_tx_ring
->r_producer
<< MBOX_TD_PROD_IDX_SHIFT
) &
388 MBOX_TD_PROD_IDX_MASK
));
389 mutex_exit(&atgep
->atge_mbox_lock
);
393 atge_l1_program_dma(atge_t
*atgep
)
398 l1
= atgep
->atge_private_data
;
401 r
= atgep
->atge_tx_ring
;
402 OUTL(atgep
, ATGE_DESC_ADDR_HI
,
403 ATGE_ADDR_HI(r
->r_desc_ring
->cookie
.dmac_laddress
));
404 OUTL(atgep
, ATGE_DESC_TPD_ADDR_LO
,
405 ATGE_ADDR_LO(r
->r_desc_ring
->cookie
.dmac_laddress
));
408 r
= l1
->atge_rx_ring
;
409 OUTL(atgep
, ATGE_DESC_RD_ADDR_LO
,
410 ATGE_ADDR_LO(r
->r_desc_ring
->cookie
.dmac_laddress
));
413 OUTL(atgep
, ATGE_DESC_RRD_ADDR_LO
,
414 ATGE_ADDR_LO(l1
->atge_l1_rr
->cookie
.dmac_laddress
));
417 OUTL(atgep
, ATGE_DESC_CMB_ADDR_LO
,
418 ATGE_ADDR_LO(l1
->atge_l1_cmb
->cookie
.dmac_laddress
));
421 OUTL(atgep
, ATGE_DESC_SMB_ADDR_LO
,
422 ATGE_ADDR_LO(l1
->atge_l1_smb
->cookie
.dmac_laddress
));
425 * Set RX return ring (RR) counter.
427 OUTL(atgep
, ATGE_DESC_RRD_RD_CNT
,
428 ((L1_RR_RING_CNT
<< DESC_RRD_CNT_SHIFT
) &
430 ((L1_RX_RING_CNT
<< DESC_RD_CNT_SHIFT
) & DESC_RD_CNT_MASK
));
433 * Set TX descriptor counter.
435 OUTL(atgep
, ATGE_DESC_TPD_CNT
,
436 (ATGE_TX_RING_CNT
<< DESC_TPD_CNT_SHIFT
) & DESC_TPD_CNT_MASK
);
439 * Inform hardware that we have loaded DMA registers.
441 OUTL(atgep
, ATGE_DMA_BLOCK
, DMA_BLOCK_LOAD
);
444 * Initialize mailbox register (mbox).
446 atge_l1_sync_mbox(atgep
);
450 atge_l1_gather_stats(atge_t
*atgep
)
457 ASSERT(atgep
!= NULL
);
459 l1
= atgep
->atge_private_data
;
460 dma
= l1
->atge_l1_smb
;
461 DMA_SYNC(dma
, 0, L1_SMB_BLOCK_SZ
, DDI_DMA_SYNC_FORKERNEL
);
462 stat
= (atge_l1_smb_t
*)atgep
->atge_hw_stats
;
463 smb
= (atge_l1_smb_t
*)dma
->addr
;
466 stat
->rx_frames
+= smb
->rx_frames
;
467 stat
->rx_bcast_frames
+= smb
->rx_bcast_frames
;
468 stat
->rx_mcast_frames
+= smb
->rx_mcast_frames
;
469 stat
->rx_pause_frames
+= smb
->rx_pause_frames
;
470 stat
->rx_control_frames
+= smb
->rx_control_frames
;
471 stat
->rx_crcerrs
+= smb
->rx_crcerrs
;
472 stat
->rx_lenerrs
+= smb
->rx_lenerrs
;
473 stat
->rx_bytes
+= smb
->rx_bytes
;
474 stat
->rx_runts
+= smb
->rx_runts
;
475 stat
->rx_fragments
+= smb
->rx_fragments
;
476 stat
->rx_pkts_64
+= smb
->rx_pkts_64
;
477 stat
->rx_pkts_65_127
+= smb
->rx_pkts_65_127
;
478 stat
->rx_pkts_128_255
+= smb
->rx_pkts_128_255
;
479 stat
->rx_pkts_256_511
+= smb
->rx_pkts_256_511
;
480 stat
->rx_pkts_512_1023
+= smb
->rx_pkts_512_1023
;
481 stat
->rx_pkts_1024_1518
+= smb
->rx_pkts_1024_1518
;
482 stat
->rx_pkts_1519_max
+= smb
->rx_pkts_1519_max
;
483 stat
->rx_pkts_truncated
+= smb
->rx_pkts_truncated
;
484 stat
->rx_fifo_oflows
+= smb
->rx_fifo_oflows
;
485 stat
->rx_alignerrs
+= smb
->rx_alignerrs
;
486 stat
->rx_bcast_bytes
+= smb
->rx_bcast_bytes
;
487 stat
->rx_mcast_bytes
+= smb
->rx_mcast_bytes
;
488 stat
->rx_pkts_filtered
+= smb
->rx_pkts_filtered
;
491 stat
->tx_frames
+= smb
->tx_frames
;
492 stat
->tx_bcast_frames
+= smb
->tx_bcast_frames
;
493 stat
->tx_mcast_frames
+= smb
->tx_mcast_frames
;
494 stat
->tx_pause_frames
+= smb
->tx_pause_frames
;
495 stat
->tx_excess_defer
+= smb
->tx_excess_defer
;
496 stat
->tx_control_frames
+= smb
->tx_control_frames
;
497 stat
->tx_deferred
+= smb
->tx_deferred
;
498 stat
->tx_bytes
+= smb
->tx_bytes
;
499 stat
->tx_pkts_64
+= smb
->tx_pkts_64
;
500 stat
->tx_pkts_65_127
+= smb
->tx_pkts_65_127
;
501 stat
->tx_pkts_128_255
+= smb
->tx_pkts_128_255
;
502 stat
->tx_pkts_256_511
+= smb
->tx_pkts_256_511
;
503 stat
->tx_pkts_512_1023
+= smb
->tx_pkts_512_1023
;
504 stat
->tx_pkts_1024_1518
+= smb
->tx_pkts_1024_1518
;
505 stat
->tx_pkts_1519_max
+= smb
->tx_pkts_1519_max
;
506 stat
->tx_single_colls
+= smb
->tx_single_colls
;
507 stat
->tx_multi_colls
+= smb
->tx_multi_colls
;
508 stat
->tx_late_colls
+= smb
->tx_late_colls
;
509 stat
->tx_excess_colls
+= smb
->tx_excess_colls
;
510 stat
->tx_underrun
+= smb
->tx_underrun
;
511 stat
->tx_desc_underrun
+= smb
->tx_desc_underrun
;
512 stat
->tx_lenerrs
+= smb
->tx_lenerrs
;
513 stat
->tx_pkts_truncated
+= smb
->tx_pkts_truncated
;
514 stat
->tx_bcast_bytes
+= smb
->tx_bcast_bytes
;
515 stat
->tx_mcast_bytes
+= smb
->tx_mcast_bytes
;
518 * Update global counters in atge_t.
520 atgep
->atge_brdcstrcv
+= smb
->rx_bcast_frames
;
521 atgep
->atge_multircv
+= smb
->rx_mcast_frames
;
522 atgep
->atge_multixmt
+= smb
->tx_mcast_frames
;
523 atgep
->atge_brdcstxmt
+= smb
->tx_bcast_frames
;
525 atgep
->atge_align_errors
+= smb
->rx_alignerrs
;
526 atgep
->atge_fcs_errors
+= smb
->rx_crcerrs
;
527 atgep
->atge_defer_xmts
+= smb
->tx_deferred
;
528 atgep
->atge_first_collisions
+= smb
->tx_single_colls
;
529 atgep
->atge_multi_collisions
+= smb
->tx_multi_colls
* 2;
530 atgep
->atge_tx_late_collisions
+= smb
->tx_late_colls
;
531 atgep
->atge_ex_collisions
+= smb
->tx_excess_colls
;
532 atgep
->atge_toolong_errors
+= smb
->rx_lenerrs
;
533 atgep
->atge_overflow
+= smb
->rx_fifo_oflows
;
534 atgep
->atge_underflow
+= (smb
->tx_underrun
+ smb
->tx_desc_underrun
);
535 atgep
->atge_runt
+= smb
->rx_runts
;
538 atgep
->atge_collisions
+= smb
->tx_single_colls
+
539 smb
->tx_multi_colls
* 2 + smb
->tx_late_colls
;
542 * tx_pkts_truncated counter looks suspicious. It constantly
543 * increments with no sign of Tx errors. Hence we don't factor it.
545 atgep
->atge_macxmt_errors
+= smb
->tx_late_colls
+ smb
->tx_underrun
;
547 atgep
->atge_macrcv_errors
+= smb
->rx_crcerrs
+ smb
->rx_lenerrs
+
548 smb
->rx_runts
+ smb
->rx_pkts_truncated
+
552 DMA_SYNC(dma
, 0, L1_SMB_BLOCK_SZ
, DDI_DMA_SYNC_FORDEV
);
556 atge_l1_stop_tx_mac(atge_t
*atgep
)
561 ATGE_DB(("%s: %s() called", atgep
->atge_name
, __func__
));
563 reg
= INL(atgep
, ATGE_MAC_CFG
);
564 if ((reg
& ATGE_CFG_TX_ENB
) != 0) {
565 reg
&= ~ATGE_CFG_TX_ENB
;
566 OUTL(atgep
, ATGE_MAC_CFG
, reg
);
569 /* Stop TX DMA engine. */
570 reg
= INL(atgep
, ATGE_DMA_CFG
);
571 if ((reg
& DMA_CFG_RD_ENB
) != 0) {
572 reg
&= ~DMA_CFG_RD_ENB
;
573 OUTL(atgep
, ATGE_DMA_CFG
, reg
);
576 for (t
= ATGE_RESET_TIMEOUT
; t
> 0; t
--) {
577 if ((INL(atgep
, ATGE_IDLE_STATUS
) &
578 (IDLE_STATUS_TXMAC
| IDLE_STATUS_DMARD
)) == 0)
585 atge_error(atgep
->atge_dip
, "stopping TX DMA Engine timeout");
590 atge_l1_stop_rx_mac(atge_t
*atgep
)
595 ATGE_DB(("%s: %s() called", atgep
->atge_name
, __func__
));
597 reg
= INL(atgep
, ATGE_MAC_CFG
);
598 if ((reg
& ATGE_CFG_RX_ENB
) != 0) {
599 reg
&= ~ATGE_CFG_RX_ENB
;
600 OUTL(atgep
, ATGE_MAC_CFG
, reg
);
603 /* Stop RX DMA engine. */
604 reg
= INL(atgep
, ATGE_DMA_CFG
);
605 if ((reg
& DMA_CFG_WR_ENB
) != 0) {
606 reg
&= ~DMA_CFG_WR_ENB
;
607 OUTL(atgep
, ATGE_DMA_CFG
, reg
);
610 for (t
= ATGE_RESET_TIMEOUT
; t
> 0; t
--) {
611 if ((INL(atgep
, ATGE_IDLE_STATUS
) &
612 (IDLE_STATUS_RXMAC
| IDLE_STATUS_DMAWR
)) == 0)
618 atge_error(atgep
->atge_dip
, " stopping RX DMA Engine timeout");
623 * Receives (consumes) packets.
626 atge_l1_rx(atge_t
*atgep
)
629 mblk_t
*mp
= NULL
, *rx_head
= NULL
, *rx_tail
= NULL
;
630 l1_rx_rdesc_t
*rx_rr
;
632 uint32_t index
, flags
, totlen
, pktlen
, slotlen
;
633 int nsegs
, rx_cons
= 0, cnt
;
638 l1
= atgep
->atge_private_data
;
641 DMA_SYNC(l1
->atge_l1_rr
, 0, L1_RR_RING_SZ
, DDI_DMA_SYNC_FORKERNEL
);
643 while (l1
->atge_l1_rr_consumers
!= l1
->atge_l1_rx_prod_cons
) {
644 rx_rr
= (l1_rx_rdesc_t
*)(l1
->atge_l1_rr
->addr
+
645 (l1
->atge_l1_rr_consumers
* sizeof (l1_rx_rdesc_t
)));
647 index
= ATGE_GET32(l1
->atge_l1_rr
, &rx_rr
->index
);
648 flags
= ATGE_GET32(l1
->atge_l1_rr
, &rx_rr
->flags
);
649 totlen
= L1_RX_BYTES(ATGE_GET32(l1
->atge_l1_rr
, &rx_rr
->len
));
651 rx_cons
= L1_RX_CONS(index
);
652 nsegs
= L1_RX_NSEGS(index
);
654 ATGE_DB(("%s: %s() PKT -- index : %d, flags : %x, totlen : %d,"
655 " rx_cons : %d, nsegs : %d", atgep
->atge_name
, __func__
,
656 index
, flags
, totlen
, rx_cons
, nsegs
));
661 if ((flags
& L1_RRD_ERROR
) &&
662 (flags
& (L1_RRD_CRC
| L1_RRD_CODE
| L1_RRD_DRIBBLE
|
663 L1_RRD_RUNT
| L1_RRD_OFLOW
| L1_RRD_TRUNC
)) != 0) {
664 atge_error(atgep
->atge_dip
, "errored pkt");
666 l1
->atge_rx_ring
->r_consumer
+= nsegs
;
667 l1
->atge_rx_ring
->r_consumer
%= L1_RX_RING_CNT
;
671 ASSERT(rx_cons
>= 0 && rx_cons
<= L1_RX_RING_CNT
);
673 mp
= allocb(totlen
+ VLAN_TAGSZ
, BPRI_MED
);
675 mp
->b_rptr
+= VLAN_TAGSZ
;
677 mp
->b_wptr
= bufp
+ totlen
;
680 atgep
->atge_ipackets
++;
681 atgep
->atge_rbytes
+= totlen
;
684 * If there are more than one segments, then the first
685 * segment should be of size MTU. We couldn't verify
686 * this as our driver does not support changing MTU
690 slotlen
= atgep
->atge_mtu
;
695 ATGE_DB(("%s: %s() PKT mp == NULL totlen : %d",
696 atgep
->atge_name
, __func__
, totlen
));
698 if (slotlen
> atgep
->atge_rx_buf_len
) {
699 atgep
->atge_toolong_errors
++;
700 } else if (mp
== NULL
) {
701 atgep
->atge_norcvbuf
++;
708 for (cnt
= 0, pktlen
= 0; cnt
< nsegs
; cnt
++) {
709 buf
= l1
->atge_rx_ring
->r_buf_tbl
[rx_cons
];
710 rxd
= (l1_rx_desc_t
*)(
711 l1
->atge_rx_ring
->r_desc_ring
->addr
+
712 (rx_cons
* sizeof (l1_rx_desc_t
)));
715 slotlen
= L1_RX_BYTES(ATGE_GET32(
716 l1
->atge_rx_ring
->r_desc_ring
, &rxd
->len
));
719 bcopy(buf
->addr
, (bufp
+ pktlen
), slotlen
);
722 ATGE_DB(("%s: %s() len : %d, rxcons : %d, pktlen : %d",
723 atgep
->atge_name
, __func__
, slotlen
, rx_cons
,
726 ATGE_INC_SLOT(rx_cons
, L1_RX_RING_CNT
);
729 if (rx_tail
== NULL
) {
730 rx_head
= rx_tail
= mp
;
732 rx_tail
->b_next
= mp
;
737 l1
->atge_rx_ring
->r_consumer
+= nsegs
;
738 l1
->atge_rx_ring
->r_consumer
%= L1_RX_RING_CNT
;
740 l1
->atge_rx_ring
->r_consumer
= rx_cons
;
744 * Tell the chip that this RR can be reused.
748 ATGE_INC_SLOT(l1
->atge_l1_rr_consumers
, L1_RR_RING_CNT
);
753 DMA_SYNC(l1
->atge_rx_ring
->r_desc_ring
, 0, L1_RX_RING_SZ
,
754 DDI_DMA_SYNC_FORDEV
);
756 DMA_SYNC(l1
->atge_l1_rr
, 0, L1_RR_RING_SZ
, DDI_DMA_SYNC_FORDEV
);
757 atge_l1_sync_mbox(atgep
);
759 ATGE_DB(("%s: %s() PKT Recved -> r_consumer : %d, rx_cons : %d"
760 " atge_l1_rr_consumers : %d",
761 atgep
->atge_name
, __func__
, l1
->atge_rx_ring
->r_consumer
,
762 rx_cons
, l1
->atge_l1_rr_consumers
));
770 * The interrupt handler for L1 chip.
774 atge_l1_interrupt(caddr_t arg1
, caddr_t arg2
)
776 atge_t
*atgep
= (void *)arg1
;
777 mblk_t
*rx_head
= NULL
, *rx_head1
= NULL
;
781 ASSERT(atgep
!= NULL
);
783 mutex_enter(&atgep
->atge_intr_lock
);
785 if (atgep
->atge_chip_state
& ATGE_CHIP_SUSPENDED
) {
786 mutex_exit(&atgep
->atge_intr_lock
);
787 return (DDI_INTR_UNCLAIMED
);
790 status
= INL(atgep
, ATGE_INTR_STATUS
);
791 if (status
== 0 || (status
& atgep
->atge_intrs
) == 0) {
792 mutex_exit(&atgep
->atge_intr_lock
);
794 if (atgep
->atge_flags
& ATGE_FIXED_TYPE
)
795 return (DDI_INTR_UNCLAIMED
);
797 return (DDI_INTR_CLAIMED
);
800 ATGE_DB(("%s: %s() entry status : %x",
801 atgep
->atge_name
, __func__
, status
));
804 * Disable interrupts.
806 OUTL(atgep
, ATGE_INTR_STATUS
, status
| INTR_DIS_INT
);
807 FLUSH(atgep
, ATGE_INTR_STATUS
);
810 * Check if chip is running, only then do the work.
812 if (atgep
->atge_chip_state
& ATGE_CHIP_RUNNING
) {
816 l1
= atgep
->atge_private_data
;
818 DMA_SYNC(l1
->atge_l1_cmb
, 0, L1_CMB_BLOCK_SZ
,
819 DDI_DMA_SYNC_FORKERNEL
);
821 cmb
= (l1_cmb_t
*)l1
->atge_l1_cmb
->addr
;
822 l1
->atge_l1_intr_status
=
823 ATGE_GET32(l1
->atge_l1_cmb
, &cmb
->intr_status
);
824 l1
->atge_l1_rx_prod_cons
=
825 (ATGE_GET32(l1
->atge_l1_cmb
, &cmb
->rx_prod_cons
) &
826 RRD_PROD_MASK
) >> RRD_PROD_SHIFT
;
827 l1
->atge_l1_tx_prod_cons
=
828 (ATGE_GET32(l1
->atge_l1_cmb
, &cmb
->tx_prod_cons
) &
829 TPD_CONS_MASK
) >> TPD_CONS_SHIFT
;
831 ATGE_DB(("%s: %s() atge_l1_intr_status : %x, "
832 "atge_l1_rx_prod_cons : %d, atge_l1_tx_prod_cons : %d"
833 " atge_l1_rr_consumers : %d",
834 atgep
->atge_name
, __func__
, l1
->atge_l1_intr_status
,
835 l1
->atge_l1_rx_prod_cons
, l1
->atge_l1_tx_prod_cons
,
836 l1
->atge_l1_rr_consumers
));
839 * Inform the hardware that CMB was served.
841 cmb
->intr_status
= 0;
842 DMA_SYNC(l1
->atge_l1_cmb
, 0, L1_CMB_BLOCK_SZ
,
843 DDI_DMA_SYNC_FORDEV
);
846 * We must check for RX Overflow condition and restart the
847 * chip. This needs to be done only when producer and consumer
848 * counters are same for the RR ring (Return RX).
850 if ((l1
->atge_l1_intr_status
& (INTR_CMB_RX
| INTR_MAC_RX
)) &&
851 (l1
->atge_l1_intr_status
&
852 (INTR_RX_FIFO_OFLOW
| INTR_RRD_OFLOW
) &&
853 (l1
->atge_l1_rr_consumers
== l1
->atge_l1_rx_prod_cons
))) {
855 ATGE_DB(("%s: %s() RX OVERFLOW :"
856 " atge_l1_rx_prod_cons : %d,"
857 " l1->atge_l1_rr_consumers : %d",
858 atgep
->atge_name
, __func__
,
859 l1
->atge_l1_rx_prod_cons
,
860 l1
->atge_l1_rr_consumers
));
862 mutex_enter(&atgep
->atge_tx_lock
);
863 atge_device_restart(atgep
);
864 mutex_exit(&atgep
->atge_tx_lock
);
868 rx_head
= atge_l1_rx(atgep
);
870 if (l1
->atge_l1_intr_status
& INTR_SMB
)
871 atge_l1_gather_stats(atgep
);
873 if (l1
->atge_l1_intr_status
& (INTR_CMB_TX
| INTR_MAC_TX
)) {
874 mutex_enter(&atgep
->atge_tx_lock
);
875 atge_tx_reclaim(atgep
, l1
->atge_l1_tx_prod_cons
);
876 if (atgep
->atge_tx_resched
) {
877 atgep
->atge_tx_resched
= 0;
881 mutex_exit(&atgep
->atge_tx_lock
);
884 if ((status
& (INTR_DMA_RD_TO_RST
| INTR_DMA_WR_TO_RST
)) != 0) {
885 atge_error(atgep
->atge_dip
,
886 "DMA transfer error");
888 ATGE_DB(("%s: %s() DMA transfer error",
889 atgep
->atge_name
, __func__
));
891 atge_device_stop(atgep
);
898 OUTL(atgep
, ATGE_INTR_STATUS
, INTR_DIS_DMA
| INTR_DIS_SM
);
899 mutex_exit(&atgep
->atge_intr_lock
);
901 if (status
& INTR_GPHY
|| atgep
->atge_flags
& ATGE_MII_CHECK
) {
902 ATGE_DB(("%s: %s() MII_CHECK Requested",
903 atgep
->atge_name
, __func__
));
905 if (status
& INTR_GPHY
) {
906 (void) atge_mii_read(atgep
,
907 atgep
->atge_phyaddr
, ATGE_ISR_ACK_GPHY
);
910 atgep
->atge_flags
&= ~ATGE_MII_CHECK
;
911 mii_reset(atgep
->atge_mii
);
915 * Pass the list of packets received from chip to MAC layer.
918 mac_rx(atgep
->atge_mh
, 0, rx_head
);
922 mac_rx(atgep
->atge_mh
, 0, rx_head1
);
926 * Let MAC start sending pkts if the downstream was asked to pause.
929 mac_tx_update(atgep
->atge_mh
);
931 return (DDI_INTR_CLAIMED
);
935 atge_l1_send_packet(atge_ring_t
*r
)
937 atge_l1_sync_mbox(r
->r_atge
);