void wmi_htc_tx_complete(void *ctx, HTC_PACKET *htc_pkt) { struct wmi_unified *wmi_handle = (struct wmi_unified *)ctx; wmi_buf_t wmi_cmd_buf = GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt); #ifdef WMI_INTERFACE_EVENT_LOGGING uint32_t cmd_id; #endif ASSERT(wmi_cmd_buf); #ifdef WMI_INTERFACE_EVENT_LOGGING cmd_id = WMI_GET_FIELD(cdf_nbuf_data(wmi_cmd_buf), WMI_CMD_HDR, COMMANDID); #ifdef QCA_WIFI_3_0_EMU printk("\nSent WMI command:%s command_id:0x%x over dma and recieved tx complete interupt\n", get_wmi_cmd_string(cmd_id), cmd_id); #endif cdf_spin_lock_bh(&wmi_handle->wmi_record_lock); /* Record 16 bytes of WMI cmd tx complete data - exclude TLV and WMI headers */ if (cmd_id == WMI_MGMT_TX_SEND_CMDID) { WMI_MGMT_COMMAND_TX_CMP_RECORD(cmd_id, ((uint32_t *) cdf_nbuf_data(wmi_cmd_buf) + 2)); } else { WMI_COMMAND_TX_CMP_RECORD(cmd_id, ((uint32_t *) cdf_nbuf_data(wmi_cmd_buf) + 2)); } cdf_spin_unlock_bh(&wmi_handle->wmi_record_lock); #endif cdf_nbuf_free(wmi_cmd_buf); cdf_mem_free(htc_pkt); cdf_atomic_dec(&wmi_handle->pending_cmds); }
/* WMI command API */ int wmi_unified_cmd_send(wmi_unified_t wmi_handle, wmi_buf_t buf, int len, WMI_CMD_ID cmd_id) { HTC_PACKET *pkt; A_STATUS status; void *vos_context; struct ol_softc *scn; A_UINT16 htc_tag = 0; if (wmi_get_runtime_pm_inprogress(wmi_handle)) goto skip_suspend_check; if (adf_os_atomic_read(&wmi_handle->is_target_suspended) && ( (WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID != cmd_id) && (WMI_PDEV_RESUME_CMDID != cmd_id)) ) { pr_err("%s: Target is suspended could not send WMI command: %d\n", __func__, cmd_id); VOS_ASSERT(0); return -EBUSY; } else goto dont_tag; skip_suspend_check: switch(cmd_id) { case WMI_WOW_ENABLE_CMDID: case WMI_PDEV_SUSPEND_CMDID: case WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID: case WMI_WOW_ADD_WAKE_PATTERN_CMDID: case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID: case WMI_PDEV_RESUME_CMDID: case WMI_WOW_DEL_WAKE_PATTERN_CMDID: #ifdef FEATURE_WLAN_D0WOW case WMI_D0_WOW_ENABLE_DISABLE_CMDID: #endif htc_tag = HTC_TX_PACKET_TAG_AUTO_PM; default: break; } dont_tag: /* Do sanity check on the TLV parameter structure */ { void *buf_ptr = (void *) adf_nbuf_data(buf); if (wmitlv_check_command_tlv_params(NULL, buf_ptr, len, cmd_id) != 0) { adf_os_print("\nERROR: %s: Invalid WMI Parameter Buffer for Cmd:%d\n", __func__, cmd_id); return -1; } } if (adf_nbuf_push_head(buf, sizeof(WMI_CMD_HDR)) == NULL) { pr_err("%s, Failed to send cmd %x, no memory\n", __func__, cmd_id); return -ENOMEM; } WMI_SET_FIELD(adf_nbuf_data(buf), WMI_CMD_HDR, COMMANDID, cmd_id); adf_os_atomic_inc(&wmi_handle->pending_cmds); if (adf_os_atomic_read(&wmi_handle->pending_cmds) >= WMI_MAX_CMDS) { vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); scn = vos_get_context(VOS_MODULE_ID_HIF, vos_context); pr_err("\n%s: hostcredits = %d\n", __func__, wmi_get_host_credits(wmi_handle)); HTC_dump_counter_info(wmi_handle->htc_handle); //dump_CE_register(scn); //dump_CE_debug_register(scn->hif_sc); adf_os_atomic_dec(&wmi_handle->pending_cmds); pr_err("%s: MAX 1024 WMI Pending cmds reached.\n", __func__); vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); schedule_work(&recovery_work); return -EBUSY; } pkt = adf_os_mem_alloc(NULL, sizeof(*pkt)); if (!pkt) { adf_os_atomic_dec(&wmi_handle->pending_cmds); pr_err("%s, Failed to alloc htc packet %x, no memory\n", __func__, cmd_id); return -ENOMEM; } SET_HTC_PACKET_INFO_TX(pkt, NULL, adf_nbuf_data(buf), len + sizeof(WMI_CMD_HDR), /* htt_host_data_dl_len(buf)+20 */ wmi_handle->wmi_endpoint_id, htc_tag); SET_HTC_PACKET_NET_BUF_CONTEXT(pkt, buf); WMA_LOGD("Send WMI command:%s command_id:%d", get_wmi_cmd_string(cmd_id), cmd_id); #ifdef WMI_INTERFACE_EVENT_LOGGING adf_os_spin_lock_bh(&wmi_handle->wmi_record_lock); /*Record 16 bytes of WMI cmd data - exclude TLV and WMI headers*/ WMI_COMMAND_RECORD(cmd_id ,((u_int32_t *)adf_nbuf_data(buf) + 2)); adf_os_spin_unlock_bh(&wmi_handle->wmi_record_lock); #endif status = HTCSendPkt(wmi_handle->htc_handle, pkt); if (A_OK != status) { adf_os_atomic_dec(&wmi_handle->pending_cmds); pr_err("%s %d, HTCSendPkt failed\n", __func__, __LINE__); } return ((status == A_OK) ? EOK : -1); }
static inline void wma_log_cmd_id(WMI_CMD_ID cmd_id) { WMA_LOGD("Send WMI command:%s command_id:%d", get_wmi_cmd_string(cmd_id), cmd_id); }