int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
			  int fs)
{
	void			*p ;		
	struct smt_p_0016	*cmd ;		
	SMbuf			*db ;
	u_long			msg_res_type ;	
	u_long			payload, overhead ;
	int			local ;
	int			i ;

	 local = ((fs & L_INDICATOR) != 0) ;

	if (!(p = (void *) sm_to_para(smc,sm,SMT_P0015))) {
		DB_ESS("ESS: RAF frame error, parameter type not found\n",0,0) ;
		return fs;
	}
	msg_res_type = ((struct smt_p_0015 *)p)->res_type ;

	if (!(cmd = (struct smt_p_0016 *) sm_to_para(smc,sm,SMT_P0016))) {
		 DB_ESS("ESS: RAF frame error, parameter command not found\n",0,0);
		 return fs;
	}

	DB_ESSN(2,"fc %x	ft %x\n",sm->smt_class,sm->smt_type) ;
	DB_ESSN(2,"ver %x	tran %lx\n",sm->smt_version,sm->smt_tid) ;
	DB_ESSN(2,"stn_id %s\n",addr_to_string(&sm->smt_source),0) ;

	DB_ESSN(2,"infolen %x	res %x\n",sm->smt_len, msg_res_type) ;
	DB_ESSN(2,"sbacmd %x\n",cmd->sba_cmd,0) ;

	switch (cmd->sba_cmd) {

	case REQUEST_ALLOCATION :
		if (sm->smt_type == SMT_REQUEST) {
			if (!local || smc->mib.fddiESSPayload)
				return fs;
			
			p = (void *) sm_to_para(smc,sm,SMT_P0019)  ;
			for (i = 0; i < 5; i++) {
				if (((struct smt_p_0019 *)p)->alloc_addr.a[i]) {
					return fs;
				}
			}

			smc->ess.alloc_trans_id = sm->smt_tid ;
			DB_ESS("ESS: save Alloc Req Trans ID %lx\n",sm->smt_tid,0);
			p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
			((struct smt_p_320f *)p)->mib_payload =
				smc->mib.a[PATH0].fddiPATHSbaPayload ;
			p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
			((struct smt_p_3210 *)p)->mib_overhead =
				smc->mib.a[PATH0].fddiPATHSbaOverhead ;
			sm->smt_dest = smt_sba_da ;

			if (smc->ess.local_sba_active)
				return fs | I_INDICATOR;

			if (!(db = smt_get_mbuf(smc)))
				return fs;

			db->sm_len = mb->sm_len ;
			db->sm_off = mb->sm_off ;
			memcpy(((char *)(db->sm_data+db->sm_off)),(char *)sm,
				(int)db->sm_len) ;
			dump_smt(smc,
				(struct smt_header *)(db->sm_data+db->sm_off),
				"RAF") ;
			smt_send_frame(smc,db,FC_SMT_INFO,0) ;
			return fs;
		}

		if (smt_check_para(smc,sm,plist_raf_alc_res)) {
			DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
			return fs;
		}

		if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
			!= PRIMARY_RING) ||
			(msg_res_type != SYNC_BW) ||
		(((struct smt_p_reason *)sm_to_para(smc,sm,SMT_P0012))->rdf_reason
			!= SMT_RDF_SUCCESS) ||
			(sm->smt_tid != smc->ess.alloc_trans_id)) {

			DB_ESS("ESS: Allocation Response not accepted\n",0,0) ;
			return fs;
		}

		p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
                if (!p) {
                        printk(KERN_ERR "ESS: sm_to_para failed");
                        return fs;
                }       
		payload = ((struct smt_p_320f *)p)->mib_payload ;
		p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
                if (!p) {
                        printk(KERN_ERR "ESS: sm_to_para failed");
                        return fs;
                }       
		overhead = ((struct smt_p_3210 *)p)->mib_overhead ;

		DB_ESSN(2,"payload= %lx	overhead= %lx\n",payload,overhead) ;

		(void)process_bw_alloc(smc,(long)payload,(long)overhead) ;

		return fs;
		

	case CHANGE_ALLOCATION :
		if (sm->smt_type != SMT_REQUEST) {
			DB_ESS("ESS: Do not process Change Responses\n",0,0) ;
			return fs;
		}

		if (smt_check_para(smc,sm,plist_raf_chg_req)) {
			DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
			return fs;
		}

		if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
			!= PRIMARY_RING) || (msg_res_type != SYNC_BW)) {
			DB_ESS("ESS: RAF frame with para problem, ignoring\n",0,0) ;
			return fs;
		}

		p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
		payload = ((struct smt_p_320f *)p)->mib_payload ;
		p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
		overhead = ((struct smt_p_3210 *)p)->mib_overhead ;

		DB_ESSN(2,"ESS: Change Request from %s\n",
			addr_to_string(&sm->smt_source),0) ;
		DB_ESSN(2,"payload= %lx	overhead= %lx\n",payload,overhead) ;

		if(!process_bw_alloc(smc,(long)payload,(long)overhead))
			return fs;

		ess_send_response(smc,sm,CHANGE_ALLOCATION) ;

		return fs;
		

	case REPORT_ALLOCATION :
		if (sm->smt_type != SMT_REQUEST) {
			DB_ESS("ESS: Do not process a Report Reply\n",0,0) ;
			return fs;
		}

		DB_ESSN(2,"ESS: Report Request from %s\n",
			addr_to_string(&(sm->smt_source)),0) ;

		if (msg_res_type != SYNC_BW) {
			DB_ESS("ESS: ignoring RAF with para problem\n",0,0) ;
			return fs;
		}

		ess_send_response(smc,sm,REPORT_ALLOCATION) ;

		return fs;
		

	default:
		DB_ESS("ESS: ignoring RAF with bad sba_cmd\n",0,0) ;
		break ;
	}

	return fs;
}
Example #2
0
/*
 * evaluate the RAF frame
 */
