Statistics
| Branch: | Revision:

root / hw / e1000.c @ 6fb6d245

History | View | Annotate | Download (37.1 kB)

1 7c23b892 balrog
/*
2 7c23b892 balrog
 * QEMU e1000 emulation
3 7c23b892 balrog
 *
4 7c23b892 balrog
 * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
5 7c23b892 balrog
 * Copyright (c) 2008 Qumranet
6 7c23b892 balrog
 * Based on work done by:
7 7c23b892 balrog
 * Copyright (c) 2007 Dan Aloni
8 7c23b892 balrog
 * Copyright (c) 2004 Antony T Curtis
9 7c23b892 balrog
 *
10 7c23b892 balrog
 * This library is free software; you can redistribute it and/or
11 7c23b892 balrog
 * modify it under the terms of the GNU Lesser General Public
12 7c23b892 balrog
 * License as published by the Free Software Foundation; either
13 7c23b892 balrog
 * version 2 of the License, or (at your option) any later version.
14 7c23b892 balrog
 *
15 7c23b892 balrog
 * This library is distributed in the hope that it will be useful,
16 7c23b892 balrog
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 7c23b892 balrog
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 7c23b892 balrog
 * Lesser General Public License for more details.
19 7c23b892 balrog
 *
20 7c23b892 balrog
 * You should have received a copy of the GNU Lesser General Public
21 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 7c23b892 balrog
 */
23 7c23b892 balrog
24 7c23b892 balrog
25 7c23b892 balrog
#include "hw.h"
26 7c23b892 balrog
#include "pci.h"
27 7c23b892 balrog
#include "net.h"
28 7200ac3c Mark McLoughlin
#include "net/checksum.h"
29 fbdaa002 Gerd Hoffmann
#include "loader.h"
30 7c23b892 balrog
31 7c23b892 balrog
#include "e1000_hw.h"
32 7c23b892 balrog
33 7c23b892 balrog
#define DEBUG
34 7c23b892 balrog
35 7c23b892 balrog
#ifdef DEBUG
36 7c23b892 balrog
enum {
37 7c23b892 balrog
    DEBUG_GENERAL,        DEBUG_IO,        DEBUG_MMIO,        DEBUG_INTERRUPT,
38 7c23b892 balrog
    DEBUG_RX,                DEBUG_TX,        DEBUG_MDIC,        DEBUG_EEPROM,
39 7c23b892 balrog
    DEBUG_UNKNOWN,        DEBUG_TXSUM,        DEBUG_TXERR,        DEBUG_RXERR,
40 7c23b892 balrog
    DEBUG_RXFILTER,        DEBUG_NOTYET,
41 7c23b892 balrog
};
42 7c23b892 balrog
#define DBGBIT(x)        (1<<DEBUG_##x)
43 7c23b892 balrog
static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL);
44 7c23b892 balrog
45 6c7f4b47 Blue Swirl
#define        DBGOUT(what, fmt, ...) do { \
46 7c23b892 balrog
    if (debugflags & DBGBIT(what)) \
47 6c7f4b47 Blue Swirl
        fprintf(stderr, "e1000: " fmt, ## __VA_ARGS__); \
48 7c23b892 balrog
    } while (0)
49 7c23b892 balrog
#else
50 6c7f4b47 Blue Swirl
#define        DBGOUT(what, fmt, ...) do {} while (0)
51 7c23b892 balrog
#endif
52 7c23b892 balrog
53 7c23b892 balrog
#define IOPORT_SIZE       0x40
54 e94bbefe aurel32
#define PNPMMIO_SIZE      0x20000
55 7c23b892 balrog
56 7c23b892 balrog
/*
57 7c23b892 balrog
 * HW models:
58 7c23b892 balrog
 *  E1000_DEV_ID_82540EM works with Windows and Linux
59 7c23b892 balrog
 *  E1000_DEV_ID_82573L OK with windoze and Linux 2.6.22,
60 7c23b892 balrog
 *        appears to perform better than 82540EM, but breaks with Linux 2.6.18
61 7c23b892 balrog
 *  E1000_DEV_ID_82544GC_COPPER appears to work; not well tested
62 7c23b892 balrog
 *  Others never tested
63 7c23b892 balrog
 */
64 7c23b892 balrog
enum { E1000_DEVID = E1000_DEV_ID_82540EM };
65 7c23b892 balrog
66 7c23b892 balrog
/*
67 7c23b892 balrog
 * May need to specify additional MAC-to-PHY entries --
68 7c23b892 balrog
 * Intel's Windows driver refuses to initialize unless they match
69 7c23b892 balrog
 */
70 7c23b892 balrog
enum {
71 7c23b892 balrog
    PHY_ID2_INIT = E1000_DEVID == E1000_DEV_ID_82573L ?                0xcc2 :
72 7c23b892 balrog
                   E1000_DEVID == E1000_DEV_ID_82544GC_COPPER ?        0xc30 :
73 7c23b892 balrog
                   /* default to E1000_DEV_ID_82540EM */        0xc20
74 7c23b892 balrog
};
75 7c23b892 balrog
76 7c23b892 balrog
typedef struct E1000State_st {
77 7c23b892 balrog
    PCIDevice dev;
78 a03e2aec Mark McLoughlin
    NICState *nic;
79 fbdaa002 Gerd Hoffmann
    NICConf conf;
80 7c23b892 balrog
    int mmio_index;
81 7c23b892 balrog
82 7c23b892 balrog
    uint32_t mac_reg[0x8000];
83 7c23b892 balrog
    uint16_t phy_reg[0x20];
84 7c23b892 balrog
    uint16_t eeprom_data[64];
85 7c23b892 balrog
86 7c23b892 balrog
    uint32_t rxbuf_size;
87 7c23b892 balrog
    uint32_t rxbuf_min_shift;
88 7c23b892 balrog
    int check_rxov;
89 7c23b892 balrog
    struct e1000_tx {
90 7c23b892 balrog
        unsigned char header[256];
91 8f2e8d1f aliguori
        unsigned char vlan_header[4];
92 b10fec9b Stefan Weil
        /* Fields vlan and data must not be reordered or separated. */
93 8f2e8d1f aliguori
        unsigned char vlan[4];
94 7c23b892 balrog
        unsigned char data[0x10000];
95 7c23b892 balrog
        uint16_t size;
96 7c23b892 balrog
        unsigned char sum_needed;
97 8f2e8d1f aliguori
        unsigned char vlan_needed;
98 7c23b892 balrog
        uint8_t ipcss;
99 7c23b892 balrog
        uint8_t ipcso;
100 7c23b892 balrog
        uint16_t ipcse;
101 7c23b892 balrog
        uint8_t tucss;
102 7c23b892 balrog
        uint8_t tucso;
103 7c23b892 balrog
        uint16_t tucse;
104 7c23b892 balrog
        uint8_t hdr_len;
105 7c23b892 balrog
        uint16_t mss;
106 7c23b892 balrog
        uint32_t paylen;
107 7c23b892 balrog
        uint16_t tso_frames;
108 7c23b892 balrog
        char tse;
109 b6c4f71f blueswir1
        int8_t ip;
110 b6c4f71f blueswir1
        int8_t tcp;
111 1b0009db balrog
        char cptse;     // current packet tse bit
112 7c23b892 balrog
    } tx;
113 7c23b892 balrog
114 7c23b892 balrog
    struct {
115 7c23b892 balrog
        uint32_t val_in;        // shifted in from guest driver
116 7c23b892 balrog
        uint16_t bitnum_in;
117 7c23b892 balrog
        uint16_t bitnum_out;
118 7c23b892 balrog
        uint16_t reading;
119 7c23b892 balrog
        uint32_t old_eecd;
120 7c23b892 balrog
    } eecd_state;
121 7c23b892 balrog
} E1000State;
122 7c23b892 balrog
123 7c23b892 balrog
#define        defreg(x)        x = (E1000_##x>>2)
124 7c23b892 balrog
enum {
125 7c23b892 balrog
    defreg(CTRL),        defreg(EECD),        defreg(EERD),        defreg(GPRC),
126 7c23b892 balrog
    defreg(GPTC),        defreg(ICR),        defreg(ICS),        defreg(IMC),
127 7c23b892 balrog
    defreg(IMS),        defreg(LEDCTL),        defreg(MANC),        defreg(MDIC),
128 7c23b892 balrog
    defreg(MPC),        defreg(PBA),        defreg(RCTL),        defreg(RDBAH),
129 7c23b892 balrog
    defreg(RDBAL),        defreg(RDH),        defreg(RDLEN),        defreg(RDT),
130 7c23b892 balrog
    defreg(STATUS),        defreg(SWSM),        defreg(TCTL),        defreg(TDBAH),
131 7c23b892 balrog
    defreg(TDBAL),        defreg(TDH),        defreg(TDLEN),        defreg(TDT),
132 7c23b892 balrog
    defreg(TORH),        defreg(TORL),        defreg(TOTH),        defreg(TOTL),
133 7c23b892 balrog
    defreg(TPR),        defreg(TPT),        defreg(TXDCTL),        defreg(WUFC),
134 8f2e8d1f aliguori
    defreg(RA),                defreg(MTA),        defreg(CRCERRS),defreg(VFTA),
135 8f2e8d1f aliguori
    defreg(VET),
136 7c23b892 balrog
};
137 7c23b892 balrog
138 7c23b892 balrog
enum { PHY_R = 1, PHY_W = 2, PHY_RW = PHY_R | PHY_W };
139 88b4e9db blueswir1
static const char phy_regcap[0x20] = {
140 7c23b892 balrog
    [PHY_STATUS] = PHY_R,        [M88E1000_EXT_PHY_SPEC_CTRL] = PHY_RW,
141 7c23b892 balrog
    [PHY_ID1] = PHY_R,                [M88E1000_PHY_SPEC_CTRL] = PHY_RW,
142 7c23b892 balrog
    [PHY_CTRL] = PHY_RW,        [PHY_1000T_CTRL] = PHY_RW,
143 7c23b892 balrog
    [PHY_LP_ABILITY] = PHY_R,        [PHY_1000T_STATUS] = PHY_R,
144 7c23b892 balrog
    [PHY_AUTONEG_ADV] = PHY_RW,        [M88E1000_RX_ERR_CNTR] = PHY_R,
145 700f6e2c aurel32
    [PHY_ID2] = PHY_R,                [M88E1000_PHY_SPEC_STATUS] = PHY_R
146 7c23b892 balrog
};
147 7c23b892 balrog
148 7c23b892 balrog
static void
149 6e355d90 Isaku Yamahata
ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr,
150 6e355d90 Isaku Yamahata
           pcibus_t size, int type)
