Statistics
| Branch: | Revision:

root / hw / eepro100.c @ e8ee28fb

History | View | Annotate | Download (62.8 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 7f1e9d4e Kevin Wolf
#define missing(text) fprintf(stderr, "eepro100: feature is missing in this emulation: " text "\n")
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
    uint8_t mult[8];            /* multicast mask array */
195 663e8e51 ths
    int mmio_index;
196 663e8e51 ths
    VLANClientState *vc;
197 508ef936 Gerd Hoffmann
    NICConf conf;
198 663e8e51 ths
    uint8_t scb_stat;           /* SCB stat/ack byte */
199 663e8e51 ths
    uint8_t int_stat;           /* PCI interrupt status */
200 3706c43f Stefan Weil
    /* region must not be saved by nic_save. */
201 663e8e51 ths
    uint32_t region[3];         /* PCI region addresses */
202 663e8e51 ths
    uint16_t mdimem[32];
203 c227f099 Anthony Liguori
    eeprom_t *eeprom;
204 663e8e51 ths
    uint32_t device;            /* device variant */
205 663e8e51 ths
    uint32_t pointer;
206 663e8e51 ths
    /* (cu_base + cu_offset) address the next command block in the command block list. */
207 663e8e51 ths
    uint32_t cu_base;           /* CU base address */
208 663e8e51 ths
    uint32_t cu_offset;         /* CU address offset */
209 663e8e51 ths
    /* (ru_base + ru_offset) address the RFD in the Receive Frame Area. */
210 663e8e51 ths
    uint32_t ru_base;           /* RU base address */
211 663e8e51 ths
    uint32_t ru_offset;         /* RU address offset */
212 c227f099 Anthony Liguori
    uint32_t statsaddr;         /* pointer to eepro100_stats_t */
213 4e3db917 Aurelien Jarno
    eepro100_stats_t statistics;        /* statistical counters */
214 663e8e51 ths
#if 0
215 663e8e51 ths
    uint16_t status;
216 663e8e51 ths
#endif
217 663e8e51 ths
218 663e8e51 ths
    /* Configuration bytes. */
219 663e8e51 ths
    uint8_t configuration[22];
220 663e8e51 ths
221 663e8e51 ths
    /* Data in mem is always in the byte order of the controller (le). */
222 663e8e51 ths
    uint8_t mem[PCI_MEM_SIZE];
223 663e8e51 ths
} EEPRO100State;
224 663e8e51 ths
225 663e8e51 ths
/* Default values for MDI (PHY) registers */
226 663e8e51 ths
static const uint16_t eepro100_mdi_default[] = {
227 663e8e51 ths
    /* MDI Registers 0 - 6, 7 */
228 663e8e51 ths
    0x3000, 0x780d, 0x02a8, 0x0154, 0x05e1, 0x0000, 0x0000, 0x0000,
229 663e8e51 ths
    /* MDI Registers 8 - 15 */
230 663e8e51 ths
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
231 663e8e51 ths
    /* MDI Registers 16 - 31 */
232 663e8e51 ths
    0x0003, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
233 663e8e51 ths
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
234 663e8e51 ths
};
235 663e8e51 ths
236 663e8e51 ths
/* Readonly mask for MDI (PHY) registers */
237 663e8e51 ths
static const uint16_t eepro100_mdi_mask[] = {
238 663e8e51 ths
    0x0000, 0xffff, 0xffff, 0xffff, 0xc01f, 0xffff, 0xffff, 0x0000,
239 663e8e51 ths
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
240 663e8e51 ths
    0x0fff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
241 663e8e51 ths
    0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
242 663e8e51 ths
};
243 663e8e51 ths
244 663e8e51 ths
#define POLYNOMIAL 0x04c11db6
245 663e8e51 ths
246 663e8e51 ths
/* From FreeBSD */
247 663e8e51 ths
/* XXX: optimize */
248 663e8e51 ths
static int compute_mcast_idx(const uint8_t * ep)
249 663e8e51 ths
{
250 663e8e51 ths
    uint32_t crc;
251 663e8e51 ths
    int carry, i, j;
252 663e8e51 ths
    uint8_t b;
253 663e8e51 ths
254 663e8e51 ths
    crc = 0xffffffff;
255 663e8e51 ths
    for (i = 0; i < 6; i++) {
256 663e8e51 ths
        b = *ep++;
257 663e8e51 ths
        for (j = 0; j < 8; j++) {
258 663e8e51 ths
            carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
259 663e8e51 ths
            crc <<= 1;
260 663e8e51 ths
            b >>= 1;
261 aac443e6 Stefan Weil
            if (carry) {
262 663e8e51 ths
                crc = ((crc ^ POLYNOMIAL) | carry);
263 aac443e6 Stefan Weil
            }
264 663e8e51 ths
        }
265 663e8e51 ths
    }
266 663e8e51 ths
    return (crc >> 26);
267 663e8e51 ths
}
268 663e8e51 ths
269 663e8e51 ths
#if defined(DEBUG_EEPRO100)
270 663e8e51 ths
static const char *nic_dump(const uint8_t * buf, unsigned size)
271 663e8e51 ths
{
272 663e8e51 ths
    static char dump[3 * 16 + 1];
273 663e8e51 ths
    char *p = &dump[0];
274 aac443e6 Stefan Weil
    if (size > 16) {
275 663e8e51 ths
        size = 16;
276 aac443e6 Stefan Weil
    }
277 663e8e51 ths
    while (size-- > 0) {
278 663e8e51 ths
        p += sprintf(p, " %02x", *buf++);
279 663e8e51 ths
    }
280 663e8e51 ths
    return dump;
281 663e8e51 ths
}
282 663e8e51 ths
#endif                          /* DEBUG_EEPRO100 */
283 663e8e51 ths
284 663e8e51 ths
enum scb_stat_ack {
285 663e8e51 ths
    stat_ack_not_ours = 0x00,
286 663e8e51 ths
    stat_ack_sw_gen = 0x04,
287 663e8e51 ths
    stat_ack_rnr = 0x10,
288 663e8e51 ths
    stat_ack_cu_idle = 0x20,
289 663e8e51 ths
    stat_ack_frame_rx = 0x40,
290 663e8e51 ths
    stat_ack_cu_cmd_done = 0x80,
291 663e8e51 ths
    stat_ack_not_present = 0xFF,
292 663e8e51 ths
    stat_ack_rx = (stat_ack_sw_gen | stat_ack_rnr | stat_ack_frame_rx),
293 663e8e51 ths
    stat_ack_tx = (stat_ack_cu_idle | stat_ack_cu_cmd_done),
294 663e8e51 ths
};
295 663e8e51 ths
296 663e8e51 ths
static void disable_interrupt(EEPRO100State * s)
297 663e8e51 ths
{
298 663e8e51 ths
    if (s->int_stat) {
299 aac443e6 Stefan Weil
        TRACE(INT, logout("interrupt disabled\n"));
300 273a2142 Juan Quintela
        qemu_irq_lower(s->dev.irq[0]);
301 663e8e51 ths
        s->int_stat = 0;
302 663e8e51 ths
    }
303 663e8e51 ths
}
304 663e8e51 ths
305 663e8e51 ths
static void enable_interrupt(EEPRO100State * s)
306 663e8e51 ths
{
307 663e8e51 ths
    if (!s->int_stat) {
308 aac443e6 Stefan Weil
        TRACE(INT, logout("interrupt enabled\n"));
309 273a2142 Juan Quintela
        qemu_irq_raise(s->dev.irq[0]);
310 663e8e51 ths
        s->int_stat = 1;
311 663e8e51 ths
    }
312 663e8e51 ths
}
313 663e8e51 ths
314 663e8e51 ths
static void eepro100_acknowledge(EEPRO100State * s)
315 663e8e51 ths
{
316 663e8e51 ths
    s->scb_stat &= ~s->mem[SCBAck];
317 663e8e51 ths
    s->mem[SCBAck] = s->scb_stat;
318 663e8e51 ths
    if (s->scb_stat == 0) {
319 663e8e51 ths
        disable_interrupt(s);
320 663e8e51 ths
    }
321 663e8e51 ths
}
322 663e8e51 ths
323 663e8e51 ths
static void eepro100_interrupt(EEPRO100State * s, uint8_t stat)
324 663e8e51 ths
{
325 663e8e51 ths
    uint8_t mask = ~s->mem[SCBIntmask];
326 663e8e51 ths
    s->mem[SCBAck] |= stat;
327 663e8e51 ths
    stat = s->scb_stat = s->mem[SCBAck];
328 663e8e51 ths
    stat &= (mask | 0x0f);
329 663e8e51 ths
    //~ stat &= (~s->mem[SCBIntmask] | 0x0xf);
330 663e8e51 ths
    if (stat && (mask & 0x01)) {
331 663e8e51 ths
        /* SCB mask and SCB Bit M do not disable interrupt. */
332 663e8e51 ths
        enable_interrupt(s);
333 663e8e51 ths
    } else if (s->int_stat) {
334 663e8e51 ths
        disable_interrupt(s);
335 663e8e51 ths
    }
336 663e8e51 ths
}
337 663e8e51 ths
338 663e8e51 ths
static void eepro100_cx_interrupt(EEPRO100State * s)
339 663e8e51 ths
{
340 663e8e51 ths
    /* CU completed action command. */
341 663e8e51 ths
    /* Transmit not ok (82557 only, not in emulation). */
342 663e8e51 ths
    eepro100_interrupt(s, 0x80);
343 663e8e51 ths
}
344 663e8e51 ths
345 663e8e51 ths
static void eepro100_cna_interrupt(EEPRO100State * s)
346 663e8e51 ths
{
347 663e8e51 ths
    /* CU left the active state. */
348 663e8e51 ths
    eepro100_interrupt(s, 0x20);
349 663e8e51 ths
}
350 663e8e51 ths
351 663e8e51 ths
static void eepro100_fr_interrupt(EEPRO100State * s)
352 663e8e51 ths
{
353 663e8e51 ths
    /* RU received a complete frame. */
354 663e8e51 ths
    eepro100_interrupt(s, 0x40);
355 663e8e51 ths
}
356 663e8e51 ths
357 663e8e51 ths
#if 0
358 663e8e51 ths
static void eepro100_rnr_interrupt(EEPRO100State * s)
359 663e8e51 ths
{
360 663e8e51 ths
    /* RU is not ready. */
361 663e8e51 ths
    eepro100_interrupt(s, 0x10);
362 663e8e51 ths
}
363 663e8e51 ths
#endif
364 663e8e51 ths
365 663e8e51 ths
static void eepro100_mdi_interrupt(EEPRO100State * s)
366 663e8e51 ths
{
367 663e8e51 ths
    /* MDI completed read or write cycle. */
368 663e8e51 ths
    eepro100_interrupt(s, 0x08);
369 663e8e51 ths
}
370 663e8e51 ths
371 663e8e51 ths
static void eepro100_swi_interrupt(EEPRO100State * s)
372 663e8e51 ths
{
373 663e8e51 ths
    /* Software has requested an interrupt. */
374 663e8e51 ths
    eepro100_interrupt(s, 0x04);
375 663e8e51 ths
}
376 663e8e51 ths
377 663e8e51 ths
#if 0
378 663e8e51 ths
static void eepro100_fcp_interrupt(EEPRO100State * s)
379 663e8e51 ths
{
380 663e8e51 ths
    /* Flow control pause interrupt (82558 and later). */
381 663e8e51 ths
    eepro100_interrupt(s, 0x01);
382 663e8e51 ths
}
383 663e8e51 ths
#endif
384 663e8e51 ths
385 663e8e51 ths
static void pci_reset(EEPRO100State * s)
386 663e8e51 ths
{
387 663e8e51 ths
    uint32_t device = s->device;
388 273a2142 Juan Quintela
    uint8_t *pci_conf = s->dev.config;
389 663e8e51 ths
390 aac443e6 Stefan Weil
    TRACE(OTHER, logout("%p\n", s));
391 663e8e51 ths
392 663e8e51 ths
    /* PCI Vendor ID */
393 deb54399 aliguori
    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
394 d6fd1e66 Stefan Weil
    /* PCI Device ID depends on device and is set below. */
395 663e8e51 ths
    /* PCI Command */
396 663e8e51 ths
    PCI_CONFIG_16(PCI_COMMAND, 0x0000);
397 663e8e51 ths
    /* PCI Status */
398 663e8e51 ths
    PCI_CONFIG_16(PCI_STATUS, 0x2800);
399 663e8e51 ths
    /* PCI Revision ID */
400 663e8e51 ths
    PCI_CONFIG_8(PCI_REVISION_ID, 0x08);
401 663e8e51 ths
    /* PCI Class Code */
402 663e8e51 ths
    PCI_CONFIG_8(0x09, 0x00);
403 173a543b blueswir1
    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
404 663e8e51 ths
    /* PCI Cache Line Size */
405 663e8e51 ths
    /* check cache line size!!! */
406 663e8e51 ths
    //~ PCI_CONFIG_8(0x0c, 0x00);
407 663e8e51 ths
    /* PCI Latency Timer */
408 663e8e51 ths
    PCI_CONFIG_8(0x0d, 0x20);   // latency timer = 32 clocks
409 663e8e51 ths
    /* PCI Header Type */
410 663e8e51 ths
    /* BIST (built-in self test) */
411 663e8e51 ths
#if defined(TARGET_I386)
412 663e8e51 ths
// !!! workaround for buggy bios
413 663e8e51 ths
//~ #define PCI_ADDRESS_SPACE_MEM_PREFETCH 0
414 663e8e51 ths
#endif
415 663e8e51 ths
#if 0
416 663e8e51 ths
    /* PCI Base Address Registers */
417 663e8e51 ths
    /* CSR Memory Mapped Base Address */
418 663e8e51 ths
    PCI_CONFIG_32(PCI_BASE_ADDRESS_0,
419 663e8e51 ths
                  PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_MEM_PREFETCH);
420 663e8e51 ths
    /* CSR I/O Mapped Base Address */
421 663e8e51 ths
    PCI_CONFIG_32(PCI_BASE_ADDRESS_1, PCI_ADDRESS_SPACE_IO);
422 663e8e51 ths
#if 0
423 663e8e51 ths
    /* Flash Memory Mapped Base Address */
424 663e8e51 ths
    PCI_CONFIG_32(PCI_BASE_ADDRESS_2, 0xfffe0000 | PCI_ADDRESS_SPACE_MEM);
425 663e8e51 ths
#endif
426 663e8e51 ths
#endif
427 663e8e51 ths
    /* Expansion ROM Base Address (depends on boot disable!!!) */
428 663e8e51 ths
    PCI_CONFIG_32(0x30, 0x00000000);
429 663e8e51 ths
    /* Capability Pointer */
430 663e8e51 ths
    PCI_CONFIG_8(0x34, 0xdc);
431 aac443e6 Stefan Weil
    /* Interrupt Line */
432 663e8e51 ths
    /* Interrupt Pin */
433 663e8e51 ths
    PCI_CONFIG_8(0x3d, 1);      // interrupt pin 0
434 663e8e51 ths
    /* Minimum Grant */
435 663e8e51 ths
    PCI_CONFIG_8(0x3e, 0x08);
436 663e8e51 ths
    /* Maximum Latency */
437 663e8e51 ths
    PCI_CONFIG_8(0x3f, 0x18);
438 663e8e51 ths
    /* Power Management Capabilities / Next Item Pointer / Capability ID */
439 663e8e51 ths
    PCI_CONFIG_32(0xdc, 0x7e210001);
440 663e8e51 ths
441 663e8e51 ths
    switch (device) {
442 663e8e51 ths
    case i82551:
443 d6fd1e66 Stefan Weil
        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82551IT);
444 663e8e51 ths
        PCI_CONFIG_8(PCI_REVISION_ID, 0x0f);
445 663e8e51 ths
        break;
446 663e8e51 ths
    case i82557B:
447 d6fd1e66 Stefan Weil
        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
448 663e8e51 ths
        PCI_CONFIG_8(PCI_REVISION_ID, 0x02);
449 663e8e51 ths
        break;
450 663e8e51 ths
    case i82557C:
451 d6fd1e66 Stefan Weil
        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
452 663e8e51 ths
        PCI_CONFIG_8(PCI_REVISION_ID, 0x03);
453 663e8e51 ths
        break;
454 663e8e51 ths
    case i82558B:
455 d6fd1e66 Stefan Weil
        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
456 663e8e51 ths
        PCI_CONFIG_16(PCI_STATUS, 0x2810);
457 663e8e51 ths
        PCI_CONFIG_8(PCI_REVISION_ID, 0x05);
458 663e8e51 ths
        break;
459 663e8e51 ths
    case i82559C:
460 d6fd1e66 Stefan Weil
        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
461 663e8e51 ths
        PCI_CONFIG_16(PCI_STATUS, 0x2810);
462 663e8e51 ths
        //~ PCI_CONFIG_8(PCI_REVISION_ID, 0x08);
463 663e8e51 ths
        break;
464 663e8e51 ths
    case i82559ER:
465 d6fd1e66 Stefan Weil
        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82551IT);
