blob: 26f5906dcef11b91b90fa546e00e0b36910ba3e8 [file] [log] [blame]
Sivanesan Rajapupathi5c31b212016-01-06 16:21:57 -05001/*
2 **************************************************************************
Stephen Wangaed46332016-12-12 17:29:03 -08003 * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
Sivanesan Rajapupathi5c31b212016-01-06 16:21:57 -05004 * 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_oam.c
19 * OAM - Operations, Administration and Maintenance Service for NSS
20 *
21 * This adapter module is responsible for sending and
22 * receiving to and from NSS FW
23 * This file contains the API for communicating NSS FW to send/receive
24 * commands OAM commands.
25 */
26
27#include "nss_tx_rx_common.h"
28
29/*
30 * nss_oam_rx_msg_handler()
31 * Message handler for OAM messages from NSS
32 */
33static void nss_oam_rx_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused)) void *app_data)
34{
35 struct nss_oam_msg *nom = (struct nss_oam_msg *)ncm;
36 nss_oam_msg_callback_t cb;
37
38 /*
39 * Sanity check the message type
40 */
Suruchi Agarwalef8a8702016-01-08 12:40:08 -080041 if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_oam_msg)) {
42 nss_warning("%p: recevied with invalid msg size: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
Sivanesan Rajapupathi5c31b212016-01-06 16:21:57 -050043 return;
44 }
45
46 if (ncm->type > NSS_OAM_MSG_TYPE_MAX) {
47 nss_warning("%p: received with invalid resp type: %d", nss_ctx, ncm->type);
48 return;
49 }
50
51 /*
52 * Log the failures
53 */
54 nss_core_log_msg_failures(nss_ctx, ncm);
55
56 if (ncm->response == NSS_CMM_RESPONSE_NOTIFY) {
Stephen Wangaed46332016-12-12 17:29:03 -080057 ncm->cb = (nss_ptr_t)nss_top_main.oam_callback;
58 ncm->app_data = (nss_ptr_t)nss_top_main.oam_ctx;
Sivanesan Rajapupathi5c31b212016-01-06 16:21:57 -050059 }
60
61 cb = (nss_oam_msg_callback_t)ncm->cb;
62 if (unlikely(!cb)) {
63 nss_trace("%p: rx handler has been unregistered for i/f: %d", nss_ctx, ncm->interface);
64 return;
65 }
66 cb((void *)ncm->app_data, nom);
67}
68
69/*
70 * nss_oam_tx()
71 * Transmit an oam message to the FW.
72 */
73nss_tx_status_t nss_oam_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_oam_msg *nom)
74{
75 const uint32_t msg_sz = sizeof(struct nss_oam_msg);
76 struct nss_cmn_msg *ncm = &nom->cm;
77 struct sk_buff *nbuf;
78 int32_t status;
79
80 NSS_VERIFY_CTX_MAGIC(nss_ctx);
81 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
82 nss_warning("%p: oam msg dropped as core not ready", nss_ctx);
83 return NSS_TX_FAILURE_NOT_READY;
84 }
85
86 if (ncm->type > NSS_OAM_MSG_TYPE_MAX) {
87 nss_warning("%p: CMD type for oam module is invalid - %d", nss_ctx, ncm->type);
88 return NSS_TX_FAILURE_BAD_PARAM;
89 }
90
91 if (ncm->interface != NSS_OAM_INTERFACE) {
92 nss_warning("%p: tx message request for another interface: %d", nss_ctx, ncm->interface);
93 return NSS_TX_FAILURE;
94 }
95
Suruchi Agarwalef8a8702016-01-08 12:40:08 -080096 if (nss_cmn_get_msg_len(ncm) > msg_sz) {
97 nss_warning("%p: tx request with invalid size: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
Sivanesan Rajapupathi5c31b212016-01-06 16:21:57 -050098 return NSS_TX_FAILURE_TOO_SHORT;
99 }
100
101 /*
102 * Check whether msg_sz exceeds max payload size
103 */
104 BUG_ON(msg_sz > NSS_NBUF_PAYLOAD_SIZE);
105
106 nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
107 if (unlikely(!nbuf)) {
108 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]);
109 nss_warning("%p: msg dropped as command allocation failed", nss_ctx);
110 return NSS_TX_FAILURE;
111 }
112
113 /*
114 * Copy the message to our skb.
115 */
116 memcpy(skb_put(nbuf, msg_sz), nom, msg_sz);
117
118 status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
119 if (status != NSS_CORE_STATUS_SUCCESS) {
120 dev_kfree_skb_any(nbuf);
121 nss_warning("%p: unable to enqueue OAM msg\n", nss_ctx);
122 return NSS_TX_FAILURE;
123 }
124
Stephen Wang90c67de2016-04-26 15:15:59 -0700125 nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
Sivanesan Rajapupathi5c31b212016-01-06 16:21:57 -0500126 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
127 return NSS_TX_SUCCESS;
128}
129EXPORT_SYMBOL(nss_oam_tx_msg);
130
131/*
132 * nss_oam_notify_register()
133 * Register to receive OAM events.
134 */
135struct nss_ctx_instance *nss_oam_notify_register(nss_oam_msg_callback_t cb, void *app_data)
136{
137 if (nss_top_main.oam_ctx || nss_top_main.oam_callback) {
138 nss_warning("Failed to register notify callback - already registered\n");
139 return NULL;
140 }
141
142 nss_top_main.oam_ctx = app_data;
143 nss_top_main.oam_callback = cb;
144 return &nss_top_main.nss[nss_top_main.oam_handler_id];
145}
146EXPORT_SYMBOL(nss_oam_notify_register);
147
148/*
149 * nss_oam_notify_unregister()
150 * Unregister to received OAM events.
151 */
152void nss_oam_notify_unregister(void)
153{
154 nss_top_main.oam_callback = NULL;
155 nss_top_main.oam_ctx = NULL;
156}
157EXPORT_SYMBOL(nss_oam_notify_unregister);
158
159/*
160 * nss_register_oam_handler()
161 * Register our handler to receive messages for this interface
162 */
163void nss_oam_register_handler(void)
164{
Thomas Wu91f4bdf2017-06-09 12:03:02 -0700165 struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[nss_top_main.oam_handler_id];
166
167 if (nss_core_register_handler(nss_ctx, NSS_OAM_INTERFACE, nss_oam_rx_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) {
Sivanesan Rajapupathi5c31b212016-01-06 16:21:57 -0500168 nss_warning("OAM handler failed to register");
169 }
170}