diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-07-31 09:06:29 +0200 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-08-27 09:58:13 +0200 |
commit | 33f810b2036f13f1b123062a9e5c1794d400ce81 (patch) | |
tree | 370b55026f4bd856e96842f86af631ca2bab3da2 /drivers/net/skfp/fplustm.c | |
parent | Merge branch 'davem-next.mii' of git://git.kernel.org/pub/scm/linux/kernel/gi... (diff) | |
download | linux-33f810b2036f13f1b123062a9e5c1794d400ce81.tar.xz linux-33f810b2036f13f1b123062a9e5c1794d400ce81.zip |
fddi: Move the FDDI drivers
Move the FDDI drivers into drivers/net/fddi/ and make the
necessary Kconfig and Makefile changes.
CC: "Maciej W. Rozycki" <macro@linux-mips.org>
CC: Christoph Goos <cgoos@syskonnect.de>
CC: <linux@syskonnect.de>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/skfp/fplustm.c')
-rw-r--r-- | drivers/net/skfp/fplustm.c | 1491 |
1 files changed, 0 insertions, 1491 deletions
diff --git a/drivers/net/skfp/fplustm.c b/drivers/net/skfp/fplustm.c deleted file mode 100644 index a20ed1a98099..000000000000 --- a/drivers/net/skfp/fplustm.c +++ /dev/null @@ -1,1491 +0,0 @@ -/****************************************************************************** - * - * (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 <linux/bitrev.h> - -#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 const int mac_imsk1u = FM_STXABRS | FM_STXABRA0 | FM_SXMTABT ; -static const int mac_imsk1l = FM_SQLCKS | FM_SQLCKA0 | FM_SPCEPDS | FM_SPCEPDA0| - FM_STBURS | FM_STBURA0 ; - - /* delete FM_SRBFL after tests */ -static const int mac_imsk2u = FM_SERRSF | FM_SNFSLD | FM_SRCVOVR | FM_SRBFL | - FM_SMYCLM ; -static const int mac_imsk2l = FM_STRTEXR | FM_SDUPCLM | FM_SFRMCTR | - FM_SERRCTR | FM_SLSTCTR | - FM_STRTEXP | FM_SMULTDA | FM_SRNGOP ; - -static const int mac_imsk3u = FM_SRCVOVR2 | FM_SRBFL2 ; -static const int mac_imsk3l = FM_SRPERRQ2 | FM_SRPERRQ1 ; - -static const 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 structure - */ - 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 ; length of the frame including the FC */ -{ - int i ; - __le32 *p ; - - CHECK_NPP() ; - MARW(off) ; /* set memory address reg for writes */ - - p = (__le32 *) 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,le32_to_cpu(*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(__le32,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,le32_to_cpu(a[0])) ; - outpw(FM_A(FM_CMDREG2),FM_ISTTB) ; /* set the tag bit */ - write_mdr(smc,le32_to_cpu(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),(unsigned short)~mac_imsk1u); - outpw(FM_A(FM_IMSK1L),(unsigned short)~mac_imsk1l); - outpw(FM_A(FM_IMSK2U),(unsigned short)~mac_imsk2u); - outpw(FM_A(FM_IMSK2L),(unsigned short)~mac_imsk2l); - outpw(FM_A(FM_IMSK3U),(unsigned short)~mac_imsk3u); - outpw(FM_A(FM_IMSK3L),(unsigned short)~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 = bitrev8(*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_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; -} - -/* - * 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 promiscuous - 4 RX_DISABLE_PROMISC disable promiscuous - 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) ; - } -} - |