Beispiel #1
0
int get_prom(u8* mac_addr, u8* base_addr)
{
	u8 prom[32];
	int i, j;
	struct {
		u_char value, offset;
	} program_seq[] = {
		{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
		{0x48, EN0_DCFG},		/* Set byte-wide (0x48) access. */
		{0x00, EN0_RCNTLO},		/* Clear the count regs. */
		{0x00, EN0_RCNTHI},
		{0x00, EN0_IMR},		/* Mask completion irq. */
		{0xFF, EN0_ISR},
		{E8390_RXOFF, EN0_RXCR},	/* 0x20 Set to monitor */
		{E8390_TXOFF, EN0_TXCR},	/* 0x02 and loopback mode. */
		{32, EN0_RCNTLO},
		{0x00, EN0_RCNTHI},
		{0x00, EN0_RSARLO},		/* DMA starting at 0x0000. */
		{0x00, EN0_RSARHI},
		{E8390_RREAD+E8390_START, E8390_CMD},
	};

	PRINTK ("trying to get MAC via prom reading\n");

	pcnet_reset_8390 (base_addr);

	mdelay (10);

	for (i = 0; i < sizeof (program_seq) / sizeof (program_seq[0]); i++)
		n2k_outb (program_seq[i].value, program_seq[i].offset);

	PRINTK ("PROM:");
	for (i = 0; i < 32; i++) {
		prom[i] = n2k_inb (PCNET_DATAPORT);
		PRINTK (" %02x", prom[i]);
	}
	PRINTK ("\n");
	for (i = 0; i < NR_INFO; i++) {
		if ((prom[0] == hw_info[i].a0) &&
			(prom[2] == hw_info[i].a1) &&
			(prom[4] == hw_info[i].a2)) {
			PRINTK ("matched board %d\n", i);
			break;
		}
	}
	if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) {
		PRINTK ("on exit i is %d/%ld\n", i, NR_INFO);
		PRINTK ("MAC address is ");
		for (j = 0; j < 6; j++) {
			mac_addr[j] = prom[j << 1];
			PRINTK ("%02x:", mac_addr[i]);
		}
		PRINTK ("\n");
		return (i < NR_INFO) ? i : 0;
	}
	return 0;
}
Beispiel #2
0
int get_prom(struct nic_priv_data *dp, u8* mac_addr)
{
	u8 prom[32];
	int i, j;
	struct {
		unsigned char value, offset;
	} program_seq[] = {
		{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
		{0x48, EN0_DCFG},		/* Set byte-wide (0x48) access. */
		{0x00, EN0_RCNTLO},		/* Clear the count regs. */
		{0x00, EN0_RCNTHI},
		{0x00, EN0_IMR},		/* Mask completion irq. */
		{0xFF, EN0_ISR},
		{E8390_RXOFF, EN0_RXCR},	/* 0x20 Set to monitor */
		{E8390_TXOFF, EN0_TXCR},	/* 0x02 and loopback mode. */
		{32, EN0_RCNTLO},
		{0x00, EN0_RCNTHI},
		{0x00, EN0_RSARLO},		/* DMA starting at 0x0000. */
		{0x00, EN0_RSARHI},
		{E8390_RREAD+E8390_START, E8390_CMD},
	};

	pcnet_reset_8390(dp);

	for (i = 0; i < sizeof (program_seq) / sizeof (program_seq[0]); i++)
		n2k_outb (dp, program_seq[i].value, program_seq[i].offset);

	for (i = 0; i < 32; i++) {
		prom[i] = n2k_inb (dp, PCNET_DATAPORT);
	}

	for (i = 0;; i++) {
		if (hw_info[i].dev_name == NULL) break;

		if ((prom[0] == hw_info[i].a0) &&
			(prom[2] == hw_info[i].a1) &&
			(prom[4] == hw_info[i].a2)) {
			vmm_printf("%s detected.\n", hw_info[i].dev_name);
			break;
		}
	}

	if ((prom[28] == 0x57) && (prom[30] == 0x57)) {
		vmm_printf ("MAC address is ");
		for (j = 0; j < 6; j++) {
			if (j) vmm_printf(":");
			mac_addr[j] = prom[j << 1];
			vmm_printf ("%02x", mac_addr[j]);
		}
		vmm_printf ("\n");
	}
	return VMM_OK;
}
Beispiel #3
0
static int pcnet_resume(struct pcmcia_device *link)
{
	struct net_device *dev = link->priv;

	if (link->open) {
		pcnet_reset_8390(dev);
		NS8390_init(dev, 1);
		netif_device_attach(dev);
	}

	return 0;
}
Beispiel #4
0
static hw_info_t *get_prom(struct pcmcia_device *link)
{
    struct net_device *dev = link->priv;
    unsigned int ioaddr = dev->base_addr;
    u_char prom[32];
    int i, j;

    /* This is lifted straight from drivers/net/ethernet/8390/ne.c */
    struct {
	u_char value, offset;
    } program_seq[] = {
	{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
	{0x48,	EN0_DCFG},	/* Set byte-wide (0x48) access. */
	{0x00,	EN0_RCNTLO},	/* Clear the count regs. */
	{0x00,	EN0_RCNTHI},
	{0x00,	EN0_IMR},	/* Mask completion irq. */
	{0xFF,	EN0_ISR},
	{E8390_RXOFF, EN0_RXCR},	/* 0x20  Set to monitor */
	{E8390_TXOFF, EN0_TXCR},	/* 0x02  and loopback mode. */
	{32,	EN0_RCNTLO},
	{0x00,	EN0_RCNTHI},
	{0x00,	EN0_RSARLO},	/* DMA starting at 0x0000. */
	{0x00,	EN0_RSARHI},
	{E8390_RREAD+E8390_START, E8390_CMD},
    };

    pcnet_reset_8390(dev);
    mdelay(10);

    for (i = 0; i < ARRAY_SIZE(program_seq); i++)
	outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);

    for (i = 0; i < 32; i++)
	prom[i] = inb(ioaddr + PCNET_DATAPORT);
    for (i = 0; i < NR_INFO; i++) {
	if ((prom[0] == hw_info[i].a0) &&
	    (prom[2] == hw_info[i].a1) &&
	    (prom[4] == hw_info[i].a2))
	    break;
    }
    if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) {
	for (j = 0; j < 6; j++)
	    dev->dev_addr[j] = prom[j<<1];
	return (i < NR_INFO) ? hw_info+i : &default_info;
    }
    return NULL;
} /* get_prom */
Beispiel #5
0
static void dma_block_output(struct net_device *dev, int count,
			     const u_char *buf, const int start_page)
{
    unsigned int nic_base = dev->base_addr;
    pcnet_dev_t *info = PRIV(dev);
#ifdef PCMCIA_DEBUG
    int retries = 0;
#endif
    u_long dma_start;

#ifdef PCMCIA_DEBUG
    if (ei_debug > 4)
	netdev_dbg(dev, "[bo=%d]\n", count);
#endif

    /* Round the count up for word writes.  Do we need to do this?
       What effect will an odd byte count have on the 8390?
       I should check someday. */
    if (count & 0x01)
	count++;
    if (ei_status.dmaing) {
	netdev_notice(dev, "DMAing conflict in dma_block_output."
	       "[DMAstat:%1x][irqlock:%1x]\n",
	       ei_status.dmaing, ei_status.irqlock);
	return;
    }
    ei_status.dmaing |= 0x01;
    /* We should already be in page 0, but to be safe... */
    outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base+PCNET_CMD);