151 7c23b892 balrog
{
152 89e8b13c Isaku Yamahata
    DBGOUT(IO, "e1000_ioport_map addr=0x%04"FMT_PCIBUS
153 89e8b13c Isaku Yamahata
           " size=0x%08"FMT_PCIBUS"\n", addr, size);
154 7c23b892 balrog
}
155 7c23b892 balrog
156 7c23b892 balrog
static void
157 7c23b892 balrog
set_interrupt_cause(E1000State *s, int index, uint32_t val)
158 7c23b892 balrog
{
159 7c23b892 balrog
    if (val)
160 7c23b892 balrog
        val |= E1000_ICR_INT_ASSERTED;
161 7c23b892 balrog
    s->mac_reg[ICR] = val;
162 b1332393 Bill Paul
    s->mac_reg[ICS] = val;
163 bc26e55a Blue Swirl
    qemu_set_irq(s->dev.irq[0], (s->mac_reg[IMS] & s->mac_reg[ICR]) != 0);
164 7c23b892 balrog
}
165 7c23b892 balrog
166 7c23b892 balrog
static void
167 7c23b892 balrog
set_ics(E1000State *s, int index, uint32_t val)
168 7c23b892 balrog
{
169 7c23b892 balrog
    DBGOUT(INTERRUPT, "set_ics %x, ICR %x, IMR %x\n", val, s->mac_reg[ICR],
170 7c23b892 balrog
        s->mac_reg[IMS]);
171 7c23b892 balrog
    set_interrupt_cause(s, 0, val | s->mac_reg[ICR]);
172 7c23b892 balrog
}
173 7c23b892 balrog
174 7c23b892 balrog
static int
175 7c23b892 balrog
rxbufsize(uint32_t v)
176 7c23b892 balrog
{
177 7c23b892 balrog
    v &= E1000_RCTL_BSEX | E1000_RCTL_SZ_16384 | E1000_RCTL_SZ_8192 |
178 7c23b892 balrog
         E1000_RCTL_SZ_4096 | E1000_RCTL_SZ_2048 | E1000_RCTL_SZ_1024 |
179 7c23b892 balrog
         E1000_RCTL_SZ_512 | E1000_RCTL_SZ_256;
180 7c23b892 balrog
    switch (v) {
181 7c23b892 balrog
    case E1000_RCTL_BSEX | E1000_RCTL_SZ_16384:
182 7c23b892 balrog
        return 16384;
183 7c23b892 balrog
    case E1000_RCTL_BSEX | E1000_RCTL_SZ_8192:
184 7c23b892 balrog
        return 8192;
185 7c23b892 balrog
    case E1000_RCTL_BSEX | E1000_RCTL_SZ_4096:
186 7c23b892 balrog
        return 4096;
187 7c23b892 balrog
    case E1000_RCTL_SZ_1024:
188 7c23b892 balrog
        return 1024;
189 7c23b892 balrog
    case E1000_RCTL_SZ_512:
190 7c23b892 balrog
        return 512;
191 7c23b892 balrog
    case E1000_RCTL_SZ_256:
192 7c23b892 balrog
        return 256;
193 7c23b892 balrog
    }
194 7c23b892 balrog
    return 2048;
195 7c23b892 balrog
}
196 7c23b892 balrog
197 7c23b892 balrog
static void
198 cab3c825 Kevin Wolf
set_ctrl(E1000State *s, int index, uint32_t val)
199 cab3c825 Kevin Wolf
{
200 cab3c825 Kevin Wolf
    /* RST is self clearing */
201 cab3c825 Kevin Wolf
    s->mac_reg[CTRL] = val & ~E1000_CTRL_RST;
202 cab3c825 Kevin Wolf
}
203 cab3c825 Kevin Wolf
204 cab3c825 Kevin Wolf
static void
205 7c23b892 balrog
set_rx_control(E1000State *s, int index, uint32_t val)
206 7c23b892 balrog
{
207 7c23b892 balrog
    s->mac_reg[RCTL] = val;
208 7c23b892 balrog
    s->rxbuf_size = rxbufsize(val);
209 7c23b892 balrog
    s->rxbuf_min_shift = ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1;
210 7c23b892 balrog
    DBGOUT(RX, "RCTL: %d, mac_reg[RCTL] = 0x%x\n", s->mac_reg[RDT],
211 7c23b892 balrog
           s->mac_reg[RCTL]);
212 7c23b892 balrog
}
213 7c23b892 balrog
214 7c23b892 balrog
static void
215 7c23b892 balrog
set_mdic(E1000State *s, int index, uint32_t val)
216 7c23b892 balrog
{
217 7c23b892 balrog
    uint32_t data = val & E1000_MDIC_DATA_MASK;
218 7c23b892 balrog
    uint32_t addr = ((val & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
219 7c23b892 balrog
220 7c23b892 balrog
    if ((val & E1000_MDIC_PHY_MASK) >> E1000_MDIC_PHY_SHIFT != 1) // phy #
221 7c23b892 balrog
        val = s->mac_reg[MDIC] | E1000_MDIC_ERROR;
222 7c23b892 balrog
    else if (val & E1000_MDIC_OP_READ) {
223 7c23b892 balrog
        DBGOUT(MDIC, "MDIC read reg 0x%x\n", addr);
224 7c23b892 balrog
        if (!(phy_regcap[addr] & PHY_R)) {
225 7c23b892 balrog
            DBGOUT(MDIC, "MDIC read reg %x unhandled\n", addr);
226 7c23b892 balrog
            val |= E1000_MDIC_ERROR;
227 7c23b892 balrog
        } else
228 7c23b892 balrog
            val = (val ^ data) | s->phy_reg[addr];
229 7c23b892 balrog
    } else if (val & E1000_MDIC_OP_WRITE) {
230 7c23b892 balrog
        DBGOUT(MDIC, "MDIC write reg 0x%x, value 0x%x\n", addr, data);
231 7c23b892 balrog
        if (!(phy_regcap[addr] & PHY_W)) {
232 7c23b892 balrog
            DBGOUT(MDIC, "MDIC write reg %x unhandled\n", addr);
233 7c23b892 balrog
            val |= E1000_MDIC_ERROR;
234 7c23b892 balrog
        } else
235 7c23b892 balrog
            s->phy_reg[addr] = data;
236 7c23b892 balrog
    }
237 7c23b892 balrog
    s->mac_reg[MDIC] = val | E1000_MDIC_READY;
238 7c23b892 balrog
    set_ics(s, 0, E1000_ICR_MDAC);
239 7c23b892 balrog
}
240 7c23b892 balrog
241 7c23b892 balrog
static uint32_t
242 7c23b892 balrog
get_eecd(E1000State *s, int index)
243 7c23b892 balrog
{
244 7c23b892 balrog
    uint32_t ret = E1000_EECD_PRES|E1000_EECD_GNT | s->eecd_state.old_eecd;
245 7c23b892 balrog
246 7c23b892 balrog
    DBGOUT(EEPROM, "reading eeprom bit %d (reading %d)\n",
247 7c23b892 balrog
           s->eecd_state.bitnum_out, s->eecd_state.reading);
248 7c23b892 balrog
    if (!s->eecd_state.reading ||
249 7c23b892 balrog
        ((s->eeprom_data[(s->eecd_state.bitnum_out >> 4) & 0x3f] >>
250 7c23b892 balrog
          ((s->eecd_state.bitnum_out & 0xf) ^ 0xf))) & 1)
251 7c23b892 balrog
        ret |= E1000_EECD_DO;
252 7c23b892 balrog
    return ret;
253 7c23b892 balrog
}
254 7c23b892 balrog
255 7c23b892 balrog
static void
256 7c23b892 balrog
set_eecd(E1000State *s, int index, uint32_t val)
257 7c23b892 balrog
{
258 7c23b892 balrog
    uint32_t oldval = s->eecd_state.old_eecd;
259 7c23b892 balrog
260 7c23b892 balrog
    s->eecd_state.old_eecd = val & (E1000_EECD_SK | E1000_EECD_CS |
261 7c23b892 balrog
            E1000_EECD_DI|E1000_EECD_FWE_MASK|E1000_EECD_REQ);
262 7c23b892 balrog
    if (!(E1000_EECD_SK & (val ^ oldval)))        // no clock edge
263 7c23b892 balrog
        return;
264 7c23b892 balrog
    if (!(E1000_EECD_SK & val)) {                // falling edge
265 7c23b892 balrog
        s->eecd_state.bitnum_out++;
266 7c23b892 balrog
        return;
267 7c23b892 balrog
    }
268 7c23b892 balrog
    if (!(val & E1000_EECD_CS)) {                // rising, no CS (EEPROM reset)
269 7c23b892 balrog
        memset(&s->eecd_state, 0, sizeof s->eecd_state);
270 356c7ff4 Naphtali Sprei
        /*
271 356c7ff4 Naphtali Sprei
         * restore old_eecd's E1000_EECD_SK (known to be on)
272 356c7ff4 Naphtali Sprei
         * to avoid false detection of a clock edge
273 356c7ff4 Naphtali Sprei
         */
274 356c7ff4 Naphtali Sprei
        s->eecd_state.old_eecd = E1000_EECD_SK;
275 7c23b892 balrog
        return;
276 7c23b892 balrog
    }
277 7c23b892 balrog
    s->eecd_state.val_in <<= 1;
278 7c23b892 balrog
    if (val & E1000_EECD_DI)
279 7c23b892 balrog
        s->eecd_state.val_in |= 1;
280 7c23b892 balrog
    if (++s->eecd_state.bitnum_in == 9 && !s->eecd_state.reading) {
281 7c23b892 balrog
        s->eecd_state.bitnum_out = ((s->eecd_state.val_in & 0x3f)<<4)-1;
282 7c23b892 balrog
        s->eecd_state.reading = (((s->eecd_state.val_in >> 6) & 7) ==
283 7c23b892 balrog
            EEPROM_READ_OPCODE_MICROWIRE);
284 7c23b892 balrog
    }
285 7c23b892 balrog
    DBGOUT(EEPROM, "eeprom bitnum in %d out %d, reading %d\n",
286 7c23b892 balrog
           s->eecd_state.bitnum_in, s->eecd_state.bitnum_out,
287 7c23b892 balrog
           s->eecd_state.reading);
288 7c23b892 balrog
}
289 7c23b892 balrog
290 7c23b892 balrog
static uint32_t
291 7c23b892 balrog
flash_eerd_read(E1000State *s, int x)
292 7c23b892 balrog
{
293 7c23b892 balrog
    unsigned int index, r = s->mac_reg[EERD] & ~E1000_EEPROM_RW_REG_START;
294 7c23b892 balrog
295 b1332393 Bill Paul
    if ((s->mac_reg[EERD] & E1000_EEPROM_RW_REG_START) == 0)
296 b1332393 Bill Paul
        return (s->mac_reg[EERD]);
297 b1332393 Bill Paul
298 7c23b892 balrog
    if ((index = r >> E1000_EEPROM_RW_ADDR_SHIFT) > EEPROM_CHECKSUM_REG)
299 b1332393 Bill Paul
        return (E1000_EEPROM_RW_REG_DONE | r);
300 b1332393 Bill Paul
301 b1332393 Bill Paul
    return ((s->eeprom_data[index] << E1000_EEPROM_RW_REG_DATA) |
302 b1332393 Bill Paul
           E1000_EEPROM_RW_REG_DONE | r);
303 7c23b892 balrog
}
304 7c23b892 balrog
305 7c23b892 balrog
static void
306 7c23b892 balrog
putsum(uint8_t *data, uint32_t n, uint32_t sloc, uint32_t css, uint32_t cse)
307 7c23b892 balrog
{
308 c6a6a5e3 aliguori
    uint32_t sum;
309 c6a6a5e3 aliguori
310 7c23b892 balrog
    if (cse && cse < n)
311 7c23b892 balrog
        n = cse + 1;
312 c6a6a5e3 aliguori
    if (sloc < n-1) {
313 c6a6a5e3 aliguori
        sum = net_checksum_add(n-css, data+css);
314 7c23b892 balrog
        cpu_to_be16wu((uint16_t *)(data + sloc),
315 c6a6a5e3 aliguori
                      net_checksum_finish(sum));
316 c6a6a5e3 aliguori
    }
317 7c23b892 balrog
}
318 7c23b892 balrog
319 8f2e8d1f aliguori
static inline int
320 8f2e8d1f aliguori
vlan_enabled(E1000State *s)
321 8f2e8d1f aliguori
{
322 8f2e8d1f aliguori
    return ((s->mac_reg[CTRL] & E1000_CTRL_VME) != 0);
323 8f2e8d1f aliguori
}
324 8f2e8d1f aliguori
325 8f2e8d1f aliguori
static inline int
326 8f2e8d1f aliguori
vlan_rx_filter_enabled(E1000State *s)
327 8f2e8d1f aliguori
{
328 8f2e8d1f aliguori
    return ((s->mac_reg[RCTL] & E1000_RCTL_VFE) != 0);
329 8f2e8d1f aliguori
}
330 8f2e8d1f aliguori
331 8f2e8d1f aliguori
static inline int
332 8f2e8d1f aliguori
is_vlan_packet(E1000State *s, const uint8_t *buf)
333 8f2e8d1f aliguori
{
334 8f2e8d1f aliguori
    return (be16_to_cpup((uint16_t *)(buf + 12)) ==
335 8f2e8d1f aliguori
                le16_to_cpup((uint16_t *)(s->mac_reg + VET)));
336 8f2e8d1f aliguori
}
337 8f2e8d1f aliguori
338 8f2e8d1f aliguori
static inline int
339 8f2e8d1f aliguori
is_vlan_txd(uint32_t txd_lower)
340 8f2e8d1f aliguori
{
341 8f2e8d1f aliguori
    return ((txd_lower & E1000_TXD_CMD_VLE) != 0);
342 8f2e8d1f aliguori
}
343 8f2e8d1f aliguori
344 7c23b892 balrog
static void
345 7c23b892 balrog
xmit_seg(E1000State *s)
346 7c23b892 balrog
{
347 7c23b892 balrog
    uint16_t len, *sp;
348 7c23b892 balrog
    unsigned int frames = s->tx.tso_frames, css, sofar, n;
349 7c23b892 balrog
    struct e1000_tx *tp = &s->tx;
350 7c23b892 balrog
351 1b0009db balrog
    if (tp->tse && tp->cptse) {
352 7c23b892 balrog
        css = tp->ipcss;
353 7c23b892 balrog
        DBGOUT(TXSUM, "frames %d size %d ipcss %d\n",
354 7c23b892 balrog
               frames, tp->size, css);
355 7c23b892 balrog
        if (tp->ip) {                // IPv4
356 7c23b892 balrog
            cpu_to_be16wu((uint16_t *)(tp->data+css+2),
357 7c23b892 balrog
                          tp->size - css);
358 7c23b892 balrog
            cpu_to_be16wu((uint16_t *)(tp->data+css+4),
359 7c23b892 balrog
                          be16_to_cpup((uint16_t *)(tp->data+css+4))+frames);
360 7c23b892 balrog
        } else                        // IPv6
361 7c23b892 balrog
            cpu_to_be16wu((uint16_t *)(tp->data+css+4),
362 7c23b892 balrog
                          tp->size - css);
363 7c23b892 balrog
        css = tp->tucss;
364 7c23b892 balrog
        len = tp->size - css;
365 7c23b892 balrog
        DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", tp->tcp, css, len);
366 7c23b892 balrog
        if (tp->tcp) {
367 7c23b892 balrog
            sofar = frames * tp->mss;
368 7c23b892 balrog
            cpu_to_be32wu((uint32_t *)(tp->data+css+4),        // seq
369 88738c09 aurel32
                be32_to_cpupu((uint32_t *)(tp->data+css+4))+sofar);
370 7c23b892 balrog
            if (tp->paylen - sofar > tp->mss)
371 7c23b892 balrog
                tp->data[css + 13] &= ~9;                // PSH, FIN
372 7c23b892 balrog
        } else        // UDP
373 7c23b892 balrog
            cpu_to_be16wu((uint16_t *)(tp->data+css+4), len);
374 7c23b892 balrog
        if (tp->sum_needed & E1000_TXD_POPTS_TXSM) {
375 7c23b892 balrog
            // add pseudo-header length before checksum calculation
376 7c23b892 balrog
            sp = (uint16_t *)(tp->data + tp->tucso);
377 7c23b892 balrog
            cpu_to_be16wu(sp, be16_to_cpup(sp) + len);
378 7c23b892 balrog
        }
379 7c23b892 balrog
        tp->tso_frames++;
380 7c23b892 balrog
    }
381 7c23b892 balrog
382 7c23b892 balrog
    if (tp->sum_needed & E1000_TXD_POPTS_TXSM)
383 7c23b892 balrog
        putsum(tp->data, tp->size, tp->tucso, tp->tucss, tp->tucse);
384 7c23b892 balrog
    if (tp->sum_needed & E1000_TXD_POPTS_IXSM)
385 7c23b892 balrog
        putsum(tp->data, tp->size, tp->ipcso, tp->ipcss, tp->ipcse);
386 8f2e8d1f aliguori
    if (tp->vlan_needed) {
387 b10fec9b Stefan Weil
        memmove(tp->vlan, tp->data, 4);
388 b10fec9b Stefan Weil
        memmove(tp->data, tp->data + 4, 8);
389 8f2e8d1f aliguori
        memcpy(tp->data + 8, tp->vlan_header, 4);
390 a03e2aec Mark McLoughlin
        qemu_send_packet(&s->nic->nc, tp->vlan, tp->size + 4);
391 8f2e8d1f aliguori
    } else
392 a03e2aec Mark McLoughlin
        qemu_send_packet(&s->nic->nc, tp->data, tp->size);
393 7c23b892 balrog
    s->mac_reg[TPT]++;
394 7c23b892 balrog
    s->mac_reg[GPTC]++;
395 7c23b892 balrog
    n = s->mac_reg[TOTL];
396 7c23b892 balrog
    if ((s->mac_reg[TOTL] += s->tx.size) < n)
397 7c23b892 balrog
        s->mac_reg[TOTH]++;
398 7c23b892 balrog
}
399 7c23b892 balrog
400 7c23b892 balrog
static void
401 7c23b892 balrog
process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
402 7c23b892 balrog
{
403 7c23b892 balrog
    uint32_t txd_lower = le32_to_cpu(dp->lower.data);
404 7c23b892 balrog
    uint32_t dtype = txd_lower & (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D);
405 7c23b892 balrog
    unsigned int split_size = txd_lower & 0xffff, bytes, sz, op;
406 7c23b892 balrog
    unsigned int msh = 0xfffff, hdr = 0;
407 7c23b892 balrog
    uint64_t addr;
408 7c23b892 balrog
    struct e1000_context_desc *xp = (struct e1000_context_desc *)dp;
409 7c23b892 balrog
    struct e1000_tx *tp = &s->tx;
410 7c23b892 balrog
411 7c23b892 balrog
    if (dtype == E1000_TXD_CMD_DEXT) {        // context descriptor
412 7c23b892 balrog
        op = le32_to_cpu(xp->cmd_and_length);
413 7c23b892 balrog
        tp->ipcss = xp->lower_setup.ip_fields.ipcss;
414 7c23b892 balrog
        tp->ipcso = xp->lower_setup.ip_fields.ipcso;
415 7c23b892 balrog
        tp->ipcse = le16_to_cpu(xp->lower_setup.ip_fields.ipcse);
416 7c23b892 balrog
        tp->tucss = xp->upper_setup.tcp_fields.tucss;
417 7c23b892 balrog
        tp->tucso = xp->upper_setup.tcp_fields.tucso;
418 7c23b892 balrog
        tp->tucse = le16_to_cpu(xp->upper_setup.tcp_fields.tucse);
419 7c23b892 balrog
        tp->paylen = op & 0xfffff;
420 7c23b892 balrog
        tp->hdr_len = xp->tcp_seg_setup.fields.hdr_len;
421 7c23b892 balrog
        tp->mss = le16_to_cpu(xp->tcp_seg_setup.fields.mss);
422 7c23b892 balrog
        tp->ip = (op & E1000_TXD_CMD_IP) ? 1 : 0;
423 7c23b892 balrog
        tp->tcp = (op & E1000_TXD_CMD_TCP) ? 1 : 0;
424 7c23b892 balrog
        tp->tse = (op & E1000_TXD_CMD_TSE) ? 1 : 0;
425 7c23b892 balrog
        tp->tso_frames = 0;
426 7c23b892 balrog
        if (tp->tucso == 0) {        // this is probably wrong
427 7c23b892 balrog
            DBGOUT(TXSUM, "TCP/UDP: cso 0!\n");
428 7c23b892 balrog
            tp->tucso = tp->tucss + (tp->tcp ? 16 : 6);
429 7c23b892 balrog
        }
430 7c23b892 balrog
        return;
431 1b0009db balrog
    } else if (dtype == (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D)) {
432 1b0009db balrog
        // data descriptor
433 7c23b892 balrog
        tp->sum_needed = le32_to_cpu(dp->upper.data) >> 8;
434 1b0009db balrog
        tp->cptse = ( txd_lower & E1000_TXD_CMD_TSE ) ? 1 : 0;
435 1b0009db balrog
    } else
436 1b0009db balrog
        // legacy descriptor
437 1b0009db balrog
        tp->cptse = 0;
438 7c23b892 balrog
439 8f2e8d1f aliguori
    if (vlan_enabled(s) && is_vlan_txd(txd_lower) &&
440 8f2e8d1f aliguori
        (tp->cptse || txd_lower & E1000_TXD_CMD_EOP)) {
441 8f2e8d1f aliguori
        tp->vlan_needed = 1;
442 8f2e8d1f aliguori
        cpu_to_be16wu((uint16_t *)(tp->vlan_header),
443 8f2e8d1f aliguori
                      le16_to_cpup((uint16_t *)(s->mac_reg + VET)));
444 8f2e8d1f aliguori
        cpu_to_be16wu((uint16_t *)(tp->vlan_header + 2),
445 8f2e8d1f aliguori
                      le16_to_cpu(dp->upper.fields.special));
446 8f2e8d1f aliguori
    }
447 8f2e8d1f aliguori
        
448 7c23b892 balrog
    addr = le64_to_cpu(dp->buffer_addr);
449 1b0009db balrog
    if (tp->tse && tp->cptse) {
450 7c23b892 balrog
        hdr = tp->hdr_len;
451 7c23b892 balrog
        msh = hdr + tp->mss;
452 1b0009db balrog
        do {
453 1b0009db balrog
            bytes = split_size;
454 1b0009db balrog
            if (tp->size + bytes > msh)
455 1b0009db balrog
                bytes = msh - tp->size;
456 1b0009db balrog
            cpu_physical_memory_read(addr, tp->data + tp->size, bytes);
457 1b0009db balrog
            if ((sz = tp->size + bytes) >= hdr && tp->size < hdr)
458 1b0009db balrog
                memmove(tp->header, tp->data, hdr);
459 1b0009db balrog
            tp->size = sz;
460 1b0009db balrog
            addr += bytes;
461 1b0009db balrog
            if (sz == msh) {
462 1b0009db balrog
                xmit_seg(s);
463 1b0009db balrog
                memmove(tp->data, tp->header, hdr);
464 1b0009db balrog
                tp->size = hdr;
465 1b0009db balrog
            }
466 1b0009db balrog
        } while (split_size -= bytes);
467 1b0009db balrog
    } else if (!tp->tse && tp->cptse) {
468 1b0009db balrog
        // context descriptor TSE is not set, while data descriptor TSE is set
469 1b0009db balrog
        DBGOUT(TXERR, "TCP segmentaion Error\n");
470 1b0009db balrog
    } else {
471 1b0009db balrog
        cpu_physical_memory_read(addr, tp->data + tp->size, split_size);
472 1b0009db balrog
        tp->size += split_size;
473 7c23b892 balrog
    }
474 7c23b892 balrog
475 7c23b892 balrog
    if (!(txd_lower & E1000_TXD_CMD_EOP))
476 7c23b892 balrog
        return;
477 1b0009db balrog
    if (!(tp->tse && tp->cptse && tp->size < hdr))
478 7c23b892 balrog
        xmit_seg(s);
479 7c23b892 balrog
    tp->tso_frames = 0;
480 7c23b892 balrog
    tp->sum_needed = 0;
481 8f2e8d1f aliguori
    tp->vlan_needed = 0;
482 7c23b892 balrog
    tp->size = 0;
483 1b0009db balrog
    tp->cptse = 0;
484 7c23b892 balrog
}
485 7c23b892 balrog
486 7c23b892 balrog
static uint32_t
487 c227f099 Anthony Liguori
txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp)
488 7c23b892 balrog
{
489 7c23b892 balrog
    uint32_t txd_upper, txd_lower = le32_to_cpu(dp->lower.data);
490 7c23b892 balrog
491 7c23b892 balrog
    if (!(txd_lower & (E1000_TXD_CMD_RS|E1000_TXD_CMD_RPS)))
492 7c23b892 balrog
        return 0;
493 7c23b892 balrog
    txd_upper = (le32_to_cpu(dp->upper.data) | E1000_TXD_STAT_DD) &
494 7c23b892 balrog
                ~(E1000_TXD_STAT_EC | E1000_TXD_STAT_LC | E1000_TXD_STAT_TU);
495 7c23b892 balrog
    dp->upper.data = cpu_to_le32(txd_upper);
496 7c23b892 balrog
    cpu_physical_memory_write(base + ((char *)&dp->upper - (char *)dp),
497 7c23b892 balrog
                              (void *)&dp->upper, sizeof(dp->upper));
498 7c23b892 balrog
    return E1000_ICR_TXDW;
499 7c23b892 balrog
}
500 7c23b892 balrog
501 7c23b892 balrog
static void
502 7c23b892 balrog
start_xmit(E1000State *s)
503 7c23b892 balrog
{
504 c227f099 Anthony Liguori
    target_phys_addr_t base;
505 7c23b892 balrog
    struct e1000_tx_desc desc;
506 7c23b892 balrog
    uint32_t tdh_start = s->mac_reg[TDH], cause = E1000_ICS_TXQE;
507 7c23b892 balrog
508 7c23b892 balrog
    if (!(s->mac_reg[TCTL] & E1000_TCTL_EN)) {
509 7c23b892 balrog
        DBGOUT(TX, "tx disabled\n");
510 7c23b892 balrog
        return;
511 7c23b892 balrog
    }
512 7c23b892 balrog
513 7c23b892 balrog
    while (s->mac_reg[TDH] != s->mac_reg[TDT]) {
514 7c23b892 balrog
        base = ((uint64_t)s->mac_reg[TDBAH] << 32) + s->mac_reg[TDBAL] +
515 7c23b892 balrog
               sizeof(struct e1000_tx_desc) * s->mac_reg[TDH];
516 7c23b892 balrog
        cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
517 7c23b892 balrog
518 7c23b892 balrog
        DBGOUT(TX, "index %d: %p : %x %x\n", s->mac_reg[TDH],
519 6106075b ths
               (void *)(intptr_t)desc.buffer_addr, desc.lower.data,
520 7c23b892 balrog
               desc.upper.data);
521 7c23b892 balrog
522 7c23b892 balrog
        process_tx_desc(s, &desc);
523 7c23b892 balrog
        cause |= txdesc_writeback(base, &desc);
524 7c23b892 balrog
525 7c23b892 balrog
        if (++s->mac_reg[TDH] * sizeof(desc) >= s->mac_reg[TDLEN])
526 7c23b892 balrog
            s->mac_reg[TDH] = 0;
527 7c23b892 balrog
        /*
528 7c23b892 balrog
         * the following could happen only if guest sw assigns
529 7c23b892 balrog
         * bogus values to TDT/TDLEN.
530 7c23b892 balrog
         * there's nothing too intelligent we could do about this.
531 7c23b892 balrog
         */
532 7c23b892 balrog
        if (s->mac_reg[TDH] == tdh_start) {
533 7c23b892 balrog
            DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n",
534 7c23b892 balrog
                   tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]);
535 7c23b892 balrog
            break;
536 7c23b892 balrog
        }
537 7c23b892 balrog
    }
