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