blob: 4f5bf5c01a96cc3547a515f1116d36a8347a386d [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;
83
84 for (i = 0; i < NSS_EXCEPTION_EVENT_IPV6_MAX; i++) {
85 nss_top->stats_if_exception_ipv6[i] += nins->exception_events[i];
86 }
87 spin_unlock_bh(&nss_top->stats_lock);
88}
89
90/*
Sol Kavy879eb8b2014-04-07 19:11:31 -070091 * nss_ipv6_rx_msg_handler()
92 * Handle NSS -> HLOS messages for IPv6 bridge/route
93 */
94static void nss_ipv6_rx_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data)
95{
96 struct nss_ipv6_msg *nim = (struct nss_ipv6_msg *)ncm;
97 nss_ipv6_msg_callback_t cb;
98
99 BUG_ON(ncm->interface != NSS_IPV6_RX_INTERFACE);
100
101 /*
102 * Is this a valid request/response packet?
103 */
Murat Sezgin5c8c7362014-09-02 17:58:21 -0700104 if (ncm->type >= NSS_IPV6_MAX_MSG_TYPES) {
Sol Kavy879eb8b2014-04-07 19:11:31 -0700105 nss_warning("%p: received invalid message %d for IPv6 interface", nss_ctx, nim->cm.type);
106 return;
107 }
108
109 if (ncm->len > sizeof(struct nss_ipv6_msg)) {
110 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
111 return;
112 }
113
114 /*
115 * Log failures
116 */
117 nss_core_log_msg_failures(nss_ctx, ncm);
118
119 /*
120 * Handle deprecated messages. Eventually these messages should be removed.
121 */
122 switch (nim->cm.type) {
Murat Sezgin0c0561d2014-04-09 18:55:58 -0700123 case NSS_IPV6_RX_NODE_STATS_SYNC_MSG:
124 /*
125 * Update driver statistics on node sync.
126 */
127 nss_ipv6_driver_node_sync_update(nss_ctx, &nim->msg.node_stats);
128 break;
129
Sol Kavy879eb8b2014-04-07 19:11:31 -0700130 case NSS_IPV6_RX_CONN_STATS_SYNC_MSG:
131 /*
132 * Update driver statistics on connection sync.
133 */
134 nss_ipv6_driver_conn_sync_update(nss_ctx, &nim->msg.conn_stats);
Sakthi Vignesh Radhakrishnan515f8c22014-06-21 15:04:19 -0700135 break;
Sol Kavy879eb8b2014-04-07 19:11:31 -0700136 }
Abhishek Rastogi55f39452014-05-08 19:23:29 +0530137
Sol Kavy879eb8b2014-04-07 19:11:31 -0700138 /*
139 * Update the callback and app_data for NOTIFY messages, IPv6 sends all notify messages
140 * to the same callback/app_data.
141 */
142 if (nim->cm.response == NSS_CMM_RESPONSE_NOTIFY) {
143 ncm->cb = (uint32_t)nss_ctx->nss_top->ipv6_callback;
144 ncm->app_data = (uint32_t)nss_ctx->nss_top->ipv6_ctx;
145 }
146
147 /*
148 * Do we have a callback?
149 */
150 if (!ncm->cb) {
151 return;
152 }
153
154 /*
155 * Callback
156 */
157 cb = (nss_ipv6_msg_callback_t)ncm->cb;
158 cb((void *)ncm->app_data, nim);
159}
160
161/*
162 * nss_ipv6_tx()
163 * Transmit an ipv6 message to the FW.
164 */
165nss_tx_status_t nss_ipv6_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim)
166{
167 struct nss_ipv6_msg *nim2;
168 struct nss_cmn_msg *ncm = &nim->cm;
169 struct sk_buff *nbuf;
170 int32_t status;
171
172 NSS_VERIFY_CTX_MAGIC(nss_ctx);
173 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
174 nss_warning("%p: ipv6 msg dropped as core not ready", nss_ctx);
175 return NSS_TX_FAILURE_NOT_READY;
176 }
177
178 /*
179 * Sanity check the message
180 */
181 if (ncm->interface != NSS_IPV6_RX_INTERFACE) {
182 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
183 return NSS_TX_FAILURE;
184 }
185
Murat Sezgin5c8c7362014-09-02 17:58:21 -0700186 if (ncm->type >= NSS_IPV6_MAX_MSG_TYPES) {
Sol Kavy879eb8b2014-04-07 19:11:31 -0700187 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
188 return NSS_TX_FAILURE;
189 }
190
191 if (ncm->len > sizeof(struct nss_ipv6_msg)) {
192 nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
193 return NSS_TX_FAILURE;
194 }
195
Pamidipati, Vijayb6e38842014-09-16 10:26:05 +0530196 nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700197 if (unlikely(!nbuf)) {
198 spin_lock_bh(&nss_ctx->nss_top->stats_lock);
199 nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]++;
200 spin_unlock_bh(&nss_ctx->nss_top->stats_lock);
201 nss_warning("%p: msg dropped as command allocation failed", nss_ctx);
202 return NSS_TX_FAILURE;
203 }
204
205 /*
206 * Copy the message to our skb.
207 */
208 nim2 = (struct nss_ipv6_msg *)skb_put(nbuf, sizeof(struct nss_ipv6_msg));
209 memcpy(nim2, nim, sizeof(struct nss_ipv6_msg));
210
211 status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
212 if (status != NSS_CORE_STATUS_SUCCESS) {
Pamidipati, Vijayb6e38842014-09-16 10:26:05 +0530213 dev_kfree_skb_any(nbuf);
Sol Kavy879eb8b2014-04-07 19:11:31 -0700214 nss_warning("%p: Unable to enqueue 'Destroy IPv6' rule\n", nss_ctx);
215 return NSS_TX_FAILURE;
216 }
217
218 nss_hal_send_interrupt(nss_ctx->nmap, nss_ctx->h2n_desc_rings[NSS_IF_CMD_QUEUE].desc_ring.int_bit,
219 NSS_REGS_H2N_INTR_STATUS_DATA_COMMAND_QUEUE);
220
221 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
222 return NSS_TX_SUCCESS;
223}
224
225/*
226 **********************************
227 Register/Unregister/Miscellaneous APIs
228 **********************************
229 */
230
231/*
232 * nss_ipv6_notify_register()
233 * Register to received IPv6 events.
234 *
235 * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv6 on any core?
236 */
237struct nss_ctx_instance *nss_ipv6_notify_register(nss_ipv6_msg_callback_t cb, void *app_data)
238{
239 /*
240 * TODO: We need to have a new array in support of the new API
241 * TODO: If we use a per-context array, we would move the array into nss_ctx based.
242 */
243 nss_top_main.ipv6_callback = cb;
244 nss_top_main.ipv6_ctx = app_data;
245 return &nss_top_main.nss[nss_top_main.ipv6_handler_id];
246}
247
248/*
249 * nss_ipv6_notify_unregister()
250 * Unregister to received IPv6 events.
251 *
252 * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv6 on any core?
253 */
254void nss_ipv6_notify_unregister(void)
255{
256 nss_top_main.ipv6_callback = NULL;
257}
258
259/*
260 * nss_ipv6_get_mgr()
261 *
262 * TODO: This only suppports a single ipv6, do we ever want to support more?
263 */
264struct nss_ctx_instance *nss_ipv6_get_mgr(void)
265{
266 return (void *)&nss_top_main.nss[nss_top_main.ipv6_handler_id];
267}
268
269/*
270 * nss_ipv6_register_handler()
271 * Register our handler to receive messages for this interface
272 */
273void nss_ipv6_register_handler()
274{
275 if (nss_core_register_handler(NSS_IPV6_RX_INTERFACE, nss_ipv6_rx_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) {
276 nss_warning("IPv6 handler failed to register");
277 }
278}
279
Vijay Dewangan9db18752014-09-15 16:25:01 -0700280/*
281 * nss_ipv6_conn_cfg_callback()
282 * call back function for the ipv6 connection configuration handler
283 */
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700284static void nss_ipv6_conn_cfg_callback(void *app_data, struct nss_ipv6_msg *nim)
Vijay Dewangan9db18752014-09-15 16:25:01 -0700285{
286 if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700287 /*
288 * Error, hence we are not updating the nss_ipv4_conn_cfg
289 * Restore the current_value to its previous state
290 */
Vijay Dewangan488e5372014-12-29 21:40:11 -0800291 i6cfgp.response = NSS_FAILURE;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700292 complete(&i6cfgp.complete);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700293 return;
294 }
295
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700296 /*
297 * Sucess at NSS FW, hence updating nss_ipv4_conn_cfg, with the valid value
298 * saved at the sysctl handler.
299 */
Vijay Dewangan9db18752014-09-15 16:25:01 -0700300 nss_info("IPv6 connection configuration success: %d\n", nim->cm.error);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800301 i6cfgp.response = NSS_SUCCESS;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700302 complete(&i6cfgp.complete);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700303}
304
305
306/*
307 * nss_ipv6_conn_cfg_handler()
308 * Sets the number of connections for IPv6
309 */
310static int nss_ipv6_conn_cfg_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
311{
312 struct nss_top_instance *nss_top = &nss_top_main;
313 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
314 struct nss_ipv6_msg nim;
315 struct nss_ipv6_rule_conn_cfg_msg *nirccm;
316 nss_tx_status_t nss_tx_status;
Vijay Dewangan488e5372014-12-29 21:40:11 -0800317 int ret = NSS_FAILURE;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700318 uint32_t sum_of_conn;
319
320 /*
321 * Acquiring semaphore
322 */
323 down(&i6cfgp.sem);
324
325 /*
326 * Take a snapshot of the current value
327 */
328 i6cfgp.current_value = nss_ipv6_conn_cfg;
329
330 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
331 if (ret || (!write)) {
332 up(&i6cfgp.sem);
333 return ret;
334 }
Vijay Dewangan9db18752014-09-15 16:25:01 -0700335
336 /*
337 * Specifications for input
338 * 1) The input should be power of 2.
339 * 2) Input for ipv4 and ipv6 sum togther should not exceed 8k
340 * 3) Min. value should be at leat 256 connections. This is the
341 * minimum connections we will support for each of them.
342 */
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700343 sum_of_conn = nss_ipv4_conn_cfg + nss_ipv6_conn_cfg;
344 if ((nss_ipv6_conn_cfg & NSS_NUM_CONN_QUANTA_MASK) ||
345 (sum_of_conn > NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6) ||
346 (nss_ipv6_conn_cfg < NSS_MIN_NUM_CONN)) {
Vijay Dewangan9db18752014-09-15 16:25:01 -0700347 nss_warning("%p: input supported connections (%d) does not adhere\
348 specifications\n1) not power of 2,\n2) is less than \
349 min val: %d, OR\n IPv4/6 total exceeds %d\n",
350 nss_ctx,
351 nss_ipv6_conn_cfg,
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700352 NSS_MIN_NUM_CONN,
353 NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6);
Stephen Wang06761022015-03-03 16:38:42 -0800354 goto failure;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700355 }
356
Vijay Dewangan9db18752014-09-15 16:25:01 -0700357
358 nss_info("%p: IPv6 supported connections: %d\n", nss_ctx, nss_ipv6_conn_cfg);
359
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700360 nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_CONN_CFG_RULE_MSG,
Sundarajan Srinivasan30a53d42015-01-30 10:52:08 -0800361 sizeof(struct nss_ipv6_rule_conn_cfg_msg), nss_ipv6_conn_cfg_callback, NULL);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700362
363 nirccm = &nim.msg.rule_conn_cfg;
364 nirccm->num_conn = htonl(nss_ipv6_conn_cfg);
365 nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
366
367 if (nss_tx_status != NSS_TX_SUCCESS) {
368 nss_warning("%p: nss_tx error setting IPv6 Connections: %d\n",
369 nss_ctx,
370 nss_ipv6_conn_cfg);
Stephen Wang06761022015-03-03 16:38:42 -0800371 goto failure;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700372 }
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700373
374 /*
375 * Blocking call, wait till we get ACK for this msg.
376 */
377 ret = wait_for_completion_timeout(&i6cfgp.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
378 if (ret == 0) {
379 nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
Stephen Wang06761022015-03-03 16:38:42 -0800380 goto failure;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700381 }
382
383 /*
384 * ACK/NACK received from NSS FW
385 * If ACK: Callback function will update nss_ipv4_conn_cfg with
386 * i6cfgp.num_conn_valid, which holds the user input
387 */
Vijay Dewangan488e5372014-12-29 21:40:11 -0800388 if (NSS_FAILURE == i6cfgp.response) {
Stephen Wang06761022015-03-03 16:38:42 -0800389 goto failure;
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700390 }
391
392 up(&i6cfgp.sem);
Vijay Dewangan488e5372014-12-29 21:40:11 -0800393 return NSS_SUCCESS;
Stephen Wang06761022015-03-03 16:38:42 -0800394
395failure:
396 /*
397 * Restore the current_value to its previous state
398 */
399 nss_ipv6_conn_cfg = i6cfgp.current_value;
400 up(&i6cfgp.sem);
401 return NSS_FAILURE;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700402}
403
404static ctl_table nss_ipv6_table[] = {
405 {
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700406 .procname = "ipv6_conn",
407 .data = &nss_ipv6_conn_cfg,
408 .maxlen = sizeof(int),
409 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700410 .proc_handler = &nss_ipv6_conn_cfg_handler,
411 },
412 { }
413};
414
415static ctl_table nss_ipv6_dir[] = {
416 {
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700417 .procname = "ipv6cfg",
418 .mode = 0555,
419 .child = nss_ipv6_table,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700420 },
421 { }
422};
423
424static ctl_table nss_ipv6_root_dir[] = {
425 {
426 .procname = "nss",
427 .mode = 0555,
428 .child = nss_ipv6_dir,
429 },
430 { }
431};
432
433static ctl_table nss_ipv6_root[] = {
434 {
435 .procname = "dev",
436 .mode = 0555,
437 .child = nss_ipv6_root_dir,
438 },
439 { }
440};
441
442static struct ctl_table_header *nss_ipv6_header;
443
444/*
445 * nss_ipv6_register_sysctl()
446 * Register sysctl specific to ipv4
447 */
448void nss_ipv6_register_sysctl(void)
449{
450 /*
451 * Register sysctl table.
452 */
453 nss_ipv6_header = register_sysctl_table(nss_ipv6_root);
Vijay Dewangan4861f4e2014-10-14 16:56:35 -0700454 sema_init(&i6cfgp.sem, 1);
455 init_completion(&i6cfgp.complete);
456 i6cfgp.current_value = nss_ipv6_conn_cfg;
Vijay Dewangan9db18752014-09-15 16:25:01 -0700457}
458
459/*
460 * nss_ipv6_unregister_sysctl()
461 * Unregister sysctl specific to ipv4
462 */
463void nss_ipv6_unregister_sysctl(void)
464{
465 /*
466 * Unregister sysctl table.
467 */
468 if (nss_ipv6_header) {
469 unregister_sysctl_table(nss_ipv6_header);
470 }
471}
472
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700473/*
474 * nss_ipv6_msg_init()
475 * Initialize IPv6 message.
476 */
477void 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 -0800478 nss_ipv6_msg_callback_t cb, void *app_data)
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700479{
480 nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data);
481}
482
Sol Kavy879eb8b2014-04-07 19:11:31 -0700483EXPORT_SYMBOL(nss_ipv6_tx);
484EXPORT_SYMBOL(nss_ipv6_notify_register);
485EXPORT_SYMBOL(nss_ipv6_notify_unregister);
486EXPORT_SYMBOL(nss_ipv6_get_mgr);
487EXPORT_SYMBOL(nss_ipv6_register_handler);
Vijay Dewangan9db18752014-09-15 16:25:01 -0700488EXPORT_SYMBOL(nss_ipv6_register_sysctl);
489EXPORT_SYMBOL(nss_ipv6_unregister_sysctl);
Sundarajan Srinivasan02e6c2b2014-10-06 11:51:12 -0700490EXPORT_SYMBOL(nss_ipv6_msg_init);