linux/drivers/net/fddi/skfp/fplustm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/******************************************************************************
   3 *
   4 *      (C)Copyright 1998,1999 SysKonnect,
   5 *      a business unit of Schneider & Koch & Co. Datensysteme GmbH.
   6 *
   7 *      See the file "skfddi.c" for further information.
   8 *
   9 *      The information in this file is provided "AS IS" without warranty.
  10 *
  11 ******************************************************************************/
  12
  13/*
  14 * FORMAC+ Driver for tag mode
  15 */
  16
  17#include "h/types.h"
  18#include "h/fddi.h"
  19#include "h/smc.h"
  20#include "h/supern_2.h"
  21#include <linux/bitrev.h>
  22#include <linux/etherdevice.h>
  23
  24#ifndef lint
  25static const char ID_sccs[] = "@(#)fplustm.c    1.32 99/02/23 (C) SK " ;
  26#endif
  27
  28#ifndef UNUSED
  29#ifdef  lint
  30#define UNUSED(x)       (x) = (x)
  31#else
  32#define UNUSED(x)
  33#endif
  34#endif
  35
  36#define FM_ADDRX         (FM_ADDET|FM_EXGPA0|FM_EXGPA1)
  37#define MS2BCLK(x)      ((x)*12500L)
  38#define US2BCLK(x)      ((x)*1250L)
  39
  40/*
  41 * prototypes for static function
  42 */
  43static void build_claim_beacon(struct s_smc *smc, u_long t_request);
  44static int init_mac(struct s_smc *smc, int all);
  45static void rtm_init(struct s_smc *smc);
  46static void smt_split_up_fifo(struct s_smc *smc);
  47
  48#if (!defined(NO_SMT_PANIC) || defined(DEBUG))
  49static  char write_mdr_warning [] = "E350 write_mdr() FM_SNPPND is set\n";
  50static  char cam_warning [] = "E_SMT_004: CAM still busy\n";
  51#endif
  52
  53#define DUMMY_READ()    smc->hw.mc_dummy = (u_short) inp(ADDR(B0_RAP))
  54
  55#define CHECK_NPP() {   unsigned int k = 10000 ;\
  56                        while ((inpw(FM_A(FM_STMCHN)) & FM_SNPPND) && k) k--;\
  57                        if (!k) { \
  58                                SMT_PANIC(smc,SMT_E0130, SMT_E0130_MSG) ; \
  59                        }       \
  60                }
  61
  62#define CHECK_CAM() {   unsigned int k = 10 ;\
  63                        while (!(inpw(FM_A(FM_AFSTAT)) & FM_DONE) && k) k--;\
  64                        if (!k) { \
  65                                SMT_PANIC(smc,SMT_E0131, SMT_E0131_MSG) ; \
  66                        }       \
  67                }
  68
  69const struct fddi_addr fddi_broadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
  70static const struct fddi_addr null_addr = {{0,0,0,0,0,0}};
  71static const struct fddi_addr dbeacon_multi = {{0x01,0x80,0xc2,0x00,0x01,0x00}};
  72
  73static const u_short my_said = 0xffff ; /* short address (n.u.) */
  74static const u_short my_sagp = 0xffff ; /* short group address (n.u.) */
  75
  76/*
  77 * define my address
  78 */
  79#ifdef  USE_CAN_ADDR
  80#define MA      smc->hw.fddi_canon_addr
  81#else
  82#define MA      smc->hw.fddi_home_addr
  83#endif
  84
  85
  86/*
  87 * useful interrupt bits
  88 */
  89static const int mac_imsk1u = FM_STXABRS | FM_STXABRA0 | FM_SXMTABT ;
  90static const int mac_imsk1l = FM_SQLCKS | FM_SQLCKA0 | FM_SPCEPDS | FM_SPCEPDA0|
  91                        FM_STBURS | FM_STBURA0 ;
  92
  93        /* delete FM_SRBFL after tests */
  94static const int mac_imsk2u = FM_SERRSF | FM_SNFSLD | FM_SRCVOVR | FM_SRBFL |
  95                        FM_SMYCLM ;
  96static const int mac_imsk2l = FM_STRTEXR | FM_SDUPCLM | FM_SFRMCTR |
  97                        FM_SERRCTR | FM_SLSTCTR |
  98                        FM_STRTEXP | FM_SMULTDA | FM_SRNGOP ;
  99
 100static const int mac_imsk3u = FM_SRCVOVR2 | FM_SRBFL2 ;
 101static const int mac_imsk3l = FM_SRPERRQ2 | FM_SRPERRQ1 ;
 102
 103static const int mac_beacon_imsk2u = FM_SOTRBEC | FM_SMYBEC | FM_SBEC |
 104                        FM_SLOCLM | FM_SHICLM | FM_SMYCLM | FM_SCLM ;
 105
 106
 107static u_long mac_get_tneg(struct s_smc *smc)
 108{
 109        u_long  tneg ;
 110
 111        tneg = (u_long)((long)inpw(FM_A(FM_TNEG))<<5) ;
 112        return (u_long)((tneg + ((inpw(FM_A(FM_TMRS))>>10)&0x1f)) |
 113                0xffe00000L) ;
 114}
 115
 116void mac_update_counter(struct s_smc *smc)
 117{
 118        smc->mib.m[MAC0].fddiMACFrame_Ct =
 119                (smc->mib.m[MAC0].fddiMACFrame_Ct & 0xffff0000L)
 120                + (u_short) inpw(FM_A(FM_FCNTR)) ;
 121        smc->mib.m[MAC0].fddiMACLost_Ct =
 122                (smc->mib.m[MAC0].fddiMACLost_Ct & 0xffff0000L)
 123                + (u_short) inpw(FM_A(FM_LCNTR)) ;
 124        smc->mib.m[MAC0].fddiMACError_Ct =
 125                (smc->mib.m[MAC0].fddiMACError_Ct & 0xffff0000L)
 126                + (u_short) inpw(FM_A(FM_ECNTR)) ;
 127        smc->mib.m[MAC0].fddiMACT_Neg = mac_get_tneg(smc) ;
 128#ifdef SMT_REAL_TOKEN_CT
 129        /*
 130         * If the token counter is emulated it is updated in smt_event.
 131         */
 132        TBD
 133#else
 134        smt_emulate_token_ct( smc, MAC0 );
 135#endif
 136}
 137
 138/*
 139 * write long value into buffer memory over memory data register (MDR),
 140 */
 141static void write_mdr(struct s_smc *smc, u_long val)
 142{
 143        CHECK_NPP() ;
 144        MDRW(val) ;
 145}
 146
 147#if 0
 148/*
 149 * read long value from buffer memory over memory data register (MDR),
 150 */
 151static u_long read_mdr(struct s_smc *smc, unsigned int addr)
 152{
 153        long p ;
 154        CHECK_NPP() ;
 155        MARR(addr) ;
 156        outpw(FM_A(FM_CMDREG1),FM_IRMEMWO) ;
 157        CHECK_NPP() ;   /* needed for PCI to prevent from timeing violations */
 158/*      p = MDRR() ; */ /* bad read values if the workaround */
 159                        /* smc->hw.mc_dummy = *((short volatile far *)(addr)))*/
 160                        /* is used */
 161        p = (u_long)inpw(FM_A(FM_MDRU))<<16 ;
 162        p += (u_long)inpw(FM_A(FM_MDRL)) ;
 163        return p;
 164}
 165#endif
 166
 167/*
 168 * clear buffer memory
 169 */
 170static void init_ram(struct s_smc *smc)
 171{
 172        u_short i ;
 173
 174        smc->hw.fp.fifo.rbc_ram_start = 0 ;
 175        smc->hw.fp.fifo.rbc_ram_end =
 176                smc->hw.fp.fifo.rbc_ram_start + RBC_MEM_SIZE ;
 177        CHECK_NPP() ;
 178        MARW(smc->hw.fp.fifo.rbc_ram_start) ;
 179        for (i = smc->hw.fp.fifo.rbc_ram_start;
 180                i < (u_short) (smc->hw.fp.fifo.rbc_ram_end-1); i++)
 181                write_mdr(smc,0L) ;
 182        /* Erase the last byte too */
 183        write_mdr(smc,0L) ;
 184}
 185
 186/*
 187 * set receive FIFO pointer
 188 */
 189static void set_recvptr(struct s_smc *smc)
 190{
 191        /*
 192         * initialize the pointer for receive queue 1
 193         */
 194        outpw(FM_A(FM_RPR1),smc->hw.fp.fifo.rx1_fifo_start) ;   /* RPR1 */
 195        outpw(FM_A(FM_SWPR1),smc->hw.fp.fifo.rx1_fifo_start) ;  /* SWPR1 */
 196        outpw(FM_A(FM_WPR1),smc->hw.fp.fifo.rx1_fifo_start) ;   /* WPR1 */
 197        outpw(FM_A(FM_EARV1),smc->hw.fp.fifo.tx_s_start-1) ;    /* EARV1 */
 198
 199        /*
 200         * initialize the pointer for receive queue 2
 201         */
 202        if (smc->hw.fp.fifo.rx2_fifo_size) {
 203                outpw(FM_A(FM_RPR2),smc->hw.fp.fifo.rx2_fifo_start) ;
 204                outpw(FM_A(FM_SWPR2),smc->hw.fp.fifo.rx2_fifo_start) ;
 205                outpw(FM_A(FM_WPR2),smc->hw.fp.fifo.rx2_fifo_start) ;
 206                outpw(FM_A(FM_EARV2),smc->hw.fp.fifo.rbc_ram_end-1) ;
 207        }
 208        else {
 209                outpw(FM_A(FM_RPR2),smc->hw.fp.fifo.rbc_ram_end-1) ;
 210                outpw(FM_A(FM_SWPR2),smc->hw.fp.fifo.rbc_ram_end-1) ;
 211                outpw(FM_A(FM_WPR2),smc->hw.fp.fifo.rbc_ram_end-1) ;
 212                outpw(FM_A(FM_EARV2),smc->hw.fp.fifo.rbc_ram_end-1) ;
 213        }
 214}
 215
 216/*
 217 * set transmit FIFO pointer
 218 */
 219static void set_txptr(struct s_smc *smc)
 220{
 221        outpw(FM_A(FM_CMDREG2),FM_IRSTQ) ;      /* reset transmit queues */
 222
 223        /*
 224         * initialize the pointer for asynchronous transmit queue
 225         */
 226        outpw(FM_A(FM_RPXA0),smc->hw.fp.fifo.tx_a0_start) ;     /* RPXA0 */
 227        outpw(FM_A(FM_SWPXA0),smc->hw.fp.fifo.tx_a0_start) ;    /* SWPXA0 */
 228        outpw(FM_A(FM_WPXA0),smc->hw.fp.fifo.tx_a0_start) ;     /* WPXA0 */
 229        outpw(FM_A(FM_EAA0),smc->hw.fp.fifo.rx2_fifo_start-1) ; /* EAA0 */
 230
 231        /*
 232         * initialize the pointer for synchronous transmit queue
 233         */
 234        if (smc->hw.fp.fifo.tx_s_size) {
 235                outpw(FM_A(FM_RPXS),smc->hw.fp.fifo.tx_s_start) ;
 236                outpw(FM_A(FM_SWPXS),smc->hw.fp.fifo.tx_s_start) ;
 237                outpw(FM_A(FM_WPXS),smc->hw.fp.fifo.tx_s_start) ;
 238                outpw(FM_A(FM_EAS),smc->hw.fp.fifo.tx_a0_start-1) ;
 239        }
 240        else {
 241                outpw(FM_A(FM_RPXS),smc->hw.fp.fifo.tx_a0_start-1) ;
 242                outpw(FM_A(FM_SWPXS),smc->hw.fp.fifo.tx_a0_start-1) ;
 243                outpw(FM_A(FM_WPXS),smc->hw.fp.fifo.tx_a0_start-1) ;
 244                outpw(FM_A(FM_EAS),smc->hw.fp.fifo.tx_a0_start-1) ;
 245        }
 246}
 247
 248/*
 249 * init memory buffer management registers
 250 */
 251static void init_rbc(struct s_smc *smc)
 252{
 253        u_short rbc_ram_addr ;
 254
 255        /*
 256         * set unused pointers or permanent pointers
 257         */
 258        rbc_ram_addr = smc->hw.fp.fifo.rx2_fifo_start - 1 ;
 259
 260        outpw(FM_A(FM_RPXA1),rbc_ram_addr) ;    /* a1-send pointer */
 261        outpw(FM_A(FM_WPXA1),rbc_ram_addr) ;
 262        outpw(FM_A(FM_SWPXA1),rbc_ram_addr) ;
 263        outpw(FM_A(FM_EAA1),rbc_ram_addr) ;
 264
 265        set_recvptr(smc) ;
 266        set_txptr(smc) ;
 267}
 268
 269/*
 270 * init rx pointer
 271 */
 272static void init_rx(struct s_smc *smc)
 273{
 274        struct s_smt_rx_queue   *queue ;
 275
 276        /*
 277         * init all tx data structures for receive queue 1
 278         */
 279        smc->hw.fp.rx[QUEUE_R1] = queue = &smc->hw.fp.rx_q[QUEUE_R1] ;
 280        queue->rx_bmu_ctl = (HW_PTR) ADDR(B0_R1_CSR) ;
 281        queue->rx_bmu_dsc = (HW_PTR) ADDR(B4_R1_DA) ;
 282
 283        /*
 284         * init all tx data structures for receive queue 2
 285         */
 286        smc->hw.fp.rx[QUEUE_R2] = queue = &smc->hw.fp.rx_q[QUEUE_R2] ;
 287        queue->rx_bmu_ctl = (HW_PTR) ADDR(B0_R2_CSR) ;
 288        queue->rx_bmu_dsc = (HW_PTR) ADDR(B4_R2_DA) ;
 289}
 290
 291/*
 292 * set the TSYNC register of the FORMAC to regulate synchronous transmission
 293 */
 294void set_formac_tsync(struct s_smc *smc, long sync_bw)
 295{
 296        outpw(FM_A(FM_TSYNC),(unsigned int) (((-sync_bw) >> 5) & 0xffff) ) ;
 297}
 298
 299/*
 300 * init all tx data structures
 301 */
 302static void init_tx(struct s_smc *smc)
 303{
 304        struct s_smt_tx_queue   *queue ;
 305
 306        /*
 307         * init all tx data structures for the synchronous queue
 308         */
 309        smc->hw.fp.tx[QUEUE_S] = queue = &smc->hw.fp.tx_q[QUEUE_S] ;
 310        queue->tx_bmu_ctl = (HW_PTR) ADDR(B0_XS_CSR) ;
 311        queue->tx_bmu_dsc = (HW_PTR) ADDR(B5_XS_DA) ;
 312
 313#ifdef ESS
 314        set_formac_tsync(smc,smc->ess.sync_bw) ;
 315#endif
 316
 317        /*
 318         * init all tx data structures for the asynchronous queue 0
 319         */
 320        smc->hw.fp.tx[QUEUE_A0] = queue = &smc->hw.fp.tx_q[QUEUE_A0] ;
 321        queue->tx_bmu_ctl = (HW_PTR) ADDR(B0_XA_CSR) ;
 322        queue->tx_bmu_dsc = (HW_PTR) ADDR(B5_XA_DA) ;
 323
 324
 325        llc_recover_tx(smc) ;
 326}
 327
 328static void mac_counter_init(struct s_smc *smc)
 329{
 330        int i ;
 331        u_long *ec ;
 332
 333        /*
 334         * clear FORMAC+ frame-, lost- and error counter
 335         */
 336        outpw(FM_A(FM_FCNTR),0) ;
 337        outpw(FM_A(FM_LCNTR),0) ;
 338        outpw(FM_A(FM_ECNTR),0) ;
 339        /*
 340         * clear internal error counter structure
 341         */
 342        ec = (u_long *)&smc->hw.fp.err_stats ;
 343        for (i = (sizeof(struct err_st)/sizeof(long)) ; i ; i--)
 344                *ec++ = 0L ;
 345        smc->mib.m[MAC0].fddiMACRingOp_Ct = 0 ;
 346}
 347
 348/*
 349 * set FORMAC address, and t_request
 350 */
 351static  void set_formac_addr(struct s_smc *smc)
 352{
 353        long    t_requ = smc->mib.m[MAC0].fddiMACT_Req ;
 354
 355        outpw(FM_A(FM_SAID),my_said) ;  /* set short address */
 356        outpw(FM_A(FM_LAIL),(unsigned short)((smc->hw.fddi_home_addr.a[4]<<8) +
 357                                        smc->hw.fddi_home_addr.a[5])) ;
 358        outpw(FM_A(FM_LAIC),(unsigned short)((smc->hw.fddi_home_addr.a[2]<<8) +
 359                                        smc->hw.fddi_home_addr.a[3])) ;
 360        outpw(FM_A(FM_LAIM),(unsigned short)((smc->hw.fddi_home_addr.a[0]<<8) +
 361                                        smc->hw.fddi_home_addr.a[1])) ;
 362
 363        outpw(FM_A(FM_SAGP),my_sagp) ;  /* set short group address */
 364
 365        outpw(FM_A(FM_LAGL),(unsigned short)((smc->hw.fp.group_addr.a[4]<<8) +
 366                                        smc->hw.fp.group_addr.a[5])) ;
 367        outpw(FM_A(FM_LAGC),(unsigned short)((smc->hw.fp.group_addr.a[2]<<8) +
 368                                        smc->hw.fp.group_addr.a[3])) ;
 369        outpw(FM_A(FM_LAGM),(unsigned short)((smc->hw.fp.group_addr.a[0]<<8) +
 370                                        smc->hw.fp.group_addr.a[1])) ;
 371
 372        /* set r_request regs. (MSW & LSW of TRT ) */
 373        outpw(FM_A(FM_TREQ1),(unsigned short)(t_requ>>16)) ;
 374        outpw(FM_A(FM_TREQ0),(unsigned short)t_requ) ;
 375}
 376
 377static void set_int(char *p, int l)
 378{
 379        p[0] = (char)(l >> 24) ;
 380        p[1] = (char)(l >> 16) ;
 381        p[2] = (char)(l >> 8) ;
 382        p[3] = (char)(l >> 0) ;
 383}
 384
 385/*
 386 * copy TX descriptor to buffer mem
 387 * append FC field and MAC frame
 388 * if more bit is set in descr
 389 *      append pointer to descriptor (endless loop)
 390 * else
 391 *      append 'end of chain' pointer
 392 */
 393static void copy_tx_mac(struct s_smc *smc, u_long td, struct fddi_mac *mac,
 394                        unsigned int off, int len)
 395/* u_long td;            transmit descriptor */
 396/* struct fddi_mac *mac; mac frame pointer */
 397/* unsigned int off;     start address within buffer memory */
 398/* int len ;             length of the frame including the FC */
 399{
 400        int     i ;
 401        __le32  *p ;
 402
 403        CHECK_NPP() ;
 404        MARW(off) ;             /* set memory address reg for writes */
 405
 406        p = (__le32 *) mac ;
 407        for (i = (len + 3)/4 ; i ; i--) {
 408                if (i == 1) {
 409                        /* last word, set the tag bit */
 410                        outpw(FM_A(FM_CMDREG2),FM_ISTTB) ;
 411                }
 412                write_mdr(smc,le32_to_cpu(*p)) ;
 413                p++ ;
 414        }
 415
 416        outpw(FM_A(FM_CMDREG2),FM_ISTTB) ;      /* set the tag bit */
 417        write_mdr(smc,td) ;     /* write over memory data reg to buffer */
 418}
 419
 420/*
 421        BEGIN_MANUAL_ENTRY(module;tests;3)
 422        How to test directed beacon frames
 423        ----------------------------------------------------------------
 424
 425        o Insert a break point in the function build_claim_beacon()
 426          before calling copy_tx_mac() for building the claim frame.
 427        o Modify the RM3_DETECT case so that the RM6_DETECT state
 428          will always entered from the RM3_DETECT state (function rmt_fsm(),
 429          rmt.c)
 430        o Compile the driver.
 431        o Set the parameter TREQ in the protocol.ini or net.cfg to a
 432          small value to make sure your station will win the claim
 433          process.
 434        o Start the driver.
 435        o When you reach the break point, modify the SA and DA address
 436          of the claim frame (e.g. SA = DA = 10005affffff).
 437        o When you see RM3_DETECT and RM6_DETECT, observe the direct
 438          beacon frames on the UPPSLANA.
 439
 440        END_MANUAL_ENTRY
 441 */
 442static void directed_beacon(struct s_smc *smc)
 443{
 444        SK_LOC_DECL(__le32,a[2]) ;
 445
 446        /*
 447         * set UNA in frame
 448         * enable FORMAC to send endless queue of directed beacon
 449         * important: the UNA starts at byte 1 (not at byte 0)
 450         */
 451        * (char *) a = (char) ((long)DBEACON_INFO<<24L) ;
 452        a[1] = 0 ;
 453        memcpy((char *)a+1, (char *) &smc->mib.m[MAC0].fddiMACUpstreamNbr, ETH_ALEN);
 454
 455        CHECK_NPP() ;
 456         /* set memory address reg for writes */
 457        MARW(smc->hw.fp.fifo.rbc_ram_start+DBEACON_FRAME_OFF+4) ;
 458        write_mdr(smc,le32_to_cpu(a[0])) ;
 459        outpw(FM_A(FM_CMDREG2),FM_ISTTB) ;      /* set the tag bit */
 460        write_mdr(smc,le32_to_cpu(a[1])) ;
 461
 462        outpw(FM_A(FM_SABC),smc->hw.fp.fifo.rbc_ram_start + DBEACON_FRAME_OFF) ;
 463}
 464
 465/*
 466        setup claim & beacon pointer
 467        NOTE :
 468                special frame packets end with a pointer to their own
 469                descriptor, and the MORE bit is set in the descriptor
 470*/
 471static void build_claim_beacon(struct s_smc *smc, u_long t_request)
 472{
 473        u_int   td ;
 474        int     len ;
 475        struct fddi_mac_sf *mac ;
 476
 477        /*
 478         * build claim packet
 479         */
 480        len = 17 ;
 481        td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ;
 482        mac = &smc->hw.fp.mac_sfb ;
 483        mac->mac_fc = FC_CLAIM ;
 484        /* DA == SA in claim frame */
 485        mac->mac_source = mac->mac_dest = MA ;
 486        /* 2's complement */
 487        set_int((char *)mac->mac_info,(int)t_request) ;
 488
 489        copy_tx_mac(smc,td,(struct fddi_mac *)mac,
 490                smc->hw.fp.fifo.rbc_ram_start + CLAIM_FRAME_OFF,len) ;
 491        /* set CLAIM start pointer */
 492        outpw(FM_A(FM_SACL),smc->hw.fp.fifo.rbc_ram_start + CLAIM_FRAME_OFF) ;
 493
 494        /*
 495         * build beacon packet
 496         */
 497        len = 17 ;
 498        td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ;
 499        mac->mac_fc = FC_BEACON ;
 500        mac->mac_source = MA ;
 501        mac->mac_dest = null_addr ;             /* DA == 0 in beacon frame */
 502        set_int((char *) mac->mac_info,((int)BEACON_INFO<<24) + 0 ) ;
 503
 504        copy_tx_mac(smc,td,(struct fddi_mac *)mac,
 505                smc->hw.fp.fifo.rbc_ram_start + BEACON_FRAME_OFF,len) ;
 506        /* set beacon start pointer */
 507        outpw(FM_A(FM_SABC),smc->hw.fp.fifo.rbc_ram_start + BEACON_FRAME_OFF) ;
 508
 509        /*
 510         * build directed beacon packet
 511         * contains optional UNA
 512         */
 513        len = 23 ;
 514        td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ;
 515        mac->mac_fc = FC_BEACON ;
 516        mac->mac_source = MA ;
 517        mac->mac_dest = dbeacon_multi ;         /* multicast */
 518        set_int((char *) mac->mac_info,((int)DBEACON_INFO<<24) + 0 ) ;
 519        set_int((char *) mac->mac_info+4,0) ;
 520        set_int((char *) mac->mac_info+8,0) ;
 521
 522        copy_tx_mac(smc,td,(struct fddi_mac *)mac,
 523                smc->hw.fp.fifo.rbc_ram_start + DBEACON_FRAME_OFF,len) ;
 524
 525        /* end of claim/beacon queue */
 526        outpw(FM_A(FM_EACB),smc->hw.fp.fifo.rx1_fifo_start-1) ;
 527
 528        outpw(FM_A(FM_WPXSF),0) ;
 529        outpw(FM_A(FM_RPXSF),0) ;
 530}
 531
 532static void formac_rcv_restart(struct s_smc *smc)
 533{
 534        /* enable receive function */
 535        SETMASK(FM_A(FM_MDREG1),smc->hw.fp.rx_mode,FM_ADDRX) ;
 536
 537        outpw(FM_A(FM_CMDREG1),FM_ICLLR) ;      /* clear receive lock */
 538}
 539
 540void formac_tx_restart(struct s_smc *smc)
 541{
 542        outpw(FM_A(FM_CMDREG1),FM_ICLLS) ;      /* clear s-frame lock */
 543        outpw(FM_A(FM_CMDREG1),FM_ICLLA0) ;     /* clear a-frame lock */
 544}
 545
 546static void enable_formac(struct s_smc *smc)
 547{
 548        /* set formac IMSK : 0 enables irq */
 549        outpw(FM_A(FM_IMSK1U),(unsigned short)~mac_imsk1u);
 550        outpw(FM_A(FM_IMSK1L),(unsigned short)~mac_imsk1l);
 551        outpw(FM_A(FM_IMSK2U),(unsigned short)~mac_imsk2u);
 552        outpw(FM_A(FM_IMSK2L),(unsigned short)~mac_imsk2l);
 553        outpw(FM_A(FM_IMSK3U),(unsigned short)~mac_imsk3u);
 554        outpw(FM_A(FM_IMSK3L),(unsigned short)~mac_imsk3l);
 555}
 556
 557#if 0   /* Removed because the driver should use the ASICs TX complete IRQ. */
 558        /* The FORMACs tx complete IRQ should be used any longer */
 559
 560/*
 561        BEGIN_MANUAL_ENTRY(if,func;others;4)
 562
 563        void enable_tx_irq(smc, queue)
 564        struct s_smc *smc ;
 565        u_short queue ;
 566
 567Function        DOWNCALL        (SMT, fplustm.c)
 568                enable_tx_irq() enables the FORMACs transmit complete
 569                interrupt of the queue.
 570
 571Para    queue   = QUEUE_S:      synchronous queue
 572                = QUEUE_A0:     asynchronous queue
 573
 574Note    After any ring operational change the transmit complete
 575        interrupts are disabled.
 576        The operating system dependent module must enable
 577        the transmit complete interrupt of a queue,
 578                - when it queues the first frame,
 579                  because of no transmit resources are beeing
 580                  available and
 581                - when it escapes from the function llc_restart_tx
 582                  while some frames are still queued.
 583
 584        END_MANUAL_ENTRY
 585 */
 586void enable_tx_irq(struct s_smc *smc, u_short queue)
 587/* u_short queue; 0 = synchronous queue, 1 = asynchronous queue 0 */
 588{
 589        u_short imask ;
 590
 591        imask = ~(inpw(FM_A(FM_IMSK1U))) ;
 592
 593        if (queue == 0) {
 594                outpw(FM_A(FM_IMSK1U),~(imask|FM_STEFRMS)) ;
 595        }
 596        if (queue == 1) {
 597                outpw(FM_A(FM_IMSK1U),~(imask|FM_STEFRMA0)) ;
 598        }
 599}
 600
 601/*
 602        BEGIN_MANUAL_ENTRY(if,func;others;4)
 603
 604        void disable_tx_irq(smc, queue)
 605        struct s_smc *smc ;
 606        u_short queue ;
 607
 608Function        DOWNCALL        (SMT, fplustm.c)
 609                disable_tx_irq disables the FORMACs transmit complete
 610                interrupt of the queue
 611
 612Para    queue   = QUEUE_S:      synchronous queue
 613                = QUEUE_A0:     asynchronous queue
 614
 615Note    The operating system dependent module should disable
 616        the transmit complete interrupts if it escapes from the
 617        function llc_restart_tx and no frames are queued.
 618
 619        END_MANUAL_ENTRY
 620 */
 621void disable_tx_irq(struct s_smc *smc, u_short queue)
 622/* u_short queue; 0 = synchronous queue, 1 = asynchronous queue 0 */
 623{
 624        u_short imask ;
 625
 626        imask = ~(inpw(FM_A(FM_IMSK1U))) ;
 627
 628        if (queue == 0) {
 629                outpw(FM_A(FM_IMSK1U),~(imask&~FM_STEFRMS)) ;
 630        }
 631        if (queue == 1) {
 632                outpw(FM_A(FM_IMSK1U),~(imask&~FM_STEFRMA0)) ;
 633        }
 634}
 635#endif
 636
 637static void disable_formac(struct s_smc *smc)
 638{
 639        /* clear formac IMSK : 1 disables irq */
 640        outpw(FM_A(FM_IMSK1U),MW) ;
 641        outpw(FM_A(FM_IMSK1L),MW) ;
 642        outpw(FM_A(FM_IMSK2U),MW) ;
 643        outpw(FM_A(FM_IMSK2L),MW) ;
 644        outpw(FM_A(FM_IMSK3U),MW) ;
 645        outpw(FM_A(FM_IMSK3L),MW) ;
 646}
 647
 648
 649static void mac_ring_up(struct s_smc *smc, int up)
 650{
 651        if (up) {
 652                formac_rcv_restart(smc) ;       /* enable receive function */
 653                smc->hw.mac_ring_is_up = TRUE ;
 654                llc_restart_tx(smc) ;           /* TX queue */
 655        }
 656        else {
 657                /* disable receive function */
 658                SETMASK(FM_A(FM_MDREG1),FM_MDISRCV,FM_ADDET) ;
 659
 660                /* abort current transmit activity */
 661                outpw(FM_A(FM_CMDREG2),FM_IACTR) ;
 662
 663                smc->hw.mac_ring_is_up = FALSE ;
 664        }
 665}
 666
 667/*--------------------------- ISR handling ----------------------------------*/
 668/*
 669 * mac1_irq is in drvfbi.c
 670 */
 671
 672/*
 673 * mac2_irq:    status bits for the receive queue 1, and ring status
 674 *              ring status indication bits
 675 */
 676void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l)
 677{
 678        u_short change_s2l ;
 679        u_short change_s2u ;
 680
 681        /* (jd) 22-Feb-1999
 682         * Restart 2_DMax Timer after end of claiming or beaconing
 683         */
 684        if (code_s2u & (FM_SCLM|FM_SHICLM|FM_SBEC|FM_SOTRBEC)) {
 685                queue_event(smc,EVENT_RMT,RM_TX_STATE_CHANGE) ;
 686        }
 687        else if (code_s2l & (FM_STKISS)) {
 688                queue_event(smc,EVENT_RMT,RM_TX_STATE_CHANGE) ;
 689        }
 690
 691        /*
 692         * XOR current st bits with the last to avoid useless RMT event queuing
 693         */
 694        change_s2l = smc->hw.fp.s2l ^ code_s2l ;
 695        change_s2u = smc->hw.fp.s2u ^ code_s2u ;
 696
 697        if ((change_s2l & FM_SRNGOP) ||
 698                (!smc->hw.mac_ring_is_up && ((code_s2l & FM_SRNGOP)))) {
 699                if (code_s2l & FM_SRNGOP) {
 700                        mac_ring_up(smc,1) ;
 701                        queue_event(smc,EVENT_RMT,RM_RING_OP) ;
 702                        smc->mib.m[MAC0].fddiMACRingOp_Ct++ ;
 703                }
 704                else {
 705                        mac_ring_up(smc,0) ;
 706                        queue_event(smc,EVENT_RMT,RM_RING_NON_OP) ;
 707                }
 708                goto mac2_end ;
 709        }
 710        if (code_s2l & FM_SMISFRM) {    /* missed frame */
 711                smc->mib.m[MAC0].fddiMACNotCopied_Ct++ ;
 712        }
 713        if (code_s2u & (FM_SRCVOVR |    /* recv. FIFO overflow */
 714                        FM_SRBFL)) {    /* recv. buffer full */
 715                smc->hw.mac_ct.mac_r_restart_counter++ ;
 716/*              formac_rcv_restart(smc) ;       */
 717                smt_stat_counter(smc,1) ;
 718/*              goto mac2_end ;                 */
 719        }
 720        if (code_s2u & FM_SOTRBEC)
 721                queue_event(smc,EVENT_RMT,RM_OTHER_BEACON) ;
 722        if (code_s2u & FM_SMYBEC)
 723                queue_event(smc,EVENT_RMT,RM_MY_BEACON) ;
 724        if (change_s2u & code_s2u & FM_SLOCLM) {
 725                DB_RMTN(2, "RMT : lower claim received");
 726        }
 727        if ((code_s2u & FM_SMYCLM) && !(code_s2l & FM_SDUPCLM)) {
 728                /*
 729                 * This is my claim and that claim is not detected as a
 730                 * duplicate one.
 731                 */
 732                queue_event(smc,EVENT_RMT,RM_MY_CLAIM) ;
 733        }
 734        if (code_s2l & FM_SDUPCLM) {
 735                /*
 736                 * If a duplicate claim frame (same SA but T_Bid != T_Req)
 737                 * this flag will be set.
 738                 * In the RMT state machine we need a RM_VALID_CLAIM event
 739                 * to do the appropriate state change.
 740                 * RM(34c)
 741                 */
 742                queue_event(smc,EVENT_RMT,RM_VALID_CLAIM) ;
 743        }
 744        if (change_s2u & code_s2u & FM_SHICLM) {
 745                DB_RMTN(2, "RMT : higher claim received");
 746        }
 747        if ( (code_s2l & FM_STRTEXP) ||
 748             (code_s2l & FM_STRTEXR) )
 749                queue_event(smc,EVENT_RMT,RM_TRT_EXP) ;
 750        if (code_s2l & FM_SMULTDA) {
 751                /*
 752                 * The MAC has found a 2. MAC with the same address.
 753                 * Signal dup_addr_test = failed to RMT state machine.
 754                 * RM(25)
 755                 */
 756                smc->r.dup_addr_test = DA_FAILED ;
 757                queue_event(smc,EVENT_RMT,RM_DUP_ADDR) ;
 758        }
 759        if (code_s2u & FM_SBEC)
 760                smc->hw.fp.err_stats.err_bec_stat++ ;
 761        if (code_s2u & FM_SCLM)
 762                smc->hw.fp.err_stats.err_clm_stat++ ;
 763        if (code_s2l & FM_STVXEXP)
 764                smc->mib.m[MAC0].fddiMACTvxExpired_Ct++ ;
 765        if ((code_s2u & (FM_SBEC|FM_SCLM))) {
 766                if (!(change_s2l & FM_SRNGOP) && (smc->hw.fp.s2l & FM_SRNGOP)) {
 767                        mac_ring_up(smc,0) ;
 768                        queue_event(smc,EVENT_RMT,RM_RING_NON_OP) ;
 769
 770                        mac_ring_up(smc,1) ;
 771                        queue_event(smc,EVENT_RMT,RM_RING_OP) ;
 772                        smc->mib.m[MAC0].fddiMACRingOp_Ct++ ;
 773                }
 774        }
 775        if (code_s2l & FM_SPHINV)
 776                smc->hw.fp.err_stats.err_phinv++ ;
 777        if (code_s2l & FM_SSIFG)
 778                smc->hw.fp.err_stats.err_sifg_det++ ;
 779        if (code_s2l & FM_STKISS)
 780                smc->hw.fp.err_stats.err_tkiss++ ;
 781        if (code_s2l & FM_STKERR)
 782                smc->hw.fp.err_stats.err_tkerr++ ;
 783        if (code_s2l & FM_SFRMCTR)
 784                smc->mib.m[MAC0].fddiMACFrame_Ct += 0x10000L ;
 785        if (code_s2l & FM_SERRCTR)
 786                smc->mib.m[MAC0].fddiMACError_Ct += 0x10000L ;
 787        if (code_s2l & FM_SLSTCTR)
 788                smc->mib.m[MAC0].fddiMACLost_Ct  += 0x10000L ;
 789        if (code_s2u & FM_SERRSF) {
 790                SMT_PANIC(smc,SMT_E0114, SMT_E0114_MSG) ;
 791        }
 792mac2_end:
 793        /* notice old status */
 794        smc->hw.fp.s2l = code_s2l ;
 795        smc->hw.fp.s2u = code_s2u ;
 796        outpw(FM_A(FM_IMSK2U),~mac_imsk2u) ;
 797}
 798
 799/*
 800 * mac3_irq:    receive queue 2 bits and address detection bits
 801 */
 802void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l)
 803{
 804        UNUSED(code_s3l) ;
 805
 806        if (code_s3u & (FM_SRCVOVR2 |   /* recv. FIFO overflow */
 807                        FM_SRBFL2)) {   /* recv. buffer full */
 808                smc->hw.mac_ct.mac_r_restart_counter++ ;
 809                smt_stat_counter(smc,1);
 810        }
 811
 812
 813        if (code_s3u & FM_SRPERRQ2) {   /* parity error receive queue 2 */
 814                SMT_PANIC(smc,SMT_E0115, SMT_E0115_MSG) ;
 815        }
 816        if (code_s3u & FM_SRPERRQ1) {   /* parity error receive queue 2 */
 817                SMT_PANIC(smc,SMT_E0116, SMT_E0116_MSG) ;
 818        }
 819}
 820
 821
 822/*
 823 * take formac offline
 824 */
 825static void formac_offline(struct s_smc *smc)
 826{
 827        outpw(FM_A(FM_CMDREG2),FM_IACTR) ;/* abort current transmit activity */
 828
 829        /* disable receive function */
 830        SETMASK(FM_A(FM_MDREG1),FM_MDISRCV,FM_ADDET) ;
 831
 832        /* FORMAC+ 'Initialize Mode' */
 833        SETMASK(FM_A(FM_MDREG1),FM_MINIT,FM_MMODE) ;
 834
 835        disable_formac(smc) ;
 836        smc->hw.mac_ring_is_up = FALSE ;
 837        smc->hw.hw_state = STOPPED ;
 838}
 839
 840/*
 841 * bring formac online
 842 */
 843static void formac_online(struct s_smc *smc)
 844{
 845        enable_formac(smc) ;
 846        SETMASK(FM_A(FM_MDREG1),FM_MONLINE | FM_SELRA | MDR1INIT |
 847                smc->hw.fp.rx_mode, FM_MMODE | FM_SELRA | FM_ADDRX) ;
 848}
 849
 850/*
 851 * FORMAC+ full init. (tx, rx, timer, counter, claim & beacon)
 852 */
 853int init_fplus(struct s_smc *smc)
 854{
 855        smc->hw.fp.nsa_mode = FM_MRNNSAFNMA ;
 856        smc->hw.fp.rx_mode = FM_MDAMA ;
 857        smc->hw.fp.group_addr = fddi_broadcast ;
 858        smc->hw.fp.func_addr = 0 ;
 859        smc->hw.fp.frselreg_init = 0 ;
 860
 861        init_driver_fplus(smc) ;
 862        if (smc->s.sas == SMT_DAS)
 863                smc->hw.fp.mdr3init |= FM_MENDAS ;
 864
 865        smc->hw.mac_ct.mac_nobuf_counter = 0 ;
 866        smc->hw.mac_ct.mac_r_restart_counter = 0 ;
 867
 868        smc->hw.fp.fm_st1u = (HW_PTR) ADDR(B0_ST1U) ;
 869        smc->hw.fp.fm_st1l = (HW_PTR) ADDR(B0_ST1L) ;
 870        smc->hw.fp.fm_st2u = (HW_PTR) ADDR(B0_ST2U) ;
 871        smc->hw.fp.fm_st2l = (HW_PTR) ADDR(B0_ST2L) ;
 872        smc->hw.fp.fm_st3u = (HW_PTR) ADDR(B0_ST3U) ;
 873        smc->hw.fp.fm_st3l = (HW_PTR) ADDR(B0_ST3L) ;
 874
 875        smc->hw.fp.s2l = smc->hw.fp.s2u = 0 ;
 876        smc->hw.mac_ring_is_up = 0 ;
 877
 878        mac_counter_init(smc) ;
 879
 880        /* convert BCKL units to symbol time */
 881        smc->hw.mac_pa.t_neg = (u_long)0 ;
 882        smc->hw.mac_pa.t_pri = (u_long)0 ;
 883
 884        /* make sure all PCI settings are correct */
 885        mac_do_pci_fix(smc) ;
 886
 887        return init_mac(smc, 1);
 888        /* enable_formac(smc) ; */
 889}
 890
 891static int init_mac(struct s_smc *smc, int all)
 892{
 893        u_short t_max,x ;
 894        u_long  time=0 ;
 895
 896        /*
 897         * clear memory
 898         */
 899        outpw(FM_A(FM_MDREG1),FM_MINIT) ;       /* FORMAC+ init mode */
 900        set_formac_addr(smc) ;
 901        outpw(FM_A(FM_MDREG1),FM_MMEMACT) ;     /* FORMAC+ memory activ mode */
 902        /* Note: Mode register 2 is set here, incase parity is enabled. */
 903        outpw(FM_A(FM_MDREG2),smc->hw.fp.mdr2init) ;
 904
 905        if (all) {
 906                init_ram(smc) ;
 907        }
 908        else {
 909                /*
 910                 * reset the HPI, the Master and the BMUs
 911                 */
 912                outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;
 913                time = hwt_quick_read(smc) ;
 914        }
 915
 916        /*
 917         * set all pointers, frames etc
 918         */
 919        smt_split_up_fifo(smc) ;
 920
 921        init_tx(smc) ;
 922        init_rx(smc) ;
 923        init_rbc(smc) ;
 924
 925        build_claim_beacon(smc,smc->mib.m[MAC0].fddiMACT_Req) ;
 926
 927        /* set RX threshold */
 928        /* see Errata #SN2 Phantom receive overflow */
 929        outpw(FM_A(FM_FRMTHR),14<<12) ;         /* switch on */
 930
 931        /* set formac work mode */
 932        outpw(FM_A(FM_MDREG1),MDR1INIT | FM_SELRA | smc->hw.fp.rx_mode) ;
 933        outpw(FM_A(FM_MDREG2),smc->hw.fp.mdr2init) ;
 934        outpw(FM_A(FM_MDREG3),smc->hw.fp.mdr3init) ;
 935        outpw(FM_A(FM_FRSELREG),smc->hw.fp.frselreg_init) ;
 936
 937        /* set timer */
 938        /*
 939         * errata #22 fplus:
 940         * T_MAX must not be FFFE
 941         * or one of FFDF, FFB8, FF91 (-0x27 etc..)
 942         */
 943        t_max = (u_short)(smc->mib.m[MAC0].fddiMACT_Max/32) ;
 944        x = t_max/0x27 ;
 945        x *= 0x27 ;
 946        if ((t_max == 0xfffe) || (t_max - x == 0x16))
 947                t_max-- ;
 948        outpw(FM_A(FM_TMAX),(u_short)t_max) ;
 949
 950        /* BugFix for report #10204 */
 951        if (smc->mib.m[MAC0].fddiMACTvxValue < (u_long) (- US2BCLK(52))) {
 952                outpw(FM_A(FM_TVX), (u_short) (- US2BCLK(52))/255 & MB) ;
 953        } else {
 954                outpw(FM_A(FM_TVX),
 955                        (u_short)((smc->mib.m[MAC0].fddiMACTvxValue/255) & MB)) ;
 956        }
 957
 958        outpw(FM_A(FM_CMDREG1),FM_ICLLS) ;      /* clear s-frame lock */
 959        outpw(FM_A(FM_CMDREG1),FM_ICLLA0) ;     /* clear a-frame lock */
 960        outpw(FM_A(FM_CMDREG1),FM_ICLLR);       /* clear receive lock */
 961
 962        /* Auto unlock receice threshold for receive queue 1 and 2 */
 963        outpw(FM_A(FM_UNLCKDLY),(0xff|(0xff<<8))) ;
 964
 965        rtm_init(smc) ;                         /* RT-Monitor */
 966
 967        if (!all) {
 968                /*
 969                 * after 10ms, reset the BMUs and repair the rings
 970                 */
 971                hwt_wait_time(smc,time,MS2BCLK(10)) ;
 972                outpd(ADDR(B0_R1_CSR),CSR_SET_RESET) ;
 973                outpd(ADDR(B0_XA_CSR),CSR_SET_RESET) ;
 974                outpd(ADDR(B0_XS_CSR),CSR_SET_RESET) ;
 975                outp(ADDR(B0_CTRL), CTRL_HPI_CLR) ;
 976                outpd(ADDR(B0_R1_CSR),CSR_CLR_RESET) ;
 977                outpd(ADDR(B0_XA_CSR),CSR_CLR_RESET) ;
 978                outpd(ADDR(B0_XS_CSR),CSR_CLR_RESET) ;
 979                if (!smc->hw.hw_is_64bit) {
 980                        outpd(ADDR(B4_R1_F), RX_WATERMARK) ;
 981                        outpd(ADDR(B5_XA_F), TX_WATERMARK) ;
 982                        outpd(ADDR(B5_XS_F), TX_WATERMARK) ;
 983                }
 984                smc->hw.hw_state = STOPPED ;
 985                mac_drv_repair_descr(smc) ;
 986        }
 987        smc->hw.hw_state = STARTED ;
 988
 989        return 0;
 990}
 991
 992
 993/*
 994 * called by CFM
 995 */
 996void config_mux(struct s_smc *smc, int mux)
 997{
 998        plc_config_mux(smc,mux) ;
 999
1000        SETMASK(FM_A(FM_MDREG1),FM_SELRA,FM_SELRA) ;
1001}
1002
1003/*
1004 * called by RMT
1005 * enable CLAIM/BEACON interrupts
1006 * (only called if these events are of interest, e.g. in DETECT state
1007 * the interrupt must not be permanently enabled
1008 * RMT calls this function periodically (timer driven polling)
1009 */
1010void sm_mac_check_beacon_claim(struct s_smc *smc)
1011{
1012        /* set formac IMSK : 0 enables irq */
1013        outpw(FM_A(FM_IMSK2U),~(mac_imsk2u | mac_beacon_imsk2u)) ;
1014        /* the driver must receive the directed beacons */
1015        formac_rcv_restart(smc) ;
1016        process_receive(smc) ;
1017}
1018
1019/*-------------------------- interface functions ----------------------------*/
1020/*
1021 * control MAC layer    (called by RMT)
1022 */
1023void sm_ma_control(struct s_smc *smc, int mode)
1024{
1025        switch(mode) {
1026        case MA_OFFLINE :
1027                /* Add to make the MAC offline in RM0_ISOLATED state */
1028                formac_offline(smc) ;
1029                break ;
1030        case MA_RESET :
1031                (void)init_mac(smc,0) ;
1032                break ;
1033        case MA_BEACON :
1034                formac_online(smc) ;
1035                break ;
1036        case MA_DIRECTED :
1037                directed_beacon(smc) ;
1038                break ;
1039        case MA_TREQ :
1040                /*
1041                 * no actions necessary, TREQ is already set
1042                 */
1043                break ;
1044        }
1045}
1046
1047int sm_mac_get_tx_state(struct s_smc *smc)
1048{
1049        return (inpw(FM_A(FM_STMCHN))>>4) & 7;
1050}
1051
1052/*
1053 * multicast functions
1054 */
1055
1056static struct s_fpmc* mac_get_mc_table(struct s_smc *smc,
1057                                       struct fddi_addr *user,
1058                                       struct fddi_addr *own,
1059                                       int del, int can)
1060{
1061        struct s_fpmc   *tb ;
1062        struct s_fpmc   *slot ;
1063        u_char  *p ;
1064        int i ;
1065
1066        /*
1067         * set own = can(user)
1068         */
1069        *own = *user ;
1070        if (can) {
1071                p = own->a ;
1072                for (i = 0 ; i < 6 ; i++, p++)
1073                        *p = bitrev8(*p);
1074        }
1075        slot = NULL;
1076        for (i = 0, tb = smc->hw.fp.mc.table ; i < FPMAX_MULTICAST ; i++, tb++){
1077                if (!tb->n) {           /* not used */
1078                        if (!del && !slot)      /* if !del save first free */
1079                                slot = tb ;
1080                        continue ;
1081                }
1082                if (!ether_addr_equal((char *)&tb->a, (char *)own))
1083                        continue ;
1084                return tb;
1085        }
1086        return slot;                    /* return first free or NULL */
1087}
1088
1089/*
1090        BEGIN_MANUAL_ENTRY(if,func;others;2)
1091
1092        void mac_clear_multicast(smc)
1093        struct s_smc *smc ;
1094
1095Function        DOWNCALL        (SMT, fplustm.c)
1096                Clear all multicast entries
1097
1098        END_MANUAL_ENTRY()
1099 */
1100void mac_clear_multicast(struct s_smc *smc)
1101{
1102        struct s_fpmc   *tb ;
1103        int i ;
1104
1105        smc->hw.fp.os_slots_used = 0 ;  /* note the SMT addresses */
1106                                        /* will not be deleted */
1107        for (i = 0, tb = smc->hw.fp.mc.table ; i < FPMAX_MULTICAST ; i++, tb++){
1108                if (!tb->perm) {
1109                        tb->n = 0 ;
1110                }
1111        }
1112}
1113
1114/*
1115        BEGIN_MANUAL_ENTRY(if,func;others;2)
1116
1117        int mac_add_multicast(smc,addr,can)
1118        struct s_smc *smc ;
1119        struct fddi_addr *addr ;
1120        int can ;
1121
1122Function        DOWNCALL        (SMC, fplustm.c)
1123                Add an entry to the multicast table
1124
1125Para    addr    pointer to a multicast address
1126        can     = 0:    the multicast address has the physical format
1127                = 1:    the multicast address has the canonical format
1128                | 0x80  permanent
1129
1130Returns 0: success
1131        1: address table full
1132
1133Note    After a 'driver reset' or a 'station set address' all
1134        entries of the multicast table are cleared.
1135        In this case the driver has to fill the multicast table again.
1136        After the operating system dependent module filled
1137        the multicast table it must call mac_update_multicast
1138        to activate the new multicast addresses!
1139
1140        END_MANUAL_ENTRY()
1141 */
1142int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can)
1143{
1144        SK_LOC_DECL(struct fddi_addr,own) ;
1145        struct s_fpmc   *tb ;
1146
1147        /*
1148         * check if there are free table entries
1149         */
1150        if (can & 0x80) {
1151                if (smc->hw.fp.smt_slots_used >= SMT_MAX_MULTI) {
1152                        return 1;
1153                }
1154        }
1155        else {
1156                if (smc->hw.fp.os_slots_used >= FPMAX_MULTICAST-SMT_MAX_MULTI) {
1157                        return 1;
1158                }
1159        }
1160
1161        /*
1162         * find empty slot
1163         */
1164        if (!(tb = mac_get_mc_table(smc,addr,&own,0,can & ~0x80)))
1165                return 1;
1166        tb->n++ ;
1167        tb->a = own ;
1168        tb->perm = (can & 0x80) ? 1 : 0 ;
1169
1170        if (can & 0x80)
1171                smc->hw.fp.smt_slots_used++ ;
1172        else
1173                smc->hw.fp.os_slots_used++ ;
1174
1175        return 0;
1176}
1177
1178/*
1179 * mode
1180 */
1181
1182#define RX_MODE_PROM            0x1
1183#define RX_MODE_ALL_MULTI       0x2
1184
1185/*
1186        BEGIN_MANUAL_ENTRY(if,func;others;2)
1187
1188        void mac_update_multicast(smc)
1189        struct s_smc *smc ;
1190
1191Function        DOWNCALL        (SMT, fplustm.c)
1192                Update FORMAC multicast registers
1193
1194        END_MANUAL_ENTRY()
1195 */
1196void mac_update_multicast(struct s_smc *smc)
1197{
1198        struct s_fpmc   *tb ;
1199        u_char  *fu ;
1200        int     i ;
1201
1202        /*
1203         * invalidate the CAM
1204         */
1205        outpw(FM_A(FM_AFCMD),FM_IINV_CAM) ;
1206
1207        /*
1208         * set the functional address
1209         */
1210        if (smc->hw.fp.func_addr) {
1211                fu = (u_char *) &smc->hw.fp.func_addr ;
1212                outpw(FM_A(FM_AFMASK2),0xffff) ;
1213                outpw(FM_A(FM_AFMASK1),(u_short) ~((fu[0] << 8) + fu[1])) ;
1214                outpw(FM_A(FM_AFMASK0),(u_short) ~((fu[2] << 8) + fu[3])) ;
1215                outpw(FM_A(FM_AFPERS),FM_VALID|FM_DA) ;
1216                outpw(FM_A(FM_AFCOMP2), 0xc000) ;
1217                outpw(FM_A(FM_AFCOMP1), 0x0000) ;
1218                outpw(FM_A(FM_AFCOMP0), 0x0000) ;
1219                outpw(FM_A(FM_AFCMD),FM_IWRITE_CAM) ;
1220        }
1221
1222        /*
1223         * set the mask and the personality register(s)
1224         */
1225        outpw(FM_A(FM_AFMASK0),0xffff) ;
1226        outpw(FM_A(FM_AFMASK1),0xffff) ;
1227        outpw(FM_A(FM_AFMASK2),0xffff) ;
1228        outpw(FM_A(FM_AFPERS),FM_VALID|FM_DA) ;
1229
1230        for (i = 0, tb = smc->hw.fp.mc.table; i < FPMAX_MULTICAST; i++, tb++) {
1231                if (tb->n) {
1232                        CHECK_CAM() ;
1233
1234                        /*
1235                         * write the multicast address into the CAM
1236                         */
1237                        outpw(FM_A(FM_AFCOMP2),
1238                                (u_short)((tb->a.a[0]<<8)+tb->a.a[1])) ;
1239                        outpw(FM_A(FM_AFCOMP1),
1240                                (u_short)((tb->a.a[2]<<8)+tb->a.a[3])) ;
1241                        outpw(FM_A(FM_AFCOMP0),
1242                                (u_short)((tb->a.a[4]<<8)+tb->a.a[5])) ;
1243                        outpw(FM_A(FM_AFCMD),FM_IWRITE_CAM) ;
1244                }
1245        }
1246}
1247
1248/*
1249        BEGIN_MANUAL_ENTRY(if,func;others;3)
1250
1251        void mac_set_rx_mode(smc,mode)
1252        struct s_smc *smc ;
1253        int mode ;
1254
1255Function        DOWNCALL/INTERN (SMT, fplustm.c)
1256                This function enables / disables the selected receive.
1257                Don't call this function if the hardware module is
1258                used -- use mac_drv_rx_mode() instead of.
1259
1260Para    mode =  1       RX_ENABLE_ALLMULTI      enable all multicasts
1261                2       RX_DISABLE_ALLMULTI     disable "enable all multicasts"
1262                3       RX_ENABLE_PROMISC       enable promiscuous
1263                4       RX_DISABLE_PROMISC      disable promiscuous
1264                5       RX_ENABLE_NSA           enable reception of NSA frames
1265                6       RX_DISABLE_NSA          disable reception of NSA frames
1266
1267Note    The selected receive modes will be lost after 'driver reset'
1268        or 'set station address'
1269
1270        END_MANUAL_ENTRY
1271 */
1272void mac_set_rx_mode(struct s_smc *smc, int mode)
1273{
1274        switch (mode) {
1275        case RX_ENABLE_ALLMULTI :
1276                smc->hw.fp.rx_prom |= RX_MODE_ALL_MULTI ;
1277                break ;
1278        case RX_DISABLE_ALLMULTI :
1279                smc->hw.fp.rx_prom &= ~RX_MODE_ALL_MULTI ;
1280                break ;
1281        case RX_ENABLE_PROMISC :
1282                smc->hw.fp.rx_prom |= RX_MODE_PROM ;
1283                break ;
1284        case RX_DISABLE_PROMISC :
1285                smc->hw.fp.rx_prom &= ~RX_MODE_PROM ;
1286                break ;
1287        case RX_ENABLE_NSA :
1288                smc->hw.fp.nsa_mode = FM_MDAMA ;
1289                smc->hw.fp.rx_mode = (smc->hw.fp.rx_mode & ~FM_ADDET) |
1290                        smc->hw.fp.nsa_mode ;
1291                break ;
1292        case RX_DISABLE_NSA :
1293                smc->hw.fp.nsa_mode = FM_MRNNSAFNMA ;
1294                smc->hw.fp.rx_mode = (smc->hw.fp.rx_mode & ~FM_ADDET) |
1295                        smc->hw.fp.nsa_mode ;
1296                break ;
1297        }
1298        if (smc->hw.fp.rx_prom & RX_MODE_PROM) {
1299                smc->hw.fp.rx_mode = FM_MLIMPROM ;
1300        }
1301        else if (smc->hw.fp.rx_prom & RX_MODE_ALL_MULTI) {
1302                smc->hw.fp.rx_mode = smc->hw.fp.nsa_mode | FM_EXGPA0 ;
1303        }
1304        else
1305                smc->hw.fp.rx_mode = smc->hw.fp.nsa_mode ;
1306        SETMASK(FM_A(FM_MDREG1),smc->hw.fp.rx_mode,FM_ADDRX) ;
1307        mac_update_multicast(smc) ;
1308}
1309
1310/*
1311        BEGIN_MANUAL_ENTRY(module;tests;3)
1312        How to test the Restricted Token Monitor
1313        ----------------------------------------------------------------
1314
1315        o Insert a break point in the function rtm_irq()
1316        o Remove all stations with a restricted token monitor from the
1317          network.
1318        o Connect a UPPS ISA or EISA station to the network.
1319        o Give the FORMAC of UPPS station the command to send
1320          restricted tokens until the ring becomes instable.
1321        o Now connect your test test client.
1322        o The restricted token monitor should detect the restricted token,
1323          and your break point will be reached.
1324        o You can ovserve how the station will clean the ring.
1325
1326        END_MANUAL_ENTRY
1327 */
1328void rtm_irq(struct s_smc *smc)
1329{
1330        outpw(ADDR(B2_RTM_CRTL),TIM_CL_IRQ) ;           /* clear IRQ */
1331        if (inpw(ADDR(B2_RTM_CRTL)) & TIM_RES_TOK) {
1332                outpw(FM_A(FM_CMDREG1),FM_ICL) ;        /* force claim */
1333                DB_RMT("RMT: fddiPATHT_Rmode expired");
1334                AIX_EVENT(smc, (u_long) FDDI_RING_STATUS,
1335                                (u_long) FDDI_SMT_EVENT,
1336                                (u_long) FDDI_RTT, smt_get_event_word(smc));
1337        }
1338        outpw(ADDR(B2_RTM_CRTL),TIM_START) ;    /* enable RTM monitoring */
1339}
1340
1341static void rtm_init(struct s_smc *smc)
1342{
1343        outpd(ADDR(B2_RTM_INI),0) ;             /* timer = 0 */
1344        outpw(ADDR(B2_RTM_CRTL),TIM_START) ;    /* enable IRQ */
1345}
1346
1347void rtm_set_timer(struct s_smc *smc)
1348{
1349        /*
1350         * MIB timer and hardware timer have the same resolution of 80nS
1351         */
1352        DB_RMT("RMT: setting new fddiPATHT_Rmode, t = %d ns",
1353               (int)smc->mib.a[PATH0].fddiPATHT_Rmode);
1354        outpd(ADDR(B2_RTM_INI),smc->mib.a[PATH0].fddiPATHT_Rmode) ;
1355}
1356
1357static void smt_split_up_fifo(struct s_smc *smc)
1358{
1359
1360/*
1361        BEGIN_MANUAL_ENTRY(module;mem;1)
1362        -------------------------------------------------------------
1363        RECEIVE BUFFER MEMORY DIVERSION
1364        -------------------------------------------------------------
1365
1366        R1_RxD == SMT_R1_RXD_COUNT
1367        R2_RxD == SMT_R2_RXD_COUNT
1368
1369        SMT_R1_RXD_COUNT must be unequal zero
1370
1371                   | R1_RxD R2_RxD |R1_RxD R2_RxD | R1_RxD R2_RxD
1372                   |   x      0    |  x     1-3   |   x     < 3
1373        ----------------------------------------------------------------------
1374                   |   63,75 kB    |    54,75     |     R1_RxD
1375        rx queue 1 | RX_FIFO_SPACE | RX_LARGE_FIFO| ------------- * 63,75 kB
1376                   |               |              | R1_RxD+R2_RxD
1377        ----------------------------------------------------------------------
1378                   |               |    9 kB      |     R2_RxD
1379        rx queue 2 |    0 kB       | RX_SMALL_FIFO| ------------- * 63,75 kB
1380                   |  (not used)   |              | R1_RxD+R2_RxD
1381
1382        END_MANUAL_ENTRY
1383*/
1384
1385        if (SMT_R1_RXD_COUNT == 0) {
1386                SMT_PANIC(smc,SMT_E0117, SMT_E0117_MSG) ;
1387        }
1388
1389        switch(SMT_R2_RXD_COUNT) {
1390        case 0:
1391                smc->hw.fp.fifo.rx1_fifo_size = RX_FIFO_SPACE ;
1392                smc->hw.fp.fifo.rx2_fifo_size = 0 ;
1393                break ;
1394        case 1:
1395        case 2:
1396        case 3:
1397                smc->hw.fp.fifo.rx1_fifo_size = RX_LARGE_FIFO ;
1398                smc->hw.fp.fifo.rx2_fifo_size = RX_SMALL_FIFO ;
1399                break ;
1400        default:        /* this is not the real defaule */
1401                smc->hw.fp.fifo.rx1_fifo_size = RX_FIFO_SPACE *
1402                SMT_R1_RXD_COUNT/(SMT_R1_RXD_COUNT+SMT_R2_RXD_COUNT) ;
1403                smc->hw.fp.fifo.rx2_fifo_size = RX_FIFO_SPACE *
1404                SMT_R2_RXD_COUNT/(SMT_R1_RXD_COUNT+SMT_R2_RXD_COUNT) ;
1405                break ;
1406        }
1407
1408/*
1409        BEGIN_MANUAL_ENTRY(module;mem;1)
1410        -------------------------------------------------------------
1411        TRANSMIT BUFFER MEMORY DIVERSION
1412        -------------------------------------------------------------
1413
1414
1415                 | no sync bw   | sync bw available and | sync bw available and
1416                 | available    | SynchTxMode = SPLIT   | SynchTxMode = ALL
1417        -----------------------------------------------------------------------
1418        sync tx  |     0 kB     |       32 kB           |       55 kB
1419        queue    |              |   TX_MEDIUM_FIFO      |   TX_LARGE_FIFO
1420        -----------------------------------------------------------------------
1421        async tx |    64 kB     |       32 kB           |        9 k
1422        queue    | TX_FIFO_SPACE|   TX_MEDIUM_FIFO      |   TX_SMALL_FIFO
1423
1424        END_MANUAL_ENTRY
1425*/
1426
1427        /*
1428         * set the tx mode bits
1429         */
1430        if (smc->mib.a[PATH0].fddiPATHSbaPayload) {
1431#ifdef ESS
1432                smc->hw.fp.fifo.fifo_config_mode |=
1433                        smc->mib.fddiESSSynchTxMode | SYNC_TRAFFIC_ON ;
1434#endif
1435        }
1436        else {
1437                smc->hw.fp.fifo.fifo_config_mode &=
1438                        ~(SEND_ASYNC_AS_SYNC|SYNC_TRAFFIC_ON) ;
1439        }
1440
1441        /*
1442         * split up the FIFO
1443         */
1444        if (smc->hw.fp.fifo.fifo_config_mode & SYNC_TRAFFIC_ON) {
1445                if (smc->hw.fp.fifo.fifo_config_mode & SEND_ASYNC_AS_SYNC) {
1446                        smc->hw.fp.fifo.tx_s_size = TX_LARGE_FIFO ;
1447                        smc->hw.fp.fifo.tx_a0_size = TX_SMALL_FIFO ;
1448                }
1449                else {
1450                        smc->hw.fp.fifo.tx_s_size = TX_MEDIUM_FIFO ;
1451                        smc->hw.fp.fifo.tx_a0_size = TX_MEDIUM_FIFO ;
1452                }
1453        }
1454        else {
1455                        smc->hw.fp.fifo.tx_s_size = 0 ;
1456                        smc->hw.fp.fifo.tx_a0_size = TX_FIFO_SPACE ;
1457        }
1458
1459        smc->hw.fp.fifo.rx1_fifo_start = smc->hw.fp.fifo.rbc_ram_start +
1460                RX_FIFO_OFF ;
1461        smc->hw.fp.fifo.tx_s_start = smc->hw.fp.fifo.rx1_fifo_start +
1462                smc->hw.fp.fifo.rx1_fifo_size ;
1463        smc->hw.fp.fifo.tx_a0_start = smc->hw.fp.fifo.tx_s_start +
1464                smc->hw.fp.fifo.tx_s_size ;
1465        smc->hw.fp.fifo.rx2_fifo_start = smc->hw.fp.fifo.tx_a0_start +
1466                smc->hw.fp.fifo.tx_a0_size ;
1467
1468        DB_SMT("FIFO split: mode = %x", smc->hw.fp.fifo.fifo_config_mode);
1469        DB_SMT("rbc_ram_start = %x       rbc_ram_end =  %x",
1470               smc->hw.fp.fifo.rbc_ram_start, smc->hw.fp.fifo.rbc_ram_end);
1471        DB_SMT("rx1_fifo_start = %x      tx_s_start =   %x",
1472               smc->hw.fp.fifo.rx1_fifo_start, smc->hw.fp.fifo.tx_s_start);
1473        DB_SMT("tx_a0_start =   %x       rx2_fifo_start =       %x",
1474               smc->hw.fp.fifo.tx_a0_start, smc->hw.fp.fifo.rx2_fifo_start);
1475}
1476
1477void formac_reinit_tx(struct s_smc *smc)
1478{
1479        /*
1480         * Split up the FIFO and reinitialize the MAC if synchronous
1481         * bandwidth becomes available but no synchronous queue is
1482         * configured.
1483         */
1484        if (!smc->hw.fp.fifo.tx_s_size && smc->mib.a[PATH0].fddiPATHSbaPayload){
1485                (void)init_mac(smc,0) ;
1486        }
1487}
1488
1489