Statistics
| Branch: | Revision:

root / hw / eepro100.c @ c0b1905b

History | View | Annotate | Download (61.3 kB)

1 663e8e51 ths
/*
2 663e8e51 ths
 * QEMU i8255x (PRO100) emulation
3 663e8e51 ths
 *
4 663e8e51 ths
 * Copyright (c) 2006-2007 Stefan Weil
5 663e8e51 ths
 *
6 663e8e51 ths
 * Portions of the code are copies from grub / etherboot eepro100.c
7 663e8e51 ths
 * and linux e100.c.
8 663e8e51 ths
 *
9 663e8e51 ths
 * This program is free software; you can redistribute it and/or modify
10 663e8e51 ths
 * it under the terms of the GNU General Public License as published by
11 663e8e51 ths
 * the Free Software Foundation; either version 2 of the License, or
12 663e8e51 ths
 * (at your option) any later version.
13 663e8e51 ths
 *
14 663e8e51 ths
 * This program is distributed in the hope that it will be useful,
15 663e8e51 ths
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 663e8e51 ths
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 663e8e51 ths
 * GNU General Public License for more details.
18 663e8e51 ths
 *
19 663e8e51 ths
 * You should have received a copy of the GNU General Public License
20 8167ee88 Blue Swirl
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 663e8e51 ths
 *
22 663e8e51 ths
 * Tested features (i82559):
23 663e8e51 ths
 *      PXE boot (i386) no valid link
24 663e8e51 ths
 *      Linux networking (i386) ok
25 663e8e51 ths
 *
26 663e8e51 ths
 * Untested:
27 663e8e51 ths
 *      non-i386 platforms
28 663e8e51 ths
 *      Windows networking
29 663e8e51 ths
 *
30 663e8e51 ths
 * References:
31 663e8e51 ths
 *
32 663e8e51 ths
 * Intel 8255x 10/100 Mbps Ethernet Controller Family
33 663e8e51 ths
 * Open Source Software Developer Manual
34 663e8e51 ths
 */
35 663e8e51 ths
36 663e8e51 ths
#if defined(TARGET_I386)
37 663e8e51 ths
# warning "PXE boot still not working!"
38 663e8e51 ths
#endif
39 663e8e51 ths
40 663e8e51 ths
#include <stddef.h>             /* offsetof */
41 b84a5c6f Amit Shah
#include <stdbool.h>
42 87ecb68b pbrook
#include "hw.h"
43 87ecb68b pbrook
#include "pci.h"
44 87ecb68b pbrook
#include "net.h"
45 663e8e51 ths
#include "eeprom93xx.h"
46 663e8e51 ths
47 663e8e51 ths
/* Common declarations for all PCI devices. */
48 663e8e51 ths
49 663e8e51 ths
#define PCI_CONFIG_8(offset, value) \
50 663e8e51 ths
    (pci_conf[offset] = (value))
51 663e8e51 ths
#define PCI_CONFIG_16(offset, value) \
52 663e8e51 ths
    (*(uint16_t *)&pci_conf[offset] = cpu_to_le16(value))
53 663e8e51 ths
#define PCI_CONFIG_32(offset, value) \
54 663e8e51 ths
    (*(uint32_t *)&pci_conf[offset] = cpu_to_le32(value))
55 663e8e51 ths
56 663e8e51 ths
#define KiB 1024
57 663e8e51 ths
58 aac443e6 Stefan Weil
/* Debug EEPRO100 card. */
59 663e8e51 ths
//~ #define DEBUG_EEPRO100
60 663e8e51 ths
61 663e8e51 ths
#ifdef DEBUG_EEPRO100
62 001faf32 Blue Swirl
#define logout(fmt, ...) fprintf(stderr, "EE100\t%-24s" fmt, __func__, ## __VA_ARGS__)
63 663e8e51 ths
#else
64 001faf32 Blue Swirl
#define logout(fmt, ...) ((void)0)
65 663e8e51 ths
#endif
66 663e8e51 ths
67 663e8e51 ths
/* Set flags to 0 to disable debug output. */
68 aac443e6 Stefan Weil
#define INT     1       /* interrupt related actions */
69 aac443e6 Stefan Weil
#define MDI     1       /* mdi related actions */
70 aac443e6 Stefan Weil
#define OTHER   1
71 aac443e6 Stefan Weil
#define RXTX    1
72 aac443e6 Stefan Weil
#define EEPROM  1       /* eeprom related actions */
73 663e8e51 ths
74 663e8e51 ths
#define TRACE(flag, command) ((flag) ? (command) : (void)0)
75 663e8e51 ths
76 663e8e51 ths
#define missing(text)       assert(!"feature is missing in this emulation: " text)
77 663e8e51 ths
78 663e8e51 ths
#define MAX_ETH_FRAME_SIZE 1514
79 663e8e51 ths
80 663e8e51 ths
/* This driver supports several different devices which are declared here. */
81 c4c270e2 Stefan Weil
#define i82550          0x82550
82 663e8e51 ths
#define i82551          0x82551
83 c4c270e2 Stefan Weil
#define i82557A         0x82557a
84 663e8e51 ths
#define i82557B         0x82557b
85 663e8e51 ths
#define i82557C         0x82557c
86 c4c270e2 Stefan Weil
#define i82558A         0x82558a
87 663e8e51 ths
#define i82558B         0x82558b
88 c4c270e2 Stefan Weil
#define i82559A         0x82559a
89 c4c270e2 Stefan Weil
#define i82559B         0x82559b
90 663e8e51 ths
#define i82559C         0x82559c
91 663e8e51 ths
#define i82559ER        0x82559e
92 663e8e51 ths
#define i82562          0x82562
93 663e8e51 ths
94 aac443e6 Stefan Weil
/* Use 64 word EEPROM. TODO: could be a runtime option. */
95 663e8e51 ths
#define EEPROM_SIZE     64
96 663e8e51 ths
97 663e8e51 ths
#define PCI_MEM_SIZE            (4 * KiB)
98 663e8e51 ths
#define PCI_IO_SIZE             64
99 663e8e51 ths
#define PCI_FLASH_SIZE          (128 * KiB)
100 663e8e51 ths
101 663e8e51 ths
#define BIT(n) (1 << (n))
102 663e8e51 ths
#define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
103 663e8e51 ths
104 663e8e51 ths
/* The SCB accepts the following controls for the Tx and Rx units: */
105 663e8e51 ths
#define  CU_NOP         0x0000  /* No operation. */
106 663e8e51 ths
#define  CU_START       0x0010  /* CU start. */
107 663e8e51 ths
#define  CU_RESUME      0x0020  /* CU resume. */
108 663e8e51 ths
#define  CU_STATSADDR   0x0040  /* Load dump counters address. */
109 663e8e51 ths
#define  CU_SHOWSTATS   0x0050  /* Dump statistical counters. */
110 663e8e51 ths
#define  CU_CMD_BASE    0x0060  /* Load CU base address. */
111 663e8e51 ths
#define  CU_DUMPSTATS   0x0070  /* Dump and reset statistical counters. */
112 663e8e51 ths
#define  CU_SRESUME     0x00a0  /* CU static resume. */
113 663e8e51 ths
114 663e8e51 ths
#define  RU_NOP         0x0000
115 663e8e51 ths
#define  RX_START       0x0001
116 663e8e51 ths
#define  RX_RESUME      0x0002
117 663e8e51 ths
#define  RX_ABORT       0x0004
118 663e8e51 ths
#define  RX_ADDR_LOAD   0x0006
119 663e8e51 ths
#define  RX_RESUMENR    0x0007
120 663e8e51 ths
#define INT_MASK        0x0100
121 663e8e51 ths
#define DRVR_INT        0x0200  /* Driver generated interrupt. */
122 663e8e51 ths
123 663e8e51 ths
/* Offsets to the various registers.
124 663e8e51 ths
   All accesses need not be longword aligned. */