538 7c23b892 balrog
    set_ics(s, 0, cause);
539 7c23b892 balrog
}
540 7c23b892 balrog
541 7c23b892 balrog
static int
542 7c23b892 balrog
receive_filter(E1000State *s, const uint8_t *buf, int size)
543 7c23b892 balrog
{
544 7c23b892 balrog
    static uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
545 7c23b892 balrog
    static int mta_shift[] = {4, 3, 2, 0};
546 7c23b892 balrog
    uint32_t f, rctl = s->mac_reg[RCTL], ra[2], *rp;
547 7c23b892 balrog
548 8f2e8d1f aliguori
    if (is_vlan_packet(s, buf) && vlan_rx_filter_enabled(s)) {
549 8f2e8d1f aliguori
        uint16_t vid = be16_to_cpup((uint16_t *)(buf + 14));
550 8f2e8d1f aliguori
        uint32_t vfta = le32_to_cpup((uint32_t *)(s->mac_reg + VFTA) +
551 8f2e8d1f aliguori
                                     ((vid >> 5) & 0x7f));
552 8f2e8d1f aliguori
        if ((vfta & (1 << (vid & 0x1f))) == 0)
553 8f2e8d1f aliguori
            return 0;
554 8f2e8d1f aliguori
    }
555 8f2e8d1f aliguori
556 7c23b892 balrog
    if (rctl & E1000_RCTL_UPE)                        // promiscuous
557 7c23b892 balrog
        return 1;
558 7c23b892 balrog
559 7c23b892 balrog
    if ((buf[0] & 1) && (rctl & E1000_RCTL_MPE))        // promiscuous mcast
560 7c23b892 balrog
        return 1;
561 7c23b892 balrog
562 7c23b892 balrog
    if ((rctl & E1000_RCTL_BAM) && !memcmp(buf, bcast, sizeof bcast))
563 7c23b892 balrog
        return 1;
564 7c23b892 balrog
565 7c23b892 balrog
    for (rp = s->mac_reg + RA; rp < s->mac_reg + RA + 32; rp += 2) {
566 7c23b892 balrog
        if (!(rp[1] & E1000_RAH_AV))
567 7c23b892 balrog
            continue;
568 7c23b892 balrog
        ra[0] = cpu_to_le32(rp[0]);
569 7c23b892 balrog
        ra[1] = cpu_to_le32(rp[1]);
570 7c23b892 balrog
        if (!memcmp(buf, (uint8_t *)ra, 6)) {
571 7c23b892 balrog
            DBGOUT(RXFILTER,
572 7c23b892 balrog
                   "unicast match[%d]: %02x:%02x:%02x:%02x:%02x:%02x\n",
573 7c23b892 balrog
                   (int)(rp - s->mac_reg - RA)/2,
574 7c23b892 balrog
                   buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
575 7c23b892 balrog
            return 1;
576 7c23b892 balrog
        }
577 7c23b892 balrog
    }
578 7c23b892 balrog
    DBGOUT(RXFILTER, "unicast mismatch: %02x:%02x:%02x:%02x:%02x:%02x\n",
579 7c23b892 balrog
           buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
580 7c23b892 balrog
581 7c23b892 balrog
    f = mta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3];
582 7c23b892 balrog
    f = (((buf[5] << 8) | buf[4]) >> f) & 0xfff;
583 7c23b892 balrog
    if (s->mac_reg[MTA + (f >> 5)] & (1 << (f & 0x1f)))
584 7c23b892 balrog
        return 1;
585 7c23b892 balrog
    DBGOUT(RXFILTER,
586 7c23b892 balrog
           "dropping, inexact filter mismatch: %02x:%02x:%02x:%02x:%02x:%02x MO %d MTA[%d] %x\n",
587 7c23b892 balrog
           buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
588 7c23b892 balrog
           (rctl >> E1000_RCTL_MO_SHIFT) & 3, f >> 5,
589 7c23b892 balrog
           s->mac_reg[MTA + (f >> 5)]);
590 7c23b892 balrog
591 7c23b892 balrog
    return 0;
592 7c23b892 balrog
}
593 7c23b892 balrog
594 99ed7e30 aliguori
static void
595 a03e2aec Mark McLoughlin
e1000_set_link_status(VLANClientState *nc)
596 99ed7e30 aliguori
{
597 a03e2aec Mark McLoughlin
    E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
598 99ed7e30 aliguori
    uint32_t old_status = s->mac_reg[STATUS];
599 99ed7e30 aliguori
600 a03e2aec Mark McLoughlin
    if (nc->link_down)
601 99ed7e30 aliguori
        s->mac_reg[STATUS] &= ~E1000_STATUS_LU;
602 99ed7e30 aliguori
    else
603 99ed7e30 aliguori
        s->mac_reg[STATUS] |= E1000_STATUS_LU;
604 99ed7e30 aliguori
605 99ed7e30 aliguori
    if (s->mac_reg[STATUS] != old_status)
606 99ed7e30 aliguori
        set_ics(s, 0, E1000_ICR_LSC);
607 99ed7e30 aliguori
}
608 99ed7e30 aliguori
609 7c23b892 balrog
static int
610 a03e2aec Mark McLoughlin
e1000_can_receive(VLANClientState *nc)
611 7c23b892 balrog
{
612 a03e2aec Mark McLoughlin
    E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
613 7c23b892 balrog
614 4105de67 aliguori
    return (s->mac_reg[RCTL] & E1000_RCTL_EN);
615 7c23b892 balrog
}
616 7c23b892 balrog
617 4f1c942b Mark McLoughlin
static ssize_t
618 a03e2aec Mark McLoughlin
e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
619 7c23b892 balrog
{
620 a03e2aec Mark McLoughlin
    E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
621 7c23b892 balrog
    struct e1000_rx_desc desc;
622 c227f099 Anthony Liguori
    target_phys_addr_t base;
623 7c23b892 balrog
    unsigned int n, rdt;
624 7c23b892 balrog
    uint32_t rdh_start;
625 8f2e8d1f aliguori
    uint16_t vlan_special = 0;
626 8f2e8d1f aliguori
    uint8_t vlan_status = 0, vlan_offset = 0;
627 7c23b892 balrog
628 7c23b892 balrog
    if (!(s->mac_reg[RCTL] & E1000_RCTL_EN))
629 4f1c942b Mark McLoughlin
        return -1;
630 7c23b892 balrog
631 7c23b892 balrog
    if (size > s->rxbuf_size) {
632 cda9046b Mark McLoughlin
        DBGOUT(RX, "packet too large for buffers (%lu > %d)\n",
633 cda9046b Mark McLoughlin
               (unsigned long)size, s->rxbuf_size);
634 4f1c942b Mark McLoughlin
        return -1;
635 7c23b892 balrog
    }
636 7c23b892 balrog
637 7c23b892 balrog
    if (!receive_filter(s, buf, size))
638 4f1c942b Mark McLoughlin
        return size;
639 7c23b892 balrog
640 8f2e8d1f aliguori
    if (vlan_enabled(s) && is_vlan_packet(s, buf)) {
641 8f2e8d1f aliguori
        vlan_special = cpu_to_le16(be16_to_cpup((uint16_t *)(buf + 14)));
642 8f2e8d1f aliguori
        memmove((void *)(buf + 4), buf, 12);
643 8f2e8d1f aliguori
        vlan_status = E1000_RXD_STAT_VP;
644 8f2e8d1f aliguori
        vlan_offset = 4;
645 8f2e8d1f aliguori
        size -= 4;
646 8f2e8d1f aliguori
    }
647 8f2e8d1f aliguori
648 7c23b892 balrog
    rdh_start = s->mac_reg[RDH];
649 7c23b892 balrog
    size += 4; // for the header
650 7c23b892 balrog
    do {
651 7c23b892 balrog
        if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
652 7c23b892 balrog
            set_ics(s, 0, E1000_ICS_RXO);
653 4f1c942b Mark McLoughlin
            return -1;
654 7c23b892 balrog
        }
655 7c23b892 balrog
        base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +
656 7c23b892 balrog
               sizeof(desc) * s->mac_reg[RDH];
657 7c23b892 balrog
        cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
658 8f2e8d1f aliguori
        desc.special = vlan_special;
659 8f2e8d1f aliguori
        desc.status |= (vlan_status | E1000_RXD_STAT_DD);
660 7c23b892 balrog
        if (desc.buffer_addr) {
661 7c23b892 balrog
            cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr),
662 8f2e8d1f aliguori
                                      (void *)(buf + vlan_offset), size);
663 7c23b892 balrog
            desc.length = cpu_to_le16(size);
664 7c23b892 balrog
            desc.status |= E1000_RXD_STAT_EOP|E1000_RXD_STAT_IXSM;
665 7c23b892 balrog
        } else // as per intel docs; skip descriptors with null buf addr
