Merge branch 'vendor/FILE'
[dragonfly.git] / sys / dev / atm / hea / eni_intr.c
1 /*
2  *
3  * ===================================
4  * HARP  |  Host ATM Research Platform
5  * ===================================
6  *
7  *
8  * This Host ATM Research Platform ("HARP") file (the "Software") is
9  * made available by Network Computing Services, Inc. ("NetworkCS")
10  * "AS IS".  NetworkCS does not provide maintenance, improvements or
11  * support of any kind.
12  *
13  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17  * In no event shall NetworkCS be responsible for any damages, including
18  * but not limited to consequential damages, arising from or relating to
19  * any use of the Software or related support.
20  *
21  * Copyright 1994-1998 Network Computing Services, Inc.
22  *
23  * Copies of this Software may be made, however, the above copyright
24  * notice must be reproduced on all copies.
25  *
26  *      @(#) $FreeBSD: src/sys/dev/hea/eni_intr.c,v 1.4 1999/08/28 00:41:44 peter Exp $
27  *      @(#) $DragonFly: src/sys/dev/atm/hea/eni_intr.c,v 1.7 2008/03/01 22:03:13 swildner Exp $
28  */
29
30 /*
31  * Efficient ENI Adapter Support
32  * -----------------------------
33  *
34  * Interrupt processing
35  *
36  */
37
38 #include <netproto/atm/kern_include.h>
39
40 #include "eni_stats.h"
41 #include "eni.h"
42 #include "eni_suni.h"
43 #include "eni_var.h"
44
45 static void     eni_suni_intr (Eni_unit *);
46
47 /*
48  * SUNI Interrupt processing
49  *
50  * Currently, we don't do anything more then clear the interrupt
51  * for the SUNI chip.
52  *
53  * Arguments:
54  *      eup             pointer to device unit structure
55  *
56  * Returns:
57  *      none
58  *
59  */
60 static void
61 eni_suni_intr(Eni_unit *eup)
62 {
63         int     SuniInt;
64         int     val;
65
66         SuniInt = eup->eu_suni[SUNI_IS_REG];
67         
68         /* RSOPI */
69         if ( SuniInt & SUNI_RSOPI )
70                 val = eup->eu_suni[SUNI_RSOP_REG];
71
72         /* RLOPI */
73         if ( SuniInt & SUNI_RLOPI )
74                 val = eup->eu_suni[SUNI_RLOP_REG];
75
76         /* RPOPI */
77         if ( SuniInt & SUNI_RPOPI )
78                 val = eup->eu_suni[SUNI_RPOP_IS_REG];
79
80         /* RACPI */
81         if ( SuniInt & SUNI_RACPI )
82                 val = eup->eu_suni[SUNI_RACP_REG];
83
84         /* TACPI */
85         if ( SuniInt & SUNI_TACPI )
86                 val = eup->eu_suni[SUNI_TACP_REG];
87
88         /* TROOLI */
89         if ( SuniInt & SUNI_TROOLI )
90                 val = eup->eu_suni[SUNI_CLOCK_REG];
91
92         /* LCDI */
93                 /* Cleared when reading Master Interrupt Status Reg */
94
95         /* RDOOLI */
96         if ( SuniInt & SUNI_RDOOLI )
97                 val = eup->eu_suni[SUNI_CLOCK_REG];
98
99         return;
100 }
101
102 /*
103  * Device interrupt routine
104  *
105  * Service an interrupt from this device
106  *
107  * Arguments:
108  *      eup             pointer to device unit structure
109  *
110  * Returns:
111  *      none
112  *
113  */
114 void
115 eni_intr(void *arg)
116 {
117         Eni_unit        *eup = (Eni_unit *)arg;
118
119         /*
120          * Read and acknowledge any interrupts
121          */
122         u_long  mask = eup->eu_midway[MIDWAY_ISA];
123         /*
124          * Read the error statistics counter
125          */
126         u_long  sval = eup->eu_midway[MIDWAY_STAT];
127
128         /*
129          * Update statistics from adapter
130          */
131         eup->eu_trash += ( sval >> 16 );
132         eup->eu_ovfl += ( sval & 0xffff );
133
134         /*
135          * We handle any DMA completes first so
136          * that we can free resources for use
137          * during transmit and especially receive
138          */
139         /*
140          * Handle RX DMA Complete
141          */
142         if ( mask & ENI_INT_RX_DMA ) {
143                 eni_recv_drain ( eup );
144         }
145
146         /*
147          * Handle TX DMA Complete
148          */
149         if ( mask & ENI_INT_TX_DMA ) {
150                 eni_xmit_drain ( eup );
151         }
152
153         /*
154          * Look for any PDUs in service list
155          */
156         if ( mask & ENI_INT_SERVICE ) {
157                 eni_do_service ( eup );
158         }
159
160         /*
161          * Handle miscelaneous interrupts
162          */
163         if ( mask & ENI_INT_STAT ) {                    /* STAT_OVFL */
164                 log ( LOG_INFO, "eni_intr: stat_ovfl: 0x%lx\n", sval );
165         }
166         if ( mask & ENI_INT_SUNI ) {                    /* SUNI_INTR */
167                 eni_suni_intr ( eup );
168         }
169         if ( mask & ENI_INT_DMA_ERR ) {                 /* DMA Error */
170                 log ( LOG_ERR,
171                         "eni_intr: DMA Error\n" );
172                 /*
173                  * We don't know how to recover from DMA errors
174                  * yet. The adapter has disabled any further
175                  * processing and we're going to leave it like
176                  * that.
177                  */
178                 return;                                 /* Leave now */
179         }
180         if ( mask & ENI_INT_IDEN ) {
181                 log ( LOG_ERR,
182                         "eni_intr: TX DMA Ident mismatch\n" );
183                 /*
184                  * Something in the TX buffer has really gotten messed
185                  * up. Since this is most likely a driver bug, and
186                  * the adapter has shut everything down, leave it
187                  * like that.
188                  */
189                 return;                                 /* Leave now */
190         }
191         if ( mask & ENI_INT_DMA_OVFL )
192                 eup->eu_stats.eni_st_drv.drv_xm_dmaovfl++;
193         if ( mask & ENI_INT_DMA_LERR ) {
194                 log ( LOG_ERR,
195                         "eni_intr: DMA LERR\n" );
196                 return;
197         }
198 }
199