updated on Tue Jan 10 12:02:00 UTC 2012
[aur-mirror.git] / qemu-6828 / e100
blob9f6cb4aa31f55101ef7d9e9b2e3aac561e718b3f
1 # HG changeset patch
2 # Parent 4a8ebab4db51ea6b64c53788092f9565f0d4236a
4 diff -r 4a8ebab4db51 hw/eepro100.c
5 --- a/hw/eepro100.c     Fri Aug 27 03:15:33 2010 -0400
6 +++ b/hw/eepro100.c     Mon Aug 30 13:06:26 2010 -0400
7 @@ -57,10 +57,12 @@
8  #define KiB 1024
9  
10  /* Debug EEPRO100 card. */
11 -//~ #define DEBUG_EEPRO100
12 +#define DEBUG_EEPRO100
14 +int e100_debug = 0;
16  #ifdef DEBUG_EEPRO100
17 -#define logout(fmt, ...) fprintf(stderr, "EE100\t%-24s" fmt, __func__, ## __VA_ARGS__)
18 +#define logout(fmt, ...) do {if (e100_debug) fprintf(stderr, "EE100\t%-24s" fmt, __func__, ## __VA_ARGS__);} while (0)
19  #else
20  #define logout(fmt, ...) ((void)0)
21  #endif
22 @@ -72,7 +74,7 @@
23  #define RXTX    1
24  #define EEPROM  1       /* eeprom related actions */
26 -#define TRACE(flag, command) ((flag) ? (command) : (void)0)
27 +#define TRACE(flag, command) do {if (flag) {command;}} while (0)
29  #define missing(text) fprintf(stderr, "eepro100: feature is missing in this emulation: " text "\n")
31 @@ -164,6 +166,15 @@
32  } eepro100_rx_t;
34  typedef struct {
35 +    uint16_t count;
36 +    uint16_t pad0;
37 +    uint32_t link;
38 +    uint32_t buf_addr;
39 +    uint16_t size;
40 +    uint16_t pad1;
41 +} eepro100_rbd_t;
43 +typedef struct {
44      uint32_t tx_good_frames, tx_max_collisions, tx_late_collisions,
45          tx_underruns, tx_lost_crs, tx_deferred, tx_single_collisions,
46          tx_multiple_collisions, tx_total_collisions;
47 @@ -211,6 +222,7 @@
48      /* (ru_base + ru_offset) address the RFD in the Receive Frame Area. */
49      uint32_t ru_base;           /* RU base address */
50      uint32_t ru_offset;         /* RU address offset */
51 +    uint32_t rbd_offset;        /* RBD address offset */
52      uint32_t statsaddr;         /* pointer to eepro100_stats_t */
54      /* Statistical counters. Also used for wake-up packet (i82559). */
55 @@ -758,7 +770,7 @@
56          uint16_t command = le16_to_cpu(tx.command);
57          logout
58              ("val=0x%02x (cu start), status=0x%04x, command=0x%04x, link=0x%08x\n",
59 -             val, status, command, tx.link);
60 +             CU_START, status, command, tx.link);
61          bool bit_el = ((command & 0x8000) != 0);
62          bool bit_s = ((command & 0x4000) != 0);
63          bool bit_i = ((command & 0x2000) != 0);
64 @@ -773,7 +785,7 @@
65              break;
66          case CmdIASetup:
67              cpu_physical_memory_read(cb_address + 8, &s->conf.macaddr.a[0], 6);
68 -            TRACE(OTHER, logout("macaddr: %s\n", nic_dump(&s->macaddr[0], 6)));
69 +            TRACE(OTHER, logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6)));
70              break;
71          case CmdConfigure:
72              cpu_physical_memory_read(cb_address + 8, &s->configuration[0],
73 @@ -812,18 +824,13 @@
74              uint16_t size = 0;
75              uint32_t tbd_address = cb_address + 0x10;
76              assert(tcb_bytes <= sizeof(buf));
77 -            while (size < tcb_bytes) {
78 -                uint32_t tx_buffer_address = ldl_phys(tbd_address);
79 -                uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
80 -                //~ uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
81 -                tbd_address += 8;
82 +            if (tbd_array == 0xffffffff) {
83 +                /* Simplified mode. */
84                  TRACE(RXTX, logout
85                      ("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n",
86 -                     tx_buffer_address, tx_buffer_size));
87 -                tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
88 -                cpu_physical_memory_read(tx_buffer_address, &buf[size],
89 -                                         tx_buffer_size);
90 -                size += tx_buffer_size;
91 +                     tbd_address, tcb_bytes));
92 +                cpu_physical_memory_read(tbd_address, buf, tcb_bytes);
93 +                size = tcb_bytes;
94              }
95              if (tbd_array == 0xffffffff) {
96                  /* Simplified mode. Was already handled by code above. */
97 @@ -834,7 +841,7 @@
98                      /* Extended Flexible TCB. */
99                      for (; tbd_count < 2; tbd_count++) {
100                          uint32_t tx_buffer_address = ldl_phys(tbd_address);
101 -                        uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
102 +                        uint16_t tx_buffer_size = lduw_phys(tbd_address + 4) & 0x3fff;
103                          uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
104                          tbd_address += 8;
105                          TRACE(RXTX, logout
106 @@ -987,6 +994,16 @@
107          }
108          set_ru_state(s, ru_ready);
109          s->ru_offset = s->pointer;
111 +        eepro100_rx_t rx;
112 +        cpu_physical_memory_read(s->ru_base + s->ru_offset, (uint8_t *) & rx,
113 +                                 offsetof(eepro100_rx_t, packet));
114 +        uint16_t rfd_command = le16_to_cpu(rx.command);
116 +        /* If the SF bit is set, then use flexible mode. */
117 +        if (rfd_command & 0x0008)
118 +            s->rbd_offset = le32_to_cpu(rx.rx_buf_addr);
120          TRACE(OTHER, logout("val=0x%02x (rx start)\n", val));
121          break;
122      case RX_RESUME:
123 @@ -1003,6 +1020,10 @@
124          TRACE(OTHER, logout("val=0x%02x (RU base address)\n", val));
125          s->ru_base = s->pointer;
126          break;
127 +    case RX_ABORT:
128 +        /* TODO XXX _AP_ need to generate interrupts and halt all activity. */
129 +        set_ru_state(s, ru_idle);
130 +        break;
131      default:
132          logout("val=0x%02x (undefined RU command)\n", val);
133          missing("Undefined SU command");
134 @@ -1696,7 +1717,6 @@
135            rfd_command, rx.link, rx.rx_buf_addr, rfd_size));
136      stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, status),
137               rfd_status);
138 -    stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, count), size);
139      /* Early receive interrupt not supported. */
140      //~ eepro100_er_interrupt(s);
141      /* Receive CRC Transfer not supported. */
142 @@ -1706,8 +1726,28 @@
143      }
144      /* TODO: check stripping enable bit. */
145      //~ assert(!(s->configuration[17] & 1));
146 -    cpu_physical_memory_write(s->ru_base + s->ru_offset +
147 -                              offsetof(eepro100_rx_t, packet), buf, size);
149 +    if (rfd_command & 0x0008) {
150 +       /* XXX TODO _AP_ support more links */
151 +       eepro100_rbd_t rbd;
152 +       int wrote = 0;
153 +       do {
154 +            cpu_physical_memory_read(s->ru_base + s->rbd_offset, (uint8_t *) &rbd, sizeof(rbd));
155 +            int w = (size - wrote) > rbd.size ? rbd.size : (size - wrote);
156 +            cpu_physical_memory_write(s->ru_base + rbd.buf_addr, buf + wrote, w);
157 +            stw_phys(s->ru_base + s->rbd_offset, w | 0x8000 | 0x4000);
158 +            wrote += w;
159 +            s->rbd_offset = le32_to_cpu(rbd.link);
160 +       } while(wrote < size);
161 +    } else {
162 +        /* Simplified mode. */
163 +        assert(size <= rfd_size);
164 +        cpu_physical_memory_write(s->ru_base + s->ru_offset +
165 +                                  offsetof(eepro100_rx_t, packet), buf, size);
166 +    }
167 +    /* Update the EOF and F bits in addition to setting the size. */
168 +    stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, count), size | 0x8000 | 0x4000);
170      s->statistics.rx_good_frames++;
171      eepro100_fr_interrupt(s);
172      s->ru_offset = le32_to_cpu(rx.link);
173 @@ -1747,6 +1787,7 @@
174          VMSTATE_UINT32(cu_offset, EEPRO100State),
175          VMSTATE_UINT32(ru_base, EEPRO100State),
176          VMSTATE_UINT32(ru_offset, EEPRO100State),
177 +        VMSTATE_UINT32(rbd_offset, EEPRO100State),
178          VMSTATE_UINT32(statsaddr, EEPRO100State),
179          /* Save eepro100_stats_t statistics. */
180          VMSTATE_UINT32(statistics.tx_good_frames, EEPRO100State),
181 @@ -1832,7 +1873,7 @@
182                             pci_mmio_map);
184      qemu_macaddr_default_if_unset(&s->conf.macaddr);
185 -    logout("macaddr: %s\n", nic_dump(&s->macaddr[0], 6));
186 +    logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6));
187      assert(s->region[1] == 0);
189      nic_reset(s);
190 diff -r 4a8ebab4db51 qemu-options.hx
191 --- a/qemu-options.hx   Fri Aug 27 03:15:33 2010 -0400
192 +++ b/qemu-options.hx   Mon Aug 30 13:06:26 2010 -0400
193 @@ -1954,6 +1954,13 @@
194  Write device configuration to @var{file}.
195  ETEXI
197 +DEF("debug-e100", 0, QEMU_OPTION_debug_e100,
198 +"-debug-e100     print E100 debug statments\n")
199 +STEXI
200 +@item -debug-e100
201 +Print E100 debug statments.
202 +ETEXI
204  HXCOMM This is the last statement. Insert new options before this line!
205  STEXI
206  @end table
207 diff -r 4a8ebab4db51 vl.c
208 --- a/vl.c      Fri Aug 27 03:15:33 2010 -0400
209 +++ b/vl.c      Mon Aug 30 13:06:26 2010 -0400
210 @@ -5653,6 +5653,12 @@
211                      fclose(fp);
212                      break;
213                  }
214 +            case QEMU_OPTION_debug_e100:
215 +                {
216 +                    extern int e100_debug;
217 +                    e100_debug = 1;
218 +                    break;
219 +                }
220              }
221          }
222      }