466 663e8e51 ths
        PCI_CONFIG_16(PCI_STATUS, 0x2810);
467 663e8e51 ths
        PCI_CONFIG_8(PCI_REVISION_ID, 0x09);
468 663e8e51 ths
        break;
469 663e8e51 ths
    //~ PCI_CONFIG_16(PCI_DEVICE_ID, 0x1029);
470 663e8e51 ths
    //~ PCI_CONFIG_16(PCI_DEVICE_ID, 0x1030);       /* 82559 InBusiness 10/100 */
471 663e8e51 ths
    default:
472 663e8e51 ths
        logout("Device %X is undefined!\n", device);
473 663e8e51 ths
    }
474 663e8e51 ths
475 663e8e51 ths
    if (device == i82557C || device == i82558B || device == i82559C) {
476 663e8e51 ths
        logout("Get device id and revision from EEPROM!!!\n");
477 663e8e51 ths
    }
478 663e8e51 ths
}
479 663e8e51 ths
480 663e8e51 ths
static void nic_selective_reset(EEPRO100State * s)
481 663e8e51 ths
{
482 663e8e51 ths
    size_t i;
483 663e8e51 ths
    uint16_t *eeprom_contents = eeprom93xx_data(s->eeprom);
484 663e8e51 ths
    //~ eeprom93xx_reset(s->eeprom);
485 508ef936 Gerd Hoffmann
    memcpy(eeprom_contents, s->conf.macaddr.a, 6);
486 663e8e51 ths
    eeprom_contents[0xa] = 0x4000;
487 f4e94dfe =?UTF-8?q?Reimar=20D=C3=B6ffinger?=
    if (s->device == i82557B || s->device == i82557C)
488 f4e94dfe =?UTF-8?q?Reimar=20D=C3=B6ffinger?=
        eeprom_contents[5] = 0x0100;
489 663e8e51 ths
    uint16_t sum = 0;
490 663e8e51 ths
    for (i = 0; i < EEPROM_SIZE - 1; i++) {
491 663e8e51 ths
        sum += eeprom_contents[i];
492 663e8e51 ths
    }
493 663e8e51 ths
    eeprom_contents[EEPROM_SIZE - 1] = 0xbaba - sum;
494 aac443e6 Stefan Weil
    TRACE(EEPROM, logout("checksum=0x%04x\n", eeprom_contents[EEPROM_SIZE - 1]));
495 663e8e51 ths
496 663e8e51 ths
    memset(s->mem, 0, sizeof(s->mem));
497 663e8e51 ths
    uint32_t val = BIT(21);
498 663e8e51 ths
    memcpy(&s->mem[SCBCtrlMDI], &val, sizeof(val));
499 663e8e51 ths
500 663e8e51 ths
    assert(sizeof(s->mdimem) == sizeof(eepro100_mdi_default));
501 663e8e51 ths
    memcpy(&s->mdimem[0], &eepro100_mdi_default[0], sizeof(s->mdimem));
502 663e8e51 ths
}
503 663e8e51 ths
504 663e8e51 ths
static void nic_reset(void *opaque)
505 663e8e51 ths
{
506 769cf7a5 Juan Quintela
    EEPRO100State *s = opaque;
507 aac443e6 Stefan Weil
    TRACE(OTHER, logout("%p\n", s));
508 663e8e51 ths
    nic_selective_reset(s);
509 663e8e51 ths
}
510 663e8e51 ths
511 663e8e51 ths
#if defined(DEBUG_EEPRO100)
512 6a0b9cc9 Reimar Dรถffinger
static const char * const reg[PCI_IO_SIZE / 4] = {
513 663e8e51 ths
    "Command/Status",
514 663e8e51 ths
    "General Pointer",
515 663e8e51 ths
    "Port",
516 663e8e51 ths
    "EEPROM/Flash Control",
517 663e8e51 ths
    "MDI Control",
518 663e8e51 ths
    "Receive DMA Byte Count",
519 aac443e6 Stefan Weil
    "Flow control",
520 663e8e51 ths
    "General Status/Control"
521 663e8e51 ths
};
522 663e8e51 ths
523 663e8e51 ths
static char *regname(uint32_t addr)
524 663e8e51 ths
{
525 663e8e51 ths
    static char buf[16];
526 663e8e51 ths
    if (addr < PCI_IO_SIZE) {
527 663e8e51 ths
        const char *r = reg[addr / 4];
528 663e8e51 ths
        if (r != 0) {
529 41cbc23c Stefan Weil
            snprintf(buf, sizeof(buf), "%s+%u", r, addr % 4);
530 663e8e51 ths
        } else {
531 41cbc23c Stefan Weil
            snprintf(buf, sizeof(buf), "0x%02x", addr);
532 663e8e51 ths
        }
533 663e8e51 ths
    } else {
534 41cbc23c Stefan Weil
        snprintf(buf, sizeof(buf), "??? 0x%08x", addr);
535 663e8e51 ths
    }
536 663e8e51 ths
    return buf;
537 663e8e51 ths
}
538 663e8e51 ths
#endif                          /* DEBUG_EEPRO100 */
539 663e8e51 ths
540 663e8e51 ths
#if 0
541 663e8e51 ths
static uint16_t eepro100_read_status(EEPRO100State * s)
542 663e8e51 ths
{
543 663e8e51 ths
    uint16_t val = s->status;
544 aac443e6 Stefan Weil
    TRACE(OTHER, logout("val=0x%04x\n", val));
545 663e8e51 ths
    return val;
546 663e8e51 ths
}
547 663e8e51 ths

