remove __P() from this directory
[dragonfly.git] / sys / dev / atm / hea / eni_if.c
CommitLineData
984263bc
MD
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 $
38e94a25 27 * @(#) $DragonFly: src/sys/dev/atm/hea/eni_if.c,v 1.5 2003/08/27 10:35:15 rob Exp $
984263bc
MD
28 */
29
30/*
31 * Efficient ENI Adapter Support
32 * -----------------------------
33 *
34 * Network interface layer support
35 *
36 */
37
d2438d69 38#include <netproto/atm/kern_include.h>
984263bc 39
1f2de5d4
MD
40#include "eni_stats.h"
41#include "eni.h"
42#include "eni_suni.h"
43#include "eni_var.h"
984263bc 44
38e94a25 45static void eni_get_stats (Eni_unit *);
984263bc
MD
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 */
75void
76eni_zero_stats ( eup )
77 Eni_unit *eup;
78{
79 int val;
80
81 /*
82 * Write the SUNI master control register which
83 * will cause all the statistics counters to be
84 * loaded.
85 */
86 eup->eu_suni[SUNI_MASTER_REG] = eup->eu_suni[SUNI_MASTER_REG];
87
88 /*
89 * Delay to allow for counter load time...
90 */
91 DELAY ( SUNI_DELAY );
92
93 /*
94 * Statistics counters contain the number of events
95 * since the last time the counter was read.
96 */
97 val = READ_TWO ( SUNI_SECT_BIP_REG ); /* oc3_sect_bip8 */
98 val = READ_TWO ( SUNI_PATH_BIP_REG ); /* oc3_path_bip8 */
99 val = READ_THREE ( SUNI_LINE_BIP_REG ); /* oc3_line_bip24 */
100 val = READ_THREE ( SUNI_LINE_FEBE_REG ); /* oc3_line_febe */
101 val = READ_TWO ( SUNI_PATH_FEBE_REG ); /* oc3_path_febe */
102 val = READ_ONE ( SUNI_HECS_REG ); /* oc3_hec_corr */
103 val = READ_ONE ( SUNI_UHECS_REG ); /* oc3_hec_uncorr */
104}
105
106/*
107 * Retrieve SUNI stats
108 *
109 * Arguments:
110 * eup pointer to per unit structure
111 *
112 * Returns:
113 * none
114 *
115 */
116static void
117eni_get_stats ( eup )
118 Eni_unit *eup;
119{
120 /*
121 * Write the SUNI master control register which
122 * will cause all the statistics counters to be
123 * loaded.
124 */
125 eup->eu_suni[SUNI_MASTER_REG] = eup->eu_suni[SUNI_MASTER_REG];
126
127 /*
128 * Delay to allow for counter load time...
129 */
130 DELAY ( 10 );
131
132 /*
133 * Statistics counters contain the number of events
134 * since the last time the counter was read.
135 */
136 eup->eu_stats.eni_st_oc3.oc3_sect_bip8 +=
137 READ_TWO ( SUNI_SECT_BIP_REG );
138 eup->eu_stats.eni_st_oc3.oc3_path_bip8 +=
139 READ_TWO ( SUNI_PATH_BIP_REG );
140 eup->eu_stats.eni_st_oc3.oc3_line_bip24 +=
141 READ_THREE ( SUNI_LINE_BIP_REG );
142 eup->eu_stats.eni_st_oc3.oc3_line_febe +=
143 READ_THREE ( SUNI_LINE_FEBE_REG );
144 eup->eu_stats.eni_st_oc3.oc3_path_febe +=
145 READ_TWO ( SUNI_PATH_FEBE_REG );
146 eup->eu_stats.eni_st_oc3.oc3_hec_corr +=
147 READ_ONE ( SUNI_HECS_REG );
148 eup->eu_stats.eni_st_oc3.oc3_hec_uncorr +=
149 READ_ONE ( SUNI_UHECS_REG );
150}
151
152/*
153 * Handle netatm core service interface ioctl requests
154 *
155 * Called at splnet.
156 *
157 * Arguments:
158 * code ioctl function (sub)code
159 * data data to/from ioctl
160 * arg optional code-specific argument
161 *
162 * Returns:
163 * 0 request processed successfully
164 * error request failed - reason code
165 *
166 */
167int
168eni_atm_ioctl ( code, data, arg )
169 int code;
170 caddr_t data;
171 caddr_t arg;
172{
173 struct atminfreq *aip = (struct atminfreq *)data;
174 struct atm_pif *pip = (struct atm_pif *)arg;
175 Eni_unit *eup = (Eni_unit *)pip;
176 caddr_t buf = aip->air_buf_addr;
177 struct air_vinfo_rsp *avr;
178 int count, len, buf_len = aip->air_buf_len;
179 int err = 0;
180 char ifname[2*IFNAMSIZ];
181
182 ATM_DEBUG2("eni_atm_ioctl: code=%d, opcode=%d\n",
183 code, aip->air_opcode );
184
185 switch ( aip->air_opcode ) {
186
187 case AIOCS_INF_VST:
188 /*
189 * Get vendor statistics
190 */
191 if ( eup == NULL )
192 return ( ENXIO );
193 snprintf ( ifname, sizeof(ifname),
194 "%s%d", pip->pif_name, pip->pif_unit );
195
196 /*
197 * Cast response structure onto user's buffer
198 */
199 avr = (struct air_vinfo_rsp *)buf;
200
201 /*
202 * How large is the response structure
203 */
204 len = sizeof(struct air_vinfo_rsp);
205
206 /*
207 * Sanity check - enough room for response structure?
208 */
209 if ( buf_len < len )
210 return ( ENOSPC );
211
212 /*
213 * Copy interface name into response structure
214 */
215 if ((err = copyout(ifname, avr->avsp_intf, IFNAMSIZ)) != 0)
216 break;
217
218 /*
219 * Advance the buffer address and decrement the size
220 */
221 buf += len;
222 buf_len -= len;
223
224 /*
225 * Get the vendor stats (SUNI) from the hardware
226 */
227 eni_get_stats ( eup );
228 /*
229 * Stick as much of it as we have room for
230 * into the response
231 */
232 count = MIN ( sizeof(Eni_stats), buf_len );
233
234 /*
235 * Copy stats into user's buffer. Return value is
236 * amount of data copied.
237 */
238 if ((err = copyout((void *)&eup->eu_stats, buf, count)) != 0)
239 break;
240 buf += count;
241 buf_len -= count;
242 if ( count < sizeof(Eni_stats) )
243 err = ENOSPC;
244
245 /*
246 * Record amount we're returning as vendor info...
247 */
248 if ((err = copyout(&count, &avr->avsp_len, sizeof(int))) != 0)
249 break;
250
251 /*
252 * Update the reply pointers and length
253 */
254 aip->air_buf_addr = buf;
255 aip->air_buf_len = buf_len;
256 break;
257
258 default:
259 err = ENOSYS; /* Operation not supported */
260 break;
261 }
262
263 return ( err );
264
265}
266