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