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