blob: 29203b25438f5d00cb6549afad46c9f6d297a4d2 [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>
Thomas Wufb6a6842013-10-23 13:14:27 -070030#include <nss_clocks.h>
Abhishek Rastogibc74e432013-04-02 10:28:22 +053031
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)
38#include <linux/of.h>
39#include <linux/of_net.h>
40#include <linux/of_irq.h>
41#include <linux/of_address.h>
42#include <linux/reset.h>
43#else
Abhishek Rastogibc74e432013-04-02 10:28:22 +053044#include <mach/msm_nss.h>
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080045#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +053046
wthomas442c7972013-08-05 14:28:17 -070047#include <linux/sysctl.h>
48#include <linux/regulator/consumer.h>
Thomas Wufb6a6842013-10-23 13:14:27 -070049#include <linux/clk.h>
Thomas Wu49008962014-04-02 14:50:47 -070050#include <linux/firmware.h>
51
Saurabh Misra09dddeb2014-09-30 16:38:07 -070052#include "nss_capwap.h"
53
Thomas Wu49008962014-04-02 14:50:47 -070054/*
55 * Macros
56 */
57#define MIN_IMG_SIZE 64*1024
Radha krishna Simha Jiguru6e74d572014-05-13 11:30:20 +053058#define NETAP0_IMAGE "qca-nss0.bin"
59#define NETAP1_IMAGE "qca-nss1.bin"
wthomas442c7972013-08-05 14:28:17 -070060
Abhishek Rastogibc74e432013-04-02 10:28:22 +053061/*
62 * Global declarations
63 */
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +053064int nss_ctl_redirect __read_mostly = 0;
Sakthi Vignesh Radhakrishnanaf39aad2014-03-31 11:31:03 -070065int nss_ctl_debug __read_mostly = 0;
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053066int nss_rps_cfg __read_mostly = 0;
Saurabh Misra96998db2014-07-10 12:15:48 -070067int nss_ctl_logbuf __read_mostly = 0;
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -080068int nss_jumbo_mru __read_mostly = 0;
69int nss_paged_mode __read_mostly = 0;
Abhishek Rastogibc74e432013-04-02 10:28:22 +053070
71/*
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +053072 * PM client handle
73 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080074#if (NSS_PM_SUPPORT == 1)
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +053075static void *pm_client;
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -080076#endif
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +053077
78/*
wthomas626147f2013-09-18 13:12:40 -070079 * Handler to send NSS messages
80 */
81void *nss_freq_change_context;
Thomas Wufb6a6842013-10-23 13:14:27 -070082struct clk *nss_core0_clk;
wthomas626147f2013-09-18 13:12:40 -070083
84/*
Abhishek Rastogibc74e432013-04-02 10:28:22 +053085 * Top level nss context structure
86 */
87struct nss_top_instance nss_top_main;
wthomas442c7972013-08-05 14:28:17 -070088struct nss_cmd_buffer nss_cmd_buf;
wthomas626147f2013-09-18 13:12:40 -070089struct nss_runtime_sampling nss_runtime_samples;
90struct workqueue_struct *nss_wq;
91
92/*
93 * Work Queue to handle messages to Kernel
94 */
95nss_work_t *nss_work;
Abhishek Rastogibc74e432013-04-02 10:28:22 +053096
97/*
98 * File local/Static variables/functions
99 */
100
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530101static const struct net_device_ops nss_netdev_ops;
102static const struct ethtool_ops nss_ethtool_ops;
103
104/*
105 * nss_dummy_netdev_setup()
106 * Dummy setup for net_device handler
107 */
108static void nss_dummy_netdev_setup(struct net_device *ndev)
109{
wthomas626147f2013-09-18 13:12:40 -0700110
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530111}
112
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530113/*
114 * nss_handle_irq()
115 * HLOS interrupt handler for nss interrupts
116 */
117static irqreturn_t nss_handle_irq (int irq, void *ctx)
118{
119 struct int_ctx_instance *int_ctx = (struct int_ctx_instance *) ctx;
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +0530120 struct nss_ctx_instance *nss_ctx = int_ctx->nss_ctx;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530121
122 /*
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +0530123 * Mask interrupt until our bottom half re-enables it
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530124 */
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +0530125 nss_hal_disable_interrupt(nss_ctx->nmap, int_ctx->irq,
126 int_ctx->shift_factor, NSS_HAL_SUPPORTED_INTERRUPTS);
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530127
128 /*
129 * Schedule tasklet to process interrupt cause
130 */
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530131 napi_schedule(&int_ctx->napi);
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530132 return IRQ_HANDLED;
133}
134
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800135#if (NSS_DT_SUPPORT == 1)
136/*
137 * nss_drv_of_get_pdata()
138 * Retrieve platform data from device node.
139 */
140static struct nss_platform_data *nss_drv_of_get_pdata(struct device_node *np,
141 struct platform_device *pdev)
142{
143 struct nss_platform_data *npd = NULL;
144 struct nss_ctx_instance *nss_ctx = NULL;
145 struct nss_top_instance *nss_top = &nss_top_main;
146 uint32_t val;
147 struct resource res_nphys, res_vphys;
148 int32_t i;
149
150 npd = devm_kzalloc(&pdev->dev, sizeof(struct nss_platform_data), GFP_KERNEL);
151 if (!npd) {
152 return NULL;
153 }
154
155 if (of_property_read_u32(np, "qcom,id", &npd->id)
156 || of_property_read_u32(np, "qcom,rst_addr", &npd->rst_addr)
157 || of_property_read_u32(np, "qcom,load_addr", &npd->load_addr)
158 || of_property_read_u32(np, "qcom,turbo_frequency", &npd->turbo_frequency)
159 || of_property_read_u32(np, "qcom,gmac0_enabled", &npd->gmac_enabled[0])
160 || of_property_read_u32(np, "qcom,gmac1_enabled", &npd->gmac_enabled[1])
161 || of_property_read_u32(np, "qcom,gmac2_enabled", &npd->gmac_enabled[2])
162 || of_property_read_u32(np, "qcom,gmac3_enabled", &npd->gmac_enabled[3])
163 || of_property_read_u32(np, "qcom,num_irq", &npd->num_irq)) {
164 pr_err("%s: error reading critical device node properties\n", np->name);
165 goto out;
166 }
167
168 nss_ctx = &nss_top->nss[npd->id];
169 nss_ctx->id = npd->id;
170
171 if (of_address_to_resource(np, 0, &res_nphys) != 0) {
172 nss_info("%p: nss%d: of_address_to_resource() fail for nphys \n", nss_ctx, nss_ctx->id);
173 goto out;
174 }
175
176 if (of_address_to_resource(np, 1, &res_vphys) != 0) {
177 nss_info("%p: nss%d: of_address_to_resource() fail for vphys \n", nss_ctx, nss_ctx->id);
178 goto out;
179 }
180
181 /*
182 * Save physical addresses
183 */
184 npd->nphys = res_nphys.start;
185 npd->vphys = res_vphys.start;
186
187 npd->nmap = (uint32_t)ioremap_nocache(npd->nphys, resource_size(&res_nphys));
188 if (!npd->nmap) {
189 nss_info("%p: nss%d: ioremap() fail for nphys \n", nss_ctx, nss_ctx->id);
190 goto out;
191 }
192
193 npd->vmap = (uint32_t)ioremap_nocache(npd->vphys, resource_size(&res_vphys));
194 if (!npd->vmap) {
195 nss_info("%p: nss%d: ioremap() fail for vphys \n", nss_ctx, nss_ctx->id);
196 goto out;
197 }
198
199 /*
200 * Clear TCM memory used by this core
201 */
202 for (i = 0; i < resource_size(&res_vphys) ; i += 4) {
203 nss_write_32((uint32_t)npd->vmap, i, 0);
204 }
205
206 /*
207 * Get IRQ numbers
208 */
209 for (val = 0 ; val < npd->num_irq ; val++) {
210 npd->irq[val] = irq_of_parse_and_map(np, val);
211 if (!npd->irq[val]) {
212 nss_info("%p: nss%d: irq_of_parse_and_map() fail for irq %d\n",
213 nss_ctx, nss_ctx->id, val);
214 goto out;
215 }
216 }
217
218 if (of_property_read_u32(np, "qcom,ipv4_enabled", &npd->ipv4_enabled)
219 || of_property_read_u32(np, "qcom,ipv6_enabled", &npd->ipv6_enabled)
220 || of_property_read_u32(np, "qcom,l2switch_enabled", &npd->l2switch_enabled)
221 || of_property_read_u32(np, "qcom,crypto_enabled", &npd->crypto_enabled)
222 || of_property_read_u32(np, "qcom,ipsec_enabled", &npd->ipsec_enabled)
223 || of_property_read_u32(np, "qcom,wlan_enabled", &npd->wlan_enabled)
224 || of_property_read_u32(np, "qcom,tun6rd_enabled", &npd->tun6rd_enabled)
225 || of_property_read_u32(np, "qcom,tunipip6_enabled", &npd->tunipip6_enabled)
226 || of_property_read_u32(np, "qcom,shaping_enabled", &npd->shaping_enabled)) {
227 pr_warn("%s: error reading non-critical device node properties\n", np->name);
228 }
229
230 return npd;
231
232out:
233 if (npd->nmap) {
234 iounmap((void *)npd->nmap);
235 }
236
237 if (npd->vmap) {
238 iounmap((void *)npd->vmap);
239 }
240
241 devm_kfree(&pdev->dev, npd);
242
243 return NULL;
244}
245
246#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530247/*
248 * nss_probe()
249 * HLOS device probe callback
250 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800251#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,7,0))
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530252static int __devinit nss_probe(struct platform_device *nss_dev)
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800253#else
254static int nss_probe(struct platform_device *nss_dev)
255#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530256{
257 struct nss_top_instance *nss_top = &nss_top_main;
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800258 struct nss_ctx_instance *nss_ctx = NULL;
259 struct nss_platform_data *npd = NULL;
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530260 struct netdev_priv_instance *ndev_priv;
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800261#if (NSS_DT_SUPPORT == 1)
262 struct reset_control *rstctl = NULL;
263#endif
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530264 int i, err = 0;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530265
Thomas Wu49008962014-04-02 14:50:47 -0700266 const struct firmware *nss_fw = NULL;
267 int rc = -ENODEV;
268 void __iomem *load_mem;
269
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800270#if (NSS_DT_SUPPORT == 1)
271 struct device_node *np = NULL;
272
273 if (nss_top_main.nss_hal_common_init_done == false) {
274 /*
275 * Perform clock init common to all NSS cores
276 */
277 struct clk *nss_tcm_src = NULL;
278 struct clk *nss_tcm_clk = NULL;
279
280 /*
281 * Attach debug interface to TLMM
282 */
283 nss_write_32((uint32_t)nss_top_main.nss_fpb_base, NSS_REGS_FPB_CSR_CFG_OFFSET, 0x360);
284
285 /*
286 * NSS TCM CLOCK
287 */
288 nss_tcm_src = clk_get(&nss_dev->dev, NSS_TCM_SRC_CLK);
289 if (IS_ERR(nss_tcm_src)) {
290 pr_err("nss-driver: cannot get clock: " NSS_TCM_SRC_CLK);
291 return -EFAULT;
292 }
293
294 clk_set_rate(nss_tcm_src, NSSTCM_FREQ);
295 clk_prepare(nss_tcm_src);
296 clk_enable(nss_tcm_src);
297
298 nss_tcm_clk = clk_get(&nss_dev->dev, NSS_TCM_CLK);
299 if (IS_ERR(nss_tcm_clk)) {
300 pr_err("nss-driver: cannot get clock: " NSS_TCM_CLK);
301 return -EFAULT;
302 }
303
304 clk_prepare(nss_tcm_clk);
305 clk_enable(nss_tcm_clk);
306
307 nss_top_main.nss_hal_common_init_done = true;
308 nss_info("nss_hal_common_reset Done.\n");
309 }
310
311 if (nss_dev->dev.of_node) {
312 /*
313 * Device Tree based init
314 */
315
316 np = of_node_get(nss_dev->dev.of_node);
317 npd = nss_drv_of_get_pdata(np, nss_dev);
318
319 of_node_put(np);
320
321 if (!npd) {
322 return -EFAULT;
323 }
324
325 nss_ctx = &nss_top->nss[npd->id];
326 nss_ctx->id = npd->id;
327 nss_dev->id = nss_ctx->id;
328
329 } else {
330 /*
331 * Platform Device based init
332 */
333
334 npd = (struct nss_platform_data *) nss_dev->dev.platform_data;
335 nss_ctx = &nss_top->nss[nss_dev->id];
336 nss_ctx->id = nss_dev->id;
337 }
338
339#else
340 npd = (struct nss_platform_data *) nss_dev->dev.platform_data;
341 nss_ctx = &nss_top->nss[nss_dev->id];
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530342 nss_ctx->id = nss_dev->id;
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800343#endif
344 nss_ctx->nss_top = nss_top;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530345
wthomas442c7972013-08-05 14:28:17 -0700346 nss_info("%p: NSS_DEV_ID %s \n", nss_ctx, dev_name(&nss_dev->dev));
347
Stephen Wang38e89bc2014-11-06 11:34:45 -0800348 /*
Radha krishna Simha Jiguru27bff9a2014-03-18 16:31:34 +0530349 * F/W load from NSS Driver
350 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800351 if (nss_ctx->id == 0) {
Radha krishna Simha Jiguru27bff9a2014-03-18 16:31:34 +0530352 rc = request_firmware(&nss_fw, NETAP0_IMAGE, &(nss_dev->dev));
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800353 } else if (nss_ctx->id == 1) {
Radha krishna Simha Jiguru27bff9a2014-03-18 16:31:34 +0530354 rc = request_firmware(&nss_fw, NETAP1_IMAGE, &(nss_dev->dev));
355 } else {
Samarjeet Banerjee7bce8c52014-05-02 15:32:13 +0530356 nss_warning("%p: Invalid nss dev: %d \n", nss_ctx, nss_dev->id);
Radha krishna Simha Jiguru27bff9a2014-03-18 16:31:34 +0530357 }
358
359 /*
360 * Check if the file read is successful
361 */
362 if (rc) {
363 nss_warning("%p: request_firmware failed with err code: %d", nss_ctx, rc);
364 err = rc;
365 goto err_init_0;
Radha krishna Simha Jiguru27bff9a2014-03-18 16:31:34 +0530366 }
367
Radha krishna Simha Jiguru9ed88c62014-04-11 12:12:33 +0530368 if (nss_fw->size < MIN_IMG_SIZE) {
369 nss_warning("%p: nss firmware is truncated, size:%d", nss_ctx, nss_fw->size);
Thomas Wu49008962014-04-02 14:50:47 -0700370 }
371
Radha krishna Simha Jiguru9ed88c62014-04-11 12:12:33 +0530372 load_mem = ioremap_nocache(npd->load_addr, nss_fw->size);
373 if (load_mem == NULL) {
374 nss_warning("%p: ioremap_nocache failed: %x", nss_ctx, npd->load_addr);
375 release_firmware(nss_fw);
Thomas Wu49008962014-04-02 14:50:47 -0700376 goto err_init_0;
Thomas Wu49008962014-04-02 14:50:47 -0700377 }
378
Saurabh Misra96998db2014-07-10 12:15:48 -0700379 printk("nss_driver - fw of size %u bytes copied to load addr: %x, nss_id : %d\n", nss_fw->size, npd->load_addr, nss_dev->id);
Radha krishna Simha Jiguru9ed88c62014-04-11 12:12:33 +0530380 memcpy_toio(load_mem, nss_fw->data, nss_fw->size);
381 release_firmware(nss_fw);
382 iounmap(load_mem);
383
wthomas442c7972013-08-05 14:28:17 -0700384 /*
385 * Both NSS cores controlled by same regulator, Hook only Once
386 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800387 if (!nss_ctx->id) {
Thomas Wufb6a6842013-10-23 13:14:27 -0700388 nss_core0_clk = clk_get(&nss_dev->dev, "nss_core_clk");
389 if (IS_ERR(nss_core0_clk)) {
wthomas442c7972013-08-05 14:28:17 -0700390
Thomas Wufb6a6842013-10-23 13:14:27 -0700391 err = PTR_ERR(nss_core0_clk);
wthomas442c7972013-08-05 14:28:17 -0700392 nss_info("%p: Regulator %s get failed, err=%d\n", nss_ctx, dev_name(&nss_dev->dev), err);
393 return err;
394
wthomas442c7972013-08-05 14:28:17 -0700395 }
Thomas Wufb6a6842013-10-23 13:14:27 -0700396 clk_set_rate(nss_core0_clk, NSS_FREQ_550);
397 clk_prepare(nss_core0_clk);
398 clk_enable(nss_core0_clk);
Thomas Wu0a0a9c92013-11-21 15:28:19 -0800399
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800400#if (NSS_PM_SUPPORT == 1)
Thomas Wu0a0a9c92013-11-21 15:28:19 -0800401 /*
402 * Check if turbo is supported
403 */
404 if (npd->turbo_frequency) {
405 /*
406 * Turbo is supported
407 */
408 printk("nss_driver - Turbo Support %d\n", npd->turbo_frequency);
409 nss_runtime_samples.freq_scale_sup_max = NSS_MAX_CPU_SCALES;
Pamidipati, Vijayf9b5a272014-01-22 14:24:10 +0530410 nss_pm_set_turbo();
Thomas Wu0a0a9c92013-11-21 15:28:19 -0800411 } else {
412 printk("nss_driver - Turbo No Support %d\n", npd->turbo_frequency);
413 nss_runtime_samples.freq_scale_sup_max = NSS_MAX_CPU_SCALES - 1;
414 }
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800415#else
416 printk("nss_driver - Turbo Not Supported\n");
417#endif
wthomas442c7972013-08-05 14:28:17 -0700418 }
419
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530420 /*
Sakthi Vignesh Radhakrishnand923e342013-12-09 11:53:03 -0800421 * Get load address of NSS firmware
422 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800423 nss_info("%p: Setting NSS%d Firmware load address to %x\n", nss_ctx, nss_ctx->id, npd->load_addr);
424 nss_top->nss[nss_ctx->id].load = npd->load_addr;
Sakthi Vignesh Radhakrishnand923e342013-12-09 11:53:03 -0800425
426 /*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530427 * Get virtual and physical memory addresses for nss logical/hardware address maps
428 */
429
430 /*
431 * Virtual address of CSM space
432 */
433 nss_ctx->nmap = npd->nmap;
434 nss_assert(nss_ctx->nmap);
435
436 /*
437 * Physical address of CSM space
438 */
439 nss_ctx->nphys = npd->nphys;
440 nss_assert(nss_ctx->nphys);
441
442 /*
443 * Virtual address of logical registers space
444 */
445 nss_ctx->vmap = npd->vmap;
446 nss_assert(nss_ctx->vmap);
447
448 /*
449 * Physical address of logical registers space
450 */
451 nss_ctx->vphys = npd->vphys;
452 nss_assert(nss_ctx->vphys);
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530453 nss_info("%d:ctx=%p, vphys=%x, vmap=%x, nphys=%x, nmap=%x",
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800454 nss_ctx->id, nss_ctx, nss_ctx->vphys, nss_ctx->vmap, nss_ctx->nphys, nss_ctx->nmap);
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530455
456 /*
457 * Register netdevice handlers
458 */
459 nss_ctx->int_ctx[0].ndev = alloc_netdev(sizeof(struct netdev_priv_instance),
460 "qca-nss-dev%d", nss_dummy_netdev_setup);
461 if (nss_ctx->int_ctx[0].ndev == NULL) {
462 nss_warning("%p: Could not allocate net_device #0", nss_ctx);
463 err = -ENOMEM;
464 goto err_init_0;
465 }
466
467 nss_ctx->int_ctx[0].ndev->netdev_ops = &nss_netdev_ops;
468 nss_ctx->int_ctx[0].ndev->ethtool_ops = &nss_ethtool_ops;
469 err = register_netdev(nss_ctx->int_ctx[0].ndev);
470 if (err) {
471 nss_warning("%p: Could not register net_device #0", nss_ctx);
472 goto err_init_1;
473 }
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530474
475 /*
476 * request for IRQs
477 *
478 * WARNING: CPU affinities should be set using OS supported methods
479 */
480 nss_ctx->int_ctx[0].nss_ctx = nss_ctx;
481 nss_ctx->int_ctx[0].shift_factor = 0;
482 nss_ctx->int_ctx[0].irq = npd->irq[0];
483 err = request_irq(npd->irq[0], nss_handle_irq, IRQF_DISABLED, "nss", &nss_ctx->int_ctx[0]);
484 if (err) {
485 nss_warning("%d: IRQ0 request failed", nss_dev->id);
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530486 goto err_init_2;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530487 }
488
489 /*
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530490 * Register NAPI for NSS core interrupt #0
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530491 */
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530492 ndev_priv = netdev_priv(nss_ctx->int_ctx[0].ndev);
493 ndev_priv->int_ctx = &nss_ctx->int_ctx[0];
494 netif_napi_add(nss_ctx->int_ctx[0].ndev, &nss_ctx->int_ctx[0].napi, nss_core_handle_napi, 64);
495 napi_enable(&nss_ctx->int_ctx[0].napi);
496 nss_ctx->int_ctx[0].napi_active = true;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530497
498 /*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530499 * Check if second interrupt is supported on this nss core
500 */
501 if (npd->num_irq > 1) {
502 nss_info("%d: This NSS core supports two interrupts", nss_dev->id);
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530503
504 /*
505 * Register netdevice handlers
506 */
507 nss_ctx->int_ctx[1].ndev = alloc_netdev(sizeof(struct netdev_priv_instance),
508 "qca-nss-dev%d", nss_dummy_netdev_setup);
509 if (nss_ctx->int_ctx[1].ndev == NULL) {
510 nss_warning("%p: Could not allocate net_device #1", nss_ctx);
511 err = -ENOMEM;
512 goto err_init_3;
513 }
514
515 nss_ctx->int_ctx[1].ndev->netdev_ops = &nss_netdev_ops;
516 nss_ctx->int_ctx[1].ndev->ethtool_ops = &nss_ethtool_ops;
517 err = register_netdev(nss_ctx->int_ctx[1].ndev);
518 if (err) {
519 nss_warning("%p: Could not register net_device #1", nss_ctx);
520 goto err_init_4;
521 }
522
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530523 nss_ctx->int_ctx[1].nss_ctx = nss_ctx;
524 nss_ctx->int_ctx[1].shift_factor = 15;
525 nss_ctx->int_ctx[1].irq = npd->irq[1];
526 err = request_irq(npd->irq[1], nss_handle_irq, IRQF_DISABLED, "nss", &nss_ctx->int_ctx[1]);
527 if (err) {
528 nss_warning("%d: IRQ1 request failed for nss", nss_dev->id);
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530529 goto err_init_5;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530530 }
531
532 /*
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530533 * Register NAPI for NSS core interrupt #1
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530534 */
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530535 ndev_priv = netdev_priv(nss_ctx->int_ctx[1].ndev);
536 ndev_priv->int_ctx = &nss_ctx->int_ctx[1];
537 netif_napi_add(nss_ctx->int_ctx[1].ndev, &nss_ctx->int_ctx[1].napi, nss_core_handle_napi, 64);
538 napi_enable(&nss_ctx->int_ctx[1].napi);
539 nss_ctx->int_ctx[1].napi_active = true;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530540 }
541
542 spin_lock_bh(&(nss_top->lock));
543
544 /*
545 * Check functionalities are supported by this NSS core
546 */
Murat Sezgin7a705422014-01-30 16:09:22 -0800547 if (npd->shaping_enabled == NSS_FEATURE_ENABLED) {
548 nss_top->shaping_handler_id = nss_dev->id;
Radha krishna Simha Jiguru9ed88c62014-04-11 12:12:33 +0530549 printk(KERN_INFO "%p: NSS Shaping is enabled, handler id: %u\n", __func__, nss_top->shaping_handler_id);
Murat Sezgin7a705422014-01-30 16:09:22 -0800550 }
551
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530552 if (npd->ipv4_enabled == NSS_FEATURE_ENABLED) {
553 nss_top->ipv4_handler_id = nss_dev->id;
Abhishek Rastogi9da47472014-03-18 19:46:15 +0530554 nss_ipv4_register_handler();
555 nss_pppoe_register_handler();
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530556 nss_eth_rx_register_handler();
557 nss_n2h_register_handler();
Sol Kavy2783c072014-04-05 12:53:13 -0700558 nss_virt_if_register_handler();
Tushar Mathura3e03052014-04-07 20:17:28 +0530559 nss_lag_register_handler();
Ankit Dhanuka9b430252014-08-12 13:53:41 +0530560 nss_dynamic_interface_register_handler();
Saurabh Misra09dddeb2014-09-30 16:38:07 -0700561 nss_top->capwap_handler_id = nss_dev->id;
562 nss_capwap_init();
Ankit Dhanuka9b430252014-08-12 13:53:41 +0530563
Sol Kavy4013e282014-04-06 15:57:00 -0700564 for (i = 0; i < NSS_MAX_VIRTUAL_INTERFACES; i++) {
565 nss_top->virt_if_handler_id[i] = nss_dev->id;
566 }
Ankit Dhanuka65935322014-10-08 19:20:47 +0530567
568 nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR] = nss_dev->id;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530569 }
570
Selin Dag6d9b0c12014-11-04 18:27:21 -0800571 if (npd->ipv4_reasm_enabled == NSS_FEATURE_ENABLED) {
572 nss_top->ipv4_reasm_handler_id = nss_dev->id;
573 nss_ipv4_reasm_register_handler();
574 }
575
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530576 if (npd->ipv6_enabled == NSS_FEATURE_ENABLED) {
577 nss_top->ipv6_handler_id = nss_dev->id;
Abhishek Rastogi9da47472014-03-18 19:46:15 +0530578 nss_ipv6_register_handler();
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530579 }
580
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530581 if (npd->crypto_enabled == NSS_FEATURE_ENABLED) {
582 nss_top->crypto_handler_id = nss_dev->id;
Abhishek Rastogi9da47472014-03-18 19:46:15 +0530583 nss_crypto_register_handler();
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530584 }
585
586 if (npd->ipsec_enabled == NSS_FEATURE_ENABLED) {
587 nss_top->ipsec_handler_id = nss_dev->id;
Abhishek Rastogi9da47472014-03-18 19:46:15 +0530588 nss_ipsec_register_handler();
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530589 }
590
591 if (npd->wlan_enabled == NSS_FEATURE_ENABLED) {
592 nss_top->wlan_handler_id = nss_dev->id;
593 }
594
Bharath M Kumar0d87e912013-08-12 18:32:57 +0530595 if (npd->tun6rd_enabled == NSS_FEATURE_ENABLED) {
596 nss_top->tun6rd_handler_id = nss_dev->id;
597 }
598
Bharath M Kumar614bbf82013-08-31 20:18:44 +0530599 if (npd->tunipip6_enabled == NSS_FEATURE_ENABLED) {
600 nss_top->tunipip6_handler_id = nss_dev->id;
Abhishek Rastogi9da47472014-03-18 19:46:15 +0530601 nss_tunipip6_register_handler();
Bharath M Kumar614bbf82013-08-31 20:18:44 +0530602 }
603
Ankit Dhanuka607508d2014-08-21 20:20:34 +0530604 if (npd->gre_redir_enabled == NSS_FEATURE_ENABLED) {
605 nss_top->gre_redir_handler_id = nss_dev->id;
606 nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR] = nss_dev->id;
607 nss_gre_redir_register_handler();
Ankit Dhanuka2ae20a82014-08-25 18:04:00 +0530608 nss_sjack_register_handler();
Ankit Dhanuka607508d2014-08-21 20:20:34 +0530609 }
610
Stephen Wang38e89bc2014-11-06 11:34:45 -0800611 /*
612 * Mark data plane enabled so when nss core init done we call register to nss-gmac
613 */
614 for (i = 0 ; i < NSS_MAX_PHYSICAL_INTERFACES ; i ++) {
615 if (npd->gmac_enabled[i] == NSS_FEATURE_ENABLED) {
616 nss_data_plane_set_enabled(i);
617 }
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530618 }
619
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800620#if (NSS_PM_SUPPORT == 1)
Sundarajan Srinivasandedd8e42014-10-06 11:59:34 -0700621 nss_freq_register_handler();
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800622#endif
Thomas Wuc3e382c2014-10-29 15:35:13 -0700623 nss_lso_rx_register_handler();
624
wthomas626147f2013-09-18 13:12:40 -0700625 nss_top->frequency_handler_id = nss_dev->id;
626
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530627 spin_unlock_bh(&(nss_top->lock));
628
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530629 /*
630 * Initialize decongestion callbacks to NULL
631 */
632 for (i = 0; i< NSS_MAX_CLIENTS; i++) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530633 nss_ctx->queue_decongestion_callback[i] = 0;
634 nss_ctx->queue_decongestion_ctx[i] = 0;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530635 }
636
637 spin_lock_init(&(nss_ctx->decongest_cb_lock));
638 nss_ctx->magic = NSS_CTX_MAGIC;
639
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530640 nss_info("%p: Reseting NSS core %d now", nss_ctx, nss_ctx->id);
641
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530642 /*
643 * Enable clocks and bring NSS core out of reset
644 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800645#if (NSS_DT_SUPPORT == 1)
646 /*
647 * Remove UBI32 reset clamp
648 */
649 rstctl = devm_reset_control_get(&nss_dev->dev, NSS_CORE_CLK_RST_CLAMP);
650 if (IS_ERR(rstctl)) {
651 nss_info("%p: Deassert UBI32 reset clamp failed", nss_ctx, nss_ctx->id);
652 err = -EFAULT;
653 goto err_init_5;
654 }
655 reset_control_deassert(rstctl);
656 mdelay(1);
657 reset_control_put(rstctl);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530658
659 /*
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800660 * Remove UBI32 core clamp
661 */
662 rstctl = devm_reset_control_get(&nss_dev->dev, NSS_CORE_CLAMP);
663 if (IS_ERR(rstctl)) {
664 nss_info("%p: Deassert UBI32 core clamp failed", nss_ctx, nss_ctx->id);
665 err = -EFAULT;
666 goto err_init_5;
667 }
668 reset_control_deassert(rstctl);
669 mdelay(1);
670 reset_control_put(rstctl);
671
672 /*
673 * Remove UBI32 AHB reset
674 */
675 rstctl = devm_reset_control_get(&nss_dev->dev, NSS_CORE_AHB_RESET);
676 if (IS_ERR(rstctl)) {
677 nss_info("%p: Deassert AHB reset failed", nss_ctx, nss_ctx->id);
678 err = -EFAULT;
679 goto err_init_5;
680 }
681 reset_control_deassert(rstctl);
682 mdelay(1);
683 reset_control_put(rstctl);
684
685 /*
686 * Remove UBI32 AXI reset
687 */
688 rstctl = devm_reset_control_get(&nss_dev->dev, NSS_CORE_AXI_RESET);
689 if (IS_ERR(rstctl)) {
690 nss_info("%p: Deassert AXI reset failed", nss_ctx, nss_ctx->id);
691 err = -EFAULT;
692 goto err_init_5;
693 }
694 reset_control_deassert(rstctl);
695 mdelay(1);
696 reset_control_put(rstctl);
697
698 nss_hal_core_reset(nss_ctx->nmap, nss_ctx->load);
699#else
700 nss_hal_core_reset(nss_dev->id, nss_ctx->nmap, nss_ctx->load, nss_top->clk_src);
701#endif
702 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530703 * Enable interrupts for NSS core
704 */
705 nss_hal_enable_interrupt(nss_ctx->nmap, nss_ctx->int_ctx[0].irq,
706 nss_ctx->int_ctx[0].shift_factor, NSS_HAL_SUPPORTED_INTERRUPTS);
707
708 if (npd->num_irq > 1) {
709 nss_hal_enable_interrupt(nss_ctx->nmap, nss_ctx->int_ctx[1].irq,
710 nss_ctx->int_ctx[1].shift_factor, NSS_HAL_SUPPORTED_INTERRUPTS);
711 }
712
Radhakrishna Jigurub7346cf2013-12-16 13:08:43 +0530713 /*
714 * Initialize max buffer size for NSS core
715 */
716 nss_ctx->max_buf_size = NSS_NBUF_PAYLOAD_SIZE;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530717 nss_info("%p: All resources initialized and nss core%d has been brought out of reset", nss_ctx, nss_dev->id);
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530718 goto err_init_0;
719
720err_init_5:
721 unregister_netdev(nss_ctx->int_ctx[1].ndev);
722err_init_4:
723 free_netdev(nss_ctx->int_ctx[1].ndev);
724err_init_3:
725 free_irq(npd->irq[0], &nss_ctx->int_ctx[0]);
726err_init_2:
727 unregister_netdev(nss_ctx->int_ctx[0].ndev);
728err_init_1:
729 free_netdev(nss_ctx->int_ctx[0].ndev);
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800730
731#if (NSS_DT_SUPPORT == 1)
732 if (nss_dev->dev.of_node) {
733 if (npd->nmap) {
734 iounmap((void *)npd->nmap);
735 }
736
737 if (npd->vmap) {
738 iounmap((void *)npd->vmap);
739 }
740 }
741#endif
742
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530743err_init_0:
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800744
745#if (NSS_DT_SUPPORT == 1)
746 if (nss_dev->dev.of_node) {
747 devm_kfree(&nss_dev->dev, npd);
748 }
749
750#endif
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530751 return err;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530752}
753
754/*
755 * nss_remove()
756 * HLOS device remove callback
757 */
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800758#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,7,0))
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530759static int __devexit nss_remove(struct platform_device *nss_dev)
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800760#else
761static int nss_remove(struct platform_device *nss_dev)
762#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530763{
764 struct nss_top_instance *nss_top = &nss_top_main;
765 struct nss_ctx_instance *nss_ctx = &nss_top->nss[nss_dev->id];
Stephen Wang38e89bc2014-11-06 11:34:45 -0800766 int i;
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530767
768 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530769 * Clean-up debugfs
770 */
771 nss_stats_clean();
772
773 /*
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530774 * Disable interrupts and bottom halves in HLOS
775 * Disable interrupts from NSS to HLOS
776 */
777 nss_hal_disable_interrupt(nss_ctx->nmap, nss_ctx->int_ctx[0].irq,
778 nss_ctx->int_ctx[0].shift_factor, NSS_HAL_SUPPORTED_INTERRUPTS);
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530779
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530780 free_irq(nss_ctx->int_ctx[0].irq, &nss_ctx->int_ctx[0]);
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530781 unregister_netdev(nss_ctx->int_ctx[0].ndev);
782 free_netdev(nss_ctx->int_ctx[0].ndev);
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530783
784 /*
785 * Check if second interrupt is supported
786 * If so then clear resources for second interrupt as well
787 */
788 if (nss_ctx->int_ctx[1].irq) {
789 nss_hal_disable_interrupt(nss_ctx->nmap, nss_ctx->int_ctx[1].irq,
790 nss_ctx->int_ctx[1].shift_factor, NSS_HAL_SUPPORTED_INTERRUPTS);
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530791 free_irq(nss_ctx->int_ctx[1].irq, &nss_ctx->int_ctx[1]);
Abhishek Rastogi271eee72013-07-29 21:08:36 +0530792 unregister_netdev(nss_ctx->int_ctx[1].ndev);
793 free_netdev(nss_ctx->int_ctx[1].ndev);
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530794 }
795
Stephen Wang38e89bc2014-11-06 11:34:45 -0800796 /*
797 * nss-drv is exiting, remove from nss-gmac
798 */
799 for (i = 0 ; i < NSS_MAX_PHYSICAL_INTERFACES ; i ++) {
Sundarajan Srinivasan70374842014-11-19 15:22:52 -0800800 if (nss_top->subsys_dp_register[i].ndev) {
Stephen Wang38e89bc2014-11-06 11:34:45 -0800801 nss_data_plane_unregister_from_nss_gmac(i);
802 }
803 }
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800804#if (NSS_DT_SUPPORT == 1)
805 if (nss_dev->dev.of_node) {
806 if (nss_ctx->nmap) {
807 iounmap((void *)nss_ctx->nmap);
808 nss_ctx->nmap = 0;
809 }
810
811 if (nss_ctx->vmap) {
812 iounmap((void *)nss_ctx->vmap);
813 nss_ctx->vmap = 0;
814 }
815 }
816#endif
Stephen Wang38e89bc2014-11-06 11:34:45 -0800817
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530818 nss_info("%p: All resources freed for nss core%d", nss_ctx, nss_dev->id);
819 return 0;
820}
821
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800822#if (NSS_DT_SUPPORT == 1)
823static struct of_device_id nss_dt_ids[] = {
824 { .compatible = "qcom,nss0" },
825 { .compatible = "qcom,nss1" },
826 {},
827};
828MODULE_DEVICE_TABLE(of, nss_dt_ids);
829#endif
830
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530831/*
832 * nss_driver
833 * Platform driver structure for NSS
834 */
835struct platform_driver nss_driver = {
836 .probe = nss_probe,
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800837#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,7,0))
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530838 .remove = __devexit_p(nss_remove),
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800839#else
840 .remove = nss_remove,
841#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530842 .driver = {
843 .name = "qca-nss",
844 .owner = THIS_MODULE,
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800845#if (NSS_DT_SUPPORT == 1)
846 .of_match_table = of_match_ptr(nss_dt_ids),
847#endif
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530848 },
849};
850
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -0800851#if (NSS_PM_SUPPORT == 1)
Abhishek Rastogibc74e432013-04-02 10:28:22 +0530852/*
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530853 * nss_reset_frequency_stats_samples()
854 * Reset all frequency sampling state when auto scaling is turned off.
855 */
856static void nss_reset_frequency_stats_samples (void)
857{
858 nss_runtime_samples.buffer_index = 0;
859 nss_runtime_samples.sum = 0;
860 nss_runtime_samples.average = 0;
861 nss_runtime_samples.sample_count = 0;
862 nss_runtime_samples.message_rate_limit = 0;
863 nss_runtime_samples.freq_scale_rate_limit_up = 0;
864 nss_runtime_samples.freq_scale_rate_limit_down = 0;
865}
866
867/*
wthomas626147f2013-09-18 13:12:40 -0700868 ***************************************************************************************************
Thomas Wufb6a6842013-10-23 13:14:27 -0700869 * nss_wq_function() is used to queue up requests to change NSS frequencies.
870 * The function will take care of NSS notices and also control clock.
871 * The auto rate algorithmn will queue up requests or the procfs may also queue up these requests.
wthomas626147f2013-09-18 13:12:40 -0700872 ***************************************************************************************************
873 */
874
875/*
876 * nss_wq_function()
877 * Added to Handle BH requests to kernel
878 */
879void nss_wq_function (struct work_struct *work)
880{
881 nss_work_t *my_work = (nss_work_t *)work;
882
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530883 nss_freq_change(nss_freq_change_context, my_work->frequency, my_work->stats_enable, 0);
Thomas Wufb6a6842013-10-23 13:14:27 -0700884 clk_set_rate(nss_core0_clk, my_work->frequency);
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530885 nss_freq_change(nss_freq_change_context, my_work->frequency, my_work->stats_enable, 1);
wthomas626147f2013-09-18 13:12:40 -0700886
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +0530887 if(!pm_client) {
888 goto out;
889 }
890
891 if (my_work->frequency == NSS_FREQ_733) {
892 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_TURBO);
893 } else if ((my_work->frequency == NSS_FREQ_275) || (my_work->frequency == NSS_FREQ_550)) {
894 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_NOMINAL);
895 } else {
896 nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_IDLE);
897 }
898out:
wthomas626147f2013-09-18 13:12:40 -0700899 kfree((void *)work);
900}
901
902/*
wthomas442c7972013-08-05 14:28:17 -0700903 * nss_current_freq_handler()
904 * Handle Userspace Frequency Change Requests
905 */
906static int nss_current_freq_handler (ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
907{
wthomas442c7972013-08-05 14:28:17 -0700908 int ret;
wthomas626147f2013-09-18 13:12:40 -0700909
910 BUG_ON(!nss_wq);
wthomas442c7972013-08-05 14:28:17 -0700911
912 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
913
wthomasd39fa822013-08-22 16:44:23 -0700914 if (!write) {
wthomas626147f2013-09-18 13:12:40 -0700915 printk("Frequency Set to %d\n", nss_cmd_buf.current_freq);
wthomasd39fa822013-08-22 16:44:23 -0700916 return ret;
wthomas442c7972013-08-05 14:28:17 -0700917 }
wthomasd39fa822013-08-22 16:44:23 -0700918
wthomas626147f2013-09-18 13:12:40 -0700919 /* Turn off Auto Scale */
920 nss_cmd_buf.auto_scale = 0;
921 nss_runtime_samples.freq_scale_ready = 0;
wthomasd39fa822013-08-22 16:44:23 -0700922
Thomas Wu0a0a9c92013-11-21 15:28:19 -0800923 /* If support NSS freq is in the table send the new frequency request to NSS or If No Turbo and ask for turbo freq */
924 if (((nss_cmd_buf.current_freq != NSS_FREQ_110) && (nss_cmd_buf.current_freq != NSS_FREQ_275) && (nss_cmd_buf.current_freq != NSS_FREQ_550) && (nss_cmd_buf.current_freq != NSS_FREQ_733)) || ((nss_runtime_samples.freq_scale_sup_max != NSS_MAX_CPU_SCALES) && (nss_cmd_buf.current_freq == NSS_FREQ_733))) {
Thomas Wufb6a6842013-10-23 13:14:27 -0700925 printk("Frequency not found. Please check Frequency Table\n");
wthomas626147f2013-09-18 13:12:40 -0700926 return ret;
wthomasd39fa822013-08-22 16:44:23 -0700927 }
928
Thomas Wu7409bce2014-05-21 10:56:07 -0700929 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
wthomas626147f2013-09-18 13:12:40 -0700930 if (!nss_work) {
931 nss_info("NSS Freq WQ kmalloc fail");
932 return ret;
933 }
934 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
935 nss_work->frequency = nss_cmd_buf.current_freq;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530936 nss_work->stats_enable = 0;
937
938 /* Ensure we start with a fresh set of samples later */
939 nss_reset_frequency_stats_samples();
940
wthomas626147f2013-09-18 13:12:40 -0700941 queue_work(nss_wq, (struct work_struct *)nss_work);
942
wthomas442c7972013-08-05 14:28:17 -0700943 return ret;
944}
945
946/*
947 * nss_auto_scale_handler()
948 * Enables or Disable Auto Scaling
949 */
950static int nss_auto_scale_handler (ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
951{
952 int ret;
953
954 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
955
wthomas626147f2013-09-18 13:12:40 -0700956 if (!write) {
957 return ret;
958 }
959
Thomas Wufb6a6842013-10-23 13:14:27 -0700960 if (nss_cmd_buf.auto_scale != 1) {
wthomas626147f2013-09-18 13:12:40 -0700961 /*
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530962 * Is auto scaling currently enabled? If so, send the command to
963 * disable stats reporting to NSS
wthomas626147f2013-09-18 13:12:40 -0700964 */
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530965 if (nss_runtime_samples.freq_scale_ready != 0) {
966 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
Thomas Wu7409bce2014-05-21 10:56:07 -0700967 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +0530968 if (!nss_work) {
969 nss_info("NSS Freq WQ kmalloc fail");
970 return ret;
971 }
972 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
973 nss_work->frequency = nss_cmd_buf.current_freq;
974 nss_work->stats_enable = 0;
975 queue_work(nss_wq, (struct work_struct *)nss_work);
976 nss_runtime_samples.freq_scale_ready = 0;
977
978 /*
979 * The current samples would be stale later when scaling is
980 * enabled again, hence reset them
981 */
982 nss_reset_frequency_stats_samples();
983 }
Thomas Wufb6a6842013-10-23 13:14:27 -0700984 return ret;
wthomas626147f2013-09-18 13:12:40 -0700985 }
wthomas442c7972013-08-05 14:28:17 -0700986
Thomas Wufb6a6842013-10-23 13:14:27 -0700987 /*
988 * Auto Scaling is already being done
989 */
990 if (nss_runtime_samples.freq_scale_ready == 1) {
991 return ret;
992 }
993
994 /*
995 * Setup default values - Middle of Freq Scale Band
996 */
997 nss_runtime_samples.freq_scale_index = 1;
998 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
999
Thomas Wu7409bce2014-05-21 10:56:07 -07001000 nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
Thomas Wufb6a6842013-10-23 13:14:27 -07001001 if (!nss_work) {
1002 nss_info("NSS Freq WQ kmalloc fail");
1003 return ret;
1004 }
1005 INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
1006 nss_work->frequency = nss_cmd_buf.current_freq;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +05301007 nss_work->stats_enable = 1;
Thomas Wufb6a6842013-10-23 13:14:27 -07001008 queue_work(nss_wq, (struct work_struct *)nss_work);
1009
1010 nss_runtime_samples.freq_scale_ready = 1;
1011
wthomas442c7972013-08-05 14:28:17 -07001012 return ret;
1013}
1014
1015/*
1016 * nss_get_freq_table_handler()
1017 * Display Support Freq and Ex how to Change.
1018 */
Thomas Wu05495be2013-12-19 14:24:24 -08001019static 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 -07001020{
1021 int ret;
1022
1023 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1024
Thomas Wu0a0a9c92013-11-21 15:28:19 -08001025 if (nss_runtime_samples.freq_scale_sup_max != NSS_MAX_CPU_SCALES) {
1026 printk("Frequency Supported - 110Mhz 275Mhz 550Mhz\n");
1027 printk("Ex. To Change Frequency - echo 110000000 > current_freq \n");
1028
1029 return ret;
1030 }
1031
wthomas626147f2013-09-18 13:12:40 -07001032 printk("Frequency Supported - 110Mhz 275Mhz 550Mhz 733Mhz \n");
wthomas442c7972013-08-05 14:28:17 -07001033 printk("Ex. To Change Frequency - echo 110000000 > current_freq \n");
1034
1035 return ret;
1036}
1037
1038/*
Thomas Wu05495be2013-12-19 14:24:24 -08001039 * nss_get_average_inst_handler()
1040 * Display AVG Inst Per Ms.
1041 */
1042static int nss_get_average_inst_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
1043{
1044 int ret;
1045
1046 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1047
1048 if (!ret && !write) {
1049 printk("Current Inst Per Ms %x\n", nss_runtime_samples.average);
1050 }
1051
1052 return ret;
1053}
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -08001054#endif /* NSS_PM_SUPPORT */
Thomas Wu05495be2013-12-19 14:24:24 -08001055
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -08001056#if (NSS_FW_DBG_SUPPORT == 1)
Thomas Wu05495be2013-12-19 14:24:24 -08001057/*
Abhishek Rastogi1626a902013-11-21 17:09:49 +05301058 * nss_debug_handler()
1059 * Enable NSS debug output
1060 */
1061static int nss_debug_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
1062{
1063 int ret;
1064
1065 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1066 if (!ret) {
1067 if ((write) && (nss_ctl_debug != 0)) {
1068 printk("Enabling NSS SPI Debug\n");
1069 nss_hal_debug_enable();
1070 }
1071 }
1072
1073 return ret;
1074}
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -08001075#endif
Abhishek Rastogi1626a902013-11-21 17:09:49 +05301076
1077/*
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +05301078 * nss_rps_handler()
1079 * Enable NSS RPS
1080 */
1081static int nss_rpscfg_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
1082{
1083 struct nss_top_instance *nss_top = &nss_top_main;
1084 struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
1085 int ret;
1086
1087 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1088 if (!ret) {
1089 if ((write) && (nss_rps_cfg == 1)) {
1090 printk("Enabling NSS RPS\n");
Sundarajan Srinivasanf1e57462014-09-17 15:24:01 -07001091 nss_n2h_tx(nss_ctx, 1);
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +05301092 return ret;
1093 }
1094
1095 if ((write) && (nss_rps_cfg == 0)) {
1096 printk("Runtime disabling of NSS RPS not supported \n");
1097 return ret;
1098 }
1099
1100 if (write) {
1101 printk("Invalid input value.Valid values are 0 and 1 \n");
1102 }
1103
1104 }
1105
1106 return ret;
1107}
1108
1109/*
Thomas Wu52075f42014-02-06 16:32:42 -08001110 * nss_coredump_handler()
1111 * Send Signal To Coredump NSS Cores
1112 */
1113static int nss_coredump_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
1114{
1115 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *) nss_freq_change_context;
1116 int ret;
1117
1118 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1119 if (!ret) {
1120 if ((write) && (nss_ctl_debug != 0)) {
1121 printk("Coredumping to DDR\n");
1122 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);
1123 }
1124 }
1125
1126 return ret;
1127}
1128
1129/*
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -08001130 * nss_jumbo_mru_handler()
1131 * Sysctl to modify nss_jumbo_mru
1132 */
1133static int nss_jumbo_mru_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
1134{
1135 int ret;
1136
1137 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1138 if (ret) {
1139 return ret;
1140 }
1141
1142 if (write) {
1143 nss_core_set_jumbo_mru(nss_jumbo_mru);
1144 nss_info("jumbo_mru set to %d\n", nss_jumbo_mru);
1145 }
1146
1147 return ret;
1148}
1149
1150/* nss_paged_mode_handler()
1151 * Sysctl to modify nss_paged_mode.
1152 */
1153
1154static int nss_paged_mode_handler(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
1155{
1156 int ret;
1157
1158 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1159 if (ret) {
1160 return ret;
1161 }
1162
1163 if (write) {
1164 nss_core_set_paged_mode(nss_paged_mode);
1165 nss_info("paged_mode set to %d\n", nss_paged_mode);
1166 }
1167
1168 return ret;
1169}
1170
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -08001171#if (NSS_PM_SUPPORT == 1)
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -08001172/*
wthomas442c7972013-08-05 14:28:17 -07001173 * sysctl-tuning infrastructure.
1174 */
1175static ctl_table nss_freq_table[] = {
1176 {
1177 .procname = "current_freq",
1178 .data = &nss_cmd_buf.current_freq,
1179 .maxlen = sizeof(int),
1180 .mode = 0644,
1181 .proc_handler = &nss_current_freq_handler,
1182 },
1183 {
1184 .procname = "freq_table",
1185 .data = &nss_cmd_buf.max_freq,
1186 .maxlen = sizeof(int),
1187 .mode = 0644,
1188 .proc_handler = &nss_get_freq_table_handler,
1189 },
1190 {
1191 .procname = "auto_scale",
1192 .data = &nss_cmd_buf.auto_scale,
1193 .maxlen = sizeof(int),
1194 .mode = 0644,
1195 .proc_handler = &nss_auto_scale_handler,
1196 },
Thomas Wu05495be2013-12-19 14:24:24 -08001197 {
1198 .procname = "inst_per_sec",
1199 .data = &nss_cmd_buf.average_inst,
1200 .maxlen = sizeof(int),
1201 .mode = 0644,
1202 .proc_handler = &nss_get_average_inst_handler,
1203 },
wthomas442c7972013-08-05 14:28:17 -07001204 { }
1205};
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -08001206#endif
wthomas442c7972013-08-05 14:28:17 -07001207
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +05301208static ctl_table nss_general_table[] = {
1209 {
1210 .procname = "redirect",
1211 .data = &nss_ctl_redirect,
1212 .maxlen = sizeof(int),
1213 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -07001214 .proc_handler = proc_dointvec,
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +05301215 },
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -08001216#if (NSS_FW_DBG_SUPPORT == 1)
Abhishek Rastogi1626a902013-11-21 17:09:49 +05301217 {
1218 .procname = "debug",
1219 .data = &nss_ctl_debug,
1220 .maxlen = sizeof(int),
1221 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -07001222 .proc_handler = &nss_debug_handler,
Abhishek Rastogi1626a902013-11-21 17:09:49 +05301223 },
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -08001224#endif
Thomas Wu52075f42014-02-06 16:32:42 -08001225 {
1226 .procname = "coredump",
1227 .data = &nss_cmd_buf.coredump,
1228 .maxlen = sizeof(int),
1229 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -07001230 .proc_handler = &nss_coredump_handler,
Thomas Wu52075f42014-02-06 16:32:42 -08001231 },
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +05301232 {
1233 .procname = "rps",
1234 .data = &nss_rps_cfg,
1235 .maxlen = sizeof(int),
1236 .mode = 0644,
Vijay Dewangan9db18752014-09-15 16:25:01 -07001237 .proc_handler = &nss_rpscfg_handler,
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +05301238 },
Saurabh Misra96998db2014-07-10 12:15:48 -07001239 {
1240 .procname = "logbuf",
1241 .data = &nss_ctl_logbuf,
1242 .maxlen = sizeof(int),
1243 .mode = 0644,
1244 .proc_handler = &nss_logbuffer_handler,
1245 },
Sundarajan Srinivasanf9c4a232014-11-18 13:25:40 -08001246 {
1247 .procname = "jumbo_mru",
1248 .data = &nss_jumbo_mru,
1249 .maxlen = sizeof(int),
1250 .mode = 0644,
1251 .proc_handler = &nss_jumbo_mru_handler,
1252 },
1253 {
1254 .procname = "paged_mode",
1255 .data = &nss_paged_mode,
1256 .maxlen = sizeof(int),
1257 .mode = 0644,
1258 .proc_handler = &nss_paged_mode_handler,
1259 },
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +05301260 { }
1261};
1262
wthomas442c7972013-08-05 14:28:17 -07001263static ctl_table nss_clock_dir[] = {
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -08001264#if (NSS_PM_SUPPORT == 1)
wthomas442c7972013-08-05 14:28:17 -07001265 {
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +05301266 .procname = "clock",
1267 .mode = 0555,
1268 .child = nss_freq_table,
1269 },
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -08001270#endif
Abhishek Rastogi5cd2e4c2013-11-13 18:09:08 +05301271 {
1272 .procname = "general",
1273 .mode = 0555,
1274 .child = nss_general_table,
wthomas442c7972013-08-05 14:28:17 -07001275 },
1276 { }
1277};
1278
1279static ctl_table nss_root_dir[] = {
1280 {
1281 .procname = "nss",
1282 .mode = 0555,
1283 .child = nss_clock_dir,
1284 },
1285 { }
1286};
1287
1288static ctl_table nss_root[] = {
1289 {
1290 .procname = "dev",
1291 .mode = 0555,
1292 .child = nss_root_dir,
1293 },
1294 { }
1295};
1296
1297static struct ctl_table_header *nss_dev_header;
1298
1299/*
Abhishek Rastogibc74e432013-04-02 10:28:22 +05301300 * nss_init()
1301 * Registers nss driver
1302 */
1303static int __init nss_init(void)
1304{
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -08001305#if (NSS_DT_SUPPORT == 1)
1306 struct device_node *cmn = NULL;
1307 struct resource res_nss_fpb_base;
1308#endif
1309
Abhishek Rastogibc74e432013-04-02 10:28:22 +05301310 nss_info("Init NSS driver");
1311
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -08001312#if (NSS_PM_SUPPORT == 1)
Sundarajan Srinivasandedd8e42014-10-06 11:59:34 -07001313 nss_freq_change_context = nss_freq_get_mgr();
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -08001314#else
1315 nss_freq_change_context = NULL;
1316#endif
Sundarajan Srinivasandedd8e42014-10-06 11:59:34 -07001317
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -08001318#if (NSS_DT_SUPPORT == 1)
1319 /*
1320 * Get reference to NSS common device node
1321 */
1322 cmn = of_find_node_by_name(NULL, "nss-common");
1323 if (!cmn) {
1324 nss_info("cannot find nss-common node\n");
1325 return -EFAULT;
1326 }
1327
1328 if (of_address_to_resource(cmn, 0, &res_nss_fpb_base) != 0) {
1329 nss_info("of_address_to_resource() return error for nss_fpb_base\n");
1330 of_node_put(cmn);
1331 return -EFAULT;
1332 }
1333
1334 nss_top_main.nss_fpb_base = ioremap_nocache(res_nss_fpb_base.start,
1335 resource_size(&res_nss_fpb_base));
1336 if (!nss_top_main.nss_fpb_base) {
1337 nss_info("ioremap fail for nss_fpb_base\n");
1338 of_node_put(cmn);
1339 return -EFAULT;
1340 }
1341
1342 nss_top_main.nss_hal_common_init_done = false;
1343
1344 /*
1345 * Release reference to NSS common device node
1346 */
1347 of_node_put(cmn);
1348 cmn = NULL;
1349#else
Abhishek Rastogibc74e432013-04-02 10:28:22 +05301350 /*
1351 * Perform clock init common to all NSS cores
1352 */
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301353 nss_hal_common_reset(&(nss_top_main.clk_src));
Abhishek Rastogibc74e432013-04-02 10:28:22 +05301354
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -08001355#endif /* NSS_DT_SUPPORT */
1356
Abhishek Rastogibc74e432013-04-02 10:28:22 +05301357 /*
1358 * Enable spin locks
1359 */
1360 spin_lock_init(&(nss_top_main.lock));
1361 spin_lock_init(&(nss_top_main.stats_lock));
1362
1363 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +05301364 * Enable NSS statistics
1365 */
1366 nss_stats_init();
1367
1368 /*
wthomas442c7972013-08-05 14:28:17 -07001369 * Register sysctl table.
1370 */
1371 nss_dev_header = register_sysctl_table(nss_root);
1372
1373 /*
Vijay Dewangan9db18752014-09-15 16:25:01 -07001374 * Registering sysctl for ipv4/6 specific config.
1375 */
1376 nss_ipv4_register_sysctl();
1377 nss_ipv6_register_sysctl();
1378
Sundarajan Srinivasan758e8f42014-12-08 14:56:24 -08001379#if (NSS_PM_SUPPORT == 1)
Vijay Dewangan9db18752014-09-15 16:25:01 -07001380 /*
wthomas626147f2013-09-18 13:12:40 -07001381 * Setup Runtime Sample values
1382 */
1383 nss_runtime_samples.freq_scale[0].frequency = NSS_FREQ_110;
wthomas626147f2013-09-18 13:12:40 -07001384 nss_runtime_samples.freq_scale[0].minimum = NSS_FREQ_110_MIN;
1385 nss_runtime_samples.freq_scale[0].maximum = NSS_FREQ_110_MAX;
wthomas626147f2013-09-18 13:12:40 -07001386 nss_runtime_samples.freq_scale[1].frequency = NSS_FREQ_550;
wthomas626147f2013-09-18 13:12:40 -07001387 nss_runtime_samples.freq_scale[1].minimum = NSS_FREQ_550_MIN;
1388 nss_runtime_samples.freq_scale[1].maximum = NSS_FREQ_550_MAX;
wthomas626147f2013-09-18 13:12:40 -07001389 nss_runtime_samples.freq_scale[2].frequency = NSS_FREQ_733;
wthomas626147f2013-09-18 13:12:40 -07001390 nss_runtime_samples.freq_scale[2].minimum = NSS_FREQ_733_MIN;
1391 nss_runtime_samples.freq_scale[2].maximum = NSS_FREQ_733_MAX;
wthomas626147f2013-09-18 13:12:40 -07001392 nss_runtime_samples.freq_scale_index = 1;
1393 nss_runtime_samples.freq_scale_ready = 0;
Thomas Wu9681f7e2013-11-06 13:12:57 -08001394 nss_runtime_samples.freq_scale_rate_limit_up = 0;
1395 nss_runtime_samples.freq_scale_rate_limit_down = 0;
wthomas626147f2013-09-18 13:12:40 -07001396 nss_runtime_samples.buffer_index = 0;
1397 nss_runtime_samples.sum = 0;
1398 nss_runtime_samples.sample_count = 0;
1399 nss_runtime_samples.average = 0;
1400 nss_runtime_samples.message_rate_limit = 0;
Kiran Kumar C.S.K69fd5992014-01-06 20:58:14 +05301401 nss_runtime_samples.initialized = 0;
wthomas626147f2013-09-18 13:12:40 -07001402
Thomas Wu05495be2013-12-19 14:24:24 -08001403 nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency;
1404
wthomas626147f2013-09-18 13:12:40 -07001405 /*
1406 * Initial Workqueue
1407 */
1408 nss_wq = create_workqueue("nss_freq_queue");
1409
1410 /*
Pamidipati, Vijay7f413b52013-09-24 19:07:12 +05301411 * Initialize NSS Bus PM module
1412 */
1413 nss_pm_init();
1414
1415 /*
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +05301416 * Register with Bus driver
1417 */
1418 pm_client = nss_pm_client_register(NSS_PM_CLIENT_NETAP);
1419 if (!pm_client) {
1420 nss_warning("Error registering with PM driver");
1421 }
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -08001422#endif
Pamidipati, Vijay5d27d812013-11-22 16:48:11 +05301423
1424 /*
Abhishek Rastogibc74e432013-04-02 10:28:22 +05301425 * Register platform_driver
1426 */
1427 return platform_driver_register(&nss_driver);
1428}
1429
1430/*
1431 * nss_cleanup()
1432 * Unregisters nss driver
1433 */
1434static void __exit nss_cleanup(void)
1435{
1436 nss_info("Exit NSS driver");
wthomas442c7972013-08-05 14:28:17 -07001437
1438 if (nss_dev_header)
1439 unregister_sysctl_table(nss_dev_header);
1440
Vijay Dewangan9db18752014-09-15 16:25:01 -07001441 /*
Vijay Dewangan488e5372014-12-29 21:40:11 -08001442 * Unregister n2h specific sysctl
1443 */
1444 nss_n2h_empty_pool_buf_unregister_sysctl();
1445
1446 /*
Vijay Dewangan9db18752014-09-15 16:25:01 -07001447 * Unregister ipv4/6 specific sysctl
1448 */
1449 nss_ipv4_unregister_sysctl();
1450 nss_ipv6_unregister_sysctl();
1451
Sundarajan Srinivasan4691ba62014-11-07 11:24:07 -08001452#if (NSS_DT_SUPPORT == 1)
1453 if(nss_top_main.nss_fpb_base) {
1454 iounmap(nss_top_main.nss_fpb_base);
1455 nss_top_main.nss_fpb_base = 0;
1456 }
1457#endif
1458
Abhishek Rastogibc74e432013-04-02 10:28:22 +05301459 platform_driver_unregister(&nss_driver);
1460}
1461
1462module_init(nss_init);
1463module_exit(nss_cleanup);
1464
1465MODULE_DESCRIPTION("QCA NSS Driver");
1466MODULE_AUTHOR("Qualcomm Atheros Inc");
1467MODULE_LICENSE("Dual BSD/GPL");