From: John Hodge Date: Tue, 1 Oct 2013 14:59:16 +0000 (+0800) Subject: UDI/ne2000 - Adding RX framework X-Git-Tag: rel0.15~152 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=fb9d8f2d3c416bb3dc6702fae5891dedd990da44;p=tpg%2Facess2.git UDI/ne2000 - Adding RX framework --- diff --git a/UDI/drivers/net_ne2000/ne2000_common.h b/UDI/drivers/net_ne2000/ne2000_common.h index bfa27ea6..739bafe6 100644 --- a/UDI/drivers/net_ne2000/ne2000_common.h +++ b/UDI/drivers/net_ne2000/ne2000_common.h @@ -20,12 +20,22 @@ typedef struct { udi_init_context_t init_context; - struct - { + udi_cb_t *active_cb; + + udi_intr_attach_cb_t *intr_attach_cb; + + struct { udi_index_t pio_index; + udi_index_t n_intr_event_cb; + + udi_index_t rx_chan_index; } init; - udi_pio_handle_t pio_handles[1]; + udi_pio_handle_t pio_handles[4]; + udi_channel_t interrupt_channel; + udi_channel_t rx_channel; + udi_channel_t tx_channel; + udi_ubit8_t macaddr[6]; } ne2k_rdata_t; @@ -62,12 +72,18 @@ typedef struct extern udi_channel_event_ind_op_t ne2k_bus_dev_channel_event_ind; extern udi_bus_bind_ack_op_t ne2k_bus_dev_bus_bind_ack; extern udi_pio_map_call_t ne2k_bus_dev_bind__pio_map; +extern udi_channel_spawn_call_t ne2k_bus_dev_bind__intr_chanel; +extern udi_cb_alloc_call_t ne2k_bus_dev_bind__intr_attach; extern udi_bus_unbind_ack_op_t ne2k_bus_dev_bus_unbind_ack; extern udi_intr_attach_ack_op_t ne2k_bus_dev_intr_attach_ack; +extern udi_cb_alloc_call_t ne2k_bus_dev_bind__intr_event_cb; +extern udi_pio_trans_call_t ne2k_bus_dev_bind__card_reset; extern udi_intr_detach_ack_op_t ne2k_bus_dev_intr_detach_ack; extern udi_channel_event_ind_op_t ne2k_nd_ctrl_channel_event_ind; extern udi_nd_bind_req_op_t ne2k_nd_ctrl_bind_req; +extern udi_channel_spawn_call_t ne2k_nd_ctrl_bind__tx_chan_ok; +extern udi_channel_spawn_call_t ne2k_nd_ctrl_bind__rx_chan_ok; extern udi_nd_unbind_req_op_t ne2k_nd_ctrl_unbind_req; extern udi_nd_enable_req_op_t ne2k_nd_ctrl_enable_req; extern udi_nd_disable_req_op_t ne2k_nd_ctrl_disable_req; @@ -81,5 +97,10 @@ extern udi_nd_exp_tx_req_op_t ne2k_nd_tx_exp_tx_req; extern udi_channel_event_ind_op_t ne2k_nd_rx_channel_event_ind; extern udi_nd_rx_rdy_op_t ne2k_nd_rx_rx_rdy; +extern udi_channel_event_ind_op_t ne2k_bus_irq_channel_event_ind; +extern udi_intr_event_ind_op_t ne2k_bus_irq_intr_event_ind; + +extern void ne2k_intr__rx_ok(udi_cb_t *gcb); + #endif diff --git a/UDI/drivers/net_ne2000/ne2000_core.c b/UDI/drivers/net_ne2000/ne2000_core.c index 11fc72f9..acecb498 100644 --- a/UDI/drivers/net_ne2000/ne2000_core.c +++ b/UDI/drivers/net_ne2000/ne2000_core.c @@ -9,8 +9,23 @@ #include #include "ne2000_common.h" -#define NE2K_META_BUS 1 -#define NE2K_META_NIC 2 +enum { + NE2K_META_BUS = 1, + NE2K_META_NIC, +}; +enum { + NE2K_OPS_DEV = 1, + NE2K_OPS_CTRL, + NE2K_OPS_TX, + NE2K_OPS_RX, + NE2K_OPS_IRQ, +}; +enum { + NE2K_CB_INTR = 1, + NE2K_CB_INTR_EVENT, +}; + +#define NE2K_NUM_INTR_EVENT_CBS 4 // === GLOBALS === #define PIO_op_RI(op, reg, sz, val) {UDI_PIO_##op+UDI_PIO_DIRECT+UDI_PIO_##reg, UDI_PIO_##sz##BYTE, val} @@ -18,102 +33,7 @@ #define PIO_OUT_RI1(reg, ofs) PIO_op_RI(OUT, reg, 1, ofs) #define PIO_IN_RI1(reg, ofs) PIO_op_RI(IN, reg, 1, ofs) // --- Programmed IO --- -/// Ne2000 reset operation (reads MAC address too) -udi_pio_trans_t ne2k_pio_reset[] = { - // - Reset card - PIO_IN_RI1(R0, NE2K_REG_RESET), - PIO_OUT_RI1(R0, NE2K_REG_RESET), - // While ISR bit 7 is unset, spin - {UDI_PIO_LABEL, 0, 1}, - PIO_IN_RI1(R0, NE2K_REG_ISR), - {UDI_PIO_AND_IMM+UDI_PIO_R0, UDI_PIO_1BYTE, 0x80}, - {UDI_PIO_CSKIP+UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_NZ}, - {UDI_PIO_BRANCH, 0, 1}, - // ISR = 0x80 [Clear reset] - PIO_OUT_RI1(R0, NE2K_REG_ISR), - // - Init pass 1 - // CMD = 0x40|0x21 [Page1, NoDMA, Stop] - PIO_MOV_RI1(R0, 0x40|0x21), - PIO_OUT_RI1(R0, NE2K_REG_CMD), - // CURR = First RX page - PIO_MOV_RI1(R0, NE2K_RX_FIRST_PG), - PIO_OUT_RI1(R0, NE2K_REG_CURR), - // CMD = 0x21 [Page0, NoDMA, Stop] - PIO_MOV_RI1(R0, 0x21), - PIO_OUT_RI1(R0, NE2K_REG_CMD), - // DCR = ? [WORD, ...] - PIO_MOV_RI1(R0, 0x49), - PIO_OUT_RI1(R0, NE2K_REG_DCR), - // IMR = 0 [Disable all] - PIO_MOV_RI1(R0, 0x00), - PIO_OUT_RI1(R0, NE2K_REG_IMR), - // ISR = 0xFF [ACK all] - PIO_MOV_RI1(R0, 0xFF), - PIO_OUT_RI1(R0, NE2K_REG_ISR), - // RCR = 0x20 [Monitor] - PIO_MOV_RI1(R0, 0x20), - PIO_OUT_RI1(R0, NE2K_REG_RCR), - // TCR = 0x02 [TX Off, Loopback] - PIO_MOV_RI1(R0, 0x02), - PIO_OUT_RI1(R0, NE2K_REG_TCR), - // - Read MAC address from EEPROM (24 bytes from 0) - PIO_MOV_RI1(R0, 0), - PIO_MOV_RI1(R1, 0), - PIO_OUT_RI1(R0, NE2K_REG_RSAR0), - PIO_OUT_RI1(R1, NE2K_REG_RSAR1), - PIO_MOV_RI1(R0, 6*4), - PIO_MOV_RI1(R1, 0), - PIO_OUT_RI1(R0, NE2K_REG_RBCR0), - PIO_OUT_RI1(R1, NE2K_REG_RBCR1), - // CMD = 0x0A [Start remote DMA] - PIO_MOV_RI1(R0, 0x0A), - PIO_OUT_RI1(R0, NE2K_REG_CMD), - // Read MAC address - PIO_MOV_RI1(R0, 0), // - Buffer offset (incremented by 1 each iteration) - PIO_MOV_RI1(R1, NE2K_REG_MEM), // - Reg offset (no increment) - PIO_MOV_RI1(R2, 6), // - Six iterations - {UDI_PIO_REP_IN_IND, UDI_PIO_1BYTE, - UDI_PIO_REP_ARGS(UDI_PIO_BUF, UDI_PIO_R0, 1, UDI_PIO_R1, 0, UDI_PIO_R2)}, - // - Setup - // PSTART = First RX page [Receive area start] - PIO_MOV_RI1(R0, NE2K_RX_FIRST_PG), - PIO_OUT_RI1(R0, NE2K_REG_PSTART), - // BNRY = Last RX page - 1 [???] - PIO_MOV_RI1(R0, NE2K_RX_LAST_PG-1), - PIO_OUT_RI1(R0, NE2K_REG_BNRY), - // PSTOP = Last RX page [???] - PIO_MOV_RI1(R0, NE2K_RX_LAST_PG), - PIO_OUT_RI1(R0, NE2K_REG_PSTOP), - // > Clear all interrupt and set mask - // ISR = 0xFF [ACK all] - PIO_MOV_RI1(R0, 0xFF), - PIO_OUT_RI1(R0, NE2K_REG_ISR), - // IMR = 0x3F [] - PIO_MOV_RI1(R0, 0x3F), - PIO_OUT_RI1(R0, NE2K_REG_IMR), - // CMD = 0x22 [NoDMA, Start] - PIO_MOV_RI1(R0, 0x22), - PIO_OUT_RI1(R0, NE2K_REG_CMD), - // RCR = 0x0F [Wrap, Promisc] - PIO_MOV_RI1(R0, 0x0F), - PIO_OUT_RI1(R0, NE2K_REG_RCR), - // TCR = 0x00 [Normal] - PIO_MOV_RI1(R0, 0x00), - PIO_OUT_RI1(R0, NE2K_REG_TCR), - // TPSR = 0x40 [TX Start] - PIO_MOV_RI1(R0, 0x40), - PIO_OUT_RI1(R0, NE2K_REG_TPSR), - // End - {UDI_PIO_END_IMM, UDI_PIO_2BYTE, 0} -}; -struct { - udi_pio_trans_t *trans_list; - udi_ubit16_t list_length; - udi_ubit16_t pio_attributes; -} ne2k_pio_ops[] = { - {ne2k_pio_reset, ARRAY_SIZEOF(ne2k_pio_reset), 0} -}; -const int NE2K_NUM_PIO_OPS = ARRAY_SIZEOF(ne2k_pio_ops); +#include "ne2000_pio.h" // === CODE === // --- Management @@ -138,7 +58,7 @@ void ne2k_enumerate_req(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level) rdata->macaddr[0], rdata->macaddr[1], rdata->macaddr[2], rdata->macaddr[3], rdata->macaddr[4], rdata->macaddr[5] ); attr_list ++; - udi_enumerate_ack(cb, UDI_ENUMERATE_OK, 2); + udi_enumerate_ack(cb, UDI_ENUMERATE_OK, NE2K_OPS_CTRL); break; case UDI_ENUMERATE_NEXT: udi_enumerate_ack(cb, UDI_ENUMERATE_DONE, 0); @@ -170,6 +90,7 @@ void ne2k_bus_dev_bus_bind_ack(udi_bus_bind_cb_t *cb, { udi_cb_t *gcb = UDI_GCB(cb); ne2k_rdata_t *rdata = gcb->context; + rdata->active_cb = gcb; // Set up PIO handles rdata->init.pio_index = -1; @@ -192,17 +113,78 @@ void ne2k_bus_dev_bind__pio_map(udi_cb_t *gcb, udi_pio_handle_t new_pio_handle) ne2k_pio_ops[rdata->init.pio_index].list_length, UDI_PIO_LITTLE_ENDIAN, 0, 0 ); + return ; } - else - { - // Next! - } + + // Next: Bind interrupt + udi_channel_spawn(ne2k_bus_dev_bind__intr_chanel, gcb, gcb->channel, + 0, NE2K_OPS_IRQ, rdata); +} +void ne2k_bus_dev_bind__intr_chanel(udi_cb_t *gcb, udi_channel_t new_channel) +{ + ne2k_rdata_t *rdata = gcb->context; + + rdata->interrupt_channel = new_channel; + + udi_cb_alloc(ne2k_bus_dev_bind__intr_attach, gcb, NE2K_CB_INTR, gcb->channel); +} +void ne2k_bus_dev_bind__intr_attach(udi_cb_t *gcb, udi_cb_t *new_cb) +{ + ne2k_rdata_t *rdata = gcb->context; + udi_intr_attach_cb_t *intr_cb = UDI_MCB(new_cb, udi_intr_attach_cb_t); + intr_cb->interrupt_idx = 0; + intr_cb->min_event_pend = 2; + intr_cb->preprocessing_handle = rdata->pio_handles[NE2K_PIO_IRQACK]; + udi_intr_attach_req(intr_cb); + // continued in ne2k_bus_dev_intr_attach_ack } void ne2k_bus_dev_bus_unbind_ack(udi_bus_bind_cb_t *cb) { } void ne2k_bus_dev_intr_attach_ack(udi_intr_attach_cb_t *intr_attach_cb, udi_status_t status) { + udi_cb_t *gcb = UDI_GCB(intr_attach_cb); + ne2k_rdata_t *rdata = gcb->context; + // continuing from ne2k_bus_dev_bind__intr_attach + if( status != UDI_OK ) { + // TODO: Error + udi_cb_free( UDI_GCB(intr_attach_cb) ); + return ; + } + + rdata->intr_attach_cb = intr_attach_cb; + + rdata->init.n_intr_event_cb = 0; + udi_cb_alloc(ne2k_bus_dev_bind__intr_event_cb, gcb, NE2K_CB_INTR_EVENT, rdata->interrupt_channel); + // V V V V +} +void ne2k_bus_dev_bind__intr_event_cb(udi_cb_t *gcb, udi_cb_t *new_cb) +{ + ne2k_rdata_t *rdata = gcb->context; + + udi_intr_event_cb_t *intr_event_cb = UDI_MCB(new_cb, udi_intr_event_cb_t); + udi_intr_event_rdy(intr_event_cb); + rdata->init.n_intr_event_cb ++; + + if( rdata->init.n_intr_event_cb < NE2K_NUM_INTR_EVENT_CBS ) + { + udi_cb_alloc(ne2k_bus_dev_bind__intr_event_cb, gcb, + NE2K_CB_INTR_EVENT, rdata->interrupt_channel); + // A A A A + return ; + } + + udi_pio_trans(ne2k_bus_dev_bind__card_reset, gcb, + rdata->pio_handles[NE2K_PIO_RESET], 0, NULL, &rdata->macaddr); + // V V V V +} + +void ne2k_bus_dev_bind__card_reset(udi_cb_t *gcb, udi_buf_t *new_buf, udi_status_t status, udi_ubit16_t result) +{ + ne2k_rdata_t *rdata = gcb->context; + // Done! (Finally) + udi_channel_event_complete( UDI_MCB(rdata->active_cb, udi_channel_event_cb_t), UDI_OK ); + // = = = = } void ne2k_bus_dev_intr_detach_ack(udi_intr_detach_cb_t *intr_detach_cb) { @@ -213,12 +195,33 @@ void ne2k_nd_ctrl_channel_event_ind(udi_channel_event_cb_t *cb) } void ne2k_nd_ctrl_bind_req(udi_nic_bind_cb_t *cb, udi_index_t tx_chan_index, udi_index_t rx_chan_index) { + udi_cb_t *gcb = UDI_GCB(cb); + ne2k_rdata_t *rdata = gcb->context; + rdata->init.rx_chan_index = rx_chan_index; + udi_channel_spawn(ne2k_nd_ctrl_bind__tx_chan_ok, gcb, gcb->channel, tx_chan_index, NE2K_OPS_TX, rdata); + // V V V V +} +void ne2k_nd_ctrl_bind__tx_chan_ok(udi_cb_t *gcb, udi_channel_t new_channel) +{ + ne2k_rdata_t *rdata = gcb->context; + rdata->tx_channel = new_channel; + udi_channel_spawn(ne2k_nd_ctrl_bind__rx_chan_ok, gcb, gcb->channel, + rdata->init.rx_chan_index, NE2K_OPS_RX, rdata); + // V V V V +} +void ne2k_nd_ctrl_bind__rx_chan_ok(udi_cb_t *cb, udi_channel_t new_channel) +{ + ne2k_rdata_t *rdata = cb->context; + rdata->rx_channel = new_channel; + udi_nsr_bind_ack( UDI_MCB(cb, udi_nic_bind_cb_t), UDI_OK ); + // = = = = } void ne2k_nd_ctrl_unbind_req(udi_nic_cb_t *cb) { } void ne2k_nd_ctrl_enable_req(udi_nic_cb_t *cb) { + // Enable } void ne2k_nd_ctrl_disable_req(udi_nic_cb_t *cb) { @@ -229,6 +232,18 @@ void ne2k_nd_ctrl_ctrl_req(udi_nic_ctrl_cb_t *cb) void ne2k_nd_ctrl_info_req(udi_nic_info_cb_t *cb, udi_boolean_t reset_statistics) { } +// --- IRQ +void ne2k_bus_irq_channel_event_ind(udi_channel_event_cb_t *cb) +{ +} +void ne2k_bus_irq_intr_event_ind(udi_intr_event_cb_t *cb, udi_ubit8_t flags) +{ + if( cb->intr_result & 0x01 ) + { + ne2k_intr__rx_ok( UDI_GCB(cb) ); + } + udi_intr_event_rdy(cb); +} // === Definition structures === udi_mgmt_ops_t ne2k_mgmt_ops = { @@ -267,6 +282,12 @@ udi_nd_rx_ops_t ne2k_nd_rx_ops = { ne2k_nd_rx_rx_rdy }; udi_ubit8_t ne2k_nd_rx_ops_flags[2] = {0}; +udi_intr_handler_ops_t ne2k_bus_irq_ops = { + ne2k_bus_irq_channel_event_ind, + ne2k_bus_irq_intr_event_ind +}; +udi_ubit8_t ne2k_bus_irq_ops_flags[2] = {0}; + udi_primary_init_t ne2k_pri_init = { .mgmt_ops = &ne2k_mgmt_ops, .mgmt_op_flags = ne2k_mgmt_op_flags, @@ -278,29 +299,35 @@ udi_primary_init_t ne2k_pri_init = { }; udi_ops_init_t ne2k_ops_list[] = { { - 1, NE2K_META_BUS, UDI_BUS_DEVICE_OPS_NUM, + NE2K_OPS_DEV, NE2K_META_BUS, UDI_BUS_DEVICE_OPS_NUM, 0, (udi_ops_vector_t*)&ne2k_bus_dev_ops, ne2k_bus_dev_ops_flags }, { - 2, NE2K_META_NIC, UDI_ND_CTRL_OPS_NUM, + NE2K_OPS_CTRL, NE2K_META_NIC, UDI_ND_CTRL_OPS_NUM, 0, (udi_ops_vector_t*)&ne2k_nd_ctrl_ops, ne2k_nd_ctrl_ops_flags }, { - 3, NE2K_META_NIC, UDI_ND_TX_OPS_NUM, + NE2K_OPS_TX, NE2K_META_NIC, UDI_ND_TX_OPS_NUM, 0, (udi_ops_vector_t*)&ne2k_nd_tx_ops, ne2k_nd_tx_ops_flags }, { - 4, NE2K_META_NIC, UDI_ND_RX_OPS_NUM, + NE2K_OPS_RX, NE2K_META_NIC, UDI_ND_RX_OPS_NUM, 0, (udi_ops_vector_t*)&ne2k_nd_rx_ops, ne2k_nd_rx_ops_flags }, + { + NE2K_OPS_IRQ, NE2K_META_BUS, UDI_BUS_INTR_HANDLER_OPS_NUM, + 0, + (udi_ops_vector_t*)&ne2k_bus_irq_ops, + ne2k_bus_irq_ops_flags + }, {0} }; const udi_init_t udi_init_info = { diff --git a/UDI/drivers/net_ne2000/ne2000_pio.h b/UDI/drivers/net_ne2000/ne2000_pio.h new file mode 100644 index 00000000..b862fe87 --- /dev/null +++ b/UDI/drivers/net_ne2000/ne2000_pio.h @@ -0,0 +1,212 @@ +// +// Ne2000 reset operation (reads MAC address too) +// +udi_pio_trans_t ne2k_pio_reset[] = { + // - Reset card + PIO_IN_RI1(R0, NE2K_REG_RESET), + PIO_OUT_RI1(R0, NE2K_REG_RESET), + // While ISR bit 7 is unset, spin + {UDI_PIO_LABEL, 0, 1}, + PIO_IN_RI1(R0, NE2K_REG_ISR), + {UDI_PIO_AND_IMM+UDI_PIO_R0, UDI_PIO_1BYTE, 0x80}, + {UDI_PIO_CSKIP+UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_NZ}, + {UDI_PIO_BRANCH, 0, 1}, + // ISR = 0x80 [Clear reset] + PIO_OUT_RI1(R0, NE2K_REG_ISR), + // - Init pass 1 + // CMD = 0x40|0x21 [Page1, NoDMA, Stop] + PIO_MOV_RI1(R0, 0x40|0x21), + PIO_OUT_RI1(R0, NE2K_REG_CMD), + // CURR = First RX page + PIO_MOV_RI1(R0, NE2K_RX_FIRST_PG), + PIO_OUT_RI1(R0, NE2K_REG_CURR), + // CMD = 0x21 [Page0, NoDMA, Stop] + PIO_MOV_RI1(R0, 0x21), + PIO_OUT_RI1(R0, NE2K_REG_CMD), + // DCR = ? [WORD, ...] + PIO_MOV_RI1(R0, 0x49), + PIO_OUT_RI1(R0, NE2K_REG_DCR), + // IMR = 0 [Disable all] + PIO_MOV_RI1(R0, 0x00), + PIO_OUT_RI1(R0, NE2K_REG_IMR), + // ISR = 0xFF [ACK all] + PIO_MOV_RI1(R0, 0xFF), + PIO_OUT_RI1(R0, NE2K_REG_ISR), + // RCR = 0x20 [Monitor] + PIO_MOV_RI1(R0, 0x20), + PIO_OUT_RI1(R0, NE2K_REG_RCR), + // TCR = 0x02 [TX Off, Loopback] + PIO_MOV_RI1(R0, 0x02), + PIO_OUT_RI1(R0, NE2K_REG_TCR), + // - Read MAC address from EEPROM (24 bytes from 0) + PIO_MOV_RI1(R0, 0), + PIO_MOV_RI1(R1, 0), + PIO_OUT_RI1(R0, NE2K_REG_RSAR0), + PIO_OUT_RI1(R1, NE2K_REG_RSAR1), + PIO_MOV_RI1(R0, 6*4), + PIO_MOV_RI1(R1, 0), + PIO_OUT_RI1(R0, NE2K_REG_RBCR0), + PIO_OUT_RI1(R1, NE2K_REG_RBCR1), + // CMD = 0x0A [Start remote DMA] + PIO_MOV_RI1(R0, 0x0A), + PIO_OUT_RI1(R0, NE2K_REG_CMD), + // Read MAC address + PIO_MOV_RI1(R0, 0), // - Buffer offset (incremented by 1 each iteration) + PIO_MOV_RI1(R1, NE2K_REG_MEM), // - Reg offset (no increment) + PIO_MOV_RI1(R2, 6), // - Six iterations + {UDI_PIO_REP_IN_IND, UDI_PIO_1BYTE, + UDI_PIO_REP_ARGS(UDI_PIO_MEM, UDI_PIO_R0, 1, UDI_PIO_R1, 0, UDI_PIO_R2)}, + // End + {UDI_PIO_END_IMM, UDI_PIO_2BYTE, 0} +}; +// +// Enable the card +// +udi_pio_trans_t ne2k_pio_enable[] = { + // - Setup + // PSTART = First RX page [Receive area start] + PIO_MOV_RI1(R0, NE2K_RX_FIRST_PG), + PIO_OUT_RI1(R0, NE2K_REG_PSTART), + // BNRY = Last RX page - 1 [???] + PIO_MOV_RI1(R0, NE2K_RX_LAST_PG-1), + PIO_OUT_RI1(R0, NE2K_REG_BNRY), + // PSTOP = Last RX page [???] + PIO_MOV_RI1(R0, NE2K_RX_LAST_PG), + PIO_OUT_RI1(R0, NE2K_REG_PSTOP), + // CMD = 0x22 [NoDMA, Start] + PIO_MOV_RI1(R0, 0x22), + PIO_OUT_RI1(R0, NE2K_REG_CMD), + // RCR = 0x0F [Wrap, Promisc] + PIO_MOV_RI1(R0, 0x0F), + PIO_OUT_RI1(R0, NE2K_REG_RCR), + // TCR = 0x00 [Normal] + PIO_MOV_RI1(R0, 0x00), + PIO_OUT_RI1(R0, NE2K_REG_TCR), + // TPSR = 0x40 [TX Start] + PIO_MOV_RI1(R0, 0x40), + PIO_OUT_RI1(R0, NE2K_REG_TPSR), + // End + {UDI_PIO_END_IMM, UDI_PIO_2BYTE, 0} +}; +// +// Read a packet +// - Expects an output buffer +// +udi_pio_trans_t ne2k_pio_rx[] = { + // Get current page into R7 + PIO_MOV_RI1(R0, 0), + {UDI_PIO_LOAD|UDI_PIO_MEM|UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_R7}, + // Read header into regs, then data into buffer + // - CMD = 0x22 + PIO_MOV_RI1(R0, 0x22), PIO_OUT_RI1(R0, NE2K_REG_CMD), + // - Clear RDMA flag + PIO_MOV_RI1(R0, 0x40), PIO_OUT_RI1(R0, NE2K_REG_ISR), + // - Set up transaction for 1 page from CurRX + PIO_MOV_RI1(R0, 1), + PIO_MOV_RI1(R1, 0), + PIO_OUT_RI1(R7, NE2K_REG_RSAR0), // Current RX page + PIO_OUT_RI1(R1, NE2K_REG_RSAR1), + PIO_OUT_RI1(R0, NE2K_REG_RBCR0), + PIO_OUT_RI1(R1, NE2K_REG_RBCR1), + // - Start read + PIO_MOV_RI1(R0, 0x0A), PIO_OUT_RI1(R0, NE2K_REG_CMD), + {UDI_PIO_DELAY, 0, 0}, + // > Header to registers + {UDI_PIO_IN|UDI_PIO_DIRECT|UDI_PIO_R6, UDI_PIO_2BYTE, NE2K_REG_MEM}, // Status,NextPacketPage + {UDI_PIO_IN|UDI_PIO_DIRECT|UDI_PIO_R5, UDI_PIO_2BYTE, NE2K_REG_MEM}, // Length (bytes) + // > Data to buffer (126 words) + PIO_MOV_RI1(R4, 0), // - Buffer offset (incremented by 1 each iteration) + PIO_MOV_RI1(R1, NE2K_REG_MEM), // - Reg offset (no increment) + PIO_MOV_RI1(R2, 256/2-2), // - Six iterations + {UDI_PIO_REP_IN_IND, UDI_PIO_2BYTE, + UDI_PIO_REP_ARGS(UDI_PIO_BUF, UDI_PIO_R4, 2, UDI_PIO_R1, 0, UDI_PIO_R2)}, + // - Subtract 256-4 from length, if <=0 we've grabbed the entire packet + {UDI_PIO_SUB|UDI_PIO_R5, UDI_PIO_2BYTE, 256-4}, + {UDI_PIO_LABEL, 0, 2}, + {UDI_PIO_CSKIP|UDI_PIO_R5, UDI_PIO_2BYTE, UDI_PIO_NZ}, + {UDI_PIO_BRANCH, 0, 1}, // 1: End if ==0 + {UDI_PIO_CSKIP|UDI_PIO_R5, UDI_PIO_2BYTE, UDI_PIO_NNEG}, + {UDI_PIO_BRANCH, 0, 1}, // 1: End if <0 + // - Read pages until all of packet RXd + {UDI_PIO_ADD|UDI_PIO_DIRECT|UDI_PIO_R7, UDI_PIO_1BYTE, 1}, + {UDI_PIO_STORE|UDI_PIO_DIRECT|UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_R7}, + {UDI_PIO_SUB|UDI_PIO_R0, UDI_PIO_1BYTE, NE2K_RX_LAST_PG+1}, + {UDI_PIO_CSKIP|UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_NZ}, // if R7-RX_LAST == 0 + {UDI_PIO_LOAD_IMM|UDI_PIO_R7, UDI_PIO_1BYTE, NE2K_RX_FIRST_PG}, // R7 = RX_FIRST + // > Transaction start + PIO_MOV_RI1(R0, 1), + PIO_MOV_RI1(R1, 0), + PIO_OUT_RI1(R7, NE2K_REG_RSAR0), // Current RX page + PIO_OUT_RI1(R1, NE2K_REG_RSAR1), + PIO_OUT_RI1(R0, NE2K_REG_RBCR0), + PIO_OUT_RI1(R1, NE2K_REG_RBCR1), + PIO_MOV_RI1(R0, 0x0A), PIO_OUT_RI1(R0, NE2K_REG_CMD), + {UDI_PIO_DELAY, 0, 0}, + // > Data to buffer (128 words) + // buffer offset maintained in R4 + PIO_MOV_RI1(R1, NE2K_REG_MEM), // - Reg offset (no increment) + PIO_MOV_RI1(R2, 256/2), // - Six iterations + {UDI_PIO_REP_IN_IND, UDI_PIO_2BYTE, + UDI_PIO_REP_ARGS(UDI_PIO_BUF, UDI_PIO_R4, 2, UDI_PIO_R1, 0, UDI_PIO_R2)}, + // - Jump to length check + {UDI_PIO_SUB|UDI_PIO_R5, UDI_PIO_2BYTE, 256}, + {UDI_PIO_BRANCH, 0, 2}, // 2: Check against length + + // Cleanup + {UDI_PIO_LABEL, 0, 1}, + // - Update next RX page, return status + {UDI_PIO_OUT|UDI_PIO_DIRECT|UDI_PIO_R7, UDI_PIO_1BYTE, NE2K_REG_BNRY}, + {UDI_PIO_STORE|UDI_PIO_DIRECT|UDI_PIO_R7, UDI_PIO_2BYTE, UDI_PIO_R6}, // Status,Next + {UDI_PIO_SHIFT_RIGHT|UDI_PIO_DIRECT|UDI_PIO_R7, UDI_PIO_2BYTE, 8}, // Next + PIO_MOV_RI1(R0, 0), + {UDI_PIO_STORE|UDI_PIO_MEM|UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_R7}, // Store to mem[0] + + {UDI_PIO_END, UDI_PIO_1BYTE, UDI_PIO_R6} // Status +}; +// +// +// +udi_pio_trans_t ne2k_pio_irqack[] = { + // 0: Enable interrupts + // IMR = 0x3F [] + PIO_MOV_RI1(R0, 0x3F), + PIO_OUT_RI1(R0, NE2K_REG_IMR), + // ISR = 0xFF [ACK all] + PIO_MOV_RI1(R0, 0xFF), + PIO_OUT_RI1(R0, NE2K_REG_ISR), + {UDI_PIO_END_IMM, UDI_PIO_2BYTE, 0}, + // 1: Normal + {UDI_PIO_LABEL, 0, 1}, + PIO_IN_RI1(R0, NE2K_REG_ISR), + PIO_OUT_RI1(R0, NE2K_REG_ISR), + {UDI_PIO_CSKIP|UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_Z}, // if R0!=0 + {UDI_PIO_END, UDI_PIO_2BYTE, UDI_PIO_R0}, + // - No IRQ, quiet quit + PIO_MOV_RI1(R0, UDI_INTR_NO_EVENT), + PIO_MOV_RI1(R1, 0), // scratch offset + {UDI_PIO_STORE|UDI_PIO_SCRATCH|UDI_PIO_R1, UDI_PIO_1BYTE, UDI_PIO_R0}, + {UDI_PIO_END_IMM, UDI_PIO_2BYTE, 0}, + // 2: Overrun + {UDI_PIO_LABEL, 0, 2}, + // 3: Overrun irqs + {UDI_PIO_LABEL, 0, 3}, + {UDI_PIO_END_IMM, UDI_PIO_2BYTE, 0}, +}; + +struct { + udi_pio_trans_t *trans_list; + udi_ubit16_t list_length; + udi_ubit16_t pio_attributes; +} ne2k_pio_ops[] = { + {ne2k_pio_reset, ARRAY_SIZEOF(ne2k_pio_reset), 0}, + {ne2k_pio_enable, ARRAY_SIZEOF(ne2k_pio_enable), 0}, + {ne2k_pio_rx, ARRAY_SIZEOF(ne2k_pio_rx), 0}, + {ne2k_pio_irqack, ARRAY_SIZEOF(ne2k_pio_irqack), 0}, +}; +const int NE2K_NUM_PIO_OPS = ARRAY_SIZEOF(ne2k_pio_ops); +enum { + NE2K_PIO_RESET, + NE2K_PIO_ENABLE, + NE2K_PIO_RX, + NE2K_PIO_IRQACK, +}; diff --git a/UDI/drivers/net_ne2000/ne2000_rx.c b/UDI/drivers/net_ne2000/ne2000_rx.c index e69de29b..cc603902 100644 --- a/UDI/drivers/net_ne2000/ne2000_rx.c +++ b/UDI/drivers/net_ne2000/ne2000_rx.c @@ -0,0 +1,17 @@ +/* + * UDI Ne2000 NIC Driver + * By John Hodge (thePowersGang) + * + * ne2000_rx.c + * - Receive Code + */ +#include +#include +#include "ne2000_common.h" + +// === CODE === +void ne2k_intr__rx_ok(udi_cb_t *gcb) +{ + +} + diff --git a/UDI/drivers/net_ne2000/udiprops.txt b/UDI/drivers/net_ne2000/udiprops.txt index e6edadad..ca8f4292 100644 --- a/UDI/drivers/net_ne2000/udiprops.txt +++ b/UDI/drivers/net_ne2000/udiprops.txt @@ -36,4 +36,3 @@ region 0 # Source-only udiprops source_files ne2000_core.c ne2000_rx.c ne2000_tx.c -compile_options