Revision f6953f13 hw/etraxfs_eth.c

b/hw/etraxfs_eth.c
53 53

  
54 54
	switch (regnum) {
55 55
		case 1:
56
			/* MR1.  */
56
			/* MR1.	 */
57 57
			/* Speeds and modes.  */
58 58
			r |= (1 << 13) | (1 << 14);
59 59
			r |= (1 << 11) | (1 << 12);
60 60
			r |= (1 << 5); /* Autoneg complete.  */
61
			r |= (1 << 3); /* Autoneg able.  */
62
			r |= (1 << 2); /* Link.  */
61
			r |= (1 << 3); /* Autoneg able.	 */
62
			r |= (1 << 2); /* Link.	 */
63 63
			break;
64 64
		case 5:
65 65
			/* Link partner ability.
......
123 123

  
124 124
struct qemu_mdio
125 125
{
126
	/* bus.  */
126
	/* bus.	 */
127 127
	int mdc;
128 128
	int mdio;
129 129

  
......
285 285

  
286 286
/* ETRAX-FS Ethernet MAC block starts here.  */
287 287

  
288
#define R_STAT            0x2c
289
#define RW_MGM_CTRL       0x28
290
#define FS_ETH_MAX_REGS   0x5c
288
#define RW_MA0_LO	  0x00
289
#define RW_MA0_HI	  0x04
290
#define RW_MA1_LO	  0x08
291
#define RW_MA1_HI	  0x0c
292
#define RW_GA_LO	  0x10
293
#define RW_GA_HI	  0x14
294
#define RW_GEN_CTRL	  0x18
295
#define RW_REC_CTRL	  0x1c
296
#define RW_TR_CTRL	  0x20
297
#define RW_CLR_ERR	  0x24
298
#define RW_MGM_CTRL	  0x28
299
#define R_STAT		  0x2c
300
#define FS_ETH_MAX_REGS	  0x5c
291 301

  
292 302
struct fs_eth
293 303
{
294
        CPUState *env;
304
	CPUState *env;
295 305
	qemu_irq *irq;
296
        target_phys_addr_t base;
306
	target_phys_addr_t base;
297 307
	VLANClientState *vc;
298
	uint8_t macaddr[6];
299 308
	int ethregs;
300 309

  
310
	/* Two addrs in the filter.  */
311
	uint8_t macaddr[2][6];
301 312
	uint32_t regs[FS_ETH_MAX_REGS];
302 313

  
303 314
	unsigned char rx_fifo[1536];
......
309 320

  
310 321
	/* MDIO bus.  */
311 322
	struct qemu_mdio mdio_bus;
312
	/* PHY.  */
323
	/* PHY.	 */
313 324
	struct qemu_phy phy;
314 325
};
315 326

  
316 327
static uint32_t eth_rinvalid (void *opaque, target_phys_addr_t addr)
317 328
{
318
        struct fs_eth *eth = opaque;
319
        CPUState *env = eth->env;
320
        cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n", 
321
                  addr, env->pc);
322
        return 0;
329
	struct fs_eth *eth = opaque;
330
	CPUState *env = eth->env;
331
	cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n", 
332
		  addr, env->pc);
333
	return 0;
323 334
}
324 335

  
325 336
static uint32_t eth_readl (void *opaque, target_phys_addr_t addr)
326 337
{
327
        struct fs_eth *eth = opaque;
328
        D(CPUState *env = eth->env);
329
        uint32_t r = 0;
338
	struct fs_eth *eth = opaque;
339
	D(CPUState *env = eth->env);
340
	uint32_t r = 0;
330 341

  
331
        /* Make addr relative to this instances base.  */
332
        addr -= eth->base;
333
        switch (addr) {
342
	/* Make addr relative to this instances base.  */
343
	addr -= eth->base;
344
	switch (addr) {
334 345
		case R_STAT:
335 346
			/* Attach an MDIO/PHY abstraction.  */
336 347
			r = eth->mdio_bus.mdio & 1;
337 348
			break;
338
        default:
349
	default:
339 350
		r = eth->regs[addr];
340
                D(printf ("%s %x p=%x\n", __func__, addr, env->pc));
341
                break;
342
        }
343
        return r;
351
		D(printf ("%s %x p=%x\n", __func__, addr, env->pc));
352
		break;
353
	}
354
	return r;
344 355
}
345 356

  
346 357
static void
347 358
eth_winvalid (void *opaque, target_phys_addr_t addr, uint32_t value)
348 359
{
349
        struct fs_eth *eth = opaque;
350
        CPUState *env = eth->env;
351
        cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n", 
352
                  addr, env->pc);
