Subversion Repositories HelenOS

Rev

Rev 4723 | 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 Mejdrech ported to HelenOS
  25.  */
  26.  
  27. /** @addtogroup dp8390
  28.  *  @{
  29.  */
  30.  
  31. /** @file
  32.  *  \todo
  33.  */
  34.  
  35. #include <assert.h>
  36. #include <errno.h>
  37.  
  38. #include "../../include/byteorder.h"
  39.  
  40. #include "../../structures/packet/packet.h"
  41. #include "../../structures/packet/packet_client.h"
  42.  
  43. #include "../netif.h"
  44.  
  45. #include "dp8390_drv.h"
  46. #include "dp8390_port.h"
  47.  
  48. /*
  49.  * dp8390.c
  50.  *
  51.  * Created: before Dec 28, 1992 by Philip Homburg <philip@f-mnx.phicoh.com>
  52.  *
  53.  * Modified Mar 10 1994 by Philip Homburg
  54.  *  Become a generic dp8390 driver.
  55.  *
  56.  * Modified Dec 20 1996 by G. Falzoni <falzoni@marina.scn.de>
  57.  *  Added support for 3c503 boards.
  58.  */
  59.  
  60. #include "local.h"
  61. #include "dp8390.h"
  62.  
  63. int queue_packet( dpeth_t * dep, packet_t packet );
  64. static void outsb( port_t port, void * buf, size_t size );
  65. static void outsw( port_t port, void * buf, size_t size );
  66.  
  67. //static u16_t eth_ign_proto;
  68. //static char *progname;
  69.  
  70. /* Configuration */
  71. /*typedef struct dp_conf
  72. {
  73.     port_t dpc_port;
  74.     int dpc_irq;
  75.     phys_bytes dpc_mem;
  76.     char *dpc_envvar;
  77. } dp_conf_t;
  78. */
  79. //dp_conf_t dp_conf[]=  /* Card addresses */
  80. //{
  81.     /* I/O port, IRQ,  Buffer address,  Env. var. */
  82. /*  {  0x280,     3,    0xD0000,        "DPETH0"    },
  83.     {  0x300,     5,    0xC8000,        "DPETH1"    },
  84.     {  0x380,    10,    0xD8000,        "DPETH2"    },
  85. };
  86. */
  87. /* Test if dp_conf has exactly DE_PORT_NR entries.  If not then you will see
  88.  * the error: "array size is negative".
  89.  */
  90. //extern int ___dummy[DE_PORT_NR == sizeof(dp_conf)/sizeof(dp_conf[0]) ? 1 : -1];
  91.  
  92. /* Card inits configured out? */
  93. #if !ENABLE_WDETH
  94. #define wdeth_probe(dep)    (0)
  95. #endif
  96. #if !ENABLE_NE2000
  97. #define ne_probe(dep)       (0)
  98. #endif
  99. #if !ENABLE_3C503
  100. #define el2_probe(dep)      (0)
  101. #endif
  102.  
  103. /* Some clones of the dp8390 and the PC emulator 'Bochs' require the CR_STA
  104.  * on writes to the CR register. Additional CR_STAs do not appear to hurt
  105.  * genuine dp8390s
  106.  */
  107. #define CR_EXTRA    CR_STA
  108.  
  109. //#if ENABLE_PCI
  110. //_PROTOTYPE( static void pci_conf, (void)              );
  111. //#endif
  112. //_PROTOTYPE( static void do_vwrite, (message *mp, int from_int,
  113. //                          int vectored)   );
  114. //_PROTOTYPE( static void do_vwrite_s, (message *mp, int from_int)  );
  115. //_PROTOTYPE( static void do_vread, (message *mp, int vectored)     );
  116. //_PROTOTYPE( static void do_vread_s, (message *mp)         );
  117. //_PROTOTYPE( static void do_init, (message *mp)                );
  118. //_PROTOTYPE( static void do_int, (dpeth_t *dep)                );
  119. //_PROTOTYPE( static void do_getstat, (message *mp)         );
  120. //_PROTOTYPE( static void do_getstat_s, (message *mp)           );
  121. //_PROTOTYPE( static void do_getname, (message *mp)         );
  122. //_PROTOTYPE( static void do_stop, (message *mp)                );
  123. _PROTOTYPE( static void dp_init, (dpeth_t *dep)             );
  124. //_PROTOTYPE( static void dp_confaddr, (dpeth_t *dep)           );
  125. _PROTOTYPE( static void dp_reinit, (dpeth_t *dep)           );
  126. _PROTOTYPE( static void dp_reset, (dpeth_t *dep)            );
  127. //_PROTOTYPE( static void dp_check_ints, (dpeth_t *dep)         );
  128. _PROTOTYPE( static void dp_recv, (dpeth_t *dep)             );
  129. _PROTOTYPE( static void dp_send, (dpeth_t *dep)             );
  130. //_PROTOTYPE( static void dp8390_stop, (void)               );
  131. _PROTOTYPE( static void dp_getblock, (dpeth_t *dep, int page,
  132.                 size_t offset, size_t size, void *dst)  );
  133. _PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page,
  134.                 size_t offset, size_t size, void *dst)  );
  135. _PROTOTYPE( static void dp_pio16_getblock, (dpeth_t *dep, int page,
  136.                 size_t offset, size_t size, void *dst)  );
  137. _PROTOTYPE( static int dp_pkt2user, (dpeth_t *dep, int page,
  138.                             int length) );
  139. //_PROTOTYPE( static int dp_pkt2user_s, (dpeth_t *dep, int page,
  140. //                          int length) );
  141. _PROTOTYPE( static void dp_user2nic, (dpeth_t *dep, iovec_dat_t *iovp,
  142.         vir_bytes offset, int nic_addr, vir_bytes count)    );
  143. //_PROTOTYPE( static void dp_user2nic_s, (dpeth_t *dep, iovec_dat_s_t *iovp,
  144. //      vir_bytes offset, int nic_addr, vir_bytes count)    );
  145. _PROTOTYPE( static void dp_pio8_user2nic, (dpeth_t *dep,
  146.                 iovec_dat_t *iovp, vir_bytes offset,
  147.                 int nic_addr, vir_bytes count)      );
  148. //_PROTOTYPE( static void dp_pio8_user2nic_s, (dpeth_t *dep,
  149. //              iovec_dat_s_t *iovp, vir_bytes offset,
  150. //              int nic_addr, vir_bytes count)      );
  151. _PROTOTYPE( static void dp_pio16_user2nic, (dpeth_t *dep,
  152.                 iovec_dat_t *iovp, vir_bytes offset,
  153.                 int nic_addr, vir_bytes count)      );
  154. //_PROTOTYPE( static void dp_pio16_user2nic_s, (dpeth_t *dep,
  155. //              iovec_dat_s_t *iovp, vir_bytes offset,
  156. //              int nic_addr, vir_bytes count)      );
  157. _PROTOTYPE( static void dp_nic2user, (dpeth_t *dep, int nic_addr,
  158.         iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
  159. //_PROTOTYPE( static void dp_nic2user_s, (dpeth_t *dep, int nic_addr,
  160. //      iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
  161. _PROTOTYPE( static void dp_pio8_nic2user, (dpeth_t *dep, int nic_addr,
  162.         iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
  163. //_PROTOTYPE( static void dp_pio8_nic2user_s, (dpeth_t *dep, int nic_addr,
  164. //      iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
  165. _PROTOTYPE( static void dp_pio16_nic2user, (dpeth_t *dep, int nic_addr,
  166.         iovec_dat_t *iovp, vir_bytes offset, vir_bytes count)   );
  167. //_PROTOTYPE( static void dp_pio16_nic2user_s, (dpeth_t *dep, int nic_addr,
  168. //      iovec_dat_s_t *iovp, vir_bytes offset, vir_bytes count) );
  169. _PROTOTYPE( static void dp_next_iovec, (iovec_dat_t *iovp)      );
  170. //_PROTOTYPE( static void dp_next_iovec_s, (iovec_dat_s_t *iovp)        );
  171. _PROTOTYPE( static void conf_hw, (dpeth_t *dep)             );
  172. //_PROTOTYPE( static void update_conf, (dpeth_t *dep, dp_conf_t *dcp)   );
  173. _PROTOTYPE( static void map_hw_buffer, (dpeth_t *dep)           );
  174. //_PROTOTYPE( static int calc_iovec_size, (iovec_dat_t *iovp)       );
  175. //_PROTOTYPE( static int calc_iovec_size_s, (iovec_dat_s_t *iovp)       );
  176. _PROTOTYPE( static void reply, (dpeth_t *dep, int err, int may_block)   );
  177. //_PROTOTYPE( static void mess_reply, (message *req, message *reply)    );
  178. _PROTOTYPE( static void get_userdata, (int user_proc,
  179.         vir_bytes user_addr, vir_bytes count, void *loc_addr)   );
  180. //_PROTOTYPE( static void get_userdata_s, (int user_proc,
  181. //      cp_grant_id_t grant, vir_bytes offset, vir_bytes count,
  182. //      void *loc_addr) );
  183. //_PROTOTYPE( static void put_userdata, (int user_proc,
  184. //      vir_bytes user_addr, vir_bytes count, void *loc_addr)   );
  185. //_PROTOTYPE( static void put_userdata_s, (int user_proc,
  186. //      cp_grant_id_t grant, size_t count, void *loc_addr)  );
  187. _PROTOTYPE( static void insb, (port_t port, void *buf, size_t size)             );
  188. _PROTOTYPE( static void insw, (port_t port, void *buf, size_t size)             );
  189. //_PROTOTYPE( static void do_vir_insb, (port_t port, int proc,
  190. //                  vir_bytes buf, size_t size) );
  191. //_PROTOTYPE( static void do_vir_insw, (port_t port, int proc,
  192. //                  vir_bytes buf, size_t size) );
  193. //_PROTOTYPE( static void do_vir_outsb, (port_t port, int proc,
  194. //                  vir_bytes buf, size_t size) );
  195. //_PROTOTYPE( static void do_vir_outsw, (port_t port, int proc,
  196. //                  vir_bytes buf, size_t size) );
  197.  
  198. int do_probe( dpeth_t * dep ){
  199.     /* This is the default, try to (re)locate the device. */
  200.     conf_hw(dep);
  201.     if (dep->de_mode == DEM_DISABLED)
  202.     {
  203.         /* Probe failed, or the device is configured off. */
  204.         return EXDEV;//ENXIO;
  205.     }
  206.     if (dep->de_mode == DEM_ENABLED)
  207.         dp_init(dep);
  208.     return EOK;
  209. }
  210.  
  211. /*===========================================================================*
  212.  *              dp8390_dump                  *
  213.  *===========================================================================*/
  214. void dp8390_dump( dpeth_t * dep )
  215. {
  216. //  dpeth_t *dep;
  217.     int /*i,*/ isr;
  218.  
  219. //  printf("\n");
  220. //  for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
  221. //  {
  222. #if XXX
  223.         if (dep->de_mode == DEM_DISABLED)
  224.             printf("dp8390 port %d is disabled\n", i);
  225.         else if (dep->de_mode == DEM_SINK)
  226.             printf("dp8390 port %d is in sink mode\n", i);
  227. #endif
  228.  
  229.         if (dep->de_mode != DEM_ENABLED)
  230. //          continue;
  231.             return;
  232.  
  233. //      printf("dp8390 statistics of port %d:\n", i);
  234.  
  235.         printf("recvErr    :%8ld\t", dep->de_stat.ets_recvErr);
  236.         printf("sendErr    :%8ld\t", dep->de_stat.ets_sendErr);
  237.         printf("OVW        :%8ld\n", dep->de_stat.ets_OVW);
  238.  
  239.         printf("CRCerr     :%8ld\t", dep->de_stat.ets_CRCerr);
  240.         printf("frameAll   :%8ld\t", dep->de_stat.ets_frameAll);
  241.         printf("missedP    :%8ld\n", dep->de_stat.ets_missedP);
  242.  
  243.         printf("packetR    :%8ld\t", dep->de_stat.ets_packetR);
  244.         printf("packetT    :%8ld\t", dep->de_stat.ets_packetT);
  245.         printf("transDef   :%8ld\n", dep->de_stat.ets_transDef);
  246.  
  247.         printf("collision  :%8ld\t", dep->de_stat.ets_collision);
  248.         printf("transAb    :%8ld\t", dep->de_stat.ets_transAb);
  249.         printf("carrSense  :%8ld\n", dep->de_stat.ets_carrSense);
  250.  
  251.         printf("fifoUnder  :%8ld\t", dep->de_stat.ets_fifoUnder);
  252.         printf("fifoOver   :%8ld\t", dep->de_stat.ets_fifoOver);
  253.         printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);
  254.  
  255.         printf("OWC        :%8ld\t", dep->de_stat.ets_OWC);
  256.  
  257.         isr= inb_reg0(dep, DP_ISR);
  258.         printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
  259.                     inb_reg0(dep, DP_ISR), dep->de_flags);
  260. //  }
  261. }
  262.  
  263. /*===========================================================================*
  264.  *              do_init                      *
  265.  *===========================================================================*/
  266. int do_init( dpeth_t * dep, int mode ){
  267.     if (dep->de_mode == DEM_DISABLED)
  268.     {
  269.         // might call do_probe()
  270.         return EXDEV;
  271.     }
  272.  
  273.     if (dep->de_mode == DEM_SINK)
  274.     {
  275. //      strncpy((char *) dep->de_address.ea_addr, "ZDP", 6);
  276. //      dep->de_address.ea_addr[5] = port;
  277. //      dp_confaddr(dep);
  278. //      reply_mess.m_type = DL_CONF_REPLY;
  279. //      reply_mess.m3_i1 = mp->DL_PORT;
  280. //      reply_mess.m3_i2 = DE_PORT_NR;
  281. //      *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
  282. //      mess_reply(mp, &reply_mess);
  283. //      return;
  284.         return EOK;
  285.     }
  286.     assert(dep->de_mode == DEM_ENABLED);
  287.     assert(dep->de_flags & DEF_ENABLED);
  288.  
  289.     dep->de_flags &= ~(DEF_PROMISC | DEF_MULTI | DEF_BROAD);
  290.  
  291.     if (mode & DL_PROMISC_REQ)
  292.         dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;
  293.     if (mode & DL_MULTI_REQ)
  294.         dep->de_flags |= DEF_MULTI;
  295.     if (mode & DL_BROAD_REQ)
  296.         dep->de_flags |= DEF_BROAD;
  297.  
  298. //  dep->de_client = mp->m_source;
  299.     dp_reinit(dep);
  300.  
  301. //  reply_mess.m_type = DL_CONF_REPLY;
  302. //  reply_mess.m3_i1 = mp->DL_PORT;
  303. //  reply_mess.m3_i2 = DE_PORT_NR;
  304. //  *(ether_addr_t *) reply_mess.m3_ca1 = dep->de_address;
  305.  
  306. //  mess_reply(mp, &reply_mess);
  307.     return EOK;
  308. }
  309.  
  310. /*===========================================================================*
  311.  *              do_stop                      *
  312.  *===========================================================================*/
  313. void do_stop( dpeth_t * dep ){
  314.     if(( dep->de_mode != DEM_SINK ) && ( dep->de_mode == DEM_ENABLED ) && ( dep->de_flags & DEF_ENABLED )){
  315.         outb_reg0( dep, DP_CR, CR_STP | CR_DM_ABORT );
  316.         ( dep->de_stopf )( dep );
  317.  
  318.         dep->de_flags = DEF_EMPTY;
  319.     }
  320. }
  321.  
  322. int queue_packet( dpeth_t * dep, packet_t packet ){
  323.     packet_t    tmp;
  324.  
  325.     if( dep->packet_count >= MAX_PACKETS ){
  326.         netif_pq_release( packet_get_id( packet ));
  327.         return ELIMIT;
  328.     }
  329.  
  330.     tmp = dep->packet_queue;
  331.     while( pq_next( tmp )){
  332.         tmp = pq_next( tmp );
  333.     }
  334.     if( ! pq_add( tmp, packet, 0, 0 )){
  335.         return EINVAL;
  336.     }
  337.     if( ! dep->packet_count ){
  338.         dep->packet_queue = packet;
  339.     }
  340.     ++ dep->packet_count;
  341.     return EBUSY;
  342. }
  343.  
  344. /*===========================================================================*
  345.  *          based on    do_vwrite                    *
  346.  *===========================================================================*/
  347. int do_pwrite( dpeth_t * dep, packet_t packet, int from_int )
  348. {
  349. //  int port, count, size;
  350.     int size;
  351.     int sendq_head;
  352. /*  dpeth_t *dep;
  353.  
  354.     port = mp->DL_PORT;
  355.     count = mp->DL_COUNT;
  356.     if (port < 0 || port >= DE_PORT_NR)
  357.         panic("", "dp8390: illegal port", port);
  358.     dep= &de_table[port];
  359.     dep->de_client= mp->DL_PROC;
  360. */
  361.     if (dep->de_mode == DEM_SINK)
  362.     {
  363.         assert(!from_int);
  364. //      dep->de_flags |= DEF_PACK_SEND;
  365.         reply(dep, OK, FALSE);
  366. //      return;
  367.         return EOK;
  368.     }
  369.     assert(dep->de_mode == DEM_ENABLED);
  370.     assert(dep->de_flags & DEF_ENABLED);
  371.     if( dep->packet_queue && ( ! from_int )){
  372. //  if (dep->de_flags & DEF_SEND_AVAIL){
  373. //      panic("", "dp8390: send already in progress", NO_NUM);
  374.         return queue_packet( dep, packet );
  375.     }
  376.  
  377.     sendq_head= dep->de_sendq_head;
  378. //  if (dep->de_sendq[sendq_head].sq_filled)
  379. //  {
  380. //      if (from_int)
  381. //          panic("", "dp8390: should not be sending\n", NO_NUM);
  382. //      dep->de_sendmsg= *mp;
  383. //      dep->de_flags |= DEF_SEND_AVAIL;
  384. //      reply(dep, OK, FALSE);
  385. //      return;
  386. //      return queue_packet( dep, packet );
  387. //  }
  388. //  assert(!(dep->de_flags & DEF_PACK_SEND));
  389.  
  390. /*  if (vectored)
  391.     {
  392.         get_userdata(mp->DL_PROC, (vir_bytes) mp->DL_ADDR,
  393.             (count > IOVEC_NR ? IOVEC_NR : count) *
  394.             sizeof(iovec_t), dep->de_write_iovec.iod_iovec);
  395.         dep->de_write_iovec.iod_iovec_s = count;
  396.         dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
  397.         dep->de_write_iovec.iod_iovec_addr = (vir_bytes) mp->DL_ADDR;
  398.  
  399.         dep->de_tmp_iovec = dep->de_write_iovec;
  400.         size = calc_iovec_size(&dep->de_tmp_iovec);
  401.     }
  402.     else
  403.     {  
  404.         dep->de_write_iovec.iod_iovec[0].iov_addr =
  405.             (vir_bytes) mp->DL_ADDR;
  406.         dep->de_write_iovec.iod_iovec[0].iov_size =
  407.             mp->DL_COUNT;
  408.         dep->de_write_iovec.iod_iovec_s = 1;
  409.         dep->de_write_iovec.iod_proc_nr = mp->DL_PROC;
  410.         dep->de_write_iovec.iod_iovec_addr = 0;
  411.         size= mp->DL_COUNT;
  412.     }
  413. */
  414.     size = packet_get_data_length( packet );
  415.     dep->de_write_iovec.iod_iovec[0].iov_addr = ( vir_bytes ) packet_get_data( packet );
  416.     dep->de_write_iovec.iod_iovec[0].iov_size = size;
  417.     dep->de_write_iovec.iod_iovec_s = 1;
  418.     dep->de_write_iovec.iod_iovec_addr = NULL;
  419.  
  420.     if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)
  421.     {
  422.         panic("", "dp8390: invalid packet size", size);
  423.         return EINVAL;
  424.     }
  425.     (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,
  426.         dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
  427.         size);
  428.     dep->de_sendq[sendq_head].sq_filled= TRUE;
  429.     if (dep->de_sendq_tail == sendq_head)
  430.     {
  431.         outb_reg0(dep, DP_TPSR, dep->de_sendq[sendq_head].sq_sendpage);
  432.         outb_reg0(dep, DP_TBCR1, size >> 8);
  433.         outb_reg0(dep, DP_TBCR0, size & 0xff);
  434.         outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);/* there it goes.. */
  435.     }
  436.     else
  437.         dep->de_sendq[sendq_head].sq_size= size;
  438.    
  439.     if (++sendq_head == dep->de_sendq_nr)
  440.         sendq_head= 0;
  441.     assert(sendq_head < SENDQ_NR);
  442.     dep->de_sendq_head= sendq_head;
  443.  
  444. //  dep->de_flags |= DEF_PACK_SEND;
  445.  
  446.     /* If the interrupt handler called, don't send a reply. The reply
  447.      * will be sent after all interrupts are handled.
  448.      */
  449.     if (from_int)
  450.         return EOK;
  451.     reply(dep, OK, FALSE);
  452.  
  453.     assert(dep->de_mode == DEM_ENABLED);
  454.     assert(dep->de_flags & DEF_ENABLED);
  455.     return EOK;
  456. }
  457.  
  458. /*===========================================================================*
  459.  *              dp_init                      *
  460.  *===========================================================================*/
  461. void dp_init(dep)
  462. dpeth_t *dep;
  463. {
  464.     int dp_rcr_reg;
  465.     int i;//, r;
  466.  
  467.     /* General initialization */
  468.     dep->de_flags = DEF_EMPTY;
  469.     (*dep->de_initf)(dep);
  470.  
  471. //  dp_confaddr(dep);
  472.  
  473.     if (debug)
  474.     {
  475.         printf("%s: Ethernet address ", dep->de_name);
  476.         for (i= 0; i < 6; i++)
  477.             printf("%x%c", dep->de_address.ea_addr[i],
  478.                             i < 5 ? ':' : '\n');
  479.     }
  480.  
  481.     /* Map buffer */
  482.     map_hw_buffer(dep);
  483.  
  484.     /* Initialization of the dp8390 following the mandatory procedure
  485.      * in reference manual ("DP8390D/NS32490D NIC Network Interface
  486.      * Controller", National Semiconductor, July 1995, Page 29).
  487.      */
  488.     /* Step 1: */
  489.     outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_DM_ABORT);
  490.     /* Step 2: */
  491.     if (dep->de_16bit)
  492.         outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES | DCR_BMS);
  493.     else
  494.         outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES | DCR_BMS);
  495.     /* Step 3: */
  496.     outb_reg0(dep, DP_RBCR0, 0);
  497.     outb_reg0(dep, DP_RBCR1, 0);
  498.     /* Step 4: */
  499.     dp_rcr_reg = 0;
  500.     if (dep->de_flags & DEF_PROMISC)
  501.         dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
  502.     if (dep->de_flags & DEF_BROAD)
  503.         dp_rcr_reg |= RCR_AB;
  504.     if (dep->de_flags & DEF_MULTI)
  505.         dp_rcr_reg |= RCR_AM;
  506.     outb_reg0(dep, DP_RCR, dp_rcr_reg);
  507.     /* Step 5: */
  508.     outb_reg0(dep, DP_TCR, TCR_INTERNAL);
  509.     /* Step 6: */
  510.     outb_reg0(dep, DP_BNRY, dep->de_startpage);
  511.     outb_reg0(dep, DP_PSTART, dep->de_startpage);
  512.     outb_reg0(dep, DP_PSTOP, dep->de_stoppage);
  513.     /* Step 7: */
  514.     outb_reg0(dep, DP_ISR, 0xFF);
  515.     /* Step 8: */
  516.     outb_reg0(dep, DP_IMR, IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE |
  517.         IMR_OVWE | IMR_CNTE);
  518.     /* Step 9: */
  519.     outb_reg0(dep, DP_CR, CR_PS_P1 | CR_DM_ABORT | CR_STP);
  520.  
  521.     outb_reg1(dep, DP_PAR0, dep->de_address.ea_addr[0]);
  522.     outb_reg1(dep, DP_PAR1, dep->de_address.ea_addr[1]);
  523.     outb_reg1(dep, DP_PAR2, dep->de_address.ea_addr[2]);
  524.     outb_reg1(dep, DP_PAR3, dep->de_address.ea_addr[3]);
  525.     outb_reg1(dep, DP_PAR4, dep->de_address.ea_addr[4]);
  526.     outb_reg1(dep, DP_PAR5, dep->de_address.ea_addr[5]);
  527.  
  528.     outb_reg1(dep, DP_MAR0, 0xff);
  529.     outb_reg1(dep, DP_MAR1, 0xff);
  530.     outb_reg1(dep, DP_MAR2, 0xff);
  531.     outb_reg1(dep, DP_MAR3, 0xff);
  532.     outb_reg1(dep, DP_MAR4, 0xff);
  533.     outb_reg1(dep, DP_MAR5, 0xff);
  534.     outb_reg1(dep, DP_MAR6, 0xff);
  535.     outb_reg1(dep, DP_MAR7, 0xff);
  536.  
  537.     outb_reg1(dep, DP_CURR, dep->de_startpage + 1);
  538.     /* Step 10: */
  539.     outb_reg0(dep, DP_CR, CR_DM_ABORT | CR_STA);
  540.     /* Step 11: */
  541.     outb_reg0(dep, DP_TCR, TCR_NORMAL);
  542.  
  543.     inb_reg0(dep, DP_CNTR0);        /* reset counters by reading */
  544.     inb_reg0(dep, DP_CNTR1);
  545.     inb_reg0(dep, DP_CNTR2);
  546.  
  547.     /* Finish the initialization. */
  548.     dep->de_flags |= DEF_ENABLED;
  549.     for (i= 0; i<dep->de_sendq_nr; i++)
  550.         dep->de_sendq[i].sq_filled= 0;
  551.     dep->de_sendq_head= 0;
  552.     dep->de_sendq_tail= 0;
  553.     if (!dep->de_prog_IO)
  554.     {
  555.         dep->de_user2nicf= dp_user2nic;
  556. //      dep->de_user2nicf_s= dp_user2nic_s;
  557.         dep->de_nic2userf= dp_nic2user;
  558. //      dep->de_nic2userf_s= dp_nic2user_s;
  559.         dep->de_getblockf= dp_getblock;
  560.     }
  561.     else if (dep->de_16bit)
  562.     {
  563.         dep->de_user2nicf= dp_pio16_user2nic;
  564. //      dep->de_user2nicf_s= dp_pio16_user2nic_s;
  565.         dep->de_nic2userf= dp_pio16_nic2user;
  566. //      dep->de_nic2userf_s= dp_pio16_nic2user_s;
  567.         dep->de_getblockf= dp_pio16_getblock;
  568.     }
  569.     else
  570.     {
  571.         dep->de_user2nicf= dp_pio8_user2nic;
  572. //      dep->de_user2nicf_s= dp_pio8_user2nic_s;
  573.         dep->de_nic2userf= dp_pio8_nic2user;
  574. //      dep->de_nic2userf_s= dp_pio8_nic2user_s;
  575.         dep->de_getblockf= dp_pio8_getblock;
  576.     }
  577.  
  578.     /* Set the interrupt handler and policy. Do not automatically
  579.      * reenable interrupts. Return the IRQ line number on interrupts.
  580.      */
  581. /*  dep->de_hook = dep->de_irq;
  582.     r= sys_irqsetpolicy(dep->de_irq, 0, &dep->de_hook);
  583.     if (r != OK)
  584.         panic("DP8390", "sys_irqsetpolicy failed", r);
  585.  
  586.     r= sys_irqenable(&dep->de_hook);
  587.     if (r != OK)
  588.     {
  589.         panic("DP8390", "unable enable interrupts", r);
  590.     }
  591. */
  592. }
  593.  
  594. /*===========================================================================*
  595.  *              dp_reinit                    *
  596.  *===========================================================================*/
  597. static void dp_reinit(dep)
  598. dpeth_t *dep;
  599. {
  600.     int dp_rcr_reg;
  601.  
  602.     outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
  603.  
  604.     dp_rcr_reg = 0;
  605.     if (dep->de_flags & DEF_PROMISC)
  606.         dp_rcr_reg |= RCR_AB | RCR_PRO | RCR_AM;
  607.     if (dep->de_flags & DEF_BROAD)
  608.         dp_rcr_reg |= RCR_AB;
  609.     if (dep->de_flags & DEF_MULTI)
  610.         dp_rcr_reg |= RCR_AM;
  611.     outb_reg0(dep, DP_RCR, dp_rcr_reg);
  612. }
  613.  
  614. /*===========================================================================*
  615.  *              dp_reset                     *
  616.  *===========================================================================*/
  617. static void dp_reset(dep)
  618. dpeth_t *dep;
  619. {
  620.     int i;
  621.  
  622.     /* Stop chip */
  623.     outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
  624.     outb_reg0(dep, DP_RBCR0, 0);
  625.     outb_reg0(dep, DP_RBCR1, 0);
  626.     for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
  627.         ; /* Do nothing */
  628.     outb_reg0(dep, DP_TCR, TCR_1EXTERNAL|TCR_OFST);
  629.     outb_reg0(dep, DP_CR, CR_STA|CR_DM_ABORT);
  630.     outb_reg0(dep, DP_TCR, TCR_NORMAL);
  631.  
  632.     /* Acknowledge the ISR_RDC (remote dma) interrupt. */
  633.     for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); i++)
  634.         ; /* Do nothing */
  635.     outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & ~ISR_RDC);
  636.  
  637.     /* Reset the transmit ring. If we were transmitting a packet, we
  638.      * pretend that the packet is processed. Higher layers will
  639.      * retransmit if the packet wasn't actually sent.
  640.      */
  641.     dep->de_sendq_head= dep->de_sendq_tail= 0;
  642.     for (i= 0; i<dep->de_sendq_nr; i++)
  643.         dep->de_sendq[i].sq_filled= 0;
  644.     dp_send(dep);
  645.     dep->de_flags &= ~DEF_STOPPED;
  646. }
  647.  
  648. /*===========================================================================*
  649.  *              dp_check_ints                    *
  650.  *===========================================================================*/
  651. void dp_check_ints(dep, isr)
  652. dpeth_t *dep;
  653. int isr;
  654. {
  655.     int /*isr,*/ tsr;
  656.     int size, sendq_tail;
  657.  
  658.     if (!(dep->de_flags & DEF_ENABLED))
  659.         panic("", "dp8390: got premature interrupt", NO_NUM);
  660.  
  661.     for(;;)
  662.     {
  663. //      isr = inb_reg0(dep, DP_ISR);
  664.         if (!isr)
  665.             break;
  666.         outb_reg0(dep, DP_ISR, isr);
  667.         if (isr & (ISR_PTX|ISR_TXE))
  668.         {
  669.             if (isr & ISR_TXE)
  670.             {
  671. #if DEBUG
  672.  { printf("%s: got send Error\n", dep->de_name); }
  673. #endif
  674.                 dep->de_stat.ets_sendErr++;
  675.             }
  676.             else
  677.             {
  678.                 tsr = inb_reg0(dep, DP_TSR);
  679.  
  680.                 if (tsr & TSR_PTX) dep->de_stat.ets_packetT++;
  681. #if 0   /* Reserved in later manuals, should be ignored */
  682.                 if (!(tsr & TSR_DFR))
  683.                 {
  684.                     /* In most (all?) implementations of
  685.                      * the dp8390, this bit is set
  686.                      * when the packet is not deferred
  687.                      */
  688.                     dep->de_stat.ets_transDef++;
  689.                 }
  690. #endif
  691.                 if (tsr & TSR_COL) dep->de_stat.ets_collision++;
  692.                 if (tsr & TSR_ABT) dep->de_stat.ets_transAb++;
  693.                 if (tsr & TSR_CRS) dep->de_stat.ets_carrSense++;
  694.                 if (tsr & TSR_FU
  695.                     && ++dep->de_stat.ets_fifoUnder <= 10)
  696.                 {
  697.                     printf("%s: fifo underrun\n",
  698.                         dep->de_name);
  699.                 }
  700.                 if (tsr & TSR_CDH
  701.                     && ++dep->de_stat.ets_CDheartbeat <= 10)
  702.                 {
  703.                     printf("%s: CD heart beat failure\n",
  704.                         dep->de_name);
  705.                 }
  706.                 if (tsr & TSR_OWC) dep->de_stat.ets_OWC++;
  707.             }
  708.             sendq_tail= dep->de_sendq_tail;
  709.  
  710.             if (!(dep->de_sendq[sendq_tail].sq_filled))
  711.             {
  712.                 /* Software bug? */
  713.                 assert(!debug);
  714.  
  715.                 /* Or hardware bug? */
  716.                 printf(
  717.                 "%s: transmit interrupt, but not sending\n",
  718.                     dep->de_name);
  719.                 continue;
  720.             }
  721.             dep->de_sendq[sendq_tail].sq_filled= 0;
  722.             if (++sendq_tail == dep->de_sendq_nr)
  723.                 sendq_tail= 0;
  724.             dep->de_sendq_tail= sendq_tail;
  725.             if (dep->de_sendq[sendq_tail].sq_filled)
  726.             {
  727.                 size= dep->de_sendq[sendq_tail].sq_size;
  728.                 outb_reg0(dep, DP_TPSR,
  729.                     dep->de_sendq[sendq_tail].sq_sendpage);
  730.                 outb_reg0(dep, DP_TBCR1, size >> 8);
  731.                 outb_reg0(dep, DP_TBCR0, size & 0xff);
  732.                 outb_reg0(dep, DP_CR, CR_TXP | CR_EXTRA);
  733.             }
  734. //          if (dep->de_flags & DEF_SEND_AVAIL)
  735.                 dp_send(dep);
  736.         }
  737.  
  738.         if (isr & ISR_PRX)
  739.         {
  740.             /* Only call dp_recv if there is a read request */
  741. //          if (dep->de_flags) & DEF_READING)
  742.                 dp_recv(dep);
  743.         }
  744.        
  745.         if (isr & ISR_RXE) dep->de_stat.ets_recvErr++;
  746.         if (isr & ISR_CNT)
  747.         {
  748.             dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);
  749.             dep->de_stat.ets_frameAll += inb_reg0(dep, DP_CNTR1);
  750.             dep->de_stat.ets_missedP += inb_reg0(dep, DP_CNTR2);
  751.         }
  752.         if (isr & ISR_OVW)
  753.         {
  754.             dep->de_stat.ets_OVW++;
  755. #if 0
  756.             { printW(); printf(
  757.                 "%s: got overwrite warning\n", dep->de_name); }
  758. #endif
  759. /*          if (dep->de_flags & DEF_READING)
  760.             {
  761.                 printf(
  762. "dp_check_ints: strange: overwrite warning and pending read request\n");
  763.                 dp_recv(dep);
  764.             }
  765. */      }
  766.         if (isr & ISR_RDC)
  767.         {
  768.             /* Nothing to do */
  769.         }
  770.         if (isr & ISR_RST)
  771.         {
  772.             /* this means we got an interrupt but the ethernet
  773.              * chip is shutdown. We set the flag DEF_STOPPED,
  774.              * and continue processing arrived packets. When the
  775.              * receive buffer is empty, we reset the dp8390.
  776.              */
  777. #if 0
  778.              { printW(); printf(
  779.                 "%s: NIC stopped\n", dep->de_name); }
  780. #endif
  781.             dep->de_flags |= DEF_STOPPED;
  782.             break;
  783.         }
  784.         isr = inb_reg0(dep, DP_ISR);
  785.     }
  786. //  if ((dep->de_flags & (DEF_READING|DEF_STOPPED)) ==
  787. //                      (DEF_READING|DEF_STOPPED))
  788.     if ((dep->de_flags & DEF_STOPPED) == DEF_STOPPED )
  789.     {
  790.         /* The chip is stopped, and all arrived packets are
  791.          * delivered.
  792.          */
  793.         dp_reset(dep);
  794.     }
  795. }
  796.  
  797. /*===========================================================================*
  798.  *              dp_recv                      *
  799.  *===========================================================================*/
  800. static void dp_recv(dep)
  801. dpeth_t *dep;
  802. {
  803.     dp_rcvhdr_t header;
  804.     unsigned pageno, curr, next;
  805.     vir_bytes length;
  806.     int packet_processed, r;
  807.     u16_t eth_type;
  808.  
  809.     packet_processed = FALSE;
  810.     pageno = inb_reg0(dep, DP_BNRY) + 1;
  811.     if (pageno == dep->de_stoppage) pageno = dep->de_startpage;
  812.  
  813.     do
  814.     {
  815.         outb_reg0(dep, DP_CR, CR_PS_P1 | CR_EXTRA);
  816.         curr = inb_reg1(dep, DP_CURR);
  817.         outb_reg0(dep, DP_CR, CR_PS_P0 | CR_EXTRA);
  818.  
  819.         if (curr == pageno) break;
  820.  
  821.         (dep->de_getblockf)(dep, pageno, (size_t)0, sizeof(header),
  822.             &header);
  823.         (dep->de_getblockf)(dep, pageno, sizeof(header) +
  824.             2*sizeof(ether_addr_t), sizeof(eth_type), &eth_type);
  825.  
  826.         length = (header.dr_rbcl | (header.dr_rbch << 8)) -
  827.             sizeof(dp_rcvhdr_t);
  828.         next = header.dr_next;
  829.         if (length < ETH_MIN_PACK_SIZE ||
  830.             length > ETH_MAX_PACK_SIZE_TAGGED)
  831.         {
  832.             printf("%s: packet with strange length arrived: %d\n",
  833.                 dep->de_name, (int) length);
  834.             next= curr;
  835.         }
  836.         else if (next < dep->de_startpage || next >= dep->de_stoppage)
  837.         {
  838.             printf("%s: strange next page\n", dep->de_name);
  839.             next= curr;
  840.         }
  841. /*      else if (eth_type == eth_ign_proto)
  842.         {
  843. */          /* Hack: ignore packets of a given protocol, useful
  844.              * if you share a net with 80 computers sending
  845.              * Amoeba FLIP broadcasts.  (Protocol 0x8146.)
  846.              */
  847. /*          static int first= 1;
  848.             if (first)
  849.             {
  850.                 first= 0;
  851.                 printf("%s: dropping proto 0x%04x packets\n",
  852.                     dep->de_name,
  853.                     ntohs(eth_ign_proto));
  854.             }
  855.             dep->de_stat.ets_packetR++;
  856.         }
  857. */      else if (header.dr_status & RSR_FO)
  858.         {
  859.             /* This is very serious, so we issue a warning and
  860.              * reset the buffers */
  861.             printf("%s: fifo overrun, resetting receive buffer\n",
  862.                 dep->de_name);
  863.             dep->de_stat.ets_fifoOver++;
  864.             next = curr;
  865.         }
  866.         else if ((header.dr_status & RSR_PRX) &&
  867.                        (dep->de_flags & DEF_ENABLED))
  868.         {
  869. //          if (dep->de_safecopy_read)
  870. //              r = dp_pkt2user_s(dep, pageno, length);
  871. //          else
  872.                 r = dp_pkt2user(dep, pageno, length);
  873.             if (r != OK)
  874.                 return;
  875.  
  876.             packet_processed = TRUE;
  877.             dep->de_stat.ets_packetR++;
  878.         }
  879.         if (next == dep->de_startpage)
  880.             outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);
  881.         else
  882.             outb_reg0(dep, DP_BNRY, next - 1);
  883.  
  884.         pageno = next;
  885.     }
  886.     while (!packet_processed);
  887. }
  888.  
  889. /*===========================================================================*
  890.  *              dp_send                      *
  891.  *===========================================================================*/
  892. static void dp_send(dep)
  893. dpeth_t *dep;
  894. {
  895.     packet_t packet;
  896.  
  897. //  if (!(dep->de_flags & DEF_SEND_AVAIL))
  898. //      return;
  899.  
  900.     if( dep->packet_queue ){
  901.         packet = dep->packet_queue;
  902.         dep->packet_queue = pq_detach( packet );
  903.         do_pwrite( dep, packet, TRUE );
  904.         netif_pq_release( packet_get_id( packet ));
  905.         -- dep->packet_count;
  906.     }
  907. //  if( ! dep->packet_queue ){
  908. //      dep->de_flags &= ~DEF_SEND_AVAIL;
  909. //  }
  910. /*  switch(dep->de_sendmsg.m_type)
  911.     {
  912.     case DL_WRITE:  do_vwrite(&dep->de_sendmsg, TRUE, FALSE);   break;
  913.     case DL_WRITEV: do_vwrite(&dep->de_sendmsg, TRUE, TRUE);    break;
  914.     case DL_WRITEV_S: do_vwrite_s(&dep->de_sendmsg, TRUE);  break;
  915.     default:
  916.         panic("", "dp8390: wrong type", dep->de_sendmsg.m_type);
  917.         break;
  918.     }
  919. */
  920. }
  921.  
  922. /*===========================================================================*
  923.  *              dp_getblock                  *
  924.  *===========================================================================*/
  925. static void dp_getblock(dep, page, offset, size, dst)
  926. dpeth_t *dep;
  927. int page;
  928. size_t offset;
  929. size_t size;
  930. void *dst;
  931. {
  932. //  int r;
  933.  
  934.     offset = page * DP_PAGESIZE + offset;
  935.  
  936.     memcpy(dst, dep->de_locmem + offset, size);
  937. }
  938.  
  939. /*===========================================================================*
  940.  *              dp_pio8_getblock                 *
  941.  *===========================================================================*/
  942. static void dp_pio8_getblock(dep, page, offset, size, dst)
  943. dpeth_t *dep;
  944. int page;
  945. size_t offset;
  946. size_t size;
  947. void *dst;
  948. {
  949.     offset = page * DP_PAGESIZE + offset;
  950.     outb_reg0(dep, DP_RBCR0, size & 0xFF);
  951.     outb_reg0(dep, DP_RBCR1, size >> 8);
  952.     outb_reg0(dep, DP_RSAR0, offset & 0xFF);
  953.     outb_reg0(dep, DP_RSAR1, offset >> 8);
  954.     outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
  955.  
  956.     insb(dep->de_data_port, dst, size);
  957. }
  958.  
  959. /*===========================================================================*
  960.  *              dp_pio16_getblock                *
  961.  *===========================================================================*/
  962. static void dp_pio16_getblock(dep, page, offset, size, dst)
  963. dpeth_t *dep;
  964. int page;
  965. size_t offset;
  966. size_t size;
  967. void *dst;
  968. {
  969.     offset = page * DP_PAGESIZE + offset;
  970.     outb_reg0(dep, DP_RBCR0, size & 0xFF);
  971.     outb_reg0(dep, DP_RBCR1, size >> 8);
  972.     outb_reg0(dep, DP_RSAR0, offset & 0xFF);
  973.     outb_reg0(dep, DP_RSAR1, offset >> 8);
  974.     outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
  975.  
  976.     assert (!(size & 1));
  977.     insw(dep->de_data_port, dst, size);
  978. }
  979.  
  980. /*===========================================================================*
  981.  *              dp_pkt2user                  *
  982.  *===========================================================================*/
  983. static int dp_pkt2user(dep, page, length)
  984. dpeth_t *dep;
  985. int page, length;
  986. {
  987.     int last, count;
  988.     packet_t    packet;
  989.     packet_t    queue;
  990.  
  991. //  if (!(dep->de_flags & DEF_READING))
  992. //      return EGENERIC;
  993.  
  994.     packet = netif_packet_get_1( length );
  995.     if( ! packet ) return ENOMEM;
  996.     dep->de_read_iovec.iod_iovec[0].iov_addr = ( vir_bytes ) packet_suffix( packet, length );
  997.     dep->de_read_iovec.iod_iovec[0].iov_size = length;
  998.     dep->de_read_iovec.iod_iovec_s = 1;
  999.     dep->de_read_iovec.iod_iovec_addr = NULL;
  1000.  
  1001.     last = page + (length - 1) / DP_PAGESIZE;
  1002.     if (last >= dep->de_stoppage)
  1003.     {
  1004.         count = (dep->de_stoppage - page) * DP_PAGESIZE -
  1005.             sizeof(dp_rcvhdr_t);
  1006.  
  1007.         /* Save read_iovec since we need it twice. */
  1008.         dep->de_tmp_iovec = dep->de_read_iovec;
  1009.         (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
  1010.             sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count);
  1011.         (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE,
  1012.                 &dep->de_read_iovec, count, length - count);
  1013.     }
  1014.     else
  1015.     {
  1016.         (dep->de_nic2userf)(dep, page * DP_PAGESIZE +
  1017.             sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);
  1018.     }
  1019.  
  1020.     dep->de_read_s = length;
  1021.     dep->de_flags |= DEF_PACK_RECV;
  1022. //  dep->de_flags &= ~DEF_READING;
  1023.  
  1024.     if( dep->received_count >= MAX_PACKETS ){
  1025.         netif_pq_release( packet_get_id( packet ));
  1026.         return ELIMIT;
  1027.     }else{
  1028.         queue = pq_add( dep->received_queue, packet, 0, 0 );
  1029.         if( queue ){
  1030.             dep->received_queue = queue;
  1031.             ++ dep->received_count;
  1032.         }else{
  1033.             netif_pq_release( packet_get_id( packet ));
  1034.         }
  1035.     }
  1036.     return OK;
  1037. }
  1038.  
  1039. /*===========================================================================*
  1040.  *              dp_user2nic                  *
  1041.  *===========================================================================*/
  1042. static void dp_user2nic(dep, iovp, offset, nic_addr, count)
  1043. dpeth_t *dep;
  1044. iovec_dat_t *iovp;
  1045. vir_bytes offset;
  1046. int nic_addr;
  1047. vir_bytes count;
  1048. {
  1049.     vir_bytes vir_hw;//, vir_user;
  1050.     int bytes, i, r;
  1051.  
  1052.     vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
  1053.  
  1054.     i= 0;
  1055.     while (count > 0)
  1056.     {
  1057.         if (i >= IOVEC_NR)
  1058.         {
  1059.             dp_next_iovec(iovp);
  1060.             i= 0;
  1061.             continue;
  1062.         }
  1063.         assert(i < iovp->iod_iovec_s);
  1064.         if (offset >= iovp->iod_iovec[i].iov_size)
  1065.         {
  1066.             offset -= iovp->iod_iovec[i].iov_size;
  1067.             i++;
  1068.             continue;
  1069.         }
  1070.         bytes = iovp->iod_iovec[i].iov_size - offset;
  1071.         if (bytes > count)
  1072.             bytes = count;
  1073.  
  1074.         r= sys_vircopy(iovp->iod_proc_nr, D,
  1075.             iovp->iod_iovec[i].iov_addr + offset,
  1076.             SELF, D, vir_hw, bytes);
  1077.         if (r != OK)
  1078.             panic("DP8390", "dp_user2nic: sys_vircopy failed", r);
  1079.  
  1080.         count -= bytes;
  1081.         vir_hw += bytes;
  1082.         offset += bytes;
  1083.     }
  1084.     assert(count == 0);
  1085. }
  1086.  
  1087. /*===========================================================================*
  1088.  *              dp_pio8_user2nic                 *
  1089.  *===========================================================================*/
  1090. static void dp_pio8_user2nic(dep, iovp, offset, nic_addr, count)
  1091. dpeth_t *dep;
  1092. iovec_dat_t *iovp;
  1093. vir_bytes offset;
  1094. int nic_addr;
  1095. vir_bytes count;
  1096. {
  1097. //  phys_bytes phys_user;
  1098.     int bytes, i;
  1099.  
  1100.     outb_reg0(dep, DP_ISR, ISR_RDC);
  1101.  
  1102.     outb_reg0(dep, DP_RBCR0, count & 0xFF);
  1103.     outb_reg0(dep, DP_RBCR1, count >> 8);
  1104.     outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
  1105.     outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
  1106.     outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
  1107.  
  1108.     i= 0;
  1109.     while (count > 0)
  1110.     {
  1111.         if (i >= IOVEC_NR)
  1112.         {
  1113.             dp_next_iovec(iovp);
  1114.             i= 0;
  1115.             continue;
  1116.         }
  1117.         assert(i < iovp->iod_iovec_s);
  1118.         if (offset >= iovp->iod_iovec[i].iov_size)
  1119.         {
  1120.             offset -= iovp->iod_iovec[i].iov_size;
  1121.             i++;
  1122.             continue;
  1123.         }
  1124.         bytes = iovp->iod_iovec[i].iov_size - offset;
  1125.         if (bytes > count)
  1126.             bytes = count;
  1127.  
  1128.         do_vir_outsb(dep->de_data_port, iovp->iod_proc_nr,
  1129.             iovp->iod_iovec[i].iov_addr + offset, bytes);
  1130.         count -= bytes;
  1131.         offset += bytes;
  1132.     }
  1133.     assert(count == 0);
  1134.  
  1135.     for (i= 0; i<100; i++)
  1136.     {
  1137.         if (inb_reg0(dep, DP_ISR) & ISR_RDC)
  1138.             break;
  1139.     }
  1140.     if (i == 100)
  1141.     {
  1142.         panic("", "dp8390: remote dma failed to complete", NO_NUM);
  1143.     }
  1144. }
  1145.  
  1146. /*===========================================================================*
  1147.  *              dp_pio16_user2nic                *
  1148.  *===========================================================================*/
  1149. static void dp_pio16_user2nic(dep, iovp, offset, nic_addr, count)
  1150. dpeth_t *dep;
  1151. iovec_dat_t *iovp;
  1152. vir_bytes offset;
  1153. int nic_addr;
  1154. vir_bytes count;
  1155. {
  1156.     vir_bytes vir_user;
  1157.     vir_bytes ecount;
  1158.     int i, r, bytes, user_proc;
  1159.     u8_t two_bytes[2];
  1160.     int odd_byte;
  1161.  
  1162.     ecount= (count+1) & ~1;
  1163.     odd_byte= 0;
  1164.  
  1165.     outb_reg0(dep, DP_ISR, ISR_RDC);
  1166.     outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
  1167.     outb_reg0(dep, DP_RBCR1, ecount >> 8);
  1168.     outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
  1169.     outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
  1170.     outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
  1171.  
  1172.     i= 0;
  1173.     while (count > 0)
  1174.     {
  1175.         if (i >= IOVEC_NR)
  1176.         {
  1177.             dp_next_iovec(iovp);
  1178.             i= 0;
  1179.             continue;
  1180.         }
  1181.         assert(i < iovp->iod_iovec_s);
  1182.         if (offset >= iovp->iod_iovec[i].iov_size)
  1183.         {
  1184.             offset -= iovp->iod_iovec[i].iov_size;
  1185.             i++;
  1186.             continue;
  1187.         }
  1188.         bytes = iovp->iod_iovec[i].iov_size - offset;
  1189.         if (bytes > count)
  1190.             bytes = count;
  1191.  
  1192.         user_proc= iovp->iod_proc_nr;
  1193.         vir_user= iovp->iod_iovec[i].iov_addr + offset;
  1194.         if (odd_byte)
  1195.         {
  1196.             r= sys_vircopy(user_proc, D, vir_user,
  1197.                 SELF, D, (vir_bytes)&two_bytes[1], 1);
  1198.             if (r != OK)
  1199.             {
  1200.                 panic("DP8390",
  1201.                     "dp_pio16_user2nic: sys_vircopy failed",
  1202.                     r);
  1203.             }
  1204.             outw(dep->de_data_port, *(u16_t *)two_bytes);
  1205.             count--;
  1206.             offset++;
  1207.             bytes--;
  1208.             vir_user++;
  1209.             odd_byte= 0;
  1210.             if (!bytes)
  1211.                 continue;
  1212.         }
  1213.         ecount= bytes & ~1;
  1214.         if (ecount != 0)
  1215.         {
  1216.             do_vir_outsw(dep->de_data_port, user_proc, vir_user,
  1217.                 ecount);
  1218.             count -= ecount;
  1219.             offset += ecount;
  1220.             bytes -= ecount;
  1221.             vir_user += ecount;
  1222.         }
  1223.         if (bytes)
  1224.         {
  1225.             assert(bytes == 1);
  1226.             r= sys_vircopy(user_proc, D, vir_user,
  1227.                 SELF, D, (vir_bytes)&two_bytes[0], 1);
  1228.             if (r != OK)
  1229.             {
  1230.                 panic("DP8390",
  1231.                     "dp_pio16_user2nic: sys_vircopy failed",
  1232.                     r);
  1233.             }
  1234.             count--;
  1235.             offset++;
  1236.             bytes--;
  1237.             vir_user++;
  1238.             odd_byte= 1;
  1239.         }
  1240.     }
  1241.     assert(count == 0);
  1242.  
  1243.     if (odd_byte)
  1244.         outw(dep->de_data_port, *(u16_t *)two_bytes);
  1245.  
  1246.     for (i= 0; i<100; i++)
  1247.     {
  1248.         if (inb_reg0(dep, DP_ISR) & ISR_RDC)
  1249.             break;
  1250.     }
  1251.     if (i == 100)
  1252.     {
  1253.         panic("", "dp8390: remote dma failed to complete", NO_NUM);
  1254.     }
  1255. }
  1256.  
  1257. /*===========================================================================*
  1258.  *              dp_nic2user                  *
  1259.  *===========================================================================*/
  1260. static void dp_nic2user(dep, nic_addr, iovp, offset, count)
  1261. dpeth_t *dep;
  1262. int nic_addr;
  1263. iovec_dat_t *iovp;
  1264. vir_bytes offset;
  1265. vir_bytes count;
  1266. {
  1267.     vir_bytes vir_hw;//, vir_user;
  1268.     int bytes, i, r;
  1269.  
  1270.     vir_hw = (vir_bytes)dep->de_locmem + nic_addr;
  1271.  
  1272.     i= 0;
  1273.     while (count > 0)
  1274.     {
  1275.         if (i >= IOVEC_NR)
  1276.         {
  1277.             dp_next_iovec(iovp);
  1278.             i= 0;
  1279.             continue;
  1280.         }
  1281.         assert(i < iovp->iod_iovec_s);
  1282.         if (offset >= iovp->iod_iovec[i].iov_size)
  1283.         {
  1284.             offset -= iovp->iod_iovec[i].iov_size;
  1285.             i++;
  1286.             continue;
  1287.         }
  1288.         bytes = iovp->iod_iovec[i].iov_size - offset;
  1289.         if (bytes > count)
  1290.             bytes = count;
  1291.  
  1292.         r= sys_vircopy(SELF, D, vir_hw,
  1293.             iovp->iod_proc_nr, D,
  1294.             iovp->iod_iovec[i].iov_addr + offset, bytes);
  1295.         if (r != OK)
  1296.             panic("DP8390", "dp_nic2user: sys_vircopy failed", r);
  1297.  
  1298.         count -= bytes;
  1299.         vir_hw += bytes;
  1300.         offset += bytes;
  1301.     }
  1302.     assert(count == 0);
  1303. }
  1304.  
  1305. /*===========================================================================*
  1306.  *              dp_pio8_nic2user                 *
  1307.  *===========================================================================*/
  1308. static void dp_pio8_nic2user(dep, nic_addr, iovp, offset, count)
  1309. dpeth_t *dep;
  1310. int nic_addr;
  1311. iovec_dat_t *iovp;
  1312. vir_bytes offset;
  1313. vir_bytes count;
  1314. {
  1315. //  phys_bytes phys_user;
  1316.     int bytes, i;
  1317.  
  1318.     outb_reg0(dep, DP_RBCR0, count & 0xFF);
  1319.     outb_reg0(dep, DP_RBCR1, count >> 8);
  1320.     outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
  1321.     outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
  1322.     outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
  1323.  
  1324.     i= 0;
  1325.     while (count > 0)
  1326.     {
  1327.         if (i >= IOVEC_NR)
  1328.         {
  1329.             dp_next_iovec(iovp);
  1330.             i= 0;
  1331.             continue;
  1332.         }
  1333.         assert(i < iovp->iod_iovec_s);
  1334.         if (offset >= iovp->iod_iovec[i].iov_size)
  1335.         {
  1336.             offset -= iovp->iod_iovec[i].iov_size;
  1337.             i++;
  1338.             continue;
  1339.         }
  1340.         bytes = iovp->iod_iovec[i].iov_size - offset;
  1341.         if (bytes > count)
  1342.             bytes = count;
  1343.  
  1344.         do_vir_insb(dep->de_data_port, iovp->iod_proc_nr,
  1345.             iovp->iod_iovec[i].iov_addr + offset, bytes);
  1346.         count -= bytes;
  1347.         offset += bytes;
  1348.     }
  1349.     assert(count == 0);
  1350. }
  1351.  
  1352. /*===========================================================================*
  1353.  *              dp_pio16_nic2user                *
  1354.  *===========================================================================*/
  1355. static void dp_pio16_nic2user(dep, nic_addr, iovp, offset, count)
  1356. dpeth_t *dep;
  1357. int nic_addr;
  1358. iovec_dat_t *iovp;
  1359. vir_bytes offset;
  1360. vir_bytes count;
  1361. {
  1362.     vir_bytes vir_user;
  1363.     vir_bytes ecount;
  1364.     int i, r, bytes, user_proc;
  1365.     u8_t two_bytes[2];
  1366.     int odd_byte;
  1367.  
  1368.     ecount= (count+1) & ~1;
  1369.     odd_byte= 0;
  1370.  
  1371.     outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
  1372.     outb_reg0(dep, DP_RBCR1, ecount >> 8);
  1373.     outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
  1374.     outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
  1375.     outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
  1376.  
  1377.     i= 0;
  1378.     while (count > 0)
  1379.     {
  1380.         if (i >= IOVEC_NR)
  1381.         {
  1382.             dp_next_iovec(iovp);
  1383.             i= 0;
  1384.             continue;
  1385.         }
  1386.         assert(i < iovp->iod_iovec_s);
  1387.         if (offset >= iovp->iod_iovec[i].iov_size)
  1388.         {
  1389.             offset -= iovp->iod_iovec[i].iov_size;
  1390.             i++;
  1391.             continue;
  1392.         }
  1393.         bytes = iovp->iod_iovec[i].iov_size - offset;
  1394.         if (bytes > count)
  1395.             bytes = count;
  1396.  
  1397.         user_proc= iovp->iod_proc_nr;
  1398.         vir_user= iovp->iod_iovec[i].iov_addr + offset;
  1399.         if (odd_byte)
  1400.         {
  1401.             r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[1],
  1402.                 user_proc, D, vir_user,  1);
  1403.             if (r != OK)
  1404.             {
  1405.                 panic("DP8390",
  1406.                     "dp_pio16_nic2user: sys_vircopy failed",
  1407.                     r);
  1408.             }
  1409.             count--;
  1410.             offset++;
  1411.             bytes--;
  1412.             vir_user++;
  1413.             odd_byte= 0;
  1414.             if (!bytes)
  1415.                 continue;
  1416.         }
  1417.         ecount= bytes & ~1;
  1418.         if (ecount != 0)
  1419.         {
  1420.             do_vir_insw(dep->de_data_port, user_proc, vir_user,
  1421.                 ecount);
  1422.             count -= ecount;
  1423.             offset += ecount;
  1424.             bytes -= ecount;
  1425.             vir_user += ecount;
  1426.         }
  1427.         if (bytes)
  1428.         {
  1429.             assert(bytes == 1);
  1430.             *(u16_t *)two_bytes= inw(dep->de_data_port);
  1431.             r= sys_vircopy(SELF, D, (vir_bytes)&two_bytes[0],
  1432.                 user_proc, D, vir_user,  1);
  1433.             if (r != OK)
  1434.             {
  1435.                 panic("DP8390",
  1436.                     "dp_pio16_nic2user: sys_vircopy failed",
  1437.                     r);
  1438.             }
  1439.             count--;
  1440.             offset++;
  1441.             bytes--;
  1442.             vir_user++;
  1443.             odd_byte= 1;
  1444.         }
  1445.     }
  1446.     assert(count == 0);
  1447. }
  1448.  
  1449. /*===========================================================================*
  1450.  *              dp_next_iovec                    *
  1451.  *===========================================================================*/
  1452. static void dp_next_iovec(iovp)
  1453. iovec_dat_t *iovp;
  1454. {
  1455.     assert(iovp->iod_iovec_s > IOVEC_NR);
  1456.  
  1457.     iovp->iod_iovec_s -= IOVEC_NR;
  1458.  
  1459.     iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t);
  1460.  
  1461.     get_userdata(iovp->iod_proc_nr, iovp->iod_iovec_addr,
  1462.         (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) *
  1463.         sizeof(iovec_t), iovp->iod_iovec);
  1464. }
  1465.  
  1466. /*===========================================================================*
  1467.  *              conf_hw                      *
  1468.  *===========================================================================*/
  1469. static void conf_hw(dep)
  1470. dpeth_t *dep;
  1471. {
  1472. //  static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0    /* ,... */ };
  1473.  
  1474. //  int ifnr;
  1475. //  dp_conf_t *dcp;
  1476.  
  1477. //  dep->de_mode= DEM_DISABLED; /* Superfluous */
  1478. //  ifnr= dep-de_table;
  1479.  
  1480. //  dcp= &dp_conf[ifnr];
  1481. //  update_conf(dep, dcp);
  1482. //  if (dep->de_mode != DEM_ENABLED)
  1483. //      return;
  1484.     if (!wdeth_probe(dep) && !ne_probe(dep) && !el2_probe(dep))
  1485.     {
  1486.         printf("%s: No ethernet card found at 0x%x\n",
  1487.             dep->de_name, dep->de_base_port);
  1488.         dep->de_mode= DEM_DISABLED;
  1489.         return;
  1490.     }
  1491.  
  1492. /* XXX */ if (dep->de_linmem == 0) dep->de_linmem= 0xFFFF0000;
  1493.  
  1494.     dep->de_mode = DEM_ENABLED;
  1495.  
  1496.     dep->de_flags = DEF_EMPTY;
  1497. //  dep->de_stat = empty_stat;
  1498. }
  1499.  
  1500. /*===========================================================================*
  1501.  *              map_hw_buffer                    *
  1502.  *===========================================================================*/
  1503. static void map_hw_buffer(dep)
  1504. dpeth_t *dep;
  1505. {
  1506. //  int r;
  1507. //  size_t o, size;
  1508. //  char *buf, *abuf;
  1509.  
  1510.     if (dep->de_prog_IO)
  1511.     {
  1512. #if 0
  1513.         if(debug){
  1514.             printf(
  1515.             "map_hw_buffer: programmed I/O, no need to map buffer\n");
  1516.         }
  1517. #endif
  1518.         dep->de_locmem = (char *)-dep->de_ramsize; /* trap errors */
  1519.         return;
  1520.     }else{
  1521.         printf( "map_hw_buffer: no buffer!\n" );
  1522.     }
  1523.  
  1524. //  size = dep->de_ramsize + PAGE_SIZE; /* Add PAGE_SIZE for
  1525. //                       * alignment
  1526. //                       */
  1527. //  buf= malloc(size);
  1528. //  if (buf == NULL)
  1529. //      panic(__FILE__, "map_hw_buffer: cannot malloc size", size);
  1530. //  o= PAGE_SIZE - ((vir_bytes)buf % PAGE_SIZE);
  1531. //  abuf= buf + o;
  1532. //  printf("buf at 0x%x, abuf at 0x%x\n", buf, abuf);
  1533.  
  1534. //  r= sys_vm_map(SELF, 1 /* map */, (vir_bytes)abuf,
  1535. //          dep->de_ramsize, (phys_bytes)dep->de_linmem);
  1536. //  if (r != OK)
  1537. //      panic(__FILE__, "map_hw_buffer: sys_vm_map failed", r);
  1538. //  dep->de_locmem = abuf;
  1539. }
  1540.  
  1541. /*===========================================================================*
  1542.  *              reply                        *
  1543.  *===========================================================================*/
  1544. static void reply(dep, err, may_block)
  1545. dpeth_t *dep;
  1546. int err;
  1547. int may_block;
  1548. {
  1549. /*  message reply;
  1550.     int status;
  1551.     int r;
  1552.  
  1553.     status = 0;
  1554.     if (dep->de_flags & DEF_PACK_SEND)
  1555.         status |= DL_PACK_SEND;
  1556.     if (dep->de_flags & DEF_PACK_RECV)
  1557.         status |= DL_PACK_RECV;
  1558.  
  1559.     reply.m_type = DL_TASK_REPLY;
  1560.     reply.DL_PORT = dep - de_table;
  1561.     reply.DL_PROC = dep->de_client;
  1562.     reply.DL_STAT = status | ((u32_t) err << 16);
  1563.     reply.DL_COUNT = dep->de_read_s;
  1564.     reply.DL_CLCK = 0;  *//* Don't know */
  1565. /*  r= send(dep->de_client, &reply);
  1566.  
  1567.     if (r == ELOCKED && may_block)
  1568.     {
  1569. #if 0
  1570.         printf("send locked\n");
  1571. #endif
  1572.         return;
  1573.     }
  1574.  
  1575.     if (r < 0)
  1576.         panic("", "dp8390: send failed:", r);
  1577.    
  1578. */  dep->de_read_s = 0;
  1579. //  dep->de_flags &= ~(DEF_PACK_SEND | DEF_PACK_RECV);
  1580. }
  1581.  
  1582. /*===========================================================================*
  1583.  *              get_userdata                     *
  1584.  *===========================================================================*/
  1585. static void get_userdata(user_proc, user_addr, count, loc_addr)
  1586. int user_proc;
  1587. vir_bytes user_addr;
  1588. vir_bytes count;
  1589. void *loc_addr;
  1590. {
  1591.     int r;
  1592.  
  1593.     r= sys_vircopy(user_proc, D, user_addr,
  1594.         SELF, D, (vir_bytes)loc_addr, count);
  1595.     if (r != OK)
  1596.         panic("DP8390", "get_userdata: sys_vircopy failed", r);
  1597. }
  1598.  
  1599. static void insb(port_t port, void *buf, size_t size)
  1600. {
  1601.     size_t i;
  1602.  
  1603.     for( i = 0; i < size; ++ i ){
  1604.         *(( uint8_t * ) buf + i ) = inb( port );
  1605.     }
  1606. }
  1607.  
  1608. static void insw(port_t port, void *buf, size_t size)
  1609. {
  1610.     size_t i;
  1611.  
  1612.     for( i = 0; i * 2 < size; ++ i ){
  1613.         *(( uint16_t * ) buf + i ) = inw( port );
  1614.     }
  1615. }
  1616.  
  1617. static void outsb(port_t port, void *buf, size_t size)
  1618. {
  1619.     size_t i;
  1620.  
  1621.     for( i = 0; i < size; ++ i ){
  1622.         outb( port, *(( uint8_t * ) buf + i ));
  1623.     }
  1624. }
  1625.  
  1626. static void outsw(port_t port, void *buf, size_t size)
  1627. {
  1628.     size_t i;
  1629.  
  1630.     for( i = 0; i * 2 < size; ++ i ){
  1631.         outw( port, *(( uint16_t * ) buf + i ));
  1632.     }
  1633. }
  1634.  
  1635. /*
  1636.  * $PchId: dp8390.c,v 1.25 2005/02/10 17:32:07 philip Exp $
  1637.  */
  1638.  
  1639. /** @}
  1640.  */
  1641.