12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025 |
- /*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
- *
- * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
- *
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
- /*
- * This file was originally distributed by Qualcomm Atheros, Inc.
- * under proprietary terms before Copyright ownership was assigned
- * to the Linux Foundation.
- */
- /**
- * @file htt_h2t.c
- * @brief Provide functions to send host->target HTT messages.
- * @details
- * This file contains functions related to host->target HTT messages.
- * There are a couple aspects of this host->target messaging:
- * 1. This file contains the function that is called by HTC when
- * a host->target send completes.
- * This send-completion callback is primarily relevant to HL,
- * to invoke the download scheduler to set up a new download,
- * and optionally free the tx frame whose download is completed.
- * For both HL and LL, this completion callback frees up the
- * HTC_PACKET object used to specify the download.
- * 2. This file contains functions for creating messages to send
- * from the host to the target.
- */
- #include <cdf_memory.h> /* cdf_mem_copy */
- #include <cdf_nbuf.h> /* cdf_nbuf_map_single */
- #include <htc_api.h> /* HTC_PACKET */
- #include <htc.h> /* HTC_HDR_ALIGNMENT_PADDING */
- #include <htt.h> /* HTT host->target msg defs */
- #include <ol_txrx_htt_api.h> /* ol_tx_completion_handler, htt_tx_status */
- #include <ol_htt_tx_api.h>
- #include <htt_internal.h>
- #define HTT_MSG_BUF_SIZE(msg_bytes) \
- ((msg_bytes) + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING)
- #ifndef container_of
- #define container_of(ptr, type, member) \
- ((type *)((char *)(ptr) - (char *)(&((type *)0)->member)))
- #endif
- static void
- htt_h2t_send_complete_free_netbuf(void *pdev, A_STATUS status,
- cdf_nbuf_t netbuf, uint16_t msdu_id)
- {
- cdf_nbuf_free(netbuf);
- }
- void htt_h2t_send_complete(void *context, HTC_PACKET *htc_pkt)
- {
- void (*send_complete_part2)(void *pdev, A_STATUS status,
- cdf_nbuf_t msdu, uint16_t msdu_id);
- struct htt_pdev_t *pdev = (struct htt_pdev_t *)context;
- struct htt_htc_pkt *htt_pkt;
- cdf_nbuf_t netbuf;
- send_complete_part2 = htc_pkt->pPktContext;
- htt_pkt = container_of(htc_pkt, struct htt_htc_pkt, htc_pkt);
- /* process (free or keep) the netbuf that held the message */
- netbuf = (cdf_nbuf_t) htc_pkt->pNetBufContext;
- if (send_complete_part2 != NULL) {
- send_complete_part2(htt_pkt->pdev_ctxt, htc_pkt->Status, netbuf,
- htt_pkt->msdu_id);
- }
- /* free the htt_htc_pkt / HTC_PACKET object */
- htt_htc_pkt_free(pdev, htt_pkt);
- }
- HTC_SEND_FULL_ACTION htt_h2t_full(void *context, HTC_PACKET *pkt)
- {
- /* FIX THIS */
- return HTC_SEND_FULL_KEEP;
- }
- #if defined(HELIUMPLUS_PADDR64)
- A_STATUS htt_h2t_frag_desc_bank_cfg_msg(struct htt_pdev_t *pdev)
- {
- A_STATUS rc = A_OK;
- struct htt_htc_pkt *pkt;
- cdf_nbuf_t msg;
- u_int32_t *msg_word;
- struct htt_tx_frag_desc_bank_cfg_t *bank_cfg;
- 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 = cdf_nbuf_alloc(
- pdev->osdev,
- HTT_MSG_BUF_SIZE(sizeof(struct htt_tx_frag_desc_bank_cfg_t)),
- /* 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.
- */
- cdf_nbuf_put_tail(msg, sizeof(struct htt_tx_frag_desc_bank_cfg_t));
- /* fill in the message contents */
- msg_word = (u_int32_t *) cdf_nbuf_data(msg);
- memset(msg_word, 0 , sizeof(struct htt_tx_frag_desc_bank_cfg_t));
- /* rewind beyond alignment pad to get to the HTC header reserved area */
- cdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
- *msg_word = 0;
- HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG);
- bank_cfg = (struct htt_tx_frag_desc_bank_cfg_t *)msg_word;
- /** @note @todo Hard coded to 0 Assuming just one pdev for now.*/
- HTT_H2T_FRAG_DESC_BANK_PDEVID_SET(*msg_word, 0);
- /** @note Hard coded to 1.*/
- HTT_H2T_FRAG_DESC_BANK_NUM_BANKS_SET(*msg_word, 1);
- HTT_H2T_FRAG_DESC_BANK_DESC_SIZE_SET(*msg_word, pdev->frag_descs.size);
- HTT_H2T_FRAG_DESC_BANK_SWAP_SET(*msg_word, 0);
- /** Bank specific data structure.*/
- #if HTT_PADDR64
- bank_cfg->bank_base_address[0].lo =
- pdev->frag_descs.desc_pages.dma_pages->page_p_addr;
- bank_cfg->bank_base_address[0].hi = 0;
- #else /* ! HTT_PADDR64 */
- bank_cfg->bank_base_address[0] =
- pdev->frag_descs.desc_pages.dma_pages->page_p_addr;
- #endif /* HTT_PADDR64 */
- /* Logical Min index */
- HTT_H2T_FRAG_DESC_BANK_MIN_IDX_SET(bank_cfg->bank_info[0], 0);
- /* Logical Max index */
- HTT_H2T_FRAG_DESC_BANK_MAX_IDX_SET(bank_cfg->bank_info[0],
- pdev->frag_descs.pool_elems-1);
- SET_HTC_PACKET_INFO_TX(
- &pkt->htc_pkt,
- htt_h2t_send_complete_free_netbuf,
- cdf_nbuf_data(msg),
- cdf_nbuf_len(msg),
- pdev->htc_endpoint,
- 1); /* tag - not relevant here */
- SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
- rc = htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
- return rc;
- }
- #endif /* defined(HELIUMPLUS_PADDR64) */
- A_STATUS htt_h2t_ver_req_msg(struct htt_pdev_t *pdev)
- {
- struct htt_htc_pkt *pkt;
- cdf_nbuf_t msg;
- uint32_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 */
- /* reserve room for the HTC header */
- msg = cdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_VER_REQ_BYTES),
- 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 cdf_nbuf_push_head.
- * The contribution from the HTC header is added separately inside HTC.
- */
- cdf_nbuf_put_tail(msg, HTT_VER_REQ_BYTES);
- /* fill in the message contents */
- msg_word = (uint32_t *) cdf_nbuf_data(msg);
- /* rewind beyond alignment pad to get to the HTC header reserved area */
- cdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
- *msg_word = 0;
- HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_VERSION_REQ);
- SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
- htt_h2t_send_complete_free_netbuf,
- cdf_nbuf_data(msg), cdf_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 (htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK)
- htt_htc_misc_pkt_list_add(pdev, pkt);
- #else
- htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
- #endif
- return A_OK;
- }
- A_STATUS htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev)
- {
- struct htt_htc_pkt *pkt;
- cdf_nbuf_t msg;
- uint32_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 */
- /* reserve room for the HTC header */
- msg = cdf_nbuf_alloc(pdev->osdev,
- HTT_MSG_BUF_SIZE(HTT_RX_RING_CFG_BYTES(1)),
- 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 cdf_nbuf_push_head.
- * The contribution from the HTC header is added separately inside HTC.
- */
- cdf_nbuf_put_tail(msg, HTT_RX_RING_CFG_BYTES(1));
- /* fill in the message contents */
- msg_word = (uint32_t *) cdf_nbuf_data(msg);
- /* rewind beyond alignment pad to get to the HTC header reserved area */
- cdf_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;
- #if HTT_PADDR64
- HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_LO_SET(*msg_word,
- pdev->rx_ring.alloc_idx.paddr);
- msg_word++;
- HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_HI_SET(*msg_word, 0);
- #else /* ! HTT_PADDR64 */
- HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_SET(*msg_word,
- pdev->rx_ring.alloc_idx.paddr);
- #endif /* HTT_PADDR64 */
- msg_word++;
- *msg_word = 0;
- #if HTT_PADDR64
- HTT_RX_RING_CFG_BASE_PADDR_LO_SET(*msg_word,
- pdev->rx_ring.base_paddr);
- msg_word++;
- HTT_RX_RING_CFG_BASE_PADDR_HI_SET(*msg_word, 0);
- #else /* ! HTT_PADDR64 */
- HTT_RX_RING_CFG_BASE_PADDR_SET(*msg_word, pdev->rx_ring.base_paddr);
- #endif /* HTT_PADDR64 */
- 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 */
- cdf_print("Pkt log is enabled\n");
- htt_htc_disable_aspm();
- } else {
- cdf_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);
- /* always present? */
- HTT_RX_RING_CFG_ENABLED_FRAG_INFO_SET(*msg_word, 1);
- 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_DESC_HDR_STATUS_OFFSET32);
- HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_SET(*msg_word,
- HTT_RX_DESC_RESERVATION32);
- msg_word++;
- *msg_word = 0;
- HTT_RX_RING_CFG_OFFSET_PPDU_START_SET(*msg_word,
- RX_DESC_PPDU_START_OFFSET32);
- HTT_RX_RING_CFG_OFFSET_PPDU_END_SET(*msg_word,
- RX_DESC_PPDU_END_OFFSET32);
- msg_word++;
- *msg_word = 0;
- HTT_RX_RING_CFG_OFFSET_MPDU_START_SET(*msg_word,
- RX_DESC_MPDU_START_OFFSET32);
- HTT_RX_RING_CFG_OFFSET_MPDU_END_SET(*msg_word,
- RX_DESC_MPDU_END_OFFSET32);
- msg_word++;
- *msg_word = 0;
- HTT_RX_RING_CFG_OFFSET_MSDU_START_SET(*msg_word,
- RX_DESC_MSDU_START_OFFSET32);
- HTT_RX_RING_CFG_OFFSET_MSDU_END_SET(*msg_word,
- RX_DESC_MSDU_END_OFFSET32);
- msg_word++;
- *msg_word = 0;
- HTT_RX_RING_CFG_OFFSET_RX_ATTN_SET(*msg_word,
- RX_DESC_ATTN_OFFSET32);
- HTT_RX_RING_CFG_OFFSET_FRAG_INFO_SET(*msg_word,
- RX_DESC_FRAG_INFO_OFFSET32);
- SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
- htt_h2t_send_complete_free_netbuf,
- cdf_nbuf_data(msg),
- cdf_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 (htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK)
- htt_htc_misc_pkt_list_add(pdev, pkt);
- #else
- htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
- #endif
- return A_OK;
- }
- int
- htt_h2t_dbg_stats_get(struct htt_pdev_t *pdev,
- uint32_t stats_type_upload_mask,
- uint32_t stats_type_reset_mask,
- uint8_t cfg_stat_type, uint32_t cfg_val, uint64_t cookie)
- {
- struct htt_htc_pkt *pkt;
- cdf_nbuf_t msg;
- uint32_t *msg_word;
- uint16_t htc_tag = 1;
- pkt = htt_htc_pkt_alloc(pdev);
- if (!pkt)
- return -EINVAL; /* 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? */
- cdf_print("%#x %#x stats not supported\n",
- stats_type_upload_mask, stats_type_reset_mask);
- return -EINVAL; /* 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 = cdf_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 -EINVAL; /* failure */
- }
- /* set the length of the message */
- cdf_nbuf_put_tail(msg, HTT_H2T_STATS_REQ_MSG_SZ);
- /* fill in the message contents */
- msg_word = (uint32_t *) cdf_nbuf_data(msg);
- /* rewind beyond alignment pad to get to the HTC header reserved area */
- cdf_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,
- cdf_nbuf_data(msg),
- cdf_nbuf_len(msg),
- pdev->htc_endpoint,
- htc_tag); /* tag - not relevant here */
- SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
- #ifdef ATH_11AC_TXCOMPACT
- if (htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK)
- htt_htc_misc_pkt_list_add(pdev, pkt);
- #else
- htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
- #endif
- return 0;
- }
- A_STATUS htt_h2t_sync_msg(struct htt_pdev_t *pdev, uint8_t sync_cnt)
- {
- struct htt_htc_pkt *pkt;
- cdf_nbuf_t msg;
- uint32_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 */
- /* reserve room for HTC header */
- msg = cdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_H2T_SYNC_MSG_SZ),
- 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 */
- cdf_nbuf_put_tail(msg, HTT_H2T_SYNC_MSG_SZ);
- /* fill in the message contents */
- msg_word = (uint32_t *) cdf_nbuf_data(msg);
- /* rewind beyond alignment pad to get to the HTC header reserved area */
- cdf_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,
- cdf_nbuf_data(msg),
- cdf_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 (htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK)
- htt_htc_misc_pkt_list_add(pdev, pkt);
- #else
- htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
- #endif
- return A_OK;
- }
- int
- htt_h2t_aggr_cfg_msg(struct htt_pdev_t *pdev,
- int max_subfrms_ampdu, int max_subfrms_amsdu)
- {
- struct htt_htc_pkt *pkt;
- cdf_nbuf_t msg;
- uint32_t *msg_word;
- pkt = htt_htc_pkt_alloc(pdev);
- if (!pkt)
- return -EINVAL; /* 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 */
- /* reserve room for HTC header */
- msg = cdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_AGGR_CFG_MSG_SZ),
- HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
- false);
- if (!msg) {
- htt_htc_pkt_free(pdev, pkt);
- return -EINVAL; /* failure */
- }
- /* set the length of the message */
- cdf_nbuf_put_tail(msg, HTT_AGGR_CFG_MSG_SZ);
- /* fill in the message contents */
- msg_word = (uint32_t *) cdf_nbuf_data(msg);
- /* rewind beyond alignment pad to get to the HTC header reserved area */
- cdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
- *msg_word = 0;
- HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_AGGR_CFG);
- if (max_subfrms_ampdu && (max_subfrms_ampdu <= 64)) {
- HTT_AGGR_CFG_MAX_NUM_AMPDU_SUBFRM_SET(*msg_word,
- max_subfrms_ampdu);
- }
- if (max_subfrms_amsdu && (max_subfrms_amsdu < 32)) {
- HTT_AGGR_CFG_MAX_NUM_AMSDU_SUBFRM_SET(*msg_word,
- max_subfrms_amsdu);
- }
- SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
- htt_h2t_send_complete_free_netbuf,
- cdf_nbuf_data(msg),
- cdf_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 (htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK)
- htt_htc_misc_pkt_list_add(pdev, pkt);
- #else
- htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
- #endif
- return 0;
- }
- #ifdef IPA_OFFLOAD
- /**
- * htt_h2t_ipa_uc_rsc_cfg_msg() - Send WDI IPA config message to firmware
- * @pdev: handle to the HTT instance
- *
- * Return: 0 success
- * A_NO_MEMORY No memory fail
- */
- #ifdef QCA_WIFI_2_0
- /* Rome Support only WDI 1.0 */
- int htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev)
- {
- struct htt_htc_pkt *pkt;
- cdf_nbuf_t msg;
- uint32_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 */
- /* reserve room for HTC header */
- msg = cdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_WDI_IPA_CFG_SZ),
- 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 */
- cdf_nbuf_put_tail(msg, HTT_WDI_IPA_CFG_SZ);
- /* fill in the message contents */
- msg_word = (uint32_t *) cdf_nbuf_data(msg);
- /* rewind beyond alignment pad to get to the HTC header reserved area */
- cdf_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,
- cdf_nbuf_data(msg),
- cdf_nbuf_len(msg),
- pdev->htc_endpoint,
- HTC_TX_PACKET_TAG_RUNTIME_PUT);
- SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
- htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
- return A_OK;
- }
- #else
- int htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev)
- {
- struct htt_htc_pkt *pkt;
- cdf_nbuf_t msg;
- uint32_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 */
- /* reserve room for HTC header */
- msg = cdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_WDI_IPA_CFG_SZ),
- 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 */
- cdf_nbuf_put_tail(msg, HTT_WDI_IPA_CFG_SZ);
- /* fill in the message contents */
- msg_word = (uint32_t *) cdf_nbuf_data(msg);
- /* rewind beyond alignment pad to get to the HTC header reserved area */
- cdf_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;
- /* TX COMP RING BASE LO */
- HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_LO_SET(*msg_word,
- (unsigned int)pdev->ipa_uc_tx_rsc.tx_comp_base.paddr);
- msg_word++;
- *msg_word = 0;
- /* TX COMP RING BASE HI, NONE */
- 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_LO_SET(*msg_word,
- (unsigned int)pdev->ipa_uc_tx_rsc.tx_comp_idx_paddr);
- msg_word++;
- *msg_word = 0;
- msg_word++;
- *msg_word = 0;
- HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_LO_SET(*msg_word,
- (unsigned int)pdev->ipa_uc_tx_rsc.tx_ce_idx.paddr);
- msg_word++;
- *msg_word = 0;
- msg_word++;
- *msg_word = 0;
- HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_LO_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_BASE_ADDR_HI_SET(*msg_word,
- 0);
- 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_LO_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_RD_IDX_ADDR_HI_SET(*msg_word,
- 0);
- msg_word++;
- *msg_word = 0;
- HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_LO_SET(*msg_word,
- (unsigned int)pdev->ipa_uc_rx_rsc.rx_rdy_idx_paddr);
- msg_word++;
- *msg_word = 0;
- HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_HI_SET(*msg_word,
- 0);
- msg_word++;
- *msg_word = 0;
- HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_LO_SET(*msg_word,
- (unsigned int)pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.paddr);
- msg_word++;
- *msg_word = 0;
- HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_HI_SET(*msg_word,
- 0);
- msg_word++;
- *msg_word = 0;
- HTT_WDI_IPA_CFG_RX_RING2_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_RING2_RD_IDX_ADDR_LO_SET(*msg_word,
- (unsigned int)pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.paddr);
- msg_word++;
- *msg_word = 0;
- HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_HI_SET(*msg_word,
- 0);
- msg_word++;
- *msg_word = 0;
- HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_LO_SET(*msg_word,
- (unsigned int)pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.paddr);
- msg_word++;
- *msg_word = 0;
- HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_HI_SET(*msg_word,
- 0);
- SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
- htt_h2t_send_complete_free_netbuf,
- cdf_nbuf_data(msg),
- cdf_nbuf_len(msg),
- pdev->htc_endpoint,
- 1); /* tag - not relevant here */
- SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
- htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
- return A_OK;
- }
- #endif
- /**
- * htt_h2t_ipa_uc_set_active() - Propagate WDI path enable/disable to firmware
- * @pdev: handle to the HTT instance
- * @uc_active: WDI UC path enable or not
- * @is_tx: TX path or RX path
- *
- * Return: 0 success
- * A_NO_MEMORY No memory fail
- */
- int htt_h2t_ipa_uc_set_active(struct htt_pdev_t *pdev,
- bool uc_active, bool is_tx)
- {
- struct htt_htc_pkt *pkt;
- cdf_nbuf_t msg;
- uint32_t *msg_word;
- uint8_t active_target = 0;
- 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 */
- /* reserve room for HTC header */
- msg = cdf_nbuf_alloc(pdev->osdev,
- HTT_MSG_BUF_SIZE(HTT_WDI_IPA_OP_REQUEST_SZ),
- 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 */
- cdf_nbuf_put_tail(msg, HTT_WDI_IPA_OP_REQUEST_SZ);
- /* fill in the message contents */
- msg_word = (uint32_t *) cdf_nbuf_data(msg);
- /* rewind beyond alignment pad to get to the HTC header reserved area */
- cdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
- *msg_word = 0;
- if (uc_active && is_tx)
- active_target = HTT_WDI_IPA_OPCODE_TX_RESUME;
- else if (!uc_active && is_tx)
- active_target = HTT_WDI_IPA_OPCODE_TX_SUSPEND;
- else if (uc_active && !is_tx)
- active_target = HTT_WDI_IPA_OPCODE_RX_RESUME;
- else if (!uc_active && !is_tx)
- active_target = HTT_WDI_IPA_OPCODE_RX_SUSPEND;
- HTT_WDI_IPA_OP_REQUEST_OP_CODE_SET(*msg_word, active_target);
- 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,
- cdf_nbuf_data(msg),
- cdf_nbuf_len(msg),
- pdev->htc_endpoint,
- 1); /* tag - not relevant here */
- SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
- htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
- return A_OK;
- }
- /**
- * htt_h2t_ipa_uc_get_stats() - WDI UC state query request to firmware
- * @pdev: handle to the HTT instance
- *
- * Return: 0 success
- * A_NO_MEMORY No memory fail
- */
- int htt_h2t_ipa_uc_get_stats(struct htt_pdev_t *pdev)
- {
- struct htt_htc_pkt *pkt;
- cdf_nbuf_t msg;
- uint32_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 */
- /* reserve room for HTC header */
- msg = cdf_nbuf_alloc(pdev->osdev,
- HTT_MSG_BUF_SIZE(HTT_WDI_IPA_OP_REQUEST_SZ),
- 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 */
- cdf_nbuf_put_tail(msg, HTT_WDI_IPA_OP_REQUEST_SZ);
- /* fill in the message contents */
- msg_word = (uint32_t *) cdf_nbuf_data(msg);
- /* rewind beyond alignment pad to get to the HTC header reserved area */
- cdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
- *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,
- cdf_nbuf_data(msg),
- cdf_nbuf_len(msg),
- pdev->htc_endpoint,
- 1); /* tag - not relevant here */
- SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
- htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
- return A_OK;
- }
- #endif /* IPA_OFFLOAD */
|