blob: 50c38347af34ab8cf0e4494db80528ef44ba5972 [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 */
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/*
57 * nss_cmn_get_interface_number()
58 * Return the interface number of the NSS net_device.
59 *
60 * Returns -1 on failure or the interface number of dev is an NSS net_device.
61 */
62int32_t nss_cmn_get_interface_number(struct nss_ctx_instance *nss_ctx, struct net_device *dev)
63{
64 int i;
65
66 NSS_VERIFY_CTX_MAGIC(nss_ctx);
67 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
68 nss_warning("%p: Interface number could not be found as core not ready", nss_ctx);
69 return -1;
70 }
71
72 nss_assert(dev != 0);
73
74 /*
75 * Check physical interface table
76 */
77 for (i = 0; i < NSS_MAX_NET_INTERFACES; i++) {
Stephen Wang84e0e992016-09-07 12:31:40 -070078 if (dev == nss_ctx->subsys_dp_register[i].ndev) {
Abhishek Rastogi99714332014-04-02 19:38:12 +053079 return i;
80 }
81 }
82
83 nss_warning("%p: Interface number could not be found as interface has not registered yet", nss_ctx);
84 return -1;
85}
Stephen Wanga73a7892017-07-05 15:23:14 -070086EXPORT_SYMBOL(nss_cmn_get_interface_number);
Abhishek Rastogi99714332014-04-02 19:38:12 +053087
88/*
89 * nss_cmn_get_interface_dev()
90 * Return the net_device for NSS interface id.
91 *
92 * Returns NULL on failure or the net_device for NSS interface id.
93 */
94struct net_device *nss_cmn_get_interface_dev(struct nss_ctx_instance *ctx, uint32_t if_num)
95{
96 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)ctx;
97
98 NSS_VERIFY_CTX_MAGIC(nss_ctx);
99 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
100 nss_warning("%p: Interface device could not be found as core not ready", nss_ctx);
101 return NULL;
102 }
103
104 if (unlikely(if_num >= NSS_MAX_NET_INTERFACES)) {
105 return NULL;
106 }
107
Stephen Wang84e0e992016-09-07 12:31:40 -0700108 return nss_ctx->subsys_dp_register[if_num].ndev;
Abhishek Rastogi99714332014-04-02 19:38:12 +0530109}
Stephen Wanga73a7892017-07-05 15:23:14 -0700110EXPORT_SYMBOL(nss_cmn_get_interface_dev);
111
112/*
113 * nss_cmn_get_interface_number_by_dev_and_type()
114 * Return the NSS interface id for the net_device.
115 *
116 * Returns < 0 on failure or the NSS interface id for the given device and type.
117 */
118int32_t nss_cmn_get_interface_number_by_dev_and_type(struct net_device *dev, uint32_t type)
119{
120 int i, core;
121 struct nss_subsystem_dataplane_register *nsdr;
122
123 nss_assert(dev != 0);
124 for (core = 0; core < NSS_MAX_CORES; core++) {
125 for (i = 0; i < NSS_MAX_NET_INTERFACES; i++) {
126 nsdr = &nss_top_main.nss[core].subsys_dp_register[i];
127 if (dev == nsdr->ndev && type == nsdr->type) {
128 return i;
129 }
130 }
131 }
132
133 nss_warning("Interface number could not be found for %p (%s) as interface has not registered yet", dev, dev->name);
134 return -1;
135}
136EXPORT_SYMBOL(nss_cmn_get_interface_number_by_dev_and_type);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530137
138/*
Gareth Williamsb52af512014-04-25 19:31:15 +0100139 * nss_cmn_get_interface_number_by_dev()
140 * Return the NSS interface id for the net_device.
141 *
142 * Returns < 0 on failure or the NSS interface id for the given device.
143 */
144int32_t nss_cmn_get_interface_number_by_dev(struct net_device *dev)
145{
Stephen Wanga73a7892017-07-05 15:23:14 -0700146 return nss_cmn_get_interface_number_by_dev_and_type(dev, 0);
Gareth Williamsb52af512014-04-25 19:31:15 +0100147}
Stephen Wanga73a7892017-07-05 15:23:14 -0700148EXPORT_SYMBOL(nss_cmn_get_interface_number_by_dev);
Gareth Williamsb52af512014-04-25 19:31:15 +0100149
150/*
Abhishek Rastogi99714332014-04-02 19:38:12 +0530151 * nss_cmn_get_state()
152 * return the NSS initialization state
153 */
154nss_state_t nss_cmn_get_state(struct nss_ctx_instance *ctx)
155{
156 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)ctx;
157 nss_state_t state = NSS_STATE_UNINITIALIZED;
158
159 NSS_VERIFY_CTX_MAGIC(nss_ctx);
160 spin_lock_bh(&nss_top_main.lock);
161 if (nss_ctx->state == NSS_CORE_STATE_INITIALIZED) {
162 state = NSS_STATE_INITIALIZED;
163 }
164 spin_unlock_bh(&nss_top_main.lock);
165
166 return state;
167}
Stephen Wanga73a7892017-07-05 15:23:14 -0700168EXPORT_SYMBOL(nss_cmn_get_state);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530169
170/*
Sakthi Vignesh Radhakrishnan2842f9c2017-07-27 13:56:07 -0700171 * nss_cmn_interface_is_redirect()
172 * Return true if the interface is a redirect interface.
Abhishek Rastogi99714332014-04-02 19:38:12 +0530173 */
Sakthi Vignesh Radhakrishnan2842f9c2017-07-27 13:56:07 -0700174bool nss_cmn_interface_is_redirect(struct nss_ctx_instance *nss_ctx, int32_t interface_num)
Abhishek Rastogi99714332014-04-02 19:38:12 +0530175{
Casey Chend90d0e62017-11-06 13:21:26 -0800176 enum nss_dynamic_interface_type type = nss_dynamic_interface_get_type(nss_ctx, interface_num);
177
178 return type == NSS_DYNAMIC_INTERFACE_TYPE_WIFI
179 || type == NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR_N2H
180 || type == NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR_H2N
181 || type == NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED;
Abhishek Rastogi99714332014-04-02 19:38:12 +0530182}
Stephen Wanga73a7892017-07-05 15:23:14 -0700183EXPORT_SYMBOL(nss_cmn_interface_is_redirect);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530184
185/*
ratheesh kannoth93ba95c2017-07-13 15:52:52 +0530186 * nss_cmn_rx_dropped_sum()
187 * Sum rx_dropped count.
188 */
189uint32_t nss_cmn_rx_dropped_sum(struct nss_cmn_node_stats *node_stats)
190{
191 uint32_t sum = 0;
192 int i;
193 for (i = 0; i < NSS_MAX_NUM_PRI; i++) {
194 sum += node_stats->rx_dropped[i];
195 }
196 return sum;
197}
Stephen Wanga73a7892017-07-05 15:23:14 -0700198EXPORT_SYMBOL(nss_cmn_rx_dropped_sum);
ratheesh kannoth93ba95c2017-07-13 15:52:52 +0530199
200/*
Abhishek Rastogi99714332014-04-02 19:38:12 +0530201 * nss_cmn_register_queue_decongestion()
202 * Register for queue decongestion event
203 */
204nss_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)
205{
206 uint32_t i;
207
208 NSS_VERIFY_CTX_MAGIC(nss_ctx);
209 spin_lock_bh(&nss_ctx->decongest_cb_lock);
210
211 /*
212 * Find vacant location in callback table
213 */
214 for (i = 0; i< NSS_MAX_CLIENTS; i++) {
215 if (nss_ctx->queue_decongestion_callback[i] == NULL) {
216 nss_ctx->queue_decongestion_callback[i] = event_callback;
217 nss_ctx->queue_decongestion_ctx[i] = app_ctx;
218 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
219 return NSS_CB_REGISTER_SUCCESS;
220 }
221 }
222
223 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
224 return NSS_CB_REGISTER_FAILED;
225}
Stephen Wanga73a7892017-07-05 15:23:14 -0700226EXPORT_SYMBOL(nss_cmn_register_queue_decongestion);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530227
228/*
229 * nss_cmn_unregister_queue_decongestion()
230 * Unregister for queue decongestion event
231 */
232nss_cb_unregister_status_t nss_cmn_unregister_queue_decongestion(struct nss_ctx_instance *nss_ctx, nss_cmn_queue_decongestion_callback_t event_callback)
233{
234 uint32_t i;
235
236 NSS_VERIFY_CTX_MAGIC(nss_ctx);
237 spin_lock_bh(&nss_ctx->decongest_cb_lock);
238
239 /*
240 * Find actual location in callback table
241 */
242 for (i = 0; i< NSS_MAX_CLIENTS; i++) {
243 if (nss_ctx->queue_decongestion_callback[i] == event_callback) {
244 nss_ctx->queue_decongestion_callback[i] = NULL;
245 nss_ctx->queue_decongestion_ctx[i] = NULL;
246 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
247 return NSS_CB_UNREGISTER_SUCCESS;
248 }
249 }
250
251 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
252 return NSS_CB_UNREGISTER_FAILED;
253}
Stephen Wanga73a7892017-07-05 15:23:14 -0700254EXPORT_SYMBOL(nss_cmn_unregister_queue_decongestion);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530255
Radha krishna Simha Jiguru7098a962015-12-09 11:18:23 +0530256/*
257 * nss_cmn_get_nss_enabled()
258 * Check if NSS mode is supported on platform
259 *
260 * This API checks the device tree parameter to decide on whether
261 * NSS mode is enabled. On older kernels this will always return true
262 */
263bool nss_cmn_get_nss_enabled(void)
264{
265#if (NSS_DT_SUPPORT == 1)
266 struct device_node *cmn = NULL;
267
268 /*
269 * Get reference to NSS common device node
270 */
271 cmn = of_find_node_by_name(NULL, "nss-common");
272 if (!cmn) {
273 nss_info_always("nss is not enabled on this platform\n");
274 return false;
275 }
276#endif
277 return true;
278}
Radha krishna Simha Jiguru7098a962015-12-09 11:18:23 +0530279EXPORT_SYMBOL(nss_cmn_get_nss_enabled);