Nachiket Kukade | f412a02 | 2018-05-21 17:28:32 +0530 | [diff] [blame] | 1 | /* |
Rajeev Kumar Sirasanagandla | f3ed004 | 2019-05-08 18:45:44 +0530 | [diff] [blame] | 2 | * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. |
Nachiket Kukade | f412a02 | 2018-05-21 17:28:32 +0530 | [diff] [blame] | 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 | #include "wmi_unified_apf_tlv.h" |
Tushnim Bhattacharyya | 33087cb | 2019-08-12 15:58:40 -0700 | [diff] [blame] | 20 | #include "wmi.h" |
Nachiket Kukade | f412a02 | 2018-05-21 17:28:32 +0530 | [diff] [blame] | 21 | |
Nachiket Kukade | b29adc4 | 2018-05-25 14:52:55 +0530 | [diff] [blame] | 22 | QDF_STATUS wmi_send_set_active_apf_mode_cmd_tlv(wmi_unified_t wmi_handle, |
Nachiket Kukade | f412a02 | 2018-05-21 17:28:32 +0530 | [diff] [blame] | 23 | uint8_t vdev_id, |
Nachiket Kukade | a52b818 | 2018-05-22 12:17:15 +0530 | [diff] [blame] | 24 | enum wmi_host_active_apf_mode |
Nachiket Kukade | f412a02 | 2018-05-21 17:28:32 +0530 | [diff] [blame] | 25 | ucast_mode, |
Nachiket Kukade | a52b818 | 2018-05-22 12:17:15 +0530 | [diff] [blame] | 26 | enum wmi_host_active_apf_mode |
Nachiket Kukade | f412a02 | 2018-05-21 17:28:32 +0530 | [diff] [blame] | 27 | mcast_bcast_mode) |
| 28 | { |
| 29 | const WMITLV_TAG_ID tag_id = |
| 30 | WMITLV_TAG_STRUC_wmi_bpf_set_vdev_active_mode_cmd_fixed_param; |
| 31 | const uint32_t tlv_len = WMITLV_GET_STRUCT_TLVLEN( |
| 32 | wmi_bpf_set_vdev_active_mode_cmd_fixed_param); |
| 33 | QDF_STATUS status; |
| 34 | wmi_bpf_set_vdev_active_mode_cmd_fixed_param *cmd; |
| 35 | wmi_buf_t buf; |
| 36 | |
Nachiket Kukade | b29adc4 | 2018-05-25 14:52:55 +0530 | [diff] [blame] | 37 | WMI_LOGD("Sending WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID(%u, %d, %d)", |
Nachiket Kukade | f412a02 | 2018-05-21 17:28:32 +0530 | [diff] [blame] | 38 | vdev_id, ucast_mode, mcast_bcast_mode); |
| 39 | |
| 40 | /* allocate command buffer */ |
| 41 | buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); |
| 42 | if (!buf) { |
| 43 | WMI_LOGE("%s: wmi_buf_alloc failed", __func__); |
| 44 | return QDF_STATUS_E_NOMEM; |
| 45 | } |
| 46 | |
| 47 | /* set TLV header */ |
| 48 | cmd = (wmi_bpf_set_vdev_active_mode_cmd_fixed_param *)wmi_buf_data(buf); |
| 49 | WMITLV_SET_HDR(&cmd->tlv_header, tag_id, tlv_len); |
| 50 | |
| 51 | /* populate data */ |
| 52 | cmd->vdev_id = vdev_id; |
| 53 | cmd->uc_mode = ucast_mode; |
| 54 | cmd->mcbc_mode = mcast_bcast_mode; |
| 55 | |
| 56 | /* send to FW */ |
| 57 | status = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), |
| 58 | WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID); |
| 59 | if (QDF_IS_STATUS_ERROR(status)) { |
Nachiket Kukade | b29adc4 | 2018-05-25 14:52:55 +0530 | [diff] [blame] | 60 | WMI_LOGE("Failed to send WMI_BPF_SET_VDEV_ACTIVE_MODE_CMDID:%d", |
Nachiket Kukade | f412a02 | 2018-05-21 17:28:32 +0530 | [diff] [blame] | 61 | status); |
| 62 | wmi_buf_free(buf); |
| 63 | return status; |
| 64 | } |
| 65 | |
Nachiket Kukade | b29adc4 | 2018-05-25 14:52:55 +0530 | [diff] [blame] | 66 | return QDF_STATUS_SUCCESS; |
| 67 | } |
| 68 | |
| 69 | QDF_STATUS wmi_send_apf_enable_cmd_tlv(wmi_unified_t wmi_handle, |
| 70 | uint32_t vdev_id, |
| 71 | bool enable) |
| 72 | { |
| 73 | wmi_bpf_set_vdev_enable_cmd_fixed_param *cmd; |
| 74 | wmi_buf_t buf; |
| 75 | |
| 76 | buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); |
| 77 | if (!buf) { |
| 78 | WMI_LOGP("%s: wmi_buf_alloc failed", __func__); |
| 79 | return QDF_STATUS_E_NOMEM; |
| 80 | } |
| 81 | |
| 82 | cmd = (wmi_bpf_set_vdev_enable_cmd_fixed_param *) wmi_buf_data(buf); |
| 83 | WMITLV_SET_HDR(&cmd->tlv_header, |
| 84 | WMITLV_TAG_STRUC_wmi_bpf_set_vdev_enable_cmd_fixed_param, |
| 85 | WMITLV_GET_STRUCT_TLVLEN( |
| 86 | wmi_bpf_set_vdev_enable_cmd_fixed_param)); |
| 87 | cmd->vdev_id = vdev_id; |
| 88 | cmd->is_enabled = enable; |
| 89 | |
| 90 | if (wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), |
| 91 | WMI_BPF_SET_VDEV_ENABLE_CMDID)) { |
| 92 | WMI_LOGE("%s: Failed to enable/disable APF interpreter", |
| 93 | __func__); |
| 94 | wmi_buf_free(buf); |
| 95 | return QDF_STATUS_E_FAILURE; |
| 96 | } |
Nachiket Kukade | f412a02 | 2018-05-21 17:28:32 +0530 | [diff] [blame] | 97 | |
| 98 | return QDF_STATUS_SUCCESS; |
| 99 | } |
| 100 | |
Nachiket Kukade | b29adc4 | 2018-05-25 14:52:55 +0530 | [diff] [blame] | 101 | QDF_STATUS |
| 102 | wmi_send_apf_write_work_memory_cmd_tlv(wmi_unified_t wmi_handle, |
| 103 | struct wmi_apf_write_memory_params |
| 104 | *apf_write_params) |
| 105 | { |
| 106 | wmi_bpf_set_vdev_work_memory_cmd_fixed_param *cmd; |
| 107 | uint32_t wmi_buf_len; |
| 108 | wmi_buf_t buf; |
| 109 | uint8_t *buf_ptr; |
| 110 | uint32_t aligned_len = 0; |
| 111 | |
| 112 | wmi_buf_len = sizeof(*cmd); |
| 113 | if (apf_write_params->length) { |
| 114 | aligned_len = roundup(apf_write_params->length, |
| 115 | sizeof(A_UINT32)); |
| 116 | |
| 117 | wmi_buf_len += WMI_TLV_HDR_SIZE + aligned_len; |
| 118 | |
| 119 | } |
| 120 | |
| 121 | buf = wmi_buf_alloc(wmi_handle, wmi_buf_len); |
| 122 | if (!buf) { |
| 123 | WMI_LOGP("%s: wmi_buf_alloc failed", __func__); |
| 124 | return QDF_STATUS_E_NOMEM; |
| 125 | } |
| 126 | |
| 127 | buf_ptr = wmi_buf_data(buf); |
| 128 | cmd = (wmi_bpf_set_vdev_work_memory_cmd_fixed_param *)buf_ptr; |
| 129 | WMITLV_SET_HDR(&cmd->tlv_header, |
| 130 | WMITLV_TAG_STRUC_wmi_bpf_set_vdev_work_memory_cmd_fixed_param, |
| 131 | WMITLV_GET_STRUCT_TLVLEN( |
| 132 | wmi_bpf_set_vdev_work_memory_cmd_fixed_param)); |
| 133 | cmd->vdev_id = apf_write_params->vdev_id; |
| 134 | cmd->bpf_version = apf_write_params->apf_version; |
| 135 | cmd->program_len = apf_write_params->program_len; |
| 136 | cmd->addr_offset = apf_write_params->addr_offset; |
| 137 | cmd->length = apf_write_params->length; |
| 138 | |
| 139 | if (apf_write_params->length) { |
| 140 | buf_ptr += sizeof(*cmd); |
| 141 | WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, |
| 142 | aligned_len); |
| 143 | buf_ptr += WMI_TLV_HDR_SIZE; |
| 144 | qdf_mem_copy(buf_ptr, apf_write_params->buf, |
| 145 | apf_write_params->length); |
| 146 | } |
| 147 | |
| 148 | if (wmi_unified_cmd_send(wmi_handle, buf, wmi_buf_len, |
| 149 | WMI_BPF_SET_VDEV_WORK_MEMORY_CMDID)) { |
| 150 | WMI_LOGE("%s: Failed to write APF work memory", __func__); |
| 151 | wmi_buf_free(buf); |
| 152 | return QDF_STATUS_E_FAILURE; |
| 153 | } |
| 154 | |
| 155 | return QDF_STATUS_SUCCESS; |
| 156 | } |
| 157 | |
| 158 | QDF_STATUS |
| 159 | wmi_send_apf_read_work_memory_cmd_tlv(wmi_unified_t wmi_handle, |
| 160 | struct wmi_apf_read_memory_params |
| 161 | *apf_read_params) |
| 162 | { |
| 163 | wmi_bpf_get_vdev_work_memory_cmd_fixed_param *cmd; |
| 164 | wmi_buf_t buf; |
| 165 | |
| 166 | buf = wmi_buf_alloc(wmi_handle, sizeof(*cmd)); |
| 167 | if (!buf) { |
| 168 | WMI_LOGP("%s: wmi_buf_alloc failed", __func__); |
| 169 | return QDF_STATUS_E_NOMEM; |
| 170 | } |
| 171 | |
| 172 | cmd = (wmi_bpf_get_vdev_work_memory_cmd_fixed_param *) |
| 173 | wmi_buf_data(buf); |
| 174 | |
| 175 | WMITLV_SET_HDR(&cmd->tlv_header, |
| 176 | WMITLV_TAG_STRUC_wmi_bpf_get_vdev_work_memory_cmd_fixed_param, |
| 177 | WMITLV_GET_STRUCT_TLVLEN( |
| 178 | wmi_bpf_get_vdev_work_memory_cmd_fixed_param)); |
| 179 | cmd->vdev_id = apf_read_params->vdev_id; |
| 180 | cmd->addr_offset = apf_read_params->addr_offset; |
| 181 | cmd->length = apf_read_params->length; |
| 182 | |
| 183 | if (wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cmd), |
| 184 | WMI_BPF_GET_VDEV_WORK_MEMORY_CMDID)) { |
| 185 | WMI_LOGE("%s: Failed to get APF work memory", __func__); |
| 186 | wmi_buf_free(buf); |
| 187 | return QDF_STATUS_E_FAILURE; |
| 188 | } |
| 189 | |
| 190 | return QDF_STATUS_SUCCESS; |
| 191 | } |
| 192 | |
| 193 | QDF_STATUS |
| 194 | wmi_extract_apf_read_memory_resp_event_tlv(wmi_unified_t wmi_handle, |
| 195 | void *evt_buf, |
| 196 | struct wmi_apf_read_memory_resp_event_params |
| 197 | *resp) |
| 198 | { |
| 199 | WMI_BPF_GET_VDEV_WORK_MEMORY_RESP_EVENTID_param_tlvs *param_buf; |
| 200 | wmi_bpf_get_vdev_work_memory_resp_evt_fixed_param *data_event; |
| 201 | |
| 202 | param_buf = evt_buf; |
| 203 | if (!param_buf) { |
| 204 | WMI_LOGE("encrypt decrypt resp evt_buf is NULL"); |
| 205 | return QDF_STATUS_E_INVAL; |
| 206 | } |
| 207 | |
| 208 | data_event = param_buf->fixed_param; |
| 209 | |
| 210 | resp->vdev_id = data_event->vdev_id; |
| 211 | resp->offset = data_event->offset; |
| 212 | resp->more_data = data_event->fragment; |
| 213 | |
| 214 | if (data_event->length > param_buf->num_data) { |
| 215 | WMI_LOGE("FW msg data_len %d more than TLV hdr %d", |
| 216 | data_event->length, |
| 217 | param_buf->num_data); |
| 218 | return QDF_STATUS_E_INVAL; |
| 219 | } |
Nachiket Kukade | b29adc4 | 2018-05-25 14:52:55 +0530 | [diff] [blame] | 220 | |
Rajeev Kumar Sirasanagandla | f3ed004 | 2019-05-08 18:45:44 +0530 | [diff] [blame] | 221 | if (data_event->length && param_buf->data) { |
| 222 | resp->length = data_event->length; |
Nachiket Kukade | b29adc4 | 2018-05-25 14:52:55 +0530 | [diff] [blame] | 223 | resp->data = (uint8_t *)param_buf->data; |
Rajeev Kumar Sirasanagandla | f3ed004 | 2019-05-08 18:45:44 +0530 | [diff] [blame] | 224 | } |
Nachiket Kukade | b29adc4 | 2018-05-25 14:52:55 +0530 | [diff] [blame] | 225 | |
| 226 | return QDF_STATUS_SUCCESS; |
| 227 | } |