Exemple #1
0
/*@only@*//*@null@*/wwd_result_t wwd_bus_read_frame( wiced_buffer_t* buffer )
{
    uint32_t intstatus;
    void *p0 = NULL;
    uint16_t *hwtag;

    intstatus = read_intstatus();

    /* Handle DMA interrupts */
    if (intstatus & I_XI) {
        dma_tx_reclaim();
    }


    if ( rxactive_dma( ) == 0 )
    {
        refill_dma( );
        if ( rxactive_dma( ) != 0 )
        {
            int_enab();
        }
    }


        /* Handle DMA errors */
    if (intstatus & I_ERRORS) {
        refill_dma( );
        WPRINT_WWD_DEBUG(("RX errors: intstatus: 0x%x\n", (unsigned int)intstatus));
    }
    /* Handle DMA receive interrupt */
    p0 = read_dma_packet( &hwtag );
    if ( p0  == NULL)
    {

        if ( rxactive_dma( ) != 0 )
        {
            int_enab();
        }

        return WWD_NO_PACKET_TO_RECEIVE;
    }

    *buffer = p0;

    host_buffer_add_remove_at_front( buffer, - (int)sizeof(wwd_buffer_header_t) );
    wwd_sdpcm_update_credit((uint8_t*)hwtag);

    refill_dma( );
    /* where are buffers from dma_rx and dma_getnextrxp created? */

    return WWD_SUCCESS;



}
Exemple #2
0
wwd_result_t wwd_process_clm_data(void)
{
    wwd_result_t ret = WWD_SUCCESS;
    uint32_t clm_blob_size;
    uint32_t datalen;
    unsigned int size2alloc, data_offset;
    unsigned char *chunk_buf;
    uint16_t dl_flag = DL_BEGIN;
    unsigned int cumulative_len = 0;
    unsigned int chunk_len;
    uint32_t size_read;

    /* clm file size is the initial datalen value which is decremented */
    clm_blob_size = resource_get_size( &wifi_firmware_clm_blob );
    datalen = clm_blob_size;

    data_offset = offsetof(wl_dload_data_t, data);
    size2alloc = data_offset + MAX_CHUNK_LEN;

    if ((chunk_buf = (unsigned char *)malloc(size2alloc)) != NULL) {
        memset(chunk_buf, 0, size2alloc);

        do {
            if (datalen >= MAX_CHUNK_LEN)
                chunk_len = MAX_CHUNK_LEN;
            else
                chunk_len = datalen;

            // check size_read is full value also and resource read return
            if ((ret = resource_read(&wifi_firmware_clm_blob, cumulative_len, chunk_len, &size_read, chunk_buf + data_offset)) != WWD_SUCCESS) {
                break;
            }

            if (size_read != chunk_len) {
                wiced_assert("During CLM download, resource_read() returned less of the file than should be available\n", 1 == 0);
                ret = WWD_CLM_BLOB_DLOAD_ERROR;
                break;
            }

            cumulative_len += chunk_len;

            if (datalen - chunk_len == 0)
                dl_flag |= DL_END;

            ret = wwd_download2dongle(WWD_STA_INTERFACE, IOVAR_STR_CLMLOAD, dl_flag, DL_TYPE_CLM,
                chunk_buf, data_offset + chunk_len);
            dl_flag &= (uint16_t)~DL_BEGIN;

            datalen = datalen - chunk_len;
        } while ((datalen > 0) && (ret == WWD_SUCCESS));

        free(chunk_buf);
        if ( ret != WWD_SUCCESS )
        {
            wwd_result_t ret_clmload_status;
            wiced_buffer_t buffer;
            wiced_buffer_t response;
            void *data;

            WPRINT_WWD_DEBUG(("clmload (%ld byte file) failed with return %d; ", clm_blob_size, ret));
            data = (int*)wwd_sdpcm_get_iovar_buffer( &buffer, 4, IOVAR_STR_CLMLOAD_STATUS );
            CHECK_IOCTL_BUFFER( data );
            ret_clmload_status = wwd_sdpcm_send_iovar( SDPCM_GET, buffer, &response, WWD_STA_INTERFACE );
            if ( ret_clmload_status != WWD_SUCCESS )
            {
                WPRINT_WWD_DEBUG(("clmload_status failed with return %d\n", ret_clmload_status));
            }
            else
            {
                uint32_t *clmload_status = (uint32_t *)host_buffer_get_current_piece_data_pointer( response );

                if ( clmload_status != NULL )
                {
                    WPRINT_WWD_DEBUG(("clmload_status is %lu\n", *clmload_status));
                    host_buffer_release( response, WWD_NETWORK_RX );
                }
            }
        }
    } else {
        ret = WWD_MALLOC_FAILURE;
    }

    return ret;
}
/** The WWD Thread function
 *
 *  This is the main loop of the WWD Thread.
 *  It simply calls @ref wwd_thread_poll_all to send/receive all waiting packets, then goes
 *  to sleep.  The sleep has a 100ms timeout, causing the send/receive queues to be
 *  checked 10 times per second in case an interrupt is missed.
 *  Once the quit flag has been set, flags/mutexes are cleaned up, and the function exits.
 *
 * @param thread_input  : unused parameter needed to match thread prototype.
 *
 */
