1 /* 2 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: defines DP interaction with FW using WMI 22 */ 23 24 #include <qdf_status.h> 25 #include "target_if_dp.h" 26 #include <init_deinit_lmac.h> 27 28 void 29 target_if_peer_set_default_routing(struct cdp_ctrl_objmgr_psoc *psoc, 30 uint8_t pdev_id, uint8_t *peer_macaddr, 31 uint8_t vdev_id, 32 bool hash_based, uint8_t ring_num, 33 uint8_t lmac_peer_id_msb) 34 { 35 uint32_t value; 36 struct peer_set_params param; 37 struct wmi_unified *pdev_wmi_handle; 38 struct wlan_objmgr_pdev *pdev = 39 wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc, 40 pdev_id, WLAN_PDEV_TARGET_IF_ID); 41 42 if (!pdev) { 43 target_if_err("pdev with id %d is NULL", pdev_id); 44 return; 45 } 46 47 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); 48 if (!pdev_wmi_handle) { 49 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); 50 target_if_err("pdev wmi handle NULL"); 51 return; 52 } 53 54 qdf_mem_zero(¶m, sizeof(param)); 55 56 /* TODO: Need bit definitions for ring number and hash based routing 57 * fields in common wmi header file 58 */ 59 value = ((hash_based) ? 1 : 0) | (ring_num << 1); 60 61 if (lmac_peer_id_msb) 62 QDF_SET_BITS(value, PEER_ROUTING_LMAC_ID_INDEX, 63 PEER_ROUTING_LMAC_ID_BITS, lmac_peer_id_msb); 64 65 param.param_id = WMI_HOST_PEER_SET_DEFAULT_ROUTING; 66 param.vdev_id = vdev_id; 67 param.param_value = value; 68 69 if (wmi_set_peer_param_send(pdev_wmi_handle, peer_macaddr, ¶m)) { 70 target_if_err("Unable to set default routing for peer " 71 QDF_MAC_ADDR_FMT, 72 QDF_MAC_ADDR_REF(peer_macaddr)); 73 } 74 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); 75 } 76 77 #ifdef SERIALIZE_QUEUE_SETUP 78 static QDF_STATUS 79 target_if_rx_reorder_queue_setup(struct scheduler_msg *msg) 80 { 81 struct rx_reorder_queue_setup_params param; 82 struct wmi_unified *pdev_wmi_handle; 83 struct reorder_q_setup *q_params; 84 QDF_STATUS status; 85 struct wlan_objmgr_pdev *pdev; 86 struct wlan_objmgr_psoc *psoc; 87 88 if (!(msg->bodyptr)) { 89 target_if_err("rx_reorder: Invalid message body"); 90 return QDF_STATUS_E_INVAL; 91 } 92 93 q_params = msg->bodyptr; 94 psoc = (struct wlan_objmgr_psoc *)q_params->psoc; 95 96 pdev = wlan_objmgr_get_pdev_by_id(psoc, q_params->pdev_id, 97 WLAN_PDEV_TARGET_IF_ID); 98 99 if (!pdev) { 100 target_if_err("pdev with id %d is NULL", q_params->pdev_id); 101 return QDF_STATUS_E_INVAL; 102 } 103 104 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); 105 if (!pdev_wmi_handle) { 106 target_if_err("pdev wmi handle NULL"); 107 status = QDF_STATUS_E_FAILURE; 108 goto out; 109 } 110 111 param.tid = q_params->tid; 112 param.vdev_id = q_params->vdev_id; 113 param.peer_macaddr = q_params->peer_mac; 114 param.hw_qdesc_paddr_lo = q_params->hw_qdesc_paddr & 0xffffffff; 115 param.hw_qdesc_paddr_hi = (uint64_t)q_params->hw_qdesc_paddr >> 32; 116 param.queue_no = q_params->queue_no; 117 param.ba_window_size_valid = q_params->ba_window_size_valid; 118 param.ba_window_size = q_params->ba_window_size; 119 120 status = wmi_unified_peer_rx_reorder_queue_setup_send(pdev_wmi_handle, 121 ¶m); 122 out: 123 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); 124 qdf_mem_free(q_params); 125 126 return status; 127 } 128 129 QDF_STATUS 130 target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc, 131 uint8_t pdev_id, 132 uint8_t vdev_id, uint8_t *peer_macaddr, 133 qdf_dma_addr_t hw_qdesc, int tid, 134 uint16_t queue_no, 135 uint8_t ba_window_size_valid, 136 uint16_t ba_window_size) 137 { 138 struct scheduler_msg msg = {0}; 139 struct reorder_q_setup *q_params; 140 QDF_STATUS status; 141 142 q_params = qdf_mem_malloc(sizeof(*q_params)); 143 if (!q_params) 144 return QDF_STATUS_E_NOMEM; 145 146 q_params->psoc = psoc; 147 q_params->vdev_id = vdev_id; 148 q_params->pdev_id = pdev_id; 149 q_params->hw_qdesc_paddr = hw_qdesc; 150 q_params->tid = tid; 151 q_params->queue_no = queue_no; 152 q_params->ba_window_size_valid = ba_window_size_valid; 153 q_params->ba_window_size = ba_window_size; 154 qdf_mem_copy(q_params->peer_mac, peer_macaddr, QDF_MAC_ADDR_SIZE); 155 156 msg.bodyptr = q_params; 157 msg.callback = target_if_rx_reorder_queue_setup; 158 status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF, 159 QDF_MODULE_ID_TARGET_IF, 160 QDF_MODULE_ID_TARGET_IF, &msg); 161 162 if (status != QDF_STATUS_SUCCESS) 163 qdf_mem_free(q_params); 164 165 return status; 166 } 167 168 #else 169 170 QDF_STATUS 171 target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc, 172 uint8_t pdev_id, 173 uint8_t vdev_id, uint8_t *peer_macaddr, 174 qdf_dma_addr_t hw_qdesc, int tid, 175 uint16_t queue_no, 176 uint8_t ba_window_size_valid, 177 uint16_t ba_window_size) 178 { 179 struct rx_reorder_queue_setup_params param; 180 struct wmi_unified *pdev_wmi_handle; 181 QDF_STATUS status; 182 struct wlan_objmgr_pdev *pdev = 183 wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc, 184 pdev_id, WLAN_PDEV_TARGET_IF_ID); 185 186 if (!pdev) { 187 target_if_err("pdev with id %d is NULL", pdev_id); 188 return QDF_STATUS_E_INVAL; 189 } 190 191 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); 192 if (!pdev_wmi_handle) { 193 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); 194 target_if_err("pdev wmi handle NULL"); 195 return QDF_STATUS_E_FAILURE; 196 } 197 param.tid = tid; 198 param.vdev_id = vdev_id; 199 param.peer_macaddr = peer_macaddr; 200 param.hw_qdesc_paddr_lo = hw_qdesc & 0xffffffff; 201 param.hw_qdesc_paddr_hi = (uint64_t)hw_qdesc >> 32; 202 param.queue_no = queue_no; 203 param.ba_window_size_valid = ba_window_size_valid; 204 param.ba_window_size = ba_window_size; 205 206 status = wmi_unified_peer_rx_reorder_queue_setup_send(pdev_wmi_handle, 207 ¶m); 208 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); 209 210 return status; 211 } 212 #endif 213 214 QDF_STATUS 215 target_if_peer_rx_reorder_queue_remove(struct cdp_ctrl_objmgr_psoc *psoc, 216 uint8_t pdev_id, 217 uint8_t vdev_id, uint8_t *peer_macaddr, 218 uint32_t peer_tid_bitmap) 219 { 220 struct rx_reorder_queue_remove_params param; 221 struct wmi_unified *pdev_wmi_handle; 222 QDF_STATUS status; 223 struct wlan_objmgr_pdev *pdev = 224 wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc, 225 pdev_id, WLAN_PDEV_TARGET_IF_ID); 226 227 if (!pdev) { 228 target_if_err("pdev with id %d is NULL", pdev_id); 229 return QDF_STATUS_E_INVAL; 230 } 231 232 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); 233 if (!pdev_wmi_handle) { 234 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); 235 target_if_err("pdev wmi handle NULL"); 236 return QDF_STATUS_E_FAILURE; 237 } 238 param.vdev_id = vdev_id; 239 param.peer_macaddr = peer_macaddr; 240 param.peer_tid_bitmap = peer_tid_bitmap; 241 status = wmi_unified_peer_rx_reorder_queue_remove_send(pdev_wmi_handle, 242 ¶m); 243 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); 244 245 return status; 246 } 247 248 QDF_STATUS 249 target_if_lro_hash_config(struct cdp_ctrl_objmgr_psoc *psoc, uint8_t pdev_id, 250 struct cdp_lro_hash_config *lro_hash_cfg) 251 { 252 struct wmi_lro_config_cmd_t wmi_lro_cmd = {0}; 253 struct wmi_unified *pdev_wmi_handle; 254 QDF_STATUS status; 255 struct wlan_objmgr_pdev *pdev = 256 wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc, 257 pdev_id, WLAN_PDEV_TARGET_IF_ID); 258 259 if (!pdev) { 260 target_if_err("pdev with id %d is NULL", pdev_id); 261 return QDF_STATUS_E_INVAL; 262 } 263 264 pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); 265 if (!lro_hash_cfg || !pdev_wmi_handle) { 266 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); 267 target_if_err("wmi_handle: 0x%pK, lro_hash_cfg: 0x%pK", 268 pdev_wmi_handle, lro_hash_cfg); 269 return QDF_STATUS_E_FAILURE; 270 } 271 272 wmi_lro_cmd.lro_enable = lro_hash_cfg->lro_enable; 273 wmi_lro_cmd.tcp_flag = lro_hash_cfg->tcp_flag; 274 wmi_lro_cmd.tcp_flag_mask = lro_hash_cfg->tcp_flag_mask; 275 wmi_lro_cmd.pdev_id = pdev_id; 276 277 qdf_mem_copy(wmi_lro_cmd.toeplitz_hash_ipv4, 278 lro_hash_cfg->toeplitz_hash_ipv4, 279 LRO_IPV4_SEED_ARR_SZ * sizeof(uint32_t)); 280 281 qdf_mem_copy(wmi_lro_cmd.toeplitz_hash_ipv6, 282 lro_hash_cfg->toeplitz_hash_ipv6, 283 LRO_IPV6_SEED_ARR_SZ * sizeof(uint32_t)); 284 285 status = wmi_unified_lro_config_cmd(pdev_wmi_handle, 286 &wmi_lro_cmd); 287 wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID); 288 289 return status; 290 } 291