[go: nahoru, domu]

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
29static 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 */
47static void build_claim_beacon(struct s_smc *smc, u_long t_request);
48static int init_mac(struct s_smc *smc, int all);
49static void rtm_init(struct s_smc *smc);
50static void smt_split_up_fifo(struct s_smc *smc);
51
52#if (!defined(NO_SMT_PANIC) || defined(DEBUG))
53static	char write_mdr_warning [] = "E350 write_mdr() FM_SNPPND is set\n";
54static	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
73const struct fddi_addr fddi_broadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
74static const struct fddi_addr null_addr = {{0,0,0,0,0,0}};
75static const struct fddi_addr dbeacon_multi = {{0x01,0x80,0xc2,0x00,0x01,0x00}};
76
77static const u_short my_said = 0xffff ;	/* short address (n.u.) */
78static 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 */
93static const int mac_imsk1u = FM_STXABRS | FM_STXABRA0 | FM_SXMTABT ;
94static const int mac_imsk1l = FM_SQLCKS | FM_SQLCKA0 | FM_SPCEPDS | FM_SPCEPDA0|
95			FM_STBURS | FM_STBURA0 ;
96
97	/* delete FM_SRBFL after tests */
98static const int mac_imsk2u = FM_SERRSF | FM_SNFSLD | FM_SRCVOVR | FM_SRBFL |
99			FM_SMYCLM ;
100static const int mac_imsk2l = FM_STRTEXR | FM_SDUPCLM | FM_SFRMCTR |
101			FM_SERRCTR | FM_SLSTCTR |
102			FM_STRTEXP | FM_SMULTDA | FM_SRNGOP ;
103
104static const int mac_imsk3u = FM_SRCVOVR2 | FM_SRBFL2 ;
105static const int mac_imsk3l = FM_SRPERRQ2 | FM_SRPERRQ1 ;
106
107static const int mac_beacon_imsk2u = FM_SOTRBEC | FM_SMYBEC | FM_SBEC |
108			FM_SLOCLM | FM_SHICLM | FM_SMYCLM | FM_SCLM ;
109
110
111static 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
120void 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 */
145static 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 */
155static 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 */
174static 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 */
193static 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 */
223static 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 */
255static 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 */
276static 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 */
298void 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 */
306static 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
332static 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 */
355static	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
381static 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 */
397static 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 */
446static 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*/
475static 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
536static 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
544void 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
550static 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
571Function	DOWNCALL	(SMT, fplustm.c)
572		enable_tx_irq() enables the FORMACs transmit complete
573		interrupt of the queue.
574
575Para	queue	= QUEUE_S:	synchronous queue
576		= QUEUE_A0:	asynchronous queue
577
578Note	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 */
590void 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
612Function	DOWNCALL	(SMT, fplustm.c)
613		disable_tx_irq disables the FORMACs transmit complete
614		interrupt of the queue
615
616Para	queue	= QUEUE_S:	synchronous queue
617		= QUEUE_A0:	asynchronous queue
618
619Note	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 */
625void 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
641static 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
653static 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 */
680void 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	}
796mac2_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 */
806void 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 */
829static 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 */
847static 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 */
857int 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
895static 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 */
1000void 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 */
1014void 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 */
1027void 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
1051int 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
1060static 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
1099Function	DOWNCALL	(SMT, fplustm.c)
1100		Clear all multicast entries
1101
1102	END_MANUAL_ENTRY()
1103 */
1104void 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
1126Function	DOWNCALL	(SMC, fplustm.c)
1127		Add an entry to the multicast table
1128
1129Para	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
1134Returns	0: success
1135	1: address table full
1136
1137Note	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 */
1146int 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
1195Function	DOWNCALL	(SMT, fplustm.c)
1196		Update FORMAC multicast registers
1197
1198	END_MANUAL_ENTRY()
1199 */
1200void 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
1259Function	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
1264Para	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
1271Note	The selected receive modes will be lost after 'driver reset'
1272	or 'set station address'
1273
1274	END_MANUAL_ENTRY
1275 */
1276void 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 */
1332void 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
1345static 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
1351void 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
1361static 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
1481void 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