1 /*
2  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /**
18  *  DOC: wlan_mgmt_txrx_rx_re_tgt_api.c
19  *  This file contains mgmt rx re-ordering tgt layer related function
20  *  definitions
21  */
22 #include <wlan_mgmt_txrx_rx_reo_tgt_api.h>
23 #include "../../core/src/wlan_mgmt_txrx_rx_reo_i.h"
24 
25 QDF_STATUS
26 tgt_mgmt_rx_reo_read_snapshot(
27 			struct wlan_objmgr_pdev *pdev,
28 			struct mgmt_rx_reo_snapshot *address,
29 			enum mgmt_rx_reo_shared_snapshot_id id,
30 			struct mgmt_rx_reo_snapshot_params *value)
31 {
32 	struct wlan_lmac_if_mgmt_rx_reo_tx_ops *mgmt_rx_reo_txops;
33 
34 	mgmt_rx_reo_txops = wlan_pdev_get_mgmt_rx_reo_txops(pdev);
35 	if (!mgmt_rx_reo_txops) {
36 		mgmt_rx_reo_err("mgmt rx reo txops is NULL");
37 		return QDF_STATUS_E_INVAL;
38 	}
39 
40 	if (!mgmt_rx_reo_txops->read_mgmt_rx_reo_snapshot) {
41 		mgmt_rx_reo_err("mgmt rx reo read snapshot txops is NULL");
42 		return QDF_STATUS_E_NULL_VALUE;
43 	}
44 
45 	return mgmt_rx_reo_txops->read_mgmt_rx_reo_snapshot(pdev, address, id,
46 							    value);
47 }
48 
49 /**
50  * tgt_mgmt_rx_reo_enter_algo_without_buffer() - Entry point to the MGMT Rx REO
51  * algorithm when there is no frame buffer
52  * @pdev: pdev for which this frame/event is intended
53  * @reo_params: MGMT Rx REO parameters corresponding to this frame/event
54  * @type: Type of the MGMT Rx REO frame/event descriptor
55  *
56  * Return: QDF_STATUS of operation
57  */
58 static QDF_STATUS
59 tgt_mgmt_rx_reo_enter_algo_without_buffer(
60 				struct wlan_objmgr_pdev *pdev,
61 				struct mgmt_rx_reo_params *reo_params,
62 				enum mgmt_rx_reo_frame_descriptor_type type)
63 {
64 	struct mgmt_rx_event_params mgmt_rx_params;
65 	struct mgmt_rx_reo_frame_descriptor desc;
66 	bool is_frm_queued;
67 	QDF_STATUS status;
68 
69 	if (!pdev) {
70 		mgmt_rx_reo_err("pdev is null");
71 		return QDF_STATUS_E_NULL_VALUE;
72 	}
73 
74 	if (!reo_params) {
75 		mgmt_rx_reo_err("mgmt rx reo params are null");
76 		return QDF_STATUS_E_NULL_VALUE;
77 	}
78 
79 	mgmt_rx_params.reo_params = reo_params;
80 
81 	desc.nbuf = NULL; /* No frame buffer */
82 	desc.rx_params = &mgmt_rx_params;
83 	desc.type = type;
84 
85 	/** If REO is not required for this descriptor,
86 	 *  no need to proceed further
87 	 */
88 	if (!is_mgmt_rx_reo_required(pdev, &desc))
89 		return  QDF_STATUS_SUCCESS;
90 
91 	/* Enter the REO algorithm */
92 	status = wlan_mgmt_rx_reo_algo_entry(pdev, &desc, &is_frm_queued);
93 
94 	qdf_assert_always(!is_frm_queued);
95 
96 	return status;
97 }
98 
99 QDF_STATUS
100 tgt_mgmt_rx_reo_fw_consumed_event_handler(struct wlan_objmgr_pdev *pdev,
101 					  struct mgmt_rx_reo_params *params)
102 {
103 	return tgt_mgmt_rx_reo_enter_algo_without_buffer(
104 			pdev, params, MGMT_RX_REO_FRAME_DESC_FW_CONSUMED_FRAME);
105 }
106 
107 QDF_STATUS
108 tgt_mgmt_rx_reo_host_drop_handler(struct wlan_objmgr_pdev *pdev,
109 				  struct mgmt_rx_reo_params *params)
110 {
111 	return tgt_mgmt_rx_reo_enter_algo_without_buffer(
112 			pdev, params, MGMT_RX_REO_FRAME_DESC_ERROR_FRAME);
113 }
114 
115 QDF_STATUS tgt_mgmt_rx_reo_filter_config(struct wlan_objmgr_pdev *pdev,
116 					 struct mgmt_rx_reo_filter *filter)
117 {
118 	struct wlan_lmac_if_mgmt_rx_reo_tx_ops *mgmt_rx_reo_txops;
119 
120 	mgmt_rx_reo_txops = wlan_pdev_get_mgmt_rx_reo_txops(pdev);
121 	if (!mgmt_rx_reo_txops) {
122 		mgmt_rx_reo_err("MGMT Rx REO txops is NULL");
123 		return QDF_STATUS_E_NULL_VALUE;
124 	}
125 
126 	if (!mgmt_rx_reo_txops->mgmt_rx_reo_filter_config) {
127 		mgmt_rx_reo_err("mgmt_rx_reo_filter_config is NULL");
128 		return QDF_STATUS_E_NULL_VALUE;
129 	}
130 
131 	return mgmt_rx_reo_txops->mgmt_rx_reo_filter_config(pdev, filter);
132 }
133 
134 QDF_STATUS
135 tgt_mgmt_rx_reo_get_snapshot_address(
136 			struct wlan_objmgr_pdev *pdev,
137 			enum mgmt_rx_reo_shared_snapshot_id id,
138 			struct mgmt_rx_reo_snapshot **address)
139 {
140 	struct wlan_lmac_if_mgmt_rx_reo_tx_ops *mgmt_rx_reo_txops;
141 
142 	mgmt_rx_reo_txops = wlan_pdev_get_mgmt_rx_reo_txops(pdev);
143 	if (!mgmt_rx_reo_txops) {
144 		mgmt_rx_reo_err("mgmt rx reo txops is NULL");
145 		return QDF_STATUS_E_NULL_VALUE;
146 	}
147 
148 	if (!mgmt_rx_reo_txops->get_mgmt_rx_reo_snapshot_address) {
149 		mgmt_rx_reo_err("txops entry for get snapshot address is null");
150 		return QDF_STATUS_E_NULL_VALUE;
151 	}
152 
153 	return mgmt_rx_reo_txops->get_mgmt_rx_reo_snapshot_address(pdev, id,
154 								   address);
155 }
156 
157 QDF_STATUS tgt_mgmt_rx_reo_frame_handler(
158 				struct wlan_objmgr_pdev *pdev,
159 				qdf_nbuf_t buf,
160 				struct mgmt_rx_event_params *mgmt_rx_params)
161 {
162 	QDF_STATUS status;
163 	struct mgmt_rx_reo_frame_descriptor desc;
164 	bool is_queued;
165 
166 	if (!pdev) {
167 		mgmt_rx_reo_err("pdev is NULL");
168 		status = QDF_STATUS_E_NULL_VALUE;
169 		goto cleanup;
170 	}
171 
172 	if (!buf) {
173 		mgmt_rx_reo_err("nbuf is NULL");
174 		status = QDF_STATUS_E_NULL_VALUE;
175 		goto cleanup;
176 	}
177 
178 	if (!mgmt_rx_params) {
179 		mgmt_rx_reo_err("MGMT rx params is NULL");
180 		status = QDF_STATUS_E_NULL_VALUE;
181 		goto cleanup;
182 	}
183 
184 	/* Populate frame descriptor */
185 	desc.type = MGMT_RX_REO_FRAME_DESC_HOST_CONSUMED_FRAME;
186 	desc.nbuf = buf;
187 	desc.rx_params = mgmt_rx_params;
188 
189 	/* If REO is not required for this frame, process it right away */
190 	if (!is_mgmt_rx_reo_required(pdev, &desc)) {
191 		return tgt_mgmt_txrx_process_rx_frame(pdev, buf,
192 						      mgmt_rx_params);
193 	}
194 
195 	status = wlan_mgmt_rx_reo_algo_entry(pdev, &desc, &is_queued);
196 
197 	/* If frame is queued, we shouldn't free up params and buf pointers */
198 	if (is_queued)
199 		return status;
200 cleanup:
201 	qdf_nbuf_free(buf);
202 	free_mgmt_rx_event_params(mgmt_rx_params);
203 
204 	return status;
205 }
206