548 663e8e51 ths
static void eepro100_write_status(EEPRO100State * s, uint16_t val)
549 663e8e51 ths
{
550 aac443e6 Stefan Weil
    TRACE(OTHER, logout("val=0x%04x\n", val));
551 663e8e51 ths
    s->status = val;
552 663e8e51 ths
}
553 663e8e51 ths
#endif
554 663e8e51 ths
555 663e8e51 ths
/*****************************************************************************
556 663e8e51 ths
 *
557 663e8e51 ths
 * Command emulation.
558 663e8e51 ths
 *
559 663e8e51 ths
 ****************************************************************************/
560 663e8e51 ths
561 663e8e51 ths
#if 0
562 663e8e51 ths
static uint16_t eepro100_read_command(EEPRO100State * s)
563 663e8e51 ths
{
564 663e8e51 ths
    uint16_t val = 0xffff;
565 aac443e6 Stefan Weil
    //~ TRACE(OTHER, logout("val=0x%04x\n", val));
566 663e8e51 ths
    return val;
567 663e8e51 ths
}
568 663e8e51 ths
#endif
569 663e8e51 ths
570 0859df68 Naphtali Sprei
static bool device_supports_eTxCB(EEPRO100State * s)
571 0859df68 Naphtali Sprei
{
572 0859df68 Naphtali Sprei
    return (s->device != i82557B && s->device != i82557C);
573 0859df68 Naphtali Sprei
}
574 0859df68 Naphtali Sprei
575 663e8e51 ths
/* Commands that can be put in a command list entry. */
576 663e8e51 ths
enum commands {
577 663e8e51 ths
    CmdNOp = 0,
578 663e8e51 ths
    CmdIASetup = 1,
579 663e8e51 ths
    CmdConfigure = 2,
580 663e8e51 ths
    CmdMulticastList = 3,
581 663e8e51 ths
    CmdTx = 4,
582 663e8e51 ths
    CmdTDR = 5,                 /* load microcode */
583 663e8e51 ths
    CmdDump = 6,
584 663e8e51 ths
    CmdDiagnose = 7,
585 663e8e51 ths
586 663e8e51 ths
    /* And some extra flags: */
587 663e8e51 ths
    CmdSuspend = 0x4000,        /* Suspend after completion. */
588 663e8e51 ths
    CmdIntr = 0x2000,           /* Interrupt after completion. */
589 663e8e51 ths
    CmdTxFlex = 0x0008,         /* Use "Flexible mode" for CmdTx command. */
590 663e8e51 ths
};
591 663e8e51 ths
592 c227f099 Anthony Liguori
static cu_state_t get_cu_state(EEPRO100State * s)
593 663e8e51 ths
{
594 663e8e51 ths
    return ((s->mem[SCBStatus] >> 6) & 0x03);
595 663e8e51 ths
}
596 663e8e51 ths
597 c227f099 Anthony Liguori
static void set_cu_state(EEPRO100State * s, cu_state_t state)
598 663e8e51 ths
{
599 663e8e51 ths
    s->mem[SCBStatus] = (s->mem[SCBStatus] & 0x3f) + (state << 6);
600 663e8e51 ths
}
601 663e8e51 ths
602 c227f099 Anthony Liguori
static ru_state_t get_ru_state(EEPRO100State * s)
603 663e8e51 ths
{
604 663e8e51 ths
    return ((s->mem[SCBStatus] >> 2) & 0x0f);
605 663e8e51 ths
}
606 663e8e51 ths
607 c227f099 Anthony Liguori
static void set_ru_state(EEPRO100State * s, ru_state_t state)
608 663e8e51 ths
{
609 663e8e51 ths
    s->mem[SCBStatus] = (s->mem[SCBStatus] & 0xc3) + (state << 2);
610 663e8e51 ths
}
611 663e8e51 ths
612 663e8e51 ths
static void dump_statistics(EEPRO100State * s)
613 663e8e51 ths
{
614 663e8e51 ths
    /* Dump statistical data. Most data is never changed by the emulation
615 663e8e51 ths
     * and always 0, so we first just copy the whole block and then those
616 663e8e51 ths
     * values which really matter.
617 663e8e51 ths
     * Number of data should check configuration!!!
618 663e8e51 ths
     */
619 663e8e51 ths
    cpu_physical_memory_write(s->statsaddr, (uint8_t *) & s->statistics, 64);
620 663e8e51 ths
    stl_phys(s->statsaddr + 0, s->statistics.tx_good_frames);
621 663e8e51 ths
    stl_phys(s->statsaddr + 36, s->statistics.rx_good_frames);
622 663e8e51 ths
    stl_phys(s->statsaddr + 48, s->statistics.rx_resource_errors);
623 663e8e51 ths
    stl_phys(s->statsaddr + 60, s->statistics.rx_short_frame_errors);
624 663e8e51 ths
    //~ stw_phys(s->statsaddr + 76, s->statistics.xmt_tco_frames);
625 663e8e51 ths
    //~ stw_phys(s->statsaddr + 78, s->statistics.rcv_tco_frames);
626 663e8e51 ths
    //~ missing("CU dump statistical counters");
627 663e8e51 ths
}
628 663e8e51 ths
629 5fa9a0ae Stefan Weil
static void action_command(EEPRO100State *s)
630 663e8e51 ths
{
631 5fa9a0ae Stefan Weil
    for (;;) {
632 5fa9a0ae Stefan Weil
        uint32_t cb_address = s->cu_base + s->cu_offset;
633 5fa9a0ae Stefan Weil
        eepro100_tx_t tx;
634 663e8e51 ths
        cpu_physical_memory_read(cb_address, (uint8_t *) & tx, sizeof(tx));
635 663e8e51 ths
        uint16_t status = le16_to_cpu(tx.status);
636 663e8e51 ths
        uint16_t command = le16_to_cpu(tx.command);
637 663e8e51 ths
        logout
638 663e8e51 ths
            ("val=0x%02x (cu start), status=0x%04x, command=0x%04x, link=0x%08x\n",
639 663e8e51 ths
             val, status, command, tx.link);
640 663e8e51 ths
        bool bit_el = ((command & 0x8000) != 0);
641 663e8e51 ths
        bool bit_s = ((command & 0x4000) != 0);
642 663e8e51 ths
        bool bit_i = ((command & 0x2000) != 0);
643 663e8e51 ths
        bool bit_nc = ((command & 0x0010) != 0);
644 7f1e9d4e Kevin Wolf
        bool success = true;
645 663e8e51 ths
        //~ bool bit_sf = ((command & 0x0008) != 0);
646 663e8e51 ths
        uint16_t cmd = command & 0x0007;
647 663e8e51 ths
        s->cu_offset = le32_to_cpu(tx.link);
648 663e8e51 ths
        switch (cmd) {
649 663e8e51 ths
        case CmdNOp:
650 663e8e51 ths
            /* Do nothing. */
651 663e8e51 ths
            break;
652 663e8e51 ths
        case CmdIASetup:
653 508ef936 Gerd Hoffmann
            cpu_physical_memory_read(cb_address + 8, &s->conf.macaddr.a[0], 6);
654 aac443e6 Stefan Weil
            TRACE(OTHER, logout("macaddr: %s\n", nic_dump(&s->macaddr[0], 6)));
655 663e8e51 ths
            break;
656 663e8e51 ths
        case CmdConfigure:
657 663e8e51 ths
            cpu_physical_memory_read(cb_address + 8, &s->configuration[0],
658 663e8e51 ths
                                     sizeof(s->configuration));
659 aac443e6 Stefan Weil
            TRACE(OTHER, logout("configuration: %s\n", nic_dump(&s->configuration[0], 16)));
660 663e8e51 ths
            break;
661 663e8e51 ths
        case CmdMulticastList:
662 663e8e51 ths
            //~ missing("multicast list");
663 663e8e51 ths
            break;
664 663e8e51 ths
        case CmdTx:
665 663e8e51 ths
            (void)0;
666 663e8e51 ths
            uint32_t tbd_array = le32_to_cpu(tx.tx_desc_addr);
667 663e8e51 ths
            uint16_t tcb_bytes = (le16_to_cpu(tx.tcb_bytes) & 0x3fff);
668 aac443e6 Stefan Weil
            TRACE(RXTX, logout
669 663e8e51 ths
                ("transmit, TBD array address 0x%08x, TCB byte count 0x%04x, TBD count %u\n",
670 aac443e6 Stefan Weil
                 tbd_array, tcb_bytes, tx.tbd_count));
671 7f1e9d4e Kevin Wolf
672 7f1e9d4e Kevin Wolf
            if (bit_nc) {
673 7f1e9d4e Kevin Wolf
                missing("CmdTx: NC = 0");
674 7f1e9d4e Kevin Wolf
                success = false;
675 7f1e9d4e Kevin Wolf
                break;
676 7f1e9d4e Kevin Wolf
            }
677 663e8e51 ths
            //~ assert(!bit_sf);
678 7f1e9d4e Kevin Wolf
            if (tcb_bytes > 2600) {
679 7f1e9d4e Kevin Wolf
                logout("TCB byte count too large, using 2600\n");
680 7f1e9d4e Kevin Wolf
                tcb_bytes = 2600;
681 7f1e9d4e Kevin Wolf
            }
682 663e8e51 ths
            /* Next assertion fails for local configuration. */
683 663e8e51 ths
            //~ assert((tcb_bytes > 0) || (tbd_array != 0xffffffff));
684 663e8e51 ths
            if (!((tcb_bytes > 0) || (tbd_array != 0xffffffff))) {
685 663e8e51 ths
                logout
686 663e8e51 ths
                    ("illegal values of TBD array address and TCB byte count!\n");
687 663e8e51 ths
            }
688 24e6f355 Reimar Dรถffinger
            // sends larger than MAX_ETH_FRAME_SIZE are allowed, up to 2600 bytes
689 24e6f355 Reimar Dรถffinger
            uint8_t buf[2600];
690 663e8e51 ths
            uint16_t size = 0;
691 663e8e51 ths
            uint32_t tbd_address = cb_address + 0x10;
692 663e8e51 ths
            assert(tcb_bytes <= sizeof(buf));
693 663e8e51 ths
            while (size < tcb_bytes) {
694 663e8e51 ths
                uint32_t tx_buffer_address = ldl_phys(tbd_address);
695 663e8e51 ths
                uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
696 663e8e51 ths
                //~ uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
697 663e8e51 ths
                tbd_address += 8;
698 aac443e6 Stefan Weil
                TRACE(RXTX, logout
699 663e8e51 ths
                    ("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n",
700 aac443e6 Stefan Weil
                     tx_buffer_address, tx_buffer_size));
701 24e6f355 Reimar Dรถffinger
                tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
702 663e8e51 ths
                cpu_physical_memory_read(tx_buffer_address, &buf[size],
703 663e8e51 ths
                                         tx_buffer_size);
704 663e8e51 ths
                size += tx_buffer_size;
705 663e8e51 ths
            }
706 663e8e51 ths
            if (tbd_array == 0xffffffff) {
707 663e8e51 ths
                /* Simplified mode. Was already handled by code above. */
708 663e8e51 ths
            } else {
709 663e8e51 ths
                /* Flexible mode. */
710 663e8e51 ths
                uint8_t tbd_count = 0;
711 0859df68 Naphtali Sprei
                if (device_supports_eTxCB(s) && !(s->configuration[6] & BIT(4))) {
712 3f9cb1c1 Naphtali Sprei
                    /* Extended Flexible TCB. */
713 663e8e51 ths
                    for (; tbd_count < 2; tbd_count++) {
714 663e8e51 ths
                        uint32_t tx_buffer_address = ldl_phys(tbd_address);
715 663e8e51 ths
                        uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
716 663e8e51 ths
                        uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
717 663e8e51 ths
                        tbd_address += 8;
718 aac443e6 Stefan Weil
                        TRACE(RXTX, logout
719 3f9cb1c1 Naphtali Sprei
                            ("TBD (extended flexible mode): buffer address 0x%08x, size 0x%04x\n",
720 aac443e6 Stefan Weil
                             tx_buffer_address, tx_buffer_size));
721 24e6f355 Reimar Dรถffinger
                        tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
722 663e8e51 ths
                        cpu_physical_memory_read(tx_buffer_address, &buf[size],
723 663e8e51 ths
                                                 tx_buffer_size);
724 663e8e51 ths
                        size += tx_buffer_size;
725 663e8e51 ths
                        if (tx_buffer_el & 1) {
726 663e8e51 ths
                            break;
727 663e8e51 ths
                        }
728 663e8e51 ths
                    }
729 663e8e51 ths
                }
730 663e8e51 ths
                tbd_address = tbd_array;
731 663e8e51 ths
                for (; tbd_count < tx.tbd_count; tbd_count++) {
732 663e8e51 ths
                    uint32_t tx_buffer_address = ldl_phys(tbd_address);
733 663e8e51 ths
                    uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
734 663e8e51 ths
                    uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
735 663e8e51 ths
                    tbd_address += 8;
736 aac443e6 Stefan Weil
                    TRACE(RXTX, logout
737 663e8e51 ths
                        ("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n",
738 aac443e6 Stefan Weil
                         tx_buffer_address, tx_buffer_size));
739 24e6f355 Reimar Dรถffinger
                    tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
740 663e8e51 ths
                    cpu_physical_memory_read(tx_buffer_address, &buf[size],
741 663e8e51 ths
                                             tx_buffer_size);
742 663e8e51 ths
                    size += tx_buffer_size;
743 663e8e51 ths
                    if (tx_buffer_el & 1) {
744 663e8e51 ths
                        break;
745 663e8e51 ths
                    }
746 663e8e51 ths
                }
747 663e8e51 ths
            }
748 aac443e6 Stefan Weil
            TRACE(RXTX, logout("%p sending frame, len=%d,%s\n", s, size, nic_dump(buf, size)));
749 663e8e51 ths
            qemu_send_packet(s->vc, buf, size);
750 663e8e51 ths
            s->statistics.tx_good_frames++;
751 663e8e51 ths
            /* Transmit with bad status would raise an CX/TNO interrupt.
752 663e8e51 ths
             * (82557 only). Emulation never has bad status. */
753 663e8e51 ths
            //~ eepro100_cx_interrupt(s);
754 663e8e51 ths
            break;
755 663e8e51 ths
        case CmdTDR:
756 aac443e6 Stefan Weil
            TRACE(OTHER, logout("load microcode\n"));
757 663e8e51 ths
            /* Starting with offset 8, the command contains
758 663e8e51 ths
             * 64 dwords microcode which we just ignore here. */
759 663e8e51 ths
            break;
760 663e8e51 ths
        default:
761 663e8e51 ths
            missing("undefined command");
762 7f1e9d4e Kevin Wolf
            success = false;
763 7f1e9d4e Kevin Wolf
            break;
764 663e8e51 ths
        }
765 7f1e9d4e Kevin Wolf
        /* Write new status. */
766 7f1e9d4e Kevin Wolf
        stw_phys(cb_address, status | 0x8000 | (success ? 0x2000 : 0));
767 663e8e51 ths
        if (bit_i) {
768 663e8e51 ths
            /* CU completed action. */
769 663e8e51 ths
            eepro100_cx_interrupt(s);
770 663e8e51 ths
        }
771 663e8e51 ths
        if (bit_el) {
772 aac443e6 Stefan Weil
            /* CU becomes idle. Terminate command loop. */
773 663e8e51 ths
            set_cu_state(s, cu_idle);
774 663e8e51 ths
            eepro100_cna_interrupt(s);
775 5fa9a0ae Stefan Weil
            break;
776 663e8e51 ths
        } else if (bit_s) {
777 5fa9a0ae Stefan Weil
            /* CU becomes suspended. Terminate command loop. */
778 663e8e51 ths
            set_cu_state(s, cu_suspended);
779 663e8e51 ths
            eepro100_cna_interrupt(s);
780 5fa9a0ae Stefan Weil
            break;
781 663e8e51 ths
        } else {
782 663e8e51 ths
            /* More entries in list. */
783 aac443e6 Stefan Weil
            TRACE(OTHER, logout("CU list with at least one more entry\n"));
784 663e8e51 ths
        }
785 5fa9a0ae Stefan Weil
    }
786 5fa9a0ae Stefan Weil
    TRACE(OTHER, logout("CU list empty\n"));
787 5fa9a0ae Stefan Weil
    /* List is empty. Now CU is idle or suspended. */
788 5fa9a0ae Stefan Weil
}
789 5fa9a0ae Stefan Weil
790 5fa9a0ae Stefan Weil
static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
791 5fa9a0ae Stefan Weil
{
792 5fa9a0ae Stefan Weil
    switch (val) {
793 5fa9a0ae Stefan Weil
    case CU_NOP:
794 5fa9a0ae Stefan Weil
        /* No operation. */
795 5fa9a0ae Stefan Weil
        break;
796 5fa9a0ae Stefan Weil
    case CU_START:
797 5fa9a0ae Stefan Weil
        if (get_cu_state(s) != cu_idle) {
798 5fa9a0ae Stefan Weil
            /* Intel documentation says that CU must be idle for the CU
799 5fa9a0ae Stefan Weil
             * start command. Intel driver for Linux also starts the CU
800 5fa9a0ae Stefan Weil
             * from suspended state. */
801 5fa9a0ae Stefan Weil
            logout("CU state is %u, should be %u\n", get_cu_state(s), cu_idle);
802 5fa9a0ae Stefan Weil
            //~ assert(!"wrong CU state");
803 5fa9a0ae Stefan Weil
        }
804 5fa9a0ae Stefan Weil
        set_cu_state(s, cu_active);
805 5fa9a0ae Stefan Weil
        s->cu_offset = s->pointer;
806 5fa9a0ae Stefan Weil
        action_command(s);
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 5fa9a0ae Stefan Weil
            action_command(s);
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 dbbaaff6 =?UTF-8?q?Reimar=20D=C3=B6ffinger?=
    case SCBCmd:
1203 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
1204 663e8e51 ths
        break;
1205 663e8e51 ths
    case SCBeeprom:
1206 663e8e51 ths
        val = eepro100_read_eeprom(s);
1207 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
1208 663e8e51 ths
        break;
1209 663e8e51 ths
    default:
1210 663e8e51 ths
        logout("addr=%s val=0x%04x\n", regname(addr), val);
1211 663e8e51 ths
        missing("unknown word read");
1212 663e8e51 ths
    }
1213 663e8e51 ths
    return val;
1214 663e8e51 ths
}
1215 663e8e51 ths
1216 663e8e51 ths
static uint32_t eepro100_read4(EEPRO100State * s, uint32_t addr)
1217 663e8e51 ths
{
1218 663e8e51 ths
    uint32_t val;
1219 663e8e51 ths
    if (addr <= sizeof(s->mem) - sizeof(val)) {
1220 663e8e51 ths
        memcpy(&val, &s->mem[addr], sizeof(val));
1221 663e8e51 ths
    }
1222 663e8e51 ths
1223 663e8e51 ths
    switch (addr) {
1224 663e8e51 ths
    case SCBStatus:
1225 663e8e51 ths
        //~ val = eepro100_read_status(s);
1226 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
1227 663e8e51 ths
        break;
1228 663e8e51 ths
    case SCBPointer:
1229 663e8e51 ths
        //~ val = eepro100_read_pointer(s);
1230 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
1231 663e8e51 ths
        break;
1232 663e8e51 ths
    case SCBPort:
1233 663e8e51 ths
        val = eepro100_read_port(s);
1234 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
1235 663e8e51 ths
        break;
1236 663e8e51 ths
    case SCBCtrlMDI:
1237 663e8e51 ths
        val = eepro100_read_mdi(s);
1238 663e8e51 ths
        break;
1239 663e8e51 ths
    default:
1240 663e8e51 ths
        logout("addr=%s val=0x%08x\n", regname(addr), val);
1241 663e8e51 ths
        missing("unknown longword read");
1242 663e8e51 ths
    }
1243 663e8e51 ths
    return val;
1244 663e8e51 ths
}
1245 663e8e51 ths
1246 663e8e51 ths
static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val)
1247 663e8e51 ths
{
1248 663e8e51 ths
    if (addr <= sizeof(s->mem) - sizeof(val)) {
1249 663e8e51 ths
        memcpy(&s->mem[addr], &val, sizeof(val));
1250 663e8e51 ths
    }
1251 663e8e51 ths
1252 aac443e6 Stefan Weil
    TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
1253 663e8e51 ths
1254 663e8e51 ths
    switch (addr) {
1255 663e8e51 ths
    case SCBStatus:
1256 663e8e51 ths
        //~ eepro100_write_status(s, val);
1257 663e8e51 ths
        break;
1258 663e8e51 ths
    case SCBAck:
1259 663e8e51 ths
        eepro100_acknowledge(s);
1260 663e8e51 ths
        break;
1261 663e8e51 ths
    case SCBCmd:
1262 663e8e51 ths
        eepro100_write_command(s, val);
1263 663e8e51 ths
        break;
1264 663e8e51 ths
    case SCBIntmask:
1265 663e8e51 ths
        if (val & BIT(1)) {
1266 663e8e51 ths
            eepro100_swi_interrupt(s);
1267 663e8e51 ths
        }
1268 663e8e51 ths
        eepro100_interrupt(s, 0);
1269 663e8e51 ths
        break;
1270 663e8e51 ths
    case SCBPort + 3:
1271 aac443e6 Stefan Weil
    case SCBFlow:       /* does not exist on 82557 */
1272 3257d2b6 ths
    case SCBFlow + 1:
1273 3257d2b6 ths
    case SCBFlow + 2:
1274 3257d2b6 ths
    case SCBFlow + 3:
1275 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
1276 663e8e51 ths
        break;
1277 663e8e51 ths
    case SCBeeprom:
1278 663e8e51 ths
        eepro100_write_eeprom(s->eeprom, val);
1279 663e8e51 ths
        break;
1280 663e8e51 ths
    default:
1281 663e8e51 ths
        logout("addr=%s val=0x%02x\n", regname(addr), val);
1282 663e8e51 ths
        missing("unknown byte write");
1283 663e8e51 ths
    }
1284 663e8e51 ths
}
1285 663e8e51 ths
1286 663e8e51 ths
static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val)
1287 663e8e51 ths
{
1288 663e8e51 ths
    if (addr <= sizeof(s->mem) - sizeof(val)) {
1289 663e8e51 ths
        memcpy(&s->mem[addr], &val, sizeof(val));
1290 663e8e51 ths
    }
1291 663e8e51 ths
1292 aac443e6 Stefan Weil
    TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
1293 663e8e51 ths
1294 663e8e51 ths
    switch (addr) {
1295 663e8e51 ths
    case SCBStatus:
1296 663e8e51 ths
        //~ eepro100_write_status(s, val);
1297 663e8e51 ths
        eepro100_acknowledge(s);
1298 663e8e51 ths
        break;
1299 663e8e51 ths
    case SCBCmd:
1300 663e8e51 ths
        eepro100_write_command(s, val);
1301 663e8e51 ths
        eepro100_write1(s, SCBIntmask, val >> 8);
1302 663e8e51 ths
        break;
1303 663e8e51 ths
    case SCBeeprom:
1304 663e8e51 ths
        eepro100_write_eeprom(s->eeprom, val);
1305 663e8e51 ths
        break;
1306 663e8e51 ths
    default:
1307 663e8e51 ths
        logout("addr=%s val=0x%04x\n", regname(addr), val);
1308 663e8e51 ths
        missing("unknown word write");
1309 663e8e51 ths
    }
1310 663e8e51 ths
}
1311 663e8e51 ths
1312 663e8e51 ths
static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val)
1313 663e8e51 ths
{
1314 663e8e51 ths
    if (addr <= sizeof(s->mem) - sizeof(val)) {
1315 663e8e51 ths
        memcpy(&s->mem[addr], &val, sizeof(val));
1316 663e8e51 ths
    }
1317 663e8e51 ths
1318 663e8e51 ths
    switch (addr) {
1319 663e8e51 ths
    case SCBPointer:
1320 663e8e51 ths
        eepro100_write_pointer(s, val);
1321 663e8e51 ths
        break;
1322 663e8e51 ths
    case SCBPort:
1323 aac443e6 Stefan Weil
        TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
1324 663e8e51 ths
        eepro100_write_port(s, val);
1325 663e8e51 ths
        break;
1326 663e8e51 ths
    case SCBCtrlMDI:
1327 663e8e51 ths
        eepro100_write_mdi(s, val);
1328 663e8e51 ths
        break;
1329 663e8e51 ths
    default:
1330 663e8e51 ths
        logout("addr=%s val=0x%08x\n", regname(addr), val);
1331 663e8e51 ths
        missing("unknown longword write");
1332 663e8e51 ths
    }
1333 663e8e51 ths
}
1334 663e8e51 ths
1335 aac443e6 Stefan Weil
/*****************************************************************************
1336 aac443e6 Stefan Weil
 *
1337 aac443e6 Stefan Weil
 * Port mapped I/O.
1338 aac443e6 Stefan Weil
 *
1339 aac443e6 Stefan Weil
 ****************************************************************************/
