/[gxemul]/trunk/src/devices/dev_le.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/devices/dev_le.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 4 by dpavlin, Mon Oct 8 16:18:00 2007 UTC revision 28 by dpavlin, Mon Oct 8 16:20:26 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_le.c,v 1.39 2005/03/14 19:14:02 debug Exp $   *  $Id: dev_le.c,v 1.51 2006/07/14 16:33:28 debug Exp $
29   *     *  
30   *  LANCE ethernet, as used in DECstations.   *  LANCE ethernet, as used in DECstations.
31   *   *
# Line 47  Line 47 
47   *   *
48   *  TODO:  Error conditions (such as when there are not enough receive   *  TODO:  Error conditions (such as when there are not enough receive
49   *         buffers) are not emulated yet.   *         buffers) are not emulated yet.
50     *
51     *         (Old bug, but probably still valid:  "UDP packets that are too
52     *         large are not handled well by the Lance device.")
53   */   */
54    
55  #include <stdio.h>  #include <stdio.h>
# Line 93  struct le_data { Line 96  struct le_data {
96          int             reg_select;          int             reg_select;
97          uint16_t        reg[N_REGISTERS];          uint16_t        reg[N_REGISTERS];
98    
99          unsigned char   sram[SRAM_SIZE];          unsigned char   *sram;
100    
101          /*  Initialization block:  */          /*  Initialization block:  */
102          uint32_t        init_block_addr;          uint32_t        init_block_addr;
# Line 230  static void le_tx(struct net *net, struc Line 233  static void le_tx(struct net *net, struc
233  {  {
234          int start_txp = d->txp;          int start_txp = d->txp;
235          uint16_t tx_descr[4];          uint16_t tx_descr[4];
236          int stp, enp, i, cur_packet_offset;          int stp, enp, cur_packet_offset;
237            size_t i;
238          uint32_t bufaddr, buflen;          uint32_t bufaddr, buflen;
239    
240          /*  TODO: This is just a guess:  */          /*  TODO: This is just a guess:  */
# Line 349  static void le_tx(struct net *net, struc Line 353  static void le_tx(struct net *net, struc
353   */   */
354  static void le_rx(struct net *net, struct le_data *d)  static void le_rx(struct net *net, struct le_data *d)
355  {  {
356          int i, start_rxp = d->rxp;          int start_rxp = d->rxp;
357            size_t i;
358          uint16_t rx_descr[4];          uint16_t rx_descr[4];
359          uint32_t bufaddr, buflen;          uint32_t bufaddr, buflen;
360    
# Line 387  static void le_rx(struct net *net, struc Line 392  static void le_rx(struct net *net, struc
392    
393                  /*  Copy data from the packet into SRAM:  */                  /*  Copy data from the packet into SRAM:  */
394                  for (i=0; i<buflen; i++) {                  for (i=0; i<buflen; i++) {
395                          if (d->rx_packet_offset + i >= d->rx_packet_len)                          if (d->rx_packet_offset+(ssize_t)i >= d->rx_packet_len)
396                                  break;                                  break;
397                          d->sram[(bufaddr + i) & (SRAM_SIZE-1)] =                          d->sram[(bufaddr + i) & (SRAM_SIZE-1)] =
398                              d->rx_packet[d->rx_packet_offset + i];                              d->rx_packet[d->rx_packet_offset + i];
# Line 599  void le_register_write(struct le_data *d Line 604  void le_register_write(struct le_data *d
604  }  }
605    
606    
607  /*  DEVICE_ACCESS(le_sram)
  *  dev_le_sram_access():  
  */  
 int dev_le_sram_access(struct cpu *cpu, struct memory *mem,  
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
608  {  {
609          int i, retval;          size_t i;
610            int retval;
611          struct le_data *d = extra;          struct le_data *d = extra;
612    
613  #ifdef LE_DEBUG  #ifdef LE_DEBUG
# Line 648  int dev_le_sram_access(struct cpu *cpu, Line 649  int dev_le_sram_access(struct cpu *cpu,
649  }  }
650    
651    
652  /*  DEVICE_ACCESS(le)
  *  dev_le_access():  
  */  
 int dev_le_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr,  
         unsigned char *data, size_t len, int writeflag, void *extra)  
653  {  {
654          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
655          int i, retval = 1;          size_t i;
656            int retval = 1;
657          struct le_data *d = extra;          struct le_data *d = extra;
658    
659          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
660                    idata = memory_readmax64(cpu, data, len);
661    
662  #ifdef LE_DEBUG  #ifdef LE_DEBUG
663          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
# Line 671  int dev_le_access(struct cpu *cpu, struc Line 670  int dev_le_access(struct cpu *cpu, struc
670    
671          /*  Read from station's ROM (ethernet address):  */          /*  Read from station's ROM (ethernet address):  */
672          if (relative_addr >= 0xc0000 && relative_addr <= 0xfffff) {          if (relative_addr >= 0xc0000 && relative_addr <= 0xfffff) {
673                  i = (relative_addr & 0xff) / 4;                  uint32_t a;
674                  i = d->rom[i & (ROM_SIZE-1)];                  int j = (relative_addr & 0xff) / 4;
675                    a = d->rom[j & (ROM_SIZE-1)];
676    
677                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
678                          odata = (i << 24) + (i << 16) + (i << 8) + i;                          odata = (a << 24) + (a << 16) + (a << 8) + a;
679                  } else {                  } else {
680                          fatal("[ le: WRITE to ethernet addr (%08lx):",                          fatal("[ le: WRITE to ethernet addr (%08lx):",
681                              (long)relative_addr);                              (long)relative_addr);
# Line 768  void dev_le_init(struct machine *machine Line 768  void dev_le_init(struct machine *machine
768          uint64_t buf_start, uint64_t buf_end, int irq_nr, int len)          uint64_t buf_start, uint64_t buf_end, int irq_nr, int len)
769  {  {
770          char *name2;          char *name2;
771            size_t nlen = 55;
772          struct le_data *d = malloc(sizeof(struct le_data));          struct le_data *d = malloc(sizeof(struct le_data));
773    
774          if (d == NULL) {          if (d == NULL) {
# Line 778  void dev_le_init(struct machine *machine Line 779  void dev_le_init(struct machine *machine
779          memset(d, 0, sizeof(struct le_data));          memset(d, 0, sizeof(struct le_data));
780          d->irq_nr    = irq_nr;          d->irq_nr    = irq_nr;
781    
782            d->sram = malloc(SRAM_SIZE);
783            if (d->sram == NULL) {
784                    fprintf(stderr, "out of memory\n");
785                    exit(1);
786            }
787            memset(d->sram, 0, SRAM_SIZE);
788    
789          /*  TODO:  Are these actually used yet?  */          /*  TODO:  Are these actually used yet?  */
790          d->len       = len;          d->len       = len;
791          d->buf_start = buf_start;          d->buf_start = buf_start;
# Line 792  void dev_le_init(struct machine *machine Line 800  void dev_le_init(struct machine *machine
800          /*  ROM (including the MAC address):  */          /*  ROM (including the MAC address):  */
801          net_generate_unique_mac(machine, &d->rom[0]);          net_generate_unique_mac(machine, &d->rom[0]);
802    
         /*  
          *  NOTE:  According to the Lance documentation, the low order bit of  
          *  a physical MAC address should be clear.  However, NetBSD and  
          *  Linux drop packets if the _first_ byte's lowest bit is not zero.  
          */  
         d->rom[0] &= ~1;  
         d->rom[5] &= ~1;  
   
803          /*  Copies of the MAC address and a test pattern:  */          /*  Copies of the MAC address and a test pattern:  */
804          d->rom[10] = d->rom[21] = d->rom[5];          d->rom[10] = d->rom[21] = d->rom[5];
805          d->rom[11] = d->rom[20] = d->rom[4];          d->rom[11] = d->rom[20] = d->rom[4];
# Line 816  void dev_le_init(struct machine *machine Line 816  void dev_le_init(struct machine *machine
816    
817          memory_device_register(mem, "le_sram", baseaddr,          memory_device_register(mem, "le_sram", baseaddr,
818              SRAM_SIZE, dev_le_sram_access, (void *)d,              SRAM_SIZE, dev_le_sram_access, (void *)d,
819              MEM_BINTRANS_OK | MEM_BINTRANS_WRITE_OK, d->sram);              DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK
820                | DM_READS_HAVE_NO_SIDE_EFFECTS, d->sram);
821    
822          name2 = malloc(50);          name2 = malloc(nlen);
823          if (name2 == NULL) {          if (name2 == NULL) {
824                  fprintf(stderr, "out of memory in dev_le_init()\n");                  fprintf(stderr, "out of memory in dev_le_init()\n");
825                  exit(1);                  exit(1);
826          }          }
827          sprintf(name2, "le [%02x:%02x:%02x:%02x:%02x:%02x]",          snprintf(name2, nlen, "le [%02x:%02x:%02x:%02x:%02x:%02x]",
828              d->rom[0], d->rom[1], d->rom[2], d->rom[3], d->rom[4], d->rom[5]);              d->rom[0], d->rom[1], d->rom[2], d->rom[3], d->rom[4], d->rom[5]);
829    
830          memory_device_register(mem, name2, baseaddr + 0x100000,          memory_device_register(mem, name2, baseaddr + 0x100000,
831              len - 0x100000, dev_le_access, (void *)d, MEM_DEFAULT, NULL);              len - 0x100000, dev_le_access, (void *)d, DM_DEFAULT, NULL);
832    
833          machine_add_tickfunction(machine, dev_le_tick, d, LE_TICK_SHIFT);          machine_add_tickfunction(machine, dev_le_tick, d, LE_TICK_SHIFT, 0.0);
834    
835          net_add_nic(machine->emul->net, d, &d->rom[0]);          net_add_nic(machine->emul->net, d, &d->rom[0]);
836  }  }

Legend:
Removed from v.4  
changed lines
  Added in v.28

  ViewVC Help
Powered by ViewVC 1.1.26