A_STATUS htt_h2t_sync_msg(struct htt_pdev_t *pdev, u_int8_t sync_cnt) { struct htt_htc_pkt *pkt; adf_nbuf_t msg; u_int32_t *msg_word; pkt = htt_htc_pkt_alloc(pdev); if (!pkt) { return A_NO_MEMORY; } /* show that this is not a tx frame download (not required, but helpful) */ pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; pkt->pdev_ctxt = NULL; /* not used during send-done callback */ msg = adf_nbuf_alloc( pdev->osdev, HTT_MSG_BUF_SIZE(HTT_H2T_SYNC_MSG_SZ), /* reserve room for HTC header */ HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, FALSE); if (!msg) { htt_htc_pkt_free(pdev, pkt); return A_NO_MEMORY; } /* set the length of the message */ adf_nbuf_put_tail(msg, HTT_H2T_SYNC_MSG_SZ); /* fill in the message contents */ msg_word = (u_int32_t *) adf_nbuf_data(msg); /* rewind beyond alignment pad to get to the HTC header reserved area */ adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); *msg_word = 0; HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_SYNC); HTT_H2T_SYNC_COUNT_SET(*msg_word, sync_cnt); SET_HTC_PACKET_INFO_TX( &pkt->htc_pkt, htt_h2t_send_complete_free_netbuf, adf_nbuf_data(msg), adf_nbuf_len(msg), pdev->htc_endpoint, HTC_TX_PACKET_TAG_RUNTIME_PUT); SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); #ifdef ATH_11AC_TXCOMPACT if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) htt_htc_misc_pkt_list_add(pdev, pkt); #else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); #endif if ((pdev->cfg.is_high_latency) && (!pdev->cfg.default_tx_comp_req)) { ol_tx_target_credit_update(pdev->txrx_pdev, -1); } return A_OK; }
int htt_h2t_ipa_uc_get_stats(struct htt_pdev_t *pdev) { struct htt_htc_pkt *pkt = NULL; adf_nbuf_t msg = NULL; u_int32_t *msg_word; /* New buffer alloc send */ pkt = htt_htc_pkt_alloc(pdev); if (!pkt) { return A_NO_MEMORY; } /* show that this is not a tx frame download (not required, * but helpful) */ pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; pkt->pdev_ctxt = NULL; /* not used during send-done callback */ msg = adf_nbuf_alloc( pdev->osdev, HTT_MSG_BUF_SIZE(HTT_WDI_IPA_OP_REQUEST_SZ), /* reserve room for HTC header */ HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, FALSE); if (!msg) { htt_htc_pkt_free(pdev, pkt); return A_NO_MEMORY; } /* set the length of the message */ adf_nbuf_put_tail(msg, HTT_WDI_IPA_OP_REQUEST_SZ); /* rewind beyond alignment pad to get to the HTC header reserved area */ adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); /* fill in the message contents */ msg_word = (u_int32_t *) adf_nbuf_data(msg); *msg_word = 0; HTT_WDI_IPA_OP_REQUEST_OP_CODE_SET(*msg_word, HTT_WDI_IPA_OPCODE_DBG_STATS); HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ); SET_HTC_PACKET_INFO_TX( &pkt->htc_pkt, htt_h2t_send_complete_free_netbuf, adf_nbuf_data(msg), adf_nbuf_len(msg), pdev->htc_endpoint, 1); /* tag - not relevant here */ SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); #ifdef ATH_11AC_TXCOMPACT if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) htt_htc_misc_pkt_list_add(pdev, pkt); #else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); #endif return A_OK; }
/* WMI command API */ int wmi_unified_cmd_send(wmi_unified_t wmi_handle, wmi_buf_t buf, int len, WMI_CMD_ID cmd_id) { A_STATUS status; struct cookie *cookie; if (wbuf_push(buf, sizeof(WMI_CMD_HDR)) == NULL) { return -ENOMEM; } WMI_SET_FIELD(wbuf_header(buf), WMI_CMD_HDR, COMMANDID, cmd_id); //WMI_CMD_HDR_SET_DEVID(cmd_hdr, 0); // unused cookie = ol_alloc_cookie(wmi_handle); if (!cookie) { return -ENOMEM; } cookie->PacketContext = buf; SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, cookie, wbuf_header(buf), len+sizeof(WMI_CMD_HDR), /* htt_host_data_dl_len(buf)+20 */ wmi_handle->wmi_endpoint_id, 0/*htc_tag*/); SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, buf); status = HTCSendPkt(wmi_handle->htc_handle, &cookie->HtcPkt); return ((status == A_OK) ? EOK : -1); }
A_STATUS HTCStart(HTC_HANDLE HTCHandle) { adf_nbuf_t netbuf; A_STATUS status = A_OK; HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); HTC_SETUP_COMPLETE_EX_MSG *pSetupComp; HTC_PACKET *pSendPacket; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n")); do { HTCConfigTargetHIFPipe(target); /* allocate a buffer to send */ pSendPacket = HTCAllocControlTxPacket(target); if (NULL == pSendPacket) { AR_DEBUG_ASSERT(FALSE); adf_os_print("%s: allocControlTxPacket failed\n",__func__); status = A_NO_MEMORY; break; } netbuf = (adf_nbuf_t)GET_HTC_PACKET_NET_BUF_CONTEXT(pSendPacket); /* assemble setup complete message */ adf_nbuf_put_tail(netbuf, sizeof(HTC_SETUP_COMPLETE_EX_MSG)); pSetupComp = (HTC_SETUP_COMPLETE_EX_MSG *) adf_nbuf_data(netbuf); A_MEMZERO(pSetupComp,sizeof(HTC_SETUP_COMPLETE_EX_MSG)); HTC_SET_FIELD(pSetupComp, HTC_SETUP_COMPLETE_EX_MSG, MESSAGEID, HTC_MSG_SETUP_COMPLETE_EX_ID); //if (!htc_credit_flow) { if (0) { AR_DEBUG_PRINTF(ATH_DEBUG_INIT, ("HTC will not use TX credit flow control\n")); pSetupComp->SetupFlags |= HTC_SETUP_COMPLETE_FLAGS_DISABLE_TX_CREDIT_FLOW; } else { AR_DEBUG_PRINTF(ATH_DEBUG_INIT, ("HTC using TX credit flow control\n")); } SET_HTC_PACKET_INFO_TX(pSendPacket, NULL, (A_UINT8 *)pSetupComp, sizeof(HTC_SETUP_COMPLETE_EX_MSG), ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); status = HTCSendPkt((HTC_HANDLE)target,pSendPacket); if (A_FAILED(status)) { break; } } while (FALSE); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n")); return status; }
void epping_tx_dup_pkt(epping_adapter_t *pAdapter, HTC_ENDPOINT_ID eid, adf_nbuf_t skb) { struct epping_cookie * cookie = NULL; int skb_len, ret; adf_nbuf_t new_skb; cookie = epping_alloc_cookie(pAdapter->pEpping_ctx); if (cookie == NULL) { EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: epping_alloc_cookie returns no resource\n", __func__); return; } new_skb = adf_nbuf_copy(skb); if (!new_skb) { EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: adf_nbuf_copy returns no resource\n", __func__); epping_free_cookie(pAdapter->pEpping_ctx, cookie); return; } SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, cookie, adf_nbuf_data(skb), adf_nbuf_len(new_skb), eid, 0); SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, new_skb); skb_len = (int)adf_nbuf_len(new_skb); /* send the packet */ ret = HTCSendPkt(pAdapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt); if (ret != A_OK) { EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: HTCSendPkt failed, ret = %d\n", __func__, ret); epping_free_cookie(pAdapter->pEpping_ctx, cookie); adf_nbuf_free(new_skb); return; } pAdapter->stats.tx_bytes += skb_len; ++pAdapter->stats.tx_packets; if (((pAdapter->stats.tx_packets + pAdapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 && (pAdapter->stats.tx_packets || pAdapter->stats.tx_dropped)) { epping_log_stats(pAdapter, __func__); } }
A_STATUS CAR6KMini::WMISendControlPacket( IN PVOID osbuf, HTC_ENDPOINT_ID Endpoint) { A_STATUS status; ndis_mini_buf_t *pNb; pNb = (ndis_mini_buf_t *)osbuf; SET_HTC_PACKET_INFO_TX(&pNb->HtcPacket, osbuf, a_netbuf_to_data(osbuf), a_netbuf_to_len(osbuf), Endpoint, AR6K_CONTROL_PKT_TAG); status = HTCSendPkt(m_pHTCTarget, &pNb->HtcPacket); if (A_OK != status && A_PENDING != status && m_ControlEp != Endpoint) NdisInterlockedDecrement(&m_TxPending); return status; }
/* 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); }
ssize_t ar6000_htc_raw_write(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID, char __user *buffer, size_t length) { int writePtr; raw_htc_buffer *free; AR_RAW_HTC_T *arRaw = ar->arRawHtc; if (arRawStream2EndpointID(ar,StreamID) == 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID)); return -EFAULT; } if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) { return -ERESTARTSYS; } /* Search for a free buffer */ free = get_free_buffer(ar,StreamID); /* Check if there is space to write else wait */ while (!arRaw->write_buffer_available[StreamID]) { up(&arRaw->raw_htc_write_sem[StreamID]); /* Wait for buffer to become free */ AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) write process\n", StreamID)); if (wait_event_interruptible(arRaw->raw_htc_write_queue[StreamID], arRaw->write_buffer_available[StreamID])) { return -EINTR; } if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) { return -ERESTARTSYS; } free = get_free_buffer(ar,StreamID); } /* Send the data */ writePtr = HTC_HEADER_LEN; if (length > (HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN)) { length = HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN; } if (copy_from_user(&free->data[writePtr], buffer, length)) { up(&arRaw->raw_htc_read_sem[StreamID]); return -EFAULT; } free->length = length; SET_HTC_PACKET_INFO_TX(&free->HTCPacket, free, &free->data[writePtr], length, arRawStream2EndpointID(ar,StreamID), AR6K_DATA_PKT_TAG); HTCSendPkt(ar->arHtcTarget,&free->HTCPacket); arRaw->write_buffer_available[StreamID] = FALSE; up(&arRaw->raw_htc_write_sem[StreamID]); return length; }
A_STATUS htt_h2t_rx_ring_cfg_msg_hl(struct htt_pdev_t *pdev) { struct htt_htc_pkt *pkt; adf_nbuf_t msg; u_int32_t *msg_word; pkt = htt_htc_pkt_alloc(pdev); if (!pkt) { return A_ERROR; /* failure */ } /* show that this is not a tx frame download (not required, but helpful) */ pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; pkt->pdev_ctxt = NULL; /* not used during send-done callback */ msg = adf_nbuf_alloc( pdev->osdev, HTT_MSG_BUF_SIZE(HTT_RX_RING_CFG_BYTES(1)), /* reserve room for the HTC header */ HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE); if (!msg) { htt_htc_pkt_free(pdev, pkt); return A_ERROR; /* failure */ } /* * Set the length of the message. * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added * separately during the below call to adf_nbuf_push_head. * The contribution from the HTC header is added separately inside HTC. */ adf_nbuf_put_tail(msg, HTT_RX_RING_CFG_BYTES(1)); /* fill in the message contents */ msg_word = (u_int32_t *) adf_nbuf_data(msg); /* rewind beyond alignment pad to get to the HTC header reserved area */ adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); *msg_word = 0; HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_RING_CFG); HTT_RX_RING_CFG_NUM_RINGS_SET(*msg_word, 1); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_SET( *msg_word, pdev->rx_ring.alloc_idx.paddr); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_BASE_PADDR_SET(*msg_word, pdev->rx_ring.base_paddr); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_LEN_SET(*msg_word, pdev->rx_ring.size); HTT_RX_RING_CFG_BUF_SZ_SET(*msg_word, HTT_RX_BUF_SIZE); /* FIX THIS: if the FW creates a complete translated rx descriptor, then the MAC DMA of the HW rx descriptor should be disabled. */ msg_word++; *msg_word = 0; HTT_RX_RING_CFG_ENABLED_802_11_HDR_SET(*msg_word, 0); HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_SET(*msg_word, 1); HTT_RX_RING_CFG_ENABLED_PPDU_START_SET(*msg_word, 0); HTT_RX_RING_CFG_ENABLED_PPDU_END_SET(*msg_word, 0); HTT_RX_RING_CFG_ENABLED_MPDU_START_SET(*msg_word, 0); HTT_RX_RING_CFG_ENABLED_MPDU_END_SET(*msg_word, 0); HTT_RX_RING_CFG_ENABLED_MSDU_START_SET(*msg_word, 0); HTT_RX_RING_CFG_ENABLED_MSDU_END_SET(*msg_word, 0); HTT_RX_RING_CFG_ENABLED_RX_ATTN_SET(*msg_word, 0); HTT_RX_RING_CFG_ENABLED_FRAG_INFO_SET(*msg_word, 0); /* always present? */ HTT_RX_RING_CFG_ENABLED_UCAST_SET(*msg_word, 1); HTT_RX_RING_CFG_ENABLED_MCAST_SET(*msg_word, 1); /* Must change to dynamic enable at run time * rather than at compile time */ HTT_RX_RING_CFG_ENABLED_CTRL_SET(*msg_word, 0); HTT_RX_RING_CFG_ENABLED_MGMT_SET(*msg_word, 0); HTT_RX_RING_CFG_ENABLED_NULL_SET(*msg_word, 0); HTT_RX_RING_CFG_ENABLED_PHY_SET(*msg_word, 0); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_OFFSET_802_11_HDR_SET(*msg_word, 0); HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_SET(*msg_word, 0); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_OFFSET_PPDU_START_SET(*msg_word, 0); HTT_RX_RING_CFG_OFFSET_PPDU_END_SET(*msg_word, 0); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_OFFSET_MPDU_START_SET(*msg_word, 0); HTT_RX_RING_CFG_OFFSET_MPDU_END_SET(*msg_word, 0); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_OFFSET_MSDU_START_SET(*msg_word, 0); HTT_RX_RING_CFG_OFFSET_MSDU_END_SET(*msg_word, 0); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_OFFSET_RX_ATTN_SET(*msg_word, 0); HTT_RX_RING_CFG_OFFSET_FRAG_INFO_SET(*msg_word, 0); SET_HTC_PACKET_INFO_TX( &pkt->htc_pkt, htt_h2t_send_complete_free_netbuf, adf_nbuf_data(msg), adf_nbuf_len(msg), pdev->htc_endpoint, 1); /* tag - not relevant here */ SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); #ifdef ATH_11AC_TXCOMPACT if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { htt_htc_misc_pkt_list_add(pdev, pkt); } #else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); #endif if (!pdev->cfg.default_tx_comp_req) { ol_tx_target_credit_update(pdev->txrx_pdev, -1); } return A_OK; }
A_STATUS htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev) { struct htt_htc_pkt *pkt; adf_nbuf_t msg; u_int32_t *msg_word; int enable_ctrl_data, enable_mgmt_data, enable_null_data, enable_phy_data, enable_hdr, enable_ppdu_start, enable_ppdu_end; pkt = htt_htc_pkt_alloc(pdev); if (!pkt) { return A_ERROR; /* failure */ } /* show that this is not a tx frame download (not required, but helpful) */ pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; pkt->pdev_ctxt = NULL; /* not used during send-done callback */ msg = adf_nbuf_alloc( pdev->osdev, HTT_MSG_BUF_SIZE(HTT_RX_RING_CFG_BYTES(1)), /* reserve room for the HTC header */ HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE); if (!msg) { htt_htc_pkt_free(pdev, pkt); return A_ERROR; /* failure */ } /* * Set the length of the message. * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added * separately during the below call to adf_nbuf_push_head. * The contribution from the HTC header is added separately inside HTC. */ adf_nbuf_put_tail(msg, HTT_RX_RING_CFG_BYTES(1)); /* fill in the message contents */ msg_word = (u_int32_t *) adf_nbuf_data(msg); /* rewind beyond alignment pad to get to the HTC header reserved area */ adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); *msg_word = 0; HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_RING_CFG); HTT_RX_RING_CFG_NUM_RINGS_SET(*msg_word, 1); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_SET( *msg_word, pdev->rx_ring.alloc_idx.paddr); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_BASE_PADDR_SET(*msg_word, pdev->rx_ring.base_paddr); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_LEN_SET(*msg_word, pdev->rx_ring.size); HTT_RX_RING_CFG_BUF_SZ_SET(*msg_word, HTT_RX_BUF_SIZE); /* FIX THIS: if the FW creates a complete translated rx descriptor, then the MAC DMA of the HW rx descriptor should be disabled. */ msg_word++; *msg_word = 0; #ifndef REMOVE_PKT_LOG if (ol_cfg_is_packet_log_enabled(pdev->ctrl_pdev)) { enable_ctrl_data = 1; enable_mgmt_data = 1; enable_null_data = 1; enable_phy_data = 1; enable_hdr = 1; enable_ppdu_start= 1; enable_ppdu_end = 1; /* Disable ASPM when pkt log is enabled */ adf_os_print("Pkt log is enabled\n"); htt_htc_disable_aspm(); } else { adf_os_print("Pkt log is disabled\n"); enable_ctrl_data = 0; enable_mgmt_data = 0; enable_null_data = 0; enable_phy_data = 0; enable_hdr = 0; enable_ppdu_start= 0; enable_ppdu_end = 0; } #else enable_ctrl_data = 0; enable_mgmt_data = 0; enable_null_data = 0; enable_phy_data = 0; enable_hdr = 0; enable_ppdu_start= 0; enable_ppdu_end = 0; #endif HTT_RX_RING_CFG_ENABLED_802_11_HDR_SET(*msg_word, enable_hdr); HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_SET(*msg_word, 1); HTT_RX_RING_CFG_ENABLED_PPDU_START_SET(*msg_word, enable_ppdu_start); HTT_RX_RING_CFG_ENABLED_PPDU_END_SET(*msg_word, enable_ppdu_end); HTT_RX_RING_CFG_ENABLED_MPDU_START_SET(*msg_word, 1); HTT_RX_RING_CFG_ENABLED_MPDU_END_SET(*msg_word, 1); HTT_RX_RING_CFG_ENABLED_MSDU_START_SET(*msg_word, 1); HTT_RX_RING_CFG_ENABLED_MSDU_END_SET(*msg_word, 1); HTT_RX_RING_CFG_ENABLED_RX_ATTN_SET(*msg_word, 1); HTT_RX_RING_CFG_ENABLED_FRAG_INFO_SET(*msg_word, 1); /* always present? */ HTT_RX_RING_CFG_ENABLED_UCAST_SET(*msg_word, 1); HTT_RX_RING_CFG_ENABLED_MCAST_SET(*msg_word, 1); /* Must change to dynamic enable at run time * rather than at compile time */ HTT_RX_RING_CFG_ENABLED_CTRL_SET(*msg_word, enable_ctrl_data); HTT_RX_RING_CFG_ENABLED_MGMT_SET(*msg_word, enable_mgmt_data); HTT_RX_RING_CFG_ENABLED_NULL_SET(*msg_word, enable_null_data); HTT_RX_RING_CFG_ENABLED_PHY_SET(*msg_word, enable_phy_data); HTT_RX_RING_CFG_IDX_INIT_VAL_SET(*msg_word, *pdev->rx_ring.alloc_idx.vaddr); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_OFFSET_802_11_HDR_SET(*msg_word, RX_STD_DESC_HDR_STATUS_OFFSET_DWORD); HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_SET(*msg_word, HTT_RX_STD_DESC_RESERVATION_DWORD); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_OFFSET_PPDU_START_SET(*msg_word, RX_STD_DESC_PPDU_START_OFFSET_DWORD); HTT_RX_RING_CFG_OFFSET_PPDU_END_SET(*msg_word, RX_STD_DESC_PPDU_END_OFFSET_DWORD); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_OFFSET_MPDU_START_SET(*msg_word, RX_STD_DESC_MPDU_START_OFFSET_DWORD); HTT_RX_RING_CFG_OFFSET_MPDU_END_SET(*msg_word, RX_STD_DESC_MPDU_END_OFFSET_DWORD); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_OFFSET_MSDU_START_SET(*msg_word, RX_STD_DESC_MSDU_START_OFFSET_DWORD); HTT_RX_RING_CFG_OFFSET_MSDU_END_SET(*msg_word, RX_STD_DESC_MSDU_END_OFFSET_DWORD); msg_word++; *msg_word = 0; HTT_RX_RING_CFG_OFFSET_RX_ATTN_SET(*msg_word, RX_STD_DESC_ATTN_OFFSET_DWORD); HTT_RX_RING_CFG_OFFSET_FRAG_INFO_SET(*msg_word, RX_STD_DESC_FRAG_INFO_OFFSET_DWORD); SET_HTC_PACKET_INFO_TX( &pkt->htc_pkt, htt_h2t_send_complete_free_netbuf, adf_nbuf_data(msg), adf_nbuf_len(msg), pdev->htc_endpoint, HTC_TX_PACKET_TAG_RUNTIME_PUT); SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); #ifdef ATH_11AC_TXCOMPACT if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) htt_htc_misc_pkt_list_add(pdev, pkt); #else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); #endif return A_OK; }
A_STATUS HTCConnectService(HTC_HANDLE HTCHandle, HTC_SERVICE_CONNECT_REQ *pConnectReq, HTC_SERVICE_CONNECT_RESP *pConnectResp) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); A_STATUS status = A_OK; HTC_PACKET *pSendPacket = NULL; HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg; HTC_CONNECT_SERVICE_MSG *pConnectMsg; HTC_ENDPOINT_ID assignedEndpoint = ENDPOINT_MAX; HTC_ENDPOINT *pEndpoint; unsigned int maxMsgSize = 0; adf_nbuf_t netbuf; A_UINT8 txAlloc; int length; A_BOOL disableCreditFlowCtrl = FALSE; A_UINT16 conn_flags; A_UINT16 rsp_msg_id, rsp_msg_serv_id, rsp_msg_max_msg_size; A_UINT8 rsp_msg_status, rsp_msg_end_id, rsp_msg_serv_meta_len; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCConnectService, target:%p SvcID:0x%X \n", target, pConnectReq->ServiceID)); do { AR_DEBUG_ASSERT(pConnectReq->ServiceID != 0); if (HTC_CTRL_RSVD_SVC == pConnectReq->ServiceID) { /* special case for pseudo control service */ assignedEndpoint = ENDPOINT_0; maxMsgSize = HTC_MAX_CONTROL_MESSAGE_LENGTH; txAlloc = 0; } else { txAlloc = HTCGetCreditAllocation(target,pConnectReq->ServiceID); if (!txAlloc) { AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Service %d does not allocate target credits!\n", pConnectReq->ServiceID)); } /* allocate a packet to send to the target */ pSendPacket = HTCAllocControlTxPacket(target); if (NULL == pSendPacket) { AR_DEBUG_ASSERT(FALSE); status = A_NO_MEMORY; break; } netbuf = (adf_nbuf_t)GET_HTC_PACKET_NET_BUF_CONTEXT(pSendPacket); length = sizeof(HTC_CONNECT_SERVICE_MSG) + pConnectReq->MetaDataLength; /* assemble connect service message */ adf_nbuf_put_tail(netbuf, length); pConnectMsg = (HTC_CONNECT_SERVICE_MSG *)adf_nbuf_data(netbuf); AR_DEBUG_ASSERT(pConnectMsg != NULL); A_MEMZERO(pConnectMsg,sizeof(HTC_CONNECT_SERVICE_MSG)); conn_flags = (pConnectReq->ConnectionFlags & ~HTC_SET_RECV_ALLOC_MASK) | HTC_CONNECT_FLAGS_SET_RECV_ALLOCATION(txAlloc); HTC_SET_FIELD(pConnectMsg, HTC_CONNECT_SERVICE_MSG, MESSAGEID, HTC_MSG_CONNECT_SERVICE_ID); HTC_SET_FIELD(pConnectMsg, HTC_CONNECT_SERVICE_MSG, SERVICE_ID, pConnectReq->ServiceID); HTC_SET_FIELD(pConnectMsg, HTC_CONNECT_SERVICE_MSG, CONNECTIONFLAGS, conn_flags); if (pConnectReq->ConnectionFlags & HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL) { disableCreditFlowCtrl = TRUE; } /* * EV #134248 BUG Fix : Credit miss happens resulting in failure to create * VAP. Disable Credit for WMI endpoint too. */ if (!htc_credit_flow ) { disableCreditFlowCtrl = TRUE; } /* check caller if it wants to transfer meta data */ if ((pConnectReq->pMetaData != NULL) && (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) { /* copy meta data into message buffer (after header ) */ A_MEMCPY((A_UINT8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG), pConnectReq->pMetaData, pConnectReq->MetaDataLength); HTC_SET_FIELD(pConnectMsg, HTC_CONNECT_SERVICE_MSG, SERVICEMETALENGTH, pConnectReq->MetaDataLength); } SET_HTC_PACKET_INFO_TX(pSendPacket, NULL, (A_UINT8 *)pConnectMsg, length, ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); status = HTCSendPkt((HTC_HANDLE)target,pSendPacket); /* we don't own it anymore */ pSendPacket = NULL; if (A_FAILED(status)) { break; } /* wait for response */ status = HTCWaitRecvCtrlMessage(target); if (A_FAILED(status)) { break; } /* we controlled the buffer creation so it has to be properly aligned */ pResponseMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)target->CtrlResponseBuffer; rsp_msg_id = HTC_GET_FIELD(pResponseMsg, HTC_CONNECT_SERVICE_RESPONSE_MSG, MESSAGEID); rsp_msg_serv_id = HTC_GET_FIELD(pResponseMsg, HTC_CONNECT_SERVICE_RESPONSE_MSG, SERVICEID); rsp_msg_status = HTC_GET_FIELD(pResponseMsg, HTC_CONNECT_SERVICE_RESPONSE_MSG, STATUS); rsp_msg_end_id = HTC_GET_FIELD(pResponseMsg, HTC_CONNECT_SERVICE_RESPONSE_MSG, ENDPOINTID); rsp_msg_max_msg_size = HTC_GET_FIELD(pResponseMsg, HTC_CONNECT_SERVICE_RESPONSE_MSG, MAXMSGSIZE); rsp_msg_serv_meta_len = HTC_GET_FIELD(pResponseMsg, HTC_CONNECT_SERVICE_RESPONSE_MSG, SERVICEMETALENGTH); if ((rsp_msg_id != HTC_MSG_CONNECT_SERVICE_RESPONSE_ID) || (target->CtrlResponseLength < sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG))) { /* this message is not valid */ AR_DEBUG_ASSERT(FALSE); status = A_EPROTO; break; } AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCConnectService, service 0x%X connect response from target status:%d, assigned ep: %d\n", rsp_msg_serv_id, rsp_msg_status, rsp_msg_end_id)); pConnectResp->ConnectRespCode = rsp_msg_status; /* check response status */ if (rsp_msg_status != HTC_SERVICE_SUCCESS) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Target failed service 0x%X connect request (status:%d)\n", rsp_msg_serv_id, rsp_msg_status)); status = A_EPROTO; break; } assignedEndpoint = (HTC_ENDPOINT_ID)rsp_msg_end_id; maxMsgSize = rsp_msg_max_msg_size; if ((pConnectResp->pMetaData != NULL) && (rsp_msg_serv_meta_len > 0) && (rsp_msg_serv_meta_len <= HTC_SERVICE_META_DATA_MAX_LENGTH)) { /* caller supplied a buffer and the target responded with data */ int copyLength = min((int)pConnectResp->BufferLength, (int)rsp_msg_serv_meta_len); /* copy the meta data */ A_MEMCPY(pConnectResp->pMetaData, ((A_UINT8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG), copyLength); pConnectResp->ActualLength = copyLength; } /* done processing response buffer */ target->CtrlResponseProcessing = FALSE; } /* the rest of these are parameter checks so set the error status */ status = A_EPROTO; if (assignedEndpoint >= ENDPOINT_MAX) { AR_DEBUG_ASSERT(FALSE); break; } if (0 == maxMsgSize) { AR_DEBUG_ASSERT(FALSE); break; } pEndpoint = &target->EndPoint[assignedEndpoint]; pEndpoint->Id = assignedEndpoint; if (pEndpoint->ServiceID != 0) { /* endpoint already in use! */ AR_DEBUG_ASSERT(FALSE); break; } /* return assigned endpoint to caller */ pConnectResp->Endpoint = assignedEndpoint; pConnectResp->MaxMsgLength = maxMsgSize; /* setup the endpoint */ pEndpoint->ServiceID = pConnectReq->ServiceID; /* this marks the endpoint in use */ pEndpoint->MaxTxQueueDepth = pConnectReq->MaxSendQueueDepth; pEndpoint->MaxMsgLength = maxMsgSize; pEndpoint->TxCredits = txAlloc; pEndpoint->TxCreditSize = target->TargetCreditSize; pEndpoint->TxCreditsPerMaxMsg = maxMsgSize / target->TargetCreditSize; if (maxMsgSize % target->TargetCreditSize) { pEndpoint->TxCreditsPerMaxMsg++; } /* copy all the callbacks */ pEndpoint->EpCallBacks = pConnectReq->EpCallbacks; status = HIFMapServiceToPipe(target->hif_dev, pEndpoint->ServiceID, &pEndpoint->UL_PipeID, &pEndpoint->DL_PipeID, &pEndpoint->ul_is_polled, &pEndpoint->dl_is_polled); if (A_FAILED(status)) { break; } adf_os_assert(!pEndpoint->dl_is_polled); /* not currently supported */ if (pEndpoint->ul_is_polled) { adf_os_timer_init( target->osdev, &pEndpoint->ul_poll_timer, HTCSendCompleteCheckCleanup, pEndpoint); } AR_DEBUG_PRINTF(ATH_DEBUG_SETUP, ("HTC Service:0x%4.4X, ULpipe:%d DLpipe:%d id:%d Ready\n", pEndpoint->ServiceID,pEndpoint->UL_PipeID,pEndpoint->DL_PipeID,pEndpoint->Id)); if (disableCreditFlowCtrl && pEndpoint->TxCreditFlowEnabled) { pEndpoint->TxCreditFlowEnabled = FALSE; AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HTC Service:0x%4.4X ep:%d TX flow control disabled\n", pEndpoint->ServiceID, assignedEndpoint)); } } while (FALSE); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCConnectService \n")); return status; }
static int epping_tx_send_int(adf_nbuf_t skb, epping_adapter_t *pAdapter) { EPPING_HEADER *eppingHdr = (EPPING_HEADER *)adf_nbuf_data(skb); HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED; struct epping_cookie * cookie = NULL; A_UINT8 ac = 0; A_STATUS ret = A_OK; int skb_len; EPPING_HEADER tmpHdr = *eppingHdr; /* allocate resource for this packet */ cookie = epping_alloc_cookie(pAdapter->pEpping_ctx); /* no resource */ if (cookie == NULL) { EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: epping_alloc_cookie returns no resource\n", __func__); return -1; } if (enb_tx_dump) epping_hex_dump((void *)eppingHdr, skb->len, __func__); /* * a quirk of linux, the payload of the frame is 32-bit aligned and thus * the addition of the HTC header will mis-align the start of the HTC * frame, so we add some padding which will be stripped off in the target */ if (EPPING_ALIGNMENT_PAD > 0) { A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD); } /* prepare ep/HTC information */ ac = eppingHdr->StreamNo_h; eid = pAdapter->pEpping_ctx->EppingEndpoint[ac]; if (eid < 0 || eid >= EPPING_MAX_NUM_EPIDS) { EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: invalid eid = %d, ac = %d\n", __func__, eid, ac); return -1; } if (tmpHdr.Cmd_h == EPPING_CMD_RESET_RECV_CNT || tmpHdr.Cmd_h == EPPING_CMD_CONT_RX_START) { epping_set_kperf_flag(pAdapter, eid, tmpHdr.CmdBuffer_t[0]); } if (pAdapter->pEpping_ctx->kperf[eid]) { switch (tmpHdr.Cmd_h) { case EPPING_CMD_NO_ECHO: #ifdef HIF_PCI epping_tx_copier_schedule(pAdapter->pEpping_ctx, eid, skb); #endif /* HIF_PCI */ break; default: break; } } if (pAdapter->pEpping_ctx->kperf[eid] && tmpHdr.Cmd_h == EPPING_CMD_NO_ECHO) { epping_tx_dup_pkt(pAdapter, eid, skb); } SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, cookie, adf_nbuf_data(skb), adf_nbuf_len(skb), eid, 0); SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, skb); skb_len = skb->len; /* send the packet */ ret = HTCSendPkt(pAdapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt); epping_log_packet(pAdapter, &tmpHdr, ret, __func__); if (ret != A_OK) { EPPING_LOG(VOS_TRACE_LEVEL_FATAL, "%s: HTCSendPkt failed, status = %d\n", __func__, ret); epping_free_cookie(pAdapter->pEpping_ctx, cookie); return -1; } pAdapter->stats.tx_bytes += skb_len; ++pAdapter->stats.tx_packets; if (((pAdapter->stats.tx_packets + pAdapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 && (pAdapter->stats.tx_packets || pAdapter->stats.tx_dropped)) { epping_log_stats(pAdapter, __func__); } return 0; }
/* * Start continuous transmit operation. */ static int tx99_start(struct ath_softc *sc) { static struct ath_tx99_tgt tx99_tgt; struct ath_tx99 *tx99 = sc->sc_tx99; struct ath_hal *ah = sc->sc_ah; int is2GHz = 0; adf_nbuf_t skb; HAL_CHANNEL *c = NULL; if(tx99->recv) { ath_hal_phydisable(ah); //adf_os_print("%s: device %s tx99 continuous receive mode\n", __FUNCTION__, adf_net_ifname(sc->sc_ic->ic_dev)); return 0; } /* check tx99 running state */ if(tx99->tx99_state){ /* already active */ adf_os_print("%s: already running\n", __FUNCTION__); return 0; } /* set tx99 state active */ tx99->tx99_state = 1; /* allocate diag packet buffer */ tx99->skb = ath_alloc_skb_tx99(sc->sc_osdev, 2000, 32); if (tx99->skb == NULL) { adf_os_print("%s: unable to allocate skb\n", __FUNCTION__); tx99->tx99_state = 0; return -ENOMEM; } skb = tx99->skb; /* drain all tx queue */ ath_drain_txq(sc); /* * Setup channel using configured frequency+flags. */ if (tx99_channel_setup(sc) != EOK) { adf_os_print("%s: unable to setup operation\n", __FUNCTION__); tx99->tx99_state = 0; adf_nbuf_free(skb); return -EIO; } /*disable desc tpc */ ath_hal_settpc(ah,0); /* * Setup tx power limit */ c = &sc->sc_curchan; is2GHz = TX99_IS_CHAN_2GHZ(c); ath_hal_settxpowlimit(ah,tx99->txpower,0,is2GHz); /* set tx99 enable */ tx99_tgt.txrate = adf_os_htonl(tx99->txrate); tx99_tgt.txpower = adf_os_htonl(tx99->txpower); tx99_tgt.txchain = adf_os_htonl(tx99->chanmask); tx99_tgt.htmode = adf_os_htonl(tx99->htmode); tx99_tgt.type = adf_os_htonl(tx99->type); tx99_tgt.chtype = adf_os_htonl(TX99_IS_CHAN_5GHZ(c)); tx99_tgt.txantenna = adf_os_htonl(0); if( tx99->txpower < 60 ) /* only update channel pwr if not default MAX power */ ath_hal_tx99_channel_pwr_update(ah, c, tx99->txpower); #ifdef ATH_SUPPORT_HTC ah_tx99_start(ah, (u_int8_t *)&tx99_tgt); /* send diag packet */ { struct ath_txep *txep; adf_nbuf_t skb; A_STATUS ret; adf_nbuf_put_tail(skb, 1500); txep = sc->sc_ac2ep[WME_AC_VO]; /* send packet to target */ ret = HTCSendPkt(sc->sc_host_htc_handle, NULL ,skb, sc->sc_data_VO_ep); if(ret) { adf_os_print("%s: tx99 fail \n", __FUNCTION__); tx99_stop(sc, 0); } } #else adf_nbuf_put_tail(skb, 1500); if (ath_tx99_tgt_start(sc, tx99_tgt.chtype) != EOK) { adf_os_print("%s: tx99 fail \n", __FUNCTION__); tx99_stop(sc, 0); } #endif /* wait a while to make sure target setting ready */ adf_os_mdelay(50); adf_os_print("%s: continuous transmit started\n", __FUNCTION__); return 0; }
/* * Start continuous transmit operation. */ static int tx99_start(struct ath_softc *sc) { static struct ath_tx99_tgt tx99_tgt; struct ath_tx99 *tx99 = sc->sc_tx99; struct ath_hal *ah = sc->sc_ah; int is2GHz = 0; wbuf_t wbuf; HAL_CHANNEL *chan = NULL; if(tx99->recv) { ath_hal_phydisable(ah); DPRINTF(sc, ATH_DEBUG_TX99, "%s: tx99 continuous receive mode, return!\n", __func__); return 0; } /* check tx99 running state */ if(tx99->tx99_state){ /* already active */ DPRINTF(sc, ATH_DEBUG_TX99, "%s: already running, return!\n", __func__); return 0; } OS_DELAY(10000); /* set tx99 state active */ tx99->tx99_state = 1; /* allocate diag packet buffer */ if (tx99->wbuf == NULL) { tx99->wbuf = wbuf_alloc(sc->sc_osdev, WBUF_TX_DATA, 2000); if (tx99->wbuf == NULL) { DPRINTF(sc, ATH_DEBUG_TX99, "%s: unable to allocate wbuf!\n", __func__); tx99->tx99_state = 0; return -ENOMEM; } } else { DPRINTF(sc, ATH_DEBUG_TX99, "%s: wbuf was allocated before!\n", __func__); } wbuf = tx99->wbuf; /* drain all tx queue */ ath_drain_txq(sc); /* * Setup channel using configured frequency+flags. */ if (tx99_channel_setup(sc)) { DPRINTF(sc, ATH_DEBUG_TX99, "%s: unable to setup channel!\n", __func__); /* recover the default channel and mode */ tx99->txfreq = 2412;/* ieee channel frequecy */ tx99->htmode = 0; tx99->htext = 0; goto bad; } /* * Setup tx power limit */ chan = &sc->sc_curchan; is2GHz = TX99_IS_CHAN_2GHZ(chan); ath_hal_settxpowlimit(ah,tx99->txpower,0,is2GHz); /* set tx99 enable */ tx99_tgt.txrate = htonl(tx99->txrate); tx99_tgt.txrc = htonl(tx99->txrc); tx99_tgt.txpower = htonl(tx99->txpower); tx99_tgt.txchain = htonl(tx99->chanmask); tx99_tgt.htmode = htonl(tx99->htmode); tx99_tgt.type = htonl(tx99->type); tx99_tgt.chtype = htonl(TX99_IS_CHAN_5GHZ(chan)); tx99_tgt.txantenna = htonl(0); if( tx99->txpower < 60 ) /* only update channel pwr if not default MAX power */ ath_hal_tx99_channel_pwr_update(ah, chan, tx99->txpower); #ifdef ATH_SUPPORT_HTC ah_tx99_start(ah, (u_int8_t *)&tx99_tgt); /* send diag packet */ { struct ath_txep *txep; A_STATUS ret; adf_nbuf_put_tail(skb, 1500); txep = sc->sc_ac2ep[WME_AC_VO]; /* send packet to target */ ret = HTCSendPkt(sc->sc_host_htc_handle, NULL ,skb, sc->sc_data_VO_ep); if(ret) { DPRINTF(sc, ATH_DEBUG_TX99, "%s: tx99 fail!\n", __func__); tx99_stop(sc, 0); } } #else if (ath_tx99_tgt_start(sc, tx99_tgt.chtype) != EOK) { goto bad; } #endif /* wait a while to make sure target setting ready */ OS_DELAY(50000); DPRINTF(sc, ATH_DEBUG_TX99, "%s: continuous transmit started!\n", __func__); return 0; bad: tx99_stop(sc, 0); return -EIO; }
A_STATUS htt_h2t_ver_req_msg(struct htt_pdev_t *pdev) { struct htt_htc_pkt *pkt; adf_nbuf_t msg; u_int32_t *msg_word; u_int32_t msg_size; u_int32_t max_tx_group; pkt = htt_htc_pkt_alloc(pdev); if (!pkt) { return A_ERROR; /* failure */ } max_tx_group = OL_TX_GET_MAX_GROUPS(pdev->txrx_pdev); if (max_tx_group) { msg_size = HTT_VER_REQ_BYTES + sizeof(struct htt_option_tlv_mac_tx_queue_groups_t); } else { msg_size = HTT_VER_REQ_BYTES; } /* show that this is not a tx frame download (not required, but helpful) */ pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; pkt->pdev_ctxt = NULL; /* not used during send-done callback */ msg = adf_nbuf_alloc( pdev->osdev, HTT_MSG_BUF_SIZE(msg_size), /* reserve room for the HTC header */ HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE); if (!msg) { htt_htc_pkt_free(pdev, pkt); return A_ERROR; /* failure */ } /* * Set the length of the message. * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added * separately during the below call to adf_nbuf_push_head. * The contribution from the HTC header is added separately inside HTC. */ adf_nbuf_put_tail(msg, msg_size); /* fill in the message contents */ msg_word = (u_int32_t *) adf_nbuf_data(msg); /* rewind beyond alignment pad to get to the HTC header reserved area */ adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); *msg_word = 0; HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_VERSION_REQ); if (max_tx_group) { *(msg_word + 1) = 0; /* Fill Group Info */ HTT_OPTION_TLV_TAG_SET(*(msg_word+1), HTT_OPTION_TLV_TAG_MAX_TX_QUEUE_GROUPS); HTT_OPTION_TLV_LENGTH_SET(*(msg_word+1), (sizeof(struct htt_option_tlv_mac_tx_queue_groups_t)/ sizeof(u_int32_t))); HTT_OPTION_TLV_VALUE0_SET(*(msg_word+1), max_tx_group); } SET_HTC_PACKET_INFO_TX( &pkt->htc_pkt, htt_h2t_send_complete_free_netbuf, adf_nbuf_data(msg), adf_nbuf_len(msg), pdev->htc_endpoint, 1); /* tag - not relevant here */ SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); #ifdef ATH_11AC_TXCOMPACT if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { htt_htc_misc_pkt_list_add(pdev, pkt); } #else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); #endif if ((pdev->cfg.is_high_latency) && (!pdev->cfg.default_tx_comp_req)) { ol_tx_target_credit_update(pdev->txrx_pdev, -1); } return A_OK; }
int htt_h2t_dbg_stats_get( struct htt_pdev_t *pdev, u_int32_t stats_type_upload_mask, u_int32_t stats_type_reset_mask, u_int8_t cfg_stat_type, u_int32_t cfg_val, u_int64_t cookie) { struct htt_htc_pkt *pkt; adf_nbuf_t msg; u_int32_t *msg_word; uint16_t htc_tag = 1; pkt = htt_htc_pkt_alloc(pdev); if (!pkt) { return -1; /* failure */ } if (stats_type_upload_mask >= 1 << HTT_DBG_NUM_STATS || stats_type_reset_mask >= 1 << HTT_DBG_NUM_STATS) { /* FIX THIS - add more details? */ adf_os_print("%#x %#x stats not supported\n", stats_type_upload_mask, stats_type_reset_mask); return -1; /* failure */ } if (stats_type_reset_mask) htc_tag = HTC_TX_PACKET_TAG_RUNTIME_PUT; /* show that this is not a tx frame download (not required, but helpful) */ pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; pkt->pdev_ctxt = NULL; /* not used during send-done callback */ msg = adf_nbuf_alloc( pdev->osdev, HTT_MSG_BUF_SIZE(HTT_H2T_STATS_REQ_MSG_SZ), /* reserve room for HTC header */ HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, FALSE); if (!msg) { htt_htc_pkt_free(pdev, pkt); return -1; /* failure */ } /* set the length of the message */ adf_nbuf_put_tail(msg, HTT_H2T_STATS_REQ_MSG_SZ); /* fill in the message contents */ msg_word = (u_int32_t *) adf_nbuf_data(msg); /* rewind beyond alignment pad to get to the HTC header reserved area */ adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); *msg_word = 0; HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_STATS_REQ); HTT_H2T_STATS_REQ_UPLOAD_TYPES_SET(*msg_word, stats_type_upload_mask); msg_word++; *msg_word = 0; HTT_H2T_STATS_REQ_RESET_TYPES_SET(*msg_word, stats_type_reset_mask); msg_word++; *msg_word = 0; HTT_H2T_STATS_REQ_CFG_VAL_SET(*msg_word, cfg_val); HTT_H2T_STATS_REQ_CFG_STAT_TYPE_SET(*msg_word, cfg_stat_type); /* cookie LSBs */ msg_word++; *msg_word = cookie & 0xffffffff; /* cookie MSBs */ msg_word++; *msg_word = cookie >> 32; SET_HTC_PACKET_INFO_TX( &pkt->htc_pkt, htt_h2t_send_complete_free_netbuf, adf_nbuf_data(msg), adf_nbuf_len(msg), pdev->htc_endpoint, htc_tag); SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); #ifdef ATH_11AC_TXCOMPACT if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { htt_htc_misc_pkt_list_add(pdev, pkt); } #else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); #endif if ((pdev->cfg.is_high_latency) && (!pdev->cfg.default_tx_comp_req)) { ol_tx_target_credit_update(pdev->txrx_pdev, -1); } return 0; }
int htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev) { struct htt_htc_pkt *pkt; adf_nbuf_t msg; u_int32_t *msg_word; pkt = htt_htc_pkt_alloc(pdev); if (!pkt) { return A_NO_MEMORY; } /* show that this is not a tx frame download (not required, but helpful) */ pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID; pkt->pdev_ctxt = NULL; /* not used during send-done callback */ msg = adf_nbuf_alloc( pdev->osdev, HTT_MSG_BUF_SIZE(HTT_WDI_IPA_CFG_SZ), /* reserve room for HTC header */ HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, FALSE); if (!msg) { htt_htc_pkt_free(pdev, pkt); return A_NO_MEMORY; } /* set the length of the message */ adf_nbuf_put_tail(msg, HTT_WDI_IPA_CFG_SZ); /* fill in the message contents */ msg_word = (u_int32_t *) adf_nbuf_data(msg); /* rewind beyond alignment pad to get to the HTC header reserved area */ adf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); *msg_word = 0; HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_SET(*msg_word, pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt); HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_CFG); msg_word++; *msg_word = 0; HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_SET(*msg_word, (unsigned int)pdev->ipa_uc_tx_rsc.tx_comp_base.paddr); msg_word++; *msg_word = 0; HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_SET(*msg_word, (unsigned int)ol_cfg_ipa_uc_tx_max_buf_cnt(pdev->ctrl_pdev)); msg_word++; *msg_word = 0; HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_SET(*msg_word, (unsigned int)pdev->ipa_uc_tx_rsc.tx_comp_idx_paddr); msg_word++; *msg_word = 0; HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_SET(*msg_word, (unsigned int)pdev->ipa_uc_tx_rsc.tx_ce_idx.paddr); msg_word++; *msg_word = 0; HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_SET(*msg_word, (unsigned int)pdev->ipa_uc_rx_rsc.rx_ind_ring_base.paddr); msg_word++; *msg_word = 0; HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_SET(*msg_word, (unsigned int)ol_cfg_ipa_uc_rx_ind_ring_size(pdev->ctrl_pdev)); msg_word++; *msg_word = 0; HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_SET(*msg_word, (unsigned int)pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.paddr); msg_word++; *msg_word = 0; HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_SET(*msg_word, (unsigned int)pdev->ipa_uc_rx_rsc.rx_rdy_idx_paddr); SET_HTC_PACKET_INFO_TX( &pkt->htc_pkt, htt_h2t_send_complete_free_netbuf, adf_nbuf_data(msg), adf_nbuf_len(msg), pdev->htc_endpoint, HTC_TX_PACKET_TAG_RUNTIME_PUT); SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); #ifdef ATH_11AC_TXCOMPACT if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) htt_htc_misc_pkt_list_add(pdev, pkt); #else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); #endif return A_OK; }