125 663e8e51 ths
enum speedo_offsets {
126 663e8e51 ths
    SCBStatus = 0,
127 663e8e51 ths
    SCBAck = 1,
128 663e8e51 ths
    SCBCmd = 2,                 /* Rx/Command Unit command and status. */
129 663e8e51 ths
    SCBIntmask = 3,
130 663e8e51 ths
    SCBPointer = 4,             /* General purpose pointer. */
131 663e8e51 ths
    SCBPort = 8,                /* Misc. commands and operands.  */
132 663e8e51 ths
    SCBflash = 12, SCBeeprom = 14,      /* EEPROM and flash memory control. */
133 663e8e51 ths
    SCBCtrlMDI = 16,            /* MDI interface control. */
134 663e8e51 ths
    SCBEarlyRx = 20,            /* Early receive byte count. */
135 3257d2b6 ths
    SCBFlow = 24,
136 663e8e51 ths
};
137 663e8e51 ths
138 663e8e51 ths
/* A speedo3 transmit buffer descriptor with two buffers... */
139 663e8e51 ths
typedef struct {
140 663e8e51 ths
    uint16_t status;
141 663e8e51 ths
    uint16_t command;
142 663e8e51 ths
    uint32_t link;              /* void * */
143 663e8e51 ths
    uint32_t tx_desc_addr;      /* transmit buffer decsriptor array address. */
144 663e8e51 ths
    uint16_t tcb_bytes;         /* transmit command block byte count (in lower 14 bits */
145 663e8e51 ths
    uint8_t tx_threshold;       /* transmit threshold */
146 663e8e51 ths
    uint8_t tbd_count;          /* TBD number */
147 663e8e51 ths
    //~ /* This constitutes two "TBD" entries: hdr and data */
148 663e8e51 ths
    //~ uint32_t tx_buf_addr0;  /* void *, header of frame to be transmitted.  */
149 663e8e51 ths
    //~ int32_t  tx_buf_size0;  /* Length of Tx hdr. */
150 663e8e51 ths
    //~ uint32_t tx_buf_addr1;  /* void *, data to be transmitted.  */
151 663e8e51 ths
    //~ int32_t  tx_buf_size1;  /* Length of Tx data. */
152 c227f099 Anthony Liguori
} eepro100_tx_t;
153 663e8e51 ths
154 663e8e51 ths
/* Receive frame descriptor. */
155 663e8e51 ths
typedef struct {
156 663e8e51 ths
    int16_t status;
157 663e8e51 ths
    uint16_t command;
158 663e8e51 ths
    uint32_t link;              /* struct RxFD * */
159 663e8e51 ths
    uint32_t rx_buf_addr;       /* void * */
160 663e8e51 ths
    uint16_t count;
161 663e8e51 ths
    uint16_t size;
162 663e8e51 ths
    char packet[MAX_ETH_FRAME_SIZE + 4];
163 c227f099 Anthony Liguori
} eepro100_rx_t;
164 663e8e51 ths
165 663e8e51 ths
typedef struct {
166 663e8e51 ths
    uint32_t tx_good_frames, tx_max_collisions, tx_late_collisions,
167 663e8e51 ths
        tx_underruns, tx_lost_crs, tx_deferred, tx_single_collisions,
168 663e8e51 ths
        tx_multiple_collisions, tx_total_collisions;
169 663e8e51 ths
    uint32_t rx_good_frames, rx_crc_errors, rx_alignment_errors,
170 663e8e51 ths
        rx_resource_errors, rx_overrun_errors, rx_cdt_errors,
171 663e8e51 ths
        rx_short_frame_errors;
172 663e8e51 ths
    uint32_t fc_xmt_pause, fc_rcv_pause, fc_rcv_unsupported;
173 663e8e51 ths
    uint16_t xmt_tco_frames, rcv_tco_frames;
174 663e8e51 ths
    uint32_t complete;
175 c227f099 Anthony Liguori
} eepro100_stats_t;
176 663e8e51 ths
177 663e8e51 ths
typedef enum {
178 663e8e51 ths
    cu_idle = 0,
179 663e8e51 ths
    cu_suspended = 1,
180 663e8e51 ths
    cu_active = 2,
181 663e8e51 ths
    cu_lpq_active = 2,
182 663e8e51 ths
    cu_hqp_active = 3
183 c227f099 Anthony Liguori
} cu_state_t;
184 663e8e51 ths
185 663e8e51 ths
typedef enum {
186 663e8e51 ths
    ru_idle = 0,
187 663e8e51 ths
    ru_suspended = 1,
188 663e8e51 ths
    ru_no_resources = 2,
189 663e8e51 ths
    ru_ready = 4
190 c227f099 Anthony Liguori
} ru_state_t;
191 663e8e51 ths
192 663e8e51 ths
typedef struct {
193 273a2142 Juan Quintela
    PCIDevice dev;
194 663e8e51 ths
#if 1
195 663e8e51 ths
    uint8_t cmd;
196 663e8e51 ths
    uint32_t start;
197 663e8e51 ths
    uint32_t stop;
198 4e3db917 Aurelien Jarno
    uint8_t boundary;
199 4e3db917 Aurelien Jarno
    uint8_t tsr;
200 4e3db917 Aurelien Jarno
    uint8_t tpsr;
201 4e3db917 Aurelien Jarno
    uint16_t tcnt;
202 4e3db917 Aurelien Jarno
    uint16_t rcnt;
203 4e3db917 Aurelien Jarno
    uint32_t rsar;
204 4e3db917 Aurelien Jarno
    uint8_t rsr;
205 4e3db917 Aurelien Jarno
    uint8_t rxcr;
206 4e3db917 Aurelien Jarno
    uint8_t isr;
207 4e3db917 Aurelien Jarno
    uint8_t dcfg;
208 4e3db917 Aurelien Jarno
    uint8_t imr;
209 4e3db917 Aurelien Jarno
    uint8_t phys[6];            /* mac address */
210 4e3db917 Aurelien Jarno
    uint8_t curpag;
211 663e8e51 ths
    uint8_t mult[8];            /* multicast mask array */
212 663e8e51 ths
    int mmio_index;
213 663e8e51 ths
    VLANClientState *vc;
214 663e8e51 ths
#endif
215 663e8e51 ths
    uint8_t scb_stat;           /* SCB stat/ack byte */
216 663e8e51 ths
    uint8_t int_stat;           /* PCI interrupt status */
217 663e8e51 ths
    uint32_t region[3];         /* PCI region addresses */
218 663e8e51 ths
    uint8_t macaddr[6];
219 4e3db917 Aurelien Jarno
    uint32_t statcounter[19];
220 663e8e51 ths
    uint16_t mdimem[32];
221 c227f099 Anthony Liguori
    eeprom_t *eeprom;
222 663e8e51 ths
    uint32_t device;            /* device variant */
223 663e8e51 ths
    uint32_t pointer;
224 663e8e51 ths
    /* (cu_base + cu_offset) address the next command block in the command block list. */
225 663e8e51 ths
    uint32_t cu_base;           /* CU base address */
226 663e8e51 ths
    uint32_t cu_offset;         /* CU address offset */
227 663e8e51 ths
    /* (ru_base + ru_offset) address the RFD in the Receive Frame Area. */
228 663e8e51 ths
    uint32_t ru_base;           /* RU base address */
229 663e8e51 ths
    uint32_t ru_offset;         /* RU address offset */
230 c227f099 Anthony Liguori
    uint32_t statsaddr;         /* pointer to eepro100_stats_t */
231 4e3db917 Aurelien Jarno
    eepro100_stats_t statistics;        /* statistical counters */
232 663e8e51 ths
#if 0
233 663e8e51 ths
    uint16_t status;
234 663e8e51 ths
#endif
235 663e8e51 ths
236 663e8e51 ths
    /* Configuration bytes. */
237 663e8e51 ths
    uint8_t configuration[22];
238 663e8e51 ths
239 663e8e51 ths
    /* Data in mem is always in the byte order of the controller (le). */
240 663e8e51 ths
    uint8_t mem[PCI_MEM_SIZE];
241 663e8e51 ths
} EEPRO100State;
242 663e8e51 ths
243 663e8e51 ths
/* Default values for MDI (PHY) registers */
244 663e8e51 ths
static const uint16_t eepro100_mdi_default[] = {
245 663e8e51 ths
    /* MDI Registers 0 - 6, 7 */
246 663e8e51 ths
    0x3000, 0x780d, 0x02a8, 0x0154, 0x05e1, 0x0000, 0x0000, 0x0000,
247 663e8e51 ths
    /* MDI Registers 8 - 15 */
248 663e8e51 ths
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
249 663e8e51 ths
    /* MDI Registers 16 - 31 */
250 663e8e51 ths
    0x0003, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
251 663e8e51 ths
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
252 663e8e51 ths
};
253 663e8e51 ths
254 663e8e51 ths
/* Readonly mask for MDI (PHY) registers */
255 663e8e51 ths
static const uint16_t eepro100_mdi_mask[] = {
256 663e8e51 ths
    0x0000, 0xffff, 0xffff, 0xffff, 0xc01f, 0xffff, 0xffff, 0x0000,
257 663e8e51 ths
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
258 663e8e51 ths
    0x0fff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
259 663e8e51 ths
    0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
260 663e8e51 ths
};
261 663e8e51 ths
262 663e8e51 ths
#define POLYNOMIAL 0x04c11db6
263 663e8e51 ths
264 663e8e51 ths
/* From FreeBSD */
265 663e8e51 ths
/* XXX: optimize */
266 663e8e51 ths
static int compute_mcast_idx(const uint8_t * ep)
267 663e8e51 ths
{
268 663e8e51 ths
    uint32_t crc;
269 663e8e51 ths
    int carry, i, j;
270 663e8e51 ths
    uint8_t b;
271 663e8e51 ths
272 663e8e51 ths
    crc = 0xffffffff;
273 663e8e51 ths
    for (i = 0; i < 6; i++) {
274 663e8e51 ths
        b = *ep++;
275 663e8e51 ths
        for (j = 0; j < 8; j++) {
276 663e8e51 ths
            carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
277 663e8e51 ths
            crc <<= 1;
278 663e8e51 ths
            b >>= 1;
279 aac443e6 Stefan Weil
            if (carry) {
280 663e8e51 ths
                crc = ((crc ^ POLYNOMIAL) | carry);
281 aac443e6 Stefan Weil
            }
282 663e8e51 ths
        }
283 663e8e51 ths
    }
284 663e8e51 ths
    return (crc >> 26);
285 663e8e51 ths
}
286 663e8e51 ths
287 663e8e51 ths
#if defined(DEBUG_EEPRO100)
288 663e8e51 ths
static const char *nic_dump(const uint8_t * buf, unsigned size)
289 663e8e51 ths
{
290 663e8e51 ths
    static char dump[3 * 16 + 1];
291 663e8e51 ths
    char *p = &dump[0];
292 aac443e6 Stefan Weil
    if (size > 16) {
293 663e8e51 ths
        size = 16;
294 aac443e6 Stefan Weil
    }
295 663e8e51 ths
    while (size-- > 0) {
296 663e8e51 ths
        p += sprintf(p, " %02x", *buf++);
297 663e8e51 ths
    }
298 663e8e51 ths
    return dump;
299 663e8e51 ths
}
300 663e8e51 ths
#endif                          /* DEBUG_EEPRO100 */
301 663e8e51 ths
302 663e8e51 ths
enum scb_stat_ack {
303 663e8e51 ths
    stat_ack_not_ours = 0x00,
304 663e8e51 ths
    stat_ack_sw_gen = 0x04,
305 663e8e51 ths
    stat_ack_rnr = 0x10,
306 663e8e51 ths
    stat_ack_cu_idle = 0x20,
307 663e8e51 ths
    stat_ack_frame_rx = 0x40,
308 663e8e51 ths
    stat_ack_cu_cmd_done = 0x80,
309 663e8e51 ths
    stat_ack_not_present = 0xFF,
310 663e8e51 ths
    stat_ack_rx = (stat_ack_sw_gen | stat_ack_rnr | stat_ack_frame_rx),
311 663e8e51 ths
    stat_ack_tx = (stat_ack_cu_idle | stat_ack_cu_cmd_done),
312 663e8e51 ths
};
313 663e8e51 ths
314 663e8e51 ths
static void disable_interrupt(EEPRO100State * s)
315 663e8e51 ths
{
316 663e8e51 ths
    if (s->int_stat) {
317 aac443e6 Stefan Weil
        TRACE(INT, logout("interrupt disabled\n"));
318 273a2142 Juan Quintela
        qemu_irq_lower(s->dev.irq[0]);
319 663e8e51 ths
        s->int_stat = 0;
320 663e8e51 ths
    }
321 663e8e51 ths
}
322 663e8e51 ths
323 663e8e51 ths
static void enable_interrupt(EEPRO100State * s)
324 663e8e51 ths
{
325 663e8e51 ths
    if (!s->int_stat) {
326 aac443e6 Stefan Weil
        TRACE(INT, logout("interrupt enabled\n"));
327 273a2142 Juan Quintela
        qemu_irq_raise(s->dev.irq[0]);
328 663e8e51 ths
        s->int_stat = 1;
329 663e8e51 ths
    }
330 663e8e51 ths
}
331 663e8e51 ths
332 663e8e51 ths
static void eepro100_acknowledge(EEPRO100State * s)
333 663e8e51 ths
{
334 663e8e51 ths
    s->scb_stat &= ~s->mem[SCBAck];
335 663e8e51 ths
    s->mem[SCBAck] = s->scb_stat;
336 663e8e51 ths
    if (s->scb_stat == 0) {
337 663e8e51 ths
        disable_interrupt(s);
338 663e8e51 ths
    }
339 663e8e51 ths
}
340 663e8e51 ths
341 663e8e51 ths
static void eepro100_interrupt(EEPRO100State * s, uint8_t stat)
342 663e8e51 ths
{
343 663e8e51 ths
    uint8_t mask = ~s->mem[SCBIntmask];
344 663e8e51 ths
    s->mem[SCBAck] |= stat;
345 663e8e51 ths
    stat = s->scb_stat = s->mem[SCBAck];
346 663e8e51 ths
    stat &= (mask | 0x0f);
347 663e8e51 ths
    //~ stat &= (~s->mem[SCBIntmask] | 0x0xf);
348 663e8e51 ths
    if (stat && (mask & 0x01)) {
349 663e8e51 ths
        /* SCB mask and SCB Bit M do not disable interrupt. */
350 663e8e51 ths
        enable_interrupt(s);
351 663e8e51 ths
    } else if (s->int_stat) {
352 663e8e51 ths
        disable_interrupt(s);
353 663e8e51 ths
    }
354 663e8e51 ths
}
355 663e8e51 ths
356 663e8e51 ths
static void eepro100_cx_interrupt(EEPRO100State * s)
357 663e8e51 ths
{
358 663e8e51 ths
    /* CU completed action command. */
359 663e8e51 ths
    /* Transmit not ok (82557 only, not in emulation). */
360 663e8e51 ths
    eepro100_interrupt(s, 0x80);
361 663e8e51 ths
}
362 663e8e51 ths
363 663e8e51 ths
static void eepro100_cna_interrupt(EEPRO100State * s)
364 663e8e51 ths
{
365 663e8e51 ths
    /* CU left the active state. */
366 663e8e51 ths
    eepro100_interrupt(s, 0x20);
367 663e8e51 ths
}
368 663e8e51 ths
369 663e8e51 ths
static void eepro100_fr_interrupt(EEPRO100State * s)
370 663e8e51 ths
{
371 663e8e51 ths
    /* RU received a complete frame. */
372 663e8e51 ths
    eepro100_interrupt(s, 0x40);
373 663e8e51 ths
}
374 663e8e51 ths
375 663e8e51 ths
#if 0
376 663e8e51 ths
static void eepro100_rnr_interrupt(EEPRO100State * s)
377 663e8e51 ths
{
378 663e8e51 ths
    /* RU is not ready. */
379 663e8e51 ths
    eepro100_interrupt(s, 0x10);
380 663e8e51 ths
}
381 663e8e51 ths
#endif
382 663e8e51 ths
383 663e8e51 ths
static void eepro100_mdi_interrupt(EEPRO100State * s)
384 663e8e51 ths
{
385 663e8e51 ths
    /* MDI completed read or write cycle. */
386 663e8e51 ths
    eepro100_interrupt(s, 0x08);
387 663e8e51 ths
}
388 663e8e51 ths
389 663e8e51 ths
static void eepro100_swi_interrupt(EEPRO100State * s)
390 663e8e51 ths
{
391 663e8e51 ths
    /* Software has requested an interrupt. */
392 663e8e51 ths
    eepro100_interrupt(s, 0x04);
393 663e8e51 ths
}
394 663e8e51 ths
395 663e8e51 ths
#if 0
396 663e8e51 ths
static void eepro100_fcp_interrupt(EEPRO100State * s)
397 663e8e51 ths
{
398 663e8e51 ths
    /* Flow control pause interrupt (82558 and later). */
399 663e8e51 ths
    eepro100_interrupt(s, 0x01);
400 663e8e51 ths
}
401 663e8e51 ths
#endif
402 663e8e51 ths
403 663e8e51 ths
static void pci_reset(EEPRO100State * s)
404 663e8e51 ths
{
405 663e8e51 ths
    uint32_t device = s->device;
406 273a2142 Juan Quintela
    uint8_t *pci_conf = s->dev.config;
407 663e8e51 ths
408 aac443e6 Stefan Weil
    TRACE(OTHER, logout("%p\n", s));
409 663e8e51 ths
410 663e8e51 ths
    /* PCI Vendor ID */
411 deb54399 aliguori
    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
412 d6fd1e66 Stefan Weil
    /* PCI Device ID depends on device and is set below. */
413 663e8e51 ths
    /* PCI Command */
414 663e8e51 ths
    PCI_CONFIG_16(PCI_COMMAND, 0x0000);
415 663e8e51 ths
    /* PCI Status */
416 663e8e51 ths
    PCI_CONFIG_16(PCI_STATUS, 0x2800);
417 663e8e51 ths
    /* PCI Revision ID */
418 663e8e51 ths
    PCI_CONFIG_8(PCI_REVISION_ID, 0x08);
419 663e8e51 ths
    /* PCI Class Code */
420 663e8e51 ths
    PCI_CONFIG_8(0x09, 0x00);
421 173a543b blueswir1
    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
422 663e8e51 ths
    /* PCI Cache Line Size */
423 663e8e51 ths
    /* check cache line size!!! */
424 663e8e51 ths
    //~ PCI_CONFIG_8(0x0c, 0x00);
425 663e8e51 ths
    /* PCI Latency Timer */
426 663e8e51 ths
    PCI_CONFIG_8(0x0d, 0x20);   // latency timer = 32 clocks
427 663e8e51 ths
    /* PCI Header Type */
428 663e8e51 ths
    /* BIST (built-in self test) */
429 663e8e51 ths
#if defined(TARGET_I386)
430 663e8e51 ths
// !!! workaround for buggy bios
431 663e8e51 ths
//~ #define PCI_ADDRESS_SPACE_MEM_PREFETCH 0
432 663e8e51 ths
#endif
433 663e8e51 ths
#if 0
434 663e8e51 ths
    /* PCI Base Address Registers */
435 663e8e51 ths
    /* CSR Memory Mapped Base Address */
436 663e8e51 ths
    PCI_CONFIG_32(PCI_BASE_ADDRESS_0,
437 663e8e51 ths
                  PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_MEM_PREFETCH);
438 663e8e51 ths
    /* CSR I/O Mapped Base Address */
439 663e8e51 ths
    PCI_CONFIG_32(PCI_BASE_ADDRESS_1, PCI_ADDRESS_SPACE_IO);
440 663e8e51 ths
#if 0
441 663e8e51 ths
    /* Flash Memory Mapped Base Address */
442 663e8e51 ths
    PCI_CONFIG_32(PCI_BASE_ADDRESS_2, 0xfffe0000 | PCI_ADDRESS_SPACE_MEM);
443 663e8e51 ths
#endif
444 663e8e51 ths
#endif
445 663e8e51 ths
    /* Expansion ROM Base Address (depends on boot disable!!!) */
446 663e8e51 ths
    PCI_CONFIG_32(0x30, 0x00000000);
447 663e8e51 ths
    /* Capability Pointer */
448 663e8e51 ths
    PCI_CONFIG_8(0x34, 0xdc);
449 aac443e6 Stefan Weil
    /* Interrupt Line */
450 663e8e51 ths
    /* Interrupt Pin */
451 663e8e51 ths
    PCI_CONFIG_8(0x3d, 1);      // interrupt pin 0
452 663e8e51 ths
    /* Minimum Grant */
453 663e8e51 ths
    PCI_CONFIG_8(0x3e, 0x08);
454 663e8e51 ths
    /* Maximum Latency */
455 663e8e51 ths
    PCI_CONFIG_8(0x3f, 0x18);
456 663e8e51 ths
    /* Power Management Capabilities / Next Item Pointer / Capability ID */
457 663e8e51 ths
    PCI_CONFIG_32(0xdc, 0x7e210001);
458 663e8e51 ths
459 663e8e51 ths
    switch (device) {
460 663e8e51 ths
    case i82551:
461 d6fd1e66 Stefan Weil
        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82551IT);
462 663e8e51 ths
        PCI_CONFIG_8(PCI_REVISION_ID, 0x0f);
463 663e8e51 ths
        break;
464 663e8e51 ths
    case i82557B:
465 d6fd1e66 Stefan Weil
        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
466 663e8e51 ths
        PCI_CONFIG_8(PCI_REVISION_ID, 0x02);
467 663e8e51 ths
        break;
468 663e8e51 ths
    case i82557C:
469 d6fd1e66 Stefan Weil
        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
470 663e8e51 ths
        PCI_CONFIG_8(PCI_REVISION_ID, 0x03);
471 663e8e51 ths
        break;
472 663e8e51 ths
    case i82558B:
473 d6fd1e66 Stefan Weil
        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
474 663e8e51 ths
        PCI_CONFIG_16(PCI_STATUS, 0x2810);
475 663e8e51 ths
        PCI_CONFIG_8(PCI_REVISION_ID, 0x05);
476 663e8e51 ths
        break;
477 663e8e51 ths
    case i82559C:
478 d6fd1e66 Stefan Weil
        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
479 663e8e51 ths
        PCI_CONFIG_16(PCI_STATUS, 0x2810);
480 663e8e51 ths
        //~ PCI_CONFIG_8(PCI_REVISION_ID, 0x08);
481 663e8e51 ths
        break;
482 663e8e51 ths
    case i82559ER:
483 d6fd1e66 Stefan Weil
        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82551IT);
484 663e8e51 ths
        PCI_CONFIG_16(PCI_STATUS, 0x2810);
