blob: d2f49f10848e6e816f5c83692f68e5b4ae3fa719 [file] [log] [blame]
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301/*
2 **************************************************************************
Vijay Dewangan488e5372014-12-29 21:40:11 -08003 * Copyright (c) 2013-2015, 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"
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +053023#include <asm/cacheflush.h>
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053024
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053025
Saurabh Misra71034db2015-06-04 16:18:38 -070026#define NSS_N2H_MIN_EMPTY_POOL_BUF_SZ 32
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, Vijayefcc4692014-05-09 14:47:38 +053031
Vijay Dewangan488e5372014-12-29 21:40:11 -080032struct nss_n2h_registered_data {
33 nss_n2h_msg_callback_t n2h_callback;
34 void *app_data;
35};
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053036
Vijay Dewangan488e5372014-12-29 21:40:11 -080037static struct nss_n2h_cfg_pvt nss_n2h_nepbcfgp[NSS_MAX_CORES];
38static struct nss_n2h_registered_data nss_n2h_rd[NSS_MAX_CORES];
Vijay Dewangan634ce592015-01-07 17:21:09 -080039static struct nss_n2h_cfg_pvt nss_n2h_rcp;
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +053040static struct nss_n2h_cfg_pvt nss_n2h_mitigationcp[NSS_CORE_MAX];
41static struct nss_n2h_cfg_pvt nss_n2h_bufcp[NSS_CORE_MAX];
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053042
43/*
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -070044 * nss_n2h_stats_sync()
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053045 * Handle the syncing of NSS statistics.
46 */
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -070047static void nss_n2h_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_n2h_stats_sync *nnss)
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053048{
49 struct nss_top_instance *nss_top = nss_ctx->nss_top;
50
51 spin_lock_bh(&nss_top->stats_lock);
52
53 /*
54 * common node stats
55 */
56 nss_ctx->stats_n2h[NSS_STATS_NODE_RX_PKTS] += nnss->node_stats.rx_packets;
57 nss_ctx->stats_n2h[NSS_STATS_NODE_RX_BYTES] += nnss->node_stats.rx_bytes;
58 nss_ctx->stats_n2h[NSS_STATS_NODE_RX_DROPPED] += nnss->node_stats.rx_dropped;
59 nss_ctx->stats_n2h[NSS_STATS_NODE_TX_PKTS] += nnss->node_stats.tx_packets;
60 nss_ctx->stats_n2h[NSS_STATS_NODE_TX_BYTES] += nnss->node_stats.tx_bytes;
61
62 /*
63 * General N2H stats
64 */
Murat Sezgin0c0561d2014-04-09 18:55:58 -070065 nss_ctx->stats_n2h[NSS_STATS_N2H_QUEUE_DROPPED] += nnss->queue_dropped;
66 nss_ctx->stats_n2h[NSS_STATS_N2H_TOTAL_TICKS] += nnss->total_ticks;
67 nss_ctx->stats_n2h[NSS_STATS_N2H_WORST_CASE_TICKS] += nnss->worst_case_ticks;
68 nss_ctx->stats_n2h[NSS_STATS_N2H_ITERATIONS] += nnss->iterations;
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053069
70 /*
Thomas Wu3fd8dd72014-06-11 15:57:05 -070071 * pbuf manager ocm and default pool stats
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053072 */
Thomas Wu3fd8dd72014-06-11 15:57:05 -070073 nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_OCM_ALLOC_FAILS] += nnss->pbuf_ocm_stats.pbuf_alloc_fails;
74 nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_OCM_FREE_COUNT] = nnss->pbuf_ocm_stats.pbuf_free_count;
75 nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_OCM_TOTAL_COUNT] = nnss->pbuf_ocm_stats.pbuf_total_count;
76
77 nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_DEFAULT_ALLOC_FAILS] += nnss->pbuf_default_stats.pbuf_alloc_fails;
78 nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_DEFAULT_FREE_COUNT] = nnss->pbuf_default_stats.pbuf_free_count;
79 nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_DEFAULT_TOTAL_COUNT] = nnss->pbuf_default_stats.pbuf_total_count;
80
81 /*
82 * payload mgr stats
83 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053084 nss_ctx->stats_n2h[NSS_STATS_N2H_PAYLOAD_ALLOC_FAILS] += nnss->payload_alloc_fails;
Thomas Wu53679842015-01-22 13:37:35 -080085 nss_ctx->stats_n2h[NSS_STATS_N2H_PAYLOAD_FREE_COUNT] = nnss->payload_free_count;
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053086
Sakthi Vignesh Radhakrishnan2a8ee962014-11-22 13:35:38 -080087 /*
88 * Host <=> NSS control traffic stats
89 */
90 nss_ctx->stats_n2h[NSS_STATS_N2H_H2N_CONTROL_PACKETS] += nnss->h2n_ctrl_pkts;
91 nss_ctx->stats_n2h[NSS_STATS_N2H_H2N_CONTROL_BYTES] += nnss->h2n_ctrl_bytes;
92 nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_CONTROL_PACKETS] += nnss->n2h_ctrl_pkts;
93 nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_CONTROL_BYTES] += nnss->n2h_ctrl_bytes;
94
95 /*
96 * Host <=> NSS control data traffic stats
97 */
98 nss_ctx->stats_n2h[NSS_STATS_N2H_H2N_DATA_PACKETS] += nnss->h2n_data_pkts;
99 nss_ctx->stats_n2h[NSS_STATS_N2H_H2N_DATA_BYTES] += nnss->h2n_data_bytes;
100 nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_DATA_PACKETS] += nnss->n2h_data_pkts;
101 nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_DATA_BYTES] += nnss->n2h_data_bytes;
102
Saurabh Misra71034db2015-06-04 16:18:38 -0700103 /*
104 * Payloads related stats
105 */
106 nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_TOT_PAYLOADS] = nnss->tot_payloads;
107
Guojun Jin85dfa7b2015-09-02 15:13:56 -0700108 nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_INTERFACE_INVALID] += nnss->data_interface_invalid;
109
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530110 spin_unlock_bh(&nss_top->stats_lock);
111}
112
113/*
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -0700114 * nss_n2h_interface_handler()
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530115 * Handle NSS -> HLOS messages for N2H node
116 */
Vijay Dewangan634ce592015-01-07 17:21:09 -0800117static void nss_n2h_interface_handler(struct nss_ctx_instance *nss_ctx,
118 struct nss_cmn_msg *ncm,
119 __attribute__((unused))void *app_data)
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530120{
121 struct nss_n2h_msg *nnm = (struct nss_n2h_msg *)ncm;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800122 nss_n2h_msg_callback_t cb;
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530123
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -0700124 BUG_ON(ncm->interface != NSS_N2H_INTERFACE);
125
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530126 /*
127 * Is this a valid request/response packet?
128 */
129 if (nnm->cm.type >= NSS_METADATA_TYPE_N2H_MAX) {
130 nss_warning("%p: received invalid message %d for Offload stats interface", nss_ctx, nnm->cm.type);
131 return;
132 }
133
134 switch (nnm->cm.type) {
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530135 case NSS_TX_METADATA_TYPE_N2H_RPS_CFG:
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530136 nss_info("NSS N2H rps_en %d \n",nnm->msg.rps_cfg.enable);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800137 break;
138
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530139 case NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG:
140 nss_info("NSS N2H mitigation_dis %d \n",nnm->msg.mitigation_cfg.enable);
141 break;
142
Vijay Dewangan488e5372014-12-29 21:40:11 -0800143 case NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG:
144 nss_info("%p: empty pool buf cfg response from FW", nss_ctx);
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530145 break;
146
Radha krishna Simha Jiguru7f424d52015-02-10 19:41:01 +0530147 case NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS:
148 nss_info("%p: flush payloads cmd response from FW", nss_ctx);
149 break;
150
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530151 case NSS_RX_METADATA_TYPE_N2H_STATS_SYNC:
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -0700152 nss_n2h_stats_sync(nss_ctx, &nnm->msg.stats_sync);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530153 break;
154
155 default:
156 if (ncm->response != NSS_CMN_RESPONSE_ACK) {
157 /*
158 * Check response
159 */
160 nss_info("%p: Received response %d for type %d, interface %d",
161 nss_ctx, ncm->response, ncm->type, ncm->interface);
162 }
163 }
Vijay Dewangan488e5372014-12-29 21:40:11 -0800164
165 /*
166 * Update the callback and app_data for NOTIFY messages, IPv4 sends all notify messages
167 * to the same callback/app_data.
168 */
169 if (nnm->cm.response == NSS_CMM_RESPONSE_NOTIFY) {
170 /*
171 * Place holder for the user to create right call
172 * back and app data when response is NSS_CMM_RESPONSE_NOTIFY
173 */
174 ncm->cb = (uint32_t)nss_n2h_rd[nss_ctx->id].n2h_callback;
175 ncm->app_data = (uint32_t)nss_n2h_rd[nss_ctx->id].app_data;
176 }
177
178 /*
179 * Do we have a callback?
180 */
181 if (!ncm->cb) {
182 return;
183 }
184
185 /*
186 * Callback
187 */
188 cb = (nss_n2h_msg_callback_t)ncm->cb;
189 cb((void *)ncm->app_data, nnm);
190}
191
192/*
Vijay Dewangan634ce592015-01-07 17:21:09 -0800193 * nss_n2h_rps_cfg_callback()
194 * call back function for rps configuration
195 */
196static void nss_n2h_rps_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
197{
198 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)app_data;
199 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
200
201 /*
202 * Error, hence we are not updating the nss_n2h_empty_pool_buf
203 * Restore the current_value to its previous state
204 */
205 nss_n2h_rcp.response = NSS_FAILURE;
206 complete(&nss_n2h_rcp.complete);
207 nss_warning("%p: RPS configuration failed : %d\n", nss_ctx,
208 nnm->cm.error);
209 return;
210 }
211
212 nss_info("%p: RPS configuration succeeded: %d\n", nss_ctx,
213 nnm->cm.error);
214 nss_ctx->n2h_rps_en = nnm->msg.rps_cfg.enable;
215 nss_n2h_rcp.response = NSS_SUCCESS;
216 complete(&nss_n2h_rcp.complete);
217}
218
219/*
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530220 * nss_n2h_mitigation_cfg_callback()
221 * call back function for mitigation configuration
222 */
223static void nss_n2h_mitigation_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
224{
225 int core_num = (int)app_data;
226 struct nss_top_instance *nss_top = &nss_top_main;
227 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
228
229 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
230
231 /*
232 * Error, hence we are not updating the nss_n2h_mitigate_en
233 */
234 nss_n2h_mitigationcp[core_num].response = NSS_FAILURE;
235 complete(&nss_n2h_mitigationcp[core_num].complete);
236 nss_warning("core%d: MITIGATION configuration failed : %d\n", core_num, nnm->cm.error);
237 return;
238 }
239
240 nss_info("core%d: MITIGATION configuration succeeded: %d\n", core_num, nnm->cm.error);
241
242 nss_ctx->n2h_mitigate_en = nnm->msg.mitigation_cfg.enable;
243 nss_n2h_mitigationcp[core_num].response = NSS_SUCCESS;
244 complete(&nss_n2h_mitigationcp[core_num].complete);
245}
246
247/*
248 * nss_n2h_buf_cfg_callback()
249 * call back function for pbuf configuration
250 */
251static void nss_n2h_bufs_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
252{
253 int core_num = (int)app_data;
254 unsigned int allocated_sz;
255
256 struct nss_top_instance *nss_top = &nss_top_main;
257 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
258
259 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
260 nss_n2h_bufcp[core_num].response = NSS_FAILURE;
261 nss_warning("core%d: buf configuration failed : %d\n", core_num, nnm->cm.error);
262 goto done;
263 }
264
265 nss_info("core%d: buf configuration succeeded: %d\n", core_num, nnm->cm.error);
266
267 allocated_sz = nnm->msg.buf_pool.nss_buf_page_size * nnm->msg.buf_pool.nss_buf_num_pages;
268 nss_ctx->buf_sz_allocated += allocated_sz;
269
270 nss_n2h_bufcp[core_num].response = NSS_SUCCESS;
271
272done:
273 complete(&nss_n2h_bufcp[core_num].complete);
274}
275
276/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700277 * nss_n2h_payload_stats_callback()
278 * It gets called response to payload accounting.
Vijay Dewangan488e5372014-12-29 21:40:11 -0800279 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700280static void nss_n2h_payload_stats_callback(void *app_data,
281 struct nss_n2h_msg *nnm)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800282{
283 int core_num = (int)app_data;
Saurabh Misra71034db2015-06-04 16:18:38 -0700284
Vijay Dewangan488e5372014-12-29 21:40:11 -0800285 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
286 struct nss_n2h_empty_pool_buf *nnepbcm;
287 nnepbcm = &nnm->msg.empty_pool_buf_cfg;
288
Saurabh Misra71034db2015-06-04 16:18:38 -0700289 nss_warning("%d: core empty pool buf set failure: %d\n",
290 core_num, nnm->cm.error);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800291 nss_n2h_nepbcfgp[core_num].response = NSS_FAILURE;
292 complete(&nss_n2h_nepbcfgp[core_num].complete);
293 return;
294 }
295
Saurabh Misra71034db2015-06-04 16:18:38 -0700296 if (nnm->cm.type == NSS_TX_METADATA_TYPE_GET_PAYLOAD_INFO) {
297 nss_n2h_nepbcfgp[core_num].empty_buf_pool =
298 ntohl(nnm->msg.payload_info.pool_size);
299 nss_n2h_nepbcfgp[core_num].low_water =
300 ntohl(nnm->msg.payload_info.low_water);
301 nss_n2h_nepbcfgp[core_num].high_water =
302 ntohl(nnm->msg.payload_info.high_water);
303 }
304
Vijay Dewangan488e5372014-12-29 21:40:11 -0800305 nss_n2h_nepbcfgp[core_num].response = NSS_SUCCESS;
306 complete(&nss_n2h_nepbcfgp[core_num].complete);
307}
308
309/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700310 * nss_n2h_get_payload_info()
311 * Gets Payload information
Vijay Dewangan488e5372014-12-29 21:40:11 -0800312 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700313static int nss_n2h_get_payload_info(ctl_table *ctl, int write,
314 void __user *buffer, size_t *lenp, loff_t *ppos,
315 int core_num)
316{
317 struct nss_top_instance *nss_top = &nss_top_main;
318 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
319 struct nss_n2h_msg nnm;
320 struct nss_n2h_payload_info *nnepbcm;
321 nss_tx_status_t nss_tx_status;
322 int ret = NSS_FAILURE;
323
324 /*
325 * Note that semaphore should be already held.
326 */
327
328 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
329 NSS_TX_METADATA_TYPE_GET_PAYLOAD_INFO,
330 sizeof(struct nss_n2h_payload_info),
331 nss_n2h_payload_stats_callback,
332 (void *)core_num);
333
334 nnepbcm = &nnm.msg.payload_info;
335 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
336
337 if (nss_tx_status != NSS_TX_SUCCESS) {
338 nss_warning("%p: core %d nss_tx error errorn",
339 nss_ctx, core_num);
340 return NSS_FAILURE;
341 }
342
343 /*
344 * Blocking call, wait till we get ACK for this msg.
345 */
346 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
347 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
348 if (ret == 0) {
349 nss_warning("%p: core %d waiting for ack timed out\n", nss_ctx,
350 core_num);
351 return NSS_FAILURE;
352 }
353
354 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
355 nss_warning("%p: core %d response returned failure\n", nss_ctx,
356 core_num);
357 return NSS_FAILURE;
358 }
359
360 return NSS_SUCCESS;
361}
362
363/*
364 * nss_n2h_set_empty_pool_buf()
365 * Sets empty pool buffer
366 */
367static int nss_n2h_set_empty_pool_buf(ctl_table *ctl, int write,
368 void __user *buffer,
369 size_t *lenp, loff_t *ppos,
370 int core_num, int *new_val)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800371{
372 struct nss_top_instance *nss_top = &nss_top_main;
373 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
374 struct nss_n2h_msg nnm;
375 struct nss_n2h_empty_pool_buf *nnepbcm;
376 nss_tx_status_t nss_tx_status;
377 int ret = NSS_FAILURE;
378
379 /*
380 * Acquiring semaphore
381 */
382 down(&nss_n2h_nepbcfgp[core_num].sem);
383
384 /*
385 * Take snap shot of current value
386 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700387 nss_n2h_nepbcfgp[core_num].empty_buf_pool = *new_val;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800388
Saurabh Misra71034db2015-06-04 16:18:38 -0700389 if (!write) {
390 ret = nss_n2h_get_payload_info(ctl, write, buffer, lenp, ppos,
391 core_num);
392 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool;
393 if (ret == NSS_FAILURE) {
394 up(&nss_n2h_nepbcfgp[core_num].sem);
395 return -EBUSY;
396 }
397
398 up(&nss_n2h_nepbcfgp[core_num].sem);
399
400 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
401 return ret;
402 }
403
Vijay Dewangan488e5372014-12-29 21:40:11 -0800404 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
Saurabh Misra71034db2015-06-04 16:18:38 -0700405 if (ret) {
Vijay Dewangan488e5372014-12-29 21:40:11 -0800406 up(&nss_n2h_nepbcfgp[core_num].sem);
407 return ret;
408 }
409
Vijay Dewangan488e5372014-12-29 21:40:11 -0800410 if ((*new_val < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700411 nss_warning("%p: core %d setting %d < min number of buffer",
Vijay Dewangan488e5372014-12-29 21:40:11 -0800412 nss_ctx, core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800413 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800414 }
415
416 nss_info("%p: core %d number of empty pool buffer is : %d\n",
417 nss_ctx, core_num, *new_val);
418
419 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
420 NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG,
421 sizeof(struct nss_n2h_empty_pool_buf),
Saurabh Misra71034db2015-06-04 16:18:38 -0700422 nss_n2h_payload_stats_callback,
Vijay Dewangan488e5372014-12-29 21:40:11 -0800423 (void *)core_num);
424
425 nnepbcm = &nnm.msg.empty_pool_buf_cfg;
426 nnepbcm->pool_size = htonl(*new_val);
427 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
428
429 if (nss_tx_status != NSS_TX_SUCCESS) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700430 nss_warning("%p: core %d nss_tx error empty pool buffer: %d\n",
Vijay Dewangan488e5372014-12-29 21:40:11 -0800431 nss_ctx, core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800432 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800433 }
434
435 /*
436 * Blocking call, wait till we get ACK for this msg.
437 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700438 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
439 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
Vijay Dewangan488e5372014-12-29 21:40:11 -0800440 if (ret == 0) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700441 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
442 core_num);
Stephen Wang06761022015-03-03 16:38:42 -0800443 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800444 }
445
446 /*
447 * ACK/NACK received from NSS FW
448 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
449 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
450 */
451 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
Stephen Wang06761022015-03-03 16:38:42 -0800452 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800453 }
454
455 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700456 return 0;
Stephen Wang06761022015-03-03 16:38:42 -0800457
458failure:
459 /*
460 * Restore the current_value to its previous state
461 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700462 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool;
463 up(&nss_n2h_nepbcfgp[core_num].sem);
464 return NSS_FAILURE;
465}
466
467/*
468 * nss_n2h_set_water_mark()
469 * Sets water mark for N2H SOS
470 */
471static int nss_n2h_set_water_mark(ctl_table *ctl, int write,
472 void __user *buffer,
473 size_t *lenp, loff_t *ppos,
474 int core_num, int *low, int *high)
475{
476 struct nss_top_instance *nss_top = &nss_top_main;
477 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
478 struct nss_n2h_msg nnm;
479 struct nss_n2h_water_mark *wm;
480 nss_tx_status_t nss_tx_status;
481 int ret = NSS_FAILURE;
482
483 /*
484 * Acquiring semaphore
485 */
486 down(&nss_n2h_nepbcfgp[core_num].sem);
487
488 /*
489 * Take snap shot of current value
490 */
491 nss_n2h_nepbcfgp[core_num].low_water = *low;
492 nss_n2h_nepbcfgp[core_num].high_water = *high;
493
494 if (!write) {
495 ret = nss_n2h_get_payload_info(ctl, write, buffer, lenp, ppos,
496 core_num);
497 *low = nss_n2h_nepbcfgp[core_num].low_water;
498 *high = nss_n2h_nepbcfgp[core_num].high_water;
499
500 if (ret == NSS_FAILURE) {
501 up(&nss_n2h_nepbcfgp[core_num].sem);
502 return -EBUSY;
503 }
504
505 up(&nss_n2h_nepbcfgp[core_num].sem);
506 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
507 return ret;
508 }
509
510 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
511 if (ret) {
512 up(&nss_n2h_nepbcfgp[core_num].sem);
513 return ret;
514 }
515
516 /*
517 * If either low or high water mark is not set then we do
518 * nothing.
519 */
520 if (*low == -1 || *high == -1)
521 goto failure;
522
523 if ((*low < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) ||
524 (*high < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
525 nss_warning("%p: core %d setting %d, %d < min number of buffer",
526 nss_ctx, core_num, *low, *high);
527 goto failure;
528 }
529
Radha krishna Simha Jigurue5ebd772015-08-27 20:55:09 +0530530 if ((*low > (NSS_N2H_DEFAULT_EMPTY_POOL_BUF_SZ * 5)) ||
531 (*high > (NSS_N2H_DEFAULT_EMPTY_POOL_BUF_SZ * 5))) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700532 nss_warning("%p: core %d setting %d, %d is > upper limit",
533 nss_ctx, core_num, *low, *high);
534 goto failure;
535 }
536
537 if (*low > *high) {
538 nss_warning("%p: core %d setting low %d is more than high %d",
539 nss_ctx, core_num, *low, *high);
540 goto failure;
541 }
542
543 nss_info("%p: core %d number of low : %d and high : %d\n",
544 nss_ctx, core_num, *low, *high);
545
546 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
547 NSS_TX_METADATA_TYPE_SET_WATER_MARK,
548 sizeof(struct nss_n2h_water_mark),
549 nss_n2h_payload_stats_callback,
550 (void *)core_num);
551
552 wm = &nnm.msg.wm;
553 wm->low_water = htonl(*low);
554 wm->high_water = htonl(*high);
555 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
556
557 if (nss_tx_status != NSS_TX_SUCCESS) {
558 nss_warning("%p: core %d nss_tx error setting : %d, %d\n",
559 nss_ctx, core_num, *low, *high);
560 goto failure;
561 }
562
563 /*
564 * Blocking call, wait till we get ACK for this msg.
565 */
566 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
567 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
568 if (ret == 0) {
569 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
570 core_num);
571 goto failure;
572 }
573
574 /*
575 * ACK/NACK received from NSS FW
576 */
577 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response)
578 goto failure;
579
580 up(&nss_n2h_nepbcfgp[core_num].sem);
581 return NSS_SUCCESS;
582
583failure:
584 /*
585 * Restore the current_value to its previous state
586 */
587 *low = nss_n2h_nepbcfgp[core_num].low_water;
588 *high = nss_n2h_nepbcfgp[core_num].high_water;
Stephen Wang06761022015-03-03 16:38:42 -0800589 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700590 return -EINVAL;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800591}
592
593/*
Radha krishna Simha Jiguru7f424d52015-02-10 19:41:01 +0530594 * nss_n2h_flush_payloads()
595 * Sends a command down to NSS for flushing all payloads
596 */
597nss_tx_status_t nss_n2h_flush_payloads(struct nss_ctx_instance *nss_ctx)
598{
599 struct nss_n2h_msg nnm;
600 struct nss_n2h_flush_payloads *nnflshpl;
601 nss_tx_status_t nss_tx_status;
602
603 nnflshpl = &nnm.msg.flush_payloads;
604
605 /*
606 * TODO: No additional information sent in message
607 * as of now. Need to initialize message content accordingly
608 * if needed.
609 */
610 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
611 NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS,
612 sizeof(struct nss_n2h_flush_payloads),
613 NULL,
614 NULL);
615
616 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
617 if (nss_tx_status != NSS_TX_SUCCESS) {
618 nss_warning("%p: failed to send flush payloads command to NSS\n",
619 nss_ctx);
620
621 return NSS_TX_FAILURE;
622 }
623
624 return NSS_TX_SUCCESS;
625}
626
627/*
Vijay Dewangan488e5372014-12-29 21:40:11 -0800628 * nss_n2h_empty_pool_buf_core1_handler()
629 * Sets the number of empty buffer for core 1
630 */
631static int nss_n2h_empty_pool_buf_cfg_core1_handler(ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700632 int write, void __user *buffer,
633 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800634{
635 return nss_n2h_set_empty_pool_buf(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700636 NSS_CORE_1, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800637}
638
639/*
640 * nss_n2h_empty_pool_buf_core0_handler()
641 * Sets the number of empty buffer for core 0
642 */
643static int nss_n2h_empty_pool_buf_cfg_core0_handler(ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700644 int write, void __user *buffer,
645 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800646{
647 return nss_n2h_set_empty_pool_buf(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700648 NSS_CORE_0, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0]);
649}
650
651/*
652 * nss_n2h_water_mark_core1_handler()
653 * Sets water mark for core 1
654 */
655static int nss_n2h_water_mark_core1_handler(ctl_table *ctl,
656 int write, void __user *buffer,
657 size_t *lenp, loff_t *ppos)
658{
659 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
660 NSS_CORE_1, &nss_n2h_water_mark[NSS_CORE_1][0],
661 &nss_n2h_water_mark[NSS_CORE_1][1]);
662}
663
664/*
665 * nss_n2h_water_mark_core0_handler()
666 * Sets water mark for core 0
667 */
668static int nss_n2h_water_mark_core0_handler(ctl_table *ctl,
669 int write, void __user *buffer,
670 size_t *lenp, loff_t *ppos)
671{
672 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
673 NSS_CORE_0, &nss_n2h_water_mark[NSS_CORE_0][0],
674 &nss_n2h_water_mark[NSS_CORE_0][1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800675}
676
Vijay Dewangan634ce592015-01-07 17:21:09 -0800677/*
678 * nss_n2h_rps_cfg()
679 * Send Message to NSS to enable RPS.
680 */
681nss_tx_status_t nss_n2h_rps_cfg(struct nss_ctx_instance *nss_ctx, int enable_rps)
682{
683 struct nss_n2h_msg nnm;
684 struct nss_n2h_rps *rps_cfg;
685 nss_tx_status_t nss_tx_status;
686 int ret;
687
688 down(&nss_n2h_rcp.sem);
689 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_RPS_CFG,
690 sizeof(struct nss_n2h_rps),
691 nss_n2h_rps_cfg_callback,
692 (void *)nss_ctx);
693
694 rps_cfg = &nnm.msg.rps_cfg;
695 rps_cfg->enable = enable_rps;
696
697 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
698
699 if (nss_tx_status != NSS_TX_SUCCESS) {
700 nss_warning("%p: nss_tx error setting rps\n", nss_ctx);
701
702 up(&nss_n2h_rcp.sem);
703 return NSS_FAILURE;
704 }
705
706 /*
707 * Blocking call, wait till we get ACK for this msg.
708 */
709 ret = wait_for_completion_timeout(&nss_n2h_rcp.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
710 if (ret == 0) {
711 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
712 up(&nss_n2h_rcp.sem);
713 return NSS_FAILURE;
714 }
715
716 /*
717 * ACK/NACK received from NSS FW
718 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
719 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
720 */
721 if (NSS_FAILURE == nss_n2h_rcp.response) {
722 up(&nss_n2h_rcp.sem);
723 return NSS_FAILURE;
724 }
725
726 up(&nss_n2h_rcp.sem);
727 return NSS_SUCCESS;
728}
729
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530730/*
731 * nss_n2h_mitigation_cfg()
732 * Send Message to NSS to disable MITIGATION.
733 */
734nss_tx_status_t nss_n2h_mitigation_cfg(struct nss_ctx_instance *nss_ctx, int enable_mitigation, nss_core_id_t core_num)
735{
736 struct nss_n2h_msg nnm;
737 struct nss_n2h_mitigation *mitigation_cfg;
738 nss_tx_status_t nss_tx_status;
739 int ret;
740
741 nss_assert(core_num < NSS_CORE_MAX);
742
743 down(&nss_n2h_mitigationcp[core_num].sem);
744 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG,
745 sizeof(struct nss_n2h_mitigation),
746 nss_n2h_mitigation_cfg_callback,
747 (void *)core_num);
748
749 mitigation_cfg = &nnm.msg.mitigation_cfg;
750 mitigation_cfg->enable = enable_mitigation;
751
752 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
753
754 if (nss_tx_status != NSS_TX_SUCCESS) {
755 nss_warning("%p: nss_tx error setting mitigation\n", nss_ctx);
756 goto failure;
757 }
758
759 /*
760 * Blocking call, wait till we get ACK for this msg.
761 */
762 ret = wait_for_completion_timeout(&nss_n2h_mitigationcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
763 if (ret == 0) {
764 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
765 goto failure;
766 }
767
768 /*
769 * ACK/NACK received from NSS FW
770 */
771 if (NSS_FAILURE == nss_n2h_mitigationcp[core_num].response) {
772 goto failure;
773 }
774
775 up(&nss_n2h_mitigationcp[core_num].sem);
776 return NSS_SUCCESS;
777
778failure:
779 up(&nss_n2h_mitigationcp[core_num].sem);
780 return NSS_FAILURE;
781}
782
783static inline void nss_n2h_buf_pool_free(struct nss_n2h_buf_pool *buf_pool)
784{
785 int page_count;
786 for (page_count = 0; page_count < buf_pool->nss_buf_num_pages; page_count++) {
787 kfree(buf_pool->nss_buf_pool_vaddr[page_count]);
788 }
789}
790
791/*
792 * nss_n2h_buf_cfg()
793 * Send Message to NSS to enable pbufs.
794 */
795nss_tx_status_t nss_n2h_buf_pool_cfg(struct nss_ctx_instance *nss_ctx,
796 int buf_pool_size, nss_core_id_t core_num)
797{
798 static struct nss_n2h_msg nnm;
799 struct nss_n2h_buf_pool *buf_pool;
800 nss_tx_status_t nss_tx_status;
801 int ret;
802 int page_count;
803 int num_pages = ALIGN(buf_pool_size, PAGE_SIZE)/PAGE_SIZE;
804
805 nss_assert(core_num < NSS_CORE_MAX);
806
807 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_METADATA_TYPE_N2H_ADD_BUF_POOL,
808 sizeof(struct nss_n2h_buf_pool),
809 nss_n2h_bufs_cfg_callback,
810 (void *)core_num);
811
812 do {
813
814 down(&nss_n2h_bufcp[core_num].sem);
815
816 buf_pool = &nnm.msg.buf_pool;
817 buf_pool->nss_buf_page_size = PAGE_SIZE;
818
819 for (page_count = 0; page_count < MAX_PAGES_PER_MSG && num_pages; page_count++, num_pages--) {
820
821 void *kern_addr = kzalloc(PAGE_SIZE, GFP_ATOMIC);
822 if (!kern_addr) {
823 BUG_ON(!page_count);
824 break;
825 }
826 BUG_ON((long unsigned int)kern_addr % PAGE_SIZE);
827
828 buf_pool->nss_buf_pool_vaddr[page_count] = kern_addr;
829 buf_pool->nss_buf_pool_addr[page_count] = dma_map_single(NULL, kern_addr, PAGE_SIZE, DMA_TO_DEVICE);
830 }
831
832 buf_pool->nss_buf_num_pages = page_count;
833 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
834 if (nss_tx_status != NSS_TX_SUCCESS) {
835
836 nss_n2h_buf_pool_free(buf_pool);
837 nss_warning("%p: nss_tx error setting pbuf\n", nss_ctx);
838 goto failure;
839 }
840
841 /*
842 * Blocking call, wait till we get ACK for this msg.
843 */
844 ret = wait_for_completion_timeout(&nss_n2h_bufcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
845 if (ret == 0) {
846 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
847 goto failure;
848 }
849
850 /*
851 * ACK/NACK received from NSS FW
852 */
853 if (NSS_FAILURE == nss_n2h_bufcp[core_num].response) {
854
855 nss_n2h_buf_pool_free(buf_pool);
856 goto failure;
857 }
858
859 up(&nss_n2h_bufcp[core_num].sem);
860 } while(num_pages);
861
862 return NSS_SUCCESS;
863failure:
864 up(&nss_n2h_bufcp[core_num].sem);
865 return NSS_FAILURE;
866}
867
868
869
Vijay Dewangan488e5372014-12-29 21:40:11 -0800870static ctl_table nss_n2h_table[] = {
871 {
Saurabh Misra71034db2015-06-04 16:18:38 -0700872 .procname = "n2h_empty_pool_buf_core0",
873 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0],
874 .maxlen = sizeof(int),
875 .mode = 0644,
876 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core0_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -0800877 },
878 {
Saurabh Misra71034db2015-06-04 16:18:38 -0700879 .procname = "n2h_empty_pool_buf_core1",
880 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1],
881 .maxlen = sizeof(int),
882 .mode = 0644,
883 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core1_handler,
884 },
885 {
886 .procname = "n2h_low_water_core0",
887 .data = &nss_n2h_water_mark[NSS_CORE_0][0],
888 .maxlen = sizeof(int),
889 .mode = 0644,
890 .proc_handler = &nss_n2h_water_mark_core0_handler,
891 },
892 {
893 .procname = "n2h_low_water_core1",
894 .data = &nss_n2h_water_mark[NSS_CORE_1][0],
895 .maxlen = sizeof(int),
896 .mode = 0644,
897 .proc_handler = &nss_n2h_water_mark_core1_handler,
898 },
899 {
900 .procname = "n2h_high_water_core0",
901 .data = &nss_n2h_water_mark[NSS_CORE_0][1],
902 .maxlen = sizeof(int),
903 .mode = 0644,
904 .proc_handler = &nss_n2h_water_mark_core0_handler,
905 },
906 {
907 .procname = "n2h_high_water_core1",
908 .data = &nss_n2h_water_mark[NSS_CORE_1][1],
909 .maxlen = sizeof(int),
910 .mode = 0644,
911 .proc_handler = &nss_n2h_water_mark_core1_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -0800912 },
913
914 { }
915};
916
917static ctl_table nss_n2h_dir[] = {
918 {
919 .procname = "n2hcfg",
920 .mode = 0555,
921 .child = nss_n2h_table,
922 },
923 { }
924};
925
926
927static ctl_table nss_n2h_root_dir[] = {
928 {
929 .procname = "nss",
930 .mode = 0555,
931 .child = nss_n2h_dir,
932 },
933 { }
934};
935
936static ctl_table nss_n2h_root[] = {
937 {
938 .procname = "dev",
939 .mode = 0555,
940 .child = nss_n2h_root_dir,
941 },
942 { }
943};
944
945static struct ctl_table_header *nss_n2h_header;
946
947/*
948 * nss_n2h_msg_init()
949 * Initialize IPv4 message.
950 */
951void nss_n2h_msg_init(struct nss_n2h_msg *nim, uint16_t if_num, uint32_t type,
Vijay Dewangan634ce592015-01-07 17:21:09 -0800952 uint32_t len, nss_n2h_msg_callback_t cb, void *app_data)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800953{
954 nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data);
955}
956
Vijay Dewangan488e5372014-12-29 21:40:11 -0800957/*
958 * nss_n2h_register_sysctl()
959 * Register sysctl specific to n2h
960 */
961void nss_n2h_empty_pool_buf_register_sysctl(void)
962{
963 /*
964 * Register sysctl table.
965 */
966 nss_n2h_header = register_sysctl_table(nss_n2h_root);
967
968 /*
969 * Core0
970 */
971 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_0].sem, 1);
972 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_0].complete);
Saurabh Misra71034db2015-06-04 16:18:38 -0700973 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool =
974 nss_n2h_empty_pool_buf_cfg[NSS_CORE_0];
975 nss_n2h_nepbcfgp[NSS_CORE_0].low_water =
976 nss_n2h_water_mark[NSS_CORE_0][0];
977 nss_n2h_nepbcfgp[NSS_CORE_0].high_water =
978 nss_n2h_water_mark[NSS_CORE_0][1];
Vijay Dewangan488e5372014-12-29 21:40:11 -0800979
980 /*
981 * Core1
982 */
983 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_1].sem, 1);
984 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_1].complete);
Saurabh Misra71034db2015-06-04 16:18:38 -0700985 nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool =
986 nss_n2h_empty_pool_buf_cfg[NSS_CORE_1];
987 nss_n2h_nepbcfgp[NSS_CORE_1].low_water =
988 nss_n2h_water_mark[NSS_CORE_1][0];
989 nss_n2h_nepbcfgp[NSS_CORE_1].high_water =
990 nss_n2h_water_mark[NSS_CORE_1][1];
Vijay Dewangan488e5372014-12-29 21:40:11 -0800991}
992
993/*
994 * nss_n2h_unregister_sysctl()
995 * Unregister sysctl specific to n2h
996 */
997void nss_n2h_empty_pool_buf_unregister_sysctl(void)
998{
999 /*
1000 * Unregister sysctl table.
1001 */
1002 if (nss_n2h_header) {
1003 unregister_sysctl_table(nss_n2h_header);
1004 }
1005}
1006
1007/*
1008 * nss_n2h_tx_msg()
1009 * Send messages to NSS n2h pacakge
1010 */
1011nss_tx_status_t nss_n2h_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_n2h_msg *nnm)
1012{
1013 struct nss_n2h_msg *nnm2;
1014 struct nss_cmn_msg *ncm = &nnm->cm;
1015 struct sk_buff *nbuf;
1016 nss_tx_status_t status;
1017
1018 NSS_VERIFY_CTX_MAGIC(nss_ctx);
1019 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
1020 return NSS_TX_FAILURE_NOT_READY;
1021 }
1022
1023 /*
1024 * Sanity check the message
1025 */
1026 if (ncm->interface != NSS_N2H_INTERFACE) {
1027 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
1028 return NSS_TX_FAILURE;
1029 }
1030
1031 if (ncm->type >= NSS_METADATA_TYPE_N2H_MAX) {
1032 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
1033 return NSS_TX_FAILURE;
1034 }
1035
1036 if (ncm->len > sizeof(struct nss_n2h_msg)) {
1037 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
1038 return NSS_TX_FAILURE;
1039 }
1040
1041
1042 nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
1043 if (unlikely(!nbuf)) {
Sundarajan Srinivasan62fee7e2015-01-22 11:13:10 -08001044 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 -08001045 return NSS_TX_FAILURE;
1046 }
1047
1048 /*
1049 * Copy the message to our skb.
1050 */
1051 nnm2 = (struct nss_n2h_msg *)skb_put(nbuf, sizeof(struct nss_n2h_msg));
1052 memcpy(nnm2, nnm, sizeof(struct nss_n2h_msg));
1053 status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
1054 if (status != NSS_CORE_STATUS_SUCCESS) {
1055 dev_kfree_skb_any(nbuf);
1056 nss_info("%p: unable to enqueue 'nss frequency change' - marked as stopped\n", nss_ctx);
1057 return NSS_TX_FAILURE;
1058 }
1059
1060 nss_hal_send_interrupt(nss_ctx->nmap,
1061 nss_ctx->h2n_desc_rings[NSS_IF_CMD_QUEUE].desc_ring.int_bit,
1062 NSS_REGS_H2N_INTR_STATUS_DATA_COMMAND_QUEUE);
1063 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
1064 return NSS_TX_SUCCESS;
1065}
1066
Vijay Dewangan488e5372014-12-29 21:40:11 -08001067/*
1068 * nss_n2h_notify_register()
1069 * Register to received N2H events.
1070 *
1071 * NOTE: Do we want to pass an nss_ctx here so that we can register for n2h on any core?
1072 */
1073struct nss_ctx_instance *nss_n2h_notify_register(int core, nss_n2h_msg_callback_t cb, void *app_data)
1074{
1075 if (core >= NSS_MAX_CORES) {
1076 nss_warning("Input core number %d is wrong \n", core);
1077 return NULL;
1078 }
1079 /*
1080 * TODO: We need to have a new array in support of the new API
1081 * TODO: If we use a per-context array, we would move the array into nss_ctx based.
1082 */
1083 nss_n2h_rd[core].n2h_callback = cb;
1084 nss_n2h_rd[core].app_data = app_data;
1085 return &nss_top_main.nss[core];
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301086}
1087
1088/*
1089 * nss_n2h_register_handler()
1090 */
1091void nss_n2h_register_handler()
1092{
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -07001093 nss_core_register_handler(NSS_N2H_INTERFACE, nss_n2h_interface_handler, NULL);
1094
Vijay Dewangan634ce592015-01-07 17:21:09 -08001095 /*
1096 * RPS sema init
1097 */
1098 sema_init(&nss_n2h_rcp.sem, 1);
1099 init_completion(&nss_n2h_rcp.complete);
1100
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301101 /*
1102 * MITIGATION sema init for core0
1103 */
1104 sema_init(&nss_n2h_mitigationcp[NSS_CORE_0].sem, 1);
1105 init_completion(&nss_n2h_mitigationcp[NSS_CORE_0].complete);
1106
1107 /*
1108 * MITIGATION sema init for core1
1109 */
1110 sema_init(&nss_n2h_mitigationcp[NSS_CORE_1].sem, 1);
1111 init_completion(&nss_n2h_mitigationcp[NSS_CORE_1].complete);
1112
1113 /*
1114 * PBUF addition sema init for core0
1115 */
1116 sema_init(&nss_n2h_bufcp[NSS_CORE_0].sem, 1);
1117 init_completion(&nss_n2h_bufcp[NSS_CORE_0].complete);
1118
1119 /*
1120 * PBUF addition sema init for core1
1121 */
1122 sema_init(&nss_n2h_bufcp[NSS_CORE_1].sem, 1);
1123 init_completion(&nss_n2h_bufcp[NSS_CORE_1].complete);
Vijay Dewangan634ce592015-01-07 17:21:09 -08001124
Vijay Dewangan488e5372014-12-29 21:40:11 -08001125 nss_n2h_notify_register(NSS_CORE_0, NULL, NULL);
1126 nss_n2h_notify_register(NSS_CORE_1, NULL, NULL);
1127
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301128}
Vijay Dewangan488e5372014-12-29 21:40:11 -08001129
1130EXPORT_SYMBOL(nss_n2h_notify_register);
Vijay Dewanganac7efc42015-02-09 16:04:53 -08001131EXPORT_SYMBOL(nss_n2h_empty_pool_buf_register_sysctl);