666 7c23b892 balrog
            DBGOUT(RX, "Null RX descriptor!!\n");
667 7c23b892 balrog
        cpu_physical_memory_write(base, (void *)&desc, sizeof(desc));
668 7c23b892 balrog
669 7c23b892 balrog
        if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
670 7c23b892 balrog
            s->mac_reg[RDH] = 0;
671 7c23b892 balrog
        s->check_rxov = 1;
672 7c23b892 balrog
        /* see comment in start_xmit; same here */
673 7c23b892 balrog
        if (s->mac_reg[RDH] == rdh_start) {
674 7c23b892 balrog
            DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
675 7c23b892 balrog
                   rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
676 7c23b892 balrog
            set_ics(s, 0, E1000_ICS_RXO);
677 4f1c942b Mark McLoughlin
            return -1;
678 7c23b892 balrog
        }
679 7c23b892 balrog
    } while (desc.buffer_addr == 0);
680 7c23b892 balrog
681 7c23b892 balrog
    s->mac_reg[GPRC]++;
682 7c23b892 balrog
    s->mac_reg[TPR]++;
683 7c23b892 balrog
    n = s->mac_reg[TORL];
684 7c23b892 balrog
    if ((s->mac_reg[TORL] += size) < n)
685 7c23b892 balrog
        s->mac_reg[TORH]++;
