1 /*
2  * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
3  *
4  * 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
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: target_if_psoc_timer_tx_ops.c
21  *
22  * This file provide definition for APIs registered through lmac Tx Ops
23  */
24 
25 #include <wlan_objmgr_psoc_obj.h>
26 #include <wlan_mlme_dbg.h>
27 #include <target_if_psoc_timer_tx_ops.h>
28 #include <wlan_vdev_mgr_tgt_if_rx_defs.h>
29 #include <target_if_vdev_mgr_tx_ops.h>
30 #include <target_if_vdev_mgr_rx_ops.h>
31 
target_if_psoc_vdev_rsp_timer_inuse(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)32 QDF_STATUS target_if_psoc_vdev_rsp_timer_inuse(struct wlan_objmgr_psoc *psoc,
33 					       uint8_t vdev_id)
34 {
35 	struct vdev_response_timer *vdev_rsp;
36 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
37 
38 	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
39 		mlme_err("Invalid vdev id passed VDEV_%d", vdev_id);
40 		return QDF_STATUS_E_INVAL;
41 	}
42 
43 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
44 	if (!(rx_ops && rx_ops->psoc_get_vdev_response_timer_info)) {
45 		mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id,
46 			 wlan_psoc_get_id(psoc));
47 		return QDF_STATUS_E_INVAL;
48 	}
49 
50 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
51 	if (!vdev_rsp) {
52 		mlme_err("vdev response is NULL for VDEV_%d PSOC_%d",
53 			 vdev_id, wlan_psoc_get_id(psoc));
54 		return QDF_STATUS_E_INVAL;
55 	}
56 
57 	if (qdf_atomic_read(&vdev_rsp->rsp_timer_inuse)) {
58 		mlme_err("vdev response timer still inuse VDEV_%d PSOC_%d",
59 			 vdev_id, wlan_psoc_get_id(psoc));
60 		return QDF_STATUS_E_ALREADY;
61 	}
62 
63 	return QDF_STATUS_SUCCESS;
64 }
65 
target_if_psoc_vdev_rsp_timer_init(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)66 QDF_STATUS target_if_psoc_vdev_rsp_timer_init(struct wlan_objmgr_psoc *psoc,
67 					      uint8_t vdev_id)
68 {
69 	struct vdev_response_timer *vdev_rsp;
70 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
71 
72 	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
73 		mlme_err("Invalid vdev id passed VDEV_%d PSOC_%d", vdev_id,
74 			 wlan_psoc_get_id(psoc));
75 		return QDF_STATUS_E_INVAL;
76 	}
77 
78 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
79 	if (!(rx_ops && rx_ops->psoc_get_vdev_response_timer_info)) {
80 		mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id,
81 			 wlan_psoc_get_id(psoc));
82 		return QDF_STATUS_E_INVAL;
83 	}
84 
85 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
86 	if (!vdev_rsp) {
87 		mlme_err("vdev response is NULL for VDEV_%d PSOC_%d",
88 			 vdev_id, wlan_psoc_get_id(psoc));
89 		return QDF_STATUS_E_INVAL;
90 	}
91 
92 	vdev_rsp->psoc = psoc;
93 	vdev_rsp->vdev_id = vdev_id;
94 	qdf_timer_init(NULL, &vdev_rsp->rsp_timer,
95 		       target_if_vdev_mgr_rsp_timer_mgmt_cb,
96 		       vdev_rsp, QDF_TIMER_TYPE_WAKE_APPS);
97 	qdf_atomic_init(&vdev_rsp->rsp_timer_inuse);
98 	qdf_atomic_inc(&vdev_rsp->rsp_timer_inuse);
99 
100 	return QDF_STATUS_SUCCESS;
101 }
102 
target_if_psoc_vdev_rsp_timer_deinit(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)103 void target_if_psoc_vdev_rsp_timer_deinit(struct wlan_objmgr_psoc *psoc,
104 					  uint8_t vdev_id)
105 {
106 	struct vdev_response_timer *vdev_rsp;
107 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
108 
109 	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
110 		mlme_err("Invalid vdev id passed VDEV_%d PSOC_%d", vdev_id,
111 			 wlan_psoc_get_id(psoc));
112 		return;
113 	}
114 
115 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
116 	if (!(rx_ops && rx_ops->psoc_get_vdev_response_timer_info)) {
117 		mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id,
118 			 wlan_psoc_get_id(psoc));
119 		return;
120 	}
121 
122 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
123 	if (!vdev_rsp) {
124 		mlme_err("vdev response is NULL for VDEV_%d PSOC_%d",
125 			 vdev_id, wlan_psoc_get_id(psoc));
126 		return;
127 	}
128 
129 	qdf_timer_free(&vdev_rsp->rsp_timer);
130 	qdf_atomic_set(&vdev_rsp->rsp_timer_inuse, 0);
131 	vdev_rsp->psoc = NULL;
132 }
133 
target_if_flush_psoc_vdev_timers(struct wlan_objmgr_psoc * psoc)134 void target_if_flush_psoc_vdev_timers(struct wlan_objmgr_psoc *psoc)
135 {
136 	struct vdev_response_timer *vdev_rsp;
137 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
138 	int i;
139 
140 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
141 	if (!(rx_ops && rx_ops->psoc_get_vdev_response_timer_info)) {
142 		mlme_err("PSOC_%d No Rx Ops", wlan_psoc_get_id(psoc));
143 		return;
144 	}
145 
146 	for (i = 0; i < WLAN_UMAC_PSOC_MAX_VDEVS; i++) {
147 		vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc,
148 								     i);
149 		if (vdev_rsp && qdf_atomic_read(&vdev_rsp->rsp_timer_inuse) &&
150 		    qdf_timer_sync_cancel(&vdev_rsp->rsp_timer))
151 			target_if_vdev_mgr_rsp_timer_cb(vdev_rsp);
152 	}
153 }
154 
target_if_vdev_mgr_rsp_timer_mod(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,int mseconds)155 QDF_STATUS target_if_vdev_mgr_rsp_timer_mod(
156 					struct wlan_objmgr_psoc *psoc,
157 					uint8_t vdev_id,
158 					int mseconds)
159 {
160 	struct wlan_lmac_if_mlme_rx_ops *rx_ops;
161 	struct vdev_response_timer *vdev_rsp;
162 
163 	if (!psoc) {
164 		mlme_err("Invalid input");
165 		return QDF_STATUS_E_FAILURE;
166 	}
167 
168 	rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
169 	if (!(rx_ops && rx_ops->psoc_get_vdev_response_timer_info)) {
170 		mlme_err("VDEV_%d PSOC_%d No Rx Ops", vdev_id,
171 			 wlan_psoc_get_id(psoc));
172 		return QDF_STATUS_E_FAILURE;
173 	}
174 
175 	vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
176 	qdf_timer_mod(&vdev_rsp->rsp_timer, mseconds);
177 	return QDF_STATUS_SUCCESS;
178 }
179 
180