blob: c66327ec304f6dd6f532322c39b59ce96f2e14b6 [file] [log] [blame]
Amit Gupta316729b2016-08-12 12:21:15 +05301/*
2 **************************************************************************
Thomas Wufc4d9fd2017-03-22 10:15:30 -07003 * Copyright (c) 2016-2017, 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"
18
Amit Gupta79c1c202017-06-30 15:28:13 +053019static uint8_t ppe_cc_nonexception[NSS_STATS_PPE_CPU_CODE_NONEXCEPTION_MAX] = {
20 NSS_STATS_PPE_CPU_CODE_EXP_FAKE_L2_PROT_ERR,
21 NSS_STATS_PPE_CPU_CODE_EXP_FAKE_MAC_HEADER_ERR,
22 NSS_STATS_PPE_CPU_CODE_EXP_BITMAP_MAX,
23 NSS_STATS_PPE_CPU_CODE_L2_EXP_MRU_FAIL,
24 NSS_STATS_PPE_CPU_CODE_L2_EXP_MTU_FAIL,
25 NSS_STATS_PPE_CPU_CODE_L3_EXP_IP_PREFIX_BC,
26 NSS_STATS_PPE_CPU_CODE_L3_EXP_MTU_FAIL,
27 NSS_STATS_PPE_CPU_CODE_L3_EXP_MRU_FAIL,
28 NSS_STATS_PPE_CPU_CODE_L3_EXP_ICMP_RDT,
29 NSS_STATS_PPE_CPU_CODE_L3_EXP_IP_RT_TTL1_TO_ME,
30 NSS_STATS_PPE_CPU_CODE_L3_EXP_IP_RT_TTL_ZERO,
31 NSS_STATS_PPE_CPU_CODE_L3_FLOW_SERVICE_CODE_LOOP,
32 NSS_STATS_PPE_CPU_CODE_L3_FLOW_DE_ACCELERATE,
33 NSS_STATS_PPE_CPU_CODE_L3_EXP_FLOW_SRC_IF_CHK_FAIL,
34 NSS_STATS_PPE_CPU_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH,
35 NSS_STATS_PPE_CPU_CODE_L3_EXP_MTU_DF_FAIL,
36 NSS_STATS_PPE_CPU_CODE_L3_EXP_PPPOE_MULTICAST,
37 NSS_STATS_PPE_CPU_CODE_MGMT_OFFSET,
38 NSS_STATS_PPE_CPU_CODE_MGMT_EAPOL,
39 NSS_STATS_PPE_CPU_CODE_MGMT_PPPOE_DIS,
40 NSS_STATS_PPE_CPU_CODE_MGMT_IGMP,
41 NSS_STATS_PPE_CPU_CODE_MGMT_ARP_REQ,
42 NSS_STATS_PPE_CPU_CODE_MGMT_ARP_REP,
43 NSS_STATS_PPE_CPU_CODE_MGMT_DHCPv4,
44 NSS_STATS_PPE_CPU_CODE_MGMT_MLD,
45 NSS_STATS_PPE_CPU_CODE_MGMT_NS,
46 NSS_STATS_PPE_CPU_CODE_MGMT_NA,
47 NSS_STATS_PPE_CPU_CODE_MGMT_DHCPv6,
48 NSS_STATS_PPE_CPU_CODE_PTP_OFFSET,
49 NSS_STATS_PPE_CPU_CODE_PTP_SYNC,
50 NSS_STATS_PPE_CPU_CODE_PTP_FOLLOW_UP,
51 NSS_STATS_PPE_CPU_CODE_PTP_DELAY_REQ,
52 NSS_STATS_PPE_CPU_CODE_PTP_DELAY_RESP,
53 NSS_STATS_PPE_CPU_CODE_PTP_PDELAY_REQ,
54 NSS_STATS_PPE_CPU_CODE_PTP_PDELAY_RESP,
55 NSS_STATS_PPE_CPU_CODE_PTP_PDELAY_RESP_FOLLOW_UP,
56 NSS_STATS_PPE_CPU_CODE_PTP_ANNOUNCE,
57 NSS_STATS_PPE_CPU_CODE_PTP_MANAGEMENT,
58 NSS_STATS_PPE_CPU_CODE_PTP_SIGNALING,
59 NSS_STATS_PPE_CPU_CODE_PTP_PKT_RSV_MSG,
60 NSS_STATS_PPE_CPU_CODE_IPV4_SG_UNKNOWN,
61 NSS_STATS_PPE_CPU_CODE_IPV6_SG_UNKNOWN,
62 NSS_STATS_PPE_CPU_CODE_ARP_SG_UNKNOWN,
63 NSS_STATS_PPE_CPU_CODE_ND_SG_UNKNOWN,
64 NSS_STATS_PPE_CPU_CODE_IPV4_SG_VIO,
65 NSS_STATS_PPE_CPU_CODE_IPV6_SG_VIO,
66 NSS_STATS_PPE_CPU_CODE_ARP_SG_VIO,
67 NSS_STATS_PPE_CPU_CODE_ND_SG_VIO,
68 NSS_STATS_PPE_CPU_CODE_L3_ROUTING_IP_TO_ME,
69 NSS_STATS_PPE_CPU_CODE_L3_FLOW_SNAT_ACTION,
70 NSS_STATS_PPE_CPU_CODE_L3_FLOW_DNAT_ACTION,
71 NSS_STATS_PPE_CPU_CODE_L3_FLOW_RT_ACTION,
72 NSS_STATS_PPE_CPU_CODE_L3_FLOW_BR_ACTION,
73 NSS_STATS_PPE_CPU_CODE_L3_MC_BRIDGE_ACTION,
74 NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_RT_ACTION,
75 NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_SNAPT_ACTION,
76 NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_DNAPT_ACTION,
77 NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_SNAT_ACTION,
78 NSS_STATS_PPE_CPU_CODE_L3_ROUTE_PREHEAD_DNAT_ACTION,
79 NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ACTION,
80 NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ERROR,
81 NSS_STATS_PPE_CPU_CODE_L3_ROUTE_ACTION,
82 NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_ACTION,
83 NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_NH_INVALID_ACTION,
84 NSS_STATS_PPE_CPU_CODE_L3_NO_ROUTE_PREHEAD_ACTION,
85 NSS_STATS_PPE_CPU_CODE_L3_BRIDGE_ACTION,
86 NSS_STATS_PPE_CPU_CODE_L3_FLOW_ACTION,
87 NSS_STATS_PPE_CPU_CODE_L3_FLOW_MISS_ACTION,
88 NSS_STATS_PPE_CPU_CODE_L2_NEW_MAC_ADDRESS,
89 NSS_STATS_PPE_CPU_CODE_L2_HASH_COLLISION,
90 NSS_STATS_PPE_CPU_CODE_L2_STATION_MOVE,
91 NSS_STATS_PPE_CPU_CODE_L2_LEARN_LIMIT,
92 NSS_STATS_PPE_CPU_CODE_L2_SA_LOOKUP_ACTION,
93 NSS_STATS_PPE_CPU_CODE_L2_DA_LOOKUP_ACTION,
94 NSS_STATS_PPE_CPU_CODE_APP_CTRL_ACTION,
95 NSS_STATS_PPE_CPU_CODE_IN_VLAN_FILTER_ACTION,
96 NSS_STATS_PPE_CPU_CODE_IN_VLAN_XLT_MISS,
97 NSS_STATS_PPE_CPU_CODE_EG_VLAN_FILTER_DROP,
98 NSS_STATS_PPE_CPU_CODE_ACL_PRE_ACTION,
99 NSS_STATS_PPE_CPU_CODE_ACL_POST_ACTION,
100 NSS_STATS_PPE_CPU_CODE_SERVICE_CODE_ACTION,
101};
102
Amit Gupta316729b2016-08-12 12:21:15 +0530103/*
104 * nss_ppe_verify_ifnum()
105 * Verify PPE interface number.
106 */
107static inline bool nss_ppe_verify_ifnum(int if_num)
108{
109 return nss_is_dynamic_interface(if_num) || (if_num == NSS_PPE_INTERFACE);
110}
111
112/*
113 * nss_ppe_stats_sync
114 * PPE connection sync stats from NSS
115 */
116static void nss_ppe_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_sync_stats_msg *stats_msg, uint16_t if_num)
117{
118 spin_lock_bh(&nss_ppe_stats_lock);
119 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_L3_FLOWS] += stats_msg->nss_ppe_v4_l3_flows;
120 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_L2_FLOWS] += stats_msg->nss_ppe_v4_l2_flows;
121 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_CREATE_REQ] += stats_msg->nss_ppe_v4_create_req;
122 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_CREATE_FAIL] += stats_msg->nss_ppe_v4_create_fail;
123 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_DESTROY_REQ] += stats_msg->nss_ppe_v4_destroy_req;
124 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_DESTROY_FAIL] += stats_msg->nss_ppe_v4_destroy_fail;
Amit Gupta263df9c2017-05-16 20:43:07 +0530125 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_MC_CREATE_REQ] += stats_msg->nss_ppe_v4_mc_create_req;
126 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_MC_CREATE_FAIL] += stats_msg->nss_ppe_v4_mc_create_fail;
127 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_MC_UPDATE_REQ] += stats_msg->nss_ppe_v4_mc_update_req;
128 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_MC_UPDATE_FAIL] += stats_msg->nss_ppe_v4_mc_update_fail;
129 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_MC_DESTROY_REQ] += stats_msg->nss_ppe_v4_mc_destroy_req;
130 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V4_MC_DESTROY_FAIL] += stats_msg->nss_ppe_v4_mc_destroy_fail;
Amit Gupta316729b2016-08-12 12:21:15 +0530131
132 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_L3_FLOWS] += stats_msg->nss_ppe_v6_l3_flows;
133 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_L2_FLOWS] += stats_msg->nss_ppe_v6_l2_flows;
134 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_CREATE_REQ] += stats_msg->nss_ppe_v6_create_req;
135 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_CREATE_FAIL] += stats_msg->nss_ppe_v6_create_fail;
136 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_DESTROY_REQ] += stats_msg->nss_ppe_v6_destroy_req;
137 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_DESTROY_FAIL] += stats_msg->nss_ppe_v6_destroy_fail;
Amit Gupta263df9c2017-05-16 20:43:07 +0530138 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_MC_CREATE_REQ] += stats_msg->nss_ppe_v6_mc_create_req;
139 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_MC_CREATE_FAIL] += stats_msg->nss_ppe_v6_mc_create_fail;
140 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_MC_UPDATE_REQ] += stats_msg->nss_ppe_v6_mc_update_req;
141 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_MC_UPDATE_FAIL] += stats_msg->nss_ppe_v6_mc_update_fail;
142 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_MC_DESTROY_REQ] += stats_msg->nss_ppe_v6_mc_destroy_req;
143 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_V6_MC_DESTROY_FAIL] += stats_msg->nss_ppe_v6_mc_destroy_fail;
Amit Gupta316729b2016-08-12 12:21:15 +0530144
Amit Gupta263df9c2017-05-16 20:43:07 +0530145 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_VP_FULL] += stats_msg->nss_ppe_fail_vp_full;
Amit Gupta316729b2016-08-12 12:21:15 +0530146 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_NH_FULL] += stats_msg->nss_ppe_fail_nh_full;
147 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_FLOW_FULL] += stats_msg->nss_ppe_fail_flow_full;
148 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_HOST_FULL] += stats_msg->nss_ppe_fail_host_full;
149 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_PUBIP_FULL] += stats_msg->nss_ppe_fail_pubip_full;
150 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_PORT_SETUP] += stats_msg->nss_ppe_fail_port_setup;
151 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_RW_FIFO_FULL] += stats_msg->nss_ppe_fail_rw_fifo_full;
152 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_FLOW_COMMAND] += stats_msg->nss_ppe_fail_flow_command;
153 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_UNKNOWN_PROTO] += stats_msg->nss_ppe_fail_unknown_proto;
154 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_PPE_UNRESPONSIVE] += stats_msg->nss_ppe_fail_ppe_unresponsive;
Amit Gupta263df9c2017-05-16 20:43:07 +0530155 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_CE_OPAQUE_INVALID] += stats_msg->nss_ppe_ce_opaque_invalid;
Thomas Wufc4d9fd2017-03-22 10:15:30 -0700156 nss_ppe_debug_stats.conn_stats[NSS_STATS_PPE_FAIL_FQG_FULL] += stats_msg->nss_ppe_fail_fqg_full;
Amit Gupta316729b2016-08-12 12:21:15 +0530157 spin_unlock_bh(&nss_ppe_stats_lock);
158}
159
160/*
Amit Gupta1263b082017-07-06 14:22:57 +0530161 * nss_ppe_callback()
162 * Callback to handle the completion of NSS->HLOS messages.
163 */
164static void nss_ppe_callback(void *app_data, struct nss_ppe_msg *npm)
165{
166 nss_ppe_msg_callback_t callback = (nss_ppe_msg_callback_t)ppe_pvt.cb;
167 void *data = ppe_pvt.app_data;
168
169 ppe_pvt.response = NSS_TX_SUCCESS;
170 ppe_pvt.cb = NULL;
171 ppe_pvt.app_data = NULL;
172
173 if (npm->cm.response != NSS_CMN_RESPONSE_ACK) {
174 nss_warning("ppe error response %d\n", npm->cm.response);
175 ppe_pvt.response = npm->cm.response;
176 }
177
178 if (callback) {
179 callback(data, npm);
180 }
181 complete(&ppe_pvt.complete);
182}
183
184/*
185 * nss_ppe_tx_msg()
186 * Transmit a ppe message to NSSFW
187 */
188nss_tx_status_t nss_ppe_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *msg)
189{
190 struct nss_ppe_msg *nm;
191 struct nss_cmn_msg *ncm = &msg->cm;
192 struct sk_buff *nbuf;
193 int32_t status;
194
195 NSS_VERIFY_CTX_MAGIC(nss_ctx);
196 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
197 nss_warning("%p: ppe msg dropped as core not ready\n", nss_ctx);
198 return NSS_TX_FAILURE_NOT_READY;
199 }
200
201 /*
202 * Sanity check the message
203 */
204 if (ncm->type >= NSS_PPE_MSG_MAX) {
205 nss_warning("%p: message type out of range: %d\n", nss_ctx, ncm->type);
206 return NSS_TX_FAILURE;
207 }
208
209 if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ppe_msg)) {
210 nss_warning("%p: message length is invalid: %d\n", nss_ctx, nss_cmn_get_msg_len(ncm));
211 return NSS_TX_FAILURE;
212 }
213
214 nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
215 if (unlikely(!nbuf)) {
216 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]);
217 nss_warning("%p: msg dropped as command allocation failed\n", nss_ctx);
218 return NSS_TX_FAILURE;
219 }
220
221 /*
222 * Copy the message to our skb
223 */
224 nm = (struct nss_ppe_msg *)skb_put(nbuf, sizeof(struct nss_ppe_msg));
225 memcpy(nm, msg, sizeof(struct nss_ppe_msg));
226
227 status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
228 if (status != NSS_CORE_STATUS_SUCCESS) {
229 dev_kfree_skb_any(nbuf);
230 nss_warning("%p: Unable to enqueue 'ppe message'\n", nss_ctx);
231 return NSS_TX_FAILURE;
232 }
233
234 nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
235
236 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
237 return NSS_TX_SUCCESS;
238}
239EXPORT_SYMBOL(nss_ppe_tx_msg);
240
241/*
242 * nss_ppe_tx_msg_sync()
243 * Transmit a ppe message to NSS firmware synchronously.
244 */
245nss_tx_status_t nss_ppe_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *npm)
246{
247 nss_tx_status_t status;
248 int ret = 0;
249
250 down(&ppe_pvt.sem);
251 ppe_pvt.cb = (void *)npm->cm.cb;
252 ppe_pvt.app_data = (void *)npm->cm.app_data;
253
254 npm->cm.cb = (nss_ptr_t)nss_ppe_callback;
255 npm->cm.app_data = (nss_ptr_t)NULL;
256
257 status = nss_ppe_tx_msg(nss_ctx, npm);
258 if (status != NSS_TX_SUCCESS) {
259 nss_warning("%p: ppe_tx_msg failed\n", nss_ctx);
260 up(&ppe_pvt.sem);
261 return status;
262 }
263
264 ret = wait_for_completion_timeout(&ppe_pvt.complete, msecs_to_jiffies(NSS_PPE_TX_TIMEOUT));
265 if (!ret) {
266 nss_warning("%p: ppe msg tx failed due to timeout\n", nss_ctx);
267 ppe_pvt.response = NSS_TX_FAILURE;
268 }
269
270 status = ppe_pvt.response;
271 up(&ppe_pvt.sem);
272 return status;
273}
274EXPORT_SYMBOL(nss_ppe_tx_msg_sync);
275
276/*
277 * nss_ppe_get_context()
278 * Get NSS context instance for ppe
279 */
280struct nss_ctx_instance *nss_ppe_get_context(void)
281{
282 return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.ppe_handler_id];
283}
284EXPORT_SYMBOL(nss_ppe_get_context);
285
286/*
287 * nss_ppe_msg_init()
288 * Initialize nss_ppe_msg.
289 */
290void nss_ppe_msg_init(struct nss_ppe_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data)
291{
292 nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data);
293}
294EXPORT_SYMBOL(nss_ppe_msg_init);
295
296/*
297 * nss_ppe_tx_l2_exception_msg
298 * API to send vsi assign message to NSS FW
299 */
300nss_tx_status_t nss_ppe_tx_l2_exception_msg(uint32_t if_num, bool exception_enable)
301{
302 struct nss_ctx_instance *nss_ctx = nss_ppe_get_context();
303 struct nss_ppe_msg npm;
304
305 if (!nss_ctx) {
306 nss_warning("Can't get nss context\n");
307 return NSS_TX_FAILURE;
308 }
309
310 if (!nss_ppe_verify_ifnum(if_num)) {
311 nss_warning("%p: invalid interface %d\n", nss_ctx, if_num);
312 return NSS_TX_FAILURE;
313 }
314
315 nss_ppe_msg_init(&npm, if_num, NSS_PPE_MSG_L2_EXCEPTION,
316 sizeof(struct nss_ppe_l2_exception_msg), NULL, NULL);
317
318 npm.msg.l2_exception.l2_exception_enable = exception_enable;
319
320 return nss_ppe_tx_msg_sync(nss_ctx, &npm);
321}
322EXPORT_SYMBOL(nss_ppe_tx_l2_exception_msg);
323
324/*
Amit Gupta316729b2016-08-12 12:21:15 +0530325 * nss_ppe_stats_conn_get()
326 * Get ppe connection stats.
327 */
328void nss_ppe_stats_conn_get(uint32_t *stats)
329{
330 if (!stats) {
Amit Gupta1263b082017-07-06 14:22:57 +0530331 nss_warning("No memory to copy ppe connection stats\n");
Amit Gupta316729b2016-08-12 12:21:15 +0530332 return;
333 }
334
335 spin_lock_bh(&nss_ppe_stats_lock);
336
337 if (!nss_ppe_debug_stats.valid) {
338 spin_unlock_bh(&nss_ppe_stats_lock);
339 nss_warning("PPE base address not initialized!\n");
340 return;
341 }
342
343 /*
344 * Get flow stats
345 */
346 memcpy(stats, nss_ppe_debug_stats.conn_stats, (sizeof(uint32_t) * NSS_STATS_PPE_CONN_MAX));
347
348 spin_unlock_bh(&nss_ppe_stats_lock);
349}
350
351/*
352 * nss_ppe_stats_l3_get()
353 * Get ppe L3 debug stats.
354 */
355void nss_ppe_stats_l3_get(uint32_t *stats)
356{
357 if (!stats) {
358 nss_warning("No memory to copy ppe l3 dbg stats\n");
359 return;
360 }
361
362 spin_lock_bh(&nss_ppe_stats_lock);
363
364 if (!nss_ppe_debug_stats.valid) {
365 spin_unlock_bh(&nss_ppe_stats_lock);
366 nss_warning("PPE base address not initialized!\n");
367 return;
368 }
369
370 nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG0_OFFSET);
371 nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_STATS_PPE_L3_DBG_0]);
372
373 nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG1_OFFSET);
374 nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_STATS_PPE_L3_DBG_1]);
375
376 nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG2_OFFSET);
377 nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_STATS_PPE_L3_DBG_2]);
378
379 nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG3_OFFSET);
380 nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_STATS_PPE_L3_DBG_3]);
381
382 nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG4_OFFSET);
383 nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_STATS_PPE_L3_DBG_4]);
384
385 nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG_PORT_OFFSET);
386 nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_STATS_PPE_L3_DBG_PORT]);
387
388 spin_unlock_bh(&nss_ppe_stats_lock);
389}
390
391/*
392 * nss_ppe_stats_code_get()
393 * Get ppe CPU and DROP code for last packet processed.
394 */
395void nss_ppe_stats_code_get(uint32_t *stats)
396{
397 uint32_t drop_0, drop_1, cpu_code;
398
399 nss_trace("%s(%d) Start\n", __func__, __LINE__);
400 if (!stats) {
401 nss_warning("No memory to copy ppe code\n");
402 return;
403 }
404
405 if (!nss_ppe_debug_stats.valid) {
406 nss_warning("PPE base address not initialized!\n");
407 return;
408 }
409
410 spin_lock_bh(&nss_ppe_stats_lock);
411 nss_ppe_reg_write(PPE_PKT_CODE_WR_OFFSET, PPE_PKT_CODE_DROP0_OFFSET);
412 nss_ppe_reg_read(PPE_PKT_CODE_RD_OFFSET, &drop_0);
413
414 nss_ppe_reg_write(PPE_PKT_CODE_WR_OFFSET, PPE_PKT_CODE_DROP1_OFFSET);
415 nss_ppe_reg_read(PPE_PKT_CODE_RD_OFFSET, &drop_1);
416
417 stats[NSS_STATS_PPE_CODE_DROP] = PPE_PKT_CODE_DROP_GET(drop_0, drop_1);
418
419 nss_ppe_reg_write(PPE_PKT_CODE_WR_OFFSET, PPE_PKT_CODE_CPU_OFFSET);
420 nss_ppe_reg_read(PPE_PKT_CODE_RD_OFFSET, &cpu_code);
421
422 stats[NSS_STATS_PPE_CODE_CPU] = PPE_PKT_CODE_CPU_GET(cpu_code);
423
424 spin_unlock_bh(&nss_ppe_stats_lock);
425}
426
427/*
Amit Gupta79c1c202017-06-30 15:28:13 +0530428 * nss_ppe_port_drop_code_get()
429 * Get ppe per port drop code.
430 */
431void nss_ppe_port_drop_code_get(uint32_t *stats, uint8_t port_id)
432{
433 uint8_t i;
434 nss_trace("%s(%d) Start\n", __func__, __LINE__);
435 if (!stats) {
436 nss_warning("No memory to copy ppe code\n");
437 return;
438 }
439
440 if (port_id > NSS_PPE_NUM_PHY_PORTS_MAX) {
441 nss_warning("Port id is out of range\n");
442 return;
443 }
444
445 if (!nss_ppe_debug_stats.valid) {
446 nss_warning("PPE base address not initialized!\n");
447 return;
448 }
449
450 spin_lock_bh(&nss_ppe_stats_lock);
451
452 for (i = 0; i < NSS_STATS_PPE_DROP_CODE_MAX; i++) {
453 nss_ppe_reg_read(PPE_DROP_CODE_OFFSET(i, port_id), &stats[i]);
454 }
455
456 spin_unlock_bh(&nss_ppe_stats_lock);
457}
458
459/*
460 * nss_ppe_cpu_code_exception_get()
461 * Get ppe cpu code specific for flow exceptions.
462 */
463void nss_ppe_cpu_code_exception_get(uint32_t *stats)
464{
465 uint8_t i;
466 nss_trace("%s(%d) Start\n", __func__, __LINE__);
467 if (!stats) {
468 nss_warning("No memory to copy ppe code\n");
469 return;
470 }
471
472 if (!nss_ppe_debug_stats.valid) {
473 nss_warning("PPE base address not initialized!\n");
474 return;
475 }
476
477 spin_lock_bh(&nss_ppe_stats_lock);
478
479 for (i = 0; i < NSS_STATS_PPE_CPU_CODE_EXCEPTION_MAX ; i++) {
480 nss_ppe_reg_read(PPE_CPU_CODE_OFFSET(i), &stats[i]);
481 }
482
483 spin_unlock_bh(&nss_ppe_stats_lock);
484}
485
486/*
487 * nss_ppe_cpu_code_nonexception_get()
488 * Get ppe cpu code specific for flow exceptions.
489 */
490void nss_ppe_cpu_code_nonexception_get(uint32_t *stats)
491{
492 uint8_t i;
493 nss_trace("%s(%d) Start\n", __func__, __LINE__);
494 if (!stats) {
495 nss_warning("No memory to copy ppe code\n");
496 return;
497 }
498
499 if (!nss_ppe_debug_stats.valid) {
500 nss_warning("PPE base address not initialized!\n");
501 return;
502 }
503
504 spin_lock_bh(&nss_ppe_stats_lock);
505
506 for (i = 0; i < NSS_STATS_PPE_CPU_CODE_NONEXCEPTION_MAX; i++) {
507 nss_ppe_reg_read(PPE_CPU_CODE_OFFSET(ppe_cc_nonexception[i]), &stats[i]);
508 }
509
510 spin_unlock_bh(&nss_ppe_stats_lock);
511}
512
513/*
Amit Gupta316729b2016-08-12 12:21:15 +0530514 * nss_ppe_handler()
Amit Gupta1263b082017-07-06 14:22:57 +0530515 * Handle NSS -> HLOS messages for ppe
Amit Gupta316729b2016-08-12 12:21:15 +0530516 */
517static void nss_ppe_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data)
518{
519 struct nss_ppe_msg *msg = (struct nss_ppe_msg *)ncm;
Amit Gupta1263b082017-07-06 14:22:57 +0530520 void *ctx;
Amit Gupta316729b2016-08-12 12:21:15 +0530521
Amit Gupta1263b082017-07-06 14:22:57 +0530522 nss_ppe_msg_callback_t cb;
523
524 nss_trace("nss_ctx: %p ppe msg: %p\n", nss_ctx, msg);
Amit Gupta316729b2016-08-12 12:21:15 +0530525 BUG_ON(!nss_ppe_verify_ifnum(ncm->interface));
526
527 /*
528 * Is this a valid request/response packet?
529 */
530 if (ncm->type >= NSS_PPE_MSG_MAX) {
Amit Gupta1263b082017-07-06 14:22:57 +0530531 nss_warning("%p: received invalid message %d for PPE interface\n", nss_ctx, ncm->type);
Amit Gupta316729b2016-08-12 12:21:15 +0530532 return;
533 }
534
535 if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ppe_msg)) {
Amit Gupta1263b082017-07-06 14:22:57 +0530536 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 +0530537 return;
538 }
539
540 switch (msg->cm.type) {
541 case NSS_PPE_MSG_SYNC_STATS:
542 /*
543 * session debug stats embeded in session stats msg
544 */
545 nss_ppe_stats_sync(nss_ctx, &msg->msg.stats, ncm->interface);
Amit Gupta1263b082017-07-06 14:22:57 +0530546 return;
Amit Gupta316729b2016-08-12 12:21:15 +0530547 }
Amit Gupta316729b2016-08-12 12:21:15 +0530548
Amit Gupta1263b082017-07-06 14:22:57 +0530549 /*
550 * Log failures
551 */
552 nss_core_log_msg_failures(nss_ctx, ncm);
553
554 /*
555 * Do we have a call back
556 */
557 if (!ncm->cb) {
558 return;
559 }
560
561 /*
562 * callback
563 */
564 cb = (nss_ppe_msg_callback_t)ncm->cb;
565 ctx = (void *)ncm->app_data;
566
567 cb(ctx, msg);
Thomas Wu91f4bdf2017-06-09 12:03:02 -0700568}
Thomas Wu91f4bdf2017-06-09 12:03:02 -0700569
570/*
Amit Gupta316729b2016-08-12 12:21:15 +0530571 * nss_ppe_register_handler()
572 * debugfs stats msg handler received on static ppe interface
573 *
574 * TODO: Export API so that others can also read PPE stats.
575 */
576void nss_ppe_register_handler(void)
577{
Thomas Wu91f4bdf2017-06-09 12:03:02 -0700578 struct nss_ctx_instance *nss_ctx = nss_ppe_get_context();
579
580 nss_core_register_handler(nss_ctx, NSS_PPE_INTERFACE, nss_ppe_handler, NULL);
Amit Gupta316729b2016-08-12 12:21:15 +0530581}
582
583/*
584 * nss_ppe_free()
585 * Uninitialize PPE base
586 */
587void nss_ppe_free(void)
588{
589 /*
590 * Check if PPE base is already uninitialized.
591 */
592 if (!ppe_pvt.ppe_base) {
593 return;
594 }
595
596 /*
597 * Unmap PPE base address
598 */
599 iounmap(ppe_pvt.ppe_base);
600 ppe_pvt.ppe_base = NULL;
601
602 spin_lock_bh(&nss_ppe_stats_lock);
603 nss_ppe_debug_stats.valid = false;
604 nss_ppe_debug_stats.if_num = 0;
605 nss_ppe_debug_stats.if_index = 0;
606 spin_unlock_bh(&nss_ppe_stats_lock);
607}
608
609/*
610 * nss_ppe_init()
611 * Initialize PPE base
612 */
613void nss_ppe_init(void)
614{
615 /*
616 * Check if PPE base is already initialized.
617 */
618 if (ppe_pvt.ppe_base) {
619 return;
620 }
621
622 /*
623 * Get the PPE base address
624 */
625 ppe_pvt.ppe_base = ioremap_nocache(PPE_BASE_ADDR, PPE_REG_SIZE);
626 if (!ppe_pvt.ppe_base) {
627 nss_warning("DRV can't get PPE base address\n");
628 return;
629 }
630
631 spin_lock_bh(&nss_ppe_stats_lock);
632 nss_ppe_debug_stats.valid = true;
633 nss_ppe_debug_stats.if_num = 0;
634 nss_ppe_debug_stats.if_index = 0;
635 spin_unlock_bh(&nss_ppe_stats_lock);
Amit Gupta1263b082017-07-06 14:22:57 +0530636
637 sema_init(&ppe_pvt.sem, 1);
638 init_completion(&ppe_pvt.complete);
Amit Gupta316729b2016-08-12 12:21:15 +0530639}