Statistics
| Branch: | Revision:

root / hw / lance.c @ e80cfcfc

History | View | Annotate | Download (14.3 kB)

1
/*
2
 * QEMU Lance emulation
3
 * 
4
 * Copyright (c) 2003-2004 Fabrice Bellard
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include "vl.h"
25

    
26
/* debug LANCE card */
27
//#define DEBUG_LANCE
28

    
29
#ifndef LANCE_LOG_TX_BUFFERS
30
#define LANCE_LOG_TX_BUFFERS 4
31
#define LANCE_LOG_RX_BUFFERS 4
32
#endif
33

    
34
#define CRC_POLYNOMIAL_BE 0x04c11db7UL  /* Ethernet CRC, big endian */
35
#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
36

    
37

    
38
#define LE_CSR0 0
39
#define LE_CSR1 1
40
#define LE_CSR2 2
41
#define LE_CSR3 3
42
#define LE_MAXREG (LE_CSR3 + 1)
43

    
44
#define LE_RDP  0
45
#define LE_RAP  1
46

    
47
#define LE_MO_PROM      0x8000  /* Enable promiscuous mode */
48

    
49
#define        LE_C0_ERR        0x8000        /* Error: set if BAB, SQE, MISS or ME is set */
50
#define        LE_C0_BABL        0x4000        /* BAB:  Babble: tx timeout. */
51
#define        LE_C0_CERR        0x2000        /* SQE:  Signal quality error */
52
#define        LE_C0_MISS        0x1000        /* MISS: Missed a packet */
53
#define        LE_C0_MERR        0x0800        /* ME:   Memory error */
54
#define        LE_C0_RINT        0x0400        /* Received interrupt */
55
#define        LE_C0_TINT        0x0200        /* Transmitter Interrupt */
56
#define        LE_C0_IDON        0x0100        /* IFIN: Init finished. */
57
#define        LE_C0_INTR        0x0080        /* Interrupt or error */
58
#define        LE_C0_INEA        0x0040        /* Interrupt enable */
59
#define        LE_C0_RXON        0x0020        /* Receiver on */
60
#define        LE_C0_TXON        0x0010        /* Transmitter on */
61
#define        LE_C0_TDMD        0x0008        /* Transmitter demand */
62
#define        LE_C0_STOP        0x0004        /* Stop the card */
63
#define        LE_C0_STRT        0x0002        /* Start the card */
64
#define        LE_C0_INIT        0x0001        /* Init the card */
65

    
66
#define        LE_C3_BSWP        0x4     /* SWAP */
67
#define        LE_C3_ACON        0x2        /* ALE Control */
68
#define        LE_C3_BCON        0x1        /* Byte control */
69

    
70
/* Receive message descriptor 1 */
71
#define LE_R1_OWN       0x80    /* Who owns the entry */
72
#define LE_R1_ERR       0x40    /* Error: if FRA, OFL, CRC or BUF is set */
73
#define LE_R1_FRA       0x20    /* FRA: Frame error */
74
#define LE_R1_OFL       0x10    /* OFL: Frame overflow */
75
#define LE_R1_CRC       0x08    /* CRC error */
76
#define LE_R1_BUF       0x04    /* BUF: Buffer error */
77
#define LE_R1_SOP       0x02    /* Start of packet */
78
#define LE_R1_EOP       0x01    /* End of packet */
79
#define LE_R1_POK       0x03    /* Packet is complete: SOP + EOP */
80

    
81
#define LE_T1_OWN       0x80    /* Lance owns the packet */
82
#define LE_T1_ERR       0x40    /* Error summary */
83
#define LE_T1_EMORE     0x10    /* Error: more than one retry needed */
84
#define LE_T1_EONE      0x08    /* Error: one retry needed */
85
#define LE_T1_EDEF      0x04    /* Error: deferred */
86
#define LE_T1_SOP       0x02    /* Start of packet */
87
#define LE_T1_EOP       0x01    /* End of packet */
88
#define LE_T1_POK        0x03        /* Packet is complete: SOP + EOP */
89

    
90
#define LE_T3_BUF       0x8000  /* Buffer error */
91
#define LE_T3_UFL       0x4000  /* Error underflow */
92
#define LE_T3_LCOL      0x1000  /* Error late collision */
93
#define LE_T3_CLOS      0x0800  /* Error carrier loss */
94
#define LE_T3_RTY       0x0400  /* Error retry */
95
#define LE_T3_TDR       0x03ff  /* Time Domain Reflectometry counter */
96

    
97
#define TX_RING_SIZE                        (1 << (LANCE_LOG_TX_BUFFERS))
98
#define TX_RING_MOD_MASK                (TX_RING_SIZE - 1)
99
#define TX_RING_LEN_BITS                ((LANCE_LOG_TX_BUFFERS) << 29)
100

    
101
#define RX_RING_SIZE                        (1 << (LANCE_LOG_RX_BUFFERS))
102
#define RX_RING_MOD_MASK                (RX_RING_SIZE - 1)
103
#define RX_RING_LEN_BITS                ((LANCE_LOG_RX_BUFFERS) << 29)
104

    
105
#define PKT_BUF_SZ                1544
106
#define RX_BUFF_SIZE            PKT_BUF_SZ
107
#define TX_BUFF_SIZE            PKT_BUF_SZ
108

    
109
struct lance_rx_desc {
110
        unsigned short rmd0;        /* low address of packet */
111
        unsigned char  rmd1_bits;   /* descriptor bits */
112
        unsigned char  rmd1_hadr;   /* high address of packet */
113
        short    length;                /* This length is 2s complement (negative)!
114
                                     * Buffer length
115
                                     */
116
        unsigned short mblength;    /* This is the actual number of bytes received */
117
};
118

    
119
struct lance_tx_desc {
120
        unsigned short tmd0;        /* low address of packet */
121
        unsigned char  tmd1_bits;   /* descriptor bits */
122
        unsigned char  tmd1_hadr;   /* high address of packet */
123
        short length;                      /* Length is 2s complement (negative)! */
124
        unsigned short misc;
125
};
126

    
127
/* The LANCE initialization block, described in databook. */
128
/* On the Sparc, this block should be on a DMA region     */
129
struct lance_init_block {
130
        unsigned short mode;                /* Pre-set mode (reg. 15) */
131
        unsigned char phys_addr[6];     /* Physical ethernet address */
132
        unsigned filter[2];                /* Multicast filter. */
133

    
134
        /* Receive and transmit ring base, along with extra bits. */
135
        unsigned short rx_ptr;                /* receive descriptor addr */
136
        unsigned short rx_len;                /* receive len and high addr */
137
        unsigned short tx_ptr;                /* transmit descriptor addr */
138
        unsigned short tx_len;                /* transmit len and high addr */
139
    
140
        /* The Tx and Rx ring entries must aligned on 8-byte boundaries. */
141
        struct lance_rx_desc brx_ring[RX_RING_SIZE];
142
        struct lance_tx_desc btx_ring[TX_RING_SIZE];
143
    
144
        char   tx_buf [TX_RING_SIZE][TX_BUFF_SIZE];
145
        char   pad[2];                        /* align rx_buf for copy_and_sum(). */
146
        char   rx_buf [RX_RING_SIZE][RX_BUFF_SIZE];
147
};
148

    
149
#define LEDMA_REGS 4
150
#define LEDMA_MAXADDR (LEDMA_REGS * 4 - 1)
151
#if 0
152
/* Structure to describe the current status of DMA registers on the Sparc */
153
struct sparc_dma_registers {
154
    uint32_t cond_reg;        /* DMA condition register */
155
    uint32_t st_addr;        /* Start address of this transfer */
156
    uint32_t cnt;        /* How many bytes to transfer */
157
    uint32_t dma_test;        /* DMA test register */
158
};
159
#endif
160

    
161
typedef struct LANCEState {
162
    NetDriverState *nd;
163
    uint32_t leptr;
164
    uint16_t addr;
165
    uint16_t regs[LE_MAXREG];
166
    uint8_t phys[6]; /* mac address */
167
    int irq;
168
    unsigned int rxptr, txptr;
169
    uint32_t ledmaregs[LEDMA_REGS];
170
} LANCEState;
171

    
172
static void lance_send(void *opaque);
173

    
174
static void lance_reset(void *opaque)
175
{
176
    LANCEState *s = opaque;
177
    memcpy(s->phys, s->nd->macaddr, 6);
178
    s->rxptr = 0;
179
    s->txptr = 0;
180
    memset(s->regs, 0, LE_MAXREG * 2);
181
    s->regs[LE_CSR0] = LE_C0_STOP;
182
    memset(s->ledmaregs, 0, LEDMA_REGS * 4);
183
}
184

    
185
static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
186
{
187
    LANCEState *s = opaque;
188
    uint32_t saddr;
189

    
190
    saddr = addr & LE_MAXREG;
191
    switch (saddr >> 1) {
192
    case LE_RDP:
193
        return s->regs[s->addr];
194
    case LE_RAP:
195
        return s->addr;
196
    default:
197
        break;
198
    }
199
    return 0;
200
}
201

    
202
static void lance_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
203
{
204
    LANCEState *s = opaque;
205
    uint32_t saddr;
206
    uint16_t reg;
207

    
208
    saddr = addr & LE_MAXREG;
209
    switch (saddr >> 1) {
210
    case LE_RDP:
211
        switch(s->addr) {
212
        case LE_CSR0:
213
            if (val & LE_C0_STOP) {
214
                s->regs[LE_CSR0] = LE_C0_STOP;
215
                break;
216
            }
217

    
218
            reg = s->regs[LE_CSR0];
219

    
220
            // 1 = clear for some bits
221
            reg &= ~(val & 0x7f00);
222

    
223
            // generated bits
224
            reg &= ~(LE_C0_ERR | LE_C0_INTR);
225
            if (reg & 0x7100)
226
                reg |= LE_C0_ERR;
227
            if (reg & 0x7f00)
228
                reg |= LE_C0_INTR;
229

    
230
            // direct bit
231
            reg &= ~LE_C0_INEA;
232
            reg |= val & LE_C0_INEA;
233

    
234
            // exclusive bits
235
            if (val & LE_C0_INIT) {
236
                reg |= LE_C0_IDON | LE_C0_INIT;
237
                reg &= ~LE_C0_STOP;
238
            }
239
            else if (val & LE_C0_STRT) {
240
                reg |= LE_C0_STRT | LE_C0_RXON | LE_C0_TXON;
241
                reg &= ~LE_C0_STOP;
242
            }
243

    
244
            s->regs[LE_CSR0] = reg;
245

    
246
            // trigger bits
247
            //if (val & LE_C0_TDMD)
248

    
249
            if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA))
250
                pic_set_irq(s->irq, 1);
251
            break;
252
        case LE_CSR1:
253
            s->leptr = (s->leptr & 0xffff0000) | (val & 0xffff);
254
            s->regs[s->addr] = val;
255
            break;
256
        case LE_CSR2:
257
            s->leptr = (s->leptr & 0xffff) | ((val & 0xffff) << 16);
258
            s->regs[s->addr] = val;
259
            break;
260
        case LE_CSR3:
261
            s->regs[s->addr] = val;
262
            break;
263
        }
