📄 ess.c
字号:
/****************************************************************************** * * (C)Copyright 1998,1999 SysKonnect, * a business unit of Schneider & Koch & Co. Datensysteme GmbH. * * See the file "skfddi.c" for further information. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * The information in this file is provided "AS IS" without warranty. * ******************************************************************************//* * ******************************************************************* * This SBA code implements the Synchronous Bandwidth Allocation * functions described in the "FDDI Synchronous Forum Implementer's * Agreement" dated December 1th, 1993. * ******************************************************************* * * PURPOSE: The purpose of this function is to control * synchronous allocations on a single FDDI segment. * Allocations are limited to the primary FDDI ring. * The SBM provides recovery mechanisms to recover * unused bandwidth also resolves T_Neg and * reconfiguration changes. Many of the SBM state * machine inputs are sourced by the underlying * FDDI sub-system supporting the SBA application. * * ******************************************************************* */#include "h/types.h"#include "h/fddi.h"#include "h/smc.h"#include "h/smt_p.h"#ifndef SLIM_SMT#ifdef ESS#ifndef lintstatic const char ID_sccs[] = "@(#)ess.c 1.10 96/02/23 (C) SK" ;#define LINT_USE(x)#else#define LINT_USE(x) (x)=(x)#endif#define MS2BCLK(x) ((x)*12500L)/* ------------------------------------------------------------- LOCAL VARIABLES: -------------------------------------------------------------*/static const u_short plist_raf_alc_res[] = { SMT_P0012, SMT_P320B, SMT_P320F, SMT_P3210, SMT_P0019, SMT_P001A, SMT_P001D, 0 } ;static const u_short plist_raf_chg_req[] = { SMT_P320B, SMT_P320F, SMT_P3210, SMT_P001A, 0 } ;static const struct fddi_addr smt_sba_da = {{0x80,0x01,0x43,0x00,0x80,0x0C}} ;static const struct fddi_addr null_addr = {{0,0,0,0,0,0}} ;/* ------------------------------------------------------------- GLOBAL VARIABLES: -------------------------------------------------------------*//* ------------------------------------------------------------- LOCAL FUNCTIONS: -------------------------------------------------------------*/static void ess_send_response(struct s_smc *smc, struct smt_header *sm, int sba_cmd);static void ess_config_fifo(struct s_smc *smc);static void ess_send_alc_req(struct s_smc *smc);static void ess_send_frame(struct s_smc *smc, SMbuf *mb);/* ------------------------------------------------------------- EXTERNAL FUNCTIONS: -------------------------------------------------------------*//* ------------------------------------------------------------- PUBLIC FUNCTIONS: -------------------------------------------------------------*/void ess_timer_poll(struct s_smc *smc);void ess_para_change(struct s_smc *smc);int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, int fs);int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead);/* * -------------------------------------------------------------------------- * End Station Support (ESS) * -------------------------------------------------------------------------- *//* * 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 Responce 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -