// This function is called during system initialization to register a
// network interface with the system.
static void
eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr)
{
  struct netif *netif = &sc->sc_arpcom.ac_if;
  
  netif->state = sc;
  ecosif_init(netif);
  
  // enaddr == 0 -> hardware init was incomplete (no ESA)
  if (enaddr != 0) {
    // Set up hardware address
    memcpy(netif->hwaddr, enaddr, ETHER_ADDR_LEN);
    // Perform any hardware initialization
    (sc->funs->start) (sc, (unsigned char *) &netif->hwaddr, 0);
  }
#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
// Set up interfaces so debug environment can share this device
    {
        void *dbg = CYGACC_CALL_IF_DBG_DATA();
        if (!dbg) {
            CYGACC_CALL_IF_DBG_DATA_SET((void *)sc);
        }
    }
#endif
    //
    // we call this after the driver was started successfully
    //
    lwip_dhcp_init(netif);
}
Exemple #2
0
//
// Receive one packet of data from the hardware, if available
//
int
eth_drv_read(char *eth_hdr, char *buf, int len)
{
    struct eth_drv_sc *sc = __local_enet_sc;
    struct eth_msg *msg;
    int res;
    void *dbg = CYGACC_CALL_IF_DBG_DATA();
    int old_state;
    void *eth_drv_old = 0;

    if (dbg) {
        sc = (struct eth_drv_sc *)dbg;  // Use control from installed driver
        eth_drv_old = sc->funs->eth_drv_old;
        if (eth_drv_old == 0) {
            sc->funs->eth_drv_old = sc->funs->eth_drv;
            sc->funs->eth_drv = &eth_drv_funs;    // Substitute stand-alone driver
            old_state = sc->state;
            if (!old_state & ETH_DRV_STATE_ACTIVE) {
                // This interface not fully initialized, do it now
                (sc->funs->start)(sc, (unsigned char *)&__local_enet_addr, 0);
                sc->state |= ETH_DRV_STATE_ACTIVE;
            }
        }
    }
    (sc->funs->poll)(sc);  // Give the driver a chance to fetch packets
    msg = eth_drv_msg_get(&eth_msg_full);
    if (msg && len >= msg->len - 14) {
        memcpy(eth_hdr, msg->data, 14);
        memcpy(buf, &msg->data[14], msg->len-14);
        res = msg->len;
    } else {
        res = 0;
    }
    if (msg) {
        eth_drv_msg_put(&eth_msg_free, msg);
    }
   
    if (dbg) {
        if (eth_drv_old == 0) {
            sc->funs->eth_drv = sc->funs->eth_drv_old;
            sc->funs->eth_drv_old = (struct eth_drv_funs *)0;
        }
//        if (!old_state & ETH_DRV_STATE_ACTIVE) {
//            // This interface was not fully initialized, shut it back down
//            (sc->funs->stop)(sc);
//        }
    }
    return res;
}
Exemple #3
0
void
eth_drv_write(char *eth_hdr, char *buf, int len)
{
    struct eth_drv_sg sg_list[MAX_ETH_DRV_SG];
    struct eth_drv_sc *sc = __local_enet_sc;
    int sg_len = 2;
    void *dbg = CYGACC_CALL_IF_DBG_DATA();
    int old_state;
    int wait_time = 5;  // Timeout before giving up
    void *eth_drv_old = 0;

    if (dbg) {
        sc = (struct eth_drv_sc *)dbg;  // Use control from installed driver
        eth_drv_old = sc->funs->eth_drv_old;
        if (eth_drv_old == 0) {
            sc->funs->eth_drv_old = sc->funs->eth_drv;        
            sc->funs->eth_drv = &eth_drv_funs;    // Substitute stand-alone driver
            old_state = sc->state;
            if (!old_state & ETH_DRV_STATE_ACTIVE) {
                // This interface not fully initialized, do it now
                (sc->funs->start)(sc, (unsigned char *)&__local_enet_addr, 0);
                sc->state |= ETH_DRV_STATE_ACTIVE;
            }
        }
    }

    while (!(sc->funs->can_send)(sc)) {
        // Give driver a chance to service hardware
        (sc->funs->poll)(sc);
        CYGACC_CALL_IF_DELAY_US(2*100000);
        if (--wait_time <= 0)
            goto reset_and_out;  // Give up on sending packet
    }

    sg_list[0].buf = (CYG_ADDRESS)eth_hdr;
    sg_list[0].len = 14;  // FIXME
    sg_list[1].buf = (CYG_ADDRESS)buf;
    sg_list[1].len = len;
    packet_sent = 0;
#ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
    if (cyg_io_eth_net_debug) {
        int old_console;
        old_console = start_console();
        diag_printf("Ethernet send:\n");
        DIAG_DUMP_BUF_HDR(eth_hdr, 14);
        DIAG_DUMP_BUF_BDY(buf, len);
        end_console(old_console);
    }
#endif

    (sc->funs->send)(sc, sg_list, sg_len, len+14, (CYG_ADDRWORD)&packet_sent);

    wait_time = 50000;
    while (1) {
        (sc->funs->poll)(sc);

	if(packet_sent)
	    break;
	
        CYGACC_CALL_IF_DELAY_US(2*10);
        if (--wait_time <= 0)
            goto reset_and_out;  // Give up on sending packet
    }
 reset_and_out:   
    if (dbg) {
//        if (!old_state & ETH_DRV_STATE_ACTIVE) {
//            // This interface was not fully initialized, shut it back down
//            (sc->funs->stop)(sc);
//        }
        if (eth_drv_old == 0) {
            sc->funs->eth_drv = sc->funs->eth_drv_old;
            sc->funs->eth_drv_old = (struct eth_drv_funs *)0;
        }
    }
}