686 7c23b892 balrog
687 7c23b892 balrog
    n = E1000_ICS_RXT0;
688 7c23b892 balrog
    if ((rdt = s->mac_reg[RDT]) < s->mac_reg[RDH])
689 7c23b892 balrog
        rdt += s->mac_reg[RDLEN] / sizeof(desc);
690 bf16cc8f aliguori
    if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) <= s->mac_reg[RDLEN] >>
691 bf16cc8f aliguori
        s->rxbuf_min_shift)
692 7c23b892 balrog
        n |= E1000_ICS_RXDMT0;
693 7c23b892 balrog
694 7c23b892 balrog
    set_ics(s, 0, n);
695 4f1c942b Mark McLoughlin
696 4f1c942b Mark McLoughlin
    return size;
697 7c23b892 balrog
}
698 7c23b892 balrog
699 7c23b892 balrog
static uint32_t
700 7c23b892 balrog
mac_readreg(E1000State *s, int index)
701 7c23b892 balrog
{
702 7c23b892 balrog
    return s->mac_reg[index];
703 7c23b892 balrog
}
704 7c23b892 balrog
705 7c23b892 balrog
static uint32_t
706 7c23b892 balrog
mac_icr_read(E1000State *s, int index)
707 7c23b892 balrog
{
708 7c23b892 balrog
    uint32_t ret = s->mac_reg[ICR];
709 7c23b892 balrog
710 7c23b892 balrog
    DBGOUT(INTERRUPT, "ICR read: %x\n", ret);
711 7c23b892 balrog
    set_interrupt_cause(s, 0, 0);
712 7c23b892 balrog
    return ret;
713 7c23b892 balrog
}
714 7c23b892 balrog
715 7c23b892 balrog
static uint32_t
716 7c23b892 balrog
mac_read_clr4(E1000State *s, int index)
717 7c23b892 balrog
{
718 7c23b892 balrog
    uint32_t ret = s->mac_reg[index];
719 7c23b892 balrog
720 7c23b892 balrog
    s->mac_reg[index] = 0;
721 7c23b892 balrog
    return ret;
722 7c23b892 balrog
}
723 7c23b892 balrog
724 7c23b892 balrog
static uint32_t
725 7c23b892 balrog
mac_read_clr8(E1000State *s, int index)
726 7c23b892 balrog
{
727 7c23b892 balrog
    uint32_t ret = s->mac_reg[index];
728 7c23b892 balrog
729 7c23b892 balrog
    s->mac_reg[index] = 0;
730 7c23b892 balrog
    s->mac_reg[index-1] = 0;
731 7c23b892 balrog
    return ret;
732 7c23b892 balrog
}
733 7c23b892 balrog
734 7c23b892 balrog
static void
735 7c23b892 balrog
mac_writereg(E1000State *s, int index, uint32_t val)
736 7c23b892 balrog
{
737 7c23b892 balrog
    s->mac_reg[index] = val;
738 7c23b892 balrog
}
739 7c23b892 balrog
740 7c23b892 balrog
static void
741 7c23b892 balrog
set_rdt(E1000State *s, int index, uint32_t val)
742 7c23b892 balrog
{
743 7c23b892 balrog
    s->check_rxov = 0;
744 7c23b892 balrog
    s->mac_reg[index] = val & 0xffff;
745 7c23b892 balrog
}
746 7c23b892 balrog
747 7c23b892 balrog
static void
748 7c23b892 balrog
set_16bit(E1000State *s, int index, uint32_t val)
749 7c23b892 balrog
{
750 7c23b892 balrog
    s->mac_reg[index] = val & 0xffff;
751 7c23b892 balrog
}
752 7c23b892 balrog
753 7c23b892 balrog
static void
754 7c23b892 balrog
set_dlen(E1000State *s, int index, uint32_t val)
755 7c23b892 balrog
{
756 7c23b892 balrog
    s->mac_reg[index] = val & 0xfff80;
757 7c23b892 balrog
}
758 7c23b892 balrog
759 7c23b892 balrog
static void
760 7c23b892 balrog
set_tctl(E1000State *s, int index, uint32_t val)
761 7c23b892 balrog
{
762 7c23b892 balrog
    s->mac_reg[index] = val;
763 7c23b892 balrog
    s->mac_reg[TDT] &= 0xffff;
764 7c23b892 balrog
    start_xmit(s);
765 7c23b892 balrog
}
766 7c23b892 balrog
767 7c23b892 balrog
static void
768 7c23b892 balrog
set_icr(E1000State *s, int index, uint32_t val)
769 7c23b892 balrog
{
770 7c23b892 balrog
    DBGOUT(INTERRUPT, "set_icr %x\n", val);
771 7c23b892 balrog
    set_interrupt_cause(s, 0, s->mac_reg[ICR] & ~val);
772 7c23b892 balrog
}
773 7c23b892 balrog
774 7c23b892 balrog
static void
775 7c23b892 balrog
set_imc(E1000State *s, int index, uint32_t val)
776 7c23b892 balrog
{
777 7c23b892 balrog
    s->mac_reg[IMS] &= ~val;
778 7c23b892 balrog
    set_ics(s, 0, 0);
779 7c23b892 balrog
}
780 7c23b892 balrog
781 7c23b892 balrog
static void
782 7c23b892 balrog
set_ims(E1000State *s, int index, uint32_t val)
783 7c23b892 balrog
{
784 7c23b892 balrog
    s->mac_reg[IMS] |= val;
785 7c23b892 balrog
    set_ics(s, 0, 0);
786 7c23b892 balrog
}
787 7c23b892 balrog
788 7c23b892 balrog
#define getreg(x)        [x] = mac_readreg
789 7c23b892 balrog
static uint32_t (*macreg_readops[])(E1000State *, int) = {
790 7c23b892 balrog
    getreg(PBA),        getreg(RCTL),        getreg(TDH),        getreg(TXDCTL),
791 7c23b892 balrog
    getreg(WUFC),        getreg(TDT),        getreg(CTRL),        getreg(LEDCTL),
792 7c23b892 balrog
    getreg(MANC),        getreg(MDIC),        getreg(SWSM),        getreg(STATUS),
793 7c23b892 balrog
    getreg(TORL),        getreg(TOTL),        getreg(IMS),        getreg(TCTL),
794 b1332393 Bill Paul
    getreg(RDH),        getreg(RDT),        getreg(VET),        getreg(ICS),
795 a00b2335 Kay Ackermann
    getreg(TDBAL),        getreg(TDBAH),        getreg(RDBAH),        getreg(RDBAL),
796 a00b2335 Kay Ackermann
    getreg(TDLEN),        getreg(RDLEN),
797 7c23b892 balrog
798 7c23b892 balrog
    [TOTH] = mac_read_clr8,        [TORH] = mac_read_clr8,        [GPRC] = mac_read_clr4,
799 7c23b892 balrog
    [GPTC] = mac_read_clr4,        [TPR] = mac_read_clr4,        [TPT] = mac_read_clr4,
800 7c23b892 balrog
    [ICR] = mac_icr_read,        [EECD] = get_eecd,        [EERD] = flash_eerd_read,
801 7c23b892 balrog
    [CRCERRS ... MPC] = &mac_readreg,
802 7c23b892 balrog
    [RA ... RA+31] = &mac_readreg,
803 7c23b892 balrog
    [MTA ... MTA+127] = &mac_readreg,
804 8f2e8d1f aliguori
    [VFTA ... VFTA+127] = &mac_readreg,
805 7c23b892 balrog
};
806 b1503cda malc
enum { NREADOPS = ARRAY_SIZE(macreg_readops) };
807 7c23b892 balrog
808 7c23b892 balrog
#define putreg(x)        [x] = mac_writereg
809 7c23b892 balrog
static void (*macreg_writeops[])(E1000State *, int, uint32_t) = {
810 7c23b892 balrog
    putreg(PBA),        putreg(EERD),        putreg(SWSM),        putreg(WUFC),
811 7c23b892 balrog
    putreg(TDBAL),        putreg(TDBAH),        putreg(TXDCTL),        putreg(RDBAH),
812 cab3c825 Kevin Wolf
    putreg(RDBAL),        putreg(LEDCTL), putreg(VET),
813 7c23b892 balrog
    [TDLEN] = set_dlen,        [RDLEN] = set_dlen,        [TCTL] = set_tctl,
814 7c23b892 balrog
    [TDT] = set_tctl,        [MDIC] = set_mdic,        [ICS] = set_ics,
815 7c23b892 balrog
    [TDH] = set_16bit,        [RDH] = set_16bit,        [RDT] = set_rdt,
816 7c23b892 balrog
    [IMC] = set_imc,        [IMS] = set_ims,        [ICR] = set_icr,
817 cab3c825 Kevin Wolf
    [EECD] = set_eecd,        [RCTL] = set_rx_control, [CTRL] = set_ctrl,
818 7c23b892 balrog
    [RA ... RA+31] = &mac_writereg,
819 7c23b892 balrog
    [MTA ... MTA+127] = &mac_writereg,
820 8f2e8d1f aliguori
    [VFTA ... VFTA+127] = &mac_writereg,
821 7c23b892 balrog
};
822 b1503cda malc
enum { NWRITEOPS = ARRAY_SIZE(macreg_writeops) };
823 7c23b892 balrog
824 7c23b892 balrog
static void
825 c227f099 Anthony Liguori
e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
826 7c23b892 balrog
{
827 7c23b892 balrog
    E1000State *s = opaque;
828 8da3ff18 pbrook
    unsigned int index = (addr & 0x1ffff) >> 2;
829 7c23b892 balrog
830 6b59fc74 aurel32
#ifdef TARGET_WORDS_BIGENDIAN
831 6b59fc74 aurel32
    val = bswap32(val);
832 6b59fc74 aurel32
#endif
833 7c23b892 balrog
    if (index < NWRITEOPS && macreg_writeops[index])
834 6b59fc74 aurel32
        macreg_writeops[index](s, index, val);
835 7c23b892 balrog
    else if (index < NREADOPS && macreg_readops[index])
836 7c23b892 balrog
        DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val);
