blob: 27d98d0995155c8c31c00f51af7c970b0765ea2b [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
Stephen Wang90c67de2016-04-26 15:15:59 -0700118#if (NSS_DT_SUPPORT == 1)
119/*
120 * Platform Device ID for NSS core.
121 */
122struct of_device_id nss_dt_ids[] = {
123 { .compatible = "qcom,nss" },
124 { .compatible = "qcom,nss0" },
125 { .compatible = "qcom,nss1" },
126 {},
127};
128MODULE_DEVICE_TABLE(of, nss_dt_ids);
129#endif
130
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530131/*
132 * nss_driver
133 * Platform driver structure for NSS
134 */
135struct platform_driver nss_driver = {
136 .probe = nss_probe,
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800137 .remove = nss_remove,
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530138 .driver = {
139 .name = "qca-nss",
140 .owner = THIS_MODULE,
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800141#if (NSS_DT_SUPPORT == 1)
142 .of_match_table = of_match_ptr(nss_dt_ids),
143#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530144 },
145};
146
Arunkumar T28b2d742015-06-16 22:15:58 +0530147#if (NSS_FREQ_SCALE_SUPPORT == 1)
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530148/*
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530149 * nss_reset_frequency_stats_samples()
150 * Reset all frequency sampling state when auto scaling is turned off.
151 */
152static void nss_reset_frequency_stats_samples (void)
153{
154 nss_runtime_samples.buffer_index = 0;
155 nss_runtime_samples.sum = 0;
156 nss_runtime_samples.average = 0;
157 nss_runtime_samples.sample_count = 0;
158 nss_runtime_samples.message_rate_limit = 0;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530159 nss_runtime_samples.freq_scale_rate_limit_down = 0;
160}
161
162/*
wthomas626147f2013-09-18 13:12:40 -0700163 ***************************************************************************************************
Thomas Wufb6a6842013-10-23 13:14:27 -0700164 * nss_wq_function() is used to queue up requests to change NSS frequencies.
165 * The function will take care of NSS notices and also control clock.
166 * The auto rate algorithmn will queue up requests or the procfs may also queue up these requests.
wthomas626147f2013-09-18 13:12:40 -0700167 ***************************************************************************************************
168 */
169
170/*
171 * nss_wq_function()
172 * Added to Handle BH requests to kernel
173 */
174void nss_wq_function (struct work_struct *work)
175{
176 nss_work_t *my_work = (nss_work_t *)work;
Vijay Vigneshana94c2652016-06-02 12:39:35 +0530177#if (NSS_DT_SUPPORT == 1)
178 nss_crypto_pm_event_callback_t crypto_pm_cb;
Samarjeet Banerjeecdfc0bd2016-05-28 00:22:31 +0530179 bool turbo = false;
Vijay Vigneshana94c2652016-06-02 12:39:35 +0530180#endif
wthomas626147f2013-09-18 13:12:40 -0700181
Guojun Jin32a3c6d2015-05-06 12:27:52 -0700182 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 -0700183 if (nss_top_main.nss[NSS_CORE_1].state == NSS_CORE_STATE_INITIALIZED) {
184 nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 0);
185 }
Thomas Wufb6a6842013-10-23 13:14:27 -0700186 clk_set_rate(nss_core0_clk, my_work->frequency);
Guojun Jin32a3c6d2015-05-06 12:27:52 -0700187 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 -0700188 if (nss_top_main.nss[NSS_CORE_1].state == NSS_CORE_STATE_INITIALIZED) {
189 nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 1);
190 }
wthomas626147f2013-09-18 13:12:40 -0700191
Thomas Wucd6b35a2015-07-14 10:17:48 -0700192/*
193 * If we are running NSS_PM_SUPPORT, we are on banana
194 * otherwise, we check if we are are on new kernel by checking if the
195 * fabric lookups are not NULL (success in init()))
196 */
Thomas Wu0d112192015-04-13 11:37:22 -0700197#if (NSS_PM_SUPPORT == 1)
Thomas Wucd6b35a2015-07-14 10:17:48 -0700198 if (!pm_client) {
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530199 goto out;
200 }
201
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800202 if (my_work->frequency >= NSS_FREQ_733) {
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530203 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_TURBO);
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800204 } else if (my_work->frequency > NSS_FREQ_110) {
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530205 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_NOMINAL);
206 } else {
207 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_IDLE);
208 }
Thomas Wu0d112192015-04-13 11:37:22 -0700209
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530210out:
Thomas Wucd6b35a2015-07-14 10:17:48 -0700211#else
212#if (NSS_DT_SUPPORT == 1)
Stephen Wang463f1cf2016-03-29 15:25:51 -0700213#if (NSS_FABRIC_SCALING_SUPPORT == 1)
Stephen Wang8ffd17f2016-03-07 14:03:40 -0800214 scale_fabrics();
Stephen Wang1017ad12016-03-14 10:18:06 -0700215#endif
Thomas Wucd6b35a2015-07-14 10:17:48 -0700216 if ((nss_fab0_clk != NULL) && (nss_fab0_clk != NULL)) {
217 if (my_work->frequency >= NSS_FREQ_733) {
218 clk_set_rate(nss_fab0_clk, NSS_FABRIC0_TURBO);
219 clk_set_rate(nss_fab1_clk, NSS_FABRIC1_TURBO);
220 } else if (my_work->frequency > NSS_FREQ_110) {
221 clk_set_rate(nss_fab0_clk, NSS_FABRIC0_NOMINAL);
222 clk_set_rate(nss_fab1_clk, NSS_FABRIC1_NOMINAL);
223 } else {
224 clk_set_rate(nss_fab0_clk, NSS_FABRIC0_IDLE);
225 clk_set_rate(nss_fab1_clk, NSS_FABRIC1_IDLE);
226 }
Samarjeet Banerjeecdfc0bd2016-05-28 00:22:31 +0530227
228 /*
229 * notify crypto about the clock change
230 */
231 crypto_pm_cb = nss_top_main.crypto_pm_callback;
232 if (crypto_pm_cb) {
233 turbo = (my_work->frequency >= NSS_FREQ_733);
234 crypto_pm_cb(nss_top_main.crypto_pm_ctx, turbo);
235 }
Thomas Wucd6b35a2015-07-14 10:17:48 -0700236 }
237#endif
Thomas Wu0d112192015-04-13 11:37:22 -0700238#endif
wthomas626147f2013-09-18 13:12:40 -0700239 kfree((void *)work);
240}
241
242/*
wthomas442c7972013-08-05 14:28:17 -0700243 * nss_current_freq_handler()
244 * Handle Userspace Frequency Change Requests
245 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700246static 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 -0700247{
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800248 int ret, i;
wthomas626147f2013-09-18 13:12:40 -0700249
250 BUG_ON(!nss_wq);
wthomas442c7972013-08-05 14:28:17 -0700251
252 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
253
Thomas Wuc151f2e2015-09-08 10:59:44 -0700254 if (!*lenp || (*ppos && !write)) {
wthomas626147f2013-09-18 13:12:40 -0700255 printk("Frequency Set to %d\n", nss_cmd_buf.current_freq);
Thomas Wuc151f2e2015-09-08 10:59:44 -0700256 *lenp = 0;
wthomasd39fa822013-08-22 16:44:23 -0700257 return ret;
wthomas442c7972013-08-05 14:28:17 -0700258 }
wthomasd39fa822013-08-22 16:44:23 -0700259
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800260 /*
261 * Check if frequency exists in frequency Table
262 */
263 i = 0;
Thomas Wu7132bd32015-05-07 15:03:06 -0700264 while (i < NSS_FREQ_MAX_SCALE) {
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800265 if (nss_runtime_samples.freq_scale[i].frequency == nss_cmd_buf.current_freq) {
266 break;
267 }
268 i++;
269 }
Thomas Wu7132bd32015-05-07 15:03:06 -0700270 if (i == NSS_FREQ_MAX_SCALE) {
Thomas Wufb6a6842013-10-23 13:14:27 -0700271 printk("Frequency not found. Please check Frequency Table\n");
Thomas Wub7683af2016-07-07 14:19:09 -0700272 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
wthomas626147f2013-09-18 13:12:40 -0700273 return ret;
wthomasd39fa822013-08-22 16:44:23 -0700274 }
275
Thomas Wub7683af2016-07-07 14:19:09 -0700276 /*
277 * Turn off Auto Scale
278 */
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800279 nss_cmd_buf.auto_scale = 0;
280 nss_runtime_samples.freq_scale_ready = 0;
Thomas Wub7683af2016-07-07 14:19:09 -0700281 nss_runtime_samples.freq_scale_index = i;
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800282
Thomas Wu7409bce2014-05-21 10:56:07 -0700283 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
wthomas626147f2013-09-18 13:12:40 -0700284 if (!nss_work) {
285 nss_info("NSS Freq WQ kmalloc fail");
286 return ret;
287 }
288 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
289 nss_work->frequency = nss_cmd_buf.current_freq;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530290 nss_work->stats_enable = 0;
291
Thomas Wub7683af2016-07-07 14:19:09 -0700292 /*
293 * Ensure we start with a fresh set of samples later
294 */
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530295 nss_reset_frequency_stats_samples();
296
wthomas626147f2013-09-18 13:12:40 -0700297 queue_work(nss_wq, (struct work_struct *)nss_work);
298
wthomas442c7972013-08-05 14:28:17 -0700299 return ret;
300}
301
302/*
303 * nss_auto_scale_handler()
304 * Enables or Disable Auto Scaling
305 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700306static 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 -0700307{
308 int ret;
309
310 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
311
Thomas Wuc151f2e2015-09-08 10:59:44 -0700312 if (!*lenp || (*ppos && !write)) {
wthomas626147f2013-09-18 13:12:40 -0700313 return ret;
314 }
315
Thomas Wufb6a6842013-10-23 13:14:27 -0700316 if (nss_cmd_buf.auto_scale != 1) {
wthomas626147f2013-09-18 13:12:40 -0700317 /*
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530318 * Is auto scaling currently enabled? If so, send the command to
319 * disable stats reporting to NSS
wthomas626147f2013-09-18 13:12:40 -0700320 */
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530321 if (nss_runtime_samples.freq_scale_ready != 0) {
322 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
Thomas Wu7409bce2014-05-21 10:56:07 -0700323 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530324 if (!nss_work) {
325 nss_info("NSS Freq WQ kmalloc fail");
326 return ret;
327 }
328 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
329 nss_work->frequency = nss_cmd_buf.current_freq;
330 nss_work->stats_enable = 0;
331 queue_work(nss_wq, (struct work_struct *)nss_work);
332 nss_runtime_samples.freq_scale_ready = 0;
333
334 /*
335 * The current samples would be stale later when scaling is
336 * enabled again, hence reset them
337 */
338 nss_reset_frequency_stats_samples();
339 }
Thomas Wufb6a6842013-10-23 13:14:27 -0700340 return ret;
wthomas626147f2013-09-18 13:12:40 -0700341 }
wthomas442c7972013-08-05 14:28:17 -0700342
Thomas Wufb6a6842013-10-23 13:14:27 -0700343 /*
344 * Auto Scaling is already being done
345 */
346 if (nss_runtime_samples.freq_scale_ready == 1) {
347 return ret;
348 }
349
350 /*
351 * Setup default values - Middle of Freq Scale Band
352 */
353 nss_runtime_samples.freq_scale_index = 1;
354 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
355
Thomas Wu7409bce2014-05-21 10:56:07 -0700356 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
Thomas Wufb6a6842013-10-23 13:14:27 -0700357 if (!nss_work) {
358 nss_info("NSS Freq WQ kmalloc fail");
359 return ret;
360 }
361 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
362 nss_work->frequency = nss_cmd_buf.current_freq;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530363 nss_work->stats_enable = 1;
Thomas Wufb6a6842013-10-23 13:14:27 -0700364 queue_work(nss_wq, (struct work_struct *)nss_work);
365
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800366 nss_cmd_buf.auto_scale = 0;
Thomas Wufb6a6842013-10-23 13:14:27 -0700367 nss_runtime_samples.freq_scale_ready = 1;
368
wthomas442c7972013-08-05 14:28:17 -0700369 return ret;
370}
371
372/*
373 * nss_get_freq_table_handler()
374 * Display Support Freq and Ex how to Change.
375 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700376static 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 -0700377{
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800378 int ret, i;
wthomas442c7972013-08-05 14:28:17 -0700379
380 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
381
Thomas Wuc151f2e2015-09-08 10:59:44 -0700382 if (write) {
383 return ret;
384 }
385
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800386 printk("Frequency Supported - ");
Thomas Wuc151f2e2015-09-08 10:59:44 -0700387
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800388 i = 0;
Thomas Wu7132bd32015-05-07 15:03:06 -0700389 while (i < NSS_FREQ_MAX_SCALE) {
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800390 printk("%dMhz ", nss_runtime_samples.freq_scale[i].frequency/1000000);
391 i++;
Thomas Wu0a0a9c92013-11-21 15:28:19 -0800392 }
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800393 printk("\n");
wthomas442c7972013-08-05 14:28:17 -0700394
Thomas Wuc151f2e2015-09-08 10:59:44 -0700395 *lenp = 0;
wthomas442c7972013-08-05 14:28:17 -0700396 return ret;
397}
398
399/*
Thomas Wu05495be2013-12-19 14:24:24 -0800400 * nss_get_average_inst_handler()
401 * Display AVG Inst Per Ms.
402 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700403static 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 -0800404{
405 int ret;
406
407 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
408
Thomas Wuc151f2e2015-09-08 10:59:44 -0700409 if (write) {
410 return ret;
Thomas Wu05495be2013-12-19 14:24:24 -0800411 }
412
Thomas Wuc151f2e2015-09-08 10:59:44 -0700413 printk("Current Inst Per Ms %x\n", nss_runtime_samples.average);
414
415 *lenp = 0;
Thomas Wu05495be2013-12-19 14:24:24 -0800416 return ret;
417}
Arunkumar T28b2d742015-06-16 22:15:58 +0530418#endif
Thomas Wu05495be2013-12-19 14:24:24 -0800419
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800420#if (NSS_FW_DBG_SUPPORT == 1)
Thomas Wu05495be2013-12-19 14:24:24 -0800421/*
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530422 * nss_debug_handler()
423 * Enable NSS debug output
424 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700425static 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 +0530426{
427 int ret;
428
429 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
430 if (!ret) {
431 if ((write) && (nss_ctl_debug != 0)) {
432 printk("Enabling NSS SPI Debug\n");
433 nss_hal_debug_enable();
434 }
435 }
436
437 return ret;
438}
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800439#endif
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530440
441/*
Thomas Wu52075f42014-02-06 16:32:42 -0800442 * nss_coredump_handler()
443 * Send Signal To Coredump NSS Cores
444 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700445static 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 -0800446{
Guojun Jin32a3c6d2015-05-06 12:27:52 -0700447 struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[NSS_CORE_0];
Thomas Wu52075f42014-02-06 16:32:42 -0800448 int ret;
449
450 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
451 if (!ret) {
452 if ((write) && (nss_ctl_debug != 0)) {
453 printk("Coredumping to DDR\n");
Stephen Wang90c67de2016-04-26 15:15:59 -0700454 nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_TRIGGER_COREDUMP);
Thomas Wu52075f42014-02-06 16:32:42 -0800455 }
456 }
457
458 return ret;
459}
460
461/*
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800462 * nss_jumbo_mru_handler()
463 * Sysctl to modify nss_jumbo_mru
464 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700465static 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 -0800466{
467 int ret;
468
469 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
470 if (ret) {
471 return ret;
472 }
473
474 if (write) {
475 nss_core_set_jumbo_mru(nss_jumbo_mru);
476 nss_info("jumbo_mru set to %d\n", nss_jumbo_mru);
477 }
478
479 return ret;
480}
481
482/* nss_paged_mode_handler()
483 * Sysctl to modify nss_paged_mode.
484 */
485
Stephen Wang52e6d342016-03-29 15:02:33 -0700486static 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 -0800487{
488 int ret;
489
490 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
491 if (ret) {
492 return ret;
493 }
494
495 if (write) {
496 nss_core_set_paged_mode(nss_paged_mode);
497 nss_info("paged_mode set to %d\n", nss_paged_mode);
498 }
499
500 return ret;
501}
502
Arunkumar T28b2d742015-06-16 22:15:58 +0530503#if (NSS_FREQ_SCALE_SUPPORT == 1)
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800504/*
wthomas442c7972013-08-05 14:28:17 -0700505 * sysctl-tuning infrastructure.
506 */
Stephen Wang52e6d342016-03-29 15:02:33 -0700507static struct ctl_table nss_freq_table[] = {
wthomas442c7972013-08-05 14:28:17 -0700508 {
509 .procname = "current_freq",
510 .data = &nss_cmd_buf.current_freq,
511 .maxlen = sizeof(int),
512 .mode = 0644,
513 .proc_handler = &nss_current_freq_handler,
514 },
515 {
516 .procname = "freq_table",
517 .data = &nss_cmd_buf.max_freq,
518 .maxlen = sizeof(int),
519 .mode = 0644,
520 .proc_handler = &nss_get_freq_table_handler,
521 },
522 {
523 .procname = "auto_scale",
524 .data = &nss_cmd_buf.auto_scale,
525 .maxlen = sizeof(int),
526 .mode = 0644,
527 .proc_handler = &nss_auto_scale_handler,
528 },
Thomas Wu05495be2013-12-19 14:24:24 -0800529 {
530 .procname = "inst_per_sec",
531 .data = &nss_cmd_buf.average_inst,
532 .maxlen = sizeof(int),
533 .mode = 0644,
534 .proc_handler = &nss_get_average_inst_handler,
535 },
wthomas442c7972013-08-05 14:28:17 -0700536 { }
537};
Arunkumar T28b2d742015-06-16 22:15:58 +0530538#endif
wthomas442c7972013-08-05 14:28:17 -0700539
Stephen Wang52e6d342016-03-29 15:02:33 -0700540static struct ctl_table nss_general_table[] = {
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530541 {
542 .procname = "redirect",
543 .data = &nss_ctl_redirect,
544 .maxlen = sizeof(int),
545 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700546 .proc_handler = proc_dointvec,
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530547 },
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800548#if (NSS_FW_DBG_SUPPORT == 1)
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530549 {
550 .procname = "debug",
551 .data = &nss_ctl_debug,
552 .maxlen = sizeof(int),
553 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700554 .proc_handler = &nss_debug_handler,
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530555 },
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800556#endif
Thomas Wu52075f42014-02-06 16:32:42 -0800557 {
558 .procname = "coredump",
559 .data = &nss_cmd_buf.coredump,
560 .maxlen = sizeof(int),
561 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700562 .proc_handler = &nss_coredump_handler,
Thomas Wu52075f42014-02-06 16:32:42 -0800563 },
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530564 {
Saurabh Misra96998db2014-07-10 12:15:48 -0700565 .procname = "logbuf",
566 .data = &nss_ctl_logbuf,
567 .maxlen = sizeof(int),
568 .mode = 0644,
569 .proc_handler = &nss_logbuffer_handler,
570 },
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800571 {
572 .procname = "jumbo_mru",
573 .data = &nss_jumbo_mru,
574 .maxlen = sizeof(int),
575 .mode = 0644,
576 .proc_handler = &nss_jumbo_mru_handler,
577 },
578 {
579 .procname = "paged_mode",
580 .data = &nss_paged_mode,
581 .maxlen = sizeof(int),
582 .mode = 0644,
583 .proc_handler = &nss_paged_mode_handler,
584 },
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530585 { }
586};
587
Stephen Wang52e6d342016-03-29 15:02:33 -0700588static struct ctl_table nss_clock_dir[] = {
Arunkumar T28b2d742015-06-16 22:15:58 +0530589#if (NSS_FREQ_SCALE_SUPPORT == 1)
wthomas442c7972013-08-05 14:28:17 -0700590 {
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530591 .procname = "clock",
592 .mode = 0555,
593 .child = nss_freq_table,
594 },
Arunkumar T28b2d742015-06-16 22:15:58 +0530595#endif
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530596 {
597 .procname = "general",
598 .mode = 0555,
599 .child = nss_general_table,
wthomas442c7972013-08-05 14:28:17 -0700600 },
601 { }
602};
603
Stephen Wang52e6d342016-03-29 15:02:33 -0700604static struct ctl_table nss_root_dir[] = {
wthomas442c7972013-08-05 14:28:17 -0700605 {
606 .procname = "nss",
607 .mode = 0555,
608 .child = nss_clock_dir,
609 },
610 { }
611};
612
Stephen Wang52e6d342016-03-29 15:02:33 -0700613static struct ctl_table nss_root[] = {
wthomas442c7972013-08-05 14:28:17 -0700614 {
615 .procname = "dev",
616 .mode = 0555,
617 .child = nss_root_dir,
618 },
619 { }
620};
621
622static struct ctl_table_header *nss_dev_header;
623
624/*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530625 * nss_init()
626 * Registers nss driver
627 */
628static int __init nss_init(void)
629{
630 nss_info("Init NSS driver");
631
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800632#if (NSS_DT_SUPPORT == 1)
633 /*
Stephen Wang90c67de2016-04-26 15:15:59 -0700634 * Pick up HAL by target information
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800635 */
Stephen Wang90c67de2016-04-26 15:15:59 -0700636#if defined(NSS_HAL_IPQ806X_SUPPORT)
637 if (of_machine_is_compatible("qcom,ipq8064") || of_machine_is_compatible("qcom,ipq8062")) {
638 nss_top_main.hal_ops = &nss_hal_ipq806x_ops;
Stephen Wang5901def2016-05-09 16:21:03 -0700639 nss_top_main.data_plane_ops = &nss_data_plane_gmac_ops;
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800640 }
Stephen Wang90c67de2016-04-26 15:15:59 -0700641#endif
Stephen Wangbe348022016-05-02 17:11:34 -0700642#if defined(NSS_HAL_IPQ807x_SUPPORT)
643 if (of_machine_is_compatible("qcom,ipq807x")) {
644 nss_top_main.hal_ops = &nss_hal_ipq807x_ops;
Stephen Wangdf8323b2016-05-09 22:51:22 -0700645 nss_top_main.data_plane_ops = &nss_data_plane_edma_ops;
Stephen Wangbe348022016-05-02 17:11:34 -0700646 }
647#endif
Stephen Wang90c67de2016-04-26 15:15:59 -0700648#if defined(NSS_HAL_FSM9010_SUPPORT)
649 if (of_machine_is_compatible("qcom,fsm9010")) {
650 nss_top_main.hal_ops = &nss_hal_fsm9010_ops;
Stephen Wang5901def2016-05-09 16:21:03 -0700651 nss_top_main.data_plane_ops = &nss_data_plane_gmac_ops;
Stephen Wang90c67de2016-04-26 15:15:59 -0700652 }
653#endif
654 if (!nss_top_main.hal_ops) {
655 nss_info_always("No supported HAL compiled on this platform\n");
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800656 return -EFAULT;
657 }
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800658#else
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530659 /*
Stephen Wang90c67de2016-04-26 15:15:59 -0700660 * For banana, only ipq806x is supported
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530661 */
Stephen Wang90c67de2016-04-26 15:15:59 -0700662 nss_top_main.hal_ops = &nss_hal_ipq806x_ops;
Stephen Wang5901def2016-05-09 16:21:03 -0700663 nss_top_main.data_plane_ops = &nss_data_plane_gmac_ops;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530664
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800665#endif /* NSS_DT_SUPPORT */
Stephen Wang90c67de2016-04-26 15:15:59 -0700666 nss_top_main.nss_hal_common_init_done = false;
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800667
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530668 /*
Stephen Wangb42ddc52015-12-17 18:10:35 -0800669 * Initialize data_plane workqueue
670 */
671 if (nss_data_plane_init_delay_work()) {
672 nss_warning("Error initializing nss_data_plane_workqueue\n");
673 return -EFAULT;
674 }
675
676 /*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530677 * Enable spin locks
678 */
679 spin_lock_init(&(nss_top_main.lock));
680 spin_lock_init(&(nss_top_main.stats_lock));
681
682 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530683 * Enable NSS statistics
684 */
685 nss_stats_init();
686
687 /*
wthomas442c7972013-08-05 14:28:17 -0700688 * Register sysctl table.
689 */
690 nss_dev_header = register_sysctl_table(nss_root);
691
692 /*
Vijay Dewangan9db18752014-09-15 16:25:01 -0700693 * Registering sysctl for ipv4/6 specific config.
694 */
695 nss_ipv4_register_sysctl();
696 nss_ipv6_register_sysctl();
697
Vijay Dewanganac7efc42015-02-09 16:04:53 -0800698 /*
Stephen Wang49b474b2016-03-25 10:40:30 -0700699 * Registering sysctl for n2h specific config.
Vijay Dewanganac7efc42015-02-09 16:04:53 -0800700 */
Stephen Wang49b474b2016-03-25 10:40:30 -0700701 nss_n2h_register_sysctl();
Vijay Dewanganac7efc42015-02-09 16:04:53 -0800702
Vijay Dewangan9db18752014-09-15 16:25:01 -0700703 /*
wthomas626147f2013-09-18 13:12:40 -0700704 * Setup Runtime Sample values
705 */
wthomas626147f2013-09-18 13:12:40 -0700706 nss_runtime_samples.freq_scale_index = 1;
707 nss_runtime_samples.freq_scale_ready = 0;
Thomas Wu9681f7e2013-11-06 13:12:57 -0800708 nss_runtime_samples.freq_scale_rate_limit_down = 0;
wthomas626147f2013-09-18 13:12:40 -0700709 nss_runtime_samples.buffer_index = 0;
710 nss_runtime_samples.sum = 0;
711 nss_runtime_samples.sample_count = 0;
712 nss_runtime_samples.average = 0;
713 nss_runtime_samples.message_rate_limit = 0;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530714 nss_runtime_samples.initialized = 0;
wthomas626147f2013-09-18 13:12:40 -0700715
Thomas Wu05495be2013-12-19 14:24:24 -0800716 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
717
wthomas626147f2013-09-18 13:12:40 -0700718 /*
719 * Initial Workqueue
720 */
721 nss_wq = create_workqueue("nss_freq_queue");
722
Thomas Wu0d112192015-04-13 11:37:22 -0700723#if (NSS_PM_SUPPORT == 1)
wthomas626147f2013-09-18 13:12:40 -0700724 /*
Pamidipati, Vijay7f413b52013-09-24 19:07:12 +0530725 * Initialize NSS Bus PM module
726 */
727 nss_pm_init();
728
729 /*
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530730 * Register with Bus driver
731 */
732 pm_client = nss_pm_client_register(NSS_PM_CLIENT_NETAP);
733 if (!pm_client) {
734 nss_warning("Error registering with PM driver");
735 }
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800736#endif
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530737
738 /*
Radha krishna Simha Jiguru7f424d52015-02-10 19:41:01 +0530739 * Initialize mtu size needed as start
740 */
741 nss_top_main.prev_mtu_sz = NSS_GMAC_NORMAL_FRAME_MTU;
742
743 /*
Guojun Jin1cb79522015-06-22 22:34:22 -0700744 * register panic handler and timeout control
745 */
746 nss_coredump_notify_register();
747 nss_coredump_init_delay_work();
748
749 /*
Stephen Wang1f6ad492016-01-27 23:42:06 -0800750 * Init capwap
751 */
752 nss_capwap_init();
753
754 /*
Amit Gupta316729b2016-08-12 12:21:15 +0530755 * INIT ppe on supported platform
756 */
757 if (of_machine_is_compatible("qcom,ipq807x")) {
758 nss_ppe_init();
759 }
760
761 /*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530762 * Register platform_driver
763 */
764 return platform_driver_register(&nss_driver);
765}
766
767/*
768 * nss_cleanup()
769 * Unregisters nss driver
770 */
771static void __exit nss_cleanup(void)
772{
773 nss_info("Exit NSS driver");
wthomas442c7972013-08-05 14:28:17 -0700774
775 if (nss_dev_header)
776 unregister_sysctl_table(nss_dev_header);
777
Vijay Dewangan9db18752014-09-15 16:25:01 -0700778 /*
Vijay Dewangan488e5372014-12-29 21:40:11 -0800779 * Unregister n2h specific sysctl
780 */
Stephen Wang49b474b2016-03-25 10:40:30 -0700781 nss_n2h_unregister_sysctl();
Vijay Dewangan488e5372014-12-29 21:40:11 -0800782
783 /*
Vijay Dewangan9db18752014-09-15 16:25:01 -0700784 * Unregister ipv4/6 specific sysctl
785 */
786 nss_ipv4_unregister_sysctl();
787 nss_ipv6_unregister_sysctl();
788
Stephen Wangb42ddc52015-12-17 18:10:35 -0800789 nss_data_plane_destroy_delay_work();
790
Amit Gupta316729b2016-08-12 12:21:15 +0530791 /*
792 * cleanup ppe on supported platform
793 */
794 if (of_machine_is_compatible("qcom,ipq807x")) {
795 nss_ppe_free();
796 }
797
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530798 platform_driver_unregister(&nss_driver);
799}
800
801module_init(nss_init);
802module_exit(nss_cleanup);
803
804MODULE_DESCRIPTION("QCA NSS Driver");
805MODULE_AUTHOR("Qualcomm Atheros Inc");
806MODULE_LICENSE("Dual BSD/GPL");