/******************************************************************************
 *
 *	(C)Copyright 1998,1999 SysKonnect,
 *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
 *
 *	See the file "skfddi.c" for further information.
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 *
 *	The information in this file is provided "AS IS" without warranty.
 *
 ******************************************************************************/

/*
 * FORMAC+ Driver for tag mode
 */

#include "h/types.h"
#include "h/fddi.h"
#include "h/smc.h"
#include "h/supern_2.h"
#include "can.c"

#ifndef	lint
static const char ID_sccs[] = "@(#)fplustm.c	1.32 99/02/23 (C) SK " ;
#endif

#ifndef UNUSED
#ifdef  lint
#define UNUSED(x)	(x) = (x)
#else
#define UNUSED(x)
#endif
#endif

#define FM_ADDRX	 (FM_ADDET|FM_EXGPA0|FM_EXGPA1)
#define MS2BCLK(x)	((x)*12500L)
#define US2BCLK(x)	((x)*1250L)

/*
 * prototypes for static function
 */
static void build_claim_beacon(struct s_smc *smc, u_long t_request);
static int init_mac(struct s_smc *smc, int all);
static void rtm_init(struct s_smc *smc);
static void smt_split_up_fifo(struct s_smc *smc);

#if (!defined(NO_SMT_PANIC) || defined(DEBUG))
static	char write_mdr_warning [] = "E350 write_mdr() FM_SNPPND is set\n";
static	char cam_warning [] = "E_SMT_004: CAM still busy\n";
#endif

#define	DUMMY_READ()	smc->hw.mc_dummy = (u_short) inp(ADDR(B0_RAP))

#define	CHECK_NPP() {	unsigned k = 10000 ;\
			while ((inpw(FM_A(FM_STMCHN)) & FM_SNPPND) && k) k--;\
			if (!k) { \
				SMT_PANIC(smc,SMT_E0130, SMT_E0130_MSG) ; \
			}	\
		}

#define	CHECK_CAM() {	unsigned k = 10 ;\
			while (!(inpw(FM_A(FM_AFSTAT)) & FM_DONE) && k) k--;\
			if (!k) { \
				SMT_PANIC(smc,SMT_E0131, SMT_E0131_MSG) ; \
			}	\
		}

const struct fddi_addr fddi_broadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
static const struct fddi_addr null_addr = {{0,0,0,0,0,0}};
static const struct fddi_addr dbeacon_multi = {{0x01,0x80,0xc2,0x00,0x01,0x00}};

static const u_short my_said = 0xffff ;	/* short address (n.u.) */
static const u_short my_sagp = 0xffff ;	/* short group address (n.u.) */

/*
 * define my address
 */
#ifdef	USE_CAN_ADDR
#define MA	smc->hw.fddi_canon_addr
#else
#define MA	smc->hw.fddi_home_addr
#endif


/*
 * useful interrupt bits
 */
static int mac_imsk1u = FM_STXABRS | FM_STXABRA0 | FM_SXMTABT ;
static int mac_imsk1l = FM_SQLCKS | FM_SQLCKA0 | FM_SPCEPDS | FM_SPCEPDA0|
			FM_STBURS | FM_STBURA0 ;

	/* delete FM_SRBFL after tests */
static int mac_imsk2u = FM_SERRSF | FM_SNFSLD | FM_SRCVOVR | FM_SRBFL |
			FM_SMYCLM ;
static int mac_imsk2l = FM_STRTEXR | FM_SDUPCLM | FM_SFRMCTR |
			FM_SERRCTR | FM_SLSTCTR |
			FM_STRTEXP | FM_SMULTDA | FM_SRNGOP ;

static int mac_imsk3u = FM_SRCVOVR2 | FM_SRBFL2 ;
static int mac_imsk3l = FM_SRPERRQ2 | FM_SRPERRQ1 ;

static int mac_beacon_imsk2u = FM_SOTRBEC | FM_SMYBEC | FM_SBEC |
			FM_SLOCLM | FM_SHICLM | FM_SMYCLM | FM_SCLM ;


static u_long mac_get_tneg(struct s_smc *smc)
{
	u_long	tneg ;

	tneg = (u_long)((long)inpw(FM_A(FM_TNEG))<<5) ;
	return((u_long)((tneg + ((inpw(FM_A(FM_TMRS))>>10)&0x1f)) |
		0xffe00000L)) ;
}

void mac_update_counter(struct s_smc *smc)
{
	smc->mib.m[MAC0].fddiMACFrame_Ct =
		(smc->mib.m[MAC0].fddiMACFrame_Ct & 0xffff0000L)
		+ (u_short) inpw(FM_A(FM_FCNTR)) ;
	smc->mib.m[MAC0].fddiMACLost_Ct =
		(smc->mib.m[MAC0].fddiMACLost_Ct & 0xffff0000L)
		+ (u_short) inpw(FM_A(FM_LCNTR)) ;
	smc->mib.m[MAC0].fddiMACError_Ct =
		(smc->mib.m[MAC0].fddiMACError_Ct & 0xffff0000L)
		+ (u_short) inpw(FM_A(FM_ECNTR)) ;
	smc->mib.m[MAC0].fddiMACT_Neg = mac_get_tneg(smc) ;
#ifdef SMT_REAL_TOKEN_CT
	/*
	 * If the token counter is emulated it is updated in smt_event.
	 */
	TBD
#else
	smt_emulate_token_ct( smc, MAC0 );
#endif
}

/*
 * write long value into buffer memory over memory data register (MDR),
 */
static void write_mdr(struct s_smc *smc, u_long val)
{
	CHECK_NPP() ;
	MDRW(val) ;
}

#if 0
/*
 * read long value from buffer memory over memory data register (MDR),
 */
static u_long read_mdr(struct s_smc *smc, unsigned int addr)
{
	long p ;
	CHECK_NPP() ;
	MARR(addr) ;
	outpw(FM_A(FM_CMDREG1),FM_IRMEMWO) ;
	CHECK_NPP() ;	/* needed for PCI to prevent from timeing violations */
/*	p = MDRR() ; */	/* bad read values if the workaround */
			/* smc->hw.mc_dummy = *((short volatile far *)(addr)))*/
			/* is used */
	p = (u_long)inpw(FM_A(FM_MDRU))<<16 ;
	p += (u_long)inpw(FM_A(FM_MDRL)) ;
	return(p) ;
}
#endif

/*
 * clear buffer memory
 */
static void init_ram(struct s_smc *smc)
{
	u_short i ;

	smc->hw.fp.fifo.rbc_ram_start = 0 ;
	smc->hw.fp.fifo.rbc_ram_end =
		smc->hw.fp.fifo.rbc_ram_start + RBC_MEM_SIZE ;
	CHECK_NPP() ;
	MARW(smc->hw.fp.fifo.rbc_ram_start) ;
	for (i = smc->hw.fp.fifo.rbc_ram_start;
		i < (u_short) (smc->hw.fp.fifo.rbc_ram_end-1); i++)
		write_mdr(smc,0L) ;
	/* Erase the last byte too */
	write_mdr(smc,0L) ;
}

/*
 * set receive FIFO pointer
 */
