28 static const char ID_sccs[] =
"@(#)fplustm.c 1.32 99/02/23 (C) SK " ;
33 #define UNUSED(x) (x) = (x)
39 #define FM_ADDRX (FM_ADDET|FM_EXGPA0|FM_EXGPA1)
40 #define MS2BCLK(x) ((x)*12500L)
41 #define US2BCLK(x) ((x)*1250L)
46 static void build_claim_beacon(
struct s_smc *
smc,
u_long t_request);
47 static int init_mac(
struct s_smc *
smc,
int all);
48 static void rtm_init(
struct s_smc *
smc);
49 static void smt_split_up_fifo(
struct s_smc *
smc);
51 #if (!defined(NO_SMT_PANIC) || defined(DEBUG))
52 static char write_mdr_warning [] =
"E350 write_mdr() FM_SNPPND is set\n";
53 static char cam_warning [] =
"E_SMT_004: CAM still busy\n";
56 #define DUMMY_READ() smc->hw.mc_dummy = (u_short) inp(ADDR(B0_RAP))
58 #define CHECK_NPP() { unsigned k = 10000 ;\
59 while ((inpw(FM_A(FM_STMCHN)) & FM_SNPPND) && k) k--;\
61 SMT_PANIC(smc,SMT_E0130, SMT_E0130_MSG) ; \
65 #define CHECK_CAM() { unsigned k = 10 ;\
66 while (!(inpw(FM_A(FM_AFSTAT)) & FM_DONE) && k) k--;\
68 SMT_PANIC(smc,SMT_E0131, SMT_E0131_MSG) ; \
74 static const struct fddi_addr dbeacon_multi = {{0x01,0x80,0xc2,0x00,0x01,0x00}};
76 static const u_short my_said = 0xffff ;
77 static const u_short my_sagp = 0xffff ;
83 #define MA smc->hw.fddi_canon_addr
85 #define MA smc->hw.fddi_home_addr
121 smc->
mib.m[
MAC0].fddiMACFrame_Ct =
122 (smc->
mib.m[
MAC0].fddiMACFrame_Ct & 0xffff0000
L)
124 smc->
mib.m[
MAC0].fddiMACLost_Ct =
125 (smc->
mib.m[
MAC0].fddiMACLost_Ct & 0xffff0000
L)
127 smc->
mib.m[
MAC0].fddiMACError_Ct =
128 (smc->
mib.m[
MAC0].fddiMACError_Ct & 0xffff0000
L)
130 smc->
mib.m[
MAC0].fddiMACT_Neg = mac_get_tneg(smc) ;
131 #ifdef SMT_REAL_TOKEN_CT
173 static void init_ram(
struct s_smc *smc)
177 smc->
hw.fp.fifo.rbc_ram_start = 0 ;
178 smc->
hw.fp.fifo.rbc_ram_end =
181 MARW(smc->
hw.fp.fifo.rbc_ram_start) ;
182 for (i = smc->
hw.fp.fifo.rbc_ram_start;
183 i < (
u_short) (smc->
hw.fp.fifo.rbc_ram_end-1); i++)
192 static void set_recvptr(
struct s_smc *smc)
205 if (smc->
hw.fp.fifo.rx2_fifo_size) {
222 static void set_txptr(
struct s_smc *smc)
237 if (smc->
hw.fp.fifo.tx_s_size) {
254 static void init_rbc(
struct s_smc *smc)
261 rbc_ram_addr = smc->
hw.fp.fifo.rx2_fifo_start - 1 ;
275 static void init_rx(
struct s_smc *smc)
299 outpw(FM_A(
FM_TSYNC),(
unsigned int) (((-sync_bw) >> 5) & 0xffff) ) ;
305 static void init_tx(
struct s_smc *smc)
331 static void mac_counter_init(
struct s_smc *smc)
345 ec = (
u_long *)&smc->
hw.fp.err_stats ;
346 for (i = (
sizeof(
struct err_st)/
sizeof(
long)) ;
i ; i--)
348 smc->
mib.m[
MAC0].fddiMACRingOp_Ct = 0 ;
354 static void set_formac_addr(
struct s_smc *smc)
356 long t_requ = smc->
mib.m[
MAC0].fddiMACT_Req ;
360 smc->
hw.fddi_home_addr.a[5])) ;
362 smc->
hw.fddi_home_addr.a[3])) ;
364 smc->
hw.fddi_home_addr.a[1])) ;
369 smc->
hw.fp.group_addr.a[5])) ;
371 smc->
hw.fp.group_addr.a[3])) ;
373 smc->
hw.fp.group_addr.a[1])) ;
380 static void set_int(
char *p,
int l)
382 p[0] = (
char)(l >> 24) ;
383 p[1] = (
char)(l >> 16) ;
384 p[2] = (
char)(l >> 8) ;
385 p[3] = (
char)(l >> 0) ;
397 unsigned off,
int len)
410 for (i = (len + 3)/4 ;
i ; i--) {
445 static void directed_beacon(
struct s_smc *smc)
456 memcpy((
char *)
a+1,(
char *) &smc->
mib.m[
MAC0].fddiMACUpstreamNbr,6) ;
474 static void build_claim_beacon(
struct s_smc *smc,
u_long t_request)
478 struct fddi_mac_sf *
mac ;
485 mac = &smc->
hw.fp.mac_sfb ;
488 mac->mac_source = mac->mac_dest =
MA ;
490 set_int((
char *)mac->mac_info,(
int)t_request) ;
492 copy_tx_mac(smc,td,(
struct fddi_mac *)mac,
503 mac->mac_source =
MA ;
505 set_int((
char *) mac->mac_info,((
int)
BEACON_INFO<<24) + 0 ) ;
507 copy_tx_mac(smc,td,(
struct fddi_mac *)mac,
519 mac->mac_source =
MA ;
520 mac->mac_dest = dbeacon_multi ;
521 set_int((
char *) mac->mac_info,((
int)
DBEACON_INFO<<24) + 0 ) ;
522 set_int((
char *) mac->mac_info+4,0) ;
523 set_int((
char *) mac->mac_info+8,0) ;
525 copy_tx_mac(smc,td,(
struct fddi_mac *)mac,
535 static void formac_rcv_restart(
struct s_smc *smc)
549 static void enable_formac(
struct s_smc *smc)
640 static void disable_formac(
struct s_smc *smc)
652 static void mac_ring_up(
struct s_smc *smc,
int up)
655 formac_rcv_restart(smc) ;
656 smc->
hw.mac_ring_is_up =
TRUE ;
666 smc->
hw.mac_ring_is_up =
FALSE ;
697 change_s2l = smc->
hw.fp.s2l ^ code_s2l ;
698 change_s2u = smc->
hw.fp.s2u ^ code_s2u ;
701 (!smc->
hw.mac_ring_is_up && ((code_s2l & FM_SRNGOP)))) {
702 if (code_s2l & FM_SRNGOP) {
705 smc->
mib.m[
MAC0].fddiMACRingOp_Ct++ ;
714 smc->
mib.m[
MAC0].fddiMACNotCopied_Ct++ ;
718 smc->
hw.mac_ct.mac_r_restart_counter++ ;
728 DB_RMTN(2,
"RMT : lower claim received\n",0,0) ;
737 if (code_s2l & FM_SDUPCLM) {
748 DB_RMTN(2,
"RMT : higher claim received\n",0,0) ;
763 smc->
hw.fp.err_stats.err_bec_stat++ ;
765 smc->
hw.fp.err_stats.err_clm_stat++ ;
767 smc->
mib.m[
MAC0].fddiMACTvxExpired_Ct++ ;
768 if ((code_s2u & (FM_SBEC|FM_SCLM))) {
769 if (!(change_s2l & FM_SRNGOP) && (smc->
hw.fp.s2l & FM_SRNGOP)) {
775 smc->
mib.m[
MAC0].fddiMACRingOp_Ct++ ;
779 smc->
hw.fp.err_stats.err_phinv++ ;
781 smc->
hw.fp.err_stats.err_sifg_det++ ;
783 smc->
hw.fp.err_stats.err_tkiss++ ;
785 smc->
hw.fp.err_stats.err_tkerr++ ;
787 smc->
mib.m[
MAC0].fddiMACFrame_Ct += 0x10000
L ;
789 smc->
mib.m[
MAC0].fddiMACError_Ct += 0x10000
L ;
791 smc->
mib.m[
MAC0].fddiMACLost_Ct += 0x10000
L ;
797 smc->
hw.fp.s2l = code_s2l ;
798 smc->
hw.fp.s2u = code_s2u ;
811 smc->
hw.mac_ct.mac_r_restart_counter++ ;
828 static void formac_offline(
struct s_smc *smc)
838 disable_formac(smc) ;
839 smc->
hw.mac_ring_is_up =
FALSE ;
846 static void formac_online(
struct s_smc *smc)
861 smc->
hw.fp.func_addr = 0 ;
862 smc->
hw.fp.frselreg_init = 0 ;
868 smc->
hw.mac_ct.mac_nobuf_counter = 0 ;
869 smc->
hw.mac_ct.mac_r_restart_counter = 0 ;
878 smc->
hw.fp.s2l = smc->
hw.fp.s2u = 0 ;
879 smc->
hw.mac_ring_is_up = 0 ;
881 mac_counter_init(smc) ;
888 mac_do_pci_fix(smc) ;
890 return init_mac(smc, 1);
894 static int init_mac(
struct s_smc *smc,
int all)
903 set_formac_addr(smc) ;
916 time = hwt_quick_read(smc) ;
922 smt_split_up_fifo(smc) ;
928 build_claim_beacon(smc,smc->
mib.m[
MAC0].fddiMACT_Req) ;
949 if ((t_max == 0xfffe) || (t_max - x == 0x16))
974 hwt_wait_time(smc,time,
MS2BCLK(10)) ;
982 if (!smc->
hw.hw_is_64bit) {
990 smc->
hw.hw_state = STARTED ;
1018 formac_rcv_restart(smc) ;
1031 formac_offline(smc) ;
1034 (
void)init_mac(smc,0) ;
1037 formac_online(smc) ;
1040 directed_beacon(smc) ;
1059 static struct s_fpmc* mac_get_mc_table(
struct s_smc *smc,
1065 struct s_fpmc *
slot ;
1075 for (i = 0 ; i < 6 ; i++, p++)
1085 if (
memcmp((
char *)&tb->a,(
char *)own,6))
1108 smc->
hw.fp.os_slots_used = 0 ;
1167 if (!(tb = mac_get_mc_table(smc,addr,&own,0,can & ~0x80)))
1171 tb->perm = (can & 0x80) ? 1 : 0 ;
1174 smc->
hw.fp.smt_slots_used++ ;
1176 smc->
hw.fp.os_slots_used++ ;
1185 #define RX_MODE_PROM 0x1
1186 #define RX_MODE_ALL_MULTI 0x2
1213 if (smc->
hw.fp.func_addr) {
1214 fu = (
u_char *) &smc->
hw.fp.func_addr ;
1241 (
u_short)((tb->a.a[0]<<8)+tb->a.a[1])) ;
1243 (
u_short)((tb->a.a[2]<<8)+tb->a.a[3])) ;
1245 (
u_short)((tb->a.a[4]<<8)+tb->a.a[5])) ;
1292 smc->
hw.fp.rx_mode = (smc->
hw.fp.rx_mode & ~
FM_ADDET) |
1293 smc->
hw.fp.nsa_mode ;
1297 smc->
hw.fp.rx_mode = (smc->
hw.fp.rx_mode & ~
FM_ADDET) |
1298 smc->
hw.fp.nsa_mode ;
1308 smc->
hw.fp.rx_mode = smc->
hw.fp.nsa_mode ;
1334 if (
inpw(
ADDR(B2_RTM_CRTL)) & TIM_RES_TOK) {
1336 DB_RMT(
"RMT: fddiPATHT_Rmode expired\n",0,0) ;
1339 (
u_long) FDDI_RTT, smt_get_event_word(smc));
1344 static void rtm_init(
struct s_smc *smc)
1355 DB_RMT(
"RMT: setting new fddiPATHT_Rmode, t = %d ns\n",
1356 (
int) smc->
mib.a[
PATH0].fddiPATHT_Rmode,0) ;
1357 outpd(
ADDR(B2_RTM_INI),smc->
mib.a[PATH0].fddiPATHT_Rmode) ;
1360 static void smt_split_up_fifo(
struct s_smc *smc)
1395 smc->
hw.fp.fifo.rx2_fifo_size = 0 ;
1433 if (smc->
mib.a[
PATH0].fddiPATHSbaPayload) {
1435 smc->
hw.fp.fifo.fifo_config_mode |=
1440 smc->
hw.fp.fifo.fifo_config_mode &=
1458 smc->
hw.fp.fifo.tx_s_size = 0 ;
1462 smc->
hw.fp.fifo.rx1_fifo_start = smc->
hw.fp.fifo.rbc_ram_start +
1464 smc->
hw.fp.fifo.tx_s_start = smc->
hw.fp.fifo.rx1_fifo_start +
1465 smc->
hw.fp.fifo.rx1_fifo_size ;
1466 smc->
hw.fp.fifo.tx_a0_start = smc->
hw.fp.fifo.tx_s_start +
1467 smc->
hw.fp.fifo.tx_s_size ;
1468 smc->
hw.fp.fifo.rx2_fifo_start = smc->
hw.fp.fifo.tx_a0_start +
1469 smc->
hw.fp.fifo.tx_a0_size ;
1471 DB_SMT(
"FIFO split: mode = %x\n",smc->
hw.fp.fifo.fifo_config_mode,0) ;
1472 DB_SMT(
"rbc_ram_start = %x rbc_ram_end = %x\n",
1473 smc->
hw.fp.fifo.rbc_ram_start, smc->
hw.fp.fifo.rbc_ram_end) ;
1474 DB_SMT(
"rx1_fifo_start = %x tx_s_start = %x\n",
1475 smc->
hw.fp.fifo.rx1_fifo_start, smc->
hw.fp.fifo.tx_s_start) ;
1476 DB_SMT(
"tx_a0_start = %x rx2_fifo_start = %x\n",
1477 smc->
hw.fp.fifo.tx_a0_start, smc->
hw.fp.fifo.rx2_fifo_start) ;
1487 if (!smc->
hw.fp.fifo.tx_s_size && smc->
mib.a[
PATH0].fddiPATHSbaPayload){
1488 (
void)init_mac(smc,0) ;