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 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 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 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 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 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