blob: 5a5c187a721f4340218de1b8e2fcf66c7a4d260d [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Vinay Krishna Eranna8147e702015-03-06 17:43:41 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam0fb93dd2014-02-19 00:32:59 -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.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080020 */
Kiet Lam0fb93dd2014-02-19 00:32:59 -080021
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.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/******************************************************************************
29 * wlan_ptt_sock_svc.c
30 *
31 ******************************************************************************/
32#ifdef PTT_SOCK_SVC_ENABLE
33#include <wlan_nlink_srv.h>
34#include <halTypes.h>
35#include <vos_status.h>
36#include <wlan_hdd_includes.h>
37#include <vos_trace.h>
38#include <wlan_nlink_common.h>
39#include <wlan_ptt_sock_svc.h>
40#include <vos_types.h>
41#include <vos_trace.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070042#include <wlan_hdd_ftm.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44#define PTT_SOCK_DEBUG
45#ifdef PTT_SOCK_DEBUG
46#define PTT_TRACE(level, args...) VOS_TRACE( VOS_MODULE_ID_HDD, level, ## args)
47#else
48#define PTT_TRACE(level, args...)
49#endif
50// Global variables
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -070051static struct hdd_context_s *pAdapterHandle;
Jeff Johnson295189b2012-06-20 16:38:30 -070052//Utility function to perform endianess swap
53static void ptt_sock_swap_32(void *pBuffer, unsigned int len)
54{
55 v_U32_t *pBuf32, data;
56 v_U8_t *pBuf8;
57 unsigned int i;
58 len &= ~(sizeof(v_U32_t)-1);
59 pBuf32 = (v_U32_t *) pBuffer;
60 pBuf8 = (v_U8_t *) pBuffer;
61 for (i = 0; i < len; i += 4, ++pBuf32, pBuf8 += 4) {
62 data = *pBuf32;
63 pBuf8[0] = (v_U8_t) ((data >> 24) & 0xff);
64 pBuf8[1] = (v_U8_t) ((data >> 16) & 0xff);
65 pBuf8[2] = (v_U8_t) ((data >> 8) & 0xff);
66 pBuf8[3] = (v_U8_t) ((data >> 0) & 0xff);
67 }
68}
69#ifdef PTT_SOCK_DEBUG_VERBOSE
70//Utility function to perform a hex dump
71static void ptt_sock_dump_buf(const unsigned char * pbuf, int cnt)
72{
73 int i;
74 for (i = 0; i < cnt ; i++) {
75 if ((i%16)==0)
76 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"\n%p:", pbuf);
77 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO," %02X", *pbuf);
78 pbuf++;
79 }
80 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"\n");
81}
82#endif
83//Utility function to send a netlink message to an application in user space
Hardik Kantilal Patel9a52d272014-04-29 14:24:55 +053084int ptt_sock_send_msg_to_app(tAniHdr *wmsg, int radio, int src_mod, int pid, int flag)
Jeff Johnson295189b2012-06-20 16:38:30 -070085{
86 int err = -1;
87 int payload_len;
88 int tot_msg_len;
89 tAniNlHdr *wnl;
90 struct sk_buff *skb;
91 struct nlmsghdr *nlh;
92 int wmsg_length = be16_to_cpu(wmsg->length);
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -070093 static int nlmsg_seq;
Jeff Johnson295189b2012-06-20 16:38:30 -070094 if (radio < 0 || radio > ANI_MAX_RADIOS) {
95 PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: invalid radio id [%d]\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070096 __func__, radio);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080097 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070098 }
99 payload_len = wmsg_length + 4; // 4 extra bytes for the radio idx
100 tot_msg_len = NLMSG_SPACE(payload_len);
101 if ((skb = dev_alloc_skb(tot_msg_len)) == NULL) {
102 PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: dev_alloc_skb() failed for msg size[%d]\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700103 __func__, tot_msg_len);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -0800104 return -ENOMEM;
Jeff Johnson295189b2012-06-20 16:38:30 -0700105 }
Jeff Johnsonf6624a42013-01-17 18:25:55 -0800106 nlh = nlmsg_put(skb, pid, nlmsg_seq++, src_mod, payload_len, NLM_F_REQUEST);
107 if (NULL == nlh) {
108 PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_put() failed for msg size[%d]\n",
109 __func__, tot_msg_len);
110 kfree_skb(skb);
111 return -ENOMEM;
112 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700113 wnl = (tAniNlHdr *) nlh;
114 wnl->radio = radio;
Rajesh Babu Prathipati71e9c442014-07-01 22:08:29 +0530115 vos_mem_copy(&wnl->wmsg, wmsg, wmsg_length);
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#ifdef PTT_SOCK_DEBUG_VERBOSE
117 ptt_sock_dump_buf((const unsigned char *)skb->data, skb->len);
118#endif
Sushant Kaushik5a64cf72015-05-07 15:26:02 +0530119 if (pid != INVALID_PID)
120 {
121 err = nl_srv_ucast(skb, pid, flag);
122 }
123 else
124 {
125 err = nl_srv_bcast(skb);
126 }
Vinay Krishna Eranna8147e702015-03-06 17:43:41 +0530127 if (err) {
128 PTT_TRACE(VOS_TRACE_LEVEL_INFO,
129 "%s:Failed sending Msg Type [0x%X] to pid[%d]\n",
130 __func__, be16_to_cpu(wmsg->type), pid);
131 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700132 return err;
133}
134/*
135 * Process tregisteration request and send registration response messages
136 * to the PTT Socket App in user space
137 */
138static void ptt_sock_proc_reg_req(tAniHdr *wmsg, int radio)
139{
140 tAniNlAppRegReq *reg_req;
141 tAniNlAppRegRsp rspmsg;
142 reg_req = (tAniNlAppRegReq *)(wmsg + 1);
143 memset((char *)&rspmsg, 0, sizeof(rspmsg));
144 //send reg response message to the application
145 rspmsg.ret = ANI_NL_MSG_OK;
146 rspmsg.regReq.type = reg_req->type;
Madan Mohan Koyyalamudi4aa1cda2013-09-24 19:57:30 -0700147#ifdef WLAN_KD_READY_NOTIFIER
148 /* NL client try to registration
149 * to make sure connection, broadcast READY notification */
150 nl_srv_nl_ready_indication();
151#endif /* WLAN_KD_READY_NOTIFIER */
Hardik Kantilal Patel9a52d272014-04-29 14:24:55 +0530152 /*Save the pid*/
153 pAdapterHandle->ptt_pid = reg_req->pid;
Jeff Johnson295189b2012-06-20 16:38:30 -0700154 rspmsg.regReq.pid= reg_req->pid;
155 rspmsg.wniHdr.type = cpu_to_be16(ANI_MSG_APP_REG_RSP);
156 rspmsg.wniHdr.length = cpu_to_be16(sizeof(rspmsg));
157 if (ptt_sock_send_msg_to_app((tAniHdr *)&rspmsg.wniHdr, radio,
Hardik Kantilal Patel9a52d272014-04-29 14:24:55 +0530158 ANI_NL_MSG_PUMAC, reg_req->pid, MSG_DONTWAIT) < 0)
Jeff Johnson295189b2012-06-20 16:38:30 -0700159 {
Ratheesh S P36dbc932015-08-07 14:28:57 +0530160 PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: Error sending ANI_MSG_APP_REG_RSP to pid[%d]\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700161 __func__, reg_req->pid);
Jeff Johnson295189b2012-06-20 16:38:30 -0700162 }
163}
164/*
165 * Process all the messages from the PTT Socket App in user space
166 */
167static void ptt_proc_pumac_msg(struct sk_buff * skb, tAniHdr *wmsg, int radio)
168{
169 u16 ani_msg_type = be16_to_cpu(wmsg->type);
170 switch(ani_msg_type)
171 {
172 case ANI_MSG_APP_REG_REQ:
173 PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: Received ANI_MSG_APP_REG_REQ [0x%X]\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700174 __func__, ani_msg_type);
Jeff Johnson295189b2012-06-20 16:38:30 -0700175 ptt_sock_proc_reg_req(wmsg, radio);
176 break;
177 default:
178 PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Received Unknown Msg Type[0x%X]\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700179 __func__, ani_msg_type);
Jeff Johnson295189b2012-06-20 16:38:30 -0700180 break;
181 }
182}
183/*
184 * Process all the messages from the Quarky Client
185 */
186static void ptt_proc_quarky_msg(tAniNlHdr *wnl, tAniHdr *wmsg, int radio)
187{
188 u16 ani_msg_type = be16_to_cpu(wmsg->type);
189 v_U32_t reg_addr;
190 v_U32_t reg_val;
191 v_U32_t len_payload;
192 v_U8_t* buf;
193 unsigned int arg1, arg2, arg3, arg4, cmd;
194 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
195 if (radio < 0 || radio > ANI_MAX_RADIOS) {
196 PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: ANI Msg [0x%X] invalid radio id [%d]\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700197 __func__, ani_msg_type, radio);
Jeff Johnson295189b2012-06-20 16:38:30 -0700198 return;
199 }
200 if(ani_msg_type == ANI_MSG_APP_REG_REQ)
201 {
202 ptt_sock_proc_reg_req(wmsg, radio);
203 }
204 else
205 {
206 switch (ani_msg_type)
207 {
208 case PTT_MSG_READ_REGISTER:
209 reg_addr = *(v_U32_t*) ((char*)wmsg + 8);
Jeff Johnson98e4aff2013-10-30 12:18:13 -0700210 PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_READ_REGISTER [0x%08X]\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700211 __func__, reg_addr);
Jeff Johnson295189b2012-06-20 16:38:30 -0700212 vosStatus = sme_DbgReadRegister(pAdapterHandle->hHal, reg_addr, &reg_val);
213 *(v_U32_t*) ((char*)wmsg + 12) = reg_val;
214 if(vosStatus != VOS_STATUS_SUCCESS)
Jeff Johnson98e4aff2013-10-30 12:18:13 -0700215 PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Read Register [0x%08X] failed!!\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700216 __func__, reg_addr);
Hardik Kantilal Patel9a52d272014-04-29 14:24:55 +0530217 ptt_sock_send_msg_to_app(wmsg, 0, ANI_NL_MSG_PUMAC, wnl->nlh.nlmsg_pid, MSG_DONTWAIT);
Jeff Johnson295189b2012-06-20 16:38:30 -0700218 break;
219 case PTT_MSG_WRITE_REGISTER:
220 reg_addr = *(v_U32_t*) ((const unsigned char*)wmsg + 8);
221 reg_val = *(v_U32_t*)((const unsigned char*)wmsg + 12);
Jeff Johnson98e4aff2013-10-30 12:18:13 -0700222 PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_WRITE_REGISTER Addr [0x%08X] value [0x%08X]\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700223 __func__, reg_addr, reg_val);
Jeff Johnson295189b2012-06-20 16:38:30 -0700224 vosStatus = sme_DbgWriteRegister(pAdapterHandle->hHal, reg_addr, reg_val);
225 if(vosStatus != VOS_STATUS_SUCCESS)
226 {
Jeff Johnson98e4aff2013-10-30 12:18:13 -0700227 PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Write Register [0x%08X] value [0x%08X] failed!!\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700228 __func__, reg_addr, reg_val);
Jeff Johnson295189b2012-06-20 16:38:30 -0700229 }
230 //send message to the app
Hardik Kantilal Patel9a52d272014-04-29 14:24:55 +0530231 ptt_sock_send_msg_to_app(wmsg, 0, ANI_NL_MSG_PUMAC, wnl->nlh.nlmsg_pid, MSG_DONTWAIT);
Jeff Johnson295189b2012-06-20 16:38:30 -0700232 break;
233 case PTT_MSG_READ_MEMORY:
234 reg_addr = *(v_U32_t*) ((char*)wmsg + 8);
235 len_payload = *(v_U32_t*) ((char*)wmsg + 12);
Jeff Johnson98e4aff2013-10-30 12:18:13 -0700236 PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_READ_MEMORY addr [0x%08X] bytes [0x%08X]\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700237 __func__, reg_addr, len_payload);
Jeff Johnson295189b2012-06-20 16:38:30 -0700238 buf = (v_U8_t*)wmsg + 16;
239 vosStatus = sme_DbgReadMemory(pAdapterHandle->hHal, reg_addr, buf, len_payload);
240 if(vosStatus != VOS_STATUS_SUCCESS) {
Jeff Johnson98e4aff2013-10-30 12:18:13 -0700241 PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Memory read failed for [0x%08X]!!\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700242 __func__, reg_addr);
Jeff Johnson295189b2012-06-20 16:38:30 -0700243 }
244 ptt_sock_swap_32(buf, len_payload);
245 //send message to the app
Hardik Kantilal Patel9a52d272014-04-29 14:24:55 +0530246 ptt_sock_send_msg_to_app(wmsg, 0, ANI_NL_MSG_PUMAC, wnl->nlh.nlmsg_pid, MSG_DONTWAIT);
Jeff Johnson295189b2012-06-20 16:38:30 -0700247 break;
248 case PTT_MSG_WRITE_MEMORY:
249 reg_addr = *(v_U32_t*) ((char*)wmsg + 8);
250 len_payload = *(v_U32_t*) ((char*)wmsg + 12);
Jeff Johnson98e4aff2013-10-30 12:18:13 -0700251 PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_DBG_WRITE_MEMORY addr [0x%08X] bytes [0x%08X]\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700252 __func__, reg_addr, len_payload);
Jeff Johnson295189b2012-06-20 16:38:30 -0700253 buf = (v_U8_t*)wmsg + 16;
254 ptt_sock_swap_32(buf, len_payload);
255 vosStatus = sme_DbgWriteMemory(pAdapterHandle->hHal, reg_addr, buf, len_payload);
256 if(vosStatus != VOS_STATUS_SUCCESS)
257 {
Jeff Johnson98e4aff2013-10-30 12:18:13 -0700258 PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Memory write failed for addr [0x%08X]!!\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700259 __func__, reg_addr);
Jeff Johnson295189b2012-06-20 16:38:30 -0700260 }
261 //send message to the app
Hardik Kantilal Patel9a52d272014-04-29 14:24:55 +0530262 ptt_sock_send_msg_to_app(wmsg, 0, ANI_NL_MSG_PUMAC, wnl->nlh.nlmsg_pid, MSG_DONTWAIT);
Jeff Johnson295189b2012-06-20 16:38:30 -0700263 break;
264 case PTT_MSG_LOG_DUMP_DBG:
265 cmd = *(unsigned int *) ((char *)wmsg + 8);
266 arg1 = *(unsigned int *) ((char *)wmsg + 12);
267 arg2 = *(unsigned int *) ((char *)wmsg + 16);
268 arg3 = *(unsigned int *) ((char *)wmsg + 20);
269 arg4 = *(unsigned int *) ((char *)wmsg + 24);
270 PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_LOG_DUMP_DBG %d arg1 %d arg2 %d arg3 %d arg4 %d\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700271 __func__, cmd, arg1, arg2, arg3, arg4);
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 //send message to the app
Hardik Kantilal Patel9a52d272014-04-29 14:24:55 +0530273 ptt_sock_send_msg_to_app(wmsg, 0, ANI_NL_MSG_PUMAC, wnl->nlh.nlmsg_pid, MSG_DONTWAIT);
Jeff Johnson295189b2012-06-20 16:38:30 -0700274 break;
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 case PTT_MSG_FTM_CMDS_TYPE:
276 wlan_hdd_process_ftm_cmd(pAdapterHandle,wnl);
277 break;
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 default:
279 PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Unknown ANI Msg [0x%X], length [0x%X]\n",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700280 __func__, ani_msg_type, be16_to_cpu(wmsg->length ));
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 break;
282 }
283 }
284}
285/*
286 * Process all the Netlink messages from PTT Socket app in user space
287 */
288static int ptt_sock_rx_nlink_msg (struct sk_buff * skb)
289{
290 tAniNlHdr *wnl;
291 int radio;
292 int type;
293 wnl = (tAniNlHdr *) skb->data;
294 radio = wnl->radio;
295 type = wnl->nlh.nlmsg_type;
296 switch (type) {
297 case ANI_NL_MSG_PUMAC: //Message from the PTT socket APP
298 PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: Received ANI_NL_MSG_PUMAC Msg [0x%X]\n",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530299 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -0700300 ptt_proc_pumac_msg(skb, &wnl->wmsg, radio);
301 break;
302 case ANI_NL_MSG_PTT: //Message from Quarky GUI
303 PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: Received ANI_NL_MSG_PTT Msg [0x%X]\n",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +0530304 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -0700305 ptt_proc_quarky_msg(wnl, &wnl->wmsg, radio);
306 break;
307 default:
308 PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Unknown NL Msg [0x%X]\n",__func__, type);
309 break;
310 }
311 return 0;
312}
313int ptt_sock_activate_svc(void *pAdapter)
314{
315 pAdapterHandle = (struct hdd_context_s*)pAdapter;
316 nl_srv_register(ANI_NL_MSG_PUMAC, ptt_sock_rx_nlink_msg);
317 nl_srv_register(ANI_NL_MSG_PTT, ptt_sock_rx_nlink_msg);
Leo Chang59cdc7e2013-07-10 10:08:21 -0700318#ifdef WLAN_KD_READY_NOTIFIER
319 nl_srv_nl_ready_indication();
320#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 return 0;
322}
323#endif //PTT_SOCK_SVC_ENABLE