1 /* 2 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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_afc_main.c 19 * This file provides implementation for UMAC AFC common APIs. 20 */ 21 22 #include <wlan_afc_main.h> 23 #include "wlan_afc_priv.h" 24 #include "wlan_reg_ucfg_api.h" 25 #include "wlan_cfg80211_afc.h" 26 27 /** 28 * wlan_send_afc_request() - PDEV callback function to send AFC request 29 * @pdev: Pointer to PDEV object 30 * @afc_req: Pointer to AFC request from regulatory component 31 * @arg: Pointer to argument list of callback function 32 * 33 * Return: None 34 */ 35 static void 36 wlan_send_afc_request(struct wlan_objmgr_pdev *pdev, 37 struct wlan_afc_host_request *afc_req, 38 void *arg) 39 { 40 struct wlan_objmgr_psoc *psoc; 41 struct wlan_afc_psoc_priv *afc_priv; 42 43 psoc = wlan_pdev_get_psoc(pdev); 44 45 afc_priv = afc_psoc_priv(psoc); 46 if (!afc_priv) { 47 afc_err("psoc AFC private null"); 48 return; 49 } 50 51 if (afc_priv->cbs.afc_req_func) 52 afc_priv->cbs.afc_req_func(pdev, afc_req); 53 } 54 55 /** 56 * wlan_send_afc_power_event() - PDEV callback function to send AFC power 57 * update complete event. 58 * @pdev: Pointer to PDEV object 59 * @afc_pwr_evt: Pointer to AFC power event from regulatory component 60 * @arg: Pointer to argument list of callback function 61 * 62 * Return: None 63 */ 64 static void 65 wlan_send_afc_power_event(struct wlan_objmgr_pdev *pdev, 66 struct reg_fw_afc_power_event *afc_pwr_evt, 67 void *arg) 68 { 69 struct wlan_objmgr_psoc *psoc; 70 struct wlan_afc_psoc_priv *afc_priv; 71 72 psoc = wlan_pdev_get_psoc(pdev); 73 74 afc_priv = afc_psoc_priv(psoc); 75 if (!afc_priv) { 76 afc_err("psoc AFC private null"); 77 return; 78 } 79 80 if (afc_priv->cbs.afc_updated_func) 81 afc_priv->cbs.afc_updated_func(pdev, afc_pwr_evt); 82 } 83 84 int wlan_afc_data_send(struct wlan_objmgr_psoc *psoc, 85 struct wlan_objmgr_pdev *pdev, 86 struct wlan_afc_host_resp *data, 87 uint32_t len) 88 { 89 struct wlan_afc_psoc_priv *afc_priv; 90 91 afc_priv = afc_psoc_priv(psoc); 92 if (!afc_priv) { 93 afc_err("psoc AFC private null"); 94 return -EINVAL; 95 } 96 97 if (afc_priv->cbs.afc_rsp_cp_func) 98 return afc_priv->cbs.afc_rsp_cp_func(psoc, pdev, data, len); 99 100 return -EINVAL; 101 } 102 103 QDF_STATUS wlan_afc_register_data_send_cb(struct wlan_objmgr_psoc *psoc, 104 send_response_to_afcmem func) 105 { 106 struct wlan_afc_psoc_priv *afc_priv; 107 108 afc_priv = afc_psoc_priv(psoc); 109 if (!afc_priv) { 110 afc_err("psoc AFC private null"); 111 return QDF_STATUS_E_FAILURE; 112 } 113 114 afc_priv->cbs.afc_rsp_cp_func = func; 115 116 return QDF_STATUS_SUCCESS; 117 } 118 119 QDF_STATUS 120 wlan_afc_psoc_created_notification(struct wlan_objmgr_psoc *psoc, 121 void *arg) 122 { 123 QDF_STATUS status; 124 struct wlan_afc_psoc_priv *afc_priv; 125 126 afc_priv = qdf_mem_malloc(sizeof(*afc_priv)); 127 if (!afc_priv) 128 return QDF_STATUS_E_NOMEM; 129 130 status = wlan_objmgr_psoc_component_obj_attach(psoc, 131 WLAN_UMAC_COMP_AFC, 132 afc_priv, 133 QDF_STATUS_SUCCESS); 134 135 if (QDF_IS_STATUS_ERROR(status)) { 136 qdf_mem_free(afc_priv); 137 afc_err("Failed to attach psoc AFC component"); 138 return status; 139 } 140 141 afc_priv->psoc = psoc; 142 afc_priv->cbs.afc_req_func = wlan_cfg80211_afc_send_request; 143 afc_priv->cbs.afc_updated_func = wlan_cfg80211_afc_send_update_complete; 144 145 return status; 146 } 147 148 QDF_STATUS 149 wlan_afc_psoc_destroyed_notification(struct wlan_objmgr_psoc *psoc, 150 void *arg) 151 { 152 QDF_STATUS status; 153 void *afc_priv; 154 155 afc_priv = afc_psoc_priv(psoc); 156 if (!afc_priv) { 157 afc_err("Failed to get psoc AFC component private"); 158 return QDF_STATUS_E_FAILURE; 159 } 160 161 status = wlan_objmgr_psoc_component_obj_detach(psoc, 162 WLAN_UMAC_COMP_AFC, 163 afc_priv); 164 if (QDF_IS_STATUS_ERROR(status)) 165 afc_err("Failed to detach AFC component"); 166 167 qdf_mem_free(afc_priv); 168 169 return status; 170 } 171 172 QDF_STATUS 173 wlan_afc_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, 174 void *arg) 175 { 176 QDF_STATUS status; 177 178 status = ucfg_reg_register_afc_req_rx_callback(pdev, 179 wlan_send_afc_request, 180 NULL); 181 if (QDF_IS_STATUS_ERROR(status)) { 182 afc_err("Failed to register AFC request callback"); 183 return status; 184 } 185 186 status = ucfg_reg_register_afc_power_event_callback(pdev, 187 wlan_send_afc_power_event, 188 NULL); 189 if (QDF_IS_STATUS_ERROR(status)) { 190 afc_err("Failed to register AFC power callback"); 191 ucfg_reg_unregister_afc_req_rx_callback(pdev, 192 wlan_send_afc_request); 193 return status; 194 } 195 196 return status; 197 } 198 199 QDF_STATUS 200 wlan_afc_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev, void *arg) 201 { 202 ucfg_reg_unregister_afc_req_rx_callback(pdev, 203 wlan_send_afc_request); 204 ucfg_reg_unregister_afc_power_event_callback(pdev, 205 wlan_send_afc_power_event); 206 207 return QDF_STATUS_SUCCESS; 208 } 209