qcacmn: Add support for AP chipsets

Add copy engine configuration, extended set_hia functionality,
htc_module credit flow control function and physical address calculations.

Change-Id: I5e4394bed39cc92bb8323d332dc124d948737322
Acked-by: Venkateswara Swamy Bandaru <vbandaru@codeaurora.org>
CRs-Fixed: 1009050
This commit is contained in:
Houston Hoffman
2016-05-05 19:50:44 -07:00
committed by Gerrit - the friendly Code Review server
parent c3c6bc1e5c
commit fb698efe55
11 changed files with 612 additions and 71 deletions

View File

@@ -72,6 +72,9 @@ typedef void *hif_handle_t;
#define TARGET_TYPE_AR9888 7
#define TARGET_TYPE_AR6320 8
#define TARGET_TYPE_AR900B 9
#define TARGET_TYPE_QCA9984 10
#define TARGET_TYPE_IPQ4019 11
#define TARGET_TYPE_QCA9888 12
/* For attach Peregrine 2.0 board target_reg_tbl only */
#define TARGET_TYPE_AR9888V2 13
/* For attach Rome1.0 target_reg_tbl only*/
@@ -555,6 +558,9 @@ int hif_send_single(struct hif_opaque_softc *osc, qdf_nbuf_t msdu, uint32_t
int hif_send_fast(struct hif_opaque_softc *osc, qdf_nbuf_t *nbuf_arr, uint32_t
num_msdus, uint32_t transfer_id);
void hif_pkt_dl_len_set(void *hif_sc, unsigned int pkt_download_len);
void hif_ce_war_disable(void);
void hif_ce_war_enable(void);
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 The Linux Foundation. All rights reserved.
* Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -33,6 +33,12 @@
#ifndef __HIF_PCI_INTERNAL_H__
#define __HIF_PCI_INTERNAL_H__
#ifndef CONFIG_WIN
#ifndef PEER_CACHEING_HOST_ENABLE
#define PEER_CACHEING_HOST_ENABLE 0
#endif
#endif
#define HIF_PCI_DEBUG ATH_DEBUG_MAKE_MODULE_MASK(0)
#define HIF_PCI_IPA_UC_ASSIGNED_CE 5
@@ -313,6 +319,85 @@ static struct CE_pipe_config target_ce_config_wlan_epping[] = {
};
#endif
static struct CE_attr host_ce_config_wlan_ar9888[] = {
{ /* CE0 */ CE_ATTR_FLAGS, 0, 16, 256, 0, NULL, }, /* host->target HTC control and raw streams */
/* could be moved to share CE3 */
{ /* CE1 */ CE_ATTR_FLAGS, 0, 0, 512, 512, NULL, },/* target->host BMI + HTC control */
{ /* CE2 */ CE_ATTR_FLAGS, 0, 0, 2048, 128, NULL, },/* target->host WMI */
{ /* CE3 */ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL, },/* host->target WMI */
{ /* CE4 */ CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR, 0,
CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL, }, /* host->target HTT */
#if WLAN_FEATURE_FASTPATH
{ /* CE5 */ CE_ATTR_FLAGS, 0, 0, 512, 512, NULL, }, /* target->host HTT messages */
#else /* WLAN_FEATURE_FASTPATH */
{ /* CE5 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* unused */
#endif /* WLAN_FEATURE_FASTPATH */
{ /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* Target autonomous HIF_memcpy */
{ /* CE7 */ CE_ATTR_FLAGS, 0, 2, DIAG_TRANSFER_LIMIT, 2, NULL, }, /* ce_diag, the Diagnostic Window */
{ /* CE8 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* Target autonomous HIF_memcpy */
};
static struct CE_attr host_ce_config_wlan_ar900b[] = {
{ /* CE0 */ CE_ATTR_FLAGS, 0, 16, 256, 0, NULL, }, /* host->target HTC control and raw streams */
/* could be moved to share CE3 */
{ /* CE1 */ CE_ATTR_FLAGS, 0, 0, 512, 512, NULL, },/* target->host BMI + HTC control */
{ /* CE2 */ CE_ATTR_FLAGS, 0, 0, 2048, 128, NULL, },/* target->host WMI */
{ /* CE3 */ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL, },/* host->target WMI */
{ /* CE4 */ CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR, 0,
CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL, }, /* host->target HTT */
#if WLAN_FEATURE_FASTPATH
{ /* CE5 */ CE_ATTR_FLAGS, 0, 0, 512, 512, NULL, }, /* target->host HTT messages */
#else /* WLAN_FEATURE_FASTPATH */
{ /* CE5 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* unused */
#endif /* WLAN_FEATURE_FASTPATH */
{ /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* Target autonomous HIF_memcpy */
{ /* CE7 */ CE_ATTR_FLAGS, 0, 2, DIAG_TRANSFER_LIMIT, 2, NULL, }, /* ce_diag, the Diagnostic Window */
{ /* CE8 */ CE_ATTR_FLAGS, 0, 0, 2048, 128, NULL, },/* target->host pktlog */
{ /* CE9 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* Target autonomous HIF_memcpy */
{ /* CE10 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* Target autonomous HIF_memcpy */
{ /* CE11 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* Target autonomous HIF_memcpy */
};
static struct CE_pipe_config target_ce_config_wlan_ar9888[] = {
{ /* CE0 */ 0, PIPEDIR_OUT, 32, 256, CE_ATTR_FLAGS, 0, }, /* host->target HTC control and raw streams */
{ /* CE1 */ 1, PIPEDIR_IN, 32, 512, CE_ATTR_FLAGS, 0, }, /* target->host HTC control */
{ /* CE2 */ 2, PIPEDIR_IN, 64, 2048, CE_ATTR_FLAGS, 0, }, /* target->host WMI */
{ /* CE3 */ 3, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0, }, /* host->target WMI */
{ /* CE4 */ 4, PIPEDIR_OUT, 256, 256, CE_ATTR_FLAGS, 0, }, /* host->target HTT */
/* NB: 50% of src nentries, since tx has 2 frags */
#if WLAN_FEATURE_FASTPATH
{ /* CE5 */ 5, PIPEDIR_IN, 32, 512, CE_ATTR_FLAGS, 0, }, /* target->host HTT */
#else
{ /* CE5 */ 5, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0, }, /* unused */
#endif
{ /* CE6 */ 6, PIPEDIR_INOUT, 32, 4096, CE_ATTR_FLAGS, 0, },/* Reserved for target autonomous HIF_memcpy */
/* CE7 used only by Host */
};
static struct CE_pipe_config target_ce_config_wlan_ar900b[] = {
{ /* CE0 */ 0, PIPEDIR_OUT, 32, 256, CE_ATTR_FLAGS, 0, }, /* host->target HTC control and raw streams */
{ /* CE1 */ 1, PIPEDIR_IN, 32, 512, CE_ATTR_FLAGS, 0, }, /* target->host HTC control */
{ /* CE2 */ 2, PIPEDIR_IN, 64, 2048, CE_ATTR_FLAGS, 0, }, /* target->host WMI */
{ /* CE3 */ 3, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0, }, /* host->target WMI */
{ /* CE4 */ 4, PIPEDIR_OUT, 256, 256, CE_ATTR_FLAGS, 0, }, /* host->target HTT */
/* NB: 50% of src nentries, since tx has 2 frags */
#if WLAN_FEATURE_FASTPATH
{ /* CE5 */ 5, PIPEDIR_IN, 32, 512, CE_ATTR_FLAGS, 0, }, /* target->host HTT */
#else
{ /* CE5 */ 5, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0, }, /* unused */
#endif
{ /* CE6 */ 6, PIPEDIR_INOUT, 32, 4096, CE_ATTR_FLAGS, 0, },/* Reserved for target autonomous HIF_memcpy */
{ /* CE7 */ 7, PIPEDIR_INOUT, 0, 0, 0, 0, }, /* CE7 used only by Host */
{ /* CE8 */ 8, PIPEDIR_IN, 64, 2048, CE_ATTR_FLAGS
| CE_ATTR_DISABLE_INTR, 0, }, /* target->host packtlog */
#if PEER_CACHEING_HOST_ENABLE
{ /* CE9 */ 9, PIPEDIR_INOUT, 32, 2048, CE_ATTR_FLAGS |
CE_ATTR_DISABLE_INTR, 0, }, /* target autonomous qcache memcpy */
#endif
};
static struct CE_attr *host_ce_config = host_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);

View File

@@ -82,20 +82,77 @@ hif_dump_target_memory(struct hif_opaque_softc *hif_ctx, void *ramdump_base,
(SOC_CORE_BASE_ADDRESS|CORE_CTRL_ADDRESS)) & 0x7ff) << 21) \
| 0x100000 | ((addr) & 0xfffff))
#endif
#define TARG_CPU_SPACE_TO_CE_SPACE_IPQ4019(pci_addr, addr) \
(hif_read32_mb((pci_addr)+(WIFICMN_PCIE_BAR_REG_ADDRESS)) \
| ((addr) & 0xfffff))
#define TARG_CPU_SPACE_TO_CE_SPACE_AR900B(pci_addr, addr) \
(hif_read32_mb((pci_addr)+(WIFICMN_PCIE_BAR_REG_ADDRESS)) \
| 0x100000 | ((addr) & 0xfffff))
#define SRAM_BASE_ADDRESS 0xc0000
#define SRAM_END_ADDRESS 0x100000
#define WIFI0_IPQ4019_BAR 0xa000000
#define WIFI1_IPQ4019_BAR 0xa800000
/* Wait up to this many Ms for a Diagnostic Access CE operation to complete */
#define DIAG_ACCESS_CE_TIMEOUT_MS 10
/**
* get_ce_phy_addr() - get the physical address of an soc virtual address
* @sc: hif context
* @address: soc virtual address
* @target_type: target type being used.
*
* Return: soc physical address
*/
qdf_dma_addr_t get_ce_phy_addr(struct hif_softc *sc, uint32_t address,
unsigned int target_type)
{
qdf_dma_addr_t ce_phy_addr;
struct hif_softc *scn = sc;
unsigned int region = address & 0xfffff;
unsigned int bar = address & 0xfff00000;
unsigned int sramregion = 0;
if ((target_type == TARGET_TYPE_IPQ4019) &&
(region >= SRAM_BASE_ADDRESS && region <= SRAM_END_ADDRESS)
&& (bar == WIFI0_IPQ4019_BAR ||
bar == WIFI1_IPQ4019_BAR || bar == 0)) {
sramregion = 1;
}
if ((target_type == TARGET_TYPE_IPQ4019) && sramregion == 1) {
ce_phy_addr =
TARG_CPU_SPACE_TO_CE_SPACE_IPQ4019(sc->mem, address);
} else if ((target_type == TARGET_TYPE_AR900B) ||
(target_type == TARGET_TYPE_QCA9984) ||
(target_type == TARGET_TYPE_IPQ4019) ||
(target_type == TARGET_TYPE_QCA9888)) {
ce_phy_addr =
TARG_CPU_SPACE_TO_CE_SPACE_AR900B(sc->mem, address);
} else {
ce_phy_addr =
TARG_CPU_SPACE_TO_CE_SPACE(sc->mem, address);
}
return ce_phy_addr;
}
/*
* Diagnostic read/write access is provided for startup/config/debug usage.
* Caller must guarantee proper alignment, when applicable, and single user
* at any moment.
*/
QDF_STATUS
hif_diag_read_mem(struct hif_opaque_softc *hif_ctx, uint32_t address,
uint8_t *data, int nbytes)
#define FW_SRAM_ADDRESS 0x000C0000
QDF_STATUS hif_diag_read_mem(struct hif_opaque_softc *hif_ctx,
uint32_t address, uint8_t *data, int nbytes)
{
struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
QDF_STATUS status = QDF_STATUS_SUCCESS;
qdf_dma_addr_t buf;
@@ -112,18 +169,30 @@ hif_diag_read_mem(struct hif_opaque_softc *hif_ctx, uint32_t address,
qdf_dma_addr_t ce_phy_addr = address;
unsigned int toeplitz_hash_result;
unsigned int user_flags = 0;
unsigned int target_type = 0;
unsigned int boundary_addr = 0;
transaction_id = (mux_id & MUX_ID_MASK) |
(transaction_id & TRANSACTION_ID_MASK);
#ifdef QCA_WIFI_3_0
user_flags &= DESC_DATA_FLAG_MASK;
#endif
target_type = (hif_get_target_info_handle(hif_ctx))->target_type;
/* This code cannot handle reads to non-memory space. Redirect to the
* register read fn but preserve the multi word read capability of
* this fn
*/
if (address < DRAM_BASE_ADDRESS) {
if ((target_type == TARGET_TYPE_IPQ4019) ||
(target_type == TARGET_TYPE_AR900B) ||
(target_type == TARGET_TYPE_QCA9984) ||
(target_type == TARGET_TYPE_IPQ4019) ||
(target_type == TARGET_TYPE_QCA9888))
boundary_addr = FW_SRAM_ADDRESS;
else
boundary_addr = DRAM_BASE_ADDRESS;
if (address < boundary_addr) {
if ((address & 0x3) || ((uintptr_t) data & 0x3))
return QDF_STATUS_E_INVAL;
@@ -172,31 +241,21 @@ hif_diag_read_mem(struct hif_opaque_softc *hif_ctx, uint32_t address,
goto done;
}
{ /* Request CE to send from Target(!)
* address to Host buffer */
/*
* The address supplied by the caller is in the
* Target CPU virtual address space.
*
* In order to use this address with the diagnostic CE,
* convert it from
* Target CPU virtual address space
* to
* CE address space
*/
if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
return QDF_STATUS_E_FAILURE;
ce_phy_addr =
TARG_CPU_SPACE_TO_CE_SPACE(scn->mem, address);
if (Q_TARGET_ACCESS_END(scn) < 0)
return QDF_STATUS_E_FAILURE;
if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
return QDF_STATUS_E_FAILURE;
status =
ce_send(ce_diag, NULL, ce_phy_addr, nbytes,
transaction_id, 0, user_flags);
if (status != QDF_STATUS_SUCCESS)
goto done;
}
/* convert soc virtual address to physical address */
ce_phy_addr = get_ce_phy_addr(scn, address, target_type);
if (Q_TARGET_ACCESS_END(scn) < 0)
return QDF_STATUS_E_FAILURE;
/* Request CE to send from Target(!)
* address to Host buffer */
status = ce_send(ce_diag, NULL, ce_phy_addr, nbytes,
transaction_id, 0, user_flags);
if (status != QDF_STATUS_SUCCESS)
goto done;
i = 0;
while (ce_completed_send_next(ce_diag, NULL, NULL, &buf,
@@ -278,6 +337,13 @@ QDF_STATUS hif_diag_read_access(struct hif_opaque_softc *hif_ctx,
}
}
/**
* hif_diag_write_mem() - write data into the soc memory
* @hif_ctx: hif context
* @address: soc virtual address
* @data: data to copy into the soc address
* @nbytes: number of bytes to coppy
*/
QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *hif_ctx,
uint32_t address, uint8_t *data, int nbytes)
{
@@ -298,7 +364,7 @@ QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *hif_ctx,
qdf_dma_addr_t ce_phy_addr = address;
unsigned int toeplitz_hash_result;
unsigned int user_flags = 0;
unsigned int target_type = 0;
ce_diag = hif_state->ce_diag;
transaction_id = (mux_id & MUX_ID_MASK) |
(transaction_id & TRANSACTION_ID_MASK);
@@ -327,19 +393,14 @@ QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *hif_ctx,
qdf_mem_dma_sync_single_for_device(scn->qdf_dev, CE_data_base,
orig_nbytes, DMA_TO_DEVICE);
/*
* The address supplied by the caller is in the
* Target CPU virtual address space.
*
* In order to use this address with the diagnostic CE,
* convert it from
* Target CPU virtual address space
* to
* CE address space
*/
target_type = (hif_get_target_info_handle(hif_ctx))->target_type;
if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
return QDF_STATUS_E_FAILURE;
ce_phy_addr = TARG_CPU_SPACE_TO_CE_SPACE(scn->mem, address);
/* convert soc virtual address to physical address */
ce_phy_addr = get_ce_phy_addr(scn, address, target_type);
if (Q_TARGET_ACCESS_END(scn) < 0)
return QDF_STATUS_E_FAILURE;
@@ -348,26 +409,22 @@ QDF_STATUS hif_diag_write_mem(struct hif_opaque_softc *hif_ctx,
while (remaining_bytes) {
nbytes = min(remaining_bytes, DIAG_TRANSFER_LIMIT);
{ /* Set up to receive directly into Target(!) address */
status = ce_recv_buf_enqueue(ce_diag,
NULL, ce_phy_addr);
if (status != QDF_STATUS_SUCCESS)
goto done;
}
/* Set up to receive directly into Target(!) address */
status = ce_recv_buf_enqueue(ce_diag, NULL, ce_phy_addr);
if (status != QDF_STATUS_SUCCESS)
goto done;
{
/*
* Request CE to send caller-supplied data that
* was copied to bounce buffer to Target(!) address.
*/
status =
ce_send(ce_diag, NULL,
(qdf_dma_addr_t) CE_data, nbytes,
transaction_id, 0, user_flags);
if (status != QDF_STATUS_SUCCESS)
goto done;
}
/*
* Request CE to send caller-supplied data that
* was copied to bounce buffer to Target(!) address.
*/
status = ce_send(ce_diag, NULL, (qdf_dma_addr_t) CE_data,
nbytes, transaction_id, 0, user_flags);
if (status != QDF_STATUS_SUCCESS)
goto done;
/* poll for transfer complete */
i = 0;
while (ce_completed_send_next(ce_diag, NULL, NULL, &buf,
&completed_nbytes, &id,

View File

@@ -152,6 +152,7 @@ struct CE_state {
/* Descriptor rings must be aligned to this boundary */
#define CE_DESC_RING_ALIGN 8
#define CLOCK_OVERRIDE 0x2
#ifdef QCA_WIFI_3_0
#define HIF_CE_DESC_ADDR_TO_DMA(desc) \

View File

@@ -310,6 +310,106 @@ static struct service_to_pipe target_service_to_ce_map_wlan[] = {
},
};
static struct service_to_pipe target_service_to_ce_map_ar900b[] = {
{
WMI_DATA_VO_SVC,
PIPEDIR_OUT, /* out = UL = host -> target */
3,
},
{
WMI_DATA_VO_SVC,
PIPEDIR_IN, /* in = DL = target -> host */
2,
},
{
WMI_DATA_BK_SVC,
PIPEDIR_OUT, /* out = UL = host -> target */
3,
},
{
WMI_DATA_BK_SVC,
PIPEDIR_IN, /* in = DL = target -> host */
2,
},
{
WMI_DATA_BE_SVC,
PIPEDIR_OUT, /* out = UL = host -> target */
3,
},
{
WMI_DATA_BE_SVC,
PIPEDIR_IN, /* in = DL = target -> host */
2,
},
{
WMI_DATA_VI_SVC,
PIPEDIR_OUT, /* out = UL = host -> target */
3,
},
{
WMI_DATA_VI_SVC,
PIPEDIR_IN, /* in = DL = target -> host */
2,
},
{
WMI_CONTROL_SVC,
PIPEDIR_OUT, /* out = UL = host -> target */
3,
},
{
WMI_CONTROL_SVC,
PIPEDIR_IN, /* in = DL = target -> host */
2,
},
{
HTC_CTRL_RSVD_SVC,
PIPEDIR_OUT, /* out = UL = host -> target */
0, /* could be moved to 3 (share with WMI) */
},
{
HTC_CTRL_RSVD_SVC,
PIPEDIR_IN, /* in = DL = target -> host */
1,
},
{
HTC_RAW_STREAMS_SVC, /* not currently used */
PIPEDIR_OUT, /* out = UL = host -> target */
0,
},
{
HTC_RAW_STREAMS_SVC, /* not currently used */
PIPEDIR_IN, /* in = DL = target -> host */
1,
},
{
HTT_DATA_MSG_SVC,
PIPEDIR_OUT, /* out = UL = host -> target */
4,
},
#if WLAN_FEATURE_FASTPATH
{
HTT_DATA_MSG_SVC,
PIPEDIR_IN, /* in = DL = target -> host */
5,
},
#else /* WLAN_FEATURE_FASTPATH */
{
HTT_DATA_MSG_SVC,
PIPEDIR_IN, /* in = DL = target -> host */
1,
},
#endif /* WLAN_FEATURE_FASTPATH */
/* (Additions here) */
{ /* Must be last */
0,
0,
0,
},
};
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);
@@ -355,6 +455,8 @@ bool ce_mark_datapath(struct CE_state *ce_state)
size_t map_sz;
int i;
bool rc = false;
struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(ce_state->scn);
struct hif_target_info *tgt_info = hif_get_target_info_handle(hif_hdl);
if (ce_state != NULL) {
if (QDF_IS_EPPING_ENABLED(hif_get_conparam(ce_state->scn))) {
@@ -362,9 +464,25 @@ bool ce_mark_datapath(struct CE_state *ce_state)
map_sz = sizeof(target_service_to_ce_map_wlan_epping) /
sizeof(struct service_to_pipe);
} else {
svc_map = target_service_to_ce_map_wlan;
map_sz = sizeof(target_service_to_ce_map_wlan) /
sizeof(struct service_to_pipe);
switch (tgt_info->target_type) {
default:
svc_map = target_service_to_ce_map_wlan;
map_sz =
sizeof(target_service_to_ce_map_wlan) /
sizeof(struct service_to_pipe);
break;
case TARGET_TYPE_AR900B:
case TARGET_TYPE_QCA9984:
case TARGET_TYPE_IPQ4019:
case TARGET_TYPE_QCA9888:
case TARGET_TYPE_AR9888:
case TARGET_TYPE_AR9888V2:
svc_map = target_service_to_ce_map_ar900b;
map_sz =
sizeof(target_service_to_ce_map_ar900b)
/ sizeof(struct service_to_pipe);
break;
}
}
for (i = 0; i < map_sz; i++) {
if ((svc_map[i].pipenum == ce_state->id) &&
@@ -1788,6 +1906,9 @@ int hif_wlan_enable(struct hif_softc *scn)
void hif_ce_prepare_config(struct hif_softc *scn)
{
uint32_t mode = hif_get_conparam(scn);
struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(scn);
struct hif_target_info *tgt_info = hif_get_target_info_handle(hif_hdl);
/* if epping is enabled we need to use the epping configuration. */
if (QDF_IS_EPPING_ENABLED(mode)) {
if (CE_EPPING_USES_IRQ)
@@ -1803,6 +1924,34 @@ void hif_ce_prepare_config(struct hif_softc *scn)
target_shadow_reg_cfg = target_shadow_reg_cfg_epping;
shadow_cfg_sz = sizeof(target_shadow_reg_cfg_epping);
}
switch (tgt_info->target_type) {
default:
break;
case TARGET_TYPE_AR900B:
case TARGET_TYPE_QCA9984:
case TARGET_TYPE_IPQ4019:
case TARGET_TYPE_QCA9888:
host_ce_config = host_ce_config_wlan_ar900b;
target_ce_config = target_ce_config_wlan_ar900b;
target_ce_config_sz = sizeof(target_ce_config_wlan_ar900b);
target_service_to_ce_map = target_service_to_ce_map_ar900b;
target_service_to_ce_map_sz =
sizeof(target_service_to_ce_map_ar900b);
break;
case TARGET_TYPE_AR9888:
case TARGET_TYPE_AR9888V2:
host_ce_config = host_ce_config_wlan_ar9888;
target_ce_config = target_ce_config_wlan_ar9888;
target_ce_config_sz = sizeof(target_ce_config_wlan_ar9888);
target_service_to_ce_map = target_service_to_ce_map_ar900b;
target_service_to_ce_map_sz =
sizeof(target_service_to_ce_map_ar900b);
break;
}
}
/**
@@ -2287,6 +2436,7 @@ int hif_map_service_to_pipe(struct hif_opaque_softc *hif_hdl, uint16_t svc_id,
size_t sz_tgt_svc_map_to_use;
struct hif_softc *scn = HIF_GET_SOFTC(hif_hdl);
uint32_t mode = hif_get_conparam(scn);
struct hif_target_info *tgt_info = hif_get_target_info_handle(hif_hdl);
bool dl_updated = false;
bool ul_updated = false;
@@ -2295,8 +2445,23 @@ int hif_map_service_to_pipe(struct hif_opaque_softc *hif_hdl, uint16_t svc_id,
sz_tgt_svc_map_to_use =
sizeof(target_service_to_ce_map_wlan_epping);
} else {
tgt_svc_map_to_use = target_service_to_ce_map_wlan;
sz_tgt_svc_map_to_use = sizeof(target_service_to_ce_map_wlan);
switch (tgt_info->target_type) {
default:
tgt_svc_map_to_use = target_service_to_ce_map_wlan;
sz_tgt_svc_map_to_use =
sizeof(target_service_to_ce_map_wlan);
break;
case TARGET_TYPE_AR900B:
case TARGET_TYPE_QCA9984:
case TARGET_TYPE_IPQ4019:
case TARGET_TYPE_QCA9888:
case TARGET_TYPE_AR9888:
case TARGET_TYPE_AR9888V2:
tgt_svc_map_to_use = target_service_to_ce_map_ar900b;
sz_tgt_svc_map_to_use =
sizeof(target_service_to_ce_map_ar900b);
break;
}
}
*dl_is_polled = 0; /* polling for received messages not supported */

View File

@@ -72,6 +72,22 @@ static int war1_allow_sleep;
/* io32 write workaround */
static int hif_ce_war1;
/**
* hif_ce_war_disable() - disable ce war gobally
*/
void hif_ce_war_disable(void)
{
hif_ce_war1 = 0;
}
/**
* hif_ce_war_enable() - enable ce war gobally
*/
void hif_ce_war_enable(void)
{
hif_ce_war1 = 1;
}
#ifdef CONFIG_SLUB_DEBUG_ON
/**
@@ -257,8 +273,9 @@ void war_ce_src_ring_write_idx_set(struct hif_softc *scn,
hif_write32_mb(indicator_addr, 0);
local_irq_restore(irq_flags);
}
} else
} else {
CE_SRC_RING_WRITE_IDX_SET(scn, ctrl_addr, write_index);
}
}
int

View File

@@ -296,6 +296,15 @@ uint32_t hif_hia_item_address(uint32_t target_type, uint32_t item_offset)
/* ADRASTEA doesn't have a host interest address */
ASSERT(0);
return 0;
case TARGET_TYPE_AR900B:
return AR900B_HOST_INTEREST_ADDRESS + item_offset;
case TARGET_TYPE_QCA9984:
return QCA9984_HOST_INTEREST_ADDRESS + item_offset;
case TARGET_TYPE_QCA9888:
return QCA9888_HOST_INTEREST_ADDRESS + item_offset;
case TARGET_TYPE_IPQ4019:
return IPQ4019_HOST_INTEREST_ADDRESS + item_offset;
default:
ASSERT(0);
return 0;
@@ -771,6 +780,30 @@ int hif_get_device_type(uint32_t device_id,
}
break;
case AR9887_DEVICE_ID:
*hif_type = HIF_TYPE_AR9888;
*target_type = TARGET_TYPE_AR9888;
HIF_INFO(" *********** AR9887 **************\n");
break;
case QCA9984_DEVICE_ID:
*hif_type = HIF_TYPE_QCA9984;
*target_type = TARGET_TYPE_QCA9984;
HIF_INFO(" *********** QCA9984 *************\n");
break;
case QCA9888_DEVICE_ID:
*hif_type = HIF_TYPE_QCA9888;
*target_type = TARGET_TYPE_QCA9888;
HIF_INFO(" *********** QCA9888 *************\n");
break;
case AR900B_DEVICE_ID:
*hif_type = HIF_TYPE_AR900B;
*target_type = TARGET_TYPE_AR900B;
HIF_INFO(" *********** AR900B *************\n");
break;
default:
HIF_ERROR("%s: Unsupported device ID!", __func__);
ret = -ENODEV;

View File

@@ -86,6 +86,10 @@
#define AR6320_FW_3_2 (0x32)
#define ADRASTEA_DEVICE_ID (0xabcd)
#define ADRASTEA_DEVICE_ID_P2_E12 (0x7021)
#define AR9887_DEVICE_ID (0x0050)
#define AR900B_DEVICE_ID (0x0040)
#define QCA9984_DEVICE_ID (0x0046)
#define QCA9888_DEVICE_ID (0x0056)
#define HIF_GET_PCI_SOFTC(scn) ((struct hif_pci_softc *)scn)
#define HIF_GET_CE_STATE(scn) ((struct HIF_CE_state *)scn)

View File

@@ -72,6 +72,11 @@
* use TargetCPU warm reset * instead of SOC_GLOBAL_RESET
*/
#define CPU_WARM_RESET_WAR
#ifdef CONFIG_WIN
extern int32_t frac, intval, ar900b_20_targ_clk, qca9888_20_targ_clk;
#endif
/*
* Top-level interrupt handler for all PCI interrupts from a Target.
* When a block of MSI interrupts is allocated, this top-level handler
@@ -1458,6 +1463,149 @@ static void hif_sleep_entry(void *arg)
#define HIF_HIA_MAX_POLL_LOOP 1000000
#define HIF_HIA_POLLING_DELAY_MS 10
#ifdef CONFIG_WIN
void hif_set_hia_extnd(struct hif_softc *scn)
{
struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(scn);
struct hif_target_info *tgt_info = hif_get_target_info_handle(hif_hdl);
uint32_t target_type = tgt_info->target_type;
HIF_TRACE("%s: E", __func__);
if ((target_type == TARGET_TYPE_AR900B) ||
target_type == TARGET_TYPE_QCA9984 ||
target_type == TARGET_TYPE_QCA9888) {
/* CHIP revision is 8-11 bits of the CHIP_ID register 0xec
in RTC space */
tgt_info->target_revision
= CHIP_ID_REVISION_GET(hif_read32_mb(scn->mem
+ CHIP_ID_ADDRESS));
qdf_print(KERN_INFO"chip_id 0x%x chip_revision 0x%x\n",
target_type, tgt_info->target_revision);
}
{
uint32_t flag2_value = 0;
uint32_t flag2_targ_addr =
host_interest_item_address(target_type,
offsetof(struct host_interest_s, hi_skip_clock_init));
if ((ar900b_20_targ_clk != -1) &&
(frac != -1) && (intval != -1)) {
hif_diag_read_access(hif_hdl, flag2_targ_addr,
&flag2_value);
qdf_print("\n Setting clk_override\n");
flag2_value |= CLOCK_OVERRIDE;
hif_diag_write_access(hif_hdl, flag2_targ_addr,
flag2_value);
qdf_print("\n CLOCK PLL val set %d\n", flag2_value);
} else {
qdf_print(KERN_INFO"\n CLOCK PLL skipped\n");
}
}
if (target_type == TARGET_TYPE_AR900B
|| target_type == TARGET_TYPE_QCA9984
|| target_type == TARGET_TYPE_QCA9888) {
/* for AR9980_2.0, 300 mhz clock is used, right now we assume
* this would be supplied through module parameters,
* if not supplied assumed default or same behavior as 1.0.
* Assume 1.0 clock can't be tuned, reset to defaults
*/
qdf_print(KERN_INFO"%s: setting the target pll frac %x intval %x\n",
__func__, frac, intval);
/* do not touch frac, and int val, let them be default -1,
* if desired, host can supply these through module params
*/
if (frac != -1 || intval != -1) {
uint32_t flag2_value = 0;
uint32_t flag2_targ_addr;
flag2_targ_addr =
host_interest_item_address(target_type,
offsetof(struct host_interest_s,
hi_clock_info));
hif_diag_read_access(hif_hdl,
flag2_targ_addr, &flag2_value);
qdf_print("\n ====> FRAC Val %x Address %x\n", frac,
flag2_value);
hif_diag_write_access(hif_hdl, flag2_value, frac);
qdf_print("\n INT Val %x Address %x\n",
intval, flag2_value + 4);
hif_diag_write_access(hif_hdl,
flag2_value + 4, intval);
} else {
qdf_print(KERN_INFO"%s: no frac provided, skipping pre-configuring PLL\n",
__func__);
}
/* for 2.0 write 300 mhz into hi_desired_cpu_speed_hz */
if ((target_type == TARGET_TYPE_AR900B)
&& (tgt_info->target_revision == AR900B_REV_2)
&& ar900b_20_targ_clk != -1) {
uint32_t flag2_value = 0;
uint32_t flag2_targ_addr;
flag2_targ_addr
= host_interest_item_address(target_type,
offsetof(struct host_interest_s,
hi_desired_cpu_speed_hz));
hif_diag_read_access(hif_hdl, flag2_targ_addr,
&flag2_value);
qdf_print("\n ====> hi_desired_cpu_speed_hz Address %x\n",
flag2_value);
hif_diag_write_access(hif_hdl, flag2_value,
ar900b_20_targ_clk/*300000000u*/);
} else if (target_type == TARGET_TYPE_QCA9888) {
uint32_t flag2_targ_addr;
if (200000000u != qca9888_20_targ_clk) {
qca9888_20_targ_clk = 300000000u;
/* Setting the target clock speed to 300 mhz */
}
flag2_targ_addr
= host_interest_item_address(target_type,
offsetof(struct host_interest_s,
hi_desired_cpu_speed_hz));
hif_diag_write_access(hif_hdl, flag2_targ_addr,
qca9888_20_targ_clk);
} else {
qdf_print(KERN_INFO"%s: targ_clk is not provided, skipping pre-configuring PLL\n",
__func__);
}
} else {
if (frac != -1 || intval != -1) {
uint32_t flag2_value = 0;
uint32_t flag2_targ_addr =
host_interest_item_address(target_type,
offsetof(struct host_interest_s,
hi_clock_info));
hif_diag_read_access(hif_hdl, flag2_targ_addr,
&flag2_value);
qdf_print("\n ====> FRAC Val %x Address %x\n", frac,
flag2_value);
hif_diag_write_access(hif_hdl, flag2_value, frac);
qdf_print("\n INT Val %x Address %x\n", intval,
flag2_value + 4);
hif_diag_write_access(hif_hdl, flag2_value + 4,
intval);
}
}
}
#else
void hif_set_hia_extnd(struct hif_softc *scn)
{
}
#endif
/**
* hif_set_hia() - fill out the host interest area
* @scn: hif context
@@ -1704,6 +1852,12 @@ int hif_set_hia(struct hif_softc *scn)
goto done;
}
#endif
if ((target_type == TARGET_TYPE_AR900B)
|| (target_type == TARGET_TYPE_QCA9984)
|| (target_type == TARGET_TYPE_QCA9888)
|| (target_type == TARGET_TYPE_QCA9888)) {
hif_set_hia_extnd(scn);
}
/* Tell Target to proceed with initialization */
flag2_targ_addr = hif_hia_item_address(target_type,
@@ -1743,6 +1897,8 @@ int hif_pci_bus_configure(struct hif_softc *hif_sc)
{
int status = 0;
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(hif_sc);
struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(hif_sc);
struct hif_target_info *tgt_info = hif_get_target_info_handle(hif_hdl);
hif_ce_prepare_config(hif_sc);
@@ -1772,10 +1928,12 @@ int hif_pci_bus_configure(struct hif_softc *hif_sc)
if (CONFIG_ATH_PCIE_MAX_PERF ||
CONFIG_ATH_PCIE_AWAKE_WHILE_DRIVER_LOAD) {
/* Force AWAKE forever/till the driver is loaded */
if (hif_pci_target_sleep_state_adjust(hif_sc, false, true)
< 0) {
status = -EACCES;
goto disable_wlan;
if (tgt_info->target_type != TARGET_TYPE_IPQ4019) {
if (hif_pci_target_sleep_state_adjust(hif_sc,
false, true) < 0) {
status = -EACCES;
goto disable_wlan;
}
}
}
@@ -2184,9 +2342,10 @@ static int hif_pci_configure_legacy_irq(struct hif_pci_softc *sc)
hif_write32_mb(sc->mem+(SOC_CORE_BASE_ADDRESS |
PCIE_INTR_ENABLE_ADDRESS),
HOST_GROUP0_MASK);
hif_read32_mb(sc->mem+(SOC_CORE_BASE_ADDRESS |
PCIE_INTR_ENABLE_ADDRESS));
hif_write32_mb(sc->mem + PCIE_LOCAL_BASE_ADDRESS +
PCIE_SOC_WAKE_ADDRESS,
PCIE_SOC_WAKE_RESET);
PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
end:
QDF_TRACE(QDF_MODULE_ID_HIF, QDF_TRACE_LEVEL_ERROR,
"%s: X, ret = %d", __func__, ret);

View File

@@ -711,6 +711,8 @@ void *htc_get_targetdef(HTC_HANDLE htc_handle);
int htc_runtime_suspend(HTC_HANDLE htc_ctx);
int htc_runtime_resume(HTC_HANDLE htc_ctx);
#endif
void htc_global_credit_flow_disable(void);
void htc_global_credit_flow_enable(void);
/* Disable ASPM : Disable PCIe low power */
bool htc_can_suspend_link(HTC_HANDLE HTCHandle);

View File

@@ -36,6 +36,18 @@ unsigned int htc_credit_flow = 1;
#define DEBUG_CREDIT 0
#endif
/* HTC credit flow global disable */
void htc_global_credit_flow_disable(void)
{
htc_credit_flow = 0;
}
/* HTC credit flow global enable */
void htc_global_credit_flow_enable(void)
{
htc_credit_flow = 1;
}
A_STATUS htc_connect_service(HTC_HANDLE HTCHandle,
HTC_SERVICE_CONNECT_REQ *pConnectReq,
HTC_SERVICE_CONNECT_RESP *pConnectResp)