1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include "h/types.h"
37#include "h/fddi.h"
38#include "h/smc.h"
39#include "h/smt_p.h"
40
41
42#ifndef SLIM_SMT
43
44#ifdef ESS
45
46#ifndef lint
47static const char ID_sccs[] = "@(#)ess.c 1.10 96/02/23 (C) SK" ;
48#define LINT_USE(x)
49#else
50#define LINT_USE(x) (x)=(x)
51#endif
52#define MS2BCLK(x) ((x)*12500L)
53
54
55
56
57
58
59
60static const u_short plist_raf_alc_res[] = { SMT_P0012, SMT_P320B, SMT_P320F,
61 SMT_P3210, SMT_P0019, SMT_P001A,
62 SMT_P001D, 0 } ;
63
64static const u_short plist_raf_chg_req[] = { SMT_P320B, SMT_P320F, SMT_P3210,
65 SMT_P001A, 0 } ;
66
67static const struct fddi_addr smt_sba_da = {{0x80,0x01,0x43,0x00,0x80,0x0C}} ;
68static const struct fddi_addr null_addr = {{0,0,0,0,0,0}} ;
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83static void ess_send_response(struct s_smc *smc, struct smt_header *sm,
84 int sba_cmd);
85static void ess_config_fifo(struct s_smc *smc);
86static void ess_send_alc_req(struct s_smc *smc);
87static void ess_send_frame(struct s_smc *smc, SMbuf *mb);
88
89
90
91
92
93
94
95
96
97
98
99
100
101void ess_timer_poll(struct s_smc *smc);
102void ess_para_change(struct s_smc *smc);
103int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
104 int fs);
105static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead);
106
107
108
109
110
111
112
113
114
115
116
117int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
118 int fs)
119{
120 void *p ;
121 struct smt_p_0016 *cmd ;
122 SMbuf *db ;
123 u_long msg_res_type ;
124 u_long payload, overhead ;
125 int local ;
126 int i ;
127
128
129
130
131 local = ((fs & L_INDICATOR) != 0) ;
132
133
134
135
136 if (!(p = (void *) sm_to_para(smc,sm,SMT_P0015))) {
137 DB_ESS("ESS: RAF frame error, parameter type not found");
138 return fs;
139 }
140 msg_res_type = ((struct smt_p_0015 *)p)->res_type ;
141
142
143
144
145 if (!(cmd = (struct smt_p_0016 *) sm_to_para(smc,sm,SMT_P0016))) {
146
147
148
149 DB_ESS("ESS: RAF frame error, parameter command not found");
150 return fs;
151 }
152
153 DB_ESSN(2, "fc %x ft %x", sm->smt_class, sm->smt_type);
154 DB_ESSN(2, "ver %x tran %x", sm->smt_version, sm->smt_tid);
155 DB_ESSN(2, "stn_id %s", addr_to_string(&sm->smt_source));
156
157 DB_ESSN(2, "infolen %x res %lx", sm->smt_len, msg_res_type);
158 DB_ESSN(2, "sbacmd %x", cmd->sba_cmd);
159
160
161
162
163 switch (cmd->sba_cmd) {
164
165
166
167
168 case REQUEST_ALLOCATION :
169
170
171
172 if (sm->smt_type == SMT_REQUEST) {
173
174
175
176
177 if (!local || smc->mib.fddiESSPayload)
178 return fs;
179
180 p = (void *) sm_to_para(smc,sm,SMT_P0019) ;
181 for (i = 0; i < 5; i++) {
182 if (((struct smt_p_0019 *)p)->alloc_addr.a[i]) {
183 return fs;
184 }
185 }
186
187
188
189
190
191 smc->ess.alloc_trans_id = sm->smt_tid ;
192 DB_ESS("ESS: save Alloc Req Trans ID %x", sm->smt_tid);
193 p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
194 ((struct smt_p_320f *)p)->mib_payload =
195 smc->mib.a[PATH0].fddiPATHSbaPayload ;
196 p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
197 ((struct smt_p_3210 *)p)->mib_overhead =
198 smc->mib.a[PATH0].fddiPATHSbaOverhead ;
199 sm->smt_dest = smt_sba_da ;
200
201 if (smc->ess.local_sba_active)
202 return fs | I_INDICATOR;
203
204 if (!(db = smt_get_mbuf(smc)))
205 return fs;
206
207 db->sm_len = mb->sm_len ;
208 db->sm_off = mb->sm_off ;
209 memcpy(((char *)(db->sm_data+db->sm_off)),(char *)sm,
210 (int)db->sm_len) ;
211 dump_smt(smc,
212 (struct smt_header *)(db->sm_data+db->sm_off),
213 "RAF") ;
214 smt_send_frame(smc,db,FC_SMT_INFO,0) ;
215 return fs;
216 }
217
218
219
220
221
222 if (smt_check_para(smc,sm,plist_raf_alc_res)) {
223 DB_ESS("ESS: RAF with para problem, ignoring");
224 return fs;
225 }
226
227
228
229
230
231
232
233
234
235
236
237 if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
238 != PRIMARY_RING) ||
239 (msg_res_type != SYNC_BW) ||
240 (((struct smt_p_reason *)sm_to_para(smc,sm,SMT_P0012))->rdf_reason
241 != SMT_RDF_SUCCESS) ||
242 (sm->smt_tid != smc->ess.alloc_trans_id)) {
243
244 DB_ESS("ESS: Allocation Response not accepted");
245 return fs;
246 }
247
248
249
250
251 p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
252 if (!p) {
253 printk(KERN_ERR "ESS: sm_to_para failed");
254 return fs;
255 }
256 payload = ((struct smt_p_320f *)p)->mib_payload ;
257 p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
258 if (!p) {
259 printk(KERN_ERR "ESS: sm_to_para failed");
260 return fs;
261 }
262 overhead = ((struct smt_p_3210 *)p)->mib_overhead ;
263
264 DB_ESSN(2, "payload= %lx overhead= %lx",
265 payload, overhead);
266
267
268
269
270 (void)process_bw_alloc(smc,(long)payload,(long)overhead) ;
271
272 return fs;
273
274
275
276
277
278 case CHANGE_ALLOCATION :
279
280
281
282 if (sm->smt_type != SMT_REQUEST) {
283 DB_ESS("ESS: Do not process Change Responses");
284 return fs;
285 }
286
287
288
289
290 if (smt_check_para(smc,sm,plist_raf_chg_req)) {
291 DB_ESS("ESS: RAF with para problem, ignoring");
292 return fs;
293 }
294
295
296
297
298
299
300
301 if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
302 != PRIMARY_RING) || (msg_res_type != SYNC_BW)) {
303 DB_ESS("ESS: RAF frame with para problem, ignoring");
304 return fs;
305 }
306
307
308
309
310 p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
311 payload = ((struct smt_p_320f *)p)->mib_payload ;
312 p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
313 overhead = ((struct smt_p_3210 *)p)->mib_overhead ;
314
315 DB_ESSN(2, "ESS: Change Request from %s",
316 addr_to_string(&sm->smt_source));
317 DB_ESSN(2, "payload= %lx overhead= %lx",
318 payload, overhead);
319
320
321
322
323 if(!process_bw_alloc(smc,(long)payload,(long)overhead))
324 return fs;
325
326
327
328
329 ess_send_response(smc,sm,CHANGE_ALLOCATION) ;
330
331 return fs;
332
333
334
335
336
337 case REPORT_ALLOCATION :
338
339
340
341 if (sm->smt_type != SMT_REQUEST) {
342 DB_ESS("ESS: Do not process a Report Reply");
343 return fs;
344 }
345
346 DB_ESSN(2, "ESS: Report Request from %s",
347 addr_to_string(&sm->smt_source));
348
349
350
351
352 if (msg_res_type != SYNC_BW) {
353 DB_ESS("ESS: ignoring RAF with para problem");
354 return fs;
355 }
356
357
358
359
360 ess_send_response(smc,sm,REPORT_ALLOCATION) ;
361
362 return fs;
363
364
365 default:
366
367
368
369 DB_ESS("ESS: ignoring RAF with bad sba_cmd");
370 break ;
371 }
372
373 return fs;
374}
375
376
377
378
379
380static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead)
381{
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431 if (payload > MAX_PAYLOAD || overhead > 5000) {
432 DB_ESS("ESS: payload / overhead not accepted");
433 return FALSE;
434 }
435
436
437
438
439
440 if (smc->mib.fddiESSPayload &&
441 ((u_long)payload != smc->mib.fddiESSPayload ||
442 (u_long)overhead != smc->mib.fddiESSOverhead)) {
443 smc->ess.raf_act_timer_poll = TRUE ;
444 smc->ess.timer_count = 0 ;
445 }
446
447
448
449
450 if (payload) {
451 DB_ESSN(2, "ESS: turn SMT_ST_SYNC_SERVICE bit on");
452 smc->ess.sync_bw_available = TRUE ;
453
454 smc->ess.sync_bw = overhead -
455 (long)smc->mib.m[MAC0].fddiMACT_Neg *
456 payload / 1562 ;
457 }
458 else {
459 DB_ESSN(2, "ESS: turn SMT_ST_SYNC_SERVICE bit off");
460 smc->ess.sync_bw_available = FALSE ;
461 smc->ess.sync_bw = 0 ;
462 overhead = 0 ;
463 }
464
465 smc->mib.a[PATH0].fddiPATHSbaPayload = payload ;
466 smc->mib.a[PATH0].fddiPATHSbaOverhead = overhead ;
467
468
469 DB_ESSN(2, "tsync = %lx", smc->ess.sync_bw);
470
471 ess_config_fifo(smc) ;
472 set_formac_tsync(smc,smc->ess.sync_bw) ;
473 return TRUE;
474}
475
476static void ess_send_response(struct s_smc *smc, struct smt_header *sm,
477 int sba_cmd)
478{
479 struct smt_sba_chg *chg ;
480 SMbuf *mb ;
481 void *p ;
482
483
484
485
486 if (sba_cmd == CHANGE_ALLOCATION) {
487 if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REPLY,
488 sizeof(struct smt_sba_chg))))
489 return ;
490 }
491 else {
492 if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REPLY,
493 sizeof(struct smt_sba_rep_res))))
494 return ;
495 }
496
497 chg = smtod(mb,struct smt_sba_chg *) ;
498 chg->smt.smt_tid = sm->smt_tid ;
499 chg->smt.smt_dest = sm->smt_source ;
500
501
502 chg->s_type.para.p_type = SMT_P0015 ;
503 chg->s_type.para.p_len = sizeof(struct smt_p_0015) - PARA_LEN ;
504 chg->s_type.res_type = SYNC_BW ;
505
506
507 chg->cmd.para.p_type = SMT_P0016 ;
508 chg->cmd.para.p_len = sizeof(struct smt_p_0016) - PARA_LEN ;
509 chg->cmd.sba_cmd = sba_cmd ;
510
511
512 chg->path.para.p_type = SMT_P320B ;
513 chg->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ;
514 chg->path.mib_index = SBAPATHINDEX ;
515 chg->path.path_pad = 0;
516 chg->path.path_index = PRIMARY_RING ;
517
518
519 chg->payload.para.p_type = SMT_P320F ;
520 chg->payload.para.p_len = sizeof(struct smt_p_320f) - PARA_LEN ;
521 chg->payload.mib_index = SBAPATHINDEX ;
522 chg->payload.mib_payload = smc->mib.a[PATH0].fddiPATHSbaPayload ;
523
524
525 chg->overhead.para.p_type = SMT_P3210 ;
526 chg->overhead.para.p_len = sizeof(struct smt_p_3210) - PARA_LEN ;
527 chg->overhead.mib_index = SBAPATHINDEX ;
528 chg->overhead.mib_overhead = smc->mib.a[PATH0].fddiPATHSbaOverhead ;
529
530 if (sba_cmd == CHANGE_ALLOCATION) {
531
532 chg->cat.para.p_type = SMT_P001A ;
533 chg->cat.para.p_len = sizeof(struct smt_p_001a) - PARA_LEN ;
534 p = (void *) sm_to_para(smc,sm,SMT_P001A) ;
535 chg->cat.category = ((struct smt_p_001a *)p)->category ;
536 }
537 dump_smt(smc,(struct smt_header *)chg,"RAF") ;
538 ess_send_frame(smc,mb) ;
539}
540
541void ess_timer_poll(struct s_smc *smc)
542{
543 if (!smc->ess.raf_act_timer_poll)
544 return ;
545
546 DB_ESSN(2, "ESS: timer_poll");
547
548 smc->ess.timer_count++ ;
549 if (smc->ess.timer_count == 10) {
550 smc->ess.timer_count = 0 ;
551 ess_send_alc_req(smc) ;
552 }
553}
554
555static void ess_send_alc_req(struct s_smc *smc)
556{
557 struct smt_sba_alc_req *req ;
558 SMbuf *mb ;
559
560
561
562
563
564
565 if (!smc->mib.fddiESSPayload) {
566 smc->mib.fddiESSOverhead = 0 ;
567 }
568 else {
569 if (!smc->mib.fddiESSOverhead)
570 smc->mib.fddiESSOverhead = DEFAULT_OV ;
571 }
572
573 if (smc->mib.fddiESSOverhead ==
574 smc->mib.a[PATH0].fddiPATHSbaOverhead &&
575 smc->mib.fddiESSPayload ==
576 smc->mib.a[PATH0].fddiPATHSbaPayload){
577 smc->ess.raf_act_timer_poll = FALSE ;
578 smc->ess.timer_count = 7 ;
579 return ;
580 }
581
582
583
584
585 if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REQUEST,
586 sizeof(struct smt_sba_alc_req))))
587 return ;
588 req = smtod(mb,struct smt_sba_alc_req *) ;
589 req->smt.smt_tid = smc->ess.alloc_trans_id = smt_get_tid(smc) ;
590 req->smt.smt_dest = smt_sba_da ;
591
592
593 req->s_type.para.p_type = SMT_P0015 ;
594 req->s_type.para.p_len = sizeof(struct smt_p_0015) - PARA_LEN ;
595 req->s_type.res_type = SYNC_BW ;
596
597
598 req->cmd.para.p_type = SMT_P0016 ;
599 req->cmd.para.p_len = sizeof(struct smt_p_0016) - PARA_LEN ;
600 req->cmd.sba_cmd = REQUEST_ALLOCATION ;
601
602
603
604
605
606
607
608 req->path.para.p_type = SMT_P320B ;
609 req->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ;
610 req->path.mib_index = SBAPATHINDEX ;
611 req->path.path_pad = 0;
612 req->path.path_index = PRIMARY_RING ;
613
614
615 req->pl_req.para.p_type = SMT_P0017 ;
616 req->pl_req.para.p_len = sizeof(struct smt_p_0017) - PARA_LEN ;
617 req->pl_req.sba_pl_req = smc->mib.fddiESSPayload -
618 smc->mib.a[PATH0].fddiPATHSbaPayload ;
619
620
621 req->ov_req.para.p_type = SMT_P0018 ;
622 req->ov_req.para.p_len = sizeof(struct smt_p_0018) - PARA_LEN ;
623 req->ov_req.sba_ov_req = smc->mib.fddiESSOverhead -
624 smc->mib.a[PATH0].fddiPATHSbaOverhead ;
625
626
627 req->payload.para.p_type = SMT_P320F ;
628 req->payload.para.p_len = sizeof(struct smt_p_320f) - PARA_LEN ;
629 req->payload.mib_index = SBAPATHINDEX ;
630 req->payload.mib_payload = smc->mib.a[PATH0].fddiPATHSbaPayload ;
631
632
633 req->overhead.para.p_type = SMT_P3210 ;
634 req->overhead.para.p_len = sizeof(struct smt_p_3210) - PARA_LEN ;
635 req->overhead.mib_index = SBAPATHINDEX ;
636 req->overhead.mib_overhead = smc->mib.a[PATH0].fddiPATHSbaOverhead ;
637
638
639 req->a_addr.para.p_type = SMT_P0019 ;
640 req->a_addr.para.p_len = sizeof(struct smt_p_0019) - PARA_LEN ;
641 req->a_addr.sba_pad = 0;
642 req->a_addr.alloc_addr = null_addr ;
643
644
645 req->cat.para.p_type = SMT_P001A ;
646 req->cat.para.p_len = sizeof(struct smt_p_001a) - PARA_LEN ;
647 req->cat.category = smc->mib.fddiESSCategory ;
648
649
650 req->tneg.para.p_type = SMT_P001B ;
651 req->tneg.para.p_len = sizeof(struct smt_p_001b) - PARA_LEN ;
652 req->tneg.max_t_neg = smc->mib.fddiESSMaxTNeg ;
653
654
655 req->segm.para.p_type = SMT_P001C ;
656 req->segm.para.p_len = sizeof(struct smt_p_001c) - PARA_LEN ;
657 req->segm.min_seg_siz = smc->mib.fddiESSMinSegmentSize ;
658
659 dump_smt(smc,(struct smt_header *)req,"RAF") ;
660 ess_send_frame(smc,mb) ;
661}
662
663static void ess_send_frame(struct s_smc *smc, SMbuf *mb)
664{
665
666
667
668 if (smc->ess.local_sba_active) {
669
670
671
672 DB_ESS("ESS:Send to the local SBA");
673 if (!smc->ess.sba_reply_pend)
674 smc->ess.sba_reply_pend = mb ;
675 else {
676 DB_ESS("Frame is lost - another frame was pending");
677 smt_free_mbuf(smc,mb) ;
678 }
679 }
680 else {
681
682
683
684 DB_ESS("ESS:Send to the network");
685 smt_send_frame(smc,mb,FC_SMT_INFO,0) ;
686 }
687}
688
689void ess_para_change(struct s_smc *smc)
690{
691 (void)process_bw_alloc(smc,(long)smc->mib.a[PATH0].fddiPATHSbaPayload,
692 (long)smc->mib.a[PATH0].fddiPATHSbaOverhead) ;
693}
694
695static void ess_config_fifo(struct s_smc *smc)
696{
697
698
699
700 if (smc->mib.a[PATH0].fddiPATHSbaPayload) {
701 if (smc->hw.fp.fifo.fifo_config_mode & SYNC_TRAFFIC_ON &&
702 (smc->hw.fp.fifo.fifo_config_mode&SEND_ASYNC_AS_SYNC) ==
703 smc->mib.fddiESSSynchTxMode) {
704 return ;
705 }
706 }
707 else {
708 if (!(smc->hw.fp.fifo.fifo_config_mode & SYNC_TRAFFIC_ON)) {
709 return ;
710 }
711 }
712
713
714
715
716 formac_reinit_tx(smc) ;
717}
718
719#endif
720
721#endif
722
723