1 /* 2 * Copyright (c) 2021-2022 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: target_if_mlo_mgr.c 19 * 20 * This file provide definition for APIs registered through lmac Tx Ops 21 */ 22 23 #include <wmi_unified_11be_api.h> 24 #include <init_deinit_lmac.h> 25 #include "target_if_mlo_mgr.h" 26 27 /** 28 * target_if_mlo_link_set_active_resp_handler() - function to handle mlo link 29 * set active response from firmware. 30 * @scn: scn handle 31 * @data: data buffer for event 32 * @datalen: data length 33 * 34 * Return: 0 on success, else error on failure 35 */ 36 static int 37 target_if_mlo_link_set_active_resp_handler(ol_scn_t scn, uint8_t *data, 38 uint32_t datalen) 39 { 40 QDF_STATUS status; 41 struct wlan_objmgr_psoc *psoc; 42 struct wmi_unified *wmi_handle; 43 struct wlan_lmac_if_mlo_rx_ops *rx_ops; 44 struct mlo_link_set_active_resp resp; 45 46 if (!scn || !data) { 47 target_if_err("scn: 0x%pK, data: 0x%pK", scn, data); 48 return -EINVAL; 49 } 50 51 psoc = target_if_get_psoc_from_scn_hdl(scn); 52 if (!psoc) { 53 target_if_err("null psoc"); 54 return -EINVAL; 55 } 56 57 rx_ops = target_if_mlo_get_rx_ops(psoc); 58 if (!rx_ops || !rx_ops->process_link_set_active_resp) { 59 target_if_err("callback not registered"); 60 return -EINVAL; 61 } 62 63 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 64 if (!wmi_handle) { 65 target_if_err("wmi_handle is null"); 66 return -EINVAL; 67 } 68 69 if (wmi_extract_mlo_link_set_active_resp(wmi_handle, data, &resp) != 70 QDF_STATUS_SUCCESS) { 71 target_if_err("Unable to extract mlo link set active resp"); 72 return -EINVAL; 73 } 74 75 status = rx_ops->process_link_set_active_resp(psoc, &resp); 76 77 return qdf_status_to_os_return(status); 78 } 79 80 /** 81 * target_if_mlo_register_event_handler() - function to register handler for 82 * mlo related wmi event from firmware. 83 * @psoc: psoc pointer 84 * 85 * Return: QDF_STATUS 86 */ 87 static QDF_STATUS 88 target_if_mlo_register_event_handler(struct wlan_objmgr_psoc *psoc) 89 { 90 QDF_STATUS status; 91 struct wmi_unified *wmi_handle; 92 93 if (!psoc) { 94 target_if_err("PSOC is NULL!"); 95 return QDF_STATUS_E_NULL_VALUE; 96 } 97 98 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 99 if (!wmi_handle) { 100 target_if_err("wmi_handle is null"); 101 return QDF_STATUS_E_INVAL; 102 } 103 104 status = wmi_unified_register_event_handler( 105 wmi_handle, 106 wmi_mlo_link_set_active_resp_eventid, 107 target_if_mlo_link_set_active_resp_handler, 108 WMI_RX_WORK_CTX); 109 if (QDF_IS_STATUS_ERROR(status)) { 110 target_if_err("Register mlo link set active resp cb errcode %d", 111 status); 112 if (status == QDF_STATUS_E_NOSUPPORT) 113 status = QDF_STATUS_SUCCESS; 114 } 115 116 return status; 117 } 118 119 /** 120 * target_if_mlo_unregister_event_handler() - function to unregister handler for 121 * mlo related wmi event from firmware. 122 * @psoc: psoc pointer 123 * 124 * Return: QDF_STATUS 125 */ 126 static QDF_STATUS 127 target_if_mlo_unregister_event_handler(struct wlan_objmgr_psoc *psoc) 128 { 129 struct wmi_unified *wmi_handle; 130 131 if (!psoc) { 132 target_if_err("PSOC is NULL!"); 133 return QDF_STATUS_E_INVAL; 134 } 135 136 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 137 if (!wmi_handle) { 138 target_if_err("wmi_handle is null"); 139 return QDF_STATUS_E_INVAL; 140 } 141 142 wmi_unified_unregister_event_handler(wmi_handle, 143 wmi_mlo_link_set_active_resp_eventid); 144 145 return QDF_STATUS_SUCCESS; 146 } 147 148 /** 149 * target_if_mlo_link_set_active() - Send WMI command for set mlo link active 150 * @psoc: psoc pointer 151 * @param: parameter for setting mlo link active 152 * 153 * Return: QDF_STATUS 154 */ 155 static QDF_STATUS 156 target_if_mlo_link_set_active(struct wlan_objmgr_psoc *psoc, 157 struct mlo_link_set_active_param *param) 158 { 159 QDF_STATUS ret; 160 struct wmi_unified *wmi_handle; 161 162 if (!psoc) { 163 target_if_err("null psoc"); 164 return QDF_STATUS_E_FAILURE; 165 } 166 167 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 168 if (!wmi_handle) { 169 target_if_err("null handle"); 170 return QDF_STATUS_E_FAILURE; 171 } 172 173 ret = wmi_send_mlo_link_set_active_cmd(wmi_handle, param); 174 if (QDF_IS_STATUS_ERROR(ret)) 175 target_if_err("wmi mlo link set active send failed: %d", ret); 176 177 return ret; 178 } 179 180 /** 181 * target_if_mlo_register_tx_ops() - lmac handler to register mlo tx ops 182 * callback functions 183 * @tx_ops: wlan_lmac_if_tx_ops object 184 * 185 * Return: QDF_STATUS 186 */ 187 QDF_STATUS 188 target_if_mlo_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) 189 { 190 struct wlan_lmac_if_mlo_tx_ops *mlo_tx_ops; 191 192 if (!tx_ops) { 193 target_if_err("lmac tx ops is NULL!"); 194 return QDF_STATUS_E_INVAL; 195 } 196 197 mlo_tx_ops = &tx_ops->mlo_ops; 198 if (!mlo_tx_ops) { 199 target_if_err("lmac tx ops is NULL!"); 200 return QDF_STATUS_E_FAILURE; 201 } 202 203 mlo_tx_ops->register_events = 204 target_if_mlo_register_event_handler; 205 mlo_tx_ops->unregister_events = 206 target_if_mlo_unregister_event_handler; 207 mlo_tx_ops->link_set_active = target_if_mlo_link_set_active; 208 209 return QDF_STATUS_SUCCESS; 210 } 211 212