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