int eth_init(bd_t *bd) {
	int r;
	u8 dev_addr[6];
	char ethaddr[20];

	PRINTK("### eth_init\n");

	if (!pbuf) {
		pbuf = malloc(2000);
		if (!pbuf) {
			printf("Cannot allocate rx buffer\n");
			return -1;
		}
	}

#ifdef CONFIG_DRIVER_NE2000_CCR
	{
		vu_char *p = (vu_char *) CONFIG_DRIVER_NE2000_CCR;

		PRINTK("CCR before is %x\n", *p);
		*p = CONFIG_DRIVER_NE2000_VAL;
		PRINTK("CCR after is %x\n", *p);
	}
#endif

	nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE;

	r = get_prom(dev_addr, nic.base);
	if (!r)
		return -1;

	sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
		 dev_addr[0], dev_addr[1],
		 dev_addr[2], dev_addr[3],
		 dev_addr[4], dev_addr[5]) ;
	PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr);
	setenv ("ethaddr", ethaddr);

	nic.data = nic.base + DP_DATA;
	nic.tx_buf1 = START_PG;
	nic.tx_buf2 = START_PG2;
	nic.rx_buf_start = RX_START;
	nic.rx_buf_end = RX_END;

	if (dp83902a_init() == false)
		return -1;

	dp83902a_start(dev_addr);
	initialized = 1;

	return 0;
}
Exemplo n.º 2
0
int eth_init(bd_t *bd) {
	static hw_info_t * r;
	char ethaddr[20];

	PRINTK("### eth_init\n");

	if (!pbuf) {
		pbuf = malloc(NB*2000);
		if (!pbuf) {
			printf("Cannot allocate rx buffers\n");
			return -1;
		}
	}

#ifdef CONFIG_DRIVER_NE2000_CCR
	{
		volatile unsigned char *p =  (volatile unsigned char *) CONFIG_DRIVER_NE2000_CCR;

		PRINTK("CCR before is %x\n", *p);
		*p = CONFIG_DRIVER_NE2000_VAL;
		PRINTK("CCR after is %x\n", *p);
	}
#endif

	nic_base = CONFIG_DRIVER_NE2000_BASE;
	nic.base = (cyg_uint8 *) CONFIG_DRIVER_NE2000_BASE;

	r = get_prom();
	if (!r)
		return -1;

	sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
		 dev_addr[0], dev_addr[1],
		 dev_addr[2], dev_addr[3],
		 dev_addr[4], dev_addr[5]) ;
	PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr);
	setenv ("ethaddr", ethaddr);


#define DP_DATA		0x10
	nic.data = nic.base + DP_DATA;
	nic.tx_buf1 = 0x40;
	nic.tx_buf2 = 0x48;
	nic.rx_buf_start = 0x50;
	nic.rx_buf_end = 0x80;

	if (dp83902a_init() == false)
		return -1;
	dp83902a_start(dev_addr);
	return 0;
}
Exemplo n.º 3
0
/**
 * Setup the driver and init MAC address according to doc/README.enetaddr
 * Called by ne2k_register() before registering the driver @eth layer
 *
 * @param struct ethdevice of this instance of the driver for dev->enetaddr
 * @return 0 on success, -1 on error (causing caller to print error msg)
 */
