]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - drivers/net/skfp/fplustm.c
drivers/net: return operator cleanup
[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 <linux/bitrev.h>
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 const int mac_imsk1u = FM_STXABRS | FM_STXABRA0 | FM_SXMTABT ;
93 static const 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 const int mac_imsk2u = FM_SERRSF | FM_SNFSLD | FM_SRCVOVR | FM_SRBFL |
98                         FM_SMYCLM ;
99 static const int mac_imsk2l = FM_STRTEXR | FM_SDUPCLM | FM_SFRMCTR |
100                         FM_SERRCTR | FM_SLSTCTR |
101                         FM_STRTEXP | FM_SMULTDA | FM_SRNGOP ;
102
103 static const int mac_imsk3u = FM_SRCVOVR2 | FM_SRBFL2 ;
104 static const int mac_imsk3l = FM_SRPERRQ2 | FM_SRPERRQ1 ;
105
106 static const 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 ;             length of the frame including the FC */
402 {
403         int     i ;
404         __le32  *p ;
405
406         CHECK_NPP() ;
407         MARW(off) ;             /* set memory address reg for writes */
408
409         p = (__le32 *) 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,le32_to_cpu(*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(__le32,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,le32_to_cpu(a[0])) ;
462         outpw(FM_A(FM_CMDREG2),FM_ISTTB) ;      /* set the tag bit */
463         write_mdr(smc,le32_to_cpu(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),(unsigned short)~mac_imsk1u);
553         outpw(FM_A(FM_IMSK1L),(unsigned short)~mac_imsk1l);
554         outpw(FM_A(FM_IMSK2U),(unsigned short)~mac_imsk2u);
555         outpw(FM_A(FM_IMSK2L),(unsigned short)~mac_imsk2l);
556         outpw(FM_A(FM_IMSK3U),(unsigned short)~mac_imsk3u);
557         outpw(FM_A(FM_IMSK3L),(unsigned short)~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 = bitrev8(*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_add_multicast(smc,addr,can)
1121         struct s_smc *smc ;
1122         struct fddi_addr *addr ;
1123         int can ;
1124
1125 Function        DOWNCALL        (SMC, fplustm.c)
1126                 Add an entry to the multicast table
1127
1128 Para    addr    pointer to a multicast address
1129         can     = 0:    the multicast address has the physical format
1130                 = 1:    the multicast address has the canonical format
1131                 | 0x80  permanent
1132
1133 Returns 0: success
1134         1: address table full
1135
1136 Note    After a 'driver reset' or a 'station set address' all
1137         entries of the multicast table are cleared.
1138         In this case the driver has to fill the multicast table again.
1139         After the operating system dependent module filled
1140         the multicast table it must call mac_update_multicast
1141         to activate the new multicast addresses!
1142
1143         END_MANUAL_ENTRY()
1144  */
1145 int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can)
1146 {
1147         SK_LOC_DECL(struct fddi_addr,own) ;
1148         struct s_fpmc   *tb ;
1149
1150         /*
1151          * check if there are free table entries
1152          */
1153         if (can & 0x80) {
1154                 if (smc->hw.fp.smt_slots_used >= SMT_MAX_MULTI) {
1155                         return 1;
1156                 }
1157         }
1158         else {
1159                 if (smc->hw.fp.os_slots_used >= FPMAX_MULTICAST-SMT_MAX_MULTI) {
1160                         return 1;
1161                 }
1162         }
1163
1164         /*
1165          * find empty slot
1166          */
1167         if (!(tb = mac_get_mc_table(smc,addr,&own,0,can & ~0x80)))
1168                 return 1;
1169         tb->n++ ;
1170         tb->a = own ;
1171         tb->perm = (can & 0x80) ? 1 : 0 ;
1172
1173         if (can & 0x80)
1174                 smc->hw.fp.smt_slots_used++ ;
1175         else
1176                 smc->hw.fp.os_slots_used++ ;
1177
1178         return 0;
1179 }
1180
1181 /*
1182  * mode
1183  */
1184
1185 #define RX_MODE_PROM            0x1
1186 #define RX_MODE_ALL_MULTI       0x2
1187
1188 /*
1189         BEGIN_MANUAL_ENTRY(if,func;others;2)
1190
1191         void mac_update_multicast(smc)
1192         struct s_smc *smc ;
1193
1194 Function        DOWNCALL        (SMT, fplustm.c)
1195                 Update FORMAC multicast registers
1196
1197         END_MANUAL_ENTRY()
1198  */
1199 void mac_update_multicast(struct s_smc *smc)
1200 {
1201         struct s_fpmc   *tb ;
1202         u_char  *fu ;
1203         int     i ;
1204
1205         /*
1206          * invalidate the CAM
1207          */
1208         outpw(FM_A(FM_AFCMD),FM_IINV_CAM) ;
1209
1210         /*
1211          * set the functional address
1212          */
1213         if (smc->hw.fp.func_addr) {
1214                 fu = (u_char *) &smc->hw.fp.func_addr ;
1215                 outpw(FM_A(FM_AFMASK2),0xffff) ;
1216                 outpw(FM_A(FM_AFMASK1),(u_short) ~((fu[0] << 8) + fu[1])) ;
1217                 outpw(FM_A(FM_AFMASK0),(u_short) ~((fu[2] << 8) + fu[3])) ;
1218                 outpw(FM_A(FM_AFPERS),FM_VALID|FM_DA) ;
1219                 outpw(FM_A(FM_AFCOMP2), 0xc000) ;
1220                 outpw(FM_A(FM_AFCOMP1), 0x0000) ;
1221                 outpw(FM_A(FM_AFCOMP0), 0x0000) ;
1222                 outpw(FM_A(FM_AFCMD),FM_IWRITE_CAM) ;
1223         }
1224
1225         /*
1226          * set the mask and the personality register(s)
1227          */
1228         outpw(FM_A(FM_AFMASK0),0xffff) ;
1229         outpw(FM_A(FM_AFMASK1),0xffff) ;
1230         outpw(FM_A(FM_AFMASK2),0xffff) ;
1231         outpw(FM_A(FM_AFPERS),FM_VALID|FM_DA) ;
1232
1233         for (i = 0, tb = smc->hw.fp.mc.table; i < FPMAX_MULTICAST; i++, tb++) {
1234                 if (tb->n) {
1235                         CHECK_CAM() ;
1236
1237                         /*
1238                          * write the multicast address into the CAM
1239                          */
1240                         outpw(FM_A(FM_AFCOMP2),
1241                                 (u_short)((tb->a.a[0]<<8)+tb->a.a[1])) ;
1242                         outpw(FM_A(FM_AFCOMP1),
1243                                 (u_short)((tb->a.a[2]<<8)+tb->a.a[3])) ;
1244                         outpw(FM_A(FM_AFCOMP0),
1245                                 (u_short)((tb->a.a[4]<<8)+tb->a.a[5])) ;
1246                         outpw(FM_A(FM_AFCMD),FM_IWRITE_CAM) ;
1247                 }
1248         }
1249 }
1250
1251 /*
1252         BEGIN_MANUAL_ENTRY(if,func;others;3)
1253
1254         void mac_set_rx_mode(smc,mode)
1255         struct s_smc *smc ;
1256         int mode ;
1257
1258 Function        DOWNCALL/INTERN (SMT, fplustm.c)
1259                 This function enables / disables the selected receive.
1260                 Don't call this function if the hardware module is
1261                 used -- use mac_drv_rx_mode() instead of.
1262
1263 Para    mode =  1       RX_ENABLE_ALLMULTI      enable all multicasts
1264                 2       RX_DISABLE_ALLMULTI     disable "enable all multicasts"
1265                 3       RX_ENABLE_PROMISC       enable promiscous
1266                 4       RX_DISABLE_PROMISC      disable promiscous
1267                 5       RX_ENABLE_NSA           enable reception of NSA frames
1268                 6       RX_DISABLE_NSA          disable reception of NSA frames
1269
1270 Note    The selected receive modes will be lost after 'driver reset'
1271         or 'set station address'
1272
1273         END_MANUAL_ENTRY
1274  */
1275 void mac_set_rx_mode(struct s_smc *smc, int mode)
1276 {
1277         switch (mode) {
1278         case RX_ENABLE_ALLMULTI :
1279                 smc->hw.fp.rx_prom |= RX_MODE_ALL_MULTI ;
1280                 break ;
1281         case RX_DISABLE_ALLMULTI :
1282                 smc->hw.fp.rx_prom &= ~RX_MODE_ALL_MULTI ;
1283                 break ;
1284         case RX_ENABLE_PROMISC :
1285                 smc->hw.fp.rx_prom |= RX_MODE_PROM ;
1286                 break ;
1287         case RX_DISABLE_PROMISC :
1288                 smc->hw.fp.rx_prom &= ~RX_MODE_PROM ;
1289                 break ;
1290         case RX_ENABLE_NSA :
1291                 smc->hw.fp.nsa_mode = FM_MDAMA ;
1292                 smc->hw.fp.rx_mode = (smc->hw.fp.rx_mode & ~FM_ADDET) |
1293                         smc->hw.fp.nsa_mode ;
1294                 break ;
1295         case RX_DISABLE_NSA :
1296                 smc->hw.fp.nsa_mode = FM_MRNNSAFNMA ;
1297                 smc->hw.fp.rx_mode = (smc->hw.fp.rx_mode & ~FM_ADDET) |
1298                         smc->hw.fp.nsa_mode ;
1299                 break ;
1300         }
1301         if (smc->hw.fp.rx_prom & RX_MODE_PROM) {
1302                 smc->hw.fp.rx_mode = FM_MLIMPROM ;
1303         }
1304         else if (smc->hw.fp.rx_prom & RX_MODE_ALL_MULTI) {
1305                 smc->hw.fp.rx_mode = smc->hw.fp.nsa_mode | FM_EXGPA0 ;
1306         }
1307         else
1308                 smc->hw.fp.rx_mode = smc->hw.fp.nsa_mode ;
1309         SETMASK(FM_A(FM_MDREG1),smc->hw.fp.rx_mode,FM_ADDRX) ;
1310         mac_update_multicast(smc) ;
1311 }
1312
1313 /*
1314         BEGIN_MANUAL_ENTRY(module;tests;3)
1315         How to test the Restricted Token Monitor
1316         ----------------------------------------------------------------
1317
1318         o Insert a break point in the function rtm_irq()
1319         o Remove all stations with a restricted token monitor from the
1320           network.
1321         o Connect a UPPS ISA or EISA station to the network.
1322         o Give the FORMAC of UPPS station the command to send
1323           restricted tokens until the ring becomes instable.
1324         o Now connect your test test client.
1325         o The restricted token monitor should detect the restricted token,
1326           and your break point will be reached.
1327         o You can ovserve how the station will clean the ring.
1328
1329         END_MANUAL_ENTRY
1330  */
1331 void rtm_irq(struct s_smc *smc)
1332 {
1333         outpw(ADDR(B2_RTM_CRTL),TIM_CL_IRQ) ;           /* clear IRQ */
1334         if (inpw(ADDR(B2_RTM_CRTL)) & TIM_RES_TOK) {
1335                 outpw(FM_A(FM_CMDREG1),FM_ICL) ;        /* force claim */
1336                 DB_RMT("RMT: fddiPATHT_Rmode expired\n",0,0) ;
1337                 AIX_EVENT(smc, (u_long) FDDI_RING_STATUS,
1338                                 (u_long) FDDI_SMT_EVENT,
1339                                 (u_long) FDDI_RTT, smt_get_event_word(smc));
1340         }
1341         outpw(ADDR(B2_RTM_CRTL),TIM_START) ;    /* enable RTM monitoring */
1342 }
1343
1344 static void rtm_init(struct s_smc *smc)
1345 {
1346         outpd(ADDR(B2_RTM_INI),0) ;             /* timer = 0 */
1347         outpw(ADDR(B2_RTM_CRTL),TIM_START) ;    /* enable IRQ */
1348 }
1349
1350 void rtm_set_timer(struct s_smc *smc)
1351 {
1352         /*
1353          * MIB timer and hardware timer have the same resolution of 80nS
1354          */
1355         DB_RMT("RMT: setting new fddiPATHT_Rmode, t = %d ns\n",
1356                 (int) smc->mib.a[PATH0].fddiPATHT_Rmode,0) ;
1357         outpd(ADDR(B2_RTM_INI),smc->mib.a[PATH0].fddiPATHT_Rmode) ;
1358 }
1359
1360 static void smt_split_up_fifo(struct s_smc *smc)
1361 {
1362
1363 /*
1364         BEGIN_MANUAL_ENTRY(module;mem;1)
1365         -------------------------------------------------------------
1366         RECEIVE BUFFER MEMORY DIVERSION
1367         -------------------------------------------------------------
1368
1369         R1_RxD == SMT_R1_RXD_COUNT
1370         R2_RxD == SMT_R2_RXD_COUNT
1371
1372         SMT_R1_RXD_COUNT must be unequal zero
1373
1374                    | R1_RxD R2_RxD |R1_RxD R2_RxD | R1_RxD R2_RxD
1375                    |   x      0    |  x     1-3   |   x     < 3
1376         ----------------------------------------------------------------------
1377                    |   63,75 kB    |    54,75     |     R1_RxD
1378         rx queue 1 | RX_FIFO_SPACE | RX_LARGE_FIFO| ------------- * 63,75 kB
1379                    |               |              | R1_RxD+R2_RxD
1380         ----------------------------------------------------------------------
1381                    |               |    9 kB      |     R2_RxD
1382         rx queue 2 |    0 kB       | RX_SMALL_FIFO| ------------- * 63,75 kB
1383                    |  (not used)   |              | R1_RxD+R2_RxD
1384
1385         END_MANUAL_ENTRY
1386 */
1387
1388         if (SMT_R1_RXD_COUNT == 0) {
1389                 SMT_PANIC(smc,SMT_E0117, SMT_E0117_MSG) ;
1390         }
1391
1392         switch(SMT_R2_RXD_COUNT) {
1393         case 0:
1394                 smc->hw.fp.fifo.rx1_fifo_size = RX_FIFO_SPACE ;
1395                 smc->hw.fp.fifo.rx2_fifo_size = 0 ;
1396                 break ;
1397         case 1:
1398         case 2:
1399         case 3:
1400                 smc->hw.fp.fifo.rx1_fifo_size = RX_LARGE_FIFO ;
1401                 smc->hw.fp.fifo.rx2_fifo_size = RX_SMALL_FIFO ;
1402                 break ;
1403         default:        /* this is not the real defaule */
1404                 smc->hw.fp.fifo.rx1_fifo_size = RX_FIFO_SPACE *
1405                 SMT_R1_RXD_COUNT/(SMT_R1_RXD_COUNT+SMT_R2_RXD_COUNT) ;
1406                 smc->hw.fp.fifo.rx2_fifo_size = RX_FIFO_SPACE *
1407                 SMT_R2_RXD_COUNT/(SMT_R1_RXD_COUNT+SMT_R2_RXD_COUNT) ;
1408                 break ;
1409         }
1410
1411 /*
1412         BEGIN_MANUAL_ENTRY(module;mem;1)
1413         -------------------------------------------------------------
1414         TRANSMIT BUFFER MEMORY DIVERSION
1415         -------------------------------------------------------------
1416
1417
1418                  | no sync bw   | sync bw available and | sync bw available and
1419                  | available    | SynchTxMode = SPLIT   | SynchTxMode = ALL
1420         -----------------------------------------------------------------------
1421         sync tx  |     0 kB     |       32 kB           |       55 kB
1422         queue    |              |   TX_MEDIUM_FIFO      |   TX_LARGE_FIFO
1423         -----------------------------------------------------------------------
1424         async tx |    64 kB     |       32 kB           |        9 k
1425         queue    | TX_FIFO_SPACE|   TX_MEDIUM_FIFO      |   TX_SMALL_FIFO
1426
1427         END_MANUAL_ENTRY
1428 */
1429
1430         /*
1431          * set the tx mode bits
1432          */
1433         if (smc->mib.a[PATH0].fddiPATHSbaPayload) {
1434 #ifdef ESS
1435                 smc->hw.fp.fifo.fifo_config_mode |=
1436                         smc->mib.fddiESSSynchTxMode | SYNC_TRAFFIC_ON ;
1437 #endif
1438         }
1439         else {
1440                 smc->hw.fp.fifo.fifo_config_mode &=
1441                         ~(SEND_ASYNC_AS_SYNC|SYNC_TRAFFIC_ON) ;
1442         }
1443
1444         /*
1445          * split up the FIFO
1446          */
1447         if (smc->hw.fp.fifo.fifo_config_mode & SYNC_TRAFFIC_ON) {
1448                 if (smc->hw.fp.fifo.fifo_config_mode & SEND_ASYNC_AS_SYNC) {
1449                         smc->hw.fp.fifo.tx_s_size = TX_LARGE_FIFO ;
1450                         smc->hw.fp.fifo.tx_a0_size = TX_SMALL_FIFO ;
1451                 }
1452                 else {
1453                         smc->hw.fp.fifo.tx_s_size = TX_MEDIUM_FIFO ;
1454                         smc->hw.fp.fifo.tx_a0_size = TX_MEDIUM_FIFO ;
1455                 }
1456         }
1457         else {
1458                         smc->hw.fp.fifo.tx_s_size = 0 ;
1459                         smc->hw.fp.fifo.tx_a0_size = TX_FIFO_SPACE ;
1460         }
1461
1462         smc->hw.fp.fifo.rx1_fifo_start = smc->hw.fp.fifo.rbc_ram_start +
1463                 RX_FIFO_OFF ;
1464         smc->hw.fp.fifo.tx_s_start = smc->hw.fp.fifo.rx1_fifo_start +
1465                 smc->hw.fp.fifo.rx1_fifo_size ;
1466         smc->hw.fp.fifo.tx_a0_start = smc->hw.fp.fifo.tx_s_start +
1467                 smc->hw.fp.fifo.tx_s_size ;
1468         smc->hw.fp.fifo.rx2_fifo_start = smc->hw.fp.fifo.tx_a0_start +
1469                 smc->hw.fp.fifo.tx_a0_size ;
1470
1471         DB_SMT("FIFO split: mode = %x\n",smc->hw.fp.fifo.fifo_config_mode,0) ;
1472         DB_SMT("rbc_ram_start = %x       rbc_ram_end =  %x\n",
1473                 smc->hw.fp.fifo.rbc_ram_start, smc->hw.fp.fifo.rbc_ram_end) ;
1474         DB_SMT("rx1_fifo_start = %x      tx_s_start =   %x\n",
1475                 smc->hw.fp.fifo.rx1_fifo_start, smc->hw.fp.fifo.tx_s_start) ;
1476         DB_SMT("tx_a0_start =   %x       rx2_fifo_start =       %x\n",
1477                 smc->hw.fp.fifo.tx_a0_start, smc->hw.fp.fifo.rx2_fifo_start) ;
1478 }
1479
1480 void formac_reinit_tx(struct s_smc *smc)
1481 {
1482         /*
1483          * Split up the FIFO and reinitialize the MAC if synchronous
1484          * bandwidth becomes available but no synchronous queue is
1485          * configured.
1486          */
1487         if (!smc->hw.fp.fifo.tx_s_size && smc->mib.a[PATH0].fddiPATHSbaPayload){
1488                 (void)init_mac(smc,0) ;
1489         }
1490 }
1491