blob: e6c769753baf20f5d29dbdddcd6e87eaaabd3b23 [file] [log] [blame]
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301/*
2 **************************************************************************
Amit Guptaca2ea682019-01-24 17:18:46 +05303 * Copyright (c) 2013-2019, 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
Aniruddha Paulfc578bd2019-03-18 16:59:22 +053025#define NSS_N2H_MAX_BUF_POOL_SIZE (1024 * 1024 * 20) /* 20MB */
Saurabh Misra71034db2015-06-04 16:18:38 -070026#define NSS_N2H_MIN_EMPTY_POOL_BUF_SZ 32
Aniruddha Paulfc578bd2019-03-18 16:59:22 +053027#define NSS_N2H_MAX_EMPTY_POOL_BUF_SZ 131072
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;
Shashank Balashankar4162f572018-08-21 13:32:34 -070040int nss_n2h_queue_limit[NSS_MAX_CORES] __read_mostly = {NSS_DEFAULT_QUEUE_LIMIT, NSS_DEFAULT_QUEUE_LIMIT};
Sakthi Vignesh Radhakrishnanf9823102019-03-05 15:38:36 -080041int nss_n2h_host_bp_config[NSS_MAX_CORES] __read_mostly;
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053042
Vijay Dewangan488e5372014-12-29 21:40:11 -080043struct nss_n2h_registered_data {
44 nss_n2h_msg_callback_t n2h_callback;
45 void *app_data;
46};
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053047
Vijay Dewangan488e5372014-12-29 21:40:11 -080048static struct nss_n2h_cfg_pvt nss_n2h_nepbcfgp[NSS_MAX_CORES];
49static struct nss_n2h_registered_data nss_n2h_rd[NSS_MAX_CORES];
Vijay Dewangan634ce592015-01-07 17:21:09 -080050static struct nss_n2h_cfg_pvt nss_n2h_rcp;
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +053051static struct nss_n2h_cfg_pvt nss_n2h_mitigationcp[NSS_CORE_MAX];
52static struct nss_n2h_cfg_pvt nss_n2h_bufcp[NSS_CORE_MAX];
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +053053static struct nss_n2h_cfg_pvt nss_n2h_wp;
ratheesh kannothab436af2017-07-20 08:51:07 +053054static struct nss_n2h_cfg_pvt nss_n2h_q_cfg_pvt;
Shashank Balashankar4162f572018-08-21 13:32:34 -070055static struct nss_n2h_cfg_pvt nss_n2h_q_lim_pvt;
Sakthi Vignesh Radhakrishnanf9823102019-03-05 15:38:36 -080056static struct nss_n2h_cfg_pvt nss_n2h_host_bp_cfg_pvt;
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053057
58/*
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -070059 * nss_n2h_interface_handler()
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053060 * Handle NSS -> HLOS messages for N2H node
61 */
Vijay Dewangan634ce592015-01-07 17:21:09 -080062static void nss_n2h_interface_handler(struct nss_ctx_instance *nss_ctx,
63 struct nss_cmn_msg *ncm,
Arunkumar Tba9b4a02016-11-07 11:41:14 +053064 void *app_data)
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053065{
66 struct nss_n2h_msg *nnm = (struct nss_n2h_msg *)ncm;
Vijay Dewangan488e5372014-12-29 21:40:11 -080067 nss_n2h_msg_callback_t cb;
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053068
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -070069 BUG_ON(ncm->interface != NSS_N2H_INTERFACE);
70
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053071 /*
72 * Is this a valid request/response packet?
73 */
74 if (nnm->cm.type >= NSS_METADATA_TYPE_N2H_MAX) {
75 nss_warning("%p: received invalid message %d for Offload stats interface", nss_ctx, nnm->cm.type);
76 return;
77 }
78
79 switch (nnm->cm.type) {
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053080 case NSS_TX_METADATA_TYPE_N2H_RPS_CFG:
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053081 nss_info("NSS N2H rps_en %d \n",nnm->msg.rps_cfg.enable);
Vijay Dewangan488e5372014-12-29 21:40:11 -080082 break;
83
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +053084 case NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG:
85 nss_info("NSS N2H mitigation_dis %d \n",nnm->msg.mitigation_cfg.enable);
86 break;
87
Vijay Dewangan488e5372014-12-29 21:40:11 -080088 case NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG:
89 nss_info("%p: empty pool buf cfg response from FW", nss_ctx);
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053090 break;
91
Radha krishna Simha Jiguru7f424d52015-02-10 19:41:01 +053092 case NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS:
93 nss_info("%p: flush payloads cmd response from FW", nss_ctx);
94 break;
95
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053096 case NSS_RX_METADATA_TYPE_N2H_STATS_SYNC:
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -070097 nss_n2h_stats_sync(nss_ctx, &nnm->msg.stats_sync);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053098 break;
99
100 default:
101 if (ncm->response != NSS_CMN_RESPONSE_ACK) {
102 /*
103 * Check response
104 */
105 nss_info("%p: Received response %d for type %d, interface %d",
106 nss_ctx, ncm->response, ncm->type, ncm->interface);
107 }
108 }
Vijay Dewangan488e5372014-12-29 21:40:11 -0800109
110 /*
Stephen Wang49b474b2016-03-25 10:40:30 -0700111 * Update the callback and app_data for NOTIFY messages, n2h sends all notify messages
Vijay Dewangan488e5372014-12-29 21:40:11 -0800112 * to the same callback/app_data.
113 */
Suruchi Agarwale4ad24a2018-06-11 12:03:46 +0530114 if (nnm->cm.response == NSS_CMN_RESPONSE_NOTIFY) {
Vijay Dewangan488e5372014-12-29 21:40:11 -0800115 /*
116 * Place holder for the user to create right call
Suruchi Agarwale4ad24a2018-06-11 12:03:46 +0530117 * back and app data when response is NSS_CMN_RESPONSE_NOTIFY
Vijay Dewangan488e5372014-12-29 21:40:11 -0800118 */
Stephen Wangaed46332016-12-12 17:29:03 -0800119 ncm->cb = (nss_ptr_t)nss_n2h_rd[nss_ctx->id].n2h_callback;
120 ncm->app_data = (nss_ptr_t)nss_n2h_rd[nss_ctx->id].app_data;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800121 }
122
123 /*
124 * Do we have a callback?
125 */
126 if (!ncm->cb) {
127 return;
128 }
129
130 /*
131 * Callback
132 */
133 cb = (nss_n2h_msg_callback_t)ncm->cb;
134 cb((void *)ncm->app_data, nnm);
135}
136
137/*
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530138 * nss_n2h_mitigation_cfg_callback()
139 * call back function for mitigation configuration
140 */
141static void nss_n2h_mitigation_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
142{
Stephen Wangaed46332016-12-12 17:29:03 -0800143 uint32_t core_num = (uint32_t)(nss_ptr_t)app_data;
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530144 struct nss_top_instance *nss_top = &nss_top_main;
145 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
146
147 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
148
149 /*
150 * Error, hence we are not updating the nss_n2h_mitigate_en
151 */
152 nss_n2h_mitigationcp[core_num].response = NSS_FAILURE;
153 complete(&nss_n2h_mitigationcp[core_num].complete);
154 nss_warning("core%d: MITIGATION configuration failed : %d\n", core_num, nnm->cm.error);
155 return;
156 }
157
158 nss_info("core%d: MITIGATION configuration succeeded: %d\n", core_num, nnm->cm.error);
159
160 nss_ctx->n2h_mitigate_en = nnm->msg.mitigation_cfg.enable;
161 nss_n2h_mitigationcp[core_num].response = NSS_SUCCESS;
162 complete(&nss_n2h_mitigationcp[core_num].complete);
163}
164
165/*
166 * nss_n2h_buf_cfg_callback()
167 * call back function for pbuf configuration
168 */
169static void nss_n2h_bufs_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
170{
Stephen Wangaed46332016-12-12 17:29:03 -0800171 uint32_t core_num = (uint32_t)(nss_ptr_t)app_data;
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530172 unsigned int allocated_sz;
173
174 struct nss_top_instance *nss_top = &nss_top_main;
175 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
176
177 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
178 nss_n2h_bufcp[core_num].response = NSS_FAILURE;
179 nss_warning("core%d: buf configuration failed : %d\n", core_num, nnm->cm.error);
180 goto done;
181 }
182
183 nss_info("core%d: buf configuration succeeded: %d\n", core_num, nnm->cm.error);
184
185 allocated_sz = nnm->msg.buf_pool.nss_buf_page_size * nnm->msg.buf_pool.nss_buf_num_pages;
186 nss_ctx->buf_sz_allocated += allocated_sz;
187
188 nss_n2h_bufcp[core_num].response = NSS_SUCCESS;
189
190done:
191 complete(&nss_n2h_bufcp[core_num].complete);
192}
193
194/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700195 * nss_n2h_payload_stats_callback()
196 * It gets called response to payload accounting.
Vijay Dewangan488e5372014-12-29 21:40:11 -0800197 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700198static void nss_n2h_payload_stats_callback(void *app_data,
199 struct nss_n2h_msg *nnm)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800200{
Stephen Wangaed46332016-12-12 17:29:03 -0800201 uint32_t core_num = (uint32_t)(nss_ptr_t)app_data;
Saurabh Misra71034db2015-06-04 16:18:38 -0700202
Vijay Dewangan488e5372014-12-29 21:40:11 -0800203 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
204 struct nss_n2h_empty_pool_buf *nnepbcm;
205 nnepbcm = &nnm->msg.empty_pool_buf_cfg;
206
Saurabh Misra71034db2015-06-04 16:18:38 -0700207 nss_warning("%d: core empty pool buf set failure: %d\n",
208 core_num, nnm->cm.error);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800209 nss_n2h_nepbcfgp[core_num].response = NSS_FAILURE;
210 complete(&nss_n2h_nepbcfgp[core_num].complete);
211 return;
212 }
213
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700214 if (nnm->cm.type == NSS_TX_METADATA_TYPE_GET_WATER_MARK) {
215 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size =
Saurabh Misra71034db2015-06-04 16:18:38 -0700216 ntohl(nnm->msg.payload_info.pool_size);
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700217 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water =
Saurabh Misra71034db2015-06-04 16:18:38 -0700218 ntohl(nnm->msg.payload_info.low_water);
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700219 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water =
Saurabh Misra71034db2015-06-04 16:18:38 -0700220 ntohl(nnm->msg.payload_info.high_water);
221 }
222
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700223 if (nnm->cm.type == NSS_TX_METADATA_TYPE_GET_PAGED_WATER_MARK) {
224 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size =
225 ntohl(nnm->msg.paged_payload_info.pool_size);
226 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water =
227 ntohl(nnm->msg.paged_payload_info.low_water);
228 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water =
229 ntohl(nnm->msg.paged_payload_info.high_water);
230 }
231
Vijay Dewangan488e5372014-12-29 21:40:11 -0800232 nss_n2h_nepbcfgp[core_num].response = NSS_SUCCESS;
233 complete(&nss_n2h_nepbcfgp[core_num].complete);
234}
235
236/*
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530237 * nss_n2h_set_wifi_payloads_callback()
Cemil Coskun9165c762017-12-04 14:35:24 -0800238 * call back function for response to wifi pool configuration
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530239 *
240 */
241static void nss_n2h_set_wifi_payloads_callback(void *app_data,
242 struct nss_n2h_msg *nnm)
243{
Arunkumar Tba9b4a02016-11-07 11:41:14 +0530244 struct nss_ctx_instance *nss_ctx __maybe_unused = (struct nss_ctx_instance *)app_data;
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530245 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
246
247 nss_n2h_wp.response = NSS_FAILURE;
248 complete(&nss_n2h_wp.complete);
249 nss_warning("%p: wifi pool configuration failed : %d\n", nss_ctx,
250 nnm->cm.error);
251 return;
252 }
253
254 nss_info("%p: wifi payload configuration succeeded: %d\n", nss_ctx,
255 nnm->cm.error);
256 nss_n2h_wp.response = NSS_SUCCESS;
257 complete(&nss_n2h_wp.complete);
258}
259
260/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700261 * nss_n2h_get_payload_info()
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700262 * Gets Payload information.
Vijay Dewangan488e5372014-12-29 21:40:11 -0800263 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700264static 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 -0700265{
266 struct nss_top_instance *nss_top = &nss_top_main;
267 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
Saurabh Misra71034db2015-06-04 16:18:38 -0700268 nss_tx_status_t nss_tx_status;
269 int ret = NSS_FAILURE;
270
271 /*
272 * Note that semaphore should be already held.
273 */
274
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700275 nss_tx_status = nss_n2h_tx_msg(nss_ctx, nnm);
Saurabh Misra71034db2015-06-04 16:18:38 -0700276
277 if (nss_tx_status != NSS_TX_SUCCESS) {
Stephen Wangaed46332016-12-12 17:29:03 -0800278 nss_warning("%p: core %d nss_tx error errorn", nss_ctx, (int)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700279 return NSS_FAILURE;
280 }
281
282 /*
283 * Blocking call, wait till we get ACK for this msg.
284 */
285 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
286 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
287 if (ret == 0) {
Stephen Wangaed46332016-12-12 17:29:03 -0800288 nss_warning("%p: core %d waiting for ack timed out\n", nss_ctx, (int)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700289 return NSS_FAILURE;
290 }
291
292 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
Stephen Wangaed46332016-12-12 17:29:03 -0800293 nss_warning("%p: core %d response returned failure\n", nss_ctx, (int)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700294 return NSS_FAILURE;
295 }
296
297 return NSS_SUCCESS;
298}
299
300/*
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700301 * nss_n2h_get_default_payload_info()
302 * Gets the default payload information.
303 */
304static int nss_n2h_get_default_payload_info(nss_ptr_t core_num)
305{
306 struct nss_n2h_msg nnm;
307
308 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
309 NSS_TX_METADATA_TYPE_GET_WATER_MARK,
310 sizeof(struct nss_n2h_payload_info),
311 nss_n2h_payload_stats_callback,
312 (void *)core_num);
313
314 return nss_n2h_get_payload_info(core_num, &nnm,
315 &nnm.msg.payload_info);
316}
317
318/*
319 * nss_n2h_get_paged_payload_info()
320 * Gets the paged payload information.
321 */
322static int nss_n2h_get_paged_payload_info(nss_ptr_t core_num)
323{
324 struct nss_n2h_msg nnm;
325
326 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
327 NSS_TX_METADATA_TYPE_GET_PAGED_WATER_MARK,
328 sizeof(struct nss_n2h_payload_info),
329 nss_n2h_payload_stats_callback,
330 (void *)core_num);
331
332 return nss_n2h_get_payload_info(core_num, &nnm,
333 &nnm.msg.paged_payload_info);
334}
335
336/*
Amit Guptaca2ea682019-01-24 17:18:46 +0530337 * nss_n2h_set_empty_buf_pool()
Saurabh Misra71034db2015-06-04 16:18:38 -0700338 * Sets empty pool buffer
339 */
Amit Guptaca2ea682019-01-24 17:18:46 +0530340static int nss_n2h_set_empty_buf_pool(struct ctl_table *ctl, int write,
Saurabh Misra71034db2015-06-04 16:18:38 -0700341 void __user *buffer,
342 size_t *lenp, loff_t *ppos,
Stephen Wangaed46332016-12-12 17:29:03 -0800343 nss_ptr_t core_num, int *new_val)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800344{
345 struct nss_top_instance *nss_top = &nss_top_main;
346 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
347 struct nss_n2h_msg nnm;
348 struct nss_n2h_empty_pool_buf *nnepbcm;
349 nss_tx_status_t nss_tx_status;
350 int ret = NSS_FAILURE;
351
352 /*
353 * Acquiring semaphore
354 */
355 down(&nss_n2h_nepbcfgp[core_num].sem);
356
357 /*
358 * Take snap shot of current value
359 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700360 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size = *new_val;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800361
Saurabh Misra71034db2015-06-04 16:18:38 -0700362 if (!write) {
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700363 ret = nss_n2h_get_default_payload_info(core_num);
364 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size;
Saurabh Misra71034db2015-06-04 16:18:38 -0700365 if (ret == NSS_FAILURE) {
366 up(&nss_n2h_nepbcfgp[core_num].sem);
367 return -EBUSY;
368 }
369
370 up(&nss_n2h_nepbcfgp[core_num].sem);
371
372 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
373 return ret;
374 }
375
Vijay Dewangan488e5372014-12-29 21:40:11 -0800376 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
Saurabh Misra71034db2015-06-04 16:18:38 -0700377 if (ret) {
Vijay Dewangan488e5372014-12-29 21:40:11 -0800378 up(&nss_n2h_nepbcfgp[core_num].sem);
379 return ret;
380 }
381
Vijay Dewangan488e5372014-12-29 21:40:11 -0800382 if ((*new_val < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700383 nss_warning("%p: core %d setting %d < min number of buffer",
Stephen Wangaed46332016-12-12 17:29:03 -0800384 nss_ctx, (int)core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800385 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800386 }
387
388 nss_info("%p: core %d number of empty pool buffer is : %d\n",
Stephen Wangaed46332016-12-12 17:29:03 -0800389 nss_ctx, (int)core_num, *new_val);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800390
391 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
392 NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG,
393 sizeof(struct nss_n2h_empty_pool_buf),
Saurabh Misra71034db2015-06-04 16:18:38 -0700394 nss_n2h_payload_stats_callback,
Stephen Wangaed46332016-12-12 17:29:03 -0800395 (nss_ptr_t *)core_num);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800396
397 nnepbcm = &nnm.msg.empty_pool_buf_cfg;
398 nnepbcm->pool_size = htonl(*new_val);
399 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
400
401 if (nss_tx_status != NSS_TX_SUCCESS) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700402 nss_warning("%p: core %d nss_tx error empty pool buffer: %d\n",
Stephen Wangaed46332016-12-12 17:29:03 -0800403 nss_ctx, (int)core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800404 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800405 }
406
407 /*
408 * Blocking call, wait till we get ACK for this msg.
409 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700410 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
411 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
Vijay Dewangan488e5372014-12-29 21:40:11 -0800412 if (ret == 0) {
Stephen Wangaed46332016-12-12 17:29:03 -0800413 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx, (int)core_num);
Stephen Wang06761022015-03-03 16:38:42 -0800414 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800415 }
416
417 /*
418 * ACK/NACK received from NSS FW
419 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
420 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
421 */
422 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
Stephen Wang06761022015-03-03 16:38:42 -0800423 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800424 }
425
426 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700427 return 0;
Stephen Wang06761022015-03-03 16:38:42 -0800428
429failure:
430 /*
431 * Restore the current_value to its previous state
432 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700433 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size;
434 up(&nss_n2h_nepbcfgp[core_num].sem);
435 return NSS_FAILURE;
436}
437
438/*
439 * nss_n2h_set_empty_paged_pool_buf()
440 * Sets empty paged pool buffer
441 */
442static int nss_n2h_set_empty_paged_pool_buf(struct ctl_table *ctl, int write,
443 void __user *buffer,
444 size_t *lenp, loff_t *ppos,
445 nss_ptr_t core_num, int *new_val)
446{
447 struct nss_top_instance *nss_top = &nss_top_main;
448 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
449 struct nss_n2h_msg nnm;
450 struct nss_n2h_empty_pool_buf *nneppbcm;
451 nss_tx_status_t nss_tx_status;
452 int ret = NSS_FAILURE;
453
454 /*
455 * Acquiring semaphore
456 */
457 down(&nss_n2h_nepbcfgp[core_num].sem);
458
459 /*
460 * Take snap shot of current value
461 */
462 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size = *new_val;
463
464 if (!write) {
465 ret = nss_n2h_get_paged_payload_info(core_num);
466 *new_val = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size;
467 if (ret == NSS_FAILURE) {
468 up(&nss_n2h_nepbcfgp[core_num].sem);
469 return -EBUSY;
470 }
471
472 up(&nss_n2h_nepbcfgp[core_num].sem);
473
474 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
475 return ret;
476 }
477
478 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
479 if (ret) {
480 up(&nss_n2h_nepbcfgp[core_num].sem);
481 return ret;
482 }
483
484 if ((*new_val < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
485 nss_warning("%p: core %d setting %d < min number of buffer",
486 nss_ctx, (int)core_num, *new_val);
487 goto failure;
488 }
489
490 nss_info("%p: core %d number of empty paged pool buffer is : %d\n",
491 nss_ctx, (int)core_num, *new_val);
492
493 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
494 NSS_TX_METADATA_TYPE_N2H_EMPTY_PAGED_POOL_BUF_CFG,
495 sizeof(struct nss_n2h_empty_pool_buf),
496 nss_n2h_payload_stats_callback,
497 (nss_ptr_t *)core_num);
498
499 nneppbcm = &nnm.msg.empty_pool_buf_cfg;
500 nneppbcm->pool_size = htonl(*new_val);
501 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
502
503 if (nss_tx_status != NSS_TX_SUCCESS) {
504 nss_warning("%p: core %d nss_tx error empty paged pool buffer: %d\n",
505 nss_ctx, (int)core_num, *new_val);
506 goto failure;
507 }
508
509 /*
510 * Blocking call, wait till we get ACK for this msg.
511 */
512 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
513 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
514 if (ret == 0) {
515 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx, (int)core_num);
516 goto failure;
517 }
518
519 /*
520 * ACK/NACK received from NSS FW
521 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
522 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
523 */
524 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
525 goto failure;
526 }
527
528 up(&nss_n2h_nepbcfgp[core_num].sem);
529 return 0;
530
531failure:
532 /*
533 * Restore the current_value to its previous state
534 */
535 *new_val = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size;
Saurabh Misra71034db2015-06-04 16:18:38 -0700536 up(&nss_n2h_nepbcfgp[core_num].sem);
537 return NSS_FAILURE;
538}
539
540/*
541 * nss_n2h_set_water_mark()
542 * Sets water mark for N2H SOS
543 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700544static int nss_n2h_set_water_mark(struct ctl_table *ctl, int write,
Saurabh Misra71034db2015-06-04 16:18:38 -0700545 void __user *buffer,
546 size_t *lenp, loff_t *ppos,
Stephen Wangaed46332016-12-12 17:29:03 -0800547 uint32_t core_num, int *low, int *high)
Saurabh Misra71034db2015-06-04 16:18:38 -0700548{
549 struct nss_top_instance *nss_top = &nss_top_main;
550 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
551 struct nss_n2h_msg nnm;
552 struct nss_n2h_water_mark *wm;
553 nss_tx_status_t nss_tx_status;
554 int ret = NSS_FAILURE;
555
556 /*
557 * Acquiring semaphore
558 */
559 down(&nss_n2h_nepbcfgp[core_num].sem);
560
561 /*
562 * Take snap shot of current value
563 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700564 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water = *low;
565 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water = *high;
Saurabh Misra71034db2015-06-04 16:18:38 -0700566
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700567 if (!write || *low == -1 || *high == -1) {
568 ret = nss_n2h_get_default_payload_info(core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700569 if (ret == NSS_FAILURE) {
570 up(&nss_n2h_nepbcfgp[core_num].sem);
571 return -EBUSY;
572 }
573
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700574 *low = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water;
575 *high = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water;
Saurabh Misra71034db2015-06-04 16:18:38 -0700576 }
577
578 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700579 if (!write || ret) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700580 up(&nss_n2h_nepbcfgp[core_num].sem);
581 return ret;
582 }
583
Saurabh Misra71034db2015-06-04 16:18:38 -0700584 if ((*low < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) ||
585 (*high < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
586 nss_warning("%p: core %d setting %d, %d < min number of buffer",
587 nss_ctx, core_num, *low, *high);
588 goto failure;
589 }
590
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530591 if ((*low > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ) ||
592 (*high > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700593 nss_warning("%p: core %d setting %d, %d is > upper limit",
594 nss_ctx, core_num, *low, *high);
595 goto failure;
596 }
597
598 if (*low > *high) {
599 nss_warning("%p: core %d setting low %d is more than high %d",
600 nss_ctx, core_num, *low, *high);
601 goto failure;
602 }
603
604 nss_info("%p: core %d number of low : %d and high : %d\n",
605 nss_ctx, core_num, *low, *high);
606
607 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
608 NSS_TX_METADATA_TYPE_SET_WATER_MARK,
609 sizeof(struct nss_n2h_water_mark),
610 nss_n2h_payload_stats_callback,
Stephen Wangaed46332016-12-12 17:29:03 -0800611 (void *)(nss_ptr_t)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700612
613 wm = &nnm.msg.wm;
614 wm->low_water = htonl(*low);
615 wm->high_water = htonl(*high);
616 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
617
618 if (nss_tx_status != NSS_TX_SUCCESS) {
619 nss_warning("%p: core %d nss_tx error setting : %d, %d\n",
620 nss_ctx, core_num, *low, *high);
621 goto failure;
622 }
623
624 /*
625 * Blocking call, wait till we get ACK for this msg.
626 */
627 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
628 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
629 if (ret == 0) {
630 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
631 core_num);
632 goto failure;
633 }
634
635 /*
636 * ACK/NACK received from NSS FW
637 */
638 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response)
639 goto failure;
640
641 up(&nss_n2h_nepbcfgp[core_num].sem);
642 return NSS_SUCCESS;
643
644failure:
645 /*
646 * Restore the current_value to its previous state
647 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700648 *low = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water;
649 *high = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water;
650 up(&nss_n2h_nepbcfgp[core_num].sem);
651 return -EINVAL;
652}
653
654/*
655 * nss_n2h_set_paged_water_mark()
656 * Sets water mark for paged pool N2H SOS
657 */
658static int nss_n2h_set_paged_water_mark(struct ctl_table *ctl, int write,
659 void __user *buffer,
660 size_t *lenp, loff_t *ppos,
661 uint32_t core_num, int *low, int *high)
662{
663 struct nss_top_instance *nss_top = &nss_top_main;
664 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
665 struct nss_n2h_msg nnm;
666 struct nss_n2h_water_mark *pwm;
667 nss_tx_status_t nss_tx_status;
668 int ret = NSS_FAILURE;
669
670 /*
671 * Acquiring semaphore
672 */
673 down(&nss_n2h_nepbcfgp[core_num].sem);
674
675 /*
676 * Take snap shot of current value
677 */
678 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water = *low;
679 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water = *high;
680
681 if (!write || *low == -1 || *high == -1) {
682 ret = nss_n2h_get_paged_payload_info(core_num);
683 if (ret == NSS_FAILURE) {
684 up(&nss_n2h_nepbcfgp[core_num].sem);
685 return -EBUSY;
686 }
687
688 *low = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water;
689 *high = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water;
690 }
691
692 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
693 if (!write || ret) {
694 up(&nss_n2h_nepbcfgp[core_num].sem);
695 return ret;
696 }
697
698 if ((*low < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) ||
699 (*high < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
700 nss_warning("%p: core %d setting %d, %d < min number of buffer",
701 nss_ctx, core_num, *low, *high);
702 goto failure;
703 }
704
705 if ((*low > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ) ||
706 (*high > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) {
707 nss_warning("%p: core %d setting %d, %d is > upper limit",
708 nss_ctx, core_num, *low, *high);
709 goto failure;
710 }
711
712 if (*low > *high) {
713 nss_warning("%p: core %d setting low %d is more than high %d",
714 nss_ctx, core_num, *low, *high);
715 goto failure;
716 }
717
718 nss_info("%p: core %d number of low : %d and high : %d\n",
719 nss_ctx, core_num, *low, *high);
720
721 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
722 NSS_TX_METADATA_TYPE_SET_PAGED_WATER_MARK,
723 sizeof(struct nss_n2h_water_mark),
724 nss_n2h_payload_stats_callback,
725 (void *)(nss_ptr_t)core_num);
726
727 pwm = &nnm.msg.wm_paged;
728 pwm->low_water = htonl(*low);
729 pwm->high_water = htonl(*high);
730 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
731
732 if (nss_tx_status != NSS_TX_SUCCESS) {
733 nss_warning("%p: core %d nss_tx error setting : %d, %d\n",
734 nss_ctx, core_num, *low, *high);
735 goto failure;
736 }
737
738 /*
739 * Blocking call, wait till we get ACK for this msg.
740 */
741 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
742 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
743 if (ret == 0) {
744 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
745 core_num);
746 goto failure;
747 }
748
749 /*
750 * ACK/NACK received from NSS FW
751 */
752 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response)
753 goto failure;
754
755 up(&nss_n2h_nepbcfgp[core_num].sem);
756 return NSS_SUCCESS;
757
758failure:
759 /*
760 * Restore the current_value to its previous state
761 */
762 *low = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water;
763 *high = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water;
Stephen Wang06761022015-03-03 16:38:42 -0800764 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700765 return -EINVAL;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800766}
767
768/*
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530769 * nss_n2h_cfg_wifi_pool()
770 * Sets number of wifi payloads to adjust high water mark for N2H SoS
771 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700772static int nss_n2h_cfg_wifi_pool(struct ctl_table *ctl, int write,
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530773 void __user *buffer,
774 size_t *lenp, loff_t *ppos,
775 int *payloads)
776{
777 struct nss_top_instance *nss_top = &nss_top_main;
778 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
779 struct nss_n2h_msg nnm;
780 struct nss_n2h_wifi_payloads *wp;
781 nss_tx_status_t nss_tx_status;
782 int ret = NSS_FAILURE;
783
784 /*
785 * Acquiring semaphore
786 */
787 down(&nss_n2h_wp.sem);
788
789 if (!write) {
790 *payloads = nss_n2h_wp.wifi_pool;
791
792 up(&nss_n2h_wp.sem);
793 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
794 return ret;
795 }
796
797 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
798 if (ret) {
799 up(&nss_n2h_wp.sem);
800 return ret;
801 }
802
803 /*
804 * If payloads parameter is not set, we do
805 * nothing.
806 */
807 if (*payloads == -1)
808 goto failure;
809
810 if ((*payloads < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
811 nss_warning("%p: wifi setting %d < min number of buffer",
812 nss_ctx, *payloads);
813 goto failure;
814 }
815
816 if ((*payloads > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) {
817 nss_warning("%p: wifi setting %d > max number of buffer",
818 nss_ctx, *payloads);
819 goto failure;
820 }
821
822 nss_info("%p: wifi payloads : %d\n",
823 nss_ctx, *payloads);
824
825 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
826 NSS_TX_METADATA_TYPE_N2H_WIFI_POOL_BUF_CFG,
827 sizeof(struct nss_n2h_wifi_payloads),
828 nss_n2h_set_wifi_payloads_callback,
829 (void *)nss_ctx);
830
831 wp = &nnm.msg.wp;
832 wp->payloads = htonl(*payloads);
833 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
834
835 if (nss_tx_status != NSS_TX_SUCCESS) {
836 nss_warning("%p: wifi setting %d nss_tx error",
837 nss_ctx, *payloads);
838 goto failure;
839 }
840
841 /*
842 * Blocking call, wait till we get ACK for this msg.
843 */
844 ret = wait_for_completion_timeout(&nss_n2h_wp.complete,
845 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
846 if (ret == 0) {
847 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
848 goto failure;
849 }
850
851 /*
852 * ACK/NACK received from NSS FW
853 */
854 if (NSS_FAILURE == nss_n2h_wp.response)
855 goto failure;
856
857 up(&nss_n2h_wp.sem);
858 return NSS_SUCCESS;
859
860failure:
861 up(&nss_n2h_wp.sem);
862 return -EINVAL;
863}
864
865/*
Vijay Dewangan488e5372014-12-29 21:40:11 -0800866 * nss_n2h_empty_pool_buf_core1_handler()
867 * Sets the number of empty buffer for core 1
868 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700869static int nss_n2h_empty_pool_buf_cfg_core1_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700870 int write, void __user *buffer,
871 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800872{
Amit Guptaca2ea682019-01-24 17:18:46 +0530873 return nss_n2h_set_empty_buf_pool(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700874 NSS_CORE_1, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800875}
876
877/*
878 * nss_n2h_empty_pool_buf_core0_handler()
879 * Sets the number of empty buffer for core 0
880 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700881static int nss_n2h_empty_pool_buf_cfg_core0_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700882 int write, void __user *buffer,
883 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800884{
Amit Guptaca2ea682019-01-24 17:18:46 +0530885 return nss_n2h_set_empty_buf_pool(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700886 NSS_CORE_0, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0]);
887}
888
889/*
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700890 * nss_n2h_empty_paged_pool_buf_cfg_core1_handler()
891 * Sets the number of empty paged buffer for core 1
892 */
893static int nss_n2h_empty_paged_pool_buf_cfg_core1_handler(struct ctl_table *ctl,
894 int write, void __user *buffer,
895 size_t *lenp, loff_t *ppos)
896{
897 return nss_n2h_set_empty_paged_pool_buf(ctl, write, buffer, lenp, ppos,
898 NSS_CORE_1, &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_1]);
899}
900
901/*
902 * nss_n2h_empty_paged_pool_buf_cfg_core0_handler()
903 * Sets the number of empty paged buffer for core 0
904 */
905static int nss_n2h_empty_paged_pool_buf_cfg_core0_handler(struct ctl_table *ctl,
906 int write, void __user *buffer,
907 size_t *lenp, loff_t *ppos)
908{
909 return nss_n2h_set_empty_paged_pool_buf(ctl, write, buffer, lenp, ppos,
910 NSS_CORE_0, &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0]);
911}
912
913/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700914 * nss_n2h_water_mark_core1_handler()
915 * Sets water mark for core 1
916 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700917static int nss_n2h_water_mark_core1_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700918 int write, void __user *buffer,
919 size_t *lenp, loff_t *ppos)
920{
921 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
922 NSS_CORE_1, &nss_n2h_water_mark[NSS_CORE_1][0],
923 &nss_n2h_water_mark[NSS_CORE_1][1]);
924}
925
926/*
927 * nss_n2h_water_mark_core0_handler()
928 * Sets water mark for core 0
929 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700930static int nss_n2h_water_mark_core0_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700931 int write, void __user *buffer,
932 size_t *lenp, loff_t *ppos)
933{
934 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
935 NSS_CORE_0, &nss_n2h_water_mark[NSS_CORE_0][0],
936 &nss_n2h_water_mark[NSS_CORE_0][1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800937}
938
Vijay Dewangan634ce592015-01-07 17:21:09 -0800939/*
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700940 * nss_n2h_paged_water_mark_core1_handler()
941 * Sets paged water mark for core 1
942 */
943static int nss_n2h_paged_water_mark_core1_handler(struct ctl_table *ctl,
944 int write, void __user *buffer,
945 size_t *lenp, loff_t *ppos)
946{
947 return nss_n2h_set_paged_water_mark(ctl, write, buffer, lenp, ppos,
948 NSS_CORE_1, &nss_n2h_paged_water_mark[NSS_CORE_1][0],
949 &nss_n2h_paged_water_mark[NSS_CORE_1][1]);
950}
951
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700952/*
953 * nss_n2h_paged_water_mark_core0_handler()
954 * Sets paged water mark for core 0
955 */
956static int nss_n2h_paged_water_mark_core0_handler(struct ctl_table *ctl,
957 int write, void __user *buffer,
958 size_t *lenp, loff_t *ppos)
959{
960 return nss_n2h_set_paged_water_mark(ctl, write, buffer, lenp, ppos,
961 NSS_CORE_0, &nss_n2h_paged_water_mark[NSS_CORE_0][0],
962 &nss_n2h_paged_water_mark[NSS_CORE_0][1]);
963}
964
965/*
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530966 * nss_n2h_wifi_payloads_handler()
967 * Sets number of wifi payloads
968 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700969static int nss_n2h_wifi_payloads_handler(struct ctl_table *ctl,
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530970 int write, void __user *buffer,
971 size_t *lenp, loff_t *ppos)
972{
973 return nss_n2h_cfg_wifi_pool(ctl, write, buffer, lenp, ppos,
974 &nss_n2h_wifi_pool_buf_cfg);
975}
976
977/*
ratheesh kannothab436af2017-07-20 08:51:07 +0530978 * nss_n2h_update_queue_config_callback()
979 * Callback to handle the completion of queue config command
ratheesh kannoth024a6e82017-05-18 17:48:10 +0530980 */
ratheesh kannothab436af2017-07-20 08:51:07 +0530981static void nss_n2h_update_queue_config_callback(void *app_data, struct nss_n2h_msg *nim)
ratheesh kannoth024a6e82017-05-18 17:48:10 +0530982{
ratheesh kannothab436af2017-07-20 08:51:07 +0530983 if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
984 nss_warning("n2h Error response %d\n", nim->cm.response);
985 nss_n2h_q_cfg_pvt.response = NSS_TX_FAILURE;
986 } else {
987 nss_n2h_q_cfg_pvt.response = NSS_TX_SUCCESS;
988 }
989
990 complete(&nss_n2h_q_cfg_pvt.complete);
991}
992
993/*
994 * nss_n2h_update_queue_config_async()
995 * Asynchronous call to send pnode queue configuration.
996 */
997nss_tx_status_t nss_n2h_update_queue_config_async(struct nss_ctx_instance *nss_ctx, bool mq_en, uint16_t *qlimits)
998{
999
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301000 struct nss_n2h_msg nnm;
1001 struct nss_n2h_pnode_queue_config *cfg;
1002 nss_tx_status_t status;
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301003 int i;
1004
1005 if (!mq_en) {
1006 return NSS_TX_SUCCESS;
1007 }
1008
ratheesh kannoth93ba95c2017-07-13 15:52:52 +05301009 /*
1010 * MQ mode doesnot make any sense if number of priority queues in NSS
1011 * is 1
1012 */
1013 if (NSS_MAX_NUM_PRI <= 1) {
1014 return NSS_TX_SUCCESS;
1015 }
1016
ratheesh kannothab436af2017-07-20 08:51:07 +05301017 memset(&nnm, 0, sizeof(struct nss_n2h_msg));
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301018
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301019 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1020 NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG,
1021 sizeof(struct nss_n2h_pnode_queue_config), NULL, 0);
1022
ratheesh kannothab436af2017-07-20 08:51:07 +05301023 cfg = &nnm.msg.pn_q_cfg;
1024
1025 /*
Cemil Coskun9165c762017-12-04 14:35:24 -08001026 * Update limits
1027 */
ratheesh kannothab436af2017-07-20 08:51:07 +05301028 for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
1029 cfg->qlimits[i] = qlimits[i];
1030 }
1031 cfg->mq_en = true;
1032
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301033 status = nss_n2h_tx_msg(nss_ctx, &nnm);
1034 if (status != NSS_TX_SUCCESS) {
1035 nss_warning("%p: nss_tx error to send pnode queue config\n", nss_ctx);
1036 return status;
1037 }
1038
1039 return NSS_TX_SUCCESS;
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301040}
ratheesh kannothab436af2017-07-20 08:51:07 +05301041EXPORT_SYMBOL(nss_n2h_update_queue_config_async);
1042
1043/*
1044 * nss_n2h_update_queue_config_sync()
1045 * Synchronous call to send pnode queue configuration.
1046 */
1047nss_tx_status_t nss_n2h_update_queue_config_sync(struct nss_ctx_instance *nss_ctx, bool mq_en, uint16_t *qlimits)
1048{
1049
1050 struct nss_n2h_msg nnm;
1051 struct nss_n2h_pnode_queue_config *cfg;
1052 nss_tx_status_t status;
1053 int ret, i;
1054
1055 if (!mq_en) {
1056 return NSS_TX_SUCCESS;
1057 }
1058
ratheesh kannoth93ba95c2017-07-13 15:52:52 +05301059 /*
1060 * MQ mode doesnot make any sense if number of priority queues in NSS
1061 * is 1
1062 */
1063 if (NSS_MAX_NUM_PRI <= 1) {
1064 return NSS_TX_SUCCESS;
1065 }
1066
ratheesh kannothab436af2017-07-20 08:51:07 +05301067 memset(&nnm, 0, sizeof(struct nss_n2h_msg));
1068
1069 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1070 NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG,
1071 sizeof(struct nss_n2h_pnode_queue_config), nss_n2h_update_queue_config_callback, 0);
1072
1073 cfg = &nnm.msg.pn_q_cfg;
1074
1075 /*
Cemil Coskun9165c762017-12-04 14:35:24 -08001076 * Update limits
1077 */
ratheesh kannothab436af2017-07-20 08:51:07 +05301078 for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
1079 cfg->qlimits[i] = qlimits[i];
1080 }
1081 cfg->mq_en = true;
1082
1083 down(&nss_n2h_q_cfg_pvt.sem);
1084
1085 status = nss_n2h_tx_msg(nss_ctx, &nnm);
1086
1087 if (status != NSS_TX_SUCCESS) {
1088 nss_warning("%p: n2h_tx_msg failed\n", nss_ctx);
1089 up(&nss_n2h_q_cfg_pvt.sem);
1090 return status;
1091 }
1092 ret = wait_for_completion_timeout(&nss_n2h_q_cfg_pvt.complete, msecs_to_jiffies(NSS_N2H_TX_TIMEOUT));
1093
1094 if (!ret) {
1095 nss_warning("%p: Timeout expired for pnode queue config sync message\n", nss_ctx);
1096 nss_n2h_q_cfg_pvt.response = NSS_TX_FAILURE;
1097 }
1098
1099 status = nss_n2h_q_cfg_pvt.response;
1100 up(&nss_n2h_q_cfg_pvt.sem);
1101 return status;
1102}
1103EXPORT_SYMBOL(nss_n2h_update_queue_config_sync);
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301104
1105/*
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301106 * nss_n2h_mitigation_cfg()
1107 * Send Message to NSS to disable MITIGATION.
1108 */
Stephen Wang49b474b2016-03-25 10:40:30 -07001109static 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 +05301110{
1111 struct nss_n2h_msg nnm;
1112 struct nss_n2h_mitigation *mitigation_cfg;
1113 nss_tx_status_t nss_tx_status;
1114 int ret;
1115
1116 nss_assert(core_num < NSS_CORE_MAX);
1117
1118 down(&nss_n2h_mitigationcp[core_num].sem);
1119 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG,
1120 sizeof(struct nss_n2h_mitigation),
1121 nss_n2h_mitigation_cfg_callback,
1122 (void *)core_num);
1123
1124 mitigation_cfg = &nnm.msg.mitigation_cfg;
1125 mitigation_cfg->enable = enable_mitigation;
1126
1127 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1128
1129 if (nss_tx_status != NSS_TX_SUCCESS) {
1130 nss_warning("%p: nss_tx error setting mitigation\n", nss_ctx);
1131 goto failure;
1132 }
1133
1134 /*
1135 * Blocking call, wait till we get ACK for this msg.
1136 */
1137 ret = wait_for_completion_timeout(&nss_n2h_mitigationcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
1138 if (ret == 0) {
1139 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
1140 goto failure;
1141 }
1142
1143 /*
1144 * ACK/NACK received from NSS FW
1145 */
1146 if (NSS_FAILURE == nss_n2h_mitigationcp[core_num].response) {
1147 goto failure;
1148 }
1149
1150 up(&nss_n2h_mitigationcp[core_num].sem);
1151 return NSS_SUCCESS;
1152
1153failure:
1154 up(&nss_n2h_mitigationcp[core_num].sem);
1155 return NSS_FAILURE;
1156}
1157
1158static inline void nss_n2h_buf_pool_free(struct nss_n2h_buf_pool *buf_pool)
1159{
1160 int page_count;
1161 for (page_count = 0; page_count < buf_pool->nss_buf_num_pages; page_count++) {
Stephen Wang7df68832017-08-10 16:54:35 -07001162 kfree((void *)buf_pool->nss_buf_pool_vaddr[page_count]);
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301163 }
1164}
1165
1166/*
1167 * nss_n2h_buf_cfg()
1168 * Send Message to NSS to enable pbufs.
1169 */
Stephen Wang49b474b2016-03-25 10:40:30 -07001170static nss_tx_status_t nss_n2h_buf_pool_cfg(struct nss_ctx_instance *nss_ctx,
Tallapragada4b0161b2016-07-07 21:38:34 +05301171 int buf_pool_size, nss_core_id_t core_num)
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301172{
1173 static struct nss_n2h_msg nnm;
1174 struct nss_n2h_buf_pool *buf_pool;
1175 nss_tx_status_t nss_tx_status;
1176 int ret;
1177 int page_count;
1178 int num_pages = ALIGN(buf_pool_size, PAGE_SIZE)/PAGE_SIZE;
1179
1180 nss_assert(core_num < NSS_CORE_MAX);
1181
1182 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_METADATA_TYPE_N2H_ADD_BUF_POOL,
1183 sizeof(struct nss_n2h_buf_pool),
1184 nss_n2h_bufs_cfg_callback,
1185 (void *)core_num);
1186
1187 do {
1188
1189 down(&nss_n2h_bufcp[core_num].sem);
1190
1191 buf_pool = &nnm.msg.buf_pool;
1192 buf_pool->nss_buf_page_size = PAGE_SIZE;
1193
1194 for (page_count = 0; page_count < MAX_PAGES_PER_MSG && num_pages; page_count++, num_pages--) {
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301195 void *kern_addr = kzalloc(PAGE_SIZE, GFP_ATOMIC);
1196 if (!kern_addr) {
1197 BUG_ON(!page_count);
1198 break;
1199 }
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301200
Radha krishna Simha Jiguru60068fb2017-07-28 17:40:52 +05301201 kmemleak_not_leak(kern_addr);
Stephen Wang7df68832017-08-10 16:54:35 -07001202 buf_pool->nss_buf_pool_vaddr[page_count] = (nss_ptr_t)kern_addr;
Stephen Wangefd38512017-01-24 14:01:02 -08001203 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 +05301204 }
1205
1206 buf_pool->nss_buf_num_pages = page_count;
1207 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1208 if (nss_tx_status != NSS_TX_SUCCESS) {
1209
1210 nss_n2h_buf_pool_free(buf_pool);
1211 nss_warning("%p: nss_tx error setting pbuf\n", nss_ctx);
1212 goto failure;
1213 }
1214
1215 /*
Cemil Coskun9165c762017-12-04 14:35:24 -08001216 * Blocking call, wait till we get ACK for this msg.
1217 */
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301218 ret = wait_for_completion_timeout(&nss_n2h_bufcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
1219 if (ret == 0) {
1220 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
1221 goto failure;
1222 }
1223
1224 /*
1225 * ACK/NACK received from NSS FW
1226 */
1227 if (NSS_FAILURE == nss_n2h_bufcp[core_num].response) {
1228
1229 nss_n2h_buf_pool_free(buf_pool);
1230 goto failure;
1231 }
1232
1233 up(&nss_n2h_bufcp[core_num].sem);
1234 } while(num_pages);
1235
1236 return NSS_SUCCESS;
1237failure:
1238 up(&nss_n2h_bufcp[core_num].sem);
1239 return NSS_FAILURE;
1240}
1241
Stephen Wang49b474b2016-03-25 10:40:30 -07001242
1243/*
1244 * nss_mitigation_handler()
1245 * Enable NSS MITIGATION
1246 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001247static 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 -07001248{
1249 struct nss_top_instance *nss_top = &nss_top_main;
1250 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_0];
1251 int ret;
1252
1253 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1254 if (ret) {
1255 return ret;
1256 }
1257
1258 /*
1259 * It's a read operation
1260 */
1261 if (!write) {
1262 return ret;
1263 }
1264
1265 if (!nss_n2h_core0_mitigation_cfg) {
1266 printk(KERN_INFO "Disabling NSS MITIGATION\n");
1267 nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_0);
1268 return 0;
1269 }
1270 printk(KERN_INFO "Invalid input value.Valid value is 0, Runtime re-enabling not supported\n");
1271 return -EINVAL;
1272}
1273
1274/*
1275 * nss_mitigation_handler()
1276 * Enable NSS MITIGATION
1277 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001278static 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 -07001279{
1280 struct nss_top_instance *nss_top = &nss_top_main;
1281 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_1];
1282 int ret;
1283
1284 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1285 if (ret) {
1286 return ret;
1287 }
1288
1289 /*
1290 * It's a read operation
1291 */
1292 if (!write) {
1293 return ret;
1294 }
1295
1296 if (!nss_n2h_core1_mitigation_cfg) {
1297 printk(KERN_INFO "Disabling NSS MITIGATION\n");
1298 nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_1);
1299 return 0;
1300 }
1301 printk(KERN_INFO "Invalid input value.Valid value is 0, Runtime re-enabling not supported\n");
1302 return -EINVAL;
1303}
1304
1305/*
1306 * nss_buf_handler()
1307 * Add extra NSS bufs from host memory
1308 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001309static 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 -07001310{
1311 struct nss_top_instance *nss_top = &nss_top_main;
1312 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_0];
1313 int ret;
1314
1315 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1316 if (ret) {
1317 return ret;
1318 }
1319
1320 /*
1321 * It's a read operation
1322 */
1323 if (!write) {
1324 return ret;
1325 }
1326
1327 if (nss_ctx->buf_sz_allocated) {
1328 nss_n2h_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1329 return -EPERM;
1330 }
1331
1332 if ((nss_n2h_core0_add_buf_pool_size >= 1) && (nss_n2h_core0_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) {
1333 printk(KERN_INFO "configuring additional NSS pbufs\n");
1334 ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_n2h_core0_add_buf_pool_size, NSS_CORE_0);
1335 nss_n2h_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1336 printk(KERN_INFO "additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated);
1337 return ret;
1338 }
1339
1340 printk(KERN_INFO "Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE);
1341 return -EINVAL;
1342}
1343
1344/*
1345 * nss_n2h_buf_handler()
1346 * Add extra NSS bufs from host memory
1347 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001348static 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 -07001349{
1350 struct nss_top_instance *nss_top = &nss_top_main;
1351 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_1];
1352 int ret;
1353
1354 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1355 if (ret) {
1356 return ret;
1357 }
1358
1359 /*
1360 * It's a read operation
1361 */
1362 if (!write) {
1363 return ret;
1364 }
1365
1366 if (nss_ctx->buf_sz_allocated) {
1367 nss_n2h_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1368 return -EPERM;
1369 }
1370
1371 if ((nss_n2h_core1_add_buf_pool_size >= 1) && (nss_n2h_core1_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) {
1372 printk(KERN_INFO "configuring additional NSS pbufs\n");
1373 ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_n2h_core1_add_buf_pool_size, NSS_CORE_1);
1374 nss_n2h_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1375 printk(KERN_INFO "additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated);
1376 return ret;
1377 }
1378
1379 printk(KERN_INFO "Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE);
1380 return -EINVAL;
1381}
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301382
Shashank Balashankar4162f572018-08-21 13:32:34 -07001383/*
1384 * nss_n2h_queue_limit_callback()
1385 * Callback to handle the completion of queue limit command.
1386 */
1387static void nss_n2h_queue_limit_callback(void *app_data, struct nss_n2h_msg *nim)
1388{
1389 if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
1390 nss_warning("n2h error response %d\n", nim->cm.response);
1391 }
1392
1393 nss_n2h_q_lim_pvt.response = nim->cm.response;
1394 complete(&nss_n2h_q_lim_pvt.complete);
1395}
1396
1397/*
1398 * nss_n2h_set_queue_limit_sync()
1399 * Sets the n2h queue size limit synchronously.
1400 */
1401static int nss_n2h_set_queue_limit_sync(struct ctl_table *ctl, int write, void __user *buffer,
1402 size_t *lenp, loff_t *ppos, uint32_t core_id)
1403{
1404 struct nss_top_instance *nss_top = &nss_top_main;
1405 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_id];
1406 struct nss_n2h_msg nim;
1407 struct nss_n2h_queue_limit_config *nnqlc = NULL;
1408 int ret, current_val;
1409 nss_tx_status_t nss_tx_status;
1410
1411 /*
1412 * Take a snap shot of current value
1413 */
1414 current_val = nss_n2h_queue_limit[core_id];
1415
1416 /*
1417 * Write the variable with user input
1418 */
1419 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1420 if (ret || (!write)) {
1421 return ret;
1422 }
1423
1424 /*
1425 * We dont allow shortening of the queue size at run-time
1426 */
1427 if (nss_n2h_queue_limit[core_id] < current_val) {
1428 nss_warning("%p: New queue limit %d less than previous value %d. Cant allow shortening\n",
1429 nss_ctx, nss_n2h_queue_limit[core_id], current_val);
1430 nss_n2h_queue_limit[core_id] = current_val;
1431 return NSS_TX_FAILURE;
1432 }
1433
1434 memset(&nim, 0, sizeof(struct nss_n2h_msg));
1435 nss_n2h_msg_init(&nim, NSS_N2H_INTERFACE,
1436 NSS_TX_METADATA_TYPE_N2H_QUEUE_LIMIT_CFG,
1437 sizeof(struct nss_n2h_queue_limit_config), nss_n2h_queue_limit_callback, NULL);
1438
1439 nnqlc = &nim.msg.ql_cfg;
1440 nnqlc->qlimit = nss_n2h_queue_limit[core_id];
1441
1442 /*
1443 * Send synchronous message to firmware
1444 */
1445 down(&nss_n2h_q_lim_pvt.sem);
1446
1447 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nim);
1448 if (nss_tx_status != NSS_TX_SUCCESS) {
1449 nss_warning("%p: n2h queue limit message send failed\n", nss_ctx);
1450 nss_n2h_queue_limit[core_id] = current_val;
1451 up(&nss_n2h_q_lim_pvt.sem);
1452 return nss_tx_status;
1453 }
1454
1455 ret = wait_for_completion_timeout(&nss_n2h_q_lim_pvt.complete, msecs_to_jiffies(NSS_N2H_TX_TIMEOUT));
1456 if (!ret) {
1457 nss_warning("%p: Timeout expired for queue limit sync message\n", nss_ctx);
1458 nss_n2h_queue_limit[core_id] = current_val;
1459 up(&nss_n2h_q_lim_pvt.sem);
1460 return NSS_TX_FAILURE;
1461 }
1462
1463 /*
1464 * If setting the queue limit failed, reset the value to original value
1465 */
1466 if (nss_n2h_q_lim_pvt.response != NSS_CMN_RESPONSE_ACK) {
1467 nss_n2h_queue_limit[core_id] = current_val;
1468 }
1469
1470 up(&nss_n2h_q_lim_pvt.sem);
1471 return NSS_TX_SUCCESS;
1472}
1473
1474/*
1475 * nss_n2h_queue_limit_core0_handler()
1476 * Sets the n2h queue size limit for core0
1477 */
1478static int nss_n2h_queue_limit_core0_handler(struct ctl_table *ctl,
1479 int write, void __user *buffer,
1480 size_t *lenp, loff_t *ppos)
1481{
1482 return nss_n2h_set_queue_limit_sync(ctl, write, buffer, lenp, ppos,
1483 NSS_CORE_0);
1484}
1485
1486/*
1487 * nss_n2h_queue_limit_core1_handler()
1488 * Sets the n2h queue size limit for core1
1489 */
1490static int nss_n2h_queue_limit_core1_handler(struct ctl_table *ctl,
1491 int write, void __user *buffer,
1492 size_t *lenp, loff_t *ppos)
1493{
1494 return nss_n2h_set_queue_limit_sync(ctl, write, buffer, lenp, ppos,
1495 NSS_CORE_1);
1496}
1497
Sakthi Vignesh Radhakrishnanf9823102019-03-05 15:38:36 -08001498/*
1499 * nss_n2h_host_bp_cfg_callback()
1500 * Callback function for back pressure configuration.
1501 */
1502static void nss_n2h_host_bp_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
1503{
1504 struct nss_ctx_instance *nss_ctx __maybe_unused = (struct nss_ctx_instance *)app_data;
1505 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
1506 nss_n2h_host_bp_cfg_pvt.response = NSS_FAILURE;
1507 complete(&nss_n2h_host_bp_cfg_pvt.complete);
1508 nss_warning("%p: n2h back pressure configuration failed : %d\n", nss_ctx, nnm->cm.error);
1509 return;
1510 }
1511
1512 nss_info("%p: n2h back pressure configuration succeeded: %d\n", nss_ctx, nnm->cm.error);
1513 nss_n2h_host_bp_cfg_pvt.response = NSS_SUCCESS;
1514 complete(&nss_n2h_host_bp_cfg_pvt.complete);
1515}
1516
1517/*
1518 * nss_n2h_host_bp_cfg()
1519 * Send Message to n2h to enable back pressure.
1520 */
1521static nss_tx_status_t nss_n2h_host_bp_cfg_sync(struct nss_ctx_instance *nss_ctx, int enable_bp)
1522{
1523 struct nss_n2h_msg nnm;
1524 nss_tx_status_t nss_tx_status;
1525 int ret;
1526
1527 down(&nss_n2h_host_bp_cfg_pvt.sem);
1528 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_HOST_BACK_PRESSURE_CFG,
1529 sizeof(struct nss_n2h_host_back_pressure),
1530 nss_n2h_host_bp_cfg_callback,
1531 (void *)nss_ctx);
1532
1533 nnm.msg.host_bp_cfg.enable = enable_bp;
1534
1535 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1536 if (nss_tx_status != NSS_TX_SUCCESS) {
1537 nss_warning("%p: nss_tx error setting back pressure\n", nss_ctx);
1538 up(&nss_n2h_host_bp_cfg_pvt.sem);
1539 return NSS_FAILURE;
1540 }
1541
1542 /*
1543 * Blocking call, wait till we get ACK for this msg.
1544 */
1545 ret = wait_for_completion_timeout(&nss_n2h_host_bp_cfg_pvt.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
1546 if (ret == 0) {
1547 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
1548 up(&nss_n2h_host_bp_cfg_pvt.sem);
1549 return NSS_FAILURE;
1550 }
1551
1552 /*
1553 * Response received from NSS FW
1554 */
1555 if (nss_n2h_host_bp_cfg_pvt.response == NSS_FAILURE) {
1556 up(&nss_n2h_host_bp_cfg_pvt.sem);
1557 return NSS_FAILURE;
1558 }
1559
1560 up(&nss_n2h_host_bp_cfg_pvt.sem);
1561 return NSS_SUCCESS;
1562}
1563
1564/*
1565 * nss_n2h_host_bp_cfg_handler()
1566 * Enable n2h back pressure.
1567 */
1568static int nss_n2h_host_bp_cfg_handler(struct ctl_table *ctl, int write,
1569 void __user *buffer, size_t *lenp, loff_t *ppos, uint32_t core_id)
1570{
1571 struct nss_top_instance *nss_top = &nss_top_main;
1572 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_id];
1573 int ret, ret_bp, current_state;
1574 current_state = nss_n2h_host_bp_config[core_id];
1575 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1576
1577 if (ret != NSS_SUCCESS) {
1578 return ret;
1579 }
1580
1581 if (!write) {
1582 return ret;
1583 }
1584
1585 if ((nss_n2h_host_bp_config[core_id] != 0) && (nss_n2h_host_bp_config[core_id] != 1)) {
1586 nss_info_always("Invalid input value. Valid values are 0 and 1\n");
1587 nss_n2h_host_bp_config[core_id] = current_state;
1588 return ret;
1589 }
1590
1591 nss_info("Configuring n2h back pressure\n");
1592 ret_bp = nss_n2h_host_bp_cfg_sync(nss_ctx, nss_n2h_host_bp_config[core_id]);
1593
1594 if (ret_bp != NSS_SUCCESS) {
1595 nss_warning("%p: n2h back pressure config failed\n", nss_ctx);
1596 nss_n2h_host_bp_config[core_id] = current_state;
1597 }
1598
1599 return ret_bp;
1600}
1601
1602/*
1603 * nss_n2h_host_bp_cfg_core0_handler()
1604 * Enable n2h back pressure in core 0.
1605 */
1606static int nss_n2h_host_bp_cfg_core0_handler(struct ctl_table *ctl, int write,
1607 void __user *buffer, size_t *lenp, loff_t *ppos)
1608{
1609 return nss_n2h_host_bp_cfg_handler(ctl, write, buffer, lenp, ppos, NSS_CORE_0);
1610}
1611
1612/*
1613 * nss_n2h_host_bp_cfg_core1_handler()
1614 * Enable n2h back pressure in core 1.
1615 */
1616static int nss_n2h_host_bp_cfg_core1_handler(struct ctl_table *ctl, int write,
1617 void __user *buffer, size_t *lenp, loff_t *ppos)
1618{
1619 return nss_n2h_host_bp_cfg_handler(ctl, write, buffer, lenp, ppos, NSS_CORE_1);
1620}
1621
Suman Ghosh9f7b3702018-09-21 19:51:40 +05301622static struct ctl_table nss_n2h_table_single_core[] = {
1623 {
1624 .procname = "n2h_empty_pool_buf_core0",
1625 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0],
1626 .maxlen = sizeof(int),
1627 .mode = 0644,
1628 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core0_handler,
1629 },
1630 {
1631 .procname = "n2h_empty_paged_pool_buf_core0",
1632 .data = &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0],
1633 .maxlen = sizeof(int),
1634 .mode = 0644,
1635 .proc_handler = &nss_n2h_empty_paged_pool_buf_cfg_core0_handler,
1636 },
1637 {
1638 .procname = "n2h_low_water_core0",
1639 .data = &nss_n2h_water_mark[NSS_CORE_0][0],
1640 .maxlen = sizeof(int),
1641 .mode = 0644,
1642 .proc_handler = &nss_n2h_water_mark_core0_handler,
1643 },
1644 {
1645 .procname = "n2h_high_water_core0",
1646 .data = &nss_n2h_water_mark[NSS_CORE_0][1],
1647 .maxlen = sizeof(int),
1648 .mode = 0644,
1649 .proc_handler = &nss_n2h_water_mark_core0_handler,
1650 },
1651 {
1652 .procname = "n2h_paged_low_water_core0",
1653 .data = &nss_n2h_paged_water_mark[NSS_CORE_0][0],
1654 .maxlen = sizeof(int),
1655 .mode = 0644,
1656 .proc_handler = &nss_n2h_paged_water_mark_core0_handler,
1657 },
1658 {
1659 .procname = "n2h_paged_high_water_core0",
1660 .data = &nss_n2h_paged_water_mark[NSS_CORE_0][1],
1661 .maxlen = sizeof(int),
1662 .mode = 0644,
1663 .proc_handler = &nss_n2h_paged_water_mark_core0_handler,
1664 },
1665 {
1666 .procname = "n2h_wifi_pool_buf",
1667 .data = &nss_n2h_wifi_pool_buf_cfg,
1668 .maxlen = sizeof(int),
1669 .mode = 0644,
1670 .proc_handler = &nss_n2h_wifi_payloads_handler,
1671 },
1672 {
1673 .procname = "mitigation_core0",
1674 .data = &nss_n2h_core0_mitigation_cfg,
1675 .maxlen = sizeof(int),
1676 .mode = 0644,
1677 .proc_handler = &nss_n2h_mitigationcfg_core0_handler,
1678 },
1679 {
1680 .procname = "extra_pbuf_core0",
1681 .data = &nss_n2h_core0_add_buf_pool_size,
1682 .maxlen = sizeof(int),
1683 .mode = 0644,
1684 .proc_handler = &nss_n2h_buf_cfg_core0_handler,
1685 },
1686 {
1687 .procname = "n2h_queue_limit_core0",
1688 .data = &nss_n2h_queue_limit[NSS_CORE_0],
1689 .maxlen = sizeof(int),
1690 .mode = 0644,
1691 .proc_handler = &nss_n2h_queue_limit_core0_handler,
1692 },
Sakthi Vignesh Radhakrishnanf9823102019-03-05 15:38:36 -08001693 {
1694 .procname = "host_bp_enable0",
1695 .data = &nss_n2h_host_bp_config[NSS_CORE_0],
1696 .maxlen = sizeof(int),
1697 .mode = 0644,
1698 .proc_handler = &nss_n2h_host_bp_cfg_core0_handler,
1699 },
Suman Ghosh9f7b3702018-09-21 19:51:40 +05301700
1701 { }
1702};
1703
1704static struct ctl_table nss_n2h_table_multi_core[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001705 {
Saurabh Misra71034db2015-06-04 16:18:38 -07001706 .procname = "n2h_empty_pool_buf_core0",
1707 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0],
1708 .maxlen = sizeof(int),
1709 .mode = 0644,
1710 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core0_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -08001711 },
1712 {
Saurabh Misra71034db2015-06-04 16:18:38 -07001713 .procname = "n2h_empty_pool_buf_core1",
1714 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1],
1715 .maxlen = sizeof(int),
1716 .mode = 0644,
1717 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core1_handler,
1718 },
1719 {
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001720 .procname = "n2h_empty_paged_pool_buf_core0",
1721 .data = &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0],
1722 .maxlen = sizeof(int),
1723 .mode = 0644,
1724 .proc_handler = &nss_n2h_empty_paged_pool_buf_cfg_core0_handler,
1725 },
1726 {
1727 .procname = "n2h_empty_paged_pool_buf_core1",
1728 .data = &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_1],
1729 .maxlen = sizeof(int),
1730 .mode = 0644,
1731 .proc_handler = &nss_n2h_empty_paged_pool_buf_cfg_core1_handler,
1732 },
1733
1734 {
Saurabh Misra71034db2015-06-04 16:18:38 -07001735 .procname = "n2h_low_water_core0",
1736 .data = &nss_n2h_water_mark[NSS_CORE_0][0],
1737 .maxlen = sizeof(int),
1738 .mode = 0644,
1739 .proc_handler = &nss_n2h_water_mark_core0_handler,
1740 },
1741 {
1742 .procname = "n2h_low_water_core1",
1743 .data = &nss_n2h_water_mark[NSS_CORE_1][0],
1744 .maxlen = sizeof(int),
1745 .mode = 0644,
1746 .proc_handler = &nss_n2h_water_mark_core1_handler,
1747 },
1748 {
1749 .procname = "n2h_high_water_core0",
1750 .data = &nss_n2h_water_mark[NSS_CORE_0][1],
1751 .maxlen = sizeof(int),
1752 .mode = 0644,
1753 .proc_handler = &nss_n2h_water_mark_core0_handler,
1754 },
1755 {
1756 .procname = "n2h_high_water_core1",
1757 .data = &nss_n2h_water_mark[NSS_CORE_1][1],
1758 .maxlen = sizeof(int),
1759 .mode = 0644,
1760 .proc_handler = &nss_n2h_water_mark_core1_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -08001761 },
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +05301762 {
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001763 .procname = "n2h_paged_low_water_core0",
1764 .data = &nss_n2h_paged_water_mark[NSS_CORE_0][0],
1765 .maxlen = sizeof(int),
1766 .mode = 0644,
1767 .proc_handler = &nss_n2h_paged_water_mark_core0_handler,
1768 },
1769 {
1770 .procname = "n2h_paged_low_water_core1",
1771 .data = &nss_n2h_paged_water_mark[NSS_CORE_1][0],
1772 .maxlen = sizeof(int),
1773 .mode = 0644,
1774 .proc_handler = &nss_n2h_paged_water_mark_core1_handler,
1775 },
1776 {
1777 .procname = "n2h_paged_high_water_core0",
1778 .data = &nss_n2h_paged_water_mark[NSS_CORE_0][1],
1779 .maxlen = sizeof(int),
1780 .mode = 0644,
1781 .proc_handler = &nss_n2h_paged_water_mark_core0_handler,
1782 },
1783 {
1784 .procname = "n2h_paged_high_water_core1",
1785 .data = &nss_n2h_paged_water_mark[NSS_CORE_1][1],
1786 .maxlen = sizeof(int),
1787 .mode = 0644,
1788 .proc_handler = &nss_n2h_paged_water_mark_core1_handler,
1789 },
1790 {
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +05301791 .procname = "n2h_wifi_pool_buf",
1792 .data = &nss_n2h_wifi_pool_buf_cfg,
1793 .maxlen = sizeof(int),
1794 .mode = 0644,
1795 .proc_handler = &nss_n2h_wifi_payloads_handler,
1796 },
Stephen Wang49b474b2016-03-25 10:40:30 -07001797 {
Stephen Wang49b474b2016-03-25 10:40:30 -07001798 .procname = "mitigation_core0",
1799 .data = &nss_n2h_core0_mitigation_cfg,
1800 .maxlen = sizeof(int),
1801 .mode = 0644,
1802 .proc_handler = &nss_n2h_mitigationcfg_core0_handler,
1803 },
1804 {
1805 .procname = "mitigation_core1",
1806 .data = &nss_n2h_core1_mitigation_cfg,
1807 .maxlen = sizeof(int),
1808 .mode = 0644,
1809 .proc_handler = &nss_n2h_mitigationcfg_core1_handler,
1810 },
1811 {
1812 .procname = "extra_pbuf_core0",
1813 .data = &nss_n2h_core0_add_buf_pool_size,
1814 .maxlen = sizeof(int),
1815 .mode = 0644,
1816 .proc_handler = &nss_n2h_buf_cfg_core0_handler,
1817 },
1818 {
1819 .procname = "extra_pbuf_core1",
1820 .data = &nss_n2h_core1_add_buf_pool_size,
1821 .maxlen = sizeof(int),
1822 .mode = 0644,
1823 .proc_handler = &nss_n2h_buf_cfg_core1_handler,
1824 },
Shashank Balashankar4162f572018-08-21 13:32:34 -07001825 {
1826 .procname = "n2h_queue_limit_core0",
1827 .data = &nss_n2h_queue_limit[NSS_CORE_0],
1828 .maxlen = sizeof(int),
1829 .mode = 0644,
1830 .proc_handler = &nss_n2h_queue_limit_core0_handler,
1831 },
1832 {
1833 .procname = "n2h_queue_limit_core1",
1834 .data = &nss_n2h_queue_limit[NSS_CORE_1],
1835 .maxlen = sizeof(int),
1836 .mode = 0644,
1837 .proc_handler = &nss_n2h_queue_limit_core1_handler,
1838 },
Sakthi Vignesh Radhakrishnanf9823102019-03-05 15:38:36 -08001839 {
1840 .procname = "host_bp_enable0",
1841 .data = &nss_n2h_host_bp_config[NSS_CORE_0],
1842 .maxlen = sizeof(int),
1843 .mode = 0644,
1844 .proc_handler = &nss_n2h_host_bp_cfg_core0_handler,
1845 },
1846 {
1847 .procname = "host_bp_enable1",
1848 .data = &nss_n2h_host_bp_config[NSS_CORE_1],
1849 .maxlen = sizeof(int),
1850 .mode = 0644,
1851 .proc_handler = &nss_n2h_host_bp_cfg_core1_handler,
1852 },
Vijay Dewangan488e5372014-12-29 21:40:11 -08001853 { }
1854};
1855
Suman Ghosh9f7b3702018-09-21 19:51:40 +05301856/*
1857 * This table will be overwritten during single-core registration
1858 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001859static struct ctl_table nss_n2h_dir[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001860 {
1861 .procname = "n2hcfg",
1862 .mode = 0555,
Suman Ghosh9f7b3702018-09-21 19:51:40 +05301863 .child = nss_n2h_table_multi_core,
Vijay Dewangan488e5372014-12-29 21:40:11 -08001864 },
1865 { }
1866};
1867
Stephen Wang52e6d342016-03-29 15:02:33 -07001868static struct ctl_table nss_n2h_root_dir[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001869 {
1870 .procname = "nss",
1871 .mode = 0555,
1872 .child = nss_n2h_dir,
1873 },
1874 { }
1875};
1876
Stephen Wang52e6d342016-03-29 15:02:33 -07001877static struct ctl_table nss_n2h_root[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001878 {
1879 .procname = "dev",
1880 .mode = 0555,
1881 .child = nss_n2h_root_dir,
1882 },
1883 { }
1884};
1885
1886static struct ctl_table_header *nss_n2h_header;
1887
1888/*
Amit Guptaca2ea682019-01-24 17:18:46 +05301889 * nss_n2h_cfg_empty_pool_size()
1890 * Config empty buffer pool
1891 */
1892nss_tx_status_t nss_n2h_cfg_empty_pool_size(struct nss_ctx_instance *nss_ctx, uint32_t pool_sz)
1893{
1894 struct nss_n2h_msg nnm;
1895 struct nss_n2h_empty_pool_buf *nnepbcm;
1896 nss_tx_status_t nss_tx_status;
1897
1898 if (pool_sz < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) {
1899 nss_warning("%p: setting pool size %d < min number of buffer",
1900 nss_ctx, pool_sz);
1901 return NSS_TX_FAILURE;
1902 }
1903
1904 if (pool_sz > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ) {
1905 nss_warning("%p: setting pool size %d > max number of buffer",
1906 nss_ctx, pool_sz);
1907 return NSS_TX_FAILURE;
1908 }
1909
1910 nss_info("%p: update number of empty buffer pool size: %d\n",
1911 nss_ctx, pool_sz);
1912
1913 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1914 NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG,
1915 sizeof(struct nss_n2h_empty_pool_buf), NULL, 0);
1916
1917 nnepbcm = &nnm.msg.empty_pool_buf_cfg;
1918 nnepbcm->pool_size = htonl(pool_sz);
1919 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1920
1921 if (nss_tx_status != NSS_TX_SUCCESS) {
1922 nss_warning("%p: nss_tx error empty buffer pool: %d\n", nss_ctx, pool_sz);
1923 return nss_tx_status;
1924 }
1925
1926 return nss_tx_status;
1927}
1928
1929/*
Amit Gupta738f97e2019-01-11 18:54:55 +05301930 * nss_n2h_paged_buf_pool_init()
1931 * Sends a command down to NSS to initialize paged buffer pool
1932 */
1933nss_tx_status_t nss_n2h_paged_buf_pool_init(struct nss_ctx_instance *nss_ctx)
1934{
1935 struct nss_n2h_msg nnm;
1936 nss_tx_status_t nss_tx_status;
1937
1938 /*
1939 * No additional information needed at this point
1940 */
1941 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1942 NSS_TX_METADATA_TYPE_N2H_PAGED_BUFFER_POOL_INIT,
1943 sizeof(struct nss_n2h_paged_buffer_pool_init),
1944 NULL,
1945 NULL);
1946
1947 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1948 if (nss_tx_status != NSS_TX_SUCCESS) {
1949 nss_warning("%p: failed to send paged buf configuration init command to NSS\n",
1950 nss_ctx);
1951 return NSS_TX_FAILURE;
1952 }
1953
1954 return NSS_TX_SUCCESS;
1955}
1956
1957/*
Stephen Wang49b474b2016-03-25 10:40:30 -07001958 * nss_n2h_flush_payloads()
Cemil Coskun9165c762017-12-04 14:35:24 -08001959 * Sends a command down to NSS for flushing all payloads
Stephen Wang49b474b2016-03-25 10:40:30 -07001960 */
1961nss_tx_status_t nss_n2h_flush_payloads(struct nss_ctx_instance *nss_ctx)
1962{
1963 struct nss_n2h_msg nnm;
1964 struct nss_n2h_flush_payloads *nnflshpl;
1965 nss_tx_status_t nss_tx_status;
1966
1967 nnflshpl = &nnm.msg.flush_payloads;
1968
1969 /*
1970 * TODO: No additional information sent in message
1971 * as of now. Need to initialize message content accordingly
1972 * if needed.
1973 */
1974 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1975 NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS,
1976 sizeof(struct nss_n2h_flush_payloads),
1977 NULL,
1978 NULL);
1979
1980 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1981 if (nss_tx_status != NSS_TX_SUCCESS) {
1982 nss_warning("%p: failed to send flush payloads command to NSS\n",
1983 nss_ctx);
1984
1985 return NSS_TX_FAILURE;
1986 }
1987
1988 return NSS_TX_SUCCESS;
1989}
1990
1991/*
Vijay Dewangan488e5372014-12-29 21:40:11 -08001992 * nss_n2h_msg_init()
Stephen Wang49b474b2016-03-25 10:40:30 -07001993 * Initialize n2h message.
Vijay Dewangan488e5372014-12-29 21:40:11 -08001994 */
1995void nss_n2h_msg_init(struct nss_n2h_msg *nim, uint16_t if_num, uint32_t type,
Vijay Dewangan634ce592015-01-07 17:21:09 -08001996 uint32_t len, nss_n2h_msg_callback_t cb, void *app_data)
Vijay Dewangan488e5372014-12-29 21:40:11 -08001997{
1998 nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data);
1999}
2000
Vijay Dewangan488e5372014-12-29 21:40:11 -08002001/*
Vijay Dewangan488e5372014-12-29 21:40:11 -08002002 * nss_n2h_tx_msg()
Cemil Coskun9165c762017-12-04 14:35:24 -08002003 * Send messages to NSS n2h package.
Vijay Dewangan488e5372014-12-29 21:40:11 -08002004 */
2005nss_tx_status_t nss_n2h_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_n2h_msg *nnm)
2006{
Vijay Dewangan488e5372014-12-29 21:40:11 -08002007 struct nss_cmn_msg *ncm = &nnm->cm;
Vijay Dewangan488e5372014-12-29 21:40:11 -08002008
2009 /*
2010 * Sanity check the message
2011 */
2012 if (ncm->interface != NSS_N2H_INTERFACE) {
2013 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
2014 return NSS_TX_FAILURE;
2015 }
2016
2017 if (ncm->type >= NSS_METADATA_TYPE_N2H_MAX) {
2018 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
2019 return NSS_TX_FAILURE;
2020 }
2021
Stephen Wang3e2dbd12018-03-14 17:28:17 -07002022 return nss_core_send_cmd(nss_ctx, nnm, sizeof(*nnm), NSS_NBUF_PAYLOAD_SIZE);
Vijay Dewangan488e5372014-12-29 21:40:11 -08002023}
2024
Vijay Dewangan488e5372014-12-29 21:40:11 -08002025/*
2026 * nss_n2h_notify_register()
2027 * Register to received N2H events.
2028 *
2029 * NOTE: Do we want to pass an nss_ctx here so that we can register for n2h on any core?
2030 */
2031struct nss_ctx_instance *nss_n2h_notify_register(int core, nss_n2h_msg_callback_t cb, void *app_data)
2032{
Suman Ghosh9f7b3702018-09-21 19:51:40 +05302033 if (core >= nss_top_main.num_nss) {
Vijay Dewangan488e5372014-12-29 21:40:11 -08002034 nss_warning("Input core number %d is wrong \n", core);
2035 return NULL;
2036 }
2037 /*
2038 * TODO: We need to have a new array in support of the new API
2039 * TODO: If we use a per-context array, we would move the array into nss_ctx based.
2040 */
2041 nss_n2h_rd[core].n2h_callback = cb;
2042 nss_n2h_rd[core].app_data = app_data;
2043 return &nss_top_main.nss[core];
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05302044}
2045
2046/*
2047 * nss_n2h_register_handler()
2048 */
Thomas Wu91f4bdf2017-06-09 12:03:02 -07002049void nss_n2h_register_handler(struct nss_ctx_instance *nss_ctx)
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05302050{
ratheesh kannothab436af2017-07-20 08:51:07 +05302051 sema_init(&nss_n2h_q_cfg_pvt.sem, 1);
2052 init_completion(&nss_n2h_q_cfg_pvt.complete);
2053
Thomas Wu91f4bdf2017-06-09 12:03:02 -07002054 nss_core_register_handler(nss_ctx, NSS_N2H_INTERFACE, nss_n2h_interface_handler, NULL);
Yu Huang8c107082017-07-24 14:58:26 -07002055
Cemil Coskun26be6162019-06-28 15:44:48 -07002056 if (nss_ctx->id == NSS_CORE_0) {
2057 nss_n2h_stats_dentry_create();
2058 }
Stephen Wang49b474b2016-03-25 10:40:30 -07002059}
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -07002060
Stephen Wang49b474b2016-03-25 10:40:30 -07002061/*
Suman Ghosh9f7b3702018-09-21 19:51:40 +05302062 * nss_n2h_single_core_register_sysctl()
Stephen Wang49b474b2016-03-25 10:40:30 -07002063 */
Suman Ghosh9f7b3702018-09-21 19:51:40 +05302064void nss_n2h_single_core_register_sysctl(void)
2065{
2066 /*
2067 * RPS sema init
2068 */
2069 sema_init(&nss_n2h_rcp.sem, 1);
2070 init_completion(&nss_n2h_rcp.complete);
2071
2072 /*
2073 * MITIGATION sema init for core0
2074 */
2075 sema_init(&nss_n2h_mitigationcp[NSS_CORE_0].sem, 1);
2076 init_completion(&nss_n2h_mitigationcp[NSS_CORE_0].complete);
2077
2078 /*
2079 * PBUF addition sema init for core0
2080 */
2081 sema_init(&nss_n2h_bufcp[NSS_CORE_0].sem, 1);
2082 init_completion(&nss_n2h_bufcp[NSS_CORE_0].complete);
2083
2084 /*
2085 * Core0
2086 */
2087 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_0].sem, 1);
2088 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_0].complete);
2089 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.pool_size =
2090 nss_n2h_empty_pool_buf_cfg[NSS_CORE_0];
2091 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.low_water =
2092 nss_n2h_water_mark[NSS_CORE_0][0];
2093 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.high_water =
2094 nss_n2h_water_mark[NSS_CORE_0][1];
2095 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.pool_size =
2096 nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0];
2097 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.low_water =
2098 nss_n2h_paged_water_mark[NSS_CORE_0][0];
2099 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.high_water =
2100 nss_n2h_paged_water_mark[NSS_CORE_0][1];
2101
2102 /*
2103 * WiFi pool buf cfg sema init
2104 */
2105 sema_init(&nss_n2h_wp.sem, 1);
2106 init_completion(&nss_n2h_wp.complete);
2107
2108 /*
2109 * N2H queue config sema init
2110 */
2111 sema_init(&nss_n2h_q_lim_pvt.sem, 1);
2112 init_completion(&nss_n2h_q_lim_pvt.complete);
2113
Sakthi Vignesh Radhakrishnanf9823102019-03-05 15:38:36 -08002114 /*
2115 * Back pressure config sema init
2116 */
2117 sema_init(&nss_n2h_host_bp_cfg_pvt.sem, 1);
2118 init_completion(&nss_n2h_host_bp_cfg_pvt.complete);
2119
Suman Ghosh9f7b3702018-09-21 19:51:40 +05302120 nss_n2h_notify_register(NSS_CORE_0, NULL, NULL);
2121
2122 /*
2123 * Register sysctl table.
2124 */
2125 nss_n2h_dir[0].child = nss_n2h_table_single_core;
2126 nss_n2h_header = register_sysctl_table(nss_n2h_root);
2127}
2128
2129/*
2130 * nss_n2h_multi_core_register_sysctl()
2131 */
2132void nss_n2h_multi_core_register_sysctl(void)
Stephen Wang49b474b2016-03-25 10:40:30 -07002133{
Vijay Dewangan634ce592015-01-07 17:21:09 -08002134 /*
2135 * RPS sema init
2136 */
2137 sema_init(&nss_n2h_rcp.sem, 1);
2138 init_completion(&nss_n2h_rcp.complete);
2139
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05302140 /*
2141 * MITIGATION sema init for core0
2142 */
2143 sema_init(&nss_n2h_mitigationcp[NSS_CORE_0].sem, 1);
2144 init_completion(&nss_n2h_mitigationcp[NSS_CORE_0].complete);
2145
2146 /*
2147 * MITIGATION sema init for core1
2148 */
2149 sema_init(&nss_n2h_mitigationcp[NSS_CORE_1].sem, 1);
2150 init_completion(&nss_n2h_mitigationcp[NSS_CORE_1].complete);
2151
2152 /*
2153 * PBUF addition sema init for core0
2154 */
2155 sema_init(&nss_n2h_bufcp[NSS_CORE_0].sem, 1);
2156 init_completion(&nss_n2h_bufcp[NSS_CORE_0].complete);
2157
2158 /*
2159 * PBUF addition sema init for core1
2160 */
2161 sema_init(&nss_n2h_bufcp[NSS_CORE_1].sem, 1);
2162 init_completion(&nss_n2h_bufcp[NSS_CORE_1].complete);
Vijay Dewangan634ce592015-01-07 17:21:09 -08002163
Stephen Wang49b474b2016-03-25 10:40:30 -07002164 /*
2165 * Core0
2166 */
2167 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_0].sem, 1);
2168 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_0].complete);
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002169 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.pool_size =
Stephen Wang49b474b2016-03-25 10:40:30 -07002170 nss_n2h_empty_pool_buf_cfg[NSS_CORE_0];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002171 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.low_water =
Stephen Wang49b474b2016-03-25 10:40:30 -07002172 nss_n2h_water_mark[NSS_CORE_0][0];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002173 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.high_water =
Stephen Wang49b474b2016-03-25 10:40:30 -07002174 nss_n2h_water_mark[NSS_CORE_0][1];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002175 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.pool_size =
2176 nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0];
2177 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.low_water =
2178 nss_n2h_paged_water_mark[NSS_CORE_0][0];
2179 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.high_water =
2180 nss_n2h_paged_water_mark[NSS_CORE_0][1];
2181
Stephen Wang49b474b2016-03-25 10:40:30 -07002182 /*
2183 * Core1
2184 */
2185 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_1].sem, 1);
2186 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_1].complete);
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002187 nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool_info.pool_size =
Stephen Wang49b474b2016-03-25 10:40:30 -07002188 nss_n2h_empty_pool_buf_cfg[NSS_CORE_1];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002189 nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool_info.low_water =
Stephen Wang49b474b2016-03-25 10:40:30 -07002190 nss_n2h_water_mark[NSS_CORE_1][0];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002191 nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool_info.high_water =
Stephen Wang49b474b2016-03-25 10:40:30 -07002192 nss_n2h_water_mark[NSS_CORE_1][1];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002193 nss_n2h_nepbcfgp[NSS_CORE_1].empty_paged_buf_pool_info.pool_size =
2194 nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_1];
2195 nss_n2h_nepbcfgp[NSS_CORE_1].empty_paged_buf_pool_info.low_water =
2196 nss_n2h_paged_water_mark[NSS_CORE_1][0];
2197 nss_n2h_nepbcfgp[NSS_CORE_1].empty_paged_buf_pool_info.high_water =
2198 nss_n2h_paged_water_mark[NSS_CORE_1][1];
2199
Stephen Wang49b474b2016-03-25 10:40:30 -07002200 /*
2201 * WiFi pool buf cfg sema init
2202 */
2203 sema_init(&nss_n2h_wp.sem, 1);
2204 init_completion(&nss_n2h_wp.complete);
2205
Shashank Balashankar4162f572018-08-21 13:32:34 -07002206 /*
2207 * N2H queue config sema init
2208 */
2209 sema_init(&nss_n2h_q_lim_pvt.sem, 1);
2210 init_completion(&nss_n2h_q_lim_pvt.complete);
2211
Sakthi Vignesh Radhakrishnanf9823102019-03-05 15:38:36 -08002212 /*
2213 * Back pressure config sema init
2214 */
2215 sema_init(&nss_n2h_host_bp_cfg_pvt.sem, 1);
2216 init_completion(&nss_n2h_host_bp_cfg_pvt.complete);
2217
Vijay Dewangan488e5372014-12-29 21:40:11 -08002218 nss_n2h_notify_register(NSS_CORE_0, NULL, NULL);
2219 nss_n2h_notify_register(NSS_CORE_1, NULL, NULL);
2220
Stephen Wang49b474b2016-03-25 10:40:30 -07002221 /*
2222 * Register sysctl table.
2223 */
2224 nss_n2h_header = register_sysctl_table(nss_n2h_root);
2225}
2226
2227/*
2228 * nss_n2h_unregister_sysctl()
2229 * Unregister sysctl specific to n2h
2230 */
2231void nss_n2h_unregister_sysctl(void)
2232{
2233 /*
2234 * Unregister sysctl table.
2235 */
2236 if (nss_n2h_header) {
2237 unregister_sysctl_table(nss_n2h_header);
2238 }
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05302239}
Vijay Dewangan488e5372014-12-29 21:40:11 -08002240
2241EXPORT_SYMBOL(nss_n2h_notify_register);