From: John Hodge Date: Fri, 11 Oct 2013 03:47:07 +0000 (+0800) Subject: Modules/UDI - NSR TX X-Git-Tag: rel0.15~117 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=6c17bdc4f8dee5d2a9c97f1db2cd9b85eefa9b8e;p=tpg%2Facess2.git Modules/UDI - NSR TX --- diff --git a/KernelLand/Modules/Interfaces/UDI/trans/nsr.c b/KernelLand/Modules/Interfaces/UDI/trans/nsr.c index 2ea4506c..879d0bdc 100644 --- a/KernelLand/Modules/Interfaces/UDI/trans/nsr.c +++ b/KernelLand/Modules/Interfaces/UDI/trans/nsr.c @@ -14,6 +14,7 @@ #include #define NUM_RX_BUFFERS 4 +#define NUM_TX_DESCS 4 enum { ACESSNSR_OPS_CTRL = 1, @@ -30,6 +31,14 @@ enum { }; // === TYPES === +typedef struct acessnsr_txdesc_s +{ + //udi_nic_tx_cb_t cb; + tMutex CompleteMutex; + int BufIdx; + tIPStackBuffer *IPBuffer; +} acessnsr_txdesc_t; + typedef struct { udi_init_context_t init_context; @@ -43,6 +52,9 @@ typedef struct tIPStack_AdapterType AdapterType; void *ipstack_handle; + + tWorkqueue TXWorkQueue; + acessnsr_txdesc_t TXDescs[NUM_TX_DESCS]; udi_channel_t rx_channel; udi_channel_t tx_channel; @@ -60,6 +72,7 @@ void acessnsr_ctrl_ch_ev_ind__tx_channel_spawned(udi_cb_t *gcb, udi_channel_t ch void acessnsr_ctrl_bind_ack(udi_nic_bind_cb_t *cb, udi_status_t status); void acessnsr_ctrl_bind_ack__rx_buf_allocated(udi_cb_t *gcb, udi_buf_t *new_buf); void acessnsr_ctrl_bind_ack__rx_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb); +void acessnsr_ctrl_bind_ack__tx_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb); void acessnsr_ctrl_unbind_ack(udi_nic_cb_t *cb, udi_status_t status); void acessnsr_ctrl_enable_ack(udi_nic_cb_t *cb, udi_status_t status); void acessnsr_ctrl_disable_ack(udi_nic_cb_t *cb, udi_status_t status); @@ -69,12 +82,14 @@ void acessnsr_ctrl_info_ack(udi_nic_info_cb_t *cb); // --- NSR TX void acessnsr_tx_channel_event_ind(udi_channel_event_cb_t *cb); void acessnsr_tx_rdy(udi_nic_tx_cb_t *cb); +void acessnsr_tx_rdy__buffer_cleared(udi_cb_t *gcb, udi_buf_t *buf); // --- NSR RX void acessnsr_rx_channel_event_ind(udi_channel_event_cb_t *cb); void acessnsr_rx_ind(udi_nic_rx_cb_t *cb); void acessnsr_rx_exp_ind(udi_nic_rx_cb_t *cb); // --- Acess IPStack int acessnsr_SendPacket(void *Card, tIPStackBuffer *Buffer); +void acessnsr_SendPacket__buf_write_complete(udi_cb_t *gcb, udi_buf_t *buf); tIPStackBuffer *acessnsr_WaitForPacket(void *Card); // === CODE === @@ -87,6 +102,7 @@ void acessnsr_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level) } Workqueue_Init(&rdata->RXQueue, "AcessNSR RX", offsetof(udi_nic_rx_cb_t, chain)); + Workqueue_Init(&rdata->TXWorkQueue, "AcessNSR TX", offsetof(udi_nic_tx_cb_t, chain)); udi_usage_res(cb); } @@ -199,6 +215,26 @@ void acessnsr_ctrl_bind_ack__rx_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb) // A A A A return ; } + rdata->init_idx = -1; + acessnsr_ctrl_bind_ack__tx_cb_allocated(gcb, NULL); + // V V V V +} +void acessnsr_ctrl_bind_ack__tx_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb) +{ + acessnsr_rdata_t *rdata = gcb->context; + if( rdata->init_idx != (udi_index_t)-1 ) + { + //udi_assert(new_cb); + ASSERT(new_cb); + Workqueue_AddWork( &rdata->TXWorkQueue, UDI_MCB(new_cb, udi_nic_tx_cb_t) ); + } + rdata->init_idx ++; + if( rdata->init_idx < NUM_TX_DESCS ) + { + udi_cb_alloc(acessnsr_ctrl_bind_ack__tx_cb_allocated, gcb, ACESSNSR_CB_TX, rdata->tx_channel); + // A A A A + return ; + } udi_channel_event_complete( UDI_MCB(rdata->active_cb,udi_channel_event_cb_t), UDI_OK ); // = = = = } @@ -233,7 +269,16 @@ void acessnsr_tx_channel_event_ind(udi_channel_event_cb_t *cb) } void acessnsr_tx_rdy(udi_nic_tx_cb_t *cb) { - UNIMPLEMENTED(); + //acessnsr_txdesc_t *tx = UDI_GCB(cb)->context; + // TODO: Can errors be detected here? + UDI_BUF_DELETE(acessnsr_tx_rdy__buffer_cleared, UDI_GCB(cb), cb->tx_buf->buf_size, cb->tx_buf, 0); +} +void acessnsr_tx_rdy__buffer_cleared(udi_cb_t *gcb, udi_buf_t *buf) +{ + acessnsr_txdesc_t *tx = gcb->scratch; + udi_nic_tx_cb_t *cb = UDI_MCB(gcb, udi_nic_tx_cb_t); + cb->tx_buf = buf; + Mutex_Release(&tx->CompleteMutex); // triggers acessnsr_SendPacket } // --- NSR RX void acessnsr_rx_channel_event_ind(udi_channel_event_cb_t *cb) @@ -251,13 +296,50 @@ void acessnsr_rx_ind(udi_nic_rx_cb_t *cb) } void acessnsr_rx_exp_ind(udi_nic_rx_cb_t *cb) { - UNIMPLEMENTED(); + acessnsr_rx_ind(cb); + //UNIMPLEMENTED(); } // --- Acess IPStack int acessnsr_SendPacket(void *Card, tIPStackBuffer *Buffer) { - UNIMPLEMENTED(); - return 1; + acessnsr_rdata_t *rdata = Card; + udi_nic_tx_cb_t *cb = Workqueue_GetWork(&rdata->TXWorkQueue); + ASSERT(cb); + acessnsr_txdesc_t *tx = UDI_GCB(cb)->scratch; + ASSERT(tx); + + Mutex_Acquire(&tx->CompleteMutex); + tx->IPBuffer = Buffer; + tx->BufIdx = -1; + acessnsr_SendPacket__buf_write_complete(UDI_GCB(cb), NULL); + + // Double lock is resolved once TX is complete + Mutex_Acquire(&tx->CompleteMutex); + Mutex_Release(&tx->CompleteMutex); + // TODO: TX status + + Workqueue_AddWork(&rdata->TXWorkQueue, tx); + return 0; +} +void acessnsr_SendPacket__buf_write_complete(udi_cb_t *gcb, udi_buf_t *buf) +{ + acessnsr_txdesc_t *tx = gcb->scratch; + udi_nic_tx_cb_t *cb = UDI_MCB(gcb, udi_nic_tx_cb_t); + if( tx->BufIdx >= 0 ) { + cb->tx_buf = buf; + } + size_t buflen; + const void *bufptr; + if( (tx->BufIdx = IPStack_Buffer_GetBuffer(tx->IPBuffer, tx->BufIdx, &buflen, &bufptr )) != -1 ) + { + udi_buf_write(acessnsr_SendPacket__buf_write_complete, gcb, + bufptr, buflen, cb->tx_buf, (cb->tx_buf ? cb->tx_buf->buf_size : 0), 0, NULL); + // A A A A + return ; + } + + udi_nd_tx_req(cb); + // continued in acessnsr_tx_rdy } void _FreeHeapSubBuf(void *Arg, size_t Pre, size_t Post, const void *DataBuf) { @@ -338,7 +420,7 @@ udi_ops_init_t acessnsr_ops_list[] = { udi_cb_init_t acessnsr_cb_init_list[] = { {ACESSNSR_CB_CTRL, ACESSNSR_META_NIC, UDI_NIC_BIND_CB_NUM, 0, 0,NULL}, {ACESSNSR_CB_RX, ACESSNSR_META_NIC, UDI_NIC_RX_CB_NUM, 0, 0,NULL}, - {ACESSNSR_CB_TX, ACESSNSR_META_NIC, UDI_NIC_TX_CB_NUM, 0, 0,NULL}, + {ACESSNSR_CB_TX, ACESSNSR_META_NIC, UDI_NIC_TX_CB_NUM, sizeof(acessnsr_txdesc_t), 0,NULL}, {0} }; const udi_init_t acessnsr_init = { diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c index 010eed09..c9399348 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c @@ -32,7 +32,8 @@ udi_cb_t *udi_cb_alloc_internal_v(tUDI_MetaLang *Meta, udi_index_t MetaCBNum, size_t base = Meta->CbTypes[MetaCBNum].Size; ASSERTC(base, >=, sizeof(udi_cb_t)); base -= sizeof(udi_cb_t); - LOG("+ %i + %i + %i", base, inline_size, scratch_size); + LOG("(%s) udi_cb_t + %i + %i + %i", + Meta->Name, base, inline_size, scratch_size); tUDI_CBHeader *cbhdr = NEW(tUDI_CBHeader, + base + inline_size + scratch_size); cbhdr->Metalang = Meta; cbhdr->MetaCBNum = MetaCBNum; @@ -44,9 +45,10 @@ udi_cb_t *udi_cb_alloc_internal_v(tUDI_MetaLang *Meta, udi_index_t MetaCBNum, void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx, udi_channel_t channel) { const udi_cb_init_t *cb_init; - LOG("Inst=%p, bind_cb_idx=%i, channel=%p", Inst, bind_cb_idx, channel); ASSERT(Inst); ASSERT(Inst->Module); + LOG("Inst=%p(%s), bind_cb_idx=%i, channel=%p", + Inst, Inst->Module->ModuleName, bind_cb_idx, channel); ASSERT(Inst->Module->InitInfo); ASSERT(Inst->Module->InitInfo->cb_init_list); @@ -63,18 +65,6 @@ void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx, } return udi_cb_alloc_internal_v(metalang, cb_init->meta_cb_num, cb_init->inline_size, cb_init->scratch_requirement, channel); - #if 0 - ASSERTC(cb_init->meta_cb_num, <, metalang->nCbTypes); - size_t base = metalang->CbTypes[cb_init->meta_cb_num].Size; - ASSERTC(base, >=, sizeof(udi_cb_t)); - base -= sizeof(udi_cb_t); - LOG("+ %i + %i + %i", base, cb_init->inline_size, cb_init->scratch_requirement); - udi_cb_t *ret = NEW(udi_cb_t, + base - + cb_init->inline_size + cb_init->scratch_requirement); - ret->channel = channel; - ret->scratch = (void*)ret + sizeof(udi_cb_t) + base + cb_init->inline_size; - return ret; - #endif } } Log_Warning("UDI", "Cannot find CB init def %i for '%s'", diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c index 751a369e..f2b6b4d8 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c @@ -118,20 +118,12 @@ void udi_nsr_info_ack(udi_nic_info_cb_t *cb) } // --- TX --- -void udi_nsr_tx_rdy(udi_nic_tx_cb_t *cb) -{ - UNIMPLEMENTED(); -} - -void udi_nd_tx_req(udi_nic_tx_cb_t *cb) -{ - UNIMPLEMENTED(); -} - -void udi_nd_exp_tx_req(udi_nic_tx_cb_t *cb) -{ - UNIMPLEMENTED(); -} +UDI_MEI_STUBS(udi_nsr_tx_rdy, udi_nic_tx_cb_t, 0, (), (), (), UDI_NSR_TX_OPS_NUM, 1); +udi_layout_t _udi_nsr_tx_rdy_marshal_layout[] = { UDI_DL_END }; +UDI_MEI_STUBS(udi_nd_tx_req, udi_nic_tx_cb_t, 0, (), (), (), UDI_ND_TX_OPS_NUM, 1); +udi_layout_t _udi_nd_tx_req_marshal_layout[] = { UDI_DL_END }; +UDI_MEI_STUBS(udi_nd_exp_tx_req, udi_nic_tx_cb_t, 0, (), (), (), UDI_ND_TX_OPS_NUM, 2); +udi_layout_t _udi_nd_exp_tx_req_marshal_layout[] = { UDI_DL_END }; // --- RX --- UDI_MEI_STUBS(udi_nsr_rx_ind, udi_nic_rx_cb_t, 0, (), (), (), UDI_NSR_RX_OPS_NUM, 1) @@ -170,6 +162,12 @@ udi_layout_t _NIC_RX_cb_layout[] = { UDI_DL_UBIT8_T, // rx_valid UDI_DL_END }; +udi_layout_t _NIC_TX_cb_layout[] = { + UDI_DL_CB, // chain + UDI_DL_BUF, 0, 0, 0, // tx_buf + UDI_DL_BOOLEAN_T, // completion_urgent + UDI_DL_END +}; udi_mei_op_template_t udi_mei_info__nic__nd_ctrl_ops[] = { MEI_OPINFO(udi_nd_bind_req, REQ, 0, NIC_BIND, NSR_CTRL,1, ,0), @@ -180,9 +178,12 @@ udi_mei_op_template_t udi_mei_info__nic__nsr_ctrl_ops[] = { {0} }; udi_mei_op_template_t udi_mei_info__nic__nd_tx_ops[] = { + MEI_OPINFO(udi_nd_tx_req, REQ, 0, NIC_TX, NSR_TX,1, ,0), + MEI_OPINFO(udi_nd_exp_tx_req, REQ, 0, NIC_TX, NSR_TX,1, ,0), {0} }; udi_mei_op_template_t udi_mei_info__nic__nsr_tx_ops[] = { + MEI_OPINFO(udi_nsr_tx_rdy, RDY, 0, NIC_TX, ,0, ,0), {0} }; udi_mei_op_template_t udi_mei_info__nic__nd_rx_ops[] = {