linux/drivers/net/fddi/skfp/ess.c
<<
>>
Prefs
   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(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        EXTERNAL FUNCTIONS:
  92        -------------------------------------------------------------
  93*/
  94
  95/*
  96        -------------------------------------------------------------
  97        PUBLIC FUNCTIONS:
  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 *      End Station Support     (ESS)
 111 * --------------------------------------------------------------------------
 112 */
 113
 114/*
 115 * evaluate the RAF frame
 116 */
 117int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
 118                          int fs)
 119{
 120        void                    *p ;            /* universal pointer */
 121        struct smt_p_0016       *cmd ;          /* para: command for the ESS */
 122        SMbuf                   *db ;
 123        u_long                  msg_res_type ;  /* recource type */
 124        u_long                  payload, overhead ;
 125        int                     local ;
 126        int                     i ;
 127
 128        /*
 129         * Message Processing Code
 130         */
 131         local = ((fs & L_INDICATOR) != 0) ;
 132
 133        /*
 134         * get the resource type
 135         */
 136        if (!(p = (void *) sm_to_para(smc,sm,SMT_P0015))) {
 137                DB_ESS("ESS: RAF frame error, parameter type not found\n",0,0) ;
 138                return fs;
 139        }
 140        msg_res_type = ((struct smt_p_0015 *)p)->res_type ;
 141
 142        /*
 143         * get the pointer to the ESS command
 144         */
 145        if (!(cmd = (struct smt_p_0016 *) sm_to_para(smc,sm,SMT_P0016))) {
 146                /*
 147                 * error in frame: para ESS command was not found
 148                 */
 149                 DB_ESS("ESS: RAF frame error, parameter command not found\n",0,0);
 150                 return fs;
 151        }
 152
 153        DB_ESSN(2,"fc %x        ft %x\n",sm->smt_class,sm->smt_type) ;
 154        DB_ESSN(2,"ver %x       tran %lx\n",sm->smt_version,sm->smt_tid) ;
 155        DB_ESSN(2,"stn_id %s\n",addr_to_string(&sm->smt_source),0) ;
 156
 157        DB_ESSN(2,"infolen %x   res %x\n",sm->smt_len, msg_res_type) ;
 158        DB_ESSN(2,"sbacmd %x\n",cmd->sba_cmd,0) ;
 159
 160        /*
 161         * evaluate the ESS command
 162         */
 163        switch (cmd->sba_cmd) {
 164
 165        /*
 166         * Process an ESS Allocation Request
 167         */
 168        case REQUEST_ALLOCATION :
 169                /*
 170                 * check for an RAF Request (Allocation Request)
 171                 */
 172                if (sm->smt_type == SMT_REQUEST) {
 173                        /*
 174                         * process the Allocation request only if the frame is
 175                         * local and no static allocation is used
 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                         * Note: The Application should send a LAN_LOC_FRAME.
 189                         *       The ESS do not send the Frame to the network!
 190                         */
 191                        smc->ess.alloc_trans_id = sm->smt_tid ;
 192                        DB_ESS("ESS: save Alloc Req Trans ID %lx\n",sm->smt_tid,0);
 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                 * The RAF frame is an Allocation Response !
 220                 * check the parameters
 221                 */
 222                if (smt_check_para(smc,sm,plist_raf_alc_res)) {
 223                        DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
 224                        return fs;
 225                }
 226
 227                /*
 228                 * VERIFY THE FRAME IS WELL BUILT:
 229                 *
 230                 *      1. path index = primary ring only
 231                 *      2. resource type = sync bw only
 232                 *      3. trans action id = alloc_trans_id
 233                 *      4. reason code = success
 234                 *
 235                 * If any are violated, discard the RAF frame
 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\n",0,0) ;
 245                        return fs;
 246                }
 247
 248                /*
 249                 * Extract message parameters
 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\n",payload,overhead) ;
 265
 266                /*
 267                 * process the bandwidth allocation
 268                 */
 269                (void)process_bw_alloc(smc,(long)payload,(long)overhead) ;
 270
 271                return fs;
 272                /* end of Process Allocation Request */
 273
 274        /*
 275         * Process an ESS Change Request
 276         */
 277        case CHANGE_ALLOCATION :
 278                /*
 279                 * except only replies
 280                 */
 281                if (sm->smt_type != SMT_REQUEST) {
 282                        DB_ESS("ESS: Do not process Change Responses\n",0,0) ;
 283                        return fs;
 284                }
 285
 286                /*
 287                 * check the para for the Change Request
 288                 */
 289                if (smt_check_para(smc,sm,plist_raf_chg_req)) {
 290                        DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
 291                        return fs;
 292                }
 293
 294                /*
 295                 * Verify the path index and resource
 296                 * type are correct. If any of
 297                 * these are false, don't process this
 298                 * change request frame.
 299                 */
 300                if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
 301                        != PRIMARY_RING) || (msg_res_type != SYNC_BW)) {
 302                        DB_ESS("ESS: RAF frame with para problem, ignoring\n",0,0) ;
 303                        return fs;
 304                }
 305
 306                /*
 307                 * Extract message queue parameters
 308                 */
 309                p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
 310                payload = ((struct smt_p_320f *)p)->mib_payload ;
 311                p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
 312                overhead = ((struct smt_p_3210 *)p)->mib_overhead ;
 313
 314                DB_ESSN(2,"ESS: Change Request from %s\n",
 315                        addr_to_string(&sm->smt_source),0) ;
 316                DB_ESSN(2,"payload= %lx overhead= %lx\n",payload,overhead) ;
 317
 318                /*
 319                 * process the bandwidth allocation
 320                 */
 321                if(!process_bw_alloc(smc,(long)payload,(long)overhead))
 322                        return fs;
 323
 324                /*
 325                 * send an RAF Change Reply
 326                 */
 327                ess_send_response(smc,sm,CHANGE_ALLOCATION) ;
 328
 329                return fs;
 330                /* end of Process Change Request */
 331
 332        /*
 333         * Process Report Response
 334         */
 335        case REPORT_ALLOCATION :
 336                /*
 337                 * except only requests
 338                 */
 339                if (sm->smt_type != SMT_REQUEST) {
 340                        DB_ESS("ESS: Do not process a Report Reply\n",0,0) ;
 341                        return fs;
 342                }
 343
 344                DB_ESSN(2,"ESS: Report Request from %s\n",
 345                        addr_to_string(&(sm->smt_source)),0) ;
 346
 347                /*
 348                 * verify that the resource type is sync bw only
 349                 */
 350                if (msg_res_type != SYNC_BW) {
 351                        DB_ESS("ESS: ignoring RAF with para problem\n",0,0) ;
 352                        return fs;
 353                }
 354
 355                /*
 356                 * send an RAF Change Reply
 357                 */
 358                ess_send_response(smc,sm,REPORT_ALLOCATION) ;
 359
 360                return fs;
 361                /* end of Process Report Request */
 362
 363        default:
 364                /*
 365                 * error in frame
 366                 */
 367                DB_ESS("ESS: ignoring RAF with bad sba_cmd\n",0,0) ;
 368                break ;
 369        }
 370
 371        return fs;
 372}
 373
 374/*
 375 * determines the synchronous bandwidth, set the TSYNC register and the
 376 * mib variables SBAPayload, SBAOverhead and fddiMACT-NEG.
 377 */
 378static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead)
 379{
 380        /*
 381         * determine the synchronous bandwidth (sync_bw) in bytes per T-NEG,
 382         * if the payload is greater than zero.
 383         * For the SBAPayload and the SBAOverhead we have the following
 384         * unite quations
 385         *                    _           _
 386         *                   |       bytes |
 387         *      SBAPayload = | 8000 ------ |
 388         *                   |          s  |
 389         *                    -           -
 390         *                     _       _
 391         *                    |  bytes  |
 392         *      SBAOverhead = | ------  |
 393         *                    |  T-NEG  |
 394         *                     -       -
 395         *
 396         * T-NEG is described by the equation:
 397         *
 398         *                   (-) fddiMACT-NEG
 399         *      T-NEG =     -------------------
 400         *                      12500000 1/s
 401         *
 402         * The number of bytes we are able to send is the payload
 403         * plus the overhead.
 404         *
 405         *                        bytes    T-NEG SBAPayload 8000 bytes/s
 406         * sync_bw =  SBAOverhead ------ + -----------------------------
 407         *                        T-NEG         T-NEG
 408         *
 409         *
 410         *                           1
 411         * sync_bw =  SBAOverhead + ---- (-)fddiMACT-NEG * SBAPayload
 412         *                          1562
 413         *
 414         */
 415
 416        /*
 417         * set the mib attributes fddiPATHSbaOverhead, fddiPATHSbaPayload
 418         */
 419/*      if (smt_set_obj(smc,SMT_P320F,payload,S_SET)) {
 420                DB_ESS("ESS: SMT does not accept the payload value\n",0,0) ;
 421                return FALSE;
 422        }
 423        if (smt_set_obj(smc,SMT_P3210,overhead,S_SET)) {
 424                DB_ESS("ESS: SMT does not accept the overhead value\n",0,0) ;
 425                return FALSE;
 426        } */
 427
 428        /* premliminary */
 429        if (payload > MAX_PAYLOAD || overhead > 5000) {
 430                DB_ESS("ESS: payload / overhead not accepted\n",0,0) ;
 431                return FALSE;
 432        }
 433
 434        /*
 435         * start the iterative allocation process if the payload or the overhead
 436         * are smaller than the parsed values
 437         */
 438        if (smc->mib.fddiESSPayload &&
 439                ((u_long)payload != smc->mib.fddiESSPayload ||
 440                (u_long)overhead != smc->mib.fddiESSOverhead)) {
 441                smc->ess.raf_act_timer_poll = TRUE ;
 442                smc->ess.timer_count = 0 ;
 443        }
 444
 445        /*
 446         * evulate the Payload
 447         */
 448        if (payload) {
 449                DB_ESSN(2,"ESS: turn SMT_ST_SYNC_SERVICE bit on\n",0,0) ;
 450                smc->ess.sync_bw_available = TRUE ;
 451
 452                smc->ess.sync_bw = overhead -
 453                        (long)smc->mib.m[MAC0].fddiMACT_Neg *
 454                        payload / 1562 ;
 455        }
 456        else {
 457                DB_ESSN(2,"ESS: turn SMT_ST_SYNC_SERVICE bit off\n",0,0) ;
 458                smc->ess.sync_bw_available = FALSE ;
 459                smc->ess.sync_bw = 0 ;
 460                overhead = 0 ;
 461        }
 462
 463        smc->mib.a[PATH0].fddiPATHSbaPayload = payload ;
 464        smc->mib.a[PATH0].fddiPATHSbaOverhead = overhead ;
 465
 466
 467        DB_ESSN(2,"tsync = %lx\n",smc->ess.sync_bw,0) ;
 468
 469        ess_config_fifo(smc) ;
 470        set_formac_tsync(smc,smc->ess.sync_bw) ;
 471        return TRUE;
 472}
 473
 474static void ess_send_response(struct s_smc *smc, struct smt_header *sm,
 475                              int sba_cmd)
 476{
 477        struct smt_sba_chg      *chg ;
 478        SMbuf                   *mb ;
 479        void                    *p ;
 480
 481        /*
 482         * get and initialize the response frame
 483         */
 484        if (sba_cmd == CHANGE_ALLOCATION) {
 485                if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REPLY,
 486                                sizeof(struct smt_sba_chg))))
 487                                return ;
 488        }
 489        else {
 490                if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REPLY,
 491                                sizeof(struct smt_sba_rep_res))))
 492                                return ;
 493        }
 494
 495        chg = smtod(mb,struct smt_sba_chg *) ;
 496        chg->smt.smt_tid = sm->smt_tid ;
 497        chg->smt.smt_dest = sm->smt_source ;
 498
 499        /* set P15 */
 500        chg->s_type.para.p_type = SMT_P0015 ;
 501        chg->s_type.para.p_len = sizeof(struct smt_p_0015) - PARA_LEN ;
 502        chg->s_type.res_type = SYNC_BW ;
 503
 504        /* set P16 */
 505        chg->cmd.para.p_type = SMT_P0016 ;
 506        chg->cmd.para.p_len = sizeof(struct smt_p_0016) - PARA_LEN ;
 507        chg->cmd.sba_cmd = sba_cmd ;
 508
 509        /* set P320B */
 510        chg->path.para.p_type = SMT_P320B ;
 511        chg->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ;
 512        chg->path.mib_index = SBAPATHINDEX ;
 513        chg->path.path_pad = 0;
 514        chg->path.path_index = PRIMARY_RING ;
 515
 516        /* set P320F */
 517        chg->payload.para.p_type = SMT_P320F ;
 518        chg->payload.para.p_len = sizeof(struct smt_p_320f) - PARA_LEN ;
 519        chg->payload.mib_index = SBAPATHINDEX ;
 520        chg->payload.mib_payload = smc->mib.a[PATH0].fddiPATHSbaPayload ;
 521
 522        /* set P3210 */
 523        chg->overhead.para.p_type = SMT_P3210 ;
 524        chg->overhead.para.p_len = sizeof(struct smt_p_3210) - PARA_LEN ;
 525        chg->overhead.mib_index = SBAPATHINDEX ;
 526        chg->overhead.mib_overhead = smc->mib.a[PATH0].fddiPATHSbaOverhead ;
 527
 528        if (sba_cmd == CHANGE_ALLOCATION) {
 529                /* set P1A */
 530                chg->cat.para.p_type = SMT_P001A ;
 531                chg->cat.para.p_len = sizeof(struct smt_p_001a) - PARA_LEN ;
 532                p = (void *) sm_to_para(smc,sm,SMT_P001A) ;
 533                chg->cat.category = ((struct smt_p_001a *)p)->category ;
 534        }
 535        dump_smt(smc,(struct smt_header *)chg,"RAF") ;
 536        ess_send_frame(smc,mb) ;
 537}
 538
 539void ess_timer_poll(struct s_smc *smc)
 540{
 541        if (!smc->ess.raf_act_timer_poll)
 542                return ;
 543
 544        DB_ESSN(2,"ESS: timer_poll\n",0,0) ;
 545
 546        smc->ess.timer_count++ ;
 547        if (smc->ess.timer_count == 10) {
 548                smc->ess.timer_count = 0 ;
 549                ess_send_alc_req(smc) ;
 550        }
 551}
 552
 553static void ess_send_alc_req(struct s_smc *smc)
 554{
 555        struct smt_sba_alc_req *req ;
 556        SMbuf   *mb ;
 557
 558        /*
 559         * send never allocation request where the requested payload and
 560         * overhead is zero or deallocate bandwidth when no bandwidth is
 561         * parsed
 562         */
 563        if (!smc->mib.fddiESSPayload) {
 564                smc->mib.fddiESSOverhead = 0 ;
 565        }
 566        else {
 567                if (!smc->mib.fddiESSOverhead)
 568                        smc->mib.fddiESSOverhead = DEFAULT_OV ;
 569        }
 570
 571        if (smc->mib.fddiESSOverhead ==
 572                smc->mib.a[PATH0].fddiPATHSbaOverhead &&
 573                smc->mib.fddiESSPayload ==
 574                smc->mib.a[PATH0].fddiPATHSbaPayload){
 575                smc->ess.raf_act_timer_poll = FALSE ;
 576                smc->ess.timer_count = 7 ;      /* next RAF alc req after 3 s */
 577                return ;
 578        }
 579        
 580        /*
 581         * get and initialize the response frame
 582         */
 583        if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REQUEST,
 584                        sizeof(struct smt_sba_alc_req))))
 585                        return ;
 586        req = smtod(mb,struct smt_sba_alc_req *) ;
 587        req->smt.smt_tid = smc->ess.alloc_trans_id = smt_get_tid(smc) ;
 588        req->smt.smt_dest = smt_sba_da ;
 589
 590        /* set P15 */
 591        req->s_type.para.p_type = SMT_P0015 ;
 592        req->s_type.para.p_len = sizeof(struct smt_p_0015) - PARA_LEN ;
 593        req->s_type.res_type = SYNC_BW ;
 594
 595        /* set P16 */
 596        req->cmd.para.p_type = SMT_P0016 ;
 597        req->cmd.para.p_len = sizeof(struct smt_p_0016) - PARA_LEN ;
 598        req->cmd.sba_cmd = REQUEST_ALLOCATION ;
 599
 600        /*
 601         * set the parameter type and parameter length of all used
 602         * parameters
 603         */
 604
 605        /* set P320B */
 606        req->path.para.p_type = SMT_P320B ;
 607        req->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ;
 608        req->path.mib_index = SBAPATHINDEX ;
 609        req->path.path_pad = 0;
 610        req->path.path_index = PRIMARY_RING ;
 611
 612        /* set P0017 */
 613        req->pl_req.para.p_type = SMT_P0017 ;
 614        req->pl_req.para.p_len = sizeof(struct smt_p_0017) - PARA_LEN ;
 615        req->pl_req.sba_pl_req = smc->mib.fddiESSPayload -
 616                smc->mib.a[PATH0].fddiPATHSbaPayload ;
 617
 618        /* set P0018 */
 619        req->ov_req.para.p_type = SMT_P0018 ;
 620        req->ov_req.para.p_len = sizeof(struct smt_p_0018) - PARA_LEN ;
 621        req->ov_req.sba_ov_req = smc->mib.fddiESSOverhead -
 622                smc->mib.a[PATH0].fddiPATHSbaOverhead ;
 623
 624        /* set P320F */
 625        req->payload.para.p_type = SMT_P320F ;
 626        req->payload.para.p_len = sizeof(struct smt_p_320f) - PARA_LEN ;
 627        req->payload.mib_index = SBAPATHINDEX ;
 628        req->payload.mib_payload = smc->mib.a[PATH0].fddiPATHSbaPayload ;
 629
 630        /* set P3210 */
 631        req->overhead.para.p_type = SMT_P3210 ;
 632        req->overhead.para.p_len = sizeof(struct smt_p_3210) - PARA_LEN ;
 633        req->overhead.mib_index = SBAPATHINDEX ;
 634        req->overhead.mib_overhead = smc->mib.a[PATH0].fddiPATHSbaOverhead ;
 635
 636        /* set P19 */
 637        req->a_addr.para.p_type = SMT_P0019 ;
 638        req->a_addr.para.p_len = sizeof(struct smt_p_0019) - PARA_LEN ;
 639        req->a_addr.sba_pad = 0;
 640        req->a_addr.alloc_addr = null_addr ;
 641
 642        /* set P1A */
 643        req->cat.para.p_type = SMT_P001A ;
 644        req->cat.para.p_len = sizeof(struct smt_p_001a) - PARA_LEN ;
 645        req->cat.category = smc->mib.fddiESSCategory ;
 646
 647        /* set P1B */
 648        req->tneg.para.p_type = SMT_P001B ;
 649        req->tneg.para.p_len = sizeof(struct smt_p_001b) - PARA_LEN ;
 650        req->tneg.max_t_neg = smc->mib.fddiESSMaxTNeg ;
 651
 652        /* set P1C */
 653        req->segm.para.p_type = SMT_P001C ;
 654        req->segm.para.p_len = sizeof(struct smt_p_001c) - PARA_LEN ;
 655        req->segm.min_seg_siz = smc->mib.fddiESSMinSegmentSize ;
 656
 657        dump_smt(smc,(struct smt_header *)req,"RAF") ;
 658        ess_send_frame(smc,mb) ;
 659}
 660
 661static void ess_send_frame(struct s_smc *smc, SMbuf *mb)
 662{
 663        /*
 664         * check if the frame must be send to the own ESS
 665         */
 666        if (smc->ess.local_sba_active) {
 667                /*
 668                 * Send the Change Reply to the local SBA
 669                 */
 670                DB_ESS("ESS:Send to the local SBA\n",0,0) ;
 671                if (!smc->ess.sba_reply_pend)
 672                        smc->ess.sba_reply_pend = mb ;
 673                else {
 674                        DB_ESS("Frame is lost - another frame was pending\n",0,0);
 675                        smt_free_mbuf(smc,mb) ;
 676                }
 677        }
 678        else {
 679                /*
 680                 * Send the SBA RAF Change Reply to the network
 681                 */
 682                DB_ESS("ESS:Send to the network\n",0,0) ;
 683                smt_send_frame(smc,mb,FC_SMT_INFO,0) ;
 684        }
 685}
 686
 687void ess_para_change(struct s_smc *smc)
 688{
 689        (void)process_bw_alloc(smc,(long)smc->mib.a[PATH0].fddiPATHSbaPayload,
 690                (long)smc->mib.a[PATH0].fddiPATHSbaOverhead) ;
 691}
 692
 693static void ess_config_fifo(struct s_smc *smc)
 694{
 695        /*
 696         * if nothing to do exit 
 697         */
 698        if (smc->mib.a[PATH0].fddiPATHSbaPayload) {
 699                if (smc->hw.fp.fifo.fifo_config_mode & SYNC_TRAFFIC_ON &&
 700                        (smc->hw.fp.fifo.fifo_config_mode&SEND_ASYNC_AS_SYNC) ==
 701                        smc->mib.fddiESSSynchTxMode) {
 702                        return ;
 703                }
 704        }
 705        else {
 706                if (!(smc->hw.fp.fifo.fifo_config_mode & SYNC_TRAFFIC_ON)) {
 707                        return ;
 708                }
 709        }
 710
 711        /*
 712         * split up the FIFO and reinitialize the queues
 713         */
 714        formac_reinit_tx(smc) ;
 715}
 716
 717#endif /* ESS */
 718
 719#endif  /* no SLIM_SMT */
 720
 721