FreeBSD/Linux Kernel Cross Reference
sys/dev/hfa/fore_vcm.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: releng/5.3/sys/dev/hfa/fore_vcm.c 119280 2003-08-22 06:00:27Z imp $
27 *
28 */
29
30 /*
31 * FORE Systems 200-Series Adapter Support
32 * ---------------------------------------
33 *
34 * Virtual Channel Management
35 *
36 */
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/socket.h>
41 #include <sys/socketvar.h>
42 #include <net/if.h>
43 #include <netatm/port.h>
44 #include <netatm/queue.h>
45 #include <netatm/atm.h>
46 #include <netatm/atm_sys.h>
47 #include <netatm/atm_sap.h>
48 #include <netatm/atm_cm.h>
49 #include <netatm/atm_if.h>
50 #include <netatm/atm_vc.h>
51 #include <netatm/atm_stack.h>
52 #include <netatm/atm_pcb.h>
53 #include <netatm/atm_var.h>
54 #include <dev/pci/pcivar.h>
55 #include <dev/hfa/fore.h>
56 #include <dev/hfa/fore_aali.h>
57 #include <dev/hfa/fore_slave.h>
58 #include <dev/hfa/fore_stats.h>
59 #include <dev/hfa/fore_var.h>
60 #include <dev/hfa/fore_include.h>
61
62 #ifndef lint
63 __RCSID("@(#) $FreeBSD: releng/5.3/sys/dev/hfa/fore_vcm.c 119280 2003-08-22 06:00:27Z imp $");
64 #endif
65
66
67 /*
68 * VCC Stack Instantiation
69 *
70 * This function is called via the common driver code during a device VCC
71 * stack instantiation. The common code has already validated some of
72 * the request so we just need to check a few more Fore-specific details.
73 *
74 * Called at splnet.
75 *
76 * Arguments:
77 * cup pointer to device common unit
78 * cvp pointer to common VCC entry
79 *
80 * Returns:
81 * 0 instantiation successful
82 * err instantiation failed - reason indicated
83 *
84 */
85 int
86 fore_instvcc(cup, cvp)
87 Cmn_unit *cup;
88 Cmn_vcc *cvp;
89 {
90 Fore_vcc *fvp = (Fore_vcc *)cvp;
91 Atm_attributes *ap = &fvp->fv_connvc->cvc_attr;
92
93 /*
94 * Validate requested AAL
95 */
96 switch (ap->aal.type) {
97
98 case ATM_AAL0:
99 fvp->fv_aal = FORE_AAL_0;
100 break;
101
102 case ATM_AAL3_4:
103 fvp->fv_aal = FORE_AAL_4;
104 if ((ap->aal.v.aal4.forward_max_SDU_size > FORE_IFF_MTU) ||
105 (ap->aal.v.aal4.backward_max_SDU_size > FORE_IFF_MTU))
106 return (EINVAL);
107 break;
108
109 case ATM_AAL5:
110 fvp->fv_aal = FORE_AAL_5;
111 if ((ap->aal.v.aal5.forward_max_SDU_size > FORE_IFF_MTU) ||
112 (ap->aal.v.aal5.backward_max_SDU_size > FORE_IFF_MTU))
113 return (EINVAL);
114 break;
115
116 default:
117 return (EINVAL);
118 }
119
120 return (0);
121 }
122
123 static const u_int rate_tab[255] = {
124 353207, /* 0 */
125 312501, /* 1 */ 312501, /* 2 */
126 312501, /* 3 */ 312501, /* 4 */
127 312501, /* 5 */ 312501, /* 6 */
128 312501, /* 7 */ 312501, /* 8 */
129 312501, /* 9 */ 312501, /* 10 */
130 312501, /* 11 */ 312501, /* 12 */
131 312501, /* 13 */ 312501, /* 14 */
132 312501, /* 15 */ 312501, /* 16 */
133 312501, /* 17 */ 284091, /* 18 */
134 284091, /* 19 */ 284091, /* 20 */
135 284091, /* 21 */ 284091, /* 22 */
136 284091, /* 23 */ 284091, /* 24 */
137 284091, /* 25 */ 284091, /* 26 */
138 284091, /* 27 */ 284091, /* 28 */
139 284091, /* 29 */ 284091, /* 30 */
140 284091, /* 31 */ 284091, /* 32 */
141 284091, /* 33 */ 284091, /* 34 */
142 284091, /* 35 */ 284091, /* 36 */
143 284091, /* 37 */ 284091, /* 38 */
144 260417, /* 39 */ 260417, /* 40 */
145 260417, /* 41 */ 260417, /* 42 */
146 260417, /* 43 */ 260417, /* 44 */
147 260417, /* 45 */ 260417, /* 46 */
148 260417, /* 47 */ 260417, /* 48 */
149 260417, /* 49 */ 260417, /* 50 */
150 260417, /* 51 */ 260417, /* 52 */
151 260417, /* 53 */ 260417, /* 54 */
152 260417, /* 55 */ 240385, /* 56 */
153 240385, /* 57 */ 240385, /* 58 */
154 240385, /* 59 */ 240385, /* 60 */
155 240385, /* 61 */ 240385, /* 62 */
156 240385, /* 63 */ 240385, /* 64 */
157 240385, /* 65 */ 240385, /* 66 */
158 240385, /* 67 */ 240385, /* 68 */
159 240385, /* 69 */ 240385, /* 70 */
160 223215, /* 71 */ 223215, /* 72 */
161 223215, /* 73 */ 223215, /* 74 */
162 223215, /* 75 */ 223215, /* 76 */
163 223215, /* 77 */ 223215, /* 78 */
164 223215, /* 79 */ 223215, /* 80 */
165 223215, /* 81 */ 223215, /* 82 */
166 223215, /* 83 */ 208334, /* 84 */
167 208334, /* 85 */ 208334, /* 86 */
168 208334, /* 87 */ 208334, /* 88 */
169 208334, /* 89 */ 208334, /* 90 */
170 208334, /* 91 */ 208334, /* 92 */
171 208334, /* 93 */ 208334, /* 94 */
172 195313, /* 95 */ 195313, /* 96 */
173 195313, /* 97 */ 195313, /* 98 */
174 195313, /* 101 */ 195313, /* 102 */
175 195313, /* 103 */ 183824, /* 104 */
176 183824, /* 105 */ 183824, /* 106 */
177 183824, /* 107 */ 183824, /* 108 */
178 183824, /* 109 */ 183824, /* 110 */
179 183824, /* 111 */ 183824, /* 112 */
180 173612, /* 113 */ 173612, /* 114 */
181 173612, /* 115 */ 173612, /* 116 */
182 173612, /* 117 */ 173612, /* 118 */
183 173612, /* 119 */ 173612, /* 120 */
184 164474, /* 121 */ 164474, /* 122 */
185 164474, /* 123 */ 164474, /* 124 */
186 164474, /* 125 */ 164474, /* 126 */
187 164474, /* 127 */ 156250, /* 128 */
188 156250, /* 129 */ 156250, /* 130 */
189 156250, /* 131 */ 156250, /* 132 */
190 156250, /* 133 */ 148810, /* 134 */
191 148810, /* 135 */ 148810, /* 136 */
192 148810, /* 137 */ 148810, /* 138 */
193 148810, /* 139 */ 142046, /* 140 */
194 142046, /* 141 */ 142046, /* 142 */
195 142046, /* 143 */ 142046, /* 144 */
196 135870, /* 145 */ 135870, /* 146 */
197 135870, /* 147 */ 135870, /* 148 */
198 130209, /* 149 */ 130209, /* 150 */
199 130209, /* 151 */ 130209, /* 152 */
200 130209, /* 153 */ 125000, /* 154 */
201 125000, /* 155 */ 125000, /* 156 */
202 125000, /* 157 */ 120193, /* 158 */
203 120193, /* 159 */ 120193, /* 160 */
204 115741, /* 161 */ 115741, /* 162 */
205 115741, /* 163 */ 115741, /* 164 */
206 111608, /* 165 */ 111608, /* 166 */
207 111608, /* 167 */ 107759, /* 168 */
208 107759, /* 169 */ 107759, /* 170 */
209 104167, /* 171 */ 104167, /* 172 */
210 104167, /* 173 */ 100807, /* 174 */
211 100807, /* 175 */ 97657, /* 176 */
212 97657, /* 177 */ 97657, /* 178 */
213 94697, /* 179 */ 94697, /* 180 */
214 91912, /* 181 */ 91912, /* 182 */
215 89286, /* 183 */ 89286, /* 184 */
216 86806, /* 185 */ 86806, /* 186 */
217 84460, /* 187 */ 84460, /* 188 */
218 82237, /* 189 */ 82237, /* 190 */
219 80129, /* 191 */ 78125, /* 192 */
220 78126, /* 193 */ 76220, /* 194 */
221 74405, /* 195 */ 74405, /* 196 */
222 72675, /* 197 */ 71023, /* 198 */
223 69445, /* 199 */ 69445, /* 200 */
224 67935, /* 201 */ 66490, /* 202 */
225 65105, /* 203 */ 63776, /* 204 */
226 62500, /* 205 */ 61275, /* 206 */
227 60097, /* 207 */ 58963, /* 208 */
228 57871, /* 209 */ 56819, /* 210 */
229 54825, /* 211 */ 53880, /* 212 */
230 52967, /* 213 */ 51230, /* 214 */
231 50404, /* 215 */ 48829, /* 216 */
232 47349, /* 217 */ 46642, /* 218 */
233 45290, /* 219 */ 44015, /* 220 */
234 42809, /* 221 */ 41119, /* 222 */
235 40065, /* 223 */ 39063, /* 224 */
236 37651, /* 225 */ 36338, /* 226 */
237 35113, /* 227 */ 33968, /* 228 */
238 32553, /* 229 */ 31250, /* 230 */
239 30049, /* 231 */ 28936, /* 232 */
240 27655, /* 233 */ 26261, /* 234 */
241 25000, /* 235 */ 23855, /* 236 */
242 22645, /* 237 */ 21259, /* 238 */
243 20033, /* 239 */ 18826, /* 240 */
244 17557, /* 241 */ 16277, /* 242 */
245 15025, /* 243 */ 13767, /* 244 */
246 12551, /* 245 */ 11282, /* 246 */
247 10017, /* 247 */ 8779, /* 248 */
248 7531, /* 249 */ 6263, /* 250 */
249 5017, /* 251 */ 3761, /* 252 */
250 2509, /* 253 */ 1254, /* 254 */
251 };
252
253 /*
254 * Find the best match of the high part of the Rate Control Information
255 *
256 * This function is called when a VC is opened in order to help
257 * in converting Fore's rate to PCR.
258 * The Fore's Rate Control Information is encoded as 32-bit field
259 * comprised of two 16-bit subfields.
260 *
261 * Arguments:
262 * *pcr Peak Cell Rate, will be updated with actual value
263 *
264 * Returns:
265 * descr the rate descriptor
266 *
267 */
268 static uint32_t
269 pcr2rate(int32_t *pcr)
270 {
271 u_int i;
272
273 if (*pcr >= rate_tab[0]) {
274 /* special case link rate */
275 *pcr = rate_tab[0];
276 return (0);
277 }
278
279 for (i = 0; i < sizeof(rate_tab) / sizeof(rate_tab[0]); i++)
280 if (*pcr >= rate_tab[i])
281 break;
282 if (i == sizeof(rate_tab) / sizeof(rate_tab[0])) {
283 /* smaller than smallest */
284 i--;
285 }
286 /* update with the actual value */
287 *pcr = rate_tab[i];
288 return ((255 - i) << 16) | i;
289 }
290
291 /*
292 * Open a VCC
293 *
294 * This function is called via the common driver code after receiving a
295 * stack *_INIT command. The common code has already validated most of
296 * the request so we just need to check a few more Fore-specific details.
297 * Then we just issue the command to the CP. Note that we can't wait around
298 * for the CP to process the command, so we return success for now and abort
299 * the connection if the command later fails.
300 *
301 * Called at splimp.
302 *
303 * Arguments:
304 * cup pointer to device common unit
305 * cvp pointer to common VCC entry
306 *
307 * Returns:
308 * 0 open successful
309 * else open failed
310 *
311 */
312 int
313 fore_openvcc(cup, cvp)
314 Cmn_unit *cup;
315 Cmn_vcc *cvp;
316 {
317 Fore_unit *fup = (Fore_unit *)cup;
318 Fore_vcc *fvp = (Fore_vcc *)cvp;
319 H_cmd_queue *hcp;
320 Cmd_queue *cqp;
321 struct vccb *vcp;
322
323 vcp = fvp->fv_connvc->cvc_vcc;
324
325 ATM_DEBUG4("fore_openvcc: fup=%p, fvp=%p, vcc=(%d,%d)\n",
326 fup, fvp, vcp->vc_vpi, vcp->vc_vci);
327
328 /*
329 * Validate the VPI and VCI values
330 */
331 if ((vcp->vc_vpi > fup->fu_pif.pif_maxvpi) ||
332 (vcp->vc_vci > fup->fu_pif.pif_maxvci)) {
333 return (1);
334 }
335
336 /*
337 * Compute the PCR (but only for outgoing VCCs)
338 */
339 fvp->rate = FORE_DEF_RATE;
340 if ((vcp->vc_type & VCC_OUT) && cvp->cv_connvc) {
341 Atm_attributes *attr = &cvp->cv_connvc->cvc_attr;
342
343 if (attr && attr->traffic.v.forward.PCR_all_traffic > 0 &&
344 attr->traffic.v.forward.PCR_all_traffic < rate_tab[0] &&
345 (fup->fu_shape == FUS_SHAPE_ALL ||
346 (fup->fu_shape == FUS_SHAPE_ONE &&
347 fup->fu_num_shaped == 0))) {
348 fvp->rate = pcr2rate(&attr->traffic.v.forward.
349 PCR_all_traffic);
350 fup->fu_num_shaped++;
351 }
352 }
353
354 /*
355 * Only need to tell the CP about incoming VCCs
356 */
357 if ((vcp->vc_type & VCC_IN) == 0) {
358 DEVICE_LOCK((Cmn_unit *)fup);
359 fup->fu_open_vcc++;
360 fvp->fv_state = CVS_ACTIVE;
361 DEVICE_UNLOCK((Cmn_unit *)fup);
362 return (0);
363 }
364
365 /*
366 * Queue command at end of command queue
367 */
368 hcp = fup->fu_cmd_tail;
369 if ((*hcp->hcq_status) & QSTAT_FREE) {
370
371 /*
372 * Queue entry available, so set our view of things up
373 */
374 hcp->hcq_code = CMD_ACT_VCCIN;
375 hcp->hcq_arg = fvp;
376 fup->fu_cmd_tail = hcp->hcq_next;
377 fvp->fv_flags |= FVF_ACTCMD;
378
379 /*
380 * Now set the CP-resident queue entry - the CP will grab
381 * the command when the op-code is set.
382 */
383 cqp = hcp->hcq_cpelem;
384 (*hcp->hcq_status) = QSTAT_PENDING;
385 cqp->cmdq_act.act_vccid = CP_WRITE(vcp->vc_vci);
386 if (fvp->fv_aal == FORE_AAL_0)
387 cqp->cmdq_act.act_batch = CP_WRITE(1);
388 cqp->cmdq_act.act_spec = CP_WRITE(
389 ACT_SET_SPEC(BUF_STRAT_1, fvp->fv_aal,
390 CMD_ACT_VCCIN | CMD_INTR_REQ));
391 } else {
392 /*
393 * Command queue full
394 */
395 fup->fu_stats->st_drv.drv_cm_full++;
396 return (1);
397 }
398
399 return (0);
400 }
401
402
403 /*
404 * Close a VCC
405 *
406 * This function is called via the common driver code after receiving a
407 * stack *_TERM command. The common code has already validated most of
408 * the request so we just need to check a few more Fore-specific details.
409 * Then we just issue the command to the CP. Note that we can't wait around
410 * for the CP to process the command, so we return success for now and whine
411 * if the command later fails.
412 *
413 * Called at splimp.
414 *
415 * Arguments:
416 * cup pointer to device common unit
417 * cvp pointer to common VCC entry
418 *
419 * Returns:
420 * 0 close successful
421 * else close failed
422 *
423 */
424 int
425 fore_closevcc(cup, cvp)
426 Cmn_unit *cup;
427 Cmn_vcc *cvp;
428 {
429 Fore_unit *fup = (Fore_unit *)cup;
430 Fore_vcc *fvp = (Fore_vcc *)cvp;
431 H_xmit_queue *hxp;
432 H_cmd_queue *hcp;
433 Cmd_queue *cqp;
434 struct vccb *vcp;
435 int i, err = 0;
436
437 vcp = fvp->fv_connvc->cvc_vcc;
438
439 ATM_DEBUG4("fore_closevcc: fup=%p, fvp=%p, vcc=(%d,%d)\n",
440 fup, fvp, vcp->vc_vpi, vcp->vc_vci);
441
442 DEVICE_LOCK((Cmn_unit *)fup);
443
444 /*
445 * Clear any references to this VCC in our transmit queue
446 */
447 for (hxp = fup->fu_xmit_head, i = 0;
448 (*hxp->hxq_status != QSTAT_FREE) && (i < XMIT_QUELEN);
449 hxp = hxp->hxq_next, i++) {
450 if (hxp->hxq_vcc == fvp) {
451 hxp->hxq_vcc = NULL;
452 }
453 }
454
455 /*
456 * Clear any references to this VCC in our command queue
457 */
458 for (hcp = fup->fu_cmd_head, i = 0;
459 (*hcp->hcq_status != QSTAT_FREE) && (i < CMD_QUELEN);
460 hcp = hcp->hcq_next, i++) {
461 switch (hcp->hcq_code) {
462
463 case CMD_ACT_VCCIN:
464 case CMD_ACT_VCCOUT:
465 if (hcp->hcq_arg == fvp) {
466 hcp->hcq_arg = NULL;
467 }
468 break;
469 }
470 }
471
472 /*
473 * If this VCC has been previously activated, then we need to tell
474 * the CP to deactivate it.
475 */
476 if (fvp->fv_flags & FVF_ACTCMD) {
477
478 /*
479 * Queue command at end of command queue
480 */
481 hcp = fup->fu_cmd_tail;
482 if ((*hcp->hcq_status) & QSTAT_FREE) {
483
484 /*
485 * Queue entry available, so set our view of things up
486 */
487 hcp->hcq_code = CMD_DACT_VCCIN;
488 hcp->hcq_arg = fvp;
489 fup->fu_cmd_tail = hcp->hcq_next;
490
491 /*
492 * Now set the CP-resident queue entry - the CP will
493 * grab the command when the op-code is set.
494 */
495 cqp = hcp->hcq_cpelem;
496 (*hcp->hcq_status) = QSTAT_PENDING;
497 cqp->cmdq_dact.dact_vccid = CP_WRITE(vcp->vc_vci);
498 cqp->cmdq_dact.dact_cmd =
499 CP_WRITE(CMD_DACT_VCCIN|CMD_INTR_REQ);
500 } else {
501 /*
502 * Command queue full
503 *
504 * If we get here, we'll be getting out-of-sync with
505 * the CP because we can't (for now at least) do
506 * anything about close errors in the common code.
507 * This won't be too bad, since we'll just toss any
508 * PDUs received from the VCC and the sigmgr's will
509 * always get open failures when trying to use this
510 * (vpi,vci)...oh, well...always gotta have that one
511 * last bug to fix! XXX
512 */
513 fup->fu_stats->st_drv.drv_cm_full++;
514 err = 1;
515 }
516 }
517
518 /*
519 * Finish up...
520 */
521 if (fvp->fv_state == CVS_ACTIVE)
522 fup->fu_open_vcc--;
523
524 if (fvp->rate != 0)
525 fup->fu_num_shaped--;
526
527 DEVICE_UNLOCK((Cmn_unit *)fup);
528
529 return (err);
530 }
531
Cache object: 6f1a30dc3eed65eb811c5d46f73de202
|