hwmtm.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:55k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * (C)Copyright 1998,1999 SysKonnect,
  4.  * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
  5.  *
  6.  * See the file "skfddi.c" for further information.
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * The information in this file is provided "AS IS" without warranty.
  14.  *
  15.  ******************************************************************************/
  16. #ifndef lint
  17. static char const ID_sccs[] = "@(#)hwmtm.c 1.40 99/05/31 (C) SK" ;
  18. #endif
  19. #define HWMTM
  20. #ifndef FDDI
  21. #define FDDI
  22. #endif
  23. #include "h/types.h"
  24. #include "h/fddi.h"
  25. #include "h/smc.h"
  26. #include "h/supern_2.h"
  27. #include "h/skfbiinc.h"
  28. /*
  29. -------------------------------------------------------------
  30. DOCUMENTATION
  31. -------------------------------------------------------------
  32. BEGIN_MANUAL_ENTRY(DOCUMENTATION)
  33. T B D
  34. END_MANUAL_ENTRY
  35. */
  36. /*
  37. -------------------------------------------------------------
  38. LOCAL VARIABLES:
  39. -------------------------------------------------------------
  40. */
  41. #ifdef COMMON_MB_POOL
  42. static SMbuf *mb_start = 0 ;
  43. static SMbuf *mb_free = 0 ;
  44. static int mb_init = FALSE ;
  45. static int call_count = 0 ;
  46. #endif
  47. /*
  48. -------------------------------------------------------------
  49. EXTERNE VARIABLES:
  50. -------------------------------------------------------------
  51. */
  52. #ifdef DEBUG
  53. #ifndef DEBUG_BRD
  54. extern struct smt_debug debug ;
  55. #endif
  56. #endif
  57. #ifdef NDIS_OS2
  58. extern u_char offDepth ;
  59. extern u_char force_irq_pending ;
  60. #endif
  61. /*
  62. -------------------------------------------------------------
  63. LOCAL FUNCTIONS:
  64. -------------------------------------------------------------
  65. */
  66. static void queue_llc_rx(), smt_to_llc(),
  67. init_txd_ring(), init_rxd_ring(),
  68. queue_txd_mb() ;
  69. static u_long init_descr_ring(), repair_txd_ring(),
  70. repair_rxd_ring() ;
  71. static SMbuf *get_llc_rx(), *get_txd_mb() ;
  72. /*
  73. -------------------------------------------------------------
  74. EXTERNAL FUNCTIONS:
  75. -------------------------------------------------------------
  76. */
  77. /* The external SMT functions are listed in cmtdef.h */
  78. extern void *mac_drv_get_space(), *mac_drv_get_desc_mem(),
  79. init_board(), mac_drv_fill_rxd(),
  80. plc1_irq(), mac_drv_tx_complete(),
  81. plc2_irq(), mac1_irq(),
  82. mac2_irq(), mac3_irq(),
  83. timer_irq(), mac_drv_rx_complete(),
  84. mac_drv_requeue_rxd(), init_plc(),
  85. mac_drv_clear_rxd(), llc_restart_tx(),
  86. ev_dispatcher(), smt_force_irq() ;
  87. #ifdef USE_OS_CPY
  88. extern void hwm_cpy_rxd2mb(), hwm_cpy_txd2mb() ;
  89. #endif
  90. #ifdef ALL_RX_COMPLETE
  91. extern void mac_drv_all_receives_complete() ;
  92. #endif
  93. extern u_long mac_drv_virt2phys(), dma_master() ;
  94. #ifdef NDIS_OS2
  95. extern void post_proc() ;
  96. #else
  97. extern void dma_complete() ;
  98. #endif
  99. extern int init_fplus(), mac_drv_rx_init() ;
  100. /*
  101. -------------------------------------------------------------
  102. PUBLIC FUNCTIONS:
  103. -------------------------------------------------------------
  104. */
  105. void process_receive(), smt_send_mbuf(),
  106. fddi_isr(), mac_drv_clear_txd(),
  107. smt_free_mbuf(), init_driver_fplus(),
  108. mac_drv_rx_mode(), init_fddi_driver(),
  109. mac_drv_clear_tx_queue(),
  110. mac_drv_clear_rx_queue(),
  111. hwm_tx_frag(), hwm_rx_frag() ;
  112. int mac_drv_rx_frag(), mac_drv_init(),
  113. hwm_tx_init() ;
  114. u_int mac_drv_check_space() ;
  115. SMbuf  *smt_get_mbuf() ;
  116. #ifdef DEBUG
  117. void mac_drv_debug_lev() ;
  118. #endif
  119. /*
  120. -------------------------------------------------------------
  121. MACROS:
  122. -------------------------------------------------------------
  123. */
  124. #ifndef UNUSED
  125. #ifdef lint
  126. #define UNUSED(x) (x) = (x)
  127. #else
  128. #define UNUSED(x)
  129. #endif
  130. #endif
  131. #ifdef USE_CAN_ADDR
  132. #define MA smc->hw.fddi_canon_addr.a
  133. #define GROUP_ADDR_BIT 0x01
  134. #else
  135. #define MA smc->hw.fddi_home_addr.a
  136. #define GROUP_ADDR_BIT 0x80
  137. #endif
  138. #define RXD_TXD_COUNT (HWM_ASYNC_TXD_COUNT+HWM_SYNC_TXD_COUNT+
  139. SMT_R1_RXD_COUNT+SMT_R2_RXD_COUNT)
  140. #ifdef MB_OUTSIDE_SMC
  141. #define EXT_VIRT_MEM ((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd) +
  142. MAX_MBUF*sizeof(SMbuf))
  143. #define EXT_VIRT_MEM_2 ((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd))
  144. #else
  145. #define EXT_VIRT_MEM ((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd))
  146. #endif
  147. /*
  148.  * define critical read for 16 Bit drivers
  149.  */
  150. #if defined(NDIS_OS2) || defined(ODI2)
  151. #define CR_READ(var) ((var) & 0xffff0000 | ((var) & 0xffff))
  152. #else
  153. #define CR_READ(var) (u_long)(var)
  154. #endif
  155. #define IMASK_SLOW (IS_PLINT1 | IS_PLINT2 | IS_TIMINT | IS_TOKEN | 
  156.  IS_MINTR1 | IS_MINTR2 | IS_MINTR3 | IS_R1_P | 
  157.  IS_R1_C | IS_XA_C | IS_XS_C)
  158. /*
  159. -------------------------------------------------------------
  160. INIT- AND SMT FUNCTIONS:
  161. -------------------------------------------------------------
  162. */
  163. /*
  164.  * BEGIN_MANUAL_ENTRY(mac_drv_check_space)
  165.  * u_int mac_drv_check_space()
  166.  *
  167.  * function DOWNCALL (drvsr.c)
  168.  * This function calculates the needed non virtual
  169.  * memory for MBufs, RxD and TxD descriptors etc.
  170.  * needed by the driver.
  171.  *
  172.  * return u_int memory in bytes
  173.  *
  174.  * END_MANUAL_ENTRY
  175.  */
  176. u_int mac_drv_check_space()
  177. {
  178. #ifdef MB_OUTSIDE_SMC
  179. #ifdef COMMON_MB_POOL
  180. call_count++ ;
  181. if (call_count == 1) {
  182. return(EXT_VIRT_MEM) ;
  183. }
  184. else {
  185. return(EXT_VIRT_MEM_2) ;
  186. }
  187. #else
  188. return (EXT_VIRT_MEM) ;
  189. #endif
  190. #else
  191. return (0) ;
  192. #endif
  193. }
  194. /*
  195.  * BEGIN_MANUAL_ENTRY(mac_drv_init)
  196.  * void mac_drv_init(smc)
  197.  *
  198.  * function DOWNCALL (drvsr.c)
  199.  * In this function the hardware module allocates it's
  200.  * memory.
  201.  * The operating system dependent module should call
  202.  * mac_drv_init once, after the adatper is detected.
  203.  * END_MANUAL_ENTRY
  204.  */
  205. int mac_drv_init(smc)
  206. struct s_smc *smc ;
  207. {
  208. if (sizeof(struct s_smt_fp_rxd) % 16) {
  209. SMT_PANIC(smc,HWM_E0001,HWM_E0001_MSG) ;
  210. }
  211. if (sizeof(struct s_smt_fp_txd) % 16) {
  212. SMT_PANIC(smc,HWM_E0002,HWM_E0002_MSG) ;
  213. }
  214. /*
  215.  * get the required memory for the RxDs and TxDs
  216.  */
  217. if (!(smc->os.hwm.descr_p = (union s_fp_descr volatile *)
  218. mac_drv_get_desc_mem(smc,(u_int)
  219. (RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd)))) {
  220. return(1) ; /* no space the hwm modul can't work */
  221. }
  222. /*
  223.  * get the memory for the SMT MBufs
  224.  */
  225. #ifndef MB_OUTSIDE_SMC
  226. smc->os.hwm.mbuf_pool.mb_start=(SMbuf *)(&smc->os.hwm.mbuf_pool.mb[0]) ;
  227. #else
  228. #ifndef COMMON_MB_POOL
  229. if (!(smc->os.hwm.mbuf_pool.mb_start = (SMbuf *) mac_drv_get_space(smc,
  230. MAX_MBUF*sizeof(SMbuf)))) {
  231. return(1) ; /* no space the hwm modul can't work */
  232. }
  233. #else
  234. if (!mb_start) {
  235. if (!(mb_start = (SMbuf *) mac_drv_get_space(smc,
  236. MAX_MBUF*sizeof(SMbuf)))) {
  237. return(1) ; /* no space the hwm modul can't work */
  238. }
  239. }
  240. #endif
  241. #endif
  242. return (0) ;
  243. }
  244. /*
  245.  * BEGIN_MANUAL_ENTRY(init_driver_fplus)
  246.  * init_driver_fplus(smc)
  247.  *
  248.  * Sets hardware modul specific values for the mode register 2
  249.  * (e.g. the byte alignment for the received frames, the position of the
  250.  *  least significant byte etc.)
  251.  * END_MANUAL_ENTRY
  252.  */
  253. void init_driver_fplus(smc)
  254. struct s_smc *smc ;
  255. {
  256. smc->hw.fp.mdr2init = FM_LSB | FM_BMMODE | FM_ENNPRQ | FM_ENHSRQ | 3 ;
  257. #ifdef PCI
  258. smc->hw.fp.mdr2init |= FM_CHKPAR | FM_PARITY ;
  259. #endif
  260. smc->hw.fp.mdr3init = FM_MENRQAUNLCK | FM_MENRS ;
  261. #ifdef USE_CAN_ADDR
  262. /* enable address bit swapping */
  263. smc->hw.fp.frselreg_init = FM_ENXMTADSWAP | FM_ENRCVADSWAP ;
  264. #endif
  265. }
  266. static u_long init_descr_ring(smc,start,count)
  267. struct s_smc *smc ;
  268. union s_fp_descr volatile *start;
  269. int count ;
  270. {
  271. int i ;
  272. union s_fp_descr volatile *d1 ;
  273. union s_fp_descr volatile *d2 ;
  274. u_long phys ;
  275. DB_GEN("descr ring starts at = %x ",(void *)start,0,3) ;
  276. for (i=count-1, d1=start; i ; i--) {
  277. d2 = d1 ;
  278. d1++ ; /* descr is owned by the host */
  279. d2->r.rxd_rbctrl = AIX_REVERSE(BMU_CHECK) ;
  280. d2->r.rxd_next = &d1->r ;
  281. phys = mac_drv_virt2phys(smc,(void *)d1) ;
  282. d2->r.rxd_nrdadr = AIX_REVERSE(phys) ;
  283. }
  284. DB_GEN("descr ring ends at = %x ",(void *)d1,0,3) ;
  285. d1->r.rxd_rbctrl = AIX_REVERSE(BMU_CHECK) ;
  286. d1->r.rxd_next = &start->r ;
  287. phys = mac_drv_virt2phys(smc,(void *)start) ;
  288. d1->r.rxd_nrdadr = AIX_REVERSE(phys) ;
  289. for (i=count, d1=start; i ; i--) {
  290. DRV_BUF_FLUSH(&d1->r,DDI_DMA_SYNC_FORDEV) ;
  291. d1++;
  292. }
  293. return(phys) ;
  294. }
  295. static void init_txd_ring(smc)
  296. struct s_smc *smc ;
  297. {
  298. struct s_smt_fp_txd volatile *ds ;
  299. struct s_smt_tx_queue *queue ;
  300. u_long phys ;
  301. /*
  302.  * initialize the transmit descriptors
  303.  */
  304. ds = (struct s_smt_fp_txd volatile *) ((char *)smc->os.hwm.descr_p +
  305. SMT_R1_RXD_COUNT*sizeof(struct s_smt_fp_rxd)) ;
  306. queue = smc->hw.fp.tx[QUEUE_A0] ;
  307. DB_GEN("Init async TxD ring, %d TxDs ",HWM_ASYNC_TXD_COUNT,0,3) ;
  308. (void)init_descr_ring(smc,(union s_fp_descr volatile *)ds,
  309. HWM_ASYNC_TXD_COUNT) ;
  310. phys = AIX_REVERSE(ds->txd_ntdadr) ;
  311. ds++ ;
  312. queue->tx_curr_put = queue->tx_curr_get = ds ;
  313. ds-- ;
  314. queue->tx_free = HWM_ASYNC_TXD_COUNT ;
  315. queue->tx_used = 0 ;
  316. outpd(ADDR(B5_XA_DA),phys) ;
  317. ds = (struct s_smt_fp_txd volatile *) ((char *)ds +
  318. HWM_ASYNC_TXD_COUNT*sizeof(struct s_smt_fp_txd)) ;
  319. queue = smc->hw.fp.tx[QUEUE_S] ;
  320. DB_GEN("Init sync TxD ring, %d TxDs ",HWM_SYNC_TXD_COUNT,0,3) ;
  321. (void)init_descr_ring(smc,(union s_fp_descr volatile *)ds,
  322. HWM_SYNC_TXD_COUNT) ;
  323. phys = AIX_REVERSE(ds->txd_ntdadr) ;
  324. ds++ ;
  325. queue->tx_curr_put = queue->tx_curr_get = ds ;
  326. queue->tx_free = HWM_SYNC_TXD_COUNT ;
  327. queue->tx_used = 0 ;
  328. outpd(ADDR(B5_XS_DA),phys) ;
  329. }
  330. static void init_rxd_ring(smc)
  331. struct s_smc *smc ;
  332. {
  333. struct s_smt_fp_rxd volatile *ds ;
  334. struct s_smt_rx_queue *queue ;
  335. u_long phys ;
  336. /*
  337.  * initialize the receive descriptors
  338.  */
  339. ds = (struct s_smt_fp_rxd volatile *) smc->os.hwm.descr_p ;
  340. queue = smc->hw.fp.rx[QUEUE_R1] ;
  341. DB_GEN("Init RxD ring, %d RxDs ",SMT_R1_RXD_COUNT,0,3) ;
  342. (void)init_descr_ring(smc,(union s_fp_descr volatile *)ds,
  343. SMT_R1_RXD_COUNT) ;
  344. phys = AIX_REVERSE(ds->rxd_nrdadr) ;
  345. ds++ ;
  346. queue->rx_curr_put = queue->rx_curr_get = ds ;
  347. queue->rx_free = SMT_R1_RXD_COUNT ;
  348. queue->rx_used = 0 ;
  349. outpd(ADDR(B4_R1_DA),phys) ;
  350. }
  351. /*
  352.  * BEGIN_MANUAL_ENTRY(init_fddi_driver)
  353.  * void init_fddi_driver(smc,mac_addr)
  354.  *
  355.  * initializes the driver and it's variables
  356.  *
  357.  * END_MANUAL_ENTRY
  358.  */
  359. void init_fddi_driver(smc,mac_addr)
  360. struct s_smc *smc ;
  361. u_char *mac_addr ; /* canonical address */
  362. {
  363. SMbuf *mb ;
  364. int i ;
  365. init_board(smc,mac_addr) ;
  366. (void)init_fplus(smc) ;
  367. /*
  368.  * initialize the SMbufs for the SMT
  369.  */
  370. #ifndef COMMON_MB_POOL
  371. mb = smc->os.hwm.mbuf_pool.mb_start ;
  372. smc->os.hwm.mbuf_pool.mb_free = (SMbuf *)NULL ;
  373. for (i = 0; i < MAX_MBUF; i++) {
  374. mb->sm_use_count = 1 ;
  375. smt_free_mbuf(smc,mb) ;
  376. mb++ ;
  377. }
  378. #else
  379. mb = mb_start ;
  380. if (!mb_init) {
  381. mb_free = 0 ;
  382. for (i = 0; i < MAX_MBUF; i++) {
  383. mb->sm_use_count = 1 ;
  384. smt_free_mbuf(smc,mb) ;
  385. mb++ ;
  386. }
  387. mb_init = TRUE ;
  388. }
  389. #endif
  390. /*
  391.  * initialize the other variables
  392.  */
  393. smc->os.hwm.llc_rx_pipe = smc->os.hwm.llc_rx_tail = (SMbuf *)NULL ;
  394. smc->os.hwm.txd_tx_pipe = smc->os.hwm.txd_tx_tail = NULL ;
  395. smc->os.hwm.pass_SMT = smc->os.hwm.pass_NSA = smc->os.hwm.pass_DB = 0 ;
  396. smc->os.hwm.pass_llc_promisc = TRUE ;
  397. smc->os.hwm.queued_rx_frames = smc->os.hwm.queued_txd_mb = 0 ;
  398. smc->os.hwm.detec_count = 0 ;
  399. smc->os.hwm.rx_break = 0 ;
  400. smc->os.hwm.rx_len_error = 0 ;
  401. smc->os.hwm.isr_flag = FALSE ;
  402. /*
  403.  * make sure that the start pointer is 16 byte aligned
  404.  */
  405. i = 16 - ((long)smc->os.hwm.descr_p & 0xf) ;
  406. if (i != 16) {
  407. DB_GEN("i = %d",i,0,3) ;
  408. smc->os.hwm.descr_p = (union s_fp_descr volatile *)
  409. ((char *)smc->os.hwm.descr_p+i) ;
  410. }
  411. DB_GEN("pt to descr area = %x",(void *)smc->os.hwm.descr_p,0,3) ;
  412. init_txd_ring(smc) ;
  413. init_rxd_ring(smc) ;
  414. mac_drv_fill_rxd(smc) ;
  415. init_plc(smc) ;
  416. }
  417. SMbuf *smt_get_mbuf(smc)
  418. struct s_smc *smc ;
  419. {
  420. register SMbuf *mb ;
  421. #ifndef COMMON_MB_POOL
  422. mb = smc->os.hwm.mbuf_pool.mb_free ;
  423. #else
  424. mb = mb_free ;
  425. #endif
  426. if (mb) {
  427. #ifndef COMMON_MB_POOL
  428. smc->os.hwm.mbuf_pool.mb_free = mb->sm_next ;
  429. #else
  430. mb_free = mb->sm_next ;
  431. #endif
  432. mb->sm_off = 8 ;
  433. mb->sm_use_count = 1 ;
  434. }
  435. DB_GEN("get SMbuf: mb = %x",(void *)mb,0,3) ;
  436. return (mb) ; /* May be NULL */
  437. }
  438. void smt_free_mbuf(smc, mb)
  439. struct s_smc *smc ;
  440. SMbuf *mb;
  441. {
  442. if (mb) {
  443. mb->sm_use_count-- ;
  444. DB_GEN("free_mbuf: sm_use_count = %d",mb->sm_use_count,0,3) ;
  445. /*
  446.  * If the use_count is != zero the MBuf is queued
  447.  * more than once and must not queued into the
  448.  * free MBuf queue
  449.  */
  450. if (!mb->sm_use_count) {
  451. DB_GEN("free SMbuf: mb = %x",(void *)mb,0,3) ;
  452. #ifndef COMMON_MB_POOL
  453. mb->sm_next = smc->os.hwm.mbuf_pool.mb_free ;
  454. smc->os.hwm.mbuf_pool.mb_free = mb ;
  455. #else
  456. mb->sm_next = mb_free ;
  457. mb_free = mb ;
  458. #endif
  459. }
  460. }
  461. else
  462. SMT_PANIC(smc,HWM_E0003,HWM_E0003_MSG) ;
  463. }
  464. /*
  465.  * BEGIN_MANUAL_ENTRY(mac_drv_repair_descr)
  466.  * void mac_drv_repair_descr(smc)
  467.  *
  468.  * function called from SMT (HWM / hwmtm.c)
  469.  * The BMU is idle when this function is called.
  470.  * Mac_drv_repair_descr sets up the physical address
  471.  * for all receive and transmit queues where the BMU
  472.  * should continue.
  473.  * It may be that the BMU was reseted during a fragmented
  474.  * transfer. In this case there are some fragments which will
  475.  * never completed by the BMU. The OWN bit of this fragments
  476.  * must be switched to be owned by the host.
  477.  *
  478.  * Give a start command to the receive BMU.
  479.  * Start the transmit BMUs if transmit frames pending.
  480.  *
  481.  * END_MANUAL_ENTRY
  482.  */
  483. void mac_drv_repair_descr(smc)
  484. struct s_smc *smc ;
  485. {
  486. u_long phys ;
  487. if (smc->hw.hw_state != STOPPED) {
  488. SK_BREAK() ;
  489. SMT_PANIC(smc,HWM_E0013,HWM_E0013_MSG) ;
  490. return ;
  491. }
  492. /*
  493.  * repair tx queues: don't start
  494.  */
  495. phys = repair_txd_ring(smc,smc->hw.fp.tx[QUEUE_A0]) ;
  496. outpd(ADDR(B5_XA_DA),phys) ;
  497. if (smc->hw.fp.tx_q[QUEUE_A0].tx_used) {
  498. outpd(ADDR(B0_XA_CSR),CSR_START) ;
  499. }
  500. phys = repair_txd_ring(smc,smc->hw.fp.tx[QUEUE_S]) ;
  501. outpd(ADDR(B5_XS_DA),phys) ;
  502. if (smc->hw.fp.tx_q[QUEUE_S].tx_used) {
  503. outpd(ADDR(B0_XS_CSR),CSR_START) ;
  504. }
  505. /*
  506.  * repair rx queues
  507.  */
  508. phys = repair_rxd_ring(smc,smc->hw.fp.rx[QUEUE_R1]) ;
  509. outpd(ADDR(B4_R1_DA),phys) ;
  510. outpd(ADDR(B0_R1_CSR),CSR_START) ;
  511. }
  512. static u_long repair_txd_ring(smc,queue)
  513. struct s_smc *smc ;
  514. struct s_smt_tx_queue *queue ;
  515. {
  516. int i ;
  517. int tx_used ;
  518. u_long phys ;
  519. u_long tbctrl ;
  520. struct s_smt_fp_txd volatile *t ;
  521. SK_UNUSED(smc) ;
  522. t = queue->tx_curr_get ;
  523. tx_used = queue->tx_used ;
  524. for (i = tx_used+queue->tx_free-1 ; i ; i-- ) {
  525. t = t->txd_next ;
  526. }
  527. phys = AIX_REVERSE(t->txd_ntdadr) ;
  528. t = queue->tx_curr_get ;
  529. while (tx_used) {
  530. DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORCPU) ;
  531. tbctrl = AIX_REVERSE(t->txd_tbctrl) ;
  532. if (tbctrl & BMU_OWN) {
  533. if (tbctrl & BMU_STF) {
  534. break ; /* exit the loop */
  535. }
  536. else {
  537. /*
  538.  * repair the descriptor
  539.  */
  540. t->txd_tbctrl &= AIX_REVERSE(~BMU_OWN) ;
  541. }
  542. }
  543. phys = AIX_REVERSE(t->txd_ntdadr) ;
  544. DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
  545. t = t->txd_next ;
  546. tx_used-- ;
  547. }
  548. return(phys) ;
  549. }
  550. /*
  551.  * Repairs the receive descriptor ring and returns the physical address
  552.  * where the BMU should continue working.
  553.  *
  554.  * o The physical address where the BMU was stopped has to be
  555.  *   determined. This is the next RxD after rx_curr_get with an OWN
  556.  *   bit set.
  557.  * o The BMU should start working at beginning of the next frame.
  558.  *   RxDs with an OWN bit set but with a reset STF bit should be
  559.  *   skipped and owned by the driver (OWN = 0). 
  560.  */
  561. static u_long repair_rxd_ring(smc,queue)
  562. struct s_smc *smc ;
  563. struct s_smt_rx_queue *queue ;
  564. {
  565. int i ;
  566. int rx_used ;
  567. u_long phys ;
  568. u_long rbctrl ;
  569. struct s_smt_fp_rxd volatile *r ;
  570. SK_UNUSED(smc) ;
  571. r = queue->rx_curr_get ;
  572. rx_used = queue->rx_used ;
  573. for (i = SMT_R1_RXD_COUNT-1 ; i ; i-- ) {
  574. r = r->rxd_next ;
  575. }
  576. phys = AIX_REVERSE(r->rxd_nrdadr) ;
  577. r = queue->rx_curr_get ;
  578. while (rx_used) {
  579. DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
  580. rbctrl = AIX_REVERSE(r->rxd_rbctrl) ;
  581. if (rbctrl & BMU_OWN) {
  582. if (rbctrl & BMU_STF) {
  583. break ; /* exit the loop */
  584. }
  585. else {
  586. /*
  587.  * repair the descriptor
  588.  */
  589. r->rxd_rbctrl &= AIX_REVERSE(~BMU_OWN) ;
  590. }
  591. }
  592. phys = AIX_REVERSE(r->rxd_nrdadr) ;
  593. DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ;
  594. r = r->rxd_next ;
  595. rx_used-- ;
  596. }
  597. return(phys) ;
  598. }
  599. /*
  600. -------------------------------------------------------------
  601. INTERRUPT SERVICE ROUTINE:
  602. -------------------------------------------------------------
  603. */
  604. /*
  605.  * BEGIN_MANUAL_ENTRY(fddi_isr)
  606.  * void fddi_isr(smc)
  607.  *
  608.  * function DOWNCALL (drvsr.c)
  609.  * interrupt service routine, handles the interrupt requests
  610.  * generated by the FDDI adapter.
  611.  *
  612.  * NOTE: The operating system dependent module must garantee that the
  613.  * interrupts of the adapter are disabled when it calls fddi_isr.
  614.  *
  615.  * About the USE_BREAK_ISR mechanismn:
  616.  *
  617.  * The main requirement of this mechanismn is to force an timer IRQ when
  618.  * leaving process_receive() with leave_isr set. process_receive() may
  619.  * be called at any time from anywhere!
  620.  * To be sure we don't miss such event we set 'force_irq' per default.
  621.  * We have to force and Timer IRQ if 'smc->os.hwm.leave_isr' AND
  622.  * 'force_irq' are set. 'force_irq' may be reset if a receive complete
  623.  * IRQ is pending.
  624.  *
  625.  * END_MANUAL_ENTRY
  626.  */
  627. void fddi_isr(smc)
  628. struct s_smc *smc ;
  629. {
  630. u_long is ; /* ISR source */
  631. u_short stu, stl ;
  632. SMbuf *mb ;
  633. #ifdef USE_BREAK_ISR
  634. int force_irq ;
  635. #endif
  636. #ifdef ODI2
  637. if (smc->os.hwm.rx_break) {
  638. mac_drv_fill_rxd(smc) ;
  639. if (smc->hw.fp.rx_q[QUEUE_R1].rx_used > 0) {
  640. smc->os.hwm.rx_break = 0 ;
  641. process_receive(smc) ;
  642. }
  643. else {
  644. smc->os.hwm.detec_count = 0 ;
  645. smt_force_irq(smc) ;
  646. }
  647. }
  648. #endif
  649. smc->os.hwm.isr_flag = TRUE ;
  650. #ifdef USE_BREAK_ISR
  651. force_irq = TRUE ;
  652. if (smc->os.hwm.leave_isr) {
  653. smc->os.hwm.leave_isr = FALSE ;
  654. process_receive(smc) ;
  655. }
  656. #endif
  657. while ((is = GET_ISR() & ISR_MASK)) {
  658. NDD_TRACE("CH0B",is,0,0) ;
  659. DB_GEN("ISA = 0x%x",is,0,7) ;
  660. if (is & IMASK_SLOW) {
  661. NDD_TRACE("CH1b",is,0,0) ;
  662. if (is & IS_PLINT1) { /* PLC1 */
  663. plc1_irq(smc) ;
  664. }
  665. if (is & IS_PLINT2) { /* PLC2 */
  666. plc2_irq(smc) ;
  667. }
  668. if (is & IS_MINTR1) { /* FORMAC+ STU1(U/L) */
  669. stu = inpw(FM_A(FM_ST1U)) ;
  670. stl = inpw(FM_A(FM_ST1L)) ;
  671. DB_GEN("Slow transmit complete",0,0,6) ;
  672. mac1_irq(smc,stu,stl) ;
  673. }
  674. if (is & IS_MINTR2) { /* FORMAC+ STU2(U/L) */
  675. stu= inpw(FM_A(FM_ST2U)) ;
  676. stl= inpw(FM_A(FM_ST2L)) ;
  677. DB_GEN("Slow receive complete",0,0,6) ;
  678. DB_GEN("stl = %x : stu = %x",stl,stu,7) ;
  679. mac2_irq(smc,stu,stl) ;
  680. }
  681. if (is & IS_MINTR3) { /* FORMAC+ STU3(U/L) */
  682. stu= inpw(FM_A(FM_ST3U)) ;
  683. stl= inpw(FM_A(FM_ST3L)) ;
  684. DB_GEN("FORMAC Mode Register 3",0,0,6) ;
  685. mac3_irq(smc,stu,stl) ;
  686. }
  687. if (is & IS_TIMINT) { /* Timer 82C54-2 */
  688. timer_irq(smc) ;
  689. #ifdef NDIS_OS2
  690. force_irq_pending = 0 ;
  691. #endif
  692. /*
  693.  * out of RxD detection
  694.  */
  695. if (++smc->os.hwm.detec_count > 4) {
  696. /*
  697.  * check out of RxD condition
  698.  */
  699.  process_receive(smc) ;
  700. }
  701. }
  702. if (is & IS_TOKEN) { /* Restricted Token Monitor */
  703. rtm_irq(smc) ;
  704. }
  705. if (is & IS_R1_P) { /* Parity error rx queue 1 */
  706. /* clear IRQ */
  707. outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_P) ;
  708. SMT_PANIC(smc,HWM_E0004,HWM_E0004_MSG) ;
  709. }
  710. if (is & IS_R1_C) { /* Encoding error rx queue 1 */
  711. /* clear IRQ */
  712. outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_C) ;
  713. SMT_PANIC(smc,HWM_E0005,HWM_E0005_MSG) ;
  714. }
  715. if (is & IS_XA_C) { /* Encoding error async tx q */
  716. /* clear IRQ */
  717. outpd(ADDR(B5_XA_CSR),CSR_IRQ_CL_C) ;
  718. SMT_PANIC(smc,HWM_E0006,HWM_E0006_MSG) ;
  719. }
  720. if (is & IS_XS_C) { /* Encoding error sync tx q */
  721. /* clear IRQ */
  722. outpd(ADDR(B5_XS_CSR),CSR_IRQ_CL_C) ;
  723. SMT_PANIC(smc,HWM_E0007,HWM_E0007_MSG) ;
  724. }
  725. }
  726. /*
  727.  * Fast Tx complete Async/Sync Queue (BMU service)
  728.  */
  729. if (is & (IS_XS_F|IS_XA_F)) {
  730. DB_GEN("Fast tx complete queue",0,0,6) ;
  731. /*
  732.  * clear IRQ, Note: no IRQ is lost, because
  733.  *  we always service both queues
  734.  */
  735. outpd(ADDR(B5_XS_CSR),CSR_IRQ_CL_F) ;
  736. outpd(ADDR(B5_XA_CSR),CSR_IRQ_CL_F) ;
  737. mac_drv_clear_txd(smc) ;
  738. llc_restart_tx(smc) ;
  739. }
  740. /*
  741.  * Fast Rx Complete (BMU service)
  742.  */
  743. if (is & IS_R1_F) {
  744. DB_GEN("Fast receive complete",0,0,6) ;
  745. /* clear IRQ */
  746. #ifndef USE_BREAK_ISR
  747. outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_F) ;
  748. process_receive(smc) ;
  749. #else
  750. process_receive(smc) ;
  751. if (smc->os.hwm.leave_isr) {
  752. force_irq = FALSE ;
  753. } else {
  754. outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_F) ;
  755. process_receive(smc) ;
  756. }
  757. #endif
  758. }
  759. #ifndef NDIS_OS2
  760. while ((mb = get_llc_rx(smc))) {
  761. smt_to_llc(smc,mb) ;
  762. }
  763. #else
  764. if (offDepth)
  765. post_proc() ;
  766. while (!offDepth && (mb = get_llc_rx(smc))) {
  767. smt_to_llc(smc,mb) ;
  768. }
  769. if (!offDepth && smc->os.hwm.rx_break) {
  770. process_receive(smc) ;
  771. }
  772. #endif
  773. if (smc->q.ev_get != smc->q.ev_put) {
  774. NDD_TRACE("CH2a",0,0,0) ;
  775. ev_dispatcher(smc) ;
  776. }
  777. #ifdef NDIS_OS2
  778. post_proc() ;
  779. if (offDepth) { /* leave fddi_isr because */
  780. break ; /* indications not allowed */
  781. }
  782. #endif
  783. #ifdef USE_BREAK_ISR
  784. if (smc->os.hwm.leave_isr) {
  785. break ; /* leave fddi_isr */
  786. }
  787. #endif
  788. /* NOTE: when the isr is left, no rx is pending */
  789. } /* end of interrupt source polling loop */
  790. #ifdef USE_BREAK_ISR
  791. if (smc->os.hwm.leave_isr && force_irq) {
  792. smt_force_irq(smc) ;
  793. }
  794. #endif
  795. smc->os.hwm.isr_flag = FALSE ;
  796. NDD_TRACE("CH0E",0,0,0) ;
  797. }
  798. /*
  799. -------------------------------------------------------------
  800. RECEIVE FUNCTIONS:
  801. -------------------------------------------------------------
  802. */
  803. #ifndef NDIS_OS2
  804. /*
  805.  * BEGIN_MANUAL_ENTRY(mac_drv_rx_mode)
  806.  * void mac_drv_rx_mode(smc,mode)
  807.  *
  808.  * function DOWNCALL (fplus.c)
  809.  * Corresponding to the parameter mode, the operating system
  810.  * dependent module can activate several receive modes.
  811.  *
  812.  * para mode = 1: RX_ENABLE_ALLMULTI enable all multicasts
  813.  * = 2: RX_DISABLE_ALLMULTI disable "enable all multicasts"
  814.  * = 3: RX_ENABLE_PROMISC enable promiscuous
  815.  * = 4: RX_DISABLE_PROMISC disable promiscuous
  816.  * = 5: RX_ENABLE_NSA enable rec. of all NSA frames
  817.  * (disabled after 'driver reset' & 'set station address')
  818.  * = 6: RX_DISABLE_NSA disable rec. of all NSA frames
  819.  *
  820.  * = 21: RX_ENABLE_PASS_SMT ( see description )
  821.  * = 22: RX_DISABLE_PASS_SMT (  "    "   )
  822.  * = 23: RX_ENABLE_PASS_NSA (  "    "   )
  823.  * = 24: RX_DISABLE_PASS_NSA (  "    "   )
  824.  * = 25: RX_ENABLE_PASS_DB (  "    "   )
  825.  * = 26: RX_DISABLE_PASS_DB (  "    "   )
  826.  * = 27: RX_DISABLE_PASS_ALL (  "    "   )
  827.  * = 28: RX_DISABLE_LLC_PROMISC (  "    "   )
  828.  * = 29: RX_ENABLE_LLC_PROMISC (  "    "   )
  829.  *
  830.  *
  831.  * RX_ENABLE_PASS_SMT / RX_DISABLE_PASS_SMT
  832.  *
  833.  * If the operating system dependent module activates the
  834.  * mode RX_ENABLE_PASS_SMT, the hardware module
  835.  * duplicates all SMT frames with the frame control
  836.  * FC_SMT_INFO and passes them to the LLC receive channel
  837.  * by calling mac_drv_rx_init.
  838.  * The SMT Frames which are sent by the local SMT and the NSA
  839.  * frames whose A- and C-Indicator is not set are also duplicated
  840.  * and passed.
  841.  * The receive mode RX_DISABLE_PASS_SMT disables the passing
  842.  * of SMT frames.
  843.  *
  844.  * RX_ENABLE_PASS_NSA / RX_DISABLE_PASS_NSA
  845.  *
  846.  * If the operating system dependent module activates the
  847.  * mode RX_ENABLE_PASS_NSA, the hardware module
  848.  * duplicates all NSA frames with frame control FC_SMT_NSA
  849.  * and a set A-Indicator and passed them to the LLC
  850.  * receive channel by calling mac_drv_rx_init.
  851.  * All NSA Frames which are sent by the local SMT
  852.  * are also duplicated and passed.
  853.  * The receive mode RX_DISABLE_PASS_NSA disables the passing
  854.  * of NSA frames with the A- or C-Indicator set.
  855.  *
  856.  * NOTE: For fear that the hardware module receives NSA frames with
  857.  * a reset A-Indicator, the operating system dependent module
  858.  * has to call mac_drv_rx_mode with the mode RX_ENABLE_NSA
  859.  * before activate the RX_ENABLE_PASS_NSA mode and after every
  860.  * 'driver reset' and 'set station address'.
  861.  *
  862.  * RX_ENABLE_PASS_DB / RX_DISABLE_PASS_DB
  863.  *
  864.  * If the operating system dependent module activates the
  865.  * mode RX_ENABLE_PASS_DB, direct BEACON frames
  866.  * (FC_BEACON frame control) are passed to the LLC receive
  867.  * channel by mac_drv_rx_init.
  868.  * The receive mode RX_DISABLE_PASS_DB disables the passing
  869.  * of direct BEACON frames.
  870.  *
  871.  * RX_DISABLE_PASS_ALL
  872.  *
  873.  * Disables all special receives modes. It is equal to
  874.  * call mac_drv_set_rx_mode successively with the
  875.  * parameters RX_DISABLE_NSA, RX_DISABLE_PASS_SMT,
  876.  * RX_DISABLE_PASS_NSA and RX_DISABLE_PASS_DB.
  877.  *
  878.  * RX_ENABLE_LLC_PROMISC
  879.  *
  880.  * (default) all received LLC frames and all SMT/NSA/DBEACON
  881.  * frames depending on the attitude of the flags
  882.  * PASS_SMT/PASS_NSA/PASS_DBEACON will be delivered to the
  883.  * LLC layer
  884.  *
  885.  * RX_DISABLE_LLC_PROMISC
  886.  *
  887.  * all received SMT/NSA/DBEACON frames depending on the
  888.  * attitude of the flags PASS_SMT/PASS_NSA/PASS_DBEACON
  889.  * will be delivered to the LLC layer.
  890.  * all received LLC frames with a directed address, Multicast
  891.  * or Broadcast address will be delivered to the LLC
  892.  * layer too.
  893.  *
  894.  * END_MANUAL_ENTRY
  895.  */
  896. void mac_drv_rx_mode(smc,mode)
  897. struct s_smc *smc ;
  898. int mode ;
  899. {
  900. switch(mode) {
  901. case RX_ENABLE_PASS_SMT:
  902. smc->os.hwm.pass_SMT = TRUE ;
  903. break ;
  904. case RX_DISABLE_PASS_SMT:
  905. smc->os.hwm.pass_SMT = FALSE ;
  906. break ;
  907. case RX_ENABLE_PASS_NSA:
  908. smc->os.hwm.pass_NSA = TRUE ;
  909. break ;
  910. case RX_DISABLE_PASS_NSA:
  911. smc->os.hwm.pass_NSA = FALSE ;
  912. break ;
  913. case RX_ENABLE_PASS_DB:
  914. smc->os.hwm.pass_DB = TRUE ;
  915. break ;
  916. case RX_DISABLE_PASS_DB:
  917. smc->os.hwm.pass_DB = FALSE ;
  918. break ;
  919. case RX_DISABLE_PASS_ALL:
  920. smc->os.hwm.pass_SMT = smc->os.hwm.pass_NSA = FALSE ;
  921. smc->os.hwm.pass_DB = FALSE ;
  922. smc->os.hwm.pass_llc_promisc = TRUE ;
  923. mac_set_rx_mode(smc,RX_DISABLE_NSA) ;
  924. break ;
  925. case RX_DISABLE_LLC_PROMISC:
  926. smc->os.hwm.pass_llc_promisc = FALSE ;
  927. break ;
  928. case RX_ENABLE_LLC_PROMISC:
  929. smc->os.hwm.pass_llc_promisc = TRUE ;
  930. break ;
  931. case RX_ENABLE_ALLMULTI:
  932. case RX_DISABLE_ALLMULTI:
  933. case RX_ENABLE_PROMISC:
  934. case RX_DISABLE_PROMISC:
  935. case RX_ENABLE_NSA:
  936. case RX_DISABLE_NSA:
  937. default:
  938. mac_set_rx_mode(smc,mode) ;
  939. break ;
  940. }
  941. }
  942. #endif /* ifndef NDIS_OS2 */
  943. /*
  944.  * process receive queue
  945.  */
  946. void process_receive(smc)
  947. struct s_smc *smc ;
  948. {
  949. int i ;
  950. int n ;
  951. int frag_count ; /* number of RxDs of the curr rx buf */
  952. int used_frags ; /* number of RxDs of the curr frame */
  953. struct s_smt_rx_queue *queue ; /* points to the queue ctl struct */
  954. struct s_smt_fp_rxd volatile *r ; /* rxd pointer */
  955. struct s_smt_fp_rxd volatile *rxd ; /* first rxd of rx frame */
  956. u_long rbctrl ; /* receive buffer control word */
  957. u_long rfsw ; /* receive frame status word */
  958. u_short rx_used ;
  959. u_char far *virt ;
  960. char far *data ;
  961. SMbuf *mb ;
  962. u_char fc ; /* Frame control */
  963. int len ; /* Frame length */
  964. smc->os.hwm.detec_count = 0 ;
  965. queue = smc->hw.fp.rx[QUEUE_R1] ;
  966. NDD_TRACE("RHxB",0,0,0) ;
  967. for ( ; ; ) {
  968. r = queue->rx_curr_get ;
  969. rx_used = queue->rx_used ;
  970. frag_count = 0 ;
  971. #ifdef USE_BREAK_ISR
  972. if (smc->os.hwm.leave_isr) {
  973. goto rx_end ;
  974. }
  975. #endif
  976. #ifdef NDIS_OS2
  977. if (offDepth) {
  978. smc->os.hwm.rx_break = 1 ;
  979. goto rx_end ;
  980. }
  981. smc->os.hwm.rx_break = 0 ;
  982. #endif
  983. #ifdef ODI2
  984. if (smc->os.hwm.rx_break) {
  985. goto rx_end ;
  986. }
  987. #endif
  988. n = 0 ;
  989. do {
  990. DB_RX("Check RxD %x for OWN and EOF",(void *)r,0,5) ;
  991. DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
  992. rbctrl = CR_READ(r->rxd_rbctrl) ;
  993. rbctrl = AIX_REVERSE(rbctrl) ;
  994. if (rbctrl & BMU_OWN) {
  995. NDD_TRACE("RHxE",r,rfsw,rbctrl) ;
  996. DB_RX("End of RxDs",0,0,4) ;
  997. goto rx_end ;
  998. }
  999. /*
  1000.  * out of RxD detection
  1001.  */
  1002. if (!rx_used) {
  1003. SK_BREAK() ;
  1004. SMT_PANIC(smc,HWM_E0009,HWM_E0009_MSG) ;
  1005. /* Either we don't have an RxD or all
  1006.  * RxDs are filled. Therefore it's allowed
  1007.  * for to set the STOPPED flag */
  1008. smc->hw.hw_state = STOPPED ;
  1009. mac_drv_clear_rx_queue(smc) ;
  1010. smc->hw.hw_state = STARTED ;
  1011. mac_drv_fill_rxd(smc) ;
  1012. smc->os.hwm.detec_count = 0 ;
  1013. goto rx_end ;
  1014. }
  1015. rfsw = AIX_REVERSE(r->rxd_rfsw) ;
  1016. if ((rbctrl & BMU_STF) != ((rbctrl & BMU_ST_BUF) <<5)) {
  1017. /*
  1018.  * The BMU_STF bit is deleted, 1 frame is
  1019.  * placed into more than 1 rx buffer
  1020.  *
  1021.  * skip frame by setting the rx len to 0
  1022.  *
  1023.  * if fragment count == 0
  1024.  * The missing STF bit belongs to the
  1025.  * current frame, search for the
  1026.  * EOF bit to complete the frame
  1027.  * else
  1028.  * the fragment belongs to the next frame,
  1029.  * exit the loop and process the frame
  1030.  */
  1031. SK_BREAK() ;
  1032. rfsw = 0 ;
  1033. if (frag_count) {
  1034. break ;
  1035. }
  1036. }
  1037. n += rbctrl & 0xffff ;
  1038. r = r->rxd_next ;
  1039. frag_count++ ;
  1040. rx_used-- ;
  1041. } while (!(rbctrl & BMU_EOF)) ;
  1042. used_frags = frag_count ;
  1043. DB_RX("EOF set in RxD, used_frags = %d ",used_frags,0,5) ;
  1044. /* may be next 2 DRV_BUF_FLUSH() can be skipped, because */
  1045. /* BMU_ST_BUF will not be changed by the ASIC */
  1046. DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
  1047. while (rx_used && !(r->rxd_rbctrl & AIX_REVERSE(BMU_ST_BUF))) {
  1048. DB_RX("Check STF bit in %x",(void *)r,0,5) ;
  1049. r = r->rxd_next ;
  1050. DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
  1051. frag_count++ ;
  1052. rx_used-- ;
  1053. }
  1054. DB_RX("STF bit found",0,0,5) ;
  1055. /*
  1056.  * The received frame is finished for the process receive
  1057.  */
  1058. rxd = queue->rx_curr_get ;
  1059. queue->rx_curr_get = r ;
  1060. queue->rx_free += frag_count ;
  1061. queue->rx_used = rx_used ;
  1062. /*
  1063.  * ASIC Errata no. 7 (STF - Bit Bug)
  1064.  */
  1065. rxd->rxd_rbctrl &= AIX_REVERSE(~BMU_STF) ;
  1066. for (r=rxd, i=frag_count ; i ; r=r->rxd_next, i--){
  1067. DB_RX("dma_complete for RxD %x",(void *)r,0,5) ;
  1068. dma_complete(smc,(union s_fp_descr volatile *)r,DMA_WR);
  1069. }
  1070. smc->hw.fp.err_stats.err_valid++ ;
  1071. smc->mib.m[MAC0].fddiMACCopied_Ct++ ;
  1072. /* the length of the data including the FC */
  1073. len = (rfsw & RD_LENGTH) - 4 ;
  1074. DB_RX("frame length = %d",len,0,4) ;
  1075. /*
  1076.  * check the frame_lenght and all error flags
  1077.  */
  1078. if (rfsw & (RX_MSRABT|RX_FS_E|RX_FS_CRC|RX_FS_IMPL)){
  1079. if (rfsw & RD_S_MSRABT) {
  1080. DB_RX("Frame aborted by the FORMAC",0,0,2) ;
  1081. smc->hw.fp.err_stats.err_abort++ ;
  1082. }
  1083. /*
  1084.  * check frame status
  1085.  */
  1086. if (rfsw & RD_S_SEAC2) {
  1087. DB_RX("E-Indicator set",0,0,2) ;
  1088. smc->hw.fp.err_stats.err_e_indicator++ ;
  1089. }
  1090. if (rfsw & RD_S_SFRMERR) {
  1091. DB_RX("CRC error",0,0,2) ;
  1092. smc->hw.fp.err_stats.err_crc++ ;
  1093. }
  1094. if (rfsw & RX_FS_IMPL) {
  1095. DB_RX("Implementer frame",0,0,2) ;
  1096. smc->hw.fp.err_stats.err_imp_frame++ ;
  1097. }
  1098. goto abort_frame ;
  1099. }
  1100. if (len > FDDI_RAW_MTU-4) {
  1101. DB_RX("Frame to long error",0,0,2) ;
  1102. smc->hw.fp.err_stats.err_too_long++ ;
  1103. goto abort_frame ;
  1104. }
  1105. /*
  1106.  * SUPERNET 3 Bug: FORMAC delivers status words
  1107.  * of aborded frames to the BMU
  1108.  */
  1109. if (len <= 4) {
  1110. DB_RX("Frame length = 0",0,0,2) ;
  1111. goto abort_frame ;
  1112. }
  1113. if (len != (n-4)) {
  1114. DB_RX("BMU: rx len differs: [%d:%d]",len,n,4);
  1115. smc->os.hwm.rx_len_error++ ;
  1116. goto abort_frame ;
  1117. }
  1118. /*
  1119.  * Check SA == MA
  1120.  */
  1121. virt = (u_char far *) rxd->rxd_virt ;
  1122. DB_RX("FC = %x",*virt,0,2) ;
  1123. if (virt[12] == MA[5] &&
  1124.     virt[11] == MA[4] &&
  1125.     virt[10] == MA[3] &&
  1126.     virt[9] == MA[2] &&
  1127.     virt[8] == MA[1] &&
  1128.     (virt[7] & ~GROUP_ADDR_BIT) == MA[0]) {
  1129. goto abort_frame ;
  1130. }
  1131. /*
  1132.  * test if LLC frame
  1133.  */
  1134. if (rfsw & RX_FS_LLC) {
  1135. /*
  1136.  * if pass_llc_promisc is disable
  1137.  * if DA != Multicast or Broadcast or DA!=MA
  1138.  * abort the frame
  1139.  */
  1140. if (!smc->os.hwm.pass_llc_promisc) {
  1141. if(!(virt[1] & GROUP_ADDR_BIT)) {
  1142. if (virt[6] != MA[5] ||
  1143.     virt[5] != MA[4] ||
  1144.     virt[4] != MA[3] ||
  1145.     virt[3] != MA[2] ||
  1146.     virt[2] != MA[1] ||
  1147.     virt[1] != MA[0]) {
  1148. DB_RX("DA != MA and not multi- or broadcast",0,0,2) ;
  1149. goto abort_frame ;
  1150. }
  1151. }
  1152. }
  1153. /*
  1154.  * LLC frame received
  1155.  */
  1156. DB_RX("LLC - receive",0,0,4) ;
  1157. mac_drv_rx_complete(smc,rxd,frag_count,len) ;
  1158. }
  1159. else {
  1160. if (!(mb = smt_get_mbuf(smc))) {
  1161. smc->hw.fp.err_stats.err_no_buf++ ;
  1162. DB_RX("No SMbuf; receive terminated",0,0,4) ;
  1163. goto abort_frame ;
  1164. }
  1165. data = smtod(mb,char *) - 1 ;
  1166. /*
  1167.  * copy the frame into a SMT_MBuf
  1168.  */
  1169. #ifdef USE_OS_CPY
  1170. hwm_cpy_rxd2mb(rxd,data,len) ;
  1171. #else
  1172. for (r=rxd, i=used_frags ; i ; r=r->rxd_next, i--){
  1173. n = AIX_REVERSE(r->rxd_rbctrl) & RD_LENGTH ;
  1174. DB_RX("cp SMT frame to mb: len = %d",n,0,6) ;
  1175. memcpy(data,r->rxd_virt,n) ;
  1176. data += n ;
  1177. }
  1178. data = smtod(mb,char *) - 1 ;
  1179. #endif
  1180. fc = *(char *)mb->sm_data = *data ;
  1181. mb->sm_len = len - 1 ; /* len - fc */
  1182. data++ ;
  1183. /*
  1184.  * SMT frame received
  1185.  */
  1186. switch(fc) {
  1187. case FC_SMT_INFO :
  1188. smc->hw.fp.err_stats.err_smt_frame++ ;
  1189. DB_RX("SMT frame received ",0,0,5) ;
  1190. if (smc->os.hwm.pass_SMT) {
  1191. DB_RX("pass SMT frame ",0,0,5) ;
  1192. mac_drv_rx_complete(smc, rxd,
  1193. frag_count,len) ;
  1194. }
  1195. else {
  1196. DB_RX("requeue RxD",0,0,5) ;
  1197. mac_drv_requeue_rxd(smc,rxd,frag_count);
  1198. }
  1199. smt_received_pack(smc,mb,(int)(rfsw>>25)) ;
  1200. break ;
  1201. case FC_SMT_NSA :
  1202. smc->hw.fp.err_stats.err_smt_frame++ ;
  1203. DB_RX("SMT frame received ",0,0,5) ;
  1204. /* if pass_NSA set pass the NSA frame or */
  1205. /* pass_SMT set and the A-Indicator */
  1206. /* is not set, pass the NSA frame */
  1207. if (smc->os.hwm.pass_NSA ||
  1208. (smc->os.hwm.pass_SMT &&
  1209. !(rfsw & A_INDIC))) {
  1210. DB_RX("pass SMT frame ",0,0,5) ;
  1211. mac_drv_rx_complete(smc, rxd,
  1212. frag_count,len) ;
  1213. }
  1214. else {
  1215. DB_RX("requeue RxD",0,0,5) ;
  1216. mac_drv_requeue_rxd(smc,rxd,frag_count);
  1217. }
  1218. smt_received_pack(smc,mb,(int)(rfsw>>25)) ;
  1219. break ;
  1220. case FC_BEACON :
  1221. if (smc->os.hwm.pass_DB) {
  1222. DB_RX("pass DB frame ",0,0,5) ;
  1223. mac_drv_rx_complete(smc, rxd,
  1224. frag_count,len) ;
  1225. }
  1226. else {
  1227. DB_RX("requeue RxD",0,0,5) ;
  1228. mac_drv_requeue_rxd(smc,rxd,frag_count);
  1229. }
  1230. smt_free_mbuf(smc,mb) ;
  1231. break ;
  1232. default :
  1233. /*
  1234.  * unknown FC abord the frame
  1235.  */
  1236. DB_RX("unknown FC error",0,0,2) ;
  1237. smt_free_mbuf(smc,mb) ;
  1238. DB_RX("requeue RxD",0,0,5) ;
  1239. mac_drv_requeue_rxd(smc,rxd,frag_count) ;
  1240. if ((fc & 0xf0) == FC_MAC)
  1241. smc->hw.fp.err_stats.err_mac_frame++ ;
  1242. else
  1243. smc->hw.fp.err_stats.err_imp_frame++ ;
  1244. break ;
  1245. }
  1246. }
  1247. DB_RX("next RxD is %x ",queue->rx_curr_get,0,3) ;
  1248. NDD_TRACE("RHx1",queue->rx_curr_get,0,0) ;
  1249. continue ;
  1250. /*--------------------------------------------------------------------*/
  1251. abort_frame:
  1252. DB_RX("requeue RxD",0,0,5) ;
  1253. mac_drv_requeue_rxd(smc,rxd,frag_count) ;
  1254. DB_RX("next RxD is %x ",queue->rx_curr_get,0,3) ;
  1255. NDD_TRACE("RHx2",queue->rx_curr_get,0,0) ;
  1256. }
  1257. rx_end:
  1258. #ifdef ALL_RX_COMPLETE
  1259. mac_drv_all_receives_complete(smc) ;
  1260. #endif
  1261. return ; /* lint bug: needs return detect end of function */
  1262. }
  1263. static void smt_to_llc(smc,mb)
  1264. struct s_smc *smc ;
  1265. SMbuf *mb ;
  1266. {
  1267. u_char fc ;
  1268. DB_RX("send a queued frame to the llc layer",0,0,4) ;
  1269. smc->os.hwm.r.len = mb->sm_len ;
  1270. smc->os.hwm.r.mb_pos = smtod(mb,char *) ;
  1271. fc = *smc->os.hwm.r.mb_pos ;
  1272. (void)mac_drv_rx_init(smc,(int)mb->sm_len,(int)fc,
  1273. smc->os.hwm.r.mb_pos,(int)mb->sm_len) ;
  1274. smt_free_mbuf(smc,mb) ;
  1275. }
  1276. /*
  1277.  * BEGIN_MANUAL_ENTRY(hwm_rx_frag)
  1278.  * void hwm_rx_frag(smc,virt,phys,len,frame_status)
  1279.  *
  1280.  * function MACRO (hardware module, hwmtm.h)
  1281.  * This function calls dma_master for preparing the
  1282.  * system hardware for the DMA transfer and initializes
  1283.  * the current RxD with the length and the physical and
  1284.  * virtual address of the fragment. Furthermore, it sets the
  1285.  * STF and EOF bits depending on the frame status byte,
  1286.  * switches the OWN flag of the RxD, so that it is owned by the
  1287.  * adapter and issues an rx_start.
  1288.  *
  1289.  * para virt virtual pointer to the fragment
  1290.  * len the length of the fragment
  1291.  * frame_status status of the frame, see design description
  1292.  *
  1293.  * NOTE: It is possible to call this function with a fragment length
  1294.  * of zero.
  1295.  *
  1296.  * END_MANUAL_ENTRY
  1297.  */
  1298. void hwm_rx_frag(smc,virt,phys,len,frame_status)
  1299. struct s_smc *smc ;
  1300. char far *virt ;
  1301. u_long phys ;
  1302. int len ;
  1303. int frame_status ;
  1304. {
  1305. struct s_smt_fp_rxd volatile *r ;
  1306. u_int rbctrl ;
  1307. NDD_TRACE("RHfB",virt,len,frame_status) ;
  1308. DB_RX("hwm_rx_frag: len = %d, frame_status = %xn",len,frame_status,2) ;
  1309. r = smc->hw.fp.rx_q[QUEUE_R1].rx_curr_put ;
  1310. r->rxd_virt = virt ;
  1311. r->rxd_rbadr = AIX_REVERSE(phys) ;
  1312. rbctrl = AIX_REVERSE( (((u_long)frame_status &
  1313. (FIRST_FRAG|LAST_FRAG))<<26) |
  1314. (((u_long) frame_status & FIRST_FRAG) << 21) |
  1315. BMU_OWN | BMU_CHECK | BMU_EN_IRQ_EOF | len) ;
  1316. r->rxd_rbctrl = rbctrl ;
  1317. DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ;
  1318. outpd(ADDR(B0_R1_CSR),CSR_START) ;
  1319. smc->hw.fp.rx_q[QUEUE_R1].rx_free-- ;
  1320. smc->hw.fp.rx_q[QUEUE_R1].rx_used++ ;
  1321. smc->hw.fp.rx_q[QUEUE_R1].rx_curr_put = r->rxd_next ;
  1322. NDD_TRACE("RHfE",r,AIX_REVERSE(r->rxd_rbadr),0) ;
  1323. }
  1324. #ifndef NDIS_OS2
  1325. /*
  1326.  * BEGIN_MANUAL_ENTRY(mac_drv_rx_frag)
  1327.  * int mac_drv_rx_frag(smc,virt,len)
  1328.  *
  1329.  * function DOWNCALL (hwmtm.c)
  1330.  * mac_drv_rx_frag fills the fragment with a part of the frame.
  1331.  *
  1332.  * para virt the virtual address of the fragment
  1333.  * len the length in bytes of the fragment
  1334.  *
  1335.  * return 0: success code, no errors possible
  1336.  *
  1337.  * END_MANUAL_ENTRY
  1338.  */
  1339. int mac_drv_rx_frag(smc,virt,len)
  1340. struct s_smc *smc ;
  1341. void far *virt ;
  1342. int len ;
  1343. {
  1344. NDD_TRACE("RHSB",virt,len,smc->os.hwm.r.mb_pos) ;
  1345. DB_RX("receive from queue: len/virt: = %d/%x",len,virt,4) ;
  1346. memcpy((char far *)virt,smc->os.hwm.r.mb_pos,len) ;
  1347. smc->os.hwm.r.mb_pos += len ;
  1348. NDD_TRACE("RHSE",smc->os.hwm.r.mb_pos,0,0) ;
  1349. return(0) ;
  1350. }
  1351. #endif
  1352. /*
  1353.  * BEGINN_MANUAL_ENTRY(mac_drv_clear_rx_queue)
  1354.  *
  1355.  * void mac_drv_clear_rx_queue(smc)
  1356.  * struct s_smc *smc ;
  1357.  *
  1358.  * function DOWNCALL (hardware module, hwmtm.c)
  1359.  * mac_drv_clear_rx_queue is called by the OS-specific module
  1360.  * after it has issued a card_stop.
  1361.  * In this case, the frames in the receive queue are obsolete and
  1362.  * should be removed. For removing mac_drv_clear_rx_queue
  1363.  * calls dma_master for each RxD and mac_drv_clear_rxd for each
  1364.  * receive buffer.
  1365.  *
  1366.  * NOTE: calling sequence card_stop:
  1367.  * CLI_FBI(), card_stop(),
  1368.  * mac_drv_clear_tx_queue(), mac_drv_clear_rx_queue(),
  1369.  *
  1370.  * NOTE: The caller is responsible that the BMUs are idle
  1371.  * when this function is called.
  1372.  *
  1373.  * END_MANUAL_ENTRY
  1374.  */
  1375. void mac_drv_clear_rx_queue(smc)
  1376. struct s_smc *smc ;
  1377. {
  1378. struct s_smt_fp_rxd volatile *r ;
  1379. struct s_smt_fp_rxd volatile *next_rxd ;
  1380. struct s_smt_rx_queue *queue ;
  1381. int frag_count ;
  1382. int i ;
  1383. if (smc->hw.hw_state != STOPPED) {
  1384. SK_BREAK() ;
  1385. SMT_PANIC(smc,HWM_E0012,HWM_E0012_MSG) ;
  1386. return ;
  1387. }
  1388. queue = smc->hw.fp.rx[QUEUE_R1] ;
  1389. DB_RX("clear_rx_queue",0,0,5) ;
  1390. /*
  1391.  * dma_complete and mac_drv_clear_rxd for all RxDs / receive buffers
  1392.  */
  1393. r = queue->rx_curr_get ;
  1394. while (queue->rx_used) {
  1395. DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
  1396. DB_RX("switch OWN bit of RxD 0x%x ",r,0,5) ;
  1397. r->rxd_rbctrl &= AIX_REVERSE(~BMU_OWN) ;
  1398. frag_count = 1 ;
  1399. DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ;
  1400. r = r->rxd_next ;
  1401. DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
  1402. while (r != queue->rx_curr_put &&
  1403. !(r->rxd_rbctrl & AIX_REVERSE(BMU_ST_BUF))) {
  1404. DB_RX("Check STF bit in %x",(void *)r,0,5) ;
  1405. r->rxd_rbctrl &= AIX_REVERSE(~BMU_OWN) ;
  1406. DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ;
  1407. r = r->rxd_next ;
  1408. DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
  1409. frag_count++ ;
  1410. }
  1411. DB_RX("STF bit found",0,0,5) ;
  1412. next_rxd = r ;
  1413. for (r=queue->rx_curr_get,i=frag_count; i ; r=r->rxd_next,i--){
  1414. DB_RX("dma_complete for RxD %x",(void *)r,0,5) ;
  1415. dma_complete(smc,(union s_fp_descr volatile *)r,DMA_WR);
  1416. }
  1417. DB_RX("mac_drv_clear_rxd: RxD %x frag_count %d ",
  1418. (void *)queue->rx_curr_get,frag_count,5) ;
  1419. mac_drv_clear_rxd(smc,queue->rx_curr_get,frag_count) ;
  1420. queue->rx_curr_get = next_rxd ;
  1421. queue->rx_used -= frag_count ;
  1422. queue->rx_free += frag_count ;
  1423. }
  1424. }
  1425. /*
  1426. -------------------------------------------------------------
  1427. SEND FUNCTIONS:
  1428. -------------------------------------------------------------
  1429. */
  1430. /*
  1431.  * BEGIN_MANUAL_ENTRY(hwm_tx_init)
  1432.  * int hwm_tx_init(smc,fc,frag_count,frame_len,frame_status)
  1433.  *
  1434.  * function DOWN_CALL (hardware module, hwmtm.c)
  1435.  * hwm_tx_init checks if the frame can be sent through the
  1436.  * corresponding send queue.
  1437.  *
  1438.  * para fc the frame control. To determine through which
  1439.  * send queue the frame should be transmitted.
  1440.  * 0x50 - 0x57: asynchronous LLC frame
  1441.  * 0xD0 - 0xD7: synchronous LLC frame
  1442.  * 0x41, 0x4F: SMT frame to the network
  1443.  * 0x42: SMT frame to the network and to the local SMT
  1444.  * 0x43: SMT frame to the local SMT
  1445.  * frag_count count of the fragments for this frame
  1446.  * frame_len length of the frame
  1447.  * frame_status status of the frame, the send queue bit is already
  1448.  * specified
  1449.  *
  1450.  * return frame_status
  1451.  *
  1452.  * END_MANUAL_ENTRY
  1453.  */
  1454. int hwm_tx_init(smc,fc,frag_count,frame_len,frame_status)
  1455. struct s_smc *smc ;
  1456. u_char fc ;
  1457. int frag_count ;
  1458. int frame_len ;
  1459. int frame_status ;
  1460. {
  1461. NDD_TRACE("THiB",fc,frag_count,frame_len) ;
  1462. smc->os.hwm.tx_p = smc->hw.fp.tx[frame_status & QUEUE_A0] ;
  1463. smc->os.hwm.tx_descr = TX_DESCRIPTOR | (((u_long)(frame_len-1)&3)<<27) ;
  1464. smc->os.hwm.tx_len = frame_len ;
  1465. DB_TX("hwm_tx_init: fc = %x, len = %d",fc,frame_len,3) ;
  1466. if ((fc & ~(FC_SYNC_BIT|FC_LLC_PRIOR)) == FC_ASYNC_LLC) {
  1467. frame_status |= LAN_TX ;
  1468. }
  1469. else {
  1470. switch (fc) {
  1471. case FC_SMT_INFO :
  1472. case FC_SMT_NSA :
  1473. frame_status |= LAN_TX ;
  1474. break ;
  1475. case FC_SMT_LOC :
  1476. frame_status |= LOC_TX ;
  1477. break ;
  1478. case FC_SMT_LAN_LOC :
  1479. frame_status |= LAN_TX | LOC_TX ;
  1480. break ;
  1481. default :
  1482. SMT_PANIC(smc,HWM_E0010,HWM_E0010_MSG) ;
  1483. }
  1484. }
  1485. if (!smc->hw.mac_ring_is_up) {
  1486. frame_status &= ~LAN_TX ;
  1487. frame_status |= RING_DOWN ;
  1488. DB_TX("Ring is down: terminate LAN_TX",0,0,2) ;
  1489. }
  1490. if (frag_count > smc->os.hwm.tx_p->tx_free) {
  1491. #ifndef NDIS_OS2
  1492. mac_drv_clear_txd(smc) ;
  1493. if (frag_count > smc->os.hwm.tx_p->tx_free) {
  1494. DB_TX("Out of TxDs, terminate LAN_TX",0,0,2) ;
  1495. frame_status &= ~LAN_TX ;
  1496. frame_status |= OUT_OF_TXD ;
  1497. }
  1498. #else
  1499. DB_TX("Out of TxDs, terminate LAN_TX",0,0,2) ;
  1500. frame_status &= ~LAN_TX ;
  1501. frame_status |= OUT_OF_TXD ;
  1502. #endif
  1503. }
  1504. DB_TX("frame_status = %x",frame_status,0,3) ;
  1505. NDD_TRACE("THiE",frame_status,smc->os.hwm.tx_p->tx_free,0) ;
  1506. return(frame_status) ;
  1507. }
  1508. /*
  1509.  * BEGIN_MANUAL_ENTRY(hwm_tx_frag)
  1510.  * void hwm_tx_frag(smc,virt,phys,len,frame_status)
  1511.  *
  1512.  * function DOWNCALL (hardware module, hwmtm.c)
  1513.  * If the frame should be sent to the LAN, this function calls
  1514.  * dma_master, fills the current TxD with the virtual and the
  1515.  * physical address, sets the STF and EOF bits dependent on
  1516.  * the frame status, and requests the BMU to start the
  1517.  * transmit.
  1518.  * If the frame should be sent to the local SMT, an SMT_MBuf
  1519.  * is allocated if the FIRST_FRAG bit is set in the frame_status.
  1520.  * The fragment of the frame is copied into the SMT MBuf.
  1521.  * The function smt_received_pack is called if the LAST_FRAG
  1522.  * bit is set in the frame_status word.
  1523.  *
  1524.  * para virt virtual pointer to the fragment
  1525.  * len the length of the fragment
  1526.  * frame_status status of the frame, see design description
  1527.  *
  1528.  * return nothing returned, no parameter is modified
  1529.  *
  1530.  * NOTE: It is possible to invoke this macro with a fragment length
  1531.  * of zero.
  1532.  *
  1533.  * END_MANUAL_ENTRY
  1534.  */
  1535. void hwm_tx_frag(smc,virt,phys,len,frame_status)
  1536. struct s_smc *smc ;
  1537. char far *virt ;
  1538. u_long phys ;
  1539. int len ;
  1540. int frame_status ;
  1541. {
  1542. struct s_smt_fp_txd volatile *t ;
  1543. struct s_smt_tx_queue *queue ;
  1544. u_int tbctrl ;
  1545. queue = smc->os.hwm.tx_p ;
  1546. NDD_TRACE("THfB",virt,len,frame_status) ;
  1547. /* Bug fix: AF / May 31 1999 (#missing)
  1548.  * snmpinfo problem reported by IBM is caused by invalid
  1549.  * t-pointer (txd) if LAN_TX is not set but LOC_TX only.
  1550.  * Set: t = queue->tx_curr_put  here !
  1551.  */
  1552. t = queue->tx_curr_put ;
  1553. DB_TX("hwm_tx_frag: len = %d, frame_status = %x ",len,frame_status,2) ;
  1554. if (frame_status & LAN_TX) {
  1555. /* '*t' is already defined */
  1556. DB_TX("LAN_TX: TxD = %x, virt = %x ",t,virt,3) ;
  1557. t->txd_virt = virt ;
  1558. t->txd_txdscr = AIX_REVERSE(smc->os.hwm.tx_descr) ;
  1559. t->txd_tbadr = AIX_REVERSE(phys) ;
  1560. tbctrl = AIX_REVERSE((((u_long)frame_status &
  1561. (FIRST_FRAG|LAST_FRAG|EN_IRQ_EOF))<< 26) |
  1562. BMU_OWN|BMU_CHECK |len) ;
  1563. t->txd_tbctrl = tbctrl ;
  1564. #ifndef AIX
  1565. DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
  1566. outpd(queue->tx_bmu_ctl,CSR_START) ;
  1567. #else /* ifndef AIX */
  1568. DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
  1569. if (frame_status & QUEUE_A0) {
  1570. outpd(ADDR(B0_XA_CSR),CSR_START) ;
  1571. }
  1572. else {
  1573. outpd(ADDR(B0_XS_CSR),CSR_START) ;
  1574. }
  1575. #endif
  1576. queue->tx_free-- ;
  1577. queue->tx_used++ ;
  1578. queue->tx_curr_put = t->txd_next ;
  1579. if (frame_status & LAST_FRAG) {
  1580. smc->mib.m[MAC0].fddiMACTransmit_Ct++ ;
  1581. }
  1582. }
  1583. if (frame_status & LOC_TX) {
  1584. DB_TX("LOC_TX: ",0,0,3) ;
  1585. if (frame_status & FIRST_FRAG) {
  1586. if(!(smc->os.hwm.tx_mb = smt_get_mbuf(smc))) {
  1587. smc->hw.fp.err_stats.err_no_buf++ ;
  1588. DB_TX("No SMbuf; transmit terminated",0,0,4) ;
  1589. }
  1590. else {
  1591. smc->os.hwm.tx_data =
  1592. smtod(smc->os.hwm.tx_mb,char *) - 1 ;
  1593. #ifdef USE_OS_CPY
  1594. #ifdef PASS_1ST_TXD_2_TX_COMP
  1595. hwm_cpy_txd2mb(t,smc->os.hwm.tx_data,
  1596. smc->os.hwm.tx_len) ;
  1597. #endif
  1598. #endif
  1599. }
  1600. }
  1601. if (smc->os.hwm.tx_mb) {
  1602. #ifndef USE_OS_CPY
  1603. DB_TX("copy fragment into MBuf ",0,0,3) ;
  1604. memcpy(smc->os.hwm.tx_data,virt,len) ;
  1605. smc->os.hwm.tx_data += len ;
  1606. #endif
  1607. if (frame_status & LAST_FRAG) {
  1608. #ifdef USE_OS_CPY
  1609. #ifndef PASS_1ST_TXD_2_TX_COMP
  1610. /*
  1611.  * hwm_cpy_txd2mb(txd,data,len) copies 'len' 
  1612.  * bytes from the virtual pointer in 'rxd'
  1613.  * to 'data'. The virtual pointer of the 
  1614.  * os-specific tx-buffer should be written
  1615.  * in the LAST txd.
  1616.  */ 
  1617. hwm_cpy_txd2mb(t,smc->os.hwm.tx_data,
  1618. smc->os.hwm.tx_len) ;
  1619. #endif /* nPASS_1ST_TXD_2_TX_COMP */
  1620. #endif /* USE_OS_CPY */
  1621. smc->os.hwm.tx_data =
  1622. smtod(smc->os.hwm.tx_mb,char *) - 1 ;
  1623. *(char *)smc->os.hwm.tx_mb->sm_data =
  1624. *smc->os.hwm.tx_data ;
  1625. smc->os.hwm.tx_data++ ;
  1626. smc->os.hwm.tx_mb->sm_len =
  1627. smc->os.hwm.tx_len - 1 ;
  1628. DB_TX("pass LLC frame to SMT ",0,0,3) ;
  1629. smt_received_pack(smc,smc->os.hwm.tx_mb,
  1630. RD_FS_LOCAL) ;
  1631. }
  1632. }
  1633. }
  1634. NDD_TRACE("THfE",t,queue->tx_free,0) ;
  1635. }
  1636. /*
  1637.  * queues a receive for later send
  1638.  */
  1639. static void queue_llc_rx(smc,mb)
  1640. struct s_smc *smc ;
  1641. SMbuf *mb ;
  1642. {
  1643. DB_GEN("queue_llc_rx: mb = %x",(void *)mb,0,4) ;
  1644. smc->os.hwm.queued_rx_frames++ ;
  1645. mb->sm_next = (SMbuf *)NULL ;
  1646. if (smc->os.hwm.llc_rx_pipe == 0) {
  1647. smc->os.hwm.llc_rx_pipe = mb ;
  1648. }
  1649. else {
  1650. smc->os.hwm.llc_rx_tail->sm_next = mb ;
  1651. }
  1652. smc->os.hwm.llc_rx_tail = mb ;
  1653. /*
  1654.  * force an timer IRQ to receive the data
  1655.  */
  1656. if (!smc->os.hwm.isr_flag) {
  1657. smt_force_irq(smc) ;
  1658. }
  1659. }
  1660. /*
  1661.  * get a SMbuf from the llc_rx_queue
  1662.  */
  1663. static SMbuf *get_llc_rx(smc)
  1664. struct s_smc *smc ;
  1665. {
  1666. SMbuf *mb ;
  1667. if ((mb = smc->os.hwm.llc_rx_pipe)) {
  1668. smc->os.hwm.queued_rx_frames-- ;
  1669. smc->os.hwm.llc_rx_pipe = mb->sm_next ;
  1670. }
  1671. DB_GEN("get_llc_rx: mb = 0x%x",(void *)mb,0,4) ;
  1672. return(mb) ;
  1673. }
  1674. /*
  1675.  * queues a transmit SMT MBuf during the time were the MBuf is
  1676.  * queued the TxD ring
  1677.  */
  1678. static void queue_txd_mb(smc,mb)
  1679. struct s_smc *smc ;
  1680. SMbuf *mb ;
  1681. {
  1682. DB_GEN("_rx: queue_txd_mb = %x",(void *)mb,0,4) ;
  1683. smc->os.hwm.queued_txd_mb++ ;
  1684. mb->sm_next = (SMbuf *)NULL ;
  1685. if (smc->os.hwm.txd_tx_pipe == 0) {
  1686. smc->os.hwm.txd_tx_pipe = mb ;
  1687. }
  1688. else {
  1689. smc->os.hwm.txd_tx_tail->sm_next = mb ;
  1690. }
  1691. smc->os.hwm.txd_tx_tail = mb ;
  1692. }
  1693. /*
  1694.  * get a SMbuf from the txd_tx_queue
  1695.  */
  1696. static SMbuf *get_txd_mb(smc)
  1697. struct s_smc *smc ;
  1698. {
  1699. SMbuf *mb ;
  1700. if ((mb = smc->os.hwm.txd_tx_pipe)) {
  1701. smc->os.hwm.queued_txd_mb-- ;
  1702. smc->os.hwm.txd_tx_pipe = mb->sm_next ;
  1703. }
  1704. DB_GEN("get_txd_mb: mb = 0x%x",(void *)mb,0,4) ;
  1705. return(mb) ;
  1706. }
  1707. /*
  1708.  * SMT Send function
  1709.  */
  1710. void smt_send_mbuf(smc,mb,fc)
  1711. struct s_smc *smc;
  1712. SMbuf *mb;
  1713. int fc;
  1714. {
  1715. char far *data ;
  1716. int len ;
  1717. int n ;
  1718. int i ;
  1719. int frag_count ;
  1720. int frame_status ;
  1721. SK_LOC_DECL(char far,*virt[3]) ;
  1722. int frag_len[3] ;
  1723. struct s_smt_tx_queue *queue ;
  1724. struct s_smt_fp_txd volatile *t ;
  1725. u_long phys ;
  1726. u_int tbctrl ;
  1727. NDD_TRACE("THSB",mb,fc,0) ;
  1728. DB_TX("smt_send_mbuf: mb = 0x%x, fc = 0x%x",mb,fc,4) ;
  1729. mb->sm_off-- ; /* set to fc */
  1730. mb->sm_len++ ; /* + fc */
  1731. data = smtod(mb,char *) ;
  1732. *data = fc ;
  1733. if (fc == FC_SMT_LOC)
  1734. *data = FC_SMT_INFO ;
  1735. /*
  1736.  * determine the frag count and the virt addresses of the frags
  1737.  */
  1738. frag_count = 0 ;
  1739. len = mb->sm_len ;
  1740. while (len) {
  1741. n = SMT_PAGESIZE - ((long)data & (SMT_PAGESIZE-1)) ;
  1742. if (n >= len) {
  1743. n = len ;
  1744. }
  1745. DB_TX("frag: virt/len = 0x%x/%d ",(void *)data,n,5) ;
  1746. virt[frag_count] = data ;
  1747. frag_len[frag_count] = n ;
  1748. frag_count++ ;
  1749. len -= n ;
  1750. data += n ;
  1751. }
  1752. /*
  1753.  * determine the frame status
  1754.  */
  1755. queue = smc->hw.fp.tx[QUEUE_A0] ;
  1756. if (fc == FC_BEACON || fc == FC_SMT_LOC) {
  1757. frame_status = LOC_TX ;
  1758. }
  1759. else {
  1760. frame_status = LAN_TX ;
  1761. if ((smc->os.hwm.pass_NSA &&(fc == FC_SMT_NSA)) ||
  1762.    (smc->os.hwm.pass_SMT &&(fc == FC_SMT_INFO)))
  1763. frame_status |= LOC_TX ;
  1764. }
  1765. if (!smc->hw.mac_ring_is_up || frag_count > queue->tx_free) {
  1766. if (frame_status &= ~LAN_TX) {
  1767. DB_TX("Ring is down: terminate LAN_TX",0,0,2) ;
  1768. }
  1769. else {
  1770. DB_TX("Ring is down: terminate transmission",0,0,2) ;
  1771. smt_free_mbuf(smc,mb) ;
  1772. return ;
  1773. }
  1774. }
  1775. DB_TX("frame_status = 0x%x ",frame_status,0,5) ;
  1776. if ((frame_status & LAN_TX) && (frame_status & LOC_TX)) {
  1777. mb->sm_use_count = 2 ;
  1778. }
  1779. if (frame_status & LAN_TX) {
  1780. t = queue->tx_curr_put ;
  1781. frame_status |= FIRST_FRAG ;
  1782. for (i = 0; i < frag_count; i++) {
  1783. DB_TX("init TxD = 0x%x",(void *)t,0,5) ;
  1784. if (i == frag_count-1) {
  1785. frame_status |= LAST_FRAG ;
  1786. t->txd_txdscr = AIX_REVERSE(TX_DESCRIPTOR |
  1787. (((u_long)(mb->sm_len-1)&3) << 27)) ;
  1788. }
  1789. t->txd_virt = virt[i] ;
  1790. phys = dma_master(smc, (void far *)virt[i],
  1791. frag_len[i], DMA_RD|SMT_BUF) ;
  1792. t->txd_tbadr = AIX_REVERSE(phys) ;
  1793. tbctrl = AIX_REVERSE((((u_long) frame_status &
  1794. (FIRST_FRAG|LAST_FRAG)) << 26) |
  1795. BMU_OWN | BMU_CHECK | BMU_SMT_TX |frag_len[i]) ;
  1796. t->txd_tbctrl = tbctrl ;
  1797. #ifndef AIX
  1798. DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
  1799. outpd(queue->tx_bmu_ctl,CSR_START) ;
  1800. #else
  1801. DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
  1802. outpd(ADDR(B0_XA_CSR),CSR_START) ;
  1803. #endif
  1804. frame_status &= ~FIRST_FRAG ;
  1805. queue->tx_curr_put = t = t->txd_next ;
  1806. queue->tx_free-- ;
  1807. queue->tx_used++ ;
  1808. }
  1809. smc->mib.m[MAC0].fddiMACTransmit_Ct++ ;
  1810. queue_txd_mb(smc,mb) ;
  1811. }
  1812. if (frame_status & LOC_TX) {
  1813. DB_TX("pass Mbuf to LLC queue",0,0,5) ;
  1814. queue_llc_rx(smc,mb) ;
  1815. }
  1816. /*
  1817.  * We need to unqueue the free SMT_MBUFs here, because it may
  1818.  * be that the SMT want's to send more than 1 frame for one down call
  1819.  */
  1820. mac_drv_clear_txd(smc) ;
  1821. NDD_TRACE("THSE",t,queue->tx_free,frag_count) ;
  1822. }
  1823. /* BEGIN_MANUAL_ENTRY(mac_drv_clear_txd)
  1824.  * void mac_drv_clear_txd(smc)
  1825.  *
  1826.  * function DOWNCALL (hardware module, hwmtm.c)
  1827.  * mac_drv_clear_txd searches in both send queues for TxD's
  1828.  * which were finished by the adapter. It calls dma_complete
  1829.  * for each TxD. If the last fragment of an LLC frame is
  1830.  * reached, it calls mac_drv_tx_complete to release the
  1831.  * send buffer.
  1832.  *
  1833.  * return nothing
  1834.  *
  1835.  * END_MANUAL_ENTRY
  1836.  */
  1837. void mac_drv_clear_txd(smc)
  1838. struct s_smc *smc ;
  1839. {
  1840. struct s_smt_tx_queue *queue ;
  1841. struct s_smt_fp_txd volatile *t1 ;
  1842. struct s_smt_fp_txd volatile *t2=0 ;
  1843. SMbuf *mb ;
  1844. u_long tbctrl ;
  1845. int i ;
  1846. int frag_count ;
  1847. int n ;
  1848. NDD_TRACE("THcB",0,0,0) ;
  1849. for (i = QUEUE_S; i <= QUEUE_A0; i++) {
  1850. queue = smc->hw.fp.tx[i] ;
  1851. t1 = queue->tx_curr_get ;
  1852. DB_TX("clear_txd: QUEUE = %d (0=sync/1=async)",i,0,5) ;
  1853. for ( ; ; ) {
  1854. frag_count = 0 ;
  1855. do {
  1856. DRV_BUF_FLUSH(t1,DDI_DMA_SYNC_FORCPU) ;
  1857. DB_TX("check OWN/EOF bit of TxD 0x%x",t1,0,5) ;
  1858. tbctrl = CR_READ(t1->txd_tbctrl) ;
  1859. tbctrl = AIX_REVERSE(tbctrl) ;
  1860. if (tbctrl & BMU_OWN || !queue->tx_used){
  1861. DB_TX("End of TxDs queue %d",i,0,4) ;
  1862. goto free_next_queue ; /* next queue */
  1863. }
  1864. t1 = t1->txd_next ;
  1865. frag_count++ ;
  1866. } while (!(tbctrl & BMU_EOF)) ;
  1867. t1 = queue->tx_curr_get ;
  1868. for (n = frag_count; n; n--) {
  1869. tbctrl = AIX_REVERSE(t1->txd_tbctrl) ;
  1870. dma_complete(smc,
  1871. (union s_fp_descr volatile *) t1,
  1872. (int) (DMA_RD |
  1873. ((tbctrl & BMU_SMT_TX) >> 18))) ;
  1874. t2 = t1 ;
  1875. t1 = t1->txd_next ;
  1876. }
  1877. if (tbctrl & BMU_SMT_TX) {
  1878. mb = get_txd_mb(smc) ;
  1879. smt_free_mbuf(smc,mb) ;
  1880. }
  1881. else {
  1882. #ifndef PASS_1ST_TXD_2_TX_COMP
  1883. DB_TX("mac_drv_tx_comp for TxD 0x%x",t2,0,4) ;
  1884. mac_drv_tx_complete(smc,t2) ;
  1885. #else
  1886. DB_TX("mac_drv_tx_comp for TxD 0x%x",
  1887. queue->tx_curr_get,0,4) ;
  1888. mac_drv_tx_complete(smc,queue->tx_curr_get) ;
  1889. #endif
  1890. }
  1891. queue->tx_curr_get = t1 ;
  1892. queue->tx_free += frag_count ;
  1893. queue->tx_used -= frag_count ;
  1894. }
  1895. free_next_queue: ;
  1896. }
  1897. NDD_TRACE("THcE",0,0,0) ;
  1898. }
  1899. /*
  1900.  * BEGINN_MANUAL_ENTRY(mac_drv_clear_tx_queue)
  1901.  *
  1902.  * void mac_drv_clear_tx_queue(smc)
  1903.  * struct s_smc *smc ;
  1904.  *
  1905.  * function DOWNCALL (hardware module, hwmtm.c)
  1906.  * mac_drv_clear_tx_queue is called from the SMT when
  1907.  * the RMT state machine has entered the ISOLATE state.
  1908.  * This function is also called by the os-specific module
  1909.  * after it has called the function card_stop().
  1910.  * In this case, the frames in the send queues are obsolete and
  1911.  * should be removed.
  1912.  *
  1913.  * note calling sequence:
  1914.  * CLI_FBI(), card_stop(),
  1915.  * mac_drv_clear_tx_queue(), mac_drv_clear_rx_queue(),
  1916.  *
  1917.  * NOTE: The caller is responsible that the BMUs are idle
  1918.  * when this function is called.
  1919.  *
  1920.  * END_MANUAL_ENTRY
  1921.  */
  1922. void mac_drv_clear_tx_queue(smc)
  1923. struct s_smc *smc ;
  1924. {
  1925. struct s_smt_fp_txd volatile *t ;
  1926. struct s_smt_tx_queue *queue ;
  1927. int tx_used ;
  1928. int i ;
  1929. if (smc->hw.hw_state != STOPPED) {
  1930. SK_BREAK() ;
  1931. SMT_PANIC(smc,HWM_E0011,HWM_E0011_MSG) ;
  1932. return ;
  1933. }
  1934. for (i = QUEUE_S; i <= QUEUE_A0; i++) {
  1935. queue = smc->hw.fp.tx[i] ;
  1936. DB_TX("clear_tx_queue: QUEUE = %d (0=sync/1=async)",i,0,5) ;
  1937. /*
  1938.  * switch the OWN bit of all pending frames to the host
  1939.  */
  1940. t = queue->tx_curr_get ;
  1941. tx_used = queue->tx_used ;
  1942. while (tx_used) {
  1943. DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORCPU) ;
  1944. DB_TX("switch OWN bit of TxD 0x%x ",t,0,5) ;
  1945. t->txd_tbctrl &= AIX_REVERSE(~BMU_OWN) ;
  1946. DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
  1947. t = t->txd_next ;
  1948. tx_used-- ;
  1949. }
  1950. }
  1951. /*
  1952.  * release all TxD's for both send queues
  1953.  */
  1954. mac_drv_clear_txd(smc) ;
  1955. for (i = QUEUE_S; i <= QUEUE_A0; i++) {
  1956. queue = smc->hw.fp.tx[i] ;
  1957. t = queue->tx_curr_get ;
  1958. /*
  1959.  * write the phys pointer of the NEXT descriptor into the
  1960.  * BMU's current address descriptor pointer and set
  1961.  * tx_curr_get and tx_curr_put to this position
  1962.  */
  1963. if (i == QUEUE_S) {
  1964. outpd(ADDR(B5_XS_DA),AIX_REVERSE(t->txd_ntdadr)) ;
  1965. }
  1966. else {
  1967. outpd(ADDR(B5_XA_DA),AIX_REVERSE(t->txd_ntdadr)) ;
  1968. }
  1969. queue->tx_curr_put = queue->tx_curr_get->txd_next ;
  1970. queue->tx_curr_get = queue->tx_curr_put ;
  1971. }
  1972. }
  1973. /*
  1974. -------------------------------------------------------------
  1975. TEST FUNCTIONS:
  1976. -------------------------------------------------------------
  1977. */
  1978. #ifdef DEBUG
  1979. /*
  1980.  * BEGIN_MANUAL_ENTRY(mac_drv_debug_lev)
  1981.  * void mac_drv_debug_lev(smc,flag,lev)
  1982.  *
  1983.  * function DOWNCALL (drvsr.c)
  1984.  * To get a special debug info the user can assign a debug level
  1985.  * to any debug flag.
  1986.  *
  1987.  * para flag debug flag, possible values are:
  1988.  * = 0: reset all debug flags (the defined level is
  1989.  * ignored)
  1990.  * = 1: debug.d_smtf
  1991.  * = 2: debug.d_smt
  1992.  * = 3: debug.d_ecm
  1993.  * = 4: debug.d_rmt
  1994.  * = 5: debug.d_cfm
  1995.  * = 6: debug.d_pcm
  1996.  *
  1997.  * = 10: debug.d_os.hwm_rx (hardware module receive path)
  1998.  * = 11: debug.d_os.hwm_tx(hardware module transmit path)
  1999.  * = 12: debug.d_os.hwm_gen(hardware module general flag)
  2000.  *
  2001.  * lev debug level
  2002.  *
  2003.  * END_MANUAL_ENTRY
  2004.  */
  2005. void mac_drv_debug_lev(smc,flag,lev)
  2006. struct s_smc *smc ;
  2007. int flag ;
  2008. int lev ;
  2009. {
  2010. switch(flag) {
  2011. case (int)NULL:
  2012. DB_P.d_smtf = DB_P.d_smt = DB_P.d_ecm = DB_P.d_rmt = 0 ;
  2013. DB_P.d_cfm = 0 ;
  2014. DB_P.d_os.hwm_rx = DB_P.d_os.hwm_tx = DB_P.d_os.hwm_gen = 0 ;
  2015. #ifdef SBA
  2016. DB_P.d_sba = 0 ;
  2017. #endif
  2018. #ifdef ESS
  2019. DB_P.d_ess = 0 ;
  2020. #endif
  2021. break ;
  2022. case DEBUG_SMTF:
  2023. DB_P.d_smtf = lev ;
  2024. break ;
  2025. case DEBUG_SMT:
  2026. DB_P.d_smt = lev ;
  2027. break ;
  2028. case DEBUG_ECM:
  2029. DB_P.d_ecm = lev ;
  2030. break ;
  2031. case DEBUG_RMT:
  2032. DB_P.d_rmt = lev ;
  2033. break ;
  2034. case DEBUG_CFM:
  2035. DB_P.d_cfm = lev ;
  2036. break ;
  2037. case DEBUG_PCM:
  2038. DB_P.d_pcm = lev ;
  2039. break ;
  2040. case DEBUG_SBA:
  2041. #ifdef SBA
  2042. DB_P.d_sba = lev ;
  2043. #endif
  2044. break ;
  2045. case DEBUG_ESS:
  2046. #ifdef ESS
  2047. DB_P.d_ess = lev ;
  2048. #endif
  2049. break ;
  2050. case DB_HWM_RX:
  2051. DB_P.d_os.hwm_rx = lev ;
  2052. break ;
  2053. case DB_HWM_TX:
  2054. DB_P.d_os.hwm_tx = lev ;
  2055. break ;
  2056. case DB_HWM_GEN:
  2057. DB_P.d_os.hwm_gen = lev ;
  2058. break ;
  2059. default:
  2060. break ;
  2061. }
  2062. }
  2063. #endif