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