blob: 54df82b464eed02a80f464824b0db1d242dd56b8 [file] [log] [blame]
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301/*
2 **************************************************************************
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +05303 * Copyright (c) 2013-2016, 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"
23
Stephen Wang49b474b2016-03-25 10:40:30 -070024#define NSS_N2H_MAX_BUF_POOL_SIZE (1024 * 1024 * 8) /* 8MB */
Saurabh Misra71034db2015-06-04 16:18:38 -070025#define NSS_N2H_MIN_EMPTY_POOL_BUF_SZ 32
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +053026#define NSS_N2H_MAX_EMPTY_POOL_BUF_SZ 65536
Vijay Dewangan488e5372014-12-29 21:40:11 -080027#define NSS_N2H_DEFAULT_EMPTY_POOL_BUF_SZ 8192
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053028
Saurabh Misra71034db2015-06-04 16:18:38 -070029int nss_n2h_empty_pool_buf_cfg[NSS_MAX_CORES] __read_mostly = {-1, -1};
30int nss_n2h_water_mark[NSS_MAX_CORES][2] __read_mostly = {{-1, -1}, {-1, -1} };
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +053031int nss_n2h_wifi_pool_buf_cfg __read_mostly = -1;
Stephen Wang49b474b2016-03-25 10:40:30 -070032int nss_n2h_rps_config __read_mostly;
33int nss_n2h_core0_mitigation_cfg __read_mostly = 1;
34int nss_n2h_core1_mitigation_cfg __read_mostly = 1;
35int nss_n2h_core0_add_buf_pool_size __read_mostly;
36int nss_n2h_core1_add_buf_pool_size __read_mostly;
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053037
Vijay Dewangan488e5372014-12-29 21:40:11 -080038struct nss_n2h_registered_data {
39 nss_n2h_msg_callback_t n2h_callback;
40 void *app_data;
41};
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053042
Vijay Dewangan488e5372014-12-29 21:40:11 -080043static struct nss_n2h_cfg_pvt nss_n2h_nepbcfgp[NSS_MAX_CORES];
44static struct nss_n2h_registered_data nss_n2h_rd[NSS_MAX_CORES];
Vijay Dewangan634ce592015-01-07 17:21:09 -080045static struct nss_n2h_cfg_pvt nss_n2h_rcp;
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +053046static struct nss_n2h_cfg_pvt nss_n2h_mitigationcp[NSS_CORE_MAX];
47static struct nss_n2h_cfg_pvt nss_n2h_bufcp[NSS_CORE_MAX];
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +053048static struct nss_n2h_cfg_pvt nss_n2h_wp;
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053049
50/*
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -070051 * nss_n2h_stats_sync()
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053052 * Handle the syncing of NSS statistics.
53 */
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -070054static void nss_n2h_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_n2h_stats_sync *nnss)
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053055{
56 struct nss_top_instance *nss_top = nss_ctx->nss_top;
57
58 spin_lock_bh(&nss_top->stats_lock);
59
60 /*
61 * common node stats
62 */
63 nss_ctx->stats_n2h[NSS_STATS_NODE_RX_PKTS] += nnss->node_stats.rx_packets;
64 nss_ctx->stats_n2h[NSS_STATS_NODE_RX_BYTES] += nnss->node_stats.rx_bytes;
65 nss_ctx->stats_n2h[NSS_STATS_NODE_RX_DROPPED] += nnss->node_stats.rx_dropped;
66 nss_ctx->stats_n2h[NSS_STATS_NODE_TX_PKTS] += nnss->node_stats.tx_packets;
67 nss_ctx->stats_n2h[NSS_STATS_NODE_TX_BYTES] += nnss->node_stats.tx_bytes;
68
69 /*
70 * General N2H stats
71 */
Murat Sezgin0c0561d2014-04-09 18:55:58 -070072 nss_ctx->stats_n2h[NSS_STATS_N2H_QUEUE_DROPPED] += nnss->queue_dropped;
73 nss_ctx->stats_n2h[NSS_STATS_N2H_TOTAL_TICKS] += nnss->total_ticks;
74 nss_ctx->stats_n2h[NSS_STATS_N2H_WORST_CASE_TICKS] += nnss->worst_case_ticks;
75 nss_ctx->stats_n2h[NSS_STATS_N2H_ITERATIONS] += nnss->iterations;
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053076
77 /*
Thomas Wu3fd8dd72014-06-11 15:57:05 -070078 * pbuf manager ocm and default pool stats
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053079 */
Thomas Wu3fd8dd72014-06-11 15:57:05 -070080 nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_OCM_ALLOC_FAILS] += nnss->pbuf_ocm_stats.pbuf_alloc_fails;
81 nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_OCM_FREE_COUNT] = nnss->pbuf_ocm_stats.pbuf_free_count;
82 nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_OCM_TOTAL_COUNT] = nnss->pbuf_ocm_stats.pbuf_total_count;
83
84 nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_DEFAULT_ALLOC_FAILS] += nnss->pbuf_default_stats.pbuf_alloc_fails;
85 nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_DEFAULT_FREE_COUNT] = nnss->pbuf_default_stats.pbuf_free_count;
86 nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_DEFAULT_TOTAL_COUNT] = nnss->pbuf_default_stats.pbuf_total_count;
87
88 /*
89 * payload mgr stats
90 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053091 nss_ctx->stats_n2h[NSS_STATS_N2H_PAYLOAD_ALLOC_FAILS] += nnss->payload_alloc_fails;
Thomas Wu53679842015-01-22 13:37:35 -080092 nss_ctx->stats_n2h[NSS_STATS_N2H_PAYLOAD_FREE_COUNT] = nnss->payload_free_count;
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053093
Sakthi Vignesh Radhakrishnan2a8ee962014-11-22 13:35:38 -080094 /*
95 * Host <=> NSS control traffic stats
96 */
97 nss_ctx->stats_n2h[NSS_STATS_N2H_H2N_CONTROL_PACKETS] += nnss->h2n_ctrl_pkts;
98 nss_ctx->stats_n2h[NSS_STATS_N2H_H2N_CONTROL_BYTES] += nnss->h2n_ctrl_bytes;
99 nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_CONTROL_PACKETS] += nnss->n2h_ctrl_pkts;
100 nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_CONTROL_BYTES] += nnss->n2h_ctrl_bytes;
101
102 /*
103 * Host <=> NSS control data traffic stats
104 */
105 nss_ctx->stats_n2h[NSS_STATS_N2H_H2N_DATA_PACKETS] += nnss->h2n_data_pkts;
106 nss_ctx->stats_n2h[NSS_STATS_N2H_H2N_DATA_BYTES] += nnss->h2n_data_bytes;
107 nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_DATA_PACKETS] += nnss->n2h_data_pkts;
108 nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_DATA_BYTES] += nnss->n2h_data_bytes;
109
Saurabh Misra71034db2015-06-04 16:18:38 -0700110 /*
111 * Payloads related stats
112 */
113 nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_TOT_PAYLOADS] = nnss->tot_payloads;
114
Guojun Jin85dfa7b2015-09-02 15:13:56 -0700115 nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_INTERFACE_INVALID] += nnss->data_interface_invalid;
116
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530117 spin_unlock_bh(&nss_top->stats_lock);
118}
119
120/*
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -0700121 * nss_n2h_interface_handler()
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530122 * Handle NSS -> HLOS messages for N2H node
123 */
Vijay Dewangan634ce592015-01-07 17:21:09 -0800124static void nss_n2h_interface_handler(struct nss_ctx_instance *nss_ctx,
125 struct nss_cmn_msg *ncm,
Arunkumar Tba9b4a02016-11-07 11:41:14 +0530126 void *app_data)
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530127{
128 struct nss_n2h_msg *nnm = (struct nss_n2h_msg *)ncm;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800129 nss_n2h_msg_callback_t cb;
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530130
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -0700131 BUG_ON(ncm->interface != NSS_N2H_INTERFACE);
132
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530133 /*
134 * Is this a valid request/response packet?
135 */
136 if (nnm->cm.type >= NSS_METADATA_TYPE_N2H_MAX) {
137 nss_warning("%p: received invalid message %d for Offload stats interface", nss_ctx, nnm->cm.type);
138 return;
139 }
140
141 switch (nnm->cm.type) {
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530142 case NSS_TX_METADATA_TYPE_N2H_RPS_CFG:
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530143 nss_info("NSS N2H rps_en %d \n",nnm->msg.rps_cfg.enable);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800144 break;
145
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530146 case NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG:
147 nss_info("NSS N2H mitigation_dis %d \n",nnm->msg.mitigation_cfg.enable);
148 break;
149
Vijay Dewangan488e5372014-12-29 21:40:11 -0800150 case NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG:
151 nss_info("%p: empty pool buf cfg response from FW", nss_ctx);
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530152 break;
153
Radha krishna Simha Jiguru7f424d52015-02-10 19:41:01 +0530154 case NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS:
155 nss_info("%p: flush payloads cmd response from FW", nss_ctx);
156 break;
157
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530158 case NSS_RX_METADATA_TYPE_N2H_STATS_SYNC:
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -0700159 nss_n2h_stats_sync(nss_ctx, &nnm->msg.stats_sync);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530160 break;
161
162 default:
163 if (ncm->response != NSS_CMN_RESPONSE_ACK) {
164 /*
165 * Check response
166 */
167 nss_info("%p: Received response %d for type %d, interface %d",
168 nss_ctx, ncm->response, ncm->type, ncm->interface);
169 }
170 }
Vijay Dewangan488e5372014-12-29 21:40:11 -0800171
172 /*
Stephen Wang49b474b2016-03-25 10:40:30 -0700173 * Update the callback and app_data for NOTIFY messages, n2h sends all notify messages
Vijay Dewangan488e5372014-12-29 21:40:11 -0800174 * to the same callback/app_data.
175 */
176 if (nnm->cm.response == NSS_CMM_RESPONSE_NOTIFY) {
177 /*
178 * Place holder for the user to create right call
179 * back and app data when response is NSS_CMM_RESPONSE_NOTIFY
180 */
181 ncm->cb = (uint32_t)nss_n2h_rd[nss_ctx->id].n2h_callback;
182 ncm->app_data = (uint32_t)nss_n2h_rd[nss_ctx->id].app_data;
183 }
184
185 /*
186 * Do we have a callback?
187 */
188 if (!ncm->cb) {
189 return;
190 }
191
192 /*
193 * Callback
194 */
195 cb = (nss_n2h_msg_callback_t)ncm->cb;
196 cb((void *)ncm->app_data, nnm);
197}
198
199/*
Vijay Dewangan634ce592015-01-07 17:21:09 -0800200 * nss_n2h_rps_cfg_callback()
201 * call back function for rps configuration
202 */
203static void nss_n2h_rps_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
204{
205 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)app_data;
206 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
207
208 /*
209 * Error, hence we are not updating the nss_n2h_empty_pool_buf
210 * Restore the current_value to its previous state
211 */
212 nss_n2h_rcp.response = NSS_FAILURE;
213 complete(&nss_n2h_rcp.complete);
214 nss_warning("%p: RPS configuration failed : %d\n", nss_ctx,
215 nnm->cm.error);
216 return;
217 }
218
219 nss_info("%p: RPS configuration succeeded: %d\n", nss_ctx,
220 nnm->cm.error);
221 nss_ctx->n2h_rps_en = nnm->msg.rps_cfg.enable;
222 nss_n2h_rcp.response = NSS_SUCCESS;
223 complete(&nss_n2h_rcp.complete);
224}
225
226/*
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530227 * nss_n2h_mitigation_cfg_callback()
228 * call back function for mitigation configuration
229 */
230static void nss_n2h_mitigation_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
231{
232 int core_num = (int)app_data;
233 struct nss_top_instance *nss_top = &nss_top_main;
234 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
235
236 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
237
238 /*
239 * Error, hence we are not updating the nss_n2h_mitigate_en
240 */
241 nss_n2h_mitigationcp[core_num].response = NSS_FAILURE;
242 complete(&nss_n2h_mitigationcp[core_num].complete);
243 nss_warning("core%d: MITIGATION configuration failed : %d\n", core_num, nnm->cm.error);
244 return;
245 }
246
247 nss_info("core%d: MITIGATION configuration succeeded: %d\n", core_num, nnm->cm.error);
248
249 nss_ctx->n2h_mitigate_en = nnm->msg.mitigation_cfg.enable;
250 nss_n2h_mitigationcp[core_num].response = NSS_SUCCESS;
251 complete(&nss_n2h_mitigationcp[core_num].complete);
252}
253
254/*
255 * nss_n2h_buf_cfg_callback()
256 * call back function for pbuf configuration
257 */
258static void nss_n2h_bufs_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
259{
260 int core_num = (int)app_data;
261 unsigned int allocated_sz;
262
263 struct nss_top_instance *nss_top = &nss_top_main;
264 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
265
266 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
267 nss_n2h_bufcp[core_num].response = NSS_FAILURE;
268 nss_warning("core%d: buf configuration failed : %d\n", core_num, nnm->cm.error);
269 goto done;
270 }
271
272 nss_info("core%d: buf configuration succeeded: %d\n", core_num, nnm->cm.error);
273
274 allocated_sz = nnm->msg.buf_pool.nss_buf_page_size * nnm->msg.buf_pool.nss_buf_num_pages;
275 nss_ctx->buf_sz_allocated += allocated_sz;
276
277 nss_n2h_bufcp[core_num].response = NSS_SUCCESS;
278
279done:
280 complete(&nss_n2h_bufcp[core_num].complete);
281}
282
283/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700284 * nss_n2h_payload_stats_callback()
285 * It gets called response to payload accounting.
Vijay Dewangan488e5372014-12-29 21:40:11 -0800286 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700287static void nss_n2h_payload_stats_callback(void *app_data,
288 struct nss_n2h_msg *nnm)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800289{
290 int core_num = (int)app_data;
Saurabh Misra71034db2015-06-04 16:18:38 -0700291
Vijay Dewangan488e5372014-12-29 21:40:11 -0800292 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
293 struct nss_n2h_empty_pool_buf *nnepbcm;
294 nnepbcm = &nnm->msg.empty_pool_buf_cfg;
295
Saurabh Misra71034db2015-06-04 16:18:38 -0700296 nss_warning("%d: core empty pool buf set failure: %d\n",
297 core_num, nnm->cm.error);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800298 nss_n2h_nepbcfgp[core_num].response = NSS_FAILURE;
299 complete(&nss_n2h_nepbcfgp[core_num].complete);
300 return;
301 }
302
Saurabh Misra71034db2015-06-04 16:18:38 -0700303 if (nnm->cm.type == NSS_TX_METADATA_TYPE_GET_PAYLOAD_INFO) {
304 nss_n2h_nepbcfgp[core_num].empty_buf_pool =
305 ntohl(nnm->msg.payload_info.pool_size);
306 nss_n2h_nepbcfgp[core_num].low_water =
307 ntohl(nnm->msg.payload_info.low_water);
308 nss_n2h_nepbcfgp[core_num].high_water =
309 ntohl(nnm->msg.payload_info.high_water);
310 }
311
Vijay Dewangan488e5372014-12-29 21:40:11 -0800312 nss_n2h_nepbcfgp[core_num].response = NSS_SUCCESS;
313 complete(&nss_n2h_nepbcfgp[core_num].complete);
314}
315
316/*
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530317 * nss_n2h_set_wifi_payloads_callback()
318 * call back function for response to wifi pool configuration
319 *
320 */
321static void nss_n2h_set_wifi_payloads_callback(void *app_data,
322 struct nss_n2h_msg *nnm)
323{
Arunkumar Tba9b4a02016-11-07 11:41:14 +0530324 struct nss_ctx_instance *nss_ctx __maybe_unused = (struct nss_ctx_instance *)app_data;
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530325 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
326
327 nss_n2h_wp.response = NSS_FAILURE;
328 complete(&nss_n2h_wp.complete);
329 nss_warning("%p: wifi pool configuration failed : %d\n", nss_ctx,
330 nnm->cm.error);
331 return;
332 }
333
334 nss_info("%p: wifi payload configuration succeeded: %d\n", nss_ctx,
335 nnm->cm.error);
336 nss_n2h_wp.response = NSS_SUCCESS;
337 complete(&nss_n2h_wp.complete);
338}
339
340/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700341 * nss_n2h_get_payload_info()
342 * Gets Payload information
Vijay Dewangan488e5372014-12-29 21:40:11 -0800343 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700344static int nss_n2h_get_payload_info(struct ctl_table *ctl, int write,
Saurabh Misra71034db2015-06-04 16:18:38 -0700345 void __user *buffer, size_t *lenp, loff_t *ppos,
346 int core_num)
347{
348 struct nss_top_instance *nss_top = &nss_top_main;
349 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
350 struct nss_n2h_msg nnm;
351 struct nss_n2h_payload_info *nnepbcm;
352 nss_tx_status_t nss_tx_status;
353 int ret = NSS_FAILURE;
354
355 /*
356 * Note that semaphore should be already held.
357 */
358
359 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
360 NSS_TX_METADATA_TYPE_GET_PAYLOAD_INFO,
361 sizeof(struct nss_n2h_payload_info),
362 nss_n2h_payload_stats_callback,
363 (void *)core_num);
364
365 nnepbcm = &nnm.msg.payload_info;
366 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
367
368 if (nss_tx_status != NSS_TX_SUCCESS) {
369 nss_warning("%p: core %d nss_tx error errorn",
370 nss_ctx, core_num);
371 return NSS_FAILURE;
372 }
373
374 /*
375 * Blocking call, wait till we get ACK for this msg.
376 */
377 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
378 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
379 if (ret == 0) {
380 nss_warning("%p: core %d waiting for ack timed out\n", nss_ctx,
381 core_num);
382 return NSS_FAILURE;
383 }
384
385 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
386 nss_warning("%p: core %d response returned failure\n", nss_ctx,
387 core_num);
388 return NSS_FAILURE;
389 }
390
391 return NSS_SUCCESS;
392}
393
394/*
395 * nss_n2h_set_empty_pool_buf()
396 * Sets empty pool buffer
397 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700398static int nss_n2h_set_empty_pool_buf(struct ctl_table *ctl, int write,
Saurabh Misra71034db2015-06-04 16:18:38 -0700399 void __user *buffer,
400 size_t *lenp, loff_t *ppos,
401 int core_num, int *new_val)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800402{
403 struct nss_top_instance *nss_top = &nss_top_main;
404 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
405 struct nss_n2h_msg nnm;
406 struct nss_n2h_empty_pool_buf *nnepbcm;
407 nss_tx_status_t nss_tx_status;
408 int ret = NSS_FAILURE;
409
410 /*
411 * Acquiring semaphore
412 */
413 down(&nss_n2h_nepbcfgp[core_num].sem);
414
415 /*
416 * Take snap shot of current value
417 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700418 nss_n2h_nepbcfgp[core_num].empty_buf_pool = *new_val;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800419
Saurabh Misra71034db2015-06-04 16:18:38 -0700420 if (!write) {
421 ret = nss_n2h_get_payload_info(ctl, write, buffer, lenp, ppos,
422 core_num);
423 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool;
424 if (ret == NSS_FAILURE) {
425 up(&nss_n2h_nepbcfgp[core_num].sem);
426 return -EBUSY;
427 }
428
429 up(&nss_n2h_nepbcfgp[core_num].sem);
430
431 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
432 return ret;
433 }
434
Vijay Dewangan488e5372014-12-29 21:40:11 -0800435 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
Saurabh Misra71034db2015-06-04 16:18:38 -0700436 if (ret) {
Vijay Dewangan488e5372014-12-29 21:40:11 -0800437 up(&nss_n2h_nepbcfgp[core_num].sem);
438 return ret;
439 }
440
Vijay Dewangan488e5372014-12-29 21:40:11 -0800441 if ((*new_val < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700442 nss_warning("%p: core %d setting %d < min number of buffer",
Vijay Dewangan488e5372014-12-29 21:40:11 -0800443 nss_ctx, core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800444 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800445 }
446
447 nss_info("%p: core %d number of empty pool buffer is : %d\n",
448 nss_ctx, core_num, *new_val);
449
450 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
451 NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG,
452 sizeof(struct nss_n2h_empty_pool_buf),
Saurabh Misra71034db2015-06-04 16:18:38 -0700453 nss_n2h_payload_stats_callback,
Vijay Dewangan488e5372014-12-29 21:40:11 -0800454 (void *)core_num);
455
456 nnepbcm = &nnm.msg.empty_pool_buf_cfg;
457 nnepbcm->pool_size = htonl(*new_val);
458 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
459
460 if (nss_tx_status != NSS_TX_SUCCESS) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700461 nss_warning("%p: core %d nss_tx error empty pool buffer: %d\n",
Vijay Dewangan488e5372014-12-29 21:40:11 -0800462 nss_ctx, core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800463 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800464 }
465
466 /*
467 * Blocking call, wait till we get ACK for this msg.
468 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700469 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
470 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
Vijay Dewangan488e5372014-12-29 21:40:11 -0800471 if (ret == 0) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700472 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
473 core_num);
Stephen Wang06761022015-03-03 16:38:42 -0800474 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800475 }
476
477 /*
478 * ACK/NACK received from NSS FW
479 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
480 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
481 */
482 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
Stephen Wang06761022015-03-03 16:38:42 -0800483 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800484 }
485
486 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700487 return 0;
Stephen Wang06761022015-03-03 16:38:42 -0800488
489failure:
490 /*
491 * Restore the current_value to its previous state
492 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700493 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool;
494 up(&nss_n2h_nepbcfgp[core_num].sem);
495 return NSS_FAILURE;
496}
497
498/*
499 * nss_n2h_set_water_mark()
500 * Sets water mark for N2H SOS
501 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700502static int nss_n2h_set_water_mark(struct ctl_table *ctl, int write,
Saurabh Misra71034db2015-06-04 16:18:38 -0700503 void __user *buffer,
504 size_t *lenp, loff_t *ppos,
505 int core_num, int *low, int *high)
506{
507 struct nss_top_instance *nss_top = &nss_top_main;
508 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
509 struct nss_n2h_msg nnm;
510 struct nss_n2h_water_mark *wm;
511 nss_tx_status_t nss_tx_status;
512 int ret = NSS_FAILURE;
513
514 /*
515 * Acquiring semaphore
516 */
517 down(&nss_n2h_nepbcfgp[core_num].sem);
518
519 /*
520 * Take snap shot of current value
521 */
522 nss_n2h_nepbcfgp[core_num].low_water = *low;
523 nss_n2h_nepbcfgp[core_num].high_water = *high;
524
525 if (!write) {
526 ret = nss_n2h_get_payload_info(ctl, write, buffer, lenp, ppos,
527 core_num);
528 *low = nss_n2h_nepbcfgp[core_num].low_water;
529 *high = nss_n2h_nepbcfgp[core_num].high_water;
530
531 if (ret == NSS_FAILURE) {
532 up(&nss_n2h_nepbcfgp[core_num].sem);
533 return -EBUSY;
534 }
535
536 up(&nss_n2h_nepbcfgp[core_num].sem);
537 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
538 return ret;
539 }
540
541 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
542 if (ret) {
543 up(&nss_n2h_nepbcfgp[core_num].sem);
544 return ret;
545 }
546
547 /*
548 * If either low or high water mark is not set then we do
549 * nothing.
550 */
551 if (*low == -1 || *high == -1)
552 goto failure;
553
554 if ((*low < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) ||
555 (*high < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
556 nss_warning("%p: core %d setting %d, %d < min number of buffer",
557 nss_ctx, core_num, *low, *high);
558 goto failure;
559 }
560
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530561 if ((*low > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ) ||
562 (*high > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700563 nss_warning("%p: core %d setting %d, %d is > upper limit",
564 nss_ctx, core_num, *low, *high);
565 goto failure;
566 }
567
568 if (*low > *high) {
569 nss_warning("%p: core %d setting low %d is more than high %d",
570 nss_ctx, core_num, *low, *high);
571 goto failure;
572 }
573
574 nss_info("%p: core %d number of low : %d and high : %d\n",
575 nss_ctx, core_num, *low, *high);
576
577 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
578 NSS_TX_METADATA_TYPE_SET_WATER_MARK,
579 sizeof(struct nss_n2h_water_mark),
580 nss_n2h_payload_stats_callback,
581 (void *)core_num);
582
583 wm = &nnm.msg.wm;
584 wm->low_water = htonl(*low);
585 wm->high_water = htonl(*high);
586 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
587
588 if (nss_tx_status != NSS_TX_SUCCESS) {
589 nss_warning("%p: core %d nss_tx error setting : %d, %d\n",
590 nss_ctx, core_num, *low, *high);
591 goto failure;
592 }
593
594 /*
595 * Blocking call, wait till we get ACK for this msg.
596 */
597 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
598 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
599 if (ret == 0) {
600 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
601 core_num);
602 goto failure;
603 }
604
605 /*
606 * ACK/NACK received from NSS FW
607 */
608 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response)
609 goto failure;
610
611 up(&nss_n2h_nepbcfgp[core_num].sem);
612 return NSS_SUCCESS;
613
614failure:
615 /*
616 * Restore the current_value to its previous state
617 */
618 *low = nss_n2h_nepbcfgp[core_num].low_water;
619 *high = nss_n2h_nepbcfgp[core_num].high_water;
Stephen Wang06761022015-03-03 16:38:42 -0800620 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700621 return -EINVAL;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800622}
623
624/*
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530625 * nss_n2h_cfg_wifi_pool()
626 * Sets number of wifi payloads to adjust high water mark for N2H SoS
627 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700628static int nss_n2h_cfg_wifi_pool(struct ctl_table *ctl, int write,
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530629 void __user *buffer,
630 size_t *lenp, loff_t *ppos,
631 int *payloads)
632{
633 struct nss_top_instance *nss_top = &nss_top_main;
634 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
635 struct nss_n2h_msg nnm;
636 struct nss_n2h_wifi_payloads *wp;
637 nss_tx_status_t nss_tx_status;
638 int ret = NSS_FAILURE;
639
640 /*
641 * Acquiring semaphore
642 */
643 down(&nss_n2h_wp.sem);
644
645 if (!write) {
646 *payloads = nss_n2h_wp.wifi_pool;
647
648 up(&nss_n2h_wp.sem);
649 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
650 return ret;
651 }
652
653 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
654 if (ret) {
655 up(&nss_n2h_wp.sem);
656 return ret;
657 }
658
659 /*
660 * If payloads parameter is not set, we do
661 * nothing.
662 */
663 if (*payloads == -1)
664 goto failure;
665
666 if ((*payloads < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
667 nss_warning("%p: wifi setting %d < min number of buffer",
668 nss_ctx, *payloads);
669 goto failure;
670 }
671
672 if ((*payloads > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) {
673 nss_warning("%p: wifi setting %d > max number of buffer",
674 nss_ctx, *payloads);
675 goto failure;
676 }
677
678 nss_info("%p: wifi payloads : %d\n",
679 nss_ctx, *payloads);
680
681 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
682 NSS_TX_METADATA_TYPE_N2H_WIFI_POOL_BUF_CFG,
683 sizeof(struct nss_n2h_wifi_payloads),
684 nss_n2h_set_wifi_payloads_callback,
685 (void *)nss_ctx);
686
687 wp = &nnm.msg.wp;
688 wp->payloads = htonl(*payloads);
689 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
690
691 if (nss_tx_status != NSS_TX_SUCCESS) {
692 nss_warning("%p: wifi setting %d nss_tx error",
693 nss_ctx, *payloads);
694 goto failure;
695 }
696
697 /*
698 * Blocking call, wait till we get ACK for this msg.
699 */
700 ret = wait_for_completion_timeout(&nss_n2h_wp.complete,
701 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
702 if (ret == 0) {
703 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
704 goto failure;
705 }
706
707 /*
708 * ACK/NACK received from NSS FW
709 */
710 if (NSS_FAILURE == nss_n2h_wp.response)
711 goto failure;
712
713 up(&nss_n2h_wp.sem);
714 return NSS_SUCCESS;
715
716failure:
717 up(&nss_n2h_wp.sem);
718 return -EINVAL;
719}
720
721/*
Vijay Dewangan488e5372014-12-29 21:40:11 -0800722 * nss_n2h_empty_pool_buf_core1_handler()
723 * Sets the number of empty buffer for core 1
724 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700725static int nss_n2h_empty_pool_buf_cfg_core1_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700726 int write, void __user *buffer,
727 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800728{
729 return nss_n2h_set_empty_pool_buf(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700730 NSS_CORE_1, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800731}
732
733/*
734 * nss_n2h_empty_pool_buf_core0_handler()
735 * Sets the number of empty buffer for core 0
736 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700737static int nss_n2h_empty_pool_buf_cfg_core0_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700738 int write, void __user *buffer,
739 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800740{
741 return nss_n2h_set_empty_pool_buf(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700742 NSS_CORE_0, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0]);
743}
744
745/*
746 * nss_n2h_water_mark_core1_handler()
747 * Sets water mark for core 1
748 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700749static int nss_n2h_water_mark_core1_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700750 int write, void __user *buffer,
751 size_t *lenp, loff_t *ppos)
752{
753 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
754 NSS_CORE_1, &nss_n2h_water_mark[NSS_CORE_1][0],
755 &nss_n2h_water_mark[NSS_CORE_1][1]);
756}
757
758/*
759 * nss_n2h_water_mark_core0_handler()
760 * Sets water mark for core 0
761 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700762static int nss_n2h_water_mark_core0_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700763 int write, void __user *buffer,
764 size_t *lenp, loff_t *ppos)
765{
766 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
767 NSS_CORE_0, &nss_n2h_water_mark[NSS_CORE_0][0],
768 &nss_n2h_water_mark[NSS_CORE_0][1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800769}
770
Vijay Dewangan634ce592015-01-07 17:21:09 -0800771/*
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530772 * nss_n2h_wifi_payloads_handler()
773 * Sets number of wifi payloads
774 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700775static int nss_n2h_wifi_payloads_handler(struct ctl_table *ctl,
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530776 int write, void __user *buffer,
777 size_t *lenp, loff_t *ppos)
778{
779 return nss_n2h_cfg_wifi_pool(ctl, write, buffer, lenp, ppos,
780 &nss_n2h_wifi_pool_buf_cfg);
781}
782
783/*
Vijay Dewangan634ce592015-01-07 17:21:09 -0800784 * nss_n2h_rps_cfg()
785 * Send Message to NSS to enable RPS.
786 */
Stephen Wang49b474b2016-03-25 10:40:30 -0700787static nss_tx_status_t nss_n2h_rps_cfg(struct nss_ctx_instance *nss_ctx, int enable_rps)
Vijay Dewangan634ce592015-01-07 17:21:09 -0800788{
789 struct nss_n2h_msg nnm;
790 struct nss_n2h_rps *rps_cfg;
791 nss_tx_status_t nss_tx_status;
792 int ret;
793
794 down(&nss_n2h_rcp.sem);
795 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_RPS_CFG,
796 sizeof(struct nss_n2h_rps),
797 nss_n2h_rps_cfg_callback,
798 (void *)nss_ctx);
799
800 rps_cfg = &nnm.msg.rps_cfg;
801 rps_cfg->enable = enable_rps;
802
803 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
804
805 if (nss_tx_status != NSS_TX_SUCCESS) {
806 nss_warning("%p: nss_tx error setting rps\n", nss_ctx);
807
808 up(&nss_n2h_rcp.sem);
809 return NSS_FAILURE;
810 }
811
812 /*
813 * Blocking call, wait till we get ACK for this msg.
814 */
815 ret = wait_for_completion_timeout(&nss_n2h_rcp.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
816 if (ret == 0) {
817 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
818 up(&nss_n2h_rcp.sem);
819 return NSS_FAILURE;
820 }
821
822 /*
823 * ACK/NACK received from NSS FW
824 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
825 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
826 */
827 if (NSS_FAILURE == nss_n2h_rcp.response) {
828 up(&nss_n2h_rcp.sem);
829 return NSS_FAILURE;
830 }
831
832 up(&nss_n2h_rcp.sem);
833 return NSS_SUCCESS;
834}
835
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530836/*
837 * nss_n2h_mitigation_cfg()
838 * Send Message to NSS to disable MITIGATION.
839 */
Stephen Wang49b474b2016-03-25 10:40:30 -0700840static 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 +0530841{
842 struct nss_n2h_msg nnm;
843 struct nss_n2h_mitigation *mitigation_cfg;
844 nss_tx_status_t nss_tx_status;
845 int ret;
846
847 nss_assert(core_num < NSS_CORE_MAX);
848
849 down(&nss_n2h_mitigationcp[core_num].sem);
850 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG,
851 sizeof(struct nss_n2h_mitigation),
852 nss_n2h_mitigation_cfg_callback,
853 (void *)core_num);
854
855 mitigation_cfg = &nnm.msg.mitigation_cfg;
856 mitigation_cfg->enable = enable_mitigation;
857
858 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
859
860 if (nss_tx_status != NSS_TX_SUCCESS) {
861 nss_warning("%p: nss_tx error setting mitigation\n", nss_ctx);
862 goto failure;
863 }
864
865 /*
866 * Blocking call, wait till we get ACK for this msg.
867 */
868 ret = wait_for_completion_timeout(&nss_n2h_mitigationcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
869 if (ret == 0) {
870 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
871 goto failure;
872 }
873
874 /*
875 * ACK/NACK received from NSS FW
876 */
877 if (NSS_FAILURE == nss_n2h_mitigationcp[core_num].response) {
878 goto failure;
879 }
880
881 up(&nss_n2h_mitigationcp[core_num].sem);
882 return NSS_SUCCESS;
883
884failure:
885 up(&nss_n2h_mitigationcp[core_num].sem);
886 return NSS_FAILURE;
887}
888
889static inline void nss_n2h_buf_pool_free(struct nss_n2h_buf_pool *buf_pool)
890{
891 int page_count;
892 for (page_count = 0; page_count < buf_pool->nss_buf_num_pages; page_count++) {
893 kfree(buf_pool->nss_buf_pool_vaddr[page_count]);
894 }
895}
896
897/*
898 * nss_n2h_buf_cfg()
899 * Send Message to NSS to enable pbufs.
900 */
Stephen Wang49b474b2016-03-25 10:40:30 -0700901static nss_tx_status_t nss_n2h_buf_pool_cfg(struct nss_ctx_instance *nss_ctx,
Tallapragada4b0161b2016-07-07 21:38:34 +0530902 int buf_pool_size, nss_core_id_t core_num)
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530903{
904 static struct nss_n2h_msg nnm;
905 struct nss_n2h_buf_pool *buf_pool;
906 nss_tx_status_t nss_tx_status;
907 int ret;
908 int page_count;
909 int num_pages = ALIGN(buf_pool_size, PAGE_SIZE)/PAGE_SIZE;
910
911 nss_assert(core_num < NSS_CORE_MAX);
912
913 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_METADATA_TYPE_N2H_ADD_BUF_POOL,
914 sizeof(struct nss_n2h_buf_pool),
915 nss_n2h_bufs_cfg_callback,
916 (void *)core_num);
917
918 do {
919
920 down(&nss_n2h_bufcp[core_num].sem);
921
922 buf_pool = &nnm.msg.buf_pool;
923 buf_pool->nss_buf_page_size = PAGE_SIZE;
924
925 for (page_count = 0; page_count < MAX_PAGES_PER_MSG && num_pages; page_count++, num_pages--) {
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530926 void *kern_addr = kzalloc(PAGE_SIZE, GFP_ATOMIC);
927 if (!kern_addr) {
928 BUG_ON(!page_count);
929 break;
930 }
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530931
932 buf_pool->nss_buf_pool_vaddr[page_count] = kern_addr;
933 buf_pool->nss_buf_pool_addr[page_count] = dma_map_single(NULL, kern_addr, PAGE_SIZE, DMA_TO_DEVICE);
934 }
935
936 buf_pool->nss_buf_num_pages = page_count;
937 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
938 if (nss_tx_status != NSS_TX_SUCCESS) {
939
940 nss_n2h_buf_pool_free(buf_pool);
941 nss_warning("%p: nss_tx error setting pbuf\n", nss_ctx);
942 goto failure;
943 }
944
945 /*
946 * Blocking call, wait till we get ACK for this msg.
947 */
948 ret = wait_for_completion_timeout(&nss_n2h_bufcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
949 if (ret == 0) {
950 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
951 goto failure;
952 }
953
954 /*
955 * ACK/NACK received from NSS FW
956 */
957 if (NSS_FAILURE == nss_n2h_bufcp[core_num].response) {
958
959 nss_n2h_buf_pool_free(buf_pool);
960 goto failure;
961 }
962
963 up(&nss_n2h_bufcp[core_num].sem);
964 } while(num_pages);
965
966 return NSS_SUCCESS;
967failure:
968 up(&nss_n2h_bufcp[core_num].sem);
969 return NSS_FAILURE;
970}
971
Stephen Wang49b474b2016-03-25 10:40:30 -0700972/*
973 * nss_rps_handler()
974 * Enable NSS RPS
975 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700976static int nss_n2h_rpscfg_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
Stephen Wang49b474b2016-03-25 10:40:30 -0700977{
978 struct nss_top_instance *nss_top = &nss_top_main;
979 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
980 int ret;
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530981
Stephen Wang49b474b2016-03-25 10:40:30 -0700982 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
983 if (!ret) {
984 if ((write) && (nss_n2h_rps_config == 1)) {
985 printk(KERN_INFO "Enabling NSS RPS\n");
986
987 return nss_n2h_rps_cfg(nss_ctx, 1);
988 }
989
990 if ((write) && (nss_n2h_rps_config == 0)) {
991 printk(KERN_INFO "Runtime disabling of NSS RPS not supported\n");
992 return ret;
993 }
994
995 if (write) {
996 printk(KERN_INFO "Invalid input value.Valid values are 0 and 1\n");
997 }
998
999 }
1000
1001 return ret;
1002}
1003
1004/*
1005 * nss_mitigation_handler()
1006 * Enable NSS MITIGATION
1007 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001008static 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 -07001009{
1010 struct nss_top_instance *nss_top = &nss_top_main;
1011 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_0];
1012 int ret;
1013
1014 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1015 if (ret) {
1016 return ret;
1017 }
1018
1019 /*
1020 * It's a read operation
1021 */
1022 if (!write) {
1023 return ret;
1024 }
1025
1026 if (!nss_n2h_core0_mitigation_cfg) {
1027 printk(KERN_INFO "Disabling NSS MITIGATION\n");
1028 nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_0);
1029 return 0;
1030 }
1031 printk(KERN_INFO "Invalid input value.Valid value is 0, Runtime re-enabling not supported\n");
1032 return -EINVAL;
1033}
1034
1035/*
1036 * nss_mitigation_handler()
1037 * Enable NSS MITIGATION
1038 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001039static 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 -07001040{
1041 struct nss_top_instance *nss_top = &nss_top_main;
1042 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_1];
1043 int ret;
1044
1045 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1046 if (ret) {
1047 return ret;
1048 }
1049
1050 /*
1051 * It's a read operation
1052 */
1053 if (!write) {
1054 return ret;
1055 }
1056
1057 if (!nss_n2h_core1_mitigation_cfg) {
1058 printk(KERN_INFO "Disabling NSS MITIGATION\n");
1059 nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_1);
1060 return 0;
1061 }
1062 printk(KERN_INFO "Invalid input value.Valid value is 0, Runtime re-enabling not supported\n");
1063 return -EINVAL;
1064}
1065
1066/*
1067 * nss_buf_handler()
1068 * Add extra NSS bufs from host memory
1069 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001070static 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 -07001071{
1072 struct nss_top_instance *nss_top = &nss_top_main;
1073 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_0];
1074 int ret;
1075
1076 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1077 if (ret) {
1078 return ret;
1079 }
1080
1081 /*
1082 * It's a read operation
1083 */
1084 if (!write) {
1085 return ret;
1086 }
1087
1088 if (nss_ctx->buf_sz_allocated) {
1089 nss_n2h_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1090 return -EPERM;
1091 }
1092
1093 if ((nss_n2h_core0_add_buf_pool_size >= 1) && (nss_n2h_core0_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) {
1094 printk(KERN_INFO "configuring additional NSS pbufs\n");
1095 ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_n2h_core0_add_buf_pool_size, NSS_CORE_0);
1096 nss_n2h_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1097 printk(KERN_INFO "additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated);
1098 return ret;
1099 }
1100
1101 printk(KERN_INFO "Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE);
1102 return -EINVAL;
1103}
1104
1105/*
1106 * nss_n2h_buf_handler()
1107 * Add extra NSS bufs from host memory
1108 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001109static 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 -07001110{
1111 struct nss_top_instance *nss_top = &nss_top_main;
1112 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_1];
1113 int ret;
1114
1115 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1116 if (ret) {
1117 return ret;
1118 }
1119
1120 /*
1121 * It's a read operation
1122 */
1123 if (!write) {
1124 return ret;
1125 }
1126
1127 if (nss_ctx->buf_sz_allocated) {
1128 nss_n2h_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1129 return -EPERM;
1130 }
1131
1132 if ((nss_n2h_core1_add_buf_pool_size >= 1) && (nss_n2h_core1_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) {
1133 printk(KERN_INFO "configuring additional NSS pbufs\n");
1134 ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_n2h_core1_add_buf_pool_size, NSS_CORE_1);
1135 nss_n2h_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1136 printk(KERN_INFO "additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated);
1137 return ret;
1138 }
1139
1140 printk(KERN_INFO "Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE);
1141 return -EINVAL;
1142}
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301143
Stephen Wang52e6d342016-03-29 15:02:33 -07001144static struct ctl_table nss_n2h_table[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001145 {
Saurabh Misra71034db2015-06-04 16:18:38 -07001146 .procname = "n2h_empty_pool_buf_core0",
1147 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0],
1148 .maxlen = sizeof(int),
1149 .mode = 0644,
1150 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core0_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -08001151 },
1152 {
Saurabh Misra71034db2015-06-04 16:18:38 -07001153 .procname = "n2h_empty_pool_buf_core1",
1154 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1],
1155 .maxlen = sizeof(int),
1156 .mode = 0644,
1157 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core1_handler,
1158 },
1159 {
1160 .procname = "n2h_low_water_core0",
1161 .data = &nss_n2h_water_mark[NSS_CORE_0][0],
1162 .maxlen = sizeof(int),
1163 .mode = 0644,
1164 .proc_handler = &nss_n2h_water_mark_core0_handler,
1165 },
1166 {
1167 .procname = "n2h_low_water_core1",
1168 .data = &nss_n2h_water_mark[NSS_CORE_1][0],
1169 .maxlen = sizeof(int),
1170 .mode = 0644,
1171 .proc_handler = &nss_n2h_water_mark_core1_handler,
1172 },
1173 {
1174 .procname = "n2h_high_water_core0",
1175 .data = &nss_n2h_water_mark[NSS_CORE_0][1],
1176 .maxlen = sizeof(int),
1177 .mode = 0644,
1178 .proc_handler = &nss_n2h_water_mark_core0_handler,
1179 },
1180 {
1181 .procname = "n2h_high_water_core1",
1182 .data = &nss_n2h_water_mark[NSS_CORE_1][1],
1183 .maxlen = sizeof(int),
1184 .mode = 0644,
1185 .proc_handler = &nss_n2h_water_mark_core1_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -08001186 },
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +05301187 {
1188 .procname = "n2h_wifi_pool_buf",
1189 .data = &nss_n2h_wifi_pool_buf_cfg,
1190 .maxlen = sizeof(int),
1191 .mode = 0644,
1192 .proc_handler = &nss_n2h_wifi_payloads_handler,
1193 },
Stephen Wang49b474b2016-03-25 10:40:30 -07001194 {
1195 .procname = "rps",
1196 .data = &nss_n2h_rps_config,
1197 .maxlen = sizeof(int),
1198 .mode = 0644,
1199 .proc_handler = &nss_n2h_rpscfg_handler,
1200 },
1201 {
1202 .procname = "mitigation_core0",
1203 .data = &nss_n2h_core0_mitigation_cfg,
1204 .maxlen = sizeof(int),
1205 .mode = 0644,
1206 .proc_handler = &nss_n2h_mitigationcfg_core0_handler,
1207 },
1208 {
1209 .procname = "mitigation_core1",
1210 .data = &nss_n2h_core1_mitigation_cfg,
1211 .maxlen = sizeof(int),
1212 .mode = 0644,
1213 .proc_handler = &nss_n2h_mitigationcfg_core1_handler,
1214 },
1215 {
1216 .procname = "extra_pbuf_core0",
1217 .data = &nss_n2h_core0_add_buf_pool_size,
1218 .maxlen = sizeof(int),
1219 .mode = 0644,
1220 .proc_handler = &nss_n2h_buf_cfg_core0_handler,
1221 },
1222 {
1223 .procname = "extra_pbuf_core1",
1224 .data = &nss_n2h_core1_add_buf_pool_size,
1225 .maxlen = sizeof(int),
1226 .mode = 0644,
1227 .proc_handler = &nss_n2h_buf_cfg_core1_handler,
1228 },
Vijay Dewangan488e5372014-12-29 21:40:11 -08001229
1230 { }
1231};
1232
Stephen Wang52e6d342016-03-29 15:02:33 -07001233static struct ctl_table nss_n2h_dir[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001234 {
1235 .procname = "n2hcfg",
1236 .mode = 0555,
1237 .child = nss_n2h_table,
1238 },
1239 { }
1240};
1241
1242
Stephen Wang52e6d342016-03-29 15:02:33 -07001243static struct ctl_table nss_n2h_root_dir[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001244 {
1245 .procname = "nss",
1246 .mode = 0555,
1247 .child = nss_n2h_dir,
1248 },
1249 { }
1250};
1251
Stephen Wang52e6d342016-03-29 15:02:33 -07001252static struct ctl_table nss_n2h_root[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001253 {
1254 .procname = "dev",
1255 .mode = 0555,
1256 .child = nss_n2h_root_dir,
1257 },
1258 { }
1259};
1260
1261static struct ctl_table_header *nss_n2h_header;
1262
1263/*
Stephen Wang49b474b2016-03-25 10:40:30 -07001264 * nss_n2h_flush_payloads()
1265 * Sends a command down to NSS for flushing all payloads
1266 */
1267nss_tx_status_t nss_n2h_flush_payloads(struct nss_ctx_instance *nss_ctx)
1268{
1269 struct nss_n2h_msg nnm;
1270 struct nss_n2h_flush_payloads *nnflshpl;
1271 nss_tx_status_t nss_tx_status;
1272
1273 nnflshpl = &nnm.msg.flush_payloads;
1274
1275 /*
1276 * TODO: No additional information sent in message
1277 * as of now. Need to initialize message content accordingly
1278 * if needed.
1279 */
1280 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1281 NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS,
1282 sizeof(struct nss_n2h_flush_payloads),
1283 NULL,
1284 NULL);
1285
1286 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1287 if (nss_tx_status != NSS_TX_SUCCESS) {
1288 nss_warning("%p: failed to send flush payloads command to NSS\n",
1289 nss_ctx);
1290
1291 return NSS_TX_FAILURE;
1292 }
1293
1294 return NSS_TX_SUCCESS;
1295}
1296
1297/*
Vijay Dewangan488e5372014-12-29 21:40:11 -08001298 * nss_n2h_msg_init()
Stephen Wang49b474b2016-03-25 10:40:30 -07001299 * Initialize n2h message.
Vijay Dewangan488e5372014-12-29 21:40:11 -08001300 */
1301void nss_n2h_msg_init(struct nss_n2h_msg *nim, uint16_t if_num, uint32_t type,
Vijay Dewangan634ce592015-01-07 17:21:09 -08001302 uint32_t len, nss_n2h_msg_callback_t cb, void *app_data)
Vijay Dewangan488e5372014-12-29 21:40:11 -08001303{
1304 nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data);
1305}
1306
Vijay Dewangan488e5372014-12-29 21:40:11 -08001307/*
Vijay Dewangan488e5372014-12-29 21:40:11 -08001308 * nss_n2h_tx_msg()
1309 * Send messages to NSS n2h pacakge
1310 */
1311nss_tx_status_t nss_n2h_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_n2h_msg *nnm)
1312{
1313 struct nss_n2h_msg *nnm2;
1314 struct nss_cmn_msg *ncm = &nnm->cm;
1315 struct sk_buff *nbuf;
1316 nss_tx_status_t status;
1317
1318 NSS_VERIFY_CTX_MAGIC(nss_ctx);
1319 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
1320 return NSS_TX_FAILURE_NOT_READY;
1321 }
1322
1323 /*
1324 * Sanity check the message
1325 */
1326 if (ncm->interface != NSS_N2H_INTERFACE) {
1327 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
1328 return NSS_TX_FAILURE;
1329 }
1330
1331 if (ncm->type >= NSS_METADATA_TYPE_N2H_MAX) {
1332 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
1333 return NSS_TX_FAILURE;
1334 }
1335
Suruchi Agarwalef8a8702016-01-08 12:40:08 -08001336 if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_n2h_msg)) {
1337 nss_warning("%p: tx request for another interface: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
Vijay Dewangan488e5372014-12-29 21:40:11 -08001338 return NSS_TX_FAILURE;
1339 }
1340
1341
1342 nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
1343 if (unlikely(!nbuf)) {
Sundarajan Srinivasan62fee7e2015-01-22 11:13:10 -08001344 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]);
Vijay Dewangan488e5372014-12-29 21:40:11 -08001345 return NSS_TX_FAILURE;
1346 }
1347
1348 /*
1349 * Copy the message to our skb.
1350 */
1351 nnm2 = (struct nss_n2h_msg *)skb_put(nbuf, sizeof(struct nss_n2h_msg));
1352 memcpy(nnm2, nnm, sizeof(struct nss_n2h_msg));
1353 status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
1354 if (status != NSS_CORE_STATUS_SUCCESS) {
1355 dev_kfree_skb_any(nbuf);
1356 nss_info("%p: unable to enqueue 'nss frequency change' - marked as stopped\n", nss_ctx);
1357 return NSS_TX_FAILURE;
1358 }
1359
Stephen Wang90c67de2016-04-26 15:15:59 -07001360 nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
Vijay Dewangan488e5372014-12-29 21:40:11 -08001361 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
1362 return NSS_TX_SUCCESS;
1363}
1364
Vijay Dewangan488e5372014-12-29 21:40:11 -08001365/*
1366 * nss_n2h_notify_register()
1367 * Register to received N2H events.
1368 *
1369 * NOTE: Do we want to pass an nss_ctx here so that we can register for n2h on any core?
1370 */
1371struct nss_ctx_instance *nss_n2h_notify_register(int core, nss_n2h_msg_callback_t cb, void *app_data)
1372{
1373 if (core >= NSS_MAX_CORES) {
1374 nss_warning("Input core number %d is wrong \n", core);
1375 return NULL;
1376 }
1377 /*
1378 * TODO: We need to have a new array in support of the new API
1379 * TODO: If we use a per-context array, we would move the array into nss_ctx based.
1380 */
1381 nss_n2h_rd[core].n2h_callback = cb;
1382 nss_n2h_rd[core].app_data = app_data;
1383 return &nss_top_main.nss[core];
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301384}
1385
1386/*
1387 * nss_n2h_register_handler()
1388 */
1389void nss_n2h_register_handler()
1390{
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -07001391 nss_core_register_handler(NSS_N2H_INTERFACE, nss_n2h_interface_handler, NULL);
Stephen Wang49b474b2016-03-25 10:40:30 -07001392}
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -07001393
Stephen Wang49b474b2016-03-25 10:40:30 -07001394/*
1395 * nss_n2h_register_sysctl()
1396 */
1397void nss_n2h_register_sysctl(void)
1398{
Vijay Dewangan634ce592015-01-07 17:21:09 -08001399 /*
1400 * RPS sema init
1401 */
1402 sema_init(&nss_n2h_rcp.sem, 1);
1403 init_completion(&nss_n2h_rcp.complete);
1404
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301405 /*
1406 * MITIGATION sema init for core0
1407 */
1408 sema_init(&nss_n2h_mitigationcp[NSS_CORE_0].sem, 1);
1409 init_completion(&nss_n2h_mitigationcp[NSS_CORE_0].complete);
1410
1411 /*
1412 * MITIGATION sema init for core1
1413 */
1414 sema_init(&nss_n2h_mitigationcp[NSS_CORE_1].sem, 1);
1415 init_completion(&nss_n2h_mitigationcp[NSS_CORE_1].complete);
1416
1417 /*
1418 * PBUF addition sema init for core0
1419 */
1420 sema_init(&nss_n2h_bufcp[NSS_CORE_0].sem, 1);
1421 init_completion(&nss_n2h_bufcp[NSS_CORE_0].complete);
1422
1423 /*
1424 * PBUF addition sema init for core1
1425 */
1426 sema_init(&nss_n2h_bufcp[NSS_CORE_1].sem, 1);
1427 init_completion(&nss_n2h_bufcp[NSS_CORE_1].complete);
Vijay Dewangan634ce592015-01-07 17:21:09 -08001428
Stephen Wang49b474b2016-03-25 10:40:30 -07001429 /*
1430 * Core0
1431 */
1432 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_0].sem, 1);
1433 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_0].complete);
1434 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool =
1435 nss_n2h_empty_pool_buf_cfg[NSS_CORE_0];
1436 nss_n2h_nepbcfgp[NSS_CORE_0].low_water =
1437 nss_n2h_water_mark[NSS_CORE_0][0];
1438 nss_n2h_nepbcfgp[NSS_CORE_0].high_water =
1439 nss_n2h_water_mark[NSS_CORE_0][1];
1440
1441 /*
1442 * Core1
1443 */
1444 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_1].sem, 1);
1445 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_1].complete);
1446 nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool =
1447 nss_n2h_empty_pool_buf_cfg[NSS_CORE_1];
1448 nss_n2h_nepbcfgp[NSS_CORE_1].low_water =
1449 nss_n2h_water_mark[NSS_CORE_1][0];
1450 nss_n2h_nepbcfgp[NSS_CORE_1].high_water =
1451 nss_n2h_water_mark[NSS_CORE_1][1];
1452
1453 /*
1454 * WiFi pool buf cfg sema init
1455 */
1456 sema_init(&nss_n2h_wp.sem, 1);
1457 init_completion(&nss_n2h_wp.complete);
1458
Vijay Dewangan488e5372014-12-29 21:40:11 -08001459 nss_n2h_notify_register(NSS_CORE_0, NULL, NULL);
1460 nss_n2h_notify_register(NSS_CORE_1, NULL, NULL);
1461
Stephen Wang49b474b2016-03-25 10:40:30 -07001462 /*
1463 * Register sysctl table.
1464 */
1465 nss_n2h_header = register_sysctl_table(nss_n2h_root);
1466}
1467
1468/*
1469 * nss_n2h_unregister_sysctl()
1470 * Unregister sysctl specific to n2h
1471 */
1472void nss_n2h_unregister_sysctl(void)
1473{
1474 /*
1475 * Unregister sysctl table.
1476 */
1477 if (nss_n2h_header) {
1478 unregister_sysctl_table(nss_n2h_header);
1479 }
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301480}
Vijay Dewangan488e5372014-12-29 21:40:11 -08001481
1482EXPORT_SYMBOL(nss_n2h_notify_register);