static int ne2k_setup_driver(struct eth_device *dev)
{
    PRINTK("### ne2k_setup_driver\n");

    if (!pbuf) {
        pbuf = malloc(2000);
        if (!pbuf) {
            printf("Cannot allocate rx buffer\n");
            return -1;
        }
    }

#ifdef CONFIG_DRIVER_NE2000_CCR
    {
        vu_char *p = (vu_char *) CONFIG_DRIVER_NE2000_CCR;

        PRINTK("CCR before is %x\n", *p);
        *p = CONFIG_DRIVER_NE2000_VAL;
        PRINTK("CCR after is %x\n", *p);
    }
#endif

    nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE;

    nic.data = nic.base + DP_DATA;
    nic.tx_buf1 = START_PG;
    nic.tx_buf2 = START_PG2;
    nic.rx_buf_start = RX_START;
    nic.rx_buf_end = RX_END;

    /*
     * According to doc/README.enetaddr, drivers shall give priority
     * to the MAC address value in the environment, so we do not read
     * it from the prom or eeprom if it is specified in the environment.
     */
    if (!eth_getenv_enetaddr("ethaddr", dev->enetaddr)) {
        /* If the MAC address is not in the environment, get it: */
        if (!get_prom(dev->enetaddr, nic.base)) /* get MAC from prom */
            dp83902a_init(dev->enetaddr);   /* fallback: seeprom */
        /* And write it into the environment otherwise eth_write_hwaddr
         * returns -1 due to eth_getenv_enetaddr_by_index() failing,
         * and this causes "Warning: failed to set MAC address", and
         * cmd_bdinfo has no ethaddr value which it can show: */
        eth_setenv_enetaddr("ethaddr", dev->enetaddr);
    }
    return 0;
}
Exemplo n.º 4
0
int ne2k_init(struct nic_priv_data *nic_data)
{
	int r;
	u8 eth_addr[6];

	if (!nic_data) {
		return VMM_EFAIL;
	}

	if (!nic_data->rx_rb) {
		nic_data->rx_rb = vmm_ringbuf_alloc(1, 2000);
		if (!nic_data->rx_rb) {
			vmm_printf("Cannot allocate receive buffer\n");
			return VMM_EFAIL;
		}
	}

	nic_data->base = (u8 *) (isa_vbase + CONFIG_DRIVER_NE2000_BASE);

	r = get_prom(nic_data, eth_addr);
	if (r != VMM_OK)
		return VMM_EFAIL;

	nic_data->data = nic_data->base + DP_DATA;
	nic_data->tx_buf1 = START_PG;
	nic_data->tx_buf2 = START_PG2;
	nic_data->rx_buf_start = RX_START;
	nic_data->rx_buf_end = RX_END;
	vmm_memcpy(nic_data->esa, eth_addr, sizeof(nic_data->esa));

	if (dp83902a_init(nic_data) != true) {
		return VMM_EFAIL;
	}

	dp83902a_start(nic_data, eth_addr);
	nic_data->initialized = 1;

	return VMM_OK;
}
Exemplo n.º 5
0
static int
is_ok2shutdown(time_t *now)
{
	int	prom_fd = -1;
	char	power_cycles_st[LLEN];
	char	power_cycle_limit_st[LLEN];
	char	system_board_date_st[LLEN];
	int	power_cycles, power_cycle_limit, free_cycles, scaled_cycles;
	time_t	life_began, life_passed;
	int	no_power_cycles = 0;
	int	no_system_board_date = 0;
	int	ret = 1;

	/* CONSTCOND */
	while (1) {
		if ((prom_fd = open(PROM, O_RDWR)) == -1 &&
			(errno == EAGAIN))
				continue;
		break;
	}

	/*
	 * when #power-cycles property does not exist
	 * power cycles are unlimited.
	 */
	if (get_prom(prom_fd, options, "#power-cycles",
	    power_cycles_st, sizeof (power_cycles_st)) == 0)
		goto ckdone;

	if (get_prom(prom_fd, root, "power-cycle-limit",
	    power_cycle_limit_st, sizeof (power_cycle_limit_st)) == 0) {
		power_cycle_limit = DEFAULT_POWER_CYCLE_LIMIT;
	} else {
		power_cycle_limit = atoi(power_cycle_limit_st);
	}

	/*
	 * Allow 10% of power_cycle_limit as free cycles.
	 */
	free_cycles = power_cycle_limit * 0.1;

	power_cycles = atoi(power_cycles_st);
	if (power_cycles < 0)
		no_power_cycles++;
	else if (power_cycles <= free_cycles)
		goto ckdone;

	if (no_power_cycles && log_power_cycles_error == 0) {
		logerror("Invalid PROM property \"#power-cycles\" was found.");
		log_power_cycles_error++;
	}

	if (get_prom(prom_fd, options, "system-board-date",
	    system_board_date_st, sizeof (system_board_date_st)) == 0) {
		no_system_board_date++;
	} else {
		life_began = strtol(system_board_date_st, (char **)NULL, 16);
		if (life_began > *now) {
			no_system_board_date++;
		}
	}
	if (no_system_board_date) {
		if (log_system_board_date_error == 0) {
			logerror("No or invalid PROM property "
			    "\"system-board-date\" was found.");
			log_system_board_date_error++;
		}
		life_began = DEFAULT_SYSTEM_BOARD_DATE;
	}

	life_passed = *now - life_began;

	/*
	 * Since we don't keep the date that last free_cycle is ended, we
	 * need to spread (power_cycle_limit - free_cycles) over the entire
	 * 7-year life span instead of (lifetime - date free_cycles ended).
	 */
	scaled_cycles = ((float)life_passed / (float)LIFETIME_SECS) *
				(power_cycle_limit - free_cycles);

	if (no_power_cycles)
		goto ckdone;

#ifdef DEBUG
	(void) fprintf(stderr, "Actual power_cycles = %d\t"
				"Scaled power_cycles = %d\n",
				power_cycles, scaled_cycles);
#endif
	if (power_cycles > scaled_cycles) {
		if (log_no_autoshutdown_warning == 0) {
			logerror("Automatic shutdown has been temporarily "
			    "suspended in order to preserve the reliability "
			    "of this system.");
			log_no_autoshutdown_warning++;
		}
		ret = 0;
		goto ckdone;
	}

ckdone:
	if (prom_fd != -1)
		close(prom_fd);
	return (ret);
}
Exemplo n.º 6
0
static int pcnet_confcheck(struct pcmcia_device *p_dev, void *priv_data)
{
	int *priv = priv_data;
	int try = (*priv & 0x1);

	*priv &= (p_dev->resource[2]->end >= 0x4000) ? 0x10 : ~0x10;

	if (p_dev->config_index == 0)
		return -EINVAL;

	if (p_dev->resource[0]->end + p_dev->resource[1]->end < 32)
		return -EINVAL;

	if (try)
		p_dev->io_lines = 16;
	return try_io_port(p_dev);
}

