Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f534849d authored by CNSS_WLAN Service's avatar CNSS_WLAN Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "wlan: Migrate to rpmsg for 4.14 kernel" into wlan-driver.lnx.1.0

parents 530b83df 902717dd
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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
@@ -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
+59 −0
Original line number Diff line number Diff line
@@ -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
@@ -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
+82 −0
Original line number Diff line number Diff line
@@ -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
@@ -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
 * -------------------------------------------------------------------------*/
@@ -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
 ==========================================================================*/
@@ -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 */
+112 −75
Original line number Diff line number Diff line
@@ -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 */
@@ -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
@@ -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

   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

@@ -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) {
@@ -294,6 +292,7 @@ WCTS_PALReadCallback
         WPAL_ASSERT(0);
         return;
      }
#endif

      /* forward the message to the registered handler */
      pWCTSCb->wctsRxMsgCB((WCTS_HandleType)pWCTSCb,
@@ -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

   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

@@ -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 */

@@ -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);
@@ -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,
@@ -597,8 +639,7 @@ WCTS_NotifyCallback
   wpalPostCtrlMsg(WDI_GET_PAL_CTX(), palMsg);

} /*WCTS_NotifyCallback*/


#endif

/*----------------------------------------------------------------------------
 * Externalized Function Definitions
@@ -632,7 +673,6 @@ WCTS_OpenTransport
)
{
   WCTS_ControlBlockType*    pWCTSCb;
   wpt_status                status;
   int                       smdstatus;

   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
@@ -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",
@@ -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);
@@ -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

   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

@@ -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) {
@@ -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,
@@ -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

   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

@@ -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");
+16 −0
Original line number Diff line number Diff line
@@ -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
@@ -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;
@@ -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