blob: 486a41bc02d5fceec84dfeff363e1d7410796dc0 [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
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530108 spin_unlock_bh(&nss_top->stats_lock);
109}
110
111/*
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -0700112 * nss_n2h_interface_handler()
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530113 * Handle NSS -> HLOS messages for N2H node
114 */
Vijay Dewangan634ce592015-01-07 17:21:09 -0800115static void nss_n2h_interface_handler(struct nss_ctx_instance *nss_ctx,
116 struct nss_cmn_msg *ncm,
117 __attribute__((unused))void *app_data)
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530118{
119 struct nss_n2h_msg *nnm = (struct nss_n2h_msg *)ncm;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800120 nss_n2h_msg_callback_t cb;
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530121
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -0700122 BUG_ON(ncm->interface != NSS_N2H_INTERFACE);
123
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530124 /*
125 * Is this a valid request/response packet?
126 */
127 if (nnm->cm.type >= NSS_METADATA_TYPE_N2H_MAX) {
128 nss_warning("%p: received invalid message %d for Offload stats interface", nss_ctx, nnm->cm.type);
129 return;
130 }
131
132 switch (nnm->cm.type) {
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530133 case NSS_TX_METADATA_TYPE_N2H_RPS_CFG:
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530134 nss_info("NSS N2H rps_en %d \n",nnm->msg.rps_cfg.enable);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800135 break;
136
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530137 case NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG:
138 nss_info("NSS N2H mitigation_dis %d \n",nnm->msg.mitigation_cfg.enable);
139 break;
140
Vijay Dewangan488e5372014-12-29 21:40:11 -0800141 case NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG:
142 nss_info("%p: empty pool buf cfg response from FW", nss_ctx);
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530143 break;
144
Radha krishna Simha Jiguru7f424d52015-02-10 19:41:01 +0530145 case NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS:
146 nss_info("%p: flush payloads cmd response from FW", nss_ctx);
147 break;
148
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530149 case NSS_RX_METADATA_TYPE_N2H_STATS_SYNC:
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -0700150 nss_n2h_stats_sync(nss_ctx, &nnm->msg.stats_sync);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530151 break;
152
153 default:
154 if (ncm->response != NSS_CMN_RESPONSE_ACK) {
155 /*
156 * Check response
157 */
158 nss_info("%p: Received response %d for type %d, interface %d",
159 nss_ctx, ncm->response, ncm->type, ncm->interface);
160 }
161 }
Vijay Dewangan488e5372014-12-29 21:40:11 -0800162
163 /*
164 * Update the callback and app_data for NOTIFY messages, IPv4 sends all notify messages
165 * to the same callback/app_data.
166 */
167 if (nnm->cm.response == NSS_CMM_RESPONSE_NOTIFY) {
168 /*
169 * Place holder for the user to create right call
170 * back and app data when response is NSS_CMM_RESPONSE_NOTIFY
171 */
172 ncm->cb = (uint32_t)nss_n2h_rd[nss_ctx->id].n2h_callback;
173 ncm->app_data = (uint32_t)nss_n2h_rd[nss_ctx->id].app_data;
174 }
175
176 /*
177 * Do we have a callback?
178 */
179 if (!ncm->cb) {
180 return;
181 }
182
183 /*
184 * Callback
185 */
186 cb = (nss_n2h_msg_callback_t)ncm->cb;
187 cb((void *)ncm->app_data, nnm);
188}
189
190/*
Vijay Dewangan634ce592015-01-07 17:21:09 -0800191 * nss_n2h_rps_cfg_callback()
192 * call back function for rps configuration
193 */
194static void nss_n2h_rps_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
195{
196 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)app_data;
197 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
198
199 /*
200 * Error, hence we are not updating the nss_n2h_empty_pool_buf
201 * Restore the current_value to its previous state
202 */
203 nss_n2h_rcp.response = NSS_FAILURE;
204 complete(&nss_n2h_rcp.complete);
205 nss_warning("%p: RPS configuration failed : %d\n", nss_ctx,
206 nnm->cm.error);
207 return;
208 }
209
210 nss_info("%p: RPS configuration succeeded: %d\n", nss_ctx,
211 nnm->cm.error);
212 nss_ctx->n2h_rps_en = nnm->msg.rps_cfg.enable;
213 nss_n2h_rcp.response = NSS_SUCCESS;
214 complete(&nss_n2h_rcp.complete);
215}
216
217/*
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530218 * nss_n2h_mitigation_cfg_callback()
219 * call back function for mitigation configuration
220 */
221static void nss_n2h_mitigation_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
222{
223 int core_num = (int)app_data;
224 struct nss_top_instance *nss_top = &nss_top_main;
225 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
226
227 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
228
229 /*
230 * Error, hence we are not updating the nss_n2h_mitigate_en
231 */
232 nss_n2h_mitigationcp[core_num].response = NSS_FAILURE;
233 complete(&nss_n2h_mitigationcp[core_num].complete);
234 nss_warning("core%d: MITIGATION configuration failed : %d\n", core_num, nnm->cm.error);
235 return;
236 }
237
238 nss_info("core%d: MITIGATION configuration succeeded: %d\n", core_num, nnm->cm.error);
239
240 nss_ctx->n2h_mitigate_en = nnm->msg.mitigation_cfg.enable;
241 nss_n2h_mitigationcp[core_num].response = NSS_SUCCESS;
242 complete(&nss_n2h_mitigationcp[core_num].complete);
243}
244
245/*
246 * nss_n2h_buf_cfg_callback()
247 * call back function for pbuf configuration
248 */
249static void nss_n2h_bufs_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
250{
251 int core_num = (int)app_data;
252 unsigned int allocated_sz;
253
254 struct nss_top_instance *nss_top = &nss_top_main;
255 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
256
257 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
258 nss_n2h_bufcp[core_num].response = NSS_FAILURE;
259 nss_warning("core%d: buf configuration failed : %d\n", core_num, nnm->cm.error);
260 goto done;
261 }
262
263 nss_info("core%d: buf configuration succeeded: %d\n", core_num, nnm->cm.error);
264
265 allocated_sz = nnm->msg.buf_pool.nss_buf_page_size * nnm->msg.buf_pool.nss_buf_num_pages;
266 nss_ctx->buf_sz_allocated += allocated_sz;
267
268 nss_n2h_bufcp[core_num].response = NSS_SUCCESS;
269
270done:
271 complete(&nss_n2h_bufcp[core_num].complete);
272}
273
274/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700275 * nss_n2h_payload_stats_callback()
276 * It gets called response to payload accounting.
Vijay Dewangan488e5372014-12-29 21:40:11 -0800277 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700278static void nss_n2h_payload_stats_callback(void *app_data,
279 struct nss_n2h_msg *nnm)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800280{
281 int core_num = (int)app_data;
Saurabh Misra71034db2015-06-04 16:18:38 -0700282
Vijay Dewangan488e5372014-12-29 21:40:11 -0800283 if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
284 struct nss_n2h_empty_pool_buf *nnepbcm;
285 nnepbcm = &nnm->msg.empty_pool_buf_cfg;
286
Saurabh Misra71034db2015-06-04 16:18:38 -0700287 nss_warning("%d: core empty pool buf set failure: %d\n",
288 core_num, nnm->cm.error);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800289 nss_n2h_nepbcfgp[core_num].response = NSS_FAILURE;
290 complete(&nss_n2h_nepbcfgp[core_num].complete);
291 return;
292 }
293
Saurabh Misra71034db2015-06-04 16:18:38 -0700294 if (nnm->cm.type == NSS_TX_METADATA_TYPE_GET_PAYLOAD_INFO) {
295 nss_n2h_nepbcfgp[core_num].empty_buf_pool =
296 ntohl(nnm->msg.payload_info.pool_size);
297 nss_n2h_nepbcfgp[core_num].low_water =
298 ntohl(nnm->msg.payload_info.low_water);
299 nss_n2h_nepbcfgp[core_num].high_water =
300 ntohl(nnm->msg.payload_info.high_water);
301 }
302
Vijay Dewangan488e5372014-12-29 21:40:11 -0800303 nss_n2h_nepbcfgp[core_num].response = NSS_SUCCESS;
304 complete(&nss_n2h_nepbcfgp[core_num].complete);
305}
306
307/*
Saurabh Misra71034db2015-06-04 16:18:38 -0700308 * nss_n2h_get_payload_info()
309 * Gets Payload information
Vijay Dewangan488e5372014-12-29 21:40:11 -0800310 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700311static int nss_n2h_get_payload_info(ctl_table *ctl, int write,
312 void __user *buffer, size_t *lenp, loff_t *ppos,
313 int core_num)
314{
315 struct nss_top_instance *nss_top = &nss_top_main;
316 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
317 struct nss_n2h_msg nnm;
318 struct nss_n2h_payload_info *nnepbcm;
319 nss_tx_status_t nss_tx_status;
320 int ret = NSS_FAILURE;
321
322 /*
323 * Note that semaphore should be already held.
324 */
325
326 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
327 NSS_TX_METADATA_TYPE_GET_PAYLOAD_INFO,
328 sizeof(struct nss_n2h_payload_info),
329 nss_n2h_payload_stats_callback,
330 (void *)core_num);
331
332 nnepbcm = &nnm.msg.payload_info;
333 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
334
335 if (nss_tx_status != NSS_TX_SUCCESS) {
336 nss_warning("%p: core %d nss_tx error errorn",
337 nss_ctx, core_num);
338 return NSS_FAILURE;
339 }
340
341 /*
342 * Blocking call, wait till we get ACK for this msg.
343 */
344 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
345 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
346 if (ret == 0) {
347 nss_warning("%p: core %d waiting for ack timed out\n", nss_ctx,
348 core_num);
349 return NSS_FAILURE;
350 }
351
352 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
353 nss_warning("%p: core %d response returned failure\n", nss_ctx,
354 core_num);
355 return NSS_FAILURE;
356 }
357
358 return NSS_SUCCESS;
359}
360
361/*
362 * nss_n2h_set_empty_pool_buf()
363 * Sets empty pool buffer
364 */
365static int nss_n2h_set_empty_pool_buf(ctl_table *ctl, int write,
366 void __user *buffer,
367 size_t *lenp, loff_t *ppos,
368 int core_num, int *new_val)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800369{
370 struct nss_top_instance *nss_top = &nss_top_main;
371 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
372 struct nss_n2h_msg nnm;
373 struct nss_n2h_empty_pool_buf *nnepbcm;
374 nss_tx_status_t nss_tx_status;
375 int ret = NSS_FAILURE;
376
377 /*
378 * Acquiring semaphore
379 */
380 down(&nss_n2h_nepbcfgp[core_num].sem);
381
382 /*
383 * Take snap shot of current value
384 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700385 nss_n2h_nepbcfgp[core_num].empty_buf_pool = *new_val;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800386
Saurabh Misra71034db2015-06-04 16:18:38 -0700387 if (!write) {
388 ret = nss_n2h_get_payload_info(ctl, write, buffer, lenp, ppos,
389 core_num);
390 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool;
391 if (ret == NSS_FAILURE) {
392 up(&nss_n2h_nepbcfgp[core_num].sem);
393 return -EBUSY;
394 }
395
396 up(&nss_n2h_nepbcfgp[core_num].sem);
397
398 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
399 return ret;
400 }
401
Vijay Dewangan488e5372014-12-29 21:40:11 -0800402 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
Saurabh Misra71034db2015-06-04 16:18:38 -0700403 if (ret) {
Vijay Dewangan488e5372014-12-29 21:40:11 -0800404 up(&nss_n2h_nepbcfgp[core_num].sem);
405 return ret;
406 }
407
Vijay Dewangan488e5372014-12-29 21:40:11 -0800408 if ((*new_val < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700409 nss_warning("%p: core %d setting %d < min number of buffer",
Vijay Dewangan488e5372014-12-29 21:40:11 -0800410 nss_ctx, core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800411 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800412 }
413
414 nss_info("%p: core %d number of empty pool buffer is : %d\n",
415 nss_ctx, core_num, *new_val);
416
417 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
418 NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG,
419 sizeof(struct nss_n2h_empty_pool_buf),
Saurabh Misra71034db2015-06-04 16:18:38 -0700420 nss_n2h_payload_stats_callback,
Vijay Dewangan488e5372014-12-29 21:40:11 -0800421 (void *)core_num);
422
423 nnepbcm = &nnm.msg.empty_pool_buf_cfg;
424 nnepbcm->pool_size = htonl(*new_val);
425 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
426
427 if (nss_tx_status != NSS_TX_SUCCESS) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700428 nss_warning("%p: core %d nss_tx error empty pool buffer: %d\n",
Vijay Dewangan488e5372014-12-29 21:40:11 -0800429 nss_ctx, core_num, *new_val);
Stephen Wang06761022015-03-03 16:38:42 -0800430 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800431 }
432
433 /*
434 * Blocking call, wait till we get ACK for this msg.
435 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700436 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
437 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
Vijay Dewangan488e5372014-12-29 21:40:11 -0800438 if (ret == 0) {
Saurabh Misra71034db2015-06-04 16:18:38 -0700439 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
440 core_num);
Stephen Wang06761022015-03-03 16:38:42 -0800441 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800442 }
443
444 /*
445 * ACK/NACK received from NSS FW
446 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
447 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
448 */
449 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
Stephen Wang06761022015-03-03 16:38:42 -0800450 goto failure;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800451 }
452
453 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700454 return 0;
Stephen Wang06761022015-03-03 16:38:42 -0800455
456failure:
457 /*
458 * Restore the current_value to its previous state
459 */
Saurabh Misra71034db2015-06-04 16:18:38 -0700460 *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool;
461 up(&nss_n2h_nepbcfgp[core_num].sem);
462 return NSS_FAILURE;
463}
464
465/*
466 * nss_n2h_set_water_mark()
467 * Sets water mark for N2H SOS
468 */
469static int nss_n2h_set_water_mark(ctl_table *ctl, int write,
470 void __user *buffer,
471 size_t *lenp, loff_t *ppos,
472 int core_num, int *low, int *high)
473{
474 struct nss_top_instance *nss_top = &nss_top_main;
475 struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
476 struct nss_n2h_msg nnm;
477 struct nss_n2h_water_mark *wm;
478 nss_tx_status_t nss_tx_status;
479 int ret = NSS_FAILURE;
480
481 /*
482 * Acquiring semaphore
483 */
484 down(&nss_n2h_nepbcfgp[core_num].sem);
485
486 /*
487 * Take snap shot of current value
488 */
489 nss_n2h_nepbcfgp[core_num].low_water = *low;
490 nss_n2h_nepbcfgp[core_num].high_water = *high;
491
492 if (!write) {
493 ret = nss_n2h_get_payload_info(ctl, write, buffer, lenp, ppos,
494 core_num);
495 *low = nss_n2h_nepbcfgp[core_num].low_water;
496 *high = nss_n2h_nepbcfgp[core_num].high_water;
497
498 if (ret == NSS_FAILURE) {
499 up(&nss_n2h_nepbcfgp[core_num].sem);
500 return -EBUSY;
501 }
502
503 up(&nss_n2h_nepbcfgp[core_num].sem);
504 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
505 return ret;
506 }
507
508 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
509 if (ret) {
510 up(&nss_n2h_nepbcfgp[core_num].sem);
511 return ret;
512 }
513
514 /*
515 * If either low or high water mark is not set then we do
516 * nothing.
517 */
518 if (*low == -1 || *high == -1)
519 goto failure;
520
521 if ((*low < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) ||
522 (*high < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
523 nss_warning("%p: core %d setting %d, %d < min number of buffer",
524 nss_ctx, core_num, *low, *high);
525 goto failure;
526 }
527
528 if ((*low > (NSS_N2H_DEFAULT_EMPTY_POOL_BUF_SZ * 2)) ||
529 (*high > (NSS_N2H_DEFAULT_EMPTY_POOL_BUF_SZ * 2))) {
530 nss_warning("%p: core %d setting %d, %d is > upper limit",
531 nss_ctx, core_num, *low, *high);
532 goto failure;
533 }
534
535 if (*low > *high) {
536 nss_warning("%p: core %d setting low %d is more than high %d",
537 nss_ctx, core_num, *low, *high);
538 goto failure;
539 }
540
541 nss_info("%p: core %d number of low : %d and high : %d\n",
542 nss_ctx, core_num, *low, *high);
543
544 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
545 NSS_TX_METADATA_TYPE_SET_WATER_MARK,
546 sizeof(struct nss_n2h_water_mark),
547 nss_n2h_payload_stats_callback,
548 (void *)core_num);
549
550 wm = &nnm.msg.wm;
551 wm->low_water = htonl(*low);
552 wm->high_water = htonl(*high);
553 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
554
555 if (nss_tx_status != NSS_TX_SUCCESS) {
556 nss_warning("%p: core %d nss_tx error setting : %d, %d\n",
557 nss_ctx, core_num, *low, *high);
558 goto failure;
559 }
560
561 /*
562 * Blocking call, wait till we get ACK for this msg.
563 */
564 ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
565 msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
566 if (ret == 0) {
567 nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
568 core_num);
569 goto failure;
570 }
571
572 /*
573 * ACK/NACK received from NSS FW
574 */
575 if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response)
576 goto failure;
577
578 up(&nss_n2h_nepbcfgp[core_num].sem);
579 return NSS_SUCCESS;
580
581failure:
582 /*
583 * Restore the current_value to its previous state
584 */
585 *low = nss_n2h_nepbcfgp[core_num].low_water;
586 *high = nss_n2h_nepbcfgp[core_num].high_water;
Stephen Wang06761022015-03-03 16:38:42 -0800587 up(&nss_n2h_nepbcfgp[core_num].sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700588 return -EINVAL;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800589}
590
591/*
Radha krishna Simha Jiguru7f424d52015-02-10 19:41:01 +0530592 * nss_n2h_flush_payloads()
593 * Sends a command down to NSS for flushing all payloads
594 */
595nss_tx_status_t nss_n2h_flush_payloads(struct nss_ctx_instance *nss_ctx)
596{
597 struct nss_n2h_msg nnm;
598 struct nss_n2h_flush_payloads *nnflshpl;
599 nss_tx_status_t nss_tx_status;
600
601 nnflshpl = &nnm.msg.flush_payloads;
602
603 /*
604 * TODO: No additional information sent in message
605 * as of now. Need to initialize message content accordingly
606 * if needed.
607 */
608 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
609 NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS,
610 sizeof(struct nss_n2h_flush_payloads),
611 NULL,
612 NULL);
613
614 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
615 if (nss_tx_status != NSS_TX_SUCCESS) {
616 nss_warning("%p: failed to send flush payloads command to NSS\n",
617 nss_ctx);
618
619 return NSS_TX_FAILURE;
620 }
621
622 return NSS_TX_SUCCESS;
623}
624
625/*
Vijay Dewangan488e5372014-12-29 21:40:11 -0800626 * nss_n2h_empty_pool_buf_core1_handler()
627 * Sets the number of empty buffer for core 1
628 */
629static int nss_n2h_empty_pool_buf_cfg_core1_handler(ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700630 int write, void __user *buffer,
631 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800632{
633 return nss_n2h_set_empty_pool_buf(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700634 NSS_CORE_1, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800635}
636
637/*
638 * nss_n2h_empty_pool_buf_core0_handler()
639 * Sets the number of empty buffer for core 0
640 */
641static int nss_n2h_empty_pool_buf_cfg_core0_handler(ctl_table *ctl,
Saurabh Misra71034db2015-06-04 16:18:38 -0700642 int write, void __user *buffer,
643 size_t *lenp, loff_t *ppos)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800644{
645 return nss_n2h_set_empty_pool_buf(ctl, write, buffer, lenp, ppos,
Saurabh Misra71034db2015-06-04 16:18:38 -0700646 NSS_CORE_0, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0]);
647}
648
649/*
650 * nss_n2h_water_mark_core1_handler()
651 * Sets water mark for core 1
652 */
653static int nss_n2h_water_mark_core1_handler(ctl_table *ctl,
654 int write, void __user *buffer,
655 size_t *lenp, loff_t *ppos)
656{
657 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
658 NSS_CORE_1, &nss_n2h_water_mark[NSS_CORE_1][0],
659 &nss_n2h_water_mark[NSS_CORE_1][1]);
660}
661
662/*
663 * nss_n2h_water_mark_core0_handler()
664 * Sets water mark for core 0
665 */
666static int nss_n2h_water_mark_core0_handler(ctl_table *ctl,
667 int write, void __user *buffer,
668 size_t *lenp, loff_t *ppos)
669{
670 return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
671 NSS_CORE_0, &nss_n2h_water_mark[NSS_CORE_0][0],
672 &nss_n2h_water_mark[NSS_CORE_0][1]);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800673}
674
Vijay Dewangan634ce592015-01-07 17:21:09 -0800675/*
676 * nss_n2h_rps_cfg()
677 * Send Message to NSS to enable RPS.
678 */
679nss_tx_status_t nss_n2h_rps_cfg(struct nss_ctx_instance *nss_ctx, int enable_rps)
680{
681 struct nss_n2h_msg nnm;
682 struct nss_n2h_rps *rps_cfg;
683 nss_tx_status_t nss_tx_status;
684 int ret;
685
686 down(&nss_n2h_rcp.sem);
687 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_RPS_CFG,
688 sizeof(struct nss_n2h_rps),
689 nss_n2h_rps_cfg_callback,
690 (void *)nss_ctx);
691
692 rps_cfg = &nnm.msg.rps_cfg;
693 rps_cfg->enable = enable_rps;
694
695 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
696
697 if (nss_tx_status != NSS_TX_SUCCESS) {
698 nss_warning("%p: nss_tx error setting rps\n", nss_ctx);
699
700 up(&nss_n2h_rcp.sem);
701 return NSS_FAILURE;
702 }
703
704 /*
705 * Blocking call, wait till we get ACK for this msg.
706 */
707 ret = wait_for_completion_timeout(&nss_n2h_rcp.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
708 if (ret == 0) {
709 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
710 up(&nss_n2h_rcp.sem);
711 return NSS_FAILURE;
712 }
713
714 /*
715 * ACK/NACK received from NSS FW
716 * If ACK: Callback function will update nss_n2h_empty_pool_buf with
717 * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input
718 */
719 if (NSS_FAILURE == nss_n2h_rcp.response) {
720 up(&nss_n2h_rcp.sem);
721 return NSS_FAILURE;
722 }
723
724 up(&nss_n2h_rcp.sem);
725 return NSS_SUCCESS;
726}
727
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +0530728/*
729 * nss_n2h_mitigation_cfg()
730 * Send Message to NSS to disable MITIGATION.
731 */
732nss_tx_status_t nss_n2h_mitigation_cfg(struct nss_ctx_instance *nss_ctx, int enable_mitigation, nss_core_id_t core_num)
733{
734 struct nss_n2h_msg nnm;
735 struct nss_n2h_mitigation *mitigation_cfg;
736 nss_tx_status_t nss_tx_status;
737 int ret;
738
739 nss_assert(core_num < NSS_CORE_MAX);
740
741 down(&nss_n2h_mitigationcp[core_num].sem);
742 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG,
743 sizeof(struct nss_n2h_mitigation),
744 nss_n2h_mitigation_cfg_callback,
745 (void *)core_num);
746
747 mitigation_cfg = &nnm.msg.mitigation_cfg;
748 mitigation_cfg->enable = enable_mitigation;
749
750 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
751
752 if (nss_tx_status != NSS_TX_SUCCESS) {
753 nss_warning("%p: nss_tx error setting mitigation\n", nss_ctx);
754 goto failure;
755 }
756
757 /*
758 * Blocking call, wait till we get ACK for this msg.
759 */
760 ret = wait_for_completion_timeout(&nss_n2h_mitigationcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
761 if (ret == 0) {
762 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
763 goto failure;
764 }
765
766 /*
767 * ACK/NACK received from NSS FW
768 */
769 if (NSS_FAILURE == nss_n2h_mitigationcp[core_num].response) {
770 goto failure;
771 }
772
773 up(&nss_n2h_mitigationcp[core_num].sem);
774 return NSS_SUCCESS;
775
776failure:
777 up(&nss_n2h_mitigationcp[core_num].sem);
778 return NSS_FAILURE;
779}
780
781static inline void nss_n2h_buf_pool_free(struct nss_n2h_buf_pool *buf_pool)
782{
783 int page_count;
784 for (page_count = 0; page_count < buf_pool->nss_buf_num_pages; page_count++) {
785 kfree(buf_pool->nss_buf_pool_vaddr[page_count]);
786 }
787}
788
789/*
790 * nss_n2h_buf_cfg()
791 * Send Message to NSS to enable pbufs.
792 */
793nss_tx_status_t nss_n2h_buf_pool_cfg(struct nss_ctx_instance *nss_ctx,
794 int buf_pool_size, nss_core_id_t core_num)
795{
796 static struct nss_n2h_msg nnm;
797 struct nss_n2h_buf_pool *buf_pool;
798 nss_tx_status_t nss_tx_status;
799 int ret;
800 int page_count;
801 int num_pages = ALIGN(buf_pool_size, PAGE_SIZE)/PAGE_SIZE;
802
803 nss_assert(core_num < NSS_CORE_MAX);
804
805 nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_METADATA_TYPE_N2H_ADD_BUF_POOL,
806 sizeof(struct nss_n2h_buf_pool),
807 nss_n2h_bufs_cfg_callback,
808 (void *)core_num);
809
810 do {
811
812 down(&nss_n2h_bufcp[core_num].sem);
813
814 buf_pool = &nnm.msg.buf_pool;
815 buf_pool->nss_buf_page_size = PAGE_SIZE;
816
817 for (page_count = 0; page_count < MAX_PAGES_PER_MSG && num_pages; page_count++, num_pages--) {
818
819 void *kern_addr = kzalloc(PAGE_SIZE, GFP_ATOMIC);
820 if (!kern_addr) {
821 BUG_ON(!page_count);
822 break;
823 }
824 BUG_ON((long unsigned int)kern_addr % PAGE_SIZE);
825
826 buf_pool->nss_buf_pool_vaddr[page_count] = kern_addr;
827 buf_pool->nss_buf_pool_addr[page_count] = dma_map_single(NULL, kern_addr, PAGE_SIZE, DMA_TO_DEVICE);
828 }
829
830 buf_pool->nss_buf_num_pages = page_count;
831 nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
832 if (nss_tx_status != NSS_TX_SUCCESS) {
833
834 nss_n2h_buf_pool_free(buf_pool);
835 nss_warning("%p: nss_tx error setting pbuf\n", nss_ctx);
836 goto failure;
837 }
838
839 /*
840 * Blocking call, wait till we get ACK for this msg.
841 */
842 ret = wait_for_completion_timeout(&nss_n2h_bufcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
843 if (ret == 0) {
844 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
845 goto failure;
846 }
847
848 /*
849 * ACK/NACK received from NSS FW
850 */
851 if (NSS_FAILURE == nss_n2h_bufcp[core_num].response) {
852
853 nss_n2h_buf_pool_free(buf_pool);
854 goto failure;
855 }
856
857 up(&nss_n2h_bufcp[core_num].sem);
858 } while(num_pages);
859
860 return NSS_SUCCESS;
861failure:
862 up(&nss_n2h_bufcp[core_num].sem);
863 return NSS_FAILURE;
864}
865
866
867
Vijay Dewangan488e5372014-12-29 21:40:11 -0800868static ctl_table nss_n2h_table[] = {
869 {
Saurabh Misra71034db2015-06-04 16:18:38 -0700870 .procname = "n2h_empty_pool_buf_core0",
871 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0],
872 .maxlen = sizeof(int),
873 .mode = 0644,
874 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core0_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -0800875 },
876 {
Saurabh Misra71034db2015-06-04 16:18:38 -0700877 .procname = "n2h_empty_pool_buf_core1",
878 .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1],
879 .maxlen = sizeof(int),
880 .mode = 0644,
881 .proc_handler = &nss_n2h_empty_pool_buf_cfg_core1_handler,
882 },
883 {
884 .procname = "n2h_low_water_core0",
885 .data = &nss_n2h_water_mark[NSS_CORE_0][0],
886 .maxlen = sizeof(int),
887 .mode = 0644,
888 .proc_handler = &nss_n2h_water_mark_core0_handler,
889 },
890 {
891 .procname = "n2h_low_water_core1",
892 .data = &nss_n2h_water_mark[NSS_CORE_1][0],
893 .maxlen = sizeof(int),
894 .mode = 0644,
895 .proc_handler = &nss_n2h_water_mark_core1_handler,
896 },
897 {
898 .procname = "n2h_high_water_core0",
899 .data = &nss_n2h_water_mark[NSS_CORE_0][1],
900 .maxlen = sizeof(int),
901 .mode = 0644,
902 .proc_handler = &nss_n2h_water_mark_core0_handler,
903 },
904 {
905 .procname = "n2h_high_water_core1",
906 .data = &nss_n2h_water_mark[NSS_CORE_1][1],
907 .maxlen = sizeof(int),
908 .mode = 0644,
909 .proc_handler = &nss_n2h_water_mark_core1_handler,
Vijay Dewangan488e5372014-12-29 21:40:11 -0800910 },
911
912 { }
913};
914
915static ctl_table nss_n2h_dir[] = {
916 {
917 .procname = "n2hcfg",
918 .mode = 0555,
919 .child = nss_n2h_table,
920 },
921 { }
922};
923
924
925static ctl_table nss_n2h_root_dir[] = {
926 {
927 .procname = "nss",
928 .mode = 0555,
929 .child = nss_n2h_dir,
930 },
931 { }
932};
933
934static ctl_table nss_n2h_root[] = {
935 {
936 .procname = "dev",
937 .mode = 0555,
938 .child = nss_n2h_root_dir,
939 },
940 { }
941};
942
943static struct ctl_table_header *nss_n2h_header;
944
945/*
946 * nss_n2h_msg_init()
947 * Initialize IPv4 message.
948 */
949void nss_n2h_msg_init(struct nss_n2h_msg *nim, uint16_t if_num, uint32_t type,
Vijay Dewangan634ce592015-01-07 17:21:09 -0800950 uint32_t len, nss_n2h_msg_callback_t cb, void *app_data)
Vijay Dewangan488e5372014-12-29 21:40:11 -0800951{
952 nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data);
953}
954
Vijay Dewangan488e5372014-12-29 21:40:11 -0800955/*
956 * nss_n2h_register_sysctl()
957 * Register sysctl specific to n2h
958 */
959void nss_n2h_empty_pool_buf_register_sysctl(void)
960{
961 /*
962 * Register sysctl table.
963 */
964 nss_n2h_header = register_sysctl_table(nss_n2h_root);
965
966 /*
967 * Core0
968 */
969 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_0].sem, 1);
970 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_0].complete);
Saurabh Misra71034db2015-06-04 16:18:38 -0700971 nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool =
972 nss_n2h_empty_pool_buf_cfg[NSS_CORE_0];
973 nss_n2h_nepbcfgp[NSS_CORE_0].low_water =
974 nss_n2h_water_mark[NSS_CORE_0][0];
975 nss_n2h_nepbcfgp[NSS_CORE_0].high_water =
976 nss_n2h_water_mark[NSS_CORE_0][1];
Vijay Dewangan488e5372014-12-29 21:40:11 -0800977
978 /*
979 * Core1
980 */
981 sema_init(&nss_n2h_nepbcfgp[NSS_CORE_1].sem, 1);
982 init_completion(&nss_n2h_nepbcfgp[NSS_CORE_1].complete);
Saurabh Misra71034db2015-06-04 16:18:38 -0700983 nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool =
984 nss_n2h_empty_pool_buf_cfg[NSS_CORE_1];
985 nss_n2h_nepbcfgp[NSS_CORE_1].low_water =
986 nss_n2h_water_mark[NSS_CORE_1][0];
987 nss_n2h_nepbcfgp[NSS_CORE_1].high_water =
988 nss_n2h_water_mark[NSS_CORE_1][1];
Vijay Dewangan488e5372014-12-29 21:40:11 -0800989}
990
991/*
992 * nss_n2h_unregister_sysctl()
993 * Unregister sysctl specific to n2h
994 */
995void nss_n2h_empty_pool_buf_unregister_sysctl(void)
996{
997 /*
998 * Unregister sysctl table.
999 */
1000 if (nss_n2h_header) {
1001 unregister_sysctl_table(nss_n2h_header);
1002 }
1003}
1004
1005/*
1006 * nss_n2h_tx_msg()
1007 * Send messages to NSS n2h pacakge
1008 */
1009nss_tx_status_t nss_n2h_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_n2h_msg *nnm)
1010{
1011 struct nss_n2h_msg *nnm2;
1012 struct nss_cmn_msg *ncm = &nnm->cm;
1013 struct sk_buff *nbuf;
1014 nss_tx_status_t status;
1015
1016 NSS_VERIFY_CTX_MAGIC(nss_ctx);
1017 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
1018 return NSS_TX_FAILURE_NOT_READY;
1019 }
1020
1021 /*
1022 * Sanity check the message
1023 */
1024 if (ncm->interface != NSS_N2H_INTERFACE) {
1025 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
1026 return NSS_TX_FAILURE;
1027 }
1028
1029 if (ncm->type >= NSS_METADATA_TYPE_N2H_MAX) {
1030 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
1031 return NSS_TX_FAILURE;
1032 }
1033
1034 if (ncm->len > sizeof(struct nss_n2h_msg)) {
1035 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
1036 return NSS_TX_FAILURE;
1037 }
1038
1039
1040 nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
1041 if (unlikely(!nbuf)) {
Sundarajan Srinivasan62fee7e2015-01-22 11:13:10 -08001042 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 -08001043 return NSS_TX_FAILURE;
1044 }
1045
1046 /*
1047 * Copy the message to our skb.
1048 */
1049 nnm2 = (struct nss_n2h_msg *)skb_put(nbuf, sizeof(struct nss_n2h_msg));
1050 memcpy(nnm2, nnm, sizeof(struct nss_n2h_msg));
1051 status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
1052 if (status != NSS_CORE_STATUS_SUCCESS) {
1053 dev_kfree_skb_any(nbuf);
1054 nss_info("%p: unable to enqueue 'nss frequency change' - marked as stopped\n", nss_ctx);
1055 return NSS_TX_FAILURE;
1056 }
1057
1058 nss_hal_send_interrupt(nss_ctx->nmap,
1059 nss_ctx->h2n_desc_rings[NSS_IF_CMD_QUEUE].desc_ring.int_bit,
1060 NSS_REGS_H2N_INTR_STATUS_DATA_COMMAND_QUEUE);
1061 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
1062 return NSS_TX_SUCCESS;
1063}
1064
Vijay Dewangan488e5372014-12-29 21:40:11 -08001065/*
1066 * nss_n2h_notify_register()
1067 * Register to received N2H events.
1068 *
1069 * NOTE: Do we want to pass an nss_ctx here so that we can register for n2h on any core?
1070 */
1071struct nss_ctx_instance *nss_n2h_notify_register(int core, nss_n2h_msg_callback_t cb, void *app_data)
1072{
1073 if (core >= NSS_MAX_CORES) {
1074 nss_warning("Input core number %d is wrong \n", core);
1075 return NULL;
1076 }
1077 /*
1078 * TODO: We need to have a new array in support of the new API
1079 * TODO: If we use a per-context array, we would move the array into nss_ctx based.
1080 */
1081 nss_n2h_rd[core].n2h_callback = cb;
1082 nss_n2h_rd[core].app_data = app_data;
1083 return &nss_top_main.nss[core];
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301084}
1085
1086/*
1087 * nss_n2h_register_handler()
1088 */
1089void nss_n2h_register_handler()
1090{
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -07001091 nss_core_register_handler(NSS_N2H_INTERFACE, nss_n2h_interface_handler, NULL);
1092
Vijay Dewangan634ce592015-01-07 17:21:09 -08001093 /*
1094 * RPS sema init
1095 */
1096 sema_init(&nss_n2h_rcp.sem, 1);
1097 init_completion(&nss_n2h_rcp.complete);
1098
Kalyan Tallapragadab50e8902015-08-06 17:00:54 +05301099 /*
1100 * MITIGATION sema init for core0
1101 */
1102 sema_init(&nss_n2h_mitigationcp[NSS_CORE_0].sem, 1);
1103 init_completion(&nss_n2h_mitigationcp[NSS_CORE_0].complete);
1104
1105 /*
1106 * MITIGATION sema init for core1
1107 */
1108 sema_init(&nss_n2h_mitigationcp[NSS_CORE_1].sem, 1);
1109 init_completion(&nss_n2h_mitigationcp[NSS_CORE_1].complete);
1110
1111 /*
1112 * PBUF addition sema init for core0
1113 */
1114 sema_init(&nss_n2h_bufcp[NSS_CORE_0].sem, 1);
1115 init_completion(&nss_n2h_bufcp[NSS_CORE_0].complete);
1116
1117 /*
1118 * PBUF addition sema init for core1
1119 */
1120 sema_init(&nss_n2h_bufcp[NSS_CORE_1].sem, 1);
1121 init_completion(&nss_n2h_bufcp[NSS_CORE_1].complete);
Vijay Dewangan634ce592015-01-07 17:21:09 -08001122
Vijay Dewangan488e5372014-12-29 21:40:11 -08001123 nss_n2h_notify_register(NSS_CORE_0, NULL, NULL);
1124 nss_n2h_notify_register(NSS_CORE_1, NULL, NULL);
1125
Abhishek Rastogi84d95d02014-03-26 19:31:31 +05301126}
Vijay Dewangan488e5372014-12-29 21:40:11 -08001127
1128EXPORT_SYMBOL(nss_n2h_notify_register);
Vijay Dewanganac7efc42015-02-09 16:04:53 -08001129EXPORT_SYMBOL(nss_n2h_empty_pool_buf_register_sysctl);