485 663e8e51 ths
        PCI_CONFIG_8(PCI_REVISION_ID, 0x09);
486 663e8e51 ths
        break;
487 663e8e51 ths
    //~ PCI_CONFIG_16(PCI_DEVICE_ID, 0x1029);
488 663e8e51 ths
    //~ PCI_CONFIG_16(PCI_DEVICE_ID, 0x1030);       /* 82559 InBusiness 10/100 */
489 663e8e51 ths
    default:
490 663e8e51 ths
        logout("Device %X is undefined!\n", device);
491 663e8e51 ths
    }
492 663e8e51 ths
493 663e8e51 ths
    if (device == i82557C || device == i82558B || device == i82559C) {
494 663e8e51 ths
        logout("Get device id and revision from EEPROM!!!\n");
495 663e8e51 ths
    }
496 663e8e51 ths
}
497 663e8e51 ths
498 663e8e51 ths
static void nic_selective_reset(EEPRO100State * s)
499 663e8e51 ths
{
500 663e8e51 ths
    size_t i;
501 663e8e51 ths
    uint16_t *eeprom_contents = eeprom93xx_data(s->eeprom);
502 663e8e51 ths
    //~ eeprom93xx_reset(s->eeprom);
503 663e8e51 ths
    memcpy(eeprom_contents, s->macaddr, 6);
504 663e8e51 ths
    eeprom_contents[0xa] = 0x4000;
505 663e8e51 ths
    uint16_t sum = 0;
506 663e8e51 ths
    for (i = 0; i < EEPROM_SIZE - 1; i++) {
507 663e8e51 ths
        sum += eeprom_contents[i];
508 663e8e51 ths
    }
509 663e8e51 ths
    eeprom_contents[EEPROM_SIZE - 1] = 0xbaba - sum;
510 aac443e6 Stefan Weil
    TRACE(EEPROM, logout("checksum=0x%04x\n", eeprom_contents[EEPROM_SIZE - 1]));
511 663e8e51 ths
512 663e8e51 ths
    memset(s->mem, 0, sizeof(s->mem));
513 663e8e51 ths
    uint32_t val = BIT(21);
514 663e8e51 ths
    memcpy(&s->mem[SCBCtrlMDI], &val, sizeof(val));
515 663e8e51 ths
516 663e8e51 ths
    assert(sizeof(s->mdimem) == sizeof(eepro100_mdi_default));
517 663e8e51 ths
    memcpy(&s->mdimem[0], &eepro100_mdi_default[0], sizeof(s->mdimem));
518 663e8e51 ths
}
519 663e8e51 ths
520 663e8e51 ths
static void nic_reset(void *opaque)
521 663e8e51 ths
{
522 769cf7a5 Juan Quintela
    EEPRO100State *s = opaque;
523 aac443e6 Stefan Weil
    TRACE(OTHER, logout("%p\n", s));
524 663e8e51 ths
    nic_selective_reset(s);
525 663e8e51 ths
}
526 663e8e51 ths
527 663e8e51 ths
#if defined(DEBUG_EEPRO100)
528 6a0b9cc9 Reimar Dรถffinger
static const char * const reg[PCI_IO_SIZE / 4] = {
529 663e8e51 ths
    "Command/Status",
530 663e8e51 ths
    "General Pointer",
531 663e8e51 ths
    "Port",
532 663e8e51 ths
    "EEPROM/Flash Control",
533 663e8e51 ths
    "MDI Control",
534 663e8e51 ths
    "Receive DMA Byte Count",
535 aac443e6 Stefan Weil
    "Flow control",
536 663e8e51 ths
    "General Status/Control"
537 663e8e51 ths
};
538 663e8e51 ths
539 663e8e51 ths
static char *regname(uint32_t addr)
540 663e8e51 ths
{
541 663e8e51 ths
    static char buf[16];
542 663e8e51 ths
    if (addr < PCI_IO_SIZE) {
543 663e8e51 ths
        const char *r = reg[addr / 4];
544 663e8e51 ths
        if (r != 0) {
545 41cbc23c Stefan Weil
            snprintf(buf, sizeof(buf), "%s+%u", r, addr % 4);
546 663e8e51 ths
        } else {
547 41cbc23c Stefan Weil
            snprintf(buf, sizeof(buf), "0x%02x", addr);
548 663e8e51 ths
        }
549 663e8e51 ths
    } else {
550 41cbc23c Stefan Weil
        snprintf(buf, sizeof(buf), "??? 0x%08x", addr);
551 663e8e51 ths
    }
552 663e8e51 ths
    return buf;
553 663e8e51 ths
}
554 663e8e51 ths
#endif                          /* DEBUG_EEPRO100 */
555 663e8e51 ths
556 663e8e51 ths
#if 0
557 663e8e51 ths
static uint16_t eepro100_read_status(EEPRO100State * s)
558 663e8e51 ths
{
559 663e8e51 ths
    uint16_t val = s->status;
560 aac443e6 Stefan Weil
    TRACE(OTHER, logout("val=0x%04x\n", val));
561 663e8e51 ths
    return val;
562 663e8e51 ths
}
563 663e8e51 ths

564 663e8e51 ths
static void eepro100_write_status(EEPRO100State * s, uint16_t val)
565 663e8e51 ths
{
566 aac443e6 Stefan Weil
    TRACE(OTHER, logout("val=0x%04x\n", val));
567 663e8e51 ths
    s->status = val;
568 663e8e51 ths
}
569 663e8e51 ths
#endif
570 663e8e51 ths
571 663e8e51 ths
/*****************************************************************************
572 663e8e51 ths
 *
573 663e8e51 ths
 * Command emulation.
574 663e8e51 ths
 *
575 663e8e51 ths
 ****************************************************************************/
