blob: e16f9b61d7371f34835b31c6d38df4babcadec1d [file] [log] [blame]
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301/*
2 **************************************************************************
Stephen Wangefd38512017-01-24 14:01:02 -08003 * Copyright (c) 2013-2017, 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 */
Stephen Wangaed46332016-12-12 17:29:03 -0800181 ncm->cb = (nss_ptr_t)nss_n2h_rd[nss_ctx->id].n2h_callback;
182 ncm->app_data = (nss_ptr_t)nss_n2h_rd[nss_ctx->id].app_data;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800183 }
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{
Stephen Wangaed46332016-12-12 17:29:03 -0800232 uint32_t core_num = (uint32_t)(nss_ptr_t)app_data;
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530233 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{
Stephen Wangaed46332016-12-12 17:29:03 -0800260 uint32_t core_num = (uint32_t)(nss_ptr_t)app_data;
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530261 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{
Stephen Wangaed46332016-12-12 17:29:03 -0800290 uint32_t core_num = (uint32_t)(nss_ptr_t)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,
Stephen Wangaed46332016-12-12 17:29:03 -0800346 nss_ptr_t core_num)
Saurabh Misra71034db2015-06-04 16:18:38 -0700347{
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) {
Stephen Wangaed46332016-12-12 17:29:03 -0800369 nss_warning("%p: core %d nss_tx error errorn", nss_ctx, (int)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700370 return NSS_FAILURE;
371 }
372
373 /*
374 * Blocking call, wait till we get ACK for this msg.
375 */
376 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
377 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
378 if (ret == 0) {
Stephen Wangaed46332016-12-12 17:29:03 -0800379 nss_warning("%p: core %d waiting for ack timed out\n", nss_ctx, (int)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700380 return NSS_FAILURE;
381 }
382
383 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
Stephen Wangaed46332016-12-12 17:29:03 -0800384 nss_warning("%p: core %d response returned failure\n", nss_ctx, (int)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700385 return NSS_FAILURE;
386 }
387
388 return NSS_SUCCESS;
389}
390
391/*
392 * nss_n2h_set_empty_pool_buf()
393 * Sets empty pool buffer
394 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700395static int nss_n2h_set_empty_pool_buf(struct ctl_table *ctl, int write,
Saurabh Misra71034db2015-06-04 16:18:38 -0700396 void __user *buffer,
397 size_t *lenp, loff_t *ppos,
Stephen Wangaed46332016-12-12 17:29:03 -0800398 nss_ptr_t core_num, int *new_val)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800399{
400 struct nss_top_instance *nss_top = &nss_top_main;
401 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
402 struct nss_n2h_msg nnm;
403 struct nss_n2h_empty_pool_buf *nnepbcm;
404 nss_tx_status_t nss_tx_status;
405 int ret = NSS_FAILURE;
406
407 /*
408 * Acquiring semaphore
409 */
410 down(&nss_n2h_nepbcfgp[core_num].sem);
411
412 /*
413 * Take snap shot of current value
414 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700415 nss_n2h_nepbcfgp[core_num].empty_buf_pool = *new_val;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800416
Saurabh Misra71034db2015-06-04 16:18:38 -0700417 if (!write) {
418 ret = nss_n2h_get_payload_info(ctl, write, buffer, lenp, ppos,
419 core_num);
420 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool;
421 if (ret == NSS_FAILURE) {
422 up(&nss_n2h_nepbcfgp[core_num].sem);
423 return -EBUSY;
424 }
425
426 up(&nss_n2h_nepbcfgp[core_num].sem);
427
428 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
429 return ret;
430 }
431
Vijay Dewangan488e5372014-12-29 21:40:11 -0800432 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
Saurabh Misra71034db2015-06-04 16:18:38 -0700433 if (ret) {
Vijay Dewangan488e5372014-12-29 21:40:11 -0800434 up(&nss_n2h_nepbcfgp[core_num].sem);
435 return ret;
436 }
437
Vijay Dewangan488e5372014-12-29 21:40:11 -0800438 if ((*new_val < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700439 nss_warning("%p: core %d setting %d < min number of buffer",
Stephen Wangaed46332016-12-12 17:29:03 -0800440 nss_ctx, (int)core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800441 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800442 }
443
444 nss_info("%p: core %d number of empty pool buffer is : %d\n",
Stephen Wangaed46332016-12-12 17:29:03 -0800445 nss_ctx, (int)core_num, *new_val);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800446
447 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
448 NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG,
449 sizeof(struct nss_n2h_empty_pool_buf),
Saurabh Misra71034db2015-06-04 16:18:38 -0700450 nss_n2h_payload_stats_callback,
Stephen Wangaed46332016-12-12 17:29:03 -0800451 (nss_ptr_t *)core_num);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800452
453 nnepbcm = &nnm.msg.empty_pool_buf_cfg;
454 nnepbcm->pool_size = htonl(*new_val);
455 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
456
457 if (nss_tx_status != NSS_TX_SUCCESS) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700458 nss_warning("%p: core %d nss_tx error empty pool buffer: %d\n",
Stephen Wangaed46332016-12-12 17:29:03 -0800459 nss_ctx, (int)core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800460 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800461 }
462
463 /*
464 * Blocking call, wait till we get ACK for this msg.
465 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700466 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
467 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
Vijay Dewangan488e5372014-12-29 21:40:11 -0800468 if (ret == 0) {
Stephen Wangaed46332016-12-12 17:29:03 -0800469 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx, (int)core_num);
Stephen Wang06761022015-03-03 16:38:42 -0800470 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800471 }
472
473 /*
474 * ACK/NACK received from NSS FW
475 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
476 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
477 */
478 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
Stephen Wang06761022015-03-03 16:38:42 -0800479 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800480 }
481
482 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700483 return 0;
Stephen Wang06761022015-03-03 16:38:42 -0800484
485failure:
486 /*
487 * Restore the current_value to its previous state
488 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700489 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool;
490 up(&nss_n2h_nepbcfgp[core_num].sem);
491 return NSS_FAILURE;
492}
493
494/*
495 * nss_n2h_set_water_mark()
496 * Sets water mark for N2H SOS
497 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700498static int nss_n2h_set_water_mark(struct ctl_table *ctl, int write,
Saurabh Misra71034db2015-06-04 16:18:38 -0700499 void __user *buffer,
500 size_t *lenp, loff_t *ppos,
Stephen Wangaed46332016-12-12 17:29:03 -0800501 uint32_t core_num, int *low, int *high)
Saurabh Misra71034db2015-06-04 16:18:38 -0700502{
503 struct nss_top_instance *nss_top = &nss_top_main;
504 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
505 struct nss_n2h_msg nnm;
506 struct nss_n2h_water_mark *wm;
507 nss_tx_status_t nss_tx_status;
508 int ret = NSS_FAILURE;
509
510 /*
511 * Acquiring semaphore
512 */
513 down(&nss_n2h_nepbcfgp[core_num].sem);
514
515 /*
516 * Take snap shot of current value
517 */
518 nss_n2h_nepbcfgp[core_num].low_water = *low;
519 nss_n2h_nepbcfgp[core_num].high_water = *high;
520
521 if (!write) {
522 ret = nss_n2h_get_payload_info(ctl, write, buffer, lenp, ppos,
523 core_num);
524 *low = nss_n2h_nepbcfgp[core_num].low_water;
525 *high = nss_n2h_nepbcfgp[core_num].high_water;
526
527 if (ret == NSS_FAILURE) {
528 up(&nss_n2h_nepbcfgp[core_num].sem);
529 return -EBUSY;
530 }
531
532 up(&nss_n2h_nepbcfgp[core_num].sem);
533 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
534 return ret;
535 }
536
537 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
538 if (ret) {
539 up(&nss_n2h_nepbcfgp[core_num].sem);
540 return ret;
541 }
542
543 /*
544 * If either low or high water mark is not set then we do
545 * nothing.
546 */
547 if (*low == -1 || *high == -1)
548 goto failure;
549
550 if ((*low < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) ||
551 (*high < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
552 nss_warning("%p: core %d setting %d, %d < min number of buffer",
553 nss_ctx, core_num, *low, *high);
554 goto failure;
555 }
556
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530557 if ((*low > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ) ||
558 (*high > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700559 nss_warning("%p: core %d setting %d, %d is > upper limit",
560 nss_ctx, core_num, *low, *high);
561 goto failure;
562 }
563
564 if (*low > *high) {
565 nss_warning("%p: core %d setting low %d is more than high %d",
566 nss_ctx, core_num, *low, *high);
567 goto failure;
568 }
569
570 nss_info("%p: core %d number of low : %d and high : %d\n",
571 nss_ctx, core_num, *low, *high);
572
573 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
574 NSS_TX_METADATA_TYPE_SET_WATER_MARK,
575 sizeof(struct nss_n2h_water_mark),
576 nss_n2h_payload_stats_callback,
Stephen Wangaed46332016-12-12 17:29:03 -0800577 (void *)(nss_ptr_t)core_num);
Saurabh Misra71034db2015-06-04 16:18:38 -0700578
579 wm = &nnm.msg.wm;
580 wm->low_water = htonl(*low);
581 wm->high_water = htonl(*high);
582 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
583
584 if (nss_tx_status != NSS_TX_SUCCESS) {
585 nss_warning("%p: core %d nss_tx error setting : %d, %d\n",
586 nss_ctx, core_num, *low, *high);
587 goto failure;
588 }
589
590 /*
591 * Blocking call, wait till we get ACK for this msg.
592 */
593 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
594 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
595 if (ret == 0) {
596 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
597 core_num);
598 goto failure;
599 }
600
601 /*
602 * ACK/NACK received from NSS FW
603 */
604 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response)
605 goto failure;
606
607 up(&nss_n2h_nepbcfgp[core_num].sem);
608 return NSS_SUCCESS;
609
610failure:
611 /*
612 * Restore the current_value to its previous state
613 */
614 *low = nss_n2h_nepbcfgp[core_num].low_water;
615 *high = nss_n2h_nepbcfgp[core_num].high_water;
Stephen Wang06761022015-03-03 16:38:42 -0800616 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700617 return -EINVAL;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800618}
619
620/*
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530621 * nss_n2h_cfg_wifi_pool()
622 * Sets number of wifi payloads to adjust high water mark for N2H SoS
623 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700624static int nss_n2h_cfg_wifi_pool(struct ctl_table *ctl, int write,
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530625 void __user *buffer,
626 size_t *lenp, loff_t *ppos,
627 int *payloads)
628{
629 struct nss_top_instance *nss_top = &nss_top_main;
630 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
631 struct nss_n2h_msg nnm;
632 struct nss_n2h_wifi_payloads *wp;
633 nss_tx_status_t nss_tx_status;
634 int ret = NSS_FAILURE;
635
636 /*
637 * Acquiring semaphore
638 */
639 down(&nss_n2h_wp.sem);
640
641 if (!write) {
642 *payloads = nss_n2h_wp.wifi_pool;
643
644 up(&nss_n2h_wp.sem);
645 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
646 return ret;
647 }
648
649 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
650 if (ret) {
651 up(&nss_n2h_wp.sem);
652 return ret;
653 }
654
655 /*
656 * If payloads parameter is not set, we do
657 * nothing.
658 */
659 if (*payloads == -1)
660 goto failure;
661
662 if ((*payloads < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
663 nss_warning("%p: wifi setting %d < min number of buffer",
664 nss_ctx, *payloads);
665 goto failure;
666 }
667
668 if ((*payloads > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) {
669 nss_warning("%p: wifi setting %d > max number of buffer",
670 nss_ctx, *payloads);
671 goto failure;
672 }
673
674 nss_info("%p: wifi payloads : %d\n",
675 nss_ctx, *payloads);
676
677 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
678 NSS_TX_METADATA_TYPE_N2H_WIFI_POOL_BUF_CFG,
679 sizeof(struct nss_n2h_wifi_payloads),
680 nss_n2h_set_wifi_payloads_callback,
681 (void *)nss_ctx);
682
683 wp = &nnm.msg.wp;
684 wp->payloads = htonl(*payloads);
685 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
686
687 if (nss_tx_status != NSS_TX_SUCCESS) {
688 nss_warning("%p: wifi setting %d nss_tx error",
689 nss_ctx, *payloads);
690 goto failure;
691 }
692
693 /*
694 * Blocking call, wait till we get ACK for this msg.
695 */
696 ret = wait_for_completion_timeout(&nss_n2h_wp.complete,
697 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
698 if (ret == 0) {
699 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
700 goto failure;
701 }
702
703 /*
704 * ACK/NACK received from NSS FW
705 */
706 if (NSS_FAILURE == nss_n2h_wp.response)
707 goto failure;
708
709 up(&nss_n2h_wp.sem);
710 return NSS_SUCCESS;
711
712failure:
713 up(&nss_n2h_wp.sem);
714 return -EINVAL;
715}
716
717/*
Vijay Dewangan488e5372014-12-29 21:40:11 -0800718 * nss_n2h_empty_pool_buf_core1_handler()
719 * Sets the number of empty buffer for core 1
720 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700721static int nss_n2h_empty_pool_buf_cfg_core1_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700722 int write, void __user *buffer,
723 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800724{
725 return nss_n2h_set_empty_pool_buf(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700726 NSS_CORE_1, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800727}
728
729/*
730 * nss_n2h_empty_pool_buf_core0_handler()
731 * Sets the number of empty buffer for core 0
732 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700733static int nss_n2h_empty_pool_buf_cfg_core0_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700734 int write, void __user *buffer,
735 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800736{
737 return nss_n2h_set_empty_pool_buf(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700738 NSS_CORE_0, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0]);
739}
740
741/*
742 * nss_n2h_water_mark_core1_handler()
743 * Sets water mark for core 1
744 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700745static int nss_n2h_water_mark_core1_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700746 int write, void __user *buffer,
747 size_t *lenp, loff_t *ppos)
748{
749 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
750 NSS_CORE_1, &nss_n2h_water_mark[NSS_CORE_1][0],
751 &nss_n2h_water_mark[NSS_CORE_1][1]);
752}
753
754/*
755 * nss_n2h_water_mark_core0_handler()
756 * Sets water mark for core 0
757 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700758static int nss_n2h_water_mark_core0_handler(struct ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700759 int write, void __user *buffer,
760 size_t *lenp, loff_t *ppos)
761{
762 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
763 NSS_CORE_0, &nss_n2h_water_mark[NSS_CORE_0][0],
764 &nss_n2h_water_mark[NSS_CORE_0][1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800765}
766
Vijay Dewangan634ce592015-01-07 17:21:09 -0800767/*
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530768 * nss_n2h_wifi_payloads_handler()
769 * Sets number of wifi payloads
770 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700771static int nss_n2h_wifi_payloads_handler(struct ctl_table *ctl,
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +0530772 int write, void __user *buffer,
773 size_t *lenp, loff_t *ppos)
774{
775 return nss_n2h_cfg_wifi_pool(ctl, write, buffer, lenp, ppos,
776 &nss_n2h_wifi_pool_buf_cfg);
777}
778
779/*
ratheesh kannoth024a6e82017-05-18 17:48:10 +0530780 * nss_n2h_update_queue_config()
781 * Updates pnode queue configuration and limits
782 */
783nss_tx_status_t nss_n2h_update_queue_config(int max_pri, bool mq_en, int num_pri, int *qlimits)
784{
785 struct nss_n2h_msg nnm;
786 struct nss_n2h_pnode_queue_config *cfg;
787 nss_tx_status_t status;
788 struct nss_top_instance *nss_top = &nss_top_main;
789 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
790 int i;
791
792 if (!mq_en) {
793 return NSS_TX_SUCCESS;
794 }
795
796 if (num_pri <= 0) {
797 nss_warning("%p: nss_tx error in pnode queue config param", nss_ctx);
798 return NSS_TX_FAILURE_BAD_PARAM;
799 }
800
801 if (max_pri < num_pri) {
802 nss_warning("%p: nss_tx error in pnode queue config param, maximum supported priority is %d", nss_ctx, max_pri);
803 return NSS_TX_FAILURE_BAD_PARAM;
804 }
805
806 cfg = &nnm.msg.pn_q_cfg;
807 cfg->num_pri = num_pri;
808 for (i = 0; i < num_pri; i++) {
809 cfg->qlimits[i] = qlimits[i];
810 }
811 cfg->mq_en = true;
812
813 /*
814 * Create message for FW
815 */
816 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
817 NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG,
818 sizeof(struct nss_n2h_pnode_queue_config), NULL, 0);
819
820 status = nss_n2h_tx_msg(nss_ctx, &nnm);
821 if (status != NSS_TX_SUCCESS) {
822 nss_warning("%p: nss_tx error to send pnode queue config\n", nss_ctx);
823 return status;
824 }
825
826 return NSS_TX_SUCCESS;
827
828}
829EXPORT_SYMBOL(nss_n2h_update_queue_config);
830
831/*
Vijay Dewangan634ce592015-01-07 17:21:09 -0800832 * nss_n2h_rps_cfg()
833 * Send Message to NSS to enable RPS.
834 */
Stephen Wang49b474b2016-03-25 10:40:30 -0700835static nss_tx_status_t nss_n2h_rps_cfg(struct nss_ctx_instance *nss_ctx, int enable_rps)
Vijay Dewangan634ce592015-01-07 17:21:09 -0800836{
837 struct nss_n2h_msg nnm;
838 struct nss_n2h_rps *rps_cfg;
839 nss_tx_status_t nss_tx_status;
840 int ret;
841
842 down(&nss_n2h_rcp.sem);
843 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_RPS_CFG,
844 sizeof(struct nss_n2h_rps),
845 nss_n2h_rps_cfg_callback,
846 (void *)nss_ctx);
847
848 rps_cfg = &nnm.msg.rps_cfg;
849 rps_cfg->enable = enable_rps;
850
851 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
852
853 if (nss_tx_status != NSS_TX_SUCCESS) {
854 nss_warning("%p: nss_tx error setting rps\n", nss_ctx);
855
856 up(&nss_n2h_rcp.sem);
857 return NSS_FAILURE;
858 }
859
860 /*
861 * Blocking call, wait till we get ACK for this msg.
862 */
863 ret = wait_for_completion_timeout(&nss_n2h_rcp.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
864 if (ret == 0) {
865 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
866 up(&nss_n2h_rcp.sem);
867 return NSS_FAILURE;
868 }
869
870 /*
871 * ACK/NACK received from NSS FW
872 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
873 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
874 */
875 if (NSS_FAILURE == nss_n2h_rcp.response) {
876 up(&nss_n2h_rcp.sem);
877 return NSS_FAILURE;
878 }
879
880 up(&nss_n2h_rcp.sem);
881 return NSS_SUCCESS;
882}
883
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530884/*
885 * nss_n2h_mitigation_cfg()
886 * Send Message to NSS to disable MITIGATION.
887 */
Stephen Wang49b474b2016-03-25 10:40:30 -0700888static 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 +0530889{
890 struct nss_n2h_msg nnm;
891 struct nss_n2h_mitigation *mitigation_cfg;
892 nss_tx_status_t nss_tx_status;
893 int ret;
894
895 nss_assert(core_num < NSS_CORE_MAX);
896
897 down(&nss_n2h_mitigationcp[core_num].sem);
898 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG,
899 sizeof(struct nss_n2h_mitigation),
900 nss_n2h_mitigation_cfg_callback,
901 (void *)core_num);
902
903 mitigation_cfg = &nnm.msg.mitigation_cfg;
904 mitigation_cfg->enable = enable_mitigation;
905
906 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
907
908 if (nss_tx_status != NSS_TX_SUCCESS) {
909 nss_warning("%p: nss_tx error setting mitigation\n", nss_ctx);
910 goto failure;
911 }
912
913 /*
914 * Blocking call, wait till we get ACK for this msg.
915 */
916 ret = wait_for_completion_timeout(&nss_n2h_mitigationcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
917 if (ret == 0) {
918 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
919 goto failure;
920 }
921
922 /*
923 * ACK/NACK received from NSS FW
924 */
925 if (NSS_FAILURE == nss_n2h_mitigationcp[core_num].response) {
926 goto failure;
927 }
928
929 up(&nss_n2h_mitigationcp[core_num].sem);
930 return NSS_SUCCESS;
931
932failure:
933 up(&nss_n2h_mitigationcp[core_num].sem);
934 return NSS_FAILURE;
935}
936
937static inline void nss_n2h_buf_pool_free(struct nss_n2h_buf_pool *buf_pool)
938{
939 int page_count;
940 for (page_count = 0; page_count < buf_pool->nss_buf_num_pages; page_count++) {
941 kfree(buf_pool->nss_buf_pool_vaddr[page_count]);
942 }
943}
944
945/*
946 * nss_n2h_buf_cfg()
947 * Send Message to NSS to enable pbufs.
948 */
Stephen Wang49b474b2016-03-25 10:40:30 -0700949static nss_tx_status_t nss_n2h_buf_pool_cfg(struct nss_ctx_instance *nss_ctx,
Tallapragada4b0161b2016-07-07 21:38:34 +0530950 int buf_pool_size, nss_core_id_t core_num)
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530951{
952 static struct nss_n2h_msg nnm;
953 struct nss_n2h_buf_pool *buf_pool;
954 nss_tx_status_t nss_tx_status;
955 int ret;
956 int page_count;
957 int num_pages = ALIGN(buf_pool_size, PAGE_SIZE)/PAGE_SIZE;
958
959 nss_assert(core_num < NSS_CORE_MAX);
960
961 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_METADATA_TYPE_N2H_ADD_BUF_POOL,
962 sizeof(struct nss_n2h_buf_pool),
963 nss_n2h_bufs_cfg_callback,
964 (void *)core_num);
965
966 do {
967
968 down(&nss_n2h_bufcp[core_num].sem);
969
970 buf_pool = &nnm.msg.buf_pool;
971 buf_pool->nss_buf_page_size = PAGE_SIZE;
972
973 for (page_count = 0; page_count < MAX_PAGES_PER_MSG && num_pages; page_count++, num_pages--) {
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530974 void *kern_addr = kzalloc(PAGE_SIZE, GFP_ATOMIC);
975 if (!kern_addr) {
976 BUG_ON(!page_count);
977 break;
978 }
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530979
Radha krishna Simha Jiguru60068fb2017-07-28 17:40:52 +0530980 kmemleak_not_leak(kern_addr);
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530981 buf_pool->nss_buf_pool_vaddr[page_count] = kern_addr;
Stephen Wangefd38512017-01-24 14:01:02 -0800982 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 +0530983 }
984
985 buf_pool->nss_buf_num_pages = page_count;
986 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
987 if (nss_tx_status != NSS_TX_SUCCESS) {
988
989 nss_n2h_buf_pool_free(buf_pool);
990 nss_warning("%p: nss_tx error setting pbuf\n", nss_ctx);
991 goto failure;
992 }
993
994 /*
995 * Blocking call, wait till we get ACK for this msg.
996 */
997 ret = wait_for_completion_timeout(&nss_n2h_bufcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
998 if (ret == 0) {
999 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
1000 goto failure;
1001 }
1002
1003 /*
1004 * ACK/NACK received from NSS FW
1005 */
1006 if (NSS_FAILURE == nss_n2h_bufcp[core_num].response) {
1007
1008 nss_n2h_buf_pool_free(buf_pool);
1009 goto failure;
1010 }
1011
1012 up(&nss_n2h_bufcp[core_num].sem);
1013 } while(num_pages);
1014
1015 return NSS_SUCCESS;
1016failure:
1017 up(&nss_n2h_bufcp[core_num].sem);
1018 return NSS_FAILURE;
1019}
1020
Stephen Wang49b474b2016-03-25 10:40:30 -07001021/*
1022 * nss_rps_handler()
1023 * Enable NSS RPS
1024 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001025static 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 -07001026{
1027 struct nss_top_instance *nss_top = &nss_top_main;
1028 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
1029 int ret;
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301030
Stephen Wang49b474b2016-03-25 10:40:30 -07001031 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1032 if (!ret) {
1033 if ((write) && (nss_n2h_rps_config == 1)) {
1034 printk(KERN_INFO "Enabling NSS RPS\n");
1035
1036 return nss_n2h_rps_cfg(nss_ctx, 1);
1037 }
1038
1039 if ((write) && (nss_n2h_rps_config == 0)) {
1040 printk(KERN_INFO "Runtime disabling of NSS RPS not supported\n");
1041 return ret;
1042 }
1043
1044 if (write) {
1045 printk(KERN_INFO "Invalid input value.Valid values are 0 and 1\n");
1046 }
1047
1048 }
1049
1050 return ret;
1051}
1052
1053/*
1054 * nss_mitigation_handler()
1055 * Enable NSS MITIGATION
1056 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001057static 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 -07001058{
1059 struct nss_top_instance *nss_top = &nss_top_main;
1060 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_0];
1061 int ret;
1062
1063 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1064 if (ret) {
1065 return ret;
1066 }
1067
1068 /*
1069 * It's a read operation
1070 */
1071 if (!write) {
1072 return ret;
1073 }
1074
1075 if (!nss_n2h_core0_mitigation_cfg) {
1076 printk(KERN_INFO "Disabling NSS MITIGATION\n");
1077 nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_0);
1078 return 0;
1079 }
1080 printk(KERN_INFO "Invalid input value.Valid value is 0, Runtime re-enabling not supported\n");
1081 return -EINVAL;
1082}
1083
1084/*
1085 * nss_mitigation_handler()
1086 * Enable NSS MITIGATION
1087 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001088static 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 -07001089{
1090 struct nss_top_instance *nss_top = &nss_top_main;
1091 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_1];
1092 int ret;
1093
1094 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1095 if (ret) {
1096 return ret;
1097 }
1098
1099 /*
1100 * It's a read operation
1101 */
1102 if (!write) {
1103 return ret;
1104 }
1105
1106 if (!nss_n2h_core1_mitigation_cfg) {
1107 printk(KERN_INFO "Disabling NSS MITIGATION\n");
1108 nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_1);
1109 return 0;
1110 }
1111 printk(KERN_INFO "Invalid input value.Valid value is 0, Runtime re-enabling not supported\n");
1112 return -EINVAL;
1113}
1114
1115/*
1116 * nss_buf_handler()
1117 * Add extra NSS bufs from host memory
1118 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001119static 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 -07001120{
1121 struct nss_top_instance *nss_top = &nss_top_main;
1122 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_0];
1123 int ret;
1124
1125 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1126 if (ret) {
1127 return ret;
1128 }
1129
1130 /*
1131 * It's a read operation
1132 */
1133 if (!write) {
1134 return ret;
1135 }
1136
1137 if (nss_ctx->buf_sz_allocated) {
1138 nss_n2h_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1139 return -EPERM;
1140 }
1141
1142 if ((nss_n2h_core0_add_buf_pool_size >= 1) && (nss_n2h_core0_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) {
1143 printk(KERN_INFO "configuring additional NSS pbufs\n");
1144 ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_n2h_core0_add_buf_pool_size, NSS_CORE_0);
1145 nss_n2h_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1146 printk(KERN_INFO "additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated);
1147 return ret;
1148 }
1149
1150 printk(KERN_INFO "Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE);
1151 return -EINVAL;
1152}
1153
1154/*
1155 * nss_n2h_buf_handler()
1156 * Add extra NSS bufs from host memory
1157 */
Stephen Wang52e6d342016-03-29 15:02:33 -07001158static 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 -07001159{
1160 struct nss_top_instance *nss_top = &nss_top_main;
1161 struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_1];
1162 int ret;
1163
1164 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1165 if (ret) {
1166 return ret;
1167 }
1168
1169 /*
1170 * It's a read operation
1171 */
1172 if (!write) {
1173 return ret;
1174 }
1175
1176 if (nss_ctx->buf_sz_allocated) {
1177 nss_n2h_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1178 return -EPERM;
1179 }
1180
1181 if ((nss_n2h_core1_add_buf_pool_size >= 1) && (nss_n2h_core1_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) {
1182 printk(KERN_INFO "configuring additional NSS pbufs\n");
1183 ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_n2h_core1_add_buf_pool_size, NSS_CORE_1);
1184 nss_n2h_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated;
1185 printk(KERN_INFO "additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated);
1186 return ret;
1187 }
1188
1189 printk(KERN_INFO "Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE);
1190 return -EINVAL;
1191}
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301192
Stephen Wang52e6d342016-03-29 15:02:33 -07001193static struct ctl_table nss_n2h_table[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001194 {
Saurabh Misra71034db2015-06-04 16:18:38 -07001195 .procname = "n2h_empty_pool_buf_core0",
1196 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0],
1197 .maxlen = sizeof(int),
1198 .mode = 0644,
1199 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core0_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -08001200 },
1201 {
Saurabh Misra71034db2015-06-04 16:18:38 -07001202 .procname = "n2h_empty_pool_buf_core1",
1203 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1],
1204 .maxlen = sizeof(int),
1205 .mode = 0644,
1206 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core1_handler,
1207 },
1208 {
1209 .procname = "n2h_low_water_core0",
1210 .data = &nss_n2h_water_mark[NSS_CORE_0][0],
1211 .maxlen = sizeof(int),
1212 .mode = 0644,
1213 .proc_handler = &nss_n2h_water_mark_core0_handler,
1214 },
1215 {
1216 .procname = "n2h_low_water_core1",
1217 .data = &nss_n2h_water_mark[NSS_CORE_1][0],
1218 .maxlen = sizeof(int),
1219 .mode = 0644,
1220 .proc_handler = &nss_n2h_water_mark_core1_handler,
1221 },
1222 {
1223 .procname = "n2h_high_water_core0",
1224 .data = &nss_n2h_water_mark[NSS_CORE_0][1],
1225 .maxlen = sizeof(int),
1226 .mode = 0644,
1227 .proc_handler = &nss_n2h_water_mark_core0_handler,
1228 },
1229 {
1230 .procname = "n2h_high_water_core1",
1231 .data = &nss_n2h_water_mark[NSS_CORE_1][1],
1232 .maxlen = sizeof(int),
1233 .mode = 0644,
1234 .proc_handler = &nss_n2h_water_mark_core1_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -08001235 },
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +05301236 {
1237 .procname = "n2h_wifi_pool_buf",
1238 .data = &nss_n2h_wifi_pool_buf_cfg,
1239 .maxlen = sizeof(int),
1240 .mode = 0644,
1241 .proc_handler = &nss_n2h_wifi_payloads_handler,
1242 },
Stephen Wang49b474b2016-03-25 10:40:30 -07001243 {
1244 .procname = "rps",
1245 .data = &nss_n2h_rps_config,
1246 .maxlen = sizeof(int),
1247 .mode = 0644,
1248 .proc_handler = &nss_n2h_rpscfg_handler,
1249 },
1250 {
1251 .procname = "mitigation_core0",
1252 .data = &nss_n2h_core0_mitigation_cfg,
1253 .maxlen = sizeof(int),
1254 .mode = 0644,
1255 .proc_handler = &nss_n2h_mitigationcfg_core0_handler,
1256 },
1257 {
1258 .procname = "mitigation_core1",
1259 .data = &nss_n2h_core1_mitigation_cfg,
1260 .maxlen = sizeof(int),
1261 .mode = 0644,
1262 .proc_handler = &nss_n2h_mitigationcfg_core1_handler,
1263 },
1264 {
1265 .procname = "extra_pbuf_core0",
1266 .data = &nss_n2h_core0_add_buf_pool_size,
1267 .maxlen = sizeof(int),
1268 .mode = 0644,
1269 .proc_handler = &nss_n2h_buf_cfg_core0_handler,
1270 },
1271 {
1272 .procname = "extra_pbuf_core1",
1273 .data = &nss_n2h_core1_add_buf_pool_size,
1274 .maxlen = sizeof(int),
1275 .mode = 0644,
1276 .proc_handler = &nss_n2h_buf_cfg_core1_handler,
1277 },
Vijay Dewangan488e5372014-12-29 21:40:11 -08001278
1279 { }
1280};
1281
Stephen Wang52e6d342016-03-29 15:02:33 -07001282static struct ctl_table nss_n2h_dir[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001283 {
1284 .procname = "n2hcfg",
1285 .mode = 0555,
1286 .child = nss_n2h_table,
1287 },
1288 { }
1289};
1290
Stephen Wang52e6d342016-03-29 15:02:33 -07001291static struct ctl_table nss_n2h_root_dir[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001292 {
1293 .procname = "nss",
1294 .mode = 0555,
1295 .child = nss_n2h_dir,
1296 },
1297 { }
1298};
1299
Stephen Wang52e6d342016-03-29 15:02:33 -07001300static struct ctl_table nss_n2h_root[] = {
Vijay Dewangan488e5372014-12-29 21:40:11 -08001301 {
1302 .procname = "dev",
1303 .mode = 0555,
1304 .child = nss_n2h_root_dir,
1305 },
1306 { }
1307};
1308
1309static struct ctl_table_header *nss_n2h_header;
1310
1311/*
Stephen Wang49b474b2016-03-25 10:40:30 -07001312 * nss_n2h_flush_payloads()
1313 * Sends a command down to NSS for flushing all payloads
1314 */
1315nss_tx_status_t nss_n2h_flush_payloads(struct nss_ctx_instance *nss_ctx)
1316{
1317 struct nss_n2h_msg nnm;
1318 struct nss_n2h_flush_payloads *nnflshpl;
1319 nss_tx_status_t nss_tx_status;
1320
1321 nnflshpl = &nnm.msg.flush_payloads;
1322
1323 /*
1324 * TODO: No additional information sent in message
1325 * as of now. Need to initialize message content accordingly
1326 * if needed.
1327 */
1328 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
1329 NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS,
1330 sizeof(struct nss_n2h_flush_payloads),
1331 NULL,
1332 NULL);
1333
1334 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
1335 if (nss_tx_status != NSS_TX_SUCCESS) {
1336 nss_warning("%p: failed to send flush payloads command to NSS\n",
1337 nss_ctx);
1338
1339 return NSS_TX_FAILURE;
1340 }
1341
1342 return NSS_TX_SUCCESS;
1343}
1344
1345/*
Vijay Dewangan488e5372014-12-29 21:40:11 -08001346 * nss_n2h_msg_init()
Stephen Wang49b474b2016-03-25 10:40:30 -07001347 * Initialize n2h message.
Vijay Dewangan488e5372014-12-29 21:40:11 -08001348 */
1349void nss_n2h_msg_init(struct nss_n2h_msg *nim, uint16_t if_num, uint32_t type,
Vijay Dewangan634ce592015-01-07 17:21:09 -08001350 uint32_t len, nss_n2h_msg_callback_t cb, void *app_data)
Vijay Dewangan488e5372014-12-29 21:40:11 -08001351{
1352 nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data);
1353}
1354
Vijay Dewangan488e5372014-12-29 21:40:11 -08001355/*
Vijay Dewangan488e5372014-12-29 21:40:11 -08001356 * nss_n2h_tx_msg()
1357 * Send messages to NSS n2h pacakge
1358 */
1359nss_tx_status_t nss_n2h_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_n2h_msg *nnm)
1360{
1361 struct nss_n2h_msg *nnm2;
1362 struct nss_cmn_msg *ncm = &nnm->cm;
1363 struct sk_buff *nbuf;
1364 nss_tx_status_t status;
1365
1366 NSS_VERIFY_CTX_MAGIC(nss_ctx);
1367 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
1368 return NSS_TX_FAILURE_NOT_READY;
1369 }
1370
1371 /*
1372 * Sanity check the message
1373 */
1374 if (ncm->interface != NSS_N2H_INTERFACE) {
1375 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
1376 return NSS_TX_FAILURE;
1377 }
1378
1379 if (ncm->type >= NSS_METADATA_TYPE_N2H_MAX) {
1380 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
1381 return NSS_TX_FAILURE;
1382 }
1383
Suruchi Agarwalef8a8702016-01-08 12:40:08 -08001384 if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_n2h_msg)) {
1385 nss_warning("%p: tx request for another interface: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
Vijay Dewangan488e5372014-12-29 21:40:11 -08001386 return NSS_TX_FAILURE;
1387 }
1388
Vijay Dewangan488e5372014-12-29 21:40:11 -08001389 nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
1390 if (unlikely(!nbuf)) {
Sundarajan Srinivasan62fee7e2015-01-22 11:13:10 -08001391 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 -08001392 return NSS_TX_FAILURE;
1393 }
1394
1395 /*
1396 * Copy the message to our skb.
1397 */
1398 nnm2 = (struct nss_n2h_msg *)skb_put(nbuf, sizeof(struct nss_n2h_msg));
1399 memcpy(nnm2, nnm, sizeof(struct nss_n2h_msg));
1400 status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
1401 if (status != NSS_CORE_STATUS_SUCCESS) {
1402 dev_kfree_skb_any(nbuf);
1403 nss_info("%p: unable to enqueue 'nss frequency change' - marked as stopped\n", nss_ctx);
1404 return NSS_TX_FAILURE;
1405 }
1406
Stephen Wang90c67de2016-04-26 15:15:59 -07001407 nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
Vijay Dewangan488e5372014-12-29 21:40:11 -08001408 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
1409 return NSS_TX_SUCCESS;
1410}
1411
Vijay Dewangan488e5372014-12-29 21:40:11 -08001412/*
1413 * nss_n2h_notify_register()
1414 * Register to received N2H events.
1415 *
1416 * NOTE: Do we want to pass an nss_ctx here so that we can register for n2h on any core?
1417 */
1418struct nss_ctx_instance *nss_n2h_notify_register(int core, nss_n2h_msg_callback_t cb, void *app_data)
1419{
1420 if (core >= NSS_MAX_CORES) {
1421 nss_warning("Input core number %d is wrong \n", core);
1422 return NULL;
1423 }
1424 /*
1425 * TODO: We need to have a new array in support of the new API
1426 * TODO: If we use a per-context array, we would move the array into nss_ctx based.
1427 */
1428 nss_n2h_rd[core].n2h_callback = cb;
1429 nss_n2h_rd[core].app_data = app_data;
1430 return &nss_top_main.nss[core];
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301431}
1432
1433/*
1434 * nss_n2h_register_handler()
1435 */
Thomas Wu91f4bdf2017-06-09 12:03:02 -07001436void nss_n2h_register_handler(struct nss_ctx_instance *nss_ctx)
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301437{
Thomas Wu91f4bdf2017-06-09 12:03:02 -07001438 nss_core_register_handler(nss_ctx, NSS_N2H_INTERFACE, nss_n2h_interface_handler, NULL);
Stephen Wang49b474b2016-03-25 10:40:30 -07001439}
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -07001440
Stephen Wang49b474b2016-03-25 10:40:30 -07001441/*
1442 * nss_n2h_register_sysctl()
1443 */
1444void nss_n2h_register_sysctl(void)
1445{
Vijay Dewangan634ce592015-01-07 17:21:09 -08001446 /*
1447 * RPS sema init
1448 */
1449 sema_init(&nss_n2h_rcp.sem, 1);
1450 init_completion(&nss_n2h_rcp.complete);
1451
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301452 /*
1453 * MITIGATION sema init for core0
1454 */
1455 sema_init(&nss_n2h_mitigationcp[NSS_CORE_0].sem, 1);
1456 init_completion(&nss_n2h_mitigationcp[NSS_CORE_0].complete);
1457
1458 /*
1459 * MITIGATION sema init for core1
1460 */
1461 sema_init(&nss_n2h_mitigationcp[NSS_CORE_1].sem, 1);
1462 init_completion(&nss_n2h_mitigationcp[NSS_CORE_1].complete);
1463
1464 /*
1465 * PBUF addition sema init for core0
1466 */
1467 sema_init(&nss_n2h_bufcp[NSS_CORE_0].sem, 1);
1468 init_completion(&nss_n2h_bufcp[NSS_CORE_0].complete);
1469
1470 /*
1471 * PBUF addition sema init for core1
1472 */
1473 sema_init(&nss_n2h_bufcp[NSS_CORE_1].sem, 1);
1474 init_completion(&nss_n2h_bufcp[NSS_CORE_1].complete);
Vijay Dewangan634ce592015-01-07 17:21:09 -08001475
Stephen Wang49b474b2016-03-25 10:40:30 -07001476 /*
1477 * Core0
1478 */
1479 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_0].sem, 1);
1480 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_0].complete);
1481 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool =
1482 nss_n2h_empty_pool_buf_cfg[NSS_CORE_0];
1483 nss_n2h_nepbcfgp[NSS_CORE_0].low_water =
1484 nss_n2h_water_mark[NSS_CORE_0][0];
1485 nss_n2h_nepbcfgp[NSS_CORE_0].high_water =
1486 nss_n2h_water_mark[NSS_CORE_0][1];
1487
1488 /*
1489 * Core1
1490 */
1491 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_1].sem, 1);
1492 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_1].complete);
1493 nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool =
1494 nss_n2h_empty_pool_buf_cfg[NSS_CORE_1];
1495 nss_n2h_nepbcfgp[NSS_CORE_1].low_water =
1496 nss_n2h_water_mark[NSS_CORE_1][0];
1497 nss_n2h_nepbcfgp[NSS_CORE_1].high_water =
1498 nss_n2h_water_mark[NSS_CORE_1][1];
1499
1500 /*
1501 * WiFi pool buf cfg sema init
1502 */
1503 sema_init(&nss_n2h_wp.sem, 1);
1504 init_completion(&nss_n2h_wp.complete);
1505
Vijay Dewangan488e5372014-12-29 21:40:11 -08001506 nss_n2h_notify_register(NSS_CORE_0, NULL, NULL);
1507 nss_n2h_notify_register(NSS_CORE_1, NULL, NULL);
1508
Stephen Wang49b474b2016-03-25 10:40:30 -07001509 /*
1510 * Register sysctl table.
1511 */
1512 nss_n2h_header = register_sysctl_table(nss_n2h_root);
1513}
1514
1515/*
1516 * nss_n2h_unregister_sysctl()
1517 * Unregister sysctl specific to n2h
1518 */
1519void nss_n2h_unregister_sysctl(void)
1520{
1521 /*
1522 * Unregister sysctl table.
1523 */
1524 if (nss_n2h_header) {
1525 unregister_sysctl_table(nss_n2h_header);
1526 }
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301527}
Vijay Dewangan488e5372014-12-29 21:40:11 -08001528
1529EXPORT_SYMBOL(nss_n2h_notify_register);