Modules/UDI - Heaps of fixes and features
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / trans / nsr.c
index 879d0bd..e6a3930 100644 (file)
@@ -27,7 +27,8 @@ enum {
 enum {
        ACESSNSR_CB_CTRL = 1,
        ACESSNSR_CB_RX,
-       ACESSNSR_CB_TX
+       ACESSNSR_CB_TX,
+       ACESSNSR_CB_STD,
 };
 
 // === TYPES ===
@@ -43,10 +44,7 @@ typedef struct
 {
        udi_init_context_t      init_context;   
        udi_cb_t        *active_cb;
-
-       udi_index_t     init_idx;
-       udi_buf_t       *rx_buffers[NUM_RX_BUFFERS];
-       udi_nic_rx_cb_t *rx_cbs[NUM_RX_BUFFERS];
+       udi_channel_t   saved_active_channel;
 
        tWorkqueue      RXQueue;
 
@@ -70,9 +68,9 @@ void acessnsr_ctrl_channel_event_ind(udi_channel_event_cb_t *cb);
 void acessnsr_ctrl_ch_ev_ind__rx_channel_spawned(udi_cb_t *gcb, udi_channel_t channel);
 void acessnsr_ctrl_ch_ev_ind__tx_channel_spawned(udi_cb_t *gcb, udi_channel_t channel);
 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_bind_ack__rx_cbs_allocated(udi_cb_t *gcb, udi_cb_t *first_new_cb);
+void acessnsr_ctrl_bind_ack__tx_cbs_allocated(udi_cb_t *gcb, udi_cb_t *first_new_cb);
+void acessnsr_ctrl_bind_ack__std_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);
@@ -162,81 +160,66 @@ void acessnsr_ctrl_bind_ack(udi_nic_bind_cb_t *cb, udi_status_t status)
                break;
        }
 
+       // - Register with IPStack
        if(cb->capabilities & UDI_NIC_CAP_TX_IP_CKSUM)
                rdata->AdapterType.Flags |= ADAPTERFLAG_OFFLOAD_IP4;
        if(cb->capabilities & UDI_NIC_CAP_TX_TCP_CKSUM)
                rdata->AdapterType.Flags |= ADAPTERFLAG_OFFLOAD_TCP;
        if(cb->capabilities & UDI_NIC_CAP_TX_UDP_CKSUM)
                rdata->AdapterType.Flags |= ADAPTERFLAG_OFFLOAD_UDP;
-       
        rdata->AdapterType.Name = "udi";
        rdata->AdapterType.SendPacket = acessnsr_SendPacket;
        rdata->AdapterType.WaitForPacket = acessnsr_WaitForPacket;
-
        rdata->ipstack_handle = IPStack_Adapter_Add(&rdata->AdapterType, rdata, cb->mac_addr);
 
        // Allocate RX CBs and buffers
-       rdata->init_idx = -1;
-       acessnsr_ctrl_bind_ack__rx_buf_allocated(rdata->active_cb, NULL);
+       // EVIL: Save and change channel of event CB
+       rdata->saved_active_channel = rdata->active_cb->channel;
+       rdata->active_cb->channel = rdata->rx_channel;
+       udi_cb_alloc_batch( acessnsr_ctrl_bind_ack__rx_cbs_allocated, rdata->active_cb,
+               ACESSNSR_CB_RX, NUM_RX_BUFFERS, TRUE, 0, NULL);
        // V V V V
 }
-void acessnsr_ctrl_bind_ack__rx_buf_allocated(udi_cb_t *gcb, udi_buf_t *new_buf)
+void acessnsr_ctrl_bind_ack__rx_cbs_allocated(udi_cb_t *gcb, udi_cb_t *first_new_cb)
 {
        acessnsr_rdata_t *rdata = gcb->context;
-       if( rdata->init_idx != (udi_index_t)-1 )
-       {
-               rdata->rx_buffers[rdata->init_idx] = new_buf;
-       }
-       rdata->init_idx ++;
-       if( rdata->init_idx < NUM_RX_BUFFERS )
-       {
-               UDI_BUF_ALLOC(acessnsr_ctrl_bind_ack__rx_buf_allocated, gcb, NULL, 0, NULL);
-               // A A A A
-               return ;
-       }
+       // Send of the entire list
+       ASSERT(first_new_cb);
+       udi_nd_rx_rdy( UDI_MCB(first_new_cb, udi_nic_rx_cb_t) );
        
-       rdata->init_idx = -1;
-       acessnsr_ctrl_bind_ack__rx_cb_allocated(gcb, NULL);
+       // Allocate batch (no buffers)
+       gcb->channel = rdata->tx_channel;
+       udi_cb_alloc_batch( acessnsr_ctrl_bind_ack__tx_cbs_allocated, gcb,
+               ACESSNSR_CB_TX, NUM_TX_DESCS, FALSE, 0, NULL);
+       // V V V V
 }