360
	struct fs_eth *eth = opaque;
361
	CPUState *env = eth->env;
362
	cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n", 
363
		  addr, env->pc);
364
}
365

  
366
static void eth_update_ma(struct fs_eth *eth, int ma)
367
{
368
	int reg;
369
	int i = 0;
370

  
371
	ma &= 1;
372

  
373
	reg = RW_MA0_LO;
374
	if (ma)
375
		reg = RW_MA1_LO;
376

  
377
	eth->macaddr[ma][i++] = eth->regs[reg];
378
	eth->macaddr[ma][i++] = eth->regs[reg] >> 8;
379
	eth->macaddr[ma][i++] = eth->regs[reg] >> 16;
380
	eth->macaddr[ma][i++] = eth->regs[reg] >> 24;
381
	eth->macaddr[ma][i++] = eth->regs[reg + 4];
382
	eth->macaddr[ma][i++] = eth->regs[reg + 4] >> 8;
383

  
384
	D(printf("set mac%d=%x.%x.%x.%x.%x.%x\n", ma,
385
		 eth->macaddr[ma][0], eth->macaddr[ma][1],
386
		 eth->macaddr[ma][2], eth->macaddr[ma][3],
387
		 eth->macaddr[ma][4], eth->macaddr[ma][5]));
353 388
}
354 389

  
355 390
static void
356 391
eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
357 392
{
358
        struct fs_eth *eth = opaque;
359
        CPUState *env = eth->env;
393
	struct fs_eth *eth = opaque;
394
	CPUState *env = eth->env;
395

  
396
	/* Make addr relative to this instances base.  */
397
	addr -= eth->base;
398
	switch (addr)
399
	{
400
		case RW_MA0_LO:
401
			eth->regs[addr] = value;
402
			eth_update_ma(eth, 0);
403
			break;
404
		case RW_MA0_HI:
405
			eth->regs[addr] = value;
406
			eth_update_ma(eth, 0);
407
			break;
408
		case RW_MA1_LO:
409
			eth->regs[addr] = value;
410
			eth_update_ma(eth, 1);
411
			break;
412
		case RW_MA1_HI:
413
			eth->regs[addr] = value;
414
			eth_update_ma(eth, 1);
415
			break;
360 416

  
361
        /* Make addr relative to this instances base.  */
362
        addr -= eth->base;
363
        switch (addr)
364
        {
365 417
		case RW_MGM_CTRL:
366 418
			/* Attach an MDIO/PHY abstraction.  */
367 419
			if (value & 2)
......
371 423
			eth->mdio_bus.mdc = !!(value & 4);
372 424
			break;
373 425

  
374
                default:
375
                        printf ("%s %x %x pc=%x\n",
376
                                __func__, addr, value, env->pc);
377
                        break;
378
        }
426
		default:
427
			eth->regs[addr] = value;
428
			printf ("%s %x %x pc=%x\n",
429
				__func__, addr, value, env->pc);
430
			break;
431
	}
432
}
433

  
434
/* The ETRAX FS has a groupt address table (GAT) which works like a k=1 bloom
435
   filter dropping group addresses we have not joined.	The filter has 64
436
   bits (m). The has function is a simple nible xor of the group addr.	*/
