1 /* 2 * Copyright (c) 2017-2019 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: offload lmac interface APIs definitions for Green ap 21 */ 22 23 #include <target_if_green_ap.h> 24 #include <wlan_green_ap_api.h> 25 #include <../../core/src/wlan_green_ap_main_i.h> 26 #include <target_if.h> 27 #include <wmi_unified_api.h> 28 29 QDF_STATUS target_if_register_green_ap_tx_ops( 30 struct wlan_lmac_if_tx_ops *tx_ops) 31 { 32 struct wlan_lmac_if_green_ap_tx_ops *green_ap_tx_ops; 33 34 if (!tx_ops) { 35 target_if_err("invalid tx_ops"); 36 return QDF_STATUS_E_FAILURE; 37 } 38 39 green_ap_tx_ops = &tx_ops->green_ap_tx_ops; 40 41 green_ap_tx_ops->enable_egap = target_if_green_ap_enable_egap; 42 green_ap_tx_ops->ps_on_off_send = target_if_green_ap_set_ps_on_off; 43 green_ap_tx_ops->reset_dev = NULL; 44 green_ap_tx_ops->get_current_channel = NULL; 45 green_ap_tx_ops->get_current_channel_flags = NULL; 46 green_ap_tx_ops->get_capab = NULL; 47 48 return QDF_STATUS_SUCCESS; 49 } 50 51 /** 52 * target_if_green_ap_egap_status_info_event() - egap status info event 53 * @scn: pointer to scn handle 54 * @evt_buf: pointer to event buffer 55 * @data_len: data len of the event buffer 56 * 57 * Return: 0 for success, otherwise appropriate error code 58 */ 59 static int target_if_green_ap_egap_status_info_event( 60 ol_scn_t scn, uint8_t *evt_buf, uint32_t data_len) 61 { 62 struct wlan_objmgr_pdev *pdev; 63 struct wlan_green_ap_egap_status_info egap_status_info_params; 64 void *wmi_hdl; 65 66 pdev = target_if_get_pdev_from_scn_hdl(scn); 67 if (!pdev) { 68 green_ap_err("pdev is null"); 69 return QDF_STATUS_E_FAILURE; 70 } 71 72 wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev); 73 if (!wmi_hdl) { 74 green_ap_err("null wmi_hdl"); 75 return QDF_STATUS_E_FAILURE; 76 } 77 78 if (wmi_extract_green_ap_egap_status_info(wmi_hdl, 79 evt_buf, 80 &egap_status_info_params) != 81 QDF_STATUS_SUCCESS) { 82 green_ap_err("unable to extract green ap egap status info"); 83 return QDF_STATUS_E_FAILURE; 84 } 85 86 green_ap_debug("mac_id: %d, status: %d, tx_mask: %x, rx_mask: %d", 87 egap_status_info_params.mac_id, 88 egap_status_info_params.status, 89 egap_status_info_params.tx_chainmask, 90 egap_status_info_params.rx_chainmask); 91 92 return 0; 93 } 94 95 QDF_STATUS target_if_green_ap_register_egap_event_handler( 96 struct wlan_objmgr_pdev *pdev) 97 { 98 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 99 struct wlan_green_ap_egap_params *egap_params; 100 int ret; 101 void *wmi_hdl; 102 103 if (!pdev) { 104 green_ap_err("pdev is null"); 105 return QDF_STATUS_E_INVAL; 106 } 107 108 wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev); 109 if (!wmi_hdl) { 110 green_ap_err("null wmi_hdl"); 111 return QDF_STATUS_E_FAILURE; 112 } 113 114 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 115 pdev, WLAN_UMAC_COMP_GREEN_AP); 116 if (!green_ap_ctx) { 117 green_ap_err("green ap context obtained is NULL"); 118 return QDF_STATUS_E_FAILURE; 119 } 120 egap_params = &green_ap_ctx->egap_params; 121 122 ret = wmi_unified_register_event_handler( 123 wmi_hdl, 124 wmi_ap_ps_egap_info_event_id, 125 target_if_green_ap_egap_status_info_event, 126 WMI_RX_UMAC_CTX); 127 if (ret < 0) { 128 green_ap_err("Failed to register Enhance Green AP event"); 129 egap_params->fw_egap_support = false; 130 } else { 131 green_ap_info("Set the Enhance Green AP event handler"); 132 egap_params->fw_egap_support = true; 133 } 134 135 return QDF_STATUS_SUCCESS; 136 } 137 138 QDF_STATUS target_if_green_ap_enable_egap( 139 struct wlan_objmgr_pdev *pdev, 140 struct wlan_green_ap_egap_params *egap_params) 141 { 142 struct wlan_pdev_green_ap_ctx *green_ap_ctx; 143 wmi_unified_t wmi_hdl; 144 145 if (!pdev) { 146 green_ap_err("pdev context passed is NULL"); 147 return QDF_STATUS_E_INVAL; 148 } 149 150 wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev); 151 if (!wmi_hdl) { 152 green_ap_err("null wmi_hdl"); 153 return QDF_STATUS_E_FAILURE; 154 } 155 156 green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj( 157 pdev, WLAN_UMAC_COMP_GREEN_AP); 158 if (!green_ap_ctx) { 159 green_ap_err("green ap context obtained is NULL"); 160 return QDF_STATUS_E_FAILURE; 161 } 162 163 qdf_spin_lock_bh(&green_ap_ctx->lock); 164 if (!wlan_is_egap_enabled(green_ap_ctx)) { 165 green_ap_info("enhanced green ap support is not present"); 166 qdf_spin_unlock_bh(&green_ap_ctx->lock); 167 return QDF_STATUS_SUCCESS; 168 } 169 qdf_spin_unlock_bh(&green_ap_ctx->lock); 170 171 return wmi_unified_egap_conf_params_cmd(wmi_hdl, 172 egap_params); 173 } 174 175 QDF_STATUS target_if_green_ap_set_ps_on_off(struct wlan_objmgr_pdev *pdev, 176 bool value, uint8_t pdev_id) 177 { 178 wmi_unified_t wmi_hdl; 179 180 if (!pdev) { 181 green_ap_err("pdev context passed is NULL"); 182 return QDF_STATUS_E_INVAL; 183 } 184 185 wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev); 186 if (!wmi_hdl) { 187 green_ap_err("null wmi_hdl"); 188 return QDF_STATUS_E_FAILURE; 189 } 190 191 return wmi_unified_green_ap_ps_send(wmi_hdl, 192 value, pdev_id); 193 } 194