blob: 822974633ca7e57df4e840946bf5d60ac3d7da6b [file] [log] [blame]
Radhakrishna Jiguru1c9b2252013-08-27 23:57:48 +05301/*
2 **************************************************************************
Pamidipati, Vijayee9c2972016-01-10 08:13:19 +05303 * Copyright (c) 2013 - 2016, 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;
Radha krishna Simha Jiguru28a0a252015-08-04 16:34:09 +053062int nss_skip_nw_process = 0x0;
63module_param(nss_skip_nw_process, int, S_IRUGO);
Abhishek Rastogibc74e432013-04-02 10:28:22 +053064
65/*
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +053066 * PM client handle
67 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080068#if (NSS_PM_SUPPORT == 1)
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +053069static void *pm_client;
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080070#endif
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +053071
72/*
wthomas626147f2013-09-18 13:12:40 -070073 * Handler to send NSS messages
74 */
Thomas Wufb6a6842013-10-23 13:14:27 -070075struct clk *nss_core0_clk;
wthomas626147f2013-09-18 13:12:40 -070076
77/*
Thomas Wucd6b35a2015-07-14 10:17:48 -070078 * Handle fabric requests - only on new kernel
79 */
80#if (NSS_DT_SUPPORT == 1)
81struct clk *nss_fab0_clk;
82struct clk *nss_fab1_clk;
83#endif
84
85/*
Abhishek Rastogibc74e432013-04-02 10:28:22 +053086 * Top level nss context structure
87 */
88struct nss_top_instance nss_top_main;
wthomas442c7972013-08-05 14:28:17 -070089struct nss_cmd_buffer nss_cmd_buf;
wthomas626147f2013-09-18 13:12:40 -070090struct nss_runtime_sampling nss_runtime_samples;
91struct workqueue_struct *nss_wq;
92
93/*
94 * Work Queue to handle messages to Kernel
95 */
96nss_work_t *nss_work;
Abhishek Rastogibc74e432013-04-02 10:28:22 +053097
Arunkumar T79990cb2015-06-05 10:53:16 +053098extern struct of_device_id nss_dt_ids[];
Abhishek Rastogibc74e432013-04-02 10:28:22 +053099
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530100/*
101 * nss_probe()
Arunkumar T79990cb2015-06-05 10:53:16 +0530102 * HLOS device probe callback
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530103 */
Ram Chandra Jangir6577f382016-05-31 12:16:28 +0530104static inline int nss_probe(struct platform_device *nss_dev)
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530105{
Arunkumar T79990cb2015-06-05 10:53:16 +0530106 return nss_hal_probe(nss_dev);
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530107}
108
109/*
110 * nss_remove()
Arunkumar T79990cb2015-06-05 10:53:16 +0530111 * HLOS device remove callback
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530112 */
Ram Chandra Jangir6577f382016-05-31 12:16:28 +0530113static inline int nss_remove(struct platform_device *nss_dev)
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530114{
Arunkumar T79990cb2015-06-05 10:53:16 +0530115 return nss_hal_remove(nss_dev);
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530116}
117
118/*
119 * nss_driver
120 * Platform driver structure for NSS
121 */
122struct platform_driver nss_driver = {
123 .probe = nss_probe,
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800124 .remove = nss_remove,
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530125 .driver = {
126 .name = "qca-nss",
127 .owner = THIS_MODULE,
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800128#if (NSS_DT_SUPPORT == 1)
129 .of_match_table = of_match_ptr(nss_dt_ids),
130#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530131 },
132};
133
Arunkumar T28b2d742015-06-16 22:15:58 +0530134#if (NSS_FREQ_SCALE_SUPPORT == 1)
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530135/*
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530136 * nss_reset_frequency_stats_samples()
137 * Reset all frequency sampling state when auto scaling is turned off.
138 */
139static void nss_reset_frequency_stats_samples (void)
140{
141 nss_runtime_samples.buffer_index = 0;
142 nss_runtime_samples.sum = 0;
143 nss_runtime_samples.average = 0;
144 nss_runtime_samples.sample_count = 0;
145 nss_runtime_samples.message_rate_limit = 0;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530146 nss_runtime_samples.freq_scale_rate_limit_down = 0;
147}
148
149/*
wthomas626147f2013-09-18 13:12:40 -0700150 ***************************************************************************************************
Thomas Wufb6a6842013-10-23 13:14:27 -0700151 * nss_wq_function() is used to queue up requests to change NSS frequencies.
152 * The function will take care of NSS notices and also control clock.
153 * The auto rate algorithmn will queue up requests or the procfs may also queue up these requests.
wthomas626147f2013-09-18 13:12:40 -0700154 ***************************************************************************************************
155 */
156
157/*
158 * nss_wq_function()
159 * Added to Handle BH requests to kernel
160 */
161void nss_wq_function (struct work_struct *work)
162{
163 nss_work_t *my_work = (nss_work_t *)work;
Vijay Vigneshana94c2652016-06-02 12:39:35 +0530164#if (NSS_DT_SUPPORT == 1)
165 nss_crypto_pm_event_callback_t crypto_pm_cb;
Samarjeet Banerjeecdfc0bd2016-05-28 00:22:31 +0530166 bool turbo = false;
Vijay Vigneshana94c2652016-06-02 12:39:35 +0530167#endif
wthomas626147f2013-09-18 13:12:40 -0700168
Guojun Jin32a3c6d2015-05-06 12:27:52 -0700169 nss_freq_change(&nss_top_main.nss[NSS_CORE_0], my_work->frequency, my_work->stats_enable, 0);
Guojun Jin9d782812015-05-12 14:01:25 -0700170 if (nss_top_main.nss[NSS_CORE_1].state == NSS_CORE_STATE_INITIALIZED) {
171 nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 0);
172 }
Thomas Wufb6a6842013-10-23 13:14:27 -0700173 clk_set_rate(nss_core0_clk, my_work->frequency);
Guojun Jin32a3c6d2015-05-06 12:27:52 -0700174 nss_freq_change(&nss_top_main.nss[NSS_CORE_0], my_work->frequency, my_work->stats_enable, 1);
Guojun Jin9d782812015-05-12 14:01:25 -0700175 if (nss_top_main.nss[NSS_CORE_1].state == NSS_CORE_STATE_INITIALIZED) {
176 nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 1);
177 }
wthomas626147f2013-09-18 13:12:40 -0700178
Thomas Wucd6b35a2015-07-14 10:17:48 -0700179/*
180 * If we are running NSS_PM_SUPPORT, we are on banana
181 * otherwise, we check if we are are on new kernel by checking if the
182 * fabric lookups are not NULL (success in init()))
183 */
Thomas Wu0d112192015-04-13 11:37:22 -0700184#if (NSS_PM_SUPPORT == 1)
Thomas Wucd6b35a2015-07-14 10:17:48 -0700185 if (!pm_client) {
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530186 goto out;
187 }
188
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800189 if (my_work->frequency >= NSS_FREQ_733) {
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530190 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_TURBO);
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800191 } else if (my_work->frequency > NSS_FREQ_110) {
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530192 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_NOMINAL);
193 } else {
194 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_IDLE);
195 }
Thomas Wu0d112192015-04-13 11:37:22 -0700196
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530197out:
Thomas Wucd6b35a2015-07-14 10:17:48 -0700198#else
199#if (NSS_DT_SUPPORT == 1)
Stephen Wang463f1cf2016-03-29 15:25:51 -0700200#if (NSS_FABRIC_SCALING_SUPPORT == 1)
Stephen Wang8ffd17f2016-03-07 14:03:40 -0800201 scale_fabrics();
Stephen Wang1017ad12016-03-14 10:18:06 -0700202#endif
Thomas Wucd6b35a2015-07-14 10:17:48 -0700203 if ((nss_fab0_clk != NULL) && (nss_fab0_clk != NULL)) {
204 if (my_work->frequency >= NSS_FREQ_733) {
205 clk_set_rate(nss_fab0_clk, NSS_FABRIC0_TURBO);
206 clk_set_rate(nss_fab1_clk, NSS_FABRIC1_TURBO);
207 } else if (my_work->frequency > NSS_FREQ_110) {
208 clk_set_rate(nss_fab0_clk, NSS_FABRIC0_NOMINAL);
209 clk_set_rate(nss_fab1_clk, NSS_FABRIC1_NOMINAL);
210 } else {
211 clk_set_rate(nss_fab0_clk, NSS_FABRIC0_IDLE);
212 clk_set_rate(nss_fab1_clk, NSS_FABRIC1_IDLE);
213 }
Samarjeet Banerjeecdfc0bd2016-05-28 00:22:31 +0530214
215 /*
216 * notify crypto about the clock change
217 */
218 crypto_pm_cb = nss_top_main.crypto_pm_callback;
219 if (crypto_pm_cb) {
220 turbo = (my_work->frequency >= NSS_FREQ_733);
221 crypto_pm_cb(nss_top_main.crypto_pm_ctx, turbo);
222 }
Thomas Wucd6b35a2015-07-14 10:17:48 -0700223 }
224#endif
Thomas Wu0d112192015-04-13 11:37:22 -0700225#endif
wthomas626147f2013-09-18 13:12:40 -0700226 kfree((void *)work);
227}
228
229/*
wthomas442c7972013-08-05 14:28:17 -0700230 * nss_current_freq_handler()
231 * Handle Userspace Frequency Change Requests
232 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700233static 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 -0700234{
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800235 int ret, i;
wthomas626147f2013-09-18 13:12:40 -0700236
237 BUG_ON(!nss_wq);
wthomas442c7972013-08-05 14:28:17 -0700238
239 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
240
Thomas Wuc151f2e2015-09-08 10:59:44 -0700241 if (!*lenp || (*ppos && !write)) {
wthomas626147f2013-09-18 13:12:40 -0700242 printk("Frequency Set to %d\n", nss_cmd_buf.current_freq);
Thomas Wuc151f2e2015-09-08 10:59:44 -0700243 *lenp = 0;
wthomasd39fa822013-08-22 16:44:23 -0700244 return ret;
wthomas442c7972013-08-05 14:28:17 -0700245 }
wthomasd39fa822013-08-22 16:44:23 -0700246
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800247 /*
248 * Check if frequency exists in frequency Table
249 */
250 i = 0;
Thomas Wu7132bd32015-05-07 15:03:06 -0700251 while (i < NSS_FREQ_MAX_SCALE) {
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800252 if (nss_runtime_samples.freq_scale[i].frequency == nss_cmd_buf.current_freq) {
253 break;
254 }
255 i++;
256 }
Thomas Wu7132bd32015-05-07 15:03:06 -0700257 if (i == NSS_FREQ_MAX_SCALE) {
Thomas Wufb6a6842013-10-23 13:14:27 -0700258 printk("Frequency not found. Please check Frequency Table\n");
Thomas Wub7683af2016-07-07 14:19:09 -0700259 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
wthomas626147f2013-09-18 13:12:40 -0700260 return ret;
wthomasd39fa822013-08-22 16:44:23 -0700261 }
262
Thomas Wub7683af2016-07-07 14:19:09 -0700263 /*
264 * Turn off Auto Scale
265 */
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800266 nss_cmd_buf.auto_scale = 0;
267 nss_runtime_samples.freq_scale_ready = 0;
Thomas Wub7683af2016-07-07 14:19:09 -0700268 nss_runtime_samples.freq_scale_index = i;
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800269
Thomas Wu7409bce2014-05-21 10:56:07 -0700270 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
wthomas626147f2013-09-18 13:12:40 -0700271 if (!nss_work) {
272 nss_info("NSS Freq WQ kmalloc fail");
273 return ret;
274 }
275 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
276 nss_work->frequency = nss_cmd_buf.current_freq;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530277 nss_work->stats_enable = 0;
278
Thomas Wub7683af2016-07-07 14:19:09 -0700279 /*
280 * Ensure we start with a fresh set of samples later
281 */
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530282 nss_reset_frequency_stats_samples();
283
wthomas626147f2013-09-18 13:12:40 -0700284 queue_work(nss_wq, (struct work_struct *)nss_work);
285
wthomas442c7972013-08-05 14:28:17 -0700286 return ret;
287}
288
289/*
290 * nss_auto_scale_handler()
291 * Enables or Disable Auto Scaling
292 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700293static 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 -0700294{
295 int ret;
296
297 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
298
Thomas Wuc151f2e2015-09-08 10:59:44 -0700299 if (!*lenp || (*ppos && !write)) {
wthomas626147f2013-09-18 13:12:40 -0700300 return ret;
301 }
302
Thomas Wufb6a6842013-10-23 13:14:27 -0700303 if (nss_cmd_buf.auto_scale != 1) {
wthomas626147f2013-09-18 13:12:40 -0700304 /*
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530305 * Is auto scaling currently enabled? If so, send the command to
306 * disable stats reporting to NSS
wthomas626147f2013-09-18 13:12:40 -0700307 */
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530308 if (nss_runtime_samples.freq_scale_ready != 0) {
309 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
Thomas Wu7409bce2014-05-21 10:56:07 -0700310 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530311 if (!nss_work) {
312 nss_info("NSS Freq WQ kmalloc fail");
313 return ret;
314 }
315 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
316 nss_work->frequency = nss_cmd_buf.current_freq;
317 nss_work->stats_enable = 0;
318 queue_work(nss_wq, (struct work_struct *)nss_work);
319 nss_runtime_samples.freq_scale_ready = 0;
320
321 /*
322 * The current samples would be stale later when scaling is
323 * enabled again, hence reset them
324 */
325 nss_reset_frequency_stats_samples();
326 }
Thomas Wufb6a6842013-10-23 13:14:27 -0700327 return ret;
wthomas626147f2013-09-18 13:12:40 -0700328 }
wthomas442c7972013-08-05 14:28:17 -0700329
Thomas Wufb6a6842013-10-23 13:14:27 -0700330 /*
331 * Auto Scaling is already being done
332 */
333 if (nss_runtime_samples.freq_scale_ready == 1) {
334 return ret;
335 }
336
337 /*
338 * Setup default values - Middle of Freq Scale Band
339 */
340 nss_runtime_samples.freq_scale_index = 1;
341 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
342
Thomas Wu7409bce2014-05-21 10:56:07 -0700343 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
Thomas Wufb6a6842013-10-23 13:14:27 -0700344 if (!nss_work) {
345 nss_info("NSS Freq WQ kmalloc fail");
346 return ret;
347 }
348 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
349 nss_work->frequency = nss_cmd_buf.current_freq;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530350 nss_work->stats_enable = 1;
Thomas Wufb6a6842013-10-23 13:14:27 -0700351 queue_work(nss_wq, (struct work_struct *)nss_work);
352
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800353 nss_cmd_buf.auto_scale = 0;
Thomas Wufb6a6842013-10-23 13:14:27 -0700354 nss_runtime_samples.freq_scale_ready = 1;
355
wthomas442c7972013-08-05 14:28:17 -0700356 return ret;
357}
358
359/*
360 * nss_get_freq_table_handler()
361 * Display Support Freq and Ex how to Change.
362 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700363static 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 -0700364{
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800365 int ret, i;
wthomas442c7972013-08-05 14:28:17 -0700366
367 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
368
Thomas Wuc151f2e2015-09-08 10:59:44 -0700369 if (write) {
370 return ret;
371 }
372
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800373 printk("Frequency Supported - ");
Thomas Wuc151f2e2015-09-08 10:59:44 -0700374
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800375 i = 0;
Thomas Wu7132bd32015-05-07 15:03:06 -0700376 while (i < NSS_FREQ_MAX_SCALE) {
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800377 printk("%dMhz ", nss_runtime_samples.freq_scale[i].frequency/1000000);
378 i++;
Thomas Wu0a0a9c92013-11-21 15:28:19 -0800379 }
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800380 printk("\n");
wthomas442c7972013-08-05 14:28:17 -0700381
Thomas Wuc151f2e2015-09-08 10:59:44 -0700382 *lenp = 0;
wthomas442c7972013-08-05 14:28:17 -0700383 return ret;
384}
385
386/*
Thomas Wu05495be2013-12-19 14:24:24 -0800387 * nss_get_average_inst_handler()
388 * Display AVG Inst Per Ms.
389 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700390static 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 -0800391{
392 int ret;
393
394 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
395
Thomas Wuc151f2e2015-09-08 10:59:44 -0700396 if (write) {
397 return ret;
Thomas Wu05495be2013-12-19 14:24:24 -0800398 }
399
Thomas Wuc151f2e2015-09-08 10:59:44 -0700400 printk("Current Inst Per Ms %x\n", nss_runtime_samples.average);
401
402 *lenp = 0;
Thomas Wu05495be2013-12-19 14:24:24 -0800403 return ret;
404}
Arunkumar T28b2d742015-06-16 22:15:58 +0530405#endif
Thomas Wu05495be2013-12-19 14:24:24 -0800406
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800407#if (NSS_FW_DBG_SUPPORT == 1)
Thomas Wu05495be2013-12-19 14:24:24 -0800408/*
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530409 * nss_debug_handler()
410 * Enable NSS debug output
411 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700412static 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 +0530413{
414 int ret;
415
416 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
417 if (!ret) {
418 if ((write) && (nss_ctl_debug != 0)) {
419 printk("Enabling NSS SPI Debug\n");
420 nss_hal_debug_enable();
421 }
422 }
423
424 return ret;
425}
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800426#endif
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530427
428/*
Thomas Wu52075f42014-02-06 16:32:42 -0800429 * nss_coredump_handler()
430 * Send Signal To Coredump NSS Cores
431 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700432static 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 -0800433{
Guojun Jin32a3c6d2015-05-06 12:27:52 -0700434 struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[NSS_CORE_0];
Thomas Wu52075f42014-02-06 16:32:42 -0800435 int ret;
436
437 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
438 if (!ret) {
439 if ((write) && (nss_ctl_debug != 0)) {
440 printk("Coredumping to DDR\n");
Stephen Wangf26af762015-07-15 12:00:30 -0700441 nss_hal_send_interrupt(nss_ctx->nmap, nss_ctx->h2n_desc_rings[NSS_IF_CMD_QUEUE].desc_ring.int_bit, NSS_REGS_H2N_INTR_STATUS_TRIGGER_COREDUMP);
Thomas Wu52075f42014-02-06 16:32:42 -0800442 }
443 }
444
445 return ret;
446}
447
448/*
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800449 * nss_jumbo_mru_handler()
450 * Sysctl to modify nss_jumbo_mru
451 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700452static 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 -0800453{
454 int ret;
455
456 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
457 if (ret) {
458 return ret;
459 }
460
461 if (write) {
462 nss_core_set_jumbo_mru(nss_jumbo_mru);
463 nss_info("jumbo_mru set to %d\n", nss_jumbo_mru);
464 }
465
466 return ret;
467}
468
469/* nss_paged_mode_handler()
470 * Sysctl to modify nss_paged_mode.
471 */
472
Stephen Wang52e6d342016-03-29 15:02:33 -0700473static 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 -0800474{
475 int ret;
476
477 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
478 if (ret) {
479 return ret;
480 }
481
482 if (write) {
483 nss_core_set_paged_mode(nss_paged_mode);
484 nss_info("paged_mode set to %d\n", nss_paged_mode);
485 }
486
487 return ret;
488}
489
Arunkumar T28b2d742015-06-16 22:15:58 +0530490#if (NSS_FREQ_SCALE_SUPPORT == 1)
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800491/*
wthomas442c7972013-08-05 14:28:17 -0700492 * sysctl-tuning infrastructure.
493 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700494static struct ctl_table nss_freq_table[] = {
wthomas442c7972013-08-05 14:28:17 -0700495 {
496 .procname = "current_freq",
497 .data = &nss_cmd_buf.current_freq,
498 .maxlen = sizeof(int),
499 .mode = 0644,
500 .proc_handler = &nss_current_freq_handler,
501 },
502 {
503 .procname = "freq_table",
504 .data = &nss_cmd_buf.max_freq,
505 .maxlen = sizeof(int),
506 .mode = 0644,
507 .proc_handler = &nss_get_freq_table_handler,
508 },
509 {
510 .procname = "auto_scale",
511 .data = &nss_cmd_buf.auto_scale,
512 .maxlen = sizeof(int),
513 .mode = 0644,
514 .proc_handler = &nss_auto_scale_handler,
515 },
Thomas Wu05495be2013-12-19 14:24:24 -0800516 {
517 .procname = "inst_per_sec",
518 .data = &nss_cmd_buf.average_inst,
519 .maxlen = sizeof(int),
520 .mode = 0644,
521 .proc_handler = &nss_get_average_inst_handler,
522 },
wthomas442c7972013-08-05 14:28:17 -0700523 { }
524};
Arunkumar T28b2d742015-06-16 22:15:58 +0530525#endif
wthomas442c7972013-08-05 14:28:17 -0700526
Stephen Wang52e6d342016-03-29 15:02:33 -0700527static struct ctl_table nss_general_table[] = {
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530528 {
529 .procname = "redirect",
530 .data = &nss_ctl_redirect,
531 .maxlen = sizeof(int),
532 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700533 .proc_handler = proc_dointvec,
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530534 },
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800535#if (NSS_FW_DBG_SUPPORT == 1)
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530536 {
537 .procname = "debug",
538 .data = &nss_ctl_debug,
539 .maxlen = sizeof(int),
540 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700541 .proc_handler = &nss_debug_handler,
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530542 },
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800543#endif
Thomas Wu52075f42014-02-06 16:32:42 -0800544 {
545 .procname = "coredump",
546 .data = &nss_cmd_buf.coredump,
547 .maxlen = sizeof(int),
548 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700549 .proc_handler = &nss_coredump_handler,
Thomas Wu52075f42014-02-06 16:32:42 -0800550 },
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530551 {
Saurabh Misra96998db2014-07-10 12:15:48 -0700552 .procname = "logbuf",
553 .data = &nss_ctl_logbuf,
554 .maxlen = sizeof(int),
555 .mode = 0644,
556 .proc_handler = &nss_logbuffer_handler,
557 },
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800558 {
559 .procname = "jumbo_mru",
560 .data = &nss_jumbo_mru,
561 .maxlen = sizeof(int),
562 .mode = 0644,
563 .proc_handler = &nss_jumbo_mru_handler,
564 },
565 {
566 .procname = "paged_mode",
567 .data = &nss_paged_mode,
568 .maxlen = sizeof(int),
569 .mode = 0644,
570 .proc_handler = &nss_paged_mode_handler,
571 },
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530572 { }
573};
574
Stephen Wang52e6d342016-03-29 15:02:33 -0700575static struct ctl_table nss_clock_dir[] = {
Arunkumar T28b2d742015-06-16 22:15:58 +0530576#if (NSS_FREQ_SCALE_SUPPORT == 1)
wthomas442c7972013-08-05 14:28:17 -0700577 {
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530578 .procname = "clock",
579 .mode = 0555,
580 .child = nss_freq_table,
581 },
Arunkumar T28b2d742015-06-16 22:15:58 +0530582#endif
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530583 {
584 .procname = "general",
585 .mode = 0555,
586 .child = nss_general_table,
wthomas442c7972013-08-05 14:28:17 -0700587 },
588 { }
589};
590
Stephen Wang52e6d342016-03-29 15:02:33 -0700591static struct ctl_table nss_root_dir[] = {
wthomas442c7972013-08-05 14:28:17 -0700592 {
593 .procname = "nss",
594 .mode = 0555,
595 .child = nss_clock_dir,
596 },
597 { }
598};
599
Stephen Wang52e6d342016-03-29 15:02:33 -0700600static struct ctl_table nss_root[] = {
wthomas442c7972013-08-05 14:28:17 -0700601 {
602 .procname = "dev",
603 .mode = 0555,
604 .child = nss_root_dir,
605 },
606 { }
607};
608
609static struct ctl_table_header *nss_dev_header;
610
611/*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530612 * nss_init()
613 * Registers nss driver
614 */
615static int __init nss_init(void)
616{
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800617#if (NSS_DT_SUPPORT == 1)
618 struct device_node *cmn = NULL;
619 struct resource res_nss_fpb_base;
620#endif
621
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530622 nss_info("Init NSS driver");
623
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800624#if (NSS_DT_SUPPORT == 1)
625 /*
626 * Get reference to NSS common device node
627 */
628 cmn = of_find_node_by_name(NULL, "nss-common");
629 if (!cmn) {
Xiaoping Fan921869a2015-08-12 17:19:43 -0700630 nss_info_always("qca-nss-drv.ko is loaded for symbol link\n");
631 return 0;
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800632 }
633
634 if (of_address_to_resource(cmn, 0, &res_nss_fpb_base) != 0) {
635 nss_info("of_address_to_resource() return error for nss_fpb_base\n");
636 of_node_put(cmn);
637 return -EFAULT;
638 }
639
640 nss_top_main.nss_fpb_base = ioremap_nocache(res_nss_fpb_base.start,
641 resource_size(&res_nss_fpb_base));
642 if (!nss_top_main.nss_fpb_base) {
643 nss_info("ioremap fail for nss_fpb_base\n");
644 of_node_put(cmn);
645 return -EFAULT;
646 }
647
648 nss_top_main.nss_hal_common_init_done = false;
649
650 /*
651 * Release reference to NSS common device node
652 */
653 of_node_put(cmn);
654 cmn = NULL;
655#else
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530656 /*
657 * Perform clock init common to all NSS cores
658 */
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530659 nss_hal_common_reset(&(nss_top_main.clk_src));
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530660
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800661#endif /* NSS_DT_SUPPORT */
662
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530663 /*
Stephen Wangb42ddc52015-12-17 18:10:35 -0800664 * Initialize data_plane workqueue
665 */
666 if (nss_data_plane_init_delay_work()) {
667 nss_warning("Error initializing nss_data_plane_workqueue\n");
668 return -EFAULT;
669 }
670
671 /*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530672 * Enable spin locks
673 */
674 spin_lock_init(&(nss_top_main.lock));
675 spin_lock_init(&(nss_top_main.stats_lock));
676
677 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530678 * Enable NSS statistics
679 */
680 nss_stats_init();
681
682 /*
wthomas442c7972013-08-05 14:28:17 -0700683 * Register sysctl table.
684 */
685 nss_dev_header = register_sysctl_table(nss_root);
686
687 /*
Vijay Dewangan9db18752014-09-15 16:25:01 -0700688 * Registering sysctl for ipv4/6 specific config.
689 */
690 nss_ipv4_register_sysctl();
691 nss_ipv6_register_sysctl();
692
Vijay Dewanganac7efc42015-02-09 16:04:53 -0800693 /*
Stephen Wang49b474b2016-03-25 10:40:30 -0700694 * Registering sysctl for n2h specific config.
Vijay Dewanganac7efc42015-02-09 16:04:53 -0800695 */
Stephen Wang49b474b2016-03-25 10:40:30 -0700696 nss_n2h_register_sysctl();
Vijay Dewanganac7efc42015-02-09 16:04:53 -0800697
Vijay Dewangan9db18752014-09-15 16:25:01 -0700698 /*
wthomas626147f2013-09-18 13:12:40 -0700699 * Setup Runtime Sample values
700 */
wthomas626147f2013-09-18 13:12:40 -0700701 nss_runtime_samples.freq_scale_index = 1;
702 nss_runtime_samples.freq_scale_ready = 0;
Thomas Wu9681f7e2013-11-06 13:12:57 -0800703 nss_runtime_samples.freq_scale_rate_limit_down = 0;
wthomas626147f2013-09-18 13:12:40 -0700704 nss_runtime_samples.buffer_index = 0;
705 nss_runtime_samples.sum = 0;
706 nss_runtime_samples.sample_count = 0;
707 nss_runtime_samples.average = 0;
708 nss_runtime_samples.message_rate_limit = 0;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530709 nss_runtime_samples.initialized = 0;
wthomas626147f2013-09-18 13:12:40 -0700710
Thomas Wu05495be2013-12-19 14:24:24 -0800711 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
712
wthomas626147f2013-09-18 13:12:40 -0700713 /*
714 * Initial Workqueue
715 */
716 nss_wq = create_workqueue("nss_freq_queue");
717
Thomas Wu0d112192015-04-13 11:37:22 -0700718#if (NSS_PM_SUPPORT == 1)
wthomas626147f2013-09-18 13:12:40 -0700719 /*
Pamidipati, Vijay7f413b52013-09-24 19:07:12 +0530720 * Initialize NSS Bus PM module
721 */
722 nss_pm_init();
723
724 /*
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530725 * Register with Bus driver
726 */
727 pm_client = nss_pm_client_register(NSS_PM_CLIENT_NETAP);
728 if (!pm_client) {
729 nss_warning("Error registering with PM driver");
730 }
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800731#endif
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530732
733 /*
Radha krishna Simha Jiguru7f424d52015-02-10 19:41:01 +0530734 * Initialize mtu size needed as start
735 */
736 nss_top_main.prev_mtu_sz = NSS_GMAC_NORMAL_FRAME_MTU;
737
738 /*
Guojun Jin1cb79522015-06-22 22:34:22 -0700739 * register panic handler and timeout control
740 */
741 nss_coredump_notify_register();
742 nss_coredump_init_delay_work();
743
744 /*
Stephen Wang1f6ad492016-01-27 23:42:06 -0800745 * Init capwap
746 */
747 nss_capwap_init();
748
749 /*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530750 * Register platform_driver
751 */
752 return platform_driver_register(&nss_driver);
753}
754
755/*
756 * nss_cleanup()
757 * Unregisters nss driver
758 */
759static void __exit nss_cleanup(void)
760{
Xiaoping Fan921869a2015-08-12 17:19:43 -0700761#if (NSS_DT_SUPPORT == 1)
762 struct device_node *cmn = NULL;
763
764 /*
765 * Get reference to NSS common device node
766 */
767 cmn = of_find_node_by_name(NULL, "nss-common");
768 if (!cmn) {
769 nss_info_always("cannot find nss-common node, maybe just for symbol link\n");
770 return;
771 }
772#endif
773
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530774 nss_info("Exit NSS driver");
wthomas442c7972013-08-05 14:28:17 -0700775
776 if (nss_dev_header)
777 unregister_sysctl_table(nss_dev_header);
778
Vijay Dewangan9db18752014-09-15 16:25:01 -0700779 /*
Vijay Dewangan488e5372014-12-29 21:40:11 -0800780 * Unregister n2h specific sysctl
781 */
Stephen Wang49b474b2016-03-25 10:40:30 -0700782 nss_n2h_unregister_sysctl();
Vijay Dewangan488e5372014-12-29 21:40:11 -0800783
784 /*
Vijay Dewangan9db18752014-09-15 16:25:01 -0700785 * Unregister ipv4/6 specific sysctl
786 */
787 nss_ipv4_unregister_sysctl();
788 nss_ipv6_unregister_sysctl();
789
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800790#if (NSS_DT_SUPPORT == 1)
791 if(nss_top_main.nss_fpb_base) {
792 iounmap(nss_top_main.nss_fpb_base);
793 nss_top_main.nss_fpb_base = 0;
794 }
795#endif
796
Stephen Wangb42ddc52015-12-17 18:10:35 -0800797 nss_data_plane_destroy_delay_work();
798
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530799 platform_driver_unregister(&nss_driver);
800}
801
802module_init(nss_init);
803module_exit(nss_cleanup);
804
805MODULE_DESCRIPTION("QCA NSS Driver");
806MODULE_AUTHOR("Qualcomm Atheros Inc");
807MODULE_LICENSE("Dual BSD/GPL");