264
        break;
265
    case LE_RAP:
266
        if (val < LE_MAXREG)
267
            s->addr = val;
268
        break;
269
    default:
270
        break;
271
    }
272
    lance_send(s);
273
}
274

    
275
static CPUReadMemoryFunc *lance_mem_read[3] = {
276
    lance_mem_readw,
277
    lance_mem_readw,
278
    lance_mem_readw,
279
};
280

    
281
static CPUWriteMemoryFunc *lance_mem_write[3] = {
282
    lance_mem_writew,
283
    lance_mem_writew,
284
    lance_mem_writew,
285
};
286

    
287

    
288
/* return the max buffer size if the LANCE can receive more data */
289
static int lance_can_receive(void *opaque)
290
{
291
    LANCEState *s = opaque;
292
    uint32_t dmaptr = s->leptr + s->ledmaregs[3];
293
    struct lance_init_block *ib;
294
    int i;
295
    uint16_t temp;
296

    
297
    if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
298
        return 0;
299

    
300
    ib = (void *) iommu_translate(dmaptr);
301

    
302
    for (i = 0; i < RX_RING_SIZE; i++) {
303
        cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
304
        temp &= 0xff;
305
        if (temp == (LE_R1_OWN)) {
306
#ifdef DEBUG_LANCE
307
            fprintf(stderr, "lance: can receive %d\n", RX_BUFF_SIZE);
308
#endif
309
            return RX_BUFF_SIZE;
310
        }
311
    }
312
#ifdef DEBUG_LANCE
313
    fprintf(stderr, "lance: cannot receive\n");
314
#endif
315
    return 0;
316
}
317

    
318
#define MIN_BUF_SIZE 60
319

    
320
static void lance_receive(void *opaque, const uint8_t *buf, int size)
321
{
322
    LANCEState *s = opaque;
323
    uint32_t dmaptr = s->leptr + s->ledmaregs[3];
324
    struct lance_init_block *ib;
325
    unsigned int i, old_rxptr, j;
326
    uint16_t temp;
327

    
328
    if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
329
        return;
330

    
331
    ib = (void *) iommu_translate(dmaptr);
332

    
333
    old_rxptr = s->rxptr;
334
    for (i = s->rxptr; i != ((old_rxptr - 1) & RX_RING_MOD_MASK); i = (i + 1) & RX_RING_MOD_MASK) {
335
        cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
336
        if (temp == (LE_R1_OWN)) {
337
            s->rxptr = (s->rxptr + 1) & RX_RING_MOD_MASK;
338
            temp = size;
339
            bswap16s(&temp);
340
            cpu_physical_memory_write((uint32_t)&ib->brx_ring[i].mblength, (void *) &temp, 2);
341
#if 0
342
            cpu_physical_memory_write((uint32_t)&ib->rx_buf[i], buf, size);
343
#else
344
            for (j = 0; j < size; j++) {
345
                cpu_physical_memory_write(((uint32_t)&ib->rx_buf[i]) + j, &buf[j], 1);
346
            }
347
#endif
348
            temp = LE_R1_POK;
349
            cpu_physical_memory_write((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
350
            s->regs[LE_CSR0] |= LE_C0_RINT | LE_C0_INTR;
351
            if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA))
352
                pic_set_irq(s->irq, 1);
353
#ifdef DEBUG_LANCE
354
            fprintf(stderr, "lance: got packet, len %d\n", size);
355
#endif
356
            return;
357
        }
358
    }
359
}
360

    
361
static void lance_send(void *opaque)
362
{
363
    LANCEState *s = opaque;
364
    uint32_t dmaptr = s->leptr + s->ledmaregs[3];
365
    struct lance_init_block *ib;
366
    unsigned int i, old_txptr, j;
367
    uint16_t temp;
368
    char pkt_buf[PKT_BUF_SZ];
369

    
370
    if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
371
        return;
372

    
373
    ib = (void *) iommu_translate(dmaptr);
374

    
375
    old_txptr = s->txptr;
376
    for (i = s->txptr; i != ((old_txptr - 1) & TX_RING_MOD_MASK); i = (i + 1) & TX_RING_MOD_MASK) {
377
        cpu_physical_memory_read((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1);
378
        if (temp == (LE_T1_POK|LE_T1_OWN)) {
379
            cpu_physical_memory_read((uint32_t)&ib->btx_ring[i].length, (void *) &temp, 2);
380
            bswap16s(&temp);
381
            temp = (~temp) + 1;
382
#if 0
383
            cpu_physical_memory_read((uint32_t)&ib->tx_buf[i], pkt_buf, temp);
384
#else
385
            for (j = 0; j < temp; j++) {
386
                cpu_physical_memory_read((uint32_t)&ib->tx_buf[i] + j, &pkt_buf[j], 1);
387
            }
388
#endif
389

    
390
#ifdef DEBUG_LANCE
391
            fprintf(stderr, "lance: sending packet, len %d\n", temp);
392
#endif
393
            qemu_send_packet(s->nd, pkt_buf, temp);
394
            temp = LE_T1_POK;
395
            cpu_physical_memory_write((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1);
396
            s->txptr = (s->txptr + 1) & TX_RING_MOD_MASK;
397
            s->regs[LE_CSR0] |= LE_C0_TINT | LE_C0_INTR;
398
        }
399
    }
400
}
401

    
402
static uint32_t ledma_mem_readl(void *opaque, target_phys_addr_t addr)
403
{
404
    LANCEState *s = opaque;
405
    uint32_t saddr;
406

    
407
    saddr = (addr & LEDMA_MAXADDR) >> 2;
408
    return s->ledmaregs[saddr];
409
}
410

    
411
static void ledma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
412
{
413
    LANCEState *s = opaque;
414
    uint32_t saddr;
415

    
416
    saddr = (addr & LEDMA_MAXADDR) >> 2;
417
    s->ledmaregs[saddr] = val;
418
}
419

    
420
static CPUReadMemoryFunc *ledma_mem_read[3] = {
421
    ledma_mem_readl,
422
    ledma_mem_readl,
423
    ledma_mem_readl,
424
};
425

    
426
static CPUWriteMemoryFunc *ledma_mem_write[3] = {
427
    ledma_mem_writel,
428
    ledma_mem_writel,
429
    ledma_mem_writel,
430
};
431

    
432
static void lance_save(QEMUFile *f, void *opaque)
433
{
434
    LANCEState *s = opaque;
435
    int i;
436
    
437
    qemu_put_be32s(f, &s->leptr);
438
    qemu_put_be16s(f, &s->addr);
439
    for (i = 0; i < LE_MAXREG; i ++)
440
        qemu_put_be16s(f, &s->regs[i]);
441
    qemu_put_buffer(f, s->phys, 6);
442
    qemu_put_be32s(f, &s->irq);
443
    for (i = 0; i < LEDMA_REGS; i ++)
444
        qemu_put_be32s(f, &s->ledmaregs[i]);
445
}
446

    
447
static int lance_load(QEMUFile *f, void *opaque, int version_id)
448
{
449
    LANCEState *s = opaque;
450
    int i;
451
    
452
    if (version_id != 1)
453
        return -EINVAL;
454

    
455
    qemu_get_be32s(f, &s->leptr);
456
    qemu_get_be16s(f, &s->addr);
457
    for (i = 0; i < LE_MAXREG; i ++)
458
        qemu_get_be16s(f, &s->regs[i]);
459
    qemu_get_buffer(f, s->phys, 6);
460
    qemu_get_be32s(f, &s->irq);
461
    for (i = 0; i < LEDMA_REGS; i ++)
462
        qemu_get_be32s(f, &s->ledmaregs[i]);
463
    return 0;
464
}
465

    
466
void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr)
467
{
468
    LANCEState *s;
469
    int lance_io_memory, ledma_io_memory;
470

    
471
    s = qemu_mallocz(sizeof(LANCEState));
472
    if (!s)
473
        return;
474

    
475
    s->nd = nd;
476
    s->irq = irq;
477

    
478
    lance_io_memory = cpu_register_io_memory(0, lance_mem_read, lance_mem_write, s);
479
    cpu_register_physical_memory(leaddr, 8, lance_io_memory);
480

    
481
    ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, s);
482
    cpu_register_physical_memory(ledaddr, 16, ledma_io_memory);
483

    
484
    lance_reset(s);
485
    qemu_add_read_packet(nd, lance_can_receive, lance_receive, s);
486
    register_savevm("lance", leaddr, 1, lance_save, lance_load, s);
487
    qemu_register_reset(lance_reset, s);
488
}
489