Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 1 | /* |
Rajeev Kumar | 15cf7ab | 2017-01-21 15:52:36 -0800 | [diff] [blame] | 2 | * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 3 | * |
| 4 | * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| 5 | * |
| 6 | * |
| 7 | * Permission to use, copy, modify, and/or distribute this software for |
| 8 | * any purpose with or without fee is hereby granted, provided that the |
| 9 | * above copyright notice and this permission notice appear in all |
| 10 | * copies. |
| 11 | * |
| 12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| 13 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| 14 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| 15 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| 16 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| 17 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| 18 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| 19 | * PERFORMANCE OF THIS SOFTWARE. |
| 20 | */ |
| 21 | |
| 22 | /* |
| 23 | * This file was originally distributed by Qualcomm Atheros, Inc. |
| 24 | * under proprietary terms before Copyright ownership was assigned |
| 25 | * to the Linux Foundation. |
| 26 | */ |
| 27 | |
| 28 | /* |
| 29 | * |
| 30 | * Permission to use, copy, modify, and/or distribute this software for any |
| 31 | * purpose with or without fee is hereby granted, provided that the above |
| 32 | * copyright notice and this permission notice appear in all copies. |
| 33 | * |
| 34 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 35 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 36 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 37 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 38 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 39 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 40 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 41 | */ |
| 42 | |
| 43 | #ifndef REMOVE_PKT_LOG |
Anurag Chouhan | 600c3a0 | 2016-03-01 10:33:54 +0530 | [diff] [blame] | 44 | #include "qdf_mem.h" |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 45 | #include "athdefs.h" |
| 46 | #include "pktlog_ac_i.h" |
| 47 | #include "cds_api.h" |
| 48 | #include "wma_types.h" |
Nirav Shah | 7f337db | 2016-05-25 10:49:02 +0530 | [diff] [blame] | 49 | #include "htc.h" |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 50 | |
| 51 | wdi_event_subscribe PKTLOG_TX_SUBSCRIBER; |
| 52 | wdi_event_subscribe PKTLOG_RX_SUBSCRIBER; |
| 53 | wdi_event_subscribe PKTLOG_RX_REMOTE_SUBSCRIBER; |
| 54 | wdi_event_subscribe PKTLOG_RCFIND_SUBSCRIBER; |
| 55 | wdi_event_subscribe PKTLOG_RCUPDATE_SUBSCRIBER; |
Nirav Shah | dcc4c87 | 2016-07-28 11:35:26 +0530 | [diff] [blame] | 56 | wdi_event_subscribe PKTLOG_SW_EVENT_SUBSCRIBER; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 57 | |
| 58 | struct ol_pl_arch_dep_funcs ol_pl_funcs = { |
| 59 | .pktlog_init = pktlog_init, |
| 60 | .pktlog_enable = pktlog_enable, |
| 61 | .pktlog_setsize = pktlog_setsize, |
| 62 | .pktlog_disable = pktlog_disable, /* valid for f/w disable */ |
| 63 | }; |
| 64 | |
| 65 | struct ol_pktlog_dev_t ol_pl_dev = { |
| 66 | .pl_funcs = &ol_pl_funcs, |
| 67 | }; |
| 68 | |
Komal Seelam | 3d20286 | 2016-02-24 18:43:24 +0530 | [diff] [blame] | 69 | void ol_pl_sethandle(ol_pktlog_dev_handle *pl_handle, |
| 70 | struct hif_opaque_softc *scn) |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 71 | { |
| 72 | ol_pl_dev.scn = (ol_ath_generic_softc_handle) scn; |
| 73 | *pl_handle = &ol_pl_dev; |
| 74 | } |
| 75 | |
| 76 | static A_STATUS pktlog_wma_post_msg(WMI_PKTLOG_EVENT event_types, |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 77 | WMI_CMD_ID cmd_id, bool ini_triggered, |
| 78 | uint8_t user_triggered) |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 79 | { |
Rajeev Kumar | 15cf7ab | 2017-01-21 15:52:36 -0800 | [diff] [blame] | 80 | struct scheduler_msg msg = { 0 }; |
Anurag Chouhan | fb54ab0 | 2016-02-18 18:00:46 +0530 | [diff] [blame] | 81 | QDF_STATUS status; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 82 | struct ath_pktlog_wmi_params *param; |
| 83 | |
Anurag Chouhan | 600c3a0 | 2016-03-01 10:33:54 +0530 | [diff] [blame] | 84 | param = qdf_mem_malloc(sizeof(struct ath_pktlog_wmi_params)); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 85 | |
| 86 | if (!param) |
| 87 | return A_NO_MEMORY; |
| 88 | |
| 89 | param->cmd_id = cmd_id; |
| 90 | param->pktlog_event = event_types; |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 91 | param->ini_triggered = ini_triggered; |
| 92 | param->user_triggered = user_triggered; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 93 | |
| 94 | msg.type = WMA_PKTLOG_ENABLE_REQ; |
| 95 | msg.bodyptr = param; |
| 96 | msg.bodyval = 0; |
| 97 | |
Rajeev Kumar | 15cf7ab | 2017-01-21 15:52:36 -0800 | [diff] [blame] | 98 | status = scheduler_post_msg(QDF_MODULE_ID_WMA, &msg); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 99 | |
Anurag Chouhan | fb54ab0 | 2016-02-18 18:00:46 +0530 | [diff] [blame] | 100 | if (status != QDF_STATUS_SUCCESS) { |
Anurag Chouhan | 600c3a0 | 2016-03-01 10:33:54 +0530 | [diff] [blame] | 101 | qdf_mem_free(param); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 102 | return A_ERROR; |
| 103 | } |
| 104 | |
| 105 | return A_OK; |
| 106 | } |
| 107 | |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 108 | static inline A_STATUS |
| 109 | pktlog_enable_tgt(struct hif_opaque_softc *_scn, uint32_t log_state, |
| 110 | bool ini_triggered, uint8_t user_triggered) |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 111 | { |
| 112 | uint32_t types = 0; |
| 113 | |
| 114 | if (log_state & ATH_PKTLOG_TX) |
| 115 | types |= WMI_PKTLOG_EVENT_TX; |
| 116 | |
| 117 | if (log_state & ATH_PKTLOG_RX) |
| 118 | types |= WMI_PKTLOG_EVENT_RX; |
| 119 | |
| 120 | if (log_state & ATH_PKTLOG_RCFIND) |
| 121 | types |= WMI_PKTLOG_EVENT_RCF; |
| 122 | |
| 123 | if (log_state & ATH_PKTLOG_RCUPDATE) |
| 124 | types |= WMI_PKTLOG_EVENT_RCU; |
| 125 | |
Nirav Shah | dcc4c87 | 2016-07-28 11:35:26 +0530 | [diff] [blame] | 126 | if (log_state & ATH_PKTLOG_SW_EVENT) |
| 127 | types |= WMI_PKTLOG_EVENT_SW; |
| 128 | |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 129 | return pktlog_wma_post_msg(types, WMI_PDEV_PKTLOG_ENABLE_CMDID, |
| 130 | ini_triggered, user_triggered); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 131 | } |
| 132 | |
| 133 | static inline A_STATUS |
| 134 | wdi_pktlog_subscribe(struct ol_txrx_pdev_t *txrx_pdev, int32_t log_state) |
| 135 | { |
| 136 | if (!txrx_pdev) { |
| 137 | printk("Invalid pdev in %s\n", __func__); |
| 138 | return A_ERROR; |
| 139 | } |
| 140 | if (log_state & ATH_PKTLOG_TX) { |
| 141 | if (wdi_event_sub(txrx_pdev, |
| 142 | &PKTLOG_TX_SUBSCRIBER, WDI_EVENT_TX_STATUS)) { |
| 143 | return A_ERROR; |
| 144 | } |
| 145 | } |
| 146 | if (log_state & ATH_PKTLOG_RX) { |
| 147 | if (wdi_event_sub(txrx_pdev, |
| 148 | &PKTLOG_RX_SUBSCRIBER, WDI_EVENT_RX_DESC)) { |
| 149 | return A_ERROR; |
| 150 | } |
| 151 | if (wdi_event_sub(txrx_pdev, |
| 152 | &PKTLOG_RX_REMOTE_SUBSCRIBER, |
| 153 | WDI_EVENT_RX_DESC_REMOTE)) { |
| 154 | return A_ERROR; |
| 155 | } |
| 156 | } |
| 157 | if (log_state & ATH_PKTLOG_RCFIND) { |
| 158 | if (wdi_event_sub(txrx_pdev, |
| 159 | &PKTLOG_RCFIND_SUBSCRIBER, |
| 160 | WDI_EVENT_RATE_FIND)) { |
| 161 | return A_ERROR; |
| 162 | } |
| 163 | } |
| 164 | if (log_state & ATH_PKTLOG_RCUPDATE) { |
| 165 | if (wdi_event_sub(txrx_pdev, |
| 166 | &PKTLOG_RCUPDATE_SUBSCRIBER, |
| 167 | WDI_EVENT_RATE_UPDATE)) { |
| 168 | return A_ERROR; |
| 169 | } |
| 170 | } |
Nirav Shah | dcc4c87 | 2016-07-28 11:35:26 +0530 | [diff] [blame] | 171 | if (log_state & ATH_PKTLOG_SW_EVENT) { |
| 172 | if (wdi_event_sub(txrx_pdev, |
| 173 | &PKTLOG_SW_EVENT_SUBSCRIBER, |
| 174 | WDI_EVENT_SW_EVENT)) { |
| 175 | return A_ERROR; |
| 176 | } |
| 177 | } |
| 178 | |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 179 | return A_OK; |
| 180 | } |
| 181 | |
| 182 | void pktlog_callback(void *pdev, enum WDI_EVENT event, void *log_data) |
| 183 | { |
| 184 | switch (event) { |
| 185 | case WDI_EVENT_TX_STATUS: |
| 186 | { |
| 187 | /* |
| 188 | * process TX message |
| 189 | */ |
| 190 | if (process_tx_info(pdev, log_data)) { |
| 191 | printk("Unable to process TX info\n"); |
| 192 | return; |
| 193 | } |
| 194 | break; |
| 195 | } |
| 196 | case WDI_EVENT_RX_DESC: |
| 197 | { |
| 198 | /* |
| 199 | * process RX message for local frames |
| 200 | */ |
| 201 | if (process_rx_info(pdev, log_data)) { |
| 202 | printk("Unable to process RX info\n"); |
| 203 | return; |
| 204 | } |
| 205 | break; |
| 206 | } |
| 207 | case WDI_EVENT_RX_DESC_REMOTE: |
| 208 | { |
| 209 | /* |
| 210 | * process RX message for remote frames |
| 211 | */ |
| 212 | if (process_rx_info_remote(pdev, log_data)) { |
| 213 | printk("Unable to process RX info\n"); |
| 214 | return; |
| 215 | } |
| 216 | break; |
| 217 | } |
| 218 | case WDI_EVENT_RATE_FIND: |
| 219 | { |
| 220 | /* |
| 221 | * process RATE_FIND message |
| 222 | */ |
| 223 | if (process_rate_find(pdev, log_data)) { |
| 224 | printk("Unable to process RC_FIND info\n"); |
| 225 | return; |
| 226 | } |
| 227 | break; |
| 228 | } |
| 229 | case WDI_EVENT_RATE_UPDATE: |
| 230 | { |
| 231 | /* |
| 232 | * process RATE_UPDATE message |
| 233 | */ |
| 234 | if (process_rate_update(pdev, log_data)) { |
| 235 | printk("Unable to process RC_UPDATE\n"); |
| 236 | return; |
| 237 | } |
| 238 | break; |
| 239 | } |
Nirav Shah | dcc4c87 | 2016-07-28 11:35:26 +0530 | [diff] [blame] | 240 | case WDI_EVENT_SW_EVENT: |
| 241 | { |
| 242 | /* |
| 243 | * process SW EVENT message |
| 244 | */ |
| 245 | if (process_sw_event(pdev, log_data)) { |
| 246 | printk("Unable to process SW_EVENT\n"); |
| 247 | return; |
| 248 | } |
| 249 | break; |
| 250 | } |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 251 | default: |
| 252 | break; |
| 253 | } |
| 254 | } |
| 255 | |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 256 | A_STATUS |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 257 | wdi_pktlog_unsubscribe(struct ol_txrx_pdev_t *txrx_pdev, uint32_t log_state) |
| 258 | { |
| 259 | if (log_state & ATH_PKTLOG_TX) { |
| 260 | if (wdi_event_unsub(txrx_pdev, |
| 261 | &PKTLOG_TX_SUBSCRIBER, |
| 262 | WDI_EVENT_TX_STATUS)) { |
| 263 | return A_ERROR; |
| 264 | } |
| 265 | } |
| 266 | if (log_state & ATH_PKTLOG_RX) { |
| 267 | if (wdi_event_unsub(txrx_pdev, |
| 268 | &PKTLOG_RX_SUBSCRIBER, WDI_EVENT_RX_DESC)) { |
| 269 | return A_ERROR; |
| 270 | } |
| 271 | if (wdi_event_unsub(txrx_pdev, |
| 272 | &PKTLOG_RX_REMOTE_SUBSCRIBER, |
| 273 | WDI_EVENT_RX_DESC_REMOTE)) { |
| 274 | return A_ERROR; |
| 275 | } |
| 276 | } |
| 277 | if (log_state & ATH_PKTLOG_RCFIND) { |
| 278 | if (wdi_event_unsub(txrx_pdev, |
| 279 | &PKTLOG_RCFIND_SUBSCRIBER, |
| 280 | WDI_EVENT_RATE_FIND)) { |
| 281 | return A_ERROR; |
| 282 | } |
| 283 | } |
| 284 | if (log_state & ATH_PKTLOG_RCUPDATE) { |
| 285 | if (wdi_event_unsub(txrx_pdev, |
| 286 | &PKTLOG_RCUPDATE_SUBSCRIBER, |
| 287 | WDI_EVENT_RATE_UPDATE)) { |
| 288 | return A_ERROR; |
| 289 | } |
| 290 | } |
Nirav Shah | dcc4c87 | 2016-07-28 11:35:26 +0530 | [diff] [blame] | 291 | if (log_state & ATH_PKTLOG_RCUPDATE) { |
| 292 | if (wdi_event_unsub(txrx_pdev, |
| 293 | &PKTLOG_SW_EVENT_SUBSCRIBER, |
| 294 | WDI_EVENT_SW_EVENT)) { |
| 295 | return A_ERROR; |
| 296 | } |
| 297 | } |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 298 | return A_OK; |
| 299 | } |
| 300 | |
Komal Seelam | 3d20286 | 2016-02-24 18:43:24 +0530 | [diff] [blame] | 301 | int pktlog_disable(struct hif_opaque_softc *scn) |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 302 | { |
| 303 | struct ol_txrx_pdev_t *txrx_pdev = |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame] | 304 | cds_get_context(QDF_MODULE_ID_TXRX); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 305 | struct ol_pktlog_dev_t *pl_dev; |
| 306 | struct ath_pktlog_info *pl_info; |
| 307 | |
| 308 | if (txrx_pdev == NULL || |
| 309 | txrx_pdev->pl_dev == NULL || |
| 310 | txrx_pdev->pl_dev->pl_info == NULL) |
| 311 | return -EFAULT; |
| 312 | |
| 313 | pl_dev = txrx_pdev->pl_dev; |
| 314 | pl_info = pl_dev->pl_info; |
| 315 | |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 316 | if (pktlog_wma_post_msg(0, WMI_PDEV_PKTLOG_DISABLE_CMDID, 0, 0)) { |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 317 | printk("Failed to disable pktlog in target\n"); |
| 318 | return -1; |
| 319 | } |
| 320 | |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 321 | if (pl_dev->is_pktlog_cb_subscribed && |
| 322 | wdi_pktlog_unsubscribe(txrx_pdev, pl_info->log_state)) { |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 323 | printk("Cannot unsubscribe pktlog from the WDI\n"); |
| 324 | return -1; |
| 325 | } |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 326 | pl_dev->is_pktlog_cb_subscribed = false; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 327 | return 0; |
| 328 | } |
| 329 | |
Komal Seelam | 3d20286 | 2016-02-24 18:43:24 +0530 | [diff] [blame] | 330 | void pktlog_init(struct hif_opaque_softc *scn) |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 331 | { |
| 332 | struct ath_pktlog_info *pl_info; |
| 333 | ol_txrx_pdev_handle pdev_txrx_handle; |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame] | 334 | pdev_txrx_handle = cds_get_context(QDF_MODULE_ID_TXRX); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 335 | |
| 336 | if (pdev_txrx_handle == NULL || |
| 337 | pdev_txrx_handle->pl_dev == NULL || |
| 338 | pdev_txrx_handle->pl_dev->pl_info == NULL) |
| 339 | return; |
| 340 | |
| 341 | pl_info = pdev_txrx_handle->pl_dev->pl_info; |
| 342 | |
| 343 | OS_MEMZERO(pl_info, sizeof(*pl_info)); |
| 344 | PKTLOG_LOCK_INIT(pl_info); |
| 345 | |
| 346 | pl_info->buf_size = PKTLOG_DEFAULT_BUFSIZE; |
| 347 | pl_info->buf = NULL; |
| 348 | pl_info->log_state = 0; |
| 349 | pl_info->sack_thr = PKTLOG_DEFAULT_SACK_THR; |
| 350 | pl_info->tail_length = PKTLOG_DEFAULT_TAIL_LENGTH; |
| 351 | pl_info->thruput_thresh = PKTLOG_DEFAULT_THRUPUT_THRESH; |
| 352 | pl_info->per_thresh = PKTLOG_DEFAULT_PER_THRESH; |
| 353 | pl_info->phyerr_thresh = PKTLOG_DEFAULT_PHYERR_THRESH; |
| 354 | pl_info->trigger_interval = PKTLOG_DEFAULT_TRIGGER_INTERVAL; |
| 355 | pl_info->pktlen = 0; |
| 356 | pl_info->start_time_thruput = 0; |
| 357 | pl_info->start_time_per = 0; |
Poddar, Siddarth | eefe348 | 2016-09-21 18:12:59 +0530 | [diff] [blame] | 358 | pdev_txrx_handle->pl_dev->vendor_cmd_send = false; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 359 | |
| 360 | PKTLOG_TX_SUBSCRIBER.callback = pktlog_callback; |
| 361 | PKTLOG_RX_SUBSCRIBER.callback = pktlog_callback; |
| 362 | PKTLOG_RX_REMOTE_SUBSCRIBER.callback = pktlog_callback; |
| 363 | PKTLOG_RCFIND_SUBSCRIBER.callback = pktlog_callback; |
| 364 | PKTLOG_RCUPDATE_SUBSCRIBER.callback = pktlog_callback; |
Nirav Shah | dcc4c87 | 2016-07-28 11:35:26 +0530 | [diff] [blame] | 365 | PKTLOG_SW_EVENT_SUBSCRIBER.callback = pktlog_callback; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 366 | } |
| 367 | |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 368 | int pktlog_enable(struct hif_opaque_softc *scn, int32_t log_state, |
Poddar, Siddarth | eefe348 | 2016-09-21 18:12:59 +0530 | [diff] [blame] | 369 | bool ini_triggered, uint8_t user_triggered, |
| 370 | uint32_t is_iwpriv_command) |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 371 | { |
| 372 | struct ol_pktlog_dev_t *pl_dev; |
| 373 | struct ath_pktlog_info *pl_info; |
| 374 | struct ol_txrx_pdev_t *txrx_pdev; |
| 375 | int error; |
| 376 | |
| 377 | if (!scn) { |
| 378 | printk("%s: Invalid scn context\n", __func__); |
| 379 | ASSERT(0); |
| 380 | return -1; |
| 381 | } |
| 382 | |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame] | 383 | txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 384 | if (!txrx_pdev) { |
| 385 | printk("%s: Invalid txrx_pdev context\n", __func__); |
| 386 | ASSERT(0); |
| 387 | return -1; |
| 388 | } |
| 389 | |
| 390 | pl_dev = txrx_pdev->pl_dev; |
| 391 | if (!pl_dev) { |
| 392 | printk("%s: Invalid pktlog context\n", __func__); |
| 393 | ASSERT(0); |
| 394 | return -1; |
| 395 | } |
| 396 | |
| 397 | pl_info = pl_dev->pl_info; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 398 | |
| 399 | if (!pl_info) |
| 400 | return 0; |
| 401 | |
Poddar, Siddarth | eefe348 | 2016-09-21 18:12:59 +0530 | [diff] [blame] | 402 | /* is_iwpriv_command : 0 indicates its a vendor command |
| 403 | * log_state: 0 indicates pktlog disable command |
| 404 | * vendor_cmd_send flag; false means no vendor pktlog enable |
| 405 | * command was sent previously |
| 406 | */ |
| 407 | if (is_iwpriv_command == 0 && log_state == 0 && |
| 408 | pl_dev->vendor_cmd_send == false) |
| 409 | return 0; |
| 410 | |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 411 | if (!pl_dev->tgt_pktlog_alloced) { |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 412 | if (pl_info->buf == NULL) { |
| 413 | error = pktlog_alloc_buf(scn); |
| 414 | |
| 415 | if (error != 0) |
| 416 | return error; |
| 417 | |
| 418 | if (!pl_info->buf) { |
| 419 | printk("%s: pktlog buf alloc failed\n", |
| 420 | __func__); |
| 421 | ASSERT(0); |
| 422 | return -1; |
| 423 | } |
| 424 | |
| 425 | } |
| 426 | |
| 427 | pl_info->buf->bufhdr.version = CUR_PKTLOG_VER; |
| 428 | pl_info->buf->bufhdr.magic_num = PKTLOG_MAGIC_NUM; |
| 429 | pl_info->buf->wr_offset = 0; |
| 430 | pl_info->buf->rd_offset = -1; |
| 431 | /* These below variables are used by per packet stats*/ |
| 432 | pl_info->buf->bytes_written = 0; |
| 433 | pl_info->buf->msg_index = 1; |
| 434 | pl_info->buf->offset = PKTLOG_READ_OFFSET; |
| 435 | |
| 436 | pl_info->start_time_thruput = os_get_timestamp(); |
| 437 | pl_info->start_time_per = pl_info->start_time_thruput; |
| 438 | |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 439 | pl_dev->tgt_pktlog_alloced = true; |
| 440 | } |
| 441 | |
| 442 | if (log_state != 0) { |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 443 | /* WDI subscribe */ |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 444 | if ((!pl_dev->is_pktlog_cb_subscribed) && |
| 445 | wdi_pktlog_subscribe(txrx_pdev, log_state)) { |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 446 | printk("Unable to subscribe to the WDI %s\n", __func__); |
| 447 | return -1; |
| 448 | } |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 449 | pl_dev->is_pktlog_cb_subscribed = true; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 450 | /* WMI command to enable pktlog on the firmware */ |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 451 | if (pktlog_enable_tgt(scn, log_state, ini_triggered, |
| 452 | user_triggered)) { |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 453 | printk("Device cannot be enabled, %s\n", __func__); |
| 454 | return -1; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 455 | } |
Poddar, Siddarth | eefe348 | 2016-09-21 18:12:59 +0530 | [diff] [blame] | 456 | |
| 457 | if (is_iwpriv_command == 0) |
| 458 | pl_dev->vendor_cmd_send = true; |
Poddar, Siddarth | 49fb4d7 | 2016-09-21 16:56:32 +0530 | [diff] [blame] | 459 | } else { |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 460 | pl_dev->pl_funcs->pktlog_disable(scn); |
Poddar, Siddarth | eefe348 | 2016-09-21 18:12:59 +0530 | [diff] [blame] | 461 | if (is_iwpriv_command == 0) |
| 462 | pl_dev->vendor_cmd_send = false; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 463 | } |
| 464 | |
| 465 | pl_info->log_state = log_state; |
| 466 | return 0; |
| 467 | } |
| 468 | |
Komal Seelam | 3d20286 | 2016-02-24 18:43:24 +0530 | [diff] [blame] | 469 | int pktlog_setsize(struct hif_opaque_softc *scn, int32_t size) |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 470 | { |
| 471 | ol_txrx_pdev_handle pdev_txrx_handle = |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame] | 472 | cds_get_context(QDF_MODULE_ID_TXRX); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 473 | struct ol_pktlog_dev_t *pl_dev; |
| 474 | struct ath_pktlog_info *pl_info; |
| 475 | |
| 476 | if (pdev_txrx_handle == NULL || |
| 477 | pdev_txrx_handle->pl_dev == NULL || |
| 478 | pdev_txrx_handle->pl_dev->pl_info == NULL) |
| 479 | return -EFAULT; |
| 480 | |
| 481 | pl_dev = pdev_txrx_handle->pl_dev; |
| 482 | pl_info = pl_dev->pl_info; |
| 483 | |
| 484 | if (size < 0) |
| 485 | return -EINVAL; |
| 486 | |
Poddar, Siddarth | 176c436 | 2016-10-03 12:25:00 +0530 | [diff] [blame] | 487 | if (size == pl_info->buf_size) { |
| 488 | qdf_print("%s: Pktlog Buff Size is already of same size.", |
| 489 | __func__); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 490 | return 0; |
Poddar, Siddarth | 176c436 | 2016-10-03 12:25:00 +0530 | [diff] [blame] | 491 | } |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 492 | |
| 493 | if (pl_info->log_state) { |
Poddar, Siddarth | 176c436 | 2016-10-03 12:25:00 +0530 | [diff] [blame] | 494 | qdf_print("%s: Logging should be disabled before changing" |
| 495 | "buffer size.", __func__); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 496 | return -EINVAL; |
| 497 | } |
| 498 | |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 499 | if (pl_info->buf != NULL) { |
| 500 | if (pl_dev->is_pktlog_cb_subscribed && |
| 501 | wdi_pktlog_unsubscribe(pdev_txrx_handle, |
| 502 | pl_info->log_state)) { |
| 503 | printk("Cannot unsubscribe pktlog from the WDI\n"); |
| 504 | return -EFAULT; |
| 505 | } |
Houston Hoffman | 8c48504 | 2017-02-08 13:40:21 -0800 | [diff] [blame] | 506 | pktlog_release_buf(pdev_txrx_handle); |
Srinivas Girigowda | c34f11d | 2016-02-25 16:02:42 -0800 | [diff] [blame] | 507 | pl_dev->is_pktlog_cb_subscribed = false; |
| 508 | pl_dev->tgt_pktlog_alloced = false; |
| 509 | } |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 510 | |
Poddar, Siddarth | 176c436 | 2016-10-03 12:25:00 +0530 | [diff] [blame] | 511 | if (size != 0) { |
| 512 | qdf_print("%s: New Pktlog Buff Size is %d\n", __func__, size); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 513 | pl_info->buf_size = size; |
Poddar, Siddarth | 176c436 | 2016-10-03 12:25:00 +0530 | [diff] [blame] | 514 | } |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 515 | |
| 516 | return 0; |
| 517 | } |
Nirav Shah | 7f337db | 2016-05-25 10:49:02 +0530 | [diff] [blame] | 518 | |
| 519 | /** |
| 520 | * pktlog_process_fw_msg() - process packetlog message |
| 521 | * @buff: buffer |
| 522 | * |
| 523 | * Return: None |
| 524 | */ |
| 525 | void pktlog_process_fw_msg(uint32_t *buff) |
| 526 | { |
| 527 | uint32_t *pl_hdr; |
| 528 | uint32_t log_type; |
| 529 | struct ol_txrx_pdev_t *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); |
| 530 | |
| 531 | if (!txrx_pdev) { |
| 532 | qdf_print("%s: txrx_pdev is NULL", __func__); |
| 533 | return; |
| 534 | } |
| 535 | |
| 536 | pl_hdr = buff; |
| 537 | log_type = |
| 538 | (*(pl_hdr + 1) & ATH_PKTLOG_HDR_LOG_TYPE_MASK) >> |
| 539 | ATH_PKTLOG_HDR_LOG_TYPE_SHIFT; |
| 540 | if ((log_type == PKTLOG_TYPE_TX_CTRL) |
| 541 | || (log_type == PKTLOG_TYPE_TX_STAT) |
| 542 | || (log_type == PKTLOG_TYPE_TX_MSDU_ID) |
| 543 | || (log_type == PKTLOG_TYPE_TX_FRM_HDR) |
| 544 | || (log_type == PKTLOG_TYPE_TX_VIRT_ADDR)) |
| 545 | wdi_event_handler(WDI_EVENT_TX_STATUS, |
| 546 | txrx_pdev, pl_hdr); |
| 547 | else if (log_type == PKTLOG_TYPE_RC_FIND) |
| 548 | wdi_event_handler(WDI_EVENT_RATE_FIND, |
| 549 | txrx_pdev, pl_hdr); |
| 550 | else if (log_type == PKTLOG_TYPE_RC_UPDATE) |
| 551 | wdi_event_handler(WDI_EVENT_RATE_UPDATE, |
| 552 | txrx_pdev, pl_hdr); |
| 553 | else if (log_type == PKTLOG_TYPE_RX_STAT) |
| 554 | wdi_event_handler(WDI_EVENT_RX_DESC, |
| 555 | txrx_pdev, pl_hdr); |
Nirav Shah | dcc4c87 | 2016-07-28 11:35:26 +0530 | [diff] [blame] | 556 | else if (log_type == PKTLOG_TYPE_SW_EVENT) |
| 557 | wdi_event_handler(WDI_EVENT_SW_EVENT, |
| 558 | txrx_pdev, pl_hdr); |
Nirav Shah | 7f337db | 2016-05-25 10:49:02 +0530 | [diff] [blame] | 559 | |
| 560 | } |
| 561 | |
Jeff Johnson | 3320c7f | 2016-11-22 16:00:45 -0800 | [diff] [blame] | 562 | #if defined(QCA_WIFI_3_0_ADRASTEA) |
Nirav Shah | 7f337db | 2016-05-25 10:49:02 +0530 | [diff] [blame] | 563 | /** |
| 564 | * pktlog_t2h_msg_handler() - Target to host message handler |
| 565 | * @context: pdev context |
| 566 | * @pkt: HTC packet |
| 567 | * |
| 568 | * Return: None |
| 569 | */ |
Jeff Johnson | 3320c7f | 2016-11-22 16:00:45 -0800 | [diff] [blame] | 570 | static void pktlog_t2h_msg_handler(void *context, HTC_PACKET *pkt) |
Nirav Shah | 7f337db | 2016-05-25 10:49:02 +0530 | [diff] [blame] | 571 | { |
| 572 | struct ol_pktlog_dev_t *pdev = (struct ol_pktlog_dev_t *)context; |
| 573 | qdf_nbuf_t pktlog_t2h_msg = (qdf_nbuf_t) pkt->pPktContext; |
| 574 | uint32_t *msg_word; |
| 575 | |
| 576 | /* check for successful message reception */ |
| 577 | if (pkt->Status != A_OK) { |
| 578 | if (pkt->Status != A_ECANCELED) |
| 579 | pdev->htc_err_cnt++; |
| 580 | qdf_nbuf_free(pktlog_t2h_msg); |
| 581 | return; |
| 582 | } |
| 583 | |
| 584 | /* confirm alignment */ |
| 585 | qdf_assert((((unsigned long)qdf_nbuf_data(pktlog_t2h_msg)) & 0x3) == 0); |
| 586 | |
| 587 | msg_word = (uint32_t *) qdf_nbuf_data(pktlog_t2h_msg); |
| 588 | pktlog_process_fw_msg(msg_word); |
| 589 | |
| 590 | qdf_nbuf_free(pktlog_t2h_msg); |
| 591 | } |
| 592 | |
| 593 | /** |
| 594 | * pktlog_tx_resume_handler() - resume callback |
| 595 | * @context: pdev context |
| 596 | * |
| 597 | * Return: None |
| 598 | */ |
Jeff Johnson | 3320c7f | 2016-11-22 16:00:45 -0800 | [diff] [blame] | 599 | static void pktlog_tx_resume_handler(void *context) |
Nirav Shah | 7f337db | 2016-05-25 10:49:02 +0530 | [diff] [blame] | 600 | { |
| 601 | qdf_print("%s: Not expected", __func__); |
| 602 | qdf_assert(0); |
| 603 | } |
| 604 | |
| 605 | /** |
| 606 | * pktlog_h2t_send_complete() - send complete indication |
| 607 | * @context: pdev context |
| 608 | * @htc_pkt: HTC packet |
| 609 | * |
| 610 | * Return: None |
| 611 | */ |
Jeff Johnson | 3320c7f | 2016-11-22 16:00:45 -0800 | [diff] [blame] | 612 | static void pktlog_h2t_send_complete(void *context, HTC_PACKET *htc_pkt) |
Nirav Shah | 7f337db | 2016-05-25 10:49:02 +0530 | [diff] [blame] | 613 | { |
| 614 | qdf_print("%s: Not expected", __func__); |
| 615 | qdf_assert(0); |
| 616 | } |
| 617 | |
| 618 | /** |
| 619 | * pktlog_h2t_full() - queue full indication |
| 620 | * @context: pdev context |
| 621 | * @pkt: HTC packet |
| 622 | * |
| 623 | * Return: HTC action |
| 624 | */ |
Jeff Johnson | 3320c7f | 2016-11-22 16:00:45 -0800 | [diff] [blame] | 625 | static HTC_SEND_FULL_ACTION pktlog_h2t_full(void *context, HTC_PACKET *pkt) |
Nirav Shah | 7f337db | 2016-05-25 10:49:02 +0530 | [diff] [blame] | 626 | { |
| 627 | return HTC_SEND_FULL_KEEP; |
| 628 | } |
| 629 | |
| 630 | /** |
| 631 | * pktlog_htc_connect_service() - create new endpoint for packetlog |
| 632 | * @pdev - pktlog pdev |
| 633 | * |
| 634 | * Return: 0 for success/failure |
| 635 | */ |
Jeff Johnson | 3320c7f | 2016-11-22 16:00:45 -0800 | [diff] [blame] | 636 | static int pktlog_htc_connect_service(struct ol_pktlog_dev_t *pdev) |
Nirav Shah | 7f337db | 2016-05-25 10:49:02 +0530 | [diff] [blame] | 637 | { |
| 638 | HTC_SERVICE_CONNECT_REQ connect; |
| 639 | HTC_SERVICE_CONNECT_RESP response; |
| 640 | A_STATUS status; |
| 641 | |
| 642 | qdf_mem_set(&connect, sizeof(connect), 0); |
| 643 | qdf_mem_set(&response, sizeof(response), 0); |
| 644 | |
| 645 | connect.pMetaData = NULL; |
| 646 | connect.MetaDataLength = 0; |
| 647 | connect.EpCallbacks.pContext = pdev; |
| 648 | connect.EpCallbacks.EpTxComplete = pktlog_h2t_send_complete; |
| 649 | connect.EpCallbacks.EpTxCompleteMultiple = NULL; |
| 650 | connect.EpCallbacks.EpRecv = pktlog_t2h_msg_handler; |
| 651 | connect.EpCallbacks.ep_resume_tx_queue = pktlog_tx_resume_handler; |
| 652 | |
| 653 | /* rx buffers currently are provided by HIF, not by EpRecvRefill */ |
| 654 | connect.EpCallbacks.EpRecvRefill = NULL; |
| 655 | connect.EpCallbacks.RecvRefillWaterMark = 1; |
| 656 | /* N/A, fill is done by HIF */ |
| 657 | |
| 658 | connect.EpCallbacks.EpSendFull = pktlog_h2t_full; |
| 659 | /* |
| 660 | * Specify how deep to let a queue get before htc_send_pkt will |
| 661 | * call the EpSendFull function due to excessive send queue depth. |
| 662 | */ |
| 663 | connect.MaxSendQueueDepth = PKTLOG_MAX_SEND_QUEUE_DEPTH; |
| 664 | |
| 665 | /* disable flow control for HTT data message service */ |
| 666 | connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL; |
| 667 | |
| 668 | /* connect to control service */ |
| 669 | connect.service_id = PACKET_LOG_SVC; |
| 670 | |
| 671 | status = htc_connect_service(pdev->htc_pdev, &connect, &response); |
| 672 | |
| 673 | if (status != A_OK) { |
| 674 | pdev->mt_pktlog_enabled = false; |
| 675 | return -EIO; /* failure */ |
| 676 | } |
| 677 | |
| 678 | pdev->htc_endpoint = response.Endpoint; |
| 679 | pdev->mt_pktlog_enabled = true; |
| 680 | |
| 681 | return 0; /* success */ |
| 682 | } |
| 683 | |
Nirav Shah | 7f337db | 2016-05-25 10:49:02 +0530 | [diff] [blame] | 684 | /** |
| 685 | * pktlog_htc_attach() - attach pktlog HTC service |
| 686 | * |
| 687 | * Return: 0 for success/failure |
| 688 | */ |
| 689 | int pktlog_htc_attach(void) |
| 690 | { |
| 691 | struct ol_txrx_pdev_t *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); |
| 692 | struct ol_pktlog_dev_t *pdev = NULL; |
| 693 | void *htc_pdev = cds_get_context(QDF_MODULE_ID_HTC); |
| 694 | |
| 695 | if ((!txrx_pdev) || (!txrx_pdev->pl_dev) || (!htc_pdev)) |
| 696 | return -EINVAL; |
| 697 | |
| 698 | pdev = txrx_pdev->pl_dev; |
| 699 | pdev->htc_pdev = htc_pdev; |
| 700 | return pktlog_htc_connect_service(pdev); |
| 701 | } |
| 702 | #else |
| 703 | int pktlog_htc_attach(void) |
| 704 | { |
| 705 | struct ol_txrx_pdev_t *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX); |
| 706 | struct ol_pktlog_dev_t *pdev = NULL; |
| 707 | |
| 708 | if (!txrx_pdev) |
| 709 | return -EINVAL; |
| 710 | pdev = txrx_pdev->pl_dev; |
| 711 | pdev->mt_pktlog_enabled = false; |
| 712 | return 0; |
| 713 | } |
| 714 | #endif |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 715 | #endif /* REMOVE_PKT_LOG */ |