#ifdef PCMCIA_DEBUG
  retry:
#endif

    outb_p(ENISR_RDC, nic_base + EN0_ISR);

    /* Now the normal output. */
    outb_p(count & 0xff, nic_base + EN0_RCNTLO);
    outb_p(count >> 8,   nic_base + EN0_RCNTHI);
    outb_p(0x00, nic_base + EN0_RSARLO);
    outb_p(start_page, nic_base + EN0_RSARHI);

    outb_p(E8390_RWRITE+E8390_START, nic_base + PCNET_CMD);
    outsw(nic_base + PCNET_DATAPORT, buf, count>>1);

    dma_start = jiffies;

#ifdef PCMCIA_DEBUG
    /* This was for the ALPHA version only, but enough people have been
       encountering problems that it is still here. */
    if (ei_debug > 4) {	/* DMA termination address check... */
	int addr, tries = 20;
	do {
	    int high = inb_p(nic_base + EN0_RSARHI);
	    int low = inb_p(nic_base + EN0_RSARLO);
	    addr = (high << 8) + low;
	    if ((start_page << 8) + count == addr)
		break;
	} while (--tries > 0);
	if (tries <= 0) {
	    netdev_notice(dev, "Tx packet transfer address mismatch,"
		   "%#4.4x (expected) vs. %#4.4x (actual).\n",
		   (start_page << 8) + count, addr);
	    if (retries++ == 0)
		goto retry;
	}
    }
#endif

    while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
	if (time_after(jiffies, dma_start + PCNET_RDC_TIMEOUT)) {
	    netdev_notice(dev, "timeout waiting for Tx RDC.\n");
	    pcnet_reset_8390(dev);
	    NS8390_init(dev, 1);
	    break;
	}

    outb_p(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
    if (info->flags & DELAY_OUTPUT)
	udelay((long)delay_time);
    ei_status.dmaing &= ~0x01;
}