Subversion Repositories HelenOS

Rev

Rev 4192 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 1987,1997, 2006, Vrije Universiteit, Amsterdam, The Netherlands All rights reserved. Redistribution and use of the MINIX 3 operating system in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  3.  *
  4.  * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  5.  * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  6.  * * Neither the name of the Vrije Universiteit nor the names of the software authors or contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  7.  * * Any deviations from these conditions require written permission from the copyright holder in advance
  8.  *
  9.  *
  10.  * Disclaimer
  11.  *
  12.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
  13.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  14.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  15.  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  17.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  18.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  19.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  20.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  21.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22.  *
  23.  * Changes:
  24.  *  2009 Lukas Medjrech ported to HelenOS
  25.  */
  26.  
  27. /** @addtogroup dp8390
  28.  *  @{
  29.  */
  30.  
  31. #include <assert.h>
  32.  
  33. #include <errno.h>
  34.  
  35. #include "../../include/byteorder.h"
  36.  
  37. #include "dp8390_drv.h"
  38. #include "dp8390_port.h"
  39.  
  40. /*
  41.  * dp8390.c
  42.  *
  43.  * Created: before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
  44.  *
  45.  * Modified Mar 10 1994 by Philip Homburg
  46.  *  Become a generic dp8390 driver.
  47.  *
  48.  * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>
  49.  *  Added support for 3c503 boards.
  50.  */
  51.  
  52. #include "local.h"
  53. #include "dp8390.h"
  54.  
  55. //static u16_t eth_ign_proto;
  56. //static char *progname;
  57.  
  58. /* Configuration */
  59. /*typedef struct dp_conf
  60. {
  61.     port_t dpc_port;
  62.     int dpc_irq;
  63.     phys_bytes dpc_mem;
  64.     char *dpc_envvar;
  65. } dp_conf_t;
  66. */
  67. //dp_conf_t dp_conf[]=  /* Card addresses */
  68. //{
  69.     /* I/O port, IRQ,  Buffer address,  Env. var. */
  70. /*  {  0x280,     3,    0xD0000,        "DPETH0"    },
  71.     {  0x300,     5,    0xC8000,        "DPETH1"    },
  72.     {  0x380,    10,    0xD8000,        "DPETH2"    },
  73. };
  74. */
  75. /* Test if dp_conf has exactly DE_PORT_NR entries.  If not then you will see
  76.  * the error: "array size is negative".
  77.  */
  78. //extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1];
  79.  
  80. /* Card inits configured out? */
  81. #if !ENABLE_WDETH
  82. #define wdeth_probe(dep)    (0)
  83. #endif
  84. #if !ENABLE_NE2000
  85. #define ne_probe(dep)       (0)
  86. #endif
  87. #if !ENABLE_3C503
  88. #define el2_probe(dep)      (0)
  89. #endif
  90.  
  91. /* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
  92.  * on writes to the CR register. Additional CR_STAs do not appear to hurt
  93.  * genuine dp8390s
  94.  */
  95. #define CR_EXTRA    CR_STA
  96.  
  97. //#if ENABLE_PCI
  98. //_PROTOTYPE( static void pci_conf, (void)              );
  99. //#endif
  100. //_PROTOTYPE( static void do_vwrite, (message *mp, int from_int,
  101. //                          int vectored)   );
  102. //_PROTOTYPE( static void do_vwrite_s, (message *mp, int from_int)  );
  103. //_PROTOTYPE( static void do_vread, (message *mp, int vectored)     );
  104. //_PROTOTYPE( static void do_vread_s, (message *mp)         );
  105. //_PROTOTYPE( static void do_init, (message *mp)                );
  106. //_PROTOTYPE( static void do_int, (dpeth_t *dep)                );
  107. //_PROTOTYPE( static void do_getstat, (message *mp)         );
  108. //_PROTOTYPE( static void do_getstat_s, (message *mp)           );
  109. //_PROTOTYPE( static void do_getname, (message *mp)         );
  110. //_PROTOTYPE( static void do_stop, (message *mp)                );
  111. _PROTOTYPE( static void dp_init, (dpeth_t *dep)             );
  112. //_PROTOTYPE( static void dp_confaddr, (dpeth_t *dep)           );
  113. _PROTOTYPE( static void dp_reinit, (dpeth_t *dep)           );
  114. _PROTOTYPE( static void dp_reset, (dpeth_t *dep)            );
  115. //_PROTOTYPE( static void dp_check_ints, (dpeth_t *dep)         );
  116. _PROTOTYPE( static void dp_recv, (dpeth_t *dep)             );
  117. _PROTOTYPE( static void dp_send, (dpeth_t *dep)             );
  118. //_PROTOTYPE( static void dp8390_stop, (void)               );
  119. _PROTOTYPE( static void dp_getblock, (dpeth_t *dep, int page,
  120.                 size_t offset, size_t size, void *dst)  );
  121. //_PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page,
  122. //              size_t offset, size_t size, void *dst)  );
  123. //_PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page,
  124. //              size_t offset, size_t size, void *dst)  );
  125. _PROTOTYPE( static int dp_pkt2user, (dpeth_t *dep, int page,
  126.                             int length) );
  127. //_PROTOTYPE( static int dp_pkt2user_s, (dpeth_t *dep, int page,
  128. //                          int length) );
  129. //_PROTOTYPE( static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp,
  130. //      vir_bytes offset, int nic_addr, vir_bytes count)    );
  131. //_PROTOTYPE( static void dp_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp,
  132. //      vir_bytes offset, int nic_addr, vir_bytes count)    );
  133. //_PROTOTYPE( static void dp_pio8_user2nic, (dpeth_t *dep,
  134. //              iovec_dat_t *iovp, vir_bytes offset,
  135. //              int nic_addr, vir_bytes count)      );
  136. //_PROTOTYPE( static void dp_pio8_user2nic_s, (dpeth_t *dep,
  137. //              iovec_dat_s_t *iovp, vir_bytes offset,
  138. //              int nic_addr, vir_bytes count)      );
  139. //_PROTOTYPE( static void dp_pio16_user2nic, (dpeth_t *dep,
  140. //              iovec_dat_t *iovp, vir_bytes offset,
  141. //              int nic_addr, vir_bytes count)      );
  142. //_PROTOTYPE( static void dp_pio16_user2nic_s, (dpeth_t *dep,
  143. //              iovec_dat_s_t *iovp, vir_bytes offset,
  144. //              int nic_addr, vir_bytes count)      );
  145. _PROTOTYPE( static void dp_nic2user, (dpeth_t *dep, int nic_addr,
  146.         iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
  147. //_PROTOTYPE( static void dp_nic2user_s, (dpeth_t *dep, int nic_addr,
  148. //      iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
  149. //_PROTOTYPE( static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr,
  150. //      iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
  151. //_PROTOTYPE( static void dp_pio8_nic2user_s, (dpeth_t *dep, int nic_addr,
  152. //      iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
  153. //_PROTOTYPE( static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr,
  154. //      iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
  155. //_PROTOTYPE( static void dp_pio16_nic2user_s, (dpeth_t *dep, int nic_addr,
  156. //      iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
  157. //_PROTOTYPE( static void dp_next_iovec, (iovec_dat_t *iovp)        );
  158. //_PROTOTYPE( static void dp_next_iovec_s, (iovec_dat_s_t *iovp)        );
  159. _PROTOTYPE( static void conf_hw, (dpeth_t *dep)             );
  160. //_PROTOTYPE( static void update_conf, (dpeth_t *dep, dp_conf_t *dcp)   );
  161. _PROTOTYPE( static void map_hw_buffer, (dpeth_t *dep)           );
  162. //_PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp)       );
  163. //_PROTOTYPE( static int calc_iovec_size_s, (iovec_dat_s_t *iovp)       );
  164. _PROTOTYPE( static void reply, (dpeth_t *dep, int err, int may_block)   );
  165. //_PROTOTYPE( static void mess_reply, (message *req, message *reply)    );
  166. //_PROTOTYPE( static void get_userdata, (int user_proc,
  167. //      vir_bytes user_addr, vir_bytes count, void *loc_addr)   );
  168. //_PROTOTYPE( static void get_userdata_s, (int user_proc,
  169. //      cp_grant_id_t grant, vir_bytes offset, vir_bytes count,
  170. //      void *loc_addr) );
  171. //_PROTOTYPE( static void put_userdata, (int user_proc,
  172. //      vir_bytes user_addr, vir_bytes count, void *loc_addr)   );
  173. //_PROTOTYPE( static void put_userdata_s, (int user_proc,
  174. //      cp_grant_id_t grant, size_t count, void *loc_addr)  );
  175. //_PROTOTYPE( static void insb, (port_t port, void *buf, size_t size)               );
  176. //_PROTOTYPE( static void insw, (port_t port, void *buf, size_t size)               );
  177. //_PROTOTYPE( static void do_vir_insb, (port_t port, int proc,
  178. //                  vir_bytes buf, size_t size) );
  179. //_PROTOTYPE( static void do_vir_insw, (port_t port, int proc,
  180. //                  vir_bytes buf, size_t size) );
  181. //_PROTOTYPE( static void do_vir_outsb, (port_t port, int proc,
  182. //                  vir_bytes buf, size_t size) );
  183. //_PROTOTYPE( static void do_vir_outsw, (port_t port, int proc,
  184. //                  vir_bytes buf, size_t size) );
  185.  
  186. int do_probe( dpeth_t * dep ){
  187.     /* This is the default, try to (re)locate the device. */
  188.     conf_hw(dep);
  189.     if (dep->de_mode == DEM_DISABLED)
  190.     {
  191.         /* Probe failed, or the device is configured off. */
  192.         return EXDEV;//ENXIO;
  193.     }
  194.     if (dep->de_mode == DEM_ENABLED)
  195.         dp_init(dep);
  196.     return EOK;
  197. }
  198.  
  199. /*===========================================================================*
  200.  *              do_init                      *
  201.  *===========================================================================*/
  202. int do_init( dpeth_t * dep, int mode ){
  203.     if (dep->de_mode == DEM_DISABLED)
  204.     {
  205.         // might call do_probe()
  206.         return EXDEV;
  207.     }
  208.  
  209.     if (dep->de_mode == DEM_SINK)
  210.     {
  211. //      strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
  212. //      dep->de_address.ea_addr[5] = port;
  213. //      dp_confaddr(dep);
  214.         //TODO ether address?
  215. //      reply_mess.m_type = DL_CONF_REPLY;
  216. //      reply_mess.m3_i1 = mp->DL_PORT;
  217. //      reply_mess.m3_i2 = DE_PORT_NR;
  218. //      *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
  219. //      mess_reply(mp, &reply_mess);
  220. //      return;
  221.         return EOK;
  222.     }
  223.     //TODO assert?
  224.     assert(dep->de_mode == DEM_ENABLED);
  225.     assert(dep->de_flags & DEF_ENABLED);
  226.  
  227.     dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
  228.  
  229.     if (mode & DL_PROMISC_REQ)
  230.         dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
  231.     if (mode & DL_MULTI_REQ)
  232.         dep->de_flags |= DEF_MULTI;
  233.     if (mode & DL_BROAD_REQ)
  234.         dep->de_flags |= DEF_BROAD;
  235.  
  236. //  dep->de_client = mp->m_source;
  237.     dp_reinit(dep);
  238.  
  239.     //TODO ether address?
  240. //  reply_mess.m_type = DL_CONF_REPLY;
  241. //  reply_mess.m3_i1 = mp->DL_PORT;
  242. //  reply_mess.m3_i2 = DE_PORT_NR;
  243. //  *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
  244.  
  245. //  mess_reply(mp, &reply_mess);
  246.     return EOK;
  247. }
  248.  
  249. /*===========================================================================*
  250.  *              do_stop                      *
  251.  *===========================================================================*/
  252. void do_stop( dpeth_t * dep ){
  253.     if(( dep->de_mode != DEM_SINK ) && ( dep->de_mode == DEM_ENABLED ) && ( dep->de_flags & DEF_ENABLED )){
  254.         outb_reg0( dep, DP_CR, CR_STP | CR_DM_ABORT );
  255.         ( dep->de_stopf )( dep );
  256.  
  257.         dep->de_flags = DEF_EMPTY;
  258.     }
  259. }
  260.  
  261. /*===========================================================================*
  262.  *              dp_init                      *
  263.  *===========================================================================*/
  264. void dp_init(dep)
  265. dpeth_t *dep;
  266. {
  267.     int dp_rcr_reg;
  268.     int i;//, r;
  269.  
  270.     /* General initialization */
  271.     dep->de_flags = DEF_EMPTY;
  272.     (*dep->de_initf)(dep);
  273.  
  274. //  dp_confaddr(dep);
  275.  
  276.     if (debug)
  277.     {
  278.         printf("%s: Ethernet address ", dep->de_name);
  279.         for (i= 0; i < 6; i++)
  280.             printf("%x%c", dep->de_address.ea_addr[i],
  281.                             i < 5 ? ':' : '\n');
  282.     }
  283.  
  284.     /* Map buffer */
  285.     map_hw_buffer(dep);
  286.  
  287.     /* Initialization of the dp8390 following the mandatory procedure
  288.      * in reference manual ("DP8390D/NS32490D NIC Network Interface
  289.      * Controller", National Semiconductor, July 1995, Page 29).
  290.      */
  291.     /* Step 1: */
  292.     outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
  293.     /* Step 2: */
  294.     if (dep->de_16bit)
  295.         outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
  296.     else
  297.         outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
  298.     /* Step 3: */
  299.     outb_reg0(dep, DP_RBCR0, 0);
  300.     outb_reg0(dep, DP_RBCR1, 0);
  301.     /* Step 4: */
  302.     dp_rcr_reg = 0;
  303.     if (dep->de_flags & DEF_PROMISC)
  304.         dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
  305.     if (dep->de_flags & DEF_BROAD)
  306.         dp_rcr_reg |= RCR_AB;
  307.     if (dep->de_flags & DEF_MULTI)
  308.         dp_rcr_reg |= RCR_AM;
  309.     outb_reg0(dep, DP_RCR, dp_rcr_reg);
  310.     /* Step 5: */
  311.     outb_reg0(dep, DP_TCR, TCR_INTERNAL);
  312.     /* Step 6: */
  313.     outb_reg0(dep, DP_BNRY, dep->de_startpage);
  314.     outb_reg0(dep, DP_PSTART, dep->de_startpage);
  315.     outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
  316.     /* Step 7: */
  317.     outb_reg0(dep, DP_ISR, 0xFF);
  318.     /* Step 8: */
  319.     outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
  320.         IMR_OVWE | IMR_CNTE);
  321.     /* Step 9: */
  322.     outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
  323.  
  324.     outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
  325.     outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
  326.     outb_reg1(dep, DP_PAR2, dep->de_address.ea_addr[2]);
  327.     outb_reg1(dep, DP_PAR3, dep->de_address.ea_addr[3]);
  328.     outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
  329.     outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
  330.  
  331.     outb_reg1(dep, DP_MAR0, 0xff);
  332.     outb_reg1(dep, DP_MAR1, 0xff);
  333.     outb_reg1(dep, DP_MAR2, 0xff);
  334.     outb_reg1(dep, DP_MAR3, 0xff);
  335.     outb_reg1(dep, DP_MAR4, 0xff);
  336.     outb_reg1(dep, DP_MAR5, 0xff);
  337.     outb_reg1(dep, DP_MAR6, 0xff);
  338.     outb_reg1(dep, DP_MAR7, 0xff);
  339.  
  340.     outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
  341.     /* Step 10: */
  342.     outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
  343.     /* Step 11: */
  344.     outb_reg0(dep, DP_TCR, TCR_NORMAL);
  345.  
  346.     inb_reg0(dep, DP_CNTR0);        /* reset counters by reading */
  347.     inb_reg0(dep, DP_CNTR1);
  348.     inb_reg0(dep, DP_CNTR2);
  349.  
  350.     /* Finish the initialization. */
  351.     dep->de_flags |= DEF_ENABLED;
  352.     for (i= 0; i<dep->de_sendq_nr; i++)
  353.         dep->de_sendq[i].sq_filled= 0;
  354.     dep->de_sendq_head= 0;
  355.     dep->de_sendq_tail= 0;
  356. //  if (!dep->de_prog_IO)
  357. //  {
  358. //      dep->de_user2nicf= dp_user2nic;
  359. //      dep->de_user2nicf_s= dp_user2nic_s;
  360.         dep->de_nic2userf= dp_nic2user;
  361. //      dep->de_nic2userf_s= dp_nic2user_s;
  362.         dep->de_getblockf= dp_getblock;
  363. //  }
  364. //  else if (dep->de_16bit)
  365. //  {
  366. //      dep->de_user2nicf= dp_pio16_user2nic;
  367. //      dep->de_user2nicf_s= dp_pio16_user2nic_s;
  368. //      dep->de_nic2userf= dp_pio16_nic2user;
  369. //      dep->de_nic2userf_s= dp_pio16_nic2user_s;
  370. //      dep->de_getblockf= dp_pio16_getblock;
  371. //  }
  372. //  else
  373. //  {
  374. //      dep->de_user2nicf= dp_pio8_user2nic;
  375. //      dep->de_user2nicf_s= dp_pio8_user2nic_s;
  376. //      dep->de_nic2userf= dp_pio8_nic2user;
  377. //      dep->de_nic2userf_s= dp_pio8_nic2user_s;
  378. //      dep->de_getblockf= dp_pio8_getblock;
  379. //  }
  380.  
  381.     /* Set the interrupt handler and policy. Do not automatically
  382.      * reenable interrupts. Return the IRQ line number on interrupts.
  383.      */
  384. /*  dep->de_hook = dep->de_irq;
  385.     r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
  386.     if (r != OK)
  387.         panic("DP8390", "sys_irqsetpolicy failed", r);
  388.  
  389.     r= sys_irqenable(&dep->de_hook);
  390.     if (r != OK)
  391.     {
  392.         panic("DP8390", "unable enable interrupts", r);
  393.     }
  394. */
  395. }
  396.  
  397. /*===========================================================================*
  398.  *              dp_reinit                    *
  399.  *===========================================================================*/
  400. static void dp_reinit(dep)
  401. dpeth_t *dep;
  402. {
  403.     int dp_rcr_reg;
  404.  
  405.     outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
  406.  
  407.     dp_rcr_reg = 0;
  408.     if (dep->de_flags & DEF_PROMISC)
  409.         dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
  410.     if (dep->de_flags & DEF_BROAD)
  411.         dp_rcr_reg |= RCR_AB;
  412.     if (dep->de_flags & DEF_MULTI)
  413.         dp_rcr_reg |= RCR_AM;
  414.     outb_reg0(dep, DP_RCR, dp_rcr_reg);
  415. }
  416.  
  417. /*===========================================================================*
  418.  *              dp_reset                     *
  419.  *===========================================================================*/
  420. static void dp_reset(dep)
  421. dpeth_t *dep;
  422. {
  423.     int i;
  424.  
  425.     /* Stop chip */
  426.     outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
  427.     outb_reg0(dep, DP_RBCR0, 0);
  428.     outb_reg0(dep, DP_RBCR1, 0);
  429.     for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
  430.         ; /* Do nothing */
  431.     outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
  432.     outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
  433.     outb_reg0(dep, DP_TCR, TCR_NORMAL);
  434.  
  435.     /* Acknowledge the ISR_RDC (remote dma) interrupt. */
  436.     for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); i++)
  437.         ; /* Do nothing */
  438.     outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
  439.  
  440.     /* Reset the transmit ring. If we were transmitting a packet, we
  441.      * pretend that the packet is processed. Higher layers will
  442.      * retransmit if the packet wasn't actually sent.
  443.      */
  444.     dep->de_sendq_head= dep->de_sendq_tail= 0;
  445.     for (i= 0; i<dep->de_sendq_nr; i++)
  446.         dep->de_sendq[i].sq_filled= 0;
  447.     dp_send(dep);
  448.     dep->de_flags &= ~DEF_STOPPED;
  449. }
  450.  
  451. /*===========================================================================*
  452.  *              dp_check_ints                    *
  453.  *===========================================================================*/
  454. void dp_check_ints(dep)
  455. dpeth_t *dep;
  456. {
  457.     int isr, tsr;
  458.     int size, sendq_tail;
  459.  
  460.     if (!(dep->de_flags & DEF_ENABLED))
  461.         panic("", "dp8390: got premature interrupt", NO_NUM);
  462.  
  463.     for(;;)
  464.     {
  465.         isr = inb_reg0(dep, DP_ISR);
  466.         if (!isr)
  467.             break;
  468.         outb_reg0(dep, DP_ISR, isr);
  469.         if (isr & (ISR_PTX|ISR_TXE))
  470.         {
  471.             if (isr & ISR_TXE)
  472.             {
  473. #if DEBUG
  474.  { printf("%s: got send Error\n", dep->de_name); }
  475. #endif
  476.                 dep->de_stat.ets_sendErr++;
  477.             }
  478.             else
  479.             {
  480.                 tsr = inb_reg0(dep, DP_TSR);
  481.  
  482.                 if (tsr & TSR_PTX) dep->de_stat.ets_packetT++;
  483. #if 0   /* Reserved in later manuals, should be ignored */
  484.                 if (!(tsr & TSR_DFR))
  485.                 {
  486.                     /* In most (all?) implementations of
  487.                      * the dp8390, this bit is set
  488.                      * when the packet is not deferred
  489.                      */
  490.                     dep->de_stat.ets_transDef++;
  491.                 }
  492. #endif
  493.                 if (tsr & TSR_COL) dep->de_stat.ets_collision++;
  494.                 if (tsr & TSR_ABT) dep->de_stat.ets_transAb++;
  495.                 if (tsr & TSR_CRS) dep->de_stat.ets_carrSense++;
  496.                 if (tsr & TSR_FU
  497.                     && ++dep->de_stat.ets_fifoUnder <= 10)
  498.                 {
  499.                     printf("%s: fifo underrun\n",
  500.                         dep->de_name);
  501.                 }
  502.                 if (tsr & TSR_CDH
  503.                     && ++dep->de_stat.ets_CDheartbeat <= 10)
  504.                 {
  505.                     printf("%s: CD heart beat failure\n",
  506.                         dep->de_name);
  507.                 }
  508.                 if (tsr & TSR_OWC) dep->de_stat.ets_OWC++;
  509.             }
  510.             sendq_tail= dep->de_sendq_tail;
  511.  
  512.             if (!(dep->de_sendq[sendq_tail].sq_filled))
  513.             {
  514.                 /* Software bug? */
  515.                 assert(!debug);
  516.  
  517.                 /* Or hardware bug? */
  518.                 printf(
  519.                 "%s: transmit interrupt, but not sending\n",
  520.                     dep->de_name);
  521.                 continue;
  522.             }
  523.             dep->de_sendq[sendq_tail].sq_filled= 0;
  524.             if (++sendq_tail == dep->de_sendq_nr)
  525.                 sendq_tail= 0;
  526.             dep->de_sendq_tail= sendq_tail;
  527.             if (dep->de_sendq[sendq_tail].sq_filled)
  528.             {
  529.                 size= dep->de_sendq[sendq_tail].sq_size;
  530.                 outb_reg0(dep, DP_TPSR,
  531.                     dep->de_sendq[sendq_tail].sq_sendpage);
  532.                 outb_reg0(dep, DP_TBCR1, size >> 8);
  533.                 outb_reg0(dep, DP_TBCR0, size & 0xff);
  534.                 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
  535.             }
  536.             if (dep->de_flags & DEF_SEND_AVAIL)
  537.                 dp_send(dep);
  538.         }
  539.  
  540.         if (isr & ISR_PRX)
  541.         {
  542.             /* Only call dp_recv if there is a read request */
  543.             if (dep->de_flags & DEF_READING)
  544.                 dp_recv(dep);
  545.         }
  546.        
  547.         if (isr & ISR_RXE) dep->de_stat.ets_recvErr++;
  548.         if (isr & ISR_CNT)
  549.         {
  550.             dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
  551.             dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
  552.             dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
  553.         }
  554.         if (isr & ISR_OVW)
  555.         {
  556.             dep->de_stat.ets_OVW++;
  557. #if 0
  558.             { printW(); printf(
  559.                 "%s: got overwrite warning\n", dep->de_name); }
  560. #endif
  561.             if (dep->de_flags & DEF_READING)
  562.             {
  563.                 printf(
  564. "dp_check_ints: strange: overwrite warning and pending read request\n");
  565.                 dp_recv(dep);
  566.             }
  567.         }
  568.         if (isr & ISR_RDC)
  569.         {
  570.             /* Nothing to do */
  571.         }
  572.         if (isr & ISR_RST)
  573.         {
  574.             /* this means we got an interrupt but the ethernet
  575.              * chip is shutdown. We set the flag DEF_STOPPED,
  576.              * and continue processing arrived packets. When the
  577.              * receive buffer is empty, we reset the dp8390.
  578.              */
  579. #if 0
  580.              { printW(); printf(
  581.                 "%s: NIC stopped\n", dep->de_name); }
  582. #endif
  583.             dep->de_flags |= DEF_STOPPED;
  584.             break;
  585.         }
  586.     }
  587.     if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
  588.                         (DEF_READING|DEF_STOPPED))
  589.     {
  590.         /* The chip is stopped, and all arrived packets are
  591.          * delivered.
  592.          */
  593.         dp_reset(dep);
  594.     }
  595. }
  596.  
  597. /*===========================================================================*
  598.  *              dp_recv                      *
  599.  *===========================================================================*/
  600. static void dp_recv(dep)
  601. dpeth_t *dep;
  602. {
  603.     dp_rcvhdr_t header;
  604.     unsigned pageno, curr, next;
  605.     vir_bytes length;
  606.     int packet_processed, r;
  607.     u16_t eth_type;
  608.  
  609.     packet_processed = FALSE;
  610.     pageno = inb_reg0(dep, DP_BNRY) + 1;
  611.     if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
  612.  
  613.     do
  614.     {
  615.         outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
  616.         curr = inb_reg1(dep, DP_CURR);
  617.         outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
  618.  
  619.         if (curr == pageno) break;
  620.  
  621.         (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
  622.             &header);
  623.         (dep->de_getblockf)(dep, pageno, sizeof(header) +
  624.             2*sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
  625.  
  626.         length = (header.dr_rbcl | (header.dr_rbch << 8)) -
  627.             sizeof(dp_rcvhdr_t);
  628.         next = header.dr_next;
  629.         if (length < ETH_MIN_PACK_SIZE ||
  630.             length > ETH_MAX_PACK_SIZE_TAGGED)
  631.         {
  632.             printf("%s: packet with strange length arrived: %d\n",
  633.                 dep->de_name, (int) length);
  634.             next= curr;
  635.         }
  636.         else if (next < dep->de_startpage || next >= dep->de_stoppage)
  637.         {
  638.             printf("%s: strange next page\n", dep->de_name);
  639.             next= curr;
  640.         }
  641. /*      else if (eth_type == eth_ign_proto)
  642.         {
  643. */          /* Hack: ignore packets of a given protocol, useful
  644.              * if you share a net with 80 computers sending
  645.              * Amoeba FLIP broadcasts.  (Protocol 0x8146.)
  646.              */
  647. /*          static int first= 1;
  648.             if (first)
  649.             {
  650.                 first= 0;
  651.                 printf("%s: dropping proto 0x%04x packets\n",
  652.                     dep->de_name,
  653.                     ntohs(eth_ign_proto));
  654.             }
  655.             dep->de_stat.ets_packetR++;
  656.         }
  657. */      else if (header.dr_status & RSR_FO)
  658.         {
  659.             /* This is very serious, so we issue a warning and
  660.              * reset the buffers */
  661.             printf("%s: fifo overrun, resetting receive buffer\n",
  662.                 dep->de_name);
  663.             dep->de_stat.ets_fifoOver++;
  664.             next = curr;
  665.         }
  666.         else if ((header.dr_status & RSR_PRX) &&
  667.                        (dep->de_flags & DEF_ENABLED))
  668.         {
  669. //          if (dep->de_safecopy_read)
  670. //              r = dp_pkt2user_s(dep, pageno, length);
  671. //          else
  672.                 r = dp_pkt2user(dep, pageno, length);
  673.             if (r != OK)
  674.                 return;
  675.  
  676.             packet_processed = TRUE;
  677.             dep->de_stat.ets_packetR++;
  678.         }
  679.         if (next == dep->de_startpage)
  680.             outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
  681.         else
  682.             outb_reg0(dep, DP_BNRY, next - 1);
  683.  
  684.         pageno = next;
  685.     }
  686.     while (!packet_processed);
  687. }
  688.  
  689. /*===========================================================================*
  690.  *              dp_send                      *
  691.  *===========================================================================*/
  692. static void dp_send(dep)
  693. dpeth_t *dep;
  694. {
  695. /*  if (!(dep->de_flags & DEF_SEND_AVAIL))
  696.         return;
  697.  
  698.     dep->de_flags &= ~DEF_SEND_AVAIL;
  699.     switch(dep->de_sendmsg.m_type)
  700.     {
  701.     case DL_WRITE:  do_vwrite(&dep->de_sendmsg, TRUE, FALSE);   break;
  702.     case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE);    break;
  703.     case DL_WRITEV_S: do_vwrite_s(&dep->de_sendmsg, TRUE);  break;
  704.     default:
  705.         panic("", "dp8390: wrong type", dep->de_sendmsg.m_type);
  706.         break;
  707.     }
  708. */
  709. }
  710.  
  711. /*===========================================================================*
  712.  *              dp_getblock                  *
  713.  *===========================================================================*/
  714. static void dp_getblock(dep, page, offset, size, dst)
  715. dpeth_t *dep;
  716. int page;
  717. size_t offset;
  718. size_t size;
  719. void *dst;
  720. {
  721. //  int r;
  722.  
  723.     offset = page * DP_PAGESIZE + offset;
  724.  
  725.     memcpy(dst, dep->de_locmem + offset, size);
  726. }
  727.  
  728. /*===========================================================================*
  729.  *              dp_pkt2user                  *
  730.  *===========================================================================*/
  731. static int dp_pkt2user(dep, page, length)
  732. dpeth_t *dep;
  733. int page, length;
  734. {
  735.     int last, count;
  736.  
  737.     if (!(dep->de_flags & DEF_READING))
  738.         return EGENERIC;
  739.  
  740.     last = page + (length - 1) / DP_PAGESIZE;
  741.     if (last >= dep->de_stoppage)
  742.     {
  743.         count = (dep->de_stoppage - page) * DP_PAGESIZE -
  744.             sizeof(dp_rcvhdr_t);
  745.  
  746.         /* Save read_iovec since we need it twice. */
  747.         dep->de_tmp_iovec = dep->de_read_iovec;
  748.         (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
  749.             sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count);
  750.         (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE,
  751.                 &dep->de_read_iovec, count, length - count);
  752.     }
  753.     else
  754.     {
  755.         (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
  756.             sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);
  757.     }
  758.  
  759.     dep->de_read_s = length;
  760.     dep->de_flags |= DEF_PACK_RECV;
  761.     dep->de_flags &= ~DEF_READING;
  762.  
  763.     return OK;
  764. }
  765.  
  766. /*===========================================================================*
  767.  *              dp_nic2user                  *
  768.  *===========================================================================*/
  769. static void dp_nic2user(dep, nic_addr, iovp, offset, count)
  770. dpeth_t *dep;
  771. int nic_addr;
  772. iovec_dat_t *iovp;
  773. vir_bytes offset;
  774. vir_bytes count;
  775. {
  776. /*  vir_bytes vir_hw, vir_user;
  777.     int bytes, i, r;
  778.  
  779.     vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
  780.  
  781.     i= 0;
  782.     while (count > 0)
  783.     {
  784.         if (i >= IOVEC_NR)
  785.         {
  786.             dp_next_iovec(iovp);
  787.             i= 0;
  788.             continue;
  789.         }
  790.         assert(i < iovp->iod_iovec_s);
  791.         if (offset >= iovp->iod_iovec[i].iov_size)
  792.         {
  793.             offset -= iovp->iod_iovec[i].iov_size;
  794.             i++;
  795.             continue;
  796.         }
  797.         bytes = iovp->iod_iovec[i].iov_size - offset;
  798.         if (bytes > count)
  799.             bytes = count;
  800.  
  801.         r= sys_vircopy(SELF, D, vir_hw,
  802.             iovp->iod_proc_nr, D,
  803.             iovp->iod_iovec[i].iov_addr + offset, bytes);
  804.         if (r != OK)
  805.             panic("DP8390", "dp_nic2user: sys_vircopy failed", r);
  806.  
  807.         count -= bytes;
  808.         vir_hw += bytes;
  809.         offset += bytes;
  810.     }
  811.     assert(count == 0);
  812. */
  813.     printf("n2u");
  814. }
  815.  
  816. /*===========================================================================*
  817.  *              conf_hw                      *
  818.  *===========================================================================*/
  819. static void conf_hw(dep)
  820. dpeth_t *dep;
  821. {
  822. //  static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0    /* ,... */ };
  823.  
  824. //  int ifnr;
  825. //  dp_conf_t *dcp;
  826.  
  827. //  dep->de_mode= DEM_DISABLED; /* Superfluous */
  828. //  ifnr= dep-de_table;
  829.  
  830. //  dcp= &dp_conf[ifnr];
  831. //  update_conf(dep, dcp);
  832. //  if (dep->de_mode != DEM_ENABLED)
  833. //      return;
  834.     if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))
  835.     {
  836.         printf("%s: No ethernet card found at 0x%x\n",
  837.             dep->de_name, dep->de_base_port);
  838.         dep->de_mode= DEM_DISABLED;
  839.         return;
  840.     }
  841.  
  842. /* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
  843.  
  844.     dep->de_mode = DEM_ENABLED;
  845.  
  846.     dep->de_flags = DEF_EMPTY;
  847. //  dep->de_stat = empty_stat;
  848. }
  849.  
  850. /*===========================================================================*
  851.  *              map_hw_buffer                    *
  852.  *===========================================================================*/
  853. static void map_hw_buffer(dep)
  854. dpeth_t *dep;
  855. {
  856. //  int r;
  857. //  size_t o, size;
  858. //  char *buf, *abuf;
  859.  
  860.     if (dep->de_prog_IO)
  861.     {
  862. //#if 0
  863.         if(debug){
  864.             printf(
  865.             "map_hw_buffer: programmed I/O, no need to map buffer\n");
  866.         }
  867. //#endif
  868.         dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */
  869.         return;
  870.     }
  871.  
  872. //  size = dep->de_ramsize + PAGE_SIZE; /* Add PAGE_SIZE for
  873. //                       * alignment
  874. //                       */
  875. //  buf= malloc(size);
  876. //  if (buf == NULL)
  877. //      panic(__FILE__, "map_hw_buffer: cannot malloc size", size);
  878. //  o= PAGE_SIZE - ((vir_bytes)buf % PAGE_SIZE);
  879. //  abuf= buf + o;
  880. //  printf("buf at 0x%x, abuf at 0x%x\n", buf, abuf);
  881.  
  882. //  r= sys_vm_map(SELF, 1 /* map */, (vir_bytes)abuf,
  883. //          dep->de_ramsize, (phys_bytes)dep->de_linmem);
  884. //  if (r != OK)
  885. //      panic(__FILE__, "map_hw_buffer: sys_vm_map failed", r);
  886. //  dep->de_locmem = abuf;
  887. }
  888.  
  889. /*===========================================================================*
  890.  *              reply                        *
  891.  *===========================================================================*/
  892. static void reply(dep, err, may_block)
  893. dpeth_t *dep;
  894. int err;
  895. int may_block;
  896. {
  897. /*  message reply;
  898.     int status;
  899.     int r;
  900.  
  901.     status = 0;
  902.     if (dep->de_flags & DEF_PACK_SEND)
  903.         status |= DL_PACK_SEND;
  904.     if (dep->de_flags & DEF_PACK_RECV)
  905.         status |= DL_PACK_RECV;
  906.  
  907.     reply.m_type = DL_TASK_REPLY;
  908.     reply.DL_PORT = dep - de_table;
  909.     reply.DL_PROC = dep->de_client;
  910.     reply.DL_STAT = status | ((u32_t) err << 16);
  911.     reply.DL_COUNT = dep->de_read_s;
  912.     reply.DL_CLCK = 0;  *//* Don't know */
  913. /*  r= send(dep->de_client, &reply);
  914.  
  915.     if (r == ELOCKED && may_block)
  916.     {
  917. #if 0
  918.         printf("send locked\n");
  919. #endif
  920.         return;
  921.     }
  922.  
  923.     if (r < 0)
  924.         panic("", "dp8390: send failed:", r);
  925.    
  926.     dep->de_read_s = 0;
  927. */  dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
  928. }
  929.  
  930. /*
  931.  * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $
  932.  */
  933.  
  934. /** @}
  935.  */
  936.