Revision 66321a11 hw/lance.c

b/hw/lance.c
1 1
/*
2 2
 * QEMU Lance emulation
3 3
 * 
4
 * Copyright (c) 2003-2004 Fabrice Bellard
4
 * Copyright (c) 2003-2005 Fabrice Bellard
5 5
 * 
6 6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 7
 * of this software and associated documentation files (the "Software"), to deal
......
26 26
/* debug LANCE card */
27 27
//#define DEBUG_LANCE
28 28

  
29
#ifdef DEBUG_LANCE
30
#define DPRINTF(fmt, args...) \
31
do { printf("LANCE: " fmt , ##args); } while (0)
32
#else
33
#define DPRINTF(fmt, args...)
34
#endif
35

  
29 36
#ifndef LANCE_LOG_TX_BUFFERS
30 37
#define LANCE_LOG_TX_BUFFERS 4
31 38
#define LANCE_LOG_RX_BUFFERS 4
32 39
#endif
33 40

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

  
37

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

  
44 48
#define LE_RDP  0
45 49
#define LE_RAP  1
......
148 152

  
149 153
#define LEDMA_REGS 4
150 154
#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 155

  
161 156
typedef struct LANCEState {
162 157
    NetDriverState *nd;
163 158
    uint32_t leptr;
164 159
    uint16_t addr;
165
    uint16_t regs[LE_MAXREG];
160
    uint16_t regs[LE_NREGS];
166 161
    uint8_t phys[6]; /* mac address */
167 162
    int irq;
168 163
    unsigned int rxptr, txptr;
......
177 172
    memcpy(s->phys, s->nd->macaddr, 6);
178 173
    s->rxptr = 0;
179 174
    s->txptr = 0;
180
    memset(s->regs, 0, LE_MAXREG * 2);
175
    memset(s->regs, 0, LE_NREGS * 2);
181 176
    s->regs[LE_CSR0] = LE_C0_STOP;
182 177
    memset(s->ledmaregs, 0, LEDMA_REGS * 4);
183 178
}
......
190 185
    saddr = addr & LE_MAXREG;
191 186
    switch (saddr >> 1) {
192 187
    case LE_RDP:
188
	DPRINTF("read dreg[%d] = %4.4x\n", s->addr, s->regs[s->addr]);
193 189
	return s->regs[s->addr];
194 190
    case LE_RAP:
191
	DPRINTF("read areg = %4.4x\n", s->addr);
195 192
	return s->addr;
196 193
    default:
194
	DPRINTF("read unknown(%d)\n", saddr>>1);
197 195
	break;
198 196
    }
199 197
    return 0;
......
208 206
    saddr = addr & LE_MAXREG;
209 207
    switch (saddr >> 1) {
210 208
    case LE_RDP:
209
	DPRINTF("write dreg[%d] = %4.4x\n", s->addr, val);
211 210
	switch(s->addr) {
212 211
	case LE_CSR0:
213 212
	    if (val & LE_C0_STOP) {
......
242 241
	    }
243 242

  
244 243
	    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 244
	    break;
252 245
	case LE_CSR1:
253 246
	    s->leptr = (s->leptr & 0xffff0000) | (val & 0xffff);
......
263 256
	}
264 257
	break;
265 258
    case LE_RAP:
266
	if (val < LE_MAXREG)
259
	DPRINTF("write areg = %4.4x\n", val);
260
	if (val < LE_NREGS)
267 261
	    s->addr = val;
268 262
	break;
269 263
    default:
264
	DPRINTF("write unknown(%d) = %4.4x\n", saddr>>1, val);
270 265
	break;
271 266
    }
272 267
    lance_send(s);
......
292 287
    uint32_t dmaptr = s->leptr + s->ledmaregs[3];
293 288
    struct lance_init_block *ib;
294 289
    int i;
295
    uint16_t temp;
290
    uint8_t temp8;
296 291

  
297 292
    if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
298 293
	return 0;
......
300 295
    ib = (void *) iommu_translate(dmaptr);
301 296

  
302 297
    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
298
	cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp8, 1);
299
	if (temp8 == (LE_R1_OWN)) {
300
	    DPRINTF("can receive %d\n", RX_BUFF_SIZE);
309 301
	    return RX_BUFF_SIZE;
310 302
	}
311 303
    }
312
#ifdef DEBUG_LANCE
313
    fprintf(stderr, "lance: cannot receive\n");
314
#endif
304
    DPRINTF("cannot receive\n");
315 305
    return 0;
316 306
}
317 307

  
......
322 312
    LANCEState *s = opaque;