static hw_info_t *pcnet_try_config(struct pcmcia_device *link,
				   int *has_shmem, int try)
{
	struct net_device *dev = link->priv;
	hw_info_t *local_hw_info;
	pcnet_dev_t *info = PRIV(dev);
	int priv = try;
	int ret;

	ret = pcmcia_loop_config(link, pcnet_confcheck, &priv);
	if (ret) {
		dev_warn(&link->dev, "no useable port range found\n");
		return NULL;
	}
	*has_shmem = (priv & 0x10);

	if (!link->irq)
		return NULL;

	if (resource_size(link->resource[1]) == 8)
		link->config_flags |= CONF_ENABLE_SPKR;

	if ((link->manf_id == MANFID_IBM) &&
	    (link->card_id == PRODID_IBM_HOME_AND_AWAY))
		link->config_index |= 0x10;

	ret = pcmcia_enable_device(link);
	if (ret)
		return NULL;

	dev->irq = link->irq;
	dev->base_addr = link->resource[0]->start;

	if (info->flags & HAS_MISC_REG) {
		if ((if_port == 1) || (if_port == 2))
			dev->if_port = if_port;
		else
			dev_notice(&link->dev, "invalid if_port requested\n");
	} else
		dev->if_port = 0;

	if ((link->config_base == 0x03c0) &&
	    (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
		dev_info(&link->dev,
			"this is an AX88190 card - use axnet_cs instead.\n");
		return NULL;
	}

	local_hw_info = get_hwinfo(link);
	if (!local_hw_info)
		local_hw_info = get_prom(link);
	if (!local_hw_info)
		local_hw_info = get_dl10019(link);
	if (!local_hw_info)
		local_hw_info = get_ax88190(link);
	if (!local_hw_info)
		local_hw_info = get_hwired(link);

	return local_hw_info;
}

static int pcnet_config(struct pcmcia_device *link)
{
    struct net_device *dev = link->priv;
    pcnet_dev_t *info = PRIV(dev);
    int start_pg, stop_pg, cm_offset;
    int has_shmem = 0;
    hw_info_t *local_hw_info;

    dev_dbg(&link->dev, "pcnet_config\n");

    local_hw_info = pcnet_try_config(link, &has_shmem, 0);
    if (!local_hw_info) {
	    /* check whether forcing io_lines to 16 helps... */
	    pcmcia_disable_device(link);
	    local_hw_info = pcnet_try_config(link, &has_shmem, 1);
	    if (local_hw_info == NULL) {
		    dev_notice(&link->dev, "unable to read hardware net"
			    " address for io base %#3lx\n", dev->base_addr);
		    goto failed;
	    }
    }

    info->flags = local_hw_info->flags;
    /* Check for user overrides */
    info->flags |= (delay_output) ? DELAY_OUTPUT : 0;
    if ((link->manf_id == MANFID_SOCKET) &&
	((link->card_id == PRODID_SOCKET_LPE) ||
	 (link->card_id == PRODID_SOCKET_LPE_CF) ||
	 (link->card_id == PRODID_SOCKET_EIO)))
	info->flags &= ~USE_BIG_BUF;
    if (!use_big_buf)
	info->flags &= ~USE_BIG_BUF;

    if (info->flags & USE_BIG_BUF) {
	start_pg = SOCKET_START_PG;
	stop_pg = SOCKET_STOP_PG;
	cm_offset = 0x10000;
    } else {
	start_pg = PCNET_START_PG;
	stop_pg = PCNET_STOP_PG;
	cm_offset = 0;
    }

    /* has_shmem is ignored if use_shmem != -1 */
    if ((use_shmem == 0) || (!has_shmem && (use_shmem == -1)) ||
	(setup_shmem_window(link, start_pg, stop_pg, cm_offset) != 0))
	setup_dma_config(link, start_pg, stop_pg);

    ei_status.name = "NE2000";
    ei_status.word16 = 1;
    ei_status.reset_8390 = pcnet_reset_8390;

    if (info->flags & (IS_DL10019|IS_DL10022))
	mii_phy_probe(dev);

    SET_NETDEV_DEV(dev, &link->dev);

    if (register_netdev(dev) != 0) {
	pr_notice("register_netdev() failed\n");
	goto failed;
    }

    if (info->flags & (IS_DL10019|IS_DL10022)) {
	u_char id = inb(dev->base_addr + 0x1a);
	netdev_info(dev, "NE2000 (DL100%d rev %02x): ",
	       (info->flags & IS_DL10022) ? 22 : 19, id);
	if (info->pna_phy)
	    pr_cont("PNA, ");
    } else {
	netdev_info(dev, "NE2000 Compatible: ");
    }
    pr_cont("io %#3lx, irq %d,", dev->base_addr, dev->irq);
    if (info->flags & USE_SHMEM)
	pr_cont(" mem %#5lx,", dev->mem_start);
    if (info->flags & HAS_MISC_REG)
	pr_cont(" %s xcvr,", if_names[dev->if_port]);
    pr_cont(" hw_addr %pM\n", dev->dev_addr);
    return 0;

failed:
    pcnet_release(link);
    return -ENODEV;
} /* pcnet_config */

static void pcnet_release(struct pcmcia_device *link)
{
	pcnet_dev_t *info = PRIV(link->priv);

	dev_dbg(&link->dev, "pcnet_release\n");

	if (info->flags & USE_SHMEM)
		iounmap(info->base);

	pcmcia_disable_device(link);
}