msm: ipa4: 11ad integration fixes

Fixes and configurations changes requested by GSI FW.

Change-Id: I5b736115213bef1feda7184ca839426b6aba0848
Signed-off-by: Amir Levy <alevy@codeaurora.org>
This commit is contained in:
Amir Levy
2019-01-29 10:08:12 +02:00
committed by Gerrit - the friendly Code Review server
parent a9d907d174
commit 247e2ea72f
6 changed files with 222 additions and 68 deletions

View File

@@ -95,6 +95,14 @@ int ipa_wigig_init(struct ipa_wigig_init_in_params *in,
ipa_wigig_ctx->dma_ep_misc_pa = in->dma_ep_misc_pa; ipa_wigig_ctx->dma_ep_misc_pa = in->dma_ep_misc_pa;
ipa_wigig_ctx->periph_baddr_pa = in->periph_baddr_pa; ipa_wigig_ctx->periph_baddr_pa = in->periph_baddr_pa;
IPA_WIGIG_DBG(
"periph_baddr_pa 0x%pa pseudo_cause_pa 0x%pa, int_gen_tx_pa 0x%pa, int_gen_rx_pa 0x%pa, dma_ep_misc_pa 0x%pa"
, &ipa_wigig_ctx->periph_baddr_pa,
&ipa_wigig_ctx->pseudo_cause_pa,
&ipa_wigig_ctx->int_gen_tx_pa,
&ipa_wigig_ctx->int_gen_rx_pa,
&ipa_wigig_ctx->dma_ep_misc_pa);
inout.notify = in->notify; inout.notify = in->notify;
inout.priv = in->priv; inout.priv = in->priv;
if (ipa_wigig_uc_init(&inout, in->int_notify, &out->uc_db_pa)) { if (ipa_wigig_uc_init(&inout, in->int_notify, &out->uc_db_pa)) {
@@ -103,6 +111,8 @@ int ipa_wigig_init(struct ipa_wigig_init_in_params *in,
return -EFAULT; return -EFAULT;
} }
IPA_WIGIG_DBG("uc_db_pa 0x%pa\n", &out->uc_db_pa);
out->is_uc_ready = inout.is_uC_ready; out->is_uc_ready = inout.is_uC_ready;
IPA_WIGIG_DBG("exit\n"); IPA_WIGIG_DBG("exit\n");
@@ -148,7 +158,7 @@ bool ipa_wigig_is_smmu_enabled(void)
ipa_get_smmu_params(&in, &out); ipa_get_smmu_params(&in, &out);
IPA_WIGIG_DBG("exit\n"); IPA_WIGIG_DBG("exit (%d)\n", out.smmu_enable);
return out.smmu_enable; return out.smmu_enable;
} }
@@ -168,6 +178,11 @@ static int ipa_wigig_commit_partial_hdr(
return -EINVAL; return -EINVAL;
} }
IPA_WIGIG_DBG("dst_mac_addr_offset %d hdr_len %d hdr_type %d\n",
hdr_info->dst_mac_addr_offset,
hdr_info->hdr_len,
hdr_info->hdr_type);
hdr->commit = 1; hdr->commit = 1;
hdr->num_hdrs = 2; hdr->num_hdrs = 2;
@@ -256,8 +271,11 @@ int ipa_wigig_reg_intf(
return -EPERM; return -EPERM;
} }
IPA_WIGIG_DBG("register interface for netdev %s\n", IPA_WIGIG_DBG(
in->netdev_name); "register interface for netdev %s, MAC 0x[%X][%X][%X][%X][%X][%X]\n"
, in->netdev_name,
in->netdev_mac[0], in->netdev_mac[1], in->netdev_mac[2],
in->netdev_mac[3], in->netdev_mac[4], in->netdev_mac[5]);
mutex_lock(&ipa_wigig_ctx->lock); mutex_lock(&ipa_wigig_ctx->lock);
list_for_each_entry(entry, &ipa_wigig_ctx->head_intf_list, link) list_for_each_entry(entry, &ipa_wigig_ctx->head_intf_list, link)
@@ -388,13 +406,13 @@ int ipa_wigig_dereg_intf(const char *netdev_name)
struct ipa_wigig_intf_info *entry; struct ipa_wigig_intf_info *entry;
struct ipa_wigig_intf_info *next; struct ipa_wigig_intf_info *next;
IPA_WIGIG_DBG("\n");
if (!netdev_name) { if (!netdev_name) {
IPA_WIGIG_ERR("no netdev name\n"); IPA_WIGIG_ERR("no netdev name\n");
return -EINVAL; return -EINVAL;
} }
IPA_WIGIG_DBG("netdev %s\n", netdev_name);
if (!ipa_wigig_ctx) { if (!ipa_wigig_ctx) {
IPA_WIGIG_ERR("wigig ctx is not initialized\n"); IPA_WIGIG_ERR("wigig ctx is not initialized\n");
return -EPERM; return -EPERM;
@@ -1224,6 +1242,7 @@ int ipa_wigig_disconn_pipe(enum ipa_client_type client)
/* RX will be disconnected last, deinit uC msi config */ /* RX will be disconnected last, deinit uC msi config */
if (client == IPA_CLIENT_WIGIG_PROD) { if (client == IPA_CLIENT_WIGIG_PROD) {
IPA_WIGIG_DBG("Rx pipe disconnected, deIniting uc\n");
ret = ipa_wigig_uc_msi_init(false, ret = ipa_wigig_uc_msi_init(false,
ipa_wigig_ctx->periph_baddr_pa, ipa_wigig_ctx->periph_baddr_pa,
ipa_wigig_ctx->pseudo_cause_pa, ipa_wigig_ctx->pseudo_cause_pa,
@@ -1234,6 +1253,12 @@ int ipa_wigig_disconn_pipe(enum ipa_client_type client)
IPA_WIGIG_ERR("failed unmapping msi regs\n"); IPA_WIGIG_ERR("failed unmapping msi regs\n");
WARN_ON(1); WARN_ON(1);
} }
ret = ipa_pm_deregister(ipa_wigig_ctx->ipa_pm_hdl);
if (ret) {
IPA_WIGIG_ERR("failed dereg pm\n");
WARN_ON(1);
}
} }
if (ipa_wigig_is_smmu_enabled()) if (ipa_wigig_is_smmu_enabled())
ipa_wigig_clean_smmu_info(client); ipa_wigig_clean_smmu_info(client);

View File

@@ -1667,6 +1667,8 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
} }
if (dst_ep_idx != -1) { if (dst_ep_idx != -1) {
int skb_idx;
/* SW data path */ /* SW data path */
data_idx = 0; data_idx = 0;
if (sys->policy == IPA_POLICY_NOINTR_MODE) { if (sys->policy == IPA_POLICY_NOINTR_MODE) {
@@ -1698,6 +1700,8 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
desc[data_idx].dma_address_valid = true; desc[data_idx].dma_address_valid = true;
desc[data_idx].dma_address = meta->dma_address; desc[data_idx].dma_address = meta->dma_address;
} }
skb_idx = data_idx;
data_idx++; data_idx++;
for (f = 0; f < num_frags; f++) { for (f = 0; f < num_frags; f++) {
@@ -1708,10 +1712,11 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
} }
/* don't free skb till frag mappings are released */ /* don't free skb till frag mappings are released */
if (num_frags) { if (num_frags) {
desc[data_idx + f - 1].callback = desc[2].callback; desc[data_idx + f - 1].callback =
desc[data_idx + f - 1].user1 = desc[2].user1; desc[skb_idx].callback;
desc[data_idx + f - 1].user2 = desc[2].user2; desc[data_idx + f - 1].user1 = desc[skb_idx].user1;
desc[data_idx - 1].callback = NULL; desc[data_idx + f - 1].user2 = desc[skb_idx].user2;
desc[skb_idx].callback = NULL;
} }
if (ipa3_send(sys, num_frags + data_idx, desc, true)) { if (ipa3_send(sys, num_frags + data_idx, desc, true)) {

View File

@@ -5035,7 +5035,8 @@ int ipa3_write_qmap_id(struct ipa_ioc_write_qmapid *param_in)
if (param_in->client == IPA_CLIENT_USB_PROD || if (param_in->client == IPA_CLIENT_USB_PROD ||
param_in->client == IPA_CLIENT_HSIC1_PROD || param_in->client == IPA_CLIENT_HSIC1_PROD ||
param_in->client == IPA_CLIENT_ODU_PROD || param_in->client == IPA_CLIENT_ODU_PROD ||
param_in->client == IPA_CLIENT_ETHERNET_PROD) { param_in->client == IPA_CLIENT_ETHERNET_PROD ||
param_in->client == IPA_CLIENT_WIGIG_PROD) {
result = ipa3_cfg_ep_metadata(ipa_ep_idx, &meta); result = ipa3_cfg_ep_metadata(ipa_ep_idx, &meta);
} else if (param_in->client == IPA_CLIENT_WLAN1_PROD) { } else if (param_in->client == IPA_CLIENT_WLAN1_PROD) {
ipa3_ctx->ep[ipa_ep_idx].cfg.meta = meta; ipa3_ctx->ep[ipa_ep_idx].cfg.meta = meta;

View File

@@ -9,6 +9,7 @@
#include <linux/ipa_wigig.h> #include <linux/ipa_wigig.h>
#define IPA_WIGIG_DESC_RING_EL_SIZE 32 #define IPA_WIGIG_DESC_RING_EL_SIZE 32
#define IPA_WIGIG_STATUS_RING_EL_SIZE 16
#define GSI_STOP_MAX_RETRY_CNT 10 #define GSI_STOP_MAX_RETRY_CNT 10
@@ -18,6 +19,9 @@
#define IPA_WIGIG_LSB_MASK 0x00000000FFFFFFFF #define IPA_WIGIG_LSB_MASK 0x00000000FFFFFFFF
#define IPA_WIGIG_MSB(num) ((u32)((num & IPA_WIGIG_MSB_MASK) >> 32)) #define IPA_WIGIG_MSB(num) ((u32)((num & IPA_WIGIG_MSB_MASK) >> 32))
#define IPA_WIGIG_LSB(num) ((u32)(num & IPA_WIGIG_LSB_MASK)) #define IPA_WIGIG_LSB(num) ((u32)(num & IPA_WIGIG_LSB_MASK))
/* extract PCIE addresses [0:39] relevant msb */
#define IPA_WIGIG_8_MSB_MASK 0xFF00000000
#define IPA_WIGIG_8_MSB(num) ((u32)((num & IPA_WIGIG_8_MSB_MASK) >> 32))
#define W11AD_RX 0 #define W11AD_RX 0
#define W11AD_TX 1 #define W11AD_TX 1
#define W11AD_TO_GSI_DB_m 1 #define W11AD_TO_GSI_DB_m 1
@@ -87,11 +91,10 @@ int ipa3_wigig_uc_init(
if (result) { if (result) {
inout->is_uC_ready = false; inout->is_uC_ready = false;
ipa3_ctx->uc_wigig_ctx.uc_ready_cb = inout->notify; ipa3_ctx->uc_wigig_ctx.uc_ready_cb = inout->notify;
ipa3_ctx->uc_wigig_ctx.priv = inout->priv;
} else { } else {
inout->is_uC_ready = true; inout->is_uC_ready = true;
} }
ipa3_ctx->uc_wigig_ctx.priv = inout->priv;
ipa3_ctx->uc_wigig_ctx.misc_notify_cb = int_notify; ipa3_ctx->uc_wigig_ctx.misc_notify_cb = int_notify;
*uc_db_pa = ipa3_ctx->ipa_wrapper_base + *uc_db_pa = ipa3_ctx->ipa_wrapper_base +
@@ -393,6 +396,8 @@ static int ipa3_wigig_config_gsi(bool Rx,
struct ipa_wigig_tx_pipe_data_buffer_info *tx_dbuff; struct ipa_wigig_tx_pipe_data_buffer_info *tx_dbuff;
struct ipa_wigig_tx_pipe_data_buffer_info_smmu *tx_dbuff_smmu; struct ipa_wigig_tx_pipe_data_buffer_info_smmu *tx_dbuff_smmu;
IPADBG("%s, %s\n", Rx ? "Rx" : "Tx", smmu_en ? "smmu en" : "smmu dis");
/* alloc event ring */ /* alloc event ring */
memset(&evt_props, 0, sizeof(evt_props)); memset(&evt_props, 0, sizeof(evt_props));
evt_props.intf = GSI_EVT_CHTYPE_11AD_EV; evt_props.intf = GSI_EVT_CHTYPE_11AD_EV;
@@ -456,7 +461,7 @@ static int ipa3_wigig_config_gsi(bool Rx,
channel_props.dir = GSI_CHAN_DIR_FROM_GSI; channel_props.dir = GSI_CHAN_DIR_FROM_GSI;
channel_props.re_size = GSI_CHAN_RE_SIZE_16B; channel_props.re_size = GSI_CHAN_RE_SIZE_16B;
channel_props.prot - GSI_CHAN_PROT_11AD; channel_props.prot = GSI_CHAN_PROT_11AD;
channel_props.ch_id = ep_gsi->ipa_gsi_chan_num; channel_props.ch_id = ep_gsi->ipa_gsi_chan_num;
channel_props.evt_ring_hdl = ep->gsi_evt_ring_hdl; channel_props.evt_ring_hdl = ep->gsi_evt_ring_hdl;
channel_props.xfer_cb = NULL; channel_props.xfer_cb = NULL;
@@ -514,8 +519,21 @@ static int ipa3_wigig_config_gsi(bool Rx,
gsi_scratch.rx_11ad.fixed_data_buffer_size_pow_2 = gsi_scratch.rx_11ad.fixed_data_buffer_size_pow_2 =
ilog2(rx_dbuff->data_buffer_size); ilog2(rx_dbuff->data_buffer_size);
} }
IPADBG("fixed_data_buffer_size_pow_2 %d\n", IPADBG("rx scratch: status_ring_hwtail_address_lsb 0x%X\n",
gsi_scratch.rx_11ad.status_ring_hwtail_address_lsb);
IPADBG("rx scratch: status_ring_hwtail_address_msb 0x%X\n",
gsi_scratch.rx_11ad.status_ring_hwtail_address_msb);
IPADBG("rx scratch: data_buffers_base_address_lsb 0x%X\n",
gsi_scratch.rx_11ad.data_buffers_base_address_lsb);
IPADBG("rx scratch: data_buffers_base_address_msb 0x%X\n",
gsi_scratch.rx_11ad.data_buffers_base_address_msb);
IPADBG("rx scratch: fixed_data_buffer_size_pow_2 %d\n",
gsi_scratch.rx_11ad.fixed_data_buffer_size_pow_2); gsi_scratch.rx_11ad.fixed_data_buffer_size_pow_2);
IPADBG("rx scratch 0x[%X][%X][%X][%X]\n",
gsi_scratch.data.word1,
gsi_scratch.data.word2,
gsi_scratch.data.word3,
gsi_scratch.data.word4);
} else { } else {
if (smmu_en) { if (smmu_en) {
tx_dbuff_smmu = tx_dbuff_smmu =
@@ -528,12 +546,19 @@ static int ipa3_wigig_config_gsi(bool Rx,
gsi_scratch.tx_11ad.status_ring_hwtail_address_lsb = gsi_scratch.tx_11ad.status_ring_hwtail_address_lsb =
IPA_WIGIG_LSB( IPA_WIGIG_LSB(
pipe_smmu->status_ring_HWTAIL_pa); pipe_smmu->status_ring_HWTAIL_pa);
gsi_scratch.tx_11ad.status_ring_hwtail_address_msb = gsi_scratch.tx_11ad.status_ring_hwhead_address_lsb =
IPA_WIGIG_MSB( IPA_WIGIG_LSB(
pipe_smmu->status_ring_HWTAIL_pa); pipe_smmu->status_ring_HWHEAD_pa);
gsi_scratch.tx_11ad.status_ring_hwhead_hwtail_8_msb =
IPA_WIGIG_8_MSB(
pipe_smmu->status_ring_HWHEAD_pa);
gsi_scratch.tx_11ad.fixed_data_buffer_size_pow_2 = gsi_scratch.tx_11ad.fixed_data_buffer_size_pow_2 =
ilog2(tx_dbuff_smmu->data_buffer_size); ilog2(tx_dbuff_smmu->data_buffer_size);
gsi_scratch.tx_11ad.status_ring_num_elem =
pipe_smmu->status_ring_size /
IPA_WIGIG_STATUS_RING_EL_SIZE;
} else { } else {
tx_dbuff = tx_dbuff =
(struct ipa_wigig_tx_pipe_data_buffer_info *)buff; (struct ipa_wigig_tx_pipe_data_buffer_info *)buff;
@@ -544,15 +569,35 @@ static int ipa3_wigig_config_gsi(bool Rx,
gsi_scratch.tx_11ad.status_ring_hwtail_address_lsb = gsi_scratch.tx_11ad.status_ring_hwtail_address_lsb =
IPA_WIGIG_LSB( IPA_WIGIG_LSB(
pipe->status_ring_HWTAIL_pa); pipe->status_ring_HWTAIL_pa);
gsi_scratch.tx_11ad.status_ring_hwtail_address_msb = gsi_scratch.tx_11ad.status_ring_hwhead_address_lsb =
IPA_WIGIG_MSB( IPA_WIGIG_LSB(
pipe->status_ring_HWTAIL_pa); pipe->status_ring_HWHEAD_pa);
gsi_scratch.tx_11ad.status_ring_hwhead_hwtail_8_msb =
IPA_WIGIG_8_MSB(pipe->status_ring_HWHEAD_pa);
gsi_scratch.tx_11ad.status_ring_num_elem =
pipe->status_ring_size /
IPA_WIGIG_STATUS_RING_EL_SIZE;
gsi_scratch.tx_11ad.fixed_data_buffer_size_pow_2 = gsi_scratch.tx_11ad.fixed_data_buffer_size_pow_2 =
ilog2(tx_dbuff->data_buffer_size); ilog2(tx_dbuff->data_buffer_size);
} }
IPADBG("fixed_data_buffer_size_pow_2 %d\n", gsi_scratch.tx_11ad.update_status_hwtail_mod_threshold = 1;
IPADBG("tx scratch: status_ring_hwtail_address_lsb 0x%X\n",
gsi_scratch.tx_11ad.status_ring_hwtail_address_lsb);
IPADBG("tx scratch: status_ring_hwhead_address_lsb 0x%X\n",
gsi_scratch.tx_11ad.status_ring_hwhead_address_lsb);
IPADBG("tx scratch: status_ring_hwhead_hwtail_8_msb 0x%X\n",
gsi_scratch.tx_11ad.status_ring_hwhead_hwtail_8_msb);
IPADBG("tx scratch:status_ring_num_elem %d\n",
gsi_scratch.tx_11ad.status_ring_num_elem);
IPADBG("tx scratch:fixed_data_buffer_size_pow_2 %d\n",
gsi_scratch.tx_11ad.fixed_data_buffer_size_pow_2); gsi_scratch.tx_11ad.fixed_data_buffer_size_pow_2);
IPADBG("tx scratch 0x[%X][%X][%X][%X]\n",
gsi_scratch.data.word1,
gsi_scratch.data.word2,
gsi_scratch.data.word3,
gsi_scratch.data.word4);
} }
IPADBG("ch_id: %d\n", channel_props.ch_id); IPADBG("ch_id: %d\n", channel_props.ch_id);
@@ -566,9 +611,12 @@ static int ipa3_wigig_config_gsi(bool Rx,
gsi_res = gsi_alloc_channel(&channel_props, gsi_res = gsi_alloc_channel(&channel_props,
ipa3_ctx->gsi_dev_hdl, ipa3_ctx->gsi_dev_hdl,
&ep->gsi_chan_hdl); &ep->gsi_chan_hdl);
if (gsi_res != GSI_STATUS_SUCCESS) if (gsi_res != GSI_STATUS_SUCCESS) {
IPAERR("gsi_alloc_channel failed %d\n", gsi_res);
goto fail_alloc_channel; goto fail_alloc_channel;
}
IPADBG("Writing Channel scratch\n");
ep->gsi_mem_info.chan_ring_len = channel_props.ring_len; ep->gsi_mem_info.chan_ring_len = channel_props.ring_len;
ep->gsi_mem_info.chan_ring_base_addr = channel_props.ring_base_addr; ep->gsi_mem_info.chan_ring_base_addr = channel_props.ring_base_addr;
ep->gsi_mem_info.chan_ring_base_vaddr = ep->gsi_mem_info.chan_ring_base_vaddr =
@@ -582,6 +630,9 @@ static int ipa3_wigig_config_gsi(bool Rx,
goto fail_write_channel_scratch; goto fail_write_channel_scratch;
} }
IPADBG("exit\n");
return 0;
fail_write_channel_scratch: fail_write_channel_scratch:
gsi_dealloc_channel(ep->gsi_chan_hdl); gsi_dealloc_channel(ep->gsi_chan_hdl);
fail_alloc_channel: fail_alloc_channel:
@@ -733,18 +784,28 @@ int ipa3_conn_wigig_rx_pipe_i(void *in, struct ipa_wigig_conn_out_params *out)
ep->client_notify = input_smmu->notify; ep->client_notify = input_smmu->notify;
ep->priv = input_smmu->priv; ep->priv = input_smmu->priv;
IPADBG(
"desc_ring_base %lld desc_ring_size %d status_ring_base %lld status_ring_size %d",
(unsigned long long)input_smmu->pipe_smmu.desc_ring_base_iova,
input_smmu->pipe_smmu.desc_ring_size,
(unsigned long long)input_smmu->pipe_smmu.status_ring_base_iova,
input_smmu->pipe_smmu.status_ring_size);
IPADBG("data_buffer_base_iova %lld data_buffer_size %d",
(unsigned long long)dbuff_smmu->data_buffer_base_iova,
input_smmu->dbuff_smmu.data_buffer_size);
if (IPA_WIGIG_MSB( if (IPA_WIGIG_MSB(
dbuff_smmu->data_buffer_base_iova) & dbuff_smmu->data_buffer_base_iova) &
0xFFFFFF00) { 0xFFFFFF00) {
IPAERR( IPAERR(
"data_buffers_base_address_msb is over the 8 bit limit (0xpa)\n" "data_buffers_base_address_msb is over the 8 bit limit (%lld)\n",
, &dbuff_smmu->data_buffer_base_iova); (unsigned long long)dbuff_smmu->data_buffer_base_iova);
IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
return -EFAULT; return -EFAULT;
} }
if (dbuff_smmu->data_buffer_size >> 16) { if (dbuff_smmu->data_buffer_size >> 16) {
IPAERR( IPAERR(
"data_buffer_size is over the 16 bit limit (0x%X)\n" "data_buffer_size is over the 16 bit limit (%d)\n"
, dbuff_smmu->data_buffer_size); , dbuff_smmu->data_buffer_size);
IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
return -EFAULT; return -EFAULT;
@@ -754,6 +815,16 @@ int ipa3_conn_wigig_rx_pipe_i(void *in, struct ipa_wigig_conn_out_params *out)
ep->client_notify = input->notify; ep->client_notify = input->notify;
ep->priv = input->priv; ep->priv = input->priv;
IPADBG(
"desc_ring_base_pa %pa desc_ring_size %d status_ring_base_pa %pa status_ring_size %d",
&input->pipe.desc_ring_base_pa,
input->pipe.desc_ring_size,
&input->pipe.status_ring_base_pa,
input->pipe.status_ring_size);
IPADBG("data_buffer_base_pa %pa data_buffer_size %d",
&input->dbuff.data_buffer_base_pa,
input->dbuff.data_buffer_size);
if ( if (
IPA_WIGIG_MSB(input->dbuff.data_buffer_base_pa) & 0xFFFFFF00) { IPA_WIGIG_MSB(input->dbuff.data_buffer_base_pa) & 0xFFFFFF00) {
IPAERR( IPAERR(
@@ -783,7 +854,7 @@ int ipa3_conn_wigig_rx_pipe_i(void *in, struct ipa_wigig_conn_out_params *out)
ep_cfg.mode.mode = IPA_BASIC; ep_cfg.mode.mode = IPA_BASIC;
if (ipa3_cfg_ep(ipa_ep_idx, &ep->cfg)) { if (ipa3_cfg_ep(ipa_ep_idx, &ep_cfg)) {
IPAERR("fail to setup rx pipe cfg\n"); IPAERR("fail to setup rx pipe cfg\n");
result = -EFAULT; result = -EFAULT;
goto fail; goto fail;
@@ -811,13 +882,6 @@ int ipa3_conn_wigig_rx_pipe_i(void *in, struct ipa_wigig_conn_out_params *out)
input->pipe.status_ring_HWHEAD_pa; input->pipe.status_ring_HWHEAD_pa;
} }
result = ipa3_wigig_config_uc(
true, true, 0,
ep_gsi->ipa_gsi_chan_num,
status_ring_HWHEAD_pa);
if (result)
goto fail_uc_config;
result = ipa3_wigig_config_gsi(true, result = ipa3_wigig_config_gsi(true,
is_smmu_enabled, is_smmu_enabled,
pipe_info, pipe_info,
@@ -826,6 +890,13 @@ int ipa3_conn_wigig_rx_pipe_i(void *in, struct ipa_wigig_conn_out_params *out)
if (result) if (result)
goto fail_gsi; goto fail_gsi;
result = ipa3_wigig_config_uc(
true, true, 0,
ep_gsi->ipa_gsi_chan_num,
status_ring_HWHEAD_pa);
if (result)
goto fail_uc_config;
ipa3_install_dflt_flt_rules(ipa_ep_idx); ipa3_install_dflt_flt_rules(ipa_ep_idx);
out->client = IPA_CLIENT_WIGIG_PROD; out->client = IPA_CLIENT_WIGIG_PROD;
@@ -838,12 +909,10 @@ int ipa3_conn_wigig_rx_pipe_i(void *in, struct ipa_wigig_conn_out_params *out)
return 0; return 0;
fail_gsi:
ipa3_wigig_config_uc(
false, true, 0,
ep_gsi->ipa_gsi_chan_num,
status_ring_HWHEAD_pa);
fail_uc_config: fail_uc_config:
/* Release channel and evt*/
ipa3_release_gsi_channel(ipa_ep_idx);
fail_gsi:
if (input_smmu) if (input_smmu)
ipa3_wigig_smmu_map_channel(true, &input_smmu->pipe_smmu, ipa3_wigig_smmu_map_channel(true, &input_smmu->pipe_smmu,
&input_smmu->dbuff_smmu, false); &input_smmu->dbuff_smmu, false);
@@ -874,11 +943,21 @@ int ipa3_conn_wigig_client_i(void *in, struct ipa_wigig_conn_out_params *out)
is_smmu_enabled = !ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_WLAN]; is_smmu_enabled = !ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_WLAN];
if (is_smmu_enabled) { if (is_smmu_enabled) {
input_smmu = (struct ipa_wigig_conn_tx_in_params_smmu *)in; input_smmu = (struct ipa_wigig_conn_tx_in_params_smmu *)in;
IPADBG(
"desc_ring_base %lld desc_ring_size %d status_ring_base %lld status_ring_size %d",
(unsigned long long)input_smmu->pipe_smmu.desc_ring_base_iova,
input_smmu->pipe_smmu.desc_ring_size,
(unsigned long long)input_smmu->pipe_smmu.status_ring_base_iova,
input_smmu->pipe_smmu.status_ring_size);
IPADBG("num buffers %d, data buffer size %d\n",
input_smmu->dbuff_smmu.num_buffers,
input_smmu->dbuff_smmu.data_buffer_size);
if (ipa3_wigig_tx_bit_to_ep(input_smmu->int_gen_tx_bit_num, if (ipa3_wigig_tx_bit_to_ep(input_smmu->int_gen_tx_bit_num,
&tx_client)) { &tx_client)) {
return -EINVAL; return -EINVAL;
} }
wifi_ch = input_smmu->int_gen_tx_bit_num;
if (input_smmu->dbuff_smmu.data_buffer_size >> 16) { if (input_smmu->dbuff_smmu.data_buffer_size >> 16) {
IPAERR( IPAERR(
"data_buffer_size is over the 16 bit limit (0x%X)\n" "data_buffer_size is over the 16 bit limit (0x%X)\n"
@@ -886,16 +965,37 @@ int ipa3_conn_wigig_client_i(void *in, struct ipa_wigig_conn_out_params *out)
return -EFAULT; return -EFAULT;
} }
if (IPA_WIGIG_8_MSB(
input_smmu->pipe_smmu.status_ring_HWHEAD_pa)
!= IPA_WIGIG_8_MSB(
input_smmu->pipe_smmu.status_ring_HWTAIL_pa)) {
IPAERR(
"status ring HWHEAD and HWTAIL differ in 8 MSbs head 0x%X tail 0x%X\n"
, input_smmu->pipe_smmu.status_ring_HWHEAD_pa,
input_smmu->pipe_smmu.status_ring_HWTAIL_pa);
return -EFAULT;
}
wifi_ch = input_smmu->int_gen_tx_bit_num;
/* convert to kBytes */ /* convert to kBytes */
aggr_byte_limit = IPA_ADJUST_AGGR_BYTE_HARD_LIMIT( aggr_byte_limit = IPA_ADJUST_AGGR_BYTE_HARD_LIMIT(
input_smmu->dbuff_smmu.data_buffer_size); input_smmu->dbuff_smmu.data_buffer_size);
} else { } else {
input = (struct ipa_wigig_conn_tx_in_params *)in; input = (struct ipa_wigig_conn_tx_in_params *)in;
IPADBG(
"desc_ring_base_pa %pa desc_ring_size %d status_ring_base_pa %pa status_ring_size %d",
&input->pipe.desc_ring_base_pa,
input->pipe.desc_ring_size,
&input->pipe.status_ring_base_pa,
input->pipe.status_ring_size);
IPADBG("data_buffer_size %d", input->dbuff.data_buffer_size);
if (ipa3_wigig_tx_bit_to_ep(input->int_gen_tx_bit_num, if (ipa3_wigig_tx_bit_to_ep(input->int_gen_tx_bit_num,
&tx_client)) { &tx_client)) {
return -EINVAL; return -EINVAL;
} }
wifi_ch = input->int_gen_tx_bit_num;
if (input->dbuff.data_buffer_size >> 16) { if (input->dbuff.data_buffer_size >> 16) {
IPAERR( IPAERR(
@@ -904,6 +1004,19 @@ int ipa3_conn_wigig_client_i(void *in, struct ipa_wigig_conn_out_params *out)
return -EFAULT; return -EFAULT;
} }
if (IPA_WIGIG_8_MSB(
input->pipe.status_ring_HWHEAD_pa)
!= IPA_WIGIG_8_MSB(
input->pipe.status_ring_HWTAIL_pa)) {
IPAERR(
"status ring HWHEAD and HWTAIL differ in 8 MSbs head 0x%X tail 0x%X\n"
, input->pipe.status_ring_HWHEAD_pa,
input->pipe.status_ring_HWTAIL_pa);
return -EFAULT;
}
wifi_ch = input->int_gen_tx_bit_num;
/* convert to kBytes */ /* convert to kBytes */
aggr_byte_limit = IPA_ADJUST_AGGR_BYTE_HARD_LIMIT( aggr_byte_limit = IPA_ADJUST_AGGR_BYTE_HARD_LIMIT(
input->dbuff.data_buffer_size); input->dbuff.data_buffer_size);
@@ -999,13 +1112,6 @@ int ipa3_conn_wigig_client_i(void *in, struct ipa_wigig_conn_out_params *out)
input->pipe.desc_ring_HWHEAD_pa; input->pipe.desc_ring_HWHEAD_pa;
} }
result = ipa3_wigig_config_uc(
true, false, wifi_ch,
ep_gsi->ipa_gsi_chan_num,
desc_ring_HWHEAD_pa);
if (result)
goto fail_uc_config;
result = ipa3_wigig_config_gsi(false, result = ipa3_wigig_config_gsi(false,
is_smmu_enabled, is_smmu_enabled,
pipe_info, pipe_info,
@@ -1014,6 +1120,13 @@ int ipa3_conn_wigig_client_i(void *in, struct ipa_wigig_conn_out_params *out)
if (result) if (result)
goto fail_gsi; goto fail_gsi;
result = ipa3_wigig_config_uc(
true, false, wifi_ch,
ep_gsi->ipa_gsi_chan_num,
desc_ring_HWHEAD_pa);
if (result)
goto fail_uc_config;
out->client = tx_client; out->client = tx_client;
ep->gsi_offload_state |= IPA_WIGIG_CONNECTED; ep->gsi_offload_state |= IPA_WIGIG_CONNECTED;
@@ -1023,12 +1136,10 @@ int ipa3_conn_wigig_client_i(void *in, struct ipa_wigig_conn_out_params *out)
ipa_ep_idx); ipa_ep_idx);
return 0; return 0;
fail_gsi:
ipa3_wigig_config_uc(
false, false, wifi_ch,
ep_gsi->ipa_gsi_chan_num,
desc_ring_HWHEAD_pa);
fail_uc_config: fail_uc_config:
/* Release channel and evt*/
ipa3_release_gsi_channel(ipa_ep_idx);
fail_gsi:
if (input_smmu) if (input_smmu)
ipa3_wigig_smmu_map_channel(false, &input_smmu->pipe_smmu, ipa3_wigig_smmu_map_channel(false, &input_smmu->pipe_smmu,
&input_smmu->dbuff_smmu, false); &input_smmu->dbuff_smmu, false);
@@ -1152,7 +1263,13 @@ int ipa3_wigig_uc_msi_init(bool init,
enum ipa_cpu_2_hw_offload_commands command; enum ipa_cpu_2_hw_offload_commands command;
bool map = false; bool map = false;
IPADBG("\n"); IPADBG("params: %s, %pa, %pa, %pa, %pa, %pa\n",
init ? "init" : "deInit",
&periph_baddr_pa,
&pseudo_cause_pa,
&int_gen_tx_pa,
&int_gen_rx_pa,
&dma_ep_misc_pa);
/* first make sure registers are SMMU mapped if necessary*/ /* first make sure registers are SMMU mapped if necessary*/
if ((!ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_UC])) { if ((!ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_UC])) {
@@ -1337,6 +1454,7 @@ int ipa3_enable_wigig_pipe_i(enum ipa_client_type client)
goto fail_ring_evt; goto fail_ring_evt;
} }
IPADBG("start channel\n");
res = gsi_start_channel(ep->gsi_chan_hdl); res = gsi_start_channel(ep->gsi_chan_hdl);
if (res != GSI_STATUS_SUCCESS) { if (res != GSI_STATUS_SUCCESS) {
IPAERR("gsi_start_channel failed %d\n", res); IPAERR("gsi_start_channel failed %d\n", res);
@@ -1353,6 +1471,8 @@ int ipa3_enable_wigig_pipe_i(enum ipa_client_type client)
ep->gsi_mem_info.chan_ring_len - ep->gsi_mem_info.chan_ring_len -
IPA_WIGIG_DESC_RING_EL_SIZE; IPA_WIGIG_DESC_RING_EL_SIZE;
IPADBG("ring ch doorbell (0x%llX) TX %d\n", val,
ep->gsi_chan_hdl);
res = gsi_ring_ch_ring_db(ep->gsi_chan_hdl, val); res = gsi_ring_ch_ring_db(ep->gsi_chan_hdl, val);
if (res) { if (res) {
IPAERR( IPAERR(

View File

@@ -77,22 +77,22 @@ struct ipa_wigig_reg_intf_in_params {
/* /*
* struct ipa_wigig_pipe_setup_info - WIGIG TX/Rx configuration * struct ipa_wigig_pipe_setup_info - WIGIG TX/Rx configuration
* @desc_ring_base_pa: physical address of the base of the descriptor ring * @desc_ring_base_pa: physical address of the base of the descriptor ring
* @desc_ring_size: size of the descriptor ring * @desc_ring_size: size of the descriptor ring in bytes
* @desc_ring_HWHEAD_pa: physical address of the wigig descriptor ring HWHEAD * @desc_ring_HWHEAD_pa: physical address of the wigig descriptor ring HWHEAD
* @desc_ring_HWTAIL_pa: physical address of the wigig descriptor ring HWTAIL * @desc_ring_HWTAIL_pa: physical address of the wigig descriptor ring HWTAIL
* @status_ring_base_pa: physical address of the base of the status ring * @status_ring_base_pa: physical address of the base of the status ring
* @status_ring_size: status ring size * @status_ring_size: status ring size in bytes
* @desc_ring_HWHEAD_pa: physical address of the wigig descriptor ring HWHEAD * @desc_ring_HWHEAD_pa: physical address of the wigig descriptor ring HWHEAD
* @desc_ring_HWTAIL_pa: physical address of the wigig descriptor ring HWTAIL * @desc_ring_HWTAIL_pa: physical address of the wigig descriptor ring HWTAIL
*/ */
struct ipa_wigig_pipe_setup_info { struct ipa_wigig_pipe_setup_info {
phys_addr_t desc_ring_base_pa; phys_addr_t desc_ring_base_pa;
u32 desc_ring_size; u16 desc_ring_size;
phys_addr_t desc_ring_HWHEAD_pa; phys_addr_t desc_ring_HWHEAD_pa;
phys_addr_t desc_ring_HWTAIL_pa; phys_addr_t desc_ring_HWTAIL_pa;
phys_addr_t status_ring_base_pa; phys_addr_t status_ring_base_pa;
u32 status_ring_size; u16 status_ring_size;
phys_addr_t status_ring_HWHEAD_pa; phys_addr_t status_ring_HWHEAD_pa;
phys_addr_t status_ring_HWTAIL_pa; phys_addr_t status_ring_HWTAIL_pa;
}; };
@@ -101,25 +101,25 @@ struct ipa_wigig_pipe_setup_info {
* struct ipa_wigig_pipe_setup_info_smmu - WIGIG TX/Rx configuration smmu mode * struct ipa_wigig_pipe_setup_info_smmu - WIGIG TX/Rx configuration smmu mode
* @desc_ring_base: sg_table of the base of the descriptor ring * @desc_ring_base: sg_table of the base of the descriptor ring
* @desc_ring_base_iova: IO virtual address mapped to physical base address * @desc_ring_base_iova: IO virtual address mapped to physical base address
* @desc_ring_size: size of the descriptor ring * @desc_ring_size: size of the descriptor ring in bytes
* @desc_ring_HWHEAD_pa: physical address of the wigig descriptor ring HWHEAD * @desc_ring_HWHEAD_pa: physical address of the wigig descriptor ring HWHEAD
* @desc_ring_HWTAIL_pa: physical address of the wigig descriptor ring HWTAIL * @desc_ring_HWTAIL_pa: physical address of the wigig descriptor ring HWTAIL
* @status_ring_base: sg_table of the base of the status ring * @status_ring_base: sg_table of the base of the status ring
* @status_ring_base_iova: IO virtual address mapped to physical base address * @status_ring_base_iova: IO virtual address mapped to physical base address
* @status_ring_size: status ring size * @status_ring_size: status ring size in bytes
* @desc_ring_HWHEAD_pa: physical address of the wigig descriptor ring HWHEAD * @desc_ring_HWHEAD_pa: physical address of the wigig descriptor ring HWHEAD
* @desc_ring_HWTAIL_pa: physical address of the wigig descriptor ring HWTAIL * @desc_ring_HWTAIL_pa: physical address of the wigig descriptor ring HWTAIL
*/ */
struct ipa_wigig_pipe_setup_info_smmu { struct ipa_wigig_pipe_setup_info_smmu {
struct sg_table desc_ring_base; struct sg_table desc_ring_base;
u64 desc_ring_base_iova; u64 desc_ring_base_iova;
u32 desc_ring_size; u16 desc_ring_size;
phys_addr_t desc_ring_HWHEAD_pa; phys_addr_t desc_ring_HWHEAD_pa;
phys_addr_t desc_ring_HWTAIL_pa; phys_addr_t desc_ring_HWTAIL_pa;
struct sg_table status_ring_base; struct sg_table status_ring_base;
u64 status_ring_base_iova; u64 status_ring_base_iova;
u32 status_ring_size; u16 status_ring_size;
phys_addr_t status_ring_HWHEAD_pa; phys_addr_t status_ring_HWHEAD_pa;
phys_addr_t status_ring_HWTAIL_pa; phys_addr_t status_ring_HWTAIL_pa;
}; };

View File

@@ -724,22 +724,25 @@ struct __packed gsi_11ad_rx_channel_scratch {
* TX channel scratch * TX channel scratch
* *
* @status_ring_hwtail_address_lsb: Low 32 bits of status ring hwtail address. * @status_ring_hwtail_address_lsb: Low 32 bits of status ring hwtail address.
* @status_ring_hwtail_address_msb: High 32 bits of status ring hwtail address. * @status_ring_hwhead_address_lsb: Low 32 bits of status ring hwhead address.
* @status_ring_hwhead_hwtail_8_msb: higher 8 msbs of status ring
* hwhead\hwtail addresses (should be identical).
* @update_status_hwtail_mod_threshold: The threshold in (32B) elements for * @update_status_hwtail_mod_threshold: The threshold in (32B) elements for
* updating descriptor ring 11ad HWTAIL pointer moderation. * updating descriptor ring 11ad HWTAIL pointer moderation.
* @status_ring_num_elem - the number of elements in the status ring.
* @resv1: reserved bits. * @resv1: reserved bits.
* @resv2: reserved bit.
* @fixed_data_buffer_size_pow_2: the fixed buffer size power of 2 (> MTU). * @fixed_data_buffer_size_pow_2: the fixed buffer size power of 2 (> MTU).
* @resv3: reserved bits. * @resv2: reserved bits.
*/ */
struct __packed gsi_11ad_tx_channel_scratch { struct __packed gsi_11ad_tx_channel_scratch {
uint32_t status_ring_hwtail_address_lsb; uint32_t status_ring_hwtail_address_lsb;
uint32_t status_ring_hwtail_address_msb; uint32_t status_ring_hwhead_address_lsb;
uint32_t status_ring_hwhead_hwtail_8_msb:8;
uint32_t update_status_hwtail_mod_threshold:8; uint32_t update_status_hwtail_mod_threshold:8;
uint32_t resv1:24; uint32_t status_ring_num_elem:16;
uint32_t resv2:8; uint32_t resv1:8;
uint32_t fixed_data_buffer_size_pow_2:16; uint32_t fixed_data_buffer_size_pow_2:16;
uint32_t resv3:8; uint32_t resv2:8;
}; };
/** /**