blob: f35d1cfdcb4eb22614b1ea7472d0eb7e0be8472e [file] [log] [blame]
Radhakrishna Jiguru1c9b2252013-08-27 23:57:48 +05301/*
2 **************************************************************************
Vijay Dewangan488e5372014-12-29 21:40:11 -08003 * Copyright (c) 2013 - 2015, 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"
Pamidipati, Vijay7f413b52013-09-24 19:07:12 +053028
Abhishek Rastogibc74e432013-04-02 10:28:22 +053029#include <nss_hal.h>
30
31#include <linux/module.h>
32#include <linux/platform_device.h>
wthomas442c7972013-08-05 14:28:17 -070033#include <linux/proc_fs.h>
34#include <linux/device.h>
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080035
36#if (NSS_DT_SUPPORT == 1)
37#include <linux/of.h>
38#include <linux/of_net.h>
39#include <linux/of_irq.h>
40#include <linux/of_address.h>
41#include <linux/reset.h>
42#else
Abhishek Rastogibc74e432013-04-02 10:28:22 +053043#include <mach/msm_nss.h>
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080044#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +053045
wthomas442c7972013-08-05 14:28:17 -070046#include <linux/sysctl.h>
47#include <linux/regulator/consumer.h>
Thomas Wufb6a6842013-10-23 13:14:27 -070048#include <linux/clk.h>
wthomas442c7972013-08-05 14:28:17 -070049
Abhishek Rastogibc74e432013-04-02 10:28:22 +053050/*
51 * Global declarations
52 */
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +053053int nss_ctl_redirect __read_mostly = 0;
Sakthi Vignesh Radhakrishnanaf39aad2014-03-31 11:31:03 -070054int nss_ctl_debug __read_mostly = 0;
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053055int nss_rps_cfg __read_mostly = 0;
Saurabh Misra96998db2014-07-10 12:15:48 -070056int nss_ctl_logbuf __read_mostly = 0;
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -080057int nss_jumbo_mru __read_mostly = 0;
58int nss_paged_mode __read_mostly = 0;
Abhishek Rastogibc74e432013-04-02 10:28:22 +053059
60/*
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +053061 * PM client handle
62 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080063#if (NSS_PM_SUPPORT == 1)
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +053064static void *pm_client;
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080065#endif
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +053066
67/*
wthomas626147f2013-09-18 13:12:40 -070068 * Handler to send NSS messages
69 */
Thomas Wufb6a6842013-10-23 13:14:27 -070070struct clk *nss_core0_clk;
wthomas626147f2013-09-18 13:12:40 -070071
72/*
Abhishek Rastogibc74e432013-04-02 10:28:22 +053073 * Top level nss context structure
74 */
75struct nss_top_instance nss_top_main;
wthomas442c7972013-08-05 14:28:17 -070076struct nss_cmd_buffer nss_cmd_buf;
wthomas626147f2013-09-18 13:12:40 -070077struct nss_runtime_sampling nss_runtime_samples;
78struct workqueue_struct *nss_wq;
79
80/*
81 * Work Queue to handle messages to Kernel
82 */
83nss_work_t *nss_work;
Abhishek Rastogibc74e432013-04-02 10:28:22 +053084
Arunkumar T79990cb2015-06-05 10:53:16 +053085extern struct of_device_id nss_dt_ids[];
Abhishek Rastogibc74e432013-04-02 10:28:22 +053086
Abhishek Rastogibc74e432013-04-02 10:28:22 +053087/*
88 * nss_probe()
Arunkumar T79990cb2015-06-05 10:53:16 +053089 * HLOS device probe callback
Abhishek Rastogibc74e432013-04-02 10:28:22 +053090 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080091#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,7,0))
Arunkumar T79990cb2015-06-05 10:53:16 +053092inline int __devinit nss_probe(struct platform_device *nss_dev)
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080093#else
Arunkumar T79990cb2015-06-05 10:53:16 +053094inline int nss_probe(struct platform_device *nss_dev)
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080095#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +053096{
Arunkumar T79990cb2015-06-05 10:53:16 +053097 return nss_hal_probe(nss_dev);
Abhishek Rastogibc74e432013-04-02 10:28:22 +053098}
99
100/*
101 * nss_remove()
Arunkumar T79990cb2015-06-05 10:53:16 +0530102 * HLOS device remove callback
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530103 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800104#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,7,0))
Arunkumar T79990cb2015-06-05 10:53:16 +0530105inline int __devexit nss_remove(struct platform_device *nss_dev)
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800106#else
Arunkumar T79990cb2015-06-05 10:53:16 +0530107inline int nss_remove(struct platform_device *nss_dev)
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800108#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530109{
Arunkumar T79990cb2015-06-05 10:53:16 +0530110 return nss_hal_remove(nss_dev);
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530111}
112
113/*
114 * nss_driver
115 * Platform driver structure for NSS
116 */
117struct platform_driver nss_driver = {
118 .probe = nss_probe,
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800119#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,7,0))
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530120 .remove = __devexit_p(nss_remove),
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800121#else
122 .remove = nss_remove,
123#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530124 .driver = {
125 .name = "qca-nss",
126 .owner = THIS_MODULE,
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800127#if (NSS_DT_SUPPORT == 1)
128 .of_match_table = of_match_ptr(nss_dt_ids),
129#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530130 },
131};
132
Arunkumar T28b2d742015-06-16 22:15:58 +0530133#if (NSS_FREQ_SCALE_SUPPORT == 1)
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530134/*
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530135 * nss_reset_frequency_stats_samples()
136 * Reset all frequency sampling state when auto scaling is turned off.
137 */
138static void nss_reset_frequency_stats_samples (void)
139{
140 nss_runtime_samples.buffer_index = 0;
141 nss_runtime_samples.sum = 0;
142 nss_runtime_samples.average = 0;
143 nss_runtime_samples.sample_count = 0;
144 nss_runtime_samples.message_rate_limit = 0;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530145 nss_runtime_samples.freq_scale_rate_limit_down = 0;
146}
147
148/*
wthomas626147f2013-09-18 13:12:40 -0700149 ***************************************************************************************************
Thomas Wufb6a6842013-10-23 13:14:27 -0700150 * nss_wq_function() is used to queue up requests to change NSS frequencies.
151 * The function will take care of NSS notices and also control clock.
152 * The auto rate algorithmn will queue up requests or the procfs may also queue up these requests.
wthomas626147f2013-09-18 13:12:40 -0700153 ***************************************************************************************************
154 */
155
156/*
157 * nss_wq_function()
158 * Added to Handle BH requests to kernel
159 */
160void nss_wq_function (struct work_struct *work)
161{
162 nss_work_t *my_work = (nss_work_t *)work;
163
Guojun Jin32a3c6d2015-05-06 12:27:52 -0700164 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 -0700165 if (nss_top_main.nss[NSS_CORE_1].state == NSS_CORE_STATE_INITIALIZED) {
166 nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 0);
167 }
Thomas Wufb6a6842013-10-23 13:14:27 -0700168 clk_set_rate(nss_core0_clk, my_work->frequency);
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, 1);
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, 1);
172 }
wthomas626147f2013-09-18 13:12:40 -0700173
Thomas Wu0d112192015-04-13 11:37:22 -0700174#if (NSS_PM_SUPPORT == 1)
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530175 if(!pm_client) {
176 goto out;
177 }
178
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800179 if (my_work->frequency >= NSS_FREQ_733) {
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530180 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_TURBO);
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800181 } else if (my_work->frequency > NSS_FREQ_110) {
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530182 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_NOMINAL);
183 } else {
184 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_IDLE);
185 }
Thomas Wu0d112192015-04-13 11:37:22 -0700186
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530187out:
Thomas Wu0d112192015-04-13 11:37:22 -0700188#endif
wthomas626147f2013-09-18 13:12:40 -0700189 kfree((void *)work);
190}
191
192/*
wthomas442c7972013-08-05 14:28:17 -0700193 * nss_current_freq_handler()
194 * Handle Userspace Frequency Change Requests
195 */
196static int nss_current_freq_handler (ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
197{
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800198 int ret, i;
wthomas626147f2013-09-18 13:12:40 -0700199
200 BUG_ON(!nss_wq);
wthomas442c7972013-08-05 14:28:17 -0700201
202 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
203
wthomasd39fa822013-08-22 16:44:23 -0700204 if (!write) {
wthomas626147f2013-09-18 13:12:40 -0700205 printk("Frequency Set to %d\n", nss_cmd_buf.current_freq);
wthomasd39fa822013-08-22 16:44:23 -0700206 return ret;
wthomas442c7972013-08-05 14:28:17 -0700207 }
wthomasd39fa822013-08-22 16:44:23 -0700208
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800209 /*
210 * Check if frequency exists in frequency Table
211 */
212 i = 0;
Thomas Wu7132bd32015-05-07 15:03:06 -0700213 while (i < NSS_FREQ_MAX_SCALE) {
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800214 if (nss_runtime_samples.freq_scale[i].frequency == nss_cmd_buf.current_freq) {
215 break;
216 }
217 i++;
218 }
Thomas Wu7132bd32015-05-07 15:03:06 -0700219 if (i == NSS_FREQ_MAX_SCALE) {
Thomas Wufb6a6842013-10-23 13:14:27 -0700220 printk("Frequency not found. Please check Frequency Table\n");
wthomas626147f2013-09-18 13:12:40 -0700221 return ret;
wthomasd39fa822013-08-22 16:44:23 -0700222 }
223
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800224 /* Turn off Auto Scale */
225 nss_cmd_buf.auto_scale = 0;
226 nss_runtime_samples.freq_scale_ready = 0;
227
Thomas Wu7409bce2014-05-21 10:56:07 -0700228 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
wthomas626147f2013-09-18 13:12:40 -0700229 if (!nss_work) {
230 nss_info("NSS Freq WQ kmalloc fail");
231 return ret;
232 }
233 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
234 nss_work->frequency = nss_cmd_buf.current_freq;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530235 nss_work->stats_enable = 0;
236
237 /* Ensure we start with a fresh set of samples later */
238 nss_reset_frequency_stats_samples();
239
wthomas626147f2013-09-18 13:12:40 -0700240 queue_work(nss_wq, (struct work_struct *)nss_work);
241
wthomas442c7972013-08-05 14:28:17 -0700242 return ret;
243}
244
245/*
246 * nss_auto_scale_handler()
247 * Enables or Disable Auto Scaling
248 */
249static int nss_auto_scale_handler (ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
250{
251 int ret;
252
253 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
254
wthomas626147f2013-09-18 13:12:40 -0700255 if (!write) {
256 return ret;
257 }
258
Thomas Wufb6a6842013-10-23 13:14:27 -0700259 if (nss_cmd_buf.auto_scale != 1) {
wthomas626147f2013-09-18 13:12:40 -0700260 /*
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530261 * Is auto scaling currently enabled? If so, send the command to
262 * disable stats reporting to NSS
wthomas626147f2013-09-18 13:12:40 -0700263 */
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530264 if (nss_runtime_samples.freq_scale_ready != 0) {
265 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
Thomas Wu7409bce2014-05-21 10:56:07 -0700266 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530267 if (!nss_work) {
268 nss_info("NSS Freq WQ kmalloc fail");
269 return ret;
270 }
271 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
272 nss_work->frequency = nss_cmd_buf.current_freq;
273 nss_work->stats_enable = 0;
274 queue_work(nss_wq, (struct work_struct *)nss_work);
275 nss_runtime_samples.freq_scale_ready = 0;
276
277 /*
278 * The current samples would be stale later when scaling is
279 * enabled again, hence reset them
280 */
281 nss_reset_frequency_stats_samples();
282 }
Thomas Wufb6a6842013-10-23 13:14:27 -0700283 return ret;
wthomas626147f2013-09-18 13:12:40 -0700284 }
wthomas442c7972013-08-05 14:28:17 -0700285
Thomas Wufb6a6842013-10-23 13:14:27 -0700286 /*
287 * Auto Scaling is already being done
288 */
289 if (nss_runtime_samples.freq_scale_ready == 1) {
290 return ret;
291 }
292
293 /*
294 * Setup default values - Middle of Freq Scale Band
295 */
296 nss_runtime_samples.freq_scale_index = 1;
297 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
298
Thomas Wu7409bce2014-05-21 10:56:07 -0700299 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
Thomas Wufb6a6842013-10-23 13:14:27 -0700300 if (!nss_work) {
301 nss_info("NSS Freq WQ kmalloc fail");
302 return ret;
303 }
304 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
305 nss_work->frequency = nss_cmd_buf.current_freq;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530306 nss_work->stats_enable = 1;
Thomas Wufb6a6842013-10-23 13:14:27 -0700307 queue_work(nss_wq, (struct work_struct *)nss_work);
308
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800309 nss_cmd_buf.auto_scale = 0;
Thomas Wufb6a6842013-10-23 13:14:27 -0700310 nss_runtime_samples.freq_scale_ready = 1;
311
wthomas442c7972013-08-05 14:28:17 -0700312 return ret;
313}
314
315/*
316 * nss_get_freq_table_handler()
317 * Display Support Freq and Ex how to Change.
318 */
Thomas Wu05495be2013-12-19 14:24:24 -0800319static int nss_get_freq_table_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
wthomas442c7972013-08-05 14:28:17 -0700320{
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800321 int ret, i;
wthomas442c7972013-08-05 14:28:17 -0700322
323 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
324
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800325 printk("Frequency Supported - ");
326 i = 0;
Thomas Wu7132bd32015-05-07 15:03:06 -0700327 while (i < NSS_FREQ_MAX_SCALE) {
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800328 printk("%dMhz ", nss_runtime_samples.freq_scale[i].frequency/1000000);
329 i++;
Thomas Wu0a0a9c92013-11-21 15:28:19 -0800330 }
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800331 printk("\n");
wthomas442c7972013-08-05 14:28:17 -0700332
333 return ret;
334}
335
336/*
Thomas Wu05495be2013-12-19 14:24:24 -0800337 * nss_get_average_inst_handler()
338 * Display AVG Inst Per Ms.
339 */
340static int nss_get_average_inst_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
341{
342 int ret;
343
344 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
345
346 if (!ret && !write) {
347 printk("Current Inst Per Ms %x\n", nss_runtime_samples.average);
348 }
349
350 return ret;
351}
Arunkumar T28b2d742015-06-16 22:15:58 +0530352#endif
Thomas Wu05495be2013-12-19 14:24:24 -0800353
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800354#if (NSS_FW_DBG_SUPPORT == 1)
Thomas Wu05495be2013-12-19 14:24:24 -0800355/*
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530356 * nss_debug_handler()
357 * Enable NSS debug output
358 */
359static int nss_debug_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
360{
361 int ret;
362
363 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
364 if (!ret) {
365 if ((write) && (nss_ctl_debug != 0)) {
366 printk("Enabling NSS SPI Debug\n");
367 nss_hal_debug_enable();
368 }
369 }
370
371 return ret;
372}
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800373#endif
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530374
375/*
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530376 * nss_rps_handler()
377 * Enable NSS RPS
378 */
379static int nss_rpscfg_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
380{
381 struct nss_top_instance *nss_top = &nss_top_main;
382 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
383 int ret;
384
385 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
386 if (!ret) {
387 if ((write) && (nss_rps_cfg == 1)) {
388 printk("Enabling NSS RPS\n");
Vijay Dewangan634ce592015-01-07 17:21:09 -0800389
390 return nss_n2h_rps_cfg(nss_ctx, 1);
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530391 }
392
393 if ((write) && (nss_rps_cfg == 0)) {
394 printk("Runtime disabling of NSS RPS not supported \n");
395 return ret;
396 }
397
398 if (write) {
399 printk("Invalid input value.Valid values are 0 and 1 \n");
400 }
401
402 }
403
404 return ret;
405}
406
407/*
Thomas Wu52075f42014-02-06 16:32:42 -0800408 * nss_coredump_handler()
409 * Send Signal To Coredump NSS Cores
410 */
411static int nss_coredump_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
412{
Guojun Jin32a3c6d2015-05-06 12:27:52 -0700413 struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[NSS_CORE_0];
Thomas Wu52075f42014-02-06 16:32:42 -0800414 int ret;
415
416 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
417 if (!ret) {
418 if ((write) && (nss_ctl_debug != 0)) {
419 printk("Coredumping to DDR\n");
Stephen Wangf26af762015-07-15 12:00:30 -0700420 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 -0800421 }
422 }
423
424 return ret;
425}
426
427/*
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800428 * nss_jumbo_mru_handler()
429 * Sysctl to modify nss_jumbo_mru
430 */
431static int nss_jumbo_mru_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
432{
433 int ret;
434
435 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
436 if (ret) {
437 return ret;
438 }
439
440 if (write) {
441 nss_core_set_jumbo_mru(nss_jumbo_mru);
442 nss_info("jumbo_mru set to %d\n", nss_jumbo_mru);
443 }
444
445 return ret;
446}
447
448/* nss_paged_mode_handler()
449 * Sysctl to modify nss_paged_mode.
450 */
451
452static int nss_paged_mode_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
453{
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_paged_mode(nss_paged_mode);
463 nss_info("paged_mode set to %d\n", nss_paged_mode);
464 }
465
466 return ret;
467}
468
Arunkumar T28b2d742015-06-16 22:15:58 +0530469#if (NSS_FREQ_SCALE_SUPPORT == 1)
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800470/*
wthomas442c7972013-08-05 14:28:17 -0700471 * sysctl-tuning infrastructure.
472 */
473static ctl_table nss_freq_table[] = {
474 {
475 .procname = "current_freq",
476 .data = &nss_cmd_buf.current_freq,
477 .maxlen = sizeof(int),
478 .mode = 0644,
479 .proc_handler = &nss_current_freq_handler,
480 },
481 {
482 .procname = "freq_table",
483 .data = &nss_cmd_buf.max_freq,
484 .maxlen = sizeof(int),
485 .mode = 0644,
486 .proc_handler = &nss_get_freq_table_handler,
487 },
488 {
489 .procname = "auto_scale",
490 .data = &nss_cmd_buf.auto_scale,
491 .maxlen = sizeof(int),
492 .mode = 0644,
493 .proc_handler = &nss_auto_scale_handler,
494 },
Thomas Wu05495be2013-12-19 14:24:24 -0800495 {
496 .procname = "inst_per_sec",
497 .data = &nss_cmd_buf.average_inst,
498 .maxlen = sizeof(int),
499 .mode = 0644,
500 .proc_handler = &nss_get_average_inst_handler,
501 },
wthomas442c7972013-08-05 14:28:17 -0700502 { }
503};
Arunkumar T28b2d742015-06-16 22:15:58 +0530504#endif
wthomas442c7972013-08-05 14:28:17 -0700505
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530506static ctl_table nss_general_table[] = {
507 {
508 .procname = "redirect",
509 .data = &nss_ctl_redirect,
510 .maxlen = sizeof(int),
511 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700512 .proc_handler = proc_dointvec,
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530513 },
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800514#if (NSS_FW_DBG_SUPPORT == 1)
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530515 {
516 .procname = "debug",
517 .data = &nss_ctl_debug,
518 .maxlen = sizeof(int),
519 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700520 .proc_handler = &nss_debug_handler,
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530521 },
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800522#endif
Thomas Wu52075f42014-02-06 16:32:42 -0800523 {
524 .procname = "coredump",
525 .data = &nss_cmd_buf.coredump,
526 .maxlen = sizeof(int),
527 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700528 .proc_handler = &nss_coredump_handler,
Thomas Wu52075f42014-02-06 16:32:42 -0800529 },
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530530 {
531 .procname = "rps",
532 .data = &nss_rps_cfg,
533 .maxlen = sizeof(int),
534 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700535 .proc_handler = &nss_rpscfg_handler,
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530536 },
Saurabh Misra96998db2014-07-10 12:15:48 -0700537 {
538 .procname = "logbuf",
539 .data = &nss_ctl_logbuf,
540 .maxlen = sizeof(int),
541 .mode = 0644,
542 .proc_handler = &nss_logbuffer_handler,
543 },
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800544 {
545 .procname = "jumbo_mru",
546 .data = &nss_jumbo_mru,
547 .maxlen = sizeof(int),
548 .mode = 0644,
549 .proc_handler = &nss_jumbo_mru_handler,
550 },
551 {
552 .procname = "paged_mode",
553 .data = &nss_paged_mode,
554 .maxlen = sizeof(int),
555 .mode = 0644,
556 .proc_handler = &nss_paged_mode_handler,
557 },
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530558 { }
559};
560
wthomas442c7972013-08-05 14:28:17 -0700561static ctl_table nss_clock_dir[] = {
Arunkumar T28b2d742015-06-16 22:15:58 +0530562#if (NSS_FREQ_SCALE_SUPPORT == 1)
wthomas442c7972013-08-05 14:28:17 -0700563 {
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530564 .procname = "clock",
565 .mode = 0555,
566 .child = nss_freq_table,
567 },
Arunkumar T28b2d742015-06-16 22:15:58 +0530568#endif
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530569 {
570 .procname = "general",
571 .mode = 0555,
572 .child = nss_general_table,
wthomas442c7972013-08-05 14:28:17 -0700573 },
574 { }
575};
576
577static ctl_table nss_root_dir[] = {
578 {
579 .procname = "nss",
580 .mode = 0555,
581 .child = nss_clock_dir,
582 },
583 { }
584};
585
586static ctl_table nss_root[] = {
587 {
588 .procname = "dev",
589 .mode = 0555,
590 .child = nss_root_dir,
591 },
592 { }
593};
594
595static struct ctl_table_header *nss_dev_header;
596
597/*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530598 * nss_init()
599 * Registers nss driver
600 */
601static int __init nss_init(void)
602{
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800603#if (NSS_DT_SUPPORT == 1)
604 struct device_node *cmn = NULL;
605 struct resource res_nss_fpb_base;
606#endif
607
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530608 nss_info("Init NSS driver");
609
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800610#if (NSS_DT_SUPPORT == 1)
611 /*
612 * Get reference to NSS common device node
613 */
614 cmn = of_find_node_by_name(NULL, "nss-common");
615 if (!cmn) {
616 nss_info("cannot find nss-common node\n");
617 return -EFAULT;
618 }
619
620 if (of_address_to_resource(cmn, 0, &res_nss_fpb_base) != 0) {
621 nss_info("of_address_to_resource() return error for nss_fpb_base\n");
622 of_node_put(cmn);
623 return -EFAULT;
624 }
625
626 nss_top_main.nss_fpb_base = ioremap_nocache(res_nss_fpb_base.start,
627 resource_size(&res_nss_fpb_base));
628 if (!nss_top_main.nss_fpb_base) {
629 nss_info("ioremap fail for nss_fpb_base\n");
630 of_node_put(cmn);
631 return -EFAULT;
632 }
633
634 nss_top_main.nss_hal_common_init_done = false;
635
636 /*
637 * Release reference to NSS common device node
638 */
639 of_node_put(cmn);
640 cmn = NULL;
641#else
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530642 /*
643 * Perform clock init common to all NSS cores
644 */
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530645 nss_hal_common_reset(&(nss_top_main.clk_src));
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530646
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800647#endif /* NSS_DT_SUPPORT */
648
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530649 /*
650 * Enable spin locks
651 */
652 spin_lock_init(&(nss_top_main.lock));
653 spin_lock_init(&(nss_top_main.stats_lock));
654
655 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530656 * Enable NSS statistics
657 */
658 nss_stats_init();
659
660 /*
wthomas442c7972013-08-05 14:28:17 -0700661 * Register sysctl table.
662 */
663 nss_dev_header = register_sysctl_table(nss_root);
664
665 /*
Vijay Dewangan9db18752014-09-15 16:25:01 -0700666 * Registering sysctl for ipv4/6 specific config.
667 */
668 nss_ipv4_register_sysctl();
669 nss_ipv6_register_sysctl();
670
Vijay Dewanganac7efc42015-02-09 16:04:53 -0800671 /*
672 * Registering sysctl for n2h empty pool buffer.
673 */
674 nss_n2h_empty_pool_buf_register_sysctl();
675
Vijay Dewangan9db18752014-09-15 16:25:01 -0700676 /*
wthomas626147f2013-09-18 13:12:40 -0700677 * Setup Runtime Sample values
678 */
wthomas626147f2013-09-18 13:12:40 -0700679 nss_runtime_samples.freq_scale_index = 1;
680 nss_runtime_samples.freq_scale_ready = 0;
Thomas Wu9681f7e2013-11-06 13:12:57 -0800681 nss_runtime_samples.freq_scale_rate_limit_down = 0;
wthomas626147f2013-09-18 13:12:40 -0700682 nss_runtime_samples.buffer_index = 0;
683 nss_runtime_samples.sum = 0;
684 nss_runtime_samples.sample_count = 0;
685 nss_runtime_samples.average = 0;
686 nss_runtime_samples.message_rate_limit = 0;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530687 nss_runtime_samples.initialized = 0;
wthomas626147f2013-09-18 13:12:40 -0700688
Thomas Wu05495be2013-12-19 14:24:24 -0800689 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
690
wthomas626147f2013-09-18 13:12:40 -0700691 /*
692 * Initial Workqueue
693 */
694 nss_wq = create_workqueue("nss_freq_queue");
695
Thomas Wu0d112192015-04-13 11:37:22 -0700696#if (NSS_PM_SUPPORT == 1)
wthomas626147f2013-09-18 13:12:40 -0700697 /*
Pamidipati, Vijay7f413b52013-09-24 19:07:12 +0530698 * Initialize NSS Bus PM module
699 */
700 nss_pm_init();
701
702 /*
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530703 * Register with Bus driver
704 */
705 pm_client = nss_pm_client_register(NSS_PM_CLIENT_NETAP);
706 if (!pm_client) {
707 nss_warning("Error registering with PM driver");
708 }
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800709#endif
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530710
711 /*
Radha krishna Simha Jiguru7f424d52015-02-10 19:41:01 +0530712 * Initialize mtu size needed as start
713 */
714 nss_top_main.prev_mtu_sz = NSS_GMAC_NORMAL_FRAME_MTU;
715
716 /*
Guojun Jin1cb79522015-06-22 22:34:22 -0700717 * register panic handler and timeout control
718 */
719 nss_coredump_notify_register();
720 nss_coredump_init_delay_work();
721
722 /*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530723 * Register platform_driver
724 */
725 return platform_driver_register(&nss_driver);
726}
727
728/*
729 * nss_cleanup()
730 * Unregisters nss driver
731 */
732static void __exit nss_cleanup(void)
733{
734 nss_info("Exit NSS driver");
wthomas442c7972013-08-05 14:28:17 -0700735
736 if (nss_dev_header)
737 unregister_sysctl_table(nss_dev_header);
738
Vijay Dewangan9db18752014-09-15 16:25:01 -0700739 /*
Vijay Dewangan488e5372014-12-29 21:40:11 -0800740 * Unregister n2h specific sysctl
741 */
742 nss_n2h_empty_pool_buf_unregister_sysctl();
743
744 /*
Vijay Dewangan9db18752014-09-15 16:25:01 -0700745 * Unregister ipv4/6 specific sysctl
746 */
747 nss_ipv4_unregister_sysctl();
748 nss_ipv6_unregister_sysctl();
749
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800750#if (NSS_DT_SUPPORT == 1)
751 if(nss_top_main.nss_fpb_base) {
752 iounmap(nss_top_main.nss_fpb_base);
753 nss_top_main.nss_fpb_base = 0;
754 }
755#endif
756
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530757 platform_driver_unregister(&nss_driver);
758}
759
760module_init(nss_init);
761module_exit(nss_cleanup);
762
763MODULE_DESCRIPTION("QCA NSS Driver");
764MODULE_AUTHOR("Qualcomm Atheros Inc");
765MODULE_LICENSE("Dual BSD/GPL");