837 7c23b892 balrog
    else
838 7c23b892 balrog
        DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08x\n",
839 7c23b892 balrog
               index<<2, val);
840 7c23b892 balrog
}
841 7c23b892 balrog
842 7c23b892 balrog
static void
843 c227f099 Anthony Liguori
e1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
844 7c23b892 balrog
{
845 7c23b892 balrog
    // emulate hw without byte enables: no RMW
846 7c23b892 balrog
    e1000_mmio_writel(opaque, addr & ~3,
847 6b59fc74 aurel32
                      (val & 0xffff) << (8*(addr & 3)));
848 7c23b892 balrog
}
849 7c23b892 balrog
850 7c23b892 balrog
static void
851 c227f099 Anthony Liguori
e1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
852 7c23b892 balrog
{
853 7c23b892 balrog
    // emulate hw without byte enables: no RMW
854 7c23b892 balrog
    e1000_mmio_writel(opaque, addr & ~3,
855 6b59fc74 aurel32
                      (val & 0xff) << (8*(addr & 3)));
856 7c23b892 balrog
}
857 7c23b892 balrog
858 7c23b892 balrog
static uint32_t
859 c227f099 Anthony Liguori
e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
860 7c23b892 balrog
{
861 7c23b892 balrog
    E1000State *s = opaque;
862 8da3ff18 pbrook
    unsigned int index = (addr & 0x1ffff) >> 2;
863 7c23b892 balrog
864 7c23b892 balrog
    if (index < NREADOPS && macreg_readops[index])
865 6b59fc74 aurel32
    {
866 6b59fc74 aurel32
        uint32_t val = macreg_readops[index](s, index);
867 6b59fc74 aurel32
#ifdef TARGET_WORDS_BIGENDIAN
868 6b59fc74 aurel32
        val = bswap32(val);
869 6b59fc74 aurel32
#endif
870 6b59fc74 aurel32
        return val;
871 6b59fc74 aurel32
    }
872 7c23b892 balrog
    DBGOUT(UNKNOWN, "MMIO unknown read addr=0x%08x\n", index<<2);
873 7c23b892 balrog
    return 0;
874 7c23b892 balrog
}
875 7c23b892 balrog
876 7c23b892 balrog
static uint32_t
877 c227f099 Anthony Liguori
e1000_mmio_readb(void *opaque, target_phys_addr_t addr)
878 7c23b892 balrog
{
879 6b59fc74 aurel32
    return ((e1000_mmio_readl(opaque, addr & ~3)) >>
880 7c23b892 balrog
            (8 * (addr & 3))) & 0xff;
881 7c23b892 balrog
}
882 7c23b892 balrog
883 7c23b892 balrog
static uint32_t
884 c227f099 Anthony Liguori
e1000_mmio_readw(void *opaque, target_phys_addr_t addr)
885 7c23b892 balrog
{
886 6b59fc74 aurel32
    return ((e1000_mmio_readl(opaque, addr & ~3)) >>
887 6b59fc74 aurel32
            (8 * (addr & 3))) & 0xffff;
888 7c23b892 balrog
}
889 7c23b892 balrog
890 e482dc3e Juan Quintela
static bool is_version_1(void *opaque, int version_id)
891 7c23b892 balrog
{
892 e482dc3e Juan Quintela
    return version_id == 1;
893 7c23b892 balrog
}
894 7c23b892 balrog
895 e482dc3e Juan Quintela
static const VMStateDescription vmstate_e1000 = {
896 e482dc3e Juan Quintela
    .name = "e1000",
897 e482dc3e Juan Quintela
    .version_id = 2,
898 e482dc3e Juan Quintela
    .minimum_version_id = 1,
899 e482dc3e Juan Quintela
    .minimum_version_id_old = 1,
900 e482dc3e Juan Quintela
    .fields      = (VMStateField []) {
901 e482dc3e Juan Quintela
        VMSTATE_PCI_DEVICE(dev, E1000State),
902 e482dc3e Juan Quintela
        VMSTATE_UNUSED_TEST(is_version_1, 4), /* was instance id */
903 e482dc3e Juan Quintela
        VMSTATE_UNUSED(4), /* Was mmio_base.  */
904 e482dc3e Juan Quintela
        VMSTATE_UINT32(rxbuf_size, E1000State),
905 e482dc3e Juan Quintela
        VMSTATE_UINT32(rxbuf_min_shift, E1000State),
906 e482dc3e Juan Quintela
        VMSTATE_UINT32(eecd_state.val_in, E1000State),
907 e482dc3e Juan Quintela
        VMSTATE_UINT16(eecd_state.bitnum_in, E1000State),
908 e482dc3e Juan Quintela
        VMSTATE_UINT16(eecd_state.bitnum_out, E1000State),
909 e482dc3e Juan Quintela
        VMSTATE_UINT16(eecd_state.reading, E1000State),
910 e482dc3e Juan Quintela
        VMSTATE_UINT32(eecd_state.old_eecd, E1000State),
911 e482dc3e Juan Quintela
        VMSTATE_UINT8(tx.ipcss, E1000State),
912 e482dc3e Juan Quintela
        VMSTATE_UINT8(tx.ipcso, E1000State),
913 e482dc3e Juan Quintela
        VMSTATE_UINT16(tx.ipcse, E1000State),
914 e482dc3e Juan Quintela
        VMSTATE_UINT8(tx.tucss, E1000State),
915 e482dc3e Juan Quintela
        VMSTATE_UINT8(tx.tucso, E1000State),
916 e482dc3e Juan Quintela
        VMSTATE_UINT16(tx.tucse, E1000State),
917 e482dc3e Juan Quintela
        VMSTATE_UINT32(tx.paylen, E1000State),
918 e482dc3e Juan Quintela
        VMSTATE_UINT8(tx.hdr_len, E1000State),
919 e482dc3e Juan Quintela
        VMSTATE_UINT16(tx.mss, E1000State),
920 e482dc3e Juan Quintela
        VMSTATE_UINT16(tx.size, E1000State),
921 e482dc3e Juan Quintela
        VMSTATE_UINT16(tx.tso_frames, E1000State),
922 e482dc3e Juan Quintela
        VMSTATE_UINT8(tx.sum_needed, E1000State),
923 e482dc3e Juan Quintela
        VMSTATE_INT8(tx.ip, E1000State),
924 e482dc3e Juan Quintela
        VMSTATE_INT8(tx.tcp, E1000State),
925 e482dc3e Juan Quintela
        VMSTATE_BUFFER(tx.header, E1000State),
926 e482dc3e Juan Quintela
        VMSTATE_BUFFER(tx.data, E1000State),
927 e482dc3e Juan Quintela
        VMSTATE_UINT16_ARRAY(eeprom_data, E1000State, 64),
928 e482dc3e Juan Quintela
        VMSTATE_UINT16_ARRAY(phy_reg, E1000State, 0x20),
929 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[CTRL], E1000State),
930 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[EECD], E1000State),
931 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[EERD], E1000State),
932 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[GPRC], E1000State),
933 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[GPTC], E1000State),
934 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[ICR], E1000State),
935 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[ICS], E1000State),
936 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[IMC], E1000State),
937 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[IMS], E1000State),
938 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[LEDCTL], E1000State),
939 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[MANC], E1000State),
940 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[MDIC], E1000State),
941 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[MPC], E1000State),
942 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[PBA], E1000State),
943 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[RCTL], E1000State),
944 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[RDBAH], E1000State),
945 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[RDBAL], E1000State),
946 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[RDH], E1000State),
947 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[RDLEN], E1000State),
948 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[RDT], E1000State),
949 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[STATUS], E1000State),
950 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[SWSM], E1000State),
951 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[TCTL], E1000State),
952 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[TDBAH], E1000State),
953 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[TDBAL], E1000State),
954 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[TDH], E1000State),
955 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[TDLEN], E1000State),
956 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[TDT], E1000State),
957 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[TORH], E1000State),
958 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[TORL], E1000State),
959 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[TOTH], E1000State),
960 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[TOTL], E1000State),
961 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[TPR], E1000State),
962 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[TPT], E1000State),
963 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[TXDCTL], E1000State),
964 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[WUFC], E1000State),
965 e482dc3e Juan Quintela
        VMSTATE_UINT32(mac_reg[VET], E1000State),
