blob: 9c2b10828c99cee1292e7f0f11775076c7ed8c79 [file] [log] [blame]
Abhishek Rastogi99714332014-04-02 19:38:12 +05301/*
2 **************************************************************************
Stephen Wangaed46332016-12-12 17:29:03 -08003 * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
Abhishek Rastogi99714332014-04-02 19:38:12 +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 */
16
17/*
18 * nss_cmn.c
19 * NSS generic APIs
20 */
21
Radha krishna Simha Jiguru7098a962015-12-09 11:18:23 +053022#if (NSS_DT_SUPPORT == 1)
23#include <linux/of.h>
24#endif
25
Abhishek Rastogi99714332014-04-02 19:38:12 +053026#include "nss_tx_rx_common.h"
27
28/*
Suruchi Agarwale3940e72016-07-06 15:56:51 -070029 * nss_cmn_response_str
30 * Common response structure string
31 */
32int8_t *nss_cmn_response_str[NSS_CMN_RESPONSE_LAST] = {
33 "Message Acknowledge without errors",
34 "Common message version not supported",
35 "Unknown Interface",
36 "Length Error",
37 "Message Error",
38 "FW Notification Message",
39};
40
41/*
Abhishek Rastogi99714332014-04-02 19:38:12 +053042 * nss_cmn_msg_init()
43 * Initialize the common message structure.
44 */
45void nss_cmn_msg_init(struct nss_cmn_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data)
46{
47 ncm->interface = if_num;
48 ncm->version = NSS_HLOS_MESSAGE_VERSION;
49 ncm->type = type;
50 ncm->len = len;
Stephen Wangaed46332016-12-12 17:29:03 -080051 ncm->cb = (nss_ptr_t)cb;
52 ncm->app_data = (nss_ptr_t)app_data;
Abhishek Rastogi99714332014-04-02 19:38:12 +053053}
54
55/*
56 * nss_cmn_get_interface_number()
57 * Return the interface number of the NSS net_device.
58 *
59 * Returns -1 on failure or the interface number of dev is an NSS net_device.
60 */
61int32_t nss_cmn_get_interface_number(struct nss_ctx_instance *nss_ctx, struct net_device *dev)
62{
63 int i;
64
65 NSS_VERIFY_CTX_MAGIC(nss_ctx);
66 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
67 nss_warning("%p: Interface number could not be found as core not ready", nss_ctx);
68 return -1;
69 }
70
71 nss_assert(dev != 0);
72
73 /*
74 * Check physical interface table
75 */
76 for (i = 0; i < NSS_MAX_NET_INTERFACES; i++) {
Stephen Wang84e0e992016-09-07 12:31:40 -070077 if (dev == nss_ctx->subsys_dp_register[i].ndev) {
Abhishek Rastogi99714332014-04-02 19:38:12 +053078 return i;
79 }
80 }
81
82 nss_warning("%p: Interface number could not be found as interface has not registered yet", nss_ctx);
83 return -1;
84}
85
86/*
87 * nss_cmn_get_interface_dev()
88 * Return the net_device for NSS interface id.
89 *
90 * Returns NULL on failure or the net_device for NSS interface id.
91 */
92struct net_device *nss_cmn_get_interface_dev(struct nss_ctx_instance *ctx, uint32_t if_num)
93{
94 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)ctx;
95
96 NSS_VERIFY_CTX_MAGIC(nss_ctx);
97 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
98 nss_warning("%p: Interface device could not be found as core not ready", nss_ctx);
99 return NULL;
100 }
101
102 if (unlikely(if_num >= NSS_MAX_NET_INTERFACES)) {
103 return NULL;
104 }
105
Stephen Wang84e0e992016-09-07 12:31:40 -0700106 return nss_ctx->subsys_dp_register[if_num].ndev;
Abhishek Rastogi99714332014-04-02 19:38:12 +0530107}
108
109/*
Gareth Williamsb52af512014-04-25 19:31:15 +0100110 * nss_cmn_get_interface_number_by_dev()
111 * Return the NSS interface id for the net_device.
112 *
113 * Returns < 0 on failure or the NSS interface id for the given device.
114 */
115int32_t nss_cmn_get_interface_number_by_dev(struct net_device *dev)
116{
Stephen Wang84e0e992016-09-07 12:31:40 -0700117 int i, core;
Gareth Williamsb52af512014-04-25 19:31:15 +0100118
119 nss_assert(dev != 0);
120
121 /*
Stephen Wang84e0e992016-09-07 12:31:40 -0700122 * Check physical interface table on both cores
Gareth Williamsb52af512014-04-25 19:31:15 +0100123 */
Stephen Wang84e0e992016-09-07 12:31:40 -0700124 for (core = 0; core < NSS_MAX_CORES; core++) {
125 for (i = 0; i < NSS_MAX_NET_INTERFACES; i++) {
126 if (dev == nss_top_main.nss[core].subsys_dp_register[i].ndev) {
127 return i;
128 }
Gareth Williamsb52af512014-04-25 19:31:15 +0100129 }
130 }
131
132 nss_warning("Interface number could not be found for %p (%s) as interface has not registered yet", dev, dev->name);
133 return -1;
134}
135
136/*
Abhishek Rastogi99714332014-04-02 19:38:12 +0530137 * nss_cmn_get_state()
138 * return the NSS initialization state
139 */
140nss_state_t nss_cmn_get_state(struct nss_ctx_instance *ctx)
141{
142 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)ctx;
143 nss_state_t state = NSS_STATE_UNINITIALIZED;
144
145 NSS_VERIFY_CTX_MAGIC(nss_ctx);
146 spin_lock_bh(&nss_top_main.lock);
147 if (nss_ctx->state == NSS_CORE_STATE_INITIALIZED) {
148 state = NSS_STATE_INITIALIZED;
149 }
150 spin_unlock_bh(&nss_top_main.lock);
151
152 return state;
153}
154
155/*
156 * nss_cmn_interface_is_virtual()
157 * Return true if the interface number is a virtual NSS interface
158 */
159bool nss_cmn_interface_is_virtual(void *nss_ctx, int32_t interface_num)
160{
Sundarajan Srinivasancd1631b2015-06-18 01:23:30 -0700161 return ((nss_dynamic_interface_get_type(interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_WIFI)
162 || (nss_dynamic_interface_get_type(interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR)
163 || (nss_dynamic_interface_get_type(interface_num) == NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED));
Abhishek Rastogi99714332014-04-02 19:38:12 +0530164}
165
166/*
167 * nss_cmn_register_queue_decongestion()
168 * Register for queue decongestion event
169 */
170nss_cb_register_status_t nss_cmn_register_queue_decongestion(struct nss_ctx_instance *nss_ctx, nss_cmn_queue_decongestion_callback_t event_callback, void *app_ctx)
171{
172 uint32_t i;
173
174 NSS_VERIFY_CTX_MAGIC(nss_ctx);
175 spin_lock_bh(&nss_ctx->decongest_cb_lock);
176
177 /*
178 * Find vacant location in callback table
179 */
180 for (i = 0; i< NSS_MAX_CLIENTS; i++) {
181 if (nss_ctx->queue_decongestion_callback[i] == NULL) {
182 nss_ctx->queue_decongestion_callback[i] = event_callback;
183 nss_ctx->queue_decongestion_ctx[i] = app_ctx;
184 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
185 return NSS_CB_REGISTER_SUCCESS;
186 }
187 }
188
189 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
190 return NSS_CB_REGISTER_FAILED;
191}
192
193/*
194 * nss_cmn_unregister_queue_decongestion()
195 * Unregister for queue decongestion event
196 */
197nss_cb_unregister_status_t nss_cmn_unregister_queue_decongestion(struct nss_ctx_instance *nss_ctx, nss_cmn_queue_decongestion_callback_t event_callback)
198{
199 uint32_t i;
200
201 NSS_VERIFY_CTX_MAGIC(nss_ctx);
202 spin_lock_bh(&nss_ctx->decongest_cb_lock);
203
204 /*
205 * Find actual location in callback table
206 */
207 for (i = 0; i< NSS_MAX_CLIENTS; i++) {
208 if (nss_ctx->queue_decongestion_callback[i] == event_callback) {
209 nss_ctx->queue_decongestion_callback[i] = NULL;
210 nss_ctx->queue_decongestion_ctx[i] = NULL;
211 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
212 return NSS_CB_UNREGISTER_SUCCESS;
213 }
214 }
215
216 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
217 return NSS_CB_UNREGISTER_FAILED;
218}
219
Radha krishna Simha Jiguru7098a962015-12-09 11:18:23 +0530220/*
221 * nss_cmn_get_nss_enabled()
222 * Check if NSS mode is supported on platform
223 *
224 * This API checks the device tree parameter to decide on whether
225 * NSS mode is enabled. On older kernels this will always return true
226 */
227bool nss_cmn_get_nss_enabled(void)
228{
229#if (NSS_DT_SUPPORT == 1)
230 struct device_node *cmn = NULL;
231
232 /*
233 * Get reference to NSS common device node
234 */
235 cmn = of_find_node_by_name(NULL, "nss-common");
236 if (!cmn) {
237 nss_info_always("nss is not enabled on this platform\n");
238 return false;
239 }
240#endif
241 return true;
242}
243
Abhishek Rastogi99714332014-04-02 19:38:12 +0530244EXPORT_SYMBOL(nss_cmn_get_interface_number);
245EXPORT_SYMBOL(nss_cmn_get_interface_dev);
246EXPORT_SYMBOL(nss_cmn_get_state);
247EXPORT_SYMBOL(nss_cmn_interface_is_virtual);
248EXPORT_SYMBOL(nss_cmn_msg_init);
Gareth Williamsb52af512014-04-25 19:31:15 +0100249EXPORT_SYMBOL(nss_cmn_get_interface_number_by_dev);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530250
251EXPORT_SYMBOL(nss_cmn_register_queue_decongestion);
252EXPORT_SYMBOL(nss_cmn_unregister_queue_decongestion);
Radha krishna Simha Jiguru7098a962015-12-09 11:18:23 +0530253EXPORT_SYMBOL(nss_cmn_get_nss_enabled);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530254