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