static void set_recvptr(struct s_smc *smc)
{
	/*
	 * initialize the pointer for receive queue 1
	 */
	outpw(FM_A(FM_RPR1),smc->hw.fp.fifo.rx1_fifo_start) ;	/* RPR1 */
	outpw(FM_A(FM_SWPR1),smc->hw.fp.fifo.rx1_fifo_start) ;	/* SWPR1 */
	outpw(FM_A(FM_WPR1),smc->hw.fp.fifo.rx1_fifo_start) ;	/* WPR1 */
	outpw(FM_A(FM_EARV1),smc->hw.fp.fifo.tx_s_start-1) ;	/* EARV1 */

	/*
	 * initialize the pointer for receive queue 2
	 */
	if (smc->hw.fp.fifo.rx2_fifo_size) {
		outpw(FM_A(FM_RPR2),smc->hw.fp.fifo.rx2_fifo_start) ;
		outpw(FM_A(FM_SWPR2),smc->hw.fp.fifo.rx2_fifo_start) ;
		outpw(FM_A(FM_WPR2),smc->hw.fp.fifo.rx2_fifo_start) ;
		outpw(FM_A(FM_EARV2),smc->hw.fp.fifo.rbc_ram_end-1) ;
	}
	else {
		outpw(FM_A(FM_RPR2),smc->hw.fp.fifo.rbc_ram_end-1) ;
		outpw(FM_A(FM_SWPR2),smc->hw.fp.fifo.rbc_ram_end-1) ;
		outpw(FM_A(FM_WPR2),smc->hw.fp.fifo.rbc_ram_end-1) ;
		outpw(FM_A(FM_EARV2),smc->hw.fp.fifo.rbc_ram_end-1) ;
	}
}

/*
 * set transmit FIFO pointer
 */
static void set_txptr(struct s_smc *smc)
{
	outpw(FM_A(FM_CMDREG2),FM_IRSTQ) ;	/* reset transmit queues */

	/*
	 * initialize the pointer for asynchronous transmit queue
	 */
	outpw(FM_A(FM_RPXA0),smc->hw.fp.fifo.tx_a0_start) ;	/* RPXA0 */
	outpw(FM_A(FM_SWPXA0),smc->hw.fp.fifo.tx_a0_start) ;	/* SWPXA0 */
	outpw(FM_A(FM_WPXA0),smc->hw.fp.fifo.tx_a0_start) ;	/* WPXA0 */
	outpw(FM_A(FM_EAA0),smc->hw.fp.fifo.rx2_fifo_start-1) ;	/* EAA0 */

	/*
	 * initialize the pointer for synchronous transmit queue
	 */
	if (smc->hw.fp.fifo.tx_s_size) {
		outpw(FM_A(FM_RPXS),smc->hw.fp.fifo.tx_s_start) ;
		outpw(FM_A(FM_SWPXS),smc->hw.fp.fifo.tx_s_start) ;
		outpw(FM_A(FM_WPXS),smc->hw.fp.fifo.tx_s_start) ;
		outpw(FM_A(FM_EAS),smc->hw.fp.fifo.tx_a0_start-1) ;
	}
	else {
		outpw(FM_A(FM_RPXS),smc->hw.fp.fifo.tx_a0_start-1) ;
		outpw(FM_A(FM_SWPXS),smc->hw.fp.fifo.tx_a0_start-1) ;
		outpw(FM_A(FM_WPXS),smc->hw.fp.fifo.tx_a0_start-1) ;
		outpw(FM_A(FM_EAS),smc->hw.fp.fifo.tx_a0_start-1) ;
	}
}

/*
 * init memory buffer management registers
 */
static void init_rbc(struct s_smc *smc)
{
	u_short	rbc_ram_addr ;

	/*
	 * set unused pointers or permanent pointers
	 */
	rbc_ram_addr = smc->hw.fp.fifo.rx2_fifo_start - 1 ;

	outpw(FM_A(FM_RPXA1),rbc_ram_addr) ;	/* a1-send pointer */
	outpw(FM_A(FM_WPXA1),rbc_ram_addr) ;
	outpw(FM_A(FM_SWPXA1),rbc_ram_addr) ;
	outpw(FM_A(FM_EAA1),rbc_ram_addr) ;

	set_recvptr(smc) ;
	set_txptr(smc) ;
}

/*
 * init rx pointer
 */
static void init_rx(struct s_smc *smc)
{
	struct s_smt_rx_queue	*queue ;

	/*
	 * init all tx data structures for receive queue 1
	 */
	smc->hw.fp.rx[QUEUE_R1] = queue = &smc->hw.fp.rx_q[QUEUE_R1] ;
	queue->rx_bmu_ctl = (HW_PTR) ADDR(B0_R1_CSR) ;
	queue->rx_bmu_dsc = (HW_PTR) ADDR(B4_R1_DA) ;

	/*
	 * init all tx data structures for receive queue 2
	 */
	smc->hw.fp.rx[QUEUE_R2] = queue = &smc->hw.fp.rx_q[QUEUE_R2] ;
	queue->rx_bmu_ctl = (HW_PTR) ADDR(B0_R2_CSR) ;
	queue->rx_bmu_dsc = (HW_PTR) ADDR(B4_R2_DA) ;
}

/*
 * set the TSYNC register of the FORMAC to regulate synchronous transmission
 */
void set_formac_tsync(struct s_smc *smc, long sync_bw)
{
	outpw(FM_A(FM_TSYNC),(unsigned int) (((-sync_bw) >> 5) & 0xffff) ) ;
}

/*
 * init all tx data structures
 */
static void init_tx(struct s_smc *smc)
{
	struct s_smt_tx_queue	*queue ;

	/*
	 * init all tx data structures for the synchronous queue
	 */
	smc->hw.fp.tx[QUEUE_S] = queue = &smc->hw.fp.tx_q[QUEUE_S] ;
	queue->tx_bmu_ctl = (HW_PTR) ADDR(B0_XS_CSR) ;
	queue->tx_bmu_dsc = (HW_PTR) ADDR(B5_XS_DA) ;

#ifdef ESS
	set_formac_tsync(smc,smc->ess.sync_bw) ;
#endif

	/*
	 * init all tx data structures for the asynchronous queue 0
	 */
	smc->hw.fp.tx[QUEUE_A0] = queue = &smc->hw.fp.tx_q[QUEUE_A0] ;
	queue->tx_bmu_ctl = (HW_PTR) ADDR(B0_XA_CSR) ;
	queue->tx_bmu_dsc = (HW_PTR) ADDR(B5_XA_DA) ;


	llc_recover_tx(smc) ;
}

static void mac_counter_init(struct s_smc *smc)
{
	int i ;
	u_long *ec ;

	/*
	 * clear FORMAC+ frame-, lost- and error counter
	 */
	outpw(FM_A(FM_FCNTR),0) ;
	outpw(FM_A(FM_LCNTR),0) ;
	outpw(FM_A(FM_ECNTR),0) ;
	/*
	 * clear internal error counter stucture
	 */
	ec = (u_long *)&smc->hw.fp.err_stats ;
	for (i = (sizeof(struct err_st)/sizeof(long)) ; i ; i--)
		*ec++ = 0L ;
	smc->mib.m[MAC0].fddiMACRingOp_Ct = 0 ;
}

/*
 * set FORMAC address, and t_request
 */
static	void set_formac_addr(struct s_smc *smc)
{
	long	t_requ = smc->mib.m[MAC0].fddiMACT_Req ;

	outpw(FM_A(FM_SAID),my_said) ;	/* set short address */
	outpw(FM_A(FM_LAIL),(unsigned)((smc->hw.fddi_home_addr.a[4]<<8) +
					smc->hw.fddi_home_addr.a[5])) ;
	outpw(FM_A(FM_LAIC),(unsigned)((smc->hw.fddi_home_addr.a[2]<<8) +
					smc->hw.fddi_home_addr.a[3])) ;
	outpw(FM_A(FM_LAIM),(unsigned)((smc->hw.fddi_home_addr.a[0]<<8) +
					smc->hw.fddi_home_addr.a[1])) ;

	outpw(FM_A(FM_SAGP),my_sagp) ;	/* set short group address */

	outpw(FM_A(FM_LAGL),(unsigned)((smc->hw.fp.group_addr.a[4]<<8) +
					smc->hw.fp.group_addr.a[5])) ;
	outpw(FM_A(FM_LAGC),(unsigned)((smc->hw.fp.group_addr.a[2]<<8) +
					smc->hw.fp.group_addr.a[3])) ;
	outpw(FM_A(FM_LAGM),(unsigned)((smc->hw.fp.group_addr.a[0]<<8) +
					smc->hw.fp.group_addr.a[1])) ;

	/* set r_request regs. (MSW & LSW of TRT ) */
	outpw(FM_A(FM_TREQ1),(unsigned)(t_requ>>16)) ;
	outpw(FM_A(FM_TREQ0),(unsigned)t_requ) ;
}

