blob: dd414f3171cc8bd1f57a21ad874fc50099fb8a65 [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;
Neelansh Mittalfa08fba2019-12-12 12:25:27 +0530257 nss_n2h_wp.wifi_pool = ntohl(nnm->msg.wp.payloads);
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530258 complete(&nss_n2h_wp.complete);
259}
260
261/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700262 * nss_n2h_get_payload_info()
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700263 * Gets Payload information.
Vijay Dewangan488e5372014-12-29 21:40:11 -0800264 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700265static 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 -0700266{
267 struct nss_top_instance *nss_top = &nss_top_main;
268 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
Saurabh Misra71034db2015-06-04 16:18:38 -0700269 nss_tx_status_t nss_tx_status;
270 int ret = NSS_FAILURE;
271
272 /*
273 * Note that semaphore should be already held.
274 */
275
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700276 nss_tx_status = nss_n2h_tx_msg(nss_ctx, nnm);
Saurabh Misra71034db2015-06-04 16:18:38 -0700277
278 if (nss_tx_status != NSS_TX_SUCCESS) {
Stephen Wangaed46332016-12-12 17:29:03 -0800279 nss_warning("%p: core %d nss_tx error errorn", nss_ctx, (int)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700280 return NSS_FAILURE;
281 }
282
283 /*
284 * Blocking call, wait till we get ACK for this msg.
285 */
286 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
287 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
288 if (ret == 0) {
Stephen Wangaed46332016-12-12 17:29:03 -0800289 nss_warning("%p: core %d waiting for ack timed out\n", nss_ctx, (int)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700290 return NSS_FAILURE;
291 }
292
293 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
Stephen Wangaed46332016-12-12 17:29:03 -0800294 nss_warning("%p: core %d response returned failure\n", nss_ctx, (int)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700295 return NSS_FAILURE;
296 }
297
298 return NSS_SUCCESS;
299}
300
301/*
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700302 * nss_n2h_get_default_payload_info()
303 * Gets the default payload information.
304 */
305static int nss_n2h_get_default_payload_info(nss_ptr_t core_num)
306{
307 struct nss_n2h_msg nnm;
308
309 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
310 NSS_TX_METADATA_TYPE_GET_WATER_MARK,
311 sizeof(struct nss_n2h_payload_info),
312 nss_n2h_payload_stats_callback,
313 (void *)core_num);
314
315 return nss_n2h_get_payload_info(core_num, &nnm,
316 &nnm.msg.payload_info);
317}
318
319/*
320 * nss_n2h_get_paged_payload_info()
321 * Gets the paged payload information.
322 */
323static int nss_n2h_get_paged_payload_info(nss_ptr_t core_num)
324{
325 struct nss_n2h_msg nnm;
326
327 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
328 NSS_TX_METADATA_TYPE_GET_PAGED_WATER_MARK,
329 sizeof(struct nss_n2h_payload_info),
330 nss_n2h_payload_stats_callback,
331 (void *)core_num);
332
333 return nss_n2h_get_payload_info(core_num, &nnm,
334 &nnm.msg.paged_payload_info);
335}
336
337/*
Amit Guptaca2ea682019-01-24 17:18:46 +0530338 * nss_n2h_set_empty_buf_pool()
Saurabh Misra71034db2015-06-04 16:18:38 -0700339 * Sets empty pool buffer
340 */
Amit Guptaca2ea682019-01-24 17:18:46 +0530341static int nss_n2h_set_empty_buf_pool(struct ctl_table *ctl, int write,
Saurabh Misra71034db2015-06-04 16:18:38 -0700342 void __user *buffer,
343 size_t *lenp, loff_t *ppos,
Stephen Wangaed46332016-12-12 17:29:03 -0800344 nss_ptr_t core_num, int *new_val)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800345{
346 struct nss_top_instance *nss_top = &nss_top_main;
347 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
348 struct nss_n2h_msg nnm;
349 struct nss_n2h_empty_pool_buf *nnepbcm;
350 nss_tx_status_t nss_tx_status;
351 int ret = NSS_FAILURE;
352
353 /*
354 * Acquiring semaphore
355 */
356 down(&nss_n2h_nepbcfgp[core_num].sem);
357
358 /*
359 * Take snap shot of current value
360 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700361 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size = *new_val;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800362
Saurabh Misra71034db2015-06-04 16:18:38 -0700363 if (!write) {
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700364 ret = nss_n2h_get_default_payload_info(core_num);
365 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size;
Saurabh Misra71034db2015-06-04 16:18:38 -0700366 if (ret == NSS_FAILURE) {
367 up(&nss_n2h_nepbcfgp[core_num].sem);
368 return -EBUSY;
369 }
370
371 up(&nss_n2h_nepbcfgp[core_num].sem);
372
373 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
374 return ret;
375 }
376
Vijay Dewangan488e5372014-12-29 21:40:11 -0800377 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
Saurabh Misra71034db2015-06-04 16:18:38 -0700378 if (ret) {
Vijay Dewangan488e5372014-12-29 21:40:11 -0800379 up(&nss_n2h_nepbcfgp[core_num].sem);
380 return ret;
381 }
382
Vijay Dewangan488e5372014-12-29 21:40:11 -0800383 if ((*new_val < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700384 nss_warning("%p: core %d setting %d < min number of buffer",
Stephen Wangaed46332016-12-12 17:29:03 -0800385 nss_ctx, (int)core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800386 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800387 }
388
389 nss_info("%p: core %d number of empty pool buffer is : %d\n",
Stephen Wangaed46332016-12-12 17:29:03 -0800390 nss_ctx, (int)core_num, *new_val);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800391
392 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
393 NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG,
394 sizeof(struct nss_n2h_empty_pool_buf),
Saurabh Misra71034db2015-06-04 16:18:38 -0700395 nss_n2h_payload_stats_callback,
Stephen Wangaed46332016-12-12 17:29:03 -0800396 (nss_ptr_t *)core_num);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800397
398 nnepbcm = &nnm.msg.empty_pool_buf_cfg;
399 nnepbcm->pool_size = htonl(*new_val);
400 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
401
402 if (nss_tx_status != NSS_TX_SUCCESS) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700403 nss_warning("%p: core %d nss_tx error empty pool buffer: %d\n",
Stephen Wangaed46332016-12-12 17:29:03 -0800404 nss_ctx, (int)core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800405 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800406 }
407
408 /*
409 * Blocking call, wait till we get ACK for this msg.
410 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700411 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
412 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
Vijay Dewangan488e5372014-12-29 21:40:11 -0800413 if (ret == 0) {
Stephen Wangaed46332016-12-12 17:29:03 -0800414 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx, (int)core_num);
Stephen Wang06761022015-03-03 16:38:42 -0800415 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800416 }
417
418 /*
419 * ACK/NACK received from NSS FW
420 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
421 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
422 */
423 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
Stephen Wang06761022015-03-03 16:38:42 -0800424 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800425 }
426
427 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700428 return 0;
Stephen Wang06761022015-03-03 16:38:42 -0800429
430failure:
431 /*
432 * Restore the current_value to its previous state
433 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700434 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size;
435 up(&nss_n2h_nepbcfgp[core_num].sem);
436 return NSS_FAILURE;
437}
438
439/*
440 * nss_n2h_set_empty_paged_pool_buf()
441 * Sets empty paged pool buffer
442 */
443static int nss_n2h_set_empty_paged_pool_buf(struct ctl_table *ctl, int write,
444 void __user *buffer,
445 size_t *lenp, loff_t *ppos,
446 nss_ptr_t core_num, int *new_val)
447{
448 struct nss_top_instance *nss_top = &nss_top_main;
449 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
450 struct nss_n2h_msg nnm;
451 struct nss_n2h_empty_pool_buf *nneppbcm;
452 nss_tx_status_t nss_tx_status;
453 int ret = NSS_FAILURE;
454
455 /*
456 * Acquiring semaphore
457 */
458 down(&nss_n2h_nepbcfgp[core_num].sem);
459
460 /*
461 * Take snap shot of current value
462 */
463 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size = *new_val;
464
465 if (!write) {
466 ret = nss_n2h_get_paged_payload_info(core_num);
467 *new_val = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size;
468 if (ret == NSS_FAILURE) {
469 up(&nss_n2h_nepbcfgp[core_num].sem);
470 return -EBUSY;
471 }
472
473 up(&nss_n2h_nepbcfgp[core_num].sem);
474
475 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
476 return ret;
477 }
478
479 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
480 if (ret) {
481 up(&nss_n2h_nepbcfgp[core_num].sem);
482 return ret;
483 }
484
485 if ((*new_val < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
486 nss_warning("%p: core %d setting %d < min number of buffer",
487 nss_ctx, (int)core_num, *new_val);
488 goto failure;
489 }
490
491 nss_info("%p: core %d number of empty paged pool buffer is : %d\n",
492 nss_ctx, (int)core_num, *new_val);
493
494 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
495 NSS_TX_METADATA_TYPE_N2H_EMPTY_PAGED_POOL_BUF_CFG,
496 sizeof(struct nss_n2h_empty_pool_buf),
497 nss_n2h_payload_stats_callback,
498 (nss_ptr_t *)core_num);
499
500 nneppbcm = &nnm.msg.empty_pool_buf_cfg;
501 nneppbcm->pool_size = htonl(*new_val);
502 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
503
504 if (nss_tx_status != NSS_TX_SUCCESS) {
505 nss_warning("%p: core %d nss_tx error empty paged pool buffer: %d\n",
506 nss_ctx, (int)core_num, *new_val);
507 goto failure;
508 }
509
510 /*
511 * Blocking call, wait till we get ACK for this msg.
512 */
513 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
514 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
515 if (ret == 0) {
516 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx, (int)core_num);
517 goto failure;
518 }
519
520 /*
521 * ACK/NACK received from NSS FW
522 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
523 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
524 */
525 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
526 goto failure;
527 }
528
529 up(&nss_n2h_nepbcfgp[core_num].sem);
530 return 0;
531
532failure:
533 /*
534 * Restore the current_value to its previous state
535 */
536 *new_val = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size;
Saurabh Misra71034db2015-06-04 16:18:38 -0700537 up(&nss_n2h_nepbcfgp[core_num].sem);
538 return NSS_FAILURE;
539}
540
541/*
542 * nss_n2h_set_water_mark()
543 * Sets water mark for N2H SOS
544 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700545static int nss_n2h_set_water_mark(struct ctl_table *ctl, int write,
Saurabh Misra71034db2015-06-04 16:18:38 -0700546 void __user *buffer,
547 size_t *lenp, loff_t *ppos,
Stephen Wangaed46332016-12-12 17:29:03 -0800548 uint32_t core_num, int *low, int *high)
Saurabh Misra71034db2015-06-04 16:18:38 -0700549{
550 struct nss_top_instance *nss_top = &nss_top_main;
551 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
552 struct nss_n2h_msg nnm;
553 struct nss_n2h_water_mark *wm;
554 nss_tx_status_t nss_tx_status;
555 int ret = NSS_FAILURE;
556
557 /*
558 * Acquiring semaphore
559 */
560 down(&nss_n2h_nepbcfgp[core_num].sem);
561
562 /*
563 * Take snap shot of current value
564 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700565 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water = *low;
566 nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water = *high;
Saurabh Misra71034db2015-06-04 16:18:38 -0700567
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700568 if (!write || *low == -1 || *high == -1) {
569 ret = nss_n2h_get_default_payload_info(core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700570 if (ret == NSS_FAILURE) {
571 up(&nss_n2h_nepbcfgp[core_num].sem);
572 return -EBUSY;
573 }
574
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700575 *low = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water;
576 *high = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water;
Saurabh Misra71034db2015-06-04 16:18:38 -0700577 }
578
579 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700580 if (!write || ret) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700581 up(&nss_n2h_nepbcfgp[core_num].sem);
582 return ret;
583 }
584
Saurabh Misra71034db2015-06-04 16:18:38 -0700585 if ((*low < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) ||
586 (*high < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
587 nss_warning("%p: core %d setting %d, %d < min number of buffer",
588 nss_ctx, core_num, *low, *high);
589 goto failure;
590 }
591
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530592 if ((*low > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ) ||
593 (*high > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700594 nss_warning("%p: core %d setting %d, %d is > upper limit",
595 nss_ctx, core_num, *low, *high);
596 goto failure;
597 }
598
599 if (*low > *high) {
600 nss_warning("%p: core %d setting low %d is more than high %d",
601 nss_ctx, core_num, *low, *high);
602 goto failure;
603 }
604
605 nss_info("%p: core %d number of low : %d and high : %d\n",
606 nss_ctx, core_num, *low, *high);
607
608 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
609 NSS_TX_METADATA_TYPE_SET_WATER_MARK,
610 sizeof(struct nss_n2h_water_mark),
611 nss_n2h_payload_stats_callback,
Stephen Wangaed46332016-12-12 17:29:03 -0800612 (void *)(nss_ptr_t)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700613
614 wm = &nnm.msg.wm;
615 wm->low_water = htonl(*low);
616 wm->high_water = htonl(*high);
617 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
618
619 if (nss_tx_status != NSS_TX_SUCCESS) {
620 nss_warning("%p: core %d nss_tx error setting : %d, %d\n",
621 nss_ctx, core_num, *low, *high);
622 goto failure;
623 }
624
625 /*
626 * Blocking call, wait till we get ACK for this msg.
627 */
628 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
629 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
630 if (ret == 0) {
631 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
632 core_num);
633 goto failure;
634 }
635
636 /*
637 * ACK/NACK received from NSS FW
638 */
639 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response)
640 goto failure;
641
642 up(&nss_n2h_nepbcfgp[core_num].sem);
643 return NSS_SUCCESS;
644
645failure:
646 /*
647 * Restore the current_value to its previous state
648 */
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700649 *low = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water;
650 *high = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water;
651 up(&nss_n2h_nepbcfgp[core_num].sem);
652 return -EINVAL;
653}
654
655/*
656 * nss_n2h_set_paged_water_mark()
657 * Sets water mark for paged pool N2H SOS
658 */
659static int nss_n2h_set_paged_water_mark(struct ctl_table *ctl, int write,
660 void __user *buffer,
661 size_t *lenp, loff_t *ppos,
662 uint32_t core_num, int *low, int *high)
663{
664 struct nss_top_instance *nss_top = &nss_top_main;
665 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
666 struct nss_n2h_msg nnm;
667 struct nss_n2h_water_mark *pwm;
668 nss_tx_status_t nss_tx_status;
669 int ret = NSS_FAILURE;
670
671 /*
672 * Acquiring semaphore
673 */
674 down(&nss_n2h_nepbcfgp[core_num].sem);
675
676 /*
677 * Take snap shot of current value
678 */
679 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water = *low;
680 nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water = *high;
681
682 if (!write || *low == -1 || *high == -1) {
683 ret = nss_n2h_get_paged_payload_info(core_num);
684 if (ret == NSS_FAILURE) {
685 up(&nss_n2h_nepbcfgp[core_num].sem);
686 return -EBUSY;
687 }
688
689 *low = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water;
690 *high = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water;
691 }
692
693 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
694 if (!write || ret) {
695 up(&nss_n2h_nepbcfgp[core_num].sem);
696 return ret;
697 }
698
699 if ((*low < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) ||
700 (*high < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
701 nss_warning("%p: core %d setting %d, %d < min number of buffer",
702 nss_ctx, core_num, *low, *high);
703 goto failure;
704 }
705
706 if ((*low > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ) ||
707 (*high > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) {
708 nss_warning("%p: core %d setting %d, %d is > upper limit",
709 nss_ctx, core_num, *low, *high);
710 goto failure;
711 }
712
713 if (*low > *high) {
714 nss_warning("%p: core %d setting low %d is more than high %d",
715 nss_ctx, core_num, *low, *high);
716 goto failure;
717 }
718
719 nss_info("%p: core %d number of low : %d and high : %d\n",
720 nss_ctx, core_num, *low, *high);
721
722 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
723 NSS_TX_METADATA_TYPE_SET_PAGED_WATER_MARK,
724 sizeof(struct nss_n2h_water_mark),
725 nss_n2h_payload_stats_callback,
726 (void *)(nss_ptr_t)core_num);
727
728 pwm = &nnm.msg.wm_paged;
729 pwm->low_water = htonl(*low);
730 pwm->high_water = htonl(*high);
731 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
732
733 if (nss_tx_status != NSS_TX_SUCCESS) {
734 nss_warning("%p: core %d nss_tx error setting : %d, %d\n",
735 nss_ctx, core_num, *low, *high);
736 goto failure;
737 }
738
739 /*
740 * Blocking call, wait till we get ACK for this msg.
741 */
742 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
743 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
744 if (ret == 0) {
745 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
746 core_num);
747 goto failure;
748 }
749
750 /*
751 * ACK/NACK received from NSS FW
752 */
753 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response)
754 goto failure;
755
756 up(&nss_n2h_nepbcfgp[core_num].sem);
757 return NSS_SUCCESS;
758
759failure:
760 /*
761 * Restore the current_value to its previous state
762 */
763 *low = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water;
764 *high = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water;
Stephen Wang06761022015-03-03 16:38:42 -0800765 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700766 return -EINVAL;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800767}
768
769/*
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530770 * nss_n2h_cfg_wifi_pool()
771 * Sets number of wifi payloads to adjust high water mark for N2H SoS
772 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700773static int nss_n2h_cfg_wifi_pool(struct ctl_table *ctl, int write,
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530774 void __user *buffer,
775 size_t *lenp, loff_t *ppos,
776 int *payloads)
777{
778 struct nss_top_instance *nss_top = &nss_top_main;
779 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
780 struct nss_n2h_msg nnm;
781 struct nss_n2h_wifi_payloads *wp;
782 nss_tx_status_t nss_tx_status;
783 int ret = NSS_FAILURE;
784
785 /*
786 * Acquiring semaphore
787 */
788 down(&nss_n2h_wp.sem);
789
790 if (!write) {
791 *payloads = nss_n2h_wp.wifi_pool;
792
793 up(&nss_n2h_wp.sem);
794 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
795 return ret;
796 }
797
798 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
799 if (ret) {
800 up(&nss_n2h_wp.sem);
801 return ret;
802 }
803
804 /*
805 * If payloads parameter is not set, we do
806 * nothing.
807 */
808 if (*payloads == -1)
809 goto failure;
810
811 if ((*payloads < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
812 nss_warning("%p: wifi setting %d < min number of buffer",
813 nss_ctx, *payloads);
814 goto failure;
815 }
816
817 if ((*payloads > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) {
818 nss_warning("%p: wifi setting %d > max number of buffer",
819 nss_ctx, *payloads);
820 goto failure;
821 }
822
823 nss_info("%p: wifi payloads : %d\n",
824 nss_ctx, *payloads);
825
826 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
827 NSS_TX_METADATA_TYPE_N2H_WIFI_POOL_BUF_CFG,
828 sizeof(struct nss_n2h_wifi_payloads),
829 nss_n2h_set_wifi_payloads_callback,
830 (void *)nss_ctx);
831
832 wp = &nnm.msg.wp;
833 wp->payloads = htonl(*payloads);
834 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
835
836 if (nss_tx_status != NSS_TX_SUCCESS) {
837 nss_warning("%p: wifi setting %d nss_tx error",
838 nss_ctx, *payloads);
839 goto failure;
840 }
841
842 /*
843 * Blocking call, wait till we get ACK for this msg.
844 */
845 ret = wait_for_completion_timeout(&nss_n2h_wp.complete,
846 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
847 if (ret == 0) {
848 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
849 goto failure;
850 }
851
852 /*
853 * ACK/NACK received from NSS FW
854 */
855 if (NSS_FAILURE == nss_n2h_wp.response)
856 goto failure;
857
858 up(&nss_n2h_wp.sem);
859 return NSS_SUCCESS;
860
861failure:
862 up(&nss_n2h_wp.sem);
863 return -EINVAL;
864}
865
866/*
Vijay Dewangan488e5372014-12-29 21:40:11 -0800867 * nss_n2h_empty_pool_buf_core1_handler()
868 * Sets the number of empty buffer for core 1
869 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700870static int nss_n2h_empty_pool_buf_cfg_core1_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700871 int write, void __user *buffer,
872 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800873{
Amit Guptaca2ea682019-01-24 17:18:46 +0530874 return nss_n2h_set_empty_buf_pool(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700875 NSS_CORE_1, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800876}
877
878/*
879 * nss_n2h_empty_pool_buf_core0_handler()
880 * Sets the number of empty buffer for core 0
881 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700882static int nss_n2h_empty_pool_buf_cfg_core0_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700883 int write, void __user *buffer,
884 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800885{
Amit Guptaca2ea682019-01-24 17:18:46 +0530886 return nss_n2h_set_empty_buf_pool(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700887 NSS_CORE_0, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0]);
888}
889
890/*
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700891 * nss_n2h_empty_paged_pool_buf_cfg_core1_handler()
892 * Sets the number of empty paged buffer for core 1
893 */
894static int nss_n2h_empty_paged_pool_buf_cfg_core1_handler(struct ctl_table *ctl,
895 int write, void __user *buffer,
896 size_t *lenp, loff_t *ppos)
897{
898 return nss_n2h_set_empty_paged_pool_buf(ctl, write, buffer, lenp, ppos,
899 NSS_CORE_1, &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_1]);
900}
901
902/*
903 * nss_n2h_empty_paged_pool_buf_cfg_core0_handler()
904 * Sets the number of empty paged buffer for core 0
905 */
906static int nss_n2h_empty_paged_pool_buf_cfg_core0_handler(struct ctl_table *ctl,
907 int write, void __user *buffer,
908 size_t *lenp, loff_t *ppos)
909{
910 return nss_n2h_set_empty_paged_pool_buf(ctl, write, buffer, lenp, ppos,
911 NSS_CORE_0, &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0]);
912}
913
914/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700915 * nss_n2h_water_mark_core1_handler()
916 * Sets water mark for core 1
917 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700918static int nss_n2h_water_mark_core1_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700919 int write, void __user *buffer,
920 size_t *lenp, loff_t *ppos)
921{
922 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
923 NSS_CORE_1, &nss_n2h_water_mark[NSS_CORE_1][0],
924 &nss_n2h_water_mark[NSS_CORE_1][1]);
925}
926
927/*
928 * nss_n2h_water_mark_core0_handler()
929 * Sets water mark for core 0
930 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700931static int nss_n2h_water_mark_core0_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700932 int write, void __user *buffer,
933 size_t *lenp, loff_t *ppos)
934{
935 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
936 NSS_CORE_0, &nss_n2h_water_mark[NSS_CORE_0][0],
937 &nss_n2h_water_mark[NSS_CORE_0][1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800938}
939
Vijay Dewangan634ce592015-01-07 17:21:09 -0800940/*
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700941 * nss_n2h_paged_water_mark_core1_handler()
942 * Sets paged water mark for core 1
943 */
944static int nss_n2h_paged_water_mark_core1_handler(struct ctl_table *ctl,
945 int write, void __user *buffer,
946 size_t *lenp, loff_t *ppos)
947{
948 return nss_n2h_set_paged_water_mark(ctl, write, buffer, lenp, ppos,
949 NSS_CORE_1, &nss_n2h_paged_water_mark[NSS_CORE_1][0],
950 &nss_n2h_paged_water_mark[NSS_CORE_1][1]);
951}
952
Sachin Shashidhar475012b2017-03-13 16:56:07 -0700953/*
954 * nss_n2h_paged_water_mark_core0_handler()
955 * Sets paged water mark for core 0
956 */
957static int nss_n2h_paged_water_mark_core0_handler(struct ctl_table *ctl,
958 int write, void __user *buffer,
959 size_t *lenp, loff_t *ppos)
960{
961 return nss_n2h_set_paged_water_mark(ctl, write, buffer, lenp, ppos,
962 NSS_CORE_0, &nss_n2h_paged_water_mark[NSS_CORE_0][0],
963 &nss_n2h_paged_water_mark[NSS_CORE_0][1]);
964}
965
966/*
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530967 * nss_n2h_wifi_payloads_handler()
968 * Sets number of wifi payloads
969 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700970static int nss_n2h_wifi_payloads_handler(struct ctl_table *ctl,
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530971 int write, void __user *buffer,
972 size_t *lenp, loff_t *ppos)
973{
974 return nss_n2h_cfg_wifi_pool(ctl, write, buffer, lenp, ppos,
975 &nss_n2h_wifi_pool_buf_cfg);
976}
977
978/*
ratheesh kannothab436af2017-07-20 08:51:07 +0530979 * nss_n2h_update_queue_config_callback()
980 * Callback to handle the completion of queue config command
ratheesh kannoth024a6e82017-05-18 17:48:10 +0530981 */
ratheesh kannothab436af2017-07-20 08:51:07 +0530982static void nss_n2h_update_queue_config_callback(void *app_data, struct nss_n2h_msg *nim)
ratheesh kannoth024a6e82017-05-18 17:48:10 +0530983{
ratheesh kannothab436af2017-07-20 08:51:07 +0530984 if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
985 nss_warning("n2h Error response %d\n", nim->cm.response);
986 nss_n2h_q_cfg_pvt.response = NSS_TX_FAILURE;
987 } else {
988 nss_n2h_q_cfg_pvt.response = NSS_TX_SUCCESS;
989 }
990
991 complete(&nss_n2h_q_cfg_pvt.complete);
992}
993
994/*
995 * nss_n2h_update_queue_config_async()
996 * Asynchronous call to send pnode queue configuration.
997 */
998nss_tx_status_t nss_n2h_update_queue_config_async(struct nss_ctx_instance *nss_ctx, bool mq_en, uint16_t *qlimits)
999{
1000
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301001 struct nss_n2h_msg nnm;
1002 struct nss_n2h_pnode_queue_config *cfg;
1003 nss_tx_status_t status;
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301004 int i;
1005
1006 if (!mq_en) {
1007 return NSS_TX_SUCCESS;
1008 }
1009
ratheesh kannoth93ba95c2017-07-13 15:52:52 +05301010 /*
1011 * MQ mode doesnot make any sense if number of priority queues in NSS
1012 * is 1
1013 */
1014 if (NSS_MAX_NUM_PRI <= 1) {
1015 return NSS_TX_SUCCESS;
1016 }
1017
ratheesh kannothab436af2017-07-20 08:51:07 +05301018 memset(&nnm, 0, sizeof(struct nss_n2h_msg));
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301019
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301020 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1021 NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG,
1022 sizeof(struct nss_n2h_pnode_queue_config), NULL, 0);
1023
ratheesh kannothab436af2017-07-20 08:51:07 +05301024 cfg = &nnm.msg.pn_q_cfg;
1025
1026 /*
Cemil Coskun9165c762017-12-04 14:35:24 -08001027 * Update limits
1028 */
ratheesh kannothab436af2017-07-20 08:51:07 +05301029 for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
1030 cfg->qlimits[i] = qlimits[i];
1031 }
1032 cfg->mq_en = true;
1033
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301034 status = nss_n2h_tx_msg(nss_ctx, &nnm);
1035 if (status != NSS_TX_SUCCESS) {
1036 nss_warning("%p: nss_tx error to send pnode queue config\n", nss_ctx);
1037 return status;
1038 }
1039
1040 return NSS_TX_SUCCESS;
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301041}
ratheesh kannothab436af2017-07-20 08:51:07 +05301042EXPORT_SYMBOL(nss_n2h_update_queue_config_async);
1043
1044/*
1045 * nss_n2h_update_queue_config_sync()
1046 * Synchronous call to send pnode queue configuration.
1047 */
1048nss_tx_status_t nss_n2h_update_queue_config_sync(struct nss_ctx_instance *nss_ctx, bool mq_en, uint16_t *qlimits)
1049{
1050
1051 struct nss_n2h_msg nnm;
1052 struct nss_n2h_pnode_queue_config *cfg;
1053 nss_tx_status_t status;
1054 int ret, i;
1055
1056 if (!mq_en) {
1057 return NSS_TX_SUCCESS;
1058 }
1059
ratheesh kannoth93ba95c2017-07-13 15:52:52 +05301060 /*
1061 * MQ mode doesnot make any sense if number of priority queues in NSS
1062 * is 1
1063 */
1064 if (NSS_MAX_NUM_PRI <= 1) {
1065 return NSS_TX_SUCCESS;
1066 }
1067
ratheesh kannothab436af2017-07-20 08:51:07 +05301068 memset(&nnm, 0, sizeof(struct nss_n2h_msg));
1069
1070 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1071 NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG,
1072 sizeof(struct nss_n2h_pnode_queue_config), nss_n2h_update_queue_config_callback, 0);
1073
1074 cfg = &nnm.msg.pn_q_cfg;
1075
1076 /*
Cemil Coskun9165c762017-12-04 14:35:24 -08001077 * Update limits
1078 */
ratheesh kannothab436af2017-07-20 08:51:07 +05301079 for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
1080 cfg->qlimits[i] = qlimits[i];
1081 }
1082 cfg->mq_en = true;
1083
1084 down(&nss_n2h_q_cfg_pvt.sem);
1085
1086 status = nss_n2h_tx_msg(nss_ctx, &nnm);
1087
1088 if (status != NSS_TX_SUCCESS) {
1089 nss_warning("%p: n2h_tx_msg failed\n", nss_ctx);
1090 up(&nss_n2h_q_cfg_pvt.sem);
1091 return status;
1092 }
1093 ret = wait_for_completion_timeout(&nss_n2h_q_cfg_pvt.complete, msecs_to_jiffies(NSS_N2H_TX_TIMEOUT));
1094
1095 if (!ret) {
1096 nss_warning("%p: Timeout expired for pnode queue config sync message\n", nss_ctx);
1097 nss_n2h_q_cfg_pvt.response = NSS_TX_FAILURE;
1098 }
1099
1100 status = nss_n2h_q_cfg_pvt.response;
1101 up(&nss_n2h_q_cfg_pvt.sem);
1102 return status;
1103}
1104EXPORT_SYMBOL(nss_n2h_update_queue_config_sync);
ratheesh kannoth024a6e82017-05-18 17:48:10 +05301105
1106/*
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301107 * nss_n2h_mitigation_cfg()
1108 * Send Message to NSS to disable MITIGATION.
1109 */
Stephen Wang49b474b2016-03-25 10:40:30 -07001110static 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 +05301111{
1112 struct nss_n2h_msg nnm;
1113 struct nss_n2h_mitigation *mitigation_cfg;
1114 nss_tx_status_t nss_tx_status;
1115 int ret;
1116
1117 nss_assert(core_num < NSS_CORE_MAX);
1118
1119 down(&nss_n2h_mitigationcp[core_num].sem);
1120 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG,
1121 sizeof(struct nss_n2h_mitigation),
1122 nss_n2h_mitigation_cfg_callback,
1123 (void *)core_num);
1124
1125 mitigation_cfg = &nnm.msg.mitigation_cfg;
1126 mitigation_cfg->enable = enable_mitigation;
1127
1128 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1129
1130 if (nss_tx_status != NSS_TX_SUCCESS) {
1131 nss_warning("%p: nss_tx error setting mitigation\n", nss_ctx);
1132 goto failure;
1133 }
1134
1135 /*
1136 * Blocking call, wait till we get ACK for this msg.
1137 */
1138 ret = wait_for_completion_timeout(&nss_n2h_mitigationcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
1139 if (ret == 0) {
1140 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
1141 goto failure;
1142 }
1143
1144 /*
1145 * ACK/NACK received from NSS FW
1146 */
1147 if (NSS_FAILURE == nss_n2h_mitigationcp[core_num].response) {
1148 goto failure;
1149 }
1150
1151 up(&nss_n2h_mitigationcp[core_num].sem);
1152 return NSS_SUCCESS;
1153
1154failure:
1155 up(&nss_n2h_mitigationcp[core_num].sem);
1156 return NSS_FAILURE;
1157}
1158
1159static inline void nss_n2h_buf_pool_free(struct nss_n2h_buf_pool *buf_pool)
1160{
1161 int page_count;
1162 for (page_count = 0; page_count < buf_pool->nss_buf_num_pages; page_count++) {
Stephen Wang7df68832017-08-10 16:54:35 -07001163 kfree((void *)buf_pool->nss_buf_pool_vaddr[page_count]);
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301164 }
1165}
1166
1167/*
1168 * nss_n2h_buf_cfg()
1169 * Send Message to NSS to enable pbufs.
1170 */
Stephen Wang49b474b2016-03-25 10:40:30 -07001171static nss_tx_status_t nss_n2h_buf_pool_cfg(struct nss_ctx_instance *nss_ctx,
Tallapragada4b0161b2016-07-07 21:38:34 +05301172 int buf_pool_size, nss_core_id_t core_num)
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301173{
1174 static struct nss_n2h_msg nnm;
1175 struct nss_n2h_buf_pool *buf_pool;
1176 nss_tx_status_t nss_tx_status;
1177 int ret;
1178 int page_count;
1179 int num_pages = ALIGN(buf_pool_size, PAGE_SIZE)/PAGE_SIZE;
1180
1181 nss_assert(core_num < NSS_CORE_MAX);
1182
1183 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_METADATA_TYPE_N2H_ADD_BUF_POOL,
1184 sizeof(struct nss_n2h_buf_pool),
1185 nss_n2h_bufs_cfg_callback,
1186 (void *)core_num);
1187
1188 do {
1189
1190 down(&nss_n2h_bufcp[core_num].sem);
1191
1192 buf_pool = &nnm.msg.buf_pool;
1193 buf_pool->nss_buf_page_size = PAGE_SIZE;
1194
1195 for (page_count = 0; page_count < MAX_PAGES_PER_MSG && num_pages; page_count++, num_pages--) {
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301196 void *kern_addr = kzalloc(PAGE_SIZE, GFP_ATOMIC);
1197 if (!kern_addr) {
1198 BUG_ON(!page_count);
1199 break;
1200 }
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301201
Radha krishna Simha Jiguru60068fb2017-07-28 17:40:52 +05301202 kmemleak_not_leak(kern_addr);
Stephen Wang7df68832017-08-10 16:54:35 -07001203 buf_pool->nss_buf_pool_vaddr[page_count] = (nss_ptr_t)kern_addr;
Stephen Wangefd38512017-01-24 14:01:02 -08001204 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 +05301205 }
1206
1207 buf_pool->nss_buf_num_pages = page_count;
1208 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1209 if (nss_tx_status != NSS_TX_SUCCESS) {
1210
1211 nss_n2h_buf_pool_free(buf_pool);
1212 nss_warning("%p: nss_tx error setting pbuf\n", nss_ctx);
1213 goto failure;
1214 }
1215
1216 /*
Cemil Coskun9165c762017-12-04 14:35:24 -08001217 * Blocking call, wait till we get ACK for this msg.
1218 */
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301219 ret = wait_for_completion_timeout(&nss_n2h_bufcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
1220 if (ret == 0) {
1221 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
1222 goto failure;
1223 }
1224
1225 /*
1226 * ACK/NACK received from NSS FW
1227 */
1228 if (NSS_FAILURE == nss_n2h_bufcp[core_num].response) {
1229
1230 nss_n2h_buf_pool_free(buf_pool);
1231 goto failure;
1232 }
1233
1234 up(&nss_n2h_bufcp[core_num].sem);
1235 } while(num_pages);
1236
1237 return NSS_SUCCESS;
1238failure:
1239 up(&nss_n2h_bufcp[core_num].sem);
1240 return NSS_FAILURE;
1241}
1242
Stephen Wang49b474b2016-03-25 10:40:30 -07001243
1244/*
1245 * nss_mitigation_handler()
1246 * Enable NSS MITIGATION
1247 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001248static 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 -07001249{
1250 struct nss_top_instance *nss_top = &nss_top_main;
1251 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_0];
1252 int ret;
1253
1254 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1255 if (ret) {
1256 return ret;
1257 }
1258
1259 /*
1260 * It's a read operation
1261 */
1262 if (!write) {
1263 return ret;
1264 }
1265
1266 if (!nss_n2h_core0_mitigation_cfg) {
1267 printk(KERN_INFO "Disabling NSS MITIGATION\n");
1268 nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_0);
1269 return 0;
1270 }
1271 printk(KERN_INFO "Invalid input value.Valid value is 0, Runtime re-enabling not supported\n");
1272 return -EINVAL;
1273}
1274
1275/*
1276 * nss_mitigation_handler()
1277 * Enable NSS MITIGATION
1278 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001279static 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 -07001280{
1281 struct nss_top_instance *nss_top = &nss_top_main;
1282 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_1];
1283 int ret;
1284
1285 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1286 if (ret) {
1287 return ret;
1288 }
1289
1290 /*
1291 * It's a read operation
1292 */
1293 if (!write) {
1294 return ret;
1295 }
1296
1297 if (!nss_n2h_core1_mitigation_cfg) {
1298 printk(KERN_INFO "Disabling NSS MITIGATION\n");
1299 nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_1);
1300 return 0;
1301 }
1302 printk(KERN_INFO "Invalid input value.Valid value is 0, Runtime re-enabling not supported\n");
1303 return -EINVAL;
1304}
1305
1306/*
1307 * nss_buf_handler()
1308 * Add extra NSS bufs from host memory
1309 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001310static 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 -07001311{
1312 struct nss_top_instance *nss_top = &nss_top_main;
1313 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_0];
1314 int ret;
1315
1316 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1317 if (ret) {
1318 return ret;
1319 }
1320
1321 /*
1322 * It's a read operation
1323 */
1324 if (!write) {
1325 return ret;
1326 }
1327
1328 if (nss_ctx->buf_sz_allocated) {
1329 nss_n2h_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1330 return -EPERM;
1331 }
1332
1333 if ((nss_n2h_core0_add_buf_pool_size >= 1) && (nss_n2h_core0_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) {
1334 printk(KERN_INFO "configuring additional NSS pbufs\n");
1335 ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_n2h_core0_add_buf_pool_size, NSS_CORE_0);
1336 nss_n2h_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1337 printk(KERN_INFO "additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated);
1338 return ret;
1339 }
1340
1341 printk(KERN_INFO "Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE);
1342 return -EINVAL;
1343}
1344
1345/*
1346 * nss_n2h_buf_handler()
1347 * Add extra NSS bufs from host memory
1348 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001349static 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 -07001350{
1351 struct nss_top_instance *nss_top = &nss_top_main;
1352 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_1];
1353 int ret;
1354
1355 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1356 if (ret) {
1357 return ret;
1358 }
1359
1360 /*
1361 * It's a read operation
1362 */
1363 if (!write) {
1364 return ret;
1365 }
1366
1367 if (nss_ctx->buf_sz_allocated) {
1368 nss_n2h_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1369 return -EPERM;
1370 }
1371
1372 if ((nss_n2h_core1_add_buf_pool_size >= 1) && (nss_n2h_core1_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) {
1373 printk(KERN_INFO "configuring additional NSS pbufs\n");
1374 ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_n2h_core1_add_buf_pool_size, NSS_CORE_1);
1375 nss_n2h_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1376 printk(KERN_INFO "additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated);
1377 return ret;
1378 }
1379
1380 printk(KERN_INFO "Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE);
1381 return -EINVAL;
1382}
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301383
Shashank Balashankar4162f572018-08-21 13:32:34 -07001384/*
1385 * nss_n2h_queue_limit_callback()
1386 * Callback to handle the completion of queue limit command.
1387 */
1388static void nss_n2h_queue_limit_callback(void *app_data, struct nss_n2h_msg *nim)
1389{
1390 if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
1391 nss_warning("n2h error response %d\n", nim->cm.response);
1392 }
1393
1394 nss_n2h_q_lim_pvt.response = nim->cm.response;
1395 complete(&nss_n2h_q_lim_pvt.complete);
1396}
1397
1398/*
1399 * nss_n2h_set_queue_limit_sync()
1400 * Sets the n2h queue size limit synchronously.
1401 */
1402static int nss_n2h_set_queue_limit_sync(struct ctl_table *ctl, int write, void __user *buffer,
1403 size_t *lenp, loff_t *ppos, uint32_t core_id)
1404{
1405 struct nss_top_instance *nss_top = &nss_top_main;
1406 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_id];
1407 struct nss_n2h_msg nim;
1408 struct nss_n2h_queue_limit_config *nnqlc = NULL;
1409 int ret, current_val;
1410 nss_tx_status_t nss_tx_status;
1411
1412 /*
1413 * Take a snap shot of current value
1414 */
1415 current_val = nss_n2h_queue_limit[core_id];
1416
1417 /*
1418 * Write the variable with user input
1419 */
1420 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1421 if (ret || (!write)) {
1422 return ret;
1423 }
1424
1425 /*
1426 * We dont allow shortening of the queue size at run-time
1427 */
1428 if (nss_n2h_queue_limit[core_id] < current_val) {
1429 nss_warning("%p: New queue limit %d less than previous value %d. Cant allow shortening\n",
1430 nss_ctx, nss_n2h_queue_limit[core_id], current_val);
1431 nss_n2h_queue_limit[core_id] = current_val;
1432 return NSS_TX_FAILURE;
1433 }
1434
1435 memset(&nim, 0, sizeof(struct nss_n2h_msg));
1436 nss_n2h_msg_init(&nim, NSS_N2H_INTERFACE,
1437 NSS_TX_METADATA_TYPE_N2H_QUEUE_LIMIT_CFG,
1438 sizeof(struct nss_n2h_queue_limit_config), nss_n2h_queue_limit_callback, NULL);
1439
1440 nnqlc = &nim.msg.ql_cfg;
1441 nnqlc->qlimit = nss_n2h_queue_limit[core_id];
1442
1443 /*
1444 * Send synchronous message to firmware
1445 */
1446 down(&nss_n2h_q_lim_pvt.sem);
1447
1448 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nim);
1449 if (nss_tx_status != NSS_TX_SUCCESS) {
1450 nss_warning("%p: n2h queue limit message send failed\n", nss_ctx);
1451 nss_n2h_queue_limit[core_id] = current_val;
1452 up(&nss_n2h_q_lim_pvt.sem);
1453 return nss_tx_status;
1454 }
1455
1456 ret = wait_for_completion_timeout(&nss_n2h_q_lim_pvt.complete, msecs_to_jiffies(NSS_N2H_TX_TIMEOUT));
1457 if (!ret) {
1458 nss_warning("%p: Timeout expired for queue limit sync message\n", nss_ctx);
1459 nss_n2h_queue_limit[core_id] = current_val;
1460 up(&nss_n2h_q_lim_pvt.sem);
1461 return NSS_TX_FAILURE;
1462 }
1463
1464 /*
1465 * If setting the queue limit failed, reset the value to original value
1466 */
1467 if (nss_n2h_q_lim_pvt.response != NSS_CMN_RESPONSE_ACK) {
1468 nss_n2h_queue_limit[core_id] = current_val;
1469 }
1470
1471 up(&nss_n2h_q_lim_pvt.sem);
1472 return NSS_TX_SUCCESS;
1473}
1474
1475/*
1476 * nss_n2h_queue_limit_core0_handler()
1477 * Sets the n2h queue size limit for core0
1478 */
1479static int nss_n2h_queue_limit_core0_handler(struct ctl_table *ctl,
1480 int write, void __user *buffer,
1481 size_t *lenp, loff_t *ppos)
1482{
1483 return nss_n2h_set_queue_limit_sync(ctl, write, buffer, lenp, ppos,
1484 NSS_CORE_0);
1485}
1486
1487/*
1488 * nss_n2h_queue_limit_core1_handler()
1489 * Sets the n2h queue size limit for core1
1490 */
1491static int nss_n2h_queue_limit_core1_handler(struct ctl_table *ctl,
1492 int write, void __user *buffer,
1493 size_t *lenp, loff_t *ppos)
1494{
1495 return nss_n2h_set_queue_limit_sync(ctl, write, buffer, lenp, ppos,
1496 NSS_CORE_1);
1497}
1498
Sakthi Vignesh Radhakrishnanf9823102019-03-05 15:38:36 -08001499/*
1500 * nss_n2h_host_bp_cfg_callback()
1501 * Callback function for back pressure configuration.
1502 */
1503static void nss_n2h_host_bp_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
1504{
1505 struct nss_ctx_instance *nss_ctx __maybe_unused = (struct nss_ctx_instance *)app_data;
1506 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
1507 nss_n2h_host_bp_cfg_pvt.response = NSS_FAILURE;
1508 complete(&nss_n2h_host_bp_cfg_pvt.complete);
1509 nss_warning("%p: n2h back pressure configuration failed : %d\n", nss_ctx, nnm->cm.error);
1510 return;
1511 }
1512
1513 nss_info("%p: n2h back pressure configuration succeeded: %d\n", nss_ctx, nnm->cm.error);
1514 nss_n2h_host_bp_cfg_pvt.response = NSS_SUCCESS;
1515 complete(&nss_n2h_host_bp_cfg_pvt.complete);
1516}
1517
1518/*
1519 * nss_n2h_host_bp_cfg()
1520 * Send Message to n2h to enable back pressure.
1521 */
1522static nss_tx_status_t nss_n2h_host_bp_cfg_sync(struct nss_ctx_instance *nss_ctx, int enable_bp)
1523{
1524 struct nss_n2h_msg nnm;
1525 nss_tx_status_t nss_tx_status;
1526 int ret;
1527
1528 down(&nss_n2h_host_bp_cfg_pvt.sem);
1529 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_HOST_BACK_PRESSURE_CFG,
1530 sizeof(struct nss_n2h_host_back_pressure),
1531 nss_n2h_host_bp_cfg_callback,
1532 (void *)nss_ctx);
1533
1534 nnm.msg.host_bp_cfg.enable = enable_bp;
1535
1536 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1537 if (nss_tx_status != NSS_TX_SUCCESS) {
1538 nss_warning("%p: nss_tx error setting back pressure\n", nss_ctx);
1539 up(&nss_n2h_host_bp_cfg_pvt.sem);
1540 return NSS_FAILURE;
1541 }
1542
1543 /*
1544 * Blocking call, wait till we get ACK for this msg.
1545 */
1546 ret = wait_for_completion_timeout(&nss_n2h_host_bp_cfg_pvt.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
1547 if (ret == 0) {
1548 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
1549 up(&nss_n2h_host_bp_cfg_pvt.sem);
1550 return NSS_FAILURE;
1551 }
1552
1553 /*
1554 * Response received from NSS FW
1555 */
1556 if (nss_n2h_host_bp_cfg_pvt.response == NSS_FAILURE) {
1557 up(&nss_n2h_host_bp_cfg_pvt.sem);
1558 return NSS_FAILURE;
1559 }
1560
1561 up(&nss_n2h_host_bp_cfg_pvt.sem);
1562 return NSS_SUCCESS;
1563}
1564
1565/*
1566 * nss_n2h_host_bp_cfg_handler()
1567 * Enable n2h back pressure.
1568 */
1569static int nss_n2h_host_bp_cfg_handler(struct ctl_table *ctl, int write,
1570 void __user *buffer, size_t *lenp, loff_t *ppos, uint32_t core_id)
1571{
1572 struct nss_top_instance *nss_top = &nss_top_main;
1573 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_id];
1574 int ret, ret_bp, current_state;
1575 current_state = nss_n2h_host_bp_config[core_id];
1576 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1577
1578 if (ret != NSS_SUCCESS) {
1579 return ret;
1580 }
1581
1582 if (!write) {
1583 return ret;
1584 }
1585
1586 if ((nss_n2h_host_bp_config[core_id] != 0) && (nss_n2h_host_bp_config[core_id] != 1)) {
1587 nss_info_always("Invalid input value. Valid values are 0 and 1\n");
1588 nss_n2h_host_bp_config[core_id] = current_state;
1589 return ret;
1590 }
1591
1592 nss_info("Configuring n2h back pressure\n");
1593 ret_bp = nss_n2h_host_bp_cfg_sync(nss_ctx, nss_n2h_host_bp_config[core_id]);
1594
1595 if (ret_bp != NSS_SUCCESS) {
1596 nss_warning("%p: n2h back pressure config failed\n", nss_ctx);
1597 nss_n2h_host_bp_config[core_id] = current_state;
1598 }
1599
1600 return ret_bp;
1601}
1602
1603/*
1604 * nss_n2h_host_bp_cfg_core0_handler()
1605 * Enable n2h back pressure in core 0.
1606 */
1607static int nss_n2h_host_bp_cfg_core0_handler(struct ctl_table *ctl, int write,
1608 void __user *buffer, size_t *lenp, loff_t *ppos)
1609{
1610 return nss_n2h_host_bp_cfg_handler(ctl, write, buffer, lenp, ppos, NSS_CORE_0);
1611}
1612
1613/*
1614 * nss_n2h_host_bp_cfg_core1_handler()
1615 * Enable n2h back pressure in core 1.
1616 */
1617static int nss_n2h_host_bp_cfg_core1_handler(struct ctl_table *ctl, int write,
1618 void __user *buffer, size_t *lenp, loff_t *ppos)
1619{
1620 return nss_n2h_host_bp_cfg_handler(ctl, write, buffer, lenp, ppos, NSS_CORE_1);
1621}
1622
Suman Ghosh9f7b3702018-09-21 19:51:40 +05301623static struct ctl_table nss_n2h_table_single_core[] = {
1624 {
1625 .procname = "n2h_empty_pool_buf_core0",
1626 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0],
1627 .maxlen = sizeof(int),
1628 .mode = 0644,
1629 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core0_handler,
1630 },
1631 {
1632 .procname = "n2h_empty_paged_pool_buf_core0",
1633 .data = &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0],
1634 .maxlen = sizeof(int),
1635 .mode = 0644,
1636 .proc_handler = &nss_n2h_empty_paged_pool_buf_cfg_core0_handler,
1637 },
1638 {
1639 .procname = "n2h_low_water_core0",
1640 .data = &nss_n2h_water_mark[NSS_CORE_0][0],
1641 .maxlen = sizeof(int),
1642 .mode = 0644,
1643 .proc_handler = &nss_n2h_water_mark_core0_handler,
1644 },
1645 {
1646 .procname = "n2h_high_water_core0",
1647 .data = &nss_n2h_water_mark[NSS_CORE_0][1],
1648 .maxlen = sizeof(int),
1649 .mode = 0644,
1650 .proc_handler = &nss_n2h_water_mark_core0_handler,
1651 },
1652 {
1653 .procname = "n2h_paged_low_water_core0",
1654 .data = &nss_n2h_paged_water_mark[NSS_CORE_0][0],
1655 .maxlen = sizeof(int),
1656 .mode = 0644,
1657 .proc_handler = &nss_n2h_paged_water_mark_core0_handler,
1658 },
1659 {
1660 .procname = "n2h_paged_high_water_core0",
1661 .data = &nss_n2h_paged_water_mark[NSS_CORE_0][1],
1662 .maxlen = sizeof(int),
1663 .mode = 0644,
1664 .proc_handler = &nss_n2h_paged_water_mark_core0_handler,
1665 },
1666 {
1667 .procname = "n2h_wifi_pool_buf",
1668 .data = &nss_n2h_wifi_pool_buf_cfg,
1669 .maxlen = sizeof(int),
1670 .mode = 0644,
1671 .proc_handler = &nss_n2h_wifi_payloads_handler,
1672 },
1673 {
1674 .procname = "mitigation_core0",
1675 .data = &nss_n2h_core0_mitigation_cfg,
1676 .maxlen = sizeof(int),
1677 .mode = 0644,
1678 .proc_handler = &nss_n2h_mitigationcfg_core0_handler,
1679 },
1680 {
1681 .procname = "extra_pbuf_core0",
1682 .data = &nss_n2h_core0_add_buf_pool_size,
1683 .maxlen = sizeof(int),
1684 .mode = 0644,
1685 .proc_handler = &nss_n2h_buf_cfg_core0_handler,
1686 },
1687 {
1688 .procname = "n2h_queue_limit_core0",
1689 .data = &nss_n2h_queue_limit[NSS_CORE_0],
1690 .maxlen = sizeof(int),
1691 .mode = 0644,
1692 .proc_handler = &nss_n2h_queue_limit_core0_handler,
1693 },
Sakthi Vignesh Radhakrishnanf9823102019-03-05 15:38:36 -08001694 {
1695 .procname = "host_bp_enable0",
1696 .data = &nss_n2h_host_bp_config[NSS_CORE_0],
1697 .maxlen = sizeof(int),
1698 .mode = 0644,
1699 .proc_handler = &nss_n2h_host_bp_cfg_core0_handler,
1700 },
Suman Ghosh9f7b3702018-09-21 19:51:40 +05301701
1702 { }
1703};
1704
1705static struct ctl_table nss_n2h_table_multi_core[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001706 {
Saurabh Misra71034db2015-06-04 16:18:38 -07001707 .procname = "n2h_empty_pool_buf_core0",
1708 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0],
1709 .maxlen = sizeof(int),
1710 .mode = 0644,
1711 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core0_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -08001712 },
1713 {
Saurabh Misra71034db2015-06-04 16:18:38 -07001714 .procname = "n2h_empty_pool_buf_core1",
1715 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1],
1716 .maxlen = sizeof(int),
1717 .mode = 0644,
1718 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core1_handler,
1719 },
1720 {
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001721 .procname = "n2h_empty_paged_pool_buf_core0",
1722 .data = &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0],
1723 .maxlen = sizeof(int),
1724 .mode = 0644,
1725 .proc_handler = &nss_n2h_empty_paged_pool_buf_cfg_core0_handler,
1726 },
1727 {
1728 .procname = "n2h_empty_paged_pool_buf_core1",
1729 .data = &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_1],
1730 .maxlen = sizeof(int),
1731 .mode = 0644,
1732 .proc_handler = &nss_n2h_empty_paged_pool_buf_cfg_core1_handler,
1733 },
1734
1735 {
Saurabh Misra71034db2015-06-04 16:18:38 -07001736 .procname = "n2h_low_water_core0",
1737 .data = &nss_n2h_water_mark[NSS_CORE_0][0],
1738 .maxlen = sizeof(int),
1739 .mode = 0644,
1740 .proc_handler = &nss_n2h_water_mark_core0_handler,
1741 },
1742 {
1743 .procname = "n2h_low_water_core1",
1744 .data = &nss_n2h_water_mark[NSS_CORE_1][0],
1745 .maxlen = sizeof(int),
1746 .mode = 0644,
1747 .proc_handler = &nss_n2h_water_mark_core1_handler,
1748 },
1749 {
1750 .procname = "n2h_high_water_core0",
1751 .data = &nss_n2h_water_mark[NSS_CORE_0][1],
1752 .maxlen = sizeof(int),
1753 .mode = 0644,
1754 .proc_handler = &nss_n2h_water_mark_core0_handler,
1755 },
1756 {
1757 .procname = "n2h_high_water_core1",
1758 .data = &nss_n2h_water_mark[NSS_CORE_1][1],
1759 .maxlen = sizeof(int),
1760 .mode = 0644,
1761 .proc_handler = &nss_n2h_water_mark_core1_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -08001762 },
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +05301763 {
Sachin Shashidhar475012b2017-03-13 16:56:07 -07001764 .procname = "n2h_paged_low_water_core0",
1765 .data = &nss_n2h_paged_water_mark[NSS_CORE_0][0],
1766 .maxlen = sizeof(int),
1767 .mode = 0644,
1768 .proc_handler = &nss_n2h_paged_water_mark_core0_handler,
1769 },
1770 {
1771 .procname = "n2h_paged_low_water_core1",
1772 .data = &nss_n2h_paged_water_mark[NSS_CORE_1][0],
1773 .maxlen = sizeof(int),
1774 .mode = 0644,
1775 .proc_handler = &nss_n2h_paged_water_mark_core1_handler,
1776 },
1777 {
1778 .procname = "n2h_paged_high_water_core0",
1779 .data = &nss_n2h_paged_water_mark[NSS_CORE_0][1],
1780 .maxlen = sizeof(int),
1781 .mode = 0644,
1782 .proc_handler = &nss_n2h_paged_water_mark_core0_handler,
1783 },
1784 {
1785 .procname = "n2h_paged_high_water_core1",
1786 .data = &nss_n2h_paged_water_mark[NSS_CORE_1][1],
1787 .maxlen = sizeof(int),
1788 .mode = 0644,
1789 .proc_handler = &nss_n2h_paged_water_mark_core1_handler,
1790 },
1791 {
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +05301792 .procname = "n2h_wifi_pool_buf",
1793 .data = &nss_n2h_wifi_pool_buf_cfg,
1794 .maxlen = sizeof(int),
1795 .mode = 0644,
1796 .proc_handler = &nss_n2h_wifi_payloads_handler,
1797 },
Stephen Wang49b474b2016-03-25 10:40:30 -07001798 {
Stephen Wang49b474b2016-03-25 10:40:30 -07001799 .procname = "mitigation_core0",
1800 .data = &nss_n2h_core0_mitigation_cfg,
1801 .maxlen = sizeof(int),
1802 .mode = 0644,
1803 .proc_handler = &nss_n2h_mitigationcfg_core0_handler,
1804 },
1805 {
1806 .procname = "mitigation_core1",
1807 .data = &nss_n2h_core1_mitigation_cfg,
1808 .maxlen = sizeof(int),
1809 .mode = 0644,
1810 .proc_handler = &nss_n2h_mitigationcfg_core1_handler,
1811 },
1812 {
1813 .procname = "extra_pbuf_core0",
1814 .data = &nss_n2h_core0_add_buf_pool_size,
1815 .maxlen = sizeof(int),
1816 .mode = 0644,
1817 .proc_handler = &nss_n2h_buf_cfg_core0_handler,
1818 },
1819 {
1820 .procname = "extra_pbuf_core1",
1821 .data = &nss_n2h_core1_add_buf_pool_size,
1822 .maxlen = sizeof(int),
1823 .mode = 0644,
1824 .proc_handler = &nss_n2h_buf_cfg_core1_handler,
1825 },
Shashank Balashankar4162f572018-08-21 13:32:34 -07001826 {
1827 .procname = "n2h_queue_limit_core0",
1828 .data = &nss_n2h_queue_limit[NSS_CORE_0],
1829 .maxlen = sizeof(int),
1830 .mode = 0644,
1831 .proc_handler = &nss_n2h_queue_limit_core0_handler,
1832 },
1833 {
1834 .procname = "n2h_queue_limit_core1",
1835 .data = &nss_n2h_queue_limit[NSS_CORE_1],
1836 .maxlen = sizeof(int),
1837 .mode = 0644,
1838 .proc_handler = &nss_n2h_queue_limit_core1_handler,
1839 },
Sakthi Vignesh Radhakrishnanf9823102019-03-05 15:38:36 -08001840 {
1841 .procname = "host_bp_enable0",
1842 .data = &nss_n2h_host_bp_config[NSS_CORE_0],
1843 .maxlen = sizeof(int),
1844 .mode = 0644,
1845 .proc_handler = &nss_n2h_host_bp_cfg_core0_handler,
1846 },
1847 {
1848 .procname = "host_bp_enable1",
1849 .data = &nss_n2h_host_bp_config[NSS_CORE_1],
1850 .maxlen = sizeof(int),
1851 .mode = 0644,
1852 .proc_handler = &nss_n2h_host_bp_cfg_core1_handler,
1853 },
Vijay Dewangan488e5372014-12-29 21:40:11 -08001854 { }
1855};
1856
Suman Ghosh9f7b3702018-09-21 19:51:40 +05301857/*
1858 * This table will be overwritten during single-core registration
1859 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001860static struct ctl_table nss_n2h_dir[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001861 {
1862 .procname = "n2hcfg",
1863 .mode = 0555,
Suman Ghosh9f7b3702018-09-21 19:51:40 +05301864 .child = nss_n2h_table_multi_core,
Vijay Dewangan488e5372014-12-29 21:40:11 -08001865 },
1866 { }
1867};
1868
Stephen Wang52e6d342016-03-29 15:02:33 -07001869static struct ctl_table nss_n2h_root_dir[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001870 {
1871 .procname = "nss",
1872 .mode = 0555,
1873 .child = nss_n2h_dir,
1874 },
1875 { }
1876};
1877
Stephen Wang52e6d342016-03-29 15:02:33 -07001878static struct ctl_table nss_n2h_root[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001879 {
1880 .procname = "dev",
1881 .mode = 0555,
1882 .child = nss_n2h_root_dir,
1883 },
1884 { }
1885};
1886
1887static struct ctl_table_header *nss_n2h_header;
1888
1889/*
Amit Guptaca2ea682019-01-24 17:18:46 +05301890 * nss_n2h_cfg_empty_pool_size()
1891 * Config empty buffer pool
1892 */
1893nss_tx_status_t nss_n2h_cfg_empty_pool_size(struct nss_ctx_instance *nss_ctx, uint32_t pool_sz)
1894{
1895 struct nss_n2h_msg nnm;
1896 struct nss_n2h_empty_pool_buf *nnepbcm;
1897 nss_tx_status_t nss_tx_status;
1898
1899 if (pool_sz < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) {
1900 nss_warning("%p: setting pool size %d < min number of buffer",
1901 nss_ctx, pool_sz);
1902 return NSS_TX_FAILURE;
1903 }
1904
1905 if (pool_sz > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ) {
1906 nss_warning("%p: setting pool size %d > max number of buffer",
1907 nss_ctx, pool_sz);
1908 return NSS_TX_FAILURE;
1909 }
1910
1911 nss_info("%p: update number of empty buffer pool size: %d\n",
1912 nss_ctx, pool_sz);
1913
1914 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1915 NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG,
1916 sizeof(struct nss_n2h_empty_pool_buf), NULL, 0);
1917
1918 nnepbcm = &nnm.msg.empty_pool_buf_cfg;
1919 nnepbcm->pool_size = htonl(pool_sz);
1920 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1921
1922 if (nss_tx_status != NSS_TX_SUCCESS) {
1923 nss_warning("%p: nss_tx error empty buffer pool: %d\n", nss_ctx, pool_sz);
1924 return nss_tx_status;
1925 }
1926
1927 return nss_tx_status;
1928}
1929
1930/*
Amit Gupta738f97e2019-01-11 18:54:55 +05301931 * nss_n2h_paged_buf_pool_init()
1932 * Sends a command down to NSS to initialize paged buffer pool
1933 */
1934nss_tx_status_t nss_n2h_paged_buf_pool_init(struct nss_ctx_instance *nss_ctx)
1935{
1936 struct nss_n2h_msg nnm;
1937 nss_tx_status_t nss_tx_status;
1938
1939 /*
1940 * No additional information needed at this point
1941 */
1942 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1943 NSS_TX_METADATA_TYPE_N2H_PAGED_BUFFER_POOL_INIT,
1944 sizeof(struct nss_n2h_paged_buffer_pool_init),
1945 NULL,
1946 NULL);
1947
1948 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1949 if (nss_tx_status != NSS_TX_SUCCESS) {
1950 nss_warning("%p: failed to send paged buf configuration init command to NSS\n",
1951 nss_ctx);
1952 return NSS_TX_FAILURE;
1953 }
1954
1955 return NSS_TX_SUCCESS;
1956}
1957
1958/*
Stephen Wang49b474b2016-03-25 10:40:30 -07001959 * nss_n2h_flush_payloads()
Cemil Coskun9165c762017-12-04 14:35:24 -08001960 * Sends a command down to NSS for flushing all payloads
Stephen Wang49b474b2016-03-25 10:40:30 -07001961 */
1962nss_tx_status_t nss_n2h_flush_payloads(struct nss_ctx_instance *nss_ctx)
1963{
1964 struct nss_n2h_msg nnm;
1965 struct nss_n2h_flush_payloads *nnflshpl;
1966 nss_tx_status_t nss_tx_status;
1967
1968 nnflshpl = &nnm.msg.flush_payloads;
1969
1970 /*
1971 * TODO: No additional information sent in message
1972 * as of now. Need to initialize message content accordingly
1973 * if needed.
1974 */
1975 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1976 NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS,
1977 sizeof(struct nss_n2h_flush_payloads),
1978 NULL,
1979 NULL);
1980
1981 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1982 if (nss_tx_status != NSS_TX_SUCCESS) {
1983 nss_warning("%p: failed to send flush payloads command to NSS\n",
1984 nss_ctx);
1985
1986 return NSS_TX_FAILURE;
1987 }
1988
1989 return NSS_TX_SUCCESS;
1990}
1991
1992/*
Vijay Dewangan488e5372014-12-29 21:40:11 -08001993 * nss_n2h_msg_init()
Stephen Wang49b474b2016-03-25 10:40:30 -07001994 * Initialize n2h message.
Vijay Dewangan488e5372014-12-29 21:40:11 -08001995 */
1996void nss_n2h_msg_init(struct nss_n2h_msg *nim, uint16_t if_num, uint32_t type,
Vijay Dewangan634ce592015-01-07 17:21:09 -08001997 uint32_t len, nss_n2h_msg_callback_t cb, void *app_data)
Vijay Dewangan488e5372014-12-29 21:40:11 -08001998{
1999 nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data);
2000}
2001
Vijay Dewangan488e5372014-12-29 21:40:11 -08002002/*
Vijay Dewangan488e5372014-12-29 21:40:11 -08002003 * nss_n2h_tx_msg()
Cemil Coskun9165c762017-12-04 14:35:24 -08002004 * Send messages to NSS n2h package.
Vijay Dewangan488e5372014-12-29 21:40:11 -08002005 */
2006nss_tx_status_t nss_n2h_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_n2h_msg *nnm)
2007{
Vijay Dewangan488e5372014-12-29 21:40:11 -08002008 struct nss_cmn_msg *ncm = &nnm->cm;
Vijay Dewangan488e5372014-12-29 21:40:11 -08002009
2010 /*
2011 * Sanity check the message
2012 */
2013 if (ncm->interface != NSS_N2H_INTERFACE) {
2014 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
2015 return NSS_TX_FAILURE;
2016 }
2017
2018 if (ncm->type >= NSS_METADATA_TYPE_N2H_MAX) {
2019 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
2020 return NSS_TX_FAILURE;
2021 }
2022
Stephen Wang3e2dbd12018-03-14 17:28:17 -07002023 return nss_core_send_cmd(nss_ctx, nnm, sizeof(*nnm), NSS_NBUF_PAYLOAD_SIZE);
Vijay Dewangan488e5372014-12-29 21:40:11 -08002024}
2025
Vijay Dewangan488e5372014-12-29 21:40:11 -08002026/*
2027 * nss_n2h_notify_register()
2028 * Register to received N2H events.
2029 *
2030 * NOTE: Do we want to pass an nss_ctx here so that we can register for n2h on any core?
2031 */
2032struct nss_ctx_instance *nss_n2h_notify_register(int core, nss_n2h_msg_callback_t cb, void *app_data)
2033{
Suman Ghosh9f7b3702018-09-21 19:51:40 +05302034 if (core >= nss_top_main.num_nss) {
Vijay Dewangan488e5372014-12-29 21:40:11 -08002035 nss_warning("Input core number %d is wrong \n", core);
2036 return NULL;
2037 }
2038 /*
2039 * TODO: We need to have a new array in support of the new API
2040 * TODO: If we use a per-context array, we would move the array into nss_ctx based.
2041 */
2042 nss_n2h_rd[core].n2h_callback = cb;
2043 nss_n2h_rd[core].app_data = app_data;
2044 return &nss_top_main.nss[core];
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05302045}
2046
2047/*
2048 * nss_n2h_register_handler()
2049 */
Thomas Wu91f4bdf2017-06-09 12:03:02 -07002050void nss_n2h_register_handler(struct nss_ctx_instance *nss_ctx)
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05302051{
ratheesh kannothab436af2017-07-20 08:51:07 +05302052 sema_init(&nss_n2h_q_cfg_pvt.sem, 1);
2053 init_completion(&nss_n2h_q_cfg_pvt.complete);
2054
Thomas Wu91f4bdf2017-06-09 12:03:02 -07002055 nss_core_register_handler(nss_ctx, NSS_N2H_INTERFACE, nss_n2h_interface_handler, NULL);
Yu Huang8c107082017-07-24 14:58:26 -07002056
Cemil Coskun26be6162019-06-28 15:44:48 -07002057 if (nss_ctx->id == NSS_CORE_0) {
2058 nss_n2h_stats_dentry_create();
2059 }
Stephen Wang49b474b2016-03-25 10:40:30 -07002060}
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -07002061
Stephen Wang49b474b2016-03-25 10:40:30 -07002062/*
Suman Ghosh9f7b3702018-09-21 19:51:40 +05302063 * nss_n2h_single_core_register_sysctl()
Stephen Wang49b474b2016-03-25 10:40:30 -07002064 */
Suman Ghosh9f7b3702018-09-21 19:51:40 +05302065void nss_n2h_single_core_register_sysctl(void)
2066{
2067 /*
2068 * RPS sema init
2069 */
2070 sema_init(&nss_n2h_rcp.sem, 1);
2071 init_completion(&nss_n2h_rcp.complete);
2072
2073 /*
2074 * MITIGATION sema init for core0
2075 */
2076 sema_init(&nss_n2h_mitigationcp[NSS_CORE_0].sem, 1);
2077 init_completion(&nss_n2h_mitigationcp[NSS_CORE_0].complete);
2078
2079 /*
2080 * PBUF addition sema init for core0
2081 */
2082 sema_init(&nss_n2h_bufcp[NSS_CORE_0].sem, 1);
2083 init_completion(&nss_n2h_bufcp[NSS_CORE_0].complete);
2084
2085 /*
2086 * Core0
2087 */
2088 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_0].sem, 1);
2089 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_0].complete);
2090 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.pool_size =
2091 nss_n2h_empty_pool_buf_cfg[NSS_CORE_0];
2092 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.low_water =
2093 nss_n2h_water_mark[NSS_CORE_0][0];
2094 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.high_water =
2095 nss_n2h_water_mark[NSS_CORE_0][1];
2096 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.pool_size =
2097 nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0];
2098 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.low_water =
2099 nss_n2h_paged_water_mark[NSS_CORE_0][0];
2100 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.high_water =
2101 nss_n2h_paged_water_mark[NSS_CORE_0][1];
2102
2103 /*
2104 * WiFi pool buf cfg sema init
2105 */
2106 sema_init(&nss_n2h_wp.sem, 1);
2107 init_completion(&nss_n2h_wp.complete);
2108
2109 /*
2110 * N2H queue config sema init
2111 */
2112 sema_init(&nss_n2h_q_lim_pvt.sem, 1);
2113 init_completion(&nss_n2h_q_lim_pvt.complete);
2114
Sakthi Vignesh Radhakrishnanf9823102019-03-05 15:38:36 -08002115 /*
2116 * Back pressure config sema init
2117 */
2118 sema_init(&nss_n2h_host_bp_cfg_pvt.sem, 1);
2119 init_completion(&nss_n2h_host_bp_cfg_pvt.complete);
2120
Suman Ghosh9f7b3702018-09-21 19:51:40 +05302121 nss_n2h_notify_register(NSS_CORE_0, NULL, NULL);
2122
2123 /*
2124 * Register sysctl table.
2125 */
2126 nss_n2h_dir[0].child = nss_n2h_table_single_core;
2127 nss_n2h_header = register_sysctl_table(nss_n2h_root);
2128}
2129
2130/*
2131 * nss_n2h_multi_core_register_sysctl()
2132 */
2133void nss_n2h_multi_core_register_sysctl(void)
Stephen Wang49b474b2016-03-25 10:40:30 -07002134{
Vijay Dewangan634ce592015-01-07 17:21:09 -08002135 /*
2136 * RPS sema init
2137 */
2138 sema_init(&nss_n2h_rcp.sem, 1);
2139 init_completion(&nss_n2h_rcp.complete);
2140
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05302141 /*
2142 * MITIGATION sema init for core0
2143 */
2144 sema_init(&nss_n2h_mitigationcp[NSS_CORE_0].sem, 1);
2145 init_completion(&nss_n2h_mitigationcp[NSS_CORE_0].complete);
2146
2147 /*
2148 * MITIGATION sema init for core1
2149 */
2150 sema_init(&nss_n2h_mitigationcp[NSS_CORE_1].sem, 1);
2151 init_completion(&nss_n2h_mitigationcp[NSS_CORE_1].complete);
2152
2153 /*
2154 * PBUF addition sema init for core0
2155 */
2156 sema_init(&nss_n2h_bufcp[NSS_CORE_0].sem, 1);
2157 init_completion(&nss_n2h_bufcp[NSS_CORE_0].complete);
2158
2159 /*
2160 * PBUF addition sema init for core1
2161 */
2162 sema_init(&nss_n2h_bufcp[NSS_CORE_1].sem, 1);
2163 init_completion(&nss_n2h_bufcp[NSS_CORE_1].complete);
Vijay Dewangan634ce592015-01-07 17:21:09 -08002164
Stephen Wang49b474b2016-03-25 10:40:30 -07002165 /*
2166 * Core0
2167 */
2168 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_0].sem, 1);
2169 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_0].complete);
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002170 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.pool_size =
Stephen Wang49b474b2016-03-25 10:40:30 -07002171 nss_n2h_empty_pool_buf_cfg[NSS_CORE_0];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002172 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.low_water =
Stephen Wang49b474b2016-03-25 10:40:30 -07002173 nss_n2h_water_mark[NSS_CORE_0][0];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002174 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.high_water =
Stephen Wang49b474b2016-03-25 10:40:30 -07002175 nss_n2h_water_mark[NSS_CORE_0][1];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002176 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.pool_size =
2177 nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0];
2178 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.low_water =
2179 nss_n2h_paged_water_mark[NSS_CORE_0][0];
2180 nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.high_water =
2181 nss_n2h_paged_water_mark[NSS_CORE_0][1];
2182
Stephen Wang49b474b2016-03-25 10:40:30 -07002183 /*
2184 * Core1
2185 */
2186 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_1].sem, 1);
2187 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_1].complete);
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002188 nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool_info.pool_size =
Stephen Wang49b474b2016-03-25 10:40:30 -07002189 nss_n2h_empty_pool_buf_cfg[NSS_CORE_1];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002190 nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool_info.low_water =
Stephen Wang49b474b2016-03-25 10:40:30 -07002191 nss_n2h_water_mark[NSS_CORE_1][0];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002192 nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool_info.high_water =
Stephen Wang49b474b2016-03-25 10:40:30 -07002193 nss_n2h_water_mark[NSS_CORE_1][1];
Sachin Shashidhar475012b2017-03-13 16:56:07 -07002194 nss_n2h_nepbcfgp[NSS_CORE_1].empty_paged_buf_pool_info.pool_size =
2195 nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_1];
2196 nss_n2h_nepbcfgp[NSS_CORE_1].empty_paged_buf_pool_info.low_water =
2197 nss_n2h_paged_water_mark[NSS_CORE_1][0];
2198 nss_n2h_nepbcfgp[NSS_CORE_1].empty_paged_buf_pool_info.high_water =
2199 nss_n2h_paged_water_mark[NSS_CORE_1][1];
2200
Stephen Wang49b474b2016-03-25 10:40:30 -07002201 /*
2202 * WiFi pool buf cfg sema init
2203 */
2204 sema_init(&nss_n2h_wp.sem, 1);
2205 init_completion(&nss_n2h_wp.complete);
2206
Shashank Balashankar4162f572018-08-21 13:32:34 -07002207 /*
2208 * N2H queue config sema init
2209 */
2210 sema_init(&nss_n2h_q_lim_pvt.sem, 1);
2211 init_completion(&nss_n2h_q_lim_pvt.complete);
2212
Sakthi Vignesh Radhakrishnanf9823102019-03-05 15:38:36 -08002213 /*
2214 * Back pressure config sema init
2215 */
2216 sema_init(&nss_n2h_host_bp_cfg_pvt.sem, 1);
2217 init_completion(&nss_n2h_host_bp_cfg_pvt.complete);
2218
Vijay Dewangan488e5372014-12-29 21:40:11 -08002219 nss_n2h_notify_register(NSS_CORE_0, NULL, NULL);
2220 nss_n2h_notify_register(NSS_CORE_1, NULL, NULL);
2221
Stephen Wang49b474b2016-03-25 10:40:30 -07002222 /*
2223 * Register sysctl table.
2224 */
2225 nss_n2h_header = register_sysctl_table(nss_n2h_root);
2226}
2227
2228/*
2229 * nss_n2h_unregister_sysctl()
2230 * Unregister sysctl specific to n2h
2231 */
2232void nss_n2h_unregister_sysctl(void)
2233{
2234 /*
2235 * Unregister sysctl table.
2236 */
2237 if (nss_n2h_header) {
2238 unregister_sysctl_table(nss_n2h_header);
2239 }
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05302240}
Vijay Dewangan488e5372014-12-29 21:40:11 -08002241
2242EXPORT_SYMBOL(nss_n2h_notify_register);