blob: ff3abe2b8e54a504d35b629ab2e25f552da165ba [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);
256 list_del(&msg->list);
Dundi Raviteja15c65442020-09-29 17:15:40 +0530257 spin_unlock_irqrestore(&pWCTSCb->wctsDataMsg.data_queue_lock, flags);
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 Ravitejae77b8f62020-09-08 13:35:38 +0530498 if (WCTS_CB_MAGIC != wcts_cb->wctsMagic) {
499 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
500 "%s: Received smd data in invalid state", __func__);
501 return 0;
502 }
503
Dundi Ravitejab1ed6442020-07-29 10:31:54 +0530504 if (WCTS_STATE_REM_CLOSED == wcts_cb->wctsState) {
505 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
506 "%s: received SMD data when wcts state is closed ",
507 __func__);
508 /* we should not be getting any data now */
509 return 0;
510 }
511
Dundi Raviteja902717d2020-05-21 17:24:54 +0530512 gWdiSmdStats.smd_event_data++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700513
Dundi Raviteja902717d2020-05-21 17:24:54 +0530514 msg = wpalMemoryAllocate(sizeof(*msg));
515 if (!msg) {
516 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
517 "WCTS_smd_resp_process: Memory allocation failed");
518 return 0;
519 }
520
521 msg->buf_len = len;
522 msg->buffer = wpalMemoryAllocate(len);
523 if (!msg->buffer) {
Dundi Ravitejaa2d010a2020-09-08 13:07:55 +0530524 wpalMemoryFree(msg);
Dundi Raviteja902717d2020-05-21 17:24:54 +0530525 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
526 "WCTS_smd_resp_process: Memory allocation failure");
527 WPAL_ASSERT(0);
528 return 0;
529 }
530
531 vos_mem_copy(msg->buffer, data, msg->buf_len);
532
Dundi Raviteja03d25382020-07-15 14:18:57 +0530533 spin_lock(&wcts_cb->wctsDataMsg.data_queue_lock);
Dundi Raviteja902717d2020-05-21 17:24:54 +0530534 list_add_tail(&msg->list, &wcts_cb->wctsDataMsg.data_queue);
Dundi Raviteja03d25382020-07-15 14:18:57 +0530535 spin_unlock(&wcts_cb->wctsDataMsg.data_queue_lock);
Dundi Raviteja902717d2020-05-21 17:24:54 +0530536
537 wpalPostCtrlMsg(WDI_GET_PAL_CTX(), &wcts_cb->wctsDataMsg);
538
539 return 0;
540}
541
Surabhi Vishnoi5d7bb7b2020-06-29 11:17:05 +0530542int WCTS_driver_state_process(void *priv, enum wcnss_driver_state state)
543{
544 WCTS_ControlBlockType* wcts_cb = (WCTS_ControlBlockType*) priv;
545 wpt_msg *pal_msg;
546
547 switch (state) {
548 case WCNSS_SMD_OPEN:
549 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
550 "%s: received WCNSS_SMD_OPEN from SMD", __func__);
551 /* If the prev state was 'remote closed' then it is a Riva 'restart',
552 * subsystem restart re-init
553 */
554 if (WCTS_STATE_REM_CLOSED == wcts_cb->wctsState) {
555 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
556 "%s: received WCNSS_SMD_OPEN in WCTS_STATE_REM_CLOSED state",
557 __func__);
558 /* call subsystem restart re-init function */
559 wpalDriverReInit();
560 return 0;
561 }
562 gWdiSmdStats.smd_event_open++;
563 pal_msg = &wcts_cb->wctsOpenMsg;
564 break;
565 case WCNSS_SMD_CLOSE:
566 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
567 "%s: received WCNSS_SMD_CLOSE from SMD", __func__);
568 /* SMD channel was closed from the remote side,
569 * this would happen only when Riva crashed and SMD is
570 * closing the channel on behalf of Riva */
571 vos_spin_lock_acquire(&wcts_cb->wctsStateLock);
572 wcts_cb->wctsState = WCTS_STATE_REM_CLOSED;
573 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
574 "%s: received WCNSS_SMD_CLOSE WLAN driver going down now",
575 __func__);
576 vos_spin_lock_release(&wcts_cb->wctsStateLock);
577
578 /* subsystem restart: shutdown */
579 wpalDriverShutdown();
580 gWdiSmdStats.smd_event_close++;
581 return 0;
582 }
583
584 /* serialize this event */
585 wpalPostCtrlMsg(WDI_GET_PAL_CTX(), pal_msg);
586 return 0;
587}
Dundi Raviteja902717d2020-05-21 17:24:54 +0530588#else
589void
Jeff Johnson295189b2012-06-20 16:38:30 -0700590WCTS_NotifyCallback
591(
592 void *data,
593 unsigned event
594)
595{
596 wpt_msg *palMsg;
597 WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) data;
598
599 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
600
601 /*--------------------------------------------------------------------
602 Sanity check
603 --------------------------------------------------------------------*/
604 if (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) {
605 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
606 "%s: Received unexpected SMD event %u",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700607 __func__, event);
Jeff Johnson295189b2012-06-20 16:38:30 -0700608
609 /* TODO_PRIMA what error recovery options do we have? */
610 return;
611 }
612
613 /* Serialize processing in the control thread */
614 switch (event) {
615 case SMD_EVENT_OPEN:
616 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700617 "%s: received SMD_EVENT_OPEN from SMD", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700618 /* If the prev state was 'remote closed' then it is a Riva 'restart',
619 * subsystem restart re-init
620 */
621 if (WCTS_STATE_REM_CLOSED == pWCTSCb->wctsState)
622 {
623 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
624 "%s: received SMD_EVENT_OPEN in WCTS_STATE_REM_CLOSED state",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700625 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700626 /* call subsystem restart re-init function */
627 wpalDriverReInit();
628 return;
629 }
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +0530630 gWdiSmdStats.smd_event_open++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700631 palMsg = &pWCTSCb->wctsOpenMsg;
632 break;
633
634 case SMD_EVENT_DATA:
635 if (WCTS_STATE_REM_CLOSED == pWCTSCb->wctsState)
636 {
637 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
638 "%s: received SMD data when the state is remote closed ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700639 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700640 /* we should not be getting any data now */
641 return;
642 }
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_DATA from SMD", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700645 palMsg = &pWCTSCb->wctsDataMsg;
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +0530646 gWdiSmdStats.smd_event_data++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700647 break;
648
649 case SMD_EVENT_CLOSE:
650 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700651 "%s: received SMD_EVENT_CLOSE from SMD", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700652 /* SMD channel was closed from the remote side,
653 * this would happen only when Riva crashed and SMD is
654 * closing the channel on behalf of Riva */
Siddharth Bhal3039ed32014-11-27 18:36:28 +0530655 vos_spin_lock_acquire(&pWCTSCb->wctsStateLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700656 pWCTSCb->wctsState = WCTS_STATE_REM_CLOSED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700657 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
658 "%s: received SMD_EVENT_CLOSE WLAN driver going down now",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700659 __func__);
Siddharth Bhal3039ed32014-11-27 18:36:28 +0530660 vos_spin_lock_release(&pWCTSCb->wctsStateLock);
661
Jeff Johnson295189b2012-06-20 16:38:30 -0700662 /* subsystem restart: shutdown */
663 wpalDriverShutdown();
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +0530664 gWdiSmdStats.smd_event_close++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700665 return;
666
667 case SMD_EVENT_STATUS:
668 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700669 "%s: received SMD_EVENT_STATUS from SMD", __func__);
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +0530670 gWdiSmdStats.smd_event_status++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700671 return;
672
673 case SMD_EVENT_REOPEN_READY:
Ratheesh S P36dbc932015-08-07 14:28:57 +0530674 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700675 "%s: received SMD_EVENT_REOPEN_READY from SMD", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700676
677 /* unlike other events which occur when our kernel threads are
678 running, this one is received when the threads are closed and
679 the rmmod thread is waiting. so just unblock that thread */
680 wpalEventSet(&pWCTSCb->wctsEvent);
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +0530681 gWdiSmdStats.smd_event_reopen_ready++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700682 return;
683
684 default:
685 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
686 "%s: Unexpected event %u received from SMD",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700687 __func__, event);
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +0530688 gWdiSmdStats.smd_event_err++;
Jeff Johnson295189b2012-06-20 16:38:30 -0700689
690 return;
691 }
692
693 /* serialize this event */
694 wpalPostCtrlMsg(WDI_GET_PAL_CTX(), palMsg);
695
696} /*WCTS_NotifyCallback*/
Dundi Raviteja902717d2020-05-21 17:24:54 +0530697#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700698
699/*----------------------------------------------------------------------------
700 * Externalized Function Definitions
701 * -------------------------------------------------------------------------*/
702
703
704/**
705 @brief This function is used by the DAL Core to initialize the Control
706 Transport for processing. It must be called prior to calling any
707 other APIs of the Control Transport.
708
709
710 @param szName: unique name for the channel that is to be opened
711 uSize: size of the channel that must be opened (should fit the
712 largest size of packet that the Dal Core wishes to send)
713 wctsCBs: a list of callbacks that the CT needs to use to send
714 notification and messages back to DAL
715
716 @see
717 @return A handle that must be used for further communication with the CTS.
718 This is an opaque structure for the caller and it will be used in
719 all communications to and from the CTS.
720
721*/
722WCTS_HandleType
723WCTS_OpenTransport
724(
725 const wpt_uint8* szName,
726 wpt_uint32 uSize,
727 WCTS_TransportCBsType* wctsCBs
728)
729{
730 WCTS_ControlBlockType* pWCTSCb;
Jeff Johnson295189b2012-06-20 16:38:30 -0700731 int smdstatus;
732
733 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
734
735 /*---------------------------------------------------------------------
736 Sanity check
737 ---------------------------------------------------------------------*/
738 if ((NULL == wctsCBs) || (NULL == szName) ||
739 (NULL == wctsCBs->wctsNotifyCB) || (NULL == wctsCBs->wctsRxMsgCB)) {
740 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
741 "WCTS_OpenTransport: Invalid parameters received.");
742
743 return NULL;
744 }
745
746 /* This open is coming after a SSR, we don't need to reopen SMD,
747 * the SMD port was never closed during SSR*/
748 if (gwctsHandle) {
749 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
Arif Hussain9a5d5382013-11-17 22:05:35 -0800750 "WCTS_OpenTransport port is already open");
Jeff Johnson295189b2012-06-20 16:38:30 -0700751
752 pWCTSCb = gwctsHandle;
753 if (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) {
754 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
755 "WCTS_OpenTransport: Invalid magic.");
756 return NULL;
Surabhi Vishnoie2be1f22020-06-29 11:18:48 +0530757 }
758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
759 /* Need to open smd channel in case of SSR in rpmsg */
760 smdstatus = vos_smd_open(szName, pWCTSCb);
761#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700762 pWCTSCb->wctsState = WCTS_STATE_OPEN;
763
764 pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
765 WCTS_EVENT_OPEN,
766 pWCTSCb->wctsNotifyCBData);
767
768 /* we initially don't want read interrupts
769 (we only want them if we get into deferred write mode) */
770 smd_disable_read_intr(pWCTSCb->wctsChannel);
771
772 return (WCTS_HandleType)pWCTSCb;
773 }
774
Jeff Johnson295189b2012-06-20 16:38:30 -0700775 /* allocate a ControlBlock to hold all context */
776 pWCTSCb = wpalMemoryAllocate(sizeof(*pWCTSCb));
777 if (NULL == pWCTSCb) {
778 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
779 "WCTS_OpenTransport: Memory allocation failure.");
780 return NULL;
781 }
782
783 /* make sure the control block is initialized. in particular we need
784 to make sure the embedded event and list structures are initialized
785 to prevent "magic number" tests from being run against uninitialized
786 values */
787 wpalMemoryZero(pWCTSCb, sizeof(*pWCTSCb));
788
Jeff Johnson295189b2012-06-20 16:38:30 -0700789 /*Initialise the event*/
790 wpalEventInit(&pWCTSCb->wctsEvent);
791
792 /* save the user-supplied information */
793 pWCTSCb->wctsNotifyCB = wctsCBs->wctsNotifyCB;
794 pWCTSCb->wctsNotifyCBData = wctsCBs->wctsNotifyCBData;
795 pWCTSCb->wctsRxMsgCB = wctsCBs->wctsRxMsgCB;
796 pWCTSCb->wctsRxMsgCBData = wctsCBs->wctsRxMsgCBData;
797
798 /* initialize the remaining fields */
799 wpal_list_init(&pWCTSCb->wctsPendingQueue);
800 pWCTSCb->wctsMagic = WCTS_CB_MAGIC;
Siddharth Bhal3039ed32014-11-27 18:36:28 +0530801 vos_spin_lock_init(&pWCTSCb->wctsStateLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700802 pWCTSCb->wctsState = WCTS_STATE_OPEN_PENDING;
803 pWCTSCb->wctsChannel = NULL;
804
805 /* since SMD will callback in interrupt context, we will used
806 * canned messages to serialize the SMD events into a thread
807 * context
808 */
809 pWCTSCb->wctsOpenMsg.callback = WCTS_PALOpenCallback;
810 pWCTSCb->wctsOpenMsg.pContext = pWCTSCb;
Leo Chang0f24ca12013-12-17 13:35:00 -0800811 pWCTSCb->wctsOpenMsg.type= WPAL_MC_MSG_SMD_NOTIF_OPEN_SIG;
Jeff Johnson295189b2012-06-20 16:38:30 -0700812
813 pWCTSCb->wctsDataMsg.callback = WCTS_PALDataCallback;
814 pWCTSCb->wctsDataMsg.pContext = pWCTSCb;
Dundi Raviteja902717d2020-05-21 17:24:54 +0530815 pWCTSCb->wctsDataMsg.type = WPAL_MC_MSG_SMD_NOTIF_DATA_SIG;
816#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
817 INIT_LIST_HEAD(&pWCTSCb->wctsDataMsg.data_queue);
818 spin_lock_init(&pWCTSCb->wctsDataMsg.data_queue_lock);
819#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700820
821 /*---------------------------------------------------------------------
822 Open the SMD channel
823 ---------------------------------------------------------------------*/
Dundi Raviteja902717d2020-05-21 17:24:54 +0530824 smdstatus = vos_smd_open(szName, pWCTSCb);
Jeff Johnson295189b2012-06-20 16:38:30 -0700825 if (0 != smdstatus) {
826 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
827 "%s: smd_named_open_on_edge failed with status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700828 __func__, smdstatus);
Jeff Johnson295189b2012-06-20 16:38:30 -0700829 goto fail;
830 }
831
Jeff Johnson295189b2012-06-20 16:38:30 -0700832 /* we initially don't want read interrupts
833 (we only want them if we get into deferred write mode) */
834 smd_disable_read_intr(pWCTSCb->wctsChannel);
835
836 /* we have successfully opened the SMD channel */
837 gwctsHandle = pWCTSCb;
838 return (WCTS_HandleType)pWCTSCb;
839
840 fail:
841 /* we were unable to open the SMD channel */
842 pWCTSCb->wctsMagic = 0;
843 wpalMemoryFree(pWCTSCb);
844 return NULL;
845
846}/*WCTS_OpenTransport*/
847
848
Surabhi Vishnoie2be1f22020-06-29 11:18:48 +0530849#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
850void wcts_close_channel(WCTS_HandleType wcts_handle)
851{
852 WCTS_ControlBlockType* wcts_cb = (WCTS_ControlBlockType*) wcts_handle;
Jeff Johnson295189b2012-06-20 16:38:30 -0700853
Surabhi Vishnoie2be1f22020-06-29 11:18:48 +0530854 wcnss_close_channel(wcts_cb->wctsChannel);
855}
856#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700857/**
858 @brief This function is used by the DAL Core to close the
859 Control Transport when its services are no longer
860 needed. Full close notification will be receive
861 asynchronously on the notification callback
862 registered on Open
863
864
865 @param wctsHandlehandle: received upon open
866
867 @see
868 @return 0 for success
869*/
870wpt_uint32
871WCTS_CloseTransport
872(
873 WCTS_HandleType wctsHandle
874)
875{
876 WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) wctsHandle;
877 wpt_list_node* pNode = NULL;
878 WCTS_BufferType* pBufferQueue = NULL;
879 void* pBuffer = NULL;
Dundi Raviteja902717d2020-05-21 17:24:54 +0530880#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700881 wpt_status status;
882 int smdstatus;
Dundi Raviteja902717d2020-05-21 17:24:54 +0530883#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700884
885 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
886
887 if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) {
888 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
889 "WCTS_CloseTransport: Invalid parameters received.");
890 return eWLAN_PAL_STATUS_E_INVAL;
891 }
892
Jeff Johnson295189b2012-06-20 16:38:30 -0700893 /*Free the buffers in the pending queue.*/
894 while (eWLAN_PAL_STATUS_SUCCESS ==
895 wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode)) {
896 pBufferQueue = container_of(pNode, WCTS_BufferType, node);
897 pBuffer = pBufferQueue->pBuffer;
898 wpalMemoryFree(pBuffer);
899 wpalMemoryFree(pBufferQueue);
900 }
901
902 /* Reset the state */
903 pWCTSCb->wctsState = WCTS_STATE_CLOSED;
904
Dundi Raviteja902717d2020-05-21 17:24:54 +0530905#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700906 wpalEventReset(&pWCTSCb->wctsEvent);
907 smdstatus = smd_close(pWCTSCb->wctsChannel);
908 if (0 != smdstatus) {
909 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
910 "%s: smd_close failed with status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700911 __func__, smdstatus);
Jeff Johnson295189b2012-06-20 16:38:30 -0700912 /* SMD did not successfully close the channel, therefore we
913 won't receive an asynchronous close notification so don't
914 bother to wait for an event that won't come */
915
916 } else {
917 /* close command was sent -- wait for the callback to complete */
918 status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_CLOSE_TIMEOUT);
919 if (eWLAN_PAL_STATUS_SUCCESS != status) {
920 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
921 "%s: failed to receive SMD_EVENT_REOPEN_READY",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700922 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700923 }
924
925 /* During the close sequence we deregistered from SMD. As part
926 of deregistration SMD will call back into our driver with an
927 event to let us know the channel is closed. We need to
928 insert a brief delay to allow that thread of execution to
929 exit our module. Otherwise our module may be unloaded while
930 there is still code running within the address space, and
931 that code will crash when the memory is unmapped */
932 msleep(50);
933 }
Dundi Raviteja902717d2020-05-21 17:24:54 +0530934#else
Surabhi Vishnoie2be1f22020-06-29 11:18:48 +0530935 wcts_close_channel(wctsHandle);
Surabhi Vishnoi5d7bb7b2020-06-29 11:17:05 +0530936 wlan_unregister_driver();
Dundi Raviteja902717d2020-05-21 17:24:54 +0530937#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700938
939 /* channel has (hopefully) been closed */
940 pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb,
941 WCTS_EVENT_CLOSE,
942 pWCTSCb->wctsNotifyCBData);
Siddharth Bhal3039ed32014-11-27 18:36:28 +0530943 vos_spin_lock_destroy(&pWCTSCb->wctsStateLock);
Jeff Johnson295189b2012-06-20 16:38:30 -0700944 /* release the resource */
945 pWCTSCb->wctsMagic = 0;
946 wpalMemoryFree(pWCTSCb);
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700947 gwctsHandle = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700948
949 return eWLAN_PAL_STATUS_SUCCESS;
950
951}/*WCTS_CloseTransport*/
952
953
954
955/**
956 @brief This function is used by the DAL Core to to send a
957 message over to the WLAN sub-system.
958
959 Once a buffer has been passed into the Send Message
960 API, CT takes full ownership of it and it is responsible for
961 freeing the associated resources. (This prevents a memcpy in
962 case of a deferred write)
963
964 The messages transported through the CT on both RX and TX are
965 flat memory buffers that can be accessed and manipulated
966 through standard memory functions.
967
968 @param wctsHandlehandle: received upon open
969 pMsg: the message to be sent
970 uLen: the length of the message
971
972 @see
973 @return 0 for success
974*/
975wpt_uint32
976WCTS_SendMessage
977(
978 WCTS_HandleType wctsHandle,
979 void* pMsg,
980 wpt_uint32 uLen
981)
982{
983 WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) wctsHandle;
984 WCTS_BufferType* pBufferQueue;
985 int len;
986 int written = 0;
Dundi Raviteja902717d2020-05-21 17:24:54 +0530987#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700988 int available;
Dundi Raviteja902717d2020-05-21 17:24:54 +0530989#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700990
991 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
992
993 /*--------------------------------------------------------------------
994 Sanity check
995 --------------------------------------------------------------------*/
996 if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) ||
997 (NULL == pMsg) || (0 == uLen) || (0x7fffffff < uLen)) {
998 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
999 "WCTS_SendMessage: Invalid parameters received.");
1000 WPAL_ASSERT(0);
1001 if (NULL != pMsg) {
1002 wpalMemoryFree(pMsg);
1003 }
1004 return eWLAN_PAL_STATUS_E_INVAL;
1005 }
1006
1007 /* the SMD API uses int instead of uint, so change types here */
1008 len = (int)uLen;
1009
1010 if (WCTS_STATE_OPEN == pWCTSCb->wctsState) {
Dundi Raviteja902717d2020-05-21 17:24:54 +05301011#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
1012 if (wcnss_smd_tx(pWCTSCb->wctsChannel, pMsg, len))
1013 written = -1;
1014 else
1015 written = len;
1016#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001017 available = smd_write_avail(pWCTSCb->wctsChannel);
1018 if (available >= len) {
1019 written = smd_write(pWCTSCb->wctsChannel, pMsg, len);
1020 }
Dundi Raviteja902717d2020-05-21 17:24:54 +05301021#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001022 } else if (WCTS_STATE_DEFERRED == pWCTSCb->wctsState) {
1023 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
1024 "WCTS_SendMessage: FIFO space not available, the packets will be queued");
1025 } else {
1026 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1027 "WCTS_SendMessage: Channel in illegal state [%d].",
1028 pWCTSCb->wctsState);
1029 /* force following logic to reclaim the buffer */
1030 written = -1;
1031 }
1032
1033 if (-1 == written) {
1034 /*Something wrong*/
1035 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1036 "WCTS_SendMessage: Failed to send message over the bus.");
1037 wpalMemoryFree(pMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07001038 return eWLAN_PAL_STATUS_E_FAILURE;
1039 } else if (written == len) {
1040 /* Message sent! No deferred state, free the buffer*/
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05301041 wpalMemoryZero(pMsg, len);
Jeff Johnson295189b2012-06-20 16:38:30 -07001042 wpalMemoryFree(pMsg);
1043 } else {
1044 /* This much data cannot be written at this time,
1045 queue the rest of the data for later*/
1046 pBufferQueue = wpalMemoryAllocate(sizeof(WCTS_BufferType));
1047 if (NULL == pBufferQueue) {
1048 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1049 "WCTS_SendMessage: Cannot allocate memory for queuing the buffer");
1050 wpalMemoryFree(pMsg);
1051 WPAL_ASSERT(0);
1052 return eWLAN_PAL_STATUS_E_NOMEM;
1053 }
1054
1055 pBufferQueue->bufferSize = len;
1056 pBufferQueue->pBuffer = pMsg;
Pradeep Kumar Goudaguntaf5087fa2014-07-07 19:51:49 +05301057
1058 if (eWLAN_PAL_STATUS_E_FAILURE ==
1059 wpal_list_insert_back(&pWCTSCb->wctsPendingQueue,
1060 &pBufferQueue->node))
1061 {
1062 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1063 "pBufferQueue wpal_list_insert_back failed");
1064 wpalMemoryFree(pMsg);
1065 wpalMemoryFree(pBufferQueue);
1066 WPAL_ASSERT(0);
1067 return eWLAN_PAL_STATUS_E_NOMEM;
1068 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001069
1070 /* if we are not already in the deferred state, then transition
1071 to that state. when we do so, we enable the remote read
1072 interrupt so that we'll be notified when messages are read
1073 from the remote end */
Siddharth Bhal3039ed32014-11-27 18:36:28 +05301074 vos_spin_lock_acquire(&pWCTSCb->wctsStateLock);
1075 if ((WCTS_STATE_DEFERRED != pWCTSCb->wctsState) &&
1076 (WCTS_STATE_REM_CLOSED != pWCTSCb->wctsState)) {
Jeff Johnson295189b2012-06-20 16:38:30 -07001077
Siddharth Bhal3039ed32014-11-27 18:36:28 +05301078 /* Mark the state as deferred.*/
Jeff Johnson295189b2012-06-20 16:38:30 -07001079 pWCTSCb->wctsState = WCTS_STATE_DEFERRED;
1080
1081 smd_enable_read_intr(pWCTSCb->wctsChannel);
1082 }
Siddharth Bhal3039ed32014-11-27 18:36:28 +05301083 vos_spin_lock_release(&pWCTSCb->wctsStateLock);
Gopichand Nakkalaa5e3ede2012-12-21 15:28:36 -08001084
1085 /*indicate to client that message was placed in deferred queue*/
1086 return eWLAN_PAL_STATUS_E_RESOURCES;
Jeff Johnson295189b2012-06-20 16:38:30 -07001087 }
1088
1089 return eWLAN_PAL_STATUS_SUCCESS;
1090
1091}/*WCTS_SendMessage*/
Arunk Khandavalliaf6c3af2017-01-16 11:44:46 +05301092
1093void WCTS_Dump_Smd_status(void)
1094{
1095 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1096 "Smd Read Stats: %d", gWdiSmdStats.smd_event_data);
1097 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1098 "Smd Open Stats: %d", gWdiSmdStats.smd_event_open);
1099 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1100 "Smd Close Stats: %d", gWdiSmdStats.smd_event_close);
1101 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1102 "Smd Status Stats: %d", gWdiSmdStats.smd_event_status);
1103 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1104 "Smd Reopen Stats: %d", gWdiSmdStats.smd_event_reopen_ready);
1105 WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
1106 "Smd Error Stats: %d", gWdiSmdStats.smd_event_err);
1107}