static void set_int(char *p, int l)
{
	p[0] = (char)(l >> 24) ;
	p[1] = (char)(l >> 16) ;
	p[2] = (char)(l >> 8) ;
	p[3] = (char)(l >> 0) ;
}

/*
 * copy TX descriptor to buffer mem
 * append FC field and MAC frame
 * if more bit is set in descr
 *	append pointer to descriptor (endless loop)
 * else
 *	append 'end of chain' pointer
 */
static void copy_tx_mac(struct s_smc *smc, u_long td, struct fddi_mac *mac,
			unsigned off, int len)
/* u_long td;		 transmit descriptor */
/* struct fddi_mac *mac; mac frame pointer */
/* unsigned off;	 start address within buffer memory */
/* int len ;		 lenght of the frame including the FC */
{
	int	i ;
	u_int	*p ;

	CHECK_NPP() ;
	MARW(off) ;		/* set memory address reg for writes */

	p = (u_int *) mac ;
	for (i = (len + 3)/4 ; i ; i--) {
		if (i == 1) {
			/* last word, set the tag bit */
			outpw(FM_A(FM_CMDREG2),FM_ISTTB) ;
		}
		write_mdr(smc,MDR_REVERSE(*p)) ;
		p++ ;
	}

	outpw(FM_A(FM_CMDREG2),FM_ISTTB) ;	/* set the tag bit */
	write_mdr(smc,td) ;	/* write over memory data reg to buffer */
}

/*
	BEGIN_MANUAL_ENTRY(module;tests;3)
	How to test directed beacon frames
	----------------------------------------------------------------

	o Insert a break point in the function build_claim_beacon()
	  before calling copy_tx_mac() for building the claim frame.
	o Modify the RM3_DETECT case so that the RM6_DETECT state
	  will always entered from the RM3_DETECT state (function rmt_fsm(),
	  rmt.c)
	o Compile the driver.
	o Set the parameter TREQ in the protocol.ini or net.cfg to a
	  small value to make sure your station will win the claim
	  process.
	o Start the driver.
	o When you reach the break point, modify the SA and DA address
	  of the claim frame (e.g. SA = DA = 10005affffff).
	o When you see RM3_DETECT and RM6_DETECT, observe the direct
	  beacon frames on the UPPSLANA.

	END_MANUAL_ENTRY
 */
static void directed_beacon(struct s_smc *smc)
{
	SK_LOC_DECL(u_int,a[2]) ;

	/*
	 * set UNA in frame
	 * enable FORMAC to send endless queue of directed beacon
	 * important: the UNA starts at byte 1 (not at byte 0)
	 */
	* (char *) a = (char) ((long)DBEACON_INFO<<24L) ;
	a[1] = 0 ;
	memcpy((char *)a+1,(char *) &smc->mib.m[MAC0].fddiMACUpstreamNbr,6) ;

	CHECK_NPP() ;
	 /* set memory address reg for writes */
	MARW(smc->hw.fp.fifo.rbc_ram_start+DBEACON_FRAME_OFF+4) ;
	write_mdr(smc,MDR_REVERSE(a[0])) ;
	outpw(FM_A(FM_CMDREG2),FM_ISTTB) ;	/* set the tag bit */
	write_mdr(smc,MDR_REVERSE(a[1])) ;

	outpw(FM_A(FM_SABC),smc->hw.fp.fifo.rbc_ram_start + DBEACON_FRAME_OFF) ;
}

/*
	setup claim & beacon pointer
	NOTE :
		special frame packets end with a pointer to their own
		descriptor, and the MORE bit is set in the descriptor
*/
static void build_claim_beacon(struct s_smc *smc, u_long t_request)
{
	u_int	td ;
	int	len ;
	struct fddi_mac_sf *mac ;

	/*
	 * build claim packet
	 */
	len = 17 ;
	td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ;
	mac = &smc->hw.fp.mac_sfb ;
	mac->mac_fc = FC_CLAIM ;
	/* DA == SA in claim frame */
	mac->mac_source = mac->mac_dest = MA ;
	/* 2's complement */
	set_int((char *)mac->mac_info,(int)t_request) ;

	copy_tx_mac(smc,td,(struct fddi_mac *)mac,
		smc->hw.fp.fifo.rbc_ram_start + CLAIM_FRAME_OFF,len) ;
	/* set CLAIM start pointer */
	outpw(FM_A(FM_SACL),smc->hw.fp.fifo.rbc_ram_start + CLAIM_FRAME_OFF) ;

	/*
	 * build beacon packet
	 */
	len = 17 ;
	td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ;
	mac->mac_fc = FC_BEACON ;
	mac->mac_source = MA ;
	mac->mac_dest = null_addr ;		/* DA == 0 in beacon frame */
	set_int((char *) mac->mac_info,((int)BEACON_INFO<<24) + 0 ) ;

	copy_tx_mac(smc,td,(struct fddi_mac *)mac,
		smc->hw.fp.fifo.rbc_ram_start + BEACON_FRAME_OFF,len) ;
	/* set beacon start pointer */
	outpw(FM_A(FM_SABC),smc->hw.fp.fifo.rbc_ram_start + BEACON_FRAME_OFF) ;

	/*
	 * build directed beacon packet
	 * contains optional UNA
	 */
	len = 23 ;
	td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ;
	mac->mac_fc = FC_BEACON ;
	mac->mac_source = MA ;
	mac->mac_dest = dbeacon_multi ;		/* multicast */
	set_int((char *) mac->mac_info,((int)DBEACON_INFO<<24) + 0 ) ;
	set_int((char *) mac->mac_info+4,0) ;
	set_int((char *) mac->mac_info+8,0) ;

	copy_tx_mac(smc,td,(struct fddi_mac *)mac,
		smc->hw.fp.fifo.rbc_ram_start + DBEACON_FRAME_OFF,len) ;

	/* end of claim/beacon queue */
	outpw(FM_A(FM_EACB),smc->hw.fp.fifo.rx1_fifo_start-1) ;

	outpw(FM_A(FM_WPXSF),0) ;
	outpw(FM_A(FM_RPXSF),0) ;
}

static void formac_rcv_restart(struct s_smc *smc)
{
	/* enable receive function */
	SETMASK(FM_A(FM_MDREG1),smc->hw.fp.rx_mode,FM_ADDRX) ;

	outpw(FM_A(FM_CMDREG1),FM_ICLLR) ;	/* clear receive lock */
}

void formac_tx_restart(struct s_smc *smc)
{
	outpw(FM_A(FM_CMDREG1),FM_ICLLS) ;	/* clear s-frame lock */
	outpw(FM_A(FM_CMDREG1),FM_ICLLA0) ;	/* clear a-frame lock */
}

static void enable_formac(struct s_smc *smc)
{
	/* set formac IMSK : 0 enables irq */
	outpw(FM_A(FM_IMSK1U),~mac_imsk1u) ;
	outpw(FM_A(FM_IMSK1L),~mac_imsk1l) ;
	outpw(FM_A(FM_IMSK2U),~mac_imsk2u) ;
	outpw(FM_A(FM_IMSK2L),~mac_imsk2l) ;
	outpw(FM_A(FM_IMSK3U),~mac_imsk3u) ;
	outpw(FM_A(FM_IMSK3L),~mac_imsk3l) ;
}