1340 aac443e6 Stefan Weil
1341 663e8e51 ths
static uint32_t ioport_read1(void *opaque, uint32_t addr)
1342 663e8e51 ths
{
1343 663e8e51 ths
    EEPRO100State *s = opaque;
1344 663e8e51 ths
    //~ logout("addr=%s\n", regname(addr));
1345 663e8e51 ths
    return eepro100_read1(s, addr - s->region[1]);
1346 663e8e51 ths
}
1347 663e8e51 ths
1348 663e8e51 ths
static uint32_t ioport_read2(void *opaque, uint32_t addr)
1349 663e8e51 ths
{
1350 663e8e51 ths
    EEPRO100State *s = opaque;
1351 663e8e51 ths
    return eepro100_read2(s, addr - s->region[1]);
1352 663e8e51 ths
}
1353 663e8e51 ths
1354 663e8e51 ths
static uint32_t ioport_read4(void *opaque, uint32_t addr)
1355 663e8e51 ths
{
1356 663e8e51 ths
    EEPRO100State *s = opaque;
1357 663e8e51 ths
    return eepro100_read4(s, addr - s->region[1]);
1358 663e8e51 ths
}
1359 663e8e51 ths
1360 663e8e51 ths
static void ioport_write1(void *opaque, uint32_t addr, uint32_t val)
1361 663e8e51 ths
{
1362 663e8e51 ths
    EEPRO100State *s = opaque;
1363 663e8e51 ths
    //~ logout("addr=%s val=0x%02x\n", regname(addr), val);
1364 663e8e51 ths
    eepro100_write1(s, addr - s->region[1], val);
1365 663e8e51 ths
}
1366 663e8e51 ths
1367 663e8e51 ths
static void ioport_write2(void *opaque, uint32_t addr, uint32_t val)
1368 663e8e51 ths
{
1369 663e8e51 ths
    EEPRO100State *s = opaque;
1370 663e8e51 ths
    eepro100_write2(s, addr - s->region[1], val);
1371 663e8e51 ths
}
1372 663e8e51 ths
1373 663e8e51 ths
static void ioport_write4(void *opaque, uint32_t addr, uint32_t val)
1374 663e8e51 ths
{
1375 663e8e51 ths
    EEPRO100State *s = opaque;
1376 663e8e51 ths
    eepro100_write4(s, addr - s->region[1], val);
1377 663e8e51 ths
}
1378 663e8e51 ths
1379 663e8e51 ths
/***********************************************************/
1380 663e8e51 ths
/* PCI EEPRO100 definitions */
1381 663e8e51 ths
1382 663e8e51 ths
static void pci_map(PCIDevice * pci_dev, int region_num,
1383 663e8e51 ths
                    uint32_t addr, uint32_t size, int type)
