Statistics
| Branch: | Revision:

root / hw / e1000.c @ 50132156

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