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