blob: 052282a00ff2681ecbd9557e0c0d79036cc23b68 [file] [log] [blame]
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301/*
2 **************************************************************************
Stephen Wang3e2dbd12018-03-14 17:28:17 -07003 * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05304 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all copies.
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 **************************************************************************
15 */
16
17/*
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -070018 * nss_n2h.c
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053019 * NSS N2H node APIs
20 */
21
22#include "nss_tx_rx_common.h"
Yu Huang8c107082017-07-24 14:58:26 -070023#include "nss_n2h_stats.h"
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053024
Stephen Wang49b474b2016-03-25 10:40:30 -070025#define NSS_N2H_MAX_BUF_POOL_SIZE (1024 * 1024 * 8) /* 8MB */
Saurabh Misra71034db2015-06-04 16:18:38 -070026#define NSS_N2H_MIN_EMPTY_POOL_BUF_SZ 32
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +053027#define NSS_N2H_MAX_EMPTY_POOL_BUF_SZ 65536
Vijay Dewangan488e5372014-12-29 21:40:11 -080028#define NSS_N2H_DEFAULT_EMPTY_POOL_BUF_SZ 8192
ratheesh kannothab436af2017-07-20 08:51:07 +053029#define NSS_N2H_TX_TIMEOUT 3000 /* 3 Seconds */
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053030
Saurabh Misra71034db2015-06-04 16:18:38 -070031int nss_n2h_empty_pool_buf_cfg[NSS_MAX_CORES] __read_mostly = {-1, -1};
Sachin Shashidhar475012b2017-03-13 16:56:07 -070032int nss_n2h_empty_paged_pool_buf_cfg[NSS_MAX_CORES] __read_mostly = {-1, -1};
Saurabh Misra71034db2015-06-04 16:18:38 -070033int nss_n2h_water_mark[NSS_MAX_CORES][2] __read_mostly = {{-1, -1}, {-1, -1} };
Sachin Shashidhar475012b2017-03-13 16:56:07 -070034int nss_n2h_paged_water_mark[NSS_MAX_CORES][2] __read_mostly = {{-1, -1}, {-1, -1} };
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +053035int nss_n2h_wifi_pool_buf_cfg __read_mostly = -1;
Stephen Wang49b474b2016-03-25 10:40:30 -070036int nss_n2h_core0_mitigation_cfg __read_mostly = 1;
37int nss_n2h_core1_mitigation_cfg __read_mostly = 1;
38int nss_n2h_core0_add_buf_pool_size __read_mostly;
39int nss_n2h_core1_add_buf_pool_size __read_mostly;
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053040
Vijay Dewangan488e5372014-12-29 21:40:11 -080041struct nss_n2h_registered_data {
42 nss_n2h_msg_callback_t n2h_callback;
43 void *app_data;
44};
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053045
Vijay Dewangan488e5372014-12-29 21:40:11 -080046static struct nss_n2h_cfg_pvt nss_n2h_nepbcfgp[NSS_MAX_CORES];
47static struct nss_n2h_registered_data nss_n2h_rd[NSS_MAX_CORES];
Vijay Dewangan634ce592015-01-07 17:21:09 -080048static struct nss_n2h_cfg_pvt nss_n2h_rcp;
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +053049static struct nss_n2h_cfg_pvt nss_n2h_mitigationcp[NSS_CORE_MAX];
50static struct nss_n2h_cfg_pvt nss_n2h_bufcp[NSS_CORE_MAX];
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +053051static struct nss_n2h_cfg_pvt nss_n2h_wp;
ratheesh kannothab436af2017-07-20 08:51:07 +053052static struct nss_n2h_cfg_pvt nss_n2h_q_cfg_pvt;
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053053
54/*
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -070055 * nss_n2h_interface_handler()
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053056 * Handle NSS -> HLOS messages for N2H node
57 */
Vijay Dewangan634ce592015-01-07 17:21:09 -080058static void nss_n2h_interface_handler(struct nss_ctx_instance *nss_ctx,
59 struct nss_cmn_msg *ncm,
Arunkumar Tba9b4a02016-11-07 11:41:14 +053060 void *app_data)
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053061{
62 struct nss_n2h_msg *nnm = (struct nss_n2h_msg *)ncm;
Vijay Dewangan488e5372014-12-29 21:40:11 -080063 nss_n2h_msg_callback_t cb;
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053064
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -070065 BUG_ON(ncm->interface != NSS_N2H_INTERFACE);
66
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053067 /*
68 * Is this a valid request/response packet?
69 */
70 if (nnm->cm.type >= NSS_METADATA_TYPE_N2H_MAX) {
71 nss_warning("%p: received invalid message %d for Offload stats interface", nss_ctx, nnm->cm.type);
72 return;
73 }
74
75 switch (nnm->cm.type) {
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053076 case NSS_TX_METADATA_TYPE_N2H_RPS_CFG:
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053077 nss_info("NSS N2H rps_en %d \n",nnm->msg.rps_cfg.enable);
Vijay Dewangan488e5372014-12-29 21:40:11 -080078 break;
79
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +053080 case NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG:
81 nss_info("NSS N2H mitigation_dis %d \n",nnm->msg.mitigation_cfg.enable);
82 break;
83
Vijay Dewangan488e5372014-12-29 21:40:11 -080084 case NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG:
85 nss_info("%p: empty pool buf cfg response from FW", nss_ctx);
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053086 break;
87
Radha krishna Simha Jiguru7f424d52015-02-10 19:41:01 +053088 case NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS:
89 nss_info("%p: flush payloads cmd response from FW", nss_ctx);
90 break;
91
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053092 case NSS_RX_METADATA_TYPE_N2H_STATS_SYNC:
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -070093 nss_n2h_stats_sync(nss_ctx, &nnm->msg.stats_sync);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053094 break;
95
96 default:
97 if (ncm->response != NSS_CMN_RESPONSE_ACK) {
98 /*
99 * Check response
100 */
101 nss_info("%p: Received response %d for type %d, interface %d",
102 nss_ctx, ncm->response, ncm->type, ncm->interface);
103 }
104 }
Vijay Dewangan488e5372014-12-29 21:40:11 -0800105
106 /*
Stephen Wang49b474b2016-03-25 10:40:30 -0700107 * Update the callback and app_data for NOTIFY messages, n2h sends all notify messages
Vijay Dewangan488e5372014-12-29 21:40:11 -0800108 * to the same callback/app_data.
109 */
110 if (nnm->cm.response == NSS_CMM_RESPONSE_NOTIFY) {
111 /*
112 * Place holder for the user to create right call
113 * back and app data when response is NSS_CMM_RESPONSE_NOTIFY
114 */
Stephen Wangaed46332016-12-12 17:29:03 -0800115 ncm->cb = (nss_ptr_t)nss_n2h_rd[nss_ctx->id].n2h_callback;
116 ncm->app_data = (nss_ptr_t)nss_n2h_rd[nss_ctx->id].app_data;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800117 }
118
119 /*
120 * Do we have a callback?
121 */
122 if (!ncm->cb) {
123 return;
124 }
125
126 /*
127 * Callback
128 */
129 cb = (nss_n2h_msg_callback_t)ncm->cb;
130 cb((void *)ncm->app_data, nnm);
131}
132
133/*
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530134 * nss_n2h_mitigation_cfg_callback()
135 * call back function for mitigation configuration
136 */
137static void nss_n2h_mitigation_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
138{
Stephen Wangaed46332016-12-12 17:29:03 -0800139 uint32_t core_num = (uint32_t)(nss_ptr_t)app_data;
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530140 struct nss_top_instance *nss_top = &nss_top_main;
141 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
142
143 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
144
145 /*
146 * Error, hence we are not updating the nss_n2h_mitigate_en
147 */
148 nss_n2h_mitigationcp[core_num].response = NSS_FAILURE;
149 complete(&nss_n2h_mitigationcp[core_num].complete);
150 nss_warning("core%d: MITIGATION configuration failed : %d\n", core_num, nnm->cm.error);
151 return;
152 }
153
154 nss_info("core%d: MITIGATION configuration succeeded: %d\n", core_num, nnm->cm.error);
155
156 nss_ctx->n2h_mitigate_en = nnm->msg.mitigation_cfg.enable;
157 nss_n2h_mitigationcp[core_num].response = NSS_SUCCESS;
158 complete(&nss_n2h_mitigationcp[core_num].complete);
159}
160
161/*
162 * nss_n2h_buf_cfg_callback()
163 * call back function for pbuf configuration
164 */
165static void nss_n2h_bufs_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
166{
Stephen Wangaed46332016-12-12 17:29:03 -0800167 uint32_t core_num = (uint32_t)(nss_ptr_t)app_data;
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530168 unsigned int allocated_sz;
169
170 struct nss_top_instance *nss_top = &nss_top_main;
171 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
172
173 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
174 nss_n2h_bufcp[core_num].response = NSS_FAILURE;
175 nss_warning("core%d: buf configuration failed : %d\n", core_num, nnm->cm.error);
176 goto done;
177 }
178
179 nss_info("core%d: buf configuration succeeded: %d\n", core_num, nnm->cm.error);
180
181 allocated_sz = nnm->msg.buf_pool.nss_buf_page_size * nnm->msg.buf_pool.nss_buf_num_pages;
182 nss_ctx->buf_sz_allocated += allocated_sz;
183
184 nss_n2h_bufcp[core_num].response = NSS_SUCCESS;
185
186done:
187 complete(&nss_n2h_bufcp[core_num].complete);
188}
189
190/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700191 * nss_n2h_payload_stats_callback()
192 * It gets called response to payload accounting.
Vijay Dewangan488e5372014-12-29 21:40:11 -0800193 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700194static void nss_n2h_payload_stats_callback(void *app_data,
195 struct nss_n2h_msg *nnm)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800196{
Stephen Wangaed46332016-12-12 17:29:03 -0800197 uint32_t core_num = (uint32_t)(nss_ptr_t)app_data;
Saurabh Misra71034db2015-06-04 16:18:38 -0700198
Vijay Dewangan488e5372014-12-29 21:40:11 -0800199 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
200 struct nss_n2h_empty_pool_buf *nnepbcm;
201 nnepbcm = &nnm->msg.empty_pool_buf_cfg;
202
Saurabh Misra71034db2015-06-04 16:18:38 -0700203 nss_warning("%d: core empty pool buf set failure: %d\n",
204 core_num, nnm->cm.error);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800205 nss_n2h_nepbcfgp[core_num].response = NSS_FAILURE;
206 complete(&nss_n2h_nepbcfgp[core_num].complete);
207 return;
208 }
209
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700210 if (nnm->cm.type == NSS_TX_METADATA_TYPE_GET_WATER_MARK) {
211 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size =
Saurabh Misra71034db2015-06-04 16:18:38 -0700212 ntohl(nnm->msg.payload_info.pool_size);
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700213 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water =
Saurabh Misra71034db2015-06-04 16:18:38 -0700214 ntohl(nnm->msg.payload_info.low_water);
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700215 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water =
Saurabh Misra71034db2015-06-04 16:18:38 -0700216 ntohl(nnm->msg.payload_info.high_water);
217 }
218
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700219 if (nnm->cm.type == NSS_TX_METADATA_TYPE_GET_PAGED_WATER_MARK) {
220 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size =
221 ntohl(nnm->msg.paged_payload_info.pool_size);
222 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water =
223 ntohl(nnm->msg.paged_payload_info.low_water);
224 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water =
225 ntohl(nnm->msg.paged_payload_info.high_water);
226 }
227
Vijay Dewangan488e5372014-12-29 21:40:11 -0800228 nss_n2h_nepbcfgp[core_num].response = NSS_SUCCESS;
229 complete(&nss_n2h_nepbcfgp[core_num].complete);
230}
231
232/*
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530233 * nss_n2h_set_wifi_payloads_callback()
Cemil Coskun9165c762017-12-04 14:35:24 -0800234 * call back function for response to wifi pool configuration
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530235 *
236 */
237static void nss_n2h_set_wifi_payloads_callback(void *app_data,
238 struct nss_n2h_msg *nnm)
239{
Arunkumar Tba9b4a02016-11-07 11:41:14 +0530240 struct nss_ctx_instance *nss_ctx __maybe_unused = (struct nss_ctx_instance *)app_data;
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530241 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
242
243 nss_n2h_wp.response = NSS_FAILURE;
244 complete(&nss_n2h_wp.complete);
245 nss_warning("%p: wifi pool configuration failed : %d\n", nss_ctx,
246 nnm->cm.error);
247 return;
248 }
249
250 nss_info("%p: wifi payload configuration succeeded: %d\n", nss_ctx,
251 nnm->cm.error);
252 nss_n2h_wp.response = NSS_SUCCESS;
253 complete(&nss_n2h_wp.complete);
254}
255
256/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700257 * nss_n2h_get_payload_info()
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700258 * Gets Payload information.
Vijay Dewangan488e5372014-12-29 21:40:11 -0800259 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700260static int nss_n2h_get_payload_info(nss_ptr_t core_num, struct nss_n2h_msg *nnm, struct nss_n2h_payload_info *nnepbcm)
Saurabh Misra71034db2015-06-04 16:18:38 -0700261{
262 struct nss_top_instance *nss_top = &nss_top_main;
263 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
Saurabh Misra71034db2015-06-04 16:18:38 -0700264 nss_tx_status_t nss_tx_status;
265 int ret = NSS_FAILURE;
266
267 /*
268 * Note that semaphore should be already held.
269 */
270
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700271 nss_tx_status = nss_n2h_tx_msg(nss_ctx, nnm);
Saurabh Misra71034db2015-06-04 16:18:38 -0700272
273 if (nss_tx_status != NSS_TX_SUCCESS) {
Stephen Wangaed46332016-12-12 17:29:03 -0800274 nss_warning("%p: core %d nss_tx error errorn", nss_ctx, (int)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700275 return NSS_FAILURE;
276 }
277
278 /*
279 * Blocking call, wait till we get ACK for this msg.
280 */
281 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
282 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
283 if (ret == 0) {
Stephen Wangaed46332016-12-12 17:29:03 -0800284 nss_warning("%p: core %d waiting for ack timed out\n", nss_ctx, (int)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700285 return NSS_FAILURE;
286 }
287
288 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
Stephen Wangaed46332016-12-12 17:29:03 -0800289 nss_warning("%p: core %d response returned failure\n", nss_ctx, (int)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700290 return NSS_FAILURE;
291 }
292
293 return NSS_SUCCESS;
294}
295
296/*
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700297 * nss_n2h_get_default_payload_info()
298 * Gets the default payload information.
299 */
300static int nss_n2h_get_default_payload_info(nss_ptr_t core_num)
301{
302 struct nss_n2h_msg nnm;
303
304 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
305 NSS_TX_METADATA_TYPE_GET_WATER_MARK,
306 sizeof(struct nss_n2h_payload_info),
307 nss_n2h_payload_stats_callback,
308 (void *)core_num);
309
310 return nss_n2h_get_payload_info(core_num, &nnm,
311 &nnm.msg.payload_info);
312}
313
314/*
315 * nss_n2h_get_paged_payload_info()
316 * Gets the paged payload information.
317 */
318static int nss_n2h_get_paged_payload_info(nss_ptr_t core_num)
319{
320 struct nss_n2h_msg nnm;
321
322 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
323 NSS_TX_METADATA_TYPE_GET_PAGED_WATER_MARK,
324 sizeof(struct nss_n2h_payload_info),
325 nss_n2h_payload_stats_callback,
326 (void *)core_num);
327
328 return nss_n2h_get_payload_info(core_num, &nnm,
329 &nnm.msg.paged_payload_info);
330}
331
332/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700333 * nss_n2h_set_empty_pool_buf()
334 * Sets empty pool buffer
335 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700336static int nss_n2h_set_empty_pool_buf(struct ctl_table *ctl, int write,
Saurabh Misra71034db2015-06-04 16:18:38 -0700337 void __user *buffer,
338 size_t *lenp, loff_t *ppos,
Stephen Wangaed46332016-12-12 17:29:03 -0800339 nss_ptr_t core_num, int *new_val)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800340{
341 struct nss_top_instance *nss_top = &nss_top_main;
342 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
343 struct nss_n2h_msg nnm;
344 struct nss_n2h_empty_pool_buf *nnepbcm;
345 nss_tx_status_t nss_tx_status;
346 int ret = NSS_FAILURE;
347
348 /*
349 * Acquiring semaphore
350 */
351 down(&nss_n2h_nepbcfgp[core_num].sem);
352
353 /*
354 * Take snap shot of current value
355 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700356 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size = *new_val;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800357
Saurabh Misra71034db2015-06-04 16:18:38 -0700358 if (!write) {
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700359 ret = nss_n2h_get_default_payload_info(core_num);
360 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size;
Saurabh Misra71034db2015-06-04 16:18:38 -0700361 if (ret == NSS_FAILURE) {
362 up(&nss_n2h_nepbcfgp[core_num].sem);
363 return -EBUSY;
364 }
365
366 up(&nss_n2h_nepbcfgp[core_num].sem);
367
368 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
369 return ret;
370 }
371
Vijay Dewangan488e5372014-12-29 21:40:11 -0800372 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
Saurabh Misra71034db2015-06-04 16:18:38 -0700373 if (ret) {
Vijay Dewangan488e5372014-12-29 21:40:11 -0800374 up(&nss_n2h_nepbcfgp[core_num].sem);
375 return ret;
376 }
377
Vijay Dewangan488e5372014-12-29 21:40:11 -0800378 if ((*new_val < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700379 nss_warning("%p: core %d setting %d < min number of buffer",
Stephen Wangaed46332016-12-12 17:29:03 -0800380 nss_ctx, (int)core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800381 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800382 }
383
384 nss_info("%p: core %d number of empty pool buffer is : %d\n",
Stephen Wangaed46332016-12-12 17:29:03 -0800385 nss_ctx, (int)core_num, *new_val);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800386
387 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
388 NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG,
389 sizeof(struct nss_n2h_empty_pool_buf),
Saurabh Misra71034db2015-06-04 16:18:38 -0700390 nss_n2h_payload_stats_callback,
Stephen Wangaed46332016-12-12 17:29:03 -0800391 (nss_ptr_t *)core_num);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800392
393 nnepbcm = &nnm.msg.empty_pool_buf_cfg;
394 nnepbcm->pool_size = htonl(*new_val);
395 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
396
397 if (nss_tx_status != NSS_TX_SUCCESS) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700398 nss_warning("%p: core %d nss_tx error empty pool buffer: %d\n",
Stephen Wangaed46332016-12-12 17:29:03 -0800399 nss_ctx, (int)core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800400 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800401 }
402
403 /*
404 * Blocking call, wait till we get ACK for this msg.
405 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700406 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
407 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
Vijay Dewangan488e5372014-12-29 21:40:11 -0800408 if (ret == 0) {
Stephen Wangaed46332016-12-12 17:29:03 -0800409 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx, (int)core_num);
Stephen Wang06761022015-03-03 16:38:42 -0800410 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800411 }
412
413 /*
414 * ACK/NACK received from NSS FW
415 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
416 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
417 */
418 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
Stephen Wang06761022015-03-03 16:38:42 -0800419 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800420 }
421
422 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700423 return 0;
Stephen Wang06761022015-03-03 16:38:42 -0800424
425failure:
426 /*
427 * Restore the current_value to its previous state
428 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700429 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size;
430 up(&nss_n2h_nepbcfgp[core_num].sem);
431 return NSS_FAILURE;
432}
433
434/*
435 * nss_n2h_set_empty_paged_pool_buf()
436 * Sets empty paged pool buffer
437 */
438static int nss_n2h_set_empty_paged_pool_buf(struct ctl_table *ctl, int write,
439 void __user *buffer,
440 size_t *lenp, loff_t *ppos,
441 nss_ptr_t core_num, int *new_val)
442{
443 struct nss_top_instance *nss_top = &nss_top_main;
444 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
445 struct nss_n2h_msg nnm;
446 struct nss_n2h_empty_pool_buf *nneppbcm;
447 nss_tx_status_t nss_tx_status;
448 int ret = NSS_FAILURE;
449
450 /*
451 * Acquiring semaphore
452 */
453 down(&nss_n2h_nepbcfgp[core_num].sem);
454
455 /*
456 * Take snap shot of current value
457 */
458 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size = *new_val;
459
460 if (!write) {
461 ret = nss_n2h_get_paged_payload_info(core_num);
462 *new_val = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size;
463 if (ret == NSS_FAILURE) {
464 up(&nss_n2h_nepbcfgp[core_num].sem);
465 return -EBUSY;
466 }
467
468 up(&nss_n2h_nepbcfgp[core_num].sem);
469
470 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
471 return ret;
472 }
473
474 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
475 if (ret) {
476 up(&nss_n2h_nepbcfgp[core_num].sem);
477 return ret;
478 }
479
480 if ((*new_val < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
481 nss_warning("%p: core %d setting %d < min number of buffer",
482 nss_ctx, (int)core_num, *new_val);
483 goto failure;
484 }
485
486 nss_info("%p: core %d number of empty paged pool buffer is : %d\n",
487 nss_ctx, (int)core_num, *new_val);
488
489 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
490 NSS_TX_METADATA_TYPE_N2H_EMPTY_PAGED_POOL_BUF_CFG,
491 sizeof(struct nss_n2h_empty_pool_buf),
492 nss_n2h_payload_stats_callback,
493 (nss_ptr_t *)core_num);
494
495 nneppbcm = &nnm.msg.empty_pool_buf_cfg;
496 nneppbcm->pool_size = htonl(*new_val);
497 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
498
499 if (nss_tx_status != NSS_TX_SUCCESS) {
500 nss_warning("%p: core %d nss_tx error empty paged pool buffer: %d\n",
501 nss_ctx, (int)core_num, *new_val);
502 goto failure;
503 }
504
505 /*
506 * Blocking call, wait till we get ACK for this msg.
507 */
508 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
509 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
510 if (ret == 0) {
511 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx, (int)core_num);
512 goto failure;
513 }
514
515 /*
516 * ACK/NACK received from NSS FW
517 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
518 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
519 */
520 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
521 goto failure;
522 }
523
524 up(&nss_n2h_nepbcfgp[core_num].sem);
525 return 0;
526
527failure:
528 /*
529 * Restore the current_value to its previous state
530 */
531 *new_val = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size;
Saurabh Misra71034db2015-06-04 16:18:38 -0700532 up(&nss_n2h_nepbcfgp[core_num].sem);
533 return NSS_FAILURE;
534}
535
536/*
537 * nss_n2h_set_water_mark()
538 * Sets water mark for N2H SOS
539 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700540static int nss_n2h_set_water_mark(struct ctl_table *ctl, int write,
Saurabh Misra71034db2015-06-04 16:18:38 -0700541 void __user *buffer,
542 size_t *lenp, loff_t *ppos,
Stephen Wangaed46332016-12-12 17:29:03 -0800543 uint32_t core_num, int *low, int *high)
Saurabh Misra71034db2015-06-04 16:18:38 -0700544{
545 struct nss_top_instance *nss_top = &nss_top_main;
546 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
547 struct nss_n2h_msg nnm;
548 struct nss_n2h_water_mark *wm;
549 nss_tx_status_t nss_tx_status;
550 int ret = NSS_FAILURE;
551
552 /*
553 * Acquiring semaphore
554 */
555 down(&nss_n2h_nepbcfgp[core_num].sem);
556
557 /*
558 * Take snap shot of current value
559 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700560 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water = *low;
561 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water = *high;
Saurabh Misra71034db2015-06-04 16:18:38 -0700562
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700563 if (!write || *low == -1 || *high == -1) {
564 ret = nss_n2h_get_default_payload_info(core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700565 if (ret == NSS_FAILURE) {
566 up(&nss_n2h_nepbcfgp[core_num].sem);
567 return -EBUSY;
568 }
569
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700570 *low = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water;
571 *high = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water;
Saurabh Misra71034db2015-06-04 16:18:38 -0700572 }
573
574 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700575 if (!write || ret) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700576 up(&nss_n2h_nepbcfgp[core_num].sem);
577 return ret;
578 }
579
Saurabh Misra71034db2015-06-04 16:18:38 -0700580 if ((*low < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) ||
581 (*high < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
582 nss_warning("%p: core %d setting %d, %d < min number of buffer",
583 nss_ctx, core_num, *low, *high);
584 goto failure;
585 }
586
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530587 if ((*low > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ) ||
588 (*high > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700589 nss_warning("%p: core %d setting %d, %d is > upper limit",
590 nss_ctx, core_num, *low, *high);
591 goto failure;
592 }
593
594 if (*low > *high) {
595 nss_warning("%p: core %d setting low %d is more than high %d",
596 nss_ctx, core_num, *low, *high);
597 goto failure;
598 }
599
600 nss_info("%p: core %d number of low : %d and high : %d\n",
601 nss_ctx, core_num, *low, *high);
602
603 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
604 NSS_TX_METADATA_TYPE_SET_WATER_MARK,
605 sizeof(struct nss_n2h_water_mark),
606 nss_n2h_payload_stats_callback,
Stephen Wangaed46332016-12-12 17:29:03 -0800607 (void *)(nss_ptr_t)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700608
609 wm = &nnm.msg.wm;
610 wm->low_water = htonl(*low);
611 wm->high_water = htonl(*high);
612 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
613
614 if (nss_tx_status != NSS_TX_SUCCESS) {
615 nss_warning("%p: core %d nss_tx error setting : %d, %d\n",
616 nss_ctx, core_num, *low, *high);
617 goto failure;
618 }
619
620 /*
621 * Blocking call, wait till we get ACK for this msg.
622 */
623 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
624 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
625 if (ret == 0) {
626 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
627 core_num);
628 goto failure;
629 }
630
631 /*
632 * ACK/NACK received from NSS FW
633 */
634 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response)
635 goto failure;
636
637 up(&nss_n2h_nepbcfgp[core_num].sem);
638 return NSS_SUCCESS;
639
640failure:
641 /*
642 * Restore the current_value to its previous state
643 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700644 *low = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water;
645 *high = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water;
646 up(&nss_n2h_nepbcfgp[core_num].sem);
647 return -EINVAL;
648}
649
650/*
651 * nss_n2h_set_paged_water_mark()
652 * Sets water mark for paged pool N2H SOS
653 */
654static int nss_n2h_set_paged_water_mark(struct ctl_table *ctl, int write,
655 void __user *buffer,
656 size_t *lenp, loff_t *ppos,
657 uint32_t core_num, int *low, int *high)
658{
659 struct nss_top_instance *nss_top = &nss_top_main;
660 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
661 struct nss_n2h_msg nnm;
662 struct nss_n2h_water_mark *pwm;
663 nss_tx_status_t nss_tx_status;
664 int ret = NSS_FAILURE;
665
666 /*
667 * Acquiring semaphore
668 */
669 down(&nss_n2h_nepbcfgp[core_num].sem);
670
671 /*
672 * Take snap shot of current value
673 */
674 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water = *low;
675 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water = *high;
676
677 if (!write || *low == -1 || *high == -1) {
678 ret = nss_n2h_get_paged_payload_info(core_num);
679 if (ret == NSS_FAILURE) {
680 up(&nss_n2h_nepbcfgp[core_num].sem);
681 return -EBUSY;
682 }
683
684 *low = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water;
685 *high = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water;
686 }
687
688 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
689 if (!write || ret) {
690 up(&nss_n2h_nepbcfgp[core_num].sem);
691 return ret;
692 }
693
694 if ((*low < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) ||
695 (*high < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
696 nss_warning("%p: core %d setting %d, %d < min number of buffer",
697 nss_ctx, core_num, *low, *high);
698 goto failure;
699 }
700
701 if ((*low > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ) ||
702 (*high > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) {
703 nss_warning("%p: core %d setting %d, %d is > upper limit",
704 nss_ctx, core_num, *low, *high);
705 goto failure;
706 }
707
708 if (*low > *high) {
709 nss_warning("%p: core %d setting low %d is more than high %d",
710 nss_ctx, core_num, *low, *high);
711 goto failure;
712 }
713
714 nss_info("%p: core %d number of low : %d and high : %d\n",
715 nss_ctx, core_num, *low, *high);
716
717 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
718 NSS_TX_METADATA_TYPE_SET_PAGED_WATER_MARK,
719 sizeof(struct nss_n2h_water_mark),
720 nss_n2h_payload_stats_callback,
721 (void *)(nss_ptr_t)core_num);
722
723 pwm = &nnm.msg.wm_paged;
724 pwm->low_water = htonl(*low);
725 pwm->high_water = htonl(*high);
726 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
727
728 if (nss_tx_status != NSS_TX_SUCCESS) {
729 nss_warning("%p: core %d nss_tx error setting : %d, %d\n",
730 nss_ctx, core_num, *low, *high);
731 goto failure;
732 }
733
734 /*
735 * Blocking call, wait till we get ACK for this msg.
736 */
737 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
738 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
739 if (ret == 0) {
740 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
741 core_num);
742 goto failure;
743 }
744
745 /*
746 * ACK/NACK received from NSS FW
747 */
748 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response)
749 goto failure;
750
751 up(&nss_n2h_nepbcfgp[core_num].sem);
752 return NSS_SUCCESS;
753
754failure:
755 /*
756 * Restore the current_value to its previous state
757 */
758 *low = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water;
759 *high = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water;
Stephen Wang06761022015-03-03 16:38:42 -0800760 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700761 return -EINVAL;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800762}
763
764/*
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530765 * nss_n2h_cfg_wifi_pool()
766 * Sets number of wifi payloads to adjust high water mark for N2H SoS
767 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700768static int nss_n2h_cfg_wifi_pool(struct ctl_table *ctl, int write,
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530769 void __user *buffer,
770 size_t *lenp, loff_t *ppos,
771 int *payloads)
772{
773 struct nss_top_instance *nss_top = &nss_top_main;
774 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
775 struct nss_n2h_msg nnm;
776 struct nss_n2h_wifi_payloads *wp;
777 nss_tx_status_t nss_tx_status;
778 int ret = NSS_FAILURE;
779
780 /*
781 * Acquiring semaphore
782 */
783 down(&nss_n2h_wp.sem);
784
785 if (!write) {
786 *payloads = nss_n2h_wp.wifi_pool;
787
788 up(&nss_n2h_wp.sem);
789 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
790 return ret;
791 }
792
793 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
794 if (ret) {
795 up(&nss_n2h_wp.sem);
796 return ret;
797 }
798
799 /*
800 * If payloads parameter is not set, we do
801 * nothing.
802 */
803 if (*payloads == -1)
804 goto failure;
805
806 if ((*payloads < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
807 nss_warning("%p: wifi setting %d < min number of buffer",
808 nss_ctx, *payloads);
809 goto failure;
810 }
811
812 if ((*payloads > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) {
813 nss_warning("%p: wifi setting %d > max number of buffer",
814 nss_ctx, *payloads);
815 goto failure;
816 }
817
818 nss_info("%p: wifi payloads : %d\n",
819 nss_ctx, *payloads);
820
821 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
822 NSS_TX_METADATA_TYPE_N2H_WIFI_POOL_BUF_CFG,
823 sizeof(struct nss_n2h_wifi_payloads),
824 nss_n2h_set_wifi_payloads_callback,
825 (void *)nss_ctx);
826
827 wp = &nnm.msg.wp;
828 wp->payloads = htonl(*payloads);
829 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
830
831 if (nss_tx_status != NSS_TX_SUCCESS) {
832 nss_warning("%p: wifi setting %d nss_tx error",
833 nss_ctx, *payloads);
834 goto failure;
835 }
836
837 /*
838 * Blocking call, wait till we get ACK for this msg.
839 */
840 ret = wait_for_completion_timeout(&nss_n2h_wp.complete,
841 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
842 if (ret == 0) {
843 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
844 goto failure;
845 }
846
847 /*
848 * ACK/NACK received from NSS FW
849 */
850 if (NSS_FAILURE == nss_n2h_wp.response)
851 goto failure;
852
853 up(&nss_n2h_wp.sem);
854 return NSS_SUCCESS;
855
856failure:
857 up(&nss_n2h_wp.sem);
858 return -EINVAL;
859}
860
861/*
Vijay Dewangan488e5372014-12-29 21:40:11 -0800862 * nss_n2h_empty_pool_buf_core1_handler()
863 * Sets the number of empty buffer for core 1
864 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700865static int nss_n2h_empty_pool_buf_cfg_core1_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700866 int write, void __user *buffer,
867 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800868{
869 return nss_n2h_set_empty_pool_buf(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700870 NSS_CORE_1, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800871}
872
873/*
874 * nss_n2h_empty_pool_buf_core0_handler()
875 * Sets the number of empty buffer for core 0
876 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700877static int nss_n2h_empty_pool_buf_cfg_core0_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700878 int write, void __user *buffer,
879 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800880{
881 return nss_n2h_set_empty_pool_buf(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700882 NSS_CORE_0, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0]);
883}
884
885/*
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700886 * nss_n2h_empty_paged_pool_buf_cfg_core1_handler()
887 * Sets the number of empty paged buffer for core 1
888 */
889static int nss_n2h_empty_paged_pool_buf_cfg_core1_handler(struct ctl_table *ctl,
890 int write, void __user *buffer,
891 size_t *lenp, loff_t *ppos)
892{
893 return nss_n2h_set_empty_paged_pool_buf(ctl, write, buffer, lenp, ppos,
894 NSS_CORE_1, &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_1]);
895}
896
897/*
898 * nss_n2h_empty_paged_pool_buf_cfg_core0_handler()
899 * Sets the number of empty paged buffer for core 0
900 */
901static int nss_n2h_empty_paged_pool_buf_cfg_core0_handler(struct ctl_table *ctl,
902 int write, void __user *buffer,
903 size_t *lenp, loff_t *ppos)
904{
905 return nss_n2h_set_empty_paged_pool_buf(ctl, write, buffer, lenp, ppos,
906 NSS_CORE_0, &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0]);
907}
908
909/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700910 * nss_n2h_water_mark_core1_handler()
911 * Sets water mark for core 1
912 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700913static int nss_n2h_water_mark_core1_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700914 int write, void __user *buffer,
915 size_t *lenp, loff_t *ppos)
916{
917 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
918 NSS_CORE_1, &nss_n2h_water_mark[NSS_CORE_1][0],
919 &nss_n2h_water_mark[NSS_CORE_1][1]);
920}
921
922/*
923 * nss_n2h_water_mark_core0_handler()
924 * Sets water mark for core 0
925 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700926static int nss_n2h_water_mark_core0_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700927 int write, void __user *buffer,
928 size_t *lenp, loff_t *ppos)
929{
930 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
931 NSS_CORE_0, &nss_n2h_water_mark[NSS_CORE_0][0],
932 &nss_n2h_water_mark[NSS_CORE_0][1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800933}
934
Vijay Dewangan634ce592015-01-07 17:21:09 -0800935/*
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700936 * nss_n2h_paged_water_mark_core1_handler()
937 * Sets paged water mark for core 1
938 */
939static int nss_n2h_paged_water_mark_core1_handler(struct ctl_table *ctl,
940 int write, void __user *buffer,
941 size_t *lenp, loff_t *ppos)
942{
943 return nss_n2h_set_paged_water_mark(ctl, write, buffer, lenp, ppos,
944 NSS_CORE_1, &nss_n2h_paged_water_mark[NSS_CORE_1][0],
945 &nss_n2h_paged_water_mark[NSS_CORE_1][1]);
946}
947
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700948/*
949 * nss_n2h_paged_water_mark_core0_handler()
950 * Sets paged water mark for core 0
951 */
952static int nss_n2h_paged_water_mark_core0_handler(struct ctl_table *ctl,
953 int write, void __user *buffer,
954 size_t *lenp, loff_t *ppos)
955{
956 return nss_n2h_set_paged_water_mark(ctl, write, buffer, lenp, ppos,
957 NSS_CORE_0, &nss_n2h_paged_water_mark[NSS_CORE_0][0],
958 &nss_n2h_paged_water_mark[NSS_CORE_0][1]);
959}
960
961/*
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530962 * nss_n2h_wifi_payloads_handler()
963 * Sets number of wifi payloads
964 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700965static int nss_n2h_wifi_payloads_handler(struct ctl_table *ctl,
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530966 int write, void __user *buffer,
967 size_t *lenp, loff_t *ppos)
968{
969 return nss_n2h_cfg_wifi_pool(ctl, write, buffer, lenp, ppos,
970 &nss_n2h_wifi_pool_buf_cfg);
971}
972
973/*
ratheesh kannothab436af2017-07-20 08:51:07 +0530974 * nss_n2h_update_queue_config_callback()
975 * Callback to handle the completion of queue config command
ratheesh kannoth024a6e82017-05-18 17:48:10 +0530976 */
ratheesh kannothab436af2017-07-20 08:51:07 +0530977static void nss_n2h_update_queue_config_callback(void *app_data, struct nss_n2h_msg *nim)
ratheesh kannoth024a6e82017-05-18 17:48:10 +0530978{
ratheesh kannothab436af2017-07-20 08:51:07 +0530979 if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
980 nss_warning("n2h Error response %d\n", nim->cm.response);
981 nss_n2h_q_cfg_pvt.response = NSS_TX_FAILURE;
982 } else {
983 nss_n2h_q_cfg_pvt.response = NSS_TX_SUCCESS;
984 }
985
986 complete(&nss_n2h_q_cfg_pvt.complete);
987}
988
989/*
990 * nss_n2h_update_queue_config_async()
991 * Asynchronous call to send pnode queue configuration.
992 */
993nss_tx_status_t nss_n2h_update_queue_config_async(struct nss_ctx_instance *nss_ctx, bool mq_en, uint16_t *qlimits)
994{
995
ratheesh kannoth024a6e82017-05-18 17:48:10 +0530996 struct nss_n2h_msg nnm;
997 struct nss_n2h_pnode_queue_config *cfg;
998 nss_tx_status_t status;
ratheesh kannoth024a6e82017-05-18 17:48:10 +0530999 int i;
1000
1001 if (!mq_en) {
1002 return NSS_TX_SUCCESS;
1003 }
1004
ratheesh kannoth93ba95c2017-07-13 15:52:52 +05301005 /*
1006 * MQ mode doesnot make any sense if number of priority queues in NSS
1007 * is 1
1008 */
1009 if (NSS_MAX_NUM_PRI <= 1) {
1010 return NSS_TX_SUCCESS;
1011 }
1012
ratheesh kannothab436af2017-07-20 08:51:07 +05301013 memset(&nnm, 0, sizeof(struct nss_n2h_msg));
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301014
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301015 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1016 NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG,
1017 sizeof(struct nss_n2h_pnode_queue_config), NULL, 0);
1018
ratheesh kannothab436af2017-07-20 08:51:07 +05301019 cfg = &nnm.msg.pn_q_cfg;
1020
1021 /*
Cemil Coskun9165c762017-12-04 14:35:24 -08001022 * Update limits
1023 */
ratheesh kannothab436af2017-07-20 08:51:07 +05301024 for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
1025 cfg->qlimits[i] = qlimits[i];
1026 }
1027 cfg->mq_en = true;
1028
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301029 status = nss_n2h_tx_msg(nss_ctx, &nnm);
1030 if (status != NSS_TX_SUCCESS) {
1031 nss_warning("%p: nss_tx error to send pnode queue config\n", nss_ctx);
1032 return status;
1033 }
1034
1035 return NSS_TX_SUCCESS;
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301036}
ratheesh kannothab436af2017-07-20 08:51:07 +05301037EXPORT_SYMBOL(nss_n2h_update_queue_config_async);
1038
1039/*
1040 * nss_n2h_update_queue_config_sync()
1041 * Synchronous call to send pnode queue configuration.
1042 */
1043nss_tx_status_t nss_n2h_update_queue_config_sync(struct nss_ctx_instance *nss_ctx, bool mq_en, uint16_t *qlimits)
1044{
1045
1046 struct nss_n2h_msg nnm;
1047 struct nss_n2h_pnode_queue_config *cfg;
1048 nss_tx_status_t status;
1049 int ret, i;
1050
1051 if (!mq_en) {
1052 return NSS_TX_SUCCESS;
1053 }
1054
ratheesh kannoth93ba95c2017-07-13 15:52:52 +05301055 /*
1056 * MQ mode doesnot make any sense if number of priority queues in NSS
1057 * is 1
1058 */
1059 if (NSS_MAX_NUM_PRI <= 1) {
1060 return NSS_TX_SUCCESS;
1061 }
1062
ratheesh kannothab436af2017-07-20 08:51:07 +05301063 memset(&nnm, 0, sizeof(struct nss_n2h_msg));
1064
1065 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1066 NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG,
1067 sizeof(struct nss_n2h_pnode_queue_config), nss_n2h_update_queue_config_callback, 0);
1068
1069 cfg = &nnm.msg.pn_q_cfg;
1070
1071 /*
Cemil Coskun9165c762017-12-04 14:35:24 -08001072 * Update limits
1073 */
ratheesh kannothab436af2017-07-20 08:51:07 +05301074 for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
1075 cfg->qlimits[i] = qlimits[i];
1076 }
1077 cfg->mq_en = true;
1078
1079 down(&nss_n2h_q_cfg_pvt.sem);
1080
1081 status = nss_n2h_tx_msg(nss_ctx, &nnm);
1082
1083 if (status != NSS_TX_SUCCESS) {
1084 nss_warning("%p: n2h_tx_msg failed\n", nss_ctx);
1085 up(&nss_n2h_q_cfg_pvt.sem);
1086 return status;
1087 }
1088 ret = wait_for_completion_timeout(&nss_n2h_q_cfg_pvt.complete, msecs_to_jiffies(NSS_N2H_TX_TIMEOUT));
1089
1090 if (!ret) {
1091 nss_warning("%p: Timeout expired for pnode queue config sync message\n", nss_ctx);
1092 nss_n2h_q_cfg_pvt.response = NSS_TX_FAILURE;
1093 }
1094
1095 status = nss_n2h_q_cfg_pvt.response;
1096 up(&nss_n2h_q_cfg_pvt.sem);
1097 return status;
1098}
1099EXPORT_SYMBOL(nss_n2h_update_queue_config_sync);
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301100
1101/*
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301102 * nss_n2h_mitigation_cfg()
1103 * Send Message to NSS to disable MITIGATION.
1104 */
Stephen Wang49b474b2016-03-25 10:40:30 -07001105static nss_tx_status_t nss_n2h_mitigation_cfg(struct nss_ctx_instance *nss_ctx, int enable_mitigation, nss_core_id_t core_num)
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301106{
1107 struct nss_n2h_msg nnm;
1108 struct nss_n2h_mitigation *mitigation_cfg;
1109 nss_tx_status_t nss_tx_status;
1110 int ret;
1111
1112 nss_assert(core_num < NSS_CORE_MAX);
1113
1114 down(&nss_n2h_mitigationcp[core_num].sem);
1115 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG,
1116 sizeof(struct nss_n2h_mitigation),
1117 nss_n2h_mitigation_cfg_callback,
1118 (void *)core_num);
1119
1120 mitigation_cfg = &nnm.msg.mitigation_cfg;
1121 mitigation_cfg->enable = enable_mitigation;
1122
1123 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1124
1125 if (nss_tx_status != NSS_TX_SUCCESS) {
1126 nss_warning("%p: nss_tx error setting mitigation\n", nss_ctx);
1127 goto failure;
1128 }
1129
1130 /*
1131 * Blocking call, wait till we get ACK for this msg.
1132 */
1133 ret = wait_for_completion_timeout(&nss_n2h_mitigationcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
1134 if (ret == 0) {
1135 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
1136 goto failure;
1137 }
1138
1139 /*
1140 * ACK/NACK received from NSS FW
1141 */
1142 if (NSS_FAILURE == nss_n2h_mitigationcp[core_num].response) {
1143 goto failure;
1144 }
1145
1146 up(&nss_n2h_mitigationcp[core_num].sem);
1147 return NSS_SUCCESS;
1148
1149failure:
1150 up(&nss_n2h_mitigationcp[core_num].sem);
1151 return NSS_FAILURE;
1152}
1153
1154static inline void nss_n2h_buf_pool_free(struct nss_n2h_buf_pool *buf_pool)
1155{
1156 int page_count;
1157 for (page_count = 0; page_count < buf_pool->nss_buf_num_pages; page_count++) {
Stephen Wang7df68832017-08-10 16:54:35 -07001158 kfree((void *)buf_pool->nss_buf_pool_vaddr[page_count]);
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301159 }
1160}
1161
1162/*
1163 * nss_n2h_buf_cfg()
1164 * Send Message to NSS to enable pbufs.
1165 */
Stephen Wang49b474b2016-03-25 10:40:30 -07001166static nss_tx_status_t nss_n2h_buf_pool_cfg(struct nss_ctx_instance *nss_ctx,
Tallapragada4b0161b2016-07-07 21:38:34 +05301167 int buf_pool_size, nss_core_id_t core_num)
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301168{
1169 static struct nss_n2h_msg nnm;
1170 struct nss_n2h_buf_pool *buf_pool;
1171 nss_tx_status_t nss_tx_status;
1172 int ret;
1173 int page_count;
1174 int num_pages = ALIGN(buf_pool_size, PAGE_SIZE)/PAGE_SIZE;
1175
1176 nss_assert(core_num < NSS_CORE_MAX);
1177
1178 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_METADATA_TYPE_N2H_ADD_BUF_POOL,
1179 sizeof(struct nss_n2h_buf_pool),
1180 nss_n2h_bufs_cfg_callback,
1181 (void *)core_num);
1182
1183 do {
1184
1185 down(&nss_n2h_bufcp[core_num].sem);
1186
1187 buf_pool = &nnm.msg.buf_pool;
1188 buf_pool->nss_buf_page_size = PAGE_SIZE;
1189
1190 for (page_count = 0; page_count < MAX_PAGES_PER_MSG && num_pages; page_count++, num_pages--) {
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301191 void *kern_addr = kzalloc(PAGE_SIZE, GFP_ATOMIC);
1192 if (!kern_addr) {
1193 BUG_ON(!page_count);
1194 break;
1195 }
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301196
Radha krishna Simha Jiguru60068fb2017-07-28 17:40:52 +05301197 kmemleak_not_leak(kern_addr);
Stephen Wang7df68832017-08-10 16:54:35 -07001198 buf_pool->nss_buf_pool_vaddr[page_count] = (nss_ptr_t)kern_addr;
Stephen Wangefd38512017-01-24 14:01:02 -08001199 buf_pool->nss_buf_pool_addr[page_count] = dma_map_single(nss_ctx->dev, kern_addr, PAGE_SIZE, DMA_TO_DEVICE);
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301200 }
1201
1202 buf_pool->nss_buf_num_pages = page_count;
1203 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1204 if (nss_tx_status != NSS_TX_SUCCESS) {
1205
1206 nss_n2h_buf_pool_free(buf_pool);
1207 nss_warning("%p: nss_tx error setting pbuf\n", nss_ctx);
1208 goto failure;
1209 }
1210
1211 /*
Cemil Coskun9165c762017-12-04 14:35:24 -08001212 * Blocking call, wait till we get ACK for this msg.
1213 */
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301214 ret = wait_for_completion_timeout(&nss_n2h_bufcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
1215 if (ret == 0) {
1216 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
1217 goto failure;
1218 }
1219
1220 /*
1221 * ACK/NACK received from NSS FW
1222 */
1223 if (NSS_FAILURE == nss_n2h_bufcp[core_num].response) {
1224
1225 nss_n2h_buf_pool_free(buf_pool);
1226 goto failure;
1227 }
1228
1229 up(&nss_n2h_bufcp[core_num].sem);
1230 } while(num_pages);
1231
1232 return NSS_SUCCESS;
1233failure:
1234 up(&nss_n2h_bufcp[core_num].sem);
1235 return NSS_FAILURE;
1236}
1237
Stephen Wang49b474b2016-03-25 10:40:30 -07001238
1239/*
1240 * nss_mitigation_handler()
1241 * Enable NSS MITIGATION
1242 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001243static int nss_n2h_mitigationcfg_core0_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
Stephen Wang49b474b2016-03-25 10:40:30 -07001244{
1245 struct nss_top_instance *nss_top = &nss_top_main;
1246 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_0];
1247 int ret;
1248
1249 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1250 if (ret) {
1251 return ret;
1252 }
1253
1254 /*
1255 * It's a read operation
1256 */
1257 if (!write) {
1258 return ret;
1259 }
1260
1261 if (!nss_n2h_core0_mitigation_cfg) {
1262 printk(KERN_INFO "Disabling NSS MITIGATION\n");
1263 nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_0);
1264 return 0;
1265 }
1266 printk(KERN_INFO "Invalid input value.Valid value is 0, Runtime re-enabling not supported\n");
1267 return -EINVAL;
1268}
1269
1270/*
1271 * nss_mitigation_handler()
1272 * Enable NSS MITIGATION
1273 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001274static int nss_n2h_mitigationcfg_core1_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
Stephen Wang49b474b2016-03-25 10:40:30 -07001275{
1276 struct nss_top_instance *nss_top = &nss_top_main;
1277 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_1];
1278 int ret;
1279
1280 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1281 if (ret) {
1282 return ret;
1283 }
1284
1285 /*
1286 * It's a read operation
1287 */
1288 if (!write) {
1289 return ret;
1290 }
1291
1292 if (!nss_n2h_core1_mitigation_cfg) {
1293 printk(KERN_INFO "Disabling NSS MITIGATION\n");
1294 nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_1);
1295 return 0;
1296 }
1297 printk(KERN_INFO "Invalid input value.Valid value is 0, Runtime re-enabling not supported\n");
1298 return -EINVAL;
1299}
1300
1301/*
1302 * nss_buf_handler()
1303 * Add extra NSS bufs from host memory
1304 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001305static int nss_n2h_buf_cfg_core0_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
Stephen Wang49b474b2016-03-25 10:40:30 -07001306{
1307 struct nss_top_instance *nss_top = &nss_top_main;
1308 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_0];
1309 int ret;
1310
1311 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1312 if (ret) {
1313 return ret;
1314 }
1315
1316 /*
1317 * It's a read operation
1318 */
1319 if (!write) {
1320 return ret;
1321 }
1322
1323 if (nss_ctx->buf_sz_allocated) {
1324 nss_n2h_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1325 return -EPERM;
1326 }
1327
1328 if ((nss_n2h_core0_add_buf_pool_size >= 1) && (nss_n2h_core0_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) {
1329 printk(KERN_INFO "configuring additional NSS pbufs\n");
1330 ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_n2h_core0_add_buf_pool_size, NSS_CORE_0);
1331 nss_n2h_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1332 printk(KERN_INFO "additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated);
1333 return ret;
1334 }
1335
1336 printk(KERN_INFO "Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE);
1337 return -EINVAL;
1338}
1339
1340/*
1341 * nss_n2h_buf_handler()
1342 * Add extra NSS bufs from host memory
1343 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001344static int nss_n2h_buf_cfg_core1_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
Stephen Wang49b474b2016-03-25 10:40:30 -07001345{
1346 struct nss_top_instance *nss_top = &nss_top_main;
1347 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_1];
1348 int ret;
1349
1350 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1351 if (ret) {
1352 return ret;
1353 }
1354
1355 /*
1356 * It's a read operation
1357 */
1358 if (!write) {
1359 return ret;
1360 }
1361
1362 if (nss_ctx->buf_sz_allocated) {
1363 nss_n2h_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1364 return -EPERM;
1365 }
1366
1367 if ((nss_n2h_core1_add_buf_pool_size >= 1) && (nss_n2h_core1_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) {
1368 printk(KERN_INFO "configuring additional NSS pbufs\n");
1369 ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_n2h_core1_add_buf_pool_size, NSS_CORE_1);
1370 nss_n2h_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1371 printk(KERN_INFO "additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated);
1372 return ret;
1373 }
1374
1375 printk(KERN_INFO "Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE);
1376 return -EINVAL;
1377}
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301378
Stephen Wang52e6d342016-03-29 15:02:33 -07001379static struct ctl_table nss_n2h_table[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001380 {
Saurabh Misra71034db2015-06-04 16:18:38 -07001381 .procname = "n2h_empty_pool_buf_core0",
1382 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0],
1383 .maxlen = sizeof(int),
1384 .mode = 0644,
1385 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core0_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -08001386 },
1387 {
Saurabh Misra71034db2015-06-04 16:18:38 -07001388 .procname = "n2h_empty_pool_buf_core1",
1389 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1],
1390 .maxlen = sizeof(int),
1391 .mode = 0644,
1392 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core1_handler,
1393 },
1394 {
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001395 .procname = "n2h_empty_paged_pool_buf_core0",
1396 .data = &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0],
1397 .maxlen = sizeof(int),
1398 .mode = 0644,
1399 .proc_handler = &nss_n2h_empty_paged_pool_buf_cfg_core0_handler,
1400 },
1401 {
1402 .procname = "n2h_empty_paged_pool_buf_core1",
1403 .data = &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_1],
1404 .maxlen = sizeof(int),
1405 .mode = 0644,
1406 .proc_handler = &nss_n2h_empty_paged_pool_buf_cfg_core1_handler,
1407 },
1408
1409 {
Saurabh Misra71034db2015-06-04 16:18:38 -07001410 .procname = "n2h_low_water_core0",
1411 .data = &nss_n2h_water_mark[NSS_CORE_0][0],
1412 .maxlen = sizeof(int),
1413 .mode = 0644,
1414 .proc_handler = &nss_n2h_water_mark_core0_handler,
1415 },
1416 {
1417 .procname = "n2h_low_water_core1",
1418 .data = &nss_n2h_water_mark[NSS_CORE_1][0],
1419 .maxlen = sizeof(int),
1420 .mode = 0644,
1421 .proc_handler = &nss_n2h_water_mark_core1_handler,
1422 },
1423 {
1424 .procname = "n2h_high_water_core0",
1425 .data = &nss_n2h_water_mark[NSS_CORE_0][1],
1426 .maxlen = sizeof(int),
1427 .mode = 0644,
1428 .proc_handler = &nss_n2h_water_mark_core0_handler,
1429 },
1430 {
1431 .procname = "n2h_high_water_core1",
1432 .data = &nss_n2h_water_mark[NSS_CORE_1][1],
1433 .maxlen = sizeof(int),
1434 .mode = 0644,
1435 .proc_handler = &nss_n2h_water_mark_core1_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -08001436 },
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +05301437 {
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001438 .procname = "n2h_paged_low_water_core0",
1439 .data = &nss_n2h_paged_water_mark[NSS_CORE_0][0],
1440 .maxlen = sizeof(int),
1441 .mode = 0644,
1442 .proc_handler = &nss_n2h_paged_water_mark_core0_handler,
1443 },
1444 {
1445 .procname = "n2h_paged_low_water_core1",
1446 .data = &nss_n2h_paged_water_mark[NSS_CORE_1][0],
1447 .maxlen = sizeof(int),
1448 .mode = 0644,
1449 .proc_handler = &nss_n2h_paged_water_mark_core1_handler,
1450 },
1451 {
1452 .procname = "n2h_paged_high_water_core0",
1453 .data = &nss_n2h_paged_water_mark[NSS_CORE_0][1],
1454 .maxlen = sizeof(int),
1455 .mode = 0644,
1456 .proc_handler = &nss_n2h_paged_water_mark_core0_handler,
1457 },
1458 {
1459 .procname = "n2h_paged_high_water_core1",
1460 .data = &nss_n2h_paged_water_mark[NSS_CORE_1][1],
1461 .maxlen = sizeof(int),
1462 .mode = 0644,
1463 .proc_handler = &nss_n2h_paged_water_mark_core1_handler,
1464 },
1465 {
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +05301466 .procname = "n2h_wifi_pool_buf",
1467 .data = &nss_n2h_wifi_pool_buf_cfg,
1468 .maxlen = sizeof(int),
1469 .mode = 0644,
1470 .proc_handler = &nss_n2h_wifi_payloads_handler,
1471 },
Stephen Wang49b474b2016-03-25 10:40:30 -07001472 {
Stephen Wang49b474b2016-03-25 10:40:30 -07001473 .procname = "mitigation_core0",
1474 .data = &nss_n2h_core0_mitigation_cfg,
1475 .maxlen = sizeof(int),
1476 .mode = 0644,
1477 .proc_handler = &nss_n2h_mitigationcfg_core0_handler,
1478 },
1479 {
1480 .procname = "mitigation_core1",
1481 .data = &nss_n2h_core1_mitigation_cfg,
1482 .maxlen = sizeof(int),
1483 .mode = 0644,
1484 .proc_handler = &nss_n2h_mitigationcfg_core1_handler,
1485 },
1486 {
1487 .procname = "extra_pbuf_core0",
1488 .data = &nss_n2h_core0_add_buf_pool_size,
1489 .maxlen = sizeof(int),
1490 .mode = 0644,
1491 .proc_handler = &nss_n2h_buf_cfg_core0_handler,
1492 },
1493 {
1494 .procname = "extra_pbuf_core1",
1495 .data = &nss_n2h_core1_add_buf_pool_size,
1496 .maxlen = sizeof(int),
1497 .mode = 0644,
1498 .proc_handler = &nss_n2h_buf_cfg_core1_handler,
1499 },
Vijay Dewangan488e5372014-12-29 21:40:11 -08001500
1501 { }
1502};
1503
Stephen Wang52e6d342016-03-29 15:02:33 -07001504static struct ctl_table nss_n2h_dir[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001505 {
1506 .procname = "n2hcfg",
1507 .mode = 0555,
1508 .child = nss_n2h_table,
1509 },
1510 { }
1511};
1512
Stephen Wang52e6d342016-03-29 15:02:33 -07001513static struct ctl_table nss_n2h_root_dir[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001514 {
1515 .procname = "nss",
1516 .mode = 0555,
1517 .child = nss_n2h_dir,
1518 },
1519 { }
1520};
1521
Stephen Wang52e6d342016-03-29 15:02:33 -07001522static struct ctl_table nss_n2h_root[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001523 {
1524 .procname = "dev",
1525 .mode = 0555,
1526 .child = nss_n2h_root_dir,
1527 },
1528 { }
1529};
1530
1531static struct ctl_table_header *nss_n2h_header;
1532
1533/*
Stephen Wang49b474b2016-03-25 10:40:30 -07001534 * nss_n2h_flush_payloads()
Cemil Coskun9165c762017-12-04 14:35:24 -08001535 * Sends a command down to NSS for flushing all payloads
Stephen Wang49b474b2016-03-25 10:40:30 -07001536 */
1537nss_tx_status_t nss_n2h_flush_payloads(struct nss_ctx_instance *nss_ctx)
1538{
1539 struct nss_n2h_msg nnm;
1540 struct nss_n2h_flush_payloads *nnflshpl;
1541 nss_tx_status_t nss_tx_status;
1542
1543 nnflshpl = &nnm.msg.flush_payloads;
1544
1545 /*
1546 * TODO: No additional information sent in message
1547 * as of now. Need to initialize message content accordingly
1548 * if needed.
1549 */
1550 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1551 NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS,
1552 sizeof(struct nss_n2h_flush_payloads),
1553 NULL,
1554 NULL);
1555
1556 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1557 if (nss_tx_status != NSS_TX_SUCCESS) {
1558 nss_warning("%p: failed to send flush payloads command to NSS\n",
1559 nss_ctx);
1560
1561 return NSS_TX_FAILURE;
1562 }
1563
1564 return NSS_TX_SUCCESS;
1565}
1566
1567/*
Vijay Dewangan488e5372014-12-29 21:40:11 -08001568 * nss_n2h_msg_init()
Stephen Wang49b474b2016-03-25 10:40:30 -07001569 * Initialize n2h message.
Vijay Dewangan488e5372014-12-29 21:40:11 -08001570 */
1571void nss_n2h_msg_init(struct nss_n2h_msg *nim, uint16_t if_num, uint32_t type,
Vijay Dewangan634ce592015-01-07 17:21:09 -08001572 uint32_t len, nss_n2h_msg_callback_t cb, void *app_data)
Vijay Dewangan488e5372014-12-29 21:40:11 -08001573{
1574 nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data);
1575}
1576
Vijay Dewangan488e5372014-12-29 21:40:11 -08001577/*
Vijay Dewangan488e5372014-12-29 21:40:11 -08001578 * nss_n2h_tx_msg()
Cemil Coskun9165c762017-12-04 14:35:24 -08001579 * Send messages to NSS n2h package.
Vijay Dewangan488e5372014-12-29 21:40:11 -08001580 */
1581nss_tx_status_t nss_n2h_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_n2h_msg *nnm)
1582{
Vijay Dewangan488e5372014-12-29 21:40:11 -08001583 struct nss_cmn_msg *ncm = &nnm->cm;
Vijay Dewangan488e5372014-12-29 21:40:11 -08001584
1585 /*
1586 * Sanity check the message
1587 */
1588 if (ncm->interface != NSS_N2H_INTERFACE) {
1589 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
1590 return NSS_TX_FAILURE;
1591 }
1592
1593 if (ncm->type >= NSS_METADATA_TYPE_N2H_MAX) {
1594 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
1595 return NSS_TX_FAILURE;
1596 }
1597
Stephen Wang3e2dbd12018-03-14 17:28:17 -07001598 return nss_core_send_cmd(nss_ctx, nnm, sizeof(*nnm), NSS_NBUF_PAYLOAD_SIZE);
Vijay Dewangan488e5372014-12-29 21:40:11 -08001599}
1600
Vijay Dewangan488e5372014-12-29 21:40:11 -08001601/*
1602 * nss_n2h_notify_register()
1603 * Register to received N2H events.
1604 *
1605 * NOTE: Do we want to pass an nss_ctx here so that we can register for n2h on any core?
1606 */
1607struct nss_ctx_instance *nss_n2h_notify_register(int core, nss_n2h_msg_callback_t cb, void *app_data)
1608{
1609 if (core >= NSS_MAX_CORES) {
1610 nss_warning("Input core number %d is wrong \n", core);
1611 return NULL;
1612 }
1613 /*
1614 * TODO: We need to have a new array in support of the new API
1615 * TODO: If we use a per-context array, we would move the array into nss_ctx based.
1616 */
1617 nss_n2h_rd[core].n2h_callback = cb;
1618 nss_n2h_rd[core].app_data = app_data;
1619 return &nss_top_main.nss[core];
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301620}
1621
1622/*
1623 * nss_n2h_register_handler()
1624 */
Thomas Wu91f4bdf2017-06-09 12:03:02 -07001625void nss_n2h_register_handler(struct nss_ctx_instance *nss_ctx)
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301626{
ratheesh kannothab436af2017-07-20 08:51:07 +05301627 sema_init(&nss_n2h_q_cfg_pvt.sem, 1);
1628 init_completion(&nss_n2h_q_cfg_pvt.complete);
1629
Thomas Wu91f4bdf2017-06-09 12:03:02 -07001630 nss_core_register_handler(nss_ctx, NSS_N2H_INTERFACE, nss_n2h_interface_handler, NULL);
Yu Huang8c107082017-07-24 14:58:26 -07001631
1632 nss_n2h_stats_dentry_create();
Stephen Wang49b474b2016-03-25 10:40:30 -07001633}
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -07001634
Stephen Wang49b474b2016-03-25 10:40:30 -07001635/*
1636 * nss_n2h_register_sysctl()
1637 */
1638void nss_n2h_register_sysctl(void)
1639{
Vijay Dewangan634ce592015-01-07 17:21:09 -08001640 /*
1641 * RPS sema init
1642 */
1643 sema_init(&nss_n2h_rcp.sem, 1);
1644 init_completion(&nss_n2h_rcp.complete);
1645
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301646 /*
1647 * MITIGATION sema init for core0
1648 */
1649 sema_init(&nss_n2h_mitigationcp[NSS_CORE_0].sem, 1);
1650 init_completion(&nss_n2h_mitigationcp[NSS_CORE_0].complete);
1651
1652 /*
1653 * MITIGATION sema init for core1
1654 */
1655 sema_init(&nss_n2h_mitigationcp[NSS_CORE_1].sem, 1);
1656 init_completion(&nss_n2h_mitigationcp[NSS_CORE_1].complete);
1657
1658 /*
1659 * PBUF addition sema init for core0
1660 */
1661 sema_init(&nss_n2h_bufcp[NSS_CORE_0].sem, 1);
1662 init_completion(&nss_n2h_bufcp[NSS_CORE_0].complete);
1663
1664 /*
1665 * PBUF addition sema init for core1
1666 */
1667 sema_init(&nss_n2h_bufcp[NSS_CORE_1].sem, 1);
1668 init_completion(&nss_n2h_bufcp[NSS_CORE_1].complete);
Vijay Dewangan634ce592015-01-07 17:21:09 -08001669
Stephen Wang49b474b2016-03-25 10:40:30 -07001670 /*
1671 * Core0
1672 */
1673 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_0].sem, 1);
1674 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_0].complete);
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001675 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.pool_size =
Stephen Wang49b474b2016-03-25 10:40:30 -07001676 nss_n2h_empty_pool_buf_cfg[NSS_CORE_0];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001677 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.low_water =
Stephen Wang49b474b2016-03-25 10:40:30 -07001678 nss_n2h_water_mark[NSS_CORE_0][0];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001679 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.high_water =
Stephen Wang49b474b2016-03-25 10:40:30 -07001680 nss_n2h_water_mark[NSS_CORE_0][1];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001681 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.pool_size =
1682 nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0];
1683 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.low_water =
1684 nss_n2h_paged_water_mark[NSS_CORE_0][0];
1685 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.high_water =
1686 nss_n2h_paged_water_mark[NSS_CORE_0][1];
1687
Stephen Wang49b474b2016-03-25 10:40:30 -07001688 /*
1689 * Core1
1690 */
1691 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_1].sem, 1);
1692 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_1].complete);
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001693 nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool_info.pool_size =
Stephen Wang49b474b2016-03-25 10:40:30 -07001694 nss_n2h_empty_pool_buf_cfg[NSS_CORE_1];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001695 nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool_info.low_water =
Stephen Wang49b474b2016-03-25 10:40:30 -07001696 nss_n2h_water_mark[NSS_CORE_1][0];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001697 nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool_info.high_water =
Stephen Wang49b474b2016-03-25 10:40:30 -07001698 nss_n2h_water_mark[NSS_CORE_1][1];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001699 nss_n2h_nepbcfgp[NSS_CORE_1].empty_paged_buf_pool_info.pool_size =
1700 nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_1];
1701 nss_n2h_nepbcfgp[NSS_CORE_1].empty_paged_buf_pool_info.low_water =
1702 nss_n2h_paged_water_mark[NSS_CORE_1][0];
1703 nss_n2h_nepbcfgp[NSS_CORE_1].empty_paged_buf_pool_info.high_water =
1704 nss_n2h_paged_water_mark[NSS_CORE_1][1];
1705
Stephen Wang49b474b2016-03-25 10:40:30 -07001706 /*
1707 * WiFi pool buf cfg sema init
1708 */
1709 sema_init(&nss_n2h_wp.sem, 1);
1710 init_completion(&nss_n2h_wp.complete);
1711
Vijay Dewangan488e5372014-12-29 21:40:11 -08001712 nss_n2h_notify_register(NSS_CORE_0, NULL, NULL);
1713 nss_n2h_notify_register(NSS_CORE_1, NULL, NULL);
1714
Stephen Wang49b474b2016-03-25 10:40:30 -07001715 /*
1716 * Register sysctl table.
1717 */
1718 nss_n2h_header = register_sysctl_table(nss_n2h_root);
1719}
1720
1721/*
1722 * nss_n2h_unregister_sysctl()
1723 * Unregister sysctl specific to n2h
1724 */
1725void nss_n2h_unregister_sysctl(void)
1726{
1727 /*
1728 * Unregister sysctl table.
1729 */
1730 if (nss_n2h_header) {
1731 unregister_sysctl_table(nss_n2h_header);
1732 }
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301733}
Vijay Dewangan488e5372014-12-29 21:40:11 -08001734
1735EXPORT_SYMBOL(nss_n2h_notify_register);