437
static int eth_match_groupaddr(struct fs_eth *eth, const unsigned char *sa)
438
{
439
	unsigned int hsh;
440
	int m_individual = eth->regs[RW_REC_CTRL] & 4;
441
	int match;
442

  
443
	/* First bit on the wire of a MAC address signals multicast or
444
	   physical address.  */
445
	if (!m_individual && !sa[0] & 1)
446
		return 0;
447

  
448
	/* Calculate the hash index for the GA registers. */
449
	hsh = 0;
450
	hsh ^= (*sa) & 0x3f;
451
	hsh ^= ((*sa) >> 6) & 0x03;
452
	++sa;
453
	hsh ^= ((*sa) << 2) & 0x03c;
454
	hsh ^= ((*sa) >> 4) & 0xf;
455
	++sa;
456
	hsh ^= ((*sa) << 4) & 0x30;
457
	hsh ^= ((*sa) >> 2) & 0x3f;
458
	++sa;
459
	hsh ^= (*sa) & 0x3f;
460
	hsh ^= ((*sa) >> 6) & 0x03;
461
	++sa;
462
	hsh ^= ((*sa) << 2) & 0x03c;
463
	hsh ^= ((*sa) >> 4) & 0xf;
464
	++sa;
465
	hsh ^= ((*sa) << 4) & 0x30;
466
	hsh ^= ((*sa) >> 2) & 0x3f;
467

  
468
	hsh &= 63;
469
	if (hsh > 31)
470
		match = eth->regs[RW_GA_HI] & (1 << (hsh - 32));
471
	else
472
		match = eth->regs[RW_GA_LO] & (1 << hsh);
473
	D(printf("hsh=%x ga=%x.%x mtch=%d\n", hsh,
474
		 eth->regs[RW_GA_HI], eth->regs[RW_GA_LO], match));
475
	return match;
379 476
}
380 477

  
381 478
static int eth_can_receive(void *opaque)
......
393 490

  
394 491
static void eth_receive(void *opaque, const uint8_t *buf, int size)
395 492
{
493
	unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
396 494
	struct fs_eth *eth = opaque;
495
	int use_ma0 = eth->regs[RW_REC_CTRL] & 1;
496
	int use_ma1 = eth->regs[RW_REC_CTRL] & 2;
497
	int r_bcast = eth->regs[RW_REC_CTRL] & 8;
498

  
499
	if (size < 12)
500
		return;
501

  
502
	D(printf("%x.%x.%x.%x.%x.%x ma=%d %d bc=%d\n",
503
		 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
504
		 use_ma0, use_ma1, r_bcast));
505
	       
506
	/* Does the frame get through the address filters?  */
507
	if ((!use_ma0 || memcmp(buf, eth->macaddr[0], 6))
508
	    && (!use_ma1 || memcmp(buf, eth->macaddr[1], 6))
509
	    && (!r_bcast || memcmp(buf, sa_bcast, 6))
510
	    && !eth_match_groupaddr(eth, buf))
511
		return;
512

  
397 513
	if (size > sizeof(eth->rx_fifo)) {
398
		/* TODO: signal error.  */
514
		/* TODO: signal error.	*/
515
	} else if (eth->rx_fifo_len) {
516
		/* FIFO overrun.  */
399 517
	} else {
400 518
		memcpy(eth->rx_fifo, buf, size);
401
		/* +4, HW passes the CRC to sw.  */
519
		/* +4, HW passes the CRC to sw.	 */
402 520
		eth->rx_fifo_len = size + 4;
403 521
		eth->rx_fifo_pos = 0;
404 522
	}
......
471 589
	eth->irq = irq;
472 590
	eth->dma_out = dma;
473 591
	eth->dma_in = dma + 1;
474
	memcpy(eth->macaddr, nd->macaddr, 6);
475 592

  
476 593
	/* Connect the phy.  */
477 594
	tdk_init(&eth->phy);

Also available in: Unified diff