Statistics
| Branch: | Revision:

root / hw / e1000.c @ a8b7063b

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