966 e482dc3e Juan Quintela
        VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, RA, 32),
967 e482dc3e Juan Quintela
        VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, MTA, 128),
968 e482dc3e Juan Quintela
        VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, VFTA, 128),
969 e482dc3e Juan Quintela
        VMSTATE_END_OF_LIST()
970 e482dc3e Juan Quintela
    }
971 e482dc3e Juan Quintela
};
972 7c23b892 balrog
973 88b4e9db blueswir1
static const uint16_t e1000_eeprom_template[64] = {
974 7c23b892 balrog
    0x0000, 0x0000, 0x0000, 0x0000,      0xffff, 0x0000,      0x0000, 0x0000,
975 7c23b892 balrog
    0x3000, 0x1000, 0x6403, E1000_DEVID, 0x8086, E1000_DEVID, 0x8086, 0x3040,
976 7c23b892 balrog
    0x0008, 0x2000, 0x7e14, 0x0048,      0x1000, 0x00d8,      0x0000, 0x2700,
977 7c23b892 balrog
    0x6cc9, 0x3150, 0x0722, 0x040b,      0x0984, 0x0000,      0xc000, 0x0706,
978 7c23b892 balrog
    0x1008, 0x0000, 0x0f04, 0x7fff,      0x4d01, 0xffff,      0xffff, 0xffff,
979 7c23b892 balrog
    0xffff, 0xffff, 0xffff, 0xffff,      0xffff, 0xffff,      0xffff, 0xffff,
980 7c23b892 balrog
    0x0100, 0x4000, 0x121c, 0xffff,      0xffff, 0xffff,      0xffff, 0xffff,
981 7c23b892 balrog
    0xffff, 0xffff, 0xffff, 0xffff,      0xffff, 0xffff,      0xffff, 0x0000,
982 7c23b892 balrog
};
983 7c23b892 balrog
984 88b4e9db blueswir1
static const uint16_t phy_reg_init[] = {
985 7c23b892 balrog
    [PHY_CTRL] = 0x1140,                        [PHY_STATUS] = 0x796d, // link initially up
986 7c23b892 balrog
    [PHY_ID1] = 0x141,                                [PHY_ID2] = PHY_ID2_INIT,
987 7c23b892 balrog
    [PHY_1000T_CTRL] = 0x0e00,                        [M88E1000_PHY_SPEC_CTRL] = 0x360,
988 7c23b892 balrog
    [M88E1000_EXT_PHY_SPEC_CTRL] = 0x0d60,        [PHY_AUTONEG_ADV] = 0xde1,
989 7c23b892 balrog
    [PHY_LP_ABILITY] = 0x1e0,                        [PHY_1000T_STATUS] = 0x3c00,
990 700f6e2c aurel32
    [M88E1000_PHY_SPEC_STATUS] = 0xac00,
991 7c23b892 balrog
};
992 7c23b892 balrog
993 88b4e9db blueswir1
static const uint32_t mac_reg_init[] = {
994 7c23b892 balrog
    [PBA] =     0x00100030,
995 7c23b892 balrog
    [LEDCTL] =  0x602,
996 7c23b892 balrog
    [CTRL] =    E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN0 |
997 7c23b892 balrog
                E1000_CTRL_SPD_1000 | E1000_CTRL_SLU,
998 7c23b892 balrog
    [STATUS] =  0x80000000 | E1000_STATUS_GIO_MASTER_ENABLE |
999 7c23b892 balrog
                E1000_STATUS_ASDV | E1000_STATUS_MTXCKOK |
1000 7c23b892 balrog
                E1000_STATUS_SPEED_1000 | E1000_STATUS_FD |
1001 7c23b892 balrog
                E1000_STATUS_LU,
1002 7c23b892 balrog
    [MANC] =    E1000_MANC_EN_MNG2HOST | E1000_MANC_RCV_TCO_EN |
1003 7c23b892 balrog
                E1000_MANC_ARP_EN | E1000_MANC_0298_EN |
1004 7c23b892 balrog
                E1000_MANC_RMCP_EN,
1005 7c23b892 balrog
};
1006 7c23b892 balrog
1007 7c23b892 balrog
/* PCI interface */
1008 7c23b892 balrog
1009 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const e1000_mmio_write[] = {
1010 7c23b892 balrog
    e1000_mmio_writeb,        e1000_mmio_writew,        e1000_mmio_writel
1011 7c23b892 balrog
};
1012 7c23b892 balrog
1013 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const e1000_mmio_read[] = {
1014 7c23b892 balrog
    e1000_mmio_readb,        e1000_mmio_readw,        e1000_mmio_readl
1015 7c23b892 balrog
};
1016 7c23b892 balrog
1017 7c23b892 balrog
static void
1018 7c23b892 balrog
e1000_mmio_map(PCIDevice *pci_dev, int region_num,
1019 6e355d90 Isaku Yamahata
                pcibus_t addr, pcibus_t size, int type)
