summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CORE/SERVICES/COMMON/hif.h29
-rw-r--r--CORE/SERVICES/HIF/PCIe/copy_engine.c39
-rw-r--r--CORE/SERVICES/HIF/PCIe/copy_engine_internal.h4
-rw-r--r--CORE/SERVICES/HIF/PCIe/hif_pci.c93
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.c38
5 files changed, 178 insertions, 25 deletions
diff --git a/CORE/SERVICES/COMMON/hif.h b/CORE/SERVICES/COMMON/hif.h
index fe1438f17bd2..bf40a1e1fe8c 100644
--- a/CORE/SERVICES/COMMON/hif.h
+++ b/CORE/SERVICES/COMMON/hif.h
@@ -681,21 +681,38 @@ void WAR_PCI_WRITE32(char *addr, u32 offset, u32 value);
#define A_TARGET_WRITE(targid, offset, value) \
WAR_PCI_WRITE32(TARGID_TO_PCI_ADDR(targid), (offset), (value))
#endif
+#define A_TARGET_ACCESS_BEGIN_RET(targid) \
+ do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0)
+
+#define A_TARGET_ACCESS_BEGIN_RET_EXT(targid, val) \
+ do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0)
+
+#define A_TARGET_ACCESS_BEGIN_RET_PTR(targid) \
+ do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0)
+
+#define A_TARGET_ACCESS_END_RET(targid) \
+ do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0)
+
+#define A_TARGET_ACCESS_END_RET_EXT(targid, val) \
+ do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0)
+
+#define A_TARGET_ACCESS_END_RET_PTR(targid) \
+ do {A_target_id_t unused = (A_target_id_t)(targid); unused = unused;} while(0)
#else /* CONFIG_ATH_PCIE_MAX_PERF */
void WAR_PCI_WRITE32(char *addr, u32 offset, u32 value);
#define A_TARGET_ACCESS_BEGIN_RET_EXT(targid, val) \
- if (Q_TARGET_ACCESS_BEGIN(targid) < 0 ) \
+ if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()) && Q_TARGET_ACCESS_BEGIN(targid) < 0 ) \
val = -1;
#define A_TARGET_ACCESS_BEGIN_RET(targid) \
- if (Q_TARGET_ACCESS_BEGIN(targid) < 0) \
+ if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()) && Q_TARGET_ACCESS_BEGIN(targid) < 0) \
return -1;
#define A_TARGET_ACCESS_BEGIN_RET_PTR(targid) \
- if (Q_TARGET_ACCESS_BEGIN(targid) < 0) \
+ if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()) && Q_TARGET_ACCESS_BEGIN(targid) < 0) \
return NULL;
#define A_TARGET_ACCESS_BEGIN(targid) \
@@ -706,15 +723,15 @@ void WAR_PCI_WRITE32(char *addr, u32 offset, u32 value);
HIFTargetSleepStateAdjust((targid), FALSE, TRUE)
#define A_TARGET_ACCESS_END_RET(targid) \
- if (Q_TARGET_ACCESS_END(targid) < 0) \
+ if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()) && Q_TARGET_ACCESS_END(targid) < 0) \
return -1;
#define A_TARGET_ACCESS_END_RET_EXT(targid, val) \
- if (Q_TARGET_ACCESS_END(targid) < 0) \
+ if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()) && Q_TARGET_ACCESS_END(targid) < 0) \
val = -1;
#define A_TARGET_ACCESS_END_RET_PTR(targid) \
- if (Q_TARGET_ACCESS_END(targid) < 0) \
+ if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()) && Q_TARGET_ACCESS_END(targid) < 0) \
return NULL;
#define A_TARGET_ACCESS_END(targid) \
diff --git a/CORE/SERVICES/HIF/PCIe/copy_engine.c b/CORE/SERVICES/HIF/PCIe/copy_engine.c
index ddad00a2d61f..e1e0055cc7e3 100644
--- a/CORE/SERVICES/HIF/PCIe/copy_engine.c
+++ b/CORE/SERVICES/HIF/PCIe/copy_engine.c
@@ -37,6 +37,10 @@
#include "adf_os_lock.h"
#include "hif_pci.h"
#include "regtable.h"
+#include <vos_getBin.h>
+#include "epping_main.h"
+
+#define CE_POLL_TIMEOUT 10 /* ms */
static int war1_allow_sleep;
extern int hif_pci_war1;
@@ -948,7 +952,8 @@ more_completions:
while (CE_completed_send_next_nolock(CE_state, &CE_context, &transfer_context,
&buf, &nbytes, &id, &sw_idx, &hw_idx) == A_OK){
- if(CE_id != CE_HTT_H2T_MSG){
+ if(CE_id != CE_HTT_H2T_MSG ||
+ WLAN_IS_EPPING_ENABLED(vos_get_conparam())){
adf_os_spin_unlock(&sc->target_lock);
CE_state->send_cb((struct CE_handle *)CE_state, CE_context, transfer_context, buf, nbytes, id,
sw_idx, hw_idx);
@@ -1005,7 +1010,8 @@ more_watermarks:
* we find no more events to process.
*/
if (CE_state->recv_cb && CE_recv_entries_done_nolock(sc, CE_state)) {
- if (more_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) {
+ if (WLAN_IS_EPPING_ENABLED(vos_get_conparam()) ||
+ more_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) {
goto more_completions;
} else {
adf_os_print("%s:Potential infinite loop detected during Rx processing"
@@ -1017,7 +1023,8 @@ more_watermarks:
}
if (CE_state->send_cb && CE_send_entries_done_nolock(sc, CE_state)) {
- if (more_snd_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) {
+ if (WLAN_IS_EPPING_ENABLED(vos_get_conparam()) ||
+ more_snd_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) {
goto more_completions;
} else {
adf_os_print("%s:Potential infinite loop detected during send completion"
@@ -1043,6 +1050,17 @@ more_watermarks:
A_TARGET_ACCESS_END(targid);
}
+static void
+CE_poll_timeout(void *arg)
+{
+ struct CE_state *CE_state = (struct CE_state *) arg;
+ if (CE_state->timer_inited) {
+ CE_per_engine_service(CE_state->sc, CE_state->id);
+ adf_os_timer_mod(&CE_state->poll_timer, CE_POLL_TIMEOUT);
+ }
+}
+
+
/*
* Handler for per-engine interrupts on ALL active CEs.
* This is used in cases where the system is sharing a
@@ -1513,6 +1531,15 @@ CE_init(struct hif_pci_softc *sc,
CE_DEST_RING_LOWMARK_SET(targid, ctrl_addr, 0);
CE_DEST_RING_HIGHMARK_SET(targid, ctrl_addr, nentries);
A_TARGET_ACCESS_END_RET_PTR(targid);
+
+ /* epping */
+ /* poll timer */
+ if ((CE_state->attr_flags & CE_ATTR_ENABLE_POLL)) {
+ adf_os_timer_init(scn->adf_dev, &CE_state->poll_timer,
+ CE_poll_timeout, CE_state);
+ CE_state->timer_inited = true;
+ adf_os_timer_mod(&CE_state->poll_timer, CE_POLL_TIMEOUT);
+ }
}
}
@@ -1546,6 +1573,12 @@ CE_fini(struct CE_handle *copyeng)
(CE_state->dest_ring->nentries * sizeof(struct CE_dest_desc) + CE_DESC_RING_ALIGN),
CE_state->dest_ring->base_addr_owner_space_unaligned, CE_state->dest_ring->base_addr_CE_space);
A_FREE(CE_state->dest_ring);
+
+ /* epping */
+ if (CE_state->timer_inited) {
+ CE_state->timer_inited = false;
+ adf_os_timer_free(&CE_state->poll_timer);
+ }
}
A_FREE(CE_state);
}
diff --git a/CORE/SERVICES/HIF/PCIe/copy_engine_internal.h b/CORE/SERVICES/HIF/PCIe/copy_engine_internal.h
index 4060aa5ab159..27df748ea7f1 100644
--- a/CORE/SERVICES/HIF/PCIe/copy_engine_internal.h
+++ b/CORE/SERVICES/HIF/PCIe/copy_engine_internal.h
@@ -123,6 +123,10 @@ struct CE_state {
struct CE_ring_state *src_ring;
struct CE_ring_state *dest_ring;
atomic_t rx_pending;
+
+ /* epping */
+ bool timer_inited;
+ adf_os_timer_t poll_timer;
};
/* Descriptor rings must be aligned to this boundary */
diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.c b/CORE/SERVICES/HIF/PCIe/hif_pci.c
index 0dca9ae652ee..b457c283fb2d 100644
--- a/CORE/SERVICES/HIF/PCIe/hif_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/hif_pci.c
@@ -58,6 +58,8 @@
#if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) && defined(CONFIG_CNSS)
#include <net/cnss.h>
#endif
+#include <vos_getBin.h>
+#include "epping_main.h"
/* use credit flow control over HTC */
unsigned int htc_credit_flow = 1;
@@ -162,6 +164,55 @@ static struct CE_pipe_config target_CE_config_wlan[] = {
static struct CE_pipe_config *target_CE_config = target_CE_config_wlan;
static int target_CE_config_sz = sizeof(target_CE_config_wlan);
+/*
+ * CE config for endpoint-ping test
+ * EP-ping is used to verify HTC/HIF basic functionality and could be used to
+ * measure interface performance. Here comes some notes.
+ * 1. In theory, each CE could be used to test. However, due to the limitation
+ * of target memory EP-ping only focus on CE 1/2/3/4 which are used for
+ * WMI/HTT services
+ * 2. The EP-ping CE config does not share the same CE config with WLAN
+ * application since the max_size and entries requirement for EP-ping
+ * is different.
+ */
+#define EPPING_CE_FLAGS_POLL CE_ATTR_DISABLE_INTR|CE_ATTR_ENABLE_POLL|CE_ATTR_FLAGS
+static struct CE_attr host_CE_config_wlan_epping_poll[] =
+{
+ { /* CE0 */ CE_ATTR_FLAGS, 0, 16, 256, 0, NULL, }, /* host->target HTC control and raw streams */
+ { /* CE1 */ EPPING_CE_FLAGS_POLL, 0, 0, 2048, 128, NULL, }, /* target->host EP-ping */
+ { /* CE2 */ EPPING_CE_FLAGS_POLL, 0, 0, 2048, 128, NULL, }, /* target->host EP-ping */
+ { /* CE3 */ CE_ATTR_FLAGS, 0, 128, 2048, 0, NULL, }, /* host->target EP-ping */
+ { /* CE4 */ CE_ATTR_FLAGS, 0, 128, 2048, 0, NULL, }, /* host->target EP-ping */
+ { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 128, NULL, }, /* EP-ping heartbeat */
+ { /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* unused */
+ { /* CE7 */ CE_ATTR_FLAGS, 0, 2, DIAG_TRANSFER_LIMIT, 2, NULL, }, /* ce_diag, the Diagnostic Window */
+};
+
+static struct CE_attr host_CE_config_wlan_epping_irq[] =
+{
+ { /* CE0 */ CE_ATTR_FLAGS, 0, 16, 256, 0, NULL, }, /* host->target HTC control and raw streams */
+ { /* CE1 */ CE_ATTR_FLAGS, 0, 0, 2048, 128, NULL, }, /* target->host EP-ping */
+ { /* CE2 */ CE_ATTR_FLAGS, 0, 0, 2048, 128, NULL, }, /* target->host EP-ping */
+ { /* CE3 */ CE_ATTR_FLAGS, 0, 128, 2048, 0, NULL, }, /* host->target EP-ping */
+ { /* CE4 */ CE_ATTR_FLAGS, 0, 128, 2048, 0, NULL, }, /* host->target EP-ping */
+ { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 128, NULL, }, /* EP-ping heartbeat */
+ { /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* unused */
+ { /* CE7 */ CE_ATTR_FLAGS, 0, 2, DIAG_TRANSFER_LIMIT, 2, NULL, }, /* ce_diag, the Diagnostic Window */
+};
+/*
+ * EP-ping firmware's CE configuration
+ */
+static struct CE_pipe_config target_CE_config_wlan_epping[] = {
+ { /* CE0 */ 0, PIPEDIR_OUT, 16, 256, CE_ATTR_FLAGS, 0, }, /* host->target HTC control and raw streams */
+ { /* CE1 */ 1, PIPEDIR_IN, 128, 2048, CE_ATTR_FLAGS, 0, }, /* target->host EP-ping */
+ { /* CE2 */ 2, PIPEDIR_IN, 128, 2048, CE_ATTR_FLAGS, 0, }, /* target->host EP-ping */
+ { /* CE3 */ 3, PIPEDIR_OUT, 128, 2048, CE_ATTR_FLAGS, 0, }, /* host->target EP-ping */
+ { /* CE4 */ 4, PIPEDIR_OUT, 128, 2048, CE_ATTR_FLAGS, 0, }, /* host->target EP-ping */
+ { /* CE5 */ 5, PIPEDIR_IN, 128, 2048, CE_ATTR_FLAGS, 0, }, /* EP-ping heartbeat */
+ { /* CE6 */ 6, PIPEDIR_INOUT, 0, 0, CE_ATTR_FLAGS, 0, }, /* unused */
+ /* CE7 used only by Host */
+};
+
int hif_completion_thread(struct HIF_CE_state *hif_state);
static int hif_post_recv_buffers(HIF_DEVICE *hif_device);
@@ -867,6 +918,16 @@ HIFMapServiceToPipe(HIF_DEVICE *hif_device, a_uint16_t ServiceId, a_uint8_t *ULP
break;
case WMI_DATA_BK_SVC:
+ /*
+ * To avoid some confusions, better to introduce new EP-ping
+ * service instead of using existed services. Until the main
+ * framework support this, keep this design.
+ */
+ if (WLAN_IS_EPPING_ENABLED(vos_get_conparam())) {
+ *ULPipe = 4;
+ *DLPipe = 1;
+ break;
+ }
case WMI_DATA_BE_SVC:
case WMI_DATA_VI_SVC:
case WMI_DATA_VO_SVC:
@@ -2014,6 +2075,26 @@ static struct service_to_pipe target_service_to_CE_map_wlan[] = {
static struct service_to_pipe *target_service_to_CE_map = target_service_to_CE_map_wlan;
static int target_service_to_CE_map_sz = sizeof(target_service_to_CE_map_wlan);
+static struct service_to_pipe target_service_to_CE_map_wlan_epping[] = {
+ { WMI_DATA_VO_SVC, PIPEDIR_OUT, 3, }, /* out = UL = host -> target */
+ { WMI_DATA_VO_SVC, PIPEDIR_IN, 2, }, /* in = DL = target -> host */
+ { WMI_DATA_BK_SVC, PIPEDIR_OUT, 4, }, /* out = UL = host -> target */
+ { WMI_DATA_BK_SVC, PIPEDIR_IN, 1, }, /* in = DL = target -> host */
+ { WMI_DATA_BE_SVC, PIPEDIR_OUT, 3, }, /* out = UL = host -> target */
+ { WMI_DATA_BE_SVC, PIPEDIR_IN, 2, }, /* in = DL = target -> host */
+ { WMI_DATA_VI_SVC, PIPEDIR_OUT, 3, }, /* out = UL = host -> target */
+ { WMI_DATA_VI_SVC, PIPEDIR_IN, 2, }, /* in = DL = target -> host */
+ { WMI_CONTROL_SVC, PIPEDIR_OUT, 3, }, /* out = UL = host -> target */
+ { WMI_CONTROL_SVC, PIPEDIR_IN, 2, }, /* in = DL = target -> host */
+ { HTC_CTRL_RSVD_SVC, PIPEDIR_OUT, 0, }, /* out = UL = host -> target */
+ { HTC_CTRL_RSVD_SVC, PIPEDIR_IN, 1, }, /* in = DL = target -> host */
+ { HTC_RAW_STREAMS_SVC, PIPEDIR_OUT, 0, }, /* out = UL = host -> target */
+ { HTC_RAW_STREAMS_SVC, PIPEDIR_IN, 1, }, /* in = DL = target -> host */
+ { HTT_DATA_MSG_SVC, PIPEDIR_OUT, 4, }, /* out = UL = host -> target */
+ { HTT_DATA_MSG_SVC, PIPEDIR_IN, 1, }, /* in = DL = target -> host */
+ { 0, 0, 0, }, /* Must be last */
+};
+
/*
* Send an interrupt to the device to wake up the Target CPU
* so it has an opportunity to notice any changed state.
@@ -2107,6 +2188,18 @@ HIF_PCIDeviceProbed(hif_handle_t hif_hdl)
AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__));
+ /* if epping is enabled we need to use the epping configuration. */
+ if (WLAN_IS_EPPING_ENABLED(vos_get_conparam())) {
+ if (WLAN_IS_EPPING_IRQ(vos_get_conparam()))
+ host_CE_config = host_CE_config_wlan_epping_irq;
+ else
+ host_CE_config = host_CE_config_wlan_epping_poll;
+ target_CE_config = target_CE_config_wlan_epping;
+ target_CE_config_sz = sizeof(target_CE_config_wlan_epping);
+ target_service_to_CE_map = target_service_to_CE_map_wlan_epping;
+ target_service_to_CE_map_sz = sizeof(target_service_to_CE_map_wlan_epping);
+ }
+
hif_state = (struct HIF_CE_state *)A_MALLOC(sizeof(*hif_state));
if (!hif_state) {
return -ENOMEM;
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c
index f0e7c0005037..ea4d66262c94 100644
--- a/CORE/SERVICES/HIF/PCIe/if_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/if_pci.c
@@ -52,6 +52,7 @@
#ifdef CONFIG_CNSS
#include <net/cnss.h>
#endif
+#include "epping_main.h"
#ifdef WLAN_BTAMP_FEATURE
#include "wlan_btc_svc.h"
@@ -214,11 +215,10 @@ bool hif_pci_targ_is_present(A_target_id_t targetid, void *__iomem *mem)
bool hif_max_num_receives_reached(unsigned int count)
{
-#ifdef EPPING_TEST
- return (count > 120);
-#else
- return (count > MAX_NUM_OF_RECEIVES);
-#endif
+ if (WLAN_IS_EPPING_ENABLED(vos_get_conparam()))
+ return (count > 120);
+ else
+ return (count > MAX_NUM_OF_RECEIVES);
}
void hif_init_adf_ctx(adf_os_device_t adf_dev, void *ol_sc)
@@ -689,10 +689,9 @@ hif_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
int probe_again = 0;
u_int16_t device_id;
u_int16_t revision_id;
-
u_int32_t lcr_val;
- printk(KERN_INFO "hif_pci_probe\n");
+ printk(KERN_INFO "%s:, con_mode= 0x%x\n", __func__, vos_get_conparam());
again:
ret = 0;
@@ -943,7 +942,8 @@ again:
pci_write_config_dword(pdev, 0x80, lcr_val);
#ifndef REMOVE_PKT_LOG
- if (vos_get_conparam() != VOS_FTM_MODE) {
+ if (vos_get_conparam() != VOS_FTM_MODE &&
+ !WLAN_IS_EPPING_ENABLED(vos_get_conparam())) {
/*
* pktlog initialization
*/
@@ -1272,7 +1272,8 @@ again:
}
#ifndef REMOVE_PKT_LOG
- if (vos_get_conparam() != VOS_FTM_MODE) {
+ if (vos_get_conparam() != VOS_FTM_MODE &&
+ !WLAN_IS_EPPING_ENABLED(vos_get_conparam())) {
/*
* pktlog initialization
*/
@@ -1335,10 +1336,12 @@ err_region:
void hif_pci_notify_handler(struct pci_dev *pdev, int state)
{
- int ret = 0;
- ret = hdd_wlan_notify_modem_power_state(state);
- if (ret < 0)
- printk(KERN_ERR "%s: Fail to send notify\n", __func__);
+ if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam())) {
+ int ret = 0;
+ ret = hdd_wlan_notify_modem_power_state(state);
+ if (ret < 0)
+ printk(KERN_ERR "%s: Fail to send notify\n", __func__);
+ }
}
void
@@ -1588,7 +1591,8 @@ hif_pci_remove(struct pci_dev *pdev)
scn = sc->ol_sc;
#ifndef REMOVE_PKT_LOG
- if (vos_get_conparam() != VOS_FTM_MODE)
+ if (vos_get_conparam() != VOS_FTM_MODE &&
+ !WLAN_IS_EPPING_ENABLED(vos_get_conparam()))
pktlogmod_exit(scn);
#endif
@@ -1638,14 +1642,16 @@ void hif_pci_shutdown(struct pci_dev *pdev)
scn = sc->ol_sc;
#ifndef REMOVE_PKT_LOG
- if (vos_get_conparam() != VOS_FTM_MODE)
+ if (vos_get_conparam() != VOS_FTM_MODE &&
+ !WLAN_IS_EPPING_ENABLED(vos_get_conparam()))
pktlogmod_exit(scn);
#endif
if (!vos_is_ssr_ready(__func__))
printk("Host driver is not ready for SSR, attempting anyway\n");
- hdd_wlan_shutdown();
+ if (!WLAN_IS_EPPING_ENABLED(vos_get_conparam()))
+ hdd_wlan_shutdown();
mem = (void __iomem *)sc->mem;