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 */ }
// // 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; }
// // 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; }
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); }
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); }
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); }
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; }
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; }