blob: ae83ea296b48c70a6fdd4f1b338c0e2a7775a952 [file] [log] [blame]
Sol Kavy879eb8b2014-04-07 19:11:31 -07001/*
2 **************************************************************************
Stephen Wangaed46332016-12-12 17:29:03 -08003 * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
Sol Kavy879eb8b2014-04-07 19:11:31 -07004 * 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/*
18 * nss_ipv6.c
19 * NSS IPv6 APIs
20 */
Sol Kavy879eb8b2014-04-07 19:11:31 -070021#include "nss_tx_rx_common.h"
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -070022#include "nss_dscp_map.h"
Sol Kavy879eb8b2014-04-07 19:11:31 -070023
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -070024#define NSS_IPV6_TX_MSG_TIMEOUT 1000 /* 1 sec timeout for IPv6 messages */
Stephen Wang0a2756a2016-08-04 15:52:47 -070025
26/*
27 * Private data structure for ipv6 configure messages
28 */
29struct nss_ipv6_cfg_pvt {
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -070030 struct semaphore sem; /* Semaphore structure */
31 struct completion complete; /* Completion structure */
32 int response; /* Response from FW */
33 void *cb; /* Original cb for sync msgs */
34 void *app_data; /* Original app_data for sync msgs */
35} nss_ipv6_pvt;
Stephen Wang0a2756a2016-08-04 15:52:47 -070036
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -070037/*
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -070038 * Private data structure for ipv6 connection information.
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -070039 */
40struct nss_ipv6_conn_table_info {
41 uint32_t ce_table_size; /* Size of connection entry table in NSS FW */
42 uint32_t cme_table_size; /* Size of connection match entry table in NSS FW */
43 unsigned long ce_mem; /* Start address for connection entry table */
44 unsigned long cme_mem; /* Start address for connection match entry table */
45} nss_ipv6_ct_info;
Stephen Wang0a2756a2016-08-04 15:52:47 -070046
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -070047int nss_ipv6_conn_cfg = NSS_DEFAULT_NUM_CONN;
Stephen Wangf6a9acb2017-08-23 10:35:39 -070048int nss_ipv6_accel_mode_cfg __read_mostly = 1;
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -070049
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -070050static struct nss_dscp_map_entry mapping[NSS_DSCP_MAP_ARRAY_SIZE];
Vijay Dewangan9db18752014-09-15 16:25:01 -070051
Sol Kavy879eb8b2014-04-07 19:11:31 -070052/*
Suruchi Agarwal611ecd02016-08-04 15:54:35 -070053 * Callback for conn_sync_many request message.
54 */
55nss_ipv6_msg_callback_t nss_ipv6_conn_sync_many_msg_cb = NULL;
56
57/*
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -070058 * nss_ipv6_dscp_map_usage()
59 * Help function shows the usage of the command.
Gareth Williams958aa822015-02-04 19:36:39 +000060 */
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -070061static inline void nss_ipv6_dscp_map_usage(void)
Gareth Williams958aa822015-02-04 19:36:39 +000062{
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -070063 nss_info_always("\nUsage:\n");
64 nss_info_always("echo <dscp> <action> <prio> > /proc/sys/dev/nss/ipv6cfg/ipv6_dscp_map\n\n");
65 nss_info_always("dscp[0-63] action[0-%u] prio[0-%u]:\n\n",
66 NSS_IPV6_DSCP_MAP_ACTION_MAX - 1,
67 NSS_DSCP_MAP_PRIORITY_MAX - 1);
Gareth Williams958aa822015-02-04 19:36:39 +000068}
Guojun Jin9a1cb282017-07-13 17:32:07 -070069
70/*
Sol Kavy879eb8b2014-04-07 19:11:31 -070071 * nss_ipv6_driver_conn_sync_update()
72 * Update driver specific information from the messsage.
73 */
74static void nss_ipv6_driver_conn_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync *nics)
75{
76 struct nss_top_instance *nss_top = nss_ctx->nss_top;
Sol Kavy879eb8b2014-04-07 19:11:31 -070077
78 /*
79 * Update statistics maintained by NSS driver
80 */
81 spin_lock_bh(&nss_top->stats_lock);
82 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_RX_PKTS] += nics->flow_rx_packet_count + nics->return_rx_packet_count;
83 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_RX_BYTES] += nics->flow_rx_byte_count + nics->return_rx_byte_count;
84 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_TX_PKTS] += nics->flow_tx_packet_count + nics->return_tx_packet_count;
85 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_TX_BYTES] += nics->flow_tx_byte_count + nics->return_tx_byte_count;
Abhishek Rastogi55f39452014-05-08 19:23:29 +053086 spin_unlock_bh(&nss_top->stats_lock);
Sol Kavy879eb8b2014-04-07 19:11:31 -070087}
88
89/*
Stephen Wang709f9b52015-07-07 14:48:35 -070090 * nss_ipv6_driver_conn_sync_many_update()
91 * Update driver specific information from the conn_sync_many messsage.
92 */
93static void nss_ipv6_driver_conn_sync_many_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync_many_msg *nicsm)
94{
95 uint32_t i;
96
97 /*
98 * Sanity check for the stats count
99 */
100 if (nicsm->count * sizeof(struct nss_ipv6_conn_sync) >= nicsm->size) {
101 nss_warning("%p: stats sync count %u exceeds the size of this msg %u", nss_ctx, nicsm->count, nicsm->size);
102 return;
103 }
104
105 for (i = 0; i < nicsm->count; i++) {
106 nss_ipv6_driver_conn_sync_update(nss_ctx, &nicsm->conn_sync[i]);
107 }
108}
109
110/*
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700111 * nss_ipv6_driver_node_sync_update)
112 * Update driver specific information from the messsage.
113 */
114static void nss_ipv6_driver_node_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_node_sync *nins)
115{
116 struct nss_top_instance *nss_top = nss_ctx->nss_top;
ratheesh kannoth93ba95c2017-07-13 15:52:52 +0530117 int i;
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700118
119 /*
120 * Update statistics maintained by NSS driver
121 */
122 spin_lock_bh(&nss_top->stats_lock);
123 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nins->node_stats.rx_packets;
124 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nins->node_stats.rx_bytes;
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700125 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nins->node_stats.tx_packets;
126 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nins->node_stats.tx_bytes;
127
ratheesh kannoth93ba95c2017-07-13 15:52:52 +0530128 for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
129 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += nins->node_stats.rx_dropped[i];
130 }
131
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700132 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_REQUESTS] += nins->ipv6_connection_create_requests;
133 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_COLLISIONS] += nins->ipv6_connection_create_collisions;
134 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv6_connection_create_invalid_interface;
135 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_DESTROY_REQUESTS] += nins->ipv6_connection_destroy_requests;
136 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_DESTROY_MISSES] += nins->ipv6_connection_destroy_misses;
137 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_HASH_HITS] += nins->ipv6_connection_hash_hits;
138 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_HASH_REORDERS] += nins->ipv6_connection_hash_reorders;
139 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_FLUSHES] += nins->ipv6_connection_flushes;
140 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_EVICTIONS] += nins->ipv6_connection_evictions;
Selin Dag5d68caa2015-05-12 13:23:33 -0700141 nss_top->stats_ipv6[NSS_STATS_IPV6_FRAGMENTATIONS] += nins->ipv6_fragmentations;
142 nss_top->stats_ipv6[NSS_STATS_IPV6_FRAG_FAILS] += nins->ipv6_frag_fails;
Jackson Bockus140d2b22017-08-10 13:56:44 -0700143 nss_top->stats_ipv6[NSS_STATS_IPV6_DROPPED_BY_RULE] += nins->ipv6_dropped_by_rule;
Kiran Kumar C.S.Kfadf92d2015-06-26 12:48:33 +0530144 nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_CREATE_REQUESTS] += nins->ipv6_mc_connection_create_requests;
145 nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_UPDATE_REQUESTS] += nins->ipv6_mc_connection_update_requests;
146 nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv6_mc_connection_create_invalid_interface;
147 nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_DESTROY_REQUESTS] += nins->ipv6_mc_connection_destroy_requests;
148 nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_DESTROY_MISSES] += nins->ipv6_mc_connection_destroy_misses;
149 nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_FLUSHES] += nins->ipv6_mc_connection_flushes;
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700150
151 for (i = 0; i < NSS_EXCEPTION_EVENT_IPV6_MAX; i++) {
152 nss_top->stats_if_exception_ipv6[i] += nins->exception_events[i];
153 }
154 spin_unlock_bh(&nss_top->stats_lock);
155}
156
157/*
Sol Kavy879eb8b2014-04-07 19:11:31 -0700158 * nss_ipv6_rx_msg_handler()
159 * Handle NSS -> HLOS messages for IPv6 bridge/route
160 */
161static void nss_ipv6_rx_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data)
162{
163 struct nss_ipv6_msg *nim = (struct nss_ipv6_msg *)ncm;
164 nss_ipv6_msg_callback_t cb;
165
166 BUG_ON(ncm->interface != NSS_IPV6_RX_INTERFACE);
167
168 /*
169 * Is this a valid request/response packet?
170 */
Murat Sezgin5c8c7362014-09-02 17:58:21 -0700171 if (ncm->type >= NSS_IPV6_MAX_MSG_TYPES) {
Sol Kavy879eb8b2014-04-07 19:11:31 -0700172 nss_warning("%p: received invalid message %d for IPv6 interface", nss_ctx, nim->cm.type);
173 return;
174 }
175
Suruchi Agarwalef8a8702016-01-08 12:40:08 -0800176 if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ipv6_msg)) {
177 nss_warning("%p: message length is invalid: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
Sol Kavy879eb8b2014-04-07 19:11:31 -0700178 return;
179 }
180
181 /*
Suruchi Agarwale3940e72016-07-06 15:56:51 -0700182 * Trace messages.
Sol Kavy879eb8b2014-04-07 19:11:31 -0700183 */
Suruchi Agarwale3940e72016-07-06 15:56:51 -0700184 nss_ipv6_log_rx_msg(nim);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700185
186 /*
Stephen Wang0a2756a2016-08-04 15:52:47 -0700187 * Handle deprecated messages. Eventually these messages should be removed.
Sol Kavy879eb8b2014-04-07 19:11:31 -0700188 */
189 switch (nim->cm.type) {
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700190 case NSS_IPV6_RX_NODE_STATS_SYNC_MSG:
191 /*
192 * Update driver statistics on node sync.
193 */
194 nss_ipv6_driver_node_sync_update(nss_ctx, &nim->msg.node_stats);
195 break;
196
Sol Kavy879eb8b2014-04-07 19:11:31 -0700197 case NSS_IPV6_RX_CONN_STATS_SYNC_MSG:
198 /*
199 * Update driver statistics on connection sync.
200 */
201 nss_ipv6_driver_conn_sync_update(nss_ctx, &nim->msg.conn_stats);
Sakthi Vignesh Radhakrishnan515f8c22014-06-21 15:04:19 -0700202 break;
Stephen Wang709f9b52015-07-07 14:48:35 -0700203
204 case NSS_IPV6_TX_CONN_STATS_SYNC_MANY_MSG:
205 /*
206 * Update driver statistics on connection sync many.
207 */
208 nss_ipv6_driver_conn_sync_many_update(nss_ctx, &nim->msg.conn_stats_many);
Stephen Wangaed46332016-12-12 17:29:03 -0800209 ncm->cb = (nss_ptr_t)nss_ipv6_conn_sync_many_msg_cb;
Stephen Wang709f9b52015-07-07 14:48:35 -0700210 break;
Sol Kavy879eb8b2014-04-07 19:11:31 -0700211 }
Abhishek Rastogi55f39452014-05-08 19:23:29 +0530212
Sol Kavy879eb8b2014-04-07 19:11:31 -0700213 /*
214 * Update the callback and app_data for NOTIFY messages, IPv6 sends all notify messages
215 * to the same callback/app_data.
216 */
217 if (nim->cm.response == NSS_CMM_RESPONSE_NOTIFY) {
Stephen Wangaed46332016-12-12 17:29:03 -0800218 ncm->cb = (nss_ptr_t)nss_ctx->nss_top->ipv6_callback;
219 ncm->app_data = (nss_ptr_t)nss_ctx->nss_top->ipv6_ctx;
Sol Kavy879eb8b2014-04-07 19:11:31 -0700220 }
221
222 /*
223 * Do we have a callback?
224 */
225 if (!ncm->cb) {
226 return;
227 }
228
229 /*
230 * Callback
231 */
232 cb = (nss_ipv6_msg_callback_t)ncm->cb;
233 cb((void *)ncm->app_data, nim);
234}
235
236/*
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -0700237 * nss_ipv6_tx_sync_callback()
238 * Callback to handle the completion of synchronous tx messages.
239 */
240static void nss_ipv6_tx_sync_callback(void *app_data, struct nss_ipv6_msg *nim)
241{
242 nss_ipv6_msg_callback_t callback = (nss_ipv6_msg_callback_t)nss_ipv6_pvt.cb;
243 void *data = nss_ipv6_pvt.app_data;
244
245 nss_ipv6_pvt.cb = NULL;
246 nss_ipv6_pvt.app_data = NULL;
247
248 if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
249 nss_warning("ipv6 error response %d\n", nim->cm.response);
250 nss_ipv6_pvt.response = NSS_TX_FAILURE;
251 } else {
252 nss_ipv6_pvt.response = NSS_TX_SUCCESS;
253 }
254
255 if (callback) {
256 callback(data, nim);
257 }
258
259 complete(&nss_ipv6_pvt.complete);
260}
261
262/*
263 * nss_ipv6_dscp_action_get()
264 * Gets the action mapped to dscp.
265 */
266enum nss_ipv6_dscp_map_actions nss_ipv6_dscp_action_get(uint8_t dscp)
267{
268 if (dscp > NSS_DSCP_MAP_ARRAY_SIZE) {
269 nss_warning("dscp:%u invalid\n", dscp);
270 return NSS_IPV6_DSCP_MAP_ACTION_MAX;
271 }
272
273 return mapping[dscp].action;
274}
275EXPORT_SYMBOL(nss_ipv6_dscp_action_get);
276
277/*
278 * nss_ipv6_max_conn_count()
279 * Return the maximum number of IPv6 connections that the NSS acceleration engine supports.
280 */
281int nss_ipv6_max_conn_count(void)
282{
283 return nss_ipv6_conn_cfg;
284}
285EXPORT_SYMBOL(nss_ipv6_max_conn_count);
286
287/*
288 * nss_ipv6_conn_inquiry()
289 * Inquiry if a connection has been established in NSS FW
290 */
291nss_tx_status_t nss_ipv6_conn_inquiry(struct nss_ipv6_5tuple *ipv6_5t_p,
292 nss_ipv6_msg_callback_t cb)
293{
294 nss_tx_status_t nss_tx_status;
295 struct nss_ipv6_msg nim;
296 struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[0];
297
298 /*
299 * Initialize inquiry message structure.
300 * This is async message and the result will be returned
301 * to the caller by the msg_callback passed in.
302 */
303 memset(&nim, 0, sizeof(nim));
304 nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE,
305 NSS_IPV6_TX_CONN_CFG_INQUIRY_MSG,
306 sizeof(struct nss_ipv6_inquiry_msg),
307 cb, NULL);
308 nim.msg.inquiry.rr.tuple = *ipv6_5t_p;
309 nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
310 if (nss_tx_status != NSS_TX_SUCCESS) {
311 nss_warning("%p: Send inquiry message failed\n", ipv6_5t_p);
312 }
313
314 return nss_tx_status;
315}
316EXPORT_SYMBOL(nss_ipv6_conn_inquiry);
317
318/*
Stephen Wang709f9b52015-07-07 14:48:35 -0700319 * nss_ipv6_tx_with_size()
320 * Transmit an ipv6 message to the FW with a specified size.
Sol Kavy879eb8b2014-04-07 19:11:31 -0700321 */
Stephen Wang709f9b52015-07-07 14:48:35 -0700322nss_tx_status_t nss_ipv6_tx_with_size(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim, uint32_t size)
Sol Kavy879eb8b2014-04-07 19:11:31 -0700323{
324 struct nss_ipv6_msg *nim2;
325 struct nss_cmn_msg *ncm = &nim->cm;
326 struct sk_buff *nbuf;
327 int32_t status;
328
329 NSS_VERIFY_CTX_MAGIC(nss_ctx);
330 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
331 nss_warning("%p: ipv6 msg dropped as core not ready", nss_ctx);
332 return NSS_TX_FAILURE_NOT_READY;
333 }
334
335 /*
336 * Sanity check the message
337 */
338 if (ncm->interface != NSS_IPV6_RX_INTERFACE) {
339 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
340 return NSS_TX_FAILURE;
341 }
342
Murat Sezgin5c8c7362014-09-02 17:58:21 -0700343 if (ncm->type >= NSS_IPV6_MAX_MSG_TYPES) {
Sol Kavy879eb8b2014-04-07 19:11:31 -0700344 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
345 return NSS_TX_FAILURE;
346 }
347
Suruchi Agarwalef8a8702016-01-08 12:40:08 -0800348 if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ipv6_msg)) {
349 nss_warning("%p: message length is invalid: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
Sol Kavy879eb8b2014-04-07 19:11:31 -0700350 return NSS_TX_FAILURE;
351 }
352
Stephen Wang709f9b52015-07-07 14:48:35 -0700353 if(size > PAGE_SIZE) {
354 nss_warning("%p: tx request size too large: %u", nss_ctx, size);
355 return NSS_TX_FAILURE;
356 }
357
358 nbuf = dev_alloc_skb(size);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700359 if (unlikely(!nbuf)) {
Sundarajan Srinivasan62fee7e2015-01-22 11:13:10 -0800360 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700361 nss_warning("%p: msg dropped as command allocation failed", nss_ctx);
362 return NSS_TX_FAILURE;
363 }
364
365 /*
366 * Copy the message to our skb.
367 */
Suruchi Agarwalea2e5232016-09-14 10:32:08 -0700368 nim2 = (struct nss_ipv6_msg *)skb_put(nbuf, size);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700369 memcpy(nim2, nim, sizeof(struct nss_ipv6_msg));
370
Suruchi Agarwale3940e72016-07-06 15:56:51 -0700371 /*
372 * Trace messages.
373 */
374 nss_ipv6_log_tx_msg(nim);
375
Sol Kavy879eb8b2014-04-07 19:11:31 -0700376 status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
377 if (status != NSS_CORE_STATUS_SUCCESS) {
Pamidipati, Vijayb6e38842014-09-16 10:26:05 +0530378 dev_kfree_skb_any(nbuf);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700379 nss_warning("%p: Unable to enqueue 'Destroy IPv6' rule\n", nss_ctx);
380 return NSS_TX_FAILURE;
381 }
382
Stephen Wang90c67de2016-04-26 15:15:59 -0700383 nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700384
385 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
386 return NSS_TX_SUCCESS;
387}
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700388EXPORT_SYMBOL(nss_ipv6_tx_with_size);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700389
390/*
Stephen Wang709f9b52015-07-07 14:48:35 -0700391 * nss_ipv6_tx()
Suruchi Agarwal611ecd02016-08-04 15:54:35 -0700392 * Transmit an ipv6 message to the FW.
Stephen Wang709f9b52015-07-07 14:48:35 -0700393 */
394nss_tx_status_t nss_ipv6_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim)
395{
396 return nss_ipv6_tx_with_size(nss_ctx, nim, NSS_NBUF_PAYLOAD_SIZE);
397}
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700398EXPORT_SYMBOL(nss_ipv6_tx);
Stephen Wang709f9b52015-07-07 14:48:35 -0700399
400/*
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -0700401 * nss_ipv6_tx_sync()
402 * Transmit a synchronous ipv6 message to the FW.
403 */
404nss_tx_status_t nss_ipv6_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim)
405{
406 nss_tx_status_t status;
407 int ret = 0;
408
409 down(&nss_ipv6_pvt.sem);
410 nss_ipv6_pvt.cb = (void *)nim->cm.cb;
411 nss_ipv6_pvt.app_data = (void *)nim->cm.app_data;
412
413 nim->cm.cb = (nss_ptr_t)nss_ipv6_tx_sync_callback;
414 nim->cm.app_data = (nss_ptr_t)NULL;
415
416 status = nss_ipv6_tx(nss_ctx, nim);
417 if (status != NSS_TX_SUCCESS) {
418 nss_warning("%p: nss ipv6 msg tx failed\n", nss_ctx);
419 up(&nss_ipv6_pvt.sem);
420 return status;
421 }
422
423 ret = wait_for_completion_timeout(&nss_ipv6_pvt.complete, msecs_to_jiffies(NSS_IPV6_TX_MSG_TIMEOUT));
424 if (!ret) {
425 nss_warning("%p: IPv6 tx sync failed due to timeout\n", nss_ctx);
426 nss_ipv6_pvt.response = NSS_TX_FAILURE;
427 }
428
429 status = nss_ipv6_pvt.response;
430 up(&nss_ipv6_pvt.sem);
431 return status;
432}
433EXPORT_SYMBOL(nss_ipv6_tx_sync);
434
435/*
Sol Kavy879eb8b2014-04-07 19:11:31 -0700436 **********************************
437 Register/Unregister/Miscellaneous APIs
438 **********************************
439 */
440
441/*
442 * nss_ipv6_notify_register()
443 * Register to received IPv6 events.
444 *
445 * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv6 on any core?
446 */
447struct nss_ctx_instance *nss_ipv6_notify_register(nss_ipv6_msg_callback_t cb, void *app_data)
448{
449 /*
450 * TODO: We need to have a new array in support of the new API
451 * TODO: If we use a per-context array, we would move the array into nss_ctx based.
452 */
453 nss_top_main.ipv6_callback = cb;
454 nss_top_main.ipv6_ctx = app_data;
455 return &nss_top_main.nss[nss_top_main.ipv6_handler_id];
456}
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700457EXPORT_SYMBOL(nss_ipv6_notify_register);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700458
459/*
460 * nss_ipv6_notify_unregister()
461 * Unregister to received IPv6 events.
462 *
463 * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv6 on any core?
464 */
465void nss_ipv6_notify_unregister(void)
466{
467 nss_top_main.ipv6_callback = NULL;
468}
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700469EXPORT_SYMBOL(nss_ipv6_notify_unregister);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700470
471/*
Suruchi Agarwal611ecd02016-08-04 15:54:35 -0700472 * nss_ipv6_conn_sync_many_notify_register()
473 * Register to receive IPv6 conn_sync_many message response.
474 */
475void nss_ipv6_conn_sync_many_notify_register(nss_ipv6_msg_callback_t cb)
476{
477 nss_ipv6_conn_sync_many_msg_cb = cb;
478}
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700479EXPORT_SYMBOL(nss_ipv6_conn_sync_many_notify_register);
Suruchi Agarwal611ecd02016-08-04 15:54:35 -0700480
481/*
482 * nss_ipv6_conn_sync_many_notify_unregister()
483 * Unregister to receive IPv6 conn_sync_many message response.
484 */
485void nss_ipv6_conn_sync_many_notify_unregister(void)
486{
487 nss_ipv6_conn_sync_many_msg_cb = NULL;
488}
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700489EXPORT_SYMBOL(nss_ipv6_conn_sync_many_notify_unregister);
Suruchi Agarwal611ecd02016-08-04 15:54:35 -0700490
491/*
Sol Kavy879eb8b2014-04-07 19:11:31 -0700492 * nss_ipv6_get_mgr()
493 *
494 * TODO: This only suppports a single ipv6, do we ever want to support more?
495 */
496struct nss_ctx_instance *nss_ipv6_get_mgr(void)
497{
498 return (void *)&nss_top_main.nss[nss_top_main.ipv6_handler_id];
499}
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700500EXPORT_SYMBOL(nss_ipv6_get_mgr);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700501
502/*
503 * nss_ipv6_register_handler()
504 * Register our handler to receive messages for this interface
505 */
506void nss_ipv6_register_handler()
507{
Thomas Wu91f4bdf2017-06-09 12:03:02 -0700508 struct nss_ctx_instance *nss_ctx = nss_ipv6_get_mgr();
509
510 if (nss_core_register_handler(nss_ctx, NSS_IPV6_RX_INTERFACE, nss_ipv6_rx_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) {
Sol Kavy879eb8b2014-04-07 19:11:31 -0700511 nss_warning("IPv6 handler failed to register");
512 }
513}
514
Vijay Dewangan9db18752014-09-15 16:25:01 -0700515/*
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700516 * nss_ipv6_conn_cfg_process_callback()
517 * Call back function for the ipv6 connection configuration process.
518 */
519static void nss_ipv6_conn_cfg_process_callback(void *app_data, struct nss_ipv6_msg *nim)
520{
521 struct nss_ipv6_rule_conn_cfg_msg *nirccm = &nim->msg.rule_conn_cfg;
522 struct nss_ctx_instance *nss_ctx __maybe_unused = nss_ipv6_get_mgr();
523
524 if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
525 nss_warning("%p: IPv6 connection configuration failed with error: %d\n", nss_ctx, nim->cm.error);
526 nss_core_update_max_ipv6_conn(NSS_DEFAULT_NUM_CONN);
527 nss_ipv6_free_conn_tables();
528 return;
529 }
530
531 nss_ipv6_conn_cfg = ntohl(nirccm->num_conn);
532
533 nss_warning("%p: IPv6 connection configuration success: %d\n", nss_ctx, nim->cm.error);
534}
535
536/*
Tushar Mathura3c18932015-08-24 20:27:21 +0530537 * nss_ipv6_conn_cfg_process()
538 * Process request to configure number of ipv6 connections
539 */
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700540static int nss_ipv6_conn_cfg_process(struct nss_ctx_instance *nss_ctx, int conn)
Tushar Mathura3c18932015-08-24 20:27:21 +0530541{
542 struct nss_ipv6_msg nim;
543 struct nss_ipv6_rule_conn_cfg_msg *nirccm;
544 nss_tx_status_t nss_tx_status;
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700545
546 if ((!nss_ipv6_ct_info.ce_table_size) || (!nss_ipv6_ct_info.cme_table_size)) {
547 nss_warning("%p: connection entry or connection match entry table size not available\n",
548 nss_ctx);
549 return -EINVAL;
550 }
551
552 nss_info("%p: IPv6 supported connections: %d\n", nss_ctx, conn);
553
554 nss_ipv6_ct_info.ce_mem = __get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO,
555 get_order(nss_ipv6_ct_info.ce_table_size));
556 if (!nss_ipv6_ct_info.ce_mem) {
557 nss_warning("%p: Memory allocation failed for IPv6 Connections: %d\n",
558 nss_ctx,
559 conn);
560 goto fail;
561 }
562 nss_warning("%p: CE Memory allocated for IPv6 Connections: %d\n",
563 nss_ctx,
564 conn);
565
566 nss_ipv6_ct_info.cme_mem = __get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO,
567 get_order(nss_ipv6_ct_info.cme_table_size));
568 if (!nss_ipv6_ct_info.cme_mem) {
569 nss_warning("%p: Memory allocation failed for IPv6 Connections: %d\n",
570 nss_ctx,
571 conn);
572 goto fail;
573 }
574 nss_warning("%p: CME Memory allocated for IPv6 Connections: %d\n",
575 nss_ctx,
576 conn);
577
578 memset(&nim, 0, sizeof(struct nss_ipv6_msg));
579 nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_CONN_CFG_RULE_MSG,
580 sizeof(struct nss_ipv6_rule_conn_cfg_msg), nss_ipv6_conn_cfg_process_callback, NULL);
581
582 nirccm = &nim.msg.rule_conn_cfg;
583 nirccm->num_conn = htonl(conn);
Suruchi Agarwal8c9e7162017-08-17 15:58:40 -0700584 nirccm->ce_mem = dma_map_single(nss_ctx->dev, (void *)nss_ipv6_ct_info.ce_mem, nss_ipv6_ct_info.ce_table_size, DMA_TO_DEVICE);
585 if (unlikely(dma_mapping_error(nss_ctx->dev, nirccm->ce_mem))) {
586 nss_warning("%p: DMA mapping failed for virtual address = %p", nss_ctx, (void *)nss_ipv6_ct_info.ce_mem);
587 goto fail;
588 }
589
590 nirccm->cme_mem = dma_map_single(nss_ctx->dev, (void *)nss_ipv6_ct_info.cme_mem, nss_ipv6_ct_info.cme_table_size, DMA_TO_DEVICE);
591 if (unlikely(dma_mapping_error(nss_ctx->dev, nirccm->cme_mem))) {
592 nss_warning("%p: DMA mapping failed for virtual address = %p", nss_ctx, (void *)nss_ipv6_ct_info.cme_mem);
593 goto fail;
594 }
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700595
596 nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
597 if (nss_tx_status != NSS_TX_SUCCESS) {
598 nss_warning("%p: nss_tx error setting IPv6 Connections: %d\n",
599 nss_ctx,
600 conn);
601 goto fail;
602 }
603
604 return 0;
605
606fail:
607 nss_ipv6_free_conn_tables();
608 return -EINVAL;
609}
610
611/*
612 * nss_ipv6_update_conn_count_callback()
613 * Call back function for the ipv6 get connection info message.
614 */
615static void nss_ipv6_update_conn_count_callback(void *app_data, struct nss_ipv6_msg *nim)
616{
617 struct nss_ipv6_rule_conn_get_table_size_msg *nircgts = &nim->msg.size;
618 struct nss_ctx_instance *nss_ctx = nss_ipv6_get_mgr();
619
620 if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
621 nss_warning("%p: IPv6 fetch connection info failed with error: %d\n", nss_ctx, nim->cm.error);
622 nss_core_update_max_ipv6_conn(NSS_DEFAULT_NUM_CONN);
623 return;
624 }
625
626 nss_info("IPv6 get connection info success\n");
627
628 nss_ipv6_ct_info.ce_table_size = ntohl(nircgts->ce_table_size);
629 nss_ipv6_ct_info.cme_table_size = ntohl(nircgts->cme_table_size);
630
631 if (nss_ipv6_conn_cfg_process(nss_ctx, ntohl(nircgts->num_conn)) != 0) {
632 nss_warning("%p: IPv6 connection entry or connection match entry table size\
633 not available\n", nss_ctx);
634 }
635
636 return;
637}
638
639/*
640 * nss_ipv6_update_conn_count()
641 * Sets the maximum number of IPv6 connections.
642 *
643 * It first gets the connection tables size information from NSS FW
644 * and then configures the connections in NSS FW.
645 */
646int nss_ipv6_update_conn_count(int ipv6_num_conn)
647{
648 struct nss_ctx_instance *nss_ctx = nss_ipv6_get_mgr();
649 struct nss_ipv6_msg nim;
650 struct nss_ipv6_rule_conn_get_table_size_msg *nircgts;
651 nss_tx_status_t nss_tx_status;
Tushar Mathura3c18932015-08-24 20:27:21 +0530652 uint32_t sum_of_conn;
653
654 /*
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700655 * By default, NSS FW is configured with default number of connections.
656 */
657 if (ipv6_num_conn == NSS_DEFAULT_NUM_CONN) {
658 nss_info("%p: Default number of connections (%d) already configured\n", nss_ctx, ipv6_num_conn);
659 return 0;
660 }
661
662 /*
Tushar Mathura3c18932015-08-24 20:27:21 +0530663 * Specifications for input
664 * 1) The input should be power of 2.
665 * 2) Input for ipv4 and ipv6 sum togther should not exceed 8k
666 * 3) Min. value should be at leat 256 connections. This is the
667 * minimum connections we will support for each of them.
668 */
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700669 sum_of_conn = nss_ipv4_conn_cfg + ipv6_num_conn;
670 if ((ipv6_num_conn & NSS_NUM_CONN_QUANTA_MASK) ||
Tushar Mathura3c18932015-08-24 20:27:21 +0530671 (sum_of_conn > NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6) ||
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700672 (ipv6_num_conn < NSS_MIN_NUM_CONN)) {
Tushar Mathura3c18932015-08-24 20:27:21 +0530673 nss_warning("%p: input supported connections (%d) does not adhere\
674 specifications\n1) not power of 2,\n2) is less than \
675 min val: %d, OR\n IPv4/6 total exceeds %d\n",
676 nss_ctx,
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700677 ipv6_num_conn,
Tushar Mathura3c18932015-08-24 20:27:21 +0530678 NSS_MIN_NUM_CONN,
679 NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6);
680 return -EINVAL;
681 }
682
Tushar Mathura3c18932015-08-24 20:27:21 +0530683 memset(&nim, 0, sizeof(struct nss_ipv6_msg));
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700684 nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_CONN_TABLE_SIZE_MSG,
685 sizeof(struct nss_ipv6_rule_conn_get_table_size_msg), nss_ipv6_update_conn_count_callback, NULL);
Tushar Mathura3c18932015-08-24 20:27:21 +0530686
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700687 nircgts = &nim.msg.size;
688 nircgts->num_conn = htonl(ipv6_num_conn);
Tushar Mathura3c18932015-08-24 20:27:21 +0530689 nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
Tushar Mathura3c18932015-08-24 20:27:21 +0530690 if (nss_tx_status != NSS_TX_SUCCESS) {
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700691 nss_warning("%p: Send acceleration mode message failed\n", nss_ctx);
692 return -EINVAL;
Tushar Mathura3c18932015-08-24 20:27:21 +0530693 }
694
695 return 0;
696}
697
698/*
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700699 * nss_ipv6_free_conn_tables()
700 * Frees memory allocated for connection tables
Vijay Dewangan9db18752014-09-15 16:25:01 -0700701 */
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700702void nss_ipv6_free_conn_tables(void)
Vijay Dewangan9db18752014-09-15 16:25:01 -0700703{
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700704 if (nss_ipv6_ct_info.ce_mem) {
705 free_pages(nss_ipv6_ct_info.ce_mem, get_order(nss_ipv6_ct_info.ce_table_size));
Vijay Dewangan9db18752014-09-15 16:25:01 -0700706 }
707
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700708 if (nss_ipv6_ct_info.cme_mem) {
709 free_pages(nss_ipv6_ct_info.cme_mem, get_order(nss_ipv6_ct_info.cme_table_size));
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700710 }
Vijay Dewangan9db18752014-09-15 16:25:01 -0700711
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700712 memset(&nss_ipv6_ct_info, 0, sizeof(struct nss_ipv6_conn_table_info));
713 return;
Tushar Mathura3c18932015-08-24 20:27:21 +0530714}
715
Stephen Wang0a2756a2016-08-04 15:52:47 -0700716/*
Stephen Wang0a2756a2016-08-04 15:52:47 -0700717 * nss_ipv6_accel_mode_cfg_handler()
718 * Configure acceleration mode for IPv6
719 */
720static int nss_ipv6_accel_mode_cfg_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
721{
722 struct nss_top_instance *nss_top = &nss_top_main;
723 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
724 struct nss_ipv6_msg nim;
725 struct nss_ipv6_accel_mode_cfg_msg *nipcm;
726 nss_tx_status_t nss_tx_status;
727 int ret = NSS_FAILURE;
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -0700728 int current_value;
Stephen Wang0a2756a2016-08-04 15:52:47 -0700729
730 /*
731 * Take snap shot of current value
732 */
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -0700733 current_value = nss_ipv6_accel_mode_cfg;
Stephen Wang0a2756a2016-08-04 15:52:47 -0700734
735 /*
736 * Write the variable with user input
737 */
738 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
739 if (ret || (!write)) {
Stephen Wang0a2756a2016-08-04 15:52:47 -0700740 return ret;
741 }
742
743 memset(&nim, 0, sizeof(struct nss_ipv6_msg));
744 nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_ACCEL_MODE_CFG_MSG,
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -0700745 sizeof(struct nss_ipv6_accel_mode_cfg_msg), NULL, NULL);
Stephen Wang0a2756a2016-08-04 15:52:47 -0700746
747 nipcm = &nim.msg.accel_mode_cfg;
748 nipcm->mode = htonl(nss_ipv6_accel_mode_cfg);
Stephen Wang0a2756a2016-08-04 15:52:47 -0700749
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -0700750 nss_tx_status = nss_ipv6_tx_sync(nss_ctx, &nim);
Stephen Wang0a2756a2016-08-04 15:52:47 -0700751 if (nss_tx_status != NSS_TX_SUCCESS) {
752 nss_warning("%p: Send acceleration mode message failed\n", nss_ctx);
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -0700753 nss_ipv6_accel_mode_cfg = current_value;
754 return -EIO;
755 }
756
757 return 0;
758}
759
760/*
761 * nss_ipv6_dscp_map_cfg_handler()
762 * Sysctl handler for dscp/pri mappings.
763 */
764static int nss_ipv6_dscp_map_cfg_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
765{
766 struct nss_top_instance *nss_top = &nss_top_main;
767 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
768 struct nss_dscp_map_parse out;
769 struct nss_ipv6_msg nim;
770 struct nss_ipv6_dscp2pri_cfg_msg *nipd2p;
771 nss_tx_status_t status;
772 int ret;
773
774 if (!write) {
775 return nss_dscp_map_print(ctl, buffer, lenp, ppos, mapping);
776 }
777
778 ret = nss_dscp_map_parse(ctl, buffer, lenp, ppos, &out);
779 if (ret) {
780 nss_warning("failed to parse dscp mapping:%d\n", ret);
781 return ret;
782 }
783
784 if (out.action >= NSS_IPV6_DSCP_MAP_ACTION_MAX) {
785 nss_warning("invalid action value: %d\n", out.action);
786 nss_ipv6_dscp_map_usage();
787 return -EINVAL;
788 }
789
790 memset(&nim, 0, sizeof(struct nss_ipv6_msg));
791 nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_DSCP2PRI_CFG_MSG,
792 sizeof(struct nss_ipv6_dscp2pri_cfg_msg), NULL, NULL);
793
794 nipd2p = &nim.msg.dscp2pri_cfg;
795 nipd2p->dscp = out.dscp;
796 nipd2p->priority = out.priority;
797
798 status = nss_ipv6_tx_sync(nss_ctx, &nim);
799 if (status != NSS_TX_SUCCESS) {
800 nss_warning("%p: ipv6 dscp2pri config message failed\n", nss_ctx);
801 return -EFAULT;
Stephen Wang0a2756a2016-08-04 15:52:47 -0700802 }
803
804 /*
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -0700805 * NSS firmware acknowleged the configuration, so update the mapping
806 * table on HOST side as well.
Stephen Wang0a2756a2016-08-04 15:52:47 -0700807 */
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -0700808 mapping[out.dscp].action = out.action;
809 mapping[out.dscp].priority = out.priority;
Stephen Wang0a2756a2016-08-04 15:52:47 -0700810
Stephen Wang0a2756a2016-08-04 15:52:47 -0700811 return 0;
Stephen Wang0a2756a2016-08-04 15:52:47 -0700812}
813
Stephen Wang52e6d342016-03-29 15:02:33 -0700814static struct ctl_table nss_ipv6_table[] = {
Vijay Dewangan9db18752014-09-15 16:25:01 -0700815 {
Stephen Wang0a2756a2016-08-04 15:52:47 -0700816 .procname = "ipv6_accel_mode",
817 .data = &nss_ipv6_accel_mode_cfg,
818 .maxlen = sizeof(int),
819 .mode = 0644,
820 .proc_handler = &nss_ipv6_accel_mode_cfg_handler,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700821 },
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -0700822 {
823 .procname = "ipv6_dscp_map",
824 .data = &mapping[NSS_DSCP_MAP_ARRAY_SIZE],
825 .maxlen = sizeof(struct nss_dscp_map_entry),
826 .mode = 0644,
827 .proc_handler = &nss_ipv6_dscp_map_cfg_handler,
828 },
Vijay Dewangan9db18752014-09-15 16:25:01 -0700829 { }
830};
831
Stephen Wang52e6d342016-03-29 15:02:33 -0700832static struct ctl_table nss_ipv6_dir[] = {
Vijay Dewangan9db18752014-09-15 16:25:01 -0700833 {
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700834 .procname = "ipv6cfg",
835 .mode = 0555,
836 .child = nss_ipv6_table,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700837 },
838 { }
839};
840
Stephen Wang52e6d342016-03-29 15:02:33 -0700841static struct ctl_table nss_ipv6_root_dir[] = {
Vijay Dewangan9db18752014-09-15 16:25:01 -0700842 {
843 .procname = "nss",
844 .mode = 0555,
845 .child = nss_ipv6_dir,
846 },
847 { }
848};
849
Stephen Wang52e6d342016-03-29 15:02:33 -0700850static struct ctl_table nss_ipv6_root[] = {
Vijay Dewangan9db18752014-09-15 16:25:01 -0700851 {
852 .procname = "dev",
853 .mode = 0555,
854 .child = nss_ipv6_root_dir,
855 },
856 { }
857};
858
859static struct ctl_table_header *nss_ipv6_header;
860
861/*
862 * nss_ipv6_register_sysctl()
Kiran Kumar C.S.Kfadf92d2015-06-26 12:48:33 +0530863 * Register sysctl specific to ipv6
Vijay Dewangan9db18752014-09-15 16:25:01 -0700864 */
865void nss_ipv6_register_sysctl(void)
866{
Sakthi Vignesh Radhakrishnan8d02a2d2017-09-06 14:38:59 -0700867 sema_init(&nss_ipv6_pvt.sem, 1);
868 init_completion(&nss_ipv6_pvt.complete);
Stephen Wang49b474b2016-03-25 10:40:30 -0700869
Vijay Dewangan9db18752014-09-15 16:25:01 -0700870 /*
871 * Register sysctl table.
872 */
873 nss_ipv6_header = register_sysctl_table(nss_ipv6_root);
874}
875
876/*
877 * nss_ipv6_unregister_sysctl()
Kiran Kumar C.S.Kfadf92d2015-06-26 12:48:33 +0530878 * Unregister sysctl specific to ipv6
Vijay Dewangan9db18752014-09-15 16:25:01 -0700879 */
880void nss_ipv6_unregister_sysctl(void)
881{
882 /*
883 * Unregister sysctl table.
884 */
885 if (nss_ipv6_header) {
886 unregister_sysctl_table(nss_ipv6_header);
887 }
888}
889
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700890/*
891 * nss_ipv6_msg_init()
Stephen Wang0a2756a2016-08-04 15:52:47 -0700892 * Initialize IPv6 message.
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700893 */
894void nss_ipv6_msg_init(struct nss_ipv6_msg *nim, uint16_t if_num, uint32_t type, uint32_t len,
Sundarajan Srinivasan30a53d42015-01-30 10:52:08 -0800895 nss_ipv6_msg_callback_t cb, void *app_data)
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700896{
897 nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data);
898}
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700899EXPORT_SYMBOL(nss_ipv6_msg_init);