int
eth_init(bd_t * bis)
{
	u32 Options;
	XStatus Result;

#ifdef DEBUG
	printf("EMAC Initialization Started\n\r");
#endif

	Result = XEmac_Initialize(&Emac, XPAR_EMAC_0_DEVICE_ID);
	if (Result != XST_SUCCESS) {
		return 0;
	}

	/* make sure the Emac is stopped before it is started */
	(void) XEmac_Stop(&Emac);

#ifdef CFG_ENV_IS_NOWHERE
	memcpy(bis->bi_enetaddr, EMACAddr, 6);
#endif

	Result = XEmac_SetMacAddress(&Emac, bis->bi_enetaddr);
	if (Result != XST_SUCCESS) {
		return 0;
	}

	Options =
	    (XEM_POLLED_OPTION | XEM_UNICAST_OPTION | XEM_BROADCAST_OPTION |
	     XEM_FDUPLEX_OPTION | XEM_INSERT_FCS_OPTION |
	     XEM_INSERT_PAD_OPTION);
	Result = XEmac_SetOptions(&Emac, Options);
	if (Result != XST_SUCCESS) {
		return 0;
	}

	Result = XEmac_Start(&Emac);
	if (Result != XST_SUCCESS) {
		return 0;
	}
#ifdef DEBUG
	printf("EMAC Initialization complete\n\r");
#endif

	initialized = 1;

	return (0);
}
int
eth_init(struct snet *snetp, XIntc *xintc_instance, struct eth_init_data *init_data)
{
    int           result;
    XStatus       status;
    Xuint32       options;
    XEmac_Config *config;

    Xuint16     xemac_device_id;
    Xuint16     xemac_intr_id;
    XEmac      *xemac_instance;

    struct mac_callbacks  mac_callbacks;

    void    (*send_handler)(void *callback_ref);
    void    (*recv_handler)(void *callback_ref);
    void    (*error_handler)(void *callback_ref);


    xemac_device_id = XPAR_ETHERNET_MAC_DEVICE_ID;
    xemac_intr_id   = XPAR_OPB_INTC_0_ETHERNET_MAC_IP2INTC_IRPT_INTR;

    xemac_instance = &xemac;

    send_handler  = init_data->tx_handler;
    recv_handler  = init_data->rx_handler;
    error_handler = init_data->error_handler;


    /*
     * We change the configuration of the device to indicate no DMA just in
     * case it was built with DMA. In order for this code to work, you
     * either need to do this or, better yet, build the hardware without DMA.
     */
    config = XEmac_LookupConfig(xemac_device_id);
    config->IpIfDmaConfig = XEM_CFG_NO_DMA;

    status = XEmac_Initialize(xemac_instance, xemac_device_id);
    if (status != XST_SUCCESS) {
	mbfw_printf("MBFW_ERROR: XEmac_Initialize() failed with status 0x%x \r\n", status);
        return -1;
    }

    status = XEmac_SelfTest(xemac_instance);
    if (status != XST_SUCCESS) {
	mbfw_printf("MBFW_ERROR: XEmac_SelfTest() failed with status 0x%x \r\n", status);
        return -1;
    }

    /*
     * Configure the device for unicast and broadcast addressing.
     */

    options = (DEFAULT_OPTIONS | XEM_BROADCAST_OPTION);
    status = XEmac_SetOptions(xemac_instance, options);
    if (status != XST_SUCCESS) {
	mbfw_printf("MBFW_ERROR: XEmac_SetOptions() failed with status 0x%x \r\n", status);
        return -1;
    }


    /*
     * Connect to the interrupt controller and enable interrupts
     */
    result = emac_setup_intr_system(xintc_instance,
                                    xemac_instance,
                                    xemac_device_id,
                                    xemac_intr_id);
    if (result < 0) {
        return -1;
    }

    /*
     * Set the FIFO callbacks and error handler. These callbacks are invoked
     * by the driver during interrupt processing.
     */
    XEmac_SetFifoSendHandler(xemac_instance, snetp, send_handler);
    XEmac_SetFifoRecvHandler(xemac_instance, snetp, recv_handler);
    /*
     * Ignoring the user error_handler because of mismatch in function types.
     * Needs to be fixed.
     */
    XEmac_SetErrorHandler(xemac_instance, snetp, xemac_error_handler);


    mac_callbacks.eth_start         = xemac_start;
    mac_callbacks.eth_stop          = xemac_stop;
    mac_callbacks.eth_set_mac_addr  = xemac_set_mac_addr;
    mac_callbacks.eth_tx            = xemac_tx;
    mac_callbacks.eth_rx            = xemac_rx;
    mac_callbacks.eth_rx_tohw       = NULL;

    mbfw_snet_register(snetp, xemac_instance, &mac_callbacks);

    return 0;
}