#if 0	/* Removed because the driver should use the ASICs TX complete IRQ. */
	/* The FORMACs tx complete IRQ should be used any longer */

/*
	BEGIN_MANUAL_ENTRY(if,func;others;4)

	void enable_tx_irq(smc, queue)
	struct s_smc *smc ;
	u_short	queue ;

Function	DOWNCALL	(SMT, fplustm.c)
		enable_tx_irq() enables the FORMACs transmit complete
		interrupt of the queue.

Para	queue	= QUEUE_S:	synchronous queue
		= QUEUE_A0:	asynchronous queue

Note	After any ring operational change the transmit complete
	interrupts are disabled.
	The operating system dependent module must enable
	the transmit complete interrupt of a queue,
		- when it queues the first frame,
		  because of no transmit resources are beeing
		  available and
		- when it escapes from the function llc_restart_tx
		  while some frames are still queued.

	END_MANUAL_ENTRY
 */
void enable_tx_irq(struct s_smc *smc, u_short queue)
/* u_short queue; 0 = synchronous queue, 1 = asynchronous queue 0 */
{
	u_short	imask ;

	imask = ~(inpw(FM_A(FM_IMSK1U))) ;

	if (queue == 0) {
		outpw(FM_A(FM_IMSK1U),~(imask|FM_STEFRMS)) ;
	}
	if (queue == 1) {
		outpw(FM_A(FM_IMSK1U),~(imask|FM_STEFRMA0)) ;
	}
}

/*
	BEGIN_MANUAL_ENTRY(if,func;others;4)

	void disable_tx_irq(smc, queue)
	struct s_smc *smc ;
	u_short	queue ;

Function	DOWNCALL	(SMT, fplustm.c)
		disable_tx_irq disables the FORMACs transmit complete
		interrupt of the queue

Para	queue	= QUEUE_S:	synchronous queue
		= QUEUE_A0:	asynchronous queue

Note	The operating system dependent module should disable
	the transmit complete interrupts if it escapes from the
	function llc_restart_tx and no frames are queued.

	END_MANUAL_ENTRY
 */
void disable_tx_irq(struct s_smc *smc, u_short queue)
/* u_short queue; 0 = synchronous queue, 1 = asynchronous queue 0 */
{
	u_short	imask ;

	imask = ~(inpw(FM_A(FM_IMSK1U))) ;

	if (queue == 0) {
		outpw(FM_A(FM_IMSK1U),~(imask&~FM_STEFRMS)) ;
	}
	if (queue == 1) {
		outpw(FM_A(FM_IMSK1U),~(imask&~FM_STEFRMA0)) ;
	}
}
#endif

static void disable_formac(struct s_smc *smc)
{
	/* clear formac IMSK : 1 disables irq */
	outpw(FM_A(FM_IMSK1U),MW) ;
	outpw(FM_A(FM_IMSK1L),MW) ;
	outpw(FM_A(FM_IMSK2U),MW) ;
	outpw(FM_A(FM_IMSK2L),MW) ;
	outpw(FM_A(FM_IMSK3U),MW) ;
	outpw(FM_A(FM_IMSK3L),MW) ;
}


static void mac_ring_up(struct s_smc *smc, int up)
{
	if (up) {
		formac_rcv_restart(smc) ;	/* enable receive function */
		smc->hw.mac_ring_is_up = TRUE ;
		llc_restart_tx(smc) ;		/* TX queue */
	}
	else {
		/* disable receive function */
		SETMASK(FM_A(FM_MDREG1),FM_MDISRCV,FM_ADDET) ;

		/* abort current transmit activity */
		outpw(FM_A(FM_CMDREG2),FM_IACTR) ;

		smc->hw.mac_ring_is_up = FALSE ;
	}
}

/*--------------------------- ISR handling ----------------------------------*/
/*
 * mac1_irq is in drvfbi.c
 */

/*
 * mac2_irq:	status bits for the receive queue 1, and ring status
 * 		ring status indication bits
 */
void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l)
{
	u_short	change_s2l ;
	u_short	change_s2u ;

	/* (jd) 22-Feb-1999
	 * Restart 2_DMax Timer after end of claiming or beaconing
	 */
	if (code_s2u & (FM_SCLM|FM_SHICLM|FM_SBEC|FM_SOTRBEC)) {
		queue_event(smc,EVENT_RMT,RM_TX_STATE_CHANGE) ;
	}
	else if (code_s2l & (FM_STKISS)) {
		queue_event(smc,EVENT_RMT,RM_TX_STATE_CHANGE) ;
	}

	/*
	 * XOR current st bits with the last to avoid useless RMT event queuing
	 */
	change_s2l = smc->hw.fp.s2l ^ code_s2l ;
	change_s2u = smc->hw.fp.s2u ^ code_s2u ;

	if ((change_s2l & FM_SRNGOP) ||
		(!smc->hw.mac_ring_is_up && ((code_s2l & FM_SRNGOP)))) {
		if (code_s2l & FM_SRNGOP) {
			mac_ring_up(smc,1) ;
			queue_event(smc,EVENT_RMT,RM_RING_OP) ;
			smc->mib.m[MAC0].fddiMACRingOp_Ct++ ;
		}
		else {
			mac_ring_up(smc,0) ;
			queue_event(smc,EVENT_RMT,RM_RING_NON_OP) ;
		}
		goto mac2_end ;
	}
	if (code_s2l & FM_SMISFRM) {	/* missed frame */
		smc->mib.m[MAC0].fddiMACNotCopied_Ct++ ;
	}
	if (code_s2u & (FM_SRCVOVR |	/* recv. FIFO overflow */
			FM_SRBFL)) {	/* recv. buffer full */
		smc->hw.mac_ct.mac_r_restart_counter++ ;
/*		formac_rcv_restart(smc) ;	*/
		smt_stat_counter(smc,1) ;
/*		goto mac2_end ;			*/
	}
	if (code_s2u & FM_SOTRBEC)
		queue_event(smc,EVENT_RMT,RM_OTHER_BEACON) ;
	if (code_s2u & FM_SMYBEC)
		queue_event(smc,EVENT_RMT,RM_MY_BEACON) ;
	if (change_s2u & code_s2u & FM_SLOCLM) {
		DB_RMTN(2,"RMT : lower claim received\n",0,0) ;
	}
	if ((code_s2u & FM_SMYCLM) && !(code_s2l & FM_SDUPCLM)) {
		/*
		 * This is my claim and that claim is not detected as a
		 * duplicate one.
		 */
		queue_event(smc,EVENT_RMT,RM_MY_CLAIM) ;
	}
	if (code_s2l & FM_SDUPCLM) {
		/*
		 * If a duplicate claim frame (same SA but T_Bid != T_Req)
		 * this flag will be set.
		 * In the RMT state machine we need a RM_VALID_CLAIM event
		 * to do the appropriate state change.
		 * RM(34c)
		 */
		queue_event(smc,EVENT_RMT,RM_VALID_CLAIM) ;
	}
	if (change_s2u & code_s2u & FM_SHICLM) {
		DB_RMTN(2,"RMT : higher claim received\n",0,0) ;
	}
	if ( (code_s2l & FM_STRTEXP) ||
	     (code_s2l & FM_STRTEXR) )
		queue_event(smc,EVENT_RMT,RM_TRT_EXP) ;
	if (code_s2l & FM_SMULTDA) {
		/*
		 * The MAC has found a 2. MAC with the same address.
		 * Signal dup_addr_test = failed to RMT state machine.
		 * RM(25)
		 */
		smc->r.dup_addr_test = DA_FAILED ;
		queue_event(smc,EVENT_RMT,RM_DUP_ADDR) ;
	}
	if (code_s2u & FM_SBEC)
		smc->hw.fp.err_stats.err_bec_stat++ ;
	if (code_s2u & FM_SCLM)
		smc->hw.fp.err_stats.err_clm_stat++ ;
	if (code_s2l & FM_STVXEXP)
		smc->mib.m[MAC0].fddiMACTvxExpired_Ct++ ;
	if ((code_s2u & (FM_SBEC|FM_SCLM))) {
		if (!(change_s2l & FM_SRNGOP) && (smc->hw.fp.s2l & FM_SRNGOP)) {
			mac_ring_up(smc,0) ;
			queue_event(smc,EVENT_RMT,RM_RING_NON_OP) ;

			mac_ring_up(smc,1) ;
			queue_event(smc,EVENT_RMT,RM_RING_OP) ;
			smc->mib.m[MAC0].fddiMACRingOp_Ct++ ;
		}
	}
	if (code_s2l & FM_SPHINV)
		smc->hw.fp.err_stats.err_phinv++ ;
	if (code_s2l & FM_SSIFG)
		smc->hw.fp.err_stats.err_sifg_det++ ;
	if (code_s2l & FM_STKISS)
		smc->hw.fp.err_stats.err_tkiss++ ;
	if (code_s2l & FM_STKERR)
		smc->hw.fp.err_stats.err_tkerr++ ;
	if (code_s2l & FM_SFRMCTR)
		smc->mib.m[MAC0].fddiMACFrame_Ct += 0x10000L ;
	if (code_s2l & FM_SERRCTR)
		smc->mib.m[MAC0].fddiMACError_Ct += 0x10000L ;
	if (code_s2l & FM_SLSTCTR)
		smc->mib.m[MAC0].fddiMACLost_Ct  += 0x10000L ;
	if (code_s2u & FM_SERRSF) {
		SMT_PANIC(smc,SMT_E0114, SMT_E0114_MSG) ;
	}
mac2_end:
	/* notice old status */
	smc->hw.fp.s2l = code_s2l ;
	smc->hw.fp.s2u = code_s2u ;
	outpw(FM_A(FM_IMSK2U),~mac_imsk2u) ;
}