1384 663e8e51 ths
{
1385 273a2142 Juan Quintela
    EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
1386 663e8e51 ths
1387 aac443e6 Stefan Weil
    TRACE(OTHER, logout("region %d, addr=0x%08x, size=0x%08x, type=%d\n",
1388 aac443e6 Stefan Weil
          region_num, addr, size, type));
1389 663e8e51 ths
1390 663e8e51 ths
    assert(region_num == 1);
1391 663e8e51 ths
    register_ioport_write(addr, size, 1, ioport_write1, s);
1392 663e8e51 ths
    register_ioport_read(addr, size, 1, ioport_read1, s);
1393 663e8e51 ths
    register_ioport_write(addr, size, 2, ioport_write2, s);
1394 663e8e51 ths
    register_ioport_read(addr, size, 2, ioport_read2, s);
1395 663e8e51 ths
    register_ioport_write(addr, size, 4, ioport_write4, s);
1396 663e8e51 ths
    register_ioport_read(addr, size, 4, ioport_read4, s);
1397 663e8e51 ths
1398 663e8e51 ths
    s->region[region_num] = addr;
1399 663e8e51 ths
}
1400 663e8e51 ths
1401 aac443e6 Stefan Weil
/*****************************************************************************
1402 aac443e6 Stefan Weil
 *
1403 aac443e6 Stefan Weil
 * Memory mapped I/O.
1404 aac443e6 Stefan Weil
 *
1405 aac443e6 Stefan Weil
 ****************************************************************************/
1406 aac443e6 Stefan Weil
1407 c227f099 Anthony Liguori
static void pci_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
1408 663e8e51 ths
{
1409 663e8e51 ths
    EEPRO100State *s = opaque;
1410 663e8e51 ths
    //~ logout("addr=%s val=0x%02x\n", regname(addr), val);
1411 663e8e51 ths
    eepro100_write1(s, addr, val);
1412 663e8e51 ths
}
1413 663e8e51 ths
1414 c227f099 Anthony Liguori
static void pci_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
1415 663e8e51 ths
{
1416 663e8e51 ths
    EEPRO100State *s = opaque;
1417 663e8e51 ths
    //~ logout("addr=%s val=0x%02x\n", regname(addr), val);
1418 663e8e51 ths
    eepro100_write2(s, addr, val);
1419 663e8e51 ths
}
1420 663e8e51 ths
1421 c227f099 Anthony Liguori
static void pci_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
1422 663e8e51 ths
{
1423 663e8e51 ths
    EEPRO100State *s = opaque;
1424 663e8e51 ths
    //~ logout("addr=%s val=0x%02x\n", regname(addr), val);
1425 663e8e51 ths
    eepro100_write4(s, addr, val);
1426 663e8e51 ths
}
1427 663e8e51 ths
1428 c227f099 Anthony Liguori
static uint32_t pci_mmio_readb(void *opaque, target_phys_addr_t addr)
1429 663e8e51 ths
{
1430 663e8e51 ths
    EEPRO100State *s = opaque;
1431 663e8e51 ths
    //~ logout("addr=%s\n", regname(addr));
1432 663e8e51 ths
    return eepro100_read1(s, addr);
1433 663e8e51 ths
}
1434 663e8e51 ths
1435 c227f099 Anthony Liguori
static uint32_t pci_mmio_readw(void *opaque, target_phys_addr_t addr)
1436 663e8e51 ths
{
1437 663e8e51 ths
    EEPRO100State *s = opaque;
1438 663e8e51 ths
    //~ logout("addr=%s\n", regname(addr));
1439 663e8e51 ths
    return eepro100_read2(s, addr);
1440 663e8e51 ths
}
1441 663e8e51 ths
1442 c227f099 Anthony Liguori
static uint32_t pci_mmio_readl(void *opaque, target_phys_addr_t addr)
1443 663e8e51 ths
{
1444 663e8e51 ths
    EEPRO100State *s = opaque;
1445 663e8e51 ths
    //~ logout("addr=%s\n", regname(addr));
1446 663e8e51 ths
    return eepro100_read4(s, addr);
1447 663e8e51 ths
}
1448 663e8e51 ths
1449 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const pci_mmio_write[] = {
1450 663e8e51 ths
    pci_mmio_writeb,
1451 663e8e51 ths
    pci_mmio_writew,
1452 663e8e51 ths
    pci_mmio_writel
1453 663e8e51 ths
};
1454 663e8e51 ths
1455 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const pci_mmio_read[] = {
1456 663e8e51 ths
    pci_mmio_readb,
1457 663e8e51 ths
    pci_mmio_readw,
1458 663e8e51 ths
    pci_mmio_readl
1459 663e8e51 ths
};
1460 663e8e51 ths
1461 663e8e51 ths
static void pci_mmio_map(PCIDevice * pci_dev, int region_num,
1462 663e8e51 ths
                         uint32_t addr, uint32_t size, int type)