1020 7c23b892 balrog
{
1021 7d9e52bd Juan Quintela
    E1000State *d = DO_UPCAST(E1000State, dev, pci_dev);
1022 f65ed4c1 aliguori
    int i;
1023 f65ed4c1 aliguori
    const uint32_t excluded_regs[] = {
1024 f65ed4c1 aliguori
        E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS,
1025 f65ed4c1 aliguori
        E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE
1026 f65ed4c1 aliguori
    };
1027 f65ed4c1 aliguori
1028 7c23b892 balrog
1029 89e8b13c Isaku Yamahata
    DBGOUT(MMIO, "e1000_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n",
1030 89e8b13c Isaku Yamahata
           addr, size);
1031 7c23b892 balrog
1032 7c23b892 balrog
    cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
1033 f65ed4c1 aliguori
    qemu_register_coalesced_mmio(addr, excluded_regs[0]);
1034 f65ed4c1 aliguori
1035 f65ed4c1 aliguori
    for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++)
1036 f65ed4c1 aliguori
        qemu_register_coalesced_mmio(addr + excluded_regs[i] + 4,
1037 f65ed4c1 aliguori
                                     excluded_regs[i + 1] -
1038 f65ed4c1 aliguori
                                     excluded_regs[i] - 4);
1039 7c23b892 balrog
}
1040 7c23b892 balrog
1041 b946a153 aliguori
static void
1042 a03e2aec Mark McLoughlin
e1000_cleanup(VLANClientState *nc)
1043 b946a153 aliguori
{
1044 a03e2aec Mark McLoughlin
    E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
1045 b946a153 aliguori
1046 a03e2aec Mark McLoughlin
    s->nic = NULL;
1047 b946a153 aliguori
}
1048 b946a153 aliguori
1049 4b09be85 aliguori
static int
1050 4b09be85 aliguori
pci_e1000_uninit(PCIDevice *dev)
1051 4b09be85 aliguori
{
1052 7d9e52bd Juan Quintela
    E1000State *d = DO_UPCAST(E1000State, dev, dev);
1053 4b09be85 aliguori
1054 4b09be85 aliguori
    cpu_unregister_io_memory(d->mmio_index);
1055 a03e2aec Mark McLoughlin
    qemu_del_vlan_client(&d->nic->nc);
1056 4b09be85 aliguori
    return 0;
1057 4b09be85 aliguori
}
1058 4b09be85 aliguori
1059 32c86e95 Blue Swirl
static void e1000_reset(void *opaque)
1060 32c86e95 Blue Swirl
{
1061 32c86e95 Blue Swirl
    E1000State *d = opaque;
1062 32c86e95 Blue Swirl
1063 32c86e95 Blue Swirl
    memset(d->phy_reg, 0, sizeof d->phy_reg);
1064 32c86e95 Blue Swirl
    memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init);
1065 32c86e95 Blue Swirl
    memset(d->mac_reg, 0, sizeof d->mac_reg);
1066 32c86e95 Blue Swirl
    memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init);
1067 32c86e95 Blue Swirl
    d->rxbuf_min_shift = 1;
1068 32c86e95 Blue Swirl
    memset(&d->tx, 0, sizeof d->tx);
1069 32c86e95 Blue Swirl
}
1070 32c86e95 Blue Swirl
1071 a03e2aec Mark McLoughlin
static NetClientInfo net_e1000_info = {
1072 a03e2aec Mark McLoughlin
    .type = NET_CLIENT_TYPE_NIC,
1073 a03e2aec Mark McLoughlin
    .size = sizeof(NICState),
1074 a03e2aec Mark McLoughlin
    .can_receive = e1000_can_receive,
1075 a03e2aec Mark McLoughlin
    .receive = e1000_receive,
1076 a03e2aec Mark McLoughlin
    .cleanup = e1000_cleanup,
1077 a03e2aec Mark McLoughlin
    .link_status_changed = e1000_set_link_status,
1078 a03e2aec Mark McLoughlin
};
1079 a03e2aec Mark McLoughlin
1080 81a322d4 Gerd Hoffmann
static int pci_e1000_init(PCIDevice *pci_dev)
1081 7c23b892 balrog
{
1082 7d9e52bd Juan Quintela
    E1000State *d = DO_UPCAST(E1000State, dev, pci_dev);
1083 7c23b892 balrog
    uint8_t *pci_conf;
1084 7c23b892 balrog
    uint16_t checksum = 0;
1085 7c23b892 balrog
    int i;
1086 fbdaa002 Gerd Hoffmann
    uint8_t *macaddr;
1087 aff427a1 Chris Wright
1088 7c23b892 balrog
    pci_conf = d->dev.config;
1089 7c23b892 balrog
1090 deb54399 aliguori
    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
1091 deb54399 aliguori
    pci_config_set_device_id(pci_conf, E1000_DEVID);
1092 7c23b892 balrog
    *(uint16_t *)(pci_conf+0x04) = cpu_to_le16(0x0407);
1093 7c23b892 balrog
    *(uint16_t *)(pci_conf+0x06) = cpu_to_le16(0x0010);
1094 7c23b892 balrog
    pci_conf[0x08] = 0x03;
1095 173a543b blueswir1
    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
1096 7c23b892 balrog
    pci_conf[0x0c] = 0x10;
1097 7c23b892 balrog
1098 7c23b892 balrog
    pci_conf[0x3d] = 1; // interrupt pin 0
1099 7c23b892 balrog
1100 1eed09cb Avi Kivity
    d->mmio_index = cpu_register_io_memory(e1000_mmio_read,
1101 7c23b892 balrog
            e1000_mmio_write, d);
1102 7c23b892 balrog
1103 28c2c264 Avi Kivity
    pci_register_bar((PCIDevice *)d, 0, PNPMMIO_SIZE,
1104 0392a017 Isaku Yamahata
                           PCI_BASE_ADDRESS_SPACE_MEMORY, e1000_mmio_map);
1105 7c23b892 balrog
1106 28c2c264 Avi Kivity
    pci_register_bar((PCIDevice *)d, 1, IOPORT_SIZE,
1107 0392a017 Isaku Yamahata
                           PCI_BASE_ADDRESS_SPACE_IO, ioport_map);
1108 7c23b892 balrog
1109 7c23b892 balrog
    memmove(d->eeprom_data, e1000_eeprom_template,
1110 7c23b892 balrog
        sizeof e1000_eeprom_template);
1111 fbdaa002 Gerd Hoffmann
    qemu_macaddr_default_if_unset(&d->conf.macaddr);
1112 fbdaa002 Gerd Hoffmann
    macaddr = d->conf.macaddr.a;
1113 7c23b892 balrog
    for (i = 0; i < 3; i++)
1114 9d07d757 Paul Brook
        d->eeprom_data[i] = (macaddr[2*i+1]<<8) | macaddr[2*i];
1115 7c23b892 balrog
    for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
1116 7c23b892 balrog
        checksum += d->eeprom_data[i];
1117 7c23b892 balrog
    checksum = (uint16_t) EEPROM_SUM - checksum;
1118 7c23b892 balrog
    d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;
1119 7c23b892 balrog
1120 a03e2aec Mark McLoughlin
    d->nic = qemu_new_nic(&net_e1000_info, &d->conf,
1121 a03e2aec Mark McLoughlin
                          d->dev.qdev.info->name, d->dev.qdev.id, d);
1122 7c23b892 balrog
1123 a03e2aec Mark McLoughlin
    qemu_format_nic_info_str(&d->nic->nc, macaddr);
1124 7c23b892 balrog
1125 fbdaa002 Gerd Hoffmann
    if (!pci_dev->qdev.hotplugged) {
1126 fbdaa002 Gerd Hoffmann
        static int loaded = 0;
1127 fbdaa002 Gerd Hoffmann
        if (!loaded) {
1128 fbdaa002 Gerd Hoffmann
            rom_add_option("pxe-e1000.bin");
1129 fbdaa002 Gerd Hoffmann
            loaded = 1;
1130 fbdaa002 Gerd Hoffmann
        }
1131 fbdaa002 Gerd Hoffmann
    }
1132 81a322d4 Gerd Hoffmann
    return 0;
1133 9d07d757 Paul Brook
}
1134 72da4208 aliguori
1135 fbdaa002 Gerd Hoffmann
static void qdev_e1000_reset(DeviceState *dev)
1136 fbdaa002 Gerd Hoffmann
{
1137 fbdaa002 Gerd Hoffmann
    E1000State *d = DO_UPCAST(E1000State, dev.qdev, dev);
1138 fbdaa002 Gerd Hoffmann
    e1000_reset(d);
1139 fbdaa002 Gerd Hoffmann
}
1140 fbdaa002 Gerd Hoffmann
1141 0aab0d3a Gerd Hoffmann
static PCIDeviceInfo e1000_info = {
1142 fbdaa002 Gerd Hoffmann
    .qdev.name  = "e1000",
1143 fbdaa002 Gerd Hoffmann
    .qdev.desc  = "Intel Gigabit Ethernet",
1144 fbdaa002 Gerd Hoffmann
    .qdev.size  = sizeof(E1000State),
1145 fbdaa002 Gerd Hoffmann
    .qdev.reset = qdev_e1000_reset,
1146 be73cfe2 Juan Quintela
    .qdev.vmsd  = &vmstate_e1000,
1147 fbdaa002 Gerd Hoffmann
    .init       = pci_e1000_init,
1148 fbdaa002 Gerd Hoffmann
    .exit       = pci_e1000_uninit,
1149 fbdaa002 Gerd Hoffmann
    .qdev.props = (Property[]) {
1150 fbdaa002 Gerd Hoffmann
        DEFINE_NIC_PROPERTIES(E1000State, conf),
1151 fbdaa002 Gerd Hoffmann
        DEFINE_PROP_END_OF_LIST(),
1152 fbdaa002 Gerd Hoffmann
    }
1153 0aab0d3a Gerd Hoffmann
};
1154 0aab0d3a Gerd Hoffmann
1155 9d07d757 Paul Brook
static void e1000_register_devices(void)
1156 9d07d757 Paul Brook
{
1157 0aab0d3a Gerd Hoffmann
    pci_qdev_register(&e1000_info);
1158 7c23b892 balrog
}
1159 9d07d757 Paul Brook
1160 9d07d757 Paul Brook
device_init(e1000_register_devices)