576 663e8e51 ths
577 663e8e51 ths
#if 0
578 663e8e51 ths
static uint16_t eepro100_read_command(EEPRO100State * s)
579 663e8e51 ths
{
580 663e8e51 ths
    uint16_t val = 0xffff;
581 aac443e6 Stefan Weil
    //~ TRACE(OTHER, logout("val=0x%04x\n", val));
582 663e8e51 ths
    return val;
583 663e8e51 ths
}
584 663e8e51 ths
#endif
585 663e8e51 ths
586 0859df68 Naphtali Sprei
static bool device_supports_eTxCB(EEPRO100State * s)
587 0859df68 Naphtali Sprei
{
588 0859df68 Naphtali Sprei
    return (s->device != i82557B && s->device != i82557C);
589 0859df68 Naphtali Sprei
}
590 0859df68 Naphtali Sprei
591 663e8e51 ths
/* Commands that can be put in a command list entry. */
592 663e8e51 ths
enum commands {
593 663e8e51 ths
    CmdNOp = 0,
594 663e8e51 ths
    CmdIASetup = 1,
595 663e8e51 ths
    CmdConfigure = 2,
596 663e8e51 ths
    CmdMulticastList = 3,
597 663e8e51 ths
    CmdTx = 4,
598 663e8e51 ths
    CmdTDR = 5,                 /* load microcode */
599 663e8e51 ths
    CmdDump = 6,
600 663e8e51 ths
    CmdDiagnose = 7,
601 663e8e51 ths
602 663e8e51 ths
    /* And some extra flags: */
603 663e8e51 ths
    CmdSuspend = 0x4000,        /* Suspend after completion. */
604 663e8e51 ths
    CmdIntr = 0x2000,           /* Interrupt after completion. */
605 663e8e51 ths
    CmdTxFlex = 0x0008,         /* Use "Flexible mode" for CmdTx command. */
606 663e8e51 ths
};
607 663e8e51 ths
608 c227f099 Anthony Liguori
static cu_state_t get_cu_state(EEPRO100State * s)
609 663e8e51 ths
{
610 663e8e51 ths
    return ((s->mem[SCBStatus] >> 6) & 0x03);
611 663e8e51 ths
}
612 663e8e51 ths
613 c227f099 Anthony Liguori
static void set_cu_state(EEPRO100State * s, cu_state_t state)
614 663e8e51 ths
{
615 663e8e51 ths
    s->mem[SCBStatus] = (s->mem[SCBStatus] & 0x3f) + (state << 6);
616 663e8e51 ths
}
617 663e8e51 ths
618 c227f099 Anthony Liguori
static ru_state_t get_ru_state(EEPRO100State * s)
619 663e8e51 ths
{
620 663e8e51 ths
    return ((s->mem[SCBStatus] >> 2) & 0x0f);
621 663e8e51 ths
}
622 663e8e51 ths
623 c227f099 Anthony Liguori
static void set_ru_state(EEPRO100State * s, ru_state_t state)
624 663e8e51 ths
{
625 663e8e51 ths
    s->mem[SCBStatus] = (s->mem[SCBStatus] & 0xc3) + (state << 2);
626 663e8e51 ths
}
627 663e8e51 ths
628 663e8e51 ths
static void dump_statistics(EEPRO100State * s)
629 663e8e51 ths
{
630 663e8e51 ths
    /* Dump statistical data. Most data is never changed by the emulation
631 663e8e51 ths
     * and always 0, so we first just copy the whole block and then those
632 663e8e51 ths
     * values which really matter.
633 663e8e51 ths
     * Number of data should check configuration!!!
634 663e8e51 ths
     */
635 663e8e51 ths
    cpu_physical_memory_write(s->statsaddr, (uint8_t *) & s->statistics, 64);
636 663e8e51 ths
    stl_phys(s->statsaddr + 0, s->statistics.tx_good_frames);
637 663e8e51 ths
    stl_phys(s->statsaddr + 36, s->statistics.rx_good_frames);
638 663e8e51 ths
    stl_phys(s->statsaddr + 48, s->statistics.rx_resource_errors);
639 663e8e51 ths
    stl_phys(s->statsaddr + 60, s->statistics.rx_short_frame_errors);
640 663e8e51 ths
    //~ stw_phys(s->statsaddr + 76, s->statistics.xmt_tco_frames);
641 663e8e51 ths
    //~ stw_phys(s->statsaddr + 78, s->statistics.rcv_tco_frames);
642 663e8e51 ths
    //~ missing("CU dump statistical counters");
643 663e8e51 ths
}
644 663e8e51 ths
645 663e8e51 ths
static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
646 663e8e51 ths
{
647 c227f099 Anthony Liguori
    eepro100_tx_t tx;
648 663e8e51 ths
    uint32_t cb_address;
649 663e8e51 ths
    switch (val) {
650 663e8e51 ths
    case CU_NOP:
651 663e8e51 ths
        /* No operation. */
652 663e8e51 ths
        break;
653 663e8e51 ths
    case CU_START:
654 663e8e51 ths
        if (get_cu_state(s) != cu_idle) {
655 663e8e51 ths
            /* Intel documentation says that CU must be idle for the CU
656 663e8e51 ths
             * start command. Intel driver for Linux also starts the CU
657 663e8e51 ths
             * from suspended state. */
658 663e8e51 ths
            logout("CU state is %u, should be %u\n", get_cu_state(s), cu_idle);
659 663e8e51 ths
            //~ assert(!"wrong CU state");
660 663e8e51 ths
        }
661 663e8e51 ths
        set_cu_state(s, cu_active);
662 663e8e51 ths
        s->cu_offset = s->pointer;
663 663e8e51 ths
      next_command:
664 663e8e51 ths
        cb_address = s->cu_base + s->cu_offset;
665 663e8e51 ths
        cpu_physical_memory_read(cb_address, (uint8_t *) & tx, sizeof(tx));
666 663e8e51 ths
        uint16_t status = le16_to_cpu(tx.status);
667 663e8e51 ths
        uint16_t command = le16_to_cpu(tx.command);
668 663e8e51 ths
        logout
669 663e8e51 ths
            ("val=0x%02x (cu start), status=0x%04x, command=0x%04x, link=0x%08x\n",
670 663e8e51 ths
             val, status, command, tx.link);
671 663e8e51 ths
        bool bit_el = ((command & 0x8000) != 0);
672 663e8e51 ths
        bool bit_s = ((command & 0x4000) != 0);
673 663e8e51 ths
        bool bit_i = ((command & 0x2000) != 0);
674 663e8e51 ths
        bool bit_nc = ((command & 0x0010) != 0);
675 663e8e51 ths
        //~ bool bit_sf = ((command & 0x0008) != 0);
676 663e8e51 ths
        uint16_t cmd = command & 0x0007;
677 663e8e51 ths
        s->cu_offset = le32_to_cpu(tx.link);
678 663e8e51 ths
        switch (cmd) {
679 663e8e51 ths
        case CmdNOp:
680 663e8e51 ths
            /* Do nothing. */
681 663e8e51 ths
            break;
682 663e8e51 ths
        case CmdIASetup:
683 663e8e51 ths
            cpu_physical_memory_read(cb_address + 8, &s->macaddr[0], 6);
684 aac443e6 Stefan Weil
            TRACE(OTHER, logout("macaddr: %s\n", nic_dump(&s->macaddr[0], 6)));
685 663e8e51 ths
            break;
686 663e8e51 ths
        case CmdConfigure:
687 663e8e51 ths
            cpu_physical_memory_read(cb_address + 8, &s->configuration[0],
688 663e8e51 ths
                                     sizeof(s->configuration));
689 aac443e6 Stefan Weil
            TRACE(OTHER, logout("configuration: %s\n", nic_dump(&s->configuration[0], 16)));
690 663e8e51 ths
            break;
691 663e8e51 ths
        case CmdMulticastList:
692 663e8e51 ths
            //~ missing("multicast list");
693 663e8e51 ths
            break;
694 663e8e51 ths
        case CmdTx:
695 663e8e51 ths
            (void)0;
696 663e8e51 ths
            uint32_t tbd_array = le32_to_cpu(tx.tx_desc_addr);
697 663e8e51 ths
            uint16_t tcb_bytes = (le16_to_cpu(tx.tcb_bytes) & 0x3fff);
698 aac443e6 Stefan Weil
            TRACE(RXTX, logout
699 663e8e51 ths
                ("transmit, TBD array address 0x%08x, TCB byte count 0x%04x, TBD count %u\n",
700 aac443e6 Stefan Weil
                 tbd_array, tcb_bytes, tx.tbd_count));
701 663e8e51 ths
            assert(!bit_nc);
702 663e8e51 ths
            //~ assert(!bit_sf);
703 663e8e51 ths
            assert(tcb_bytes <= 2600);
704 663e8e51 ths
            /* Next assertion fails for local configuration. */
705 663e8e51 ths
            //~ assert((tcb_bytes > 0) || (tbd_array != 0xffffffff));
706 663e8e51 ths
            if (!((tcb_bytes > 0) || (tbd_array != 0xffffffff))) {
707 663e8e51 ths
                logout
708 663e8e51 ths
                    ("illegal values of TBD array address and TCB byte count!\n");
709 663e8e51 ths
            }
710 24e6f355 Reimar Dรถffinger
            // sends larger than MAX_ETH_FRAME_SIZE are allowed, up to 2600 bytes
711 24e6f355 Reimar Dรถffinger
            uint8_t buf[2600];
712 663e8e51 ths
            uint16_t size = 0;
713 663e8e51 ths
            uint32_t tbd_address = cb_address + 0x10;
714 663e8e51 ths
            assert(tcb_bytes <= sizeof(buf));
715 663e8e51 ths
            while (size < tcb_bytes) {
716 663e8e51 ths
                uint32_t tx_buffer_address = ldl_phys(tbd_address);
717 663e8e51 ths
                uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
718 663e8e51 ths
                //~ uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
719 663e8e51 ths
                tbd_address += 8;
720 aac443e6 Stefan Weil
                TRACE(RXTX, logout
721 663e8e51 ths
                    ("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n",
722 aac443e6 Stefan Weil
                     tx_buffer_address, tx_buffer_size));
723 24e6f355 Reimar Dรถffinger
                tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
724 663e8e51 ths
                cpu_physical_memory_read(tx_buffer_address, &buf[size],
725 663e8e51 ths
                                         tx_buffer_size);
726 663e8e51 ths
                size += tx_buffer_size;
727 663e8e51 ths
            }
728 663e8e51 ths
            if (tbd_array == 0xffffffff) {
729 663e8e51 ths
                /* Simplified mode. Was already handled by code above. */
730 663e8e51 ths
            } else {
731 663e8e51 ths
                /* Flexible mode. */
732 663e8e51 ths
                uint8_t tbd_count = 0;
733 0859df68 Naphtali Sprei
                if (device_supports_eTxCB(s) && !(s->configuration[6] & BIT(4))) {
734 3f9cb1c1 Naphtali Sprei
                    /* Extended Flexible TCB. */
735 663e8e51 ths
                    assert(tcb_bytes == 0);
736 663e8e51 ths
                    for (; tbd_count < 2; tbd_count++) {
737 663e8e51 ths
                        uint32_t tx_buffer_address = ldl_phys(tbd_address);
738 663e8e51 ths
                        uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
739 663e8e51 ths
                        uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
740 663e8e51 ths
                        tbd_address += 8;
741 aac443e6 Stefan Weil
                        TRACE(RXTX, logout
742 3f9cb1c1 Naphtali Sprei
                            ("TBD (extended flexible mode): buffer address 0x%08x, size 0x%04x\n",
743 aac443e6 Stefan Weil
                             tx_buffer_address, tx_buffer_size));
744 24e6f355 Reimar Dรถffinger
                        tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
745 663e8e51 ths
                        cpu_physical_memory_read(tx_buffer_address, &buf[size],
746 663e8e51 ths
                                                 tx_buffer_size);
747 663e8e51 ths
                        size += tx_buffer_size;
748 663e8e51 ths
                        if (tx_buffer_el & 1) {
749 663e8e51 ths
                            break;
750 663e8e51 ths
                        }
751 663e8e51 ths
                    }
752 663e8e51 ths
                }
753 663e8e51 ths
                tbd_address = tbd_array;
754 663e8e51 ths
                for (; tbd_count < tx.tbd_count; tbd_count++) {
755 663e8e51 ths
                    uint32_t tx_buffer_address = ldl_phys(tbd_address);
756 663e8e51 ths
                    uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
757 663e8e51 ths
                    uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
758 663e8e51 ths
                    tbd_address += 8;
759 aac443e6 Stefan Weil
                    TRACE(RXTX, logout
760 663e8e51 ths
                        ("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n",
761 aac443e6 Stefan Weil
                         tx_buffer_address, tx_buffer_size));
762 24e6f355 Reimar Dรถffinger
                    tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
763 663e8e51 ths
                    cpu_physical_memory_read(tx_buffer_address, &buf[size],
764 663e8e51 ths
                                             tx_buffer_size);
765 663e8e51 ths
                    size += tx_buffer_size;
766 663e8e51 ths
                    if (tx_buffer_el & 1) {
767 663e8e51 ths
                        break;
768 663e8e51 ths
                    }
769 663e8e51 ths
                }
770 663e8e51 ths
            }
771 aac443e6 Stefan Weil
            TRACE(RXTX, logout("%p sending frame, len=%d,%s\n", s, size, nic_dump(buf, size)));
772 663e8e51 ths
            qemu_send_packet(s->vc, buf, size);
773 663e8e51 ths
            s->statistics.tx_good_frames++;
774 663e8e51 ths
            /* Transmit with bad status would raise an CX/TNO interrupt.
775 663e8e51 ths
             * (82557 only). Emulation never has bad status. */
776 663e8e51 ths
            //~ eepro100_cx_interrupt(s);
777 663e8e51 ths
            break;
778 663e8e51 ths
        case CmdTDR:
779 aac443e6 Stefan Weil
            TRACE(OTHER, logout("load microcode\n"));
780 663e8e51 ths
            /* Starting with offset 8, the command contains
781 663e8e51 ths
             * 64 dwords microcode which we just ignore here. */
782 663e8e51 ths
            break;
783 663e8e51 ths
        default:
784 663e8e51 ths
            missing("undefined command");
785 663e8e51 ths
        }
786 663e8e51 ths
        /* Write new status (success). */
787 663e8e51 ths
        stw_phys(cb_address, status | 0x8000 | 0x2000);
788 663e8e51 ths
        if (bit_i) {
789 663e8e51 ths
            /* CU completed action. */
790 663e8e51 ths
            eepro100_cx_interrupt(s);
791 663e8e51 ths
        }
792 663e8e51 ths
        if (bit_el) {
793 aac443e6 Stefan Weil
            /* CU becomes idle. Terminate command loop. */
794 663e8e51 ths
            set_cu_state(s, cu_idle);
795 663e8e51 ths
            eepro100_cna_interrupt(s);
796 663e8e51 ths
        } else if (bit_s) {
797 663e8e51 ths
            /* CU becomes suspended. */
798 663e8e51 ths
            set_cu_state(s, cu_suspended);
799 663e8e51 ths
            eepro100_cna_interrupt(s);
800 663e8e51 ths
        } else {
801 663e8e51 ths
            /* More entries in list. */
802 aac443e6 Stefan Weil
            TRACE(OTHER, logout("CU list with at least one more entry\n"));
803 663e8e51 ths
            goto next_command;
804 663e8e51 ths
        }
805 aac443e6 Stefan Weil
        TRACE(OTHER, logout("CU list empty\n"));
806 663e8e51 ths
        /* List is empty. Now CU is idle or suspended. */
807 663e8e51 ths
        break;
808 663e8e51 ths
    case CU_RESUME:
809 663e8e51 ths
        if (get_cu_state(s) != cu_suspended) {
810 663e8e51 ths
            logout("bad CU resume from CU state %u\n", get_cu_state(s));
811 663e8e51 ths
            /* Workaround for bad Linux eepro100 driver which resumes
812 663e8e51 ths
             * from idle state. */
813 663e8e51 ths
            //~ missing("cu resume");
814 663e8e51 ths
            set_cu_state(s, cu_suspended);
815 663e8e51 ths
        }
816 663e8e51 ths
        if (get_cu_state(s) == cu_suspended) {
817 aac443e6 Stefan Weil
            TRACE(OTHER, logout("CU resuming\n"));
818 663e8e51 ths
            set_cu_state(s, cu_active);
819 663e8e51 ths
            goto next_command;
820 663e8e51 ths
        }
821 663e8e51 ths
        break;
822 663e8e51 ths
    case CU_STATSADDR:
823 663e8e51 ths
        /* Load dump counters address. */
824 663e8e51 ths
        s->statsaddr = s->pointer;
825 aac443e6 Stefan Weil
        TRACE(OTHER, logout("val=0x%02x (status address)\n", val));
826 663e8e51 ths
        break;
827 663e8e51 ths
    case CU_SHOWSTATS:
828 663e8e51 ths
        /* Dump statistical counters. */
829 aac443e6 Stefan Weil
        TRACE(OTHER, logout("val=0x%02x (dump stats)\n", val));
830 663e8e51 ths
        dump_statistics(s);
831 663e8e51 ths
        break;
832 663e8e51 ths
    case CU_CMD_BASE:
833 663e8e51 ths
        /* Load CU base. */
834 aac443e6 Stefan Weil
        TRACE(OTHER, logout("val=0x%02x (CU base address)\n", val));
835 663e8e51 ths
        s->cu_base = s->pointer;
836 663e8e51 ths
        break;
837 663e8e51 ths
    case CU_DUMPSTATS:
838 663e8e51 ths
        /* Dump and reset statistical counters. */
839 aac443e6 Stefan Weil
        TRACE(OTHER, logout("val=0x%02x (dump stats and reset)\n", val));
840 663e8e51 ths
        dump_statistics(s);
841 663e8e51 ths
        memset(&s->statistics, 0, sizeof(s->statistics));
842 663e8e51 ths
        break;
843 663e8e51 ths
    case CU_SRESUME:
844 663e8e51 ths
        /* CU static resume. */
845 663e8e51 ths
        missing("CU static resume");
846 663e8e51 ths
        break;
847 663e8e51 ths
    default:
848 663e8e51 ths
        missing("Undefined CU command");
849 663e8e51 ths
    }
850 663e8e51 ths
}
851 663e8e51 ths
852 663e8e51 ths
static void eepro100_ru_command(EEPRO100State * s, uint8_t val)
853 663e8e51 ths
{
854 663e8e51 ths
    switch (val) {
855 663e8e51 ths
    case RU_NOP:
856 663e8e51 ths
        /* No operation. */
857 663e8e51 ths
        break;
858 663e8e51 ths
    case RX_START:
859 663e8e51 ths
        /* RU start. */
860 663e8e51 ths
        if (get_ru_state(s) != ru_idle) {
861 663e8e51 ths
            logout("RU state is %u, should be %u\n", get_ru_state(s), ru_idle);
862 663e8e51 ths
            //~ assert(!"wrong RU state");
863 663e8e51 ths
        }
864 663e8e51 ths
        set_ru_state(s, ru_ready);
865 663e8e51 ths
        s->ru_offset = s->pointer;
866 aac443e6 Stefan Weil
        TRACE(OTHER, logout("val=0x%02x (rx start)\n", val));
867 663e8e51 ths
        break;
868 663e8e51 ths
    case RX_RESUME:
869 663e8e51 ths
        /* Restart RU. */
870 663e8e51 ths
        if (get_ru_state(s) != ru_suspended) {
871 663e8e51 ths
            logout("RU state is %u, should be %u\n", get_ru_state(s),
872 663e8e51 ths
                   ru_suspended);
873 663e8e51 ths
            //~ assert(!"wrong RU state");
874 663e8e51 ths
        }
875 663e8e51 ths
        set_ru_state(s, ru_ready);
876 663e8e51 ths
        break;
877 663e8e51 ths
    case RX_ADDR_LOAD:
878 663e8e51 ths
        /* Load RU base. */
879 aac443e6 Stefan Weil
        TRACE(OTHER, logout("val=0x%02x (RU base address)\n", val));
880 663e8e51 ths
        s->ru_base = s->pointer;
881 663e8e51 ths
        break;
882 663e8e51 ths
    default:
883 663e8e51 ths
        logout("val=0x%02x (undefined RU command)\n", val);
884 663e8e51 ths
        missing("Undefined SU command");
885 663e8e51 ths
    }
886 663e8e51 ths
}
887 663e8e51 ths
888 663e8e51 ths
static void eepro100_write_command(EEPRO100State * s, uint8_t val)
889 663e8e51 ths
{
890 663e8e51 ths
    eepro100_ru_command(s, val & 0x0f);
891 663e8e51 ths
    eepro100_cu_command(s, val & 0xf0);
892 663e8e51 ths
    if ((val) == 0) {
893 aac443e6 Stefan Weil
        TRACE(OTHER, logout("val=0x%02x\n", val));
894 663e8e51 ths
    }
895 663e8e51 ths
    /* Clear command byte after command was accepted. */
896 663e8e51 ths
    s->mem[SCBCmd] = 0;
897 663e8e51 ths
}
898 663e8e51 ths
899 663e8e51 ths
/*****************************************************************************
900 663e8e51 ths
 *
901 663e8e51 ths
 * EEPROM emulation.
902 663e8e51 ths
 *
903 663e8e51 ths
 ****************************************************************************/
904 663e8e51 ths
905 663e8e51 ths
#define EEPROM_CS       0x02
906 663e8e51 ths
#define EEPROM_SK       0x01
907 663e8e51 ths
#define EEPROM_DI       0x04
908 663e8e51 ths
#define EEPROM_DO       0x08
909 663e8e51 ths
910 663e8e51 ths
static uint16_t eepro100_read_eeprom(EEPRO100State * s)
911 663e8e51 ths
{
912 663e8e51 ths
    uint16_t val;
913 663e8e51 ths
    memcpy(&val, &s->mem[SCBeeprom], sizeof(val));
914 663e8e51 ths
    if (eeprom93xx_read(s->eeprom)) {
915 663e8e51 ths
        val |= EEPROM_DO;
916 663e8e51 ths
    } else {
917 663e8e51 ths
        val &= ~EEPROM_DO;
918 663e8e51 ths
    }
919 aac443e6 Stefan Weil
    TRACE(EEPROM, logout("val=0x%04x\n", val));
920 663e8e51 ths
    return val;
921 663e8e51 ths
}
922 663e8e51 ths
923 c227f099 Anthony Liguori
static void eepro100_write_eeprom(eeprom_t * eeprom, uint8_t val)
924 663e8e51 ths
{
925 aac443e6 Stefan Weil
    TRACE(EEPROM, logout("val=0x%02x\n", val));
926 663e8e51 ths
927 663e8e51 ths
    /* mask unwriteable bits */
928 663e8e51 ths
    //~ val = SET_MASKED(val, 0x31, eeprom->value);
929 663e8e51 ths
930 663e8e51 ths
    int eecs = ((val & EEPROM_CS) != 0);
931 663e8e51 ths
    int eesk = ((val & EEPROM_SK) != 0);
932 663e8e51 ths
    int eedi = ((val & EEPROM_DI) != 0);
933 663e8e51 ths
    eeprom93xx_write(eeprom, eecs, eesk, eedi);
934 663e8e51 ths
}
935 663e8e51 ths
936 663e8e51 ths
static void eepro100_write_pointer(EEPRO100State * s, uint32_t val)
937 663e8e51 ths
{
938 663e8e51 ths
    s->pointer = le32_to_cpu(val);
939 aac443e6 Stefan Weil
    TRACE(OTHER, logout("val=0x%08x\n", val));
940 663e8e51 ths
}
941 663e8e51 ths
942 663e8e51 ths
/*****************************************************************************
943 663e8e51 ths
 *
944 663e8e51 ths
 * MDI emulation.
945 663e8e51 ths
 *
946 663e8e51 ths
 ****************************************************************************/
