Loading CORE/VOSS/inc/vos_api.h +18 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ #include <vos_timer.h> #include <vos_pack_align.h> #include <asm/arch_timer.h> #include <wlan_qct_wdi_cts.h> /** * enum userspace_log_level - Log level at userspace Loading Loading @@ -592,4 +593,21 @@ void vos_get_recovery_reason(enum vos_hang_reason *reason); * Return: None */ void vos_reset_recovery_reason(void); /** * vos_smd_open - open smd channel * @szname: channel name * @wcts_cb: WCTS control block * * Return: VOS_STATUS */ VOS_STATUS vos_smd_open(const char *szname, WCTS_ControlBlockType* wcts_cb); /** * wcts_state_open - open WCTS state, equivalent to SMD_EVENT_OPEN event * wcts_cb: WCTS control block * * Return: None */ void wcts_state_open(WCTS_ControlBlockType* wcts_cb); #endif // if !defined __VOS_NVITEM_H CORE/VOSS/src/vos_api.c +59 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ #include "bap_hdd_main.h" #endif //WLAN_BTAMP_FEATURE #include "wlan_qct_wdi_cts.h" #include "wlan_qct_pal_sync.h" /*--------------------------------------------------------------------------- * Preprocessor Definitions and Constants Loading Loading @@ -3957,3 +3958,61 @@ v_BOOL_t vos_check_monitor_state(void) return wlan_hdd_check_monitor_state(hdd_ctx); } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) VOS_STATUS vos_smd_open(const char *szname, WCTS_ControlBlockType* wcts_cb) { wcts_cb->wctsChannel = wcnss_open_channel(szname, WCTS_smd_resp_process, wcts_cb); if (IS_ERR(wcts_cb->wctsChannel)) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: wcnss_open_channel failed", __func__); return VOS_STATUS_E_INVAL; } wcts_state_open(wcts_cb); return VOS_STATUS_SUCCESS; } #else VOS_STATUS vos_smd_open(const char *szname, WCTS_ControlBlockType* wcts_cb) { int status; wpt_status wpt_status; wpalEventReset(&wcts_cb->wctsEvent); status = smd_named_open_on_edge(szname, SMD_APPS_WCNSS, &wcts_cb->wctsChannel, wcts_cb, WCTS_NotifyCallback); if (status) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: smd_named_open_on_edge failed with status %d", __func__, status); return VOS_STATUS_E_FAILURE; } /* wait for the channel to be fully opened before we proceed */ wpt_status = wpalEventWait(&wcts_cb->wctsEvent, WCTS_SMD_OPEN_TIMEOUT); if (eWLAN_PAL_STATUS_SUCCESS != wpt_status) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: failed to receive SMD_EVENT_OPEN", __func__); /* since we opened one end of the channel, close it */ status = smd_close(wcts_cb->wctsChannel); if (status) VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: smd_close failed with status %d", __func__, status); return VOS_STATUS_E_FAILURE; } return VOS_STATUS_SUCCESS; } #endif CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h +82 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,18 @@ when who what, where, why * Include Files * -------------------------------------------------------------------------*/ #include "wlan_qct_pal_type.h" #include "wlan_qct_pal_msg.h" #include "wlan_qct_os_sync.h" #include "wlan_qct_os_list.h" #ifdef EXISTS_MSM_SMD #include <mach/msm_smd.h> #else #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)) #include <linux/rpmsg.h> #else #include <soc/qcom/smd.h> #endif #endif /*---------------------------------------------------------------------------- * Preprocessor Definitions and Constants Loading @@ -80,6 +92,9 @@ when who what, where, why extern "C" { #endif /* time to wait for SMD channel to open (in msecs) */ #define WCTS_SMD_OPEN_TIMEOUT 5000 /*---------------------------------------------------------------------------- * Type Declarations * -------------------------------------------------------------------------*/ Loading Loading @@ -173,6 +188,43 @@ typedef struct void* wctsRxMsgCBData; } WCTS_TransportCBsType; /*--------------------------------------------------------------------------- WCTS_StateType ---------------------------------------------------------------------------*/ typedef enum { WCTS_STATE_CLOSED, /* Closed */ WCTS_STATE_OPEN_PENDING, /* Waiting for the OPEN event from SMD */ WCTS_STATE_OPEN, /* Open event received from SMD */ WCTS_STATE_DEFERRED, /* Write pending, SMD chennel is full */ WCTS_STATE_REM_CLOSED, /* Remote end closed the SMD channel */ WCTS_STATE_MAX } WCTS_StateType; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)) #define wcts_channel struct rpmsg_endpoint #else #define wcts_channel smd_channel_t #endif /*--------------------------------------------------------------------------- Control Transport Control Block Type ---------------------------------------------------------------------------*/ typedef struct { WCTS_NotifyCBType wctsNotifyCB; void* wctsNotifyCBData; WCTS_RxMsgCBType wctsRxMsgCB; void* wctsRxMsgCBData; WCTS_StateType wctsState; vos_spin_lock_t wctsStateLock; wcts_channel *wctsChannel; wpt_list wctsPendingQueue; wpt_uint32 wctsMagic; wpt_msg wctsOpenMsg; wpt_msg wctsDataMsg; wpt_event wctsEvent; } WCTS_ControlBlockType; /*======================================================================== * Function Declarations and Documentation ==========================================================================*/ Loading Loading @@ -265,4 +317,34 @@ WCTS_ClearPendingQueue ); void WCTS_Dump_Smd_status(void); /** * Notification callback when SMD needs to communicate asynchronously with * the client. * * This callback function may be called from interrupt context; clients must * not block or call any functions that block. * * @param[in] data The user-supplied data provided to smd_named_open_on_edge() * @param[in] event The event that occurred * * @return void */ void WCTS_NotifyCallback( void *data, unsigned event); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)) /** * WCTS_smd_resp_process() - Response callback to process recieved data * * @rpdev: rpmsg device * @buf: received data * @len: received data length * @priv: The user-supplied data provided to wcnss_open_channel() * @addr: address * * @return status */ int WCTS_smd_resp_process(struct rpmsg_device *rpdev, void *buf, int len, void *priv, u32 addr); #endif #endif /* #ifndef WLAN_QCT_WDI_CTS_H */ CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c +112 −75 Original line number Diff line number Diff line Loading @@ -85,12 +85,19 @@ #ifdef EXISTS_MSM_SMD #include <mach/msm_smd.h> #else #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) #include <soc/qcom/smd.h> #endif #endif #include <linux/delay.h> #else #include "msm_smd.h" #endif #include "vos_api.h" #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) #include <linux/wcnss_wlan.h> #endif /* Global context for CTS handle, it is required to keep this * transport open during SSR shutdown */ Loading @@ -102,48 +109,19 @@ static WCTS_HandleType gwctsHandle; /* Magic value to validate a WCTS CB (value is little endian ASCII: WCTS */ #define WCTS_CB_MAGIC 0x53544357 /* time to wait for SMD channel to open (in msecs) */ #define WCTS_SMD_OPEN_TIMEOUT 5000 /* time to wait for SMD channel to close (in msecs) */ #define WCTS_SMD_CLOSE_TIMEOUT 5000 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) #define smd_disable_read_intr(a) #define smd_enable_read_intr(a) #endif /* Global Variable for WDI SMD stats */ static struct WdiSmdStats gWdiSmdStats; /*---------------------------------------------------------------------------- * Type Declarations * -------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------- WCTS_StateType ---------------------------------------------------------------------------*/ typedef enum { WCTS_STATE_CLOSED, /* Closed */ WCTS_STATE_OPEN_PENDING, /* Waiting for the OPEN event from SMD */ WCTS_STATE_OPEN, /* Open event received from SMD */ WCTS_STATE_DEFERRED, /* Write pending, SMD chennel is full */ WCTS_STATE_REM_CLOSED, /* Remote end closed the SMD channel */ WCTS_STATE_MAX } WCTS_StateType; /*--------------------------------------------------------------------------- Control Transport Control Block Type ---------------------------------------------------------------------------*/ typedef struct { WCTS_NotifyCBType wctsNotifyCB; void* wctsNotifyCBData; WCTS_RxMsgCBType wctsRxMsgCB; void* wctsRxMsgCBData; WCTS_StateType wctsState; vos_spin_lock_t wctsStateLock; smd_channel_t* wctsChannel; wpt_list wctsPendingQueue; wpt_uint32 wctsMagic; wpt_msg wctsOpenMsg; wpt_msg wctsDataMsg; wpt_event wctsEvent; } WCTS_ControlBlockType; /*--------------------------------------------------------------------------- WDI CTS Buffer Type Loading Loading @@ -243,8 +221,12 @@ WCTS_PALReadCallback { void* buffer; int packet_size; int available; int bytes_read; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) struct data_msg *msg; #else int available; #endif /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ Loading @@ -259,6 +241,22 @@ WCTS_PALReadCallback /* iterate until no more packets are available */ while (1) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) spin_lock_bh(&pWCTSCb->wctsDataMsg.data_queue_lock); if (list_empty(&pWCTSCb->wctsDataMsg.data_queue)) { spin_unlock_bh(&pWCTSCb->wctsDataMsg.data_queue_lock); return; } msg = list_first_entry(&pWCTSCb->wctsDataMsg.data_queue, struct data_msg, list); list_del(&msg->list); spin_unlock_bh(&pWCTSCb->wctsDataMsg.data_queue_lock); buffer = msg->buffer; packet_size = msg->buf_len; bytes_read = msg->buf_len; #else /* check the length of the next packet */ packet_size = smd_cur_packet_size(pWCTSCb->wctsChannel); if (0 == packet_size) { Loading Loading @@ -294,6 +292,7 @@ WCTS_PALReadCallback WPAL_ASSERT(0); return; } #endif /* forward the message to the registered handler */ pWCTSCb->wctsRxMsgCB((WCTS_HandleType)pWCTSCb, Loading Loading @@ -329,8 +328,10 @@ WCTS_PALWriteCallback WCTS_BufferType* pBufferQueue; void* pBuffer; int len; #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) int available; int written; #endif /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ Loading Loading @@ -359,16 +360,23 @@ WCTS_PALWriteCallback pBuffer = pBufferQueue->pBuffer; len = pBufferQueue->bufferSize; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) if (wcnss_smd_tx(pWCTSCb->wctsChannel, pBuffer, len)) WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "WCTS_PALWriteCallback: channel write failure"); #else available = smd_write_avail(pWCTSCb->wctsChannel); if (available < len) { /* channel has no room for the next packet so we are done */ return; } #endif /* there is room for the next message, so we can now remove it from the deferred message queue and send it */ wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode); #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) /* note that pNode will be the same as when we peeked, so there is no need to update pBuffer or len */ Loading @@ -385,6 +393,7 @@ WCTS_PALWriteCallback hopefully the client can recover from this since there is nothing else we can do here */ } #endif /* whether we had success or failure, reclaim all memory */ wpalMemoryZero(pBuffer, len); Loading Loading @@ -475,21 +484,54 @@ WCTS_ClearPendingQueue }/*WCTS_ClearPendingQueue*/ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) int WCTS_smd_resp_process(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 addr) { WCTS_ControlBlockType* wcts_cb = (WCTS_ControlBlockType*) priv; struct data_msg *msg; /** * Notification callback when SMD needs to communicate asynchronously with * the client. * * This callback function may be called from interrupt context; clients must * not block or call any functions that block. * * @param[in] data The user-supplied data provided to smd_named_open_on_edge() * @param[in] event The event that occurred * * @return void */ gWdiSmdStats.smd_event_data++; static void msg = wpalMemoryAllocate(sizeof(*msg)); if (!msg) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "WCTS_smd_resp_process: Memory allocation failed"); return 0; } msg->buf_len = len; msg->buffer = wpalMemoryAllocate(len); if (!msg->buffer) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "WCTS_smd_resp_process: Memory allocation failure"); WPAL_ASSERT(0); return 0; } vos_mem_copy(msg->buffer, data, msg->buf_len); spin_lock_bh(&wcts_cb->wctsDataMsg.data_queue_lock); list_add_tail(&msg->list, &wcts_cb->wctsDataMsg.data_queue); spin_unlock_bh(&wcts_cb->wctsDataMsg.data_queue_lock); wpalPostCtrlMsg(WDI_GET_PAL_CTX(), &wcts_cb->wctsDataMsg); return 0; } void wcts_state_open(WCTS_ControlBlockType* wcts_cb) { wpt_msg *palMsg; gWdiSmdStats.smd_event_open++; palMsg = &wcts_cb->wctsOpenMsg; /* serialize this event */ wpalPostCtrlMsg(WDI_GET_PAL_CTX(), palMsg); } #else void WCTS_NotifyCallback ( void *data, Loading Loading @@ -597,8 +639,7 @@ WCTS_NotifyCallback wpalPostCtrlMsg(WDI_GET_PAL_CTX(), palMsg); } /*WCTS_NotifyCallback*/ #endif /*---------------------------------------------------------------------------- * Externalized Function Definitions Loading Loading @@ -632,7 +673,6 @@ WCTS_OpenTransport ) { WCTS_ControlBlockType* pWCTSCb; wpt_status status; int smdstatus; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ Loading Loading @@ -714,17 +754,15 @@ WCTS_OpenTransport pWCTSCb->wctsDataMsg.callback = WCTS_PALDataCallback; pWCTSCb->wctsDataMsg.pContext = pWCTSCb; pWCTSCb->wctsDataMsg.type = WPAL_MC_MSG_SMD_NOTIF_DATA_SIG; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) INIT_LIST_HEAD(&pWCTSCb->wctsDataMsg.data_queue); spin_lock_init(&pWCTSCb->wctsDataMsg.data_queue_lock); #endif /*--------------------------------------------------------------------- Open the SMD channel ---------------------------------------------------------------------*/ wpalEventReset(&pWCTSCb->wctsEvent); smdstatus = smd_named_open_on_edge(szName, SMD_APPS_WCNSS, &pWCTSCb->wctsChannel, pWCTSCb, WCTS_NotifyCallback); smdstatus = vos_smd_open(szName, pWCTSCb); if (0 != smdstatus) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: smd_named_open_on_edge failed with status %d", Loading @@ -732,22 +770,6 @@ WCTS_OpenTransport goto fail; } /* wait for the channel to be fully opened before we proceed */ status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_OPEN_TIMEOUT); if (eWLAN_PAL_STATUS_SUCCESS != status) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: failed to receive SMD_EVENT_OPEN", __func__); /* since we opened one end of the channel, close it */ smdstatus = smd_close(pWCTSCb->wctsChannel); if (0 != smdstatus) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: smd_close failed with status %d", __func__, smdstatus); } goto fail; } /* we initially don't want read interrupts (we only want them if we get into deferred write mode) */ smd_disable_read_intr(pWCTSCb->wctsChannel); Loading Loading @@ -789,8 +811,10 @@ WCTS_CloseTransport wpt_list_node* pNode = NULL; WCTS_BufferType* pBufferQueue = NULL; void* pBuffer = NULL; #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) wpt_status status; int smdstatus; #endif /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ Loading @@ -812,6 +836,7 @@ WCTS_CloseTransport /* Reset the state */ pWCTSCb->wctsState = WCTS_STATE_CLOSED; #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) wpalEventReset(&pWCTSCb->wctsEvent); smdstatus = smd_close(pWCTSCb->wctsChannel); if (0 != smdstatus) { Loading Loading @@ -840,6 +865,9 @@ WCTS_CloseTransport that code will crash when the memory is unmapped */ msleep(50); } #else wcnss_close_channel(pWCTSCb->wctsChannel); #endif /* channel has (hopefully) been closed */ pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb, Loading Loading @@ -889,7 +917,9 @@ WCTS_SendMessage WCTS_BufferType* pBufferQueue; int len; int written = 0; #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) int available; #endif /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ Loading @@ -911,10 +941,17 @@ WCTS_SendMessage len = (int)uLen; if (WCTS_STATE_OPEN == pWCTSCb->wctsState) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) if (wcnss_smd_tx(pWCTSCb->wctsChannel, pMsg, len)) written = -1; else written = len; #else available = smd_write_avail(pWCTSCb->wctsChannel); if (available >= len) { written = smd_write(pWCTSCb->wctsChannel, pMsg, len); } #endif } else if (WCTS_STATE_DEFERRED == pWCTSCb->wctsState) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, "WCTS_SendMessage: FIFO space not available, the packets will be queued"); Loading CORE/WDI/WPAL/inc/wlan_qct_pal_msg.h +16 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,10 @@ #include "wlan_qct_pal_type.h" #include "wlan_qct_pal_status.h" #include <linux/version.h> #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) #include <linux/spinlock_types.h> #endif /* Random signature to detect SMD OPEN NOTIFY */ #define WPAL_MC_MSG_SMD_NOTIF_OPEN_SIG 0x09E2 Loading @@ -53,6 +57,14 @@ typedef struct swpt_msg wpt_msg; typedef void (*wpal_msg_callback)(wpt_msg *pMsg); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) struct data_msg { struct list_head list; void *buffer; int buf_len; }; #endif struct swpt_msg { wpt_uint16 type; Loading @@ -61,6 +73,10 @@ struct swpt_msg wpt_uint32 val; wpal_msg_callback callback; void *pContext; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) struct list_head data_queue; spinlock_t data_queue_lock; #endif }; Loading Loading
CORE/VOSS/inc/vos_api.h +18 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ #include <vos_timer.h> #include <vos_pack_align.h> #include <asm/arch_timer.h> #include <wlan_qct_wdi_cts.h> /** * enum userspace_log_level - Log level at userspace Loading Loading @@ -592,4 +593,21 @@ void vos_get_recovery_reason(enum vos_hang_reason *reason); * Return: None */ void vos_reset_recovery_reason(void); /** * vos_smd_open - open smd channel * @szname: channel name * @wcts_cb: WCTS control block * * Return: VOS_STATUS */ VOS_STATUS vos_smd_open(const char *szname, WCTS_ControlBlockType* wcts_cb); /** * wcts_state_open - open WCTS state, equivalent to SMD_EVENT_OPEN event * wcts_cb: WCTS control block * * Return: None */ void wcts_state_open(WCTS_ControlBlockType* wcts_cb); #endif // if !defined __VOS_NVITEM_H
CORE/VOSS/src/vos_api.c +59 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ #include "bap_hdd_main.h" #endif //WLAN_BTAMP_FEATURE #include "wlan_qct_wdi_cts.h" #include "wlan_qct_pal_sync.h" /*--------------------------------------------------------------------------- * Preprocessor Definitions and Constants Loading Loading @@ -3957,3 +3958,61 @@ v_BOOL_t vos_check_monitor_state(void) return wlan_hdd_check_monitor_state(hdd_ctx); } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) VOS_STATUS vos_smd_open(const char *szname, WCTS_ControlBlockType* wcts_cb) { wcts_cb->wctsChannel = wcnss_open_channel(szname, WCTS_smd_resp_process, wcts_cb); if (IS_ERR(wcts_cb->wctsChannel)) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: wcnss_open_channel failed", __func__); return VOS_STATUS_E_INVAL; } wcts_state_open(wcts_cb); return VOS_STATUS_SUCCESS; } #else VOS_STATUS vos_smd_open(const char *szname, WCTS_ControlBlockType* wcts_cb) { int status; wpt_status wpt_status; wpalEventReset(&wcts_cb->wctsEvent); status = smd_named_open_on_edge(szname, SMD_APPS_WCNSS, &wcts_cb->wctsChannel, wcts_cb, WCTS_NotifyCallback); if (status) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: smd_named_open_on_edge failed with status %d", __func__, status); return VOS_STATUS_E_FAILURE; } /* wait for the channel to be fully opened before we proceed */ wpt_status = wpalEventWait(&wcts_cb->wctsEvent, WCTS_SMD_OPEN_TIMEOUT); if (eWLAN_PAL_STATUS_SUCCESS != wpt_status) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: failed to receive SMD_EVENT_OPEN", __func__); /* since we opened one end of the channel, close it */ status = smd_close(wcts_cb->wctsChannel); if (status) VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: smd_close failed with status %d", __func__, status); return VOS_STATUS_E_FAILURE; } return VOS_STATUS_SUCCESS; } #endif
CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h +82 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,18 @@ when who what, where, why * Include Files * -------------------------------------------------------------------------*/ #include "wlan_qct_pal_type.h" #include "wlan_qct_pal_msg.h" #include "wlan_qct_os_sync.h" #include "wlan_qct_os_list.h" #ifdef EXISTS_MSM_SMD #include <mach/msm_smd.h> #else #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)) #include <linux/rpmsg.h> #else #include <soc/qcom/smd.h> #endif #endif /*---------------------------------------------------------------------------- * Preprocessor Definitions and Constants Loading @@ -80,6 +92,9 @@ when who what, where, why extern "C" { #endif /* time to wait for SMD channel to open (in msecs) */ #define WCTS_SMD_OPEN_TIMEOUT 5000 /*---------------------------------------------------------------------------- * Type Declarations * -------------------------------------------------------------------------*/ Loading Loading @@ -173,6 +188,43 @@ typedef struct void* wctsRxMsgCBData; } WCTS_TransportCBsType; /*--------------------------------------------------------------------------- WCTS_StateType ---------------------------------------------------------------------------*/ typedef enum { WCTS_STATE_CLOSED, /* Closed */ WCTS_STATE_OPEN_PENDING, /* Waiting for the OPEN event from SMD */ WCTS_STATE_OPEN, /* Open event received from SMD */ WCTS_STATE_DEFERRED, /* Write pending, SMD chennel is full */ WCTS_STATE_REM_CLOSED, /* Remote end closed the SMD channel */ WCTS_STATE_MAX } WCTS_StateType; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)) #define wcts_channel struct rpmsg_endpoint #else #define wcts_channel smd_channel_t #endif /*--------------------------------------------------------------------------- Control Transport Control Block Type ---------------------------------------------------------------------------*/ typedef struct { WCTS_NotifyCBType wctsNotifyCB; void* wctsNotifyCBData; WCTS_RxMsgCBType wctsRxMsgCB; void* wctsRxMsgCBData; WCTS_StateType wctsState; vos_spin_lock_t wctsStateLock; wcts_channel *wctsChannel; wpt_list wctsPendingQueue; wpt_uint32 wctsMagic; wpt_msg wctsOpenMsg; wpt_msg wctsDataMsg; wpt_event wctsEvent; } WCTS_ControlBlockType; /*======================================================================== * Function Declarations and Documentation ==========================================================================*/ Loading Loading @@ -265,4 +317,34 @@ WCTS_ClearPendingQueue ); void WCTS_Dump_Smd_status(void); /** * Notification callback when SMD needs to communicate asynchronously with * the client. * * This callback function may be called from interrupt context; clients must * not block or call any functions that block. * * @param[in] data The user-supplied data provided to smd_named_open_on_edge() * @param[in] event The event that occurred * * @return void */ void WCTS_NotifyCallback( void *data, unsigned event); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)) /** * WCTS_smd_resp_process() - Response callback to process recieved data * * @rpdev: rpmsg device * @buf: received data * @len: received data length * @priv: The user-supplied data provided to wcnss_open_channel() * @addr: address * * @return status */ int WCTS_smd_resp_process(struct rpmsg_device *rpdev, void *buf, int len, void *priv, u32 addr); #endif #endif /* #ifndef WLAN_QCT_WDI_CTS_H */
CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c +112 −75 Original line number Diff line number Diff line Loading @@ -85,12 +85,19 @@ #ifdef EXISTS_MSM_SMD #include <mach/msm_smd.h> #else #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) #include <soc/qcom/smd.h> #endif #endif #include <linux/delay.h> #else #include "msm_smd.h" #endif #include "vos_api.h" #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) #include <linux/wcnss_wlan.h> #endif /* Global context for CTS handle, it is required to keep this * transport open during SSR shutdown */ Loading @@ -102,48 +109,19 @@ static WCTS_HandleType gwctsHandle; /* Magic value to validate a WCTS CB (value is little endian ASCII: WCTS */ #define WCTS_CB_MAGIC 0x53544357 /* time to wait for SMD channel to open (in msecs) */ #define WCTS_SMD_OPEN_TIMEOUT 5000 /* time to wait for SMD channel to close (in msecs) */ #define WCTS_SMD_CLOSE_TIMEOUT 5000 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) #define smd_disable_read_intr(a) #define smd_enable_read_intr(a) #endif /* Global Variable for WDI SMD stats */ static struct WdiSmdStats gWdiSmdStats; /*---------------------------------------------------------------------------- * Type Declarations * -------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------- WCTS_StateType ---------------------------------------------------------------------------*/ typedef enum { WCTS_STATE_CLOSED, /* Closed */ WCTS_STATE_OPEN_PENDING, /* Waiting for the OPEN event from SMD */ WCTS_STATE_OPEN, /* Open event received from SMD */ WCTS_STATE_DEFERRED, /* Write pending, SMD chennel is full */ WCTS_STATE_REM_CLOSED, /* Remote end closed the SMD channel */ WCTS_STATE_MAX } WCTS_StateType; /*--------------------------------------------------------------------------- Control Transport Control Block Type ---------------------------------------------------------------------------*/ typedef struct { WCTS_NotifyCBType wctsNotifyCB; void* wctsNotifyCBData; WCTS_RxMsgCBType wctsRxMsgCB; void* wctsRxMsgCBData; WCTS_StateType wctsState; vos_spin_lock_t wctsStateLock; smd_channel_t* wctsChannel; wpt_list wctsPendingQueue; wpt_uint32 wctsMagic; wpt_msg wctsOpenMsg; wpt_msg wctsDataMsg; wpt_event wctsEvent; } WCTS_ControlBlockType; /*--------------------------------------------------------------------------- WDI CTS Buffer Type Loading Loading @@ -243,8 +221,12 @@ WCTS_PALReadCallback { void* buffer; int packet_size; int available; int bytes_read; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) struct data_msg *msg; #else int available; #endif /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ Loading @@ -259,6 +241,22 @@ WCTS_PALReadCallback /* iterate until no more packets are available */ while (1) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) spin_lock_bh(&pWCTSCb->wctsDataMsg.data_queue_lock); if (list_empty(&pWCTSCb->wctsDataMsg.data_queue)) { spin_unlock_bh(&pWCTSCb->wctsDataMsg.data_queue_lock); return; } msg = list_first_entry(&pWCTSCb->wctsDataMsg.data_queue, struct data_msg, list); list_del(&msg->list); spin_unlock_bh(&pWCTSCb->wctsDataMsg.data_queue_lock); buffer = msg->buffer; packet_size = msg->buf_len; bytes_read = msg->buf_len; #else /* check the length of the next packet */ packet_size = smd_cur_packet_size(pWCTSCb->wctsChannel); if (0 == packet_size) { Loading Loading @@ -294,6 +292,7 @@ WCTS_PALReadCallback WPAL_ASSERT(0); return; } #endif /* forward the message to the registered handler */ pWCTSCb->wctsRxMsgCB((WCTS_HandleType)pWCTSCb, Loading Loading @@ -329,8 +328,10 @@ WCTS_PALWriteCallback WCTS_BufferType* pBufferQueue; void* pBuffer; int len; #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) int available; int written; #endif /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ Loading Loading @@ -359,16 +360,23 @@ WCTS_PALWriteCallback pBuffer = pBufferQueue->pBuffer; len = pBufferQueue->bufferSize; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) if (wcnss_smd_tx(pWCTSCb->wctsChannel, pBuffer, len)) WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "WCTS_PALWriteCallback: channel write failure"); #else available = smd_write_avail(pWCTSCb->wctsChannel); if (available < len) { /* channel has no room for the next packet so we are done */ return; } #endif /* there is room for the next message, so we can now remove it from the deferred message queue and send it */ wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode); #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) /* note that pNode will be the same as when we peeked, so there is no need to update pBuffer or len */ Loading @@ -385,6 +393,7 @@ WCTS_PALWriteCallback hopefully the client can recover from this since there is nothing else we can do here */ } #endif /* whether we had success or failure, reclaim all memory */ wpalMemoryZero(pBuffer, len); Loading Loading @@ -475,21 +484,54 @@ WCTS_ClearPendingQueue }/*WCTS_ClearPendingQueue*/ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) int WCTS_smd_resp_process(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 addr) { WCTS_ControlBlockType* wcts_cb = (WCTS_ControlBlockType*) priv; struct data_msg *msg; /** * Notification callback when SMD needs to communicate asynchronously with * the client. * * This callback function may be called from interrupt context; clients must * not block or call any functions that block. * * @param[in] data The user-supplied data provided to smd_named_open_on_edge() * @param[in] event The event that occurred * * @return void */ gWdiSmdStats.smd_event_data++; static void msg = wpalMemoryAllocate(sizeof(*msg)); if (!msg) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "WCTS_smd_resp_process: Memory allocation failed"); return 0; } msg->buf_len = len; msg->buffer = wpalMemoryAllocate(len); if (!msg->buffer) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "WCTS_smd_resp_process: Memory allocation failure"); WPAL_ASSERT(0); return 0; } vos_mem_copy(msg->buffer, data, msg->buf_len); spin_lock_bh(&wcts_cb->wctsDataMsg.data_queue_lock); list_add_tail(&msg->list, &wcts_cb->wctsDataMsg.data_queue); spin_unlock_bh(&wcts_cb->wctsDataMsg.data_queue_lock); wpalPostCtrlMsg(WDI_GET_PAL_CTX(), &wcts_cb->wctsDataMsg); return 0; } void wcts_state_open(WCTS_ControlBlockType* wcts_cb) { wpt_msg *palMsg; gWdiSmdStats.smd_event_open++; palMsg = &wcts_cb->wctsOpenMsg; /* serialize this event */ wpalPostCtrlMsg(WDI_GET_PAL_CTX(), palMsg); } #else void WCTS_NotifyCallback ( void *data, Loading Loading @@ -597,8 +639,7 @@ WCTS_NotifyCallback wpalPostCtrlMsg(WDI_GET_PAL_CTX(), palMsg); } /*WCTS_NotifyCallback*/ #endif /*---------------------------------------------------------------------------- * Externalized Function Definitions Loading Loading @@ -632,7 +673,6 @@ WCTS_OpenTransport ) { WCTS_ControlBlockType* pWCTSCb; wpt_status status; int smdstatus; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ Loading Loading @@ -714,17 +754,15 @@ WCTS_OpenTransport pWCTSCb->wctsDataMsg.callback = WCTS_PALDataCallback; pWCTSCb->wctsDataMsg.pContext = pWCTSCb; pWCTSCb->wctsDataMsg.type = WPAL_MC_MSG_SMD_NOTIF_DATA_SIG; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) INIT_LIST_HEAD(&pWCTSCb->wctsDataMsg.data_queue); spin_lock_init(&pWCTSCb->wctsDataMsg.data_queue_lock); #endif /*--------------------------------------------------------------------- Open the SMD channel ---------------------------------------------------------------------*/ wpalEventReset(&pWCTSCb->wctsEvent); smdstatus = smd_named_open_on_edge(szName, SMD_APPS_WCNSS, &pWCTSCb->wctsChannel, pWCTSCb, WCTS_NotifyCallback); smdstatus = vos_smd_open(szName, pWCTSCb); if (0 != smdstatus) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: smd_named_open_on_edge failed with status %d", Loading @@ -732,22 +770,6 @@ WCTS_OpenTransport goto fail; } /* wait for the channel to be fully opened before we proceed */ status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_OPEN_TIMEOUT); if (eWLAN_PAL_STATUS_SUCCESS != status) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: failed to receive SMD_EVENT_OPEN", __func__); /* since we opened one end of the channel, close it */ smdstatus = smd_close(pWCTSCb->wctsChannel); if (0 != smdstatus) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s: smd_close failed with status %d", __func__, smdstatus); } goto fail; } /* we initially don't want read interrupts (we only want them if we get into deferred write mode) */ smd_disable_read_intr(pWCTSCb->wctsChannel); Loading Loading @@ -789,8 +811,10 @@ WCTS_CloseTransport wpt_list_node* pNode = NULL; WCTS_BufferType* pBufferQueue = NULL; void* pBuffer = NULL; #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) wpt_status status; int smdstatus; #endif /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ Loading @@ -812,6 +836,7 @@ WCTS_CloseTransport /* Reset the state */ pWCTSCb->wctsState = WCTS_STATE_CLOSED; #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) wpalEventReset(&pWCTSCb->wctsEvent); smdstatus = smd_close(pWCTSCb->wctsChannel); if (0 != smdstatus) { Loading Loading @@ -840,6 +865,9 @@ WCTS_CloseTransport that code will crash when the memory is unmapped */ msleep(50); } #else wcnss_close_channel(pWCTSCb->wctsChannel); #endif /* channel has (hopefully) been closed */ pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb, Loading Loading @@ -889,7 +917,9 @@ WCTS_SendMessage WCTS_BufferType* pBufferQueue; int len; int written = 0; #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)) int available; #endif /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ Loading @@ -911,10 +941,17 @@ WCTS_SendMessage len = (int)uLen; if (WCTS_STATE_OPEN == pWCTSCb->wctsState) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) if (wcnss_smd_tx(pWCTSCb->wctsChannel, pMsg, len)) written = -1; else written = len; #else available = smd_write_avail(pWCTSCb->wctsChannel); if (available >= len) { written = smd_write(pWCTSCb->wctsChannel, pMsg, len); } #endif } else if (WCTS_STATE_DEFERRED == pWCTSCb->wctsState) { WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, "WCTS_SendMessage: FIFO space not available, the packets will be queued"); Loading
CORE/WDI/WPAL/inc/wlan_qct_pal_msg.h +16 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,10 @@ #include "wlan_qct_pal_type.h" #include "wlan_qct_pal_status.h" #include <linux/version.h> #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) #include <linux/spinlock_types.h> #endif /* Random signature to detect SMD OPEN NOTIFY */ #define WPAL_MC_MSG_SMD_NOTIF_OPEN_SIG 0x09E2 Loading @@ -53,6 +57,14 @@ typedef struct swpt_msg wpt_msg; typedef void (*wpal_msg_callback)(wpt_msg *pMsg); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) struct data_msg { struct list_head list; void *buffer; int buf_len; }; #endif struct swpt_msg { wpt_uint16 type; Loading @@ -61,6 +73,10 @@ struct swpt_msg wpt_uint32 val; wpal_msg_callback callback; void *pContext; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) struct list_head data_queue; spinlock_t data_queue_lock; #endif }; Loading