/*
 * mac3_irq:	receive queue 2 bits and address detection bits
 */
void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l)
{
	UNUSED(code_s3l) ;

	if (code_s3u & (FM_SRCVOVR2 |	/* recv. FIFO overflow */
			FM_SRBFL2)) {	/* recv. buffer full */
		smc->hw.mac_ct.mac_r_restart_counter++ ;
		smt_stat_counter(smc,1);
	}


	if (code_s3u & FM_SRPERRQ2) {	/* parity error receive queue 2 */
		SMT_PANIC(smc,SMT_E0115, SMT_E0115_MSG) ;
	}
	if (code_s3u & FM_SRPERRQ1) {	/* parity error receive queue 2 */
		SMT_PANIC(smc,SMT_E0116, SMT_E0116_MSG) ;
	}
}


/*
 * take formac offline
 */
static void formac_offline(struct s_smc *smc)
{
	outpw(FM_A(FM_CMDREG2),FM_IACTR) ;/* abort current transmit activity */

	/* disable receive function */
	SETMASK(FM_A(FM_MDREG1),FM_MDISRCV,FM_ADDET) ;

	/* FORMAC+ 'Initialize Mode' */
	SETMASK(FM_A(FM_MDREG1),FM_MINIT,FM_MMODE) ;

	disable_formac(smc) ;
	smc->hw.mac_ring_is_up = FALSE ;
	smc->hw.hw_state = STOPPED ;
}

/*
 * bring formac online
 */
static void formac_online(struct s_smc *smc)
{
	enable_formac(smc) ;
	SETMASK(FM_A(FM_MDREG1),FM_MONLINE | FM_SELRA | MDR1INIT |
		smc->hw.fp.rx_mode, FM_MMODE | FM_SELRA | FM_ADDRX) ;
}

/*
 * FORMAC+ full init. (tx, rx, timer, counter, claim & beacon)
 */
int init_fplus(struct s_smc *smc)
{
	smc->hw.fp.nsa_mode = FM_MRNNSAFNMA ;
	smc->hw.fp.rx_mode = FM_MDAMA ;
	smc->hw.fp.group_addr = fddi_broadcast ;
	smc->hw.fp.func_addr = 0 ;
	smc->hw.fp.frselreg_init = 0 ;

	init_driver_fplus(smc) ;
	if (smc->s.sas == SMT_DAS)
		smc->hw.fp.mdr3init |= FM_MENDAS ;

	smc->hw.mac_ct.mac_nobuf_counter = 0 ;
	smc->hw.mac_ct.mac_r_restart_counter = 0 ;

	smc->hw.fp.fm_st1u = (HW_PTR) ADDR(B0_ST1U) ;
	smc->hw.fp.fm_st1l = (HW_PTR) ADDR(B0_ST1L) ;
	smc->hw.fp.fm_st2u = (HW_PTR) ADDR(B0_ST2U) ;
	smc->hw.fp.fm_st2l = (HW_PTR) ADDR(B0_ST2L) ;
	smc->hw.fp.fm_st3u = (HW_PTR) ADDR(B0_ST3U) ;
	smc->hw.fp.fm_st3l = (HW_PTR) ADDR(B0_ST3L) ;

	smc->hw.fp.s2l = smc->hw.fp.s2u = 0 ;
	smc->hw.mac_ring_is_up = 0 ;

	mac_counter_init(smc) ;

	/* convert BCKL units to symbol time */
	smc->hw.mac_pa.t_neg = (u_long)0 ;
	smc->hw.mac_pa.t_pri = (u_long)0 ;

	/* make sure all PCI settings are correct */
	mac_do_pci_fix(smc) ;

	return(init_mac(smc,1)) ;
	/* enable_formac(smc) ; */
}

