Merge 9c90eafb19 on remote branch

Change-Id: I0c2d2df19655904715fe70cfc7b31881abfa949d
This commit is contained in:
Linux Build Service Account 2022-02-14 22:03:41 -08:00
commit b5f1614d6a
11 changed files with 205 additions and 13 deletions

View file

@ -1482,8 +1482,7 @@ int gsi_deregister_device(unsigned long dev_hdl, bool force)
devm_free_irq(gsi_ctx->dev, gsi_ctx->per.irq, gsi_ctx);
gsi_unmap_base();
memset(gsi_ctx, 0, sizeof(*gsi_ctx));
gsi_ctx->per_registered = false;
return GSI_STATUS_SUCCESS;
}
EXPORT_SYMBOL(gsi_deregister_device);

View file

@ -735,7 +735,9 @@ static struct map_src_dst_addr_s ipa_uc_regs_to_save_array[] = {
};
static void ipa_hal_save_regs_save_ipa_testbus(void);
#ifndef CONFIG_IPA3_APPS_REGDUMP
static void ipa_reg_save_gsi_fifo_status(void);
#endif /* CONFIG_IPA3_APPS_REGDUMP */
static void ipa_reg_save_rsrc_cnts(void);
static void ipa_hal_save_regs_ipa_cmdq(void);
static void ipa_hal_save_regs_rsrc_db(void);
@ -865,9 +867,10 @@ void ipa_save_registers(void)
num_regs += (CONFIG_IPA3_REGDUMP_NUM_EXTRA_ENDP_REGS *
IPA_REG_SAVE_NUM_EXTRA_ENDP_REGS);
#ifndef CONFIG_IPA3_APPS_REGDUMP
/* Saving GSI FIFO Status registers */
ipa_reg_save_gsi_fifo_status();
#endif /* CONFIG_IPA3_APPS_REGDUMP */
/*
* On targets that support SSR, we generally want to disable
* the following reg save functionality as it may cause stalls
@ -896,6 +899,7 @@ void ipa_save_registers(void)
}
/* GSI test bus */
#ifndef CONFIG_IPA3_APPS_REGDUMP
for (i = 0;
i < ARRAY_SIZE(ipa_reg_save_gsi_ch_test_bus_selector_array);
i++) {
@ -911,6 +915,7 @@ void ipa_save_registers(void)
i].gsi_testbus_reg =
(u32) IPA_READ_SCALER_REG(GSI_TEST_BUS_REG);
}
#endif /* CONFIG_IPA3_APPS_REGDUMP */
ipa_reg_save_rsrc_cnts();
@ -1067,6 +1072,7 @@ void ipa_save_registers(void)
*
* @return
*/
#ifndef CONFIG_IPA3_APPS_REGDUMP
static void ipa_reg_save_gsi_fifo_status(void)
{
union ipa_hwio_def_ipa_gsi_fifo_status_ctrl_u gsi_fifo_status_ctrl;
@ -1089,7 +1095,7 @@ static void ipa_reg_save_gsi_fifo_status(void)
IPA_READ_SCALER_REG(IPA_GSI_AOS_FIFO_STATUS);
}
}
#endif /* CONFIG_IPA3_APPS_REGDUMP */
/*
* FUNCTION: ipa_reg_save_rsrc_cnts
*

View file

@ -41,6 +41,7 @@
#include <linux/jiffies.h>
#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/suspend.h>
#ifdef CONFIG_ARM64
@ -124,6 +125,11 @@ static void ipa_gsi_notify_cb(struct gsi_per_notify *notify);
static int ipa3_attach_to_smmu(void);
static int ipa3_alloc_pkt_init(void);
#ifdef CONFIG_DEEPSLEEP
static void ipa3_deepsleep_resume(void);
static void ipa3_deepsleep_suspend(void);
#endif
static void ipa3_load_ipa_fw(struct work_struct *work);
static DECLARE_WORK(ipa3_fw_loading_work, ipa3_load_ipa_fw);
static DECLARE_DELAYED_WORK(ipa3_fw_load_failure_handle, ipa3_load_ipa_fw);
@ -438,6 +444,38 @@ int ipa_smmu_free_sgt(struct sg_table **out_sgt_ptr)
}
EXPORT_SYMBOL(ipa_smmu_free_sgt);
/**
* ipa_pm_notify() - PM notify to listen suspend events
*
* This callback will be invoked by the pm framework to suspend
* operation is invoked.
*
* Returns NOTIFY_DONE to pm framework completed operation.
*/
static int ipa_pm_notify(struct notifier_block *b, unsigned long event, void *p)
{
IPAERR("Entry\n");
switch (event) {
case PM_POST_SUSPEND:
#ifdef CONFIG_DEEPSLEEP
if (mem_sleep_current == PM_SUSPEND_MEM) {
IPADBG("Enter deepsleep resume\n");
ipa3_deepsleep_resume();
IPADBG("Exit deepsleep resume\n");
}
#endif
break;
}
IPAERR("Exit\n");
return NOTIFY_DONE;
}
static struct notifier_block ipa_pm_notifier = {
.notifier_call = ipa_pm_notify,
};
static const struct dev_pm_ops ipa_pm_ops = {
.suspend_late = ipa3_ap_suspend,
.resume_early = ipa3_ap_resume,
@ -5063,6 +5101,7 @@ static void ipa3_teardown_apps_pipes(void)
__ipa3_del_rt_rule(ipa3_ctx->dflt_v4_rt_rule_hdl);
__ipa3_del_hdr(ipa3_ctx->excp_hdr_hdl, false);
ipa3_teardown_sys_pipe(ipa3_ctx->clnt_hdl_cmd);
ipa3_dealloc_common_event_ring();
}
#ifdef CONFIG_COMPAT
@ -6317,6 +6356,12 @@ static inline void ipa3_enable_napi_lan_rx(void)
napi_enable(&ipa3_ctx->napi_lan_rx);
}
static inline void ipa3_disable_napi_lan_rx(void)
{
if (ipa3_ctx->lan_rx_napi_enable)
napi_disable(&ipa3_ctx->napi_lan_rx);
}
static inline void ipa3_register_to_fmwk(void)
{
struct ipa_core_data data;
@ -6691,6 +6736,11 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
IPADBG("register to fmwk\n");
ipa3_register_to_fmwk();
}
#ifdef CONFIG_DEEPSLEEP
if (!ipa3_is_ready())
ipa_fmwk_deepsleep_exit_ipa();
#endif
complete_all(&ipa3_ctx->init_completion_obj);
ipa_ut_module_init();
@ -6793,13 +6843,12 @@ static int ipa3_manual_load_ipa_fws(void)
static int ipa3_pil_load_ipa_fws(const char *sub_sys)
{
void *subsystem_get_retval = NULL;
IPADBG("PIL FW loading process initiated sub_sys=%s\n",
sub_sys);
subsystem_get_retval = subsystem_get(sub_sys);
if (IS_ERR_OR_NULL(subsystem_get_retval)) {
ipa3_ctx->subsystem_get_retval = subsystem_get(sub_sys);
if (IS_ERR_OR_NULL(ipa3_ctx->subsystem_get_retval)) {
IPAERR("Unable to PIL load FW for sub_sys=%s\n", sub_sys);
return -EINVAL;
}
@ -6808,6 +6857,20 @@ static int ipa3_pil_load_ipa_fws(const char *sub_sys)
return 0;
}
#ifdef CONFIG_DEEPSLEEP
static int ipa3_pil_unload_ipa_fws(void)
{
IPADBG("PIL FW unloading process initiated sub_sys\n");
if (ipa3_ctx->subsystem_get_retval)
subsystem_put(ipa3_ctx->subsystem_get_retval);
IPADBG("PIL FW unloading process is complete sub_sys\n");
return 0;
}
#endif
static void ipa3_load_ipa_fw(struct work_struct *work)
{
int result;
@ -9475,7 +9538,17 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p)
return -EOPNOTSUPP;
}
}
/* Below update of pre init for non smmu device, As
* existing flow initialzies only for smmu
* enabled node.*/
result = ipa3_pre_init(&ipa3_res, pdev_p);
if (result) {
IPAERR("ipa3_init failed\n");
return result;
}
ipa_fw_load_sm_handle_event(IPA_FW_LOAD_EVNT_SMMU_DONE);
goto skip_repeat_pre_init;
}
/* Proceed to real initialization */
@ -9485,6 +9558,7 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p)
return result;
}
skip_repeat_pre_init:
result = of_platform_populate(pdev_p->dev.of_node,
ipa_plat_drv_match, NULL, &pdev_p->dev);
if (result) {
@ -9513,7 +9587,8 @@ int ipa3_ap_suspend(struct device *dev)
int i;
IPADBG("Enter...\n");
if (!of_device_is_compatible(dev->of_node,"qcom,ipa"))
return 0;
/* In case there is a tx/rx handler in polling mode fail to suspend */
for (i = 0; i < ipa3_ctx->ipa_num_pipes; i++) {
if (ipa3_ctx->ep[i].sys &&
@ -9524,6 +9599,13 @@ int ipa3_ap_suspend(struct device *dev)
}
}
#ifdef CONFIG_DEEPSLEEP
if (mem_sleep_current == PM_SUSPEND_MEM) {
IPADBG("Enter deepsleep suspend\n");
ipa3_deepsleep_suspend();
IPADBG("Exit deepsleep suspend\n");
}
#endif
ipa_pm_deactivate_all_deferred();
IPADBG("Exit\n");
@ -9556,6 +9638,58 @@ bool ipa3_get_lan_rx_napi(void)
return ipa3_ctx->lan_rx_napi_enable;
}
#ifdef CONFIG_DEEPSLEEP
static void ipa3_deepsleep_suspend(void)
{
IPADBG("Entry\n");
IPA_ACTIVE_CLIENTS_INC_SIMPLE();
/* To allow default routing table delection using this flag */
ipa3_ctx->deepsleep = true;
/*Disabling the LAN NAPI*/
ipa3_disable_napi_lan_rx();
/*NOt allow uC related operations until uC load again*/
ipa3_ctx->uc_ctx.uc_loaded = false;
/*Disconnecting LAN PROD/LAN CONS/CMD PROD apps pipes*/
ipa3_teardown_apps_pipes();
/*Deregistering the GSI driver*/
gsi_deregister_device(ipa3_ctx->gsi_dev_hdl, false);
/*Destroying filter table ids*/
ipa3_destroy_flt_tbl_idrs();
/*Disabling IPA interrupt*/
ipa3_remove_interrupt_handler(IPA_TX_SUSPEND_IRQ);
ipa3_interrupts_destroy(ipa3_res.ipa_irq, &ipa3_ctx->master_pdev->dev);
/*Destroy the NAT device*/
ipa3_nat_ipv6ct_destroy_devices();
/*Freeing memory allocated for coalesing and dma task*/
ipa3_free_coal_close_frame();
ipa3_free_dma_task_for_gsi();
/*Destroying ipa hal module*/
ipahal_destroy();
ipa3_ctx->ipa_initialization_complete = false;
ipa3_debugfs_remove();
/*Unloading IPA FW to allow FW load in resume*/
ipa3_pil_unload_ipa_fws();
/*Calling framework API to reset IPA ready flag to false*/
ipa_fmwk_deepsleep_entry_ipa();
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
IPADBG("Exit\n");
}
static void ipa3_deepsleep_resume(void)
{
IPADBG("Entry\n");
/*After deeplseep exit we shouldn't allow delete the default routing table*/
ipa3_ctx->deepsleep = false;
/*Scheduling WQ to load IPA FW*/
queue_work(ipa3_ctx->transport_power_mgmt_wq,
&ipa3_fw_loading_work);
IPADBG("Exit\n");
}
#endif
static void ipa_gsi_notify_cb(struct gsi_per_notify *notify)
{
/*
@ -9985,6 +10119,8 @@ static int __init ipa_module_init(void)
/* Register as a PCI device driver */
return pci_register_driver(&ipa_pci_driver);
}
register_pm_notifier(&ipa_pm_notifier);
/* Register as a platform device driver */
return platform_driver_register(&ipa_plat_drv);
}
@ -9995,6 +10131,7 @@ static void __exit ipa_module_exit(void)
if (running_emulation)
pci_unregister_driver(&ipa_pci_driver);
platform_driver_unregister(&ipa_plat_drv);
unregister_pm_notifier(&ipa_pm_notifier);
kfree(ipa3_ctx);
ipa3_ctx = NULL;
}

