blob: 1e4d94f233a5ed307bccbad34836e9028fd12057 [file] [log] [blame]
Sol Kavya55c9a52014-04-08 14:33:16 -07001/*
2 **************************************************************************
Suruchi Agarwalef8a8702016-01-08 12:40:08 -08003 * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
Sol Kavya55c9a52014-04-08 14:33:16 -07004 * 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_if.c
19 * NSS base interfaces
20 */
21
22#include "nss_tx_rx_common.h"
Sol Kavya55c9a52014-04-08 14:33:16 -070023
24/*
25 * nss_if_msg_handler()
26 * Handle NSS -> HLOS messages for base class interfaces
27 */
28void nss_if_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm,
29 __attribute__((unused))void *app_data)
30{
31 struct nss_if_msg *nim = (struct nss_if_msg *)ncm;
32 nss_if_msg_callback_t cb;
33
34 /*
35 * We only support base class messages with this interface
36 */
37 if (ncm->type > NSS_IF_MAX_MSG_TYPES) {
38 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
39 return;
40 }
41
Sundarajan Srinivasancd1631b2015-06-18 01:23:30 -070042 if (!nss_is_dynamic_interface(ncm->interface) &&
43 !((ncm->interface >= NSS_PHYSICAL_IF_START) && (ncm->interface < NSS_VIRTUAL_IF_START))) {
44 nss_warning("%p: interface %d not in physical or dynamic if range\n", nss_ctx, ncm->interface);
Sol Kavya55c9a52014-04-08 14:33:16 -070045 return;
46 }
47
Suruchi Agarwalef8a8702016-01-08 12:40:08 -080048 if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_if_msg)) {
49 nss_warning("%p: message length too big: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
Sol Kavya55c9a52014-04-08 14:33:16 -070050 return;
51 }
52
53 /*
54 * Log failures
55 */
56 nss_core_log_msg_failures(nss_ctx, ncm);
57
58 /*
59 * Do we have a callback?
60 */
61 if (!ncm->cb) {
62 return;
63 }
64
65 /*
66 * Callback
67 */
68 cb = (nss_if_msg_callback_t)ncm->cb;
69 cb((void *)ncm->app_data, nim);
70}
71
72/*
73 * nss_if_tx_buf()
74 * Send packet to interface owned by NSS
75 */
76nss_tx_status_t nss_if_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num)
77{
78 int32_t status;
79
80 nss_trace("%p: If Tx packet, id:%d, data=%p", nss_ctx, if_num, os_buf->data);
81
82 NSS_VERIFY_CTX_MAGIC(nss_ctx);
83 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
84 nss_warning("%p: 'Phys If Tx' packet dropped as core not ready", nss_ctx);
85 return NSS_TX_FAILURE_NOT_READY;
86 }
87
Sundarajan Srinivasancd1631b2015-06-18 01:23:30 -070088 if (!nss_is_dynamic_interface(if_num) &&
89 !((if_num >= NSS_PHYSICAL_IF_START) && (if_num < NSS_VIRTUAL_IF_START))) {
90 nss_warning("%p: interface %d not in physical or dynamic if range\n", nss_ctx, if_num);
91 return NSS_TX_FAILURE_BAD_PARAM;
92 }
93
Pamidipati, Vijayefcc4692014-05-09 14:47:38 +053094 status = nss_core_send_buffer(nss_ctx, if_num, os_buf, NSS_IF_DATA_QUEUE_0, H2N_BUFFER_PACKET, 0);
Sol Kavya55c9a52014-04-08 14:33:16 -070095 if (unlikely(status != NSS_CORE_STATUS_SUCCESS)) {
96 nss_warning("%p: Unable to enqueue 'Phys If Tx' packet\n", nss_ctx);
97 if (status == NSS_CORE_STATUS_FAILURE_QUEUE) {
98 return NSS_TX_FAILURE_QUEUE;
99 }
100 return NSS_TX_FAILURE;
101 }
102
103 /*
104 * Kick the NSS awake so it can process our new entry.
105 */
Stephen Wang90c67de2016-04-26 15:15:59 -0700106 nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
Sol Kavya55c9a52014-04-08 14:33:16 -0700107 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_PACKET]);
108 return NSS_TX_SUCCESS;
109}
110
111/*
112 * nss_if_tx_msg()
113 * Transmit a message to the specific interface on this core.
114 */
115nss_tx_status_t nss_if_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_if_msg *nim)
116{
117 struct nss_cmn_msg *ncm = &nim->cm;
118 struct nss_if_msg *nim2;
119 struct net_device *dev;
120 struct sk_buff *nbuf;
121 uint32_t if_num;
122 int32_t status;
123
124 if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
125 nss_warning("Interface could not be created as core not ready");
126 return NSS_TX_FAILURE;
127 }
128
129 /*
130 * Sanity check the message
131 */
Sol Kavya55c9a52014-04-08 14:33:16 -0700132
133 if (ncm->type > NSS_IF_MAX_MSG_TYPES) {
134 nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
135 return NSS_TX_FAILURE;
136 }
137
Suruchi Agarwalef8a8702016-01-08 12:40:08 -0800138 if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_if_msg)) {
139 nss_warning("%p: invalid length: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
Sol Kavya55c9a52014-04-08 14:33:16 -0700140 return NSS_TX_FAILURE;
141 }
142
143 if_num = ncm->interface;
Stephen Wang84e0e992016-09-07 12:31:40 -0700144 dev = nss_ctx->subsys_dp_register[if_num].ndev;
Sol Kavya55c9a52014-04-08 14:33:16 -0700145 if (!dev) {
146 nss_warning("%p: Unregister interface %d: no context", nss_ctx, if_num);
147 return NSS_TX_FAILURE_BAD_PARAM;
148 }
149
Pamidipati, Vijayb6e38842014-09-16 10:26:05 +0530150 nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
Sol Kavya55c9a52014-04-08 14:33:16 -0700151 if (unlikely(!nbuf)) {
Sundarajan Srinivasan62fee7e2015-01-22 11:13:10 -0800152 NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]);
Sol Kavya55c9a52014-04-08 14:33:16 -0700153 nss_warning("%p: interface %p: command allocation failed", nss_ctx, dev);
154 return NSS_TX_FAILURE;
155 }
156
157 nim2 = (struct nss_if_msg *)skb_put(nbuf, sizeof(struct nss_if_msg));
158 memcpy(nim2, nim, sizeof(struct nss_if_msg));
159
160 status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
161 if (status != NSS_CORE_STATUS_SUCCESS) {
Pamidipati, Vijayb6e38842014-09-16 10:26:05 +0530162 dev_kfree_skb_any(nbuf);
Sol Kavya55c9a52014-04-08 14:33:16 -0700163 nss_warning("%p: Unable to enqueue 'interface' command\n", nss_ctx);
164 return NSS_TX_FAILURE;
165 }
166
Stephen Wang90c67de2016-04-26 15:15:59 -0700167 nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
Sol Kavya55c9a52014-04-08 14:33:16 -0700168 return NSS_TX_SUCCESS;
169}
170
171/*
172 * nss_if_register()
173 * Primary registration for receiving data and msgs from an interface.
174 */
175struct nss_ctx_instance *nss_if_register(uint32_t if_num,
Sakthi Vignesh Radhakrishnanef918492014-04-07 14:24:19 -0700176 nss_if_rx_callback_t rx_callback,
177 nss_if_msg_callback_t msg_callback,
Sol Kavya55c9a52014-04-08 14:33:16 -0700178 struct net_device *if_ctx)
179{
180 return NULL;
181}
182
183/*
184 * nss_if_unregister()
185 * Unregisteer the callback for this interface
186 */
187void nss_if_unregister(uint32_t if_num)
188{
189}
190
191EXPORT_SYMBOL(nss_if_tx_msg);
192EXPORT_SYMBOL(nss_if_register);
193EXPORT_SYMBOL(nss_if_unregister);