FreeBSD/Linux Kernel Cross Reference
sys/dev/atm/hea/eni_if.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_if.c,v 1.5 1999/08/28 00:41:44 peter Exp $
27 * @(#) $DragonFly: src/sys/dev/atm/hea/eni_if.c,v 1.7 2008/03/01 22:03:13 swildner Exp $
28 */
29
30 /*
31 * Efficient ENI Adapter Support
32 * -----------------------------
33 *
34 * Network interface layer support
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_get_stats (Eni_unit *);
46
47 /*
48 * SUNI statistics counters take one of three forms:
49 * single byte value (0x0 - 0xff)
50 * two byte value (0x0 - 0xffff)
51 * two + 1/2 (three) byte value
52 * (0x0 - 0x0fffff)
53 */
54 #define READ_ONE(x) ( (eup->eu_suni[(x)] & 0xff) )
55
56 #define READ_TWO(x) ( (eup->eu_suni[(x)+1] & 0xff) << 8 | \
57 (eup->eu_suni[(x)] & 0xff) )
58
59 #define READ_THREE(x) ( (eup->eu_suni[(x)+2] & 0xf) << 16 | \
60 (eup->eu_suni[(x)+1] & 0xff) << 8 | \
61 (eup->eu_suni[(x)] & 0xff) )
62
63 /*
64 * Do an initial read of the error counters without saving them.
65 * In effect, this will "zero" our idea of the number of errors
66 * which have occurred since the driver was loaded.
67 *
68 * Arguments:
69 * eup pointer to per unit structure
70 *
71 * Returns:
72 * none
73 *
74 */
75 void
76 eni_zero_stats(Eni_unit *eup)
77 {
78 int val;
79
80 /*
81 * Write the SUNI master control register which
82 * will cause all the statistics counters to be
83 * loaded.
84 */
85 eup->eu_suni[SUNI_MASTER_REG] = eup->eu_suni[SUNI_MASTER_REG];
86
87 /*
88 * Delay to allow for counter load time...
89 */
90 DELAY ( SUNI_DELAY );
91
92 /*
93 * Statistics counters contain the number of events
94 * since the last time the counter was read.
95 */
96 val = READ_TWO ( SUNI_SECT_BIP_REG ); /* oc3_sect_bip8 */
97 val = READ_TWO ( SUNI_PATH_BIP_REG ); /* oc3_path_bip8 */
98 val = READ_THREE ( SUNI_LINE_BIP_REG ); /* oc3_line_bip24 */
99 val = READ_THREE ( SUNI_LINE_FEBE_REG ); /* oc3_line_febe */
100 val = READ_TWO ( SUNI_PATH_FEBE_REG ); /* oc3_path_febe */
101 val = READ_ONE ( SUNI_HECS_REG ); /* oc3_hec_corr */
102 val = READ_ONE ( SUNI_UHECS_REG ); /* oc3_hec_uncorr */
103 }
104
105 /*
106 * Retrieve SUNI stats
107 *
108 * Arguments:
109 * eup pointer to per unit structure
110 *
111 * Returns:
112 * none
113 *
114 */
115 static void
116 eni_get_stats (Eni_unit *eup)
117 {
118 /*
119 * Write the SUNI master control register which
120 * will cause all the statistics counters to be
121 * loaded.
122 */
123 eup->eu_suni[SUNI_MASTER_REG] = eup->eu_suni[SUNI_MASTER_REG];
124
125 /*
126 * Delay to allow for counter load time...
127 */
128 DELAY ( 10 );
129
130 /*
131 * Statistics counters contain the number of events
132 * since the last time the counter was read.
133 */
134 eup->eu_stats.eni_st_oc3.oc3_sect_bip8 +=
135 READ_TWO ( SUNI_SECT_BIP_REG );
136 eup->eu_stats.eni_st_oc3.oc3_path_bip8 +=
137 READ_TWO ( SUNI_PATH_BIP_REG );
138 eup->eu_stats.eni_st_oc3.oc3_line_bip24 +=
139 READ_THREE ( SUNI_LINE_BIP_REG );
140 eup->eu_stats.eni_st_oc3.oc3_line_febe +=
141 READ_THREE ( SUNI_LINE_FEBE_REG );
142 eup->eu_stats.eni_st_oc3.oc3_path_febe +=
143 READ_TWO ( SUNI_PATH_FEBE_REG );
144 eup->eu_stats.eni_st_oc3.oc3_hec_corr +=
145 READ_ONE ( SUNI_HECS_REG );
146 eup->eu_stats.eni_st_oc3.oc3_hec_uncorr +=
147 READ_ONE ( SUNI_UHECS_REG );
148 }
149
150 /*
151 * Handle netatm core service interface ioctl requests
152 *
153 * Called at splnet.
154 *
155 * Arguments:
156 * code ioctl function (sub)code
157 * data data to/from ioctl
158 * arg optional code-specific argument
159 *
160 * Returns:
161 * 0 request processed successfully
162 * error request failed - reason code
163 *
164 */
165 int
166 eni_atm_ioctl(int code, caddr_t data, caddr_t arg)
167 {
168 struct atminfreq *aip = (struct atminfreq *)data;
169 struct atm_pif *pip = (struct atm_pif *)arg;
170 Eni_unit *eup = (Eni_unit *)pip;
171 caddr_t buf = aip->air_buf_addr;
172 struct air_vinfo_rsp *avr;
173 int count, len, buf_len = aip->air_buf_len;
174 int err = 0;
175 char ifname[2*IFNAMSIZ];
176
177 ATM_DEBUG2("eni_atm_ioctl: code=%d, opcode=%d\n",
178 code, aip->air_opcode );
179
180 switch ( aip->air_opcode ) {
181
182 case AIOCS_INF_VST:
183 /*
184 * Get vendor statistics
185 */
186 if ( eup == NULL )
187 return ( ENXIO );
188 ksnprintf ( ifname, sizeof(ifname),
189 "%s%d", pip->pif_name, pip->pif_unit );
190
191 /*
192 * Cast response structure onto user's buffer
193 */
194 avr = (struct air_vinfo_rsp *)buf;
195
196 /*
197 * How large is the response structure
198 */
199 len = sizeof(struct air_vinfo_rsp);
200
201 /*
202 * Sanity check - enough room for response structure?
203 */
204 if ( buf_len < len )
205 return ( ENOSPC );
206
207 /*
208 * Copy interface name into response structure
209 */
210 if ((err = copyout(ifname, avr->avsp_intf, IFNAMSIZ)) != 0)
211 break;
212
213 /*
214 * Advance the buffer address and decrement the size
215 */
216 buf += len;
217 buf_len -= len;
218
219 /*
220 * Get the vendor stats (SUNI) from the hardware
221 */
222 eni_get_stats ( eup );
223 /*
224 * Stick as much of it as we have room for
225 * into the response
226 */
227 count = MIN ( sizeof(Eni_stats), buf_len );
228
229 /*
230 * Copy stats into user's buffer. Return value is
231 * amount of data copied.
232 */
233 if ((err = copyout((void *)&eup->eu_stats, buf, count)) != 0)
234 break;
235 buf += count;
236 buf_len -= count;
237 if ( count < sizeof(Eni_stats) )
238 err = ENOSPC;
239
240 /*
241 * Record amount we're returning as vendor info...
242 */
243 if ((err = copyout(&count, &avr->avsp_len, sizeof(int))) != 0)
244 break;
245
246 /*
247 * Update the reply pointers and length
248 */
249 aip->air_buf_addr = buf;
250 aip->air_buf_len = buf_len;
251 break;
252
253 default:
254 err = ENOSYS; /* Operation not supported */
255 break;
256 }
257
258 return ( err );
259
260 }
261
Cache object: e261bd54b3eefaa2b1a0e3110b4b6d84
|