947 663e8e51 ths
948 663e8e51 ths
#if defined(DEBUG_EEPRO100)
949 6a0b9cc9 Reimar Dรถffinger
static const char * const mdi_op_name[] = {
950 663e8e51 ths
    "opcode 0",
951 663e8e51 ths
    "write",
952 663e8e51 ths
    "read",
953 663e8e51 ths
    "opcode 3"
954 663e8e51 ths
};
955 663e8e51 ths
956 6a0b9cc9 Reimar Dรถffinger
static const char * const mdi_reg_name[] = {
957 663e8e51 ths
    "Control",
958 663e8e51 ths
    "Status",
959 663e8e51 ths
    "PHY Identification (Word 1)",
960 663e8e51 ths
    "PHY Identification (Word 2)",
961 663e8e51 ths
    "Auto-Negotiation Advertisement",
962 663e8e51 ths
    "Auto-Negotiation Link Partner Ability",
963 663e8e51 ths
    "Auto-Negotiation Expansion"
964 663e8e51 ths
};
965 aac443e6 Stefan Weil
966 aac443e6 Stefan Weil
static const char *reg2name(uint8_t reg)
967 aac443e6 Stefan Weil
{
968 aac443e6 Stefan Weil
    static char buffer[10];
969 aac443e6 Stefan Weil
    const char *p = buffer;
970 aac443e6 Stefan Weil
    if (reg < ARRAY_SIZE(mdi_reg_name)) {
971 aac443e6 Stefan Weil
        p = mdi_reg_name[reg];
972 aac443e6 Stefan Weil
    } else {
973 aac443e6 Stefan Weil
        snprintf(buffer, sizeof(buffer), "reg=0x%02x", reg);
974 aac443e6 Stefan Weil
    }
975 aac443e6 Stefan Weil
    return p;
976 aac443e6 Stefan Weil
}
977 663e8e51 ths
#endif                          /* DEBUG_EEPRO100 */
978 663e8e51 ths
979 663e8e51 ths
static uint32_t eepro100_read_mdi(EEPRO100State * s)
980 663e8e51 ths
{
981 663e8e51 ths
    uint32_t val;
982 663e8e51 ths
    memcpy(&val, &s->mem[0x10], sizeof(val));
983 663e8e51 ths
984 663e8e51 ths
#ifdef DEBUG_EEPRO100
985 663e8e51 ths
    uint8_t raiseint = (val & BIT(29)) >> 29;
986 663e8e51 ths
    uint8_t opcode = (val & BITS(27, 26)) >> 26;
987 663e8e51 ths
    uint8_t phy = (val & BITS(25, 21)) >> 21;
988 663e8e51 ths
    uint8_t reg = (val & BITS(20, 16)) >> 16;
989 663e8e51 ths
    uint16_t data = (val & BITS(15, 0));
990 663e8e51 ths
#endif
991 663e8e51 ths
    /* Emulation takes no time to finish MDI transaction. */
992 663e8e51 ths
    val |= BIT(28);
993 663e8e51 ths
    TRACE(MDI, logout("val=0x%08x (int=%u, %s, phy=%u, %s, data=0x%04x\n",
994 663e8e51 ths
                      val, raiseint, mdi_op_name[opcode], phy,
995 aac443e6 Stefan Weil
                      reg2name(reg), data));
996 663e8e51 ths
    return val;
997 663e8e51 ths
}
998 663e8e51 ths
999 663e8e51 ths
static void eepro100_write_mdi(EEPRO100State * s, uint32_t val)
1000 663e8e51 ths
{
1001 663e8e51 ths
    uint8_t raiseint = (val & BIT(29)) >> 29;
1002 663e8e51 ths
    uint8_t opcode = (val & BITS(27, 26)) >> 26;
1003 663e8e51 ths
    uint8_t phy = (val & BITS(25, 21)) >> 21;
1004 663e8e51 ths
    uint8_t reg = (val & BITS(20, 16)) >> 16;
1005 663e8e51 ths
    uint16_t data = (val & BITS(15, 0));
1006 aac443e6 Stefan Weil
    TRACE(MDI, logout("val=0x%08x (int=%u, %s, phy=%u, %s, data=0x%04x\n",
1007 aac443e6 Stefan Weil
          val, raiseint, mdi_op_name[opcode], phy, reg2name(reg), data));
1008 663e8e51 ths
    if (phy != 1) {
1009 663e8e51 ths
        /* Unsupported PHY address. */
1010 663e8e51 ths
        //~ logout("phy must be 1 but is %u\n", phy);
1011 663e8e51 ths
        data = 0;
1012 663e8e51 ths
    } else if (opcode != 1 && opcode != 2) {
1013 663e8e51 ths
        /* Unsupported opcode. */
1014 663e8e51 ths
        logout("opcode must be 1 or 2 but is %u\n", opcode);
1015 663e8e51 ths
        data = 0;
1016 663e8e51 ths
    } else if (reg > 6) {
1017 663e8e51 ths
        /* Unsupported register. */
1018 663e8e51 ths
        logout("register must be 0...6 but is %u\n", reg);
1019 663e8e51 ths
        data = 0;
1020 663e8e51 ths
    } else {
1021 663e8e51 ths
        TRACE(MDI, logout("val=0x%08x (int=%u, %s, phy=%u, %s, data=0x%04x\n",
1022 663e8e51 ths
                          val, raiseint, mdi_op_name[opcode], phy,
1023 aac443e6 Stefan Weil
                          reg2name(reg), data));
1024 663e8e51 ths
        if (opcode == 1) {
1025 663e8e51 ths
            /* MDI write */
1026 663e8e51 ths
            switch (reg) {
1027 663e8e51 ths
            case 0:            /* Control Register */
1028 663e8e51 ths
                if (data & 0x8000) {
1029 663e8e51 ths
                    /* Reset status and control registers to default. */
1030 663e8e51 ths
                    s->mdimem[0] = eepro100_mdi_default[0];
1031 663e8e51 ths
                    s->mdimem[1] = eepro100_mdi_default[1];
1032 663e8e51 ths
                    data = s->mdimem[reg];
1033 663e8e51 ths
                } else {
1034 663e8e51 ths
                    /* Restart Auto Configuration = Normal Operation */
1035 663e8e51 ths
                    data &= ~0x0200;
1036 663e8e51 ths
                }
1037 663e8e51 ths
                break;
1038 663e8e51 ths
            case 1:            /* Status Register */
1039 663e8e51 ths
                missing("not writable");
1040 663e8e51 ths
                data = s->mdimem[reg];
1041 663e8e51 ths
                break;
1042 663e8e51 ths
            case 2:            /* PHY Identification Register (Word 1) */
1043 663e8e51 ths
            case 3:            /* PHY Identification Register (Word 2) */
1044 663e8e51 ths
                missing("not implemented");
1045 663e8e51 ths
                break;
1046 663e8e51 ths
            case 4:            /* Auto-Negotiation Advertisement Register */
1047 663e8e51 ths
            case 5:            /* Auto-Negotiation Link Partner Ability Register */
1048 663e8e51 ths
                break;
1049 663e8e51 ths
            case 6:            /* Auto-Negotiation Expansion Register */
1050 663e8e51 ths
            default:
1051 663e8e51 ths
                missing("not implemented");
1052 663e8e51 ths
            }
1053 663e8e51 ths
            s->mdimem[reg] = data;
1054 663e8e51 ths
        } else if (opcode == 2) {
1055 663e8e51 ths
            /* MDI read */
1056 663e8e51 ths
            switch (reg) {
1057 663e8e51 ths
            case 0:            /* Control Register */
1058 663e8e51 ths
                if (data & 0x8000) {
1059 663e8e51 ths
                    /* Reset status and control registers to default. */
1060 663e8e51 ths
                    s->mdimem[0] = eepro100_mdi_default[0];
1061 663e8e51 ths
                    s->mdimem[1] = eepro100_mdi_default[1];
1062 663e8e51 ths
                }
1063 663e8e51 ths
                break;
1064 663e8e51 ths
            case 1:            /* Status Register */
1065 663e8e51 ths
                s->mdimem[reg] |= 0x0020;
1066 663e8e51 ths
                break;
1067 663e8e51 ths
            case 2:            /* PHY Identification Register (Word 1) */
1068 663e8e51 ths
            case 3:            /* PHY Identification Register (Word 2) */
1069 663e8e51 ths
            case 4:            /* Auto-Negotiation Advertisement Register */
1070 663e8e51 ths
                break;
1071 663e8e51 ths
            case 5:            /* Auto-Negotiation Link Partner Ability Register */
1072 663e8e51 ths
                s->mdimem[reg] = 0x41fe;
1073 663e8e51 ths
                break;
1074 663e8e51 ths
            case 6:            /* Auto-Negotiation Expansion Register */
1075 663e8e51 ths
                s->mdimem[reg] = 0x0001;
1076 663e8e51 ths
                break;
1077 663e8e51 ths
            }
1078 663e8e51 ths
            data = s->mdimem[reg];
1079 663e8e51 ths
        }
1080 663e8e51 ths
        /* Emulation takes no time to finish MDI transaction.
1081 663e8e51 ths
         * Set MDI bit in SCB status register. */
1082 663e8e51 ths
        s->mem[SCBAck] |= 0x08;
1083 663e8e51 ths
        val |= BIT(28);
1084 663e8e51 ths
        if (raiseint) {
1085 663e8e51 ths
            eepro100_mdi_interrupt(s);
1086 663e8e51 ths
        }
1087 663e8e51 ths
    }
1088 663e8e51 ths
    val = (val & 0xffff0000) + data;
1089 663e8e51 ths
    memcpy(&s->mem[0x10], &val, sizeof(val));
1090 663e8e51 ths
}
1091 663e8e51 ths
1092 663e8e51 ths
/*****************************************************************************
1093 663e8e51 ths
 *
1094 663e8e51 ths
 * Port emulation.
1095 663e8e51 ths
 *
1096 663e8e51 ths
 ****************************************************************************/
1097 663e8e51 ths
1098 663e8e51 ths
#define PORT_SOFTWARE_RESET     0
1099 663e8e51 ths
#define PORT_SELFTEST           1
1100 663e8e51 ths
#define PORT_SELECTIVE_RESET    2
1101 663e8e51 ths
#define PORT_DUMP               3
1102 663e8e51 ths
#define PORT_SELECTION_MASK     3
1103 663e8e51 ths
1104 663e8e51 ths
typedef struct {
1105 663e8e51 ths
    uint32_t st_sign;           /* Self Test Signature */
1106 663e8e51 ths
    uint32_t st_result;         /* Self Test Results */
1107 c227f099 Anthony Liguori
} eepro100_selftest_t;
1108 663e8e51 ths
1109 663e8e51 ths
static uint32_t eepro100_read_port(EEPRO100State * s)
1110 663e8e51 ths
{
1111 663e8e51 ths
    return 0;
1112 663e8e51 ths
}
1113 663e8e51 ths
1114 663e8e51 ths
static void eepro100_write_port(EEPRO100State * s, uint32_t val)
1115 663e8e51 ths
{
1116 663e8e51 ths
    val = le32_to_cpu(val);
1117 663e8e51 ths
    uint32_t address = (val & ~PORT_SELECTION_MASK);
1118 663e8e51 ths
    uint8_t selection = (val & PORT_SELECTION_MASK);
1119 663e8e51 ths
    switch (selection) {
1120 663e8e51 ths
    case PORT_SOFTWARE_RESET:
1121 663e8e51 ths
        nic_reset(s);
1122 663e8e51 ths
        break;
1123 663e8e51 ths
    case PORT_SELFTEST:
1124 aac443e6 Stefan Weil
        TRACE(OTHER, logout("selftest address=0x%08x\n", address));
1125 c227f099 Anthony Liguori
        eepro100_selftest_t data;
1126 663e8e51 ths
        cpu_physical_memory_read(address, (uint8_t *) & data, sizeof(data));
1127 663e8e51 ths
        data.st_sign = 0xffffffff;
1128 663e8e51 ths
        data.st_result = 0;
1129 663e8e51 ths
        cpu_physical_memory_write(address, (uint8_t *) & data, sizeof(data));
1130 663e8e51 ths
        break;
1131 663e8e51 ths
    case PORT_SELECTIVE_RESET:
1132 aac443e6 Stefan Weil
        TRACE(OTHER, logout("selective reset, selftest address=0x%08x\n", address));
1133 663e8e51 ths
        nic_selective_reset(s);
1134 663e8e51 ths
        break;
1135 663e8e51 ths
    default:
1136 663e8e51 ths
        logout("val=0x%08x\n", val);
1137 663e8e51 ths
        missing("unknown port selection");
1138 663e8e51 ths
    }
1139 663e8e51 ths
}
1140 663e8e51 ths
1141 663e8e51 ths
/*****************************************************************************
1142 663e8e51 ths
 *
1143 663e8e51 ths
 * General hardware emulation.
1144 663e8e51 ths
 *
1145 663e8e51 ths
 ****************************************************************************/
