Statistics
| Branch: | Revision:

root / hw / eepro100.c @ 283c7c63

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