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