NE2K_PIO_RX,
NE2K_PIO_IRQACK,
NE2K_PIO_TX,
+ N_NE2K_PIO
};
typedef struct
udi_index_t rx_chan_index;
} init;
- udi_pio_handle_t pio_handles[4];
+ udi_pio_handle_t pio_handles[N_NE2K_PIO];
udi_channel_t interrupt_channel;
udi_channel_t rx_channel;
udi_channel_t tx_channel;
udi_nic_rx_cb_t *rx_next_cb;
+ udi_nic_rx_cb_t *rx_last_cb;
udi_ubit8_t rx_next_page;
udi_ubit8_t macaddr[6];
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_pio_trans_call_t ne2k_nd_ctrl_enable_req__trans_done;
extern udi_nd_disable_req_op_t ne2k_nd_ctrl_disable_req;
extern udi_nd_ctrl_req_op_t ne2k_nd_ctrl_ctrl_req;
extern udi_nd_info_req_op_t ne2k_nd_ctrl_info_req;
}
void ne2k_nd_ctrl_enable_req(udi_nic_cb_t *cb)
{
- // Enable
+ udi_cb_t *gcb = UDI_GCB(cb);
+ ne2k_rdata_t *rdata = gcb->context;
+ udi_pio_trans(ne2k_nd_ctrl_enable_req__trans_done, gcb,
+ rdata->pio_handles[NE2K_PIO_ENABLE], 0, NULL, NULL);
+}
+void ne2k_nd_ctrl_enable_req__trans_done(udi_cb_t *gcb, udi_buf_t *new_buf, udi_status_t status, udi_ubit16_t res)
+{
+ udi_nsr_enable_ack( UDI_MCB(gcb, udi_nic_cb_t), status );
}
void ne2k_nd_ctrl_disable_req(udi_nic_cb_t *cb)
{
}
void ne2k_bus_irq_intr_event_ind(udi_intr_event_cb_t *cb, udi_ubit8_t flags)
{
+ udi_debug_printf("ne2k_bus_irq_intr_event_ind: flags=%x, intr_result=%x\n",
+ flags, cb->intr_result);
if( cb->intr_result & 0x01 )
{
ne2k_intr__rx_ok( UDI_GCB(cb) );
udi_pio_trans_t ne2k_pio_tx[] = {
// Switch to page 0
// CMD = 0x40|0x21 [Page1, NoDMA, Stop]
- PIO_MOV_RI1(R0, 0x40|0x21),
+ PIO_MOV_RI1(R0, 0x22),
PIO_OUT_RI1(R0, NE2K_REG_CMD),
// Clear RDMA
PIO_MOV_RI1(R0, 0x40),
PIO_OUT_RI1(R0, NE2K_REG_ISR),
// Send size (TBCR, RBCR)
PIO_MOV_RI1(R1, 0x00),
- {UDI_PIO_LOAD|UDI_PIO_MEM|UDI_PIO_R0, UDI_PIO_2BYTE, UDI_PIO_R1},
+ {UDI_PIO_LOAD|UDI_PIO_MEM|UDI_PIO_R1, UDI_PIO_2BYTE, UDI_PIO_R0},
PIO_OUT_RI1(R0, NE2K_REG_TBCR0),
PIO_OUT_RI1(R0, NE2K_REG_RBCR0),
{UDI_PIO_SHIFT_RIGHT|UDI_PIO_R0, UDI_PIO_2BYTE, 8},
PIO_MOV_RI1(R0, 0x12),
PIO_OUT_RI1(R0, NE2K_REG_CMD),
// Send data
- PIO_MOV_RI1(R0, 0), // - Buffer offset (increment by 2)
+ PIO_MOV_RI1(R1, 0x00),
+ {UDI_PIO_LOAD|UDI_PIO_MEM|UDI_PIO_R1, UDI_PIO_2BYTE, UDI_PIO_R0},
+ {UDI_PIO_SHIFT_RIGHT|UDI_PIO_R0, UDI_PIO_2BYTE, 1}, // - Iterations
PIO_MOV_RI1(R1, NE2K_REG_MEM), // - Reg offset (no increment)
- PIO_MOV_RI1(R2, 256/2), // - 128 iterations
+ PIO_MOV_RI1(R2, 0), // - Offset (inc by 2 bytes)
{UDI_PIO_REP_OUT_IND, UDI_PIO_2BYTE,
- UDI_PIO_REP_ARGS(UDI_PIO_BUF, UDI_PIO_R0, 2, UDI_PIO_R1, 0, UDI_PIO_R2)},
+ UDI_PIO_REP_ARGS(UDI_PIO_BUF, UDI_PIO_R2, 1, UDI_PIO_R1, 0, UDI_PIO_R0)},
// Wait for completion (TODO: IRQ quit and wait for IRQ)
+ {UDI_PIO_LABEL, 0, 1},
+ PIO_IN_RI1(R0, NE2K_REG_ISR),
+ {UDI_PIO_AND_IMM|UDI_PIO_R0, UDI_PIO_1BYTE, 0x40},
+ {UDI_PIO_CSKIP+UDI_PIO_R0, UDI_PIO_1BYTE, UDI_PIO_NZ},
+ {UDI_PIO_BRANCH, 0, 1},
+
// Request send
PIO_MOV_RI1(R0, NE2K_TX_FIRST_PG),
PIO_OUT_RI1(R0, NE2K_REG_TPSR),
}
void ne2k_nd_rx_rx_rdy(udi_nic_rx_cb_t *cb)
{
- // TODO: Add cb(s) to avaliable list
+ udi_cb_t *gcb = UDI_GCB(cb);
+ ne2k_rdata_t *rdata = gcb->context;
+
+ // Add cb(s) to avaliable list
+ if( rdata->rx_last_cb ) {
+ rdata->rx_last_cb->chain = cb;
+ }
+ else {
+ rdata->rx_next_cb = cb;
+ }
+ rdata->rx_last_cb = cb;
+ // Follow new chain
+ while( rdata->rx_last_cb->chain )
+ rdata->rx_last_cb = rdata->rx_last_cb->chain;
+
}
void ne2k_intr__rx_ok(udi_cb_t *gcb)
{
else
{
// Drop packet due to no free cbs
+ udi_debug_printf("ne2k_intr__rx_ok: Dropped due to no free rx cbs\n");
+ // TODO: Tell hardware to drop packet
}
}
#include "ne2000_common.h"
// === PROTOTYPES ===
+void ne2k_nd_tx_tx_req__trans_done(udi_cb_t *gcb, udi_buf_t *new_buf, udi_status_t status, udi_ubit16_t res);
// === CODE ===
void ne2k_nd_tx_channel_event_ind(udi_channel_event_cb_t *cb)
void ne2k_nd_tx_tx_req(udi_nic_tx_cb_t *cb)
{
+ ne2k_rdata_t *rdata = UDI_GCB(cb)->context;
// TODO: TX request
udi_debug_printf("ne2k_nd_tx_tx_req: %p\n", cb);
- udi_nsr_tx_rdy(cb);
+ udi_debug_printf("- pio_handles[%i] = %p\n", NE2K_PIO_TX, rdata->pio_handles[NE2K_PIO_TX]);
+ udi_debug_printf("- cb->tx_buf->buf_size = %x\n", cb->tx_buf->buf_size);
+ udi_pio_trans(ne2k_nd_tx_tx_req__trans_done, UDI_GCB(cb), rdata->pio_handles[NE2K_PIO_TX],
+ 0, cb->tx_buf, &cb->tx_buf->buf_size);
+}
+void ne2k_nd_tx_tx_req__trans_done(udi_cb_t *gcb, udi_buf_t *new_buf, udi_status_t status, udi_ubit16_t res)
+{
+ udi_nsr_tx_rdy( UDI_MCB(gcb, udi_nic_tx_cb_t) );
}
void ne2k_nd_tx_exp_tx_req(udi_nic_tx_cb_t *cb)