static void wwd_thread_func( wwd_thread_arg_t /*@unused@*/thread_input ) /*@globals killed wwd_transceive_semaphore@*/ /*@modifies wwd_wlan_status, wwd_bus_interrupt, wwd_thread_quit_flag, wwd_inited, wwd_thread@*/
{
    int8_t rx_status;
    int8_t tx_status;
    wwd_result_t wwd_result;

    UNUSED_PARAMETER(thread_input);

    WWD_LOG(("Started Wiced Thread\n"));

    /* Interrupts may be enabled inside thread. To make sure none lost set flag now. */
    wwd_inited = WICED_TRUE;

    while ( wwd_thread_quit_flag != WICED_TRUE )
    {
        /* If was in deep sleep and needs wakeup, then wake first */
        if ( WICED_TRUE == wwd_wifi_ds1_needs_wake( ) )
        {
            wwd_result = wwd_wifi_ds1_finish_wake( );
            if ( WWD_SUCCESS != wwd_result )
            {
                WPRINT_WWD_ERROR(("Err %d:Unable to do ds1 wake", wwd_result));
            }
        }

        /* Check if we were woken by interrupt */
        if ( ( wwd_bus_interrupt == WICED_TRUE ) ||
           ( WWD_BUS_USE_STATUS_REPORT_SCHEME ) )
        {
           wwd_bus_interrupt = WICED_FALSE;

           /* Check if the interrupt indicated there is a packet to read */
           if ( wwd_bus_packet_available_to_read( ) != 0)
           {
               /* Receive all available packets */
               do
               {
                   rx_status = wwd_thread_receive_one_packet( );
               } while ( rx_status != 0 );
           }
        }

        /* Send all queued packets */
        do
        {
             tx_status = wwd_thread_send_one_packet( );
        }
        while (tx_status != 0);

        /* Sleep till WLAN do something */
        wwd_wait_for_wlan_event( &wwd_transceive_semaphore );
        WWD_LOG(("Wiced Thread: Woke\n"));
    }

    /* Set flag before releasing objects */
    wwd_inited = WICED_FALSE;

    /* Reset the quit flag */
    wwd_thread_quit_flag = WICED_FALSE;

    /* Delete the semaphore */
    (void) host_rtos_deinit_semaphore( &wwd_transceive_semaphore );  /* Ignore return - not much can be done about failure */

    wwd_sdpcm_quit( );

    WWD_LOG(("Stopped Wiced Thread\n"));

    if ( WWD_SUCCESS != host_rtos_finish_thread( &wwd_thread ) )
    {
        WPRINT_WWD_DEBUG(("Could not close WWD thread\n"));
    }
}