-void acessnsr_ctrl_bind_ack__rx_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb)
+void acessnsr_ctrl_bind_ack__tx_cbs_allocated(udi_cb_t *gcb, udi_cb_t *first_new_cb)
 {
        acessnsr_rdata_t *rdata = gcb->context;
-       if( rdata->init_idx != (udi_index_t)-1 )
-       {
-               udi_nic_rx_cb_t *cb = UDI_MCB(new_cb, udi_nic_rx_cb_t);
-               rdata->rx_cbs[rdata->init_idx] = cb;
-               cb->rx_buf = rdata->rx_buffers[rdata->init_idx];
-               udi_nd_rx_rdy(cb);
-       }
-       rdata->init_idx ++;
-       if( rdata->init_idx < NUM_RX_BUFFERS )
+       ASSERT(first_new_cb);
+       
        {
-               udi_cb_alloc(acessnsr_ctrl_bind_ack__rx_cb_allocated, gcb, ACESSNSR_CB_RX, rdata->rx_channel);
-               // A A A A
-               return ;
+               udi_nic_tx_cb_t *cb, *next_cb;
+               cb = UDI_MCB(first_new_cb, udi_nic_tx_cb_t);
+               ASSERT(cb);
+               do {
+                       next_cb = cb->chain;
+                       cb->chain = NULL;
+                       Workqueue_AddWork( &rdata->TXWorkQueue, cb );
+               } while(next_cb);
        }
-       rdata->init_idx = -1;
-       acessnsr_ctrl_bind_ack__tx_cb_allocated(gcb, NULL);
+       
+       // Allocate standard control CB (for enable/disable)
+       udi_cb_alloc(acessnsr_ctrl_bind_ack__std_cb_allocated, gcb,
+               ACESSNSR_CB_STD, rdata->saved_active_channel);
        // V V V V
 }
-void acessnsr_ctrl_bind_ack__tx_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb)
+void acessnsr_ctrl_bind_ack__std_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 );
-       // = = = =
+       // Final Operations:
+       // - Enable card (RX won't happen until this is called)
+       udi_nd_enable_req( UDI_MCB(new_cb, udi_nic_cb_t) );
+       // Continued in acessnsr_ctrl_enable_ack
 }
 void acessnsr_ctrl_unbind_ack(udi_nic_cb_t *cb, udi_status_t status)
 {
@@ -244,7 +227,12 @@ 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)
 {
-       UNIMPLEMENTED();
+       udi_cb_t        *gcb = UDI_GCB(cb);
+       acessnsr_rdata_t *rdata = gcb->context;
+       
+       rdata->active_cb->channel = rdata->saved_active_channel;
+       udi_channel_event_complete( UDI_MCB(rdata->active_cb,udi_channel_event_cb_t), UDI_OK );
+       // = = = =
 }
 void acessnsr_ctrl_disable_ack(udi_nic_cb_t *cb, udi_status_t status)
 {
@@ -303,11 +291,13 @@ void acessnsr_rx_exp_ind(udi_nic_rx_cb_t *cb)
 int acessnsr_SendPacket(void *Card, tIPStackBuffer *Buffer)
 {
        acessnsr_rdata_t *rdata = Card;
+       LOG("Card=%p,Buffer=%p", Card, Buffer);
        udi_nic_tx_cb_t *cb = Workqueue_GetWork(&rdata->TXWorkQueue);
        ASSERT(cb);
        acessnsr_txdesc_t *tx = UDI_GCB(cb)->scratch;
        ASSERT(tx);
-       
+
+       LOG("Mutex acquire #1 %p", cb);
        Mutex_Acquire(&tx->CompleteMutex);
        tx->IPBuffer = Buffer;
        tx->BufIdx = -1;
@@ -318,7 +308,8 @@ int acessnsr_SendPacket(void *Card, tIPStackBuffer *Buffer)
        Mutex_Release(&tx->CompleteMutex);
        // TODO: TX status
        
-       Workqueue_AddWork(&rdata->TXWorkQueue, tx);
+       LOG("Release %p", cb);  
+       Workqueue_AddWork(&rdata->TXWorkQueue, cb);
        return 0;
 }
 void acessnsr_SendPacket__buf_write_complete(udi_cb_t *gcb, udi_buf_t *buf)
@@ -332,6 +323,7 @@ void acessnsr_SendPacket__buf_write_complete(udi_cb_t *gcb, udi_buf_t *buf)
        const void      *bufptr;
        if( (tx->BufIdx = IPStack_Buffer_GetBuffer(tx->IPBuffer, tx->BufIdx, &buflen, &bufptr )) != -1 )
        {
+               Debug_HexDump("NSR", bufptr, buflen);
                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
@@ -421,6 +413,7 @@ 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, sizeof(acessnsr_txdesc_t), 0,NULL},
+       {ACESSNSR_CB_STD, ACESSNSR_META_NIC, UDI_NIC_TX_CB_NUM, 0, 0,NULL},
        {0}
 };
 const udi_init_t       acessnsr_init = {

UCC git Repository :: git.ucc.asn.au