323 313
    uint32_t dmaptr = s->leptr + s->ledmaregs[3];
324 314
    struct lance_init_block *ib;
325
    unsigned int i, old_rxptr, j;
326
    uint16_t temp;
315
    unsigned int i, old_rxptr;
316
    uint16_t temp16;
317
    uint8_t temp8;
327 318

  
319
    DPRINTF("receive size %d\n", size);
328 320
    if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
329 321
	return;
330 322

  
......
332 324

  
333 325
    old_rxptr = s->rxptr;
334 326
    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)) {
327
	cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp8, 1);
328
	if (temp8 == (LE_R1_OWN)) {
337 329
	    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
330
	    temp16 = size + 4;
331
	    bswap16s(&temp16);
332
	    cpu_physical_memory_write((uint32_t)&ib->brx_ring[i].mblength, (void *) &temp16, 2);
342 333
	    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);
334
	    temp8 = LE_R1_POK;
335
	    cpu_physical_memory_write((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp8, 1);
350 336
	    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))
337
	    if (s->regs[LE_CSR0] & LE_C0_INEA)
352 338
		pic_set_irq(s->irq, 1);
353
#ifdef DEBUG_LANCE
354
	    fprintf(stderr, "lance: got packet, len %d\n", size);
355
#endif
339
	    DPRINTF("got packet, len %d\n", size);
356 340
	    return;
357 341
	}
358 342
    }
......
363 347
    LANCEState *s = opaque;
364 348
    uint32_t dmaptr = s->leptr + s->ledmaregs[3];
365 349
    struct lance_init_block *ib;
366
    unsigned int i, old_txptr, j;
367
    uint16_t temp;
350
    unsigned int i, old_txptr;
351
    uint16_t temp16;
352
    uint8_t temp8;
368 353
    char pkt_buf[PKT_BUF_SZ];
369 354

  
355
    DPRINTF("sending packet? (csr0 %4.4x)\n", s->regs[LE_CSR0]);
370 356
    if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
371 357
	return;
372 358

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

  
361
    DPRINTF("sending packet? (dmaptr %8.8x) (ib %p) (btx_ring %p)\n", dmaptr, ib, &ib->btx_ring);
375 362
    old_txptr = s->txptr;
376 363
    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);
364
	cpu_physical_memory_read((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp8, 1);
365
	if (temp8 == (LE_T1_POK|LE_T1_OWN)) {
366
	    cpu_physical_memory_read((uint32_t)&ib->btx_ring[i].length, (void *) &temp16, 2);
367
	    bswap16s(&temp16);
368
	    temp16 = (~temp16) + 1;
369
	    cpu_physical_memory_read((uint32_t)&ib->tx_buf[i], pkt_buf, temp16);
370
	    DPRINTF("sending packet, len %d\n", temp16);
371
	    qemu_send_packet(s->nd, pkt_buf, temp16);
372
	    temp8 = LE_T1_POK;
373
	    cpu_physical_memory_write((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp8, 1);
396 374
	    s->txptr = (s->txptr + 1) & TX_RING_MOD_MASK;
397 375
	    s->regs[LE_CSR0] |= LE_C0_TINT | LE_C0_INTR;
398 376
	}
399 377
    }
378
    if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA))
379
	pic_set_irq(s->irq, 1);
400 380
}
401 381

  
402 382
static uint32_t ledma_mem_readl(void *opaque, target_phys_addr_t addr)
......
436 416
    
437 417
    qemu_put_be32s(f, &s->leptr);
438 418
    qemu_put_be16s(f, &s->addr);
439
    for (i = 0; i < LE_MAXREG; i ++)
419
    for (i = 0; i < LE_NREGS; i ++)
440 420
	qemu_put_be16s(f, &s->regs[i]);
441 421
    qemu_put_buffer(f, s->phys, 6);
442 422
    qemu_put_be32s(f, &s->irq);
......
454 434

  
455 435
    qemu_get_be32s(f, &s->leptr);
456 436
    qemu_get_be16s(f, &s->addr);
457
    for (i = 0; i < LE_MAXREG; i ++)
437
    for (i = 0; i < LE_NREGS; i ++)
458 438
	qemu_get_be16s(f, &s->regs[i]);
459 439
    qemu_get_buffer(f, s->phys, 6);
460 440
    qemu_get_be32s(f, &s->irq);
......
476 456
    s->irq = irq;
477 457

  
478 458
    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);
459
    cpu_register_physical_memory(leaddr, 4, lance_io_memory);
480 460

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

Also available in: Unified diff