diff options
| author | Mingcheng Zhu <mingchen@qca.qualcomm.com> | 2014-06-04 11:57:55 -0700 |
|---|---|---|
| committer | Akash Patel <c_akashp@qca.qualcomm.com> | 2014-07-16 21:15:09 -0700 |
| commit | 1bec7d4ceddbfecc9b05dfcbc1b63d91c3ffe142 (patch) | |
| tree | 9aebb317cba1481afa99fded1e6c47ae93f63105 | |
| parent | 3cb85a3b1d99dcb080e3a74ee562db65448df55c (diff) | |
QCACLD-NEW: HIF PCIe change to support mboxping driver
PCIe based HIF is modified to support the coexistence of
end point ping and CLD.
CRs-Fixed: 657692
Change-Id: Ide279029d6306e5b0a2c0efedc0273adf965f6c4
| -rw-r--r-- | CORE/SERVICES/COMMON/hif.h | 29 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/copy_engine.c | 39 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/copy_engine_internal.h | 4 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/hif_pci.c | 93 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/if_pci.c | 38 |
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; |