1146 663e8e51 ths
1147 663e8e51 ths
static uint8_t eepro100_read1(EEPRO100State * s, uint32_t addr)
1148 663e8e51 ths
{
1149 663e8e51 ths
    uint8_t val;
1150 663e8e51 ths
    if (addr <= sizeof(s->mem) - sizeof(val)) {
1151 663e8e51 ths
        memcpy(&val, &s->mem[addr], sizeof(val));
1152 663e8e51 ths
    }
1153 663e8e51 ths
1154 663e8e51 ths
    switch (addr) {
1155 663e8e51 ths
    case SCBStatus:
1156 663e8e51 ths
        //~ val = eepro100_read_status(s);
1157 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
1158 663e8e51 ths
        break;
1159 663e8e51 ths
    case SCBAck:
1160 663e8e51 ths
        //~ val = eepro100_read_status(s);
1161 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
1162 663e8e51 ths
        break;
1163 663e8e51 ths
    case SCBCmd:
1164 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
1165 663e8e51 ths
        //~ val = eepro100_read_command(s);
1166 663e8e51 ths
        break;
1167 663e8e51 ths
    case SCBIntmask:
1168 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
1169 663e8e51 ths
        break;
1170 663e8e51 ths
    case SCBPort + 3:
1171 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
1172 663e8e51 ths
        break;
1173 663e8e51 ths
    case SCBeeprom:
1174 663e8e51 ths
        val = eepro100_read_eeprom(s);
1175 663e8e51 ths
        break;
1176 663e8e51 ths
    case 0x1b:                 /* PMDR (power management driver register) */
1177 663e8e51 ths
        val = 0;
1178 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
1179 663e8e51 ths
        break;
1180 663e8e51 ths
    case 0x1d:                 /* general status register */
1181 663e8e51 ths
        /* 100 Mbps full duplex, valid link */
1182 663e8e51 ths
        val = 0x07;
1183 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=General Status val=%02x\n", val));
1184 663e8e51 ths
        break;
1185 663e8e51 ths
    default:
1186 663e8e51 ths
        logout("addr=%s val=0x%02x\n", regname(addr), val);
1187 663e8e51 ths
        missing("unknown byte read");
1188 663e8e51 ths
    }
1189 663e8e51 ths
    return val;
1190 663e8e51 ths
}
1191 663e8e51 ths
1192 663e8e51 ths
static uint16_t eepro100_read2(EEPRO100State * s, uint32_t addr)
1193 663e8e51 ths
{
1194 663e8e51 ths
    uint16_t val;
1195 663e8e51 ths
    if (addr <= sizeof(s->mem) - sizeof(val)) {
1196 663e8e51 ths
        memcpy(&val, &s->mem[addr], sizeof(val));
1197 663e8e51 ths
    }
1198 663e8e51 ths
1199 663e8e51 ths
    switch (addr) {
1200 663e8e51 ths
    case SCBStatus:
1201 663e8e51 ths
        //~ val = eepro100_read_status(s);
1202 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
1203 663e8e51 ths
        break;
1204 663e8e51 ths
    case SCBeeprom:
1205 663e8e51 ths
        val = eepro100_read_eeprom(s);
1206 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
1207 663e8e51 ths
        break;
1208 663e8e51 ths
    default:
1209 663e8e51 ths
        logout("addr=%s val=0x%04x\n", regname(addr), val);
1210 663e8e51 ths
        missing("unknown word read");
1211 663e8e51 ths
    }
1212 663e8e51 ths
    return val;
1213 663e8e51 ths
}
1214 663e8e51 ths
1215 663e8e51 ths
static uint32_t eepro100_read4(EEPRO100State * s, uint32_t addr)
1216 663e8e51 ths
{
1217 663e8e51 ths
    uint32_t val;
1218 663e8e51 ths
    if (addr <= sizeof(s->mem) - sizeof(val)) {
1219 663e8e51 ths
        memcpy(&val, &s->mem[addr], sizeof(val));
1220 663e8e51 ths
    }
1221 663e8e51 ths
1222 663e8e51 ths
    switch (addr) {
1223 663e8e51 ths
    case SCBStatus:
1224 663e8e51 ths
        //~ val = eepro100_read_status(s);
1225 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
1226 663e8e51 ths
        break;
1227 663e8e51 ths
    case SCBPointer:
1228 663e8e51 ths
        //~ val = eepro100_read_pointer(s);
1229 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
1230 663e8e51 ths
        break;
1231 663e8e51 ths
    case SCBPort:
1232 663e8e51 ths
        val = eepro100_read_port(s);
1233 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
1234 663e8e51 ths
        break;
1235 663e8e51 ths
    case SCBCtrlMDI:
1236 663e8e51 ths
        val = eepro100_read_mdi(s);
1237 663e8e51 ths
        break;
1238 663e8e51 ths
    default:
1239 663e8e51 ths
        logout("addr=%s val=0x%08x\n", regname(addr), val);
1240 663e8e51 ths
        missing("unknown longword read");
1241 663e8e51 ths
    }
1242 663e8e51 ths
    return val;
1243 663e8e51 ths
}
1244 663e8e51 ths
1245 663e8e51 ths
static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val)
1246 663e8e51 ths
{
1247 663e8e51 ths
    if (addr <= sizeof(s->mem) - sizeof(val)) {
1248 663e8e51 ths
        memcpy(&s->mem[addr], &val, sizeof(val));
1249 663e8e51 ths
    }
1250 663e8e51 ths
1251 aac443e6 Stefan Weil
    TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
1252 663e8e51 ths
1253 663e8e51 ths
    switch (addr) {
1254 663e8e51 ths
    case SCBStatus:
1255 663e8e51 ths
        //~ eepro100_write_status(s, val);
1256 663e8e51 ths
        break;
1257 663e8e51 ths
    case SCBAck:
1258 663e8e51 ths
        eepro100_acknowledge(s);
1259 663e8e51 ths
        break;
1260 663e8e51 ths
    case SCBCmd:
1261 663e8e51 ths
        eepro100_write_command(s, val);
1262 663e8e51 ths
        break;
1263 663e8e51 ths
    case SCBIntmask:
1264 663e8e51 ths
        if (val & BIT(1)) {
1265 663e8e51 ths
            eepro100_swi_interrupt(s);
1266 663e8e51 ths
        }
1267 663e8e51 ths
        eepro100_interrupt(s, 0);
1268 663e8e51 ths
        break;
1269 663e8e51 ths
    case SCBPort + 3:
1270 aac443e6 Stefan Weil
    case SCBFlow:       /* does not exist on 82557 */
1271 3257d2b6 ths
    case SCBFlow + 1:
1272 3257d2b6 ths
    case SCBFlow + 2:
1273 3257d2b6 ths
    case SCBFlow + 3:
1274 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
1275 663e8e51 ths
        break;
1276 663e8e51 ths
    case SCBeeprom:
1277 663e8e51 ths
        eepro100_write_eeprom(s->eeprom, val);
1278 663e8e51 ths
        break;
1279 663e8e51 ths
    default:
1280 663e8e51 ths
        logout("addr=%s val=0x%02x\n", regname(addr), val);
1281 663e8e51 ths
        missing("unknown byte write");
1282 663e8e51 ths
    }
1283 663e8e51 ths
}
1284 663e8e51 ths
1285 663e8e51 ths
static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val)
1286 663e8e51 ths
{
1287 663e8e51 ths
    if (addr <= sizeof(s->mem) - sizeof(val)) {
1288 663e8e51 ths
        memcpy(&s->mem[addr], &val, sizeof(val));
1289 663e8e51 ths
    }
1290 663e8e51 ths
1291 aac443e6 Stefan Weil
    TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
1292 663e8e51 ths
1293 663e8e51 ths
    switch (addr) {
1294 663e8e51 ths
    case SCBStatus:
1295 663e8e51 ths
        //~ eepro100_write_status(s, val);
1296 663e8e51 ths
        eepro100_acknowledge(s);
1297 663e8e51 ths
        break;
1298 663e8e51 ths
    case SCBCmd:
1299 663e8e51 ths
        eepro100_write_command(s, val);
1300 663e8e51 ths
        eepro100_write1(s, SCBIntmask, val >> 8);
1301 663e8e51 ths
        break;
1302 663e8e51 ths
    case SCBeeprom:
1303 663e8e51 ths
        eepro100_write_eeprom(s->eeprom, val);
1304 663e8e51 ths
        break;
1305 663e8e51 ths
    default:
1306 663e8e51 ths
        logout("addr=%s val=0x%04x\n", regname(addr), val);
1307 663e8e51 ths
        missing("unknown word write");
1308 663e8e51 ths
    }
1309 663e8e51 ths
}
1310 663e8e51 ths
1311 663e8e51 ths
static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val)
1312 663e8e51 ths
{
1313 663e8e51 ths
    if (addr <= sizeof(s->mem) - sizeof(val)) {
1314 663e8e51 ths
        memcpy(&s->mem[addr], &val, sizeof(val));
1315 663e8e51 ths
    }
1316 663e8e51 ths
1317 663e8e51 ths
    switch (addr) {
1318 663e8e51 ths
    case SCBPointer:
1319 663e8e51 ths
        eepro100_write_pointer(s, val);
1320 663e8e51 ths
        break;
1321 663e8e51 ths
    case SCBPort:
1322 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
1323 663e8e51 ths
        eepro100_write_port(s, val);
1324 663e8e51 ths
        break;
1325 663e8e51 ths
    case SCBCtrlMDI:
1326 663e8e51 ths
        eepro100_write_mdi(s, val);
1327 663e8e51 ths
        break;
1328 663e8e51 ths
    default:
1329 663e8e51 ths
        logout("addr=%s val=0x%08x\n", regname(addr), val);
1330 663e8e51 ths
        missing("unknown longword write");
1331 663e8e51 ths
    }
1332 663e8e51 ths
}
1333 663e8e51 ths
1334 aac443e6 Stefan Weil
/*****************************************************************************
1335 aac443e6 Stefan Weil
 *
1336 aac443e6 Stefan Weil
 * Port mapped I/O.
1337 aac443e6 Stefan Weil
 *
1338 aac443e6 Stefan Weil
 ****************************************************************************/
1339 aac443e6 Stefan Weil
1340 663e8e51 ths
static uint32_t ioport_read1(void *opaque, uint32_t addr)
1341 663e8e51 ths
{
1342 663e8e51 ths
    EEPRO100State *s = opaque;
1343 663e8e51 ths
    //~ logout("addr=%s\n", regname(addr));
1344 663e8e51 ths
    return eepro100_read1(s, addr - s->region[1]);
1345 663e8e51 ths
}
1346 663e8e51 ths
1347 663e8e51 ths
static uint32_t ioport_read2(void *opaque, uint32_t addr)
1348 663e8e51 ths
{
1349 663e8e51 ths
    EEPRO100State *s = opaque;
1350 663e8e51 ths
    return eepro100_read2(s, addr - s->region[1]);
1351 663e8e51 ths
}
1352 663e8e51 ths
1353 663e8e51 ths
static uint32_t ioport_read4(void *opaque, uint32_t addr)
1354 663e8e51 ths
{
1355 663e8e51 ths
    EEPRO100State *s = opaque;
1356 663e8e51 ths
    return eepro100_read4(s, addr - s->region[1]);
1357 663e8e51 ths
}
1358 663e8e51 ths
1359 663e8e51 ths
static void ioport_write1(void *opaque, uint32_t addr, uint32_t val)
1360 663e8e51 ths
{
1361 663e8e51 ths
    EEPRO100State *s = opaque;
1362 663e8e51 ths
    //~ logout("addr=%s val=0x%02x\n", regname(addr), val);
1363 663e8e51 ths
    eepro100_write1(s, addr - s->region[1], val);
1364 663e8e51 ths
}
1365 663e8e51 ths
1366 663e8e51 ths
static void ioport_write2(void *opaque, uint32_t addr, uint32_t val)
1367 663e8e51 ths
{
1368 663e8e51 ths
    EEPRO100State *s = opaque;
1369 663e8e51 ths
    eepro100_write2(s, addr - s->region[1], val);
1370 663e8e51 ths
}
1371 663e8e51 ths
1372 663e8e51 ths
static void ioport_write4(void *opaque, uint32_t addr, uint32_t val)
1373 663e8e51 ths
{
1374 663e8e51 ths
    EEPRO100State *s = opaque;
1375 663e8e51 ths
    eepro100_write4(s, addr - s->region[1], val);
1376 663e8e51 ths
}
1377 663e8e51 ths
1378 663e8e51 ths
/***********************************************************/
1379 663e8e51 ths
/* PCI EEPRO100 definitions */
1380 663e8e51 ths
1381 663e8e51 ths
static void pci_map(PCIDevice * pci_dev, int region_num,
1382 663e8e51 ths
                    uint32_t addr, uint32_t size, int type)
1383 663e8e51 ths
{
1384 273a2142 Juan Quintela
    EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
1385 663e8e51 ths
1386 aac443e6 Stefan Weil
    TRACE(OTHER, logout("region %d, addr=0x%08x, size=0x%08x, type=%d\n",
1387 aac443e6 Stefan Weil
          region_num, addr, size, type));
1388 663e8e51 ths
1389 663e8e51 ths
    assert(region_num == 1);
1390 663e8e51 ths
    register_ioport_write(addr, size, 1, ioport_write1, s);
1391 663e8e51 ths
    register_ioport_read(addr, size, 1, ioport_read1, s);
1392 663e8e51 ths
    register_ioport_write(addr, size, 2, ioport_write2, s);
1393 663e8e51 ths
    register_ioport_read(addr, size, 2, ioport_read2, s);
1394 663e8e51 ths
    register_ioport_write(addr, size, 4, ioport_write4, s);
1395 663e8e51 ths
    register_ioport_read(addr, size, 4, ioport_read4, s);
1396 663e8e51 ths
1397 663e8e51 ths
    s->region[region_num] = addr;
1398 663e8e51 ths
}
1399 663e8e51 ths
1400 aac443e6 Stefan Weil
/*****************************************************************************
1401 aac443e6 Stefan Weil
 *
1402 aac443e6 Stefan Weil
 * Memory mapped I/O.
1403 aac443e6 Stefan Weil
 *
1404 aac443e6 Stefan Weil
 ****************************************************************************/
1405 aac443e6 Stefan Weil
1406 c227f099 Anthony Liguori
static void pci_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
1407 663e8e51 ths
{
1408 663e8e51 ths
    EEPRO100State *s = opaque;
1409 663e8e51 ths
    //~ logout("addr=%s val=0x%02x\n", regname(addr), val);
1410 663e8e51 ths
    eepro100_write1(s, addr, val);
1411 663e8e51 ths
}
1412 663e8e51 ths
1413 c227f099 Anthony Liguori
static void pci_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
1414 663e8e51 ths
{
1415 663e8e51 ths
    EEPRO100State *s = opaque;
1416 663e8e51 ths
    //~ logout("addr=%s val=0x%02x\n", regname(addr), val);
1417 663e8e51 ths
    eepro100_write2(s, addr, val);
1418 663e8e51 ths
}
1419 663e8e51 ths
1420 c227f099 Anthony Liguori
static void pci_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
1421 663e8e51 ths
{
1422 663e8e51 ths
    EEPRO100State *s = opaque;
1423 663e8e51 ths
    //~ logout("addr=%s val=0x%02x\n", regname(addr), val);
1424 663e8e51 ths
    eepro100_write4(s, addr, val);
1425 663e8e51 ths
}
1426 663e8e51 ths
1427 c227f099 Anthony Liguori
static uint32_t pci_mmio_readb(void *opaque, target_phys_addr_t addr)
1428 663e8e51 ths
{
1429 663e8e51 ths
    EEPRO100State *s = opaque;
1430 663e8e51 ths
    //~ logout("addr=%s\n", regname(addr));
1431 663e8e51 ths
    return eepro100_read1(s, addr);
1432 663e8e51 ths
}
1433 663e8e51 ths
1434 c227f099 Anthony Liguori
static uint32_t pci_mmio_readw(void *opaque, target_phys_addr_t addr)
1435 663e8e51 ths
{
1436 663e8e51 ths
    EEPRO100State *s = opaque;
1437 663e8e51 ths
    //~ logout("addr=%s\n", regname(addr));
1438 663e8e51 ths
    return eepro100_read2(s, addr);
1439 663e8e51 ths
}
1440 663e8e51 ths
1441 c227f099 Anthony Liguori
static uint32_t pci_mmio_readl(void *opaque, target_phys_addr_t addr)
1442 663e8e51 ths
{
1443 663e8e51 ths
    EEPRO100State *s = opaque;
1444 663e8e51 ths
    //~ logout("addr=%s\n", regname(addr));
1445 663e8e51 ths
    return eepro100_read4(s, addr);
1446 663e8e51 ths
}
1447 663e8e51 ths
1448 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const pci_mmio_write[] = {
1449 663e8e51 ths
    pci_mmio_writeb,
1450 663e8e51 ths
    pci_mmio_writew,
1451 663e8e51 ths
    pci_mmio_writel
1452 663e8e51 ths
};
1453 663e8e51 ths
1454 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const pci_mmio_read[] = {
1455 663e8e51 ths
    pci_mmio_readb,
1456 663e8e51 ths
    pci_mmio_readw,
1457 663e8e51 ths
    pci_mmio_readl
1458 663e8e51 ths
};
1459 663e8e51 ths
1460 663e8e51 ths
static void pci_mmio_map(PCIDevice * pci_dev, int region_num,
1461 663e8e51 ths
                         uint32_t addr, uint32_t size, int type)
