blob: a2064d38bcc8bf06399da1ae40417ef8a6ab8865 [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/*
Thomas Wucd6b35a2015-07-14 10:17:48 -070073 * Handle fabric requests - only on new kernel
74 */
75#if (NSS_DT_SUPPORT == 1)
76struct clk *nss_fab0_clk;
77struct clk *nss_fab1_clk;
78#endif
79
80/*
Abhishek Rastogibc74e432013-04-02 10:28:22 +053081 * Top level nss context structure
82 */
83struct nss_top_instance nss_top_main;
wthomas442c7972013-08-05 14:28:17 -070084struct nss_cmd_buffer nss_cmd_buf;
wthomas626147f2013-09-18 13:12:40 -070085struct nss_runtime_sampling nss_runtime_samples;
86struct workqueue_struct *nss_wq;
87
88/*
89 * Work Queue to handle messages to Kernel
90 */
91nss_work_t *nss_work;
Abhishek Rastogibc74e432013-04-02 10:28:22 +053092
Arunkumar T79990cb2015-06-05 10:53:16 +053093extern struct of_device_id nss_dt_ids[];
Abhishek Rastogibc74e432013-04-02 10:28:22 +053094
Abhishek Rastogibc74e432013-04-02 10:28:22 +053095/*
96 * nss_probe()
Arunkumar T79990cb2015-06-05 10:53:16 +053097 * HLOS device probe callback
Abhishek Rastogibc74e432013-04-02 10:28:22 +053098 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080099#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,7,0))
Arunkumar T79990cb2015-06-05 10:53:16 +0530100inline int __devinit nss_probe(struct platform_device *nss_dev)
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800101#else
Arunkumar T79990cb2015-06-05 10:53:16 +0530102inline int nss_probe(struct platform_device *nss_dev)
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800103#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530104{
Arunkumar T79990cb2015-06-05 10:53:16 +0530105 return nss_hal_probe(nss_dev);
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530106}
107
108/*
109 * nss_remove()
Arunkumar T79990cb2015-06-05 10:53:16 +0530110 * HLOS device remove callback
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530111 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800112#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,7,0))
Arunkumar T79990cb2015-06-05 10:53:16 +0530113inline int __devexit nss_remove(struct platform_device *nss_dev)
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800114#else
Arunkumar T79990cb2015-06-05 10:53:16 +0530115inline int nss_remove(struct platform_device *nss_dev)
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800116#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530117{
Arunkumar T79990cb2015-06-05 10:53:16 +0530118 return nss_hal_remove(nss_dev);
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530119}
120
121/*
122 * nss_driver
123 * Platform driver structure for NSS
124 */
125struct platform_driver nss_driver = {
126 .probe = nss_probe,
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800127#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,7,0))
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530128 .remove = __devexit_p(nss_remove),
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800129#else
130 .remove = nss_remove,
131#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530132 .driver = {
133 .name = "qca-nss",
134 .owner = THIS_MODULE,
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800135#if (NSS_DT_SUPPORT == 1)
136 .of_match_table = of_match_ptr(nss_dt_ids),
137#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530138 },
139};
140
Arunkumar T28b2d742015-06-16 22:15:58 +0530141#if (NSS_FREQ_SCALE_SUPPORT == 1)
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530142/*
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530143 * nss_reset_frequency_stats_samples()
144 * Reset all frequency sampling state when auto scaling is turned off.
145 */
146static void nss_reset_frequency_stats_samples (void)
147{
148 nss_runtime_samples.buffer_index = 0;
149 nss_runtime_samples.sum = 0;
150 nss_runtime_samples.average = 0;
151 nss_runtime_samples.sample_count = 0;
152 nss_runtime_samples.message_rate_limit = 0;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530153 nss_runtime_samples.freq_scale_rate_limit_down = 0;
154}
155
156/*
wthomas626147f2013-09-18 13:12:40 -0700157 ***************************************************************************************************
Thomas Wufb6a6842013-10-23 13:14:27 -0700158 * nss_wq_function() is used to queue up requests to change NSS frequencies.
159 * The function will take care of NSS notices and also control clock.
160 * The auto rate algorithmn will queue up requests or the procfs may also queue up these requests.
wthomas626147f2013-09-18 13:12:40 -0700161 ***************************************************************************************************
162 */
163
164/*
165 * nss_wq_function()
166 * Added to Handle BH requests to kernel
167 */
168void nss_wq_function (struct work_struct *work)
169{
170 nss_work_t *my_work = (nss_work_t *)work;
171
Guojun Jin32a3c6d2015-05-06 12:27:52 -0700172 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 -0700173 if (nss_top_main.nss[NSS_CORE_1].state == NSS_CORE_STATE_INITIALIZED) {
174 nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 0);
175 }
Thomas Wufb6a6842013-10-23 13:14:27 -0700176 clk_set_rate(nss_core0_clk, my_work->frequency);
Guojun Jin32a3c6d2015-05-06 12:27:52 -0700177 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 -0700178 if (nss_top_main.nss[NSS_CORE_1].state == NSS_CORE_STATE_INITIALIZED) {
179 nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 1);
180 }
wthomas626147f2013-09-18 13:12:40 -0700181
Thomas Wucd6b35a2015-07-14 10:17:48 -0700182/*
183 * If we are running NSS_PM_SUPPORT, we are on banana
184 * otherwise, we check if we are are on new kernel by checking if the
185 * fabric lookups are not NULL (success in init()))
186 */
Thomas Wu0d112192015-04-13 11:37:22 -0700187#if (NSS_PM_SUPPORT == 1)
Thomas Wucd6b35a2015-07-14 10:17:48 -0700188 if (!pm_client) {
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530189 goto out;
190 }
191
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800192 if (my_work->frequency >= NSS_FREQ_733) {
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530193 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_TURBO);
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800194 } else if (my_work->frequency > NSS_FREQ_110) {
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530195 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_NOMINAL);
196 } else {
197 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_IDLE);
198 }
Thomas Wu0d112192015-04-13 11:37:22 -0700199
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530200out:
Thomas Wucd6b35a2015-07-14 10:17:48 -0700201#else
202#if (NSS_DT_SUPPORT == 1)
203 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 }
214 }
215#endif
Thomas Wu0d112192015-04-13 11:37:22 -0700216#endif
wthomas626147f2013-09-18 13:12:40 -0700217 kfree((void *)work);
218}
219
220/*
wthomas442c7972013-08-05 14:28:17 -0700221 * nss_current_freq_handler()
222 * Handle Userspace Frequency Change Requests
223 */
224static int nss_current_freq_handler (ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
225{
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800226 int ret, i;
wthomas626147f2013-09-18 13:12:40 -0700227
228 BUG_ON(!nss_wq);
wthomas442c7972013-08-05 14:28:17 -0700229
230 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
231
wthomasd39fa822013-08-22 16:44:23 -0700232 if (!write) {
wthomas626147f2013-09-18 13:12:40 -0700233 printk("Frequency Set to %d\n", nss_cmd_buf.current_freq);
wthomasd39fa822013-08-22 16:44:23 -0700234 return ret;
wthomas442c7972013-08-05 14:28:17 -0700235 }
wthomasd39fa822013-08-22 16:44:23 -0700236
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800237 /*
238 * Check if frequency exists in frequency Table
239 */
240 i = 0;
Thomas Wu7132bd32015-05-07 15:03:06 -0700241 while (i < NSS_FREQ_MAX_SCALE) {
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800242 if (nss_runtime_samples.freq_scale[i].frequency == nss_cmd_buf.current_freq) {
243 break;
244 }
245 i++;
246 }
Thomas Wu7132bd32015-05-07 15:03:06 -0700247 if (i == NSS_FREQ_MAX_SCALE) {
Thomas Wufb6a6842013-10-23 13:14:27 -0700248 printk("Frequency not found. Please check Frequency Table\n");
wthomas626147f2013-09-18 13:12:40 -0700249 return ret;
wthomasd39fa822013-08-22 16:44:23 -0700250 }
251
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800252 /* Turn off Auto Scale */
253 nss_cmd_buf.auto_scale = 0;
254 nss_runtime_samples.freq_scale_ready = 0;
255
Thomas Wu7409bce2014-05-21 10:56:07 -0700256 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
wthomas626147f2013-09-18 13:12:40 -0700257 if (!nss_work) {
258 nss_info("NSS Freq WQ kmalloc fail");
259 return ret;
260 }
261 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
262 nss_work->frequency = nss_cmd_buf.current_freq;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530263 nss_work->stats_enable = 0;
264
265 /* Ensure we start with a fresh set of samples later */
266 nss_reset_frequency_stats_samples();
267
wthomas626147f2013-09-18 13:12:40 -0700268 queue_work(nss_wq, (struct work_struct *)nss_work);
269
wthomas442c7972013-08-05 14:28:17 -0700270 return ret;
271}
272
273/*
274 * nss_auto_scale_handler()
275 * Enables or Disable Auto Scaling
276 */
277static int nss_auto_scale_handler (ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
278{
279 int ret;
280
281 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
282
wthomas626147f2013-09-18 13:12:40 -0700283 if (!write) {
284 return ret;
285 }
286
Thomas Wufb6a6842013-10-23 13:14:27 -0700287 if (nss_cmd_buf.auto_scale != 1) {
wthomas626147f2013-09-18 13:12:40 -0700288 /*
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530289 * Is auto scaling currently enabled? If so, send the command to
290 * disable stats reporting to NSS
wthomas626147f2013-09-18 13:12:40 -0700291 */
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530292 if (nss_runtime_samples.freq_scale_ready != 0) {
293 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
Thomas Wu7409bce2014-05-21 10:56:07 -0700294 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530295 if (!nss_work) {
296 nss_info("NSS Freq WQ kmalloc fail");
297 return ret;
298 }
299 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
300 nss_work->frequency = nss_cmd_buf.current_freq;
301 nss_work->stats_enable = 0;
302 queue_work(nss_wq, (struct work_struct *)nss_work);
303 nss_runtime_samples.freq_scale_ready = 0;
304
305 /*
306 * The current samples would be stale later when scaling is
307 * enabled again, hence reset them
308 */
309 nss_reset_frequency_stats_samples();
310 }
Thomas Wufb6a6842013-10-23 13:14:27 -0700311 return ret;
wthomas626147f2013-09-18 13:12:40 -0700312 }
wthomas442c7972013-08-05 14:28:17 -0700313
Thomas Wufb6a6842013-10-23 13:14:27 -0700314 /*
315 * Auto Scaling is already being done
316 */
317 if (nss_runtime_samples.freq_scale_ready == 1) {
318 return ret;
319 }
320
321 /*
322 * Setup default values - Middle of Freq Scale Band
323 */
324 nss_runtime_samples.freq_scale_index = 1;
325 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
326
Thomas Wu7409bce2014-05-21 10:56:07 -0700327 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
Thomas Wufb6a6842013-10-23 13:14:27 -0700328 if (!nss_work) {
329 nss_info("NSS Freq WQ kmalloc fail");
330 return ret;
331 }
332 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
333 nss_work->frequency = nss_cmd_buf.current_freq;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530334 nss_work->stats_enable = 1;
Thomas Wufb6a6842013-10-23 13:14:27 -0700335 queue_work(nss_wq, (struct work_struct *)nss_work);
336
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800337 nss_cmd_buf.auto_scale = 0;
Thomas Wufb6a6842013-10-23 13:14:27 -0700338 nss_runtime_samples.freq_scale_ready = 1;
339
wthomas442c7972013-08-05 14:28:17 -0700340 return ret;
341}
342
343/*
344 * nss_get_freq_table_handler()
345 * Display Support Freq and Ex how to Change.
346 */
Thomas Wu05495be2013-12-19 14:24:24 -0800347static 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 -0700348{
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800349 int ret, i;
wthomas442c7972013-08-05 14:28:17 -0700350
351 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
352
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800353 printk("Frequency Supported - ");
354 i = 0;
Thomas Wu7132bd32015-05-07 15:03:06 -0700355 while (i < NSS_FREQ_MAX_SCALE) {
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800356 printk("%dMhz ", nss_runtime_samples.freq_scale[i].frequency/1000000);
357 i++;
Thomas Wu0a0a9c92013-11-21 15:28:19 -0800358 }
Thomas Wu0e2fc4f2015-03-04 15:39:14 -0800359 printk("\n");
wthomas442c7972013-08-05 14:28:17 -0700360
361 return ret;
362}
363
364/*
Thomas Wu05495be2013-12-19 14:24:24 -0800365 * nss_get_average_inst_handler()
366 * Display AVG Inst Per Ms.
367 */
368static int nss_get_average_inst_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
369{
370 int ret;
371
372 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
373
374 if (!ret && !write) {
375 printk("Current Inst Per Ms %x\n", nss_runtime_samples.average);
376 }
377
378 return ret;
379}
Arunkumar T28b2d742015-06-16 22:15:58 +0530380#endif
Thomas Wu05495be2013-12-19 14:24:24 -0800381
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800382#if (NSS_FW_DBG_SUPPORT == 1)
Thomas Wu05495be2013-12-19 14:24:24 -0800383/*
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530384 * nss_debug_handler()
385 * Enable NSS debug output
386 */
387static int nss_debug_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
388{
389 int ret;
390
391 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
392 if (!ret) {
393 if ((write) && (nss_ctl_debug != 0)) {
394 printk("Enabling NSS SPI Debug\n");
395 nss_hal_debug_enable();
396 }
397 }
398
399 return ret;
400}
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800401#endif
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530402
403/*
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530404 * nss_rps_handler()
405 * Enable NSS RPS
406 */
407static int nss_rpscfg_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
408{
409 struct nss_top_instance *nss_top = &nss_top_main;
410 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
411 int ret;
412
413 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
414 if (!ret) {
415 if ((write) && (nss_rps_cfg == 1)) {
416 printk("Enabling NSS RPS\n");
Vijay Dewangan634ce592015-01-07 17:21:09 -0800417
418 return nss_n2h_rps_cfg(nss_ctx, 1);
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530419 }
420
421 if ((write) && (nss_rps_cfg == 0)) {
422 printk("Runtime disabling of NSS RPS not supported \n");
423 return ret;
424 }
425
426 if (write) {
427 printk("Invalid input value.Valid values are 0 and 1 \n");
428 }
429
430 }
431
432 return ret;
433}
434
435/*
Thomas Wu52075f42014-02-06 16:32:42 -0800436 * nss_coredump_handler()
437 * Send Signal To Coredump NSS Cores
438 */
439static int nss_coredump_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
440{
Guojun Jin32a3c6d2015-05-06 12:27:52 -0700441 struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[NSS_CORE_0];
Thomas Wu52075f42014-02-06 16:32:42 -0800442 int ret;
443
444 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
445 if (!ret) {
446 if ((write) && (nss_ctl_debug != 0)) {
447 printk("Coredumping to DDR\n");
448 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_COREDUMP_START);
449 }
450 }
451
452 return ret;
453}
454
455/*
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800456 * nss_jumbo_mru_handler()
457 * Sysctl to modify nss_jumbo_mru
458 */
459static int nss_jumbo_mru_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
460{
461 int ret;
462
463 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
464 if (ret) {
465 return ret;
466 }
467
468 if (write) {
469 nss_core_set_jumbo_mru(nss_jumbo_mru);
470 nss_info("jumbo_mru set to %d\n", nss_jumbo_mru);
471 }
472
473 return ret;
474}
475
476/* nss_paged_mode_handler()
477 * Sysctl to modify nss_paged_mode.
478 */
479
480static int nss_paged_mode_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
481{
482 int ret;
483
484 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
485 if (ret) {
486 return ret;
487 }
488
489 if (write) {
490 nss_core_set_paged_mode(nss_paged_mode);
491 nss_info("paged_mode set to %d\n", nss_paged_mode);
492 }
493
494 return ret;
495}
496
Arunkumar T28b2d742015-06-16 22:15:58 +0530497#if (NSS_FREQ_SCALE_SUPPORT == 1)
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800498/*
wthomas442c7972013-08-05 14:28:17 -0700499 * sysctl-tuning infrastructure.
500 */
501static ctl_table nss_freq_table[] = {
502 {
503 .procname = "current_freq",
504 .data = &nss_cmd_buf.current_freq,
505 .maxlen = sizeof(int),
506 .mode = 0644,
507 .proc_handler = &nss_current_freq_handler,
508 },
509 {
510 .procname = "freq_table",
511 .data = &nss_cmd_buf.max_freq,
512 .maxlen = sizeof(int),
513 .mode = 0644,
514 .proc_handler = &nss_get_freq_table_handler,
515 },
516 {
517 .procname = "auto_scale",
518 .data = &nss_cmd_buf.auto_scale,
519 .maxlen = sizeof(int),
520 .mode = 0644,
521 .proc_handler = &nss_auto_scale_handler,
522 },
Thomas Wu05495be2013-12-19 14:24:24 -0800523 {
524 .procname = "inst_per_sec",
525 .data = &nss_cmd_buf.average_inst,
526 .maxlen = sizeof(int),
527 .mode = 0644,
528 .proc_handler = &nss_get_average_inst_handler,
529 },
wthomas442c7972013-08-05 14:28:17 -0700530 { }
531};
Arunkumar T28b2d742015-06-16 22:15:58 +0530532#endif
wthomas442c7972013-08-05 14:28:17 -0700533
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530534static ctl_table nss_general_table[] = {
535 {
536 .procname = "redirect",
537 .data = &nss_ctl_redirect,
538 .maxlen = sizeof(int),
539 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700540 .proc_handler = proc_dointvec,
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530541 },
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800542#if (NSS_FW_DBG_SUPPORT == 1)
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530543 {
544 .procname = "debug",
545 .data = &nss_ctl_debug,
546 .maxlen = sizeof(int),
547 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700548 .proc_handler = &nss_debug_handler,
Abhishek Rastogi1626a902013-11-21 17:09:49 +0530549 },
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -0800550#endif
Thomas Wu52075f42014-02-06 16:32:42 -0800551 {
552 .procname = "coredump",
553 .data = &nss_cmd_buf.coredump,
554 .maxlen = sizeof(int),
555 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700556 .proc_handler = &nss_coredump_handler,
Thomas Wu52075f42014-02-06 16:32:42 -0800557 },
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530558 {
559 .procname = "rps",
560 .data = &nss_rps_cfg,
561 .maxlen = sizeof(int),
562 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -0700563 .proc_handler = &nss_rpscfg_handler,
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +0530564 },
Saurabh Misra96998db2014-07-10 12:15:48 -0700565 {
566 .procname = "logbuf",
567 .data = &nss_ctl_logbuf,
568 .maxlen = sizeof(int),
569 .mode = 0644,
570 .proc_handler = &nss_logbuffer_handler,
571 },
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -0800572 {
573 .procname = "jumbo_mru",
574 .data = &nss_jumbo_mru,
575 .maxlen = sizeof(int),
576 .mode = 0644,
577 .proc_handler = &nss_jumbo_mru_handler,
578 },
579 {
580 .procname = "paged_mode",
581 .data = &nss_paged_mode,
582 .maxlen = sizeof(int),
583 .mode = 0644,
584 .proc_handler = &nss_paged_mode_handler,
585 },
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530586 { }
587};
588
wthomas442c7972013-08-05 14:28:17 -0700589static ctl_table nss_clock_dir[] = {
Arunkumar T28b2d742015-06-16 22:15:58 +0530590#if (NSS_FREQ_SCALE_SUPPORT == 1)
wthomas442c7972013-08-05 14:28:17 -0700591 {
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530592 .procname = "clock",
593 .mode = 0555,
594 .child = nss_freq_table,
595 },
Arunkumar T28b2d742015-06-16 22:15:58 +0530596#endif
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +0530597 {
598 .procname = "general",
599 .mode = 0555,
600 .child = nss_general_table,
wthomas442c7972013-08-05 14:28:17 -0700601 },
602 { }
603};
604
605static ctl_table nss_root_dir[] = {
606 {
607 .procname = "nss",
608 .mode = 0555,
609 .child = nss_clock_dir,
610 },
611 { }
612};
613
614static ctl_table nss_root[] = {
615 {
616 .procname = "dev",
617 .mode = 0555,
618 .child = nss_root_dir,
619 },
620 { }
621};
622
623static struct ctl_table_header *nss_dev_header;
624
625/*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530626 * nss_init()
627 * Registers nss driver
628 */
629static int __init nss_init(void)
630{
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800631#if (NSS_DT_SUPPORT == 1)
632 struct device_node *cmn = NULL;
633 struct resource res_nss_fpb_base;
634#endif
635
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530636 nss_info("Init NSS driver");
637
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800638#if (NSS_DT_SUPPORT == 1)
639 /*
640 * Get reference to NSS common device node
641 */
642 cmn = of_find_node_by_name(NULL, "nss-common");
643 if (!cmn) {
644 nss_info("cannot find nss-common node\n");
645 return -EFAULT;
646 }
647
648 if (of_address_to_resource(cmn, 0, &res_nss_fpb_base) != 0) {
649 nss_info("of_address_to_resource() return error for nss_fpb_base\n");
650 of_node_put(cmn);
651 return -EFAULT;
652 }
653
654 nss_top_main.nss_fpb_base = ioremap_nocache(res_nss_fpb_base.start,
655 resource_size(&res_nss_fpb_base));
656 if (!nss_top_main.nss_fpb_base) {
657 nss_info("ioremap fail for nss_fpb_base\n");
658 of_node_put(cmn);
659 return -EFAULT;
660 }
661
662 nss_top_main.nss_hal_common_init_done = false;
663
664 /*
665 * Release reference to NSS common device node
666 */
667 of_node_put(cmn);
668 cmn = NULL;
669#else
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530670 /*
671 * Perform clock init common to all NSS cores
672 */
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530673 nss_hal_common_reset(&(nss_top_main.clk_src));
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530674
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800675#endif /* NSS_DT_SUPPORT */
676
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530677 /*
678 * Enable spin locks
679 */
680 spin_lock_init(&(nss_top_main.lock));
681 spin_lock_init(&(nss_top_main.stats_lock));
682
683 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530684 * Enable NSS statistics
685 */
686 nss_stats_init();
687
688 /*
wthomas442c7972013-08-05 14:28:17 -0700689 * Register sysctl table.
690 */
691 nss_dev_header = register_sysctl_table(nss_root);
692
693 /*
Vijay Dewangan9db18752014-09-15 16:25:01 -0700694 * Registering sysctl for ipv4/6 specific config.
695 */
696 nss_ipv4_register_sysctl();
697 nss_ipv6_register_sysctl();
698
Vijay Dewanganac7efc42015-02-09 16:04:53 -0800699 /*
700 * Registering sysctl for n2h empty pool buffer.
701 */
702 nss_n2h_empty_pool_buf_register_sysctl();
703
Vijay Dewangan9db18752014-09-15 16:25:01 -0700704 /*
wthomas626147f2013-09-18 13:12:40 -0700705 * Setup Runtime Sample values
706 */
wthomas626147f2013-09-18 13:12:40 -0700707 nss_runtime_samples.freq_scale_index = 1;
708 nss_runtime_samples.freq_scale_ready = 0;
Thomas Wu9681f7e2013-11-06 13:12:57 -0800709 nss_runtime_samples.freq_scale_rate_limit_down = 0;
wthomas626147f2013-09-18 13:12:40 -0700710 nss_runtime_samples.buffer_index = 0;
711 nss_runtime_samples.sum = 0;
712 nss_runtime_samples.sample_count = 0;
713 nss_runtime_samples.average = 0;
714 nss_runtime_samples.message_rate_limit = 0;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530715 nss_runtime_samples.initialized = 0;
wthomas626147f2013-09-18 13:12:40 -0700716
Thomas Wu05495be2013-12-19 14:24:24 -0800717 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
718
wthomas626147f2013-09-18 13:12:40 -0700719 /*
720 * Initial Workqueue
721 */
722 nss_wq = create_workqueue("nss_freq_queue");
723
Thomas Wu0d112192015-04-13 11:37:22 -0700724#if (NSS_PM_SUPPORT == 1)
wthomas626147f2013-09-18 13:12:40 -0700725 /*
Pamidipati, Vijay7f413b52013-09-24 19:07:12 +0530726 * Initialize NSS Bus PM module
727 */
728 nss_pm_init();
729
730 /*
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530731 * Register with Bus driver
732 */
733 pm_client = nss_pm_client_register(NSS_PM_CLIENT_NETAP);
734 if (!pm_client) {
735 nss_warning("Error registering with PM driver");
736 }
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800737#endif
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530738
739 /*
Radha krishna Simha Jiguru7f424d52015-02-10 19:41:01 +0530740 * Initialize mtu size needed as start
741 */
742 nss_top_main.prev_mtu_sz = NSS_GMAC_NORMAL_FRAME_MTU;
743
744 /*
Guojun Jin1cb79522015-06-22 22:34:22 -0700745 * register panic handler and timeout control
746 */
747 nss_coredump_notify_register();
748 nss_coredump_init_delay_work();
749
750 /*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530751 * Register platform_driver
752 */
753 return platform_driver_register(&nss_driver);
754}
755
756/*
757 * nss_cleanup()
758 * Unregisters nss driver
759 */
760static void __exit nss_cleanup(void)
761{
762 nss_info("Exit NSS driver");
wthomas442c7972013-08-05 14:28:17 -0700763
764 if (nss_dev_header)
765 unregister_sysctl_table(nss_dev_header);
766
Vijay Dewangan9db18752014-09-15 16:25:01 -0700767 /*
Vijay Dewangan488e5372014-12-29 21:40:11 -0800768 * Unregister n2h specific sysctl
769 */
770 nss_n2h_empty_pool_buf_unregister_sysctl();
771
772 /*
Vijay Dewangan9db18752014-09-15 16:25:01 -0700773 * Unregister ipv4/6 specific sysctl
774 */
775 nss_ipv4_unregister_sysctl();
776 nss_ipv6_unregister_sysctl();
777
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800778#if (NSS_DT_SUPPORT == 1)
779 if(nss_top_main.nss_fpb_base) {
780 iounmap(nss_top_main.nss_fpb_base);
781 nss_top_main.nss_fpb_base = 0;
782 }
783#endif
784
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530785 platform_driver_unregister(&nss_driver);
786}
787
788module_init(nss_init);
789module_exit(nss_cleanup);
790
791MODULE_DESCRIPTION("QCA NSS Driver");
792MODULE_AUTHOR("Qualcomm Atheros Inc");
793MODULE_LICENSE("Dual BSD/GPL");