static int init_mac(struct s_smc *smc, int all)
{
	u_short	t_max,x ;
	u_long	time=0 ;

	/*
	 * clear memory
	 */
	outpw(FM_A(FM_MDREG1),FM_MINIT) ;	/* FORMAC+ init mode */
	set_formac_addr(smc) ;
	outpw(FM_A(FM_MDREG1),FM_MMEMACT) ;	/* FORMAC+ memory activ mode */
	/* Note: Mode register 2 is set here, incase parity is enabled. */
	outpw(FM_A(FM_MDREG2),smc->hw.fp.mdr2init) ;

	if (all) {
		init_ram(smc) ;
	}
	else {
		/*
		 * reset the HPI, the Master and the BMUs
		 */
		outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;
		time = hwt_quick_read(smc) ;
	}

	/*
	 * set all pointers, frames etc
	 */
	smt_split_up_fifo(smc) ;

	init_tx(smc) ;
	init_rx(smc) ;
	init_rbc(smc) ;

	build_claim_beacon(smc,smc->mib.m[MAC0].fddiMACT_Req) ;

	/* set RX threshold */
	/* see Errata #SN2 Phantom receive overflow */
	outpw(FM_A(FM_FRMTHR),14<<12) ;		/* switch on */

	/* set formac work mode */
	outpw(FM_A(FM_MDREG1),MDR1INIT | FM_SELRA | smc->hw.fp.rx_mode) ;
	outpw(FM_A(FM_MDREG2),smc->hw.fp.mdr2init) ;
	outpw(FM_A(FM_MDREG3),smc->hw.fp.mdr3init) ;
	outpw(FM_A(FM_FRSELREG),smc->hw.fp.frselreg_init) ;

	/* set timer */
	/*
	 * errata #22 fplus:
	 * T_MAX must not be FFFE
	 * or one of FFDF, FFB8, FF91 (-0x27 etc..)
	 */
	t_max = (u_short)(smc->mib.m[MAC0].fddiMACT_Max/32) ;
	x = t_max/0x27 ;
	x *= 0x27 ;
	if ((t_max == 0xfffe) || (t_max - x == 0x16))
		t_max-- ;
	outpw(FM_A(FM_TMAX),(u_short)t_max) ;

	/* BugFix for report #10204 */
	if (smc->mib.m[MAC0].fddiMACTvxValue < (u_long) (- US2BCLK(52))) {
		outpw(FM_A(FM_TVX), (u_short) (- US2BCLK(52))/255 & MB) ;
	} else {
		outpw(FM_A(FM_TVX),
			(u_short)((smc->mib.m[MAC0].fddiMACTvxValue/255) & MB)) ;
	}

	outpw(FM_A(FM_CMDREG1),FM_ICLLS) ;	/* clear s-frame lock */
	outpw(FM_A(FM_CMDREG1),FM_ICLLA0) ;	/* clear a-frame lock */
	outpw(FM_A(FM_CMDREG1),FM_ICLLR);	/* clear receive lock */

	/* Auto unlock receice threshold for receive queue 1 and 2 */
	outpw(FM_A(FM_UNLCKDLY),(0xff|(0xff<<8))) ;

	rtm_init(smc) ;				/* RT-Monitor */

	if (!all) {
		/*
		 * after 10ms, reset the BMUs and repair the rings
		 */
		hwt_wait_time(smc,time,MS2BCLK(10)) ;
		outpd(ADDR(B0_R1_CSR),CSR_SET_RESET) ;
		outpd(ADDR(B0_XA_CSR),CSR_SET_RESET) ;
		outpd(ADDR(B0_XS_CSR),CSR_SET_RESET) ;
		outp(ADDR(B0_CTRL), CTRL_HPI_CLR) ;
		outpd(ADDR(B0_R1_CSR),CSR_CLR_RESET) ;
		outpd(ADDR(B0_XA_CSR),CSR_CLR_RESET) ;
		outpd(ADDR(B0_XS_CSR),CSR_CLR_RESET) ;
		if (!smc->hw.hw_is_64bit) {
			outpd(ADDR(B4_R1_F), RX_WATERMARK) ;
			outpd(ADDR(B5_XA_F), TX_WATERMARK) ;
			outpd(ADDR(B5_XS_F), TX_WATERMARK) ;
		}
		smc->hw.hw_state = STOPPED ;
		mac_drv_repair_descr(smc) ;
	}
	smc->hw.hw_state = STARTED ;

	return(0) ;
}


/*
 * called by CFM
 */
void config_mux(struct s_smc *smc, int mux)
{
	plc_config_mux(smc,mux) ;

	SETMASK(FM_A(FM_MDREG1),FM_SELRA,FM_SELRA) ;
}

/*
 * called by RMT
 * enable CLAIM/BEACON interrupts
 * (only called if these events are of interest, e.g. in DETECT state
 * the interrupt must not be permanently enabled
 * RMT calls this function periodically (timer driven polling)
 */
void sm_mac_check_beacon_claim(struct s_smc *smc)
{
	/* set formac IMSK : 0 enables irq */
	outpw(FM_A(FM_IMSK2U),~(mac_imsk2u | mac_beacon_imsk2u)) ;
	/* the driver must receive the directed beacons */
	formac_rcv_restart(smc) ;
	process_receive(smc) ;
}

/*-------------------------- interface functions ----------------------------*/
/*
 * control MAC layer	(called by RMT)
 */
void sm_ma_control(struct s_smc *smc, int mode)
{
	switch(mode) {
	case MA_OFFLINE :
		/* Add to make the MAC offline in RM0_ISOLATED state */
		formac_offline(smc) ;
		break ;
	case MA_RESET :
		(void)init_mac(smc,0) ;
		break ;
	case MA_BEACON :
		formac_online(smc) ;
		break ;
	case MA_DIRECTED :
		directed_beacon(smc) ;
		break ;
	case MA_TREQ :
		/*
		 * no actions necessary, TREQ is already set
		 */
		break ;
	}
}

int sm_mac_get_tx_state(struct s_smc *smc)
{
	return((inpw(FM_A(FM_STMCHN))>>4)&7) ;
}

/*
 * multicast functions
 */

static struct s_fpmc* mac_get_mc_table(struct s_smc *smc,
				       struct fddi_addr *user,
				       struct fddi_addr *own,
				       int del, int can)
{
	struct s_fpmc	*tb ;
	struct s_fpmc	*slot ;
	u_char	*p ;
	int i ;

	/*
	 * set own = can(user)
	 */
	*own = *user ;
	if (can) {
		p = own->a ;
		for (i = 0 ; i < 6 ; i++, p++)
			*p = canonical[*p] ;
	}
	slot = NULL;
	for (i = 0, tb = smc->hw.fp.mc.table ; i < FPMAX_MULTICAST ; i++, tb++){
		if (!tb->n) {		/* not used */
			if (!del && !slot)	/* if !del save first free */
				slot = tb ;
			continue ;
		}
		if (memcmp((char *)&tb->a,(char *)own,6))
			continue ;
		return(tb) ;
	}
	return(slot) ;			/* return first free or NULL */
}

/*
	BEGIN_MANUAL_ENTRY(if,func;others;2)

	void mac_clear_multicast(smc)
	struct s_smc *smc ;

Function	DOWNCALL	(SMT, fplustm.c)
		Clear all multicast entries

	END_MANUAL_ENTRY()
 */
void mac_clear_multicast(struct s_smc *smc)
{
	struct s_fpmc	*tb ;
	int i ;

	smc->hw.fp.os_slots_used = 0 ;	/* note the SMT addresses */
					/* will not be deleted */
	for (i = 0, tb = smc->hw.fp.mc.table ; i < FPMAX_MULTICAST ; i++, tb++){
		if (!tb->perm) {
			tb->n = 0 ;
		}
	}
}

/*
	BEGIN_MANUAL_ENTRY(if,func;others;2)

	int mac_set_func_addr(smc,f_addr)
	struct s_smc *smc ;
	u_long f_addr ;

Function	DOWNCALL	(SMT, fplustm.c)
		Set a Token-Ring functional address, the address will
		be activated after calling mac_update_multicast()

Para	f_addr	functional bits in non-canonical format

Returns	0: always success

	END_MANUAL_ENTRY()
 */
int mac_set_func_addr(struct s_smc *smc, u_long f_addr)
{
	smc->hw.fp.func_addr = f_addr ;
	return(0) ;
}


/*
	BEGIN_MANUAL_ENTRY(if,func;others;2)

	int mac_add_multicast(smc,addr,can)
	struct s_smc *smc ;
	struct fddi_addr *addr ;
	int can ;

Function	DOWNCALL	(SMC, fplustm.c)
		Add an entry to the multicast table

Para	addr	pointer to a multicast address
	can	= 0:	the multicast address has the physical format
		= 1:	the multicast address has the canonical format
		| 0x80	permanent

Returns	0: success
	1: address table full

Note	After a 'driver reset' or a 'station set address' all
	entries of the multicast table are cleared.
	In this case the driver has to fill the multicast table again.
	After the operating system dependent module filled
	the multicast table it must call mac_update_multicast
	to activate the new multicast addresses!

	END_MANUAL_ENTRY()
 */
int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can)
{
	SK_LOC_DECL(struct fddi_addr,own) ;
	struct s_fpmc	*tb ;

	/*
	 * check if there are free table entries
	 */
	if (can & 0x80) {
		if (smc->hw.fp.smt_slots_used >= SMT_MAX_MULTI) {
			return(1) ;
		}
	}
	else {
		if (smc->hw.fp.os_slots_used >= FPMAX_MULTICAST-SMT_MAX_MULTI) {
			return(1) ;
		}
	}

	/*
	 * find empty slot
	 */
	if (!(tb = mac_get_mc_table(smc,addr,&own,0,can & ~0x80)))
		return(1) ;
	tb->n++ ;
	tb->a = own ;
	tb->perm = (can & 0x80) ? 1 : 0 ;

	if (can & 0x80)
		smc->hw.fp.smt_slots_used++ ;
	else
		smc->hw.fp.os_slots_used++ ;

	return(0) ;
}

