Statistics
| Branch: | Revision:

root / hw / e1000.c @ 4af39611

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