Statistics
| Branch: | Revision:

root / hw / e1000.c @ 75973fa1

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