/*
	BEGIN_MANUAL_ENTRY(if,func;others;2)

	void mac_del_multicast(smc,addr,can)
	struct s_smc *smc ;
	struct fddi_addr *addr ;
	int can ;

Function	DOWNCALL	(SMT, fplustm.c)
		Delete an entry from the multicast table

Para	addr	pointer to a multicast address
	can	= 0:	the multicast address has the physical format
		= 1:	the multicast address has the canonical format
		| 0x80	permanent

	END_MANUAL_ENTRY()
 */
void mac_del_multicast(struct s_smc *smc, struct fddi_addr *addr, int can)
{
	SK_LOC_DECL(struct fddi_addr,own) ;
	struct s_fpmc	*tb ;

	if (!(tb = mac_get_mc_table(smc,addr,&own,1,can & ~0x80)))
		return ;
	/*
	 * permanent addresses must be deleted with perm bit
	 * and vice versa
	 */
	if (( tb->perm &&  (can & 0x80)) ||
	    (!tb->perm && !(can & 0x80))) {
		/*
		 * delete it
		 */
		if (tb->n) {
			tb->n-- ;
			if (tb->perm) {
				smc->hw.fp.smt_slots_used-- ;
			}
			else {
				smc->hw.fp.os_slots_used-- ;
			}
		}
	}
}

/*
 * mode
 */

#define RX_MODE_PROM		0x1
#define RX_MODE_ALL_MULTI	0x2

/*
	BEGIN_MANUAL_ENTRY(if,func;others;2)

	void mac_update_multicast(smc)
	struct s_smc *smc ;

Function	DOWNCALL	(SMT, fplustm.c)
		Update FORMAC multicast registers

	END_MANUAL_ENTRY()
 */
void mac_update_multicast(struct s_smc *smc)
{
	struct s_fpmc	*tb ;
	u_char	*fu ;
	int	i ;

	/*
	 * invalidate the CAM
	 */
	outpw(FM_A(FM_AFCMD),FM_IINV_CAM) ;

	/*
	 * set the functional address
	 */
	if (smc->hw.fp.func_addr) {
		fu = (u_char *) &smc->hw.fp.func_addr ;
		outpw(FM_A(FM_AFMASK2),0xffff) ;
		outpw(FM_A(FM_AFMASK1),(u_short) ~((fu[0] << 8) + fu[1])) ;
		outpw(FM_A(FM_AFMASK0),(u_short) ~((fu[2] << 8) + fu[3])) ;
		outpw(FM_A(FM_AFPERS),FM_VALID|FM_DA) ;
		outpw(FM_A(FM_AFCOMP2), 0xc000) ;
		outpw(FM_A(FM_AFCOMP1), 0x0000) ;
		outpw(FM_A(FM_AFCOMP0), 0x0000) ;
		outpw(FM_A(FM_AFCMD),FM_IWRITE_CAM) ;
	}

	/*
	 * set the mask and the personality register(s)
	 */
	outpw(FM_A(FM_AFMASK0),0xffff) ;
	outpw(FM_A(FM_AFMASK1),0xffff) ;
	outpw(FM_A(FM_AFMASK2),0xffff) ;
	outpw(FM_A(FM_AFPERS),FM_VALID|FM_DA) ;

	for (i = 0, tb = smc->hw.fp.mc.table; i < FPMAX_MULTICAST; i++, tb++) {
		if (tb->n) {
			CHECK_CAM() ;

			/*
			 * write the multicast address into the CAM
			 */
			outpw(FM_A(FM_AFCOMP2),
				(u_short)((tb->a.a[0]<<8)+tb->a.a[1])) ;
			outpw(FM_A(FM_AFCOMP1),
				(u_short)((tb->a.a[2]<<8)+tb->a.a[3])) ;
			outpw(FM_A(FM_AFCOMP0),
				(u_short)((tb->a.a[4]<<8)+tb->a.a[5])) ;
			outpw(FM_A(FM_AFCMD),FM_IWRITE_CAM) ;
		}
	}
}

/*
	BEGIN_MANUAL_ENTRY(if,func;others;3)

	void mac_set_rx_mode(smc,mode)
	struct s_smc *smc ;
	int mode ;

Function	DOWNCALL/INTERN	(SMT, fplustm.c)
		This function enables / disables the selected receive.
		Don't call this function if the hardware module is
		used -- use mac_drv_rx_mode() instead of.

Para	mode =	1	RX_ENABLE_ALLMULTI	enable all multicasts
		2	RX_DISABLE_ALLMULTI	disable "enable all multicasts"
		3	RX_ENABLE_PROMISC	enable promiscous
		4	RX_DISABLE_PROMISC	disable promiscous
		5	RX_ENABLE_NSA		enable reception of NSA frames
		6	RX_DISABLE_NSA		disable reception of NSA frames

Note	The selected receive modes will be lost after 'driver reset'
	or 'set station address'

	END_MANUAL_ENTRY
 */
void mac_set_rx_mode(struct s_smc *smc, int mode)
{
	switch (mode) {
	case RX_ENABLE_ALLMULTI :
		smc->hw.fp.rx_prom |= RX_MODE_ALL_MULTI ;
		break ;
	case RX_DISABLE_ALLMULTI :
		smc->hw.fp.rx_prom &= ~RX_MODE_ALL_MULTI ;
		break ;
	case RX_ENABLE_PROMISC :
		smc->hw.fp.rx_prom |= RX_MODE_PROM ;
		break ;
	case RX_DISABLE_PROMISC :
		smc->hw.fp.rx_prom &= ~RX_MODE_PROM ;
		break ;
	case RX_ENABLE_NSA :
		smc->hw.fp.nsa_mode = FM_MDAMA ;
		smc->hw.fp.rx_mode = (smc->hw.fp.rx_mode & ~FM_ADDET) |
			smc->hw.fp.nsa_mode ;
		break ;
	case RX_DISABLE_NSA :
		smc->hw.fp.nsa_mode = FM_MRNNSAFNMA ;
		smc->hw.fp.rx_mode = (smc->hw.fp.rx_mode & ~FM_ADDET) |
			smc->hw.fp.nsa_mode ;
		break ;
	}
	if (smc->hw.fp.rx_prom & RX_MODE_PROM) {
		smc->hw.fp.rx_mode = FM_MLIMPROM ;
	}
	else if (smc->hw.fp.rx_prom & RX_MODE_ALL_MULTI) {
		smc->hw.fp.rx_mode = smc->hw.fp.nsa_mode | FM_EXGPA0 ;
	}
	else
		smc->hw.fp.rx_mode = smc->hw.fp.nsa_mode ;
	SETMASK(FM_A(FM_MDREG1),smc->hw.fp.rx_mode,FM_ADDRX) ;
	mac_update_multicast(smc) ;
}

/*
	BEGIN_MANUAL_ENTRY(module;tests;3)
	How to test the Restricted Token Monitor
	----------------------------------------------------------------

	o Insert a break point in the function rtm_irq()
	o Remove all stations with a restricted token monitor from the
	  network.
	o Connect a UPPS ISA or EISA station to the network.
	o Give the FORMAC of UPPS station the command to send
	  restricted tokens until the ring becomes instable.
	o Now connect your test test client.
	o The restricted token monitor should detect the restricted token,
	  and your break point will be reached.
	o You can ovserve how the station will clean the ring.

	END_MANUAL_ENTRY
 */
