3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
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.
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.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/dev/hea/eni_vcm.c,v 1.3 1999/08/28 00:41:47 peter Exp $
27 * @(#) $DragonFly: src/sys/dev/atm/hea/eni_vcm.c,v 1.7 2008/03/01 22:03:13 swildner Exp $
31 * Efficient ENI Adapter Support
32 * -----------------------------
34 * Virtual Channel Managment
39 #include <netproto/atm/kern_include.h>
41 #include "eni_stats.h"
46 * VCC Stack Instantiation
48 * This function is called via the common driver code during a device VCC
49 * stack instantiation. The common code has already validated some of
50 * the request so we just need to check a few more ENI-specific details.
55 * cup pointer to device common unit
56 * cvp pointer to common VCC entry
59 * 0 instantiation successful
60 * err instantiation failed - reason indicated
64 eni_instvcc(Cmn_unit *cup, Cmn_vcc *cvp)
66 Eni_unit *eup = (Eni_unit *)cup;
67 Eni_vcc *evp = (Eni_vcc *)cvp;
68 Atm_attributes *ap = &evp->ev_connvc->cvc_attr;
71 * Validate requested AAL
73 switch (ap->aal.type) {
79 if ((ap->aal.v.aal5.forward_max_SDU_size > ENI_IFF_MTU) ||
80 (ap->aal.v.aal5.backward_max_SDU_size > ENI_IFF_MTU)) {
81 eup->eu_stats.eni_st_drv.drv_vc_maxpdu++;
97 * This function is called via the common driver code after receiving a
98 * stack *_INIT* command. The common code has already validated most of
99 * the request so we just need to check a few more ENI-specific details.
104 * cup pointer to device common unit
105 * cvp pointer to common VCC entry
113 eni_openvcc(Cmn_unit *cup, Cmn_vcc *cvp)
115 Eni_unit *eup = (Eni_unit *)cup;
116 Eni_vcc *evp = (Eni_vcc *)cvp;
117 struct vccb *vcp = evp->ev_connvc->cvc_vcc;
126 * Validate the VPI and VCI values
128 if ( (vcp->vc_vpi > eup->eu_pif.pif_maxvpi) ||
129 (vcp->vc_vci > eup->eu_pif.pif_maxvci) ) {
130 eup->eu_stats.eni_st_drv.drv_vc_badrng++;
135 * Check if this VCI is already active
137 vct = &eup->eu_vcitbl[ vcp->vc_vci ];
138 if ( vct->vci_control >> VCI_MODE_SHIFT != VCI_MODE_TRASH ) {
143 * Allocate some permanent adapter memory for the reassembly
144 * buffer. Special case the signalling channel(s) buffer size.
145 * Otherwise, the buffer size will be based on whether this is
146 * a server or client card.
148 if ( vcp->vc_vci == UNI_SIG_VCI ) /* HACK */
151 size = (eup->eu_ramsize > MAX_CLIENT_RAM * ENI_BUF_PGSZ) ?
152 RX_SERVER_BSIZE * ENI_BUF_PGSZ :
153 RX_CLIENT_BSIZE * ENI_BUF_PGSZ;
155 if ( ( evp->ev_rxbuf = eni_allocate_buffer ( eup, (u_long *)&size ) )
162 * We only need to open incoming VCI's so outbound VCI's
163 * just get set to CVS_ACTIVE state.
165 if ( ( vcp->vc_type & VCC_IN ) == 0 ) {
167 * Set the state and return - nothing else needs to be done.
169 evp->ev_state = CVS_ACTIVE;
174 * Set the VCI Table entry to start receiving
176 mode = ( evp->ev_connvc->cvc_attr.aal.type == ATM_AAL5
177 ? VCI_MODE_AAL5 : VCI_MODE_AAL0 );
178 size >>= ENI_LOC_PREDIV; /* Predivide by 256 WORDS */
179 for ( nsize = -1; size; nsize++ )
182 vct->vci_control = mode << VCI_MODE_SHIFT |
183 PTI_MODE_TRASH << VCI_PTI_SHIFT |
184 ( (u_int)(evp->ev_rxbuf) >> ENI_LOC_PREDIV ) << VCI_LOC_SHIFT |
185 nsize << VCI_SIZE_SHIFT;
186 vct->vci_descr = 0; /* Descr = Rdptr = 0 */
187 vct->vci_write = 0; /* WritePtr = CellCount = 0 */
192 evp->ev_state = CVS_ACTIVE;
200 * This function is called via the common driver code after receiving a
201 * stack *_TERM* command. The common code has already validated most of
202 * the request so we just need to check a few more ENI-specific details.
207 * cup pointer to device common unit
208 * cvp pointer to common VCC entry
216 eni_closevcc(Cmn_unit *cup, Cmn_vcc *cvp)
218 Eni_unit *eup = (Eni_unit *)cup;
219 Eni_vcc *evp = (Eni_vcc *)cvp;
220 struct vccb *vcp = evp->ev_connvc->cvc_vcc;
226 * Clear any references to this VCC in our transmit queue
229 * We'll simply allow any existing TX requests to be
230 * sent as that's easier then pulling them out of
231 * everywhere. Besides, they should be ignored at the
232 * receiver whenever the other end shuts down.
236 * Free the adapter receive buffer
238 (void) eni_free_buffer ( eup, (caddr_t)evp->ev_rxbuf );
241 * If this is an outbound only VCI, then we can close
244 if ( ( vcp->vc_type & VCC_IN ) == 0 ) {
246 * The state will be set to TERM when we return
247 * to the *_TERM caller.
253 * Find VCI entry in VCI Table
255 vct = &eup->eu_vcitbl[ vcp->vc_vci ];
258 * Reset the VCI state
260 vct->vci_control = ( vct->vci_control & VCI_MODE_MASK )
261 /* | VCI_MODE_TRASH */;
262 DELAY ( MIDWAY_DELAY ); /* Give the adapter time to */
263 /* make the transition */
268 KM_ZERO ( vct, sizeof(VCI_Table) );