FreeCalypso > hg > fc-magnetite
view src/g23m-aci/gdd_dio/gdd_dio_dtxf.c @ 673:62a5285e014a
Lorekeeping: allow tpudrv-leonardo.lib on Leonardo/Tango
Back in 2015 the Mother's idea was to produce a FreeCalypso development
board that would be a clone of TI Leonardo, including the original
quadband RFFE; one major additional stipulation was that this board
needed to be able to run original unmodified TCS211-20070608 firmware
with all blobs intact, with only minimal binary patches to main.lib
and tpudrv.lib. The necessary patched libs were produced at that time
in the tcs211-patches repository.
That plan was changed and we produced FCDEV3B instead, with Openmoko's
triband RFFE instead of Leonardo quadband, but when FC Magnetite started
in 2016, a TPUDRV_blob= provision was still made, allowing the possibility
of patching OM's tpudrv.lib for a restored Leonardo RFFE.
Now in 2020 we have FC Tango which is essentially a verbatim clone of
Leonardo core, including the original quadband RFFE. We have also
deblobbed our firmware so much that we have absolutely no real need
for a blob version of tpudrv.lib - but I thought it would be neat to put
the ancient TPUDRV_blob= mechanism (classic config) to its originally
intended use, just for the heck of it.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 29 May 2020 03:55:36 +0000 |
parents | 53929b40109c |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | File : gdd_dio_txf.c +----------------------------------------------------------------------------- | Copyright 2002 Texas Instruments Berlin, AG | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Berlin, AG | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Berlin, AG. +----------------------------------------------------------------------------- | Purpose : This modul is part of the entity gdd_dio and implements the | dtx service functions. +----------------------------------------------------------------------------- */ #define ENTITY_GDD_DIO /*==== INCLUDES =============================================================*/ #include "typedefs.h" /* to get Condat data types */ #include "vsi.h" /* to get a lot of macros */ /* GDD stuff */ #include "gdd_dio.h" /* to get the global entity definitions */ #include "gdd_dio_con_mgr.h" #include "gdd_dio_dtxf.h" #include "gdd_dio_rxf.h" #include "gdd_dio_drxf.h" /* Needed for allocate_gdd_desc_list() etc */ #include "gdd_dio_queue.h" /*==== CONST ================================================================*/ /*==== LOCAL VARS ===========================================================*/ /*==== PRIVATE FUNCTIONS ====================================================*/ /*==== PUBLIC FUNCTIONS =====================================================*/ GLOBAL GDD_RESULT gdd_dio_dtx_get_send_buffer ( T_GDD_CON_HANDLE con_handle, T_GDD_BUF ** send_buf, U16 data_size ) { T_GDD_INST_ID inst; T_GDD_DIO_DATA * gdd_dio_data; T_GDD_DIO_CON_DATA * con_data; T_dio_buffer * dio_buf; TRACE_USER_CLASS(TC_FUNC_DATA_FLOW, "[GDD] gdd_dio_dtx_get_send_buffer()"); inst = (T_GDD_INST_ID)inst_num_from_dev_id(con_handle); /** * Do the necessary checks. */ if(inst < 0) { TRACE_ERROR("[GDD] Invalid connection handle"); return GDD_INVALID_PARAMS; } if(inst >= GDD_NUM_INSTS) { TRACE_ERROR("[GDD] inst id out of bounds"); return GDD_INTERNAL_ERROR; } gdd_dio_data = &gdd_dio_data_base[inst]; if(gdd_dio_init_flag[inst] EQ FALSE) { TRACE_ERROR("[GDD] Instance not initialized"); return GDD_INVALID_PARAMS; } if (gdd_dio_data->ker.state NEQ GDD_DIO_KER_READY) { TRACE_ERROR("[GDD] DIO driver not initialized"); return GDD_INTERNAL_ERROR; } con_data = get_con_data(gdd_dio_data, con_handle); if(con_data EQ NULL) { TRACE_ERROR("[GDD] Invalid connection handle"); return GDD_INVALID_PARAMS; } if(data_size EQ 0 || data_size > con_data->dio_cap.mtu_data) { TRACE_ERROR("[GDD] requested data_size (MTU size) out of range"); return GDD_INVALID_PARAMS; } if( con_data->con_state EQ GDD_DIO_CON_CONNECT || con_data->con_state EQ GDD_DIO_CON_SENDING || gdd_dio_queue_peek_next_for_dequeue(&con_data->rx_queue, &dio_buf) EQ FALSE) { /* Set the flag indicating the somebody (the client) is waiting for a send buffer. As a consequence, the signal GDD_SIGTYPE_SEND_BUF_AVAILABLE will be sent as soon as we receive a new RX buffer from PSI. */ char * reason; if(con_data->con_state EQ GDD_DIO_CON_CONNECT) reason = "con_state=GDD_DIO_CON_CONNECT"; else if(con_data->con_state EQ GDD_DIO_CON_SENDING) reason = "con_state=GDD_DIO_CON_SENDING"; else reason = "no buffer available in RX queue"; con_data->wait_send_buf = TRUE; TRACE_EVENT_P2("[GDD] Cannot return buffer [con_handle=0x%4x: %s]", con_handle, reason); return GDD_NO_BUF_AVAILABLE; } else { /* Make sure that buffer can hold what is requested. We must take into account that the first 2-byte segment holding the protocol ID which is not part of the pay-load */ if(data_size > (dio_buf->length-2)) { TRACE_ERROR("[GDD] Requested buffer size too large"); return GDD_REQ_BUF_TOO_LARGE; } else { /* Setup current descriptor list and pass it back to the client */ (*send_buf) = (T_GDD_BUF *)dio_buf; con_data->con_state = GDD_DIO_CON_SENDING; return GDD_OK; } } } GLOBAL GDD_RESULT gdd_dio_dtx_send_buffer(T_GDD_CON_HANDLE con_handle, T_GDD_BUF * buf) { #ifdef GDD_MAKE_DTX_CONTEXT_SWITCH U32 signal = GDD_DIO_SIGNAL_SEND_DATA | (U32)con_handle; #endif /* GDD_MAKE_DTX_CONTEXT_SWITCH */ T_GDD_INST_ID inst; T_GDD_DIO_DATA * gdd_dio_data; T_GDD_DIO_CON_DATA * con_data; T_dio_buffer * dio_buf; TRACE_USER_CLASS(TC_FUNC_DATA_FLOW, "[GDD] gdd_dio_dtx_send_buffer()"); inst = (T_GDD_INST_ID)inst_num_from_dev_id(con_handle); /** * Do the necessary checks. */ if(inst < 0) { TRACE_ERROR("[GDD] Invalid connection handle"); return GDD_INVALID_PARAMS; } else if(inst >= GDD_NUM_INSTS) { TRACE_ERROR("[GDD] inst id out of bounds"); return GDD_INTERNAL_ERROR; } gdd_dio_data = &gdd_dio_data_base[inst]; if(gdd_dio_init_flag[inst] EQ FALSE) { TRACE_ERROR("[GDD] Instance not initialized"); return GDD_ALREADY_INITIALIZED; } if (gdd_dio_data->ker.state NEQ GDD_DIO_KER_READY) { TRACE_ERROR("[GDD] DIO driver not initialized"); return GDD_INTERNAL_ERROR; } con_data = get_con_data(gdd_dio_data, con_handle); if(con_data EQ NULL) { TRACE_ERROR("[GDD] Invalid connection handle"); return GDD_INVALID_PARAMS; } /* The pointer which is next for dequeue must be the one which corresponds to the buffer for sending ! */ if(gdd_dio_queue_peek_next_for_dequeue(&con_data->rx_queue, &dio_buf) EQ FALSE) { return GDD_INTERNAL_ERROR; } #ifdef GDD_MAKE_DTX_CONTEXT_SWITCH #ifdef MEMORY_SUPERVISION vsi_c_ssend(hCommGDD_DIO, signal, (T_VOID_STRUCT*)dio_buf, sizeof(T_VOID_STRUCT*), __FILE__, __LINE__); #else vsi_c_ssend(hCommGDD_DIO, signal, (T_VOID_STRUCT*)dio_buf, sizeof(T_VOID_STRUCT*)); #endif return GDD_OK; #else /* GDD_MAKE_DTX_CONTEXT_SWITCH */ /* Call the corresponding RX function directly instead of sending signal */ gdd_dio_rx_sig_send_data(con_handle, dio_buf); return GDD_OK; #endif /* GDD_MAKE_DTX_CONTEXT_SWITCH */ }