1463 663e8e51 ths
{
1464 273a2142 Juan Quintela
    EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
1465 663e8e51 ths
1466 aac443e6 Stefan Weil
    TRACE(OTHER, logout("region %d, addr=0x%08x, size=0x%08x, type=%d\n",
1467 aac443e6 Stefan Weil
          region_num, addr, size, type));
1468 663e8e51 ths
1469 663e8e51 ths
    if (region_num == 0) {
1470 663e8e51 ths
        /* Map control / status registers. */
1471 273a2142 Juan Quintela
        cpu_register_physical_memory(addr, size, s->mmio_index);
1472 273a2142 Juan Quintela
        s->region[region_num] = addr;
1473 663e8e51 ths
    }
1474 663e8e51 ths
}
1475 663e8e51 ths
1476 e3f5ec2b Mark McLoughlin
static int nic_can_receive(VLANClientState *vc)
1477 663e8e51 ths
{
1478 e3f5ec2b Mark McLoughlin
    EEPRO100State *s = vc->opaque;
1479 aac443e6 Stefan Weil
    TRACE(RXTX, logout("%p\n", s));
1480 663e8e51 ths
    return get_ru_state(s) == ru_ready;
1481 663e8e51 ths
    //~ return !eepro100_buffer_full(s);
1482 663e8e51 ths
}
1483 663e8e51 ths
1484 4f1c942b Mark McLoughlin
static ssize_t nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
1485 663e8e51 ths
{
1486 663e8e51 ths
    /* TODO:
1487 663e8e51 ths
     * - Magic packets should set bit 30 in power management driver register.
1488 663e8e51 ths
     * - Interesting packets should set bit 29 in power management driver register.
1489 663e8e51 ths
     */
1490 e3f5ec2b Mark McLoughlin
    EEPRO100State *s = vc->opaque;
1491 663e8e51 ths
    uint16_t rfd_status = 0xa000;
1492 663e8e51 ths
    static const uint8_t broadcast_macaddr[6] =
1493 663e8e51 ths
        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1494 663e8e51 ths
1495 663e8e51 ths
    /* TODO: check multiple IA bit. */
1496 7f1e9d4e Kevin Wolf
    if (s->configuration[20] & BIT(6)) {
1497 7f1e9d4e Kevin Wolf
        missing("Multiple IA bit");
1498 7f1e9d4e Kevin Wolf
        return -1;
1499 7f1e9d4e Kevin Wolf
    }
1500 663e8e51 ths
1501 663e8e51 ths
    if (s->configuration[8] & 0x80) {
1502 663e8e51 ths
        /* CSMA is disabled. */
1503 663e8e51 ths
        logout("%p received while CSMA is disabled\n", s);
1504 4f1c942b Mark McLoughlin
        return -1;
1505 663e8e51 ths
    } else if (size < 64 && (s->configuration[7] & 1)) {
1506 663e8e51 ths
        /* Short frame and configuration byte 7/0 (discard short receive) set:
1507 663e8e51 ths
         * Short frame is discarded */
1508 067d01de Stefan Weil
        logout("%p received short frame (%zu byte)\n", s, size);
1509 663e8e51 ths
        s->statistics.rx_short_frame_errors++;
1510 4f1c942b Mark McLoughlin
        //~ return -1;
1511 663e8e51 ths
    } else if ((size > MAX_ETH_FRAME_SIZE + 4) && !(s->configuration[18] & 8)) {
1512 663e8e51 ths
        /* Long frame and configuration byte 18/3 (long receive ok) not set:
1513 663e8e51 ths
         * Long frames are discarded. */
1514 067d01de Stefan Weil
        logout("%p received long frame (%zu byte), ignored\n", s, size);
1515 4f1c942b Mark McLoughlin
        return -1;
1516 508ef936 Gerd Hoffmann
    } else if (memcmp(buf, s->conf.macaddr.a, 6) == 0) {       // !!!
1517 663e8e51 ths
        /* Frame matches individual address. */
1518 663e8e51 ths
        /* TODO: check configuration byte 15/4 (ignore U/L). */
1519 067d01de Stefan Weil
        TRACE(RXTX, logout("%p received frame for me, len=%zu\n", s, size));
1520 663e8e51 ths
    } else if (memcmp(buf, broadcast_macaddr, 6) == 0) {
1521 663e8e51 ths
        /* Broadcast frame. */
1522 067d01de Stefan Weil
        TRACE(RXTX, logout("%p received broadcast, len=%zu\n", s, size));
1523 663e8e51 ths
        rfd_status |= 0x0002;
1524 663e8e51 ths
    } else if (buf[0] & 0x01) { // !!!
1525 663e8e51 ths
        /* Multicast frame. */
1526 067d01de Stefan Weil
        TRACE(RXTX, logout("%p received multicast, len=%zu\n", s, size));
1527 663e8e51 ths
        /* TODO: check multicast all bit. */
1528 7f1e9d4e Kevin Wolf
        if (s->configuration[21] & BIT(3)) {
1529 7f1e9d4e Kevin Wolf
            missing("Multicast All bit");
1530 7f1e9d4e Kevin Wolf
        }
1531 663e8e51 ths
        int mcast_idx = compute_mcast_idx(buf);
1532 663e8e51 ths
        if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) {
1533 4f1c942b Mark McLoughlin
            return size;
1534 663e8e51 ths
        }
1535 663e8e51 ths
        rfd_status |= 0x0002;
1536 663e8e51 ths
    } else if (s->configuration[15] & 1) {
1537 663e8e51 ths
        /* Promiscuous: receive all. */
1538 067d01de Stefan Weil
        TRACE(RXTX, logout("%p received frame in promiscuous mode, len=%zu\n", s, size));
1539 663e8e51 ths
        rfd_status |= 0x0004;
1540 663e8e51 ths
    } else {
1541 067d01de Stefan Weil
        TRACE(RXTX, logout("%p received frame, ignored, len=%zu,%s\n", s, size,
1542 aac443e6 Stefan Weil
              nic_dump(buf, size)));
1543 4f1c942b Mark McLoughlin
        return size;
1544 663e8e51 ths
    }
1545 663e8e51 ths
1546 663e8e51 ths
    if (get_ru_state(s) != ru_ready) {
1547 aac443e6 Stefan Weil
        /* No resources available. */
1548 aac443e6 Stefan Weil
        logout("no resources, state=%u\n", get_ru_state(s));
1549 663e8e51 ths
        s->statistics.rx_resource_errors++;
1550 aac443e6 Stefan Weil
        //~ assert(!"no resources");
1551 4f1c942b Mark McLoughlin
        return -1;
1552 663e8e51 ths
    }
1553 663e8e51 ths
    //~ !!!
1554 663e8e51 ths
//~ $3 = {status = 0x0, command = 0xc000, link = 0x2d220, rx_buf_addr = 0x207dc, count = 0x0, size = 0x5f8, packet = {0x0 <repeats 1518 times>}}
1555 c227f099 Anthony Liguori
    eepro100_rx_t rx;
1556 663e8e51 ths
    cpu_physical_memory_read(s->ru_base + s->ru_offset, (uint8_t *) & rx,
1557 c227f099 Anthony Liguori
                             offsetof(eepro100_rx_t, packet));
1558 663e8e51 ths
    uint16_t rfd_command = le16_to_cpu(rx.command);
1559 663e8e51 ths
    uint16_t rfd_size = le16_to_cpu(rx.size);
1560 7f1e9d4e Kevin Wolf
1561 7f1e9d4e Kevin Wolf
    if (size > rfd_size) {
1562 7f1e9d4e Kevin Wolf
        logout("Receive buffer (%" PRId16 " bytes) too small for data "
1563 7f1e9d4e Kevin Wolf
            "(%zu bytes); data truncated\n", rfd_size, size);
1564 7f1e9d4e Kevin Wolf
        size = rfd_size;
1565 7f1e9d4e Kevin Wolf
    }
1566 663e8e51 ths
    if (size < 64) {
1567 663e8e51 ths
        rfd_status |= 0x0080;
1568 663e8e51 ths
    }
1569 aac443e6 Stefan Weil
    TRACE(OTHER, logout("command 0x%04x, link 0x%08x, addr 0x%08x, size %u\n",
1570 aac443e6 Stefan Weil
          rfd_command, rx.link, rx.rx_buf_addr, rfd_size));
1571 c227f099 Anthony Liguori
    stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, status),
1572 663e8e51 ths
             rfd_status);
1573 c227f099 Anthony Liguori
    stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, count), size);
1574 663e8e51 ths
    /* Early receive interrupt not supported. */
1575 663e8e51 ths
    //~ eepro100_er_interrupt(s);
1576 663e8e51 ths
    /* Receive CRC Transfer not supported. */
1577 7f1e9d4e Kevin Wolf
    if (s->configuration[18] & 4) {
1578 7f1e9d4e Kevin Wolf
        missing("Receive CRC Transfer");
1579 7f1e9d4e Kevin Wolf
        return -1;
1580 7f1e9d4e Kevin Wolf
    }
1581 663e8e51 ths
    /* TODO: check stripping enable bit. */
1582 663e8e51 ths
    //~ assert(!(s->configuration[17] & 1));
1583 663e8e51 ths
    cpu_physical_memory_write(s->ru_base + s->ru_offset +
1584 c227f099 Anthony Liguori
                              offsetof(eepro100_rx_t, packet), buf, size);
1585 663e8e51 ths
    s->statistics.rx_good_frames++;
1586 663e8e51 ths
    eepro100_fr_interrupt(s);
1587 663e8e51 ths
    s->ru_offset = le32_to_cpu(rx.link);
1588 663e8e51 ths
    if (rfd_command & 0x8000) {
1589 663e8e51 ths
        /* EL bit is set, so this was the last frame. */
1590 7f1e9d4e Kevin Wolf
        logout("receive: Running out of frames\n");
1591 7f1e9d4e Kevin Wolf
        set_ru_state(s, ru_suspended);
1592 663e8e51 ths
    }
1593 663e8e51 ths
    if (rfd_command & 0x4000) {
1594 663e8e51 ths
        /* S bit is set. */
1595 663e8e51 ths
        set_ru_state(s, ru_suspended);
1596 663e8e51 ths
    }
1597 4f1c942b Mark McLoughlin
    return size;
