Statistics
| Branch: | Revision:

root / hw / e1000.c @ a6307b08

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