blob: 7b0b20bba6fb538d800f663b78b03eab359f78c6 [file] [log] [blame]
Amit Gupta316729b2016-08-12 12:21:15 +05301/*
2 **************************************************************************
Amit Gupta24a1ccb2018-02-26 18:32:35 +05303 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
Amit Gupta316729b2016-08-12 12:21:15 +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#include "nss_ppe.h"
Yu Huang8c107082017-07-24 14:58:26 -070018#include "nss_ppe_stats.h"
Amit Gupta79c1c202017-06-30 15:28:13 +053019
Amit Gupta6c0f6412017-11-20 15:42:43 +053020DEFINE_SPINLOCK(nss_ppe_stats_lock);
21
Amit Guptacb1696b2017-11-13 13:09:06 +053022struct nss_ppe_stats_debug nss_ppe_debug_stats;
Amit Gupta6c0f6412017-11-20 15:42:43 +053023struct nss_ppe_pvt ppe_pvt;
Amit Guptacb1696b2017-11-13 13:09:06 +053024
Amit Gupta316729b2016-08-12 12:21:15 +053025/*
26 * nss_ppe_verify_ifnum()
27 * Verify PPE interface number.
28 */
29static inline bool nss_ppe_verify_ifnum(int if_num)
30{
31 return nss_is_dynamic_interface(if_num) || (if_num == NSS_PPE_INTERFACE);
32}
33
34/*
Amit Gupta1263b082017-07-06 14:22:57 +053035 * nss_ppe_callback()
36 * Callback to handle the completion of NSS->HLOS messages.
37 */
38static void nss_ppe_callback(void *app_data, struct nss_ppe_msg *npm)
39{
40 nss_ppe_msg_callback_t callback = (nss_ppe_msg_callback_t)ppe_pvt.cb;
41 void *data = ppe_pvt.app_data;
42
43 ppe_pvt.response = NSS_TX_SUCCESS;
44 ppe_pvt.cb = NULL;
45 ppe_pvt.app_data = NULL;
46
47 if (npm->cm.response != NSS_CMN_RESPONSE_ACK) {
48 nss_warning("ppe error response %d\n", npm->cm.response);
49 ppe_pvt.response = npm->cm.response;
50 }
51
52 if (callback) {
53 callback(data, npm);
54 }
55 complete(&ppe_pvt.complete);
56}
57
58/*
59 * nss_ppe_tx_msg()
60 * Transmit a ppe message to NSSFW
61 */
62nss_tx_status_t nss_ppe_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *msg)
63{
Amit Gupta1263b082017-07-06 14:22:57 +053064 struct nss_cmn_msg *ncm = &msg->cm;
Amit Gupta1263b082017-07-06 14:22:57 +053065
66 /*
67 * Sanity check the message
68 */
69 if (ncm->type >= NSS_PPE_MSG_MAX) {
70 nss_warning("%p: message type out of range: %d\n", nss_ctx, ncm->type);
71 return NSS_TX_FAILURE;
72 }
73
Stephen Wang3e2dbd12018-03-14 17:28:17 -070074 if (!nss_ppe_verify_ifnum(ncm->interface)) {
75 nss_warning("%p: invalid interface %d\n", nss_ctx, ncm->interface);
Amit Gupta1263b082017-07-06 14:22:57 +053076 return NSS_TX_FAILURE;
77 }
78
Stephen Wang3e2dbd12018-03-14 17:28:17 -070079 return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE);
Amit Gupta1263b082017-07-06 14:22:57 +053080}
Amit Gupta1263b082017-07-06 14:22:57 +053081
82/*
83 * nss_ppe_tx_msg_sync()
84 * Transmit a ppe message to NSS firmware synchronously.
85 */
86nss_tx_status_t nss_ppe_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *npm)
87{
88 nss_tx_status_t status;
89 int ret = 0;
90
91 down(&ppe_pvt.sem);
92 ppe_pvt.cb = (void *)npm->cm.cb;
93 ppe_pvt.app_data = (void *)npm->cm.app_data;
94
95 npm->cm.cb = (nss_ptr_t)nss_ppe_callback;
96 npm->cm.app_data = (nss_ptr_t)NULL;
97
98 status = nss_ppe_tx_msg(nss_ctx, npm);
99 if (status != NSS_TX_SUCCESS) {
100 nss_warning("%p: ppe_tx_msg failed\n", nss_ctx);
101 up(&ppe_pvt.sem);
102 return status;
103 }
104
105 ret = wait_for_completion_timeout(&ppe_pvt.complete, msecs_to_jiffies(NSS_PPE_TX_TIMEOUT));
106 if (!ret) {
107 nss_warning("%p: ppe msg tx failed due to timeout\n", nss_ctx);
108 ppe_pvt.response = NSS_TX_FAILURE;
109 }
110
111 status = ppe_pvt.response;
112 up(&ppe_pvt.sem);
113 return status;
114}
Amit Gupta1263b082017-07-06 14:22:57 +0530115
116/*
117 * nss_ppe_get_context()
118 * Get NSS context instance for ppe
119 */
120struct nss_ctx_instance *nss_ppe_get_context(void)
121{
122 return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.ppe_handler_id];
123}
Amit Gupta1263b082017-07-06 14:22:57 +0530124
125/*
126 * nss_ppe_msg_init()
127 * Initialize nss_ppe_msg.
128 */
129void nss_ppe_msg_init(struct nss_ppe_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data)
130{
131 nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data);
132}
Amit Gupta1263b082017-07-06 14:22:57 +0530133
134/*
Amit Gupta24a1ccb2018-02-26 18:32:35 +0530135 * nss_ppe_tx_ipsec_config_msg
136 * API to send inline IPsec port configure message to NSS FW
137 */
Vijay Vigneshan2475f412018-05-14 19:49:44 +0530138nss_tx_status_t nss_ppe_tx_ipsec_config_msg(uint32_t nss_ifnum, uint32_t vsi_num, uint16_t mtu,
139 __attribute__((unused))uint16_t mru)
Amit Gupta24a1ccb2018-02-26 18:32:35 +0530140{
141 struct nss_ctx_instance *nss_ctx = nss_ppe_get_context();
142 struct nss_ppe_msg npm = {0};
143
144 if (!nss_ctx) {
145 nss_warning("Can't get nss context\n");
146 return NSS_TX_FAILURE;
147 }
148
149 if (vsi_num >= NSS_PPE_VSI_NUM_MAX) {
150 nss_warning("Invalid vsi number:%u\n", vsi_num);
151 return NSS_TX_FAILURE;
152 }
153
154 nss_ppe_msg_init(&npm, NSS_PPE_INTERFACE, NSS_PPE_MSG_IPSEC_PORT_CONFIG,
155 sizeof(struct nss_ppe_ipsec_port_config_msg), NULL, NULL);
156
157 npm.msg.ipsec_config.nss_ifnum = nss_ifnum;
158 npm.msg.ipsec_config.vsi_num = vsi_num;
159 npm.msg.ipsec_config.mtu = mtu;
160
161 return nss_ppe_tx_msg_sync(nss_ctx, &npm);
162}
Amit Gupta24a1ccb2018-02-26 18:32:35 +0530163
164/*
165 * nss_ppe_tx_ipsec_mtu_msg
166 * API to send IPsec port MTU change message to NSS FW
167 */
Vijay Vigneshan2475f412018-05-14 19:49:44 +0530168nss_tx_status_t nss_ppe_tx_ipsec_mtu_msg(uint32_t nss_ifnum, uint16_t mtu, __attribute__((unused))uint16_t mru)
Amit Gupta24a1ccb2018-02-26 18:32:35 +0530169{
170 struct nss_ctx_instance *nss_ctx = nss_ppe_get_context();
171 struct nss_ppe_msg npm = {0};
172
173 if (!nss_ctx) {
174 nss_warning("Can't get nss context\n");
175 return NSS_TX_FAILURE;
176 }
177
178 nss_ppe_msg_init(&npm, NSS_PPE_INTERFACE, NSS_PPE_MSG_IPSEC_PORT_MTU_CHANGE,
179 sizeof(struct nss_ppe_ipsec_port_mtu_msg), NULL, NULL);
180
181 npm.msg.ipsec_mtu.nss_ifnum = nss_ifnum;
182 npm.msg.ipsec_mtu.mtu = mtu;
183
184 return nss_ppe_tx_msg_sync(nss_ctx, &npm);
185}
Amit Gupta24a1ccb2018-02-26 18:32:35 +0530186
187/*
188 * nss_ppe_tx_ipsec_add_intf_msg
189 * API to attach NSS interface to IPsec port
190 */
191nss_tx_status_t nss_ppe_tx_ipsec_add_intf_msg(uint32_t nss_ifnum)
192{
193 struct nss_ctx_instance *nss_ctx = nss_ppe_get_context();
194 struct nss_ppe_msg npm = {0};
195
196 if (!nss_ctx) {
197 nss_warning("Can't get nss context\n");
198 return NSS_TX_FAILURE;
199 }
200
201 nss_ppe_msg_init(&npm, NSS_PPE_INTERFACE, NSS_PPE_MSG_IPSEC_ADD_INTF,
202 sizeof(struct nss_ppe_ipsec_add_intf_msg), NULL, NULL);
203
204 npm.msg.ipsec_addif.nss_ifnum = nss_ifnum;
205
206 return nss_ppe_tx_msg_sync(nss_ctx, &npm);
207}
Amit Gupta24a1ccb2018-02-26 18:32:35 +0530208
209/*
210 * nss_ppe_tx_ipsec_del_intf_msg
211 * API to detach NSS interface to IPsec port
212 */
213nss_tx_status_t nss_ppe_tx_ipsec_del_intf_msg(uint32_t nss_ifnum)
214{
215 struct nss_ctx_instance *nss_ctx = nss_ppe_get_context();
216 struct nss_ppe_msg npm = {0};
217
218 if (!nss_ctx) {
219 nss_warning("Can't get nss context\n");
220 return NSS_TX_FAILURE;
221 }
222
223 nss_ppe_msg_init(&npm, NSS_PPE_INTERFACE, NSS_PPE_MSG_IPSEC_DEL_INTF,
224 sizeof(struct nss_ppe_ipsec_del_intf_msg), NULL, NULL);
225
226 npm.msg.ipsec_delif.nss_ifnum = nss_ifnum;
227
228 return nss_ppe_tx_msg_sync(nss_ctx, &npm);
229}
Amit Gupta24a1ccb2018-02-26 18:32:35 +0530230
231/*
Amit Gupta316729b2016-08-12 12:21:15 +0530232 * nss_ppe_handler()
Amit Gupta1263b082017-07-06 14:22:57 +0530233 * Handle NSS -> HLOS messages for ppe
Amit Gupta316729b2016-08-12 12:21:15 +0530234 */
235static void nss_ppe_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data)
236{
237 struct nss_ppe_msg *msg = (struct nss_ppe_msg *)ncm;
Amit Gupta1263b082017-07-06 14:22:57 +0530238 void *ctx;
Amit Gupta316729b2016-08-12 12:21:15 +0530239
Amit Gupta1263b082017-07-06 14:22:57 +0530240 nss_ppe_msg_callback_t cb;
241
242 nss_trace("nss_ctx: %p ppe msg: %p\n", nss_ctx, msg);
Amit Gupta316729b2016-08-12 12:21:15 +0530243 BUG_ON(!nss_ppe_verify_ifnum(ncm->interface));
244
245 /*
246 * Is this a valid request/response packet?
247 */
248 if (ncm->type >= NSS_PPE_MSG_MAX) {
Amit Gupta1263b082017-07-06 14:22:57 +0530249 nss_warning("%p: received invalid message %d for PPE interface\n", nss_ctx, ncm->type);
Amit Gupta316729b2016-08-12 12:21:15 +0530250 return;
251 }
252
253 if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ppe_msg)) {
Amit Gupta1263b082017-07-06 14:22:57 +0530254 nss_warning("%p: Length of message is greater than required: %d\n", nss_ctx, nss_cmn_get_msg_len(ncm));
Amit Gupta316729b2016-08-12 12:21:15 +0530255 return;
256 }
257
258 switch (msg->cm.type) {
259 case NSS_PPE_MSG_SYNC_STATS:
260 /*
261 * session debug stats embeded in session stats msg
262 */
263 nss_ppe_stats_sync(nss_ctx, &msg->msg.stats, ncm->interface);
Amit Gupta1263b082017-07-06 14:22:57 +0530264 return;
Amit Gupta316729b2016-08-12 12:21:15 +0530265 }
Amit Gupta316729b2016-08-12 12:21:15 +0530266
Amit Gupta1263b082017-07-06 14:22:57 +0530267 /*
268 * Log failures
269 */
270 nss_core_log_msg_failures(nss_ctx, ncm);
271
272 /*
273 * Do we have a call back
274 */
275 if (!ncm->cb) {
276 return;
277 }
278
279 /*
280 * callback
281 */
282 cb = (nss_ppe_msg_callback_t)ncm->cb;
283 ctx = (void *)ncm->app_data;
284
285 cb(ctx, msg);
Thomas Wu91f4bdf2017-06-09 12:03:02 -0700286}
Thomas Wu91f4bdf2017-06-09 12:03:02 -0700287
288/*
Amit Gupta316729b2016-08-12 12:21:15 +0530289 * nss_ppe_register_handler()
290 * debugfs stats msg handler received on static ppe interface
291 *
292 * TODO: Export API so that others can also read PPE stats.
293 */
294void nss_ppe_register_handler(void)
295{
Thomas Wu91f4bdf2017-06-09 12:03:02 -0700296 struct nss_ctx_instance *nss_ctx = nss_ppe_get_context();
297
298 nss_core_register_handler(nss_ctx, NSS_PPE_INTERFACE, nss_ppe_handler, NULL);
Yu Huang8c107082017-07-24 14:58:26 -0700299
Amit Guptac438e212018-04-25 19:18:14 +0530300 if (nss_ppe_debug_stats.valid) {
301 nss_ppe_stats_dentry_create();
302 }
Amit Gupta316729b2016-08-12 12:21:15 +0530303}
304
305/*
306 * nss_ppe_free()
307 * Uninitialize PPE base
308 */
309void nss_ppe_free(void)
310{
311 /*
312 * Check if PPE base is already uninitialized.
313 */
314 if (!ppe_pvt.ppe_base) {
315 return;
316 }
317
318 /*
319 * Unmap PPE base address
320 */
321 iounmap(ppe_pvt.ppe_base);
322 ppe_pvt.ppe_base = NULL;
323
324 spin_lock_bh(&nss_ppe_stats_lock);
325 nss_ppe_debug_stats.valid = false;
326 nss_ppe_debug_stats.if_num = 0;
327 nss_ppe_debug_stats.if_index = 0;
328 spin_unlock_bh(&nss_ppe_stats_lock);
329}
330
331/*
332 * nss_ppe_init()
333 * Initialize PPE base
334 */
335void nss_ppe_init(void)
336{
337 /*
338 * Check if PPE base is already initialized.
339 */
340 if (ppe_pvt.ppe_base) {
341 return;
342 }
343
344 /*
345 * Get the PPE base address
346 */
347 ppe_pvt.ppe_base = ioremap_nocache(PPE_BASE_ADDR, PPE_REG_SIZE);
348 if (!ppe_pvt.ppe_base) {
349 nss_warning("DRV can't get PPE base address\n");
350 return;
351 }
352
353 spin_lock_bh(&nss_ppe_stats_lock);
354 nss_ppe_debug_stats.valid = true;
355 nss_ppe_debug_stats.if_num = 0;
356 nss_ppe_debug_stats.if_index = 0;
357 spin_unlock_bh(&nss_ppe_stats_lock);
Amit Gupta1263b082017-07-06 14:22:57 +0530358
359 sema_init(&ppe_pvt.sem, 1);
360 init_completion(&ppe_pvt.complete);
Amit Gupta316729b2016-08-12 12:21:15 +0530361}