void rtm_irq(struct s_smc *smc)
{
	outpw(ADDR(B2_RTM_CRTL),TIM_CL_IRQ) ;		/* clear IRQ */
	if (inpw(ADDR(B2_RTM_CRTL)) & TIM_RES_TOK) {
		outpw(FM_A(FM_CMDREG1),FM_ICL) ;	/* force claim */
		DB_RMT("RMT: fddiPATHT_Rmode expired\n",0,0) ;
		AIX_EVENT(smc, (u_long) FDDI_RING_STATUS,
				(u_long) FDDI_SMT_EVENT,
				(u_long) FDDI_RTT, smt_get_event_word(smc));
	}
	outpw(ADDR(B2_RTM_CRTL),TIM_START) ;	/* enable RTM monitoring */
}

static void rtm_init(struct s_smc *smc)
{
	outpd(ADDR(B2_RTM_INI),0) ;		/* timer = 0 */
	outpw(ADDR(B2_RTM_CRTL),TIM_START) ;	/* enable IRQ */
}

void rtm_set_timer(struct s_smc *smc)
{
	/*
	 * MIB timer and hardware timer have the same resolution of 80nS
	 */
	DB_RMT("RMT: setting new fddiPATHT_Rmode, t = %d ns \n",
		(int) smc->mib.a[PATH0].fddiPATHT_Rmode,0) ;
	outpd(ADDR(B2_RTM_INI),smc->mib.a[PATH0].fddiPATHT_Rmode) ;
}

static void smt_split_up_fifo(struct s_smc *smc)
{

/*
	BEGIN_MANUAL_ENTRY(module;mem;1)
	-------------------------------------------------------------
	RECEIVE BUFFER MEMORY DIVERSION
	-------------------------------------------------------------

	R1_RxD == SMT_R1_RXD_COUNT
	R2_RxD == SMT_R2_RXD_COUNT

	SMT_R1_RXD_COUNT must be unequal zero

		   | R1_RxD R2_RxD |R1_RxD R2_RxD | R1_RxD R2_RxD
		   |   x      0	   |  x	    1-3	  |   x     < 3
	----------------------------------------------------------------------
		   |   63,75 kB	   |    54,75	  |	R1_RxD
	rx queue 1 | RX_FIFO_SPACE | RX_LARGE_FIFO| ------------- * 63,75 kB
		   |		   |		  | R1_RxD+R2_RxD
	----------------------------------------------------------------------
		   |		   |    9 kB	  |     R2_RxD
	rx queue 2 |	0 kB	   | RX_SMALL_FIFO| ------------- * 63,75 kB
		   |  (not used)   |		  | R1_RxD+R2_RxD

	END_MANUAL_ENTRY
*/

	if (SMT_R1_RXD_COUNT == 0) {
		SMT_PANIC(smc,SMT_E0117, SMT_E0117_MSG) ;
	}

	switch(SMT_R2_RXD_COUNT) {
	case 0:
		smc->hw.fp.fifo.rx1_fifo_size = RX_FIFO_SPACE ;
		smc->hw.fp.fifo.rx2_fifo_size = 0 ;
		break ;
	case 1:
	case 2:
	case 3:
		smc->hw.fp.fifo.rx1_fifo_size = RX_LARGE_FIFO ;
		smc->hw.fp.fifo.rx2_fifo_size = RX_SMALL_FIFO ;
		break ;
	default:	/* this is not the real defaule */
		smc->hw.fp.fifo.rx1_fifo_size = RX_FIFO_SPACE *
		SMT_R1_RXD_COUNT/(SMT_R1_RXD_COUNT+SMT_R2_RXD_COUNT) ;
		smc->hw.fp.fifo.rx2_fifo_size = RX_FIFO_SPACE *
		SMT_R2_RXD_COUNT/(SMT_R1_RXD_COUNT+SMT_R2_RXD_COUNT) ;
		break ;
	}

/*
	BEGIN_MANUAL_ENTRY(module;mem;1)
	-------------------------------------------------------------
	TRANSMIT BUFFER MEMORY DIVERSION
	-------------------------------------------------------------


		 | no sync bw	| sync bw available and | sync bw available and
		 | available	| SynchTxMode = SPLIT	| SynchTxMode = ALL
	-----------------------------------------------------------------------
	sync tx	 |     0 kB	|	32 kB		|	55 kB
	queue	 |		|   TX_MEDIUM_FIFO	|   TX_LARGE_FIFO
	-----------------------------------------------------------------------
	async tx |    64 kB	|	32 kB		|	 9 k
	queue	 | TX_FIFO_SPACE|   TX_MEDIUM_FIFO	|   TX_SMALL_FIFO

	END_MANUAL_ENTRY
*/

	/*
	 * set the tx mode bits
	 */
	if (smc->mib.a[PATH0].fddiPATHSbaPayload) {
#ifdef ESS
		smc->hw.fp.fifo.fifo_config_mode |=
			smc->mib.fddiESSSynchTxMode | SYNC_TRAFFIC_ON ;
#endif
	}
	else {
		smc->hw.fp.fifo.fifo_config_mode &=
			~(SEND_ASYNC_AS_SYNC|SYNC_TRAFFIC_ON) ;
	}

	/*
	 * split up the FIFO
	 */
	if (smc->hw.fp.fifo.fifo_config_mode & SYNC_TRAFFIC_ON) {
		if (smc->hw.fp.fifo.fifo_config_mode & SEND_ASYNC_AS_SYNC) {
			smc->hw.fp.fifo.tx_s_size = TX_LARGE_FIFO ;
			smc->hw.fp.fifo.tx_a0_size = TX_SMALL_FIFO ;
		}
		else {
			smc->hw.fp.fifo.tx_s_size = TX_MEDIUM_FIFO ;
			smc->hw.fp.fifo.tx_a0_size = TX_MEDIUM_FIFO ;
		}
	}
	else {
			smc->hw.fp.fifo.tx_s_size = 0 ;
			smc->hw.fp.fifo.tx_a0_size = TX_FIFO_SPACE ;
	}

	smc->hw.fp.fifo.rx1_fifo_start = smc->hw.fp.fifo.rbc_ram_start +
		RX_FIFO_OFF ;
	smc->hw.fp.fifo.tx_s_start = smc->hw.fp.fifo.rx1_fifo_start +
		smc->hw.fp.fifo.rx1_fifo_size ;
	smc->hw.fp.fifo.tx_a0_start = smc->hw.fp.fifo.tx_s_start +
		smc->hw.fp.fifo.tx_s_size ;
	smc->hw.fp.fifo.rx2_fifo_start = smc->hw.fp.fifo.tx_a0_start +
		smc->hw.fp.fifo.tx_a0_size ;

	DB_SMT("FIFO split: mode = %x\n",smc->hw.fp.fifo.fifo_config_mode,0) ;
	DB_SMT("rbc_ram_start =	%x	 rbc_ram_end = 	%x\n",
		smc->hw.fp.fifo.rbc_ram_start, smc->hw.fp.fifo.rbc_ram_end) ;
	DB_SMT("rx1_fifo_start = %x	 tx_s_start = 	%x\n",
		smc->hw.fp.fifo.rx1_fifo_start, smc->hw.fp.fifo.tx_s_start) ;
	DB_SMT("tx_a0_start =	%x	 rx2_fifo_start = 	%x\n",
		smc->hw.fp.fifo.tx_a0_start, smc->hw.fp.fifo.rx2_fifo_start) ;
}

void formac_reinit_tx(struct s_smc *smc)
{
	/*
	 * Split up the FIFO and reinitialize the MAC if synchronous
	 * bandwidth becomes available but no synchronous queue is
	 * configured.
	 */
	if (!smc->hw.fp.fifo.tx_s_size && smc->mib.a[PATH0].fddiPATHSbaPayload){
		(void)init_mac(smc,0) ;
	}
}

