blob: 3e6fef0eb2b47c3756709c51cd6b012abc90cd02 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +05302 * Copyright (c) 2012-2015,2017 The Linux Foundation. All rights reserved.
Kiet Lam1ed83fc2014-02-19 01:15:45 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Jeff Johnson295189b2012-06-20 16:38:30 -070026 */
27
28/*===========================================================================
29
30 W L A N _ Q C T _ C T S . C
31
32 OVERVIEW:
33
34 This software unit holds the implementation of the WLAN Control Transport
35 Service Layer.
36
37 The functions externalized by this module are to be called by the DAL Core
38 that wishes to use a platform agnostic API to communicate with the WLAN SS.
39
40 DEPENDENCIES:
41
42 Are listed for each API below.
43
44
Jeff Johnson295189b2012-06-20 16:38:30 -070045===========================================================================*/
46
47/*===========================================================================
48
49 EDIT HISTORY FOR FILE
50
51
52 This section contains comments describing changes made to the module.
53 Notice that changes are listed in reverse chronological order.
54
55
56 $Header$$DateTime$$Author$
57
58
59 when who what, where, why
60 ---------- --- --------------------------------------------------------
61 2011-02-28 jtj Linux/Android implementation which utilizes SMD
62 2010-08-09 mss Created module
63
64===========================================================================*/
65
66
67
68/*===========================================================================
69
70 INCLUDE FILES FOR MODULE
71
72===========================================================================*/
73
74/*----------------------------------------------------------------------------
75 * Include Files
76 * -------------------------------------------------------------------------*/
77#include "wlan_qct_wdi_cts.h"
78#include "wlan_qct_pal_msg.h"
79#include "wlan_qct_pal_api.h"
80#include "wlan_qct_pal_trace.h"
81#include "wlan_qct_os_list.h"
82#include "wlan_qct_wdi.h"
83#include "wlan_qct_wdi_i.h"
84#ifdef CONFIG_ANDROID
Jeff Johnsonda0c2212014-01-03 12:06:27 -080085#ifdef EXISTS_MSM_SMD
Jeff Johnson295189b2012-06-20 16:38:30 -070086#include <mach/msm_smd.h>
Jeff Johnsonda0c2212014-01-03 12:06:27 -080087#else
Dundi Raviteja902717d2020-05-21 17:24:54 +053088#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
Jeff Johnsonda0c2212014-01-03 12:06:27 -080089#include <soc/qcom/smd.h>
90#endif
Dundi Raviteja902717d2020-05-21 17:24:54 +053091#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070092#include <linux/delay.h>
93#else
94#include "msm_smd.h"
95#endif
Dundi Raviteja902717d2020-05-21 17:24:54 +053096#include "vos_api.h"
97
98#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
99#include <linux/wcnss_wlan.h>
100#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102/* Global context for CTS handle, it is required to keep this
103 * transport open during SSR shutdown */
104static WCTS_HandleType gwctsHandle;
105/*----------------------------------------------------------------------------
106 * Preprocessor Definitions and Constants
107 * -------------------------------------------------------------------------*/
108
109/* Magic value to validate a WCTS CB (value is little endian ASCII: WCTS */
110#define WCTS_CB_MAGIC 0x53544357
111
Jeff Johnson295189b2012-06-20 16:38:30 -0700112/* time to wait for SMD channel to close (in msecs) */
113#define WCTS_SMD_CLOSE_TIMEOUT 5000
114
Dundi Raviteja902717d2020-05-21 17:24:54 +0530115#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
116#define smd_disable_read_intr(a)
117#define smd_enable_read_intr(a)
118#endif
119
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +0530120/* Global Variable for WDI SMD stats */
121static struct WdiSmdStats gWdiSmdStats;
Jeff Johnson295189b2012-06-20 16:38:30 -0700122/*----------------------------------------------------------------------------
123 * Type Declarations
124 * -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700125
126/*---------------------------------------------------------------------------
127 WDI CTS Buffer Type
128 ---------------------------------------------------------------------------*/
129typedef struct
130{
131 /*Node for linking pending buffers into a linked list */
132 wpt_list_node node;
133
134 /*Buffer associated with the request */
135 void* pBuffer;
136
137 /*Buffer Size*/
138 int bufferSize;
139
140} WCTS_BufferType;
141
142/*----------------------------------------------------------------------------
143 * Global Data Definitions
144 * -------------------------------------------------------------------------*/
145
146/*----------------------------------------------------------------------------
147 * Static Variable Definitions
148 * -------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700149
Jeff Johnson295189b2012-06-20 16:38:30 -0700150/*----------------------------------------------------------------------------
151 * Static Function Declarations and Definitions
152 * -------------------------------------------------------------------------*/
153
154
155
156/**
157 @brief Callback function for serializing WCTS Open
158 processing in the control context
159 @param
160
161 pMsg - pointer to the message
162
163 @see
164 @return void
165*/
166static void
167WCTS_PALOpenCallback
168(
169 wpt_msg *pMsg
170)
171{
172 WCTS_ControlBlockType* pWCTSCb;
173 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
174
175 /* extract our context from the message */
176 pWCTSCb = pMsg->pContext;
177
178 /*--------------------------------------------------------------------
179 Sanity check
180 --------------------------------------------------------------------*/
181 if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) {
182 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
183 "WCTS_PALOpenCallback: Invalid parameters received.");
184 return;
185 }
186
187 if (WCTS_STATE_OPEN_PENDING != pWCTSCb->wctsState) {
188 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
189 "WCTS_PALOpenCallback: Invoke from invalid state %d.",
190 pWCTSCb->wctsState);
191 return;
192 }
193
194 /* notified registered client that the channel is open */
195 pWCTSCb->wctsState = WCTS_STATE_OPEN;
196 pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
197 WCTS_EVENT_OPEN,
198 pWCTSCb->wctsNotifyCBData);
199
200 /* signal event for WCTS_OpenTransport to proceed */
201 wpalEventSet(&pWCTSCb->wctsEvent);
202
203}/*WCTS_PALOpenCallback*/
204
205
206
207/**
208 @brief Callback function for serializing WCTS Read
209 processing in the control context
210
211 @param pWCTSCb WCTS Control Block
212
213 @see
214 @return void
215*/
216static void
217WCTS_PALReadCallback
218(
219 WCTS_ControlBlockType* pWCTSCb
220)
221{
222 void* buffer;
223 int packet_size;
Jeff Johnson295189b2012-06-20 16:38:30 -0700224 int bytes_read;
Dundi Raviteja902717d2020-05-21 17:24:54 +0530225#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
226 struct data_msg *msg;
227#else
228 int available;
229#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700230
231 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
232
233 /*--------------------------------------------------------------------
234 Sanity check
235 --------------------------------------------------------------------*/
236 if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) {
237 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
238 "WCTS_PALReadCallback: Invalid parameter received.");
239 return;
240 }
241
242 /* iterate until no more packets are available */
243 while (1) {
Dundi Raviteja902717d2020-05-21 17:24:54 +0530244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
Dundi Raviteja47487352020-09-04 17:29:30 +0530245 unsigned long flags;
246
247 spin_lock_irqsave(&pWCTSCb->wctsDataMsg.data_queue_lock, flags);
Dundi Raviteja902717d2020-05-21 17:24:54 +0530248 if (list_empty(&pWCTSCb->wctsDataMsg.data_queue)) {
Dundi Raviteja47487352020-09-04 17:29:30 +0530249 spin_unlock_irqrestore(&pWCTSCb->wctsDataMsg.data_queue_lock,
250 flags);
Dundi Raviteja902717d2020-05-21 17:24:54 +0530251 return;
252 }
253
254 msg = list_first_entry(&pWCTSCb->wctsDataMsg.data_queue,
255 struct data_msg, list);
Dundi Raviteja47487352020-09-04 17:29:30 +0530256 spin_unlock_irqrestore(&pWCTSCb->wctsDataMsg.data_queue_lock, flags);
Dundi Raviteja902717d2020-05-21 17:24:54 +0530257 list_del(&msg->list);
Dundi Raviteja902717d2020-05-21 17:24:54 +0530258
259 buffer = msg->buffer;
260 packet_size = msg->buf_len;
261 bytes_read = msg->buf_len;
Dundi Raviteja47f5ae72020-07-13 10:14:37 +0530262 wpalMemoryFree(msg);
Dundi Raviteja902717d2020-05-21 17:24:54 +0530263#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700264 /* check the length of the next packet */
265 packet_size = smd_cur_packet_size(pWCTSCb->wctsChannel);
266 if (0 == packet_size) {
267 /* No more data to be read */
268 return;
269 }
270
271 /* Check how much of the data is available */
272 available = smd_read_avail(pWCTSCb->wctsChannel);
273 if (available < packet_size) {
274 /* Entire packet not yet ready to be read --
275 There will be another notification when it is ready */
276 return;
277 }
278
279 buffer = wpalMemoryAllocate(packet_size);
280 if (NULL == buffer) {
281 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
282 "WCTS_PALReadCallback: Memory allocation failure");
283 WPAL_ASSERT(0);
284 return;
285 }
286
287 bytes_read = smd_read(pWCTSCb->wctsChannel,
288 buffer,
289 packet_size);
290
291 if (bytes_read != packet_size) {
292 /*Some problem, do not forward it to WDI.*/
293 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
294 "WCTS_PALReadCallback: Failed to read data from SMD");
295 wpalMemoryFree(buffer);
296 WPAL_ASSERT(0);
297 return;
298 }
Dundi Raviteja902717d2020-05-21 17:24:54 +0530299#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700300
301 /* forward the message to the registered handler */
302 pWCTSCb->wctsRxMsgCB((WCTS_HandleType)pWCTSCb,
303 buffer,
304 packet_size,
305 pWCTSCb->wctsRxMsgCBData);
306
307 /* Free the allocated buffer*/
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +0530308 wpalMemoryZero(buffer, bytes_read);
Jeff Johnson295189b2012-06-20 16:38:30 -0700309 wpalMemoryFree(buffer);
310 }
311
312} /*WCTS_PALReadCallback*/
313
314
315
316/**
317 @brief Callback function for serializing WCTS Write
318 processing in the control context
319
320 @param pWCTSCb WCTS Control Block
321
322 @see
323 @return void
324*/
325static void
326WCTS_PALWriteCallback
327(
328 WCTS_ControlBlockType* pWCTSCb
329)
330{
331 wpt_list_node* pNode;
332 WCTS_BufferType* pBufferQueue;
333 void* pBuffer;
334 int len;
Dundi Raviteja902717d2020-05-21 17:24:54 +0530335#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700336 int available;
337 int written;
Dundi Raviteja902717d2020-05-21 17:24:54 +0530338#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700339
340 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
341
342 /*--------------------------------------------------------------------
343 Sanity check
344 --------------------------------------------------------------------*/
345 if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) {
346 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
347 "WCTS_PALWriteCallback: Invalid parameter received.");
348 return;
349 }
350
351 /* if we are not deferred, then there are no pending packets */
352 if (WCTS_STATE_DEFERRED != pWCTSCb->wctsState) {
353 return;
354 }
355
356 /* Keep sending deferred messages as long as there is room in
357 the channel. Note that we initially peek at the head of the
358 list to access the parameters for the next message; we don't
359 actually remove the next message from the deferred list until
360 we know the channel can handle it */
361 while (eWLAN_PAL_STATUS_SUCCESS ==
362 wpal_list_peek_front(&pWCTSCb->wctsPendingQueue, &pNode)) {
363 pBufferQueue = container_of(pNode, WCTS_BufferType, node);
364 pBuffer = pBufferQueue->pBuffer;
365 len = pBufferQueue->bufferSize;
366
Dundi Raviteja902717d2020-05-21 17:24:54 +0530367#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
368 if (wcnss_smd_tx(pWCTSCb->wctsChannel, pBuffer, len))
369 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
370 "WCTS_PALWriteCallback: channel write failure");
371#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700372 available = smd_write_avail(pWCTSCb->wctsChannel);
373 if (available < len) {
374 /* channel has no room for the next packet so we are done */
375 return;
376 }
Dundi Raviteja902717d2020-05-21 17:24:54 +0530377#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700378
379 /* there is room for the next message, so we can now remove
380 it from the deferred message queue and send it */
381 wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode);
382
Dundi Raviteja902717d2020-05-21 17:24:54 +0530383#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700384 /* note that pNode will be the same as when we peeked, so
385 there is no need to update pBuffer or len */
386
387 written = smd_write(pWCTSCb->wctsChannel, pBuffer, len);
388 if (written != len) {
389 /* Something went wrong */
390 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
391 "WCTS_PALWriteCallback: channel write failure");
392
393 /* we were unable to send the message that was at the head
394 of the deferred list. there is nothing else we can do
395 other than drop it, so we will just fall through to the
396 "success" processing.
397 hopefully the client can recover from this since there is
398 nothing else we can do here */
399 }
Dundi Raviteja902717d2020-05-21 17:24:54 +0530400#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700401
402 /* whether we had success or failure, reclaim all memory */
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +0530403 wpalMemoryZero(pBuffer, len);
Jeff Johnson295189b2012-06-20 16:38:30 -0700404 wpalMemoryFree(pBuffer);
405 wpalMemoryFree(pBufferQueue);
406
407 /* we'll continue to iterate until the channel is full or all
408 of the deferred messages have been sent */
409 }
410
411 /* if we've exited the loop, then we have drained the deferred queue.
412 set the state to indicate we are no longer deferred, and turn off
413 the remote read interrupt */
414 pWCTSCb->wctsState = WCTS_STATE_OPEN;
415 smd_disable_read_intr(pWCTSCb->wctsChannel);
416
417} /*WCTS_PALWriteCallback*/
418
419
420
421/**
422 @brief Callback function for serializing SMD DATA Event
423 processing in the control context
424 @param
425
426 pMsg - pointer to the message
427
428 @see
429 @return void
430*/
431static void
432WCTS_PALDataCallback
433(
434 wpt_msg *pMsg
435)
436{
437 WCTS_ControlBlockType* pWCTSCb;
438 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
439
440 /* extract our context from the message */
441 pWCTSCb = pMsg->pContext;
442
443 /* process any incoming messages */
444 WCTS_PALReadCallback(pWCTSCb);
445
446 /* send any deferred messages */
447 WCTS_PALWriteCallback(pWCTSCb);
448
449} /*WCTS_PALDataCallback*/
450
451/**
452 @brief This helper function is used to clean up the pending
453 messages in the transport queue
454
455 @param wctsHandlehandle: transport handle
456
457 @see
458 @return 0 for success
459*/
Madan Mohan Koyyalamudifab2a7e2012-09-28 15:20:00 -0700460wpt_uint32
Jeff Johnson295189b2012-06-20 16:38:30 -0700461WCTS_ClearPendingQueue
462(
463 WCTS_HandleType wctsHandle
464)
465{
466 WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) wctsHandle;
467 wpt_list_node* pNode = NULL;
468 WCTS_BufferType* pBufferQueue = NULL;
469 void* pBuffer = NULL;
470
471 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
472
473 if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) {
474 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
475 "WCTS_ClearPendingQueue: Invalid parameters received.");
476 return eWLAN_PAL_STATUS_E_INVAL;
477 }
478
479 /*Free the buffers in the pending queue.*/
480 while (eWLAN_PAL_STATUS_SUCCESS ==
481 wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode)) {
482 pBufferQueue = container_of(pNode, WCTS_BufferType, node);
483 pBuffer = pBufferQueue->pBuffer;
484 wpalMemoryFree(pBuffer);
485 wpalMemoryFree(pBufferQueue);
486 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700487 return eWLAN_PAL_STATUS_SUCCESS;
488
489}/*WCTS_ClearPendingQueue*/
490
Dundi Raviteja902717d2020-05-21 17:24:54 +0530491#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
492int WCTS_smd_resp_process(struct rpmsg_device *rpdev,
493 void *data, int len, void *priv, u32 addr)
494{
495 WCTS_ControlBlockType* wcts_cb = (WCTS_ControlBlockType*) priv;
496 struct data_msg *msg;
Jeff Johnson295189b2012-06-20 16:38:30 -0700497
Dundi Ravitejab1ed6442020-07-29 10:31:54 +0530498 if (WCTS_STATE_REM_CLOSED == wcts_cb->wctsState) {
499 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
500 "%s: received SMD data when wcts state is closed ",
501 __func__);
502 /* we should not be getting any data now */
503 return 0;
504 }
505
Dundi Raviteja902717d2020-05-21 17:24:54 +0530506 gWdiSmdStats.smd_event_data++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700507
Dundi Raviteja902717d2020-05-21 17:24:54 +0530508 msg = wpalMemoryAllocate(sizeof(*msg));
509 if (!msg) {
510 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
511 "WCTS_smd_resp_process: Memory allocation failed");
512 return 0;
513 }
514
515 msg->buf_len = len;
516 msg->buffer = wpalMemoryAllocate(len);
517 if (!msg->buffer) {
518 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
519 "WCTS_smd_resp_process: Memory allocation failure");
520 WPAL_ASSERT(0);
521 return 0;
522 }
523
524 vos_mem_copy(msg->buffer, data, msg->buf_len);
525
Dundi Raviteja03d25382020-07-15 14:18:57 +0530526 spin_lock(&wcts_cb->wctsDataMsg.data_queue_lock);
Dundi Raviteja902717d2020-05-21 17:24:54 +0530527 list_add_tail(&msg->list, &wcts_cb->wctsDataMsg.data_queue);
Dundi Raviteja03d25382020-07-15 14:18:57 +0530528 spin_unlock(&wcts_cb->wctsDataMsg.data_queue_lock);
Dundi Raviteja902717d2020-05-21 17:24:54 +0530529
530 wpalPostCtrlMsg(WDI_GET_PAL_CTX(), &wcts_cb->wctsDataMsg);
531
532 return 0;
533}
534
Surabhi Vishnoi5d7bb7b2020-06-29 11:17:05 +0530535int WCTS_driver_state_process(void *priv, enum wcnss_driver_state state)
536{
537 WCTS_ControlBlockType* wcts_cb = (WCTS_ControlBlockType*) priv;
538 wpt_msg *pal_msg;
539
540 switch (state) {
541 case WCNSS_SMD_OPEN:
542 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
543 "%s: received WCNSS_SMD_OPEN from SMD", __func__);
544 /* If the prev state was 'remote closed' then it is a Riva 'restart',
545 * subsystem restart re-init
546 */
547 if (WCTS_STATE_REM_CLOSED == wcts_cb->wctsState) {
548 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
549 "%s: received WCNSS_SMD_OPEN in WCTS_STATE_REM_CLOSED state",
550 __func__);
551 /* call subsystem restart re-init function */
552 wpalDriverReInit();
553 return 0;
554 }
555 gWdiSmdStats.smd_event_open++;
556 pal_msg = &wcts_cb->wctsOpenMsg;
557 break;
558 case WCNSS_SMD_CLOSE:
559 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
560 "%s: received WCNSS_SMD_CLOSE from SMD", __func__);
561 /* SMD channel was closed from the remote side,
562 * this would happen only when Riva crashed and SMD is
563 * closing the channel on behalf of Riva */
564 vos_spin_lock_acquire(&wcts_cb->wctsStateLock);
565 wcts_cb->wctsState = WCTS_STATE_REM_CLOSED;
566 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
567 "%s: received WCNSS_SMD_CLOSE WLAN driver going down now",
568 __func__);
569 vos_spin_lock_release(&wcts_cb->wctsStateLock);
570
571 /* subsystem restart: shutdown */
572 wpalDriverShutdown();
573 gWdiSmdStats.smd_event_close++;
574 return 0;
575 }
576
577 /* serialize this event */
578 wpalPostCtrlMsg(WDI_GET_PAL_CTX(), pal_msg);
579 return 0;
580}
Dundi Raviteja902717d2020-05-21 17:24:54 +0530581#else
582void
Jeff Johnson295189b2012-06-20 16:38:30 -0700583WCTS_NotifyCallback
584(
585 void *data,
586 unsigned event
587)
588{
589 wpt_msg *palMsg;
590 WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) data;
591
592 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
593
594 /*--------------------------------------------------------------------
595 Sanity check
596 --------------------------------------------------------------------*/
597 if (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) {
598 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
599 "%s: Received unexpected SMD event %u",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700600 __func__, event);
Jeff Johnson295189b2012-06-20 16:38:30 -0700601
602 /* TODO_PRIMA what error recovery options do we have? */
603 return;
604 }
605
606 /* Serialize processing in the control thread */
607 switch (event) {
608 case SMD_EVENT_OPEN:
609 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700610 "%s: received SMD_EVENT_OPEN from SMD", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700611 /* If the prev state was 'remote closed' then it is a Riva 'restart',
612 * subsystem restart re-init
613 */
614 if (WCTS_STATE_REM_CLOSED == pWCTSCb->wctsState)
615 {
616 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
617 "%s: received SMD_EVENT_OPEN in WCTS_STATE_REM_CLOSED state",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700618 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700619 /* call subsystem restart re-init function */
620 wpalDriverReInit();
621 return;
622 }
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +0530623 gWdiSmdStats.smd_event_open++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700624 palMsg = &pWCTSCb->wctsOpenMsg;
625 break;
626
627 case SMD_EVENT_DATA:
628 if (WCTS_STATE_REM_CLOSED == pWCTSCb->wctsState)
629 {
630 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
631 "%s: received SMD data when the state is remote closed ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700632 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700633 /* we should not be getting any data now */
634 return;
635 }
636 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700637 "%s: received SMD_EVENT_DATA from SMD", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700638 palMsg = &pWCTSCb->wctsDataMsg;
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +0530639 gWdiSmdStats.smd_event_data++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700640 break;
641
642 case SMD_EVENT_CLOSE:
643 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700644 "%s: received SMD_EVENT_CLOSE from SMD", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700645 /* SMD channel was closed from the remote side,
646 * this would happen only when Riva crashed and SMD is
647 * closing the channel on behalf of Riva */
Siddharth Bhal3039ed32014-11-27 18:36:28 +0530648 vos_spin_lock_acquire(&pWCTSCb->wctsStateLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700649 pWCTSCb->wctsState = WCTS_STATE_REM_CLOSED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700650 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
651 "%s: received SMD_EVENT_CLOSE WLAN driver going down now",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700652 __func__);
Siddharth Bhal3039ed32014-11-27 18:36:28 +0530653 vos_spin_lock_release(&pWCTSCb->wctsStateLock);
654
Jeff Johnson295189b2012-06-20 16:38:30 -0700655 /* subsystem restart: shutdown */
656 wpalDriverShutdown();
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +0530657 gWdiSmdStats.smd_event_close++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700658 return;
659
660 case SMD_EVENT_STATUS:
661 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700662 "%s: received SMD_EVENT_STATUS from SMD", __func__);
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +0530663 gWdiSmdStats.smd_event_status++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700664 return;
665
666 case SMD_EVENT_REOPEN_READY:
Ratheesh S P36dbc932015-08-07 14:28:57 +0530667 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700668 "%s: received SMD_EVENT_REOPEN_READY from SMD", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700669
670 /* unlike other events which occur when our kernel threads are
671 running, this one is received when the threads are closed and
672 the rmmod thread is waiting. so just unblock that thread */
673 wpalEventSet(&pWCTSCb->wctsEvent);
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +0530674 gWdiSmdStats.smd_event_reopen_ready++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700675 return;
676
677 default:
678 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
679 "%s: Unexpected event %u received from SMD",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700680 __func__, event);
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +0530681 gWdiSmdStats.smd_event_err++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700682
683 return;
684 }
685
686 /* serialize this event */
687 wpalPostCtrlMsg(WDI_GET_PAL_CTX(), palMsg);
688
689} /*WCTS_NotifyCallback*/
Dundi Raviteja902717d2020-05-21 17:24:54 +0530690#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700691
692/*----------------------------------------------------------------------------
693 * Externalized Function Definitions
694 * -------------------------------------------------------------------------*/
695
696
697/**
698 @brief This function is used by the DAL Core to initialize the Control
699 Transport for processing. It must be called prior to calling any
700 other APIs of the Control Transport.
701
702
703 @param szName: unique name for the channel that is to be opened
704 uSize: size of the channel that must be opened (should fit the
705 largest size of packet that the Dal Core wishes to send)
706 wctsCBs: a list of callbacks that the CT needs to use to send
707 notification and messages back to DAL
708
709 @see
710 @return A handle that must be used for further communication with the CTS.
711 This is an opaque structure for the caller and it will be used in
712 all communications to and from the CTS.
713
714*/
715WCTS_HandleType
716WCTS_OpenTransport
717(
718 const wpt_uint8* szName,
719 wpt_uint32 uSize,
720 WCTS_TransportCBsType* wctsCBs
721)
722{
723 WCTS_ControlBlockType* pWCTSCb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700724 int smdstatus;
725
726 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
727
728 /*---------------------------------------------------------------------
729 Sanity check
730 ---------------------------------------------------------------------*/
731 if ((NULL == wctsCBs) || (NULL == szName) ||
732 (NULL == wctsCBs->wctsNotifyCB) || (NULL == wctsCBs->wctsRxMsgCB)) {
733 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
734 "WCTS_OpenTransport: Invalid parameters received.");
735
736 return NULL;
737 }
738
739 /* This open is coming after a SSR, we don't need to reopen SMD,
740 * the SMD port was never closed during SSR*/
741 if (gwctsHandle) {
742 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
Arif Hussain9a5d5382013-11-17 22:05:35 -0800743 "WCTS_OpenTransport port is already open");
Jeff Johnson295189b2012-06-20 16:38:30 -0700744
745 pWCTSCb = gwctsHandle;
746 if (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) {
747 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
748 "WCTS_OpenTransport: Invalid magic.");
749 return NULL;
Surabhi Vishnoie2be1f22020-06-29 11:18:48 +0530750 }
751#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
752 /* Need to open smd channel in case of SSR in rpmsg */
753 smdstatus = vos_smd_open(szName, pWCTSCb);
754#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700755 pWCTSCb->wctsState = WCTS_STATE_OPEN;
756
757 pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
758 WCTS_EVENT_OPEN,
759 pWCTSCb->wctsNotifyCBData);
760
761 /* we initially don't want read interrupts
762 (we only want them if we get into deferred write mode) */
763 smd_disable_read_intr(pWCTSCb->wctsChannel);
764
765 return (WCTS_HandleType)pWCTSCb;
766 }
767
Jeff Johnson295189b2012-06-20 16:38:30 -0700768 /* allocate a ControlBlock to hold all context */
769 pWCTSCb = wpalMemoryAllocate(sizeof(*pWCTSCb));
770 if (NULL == pWCTSCb) {
771 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
772 "WCTS_OpenTransport: Memory allocation failure.");
773 return NULL;
774 }
775
776 /* make sure the control block is initialized. in particular we need
777 to make sure the embedded event and list structures are initialized
778 to prevent "magic number" tests from being run against uninitialized
779 values */
780 wpalMemoryZero(pWCTSCb, sizeof(*pWCTSCb));
781
Jeff Johnson295189b2012-06-20 16:38:30 -0700782 /*Initialise the event*/
783 wpalEventInit(&pWCTSCb->wctsEvent);
784
785 /* save the user-supplied information */
786 pWCTSCb->wctsNotifyCB = wctsCBs->wctsNotifyCB;
787 pWCTSCb->wctsNotifyCBData = wctsCBs->wctsNotifyCBData;
788 pWCTSCb->wctsRxMsgCB = wctsCBs->wctsRxMsgCB;
789 pWCTSCb->wctsRxMsgCBData = wctsCBs->wctsRxMsgCBData;
790
791 /* initialize the remaining fields */
792 wpal_list_init(&pWCTSCb->wctsPendingQueue);
793 pWCTSCb->wctsMagic = WCTS_CB_MAGIC;
Siddharth Bhal3039ed32014-11-27 18:36:28 +0530794 vos_spin_lock_init(&pWCTSCb->wctsStateLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700795 pWCTSCb->wctsState = WCTS_STATE_OPEN_PENDING;
796 pWCTSCb->wctsChannel = NULL;
797
798 /* since SMD will callback in interrupt context, we will used
799 * canned messages to serialize the SMD events into a thread
800 * context
801 */
802 pWCTSCb->wctsOpenMsg.callback = WCTS_PALOpenCallback;
803 pWCTSCb->wctsOpenMsg.pContext = pWCTSCb;
Leo Chang0f24ca12013-12-17 13:35:00 -0800804 pWCTSCb->wctsOpenMsg.type= WPAL_MC_MSG_SMD_NOTIF_OPEN_SIG;
Jeff Johnson295189b2012-06-20 16:38:30 -0700805
806 pWCTSCb->wctsDataMsg.callback = WCTS_PALDataCallback;
807 pWCTSCb->wctsDataMsg.pContext = pWCTSCb;
Dundi Raviteja902717d2020-05-21 17:24:54 +0530808 pWCTSCb->wctsDataMsg.type = WPAL_MC_MSG_SMD_NOTIF_DATA_SIG;
809#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
810 INIT_LIST_HEAD(&pWCTSCb->wctsDataMsg.data_queue);
811 spin_lock_init(&pWCTSCb->wctsDataMsg.data_queue_lock);
812#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700813
814 /*---------------------------------------------------------------------
815 Open the SMD channel
816 ---------------------------------------------------------------------*/
Dundi Raviteja902717d2020-05-21 17:24:54 +0530817 smdstatus = vos_smd_open(szName, pWCTSCb);
Jeff Johnson295189b2012-06-20 16:38:30 -0700818 if (0 != smdstatus) {
819 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
820 "%s: smd_named_open_on_edge failed with status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700821 __func__, smdstatus);
Jeff Johnson295189b2012-06-20 16:38:30 -0700822 goto fail;
823 }
824
Jeff Johnson295189b2012-06-20 16:38:30 -0700825 /* we initially don't want read interrupts
826 (we only want them if we get into deferred write mode) */
827 smd_disable_read_intr(pWCTSCb->wctsChannel);
828
829 /* we have successfully opened the SMD channel */
830 gwctsHandle = pWCTSCb;
831 return (WCTS_HandleType)pWCTSCb;
832
833 fail:
834 /* we were unable to open the SMD channel */
835 pWCTSCb->wctsMagic = 0;
836 wpalMemoryFree(pWCTSCb);
837 return NULL;
838
839}/*WCTS_OpenTransport*/
840
841
Surabhi Vishnoie2be1f22020-06-29 11:18:48 +0530842#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
843void wcts_close_channel(WCTS_HandleType wcts_handle)
844{
845 WCTS_ControlBlockType* wcts_cb = (WCTS_ControlBlockType*) wcts_handle;
Jeff Johnson295189b2012-06-20 16:38:30 -0700846
Surabhi Vishnoie2be1f22020-06-29 11:18:48 +0530847 wcnss_close_channel(wcts_cb->wctsChannel);
848}
849#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700850/**
851 @brief This function is used by the DAL Core to close the
852 Control Transport when its services are no longer
853 needed. Full close notification will be receive
854 asynchronously on the notification callback
855 registered on Open
856
857
858 @param wctsHandlehandle: received upon open
859
860 @see
861 @return 0 for success
862*/
863wpt_uint32
864WCTS_CloseTransport
865(
866 WCTS_HandleType wctsHandle
867)
868{
869 WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) wctsHandle;
870 wpt_list_node* pNode = NULL;
871 WCTS_BufferType* pBufferQueue = NULL;
872 void* pBuffer = NULL;
Dundi Raviteja902717d2020-05-21 17:24:54 +0530873#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700874 wpt_status status;
875 int smdstatus;
Dundi Raviteja902717d2020-05-21 17:24:54 +0530876#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700877
878 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
879
880 if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) {
881 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
882 "WCTS_CloseTransport: Invalid parameters received.");
883 return eWLAN_PAL_STATUS_E_INVAL;
884 }
885
Jeff Johnson295189b2012-06-20 16:38:30 -0700886 /*Free the buffers in the pending queue.*/
887 while (eWLAN_PAL_STATUS_SUCCESS ==
888 wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode)) {
889 pBufferQueue = container_of(pNode, WCTS_BufferType, node);
890 pBuffer = pBufferQueue->pBuffer;
891 wpalMemoryFree(pBuffer);
892 wpalMemoryFree(pBufferQueue);
893 }
894
895 /* Reset the state */
896 pWCTSCb->wctsState = WCTS_STATE_CLOSED;
897
Dundi Raviteja902717d2020-05-21 17:24:54 +0530898#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700899 wpalEventReset(&pWCTSCb->wctsEvent);
900 smdstatus = smd_close(pWCTSCb->wctsChannel);
901 if (0 != smdstatus) {
902 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
903 "%s: smd_close failed with status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700904 __func__, smdstatus);
Jeff Johnson295189b2012-06-20 16:38:30 -0700905 /* SMD did not successfully close the channel, therefore we
906 won't receive an asynchronous close notification so don't
907 bother to wait for an event that won't come */
908
909 } else {
910 /* close command was sent -- wait for the callback to complete */
911 status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_CLOSE_TIMEOUT);
912 if (eWLAN_PAL_STATUS_SUCCESS != status) {
913 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
914 "%s: failed to receive SMD_EVENT_REOPEN_READY",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700915 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700916 }
917
918 /* During the close sequence we deregistered from SMD. As part
919 of deregistration SMD will call back into our driver with an
920 event to let us know the channel is closed. We need to
921 insert a brief delay to allow that thread of execution to
922 exit our module. Otherwise our module may be unloaded while
923 there is still code running within the address space, and
924 that code will crash when the memory is unmapped */
925 msleep(50);
926 }
Dundi Raviteja902717d2020-05-21 17:24:54 +0530927#else
Surabhi Vishnoie2be1f22020-06-29 11:18:48 +0530928 wcts_close_channel(wctsHandle);
Surabhi Vishnoi5d7bb7b2020-06-29 11:17:05 +0530929 wlan_unregister_driver();
Dundi Raviteja902717d2020-05-21 17:24:54 +0530930#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700931
932 /* channel has (hopefully) been closed */
933 pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
934 WCTS_EVENT_CLOSE,
935 pWCTSCb->wctsNotifyCBData);
Siddharth Bhal3039ed32014-11-27 18:36:28 +0530936 vos_spin_lock_destroy(&pWCTSCb->wctsStateLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700937 /* release the resource */
938 pWCTSCb->wctsMagic = 0;
939 wpalMemoryFree(pWCTSCb);
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700940 gwctsHandle = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700941
942 return eWLAN_PAL_STATUS_SUCCESS;
943
944}/*WCTS_CloseTransport*/
945
946
947
948/**
949 @brief This function is used by the DAL Core to to send a
950 message over to the WLAN sub-system.
951
952 Once a buffer has been passed into the Send Message
953 API, CT takes full ownership of it and it is responsible for
954 freeing the associated resources. (This prevents a memcpy in
955 case of a deferred write)
956
957 The messages transported through the CT on both RX and TX are
958 flat memory buffers that can be accessed and manipulated
959 through standard memory functions.
960
961 @param wctsHandlehandle: received upon open
962 pMsg: the message to be sent
963 uLen: the length of the message
964
965 @see
966 @return 0 for success
967*/
968wpt_uint32
969WCTS_SendMessage
970(
971 WCTS_HandleType wctsHandle,
972 void* pMsg,
973 wpt_uint32 uLen
974)
975{
976 WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) wctsHandle;
977 WCTS_BufferType* pBufferQueue;
978 int len;
979 int written = 0;
Dundi Raviteja902717d2020-05-21 17:24:54 +0530980#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700981 int available;
Dundi Raviteja902717d2020-05-21 17:24:54 +0530982#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700983
984 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
985
986 /*--------------------------------------------------------------------
987 Sanity check
988 --------------------------------------------------------------------*/
989 if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) ||
990 (NULL == pMsg) || (0 == uLen) || (0x7fffffff < uLen)) {
991 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
992 "WCTS_SendMessage: Invalid parameters received.");
993 WPAL_ASSERT(0);
994 if (NULL != pMsg) {
995 wpalMemoryFree(pMsg);
996 }
997 return eWLAN_PAL_STATUS_E_INVAL;
998 }
999
1000 /* the SMD API uses int instead of uint, so change types here */
1001 len = (int)uLen;
1002
1003 if (WCTS_STATE_OPEN == pWCTSCb->wctsState) {
Dundi Raviteja902717d2020-05-21 17:24:54 +05301004#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
1005 if (wcnss_smd_tx(pWCTSCb->wctsChannel, pMsg, len))
1006 written = -1;
1007 else
1008 written = len;
1009#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001010 available = smd_write_avail(pWCTSCb->wctsChannel);
1011 if (available >= len) {
1012 written = smd_write(pWCTSCb->wctsChannel, pMsg, len);
1013 }
Dundi Raviteja902717d2020-05-21 17:24:54 +05301014#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001015 } else if (WCTS_STATE_DEFERRED == pWCTSCb->wctsState) {
1016 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
1017 "WCTS_SendMessage: FIFO space not available, the packets will be queued");
1018 } else {
1019 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1020 "WCTS_SendMessage: Channel in illegal state [%d].",
1021 pWCTSCb->wctsState);
1022 /* force following logic to reclaim the buffer */
1023 written = -1;
1024 }
1025
1026 if (-1 == written) {
1027 /*Something wrong*/
1028 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1029 "WCTS_SendMessage: Failed to send message over the bus.");
1030 wpalMemoryFree(pMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07001031 return eWLAN_PAL_STATUS_E_FAILURE;
1032 } else if (written == len) {
1033 /* Message sent! No deferred state, free the buffer*/
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05301034 wpalMemoryZero(pMsg, len);
Jeff Johnson295189b2012-06-20 16:38:30 -07001035 wpalMemoryFree(pMsg);
1036 } else {
1037 /* This much data cannot be written at this time,
1038 queue the rest of the data for later*/
1039 pBufferQueue = wpalMemoryAllocate(sizeof(WCTS_BufferType));
1040 if (NULL == pBufferQueue) {
1041 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1042 "WCTS_SendMessage: Cannot allocate memory for queuing the buffer");
1043 wpalMemoryFree(pMsg);
1044 WPAL_ASSERT(0);
1045 return eWLAN_PAL_STATUS_E_NOMEM;
1046 }
1047
1048 pBufferQueue->bufferSize = len;
1049 pBufferQueue->pBuffer = pMsg;
Pradeep Kumar Goudaguntaf5087fa2014-07-07 19:51:49 +05301050
1051 if (eWLAN_PAL_STATUS_E_FAILURE ==
1052 wpal_list_insert_back(&pWCTSCb->wctsPendingQueue,
1053 &pBufferQueue->node))
1054 {
1055 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1056 "pBufferQueue wpal_list_insert_back failed");
1057 wpalMemoryFree(pMsg);
1058 wpalMemoryFree(pBufferQueue);
1059 WPAL_ASSERT(0);
1060 return eWLAN_PAL_STATUS_E_NOMEM;
1061 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001062
1063 /* if we are not already in the deferred state, then transition
1064 to that state. when we do so, we enable the remote read
1065 interrupt so that we'll be notified when messages are read
1066 from the remote end */
Siddharth Bhal3039ed32014-11-27 18:36:28 +05301067 vos_spin_lock_acquire(&pWCTSCb->wctsStateLock);
1068 if ((WCTS_STATE_DEFERRED != pWCTSCb->wctsState) &&
1069 (WCTS_STATE_REM_CLOSED != pWCTSCb->wctsState)) {
Jeff Johnson295189b2012-06-20 16:38:30 -07001070
Siddharth Bhal3039ed32014-11-27 18:36:28 +05301071 /* Mark the state as deferred.*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 pWCTSCb->wctsState = WCTS_STATE_DEFERRED;
1073
1074 smd_enable_read_intr(pWCTSCb->wctsChannel);
1075 }
Siddharth Bhal3039ed32014-11-27 18:36:28 +05301076 vos_spin_lock_release(&pWCTSCb->wctsStateLock);
Gopichand Nakkalaa5e3ede2012-12-21 15:28:36 -08001077
1078 /*indicate to client that message was placed in deferred queue*/
1079 return eWLAN_PAL_STATUS_E_RESOURCES;
Jeff Johnson295189b2012-06-20 16:38:30 -07001080 }
1081
1082 return eWLAN_PAL_STATUS_SUCCESS;
1083
1084}/*WCTS_SendMessage*/
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +05301085
1086void WCTS_Dump_Smd_status(void)
1087{
1088 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1089 "Smd Read Stats: %d", gWdiSmdStats.smd_event_data);
1090 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1091 "Smd Open Stats: %d", gWdiSmdStats.smd_event_open);
1092 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1093 "Smd Close Stats: %d", gWdiSmdStats.smd_event_close);
1094 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1095 "Smd Status Stats: %d", gWdiSmdStats.smd_event_status);
1096 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1097 "Smd Reopen Stats: %d", gWdiSmdStats.smd_event_reopen_ready);
1098 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1099 "Smd Error Stats: %d", gWdiSmdStats.smd_event_err);
1100}