Statistics
| Branch: | Revision:

root / hw / eepro100.c @ 3031efab

History | View | Annotate | Download (58.2 kB)

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

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