1462 663e8e51 ths
{
1463 273a2142 Juan Quintela
    EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
1464 663e8e51 ths
1465 aac443e6 Stefan Weil
    TRACE(OTHER, logout("region %d, addr=0x%08x, size=0x%08x, type=%d\n",
1466 aac443e6 Stefan Weil
          region_num, addr, size, type));
1467 663e8e51 ths
1468 663e8e51 ths
    if (region_num == 0) {
1469 663e8e51 ths
        /* Map control / status registers. */
1470 273a2142 Juan Quintela
        cpu_register_physical_memory(addr, size, s->mmio_index);
1471 273a2142 Juan Quintela
        s->region[region_num] = addr;
1472 663e8e51 ths
    }
1473 663e8e51 ths
}
1474 663e8e51 ths
1475 e3f5ec2b Mark McLoughlin
static int nic_can_receive(VLANClientState *vc)
1476 663e8e51 ths
{
1477 e3f5ec2b Mark McLoughlin
    EEPRO100State *s = vc->opaque;
1478 aac443e6 Stefan Weil
    TRACE(RXTX, logout("%p\n", s));
1479 663e8e51 ths
    return get_ru_state(s) == ru_ready;
1480 663e8e51 ths
    //~ return !eepro100_buffer_full(s);
1481 663e8e51 ths
}
1482 663e8e51 ths
1483 4f1c942b Mark McLoughlin
static ssize_t nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
1484 663e8e51 ths
{
1485 663e8e51 ths
    /* TODO:
1486 663e8e51 ths
     * - Magic packets should set bit 30 in power management driver register.
1487 663e8e51 ths
     * - Interesting packets should set bit 29 in power management driver register.
1488 663e8e51 ths
     */
1489 e3f5ec2b Mark McLoughlin
    EEPRO100State *s = vc->opaque;
1490 663e8e51 ths
    uint16_t rfd_status = 0xa000;
1491 663e8e51 ths
    static const uint8_t broadcast_macaddr[6] =
1492 663e8e51 ths
        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1493 663e8e51 ths
1494 663e8e51 ths
    /* TODO: check multiple IA bit. */
1495 663e8e51 ths
    assert(!(s->configuration[20] & BIT(6)));
1496 663e8e51 ths
1497 663e8e51 ths
    if (s->configuration[8] & 0x80) {
1498 663e8e51 ths
        /* CSMA is disabled. */
1499 663e8e51 ths
        logout("%p received while CSMA is disabled\n", s);
1500 4f1c942b Mark McLoughlin
        return -1;
1501 663e8e51 ths
    } else if (size < 64 && (s->configuration[7] & 1)) {
1502 663e8e51 ths
        /* Short frame and configuration byte 7/0 (discard short receive) set:
1503 663e8e51 ths
         * Short frame is discarded */
1504 067d01de Stefan Weil
        logout("%p received short frame (%zu byte)\n", s, size);
1505 663e8e51 ths
        s->statistics.rx_short_frame_errors++;
1506 4f1c942b Mark McLoughlin
        //~ return -1;
1507 663e8e51 ths
    } else if ((size > MAX_ETH_FRAME_SIZE + 4) && !(s->configuration[18] & 8)) {
1508 663e8e51 ths
        /* Long frame and configuration byte 18/3 (long receive ok) not set:
1509 663e8e51 ths
         * Long frames are discarded. */
1510 067d01de Stefan Weil
        logout("%p received long frame (%zu byte), ignored\n", s, size);
1511 4f1c942b Mark McLoughlin
        return -1;
1512 663e8e51 ths
    } else if (memcmp(buf, s->macaddr, 6) == 0) {       // !!!
1513 663e8e51 ths
        /* Frame matches individual address. */
1514 663e8e51 ths
        /* TODO: check configuration byte 15/4 (ignore U/L). */
1515 067d01de Stefan Weil
        TRACE(RXTX, logout("%p received frame for me, len=%zu\n", s, size));
1516 663e8e51 ths
    } else if (memcmp(buf, broadcast_macaddr, 6) == 0) {
1517 663e8e51 ths
        /* Broadcast frame. */
1518 067d01de Stefan Weil
        TRACE(RXTX, logout("%p received broadcast, len=%zu\n", s, size));
1519 663e8e51 ths
        rfd_status |= 0x0002;
1520 663e8e51 ths
    } else if (buf[0] & 0x01) { // !!!
1521 663e8e51 ths
        /* Multicast frame. */
1522 067d01de Stefan Weil
        TRACE(RXTX, logout("%p received multicast, len=%zu\n", s, size));
1523 663e8e51 ths
        /* TODO: check multicast all bit. */
1524 663e8e51 ths
        assert(!(s->configuration[21] & BIT(3)));
1525 663e8e51 ths
        int mcast_idx = compute_mcast_idx(buf);
1526 663e8e51 ths
        if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) {
1527 4f1c942b Mark McLoughlin
            return size;
1528 663e8e51 ths
        }
1529 663e8e51 ths
        rfd_status |= 0x0002;
1530 663e8e51 ths
    } else if (s->configuration[15] & 1) {
1531 663e8e51 ths
        /* Promiscuous: receive all. */
1532 067d01de Stefan Weil
        TRACE(RXTX, logout("%p received frame in promiscuous mode, len=%zu\n", s, size));
1533 663e8e51 ths
        rfd_status |= 0x0004;
1534 663e8e51 ths
    } else {
1535 067d01de Stefan Weil
        TRACE(RXTX, logout("%p received frame, ignored, len=%zu,%s\n", s, size,
1536 aac443e6 Stefan Weil
              nic_dump(buf, size)));
1537 4f1c942b Mark McLoughlin
        return size;
1538 663e8e51 ths
    }
1539 663e8e51 ths
1540 663e8e51 ths
    if (get_ru_state(s) != ru_ready) {
1541 aac443e6 Stefan Weil
        /* No resources available. */
1542 aac443e6 Stefan Weil
        logout("no resources, state=%u\n", get_ru_state(s));
1543 663e8e51 ths
        s->statistics.rx_resource_errors++;
1544 aac443e6 Stefan Weil
        //~ assert(!"no resources");
1545 4f1c942b Mark McLoughlin
        return -1;
1546 663e8e51 ths
    }
1547 663e8e51 ths
    //~ !!!
1548 663e8e51 ths
//~ $3 = {status = 0x0, command = 0xc000, link = 0x2d220, rx_buf_addr = 0x207dc, count = 0x0, size = 0x5f8, packet = {0x0 <repeats 1518 times>}}
1549 c227f099 Anthony Liguori
    eepro100_rx_t rx;
1550 663e8e51 ths
    cpu_physical_memory_read(s->ru_base + s->ru_offset, (uint8_t *) & rx,
1551 c227f099 Anthony Liguori
                             offsetof(eepro100_rx_t, packet));
1552 663e8e51 ths
    uint16_t rfd_command = le16_to_cpu(rx.command);
1553 663e8e51 ths
    uint16_t rfd_size = le16_to_cpu(rx.size);
1554 663e8e51 ths
    assert(size <= rfd_size);
1555 663e8e51 ths
    if (size < 64) {
1556 663e8e51 ths
        rfd_status |= 0x0080;
1557 663e8e51 ths
    }
1558 aac443e6 Stefan Weil
    TRACE(OTHER, logout("command 0x%04x, link 0x%08x, addr 0x%08x, size %u\n",
1559 aac443e6 Stefan Weil
          rfd_command, rx.link, rx.rx_buf_addr, rfd_size));
1560 c227f099 Anthony Liguori
    stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, status),
1561 663e8e51 ths
             rfd_status);
1562 c227f099 Anthony Liguori
    stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, count), size);
1563 663e8e51 ths
    /* Early receive interrupt not supported. */
1564 663e8e51 ths
    //~ eepro100_er_interrupt(s);
1565 663e8e51 ths
    /* Receive CRC Transfer not supported. */
1566 663e8e51 ths
    assert(!(s->configuration[18] & 4));
1567 663e8e51 ths
    /* TODO: check stripping enable bit. */
1568 663e8e51 ths
    //~ assert(!(s->configuration[17] & 1));
1569 663e8e51 ths
    cpu_physical_memory_write(s->ru_base + s->ru_offset +
1570 c227f099 Anthony Liguori
                              offsetof(eepro100_rx_t, packet), buf, size);
1571 663e8e51 ths
    s->statistics.rx_good_frames++;
1572 663e8e51 ths
    eepro100_fr_interrupt(s);
1573 663e8e51 ths
    s->ru_offset = le32_to_cpu(rx.link);
1574 663e8e51 ths
    if (rfd_command & 0x8000) {
1575 663e8e51 ths
        /* EL bit is set, so this was the last frame. */
1576 663e8e51 ths
        assert(0);
1577 663e8e51 ths
    }
1578 663e8e51 ths
    if (rfd_command & 0x4000) {
1579 663e8e51 ths
        /* S bit is set. */
1580 663e8e51 ths
        set_ru_state(s, ru_suspended);
1581 663e8e51 ths
    }
1582 4f1c942b Mark McLoughlin
    return size;
1583 663e8e51 ths
}
1584 663e8e51 ths
1585 663e8e51 ths
static int nic_load(QEMUFile * f, void *opaque, int version_id)
1586 663e8e51 ths
{
1587 769cf7a5 Juan Quintela
    EEPRO100State *s = opaque;
1588 2657c663 balrog
    int i;
1589 663e8e51 ths
    int ret;
1590 663e8e51 ths
1591 4e3db917 Aurelien Jarno
    if (version_id > 3)
1592 663e8e51 ths
        return -EINVAL;
1593 4e3db917 Aurelien Jarno
1594 4e3db917 Aurelien Jarno
    if (version_id >= 3) {
1595 4e3db917 Aurelien Jarno
        ret = pci_device_load(&s->dev, f);
1596 4e3db917 Aurelien Jarno
        if (ret < 0)
1597 4e3db917 Aurelien Jarno
            return ret;
1598 663e8e51 ths
    }
1599 663e8e51 ths
1600 4e3db917 Aurelien Jarno
    if (version_id >= 2) {
1601 4e3db917 Aurelien Jarno
        qemu_get_8s(f, &s->rxcr);
1602 4e3db917 Aurelien Jarno
    } else {
1603 4e3db917 Aurelien Jarno
        s->rxcr = 0x0c;
1604 663e8e51 ths
    }
1605 663e8e51 ths
1606 663e8e51 ths
    qemu_get_8s(f, &s->cmd);
1607 663e8e51 ths
    qemu_get_be32s(f, &s->start);
1608 663e8e51 ths
    qemu_get_be32s(f, &s->stop);
1609 4e3db917 Aurelien Jarno
    qemu_get_8s(f, &s->boundary);
1610 4e3db917 Aurelien Jarno
    qemu_get_8s(f, &s->tsr);
1611 4e3db917 Aurelien Jarno
    qemu_get_8s(f, &s->tpsr);
1612 4e3db917 Aurelien Jarno
    qemu_get_be16s(f, &s->tcnt);
1613 4e3db917 Aurelien Jarno
    qemu_get_be16s(f, &s->rcnt);
1614 4e3db917 Aurelien Jarno
    qemu_get_be32s(f, &s->rsar);
1615 4e3db917 Aurelien Jarno
    qemu_get_8s(f, &s->rsr);
1616 4e3db917 Aurelien Jarno
    qemu_get_8s(f, &s->isr);
1617 4e3db917 Aurelien Jarno
    qemu_get_8s(f, &s->dcfg);
1618 4e3db917 Aurelien Jarno
    qemu_get_8s(f, &s->imr);
1619 4e3db917 Aurelien Jarno
    qemu_get_buffer(f, s->phys, 6);
1620 4e3db917 Aurelien Jarno
    qemu_get_8s(f, &s->curpag);
1621 663e8e51 ths
    qemu_get_buffer(f, s->mult, 8);
1622 663e8e51 ths
    qemu_get_buffer(f, s->mem, sizeof(s->mem));
1623 663e8e51 ths
1624 aac443e6 Stefan Weil
    /* Restore all members of struct between scv_stat and mem. */
1625 2657c663 balrog
    qemu_get_8s(f, &s->scb_stat);
1626 2657c663 balrog
    qemu_get_8s(f, &s->int_stat);
1627 4e3db917 Aurelien Jarno
    for (i = 0; i < 3; i++) {
1628 2657c663 balrog
        qemu_get_be32s(f, &s->region[i]);
1629 aac443e6 Stefan Weil
    }
1630 2657c663 balrog
    qemu_get_buffer(f, s->macaddr, 6);
1631 4e3db917 Aurelien Jarno
    for (i = 0; i < 19; i++) {
1632 4e3db917 Aurelien Jarno
        qemu_get_be32s(f, &s->statcounter[i]);
1633 4e3db917 Aurelien Jarno
    }
1634 4e3db917 Aurelien Jarno
    for (i = 0; i < 32; i++) {
1635 2657c663 balrog
        qemu_get_be16s(f, &s->mdimem[i]);
1636 aac443e6 Stefan Weil
    }
1637 aac443e6 Stefan Weil
    /* The eeprom should be saved and restored by its own routines. */
1638 2657c663 balrog
    qemu_get_be32s(f, &s->device);
1639 2657c663 balrog
    qemu_get_be32s(f, &s->pointer);
1640 2657c663 balrog
    qemu_get_be32s(f, &s->cu_base);
1641 2657c663 balrog
    qemu_get_be32s(f, &s->cu_offset);
1642 2657c663 balrog
    qemu_get_be32s(f, &s->ru_base);
1643 2657c663 balrog
    qemu_get_be32s(f, &s->ru_offset);
1644 2657c663 balrog
    qemu_get_be32s(f, &s->statsaddr);
1645 aac443e6 Stefan Weil
    /* Restore epro100_stats_t statistics. */
1646 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_good_frames);
1647 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_max_collisions);
1648 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_late_collisions);
1649 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_underruns);
1650 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_lost_crs);
1651 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_deferred);
1652 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_single_collisions);
1653 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_multiple_collisions);
1654 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_total_collisions);
1655 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_good_frames);
1656 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_crc_errors);
1657 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_alignment_errors);
1658 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_resource_errors);
1659 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_overrun_errors);
1660 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_cdt_errors);
1661 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_short_frame_errors);
1662 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.fc_xmt_pause);
1663 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.fc_rcv_pause);
1664 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.fc_rcv_unsupported);
1665 2657c663 balrog
    qemu_get_be16s(f, &s->statistics.xmt_tco_frames);
1666 2657c663 balrog
    qemu_get_be16s(f, &s->statistics.rcv_tco_frames);
1667 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.complete);
1668 2657c663 balrog
#if 0
1669 2657c663 balrog
    qemu_get_be16s(f, &s->status);
1670 2657c663 balrog
#endif
1671 2657c663 balrog
1672 2657c663 balrog
    /* Configuration bytes. */
1673 2657c663 balrog
    qemu_get_buffer(f, s->configuration, sizeof(s->configuration));
1674 2657c663 balrog
1675 663e8e51 ths
    return 0;