1598 663e8e51 ths
}
1599 663e8e51 ths
1600 663e8e51 ths
static int nic_load(QEMUFile * f, void *opaque, int version_id)
1601 663e8e51 ths
{
1602 769cf7a5 Juan Quintela
    EEPRO100State *s = opaque;
1603 2657c663 balrog
    int i;
1604 663e8e51 ths
    int ret;
1605 663e8e51 ths
1606 4e3db917 Aurelien Jarno
    if (version_id > 3)
1607 663e8e51 ths
        return -EINVAL;
1608 4e3db917 Aurelien Jarno
1609 3706c43f Stefan Weil
    ret = pci_device_load(&s->dev, f);
1610 3706c43f Stefan Weil
    if (ret < 0) {
1611 3706c43f Stefan Weil
        return ret;
1612 663e8e51 ths
    }
1613 663e8e51 ths
1614 3706c43f Stefan Weil
    /* Skip unused entries. */
1615 3706c43f Stefan Weil
    qemu_fseek(f, 32, SEEK_CUR);
1616 663e8e51 ths
1617 663e8e51 ths
    qemu_get_buffer(f, s->mult, 8);
1618 663e8e51 ths
    qemu_get_buffer(f, s->mem, sizeof(s->mem));
1619 663e8e51 ths
1620 3706c43f Stefan Weil
    /* Restore all members of struct between scb_stat and mem. */
1621 2657c663 balrog
    qemu_get_8s(f, &s->scb_stat);
1622 2657c663 balrog
    qemu_get_8s(f, &s->int_stat);
1623 3706c43f Stefan Weil
    /* Skip unused entries. */
1624 3706c43f Stefan Weil
    qemu_fseek(f, 3 * 4, SEEK_CUR);
1625 508ef936 Gerd Hoffmann
    qemu_get_buffer(f, s->conf.macaddr.a, 6);
1626 3706c43f Stefan Weil
    /* Skip unused entries. */
1627 3706c43f Stefan Weil
    qemu_fseek(f, 19 * 4, SEEK_CUR);
1628 4e3db917 Aurelien Jarno
    for (i = 0; i < 32; i++) {
1629 2657c663 balrog
        qemu_get_be16s(f, &s->mdimem[i]);
1630 aac443e6 Stefan Weil
    }
1631 aac443e6 Stefan Weil
    /* The eeprom should be saved and restored by its own routines. */
1632 2657c663 balrog
    qemu_get_be32s(f, &s->device);
1633 3706c43f Stefan Weil
    // TODO check device.
1634 2657c663 balrog
    qemu_get_be32s(f, &s->pointer);
1635 2657c663 balrog
    qemu_get_be32s(f, &s->cu_base);
1636 2657c663 balrog
    qemu_get_be32s(f, &s->cu_offset);
1637 2657c663 balrog
    qemu_get_be32s(f, &s->ru_base);
1638 2657c663 balrog
    qemu_get_be32s(f, &s->ru_offset);
1639 2657c663 balrog
    qemu_get_be32s(f, &s->statsaddr);
1640 aac443e6 Stefan Weil
    /* Restore epro100_stats_t statistics. */
1641 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_good_frames);
1642 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_max_collisions);
1643 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_late_collisions);
1644 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_underruns);
1645 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_lost_crs);
1646 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_deferred);
1647 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_single_collisions);
1648 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_multiple_collisions);
1649 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.tx_total_collisions);
1650 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_good_frames);
1651 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_crc_errors);
1652 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_alignment_errors);
1653 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_resource_errors);
1654 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_overrun_errors);
1655 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_cdt_errors);
1656 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.rx_short_frame_errors);
1657 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.fc_xmt_pause);
1658 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.fc_rcv_pause);
1659 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.fc_rcv_unsupported);
1660 2657c663 balrog
    qemu_get_be16s(f, &s->statistics.xmt_tco_frames);
1661 2657c663 balrog
    qemu_get_be16s(f, &s->statistics.rcv_tco_frames);
1662 2657c663 balrog
    qemu_get_be32s(f, &s->statistics.complete);
1663 2657c663 balrog
#if 0
1664 2657c663 balrog
    qemu_get_be16s(f, &s->status);
1665 2657c663 balrog
#endif
1666 2657c663 balrog
1667 2657c663 balrog
    /* Configuration bytes. */
1668 2657c663 balrog
    qemu_get_buffer(f, s->configuration, sizeof(s->configuration));
1669 2657c663 balrog
1670 663e8e51 ths
    return 0;
1671 663e8e51 ths
}
1672 663e8e51 ths
1673 663e8e51 ths
static void nic_save(QEMUFile * f, void *opaque)
1674 663e8e51 ths
{
1675 769cf7a5 Juan Quintela
    EEPRO100State *s = opaque;
1676 2657c663 balrog
    int i;
1677 663e8e51 ths
1678 273a2142 Juan Quintela
    pci_device_save(&s->dev, f);
1679 663e8e51 ths
1680 3706c43f Stefan Weil
    /* Skip unused entries. */
1681 3706c43f Stefan Weil
    qemu_fseek(f, 32, SEEK_CUR);
1682 3706c43f Stefan Weil
1683 663e8e51 ths
    qemu_put_buffer(f, s->mult, 8);
1684 663e8e51 ths
    qemu_put_buffer(f, s->mem, sizeof(s->mem));
1685 2657c663 balrog
1686 3706c43f Stefan Weil
    /* Save all members of struct between scb_stat and mem. */
1687 2657c663 balrog
    qemu_put_8s(f, &s->scb_stat);
1688 2657c663 balrog
    qemu_put_8s(f, &s->int_stat);
1689 3706c43f Stefan Weil
    /* Skip unused entries. */
1690 3706c43f Stefan Weil
    qemu_fseek(f, 3 * 4, SEEK_CUR);
1691 508ef936 Gerd Hoffmann
    qemu_put_buffer(f, s->conf.macaddr.a, 6);
1692 3706c43f Stefan Weil
    /* Skip unused entries. */
1693 3706c43f Stefan Weil
    qemu_fseek(f, 19 * 4, SEEK_CUR);
1694 4e3db917 Aurelien Jarno
    for (i = 0; i < 32; i++) {
1695 2657c663 balrog
        qemu_put_be16s(f, &s->mdimem[i]);
1696 aac443e6 Stefan Weil
    }
1697 aac443e6 Stefan Weil
    /* The eeprom should be saved and restored by its own routines. */
1698 2657c663 balrog
    qemu_put_be32s(f, &s->device);
1699 2657c663 balrog
    qemu_put_be32s(f, &s->pointer);
1700 2657c663 balrog
    qemu_put_be32s(f, &s->cu_base);
1701 2657c663 balrog
    qemu_put_be32s(f, &s->cu_offset);
1702 2657c663 balrog
    qemu_put_be32s(f, &s->ru_base);
1703 2657c663 balrog
    qemu_put_be32s(f, &s->ru_offset);
1704 2657c663 balrog
    qemu_put_be32s(f, &s->statsaddr);
1705 aac443e6 Stefan Weil
    /* Save epro100_stats_t statistics. */
1706 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_good_frames);
1707 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_max_collisions);
1708 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_late_collisions);
1709 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_underruns);
1710 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_lost_crs);
1711 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_deferred);
1712 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_single_collisions);
1713 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_multiple_collisions);
1714 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.tx_total_collisions);
1715 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_good_frames);
1716 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_crc_errors);
1717 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_alignment_errors);
1718 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_resource_errors);
1719 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_overrun_errors);
1720 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_cdt_errors);
1721 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.rx_short_frame_errors);
1722 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.fc_xmt_pause);
1723 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.fc_rcv_pause);
1724 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.fc_rcv_unsupported);
1725 2657c663 balrog
    qemu_put_be16s(f, &s->statistics.xmt_tco_frames);
1726 2657c663 balrog
    qemu_put_be16s(f, &s->statistics.rcv_tco_frames);
1727 2657c663 balrog
    qemu_put_be32s(f, &s->statistics.complete);
1728 2657c663 balrog
#if 0
1729 2657c663 balrog
    qemu_put_be16s(f, &s->status);
1730 2657c663 balrog
#endif
1731 2657c663 balrog
1732 2657c663 balrog
    /* Configuration bytes. */
1733 2657c663 balrog
    qemu_put_buffer(f, s->configuration, sizeof(s->configuration));
1734 663e8e51 ths
}
1735 663e8e51 ths
1736 b946a153 aliguori
static void nic_cleanup(VLANClientState *vc)
1737 b946a153 aliguori
{
1738 b946a153 aliguori
    EEPRO100State *s = vc->opaque;
1739 b946a153 aliguori
1740 508ef936 Gerd Hoffmann
    s->vc = NULL;
1741 b946a153 aliguori
}
1742 b946a153 aliguori
1743 c4c270e2 Stefan Weil
static int pci_nic_uninit(PCIDevice *pci_dev)
1744 b946a153 aliguori
{
1745 c4c270e2 Stefan Weil
    EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
1746 b946a153 aliguori
1747 b946a153 aliguori
    cpu_unregister_io_memory(s->mmio_index);
1748 508ef936 Gerd Hoffmann
    unregister_savevm(s->vc->model, s);
1749 508ef936 Gerd Hoffmann
    eeprom93xx_free(s->eeprom);
1750 508ef936 Gerd Hoffmann
    qemu_del_vlan_client(s->vc);
1751 b946a153 aliguori
    return 0;
1752 b946a153 aliguori
}
1753 b946a153 aliguori
1754 81a322d4 Gerd Hoffmann
static int nic_init(PCIDevice *pci_dev, uint32_t device)
1755 663e8e51 ths
{
1756 273a2142 Juan Quintela
    EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
1757 663e8e51 ths
1758 aac443e6 Stefan Weil
    TRACE(OTHER, logout("\n"));
1759 663e8e51 ths
1760 663e8e51 ths
    s->device = device;
1761 663e8e51 ths
1762 663e8e51 ths
    pci_reset(s);
1763 663e8e51 ths
1764 663e8e51 ths
    /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM,
1765 663e8e51 ths
     * i82559 and later support 64 or 256 word EEPROM. */
1766 663e8e51 ths
    s->eeprom = eeprom93xx_new(EEPROM_SIZE);
1767 663e8e51 ths
1768 663e8e51 ths
    /* Handler for memory-mapped I/O */
1769 273a2142 Juan Quintela
    s->mmio_index =
1770 1eed09cb Avi Kivity
        cpu_register_io_memory(pci_mmio_read, pci_mmio_write, s);
1771 663e8e51 ths
1772 273a2142 Juan Quintela
    pci_register_bar(&s->dev, 0, PCI_MEM_SIZE,
1773 663e8e51 ths
                           PCI_ADDRESS_SPACE_MEM |
1774 663e8e51 ths
                           PCI_ADDRESS_SPACE_MEM_PREFETCH, pci_mmio_map);
1775 273a2142 Juan Quintela
    pci_register_bar(&s->dev, 1, PCI_IO_SIZE, PCI_ADDRESS_SPACE_IO,
1776 663e8e51 ths
                           pci_map);
1777 273a2142 Juan Quintela
    pci_register_bar(&s->dev, 2, PCI_FLASH_SIZE, PCI_ADDRESS_SPACE_MEM,
1778 663e8e51 ths
                           pci_mmio_map);
1779 663e8e51 ths
1780 508ef936 Gerd Hoffmann
    qemu_macaddr_default_if_unset(&s->conf.macaddr);
1781 663e8e51 ths
    logout("macaddr: %s\n", nic_dump(&s->macaddr[0], 6));
1782 663e8e51 ths
    assert(s->region[1] == 0);
1783 663e8e51 ths
1784 663e8e51 ths
    nic_reset(s);
1785 663e8e51 ths
1786 508ef936 Gerd Hoffmann
    s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
1787 508ef936 Gerd Hoffmann
                                 s->conf.vlan, s->conf.peer,
1788 508ef936 Gerd Hoffmann
                                 pci_dev->qdev.info->name, pci_dev->qdev.id,
1789 508ef936 Gerd Hoffmann
                                 nic_can_receive, nic_receive, NULL, NULL,
1790 b946a153 aliguori
                                 nic_cleanup, s);
