b3ce30ea519fcec667df6503033b49123b279f17
[dragonfly.git] / sys / dev / atm / hfa / fore_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/hfa/fore_if.c,v 1.5 1999/08/28 00:41:49 peter Exp $
27  *      @(#) $DragonFly: src/sys/dev/atm/hfa/fore_if.c,v 1.4 2006/12/20 18:14:38 dillon Exp $
28  */
29
30 /*
31  * FORE Systems 200-Series Adapter Support
32  * ---------------------------------------
33  *
34  * Network interface layer support
35  *
36  */
37
38 #include "fore_include.h"
39
40 /*
41  * Handle netatm core service interface ioctl requests 
42  *
43  * Called at splnet.
44  *
45  * Arguments:
46  *      code            ioctl function (sub)code
47  *      data            data to/from ioctl
48  *      arg             optional code-specific argument
49  *
50  * Returns:
51  *      0               request processed successfully
52  *      error           request failed - reason code
53  */
54 int
55 fore_atm_ioctl(code, data, arg)
56         int     code;
57         caddr_t data;
58         caddr_t arg;
59 {
60         struct atminfreq        *aip = (struct atminfreq *)data;
61         struct atm_pif          *pip;
62         Fore_unit               *fup;
63         caddr_t                 buf = aip->air_buf_addr;
64         struct air_vinfo_rsp    *avr;
65         int                     count, len, buf_len = aip->air_buf_len;
66         int                     err = 0;
67         char                    ifname[2*IFNAMSIZ];
68  
69
70         ATM_DEBUG2("fore_atm_ioctl: code=%d, opcode=%d\n", 
71                 code, aip->air_opcode);
72
73         switch ( aip->air_opcode ) {
74
75         case AIOCS_INF_VST:
76                 /*
77                  * Get vendor statistics
78                  */
79                 pip = (struct atm_pif *)arg;
80                 fup = (Fore_unit *)pip;
81                 if ( pip == NULL )
82                         return ( ENXIO );
83                 ksnprintf ( ifname, sizeof(ifname),
84                     "%s%d", pip->pif_name, pip->pif_unit );
85
86                 /*
87                  * Cast response structure onto user's buffer
88                  */
89                 avr = (struct air_vinfo_rsp *)buf;
90
91                 /*
92                  * How large is the response structure?
93                  */
94                 len = sizeof(struct air_vinfo_rsp);
95
96                 /*
97                  * Sanity check - enough room for response structure?
98                  */
99                 if ( buf_len < len )
100                         return ( ENOSPC );
101
102                 /*
103                  * Copy interface name into response structure
104                  */
105                 if ((err = copyout ( ifname, avr->avsp_intf, IFNAMSIZ)) != 0)
106                         break;
107
108                 /*
109                  * Advance the buffer address and decrement the size
110                  */
111                 buf += len;
112                 buf_len -= len;
113
114                 /*
115                  * Get the vendor stats from the hardware
116                  */
117                 count = 0;
118                 if ( ( err = fore_get_stats ( fup ) ) == 0 )
119                 {
120                         /*
121                          * Stick as much of it as we have room for 
122                          * into the response
123                          */
124                         count = min ( sizeof(Fore_stats), buf_len );
125
126                         /*
127                          * Copy stats into user's buffer. Return value is
128                          * amount of data copied.
129                          */
130                         if ((err = copyout((caddr_t)fup->fu_stats, buf, count)) != 0)
131                                 break;
132                         buf += count;
133                         buf_len -= count;
134                         if ( count < sizeof(Fore_stats) )
135                                 err = ENOSPC;
136                 }
137
138                 /*
139                  * Record amount we're returning as vendor info...
140                  */
141                 if ((err = copyout(&count, &avr->avsp_len, sizeof(int))) != 0)
142                         break;
143
144                 /*
145                  * Update the reply pointers and lengths
146                  */
147                 aip->air_buf_addr = buf;
148                 aip->air_buf_len = buf_len;
149                 break;
150
151         default:
152                 err = ENOSYS;           /* Operation not supported */
153                 break;
154         }
155
156         return (err);
157 }
158
159
160 /*
161  * Free Fore-specific device resources
162  * 
163  * Frees all dynamically acquired resources for a device unit.  Before
164  * this function is called, the CP will have been reset and our interrupt
165  * vectors removed.
166  *
167  * Arguments:
168  *      fup     pointer to device unit structure
169  *
170  * Returns:
171  *      none
172  *
173  */
174 void
175 fore_interface_free(fup)
176         Fore_unit       *fup;
177 {
178
179         /*
180          * Free up all of our allocated memory
181          */
182         fore_xmit_free(fup);
183         fore_recv_free(fup);
184         fore_buf_free(fup);
185         fore_cmd_free(fup);
186
187         /*
188          * Clear device initialized
189          */
190         if (fup->fu_flags & CUF_INITED) {
191                 fup->fu_flags &= ~CUF_INITED;
192         }
193
194         if (fup->fu_flags & FUF_STATCMD) {
195                 DMA_FREE_ADDR(fup->fu_stats, fup->fu_statsd,
196                         sizeof(Fore_cp_stats), 0);
197                 fup->fu_flags &= ~FUF_STATCMD;
198         }
199         return;
200 }
201