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