blob: 16067a4661350b3461f0a6e8396db8220cee78cc [file] [log] [blame]
Sol Kavy879eb8b2014-04-07 19:11:31 -07001/*
2 **************************************************************************
Vijay Dewangan488e5372014-12-29 21:40:11 -08003 * Copyright (c) 2014 - 2015, 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"
Sol Kavy879eb8b2014-04-07 19:11:31 -070022
Vijay Dewangan4861f4e2014-10-14 16:56:35 -070023int nss_ipv6_conn_cfg __read_mostly = NSS_DEFAULT_NUM_CONN;
24static struct nss_conn_cfg_pvt i6cfgp;
Vijay Dewangan9db18752014-09-15 16:25:01 -070025
Sol Kavy879eb8b2014-04-07 19:11:31 -070026/*
Gareth Williams958aa822015-02-04 19:36:39 +000027 * nss_ipv6_max_conn_count()
28 * Return the maximum number of IPv6 connections that the NSS acceleration engine supports.
29 */
30int nss_ipv6_max_conn_count(void)
31{
32 return nss_ipv6_conn_cfg;
33}
34EXPORT_SYMBOL(nss_ipv6_max_conn_count);
35
36/*
Sol Kavy879eb8b2014-04-07 19:11:31 -070037 * nss_ipv6_driver_conn_sync_update()
38 * Update driver specific information from the messsage.
39 */
40static void nss_ipv6_driver_conn_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync *nics)
41{
42 struct nss_top_instance *nss_top = nss_ctx->nss_top;
Sol Kavy879eb8b2014-04-07 19:11:31 -070043
44 /*
45 * Update statistics maintained by NSS driver
46 */
47 spin_lock_bh(&nss_top->stats_lock);
48 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_RX_PKTS] += nics->flow_rx_packet_count + nics->return_rx_packet_count;
49 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_RX_BYTES] += nics->flow_rx_byte_count + nics->return_rx_byte_count;
50 nss_top->stats_ipv6[NSS_STATS_IPV6_ACCELERATED_TX_PKTS] += nics->flow_tx_packet_count + nics->return_tx_packet_count;
51 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 +053052 spin_unlock_bh(&nss_top->stats_lock);
Sol Kavy879eb8b2014-04-07 19:11:31 -070053}
54
55/*
Murat Sezgin0c0561d2014-04-09 18:55:58 -070056 * nss_ipv6_driver_node_sync_update)
57 * Update driver specific information from the messsage.
58 */
59static void nss_ipv6_driver_node_sync_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_node_sync *nins)
60{
61 struct nss_top_instance *nss_top = nss_ctx->nss_top;
62 uint32_t i;
63
64 /*
65 * Update statistics maintained by NSS driver
66 */
67 spin_lock_bh(&nss_top->stats_lock);
68 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nins->node_stats.rx_packets;
69 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nins->node_stats.rx_bytes;
70 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_DROPPED] += nins->node_stats.rx_dropped;
71 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nins->node_stats.tx_packets;
72 nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nins->node_stats.tx_bytes;
73
Murat Sezgin0c0561d2014-04-09 18:55:58 -070074 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_REQUESTS] += nins->ipv6_connection_create_requests;
75 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_COLLISIONS] += nins->ipv6_connection_create_collisions;
76 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv6_connection_create_invalid_interface;
77 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_DESTROY_REQUESTS] += nins->ipv6_connection_destroy_requests;
78 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_DESTROY_MISSES] += nins->ipv6_connection_destroy_misses;
79 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_HASH_HITS] += nins->ipv6_connection_hash_hits;
80 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_HASH_REORDERS] += nins->ipv6_connection_hash_reorders;
81 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_FLUSHES] += nins->ipv6_connection_flushes;
82 nss_top->stats_ipv6[NSS_STATS_IPV6_CONNECTION_EVICTIONS] += nins->ipv6_connection_evictions;
Selin Dag5d68caa2015-05-12 13:23:33 -070083 nss_top->stats_ipv6[NSS_STATS_IPV6_FRAGMENTATIONS] += nins->ipv6_fragmentations;
84 nss_top->stats_ipv6[NSS_STATS_IPV6_FRAG_FAILS] += nins->ipv6_frag_fails;
Kiran Kumar C.S.Kfadf92d2015-06-26 12:48:33 +053085 nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_CREATE_REQUESTS] += nins->ipv6_mc_connection_create_requests;
86 nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_UPDATE_REQUESTS] += nins->ipv6_mc_connection_update_requests;
87 nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv6_mc_connection_create_invalid_interface;
88 nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_DESTROY_REQUESTS] += nins->ipv6_mc_connection_destroy_requests;
89 nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_DESTROY_MISSES] += nins->ipv6_mc_connection_destroy_misses;
90 nss_top->stats_ipv6[NSS_STATS_IPV6_MC_CONNECTION_FLUSHES] += nins->ipv6_mc_connection_flushes;
Murat Sezgin0c0561d2014-04-09 18:55:58 -070091
92 for (i = 0; i < NSS_EXCEPTION_EVENT_IPV6_MAX; i++) {
93 nss_top->stats_if_exception_ipv6[i] += nins->exception_events[i];
94 }
95 spin_unlock_bh(&nss_top->stats_lock);
96}
97
98/*
Sol Kavy879eb8b2014-04-07 19:11:31 -070099 * nss_ipv6_rx_msg_handler()
100 * Handle NSS -> HLOS messages for IPv6 bridge/route
101 */
102static void nss_ipv6_rx_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data)
103{
104 struct nss_ipv6_msg *nim = (struct nss_ipv6_msg *)ncm;
105 nss_ipv6_msg_callback_t cb;
106
107 BUG_ON(ncm->interface != NSS_IPV6_RX_INTERFACE);
108
109 /*
110 * Is this a valid request/response packet?
111 */
Murat Sezgin5c8c7362014-09-02 17:58:21 -0700112 if (ncm->type >= NSS_IPV6_MAX_MSG_TYPES) {
Sol Kavy879eb8b2014-04-07 19:11:31 -0700113 nss_warning("%p: received invalid message %d for IPv6 interface", nss_ctx, nim->cm.type);
114 return;
115 }
116
117 if (ncm->len > sizeof(struct nss_ipv6_msg)) {
118 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
119 return;
120 }
121
122 /*
123 * Log failures
124 */
125 nss_core_log_msg_failures(nss_ctx, ncm);
126
127 /*
128 * Handle deprecated messages. Eventually these messages should be removed.
129 */
130 switch (nim->cm.type) {
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700131 case NSS_IPV6_RX_NODE_STATS_SYNC_MSG:
132 /*
133 * Update driver statistics on node sync.
134 */
135 nss_ipv6_driver_node_sync_update(nss_ctx, &nim->msg.node_stats);
136 break;
137
Sol Kavy879eb8b2014-04-07 19:11:31 -0700138 case NSS_IPV6_RX_CONN_STATS_SYNC_MSG:
139 /*
140 * Update driver statistics on connection sync.
141 */
142 nss_ipv6_driver_conn_sync_update(nss_ctx, &nim->msg.conn_stats);
Sakthi Vignesh Radhakrishnan515f8c22014-06-21 15:04:19 -0700143 break;
Sol Kavy879eb8b2014-04-07 19:11:31 -0700144 }
Abhishek Rastogi55f39452014-05-08 19:23:29 +0530145
Sol Kavy879eb8b2014-04-07 19:11:31 -0700146 /*
147 * Update the callback and app_data for NOTIFY messages, IPv6 sends all notify messages
148 * to the same callback/app_data.
149 */
150 if (nim->cm.response == NSS_CMM_RESPONSE_NOTIFY) {
151 ncm->cb = (uint32_t)nss_ctx->nss_top->ipv6_callback;
152 ncm->app_data = (uint32_t)nss_ctx->nss_top->ipv6_ctx;
153 }
154
155 /*
156 * Do we have a callback?
157 */
158 if (!ncm->cb) {
159 return;
160 }
161
162 /*
163 * Callback
164 */
165 cb = (nss_ipv6_msg_callback_t)ncm->cb;
166 cb((void *)ncm->app_data, nim);
167}
168
169/*
170 * nss_ipv6_tx()
171 * Transmit an ipv6 message to the FW.
172 */
173nss_tx_status_t nss_ipv6_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim)
174{
175 struct nss_ipv6_msg *nim2;
176 struct nss_cmn_msg *ncm = &nim->cm;
177 struct sk_buff *nbuf;
178 int32_t status;
179
180 NSS_VERIFY_CTX_MAGIC(nss_ctx);
181 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
182 nss_warning("%p: ipv6 msg dropped as core not ready", nss_ctx);
183 return NSS_TX_FAILURE_NOT_READY;
184 }
185
186 /*
187 * Sanity check the message
188 */
189 if (ncm->interface != NSS_IPV6_RX_INTERFACE) {
190 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
191 return NSS_TX_FAILURE;
192 }
193
Murat Sezgin5c8c7362014-09-02 17:58:21 -0700194 if (ncm->type >= NSS_IPV6_MAX_MSG_TYPES) {
Sol Kavy879eb8b2014-04-07 19:11:31 -0700195 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
196 return NSS_TX_FAILURE;
197 }
198
199 if (ncm->len > sizeof(struct nss_ipv6_msg)) {
200 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
201 return NSS_TX_FAILURE;
202 }
203
Pamidipati, Vijayb6e38842014-09-16 10:26:05 +0530204 nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700205 if (unlikely(!nbuf)) {
Sundarajan Srinivasan62fee7e2015-01-22 11:13:10 -0800206 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 -0700207 nss_warning("%p: msg dropped as command allocation failed", nss_ctx);
208 return NSS_TX_FAILURE;
209 }
210
211 /*
212 * Copy the message to our skb.
213 */
214 nim2 = (struct nss_ipv6_msg *)skb_put(nbuf, sizeof(struct nss_ipv6_msg));
215 memcpy(nim2, nim, sizeof(struct nss_ipv6_msg));
216
217 status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
218 if (status != NSS_CORE_STATUS_SUCCESS) {
Pamidipati, Vijayb6e38842014-09-16 10:26:05 +0530219 dev_kfree_skb_any(nbuf);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700220 nss_warning("%p: Unable to enqueue 'Destroy IPv6' rule\n", nss_ctx);
221 return NSS_TX_FAILURE;
222 }
223
224 nss_hal_send_interrupt(nss_ctx->nmap, nss_ctx->h2n_desc_rings[NSS_IF_CMD_QUEUE].desc_ring.int_bit,
225 NSS_REGS_H2N_INTR_STATUS_DATA_COMMAND_QUEUE);
226
227 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
228 return NSS_TX_SUCCESS;
229}
230
231/*
232 **********************************
233 Register/Unregister/Miscellaneous APIs
234 **********************************
235 */
236
237/*
238 * nss_ipv6_notify_register()
239 * Register to received IPv6 events.
240 *
241 * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv6 on any core?
242 */
243struct nss_ctx_instance *nss_ipv6_notify_register(nss_ipv6_msg_callback_t cb, void *app_data)
244{
245 /*
246 * TODO: We need to have a new array in support of the new API
247 * TODO: If we use a per-context array, we would move the array into nss_ctx based.
248 */
249 nss_top_main.ipv6_callback = cb;
250 nss_top_main.ipv6_ctx = app_data;
251 return &nss_top_main.nss[nss_top_main.ipv6_handler_id];
252}
253
254/*
255 * nss_ipv6_notify_unregister()
256 * Unregister to received IPv6 events.
257 *
258 * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv6 on any core?
259 */
260void nss_ipv6_notify_unregister(void)
261{
262 nss_top_main.ipv6_callback = NULL;
263}
264
265/*
266 * nss_ipv6_get_mgr()
267 *
268 * TODO: This only suppports a single ipv6, do we ever want to support more?
269 */
270struct nss_ctx_instance *nss_ipv6_get_mgr(void)
271{
272 return (void *)&nss_top_main.nss[nss_top_main.ipv6_handler_id];
273}
274
275/*
276 * nss_ipv6_register_handler()
277 * Register our handler to receive messages for this interface
278 */
279void nss_ipv6_register_handler()
280{
281 if (nss_core_register_handler(NSS_IPV6_RX_INTERFACE, nss_ipv6_rx_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) {
282 nss_warning("IPv6 handler failed to register");
283 }
284}
285
Vijay Dewangan9db18752014-09-15 16:25:01 -0700286/*
287 * nss_ipv6_conn_cfg_callback()
288 * call back function for the ipv6 connection configuration handler
289 */
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700290static void nss_ipv6_conn_cfg_callback(void *app_data, struct nss_ipv6_msg *nim)
Vijay Dewangan9db18752014-09-15 16:25:01 -0700291{
292 if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700293 /*
Kiran Kumar C.S.Kfadf92d2015-06-26 12:48:33 +0530294 * Error, hence we are not updating the nss_ipv6_conn_cfg
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700295 * Restore the current_value to its previous state
296 */
Vijay Dewangan488e5372014-12-29 21:40:11 -0800297 i6cfgp.response = NSS_FAILURE;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700298 complete(&i6cfgp.complete);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700299 return;
300 }
301
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700302 /*
Kiran Kumar C.S.Kfadf92d2015-06-26 12:48:33 +0530303 * Sucess at NSS FW, hence updating nss_ipv6_conn_cfg, with the valid value
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700304 * saved at the sysctl handler.
305 */
Vijay Dewangan9db18752014-09-15 16:25:01 -0700306 nss_info("IPv6 connection configuration success: %d\n", nim->cm.error);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800307 i6cfgp.response = NSS_SUCCESS;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700308 complete(&i6cfgp.complete);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700309}
310
311
312/*
313 * nss_ipv6_conn_cfg_handler()
314 * Sets the number of connections for IPv6
315 */
316static int nss_ipv6_conn_cfg_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
317{
318 struct nss_top_instance *nss_top = &nss_top_main;
319 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
320 struct nss_ipv6_msg nim;
321 struct nss_ipv6_rule_conn_cfg_msg *nirccm;
322 nss_tx_status_t nss_tx_status;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800323 int ret = NSS_FAILURE;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700324 uint32_t sum_of_conn;
325
326 /*
327 * Acquiring semaphore
328 */
329 down(&i6cfgp.sem);
330
331 /*
332 * Take a snapshot of the current value
333 */
334 i6cfgp.current_value = nss_ipv6_conn_cfg;
335
336 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
337 if (ret || (!write)) {
338 up(&i6cfgp.sem);
339 return ret;
340 }
Vijay Dewangan9db18752014-09-15 16:25:01 -0700341
342 /*
343 * Specifications for input
344 * 1) The input should be power of 2.
345 * 2) Input for ipv4 and ipv6 sum togther should not exceed 8k
346 * 3) Min. value should be at leat 256 connections. This is the
347 * minimum connections we will support for each of them.
348 */
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700349 sum_of_conn = nss_ipv4_conn_cfg + nss_ipv6_conn_cfg;
350 if ((nss_ipv6_conn_cfg & NSS_NUM_CONN_QUANTA_MASK) ||
351 (sum_of_conn > NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6) ||
352 (nss_ipv6_conn_cfg < NSS_MIN_NUM_CONN)) {
Vijay Dewangan9db18752014-09-15 16:25:01 -0700353 nss_warning("%p: input supported connections (%d) does not adhere\
354 specifications\n1) not power of 2,\n2) is less than \
355 min val: %d, OR\n IPv4/6 total exceeds %d\n",
356 nss_ctx,
357 nss_ipv6_conn_cfg,
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700358 NSS_MIN_NUM_CONN,
359 NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6);
Stephen Wang06761022015-03-03 16:38:42 -0800360 goto failure;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700361 }
362
Vijay Dewangan9db18752014-09-15 16:25:01 -0700363
364 nss_info("%p: IPv6 supported connections: %d\n", nss_ctx, nss_ipv6_conn_cfg);
365
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700366 nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_CONN_CFG_RULE_MSG,
Sundarajan Srinivasan30a53d42015-01-30 10:52:08 -0800367 sizeof(struct nss_ipv6_rule_conn_cfg_msg), nss_ipv6_conn_cfg_callback, NULL);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700368
369 nirccm = &nim.msg.rule_conn_cfg;
370 nirccm->num_conn = htonl(nss_ipv6_conn_cfg);
371 nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
372
373 if (nss_tx_status != NSS_TX_SUCCESS) {
374 nss_warning("%p: nss_tx error setting IPv6 Connections: %d\n",
375 nss_ctx,
376 nss_ipv6_conn_cfg);
Stephen Wang06761022015-03-03 16:38:42 -0800377 goto failure;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700378 }
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700379
380 /*
381 * Blocking call, wait till we get ACK for this msg.
382 */
383 ret = wait_for_completion_timeout(&i6cfgp.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
384 if (ret == 0) {
385 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
Stephen Wang06761022015-03-03 16:38:42 -0800386 goto failure;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700387 }
388
389 /*
390 * ACK/NACK received from NSS FW
Kiran Kumar C.S.Kfadf92d2015-06-26 12:48:33 +0530391 * If ACK: Callback function will update nss_ipv6_conn_cfg with
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700392 * i6cfgp.num_conn_valid, which holds the user input
393 */
Vijay Dewangan488e5372014-12-29 21:40:11 -0800394 if (NSS_FAILURE == i6cfgp.response) {
Stephen Wang06761022015-03-03 16:38:42 -0800395 goto failure;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700396 }
397
398 up(&i6cfgp.sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700399 return 0;
Stephen Wang06761022015-03-03 16:38:42 -0800400
401failure:
402 /*
403 * Restore the current_value to its previous state
404 */
405 nss_ipv6_conn_cfg = i6cfgp.current_value;
406 up(&i6cfgp.sem);
Thomas Wu651b3902015-05-12 11:21:09 -0700407 return -EINVAL;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700408}
409
410static ctl_table nss_ipv6_table[] = {
411 {
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700412 .procname = "ipv6_conn",
413 .data = &nss_ipv6_conn_cfg,
414 .maxlen = sizeof(int),
415 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700416 .proc_handler = &nss_ipv6_conn_cfg_handler,
417 },
418 { }
419};
420
421static ctl_table nss_ipv6_dir[] = {
422 {
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700423 .procname = "ipv6cfg",
424 .mode = 0555,
425 .child = nss_ipv6_table,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700426 },
427 { }
428};
429
430static ctl_table nss_ipv6_root_dir[] = {
431 {
432 .procname = "nss",
433 .mode = 0555,
434 .child = nss_ipv6_dir,
435 },
436 { }
437};
438
439static ctl_table nss_ipv6_root[] = {
440 {
441 .procname = "dev",
442 .mode = 0555,
443 .child = nss_ipv6_root_dir,
444 },
445 { }
446};
447
448static struct ctl_table_header *nss_ipv6_header;
449
450/*
451 * nss_ipv6_register_sysctl()
Kiran Kumar C.S.Kfadf92d2015-06-26 12:48:33 +0530452 * Register sysctl specific to ipv6
Vijay Dewangan9db18752014-09-15 16:25:01 -0700453 */
454void nss_ipv6_register_sysctl(void)
455{
456 /*
457 * Register sysctl table.
458 */
459 nss_ipv6_header = register_sysctl_table(nss_ipv6_root);
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700460 sema_init(&i6cfgp.sem, 1);
461 init_completion(&i6cfgp.complete);
462 i6cfgp.current_value = nss_ipv6_conn_cfg;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700463}
464
465/*
466 * nss_ipv6_unregister_sysctl()
Kiran Kumar C.S.Kfadf92d2015-06-26 12:48:33 +0530467 * Unregister sysctl specific to ipv6
Vijay Dewangan9db18752014-09-15 16:25:01 -0700468 */
469void nss_ipv6_unregister_sysctl(void)
470{
471 /*
472 * Unregister sysctl table.
473 */
474 if (nss_ipv6_header) {
475 unregister_sysctl_table(nss_ipv6_header);
476 }
477}
478
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700479/*
480 * nss_ipv6_msg_init()
481 * Initialize IPv6 message.
482 */
483void 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 -0800484 nss_ipv6_msg_callback_t cb, void *app_data)
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700485{
486 nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data);
487}
488
Sol Kavy879eb8b2014-04-07 19:11:31 -0700489EXPORT_SYMBOL(nss_ipv6_tx);
490EXPORT_SYMBOL(nss_ipv6_notify_register);
491EXPORT_SYMBOL(nss_ipv6_notify_unregister);
492EXPORT_SYMBOL(nss_ipv6_get_mgr);
493EXPORT_SYMBOL(nss_ipv6_register_handler);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700494EXPORT_SYMBOL(nss_ipv6_register_sysctl);
495EXPORT_SYMBOL(nss_ipv6_unregister_sysctl);
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700496EXPORT_SYMBOL(nss_ipv6_msg_init);