1 /* 2 * Copyright (c) 2021 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 #include <osdep.h> 20 #include <wmi.h> 21 #include <wmi_unified_priv.h> 22 #include <wmi_unified_wds_api.h> 23 24 /** 25 * send_peer_add_wds_entry_cmd_tlv() - send peer add command to fw 26 * @wmi_handle: wmi handle 27 * @param: pointer holding peer details 28 * 29 * Return: QDF_STATUS_SUCCESS for success or error code 30 */ 31 static QDF_STATUS 32 send_peer_add_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 33 struct peer_add_wds_entry_params *param) 34 { 35 wmi_peer_add_wds_entry_cmd_fixed_param *cmd; 36 wmi_buf_t buf; 37 int len = sizeof(*cmd); 38 QDF_STATUS ret; 39 40 buf = wmi_buf_alloc(wmi_handle, len); 41 if (!buf) 42 return QDF_STATUS_E_NOMEM; 43 44 cmd = (wmi_peer_add_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 45 WMITLV_SET_HDR(&cmd->tlv_header, 46 WMITLV_TAG_STRUC_wmi_peer_add_wds_entry_cmd_fixed_param, 47 WMITLV_GET_STRUCT_TLVLEN 48 (wmi_peer_add_wds_entry_cmd_fixed_param)); 49 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 50 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 51 52 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? 53 WMI_WDS_FLAG_STATIC : 0; 54 cmd->vdev_id = param->vdev_id; 55 56 wmi_mtrace(WMI_PEER_ADD_WDS_ENTRY_CMDID, cmd->vdev_id, 0); 57 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 58 WMI_PEER_ADD_WDS_ENTRY_CMDID); 59 if (QDF_IS_STATUS_ERROR(ret)) 60 wmi_buf_free(buf); 61 62 return ret; 63 } 64 65 /** 66 * send_peer_del_wds_entry_cmd_tlv() - send peer delete command to fw 67 * @wmi_handle: wmi handle 68 * @param: pointer holding peer details 69 * 70 * Return: QDF_STATUS_SUCCESS for success or error code 71 */ 72 static QDF_STATUS 73 send_peer_del_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 74 struct peer_del_wds_entry_params *param) 75 { 76 wmi_peer_remove_wds_entry_cmd_fixed_param *cmd; 77 wmi_buf_t buf; 78 int len = sizeof(*cmd); 79 QDF_STATUS ret; 80 81 buf = wmi_buf_alloc(wmi_handle, len); 82 if (!buf) 83 return QDF_STATUS_E_NOMEM; 84 85 cmd = (wmi_peer_remove_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 86 WMITLV_SET_HDR(&cmd->tlv_header, 87 WMITLV_TAG_STRUC_wmi_peer_remove_wds_entry_cmd_fixed_param, 88 WMITLV_GET_STRUCT_TLVLEN 89 (wmi_peer_remove_wds_entry_cmd_fixed_param)); 90 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 91 92 cmd->vdev_id = param->vdev_id; 93 94 wmi_mtrace(WMI_PEER_REMOVE_WDS_ENTRY_CMDID, cmd->vdev_id, 0); 95 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 96 WMI_PEER_REMOVE_WDS_ENTRY_CMDID); 97 if (QDF_IS_STATUS_ERROR(ret)) 98 wmi_buf_free(buf); 99 100 return ret; 101 } 102 103 /** 104 * send_peer_update_wds_entry_cmd_tlv() - send peer update command to fw 105 * @wmi_handle: wmi handle 106 * @param: pointer holding peer details 107 * 108 * Return: QDF_STATUS_SUCCESS for success or error code 109 */ 110 static QDF_STATUS 111 send_peer_update_wds_entry_cmd_tlv(wmi_unified_t wmi_handle, 112 struct peer_update_wds_entry_params *param) 113 { 114 wmi_peer_update_wds_entry_cmd_fixed_param *cmd; 115 wmi_buf_t buf; 116 int len = sizeof(*cmd); 117 QDF_STATUS ret; 118 119 buf = wmi_buf_alloc(wmi_handle, len); 120 if (!buf) 121 return QDF_STATUS_E_NOMEM; 122 123 cmd = (wmi_peer_update_wds_entry_cmd_fixed_param *)wmi_buf_data(buf); 124 WMITLV_SET_HDR(&cmd->tlv_header, 125 WMITLV_TAG_STRUC_wmi_peer_update_wds_entry_cmd_fixed_param, 126 WMITLV_GET_STRUCT_TLVLEN 127 (wmi_peer_update_wds_entry_cmd_fixed_param)); 128 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->dest_addr, &cmd->wds_macaddr); 129 WMI_CHAR_ARRAY_TO_MAC_ADDR(param->peer_addr, &cmd->peer_macaddr); 130 131 cmd->flags = (param->flags & WMI_HOST_WDS_FLAG_STATIC) ? 132 WMI_WDS_FLAG_STATIC : 0; 133 cmd->vdev_id = param->vdev_id; 134 135 wmi_mtrace(WMI_PEER_UPDATE_WDS_ENTRY_CMDID, cmd->vdev_id, 0); 136 ret = wmi_unified_cmd_send(wmi_handle, buf, len, 137 WMI_PEER_UPDATE_WDS_ENTRY_CMDID); 138 if (QDF_IS_STATUS_ERROR(ret)) 139 wmi_buf_free(buf); 140 141 return ret; 142 } 143 144 void wmi_wds_attach_tlv(wmi_unified_t wmi_handle) 145 { 146 struct wmi_ops *ops = wmi_handle->ops; 147 148 ops->send_peer_add_wds_entry_cmd = send_peer_add_wds_entry_cmd_tlv; 149 ops->send_peer_del_wds_entry_cmd = send_peer_del_wds_entry_cmd_tlv; 150 ops->send_peer_update_wds_entry_cmd = 151 send_peer_update_wds_entry_cmd_tlv; 152 } 153