blob: af109c35974462443487a3f60cef16daf60afea8 [file] [log] [blame]
Radhakrishna Jiguru1c9b2252013-08-27 23:57:48 +05301/*
2 **************************************************************************
Radha krishna Simha Jiguru68d0cbc2019-02-15 00:19:21 +05303 * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
Radhakrishna Jiguru1c9b2252013-08-27 23:57:48 +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 */
Abhishek Rastogibc74e432013-04-02 10:28:22 +053016
17/*
18 * nss_init.c
19 * NSS init APIs
20 *
21 */
Abhishek Rastogibc74e432013-04-02 10:28:22 +053022#include "nss_core.h"
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080023#if (NSS_PM_SUPPORT == 1)
Pamidipati, Vijay7f413b52013-09-24 19:07:12 +053024#include "nss_pm.h"
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080025#endif
Abhishek Rastogi9da47472014-03-18 19:46:15 +053026#include "nss_tx_rx_common.h"
Stephen Wang38e89bc2014-11-06 11:34:45 -080027#include "nss_data_plane.h"
Stephen Wang1f6ad492016-01-27 23:42:06 -080028#include "nss_capwap.h"
Pamidipati, Vijay7f413b52013-09-24 19:07:12 +053029
Abhishek Rastogibc74e432013-04-02 10:28:22 +053030#include <nss_hal.h>
31
32#include <linux/module.h>
33#include <linux/platform_device.h>
wthomas442c7972013-08-05 14:28:17 -070034#include <linux/proc_fs.h>
35#include <linux/device.h>
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080036
37#if (NSS_DT_SUPPORT == 1)
Stephen Wang463f1cf2016-03-29 15:25:51 -070038#if (NSS_FABRIC_SCALING_SUPPORT == 1)
Stephen Wang8ffd17f2016-03-07 14:03:40 -080039#include <linux/fab_scaling.h>
Stephen Wang1017ad12016-03-14 10:18:06 -070040#endif
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080041#include <linux/of.h>
42#include <linux/of_net.h>
43#include <linux/of_irq.h>
44#include <linux/of_address.h>
45#include <linux/reset.h>
46#else
Abhishek Rastogibc74e432013-04-02 10:28:22 +053047#include <mach/msm_nss.h>
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080048#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +053049
wthomas442c7972013-08-05 14:28:17 -070050#include <linux/sysctl.h>
51#include <linux/regulator/consumer.h>
Thomas Wufb6a6842013-10-23 13:14:27 -070052#include <linux/clk.h>
wthomas442c7972013-08-05 14:28:17 -070053
Abhishek Rastogibc74e432013-04-02 10:28:22 +053054/*
55 * Global declarations
56 */
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +053057int nss_ctl_redirect __read_mostly = 0;
Sakthi Vignesh Radhakrishnanaf39aad2014-03-31 11:31:03 -070058int nss_ctl_debug __read_mostly = 0;
Saurabh Misra96998db2014-07-10 12:15:48 -070059int nss_ctl_logbuf __read_mostly = 0;
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -080060int nss_jumbo_mru __read_mostly = 0;
61int nss_paged_mode __read_mostly = 0;
Casey Chen56c13632018-09-10 17:05:03 -070062#if (NSS_SKB_REUSE_SUPPORT == 1)
63int nss_max_reuse __read_mostly = PAGE_SIZE;
64#endif
Radha krishna Simha Jiguru28a0a252015-08-04 16:34:09 +053065int nss_skip_nw_process = 0x0;
66module_param(nss_skip_nw_process, int, S_IRUGO);
Abhishek Rastogibc74e432013-04-02 10:28:22 +053067
68/*
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +053069 * PM client handle
70 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080071#if (NSS_PM_SUPPORT == 1)
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +053072static void *pm_client;
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080073#endif
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +053074
75/*
wthomas626147f2013-09-18 13:12:40 -070076 * Handler to send NSS messages
77 */
Thomas Wufb6a6842013-10-23 13:14:27 -070078struct clk *nss_core0_clk;
Thomas Wu63bcff62017-03-20 11:44:41 -070079struct clk *nss_core1_clk;
wthomas626147f2013-09-18 13:12:40 -070080
81/*
Thomas Wucd6b35a2015-07-14 10:17:48 -070082 * Handle fabric requests - only on new kernel
83 */
84#if (NSS_DT_SUPPORT == 1)
85struct clk *nss_fab0_clk;
86struct clk *nss_fab1_clk;
87#endif
88
89/*
Abhishek Rastogibc74e432013-04-02 10:28:22 +053090 * Top level nss context structure
91 */
92struct nss_top_instance nss_top_main;
wthomas442c7972013-08-05 14:28:17 -070093struct nss_cmd_buffer nss_cmd_buf;
wthomas626147f2013-09-18 13:12:40 -070094struct nss_runtime_sampling nss_runtime_samples;
95struct workqueue_struct *nss_wq;
96
97/*
98 * Work Queue to handle messages to Kernel
99 */
100nss_work_t *nss_work;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530101
Arunkumar T79990cb2015-06-05 10:53:16 +0530102extern struct of_device_id nss_dt_ids[];
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530103
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530104/*
105 * nss_probe()
Cemil Coskun9165c762017-12-04 14:35:24 -0800106 * HLOS device probe callback
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530107 */
Ram Chandra Jangir6577f382016-05-31 12:16:28 +0530108static inline int nss_probe(struct platform_device *nss_dev)
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530109{
Arunkumar T79990cb2015-06-05 10:53:16 +0530110 return nss_hal_probe(nss_dev);
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530111}
112
113/*
114 * nss_remove()
Cemil Coskun9165c762017-12-04 14:35:24 -0800115 * HLOS device remove callback
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530116 */
Ram Chandra Jangir6577f382016-05-31 12:16:28 +0530117static inline int nss_remove(struct platform_device *nss_dev)
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530118{
Arunkumar T79990cb2015-06-05 10:53:16 +0530119 return nss_hal_remove(nss_dev);
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530120}
121
Stephen Wang90c67de2016-04-26 15:15:59 -0700122#if (NSS_DT_SUPPORT == 1)
123/*
124 * Platform Device ID for NSS core.
125 */
126struct of_device_id nss_dt_ids[] = {
127 { .compatible = "qcom,nss" },
128 { .compatible = "qcom,nss0" },
129 { .compatible = "qcom,nss1" },
130 {},
131};
132MODULE_DEVICE_TABLE(of, nss_dt_ids);
133#endif
134
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530135/*
136 * nss_driver
137 * Platform driver structure for NSS
138 */
139struct platform_driver nss_driver = {
140 .probe = nss_probe,
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800141 .remove = nss_remove,
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530142 .driver = {
143 .name = "qca-nss",
144 .owner = THIS_MODULE,
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800145#if (NSS_DT_SUPPORT == 1)
146 .of_match_table = of_match_ptr(nss_dt_ids),
147#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530148 },
149};
150
Arunkumar T28b2d742015-06-16 22:15:58 +0530151#if (NSS_FREQ_SCALE_SUPPORT == 1)
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530152/*
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530153 * nss_reset_frequency_stats_samples()
154 * Reset all frequency sampling state when auto scaling is turned off.
155 */
Thomas Wud6af3772017-09-01 13:42:28 -0700156static void nss_reset_frequency_stats_samples(void)
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530157{
158 nss_runtime_samples.buffer_index = 0;
159 nss_runtime_samples.sum = 0;
160 nss_runtime_samples.average = 0;
161 nss_runtime_samples.sample_count = 0;
162 nss_runtime_samples.message_rate_limit = 0;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530163 nss_runtime_samples.freq_scale_rate_limit_down = 0;
164}
165
166/*
wthomas442c7972013-08-05 14:28:17 -0700167 * nss_current_freq_handler()
168 * Handle Userspace Frequency Change Requests
169 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700170static int nss_current_freq_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
wthomas442c7972013-08-05 14:28:17 -0700171{
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800172 int ret, i;
wthomas626147f2013-09-18 13:12:40 -0700173
174 BUG_ON(!nss_wq);
wthomas442c7972013-08-05 14:28:17 -0700175
176 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
177
Thomas Wuc151f2e2015-09-08 10:59:44 -0700178 if (!*lenp || (*ppos && !write)) {
wthomas626147f2013-09-18 13:12:40 -0700179 printk("Frequency Set to %d\n", nss_cmd_buf.current_freq);
Thomas Wuc151f2e2015-09-08 10:59:44 -0700180 *lenp = 0;
wthomasd39fa822013-08-22 16:44:23 -0700181 return ret;
wthomas442c7972013-08-05 14:28:17 -0700182 }
wthomasd39fa822013-08-22 16:44:23 -0700183
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800184 /*
185 * Check if frequency exists in frequency Table
186 */
187 i = 0;
Thomas Wu7132bd32015-05-07 15:03:06 -0700188 while (i < NSS_FREQ_MAX_SCALE) {
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800189 if (nss_runtime_samples.freq_scale[i].frequency == nss_cmd_buf.current_freq) {
190 break;
191 }
192 i++;
193 }
Thomas Wu7132bd32015-05-07 15:03:06 -0700194 if (i == NSS_FREQ_MAX_SCALE) {
Thomas Wufb6a6842013-10-23 13:14:27 -0700195 printk("Frequency not found. Please check Frequency Table\n");
Thomas Wub7683af2016-07-07 14:19:09 -0700196 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
wthomas626147f2013-09-18 13:12:40 -0700197 return ret;
wthomasd39fa822013-08-22 16:44:23 -0700198 }
199
Thomas Wub7683af2016-07-07 14:19:09 -0700200 /*
201 * Turn off Auto Scale
202 */
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800203 nss_cmd_buf.auto_scale = 0;
204 nss_runtime_samples.freq_scale_ready = 0;
Thomas Wub7683af2016-07-07 14:19:09 -0700205 nss_runtime_samples.freq_scale_index = i;
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800206
Thomas Wu7409bce2014-05-21 10:56:07 -0700207 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
wthomas626147f2013-09-18 13:12:40 -0700208 if (!nss_work) {
209 nss_info("NSS Freq WQ kmalloc fail");
210 return ret;
211 }
Thomas Wud6af3772017-09-01 13:42:28 -0700212 INIT_WORK((struct work_struct *)nss_work, nss_hal_wq_function);
wthomas626147f2013-09-18 13:12:40 -0700213 nss_work->frequency = nss_cmd_buf.current_freq;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530214 nss_work->stats_enable = 0;
215
Thomas Wub7683af2016-07-07 14:19:09 -0700216 /*
217 * Ensure we start with a fresh set of samples later
218 */
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530219 nss_reset_frequency_stats_samples();
220
wthomas626147f2013-09-18 13:12:40 -0700221 queue_work(nss_wq, (struct work_struct *)nss_work);
222
wthomas442c7972013-08-05 14:28:17 -0700223 return ret;
224}
225
226/*
227 * nss_auto_scale_handler()
228 * Enables or Disable Auto Scaling
229 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700230static int nss_auto_scale_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
wthomas442c7972013-08-05 14:28:17 -0700231{
232 int ret;
233
234 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
235
Thomas Wuc151f2e2015-09-08 10:59:44 -0700236 if (!*lenp || (*ppos && !write)) {
wthomas626147f2013-09-18 13:12:40 -0700237 return ret;
238 }
239
Thomas Wufb6a6842013-10-23 13:14:27 -0700240 if (nss_cmd_buf.auto_scale != 1) {
wthomas626147f2013-09-18 13:12:40 -0700241 /*
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530242 * Is auto scaling currently enabled? If so, send the command to
243 * disable stats reporting to NSS
wthomas626147f2013-09-18 13:12:40 -0700244 */
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530245 if (nss_runtime_samples.freq_scale_ready != 0) {
246 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
Thomas Wu7409bce2014-05-21 10:56:07 -0700247 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530248 if (!nss_work) {
249 nss_info("NSS Freq WQ kmalloc fail");
250 return ret;
251 }
Thomas Wud6af3772017-09-01 13:42:28 -0700252 INIT_WORK((struct work_struct *)nss_work, nss_hal_wq_function);
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530253 nss_work->frequency = nss_cmd_buf.current_freq;
254 nss_work->stats_enable = 0;
255 queue_work(nss_wq, (struct work_struct *)nss_work);
256 nss_runtime_samples.freq_scale_ready = 0;
257
258 /*
259 * The current samples would be stale later when scaling is
260 * enabled again, hence reset them
261 */
262 nss_reset_frequency_stats_samples();
263 }
Thomas Wufb6a6842013-10-23 13:14:27 -0700264 return ret;
wthomas626147f2013-09-18 13:12:40 -0700265 }
wthomas442c7972013-08-05 14:28:17 -0700266
Thomas Wufb6a6842013-10-23 13:14:27 -0700267 /*
Thomas Wufb6a6842013-10-23 13:14:27 -0700268 * Setup default values - Middle of Freq Scale Band
269 */
270 nss_runtime_samples.freq_scale_index = 1;
Thomas Wubfe3ffc2019-07-19 16:09:52 -0700271 nss_runtime_samples.sample_count = 0;
272 nss_runtime_samples.initialized = 0;
Thomas Wufb6a6842013-10-23 13:14:27 -0700273 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
274
Thomas Wu7409bce2014-05-21 10:56:07 -0700275 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
Thomas Wufb6a6842013-10-23 13:14:27 -0700276 if (!nss_work) {
277 nss_info("NSS Freq WQ kmalloc fail");
278 return ret;
279 }
Thomas Wud6af3772017-09-01 13:42:28 -0700280 INIT_WORK((struct work_struct *)nss_work, nss_hal_wq_function);
Thomas Wufb6a6842013-10-23 13:14:27 -0700281 nss_work->frequency = nss_cmd_buf.current_freq;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530282 nss_work->stats_enable = 1;
Thomas Wufb6a6842013-10-23 13:14:27 -0700283 queue_work(nss_wq, (struct work_struct *)nss_work);
284
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800285 nss_cmd_buf.auto_scale = 0;
Thomas Wufb6a6842013-10-23 13:14:27 -0700286 nss_runtime_samples.freq_scale_ready = 1;
287
wthomas442c7972013-08-05 14:28:17 -0700288 return ret;
289}
290
291/*
292 * nss_get_freq_table_handler()
293 * Display Support Freq and Ex how to Change.
294 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700295static int nss_get_freq_table_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
wthomas442c7972013-08-05 14:28:17 -0700296{
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800297 int ret, i;
wthomas442c7972013-08-05 14:28:17 -0700298
299 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
300
Thomas Wuc151f2e2015-09-08 10:59:44 -0700301 if (write) {
302 return ret;
303 }
304
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800305 printk("Frequency Supported - ");
Thomas Wuc151f2e2015-09-08 10:59:44 -0700306
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800307 i = 0;
Thomas Wu7132bd32015-05-07 15:03:06 -0700308 while (i < NSS_FREQ_MAX_SCALE) {
Thomas Wu6a48ac92017-11-03 10:48:04 -0700309 printk("%d Hz ", nss_runtime_samples.freq_scale[i].frequency);
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800310 i++;
Thomas Wu0a0a9c92013-11-21 15:28:19 -0800311 }
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800312 printk("\n");
wthomas442c7972013-08-05 14:28:17 -0700313
Thomas Wuc151f2e2015-09-08 10:59:44 -0700314 *lenp = 0;
wthomas442c7972013-08-05 14:28:17 -0700315 return ret;
316}
317
318/*
Thomas Wu05495be2013-12-19 14:24:24 -0800319 * nss_get_average_inst_handler()
320 * Display AVG Inst Per Ms.
321 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700322static int nss_get_average_inst_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
Thomas Wu05495be2013-12-19 14:24:24 -0800323{
324 int ret;
325
326 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
327
Thomas Wuc151f2e2015-09-08 10:59:44 -0700328 if (write) {
329 return ret;
Thomas Wu05495be2013-12-19 14:24:24 -0800330 }
331
Thomas Wuc151f2e2015-09-08 10:59:44 -0700332 printk("Current Inst Per Ms %x\n", nss_runtime_samples.average);
333
334 *lenp = 0;
Thomas Wu05495be2013-12-19 14:24:24 -0800335 return ret;
336}
Arunkumar T28b2d742015-06-16 22:15:58 +0530337#endif
Thomas Wu05495be2013-12-19 14:24:24 -0800338
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800339#if (NSS_FW_DBG_SUPPORT == 1)
Thomas Wu05495be2013-12-19 14:24:24 -0800340/*
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530341 * nss_debug_handler()
342 * Enable NSS debug output
343 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700344static int nss_debug_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530345{
346 int ret;
347
348 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
349 if (!ret) {
350 if ((write) && (nss_ctl_debug != 0)) {
351 printk("Enabling NSS SPI Debug\n");
352 nss_hal_debug_enable();
353 }
354 }
355
356 return ret;
357}
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800358#endif
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530359
360/*
Thomas Wu52075f42014-02-06 16:32:42 -0800361 * nss_coredump_handler()
362 * Send Signal To Coredump NSS Cores
363 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700364static int nss_coredump_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
Thomas Wu52075f42014-02-06 16:32:42 -0800365{
Guojun Jin32a3c6d2015-05-06 12:27:52 -0700366 struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[NSS_CORE_0];
Thomas Wu52075f42014-02-06 16:32:42 -0800367 int ret;
368
369 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
370 if (!ret) {
Guojun Jin244ecab2017-03-16 16:04:25 -0700371 /*
372 * if nss_cmd_buf.coredump is not 0 or 1, panic will be disabled
373 * when NSS FW crashes, so OEM/ODM have a chance to use mdump
374 * to dump crash dump (coredump) and send dump to us for analysis.
375 */
376 if ((write) && (nss_ctl_debug != 0) && nss_cmd_buf.coredump == 1) {
Thomas Wu52075f42014-02-06 16:32:42 -0800377 printk("Coredumping to DDR\n");
Stephen Wang90c67de2016-04-26 15:15:59 -0700378 nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_TRIGGER_COREDUMP);
Thomas Wu52075f42014-02-06 16:32:42 -0800379 }
380 }
381
382 return ret;
383}
384
385/*
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800386 * nss_jumbo_mru_handler()
387 * Sysctl to modify nss_jumbo_mru
388 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700389static int nss_jumbo_mru_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800390{
391 int ret;
392
393 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
394 if (ret) {
395 return ret;
396 }
397
398 if (write) {
399 nss_core_set_jumbo_mru(nss_jumbo_mru);
400 nss_info("jumbo_mru set to %d\n", nss_jumbo_mru);
401 }
402
403 return ret;
404}
405
406/* nss_paged_mode_handler()
407 * Sysctl to modify nss_paged_mode.
408 */
409
Stephen Wang52e6d342016-03-29 15:02:33 -0700410static int nss_paged_mode_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800411{
412 int ret;
413
414 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
415 if (ret) {
416 return ret;
417 }
418
419 if (write) {
420 nss_core_set_paged_mode(nss_paged_mode);
421 nss_info("paged_mode set to %d\n", nss_paged_mode);
422 }
423
424 return ret;
425}
426
Casey Chen56c13632018-09-10 17:05:03 -0700427#if (NSS_SKB_REUSE_SUPPORT == 1)
428/*
429 * nss_get_min_reuse_handler()
430 * Sysctl to get min reuse sizes
431 */
432static int nss_get_min_reuse_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
433{
434 int ret;
435 struct nss_ctx_instance *nss_ctx = NULL;
436 uint32_t core_id;
437
438 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
439 if (ret) {
440 return ret;
441 }
442
443 printk("Min SKB reuse sizes - ");
444
445 for (core_id = 0; core_id < NSS_CORE_MAX; core_id++) {
446 nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[core_id];
447 printk("core %d: %d ", core_id, nss_core_get_min_reuse(nss_ctx));
448 }
449
450 printk("\n");
451 *lenp = 0;
452 return ret;
453}
454
455/*
456 * nss_max_reuse_handler()
457 * Sysctl to modify nss_max_reuse
458 */
459static int nss_max_reuse_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
460{
461 int ret;
462
463 nss_max_reuse = nss_core_get_max_reuse();
464 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
465 if (ret) {
466 return ret;
467 }
468
469 if (write) {
470 nss_core_set_max_reuse(nss_max_reuse);
471 nss_info("max_reuse set to %d\n", nss_max_reuse);
472 }
473
474 return ret;
475}
476
477/*
478 * sysctl-tuning for NSS driver SKB reuse
479 */
480static struct ctl_table nss_skb_reuse_table[] = {
481 {
482 .procname = "min_sizes",
483 .data = NULL,
484 .maxlen = sizeof(int),
485 .mode = 0644,
486 .proc_handler = &nss_get_min_reuse_handler,
487 },
488 {
489 .procname = "max_size",
490 .data = &nss_max_reuse,
491 .maxlen = sizeof(int),
492 .mode = 0644,
493 .proc_handler = &nss_max_reuse_handler,
494 },
495 { }
496};
497#endif
498
Arunkumar T28b2d742015-06-16 22:15:58 +0530499#if (NSS_FREQ_SCALE_SUPPORT == 1)
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800500/*
wthomas442c7972013-08-05 14:28:17 -0700501 * sysctl-tuning infrastructure.
502 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700503static struct ctl_table nss_freq_table[] = {
wthomas442c7972013-08-05 14:28:17 -0700504 {
505 .procname = "current_freq",
506 .data = &nss_cmd_buf.current_freq,
507 .maxlen = sizeof(int),
508 .mode = 0644,
509 .proc_handler = &nss_current_freq_handler,
510 },
511 {
512 .procname = "freq_table",
513 .data = &nss_cmd_buf.max_freq,
514 .maxlen = sizeof(int),
515 .mode = 0644,
516 .proc_handler = &nss_get_freq_table_handler,
517 },
518 {
519 .procname = "auto_scale",
520 .data = &nss_cmd_buf.auto_scale,
521 .maxlen = sizeof(int),
522 .mode = 0644,
523 .proc_handler = &nss_auto_scale_handler,
524 },
Thomas Wu05495be2013-12-19 14:24:24 -0800525 {
526 .procname = "inst_per_sec",
527 .data = &nss_cmd_buf.average_inst,
528 .maxlen = sizeof(int),
529 .mode = 0644,
530 .proc_handler = &nss_get_average_inst_handler,
531 },
wthomas442c7972013-08-05 14:28:17 -0700532 { }
533};
Arunkumar T28b2d742015-06-16 22:15:58 +0530534#endif
wthomas442c7972013-08-05 14:28:17 -0700535
Stephen Wang52e6d342016-03-29 15:02:33 -0700536static struct ctl_table nss_general_table[] = {
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530537 {
538 .procname = "redirect",
539 .data = &nss_ctl_redirect,
540 .maxlen = sizeof(int),
541 .mode = 0644,
Cemil Coskun9165c762017-12-04 14:35:24 -0800542 .proc_handler = proc_dointvec,
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530543 },
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800544#if (NSS_FW_DBG_SUPPORT == 1)
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530545 {
546 .procname = "debug",
547 .data = &nss_ctl_debug,
548 .maxlen = sizeof(int),
549 .mode = 0644,
Cemil Coskun9165c762017-12-04 14:35:24 -0800550 .proc_handler = &nss_debug_handler,
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530551 },
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800552#endif
Thomas Wu52075f42014-02-06 16:32:42 -0800553 {
554 .procname = "coredump",
555 .data = &nss_cmd_buf.coredump,
556 .maxlen = sizeof(int),
557 .mode = 0644,
Cemil Coskun9165c762017-12-04 14:35:24 -0800558 .proc_handler = &nss_coredump_handler,
Thomas Wu52075f42014-02-06 16:32:42 -0800559 },
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530560 {
Saurabh Misra96998db2014-07-10 12:15:48 -0700561 .procname = "logbuf",
562 .data = &nss_ctl_logbuf,
563 .maxlen = sizeof(int),
564 .mode = 0644,
Cemil Coskun9165c762017-12-04 14:35:24 -0800565 .proc_handler = &nss_logbuffer_handler,
Saurabh Misra96998db2014-07-10 12:15:48 -0700566 },
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800567 {
568 .procname = "jumbo_mru",
569 .data = &nss_jumbo_mru,
570 .maxlen = sizeof(int),
571 .mode = 0644,
572 .proc_handler = &nss_jumbo_mru_handler,
573 },
574 {
575 .procname = "paged_mode",
576 .data = &nss_paged_mode,
577 .maxlen = sizeof(int),
578 .mode = 0644,
579 .proc_handler = &nss_paged_mode_handler,
580 },
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530581 { }
582};
583
Casey Chen56c13632018-09-10 17:05:03 -0700584static struct ctl_table nss_init_dir[] = {
Arunkumar T28b2d742015-06-16 22:15:58 +0530585#if (NSS_FREQ_SCALE_SUPPORT == 1)
wthomas442c7972013-08-05 14:28:17 -0700586 {
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530587 .procname = "clock",
588 .mode = 0555,
589 .child = nss_freq_table,
590 },
Arunkumar T28b2d742015-06-16 22:15:58 +0530591#endif
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530592 {
593 .procname = "general",
594 .mode = 0555,
595 .child = nss_general_table,
wthomas442c7972013-08-05 14:28:17 -0700596 },
Casey Chen56c13632018-09-10 17:05:03 -0700597#if (NSS_SKB_REUSE_SUPPORT == 1)
598 {
599 .procname = "skb_reuse",
600 .mode = 0555,
601 .child = nss_skb_reuse_table,
602 },
603#endif
wthomas442c7972013-08-05 14:28:17 -0700604 { }
605};
606
Stephen Wang52e6d342016-03-29 15:02:33 -0700607static struct ctl_table nss_root_dir[] = {
wthomas442c7972013-08-05 14:28:17 -0700608 {
609 .procname = "nss",
610 .mode = 0555,
Casey Chen56c13632018-09-10 17:05:03 -0700611 .child = nss_init_dir,
wthomas442c7972013-08-05 14:28:17 -0700612 },
613 { }
614};
615
Stephen Wang52e6d342016-03-29 15:02:33 -0700616static struct ctl_table nss_root[] = {
wthomas442c7972013-08-05 14:28:17 -0700617 {
618 .procname = "dev",
619 .mode = 0555,
620 .child = nss_root_dir,
621 },
622 { }
623};
624
625static struct ctl_table_header *nss_dev_header;
626
627/*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530628 * nss_init()
629 * Registers nss driver
630 */
631static int __init nss_init(void)
632{
Radha krishna Simha Jiguru3295b8b2017-03-12 10:54:15 +0530633#if (NSS_DT_SUPPORT == 1)
634 struct device_node *cmn = NULL;
635#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530636 nss_info("Init NSS driver");
637
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800638#if (NSS_DT_SUPPORT == 1)
639 /*
Radha krishna Simha Jiguru3295b8b2017-03-12 10:54:15 +0530640 * Get reference to NSS common device node
641 */
642 cmn = of_find_node_by_name(NULL, "nss-common");
643 if (!cmn) {
644 nss_info_always("qca-nss-drv.ko is loaded for symbol link\n");
645 return 0;
646 }
647 of_node_put(cmn);
648
649 /*
Stephen Wang90c67de2016-04-26 15:15:59 -0700650 * Pick up HAL by target information
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800651 */
Stephen Wang90c67de2016-04-26 15:15:59 -0700652#if defined(NSS_HAL_IPQ806X_SUPPORT)
653 if (of_machine_is_compatible("qcom,ipq8064") || of_machine_is_compatible("qcom,ipq8062")) {
654 nss_top_main.hal_ops = &nss_hal_ipq806x_ops;
Stephen Wang5901def2016-05-09 16:21:03 -0700655 nss_top_main.data_plane_ops = &nss_data_plane_gmac_ops;
Suman Ghosh9f7b3702018-09-21 19:51:40 +0530656 nss_top_main.num_nss = 2;
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800657 }
Stephen Wang90c67de2016-04-26 15:15:59 -0700658#endif
Stephen Wangbe348022016-05-02 17:11:34 -0700659#if defined(NSS_HAL_IPQ807x_SUPPORT)
660 if (of_machine_is_compatible("qcom,ipq807x")) {
661 nss_top_main.hal_ops = &nss_hal_ipq807x_ops;
Stephen Wangdf8323b2016-05-09 22:51:22 -0700662 nss_top_main.data_plane_ops = &nss_data_plane_edma_ops;
Radha krishna Simha Jiguru68d0cbc2019-02-15 00:19:21 +0530663#if defined(NSS_MEM_PROFILE_LOW)
664 nss_top_main.num_nss = 1;
665#else
Suman Ghosh9f7b3702018-09-21 19:51:40 +0530666 nss_top_main.num_nss = 2;
Radha krishna Simha Jiguru68d0cbc2019-02-15 00:19:21 +0530667#endif
Stephen Wangbe348022016-05-02 17:11:34 -0700668 }
669#endif
Suman Ghosh3f940232018-08-17 20:43:03 +0530670#if defined(NSS_HAL_IPQ60XX_SUPPORT)
671 if (of_machine_is_compatible("qcom,ipq6018")) {
672 nss_top_main.hal_ops = &nss_hal_ipq60xx_ops;
673 nss_top_main.data_plane_ops = &nss_data_plane_edma_ops;
Suman Ghosh9f7b3702018-09-21 19:51:40 +0530674 nss_top_main.num_nss = 1;
Suman Ghosh3f940232018-08-17 20:43:03 +0530675 }
676#endif
Stephen Wang90c67de2016-04-26 15:15:59 -0700677#if defined(NSS_HAL_FSM9010_SUPPORT)
678 if (of_machine_is_compatible("qcom,fsm9010")) {
679 nss_top_main.hal_ops = &nss_hal_fsm9010_ops;
Stephen Wang5901def2016-05-09 16:21:03 -0700680 nss_top_main.data_plane_ops = &nss_data_plane_gmac_ops;
Suman Ghosh9f7b3702018-09-21 19:51:40 +0530681 nss_top_main.num_nss = 1;
Stephen Wang90c67de2016-04-26 15:15:59 -0700682 }
683#endif
684 if (!nss_top_main.hal_ops) {
685 nss_info_always("No supported HAL compiled on this platform\n");
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800686 return -EFAULT;
687 }
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800688#else
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530689 /*
Stephen Wang90c67de2016-04-26 15:15:59 -0700690 * For banana, only ipq806x is supported
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530691 */
Stephen Wang90c67de2016-04-26 15:15:59 -0700692 nss_top_main.hal_ops = &nss_hal_ipq806x_ops;
Stephen Wang5901def2016-05-09 16:21:03 -0700693 nss_top_main.data_plane_ops = &nss_data_plane_gmac_ops;
Suman Ghosh9f7b3702018-09-21 19:51:40 +0530694 nss_top_main.num_nss = 2;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530695
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800696#endif /* NSS_DT_SUPPORT */
Stephen Wang90c67de2016-04-26 15:15:59 -0700697 nss_top_main.nss_hal_common_init_done = false;
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800698
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530699 /*
Stephen Wangb42ddc52015-12-17 18:10:35 -0800700 * Initialize data_plane workqueue
701 */
702 if (nss_data_plane_init_delay_work()) {
703 nss_warning("Error initializing nss_data_plane_workqueue\n");
704 return -EFAULT;
705 }
706
707 /*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530708 * Enable spin locks
709 */
710 spin_lock_init(&(nss_top_main.lock));
711 spin_lock_init(&(nss_top_main.stats_lock));
c_athandfde2e912017-01-10 15:40:12 +0530712 mutex_init(&(nss_top_main.wq_lock));
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530713
714 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530715 * Enable NSS statistics
716 */
717 nss_stats_init();
718
719 /*
wthomas442c7972013-08-05 14:28:17 -0700720 * Register sysctl table.
721 */
722 nss_dev_header = register_sysctl_table(nss_root);
723
724 /*
Vijay Dewangan9db18752014-09-15 16:25:01 -0700725 * Registering sysctl for ipv4/6 specific config.
726 */
727 nss_ipv4_register_sysctl();
728 nss_ipv6_register_sysctl();
729
Vijay Dewanganac7efc42015-02-09 16:04:53 -0800730 /*
Stephen Wang49b474b2016-03-25 10:40:30 -0700731 * Registering sysctl for n2h specific config.
Vijay Dewanganac7efc42015-02-09 16:04:53 -0800732 */
Suman Ghosh9f7b3702018-09-21 19:51:40 +0530733 if (nss_top_main.num_nss == 1) {
734 nss_n2h_single_core_register_sysctl();
735 } else {
736 nss_n2h_multi_core_register_sysctl();
737 }
Vijay Dewanganac7efc42015-02-09 16:04:53 -0800738
Vijay Dewangan9db18752014-09-15 16:25:01 -0700739 /*
Cemil Coskun9165c762017-12-04 14:35:24 -0800740 * Registering sysctl for rps specific config.
741 */
742 nss_rps_register_sysctl();
743
744 /*
Cemil Coskun497f7ec2018-07-12 14:08:53 -0700745 * Registering sysctl for c2c_tx specific config.
746 */
747 nss_c2c_tx_register_sysctl();
748
749 /*
Sakthi Vignesh Radhakrishnan150c5592019-07-02 10:17:44 -0700750 * Registering sysctl for for printing non zero stats.
751 */
752 nss_stats_register_sysctl();
753
754 /*
Jackson Bockusc2a4e682017-06-23 11:59:29 -0700755 * Register sysctl for project config
756 */
757 nss_project_register_sysctl();
758
759 /*
Amit Gupta1fe4d912019-03-19 15:57:10 +0530760 * Registering sysctl for pppoe specific config.
761 */
762 nss_pppoe_register_sysctl();
763
764 /*
wthomas626147f2013-09-18 13:12:40 -0700765 * Setup Runtime Sample values
766 */
wthomas626147f2013-09-18 13:12:40 -0700767 nss_runtime_samples.freq_scale_index = 1;
768 nss_runtime_samples.freq_scale_ready = 0;
Thomas Wu9681f7e2013-11-06 13:12:57 -0800769 nss_runtime_samples.freq_scale_rate_limit_down = 0;
wthomas626147f2013-09-18 13:12:40 -0700770 nss_runtime_samples.buffer_index = 0;
771 nss_runtime_samples.sum = 0;
772 nss_runtime_samples.sample_count = 0;
773 nss_runtime_samples.average = 0;
774 nss_runtime_samples.message_rate_limit = 0;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530775 nss_runtime_samples.initialized = 0;
wthomas626147f2013-09-18 13:12:40 -0700776
Thomas Wu05495be2013-12-19 14:24:24 -0800777 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
778
wthomas626147f2013-09-18 13:12:40 -0700779 /*
780 * Initial Workqueue
781 */
782 nss_wq = create_workqueue("nss_freq_queue");
783
Thomas Wu0d112192015-04-13 11:37:22 -0700784#if (NSS_PM_SUPPORT == 1)
wthomas626147f2013-09-18 13:12:40 -0700785 /*
Pamidipati, Vijay7f413b52013-09-24 19:07:12 +0530786 * Initialize NSS Bus PM module
787 */
788 nss_pm_init();
789
790 /*
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530791 * Register with Bus driver
792 */
793 pm_client = nss_pm_client_register(NSS_PM_CLIENT_NETAP);
794 if (!pm_client) {
795 nss_warning("Error registering with PM driver");
796 }
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800797#endif
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530798
799 /*
Radha krishna Simha Jiguru7f424d52015-02-10 19:41:01 +0530800 * Initialize mtu size needed as start
801 */
Stephen Wanga428d0b2017-01-12 21:30:01 -0800802 nss_top_main.prev_mtu_sz = ETH_DATA_LEN;
Radha krishna Simha Jiguru7f424d52015-02-10 19:41:01 +0530803
804 /*
Guojun Jin1cb79522015-06-22 22:34:22 -0700805 * register panic handler and timeout control
806 */
807 nss_coredump_notify_register();
808 nss_coredump_init_delay_work();
809
810 /*
Stephen Wang1f6ad492016-01-27 23:42:06 -0800811 * Init capwap
812 */
813 nss_capwap_init();
814
815 /*
Yu Huang6b2f0be2017-10-18 16:11:49 -0700816 * Init QRFS
817 */
818 nss_qrfs_init();
819
820 /*
Cemil Coskun1c9c3922018-01-23 16:21:49 -0800821 * Init c2c_tx
822 */
823 nss_c2c_tx_init();
824
825 /*
Cemil Coskuncdcd1dd2019-01-28 13:35:31 -0800826 * Init pvxlan
827 */
828 nss_pvxlan_init();
829
830 /*
Suman Ghosh85f353a2019-06-03 14:47:32 +0530831 * Init clmap
832 */
833 nss_clmap_init();
834
835 /*
Amit Gupta316729b2016-08-12 12:21:15 +0530836 * INIT ppe on supported platform
837 */
Suman Ghosh3f940232018-08-17 20:43:03 +0530838 if (of_machine_is_compatible("qcom,ipq807x") || of_machine_is_compatible("qcom,ipq6018")) {
Amit Gupta316729b2016-08-12 12:21:15 +0530839 nss_ppe_init();
840 }
841
842 /*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530843 * Register platform_driver
844 */
845 return platform_driver_register(&nss_driver);
846}
847
848/*
849 * nss_cleanup()
850 * Unregisters nss driver
851 */
852static void __exit nss_cleanup(void)
853{
854 nss_info("Exit NSS driver");
wthomas442c7972013-08-05 14:28:17 -0700855
856 if (nss_dev_header)
857 unregister_sysctl_table(nss_dev_header);
858
Vijay Dewangan9db18752014-09-15 16:25:01 -0700859 /*
Vijay Dewangan488e5372014-12-29 21:40:11 -0800860 * Unregister n2h specific sysctl
861 */
Stephen Wang49b474b2016-03-25 10:40:30 -0700862 nss_n2h_unregister_sysctl();
Vijay Dewangan488e5372014-12-29 21:40:11 -0800863
864 /*
Cemil Coskun9165c762017-12-04 14:35:24 -0800865 * Unregister rps specific sysctl
866 */
867 nss_rps_unregister_sysctl();
868
869 /*
Cemil Coskun497f7ec2018-07-12 14:08:53 -0700870 * Unregister c2c_tx specific sysctl
871 */
872 nss_c2c_tx_unregister_sysctl();
873
874 /*
Amit Gupta1fe4d912019-03-19 15:57:10 +0530875 * Unregister pppoe specific sysctl
876 */
877 nss_pppoe_unregister_sysctl();
878
879 /*
Vijay Dewangan9db18752014-09-15 16:25:01 -0700880 * Unregister ipv4/6 specific sysctl
881 */
882 nss_ipv4_unregister_sysctl();
883 nss_ipv6_unregister_sysctl();
884
Suruchi Agarwalcdcb5b42017-07-06 11:08:22 -0700885 /*
886 * Free Memory allocated for connection tables
887 */
888 nss_ipv4_free_conn_tables();
889 nss_ipv6_free_conn_tables();
890
Jackson Bockusc2a4e682017-06-23 11:59:29 -0700891 nss_project_unregister_sysctl();
Stephen Wangb42ddc52015-12-17 18:10:35 -0800892 nss_data_plane_destroy_delay_work();
893
Amit Gupta316729b2016-08-12 12:21:15 +0530894 /*
895 * cleanup ppe on supported platform
896 */
Suman Ghosh3f940232018-08-17 20:43:03 +0530897 if (of_machine_is_compatible("qcom,ipq807x") || of_machine_is_compatible("qcom,ipq6018")) {
Amit Gupta316729b2016-08-12 12:21:15 +0530898 nss_ppe_free();
899 }
900
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530901 platform_driver_unregister(&nss_driver);
902}
903
904module_init(nss_init);
905module_exit(nss_cleanup);
906
907MODULE_DESCRIPTION("QCA NSS Driver");
908MODULE_AUTHOR("Qualcomm Atheros Inc");
909MODULE_LICENSE("Dual BSD/GPL");