예제 #1
0
static void
rfa_init () 
{
    //cprintf ("\n\nRFA Initialization started! \n");

    rfa_alloc ();

    outl(nic.io_base + CSR_GP, nic.rfa.front->phy_addr);
    e100_exec_cmd (CSR_COMMAND, RUC_START); 


/**
 * This section is for test when we finished rfa_alloc ()  
 **/
//#define HAVE_RFA_ALLOC_TEST
#ifdef HAVE_RFA_ALLOC_TEST
    while (nic.rfa.rfd_avail > 0)
        rfa_validate ();

    int scb_status = inb(nic.io_base + CSR_STATUS);

    printf ("rfd slot is full, current RU state = %02x\n", scb_status & RUS_MASK);

    char s[1518];
    while (rfa_retrieve_data (s) >= 0);


    e100_exec_cmd (CSR_COMMAND, RUC_RESUME);

    while (nic.rfa.rfd_avail > 0)
        rfa_validate ();
#endif /* test rfa_allc */
}
예제 #2
0
파일: e100.c 프로젝트: mcorley/jos
// 
// Frames arrive at the device independent of the state of the RU. When a frame 
// is arriving, the E100 is referred to as actively receiving, even when the RU 
// is not in the ready state and the frame is being discarded.
// 
int
e100_rx(char *data)
{
	int r, scb_status;

	// Clean up any RFDs in the ring that are complete.
	e100_rx_clean();

	// If there are no more empty slots in the 
	// receive DMA ring drop the packet.
	if (e100.rfds_avail == 0)
		return -E_RFA_FULL;

	// If there are no packets in the receive DMA ring signal
	// to the asking the user environment to go to sleep and
	// try to re-execute the system call at a later time.
	if (e100.rfds_avail == RFASIZE)
		return -E_RFA_EMPTY;

	// Indicate newly arrived packets.
	r = e100_rx_indicate(data);

	scb_status = inb(e100.io_base + CSR_SCB_STATUS);	
	if ((scb_status & RUS_MASK) == RUS_SUSPENDED) {
		// if the RU is in the suspended state and not actively 
		// discarding a frame the RU goes to the ready state and 
		// configures a new RFD when we issue the resume command.		
		e100_exec_cmd(CSR_SCB_COMMAND, RUC_RESUME);
	}

	return r;	
}
예제 #3
0
파일: e100.c 프로젝트: mcorley/jos
//
// Transmits a packet of data in simple mode. The simplified structure expects 
// the transmit data to reside entirely in the memory space immediately after 
// the transmit command block (TCB).
// If there are no more empty slots in the transmit DMA ring we simply 
// drop the packet to avoid possible deadlock situations that might rise
// up if we pause the environment to allow the card to catch up.
//
// RETURNS
// 	0 on success
// 	-E_CBL_FULL if no more empty slots in cbl
//
int
e100_xmit_frame(const char *data, uint16_t len)
{
	// Reclaim CBs in the CBL that were successfully 
	// sent over the wire by the CU.
	e100_tx_clean();

	// If there are no more empty slots in the 
	// transmit DMA ring drop the packet.
	if (e100.cbs_avail == 0)
		return -E_CBL_FULL;

	// Places the packet into the next available buffer in the ring.
	// Clear the S bit on the current CB so the CU proceeds to execute 
	// the new CB when we resume CU operation.	
	e100.cb_to_use->command &= ~CB_S;
	e100_xmit_prepare(data, len, CB_S);

	int scb_status = inb(e100.io_base + CSR_SCB_STATUS);
	if ((scb_status & CUS_MASK) == CUS_SUSPENDED) {
		// If the CU is in the suspended state the CU Resume 
		// command resumes CU operation and requests the beginning 
		// of the next CB if the S bit is clear on current CB.		
		e100_exec_cmd(CSR_SCB_COMMAND, CUC_RESUME);
	}

	return 0;
}
예제 #4
0
static void
cbl_init () 
{
    cbl_alloc ();

    cbl_append_nop (CBF_S);

    outl(nic.io_base + CSR_GP, nic.cbl.front->phy_addr);
    e100_exec_cmd (CSR_COMMAND, CUC_START); 
}
예제 #5
0
파일: e100.c 프로젝트: mcorley/jos
void 
e100_init(void)
{
	// Reset the device preparing it for normal operation.
	e100_software_reset();

	// Create the receive and transmit DMA rings.
	e100_cbl_alloc();
	e100_rfa_alloc();
	
	// Tell the CU where to find the CBL by sending it the
	// physical address of the first buffer in the ring.
	outl(e100.io_base + CSR_SCB_GEN_PTR, e100.cbs->pa);
	// When the CU detects the CU Start (CU_START) command, it begins 
	// executing the first action command in the list.
	e100_exec_cmd(CSR_SCB_COMMAND, CUC_START);

	// Tell the RU where to find the RFA by sending it the
	// physical address of the first buffer in the ring.
	outl(e100.io_base + CSR_SCB_GEN_PTR, e100.rfds->pa);
	// For the RU start (RU_START) command, the CPU activates the RU 
	// for frame reception.
	e100_exec_cmd(CSR_SCB_COMMAND, RUC_START);	
}
예제 #6
0
static void e100_init()
{
	int r = 0;
	page_net_init();
	/* reset device before using */
	e100_reset();
	printf("e100_reset\n");

	/* all interrupts to be disabled */
	r = e100_exec_cmd(CSR_INT, 1);
	printf("e100 CSR_INT ret=%d\n", r);

	cbl_init();
	rfa_init();
	printf("rfa_init, page_index=%d\n", page_index);
}
예제 #7
0
int 
e100_receive (char *data)
{
    rfa_validate ();

    if (nic.rfa.rfd_wait == 0)
        return -E_RFA_EMPTY;

    int r = rfa_retrieve_data (data);
 
    int scb_status = inb(nic.io_base + CSR_STATUS);
    if ((scb_status & RUS_MASK) == RUS_SUSPEND)
        e100_exec_cmd (CSR_COMMAND, RUC_RESUME); 

    return r;
}
예제 #8
0
int e100_transmit (const char *data, uint16_t len)
{
    cbl_validate ();

    if (nic.cbl.cb_avail == 0)
        return -E_CBL_FULL;
    
    nic.cbl.rear->cb_control &= ~CBF_S;
    cbl_append_transmit (data, len, CBF_S);

    int scb_status = inb(nic.io_base + CSR_STATUS);
    if ((scb_status & CUS_MASK) == CUS_SUSPENDED)
        e100_exec_cmd (CSR_COMMAND, CUC_RESUME); 

    return 0;
}