View file

@ -4765,6 +4765,13 @@ static void ipa_dma_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify)
}
}
void ipa3_dealloc_common_event_ring(void)
{
IPA_ACTIVE_CLIENTS_INC_SIMPLE();
gsi_dealloc_evt_ring(ipa3_ctx->gsi_evt_comm_hdl);
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
}
int ipa3_alloc_common_event_ring(void)
{
struct gsi_evt_ring_props gsi_evt_ring_props;

View file

@ -2128,6 +2128,8 @@ struct ipa3_context {
bool (*get_teth_port_state[IPA_MAX_CLNT])(void);
atomic_t is_ssr;
bool deepsleep;
void *subsystem_get_retval;
struct IpaHwOffloadStatsAllocCmdData_t
gsi_info[IPA_HW_PROTOCOL_MAX];
bool ipa_wan_skb_page;
@ -2509,7 +2511,6 @@ int ipa3_start_stop_client_prod_gsi_chnl(enum ipa_client_type client,
bool start_chnl);
void ipa3_client_prod_post_shutdown_cleanup(void);
int ipa3_set_reset_client_cons_pipe_sus_holb(bool set_reset, u32 tmr_val,
enum ipa_client_type client);
@ -3127,6 +3128,7 @@ int ipa3_get_ntn_stats(struct Ipa3HwStatsNTNInfoData_t *stats);
struct dentry *ipa_debugfs_get_root(void);
void ipa3_enable_dcd(void);
void ipa3_disable_prefetch(enum ipa_client_type client);
void ipa3_dealloc_common_event_ring(void);
int ipa3_alloc_common_event_ring(void);
int ipa3_allocate_dma_task_for_gsi(void);
void ipa3_free_dma_task_for_gsi(void);

View file

@ -1366,8 +1366,9 @@ int ipa3_nat_init_cmd(
goto bail;
}
if (init->table_entries == 0) {
IPAERR_RL("Table entries is zero\n");
if (init->table_entries == 0 ||
init->table_entries == U16_MAX) {
IPAERR_RL("Table entries is %d\n", init->table_entries);
result = -EPERM;
goto bail;
}

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "ipa_i.h"
@ -284,7 +285,7 @@ int ipa_setup_odl_pipe(void)
ipa_odl_ep_cfg = &ipa3_odl_ctx->odl_sys_param;
IPADBG("Setting up the odl endpoint\n");
ipa_odl_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en = IPA_ENABLE_CS_OFFLOAD_DL;
ipa_odl_ep_cfg->ipa_ep_cfg.cfg.cs_offload_en = IPA_DISABLE_CS_OFFLOAD;
ipa_odl_ep_cfg->ipa_ep_cfg.aggr.aggr_en = IPA_ENABLE_AGGR;
ipa_odl_ep_cfg->ipa_ep_cfg.aggr.aggr_hard_byte_limit_en = 1;
@ -366,6 +367,11 @@ int ipa3_odl_pipe_open(void)
return 0;
}
if (atomic_read(&ipa3_ctx->is_ssr)) {
IPAERR("SSR in progress ODL pipe configuration not allowed\n");
return 0;
}
memset(&holb_cfg, 0, sizeof(holb_cfg));
holb_cfg.tmr_val = 0;
holb_cfg.en = 1;

View file

@ -1753,7 +1753,7 @@ int __ipa3_del_rt_rule(u32 rule_hdl)
!strcmp(entry->tbl->name, IPA_DFLT_RT_TBL_NAME)) {
IPADBG("Deleting rule from default rt table idx=%u\n",
entry->tbl->idx);
if (entry->tbl->rule_cnt == 1) {
if (entry->tbl->rule_cnt == 1 && !ipa3_ctx->deepsleep) {
IPAERR_RL("Default tbl last rule cannot be deleted\n");
return -EINVAL;
}

View file

@ -1113,6 +1113,17 @@ remap_fail:
return result;
}
void ipa3_uc_interface_destroy(void)
{
if(ipa3_ctx->uc_ctx.uc_inited) {
ipa3_remove_interrupt_handler(IPA_UC_IRQ_2);
ipa3_remove_interrupt_handler(IPA_UC_IRQ_1);
ipa3_remove_interrupt_handler(IPA_UC_IRQ_0);
iounmap(ipa3_ctx->uc_ctx.uc_sram_mmio);
ipa3_ctx->uc_ctx.uc_inited = false;
}
}
/**
* ipa3_uc_send_cmd() - Send a command to the uC
*

View file

@ -2991,6 +2991,13 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this,
break;
#if IS_ENABLED(CONFIG_DEEPSLEEP)
case SUBSYS_AFTER_DS_ENTRY:
IPAWANINFO("IPA Received AFTER DEEPSLEEP ENTRY\n");
if (atomic_read(&rmnet_ipa3_ctx->is_ssr) &&
ipa3_ctx_get_type(IPA_HW_TYPE) < IPA_HW_v4_0)
ipa3_q6_post_shutdown_cleanup();
IPAWANINFO("AFTER DEEPSLEEP ENTRY handling is complete\n");
break;
#endif
case SUBSYS_AFTER_SHUTDOWN:
IPAWANINFO("IPA Received MPSS AFTER_SHUTDOWN\n");
@ -3005,6 +3012,17 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this,
break;
#if IS_ENABLED(CONFIG_DEEPSLEEP)
case SUBSYS_BEFORE_DS_EXIT:
IPAWANINFO("IPA received BEFORE DEEPSLEEP EXIT\n");
if (atomic_read(&rmnet_ipa3_ctx->is_ssr)) {
/* clean up cached QMI msg/handlers */
ipa3_qmi_service_exit();
ipa3_q6_pre_powerup_cleanup();
}
/* hold a proxy vote for the modem. */
ipa3_proxy_clk_vote(atomic_read(&rmnet_ipa3_ctx->is_ssr));
ipa3_reset_freeze_vote();
IPAWANINFO("BEFORE DEEPSLEEP EXIT handling is complete\n");
break;
#endif
case SUBSYS_BEFORE_POWERUP:
IPAWANINFO("IPA received MPSS BEFORE_POWERUP\n");

View file

@ -215,6 +215,11 @@ int ipa3_teth_bridge_driver_init(void)
{
int res;
if(ipa3_teth_ctx) {
TETH_DBG("Tethering bridge already initlized\n");
return 0;
}
TETH_DBG("Tethering bridge driver init\n");
ipa3_teth_ctx = kzalloc(sizeof(*ipa3_teth_ctx), GFP_KERNEL);
if (!ipa3_teth_ctx)