int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
			  int fs)
{
	void			*p ;		/* universal pointer */
	struct smt_p_0016	*cmd ;		/* para: command for the ESS */
	SMbuf			*db ;
	u_long			msg_res_type ;	/* recource type */
	u_long			payload, overhead ;
	int			local ;
	int			i ;

	/*
	 * Message Processing Code
	 */
	 local = ((fs & L_INDICATOR) != 0) ;

	/*
	 * get the resource type
	 */
	if (!(p = (void *) sm_to_para(smc,sm,SMT_P0015))) {
		DB_ESS("ESS: RAF frame error, parameter type not found\n",0,0) ;
		return fs;
	}
	msg_res_type = ((struct smt_p_0015 *)p)->res_type ;

	/*
	 * get the pointer to the ESS command
	 */
	if (!(cmd = (struct smt_p_0016 *) sm_to_para(smc,sm,SMT_P0016))) {
		/*
		 * error in frame: para ESS command was not found
		 */
		 DB_ESS("ESS: RAF frame error, parameter command not found\n",0,0);
		 return fs;
	}

	DB_ESSN(2,"fc %x	ft %x\n",sm->smt_class,sm->smt_type) ;
	DB_ESSN(2,"ver %x	tran %lx\n",sm->smt_version,sm->smt_tid) ;
	DB_ESSN(2,"stn_id %s\n",addr_to_string(&sm->smt_source),0) ;

	DB_ESSN(2,"infolen %x	res %x\n",sm->smt_len, msg_res_type) ;
	DB_ESSN(2,"sbacmd %x\n",cmd->sba_cmd,0) ;

	/*
	 * evaluate the ESS command
	 */
	switch (cmd->sba_cmd) {

	/*
	 * Process an ESS Allocation Request
	 */
	case REQUEST_ALLOCATION :
		/*
		 * check for an RAF Request (Allocation Request)
		 */
		if (sm->smt_type == SMT_REQUEST) {
			/*
			 * process the Allocation request only if the frame is
			 * local and no static allocation is used
			 */
			if (!local || smc->mib.fddiESSPayload)
				return fs;

			p = (void *) sm_to_para(smc,sm,SMT_P0019)  ;
			for (i = 0; i < 5; i++) {
				if (((struct smt_p_0019 *)p)->alloc_addr.a[i]) {
					return fs;
				}
			}

			/*
			 * Note: The Application should send a LAN_LOC_FRAME.
			 *	 The ESS do not send the Frame to the network!
			 */
			smc->ess.alloc_trans_id = sm->smt_tid ;
			DB_ESS("ESS: save Alloc Req Trans ID %lx\n",sm->smt_tid,0);
			p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
			((struct smt_p_320f *)p)->mib_payload =
				smc->mib.a[PATH0].fddiPATHSbaPayload ;
			p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
			((struct smt_p_3210 *)p)->mib_overhead =
				smc->mib.a[PATH0].fddiPATHSbaOverhead ;
			sm->smt_dest = smt_sba_da ;

			if (smc->ess.local_sba_active)
				return fs | I_INDICATOR;

			if (!(db = smt_get_mbuf(smc)))
				return fs;

			db->sm_len = mb->sm_len ;
			db->sm_off = mb->sm_off ;
			memcpy(((char *)(db->sm_data+db->sm_off)),(char *)sm,
				(int)db->sm_len) ;
			dump_smt(smc,
				(struct smt_header *)(db->sm_data+db->sm_off),
				"RAF") ;
			smt_send_frame(smc,db,FC_SMT_INFO,0) ;
			return fs;
		}

		/*
		 * The RAF frame is an Allocation Response !
		 * check the parameters
		 */
		if (smt_check_para(smc,sm,plist_raf_alc_res)) {
			DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
			return fs;
		}

		/*
		 * VERIFY THE FRAME IS WELL BUILT:
		 *
		 *	1. path index = primary ring only
		 *	2. resource type = sync bw only
		 *	3. trans action id = alloc_trans_id
		 *	4. reason code = success
		 *
		 * If any are violated, discard the RAF frame
		 */
		if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
			!= PRIMARY_RING) ||
			(msg_res_type != SYNC_BW) ||
		(((struct smt_p_reason *)sm_to_para(smc,sm,SMT_P0012))->rdf_reason
			!= SMT_RDF_SUCCESS) ||
			(sm->smt_tid != smc->ess.alloc_trans_id)) {

			DB_ESS("ESS: Allocation Response not accepted\n",0,0) ;
			return fs;
		}

		/*
		 * Extract message parameters
		 */
		p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
                if (!p) {
                        printk(KERN_ERR "ESS: sm_to_para failed");
                        return fs;
                }
		payload = ((struct smt_p_320f *)p)->mib_payload ;
		p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
                if (!p) {
                        printk(KERN_ERR "ESS: sm_to_para failed");
                        return fs;
                }
		overhead = ((struct smt_p_3210 *)p)->mib_overhead ;

		DB_ESSN(2,"payload= %lx	overhead= %lx\n",payload,overhead) ;

		/*
		 * process the bandwidth allocation
		 */
		(void)process_bw_alloc(smc,(long)payload,(long)overhead) ;

		return fs;
		/* end of Process Allocation Request */

	/*
	 * Process an ESS Change Request
	 */
	case CHANGE_ALLOCATION :
		/*
		 * except only replies
		 */
		if (sm->smt_type != SMT_REQUEST) {
			DB_ESS("ESS: Do not process Change Responses\n",0,0) ;
			return fs;
		}

		/*
		 * check the para for the Change Request
		 */
		if (smt_check_para(smc,sm,plist_raf_chg_req)) {
			DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
			return fs;
		}

		/*
		 * Verify the path index and resource
		 * type are correct. If any of
		 * these are false, don't process this
		 * change request frame.
		 */
		if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
			!= PRIMARY_RING) || (msg_res_type != SYNC_BW)) {
			DB_ESS("ESS: RAF frame with para problem, ignoring\n",0,0) ;
			return fs;
		}

		/*
		 * Extract message queue parameters
		 */
		p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
		payload = ((struct smt_p_320f *)p)->mib_payload ;
		p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
		overhead = ((struct smt_p_3210 *)p)->mib_overhead ;

		DB_ESSN(2,"ESS: Change Request from %s\n",
			addr_to_string(&sm->smt_source),0) ;
		DB_ESSN(2,"payload= %lx	overhead= %lx\n",payload,overhead) ;

		/*
		 * process the bandwidth allocation
		 */
		if(!process_bw_alloc(smc,(long)payload,(long)overhead))
			return fs;

		/*
		 * send an RAF Change Reply
		 */
		ess_send_response(smc,sm,CHANGE_ALLOCATION) ;

		return fs;
		/* end of Process Change Request */

	/*
	 * Process Report Response
	 */
	case REPORT_ALLOCATION :
		/*
		 * except only requests
		 */
		if (sm->smt_type != SMT_REQUEST) {
			DB_ESS("ESS: Do not process a Report Reply\n",0,0) ;
			return fs;
		}

		DB_ESSN(2,"ESS: Report Request from %s\n",
			addr_to_string(&(sm->smt_source)),0) ;

		/*
		 * verify that the resource type is sync bw only
		 */
		if (msg_res_type != SYNC_BW) {
			DB_ESS("ESS: ignoring RAF with para problem\n",0,0) ;
			return fs;
		}

		/*
		 * send an RAF Change Reply
		 */
		ess_send_response(smc,sm,REPORT_ALLOCATION) ;

		return fs;
		/* end of Process Report Request */

	default:
		/*
		 * error in frame
		 */
		DB_ESS("ESS: ignoring RAF with bad sba_cmd\n",0,0) ;
		break ;
	}

	return fs;
}