1676 663e8e51 ths
}
1677 663e8e51 ths
1678 663e8e51 ths
static void nic_save(QEMUFile * f, void *opaque)
1679 663e8e51 ths
{
1680 769cf7a5 Juan Quintela
    EEPRO100State *s = opaque;
1681 2657c663 balrog
    int i;
1682 663e8e51 ths
1683 273a2142 Juan Quintela
    pci_device_save(&s->dev, f);
1684 663e8e51 ths
1685 4e3db917 Aurelien Jarno
    qemu_put_8s(f, &s->rxcr);
1686 4e3db917 Aurelien Jarno
1687 663e8e51 ths
    qemu_put_8s(f, &s->cmd);
1688 663e8e51 ths
    qemu_put_be32s(f, &s->start);
1689 663e8e51 ths
    qemu_put_be32s(f, &s->stop);
1690 4e3db917 Aurelien Jarno
    qemu_put_8s(f, &s->boundary);
1691 4e3db917 Aurelien Jarno
    qemu_put_8s(f, &s->tsr);
1692 4e3db917 Aurelien Jarno
    qemu_put_8s(f, &s->tpsr);
1693 4e3db917 Aurelien Jarno
    qemu_put_be16s(f, &s->tcnt);
1694 4e3db917 Aurelien Jarno
    qemu_put_be16s(f, &s->rcnt);
1695 4e3db917 Aurelien Jarno
    qemu_put_be32s(f, &s->rsar);
1696 4e3db917 Aurelien Jarno
    qemu_put_8s(f, &s->rsr);
1697 4e3db917 Aurelien Jarno
    qemu_put_8s(f, &s->isr);
1698 4e3db917 Aurelien Jarno
    qemu_put_8s(f, &s->dcfg);
1699 4e3db917 Aurelien Jarno
    qemu_put_8s(f, &s->imr);
1700 4e3db917 Aurelien Jarno
    qemu_put_buffer(f, s->phys, 6);
1701 4e3db917 Aurelien Jarno
    qemu_put_8s(f, &s->curpag);
1702 663e8e51 ths
    qemu_put_buffer(f, s->mult, 8);
1703 663e8e51 ths
    qemu_put_buffer(f, s->mem, sizeof(s->mem));
1704 2657c663 balrog
1705 aac443e6 Stefan Weil
    /* Save all members of struct between scv_stat and mem. */
1706 2657c663 balrog
    qemu_put_8s(f, &s->scb_stat);
1707 2657c663 balrog
    qemu_put_8s(f, &s->int_stat);
1708 4e3db917 Aurelien Jarno
    for (i = 0; i < 3; i++) {
1709 2657c663 balrog
        qemu_put_be32s(f, &s->region[i]);
1710 aac443e6 Stefan Weil
    }
1711 2657c663 balrog
    qemu_put_buffer(f, s->macaddr, 6);
1712 4e3db917 Aurelien Jarno
    for (i = 0; i < 19; i++) {
1713 4e3db917 Aurelien Jarno
        qemu_put_be32s(f, &s->statcounter[i]);
1714 4e3db917 Aurelien Jarno
    }
1715 4e3db917 Aurelien Jarno
    for (i = 0; i < 32; i++) {
1716 2657c663 balrog
        qemu_put_be16s(f, &s->mdimem[i]);
1717 aac443e6 Stefan Weil
    }
1718 aac443e6 Stefan Weil
    /* The eeprom should be saved and restored by its own routines. */
1719 2657c663 balrog
    qemu_put_be32s(f, &s->device);
1720 2657c663 balrog
    qemu_put_be32s(f, &s->pointer);
1721 2657c663 balrog
    qemu_put_be32s(f, &s->cu_base);
1722 2657c663 balrog
    qemu_put_be32s(f, &s->cu_offset);
1723 2657c663 balrog
    qemu_put_be32s(f, &s->ru_base);
1724 2657c663 balrog
    qemu_put_be32s(f, &s->ru_offset);
1725 2657c663 balrog
    qemu_put_be32s(f, &s->statsaddr);
1726 aac443e6 Stefan Weil
    /* Save epro100_stats_t statistics. */
1727 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_good_frames);
1728 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_max_collisions);
1729 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_late_collisions);
1730 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_underruns);
1731 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_lost_crs);
1732 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_deferred);
1733 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_single_collisions);
1734 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_multiple_collisions);
1735 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_total_collisions);
1736 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_good_frames);
1737 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_crc_errors);
1738 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_alignment_errors);
1739 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_resource_errors);
1740 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_overrun_errors);
1741 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_cdt_errors);
1742 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_short_frame_errors);
1743 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.fc_xmt_pause);
1744 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.fc_rcv_pause);
1745 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.fc_rcv_unsupported);
1746 2657c663 balrog
    qemu_put_be16s(f, &s->statistics.xmt_tco_frames);
1747 2657c663 balrog
    qemu_put_be16s(f, &s->statistics.rcv_tco_frames);
1748 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.complete);
1749 2657c663 balrog
#if 0
1750 2657c663 balrog
    qemu_put_be16s(f, &s->status);
1751 2657c663 balrog
#endif
1752 2657c663 balrog
1753 2657c663 balrog
    /* Configuration bytes. */
1754 2657c663 balrog
    qemu_put_buffer(f, s->configuration, sizeof(s->configuration));
1755 663e8e51 ths
}
1756 663e8e51 ths
1757 b946a153 aliguori
static void nic_cleanup(VLANClientState *vc)
1758 b946a153 aliguori
{
1759 b946a153 aliguori
    EEPRO100State *s = vc->opaque;
1760 b946a153 aliguori
1761 b946a153 aliguori
    unregister_savevm(vc->model, s);
1762 b946a153 aliguori
1763 b946a153 aliguori
    eeprom93xx_free(s->eeprom);
1764 b946a153 aliguori
}
1765 b946a153 aliguori
1766 c4c270e2 Stefan Weil
static int pci_nic_uninit(PCIDevice *pci_dev)
1767 b946a153 aliguori
{
1768 c4c270e2 Stefan Weil
    EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
1769 b946a153 aliguori
1770 b946a153 aliguori
    cpu_unregister_io_memory(s->mmio_index);
1771 b946a153 aliguori
1772 b946a153 aliguori
    return 0;
1773 b946a153 aliguori
}
1774 b946a153 aliguori
1775 81a322d4 Gerd Hoffmann
static int nic_init(PCIDevice *pci_dev, uint32_t device)
1776 663e8e51 ths
{
1777 273a2142 Juan Quintela
    EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
1778 663e8e51 ths
1779 aac443e6 Stefan Weil
    TRACE(OTHER, logout("\n"));
1780 663e8e51 ths
1781 663e8e51 ths
    s->device = device;
1782 663e8e51 ths
1783 663e8e51 ths
    pci_reset(s);
1784 663e8e51 ths
1785 663e8e51 ths
    /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM,
1786 663e8e51 ths
     * i82559 and later support 64 or 256 word EEPROM. */
1787 663e8e51 ths
    s->eeprom = eeprom93xx_new(EEPROM_SIZE);
1788 663e8e51 ths
1789 663e8e51 ths
    /* Handler for memory-mapped I/O */
1790 273a2142 Juan Quintela
    s->mmio_index =
1791 1eed09cb Avi Kivity
        cpu_register_io_memory(pci_mmio_read, pci_mmio_write, s);
1792 663e8e51 ths
1793 273a2142 Juan Quintela
    pci_register_bar(&s->dev, 0, PCI_MEM_SIZE,
1794 663e8e51 ths
                           PCI_ADDRESS_SPACE_MEM |
1795 663e8e51 ths
                           PCI_ADDRESS_SPACE_MEM_PREFETCH, pci_mmio_map);
1796 273a2142 Juan Quintela
    pci_register_bar(&s->dev, 1, PCI_IO_SIZE, PCI_ADDRESS_SPACE_IO,
1797 663e8e51 ths
                           pci_map);
1798 273a2142 Juan Quintela
    pci_register_bar(&s->dev, 2, PCI_FLASH_SIZE, PCI_ADDRESS_SPACE_MEM,
1799 663e8e51 ths
                           pci_mmio_map);
1800 663e8e51 ths
1801 273a2142 Juan Quintela
    qdev_get_macaddr(&s->dev.qdev, s->macaddr);
1802 663e8e51 ths
    logout("macaddr: %s\n", nic_dump(&s->macaddr[0], 6));
1803 663e8e51 ths
    assert(s->region[1] == 0);
1804 663e8e51 ths
1805 663e8e51 ths
    nic_reset(s);
1806 663e8e51 ths
1807 273a2142 Juan Quintela
    s->vc = qdev_get_vlan_client(&s->dev.qdev,
1808 463af534 Mark McLoughlin
                                 nic_can_receive, nic_receive, NULL,
1809 b946a153 aliguori
                                 nic_cleanup, s);
1810 663e8e51 ths
1811 7cb7434b aliguori
    qemu_format_nic_info_str(s->vc, s->macaddr);
1812 aac443e6 Stefan Weil
    TRACE(OTHER, logout("%s\n", s->vc->info_str));
1813 663e8e51 ths
1814 a08d4367 Jan Kiszka
    qemu_register_reset(nic_reset, s);
1815 663e8e51 ths
1816 4e3db917 Aurelien Jarno
    register_savevm(s->vc->model, -1, 3, nic_save, nic_load, s);
1817 81a322d4 Gerd Hoffmann
    return 0;
1818 663e8e51 ths
}
1819 663e8e51 ths
1820 c4c270e2 Stefan Weil
static int pci_i82550_init(PCIDevice *pci_dev)
1821 c4c270e2 Stefan Weil
{
1822 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82550);
1823 c4c270e2 Stefan Weil
}
1824 c4c270e2 Stefan Weil
1825 c4c270e2 Stefan Weil
static int pci_i82551_init(PCIDevice *pci_dev)
1826 c4c270e2 Stefan Weil
{
1827 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82551);
1828 c4c270e2 Stefan Weil
}
1829 c4c270e2 Stefan Weil
1830 c4c270e2 Stefan Weil
static int pci_i82557a_init(PCIDevice *pci_dev)
1831 c4c270e2 Stefan Weil
{
1832 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82557A);
1833 c4c270e2 Stefan Weil
}
1834 c4c270e2 Stefan Weil
1835 c4c270e2 Stefan Weil
static int pci_i82557b_init(PCIDevice *pci_dev)
1836 c4c270e2 Stefan Weil
{
1837 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82557B);
1838 c4c270e2 Stefan Weil
}
1839 c4c270e2 Stefan Weil
1840 c4c270e2 Stefan Weil
static int pci_i82557c_init(PCIDevice *pci_dev)
1841 c4c270e2 Stefan Weil
{
1842 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82557C);
1843 c4c270e2 Stefan Weil
}
1844 c4c270e2 Stefan Weil
1845 c4c270e2 Stefan Weil
static int pci_i82558a_init(PCIDevice *pci_dev)
1846 c4c270e2 Stefan Weil
{
1847 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82558A);
1848 c4c270e2 Stefan Weil
}
1849 c4c270e2 Stefan Weil
1850 c4c270e2 Stefan Weil
static int pci_i82558b_init(PCIDevice *pci_dev)
1851 c4c270e2 Stefan Weil
{
1852 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82558B);
1853 c4c270e2 Stefan Weil
}
1854 c4c270e2 Stefan Weil
1855 c4c270e2 Stefan Weil
static int pci_i82559a_init(PCIDevice *pci_dev)
1856 c4c270e2 Stefan Weil
{
1857 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82559A);
1858 c4c270e2 Stefan Weil
}
1859 c4c270e2 Stefan Weil
1860 c4c270e2 Stefan Weil
static int pci_i82559b_init(PCIDevice *pci_dev)
1861 c4c270e2 Stefan Weil
{
1862 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82559B);
1863 c4c270e2 Stefan Weil
}
1864 c4c270e2 Stefan Weil
1865 c4c270e2 Stefan Weil
static int pci_i82559c_init(PCIDevice *pci_dev)
1866 9d07d757 Paul Brook
{
1867 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82559C);
1868 9d07d757 Paul Brook
}
1869 9d07d757 Paul Brook
1870 c4c270e2 Stefan Weil
static int pci_i82559er_init(PCIDevice *pci_dev)
1871 663e8e51 ths
{
1872 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82559ER);
1873 663e8e51 ths
}
1874 663e8e51 ths
1875 c4c270e2 Stefan Weil
static int pci_i82562_init(PCIDevice *pci_dev)
1876 663e8e51 ths
{
1877 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82562);
1878 663e8e51 ths
}
1879 663e8e51 ths
1880 0aab0d3a Gerd Hoffmann
static PCIDeviceInfo eepro100_info[] = {
1881 0aab0d3a Gerd Hoffmann
    {
1882 c4c270e2 Stefan Weil
        .qdev.name = "i82550",
1883 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1884 c4c270e2 Stefan Weil
        .init      = pci_i82550_init,
1885 c4c270e2 Stefan Weil
    },{
1886 0aab0d3a Gerd Hoffmann
        .qdev.name = "i82551",
1887 273a2142 Juan Quintela
        .qdev.size = sizeof(EEPRO100State),
1888 0aab0d3a Gerd Hoffmann
        .init      = pci_i82551_init,
1889 e3936fa5 Gerd Hoffmann
        .exit      = pci_nic_uninit,
1890 0aab0d3a Gerd Hoffmann
    },{
1891 c4c270e2 Stefan Weil
        .qdev.name = "i82557a",
1892 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1893 c4c270e2 Stefan Weil
        .init      = pci_i82557a_init,
1894 c4c270e2 Stefan Weil
    },{
1895 0aab0d3a Gerd Hoffmann
        .qdev.name = "i82557b",
1896 273a2142 Juan Quintela
        .qdev.size = sizeof(EEPRO100State),
1897 0aab0d3a Gerd Hoffmann
        .init      = pci_i82557b_init,
1898 e3936fa5 Gerd Hoffmann
        .exit      = pci_nic_uninit,
1899 0aab0d3a Gerd Hoffmann
    },{
1900 c4c270e2 Stefan Weil
        .qdev.name = "i82557c",
1901 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1902 c4c270e2 Stefan Weil
        .init      = pci_i82557c_init,
1903 c4c270e2 Stefan Weil
    },{
1904 c4c270e2 Stefan Weil
        .qdev.name = "i82558a",
1905 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1906 c4c270e2 Stefan Weil
        .init      = pci_i82558a_init,
1907 c4c270e2 Stefan Weil
    },{
1908 c4c270e2 Stefan Weil
        .qdev.name = "i82558b",
1909 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1910 c4c270e2 Stefan Weil
        .init      = pci_i82558b_init,
1911 c4c270e2 Stefan Weil
    },{
1912 c4c270e2 Stefan Weil
        .qdev.name = "i82559a",
1913 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1914 c4c270e2 Stefan Weil
        .init      = pci_i82559a_init,
1915 c4c270e2 Stefan Weil
    },{
1916 c4c270e2 Stefan Weil
        .qdev.name = "i82559b",
1917 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1918 c4c270e2 Stefan Weil
        .init      = pci_i82559b_init,
1919 c4c270e2 Stefan Weil
    },{
1920 c4c270e2 Stefan Weil
        .qdev.name = "i82559c",
1921 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1922 c4c270e2 Stefan Weil
        .init      = pci_i82559c_init,
1923 c4c270e2 Stefan Weil
    },{
1924 0aab0d3a Gerd Hoffmann
        .qdev.name = "i82559er",
1925 273a2142 Juan Quintela
        .qdev.size = sizeof(EEPRO100State),
1926 0aab0d3a Gerd Hoffmann
        .init      = pci_i82559er_init,
1927 e3936fa5 Gerd Hoffmann
        .exit      = pci_nic_uninit,
1928 0aab0d3a Gerd Hoffmann
    },{
1929 c4c270e2 Stefan Weil
        .qdev.name = "i82562",
1930 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1931 c4c270e2 Stefan Weil
        .init      = pci_i82562_init,
1932 c4c270e2 Stefan Weil
    },{
1933 0aab0d3a Gerd Hoffmann
        /* end of list */
1934 0aab0d3a Gerd Hoffmann
    }
1935 0aab0d3a Gerd Hoffmann
};
1936 0aab0d3a Gerd Hoffmann
1937 9d07d757 Paul Brook
static void eepro100_register_devices(void)
1938 663e8e51 ths
{
1939 0aab0d3a Gerd Hoffmann
    pci_qdev_register_many(eepro100_info);
1940 663e8e51 ths
}
1941 663e8e51 ths
1942 9d07d757 Paul Brook
device_init(eepro100_register_devices)