Statistics
| Branch: | Revision:

root / hw / e1000.c @ 88738c09

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