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