blob: f8188471cbcf9bde9f72241999c393fddaf63a82 [file] [log] [blame]
Abhishek Rastogi99714332014-04-02 19:38:12 +05301/*
2 **************************************************************************
Murat Sezgin8fb2f362019-01-22 10:44:53 -08003 * Copyright (c) 2014-2019, 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()
Casey Chen3589c452018-09-20 15:27:41 -070043 * Initialize the common message of an ASYNC message.
Abhishek Rastogi99714332014-04-02 19:38:12 +053044 */
Shashank Balashankar497b0152017-09-07 11:26:10 -070045void nss_cmn_msg_init(struct nss_cmn_msg *ncm, uint32_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data)
Abhishek Rastogi99714332014-04-02 19:38:12 +053046{
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}
Stephen Wanga73a7892017-07-05 15:23:14 -070054EXPORT_SYMBOL(nss_cmn_msg_init);
Abhishek Rastogi99714332014-04-02 19:38:12 +053055
56/*
Casey Chen3589c452018-09-20 15:27:41 -070057 * nss_cmn_msg_sync_init()
58 * Initialize the common message of a SYNC message.
59 */
60void nss_cmn_msg_sync_init(struct nss_cmn_msg *ncm, uint32_t if_num, uint32_t type, uint32_t len)
61{
62 nss_cmn_msg_init(ncm, if_num, type, len, NULL, NULL);
63}
64EXPORT_SYMBOL(nss_cmn_msg_sync_init);
65
66/*
Abhishek Rastogi99714332014-04-02 19:38:12 +053067 * nss_cmn_get_interface_number()
68 * Return the interface number of the NSS net_device.
69 *
70 * Returns -1 on failure or the interface number of dev is an NSS net_device.
71 */
72int32_t nss_cmn_get_interface_number(struct nss_ctx_instance *nss_ctx, struct net_device *dev)
73{
74 int i;
75
76 NSS_VERIFY_CTX_MAGIC(nss_ctx);
77 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
Selin Dagb4a99d82018-08-30 09:19:54 -070078 nss_warning("%p: Interface number could not be found as core not ready\n", nss_ctx);
Abhishek Rastogi99714332014-04-02 19:38:12 +053079 return -1;
80 }
81
82 nss_assert(dev != 0);
83
84 /*
85 * Check physical interface table
86 */
87 for (i = 0; i < NSS_MAX_NET_INTERFACES; i++) {
Stephen Wang84e0e992016-09-07 12:31:40 -070088 if (dev == nss_ctx->subsys_dp_register[i].ndev) {
Abhishek Rastogi99714332014-04-02 19:38:12 +053089 return i;
90 }
91 }
92
Selin Dagb4a99d82018-08-30 09:19:54 -070093 nss_warning("%p: Interface number could not be found as interface has not registered yet\n", nss_ctx);
Abhishek Rastogi99714332014-04-02 19:38:12 +053094 return -1;
95}
Stephen Wanga73a7892017-07-05 15:23:14 -070096EXPORT_SYMBOL(nss_cmn_get_interface_number);
Abhishek Rastogi99714332014-04-02 19:38:12 +053097
98/*
Suruchi Sumana034a2f2019-07-30 17:50:58 +053099 * nss_cmn_append_core_id()
100 * Return the NSS interface number with core ID.
101 */
102int nss_cmn_append_core_id(struct nss_ctx_instance *nss_ctx, int if_num)
103{
104 NSS_VERIFY_CTX_MAGIC(nss_ctx);
105
106 return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num);
107}
108EXPORT_SYMBOL(nss_cmn_append_core_id);
109
110/*
Abhishek Rastogi99714332014-04-02 19:38:12 +0530111 * nss_cmn_get_interface_dev()
112 * Return the net_device for NSS interface id.
113 *
114 * Returns NULL on failure or the net_device for NSS interface id.
115 */
116struct net_device *nss_cmn_get_interface_dev(struct nss_ctx_instance *ctx, uint32_t if_num)
117{
118 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)ctx;
119
120 NSS_VERIFY_CTX_MAGIC(nss_ctx);
121 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
Selin Dagb4a99d82018-08-30 09:19:54 -0700122 nss_warning("%p: Interface device could not be found as core not ready\n", nss_ctx);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530123 return NULL;
124 }
125
126 if (unlikely(if_num >= NSS_MAX_NET_INTERFACES)) {
127 return NULL;
128 }
129
Stephen Wang84e0e992016-09-07 12:31:40 -0700130 return nss_ctx->subsys_dp_register[if_num].ndev;
Abhishek Rastogi99714332014-04-02 19:38:12 +0530131}
Stephen Wanga73a7892017-07-05 15:23:14 -0700132EXPORT_SYMBOL(nss_cmn_get_interface_dev);
133
134/*
135 * nss_cmn_get_interface_number_by_dev_and_type()
136 * Return the NSS interface id for the net_device.
137 *
138 * Returns < 0 on failure or the NSS interface id for the given device and type.
139 */
140int32_t nss_cmn_get_interface_number_by_dev_and_type(struct net_device *dev, uint32_t type)
141{
142 int i, core;
143 struct nss_subsystem_dataplane_register *nsdr;
144
145 nss_assert(dev != 0);
Radha krishna Simha Jiguru68d0cbc2019-02-15 00:19:21 +0530146 for (core = 0; core < nss_top_main.num_nss; core++) {
Stephen Wanga73a7892017-07-05 15:23:14 -0700147 for (i = 0; i < NSS_MAX_NET_INTERFACES; i++) {
148 nsdr = &nss_top_main.nss[core].subsys_dp_register[i];
149 if (dev == nsdr->ndev && type == nsdr->type) {
150 return i;
151 }
152 }
153 }
154
Selin Dagb4a99d82018-08-30 09:19:54 -0700155 nss_warning("Interface number could not be found for %p (%s) as interface has not registered yet\n", dev, dev->name);
Stephen Wanga73a7892017-07-05 15:23:14 -0700156 return -1;
157}
158EXPORT_SYMBOL(nss_cmn_get_interface_number_by_dev_and_type);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530159
160/*
Gareth Williamsb52af512014-04-25 19:31:15 +0100161 * nss_cmn_get_interface_number_by_dev()
162 * Return the NSS interface id for the net_device.
163 *
164 * Returns < 0 on failure or the NSS interface id for the given device.
165 */
166int32_t nss_cmn_get_interface_number_by_dev(struct net_device *dev)
167{
Stephen Wanga73a7892017-07-05 15:23:14 -0700168 return nss_cmn_get_interface_number_by_dev_and_type(dev, 0);
Gareth Williamsb52af512014-04-25 19:31:15 +0100169}
Stephen Wanga73a7892017-07-05 15:23:14 -0700170EXPORT_SYMBOL(nss_cmn_get_interface_number_by_dev);
Gareth Williamsb52af512014-04-25 19:31:15 +0100171
172/*
Abhishek Rastogi99714332014-04-02 19:38:12 +0530173 * nss_cmn_get_state()
174 * return the NSS initialization state
175 */
176nss_state_t nss_cmn_get_state(struct nss_ctx_instance *ctx)
177{
178 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)ctx;
179 nss_state_t state = NSS_STATE_UNINITIALIZED;
180
181 NSS_VERIFY_CTX_MAGIC(nss_ctx);
182 spin_lock_bh(&nss_top_main.lock);
183 if (nss_ctx->state == NSS_CORE_STATE_INITIALIZED) {
184 state = NSS_STATE_INITIALIZED;
185 }
186 spin_unlock_bh(&nss_top_main.lock);
187
188 return state;
189}
Stephen Wanga73a7892017-07-05 15:23:14 -0700190EXPORT_SYMBOL(nss_cmn_get_state);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530191
192/*
Sakthi Vignesh Radhakrishnan2842f9c2017-07-27 13:56:07 -0700193 * nss_cmn_interface_is_redirect()
194 * Return true if the interface is a redirect interface.
Abhishek Rastogi99714332014-04-02 19:38:12 +0530195 */
Sakthi Vignesh Radhakrishnan2842f9c2017-07-27 13:56:07 -0700196bool nss_cmn_interface_is_redirect(struct nss_ctx_instance *nss_ctx, int32_t interface_num)
Abhishek Rastogi99714332014-04-02 19:38:12 +0530197{
Casey Chend90d0e62017-11-06 13:21:26 -0800198 enum nss_dynamic_interface_type type = nss_dynamic_interface_get_type(nss_ctx, interface_num);
199
200 return type == NSS_DYNAMIC_INTERFACE_TYPE_WIFI
Murat Sezgin8fb2f362019-01-22 10:44:53 -0800201 || type == NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_N2H
202 || type == NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_H2N
Casey Chend90d0e62017-11-06 13:21:26 -0800203 || type == NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED;
Abhishek Rastogi99714332014-04-02 19:38:12 +0530204}
Stephen Wanga73a7892017-07-05 15:23:14 -0700205EXPORT_SYMBOL(nss_cmn_interface_is_redirect);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530206
207/*
Aniruddha Paul0c0b86a2019-07-11 14:37:25 +0530208 * nss_cmn_interface_is_reuse_not_supported()
209 * Determines if the interface supports skb no-reuse.
210 */
211bool nss_cmn_interface_is_reuse_not_supported(struct nss_ctx_instance *nss_ctx, int32_t interface_num)
212{
213 enum nss_dynamic_interface_type type = NSS_DYNAMIC_INTERFACE_TYPE_NONE;
214
215 /*
216 * Check if the interface belongs to the GRE exception DS.
217 */
218 type = nss_dynamic_interface_get_type(nss_ctx, interface_num);
219 return type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_DS;
220}
221EXPORT_SYMBOL(nss_cmn_interface_is_reuse_not_supported);
222
223/*
ratheesh kannoth93ba95c2017-07-13 15:52:52 +0530224 * nss_cmn_rx_dropped_sum()
225 * Sum rx_dropped count.
226 */
227uint32_t nss_cmn_rx_dropped_sum(struct nss_cmn_node_stats *node_stats)
228{
229 uint32_t sum = 0;
230 int i;
231 for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
232 sum += node_stats->rx_dropped[i];
233 }
234 return sum;
235}
Stephen Wanga73a7892017-07-05 15:23:14 -0700236EXPORT_SYMBOL(nss_cmn_rx_dropped_sum);
ratheesh kannoth93ba95c2017-07-13 15:52:52 +0530237
238/*
Abhishek Rastogi99714332014-04-02 19:38:12 +0530239 * nss_cmn_register_queue_decongestion()
240 * Register for queue decongestion event
241 */
242nss_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)
243{
244 uint32_t i;
245
246 NSS_VERIFY_CTX_MAGIC(nss_ctx);
247 spin_lock_bh(&nss_ctx->decongest_cb_lock);
248
249 /*
250 * Find vacant location in callback table
251 */
252 for (i = 0; i< NSS_MAX_CLIENTS; i++) {
253 if (nss_ctx->queue_decongestion_callback[i] == NULL) {
254 nss_ctx->queue_decongestion_callback[i] = event_callback;
255 nss_ctx->queue_decongestion_ctx[i] = app_ctx;
256 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
257 return NSS_CB_REGISTER_SUCCESS;
258 }
259 }
260
261 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
262 return NSS_CB_REGISTER_FAILED;
263}
Stephen Wanga73a7892017-07-05 15:23:14 -0700264EXPORT_SYMBOL(nss_cmn_register_queue_decongestion);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530265
266/*
267 * nss_cmn_unregister_queue_decongestion()
268 * Unregister for queue decongestion event
269 */
270nss_cb_unregister_status_t nss_cmn_unregister_queue_decongestion(struct nss_ctx_instance *nss_ctx, nss_cmn_queue_decongestion_callback_t event_callback)
271{
272 uint32_t i;
273
274 NSS_VERIFY_CTX_MAGIC(nss_ctx);
275 spin_lock_bh(&nss_ctx->decongest_cb_lock);
276
277 /*
278 * Find actual location in callback table
279 */
280 for (i = 0; i< NSS_MAX_CLIENTS; i++) {
281 if (nss_ctx->queue_decongestion_callback[i] == event_callback) {
282 nss_ctx->queue_decongestion_callback[i] = NULL;
283 nss_ctx->queue_decongestion_ctx[i] = NULL;
284 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
285 return NSS_CB_UNREGISTER_SUCCESS;
286 }
287 }
288
289 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
290 return NSS_CB_UNREGISTER_FAILED;
291}
Stephen Wanga73a7892017-07-05 15:23:14 -0700292EXPORT_SYMBOL(nss_cmn_unregister_queue_decongestion);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530293
Radha krishna Simha Jiguru7098a962015-12-09 11:18:23 +0530294/*
Selin Dagb4a99d82018-08-30 09:19:54 -0700295 * nss_cmn_register_service_code()
296 * Register for service code event
297 */
298nss_cb_register_status_t nss_cmn_register_service_code(struct nss_ctx_instance *nss_ctx, nss_cmn_service_code_callback_t cb, uint8_t service_code, void *app_data)
299{
300 NSS_VERIFY_CTX_MAGIC(nss_ctx);
301
302 if (nss_ctx->service_code_callback[service_code]) {
303 /*
304 * We already have a callback registered for this service code.
305 */
306 nss_warning("%p: a callback is registered already for this service code %d\n", nss_ctx, service_code);
307
308 return NSS_CB_REGISTER_FAILED;
309 }
310
311 nss_ctx->service_code_callback[service_code] = cb;
312 nss_ctx->service_code_ctx[service_code] = app_data;
313 return NSS_CB_REGISTER_SUCCESS;
314}
315EXPORT_SYMBOL(nss_cmn_register_service_code);
316
317/*
318 * nss_cmn_unregister_service_code()
319 * Unregister for service code event
320 */
321nss_cb_unregister_status_t nss_cmn_unregister_service_code(struct nss_ctx_instance *nss_ctx, nss_cmn_service_code_callback_t cb, uint8_t service_code)
322{
323 NSS_VERIFY_CTX_MAGIC(nss_ctx);
324
325 if (!nss_ctx->service_code_callback[service_code]) {
326 /*
327 * No callback was registered for this service code.
328 */
329 nss_warning("%p: no callback is registered for this service code %d\n", nss_ctx, service_code);
330 return NSS_CB_UNREGISTER_FAILED;
331 }
332
333 nss_ctx->service_code_callback[service_code] = NULL;
334 nss_ctx->service_code_ctx[service_code] = NULL;
335 return NSS_CB_UNREGISTER_SUCCESS;
336}
337EXPORT_SYMBOL(nss_cmn_unregister_service_code);
338
339/*
Radha krishna Simha Jiguru7098a962015-12-09 11:18:23 +0530340 * nss_cmn_get_nss_enabled()
341 * Check if NSS mode is supported on platform
342 *
343 * This API checks the device tree parameter to decide on whether
344 * NSS mode is enabled. On older kernels this will always return true
345 */
346bool nss_cmn_get_nss_enabled(void)
347{
348#if (NSS_DT_SUPPORT == 1)
349 struct device_node *cmn = NULL;
350
351 /*
352 * Get reference to NSS common device node
353 */
354 cmn = of_find_node_by_name(NULL, "nss-common");
355 if (!cmn) {
356 nss_info_always("nss is not enabled on this platform\n");
357 return false;
358 }
359#endif
360 return true;
361}
Radha krishna Simha Jiguru7098a962015-12-09 11:18:23 +0530362EXPORT_SYMBOL(nss_cmn_get_nss_enabled);