blob: 4af208b01cdd9f0df54f79d30cec3010201cc2c0 [file] [log] [blame]
Abhishek Rastogi99714332014-04-02 19:38:12 +05301/*
2 **************************************************************************
3 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
4 * 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
22#include "nss_tx_rx_common.h"
23
24/*
25 * nss_cmn_msg_init()
26 * Initialize the common message structure.
27 */
28void nss_cmn_msg_init(struct nss_cmn_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data)
29{
30 ncm->interface = if_num;
31 ncm->version = NSS_HLOS_MESSAGE_VERSION;
32 ncm->type = type;
33 ncm->len = len;
34 ncm->cb = (uint32_t)cb;
35 ncm->app_data = (uint32_t)app_data;
36}
37
38/*
39 * nss_cmn_get_interface_number()
40 * Return the interface number of the NSS net_device.
41 *
42 * Returns -1 on failure or the interface number of dev is an NSS net_device.
43 */
44int32_t nss_cmn_get_interface_number(struct nss_ctx_instance *nss_ctx, struct net_device *dev)
45{
46 int i;
47
48 NSS_VERIFY_CTX_MAGIC(nss_ctx);
49 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
50 nss_warning("%p: Interface number could not be found as core not ready", nss_ctx);
51 return -1;
52 }
53
54 nss_assert(dev != 0);
55
56 /*
57 * Check physical interface table
58 */
59 for (i = 0; i < NSS_MAX_NET_INTERFACES; i++) {
60 if (dev == ((struct nss_ctx_instance *)nss_ctx)->nss_top->if_ctx[i]) {
61 return i;
62 }
63 }
64
65 nss_warning("%p: Interface number could not be found as interface has not registered yet", nss_ctx);
66 return -1;
67}
68
69/*
70 * nss_cmn_get_interface_dev()
71 * Return the net_device for NSS interface id.
72 *
73 * Returns NULL on failure or the net_device for NSS interface id.
74 */
75struct net_device *nss_cmn_get_interface_dev(struct nss_ctx_instance *ctx, uint32_t if_num)
76{
77 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)ctx;
78
79 NSS_VERIFY_CTX_MAGIC(nss_ctx);
80 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
81 nss_warning("%p: Interface device could not be found as core not ready", nss_ctx);
82 return NULL;
83 }
84
85 if (unlikely(if_num >= NSS_MAX_NET_INTERFACES)) {
86 return NULL;
87 }
88
89 return nss_ctx->nss_top->if_ctx[if_num];
90}
91
92/*
Gareth Williamsb52af512014-04-25 19:31:15 +010093 * nss_cmn_get_interface_number_by_dev()
94 * Return the NSS interface id for the net_device.
95 *
96 * Returns < 0 on failure or the NSS interface id for the given device.
97 */
98int32_t nss_cmn_get_interface_number_by_dev(struct net_device *dev)
99{
100 int i;
101
102 nss_assert(dev != 0);
103
104 /*
105 * Check physical interface table
106 */
107 for (i = 0; i < NSS_MAX_NET_INTERFACES; i++) {
108 if (dev == nss_top_main.if_ctx[i]) {
109 return i;
110 }
111 }
112
113 nss_warning("Interface number could not be found for %p (%s) as interface has not registered yet", dev, dev->name);
114 return -1;
115}
116
117/*
Abhishek Rastogi99714332014-04-02 19:38:12 +0530118 * nss_cmn_get_state()
119 * return the NSS initialization state
120 */
121nss_state_t nss_cmn_get_state(struct nss_ctx_instance *ctx)
122{
123 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)ctx;
124 nss_state_t state = NSS_STATE_UNINITIALIZED;
125
126 NSS_VERIFY_CTX_MAGIC(nss_ctx);
127 spin_lock_bh(&nss_top_main.lock);
128 if (nss_ctx->state == NSS_CORE_STATE_INITIALIZED) {
129 state = NSS_STATE_INITIALIZED;
130 }
131 spin_unlock_bh(&nss_top_main.lock);
132
133 return state;
134}
135
136/*
137 * nss_cmn_interface_is_virtual()
138 * Return true if the interface number is a virtual NSS interface
139 */
140bool nss_cmn_interface_is_virtual(void *nss_ctx, int32_t interface_num)
141{
142 return (NSS_IS_IF_TYPE(VIRTUAL, interface_num));
143}
144
145/*
146 * nss_cmn_register_queue_decongestion()
147 * Register for queue decongestion event
148 */
149nss_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)
150{
151 uint32_t i;
152
153 NSS_VERIFY_CTX_MAGIC(nss_ctx);
154 spin_lock_bh(&nss_ctx->decongest_cb_lock);
155
156 /*
157 * Find vacant location in callback table
158 */
159 for (i = 0; i< NSS_MAX_CLIENTS; i++) {
160 if (nss_ctx->queue_decongestion_callback[i] == NULL) {
161 nss_ctx->queue_decongestion_callback[i] = event_callback;
162 nss_ctx->queue_decongestion_ctx[i] = app_ctx;
163 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
164 return NSS_CB_REGISTER_SUCCESS;
165 }
166 }
167
168 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
169 return NSS_CB_REGISTER_FAILED;
170}
171
172/*
173 * nss_cmn_unregister_queue_decongestion()
174 * Unregister for queue decongestion event
175 */
176nss_cb_unregister_status_t nss_cmn_unregister_queue_decongestion(struct nss_ctx_instance *nss_ctx, nss_cmn_queue_decongestion_callback_t event_callback)
177{
178 uint32_t i;
179
180 NSS_VERIFY_CTX_MAGIC(nss_ctx);
181 spin_lock_bh(&nss_ctx->decongest_cb_lock);
182
183 /*
184 * Find actual location in callback table
185 */
186 for (i = 0; i< NSS_MAX_CLIENTS; i++) {
187 if (nss_ctx->queue_decongestion_callback[i] == event_callback) {
188 nss_ctx->queue_decongestion_callback[i] = NULL;
189 nss_ctx->queue_decongestion_ctx[i] = NULL;
190 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
191 return NSS_CB_UNREGISTER_SUCCESS;
192 }
193 }
194
195 spin_unlock_bh(&nss_ctx->decongest_cb_lock);
196 return NSS_CB_UNREGISTER_FAILED;
197}
198
199EXPORT_SYMBOL(nss_cmn_get_interface_number);
200EXPORT_SYMBOL(nss_cmn_get_interface_dev);
201EXPORT_SYMBOL(nss_cmn_get_state);
202EXPORT_SYMBOL(nss_cmn_interface_is_virtual);
203EXPORT_SYMBOL(nss_cmn_msg_init);
Gareth Williamsb52af512014-04-25 19:31:15 +0100204EXPORT_SYMBOL(nss_cmn_get_interface_number_by_dev);
Abhishek Rastogi99714332014-04-02 19:38:12 +0530205
206EXPORT_SYMBOL(nss_cmn_register_queue_decongestion);
207EXPORT_SYMBOL(nss_cmn_unregister_queue_decongestion);
208