18 static char const ID_sccs[] =
"@(#)hwmtm.c 1.40 99/05/31 (C) SK" ;
49 static SMbuf *mb_start = 0 ;
50 static SMbuf *mb_free = 0 ;
51 static int mb_init =
FALSE ;
52 static int call_count = 0 ;
63 extern struct smt_debug
debug ;
69 extern u_char force_irq_pending ;
80 static void init_txd_ring(
struct s_smc *
smc);
81 static void init_rxd_ring(
struct s_smc *
smc);
89 static void mac_drv_clear_txd(
struct s_smc *
smc);
105 int frag_count,
int len);
113 extern void hwm_cpy_rxd2mb(
void);
114 extern void hwm_cpy_txd2mb(
void);
117 #ifdef ALL_RX_COMPLETE
118 extern void mac_drv_all_receives_complete(
void);
125 extern void post_proc(
void);
161 void mac_drv_debug_lev(
void);
171 #define UNUSED(x) (x) = (x)
178 #define MA smc->hw.fddi_canon_addr.a
179 #define GROUP_ADDR_BIT 0x01
181 #define MA smc->hw.fddi_home_addr.a
182 #define GROUP_ADDR_BIT 0x80
185 #define RXD_TXD_COUNT (HWM_ASYNC_TXD_COUNT+HWM_SYNC_TXD_COUNT+\
186 SMT_R1_RXD_COUNT+SMT_R2_RXD_COUNT)
188 #ifdef MB_OUTSIDE_SMC
189 #define EXT_VIRT_MEM ((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd) +\
190 MAX_MBUF*sizeof(SMbuf))
191 #define EXT_VIRT_MEM_2 ((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd))
193 #define EXT_VIRT_MEM ((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd))
199 #if defined(NDIS_OS2) || defined(ODI2)
200 #define CR_READ(var) ((var) & 0xffff0000 | ((var) & 0xffff))
202 #define CR_READ(var) (__le32)(var)
205 #define IMASK_SLOW (IS_PLINT1 | IS_PLINT2 | IS_TIMINT | IS_TOKEN | \
206 IS_MINTR1 | IS_MINTR2 | IS_MINTR3 | IS_R1_P | \
207 IS_R1_C | IS_XA_C | IS_XS_C)
231 #ifdef MB_OUTSIDE_SMC
232 #ifdef COMMON_MB_POOL
234 if (call_count == 1) {
238 return EXT_VIRT_MEM_2;
271 if (!(smc->
os.hwm.descr_p = (
union s_fp_descr volatile *)
280 #ifndef MB_OUTSIDE_SMC
281 smc->
os.hwm.mbuf_pool.mb_start=(
SMbuf *)(&smc->
os.hwm.mbuf_pool.mb[0]) ;
283 #ifndef COMMON_MB_POOL
333 DB_GEN(
"descr ring starts at = %x ",(
void *)start,0,3) ;
334 for (i=count-1, d1=start;
i ; i--) {
338 d2->
r.rxd_next = &d1->
r ;
342 DB_GEN(
"descr ring ends at = %x ",(
void *)d1,0,3) ;
344 d1->
r.rxd_next = &start->
r ;
348 for (i=count, d1=start;
i ; i--) {
355 static void init_txd_ring(
struct s_smc *smc)
364 ds = (
struct s_smt_fp_txd volatile *) ((
char *)smc->
os.hwm.descr_p +
392 static void init_rxd_ring(
struct s_smc *smc)
433 #ifndef COMMON_MB_POOL
434 mb = smc->
os.hwm.mbuf_pool.mb_start ;
437 mb->sm_use_count = 1 ;
446 mb->sm_use_count = 1 ;
457 smc->
os.hwm.llc_rx_pipe = smc->
os.hwm.llc_rx_tail = (
SMbuf *)
NULL ;
458 smc->
os.hwm.txd_tx_pipe = smc->
os.hwm.txd_tx_tail =
NULL ;
459 smc->
os.hwm.pass_SMT = smc->
os.hwm.pass_NSA = smc->
os.hwm.pass_DB = 0 ;
460 smc->
os.hwm.pass_llc_promisc =
TRUE ;
461 smc->
os.hwm.queued_rx_frames = smc->
os.hwm.queued_txd_mb = 0 ;
462 smc->
os.hwm.detec_count = 0 ;
463 smc->
os.hwm.rx_break = 0 ;
464 smc->
os.hwm.rx_len_error = 0 ;
470 i = 16 - ((
long)smc->
os.hwm.descr_p & 0xf) ;
474 ((
char *)smc->
os.hwm.descr_p+
i) ;
476 DB_GEN(
"pt to descr area = %x",(
void *)smc->
os.hwm.descr_p,0,3) ;
490 #ifndef COMMON_MB_POOL
491 mb = smc->
os.hwm.mbuf_pool.mb_free ;
496 #ifndef COMMON_MB_POOL
497 smc->
os.hwm.mbuf_pool.mb_free = mb->
sm_next ;
502 mb->sm_use_count = 1 ;
504 DB_GEN(
"get SMbuf: mb = %x",(
void *)mb,0,3) ;
513 DB_GEN(
"free_mbuf: sm_use_count = %d",mb->sm_use_count,0,3) ;
519 if (!mb->sm_use_count) {
520 DB_GEN(
"free SMbuf: mb = %x",(
void *)mb,0,3) ;
521 #ifndef COMMON_MB_POOL
522 mb->
sm_next = smc->
os.hwm.mbuf_pool.mb_free ;
523 smc->
os.hwm.mbuf_pool.mb_free =
mb ;
567 phys = repair_txd_ring(smc,smc->
hw.fp.tx[
QUEUE_A0]) ;
572 phys = repair_txd_ring(smc,smc->
hw.fp.tx[
QUEUE_S]) ;
581 phys = repair_rxd_ring(smc,smc->
hw.fp.rx[
QUEUE_R1]) ;
598 for (i = tx_used+queue->
tx_free-1 ; i ; i-- ) {
720 if (smc->
os.hwm.rx_break) {
723 smc->
os.hwm.rx_break = 0 ;
727 smc->
os.hwm.detec_count = 0 ;
732 smc->
os.hwm.isr_flag =
TRUE ;
736 if (smc->
os.hwm.leave_isr) {
737 smc->
os.hwm.leave_isr =
FALSE ;
742 while ((is = GET_ISR() &
ISR_MASK)) {
743 NDD_TRACE(
"CH0B",is,0,0) ;
744 DB_GEN(
"ISA = 0x%x",is,0,7) ;
747 NDD_TRACE(
"CH1b",is,0,0) ;
748 if (is & IS_PLINT1) {
751 if (is & IS_PLINT2) {
754 if (is & IS_MINTR1) {
757 DB_GEN(
"Slow transmit complete",0,0,6) ;
760 if (is & IS_MINTR2) {
763 DB_GEN(
"Slow receive complete",0,0,6) ;
764 DB_GEN(
"stl = %x : stu = %x",stl,stu,7) ;
767 if (is & IS_MINTR3) {
770 DB_GEN(
"FORMAC Mode Register 3",0,0,6) ;
776 force_irq_pending = 0 ;
781 if (++smc->
os.hwm.detec_count > 4) {
816 if (is & (IS_XS_F|IS_XA_F)) {
817 DB_GEN(
"Fast tx complete queue",0,0,6) ;
824 mac_drv_clear_txd(smc) ;
832 DB_GEN(
"Fast receive complete",0,0,6) ;
834 #ifndef USE_BREAK_ISR
839 if (smc->
os.hwm.leave_isr) {
849 while ((mb = get_llc_rx(smc))) {
856 while (!offDepth && (mb = get_llc_rx(smc))) {
860 if (!offDepth && smc->
os.hwm.rx_break) {
864 if (smc->
q.ev_get != smc->
q.ev_put) {
865 NDD_TRACE(
"CH2a",0,0,0) ;
875 if (smc->
os.hwm.leave_isr) {
884 if (smc->
os.hwm.leave_isr && force_irq) {
889 NDD_TRACE(
"CH0E",0,0,0) ;
996 smc->
os.hwm.pass_SMT =
TRUE ;
1002 smc->
os.hwm.pass_NSA =
TRUE ;
1005 smc->
os.hwm.pass_NSA =
FALSE ;
1008 smc->
os.hwm.pass_DB =
TRUE ;
1014 smc->
os.hwm.pass_SMT = smc->
os.hwm.pass_NSA =
FALSE ;
1016 smc->
os.hwm.pass_llc_promisc =
TRUE ;
1020 smc->
os.hwm.pass_llc_promisc =
FALSE ;
1023 smc->
os.hwm.pass_llc_promisc =
TRUE ;
1059 smc->
os.hwm.detec_count = 0 ;
1061 NDD_TRACE(
"RHxB",0,0,0) ;
1067 #ifdef USE_BREAK_ISR
1068 if (smc->
os.hwm.leave_isr) {
1074 smc->
os.hwm.rx_break = 1 ;
1077 smc->
os.hwm.rx_break = 0 ;
1080 if (smc->
os.hwm.rx_break) {
1086 DB_RX(
"Check RxD %x for OWN and EOF",(
void *)r,0,5) ;
1091 NDD_TRACE(
"RHxE",r,rfsw,rbctrl) ;
1092 DB_RX(
"End of RxDs",0,0,4) ;
1106 smc->
hw.hw_state = STARTED ;
1108 smc->
os.hwm.detec_count = 0 ;
1112 if ((rbctrl &
BMU_STF) != ((rbctrl & BMU_ST_BUF) <<5)) {
1133 n += rbctrl & 0xffff ;
1137 }
while (!(rbctrl &
BMU_EOF)) ;
1138 used_frags = frag_count ;
1139 DB_RX(
"EOF set in RxD, used_frags = %d ",used_frags,0,5) ;
1145 DB_RX(
"Check STF bit in %x",(
void *)r,0,5) ;
1151 DB_RX(
"STF bit found",0,0,5) ;
1158 queue->
rx_free += frag_count ;
1166 for (r=rxd, i=frag_count ;
i ; r=r->
rxd_next, i--){
1167 DB_RX(
"dma_complete for RxD %x",(
void *)r,0,5) ;
1170 smc->
hw.fp.err_stats.err_valid++ ;
1171 smc->
mib.m[
MAC0].fddiMACCopied_Ct++ ;
1176 DB_RX(
"frame length = %d",len,0,4) ;
1182 DB_RX(
"Frame aborted by the FORMAC",0,0,2) ;
1183 smc->
hw.fp.err_stats.err_abort++ ;
1189 DB_RX(
"E-Indicator set",0,0,2) ;
1190 smc->
hw.fp.err_stats.err_e_indicator++ ;
1193 DB_RX(
"CRC error",0,0,2) ;
1194 smc->
hw.fp.err_stats.err_crc++ ;
1197 DB_RX(
"Implementer frame",0,0,2) ;
1198 smc->
hw.fp.err_stats.err_imp_frame++ ;
1203 DB_RX(
"Frame too long error",0,0,2) ;
1204 smc->
hw.fp.err_stats.err_too_long++ ;
1212 DB_RX(
"Frame length = 0",0,0,2) ;
1217 DB_RX(
"BMU: rx len differs: [%d:%d]",len,n,4);
1218 smc->
os.hwm.rx_len_error++ ;
1226 DB_RX(
"FC = %x",*virt,0,2) ;
1227 if (virt[12] ==
MA[5] &&
1228 virt[11] ==
MA[4] &&
1229 virt[10] ==
MA[3] &&
1245 if (!smc->
os.hwm.pass_llc_promisc) {
1247 if (virt[6] !=
MA[5] ||
1253 DB_RX(
"DA != MA and not multi- or broadcast",0,0,2) ;
1262 DB_RX(
"LLC - receive",0,0,4) ;
1267 smc->
hw.fp.err_stats.err_no_buf++ ;
1268 DB_RX(
"No SMbuf; receive terminated",0,0,4) ;
1271 data =
smtod(mb,
char *) - 1 ;
1277 hwm_cpy_rxd2mb(rxd,data,len) ;
1279 for (r=rxd, i=used_frags ;
i ; r=r->
rxd_next, i--){
1281 DB_RX(
"cp SMT frame to mb: len = %d",n,0,6) ;
1285 data =
smtod(mb,
char *) - 1 ;
1287 fc = *(
char *)mb->
sm_data = *data ;
1296 smc->
hw.fp.err_stats.err_smt_frame++ ;
1297 DB_RX(
"SMT frame received ",0,0,5) ;
1299 if (smc->
os.hwm.pass_SMT) {
1300 DB_RX(
"pass SMT frame ",0,0,5) ;
1305 DB_RX(
"requeue RxD",0,0,5) ;
1312 smc->
hw.fp.err_stats.err_smt_frame++ ;
1313 DB_RX(
"SMT frame received ",0,0,5) ;
1318 if (smc->
os.hwm.pass_NSA ||
1319 (smc->
os.hwm.pass_SMT &&
1321 DB_RX(
"pass SMT frame ",0,0,5) ;
1326 DB_RX(
"requeue RxD",0,0,5) ;
1333 if (smc->
os.hwm.pass_DB) {
1334 DB_RX(
"pass DB frame ",0,0,5) ;
1339 DB_RX(
"requeue RxD",0,0,5) ;
1348 DB_RX(
"unknown FC error",0,0,2) ;
1350 DB_RX(
"requeue RxD",0,0,5) ;
1352 if ((fc & 0xf0) ==
FC_MAC)
1353 smc->
hw.fp.err_stats.err_mac_frame++ ;
1355 smc->
hw.fp.err_stats.err_imp_frame++ ;
1367 DB_RX(
"requeue RxD",0,0,5) ;
1374 #ifdef ALL_RX_COMPLETE
1375 mac_drv_all_receives_complete(smc) ;
1384 DB_RX(
"send a queued frame to the llc layer",0,0,4) ;
1386 smc->
os.hwm.r.mb_pos =
smtod(mb,
char *) ;
1387 fc = *smc->
os.hwm.r.mb_pos ;
1389 smc->
os.hwm.r.mb_pos,(
int)mb->
sm_len) ;
1421 NDD_TRACE(
"RHfB",virt,len,frame_status) ;
1422 DB_RX(
"hwm_rx_frag: len = %d, frame_status = %x\n",len,frame_status,2) ;
1478 DB_RX(
"clear_rx_queue",0,0,5) ;
1486 DB_RX(
"switch OWN bit of RxD 0x%x ",r,0,5) ;
1494 DB_RX(
"Check STF bit in %x",(
void *)r,0,5) ;
1501 DB_RX(
"STF bit found",0,0,5) ;
1505 DB_RX(
"dma_complete for RxD %x",(
void *)r,0,5) ;
1509 DB_RX(
"mac_drv_clear_rxd: RxD %x frag_count %d ",
1514 queue->
rx_used -= frag_count ;
1515 queue->
rx_free += frag_count ;
1553 NDD_TRACE(
"THiB",fc,frag_count,frame_len) ;
1554 smc->
os.hwm.tx_p = smc->
hw.fp.tx[frame_status &
QUEUE_A0] ;
1556 smc->
os.hwm.tx_len = frame_len ;
1557 DB_TX(
"hwm_tx_init: fc = %x, len = %d",fc,frame_len,3) ;
1577 if (!smc->
hw.mac_ring_is_up) {
1578 frame_status &= ~
LAN_TX ;
1580 DB_TX(
"Ring is down: terminate LAN_TX",0,0,2) ;
1582 if (frag_count > smc->
os.hwm.tx_p->tx_free) {
1584 mac_drv_clear_txd(smc) ;
1585 if (frag_count > smc->
os.hwm.tx_p->tx_free) {
1586 DB_TX(
"Out of TxDs, terminate LAN_TX",0,0,2) ;
1587 frame_status &= ~
LAN_TX ;
1591 DB_TX(
"Out of TxDs, terminate LAN_TX",0,0,2) ;
1592 frame_status &= ~
LAN_TX ;
1596 DB_TX(
"frame_status = %x",frame_status,0,3) ;
1597 NDD_TRACE(
"THiE",frame_status,smc->
os.hwm.tx_p->tx_free,0) ;
1635 queue = smc->
os.hwm.tx_p ;
1637 NDD_TRACE(
"THfB",virt,len,frame_status) ;
1645 DB_TX(
"hwm_tx_frag: len = %d, frame_status = %x ",len,frame_status,2) ;
1646 if (frame_status &
LAN_TX) {
1648 DB_TX(
"LAN_TX: TxD = %x, virt = %x ",t,virt,3) ;
1673 smc->
mib.m[
MAC0].fddiMACTransmit_Ct++ ;
1676 if (frame_status &
LOC_TX) {
1677 DB_TX(
"LOC_TX: ",0,0,3) ;
1680 smc->
hw.fp.err_stats.err_no_buf++ ;
1681 DB_TX(
"No SMbuf; transmit terminated",0,0,4) ;
1684 smc->
os.hwm.tx_data =
1685 smtod(smc->
os.hwm.tx_mb,
char *) - 1 ;
1687 #ifdef PASS_1ST_TXD_2_TX_COMP
1688 hwm_cpy_txd2mb(t,smc->
os.hwm.tx_data,
1689 smc->
os.hwm.tx_len) ;
1694 if (smc->
os.hwm.tx_mb) {
1696 DB_TX(
"copy fragment into MBuf ",0,0,3) ;
1697 memcpy(smc->
os.hwm.tx_data,virt,len) ;
1698 smc->
os.hwm.tx_data += len ;
1702 #ifndef PASS_1ST_TXD_2_TX_COMP
1710 hwm_cpy_txd2mb(t,smc->
os.hwm.tx_data,
1711 smc->
os.hwm.tx_len) ;
1714 smc->
os.hwm.tx_data =
1715 smtod(smc->
os.hwm.tx_mb,
char *) - 1 ;
1716 *(
char *)smc->
os.hwm.tx_mb->sm_data =
1717 *smc->
os.hwm.tx_data ;
1718 smc->
os.hwm.tx_data++ ;
1719 smc->
os.hwm.tx_mb->sm_len =
1720 smc->
os.hwm.tx_len - 1 ;
1721 DB_TX(
"pass LLC frame to SMT ",0,0,3) ;
1727 NDD_TRACE(
"THfE",t,queue->
tx_free,0) ;
1734 static void queue_llc_rx(
struct s_smc *smc,
SMbuf *mb)
1736 DB_GEN(
"queue_llc_rx: mb = %x",(
void *)mb,0,4) ;
1737 smc->
os.hwm.queued_rx_frames++ ;
1739 if (smc->
os.hwm.llc_rx_pipe ==
NULL) {
1740 smc->
os.hwm.llc_rx_pipe =
mb ;
1743 smc->
os.hwm.llc_rx_tail->sm_next =
mb ;
1745 smc->
os.hwm.llc_rx_tail =
mb ;
1750 if (!smc->
os.hwm.isr_flag) {
1762 if ((mb = smc->
os.hwm.llc_rx_pipe)) {
1763 smc->
os.hwm.queued_rx_frames-- ;
1766 DB_GEN(
"get_llc_rx: mb = 0x%x",(
void *)mb,0,4) ;
1774 static void queue_txd_mb(
struct s_smc *smc,
SMbuf *mb)
1776 DB_GEN(
"_rx: queue_txd_mb = %x",(
void *)mb,0,4) ;
1777 smc->
os.hwm.queued_txd_mb++ ;
1779 if (smc->
os.hwm.txd_tx_pipe ==
NULL) {
1780 smc->
os.hwm.txd_tx_pipe =
mb ;
1783 smc->
os.hwm.txd_tx_tail->sm_next =
mb ;
1785 smc->
os.hwm.txd_tx_tail =
mb ;
1795 if ((mb = smc->
os.hwm.txd_tx_pipe)) {
1796 smc->
os.hwm.queued_txd_mb-- ;
1799 DB_GEN(
"get_txd_mb: mb = 0x%x",(
void *)mb,0,4) ;
1821 NDD_TRACE(
"THSB",mb,fc,0) ;
1822 DB_TX(
"smt_send_mbuf: mb = 0x%x, fc = 0x%x",mb,fc,4) ;
1826 data =
smtod(mb,
char *) ;
1841 DB_TX(
"frag: virt/len = 0x%x/%d ",(
void *)data,n,5) ;
1842 virt[frag_count] =
data ;
1843 frag_len[frag_count] =
n ;
1863 if (!smc->
hw.mac_ring_is_up || frag_count > queue->
tx_free) {
1866 DB_TX(
"Ring is down: terminate LAN_TX",0,0,2) ;
1869 DB_TX(
"Ring is down: terminate transmission",0,0,2) ;
1874 DB_TX(
"frame_status = 0x%x ",frame_status,0,5) ;
1876 if ((frame_status &
LAN_TX) && (frame_status &
LOC_TX)) {
1877 mb->sm_use_count = 2 ;
1880 if (frame_status & LAN_TX) {
1883 for (i = 0; i < frag_count; i++) {
1884 DB_TX(
"init TxD = 0x%x",(
void *)t,0,5) ;
1885 if (i == frag_count-1) {
1910 smc->
mib.m[
MAC0].fddiMACTransmit_Ct++ ;
1911 queue_txd_mb(smc,mb) ;
1914 if (frame_status & LOC_TX) {
1915 DB_TX(
"pass Mbuf to LLC queue",0,0,5) ;
1916 queue_llc_rx(smc,mb) ;
1923 mac_drv_clear_txd(smc) ;
1924 NDD_TRACE(
"THSE",t,queue->
tx_free,frag_count) ;
1941 static void mac_drv_clear_txd(
struct s_smc *smc)
1952 NDD_TRACE(
"THcB",0,0,0) ;
1954 queue = smc->
hw.fp.tx[
i] ;
1956 DB_TX(
"clear_txd: QUEUE = %d (0=sync/1=async)",i,0,5) ;
1963 DB_TX(
"check OWN/EOF bit of TxD 0x%x",t1,0,5) ;
1967 DB_TX(
"End of TxDs queue %d",i,0,4) ;
1968 goto free_next_queue ;
1972 }
while (!(tbctrl &
BMU_EOF)) ;
1975 for (n = frag_count;
n; n--) {
1980 ((tbctrl & BMU_SMT_TX) >> 18))) ;
1985 if (tbctrl & BMU_SMT_TX) {
1986 mb = get_txd_mb(smc) ;
1990 #ifndef PASS_1ST_TXD_2_TX_COMP
1991 DB_TX(
"mac_drv_tx_comp for TxD 0x%x",t2,0,4) ;
1994 DB_TX(
"mac_drv_tx_comp for TxD 0x%x",
2000 queue->
tx_free += frag_count ;
2001 queue->
tx_used -= frag_count ;
2005 NDD_TRACE(
"THcE",0,0,0) ;
2045 queue = smc->
hw.fp.tx[
i] ;
2046 DB_TX(
"clear_tx_queue: QUEUE = %d (0=sync/1=async)",i,0,5) ;
2055 DB_TX(
"switch OWN bit of TxD 0x%x ",t,0,5) ;
2066 mac_drv_clear_txd(smc) ;
2069 queue = smc->
hw.fp.tx[
i] ;
2123 void mac_drv_debug_lev(
struct s_smc *smc,
int flag,
int lev)
2127 DB_P.d_smtf = DB_P.d_smt = DB_P.d_ecm = DB_P.d_rmt = 0 ;
2129 DB_P.d_os.hwm_rx = DB_P.d_os.hwm_tx = DB_P.d_os.hwm_gen = 0 ;
2166 DB_P.d_os.hwm_rx = lev ;
2169 DB_P.d_os.hwm_tx = lev ;
2172 DB_P.d_os.hwm_gen = lev ;