1791 663e8e51 ths
1792 508ef936 Gerd Hoffmann
    qemu_format_nic_info_str(s->vc, s->conf.macaddr.a);
1793 aac443e6 Stefan Weil
    TRACE(OTHER, logout("%s\n", s->vc->info_str));
1794 663e8e51 ths
1795 a08d4367 Jan Kiszka
    qemu_register_reset(nic_reset, s);
1796 663e8e51 ths
1797 4e3db917 Aurelien Jarno
    register_savevm(s->vc->model, -1, 3, nic_save, nic_load, s);
1798 81a322d4 Gerd Hoffmann
    return 0;
1799 663e8e51 ths
}
1800 663e8e51 ths
1801 c4c270e2 Stefan Weil
static int pci_i82550_init(PCIDevice *pci_dev)
1802 c4c270e2 Stefan Weil
{
1803 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82550);
1804 c4c270e2 Stefan Weil
}
1805 c4c270e2 Stefan Weil
1806 c4c270e2 Stefan Weil
static int pci_i82551_init(PCIDevice *pci_dev)
1807 c4c270e2 Stefan Weil
{
1808 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82551);
1809 c4c270e2 Stefan Weil
}
1810 c4c270e2 Stefan Weil
1811 c4c270e2 Stefan Weil
static int pci_i82557a_init(PCIDevice *pci_dev)
1812 c4c270e2 Stefan Weil
{
1813 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82557A);
1814 c4c270e2 Stefan Weil
}
1815 c4c270e2 Stefan Weil
1816 c4c270e2 Stefan Weil
static int pci_i82557b_init(PCIDevice *pci_dev)
1817 c4c270e2 Stefan Weil
{
1818 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82557B);
1819 c4c270e2 Stefan Weil
}
1820 c4c270e2 Stefan Weil
1821 c4c270e2 Stefan Weil
static int pci_i82557c_init(PCIDevice *pci_dev)
1822 c4c270e2 Stefan Weil
{
1823 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82557C);
1824 c4c270e2 Stefan Weil
}
1825 c4c270e2 Stefan Weil
1826 c4c270e2 Stefan Weil
static int pci_i82558a_init(PCIDevice *pci_dev)
1827 c4c270e2 Stefan Weil
{
1828 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82558A);
1829 c4c270e2 Stefan Weil
}
1830 c4c270e2 Stefan Weil
1831 c4c270e2 Stefan Weil
static int pci_i82558b_init(PCIDevice *pci_dev)
1832 c4c270e2 Stefan Weil
{
1833 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82558B);
1834 c4c270e2 Stefan Weil
}
1835 c4c270e2 Stefan Weil
1836 c4c270e2 Stefan Weil
static int pci_i82559a_init(PCIDevice *pci_dev)
1837 c4c270e2 Stefan Weil
{
1838 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82559A);
1839 c4c270e2 Stefan Weil
}
1840 c4c270e2 Stefan Weil
1841 c4c270e2 Stefan Weil
static int pci_i82559b_init(PCIDevice *pci_dev)
1842 c4c270e2 Stefan Weil
{
1843 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82559B);
1844 c4c270e2 Stefan Weil
}
1845 c4c270e2 Stefan Weil
1846 c4c270e2 Stefan Weil
static int pci_i82559c_init(PCIDevice *pci_dev)
1847 9d07d757 Paul Brook
{
1848 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82559C);
1849 9d07d757 Paul Brook
}
1850 9d07d757 Paul Brook
1851 c4c270e2 Stefan Weil
static int pci_i82559er_init(PCIDevice *pci_dev)
1852 663e8e51 ths
{
1853 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82559ER);
1854 663e8e51 ths
}
1855 663e8e51 ths
1856 c4c270e2 Stefan Weil
static int pci_i82562_init(PCIDevice *pci_dev)
1857 663e8e51 ths
{
1858 c4c270e2 Stefan Weil
    return nic_init(pci_dev, i82562);
1859 663e8e51 ths
}
1860 663e8e51 ths
1861 0aab0d3a Gerd Hoffmann
static PCIDeviceInfo eepro100_info[] = {
1862 0aab0d3a Gerd Hoffmann
    {
1863 c4c270e2 Stefan Weil
        .qdev.name = "i82550",
1864 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1865 c4c270e2 Stefan Weil
        .init      = pci_i82550_init,
1866 508ef936 Gerd Hoffmann
        .qdev.props = (Property[]) {
1867 508ef936 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
1868 508ef936 Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
1869 508ef936 Gerd Hoffmann
        },
1870 c4c270e2 Stefan Weil
    },{
1871 0aab0d3a Gerd Hoffmann
        .qdev.name = "i82551",
1872 273a2142 Juan Quintela
        .qdev.size = sizeof(EEPRO100State),
1873 0aab0d3a Gerd Hoffmann
        .init      = pci_i82551_init,
1874 e3936fa5 Gerd Hoffmann
        .exit      = pci_nic_uninit,
1875 508ef936 Gerd Hoffmann
        .qdev.props = (Property[]) {
1876 508ef936 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
1877 508ef936 Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
1878 508ef936 Gerd Hoffmann
        },
1879 0aab0d3a Gerd Hoffmann
    },{
1880 c4c270e2 Stefan Weil
        .qdev.name = "i82557a",
1881 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1882 c4c270e2 Stefan Weil
        .init      = pci_i82557a_init,
1883 508ef936 Gerd Hoffmann
        .qdev.props = (Property[]) {
1884 508ef936 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
1885 508ef936 Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
1886 508ef936 Gerd Hoffmann
        },
1887 c4c270e2 Stefan Weil
    },{
1888 0aab0d3a Gerd Hoffmann
        .qdev.name = "i82557b",
1889 273a2142 Juan Quintela
        .qdev.size = sizeof(EEPRO100State),
1890 0aab0d3a Gerd Hoffmann
        .init      = pci_i82557b_init,
1891 e3936fa5 Gerd Hoffmann
        .exit      = pci_nic_uninit,
1892 508ef936 Gerd Hoffmann
        .qdev.props = (Property[]) {
1893 508ef936 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
1894 508ef936 Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
1895 508ef936 Gerd Hoffmann
        },
1896 0aab0d3a Gerd Hoffmann
    },{
1897 c4c270e2 Stefan Weil
        .qdev.name = "i82557c",
1898 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1899 c4c270e2 Stefan Weil
        .init      = pci_i82557c_init,
1900 508ef936 Gerd Hoffmann
        .qdev.props = (Property[]) {
1901 508ef936 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
1902 508ef936 Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
1903 508ef936 Gerd Hoffmann
        },
1904 c4c270e2 Stefan Weil
    },{
1905 c4c270e2 Stefan Weil
        .qdev.name = "i82558a",
1906 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1907 c4c270e2 Stefan Weil
        .init      = pci_i82558a_init,
1908 508ef936 Gerd Hoffmann
        .qdev.props = (Property[]) {
1909 508ef936 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
1910 508ef936 Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
1911 508ef936 Gerd Hoffmann
        },
1912 c4c270e2 Stefan Weil
    },{
1913 c4c270e2 Stefan Weil
        .qdev.name = "i82558b",
1914 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1915 c4c270e2 Stefan Weil
        .init      = pci_i82558b_init,
1916 508ef936 Gerd Hoffmann
        .qdev.props = (Property[]) {
1917 508ef936 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
1918 508ef936 Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
1919 508ef936 Gerd Hoffmann
        },
1920 c4c270e2 Stefan Weil
    },{
1921 c4c270e2 Stefan Weil
        .qdev.name = "i82559a",
1922 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1923 c4c270e2 Stefan Weil
        .init      = pci_i82559a_init,
1924 508ef936 Gerd Hoffmann
        .qdev.props = (Property[]) {
1925 508ef936 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
1926 508ef936 Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
1927 508ef936 Gerd Hoffmann
        },
1928 c4c270e2 Stefan Weil
    },{
1929 c4c270e2 Stefan Weil
        .qdev.name = "i82559b",
1930 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1931 c4c270e2 Stefan Weil
        .init      = pci_i82559b_init,
1932 508ef936 Gerd Hoffmann
        .qdev.props = (Property[]) {
1933 508ef936 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
1934 508ef936 Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
1935 508ef936 Gerd Hoffmann
        },
1936 c4c270e2 Stefan Weil
    },{
1937 c4c270e2 Stefan Weil
        .qdev.name = "i82559c",
1938 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1939 c4c270e2 Stefan Weil
        .init      = pci_i82559c_init,
1940 508ef936 Gerd Hoffmann
        .qdev.props = (Property[]) {
1941 508ef936 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
1942 508ef936 Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
1943 508ef936 Gerd Hoffmann
        },
1944 c4c270e2 Stefan Weil
    },{
1945 0aab0d3a Gerd Hoffmann
        .qdev.name = "i82559er",
1946 273a2142 Juan Quintela
        .qdev.size = sizeof(EEPRO100State),
1947 0aab0d3a Gerd Hoffmann
        .init      = pci_i82559er_init,
1948 e3936fa5 Gerd Hoffmann
        .exit      = pci_nic_uninit,
1949 508ef936 Gerd Hoffmann
        .qdev.props = (Property[]) {
1950 508ef936 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
1951 508ef936 Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
1952 508ef936 Gerd Hoffmann
        },
1953 0aab0d3a Gerd Hoffmann
    },{
1954 c4c270e2 Stefan Weil
        .qdev.name = "i82562",
1955 c4c270e2 Stefan Weil
        .qdev.size = sizeof(EEPRO100State),
1956 c4c270e2 Stefan Weil
        .init      = pci_i82562_init,
1957 508ef936 Gerd Hoffmann
        .qdev.props = (Property[]) {
1958 508ef936 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
1959 508ef936 Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
1960 508ef936 Gerd Hoffmann
        },
1961 c4c270e2 Stefan Weil
    },{
1962 0aab0d3a Gerd Hoffmann
        /* end of list */
1963 0aab0d3a Gerd Hoffmann
    }
1964 0aab0d3a Gerd Hoffmann
};
1965 0aab0d3a Gerd Hoffmann
1966 9d07d757 Paul Brook
static void eepro100_register_devices(void)
1967 663e8e51 ths
{
1968 0aab0d3a Gerd Hoffmann
    pci_qdev_register_many(eepro100_info);
1969 663e8e51 ths
}
1970 663e8e51 ths
1971 9d07d757 Paul Brook
device_init(eepro100_register_devices)